aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp24
-rw-r--r--CHANGES79
-rw-r--r--CMakeLists.txt2334
-rw-r--r--CONTRIBUTING.md29
-rw-r--r--CREDITS30
-rw-r--r--GenVersion.bat23
-rw-r--r--INSTALL.md (renamed from INSTALL.txt)49
-rw-r--r--METADATA18
-rw-r--r--Makefile.in280
-rw-r--r--README.md (renamed from README)65
-rw-r--r--README.version2
-rw-r--r--SUNOS4/nit_if.o.sparcbin5212 -> 0 bytes
-rw-r--r--SUNOS4/nit_if.o.sun3bin4267 -> 0 bytes
-rw-r--r--SUNOS4/nit_if.o.sun4c.4.0.3cbin5291 -> 0 bytes
-rw-r--r--VERSION2
-rw-r--r--Win32/Include/Gnuc.h8
-rw-r--r--Win32/Include/net/if.h230
-rw-r--r--Win32/Prj/wpcap.vcxproj13
-rw-r--r--Win32/Prj/wpcap.vcxproj.filters2
-rw-r--r--aclocal.m4471
-rw-r--r--bpf/net/bpf_filter.c766
-rw-r--r--bpf_dump.c7
-rw-r--r--[l---------]bpf_filter.c540
-rw-r--r--bpf_image.c158
-rwxr-xr-xchmod_bpf2
-rw-r--r--cmake/Modules/FindDAG.cmake32
-rw-r--r--cmake/Modules/FindFseeko.cmake85
-rw-r--r--cmake/Modules/FindLFS.cmake153
-rw-r--r--cmake/Modules/FindPacket.cmake81
-rw-r--r--cmake/Modules/FindSNF.cmake24
-rw-r--r--cmake/Modules/FindTC.cmake24
-rw-r--r--cmake/have_siocglifconf.c (renamed from config/have_siocglifconf.c)0
-rw-r--r--cmake/preconfigure.cmake55
-rw-r--r--cmake_uninstall.cmake.in21
-rw-r--r--cmakeconfig.h.in229
-rwxr-xr-x[-rw-r--r--]config.guess685
-rw-r--r--config.h211
-rw-r--r--config.h.in203
-rwxr-xr-x[-rw-r--r--]config.sub1681
-rwxr-xr-xconfigure4574
-rw-r--r--configure.ac1431
-rw-r--r--diag-control.h219
-rw-r--r--dlpisubs.c18
-rw-r--r--doc/DLT_ALLOCATE_HOWTO.md29
-rw-r--r--doc/README.Win32 (renamed from README.Win32)0
-rw-r--r--doc/README.aix (renamed from README.aix)0
-rw-r--r--doc/README.dag (renamed from README.dag)0
-rw-r--r--doc/README.hpux (renamed from README.hpux)0
-rw-r--r--doc/README.linux.md (renamed from README.linux)0
-rw-r--r--doc/README.macos (renamed from README.macosx)14
-rw-r--r--doc/README.septel (renamed from README.septel)2
-rw-r--r--doc/README.sita (renamed from README.sita)2
-rw-r--r--doc/README.tru64 (renamed from README.tru64)0
-rw-r--r--etherent.c79
-rw-r--r--extract.h16
-rw-r--r--fad-getad.c40
-rw-r--r--fad-gifc.c89
-rw-r--r--fad-glifc.c73
-rw-r--r--fad-helpers.c884
-rw-r--r--fmtutils.c131
-rw-r--r--fmtutils.h50
-rw-r--r--ftmacros.h115
-rwxr-xr-xgen_version_c.sh11
-rwxr-xr-xgen_version_header.sh19
-rw-r--r--gencode.c813
-rw-r--r--gencode.h42
-rw-r--r--grammar.c941
-rw-r--r--grammar.h10
-rw-r--r--grammar.y63
-rw-r--r--inet.c403
-rw-r--r--libpcap.pc.in18
-rw-r--r--missing/getopt.c5
-rw-r--r--missing/getopt.h2
-rw-r--r--missing/strtok_r.c2
-rw-r--r--msdos/common.dj86
-rw-r--r--msdos/makefile6
-rw-r--r--msdos/makefile.dj2
-rw-r--r--msdos/makefile.wc4
-rw-r--r--msdos/ndis2.c860
-rw-r--r--msdos/ndis2.h559
-rw-r--r--msdos/ndis_0.asm188
-rw-r--r--msdos/readme.dos2
-rw-r--r--nametoaddr.c431
l---------net1
-rwxr-xr-xnomkdep6
-rw-r--r--optimize.c268
-rw-r--r--optimize.h28
-rw-r--r--pcap-bpf.c606
-rw-r--r--pcap-bt-linux.c83
-rw-r--r--pcap-bt-linux.h2
-rw-r--r--pcap-bt-monitor-linux.c48
-rw-r--r--pcap-bt-monitor-linux.h2
-rw-r--r--pcap-common.c141
-rw-r--r--pcap-common.h32
-rwxr-xr-xpcap-config89
-rw-r--r--pcap-config.in9
-rw-r--r--pcap-dag.c747
-rw-r--r--pcap-dag.h2
-rw-r--r--pcap-dbus.c88
-rw-r--r--pcap-dbus.h2
-rw-r--r--pcap-dll.rc36
-rw-r--r--pcap-dlpi.c246
-rw-r--r--pcap-dos.c70
-rw-r--r--pcap-enet.c2
-rw-r--r--pcap-filter.manmisc42
-rw-r--r--pcap-filter.manmisc.in42
-rw-r--r--pcap-int.h156
-rw-r--r--pcap-libdlpi.c72
-rw-r--r--pcap-linktype.manmisc2
-rw-r--r--pcap-linktype.manmisc.in2
-rw-r--r--pcap-linux.c850
-rw-r--r--pcap-netfilter-linux.c207
-rw-r--r--pcap-netfilter-linux.h2
-rw-r--r--pcap-netmap.c306
-rw-r--r--pcap-netmap.h2
-rw-r--r--pcap-new.c1085
-rw-r--r--pcap-nit.c61
-rw-r--r--pcap-npf.c (renamed from pcap-win32.c)1140
-rw-r--r--pcap-null.c30
-rw-r--r--pcap-pf.c113
-rw-r--r--pcap-rdmasniff.c436
-rw-r--r--pcap-rdmasniff.h2
-rw-r--r--pcap-rpcap-int.h75
-rw-r--r--pcap-rpcap.c3326
-rw-r--r--pcap-rpcap.h478
-rw-r--r--pcap-septel.c70
-rw-r--r--pcap-septel.h2
-rw-r--r--pcap-sita.c72
-rw-r--r--pcap-snf.c355
-rw-r--r--pcap-snf.h2
-rw-r--r--pcap-snit.c102
-rw-r--r--pcap-snoop.c78
-rw-r--r--pcap-stdinc.h126
-rw-r--r--pcap-tc.c71
-rw-r--r--pcap-tc.h2
-rw-r--r--pcap-tstamp.manmisc6
-rw-r--r--pcap-tstamp.manmisc.in6
-rw-r--r--pcap-types.h50
-rw-r--r--pcap-usb-linux.c443
-rw-r--r--pcap-usb-linux.h2
-rw-r--r--pcap.3pcap92
-rw-r--r--pcap.3pcap.in92
-rw-r--r--pcap.c2390
-rw-r--r--pcap/bluetooth.h9
-rw-r--r--pcap/bpf.h14
-rw-r--r--pcap/can_socketcan.h12
-rw-r--r--pcap/compiler-tests.h163
-rw-r--r--pcap/dlt.h107
-rw-r--r--pcap/export-defs.h108
-rw-r--r--pcap/funcattrs.h261
-rw-r--r--pcap/namedb.h2
-rw-r--r--pcap/nflog.h30
-rw-r--r--pcap/pcap-inttypes.h117
-rw-r--r--pcap/pcap.h469
-rw-r--r--pcap/sll.h12
-rw-r--r--pcap/usb.h54
-rw-r--r--pcap/vlan.h6
-rw-r--r--pcap_activate.3pcap2
-rw-r--r--pcap_breakloop.3pcap18
-rw-r--r--pcap_can_set_rfmon.3pcap2
-rw-r--r--pcap_compile.3pcap12
-rw-r--r--pcap_compile.3pcap.in12
-rw-r--r--pcap_datalink.3pcap2
-rw-r--r--pcap_datalink.3pcap.in2
-rw-r--r--pcap_datalink_name_to_val.3pcap2
-rw-r--r--pcap_datalink_val_to_name.3pcap2
-rw-r--r--pcap_dump_ftell.3pcap19
-rw-r--r--pcap_dump_open.3pcap10
-rw-r--r--pcap_dump_open.3pcap.in10
-rw-r--r--pcap_fileno.3pcap2
-rw-r--r--pcap_findalldevs.3pcap26
-rw-r--r--pcap_get_required_select_timeout.3pcap84
-rw-r--r--pcap_get_selectable_fd.3pcap96
-rw-r--r--pcap_geterr.3pcap2
-rw-r--r--pcap_is_swapped.3pcap2
-rw-r--r--pcap_lookupdev.3pcap24
-rw-r--r--pcap_loop.3pcap20
-rw-r--r--pcap_major_version.3pcap4
-rw-r--r--pcap_next_ex.3pcap29
-rw-r--r--pcap_open_dead.3pcap2
-rw-r--r--pcap_open_dead.3pcap.in2
-rw-r--r--pcap_open_live.3pcap7
-rw-r--r--pcap_open_offline.3pcap4
-rw-r--r--pcap_open_offline.3pcap.in4
-rw-r--r--pcap_set_protocol_linux.3pcap67
-rw-r--r--pcap_set_timeout.3pcap19
-rw-r--r--pcap_set_tstamp_type.3pcap2
-rw-r--r--pcap_set_tstamp_type.3pcap.in2
-rw-r--r--pcap_version.h13
-rw-r--r--pcap_version.h.in13
-rw-r--r--portability.h114
-rw-r--r--remote-ext.h467
-rw-r--r--rpcap-protocol.c195
-rw-r--r--rpcap-protocol.h450
-rw-r--r--rpcapd/.gitignore5
-rw-r--r--rpcapd/CMakeLists.txt118
-rw-r--r--rpcapd/Makefile.in130
-rw-r--r--rpcapd/config_params.h56
-rw-r--r--rpcapd/daemon.c2554
-rw-r--r--rpcapd/daemon.h45
-rw-r--r--rpcapd/fileconf.c216
-rw-r--r--rpcapd/fileconf.h39
-rw-r--r--rpcapd/log-stderr.c41
-rw-r--r--rpcapd/log.h12
-rw-r--r--rpcapd/org.tcpdump.rpcapd.plist30
-rw-r--r--rpcapd/rpcapd.c1309
-rw-r--r--rpcapd/rpcapd.h44
-rw-r--r--rpcapd/rpcapd.inetd.conf2
-rw-r--r--rpcapd/rpcapd.manadmin.in223
-rw-r--r--rpcapd/rpcapd.rc39
-rw-r--r--rpcapd/rpcapd.socket9
-rw-r--r--rpcapd/rpcapd.xinetd.conf8
-rw-r--r--rpcapd/rpcapd@.service6
-rw-r--r--rpcapd/win32-svc.c182
-rw-r--r--rpcapd/win32-svc.h33
-rw-r--r--savefile.c69
-rw-r--r--scanner.c5174
-rw-r--r--scanner.h75
-rw-r--r--scanner.l93
-rw-r--r--sf-pcap.c302
-rw-r--r--sf-pcapng.c (renamed from sf-pcap-ng.c)227
-rw-r--r--sf-pcapng.h (renamed from sf-pcap-ng.h)8
-rw-r--r--sockutils.c475
-rw-r--r--sockutils.h79
-rw-r--r--testprogs/.gitignore13
-rw-r--r--testprogs/BPF/1.txt2
-rw-r--r--testprogs/BPF/2.txt2
-rw-r--r--testprogs/BPF/3.txt1
-rw-r--r--testprogs/BPF/4.txt2
-rw-r--r--testprogs/BPF/5.txt1
-rw-r--r--testprogs/BPF/6.txt1
-rw-r--r--testprogs/BPF/7.txt1
-rw-r--r--testprogs/CMakeLists.txt40
-rw-r--r--testprogs/Makefile.in144
-rw-r--r--testprogs/can_set_rfmon_test.c (renamed from tests/can_set_rfmon_test.c)6
-rw-r--r--testprogs/capturetest.c (renamed from tests/capturetest.c)69
-rw-r--r--testprogs/filtertest.c (renamed from tests/filtertest.c)147
-rw-r--r--testprogs/findalldevstest.c311
-rw-r--r--testprogs/opentest.c (renamed from tests/opentest.c)69
-rw-r--r--testprogs/pcap_compile_test.c11
-rw-r--r--testprogs/reactivatetest.c (renamed from tests/reactivatetest.c)6
-rw-r--r--testprogs/selpolltest.c (renamed from tests/selpolltest.c)234
-rw-r--r--testprogs/threadsignaltest.c393
-rw-r--r--testprogs/unix.h58
-rw-r--r--testprogs/valgrindtest.c (renamed from tests/valgrindtest.c)77
-rwxr-xr-xtestprogs/visopts.py310
-rw-r--r--tests/CMakeLists.txt42
-rw-r--r--tests/findalldevstest.c161
-rw-r--r--tests/shb-option-too-long.pcapngbin0 -> 180 bytes
-rw-r--r--varattrs.h59
-rw-r--r--version.c3
251 files changed, 33766 insertions, 18854 deletions
diff --git a/Android.bp b/Android.bp
index 1d3a5cbb..f18fb082 100644
--- a/Android.bp
+++ b/Android.bp
@@ -43,22 +43,20 @@ cc_library {
"pcap-netfilter-linux-android.c",
"fad-getad.c",
"pcap.c",
- "inet.c",
- "fad-helpers.c",
"gencode.c",
"optimize.c",
"nametoaddr.c",
"etherent.c",
+ "fmtutils.c",
"savefile.c",
"sf-pcap.c",
- "sf-pcap-ng.c",
+ "sf-pcapng.c",
"pcap-common.c",
"bpf_image.c",
+ "bpf_filter.c",
"bpf_dump.c",
"scanner.c",
"grammar.c",
- "bpf_filter.c",
- "version.c",
],
export_include_dirs: ["."],
@@ -74,13 +72,15 @@ cc_test {
gtest: false,
// (Matches order in libpcap's Makefile.)
srcs: [
- "tests/capturetest.c",
- "tests/can_set_rfmon_test.c",
- "tests/filtertest.c",
- "tests/findalldevstest.c",
- "tests/opentest.c",
- "tests/reactivatetest.c",
- "tests/selpolltest.c",
+ "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/valgrindtest.c",
],
static_libs: ["libpcap"],
test_per_src: true,
diff --git a/CHANGES b/CHANGES
index 17840965..4607f14a 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,82 @@
+Sunday, June 24, 2018, by mcr@sandelman.ca
+ Summary for 1.9.0 libpcap release
+ Added testing system to libpcap, independent of tcpdump
+ Changes to how pcap_t is activated
+ Adding support for Large stream buffers on Endace DAG cards
+ Changes to BSD 3-clause license to 2-clause licence
+ Additions to TCP header parsing, per RFC3168
+ Add CMake build process (extensive number of changes)
+ Assign a value for OpenBSD DLT_OPENFLOW.
+ Support setting non-blocking mode before activating.
+ Extensive build support for Windows VS2010 and MINGW (many many changes, over many months)
+ Added RPCAPD support when --enable-remote (default no)
+ Add the rpcap daemon source and build instructions.
+ Put back the greasy "save the capture filter string so we can tweak it"
+ hack, that keeps libpcap from capturing rpcap traffic.
+ Fixes for captures on MacOS, utun0
+ fixes so that non-AF_INET addresses, are not ==AF_INET6 addresses.
+ Add a linktype for IBM SDLC frames containing SNA PDUs.
+ pcap_compile() in 1.8.0 and later is newly thread-safe.
+ bound snaplen for linux tpacket_v2 to ~64k
+ Make VLAN filter handle both metadata and inline tags
+ D-Bus captures can now be up to 128MB in size
+ Added LORATAP DLT value
+ Added DLT_VSOCK for http://qemu-project.org/Features/VirtioVsock
+ probe_devices() fixes not to overrun buffer for name of device
+ Add linux-specific pcap_set_protocol_linux() to allow specifying a specific capture protocol.
+ RDMA sniffing support for pcap
+ Add Nordic Semiconductor Bluetooth LE sniffer link-layer header type.
+ fixes for reading /etc/ethers
+ Make it possible to build on Windows without packet.dll.
+ Add tests for large file support on UN*X.
+ Solaris fixes to work with 2.8.6
+ configuration test now looks for header files, not capture devices present
+ Fix to work with Berkeley YACC.
+ fixes for DragonBSD compilation of pcap-netmap.c
+ Clean up the ether_hostton() stuff.
+ Add an option to disable Linux memory-mapped capture support.
+ Add DAG API support checks.
+ Add Septel, Myricom SNF, and Riverbed TurboCap checks.
+ Add checks for Linux USB, Linux Bluetooth, D-Bus, and RDMA sniffing support.
+ Add a check for hardware time stamping on Linux.
+ Don't bother supporting pre-2005 Visual Studio.
+ Increased minimum autoconf version requirement to 2.64
+ Add DLT value 273 for XRA-31 sniffer
+ Clean up handing of signal interrupts in pcap_read_nocb_remote().
+ Use the XPG 4.2 versions of the networking APIs in Solaris.
+ Fix, and better explain, the "IPv6 means IPv6, not IPv4" option setting.
+ Explicitly warn that negative packet buffer timeouts should not be used.
+ rpcapd: Add support inetd-likes, including xinetd.conf, and systemd units
+ Rename DLT_IEEE802_15_4 to DLT_IEEE802_15_4_WITHFCS.
+ Add DISPLAYPORT AUX link type
+ Remove the sunos4 kernel modules and all references to them.
+ Add more interface flags to pcap_findalldevs().
+ Summary for 1.9.0 libpcap release (to 2017-01-25 by guy@alum.mit.edu)
+ Man page improvements
+ Fix Linux cooked mode userspace filtering (GitHub pull request #429)
+ Fix compilation if IPv6 support not enabled
+ 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/CMakeLists.txt b/CMakeLists.txt
index 0ed8b612..905ba61a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,167 +1,848 @@
-cmake_minimum_required( VERSION 2.8.8 )
+cmake_minimum_required(VERSION 2.8.6)
-project( pcap )
#
-# Call the library "wpcap" on Windows, for backwards compatibility.
+# 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( WIN32 )
- set( LIBRARY_NAME wpcap )
-else()
- set( LIBRARY_NAME pcap )
+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
###################################################################
-option (INET6 "Enable IPv6" ON)
-if( MSVC )
- option (USE_STATIC_RT "Use static Runtime" ON)
-endif( MSVC )
-option (BUILD_SHARED_LIBS "Build shared libraries" ON)
-if( WIN32 )
+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 )
+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()
#
-# XXX - this should be an option, defaulting to "yes" for Windows and to
-# "no", for now, on UN*X.
+# 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( WIN32 )
- set( HAVE_REMOTE 1 )
-endif( WIN32 )
+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 )
+add_definitions(-DHAVE_CONFIG_H)
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${pcap_SOURCE_DIR}
)
-if( WIN32 )
- if( NOT "${PACKET_DLL_DIR}" STREQUAL "" )
- include_directories("${PACKET_DLL_DIR}/Include")
- if( CMAKE_CL_64 )
- link_directories("${PACKET_DLL_DIR}/Lib/x64")
- else( CMAKE_CL_64 )
- link_directories("${PACKET_DLL_DIR}/Lib")
- endif( CMAKE_CL_64 )
- endif()
- include_directories(
- ../Common/
- Win32/Include
- )
-endif( WIN32)
-
-add_definitions( -DBUILDING_PCAP )
-
-if( MSVC )
- add_definitions( -D__STDC__ )
- add_definitions( -D_CRT_SECURE_NO_WARNINGS )
- add_definitions( "-D_U_=" )
-elseif( CMAKE_COMPILER_IS_GNUCXX )
- add_definitions( "-D_U_=__attribute__((unused))" )
-else(MSVC)
- add_definitions( "-D_U_=" )
-endif( MSVC )
-
-if( MSVC )
- if (USE_STATIC_RT)
- MESSAGE( STATUS "Use STATIC runtime" )
- set(NAME_RT MT)
- set (CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /MT")
- set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MT")
- set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
- set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
-
- set (CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} /MT")
- set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /MT")
- set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT")
- set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd")
- else (USE_STATIC_RT)
- MESSAGE( STATUS "Use DYNAMIC runtime" )
- set(NAME_RT MD)
- set (CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /MD")
- set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MD")
- set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD")
- set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
-
- set (CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} /MD")
- set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /MD")
- set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MD")
- set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MDd")
- endif (USE_STATIC_RT)
-endif( MSVC )
+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(CheckFunctionExists)
+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 )
-check_include_file( limits.h HAVE_LIMITS_H )
+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( strlcpy HAVE_STRLCPY )
-check_function_exists( snprintf HAVE_SNPRINTF )
-check_function_exists( vsnprintf HAVE_VSNPRINTF )
-check_function_exists( strtok_r HAVE_STRTOK_R )
+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.
-if (WIN32)
+# 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)
#
- # Check for Windows-only functions, such as packet.dll functions.
+ # We need winsock2.h and ws2tcpip.h.
#
- check_function_exists( PacketIsLoopbackAdapter HAVE_PACKET_IS_LOOPBACK_ADAPTER )
-endif()
+ 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_struct() macro that's like check_struct_has_member()
+# 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_struct_has_member() and look for ss_family.
+# so we use check_type_size() and ignore the size.
#
-check_struct_has_member("struct sockaddr_storage" ss_family sys/socket.h HAVE_SOCKADDR_STORAGE)
-set(CMAKE_EXTRA_INCLUDE_FILES unistd.h sys/socket.h)
+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)
-set(CMAKE_EXTRA_INCLUDE_FILES unistd.h)
+cmake_pop_check_state()
#
# Structure fields.
#
-check_struct_has_member("struct sockaddr" sa_len sys/socket.h HAVE_SOCKADDR_SA_LEN )
+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)
-if( INET6 )
- MESSAGE( STATUS "Use IPv6" )
-endif( INET6 )
+#
+# 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()
-if( WIN32 )
- add_definitions( -DHAVE_ADDRINFO )
-endif( WIN32 )
+#
+# 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()
-######################################
-# External dependencies
-######################################
+#
+# 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
@@ -169,104 +850,337 @@ endif( WIN32 )
set(PROJECT_SOURCE_LIST_C
bpf_dump.c
+ bpf_filter.c
bpf_image.c
etherent.c
- fad-helpers.c
+ fmtutils.c
gencode.c
- inet.c
nametoaddr.c
optimize.c
pcap-common.c
pcap.c
savefile.c
- sf-pcap-ng.c
+ sf-pcapng.c
sf-pcap.c
- bpf/net/bpf_filter.c
)
-if( WIN32 )
- set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/win_snprintf.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 )
-
-if( HAVE_REMOTE )
- set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C}
- pcap-new.c pcap-rpcap.c sockutils.c)
-endif( HAVE_REMOTE )
+ 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.
+# Determine the main pcap-XXX.c file to use, and the libraries with
+# which we need to link libpcap, if any.
#
-if( WIN32 )
+if(WIN32)
+ #
+ # Windows.
#
- # WinPcap.
+ # Has the user explicitly specified a capture type?
#
- set( PCAP_TYPE win32 )
+ 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.
+ # UN*X.
+ #
+ # Figure out what type of packet capture mechanism we have, and
+ # what libraries we'd need to link libpcap with, if any.
#
- if( EXISTS /dev/bpf )
- #
- # Cloning BPF device.
- #
- set( PCAP_TYPE bpf )
- AC_DEFINE(HAVE_CLONING_BPF,1,[define if you have a cloning BPF device])
- elseif( EXISTS /dev/bpf0 )
- set( PCAP_TYPE bpf )
+ #
+ # Has the user explicitly specified a capture type?
+ #
+ if(PCAP_TYPE STREQUAL "")
#
- # XXX - many more BPF checks.
+ # Check for a bunch of headers for various packet capture mechanisms.
#
- elseif( EXISTS /usr/include/net/pfilt.h )
+ 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")
#
- # DEC OSF/1, Digital UNIX, Tru64 UNIX
+ # Needed for common functions used by pcap-[dlpi,libdlpi].c
#
- set( PCAP_TYPE pf )
- elseif( EXISTS /dev/enet )
- set( PCAP_TYPE enet )
- elseif( EXISTS /dev/nit )
- set( PCAP_TYPE snit )
- elseif( EXISTS /usr/include/sys/net/nit.h )
- set( PCAP_TYPE nit )
- elseif( EXISTS /usr/include/linux/socket.h )
- set( PCAP_TYPE linux )
+ set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} dlpisubs.c)
- #
- # Do we have the wireless extensions?
- #
- check_include_file( linux/wireless.h HAVE_LINUX_WIRELESS_H )
+ #
+ # 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()
#
- # XXX - many more Linux checks.
- #
- elseif( EXISTS /usr/include/net/raw.h )
- set( PCAP_TYPE snoop )
- elseif( EXISTS /usr/include/odmi.h )
+ # This check is for Solaris with DLPI support for passive modes.
+ # See dlpi(7P) for more details.
#
- # 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.
+ # 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.
#
- set( PCAP_TYPE bpf )
- elseif( /usr/include/sys/dlpi.h )
- set( PCAP_TYPE dlpi )
+ 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")
#
- # XXX - many more DLPI checks.
+ # 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()
- set( PCAP_TYPE null )
+ message(FATAL_ERROR "${PCAP_TYPE} is not a valid pcap type")
endif()
-endif( WIN32 )
-message(STATUS "Packet capture mechanism type: ${PCAP_TYPE}")
+endif(WIN32)
+
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-${PCAP_TYPE}.c)
#
@@ -274,31 +1188,54 @@ set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-${PCAP_TYPE}.c)
# if we support capturing. Don't bother if we don't support
# capturing.
#
-if( NOT WIN32 )
+if(NOT WIN32)
#
# UN*X - figure out what type of interface list mechanism we
# have.
#
- if( ${PCAP_TYPE} STREQUAL "null" )
- #
- # We can't capture, so we can't open any capture
- # devices, so we won't return any interfaces.
- #
- set( FINDALLDEVS_TYPE null )
- else()
- check_function_exists( getifaddrs HAVE_GETIFADDRS )
- if( ${HAVE_GETIFADDRS} )
+ # 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_file( ifaddrs.h HAVE_IFADDRS_H )
- if( ${HAVE_IFADDRS_H} )
+ 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 )
+ set(FINDALLDEVS_TYPE getad)
else()
#
# We don't have the header - give up.
@@ -309,60 +1246,491 @@ if( NOT WIN32 )
# 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>." )
+ message(FATAL_ERROR "Your system has getifaddrs() but doesn't have a usable <ifaddrs.h>.")
endif()
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.
#
- if( ${PCAP_TYPE} STREQUAL "dlpi" OR ${PCAP_TYPE} STREQUAL "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.
- #
- try_compile( HAVE_SIOCGLIFCONF ${CMAKE_CURRENT_BINARY_DIR} "${pcap_SOURCE_DIR}/config/have_siocglifconf.c" )
- message( STATUS "HAVE_SIOCGLIFCONF = ${HAVE_SIOCGLIFCONF}" )
- if( HAVE_SIOCGLIFCONF )
- set( FINDALLDEVS_TYPE glifc )
- else()
- set( FINDALLDEVS_TYPE gifc )
- endif()
+ # 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)
#
- # Assume we just have SIOCGIFCONF.
- # (XXX - on at least later Linux kernels, there's
- # another mechanism, and we should be using that
- # instead.)
+ # OK, is HCI_CHANNEL_MONITOR defined?
#
- set( FINDALLDEVS_TYPE gifc )
+ 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()
- message(STATUS "Find-interfaces mechanism type: ${FINDALLDEVS_TYPE}")
- set( PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} fad-${FINDALLDEVS_TYPE}.c )
endif()
-file(GLOB PROJECT_SOURCE_LIST_CORE_H
+# 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
)
-set( PROJECT_SOURCE_LIST_H ${PROJECT_SOURCE_LIST_H} ${PROJECT_SOURCE_LIST_CORE_H} )
-if( WIN32 )
- file(GLOB PROJECT_SOURCE_LIST_WIN32_H
- Win32/Include/*.h
- )
- set( PROJECT_SOURCE_LIST_H ${PROJECT_SOURCE_LIST_H} ${PROJECT_SOURCE_LIST_WIN32_H} )
-endif( WIN32 )
+#
+# 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} and YACC/Berkeley YACC/Bison.
+# Flex/Lex and YACC/Berkeley YACC/Bison.
# From a mail message to the CMake mailing list by Andy Cedilnik of
# Kitware.
#
@@ -371,8 +1739,8 @@ endif( WIN32 )
# 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." )
+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}")
@@ -391,7 +1759,7 @@ add_custom_command(
#
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/scanner.c PROPERTIES
GENERATED TRUE
- OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/scanner.h
+ OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/grammar.h
)
#
@@ -403,19 +1771,19 @@ set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/scanner.c PROPERTIES
# 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." )
+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 notby looking at the last component
+# 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" )
+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
@@ -430,6 +1798,7 @@ add_custom_command(
#
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/grammar.c PROPERTIES
GENERATED TRUE
+ OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/scanner.h
)
#
@@ -437,84 +1806,491 @@ set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/grammar.c PROPERTIES
#
#set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} ${CMAKE_CURRENT_BINARY_DIR}/grammar.c)
-if( WIN32 )
+#
+# 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()
+
#
- # CMake does not love Windows.
+ # Use System V conventions for man pages.
#
- file(TO_NATIVE_PATH "${pcap_SOURCE_DIR}/GenVersion.bat" GenVersion_path)
- file(TO_NATIVE_PATH "${pcap_SOURCE_DIR}/VERSION" VERSION_path)
- file(TO_NATIVE_PATH "${pcap_SOURCE_DIR}/pcap_version.h.in" version_h_in_path)
- file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/pcap_version.h" version_h_path)
- add_custom_command(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pcap_version.h
- SOURCE ${pcap_SOURCE_DIR}/VERSION ${pcap_SOURCE_DIR}/pcap_version.h.in
- COMMAND ${GenVersion_path} ${VERSION_path} ${version_h_in_path} ${version_h_path}
- DEPENDS ${pcap_SOURCE_DIR}/VERSION ${pcap_SOURCE_DIR}/pcap_version.h.in
- )
-else( WIN32 )
- add_custom_command(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/version.c
- SOURCE ${pcap_SOURCE_DIR}/VERSION
- COMMAND ${pcap_SOURCE_DIR}/gen_version_c.sh ${pcap_SOURCE_DIR}/VERSION ${CMAKE_CURRENT_BINARY_DIR}/version.c
- DEPENDS ${pcap_SOURCE_DIR}/VERSION
- )
- add_custom_command(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pcap_version.h
- SOURCE ${pcap_SOURCE_DIR}/VERSION
- COMMAND ${pcap_SOURCE_DIR}/gen_version_header.sh ${pcap_SOURCE_DIR}/VERSION ${pcap_SOURCE_DIR}/pcap_version.h.in ${CMAKE_CURRENT_BINARY_DIR}/pcap_version.h
- DEPENDS ${pcap_SOURCE_DIR}/VERSION
- )
-
+ 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")
#
- # Since version.c does not exists yet when cmake is run, mark
- # it as generated.
+ # 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_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/version.c PROPERTIES
- GENERATED TRUE
- )
+ 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 version.c to the list of sources.
+ # Add pcap-dll.rc to the list of sources.
#
- set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} ${CMAKE_CURRENT_BINARY_DIR}/version.c)
-endif( WIN32 )
+ set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} ${pcap_SOURCE_DIR}/pcap-dll.rc)
+endif(WIN32)
#
-# Since pcap_version.h does not exists yet when cmake is run, mark
-# it as generated.
+# Add subdirectories after we've set various variables, so they pick up
+# pick up those variables.
#
-set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/pcap_version.h PROPERTIES
- GENERATED TRUE
-)
+if(ENABLE_REMOTE)
+ add_subdirectory(rpcapd)
+endif(ENABLE_REMOTE)
+add_subdirectory(testprogs)
+
+######################################
+# Register targets
+######################################
#
-# Add pcap_version.h to the list of headers.
+# Special target to serialize the building of the generated source.
#
-set(PROJECT_SOURCE_LIST_H ${PROJECT_SOURCE_LIST_H} ${CMAKE_CURRENT_BINARY_DIR}/pcap_version.h)
+# 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
+)
-source_group("Source Files" FILES ${PROJECT_SOURCE_LIST_C})
-source_group("Header Files" FILES ${PROJECT_SOURCE_LIST_H})
+set_source_files_properties(${PROJECT_EXTERNAL_OBJECT_LIST} PROPERTIES
+ EXTERNAL_OBJECT TRUE)
-######################################
-# Register targets
-######################################
+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}
+add_library(${LIBRARY_NAME}_static STATIC
${PROJECT_SOURCE_LIST_C}
${CMAKE_CURRENT_BINARY_DIR}/grammar.c
${CMAKE_CURRENT_BINARY_DIR}/scanner.c
- ${PROJECT_SOURCE_LIST_H}
+ ${PROJECT_EXTERNAL_OBJECT_LIST}
)
+add_dependencies(${LIBRARY_NAME}_static SerializeTarget)
+set_target_properties(${LIBRARY_NAME}_static PROPERTIES
+ COMPILE_DEFINITIONS BUILDING_PCAP)
-if( WIN32 )
- target_link_libraries ( ${LIBRARY_NAME}
- packet
- ws2_32
+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 )
+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_linux.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)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pcap-bpf.h DESTINATION include)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pcap-namedb.h DESTINATION include)
+
+# On UN*X, and on Windows when not using MSVC, generate libpcap.pc and
+# pcap-config and process man pages and arrange that they be installed.
+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/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000..69b59726
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -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](https://www.tcpdump.org/#mailing-lists)
+to the mailing list tcpdump-workers@lists.tcpdump.org and ask!
diff --git a/CREDITS b/CREDITS
index b40152f5..8b7e7ce8 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1,21 +1,18 @@
-This file lists people who have contributed to libpcap:
+This file lists people who have contributed to libpcap.
-The current maintainers:
- Bill Fenner <fenner at research dot att dot com>
+The current maintainers (in alphabetical order):
Denis Ovsienko <denis at ovsienko dot info>
- Fulvio Risso <risso at polito dot it>
+ Francois-Xavier Le Bail <devel dot fx dot lebail at orange dot fr>
Guy Harris <guy at alum dot mit dot edu>
- Hannes Gredler <hannes at juniper dot net>
Michael Richardson <mcr at sandelman dot ottawa dot on dot ca>
- Francois-Xavier Le Bail <fx dot lebail at yahoo dot com>
-
-Additional people who have contributed patches:
+Additional people who have contributed patches (in alphabetical order):
Akos Vandra <axos88 at gmail dot com>
Alan Bawden <Alan at LCS dot MIT dot EDU>
Albert Chin <china at thewrittenword dot com>
Alexander 'Leo' Bergolth <Leo dot Bergolth at wu-wien dot ac dot at>
Alexey Kuznetsov <kuznet at ms2 dot inr dot ac dot ru>
+ Ali Abdulkadir <autostart dot ini at gmail dot com>
Alon Bar-Lev <alonbl at sourceforge dot net>
Andres Perera <andres dot p at zoho dot com>
Andrew Brown <atatat at atatdot dot net>
@@ -62,9 +59,10 @@ Additional people who have contributed patches:
Gabor Tatarka <gabor dot tatarka at ericsson dot com>
Garrett Cooper <yaberauneya at sourceforge dot net>
George Neville-Neil <gnn at freebsd dot org>
+ Gerard Garcia <nouboh at gmail dot com>
Gianluca Varenni <gianluca dot varenni at gmail dot com>
Gilbert Hoyek <gil_hoyek at hotmail dot com>
- Gisle Vanem <gvanem at 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>
@@ -99,6 +97,7 @@ Additional people who have contributed patches:
Koryn Grant <koryn at endace dot com>
Kris Katterjohn <katterjohn at gmail dot com>
Krzysztof Halasa <khc at pm dot waw dot pl>
+ Lennert Buytenhek <buytenh at wantstofly dot org>
Lorenzo Cavallaro <sullivan at sikurezza dot org>
Loris Degioanni <loris at netgroup-serv dot polito dot it>
Love Hörnquist-Åstrand <lha at stacken dot kth dot se>
@@ -114,6 +113,7 @@ Additional people who have contributed patches:
Márton Németh <nm127 at freemail dot hu>
Matthew Luckie <mjl at luckie dot org dot nz>
Max Laier <max at love2party dot net>
+ Michal Kubecek <mkubecek at suse dot cz>
Michal Labedzki <michal dot labedzki at tieto dot com>
Michal Sekletar <msekleta at redhat dot com>
Mike Frysinger <vapier at gmail dot com>
@@ -129,7 +129,7 @@ Additional people who have contributed patches:
Olaf Kirch <okir at caldera dot de>
Ollie Wild <aaw at users dot sourceforge dot net>
Onno van der Linden <onno at simplex dot nl>
- Paolo Abeni <paolo dot abeni at email dot it>
+ Paolo Abeni <paolo dot abeni at email dot it> and redhat dot com
Patrick Marie <mycroft at virgaria dot org>
Patrick McHardy <kaber at trash not net>
Paul Mundt <lethal at linux-sh dot org>
@@ -145,6 +145,8 @@ Additional people who have contributed patches:
Rick Jones <raj at cup dot hp dot com>
Robert Edmonds <stu-42 at sourceforge dot net>
Roberto Mariani <jelot-tcpdump at jelot dot it>
+ Rongxi Li <rongxi dot li at chaitin dot com>
+ Roland Dreier <roland at purestorage dot com>
Romain Francoise <rfrancoise at debian dot org>
Sagun Shakya <sagun dot shakya at sun dot com>
Scott Barron <sb125499 at ohiou dot edu>
@@ -167,6 +169,7 @@ Additional people who have contributed patches:
Wesley Shields <wxs at FreeBSD dot org>
Xianjie Zhang <xzhang at cup dot hp dot com>
Xin Li <delphij at FreeBSD dot org>
+ Xue Jiang Qing <xuejianqing at star-net dot cn>
Yen Yen Lim
Yoann Vandoorselaere <yoann at prelude-ids dot org>
Yvan Vanhullebus <vanhu at sourceforge dot net>
@@ -176,5 +179,8 @@ The original LBL crew:
Craig Leres
Van Jacobson
-Past maintainers:
- Jun-ichiro itojun Hagino <itojun at iijlab dot net> Also see: http://www.wide.ad.jp/itojun-award/
+Past maintainers (in alphabetical order):
+ Bill Fenner <fenner at research dot att dot com>
+ Fulvio Risso <risso at polito dot it>
+ Hannes Gredler <hannes at gredler dot at>
+ Jun-ichiro itojun Hagino <itojun at iijlab dot net> Also see: http://www.wide.ad.jp/itojun-award/
diff --git a/GenVersion.bat b/GenVersion.bat
deleted file mode 100644
index babf3737..00000000
--- a/GenVersion.bat
+++ /dev/null
@@ -1,23 +0,0 @@
-REM
-REM Automatically generate pcap_version.h based on pcap_version.h.in
-REM for Windows
-REM The version string comes from VERSION
-REM @echo off
-REM
-
-setlocal enableextensions disabledelayedexpansion
-
-set "search=%%%%LIBPCAP_VERSION%%%%"
-set /p replace=<%1
-
-if exist %3 del %3 2>nul
-
-for /f "delims=" %%i in ('type %2' ) do (
- set "line=%%i"
- setlocal enabledelayedexpansion
- set "line=!line:%search%=%replace%!"
- >>%3 echo(!line!
- endlocal
-)
-
-echo pcap_version.h generated
diff --git a/INSTALL.txt b/INSTALL.md
index f305aa2b..96c87a2c 100644
--- a/INSTALL.txt
+++ b/INSTALL.md
@@ -69,10 +69,6 @@ before /usr/ucb or else:
before running configure. (You might have to do a "make distclean"
if you already ran configure once).
-Also note that "make depend" won't work; while all of the known
-universe uses -M, the SPARCompiler uses -xM to generate makefile
-dependencies.
-
If you are trying to do packet capture with a FORE ATM card, you may or
may not be able to. They usually only release their driver in object
code so unless their driver supports packet capture, there's not much
@@ -250,43 +246,27 @@ 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
+INSTALL.md - this file
LICENSE - the license under which tcpdump is distributed
Makefile.in - compilation rules (input to the configure script)
-README - description of distribution
-README.aix - notes on using libpcap on AIX
-README.dag - notes on using libpcap to capture on Endace DAG devices
-README.hpux - notes on using libpcap on HP-UX
-README.linux - notes on using libpcap on Linux
-README.macosx - notes on using libpcap on Mac OS X
-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
+README.md - description of distribution
+doc/README.aix - notes on using libpcap on AIX
+doc/README.dag - notes on using libpcap to capture on Endace DAG devices
+doc/README.hpux - notes on using libpcap on HP-UX
+doc/README.linux.md - notes on using libpcap on Linux
+doc/README.macos - notes on using libpcap on macOS
+doc/README.septel - notes on using libpcap to capture on Intel/Septel devices
+doc/README.sita - notes on using libpcap to capture on SITA devices
+doc/README.tru64 - notes on using libpcap on Digital/Tru64 UNIX
+doc/README.Win32 - notes on using libpcap on Win32 systems (with WinPcap)
VERSION - version of this release
acconfig.h - support for post-2.13 autoconf
aclocal.m4 - autoconf macros
@@ -314,7 +294,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 +326,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 +340,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/METADATA b/METADATA
new file mode 100644
index 00000000..36f21c34
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,18 @@
+name: "libpcap"
+description: "A system-independent interface for user-level packet capture."
+third_party {
+ url {
+ type: HOMEPAGE
+ value: "https://www.tcpdump.org/"
+ }
+ url {
+ type: ARCHIVE
+ value: "https://github.com/the-tcpdump-group/libpcap/archive/libpcap-1.9.0.tar.gz"
+ }
+ version: "libcap-1.9.0"
+ last_upgrade_date {
+ year: 2018
+ month: 7
+ day: 22
+ }
+}
diff --git a/Makefile.in b/Makefile.in
index e71d973c..dff75ec1 100644
--- a/Makefile.in
+++ b/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_linux.3pcap \
pcap_set_rfmon.3pcap \
pcap_set_snaplen.3pcap \
pcap_set_timeout.3pcap \
@@ -231,38 +230,31 @@ MANMISC = \
pcap-tstamp.manmisc.in
EXTRA_DIST = \
- $(TESTS_SRC) \
CHANGES \
ChmodBPF/ChmodBPF \
ChmodBPF/StartupParameters.plist \
CREDITS \
CMakeLists.txt \
- GenVersion.bat \
- INSTALL.txt \
+ INSTALL.md \
LICENSE \
Makefile.in \
Makefile-devel-adds \
- README \
- README.aix \
- README.dag \
- README.hpux \
- README.linux \
- README.macosx \
- 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 \
+ README.md \
+ doc \
+ CONTRIBUTING.md \
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 +265,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 +275,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 +283,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 +303,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 +315,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 +338,48 @@ 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.c \
+ 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 +392,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 +453,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 +474,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 +483,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 +507,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 +525,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 +559,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 +662,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 +718,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)
@@ -742,11 +744,13 @@ tags: $(TAGFILES)
releasetar:
@cwd=`pwd` ; dir=`basename $$cwd` ; name=$(PROG)-`cat VERSION` ; \
mkdir $$name; \
- tar cf - $(CSRC) $(HDR) $(MAN1) $(MAN3PCAP_EXPAND) \
+ tar -c --exclude='*~' -f - $(CSRC) $(HDR) $(MAN1) $(MAN3PCAP_EXPAND) \
$(MAN3PCAP_NOEXPAND) $(MANFILE) $(MANMISC) $(EXTRA_DIST) | \
(cd $$name; tar xf -); \
tar -c -z -f $$name.tar.gz $$name; \
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/README b/README.md
index 9f65948d..78cc3c4b 100644
--- a/README
+++ b/README.md
@@ -1,18 +1,18 @@
-LIBPCAP 1.x.y
-
-www.tcpdump.org
-
-Please send inquiries/comments/reports to:
- tcpdump-workers@lists.tcpdump.org
+To report a security issue please send an e-mail to security@tcpdump.org.
-Anonymous Git is available via:
- git clone git://bpf.tcpdump.org/libpcap
+To report bugs and other problems, contribute patches, request a
+feature, provide generic feedback etc please see the file
+[CONTRIBUTING](CONTRIBUTING.md) in the libpcap source tree root.
-Please submit patches by forking the branch on GitHub at
+The directory doc/ has README files about specific operating systems and
+options.
- http://github.com/the-tcpdump-group/libpcap/tree/master
+LIBPCAP 1.x.y
+Now maintained by "The Tcpdump Group"
+https://www.tcpdump.org
-and issuing a pull request.
+Anonymous Git is available via:
+ https://github.com/the-tcpdump-group/libpcap.git
formerly from Lawrence Berkeley National Laboratory
Network Research Group <libpcap@ee.lbl.gov>
@@ -43,15 +43,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,17 +62,18 @@ 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
-information on configuring that option.
+Linux has a number of BPF based systems, and libpcap does not support
+any of the eBPF mechanisms as yet, although it supports many of the
+memory mapped receive mechanisms.
+See the [README.linux](doc/README.linux.md) file for more information.
Note to Linux distributions and *BSD systems that include libpcap:
@@ -87,20 +88,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/README.version b/README.version
deleted file mode 100644
index 256063e1..00000000
--- a/README.version
+++ /dev/null
@@ -1,2 +0,0 @@
-URL: http://www.tcpdump.org/release/libpcap-1.8.1.tar.gz
-Version: 1.8.1
diff --git a/SUNOS4/nit_if.o.sparc b/SUNOS4/nit_if.o.sparc
deleted file mode 100644
index d05073ea..00000000
--- a/SUNOS4/nit_if.o.sparc
+++ /dev/null
Binary files differ
diff --git a/SUNOS4/nit_if.o.sun3 b/SUNOS4/nit_if.o.sun3
deleted file mode 100644
index c393fc6e..00000000
--- a/SUNOS4/nit_if.o.sun3
+++ /dev/null
Binary files differ
diff --git a/SUNOS4/nit_if.o.sun4c.4.0.3c b/SUNOS4/nit_if.o.sun4c.4.0.3c
deleted file mode 100644
index ef010392..00000000
--- a/SUNOS4/nit_if.o.sun4c.4.0.3c
+++ /dev/null
Binary files differ
diff --git a/VERSION b/VERSION
index a8fdfda1..f8e233b2 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.8.1
+1.9.0
diff --git a/Win32/Include/Gnuc.h b/Win32/Include/Gnuc.h
deleted file mode 100644
index e1b5951d..00000000
--- a/Win32/Include/Gnuc.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* inline foo */
-#ifndef __cplusplus
-#ifdef __GNUC__
-#define inline __inline
-#else
-#define inline
-#endif
-#endif
diff --git a/Win32/Include/net/if.h b/Win32/Include/net/if.h
deleted file mode 100644
index 58d3c16e..00000000
--- a/Win32/Include/net/if.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1989, 1993
- * 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 University of
- * California, Berkeley and its contributors.
- * 4. 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 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.
- *
- * @(#)if.h 8.1 (Berkeley) 6/10/93
- * $FreeBSD: src/sys/net/if.h,v 1.49.2.1 1999/08/29 16:28:15 peter Exp $
- */
-
-#ifndef _NET_IF_H_
-#define _NET_IF_H_
-
-/*
- * <net/if.h> does not depend on <sys/time.h> on most other systems. This
- * helps userland compatability. (struct timeval ifi_lastchange)
- */
-#ifndef KERNEL
-#include <pcap-stdinc.h>
-#endif
-
-/*
- * Structure describing information about an interface
- * which may be of interest to management entities.
- */
-struct if_data {
- /* generic interface information */
- u_char ifi_type; /* ethernet, tokenring, etc */
- u_char ifi_physical; /* e.g., AUI, Thinnet, 10base-T, etc */
- u_char ifi_addrlen; /* media address length */
- u_char ifi_hdrlen; /* media header length */
- u_char ifi_recvquota; /* polling quota for receive intrs */
- u_char ifi_xmitquota; /* polling quota for xmit intrs */
- u_long ifi_mtu; /* maximum transmission unit */
- u_long ifi_metric; /* routing metric (external only) */
- u_long ifi_baudrate; /* linespeed */
- /* volatile statistics */
- u_long ifi_ipackets; /* packets received on interface */
- u_long ifi_ierrors; /* input errors on interface */
- u_long ifi_opackets; /* packets sent on interface */
- u_long ifi_oerrors; /* output errors on interface */
- u_long ifi_collisions; /* collisions on csma interfaces */
- u_long ifi_ibytes; /* total number of octets received */
- u_long ifi_obytes; /* total number of octets sent */
- u_long ifi_imcasts; /* packets received via multicast */
- u_long ifi_omcasts; /* packets sent via multicast */
- u_long ifi_iqdrops; /* dropped on input, this interface */
- u_long ifi_noproto; /* destined for unsupported protocol */
- u_long ifi_recvtiming; /* usec spent receiving when timing */
- u_long ifi_xmittiming; /* usec spent xmitting when timing */
- struct timeval ifi_lastchange; /* time of last administrative change */
-};
-
-/* ws2tcpip.h has interface flags: IFF_* */
-#if 0
-#define IFF_UP 0x1 /* interface is up */
-#define IFF_BROADCAST 0x2 /* broadcast address valid */
-#define IFF_DEBUG 0x4 /* turn on debugging */
-#define IFF_LOOPBACK 0x8 /* is a loopback net */
-#define IFF_POINTOPOINT 0x10 /* interface is point-to-point link */
-/*#define IFF_NOTRAILERS 0x20 * obsolete: avoid use of trailers */
-#define IFF_RUNNING 0x40 /* resources allocated */
-#define IFF_NOARP 0x80 /* no address resolution protocol */
-#define IFF_PROMISC 0x100 /* receive all packets */
-#define IFF_ALLMULTI 0x200 /* receive all multicast packets */
-#define IFF_OACTIVE 0x400 /* transmission in progress */
-#define IFF_SIMPLEX 0x800 /* can't hear own transmissions */
-#define IFF_LINK0 0x1000 /* per link layer defined bit */
-#define IFF_LINK1 0x2000 /* per link layer defined bit */
-#define IFF_LINK2 0x4000 /* per link layer defined bit */
-#define IFF_ALTPHYS IFF_LINK2 /* use alternate physical connection */
-#define IFF_MULTICAST 0x8000 /* supports multicast */
-#endif /* 0 */
-
-/* flags set internally only: */
-#define IFF_CANTCHANGE \
- (IFF_BROADCAST|IFF_POINTOPOINT|IFF_RUNNING|IFF_OACTIVE|\
- IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI)
-
-#define IFQ_MAXLEN 50
-#define IFNET_SLOWHZ 1 /* granularity is 1 second */
-
-/*
- * Message format for use in obtaining information about interfaces
- * from getkerninfo and the routing socket
- */
-struct if_msghdr {
- u_short ifm_msglen; /* to skip over non-understood messages */
- u_char ifm_version; /* future binary compatability */
- u_char ifm_type; /* message type */
- int ifm_addrs; /* like rtm_addrs */
- int ifm_flags; /* value of if_flags */
- u_short ifm_index; /* index for associated ifp */
- struct if_data ifm_data;/* statistics and other data about if */
-};
-
-/*
- * Message format for use in obtaining information about interface addresses
- * from getkerninfo and the routing socket
- */
-struct ifa_msghdr {
- u_short ifam_msglen; /* to skip over non-understood messages */
- u_char ifam_version; /* future binary compatability */
- u_char ifam_type; /* message type */
- int ifam_addrs; /* like rtm_addrs */
- int ifam_flags; /* value of ifa_flags */
- u_short ifam_index; /* index for associated ifp */
- int ifam_metric; /* value of ifa_metric */
-};
-
-/*
- * Message format for use in obtaining information about multicast addresses
- * from the routing socket
- */
-struct ifma_msghdr {
- u_short ifmam_msglen; /* to skip over non-understood messages */
- u_char ifmam_version; /* future binary compatability */
- u_char ifmam_type; /* message type */
- int ifmam_addrs; /* like rtm_addrs */
- int ifmam_flags; /* value of ifa_flags */
- u_short ifmam_index; /* index for associated ifp */
-};
-
-/*
- * Interface request structure used for socket
- * ioctl's. All interface ioctl's must have parameter
- * definitions which begin with ifr_name. The
- * remainder may be interface specific.
- */
-struct ifreq {
-#define IFNAMSIZ 16
- char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
- union {
- struct sockaddr ifru_addr;
- struct sockaddr ifru_dstaddr;
- struct sockaddr ifru_broadaddr;
- short ifru_flags;
- int ifru_metric;
- int ifru_mtu;
- int ifru_phys;
- int ifru_media;
- caddr_t ifru_data;
- } ifr_ifru;
-#define ifr_addr ifr_ifru.ifru_addr /* address */
-#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
-#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
-#define ifr_flags ifr_ifru.ifru_flags /* flags */
-#define ifr_metric ifr_ifru.ifru_metric /* metric */
-#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
-#define ifr_phys ifr_ifru.ifru_phys /* physical wire */
-#define ifr_media ifr_ifru.ifru_media /* physical media */
-#define ifr_data ifr_ifru.ifru_data /* for use by interface */
-};
-
-#define _SIZEOF_ADDR_IFREQ(ifr) \
- ((ifr).ifr_addr.sa_len > sizeof(struct sockaddr) ? \
- (sizeof(struct ifreq) - sizeof(struct sockaddr) + \
- (ifr).ifr_addr.sa_len) : sizeof(struct ifreq))
-
-struct ifaliasreq {
- char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */
- struct sockaddr ifra_addr;
- struct sockaddr ifra_broadaddr;
- struct sockaddr ifra_mask;
-};
-
-struct ifmediareq {
- char ifm_name[IFNAMSIZ]; /* if name, e.g. "en0" */
- int ifm_current; /* current media options */
- int ifm_mask; /* don't care mask */
- int ifm_status; /* media status */
- int ifm_active; /* active options */
- int ifm_count; /* # entries in ifm_ulist array */
- int *ifm_ulist; /* media words */
-};
-/*
- * Structure used in SIOCGIFCONF request.
- * Used to retrieve interface configuration
- * for machine (useful for programs which
- * must know all networks accessible).
- */
-struct ifconf {
- int ifc_len; /* size of associated buffer */
- union {
- caddr_t ifcu_buf;
- struct ifreq *ifcu_req;
- } ifc_ifcu;
-#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
-#define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */
-};
-
-#ifdef KERNEL
-#ifdef MALLOC_DECLARE
-MALLOC_DECLARE(M_IFADDR);
-MALLOC_DECLARE(M_IFMADDR);
-#endif
-#endif
-
-/* XXX - this should go away soon */
-#ifdef KERNEL
-#include <net/if_var.h>
-#endif
-
-#endif /* !_NET_IF_H_ */
diff --git a/Win32/Prj/wpcap.vcxproj b/Win32/Prj/wpcap.vcxproj
index c923357a..43b7099b 100644
--- a/Win32/Prj/wpcap.vcxproj
+++ b/Win32/Prj/wpcap.vcxproj
@@ -100,7 +100,7 @@
<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;BUILDING_PCAP;HAVE_STRERROR;__STDC__;INET6;_WINDOWS;HAVE_ADDRINFO;HAVE_REMOTE;WIN32;_U_=;YY_NO_UNISTD_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <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>
@@ -125,7 +125,7 @@ win_bison -ppcap_ --yacc --output=..\..\grammar.c --defines ..\..\grammar.y</Com
<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;BUILDING_PCAP;HAVE_STRERROR;__STDC__;INET6;_WINDOWS;HAVE_ADDRINFO;HAVE_REMOTE;WIN32;_U_=;YY_NO_UNISTD_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <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>
@@ -151,7 +151,7 @@ win_bison -ppcap_ --yacc --output=..\..\grammar.c --defines ..\..\grammar.y</Com
<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;BUILDING_PCAP;HAVE_STRERROR;__STDC__;INET6;_WINDOWS;HAVE_ADDRINFO;HAVE_REMOTE;WIN32;_U_=;YY_NO_UNISTD_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <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>
@@ -177,7 +177,7 @@ win_bison -ppcap_ --yacc --output=..\..\grammar.c --defines ..\..\grammar.y</Com
<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;BUILDING_PCAP;HAVE_STRERROR;__STDC__;INET6;_WINDOWS;HAVE_ADDRINFO;HAVE_REMOTE;WIN32;_U_=;YY_NO_UNISTD_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <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>
@@ -198,7 +198,6 @@ win_bison -ppcap_ --yacc --output=..\..\grammar.c --defines ..\..\grammar.y</Com
<ClCompile Include="..\..\bpf_dump.c" />
<ClCompile Include="..\..\bpf_image.c" />
<ClCompile Include="..\..\etherent.c" />
- <ClCompile Include="..\..\fad-helpers.c" />
<ClCompile Include="..\..\gencode.c" />
<ClCompile Include="..\..\grammar.c" />
<ClCompile Include="..\..\inet.c" />
@@ -212,7 +211,7 @@ win_bison -ppcap_ --yacc --output=..\..\grammar.c --defines ..\..\grammar.y</Com
<ClCompile Include="..\..\pcap.c" />
<ClCompile Include="..\..\savefile.c" />
<ClCompile Include="..\..\scanner.c" />
- <ClCompile Include="..\..\sf-pcap-ng.c" />
+ <ClCompile Include="..\..\sf-pcapng.c" />
<ClCompile Include="..\..\sf-pcap.c" />
<ClCompile Include="..\..\sockutils.c" />
</ItemGroup>
@@ -231,4 +230,4 @@ win_bison -ppcap_ --yacc --output=..\..\grammar.c --defines ..\..\grammar.y</Com
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/Win32/Prj/wpcap.vcxproj.filters b/Win32/Prj/wpcap.vcxproj.filters
index 72f1492c..6e06ccbc 100644
--- a/Win32/Prj/wpcap.vcxproj.filters
+++ b/Win32/Prj/wpcap.vcxproj.filters
@@ -43,7 +43,7 @@
<ClCompile Include="..\..\sf-pcap.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\sf-pcap-ng.c">
+ <ClCompile Include="..\..\sf-pcapng.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\pcap-common.c">
diff --git a/aclocal.m4 b/aclocal.m4
index 83f5761f..ac163d42 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -266,6 +266,14 @@ dnl Check whether the compiler option specified as the second argument
dnl is supported by the compiler and, if so, add it to the macro
dnl specified as the first argument
dnl
+dnl If a third argument is supplied, treat it as C code to be compiled
+dnl with the flag in question, and the "treat warnings as errors" flag
+dnl set, and don't add the flag to the first argument if the compile
+dnl fails; this is for warning options cause problems that can't be
+dnl worked around. If a third argument is supplied, a fourth argument
+dnl should also be supplied; it's a message desribing what the test
+dnl program is checking.
+dnl
AC_DEFUN(AC_LBL_CHECK_COMPILER_OPT,
[
AC_MSG_CHECKING([whether the compiler supports the $2 option])
@@ -287,8 +295,38 @@ AC_DEFUN(AC_LBL_CHECK_COMPILER_OPT,
[return 0],
[
AC_MSG_RESULT([yes])
+ can_add_to_cflags=yes
+ #
+ # The compile supports this; do we have some C code for
+ # which the warning should *not* appear?
+ # We test the fourth argument because the third argument
+ # could contain quotes, breaking the test.
+ #
+ if test "x$4" != "x"
+ then
+ CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
+ AC_MSG_CHECKING(whether $2 $4)
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE($3)],
+ [
+ #
+ # Not a problem.
+ #
+ AC_MSG_RESULT(no)
+ ],
+ [
+ #
+ # A problem.
+ #
+ AC_MSG_RESULT(yes)
+ can_add_to_cflags=no
+ ])
+ fi
CFLAGS="$save_CFLAGS"
- $1="$$1 $2"
+ if test x"$can_add_to_cflags" = "xyes"
+ then
+ $1="$$1 $2"
+ fi
],
[
AC_MSG_RESULT([no])
@@ -384,8 +422,7 @@ AC_DEFUN(AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT,
if test ! -z "$ac_lbl_dependency_flag"; then
AC_LANG_CONFTEST(
[AC_LANG_SOURCE([[int main(void) { return 0; }]])])
- echo "$CC" $ac_lbl_dependency_flag conftest.c >&5
- if "$CC" $ac_lbl_dependency_flag conftest.c >/dev/null 2>&1; then
+ 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'
@@ -395,7 +432,7 @@ AC_DEFUN(AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT,
# We can't run mkdep, so have "make depend" do
# nothing.
#
- MKDEP=:
+ MKDEP='${srcdir}/nomkdep'
fi
rm -rf conftest*
else
@@ -404,7 +441,7 @@ AC_DEFUN(AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT,
# We can't run mkdep, so have "make depend" do
# nothing.
#
- MKDEP=:
+ MKDEP='${srcdir}/nomkdep'
fi
AC_SUBST(DEPENDENCY_CFLAG)
AC_SUBST(MKDEP)
@@ -419,7 +456,7 @@ dnl AC_LBL_SHLIBS_INIT
dnl
dnl results:
dnl
-dnl V_CCOPT (modified to build position-independent code)
+dnl V_SHLIB_CCOPT (modified to build position-independent code)
dnl V_SHLIB_CMD
dnl V_SHLIB_OPT
dnl V_SONAME_OPT
@@ -432,7 +469,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
# 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;
@@ -470,13 +507,13 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
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"
@@ -492,7 +529,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
;;
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.
@@ -507,7 +544,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
# 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;
@@ -533,7 +570,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
#
# "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,"
@@ -541,7 +578,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
;;
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 "
@@ -564,7 +601,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
;;
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 "
@@ -691,90 +728,6 @@ AC_DEFUN(AC_LBL_UNION_WAIT,
fi])
dnl
-dnl Checks to see if the sockaddr struct has the 4.4 BSD sa_len member
-dnl
-dnl usage:
-dnl
-dnl AC_LBL_SOCKADDR_SA_LEN
-dnl
-dnl results:
-dnl
-dnl HAVE_SOCKADDR_SA_LEN (defined)
-dnl
-AC_DEFUN(AC_LBL_SOCKADDR_SA_LEN,
- [AC_MSG_CHECKING(if sockaddr struct has the sa_len member)
- AC_CACHE_VAL(ac_cv_lbl_sockaddr_has_sa_len,
- AC_TRY_COMPILE([
-# include <sys/types.h>
-# include <sys/socket.h>],
- [u_int i = sizeof(((struct sockaddr *)0)->sa_len)],
- ac_cv_lbl_sockaddr_has_sa_len=yes,
- ac_cv_lbl_sockaddr_has_sa_len=no))
- AC_MSG_RESULT($ac_cv_lbl_sockaddr_has_sa_len)
- if test $ac_cv_lbl_sockaddr_has_sa_len = yes ; then
- AC_DEFINE(HAVE_SOCKADDR_SA_LEN,1,[if struct sockaddr has the sa_len member])
- fi])
-
-dnl
-dnl Checks to see if there's a sockaddr_storage structure
-dnl
-dnl usage:
-dnl
-dnl AC_LBL_SOCKADDR_STORAGE
-dnl
-dnl results:
-dnl
-dnl HAVE_SOCKADDR_STORAGE (defined)
-dnl
-AC_DEFUN(AC_LBL_SOCKADDR_STORAGE,
- [AC_MSG_CHECKING(if sockaddr_storage struct exists)
- AC_CACHE_VAL(ac_cv_lbl_has_sockaddr_storage,
- AC_TRY_COMPILE([
-# include <sys/types.h>
-# include <sys/socket.h>],
- [u_int i = sizeof (struct sockaddr_storage)],
- ac_cv_lbl_has_sockaddr_storage=yes,
- ac_cv_lbl_has_sockaddr_storage=no))
- AC_MSG_RESULT($ac_cv_lbl_has_sockaddr_storage)
- if test $ac_cv_lbl_has_sockaddr_storage = yes ; then
- AC_DEFINE(HAVE_SOCKADDR_STORAGE,1,[if struct sockaddr_storage exists])
- fi])
-
-dnl
-dnl Checks to see if the dl_hp_ppa_info_t struct has the HP-UX 11.00
-dnl dl_module_id_1 member
-dnl
-dnl usage:
-dnl
-dnl AC_LBL_HP_PPA_INFO_T_DL_MODULE_ID_1
-dnl
-dnl results:
-dnl
-dnl HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1 (defined)
-dnl
-dnl NOTE: any compile failure means we conclude that it doesn't have
-dnl that member, so if we don't have DLPI, don't have a <sys/dlpi_ext.h>
-dnl header, or have one that doesn't declare a dl_hp_ppa_info_t type,
-dnl we conclude it doesn't have that member (which is OK, as either we
-dnl won't be using code that would use that member, or we wouldn't
-dnl compile in any case).
-dnl
-AC_DEFUN(AC_LBL_HP_PPA_INFO_T_DL_MODULE_ID_1,
- [AC_MSG_CHECKING(if dl_hp_ppa_info_t struct has dl_module_id_1 member)
- AC_CACHE_VAL(ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1,
- AC_TRY_COMPILE([
-# include <sys/types.h>
-# include <sys/dlpi.h>
-# include <sys/dlpi_ext.h>],
- [u_int i = sizeof(((dl_hp_ppa_info_t *)0)->dl_module_id_1)],
- ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1=yes,
- ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1=no))
- AC_MSG_RESULT($ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1)
- if test $ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1 = yes ; then
- AC_DEFINE(HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1,1,[if ppa_info_t_dl_module_id exists])
- fi])
-
-dnl
dnl Checks to see if -R is used
dnl
dnl usage:
@@ -932,6 +885,50 @@ AC_DEFUN(AC_LBL_DEVEL,
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)
+ #
+ # This can cause problems with ntohs(), ntohl(),
+ # htons(), and htonl() on some platforms, such
+ # as OpenBSD 6.3 with Clang 5.0.1. I guess the
+ # problem is that the macro that ultimately does
+ # the byte-swapping involves a conditional
+ # expression that tests whether the value being
+ # swapped is a compile-time constant or not,
+ # using __builtin_constant_p(), and, depending
+ # on whether it is, does a compile-time swap or
+ # a run-time swap; perhaps the compiler always
+ # considers one of the two results of the
+ # conditional expressin is never evaluated,
+ # because the conditional check is done at
+ # compile time, and thus always says "that
+ # expression is never executed".
+ #
+ # (Perhaps there should be a way of flagging
+ # an expression that you *want* evaluated at
+ # compile time, so that the compiler 1) warns
+ # if it *can't* be evaluated at compile time
+ # and 2) *doesn't* warn that the true or false
+ # branch will never be reached.)
+ #
+ AC_LBL_CHECK_COMPILER_OPT($1, -Wunreachable-code,
+ [
+#include <arpa/inet.h>
+
+unsigned short
+testme(unsigned short a)
+{
+ return ntohs(a);
+}
+ ],
+ [generates warnings from ntohs()])
fi
AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT()
#
@@ -1020,234 +1017,62 @@ fi
dnl
dnl AC_LBL_LIBRARY_NET
dnl
-dnl This test is for network applications that need socket() and
-dnl gethostbyname() -ish functions. Under Solaris, those applications
-dnl need to link with "-lsocket -lnsl". Under IRIX, they need to link
-dnl with "-lnsl" but should *not* link with "-lsocket" because
-dnl libsocket.a breaks a number of things (for instance:
-dnl gethostbyname() under IRIX 5.2, and snoop sockets under most
-dnl versions of IRIX).
-dnl
-dnl Unfortunately, many application developers are not aware of this,
-dnl and mistakenly write tests that cause -lsocket to be used under
-dnl IRIX. It is also easy to write tests that cause -lnsl to be used
-dnl under operating systems where neither are necessary (or useful),
-dnl such as SunOS 4.1.4, which uses -lnsl for TLI.
-dnl
-dnl This test exists so that every application developer does not test
-dnl this in a different, and subtly broken fashion.
-
-dnl It has been argued that this test should be broken up into two
-dnl seperate tests, one for the resolver libraries, and one for the
-dnl libraries necessary for using Sockets API. Unfortunately, the two
-dnl are carefully intertwined and allowing the autoconf user to use
-dnl them independantly potentially results in unfortunate ordering
-dnl dependancies -- as such, such component macros would have to
-dnl carefully use indirection and be aware if the other components were
-dnl executed. Since other autoconf macros do not go to this trouble,
-dnl and almost no applications use sockets without the resolver, this
-dnl complexity has not been implemented.
-dnl
-dnl The check for libresolv is in case you are attempting to link
-dnl statically and happen to have a libresolv.a lying around (and no
-dnl libnsl.a).
-dnl
-AC_DEFUN(AC_LBL_LIBRARY_NET, [
- # 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:
- AC_SEARCH_LIBS(gethostbyname, nsl socket resolv)
- # 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
- AC_CHECK_LIB(socket, gethostbyname,
- LIBS="-lsocket -lnsl $LIBS", , -lnsl)
- fi
- AC_SEARCH_LIBS(socket, socket, ,
- AC_CHECK_LIB(socket, socket, LIBS="-lsocket -lnsl $LIBS", , -lnsl))
- # DLPI needs putmsg under HPUX so test for -lstr while we're at it
- AC_SEARCH_LIBS(putmsg, str)
- ])
-
-dnl
-dnl Test for __attribute__
-dnl
-
-AC_DEFUN(AC_C___ATTRIBUTE__, [
-AC_MSG_CHECKING(for __attribute__)
-AC_CACHE_VAL(ac_cv___attribute__, [
-AC_COMPILE_IFELSE([
- AC_LANG_SOURCE([[
-#include <stdlib.h>
-
-static void foo(void) __attribute__ ((noreturn));
-
-static void
-foo(void)
-{
- exit(1);
-}
-
-int
-main(int argc, char **argv)
-{
- foo();
-}
- ]])],
-ac_cv___attribute__=yes,
-ac_cv___attribute__=no)])
-if test "$ac_cv___attribute__" = "yes"; then
- AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__])
-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_=\"\""
-fi
-AC_MSG_RESULT($ac_cv___attribute__)
-])
-
+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 Test whether __attribute__((unused)) can be used without warnings
+dnl On most operating systems, they're available in the system library.
dnl
-
-AC_DEFUN(AC_C___ATTRIBUTE___UNUSED, [
-AC_MSG_CHECKING([whether __attribute__((unused)) can be used without warnings])
-AC_CACHE_VAL(ac_cv___attribute___unused, [
-save_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
-AC_COMPILE_IFELSE([
- AC_LANG_SOURCE([[
-#include <stdlib.h>
-#include <stdio.h>
-
-int
-main(int argc __attribute((unused)), char **argv __attribute((unused)))
-{
- printf("Hello, world!\n");
- return 0;
-}
- ]])],
-ac_cv___attribute___unused=yes,
-ac_cv___attribute___unused=no)])
-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
-AC_MSG_RESULT($ac_cv___attribute___unused)
-])
-
+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 Test whether __attribute__((format)) can be used without warnings
+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)
-AC_DEFUN(AC_C___ATTRIBUTE___FORMAT, [
-AC_MSG_CHECKING([whether __attribute__((format)) can be used without warnings])
-AC_CACHE_VAL(ac_cv___attribute___format, [
-save_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
-AC_COMPILE_IFELSE([
- AC_LANG_SOURCE([[
-#include <stdlib.h>
-
-extern int foo(const char *fmt, ...)
- __attribute__ ((format (printf, 1, 2)));
-
-int
-main(int argc, char **argv)
-{
- foo("%s", "test");
-}
- ]])],
-ac_cv___attribute___format=yes,
-ac_cv___attribute___format=no)])
-CFLAGS="$save_CFLAGS"
-if test "$ac_cv___attribute___format" = "yes"; then
- AC_DEFINE(__ATTRIBUTE___FORMAT_OK, 1,
- [define if your compiler allows __attribute__((format)) without a warning])
-fi
-AC_MSG_RESULT($ac_cv___attribute___format)
+ #
+ # 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)
])
-
-dnl
-dnl Checks to see if tpacket_stats is defined in linux/if_packet.h
-dnl If so then pcap-linux.c can use this to report proper statistics.
-dnl
-dnl -Scott Barron
-dnl
-AC_DEFUN(AC_LBL_TPACKET_STATS,
- [AC_MSG_CHECKING(if if_packet.h has tpacket_stats defined)
- AC_CACHE_VAL(ac_cv_lbl_tpacket_stats,
- AC_TRY_COMPILE([
-# include <linux/if_packet.h>],
- [struct tpacket_stats stats],
- ac_cv_lbl_tpacket_stats=yes,
- ac_cv_lbl_tpacket_stats=no))
- AC_MSG_RESULT($ac_cv_lbl_tpacket_stats)
- if test $ac_cv_lbl_tpacket_stats = yes; then
- AC_DEFINE(HAVE_TPACKET_STATS,1,[if if_packet.h has tpacket_stats defined])
- fi])
-
-dnl
-dnl Checks to see if the tpacket_auxdata struct has a tp_vlan_tci member.
-dnl
-dnl usage:
-dnl
-dnl AC_LBL_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI
-dnl
-dnl results:
-dnl
-dnl HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI (defined)
-dnl
-dnl NOTE: any compile failure means we conclude that it doesn't have
-dnl that member, so if we don't have tpacket_auxdata, we conclude it
-dnl doesn't have that member (which is OK, as either we won't be using
-dnl code that would use that member, or we wouldn't compile in any case).
-dnl
-AC_DEFUN(AC_LBL_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI,
- [AC_MSG_CHECKING(if tpacket_auxdata struct has tp_vlan_tci member)
- AC_CACHE_VAL(ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci,
- AC_TRY_COMPILE([
-# include <sys/types.h>
-# include <linux/if_packet.h>],
- [u_int i = sizeof(((struct tpacket_auxdata *)0)->tp_vlan_tci)],
- ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci=yes,
- ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci=no))
- AC_MSG_RESULT($ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci)
- if test $ac_cv_lbl_linux_tpacket_auxdata_tp_vlan_tci = yes ; then
- HAVE_LINUX_TPACKET_AUXDATA=tp_vlan_tci
- AC_SUBST(HAVE_LINUX_TPACKET_AUXDATA)
- AC_DEFINE(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI,1,[if tp_vlan_tci exists])
- fi])
-
-dnl
-dnl Checks to see if Solaris has the dl_passive_req_t struct defined
-dnl in <sys/dlpi.h>.
-dnl
-dnl usage:
-dnl
-dnl AC_LBL_DL_PASSIVE_REQ_T
-dnl
-dnl results:
-dnl
-dnl HAVE_DLPI_PASSIVE (defined)
-dnl
-AC_DEFUN(AC_LBL_DL_PASSIVE_REQ_T,
- [AC_MSG_CHECKING(if dl_passive_req_t struct exists)
- AC_CACHE_VAL(ac_cv_lbl_has_dl_passive_req_t,
- AC_TRY_COMPILE([
-# include <sys/types.h>
-# include <sys/dlpi.h>],
- [u_int i = sizeof(dl_passive_req_t)],
- ac_cv_lbl_has_dl_passive_req_t=yes,
- ac_cv_lbl_has_dl_passive_req_t=no))
- AC_MSG_RESULT($ac_cv_lbl_has_dl_passive_req_t)
- if test $ac_cv_lbl_has_dl_passive_req_t = yes ; then
- AC_DEFINE(HAVE_DLPI_PASSIVE,1,[if passive_req_t primitive
- exists])
- fi])
diff --git a/bpf/net/bpf_filter.c b/bpf/net/bpf_filter.c
deleted file mode 100644
index 01a1b64e..00000000
--- a/bpf/net/bpf_filter.c
+++ /dev/null
@@ -1,766 +0,0 @@
-/*-
- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from the Stanford/CMU enet packet filter,
- * (net/enet.c) distributed as part of 4.3BSD, and code contributed
- * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
- * Berkeley Laboratory.
- *
- * 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 University of
- * California, Berkeley and its contributors.
- * 4. 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 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.
- *
- * @(#)bpf.c 7.5 (Berkeley) 7/15/91
- */
-
-#ifdef HAVE_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/param.h>
-#include <sys/types.h>
-#include <sys/time.h>
-
-#define SOLARIS (defined(sun) && (defined(__SVR4) || defined(__svr4__)))
-#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
-
-#ifndef LBL_ALIGN
-/*
- * XXX - IA-64? If not, this probably won't work on Win64 IA-64
- * systems, unless LBL_ALIGN is defined elsewhere for them.
- * XXX - SuperH? If not, this probably won't work on WinCE SuperH
- * systems, unless LBL_ALIGN is defined elsewhere for them.
- */
-#if defined(sparc) || defined(__sparc__) || defined(mips) || \
- defined(ibm032) || defined(__alpha) || defined(__hpux) || \
- defined(__arm__)
-#define LBL_ALIGN
-#endif
-#endif
-
-#ifndef LBL_ALIGN
-#ifndef _WIN32
-#include <netinet/in.h>
-#endif
-
-#define EXTRACT_SHORT(p) ((u_short)ntohs(*(u_short *)p))
-#define EXTRACT_LONG(p) (ntohl(*(u_int32 *)p))
-#else
-#define EXTRACT_SHORT(p)\
- ((u_short)\
- ((u_short)*((u_char *)p+0)<<8|\
- (u_short)*((u_char *)p+1)<<0))
-#define EXTRACT_LONG(p)\
- ((u_int32)*((u_char *)p+0)<<24|\
- (u_int32)*((u_char *)p+1)<<16|\
- (u_int32)*((u_char *)p+2)<<8|\
- (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>
-#include <linux/filter.h>
-#endif
-
-enum {
- BPF_S_ANC_NONE,
- BPF_S_ANC_VLAN_TAG,
- BPF_S_ANC_VLAN_TAG_PRESENT,
-};
-
-/*
- * Execute the filter program starting at pc on the packet p
- * wirelen is the length of the original packet
- * buflen is the amount of data present
- * aux_data is auxiliary data, currently used only when interpreting
- * filters intended for the Linux kernel in cases where the kernel
- * rejects the filter; it contains VLAN tag information
- * For the kernel, p is assumed to be a pointer to an mbuf if buflen is 0,
- * in all other cases, p is a pointer to a buffer and buflen is its size.
- *
- * 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;
-{
- 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)
- /*
- * No filter means accept all.
- */
- return (u_int)-1;
- A = 0;
- X = 0;
- --pc;
- while (1) {
- ++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;
-
- case BPF_RET|BPF_A:
- return (u_int)A;
-
- 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;
-
- 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;
-#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;
- }
-#endif
- continue;
- }
- case BPF_LD|BPF_W|BPF_LEN:
- A = wirelen;
- continue;
-
- case BPF_LDX|BPF_W|BPF_LEN:
- X = wirelen;
- continue;
-
- case BPF_LD|BPF_W|BPF_IND:
- 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;
-
- case BPF_LD|BPF_H|BPF_IND:
- 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;
-
- 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;
-
- 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;
-
- case BPF_LD|BPF_IMM:
- A = pc->k;
- continue;
-
- case BPF_LDX|BPF_IMM:
- X = pc->k;
- continue;
-
- case BPF_LD|BPF_MEM:
- A = mem[pc->k];
- continue;
-
- case BPF_LDX|BPF_MEM:
- X = mem[pc->k];
- continue;
-
- case BPF_ST:
- mem[pc->k] = A;
- continue;
-
- case BPF_STX:
- mem[pc->k] = X;
- 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:
- pc += (A > pc->k) ? pc->jt : pc->jf;
- continue;
-
- case BPF_JMP|BPF_JGE|BPF_K:
- pc += (A >= pc->k) ? pc->jt : pc->jf;
- continue;
-
- case BPF_JMP|BPF_JEQ|BPF_K:
- pc += (A == pc->k) ? pc->jt : pc->jf;
- continue;
-
- case BPF_JMP|BPF_JSET|BPF_K:
- pc += (A & pc->k) ? pc->jt : pc->jf;
- continue;
-
- case BPF_JMP|BPF_JGT|BPF_X:
- pc += (A > X) ? pc->jt : pc->jf;
- continue;
-
- case BPF_JMP|BPF_JGE|BPF_X:
- pc += (A >= X) ? pc->jt : pc->jf;
- continue;
-
- case BPF_JMP|BPF_JEQ|BPF_X:
- pc += (A == X) ? pc->jt : pc->jf;
- continue;
-
- case BPF_JMP|BPF_JSET|BPF_X:
- pc += (A & X) ? pc->jt : pc->jf;
- continue;
-
- case BPF_ALU|BPF_ADD|BPF_X:
- A += X;
- continue;
-
- case BPF_ALU|BPF_SUB|BPF_X:
- A -= X;
- continue;
-
- case BPF_ALU|BPF_MUL|BPF_X:
- A *= X;
- continue;
-
- case BPF_ALU|BPF_DIV|BPF_X:
- if (X == 0)
- return 0;
- A /= X;
- continue;
-
- case BPF_ALU|BPF_MOD|BPF_X:
- if (X == 0)
- return 0;
- A %= X;
- continue;
-
- case BPF_ALU|BPF_AND|BPF_X:
- A &= X;
- continue;
-
- case BPF_ALU|BPF_OR|BPF_X:
- A |= X;
- continue;
-
- case BPF_ALU|BPF_XOR|BPF_X:
- A ^= X;
- continue;
-
- case BPF_ALU|BPF_LSH|BPF_X:
- A <<= X;
- continue;
-
- case BPF_ALU|BPF_RSH|BPF_X:
- A >>= X;
- continue;
-
- case BPF_ALU|BPF_ADD|BPF_K:
- A += pc->k;
- continue;
-
- case BPF_ALU|BPF_SUB|BPF_K:
- A -= pc->k;
- continue;
-
- case BPF_ALU|BPF_MUL|BPF_K:
- A *= pc->k;
- continue;
-
- case BPF_ALU|BPF_DIV|BPF_K:
- A /= pc->k;
- continue;
-
- case BPF_ALU|BPF_MOD|BPF_K:
- A %= pc->k;
- continue;
-
- case BPF_ALU|BPF_AND|BPF_K:
- A &= pc->k;
- continue;
-
- case BPF_ALU|BPF_OR|BPF_K:
- A |= pc->k;
- continue;
-
- case BPF_ALU|BPF_XOR|BPF_K:
- A ^= pc->k;
- continue;
-
- case BPF_ALU|BPF_LSH|BPF_K:
- A <<= pc->k;
- continue;
-
- case BPF_ALU|BPF_RSH|BPF_K:
- A >>= pc->k;
- continue;
-
- case BPF_ALU|BPF_NEG:
- /*
- * Most BPF arithmetic is unsigned, but negation
- * can't be unsigned; throw some casts to
- * specify what we're trying to do.
- */
- A = (u_int32)(-(int32)A);
- continue;
-
- case BPF_MISC|BPF_TAX:
- X = A;
- continue;
-
- case BPF_MISC|BPF_TXA:
- A = X;
- continue;
- }
- }
-}
-
-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;
-{
- return bpf_filter_with_aux_data(pc, p, wirelen, buflen, NULL);
-}
-
-
-/*
- * Return true if the 'fcode' is a valid filter program.
- * The constraints are that each jump be forward and to a valid
- * code, that memory accesses are within valid ranges (to the
- * extent that this can be checked statically; loads of packet
- * data have to be, and are, also checked at run time), and that
- * the code terminates with either an accept or reject.
- *
- * The kernel needs to be able to verify an application's filter code.
- * Otherwise, a bogus program could easily crash the system.
- */
-int
-bpf_validate(f, len)
- 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];
- switch (BPF_CLASS(p->code)) {
- /*
- * Check that memory operations use valid addresses.
- */
- case BPF_LD:
- case BPF_LDX:
- switch (BPF_MODE(p->code)) {
- case BPF_IMM:
- break;
- case BPF_ABS:
- case BPF_IND:
- case BPF_MSH:
- /*
- * There's no maximum packet data size
- * 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)
- return 0;
- break;
- case BPF_LEN:
- break;
- default:
- return 0;
- }
- break;
- case BPF_ST:
- case BPF_STX:
- if (p->k >= BPF_MEMWORDS)
- return 0;
- break;
- case BPF_ALU:
- switch (BPF_OP(p->code)) {
- case BPF_ADD:
- case BPF_SUB:
- case BPF_MUL:
- case BPF_OR:
- case BPF_AND:
- case BPF_XOR:
- case BPF_LSH:
- case BPF_RSH:
- case BPF_NEG:
- break;
- case BPF_DIV:
- case BPF_MOD:
- /*
- * Check for constant division or modulus
- * by 0.
- */
- if (BPF_SRC(p->code) == BPF_K && p->k == 0)
- return 0;
- break;
- default:
- return 0;
- }
- break;
- case BPF_JMP:
- /*
- * Check that jumps are within the code block,
- * and that unconditional branches don't go
- * backwards as a result of an overflow.
- * Unconditional branches have a 32-bit offset,
- * so they could overflow; we check to make
- * sure they don't. Conditional branches have
- * an 8-bit offset, and the from address is <=
- * BPF_MAXINSNS, and we assume that BPF_MAXINSNS
- * is sufficiently small that adding 255 to it
- * won't overflow.
- *
- * We know that len is <= BPF_MAXINSNS, and we
- * assume that BPF_MAXINSNS is < the maximum size
- * of a u_int, so that i + 1 doesn't overflow.
- *
- * For userland, we don't know that the from
- * or len are <= BPF_MAXINSNS, but we know that
- * from <= len, and, except on a 64-bit system,
- * it's unlikely that len, if it truly reflects
- * the size of the program we've been handed,
- * will be anywhere near the maximum size of
- * a u_int. We also don't check for backward
- * branches, as we currently support them in
- * userland for the protochain operation.
- */
- 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:
- case BPF_JGT:
- case BPF_JGE:
- case BPF_JSET:
- if (from + p->jt >= (u_int)len || from + p->jf >= (u_int)len)
- return 0;
- break;
- default:
- return 0;
- }
- break;
- case BPF_RET:
- break;
- case BPF_MISC:
- break;
- default:
- return 0;
- }
- }
- return BPF_CLASS(f[len - 1].code) == BPF_RET;
-}
diff --git a/bpf_dump.c b/bpf_dump.c
index d5ab61e5..a9c91169 100644
--- a/bpf_dump.c
+++ b/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/bpf_filter.c b/bpf_filter.c
index 0605488a..615ed3fc 120000..100644
--- a/bpf_filter.c
+++ b/bpf_filter.c
@@ -1 +1,539 @@
-./bpf/net/bpf_filter.c \ No newline at end of file
+/*-
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from the Stanford/CMU enet packet filter,
+ * (net/enet.c) distributed as part of 4.3BSD, and code contributed
+ * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
+ * Berkeley Laboratory.
+ *
+ * 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 University of
+ * California, Berkeley and its contributors.
+ * 4. 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 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.
+ *
+ * @(#)bpf.c 7.5 (Berkeley) 7/15/91
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.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>
+#endif /* _WIN32 */
+
+#include <pcap/bpf.h>
+
+#include <stdlib.h>
+
+#define int32 bpf_int32
+#define u_int32 bpf_u_int32
+
+#ifndef LBL_ALIGN
+/*
+ * XXX - IA-64? If not, this probably won't work on Win64 IA-64
+ * systems, unless LBL_ALIGN is defined elsewhere for them.
+ * XXX - SuperH? If not, this probably won't work on WinCE SuperH
+ * systems, unless LBL_ALIGN is defined elsewhere for them.
+ */
+#if defined(sparc) || defined(__sparc__) || defined(mips) || \
+ defined(ibm032) || defined(__alpha) || defined(__hpux) || \
+ defined(__arm__)
+#define LBL_ALIGN
+#endif
+#endif
+
+#ifndef LBL_ALIGN
+#ifndef _WIN32
+#include <netinet/in.h>
+#endif
+
+#define EXTRACT_SHORT(p) ((u_short)ntohs(*(u_short *)p))
+#define EXTRACT_LONG(p) (ntohl(*(u_int32 *)p))
+#else
+#define EXTRACT_SHORT(p)\
+ ((u_short)\
+ ((u_short)*((u_char *)p+0)<<8|\
+ (u_short)*((u_char *)p+1)<<0))
+#define EXTRACT_LONG(p)\
+ ((u_int32)*((u_char *)p+0)<<24|\
+ (u_int32)*((u_char *)p+1)<<16|\
+ (u_int32)*((u_char *)p+2)<<8|\
+ (u_int32)*((u_char *)p+3)<<0)
+#endif
+
+#ifdef __linux__
+#include <linux/types.h>
+#include <linux/if_packet.h>
+#include <linux/filter.h>
+#endif
+
+enum {
+ BPF_S_ANC_NONE,
+ BPF_S_ANC_VLAN_TAG,
+ BPF_S_ANC_VLAN_TAG_PRESENT,
+};
+
+/*
+ * Execute the filter program starting at pc on the packet p
+ * wirelen is the length of the original packet
+ * buflen is the amount of data present
+ * aux_data is auxiliary data, currently used only when interpreting
+ * filters intended for the Linux kernel in cases where the kernel
+ * rejects the filter; it contains VLAN tag information
+ * For the kernel, p is assumed to be a pointer to an mbuf if buflen is 0,
+ * in all other cases, p is a pointer to a buffer and buflen is its size.
+ *
+ * Thanks to Ani Sinha <ani@arista.com> for providing initial implementation
+ */
+u_int
+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 (pc == 0)
+ /*
+ * No filter means accept all.
+ */
+ return (u_int)-1;
+ A = 0;
+ X = 0;
+ --pc;
+ for (;;) {
+ ++pc;
+ switch (pc->code) {
+
+ default:
+ abort();
+ case BPF_RET|BPF_K:
+ return (u_int)pc->k;
+
+ case BPF_RET|BPF_A:
+ return (u_int)A;
+
+ case BPF_LD|BPF_W|BPF_ABS:
+ k = pc->k;
+ if (k > buflen || sizeof(int32_t) > buflen - k) {
+ return 0;
+ }
+ A = EXTRACT_LONG(&p[k]);
+ continue;
+
+ case BPF_LD|BPF_H|BPF_ABS:
+ k = pc->k;
+ if (k > buflen || sizeof(int16_t) > buflen - k) {
+ return 0;
+ }
+ A = EXTRACT_SHORT(&p[k]);
+ continue;
+
+ case BPF_LD|BPF_B|BPF_ABS:
+ 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
+ default:
+ k = pc->k;
+ if (k >= buflen) {
+ return 0;
+ }
+ A = p[k];
+ break;
+ }
+ continue;
+
+ case BPF_LD|BPF_W|BPF_LEN:
+ A = wirelen;
+ continue;
+
+ case BPF_LDX|BPF_W|BPF_LEN:
+ X = wirelen;
+ continue;
+
+ case BPF_LD|BPF_W|BPF_IND:
+ k = X + pc->k;
+ if (pc->k > buflen || X > buflen - pc->k ||
+ sizeof(int32_t) > buflen - k) {
+ return 0;
+ }
+ A = EXTRACT_LONG(&p[k]);
+ continue;
+
+ case BPF_LD|BPF_H|BPF_IND:
+ k = X + pc->k;
+ if (X > buflen || pc->k > buflen - X ||
+ sizeof(int16_t) > buflen - k) {
+ return 0;
+ }
+ A = EXTRACT_SHORT(&p[k]);
+ continue;
+
+ case BPF_LD|BPF_B|BPF_IND:
+ k = X + pc->k;
+ if (pc->k >= buflen || X >= buflen - pc->k) {
+ return 0;
+ }
+ A = p[k];
+ continue;
+
+ case BPF_LDX|BPF_MSH|BPF_B:
+ k = pc->k;
+ if (k >= buflen) {
+ return 0;
+ }
+ X = (p[pc->k] & 0xf) << 2;
+ continue;
+
+ case BPF_LD|BPF_IMM:
+ A = pc->k;
+ continue;
+
+ case BPF_LDX|BPF_IMM:
+ X = pc->k;
+ continue;
+
+ case BPF_LD|BPF_MEM:
+ A = mem[pc->k];
+ continue;
+
+ case BPF_LDX|BPF_MEM:
+ X = mem[pc->k];
+ continue;
+
+ case BPF_ST:
+ mem[pc->k] = A;
+ continue;
+
+ case BPF_STX:
+ mem[pc->k] = X;
+ continue;
+
+ case BPF_JMP|BPF_JA:
+ /*
+ * XXX - we currently implement "ip6 protochain"
+ * with backward jumps, so sign-extend pc->k.
+ */
+ pc += (bpf_int32)pc->k;
+ continue;
+
+ case BPF_JMP|BPF_JGT|BPF_K:
+ pc += (A > pc->k) ? pc->jt : pc->jf;
+ continue;
+
+ case BPF_JMP|BPF_JGE|BPF_K:
+ pc += (A >= pc->k) ? pc->jt : pc->jf;
+ continue;
+
+ case BPF_JMP|BPF_JEQ|BPF_K:
+ pc += (A == pc->k) ? pc->jt : pc->jf;
+ continue;
+
+ case BPF_JMP|BPF_JSET|BPF_K:
+ pc += (A & pc->k) ? pc->jt : pc->jf;
+ continue;
+
+ case BPF_JMP|BPF_JGT|BPF_X:
+ pc += (A > X) ? pc->jt : pc->jf;
+ continue;
+
+ case BPF_JMP|BPF_JGE|BPF_X:
+ pc += (A >= X) ? pc->jt : pc->jf;
+ continue;
+
+ case BPF_JMP|BPF_JEQ|BPF_X:
+ pc += (A == X) ? pc->jt : pc->jf;
+ continue;
+
+ case BPF_JMP|BPF_JSET|BPF_X:
+ pc += (A & X) ? pc->jt : pc->jf;
+ continue;
+
+ case BPF_ALU|BPF_ADD|BPF_X:
+ A += X;
+ continue;
+
+ case BPF_ALU|BPF_SUB|BPF_X:
+ A -= X;
+ continue;
+
+ case BPF_ALU|BPF_MUL|BPF_X:
+ A *= X;
+ continue;
+
+ case BPF_ALU|BPF_DIV|BPF_X:
+ if (X == 0)
+ return 0;
+ A /= X;
+ continue;
+
+ case BPF_ALU|BPF_MOD|BPF_X:
+ if (X == 0)
+ return 0;
+ A %= X;
+ continue;
+
+ case BPF_ALU|BPF_AND|BPF_X:
+ A &= X;
+ continue;
+
+ case BPF_ALU|BPF_OR|BPF_X:
+ A |= X;
+ continue;
+
+ case BPF_ALU|BPF_XOR|BPF_X:
+ A ^= X;
+ continue;
+
+ case BPF_ALU|BPF_LSH|BPF_X:
+ A <<= X;
+ continue;
+
+ case BPF_ALU|BPF_RSH|BPF_X:
+ A >>= X;
+ continue;
+
+ case BPF_ALU|BPF_ADD|BPF_K:
+ A += pc->k;
+ continue;
+
+ case BPF_ALU|BPF_SUB|BPF_K:
+ A -= pc->k;
+ continue;
+
+ case BPF_ALU|BPF_MUL|BPF_K:
+ A *= pc->k;
+ continue;
+
+ case BPF_ALU|BPF_DIV|BPF_K:
+ A /= pc->k;
+ continue;
+
+ case BPF_ALU|BPF_MOD|BPF_K:
+ A %= pc->k;
+ continue;
+
+ case BPF_ALU|BPF_AND|BPF_K:
+ A &= pc->k;
+ continue;
+
+ case BPF_ALU|BPF_OR|BPF_K:
+ A |= pc->k;
+ continue;
+
+ case BPF_ALU|BPF_XOR|BPF_K:
+ A ^= pc->k;
+ continue;
+
+ case BPF_ALU|BPF_LSH|BPF_K:
+ A <<= pc->k;
+ continue;
+
+ case BPF_ALU|BPF_RSH|BPF_K:
+ A >>= pc->k;
+ continue;
+
+ case BPF_ALU|BPF_NEG:
+ /*
+ * Most BPF arithmetic is unsigned, but negation
+ * can't be unsigned; throw some casts to
+ * specify what we're trying to do.
+ */
+ A = (u_int32)(-(int32)A);
+ continue;
+
+ case BPF_MISC|BPF_TAX:
+ X = A;
+ continue;
+
+ case BPF_MISC|BPF_TXA:
+ A = X;
+ continue;
+ }
+ }
+}
+
+u_int
+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);
+}
+
+
+/*
+ * Return true if the 'fcode' is a valid filter program.
+ * The constraints are that each jump be forward and to a valid
+ * code, that memory accesses are within valid ranges (to the
+ * extent that this can be checked statically; loads of packet
+ * data have to be, and are, also checked at run time), and that
+ * the code terminates with either an accept or reject.
+ *
+ * The kernel needs to be able to verify an application's filter code.
+ * Otherwise, a bogus program could easily crash the system.
+ */
+int
+bpf_validate(const struct bpf_insn *f, int len)
+{
+ u_int i, from;
+ const struct bpf_insn *p;
+
+ if (len < 1)
+ return 0;
+
+ for (i = 0; i < (u_int)len; ++i) {
+ p = &f[i];
+ switch (BPF_CLASS(p->code)) {
+ /*
+ * Check that memory operations use valid addresses.
+ */
+ case BPF_LD:
+ case BPF_LDX:
+ switch (BPF_MODE(p->code)) {
+ case BPF_IMM:
+ break;
+ case BPF_ABS:
+ case BPF_IND:
+ case BPF_MSH:
+ /*
+ * There's no maximum packet data size
+ * in userland. The runtime packet length
+ * check suffices.
+ */
+ break;
+ case BPF_MEM:
+ if (p->k >= BPF_MEMWORDS)
+ return 0;
+ break;
+ case BPF_LEN:
+ break;
+ default:
+ return 0;
+ }
+ break;
+ case BPF_ST:
+ case BPF_STX:
+ if (p->k >= BPF_MEMWORDS)
+ return 0;
+ break;
+ case BPF_ALU:
+ switch (BPF_OP(p->code)) {
+ case BPF_ADD:
+ case BPF_SUB:
+ case BPF_MUL:
+ case BPF_OR:
+ case BPF_AND:
+ case BPF_XOR:
+ case BPF_LSH:
+ case BPF_RSH:
+ case BPF_NEG:
+ break;
+ case BPF_DIV:
+ case BPF_MOD:
+ /*
+ * Check for constant division or modulus
+ * by 0.
+ */
+ if (BPF_SRC(p->code) == BPF_K && p->k == 0)
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+ break;
+ case BPF_JMP:
+ /*
+ * Check that jumps are within the code block,
+ * and that unconditional branches don't go
+ * backwards as a result of an overflow.
+ * Unconditional branches have a 32-bit offset,
+ * so they could overflow; we check to make
+ * sure they don't. Conditional branches have
+ * an 8-bit offset, and the from address is <=
+ * BPF_MAXINSNS, and we assume that BPF_MAXINSNS
+ * is sufficiently small that adding 255 to it
+ * won't overflow.
+ *
+ * We know that len is <= BPF_MAXINSNS, and we
+ * assume that BPF_MAXINSNS is < the maximum size
+ * of a u_int, so that i + 1 doesn't overflow.
+ *
+ * For userland, we don't know that the from
+ * or len are <= BPF_MAXINSNS, but we know that
+ * from <= len, and, except on a 64-bit system,
+ * it's unlikely that len, if it truly reflects
+ * the size of the program we've been handed,
+ * will be anywhere near the maximum size of
+ * a u_int. We also don't check for backward
+ * branches, as we currently support them in
+ * userland for the protochain operation.
+ */
+ from = i + 1;
+ switch (BPF_OP(p->code)) {
+ case BPF_JA:
+ if (from + p->k >= (u_int)len)
+ return 0;
+ break;
+ case BPF_JEQ:
+ case BPF_JGT:
+ case BPF_JGE:
+ case BPF_JSET:
+ if (from + p->jt >= (u_int)len || from + p->jf >= (u_int)len)
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+ break;
+ case BPF_RET:
+ break;
+ case BPF_MISC:
+ break;
+ default:
+ return 0;
+ }
+ }
+ return BPF_CLASS(f[len - 1].code) == BPF_RET;
+}
diff --git a/bpf_image.c b/bpf_image.c
index 01ec536d..ab41d1ef 100644
--- a/bpf_image.c
+++ b/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/chmod_bpf b/chmod_bpf
index 0a30d993..946fec37 100755
--- a/chmod_bpf
+++ b/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/cmake/Modules/FindDAG.cmake b/cmake/Modules/FindDAG.cmake
new file mode 100644
index 00000000..ef135284
--- /dev/null
+++ b/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/cmake/Modules/FindFseeko.cmake b/cmake/Modules/FindFseeko.cmake
new file mode 100644
index 00000000..ca53a5a6
--- /dev/null
+++ b/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/cmake/Modules/FindLFS.cmake b/cmake/Modules/FindLFS.cmake
new file mode 100644
index 00000000..be5f0d48
--- /dev/null
+++ b/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/cmake/Modules/FindPacket.cmake b/cmake/Modules/FindPacket.cmake
new file mode 100644
index 00000000..1311cdb9
--- /dev/null
+++ b/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/cmake/Modules/FindSNF.cmake b/cmake/Modules/FindSNF.cmake
new file mode 100644
index 00000000..76dcced4
--- /dev/null
+++ b/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/cmake/Modules/FindTC.cmake b/cmake/Modules/FindTC.cmake
new file mode 100644
index 00000000..bb24c667
--- /dev/null
+++ b/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/config/have_siocglifconf.c b/cmake/have_siocglifconf.c
index 5a67abc1..5a67abc1 100644
--- a/config/have_siocglifconf.c
+++ b/cmake/have_siocglifconf.c
diff --git a/cmake/preconfigure.cmake b/cmake/preconfigure.cmake
deleted file mode 100644
index c8c92a48..00000000
--- a/cmake/preconfigure.cmake
+++ /dev/null
@@ -1,55 +0,0 @@
-if( NOT LIBPCAP_PRECONFIGURED )
- set( LIBPCAP_PRECONFIGURED TRUE )
-
- ###################################################################
- # Parameters
- ###################################################################
-
- option (USE_STATIC_RT "Use static Runtime" ON)
-
- ######################################
- # Project setings
- ######################################
-
- add_definitions( -DBUILDING_PCAP )
-
- if( MSVC )
- add_definitions( -D__STDC__ )
- add_definitions( -D_CRT_SECURE_NO_WARNINGS )
- add_definitions( "-D_U_=" )
- elseif( CMAKE_COMPILER_IS_GNUCXX )
- add_definitions( "-D_U_=__attribute__((unused))" )
- else(MSVC)
- add_definitions( "-D_U_=" )
- endif( MSVC )
-
- if (USE_STATIC_RT)
- MESSAGE( STATUS "Use STATIC runtime" )
-
- if( MSVC )
- set (CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /MT")
- set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MT")
- set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
- set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
-
- set (CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} /MT")
- set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /MT")
- set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT")
- set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd")
- endif( MSVC )
- else (USE_STATIC_RT)
- MESSAGE( STATUS "Use DYNAMIC runtime" )
-
- if( MSVC )
- set (CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /MD")
- set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MD")
- set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD")
- set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
-
- set (CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} /MD")
- set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /MD")
- set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MD")
- set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MDd")
- endif( MSVC )
- endif (USE_STATIC_RT)
-endif( NOT LIBPCAP_PRECONFIGURED )
diff --git a/cmake_uninstall.cmake.in b/cmake_uninstall.cmake.in
new file mode 100644
index 00000000..2037e365
--- /dev/null
+++ b/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/cmakeconfig.h.in b/cmakeconfig.h.in
index 94edb5f4..6760cec7 100644
--- a/cmakeconfig.h.in
+++ b/cmakeconfig.h.in
@@ -1,10 +1,19 @@
/* 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 if you have a cloning BPF device */
-#cmakedefine HAVE_CLONING_BPF 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
@@ -15,21 +24,20 @@
/* define if you have dag_get_stream_erf_types() */
#cmakedefine HAVE_DAG_GET_STREAM_ERF_TYPES 1
-/* define if you have streams capable DAG API */
-#cmakedefine HAVE_DAG_STREAMS_API 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', and to 0 if you
- don't. */
+/* Define to 1 if you have the declaration of `ether_hostton' */
#cmakedefine HAVE_DECL_ETHER_HOSTTON 1
-/* define if you have a /dev/dlpi */
-#cmakedefine HAVE_DEV_DLPI 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
-/* if passive_req_t primitive exists */
-#cmakedefine HAVE_DLPI_PASSIVE 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
@@ -37,15 +45,15 @@
/* 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
-/* if ppa_info_t_dl_module_id exists */
-#cmakedefine HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1 1
-
/* Define to 1 if you have the <inttypes.h> header file. */
#cmakedefine HAVE_INTTYPES_H 1
@@ -76,24 +84,24 @@
/* 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/if_packet.h> header file. */
-#cmakedefine HAVE_LINUX_IF_PACKET_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
-/* if tp_vlan_tci exists */
-#cmakedefine HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI 1
-
-/* Define to 1 if you have the <linux/types.h> header file. */
-#cmakedefine HAVE_LINUX_TYPES_H 1
-
/* Define to 1 if you have the <linux/usbdevice_fs.h> header file. */
#cmakedefine HAVE_LINUX_USBDEVICE_FS_H 1
@@ -103,32 +111,35 @@
/* Define to 1 if you have the <memory.h> header file. */
#cmakedefine HAVE_MEMORY_H 1
-/* Define to 1 if you have the <netinet/ether.h> header file. */
-#cmakedefine HAVE_NETINET_ETHER_H 1
-
-/* Define to 1 if you have the <netinet/if_ether.h> header file. */
-#cmakedefine HAVE_NETINET_IF_ETHER_H 1
-
-/* Define to 1 if you have the <netpacket/if_packet.h> header file. */
-#cmakedefine HAVE_NETPACKET_IF_PACKET_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 remote packet capture is to be supported */
-#cmakedefine HAVE_REMOTE 1
-
-/* Define to 1 if you have the <paths.h> header file. */
-#cmakedefine HAVE_PATHS_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
@@ -142,18 +153,18 @@
/* Define to 1 if you have the `snprintf' function. */
#cmakedefine HAVE_SNPRINTF 1
-/* if struct sockaddr has the sa_len member */
-#cmakedefine HAVE_SOCKADDR_SA_LEN 1
-
-/* if struct sockaddr_storage exists */
-#cmakedefine HAVE_SOCKADDR_STORAGE 1
-
-/* define if socklen_t is defined */
+/* 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
@@ -163,17 +174,57 @@
/* 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 you have the <sys/bitypes.h> header file. */
-#cmakedefine HAVE_SYS_BITYPES_H 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
@@ -181,9 +232,15 @@
/* 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
@@ -196,27 +253,15 @@
/* define if you have the TurboCap API */
#cmakedefine HAVE_TC_API 1
-/* if if_packet.h has tpacket_stats defined */
-#cmakedefine HAVE_TPACKET_STATS 1
-
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H 1
-/* if struct usbdevfs_ctrltransfer has bRequestType */
-#cmakedefine HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE 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
-/* define if the system supports zerocopy BPF */
-#cmakedefine HAVE_ZEROCOPY_BPF 1
-
-/* define if your compiler has __attribute__ */
-#cmakedefine HAVE___ATTRIBUTE__ 1
-
/* IPv6 */
#cmakedefine INET6 1
@@ -224,10 +269,7 @@
#cmakedefine LBL_ALIGN 1
/* path for device for USB sniffing */
-#cmakedefine LINUX_USB_MON_DEV 1
-
-/* if we need a pcap_parse wrapper around yyparse */
-#cmakedefine NEED_YYPARSE_WRAPPER 1
+#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
@@ -235,17 +277,23 @@
/* 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 1
+#cmakedefine PACKAGE_NAME "@PACKAGE_NAME@"
/* Define to the full name and version of this package. */
-#cmakedefine PACKAGE_STRING 1
+#cmakedefine PACKAGE_STRING "@PACKAGE_STRING@"
/* Define to the one symbol short name of this package. */
#cmakedefine PACKAGE_TARNAME 1
@@ -254,10 +302,7 @@
#cmakedefine PACKAGE_URL 1
/* Define to the version of this package. */
-#cmakedefine PACKAGE_VERSION 1
-
-/* /dev/dlpi directory */
-#cmakedefine PCAP_DEV_PREFIX 1
+#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@"
/* target host supports Bluetooth sniffing */
#cmakedefine PCAP_SUPPORT_BT 1
@@ -271,21 +316,30 @@
/* target host supports netfilter sniffing */
#cmakedefine PCAP_SUPPORT_NETFILTER 1
-/* use Linux packet ring capture if available */
+/* 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
-/* if struct sockaddr_hci has hci_channel member */
-#cmakedefine SOCKADDR_HCI_HAS_HCI_CHANNEL 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
@@ -306,40 +360,7 @@
/* define on AIX to get certain functions */
#cmakedefine _SUN 1
-/* define if your compiler allows __attribute__((format)) without a warning */
-#cmakedefine __ATTRIBUTE___FORMAT_OK 1
-
#if 0
-/* to handle Ultrix compilers that don't support const in prototypes */
-#cmakedefine const 1
-
-/* Define as token for inline if inlining supported */
-#cmakedefine inline 1
-
-/* Define to `short' if int16_t not defined. */
-#cmakedefine int16_t 1
-
-/* Define to `int' if int32_t not defined. */
-#cmakedefine int32_t 1
-
-/* Define to `long long' if int64_t not defined. */
-#cmakedefine int64_t 1
-
-/* Define to `signed char' if int8_t not defined. */
-#cmakedefine int8_t 1
-
/* on sinix */
#cmakedefine sinix 1
-
-/* Define to `unsigned short' if u_int16_t not defined. */
-#cmakedefine u_int16_t 1
-
-/* Define to `unsigned int' if u_int32_t not defined. */
-#cmakedefine u_int32_t 1
-
-/* Define to `unsigned long long' if u_int64_t not defined. */
-#cmakedefine u_int64_t 1
-
-/* Define to `unsigned char' if u_int8_t not defined. */
-#cmakedefine u_int8_t 1
#endif
diff --git a/config.guess b/config.guess
index 44290b83..2b79f6d8 100644..100755
--- a/config.guess
+++ b/config.guess
@@ -1,8 +1,8 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2015 Free Software Foundation, Inc.
+# Copyright 1992-2018 Free Software Foundation, Inc.
-timestamp='2015-02-23'
+timestamp='2018-07-06'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@ timestamp='2015-02-23'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -27,7 +27,7 @@ timestamp='2015-02-23'
# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
#
# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
#
# Please send patches to <config-patches@gnu.org>.
@@ -39,7 +39,7 @@ Usage: $0 [OPTION]
Output the configuration name of the system \`$me' is run on.
-Operation modes:
+Options:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
@@ -50,7 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2015 Free Software Foundation, Inc.
+Copyright 1992-2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -101,15 +101,15 @@ trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && e
trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
: ${TMPDIR=/tmp} ;
{ tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp 2>/dev/null) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
dummy=$tmp/dummy ;
tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,) echo "int x;" > $dummy.c ;
+case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
+ ,,) echo "int x;" > "$dummy.c" ;
for c in cc gcc c89 c99 ; do
- if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
CC_FOR_BUILD="$c"; break ;
fi ;
done ;
@@ -132,14 +132,14 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-case "${UNAME_SYSTEM}" in
+case "$UNAME_SYSTEM" in
Linux|GNU|GNU/*)
# If the system lacks a compiler, then just pick glibc.
# We could probably try harder.
LIBC=gnu
- eval $set_cc_for_build
- cat <<-EOF > $dummy.c
+ eval "$set_cc_for_build"
+ cat <<-EOF > "$dummy.c"
#include <features.h>
#if defined(__UCLIBC__)
LIBC=uclibc
@@ -149,13 +149,20 @@ Linux|GNU|GNU/*)
LIBC=gnu
#endif
EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`"
+
+ # If ldd exists, use it to detect musl libc.
+ if command -v ldd >/dev/null && \
+ ldd --version 2>&1 | grep -q ^musl
+ then
+ LIBC=musl
+ fi
;;
esac
# Note: order is significant - the case branches are not exclusive.
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
@@ -169,27 +176,30 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# portion of the name. We always set it to "unknown".
sysctl="sysctl -n hw.machine_arch"
UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
- /sbin/$sysctl 2>/dev/null || \
- /usr/sbin/$sysctl 2>/dev/null || \
+ "/sbin/$sysctl" 2>/dev/null || \
+ "/usr/sbin/$sysctl" 2>/dev/null || \
echo unknown)`
- case "${UNAME_MACHINE_ARCH}" in
+ case "$UNAME_MACHINE_ARCH" in
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
earmv*)
- arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
- endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
- machine=${arch}${endian}-unknown
+ arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+ endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
+ machine="${arch}${endian}"-unknown
;;
- *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ *) machine="$UNAME_MACHINE_ARCH"-unknown ;;
esac
# The Operating System including object format, if it has switched
- # to ELF recently, or will in the future.
- case "${UNAME_MACHINE_ARCH}" in
- arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
- eval $set_cc_for_build
+ # to ELF recently (or will in the future) and ABI.
+ case "$UNAME_MACHINE_ARCH" in
+ earm*)
+ os=netbsdelf
+ ;;
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval "$set_cc_for_build"
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ELF__
then
@@ -205,10 +215,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
;;
esac
# Determine ABI tags.
- case "${UNAME_MACHINE_ARCH}" in
+ case "$UNAME_MACHINE_ARCH" in
earm*)
expr='s/^earmv[0-9]/-eabi/;s/eb$//'
- abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
+ abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
;;
esac
# The OS release
@@ -216,39 +226,55 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# thus, need a distinct triplet. However, they do not need
# kernel version information, so it can be replaced with a
# suitable tag, in the style of linux-gnu.
- case "${UNAME_VERSION}" in
+ case "$UNAME_VERSION" in
Debian*)
release='-gnu'
;;
*)
- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
;;
esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "${machine}-${os}${release}${abi}"
+ echo "$machine-${os}${release}${abi-}"
exit ;;
*:Bitrig:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
exit ;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
+ exit ;;
+ *:LibertyBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+ echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
+ exit ;;
+ *:MidnightBSD:*:*)
+ echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE"
exit ;;
*:ekkoBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE"
exit ;;
*:SolidBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE"
exit ;;
macppc:MirBSD:*:*)
- echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ echo powerpc-unknown-mirbsd"$UNAME_RELEASE"
exit ;;
*:MirBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE"
+ exit ;;
+ *:Sortix:*:*)
+ echo "$UNAME_MACHINE"-unknown-sortix
+ exit ;;
+ *:Redox:*:*)
+ echo "$UNAME_MACHINE"-unknown-redox
exit ;;
+ mips:OSF1:*.*)
+ echo mips-dec-osf1
+ exit ;;
alpha:OSF1:*:*)
case $UNAME_RELEASE in
*4.0)
@@ -265,63 +291,54 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
case "$ALPHA_CPU_TYPE" in
"EV4 (21064)")
- UNAME_MACHINE="alpha" ;;
+ UNAME_MACHINE=alpha ;;
"EV4.5 (21064)")
- UNAME_MACHINE="alpha" ;;
+ UNAME_MACHINE=alpha ;;
"LCA4 (21066/21068)")
- UNAME_MACHINE="alpha" ;;
+ UNAME_MACHINE=alpha ;;
"EV5 (21164)")
- UNAME_MACHINE="alphaev5" ;;
+ UNAME_MACHINE=alphaev5 ;;
"EV5.6 (21164A)")
- UNAME_MACHINE="alphaev56" ;;
+ UNAME_MACHINE=alphaev56 ;;
"EV5.6 (21164PC)")
- UNAME_MACHINE="alphapca56" ;;
+ UNAME_MACHINE=alphapca56 ;;
"EV5.7 (21164PC)")
- UNAME_MACHINE="alphapca57" ;;
+ UNAME_MACHINE=alphapca57 ;;
"EV6 (21264)")
- UNAME_MACHINE="alphaev6" ;;
+ UNAME_MACHINE=alphaev6 ;;
"EV6.7 (21264A)")
- UNAME_MACHINE="alphaev67" ;;
+ UNAME_MACHINE=alphaev67 ;;
"EV6.8CB (21264C)")
- UNAME_MACHINE="alphaev68" ;;
+ UNAME_MACHINE=alphaev68 ;;
"EV6.8AL (21264B)")
- UNAME_MACHINE="alphaev68" ;;
+ UNAME_MACHINE=alphaev68 ;;
"EV6.8CX (21264D)")
- UNAME_MACHINE="alphaev68" ;;
+ UNAME_MACHINE=alphaev68 ;;
"EV6.9A (21264/EV69A)")
- UNAME_MACHINE="alphaev69" ;;
+ UNAME_MACHINE=alphaev69 ;;
"EV7 (21364)")
- UNAME_MACHINE="alphaev7" ;;
+ UNAME_MACHINE=alphaev7 ;;
"EV7.9 (21364A)")
- UNAME_MACHINE="alphaev79" ;;
+ UNAME_MACHINE=alphaev79 ;;
esac
# A Pn.n version is a patched version.
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`"
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
exitcode=$?
trap '' 0
exit $exitcode ;;
- Alpha\ *:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # Should we change UNAME_MACHINE based on the output of uname instead
- # of the specific Alpha model?
- echo alpha-pc-interix
- exit ;;
- 21064:Windows_NT:50:3)
- echo alpha-dec-winnt3.5
- exit ;;
Amiga*:UNIX_System_V:4.0:*)
echo m68k-unknown-sysv4
exit ;;
*:[Aa]miga[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-amigaos
+ echo "$UNAME_MACHINE"-unknown-amigaos
exit ;;
*:[Mm]orph[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-morphos
+ echo "$UNAME_MACHINE"-unknown-morphos
exit ;;
*:OS/390:*:*)
echo i370-ibm-openedition
@@ -333,7 +350,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo powerpc-ibm-os400
exit ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix${UNAME_RELEASE}
+ echo arm-acorn-riscix"$UNAME_RELEASE"
exit ;;
arm*:riscos:*:*|arm*:RISCOS:*:*)
echo arm-unknown-riscos
@@ -360,38 +377,38 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
sparc) echo sparc-icl-nx7; exit ;;
esac ;;
s390x:SunOS:*:*)
- echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
exit ;;
sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
exit ;;
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
- echo i386-pc-auroraux${UNAME_RELEASE}
+ echo i386-pc-auroraux"$UNAME_RELEASE"
exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
- eval $set_cc_for_build
- SUN_ARCH="i386"
+ eval "$set_cc_for_build"
+ SUN_ARCH=i386
# If there is a compiler, see if it is configured for 64-bit objects.
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
# This test works for both compilers.
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
- SUN_ARCH="x86_64"
+ SUN_ARCH=x86_64
fi
fi
- echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
exit ;;
sun4*:SunOS:*:*)
case "`/usr/bin/arch -k`" in
@@ -400,25 +417,25 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
;;
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`"
exit ;;
sun3*:SunOS:*:*)
- echo m68k-sun-sunos${UNAME_RELEASE}
+ echo m68k-sun-sunos"$UNAME_RELEASE"
exit ;;
sun*:*:4.2BSD:*)
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
case "`/bin/arch`" in
sun3)
- echo m68k-sun-sunos${UNAME_RELEASE}
+ echo m68k-sun-sunos"$UNAME_RELEASE"
;;
sun4)
- echo sparc-sun-sunos${UNAME_RELEASE}
+ echo sparc-sun-sunos"$UNAME_RELEASE"
;;
esac
exit ;;
aushp:SunOS:*:*)
- echo sparc-auspex-sunos${UNAME_RELEASE}
+ echo sparc-auspex-sunos"$UNAME_RELEASE"
exit ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
@@ -429,44 +446,44 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
+ echo m68k-atari-mint"$UNAME_RELEASE"
exit ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
+ echo m68k-atari-mint"$UNAME_RELEASE"
exit ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
+ echo m68k-atari-mint"$UNAME_RELEASE"
exit ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
+ echo m68k-milan-mint"$UNAME_RELEASE"
exit ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
+ echo m68k-hades-mint"$UNAME_RELEASE"
exit ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
+ echo m68k-unknown-mint"$UNAME_RELEASE"
exit ;;
m68k:machten:*:*)
- echo m68k-apple-machten${UNAME_RELEASE}
+ echo m68k-apple-machten"$UNAME_RELEASE"
exit ;;
powerpc:machten:*:*)
- echo powerpc-apple-machten${UNAME_RELEASE}
+ echo powerpc-apple-machten"$UNAME_RELEASE"
exit ;;
RISC*:Mach:*:*)
echo mips-dec-mach_bsd4.3
exit ;;
RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix${UNAME_RELEASE}
+ echo mips-dec-ultrix"$UNAME_RELEASE"
exit ;;
VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix${UNAME_RELEASE}
+ echo vax-dec-ultrix"$UNAME_RELEASE"
exit ;;
2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix${UNAME_RELEASE}
+ echo clipper-intergraph-clix"$UNAME_RELEASE"
exit ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ eval "$set_cc_for_build"
+ sed 's/^ //' << EOF > "$dummy.c"
#ifdef __cplusplus
#include <stdio.h> /* for printf() prototype */
int main (int argc, char *argv[]) {
@@ -475,23 +492,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
#endif
#if defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_SVR4)
- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0);
#endif
#endif
exit (-1);
}
EOF
- $CC_FOR_BUILD -o $dummy $dummy.c &&
- dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
- SYSTEM_NAME=`$dummy $dummyarg` &&
+ $CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
+ dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
{ echo "$SYSTEM_NAME"; exit; }
- echo mips-mips-riscos${UNAME_RELEASE}
+ echo mips-mips-riscos"$UNAME_RELEASE"
exit ;;
Motorola:PowerMAX_OS:*:*)
echo powerpc-motorola-powermax
@@ -517,17 +534,17 @@ EOF
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ]
then
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
- [ ${TARGET_BINARY_INTERFACE}x = x ]
+ if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \
+ [ "$TARGET_BINARY_INTERFACE"x = x ]
then
- echo m88k-dg-dgux${UNAME_RELEASE}
+ echo m88k-dg-dgux"$UNAME_RELEASE"
else
- echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ echo m88k-dg-dguxbcs"$UNAME_RELEASE"
fi
else
- echo i586-dg-dgux${UNAME_RELEASE}
+ echo i586-dg-dgux"$UNAME_RELEASE"
fi
exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
@@ -544,7 +561,7 @@ EOF
echo m68k-tektronix-bsd
exit ;;
*:IRIX*:*:*)
- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`"
exit ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
@@ -556,14 +573,14 @@ EOF
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
fi
- echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV"
exit ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ eval "$set_cc_for_build"
+ sed 's/^ //' << EOF > "$dummy.c"
#include <sys/systemcfg.h>
main()
@@ -574,7 +591,7 @@ EOF
exit(0);
}
EOF
- if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
then
echo "$SYSTEM_NAME"
else
@@ -588,7 +605,7 @@ EOF
exit ;;
*:AIX:*:[4567])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
- if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
@@ -597,18 +614,18 @@ EOF
IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
fi
- echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ echo "$IBM_ARCH"-ibm-aix"$IBM_REV"
exit ;;
*:AIX:*:*)
echo rs6000-ibm-aix
exit ;;
- ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
echo romp-ibm-bsd4.4
exit ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to
exit ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
echo rs6000-bull-bosx
@@ -623,28 +640,28 @@ EOF
echo m68k-hp-bsd4.4
exit ;;
9000/[34678]??:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
+ HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+ case "$UNAME_MACHINE" in
+ 9000/31?) HP_ARCH=m68000 ;;
+ 9000/[34]??) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ case "$sc_cpu_version" in
+ 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ case "$sc_kernel_bits" in
+ 32) HP_ARCH=hppa2.0n ;;
+ 64) HP_ARCH=hppa2.0w ;;
+ '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20
esac ;;
esac
fi
- if [ "${HP_ARCH}" = "" ]; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ if [ "$HP_ARCH" = "" ]; then
+ eval "$set_cc_for_build"
+ sed 's/^ //' << EOF > "$dummy.c"
#define _HPUX_SOURCE
#include <stdlib.h>
@@ -677,13 +694,13 @@ EOF
exit (0);
}
EOF
- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
- if [ ${HP_ARCH} = "hppa2.0w" ]
+ if [ "$HP_ARCH" = hppa2.0w ]
then
- eval $set_cc_for_build
+ eval "$set_cc_for_build"
# hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
# 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
@@ -694,23 +711,23 @@ EOF
# $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
# => hppa64-hp-hpux11.23
- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
grep -q __LP64__
then
- HP_ARCH="hppa2.0w"
+ HP_ARCH=hppa2.0w
else
- HP_ARCH="hppa64"
+ HP_ARCH=hppa64
fi
fi
- echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
exit ;;
ia64:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- echo ia64-hp-hpux${HPUX_REV}
+ HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux"$HPUX_REV"
exit ;;
3050*:HI-UX:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ eval "$set_cc_for_build"
+ sed 's/^ //' << EOF > "$dummy.c"
#include <unistd.h>
int
main ()
@@ -735,11 +752,11 @@ EOF
exit (0);
}
EOF
- $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
{ echo "$SYSTEM_NAME"; exit; }
echo unknown-hitachi-hiuxwe2
exit ;;
- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
echo hppa1.1-hp-bsd
exit ;;
9000/8??:4.3bsd:*:*)
@@ -748,7 +765,7 @@ EOF
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
echo hppa1.0-hp-mpeix
exit ;;
- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
echo hppa1.1-hp-osf
exit ;;
hp8??:OSF1:*:*)
@@ -756,9 +773,9 @@ EOF
exit ;;
i*86:OSF1:*:*)
if [ -x /usr/sbin/sysversion ] ; then
- echo ${UNAME_MACHINE}-unknown-osf1mk
+ echo "$UNAME_MACHINE"-unknown-osf1mk
else
- echo ${UNAME_MACHINE}-unknown-osf1
+ echo "$UNAME_MACHINE"-unknown-osf1
fi
exit ;;
parisc*:Lites*:*:*)
@@ -783,127 +800,109 @@ EOF
echo c4-convex-bsd
exit ;;
CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*[A-Z]90:*:*:*)
- echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
-e 's/\.[^.]*$/.X/'
exit ;;
CRAY*TS:*:*:*)
- echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*SV1:*:*:*)
- echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
exit ;;
*:UNICOS/mp:*:*)
- echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE"
exit ;;
sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi${UNAME_RELEASE}
+ echo sparc-unknown-bsdi"$UNAME_RELEASE"
exit ;;
*:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
exit ;;
*:FreeBSD:*:*)
UNAME_PROCESSOR=`/usr/bin/uname -p`
- case ${UNAME_PROCESSOR} in
+ case "$UNAME_PROCESSOR" in
amd64)
- echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- *)
- echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ UNAME_PROCESSOR=x86_64 ;;
+ i386)
+ UNAME_PROCESSOR=i586 ;;
esac
+ echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
exit ;;
i*:CYGWIN*:*)
- echo ${UNAME_MACHINE}-pc-cygwin
+ echo "$UNAME_MACHINE"-pc-cygwin
exit ;;
*:MINGW64*:*)
- echo ${UNAME_MACHINE}-pc-mingw64
+ echo "$UNAME_MACHINE"-pc-mingw64
exit ;;
*:MINGW*:*)
- echo ${UNAME_MACHINE}-pc-mingw32
+ echo "$UNAME_MACHINE"-pc-mingw32
exit ;;
*:MSYS*:*)
- echo ${UNAME_MACHINE}-pc-msys
- exit ;;
- i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
+ echo "$UNAME_MACHINE"-pc-msys
exit ;;
i*:PW*:*)
- echo ${UNAME_MACHINE}-pc-pw32
+ echo "$UNAME_MACHINE"-pc-pw32
exit ;;
*:Interix*:*)
- case ${UNAME_MACHINE} in
+ case "$UNAME_MACHINE" in
x86)
- echo i586-pc-interix${UNAME_RELEASE}
+ echo i586-pc-interix"$UNAME_RELEASE"
exit ;;
authenticamd | genuineintel | EM64T)
- echo x86_64-unknown-interix${UNAME_RELEASE}
+ echo x86_64-unknown-interix"$UNAME_RELEASE"
exit ;;
IA64)
- echo ia64-unknown-interix${UNAME_RELEASE}
+ echo ia64-unknown-interix"$UNAME_RELEASE"
exit ;;
esac ;;
- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
- echo i${UNAME_MACHINE}-pc-mks
- exit ;;
- 8664:Windows_NT:*)
- echo x86_64-pc-mks
- exit ;;
- i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
- # UNAME_MACHINE based on the output of uname instead of i386?
- echo i586-pc-interix
- exit ;;
i*:UWIN*:*)
- echo ${UNAME_MACHINE}-pc-uwin
+ echo "$UNAME_MACHINE"-pc-uwin
exit ;;
amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
echo x86_64-unknown-cygwin
exit ;;
- p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin
- exit ;;
prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
exit ;;
*:GNU:*:*)
# the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`"
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC"
exit ;;
- i*86:Minix:*:*)
- echo ${UNAME_MACHINE}-pc-minix
+ *:Minix:*:*)
+ echo "$UNAME_MACHINE"-unknown-minix
exit ;;
aarch64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
@@ -916,58 +915,64 @@ EOF
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
- if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
arc:Linux:*:* | arceb:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
arm*:Linux:*:*)
- eval $set_cc_for_build
+ eval "$set_cc_for_build"
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi
else
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf
fi
fi
exit ;;
avr32*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
cris:Linux:*:*)
- echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
exit ;;
crisv32:Linux:*:*)
- echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
+ exit ;;
+ e2k:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
frv:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
hexagon:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
i*86:Linux:*:*)
- echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
exit ;;
ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
+ k1om:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
mips:Linux:*:* | mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ eval "$set_cc_for_build"
+ sed 's/^ //' << EOF > "$dummy.c"
#undef CPU
#undef ${UNAME_MACHINE}
#undef ${UNAME_MACHINE}el
@@ -981,64 +986,70 @@ EOF
#endif
#endif
EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`"
+ test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; }
;;
+ mips64el:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ exit ;;
openrisc*:Linux:*:*)
- echo or1k-unknown-linux-${LIBC}
+ echo or1k-unknown-linux-"$LIBC"
exit ;;
or32:Linux:*:* | or1k*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
padre:Linux:*:*)
- echo sparc-unknown-linux-${LIBC}
+ echo sparc-unknown-linux-"$LIBC"
exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-${LIBC}
+ echo hppa64-unknown-linux-"$LIBC"
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
- PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
- *) echo hppa-unknown-linux-${LIBC} ;;
+ PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;
+ PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;
+ *) echo hppa-unknown-linux-"$LIBC" ;;
esac
exit ;;
ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-${LIBC}
+ echo powerpc64-unknown-linux-"$LIBC"
exit ;;
ppc:Linux:*:*)
- echo powerpc-unknown-linux-${LIBC}
+ echo powerpc-unknown-linux-"$LIBC"
exit ;;
ppc64le:Linux:*:*)
- echo powerpc64le-unknown-linux-${LIBC}
+ echo powerpc64le-unknown-linux-"$LIBC"
exit ;;
ppcle:Linux:*:*)
- echo powerpcle-unknown-linux-${LIBC}
+ echo powerpcle-unknown-linux-"$LIBC"
+ exit ;;
+ riscv32:Linux:*:* | riscv64:Linux:*:*)
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ echo "$UNAME_MACHINE"-ibm-linux-"$LIBC"
exit ;;
sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
tile*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
vax:Linux:*:*)
- echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
exit ;;
x86_64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
exit ;;
xtensa*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
@@ -1052,34 +1063,34 @@ EOF
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION"
exit ;;
i*86:OS/2:*:*)
# If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
- echo ${UNAME_MACHINE}-pc-os2-emx
+ echo "$UNAME_MACHINE"-pc-os2-emx
exit ;;
i*86:XTS-300:*:STOP)
- echo ${UNAME_MACHINE}-unknown-stop
+ echo "$UNAME_MACHINE"-unknown-stop
exit ;;
i*86:atheos:*:*)
- echo ${UNAME_MACHINE}-unknown-atheos
+ echo "$UNAME_MACHINE"-unknown-atheos
exit ;;
i*86:syllable:*:*)
- echo ${UNAME_MACHINE}-pc-syllable
+ echo "$UNAME_MACHINE"-pc-syllable
exit ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
+ echo i386-unknown-lynxos"$UNAME_RELEASE"
exit ;;
i*86:*DOS:*:*)
- echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ echo "$UNAME_MACHINE"-pc-msdosdjgpp
exit ;;
- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
- UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ i*86:*:4.*:*)
+ UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"
else
- echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL"
fi
exit ;;
i*86:*:5:[678]*)
@@ -1089,12 +1100,12 @@ EOF
*Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;;
esac
- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}"
exit ;;
i*86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"
elif /bin/uname -X 2>/dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
@@ -1104,9 +1115,9 @@ EOF
&& UNAME_MACHINE=i686
(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
- echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL"
else
- echo ${UNAME_MACHINE}-pc-sysv32
+ echo "$UNAME_MACHINE"-pc-sysv32
fi
exit ;;
pc:*:*:*)
@@ -1114,7 +1125,7 @@ EOF
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i586.
# Note: whatever this is, it MUST be the same as what config.sub
- # prints for the "djgpp" host, or else GDB configury will decide that
+ # prints for the "djgpp" host, or else GDB configure will decide that
# this is a cross-build.
echo i586-pc-msdosdjgpp
exit ;;
@@ -1126,9 +1137,9 @@ EOF
exit ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4
fi
exit ;;
mini*:CTIX:SYS*5:*)
@@ -1148,9 +1159,9 @@ EOF
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
@@ -1159,28 +1170,28 @@ EOF
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos${UNAME_RELEASE}
+ echo m68k-unknown-lynxos"$UNAME_RELEASE"
exit ;;
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit ;;
TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos${UNAME_RELEASE}
+ echo sparc-unknown-lynxos"$UNAME_RELEASE"
exit ;;
rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ echo rs6000-unknown-lynxos"$UNAME_RELEASE"
exit ;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
- echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ echo powerpc-unknown-lynxos"$UNAME_RELEASE"
exit ;;
SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv${UNAME_RELEASE}
+ echo mips-dde-sysv"$UNAME_RELEASE"
exit ;;
RM*:ReliantUNIX-*:*:*)
echo mips-sni-sysv4
@@ -1191,7 +1202,7 @@ EOF
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo ${UNAME_MACHINE}-sni-sysv4
+ echo "$UNAME_MACHINE"-sni-sysv4
else
echo ns32k-sni-sysv
fi
@@ -1211,23 +1222,23 @@ EOF
exit ;;
i*86:VOS:*:*)
# From Paul.Green@stratus.com.
- echo ${UNAME_MACHINE}-stratus-vos
+ echo "$UNAME_MACHINE"-stratus-vos
exit ;;
*:VOS:*:*)
# From Paul.Green@stratus.com.
echo hppa1.1-stratus-vos
exit ;;
mc68*:A/UX:*:*)
- echo m68k-apple-aux${UNAME_RELEASE}
+ echo m68k-apple-aux"$UNAME_RELEASE"
exit ;;
news*:NEWS-OS:6*:*)
echo mips-sony-newsos6
exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
+ echo mips-nec-sysv"$UNAME_RELEASE"
else
- echo mips-unknown-sysv${UNAME_RELEASE}
+ echo mips-unknown-sysv"$UNAME_RELEASE"
fi
exit ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
@@ -1246,46 +1257,56 @@ EOF
echo x86_64-unknown-haiku
exit ;;
SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux${UNAME_RELEASE}
+ echo sx4-nec-superux"$UNAME_RELEASE"
exit ;;
SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux${UNAME_RELEASE}
+ echo sx5-nec-superux"$UNAME_RELEASE"
exit ;;
SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux${UNAME_RELEASE}
+ echo sx6-nec-superux"$UNAME_RELEASE"
exit ;;
SX-7:SUPER-UX:*:*)
- echo sx7-nec-superux${UNAME_RELEASE}
+ echo sx7-nec-superux"$UNAME_RELEASE"
exit ;;
SX-8:SUPER-UX:*:*)
- echo sx8-nec-superux${UNAME_RELEASE}
+ echo sx8-nec-superux"$UNAME_RELEASE"
exit ;;
SX-8R:SUPER-UX:*:*)
- echo sx8r-nec-superux${UNAME_RELEASE}
+ echo sx8r-nec-superux"$UNAME_RELEASE"
+ exit ;;
+ SX-ACE:SUPER-UX:*:*)
+ echo sxace-nec-superux"$UNAME_RELEASE"
exit ;;
Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ echo powerpc-apple-rhapsody"$UNAME_RELEASE"
exit ;;
*:Rhapsody:*:*)
- echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"
exit ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- eval $set_cc_for_build
+ eval "$set_cc_for_build"
if test "$UNAME_PROCESSOR" = unknown ; then
UNAME_PROCESSOR=powerpc
fi
- if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then
+ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
then
case $UNAME_PROCESSOR in
i386) UNAME_PROCESSOR=x86_64 ;;
powerpc) UNAME_PROCESSOR=powerpc64 ;;
esac
fi
+ # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
+ if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_PPC >/dev/null
+ then
+ UNAME_PROCESSOR=powerpc
+ fi
fi
elif test "$UNAME_PROCESSOR" = i386 ; then
# Avoid executing cc on OS X 10.9, as it ships with a stub
@@ -1296,27 +1317,33 @@ EOF
# that Apple uses in portable devices.
UNAME_PROCESSOR=x86_64
fi
- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
UNAME_PROCESSOR=`uname -p`
- if test "$UNAME_PROCESSOR" = "x86"; then
+ if test "$UNAME_PROCESSOR" = x86; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
- echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE"
exit ;;
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
- NEO-?:NONSTOP_KERNEL:*:*)
- echo neo-tandem-nsk${UNAME_RELEASE}
+ NEO-*:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk"$UNAME_RELEASE"
exit ;;
NSE-*:NONSTOP_KERNEL:*:*)
- echo nse-tandem-nsk${UNAME_RELEASE}
+ echo nse-tandem-nsk"$UNAME_RELEASE"
+ exit ;;
+ NSR-*:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk"$UNAME_RELEASE"
exit ;;
- NSR-?:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk${UNAME_RELEASE}
+ NSV-*:NONSTOP_KERNEL:*:*)
+ echo nsv-tandem-nsk"$UNAME_RELEASE"
+ exit ;;
+ NSX-*:NONSTOP_KERNEL:*:*)
+ echo nsx-tandem-nsk"$UNAME_RELEASE"
exit ;;
*:NonStop-UX:*:*)
echo mips-compaq-nonstopux
@@ -1325,18 +1352,18 @@ EOF
echo bs2000-siemens-sysv
exit ;;
DS/*:UNIX_System_V:*:*)
- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE"
exit ;;
*:Plan9:*:*)
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
# operating systems.
- if test "$cputype" = "386"; then
+ if test "$cputype" = 386; then
UNAME_MACHINE=i386
else
UNAME_MACHINE="$cputype"
fi
- echo ${UNAME_MACHINE}-unknown-plan9
+ echo "$UNAME_MACHINE"-unknown-plan9
exit ;;
*:TOPS-10:*:*)
echo pdp10-unknown-tops10
@@ -1357,14 +1384,14 @@ EOF
echo pdp10-unknown-its
exit ;;
SEI:*:*:SEIUX)
- echo mips-sei-seiux${UNAME_RELEASE}
+ echo mips-sei-seiux"$UNAME_RELEASE"
exit ;;
*:DragonFly:*:*)
- echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
exit ;;
*:*VMS:*:*)
UNAME_MACHINE=`(uname -p) 2>/dev/null`
- case "${UNAME_MACHINE}" in
+ case "$UNAME_MACHINE" in
A*) echo alpha-dec-vms ; exit ;;
I*) echo ia64-dec-vms ; exit ;;
V*) echo vax-dec-vms ; exit ;;
@@ -1373,34 +1400,48 @@ EOF
echo i386-pc-xenix
exit ;;
i*86:skyos:*:*)
- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`"
exit ;;
i*86:rdos:*:*)
- echo ${UNAME_MACHINE}-pc-rdos
+ echo "$UNAME_MACHINE"-pc-rdos
exit ;;
i*86:AROS:*:*)
- echo ${UNAME_MACHINE}-pc-aros
+ echo "$UNAME_MACHINE"-pc-aros
exit ;;
x86_64:VMkernel:*:*)
- echo ${UNAME_MACHINE}-unknown-esx
+ echo "$UNAME_MACHINE"-unknown-esx
+ exit ;;
+ amd64:Isilon\ OneFS:*:*)
+ echo x86_64-unknown-onefs
exit ;;
esac
+echo "$0: unable to guess system type" >&2
+
+case "$UNAME_MACHINE:$UNAME_SYSTEM" in
+ mips:Linux | mips64:Linux)
+ # If we got here on MIPS GNU/Linux, output extra information.
+ cat >&2 <<EOF
+
+NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize
+the system type. Please install a C compiler and try again.
+EOF
+ ;;
+esac
+
cat >&2 <<EOF
-$0: unable to guess system type
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
+This script (version $timestamp), has failed to recognize the
+operating system you are using. If your script is old, overwrite *all*
+copies of config.guess and config.sub with the latest versions from:
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+ https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
and
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+ https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <config-patches@gnu.org> in order to provide the needed
-information to handle your system.
+If $0 has already been updated, send the following data and any
+information you think might be pertinent to config-patches@gnu.org to
+provide the necessary information to handle your system.
config.guess timestamp = $timestamp
@@ -1419,16 +1460,16 @@ hostinfo = `(hostinfo) 2>/dev/null`
/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
+UNAME_MACHINE = "$UNAME_MACHINE"
+UNAME_RELEASE = "$UNAME_RELEASE"
+UNAME_SYSTEM = "$UNAME_SYSTEM"
+UNAME_VERSION = "$UNAME_VERSION"
EOF
exit 1
# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
diff --git a/config.h b/config.h
index 9ce0ffc6..1dc9c7fc 100644
--- a/config.h
+++ b/config.h
@@ -1,11 +1,23 @@
/* config.h. Generated from config.h.in by configure. */
/* 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 */
@@ -16,40 +28,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' */
#define HAVE_DECL_ETHER_HOSTTON 1
-/* 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. */
+#define HAVE_FFS 1
+
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
#define HAVE_FSEEKO 1
+/* 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. */
#define HAVE_INTTYPES_H 1
+/* Define to 1 if you have the `dag' library (-ldag). */
+/* #undef HAVE_LIBDAG */
+
/* if libdlpi exists */
/* #undef HAVE_LIBDLPI */
@@ -77,24 +94,24 @@
/* Define to 1 if you have the <linux/ethtool.h> header file. */
#define HAVE_LINUX_ETHTOOL_H 1
+/* 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. */
#define HAVE_LINUX_IF_BONDING_H 1
-/* Define to 1 if you have the <linux/if_packet.h> header file. */
-#define HAVE_LINUX_IF_PACKET_H 1
-
/* Define to 1 if you have the <linux/net_tstamp.h> header file. */
#define HAVE_LINUX_NET_TSTAMP_H 1
+/* Define to 1 if you have the <linux/socket.h> header file. */
+#define HAVE_LINUX_SOCKET_H 1
+
/* Define to 1 if you have the <linux/sockios.h> header file. */
#define HAVE_LINUX_SOCKIOS_H 1
-/* if tp_vlan_tci exists */
-#define HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI 1
-
-/* Define to 1 if you have the <linux/types.h> header file. */
-#define HAVE_LINUX_TYPES_H 1
-
/* Define to 1 if you have the <linux/usbdevice_fs.h> header file. */
#define HAVE_LINUX_USBDEVICE_FS_H 1
@@ -104,24 +121,30 @@
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
-/* Define to 1 if you have the <netinet/ether.h> header file. */
-#define HAVE_NETINET_ETHER_H 1
-
-/* Define to 1 if you have the <netinet/if_ether.h> header file. */
-#define HAVE_NETINET_IF_ETHER_H 1
-
-/* 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. */
#define HAVE_NETPACKET_PACKET_H 1
+/* 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 */
@@ -137,18 +160,18 @@
/* Define to 1 if you have the `snprintf' function. */
#define HAVE_SNPRINTF 1
-/* if struct sockaddr has the sa_len member */
-/* #undef HAVE_SOCKADDR_SA_LEN */
-
-/* if struct sockaddr_storage exists */
-#define HAVE_SOCKADDR_STORAGE 1
-
-/* define if socklen_t is defined */
+/* Define to 1 if the system has the type `socklen_t'. */
#define HAVE_SOCKLEN_T 1
/* 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. */
#define HAVE_STDINT_H 1
@@ -158,12 +181,21 @@
/* Define to 1 if you have the `strerror' function. */
#define HAVE_STRERROR 1
+/* Define to 1 if you have the `strerror_r' function. */
+#define HAVE_STRERROR_R 1
+
+/* 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. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
+/* Define to 1 if you have the `strlcat' function. */
+#define HAVE_STRLCAT 1
+
/* Define to 1 if you have the `strlcpy' function. */
#define HAVE_STRLCPY 1
@@ -176,8 +208,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'. */
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+
+/* Define to 1 if `tp_vlan_tci' is a member of `struct tpacket_auxdata'. */
+#define HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI 1
+
+/* Define to 1 if the system has the type `struct tpacket_stats'. */
+#define HAVE_STRUCT_TPACKET_STATS 1
+
+/* Define to 1 if `bRequestType' is a member of `struct
+ usbdevfs_ctrltransfer'. */
+#define HAVE_STRUCT_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE 1
/* Define to 1 if you have the <sys/bufmod.h> header file. */
/* #undef HAVE_SYS_BUFMOD_H */
@@ -185,11 +239,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. */
-#define HAVE_SYS_SELECT_H 1
+/* 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 */
@@ -203,24 +260,12 @@
/* define if you have the TurboCap API */
/* #undef HAVE_TC_API */
-/* if if_packet.h has tpacket_stats defined */
-#define HAVE_TPACKET_STATS 1
-
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
-/* if struct usbdevfs_ctrltransfer has bRequestType */
-#define HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE 1
-
/* Define to 1 if you have the `vsnprintf' function. */
#define HAVE_VSNPRINTF 1
-/* define if the system supports zerocopy BPF */
-/* #undef HAVE_ZEROCOPY_BPF */
-
-/* define if your compiler has __attribute__ */
-#define HAVE___ATTRIBUTE__ 1
-
/* IPv6 */
#define INET6 1
@@ -236,6 +281,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 */
@@ -243,22 +291,19 @@
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
-#define PACKAGE_NAME ""
+#define PACKAGE_NAME "pcap"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING ""
+#define PACKAGE_STRING "pcap 1.9.0-PRE-GIT"
/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME ""
+#define PACKAGE_TARNAME "pcap"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION ""
-
-/* /dev/dlpi directory */
-/* #undef PCAP_DEV_PREFIX */
+#define PACKAGE_VERSION "1.9.0-PRE-GIT"
/* target host supports Bluetooth sniffing */
/* #undef PCAP_SUPPORT_BT */
@@ -272,21 +317,30 @@
/* target host supports netfilter sniffing */
#define PCAP_SUPPORT_NETFILTER 1
-/* use Linux packet ring capture if available */
+/* target host supports netmap */
+/* #undef PCAP_SUPPORT_NETMAP */
+
+/* use packet ring capture support on Linux if available */
#define PCAP_SUPPORT_PACKET_RING 1
+/* target host supports RDMA sniffing */
+/* #undef PCAP_SUPPORT_RDMASNIFF */
+
/* target host supports USB sniffing */
#define PCAP_SUPPORT_USB 1
/* 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. */
#define STDC_HEADERS 1
+/* Define to 1 if strings.h declares `ffs' */
+#define 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 */
@@ -311,38 +365,11 @@
/* define on AIX to get certain functions */
/* #undef _SUN */
-/* define if your compiler allows __attribute__((format)) without a warning */
-#define __ATTRIBUTE___FORMAT_OK 1
-
/* to handle Ultrix compilers that don't support const in prototypes */
/* #undef const */
/* Define as token for inline if inlining supported */
#define inline 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/config.h.in b/config.h.in
index e85b2a3f..b1a20a44 100644
--- a/config.h.in
+++ b/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/config.sub b/config.sub
index bc855a2a..c95acc68 100644..100755
--- a/config.sub
+++ b/config.sub
@@ -1,8 +1,8 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2015 Free Software Foundation, Inc.
+# Copyright 1992-2018 Free Software Foundation, Inc.
-timestamp='2015-02-22'
+timestamp='2018-07-03'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@ timestamp='2015-02-22'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -33,7 +33,7 @@ timestamp='2015-02-22'
# Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
@@ -53,12 +53,11 @@ timestamp='2015-02-22'
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
- $0 [OPTION] ALIAS
+Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
Canonicalize a configuration name.
-Operation modes:
+Options:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
@@ -68,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2015 Free Software Foundation, Inc.
+Copyright 1992-2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -95,7 +94,7 @@ while test $# -gt 0 ; do
*local*)
# First pass through any local machine types.
- echo $1
+ echo "$1"
exit ;;
* )
@@ -111,134 +110,455 @@ case $# in
exit 1;;
esac
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
- nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
- linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
- knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
- kopensolaris*-gnu* | \
- storm-chaos* | os2-emx* | rtmk-nova*)
- os=-$maybe_os
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
- ;;
- android-linux)
- os=-linux-android
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
- ;;
- *)
- basic_machine=`echo $1 | sed 's/-[^-]*$//'`
- if [ $basic_machine != $1 ]
- then os=`echo $1 | sed 's/.*-/-/'`
- else os=; fi
- ;;
-esac
+# Split fields of configuration type
+IFS="-" read -r field1 field2 field3 field4 <<EOF
+$1
+EOF
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work. We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
- -sun*os*)
- # Prevent following clause from handling this invalid input.
- ;;
- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis | -knuth | -cray | -microblaze*)
- os=
- basic_machine=$1
- ;;
- -bluegene*)
- os=-cnk
- ;;
- -sim | -cisco | -oki | -wec | -winbond)
- os=
- basic_machine=$1
- ;;
- -scout)
- ;;
- -wrs)
- os=-vxworks
- basic_machine=$1
- ;;
- -chorusos*)
- os=-chorusos
- basic_machine=$1
- ;;
- -chorusrdb)
- os=-chorusrdb
- basic_machine=$1
- ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- -sco6)
- os=-sco5v6
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5)
- os=-sco3.2v5
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco4)
- os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2v[4-9]*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5v6*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco*)
- os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -udk*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -isc)
- os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -clix*)
- basic_machine=clipper-intergraph
- ;;
- -isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -lynx*178)
- os=-lynxos178
- ;;
- -lynx*5)
- os=-lynxos5
- ;;
- -lynx*)
- os=-lynxos
+# Separate into logical components for further validation
+case $1 in
+ *-*-*-*-*)
+ echo Invalid configuration \`"$1"\': more than four components >&2
+ exit 1
;;
- -ptx*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ *-*-*-*)
+ basic_machine=$field1-$field2
+ os=$field3-$field4
;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ *-*-*)
+ # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two
+ # parts
+ maybe_os=$field2-$field3
+ case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc \
+ | linux-newlib* | linux-musl* | linux-uclibc* | uclinux-uclibc* \
+ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
+ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
+ | storm-chaos* | os2-emx* | rtmk-nova*)
+ basic_machine=$field1
+ os=$maybe_os
+ ;;
+ android-linux)
+ basic_machine=$field1-unknown
+ os=linux-android
+ ;;
+ *)
+ basic_machine=$field1-$field2
+ os=$field3
+ ;;
+ esac
;;
- -psos*)
- os=-psos
+ *-*)
+ # Second component is usually, but not always the OS
+ case $field2 in
+ # Prevent following clause from handling this valid os
+ sun*os*)
+ basic_machine=$field1
+ os=$field2
+ ;;
+ # Manufacturers
+ dec* | mips* | sequent* | encore* | pc532* | sgi* | sony* \
+ | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \
+ | unicom* | ibm* | next | hp | isi* | apollo | altos* \
+ | convergent* | ncr* | news | 32* | 3600* | 3100* | hitachi* \
+ | c[123]* | convex* | sun | crds | omron* | dg | ultra | tti* \
+ | harris | dolphin | highlevel | gould | cbm | ns | masscomp \
+ | apple | axis | knuth | cray | microblaze* \
+ | sim | cisco | oki | wec | wrs | winbond)
+ basic_machine=$field1-$field2
+ os=
+ ;;
+ *)
+ basic_machine=$field1
+ os=$field2
+ ;;
+ esac
;;
- -mint | -mint[0-9]*)
- basic_machine=m68k-atari
- os=-mint
+ *)
+ # Convert single-component short-hands not valid as part of
+ # multi-component configurations.
+ case $field1 in
+ 386bsd)
+ basic_machine=i386-pc
+ os=bsd
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=udi
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=scout
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=bsd
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=sysv
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=aros
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=linux
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=cegcc
+ ;;
+ cray)
+ basic_machine=j90-cray
+ os=unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=unicosmp
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=msdosdjgpp
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=ebmon
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=ose
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=go32
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=sysv3
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=hpux
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=proelf
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=mach
+ ;;
+ vsta)
+ basic_machine=i386-unknown
+ os=vsta
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=sysv
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=linux
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=sysv
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=mingw64
+ ;;
+ mingw32)
+ basic_machine=i686-pc
+ os=mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=mingw32ce
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=morphos
+ ;;
+ moxiebox)
+ basic_machine=moxie-unknown
+ os=moxiebox
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=msdos
+ ;;
+ msys)
+ basic_machine=i686-pc
+ os=msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=sysv
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=nonstopux
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=os68k
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=linux
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=pw32
+ ;;
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=rdos
+ ;;
+ rdos32)
+ basic_machine=i386-pc
+ os=rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=coff
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=udi
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=seiux
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=sysv2
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=sysv4
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=solaris2
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=unicos
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=tops20
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=vms
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=vxworks
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=mingw32
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=unicos
+ ;;
+ *)
+ basic_machine=$1
+ os=
+ ;;
+ esac
;;
esac
@@ -253,17 +573,18 @@ case $basic_machine in
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arceb \
- | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv6m | armv[78][arm] \
| avr | avr32 \
+ | ba \
| be32 | be64 \
| bfin \
- | c4x | c8051 | clipper \
+ | c4x | c8051 | clipper | csky \
| d10v | d30v | dlx | dsp16xx \
- | epiphany \
+ | e2k | epiphany \
| fido | fr30 | frv | ft32 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
- | i370 | i860 | i960 | ia64 \
+ | i370 | i860 | i960 | ia16 | ia64 \
| ip2k | iq2000 \
| k1om \
| le32 | le64 \
@@ -296,16 +617,18 @@ case $basic_machine in
| mt \
| msp430 \
| nds32 | nds32le | nds32be \
+ | nfp \
| nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
| open8 | or1k | or1knd | or32 \
- | pdp10 | pdp11 | pj | pjl \
+ | pdp10 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pru \
| pyramid \
- | riscv32 | riscv64 \
+ | riscv | riscv32 | riscv64 \
| rl78 | rx \
| score \
- | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
@@ -314,7 +637,7 @@ case $basic_machine in
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| visium \
- | we32k \
+ | wasm32 \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
basic_machine=$basic_machine-unknown
@@ -333,20 +656,23 @@ case $basic_machine in
;;
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
basic_machine=$basic_machine-unknown
- os=-none
+ os=${os:-none}
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
;;
- m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ m9s12z | m68hcs12z | hcs12z | s12z)
+ basic_machine=s12z-unknown
+ os=${os:-none}
;;
ms1)
basic_machine=mt-unknown
;;
-
strongarm | thumb | xscale)
basic_machine=arm-unknown
;;
xgate)
basic_machine=$basic_machine-unknown
- os=-none
+ os=${os:-none}
;;
xscaleeb)
basic_machine=armeb-unknown
@@ -362,11 +688,6 @@ case $basic_machine in
i*86 | x86_64)
basic_machine=$basic_machine-pc
;;
- # Object if more than one company name word.
- *-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
@@ -376,17 +697,18 @@ case $basic_machine in
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
+ | ba-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
- | c8051-* | clipper-* | craynv-* | cydra-* \
+ | c8051-* | clipper-* | craynv-* | csky-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
- | elxsi-* \
+ | e2k-* | elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| hexagon-* \
- | i*86-* | i860-* | i960-* | ia64-* \
+ | i*86-* | i860-* | i960-* | ia16-* | ia64-* \
| ip2k-* | iq2000-* \
| k1om-* \
| le32-* | le64-* \
@@ -420,6 +742,7 @@ case $basic_machine in
| mt-* \
| msp430-* \
| nds32-* | nds32le-* | nds32be-* \
+ | nfp-* \
| nios-* | nios2-* | nios2eb-* | nios2el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| open8-* \
@@ -427,13 +750,15 @@ case $basic_machine in
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pru-* \
| pyramid-* \
+ | riscv-* | riscv32-* | riscv64-* \
| rl78-* | romp-* | rs6000-* | rx-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
| tahoe-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tile*-* \
@@ -442,6 +767,7 @@ case $basic_machine in
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
| visium-* \
+ | wasm32-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
@@ -454,138 +780,77 @@ case $basic_machine in
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
- 386bsd)
- basic_machine=i386-unknown
- os=-bsd
- ;;
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
basic_machine=m68000-att
;;
3b*)
basic_machine=we32k-att
;;
- a29khif)
- basic_machine=a29k-amd
- os=-udi
- ;;
abacus)
basic_machine=abacus-unknown
;;
- adobe68k)
- basic_machine=m68010-adobe
- os=-scout
- ;;
alliant | fx80)
basic_machine=fx80-alliant
;;
altos | altos3068)
basic_machine=m68k-altos
;;
- am29k)
- basic_machine=a29k-none
- os=-bsd
- ;;
amd64)
basic_machine=x86_64-pc
;;
amd64-*)
- basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- amdahl)
- basic_machine=580-amdahl
- os=-sysv
+ basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
amiga | amiga-*)
basic_machine=m68k-unknown
;;
- amigaos | amigados)
- basic_machine=m68k-unknown
- os=-amigaos
- ;;
- amigaunix | amix)
- basic_machine=m68k-unknown
- os=-sysv4
- ;;
- apollo68)
- basic_machine=m68k-apollo
- os=-sysv
- ;;
- apollo68bsd)
- basic_machine=m68k-apollo
- os=-bsd
- ;;
- aros)
- basic_machine=i386-pc
- os=-aros
- ;;
- aux)
- basic_machine=m68k-apple
- os=-aux
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- blackfin)
- basic_machine=bfin-unknown
- os=-linux
+ asmjs)
+ basic_machine=asmjs-unknown
;;
blackfin-*)
- basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
+ basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ os=linux
;;
bluegene*)
basic_machine=powerpc-ibm
- os=-cnk
+ os=cnk
;;
c54x-*)
- basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
c55x-*)
- basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
c6x-*)
- basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
c90)
basic_machine=c90-cray
- os=-unicos
- ;;
- cegcc)
- basic_machine=arm-unknown
- os=-cegcc
+ os=${os:-unicos}
;;
convex-c1)
basic_machine=c1-convex
- os=-bsd
+ os=bsd
;;
convex-c2)
basic_machine=c2-convex
- os=-bsd
+ os=bsd
;;
convex-c32)
basic_machine=c32-convex
- os=-bsd
+ os=bsd
;;
convex-c34)
basic_machine=c34-convex
- os=-bsd
+ os=bsd
;;
convex-c38)
basic_machine=c38-convex
- os=-bsd
- ;;
- cray | j90)
- basic_machine=j90-cray
- os=-unicos
- ;;
- craynv)
- basic_machine=craynv-cray
- os=-unicosmp
+ os=bsd
;;
cr16 | cr16-*)
basic_machine=cr16-unknown
- os=-elf
+ os=${os:-elf}
;;
crds | unos)
basic_machine=m68k-crds
@@ -598,7 +863,7 @@ case $basic_machine in
;;
crx)
basic_machine=crx-unknown
- os=-elf
+ os=${os:-elf}
;;
da30 | da30-*)
basic_machine=m68k-da30
@@ -608,50 +873,38 @@ case $basic_machine in
;;
decsystem10* | dec10*)
basic_machine=pdp10-dec
- os=-tops10
+ os=tops10
;;
decsystem20* | dec20*)
basic_machine=pdp10-dec
- os=-tops20
+ os=tops20
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
;;
- delta88)
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- dicos)
- basic_machine=i686-pc
- os=-dicos
- ;;
- djgpp)
- basic_machine=i586-pc
- os=-msdosdjgpp
- ;;
dpx20 | dpx20-*)
basic_machine=rs6000-bull
- os=-bosx
+ os=${os:-bosx}
;;
- dpx2* | dpx2*-bull)
+ dpx2*)
basic_machine=m68k-bull
- os=-sysv3
+ os=sysv3
;;
- ebmon29k)
- basic_machine=a29k-amd
- os=-ebmon
+ e500v[12])
+ basic_machine=powerpc-unknown
+ os=$os"spe"
;;
- elxsi)
- basic_machine=elxsi-elxsi
- os=-bsd
+ e500v[12]-*)
+ basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ os=$os"spe"
;;
encore | umax | mmax)
basic_machine=ns32k-encore
;;
- es1800 | OSE68k | ose68k | ose | OSE)
- basic_machine=m68k-ericsson
- os=-ose
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=${os:-bsd}
;;
fx2800)
basic_machine=i860-alliant
@@ -659,45 +912,13 @@ case $basic_machine in
genix)
basic_machine=ns32k-ns
;;
- gmicro)
- basic_machine=tron-gmicro
- os=-sysv
- ;;
- go32)
- basic_machine=i386-pc
- os=-go32
- ;;
h3050r* | hiux*)
basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- h8300hms)
- basic_machine=h8300-hitachi
- os=-hms
- ;;
- h8300xray)
- basic_machine=h8300-hitachi
- os=-xray
- ;;
- h8500hms)
- basic_machine=h8500-hitachi
- os=-hms
- ;;
- harris)
- basic_machine=m88k-harris
- os=-sysv3
+ os=hiuxwe2
;;
hp300-*)
basic_machine=m68k-hp
;;
- hp300bsd)
- basic_machine=m68k-hp
- os=-bsd
- ;;
- hp300hpux)
- basic_machine=m68k-hp
- os=-hpux
- ;;
hp3k9[0-9][0-9] | hp9[0-9][0-9])
basic_machine=hppa1.0-hp
;;
@@ -727,200 +948,82 @@ case $basic_machine in
hp9k8[0-9][0-9] | hp8[0-9][0-9])
basic_machine=hppa1.0-hp
;;
- hppa-next)
- os=-nextstep3
- ;;
- hppaosf)
- basic_machine=hppa1.1-hp
- os=-osf
- ;;
- hppro)
- basic_machine=hppa1.1-hp
- os=-proelf
- ;;
i370-ibm* | ibm*)
basic_machine=i370-ibm
;;
i*86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv32
+ basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
+ os=sysv32
;;
i*86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv4
+ basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
+ os=sysv4
;;
i*86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv
+ basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
+ os=sysv
;;
i*86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-solaris2
- ;;
- i386mach)
- basic_machine=i386-mach
- os=-mach
+ basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
+ os=solaris2
;;
- i386-vsta | vsta)
- basic_machine=i386-unknown
- os=-vsta
+ j90 | j90-cray)
+ basic_machine=j90-cray
+ os=${os:-unicos}
;;
iris | iris4d)
basic_machine=mips-sgi
case $os in
- -irix*)
+ irix*)
;;
*)
- os=-irix4
+ os=irix4
;;
esac
;;
- isi68 | isi)
- basic_machine=m68k-isi
- os=-sysv
- ;;
leon-*|leon[3-9]-*)
- basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
- ;;
- m68knommu)
- basic_machine=m68k-unknown
- os=-linux
+ basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'`
;;
m68knommu-*)
- basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
- magnum | m3230)
- basic_machine=mips-mips
- os=-sysv
- ;;
- merlin)
- basic_machine=ns32k-utek
- os=-sysv
+ basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ os=linux
;;
microblaze*)
basic_machine=microblaze-xilinx
;;
- mingw64)
- basic_machine=x86_64-pc
- os=-mingw64
- ;;
- mingw32)
- basic_machine=i686-pc
- os=-mingw32
- ;;
- mingw32ce)
- basic_machine=arm-unknown
- os=-mingw32ce
- ;;
miniframe)
basic_machine=m68000-convergent
;;
- *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)
basic_machine=m68k-atari
- os=-mint
+ os=mint
;;
mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`
;;
mips3*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
- ;;
- monitor)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- morphos)
- basic_machine=powerpc-unknown
- os=-morphos
- ;;
- moxiebox)
- basic_machine=moxie-unknown
- os=-moxiebox
- ;;
- msdos)
- basic_machine=i386-pc
- os=-msdos
+ basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown
;;
ms1-*)
- basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
- ;;
- msys)
- basic_machine=i686-pc
- os=-msys
- ;;
- mvs)
- basic_machine=i370-ibm
- os=-mvs
- ;;
- nacl)
- basic_machine=le32-unknown
- os=-nacl
- ;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- ;;
- netbsd386)
- basic_machine=i386-unknown
- os=-netbsd
- ;;
- netwinder)
- basic_machine=armv4l-rebel
- os=-linux
- ;;
- news | news700 | news800 | news900)
- basic_machine=m68k-sony
- os=-newsos
- ;;
- news1000)
- basic_machine=m68030-sony
- os=-newsos
+ basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'`
;;
news-3600 | risc-news)
basic_machine=mips-sony
- os=-newsos
+ os=newsos
;;
- necv70)
- basic_machine=v70-nec
- os=-sysv
- ;;
- next | m*-next )
+ next | m*-next)
basic_machine=m68k-next
case $os in
- -nextstep* )
+ nextstep* )
;;
- -ns2*)
- os=-nextstep2
+ ns2*)
+ os=nextstep2
;;
*)
- os=-nextstep3
+ os=nextstep3
;;
esac
;;
- nh3000)
- basic_machine=m68k-harris
- os=-cxux
- ;;
- nh[45]000)
- basic_machine=m88k-harris
- os=-cxux
- ;;
- nindy960)
- basic_machine=i960-intel
- os=-nindy
- ;;
- mon960)
- basic_machine=i960-intel
- os=-mon960
- ;;
- nonstopux)
- basic_machine=mips-compaq
- os=-nonstopux
- ;;
np1)
basic_machine=np1-gould
;;
@@ -933,40 +1036,26 @@ case $basic_machine in
nsr-tandem)
basic_machine=nsr-tandem
;;
+ nsv-tandem)
+ basic_machine=nsv-tandem
+ ;;
+ nsx-tandem)
+ basic_machine=nsx-tandem
+ ;;
op50n-* | op60c-*)
basic_machine=hppa1.1-oki
- os=-proelf
+ os=proelf
;;
openrisc | openrisc-*)
basic_machine=or32-unknown
;;
- os400)
- basic_machine=powerpc-ibm
- os=-os400
- ;;
- OSE68000 | ose68000)
- basic_machine=m68000-ericsson
- os=-ose
- ;;
- os68k)
- basic_machine=m68k-none
- os=-os68k
- ;;
pa-hitachi)
basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- paragon)
- basic_machine=i860-intel
- os=-osf
- ;;
- parisc)
- basic_machine=hppa-unknown
- os=-linux
+ os=hiuxwe2
;;
parisc-*)
- basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
+ basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ os=linux
;;
pbd)
basic_machine=sparc-tti
@@ -981,7 +1070,7 @@ case $basic_machine in
basic_machine=i386-pc
;;
pc98-*)
- basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
@@ -996,16 +1085,16 @@ case $basic_machine in
basic_machine=i786-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
pentium4-*)
- basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
@@ -1015,43 +1104,27 @@ case $basic_machine in
ppc | ppcbe) basic_machine=powerpc-unknown
;;
ppc-* | ppcbe-*)
- basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
- ppcle | powerpclittle | ppc-le | powerpc-little)
+ ppcle | powerpclittle)
basic_machine=powerpcle-unknown
;;
ppcle-* | powerpclittle-*)
- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
;;
- ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
- ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ ppc64le | powerpc64little)
basic_machine=powerpc64le-unknown
;;
ppc64le-* | powerpc64little-*)
- basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
ps2)
basic_machine=i386-ibm
;;
- pw32)
- basic_machine=i586-unknown
- os=-pw32
- ;;
- rdos | rdos64)
- basic_machine=x86_64-pc
- os=-rdos
- ;;
- rdos32)
- basic_machine=i386-pc
- os=-rdos
- ;;
- rom68k)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
rm[46]00)
basic_machine=mips-siemens
;;
@@ -1064,10 +1137,6 @@ case $basic_machine in
s390x | s390x-*)
basic_machine=s390x-ibm
;;
- sa29200)
- basic_machine=a29k-amd
- os=-udi
- ;;
sb1)
basic_machine=mipsisa64sb1-unknown
;;
@@ -1076,32 +1145,17 @@ case $basic_machine in
;;
sde)
basic_machine=mipsisa32-sde
- os=-elf
- ;;
- sei)
- basic_machine=mips-sei
- os=-seiux
+ os=${os:-elf}
;;
sequent)
basic_machine=i386-sequent
;;
- sh)
- basic_machine=sh-hitachi
- os=-hms
- ;;
sh5el)
basic_machine=sh5le-unknown
;;
- sh64)
- basic_machine=sh64-unknown
- ;;
- sparclite-wrs | simso-wrs)
+ simso-wrs)
basic_machine=sparclite-wrs
- os=-vxworks
- ;;
- sps7)
- basic_machine=m68k-bull
- os=-sysv2
+ os=vxworks
;;
spur)
basic_machine=spur-unknown
@@ -1109,44 +1163,12 @@ case $basic_machine in
st2000)
basic_machine=m68k-tandem
;;
- stratus)
- basic_machine=i860-stratus
- os=-sysv4
- ;;
strongarm-* | thumb-*)
- basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;;
sun2)
basic_machine=m68000-sun
;;
- sun2os3)
- basic_machine=m68000-sun
- os=-sunos3
- ;;
- sun2os4)
- basic_machine=m68000-sun
- os=-sunos4
- ;;
- sun3os3)
- basic_machine=m68k-sun
- os=-sunos3
- ;;
- sun3os4)
- basic_machine=m68k-sun
- os=-sunos4
- ;;
- sun4os3)
- basic_machine=sparc-sun
- os=-sunos3
- ;;
- sun4os4)
- basic_machine=sparc-sun
- os=-sunos4
- ;;
- sun4sol2)
- basic_machine=sparc-sun
- os=-solaris2
- ;;
sun3 | sun3-*)
basic_machine=m68k-sun
;;
@@ -1156,25 +1178,9 @@ case $basic_machine in
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
;;
- sv1)
- basic_machine=sv1-cray
- os=-unicos
- ;;
- symmetry)
- basic_machine=i386-sequent
- os=-dynix
- ;;
- t3e)
- basic_machine=alphaev5-cray
- os=-unicos
- ;;
- t90)
- basic_machine=t90-cray
- os=-unicos
- ;;
tile*)
basic_machine=$basic_machine-unknown
- os=-linux-gnu
+ os=linux-gnu
;;
tx39)
basic_machine=mipstx39-unknown
@@ -1182,85 +1188,32 @@ case $basic_machine in
tx39el)
basic_machine=mipstx39el-unknown
;;
- toad1)
- basic_machine=pdp10-xkl
- os=-tops20
- ;;
tower | tower-32)
basic_machine=m68k-ncr
;;
- tpf)
- basic_machine=s390x-ibm
- os=-tpf
- ;;
- udi29k)
- basic_machine=a29k-amd
- os=-udi
- ;;
- ultra3)
- basic_machine=a29k-nyu
- os=-sym1
- ;;
- v810 | necv810)
- basic_machine=v810-nec
- os=-none
- ;;
- vaxv)
- basic_machine=vax-dec
- os=-sysv
- ;;
- vms)
- basic_machine=vax-dec
- os=-vms
- ;;
vpp*|vx|vx-*)
basic_machine=f301-fujitsu
;;
- vxworks960)
- basic_machine=i960-wrs
- os=-vxworks
- ;;
- vxworks68)
- basic_machine=m68k-wrs
- os=-vxworks
- ;;
- vxworks29k)
- basic_machine=a29k-wrs
- os=-vxworks
- ;;
w65*)
basic_machine=w65-wdc
- os=-none
+ os=none
;;
w89k-*)
basic_machine=hppa1.1-winbond
- os=-proelf
+ os=proelf
;;
- xbox)
- basic_machine=i686-pc
- os=-mingw32
+ x64)
+ basic_machine=x86_64-pc
;;
xps | xps100)
basic_machine=xps100-honeywell
;;
xscale-* | xscalee[bl]-*)
- basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
- ;;
- ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- z8k-*-coff)
- basic_machine=z8k-unknown
- os=-sim
- ;;
- z80-*-coff)
- basic_machine=z80-unknown
- os=-sim
+ basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
;;
none)
basic_machine=none-none
- os=-none
+ os=${os:-none}
;;
# Here we handle the default manufacturer of certain CPU types. It is in
@@ -1286,10 +1239,6 @@ case $basic_machine in
vax)
basic_machine=vax-dec
;;
- pdp10)
- # there are many clones, so DEC is not a safe bet
- basic_machine=pdp10-unknown
- ;;
pdp11)
basic_machine=pdp11-dec
;;
@@ -1299,9 +1248,6 @@ case $basic_machine in
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
- sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
- basic_machine=sparc-sun
- ;;
cydra)
basic_machine=cydra-cydrome
;;
@@ -1321,7 +1267,7 @@ case $basic_machine in
# Make sure to match an already-canonicalized machine name.
;;
*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
exit 1
;;
esac
@@ -1329,10 +1275,10 @@ esac
# Here we canonicalize certain aliases for manufacturers.
case $basic_machine in
*-digital*)
- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'`
;;
*-commodore*)
- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'`
;;
*)
;;
@@ -1340,197 +1286,246 @@ esac
# Decode manufacturer-specific aliases for certain operating systems.
-if [ x"$os" != x"" ]
+if [ x$os != x ]
then
case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
- # -solaris* is a basic system type, with this one exception.
- -auroraux)
- os=-auroraux
+ # First match some system type aliases that might get confused
+ # with valid system types.
+ # solaris* is a basic system type, with this one exception.
+ auroraux)
+ os=auroraux
;;
- -solaris1 | -solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ bluegene*)
+ os=cnk
;;
- -solaris)
- os=-solaris2
+ solaris1 | solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
- -svr4*)
- os=-sysv4
+ solaris)
+ os=solaris2
;;
- -unixware*)
- os=-sysv4.2uw
+ unixware*)
+ os=sysv4.2uw
;;
- -gnu/linux*)
+ gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;;
- # First accept the basic system types.
+ # es1800 is here to avoid being matched by es* (a different OS)
+ es1800*)
+ os=ose
+ ;;
+ # Some version numbers need modification
+ chorusos*)
+ os=chorusos
+ ;;
+ isc)
+ os=isc2.2
+ ;;
+ sco6)
+ os=sco5v6
+ ;;
+ sco5)
+ os=sco3.2v5
+ ;;
+ sco4)
+ os=sco3.2v4
+ ;;
+ sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ ;;
+ sco3.2v[4-9]* | sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ ;;
+ scout)
+ # Don't match below
+ ;;
+ sco*)
+ os=sco3.2v2
+ ;;
+ psos*)
+ os=psos
+ ;;
+ # Now accept the basic system types.
# The portable systems comes first.
- # Each alternative MUST END IN A *, to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
- | -sym* | -kopensolaris* | -plan9* \
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* | -aros* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -bitrig* | -openbsd* | -solidbsd* \
- | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
- | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* | -cegcc* \
- | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
- | -linux-newlib* | -linux-musl* | -linux-uclibc* \
- | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
- | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
- | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
- | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+ # Each alternative MUST end in a * to match a version number.
+ # sysv* is not here because it comes later, after sysvr4.
+ gnu* | bsd* | mach* | minix* | genix* | ultrix* | irix* \
+ | *vms* | esix* | aix* | cnk* | sunos | sunos[34]*\
+ | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
+ | sym* | kopensolaris* | plan9* \
+ | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
+ | aos* | aros* | cloudabi* | sortix* \
+ | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
+ | clix* | riscos* | uniplus* | iris* | rtu* | xenix* \
+ | knetbsd* | mirbsd* | netbsd* \
+ | bitrig* | openbsd* | solidbsd* | libertybsd* \
+ | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \
+ | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
+ | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
+ | udi* | eabi* | lites* | ieee* | go32* | aux* | hcos* \
+ | chorusrdb* | cegcc* | glidix* \
+ | cygwin* | msys* | pe* | moss* | proelf* | rtems* \
+ | midipix* | mingw32* | mingw64* | linux-gnu* | linux-android* \
+ | linux-newlib* | linux-musl* | linux-uclibc* \
+ | uxpv* | beos* | mpeix* | udk* | moxiebox* \
+ | interix* | uwin* | mks* | rhapsody* | darwin* \
+ | openstep* | oskit* | conix* | pw32* | nonstopux* \
+ | storm-chaos* | tops10* | tenex* | tops20* | its* \
+ | os2* | vos* | palmos* | uclinux* | nucleus* \
+ | morphos* | superux* | rtmk* | windiss* \
+ | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \
+ | skyos* | haiku* | rdos* | toppers* | drops* | es* \
+ | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
+ | midnightbsd*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
- -qnx*)
+ qnx*)
case $basic_machine in
x86-* | i*86-*)
;;
*)
- os=-nto$os
+ os=nto-$os
;;
esac
;;
- -nto-qnx*)
+ hiux*)
+ os=hiuxwe2
;;
- -nto*)
- os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ nto-qnx*)
;;
- -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
- | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
- | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
- -mac*)
- os=`echo $os | sed -e 's|mac|macos|'`
+ sim | xray | os68k* | v88r* \
+ | windows* | osx | abug | netware* | os9* \
+ | macos* | mpw* | magic* | mmixware* | mon960* | lnews*)
;;
- -linux-dietlibc)
- os=-linux-dietlibc
+ linux-dietlibc)
+ os=linux-dietlibc
;;
- -linux*)
+ linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
- -sunos5*)
- os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ lynx*178)
+ os=lynxos178
+ ;;
+ lynx*5)
+ os=lynxos5
+ ;;
+ lynx*)
+ os=lynxos
;;
- -sunos6*)
- os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ mac*)
+ os=`echo "$os" | sed -e 's|mac|macos|'`
;;
- -opened*)
- os=-openedition
+ opened*)
+ os=openedition
;;
- -os400*)
- os=-os400
+ os400*)
+ os=os400
;;
- -wince*)
- os=-wince
+ sunos5*)
+ os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
;;
- -osfrose*)
- os=-osfrose
+ sunos6*)
+ os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
;;
- -osf*)
- os=-osf
+ wince*)
+ os=wince
;;
- -utek*)
- os=-bsd
+ utek*)
+ os=bsd
;;
- -dynix*)
- os=-bsd
+ dynix*)
+ os=bsd
;;
- -acis*)
- os=-aos
+ acis*)
+ os=aos
;;
- -atheos*)
- os=-atheos
+ atheos*)
+ os=atheos
;;
- -syllable*)
- os=-syllable
+ syllable*)
+ os=syllable
;;
- -386bsd)
- os=-bsd
+ 386bsd)
+ os=bsd
;;
- -ctix* | -uts*)
- os=-sysv
+ ctix* | uts*)
+ os=sysv
;;
- -nova*)
- os=-rtmk-nova
+ nova*)
+ os=rtmk-nova
;;
- -ns2 )
- os=-nextstep2
+ ns2)
+ os=nextstep2
;;
- -nsk*)
- os=-nsk
+ nsk*)
+ os=nsk
;;
# Preserve the version number of sinix5.
- -sinix5.*)
+ sinix5.*)
os=`echo $os | sed -e 's|sinix|sysv|'`
;;
- -sinix*)
- os=-sysv4
+ sinix*)
+ os=sysv4
;;
- -tpf*)
- os=-tpf
+ tpf*)
+ os=tpf
;;
- -triton*)
- os=-sysv3
+ triton*)
+ os=sysv3
;;
- -oss*)
- os=-sysv3
+ oss*)
+ os=sysv3
;;
- -svr4)
- os=-sysv4
+ svr4*)
+ os=sysv4
;;
- -svr3)
- os=-sysv3
+ svr3)
+ os=sysv3
;;
- -sysvr4)
- os=-sysv4
+ sysvr4)
+ os=sysv4
;;
- # This must come after -sysvr4.
- -sysv*)
+ # This must come after sysvr4.
+ sysv*)
;;
- -ose*)
- os=-ose
+ ose*)
+ os=ose
;;
- -es1800*)
- os=-ose
+ *mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
+ os=mint
;;
- -xenix)
- os=-xenix
+ zvmoe)
+ os=zvmoe
;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- os=-mint
+ dicos*)
+ os=dicos
;;
- -aros*)
- os=-aros
+ pikeos*)
+ # Until real need of OS specific support for
+ # particular features comes up, bare metal
+ # configurations are quite functional.
+ case $basic_machine in
+ arm*)
+ os=eabi
+ ;;
+ *)
+ os=elf
+ ;;
+ esac
;;
- -zvmoe)
- os=-zvmoe
+ nacl*)
;;
- -dicos*)
- os=-dicos
+ ios)
;;
- -nacl*)
+ none)
;;
- -none)
+ *-eabi)
;;
*)
- # Get rid of the `-' at the beginning of $os.
- os=`echo $os | sed 's/[^-]*-//'`
- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
exit 1
;;
esac
@@ -1548,176 +1543,179 @@ else
case $basic_machine in
score-*)
- os=-elf
+ os=elf
;;
spu-*)
- os=-elf
+ os=elf
;;
*-acorn)
- os=-riscix1.2
+ os=riscix1.2
;;
arm*-rebel)
- os=-linux
+ os=linux
;;
arm*-semi)
- os=-aout
+ os=aout
;;
c4x-* | tic4x-*)
- os=-coff
+ os=coff
;;
c8051-*)
- os=-elf
+ os=elf
+ ;;
+ clipper-intergraph)
+ os=clix
;;
hexagon-*)
- os=-elf
+ os=elf
;;
tic54x-*)
- os=-coff
+ os=coff
;;
tic55x-*)
- os=-coff
+ os=coff
;;
tic6x-*)
- os=-coff
+ os=coff
;;
# This must come before the *-dec entry.
pdp10-*)
- os=-tops20
+ os=tops20
;;
pdp11-*)
- os=-none
+ os=none
;;
*-dec | vax-*)
- os=-ultrix4.2
+ os=ultrix4.2
;;
m68*-apollo)
- os=-domain
+ os=domain
;;
i386-sun)
- os=-sunos4.0.2
+ os=sunos4.0.2
;;
m68000-sun)
- os=-sunos3
+ os=sunos3
;;
m68*-cisco)
- os=-aout
+ os=aout
;;
mep-*)
- os=-elf
+ os=elf
;;
mips*-cisco)
- os=-elf
+ os=elf
;;
mips*-*)
- os=-elf
+ os=elf
;;
or32-*)
- os=-coff
+ os=coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
- os=-sysv3
+ os=sysv3
;;
sparc-* | *-sun)
- os=-sunos4.1.1
+ os=sunos4.1.1
;;
- *-be)
- os=-beos
+ pru-*)
+ os=elf
;;
- *-haiku)
- os=-haiku
+ *-be)
+ os=beos
;;
*-ibm)
- os=-aix
+ os=aix
;;
*-knuth)
- os=-mmixware
+ os=mmixware
;;
*-wec)
- os=-proelf
+ os=proelf
;;
*-winbond)
- os=-proelf
+ os=proelf
;;
*-oki)
- os=-proelf
+ os=proelf
;;
*-hp)
- os=-hpux
+ os=hpux
;;
*-hitachi)
- os=-hiux
+ os=hiux
;;
i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
- os=-sysv
+ os=sysv
;;
*-cbm)
- os=-amigaos
+ os=amigaos
;;
*-dg)
- os=-dgux
+ os=dgux
;;
*-dolphin)
- os=-sysv3
+ os=sysv3
;;
m68k-ccur)
- os=-rtu
+ os=rtu
;;
m88k-omron*)
- os=-luna
+ os=luna
;;
- *-next )
- os=-nextstep
+ *-next)
+ os=nextstep
;;
*-sequent)
- os=-ptx
+ os=ptx
;;
*-crds)
- os=-unos
+ os=unos
;;
*-ns)
- os=-genix
+ os=genix
;;
i370-*)
- os=-mvs
- ;;
- *-next)
- os=-nextstep3
+ os=mvs
;;
*-gould)
- os=-sysv
+ os=sysv
;;
*-highlevel)
- os=-bsd
+ os=bsd
;;
*-encore)
- os=-bsd
+ os=bsd
;;
*-sgi)
- os=-irix
+ os=irix
;;
*-siemens)
- os=-sysv4
+ os=sysv4
;;
*-masscomp)
- os=-rtu
+ os=rtu
;;
f30[01]-fujitsu | f700-fujitsu)
- os=-uxpv
+ os=uxpv
;;
*-rom68k)
- os=-coff
+ os=coff
;;
*-*bug)
- os=-coff
+ os=coff
;;
*-apple)
- os=-macos
+ os=macos
;;
*-atari*)
- os=-mint
+ os=mint
+ ;;
+ *-wrs)
+ os=vxworks
;;
*)
- os=-none
+ os=none
;;
esac
fi
@@ -1728,79 +1726,82 @@ vendor=unknown
case $basic_machine in
*-unknown)
case $os in
- -riscix*)
+ riscix*)
vendor=acorn
;;
- -sunos*)
+ sunos*)
vendor=sun
;;
- -cnk*|-aix*)
+ cnk*|-aix*)
vendor=ibm
;;
- -beos*)
+ beos*)
vendor=be
;;
- -hpux*)
+ hpux*)
vendor=hp
;;
- -mpeix*)
+ mpeix*)
vendor=hp
;;
- -hiux*)
+ hiux*)
vendor=hitachi
;;
- -unos*)
+ unos*)
vendor=crds
;;
- -dgux*)
+ dgux*)
vendor=dg
;;
- -luna*)
+ luna*)
vendor=omron
;;
- -genix*)
+ genix*)
vendor=ns
;;
- -mvs* | -opened*)
+ clix*)
+ vendor=intergraph
+ ;;
+ mvs* | opened*)
vendor=ibm
;;
- -os400*)
+ os400*)
vendor=ibm
;;
- -ptx*)
+ ptx*)
vendor=sequent
;;
- -tpf*)
+ tpf*)
vendor=ibm
;;
- -vxsim* | -vxworks* | -windiss*)
+ vxsim* | vxworks* | windiss*)
vendor=wrs
;;
- -aux*)
+ aux*)
vendor=apple
;;
- -hms*)
+ hms*)
vendor=hitachi
;;
- -mpw* | -macos*)
+ mpw* | macos*)
vendor=apple
;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ *mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
vendor=atari
;;
- -vos*)
+ vos*)
vendor=stratus
;;
esac
- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"`
;;
esac
-echo $basic_machine$os
+echo "$basic_machine-$os"
exit
# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
diff --git a/configure b/configure
index 4c64875e..9a8c1588 100755
--- a/configure
+++ b/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
+
+
@@ -3363,8 +3623,47 @@ if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
+ can_add_to_cflags=yes
+ #
+ # The compile supports this; do we have some C code for
+ # which the warning should *not* appear?
+ # We test the fourth argument because the third argument
+ # could contain quotes, breaking the test.
+ #
+ if test "x" != "x"
+ then
+ CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -fvisibility=hidden " >&5
+$as_echo_n "checking whether -fvisibility=hidden ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ #
+ # Not a problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+
+ #
+ # A problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ can_add_to_cflags=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
CFLAGS="$save_CFLAGS"
- V_CCOPT="$V_CCOPT -fvisibility=hidden"
+ if test x"$can_add_to_cflags" = "xyes"
+ then
+ V_CCOPT="$V_CCOPT -fvisibility=hidden"
+ fi
else
@@ -3424,8 +3723,47 @@ if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
+ can_add_to_cflags=yes
+ #
+ # The compile supports this; do we have some C code for
+ # which the warning should *not* appear?
+ # We test the fourth argument because the third argument
+ # could contain quotes, breaking the test.
+ #
+ if test "x" != "x"
+ then
+ CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -fvisibility=hidden " >&5
+$as_echo_n "checking whether -fvisibility=hidden ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ #
+ # Not a problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+
+ #
+ # A problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ can_add_to_cflags=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
CFLAGS="$save_CFLAGS"
- V_CCOPT="$V_CCOPT -fvisibility=hidden"
+ if test x"$can_add_to_cflags" = "xyes"
+ then
+ V_CCOPT="$V_CCOPT -fvisibility=hidden"
+ fi
else
@@ -3547,8 +3885,47 @@ if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
+ can_add_to_cflags=yes
+ #
+ # The compile supports this; do we have some C code for
+ # which the warning should *not* appear?
+ # We test the fourth argument because the third argument
+ # could contain quotes, breaking the test.
+ #
+ if test "x" != "x"
+ then
+ CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -xldscope=hidden " >&5
+$as_echo_n "checking whether -xldscope=hidden ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ #
+ # Not a problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+
+ #
+ # A problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ can_add_to_cflags=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
CFLAGS="$save_CFLAGS"
- V_CCOPT="$V_CCOPT -xldscope=hidden"
+ if test x"$can_add_to_cflags" = "xyes"
+ then
+ V_CCOPT="$V_CCOPT -xldscope=hidden"
+ fi
else
@@ -3605,7 +3982,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 +4020,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 +4042,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 +4057,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 +4083,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 +4091,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 +4114,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 +4186,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 +4855,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 +4868,12 @@ fi
done
-for ac_header in linux/types.h
+for ac_header in netpacket/packet.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 :
+ 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 HAVE_LINUX_TYPES_H 1
-_ACEOF
-
-fi
-
-done
-
-for ac_header in linux/if_packet.h netpacket/packet.h netpacket/if_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 :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define HAVE_NETPACKET_PACKET_H 1
_ACEOF
fi
@@ -4818,50 +4929,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 +4998,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 +5059,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 +5127,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 +5184,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 +5232,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 +5249,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 +5553,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>?
+ #
+ # This test fails if we don't have <net/ethernet.h> or if we do
+ # but it doesn't declare ether_hostton().
#
- if test "$ac_cv_header_netinet_if_ether_h" = yes; then
+ 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
+ #
+ # 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_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 +5603,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,15 +5727,152 @@ _ACEOF
fi
+ fi
+fi
+
+#
+# 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 :
+
+ #
+ # 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 :
-$as_echo "#define HAVE_DECL_ETHER_HOSTTON 0" >>confdefs.h
+ #
+ # Yes.
+ #
+ ac_lbl_have_pthreads="found"
- else
+else
-$as_echo "#define HAVE_DECL_ETHER_HOSTTON 1" >>confdefs.h
+ #
+ # 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. */
- fi
+/* 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
+
+
+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; }
@@ -5412,7 +5900,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 +5921,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 +6257,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; }
-
-$as_echo "#define HAVE_DEV_DLPI 1" >>confdefs.h
+ 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>
- 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 +6307,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 +6317,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 +6538,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 +6601,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 +6652,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 +6697,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 +6741,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 +6888,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 +6903,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
+
+fi
+
+done
- 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; }
- 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 +6966,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
+ 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
- dag_streams="0"
+ 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 +7107,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 +7165,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 +7176,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 +7531,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.
#
@@ -7234,17 +7961,22 @@ fi
$as_echo "$tcpdump_cv_capable_yacc" >&6; }
if test $tcpdump_cv_capable_yacc = insufficient ; then
as_fn_error $? "$YACC is insufficient to compile libpcap.
- libpcap requires Bison, Berkeley YACC, or another YACC compatible with them." "$LINENO" 5
+ libpcap requires Bison, a newer version of Berkeley YACC with support
+ for reentrant parsers, or another YACC compatible with them." "$LINENO" 5
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 +8121,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 +8131,7 @@ hpux10.0*)
#
# Use System V conventions for man pages.
#
+ MAN_ADMIN_COMMANDS=1m
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
;;
@@ -7407,6 +8141,7 @@ hpux10.1*)
#
# Use System V conventions for man pages.
#
+ MAN_ADMIN_COMMANDS=1m
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
;;
@@ -7436,7 +8171,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 +8195,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 +8244,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
@@ -7793,8 +8552,47 @@ if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
+ can_add_to_cflags=yes
+ #
+ # The compile supports this; do we have some C code for
+ # which the warning should *not* appear?
+ # We test the fourth argument because the third argument
+ # could contain quotes, breaking the test.
+ #
+ if test "x" != "x"
+ then
+ CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wall " >&5
+$as_echo_n "checking whether -Wall ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ #
+ # Not a problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+
+ #
+ # A problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ can_add_to_cflags=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
CFLAGS="$save_CFLAGS"
- V_CCOPT="$V_CCOPT -Wall"
+ if test x"$can_add_to_cflags" = "xyes"
+ then
+ V_CCOPT="$V_CCOPT -Wall"
+ fi
else
@@ -7836,8 +8634,47 @@ if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
+ can_add_to_cflags=yes
+ #
+ # The compile supports this; do we have some C code for
+ # which the warning should *not* appear?
+ # We test the fourth argument because the third argument
+ # could contain quotes, breaking the test.
+ #
+ if test "x" != "x"
+ then
+ CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wsign-compare " >&5
+$as_echo_n "checking whether -Wsign-compare ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ #
+ # Not a problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+
+ #
+ # A problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ can_add_to_cflags=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
CFLAGS="$save_CFLAGS"
- V_CCOPT="$V_CCOPT -Wsign-compare"
+ if test x"$can_add_to_cflags" = "xyes"
+ then
+ V_CCOPT="$V_CCOPT -Wsign-compare"
+ fi
else
@@ -7879,8 +8716,47 @@ if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
+ can_add_to_cflags=yes
+ #
+ # The compile supports this; do we have some C code for
+ # which the warning should *not* appear?
+ # We test the fourth argument because the third argument
+ # could contain quotes, breaking the test.
+ #
+ if test "x" != "x"
+ then
+ CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wmissing-prototypes " >&5
+$as_echo_n "checking whether -Wmissing-prototypes ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ #
+ # Not a problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+
+ #
+ # A problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ can_add_to_cflags=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
CFLAGS="$save_CFLAGS"
- V_CCOPT="$V_CCOPT -Wmissing-prototypes"
+ if test x"$can_add_to_cflags" = "xyes"
+ then
+ V_CCOPT="$V_CCOPT -Wmissing-prototypes"
+ fi
else
@@ -7922,8 +8798,47 @@ if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
+ can_add_to_cflags=yes
+ #
+ # The compile supports this; do we have some C code for
+ # which the warning should *not* appear?
+ # We test the fourth argument because the third argument
+ # could contain quotes, breaking the test.
+ #
+ if test "x" != "x"
+ then
+ CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wstrict-prototypes " >&5
+$as_echo_n "checking whether -Wstrict-prototypes ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ #
+ # Not a problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+
+ #
+ # A problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ can_add_to_cflags=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
CFLAGS="$save_CFLAGS"
- V_CCOPT="$V_CCOPT -Wstrict-prototypes"
+ if test x"$can_add_to_cflags" = "xyes"
+ then
+ V_CCOPT="$V_CCOPT -Wstrict-prototypes"
+ fi
else
@@ -7965,8 +8880,47 @@ if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
+ can_add_to_cflags=yes
+ #
+ # The compile supports this; do we have some C code for
+ # which the warning should *not* appear?
+ # We test the fourth argument because the third argument
+ # could contain quotes, breaking the test.
+ #
+ if test "x" != "x"
+ then
+ CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wshadow " >&5
+$as_echo_n "checking whether -Wshadow ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ #
+ # Not a problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+
+ #
+ # A problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ can_add_to_cflags=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
CFLAGS="$save_CFLAGS"
- V_CCOPT="$V_CCOPT -Wshadow"
+ if test x"$can_add_to_cflags" = "xyes"
+ then
+ V_CCOPT="$V_CCOPT -Wshadow"
+ fi
else
@@ -8008,8 +8962,47 @@ if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
+ can_add_to_cflags=yes
+ #
+ # The compile supports this; do we have some C code for
+ # which the warning should *not* appear?
+ # We test the fourth argument because the third argument
+ # could contain quotes, breaking the test.
+ #
+ if test "x" != "x"
+ then
+ CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wdeclaration-after-statement " >&5
+$as_echo_n "checking whether -Wdeclaration-after-statement ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ #
+ # Not a problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+
+ #
+ # A problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ can_add_to_cflags=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
CFLAGS="$save_CFLAGS"
- V_CCOPT="$V_CCOPT -Wdeclaration-after-statement"
+ if test x"$can_add_to_cflags" = "xyes"
+ then
+ V_CCOPT="$V_CCOPT -Wdeclaration-after-statement"
+ fi
else
@@ -8051,8 +9044,655 @@ if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
+ can_add_to_cflags=yes
+ #
+ # The compile supports this; do we have some C code for
+ # which the warning should *not* appear?
+ # We test the fourth argument because the third argument
+ # could contain quotes, breaking the test.
+ #
+ if test "x" != "x"
+ then
+ CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wused-but-marked-unused " >&5
+$as_echo_n "checking whether -Wused-but-marked-unused ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ #
+ # Not a problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+
+ #
+ # A problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ can_add_to_cflags=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ CFLAGS="$save_CFLAGS"
+ if test x"$can_add_to_cflags" = "xyes"
+ then
+ V_CCOPT="$V_CCOPT -Wused-but-marked-unused"
+ fi
+
+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 -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; }
+ can_add_to_cflags=yes
+ #
+ # The compile supports this; do we have some C code for
+ # which the warning should *not* appear?
+ # We test the fourth argument because the third argument
+ # could contain quotes, breaking the test.
+ #
+ if test "x" != "x"
+ then
+ CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wdocumentation " >&5
+$as_echo_n "checking whether -Wdocumentation ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ #
+ # Not a problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+
+ #
+ # A problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ can_add_to_cflags=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ CFLAGS="$save_CFLAGS"
+ if test x"$can_add_to_cflags" = "xyes"
+ then
+ V_CCOPT="$V_CCOPT -Wdocumentation"
+ fi
+
+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; }
+ can_add_to_cflags=yes
+ #
+ # The compile supports this; do we have some C code for
+ # which the warning should *not* appear?
+ # We test the fourth argument because the third argument
+ # could contain quotes, breaking the test.
+ #
+ if test "x" != "x"
+ then
+ CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wcomma " >&5
+$as_echo_n "checking whether -Wcomma ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ #
+ # Not a problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+
+ #
+ # A problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ can_add_to_cflags=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ CFLAGS="$save_CFLAGS"
+ if test x"$can_add_to_cflags" = "xyes"
+ then
+ V_CCOPT="$V_CCOPT -Wcomma"
+ fi
+
+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; }
+ can_add_to_cflags=yes
+ #
+ # The compile supports this; do we have some C code for
+ # which the warning should *not* appear?
+ # We test the fourth argument because the third argument
+ # could contain quotes, breaking the test.
+ #
+ if test "x" != "x"
+ then
+ CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wmissing-noreturn " >&5
+$as_echo_n "checking whether -Wmissing-noreturn ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ #
+ # Not a problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+
+ #
+ # A problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ can_add_to_cflags=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ CFLAGS="$save_CFLAGS"
+ if test x"$can_add_to_cflags" = "xyes"
+ then
+ V_CCOPT="$V_CCOPT -Wmissing-noreturn"
+ fi
+
+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; }
+ can_add_to_cflags=yes
+ #
+ # The compile supports this; do we have some C code for
+ # which the warning should *not* appear?
+ # We test the fourth argument because the third argument
+ # could contain quotes, breaking the test.
+ #
+ if test "x" != "x"
+ then
+ CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wmissing-variable-declarations " >&5
+$as_echo_n "checking whether -Wmissing-variable-declarations ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ #
+ # Not a problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+
+ #
+ # A problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ can_add_to_cflags=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ CFLAGS="$save_CFLAGS"
+ if test x"$can_add_to_cflags" = "xyes"
+ then
+ V_CCOPT="$V_CCOPT -Wmissing-variable-declarations"
+ fi
+
+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; }
+ can_add_to_cflags=yes
+ #
+ # The compile supports this; do we have some C code for
+ # which the warning should *not* appear?
+ # We test the fourth argument because the third argument
+ # could contain quotes, breaking the test.
+ #
+ if test "x" != "x"
+ then
+ CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wunused-parameter " >&5
+$as_echo_n "checking whether -Wunused-parameter ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ #
+ # Not a problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+
+ #
+ # A problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ can_add_to_cflags=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
CFLAGS="$save_CFLAGS"
- V_CCOPT="$V_CCOPT -Wused-but-marked-unused"
+ if test x"$can_add_to_cflags" = "xyes"
+ then
+ V_CCOPT="$V_CCOPT -Wunused-parameter"
+ fi
+
+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; }
+ can_add_to_cflags=yes
+ #
+ # The compile supports this; do we have some C code for
+ # which the warning should *not* appear?
+ # We test the fourth argument because the third argument
+ # could contain quotes, breaking the test.
+ #
+ if test "x" != "x"
+ then
+ CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wformat-nonliteral " >&5
+$as_echo_n "checking whether -Wformat-nonliteral ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ #
+ # Not a problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+
+ #
+ # A problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ can_add_to_cflags=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ CFLAGS="$save_CFLAGS"
+ if test x"$can_add_to_cflags" = "xyes"
+ then
+ V_CCOPT="$V_CCOPT -Wformat-nonliteral"
+ fi
+
+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
+
+ #
+ # This can cause problems with ntohs(), ntohl(),
+ # htons(), and htonl() on some platforms, such
+ # as OpenBSD 6.3 with Clang 5.0.1. I guess the
+ # problem is that the macro that ultimately does
+ # the byte-swapping involves a conditional
+ # expression that tests whether the value being
+ # swapped is a compile-time constant or not,
+ # using __builtin_constant_p(), and, depending
+ # on whether it is, does a compile-time swap or
+ # a run-time swap; perhaps the compiler always
+ # considers one of the two results of the
+ # conditional expressin is never evaluated,
+ # because the conditional check is done at
+ # compile time, and thus always says "that
+ # expression is never executed".
+ #
+ # (Perhaps there should be a way of flagging
+ # an expression that you *want* evaluated at
+ # compile time, so that the compiler 1) warns
+ # if it *can't* be evaluated at compile time
+ # and 2) *doesn't* warn that the true or false
+ # branch will never be reached.)
+ #
+
+ { $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; }
+ can_add_to_cflags=yes
+ #
+ # The compile supports this; do we have some C code for
+ # which the warning should *not* appear?
+ # We test the fourth argument because the third argument
+ # could contain quotes, breaking the test.
+ #
+ if test "xgenerates warnings from ntohs()" != "x"
+ then
+ CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wunreachable-code generates warnings from ntohs()" >&5
+$as_echo_n "checking whether -Wunreachable-code generates warnings from ntohs()... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <arpa/inet.h>
+
+unsigned short
+testme(unsigned short a)
+{
+ return ntohs(a);
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ #
+ # Not a problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+
+ #
+ # A problem.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ can_add_to_cflags=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ CFLAGS="$save_CFLAGS"
+ if test x"$can_add_to_cflags" = "xyes"
+ then
+ V_CCOPT="$V_CCOPT -Wunreachable-code"
+ fi
else
@@ -8135,8 +9775,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 +9791,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 +9801,7 @@ $as_echo "no" >&6; }
# We can't run mkdep, so have "make depend" do
# nothing.
#
- MKDEP=:
+ MKDEP='${srcdir}/nomkdep'
fi
@@ -8184,108 +9827,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 +9985,12 @@ $as_echo "#define LBL_ALIGN 1" >>confdefs.h
fi
-rm -f net
-ln -s ${srcdir}/bpf/net net
+
+
+
+
+
+
@@ -8493,45 +10100,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 +10204,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 +10279,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 +10404,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 +10534,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 +10748,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 +11256,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 +11322,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 +11467,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 +12027,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/configure.ac b/configure.ac
index da2f940d..eff6eb89 100644
--- a/configure.ac
+++ b/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.
#
@@ -1180,17 +1529,22 @@ AC_CACHE_CHECK([for capable yacc/bison], tcpdump_cv_capable_yacc,
fi)
if test $tcpdump_cv_capable_yacc = insufficient ; then
AC_MSG_ERROR([$YACC is insufficient to compile libpcap.
- libpcap requires Bison, Berkeley YACC, or another YACC compatible with them.])
+ libpcap requires Bison, a newer version of Berkeley YACC with support
+ for reentrant parsers, or another YACC compatible with them.])
fi
#
-# 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 +1593,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 +1681,7 @@ hpux9*)
#
# Use System V conventions for man pages.
#
+ MAN_ADMIN_COMMANDS=1m
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
;;
@@ -1336,6 +1691,7 @@ hpux10.0*)
#
# Use System V conventions for man pages.
#
+ MAN_ADMIN_COMMANDS=1m
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
;;
@@ -1345,6 +1701,7 @@ hpux10.1*)
#
# Use System V conventions for man pages.
#
+ MAN_ADMIN_COMMANDS=1m
MAN_FILE_FORMATS=4
MAN_MISC_INFO=5
;;
@@ -1378,7 +1735,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 +1759,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 +1786,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 +1825,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 +1881,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 +1933,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 +1986,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 +2004,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 +2052,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 +2138,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 +2210,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 +2266,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 +2275,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/diag-control.h b/diag-control.h
new file mode 100644
index 00000000..cfc581b3
--- /dev/null
+++ b/diag-control.h
@@ -0,0 +1,219 @@
+/* -*- 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.
+ *
+ * In addition, the generated code may have functions with unreachable
+ * code, so suppress warnings about those.
+ */
+ #if defined(_MSC_VER)
+ /*
+ * This is Microsoft Visual Studio; we can use
+ * __pragma(warning(disable:XXXX)) and __pragma(warning(push/pop)).
+ */
+ #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.
+ *
+ * The generated code may have functions with unreachable code, so
+ * suppress warnings about those.
+ */
+ #if defined(_MSC_VER)
+ /*
+ * This is Microsoft Visual Studio; we can use
+ * __pragma(warning(disable:XXXX)) and __pragma(warning(push/pop)).
+ *
+ * Suppress 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/dlpisubs.c b/dlpisubs.c
index fb94a605..5f6e41af 100644
--- a/dlpisubs.c
+++ b/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/doc/DLT_ALLOCATE_HOWTO.md b/doc/DLT_ALLOCATE_HOWTO.md
new file mode 100644
index 00000000..ff77128e
--- /dev/null
+++ b/doc/DLT_ALLOCATE_HOWTO.md
@@ -0,0 +1,29 @@
+DLT and LINKTYPE allocation
+===========================
+
+DLT_ types live in pcap/dlt.h. They can be requested by the community on a
+First-Come First-Served basis [i.e. https://tools.ietf.org/html/rfc8126#section-4.4 ]
+(Although libpcap is not at this time an IETF specification, there have been
+some as yet-incomplete efforts to do this).
+
+The Tcpdump Group prefers to link to an open specification on the new DLT_
+type, but they are available for closed, proprietary projects as well.
+In that case, a stable email address suffices so that someone who finds
+an unknown DLT_ type can investigate.
+We prefer to give out unambiguous numbers, and we try to do it as quickly
+as possible, but DLT_USERx is available while you wait.
+
+Note that DLT_ types are, in theory, private to the capture mechanism and can
+in some cases be operating system specific, and so a second set of values,
+LINKTYPE_ is allocated for actually writing to pcap files. As much as
+possible going forward, the DLT_ and LINKTYPE_ value are identical, however,
+this was not always the case. See pcap-common.c.
+
+The LINKTYPE_ values are not exported, but are in pcap-common.c only.
+
+DEVELOPER NOTES
+---------------
+
+When allocating a new DLT_ value, a corresponding value needs to be
+added to pcap-common.c.
+It is not necessary to copy the comments from dlt.h to pcap-common.c.
diff --git a/README.Win32 b/doc/README.Win32
index 0a42dab9..0a42dab9 100644
--- a/README.Win32
+++ b/doc/README.Win32
diff --git a/README.aix b/doc/README.aix
index 92e513ff..92e513ff 100644
--- a/README.aix
+++ b/doc/README.aix
diff --git a/README.dag b/doc/README.dag
index accae7c3..accae7c3 100644
--- a/README.dag
+++ b/doc/README.dag
diff --git a/README.hpux b/doc/README.hpux
index 65ecff97..65ecff97 100644
--- a/README.hpux
+++ b/doc/README.hpux
diff --git a/README.linux b/doc/README.linux.md
index ffcb9288..ffcb9288 100644
--- a/README.linux
+++ b/doc/README.linux.md
diff --git a/README.macosx b/doc/README.macos
index 3dc92117..3cceb233 100644
--- a/README.macosx
+++ b/doc/README.macos
@@ -1,5 +1,5 @@
-As with other systems using BPF, Mac OS X allows users with read access
-to the BPF devices to capture packets with libpcap and allows users with
+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
@@ -12,16 +12,16 @@ 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 Mac OS X, the BPF devices live on devfs, but the OS X 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
+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 Mac OS X;
+ a "startup item" for older versions of macOS;
- a launchd daemon for Tiger and later versions of Mac OS X;
+ 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
diff --git a/README.septel b/doc/README.septel
index 483de6a7..fa2c0c9a 100644
--- a/README.septel
+++ b/doc/README.septel
@@ -40,7 +40,7 @@ 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 crutial and
+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
diff --git a/README.sita b/doc/README.sita
index 014d51d9..5a65822e 100644
--- a/README.sita
+++ b/doc/README.sita
@@ -1,5 +1,5 @@
The following instructions apply if you have a Linux platform and want
-libpcap to support the 'ACN' WAN/LAN router product from from SITA
+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
diff --git a/README.tru64 b/doc/README.tru64
index 2420d9e1..2420d9e1 100644
--- a/README.tru64
+++ b/doc/README.tru64
diff --git a/etherent.c b/etherent.c
index 5cfd1b4c..5f499613 100644
--- a/etherent.c
+++ b/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/extract.h b/extract.h
index face5b7e..aa3ff991 100644
--- a/extract.h
+++ b/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/fad-getad.c b/fad-getad.c
index b67b5cdc..5236fbb9 100644
--- a/fad-getad.c
+++ b/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/fad-gifc.c b/fad-gifc.c
index 1b24af29..6b161274 100644
--- a/fad-gifc.c
+++ b/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/fad-glifc.c b/fad-glifc.c
index 511481cf..f22f56d7 100644
--- a/fad-glifc.c
+++ b/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/fad-helpers.c b/fad-helpers.c
deleted file mode 100644
index 4860bc55..00000000
--- a/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/fmtutils.c b/fmtutils.c
new file mode 100644
index 00000000..f1a89073
--- /dev/null
+++ b/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/fmtutils.h b/fmtutils.h
new file mode 100644
index 00000000..62c78fdb
--- /dev/null
+++ b/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/ftmacros.h b/ftmacros.h
new file mode 100644
index 00000000..de8da98e
--- /dev/null
+++ b/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/gen_version_c.sh b/gen_version_c.sh
deleted file mode 100755
index d5a5e75b..00000000
--- a/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/gen_version_header.sh b/gen_version_header.sh
deleted file mode 100755
index 6b4b82da..00000000
--- a/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/gencode.c b/gencode.c
index a887f273..959a56e6 100644
--- a/gencode.c
+++ b/gencode.c
@@ -21,33 +21,21 @@
*/
#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>
@@ -94,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
@@ -121,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 */
@@ -137,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"
@@ -277,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
@@ -288,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.
@@ -358,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;
@@ -426,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);
@@ -434,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;
@@ -523,7 +514,8 @@ static struct block *gen_host6(compiler_state_t *, struct in6_addr *,
struct in6_addr *, int, int, int);
#endif
#ifndef INET6
-static struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int);
+static struct block *gen_gateway(compiler_state_t *, const u_char *,
+ struct addrinfo *, int, int);
#endif
static struct block *gen_ipfrag(compiler_state_t *);
static struct block *gen_portatom(compiler_state_t *, int, bpf_int32);
@@ -582,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;
@@ -653,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");
@@ -663,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;
@@ -670,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.
@@ -685,12 +673,41 @@ 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
cstate.ai = NULL;
+#endif
cstate.ic.root = NULL;
cstate.ic.cur_mark = 0;
cstate.bpf_pcap = p;
@@ -716,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);
/*
@@ -800,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;
@@ -822,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;
@@ -885,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;
@@ -897,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);
@@ -908,8 +922,7 @@ gen_or(b0, b1)
}
void
-gen_not(b)
- struct block *b;
+gen_not(struct block *b)
{
b->sense = !b->sense;
}
@@ -1061,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.
@@ -1072,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;
@@ -1089,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;
@@ -1403,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:
@@ -1434,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:
@@ -1499,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:
@@ -1512,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:
@@ -1525,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:
@@ -1538,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:
@@ -1555,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:
@@ -1591,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);
}
@@ -1717,7 +1735,7 @@ gen_load_a(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
default:
abort();
- return NULL;
+ /* NOTREACHED */
}
return s;
}
@@ -1781,6 +1799,7 @@ gen_loadx_iphdrlen(compiler_state_t *cstate)
return s;
}
+
static struct block *
gen_uncond(compiler_state_t *cstate, int rsense)
{
@@ -2798,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
@@ -2883,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) {
@@ -2971,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
@@ -3527,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);
}
@@ -3827,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();
}
@@ -3843,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) {
@@ -3868,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);
@@ -3913,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:
@@ -3969,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:
@@ -4025,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:
@@ -4506,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:
@@ -4634,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);
@@ -4642,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);
@@ -4902,13 +4990,12 @@ gen_host6(compiler_state_t *cstate, struct in6_addr *addr,
#ifndef INET6
static struct block *
-gen_gateway(eaddr, alist, proto, dir)
- 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'");
@@ -4956,12 +5043,48 @@ gen_gateway(eaddr, alist, proto, dir)
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);
@@ -5643,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;
}
@@ -5695,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
@@ -6199,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;
@@ -6304,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;
@@ -6353,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;
}
@@ -6369,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:
@@ -6467,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(eaddr, alist, proto, dir);
- free(eaddr);
return b;
#else
bpf_error(cstate, "'gateway' not supported in this configuration");
@@ -6544,7 +6660,6 @@ gen_mcode(compiler_state_t *cstate, const char *s1, const char *s2,
/* NOTREACHED */
}
/* NOTREACHED */
- return NULL;
}
struct block *
@@ -6663,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);
@@ -6685,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);
@@ -6710,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*/
@@ -6748,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
@@ -7003,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);
@@ -7176,7 +7338,6 @@ alloc_reg(compiler_state_t *cstate)
}
bpf_error(cstate, "too many registers needed to evaluate expression");
/* NOTREACHED */
- return 0;
}
/*
@@ -7331,7 +7492,6 @@ gen_broadcast(compiler_state_t *cstate, int proto)
}
bpf_error(cstate, "only link-layer/IP broadcast filters supported");
/* NOTREACHED */
- return NULL;
}
/*
@@ -7527,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;
}
/*
@@ -7628,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)
/*
@@ -7655,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) */
}
@@ -7772,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 */
@@ -7888,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 *
@@ -7920,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:
@@ -7947,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
@@ -8064,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 &&
@@ -8136,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;
}
@@ -8557,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);
@@ -8566,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);
@@ -8589,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);
@@ -8791,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)
@@ -8804,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)
@@ -8828,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)
@@ -8848,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/gencode.h b/gencode.h
index 2b089d21..88def5a8 100644
--- a/gencode.h
+++ b/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/grammar.c b/grammar.c
index 673449bd..2be760b8 100644
--- a/grammar.c
+++ b/grammar.c
@@ -1,8 +1,8 @@
-/* A Bison parser, made by GNU Bison 3.0.2. */
+/* A Bison parser, made by GNU Bison 3.0.4. */
/* Bison implementation for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -44,7 +44,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "3.0.2"
+#define YYBISON_VERSION "3.0.4"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -93,19 +93,15 @@
*/
#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;
@@ -117,6 +113,8 @@ struct rtentry;
#include <stdio.h>
+#include "diag-control.h"
+
#include "pcap-int.h"
#include "gencode.h"
@@ -136,9 +134,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 */
@@ -245,8 +264,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 */
@@ -292,28 +311,24 @@ 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 */
-#line 317 "grammar.c" /* yacc.c:339 */
+DIAG_OFF_BISON_BYACC
+
+#line 332 "grammar.c" /* yacc.c:339 */
# ifndef YY_NULLPTR
# if defined __cplusplus && 201103L <= __cplusplus
@@ -592,10 +607,10 @@ extern int pcap_debug;
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE YYSTYPE;
+
union YYSTYPE
{
-#line 271 "grammar.y" /* yacc.c:355 */
+#line 286 "grammar.y" /* yacc.c:355 */
int i;
bpf_u_int32 h;
@@ -611,8 +626,10 @@ union YYSTYPE
} blk;
struct block *rblk;
-#line 615 "grammar.c" /* yacc.c:355 */
+#line 630 "grammar.c" /* yacc.c:355 */
};
+
+typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif
@@ -625,7 +642,7 @@ int pcap_parse (void *yyscanner, compiler_state_t *cstate);
/* Copy the second part of user declarations. */
-#line 629 "grammar.c" /* yacc.c:358 */
+#line 646 "grammar.c" /* yacc.c:358 */
#ifdef short
# undef short
@@ -934,29 +951,29 @@ static const yytype_uint8 yytranslate[] =
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 345, 345, 349, 351, 353, 354, 355, 356, 357,
- 359, 361, 363, 364, 366, 368, 369, 371, 373, 386,
- 395, 404, 413, 422, 424, 426, 428, 429, 430, 432,
- 434, 436, 437, 439, 440, 441, 442, 443, 444, 446,
- 447, 448, 449, 451, 453, 454, 455, 456, 457, 458,
- 461, 462, 465, 466, 467, 468, 469, 470, 471, 472,
- 473, 474, 475, 476, 479, 480, 481, 482, 485, 487,
- 488, 489, 490, 491, 492, 493, 494, 495, 496, 497,
- 498, 499, 500, 501, 502, 503, 504, 505, 506, 507,
- 508, 509, 510, 511, 512, 513, 514, 515, 516, 517,
- 518, 519, 520, 521, 522, 523, 524, 525, 527, 528,
- 529, 530, 531, 532, 533, 534, 535, 536, 537, 538,
- 539, 540, 541, 542, 543, 544, 545, 548, 549, 550,
- 551, 552, 553, 556, 561, 564, 568, 571, 572, 578,
- 579, 599, 615, 616, 637, 640, 641, 654, 655, 658,
- 661, 662, 663, 665, 666, 667, 669, 670, 672, 673,
- 674, 675, 676, 677, 678, 679, 680, 681, 682, 683,
- 684, 685, 686, 688, 689, 690, 691, 692, 694, 695,
- 697, 698, 699, 700, 701, 702, 703, 705, 706, 707,
- 708, 711, 712, 714, 715, 716, 717, 719, 726, 727,
- 730, 731, 732, 733, 734, 735, 738, 739, 740, 741,
- 742, 743, 744, 745, 747, 748, 749, 750, 752, 765,
- 766
+ 0, 360, 360, 364, 366, 368, 369, 370, 371, 372,
+ 374, 376, 378, 379, 381, 383, 384, 386, 388, 401,
+ 410, 419, 428, 437, 439, 441, 443, 444, 445, 447,
+ 449, 451, 452, 454, 455, 456, 457, 458, 459, 461,
+ 462, 463, 464, 466, 468, 469, 470, 471, 472, 473,
+ 476, 477, 480, 481, 482, 483, 484, 485, 486, 487,
+ 488, 489, 490, 491, 494, 495, 496, 497, 500, 502,
+ 503, 504, 505, 506, 507, 508, 509, 510, 511, 512,
+ 513, 514, 515, 516, 517, 518, 519, 520, 521, 522,
+ 523, 524, 525, 526, 527, 528, 529, 530, 531, 532,
+ 533, 534, 535, 536, 537, 538, 539, 540, 542, 543,
+ 544, 545, 546, 547, 548, 549, 550, 551, 552, 553,
+ 554, 555, 556, 557, 558, 559, 560, 563, 564, 565,
+ 566, 567, 568, 571, 576, 579, 583, 586, 587, 593,
+ 594, 614, 630, 631, 652, 655, 656, 669, 670, 673,
+ 676, 677, 678, 680, 681, 682, 684, 685, 687, 688,
+ 689, 690, 691, 692, 693, 694, 695, 696, 697, 698,
+ 699, 700, 701, 703, 704, 705, 706, 707, 709, 710,
+ 712, 713, 714, 715, 716, 717, 718, 720, 721, 722,
+ 723, 726, 727, 729, 730, 731, 732, 734, 741, 742,
+ 745, 746, 747, 748, 749, 750, 753, 754, 755, 756,
+ 757, 758, 759, 760, 762, 763, 764, 765, 767, 780,
+ 781
};
#endif
@@ -2060,90 +2077,90 @@ yyreduce:
switch (yyn)
{
case 2:
-#line 346 "grammar.y" /* yacc.c:1646 */
+#line 361 "grammar.y" /* yacc.c:1646 */
{
finish_parse(cstate, (yyvsp[0].blk).b);
}
-#line 2068 "grammar.c" /* yacc.c:1646 */
+#line 2085 "grammar.c" /* yacc.c:1646 */
break;
case 4:
-#line 351 "grammar.y" /* yacc.c:1646 */
+#line 366 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).q = qerr; }
-#line 2074 "grammar.c" /* yacc.c:1646 */
+#line 2091 "grammar.c" /* yacc.c:1646 */
break;
case 6:
-#line 354 "grammar.y" /* yacc.c:1646 */
+#line 369 "grammar.y" /* yacc.c:1646 */
{ gen_and((yyvsp[-2].blk).b, (yyvsp[0].blk).b); (yyval.blk) = (yyvsp[0].blk); }
-#line 2080 "grammar.c" /* yacc.c:1646 */
+#line 2097 "grammar.c" /* yacc.c:1646 */
break;
case 7:
-#line 355 "grammar.y" /* yacc.c:1646 */
+#line 370 "grammar.y" /* yacc.c:1646 */
{ gen_and((yyvsp[-2].blk).b, (yyvsp[0].blk).b); (yyval.blk) = (yyvsp[0].blk); }
-#line 2086 "grammar.c" /* yacc.c:1646 */
+#line 2103 "grammar.c" /* yacc.c:1646 */
break;
case 8:
-#line 356 "grammar.y" /* yacc.c:1646 */
+#line 371 "grammar.y" /* yacc.c:1646 */
{ gen_or((yyvsp[-2].blk).b, (yyvsp[0].blk).b); (yyval.blk) = (yyvsp[0].blk); }
-#line 2092 "grammar.c" /* yacc.c:1646 */
+#line 2109 "grammar.c" /* yacc.c:1646 */
break;
case 9:
-#line 357 "grammar.y" /* yacc.c:1646 */
+#line 372 "grammar.y" /* yacc.c:1646 */
{ gen_or((yyvsp[-2].blk).b, (yyvsp[0].blk).b); (yyval.blk) = (yyvsp[0].blk); }
-#line 2098 "grammar.c" /* yacc.c:1646 */
+#line 2115 "grammar.c" /* yacc.c:1646 */
break;
case 10:
-#line 359 "grammar.y" /* yacc.c:1646 */
+#line 374 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk) = (yyvsp[-1].blk); }
-#line 2104 "grammar.c" /* yacc.c:1646 */
+#line 2121 "grammar.c" /* yacc.c:1646 */
break;
case 11:
-#line 361 "grammar.y" /* yacc.c:1646 */
+#line 376 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk) = (yyvsp[-1].blk); }
-#line 2110 "grammar.c" /* yacc.c:1646 */
+#line 2127 "grammar.c" /* yacc.c:1646 */
break;
case 13:
-#line 364 "grammar.y" /* yacc.c:1646 */
+#line 379 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = gen_ncode(cstate, NULL, (bpf_u_int32)(yyvsp[0].i),
(yyval.blk).q = (yyvsp[-1].blk).q); }
-#line 2117 "grammar.c" /* yacc.c:1646 */
+#line 2134 "grammar.c" /* yacc.c:1646 */
break;
case 14:
-#line 366 "grammar.y" /* yacc.c:1646 */
+#line 381 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk) = (yyvsp[-1].blk); }
-#line 2123 "grammar.c" /* yacc.c:1646 */
+#line 2140 "grammar.c" /* yacc.c:1646 */
break;
case 15:
-#line 368 "grammar.y" /* yacc.c:1646 */
+#line 383 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = gen_scode(cstate, (yyvsp[0].s), (yyval.blk).q = (yyvsp[-1].blk).q); }
-#line 2129 "grammar.c" /* yacc.c:1646 */
+#line 2146 "grammar.c" /* yacc.c:1646 */
break;
case 16:
-#line 369 "grammar.y" /* yacc.c:1646 */
+#line 384 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = gen_mcode(cstate, (yyvsp[-2].s), NULL, (yyvsp[0].i),
(yyval.blk).q = (yyvsp[-3].blk).q); }
-#line 2136 "grammar.c" /* yacc.c:1646 */
+#line 2153 "grammar.c" /* yacc.c:1646 */
break;
case 17:
-#line 371 "grammar.y" /* yacc.c:1646 */
+#line 386 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = gen_mcode(cstate, (yyvsp[-2].s), (yyvsp[0].s), 0,
(yyval.blk).q = (yyvsp[-3].blk).q); }
-#line 2143 "grammar.c" /* yacc.c:1646 */
+#line 2160 "grammar.c" /* yacc.c:1646 */
break;
case 18:
-#line 373 "grammar.y" /* yacc.c:1646 */
+#line 388 "grammar.y" /* yacc.c:1646 */
{
/* Decide how to parse HID based on proto */
(yyval.blk).q = (yyvsp[-1].blk).q;
@@ -2157,11 +2174,11 @@ yyreduce:
bpf_error(cstate, "'protochain' modifier applied to ip host");
(yyval.blk).b = gen_ncode(cstate, (yyvsp[0].s), 0, (yyval.blk).q);
}
-#line 2161 "grammar.c" /* yacc.c:1646 */
+#line 2178 "grammar.c" /* yacc.c:1646 */
break;
case 19:
-#line 386 "grammar.y" /* yacc.c:1646 */
+#line 401 "grammar.y" /* yacc.c:1646 */
{
#ifdef INET6
(yyval.blk).b = gen_mcode6(cstate, (yyvsp[-2].s), NULL, (yyvsp[0].i),
@@ -2171,11 +2188,11 @@ yyreduce:
"in this configuration");
#endif /*INET6*/
}
-#line 2175 "grammar.c" /* yacc.c:1646 */
+#line 2192 "grammar.c" /* yacc.c:1646 */
break;
case 20:
-#line 395 "grammar.y" /* yacc.c:1646 */
+#line 410 "grammar.y" /* yacc.c:1646 */
{
#ifdef INET6
(yyval.blk).b = gen_mcode6(cstate, (yyvsp[0].s), 0, 128,
@@ -2185,11 +2202,11 @@ yyreduce:
"in this configuration");
#endif /*INET6*/
}
-#line 2189 "grammar.c" /* yacc.c:1646 */
+#line 2206 "grammar.c" /* yacc.c:1646 */
break;
case 21:
-#line 404 "grammar.y" /* yacc.c:1646 */
+#line 419 "grammar.y" /* yacc.c:1646 */
{
(yyval.blk).b = gen_ecode(cstate, (yyvsp[0].e), (yyval.blk).q = (yyvsp[-1].blk).q);
/*
@@ -2199,11 +2216,11 @@ yyreduce:
*/
free((yyvsp[0].e));
}
-#line 2203 "grammar.c" /* yacc.c:1646 */
+#line 2220 "grammar.c" /* yacc.c:1646 */
break;
case 22:
-#line 413 "grammar.y" /* yacc.c:1646 */
+#line 428 "grammar.y" /* yacc.c:1646 */
{
(yyval.blk).b = gen_acode(cstate, (yyvsp[0].e), (yyval.blk).q = (yyvsp[-1].blk).q);
/*
@@ -2213,691 +2230,691 @@ yyreduce:
*/
free((yyvsp[0].e));
}
-#line 2217 "grammar.c" /* yacc.c:1646 */
+#line 2234 "grammar.c" /* yacc.c:1646 */
break;
case 23:
-#line 422 "grammar.y" /* yacc.c:1646 */
+#line 437 "grammar.y" /* yacc.c:1646 */
{ gen_not((yyvsp[0].blk).b); (yyval.blk) = (yyvsp[0].blk); }
-#line 2223 "grammar.c" /* yacc.c:1646 */
+#line 2240 "grammar.c" /* yacc.c:1646 */
break;
case 24:
-#line 424 "grammar.y" /* yacc.c:1646 */
+#line 439 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk) = (yyvsp[-1].blk); }
-#line 2229 "grammar.c" /* yacc.c:1646 */
+#line 2246 "grammar.c" /* yacc.c:1646 */
break;
case 25:
-#line 426 "grammar.y" /* yacc.c:1646 */
+#line 441 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk) = (yyvsp[-1].blk); }
-#line 2235 "grammar.c" /* yacc.c:1646 */
+#line 2252 "grammar.c" /* yacc.c:1646 */
break;
case 27:
-#line 429 "grammar.y" /* yacc.c:1646 */
+#line 444 "grammar.y" /* yacc.c:1646 */
{ gen_and((yyvsp[-2].blk).b, (yyvsp[0].blk).b); (yyval.blk) = (yyvsp[0].blk); }
-#line 2241 "grammar.c" /* yacc.c:1646 */
+#line 2258 "grammar.c" /* yacc.c:1646 */
break;
case 28:
-#line 430 "grammar.y" /* yacc.c:1646 */
+#line 445 "grammar.y" /* yacc.c:1646 */
{ gen_or((yyvsp[-2].blk).b, (yyvsp[0].blk).b); (yyval.blk) = (yyvsp[0].blk); }
-#line 2247 "grammar.c" /* yacc.c:1646 */
+#line 2264 "grammar.c" /* yacc.c:1646 */
break;
case 29:
-#line 432 "grammar.y" /* yacc.c:1646 */
+#line 447 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = gen_ncode(cstate, NULL, (bpf_u_int32)(yyvsp[0].i),
(yyval.blk).q = (yyvsp[-1].blk).q); }
-#line 2254 "grammar.c" /* yacc.c:1646 */
+#line 2271 "grammar.c" /* yacc.c:1646 */
break;
case 32:
-#line 437 "grammar.y" /* yacc.c:1646 */
+#line 452 "grammar.y" /* yacc.c:1646 */
{ gen_not((yyvsp[0].blk).b); (yyval.blk) = (yyvsp[0].blk); }
-#line 2260 "grammar.c" /* yacc.c:1646 */
+#line 2277 "grammar.c" /* yacc.c:1646 */
break;
case 33:
-#line 439 "grammar.y" /* yacc.c:1646 */
+#line 454 "grammar.y" /* yacc.c:1646 */
{ QSET((yyval.blk).q, (yyvsp[-2].i), (yyvsp[-1].i), (yyvsp[0].i)); }
-#line 2266 "grammar.c" /* yacc.c:1646 */
+#line 2283 "grammar.c" /* yacc.c:1646 */
break;
case 34:
-#line 440 "grammar.y" /* yacc.c:1646 */
+#line 455 "grammar.y" /* yacc.c:1646 */
{ QSET((yyval.blk).q, (yyvsp[-1].i), (yyvsp[0].i), Q_DEFAULT); }
-#line 2272 "grammar.c" /* yacc.c:1646 */
+#line 2289 "grammar.c" /* yacc.c:1646 */
break;
case 35:
-#line 441 "grammar.y" /* yacc.c:1646 */
+#line 456 "grammar.y" /* yacc.c:1646 */
{ QSET((yyval.blk).q, (yyvsp[-1].i), Q_DEFAULT, (yyvsp[0].i)); }
-#line 2278 "grammar.c" /* yacc.c:1646 */
+#line 2295 "grammar.c" /* yacc.c:1646 */
break;
case 36:
-#line 442 "grammar.y" /* yacc.c:1646 */
+#line 457 "grammar.y" /* yacc.c:1646 */
{ QSET((yyval.blk).q, (yyvsp[-1].i), Q_DEFAULT, Q_PROTO); }
-#line 2284 "grammar.c" /* yacc.c:1646 */
+#line 2301 "grammar.c" /* yacc.c:1646 */
break;
case 37:
-#line 443 "grammar.y" /* yacc.c:1646 */
+#line 458 "grammar.y" /* yacc.c:1646 */
{ QSET((yyval.blk).q, (yyvsp[-1].i), Q_DEFAULT, Q_PROTOCHAIN); }
-#line 2290 "grammar.c" /* yacc.c:1646 */
+#line 2307 "grammar.c" /* yacc.c:1646 */
break;
case 38:
-#line 444 "grammar.y" /* yacc.c:1646 */
+#line 459 "grammar.y" /* yacc.c:1646 */
{ QSET((yyval.blk).q, (yyvsp[-1].i), Q_DEFAULT, (yyvsp[0].i)); }
-#line 2296 "grammar.c" /* yacc.c:1646 */
+#line 2313 "grammar.c" /* yacc.c:1646 */
break;
case 39:
-#line 446 "grammar.y" /* yacc.c:1646 */
+#line 461 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk) = (yyvsp[0].blk); }
-#line 2302 "grammar.c" /* yacc.c:1646 */
+#line 2319 "grammar.c" /* yacc.c:1646 */
break;
case 40:
-#line 447 "grammar.y" /* yacc.c:1646 */
+#line 462 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = (yyvsp[-1].blk).b; (yyval.blk).q = (yyvsp[-2].blk).q; }
-#line 2308 "grammar.c" /* yacc.c:1646 */
+#line 2325 "grammar.c" /* yacc.c:1646 */
break;
case 41:
-#line 448 "grammar.y" /* yacc.c:1646 */
+#line 463 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = gen_proto_abbrev(cstate, (yyvsp[0].i)); (yyval.blk).q = qerr; }
-#line 2314 "grammar.c" /* yacc.c:1646 */
+#line 2331 "grammar.c" /* yacc.c:1646 */
break;
case 42:
-#line 449 "grammar.y" /* yacc.c:1646 */
+#line 464 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = gen_relation(cstate, (yyvsp[-1].i), (yyvsp[-2].a), (yyvsp[0].a), 0);
(yyval.blk).q = qerr; }
-#line 2321 "grammar.c" /* yacc.c:1646 */
+#line 2338 "grammar.c" /* yacc.c:1646 */
break;
case 43:
-#line 451 "grammar.y" /* yacc.c:1646 */
+#line 466 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = gen_relation(cstate, (yyvsp[-1].i), (yyvsp[-2].a), (yyvsp[0].a), 1);
(yyval.blk).q = qerr; }
-#line 2328 "grammar.c" /* yacc.c:1646 */
+#line 2345 "grammar.c" /* yacc.c:1646 */
break;
case 44:
-#line 453 "grammar.y" /* yacc.c:1646 */
+#line 468 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = (yyvsp[0].rblk); (yyval.blk).q = qerr; }
-#line 2334 "grammar.c" /* yacc.c:1646 */
+#line 2351 "grammar.c" /* yacc.c:1646 */
break;
case 45:
-#line 454 "grammar.y" /* yacc.c:1646 */
+#line 469 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = gen_atmtype_abbrev(cstate, (yyvsp[0].i)); (yyval.blk).q = qerr; }
-#line 2340 "grammar.c" /* yacc.c:1646 */
+#line 2357 "grammar.c" /* yacc.c:1646 */
break;
case 46:
-#line 455 "grammar.y" /* yacc.c:1646 */
+#line 470 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = gen_atmmulti_abbrev(cstate, (yyvsp[0].i)); (yyval.blk).q = qerr; }
-#line 2346 "grammar.c" /* yacc.c:1646 */
+#line 2363 "grammar.c" /* yacc.c:1646 */
break;
case 47:
-#line 456 "grammar.y" /* yacc.c:1646 */
+#line 471 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = (yyvsp[0].blk).b; (yyval.blk).q = qerr; }
-#line 2352 "grammar.c" /* yacc.c:1646 */
+#line 2369 "grammar.c" /* yacc.c:1646 */
break;
case 48:
-#line 457 "grammar.y" /* yacc.c:1646 */
+#line 472 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = gen_mtp2type_abbrev(cstate, (yyvsp[0].i)); (yyval.blk).q = qerr; }
-#line 2358 "grammar.c" /* yacc.c:1646 */
+#line 2375 "grammar.c" /* yacc.c:1646 */
break;
case 49:
-#line 458 "grammar.y" /* yacc.c:1646 */
+#line 473 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = (yyvsp[0].blk).b; (yyval.blk).q = qerr; }
-#line 2364 "grammar.c" /* yacc.c:1646 */
+#line 2381 "grammar.c" /* yacc.c:1646 */
break;
case 51:
-#line 462 "grammar.y" /* yacc.c:1646 */
+#line 477 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_DEFAULT; }
-#line 2370 "grammar.c" /* yacc.c:1646 */
+#line 2387 "grammar.c" /* yacc.c:1646 */
break;
case 52:
-#line 465 "grammar.y" /* yacc.c:1646 */
+#line 480 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_SRC; }
-#line 2376 "grammar.c" /* yacc.c:1646 */
+#line 2393 "grammar.c" /* yacc.c:1646 */
break;
case 53:
-#line 466 "grammar.y" /* yacc.c:1646 */
+#line 481 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_DST; }
-#line 2382 "grammar.c" /* yacc.c:1646 */
+#line 2399 "grammar.c" /* yacc.c:1646 */
break;
case 54:
-#line 467 "grammar.y" /* yacc.c:1646 */
+#line 482 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_OR; }
-#line 2388 "grammar.c" /* yacc.c:1646 */
+#line 2405 "grammar.c" /* yacc.c:1646 */
break;
case 55:
-#line 468 "grammar.y" /* yacc.c:1646 */
+#line 483 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_OR; }
-#line 2394 "grammar.c" /* yacc.c:1646 */
+#line 2411 "grammar.c" /* yacc.c:1646 */
break;
case 56:
-#line 469 "grammar.y" /* yacc.c:1646 */
+#line 484 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_AND; }
-#line 2400 "grammar.c" /* yacc.c:1646 */
+#line 2417 "grammar.c" /* yacc.c:1646 */
break;
case 57:
-#line 470 "grammar.y" /* yacc.c:1646 */
+#line 485 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_AND; }
-#line 2406 "grammar.c" /* yacc.c:1646 */
+#line 2423 "grammar.c" /* yacc.c:1646 */
break;
case 58:
-#line 471 "grammar.y" /* yacc.c:1646 */
+#line 486 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_ADDR1; }
-#line 2412 "grammar.c" /* yacc.c:1646 */
+#line 2429 "grammar.c" /* yacc.c:1646 */
break;
case 59:
-#line 472 "grammar.y" /* yacc.c:1646 */
+#line 487 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_ADDR2; }
-#line 2418 "grammar.c" /* yacc.c:1646 */
+#line 2435 "grammar.c" /* yacc.c:1646 */
break;
case 60:
-#line 473 "grammar.y" /* yacc.c:1646 */
+#line 488 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_ADDR3; }
-#line 2424 "grammar.c" /* yacc.c:1646 */
+#line 2441 "grammar.c" /* yacc.c:1646 */
break;
case 61:
-#line 474 "grammar.y" /* yacc.c:1646 */
+#line 489 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_ADDR4; }
-#line 2430 "grammar.c" /* yacc.c:1646 */
+#line 2447 "grammar.c" /* yacc.c:1646 */
break;
case 62:
-#line 475 "grammar.y" /* yacc.c:1646 */
+#line 490 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_RA; }
-#line 2436 "grammar.c" /* yacc.c:1646 */
+#line 2453 "grammar.c" /* yacc.c:1646 */
break;
case 63:
-#line 476 "grammar.y" /* yacc.c:1646 */
+#line 491 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_TA; }
-#line 2442 "grammar.c" /* yacc.c:1646 */
+#line 2459 "grammar.c" /* yacc.c:1646 */
break;
case 64:
-#line 479 "grammar.y" /* yacc.c:1646 */
+#line 494 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_HOST; }
-#line 2448 "grammar.c" /* yacc.c:1646 */
+#line 2465 "grammar.c" /* yacc.c:1646 */
break;
case 65:
-#line 480 "grammar.y" /* yacc.c:1646 */
+#line 495 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_NET; }
-#line 2454 "grammar.c" /* yacc.c:1646 */
+#line 2471 "grammar.c" /* yacc.c:1646 */
break;
case 66:
-#line 481 "grammar.y" /* yacc.c:1646 */
+#line 496 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_PORT; }
-#line 2460 "grammar.c" /* yacc.c:1646 */
+#line 2477 "grammar.c" /* yacc.c:1646 */
break;
case 67:
-#line 482 "grammar.y" /* yacc.c:1646 */
+#line 497 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_PORTRANGE; }
-#line 2466 "grammar.c" /* yacc.c:1646 */
+#line 2483 "grammar.c" /* yacc.c:1646 */
break;
case 68:
-#line 485 "grammar.y" /* yacc.c:1646 */
+#line 500 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_GATEWAY; }
-#line 2472 "grammar.c" /* yacc.c:1646 */
+#line 2489 "grammar.c" /* yacc.c:1646 */
break;
case 69:
-#line 487 "grammar.y" /* yacc.c:1646 */
+#line 502 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_LINK; }
-#line 2478 "grammar.c" /* yacc.c:1646 */
+#line 2495 "grammar.c" /* yacc.c:1646 */
break;
case 70:
-#line 488 "grammar.y" /* yacc.c:1646 */
+#line 503 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_IP; }
-#line 2484 "grammar.c" /* yacc.c:1646 */
+#line 2501 "grammar.c" /* yacc.c:1646 */
break;
case 71:
-#line 489 "grammar.y" /* yacc.c:1646 */
+#line 504 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_ARP; }
-#line 2490 "grammar.c" /* yacc.c:1646 */
+#line 2507 "grammar.c" /* yacc.c:1646 */
break;
case 72:
-#line 490 "grammar.y" /* yacc.c:1646 */
+#line 505 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_RARP; }
-#line 2496 "grammar.c" /* yacc.c:1646 */
+#line 2513 "grammar.c" /* yacc.c:1646 */
break;
case 73:
-#line 491 "grammar.y" /* yacc.c:1646 */
+#line 506 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_SCTP; }
-#line 2502 "grammar.c" /* yacc.c:1646 */
+#line 2519 "grammar.c" /* yacc.c:1646 */
break;
case 74:
-#line 492 "grammar.y" /* yacc.c:1646 */
+#line 507 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_TCP; }
-#line 2508 "grammar.c" /* yacc.c:1646 */
+#line 2525 "grammar.c" /* yacc.c:1646 */
break;
case 75:
-#line 493 "grammar.y" /* yacc.c:1646 */
+#line 508 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_UDP; }
-#line 2514 "grammar.c" /* yacc.c:1646 */
+#line 2531 "grammar.c" /* yacc.c:1646 */
break;
case 76:
-#line 494 "grammar.y" /* yacc.c:1646 */
+#line 509 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_ICMP; }
-#line 2520 "grammar.c" /* yacc.c:1646 */
+#line 2537 "grammar.c" /* yacc.c:1646 */
break;
case 77:
-#line 495 "grammar.y" /* yacc.c:1646 */
+#line 510 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_IGMP; }
-#line 2526 "grammar.c" /* yacc.c:1646 */
+#line 2543 "grammar.c" /* yacc.c:1646 */
break;
case 78:
-#line 496 "grammar.y" /* yacc.c:1646 */
+#line 511 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_IGRP; }
-#line 2532 "grammar.c" /* yacc.c:1646 */
+#line 2549 "grammar.c" /* yacc.c:1646 */
break;
case 79:
-#line 497 "grammar.y" /* yacc.c:1646 */
+#line 512 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_PIM; }
-#line 2538 "grammar.c" /* yacc.c:1646 */
+#line 2555 "grammar.c" /* yacc.c:1646 */
break;
case 80:
-#line 498 "grammar.y" /* yacc.c:1646 */
+#line 513 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_VRRP; }
-#line 2544 "grammar.c" /* yacc.c:1646 */
+#line 2561 "grammar.c" /* yacc.c:1646 */
break;
case 81:
-#line 499 "grammar.y" /* yacc.c:1646 */
+#line 514 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_CARP; }
-#line 2550 "grammar.c" /* yacc.c:1646 */
+#line 2567 "grammar.c" /* yacc.c:1646 */
break;
case 82:
-#line 500 "grammar.y" /* yacc.c:1646 */
+#line 515 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_ATALK; }
-#line 2556 "grammar.c" /* yacc.c:1646 */
+#line 2573 "grammar.c" /* yacc.c:1646 */
break;
case 83:
-#line 501 "grammar.y" /* yacc.c:1646 */
+#line 516 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_AARP; }
-#line 2562 "grammar.c" /* yacc.c:1646 */
+#line 2579 "grammar.c" /* yacc.c:1646 */
break;
case 84:
-#line 502 "grammar.y" /* yacc.c:1646 */
+#line 517 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_DECNET; }
-#line 2568 "grammar.c" /* yacc.c:1646 */
+#line 2585 "grammar.c" /* yacc.c:1646 */
break;
case 85:
-#line 503 "grammar.y" /* yacc.c:1646 */
+#line 518 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_LAT; }
-#line 2574 "grammar.c" /* yacc.c:1646 */
+#line 2591 "grammar.c" /* yacc.c:1646 */
break;
case 86:
-#line 504 "grammar.y" /* yacc.c:1646 */
+#line 519 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_SCA; }
-#line 2580 "grammar.c" /* yacc.c:1646 */
+#line 2597 "grammar.c" /* yacc.c:1646 */
break;
case 87:
-#line 505 "grammar.y" /* yacc.c:1646 */
+#line 520 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_MOPDL; }
-#line 2586 "grammar.c" /* yacc.c:1646 */
+#line 2603 "grammar.c" /* yacc.c:1646 */
break;
case 88:
-#line 506 "grammar.y" /* yacc.c:1646 */
+#line 521 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_MOPRC; }
-#line 2592 "grammar.c" /* yacc.c:1646 */
+#line 2609 "grammar.c" /* yacc.c:1646 */
break;
case 89:
-#line 507 "grammar.y" /* yacc.c:1646 */
+#line 522 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_IPV6; }
-#line 2598 "grammar.c" /* yacc.c:1646 */
+#line 2615 "grammar.c" /* yacc.c:1646 */
break;
case 90:
-#line 508 "grammar.y" /* yacc.c:1646 */
+#line 523 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_ICMPV6; }
-#line 2604 "grammar.c" /* yacc.c:1646 */
+#line 2621 "grammar.c" /* yacc.c:1646 */
break;
case 91:
-#line 509 "grammar.y" /* yacc.c:1646 */
+#line 524 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_AH; }
-#line 2610 "grammar.c" /* yacc.c:1646 */
+#line 2627 "grammar.c" /* yacc.c:1646 */
break;
case 92:
-#line 510 "grammar.y" /* yacc.c:1646 */
+#line 525 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_ESP; }
-#line 2616 "grammar.c" /* yacc.c:1646 */
+#line 2633 "grammar.c" /* yacc.c:1646 */
break;
case 93:
-#line 511 "grammar.y" /* yacc.c:1646 */
+#line 526 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_ISO; }
-#line 2622 "grammar.c" /* yacc.c:1646 */
+#line 2639 "grammar.c" /* yacc.c:1646 */
break;
case 94:
-#line 512 "grammar.y" /* yacc.c:1646 */
+#line 527 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_ESIS; }
-#line 2628 "grammar.c" /* yacc.c:1646 */
+#line 2645 "grammar.c" /* yacc.c:1646 */
break;
case 95:
-#line 513 "grammar.y" /* yacc.c:1646 */
+#line 528 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_ISIS; }
-#line 2634 "grammar.c" /* yacc.c:1646 */
+#line 2651 "grammar.c" /* yacc.c:1646 */
break;
case 96:
-#line 514 "grammar.y" /* yacc.c:1646 */
+#line 529 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_ISIS_L1; }
-#line 2640 "grammar.c" /* yacc.c:1646 */
+#line 2657 "grammar.c" /* yacc.c:1646 */
break;
case 97:
-#line 515 "grammar.y" /* yacc.c:1646 */
+#line 530 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_ISIS_L2; }
-#line 2646 "grammar.c" /* yacc.c:1646 */
+#line 2663 "grammar.c" /* yacc.c:1646 */
break;
case 98:
-#line 516 "grammar.y" /* yacc.c:1646 */
+#line 531 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_ISIS_IIH; }
-#line 2652 "grammar.c" /* yacc.c:1646 */
+#line 2669 "grammar.c" /* yacc.c:1646 */
break;
case 99:
-#line 517 "grammar.y" /* yacc.c:1646 */
+#line 532 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_ISIS_LSP; }
-#line 2658 "grammar.c" /* yacc.c:1646 */
+#line 2675 "grammar.c" /* yacc.c:1646 */
break;
case 100:
-#line 518 "grammar.y" /* yacc.c:1646 */
+#line 533 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_ISIS_SNP; }
-#line 2664 "grammar.c" /* yacc.c:1646 */
+#line 2681 "grammar.c" /* yacc.c:1646 */
break;
case 101:
-#line 519 "grammar.y" /* yacc.c:1646 */
+#line 534 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_ISIS_PSNP; }
-#line 2670 "grammar.c" /* yacc.c:1646 */
+#line 2687 "grammar.c" /* yacc.c:1646 */
break;
case 102:
-#line 520 "grammar.y" /* yacc.c:1646 */
+#line 535 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_ISIS_CSNP; }
-#line 2676 "grammar.c" /* yacc.c:1646 */
+#line 2693 "grammar.c" /* yacc.c:1646 */
break;
case 103:
-#line 521 "grammar.y" /* yacc.c:1646 */
+#line 536 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_CLNP; }
-#line 2682 "grammar.c" /* yacc.c:1646 */
+#line 2699 "grammar.c" /* yacc.c:1646 */
break;
case 104:
-#line 522 "grammar.y" /* yacc.c:1646 */
+#line 537 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_STP; }
-#line 2688 "grammar.c" /* yacc.c:1646 */
+#line 2705 "grammar.c" /* yacc.c:1646 */
break;
case 105:
-#line 523 "grammar.y" /* yacc.c:1646 */
+#line 538 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_IPX; }
-#line 2694 "grammar.c" /* yacc.c:1646 */
+#line 2711 "grammar.c" /* yacc.c:1646 */
break;
case 106:
-#line 524 "grammar.y" /* yacc.c:1646 */
+#line 539 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_NETBEUI; }
-#line 2700 "grammar.c" /* yacc.c:1646 */
+#line 2717 "grammar.c" /* yacc.c:1646 */
break;
case 107:
-#line 525 "grammar.y" /* yacc.c:1646 */
+#line 540 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = Q_RADIO; }
-#line 2706 "grammar.c" /* yacc.c:1646 */
+#line 2723 "grammar.c" /* yacc.c:1646 */
break;
case 108:
-#line 527 "grammar.y" /* yacc.c:1646 */
+#line 542 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_broadcast(cstate, (yyvsp[-1].i)); }
-#line 2712 "grammar.c" /* yacc.c:1646 */
+#line 2729 "grammar.c" /* yacc.c:1646 */
break;
case 109:
-#line 528 "grammar.y" /* yacc.c:1646 */
+#line 543 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_multicast(cstate, (yyvsp[-1].i)); }
-#line 2718 "grammar.c" /* yacc.c:1646 */
+#line 2735 "grammar.c" /* yacc.c:1646 */
break;
case 110:
-#line 529 "grammar.y" /* yacc.c:1646 */
+#line 544 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_less(cstate, (yyvsp[0].i)); }
-#line 2724 "grammar.c" /* yacc.c:1646 */
+#line 2741 "grammar.c" /* yacc.c:1646 */
break;
case 111:
-#line 530 "grammar.y" /* yacc.c:1646 */
+#line 545 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_greater(cstate, (yyvsp[0].i)); }
-#line 2730 "grammar.c" /* yacc.c:1646 */
+#line 2747 "grammar.c" /* yacc.c:1646 */
break;
case 112:
-#line 531 "grammar.y" /* yacc.c:1646 */
+#line 546 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_byteop(cstate, (yyvsp[-1].i), (yyvsp[-2].i), (yyvsp[0].i)); }
-#line 2736 "grammar.c" /* yacc.c:1646 */
+#line 2753 "grammar.c" /* yacc.c:1646 */
break;
case 113:
-#line 532 "grammar.y" /* yacc.c:1646 */
+#line 547 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_inbound(cstate, 0); }
-#line 2742 "grammar.c" /* yacc.c:1646 */
+#line 2759 "grammar.c" /* yacc.c:1646 */
break;
case 114:
-#line 533 "grammar.y" /* yacc.c:1646 */
+#line 548 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_inbound(cstate, 1); }
-#line 2748 "grammar.c" /* yacc.c:1646 */
+#line 2765 "grammar.c" /* yacc.c:1646 */
break;
case 115:
-#line 534 "grammar.y" /* yacc.c:1646 */
+#line 549 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_vlan(cstate, (yyvsp[0].i)); }
-#line 2754 "grammar.c" /* yacc.c:1646 */
+#line 2771 "grammar.c" /* yacc.c:1646 */
break;
case 116:
-#line 535 "grammar.y" /* yacc.c:1646 */
+#line 550 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_vlan(cstate, -1); }
-#line 2760 "grammar.c" /* yacc.c:1646 */
+#line 2777 "grammar.c" /* yacc.c:1646 */
break;
case 117:
-#line 536 "grammar.y" /* yacc.c:1646 */
+#line 551 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_mpls(cstate, (yyvsp[0].i)); }
-#line 2766 "grammar.c" /* yacc.c:1646 */
+#line 2783 "grammar.c" /* yacc.c:1646 */
break;
case 118:
-#line 537 "grammar.y" /* yacc.c:1646 */
+#line 552 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_mpls(cstate, -1); }
-#line 2772 "grammar.c" /* yacc.c:1646 */
+#line 2789 "grammar.c" /* yacc.c:1646 */
break;
case 119:
-#line 538 "grammar.y" /* yacc.c:1646 */
+#line 553 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_pppoed(cstate); }
-#line 2778 "grammar.c" /* yacc.c:1646 */
+#line 2795 "grammar.c" /* yacc.c:1646 */
break;
case 120:
-#line 539 "grammar.y" /* yacc.c:1646 */
+#line 554 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_pppoes(cstate, (yyvsp[0].i)); }
-#line 2784 "grammar.c" /* yacc.c:1646 */
+#line 2801 "grammar.c" /* yacc.c:1646 */
break;
case 121:
-#line 540 "grammar.y" /* yacc.c:1646 */
+#line 555 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_pppoes(cstate, -1); }
-#line 2790 "grammar.c" /* yacc.c:1646 */
+#line 2807 "grammar.c" /* yacc.c:1646 */
break;
case 122:
-#line 541 "grammar.y" /* yacc.c:1646 */
+#line 556 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_geneve(cstate, (yyvsp[0].i)); }
-#line 2796 "grammar.c" /* yacc.c:1646 */
+#line 2813 "grammar.c" /* yacc.c:1646 */
break;
case 123:
-#line 542 "grammar.y" /* yacc.c:1646 */
+#line 557 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_geneve(cstate, -1); }
-#line 2802 "grammar.c" /* yacc.c:1646 */
+#line 2819 "grammar.c" /* yacc.c:1646 */
break;
case 124:
-#line 543 "grammar.y" /* yacc.c:1646 */
+#line 558 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = (yyvsp[0].rblk); }
-#line 2808 "grammar.c" /* yacc.c:1646 */
+#line 2825 "grammar.c" /* yacc.c:1646 */
break;
case 125:
-#line 544 "grammar.y" /* yacc.c:1646 */
+#line 559 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = (yyvsp[0].rblk); }
-#line 2814 "grammar.c" /* yacc.c:1646 */
+#line 2831 "grammar.c" /* yacc.c:1646 */
break;
case 126:
-#line 545 "grammar.y" /* yacc.c:1646 */
+#line 560 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = (yyvsp[0].rblk); }
-#line 2820 "grammar.c" /* yacc.c:1646 */
+#line 2837 "grammar.c" /* yacc.c:1646 */
break;
case 127:
-#line 548 "grammar.y" /* yacc.c:1646 */
+#line 563 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_pf_ifname(cstate, (yyvsp[0].s)); }
-#line 2826 "grammar.c" /* yacc.c:1646 */
+#line 2843 "grammar.c" /* yacc.c:1646 */
break;
case 128:
-#line 549 "grammar.y" /* yacc.c:1646 */
+#line 564 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_pf_ruleset(cstate, (yyvsp[0].s)); }
-#line 2832 "grammar.c" /* yacc.c:1646 */
+#line 2849 "grammar.c" /* yacc.c:1646 */
break;
case 129:
-#line 550 "grammar.y" /* yacc.c:1646 */
+#line 565 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_pf_rnr(cstate, (yyvsp[0].i)); }
-#line 2838 "grammar.c" /* yacc.c:1646 */
+#line 2855 "grammar.c" /* yacc.c:1646 */
break;
case 130:
-#line 551 "grammar.y" /* yacc.c:1646 */
+#line 566 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_pf_srnr(cstate, (yyvsp[0].i)); }
-#line 2844 "grammar.c" /* yacc.c:1646 */
+#line 2861 "grammar.c" /* yacc.c:1646 */
break;
case 131:
-#line 552 "grammar.y" /* yacc.c:1646 */
+#line 567 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_pf_reason(cstate, (yyvsp[0].i)); }
-#line 2850 "grammar.c" /* yacc.c:1646 */
+#line 2867 "grammar.c" /* yacc.c:1646 */
break;
case 132:
-#line 553 "grammar.y" /* yacc.c:1646 */
+#line 568 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_pf_action(cstate, (yyvsp[0].i)); }
-#line 2856 "grammar.c" /* yacc.c:1646 */
+#line 2873 "grammar.c" /* yacc.c:1646 */
break;
case 133:
-#line 557 "grammar.y" /* yacc.c:1646 */
+#line 572 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_p80211_type(cstate, (yyvsp[-2].i) | (yyvsp[0].i),
IEEE80211_FC0_TYPE_MASK |
IEEE80211_FC0_SUBTYPE_MASK);
}
-#line 2865 "grammar.c" /* yacc.c:1646 */
+#line 2882 "grammar.c" /* yacc.c:1646 */
break;
case 134:
-#line 561 "grammar.y" /* yacc.c:1646 */
+#line 576 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_p80211_type(cstate, (yyvsp[0].i),
IEEE80211_FC0_TYPE_MASK);
}
-#line 2873 "grammar.c" /* yacc.c:1646 */
+#line 2890 "grammar.c" /* yacc.c:1646 */
break;
case 135:
-#line 564 "grammar.y" /* yacc.c:1646 */
+#line 579 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_p80211_type(cstate, (yyvsp[0].i),
IEEE80211_FC0_TYPE_MASK |
IEEE80211_FC0_SUBTYPE_MASK);
}
-#line 2882 "grammar.c" /* yacc.c:1646 */
+#line 2899 "grammar.c" /* yacc.c:1646 */
break;
case 136:
-#line 568 "grammar.y" /* yacc.c:1646 */
+#line 583 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_p80211_fcdir(cstate, (yyvsp[0].i)); }
-#line 2888 "grammar.c" /* yacc.c:1646 */
+#line 2905 "grammar.c" /* yacc.c:1646 */
break;
case 138:
-#line 572 "grammar.y" /* yacc.c:1646 */
+#line 587 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = str2tok((yyvsp[0].s), ieee80211_types);
if ((yyval.i) == -1)
bpf_error(cstate, "unknown 802.11 type name");
}
-#line 2897 "grammar.c" /* yacc.c:1646 */
+#line 2914 "grammar.c" /* yacc.c:1646 */
break;
case 140:
-#line 579 "grammar.y" /* yacc.c:1646 */
+#line 594 "grammar.y" /* yacc.c:1646 */
{ const struct tok *types = NULL;
int i;
for (i = 0;; i++) {
@@ -2916,11 +2933,11 @@ yyreduce:
if ((yyval.i) == -1)
bpf_error(cstate, "unknown 802.11 subtype name");
}
-#line 2920 "grammar.c" /* yacc.c:1646 */
+#line 2937 "grammar.c" /* yacc.c:1646 */
break;
case 141:
-#line 599 "grammar.y" /* yacc.c:1646 */
+#line 614 "grammar.y" /* yacc.c:1646 */
{ int i;
for (i = 0;; i++) {
if (ieee80211_type_subtypes[i].tok == NULL) {
@@ -2935,17 +2952,17 @@ yyreduce:
}
}
}
-#line 2939 "grammar.c" /* yacc.c:1646 */
+#line 2956 "grammar.c" /* yacc.c:1646 */
break;
case 142:
-#line 615 "grammar.y" /* yacc.c:1646 */
+#line 630 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_llc(cstate); }
-#line 2945 "grammar.c" /* yacc.c:1646 */
+#line 2962 "grammar.c" /* yacc.c:1646 */
break;
case 143:
-#line 616 "grammar.y" /* yacc.c:1646 */
+#line 631 "grammar.y" /* yacc.c:1646 */
{ if (pcap_strcasecmp((yyvsp[0].s), "i") == 0)
(yyval.rblk) = gen_llc_i(cstate);
else if (pcap_strcasecmp((yyvsp[0].s), "s") == 0)
@@ -2966,17 +2983,17 @@ yyreduce:
}
}
}
-#line 2970 "grammar.c" /* yacc.c:1646 */
+#line 2987 "grammar.c" /* yacc.c:1646 */
break;
case 144:
-#line 637 "grammar.y" /* yacc.c:1646 */
+#line 652 "grammar.y" /* yacc.c:1646 */
{ (yyval.rblk) = gen_llc_s_subtype(cstate, LLC_RNR); }
-#line 2976 "grammar.c" /* yacc.c:1646 */
+#line 2993 "grammar.c" /* yacc.c:1646 */
break;
case 146:
-#line 641 "grammar.y" /* yacc.c:1646 */
+#line 656 "grammar.y" /* yacc.c:1646 */
{ if (pcap_strcasecmp((yyvsp[0].s), "nods") == 0)
(yyval.i) = IEEE80211_FC1_DIR_NODS;
else if (pcap_strcasecmp((yyvsp[0].s), "tods") == 0)
@@ -2988,412 +3005,412 @@ yyreduce:
else
bpf_error(cstate, "unknown 802.11 direction");
}
-#line 2992 "grammar.c" /* yacc.c:1646 */
+#line 3009 "grammar.c" /* yacc.c:1646 */
break;
case 147:
-#line 654 "grammar.y" /* yacc.c:1646 */
+#line 669 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = (yyvsp[0].i); }
-#line 2998 "grammar.c" /* yacc.c:1646 */
+#line 3015 "grammar.c" /* yacc.c:1646 */
break;
case 148:
-#line 655 "grammar.y" /* yacc.c:1646 */
+#line 670 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = pfreason_to_num(cstate, (yyvsp[0].s)); }
-#line 3004 "grammar.c" /* yacc.c:1646 */
+#line 3021 "grammar.c" /* yacc.c:1646 */
break;
case 149:
-#line 658 "grammar.y" /* yacc.c:1646 */
+#line 673 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = pfaction_to_num(cstate, (yyvsp[0].s)); }
-#line 3010 "grammar.c" /* yacc.c:1646 */
+#line 3027 "grammar.c" /* yacc.c:1646 */
break;
case 150:
-#line 661 "grammar.y" /* yacc.c:1646 */
+#line 676 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = BPF_JGT; }
-#line 3016 "grammar.c" /* yacc.c:1646 */
+#line 3033 "grammar.c" /* yacc.c:1646 */
break;
case 151:
-#line 662 "grammar.y" /* yacc.c:1646 */
+#line 677 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = BPF_JGE; }
-#line 3022 "grammar.c" /* yacc.c:1646 */
+#line 3039 "grammar.c" /* yacc.c:1646 */
break;
case 152:
-#line 663 "grammar.y" /* yacc.c:1646 */
+#line 678 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = BPF_JEQ; }
-#line 3028 "grammar.c" /* yacc.c:1646 */
+#line 3045 "grammar.c" /* yacc.c:1646 */
break;
case 153:
-#line 665 "grammar.y" /* yacc.c:1646 */
+#line 680 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = BPF_JGT; }
-#line 3034 "grammar.c" /* yacc.c:1646 */
+#line 3051 "grammar.c" /* yacc.c:1646 */
break;
case 154:
-#line 666 "grammar.y" /* yacc.c:1646 */
+#line 681 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = BPF_JGE; }
-#line 3040 "grammar.c" /* yacc.c:1646 */
+#line 3057 "grammar.c" /* yacc.c:1646 */
break;
case 155:
-#line 667 "grammar.y" /* yacc.c:1646 */
+#line 682 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = BPF_JEQ; }
-#line 3046 "grammar.c" /* yacc.c:1646 */
+#line 3063 "grammar.c" /* yacc.c:1646 */
break;
case 156:
-#line 669 "grammar.y" /* yacc.c:1646 */
+#line 684 "grammar.y" /* yacc.c:1646 */
{ (yyval.a) = gen_loadi(cstate, (yyvsp[0].i)); }
-#line 3052 "grammar.c" /* yacc.c:1646 */
+#line 3069 "grammar.c" /* yacc.c:1646 */
break;
case 158:
-#line 672 "grammar.y" /* yacc.c:1646 */
+#line 687 "grammar.y" /* yacc.c:1646 */
{ (yyval.a) = gen_load(cstate, (yyvsp[-3].i), (yyvsp[-1].a), 1); }
-#line 3058 "grammar.c" /* yacc.c:1646 */
+#line 3075 "grammar.c" /* yacc.c:1646 */
break;
case 159:
-#line 673 "grammar.y" /* yacc.c:1646 */
+#line 688 "grammar.y" /* yacc.c:1646 */
{ (yyval.a) = gen_load(cstate, (yyvsp[-5].i), (yyvsp[-3].a), (yyvsp[-1].i)); }
-#line 3064 "grammar.c" /* yacc.c:1646 */
+#line 3081 "grammar.c" /* yacc.c:1646 */
break;
case 160:
-#line 674 "grammar.y" /* yacc.c:1646 */
+#line 689 "grammar.y" /* yacc.c:1646 */
{ (yyval.a) = gen_arth(cstate, BPF_ADD, (yyvsp[-2].a), (yyvsp[0].a)); }
-#line 3070 "grammar.c" /* yacc.c:1646 */
+#line 3087 "grammar.c" /* yacc.c:1646 */
break;
case 161:
-#line 675 "grammar.y" /* yacc.c:1646 */
+#line 690 "grammar.y" /* yacc.c:1646 */
{ (yyval.a) = gen_arth(cstate, BPF_SUB, (yyvsp[-2].a), (yyvsp[0].a)); }
-#line 3076 "grammar.c" /* yacc.c:1646 */
+#line 3093 "grammar.c" /* yacc.c:1646 */
break;
case 162:
-#line 676 "grammar.y" /* yacc.c:1646 */
+#line 691 "grammar.y" /* yacc.c:1646 */
{ (yyval.a) = gen_arth(cstate, BPF_MUL, (yyvsp[-2].a), (yyvsp[0].a)); }
-#line 3082 "grammar.c" /* yacc.c:1646 */
+#line 3099 "grammar.c" /* yacc.c:1646 */
break;
case 163:
-#line 677 "grammar.y" /* yacc.c:1646 */
+#line 692 "grammar.y" /* yacc.c:1646 */
{ (yyval.a) = gen_arth(cstate, BPF_DIV, (yyvsp[-2].a), (yyvsp[0].a)); }
-#line 3088 "grammar.c" /* yacc.c:1646 */
+#line 3105 "grammar.c" /* yacc.c:1646 */
break;
case 164:
-#line 678 "grammar.y" /* yacc.c:1646 */
+#line 693 "grammar.y" /* yacc.c:1646 */
{ (yyval.a) = gen_arth(cstate, BPF_MOD, (yyvsp[-2].a), (yyvsp[0].a)); }
-#line 3094 "grammar.c" /* yacc.c:1646 */
+#line 3111 "grammar.c" /* yacc.c:1646 */
break;
case 165:
-#line 679 "grammar.y" /* yacc.c:1646 */
+#line 694 "grammar.y" /* yacc.c:1646 */
{ (yyval.a) = gen_arth(cstate, BPF_AND, (yyvsp[-2].a), (yyvsp[0].a)); }
-#line 3100 "grammar.c" /* yacc.c:1646 */
+#line 3117 "grammar.c" /* yacc.c:1646 */
break;
case 166:
-#line 680 "grammar.y" /* yacc.c:1646 */
+#line 695 "grammar.y" /* yacc.c:1646 */
{ (yyval.a) = gen_arth(cstate, BPF_OR, (yyvsp[-2].a), (yyvsp[0].a)); }
-#line 3106 "grammar.c" /* yacc.c:1646 */
+#line 3123 "grammar.c" /* yacc.c:1646 */
break;
case 167:
-#line 681 "grammar.y" /* yacc.c:1646 */
+#line 696 "grammar.y" /* yacc.c:1646 */
{ (yyval.a) = gen_arth(cstate, BPF_XOR, (yyvsp[-2].a), (yyvsp[0].a)); }
-#line 3112 "grammar.c" /* yacc.c:1646 */
+#line 3129 "grammar.c" /* yacc.c:1646 */
break;
case 168:
-#line 682 "grammar.y" /* yacc.c:1646 */
+#line 697 "grammar.y" /* yacc.c:1646 */
{ (yyval.a) = gen_arth(cstate, BPF_LSH, (yyvsp[-2].a), (yyvsp[0].a)); }
-#line 3118 "grammar.c" /* yacc.c:1646 */
+#line 3135 "grammar.c" /* yacc.c:1646 */
break;
case 169:
-#line 683 "grammar.y" /* yacc.c:1646 */
+#line 698 "grammar.y" /* yacc.c:1646 */
{ (yyval.a) = gen_arth(cstate, BPF_RSH, (yyvsp[-2].a), (yyvsp[0].a)); }
-#line 3124 "grammar.c" /* yacc.c:1646 */
+#line 3141 "grammar.c" /* yacc.c:1646 */
break;
case 170:
-#line 684 "grammar.y" /* yacc.c:1646 */
+#line 699 "grammar.y" /* yacc.c:1646 */
{ (yyval.a) = gen_neg(cstate, (yyvsp[0].a)); }
-#line 3130 "grammar.c" /* yacc.c:1646 */
+#line 3147 "grammar.c" /* yacc.c:1646 */
break;
case 171:
-#line 685 "grammar.y" /* yacc.c:1646 */
+#line 700 "grammar.y" /* yacc.c:1646 */
{ (yyval.a) = (yyvsp[-1].a); }
-#line 3136 "grammar.c" /* yacc.c:1646 */
+#line 3153 "grammar.c" /* yacc.c:1646 */
break;
case 172:
-#line 686 "grammar.y" /* yacc.c:1646 */
+#line 701 "grammar.y" /* yacc.c:1646 */
{ (yyval.a) = gen_loadlen(cstate); }
-#line 3142 "grammar.c" /* yacc.c:1646 */
+#line 3159 "grammar.c" /* yacc.c:1646 */
break;
case 173:
-#line 688 "grammar.y" /* yacc.c:1646 */
+#line 703 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = '&'; }
-#line 3148 "grammar.c" /* yacc.c:1646 */
+#line 3165 "grammar.c" /* yacc.c:1646 */
break;
case 174:
-#line 689 "grammar.y" /* yacc.c:1646 */
+#line 704 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = '|'; }
-#line 3154 "grammar.c" /* yacc.c:1646 */
+#line 3171 "grammar.c" /* yacc.c:1646 */
break;
case 175:
-#line 690 "grammar.y" /* yacc.c:1646 */
+#line 705 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = '<'; }
-#line 3160 "grammar.c" /* yacc.c:1646 */
+#line 3177 "grammar.c" /* yacc.c:1646 */
break;
case 176:
-#line 691 "grammar.y" /* yacc.c:1646 */
+#line 706 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = '>'; }
-#line 3166 "grammar.c" /* yacc.c:1646 */
+#line 3183 "grammar.c" /* yacc.c:1646 */
break;
case 177:
-#line 692 "grammar.y" /* yacc.c:1646 */
+#line 707 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = '='; }
-#line 3172 "grammar.c" /* yacc.c:1646 */
+#line 3189 "grammar.c" /* yacc.c:1646 */
break;
case 179:
-#line 695 "grammar.y" /* yacc.c:1646 */
+#line 710 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = (yyvsp[-1].i); }
-#line 3178 "grammar.c" /* yacc.c:1646 */
+#line 3195 "grammar.c" /* yacc.c:1646 */
break;
case 180:
-#line 697 "grammar.y" /* yacc.c:1646 */
+#line 712 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = A_LANE; }
-#line 3184 "grammar.c" /* yacc.c:1646 */
+#line 3201 "grammar.c" /* yacc.c:1646 */
break;
case 181:
-#line 698 "grammar.y" /* yacc.c:1646 */
+#line 713 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = A_METAC; }
-#line 3190 "grammar.c" /* yacc.c:1646 */
+#line 3207 "grammar.c" /* yacc.c:1646 */
break;
case 182:
-#line 699 "grammar.y" /* yacc.c:1646 */
+#line 714 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = A_BCC; }
-#line 3196 "grammar.c" /* yacc.c:1646 */
+#line 3213 "grammar.c" /* yacc.c:1646 */
break;
case 183:
-#line 700 "grammar.y" /* yacc.c:1646 */
+#line 715 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = A_OAMF4EC; }
-#line 3202 "grammar.c" /* yacc.c:1646 */
+#line 3219 "grammar.c" /* yacc.c:1646 */
break;
case 184:
-#line 701 "grammar.y" /* yacc.c:1646 */
+#line 716 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = A_OAMF4SC; }
-#line 3208 "grammar.c" /* yacc.c:1646 */
+#line 3225 "grammar.c" /* yacc.c:1646 */
break;
case 185:
-#line 702 "grammar.y" /* yacc.c:1646 */
+#line 717 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = A_SC; }
-#line 3214 "grammar.c" /* yacc.c:1646 */
+#line 3231 "grammar.c" /* yacc.c:1646 */
break;
case 186:
-#line 703 "grammar.y" /* yacc.c:1646 */
+#line 718 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = A_ILMIC; }
-#line 3220 "grammar.c" /* yacc.c:1646 */
+#line 3237 "grammar.c" /* yacc.c:1646 */
break;
case 187:
-#line 705 "grammar.y" /* yacc.c:1646 */
+#line 720 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = A_OAM; }
-#line 3226 "grammar.c" /* yacc.c:1646 */
+#line 3243 "grammar.c" /* yacc.c:1646 */
break;
case 188:
-#line 706 "grammar.y" /* yacc.c:1646 */
+#line 721 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = A_OAMF4; }
-#line 3232 "grammar.c" /* yacc.c:1646 */
+#line 3249 "grammar.c" /* yacc.c:1646 */
break;
case 189:
-#line 707 "grammar.y" /* yacc.c:1646 */
+#line 722 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = A_CONNECTMSG; }
-#line 3238 "grammar.c" /* yacc.c:1646 */
+#line 3255 "grammar.c" /* yacc.c:1646 */
break;
case 190:
-#line 708 "grammar.y" /* yacc.c:1646 */
+#line 723 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = A_METACONNECT; }
-#line 3244 "grammar.c" /* yacc.c:1646 */
+#line 3261 "grammar.c" /* yacc.c:1646 */
break;
case 191:
-#line 711 "grammar.y" /* yacc.c:1646 */
+#line 726 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).atmfieldtype = A_VPI; }
-#line 3250 "grammar.c" /* yacc.c:1646 */
+#line 3267 "grammar.c" /* yacc.c:1646 */
break;
case 192:
-#line 712 "grammar.y" /* yacc.c:1646 */
+#line 727 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).atmfieldtype = A_VCI; }
-#line 3256 "grammar.c" /* yacc.c:1646 */
+#line 3273 "grammar.c" /* yacc.c:1646 */
break;
case 194:
-#line 715 "grammar.y" /* yacc.c:1646 */
+#line 730 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = gen_atmfield_code(cstate, (yyvsp[-2].blk).atmfieldtype, (bpf_int32)(yyvsp[0].i), (bpf_u_int32)(yyvsp[-1].i), 0); }
-#line 3262 "grammar.c" /* yacc.c:1646 */
+#line 3279 "grammar.c" /* yacc.c:1646 */
break;
case 195:
-#line 716 "grammar.y" /* yacc.c:1646 */
+#line 731 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = gen_atmfield_code(cstate, (yyvsp[-2].blk).atmfieldtype, (bpf_int32)(yyvsp[0].i), (bpf_u_int32)(yyvsp[-1].i), 1); }
-#line 3268 "grammar.c" /* yacc.c:1646 */
+#line 3285 "grammar.c" /* yacc.c:1646 */
break;
case 196:
-#line 717 "grammar.y" /* yacc.c:1646 */
+#line 732 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = (yyvsp[-1].blk).b; (yyval.blk).q = qerr; }
-#line 3274 "grammar.c" /* yacc.c:1646 */
+#line 3291 "grammar.c" /* yacc.c:1646 */
break;
case 197:
-#line 719 "grammar.y" /* yacc.c:1646 */
+#line 734 "grammar.y" /* yacc.c:1646 */
{
(yyval.blk).atmfieldtype = (yyvsp[-1].blk).atmfieldtype;
if ((yyval.blk).atmfieldtype == A_VPI ||
(yyval.blk).atmfieldtype == A_VCI)
(yyval.blk).b = gen_atmfield_code(cstate, (yyval.blk).atmfieldtype, (bpf_int32) (yyvsp[0].i), BPF_JEQ, 0);
}
-#line 3285 "grammar.c" /* yacc.c:1646 */
+#line 3302 "grammar.c" /* yacc.c:1646 */
break;
case 199:
-#line 727 "grammar.y" /* yacc.c:1646 */
+#line 742 "grammar.y" /* yacc.c:1646 */
{ gen_or((yyvsp[-2].blk).b, (yyvsp[0].blk).b); (yyval.blk) = (yyvsp[0].blk); }
-#line 3291 "grammar.c" /* yacc.c:1646 */
+#line 3308 "grammar.c" /* yacc.c:1646 */
break;
case 200:
-#line 730 "grammar.y" /* yacc.c:1646 */
+#line 745 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = M_FISU; }
-#line 3297 "grammar.c" /* yacc.c:1646 */
+#line 3314 "grammar.c" /* yacc.c:1646 */
break;
case 201:
-#line 731 "grammar.y" /* yacc.c:1646 */
+#line 746 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = M_LSSU; }
-#line 3303 "grammar.c" /* yacc.c:1646 */
+#line 3320 "grammar.c" /* yacc.c:1646 */
break;
case 202:
-#line 732 "grammar.y" /* yacc.c:1646 */
+#line 747 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = M_MSU; }
-#line 3309 "grammar.c" /* yacc.c:1646 */
+#line 3326 "grammar.c" /* yacc.c:1646 */
break;
case 203:
-#line 733 "grammar.y" /* yacc.c:1646 */
+#line 748 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = MH_FISU; }
-#line 3315 "grammar.c" /* yacc.c:1646 */
+#line 3332 "grammar.c" /* yacc.c:1646 */
break;
case 204:
-#line 734 "grammar.y" /* yacc.c:1646 */
+#line 749 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = MH_LSSU; }
-#line 3321 "grammar.c" /* yacc.c:1646 */
+#line 3338 "grammar.c" /* yacc.c:1646 */
break;
case 205:
-#line 735 "grammar.y" /* yacc.c:1646 */
+#line 750 "grammar.y" /* yacc.c:1646 */
{ (yyval.i) = MH_MSU; }
-#line 3327 "grammar.c" /* yacc.c:1646 */
+#line 3344 "grammar.c" /* yacc.c:1646 */
break;
case 206:
-#line 738 "grammar.y" /* yacc.c:1646 */
+#line 753 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).mtp3fieldtype = M_SIO; }
-#line 3333 "grammar.c" /* yacc.c:1646 */
+#line 3350 "grammar.c" /* yacc.c:1646 */
break;
case 207:
-#line 739 "grammar.y" /* yacc.c:1646 */
+#line 754 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).mtp3fieldtype = M_OPC; }
-#line 3339 "grammar.c" /* yacc.c:1646 */
+#line 3356 "grammar.c" /* yacc.c:1646 */
break;
case 208:
-#line 740 "grammar.y" /* yacc.c:1646 */
+#line 755 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).mtp3fieldtype = M_DPC; }
-#line 3345 "grammar.c" /* yacc.c:1646 */
+#line 3362 "grammar.c" /* yacc.c:1646 */
break;
case 209:
-#line 741 "grammar.y" /* yacc.c:1646 */
+#line 756 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).mtp3fieldtype = M_SLS; }
-#line 3351 "grammar.c" /* yacc.c:1646 */
+#line 3368 "grammar.c" /* yacc.c:1646 */
break;
case 210:
-#line 742 "grammar.y" /* yacc.c:1646 */
+#line 757 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).mtp3fieldtype = MH_SIO; }
-#line 3357 "grammar.c" /* yacc.c:1646 */
+#line 3374 "grammar.c" /* yacc.c:1646 */
break;
case 211:
-#line 743 "grammar.y" /* yacc.c:1646 */
+#line 758 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).mtp3fieldtype = MH_OPC; }
-#line 3363 "grammar.c" /* yacc.c:1646 */
+#line 3380 "grammar.c" /* yacc.c:1646 */
break;
case 212:
-#line 744 "grammar.y" /* yacc.c:1646 */
+#line 759 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).mtp3fieldtype = MH_DPC; }
-#line 3369 "grammar.c" /* yacc.c:1646 */
+#line 3386 "grammar.c" /* yacc.c:1646 */
break;
case 213:
-#line 745 "grammar.y" /* yacc.c:1646 */
+#line 760 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).mtp3fieldtype = MH_SLS; }
-#line 3375 "grammar.c" /* yacc.c:1646 */
+#line 3392 "grammar.c" /* yacc.c:1646 */
break;
case 215:
-#line 748 "grammar.y" /* yacc.c:1646 */
+#line 763 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = gen_mtp3field_code(cstate, (yyvsp[-2].blk).mtp3fieldtype, (u_int)(yyvsp[0].i), (u_int)(yyvsp[-1].i), 0); }
-#line 3381 "grammar.c" /* yacc.c:1646 */
+#line 3398 "grammar.c" /* yacc.c:1646 */
break;
case 216:
-#line 749 "grammar.y" /* yacc.c:1646 */
+#line 764 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = gen_mtp3field_code(cstate, (yyvsp[-2].blk).mtp3fieldtype, (u_int)(yyvsp[0].i), (u_int)(yyvsp[-1].i), 1); }
-#line 3387 "grammar.c" /* yacc.c:1646 */
+#line 3404 "grammar.c" /* yacc.c:1646 */
break;
case 217:
-#line 750 "grammar.y" /* yacc.c:1646 */
+#line 765 "grammar.y" /* yacc.c:1646 */
{ (yyval.blk).b = (yyvsp[-1].blk).b; (yyval.blk).q = qerr; }
-#line 3393 "grammar.c" /* yacc.c:1646 */
+#line 3410 "grammar.c" /* yacc.c:1646 */
break;
case 218:
-#line 752 "grammar.y" /* yacc.c:1646 */
+#line 767 "grammar.y" /* yacc.c:1646 */
{
(yyval.blk).mtp3fieldtype = (yyvsp[-1].blk).mtp3fieldtype;
if ((yyval.blk).mtp3fieldtype == M_SIO ||
@@ -3406,17 +3423,17 @@ yyreduce:
(yyval.blk).mtp3fieldtype == MH_SLS)
(yyval.blk).b = gen_mtp3field_code(cstate, (yyval.blk).mtp3fieldtype, (u_int) (yyvsp[0].i), BPF_JEQ, 0);
}
-#line 3410 "grammar.c" /* yacc.c:1646 */
+#line 3427 "grammar.c" /* yacc.c:1646 */
break;
case 220:
-#line 766 "grammar.y" /* yacc.c:1646 */
+#line 781 "grammar.y" /* yacc.c:1646 */
{ gen_or((yyvsp[-2].blk).b, (yyvsp[0].blk).b); (yyval.blk) = (yyvsp[0].blk); }
-#line 3416 "grammar.c" /* yacc.c:1646 */
+#line 3433 "grammar.c" /* yacc.c:1646 */
break;
-#line 3420 "grammar.c" /* yacc.c:1646 */
+#line 3437 "grammar.c" /* yacc.c:1646 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -3644,5 +3661,5 @@ yyreturn:
#endif
return yyresult;
}
-#line 768 "grammar.y" /* yacc.c:1906 */
+#line 783 "grammar.y" /* yacc.c:1906 */
diff --git a/grammar.h b/grammar.h
index 2a495a0d..286cc798 100644
--- a/grammar.h
+++ b/grammar.h
@@ -1,8 +1,8 @@
-/* A Bison parser, made by GNU Bison 3.0.2. */
+/* A Bison parser, made by GNU Bison 3.0.4. */
/* Bison interface for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -289,10 +289,10 @@ extern int pcap_debug;
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE YYSTYPE;
+
union YYSTYPE
{
-#line 271 "grammar.y" /* yacc.c:1909 */
+#line 286 "grammar.y" /* yacc.c:1909 */
int i;
bpf_u_int32 h;
@@ -310,6 +310,8 @@ union YYSTYPE
#line 312 "grammar.h" /* yacc.c:1909 */
};
+
+typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif
diff --git a/grammar.y b/grammar.y
index 8e1d40a7..be80e2bf 100644
--- a/grammar.y
+++ b/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 }
%{
/*
@@ -47,19 +47,15 @@
*/
#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;
@@ -71,6 +67,8 @@ struct rtentry;
#include <stdio.h>
+#include "diag-control.h"
+
#include "pcap-int.h"
#include "gencode.h"
@@ -90,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 */
@@ -199,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 */
@@ -246,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/inet.c b/inet.c
deleted file mode 100644
index 16a483d4..00000000
--- a/inet.c
+++ /dev/null
@@ -1,403 +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 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/libpcap.pc.in b/libpcap.pc.in
new file mode 100644
index 00000000..d74cbc55
--- /dev/null
+++ b/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/missing/getopt.c b/missing/getopt.c
index cc798e1d..7c897c6f 100644
--- a/missing/getopt.c
+++ b/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/missing/getopt.h b/missing/getopt.h
index d176345a..fc83c944 100644
--- a/missing/getopt.h
+++ b/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/missing/strtok_r.c b/missing/strtok_r.c
index c9c94b95..5fca2f3d 100644
--- a/missing/strtok_r.c
+++ b/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/msdos/common.dj b/msdos/common.dj
deleted file mode 100644
index dacfd1fd..00000000
--- a/msdos/common.dj
+++ /dev/null
@@ -1,86 +0,0 @@
-#
-# Common defines for libpcap and 16/32-bit network drivers (djgpp)
-#
-
-.SUFFIXES: .exe .wlm .dxe .l .y
-.PHONY: check_gcclib
-
-default: check_gcclib all
-
-#
-# This value is normally not important. Used by 'dxe3gen' in
-# msdos/pm_drvr/makefile.dj to make "dynamically loaded modules".
-# But this is not finished.
-#
-#GCC_LIB = $(shell gcc -print-libgcc-file-name)
-GCC_LIB = .
-MAKEFILE = Makefile.dj
-
-#
-# DLX 2.91+ lib. Change path to suite.
-# Not used anymore. Uses DXE3 now.
-#
-# DLX_LIB = $(DJDIR)/contrib/dlx.291/libdlx.a
-# DLX_LINK = $(DJDIR)/bin/dlxgen.exe
-
-WATT32_ROOT = $(subst \,/,$(WATT_ROOT))
-
-OBJ_DIR = djgpp.obj
-
-ifeq ($(wildcard $(GCC_LIB)),)
-check_gcclib:
- @echo libgcc.a not found. Set \"$(GCC_LIB)\" to \"/djgpp/lib/gcc/djgpp/4.X/libgcc.a\"
-endif
-
-
-#
-# Include 32-bit driver support
-#
-USE_32BIT_DRIVERS = 0
-
-#
-# Use loadable driver modules instead of statically linking
-# all drivers.
-#
-USE_32BIT_MODULES = 0
-
-#
-# Put interrupt sensitive code/data in locked sections
-# Do `make clean' in all affected directories after changing this.
-#
-USE_SECTION_LOCKING = 0
-
-#
-# Set to 1 to use exception handler lib (only for me)
-#
-USE_EXCEPT = 0
-
-CC = gcc.exe
-LD = ld.exe
-ASM = nasm.exe -fbin -dDEBUG
-YACC = bison.exe
-LEX = flex.exe
-
-CFLAGS = -g -O2 -Wall -I. -I$(WATT32_ROOT)/inc
-
-ifeq ($(USE_EXCEPT),1)
- CFLAGS += -DUSE_EXCEPT
- EXC_LIB = d:/prog/mw/except/lib/libexc.a
-endif
-
-ifeq ($(USE_SECTION_LOCKING),1)
- CFLAGS += -DUSE_SECTION_LOCKING
-endif
-
-ifeq ($(USE_32BIT_DRIVERS),1)
- CFLAGS += -DUSE_32BIT_DRIVERS
-endif
-
-%.o: %.c
- $(CC) -c $(CFLAGS) -o $@ $<
- @echo
-
-%.o: %.s
- $(CC) -c $(CFLAGS) -x assembler-with-cpp -o $@ $<
- @echo
-
diff --git a/msdos/makefile b/msdos/makefile
index 234a2763..599a619f 100644
--- a/msdos/makefile
+++ b/msdos/makefile
@@ -23,7 +23,7 @@ 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 inet.c msdos\ndis2.c msdos\pktdrvr.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
@@ -118,8 +118,6 @@ 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
-inet.obj: inet.c 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
@@ -158,8 +156,6 @@ 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
-inet.o32: inet.c 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
diff --git a/msdos/makefile.dj b/msdos/makefile.dj
index 3f56da96..190db007 100644
--- a/msdos/makefile.dj
+++ b/msdos/makefile.dj
@@ -24,7 +24,7 @@ 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-pcap-ng.c inet.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)))
diff --git a/msdos/makefile.wc b/msdos/makefile.wc
index 61ba1378..02460120 100644
--- a/msdos/makefile.wc
+++ b/msdos/makefile.wc
@@ -28,7 +28,7 @@ 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)\inet.obj $(OBJDIR)\ndis2.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 &
@@ -108,8 +108,6 @@ $(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)\inet.obj: inet.c 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
diff --git a/msdos/ndis2.c b/msdos/ndis2.c
deleted file mode 100644
index 526b2219..00000000
--- a/msdos/ndis2.c
+++ /dev/null
@@ -1,860 +0,0 @@
-/*
- * Copyright (c) 1993,1994
- * Texas A&M University. 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 Texas A&M University
- * and its contributors.
- * 4. 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 BY THE UNIVERSITY 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 UNIVERSITY 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.
- *
- * Developers:
- * David K. Hess, Douglas Lee Schales, David R. Safford
- *
- * Heavily modified for Metaware HighC + GNU C 2.8+
- * Gisle Vanem 1998
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <dos.h>
-#include <io.h>
-#include <fcntl.h>
-#include <malloc.h>
-#include <string.h>
-
-#include "pcap-dos.h"
-#include "pcap-int.h"
-#include "msdos/ndis2.h"
-
-#if defined(USE_NDIS2)
-
-/*
- * Packet buffer handling
- */
-extern int FreePktBuf (PktBuf *buf);
-extern int EnquePktBuf (PktBuf *buf);
-extern PktBuf* AllocPktBuf (void);
-
-/*
- * Various defines
- */
-#define MAX_NUM_DEBUG_STRINGS 90
-#define DEBUG_STRING_LENGTH 80
-#define STACK_POOL_SIZE 6
-#define STACK_SIZE 256
-
-#define MEDIA_FDDI 1
-#define MEDIA_ETHERNET 2
-#define MEDIA_TOKEN 3
-
-static int startDebug = 0;
-static int stopDebug = 0;
-
-static DWORD droppedPackets = 0L;
-static WORD frameSize = 0;
-static WORD headerSize = 0;
-static int mediaType = 0;
-static char *lastErr = NULL;
-
-static BYTE debugStrings [MAX_NUM_DEBUG_STRINGS][DEBUG_STRING_LENGTH];
-static BYTE *freeStacks [STACK_POOL_SIZE];
-static int freeStackPtr = STACK_POOL_SIZE - 1;
-
-static ProtMan protManEntry = NULL;
-static WORD protManDS = 0;
-static volatile int xmitPending;
-
-static struct _PktBuf *txBufPending;
-static struct _CardHandle *handle;
-static struct _CommonChars common;
-static struct _ProtocolChars protChars;
-static struct _ProtDispatch lowerTable;
-
-static struct _FailingModules failingModules;
-static struct _BindingsList bindings;
-
-static struct {
- WORD err_num;
- char *err_text;
- } ndis_errlist[] = {
-
- { ERR_SUCCESS,
- "The function completed successfully.\n" },
-
- { ERR_WAIT_FOR_RELEASE,
- "The ReceiveChain completed successfully but the protocol has\n"
- "retained control of the buffer.\n" },
-
- { ERR_REQUEST_QUEUED,
- "The current request has been queued.\n" },
-
- { ERR_FRAME_NOT_RECOGNIZED,
- "Frame not recognized.\n" },
-
- { ERR_FRAME_REJECTED,
- "Frame was discarded.\n" },
-
- { ERR_FORWARD_FRAME,
- "Protocol wishes to forward frame to another protocol.\n" },
-
- { ERR_OUT_OF_RESOURCE,
- "Out of resource.\n" },
-
- { ERR_INVALID_PARAMETER,
- "Invalid parameter.\n" },
-
- { ERR_INVALID_FUNCTION,
- "Invalid function.\n" },
-
- { ERR_NOT_SUPPORTED,
- "Not supported.\n" },
-
- { ERR_HARDWARE_ERROR,
- "Hardware error.\n" },
-
- { ERR_TRANSMIT_ERROR,
- "The packet was not transmitted due to an error.\n" },
-
- { ERR_NO_SUCH_DESTINATION,
- "Token ring packet was not recognized when transmitted.\n" },
-
- { ERR_BUFFER_TOO_SMALL,
- "Provided buffer was too small.\n" },
-
- { ERR_ALREADY_STARTED,
- "Network drivers already started.\n" },
-
- { ERR_INCOMPLETE_BINDING,
- "Protocol driver could not complete its bindings.\n" },
-
- { ERR_DRIVER_NOT_INITIALIZED,
- "MAC did not initialize properly.\n" },
-
- { ERR_HARDWARE_NOT_FOUND,
- "Hardware not found.\n" },
-
- { ERR_HARDWARE_FAILURE,
- "Hardware failure.\n" },
-
- { ERR_CONFIGURATION_FAILURE,
- "Configuration failure.\n" },
-
- { ERR_INTERRUPT_CONFLICT,
- "Interrupt conflict.\n" },
-
- { ERR_INCOMPATIBLE_MAC,
- "The MAC is not compatible with the protocol.\n" },
-
- { ERR_INITIALIZATION_FAILED,
- "Initialization failed.\n" },
-
- { ERR_NO_BINDING,
- "Binding did not occur.\n" },
-
- { ERR_NETWORK_MAY_NOT_BE_CONNECTED,
- "The network may not be connected to the adapter.\n" },
-
- { ERR_INCOMPATIBLE_OS_VERSION,
- "The version of the operating system is incompatible with the protocol.\n" },
-
- { ERR_ALREADY_REGISTERED,
- "The protocol is already registered.\n" },
-
- { ERR_PATH_NOT_FOUND,
- "PROTMAN.EXE could not be found.\n" },
-
- { ERR_INSUFFICIENT_MEMORY,
- "Insufficient memory.\n" },
-
- { ERR_INFO_NOT_FOUND,
- "Protocol Mananger info structure is lost or corrupted.\n" },
-
- { ERR_GENERAL_FAILURE,
- "General failure.\n" }
-};
-
-/*
- * Some handy macros
- */
-#define PERROR(str) printf("%s (%d): %s\n", __FILE__,__LINE__,str)
-#define DEBUG_RING() (debugStrings[stopDebug+1 == MAX_NUM_DEBUG_STRINGS ? \
- stopDebug = 0 : ++stopDebug])
-
-/*
- * needs rewrite for DOSX
- */
-#define MAC_DISPATCH(hnd) ((struct _MacUpperDispatch*)(hnd)->common->upperDispatchTable)
-#define MAC_STATUS(hnd) ((struct _MacStatusTable*) (hnd)->common->serviceStatus)
-#define MAC_CHAR(hnd) ((struct _MacChars*) (hnd)->common->serviceChars)
-
-#ifdef NDIS_DEBUG
- #define DEBUG0(str) printf (str)
- #define DEBUG1(fmt,a) printf (fmt,a)
- #define DEBUG2(fmt,a,b) printf (fmt,a,b)
- #define TRACE0(str) sprintf (DEBUG_RING(),str)
- #define TRACE1(fmt,a) sprintf (DEBUG_RING(),fmt,a)
-#else
- #define DEBUG0(str) ((void)0)
- #define DEBUG1(fmt,a) ((void)0)
- #define DEBUG2(fmt,a,b) ((void)0)
- #define TRACE0(str) ((void)0)
- #define TRACE1(fmt,a) ((void)0)
-#endif
-
-/*
- * This routine is called from both threads
- */
-void NdisFreeStack (BYTE *aStack)
-{
- GUARD();
-
- if (freeStackPtr == STACK_POOL_SIZE - 1)
- PERROR ("tried to free too many stacks");
-
- freeStacks[++freeStackPtr] = aStack;
-
- if (freeStackPtr == 0)
- TRACE0 ("freeStackPtr went positive\n");
-
- UNGUARD();
-}
-
-/*
- * This routine is called from callbacks to allocate local data
- */
-BYTE *NdisAllocStack (void)
-{
- BYTE *stack;
-
- GUARD();
-
- if (freeStackPtr < 0)
- {
- /* Ran out of stack buffers. Return NULL which will start
- * dropping packets
- */
- TRACE0 ("freeStackPtr went negative\n");
- stack = 0;
- }
- else
- stack = freeStacks[freeStackPtr--];
-
- UNGUARD();
- return (stack);
-}
-
-CALLBACK (NdisSystemRequest (DWORD param1, DWORD param2, WORD param3,
- WORD opcode, WORD targetDS))
-{
- static int bindEntry = 0;
- struct _CommonChars *macCommon;
- volatile WORD result;
-
- switch (opcode)
- {
- case REQ_INITIATE_BIND:
- macCommon = (struct _CommonChars*) param2;
- if (macCommon == NULL)
- {
- printf ("There is an NDIS misconfiguration.\n");
- result = ERR_GENERAL_FAILURE;
- break;
- }
- DEBUG2 ("module name %s\n"
- "module type %s\n",
- macCommon->moduleName,
- ((MacChars*) macCommon->serviceChars)->macName);
-
- /* Binding to the MAC */
- result = macCommon->systemRequest ((DWORD)&common, (DWORD)&macCommon,
- 0, REQ_BIND,
- macCommon->moduleDS);
-
- if (!strcmp(bindings.moduleName[bindEntry], handle->moduleName))
- handle->common = macCommon;
- else PERROR ("unknown module");
- ++bindEntry;
- break;
-
- case REQ_INITIATE_UNBIND:
- macCommon = (struct _CommonChars*) param2;
- result = macCommon->systemRequest ((DWORD)&common, 0,
- 0, REQ_UNBIND,
- macCommon->moduleDS);
- break;
-
- default:
- result = ERR_GENERAL_FAILURE;
- break;
- }
- ARGSUSED (param1);
- ARGSUSED (param3);
- ARGSUSED (targetDS);
- return (result);
-}
-
-CALLBACK (NdisRequestConfirm (WORD protId, WORD macId, WORD reqHandle,
- WORD status, WORD request, WORD protDS))
-{
- ARGSUSED (protId); ARGSUSED (macId);
- ARGSUSED (reqHandle); ARGSUSED (status);
- ARGSUSED (request); ARGSUSED (protDS);
- return (ERR_SUCCESS);
-}
-
-CALLBACK (NdisTransmitConfirm (WORD protId, WORD macId, WORD reqHandle,
- WORD status, WORD protDS))
-{
- xmitPending--;
- FreePktBuf (txBufPending); /* Add passed ECB back to the free list */
-
- ARGSUSED (reqHandle);
- ARGSUSED (status);
- ARGSUSED (protDS);
- return (ERR_SUCCESS);
-}
-
-
-/*
- * The primary function for receiving packets
- */
-CALLBACK (NdisReceiveLookahead (WORD macId, WORD frameSize,
- WORD bytesAvail, BYTE *buffer,
- BYTE *indicate, WORD protDS))
-{
- int result;
- PktBuf *pktBuf;
- WORD bytesCopied;
- struct _TDBufDescr tDBufDescr;
-
-#if 0
- TRACE1 ("lookahead length = %d, ", bytesAvail);
- TRACE1 ("ecb = %08lX, ", *ecb);
- TRACE1 ("count = %08lX\n", count);
- TRACE1 ("offset = %08lX, ", offset);
- TRACE1 ("timesAllowed = %d, ", timesAllowed);
- TRACE1 ("packet size = %d\n", look->dataLookAheadLen);
-#endif
-
- /* Allocate a buffer for the packet
- */
- if ((pktBuf = AllocPktBuf()) == NULL)
- {
- droppedPackets++;
- return (ERR_FRAME_REJECTED);
- }
-
- /*
- * Now kludge things. Note we will have to undo this later. This will
- * make the packet contiguous after the MLID has done the requested copy.
- */
-
- tDBufDescr.tDDataCount = 1;
- tDBufDescr.tDBufDescrRec[0].tDPtrType = NDIS_PTR_PHYSICAL;
- tDBufDescr.tDBufDescrRec[0].tDDataPtr = pktBuf->buffer;
- tDBufDescr.tDBufDescrRec[0].tDDataLen = pktBuf->length;
- tDBufDescr.tDBufDescrRec[0].dummy = 0;
-
- result = MAC_DISPATCH(handle)->transferData (&bytesCopied, 0, &tDBufDescr,
- handle->common->moduleDS);
- pktBuf->packetLength = bytesCopied;
-
- if (result == ERR_SUCCESS)
- EnquePktBuf(pktBuf);
- else FreePktBuf (pktBuf);
-
- ARGSUSED (frameSize);
- ARGSUSED (bytesAvail);
- ARGSUSED (indicate);
- ARGSUSED (protDS);
-
- return (ERR_SUCCESS);
-}
-
-CALLBACK (NdisIndicationComplete (WORD macId, WORD protDS))
-{
- ARGSUSED (macId);
- ARGSUSED (protDS);
-
- /* We don't give a hoot about these. Just return
- */
- return (ERR_SUCCESS);
-}
-
-/*
- * This is the OTHER way we may receive packets
- */
-CALLBACK (NdisReceiveChain (WORD macId, WORD frameSize, WORD reqHandle,
- struct _RxBufDescr *rxBufDescr,
- BYTE *indicate, WORD protDS))
-{
- struct _PktBuf *pktBuf;
- int i;
-
- /*
- * For now we copy the entire packet over to a PktBuf structure. This may be
- * a performance hit but this routine probably isn't called very much, and
- * it is a lot of work to do it otherwise. Also if it is a filter protocol
- * packet we could end up sucking up MAC buffes.
- */
-
- if ((pktBuf = AllocPktBuf()) == NULL)
- {
- droppedPackets++;
- return (ERR_FRAME_REJECTED);
- }
- pktBuf->packetLength = 0;
-
- /* Copy the packet to the buffer
- */
- for (i = 0; i < rxBufDescr->rxDataCount; ++i)
- {
- struct _RxBufDescrRec *rxDescr = &rxBufDescr->rxBufDescrRec[i];
-
- memcpy (pktBuf->buffer + pktBuf->packetLength,
- rxDescr->rxDataPtr, rxDescr->rxDataLen);
- pktBuf->packetLength += rxDescr->rxDataLen;
- }
-
- EnquePktBuf (pktBuf);
-
- ARGSUSED (frameSize);
- ARGSUSED (reqHandle);
- ARGSUSED (indicate);
- ARGSUSED (protDS);
-
- /* This frees up the buffer for the MAC to use
- */
- return (ERR_SUCCESS);
-}
-
-CALLBACK (NdisStatusProc (WORD macId, WORD param1, BYTE *indicate,
- WORD opcode, WORD protDS))
-{
- switch (opcode)
- {
- case STATUS_RING_STATUS:
- break;
- case STATUS_ADAPTER_CHECK:
- break;
- case STATUS_START_RESET:
- break;
- case STATUS_INTERRUPT:
- break;
- case STATUS_END_RESET:
- break;
- default:
- break;
- }
- ARGSUSED (macId);
- ARGSUSED (param1);
- ARGSUSED (indicate);
- ARGSUSED (opcode);
- ARGSUSED (protDS);
-
- /* We don't need to do anything about this stuff yet
- */
- return (ERR_SUCCESS);
-}
-
-/*
- * Tell the NDIS driver to start the delivery of the packet
- */
-int NdisSendPacket (struct _PktBuf *pktBuf, int macId)
-{
- struct _TxBufDescr txBufDescr;
- int result;
-
- xmitPending++;
- txBufPending = pktBuf; /* we only have 1 pending Tx at a time */
-
- txBufDescr.txImmedLen = 0;
- txBufDescr.txImmedPtr = NULL;
- txBufDescr.txDataCount = 1;
- txBufDescr.txBufDescrRec[0].txPtrType = NDIS_PTR_PHYSICAL;
- txBufDescr.txBufDescrRec[0].dummy = 0;
- txBufDescr.txBufDescrRec[0].txDataLen = pktBuf->packetLength;
- txBufDescr.txBufDescrRec[0].txDataPtr = pktBuf->buffer;
-
- result = MAC_DISPATCH(handle)->transmitChain (common.moduleId,
- pktBuf->handle,
- &txBufDescr,
- handle->common->moduleDS);
- switch (result)
- {
- case ERR_OUT_OF_RESOURCE:
- /* Note that this should not happen but if it does there is not
- * much we can do about it
- */
- printf ("ERROR: transmit queue overflowed\n");
- return (0);
-
- case ERR_SUCCESS:
- /* Everything was hunky dory and synchronous. Free up the
- * packet buffer
- */
- xmitPending--;
- FreePktBuf (pktBuf);
- return (1);
-
- case ERR_REQUEST_QUEUED:
- /* Everything was hunky dory and asynchronous. Do nothing
- */
- return (1);
-
- default:
- printf ("Tx fail, code = %04X\n", result);
- return (0);
- }
-}
-
-
-
-static int ndis_nerr = sizeof(ndis_errlist) / sizeof(ndis_errlist[0]);
-
-static char *Ndis_strerror (WORD errorCode)
-{
- static char buf[30];
- int i;
-
- for (i = 0; i < ndis_nerr; i++)
- if (errorCode == ndis_errlist[i].err_num)
- return (ndis_errlist[i].err_text);
-
- sprintf (buf,"unknown error %d",errorCode);
- return (buf);
-}
-
-
-char *NdisLastError (void)
-{
- char *errStr = lastErr;
- lastErr = NULL;
- return (errStr);
-}
-
-int NdisOpen (void)
-{
- struct _ReqBlock reqBlock;
- int result;
- int ndisFd = open (NDIS_PATH, O_RDONLY);
-
- if (ndisFd < 0)
- {
- printf ("Could not open NDIS Protocol Manager device.\n");
- return (0);
- }
-
- memset (&reqBlock, 0, sizeof(ReqBlock));
-
- reqBlock.opcode = PM_GET_PROTOCOL_MANAGER_LINKAGE;
-
- result = NdisGetLinkage (ndisFd, (char*)&reqBlock, sizeof(ReqBlock));
- if (result != 0)
- {
- printf ("Could not get Protocol Manager linkage.\n");
- close (ndisFd);
- return (0);
- }
-
- close (ndisFd);
- protManEntry = (ProtMan) reqBlock.pointer1;
- protManDS = reqBlock.word1;
-
- DEBUG2 ("Entry Point = %04X:%04X\n", FP_SEG(protManEntry),FP_OFF(protManEntry));
- DEBUG1 ("ProtMan DS = %04X\n", protManDS);
- return (1);
-}
-
-
-int NdisRegisterAndBind (int promis)
-{
- struct _ReqBlock reqBlock;
- WORD result;
-
- memset (&common,0,sizeof(common));
-
- common.tableSize = sizeof (common);
-
- common.majorNdisVersion = 2;
- common.minorNdisVersion = 0;
- common.majorModuleVersion = 2;
- common.minorModuleVersion = 0;
-
- /* Indicates binding from below and dynamically loaded
- */
- common.moduleFlags = 0x00000006L;
-
- strcpy (common.moduleName, "PCAP");
-
- common.protocolLevelUpper = 0xFF;
- common.protocolLevelLower = 1;
- common.interfaceLower = 1;
-#ifdef __DJGPP__
- common.moduleDS = _dos_ds; /* the callback data segment */
-#else
- common.moduleDS = _DS;
-#endif
-
- common.systemRequest = (SystemRequest) systemRequestGlue;
- common.serviceChars = (BYTE*) &protChars;
- common.serviceStatus = NULL;
- common.upperDispatchTable = NULL;
- common.lowerDispatchTable = (BYTE*) &lowerTable;
-
- protChars.length = sizeof (protChars);
- protChars.name[0] = 0;
- protChars.type = 0;
-
- lowerTable.backPointer = &common;
- lowerTable.requestConfirm = requestConfirmGlue;
- lowerTable.transmitConfirm = transmitConfirmGlue;
- lowerTable.receiveLookahead = receiveLookaheadGlue;
- lowerTable.indicationComplete = indicationCompleteGlue;
- lowerTable.receiveChain = receiveChainGlue;
- lowerTable.status = statusGlue;
- lowerTable.flags = 3;
- if (promis)
- lowerTable.flags |= 4; /* promiscous mode (receive everything) */
-
- bindings.numBindings = 1;
- strcpy (bindings.moduleName[0], handle->moduleName);
-
- /* Register ourselves with NDIS
- */
- reqBlock.opcode = PM_REGISTER_MODULE;
- reqBlock.pointer1 = (BYTE FAR*) &common;
- reqBlock.pointer2 = (BYTE FAR*) &bindings;
-
- result = (*protManEntry) (&reqBlock, protManDS);
- if (result)
- {
- printf ("Protman registering failed: %s\n", Ndis_strerror(result));
- return (0);
- }
-
- /* Start the binding process
- */
- reqBlock.opcode = PM_BIND_AND_START;
- reqBlock.pointer1 = (BYTE FAR*) &failingModules;
-
- result = (*protManEntry) (&reqBlock, protManDS);
- if (result)
- {
- printf ("Start binding failed: %s\n", Ndis_strerror(result));
- return (0);
- }
- return (1);
-}
-
-static int CheckMacFeatures (CardHandle *card)
-{
- DWORD serviceFlags;
- BYTE _far *mediaString;
- BYTE _far *mac_addr;
-
- DEBUG2 ("checking card features\n"
- "common table address = %08lX, macId = %d\n",
- card->common, card->common->moduleId);
-
- serviceFlags = MAC_CHAR (handle)->serviceFlags;
-
- if ((serviceFlags & SF_PROMISCUOUS) == 0)
- {
- printf ("The MAC %s does not support promiscuous mode.\n",
- card->moduleName);
- return (0);
- }
-
- mediaString = MAC_CHAR (handle)->macName;
-
- DEBUG1 ("media type = %s\n",mediaString);
-
- /* Get the media type. And set the header size
- */
- if (!strncmp(mediaString,"802.3",5) ||
- !strncmp(mediaString,"DIX",3) ||
- !strncmp(mediaString,"DIX+802.3",9))
- headerSize = sizeof (EthernetIIHeader);
-
- else if (!strncmp(mediaString,"FDDI",4))
- headerSize = sizeof (FddiHeader) +
- sizeof (Ieee802Dot2SnapHeader);
- else
- {
- printf ("Unsupported MAC type: `%s'\n", mediaString);
- return (0);
- }
-
- frameSize = MAC_CHAR (handle)->maxFrameSize;
- mac_addr = MAC_CHAR (handle)->currentAddress;
-
- printf ("Hardware address: %02X:%02X:%02X:%02X:%02X:%02X\n",
- mac_addr[0], mac_addr[1], mac_addr[2],
- mac_addr[3], mac_addr[4], mac_addr[5]);
- return (1);
-}
-
-static int NdisStartMac (CardHandle *card)
-{
- WORD result;
-
- /* Set the lookahead length
- */
- result = MAC_DISPATCH(handle)->request (common.moduleId, 0,
- headerSize, 0,
- REQ_SET_LOOKAHEAD,
- card->common->moduleDS);
-
- /* We assume that if we got INVALID PARAMETER then either this
- * is not supported or will work anyway. NE2000 does this.
- */
- if (result != ERR_SUCCESS && result != ERR_INVALID_PARAMETER)
- {
- DEBUG1 ("Set lookahead failed: %s\n", Ndis_strerror(result));
- return (0);
- }
-
- /* Set the packet filter. Note that for some medias and drivers we
- * must specify all three flags or the card(s) will not operate correctly.
- */
- result = MAC_DISPATCH(handle)->request (common.moduleId, 0,
- /* all packets */ FILTER_PROMISCUOUS |
- /* packets to us */ FILTER_DIRECTED |
- /* broadcasts */ FILTER_BROADCAST,
- 0, REQ_SET_PACKET_FILTER,
- card->common->moduleDS);
- if (result != ERR_SUCCESS)
- {
- DEBUG1 ("Set packet filter failed: %s\n", Ndis_strerror(result));
- return (0);
- }
-
- /* If OPEN/CLOSE supported then open the adapter
- */
- if (MAC_CHAR(handle)->serviceFlags & SF_OPEN_CLOSE)
- {
- result = MAC_DISPATCH(handle)->request (common.moduleId, 0, 0, NULL,
- REQ_OPEN_ADAPTER,
- card->common->moduleDS);
- if (result != ERR_SUCCESS)
- {
- DEBUG1 ("Opening the MAC failed: %s\n", Ndis_strerror(result));
- return (0);
- }
- }
- return (1);
-}
-
-void NdisShutdown (void)
-{
- struct _ReqBlock reqBlock;
- int result, i;
-
- if (!handle)
- return;
-
- /* If the adapters support open and are open then close them
- */
- if ((MAC_CHAR(handle)->serviceFlags & SF_OPEN_CLOSE) &&
- (MAC_STATUS(handle)->macStatus & MAC_OPEN))
- {
- result = MAC_DISPATCH(handle)->request (common.moduleId, 0, 0, 0,
- REQ_CLOSE_ADAPTER,
- handle->common->moduleDS);
- if (result != ERR_SUCCESS)
- {
- printf ("Closing the MAC failed: %s\n", Ndis_strerror(result));
- return;
- }
- }
-
- /* Tell the Protocol Manager to unbind and stop
- */
- reqBlock.opcode = PM_UNBIND_AND_STOP;
- reqBlock.pointer1 = (BYTE FAR*) &failingModules;
- reqBlock.pointer2 = NULL;
-
- result = (*protManEntry) (&reqBlock, protManDS);
- if (result)
- printf ("Unbind failed: %s\n", Ndis_strerror(result));
-
- for (i = 0; i < STACK_POOL_SIZE; ++i)
- free (freeStacks[i] - STACK_SIZE);
-
- handle = NULL;
-}
-
-int NdisInit (int promis)
-{
- int i, result;
-
- /* Allocate the real mode stacks used for NDIS callbacks
- */
- for (i = 0; i < STACK_POOL_SIZE; ++i)
- {
- freeStacks[i] = malloc (STACK_SIZE);
- if (!freeStacks[i])
- return (0);
- freeStacks[i] += STACK_SIZE;
- }
-
- if (!NdisOpen())
- return (0);
-
- if (!NdisRegisterAndBind(promis))
- return (0);
-
- DEBUG1 ("My module id: %d\n", common.moduleId);
- DEBUG1 ("Handle id; %d\n", handle->common->moduleId);
- DEBUG1 ("MAC card: %-16s - ", handle->moduleName);
-
- atexit (NdisShutdown);
-
- if (!CheckMacFeatures(&handle))
- return (0);
-
- switch (mediaType)
- {
- case MEDIA_FDDI:
- DEBUG0 ("Media type: FDDI");
- break;
- case MEDIA_ETHERNET:
- DEBUG0 ("Media type: ETHERNET");
- break;
- default:
- DEBUG0 ("Unsupported media.\n");
- return (0);
- }
-
- DEBUG1 (" - Frame size: %d\n", frameSize);
-
- if (!NdisStartMac(&handle))
- return (0);
- return (1);
-}
-#endif /* USE_NDIS2 */
-
diff --git a/msdos/ndis2.h b/msdos/ndis2.h
deleted file mode 100644
index f278b5dc..00000000
--- a/msdos/ndis2.h
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * Copyright (c) 1993,1994
- * Texas A&M University. 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 Texas A&M University
- * and its contributors.
- * 4. 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 BY THE UNIVERSITY 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 UNIVERSITY 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.
- *
- * Developers:
- * David K. Hess, Douglas Lee Schales, David R. Safford
- *
- * Heavily modified for Metaware HighC + GNU C 2.8+
- * Gisle Vanem 1998
- */
-
-#ifndef __PCAP_NDIS_H
-#define __PCAP_NDIS_H
-
-#if defined (__HIGHC__)
- #define pascal _CC(_CALLEE_POPS_STACK & ~_REVERSE_PARMS) /* calling convention */
- #define CALLBACK(foo) pascal WORD foo
- #define PAS_PTR(x,arg) typedef FAR WORD pascal (*x) arg
- #define GUARD() _inline (0x9C,0xFA) /* pushfd, cli */
- #define UNGUARD() _inline (0x9D) /* popfd */
- #define FAR _far
-
-#elif defined(__GNUC__)
- #define CALLBACK(foo) WORD foo __attribute__((stdcall))
- #define PAS_PTR(x,arg) typedef WORD (*x) arg __attribute__((stdcall))
- #define GUARD() __asm__ __volatile__ ("pushfd; cli")
- #define UNGUARD() __asm__ __volatile__ ("popfd")
- #define FAR
-
-#elif defined (__TURBOC__)
- #define CALLBACK(foo) WORD pascal foo
- #define PAS_PTR(x,arg) typedef WORD pascal (_far *x) arg
- #define GUARD() _asm { pushf; cli }
- #define UNGUARD() _asm { popf }
- #define FAR _far
-
-#elif defined (__WATCOMC__)
- #define CALLBACK(foo) WORD pascal foo
- #define PAS_PTR(x,arg) typedef WORD pascal (_far *x) arg
- #define GUARD() _disable()
- #define UNGUARD() _enable()
- #define FAR _far
-
-#else
- #error Unsupported compiler
-#endif
-
-
-/*
- * Forwards
- */
-struct _ReqBlock;
-struct _TxBufDescr;
-struct _TDBufDescr;
-
-/*
- * Protocol Manager API
- */
-PAS_PTR (ProtMan, (struct _ReqBlock FAR*, WORD));
-
-/*
- * System request
- */
-PAS_PTR (SystemRequest, (DWORD, DWORD, WORD, WORD, WORD));
-
-/*
- * MAC API
- */
-PAS_PTR (TransmitChain, (WORD, WORD, struct _TxBufDescr FAR*, WORD));
-PAS_PTR (TransferData, (WORD*,WORD, struct _TDBufDescr FAR*, WORD));
-PAS_PTR (Request, (WORD, WORD, WORD, DWORD, WORD, WORD));
-PAS_PTR (ReceiveRelease,(WORD, WORD));
-PAS_PTR (IndicationOn, (WORD));
-PAS_PTR (IndicationOff, (WORD));
-
-
-typedef enum {
- HARDWARE_NOT_INSTALLED = 0,
- HARDWARE_FAILED_DIAG = 1,
- HARDWARE_FAILED_CONFIG = 2,
- HARDWARE_HARD_FAULT = 3,
- HARDWARE_SOFT_FAULT = 4,
- HARDWARE_OK = 7,
- HARDWARE_MASK = 0x0007,
- MAC_BOUND = 0x0008,
- MAC_OPEN = 0x0010,
- DIAG_IN_PROGRESS = 0x0020
- } NdisMacStatus;
-
-typedef enum {
- STATUS_RING_STATUS = 1,
- STATUS_ADAPTER_CHECK = 2,
- STATUS_START_RESET = 3,
- STATUS_INTERRUPT = 4,
- STATUS_END_RESET = 5
- } NdisStatus;
-
-typedef enum {
- FILTER_DIRECTED = 1,
- FILTER_BROADCAST = 2,
- FILTER_PROMISCUOUS = 4,
- FILTER_SOURCE_ROUTE = 8
- } NdisPacketFilter;
-
-typedef enum {
- REQ_INITIATE_DIAGNOSTICS = 1,
- REQ_READ_ERROR_LOG = 2,
- REQ_SET_STATION_ADDRESS = 3,
- REQ_OPEN_ADAPTER = 4,
- REQ_CLOSE_ADAPTER = 5,
- REQ_RESET_MAC = 6,
- REQ_SET_PACKET_FILTER = 7,
- REQ_ADD_MULTICAST_ADDRESS = 8,
- REQ_DELETE_MULTICAST_ADDRESS = 9,
- REQ_UPDATE_STATISTICS = 10,
- REQ_CLEAR_STATISTICS = 11,
- REQ_INTERRUPT_REQUEST = 12,
- REQ_SET_FUNCTIONAL_ADDRESS = 13,
- REQ_SET_LOOKAHEAD = 14
- } NdisGeneralRequest;
-
-typedef enum {
- SF_BROADCAST = 0x00000001L,
- SF_MULTICAST = 0x00000002L,
- SF_FUNCTIONAL = 0x00000004L,
- SF_PROMISCUOUS = 0x00000008L,
- SF_SOFT_ADDRESS = 0x00000010L,
- SF_STATS_CURRENT = 0x00000020L,
- SF_INITIATE_DIAGS = 0x00000040L,
- SF_LOOPBACK = 0x00000080L,
- SF_RECEIVE_CHAIN = 0x00000100L,
- SF_SOURCE_ROUTING = 0x00000200L,
- SF_RESET_MAC = 0x00000400L,
- SF_OPEN_CLOSE = 0x00000800L,
- SF_INTERRUPT_REQUEST = 0x00001000L,
- SF_SOURCE_ROUTING_BRIDGE = 0x00002000L,
- SF_VIRTUAL_ADDRESSES = 0x00004000L
- } NdisMacServiceFlags;
-
-typedef enum {
- REQ_INITIATE_BIND = 1,
- REQ_BIND = 2,
- REQ_INITIATE_PREBIND = 3,
- REQ_INITIATE_UNBIND = 4,
- REQ_UNBIND = 5
- } NdisSysRequest;
-
-typedef enum {
- PM_GET_PROTOCOL_MANAGER_INFO = 1,
- PM_REGISTER_MODULE = 2,
- PM_BIND_AND_START = 3,
- PM_GET_PROTOCOL_MANAGER_LINKAGE = 4,
- PM_GET_PROTOCOL_INI_PATH = 5,
- PM_REGISTER_PROTOCOL_MANAGER_INFO = 6,
- PM_INIT_AND_REGISTER = 7,
- PM_UNBIND_AND_STOP = 8,
- PM_BIND_STATUS = 9,
- PM_REGISTER_STATUS = 10
- } NdisProtManager;
-
-
-typedef enum {
- ERR_SUCCESS = 0x00,
- ERR_WAIT_FOR_RELEASE = 0x01,
- ERR_REQUEST_QUEUED = 0x02,
- ERR_FRAME_NOT_RECOGNIZED = 0x03,
- ERR_FRAME_REJECTED = 0x04,
- ERR_FORWARD_FRAME = 0x05,
- ERR_OUT_OF_RESOURCE = 0x06,
- ERR_INVALID_PARAMETER = 0x07,
- ERR_INVALID_FUNCTION = 0x08,
- ERR_NOT_SUPPORTED = 0x09,
- ERR_HARDWARE_ERROR = 0x0A,
- ERR_TRANSMIT_ERROR = 0x0B,
- ERR_NO_SUCH_DESTINATION = 0x0C,
- ERR_BUFFER_TOO_SMALL = 0x0D,
- ERR_ALREADY_STARTED = 0x20,
- ERR_INCOMPLETE_BINDING = 0x21,
- ERR_DRIVER_NOT_INITIALIZED = 0x22,
- ERR_HARDWARE_NOT_FOUND = 0x23,
- ERR_HARDWARE_FAILURE = 0x24,
- ERR_CONFIGURATION_FAILURE = 0x25,
- ERR_INTERRUPT_CONFLICT = 0x26,
- ERR_INCOMPATIBLE_MAC = 0x27,
- ERR_INITIALIZATION_FAILED = 0x28,
- ERR_NO_BINDING = 0x29,
- ERR_NETWORK_MAY_NOT_BE_CONNECTED = 0x2A,
- ERR_INCOMPATIBLE_OS_VERSION = 0x2B,
- ERR_ALREADY_REGISTERED = 0x2C,
- ERR_PATH_NOT_FOUND = 0x2D,
- ERR_INSUFFICIENT_MEMORY = 0x2E,
- ERR_INFO_NOT_FOUND = 0x2F,
- ERR_GENERAL_FAILURE = 0xFF
- } NdisError;
-
-#define NDIS_PARAM_INTEGER 0
-#define NDIS_PARAM_STRING 1
-
-#define NDIS_TX_BUF_LENGTH 8
-#define NDIS_TD_BUF_LENGTH 1
-#define NDIS_RX_BUF_LENGTH 8
-
-#define NDIS_PTR_PHYSICAL 0
-#define NDIS_PTR_VIRTUAL 2
-
-#define NDIS_PATH "PROTMAN$"
-
-
-typedef struct _CommonChars {
- WORD tableSize;
- BYTE majorNdisVersion; /* 2 - Latest version */
- BYTE minorNdisVersion; /* 0 */
- WORD reserved1;
- BYTE majorModuleVersion;
- BYTE minorModuleVersion;
- DWORD moduleFlags;
- /* 0 - Binding at upper boundary supported
- * 1 - Binding at lower boundary supported
- * 2 - Dynamically bound.
- * 3-31 - Reserved, must be zero.
- */
- BYTE moduleName[16];
- BYTE protocolLevelUpper;
- /* 1 - MAC
- * 2 - Data Link
- * 3 - Network
- * 4 - Transport
- * 5 - Session
- * -1 - Not specified
- */
- BYTE interfaceUpper;
- BYTE protocolLevelLower;
- /* 0 - Physical
- * 1 - MAC
- * 2 - Data Link
- * 3 - Network
- * 4 - Transport
- * 5 - Session
- * -1 - Not specified
- */
- BYTE interfaceLower;
- WORD moduleId;
- WORD moduleDS;
- SystemRequest systemRequest;
- BYTE *serviceChars;
- BYTE *serviceStatus;
- BYTE *upperDispatchTable;
- BYTE *lowerDispatchTable;
- BYTE *reserved2; /* Must be NULL */
- BYTE *reserved3; /* Must be NULL */
- } CommonChars;
-
-
-typedef struct _MulticastList {
- WORD maxMulticastAddresses;
- WORD numberMulticastAddresses;
- BYTE multicastAddress[16][16];
- } MulticastList;
-
-
-typedef struct _MacChars {
- WORD tableSize;
- BYTE macName[16];
- WORD addressLength;
- BYTE permanentAddress[16];
- BYTE currentAddress[16];
- DWORD currentFunctionalAddress;
- MulticastList *multicastList;
- DWORD linkSpeed;
- DWORD serviceFlags;
- WORD maxFrameSize;
- DWORD txBufferSize;
- WORD txBufferAllocSize;
- DWORD rxBufferSize;
- WORD rxBufferAllocSize;
- BYTE ieeeVendor[3];
- BYTE vendorAdapter;
- BYTE *vendorAdapterDescription;
- WORD interruptLevel;
- WORD txQueueDepth;
- WORD maxDataBlocks;
- } MacChars;
-
-
-typedef struct _ProtocolChars {
- WORD length;
- BYTE name[16];
- WORD type;
- } ProtocolChars;
-
-
-typedef struct _MacUpperDispatch {
- CommonChars *backPointer;
- Request request;
- TransmitChain transmitChain;
- TransferData transferData;
- ReceiveRelease receiveRelease;
- IndicationOn indicationOn;
- IndicationOff indicationOff;
- } MacUpperDispatch;
-
-
-typedef struct _MacStatusTable {
- WORD tableSize;
- DWORD lastDiag;
- DWORD macStatus;
- WORD packetFilter;
- BYTE *mediaSpecificStats;
- DWORD lastClear;
- DWORD totalFramesRx;
- DWORD totalFramesCrc;
- DWORD totalBytesRx;
- DWORD totalDiscardBufSpaceRx;
- DWORD totalMulticastRx;
- DWORD totalBroadcastRx;
- DWORD obsolete1[5];
- DWORD totalDiscardHwErrorRx;
- DWORD totalFramesTx;
- DWORD totalBytesTx;
- DWORD totalMulticastTx;
- DWORD totalBroadcastTx;
- DWORD obsolete2[2];
- DWORD totalDiscardTimeoutTx;
- DWORD totalDiscardHwErrorTx;
- } MacStatusTable;
-
-
-typedef struct _ProtDispatch {
- CommonChars *backPointer;
- DWORD flags;
- /* 0 - handles non-LLC frames
- * 1 - handles specific-LSAP LLC frames
- * 2 - handles specific-LSAP LLC frames
- * 3-31 - reserved must be 0
- */
- void (*requestConfirm) (void);
- void (*transmitConfirm) (void);
- void (*receiveLookahead) (void);
- void (*indicationComplete) (void);
- void (*receiveChain) (void);
- void (*status) (void);
- } ProtDispatch;
-
-
-typedef struct _ReqBlock {
- WORD opcode;
- WORD status;
- BYTE FAR *pointer1;
- BYTE FAR *pointer2;
- WORD word1;
- } ReqBlock;
-
-
-typedef struct _TxBufDescrRec {
- BYTE txPtrType;
- BYTE dummy;
- WORD txDataLen;
- BYTE *txDataPtr;
- } TxBufDescrRec;
-
-
-typedef struct _TxBufDescr {
- WORD txImmedLen;
- BYTE *txImmedPtr;
- WORD txDataCount;
- TxBufDescrRec txBufDescrRec[NDIS_TX_BUF_LENGTH];
- } TxBufDescr;
-
-
-typedef struct _TDBufDescrRec {
- BYTE tDPtrType;
- BYTE dummy;
- WORD tDDataLen;
- BYTE *tDDataPtr;
- } TDBufDescrRec;
-
-
-typedef struct _TDBufDescr {
- WORD tDDataCount;
- TDBufDescrRec tDBufDescrRec[NDIS_TD_BUF_LENGTH];
- } TDBufDescr;
-
-
-typedef struct _RxBufDescrRec {
- WORD rxDataLen;
- BYTE *rxDataPtr;
- } RxBufDescrRec;
-
-
-typedef struct _RxBufDescr {
- WORD rxDataCount;
- RxBufDescrRec rxBufDescrRec[NDIS_RX_BUF_LENGTH];
- } RxBufDescr;
-
-
-typedef struct _PktBuf {
- struct _PktBuf *nextLink;
- struct _PktBuf *prevLink;
- int handle;
- int length;
- int packetLength;
- DWORD sequence;
- BYTE *buffer;
- } PktBuf;
-
-
-typedef struct _CardHandle {
- BYTE moduleName[16];
- CommonChars *common;
- } CardHandle;
-
-
-typedef struct _BindingsList {
- WORD numBindings;
- BYTE moduleName[2][16];
- } BindingsList;
-
-
-typedef struct _FailingModules {
- BYTE upperModuleName[16];
- BYTE lowerModuleName[16];
- } FailingModules;
-
-
-typedef union _HardwareAddress {
- BYTE bytes[6];
- WORD words[3];
- struct {
- BYTE bytes[6];
- } addr;
- } HardwareAddress;
-
-
-typedef struct _FddiHeader {
- BYTE frameControl;
- HardwareAddress etherDestHost;
- HardwareAddress etherSrcHost;
- } FddiHeader;
-
-
-typedef struct _EthernetIIHeader {
- HardwareAddress etherDestHost;
- HardwareAddress etherSrcHost;
- WORD etherType;
- } EthernetIIHeader;
-
-
-typedef struct _Ieee802Dot5Header {
- HardwareAddress etherDestHost;
- HardwareAddress etherSrcHost;
- BYTE routeInfo[30];
- } Ieee802Dot5Header;
-
-
-typedef struct _Ieee802Dot2SnapHeader {
- BYTE dsap; /* 0xAA */
- BYTE ssap; /* 0xAA */
- BYTE control; /* 3 */
- BYTE protocolId[5];
- } Ieee802Dot2SnapHeader;
-
-
-/*
- * Prototypes
- */
-extern char *NdisLastError (void);
-extern int NdisOpen (void);
-extern int NdisInit (int promis);
-extern int NdisRegisterAndBind (int promis);
-extern void NdisShutdown (void);
-extern void NdisCheckMacFeatures (struct _CardHandle *card);
-extern int NdisSendPacket (struct _PktBuf *pktBuf, int macId);
-
-/*
- * Assembly "glue" functions
- */
-extern int systemRequestGlue();
-extern int requestConfirmGlue();
-extern int transmitConfirmGlue();
-extern int receiveLookaheadGlue();
-extern int indicationCompleteGlue();
-extern int receiveChainGlue();
-extern int statusGlue();
-
-/*
- * IOCTL function
- */
-#ifdef __SMALL__
-extern int _far NdisGetLinkage (int handle, char *data, int size);
-#else
-extern int NdisGetLinkage (int handle, char *data, int size);
-#endif
-
-/*
- * NDIS callback handlers
- */
-CALLBACK (NdisSystemRequest (DWORD,DWORD, WORD, WORD, WORD));
-CALLBACK (NdisRequestConfirm ( WORD, WORD, WORD, WORD, WORD,WORD));
-CALLBACK (NdisTransmitConfirm ( WORD, WORD, WORD, WORD, WORD));
-CALLBACK (NdisReceiveLookahead ( WORD, WORD, WORD, BYTE*, BYTE*, WORD));
-CALLBACK (NdisReceiveChain ( WORD, WORD, WORD, struct _RxBufDescr*, BYTE*, WORD));
-CALLBACK (NdisStatusProc ( WORD, WORD, BYTE*, WORD,WORD));
-CALLBACK (NdisIndicationComplete( WORD, WORD));
-
-BYTE *NdisAllocStack (void);
-void NdisFreeStack (BYTE*);
-
-#ifdef __HIGHC__
- #define RENAME_ASM_SYM(x) pragma Alias(x,"@" #x "") /* prepend `@' */
- #define RENAME_C_SYM(x) pragma Alias(x,"_" #x "") /* prepend `_' */
-
- RENAME_ASM_SYM (systemRequestGlue);
- RENAME_ASM_SYM (requestConfirmGlue);
- RENAME_ASM_SYM (transmitConfirmGlue);
- RENAME_ASM_SYM (receiveLookaheadGlue);
- RENAME_ASM_SYM (indicationCompleteGlue);
- RENAME_ASM_SYM (receiveChainGlue);
- RENAME_ASM_SYM (statusGlue);
- RENAME_ASM_SYM (NdisGetLinkage);
- RENAME_C_SYM (NdisSystemRequest);
- RENAME_C_SYM (NdisRequestConfirm);
- RENAME_C_SYM (NdisTransmitConfirm);
- RENAME_C_SYM (NdisReceiveLookahead);
- RENAME_C_SYM (NdisIndicationComplete);
- RENAME_C_SYM (NdisReceiveChain);
- RENAME_C_SYM (NdisStatusProc);
- RENAME_C_SYM (NdisAllocStack);
- RENAME_C_SYM (NdisFreeStack);
-#endif
-
-#endif
diff --git a/msdos/ndis_0.asm b/msdos/ndis_0.asm
deleted file mode 100644
index ea65e0f8..00000000
--- a/msdos/ndis_0.asm
+++ /dev/null
@@ -1,188 +0,0 @@
-PAGE 60,132
-NAME NDIS_0
-
-ifdef DOSX
- .386
- _TEXT SEGMENT PUBLIC DWORD USE16 'CODE'
- _TEXT ENDS
- _DATA SEGMENT PUBLIC DWORD USE16 'CODE'
- _DATA ENDS
- _TEXT32 SEGMENT PUBLIC BYTE USE32 'CODE'
- _TEXT32 ENDS
- CB_DSEG EQU <CS> ; DOSX is tiny-model
- D_SEG EQU <_TEXT SEGMENT>
- D_END EQU <_TEXT ENDS>
- ASSUME CS:_TEXT,DS:_TEXT
-
- PUSHREGS equ <pushad>
- POPREGS equ <popad>
-
- PUBPROC macro name
- align 4
- public @&name
- @&name label near
- endm
-else
- .286
- _TEXT SEGMENT PUBLIC DWORD 'CODE'
- _TEXT ENDS
- _DATA SEGMENT PUBLIC DWORD 'DATA'
- _DATA ENDS
- CB_DSEG EQU <SEG _DATA> ; 16bit is small/large model
- D_SEG EQU <_DATA SEGMENT>
- D_END EQU <_DATA ENDS>
- ASSUME CS:_TEXT,DS:_DATA
-
- PUSHREGS equ <pusha>
- POPREGS equ <popa>
-
- PUBPROC macro name
- public _&name
- _&name label far
- endm
-endif
-
-;-------------------------------------------
-
-D_SEG
-
-D_END
-
-
-_TEXT SEGMENT
-
-EXTRN _NdisSystemRequest : near
-EXTRN _NdisRequestConfirm : near
-EXTRN _NdisTransmitConfirm : near
-EXTRN _NdisReceiveLookahead : near
-EXTRN _NdisIndicationComplete : near
-EXTRN _NdisReceiveChain : near
-EXTRN _NdisStatusProc : near
-EXTRN _NdisAllocStack : near
-EXTRN _NdisFreeStack : near
-
-;
-; *ALL* interrupt threads come through this macro.
-;
-CALLBACK macro callbackProc, argsSize
-
- pushf
- PUSHREGS ;; Save the registers
-
- push es
- push ds
- mov ax,CB_DSEG ;; Load DS
- mov ds,ax
- call _NdisAllocStack ;; Get and install a stack.
-
- mov bx,ss ;; Save off the old stack in other regs
- mov cx,sp
- mov ss,dx ;; Install the new one
- mov sp,ax
- push bx ;; Save the old one on to the new stack
- push cx
- sub sp,&argsSize ;; Allocate space for arguments on the stack
-
- mov ax,ss ;; Set up the destination for the move
- mov es,ax
- mov di,sp
- mov ds,bx ;; Set up the source for the move.
- mov si,cx
- add si,4+6+32
-
- mov cx,&argsSize ;; Move the arguments to the stack.
- shr cx,1
- cld
- rep movsw
-
- mov ax,CB_DSEG ;; Set my data segment again.
- mov ds,ax
-
- call &callbackProc ;; Call the real callback.
- pop di ;; Pop off the old stack
- pop si
- mov bx,ss ;; Save off the current allocated stack.
- mov cx,sp
- mov ss,si ;; Restore the old stack
- mov sp,di
- push ax ;; Save the return code
- push bx ;; Free the stack. Push the pointer to it
- push cx
- call _NdisFreeStack
- add sp,4
- pop ax ;; Get the return code back
- add di,32 ;; Get a pointer to ax on the stack
- mov word ptr ss:[di],ax
- pop ds
- pop es
-
- POPREGS
- popf
-endm
-
-;
-; Define all of the callbacks for the NDIS procs.
-;
-
-PUBPROC systemRequestGlue
-CALLBACK _NdisSystemRequest,14
-RETF
-
-PUBPROC requestConfirmGlue
-CALLBACK _NdisRequestConfirm,12
-RETF
-
-PUBPROC transmitConfirmGlue
-CALLBACK _NdisTransmitConfirm,10
-RETF
-
-PUBPROC receiveLookaheadGlue
-CALLBACK _NdisReceiveLookahead,16
-RETF
-
-PUBPROC indicationCompleteGlue
-CALLBACK _NdisIndicationComplete,4
-RETF
-
-PUBPROC receiveChainGlue
-CALLBACK _NdisReceiveChain,16
-RETF
-
-PUBPROC statusGlue
-CALLBACK _NdisStatusProc,12
-RETF
-
-;
-; int FAR NdisGetLinkage (int handle, char *data, int size);
-;
-
-ifdef DOSX
- PUBPROC NdisGetLinkage
- push ebx
- mov ebx, [esp+8] ; device handle
- mov eax, 4402h ; IOCTRL read function
- mov edx, [esp+12] ; DS:EDX -> result data
- mov ecx, [esp+16] ; ECX = length
- int 21h
- pop ebx
- jc @fail
- xor eax, eax
- @fail: ret
-
-else
- PUBPROC NdisGetLinkage
- enter 0, 0
- mov bx, [bp+6]
- mov ax, 4402h
- mov dx, [bp+8]
- mov cx, [bp+12]
- int 21h
- jc @fail
- xor ax, ax
- @fail: leave
- retf
-endif
-
-ENDS
-
-END
diff --git a/msdos/readme.dos b/msdos/readme.dos
index 990a2e8a..b95483fc 100644
--- a/msdos/readme.dos
+++ b/msdos/readme.dos
@@ -127,7 +127,7 @@ Follow these steps in building libpcap:
But linking the library with `tcpdump' is the ultimate test. DOS/djgpp
should now hopefully be a supported target. Get the sources at:
- http://www.tcpdump.org/
+ https://www.tcpdump.org/
or
https://github.com/the-tcpdump-group/tcpdump/
diff --git a/nametoaddr.c b/nametoaddr.c
index 71280b31..194ff45b 100644
--- a/nametoaddr.c
+++ b/nametoaddr.c
@@ -23,7 +23,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#ifdef DECNETLIB
@@ -32,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>
@@ -111,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)
@@ -141,7 +177,6 @@ pcap_nametoaddr(const char *name)
return 0;
}
-#ifdef INET6
struct addrinfo *
pcap_nametoaddrinfo(const char *name)
{
@@ -158,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.
*
@@ -188,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 */
}
/*
@@ -199,20 +287,113 @@ 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 &&
+ error != EAI_SERVICE) {
+ /*
+ * 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 &&
+ error != EAI_SERVICE) {
+ /*
+ * 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;
@@ -291,12 +472,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
@@ -316,7 +547,12 @@ 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[] = {
{ "pup", ETHERTYPE_PUP },
{ "xns", ETHERTYPE_NS },
@@ -380,17 +616,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
@@ -401,7 +636,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';
@@ -449,7 +684,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)
@@ -470,7 +705,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)
{
@@ -502,17 +741,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)
{
@@ -529,10 +761,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;
@@ -543,6 +778,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/net b/net
deleted file mode 120000
index b3eaca95..00000000
--- a/net
+++ /dev/null
@@ -1 +0,0 @@
-./bpf/net \ No newline at end of file
diff --git a/nomkdep b/nomkdep
new file mode 100755
index 00000000..bed73668
--- /dev/null
+++ b/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/optimize.c b/optimize.c
index 19980dc8..7c6424b0 100644
--- a/optimize.c
+++ b/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));
@@ -563,7 +661,7 @@ F(opt_state_t *opt_state, int code, int v0, int v1)
int val;
struct valnode *p;
- hash = (u_int)code ^ (v0 << 4) ^ (v1 << 8);
+ hash = (u_int)code ^ ((u_int)v0 << 4) ^ ((u_int)v1 << 8);
hash %= MODULUS;
for (p = opt_state->hashtbl[hash]; p; p = p->next)
@@ -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/optimize.h b/optimize.h
new file mode 100644
index 00000000..56b31f40
--- /dev/null
+++ b/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/pcap-bpf.c b/pcap-bpf.c
index b765904d..6ce383b0 100644
--- a/pcap-bpf.c
+++ b/pcap-bpf.c
@@ -20,20 +20,17 @@
*/
#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.
@@ -57,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
@@ -82,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>
@@ -121,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
@@ -224,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
@@ -252,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;
@@ -260,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;
@@ -274,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
@@ -365,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));
@@ -393,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);
}
}
@@ -412,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));
@@ -455,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);
}
@@ -473,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
/*
@@ -491,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
@@ -561,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:
@@ -571,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);
}
@@ -629,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);
}
@@ -653,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);
}
@@ -714,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);
}
}
@@ -735,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.
*
@@ -781,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));
@@ -836,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);
}
@@ -900,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);
}
@@ -1028,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;
@@ -1182,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
@@ -1197,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);
}
@@ -1215,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);
@@ -1304,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);
}
@@ -1314,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);
}
@@ -1327,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);
}
}
@@ -1349,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);
}
}
@@ -1369,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);
}
}
@@ -1535,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
@@ -1559,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);
}
@@ -1569,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) {
/*
@@ -1586,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);
}
}
@@ -1659,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;
}
@@ -1672,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;
}
@@ -1704,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;
}
@@ -1724,8 +1743,8 @@ 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;
}
@@ -1779,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);
@@ -1793,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;
}
@@ -1844,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;
}
@@ -1877,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;
@@ -1922,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;
}
@@ -1949,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;
}
@@ -1959,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;
}
@@ -1985,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;
}
@@ -2054,8 +2073,8 @@ pcap_activate_bpf(pcap_t *p)
/* 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;
}
@@ -2299,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;
}
@@ -2341,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;
}
@@ -2351,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;
}
@@ -2386,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;
}
@@ -2408,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;
}
}
@@ -2417,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;
}
@@ -2436,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;
}
@@ -2467,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;
}
@@ -2550,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) {
/*
@@ -2584,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;
@@ -2624,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) {
@@ -2640,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);
@@ -2653,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
@@ -2684,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);
}
@@ -2716,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);
}
@@ -2736,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);
@@ -2804,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);
}
@@ -3029,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);
}
@@ -3058,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);
@@ -3080,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);
@@ -3099,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/pcap-bt-linux.c b/pcap-bt-linux.c
index 4452fe44..07ed1c73 100644
--- a/pcap-bt-linux.c
+++ b/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/pcap-bt-linux.h b/pcap-bt-linux.h
index e098654d..163bd341 100644
--- a/pcap-bt-linux.h
+++ b/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/pcap-bt-monitor-linux.c b/pcap-bt-monitor-linux.c
index 521d6d50..c222c100 100644
--- a/pcap-bt-monitor-linux.c
+++ b/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/pcap-bt-monitor-linux.h b/pcap-bt-monitor-linux.h
index aada2bc7..8133710a 100644
--- a/pcap-bt-monitor-linux.h
+++ b/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/pcap-common.c b/pcap-common.c
index 84368f6c..b379d8fd 100644
--- a/pcap-common.c
+++ b/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,76 @@
*/
#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 */
+
+/*
+ * The DLT_ and LINKTYPE_ values in the "matching" range should be the
+ * same, so DLT_MATCHING_MAX and LINKTYPE_MATCHING_MAX should be the
+ * same.
+ */
+#if LINKTYPE_MATCHING_MAX != DLT_MATCHING_MAX
+#error The LINKTYPE_ matching range does not match the DLT_ matching range
+#endif
static struct linktype_map {
int dlt;
@@ -1175,7 +1237,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 +1269,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 +1415,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 +1461,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/pcap-common.h b/pcap-common.h
index 6ac5bcd2..8795a829 100644
--- a/pcap-common.h
+++ b/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,
@@ -13,9 +35,13 @@
* machine (if the file was written in little-end order).
*/
#define SWAPLONG(y) \
-((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
+ (((((u_int)(y))&0xff)<<24) | \
+ ((((u_int)(y))&0xff00)<<8) | \
+ ((((u_int)(y))&0xff0000)>>8) | \
+ ((((u_int)(y))>>24)&0xff))
#define SWAPSHORT(y) \
- ( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) )
+ ((u_short)(((((u_int)(y))&0xff)<<8) | \
+ ((((u_int)(y))&0xff00)>>8)))
extern int dlt_to_linktype(int dlt);
@@ -23,3 +49,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/pcap-config b/pcap-config
deleted file mode 100755
index ec97bd71..00000000
--- a/pcap-config
+++ /dev/null
@@ -1,89 +0,0 @@
-#! /bin/sh
-
-#
-# Script to give the appropriate compiler flags and linker flags
-# to use when building code that uses libpcap.
-#
-prefix="/usr/local"
-exec_prefix="${prefix}"
-includedir="${prefix}/include"
-libdir="${exec_prefix}/lib"
-V_RPATH_OPT="-Wl,-rpath,"
-LIBS=""
-
-static=0
-show_cflags=0
-show_libs=0
-while [ "$#" != 0 ]
-do
- case "$1" in
-
- --static)
- static=1
- ;;
-
- --cflags)
- show_cflags=1
- ;;
-
- --libs)
- show_libs=1
- ;;
-
- --additional-libs)
- show_additional_libs=1
- ;;
- esac
- shift
-done
-if [ "$V_RPATH_OPT" != "" ]
-then
- #
- # If libdir isn't /usr/lib, add it to the run-time linker path.
- #
- if [ "$libdir" != "/usr/lib" ]
- then
- RPATH=$V_RPATH_OPT$libdir
- fi
-fi
-if [ "$static" = 1 ]
-then
- #
- # Include LIBS so that the flags include libraries containing
- # routines that libpcap uses.
- #
- if [ "$show_cflags" = 1 -a "$show_libs" = 1 ]
- then
- echo "-I$includedir -L$libdir -lpcap $LIBS"
- elif [ "$show_cflags" = 1 -a "$show_additional_libs" = 1 ]
- then
- echo "-I$includedir -L$libdir $LIBS"
- elif [ "$show_cflags" = 1 ]
- then
- echo "-I$includedir"
- elif [ "$show_libs" = 1 ]
- then
- echo "-L$libdir -lpcap $LIBS"
- elif [ "$show_additional_libs" = 1 ]
- then
- echo "$LIBS"
- fi
-else
- #
- # Omit LIBS - libpcap is assumed to be linked with those
- # libraries, so there's no need to do so explicitly.
- #
- if [ "$show_cflags" = 1 -a "$show_libs" = 1 ]
- then
- echo "-I$includedir -L$libdir $RPATH -lpcap"
- elif [ "$show_cflags" = 1 -a "$show_additional_libs" = 1 ]
- then
- echo "-I$includedir"
- elif [ "$show_cflags" = 1 ]
- then
- echo "-I$includedir"
- elif [ "$show_libs" = 1 ]
- then
- echo "-L$libdir $RPATH -lpcap"
- fi
-fi
diff --git a/pcap-config.in b/pcap-config.in
index 206be3b4..54ca42f0 100644
--- a/pcap-config.in
+++ b/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/pcap-dag.c b/pcap-dag.c
index 201696cc..6b7c7919 100644
--- a/pcap-dag.c
+++ b/pcap-dag.c
@@ -1,5 +1,5 @@
/*
- * pcap-dag.c: Packet capture interface for Emulex EndaceDAG cards.
+ * pcap-dag.c: Packet capture interface for Endace DAG cards.
*
* The functionality of this code attempts to mimic that of pcap-linux as much
* as possible. This code is compiled in several different ways depending on
@@ -12,11 +12,11 @@
* Authors: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com)
* Modifications: Jesper Peterson
* Koryn Grant
- * Stephen Donnelly <stephen.donnelly@emulex.com>
+ * Stephen Donnelly <stephen.donnelly@endace.com>
*/
#ifdef HAVE_CONFIG_H
-#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/pcap-dag.h b/pcap-dag.h
index dfeccd8b..67361af9 100644
--- a/pcap-dag.h
+++ b/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/pcap-dbus.c b/pcap-dbus.c
index 8e92093d..1252975e 100644
--- a/pcap-dbus.c
+++ b/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/pcap-dbus.h b/pcap-dbus.h
index 67493cce..c97f2e12 100644
--- a/pcap-dbus.h
+++ b/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/pcap-dll.rc b/pcap-dll.rc
new file mode 100644
index 00000000..fc4f42b2
--- /dev/null
+++ b/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/pcap-dlpi.c b/pcap-dlpi.c
index a431e7c1..430051e8 100644
--- a/pcap-dlpi.c
+++ b/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/pcap-dos.c b/pcap-dos.c
index ea6b225a..b1b9ecd7 100644
--- a/pcap-dos.c
+++ b/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/pcap-enet.c b/pcap-enet.c
index 777d3e3a..cd8cdbbb 100644
--- a/pcap-enet.c
+++ b/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/pcap-filter.manmisc b/pcap-filter.manmisc
index b9bf3878..35486914 100644
--- a/pcap-filter.manmisc
+++ b/pcap-filter.manmisc
@@ -18,7 +18,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP-FILTER 7 "3 August 2015"
+.TH PCAP-FILTER 7 "5 November 2017"
.SH NAME
pcap-filter \- packet filter syntax
.br
@@ -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"
@@ -566,7 +567,7 @@ are:
and
.B block
and, with later versions of
-.BR pf (4)),
+.BR pf (4),
.BR nat ,
.BR rdr ,
.B binat
@@ -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,9 +875,24 @@ 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-ack\fP, \fBtcp-urg\fP, \fBtcp-ece\fP,
+\fBtcp-cwr\fP.
.LP
Primitives may be combined using:
.IP
@@ -1010,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/pcap-filter.manmisc.in b/pcap-filter.manmisc.in
index 9d3f34bf..3232f7e9 100644
--- a/pcap-filter.manmisc.in
+++ b/pcap-filter.manmisc.in
@@ -18,7 +18,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP-FILTER @MAN_MISC_INFO@ "3 August 2015"
+.TH PCAP-FILTER @MAN_MISC_INFO@ "5 November 2017"
.SH NAME
pcap-filter \- packet filter syntax
.br
@@ -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"
@@ -566,7 +567,7 @@ are:
and
.B block
and, with later versions of
-.BR pf (4)),
+.BR pf (4),
.BR nat ,
.BR rdr ,
.B binat
@@ -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,9 +875,24 @@ 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-ack\fP, \fBtcp-urg\fP, \fBtcp-ece\fP,
+\fBtcp-cwr\fP.
.LP
Primitives may be combined using:
.IP
@@ -1010,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/pcap-int.h b/pcap-int.h
index 7db7ff5e..5888df72 100644
--- a/pcap-int.h
+++ b/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/pcap-libdlpi.c b/pcap-libdlpi.c
index 625f1e0a..a0d16693 100644
--- a/pcap-libdlpi.c
+++ b/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/pcap-linktype.manmisc b/pcap-linktype.manmisc
index e6805676..20f2ea2b 100644
--- a/pcap-linktype.manmisc
+++ b/pcap-linktype.manmisc
@@ -43,6 +43,6 @@ The names for those values begin with
.BR LINKTYPE_ .
.PP
The link-layer header types supported by libpcap are described at
-http://www.tcpdump.org/linktypes.html.
+https://www.tcpdump.org/linktypes.html.
.SH SEE ALSO
pcap_datalink(3PCAP)
diff --git a/pcap-linktype.manmisc.in b/pcap-linktype.manmisc.in
index 7634a962..68919a78 100644
--- a/pcap-linktype.manmisc.in
+++ b/pcap-linktype.manmisc.in
@@ -43,6 +43,6 @@ The names for those values begin with
.BR LINKTYPE_ .
.PP
The link-layer header types supported by libpcap are described at
-http://www.tcpdump.org/linktypes.html.
+https://www.tcpdump.org/linktypes.html.
.SH SEE ALSO
pcap_datalink(3PCAP)
diff --git a/pcap-linux.c b/pcap-linux.c
index 924df42a..49144b64 100644
--- a/pcap-linux.c
+++ b/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_linux(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/pcap-netfilter-linux.c b/pcap-netfilter-linux.c
index bde648f3..d5c5dcdc 100644
--- a/pcap-netfilter-linux.c
+++ b/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/pcap-netfilter-linux.h b/pcap-netfilter-linux.h
index 01d9b394..97b73108 100644
--- a/pcap-netfilter-linux.h
+++ b/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/pcap-netmap.c b/pcap-netmap.c
new file mode 100644
index 00000000..f1505633
--- /dev/null
+++ b/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/pcap-netmap.h b/pcap-netmap.h
new file mode 100644
index 00000000..6a414fca
--- /dev/null
+++ b/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/pcap-new.c b/pcap-new.c
index 494e425f..6fa52e6e 100644
--- a/pcap-new.c
+++ b/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/pcap-nit.c b/pcap-nit.c
index 1b626e21..6a1a77c2 100644
--- a/pcap-nit.c
+++ b/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/pcap-win32.c b/pcap-npf.c
index d998637e..a9ff0ff4 100644
--- a/pcap-win32.c
+++ b/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
+ * reliable 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/pcap-null.c b/pcap-null.c
index b5fa3ab9..92a5e2d8 100644
--- a/pcap-null.c
+++ b/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/pcap-pf.c b/pcap-pf.c
index 73469086..fde97bac 100644
--- a/pcap-pf.c
+++ b/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/pcap-rdmasniff.c b/pcap-rdmasniff.c
new file mode 100644
index 00000000..c50fe3fd
--- /dev/null
+++ b/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/pcap-rdmasniff.h b/pcap-rdmasniff.h
new file mode 100644
index 00000000..ff1f3c20
--- /dev/null
+++ b/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/pcap-rpcap-int.h b/pcap-rpcap-int.h
new file mode 100644
index 00000000..e707a85f
--- /dev/null
+++ b/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/pcap-rpcap.c b/pcap-rpcap.c
index b954058d..e9d6245b 100644
--- a/pcap-rpcap.c
+++ b/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,237 @@ 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_nodiscard;
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);
+error_nodiscard:
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 +1033,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 +1045,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 +1067,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 +1079,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 +1087,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 +1097,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 +1117,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 +1125,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 +1135,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 +1155,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 +1164,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 +1175,22 @@ int pcap_startcapture_remote(pcap_t *fp)
/* Pack the capture filter */
if (pcap_pack_bpffilter(fp, &sendbuf[sendbufidx], &sendbufidx, &fp->fcode))
- goto error;
-
- if (sock_send(md->rmt_sockctrl, sendbuf, sendbufidx, fp->errbuf, PCAP_ERRBUF_SIZE))
- goto error;
+ goto error_nodiscard;
+ if (sock_send(pr->rmt_sockctrl, sendbuf, sendbufidx, fp->errbuf,
+ PCAP_ERRBUF_SIZE) < 0)
+ 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;
+ /* 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;
- /* 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;
+ plen = header.plen;
- 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 +1203,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 +1232,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 +1245,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 +1261,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_nodiscard;
/*
* In case the user does not want to capture RPCAP packets, let's update the filter
@@ -1247,22 +1343,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 +1367,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 +1433,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 +1471,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 +1587,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 +1598,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 +1615,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 +1632,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 +1647,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 +1660,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 +1668,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 +1679,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 +1699,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 +1783,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);
-
- if (length > PCAP_ERRBUF_SIZE)
- length = PCAP_ERRBUF_SIZE;
-
- rpcap_createhdr((struct rpcap_header *) sendbuf, RPCAP_MSG_ERROR, errcode, length);
+ int status;
- 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 +1908,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 +1948,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 +1963,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 +1973,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 +1985,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)
+ {
+ pcap_close(fp);
+ return NULL;
+ }
+ }
+ else
+ {
+ if (sock_initaddress(host, ctrlport, &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;
+ }
+ }
+
+ 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;
- sock_discard(sock, len - (PCAP_ERRBUF_SIZE - 1), NULL, 0);
+ /* 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;
- /* Put '\0' at the end of the string */
- errbuf[PCAP_ERRBUF_SIZE - 1] = 0;
+ /* 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;
+ }
+
+ /* addrinfo is no longer used */
+ freeaddrinfo(addrinfo);
+ addrinfo = NULL;
+
+ if (rpcap_doauth(sockctrl, &protocol_version, auth, errbuf) == -1)
+ {
+ sock_close(sockctrl, NULL, 0);
+ return -1;
+ }
+ active = 0;
+ }
+
+ /* RPCAP findalldevs command */
+ rpcap_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;
- va_end(ap);
- return header->type;
+ 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_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)
+ goto error_nodiscard;
+
+ /* 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;
+
+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();
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The other endpoint sent a message that is not allowed here.");
- SOCK_ASSERT(errbuf, 1);
+ /* Free whatever interfaces we've allocated. */
+ pcap_freealldevs(*alldevs);
- va_end(ap);
- return -2;
+ 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;
+ }
+
+ /* Checks that this host does not already have a cntrl connection in place */
- if (header->ver != RPCAP_VERSION)
+ /* 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 +2861,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/pcap-rpcap.h b/pcap-rpcap.h
index f84e8ba5..be31c40d 100644
--- a/pcap-rpcap.h
+++ b/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/pcap-septel.c b/pcap-septel.c
index 88dc89df..0471153f 100644
--- a/pcap-septel.c
+++ b/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/pcap-septel.h b/pcap-septel.h
index b6e1168b..0e648b20 100644
--- a/pcap-septel.h
+++ b/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/pcap-sita.c b/pcap-sita.c
index 1cd5f751..7c42791a 100644
--- a/pcap-sita.c
+++ b/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/pcap-snf.c b/pcap-snf.c
index 207c4959..4eae0b39 100644
--- a/pcap-snf.c
+++ b/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/pcap-snf.h b/pcap-snf.h
index c9d7722b..ffc64adf 100644
--- a/pcap-snf.h
+++ b/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/pcap-snit.c b/pcap-snit.c
index 79349456..9c6fbd48 100644
--- a/pcap-snit.c
+++ b/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/pcap-snoop.c b/pcap-snoop.c
index 687b1d90..a598bae5 100644
--- a/pcap-snoop.c
+++ b/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;
@@ -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/pcap-stdinc.h b/pcap-stdinc.h
deleted file mode 100644
index a1be6809..00000000
--- a/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/pcap-tc.c b/pcap-tc.c
index 768dbd7c..38c70245 100644
--- a/pcap-tc.c
+++ b/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/pcap-tc.h b/pcap-tc.h
index 59ddec26..f7b2d12d 100644
--- a/pcap-tc.h
+++ b/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/pcap-tstamp.manmisc b/pcap-tstamp.manmisc
index 7d078fb4..c8b7fed3 100644
--- a/pcap-tstamp.manmisc
+++ b/pcap-tstamp.manmisc
@@ -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/pcap-tstamp.manmisc.in b/pcap-tstamp.manmisc.in
index 2e1ef61d..38c56518 100644
--- a/pcap-tstamp.manmisc.in
+++ b/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/pcap-types.h b/pcap-types.h
new file mode 100644
index 00000000..9614f9f1
--- /dev/null
+++ b/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/pcap-usb-linux.c b/pcap-usb-linux.c
index fb1188a7..6f8adf65 100644
--- a/pcap-usb-linux.c
+++ b/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/pcap-usb-linux.h b/pcap-usb-linux.h
index 234a262f..3ddc12f4 100644
--- a/pcap-usb-linux.h
+++ b/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/pcap.3pcap b/pcap.3pcap
index 9f408a0d..c6b8891f 100644
--- a/pcap.3pcap
+++ b/pcap.3pcap
@@ -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 April 2018"
.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 (8)
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,
@@ -303,7 +304,7 @@ link-layer header whose contents can differ for different network
interfaces. To determine the format of the packets supplied by the
handle, call
.BR pcap_datalink ();
-.I http://www.tcpdump.org/linktypes.html
+.I https://www.tcpdump.org/linktypes.html
lists the values it returns and describes the packet formats that
correspond to those values.
.PP
@@ -395,6 +396,11 @@ set promiscuous mode for a not-yet-activated
.B pcap_t
for live capture
.TP
+.BR pcap_set_protocol_linux (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(7), pfconfig(8),
-usermod(1M)
+usermod(8)
.SH AUTHORS
The original authors of libpcap are:
.LP
@@ -927,11 +934,12 @@ Lawrence Berkeley National Laboratory, University of California, Berkeley, CA.
The current version is available from "The Tcpdump Group"'s Web site at
.LP
.RS
-.I http://www.tcpdump.org/
+.I https://www.tcpdump.org/
.RE
.SH BUGS
-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/pcap.3pcap.in b/pcap.3pcap.in
index 93478f1c..4a222c7b 100644
--- a/pcap.3pcap.in
+++ b/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 April 2018"
.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,
@@ -303,7 +304,7 @@ link-layer header whose contents can differ for different network
interfaces. To determine the format of the packets supplied by the
handle, call
.BR pcap_datalink ();
-.I http://www.tcpdump.org/linktypes.html
+.I https://www.tcpdump.org/linktypes.html
lists the values it returns and describes the packet formats that
correspond to those values.
.PP
@@ -395,6 +396,11 @@ set promiscuous mode for a not-yet-activated
.B pcap_t
for live capture
.TP
+.BR pcap_set_protocol_linux (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
@@ -927,11 +934,12 @@ Lawrence Berkeley National Laboratory, University of California, Berkeley, CA.
The current version is available from "The Tcpdump Group"'s Web site at
.LP
.RS
-.I http://www.tcpdump.org/
+.I https://www.tcpdump.org/
.RE
.SH BUGS
-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/pcap.c b/pcap.c
index 77a709f8..942c472a 100644
--- a/pcap.c
+++ b/pcap.c
@@ -32,23 +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>
+
+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>
@@ -57,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"
@@ -68,6 +78,8 @@
#include "pcap-int.h"
+#include "optimize.h"
+
#ifdef HAVE_DAG_API
#include "pcap-dag.h"
#endif /* HAVE_DAG_API */
@@ -100,13 +112,89 @@
#include "pcap-netfilter-linux.h"
#endif
+#ifdef PCAP_SUPPORT_NETMAP
+#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");
@@ -118,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);
@@ -126,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);
@@ -134,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);
@@ -142,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);
@@ -190,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,
@@ -295,8 +407,15 @@ 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 HAVE_DAG_API
@@ -323,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 }
};
@@ -339,34 +464,1502 @@ 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)
@@ -400,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);
}
@@ -412,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);
}
@@ -463,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)
{
@@ -477,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;
@@ -519,24 +2124,38 @@ pcap_alloc_pcap_t(char *ebuf, size_t size)
* plus a structure following it of size "size". The
* structure following it is a private data structure
* for the routines that handle this pcap_t.
+ *
+ * The structure following it must be aligned on
+ * the appropriate alignment boundary for this platform.
+ * We align on an 8-byte boundary as that's probably what
+ * at least some platforms do, even with 32-bit integers,
+ * and because we can't be sure that some values won't
+ * require 8-byte alignment even on platforms with 32-bit
+ * integers.
*/
- chunk = malloc(sizeof (pcap_t) + size);
+#define PCAP_T_ALIGNED_SIZE ((sizeof(pcap_t) + 7) & ~0x7)
+ chunk = malloc(PCAP_T_ALIGNED_SIZE + 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);
+ memset(chunk, 0, PCAP_T_ALIGNED_SIZE + size);
/*
* Get a pointer to the pcap_t at the beginning.
*/
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. */
@@ -546,7 +2165,7 @@ pcap_alloc_pcap_t(char *ebuf, size_t size)
* Set the pointer to the private data; that's the structure
* of size "size" following the pcap_t.
*/
- p->priv = (void *)(chunk + sizeof (pcap_t));
+ p->priv = (void *)(chunk + PCAP_T_ALIGNED_SIZE);
}
return (p);
@@ -569,10 +2188,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;
@@ -580,6 +2206,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.
@@ -605,16 +2240,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);
}
@@ -785,9 +2410,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;
@@ -813,6 +2454,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)
@@ -946,8 +2634,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;
@@ -955,8 +2643,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,
@@ -1271,6 +2959,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
};
@@ -1393,6 +3090,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)
{
@@ -1405,8 +3110,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
@@ -1418,6 +3123,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
@@ -1437,14 +3148,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);
}
@@ -1455,14 +3170,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)
@@ -1477,14 +3192,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);
}
@@ -1497,14 +3216,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)
@@ -1512,8 +3231,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);
@@ -1532,7 +3251,7 @@ pcap_win32_err_to_str(DWORD error, char *errbuf)
size_t errlen;
char *p;
- FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
+ FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
PCAP_ERRBUF_SIZE, NULL);
/*
@@ -1617,9 +3336,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
@@ -1666,14 +3385,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)
@@ -1687,86 +3398,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)
{
@@ -1822,56 +3483,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)
{
@@ -1884,12 +3513,6 @@ pcap_get_airpcap_handle(pcap_t *p)
}
return (handle);
}
-
-static PAirpcapHandle
-pcap_get_airpcap_handle_dead(pcap_t *p)
-{
- return (NULL);
-}
#endif
/*
@@ -2012,66 +3635,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.
@@ -2123,160 +3686,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
/*
@@ -2296,32 +3950,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/pcap/bluetooth.h b/pcap/bluetooth.h
index c5f378ab..15dc5a82 100644
--- a/pcap/bluetooth.h
+++ b/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/pcap/bpf.h b/pcap/bpf.h
index 78ad8905..1a953a9b 100644
--- a/pcap/bpf.h
+++ b/pcap/bpf.h
@@ -15,11 +15,7 @@
* 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 University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
*
@@ -72,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" {
@@ -258,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/pcap/can_socketcan.h b/pcap/can_socketcan.h
index 68d2a131..332d9ff5 100644
--- a/pcap/can_socketcan.h
+++ b/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/pcap/compiler-tests.h b/pcap/compiler-tests.h
new file mode 100644
index 00000000..5e17853a
--- /dev/null
+++ b/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/pcap/dlt.h b/pcap/dlt.h
index 2d74713e..535fd50a 100644
--- a/pcap/dlt.h
+++ b/pcap/dlt.h
@@ -15,11 +15,7 @@
* 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 University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
*
@@ -54,7 +50,7 @@
*
* See
*
- * http://www.tcpdump.org/linktypes.html
+ * https://www.tcpdump.org/linktypes.html
*
* for detailed descriptions of some of these link-layer header types.
*/
@@ -124,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
@@ -344,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;
@@ -744,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
@@ -950,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.
@@ -1233,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
@@ -1245,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.
*
@@ -1307,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
@@ -1316,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/pcap/export-defs.h b/pcap/export-defs.h
deleted file mode 100644
index a2350579..00000000
--- a/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/pcap/funcattrs.h b/pcap/funcattrs.h
new file mode 100644
index 00000000..a8b1932f
--- /dev/null
+++ b/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/pcap/namedb.h b/pcap/namedb.h
index 73fb40a4..c66846d3 100644
--- a/pcap/namedb.h
+++ b/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/pcap/nflog.h b/pcap/nflog.h
index a3867cdd..f7c85b54 100644
--- a/pcap/nflog.h
+++ b/pcap/nflog.h
@@ -28,9 +28,11 @@
#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
+ * https://www.tcpdump.org/linktypes/LINKTYPE_NFLOG.html
*
* The NFLOG header is big-endian.
*
@@ -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/pcap/pcap-inttypes.h b/pcap/pcap-inttypes.h
new file mode 100644
index 00000000..af2c23c8
--- /dev/null
+++ b/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/pcap/pcap.h b/pcap/pcap.h
index 7f92a379..bc87b3f3 100644
--- a/pcap/pcap.h
+++ b/pcap/pcap.h
@@ -32,18 +32,55 @@
* 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 */
@@ -172,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
@@ -223,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.
@@ -275,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 *);
@@ -297,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_linux(pcap_t *, int);
+#endif
+
/*
* Time stamp types.
* Not all systems and interfaces will necessarily support all of these.
@@ -360,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) \
@@ -409,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 *);
@@ -423,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 *);
@@ -430,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);
/*
@@ -457,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. */
@@ -523,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/pcap/sll.h b/pcap/sll.h
index b46d15f2..c4d08862 100644
--- a/pcap/sll.h
+++ b/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/pcap/usb.h b/pcap/usb.h
index 26a9046b..e485ec85 100644
--- a/pcap/usb.h
+++ b/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/pcap/vlan.h b/pcap/vlan.h
index 021f6129..b29dd73c 100644
--- a/pcap/vlan.h
+++ b/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/pcap_activate.3pcap b/pcap_activate.3pcap
index 8c89939f..ceb2aa74 100644
--- a/pcap_activate.3pcap
+++ b/pcap_activate.3pcap
@@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_ACTIVATE 3PCAP "7 April 2014"
+.TH PCAP_ACTIVATE 3PCAP "31 July 2016"
.SH NAME
pcap_activate \- activate a capture handle
.SH SYNOPSIS
diff --git a/pcap_breakloop.3pcap b/pcap_breakloop.3pcap
index 3f9327b1..03b8d8d1 100644
--- a/pcap_breakloop.3pcap
+++ b/pcap_breakloop.3pcap
@@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_BREAKLOOP 3PCAP "8 March 2015"
+.TH PCAP_BREAKLOOP 3PCAP "8 November 2017"
.SH NAME
pcap_breakloop \- force a pcap_dispatch() or pcap_loop() call to return
.SH SYNOPSIS
@@ -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/pcap_can_set_rfmon.3pcap b/pcap_can_set_rfmon.3pcap
index 389e50dd..eee004dd 100644
--- a/pcap_can_set_rfmon.3pcap
+++ b/pcap_can_set_rfmon.3pcap
@@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_CAN_SET_RFMON 3PCAP "3 January 2014"
+.TH PCAP_CAN_SET_RFMON 3PCAP "31 July 2016"
.SH NAME
pcap_can_set_rfmon \- check whether monitor mode can be set for a
not-yet-activated capture handle
diff --git a/pcap_compile.3pcap b/pcap_compile.3pcap
index 6eb20bef..181814b1 100644
--- a/pcap_compile.3pcap
+++ b/pcap_compile.3pcap
@@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_COMPILE 3PCAP "7 April 2014"
+.TH PCAP_COMPILE 3PCAP "24 March 2017"
.SH NAME
pcap_compile \- compile a filter expression
.SH SYNOPSIS
@@ -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/pcap_compile.3pcap.in b/pcap_compile.3pcap.in
index 2bd0eb46..29ae8f8a 100644
--- a/pcap_compile.3pcap.in
+++ b/pcap_compile.3pcap.in
@@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_COMPILE 3PCAP "7 April 2014"
+.TH PCAP_COMPILE 3PCAP "24 March 2017"
.SH NAME
pcap_compile \- compile a filter expression
.SH SYNOPSIS
@@ -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/pcap_datalink.3pcap b/pcap_datalink.3pcap
index 4cb10077..50508f81 100644
--- a/pcap_datalink.3pcap
+++ b/pcap_datalink.3pcap
@@ -41,7 +41,7 @@ It must not be called on a pcap descriptor created by
that has not yet been activated by
.BR pcap_activate() .
.PP
-.I http://www.tcpdump.org/linktypes.html
+.I https://www.tcpdump.org/linktypes.html
lists the values
.B pcap_datalink()
can return and describes the packet formats that
diff --git a/pcap_datalink.3pcap.in b/pcap_datalink.3pcap.in
index be50a649..a32f15ec 100644
--- a/pcap_datalink.3pcap.in
+++ b/pcap_datalink.3pcap.in
@@ -41,7 +41,7 @@ It must not be called on a pcap descriptor created by
that has not yet been activated by
.BR pcap_activate() .
.PP
-.I http://www.tcpdump.org/linktypes.html
+.I https://www.tcpdump.org/linktypes.html
lists the values
.B pcap_datalink()
can return and describes the packet formats that
diff --git a/pcap_datalink_name_to_val.3pcap b/pcap_datalink_name_to_val.3pcap
index 8a6905a2..e6419f25 100644
--- a/pcap_datalink_name_to_val.3pcap
+++ b/pcap_datalink_name_to_val.3pcap
@@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_DATALINK_NAME_TO_VAL 3PCAP "5 December 2014"
+.TH PCAP_DATALINK_NAME_TO_VAL 3PCAP "12 October 2016"
.SH NAME
pcap_datalink_name_to_val \- get the link-layer header type value
corresponding to a header type name
diff --git a/pcap_datalink_val_to_name.3pcap b/pcap_datalink_val_to_name.3pcap
index aa3e89a6..fad350fd 100644
--- a/pcap_datalink_val_to_name.3pcap
+++ b/pcap_datalink_val_to_name.3pcap
@@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_DATALINK_VAL_TO_NAME 3PCAP "3 January 2014"
+.TH PCAP_DATALINK_VAL_TO_NAME 3PCAP "12 October 2016"
.SH NAME
pcap_datalink_val_to_name, pcap_datalink_val_to_description \- get a
name or description for a link-layer header type value
diff --git a/pcap_dump_ftell.3pcap b/pcap_dump_ftell.3pcap
index 757e9482..ec621fb3 100644
--- a/pcap_dump_ftell.3pcap
+++ b/pcap_dump_ftell.3pcap
@@ -17,9 +17,9 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_DUMP_FTELL 3PCAP "3 January 2014"
+.TH PCAP_DUMP_FTELL 3PCAP "29 September 2017"
.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/pcap_dump_open.3pcap b/pcap_dump_open.3pcap
index fd96aab0..03956ba2 100644
--- a/pcap_dump_open.3pcap
+++ b/pcap_dump_open.3pcap
@@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_DUMP_OPEN 3PCAP "16 February 2015"
+.TH PCAP_DUMP_OPEN 3PCAP "22 June 2018"
.SH NAME
pcap_dump_open, pcap_dump_fopen \- open a file to which to write packets
.SH SYNOPSIS
@@ -48,7 +48,9 @@ for
.PP
.B pcap_dump_fopen()
is called to write data to an existing open stream
-.IR fp .
+.IR fp ;
+this stream will be closed by a subsequent call to
+.BR pcap_dump_close() .
Note that on Windows, that stream should be opened in binary mode.
.PP
.I p
@@ -91,6 +93,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(5)
+\%pcap-savefile(5)
diff --git a/pcap_dump_open.3pcap.in b/pcap_dump_open.3pcap.in
index 3f91d13b..5b37b47c 100644
--- a/pcap_dump_open.3pcap.in
+++ b/pcap_dump_open.3pcap.in
@@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_DUMP_OPEN 3PCAP "16 February 2015"
+.TH PCAP_DUMP_OPEN 3PCAP "22 June 2018"
.SH NAME
pcap_dump_open, pcap_dump_fopen \- open a file to which to write packets
.SH SYNOPSIS
@@ -48,7 +48,9 @@ for
.PP
.B pcap_dump_fopen()
is called to write data to an existing open stream
-.IR fp .
+.IR fp ;
+this stream will be closed by a subsequent call to
+.BR pcap_dump_close() .
Note that on Windows, that stream should be opened in binary mode.
.PP
.I p
@@ -91,6 +93,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/pcap_fileno.3pcap b/pcap_fileno.3pcap
index 7aeb0694..e8c9ac4d 100644
--- a/pcap_fileno.3pcap
+++ b/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/pcap_findalldevs.3pcap b/pcap_findalldevs.3pcap
index 2dd3e59b..14825ad1 100644
--- a/pcap_findalldevs.3pcap
+++ b/pcap_findalldevs.3pcap
@@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_FINDALLDEVS 3PCAP "7 April 2014"
+.TH PCAP_FINDALLDEVS 3PCAP "29 April 2018"
.SH NAME
pcap_findalldevs, pcap_freealldevs \- get a list of capture devices, and
free that list
@@ -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/pcap_get_required_select_timeout.3pcap b/pcap_get_required_select_timeout.3pcap
new file mode 100644
index 00000000..bc33e5d3
--- /dev/null
+++ b/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 "20 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/pcap_get_selectable_fd.3pcap b/pcap_get_selectable_fd.3pcap
index 86b0c268..f1ddfe2d 100644
--- a/pcap_get_selectable_fd.3pcap
+++ b/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 2018"
.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/pcap_geterr.3pcap b/pcap_geterr.3pcap
index 2e99c37d..ee681c8c 100644
--- a/pcap_geterr.3pcap
+++ b/pcap_geterr.3pcap
@@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_GETERR 3PCAP "3 January 2014"
+.TH PCAP_GETERR 3PCAP "15 January 2016"
.SH NAME
pcap_geterr, pcap_perror \- get or print libpcap error message text
.SH SYNOPSIS
diff --git a/pcap_is_swapped.3pcap b/pcap_is_swapped.3pcap
index c4e62ae5..36691d31 100644
--- a/pcap_is_swapped.3pcap
+++ b/pcap_is_swapped.3pcap
@@ -43,7 +43,7 @@ It must not be called on a pcap descriptor created by
that has not yet been activated by
.BR pcap_activate() .
.SH RETURN VALUE
-.B pcap_datalink()
+.B pcap_is_swapped()
returns true (1) or false (0) on success and
.B PCAP_ERROR_NOT_ACTIVATED
if called on a capture handle that has been created but not activated.
diff --git a/pcap_lookupdev.3pcap b/pcap_lookupdev.3pcap
index aaa3a201..eb493ba7 100644
--- a/pcap_lookupdev.3pcap
+++ b/pcap_lookupdev.3pcap
@@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_LOOKUPDEV 3PCAP "3 January 2014"
+.TH PCAP_LOOKUPDEV 3PCAP "8 September 2017"
.SH NAME
pcap_lookupdev \- find the default device on which to capture
.SH SYNOPSIS
@@ -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/pcap_loop.3pcap b/pcap_loop.3pcap
index 0eaf6e5e..4679b46e 100644
--- a/pcap_loop.3pcap
+++ b/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
@@ -130,7 +130,7 @@ value also passed to
.B pcap_loop()
or
.BR pcap_dispatch() .
-.I http://www.tcpdump.org/linktypes.html
+.I https://www.tcpdump.org/linktypes.html
lists the values
.B pcap_datalink()
can return and describes the packet formats that
@@ -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/pcap_major_version.3pcap b/pcap_major_version.3pcap
index 8334e16c..2fedfd2d 100644
--- a/pcap_major_version.3pcap
+++ b/pcap_major_version.3pcap
@@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_MAJOR_VERSION 3PCAP "7 April 2014"
+.TH PCAP_MAJOR_VERSION 3PCAP "8 January 2018"
.SH NAME
pcap_major_version, pcap_minor_version \- get the version number of a savefile
.SH SYNOPSIS
@@ -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/pcap_next_ex.3pcap b/pcap_next_ex.3pcap
index d69e7283..88e83143 100644
--- a/pcap_next_ex.3pcap
+++ b/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
@@ -85,7 +85,7 @@ value also passed to
.B pcap_loop()
or
.BR pcap_dispatch() .
-.I http://www.tcpdump.org/linktypes.html
+.I https://www.tcpdump.org/linktypes.html
lists the values
.B pcap_datalink()
can return and describes the packet formats that
@@ -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/pcap_open_dead.3pcap b/pcap_open_dead.3pcap
index 4a75c32b..118c5337 100644
--- a/pcap_open_dead.3pcap
+++ b/pcap_open_dead.3pcap
@@ -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(7)
+\%pcap-linktype(7)
diff --git a/pcap_open_dead.3pcap.in b/pcap_open_dead.3pcap.in
index a3dc5921..621e75b5 100644
--- a/pcap_open_dead.3pcap.in
+++ b/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/pcap_open_live.3pcap b/pcap_open_live.3pcap
index 8c5d4746..942d4fc3 100644
--- a/pcap_open_live.3pcap
+++ b/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 "6 December 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/pcap_open_offline.3pcap b/pcap_open_offline.3pcap
index 996572aa..3c59372f 100644
--- a/pcap_open_offline.3pcap
+++ b/pcap_open_offline.3pcap
@@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_OPEN_OFFLINE 3PCAP "3 January 2014"
+.TH PCAP_OPEN_OFFLINE 3PCAP "8 January 2018 "
.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
@@ -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/pcap_open_offline.3pcap.in b/pcap_open_offline.3pcap.in
index 7fe551ee..d0cd1617 100644
--- a/pcap_open_offline.3pcap.in
+++ b/pcap_open_offline.3pcap.in
@@ -17,7 +17,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_OPEN_OFFLINE 3PCAP "3 January 2014"
+.TH PCAP_OPEN_OFFLINE 3PCAP "8 January 2018 "
.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
@@ -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/pcap_set_protocol_linux.3pcap b/pcap_set_protocol_linux.3pcap
new file mode 100644
index 00000000..40eb8d2e
--- /dev/null
+++ b/pcap_set_protocol_linux.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_LINUX 3PCAP "24 August 2017"
+.SH NAME
+pcap_set_protocol_linux \- 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_linux(pcap_t *p, int protocol);
+.ft
+.fi
+.SH DESCRIPTION
+On network interface devices on Linux,
+.B pcap_set_protocol_linux()
+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_linux() .
+.SH RETURN VALUE
+.B pcap_set_protocol_linux()
+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/pcap_set_timeout.3pcap b/pcap_set_timeout.3pcap
index a89327f2..cacf603b 100644
--- a/pcap_set_timeout.3pcap
+++ b/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 "6 December 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/pcap_set_tstamp_type.3pcap b/pcap_set_tstamp_type.3pcap
index 8a3bda06..b797c1a5 100644
--- a/pcap_set_tstamp_type.3pcap
+++ b/pcap_set_tstamp_type.3pcap
@@ -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/pcap_set_tstamp_type.3pcap.in b/pcap_set_tstamp_type.3pcap.in
index e58cdd4b..7899da31 100644
--- a/pcap_set_tstamp_type.3pcap.in
+++ b/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/pcap_version.h b/pcap_version.h
deleted file mode 100644
index 619c6d8a..00000000
--- a/pcap_version.h
+++ /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 1.8.1";
diff --git a/pcap_version.h.in b/pcap_version.h.in
deleted file mode 100644
index 3104c8ea..00000000
--- a/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/portability.h b/portability.h
index 8a6bf40e..b3612542 100644
--- a/portability.h
+++ b/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/remote-ext.h b/remote-ext.h
deleted file mode 100644
index ed2f9bb2..00000000
--- a/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/rpcap-protocol.c b/rpcap-protocol.c
new file mode 100644
index 00000000..692f7c5c
--- /dev/null
+++ b/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/rpcap-protocol.h b/rpcap-protocol.h
new file mode 100644
index 00000000..83ebdc5b
--- /dev/null
+++ b/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/rpcapd/.gitignore b/rpcapd/.gitignore
new file mode 100644
index 00000000..50c27ab1
--- /dev/null
+++ b/rpcapd/.gitignore
@@ -0,0 +1,5 @@
+Makefile
+*~
+*.o
+rpcapd
+rpcapd.manadmin
diff --git a/rpcapd/CMakeLists.txt b/rpcapd/CMakeLists.txt
new file mode 100644
index 00000000..b3b16e37
--- /dev/null
+++ b/rpcapd/CMakeLists.txt
@@ -0,0 +1,118 @@
+if(UNIX)
+ check_function_exists(crypt HAVE_CRYPT_IN_SYSTEM_LIBRARIES)
+ if(HAVE_CRYPT_IN_SYSTEM_LIBRARIES)
+ set(HAVE_CRYPT TRUE)
+ else(HAVE_CRYPT_IN_SYSTEM_LIBRARIES)
+ check_library_exists(crypt crypt "" HAVE_CRYPT_IN_LIBCRYPT)
+ if(HAVE_CRYPT_IN_LIBCRYPT)
+ set(RPCAPD_LINK_LIBRARIES ${RPCAPD_LINK_LIBRARIES} crypt)
+ set(HAVE_CRYPT TRUE)
+ else(HAVE_CRYPT_IN_LIBCRYPT)
+ message(WARNING "crypt() not found. Won't be able to build rpcapd.")
+ endif(HAVE_CRYPT_IN_LIBCRYPT)
+ endif(HAVE_CRYPT_IN_SYSTEM_LIBRARIES)
+endif(UNIX)
+
+#
+# On UN*X, we need pthreads and crypt().
+#
+if(WIN32 OR ((CMAKE_USE_PTHREADS_INIT OR PTHREADS_FOUND) AND HAVE_CRYPT))
+ if(UNIX)
+ #
+ # Do we have getspnam()?
+ #
+ check_function_exists(getspnam HAVE_GETSPNAM)
+
+ #
+ # Find library needed for getaddrinfo.
+ # 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.
+ #
+ include(CheckLibraryExists)
+ check_function_exists(getaddrinfo STDLIBS_HAVE_GETADDRINFO)
+ if(NOT STDLIBS_HAVE_GETADDRINFO)
+ check_library_exists(xnet getaddrinfo "" LIBXNET_HAS_GETADDRINFO)
+ if(LIBXNET_HAS_GETADDRINFO)
+ set(RPCAPD_LINK_LIBRARIES ${RPCAPD_LINK_LIBRARIES} xnet)
+ else(LIBXNET_HAS_GETADDRINFO)
+ include(CMakePushCheckState)
+ 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)
+ set(RPCAPD_LINK_LIBRARIES ${RPCAPD_LINK_LIBRARIES} socket nsl)
+ endif(LIBSOCKET_HAS_GETADDRINFO)
+ endif(LIBXNET_HAS_GETADDRINFO)
+ endif(NOT STDLIBS_HAVE_GETADDRINFO)
+ endif(UNIX)
+
+ if(WIN32)
+ set(RPCAPD_EXTRA_SOURCES
+ win32-svc.c
+ ${pcap_SOURCE_DIR}/missing/getopt.c
+ ${pcap_SOURCE_DIR}/missing/win_snprintf.c
+ rpcapd.rc)
+ include_directories(${pcap_SOURCE_DIR}/rpcapd ${pcap_SOURCE_DIR}/missing)
+ endif(WIN32)
+
+ add_executable(rpcapd
+ daemon.c
+ fileconf.c
+ log-stderr.c
+ rpcapd.c
+ ${pcap_SOURCE_DIR}/rpcap-protocol.c
+ ${pcap_SOURCE_DIR}/sockutils.c
+ ${pcap_SOURCE_DIR}/fmtutils.c
+ ${RPCAPD_EXTRA_SOURCES}
+ )
+
+ if(NOT C_ADDITIONAL_FLAGS STREQUAL "")
+ set_target_properties(rpcapd PROPERTIES COMPILE_FLAGS ${C_ADDITIONAL_FLAGS})
+ endif()
+
+ if(WIN32)
+ target_link_libraries(rpcapd ${LIBRARY_NAME}
+ ${RPCAPD_LINK_LIBRARIES} ${PCAP_LINK_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+ else(WIN32)
+ target_link_libraries(rpcapd ${LIBRARY_NAME}_static
+ ${RPCAPD_LINK_LIBRARIES} ${PCAP_LINK_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+ endif(WIN32)
+
+ ######################################
+ # Install rpcap daemon 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(MANADMIN_EXPAND rpcapd.manadmin.in)
+
+ if(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8)
+ install(TARGETS rpcapd DESTINATION bin/amd64)
+ else(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8)
+ install(TARGETS rpcapd DESTINATION bin)
+ endif(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8)
+
+ # On UN*X, and on Windows when not using MSVC, generate process man
+ # pages and arrange that they be installed.
+ if(NOT MSVC)
+ #
+ # Man pages.
+ #
+ # For each section of the manual for which we have man pages
+ # that require macro expansion, do the expansion.
+ #
+ set(MANADMIN "")
+ foreach(TEMPLATE_MANPAGE ${MANADMIN_EXPAND})
+ string(REPLACE ".manadmin.in" ".${MAN_ADMIN_COMMANDS}" MANPAGE ${TEMPLATE_MANPAGE})
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY)
+ set(MANADMIN ${MANADMIN} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE})
+ endforeach(TEMPLATE_MANPAGE)
+ install(FILES ${MANADMIN} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_ADMIN_COMMANDS})
+ endif(NOT MSVC)
+endif(WIN32 OR ((CMAKE_USE_PTHREADS_INIT OR PTHREADS_FOUND) AND HAVE_CRYPT))
diff --git a/rpcapd/Makefile.in b/rpcapd/Makefile.in
new file mode 100644
index 00000000..d3e02c1a
--- /dev/null
+++ b/rpcapd/Makefile.in
@@ -0,0 +1,130 @@
+# Copyright (c) 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.
+
+#
+# Various configurable paths (remember to edit Makefile.in, not Makefile)
+#
+
+# Top level hierarchy
+prefix = @prefix@
+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
+libdir = @libdir@
+# Pathname of directory to install the man pages
+mandir = @mandir@
+
+# VPATH
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+#
+# You shouldn't need to edit anything below.
+#
+
+LD = /usr/bin/ld
+CC = @CC@
+AR = @AR@
+LN_S = @LN_S@
+MKDEP = @MKDEP@
+CCOPT = @V_CCOPT@
+INCLS = -I. -I.. -I@srcdir@ -I@srcdir@/.. @V_INCLS@
+DEFS = @DEFS@ @V_DEFS@
+ADDLOBJS = @ADDLOBJS@
+ADDLARCHIVEOBJS = @ADDLARCHIVEOBJS@
+LIBS = @LIBS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+CROSSFLAGS=
+CFLAGS = @CFLAGS@ ${CROSSFLAGS}
+LDFLAGS = @LDFLAGS@ ${CROSSFLAGS}
+DYEXT = @DYEXT@
+V_RPATH_OPT = @V_RPATH_OPT@
+DEPENDENCY_CFLAG = @DEPENDENCY_CFLAG@
+PROG=libpcap
+RPCAPD_LIBS = @RPCAPD_LIBS@
+
+# Standard CFLAGS
+FULL_CFLAGS = $(CCOPT) $(INCLS) $(DEFS) $(CFLAGS)
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+# Explicitly define compilation rule since SunOS 4's make doesn't like gcc.
+# Also, gcc does not remove the .o before forking 'as', which can be a
+# problem if you don't own the file but can write to the directory.
+.c.o:
+ @rm -f $@
+ $(CC) $(FULL_CFLAGS) -c $(srcdir)/$*.c
+
+SRC = daemon.c \
+ fileconf.c \
+ log-stderr.c \
+ rpcapd.c
+
+OBJ = $(SRC:.c=.o) ../rpcap-protocol.o ../sockutils.o ../fmtutils.o
+PUBHDR =
+
+HDR = $(PUBHDR) log.h
+
+TAGFILES = \
+ $(SRC) $(HDR)
+
+CLEANFILES = $(OBJ) rpcapd
+
+MANADMIN = \
+ rpcapd.manadmin.in
+
+rpcapd: $(OBJ) ../libpcap.a
+ $(CC) $(CCOPT) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ) ../libpcap.a $(LIBS) $(RPCAPD_LIBS) $(PTHREAD_LIBS)
+clean:
+ rm -f $(CLEANFILES)
+
+distclean: clean
+ rm -f Makefile config.cache config.log config.status \
+ config.h stamp-h stamp-h.in
+ rm -f $(MANADMIN:.in=)
+ rm -rf autom4te.cache
+
+install: rpcapd
+ [ -d $(DESTDIR)$(sbindir) ] || \
+ (mkdir -p $(DESTDIR)$(sbindir); chmod 755 $(DESTDIR)$(sbindir))
+ $(INSTALL_PROGRAM) rpcapd $(DESTDIR)$(sbindir)/rpcapd
+ [ -d $(DESTDIR)$(mandir)/man@MAN_ADMIN_COMMANDS@ ] || \
+ (mkdir -p $(DESTDIR)$(mandir)/man@MAN_ADMIN_COMMANDS@; chmod 755 $(DESTDIR)$(mandir)/man@MAN_ADMIN_COMMANDS@)
+ for i in $(MANADMIN); do \
+ $(INSTALL_DATA) `echo $$i | sed 's/.manadmin.in/.manadmin/'` \
+ $(DESTDIR)$(mandir)/man@MAN_ADMIN_COMMANDS@/`echo $$i | sed 's/.manadmin.in/.@MAN_ADMIN_COMMANDS@/'`; done
+
+uninstall:
+ rm -f $(DESTDIR)$(sbindir)/rpcapd
+ for i in $(MANADMIN); do \
+ rm -f $(DESTDIR)$(mandir)/man@MAN_ADMIN_COMMANDS@/`echo $$i | sed 's/.manadmin.in/.@MAN_ADMIN_COMMANDS@/'`; done
+
+tags: $(TAGFILES)
+ ctags -wtd $(TAGFILES)
+
+depend:
+ ../$(MKDEP) -c "$(CC)" -m "$(DEPENDENCY_CFLAG)" $(CFLAGS) $(DEFS) $(INCLS) $(SRC)
diff --git a/rpcapd/config_params.h b/rpcapd/config_params.h
new file mode 100644
index 00000000..c219ce16
--- /dev/null
+++ b/rpcapd/config_params.h
@@ -0,0 +1,56 @@
+/*
+ * 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 __CONFIG_PARAMS_H__
+#define __CONFIG_PARAMS_H__
+
+//
+// Parameters set from the configuration file.
+//
+
+#define MAX_LINE 2048 /* Maximum chars allowed for the host list (in passive mode) */
+#define MAX_HOST_LIST 64000
+#define MAX_ACTIVE_LIST 10
+
+struct active_pars
+{
+ char address[MAX_LINE + 1]; // keeps the network address (either numeric or literal) to of the active client
+ char port[MAX_LINE + 1]; // keeps the network port to bind to
+ int ai_family; // address faimly to use
+};
+
+extern char hostlist[MAX_HOST_LIST + 1]; //!< Keeps the list of the hosts that are allowed to connect to this server
+extern struct active_pars activelist[MAX_ACTIVE_LIST]; //!< Keeps the list of the hosts (host, port) on which I want to connect to (active mode)
+extern int nullAuthAllowed; //!< '1' if we permit NULL authentication, '0' otherwise
+extern char loadfile[MAX_LINE + 1]; //!< Name of the file from which we have to load the configuration
+
+#endif
diff --git a/rpcapd/daemon.c b/rpcapd/daemon.c
new file mode 100644
index 00000000..4bf42fde
--- /dev/null
+++ b/rpcapd/daemon.c
@@ -0,0 +1,2554 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "ftmacros.h"
+#include "varattrs.h"
+
+#include <errno.h> // for the errno variable
+#include <stdlib.h> // for malloc(), free(), ...
+#include <string.h> // for strlen(), ...
+
+#ifdef _WIN32
+ #include <process.h> // for threads
+#else
+ #include <unistd.h>
+ #include <pthread.h>
+ #include <sys/time.h>
+ #include <sys/types.h> // for select() and such
+ #include <pwd.h> // for password management
+#endif
+
+#ifdef HAVE_GETSPNAM
+#include <shadow.h> // for password management
+#endif
+
+#include <pcap.h> // for libpcap/WinPcap calls
+
+#include "fmtutils.h"
+#include "sockutils.h" // for socket calls
+#include "portability.h"
+#include "rpcap-protocol.h"
+#include "daemon.h"
+#include "log.h"
+
+#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_SUSPEND_WRONGAUTH 1 /* If the authentication is wrong, stops 1 sec before accepting a new auth message */
+
+// Parameters for the service loop.
+struct daemon_slpars
+{
+ SOCKET sockctrl_in; //!< SOCKET ID of the input side of the control connection
+ SOCKET sockctrl_out; //!< SOCKET ID of the output side of the control connection
+ uint8 protocol_version; //!< negotiated protocol version
+ int isactive; //!< Not null if the daemon has to run in active mode
+ int nullAuthAllowed; //!< '1' if we permit NULL authentication, '0' otherwise
+};
+
+/*
+ * Data for a session managed by a thread.
+ */
+struct session {
+ SOCKET sockctrl_out;
+ SOCKET sockdata;
+ uint8 protocol_version;
+ pcap_t *fp;
+ unsigned int TotCapt;
+};
+
+//
+// Structure to refer to a thread.
+// It includes both a Boolean indicating whether we *have* a thread,
+// and a platform-dependent (UN*X vs. Windows) identifier for the
+// thread; on Windows, we could use an invalid handle to indicate
+// that we don't have a thread, but there *is* no portable "no thread"
+// value for a pthread_t on UN*X.
+//
+struct thread_handle {
+ int have_thread;
+#ifdef _WIN32
+ HANDLE thread;
+#else
+ pthread_t thread;
+#endif
+};
+
+// Locally defined functions
+static int daemon_msg_err(SOCKET sockctrl_in, uint32 plen);
+static int daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen);
+static int daemon_AuthUserPwd(char *username, char *password, char *errbuf);
+
+static int daemon_msg_findallif_req(struct daemon_slpars *pars, uint32 plen);
+
+static int daemon_msg_open_req(struct daemon_slpars *pars, uint32 plen, char *source, size_t sourcelen);
+static int daemon_msg_startcap_req(struct daemon_slpars *pars, uint32 plen, struct thread_handle *threaddata, char *source, struct session **sessionp, struct rpcap_sampling *samp_param);
+static int daemon_msg_endcap_req(struct daemon_slpars *pars, struct session *session, struct thread_handle *threaddata);
+
+static int daemon_msg_updatefilter_req(struct daemon_slpars *pars, struct session *session, uint32 plen);
+static int daemon_unpackapplyfilter(SOCKET sockctrl_in, struct session *session, uint32 *plenp, char *errbuf);
+
+static int daemon_msg_stats_req(struct daemon_slpars *pars, struct session *session, uint32 plen, struct pcap_stat *stats, unsigned int svrcapt);
+
+static int daemon_msg_setsampling_req(struct daemon_slpars *pars, uint32 plen, struct rpcap_sampling *samp_param);
+
+static void daemon_seraddr(struct sockaddr_storage *sockaddrin, struct rpcap_sockaddr *sockaddrout);
+#ifdef _WIN32
+static unsigned __stdcall daemon_thrdatamain(void *ptr);
+#else
+static void *daemon_thrdatamain(void *ptr);
+#endif
+
+static int rpcapd_recv_msg_header(SOCKET sock, struct rpcap_header *headerp);
+static int rpcapd_recv(SOCKET sock, char *buffer, size_t toread, uint32 *plen, char *errmsgbuf);
+static int rpcapd_discard(SOCKET sock, uint32 len);
+
+int
+daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, int isactive, int nullAuthAllowed)
+{
+ struct daemon_slpars pars; // service loop parameters
+ char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
+ char errmsgbuf[PCAP_ERRBUF_SIZE + 1]; // buffer for errors to send to the client
+ int nrecv;
+ struct rpcap_header header; // RPCAP message general header
+ uint32 plen; // payload length from header
+ int authenticated = 0; // 1 if the client has successfully authenticated
+ char source[PCAP_BUF_SIZE+1]; // keeps the string that contains the interface to open
+ int got_source = 0; // 1 if we've gotten the source from an open request
+ struct session *session = NULL; // struct session main variable
+ const char *msg_type_string; // string for message type
+ int client_told_us_to_close = 0; // 1 if the client told us to close the capture
+
+ struct thread_handle threaddata; // 'read from daemon and send to client' thread
+
+ // needed to save the values of the statistics
+ struct pcap_stat stats;
+ unsigned int svrcapt;
+
+ struct rpcap_sampling samp_param; // in case sampling has been requested
+
+ // 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
+ int retval; // select() return value
+
+ // Set parameters structure
+ pars.sockctrl_in = sockctrl_in;
+ pars.sockctrl_out = sockctrl_out;
+ pars.protocol_version = 0; // not yet known
+ pars.isactive = isactive; // active mode
+ pars.nullAuthAllowed = nullAuthAllowed;
+
+ // We don't have a thread yet.
+ threaddata.have_thread = 0;
+ //
+ // We *shouldn't* have to initialize the thread indicator
+ // itself, because the compiler *should* realize that we
+ // only use this if have_thread isn't 0, but we *do* have
+ // to do it, because not all compilers *do* realize that.
+ //
+ // There is no "invalid thread handle" value for a UN*X
+ // pthread_t, so we just zero it out.
+ //
+#ifdef _WIN32
+ threaddata.thread = INVALID_HANDLE_VALUE;
+#else
+ memset(&threaddata.thread, 0, sizeof(threaddata.thread));
+#endif
+
+ *errbuf = 0; // Initialize errbuf
+
+ //
+ // The client must first authenticate; loop until they send us a
+ // message with a version we support and credentials we accept,
+ // they send us a close message indicating that they're giving up,
+ // or we get a network error or other fatal error.
+ //
+ while (!authenticated)
+ {
+ //
+ // If we're in active mode, we have to check for the
+ // initial timeout.
+ //
+ // XXX - do this on *every* trip through the loop?
+ //
+ if (!pars.isactive)
+ {
+ FD_ZERO(&rfds);
+ // We do not have to block here
+ tv.tv_sec = RPCAP_TIMEOUT_INIT;
+ tv.tv_usec = 0;
+
+ FD_SET(pars.sockctrl_in, &rfds);
+
+ retval = select(pars.sockctrl_in + 1, &rfds, NULL, NULL, &tv);
+ if (retval == -1)
+ {
+ sock_geterror("select failed: ", errmsgbuf, PCAP_ERRBUF_SIZE);
+ if (rpcap_senderror(pars.sockctrl_out, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1)
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ goto end;
+ }
+
+ // The timeout has expired
+ // So, this was a fake connection. Drop it down
+ if (retval == 0)
+ {
+ if (rpcap_senderror(pars.sockctrl_out, 0, PCAP_ERR_INITTIMEOUT, "The RPCAP initial timeout has expired", errbuf) == -1)
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ goto end;
+ }
+ }
+
+ //
+ // Read the message header from the client.
+ //
+ nrecv = rpcapd_recv_msg_header(pars.sockctrl_in, &header);
+ if (nrecv == -1)
+ {
+ // Fatal error.
+ goto end;
+ }
+ if (nrecv == -2)
+ {
+ // Client closed the connection.
+ goto end;
+ }
+
+ plen = header.plen;
+
+ //
+ // Did the client specify a version we can handle?
+ //
+ if (!RPCAP_VERSION_IS_SUPPORTED(header.ver))
+ {
+ //
+ // Tell them it's not a valid protocol version.
+ //
+ uint8 reply_version;
+
+ //
+ // If RPCAP_MIN_VERSION is 0, no version is too
+ // old, as the oldest supported version is 0,
+ // and there are no negative versions.
+ //
+#if RPCAP_MIN_VERSION != 0
+ if (header.ver < RPCAP_MIN_VERSION)
+ {
+ //
+ // Their maximum version is too old;
+ // there *is* no version we can both
+ // handle, and they might reject
+ // an error with a version they don't
+ // understand, so reply with the
+ // version they sent. That may
+ // make them retry with that version,
+ // but they'll give up on that
+ // failure.
+ //
+ reply_version = header.ver;
+ }
+ else
+#endif
+ {
+ //
+ // Their maximum version is too new,
+ // but they might be able to handle
+ // *our* maximum version, so reply
+ // with that version.
+ //
+ reply_version = RPCAP_MAX_VERSION;
+ }
+ if (rpcap_senderror(pars.sockctrl_out, reply_version,
+ PCAP_ERR_WRONGVER, "RPCAP version number mismatch",
+ errbuf) == -1)
+ {
+ // That failed; log a message and give up.
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ goto end;
+ }
+
+ // Discard the rest of the message.
+ if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
+ {
+ // Network error.
+ goto end;
+ }
+
+ // Let them try again.
+ continue;
+ }
+
+ //
+ // OK, we use the version the client specified.
+ //
+ pars.protocol_version = header.ver;
+
+ switch (header.type)
+ {
+ case RPCAP_MSG_AUTH_REQ:
+ retval = daemon_msg_auth_req(&pars, plen);
+ if (retval == -1)
+ {
+ // Fatal error; a message has
+ // been logged, so just give up.
+ goto end;
+ }
+ if (retval == -2)
+ {
+ // Non-fatal error; we sent back
+ // an error message, so let them
+ // try again.
+ continue;
+ }
+
+ // OK, we're authenticated; we sent back
+ // a reply, so start serving requests.
+ authenticated = 1;
+ break;
+
+ case RPCAP_MSG_CLOSE:
+ //
+ // The client is giving up.
+ // Discard the rest of the message, if
+ // there is anything more.
+ //
+ (void)rpcapd_discard(pars.sockctrl_in, plen);
+ // We're done with this client.
+ goto end;
+
+ case RPCAP_MSG_ERROR:
+ // Log this and close the connection?
+ // XXX - is this what happens in active
+ // mode, where *we* initiate the
+ // connection, and the client gives us
+ // an error message rather than a "let
+ // me log in" message, indicating that
+ // we're not allowed to connect to them?
+ (void)daemon_msg_err(pars.sockctrl_in, plen);
+ goto end;
+
+ case RPCAP_MSG_FINDALLIF_REQ:
+ case RPCAP_MSG_OPEN_REQ:
+ case RPCAP_MSG_STARTCAP_REQ:
+ case RPCAP_MSG_UPDATEFILTER_REQ:
+ case RPCAP_MSG_STATS_REQ:
+ case RPCAP_MSG_ENDCAP_REQ:
+ case RPCAP_MSG_SETSAMPLING_REQ:
+ //
+ // These requests can't be sent until
+ // the client is authenticated.
+ //
+ msg_type_string = rpcap_msg_type_string(header.type);
+ if (msg_type_string != NULL)
+ {
+ pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "%s request sent before authentication was completed", msg_type_string);
+ }
+ else
+ {
+ pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Message of type %u sent before authentication was completed", header.type);
+ }
+ if (rpcap_senderror(pars.sockctrl_out,
+ pars.protocol_version, PCAP_ERR_WRONGMSG,
+ errmsgbuf, errbuf) == -1)
+ {
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ goto end;
+ }
+ // Discard the rest of the message.
+ if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
+ {
+ // Network error.
+ goto end;
+ }
+ break;
+
+ case RPCAP_MSG_PACKET:
+ case RPCAP_MSG_FINDALLIF_REPLY:
+ case RPCAP_MSG_OPEN_REPLY:
+ case RPCAP_MSG_STARTCAP_REPLY:
+ case RPCAP_MSG_UPDATEFILTER_REPLY:
+ case RPCAP_MSG_AUTH_REPLY:
+ case RPCAP_MSG_STATS_REPLY:
+ case RPCAP_MSG_ENDCAP_REPLY:
+ case RPCAP_MSG_SETSAMPLING_REPLY:
+ //
+ // These are server-to-client messages.
+ //
+ msg_type_string = rpcap_msg_type_string(header.type);
+ if (msg_type_string != NULL)
+ {
+ pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message %s received from client", msg_type_string);
+ }
+ else
+ {
+ pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message of type %u received from client", header.type);
+ }
+ if (rpcap_senderror(pars.sockctrl_out,
+ pars.protocol_version, PCAP_ERR_WRONGMSG,
+ errmsgbuf, errbuf) == -1)
+ {
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ goto end;
+ }
+ // Discard the rest of the message.
+ if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
+ {
+ // Fatal error.
+ goto end;
+ }
+ break;
+
+ default:
+ //
+ // Unknown message type.
+ //
+ pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Unknown message type %u", header.type);
+ if (rpcap_senderror(pars.sockctrl_out,
+ pars.protocol_version, PCAP_ERR_WRONGMSG,
+ errmsgbuf, errbuf) == -1)
+ {
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ goto end;
+ }
+ // Discard the rest of the message.
+ if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
+ {
+ // Fatal error.
+ goto end;
+ }
+ break;
+ }
+ }
+
+ //
+ // OK, the client has authenticated itself, and we can start
+ // processing regular requests from it.
+ //
+
+ //
+ // We don't have any statistics yet.
+ //
+ stats.ps_ifdrop = 0;
+ stats.ps_recv = 0;
+ stats.ps_drop = 0;
+ svrcapt = 0;
+
+ //
+ // Service requests.
+ //
+ for (;;)
+ {
+ errbuf[0] = 0; // clear errbuf
+
+ // Avoid zombies connections; check if the connection is opens but no commands are performed
+ // from more than RPCAP_TIMEOUT_RUNTIME
+ // Conditions:
+ // - I have to be in normal mode (no active mode)
+ // - if the device is open, I don't have to be in the middle of a capture (session->sockdata)
+ // - if the device is closed, I have always to check if a new command arrives
+ //
+ // Be carefully: the capture can have been started, but an error occurred (so session != NULL, but
+ // sockdata is 0
+ if ((!pars.isactive) && ((session == NULL) || ((session != NULL) && (session->sockdata == 0))))
+ {
+ // Check for the initial timeout
+ FD_ZERO(&rfds);
+ // We do not have to block here
+ tv.tv_sec = RPCAP_TIMEOUT_RUNTIME;
+ tv.tv_usec = 0;
+
+ FD_SET(pars.sockctrl_in, &rfds);
+
+ retval = select(pars.sockctrl_in + 1, &rfds, NULL, NULL, &tv);
+ if (retval == -1)
+ {
+ sock_geterror("select failed: ", errmsgbuf, PCAP_ERRBUF_SIZE);
+ if (rpcap_senderror(pars.sockctrl_out,
+ pars.protocol_version, PCAP_ERR_NETW,
+ errmsgbuf, errbuf) == -1)
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ goto end;
+ }
+
+ // The timeout has expired
+ // So, this was a fake connection. Drop it down
+ if (retval == 0)
+ {
+ if (rpcap_senderror(pars.sockctrl_out,
+ pars.protocol_version,
+ PCAP_ERR_INITTIMEOUT,
+ "The RPCAP initial timeout has expired",
+ errbuf) == -1)
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ goto end;
+ }
+ }
+
+ //
+ // Read the message header from the client.
+ //
+ nrecv = rpcapd_recv_msg_header(pars.sockctrl_in, &header);
+ if (nrecv == -1)
+ {
+ // Fatal error.
+ goto end;
+ }
+ if (nrecv == -2)
+ {
+ // Client closed the connection.
+ goto end;
+ }
+
+ plen = header.plen;
+
+ //
+ // Did the client specify the version we negotiated?
+ //
+ // For now, there's only one version.
+ //
+ if (header.ver != pars.protocol_version)
+ {
+ //
+ // Tell them it's not the negotiated version.
+ // Send the error message with their version,
+ // so they don't reject it as having the wrong
+ // version.
+ //
+ if (rpcap_senderror(pars.sockctrl_out,
+ header.ver, PCAP_ERR_WRONGVER,
+ "RPCAP version in message isn't the negotiated version",
+ errbuf) == -1)
+ {
+ // That failed; log a message and give up.
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ goto end;
+ }
+
+ // Discard the rest of the message.
+ (void)rpcapd_discard(pars.sockctrl_in, plen);
+ // Give up on them.
+ goto end;
+ }
+
+ switch (header.type)
+ {
+ case RPCAP_MSG_ERROR: // The other endpoint reported an error
+ {
+ (void)daemon_msg_err(pars.sockctrl_in, plen);
+ // Do nothing; just exit; the error code is already into the errbuf
+ // XXX - actually exit....
+ break;
+ }
+
+ case RPCAP_MSG_FINDALLIF_REQ:
+ {
+ if (daemon_msg_findallif_req(&pars, plen) == -1)
+ {
+ // Fatal error; a message has
+ // been logged, so just give up.
+ goto end;
+ }
+ break;
+ }
+
+ case RPCAP_MSG_OPEN_REQ:
+ {
+ //
+ // Process the open request, and keep
+ // the source from it, for use later
+ // when the capture is started.
+ //
+ // XXX - we don't care if the client sends
+ // us multiple open requests, the last
+ // one wins.
+ //
+ retval = daemon_msg_open_req(&pars, plen, source, sizeof(source));
+ if (retval == -1)
+ {
+ // Fatal error; a message has
+ // been logged, so just give up.
+ goto end;
+ }
+ got_source = 1;
+ break;
+ }
+
+ case RPCAP_MSG_STARTCAP_REQ:
+ {
+ if (!got_source)
+ {
+ // They never told us what device
+ // to capture on!
+ if (rpcap_senderror(pars.sockctrl_out,
+ pars.protocol_version,
+ PCAP_ERR_STARTCAPTURE,
+ "No capture device was specified",
+ errbuf) == -1)
+ {
+ // Fatal error; log an
+ // error and give up.
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ goto end;
+ }
+ if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
+ {
+ goto end;
+ }
+ break;
+ }
+
+ if (daemon_msg_startcap_req(&pars, plen, &threaddata, source, &session, &samp_param) == -1)
+ {
+ // Fatal error; a message has
+ // been logged, so just give up.
+ goto end;
+ }
+ break;
+ }
+
+ case RPCAP_MSG_UPDATEFILTER_REQ:
+ {
+ if (session)
+ {
+ if (daemon_msg_updatefilter_req(&pars, session, plen) == -1)
+ {
+ // Fatal error; a message has
+ // been logged, so just give up.
+ goto end;
+ }
+ }
+ else
+ {
+ if (rpcap_senderror(pars.sockctrl_out,
+ pars.protocol_version,
+ PCAP_ERR_UPDATEFILTER,
+ "Device not opened. Cannot update filter",
+ errbuf) == -1)
+ {
+ // That failed; log a message and give up.
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ goto end;
+ }
+ }
+ break;
+ }
+
+ case RPCAP_MSG_CLOSE: // The other endpoint close the pcap session
+ {
+ //
+ // Indicate to our caller that the client
+ // closed the control connection.
+ // This is used only in case of active mode.
+ //
+ client_told_us_to_close = 1;
+ SOCK_DEBUG_MESSAGE("The other end system asked to close the connection.");
+ goto end;
+ }
+
+ case RPCAP_MSG_STATS_REQ:
+ {
+ if (daemon_msg_stats_req(&pars, session, plen, &stats, svrcapt) == -1)
+ {
+ // Fatal error; a message has
+ // been logged, so just give up.
+ goto end;
+ }
+ break;
+ }
+
+ case RPCAP_MSG_ENDCAP_REQ: // The other endpoint close the current capture session
+ {
+ if (session)
+ {
+ // Save statistics (we can need them in the future)
+ if (pcap_stats(session->fp, &stats))
+ {
+ svrcapt = session->TotCapt;
+ }
+ else
+ {
+ stats.ps_ifdrop = 0;
+ stats.ps_recv = 0;
+ stats.ps_drop = 0;
+ svrcapt = 0;
+ }
+
+ if (daemon_msg_endcap_req(&pars, session, &threaddata) == -1)
+ {
+ free(session);
+ session = NULL;
+ // Fatal error; a message has
+ // been logged, so just give up.
+ goto end;
+ }
+ free(session);
+ session = NULL;
+ }
+ else
+ {
+ rpcap_senderror(pars.sockctrl_out,
+ pars.protocol_version,
+ PCAP_ERR_ENDCAPTURE,
+ "Device not opened. Cannot close the capture",
+ errbuf);
+ }
+ break;
+ }
+
+ case RPCAP_MSG_SETSAMPLING_REQ:
+ {
+ if (daemon_msg_setsampling_req(&pars, plen, &samp_param) == -1)
+ {
+ // Fatal error; a message has
+ // been logged, so just give up.
+ goto end;
+ }
+ break;
+ }
+
+ case RPCAP_MSG_AUTH_REQ:
+ {
+ //
+ // We're already authenticated; you don't
+ // get to reauthenticate.
+ //
+ rpcapd_log(LOGPRIO_INFO, "The client sent an RPCAP_MSG_AUTH_REQ message after authentication was completed");
+ if (rpcap_senderror(pars.sockctrl_out,
+ pars.protocol_version,
+ PCAP_ERR_WRONGMSG,
+ "RPCAP_MSG_AUTH_REQ request sent after authentication was completed",
+ errbuf) == -1)
+ {
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ goto end;
+ }
+ // Discard the rest of the message.
+ if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
+ {
+ // Fatal error.
+ goto end;
+ }
+ goto end;
+
+ case RPCAP_MSG_PACKET:
+ case RPCAP_MSG_FINDALLIF_REPLY:
+ case RPCAP_MSG_OPEN_REPLY:
+ case RPCAP_MSG_STARTCAP_REPLY:
+ case RPCAP_MSG_UPDATEFILTER_REPLY:
+ case RPCAP_MSG_AUTH_REPLY:
+ case RPCAP_MSG_STATS_REPLY:
+ case RPCAP_MSG_ENDCAP_REPLY:
+ case RPCAP_MSG_SETSAMPLING_REPLY:
+ //
+ // These are server-to-client messages.
+ //
+ msg_type_string = rpcap_msg_type_string(header.type);
+ if (msg_type_string != NULL)
+ {
+ rpcapd_log(LOGPRIO_INFO, "The client sent a %s server-to-client message", msg_type_string);
+ pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message %s received from client", msg_type_string);
+ }
+ else
+ {
+ rpcapd_log(LOGPRIO_INFO, "The client sent a server-to-client message of type %u", header.type);
+ pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message of type %u received from client", header.type);
+ }
+ if (rpcap_senderror(pars.sockctrl_out,
+ pars.protocol_version, PCAP_ERR_WRONGMSG,
+ errmsgbuf, errbuf) == -1)
+ {
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ goto end;
+ }
+ // Discard the rest of the message.
+ if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
+ {
+ // Fatal error.
+ goto end;
+ }
+ goto end;
+
+ default:
+ //
+ // Unknown message type.
+ //
+ rpcapd_log(LOGPRIO_INFO, "The client sent a message of type %u", header.type);
+ pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Unknown message type %u", header.type);
+ if (rpcap_senderror(pars.sockctrl_out,
+ pars.protocol_version, PCAP_ERR_WRONGMSG,
+ errbuf, errmsgbuf) == -1)
+ {
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ goto end;
+ }
+ // Discard the rest of the message.
+ if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
+ {
+ // Fatal error.
+ goto end;
+ }
+ goto end;
+ }
+ }
+ }
+
+end:
+ // The child thread is about to end
+
+ // perform pcap_t cleanup, in case it has not been done
+ if (session)
+ {
+ if (threaddata.have_thread)
+ {
+#ifdef _WIN32
+ //
+ // Tell the data connection thread main capture
+ // loop to break out of that loop.
+ //
+ pcap_breakloop(session->fp);
+
+ //
+ // If it's currently blocked waiting for packets
+ // to arrive, try to wake it up, so it can see
+ // the "break out of the loop" indication.
+ //
+ SetEvent(pcap_getevent(session->fp));
+
+ //
+ // Wait for the thread to exit, so we don't close
+ // sockets out from under it.
+ //
+ // XXX - have a timeout, so we don't wait forever?
+ //
+ WaitForSingleObject(threaddata.thread, INFINITE);
+
+ //
+ // Release the thread handle, as we're done with
+ // it.
+ //
+ CloseHandle(threaddata.thread);
+#else
+ pthread_cancel(threaddata.thread);
+#endif
+ threaddata.have_thread = 0;
+ }
+ if (session->sockdata)
+ {
+ sock_close(session->sockdata, NULL, 0);
+ session->sockdata = 0;
+ }
+ pcap_close(session->fp);
+ free(session);
+ session = NULL;
+ }
+
+ // Print message and return
+ SOCK_DEBUG_MESSAGE("I'm exiting from the child loop");
+ SOCK_DEBUG_MESSAGE(errbuf);
+
+ return client_told_us_to_close;
+}
+
+/*
+ * This handles the RPCAP_MSG_ERR message.
+ */
+static int
+daemon_msg_err(SOCKET sockctrl_in, uint32 plen)
+{
+ char errbuf[PCAP_ERRBUF_SIZE];
+ char remote_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_in, remote_errbuf, PCAP_ERRBUF_SIZE - 1,
+ SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf,
+ PCAP_ERRBUF_SIZE) == -1)
+ {
+ // Network error.
+ rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
+ return -1;
+ }
+ if (rpcapd_discard(sockctrl_in, plen - (PCAP_ERRBUF_SIZE - 1)) == -1)
+ {
+ // Network error.
+ return -1;
+ }
+
+ /*
+ * Null-terminate it.
+ */
+ remote_errbuf[PCAP_ERRBUF_SIZE - 1] = '\0';
+ }
+ else if (plen == 0)
+ {
+ /* Empty error string. */
+ remote_errbuf[0] = '\0';
+ }
+ else
+ {
+ if (sock_recv(sockctrl_in, remote_errbuf, plen,
+ SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf,
+ PCAP_ERRBUF_SIZE) == -1)
+ {
+ // Network error.
+ rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
+ return -1;
+ }
+
+ /*
+ * Null-terminate it.
+ */
+ remote_errbuf[plen] = '\0';
+ }
+ // Log the message
+ rpcapd_log(LOGPRIO_ERROR, "Error from client: %s", remote_errbuf);
+ return 0;
+}
+
+/*
+ * This handles the RPCAP_MSG_AUTH_REQ message.
+ * It checks if the authentication credentials supplied by the user are valid.
+ *
+ * This function is called if the daemon receives a RPCAP_MSG_AUTH_REQ
+ * message in its authentication loop. It reads the body of the
+ * authentication message from the network and checks whether the
+ * credentials are valid.
+ *
+ * \param sockctrl: the socket for the control connection.
+ *
+ * \param nullAuthAllowed: '1' if the NULL authentication is allowed.
+ *
+ * \param errbuf: a user-allocated buffer in which the error message
+ * (if one) has to be written. It must be at least PCAP_ERRBUF_SIZE
+ * bytes long.
+ *
+ * \return '0' if everything is fine, '-1' if an unrecoverable error occurred,
+ * or '-2' if the authentication failed. For errors, an error message is
+ * returned in the 'errbuf' variable; this gives a message for the
+ * unrecoverable error or for the authentication failure.
+ */
+static int
+daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen)
+{
+ char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
+ char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client
+ struct rpcap_header header; // RPCAP message general header
+ int status;
+ struct rpcap_auth auth; // RPCAP authentication header
+
+ status = rpcapd_recv(pars->sockctrl_in, (char *) &auth, sizeof(struct rpcap_auth), &plen, errmsgbuf);
+ if (status == -1)
+ {
+ return -1;
+ }
+ if (status == -2)
+ {
+ goto error;
+ }
+
+ switch (ntohs(auth.type))
+ {
+ case RPCAP_RMTAUTH_NULL:
+ {
+ if (!pars->nullAuthAllowed)
+ {
+ // Send the client an error reply.
+ pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Authentication failed; NULL authentication not permitted.");
+ goto error;
+ }
+ break;
+ }
+
+ case RPCAP_RMTAUTH_PWD:
+ {
+ char *username, *passwd;
+ uint32 usernamelen, passwdlen;
+
+ usernamelen = ntohs(auth.slen1);
+ username = (char *) malloc (usernamelen + 1);
+ if (username == NULL)
+ {
+ pcap_fmt_errmsg_for_errno(errmsgbuf,
+ PCAP_ERRBUF_SIZE, errno, "malloc() failed");
+ goto error;
+ }
+ status = rpcapd_recv(pars->sockctrl_in, username, usernamelen, &plen, errmsgbuf);
+ if (status == -1)
+ {
+ free(username);
+ return -1;
+ }
+ if (status == -2)
+ {
+ free(username);
+ goto error;
+ }
+ username[usernamelen] = '\0';
+
+ passwdlen = ntohs(auth.slen2);
+ passwd = (char *) malloc (passwdlen + 1);
+ if (passwd == NULL)
+ {
+ pcap_fmt_errmsg_for_errno(errmsgbuf,
+ PCAP_ERRBUF_SIZE, errno, "malloc() failed");
+ free(username);
+ goto error;
+ }
+ status = rpcapd_recv(pars->sockctrl_in, passwd, passwdlen, &plen, errmsgbuf);
+ if (status == -1)
+ {
+ free(username);
+ free(passwd);
+ return -1;
+ }
+ if (status == -2)
+ {
+ free(username);
+ free(passwd);
+ goto error;
+ }
+ passwd[passwdlen] = '\0';
+
+ if (daemon_AuthUserPwd(username, passwd, errmsgbuf))
+ {
+ //
+ // Authentication failed. Let the client
+ // know.
+ //
+ free(username);
+ free(passwd);
+ if (rpcap_senderror(pars->sockctrl_out,
+ pars->protocol_version,
+ PCAP_ERR_AUTH, errmsgbuf, errbuf) == -1)
+ {
+ // That failed; log a message and give up.
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ return -1;
+ }
+
+ //
+ // Suspend for 1 second, so that they can't
+ // hammer us with repeated tries with an
+ // attack such as a dictionary attack.
+ //
+ // WARNING: this delay is inserted only
+ // at this point; if the client closes the
+ // connection and reconnects, the suspension
+ // time does not have any effect.
+ //
+ sleep_secs(RPCAP_SUSPEND_WRONGAUTH);
+ goto error_noreply;
+ }
+
+ free(username);
+ free(passwd);
+ break;
+ }
+
+ default:
+ pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Authentication type not recognized.");
+ goto error;
+ }
+
+ // The authentication succeeded; let the client know.
+ rpcap_createhdr(&header, pars->protocol_version, RPCAP_MSG_AUTH_REPLY, 0, 0);
+
+ // Send the ok message back
+ if (sock_send(pars->sockctrl_out, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1)
+ {
+ // That failed; log a messsage and give up.
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ return -1;
+ }
+
+ // Check if all the data has been read; if not, discard the data in excess
+ if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+ {
+ return -1;
+ }
+
+ return 0;
+
+error:
+ if (rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
+ PCAP_ERR_AUTH, errmsgbuf, errbuf) == -1)
+ {
+ // That failed; log a message and give up.
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ return -1;
+ }
+
+error_noreply:
+ // Check if all the data has been read; if not, discard the data in excess
+ if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+ {
+ return -1;
+ }
+
+ return -2;
+}
+
+static int
+daemon_AuthUserPwd(char *username, char *password, char *errbuf)
+{
+#ifdef _WIN32
+ /*
+ * Warning: the user which launches the process must have the
+ * SE_TCB_NAME right.
+ * This corresponds to have the "Act as part of the Operating System"
+ * turned on (administrative tools, local security settings, local
+ * policies, user right assignment)
+ * However, it seems to me that if you run it as a service, this
+ * right should be provided by default.
+ */
+ HANDLE Token;
+ if (LogonUser(username, ".", password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &Token) == 0)
+ {
+ int error;
+
+ error = GetLastError();
+ FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
+ PCAP_ERRBUF_SIZE, NULL);
+
+ return -1;
+ }
+
+ // This call should change the current thread to the selected user.
+ // I didn't test it.
+ if (ImpersonateLoggedOnUser(Token) == 0)
+ {
+ int error;
+
+ error = GetLastError();
+ FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
+ PCAP_ERRBUF_SIZE, NULL);
+
+ CloseHandle(Token);
+ return -1;
+ }
+
+ CloseHandle(Token);
+ return 0;
+
+#else
+ /*
+ * See
+ *
+ * http://www.unixpapa.com/incnote/passwd.html
+ *
+ * We use the Solaris/Linux shadow password authentication if
+ * we have getspnam(), otherwise we just do traditional
+ * authentication, which, on some platforms, might work, even
+ * with shadow passwords, if we're running as root. Traditional
+ * authenticaion won't work if we're not running as root, as
+ * I think these days all UN*Xes either won't return the password
+ * at all with getpwnam() or will only do so if you're root.
+ *
+ * XXX - perhaps what we *should* be using is PAM, if we have
+ * it. That might hide all the details of username/password
+ * authentication, whether it's done with a visible-to-root-
+ * only password database or some other authentication mechanism,
+ * behind its API.
+ */
+ struct passwd *user;
+ char *user_password;
+#ifdef HAVE_GETSPNAM
+ struct spwd *usersp;
+#endif
+
+ // This call is needed to get the uid
+ if ((user = getpwnam(username)) == NULL)
+ {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: no such user");
+ return -1;
+ }
+
+#ifdef HAVE_GETSPNAM
+ // This call is needed to get the password; otherwise 'x' is returned
+ if ((usersp = getspnam(username)) == NULL)
+ {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: no such user");
+ return -1;
+ }
+ user_password = usersp->sp_pwdp;
+#else
+ /*
+ * XXX - what about other platforms?
+ * The unixpapa.com page claims this Just Works on *BSD if you're
+ * running as root - it's from 2000, so it doesn't indicate whether
+ * macOS (which didn't come out until 2001, under the name Mac OS
+ * X) behaves like the *BSDs or not, and might also work on AIX.
+ * HP-UX does something else.
+ *
+ * Again, hopefully PAM hides all that.
+ */
+ user_password = user->pw_passwd;
+#endif
+
+ if (strcmp(user_password, (char *) crypt(password, user_password)) != 0)
+ {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: password incorrect");
+ return -1;
+ }
+
+ if (setuid(user->pw_uid))
+ {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "setuid");
+ return -1;
+ }
+
+/* if (setgid(user->pw_gid))
+ {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "setgid");
+ return -1;
+ }
+*/
+ return 0;
+
+#endif
+
+}
+
+static int
+daemon_msg_findallif_req(struct daemon_slpars *pars, uint32 plen)
+{
+ char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
+ char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client
+ 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
+ pcap_if_t *alldevs = NULL; // pointer to the header of the interface chain
+ pcap_if_t *d; // temp pointer needed to scan the interface chain
+ struct pcap_addr *address; // pcap structure that keeps a network address of an interface
+ struct rpcap_findalldevs_if *findalldevs_if;// rpcap structure that packet all the data of an interface together
+ uint16 nif = 0; // counts the number of interface listed
+
+ // Discard the rest of the message; there shouldn't be any payload.
+ if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+ {
+ // Network error.
+ return -1;
+ }
+
+ // Retrieve the device list
+ if (pcap_findalldevs(&alldevs, errmsgbuf) == -1)
+ goto error;
+
+ if (alldevs == NULL)
+ {
+ if (rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
+ PCAP_ERR_NOREMOTEIF,
+ "No interfaces found! Make sure libpcap/WinPcap is properly installed"
+ " and you have the right to access to the remote device.",
+ errbuf) == -1)
+ {
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ return -1;
+ }
+ return 0;
+ }
+
+ // checks the number of interfaces and it computes the total length of the payload
+ for (d = alldevs; d != NULL; d = d->next)
+ {
+ nif++;
+
+ if (d->description)
+ plen+= strlen(d->description);
+ if (d->name)
+ plen+= strlen(d->name);
+
+ plen+= sizeof(struct rpcap_findalldevs_if);
+
+ for (address = d->addresses; address != NULL; address = address->next)
+ {
+ /*
+ * Send only IPv4 and IPv6 addresses over the wire.
+ */
+ switch (address->addr->sa_family)
+ {
+ case AF_INET:
+#ifdef AF_INET6
+ case AF_INET6:
+#endif
+ plen+= (sizeof(struct rpcap_sockaddr) * 4);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ // RPCAP findalldevs command
+ if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL,
+ &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf,
+ PCAP_ERRBUF_SIZE) == -1)
+ goto error;
+
+ rpcap_createhdr((struct rpcap_header *) sendbuf, pars->protocol_version,
+ RPCAP_MSG_FINDALLIF_REPLY, nif, plen);
+
+ // send the interface list
+ for (d = alldevs; d != NULL; d = d->next)
+ {
+ uint16 lname, ldescr;
+
+ findalldevs_if = (struct rpcap_findalldevs_if *) &sendbuf[sendbufidx];
+
+ if (sock_bufferize(NULL, sizeof(struct rpcap_findalldevs_if), NULL,
+ &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
+ goto error;
+
+ memset(findalldevs_if, 0, sizeof(struct rpcap_findalldevs_if));
+
+ if (d->description) ldescr = (short) strlen(d->description);
+ else ldescr = 0;
+ if (d->name) lname = (short) strlen(d->name);
+ else lname = 0;
+
+ findalldevs_if->desclen = htons(ldescr);
+ findalldevs_if->namelen = htons(lname);
+ findalldevs_if->flags = htonl(d->flags);
+
+ for (address = d->addresses; address != NULL; address = address->next)
+ {
+ /*
+ * Send only IPv4 and IPv6 addresses over the wire.
+ */
+ switch (address->addr->sa_family)
+ {
+ case AF_INET:
+#ifdef AF_INET6
+ case AF_INET6:
+#endif
+ findalldevs_if->naddr++;
+ break;
+
+ default:
+ break;
+ }
+ }
+ findalldevs_if->naddr = htons(findalldevs_if->naddr);
+
+ if (sock_bufferize(d->name, lname, sendbuf, &sendbufidx,
+ RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errmsgbuf,
+ PCAP_ERRBUF_SIZE) == -1)
+ goto error;
+
+ if (sock_bufferize(d->description, ldescr, sendbuf, &sendbufidx,
+ RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errmsgbuf,
+ PCAP_ERRBUF_SIZE) == -1)
+ goto error;
+
+ // send all addresses
+ for (address = d->addresses; address != NULL; address = address->next)
+ {
+ struct rpcap_sockaddr *sockaddr;
+
+ /*
+ * Send only IPv4 and IPv6 addresses over the wire.
+ */
+ switch (address->addr->sa_family)
+ {
+ case AF_INET:
+#ifdef AF_INET6
+ case AF_INET6:
+#endif
+ sockaddr = (struct rpcap_sockaddr *) &sendbuf[sendbufidx];
+ if (sock_bufferize(NULL, sizeof(struct rpcap_sockaddr), NULL,
+ &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
+ goto error;
+ daemon_seraddr((struct sockaddr_storage *) address->addr, sockaddr);
+
+ sockaddr = (struct rpcap_sockaddr *) &sendbuf[sendbufidx];
+ if (sock_bufferize(NULL, sizeof(struct rpcap_sockaddr), NULL,
+ &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
+ goto error;
+ daemon_seraddr((struct sockaddr_storage *) address->netmask, sockaddr);
+
+ sockaddr = (struct rpcap_sockaddr *) &sendbuf[sendbufidx];
+ if (sock_bufferize(NULL, sizeof(struct rpcap_sockaddr), NULL,
+ &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
+ goto error;
+ daemon_seraddr((struct sockaddr_storage *) address->broadaddr, sockaddr);
+
+ sockaddr = (struct rpcap_sockaddr *) &sendbuf[sendbufidx];
+ if (sock_bufferize(NULL, sizeof(struct rpcap_sockaddr), NULL,
+ &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
+ goto error;
+ daemon_seraddr((struct sockaddr_storage *) address->dstaddr, sockaddr);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ // We no longer need the device list. Free it.
+ pcap_freealldevs(alldevs);
+
+ // Send a final command that says "now send it!"
+ if (sock_send(pars->sockctrl_out, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
+ {
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ return -1;
+ }
+
+ return 0;
+
+error:
+ if (alldevs)
+ pcap_freealldevs(alldevs);
+
+ if (rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
+ PCAP_ERR_FINDALLIF, errmsgbuf, errbuf) == -1)
+ {
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ \param plen: the length of the current message (needed in order to be able
+ to discard excess data in the message, if present)
+*/
+static int
+daemon_msg_open_req(struct daemon_slpars *pars, uint32 plen, char *source, size_t sourcelen)
+{
+ char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
+ char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client
+ pcap_t *fp; // pcap_t main variable
+ int nread;
+ 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_openreply *openreply; // open reply message
+
+ if (plen > sourcelen - 1)
+ {
+ pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Source string too long");
+ goto error;
+ }
+
+ nread = sock_recv(pars->sockctrl_in, source, plen,
+ SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, PCAP_ERRBUF_SIZE);
+ if (nread == -1)
+ {
+ rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
+ return -1;
+ }
+ source[nread] = '\0';
+ plen -= nread;
+
+ // XXX - make sure it's *not* a URL; we don't support opening
+ // remote devices here.
+
+ // Open the selected device
+ // This is a fake open, since we do that only to get the needed parameters, then we close the device again
+ if ((fp = pcap_open_live(source,
+ 1500 /* fake snaplen */,
+ 0 /* no promis */,
+ 1000 /* fake timeout */,
+ errmsgbuf)) == NULL)
+ goto error;
+
+ // Now, I can send a RPCAP open reply message
+ if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx,
+ RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
+ goto error;
+
+ rpcap_createhdr((struct rpcap_header *) sendbuf, pars->protocol_version,
+ RPCAP_MSG_OPEN_REPLY, 0, sizeof(struct rpcap_openreply));
+
+ openreply = (struct rpcap_openreply *) &sendbuf[sendbufidx];
+
+ if (sock_bufferize(NULL, sizeof(struct rpcap_openreply), NULL, &sendbufidx,
+ RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
+ goto error;
+
+ memset(openreply, 0, sizeof(struct rpcap_openreply));
+ openreply->linktype = htonl(pcap_datalink(fp));
+ openreply->tzoff = 0; /* This is always 0 for live captures */
+
+ // We're done with the pcap_t.
+ pcap_close(fp);
+
+ // Send the reply.
+ if (sock_send(pars->sockctrl_out, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
+ {
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ return -1;
+ }
+ return 0;
+
+error:
+ if (rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
+ PCAP_ERR_OPEN, errmsgbuf, errbuf) == -1)
+ {
+ // That failed; log a message and give up.
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ return -1;
+ }
+
+ // Check if all the data has been read; if not, discard the data in excess
+ if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+ {
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ \param plen: the length of the current message (needed in order to be able
+ to discard excess data in the message, if present)
+*/
+static int
+daemon_msg_startcap_req(struct daemon_slpars *pars, uint32 plen, struct thread_handle *threaddata, char *source, struct session **sessionp, struct rpcap_sampling *samp_param _U_)
+{
+ char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
+ char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client
+ char portdata[PCAP_BUF_SIZE]; // temp variable needed to derive the data port
+ char peerhost[PCAP_BUF_SIZE]; // temp variable needed to derive the host name of our peer
+ struct session *session = NULL; // saves state of session
+ int status;
+ 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
+
+ // socket-related variables
+ SOCKET sockdata = INVALID_SOCKET; // socket descriptor of the data connection
+ struct addrinfo hints; // temp, needed to open a socket connection
+ struct addrinfo *addrinfo; // temp, needed to open a socket connection
+ 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
+ int ret; // return value from functions
+
+#ifndef _WIN32
+ pthread_attr_t detachedAttribute; // temp, needed to set the created thread as detached
+#endif
+
+ // RPCAP-related variables
+ struct rpcap_startcapreq startcapreq; // start capture request message
+ struct rpcap_startcapreply *startcapreply; // start capture reply message
+ int serveropen_dp; // keeps who is going to open the data connection
+
+ addrinfo = NULL;
+
+ status = rpcapd_recv(pars->sockctrl_in, (char *) &startcapreq,
+ sizeof(struct rpcap_startcapreq), &plen, errmsgbuf);
+ if (status == -1)
+ {
+ goto fatal_error;
+ }
+ if (status == -2)
+ {
+ goto error;
+ }
+
+ startcapreq.flags = ntohs(startcapreq.flags);
+
+ // Create a session structure
+ session = malloc(sizeof(struct session));
+ if (session == NULL)
+ {
+ pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Can't allocate session structure");
+ goto error;
+ }
+
+ // Open the selected device
+ if ((session->fp = pcap_open_live(source,
+ ntohl(startcapreq.snaplen),
+ (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_PROMISC) ? 1 : 0 /* local device, other flags not needed */,
+ ntohl(startcapreq.read_timeout),
+ errmsgbuf)) == NULL)
+ goto error;
+
+#if 0
+ // Apply sampling parameters
+ fp->rmt_samp.method = samp_param->method;
+ fp->rmt_samp.value = samp_param->value;
+#endif
+
+ /*
+ We're in active mode if:
+ - we're using TCP, and the user wants us to be in active mode
+ - we're using UDP
+ */
+ serveropen_dp = (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_SERVEROPEN) || (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_DGRAM) || pars->isactive;
+
+ /*
+ Gets the sockaddr structure referred to the other peer in the ctrl connection
+
+ We need that because:
+ - if we're in passive mode, we need to know the address family we want to use
+ (the same used for the ctrl socket)
+ - if we're in active mode, we need to know the network address of the other host
+ we want to connect to
+ */
+ saddrlen = sizeof(struct sockaddr_storage);
+ if (getpeername(pars->sockctrl_in, (struct sockaddr *) &saddr, &saddrlen) == -1)
+ {
+ sock_geterror("getpeername(): ", errmsgbuf, PCAP_ERRBUF_SIZE);
+ goto error;
+ }
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_socktype = (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_DGRAM) ? SOCK_DGRAM : SOCK_STREAM;
+ hints.ai_family = saddr.ss_family;
+
+ // Now we have to create a new socket to send packets
+ if (serveropen_dp) // Data connection is opened by the server toward the client
+ {
+ pcap_snprintf(portdata, sizeof portdata, "%d", ntohs(startcapreq.portdata));
+
+ // Get the name of the other peer (needed to connect to that specific network address)
+ if (getnameinfo((struct sockaddr *) &saddr, saddrlen, peerhost,
+ sizeof(peerhost), NULL, 0, NI_NUMERICHOST))
+ {
+ sock_geterror("getnameinfo(): ", errmsgbuf, PCAP_ERRBUF_SIZE);
+ goto error;
+ }
+
+ if (sock_initaddress(peerhost, portdata, &hints, &addrinfo, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
+ goto error;
+
+ if ((sockdata = sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
+ goto error;
+ }
+ else // Data connection is opened by the client toward the server
+ {
+ hints.ai_flags = AI_PASSIVE;
+
+ // Let's the server socket pick up a free network port for us
+ if (sock_initaddress(NULL, "0", &hints, &addrinfo, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
+ goto error;
+
+ if ((sockdata = sock_open(addrinfo, SOCKOPEN_SERVER, 1 /* max 1 connection in queue */, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
+ goto error;
+
+ // get the complete sockaddr structure used in the data connection
+ saddrlen = sizeof(struct sockaddr_storage);
+ if (getsockname(sockdata, (struct sockaddr *) &saddr, &saddrlen) == -1)
+ {
+ sock_geterror("getsockname(): ", errmsgbuf, PCAP_ERRBUF_SIZE);
+ goto error;
+ }
+
+ // Get the local port the system picked up
+ if (getnameinfo((struct sockaddr *) &saddr, saddrlen, NULL,
+ 0, portdata, sizeof(portdata), NI_NUMERICSERV))
+ {
+ sock_geterror("getnameinfo(): ", errmsgbuf, PCAP_ERRBUF_SIZE);
+ goto error;
+ }
+ }
+
+ // addrinfo is no longer used
+ freeaddrinfo(addrinfo);
+ addrinfo = NULL;
+
+ // Needed to send an error on the ctrl connection
+ session->sockctrl_out = pars->sockctrl_out;
+ session->protocol_version = pars->protocol_version;
+
+ // Now I can set the filter
+ ret = daemon_unpackapplyfilter(pars->sockctrl_in, session, &plen, errmsgbuf);
+ if (ret == -1)
+ {
+ // Fatal error. A message has been logged; just give up.
+ goto fatal_error;
+ }
+ if (ret == -2)
+ {
+ // Non-fatal error. Send an error message to the client.
+ goto error;
+ }
+
+ // Now, I can send a RPCAP start capture reply message
+ if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx,
+ RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
+ goto error;
+
+ rpcap_createhdr((struct rpcap_header *) sendbuf, pars->protocol_version,
+ RPCAP_MSG_STARTCAP_REPLY, 0, sizeof(struct rpcap_startcapreply));
+
+ startcapreply = (struct rpcap_startcapreply *) &sendbuf[sendbufidx];
+
+ if (sock_bufferize(NULL, sizeof(struct rpcap_startcapreply), NULL,
+ &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
+ goto error;
+
+ memset(startcapreply, 0, sizeof(struct rpcap_startcapreply));
+ startcapreply->bufsize = htonl(pcap_bufsize(session->fp));
+
+ if (!serveropen_dp)
+ {
+ unsigned short port = (unsigned short)strtoul(portdata,NULL,10);
+ startcapreply->portdata = htons(port);
+ }
+
+ if (sock_send(pars->sockctrl_out, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
+ {
+ // That failed; log a message and give up.
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ goto fatal_error;
+ }
+
+ if (!serveropen_dp)
+ {
+ SOCKET socktemp; // We need another socket, since we're going to accept() a connection
+
+ // Connection creation
+ saddrlen = sizeof(struct sockaddr_storage);
+
+ socktemp = accept(sockdata, (struct sockaddr *) &saddr, &saddrlen);
+
+ if (socktemp == INVALID_SOCKET)
+ {
+ sock_geterror("accept(): ", errbuf, PCAP_ERRBUF_SIZE);
+ rpcapd_log(LOGPRIO_ERROR, "Accept of data connection failed: %s",
+ errbuf);
+ goto error;
+ }
+
+ // Now that I accepted the connection, the server socket is no longer needed
+ sock_close(sockdata, NULL, 0);
+ sockdata = socktemp;
+ }
+
+ session->sockdata = sockdata;
+
+ // Now we have to create a new thread to receive packets
+#ifdef _WIN32
+ threaddata->thread = (HANDLE)_beginthreadex(NULL, 0, daemon_thrdatamain,
+ (void *) session, 0, NULL);
+ if (threaddata->thread == 0)
+ {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error creating the data thread");
+ goto error;
+ }
+#else
+ /* GV we need this to create the thread as detached. */
+ /* GV otherwise, the thread handle is not destroyed */
+ pthread_attr_init(&detachedAttribute);
+ pthread_attr_setdetachstate(&detachedAttribute, PTHREAD_CREATE_DETACHED);
+ ret = pthread_create(&threaddata->thread, &detachedAttribute,
+ daemon_thrdatamain, (void *) session);
+ if (ret != 0)
+ {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ ret, "Error creating the data thread");
+ pthread_attr_destroy(&detachedAttribute);
+ goto error;
+ }
+ pthread_attr_destroy(&detachedAttribute);
+#endif
+ threaddata->have_thread = 1;
+
+ // Check if all the data has been read; if not, discard the data in excess
+ if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+ goto fatal_error;
+
+ *sessionp = session;
+ return 0;
+
+error:
+ //
+ // Not a fatal error, so send the client an error message and
+ // keep serving client requests.
+ //
+ *sessionp = NULL;
+
+ if (addrinfo)
+ freeaddrinfo(addrinfo);
+
+ if (threaddata->have_thread)
+ {
+#ifdef _WIN32
+ if (session->fp)
+ {
+ pcap_breakloop(session->fp);
+ SetEvent(pcap_getevent(session->fp));
+ }
+ CloseHandle(threaddata->thread);
+#else
+ pthread_cancel(threaddata->thread);
+#endif
+ threaddata->have_thread = 0;
+ }
+
+ if (sockdata != INVALID_SOCKET)
+ sock_close(sockdata, NULL, 0);
+
+ if (session)
+ {
+ if (session->fp)
+ pcap_close(session->fp);
+ free(session);
+ }
+
+ if (rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
+ PCAP_ERR_STARTCAPTURE, errmsgbuf, errbuf) == -1)
+ {
+ // That failed; log a message and give up.
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ return -1;
+ }
+
+ // Check if all the data has been read; if not, discard the data in excess
+ if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+ {
+ // Network error.
+ return -1;
+ }
+
+ return 0;
+
+fatal_error:
+ //
+ // Fatal network error, so don't try to communicate with
+ // the client, just give up.
+ //
+ *sessionp = NULL;
+
+ if (threaddata->have_thread)
+ {
+#ifdef _WIN32
+ if (session && session->fp)
+ {
+ //
+ // Tell the data connection thread main capture
+ // loop to break out of that loop.
+ //
+ pcap_breakloop(session->fp);
+
+ //
+ // If it's currently blocked waiting for packets
+ // to arrive, try to wake it up, so it can see
+ // the "break out of the loop" indication.
+ //
+ SetEvent(pcap_getevent(session->fp));
+ }
+
+ //
+ // Wait for the thread to exit, so we don't close
+ // sockets out from under it.
+ //
+ // XXX - have a timeout, so we don't wait forever?
+ //
+ WaitForSingleObject(threaddata->thread, INFINITE);
+
+ //
+ // Release the thread handle, as we're done with
+ // it.
+ //
+ CloseHandle(threaddata->thread);
+#else
+ pthread_cancel(threaddata->thread);
+#endif
+ threaddata->have_thread = 0;
+ }
+
+ if (sockdata != INVALID_SOCKET)
+ sock_close(sockdata, NULL, 0);
+
+ if (session)
+ {
+ if (session->fp)
+ pcap_close(session->fp);
+ free(session);
+ }
+
+ return -1;
+}
+
+static int
+daemon_msg_endcap_req(struct daemon_slpars *pars, struct session *session, struct thread_handle *threaddata)
+{
+ char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
+ struct rpcap_header header;
+
+ if (threaddata->have_thread)
+ {
+#ifdef _WIN32
+ //
+ // Tell the data connection thread main capture loop to
+ // break out of that loop.
+ //
+ pcap_breakloop(session->fp);
+
+ //
+ // If it's currently blocked waiting for packets to
+ // arrive, try to wake it up, so it can see the "break
+ // out of the loop" indication.
+ //
+ SetEvent(pcap_getevent(session->fp));
+
+ //
+ // Wait for the thread to exit, so we don't close
+ // sockets out from under it.
+ //
+ // XXX - have a timeout, so we don't wait forever?
+ //
+ WaitForSingleObject(threaddata->thread, INFINITE);
+
+ //
+ // Release the thread handle, as we're done with
+ // it.
+ //
+ CloseHandle(threaddata->thread);
+#else
+ pthread_cancel(threaddata->thread);
+#endif
+ threaddata->have_thread = 0;
+ }
+ if (session->sockdata)
+ {
+ sock_close(session->sockdata, NULL, 0);
+ session->sockdata = 0;
+ }
+
+ pcap_close(session->fp);
+
+ rpcap_createhdr(&header, pars->protocol_version,
+ RPCAP_MSG_ENDCAP_REPLY, 0, 0);
+
+ if (sock_send(pars->sockctrl_out, (char *) &header, sizeof(struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1)
+ {
+ // That failed; log a message and give up.
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+daemon_unpackapplyfilter(SOCKET sockctrl_in, struct session *session, uint32 *plenp, char *errmsgbuf)
+{
+ int status;
+ struct rpcap_filter filter;
+ struct rpcap_filterbpf_insn insn;
+ struct bpf_insn *bf_insn;
+ struct bpf_program bf_prog;
+ unsigned int i;
+
+ status = rpcapd_recv(sockctrl_in, (char *) &filter,
+ sizeof(struct rpcap_filter), plenp, errmsgbuf);
+ if (status == -1)
+ {
+ return -1;
+ }
+ if (status == -2)
+ {
+ return -2;
+ }
+
+ bf_prog.bf_len = ntohl(filter.nitems);
+
+ if (ntohs(filter.filtertype) != RPCAP_UPDATEFILTER_BPF)
+ {
+ pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Only BPF/NPF filters are currently supported");
+ return -2;
+ }
+
+ bf_insn = (struct bpf_insn *) malloc (sizeof(struct bpf_insn) * bf_prog.bf_len);
+ if (bf_insn == NULL)
+ {
+ pcap_fmt_errmsg_for_errno(errmsgbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc() failed");
+ return -2;
+ }
+
+ bf_prog.bf_insns = bf_insn;
+
+ for (i = 0; i < bf_prog.bf_len; i++)
+ {
+ status = rpcapd_recv(sockctrl_in, (char *) &insn,
+ sizeof(struct rpcap_filterbpf_insn), plenp, errmsgbuf);
+ if (status == -1)
+ {
+ return -1;
+ }
+ if (status == -2)
+ {
+ return -2;
+ }
+
+ bf_insn->code = ntohs(insn.code);
+ bf_insn->jf = insn.jf;
+ bf_insn->jt = insn.jt;
+ bf_insn->k = ntohl(insn.k);
+
+ bf_insn++;
+ }
+
+ if (bpf_validate(bf_prog.bf_insns, bf_prog.bf_len) == 0)
+ {
+ pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "The filter contains bogus instructions");
+ return -2;
+ }
+
+ if (pcap_setfilter(session->fp, &bf_prog))
+ {
+ pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "RPCAP error: %s", pcap_geterr(session->fp));
+ return -2;
+ }
+
+ return 0;
+}
+
+static int
+daemon_msg_updatefilter_req(struct daemon_slpars *pars, struct session *session, uint32 plen)
+{
+ char errbuf[PCAP_ERRBUF_SIZE];
+ char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client
+ int ret; // status of daemon_unpackapplyfilter()
+ struct rpcap_header header; // keeps the answer to the updatefilter command
+
+ ret = daemon_unpackapplyfilter(pars->sockctrl_in, session, &plen, errmsgbuf);
+ if (ret == -1)
+ {
+ // Fatal error. A message has been logged; just give up.
+ return -1;
+ }
+ if (ret == -2)
+ {
+ // Non-fatal error. Send an error reply to the client.
+ goto error;
+ }
+
+ // Check if all the data has been read; if not, discard the data in excess
+ if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+ {
+ // Network error.
+ return -1;
+ }
+
+ // A response is needed, otherwise the other host does not know that everything went well
+ rpcap_createhdr(&header, pars->protocol_version,
+ RPCAP_MSG_UPDATEFILTER_REPLY, 0, 0);
+
+ if (sock_send(pars->sockctrl_out, (char *) &header, sizeof (struct rpcap_header), pcap_geterr(session->fp), PCAP_ERRBUF_SIZE))
+ {
+ // That failed; log a messsage and give up.
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ return -1;
+ }
+
+ return 0;
+
+error:
+ if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+ {
+ return -1;
+ }
+ rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
+ PCAP_ERR_UPDATEFILTER, errmsgbuf, NULL);
+
+ return 0;
+}
+
+/*!
+ \brief Received the sampling parameters from remote host and it stores in the pcap_t structure.
+*/
+static int
+daemon_msg_setsampling_req(struct daemon_slpars *pars, uint32 plen, struct rpcap_sampling *samp_param)
+{
+ char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
+ char errmsgbuf[PCAP_ERRBUF_SIZE];
+ struct rpcap_header header;
+ struct rpcap_sampling rpcap_samp;
+ int status;
+
+ status = rpcapd_recv(pars->sockctrl_in, (char *) &rpcap_samp, sizeof(struct rpcap_sampling), &plen, errmsgbuf);
+ if (status == -1)
+ {
+ return -1;
+ }
+ if (status == -2)
+ {
+ goto error;
+ }
+
+ // Save these settings in the pcap_t
+ samp_param->method = rpcap_samp.method;
+ samp_param->value = ntohl(rpcap_samp.value);
+
+ // A response is needed, otherwise the other host does not know that everything went well
+ rpcap_createhdr(&header, pars->protocol_version,
+ RPCAP_MSG_SETSAMPLING_REPLY, 0, 0);
+
+ if (sock_send(pars->sockctrl_out, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1)
+ {
+ // That failed; log a messsage and give up.
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ return -1;
+ }
+
+ if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+ {
+ return -1;
+ }
+
+ return 0;
+
+error:
+ if (rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
+ PCAP_ERR_AUTH, errmsgbuf, errbuf) == -1)
+ {
+ // That failed; log a message and give up.
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ return -1;
+ }
+
+ // Check if all the data has been read; if not, discard the data in excess
+ if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+daemon_msg_stats_req(struct daemon_slpars *pars, struct session *session, uint32 plen, struct pcap_stat *stats, unsigned int svrcapt)
+{
+ char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
+ char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client
+ 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_stats *netstats; // statistics sent on the network
+
+ // Checks that the header does not contain other data; if so, discard it
+ if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
+ {
+ // Network error.
+ return -1;
+ }
+
+ if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL,
+ &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
+ goto error;
+
+ rpcap_createhdr((struct rpcap_header *) sendbuf, pars->protocol_version,
+ RPCAP_MSG_STATS_REPLY, 0, (uint16) sizeof(struct rpcap_stats));
+
+ netstats = (struct rpcap_stats *) &sendbuf[sendbufidx];
+
+ if (sock_bufferize(NULL, sizeof(struct rpcap_stats), NULL,
+ &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
+ goto error;
+
+ if (session && session->fp)
+ {
+ if (pcap_stats(session->fp, stats) == -1)
+ {
+ pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "%s", pcap_geterr(session->fp));
+ goto error;
+ }
+
+ netstats->ifdrop = htonl(stats->ps_ifdrop);
+ netstats->ifrecv = htonl(stats->ps_recv);
+ netstats->krnldrop = htonl(stats->ps_drop);
+ netstats->svrcapt = htonl(session->TotCapt);
+ }
+ else
+ {
+ // We have to keep compatibility with old applications,
+ // which ask for statistics also when the capture has
+ // already stopped.
+ netstats->ifdrop = htonl(stats->ps_ifdrop);
+ netstats->ifrecv = htonl(stats->ps_recv);
+ netstats->krnldrop = htonl(stats->ps_drop);
+ netstats->svrcapt = htonl(svrcapt);
+ }
+
+ // Send the packet
+ if (sock_send(pars->sockctrl_out, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
+ {
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ return -1;
+ }
+
+ return 0;
+
+error:
+ rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
+ PCAP_ERR_GETSTATS, errmsgbuf, NULL);
+ return 0;
+}
+
+#ifdef _WIN32
+static unsigned __stdcall
+#else
+static void *
+#endif
+daemon_thrdatamain(void *ptr)
+{
+ char errbuf[PCAP_ERRBUF_SIZE + 1]; // error buffer
+ struct session *session; // pointer to the struct session for this session
+ int retval; // general variable used to keep the return value of other functions
+ struct rpcap_pkthdr *net_pkt_header;// header of the packet
+ struct pcap_pkthdr *pkt_header; // pointer to the buffer that contains the header of the current packet
+ u_char *pkt_data; // pointer to the buffer that contains the current packet
+ size_t sendbufsize; // size for the send buffer
+ char *sendbuf; // temporary buffer in which data to be sent is buffered
+ int sendbufidx; // index which keeps the number of bytes currently buffered
+ int status;
+
+ session = (struct session *) ptr;
+
+ session->TotCapt = 0; // counter which is incremented each time a packet is received
+
+ // Initialize errbuf
+ memset(errbuf, 0, sizeof(errbuf));
+
+ //
+ // We need a buffer large enough to hold a buffer large enough
+ // for a maximum-size packet for this pcap_t.
+ //
+ if (pcap_snapshot(session->fp) < 0)
+ {
+ //
+ // The snapshot length is negative.
+ // This "should not happen".
+ //
+ rpcapd_log(LOGPRIO_ERROR,
+ "Unable to allocate the buffer for this child thread: snapshot length of %d is negative",
+ pcap_snapshot(session->fp));
+ sendbuf = NULL; // we can't allocate a buffer, so nothing to free
+ goto error;
+ }
+ //
+ // size_t is unsigned, and the result of pcap_snapshot() is signed;
+ // on no platform that we support is int larger than size_t.
+ // This means that, unless the extra information we prepend to
+ // a maximum-sized packet is impossibly large, the sum of the
+ // snapshot length and the size of that extra information will
+ // fit in a size_t.
+ //
+ // So we don't need to make sure that sendbufsize will overflow.
+ //
+ sendbufsize = sizeof(struct rpcap_header) + sizeof(struct rpcap_pkthdr) + pcap_snapshot(session->fp);
+ sendbuf = (char *) malloc (sendbufsize);
+ if (sendbuf == NULL)
+ {
+ rpcapd_log(LOGPRIO_ERROR,
+ "Unable to allocate the buffer for this child thread");
+ goto error;
+ }
+
+#ifndef _WIN32
+ // Modify thread params so that it can be killed at any time
+ retval = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+ if (retval != 0)
+ {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ retval, "pthread_setcancelstate");
+ rpcapd_log(LOGPRIO_ERROR,
+ "Can't set cancel state on data thread: %s", errbuf);
+ goto error;
+ }
+ retval = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+ if (retval != 0)
+ {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ retval, "pthread_setcanceltype");
+ rpcapd_log(LOGPRIO_ERROR,
+ "Can't set cancel type on data thread: %s", errbuf);
+ goto error;
+ }
+#endif
+
+ // Retrieve the packets
+ while ((retval = pcap_next_ex(session->fp, &pkt_header, (const u_char **) &pkt_data)) >= 0) // cast to avoid a compiler warning
+ {
+ if (retval == 0) // Read timeout elapsed
+ continue;
+
+ sendbufidx = 0;
+
+ // Bufferize the general header
+ if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL,
+ &sendbufidx, sendbufsize, SOCKBUF_CHECKONLY, errbuf,
+ PCAP_ERRBUF_SIZE) == -1)
+ {
+ rpcapd_log(LOGPRIO_ERROR,
+ "sock_bufferize() error sending packet message: %s",
+ errbuf);
+ goto error;
+ }
+
+ rpcap_createhdr((struct rpcap_header *) sendbuf,
+ session->protocol_version, RPCAP_MSG_PACKET, 0,
+ (uint16) (sizeof(struct rpcap_pkthdr) + pkt_header->caplen));
+
+ net_pkt_header = (struct rpcap_pkthdr *) &sendbuf[sendbufidx];
+
+ // Bufferize the pkt header
+ if (sock_bufferize(NULL, sizeof(struct rpcap_pkthdr), NULL,
+ &sendbufidx, sendbufsize, SOCKBUF_CHECKONLY, errbuf,
+ PCAP_ERRBUF_SIZE) == -1)
+ {
+ rpcapd_log(LOGPRIO_ERROR,
+ "sock_bufferize() error sending packet message: %s",
+ errbuf);
+ goto error;
+ }
+
+ net_pkt_header->caplen = htonl(pkt_header->caplen);
+ net_pkt_header->len = htonl(pkt_header->len);
+ net_pkt_header->npkt = htonl(++(session->TotCapt));
+ net_pkt_header->timestamp_sec = htonl(pkt_header->ts.tv_sec);
+ net_pkt_header->timestamp_usec = htonl(pkt_header->ts.tv_usec);
+
+ // Bufferize the pkt data
+ if (sock_bufferize((char *) pkt_data, pkt_header->caplen,
+ sendbuf, &sendbufidx, sendbufsize, SOCKBUF_BUFFERIZE,
+ errbuf, PCAP_ERRBUF_SIZE) == -1)
+ {
+ rpcapd_log(LOGPRIO_ERROR,
+ "sock_bufferize() error sending packet message: %s",
+ errbuf);
+ goto error;
+ }
+
+ // Send the packet
+ // If the client dropped the connection, don't report an
+ // error, just quit.
+ status = sock_send(session->sockdata, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE);
+ if (status < 0)
+ {
+ if (status == -1)
+ {
+ //
+ // Error other than "client closed the
+ // connection out from under us"; report
+ // it.
+ //
+ rpcapd_log(LOGPRIO_ERROR,
+ "Send of packet to client failed: %s",
+ errbuf);
+ }
+
+ //
+ // Give up in either case.
+ //
+ goto error;
+ }
+ }
+
+ if (retval == -1)
+ {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error reading the packets: %s", pcap_geterr(session->fp));
+ rpcap_senderror(session->sockctrl_out, session->protocol_version,
+ PCAP_ERR_READEX, errbuf, NULL);
+ goto error;
+ }
+
+error:
+ closesocket(session->sockdata);
+ session->sockdata = 0;
+
+ free(sendbuf);
+
+ return 0;
+}
+
+/*!
+ \brief It serializes a network address.
+
+ It accepts a 'sockaddr_storage' structure as input, and it converts it appropriately into a format
+ that can be used to be sent on the network. Basically, it applies all the hton()
+ conversion required to the input variable.
+
+ \param sockaddrin a 'sockaddr_storage' pointer to the variable that has to be
+ serialized. This variable can be both a 'sockaddr_in' and 'sockaddr_in6'.
+
+ \param sockaddrout an 'rpcap_sockaddr' pointer to the variable that will contain
+ the serialized data. This variable has to be allocated by the user.
+
+ \warning This function supports only AF_INET and AF_INET6 address families.
+*/
+static void
+daemon_seraddr(struct sockaddr_storage *sockaddrin, struct rpcap_sockaddr *sockaddrout)
+{
+ memset(sockaddrout, 0, sizeof(struct sockaddr_storage));
+
+ // There can be the case in which the sockaddrin is not available
+ if (sockaddrin == NULL) return;
+
+ // Warning: we support only AF_INET and AF_INET6
+ switch (sockaddrin->ss_family)
+ {
+ case AF_INET:
+ {
+ struct sockaddr_in *sockaddrin_ipv4;
+ struct rpcap_sockaddr_in *sockaddrout_ipv4;
+
+ sockaddrin_ipv4 = (struct sockaddr_in *) sockaddrin;
+ sockaddrout_ipv4 = (struct rpcap_sockaddr_in *) sockaddrout;
+ sockaddrout_ipv4->family = htons(RPCAP_AF_INET);
+ sockaddrout_ipv4->port = htons(sockaddrin_ipv4->sin_port);
+ memcpy(&sockaddrout_ipv4->addr, &sockaddrin_ipv4->sin_addr, sizeof(sockaddrout_ipv4->addr));
+ memset(sockaddrout_ipv4->zero, 0, sizeof(sockaddrout_ipv4->zero));
+ break;
+ }
+
+#ifdef AF_INET6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sockaddrin_ipv6;
+ struct rpcap_sockaddr_in6 *sockaddrout_ipv6;
+
+ sockaddrin_ipv6 = (struct sockaddr_in6 *) sockaddrin;
+ sockaddrout_ipv6 = (struct rpcap_sockaddr_in6 *) sockaddrout;
+ sockaddrout_ipv6->family = htons(RPCAP_AF_INET6);
+ sockaddrout_ipv6->port = htons(sockaddrin_ipv6->sin6_port);
+ sockaddrout_ipv6->flowinfo = htonl(sockaddrin_ipv6->sin6_flowinfo);
+ memcpy(&sockaddrout_ipv6->addr, &sockaddrin_ipv6->sin6_addr, sizeof(sockaddrout_ipv6->addr));
+ sockaddrout_ipv6->scope_id = htonl(sockaddrin_ipv6->sin6_scope_id);
+ break;
+ }
+#endif
+ }
+}
+
+
+/*!
+ \brief Suspends a thread for secs seconds.
+*/
+void sleep_secs(int secs)
+{
+#ifdef _WIN32
+ Sleep(secs*1000);
+#else
+ unsigned secs_remaining;
+
+ if (secs <= 0)
+ return;
+ secs_remaining = secs;
+ while (secs_remaining != 0)
+ secs_remaining = sleep(secs_remaining);
+#endif
+}
+
+/*
+ * Read the header of a message.
+ */
+static int
+rpcapd_recv_msg_header(SOCKET sock, struct rpcap_header *headerp)
+{
+ int nread;
+ char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
+
+ nread = sock_recv(sock, (char *) headerp, sizeof(struct rpcap_header),
+ SOCK_RECEIVEALL_YES|SOCK_EOF_ISNT_ERROR, errbuf, PCAP_ERRBUF_SIZE);
+ if (nread == -1)
+ {
+ // Network error.
+ rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
+ return -1;
+ }
+ if (nread == 0)
+ {
+ // Immediate EOF; that's treated like a close message.
+ return -2;
+ }
+ headerp->plen = ntohl(headerp->plen);
+ return 0;
+}
+
+/*
+ * 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
+rpcapd_recv(SOCKET sock, char *buffer, size_t toread, uint32 *plen, char *errmsgbuf)
+{
+ int nread;
+ char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
+
+ if (toread > *plen)
+ {
+ // Tell the client and continue.
+ pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Message payload is too short");
+ return -2;
+ }
+ nread = sock_recv(sock, buffer, toread,
+ SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, PCAP_ERRBUF_SIZE);
+ if (nread == -1)
+ {
+ rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
+ return -1;
+ }
+ *plen -= nread;
+ return 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
+rpcapd_discard(SOCKET sock, uint32 len)
+{
+ char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
+
+ if (len != 0)
+ {
+ if (sock_discard(sock, len, errbuf, PCAP_ERRBUF_SIZE) == -1)
+ {
+ // Network error.
+ rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
+ return -1;
+ }
+ }
+ return 0;
+}
diff --git a/rpcapd/daemon.h b/rpcapd/daemon.h
new file mode 100644
index 00000000..bd240b80
--- /dev/null
+++ b/rpcapd/daemon.h
@@ -0,0 +1,45 @@
+/*
+ * 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 __DAEMON_H__
+#define __DAEMON_H__
+
+//
+// Returns 1 if the client closed the control connection explicitly, 0
+// otherwise; used in active mode only.
+//
+int daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, int isactive,
+ int nullAuthAllowed);
+
+void sleep_secs(int secs);
+
+#endif
diff --git a/rpcapd/fileconf.c b/rpcapd/fileconf.c
new file mode 100644
index 00000000..ab1e9dd3
--- /dev/null
+++ b/rpcapd/fileconf.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 1987, 1993, 1994
+ * 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 University of
+ * California, Berkeley and its contributors.
+ * 4. 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 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
+
+#include "ftmacros.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <pcap.h> // for PCAP_ERRBUF_SIZE
+
+#include "sockutils.h" // for SOCK_DEBUG_MESSAGE
+#include "portability.h"
+#include "rpcapd.h"
+#include "config_params.h" // configuration file parameters
+#include "fileconf.h"
+#include "rpcap-protocol.h"
+
+static int strrem(char *string, char chr);
+
+void fileconf_read(void)
+{
+ FILE *fp;
+ char msg[PCAP_ERRBUF_SIZE + 1];
+ int i;
+
+ if ((fp = fopen(loadfile, "r")) != NULL)
+ {
+ char line[MAX_LINE + 1];
+ char *ptr;
+
+ hostlist[0] = 0;
+ i = 0;
+
+ while (fgets(line, MAX_LINE, fp) != NULL)
+ {
+ if (line[0] == '\n') continue; // Blank line
+ if (line[0] == '\r') continue; // Blank line
+ if (line[0] == '#') continue; // Comment
+
+ ptr = strstr(line, "ActiveClient");
+ if (ptr)
+ {
+ char *address, *port;
+ char *lasts;
+
+ ptr = strchr(ptr, '=') + 1;
+ address = pcap_strtok_r(ptr, RPCAP_HOSTLIST_SEP, &lasts);
+
+ if ((address != NULL) && (i < MAX_ACTIVE_LIST))
+ {
+ port = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts);
+ strlcpy(activelist[i].address, address, MAX_LINE);
+
+ if (strcmp(port, "DEFAULT") == 0) // the user choose a custom port
+ strlcpy(activelist[i].port, RPCAP_DEFAULT_NETPORT_ACTIVE, MAX_LINE);
+ else
+ strlcpy(activelist[i].port, port, MAX_LINE);
+
+ activelist[i].address[MAX_LINE] = 0;
+ activelist[i].port[MAX_LINE] = 0;
+ }
+ else
+ SOCK_DEBUG_MESSAGE("Only MAX_ACTIVE_LIST active connections are currently supported.");
+
+ i++;
+ continue;
+ }
+
+ ptr = strstr(line, "PassiveClient");
+ if (ptr)
+ {
+ ptr = strchr(ptr, '=') + 1;
+ strlcat(hostlist, ptr, MAX_HOST_LIST);
+ strlcat(hostlist, ",", MAX_HOST_LIST);
+ continue;
+ }
+
+ ptr = strstr(line, "NullAuthPermit");
+ if (ptr)
+ {
+ ptr = strstr(ptr, "YES");
+ if (ptr)
+ nullAuthAllowed = 1;
+ else
+ nullAuthAllowed = 0;
+ continue;
+ }
+ }
+
+ // clear the remaining fields of the active list
+ while (i < MAX_ACTIVE_LIST)
+ {
+ activelist[i].address[0] = 0;
+ activelist[i].port[0] = 0;
+ i++;
+ }
+
+ // Remove all '\n' and '\r' from the strings
+ strrem(hostlist, '\r');
+ strrem(hostlist, '\n');
+
+ pcap_snprintf(msg, PCAP_ERRBUF_SIZE, "New passive host list: %s\n\n", hostlist);
+ SOCK_DEBUG_MESSAGE(msg);
+ fclose(fp);
+ }
+}
+
+int fileconf_save(const char *savefile)
+{
+ FILE *fp;
+
+ if ((fp = fopen(savefile, "w")) != NULL)
+ {
+ char *token; /*, *port;*/ // temp, needed to separate items into the hostlist
+ char temphostlist[MAX_HOST_LIST + 1];
+ int i = 0;
+ char *lasts;
+
+ fprintf(fp, "# Configuration file help.\n\n");
+
+ // Save list of clients which are allowed to connect to us in passive mode
+ fprintf(fp, "# Hosts which are allowed to connect to this server (passive mode)\n");
+ fprintf(fp, "# Format: PassiveClient = <name or address>\n\n");
+
+ strncpy(temphostlist, hostlist, MAX_HOST_LIST);
+ temphostlist[MAX_HOST_LIST] = 0;
+
+ token = pcap_strtok_r(temphostlist, RPCAP_HOSTLIST_SEP, &lasts);
+ while(token != NULL)
+ {
+ fprintf(fp, "PassiveClient = %s\n", token);
+ token = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts);
+ }
+
+
+ // Save list of clients which are allowed to connect to us in active mode
+ fprintf(fp, "\n\n");
+ fprintf(fp, "# Hosts to which this server is trying to connect to (active mode)\n");
+ fprintf(fp, "# Format: ActiveClient = <name or address>, <port | DEFAULT>\n\n");
+
+
+ while ((i < MAX_ACTIVE_LIST) && (activelist[i].address[0] != 0))
+ {
+ fprintf(fp, "ActiveClient = %s, %s\n", activelist[i].address, activelist[i].port);
+ i++;
+ }
+
+ // Save if we want to permit NULL authentication
+ fprintf(fp, "\n\n");
+ fprintf(fp, "# Permit NULL authentication: YES or NOT\n\n");
+
+ if (nullAuthAllowed)
+ fprintf(fp, "NullAuthPermit = YES\n");
+ else
+ fprintf(fp, "NullAuthPermit = NO\n");
+
+ fclose(fp);
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+
+}
+
+static int strrem(char *string, char chr)
+{
+ char *pos;
+ int num = 0;
+ int len, i;
+
+ while ((pos = strchr(string, chr)) != NULL)
+ {
+ num++;
+ len = strlen(pos);
+ for (i = 0; i < len; i++)
+ pos[i] = pos[i+1];
+ }
+
+ return num;
+}
diff --git a/rpcapd/fileconf.h b/rpcapd/fileconf.h
new file mode 100644
index 00000000..912dd326
--- /dev/null
+++ b/rpcapd/fileconf.h
@@ -0,0 +1,39 @@
+/*
+ * 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 __FILECONF_H__
+#define __FILECONF_H__
+
+void fileconf_read(void);
+int fileconf_save(const char *savefile);
+
+#endif
diff --git a/rpcapd/log-stderr.c b/rpcapd/log-stderr.c
new file mode 100644
index 00000000..5af6f2e5
--- /dev/null
+++ b/rpcapd/log-stderr.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include "log.h"
+
+void
+rpcapd_log_init(void)
+{
+}
+
+void
+rpcapd_log(log_priority priority, const char *message, ...)
+{
+ const char *tag;
+ va_list ap;
+
+ switch (priority) {
+
+ case LOGPRIO_INFO:
+ tag = "";
+ break;
+
+ case LOGPRIO_WARNING:
+ tag = "warning: ";
+ break;
+
+ case LOGPRIO_ERROR:
+ tag = "error: ";
+ break;
+
+ default:
+ abort();
+ /* NOTREACHED */
+ }
+
+ fprintf(stderr, "rpcapd: %s", tag);
+ va_start(ap, message);
+ vfprintf(stderr, message, ap);
+ va_end(ap);
+ putc('\n', stderr);
+}
diff --git a/rpcapd/log.h b/rpcapd/log.h
new file mode 100644
index 00000000..b3806e1e
--- /dev/null
+++ b/rpcapd/log.h
@@ -0,0 +1,12 @@
+#include "pcap/funcattrs.h"
+
+extern void rpcapd_log_init(void);
+
+typedef enum {
+ LOGPRIO_INFO,
+ LOGPRIO_WARNING,
+ LOGPRIO_ERROR
+} log_priority;
+
+extern void rpcapd_log(log_priority priority,
+ PCAP_FORMAT_STRING(const char *message), ...) PCAP_PRINTFLIKE(2, 3);
diff --git a/rpcapd/org.tcpdump.rpcapd.plist b/rpcapd/org.tcpdump.rpcapd.plist
new file mode 100644
index 00000000..db3223a7
--- /dev/null
+++ b/rpcapd/org.tcpdump.rpcapd.plist
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>Disabled</key>
+ <false/>
+ <key>Label</key>
+ <string>com.tcpdump.rpcapd</string>
+ <key>Program</key>
+ <string>/usr/local/libexec/rpcapd</string>
+ <key>ProgramArguments</key>
+ <array>
+ <string>/usr/local/libexec/rpcapd</string>
+ <string>-i</string>
+ </array>
+ <key>Sockets</key>
+ <dict>
+ <key>Listeners</key>
+ <dict>
+ <key>SockServiceName</key>
+ <string>2002</string>
+ </dict>
+ </dict>
+ <key>inetdCompatibility</key>
+ <dict>
+ <key>Wait</key>
+ <false/>
+ </dict>
+</dict>
+</plist>
diff --git a/rpcapd/rpcapd.c b/rpcapd/rpcapd.c
new file mode 100644
index 00000000..e8b3b1d6
--- /dev/null
+++ b/rpcapd/rpcapd.c
@@ -0,0 +1,1309 @@
+/*
+ * 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.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "ftmacros.h"
+
+#include <errno.h> // for the errno variable
+#include <string.h> // for strtok, etc
+#include <stdlib.h> // for malloc(), free(), ...
+#include <pcap.h> // for PCAP_ERRBUF_SIZE
+#include <signal.h> // for signal()
+
+#include "fmtutils.h"
+#include "sockutils.h" // for socket calls
+#include "varattrs.h" // for _U_
+#include "portability.h"
+#include "rpcapd.h"
+#include "config_params.h" // configuration file parameters
+#include "fileconf.h" // for the configuration file management
+#include "rpcap-protocol.h"
+#include "daemon.h" // the true main() method of this daemon
+#include "log.h"
+
+#ifdef _WIN32
+ #include <process.h> // for thread stuff
+ #include "win32-svc.h" // for Win32 service stuff
+ #include "getopt.h" // for getopt()-for-Windows
+#else
+ #include <fcntl.h> // for open()
+ #include <unistd.h> // for exit()
+ #include <sys/wait.h> // waitpid()
+#endif
+
+//
+// Element in list of sockets on which we're listening for connections.
+//
+struct listen_sock {
+ struct listen_sock *next;
+ SOCKET sock;
+};
+
+// Global variables
+char hostlist[MAX_HOST_LIST + 1]; //!< Keeps the list of the hosts that are allowed to connect to this server
+struct active_pars activelist[MAX_ACTIVE_LIST]; //!< Keeps the list of the hosts (host, port) on which I want to connect to (active mode)
+int nullAuthAllowed; //!< '1' if we permit NULL authentication, '0' otherwise
+static struct listen_sock *listen_socks; //!< sockets on which we listen
+char loadfile[MAX_LINE + 1]; //!< Name of the file from which we have to load the configuration
+static int passivemode = 1; //!< '1' if we want to run in passive mode as well
+static struct addrinfo mainhints; //!< temporary struct to keep settings needed to open the new socket
+static char address[MAX_LINE + 1]; //!< keeps the network address (either numeric or literal) to bind to
+static char port[MAX_LINE + 1]; //!< keeps the network port to bind to
+#ifdef _WIN32
+static HANDLE state_change_event; //!< event to signal that a state change should take place
+#endif
+static volatile sig_atomic_t shutdown_server; //!< '1' if the server is to shut down
+static volatile sig_atomic_t reread_config; //!< '1' if the server is to re-read its configuration
+
+extern char *optarg; // for getopt()
+
+// Function definition
+#ifdef _WIN32
+static unsigned __stdcall main_active(void *ptr);
+static BOOL WINAPI main_ctrl_event(DWORD);
+#else
+static void *main_active(void *ptr);
+static void main_terminate(int sign);
+static void main_reread_config(int sign);
+#endif
+static void accept_connections(void);
+static void accept_connection(SOCKET listen_sock);
+#ifndef _WIN32
+static void main_reap_children(int sign);
+#endif
+#ifdef _WIN32
+static unsigned __stdcall main_passive_serviceloop_thread(void *ptr);
+#endif
+
+#define RPCAP_ACTIVE_WAIT 30 /* Waiting time between two attempts to open a connection, in active mode (default: 30 sec) */
+
+/*!
+ \brief Prints the usage screen if it is launched in console mode.
+*/
+static void printusage(void)
+{
+ const char *usagetext =
+ "USAGE:"
+ " " PROGRAM_NAME " [-b <address>] [-p <port>] [-4] [-l <host_list>] [-a <host,port>]\n"
+ " [-n] [-v] [-d] "
+#ifndef _WIN32
+ "[-i] "
+#endif
+ "[-s <config_file>] [-f <config_file>]\n\n"
+ " -b <address> the address to bind to (either numeric or literal).\n"
+ " Default: binds to all local IPv4 and IPv6 addresses\n\n"
+ " -p <port> the port to bind to.\n"
+ " Default: binds to port " RPCAP_DEFAULT_NETPORT "\n\n"
+ " -4 use only IPv4.\n"
+ " Default: use both IPv4 and IPv6 waiting sockets\n\n"
+ " -l <host_list> a file that contains a list of hosts that are allowed\n"
+ " to connect to this server (if more than one, list them one\n"
+ " per line).\n"
+ " We suggest to use literal names (instead of numeric ones)\n"
+ " in order to avoid problems with different address families.\n\n"
+ " -n permit NULL authentication (usually used with '-l')\n\n"
+ " -a <host,port> run in active mode when connecting to 'host' on port 'port'\n"
+ " In case 'port' is omitted, the default port (" RPCAP_DEFAULT_NETPORT_ACTIVE ") is used\n\n"
+ " -v run in active mode only (default: if '-a' is specified, it\n"
+ " accepts passive connections as well)\n\n"
+ " -d run in daemon mode (UNIX only) or as a service (Win32 only)\n"
+ " Warning (Win32): this switch is provided automatically when\n"
+ " the service is started from the control panel\n\n"
+#ifndef _WIN32
+ " -i run in inetd mode (UNIX only)\n\n"
+#endif
+ " -s <config_file> save the current configuration to file\n\n"
+ " -f <config_file> load the current configuration from file; all switches\n"
+ " specified from the command line are ignored\n\n"
+ " -h print this help screen\n\n";
+
+ (void)fprintf(stderr, "RPCAPD, a remote packet capture daemon.\n"
+ "Compiled with %s\n\n", pcap_lib_version());
+ printf("%s", usagetext);
+}
+
+
+
+//! Program main
+int main(int argc, char *argv[])
+{
+ char savefile[MAX_LINE + 1]; // name of the file on which we have to save the configuration
+ int isdaemon = 0; // Non-zero if the user wants to run this program as a daemon
+#ifndef _WIN32
+ int isrunbyinetd = 0; // Non-zero if this is being run by inetd or something inetd-like
+#endif
+ int retval; // keeps the returning value from several functions
+ char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
+#ifndef _WIN32
+ struct sigaction action;
+#endif
+
+ savefile[0] = 0;
+ loadfile[0] = 0;
+ hostlist[0] = 0;
+
+ // Initialize errbuf
+ memset(errbuf, 0, sizeof(errbuf));
+
+ if (sock_init(errbuf, PCAP_ERRBUF_SIZE) == -1)
+ {
+ SOCK_DEBUG_MESSAGE(errbuf);
+ exit(-1);
+ }
+
+ strncpy(address, RPCAP_DEFAULT_NETADDR, MAX_LINE);
+ strncpy(port, RPCAP_DEFAULT_NETPORT, MAX_LINE);
+
+ // Prepare to open a new server socket
+ memset(&mainhints, 0, sizeof(struct addrinfo));
+
+ mainhints.ai_family = PF_UNSPEC;
+ mainhints.ai_flags = AI_PASSIVE; // Ready to a bind() socket
+ mainhints.ai_socktype = SOCK_STREAM;
+
+ // Getting the proper command line options
+ while ((retval = getopt(argc, argv, "b:dhip:4l:na:s:f:v")) != -1)
+ {
+ switch (retval)
+ {
+ case 'b':
+ strncpy(address, optarg, MAX_LINE);
+ break;
+ case 'p':
+ strncpy(port, optarg, MAX_LINE);
+ break;
+ case '4':
+ mainhints.ai_family = PF_INET; // IPv4 server only
+ break;
+ case 'd':
+ isdaemon = 1;
+ break;
+ case 'i':
+#ifdef _WIN32
+ printusage();
+ exit(1);
+#else
+ isrunbyinetd = 1;
+#endif
+ break;
+ case 'n':
+ nullAuthAllowed = 1;
+ break;
+ case 'v':
+ passivemode = 0;
+ break;
+ case 'l':
+ {
+ strncpy(hostlist, optarg, sizeof(hostlist));
+ break;
+ }
+ case 'a':
+ {
+ char *tmpaddress, *tmpport;
+ char *lasts;
+ int i = 0;
+
+ tmpaddress = pcap_strtok_r(optarg, RPCAP_HOSTLIST_SEP, &lasts);
+
+ while ((tmpaddress != NULL) && (i < MAX_ACTIVE_LIST))
+ {
+ tmpport = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts);
+
+ strlcpy(activelist[i].address, tmpaddress, MAX_LINE);
+
+ if ((tmpport == NULL) || (strcmp(tmpport, "DEFAULT") == 0)) // the user choose a custom port
+ strlcpy(activelist[i].port, RPCAP_DEFAULT_NETPORT_ACTIVE, MAX_LINE);
+ else
+ strlcpy(activelist[i].port, tmpport, MAX_LINE);
+
+ tmpaddress = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts);
+
+ i++;
+ }
+
+ if (i > MAX_ACTIVE_LIST)
+ SOCK_DEBUG_MESSAGE("Only MAX_ACTIVE_LIST active connections are currently supported.");
+
+ // I don't initialize the remaining part of the structure, since
+ // it is already zeroed (it is a global var)
+ break;
+ }
+ case 'f':
+ strlcpy(loadfile, optarg, MAX_LINE);
+ break;
+ case 's':
+ strlcpy(savefile, optarg, MAX_LINE);
+ break;
+ case 'h':
+ printusage();
+ exit(0);
+ break;
+ default:
+ exit(1);
+ break;
+ }
+ }
+
+#ifndef _WIN32
+ if (isdaemon && isrunbyinetd)
+ {
+ fprintf(stderr, "rpcapd: -d and -i can't be used together\n");
+ exit(1);
+ }
+#endif
+
+ if (savefile[0] && fileconf_save(savefile))
+ SOCK_DEBUG_MESSAGE("Error when saving the configuration to file");
+
+ // If the file does not exist, it keeps the settings provided by the command line
+ if (loadfile[0])
+ fileconf_read();
+
+#ifdef WIN32
+ //
+ // Create a handle to signal the main loop to tell it to do
+ // something.
+ //
+ state_change_event = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (state_change_event == NULL)
+ {
+ sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
+ rpcapd_log(LOGPRIO_ERROR, "Can't create state change event: %s",
+ errbuf);
+ exit(2);
+ }
+
+ //
+ // Catch control signals.
+ //
+ if (!SetConsoleCtrlHandler(main_ctrl_event, TRUE))
+ {
+ sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
+ rpcapd_log(LOGPRIO_ERROR, "Can't set control handler: %s",
+ errbuf);
+ exit(2);
+ }
+#else
+ memset(&action, 0, sizeof (action));
+ action.sa_handler = main_terminate;
+ action.sa_flags = 0;
+ sigemptyset(&action.sa_mask);
+ sigaction(SIGTERM, &action, NULL);
+ memset(&action, 0, sizeof (action));
+ action.sa_handler = main_reap_children;
+ action.sa_flags = 0;
+ sigemptyset(&action.sa_mask);
+ sigaction(SIGCHLD, &action, NULL);
+ // Ignore SIGPIPE - we'll get EPIPE when trying to write to a closed
+ // connection, we don't want to get killed by a signal in that case
+ signal(SIGPIPE, SIG_IGN);
+#endif
+
+#ifndef _WIN32
+ if (isrunbyinetd)
+ {
+ //
+ // -i was specified, indicating that this is being run
+ // by inetd or something that can run network daemons
+ // as if it were inetd (xinetd, launchd, systemd, etc.).
+ //
+ // Our standard input is the input side of a connection,
+ // and our standard output is the output side of a
+ // connection.
+ //
+ int sockctrl_in, sockctrl_out;
+ int devnull_fd;
+
+ //
+ // Duplicate the standard input and output, making them
+ // the input and output side of the control connection.
+ //
+ sockctrl_in = dup(0);
+ if (sockctrl_in == -1)
+ {
+ sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
+ rpcapd_log(LOGPRIO_ERROR, "Can't dup standard input: %s",
+ errbuf);
+ exit(2);
+ }
+ sockctrl_out = dup(1);
+ if (sockctrl_out == -1)
+ {
+ sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
+ rpcapd_log(LOGPRIO_ERROR, "Can't dup standard output: %s",
+ errbuf);
+ exit(2);
+ }
+
+ //
+ // Try to set the standard input and output to /dev/null.
+ //
+ devnull_fd = open("/dev/null", O_RDWR);
+ if (devnull_fd != -1)
+ {
+ //
+ // If this fails, just drive on.
+ //
+ (void)dup2(devnull_fd, 0);
+ (void)dup2(devnull_fd, 1);
+ close(devnull_fd);
+ }
+
+ //
+ // Handle this client.
+ // This is passive mode, so we don't care whether we were
+ // told by the client to close.
+ //
+ (void)daemon_serviceloop(sockctrl_in, sockctrl_out, 0,
+ nullAuthAllowed);
+
+ //
+ // Nothing more to do.
+ //
+ exit(0);
+ }
+#endif
+
+ if (isdaemon)
+ {
+ //
+ // This is being run as a daemon.
+ // On UN*X, it might be manually run, or run from an
+ // rc file.
+ //
+#ifndef _WIN32
+ int pid;
+
+ //
+ // Daemonize ourselves.
+ //
+ // Unix Network Programming, pg 336
+ //
+ if ((pid = fork()) != 0)
+ exit(0); // Parent terminates
+
+ // First child continues
+ // Set daemon mode
+ setsid();
+
+ // generated under unix with 'kill -HUP', needed to reload the configuration
+ memset(&action, 0, sizeof (action));
+ action.sa_handler = main_reread_config;
+ action.sa_flags = 0;
+ sigemptyset(&action.sa_mask);
+ sigaction(SIGHUP, &action, NULL);
+
+ if ((pid = fork()) != 0)
+ exit(0); // First child terminates
+
+ // LINUX WARNING: the current linux implementation of pthreads requires a management thread
+ // to handle some hidden stuff. So, as soon as you create the first thread, two threads are
+ // created. Fom this point on, the number of threads active are always one more compared
+ // to the number you're expecting
+
+ // Second child continues
+// umask(0);
+// chdir("/");
+#else
+ //
+ // This is being run as a service on Windows.
+ //
+ // If this call succeeds, it is blocking on Win32
+ //
+ if (svc_start() != 1)
+ SOCK_DEBUG_MESSAGE("Unable to start the service");
+
+ // When the previous call returns, the entire application has to be stopped.
+ exit(0);
+#endif
+ }
+ else // Console mode
+ {
+#ifndef _WIN32
+ // Enable the catching of Ctrl+C
+ memset(&action, 0, sizeof (action));
+ action.sa_handler = main_terminate;
+ action.sa_flags = 0;
+ sigemptyset(&action.sa_mask);
+ sigaction(SIGINT, &action, NULL);
+
+ // generated under unix with 'kill -HUP', needed to reload the configuration
+ // We do not have this kind of signal in Win32
+ memset(&action, 0, sizeof (action));
+ action.sa_handler = main_reread_config;
+ action.sa_flags = 0;
+ sigemptyset(&action.sa_mask);
+ sigaction(SIGHUP, &action, NULL);
+#endif
+
+ printf("Press CTRL + C to stop the server...\n");
+ }
+
+ // If we're a Win32 service, we have already called this function in the service_main
+ main_startup();
+
+ // The code should never arrive here (since the main_startup is blocking)
+ // however this avoids a compiler warning
+ exit(0);
+}
+
+void main_startup(void)
+{
+ char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
+ struct addrinfo *addrinfo; // keeps the addrinfo chain; required to open a new socket
+ int i;
+#ifdef _WIN32
+ HANDLE threadId; // handle for the subthread
+#else
+ pid_t pid;
+#endif
+
+ i = 0;
+ addrinfo = NULL;
+ memset(errbuf, 0, sizeof(errbuf));
+
+ // Starts all the active threads
+ while ((i < MAX_ACTIVE_LIST) && (activelist[i].address[0] != 0))
+ {
+ activelist[i].ai_family = mainhints.ai_family;
+
+#ifdef _WIN32
+ threadId = (HANDLE)_beginthreadex(NULL, 0, main_active,
+ (void *)&activelist[i], 0, NULL);
+ if (threadId == 0)
+ {
+ SOCK_DEBUG_MESSAGE("Error creating the active child threads");
+ continue;
+ }
+ CloseHandle(threadId);
+#else
+ if ((pid = fork()) == 0) // I am the child
+ {
+ main_active((void *) &activelist[i]);
+ exit(0);
+ }
+#endif
+ i++;
+ }
+
+ /*
+ * The code that manages the active connections is not blocking;
+ * the code that manages the passive connection is blocking.
+ * So, if the user does not want to run in passive mode, we have
+ * to block the main thread here, otherwise the program ends and
+ * all threads are stopped.
+ *
+ * WARNING: this means that in case we have only active mode,
+ * the program does not terminate even if all the child thread
+ * terminates. The user has always to press Ctrl+C (or send a
+ * SIGTERM) to terminate the program.
+ */
+ if (passivemode)
+ {
+ struct addrinfo *tempaddrinfo;
+
+ //
+ // Get a list of sockets on which to listen.
+ //
+ if (sock_initaddress((address[0]) ? address : NULL, port, &mainhints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
+ {
+ SOCK_DEBUG_MESSAGE(errbuf);
+ return;
+ }
+
+ for (tempaddrinfo = addrinfo; tempaddrinfo;
+ tempaddrinfo = tempaddrinfo->ai_next)
+ {
+ SOCKET sock;
+ struct listen_sock *sock_info;
+
+ if ((sock = sock_open(tempaddrinfo, SOCKOPEN_SERVER, SOCKET_MAXCONN, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
+ {
+ switch (tempaddrinfo->ai_family)
+ {
+ case AF_INET:
+ {
+ struct sockaddr_in *in;
+ char addrbuf[INET_ADDRSTRLEN];
+
+ in = (struct sockaddr_in *)tempaddrinfo->ai_addr;
+ rpcapd_log(LOGPRIO_WARNING, "Can't listen on socket for %s:%u: %s",
+ inet_ntop(AF_INET, &in->sin_addr,
+ addrbuf, sizeof (addrbuf)),
+ ntohs(in->sin_port),
+ errbuf);
+ break;
+ }
+
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *in6;
+ char addrbuf[INET6_ADDRSTRLEN];
+
+ in6 = (struct sockaddr_in6 *)tempaddrinfo->ai_addr;
+ rpcapd_log(LOGPRIO_WARNING, "Can't listen on socket for %s:%u: %s",
+ inet_ntop(AF_INET6, &in6->sin6_addr,
+ addrbuf, sizeof (addrbuf)),
+ ntohs(in6->sin6_port),
+ errbuf);
+ break;
+ }
+
+ default:
+ rpcapd_log(LOGPRIO_WARNING, "Can't listen on socket for address family %u: %s",
+ tempaddrinfo->ai_family,
+ errbuf);
+ break;
+ }
+ continue;
+ }
+
+ sock_info = (struct listen_sock *) malloc(sizeof (struct listen_sock));
+ if (sock_info == NULL)
+ {
+ rpcapd_log(LOGPRIO_ERROR, "Can't allocate structure for listen socket");
+ exit(2);
+ }
+ sock_info->sock = sock;
+ sock_info->next = listen_socks;
+ listen_socks = sock_info;
+ }
+
+ freeaddrinfo(addrinfo);
+
+ if (listen_socks == NULL)
+ {
+ rpcapd_log(LOGPRIO_ERROR, "Can't listen on any address");
+ exit(2);
+ }
+
+ //
+ // Now listen on all of them, waiting for connections.
+ //
+ accept_connections();
+ }
+
+ //
+ // We're done; exit.
+ //
+ SOCK_DEBUG_MESSAGE(PROGRAM_NAME " is closing.\n");
+
+#ifndef _WIN32
+ //
+ // Sends a KILL signal to all the processes in this process's
+ // process group; i.e., it kills all the child processes
+ // we've created.
+ //
+ // XXX - that also includes us, so we will be killed as well;
+ // that may cause a message to be printed or logged.
+ //
+ kill(0, SIGKILL);
+#endif
+
+ //
+ // Just leave. We shouldn't need to clean up sockets or
+ // anything else, and if we try to do so, we'll could end
+ // up closing sockets, or shutting Winsock down, out from
+ // under service loops, causing all sorts of noisy error
+ // messages.
+ //
+ // We shouldn't need to worry about cleaning up any resources
+ // such as handles, sockets, threads, etc. - exit() should
+ // terminate the process, causing all those resources to be
+ // cleaned up (including the threads; Microsoft claims in the
+ // ExitProcess() documentation that, if ExitProcess() is called,
+ // "If a thread is waiting on a kernel object, it will not be
+ // terminated until the wait has completed.", but claims in the
+ // _beginthread()/_beginthreadex() documentation that "All threads
+ // are terminated if any thread calls abort, exit, _exit, or
+ // ExitProcess." - the latter appears to be the case, even for
+ // threads waiting on the event for a pcap_t).
+ //
+ exit(0);
+}
+
+#ifdef _WIN32
+static void
+send_state_change_event(void)
+{
+ char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
+
+ if (!SetEvent(state_change_event))
+ {
+ sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
+ rpcapd_log(LOGPRIO_ERROR, "SetEvent on shutdown event failed: %s", errbuf);
+ }
+}
+
+void
+send_shutdown_notification(void)
+{
+ //
+ // Indicate that the server should shut down.
+ //
+ shutdown_server = 1;
+
+ //
+ // Send a state change event, to wake up WSAWaitForMultipleEvents().
+ //
+ send_state_change_event();
+}
+
+void
+send_reread_configuration_notification(void)
+{
+ //
+ // Indicate that the server should re-read its configuration file.
+ //
+ reread_config = 1;
+
+ //
+ // Send a state change event, to wake up WSAWaitForMultipleEvents().
+ //
+ send_state_change_event();
+}
+
+static BOOL WINAPI main_ctrl_event(DWORD ctrltype)
+{
+ //
+ // ctrltype is one of:
+ //
+ // CTRL_C_EVENT - we got a ^C; this is like SIGINT
+ // CTRL_BREAK_EVENT - we got Ctrl+Break
+ // CTRL_CLOSE_EVENT - the console was closed; this is like SIGHUP
+ // CTRL_LOGOFF_EVENT - a user is logging off; this is received
+ // only by services
+ // CTRL_SHUTDOWN_EVENT - the systemis shutting down; this is
+ // received only by services
+ //
+ // For now, we treat all but CTRL_LOGOFF_EVENT as indications
+ // that we should shut down.
+ //
+ switch (ctrltype)
+ {
+ case CTRL_C_EVENT:
+ case CTRL_BREAK_EVENT:
+ case CTRL_CLOSE_EVENT:
+ case CTRL_SHUTDOWN_EVENT:
+ //
+ // Set a shutdown notification.
+ //
+ send_shutdown_notification();
+ break;
+
+ default:
+ break;
+ }
+
+ //
+ // We handled this.
+ //
+ return TRUE;
+}
+#else
+static void main_terminate(int sign _U_)
+{
+ //
+ // Note that the server should shut down.
+ // select() should get an EINTR error when we return,
+ // so it will wake up and know it needs to check the flag.
+ //
+ shutdown_server = 1;
+}
+
+static void main_reread_config(int sign _U_)
+{
+ //
+ // Note that the server should re-read its configuration file.
+ // select() should get an EINTR error when we return,
+ // so it will wake up and know it needs to check the flag.
+ //
+ reread_config = 1;
+}
+
+static void main_reap_children(int sign _U_)
+{
+ pid_t pid;
+ int exitstat;
+
+ // Reap all child processes that have exited.
+ // For reference, Stevens, pg 128
+
+ while ((pid = waitpid(-1, &exitstat, WNOHANG)) > 0)
+ SOCK_DEBUG_MESSAGE("Child terminated");
+
+ return;
+}
+#endif
+
+//
+// Loop waiting for incoming connections and accepting them.
+//
+static void
+accept_connections(void)
+{
+#ifdef _WIN32
+ struct listen_sock *sock_info;
+ DWORD num_events;
+ WSAEVENT *events;
+ int i;
+ char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
+
+ //
+ // How big does the set of events need to be?
+ // One for the shutdown event, plus one for every socket on which
+ // we'll be listening.
+ //
+ num_events = 1; // shutdown event
+ for (sock_info = listen_socks; sock_info;
+ sock_info = sock_info->next)
+ {
+ if (num_events == WSA_MAXIMUM_WAIT_EVENTS)
+ {
+ //
+ // WSAWaitForMultipleEvents() doesn't support
+ // more than WSA_MAXIMUM_WAIT_EVENTS events
+ // on which to wait.
+ //
+ rpcapd_log(LOGPRIO_ERROR, "Too many sockets on which to listen");
+ exit(2);
+ }
+ num_events++;
+ }
+
+ //
+ // Allocate the array of events.
+ //
+ events = (WSAEVENT *) malloc(num_events * sizeof (WSAEVENT));
+ if (events == NULL)
+ {
+ rpcapd_log(LOGPRIO_ERROR, "Can't allocate array of events which to listen");
+ exit(2);
+ }
+
+ //
+ // Fill it in.
+ //
+ events[0] = state_change_event; // state change event first
+ for (sock_info = listen_socks, i = 1; sock_info;
+ sock_info = sock_info->next, i++)
+ {
+ WSAEVENT event;
+
+ //
+ // Create an event that is signaled if there's a connection
+ // to accept on the socket in question.
+ //
+ event = WSACreateEvent();
+ if (event == WSA_INVALID_EVENT)
+ {
+ sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
+ rpcapd_log(LOGPRIO_ERROR, "Can't create socket event: %s", errbuf);
+ exit(2);
+ }
+ if (WSAEventSelect(sock_info->sock, event, FD_ACCEPT) == SOCKET_ERROR)
+ {
+ sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
+ rpcapd_log(LOGPRIO_ERROR, "Can't setup socket event: %s", errbuf);
+ exit(2);
+ }
+ events[i] = event;
+ }
+
+ for (;;)
+ {
+ //
+ // Wait for incoming connections.
+ //
+ DWORD ret;
+
+ ret = WSAWaitForMultipleEvents(num_events, events, FALSE,
+ WSA_INFINITE, FALSE);
+ if (ret == WSA_WAIT_FAILED)
+ {
+ sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
+ rpcapd_log(LOGPRIO_ERROR, "WSAWaitForMultipleEvents failed: %s", errbuf);
+ exit(2);
+ }
+
+ if (ret == WSA_WAIT_EVENT_0)
+ {
+ //
+ // The state change event was set.
+ //
+ if (shutdown_server)
+ {
+ //
+ // Time to quit. Exit the loop.
+ //
+ break;
+ }
+ if (reread_config)
+ {
+ //
+ // We should re-read the configuration
+ // file.
+ //
+ reread_config = 0; // clear the indicator
+ fileconf_read();
+ }
+ }
+
+ //
+ // Check each socket.
+ //
+ for (sock_info = listen_socks, i = 1; sock_info;
+ sock_info = sock_info->next, i++)
+ {
+ WSANETWORKEVENTS network_events;
+
+ if (WSAEnumNetworkEvents(sock_info->sock,
+ events[i], &network_events) == SOCKET_ERROR)
+ {
+ sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE);
+ rpcapd_log(LOGPRIO_ERROR, "WSAEnumNetworkEvents failed: %s", errbuf);
+ exit(2);
+ }
+ if (network_events.lNetworkEvents & FD_ACCEPT)
+ {
+ //
+ // Did an error occur?
+ //
+ if (network_events.iErrorCode[FD_ACCEPT_BIT] != 0)
+ {
+ //
+ // Yes - report it and keep going.
+ //
+ sock_fmterror(NULL,
+ network_events.iErrorCode[FD_ACCEPT_BIT],
+ errbuf,
+ PCAP_ERRBUF_SIZE);
+ rpcapd_log(LOGPRIO_ERROR, "Socket error: %s", errbuf);
+ continue;
+ }
+
+ //
+ // Accept the connection.
+ //
+ accept_connection(sock_info->sock);
+ }
+ }
+ }
+#else
+ struct listen_sock *sock_info;
+ int num_sock_fds;
+
+ //
+ // How big does the bitset of sockets on which to select() have
+ // to be?
+ //
+ num_sock_fds = 0;
+ for (sock_info = listen_socks; sock_info; sock_info = sock_info->next)
+ {
+ if (sock_info->sock + 1 > num_sock_fds)
+ {
+ if ((unsigned int)(sock_info->sock + 1) >
+ (unsigned int)FD_SETSIZE)
+ {
+ rpcapd_log(LOGPRIO_ERROR, "Socket FD is too bit for an fd_set");
+ exit(2);
+ }
+ num_sock_fds = sock_info->sock + 1;
+ }
+ }
+
+ for (;;)
+ {
+ fd_set sock_fds;
+ int ret;
+
+ //
+ // Set up an fd_set for all the sockets on which we're
+ // listening.
+ //
+ // This set is modified by select(), so we have to
+ // construct it anew each time.
+ //
+ FD_ZERO(&sock_fds);
+ for (sock_info = listen_socks; sock_info;
+ sock_info = sock_info->next)
+ {
+ FD_SET(sock_info->sock, &sock_fds);
+ }
+
+ //
+ // Wait for incoming connections.
+ //
+ ret = select(num_sock_fds, &sock_fds, NULL, NULL, NULL);
+ if (ret == -1)
+ {
+ if (errno == EINTR)
+ {
+ //
+ // If this is a "terminate the
+ // server" signal, exit the loop,
+ // otherwise just keep trying.
+ //
+ if (shutdown_server)
+ {
+ //
+ // Time to quit. Exit the loop.
+ //
+ break;
+ }
+ if (reread_config)
+ {
+ //
+ // We should re-read the configuration
+ // file.
+ //
+ reread_config = 0; // clear the indicator
+ fileconf_read();
+ }
+
+ //
+ // Go back and wait again.
+ //
+ continue;
+ }
+ else
+ {
+ rpcapd_log(LOGPRIO_ERROR, "select failed: %s",
+ strerror(errno));
+ exit(2);
+ }
+ }
+
+ //
+ // Check each socket.
+ //
+ for (sock_info = listen_socks; sock_info;
+ sock_info = sock_info->next)
+ {
+ if (FD_ISSET(sock_info->sock, &sock_fds))
+ {
+ //
+ // Accept the connection.
+ //
+ accept_connection(sock_info->sock);
+ }
+ }
+ }
+#endif
+
+ //
+ // Close all the listen sockets.
+ //
+ for (sock_info = listen_socks; sock_info; sock_info = sock_info->next)
+ {
+ closesocket(sock_info->sock);
+ }
+ sock_cleanup();
+}
+
+//
+// Accept a connection and start a worker thread, on Windows, or a
+// worker process, on UN*X, to handle the connection.
+//
+static void
+accept_connection(SOCKET listen_sock)
+{
+ char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
+ SOCKET sockctrl; // keeps the socket ID for this control connection
+ struct sockaddr_storage from; // generic sockaddr_storage variable
+ socklen_t fromlen; // keeps the length of the sockaddr_storage variable
+
+#ifdef _WIN32
+ HANDLE threadId; // handle for the subthread
+ u_long off = 0;
+ SOCKET *sockctrl_temp;
+#else
+ pid_t pid;
+#endif
+
+ // Initialize errbuf
+ memset(errbuf, 0, sizeof(errbuf));
+
+ for (;;)
+ {
+ // Accept the connection
+ fromlen = sizeof(struct sockaddr_storage);
+
+ sockctrl = accept(listen_sock, (struct sockaddr *) &from, &fromlen);
+
+ if (sockctrl != INVALID_SOCKET)
+ {
+ // Success.
+ break;
+ }
+
+ // The accept() call can return this error when a signal is catched
+ // In this case, we have simply to ignore this error code
+ // Stevens, pg 124
+#ifdef _WIN32
+ if (WSAGetLastError() == WSAEINTR)
+#else
+ if (errno == EINTR)
+#endif
+ continue;
+
+ // Don't check for errors here, since the error can be due to the fact that the thread
+ // has been killed
+ sock_geterror("accept(): ", errbuf, PCAP_ERRBUF_SIZE);
+ rpcapd_log(LOGPRIO_ERROR, "Accept of control connection from client failed: %s",
+ errbuf);
+ return;
+ }
+
+ //
+ // We have a connection.
+ // Check whether the connecting host is among the ones allowed.
+ //
+ if (sock_check_hostlist(hostlist, RPCAP_HOSTLIST_SEP, &from, errbuf, PCAP_ERRBUF_SIZE) < 0)
+ {
+ rpcap_senderror(sockctrl, 0, PCAP_ERR_HOSTNOAUTH, errbuf, NULL);
+ sock_close(sockctrl, NULL, 0);
+ return;
+ }
+
+#ifdef _WIN32
+ //
+ // Put the socket back into blocking mode; doing WSAEventSelect()
+ // on the listen socket makes that socket non-blocking, and it
+ // appears that sockets returned from an accept() on that socket
+ // are also non-blocking.
+ //
+ // First, we have to un-WSAEventSelect() this socket, and then
+ // we can turn non-blocking mode off.
+ //
+ if (WSAEventSelect(sockctrl, NULL, 0) == SOCKET_ERROR)
+ {
+ sock_geterror("ioctlsocket(FIONBIO): ", errbuf, PCAP_ERRBUF_SIZE);
+ rpcap_senderror(sockctrl, 0, PCAP_ERR_HOSTNOAUTH, errbuf, NULL);
+ sock_close(sockctrl, NULL, 0);
+ return;
+ }
+ if (ioctlsocket(sockctrl, FIONBIO, &off) == SOCKET_ERROR)
+ {
+ sock_geterror("ioctlsocket(FIONBIO): ", errbuf, PCAP_ERRBUF_SIZE);
+ rpcap_senderror(sockctrl, 0, PCAP_ERR_HOSTNOAUTH, errbuf, NULL);
+ sock_close(sockctrl, NULL, 0);
+ return;
+ }
+
+ //
+ // Allocate a location to hold the value of sockctrl.
+ // It will be freed in the newly-created thread once it's
+ // finished with it.
+ // I guess we *could* just cast sockctrl to a void *, but that's
+ // a bit ugly.
+ //
+ sockctrl_temp = (SOCKET *)malloc(sizeof (SOCKET));
+ if (sockctrl_temp == NULL)
+ {
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "malloc() failed");
+ rpcap_senderror(sockctrl, 0, PCAP_ERR_OPEN, errbuf, NULL);
+ sock_close(sockctrl, NULL, 0);
+ return;
+ }
+ *sockctrl_temp = sockctrl;
+
+ threadId = (HANDLE)_beginthreadex(NULL, 0,
+ main_passive_serviceloop_thread, (void *) sockctrl_temp, 0, NULL);
+ if (threadId == 0)
+ {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error creating the child thread");
+ rpcap_senderror(sockctrl, 0, PCAP_ERR_OPEN, errbuf, NULL);
+ sock_close(sockctrl, NULL, 0);
+ free(sockctrl_temp);
+ return;
+ }
+ CloseHandle(threadId);
+#else
+ pid = fork();
+ if (pid == -1)
+ {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error creating the child process");
+ rpcap_senderror(sockctrl, 0, PCAP_ERR_OPEN, errbuf, NULL);
+ sock_close(sockctrl, NULL, 0);
+ return;
+ }
+ if (pid == 0)
+ {
+ //
+ // Child process.
+ //
+ // Close the socket on which we're listening (must
+ // be open only in the parent).
+ //
+ closesocket(listen_sock);
+
+#if 0
+ //
+ // Modify thread params so that it can be killed at any time
+ // XXX - is this necessary? This is the main and, currently,
+ // only thread in the child process, and nobody tries to
+ // cancel us, although *we* may cancel the thread that's
+ // handling the capture loop.
+ //
+ if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL))
+ goto end;
+ if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL))
+ goto end;
+#endif
+
+ //
+ // Run the service loop.
+ // This is passive mode, so we don't care whether we were
+ // told by the client to close.
+ //
+ (void)daemon_serviceloop(sockctrl, sockctrl, 0,
+ nullAuthAllowed);
+
+ close(sockctrl);
+
+ exit(0);
+ }
+
+ // I am the parent
+ // Close the socket for this session (must be open only in the child)
+ closesocket(sockctrl);
+#endif
+}
+
+/*!
+ \brief 'true' main of the program in case the active mode is turned on.
+
+ This function loops forever trying to connect to the remote host, until the
+ daemon is turned down.
+
+ \param ptr: it keeps the 'activepars' parameters. It is a 'void *'
+ just because the thread APIs want this format.
+*/
+#ifdef _WIN32
+static unsigned __stdcall
+#else
+static void *
+#endif
+main_active(void *ptr)
+{
+ char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
+ SOCKET sockctrl; // keeps the socket ID for this control connection
+ 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 active_pars *activepars;
+
+ activepars = (struct active_pars *) ptr;
+
+ // 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_socktype = SOCK_STREAM;
+ hints.ai_family = activepars->ai_family;
+
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Connecting to host %s, port %s, using protocol %s",
+ activepars->address, activepars->port, (hints.ai_family == AF_INET) ? "IPv4":
+ (hints.ai_family == AF_INET6) ? "IPv6" : "Unspecified");
+ SOCK_DEBUG_MESSAGE(errbuf);
+
+ // Initialize errbuf
+ memset(errbuf, 0, sizeof(errbuf));
+
+ // Do the work
+ if (sock_initaddress(activepars->address, activepars->port, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
+ {
+ SOCK_DEBUG_MESSAGE(errbuf);
+ return 0;
+ }
+
+ for (;;)
+ {
+ int activeclose;
+
+ if ((sockctrl = sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
+ {
+ SOCK_DEBUG_MESSAGE(errbuf);
+
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error connecting to host %s, port %s, using protocol %s",
+ activepars->address, activepars->port, (hints.ai_family == AF_INET) ? "IPv4":
+ (hints.ai_family == AF_INET6) ? "IPv6" : "Unspecified");
+
+ SOCK_DEBUG_MESSAGE(errbuf);
+
+ sleep_secs(RPCAP_ACTIVE_WAIT);
+
+ continue;
+ }
+
+ activeclose = daemon_serviceloop(sockctrl, sockctrl, 1,
+ nullAuthAllowed);
+
+ sock_close(sockctrl, NULL, 0);
+
+ // If the connection is closed by the user explicitely, don't try to connect to it again
+ // just exit the program
+ if (activeclose == 1)
+ break;
+ }
+
+ freeaddrinfo(addrinfo);
+ return 0;
+}
+
+#ifdef _WIN32
+//
+// Main routine of a passive-mode service thread.
+//
+unsigned __stdcall main_passive_serviceloop_thread(void *ptr)
+{
+ SOCKET sockctrl;
+
+ sockctrl = *((SOCKET *)ptr);
+ free(ptr);
+
+ //
+ // Handle this client.
+ // This is passive mode, so we don't care whether we were
+ // told by the client to close.
+ //
+ (void)daemon_serviceloop(sockctrl, sockctrl, 0, nullAuthAllowed);
+
+ sock_close(sockctrl, NULL, 0);
+
+ return 0;
+}
+#endif
diff --git a/rpcapd/rpcapd.h b/rpcapd/rpcapd.h
new file mode 100644
index 00000000..90ba7ffa
--- /dev/null
+++ b/rpcapd/rpcapd.h
@@ -0,0 +1,44 @@
+/*
+ * 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 __RPCAPD_H__
+#define __RPCAPD_H__
+
+#define PROGRAM_NAME "rpcapd"
+#define SOCKET_MAXCONN 10 /* Maximum number of connections queued into the accept() */
+#ifdef _WIN32
+void send_shutdown_notification(void); // Send notification to shut down the daemon
+void send_reread_configuration_notification(void); // Send notification to re-read the configuration file
+#endif
+void main_startup(void);
+
+#endif
diff --git a/rpcapd/rpcapd.inetd.conf b/rpcapd/rpcapd.inetd.conf
new file mode 100644
index 00000000..e4fad5e6
--- /dev/null
+++ b/rpcapd/rpcapd.inetd.conf
@@ -0,0 +1,2 @@
+2002 stream tcp nowait root /usr/local/sbin/rpcapd rpcapd -i
+
diff --git a/rpcapd/rpcapd.manadmin.in b/rpcapd/rpcapd.manadmin.in
new file mode 100644
index 00000000..92f676c0
--- /dev/null
+++ b/rpcapd/rpcapd.manadmin.in
@@ -0,0 +1,223 @@
+.\" rpcapd.8
+.\"
+.\" Copyright (c) 2002-2005 NetGroup, Politecnico di Torino (Italy)
+.\" Copyright (c) 2005-2009 CACE Technologies
+.\" Copyright (c) 2018- The TCPdump Group
+.\" 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.
+.\"
+.TH RPCAPD @MAN_ADMIN_COMMANDS@ "April 20, 2018"
+.SH NAME
+rpcapd \- capture daemon to be controlled by a remote libpcap application
+.SH SYNOPSIS
+.na
+rpcapd
+[
+.B \-b
+.I address
+] [
+.B \-p
+.I port
+] [
+.B \-4
+] [
+.B \-l
+.I host_list
+]
+.br
+.ti +8
+[
+.B \-a
+.IR host , port
+] [
+.B \-n
+] [
+.B \-v
+] [
+.B \-d
+] [
+.B \-i
+] [
+.B \-s
+.I config_file
+]
+.br
+.ti +8
+[
+.B \-f
+.I config_file
+]
+.br
+.ad
+.SH DESCRIPTION
+.LP
+\fIRpcapd\fP is a daemon (Unix) or service (Win32) that allows the capture
+and filter part of libpcap to be run on a remote system.
+.LP
+Rpcapd can run in two modes: passive mode (default) and active mode.
+.LP
+In passive mode, the client (e.g., a network sniffer) connects to
+.BR rpcapd .
+It then sends hem the appropriate commands to start the capture.
+.LP
+In active mode,
+.B rpcapd
+tries to establish a connection toward the client
+(e.g., a network sniffer). The client then sends the appropriate commands
+to rpcapd to start the capture.
+.LP
+Active mode is useful in case
+.B rpcapd
+is run behind a firewall and
+cannot receive connections from the external world. In this case,
+.B rpcapd
+can be configured to establish the connection to a given host,
+which has to be configured in order to wait for that connection. After
+establishing the connection, the protocol continues its job in almost
+the same way in both active and passive mode.
+.SH Configuration file
+.LP
+The user can create a configuration file in the same folder of the
+executable, and put the configuration commands in there. In order for
+rpcapd to execute the commands, you have to restart it on Win32, i.e.
+the initialization file is parsed only at the beginning). The UNIX
+version of rpcapd will reread the configuration file when receiving a
+HUP signel. In that case, all the existing connections remain in place,
+while the new connections will be created according to the new parameters.
+.LP
+In case a user does not want to create the configuration file manually,
+they can launch rpcapd with the requested parameters plus "-s filename".
+Rpcapd will parse all the parameters and save them into the specified
+configuration file.
+.SH Installing rpcapd on Win32
+.LP
+The remote daemon is installed automatically when installing WinPcap.
+The installation process places the rpcapd file into the WinPcap folder.
+This file can be executed either from the command line, or as a service.
+For instance, the installation process updates the list of available
+services list and it creates a new item (Remote Packet Capture Protocol
+v.0 (experimental) ). To avoid security problems, the service is
+inactive and it has to be started manually (control panel -
+administrative tools - services - start).
+.LP
+The service has a set of "standard" parameters, i.e. it is launched
+with the
+.B \-d
+flag (in order to make it run as a service) and the
+.B "-f rpcapd.ini"
+flag.
+.SH Starting rpcapd on Win32
+.LP
+The rpcapd executable can be launched directly, i.e. it can run in the
+foreground as well (not as a daemon/service). The procedure is quite
+simple: you have to invoke the executable from the command line with all
+the requested parameters except for the
+.B \-d
+flag. The capture server will
+start in the foreground.
+.SH Installing rpcapd on Unix-like systems
+TBD
+.SH Starting rpcapd on Unix-like systems
+.B rpcapd
+needs sufficient privileges to perform packet capture, e.g.
+run as root or be owned by root and have suid set. Most operating
+systems provide more elegant solutions when run as user than the
+above solutions, all of them different.
+.SH OPTIONS
+.TP
+.BI \-b " address"
+Bind to the IP address specified by
+.I address
+(either numeric or literal).
+By default,
+.B rpcapd
+binds to all local IPv4 and IPv6 addresses.
+.TP
+.BI \-p " port"
+Bind to the port specified by
+.IR port .
+By default,
+.B rpcapd
+binds to port 2002.
+.TP
+.B \-4
+Listen only on IPv4 addresses.
+By default,
+.B rpcapd
+listens on both IPv4 and IPv6 addresses.
+.TP
+.BI -l " host_list"
+Only allow hosts specified in the
+.I host_list
+file to connect to this server.
+Hosts are listed one per line.
+We suggest that you use use host names rather than literal IP addresses
+in order to avoid problems with different address families.
+.TP
+.B \-n
+Permit NULL authentication (usually used with
+.BR \-l ).
+.TP
+.BI \-a " host" , "port"
+Run in active mode, connecting to host
+.I host
+on port
+.IR port .
+In case
+.I port
+is omitted, the default port (2003) is used.
+.TP
+.B -v
+Run in active mode only; by default, if
+.B \-a
+is specified,
+.B rpcapd
+it accepts passive connections as well.
+.TP
+.B \-d
+Run in daemon mode (UNIX only) or as a service (Win32 only)
+Warning (Win32): this switch is provided automatically when
+the service is started from the control panel.
+.TP
+.B \-i
+Run in inetd mode (UNIX only).
+.TP
+.BI \-s " config_file"
+Save the current configuration to
+.IR config_file .
+.TP
+.BI \-f " config_file"
+Load the current configuration from
+.IR config_file ;
+all switches specified from the command line are ignored.
+.TP
+.B \-h
+Print this help screen.
+.br
+.ad
+.SH "SEE ALSO"
+pcap(3PCAP)
diff --git a/rpcapd/rpcapd.rc b/rpcapd/rpcapd.rc
new file mode 100644
index 00000000..695c00b6
--- /dev/null
+++ b/rpcapd/rpcapd.rc
@@ -0,0 +1,39 @@
+#include "config.h"
+#undef PACKAGE_NAME
+#include <winver.h>
+#include <rpcapd.h>
+#define PACKAGE_NAME PROGRAM_NAME
+
+ VS_VERSION_INFO VERSIONINFO
+ FILEVERSION PACKAGE_VERSION_DLL
+ PRODUCTVERSION PACKAGE_VERSION_DLL
+ FILEFLAGSMASK 0x3fL
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_APP
+#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", "Remote Packet Capture Daemon"
+ VALUE "FileVersion", "PACKAGE_VERSION_DLL"
+ VALUE "InternalName", PACKAGE_NAME
+ VALUE "LegalCopyright", "Copyright (c) The TCPdump Group"
+ VALUE "LegalTrademarks", ""
+ VALUE "OriginalFilename", "rpcapd.exe"
+ VALUE "ProductName", PACKAGE_NAME
+ VALUE "ProductVersion", PACKAGE_VERSION
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+ END
diff --git a/rpcapd/rpcapd.socket b/rpcapd/rpcapd.socket
new file mode 100644
index 00000000..9d5a0bda
--- /dev/null
+++ b/rpcapd/rpcapd.socket
@@ -0,0 +1,9 @@
+[Unit]
+Description=Rpcap Socket for Per-Connection Servers
+
+[Socket]
+ListenStream=2002
+Accept=yes
+
+[Install]
+WantedBy=sockets.target
diff --git a/rpcapd/rpcapd.xinetd.conf b/rpcapd/rpcapd.xinetd.conf
new file mode 100644
index 00000000..2c79348e
--- /dev/null
+++ b/rpcapd/rpcapd.xinetd.conf
@@ -0,0 +1,8 @@
+service rpcap {
+ socket_type = stream
+ protocol = tcp
+ wait = no
+ user = root
+ server = /usr/local/sbin/rpcapd
+ server_args = -i
+}
diff --git a/rpcapd/rpcapd@.service b/rpcapd/rpcapd@.service
new file mode 100644
index 00000000..92d11719
--- /dev/null
+++ b/rpcapd/rpcapd@.service
@@ -0,0 +1,6 @@
+[Unit]
+Description=Rpcap Per-Connection Server
+
+[Service]
+ExecStart=-/usr/local/sbin/rpcapd -i
+StandardInput=socket
diff --git a/rpcapd/win32-svc.c b/rpcapd/win32-svc.c
new file mode 100644
index 00000000..8cc7dc92
--- /dev/null
+++ b/rpcapd/win32-svc.c
@@ -0,0 +1,182 @@
+/*
+ * 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.
+ *
+ */
+
+
+#include "rpcapd.h"
+#include <pcap.h> // for PCAP_ERRBUF_SIZE
+#include "sockutils.h" // for SOCK_DEBUG_MESSAGE
+#include "portability.h"
+#include "fileconf.h"
+
+static SERVICE_STATUS_HANDLE service_status_handle;
+static SERVICE_STATUS service_status;
+
+void svc_geterr(char *str);
+static void WINAPI svc_main(DWORD argc, char **argv);
+static void update_svc_status(DWORD state, DWORD progress_indicator);
+
+int svc_start(void)
+{
+ int rc;
+ SERVICE_TABLE_ENTRY ste[] =
+ {
+ { PROGRAM_NAME, svc_main },
+ { NULL, NULL }
+ };
+
+ // This call is blocking. A new thread is created which will launch
+ // the svc_main() function
+ if ( (rc = StartServiceCtrlDispatcher(ste)) == 0)
+ svc_geterr("StartServiceCtrlDispatcher()");
+
+ return rc; // FALSE if this is not started as a service
+}
+
+void svc_geterr(char *str)
+{
+ char message[PCAP_ERRBUF_SIZE];
+ char string[PCAP_ERRBUF_SIZE];
+ int val;
+
+ val = GetLastError();
+ FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
+ FORMAT_MESSAGE_MAX_WIDTH_MASK,
+ NULL, val, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPSTR) string, PCAP_ERRBUF_SIZE, NULL);
+
+ pcap_snprintf(message, PCAP_ERRBUF_SIZE, "%s failed with error %d: %s", str, val, string);
+
+ SOCK_DEBUG_MESSAGE(message);
+}
+
+void WINAPI svc_control_handler(DWORD Opcode)
+{
+ switch(Opcode)
+ {
+ case SERVICE_CONTROL_STOP:
+ //
+ // XXX - is this sufficient to clean up the service?
+ // To be really honest, only the main socket and
+ // such these stuffs are cleared; however the threads
+ // that are running are not stopped.
+ // This can be seen by placing a breakpoint at the
+ // end of svc_main(), in which you will see that is
+ // never reached. However, as soon as you set the
+ // service status to "stopped", the
+ // StartServiceCtrlDispatcher() returns and the main
+ // thread ends. Then, Win32 has a good automatic
+ // cleanup, so that all the threads which are still
+ // running are stopped when the main thread ends.
+ //
+ send_shutdown_notification();
+
+ update_svc_status(SERVICE_STOP_PENDING, 0);
+ break;
+
+ /*
+ Pause and Continue have an usual meaning and they are used just to be able
+ to change the running parameters at run-time. In other words, they act
+ like the SIGHUP signal on UNIX. All the running threads continue to run and
+ they are not paused at all.
+ Particularly,
+ - PAUSE does nothing
+ - CONTINUE re-reads the configuration file and creates the new threads that
+ can be needed according to the new configuration.
+ */
+ case SERVICE_CONTROL_PAUSE:
+ update_svc_status(SERVICE_PAUSED, 0);
+ break;
+
+ case SERVICE_CONTROL_CONTINUE:
+ update_svc_status(SERVICE_RUNNING, 0);
+ //
+ // Tell the main loop to re-read the configuration.
+ //
+ send_reread_configuration_notification();
+ break;
+
+ case SERVICE_CONTROL_INTERROGATE:
+ // Fall through to send current status.
+ // WARNING: not implemented
+ update_svc_status(SERVICE_RUNNING, 0);
+ MessageBox(NULL, "Not implemented", "warning", MB_OK);
+ break;
+
+ case SERVICE_CONTROL_PARAMCHANGE:
+ //
+ // Tell the main loop to re-read the configuration.
+ //
+ send_reread_configuration_notification();
+ break;
+ }
+
+ // Send current status.
+ return;
+}
+
+void WINAPI svc_main(DWORD argc, char **argv)
+{
+ service_status_handle = RegisterServiceCtrlHandler(PROGRAM_NAME, svc_control_handler);
+
+ if (!service_status_handle)
+ return;
+
+ service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;
+ service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_PARAMCHANGE;
+ // | SERVICE_ACCEPT_SHUTDOWN ;
+ update_svc_status(SERVICE_RUNNING, 0);
+
+ //
+ // Service requests until we're told to stop.
+ //
+ main_startup();
+
+ //
+ // It returned, so we were told to stop.
+ //
+ update_svc_status(SERVICE_STOPPED, 0);
+}
+
+static void
+update_svc_status(DWORD state, DWORD progress_indicator)
+{
+ service_status.dwWin32ExitCode = NO_ERROR;
+ service_status.dwCurrentState = state;
+ service_status.dwCheckPoint = progress_indicator;
+ service_status.dwWaitHint = 0;
+ SetServiceStatus(service_status_handle, &service_status);
+}
+
+/*
+sc create rpcapd DisplayName= "Remote Packet Capture Protocol v.0 (experimental)" binpath= "C:\cvsroot\winpcap\wpcap\PRJ\Debug\rpcapd -d -f rpcapd.ini"
+sc description rpcapd "Allows to capture traffic on this host from a remote machine."
+*/
diff --git a/rpcapd/win32-svc.h b/rpcapd/win32-svc.h
new file mode 100644
index 00000000..3f511d2c
--- /dev/null
+++ b/rpcapd/win32-svc.h
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ *
+ */
+
+int svc_start(void);
diff --git a/savefile.c b/savefile.c
index 247338c5..ec44ef4f 100644
--- a/savefile.c
+++ b/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/scanner.c b/scanner.c
index b36239ac..2cf65c9d 100644
--- a/scanner.c
+++ b/scanner.c
@@ -1,13 +1,32 @@
#line 2 "scanner.c"
-#line 2 "scanner.l"
/* 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"
-#line 11 "scanner.c"
+#line 30 "scanner.c"
#define YY_INT_ALIGNED short int
@@ -15,8 +34,8 @@
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 39
+#define YY_FLEX_MINOR_VERSION 6
+#define YY_FLEX_SUBMINOR_VERSION 1
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
@@ -95,25 +114,13 @@ typedef unsigned int flex_uint32_t;
#endif /* ! FLEXINT_H */
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else /* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif /* defined (__STDC__) */
-#endif /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
+/* TODO: this is always defined, so inline it */
#define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define yynoreturn __attribute__((__noreturn__))
#else
-#define yyconst
+#define yynoreturn
#endif
/* Returned upon end-of-file. */
@@ -226,12 +233,12 @@ struct yy_buffer_state
/* Size of input buffer in bytes, not including room for EOB
* characters.
*/
- yy_size_t yy_buf_size;
+ int yy_buf_size;
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
*/
- yy_size_t yy_n_chars;
+ int yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to
@@ -254,7 +261,7 @@ struct yy_buffer_state
int yy_bs_lineno; /**< The line count. */
int yy_bs_column; /**< The column count. */
-
+
/* Whether to try to fill the input buffer when we reach the
* end of it.
*/
@@ -310,7 +317,7 @@ static void pcap__init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner
YY_BUFFER_STATE pcap__scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
YY_BUFFER_STATE pcap__scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE pcap__scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner );
+YY_BUFFER_STATE pcap__scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
void *pcap_alloc (yy_size_t ,yyscan_t yyscanner );
void *pcap_realloc (void *,yy_size_t ,yyscan_t yyscanner );
@@ -342,7 +349,7 @@ void pcap_free (void * ,yyscan_t yyscanner );
/* Begin user sect3 */
-#define pcap_wrap(yyscanner) 1
+#define pcap_wrap(yyscanner) (/*CONSTCOND*/1)
#define YY_SKIP_YYWRAP
typedef unsigned char YY_CHAR;
@@ -354,20 +361,20 @@ typedef int yy_state_type;
static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
static int yy_get_next_buffer (yyscan_t yyscanner );
-static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+static void yynoreturn yy_fatal_error (yyconst char* msg ,yyscan_t yyscanner );
/* Done after the current pattern has been matched and before the
* corresponding action - sets up yytext.
*/
#define YY_DO_BEFORE_ACTION \
yyg->yytext_ptr = yy_bp; \
- yyleng = (size_t) (yy_cp - yy_bp); \
+ yyleng = (int) (yy_cp - yy_bp); \
yyg->yy_hold_char = *yy_cp; \
*yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp;
-#define YY_NUM_RULES 155
-#define YY_END_OF_BUFFER 156
+#define YY_NUM_RULES 184
+#define YY_END_OF_BUFFER 185
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@@ -375,172 +382,201 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[1464] =
+static yyconst flex_int16_t yy_accept[1729] =
{ 0,
- 0, 0, 156, 153, 113, 113, 113, 114, 153, 114,
- 114, 114, 154, 123, 123, 114, 114, 114, 114, 151,
- 151, 153, 151, 151, 151, 151, 151, 151, 151, 151,
- 151, 151, 151, 151, 151, 151, 151, 151, 151, 151,
- 151, 151, 114, 153, 117, 121, 67, 0, 151, 123,
- 0, 151, 151, 151, 0, 125, 119, 116, 118, 115,
- 120, 151, 152, 152, 151, 151, 151, 20, 151, 151,
- 151, 151, 151, 151, 151, 151, 151, 151, 151, 151,
- 151, 151, 151, 151, 151, 151, 151, 151, 151, 151,
- 151, 151, 151, 151, 151, 151, 151, 151, 151, 151,
-
- 151, 7, 151, 34, 35, 151, 151, 151, 151, 151,
- 151, 151, 151, 151, 151, 151, 151, 151, 151, 92,
- 151, 68, 151, 151, 151, 151, 151, 151, 60, 151,
- 151, 151, 151, 86, 151, 151, 151, 151, 151, 151,
- 61, 151, 4, 151, 151, 151, 151, 151, 151, 151,
- 68, 121, 151, 124, 124, 151, 123, 151, 0, 125,
- 123, 125, 125, 125, 151, 151, 151, 67, 5, 151,
- 81, 151, 151, 151, 151, 151, 151, 151, 55, 107,
- 1, 0, 151, 21, 151, 151, 151, 151, 151, 151,
- 151, 151, 151, 151, 151, 151, 151, 151, 151, 151,
-
- 151, 151, 36, 151, 151, 18, 43, 0, 151, 29,
- 151, 25, 70, 151, 151, 79, 37, 151, 100, 151,
- 151, 151, 151, 101, 151, 46, 69, 82, 106, 151,
- 14, 151, 3, 151, 151, 151, 151, 151, 94, 151,
- 151, 26, 151, 105, 151, 108, 38, 2, 151, 42,
- 151, 9, 151, 10, 89, 151, 88, 151, 151, 0,
- 151, 151, 124, 151, 151, 151, 151, 123, 0, 151,
+ 0, 0, 185, 182, 113, 113, 113, 114, 182, 114,
+ 114, 114, 183, 123, 123, 114, 114, 114, 114, 180,
+ 180, 182, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 114, 182, 117, 121, 67, 0, 180, 123,
+ 0, 180, 180, 180, 0, 125, 119, 116, 118, 115,
+ 120, 180, 181, 181, 180, 180, 180, 20, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+
+ 180, 7, 180, 34, 35, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 92,
+ 180, 68, 180, 180, 180, 180, 180, 180, 60, 180,
+ 180, 180, 180, 86, 180, 180, 180, 180, 180, 180,
+ 61, 180, 4, 180, 180, 180, 180, 180, 180, 180,
+ 68, 121, 180, 124, 124, 180, 123, 180, 0, 125,
+ 123, 125, 125, 125, 180, 180, 180, 67, 5, 180,
+ 81, 180, 180, 180, 180, 180, 180, 180, 55, 107,
+ 1, 0, 180, 21, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+
+ 180, 180, 36, 180, 180, 18, 43, 0, 180, 29,
+ 180, 25, 70, 180, 180, 79, 37, 180, 100, 180,
+ 180, 180, 180, 101, 180, 46, 69, 82, 106, 180,
+ 14, 180, 3, 180, 180, 180, 180, 180, 94, 180,
+ 180, 26, 180, 105, 180, 108, 38, 2, 180, 42,
+ 180, 9, 180, 10, 89, 180, 88, 180, 180, 0,
+ 180, 180, 124, 180, 180, 180, 180, 123, 0, 180,
0, 126, 125, 125, 0, 125, 0, 125, 0, 125,
- 0, 23, 151, 151, 151, 151, 64, 16, 41, 151,
- 39, 151, 151, 151, 30, 151, 98, 151, 151, 151,
-
- 111, 151, 151, 104, 110, 45, 109, 112, 11, 151,
- 12, 13, 151, 151, 151, 32, 78, 151, 62, 3,
- 99, 47, 151, 151, 151, 74, 151, 151, 151, 151,
- 48, 151, 151, 40, 151, 6, 151, 93, 151, 8,
- 95, 151, 151, 0, 151, 53, 73, 15, 151, 124,
- 124, 151, 124, 124, 124, 151, 123, 151, 0, 125,
- 151, 0, 0, 125, 0, 125, 126, 125, 0, 0,
- 0, 0, 125, 125, 125, 125, 125, 0, 151, 56,
- 57, 58, 59, 151, 22, 151, 151, 151, 151, 31,
- 151, 151, 151, 102, 103, 0, 19, 151, 151, 151,
-
- 87, 151, 33, 151, 80, 28, 27, 151, 151, 83,
- 151, 151, 151, 50, 17, 151, 151, 151, 151, 151,
- 151, 151, 151, 151, 151, 151, 151, 0, 151, 151,
- 124, 151, 151, 151, 151, 124, 124, 151, 123, 151,
- 0, 0, 125, 125, 125, 0, 0, 126, 125, 125,
- 126, 125, 0, 0, 125, 125, 125, 125, 125, 0,
- 0, 0, 0, 125, 125, 0, 125, 0, 125, 0,
- 97, 151, 151, 151, 24, 151, 151, 77, 151, 151,
- 151, 151, 151, 151, 151, 151, 151, 151, 151, 151,
- 70, 151, 151, 151, 151, 151, 151, 151, 75, 76,
-
- 151, 96, 151, 151, 151, 151, 151, 151, 151, 151,
- 151, 151, 151, 151, 124, 124, 151, 124, 124, 124,
- 124, 151, 123, 151, 0, 125, 125, 0, 125, 0,
- 0, 125, 0, 125, 126, 125, 0, 0, 0, 125,
- 125, 0, 125, 126, 125, 0, 0, 0, 0, 0,
- 0, 0, 125, 125, 125, 125, 125, 0, 151, 151,
- 151, 151, 52, 63, 151, 151, 151, 151, 151, 151,
- 151, 151, 151, 151, 151, 151, 71, 151, 151, 44,
- 84, 85, 151, 151, 151, 151, 54, 149, 145, 151,
- 147, 146, 150, 151, 0, 151, 151, 124, 151, 151,
-
- 151, 124, 151, 123, 151, 0, 0, 125, 125, 125,
- 125, 125, 125, 0, 0, 126, 125, 125, 125, 0,
+ 0, 23, 180, 180, 180, 180, 64, 16, 41, 180,
+ 39, 180, 180, 180, 30, 180, 98, 180, 180, 180,
+
+ 111, 180, 180, 104, 110, 45, 109, 112, 11, 180,
+ 12, 13, 180, 180, 180, 32, 78, 180, 62, 3,
+ 99, 47, 180, 180, 180, 74, 180, 180, 180, 180,
+ 48, 180, 180, 40, 180, 6, 180, 93, 180, 8,
+ 95, 180, 180, 0, 180, 53, 73, 15, 180, 124,
+ 124, 180, 124, 124, 124, 180, 123, 180, 0, 125,
+ 180, 0, 0, 125, 0, 125, 126, 125, 0, 0,
+ 0, 0, 125, 125, 125, 125, 125, 0, 180, 56,
+ 57, 58, 59, 180, 22, 180, 180, 180, 180, 31,
+ 180, 180, 180, 102, 103, 0, 19, 180, 180, 180,
+
+ 87, 180, 33, 180, 80, 28, 27, 180, 180, 83,
+ 180, 180, 180, 50, 17, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 0,
+ 180, 180, 124, 180, 180, 180, 180, 124, 124, 180,
+ 123, 180, 0, 0, 125, 125, 125, 0, 0, 126,
+ 125, 125, 126, 125, 0, 0, 125, 125, 125, 125,
+ 125, 0, 0, 0, 0, 125, 125, 0, 125, 0,
+ 125, 0, 97, 180, 180, 180, 24, 180, 180, 77,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 0,
+ 180, 180, 180, 180, 180, 70, 180, 180, 180, 180,
+
+ 180, 180, 180, 75, 76, 180, 96, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 124, 124, 180, 124, 124, 124, 124, 180, 123,
+ 180, 0, 125, 125, 0, 125, 0, 0, 125, 0,
+ 125, 126, 125, 0, 0, 0, 125, 125, 0, 125,
+ 126, 125, 0, 0, 0, 0, 0, 0, 0, 125,
+ 125, 125, 125, 125, 0, 180, 180, 180, 180, 52,
+ 63, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 71, 180, 180, 44, 84, 85, 180, 180,
+
+ 180, 180, 54, 176, 179, 178, 172, 180, 174, 173,
+ 177, 180, 0, 180, 180, 124, 180, 180, 180, 124,
+ 180, 123, 180, 0, 0, 125, 125, 125, 125, 125,
+ 125, 0, 0, 126, 125, 125, 125, 0, 0, 125,
+ 125, 125, 125, 125, 0, 0, 0, 0, 0, 0,
0, 125, 125, 125, 125, 125, 0, 0, 0, 0,
- 0, 0, 0, 125, 125, 125, 125, 125, 0, 0,
- 0, 0, 0, 125, 125, 0, 125, 0, 125, 0,
- 151, 151, 151, 151, 151, 151, 151, 151, 151, 151,
- 151, 151, 151, 128, 127, 151, 151, 72, 151, 151,
- 151, 148, 144, 151, 151, 124, 124, 124, 124, 151,
- 123, 151, 0, 125, 125, 0, 125, 125, 0, 125,
- 0, 0, 125, 0, 125, 126, 125, 0, 0, 0,
+ 0, 125, 125, 0, 125, 0, 125, 0, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 128, 127, 180, 180, 72, 180, 180,
+ 180, 175, 171, 180, 180, 124, 124, 124, 124, 180,
+ 123, 180, 0, 125, 125, 0, 125, 125, 0, 125,
+ 0, 0, 125, 0, 125, 126, 125, 0, 0, 0,
125, 125, 0, 125, 126, 125, 0, 0, 0, 0,
0, 125, 125, 0, 125, 126, 125, 0, 125, 125,
0, 0, 0, 0, 0, 0, 0, 125, 125, 125,
- 125, 125, 0, 65, 151, 55, 133, 140, 151, 151,
- 151, 151, 151, 151, 151, 151, 151, 66, 49, 151,
- 151, 0, 151, 151, 151, 151, 151, 123, 151, 0,
+ 125, 125, 0, 65, 180, 55, 133, 140, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 145, 144, 180, 66,
+ 49, 180, 180, 0, 180, 180, 180, 180, 180, 123,
+
+ 180, 0, 0, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 0, 0, 126, 125, 125, 125, 0, 0,
+ 125, 125, 125, 125, 125, 0, 0, 0, 0, 0,
+ 0, 0, 125, 125, 125, 125, 125, 0, 125, 125,
+ 0, 0, 0, 0, 0, 0, 0, 125, 125, 125,
+ 125, 125, 0, 0, 0, 0, 0, 0, 125, 125,
+ 0, 125, 0, 125, 0, 90, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 146, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 51, 122, 122,
+ 124, 124, 180, 123, 180, 0, 125, 125, 0, 125,
+
+ 125, 0, 125, 125, 0, 125, 0, 122, 125, 0,
+ 125, 126, 125, 0, 0, 0, 125, 125, 0, 125,
+ 126, 125, 0, 0, 0, 0, 0, 125, 125, 0,
+ 125, 126, 125, 0, 0, 0, 0, 0, 0, 125,
+ 125, 0, 125, 126, 125, 0, 125, 125, 125, 0,
+ 0, 0, 0, 0, 0, 0, 125, 125, 125, 125,
+ 125, 0, 180, 180, 180, 180, 180, 180, 180, 180,
+ 138, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 91, 122, 122, 124, 180, 122, 122, 0,
0, 125, 125, 125, 125, 125, 125, 125, 125, 125,
- 0, 0, 126, 125, 125, 125, 0, 0, 125, 125,
- 125, 125, 125, 0, 0, 0, 0, 0, 0, 0,
- 125, 125, 125, 125, 125, 0, 125, 125, 0, 0,
-
- 0, 0, 0, 0, 0, 125, 125, 125, 125, 125,
- 0, 0, 0, 0, 0, 0, 125, 125, 0, 125,
- 0, 125, 0, 90, 151, 151, 151, 151, 151, 151,
- 151, 151, 151, 151, 151, 51, 122, 122, 124, 124,
- 151, 123, 151, 0, 125, 125, 0, 125, 125, 0,
- 125, 125, 0, 125, 0, 122, 125, 0, 125, 126,
- 125, 0, 0, 0, 125, 125, 0, 125, 126, 125,
- 0, 0, 0, 0, 0, 125, 125, 0, 125, 126,
- 125, 0, 0, 0, 0, 0, 0, 125, 125, 0,
- 125, 126, 125, 0, 125, 125, 125, 0, 0, 0,
+ 125, 125, 125, 0, 122, 126, 125, 125, 125, 0,
+ 0, 125, 125, 125, 125, 125, 0, 0, 0, 0,
+ 0, 0, 0, 125, 125, 125, 125, 125, 0, 125,
+ 125, 0, 0, 0, 0, 0, 0, 0, 125, 125,
+ 125, 125, 125, 0, 125, 125, 125, 0, 0, 0,
0, 0, 0, 0, 125, 125, 125, 125, 125, 0,
- 151, 151, 151, 151, 151, 151, 151, 151, 138, 151,
- 91, 122, 122, 124, 151, 122, 122, 0, 0, 125,
- 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
- 125, 0, 122, 126, 125, 125, 125, 0, 0, 125,
- 125, 125, 125, 125, 0, 0, 0, 0, 0, 0,
- 0, 125, 125, 125, 125, 125, 0, 125, 125, 0,
- 0, 0, 0, 0, 0, 0, 125, 125, 125, 125,
- 125, 0, 125, 125, 125, 0, 0, 0, 0, 0,
- 0, 0, 125, 125, 125, 125, 125, 0, 0, 0,
-
- 0, 0, 0, 125, 125, 0, 125, 0, 125, 0,
- 151, 151, 151, 142, 151, 151, 151, 151, 151, 151,
- 151, 130, 124, 151, 123, 0, 125, 125, 0, 125,
- 125, 0, 125, 125, 0, 125, 125, 0, 125, 0,
- 0, 0, 125, 0, 0, 125, 126, 125, 0, 0,
- 0, 125, 125, 0, 125, 126, 125, 0, 0, 0,
- 0, 0, 125, 125, 0, 125, 126, 125, 0, 0,
+ 0, 0, 0, 0, 0, 125, 125, 0, 125, 0,
+ 125, 0, 180, 180, 180, 142, 180, 180, 180, 180,
+ 180, 180, 180, 130, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 124, 180, 123, 0, 125, 125,
+
+ 0, 125, 125, 0, 125, 125, 0, 125, 125, 0,
+ 125, 0, 0, 0, 125, 0, 0, 125, 126, 125,
+ 0, 0, 0, 125, 125, 0, 125, 126, 125, 0,
0, 0, 0, 0, 125, 125, 0, 125, 126, 125,
0, 0, 0, 0, 0, 0, 125, 125, 0, 125,
- 126, 125, 0, 125, 125, 125, 0, 0, 0, 0,
+ 126, 125, 0, 0, 0, 0, 0, 0, 125, 125,
+ 0, 125, 126, 125, 0, 125, 125, 125, 0, 0,
+ 0, 0, 0, 0, 0, 125, 125, 125, 125, 125,
+ 0, 180, 180, 180, 180, 132, 180, 180, 180, 136,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
- 0, 0, 0, 125, 125, 125, 125, 125, 0, 151,
- 151, 151, 151, 132, 151, 151, 151, 136, 151, 122,
- 0, 0, 125, 125, 125, 125, 125, 125, 125, 125,
- 125, 125, 125, 125, 125, 125, 125, 0, 0, 0,
- 126, 0, 0, 125, 0, 0, 125, 125, 125, 0,
- 0, 0, 0, 0, 0, 0, 125, 125, 125, 0,
- 125, 125, 0, 0, 0, 0, 0, 0, 0, 125,
- 125, 125, 0, 125, 125, 125, 0, 0, 0, 0,
+ 180, 180, 180, 122, 0, 0, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 0, 0, 0, 126, 0, 0, 125, 0, 0,
+ 125, 125, 125, 0, 0, 0, 0, 0, 0, 0,
+ 125, 125, 125, 0, 125, 125, 0, 0, 0, 0,
0, 0, 0, 125, 125, 125, 0, 125, 125, 125,
0, 0, 0, 0, 0, 0, 0, 125, 125, 125,
-
- 0, 0, 0, 0, 0, 0, 125, 125, 0, 125,
- 0, 125, 0, 129, 141, 143, 137, 151, 151, 151,
- 151, 0, 0, 125, 0, 125, 0, 125, 125, 0,
- 125, 125, 0, 125, 125, 0, 125, 125, 0, 125,
- 0, 0, 0, 0, 125, 125, 0, 125, 0, 0,
- 125, 125, 125, 0, 0, 0, 0, 125, 125, 125,
- 0, 0, 0, 0, 0, 125, 125, 125, 0, 0,
+ 0, 125, 125, 125, 0, 0, 0, 0, 0, 0,
+ 0, 125, 125, 125, 0, 0, 0, 0, 0, 0,
+ 125, 125, 0, 125, 0, 125, 0, 129, 141, 143,
+
+ 137, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 155, 180, 180, 180, 0, 0, 125,
+ 0, 125, 0, 125, 125, 0, 125, 125, 0, 125,
+ 125, 0, 125, 125, 0, 125, 0, 0, 0, 0,
+ 125, 125, 0, 125, 0, 0, 125, 125, 125, 0,
0, 0, 0, 125, 125, 125, 0, 0, 0, 0,
- 0, 125, 125, 125, 125, 125, 125, 0, 0, 0,
- 0, 0, 0, 0, 125, 125, 125, 0, 151, 151,
-
- 151, 151, 0, 0, 0, 125, 125, 125, 125, 125,
- 125, 0, 0, 0, 0, 125, 125, 0, 0, 0,
0, 125, 125, 125, 0, 0, 0, 0, 0, 125,
+ 125, 125, 0, 0, 0, 0, 0, 125, 125, 125,
+ 125, 125, 125, 0, 0, 0, 0, 0, 0, 0,
+ 125, 125, 125, 0, 180, 180, 180, 180, 180, 180,
+
+ 147, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 0, 0, 0, 125, 125, 125, 125, 125, 125,
+ 0, 0, 0, 0, 125, 125, 0, 0, 0, 0,
125, 125, 125, 0, 0, 0, 0, 0, 125, 125,
125, 125, 0, 0, 0, 0, 0, 125, 125, 125,
- 125, 0, 0, 0, 0, 0, 125, 0, 0, 0,
- 0, 0, 125, 125, 125, 151, 151, 151, 139, 125,
- 125, 125, 125, 125, 125, 125, 125, 0, 0, 0,
- 0, 125, 125, 0, 0, 125, 0, 0, 0, 125,
- 0, 0, 0, 125, 0, 0, 0, 125, 0, 0,
-
- 0, 125, 125, 125, 125, 0, 0, 0, 0, 0,
- 125, 134, 151, 131, 125, 0, 0, 125, 125, 0,
- 125, 125, 125, 0, 125, 125, 125, 0, 125, 125,
- 125, 0, 125, 125, 125, 0, 0, 0, 0, 125,
- 135, 125, 125, 0, 0, 0, 0, 0, 0, 125,
- 125, 125, 0, 0, 125, 125, 125, 125, 125, 0,
- 125, 125, 0
+ 125, 0, 0, 0, 0, 0, 125, 125, 125, 125,
+ 0, 0, 0, 0, 0, 125, 0, 0, 0, 0,
+ 0, 125, 125, 125, 180, 180, 180, 139, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 125, 125, 125, 125, 125, 125, 125, 125, 0,
+
+ 0, 0, 0, 125, 125, 0, 0, 125, 0, 0,
+ 0, 125, 0, 0, 0, 125, 0, 0, 0, 125,
+ 0, 0, 0, 125, 125, 125, 125, 0, 0, 0,
+ 0, 0, 125, 134, 180, 131, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 156, 180, 125,
+ 0, 0, 125, 125, 0, 125, 125, 125, 0, 125,
+ 125, 125, 0, 125, 125, 125, 0, 125, 125, 125,
+ 0, 0, 0, 0, 125, 135, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 152, 180, 125, 125,
+ 0, 0, 0, 0, 0, 0, 125, 125, 125, 0,
+
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 151, 0, 125, 125, 125, 125, 125, 0, 167,
+ 180, 180, 180, 180, 180, 180, 180, 154, 180, 180,
+ 125, 125, 166, 180, 180, 180, 180, 180, 180, 153,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 165, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 164, 180, 180, 180,
+ 180, 180, 170, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 157, 180, 180, 180, 180, 180, 150,
+
+ 180, 180, 168, 180, 180, 180, 180, 180, 180, 148,
+ 180, 169, 180, 163, 180, 180, 180, 180, 158, 180,
+ 160, 180, 180, 162, 159, 149, 161, 0
} ;
-static yyconst flex_int32_t yy_ec[256] =
+static yyconst YY_CHAR yy_ec[256] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
@@ -572,7 +608,7 @@ static yyconst flex_int32_t yy_ec[256] =
1, 1, 1, 1, 1
} ;
-static yyconst flex_int32_t yy_meta[54] =
+static yyconst YY_CHAR yy_meta[54] =
{ 0,
1, 2, 2, 1, 2, 1, 1, 3, 2, 4,
5, 6, 6, 6, 6, 6, 6, 6, 7, 3,
@@ -582,231 +618,259 @@ static yyconst flex_int32_t yy_meta[54] =
9, 4, 3
} ;
-static yyconst flex_int16_t yy_base[1924] =
+static yyconst flex_uint16_t yy_base[2189] =
{ 0,
- 0, 0, 3898, 53, 7420, 7420, 57, 3862, 64, 81,
- 3874, 7420, 7420, 99, 30, 151, 46, 3860, 52, 168,
+ 0, 0, 5455, 53, 7856, 7856, 57, 5433, 64, 81,
+ 5445, 7856, 7856, 99, 30, 151, 46, 5430, 52, 168,
210, 168, 160, 44, 125, 60, 31, 58, 132, 170,
- 214, 217, 229, 59, 170, 222, 237, 243, 250, 3848,
- 255, 3840, 3824, 300, 7420, 0, 7420, 316, 339, 363,
- 3857, 387, 0, 394, 0, 428, 7420, 7420, 7420, 7420,
- 7420, 296, 316, 0, 3830, 3812, 3826, 0, 3825, 3813,
- 3826, 3822, 3810, 3804, 3791, 3794, 3793, 3792, 3801, 3785,
- 3798, 3781, 116, 3776, 3779, 3764, 3762, 3767, 3773, 3762,
- 3767, 3743, 3742, 56, 68, 3747, 3745, 80, 3749, 3743,
-
- 3752, 68, 166, 0, 0, 15, 122, 3740, 3734, 189,
- 3718, 3716, 3719, 3722, 3710, 3718, 3695, 3694, 3700, 0,
- 3708, 0, 3691, 3696, 3690, 3691, 3676, 3676, 128, 3687,
- 3670, 3680, 3672, 159, 3653, 201, 3651, 38, 3650, 3662,
- 0, 3648, 0, 3646, 3645, 3650, 3642, 3633, 3624, 3639,
- 7420, 7420, 453, 477, 236, 518, 542, 566, 3647, 573,
- 3653, 597, 248, 3629, 3604, 3609, 3600, 0, 0, 3605,
- 0, 3613, 3608, 3597, 3581, 3582, 3579, 3580, 3586, 0,
- 0, 3581, 3571, 0, 3568, 3563, 3551, 3565, 3564, 3566,
- 3563, 3547, 3546, 3522, 3538, 3520, 3524, 3518, 3520, 3533,
-
- 3518, 3503, 0, 3508, 3502, 0, 0, 3506, 3494, 0,
- 3506, 0, 3503, 3491, 3489, 0, 0, 3458, 0, 3467,
- 3475, 244, 3456, 0, 3453, 3469, 0, 3464, 0, 3467,
- 0, 3434, 3438, 3432, 3435, 3439, 3432, 3428, 0, 3426,
- 3425, 0, 3414, 0, 3412, 0, 0, 0, 3408, 0,
- 153, 156, 3419, 0, 0, 3409, 0, 3391, 3392, 637,
- 3422, 660, 684, 3420, 691, 500, 281, 715, 3409, 739,
- 3408, 3407, 747, 290, 3391, 3390, 507, 788, 811, 3389,
- 0, 0, 3363, 350, 3354, 3357, 0, 0, 0, 3346,
- 0, 3345, 3338, 3322, 0, 3321, 0, 3296, 3296, 3297,
-
- 0, 3295, 3294, 0, 0, 0, 0, 0, 614, 3300,
- 0, 0, 3294, 3266, 3266, 0, 0, 3258, 0, 0,
- 0, 0, 3273, 3264, 3250, 0, 3243, 3246, 3262, 3235,
- 3229, 3240, 3220, 0, 3198, 0, 3197, 0, 275, 0,
- 0, 3190, 3181, 739, 3193, 0, 0, 0, 836, 860,
- 293, 901, 3205, 3203, 405, 924, 948, 972, 3194, 979,
- 621, 3193, 3190, 1002, 776, 1026, 1049, 3178, 0, 3173,
- 427, 428, 1073, 3172, 1097, 333, 3171, 3162, 3130, 0,
- 0, 0, 0, 3122, 0, 3125, 3121, 3104, 3103, 0,
- 3098, 3082, 3078, 0, 0, 1116, 0, 3068, 3057, 3075,
-
- 0, 3064, 0, 3068, 3061, 0, 0, 3071, 3053, 291,
- 3043, 3060, 294, 3054, 0, 3033, 3004, 3018, 3011, 3005,
- 3015, 3008, 2996, 2973, 2966, 2972, 2987, 1153, 3004, 1176,
- 1200, 3002, 1207, 883, 285, 1231, 334, 1271, 1294, 1318,
- 2993, 2977, 1326, 336, 2976, 2975, 2973, 2971, 1367, 363,
- 2970, 2969, 515, 631, 1408, 2968, 1432, 364, 2953, 2960,
- 2948, 890, 0, 371, 2947, 1120, 1473, 1496, 2946, 0,
- 0, 2918, 2920, 2901, 0, 2909, 2890, 0, 2896, 2877,
- 2862, 2877, 2875, 380, 2860, 427, 2860, 2868, 2841, 2851,
- 0, 2841, 2852, 2843, 2847, 2846, 2835, 2819, 0, 0,
-
- 2823, 0, 2818, 2810, 2823, 2821, 2815, 2811, 2791, 2789,
- 2794, 2799, 2798, 1521, 1545, 423, 1586, 2820, 2819, 633,
- 1610, 1634, 1641, 1665, 2810, 1672, 1696, 1719, 2794, 2793,
- 2792, 1742, 1127, 1766, 1789, 2791, 0, 1254, 0, 461,
- 2790, 1261, 1813, 1836, 2788, 0, 758, 785, 2795, 485,
- 805, 836, 1860, 2786, 1884, 424, 2771, 2778, 405, 2742,
- 2747, 2744, 0, 0, 2748, 2750, 2736, 2721, 2733, 2716,
- 2715, 2722, 2713, 2714, 2725, 2710, 0, 2701, 2695, 0,
- 0, 0, 2708, 2704, 2708, 2695, 0, 0, 0, 2699,
- 0, 0, 0, 2673, 1924, 2708, 1947, 1971, 2706, 1978,
-
- 425, 2002, 2026, 2033, 2057, 2697, 2696, 2065, 452, 2693,
- 2106, 476, 2692, 2677, 2676, 2675, 2147, 512, 2674, 898,
- 918, 2188, 2673, 2212, 513, 2671, 2678, 1147, 1149, 2677,
- 2661, 1270, 1336, 2253, 2652, 2277, 517, 2651, 2658, 1350,
- 0, 1357, 0, 486, 2648, 1390, 2318, 2341, 2646, 0,
- 2364, 452, 57, 497, 150, 641, 205, 610, 2602, 258,
- 291, 570, 1148, 2601, 2600, 1266, 2599, 2598, 1362, 873,
- 498, 2596, 2595, 2402, 2439, 2475, 2511, 518, 2535, 551,
- 2543, 2567, 2622, 2574, 2598, 2621, 2606, 2645, 2668, 2605,
- 2604, 2603, 2691, 1398, 2715, 2738, 2601, 0, 1455, 0,
-
- 582, 2600, 1462, 2762, 2785, 2599, 0, 1568, 0, 1575,
- 0, 699, 2583, 1907, 2809, 2832, 2582, 0, 570, 1914,
- 2589, 1470, 1490, 2588, 2587, 1521, 1583, 2856, 2577, 2880,
- 572, 2576, 2583, 590, 652, 615, 636, 787, 1270, 2075,
- 1407, 706, 709, 827, 2102, 707, 829, 631, 785, 2100,
- 2104, 2922, 852, 2945, 853, 2968, 2133, 2992, 3016, 2574,
- 2552, 3024, 660, 2551, 3065, 661, 2550, 3106, 690, 2549,
- 2548, 2546, 2545, 3147, 761, 2544, 1713, 1923, 3188, 2543,
- 3212, 897, 2520, 2527, 2075, 2076, 2526, 2525, 2082, 2142,
- 3253, 2516, 3277, 900, 2514, 2521, 901, 2170, 2520, 2143,
-
- 2144, 2519, 2472, 2164, 2185, 3318, 2463, 3342, 919, 2462,
- 2456, 0, 2235, 0, 2242, 0, 756, 2447, 2300, 3383,
- 3406, 2446, 0, 917, 940, 994, 995, 1923, 996, 1472,
- 1020, 1041, 2295, 1042, 1585, 918, 3431, 3454, 3478, 947,
- 3518, 3542, 3566, 2445, 3573, 3597, 3620, 2394, 3644, 3667,
- 2366, 3691, 3714, 2365, 2364, 2350, 3737, 2387, 3761, 3784,
- 2349, 0, 2425, 0, 956, 2348, 2462, 3808, 3831, 2344,
- 0, 2482, 0, 2489, 0, 988, 2343, 2496, 3855, 3878,
- 2325, 0, 0, 2503, 0, 2903, 0, 1035, 2324, 2910,
- 3902, 3925, 2305, 0, 0, 949, 3047, 2310, 2250, 2314,
-
- 2309, 2308, 2315, 2335, 3949, 2284, 3973, 1025, 2280, 2286,
- 2378, 2379, 2380, 2146, 1067, 2252, 2317, 1090, 2381, 1065,
- 1089, 1145, 1147, 4015, 4039, 4048, 1168, 2260, 2259, 4066,
- 1046, 2258, 4107, 1096, 2255, 4148, 1099, 2254, 4189, 1100,
- 2221, 2220, 2219, 4229, 4253, 1129, 2215, 2433, 2434, 4294,
- 2214, 4318, 1152, 2213, 2203, 2615, 2662, 2202, 2201, 2918,
- 2919, 4359, 2190, 4383, 1176, 2178, 2181, 1177, 3054, 2162,
- 2922, 3062, 2132, 2102, 3075, 3081, 4424, 2092, 4448, 1201,
- 2090, 2097, 0, 1204, 3129, 2095, 3082, 3103, 2094, 2093,
- 3123, 3142, 4489, 2083, 4513, 1206, 2073, 2080, 0, 3170,
-
- 0, 3235, 0, 1239, 2070, 3242, 4554, 4577, 2042, 0,
- 3287, 3288, 3352, 1169, 2418, 2124, 1286, 2419, 2294, 1426,
- 1512, 1223, 4602, 4626, 4635, 2041, 4652, 4676, 4699, 2040,
- 4723, 4746, 2039, 4770, 4793, 2038, 4817, 4840, 2036, 2035,
- 4864, 1265, 2034, 2033, 3305, 4905, 2010, 2009, 0, 3369,
- 0, 1335, 2008, 3501, 4929, 2007, 2005, 0, 3508, 0,
- 3996, 0, 1505, 2004, 4003, 4953, 2003, 1987, 0, 0,
- 4055, 0, 4089, 0, 1554, 1985, 4096, 4977, 1983, 1981,
- 0, 0, 4130, 0, 4137, 0, 1595, 1980, 4171, 5001,
- 1979, 1954, 0, 0, 1268, 4178, 1938, 3144, 3164, 1895,
-
- 1852, 3183, 3185, 5025, 1843, 5049, 1297, 1842, 1827, 1688,
- 1689, 1711, 1539, 1225, 1760, 4187, 1538, 1366, 2420, 5091,
- 1794, 5108, 5132, 1405, 1775, 5173, 1408, 1772, 5214, 1409,
- 1771, 5255, 1469, 1748, 5296, 1472, 1747, 1728, 4215, 5337,
- 1727, 1726, 0, 1724, 3250, 3288, 5361, 1650, 1644, 1651,
- 3313, 3352, 1618, 1601, 3379, 3400, 5385, 1588, 1545, 1536,
- 1580, 4276, 1532, 3431, 3517, 1531, 1507, 3614, 3661, 5409,
- 1480, 1479, 1482, 0, 1585, 4283, 1442, 3708, 4199, 1421,
- 1418, 4200, 4224, 5433, 1409, 1374, 1380, 0, 1586, 4341,
- 1378, 4228, 4291, 1377, 1342, 4335, 4354, 5457, 1333, 1331,
-
- 1309, 0, 4406, 0, 4413, 0, 1619, 1278, 4471, 5481,
- 0, 1273, 0, 1690, 1734, 1758, 1759, 1782, 1993, 4507,
- 4523, 5505, 1610, 0, 1272, 5546, 0, 1240, 5570, 0,
- 1215, 5594, 0, 1213, 5618, 0, 1185, 5642, 0, 75,
- 4356, 4421, 5666, 102, 137, 143, 203, 198, 4478, 0,
- 1649, 217, 250, 4540, 0, 4642, 0, 1822, 306, 317,
- 0, 4887, 0, 4894, 0, 1845, 341, 348, 0, 5072,
- 0, 5079, 0, 1869, 372, 412, 0, 5098, 0, 5155,
- 0, 1893, 414, 431, 0, 1640, 5162, 443, 4486, 4550,
- 470, 556, 4571, 4651, 5690, 551, 0, 583, 2382, 1783,
-
- 1806, 1829, 5714, 600, 621, 0, 0, 0, 0, 0,
- 0, 5196, 0, 1933, 644, 646, 0, 4693, 4740, 702,
- 731, 0, 1641, 5203, 732, 4787, 4834, 760, 763, 0,
- 0, 1642, 5237, 797, 4902, 5107, 803, 820, 0, 0,
- 1669, 5244, 822, 5252, 5265, 824, 827, 0, 0, 1671,
- 5279, 868, 5293, 5306, 871, 873, 0, 0, 5320, 0,
- 5528, 0, 1956, 867, 0, 3102, 2983, 2180, 1807, 0,
- 7420, 0, 0, 0, 0, 0, 0, 5334, 5522, 877,
- 910, 0, 7420, 5536, 0, 7420, 0, 5737, 0, 7420,
- 0, 5744, 0, 7420, 0, 5751, 0, 7420, 0, 5758,
-
- 0, 7420, 0, 1672, 5765, 965, 5773, 5774, 990, 1986,
- 0, 1830, 3360, 1877, 0, 5774, 0, 1835, 5788, 992,
- 0, 1857, 5795, 1015, 0, 1859, 5802, 1036, 0, 1860,
- 5814, 1083, 0, 1918, 5821, 1108, 0, 5828, 0, 7420,
- 1940, 1920, 5835, 1135, 0, 0, 0, 0, 0, 0,
- 1921, 5842, 1141, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 7420, 5860, 5868, 5872, 5875, 5878, 5881, 5884,
- 5887, 5890, 5893, 5896, 5899, 5902, 5905, 5908, 5911, 5914,
- 5917, 5920, 5924, 5928, 5931, 5934, 5937, 5940, 5943, 5946,
- 5949, 5952, 5956, 5960, 5963, 5966, 5970, 5972, 5975, 5978,
-
- 5981, 5984, 5987, 5990, 5993, 5996, 6000, 6002, 6005, 6009,
- 6014, 6018, 6021, 6025, 6028, 6031, 6034, 6037, 6040, 6043,
- 6046, 6050, 6054, 6057, 6061, 6065, 6070, 6074, 6076, 6080,
- 6083, 6087, 6090, 6093, 6097, 6099, 6102, 6105, 6108, 6111,
- 6114, 6117, 6120, 6123, 6126, 6130, 6132, 6135, 6138, 6141,
- 6145, 6147, 6150, 6153, 6158, 6162, 6167, 6171, 6173, 6177,
- 6180, 6184, 6189, 6193, 6196, 6199, 6202, 6205, 6208, 6211,
- 6214, 6218, 6222, 6225, 6229, 6233, 6238, 6242, 6244, 6248,
- 6251, 6255, 6258, 6263, 6267, 6272, 6276, 6278, 6282, 6285,
- 6289, 6292, 6295, 6298, 6302, 6304, 6307, 6312, 6316, 6319,
-
- 6322, 6325, 6328, 6331, 6334, 6337, 6340, 6344, 6346, 6349,
- 6352, 6355, 6359, 6361, 6364, 6367, 6370, 6373, 6377, 6379,
- 6382, 6385, 6388, 6393, 6397, 6402, 6406, 6408, 6412, 6415,
- 6419, 6424, 6428, 6431, 6434, 6437, 6440, 6443, 6446, 6449,
- 6453, 6457, 6460, 6464, 6468, 6473, 6477, 6479, 6483, 6486,
- 6490, 6493, 6498, 6502, 6507, 6511, 6513, 6517, 6520, 6524,
- 6527, 6530, 6535, 6539, 6544, 6548, 6550, 6554, 6557, 6561,
- 6564, 6567, 6570, 6574, 6576, 6579, 6584, 6588, 6591, 6594,
- 6597, 6600, 6603, 6606, 6609, 6612, 6615, 6618, 6621, 6625,
- 6627, 6630, 6633, 6636, 6639, 6643, 6645, 6648, 6651, 6654,
-
- 6657, 6660, 6664, 6666, 6669, 6672, 6675, 6678, 6681, 6685,
- 6687, 6690, 6693, 6696, 6699, 6704, 6708, 6713, 6717, 6719,
- 6723, 6726, 6730, 6735, 6739, 6742, 6745, 6748, 6751, 6754,
- 6757, 6760, 6763, 6766, 6770, 6774, 6777, 6781, 6785, 6790,
- 6794, 6796, 6800, 6803, 6807, 6810, 6815, 6819, 6824, 6828,
- 6830, 6834, 6837, 6841, 6844, 6847, 6852, 6856, 6861, 6865,
- 6867, 6871, 6874, 6878, 6881, 6884, 6889, 6893, 6898, 6902,
- 6904, 6908, 6911, 6915, 6918, 6921, 6924, 6928, 6930, 6933,
- 6936, 6941, 6945, 6948, 6951, 6954, 6957, 6960, 6963, 6966,
- 6969, 6972, 6975, 6978, 6982, 6986, 6989, 6992, 6996, 6999,
-
- 7002, 7006, 7008, 7011, 7014, 7018, 7020, 7023, 7026, 7029,
- 7033, 7035, 7038, 7041, 7044, 7048, 7050, 7053, 7056, 7059,
- 7063, 7065, 7068, 7071, 7076, 7080, 7085, 7089, 7091, 7095,
- 7098, 7102, 7107, 7111, 7114, 7117, 7120, 7123, 7126, 7129,
- 7132, 7135, 7139, 7141, 7144, 7148, 7153, 7157, 7158, 7161,
- 7166, 7170, 7175, 7179, 7180, 7183, 7186, 7191, 7195, 7200,
- 7204, 7205, 7208, 7211, 7216, 7220, 7225, 7229, 7230, 7233,
- 7236, 7241, 7245, 7250, 7254, 7255, 7258, 7261, 7264, 7268,
- 7270, 7275, 7279, 7282, 7285, 7288, 7291, 7294, 7297, 7301,
- 7306, 7310, 7311, 7314, 7317, 7320, 7323, 7326, 7329, 7332,
-
- 7335, 7338, 7341, 7346, 7350, 7353, 7356, 7359, 7363, 7367,
- 7371, 7375, 7379, 7382, 7385, 7389, 7392, 7395, 7398, 7401,
- 7404, 7408, 7411
+ 214, 217, 229, 59, 170, 222, 237, 243, 250, 5418,
+ 255, 5410, 5380, 300, 7856, 0, 7856, 316, 339, 363,
+ 5413, 387, 0, 394, 0, 428, 7856, 7856, 7856, 7856,
+ 7856, 296, 316, 0, 5386, 5383, 5397, 0, 5395, 5383,
+ 5396, 5378, 5366, 5360, 5361, 5362, 5360, 5344, 5352, 5337,
+ 5350, 5331, 116, 5341, 5312, 5297, 5295, 5299, 5305, 5294,
+ 5299, 5279, 5278, 56, 68, 5263, 5261, 80, 5265, 5259,
+
+ 5267, 68, 166, 0, 0, 15, 122, 5255, 5264, 189,
+ 5238, 5236, 5219, 5222, 5212, 5219, 5209, 5208, 5214, 0,
+ 5212, 0, 5195, 5181, 5175, 5176, 5175, 5174, 128, 5185,
+ 5168, 5167, 5160, 159, 5147, 201, 5144, 38, 5137, 5149,
+ 0, 5133, 0, 5112, 5111, 5094, 5090, 5078, 5048, 5062,
+ 7856, 7856, 453, 477, 236, 518, 542, 566, 5071, 573,
+ 5078, 597, 248, 5054, 5029, 5034, 5025, 0, 0, 5030,
+ 0, 5038, 5033, 5022, 5006, 5007, 5004, 5005, 5012, 0,
+ 0, 5006, 4996, 0, 5008, 4988, 4976, 4990, 4989, 4992,
+ 4988, 4972, 4971, 4953, 4969, 4952, 4956, 4951, 4952, 4965,
+
+ 4950, 4934, 0, 4939, 4933, 0, 0, 4937, 4927, 0,
+ 4938, 0, 4935, 4907, 4912, 0, 0, 4901, 0, 4909,
+ 4917, 244, 4899, 0, 4887, 4882, 0, 4877, 0, 4880,
+ 0, 4861, 4864, 4857, 4845, 4850, 4843, 4839, 0, 4837,
+ 4849, 0, 4838, 0, 4837, 0, 0, 0, 4819, 0,
+ 153, 156, 4830, 0, 0, 4821, 0, 4818, 4818, 637,
+ 4847, 660, 684, 4830, 691, 500, 281, 715, 4821, 739,
+ 4820, 4819, 747, 290, 4818, 4816, 507, 788, 811, 4815,
+ 0, 0, 4775, 350, 4778, 4783, 0, 0, 0, 4781,
+ 0, 4777, 4762, 4746, 0, 4746, 0, 4740, 4739, 4740,
+
+ 0, 4722, 4721, 0, 0, 0, 0, 0, 614, 4728,
+ 0, 0, 4736, 4715, 4700, 0, 0, 4698, 0, 0,
+ 0, 0, 4713, 4704, 4710, 0, 4703, 4706, 4707, 4679,
+ 4675, 4667, 4639, 0, 4632, 0, 4607, 0, 275, 0,
+ 0, 4599, 4592, 817, 4585, 0, 0, 0, 856, 880,
+ 293, 921, 4610, 4608, 405, 944, 968, 992, 4598, 999,
+ 621, 4581, 4579, 1022, 770, 1046, 1069, 4562, 0, 4553,
+ 427, 428, 1093, 4552, 1117, 333, 4551, 4550, 4519, 0,
+ 0, 0, 0, 4491, 0, 4504, 4502, 4469, 4460, 0,
+ 4477, 4472, 4463, 0, 0, 1136, 293, 4453, 4420, 4437,
+
+ 0, 4427, 0, 4429, 4422, 0, 0, 4420, 4394, 292,
+ 4393, 4411, 387, 4408, 0, 4390, 4382, 4394, 4368, 4362,
+ 4372, 4350, 4357, 4338, 4317, 4318, 4310, 4278, 4292, 1173,
+ 4310, 1196, 1220, 4305, 1227, 777, 285, 1251, 334, 1291,
+ 1314, 1338, 4294, 4293, 1346, 336, 4291, 4256, 4255, 4254,
+ 1387, 363, 4252, 4251, 515, 631, 1428, 4250, 1452, 364,
+ 4240, 4247, 4218, 840, 0, 371, 4214, 903, 1493, 1516,
+ 4212, 0, 0, 4184, 4200, 4149, 0, 4158, 4140, 0,
+ 4145, 4158, 4143, 4126, 4125, 380, 4109, 427, 4108, 1121,
+ 4106, 4095, 4082, 4067, 4076, 0, 4066, 4077, 4025, 4028,
+
+ 4026, 4015, 4014, 0, 0, 4018, 0, 3981, 3973, 3986,
+ 3984, 3976, 3949, 3960, 3929, 3923, 3918, 3909, 3888, 3885,
+ 1541, 1565, 423, 1606, 3892, 3888, 633, 1630, 1654, 1661,
+ 1685, 3877, 1692, 1716, 1739, 3876, 3857, 3856, 1762, 910,
+ 1786, 1809, 3852, 0, 1274, 0, 461, 3837, 1281, 1833,
+ 1856, 3833, 0, 785, 824, 3820, 485, 853, 856, 1880,
+ 3810, 1904, 424, 3809, 3798, 529, 3762, 3765, 3739, 0,
+ 0, 3742, 3729, 3715, 3691, 3703, 3683, 3666, 3672, 3664,
+ 3643, 3632, 3633, 3619, 3601, 56, 504, 646, 3609, 3575,
+ 3584, 3582, 0, 3573, 3567, 0, 0, 0, 3580, 3552,
+
+ 3533, 3519, 0, 0, 0, 0, 0, 3523, 0, 0,
+ 0, 3512, 1944, 3547, 1967, 1991, 3514, 1998, 325, 2022,
+ 2046, 2053, 2077, 3505, 3474, 2085, 452, 3434, 2126, 476,
+ 3393, 3386, 3385, 3365, 2167, 513, 3345, 918, 938, 2208,
+ 3344, 2232, 542, 3343, 3348, 1142, 1149, 3347, 3314, 1167,
+ 1169, 2273, 3305, 2297, 543, 3304, 3310, 1369, 0, 1376,
+ 0, 486, 3282, 1410, 2338, 2361, 3278, 0, 2384, 374,
+ 115, 389, 150, 672, 205, 610, 3235, 550, 403, 313,
+ 783, 553, 761, 522, 800, 451, 578, 893, 633, 829,
+ 571, 1108, 1112, 3231, 3228, 1123, 3206, 3189, 1130, 1128,
+
+ 593, 3186, 3185, 2422, 2459, 2495, 2531, 634, 2555, 258,
+ 2563, 2587, 3194, 2594, 2618, 2641, 3193, 2665, 2688, 3191,
+ 3188, 3185, 2711, 1417, 2735, 2758, 3184, 0, 1475, 0,
+ 723, 3172, 1482, 2782, 2805, 3147, 0, 1588, 0, 1595,
+ 0, 724, 3146, 1927, 2829, 2852, 3135, 0, 661, 1934,
+ 3122, 1290, 1425, 3114, 3111, 1490, 1510, 2876, 3101, 2900,
+ 662, 3090, 3061, 636, 803, 653, 1290, 1427, 1492, 2095,
+ 1604, 708, 849, 937, 2122, 872, 1605, 1944, 804, 1187,
+ 1242, 2099, 936, 960, 1532, 2101, 874, 938, 1015, 962,
+ 1014, 2124, 2163, 2942, 1016, 2965, 1038, 2988, 2154, 3012,
+
+ 3036, 3052, 3051, 3044, 686, 3049, 3085, 967, 3047, 3126,
+ 969, 3046, 3045, 3020, 3017, 3167, 970, 2967, 1541, 1733,
+ 3208, 2966, 3232, 1022, 2947, 2953, 2096, 2163, 2951, 2950,
+ 2164, 2182, 3273, 2909, 3297, 1042, 2908, 2915, 1043, 2255,
+ 2913, 2183, 2184, 2911, 2892, 2205, 2249, 3338, 2882, 3362,
+ 1045, 2881, 2886, 0, 2263, 0, 2320, 0, 756, 2857,
+ 2327, 3403, 3426, 2853, 0, 1061, 1062, 1087, 1111, 2337,
+ 1188, 1943, 1189, 1244, 2376, 1534, 2377, 2336, 1109, 1243,
+ 2402, 2013, 1306, 2096, 2378, 1446, 2375, 1245, 3451, 3474,
+ 3498, 1066, 3538, 3562, 3586, 2834, 3593, 3617, 3640, 2830,
+
+ 3664, 3687, 2811, 3711, 3734, 2810, 2806, 2791, 3757, 2445,
+ 3781, 3804, 2789, 0, 2482, 0, 1008, 2787, 2502, 3828,
+ 3851, 2744, 0, 2509, 0, 2516, 0, 1153, 2741, 2523,
+ 3875, 3898, 2740, 0, 0, 2923, 0, 2930, 0, 1300,
+ 2718, 3067, 3922, 3945, 2717, 0, 0, 1198, 3074, 2724,
+ 2399, 2417, 2721, 2701, 2453, 2454, 3969, 2670, 3993, 1285,
+ 2649, 2655, 2401, 2438, 3083, 2398, 1558, 2457, 2940, 1708,
+ 3084, 1557, 1385, 1709, 1508, 1754, 1710, 1755, 1778, 3120,
+ 1779, 3118, 1801, 1803, 1825, 4035, 4059, 4068, 1826, 2646,
+ 2643, 4086, 1287, 2624, 4127, 1288, 2600, 4168, 1315, 2599,
+
+ 4209, 1345, 2597, 2596, 2595, 4249, 4273, 1427, 2594, 2635,
+ 2682, 4314, 2572, 4338, 1429, 2571, 2578, 2938, 2942, 2577,
+ 2576, 3096, 3142, 4379, 2566, 4403, 1489, 2540, 2544, 1600,
+ 3156, 2542, 3151, 3164, 2541, 2540, 3183, 3184, 4444, 2531,
+ 4468, 1603, 2468, 2469, 0, 1605, 3255, 2438, 3203, 3205,
+ 2372, 2371, 3249, 3268, 4509, 2343, 4533, 1606, 2341, 2348,
+ 0, 3320, 0, 3327, 0, 1396, 2306, 3385, 4574, 4597,
+ 2299, 0, 3095, 3096, 3178, 1827, 3122, 2399, 1848, 3420,
+ 2959, 1849, 1850, 1872, 3248, 3380, 1874, 1896, 3490, 2014,
+ 3492, 1959, 2016, 3337, 4622, 4646, 4655, 2275, 4672, 4696,
+
+ 4719, 2263, 4743, 4766, 2239, 4790, 4813, 2234, 4837, 4860,
+ 2198, 2194, 4884, 1630, 2192, 2145, 3523, 4925, 2144, 2107,
+ 0, 3530, 0, 1615, 2106, 4016, 4949, 2103, 2060, 0,
+ 4023, 0, 4075, 0, 1639, 2059, 4109, 4973, 2058, 2055,
+ 0, 0, 4116, 0, 4150, 0, 1669, 2000, 4157, 4997,
+ 1999, 1976, 0, 0, 4191, 0, 4198, 0, 1748, 1951,
+ 4232, 5021, 1945, 1913, 0, 0, 1660, 4239, 1917, 3335,
+ 3399, 1914, 1897, 3400, 3420, 5045, 1882, 5069, 1661, 1842,
+ 1846, 2102, 2177, 2200, 2289, 2103, 2612, 4283, 2226, 2473,
+ 4266, 2680, 4348, 4267, 4331, 3249, 3271, 4289, 4332, 3399,
+
+ 2610, 2611, 4396, 5111, 1815, 5128, 5152, 1662, 1814, 5193,
+ 1689, 1811, 5234, 1736, 1795, 5275, 1879, 1791, 5316, 1880,
+ 1747, 1744, 4365, 5357, 1741, 1698, 0, 1697, 3634, 3681,
+ 5381, 1670, 1664, 1671, 3728, 4289, 1616, 1580, 4374, 4418,
+ 5405, 1568, 1565, 1552, 1938, 4432, 1527, 4441, 4478, 1508,
+ 1506, 4479, 4483, 5429, 1494, 1454, 1442, 0, 1940, 4497,
+ 1438, 4506, 4543, 1437, 1400, 4544, 4548, 5453, 1390, 1389,
+ 1363, 0, 1941, 4562, 1362, 4571, 4591, 83, 110, 4666,
+ 4667, 5477, 195, 198, 225, 0, 4907, 0, 4914, 0,
+ 2006, 307, 5092, 5501, 0, 348, 0, 2474, 2635, 2657,
+
+ 2659, 2681, 3003, 5107, 5162, 4670, 2703, 4291, 4356, 2682,
+ 4376, 4923, 4443, 2728, 2729, 5108, 5163, 5525, 1943, 0,
+ 372, 5566, 0, 399, 5590, 0, 418, 5614, 0, 480,
+ 5638, 0, 520, 5662, 0, 544, 4671, 4713, 5686, 551,
+ 580, 582, 610, 604, 5180, 0, 2061, 624, 643, 5216,
+ 0, 5223, 0, 2062, 696, 697, 0, 5257, 0, 5264,
+ 0, 2109, 698, 720, 0, 5298, 0, 5305, 0, 2142,
+ 721, 749, 0, 5339, 0, 5346, 0, 2193, 750, 752,
+ 0, 1995, 5548, 762, 4760, 4807, 763, 798, 4854, 5086,
+ 5710, 793, 0, 804, 4508, 2751, 2752, 2774, 2775, 5146,
+
+ 2776, 2799, 2822, 2823, 5720, 2845, 5703, 5722, 2846, 3270,
+ 3489, 5755, 820, 864, 0, 0, 0, 0, 0, 0,
+ 5555, 0, 2282, 880, 887, 0, 5127, 5354, 897, 930,
+ 0, 1997, 5739, 931, 5563, 5724, 934, 976, 0, 0,
+ 2024, 5778, 985, 5752, 5772, 1012, 1039, 0, 0, 2151,
+ 5792, 1063, 5787, 5788, 1102, 1103, 0, 0, 2181, 5802,
+ 1107, 5800, 5810, 1132, 1160, 0, 0, 5814, 0, 5828,
+ 0, 2347, 1176, 0, 5085, 3553, 2868, 2870, 3103, 5824,
+ 5827, 5837, 5838, 5839, 5826, 3379, 5843, 2892, 4573, 5736,
+ 2981, 0, 7856, 0, 0, 0, 0, 0, 0, 5845,
+
+ 5847, 1190, 1235, 0, 7856, 5871, 0, 7856, 0, 5887,
+ 0, 7856, 0, 5894, 0, 7856, 0, 5901, 0, 7856,
+ 0, 5908, 0, 7856, 0, 2270, 5915, 1236, 5923, 5924,
+ 1237, 2414, 0, 2980, 5086, 2982, 3004, 5926, 5356, 5565,
+ 3201, 5849, 4287, 3005, 5927, 5106, 5850, 3006, 5928, 0,
+ 5927, 0, 2272, 5954, 1240, 0, 2273, 5964, 1264, 0,
+ 2338, 5971, 1306, 0, 2396, 5978, 1322, 0, 2531, 5985,
+ 1356, 0, 5992, 0, 7856, 3177, 6001, 3442, 3444, 3467,
+ 6002, 6004, 6005, 6008, 3491, 6006, 3378, 6007, 2532, 6007,
+ 1357, 0, 0, 0, 0, 0, 0, 2533, 6043, 1361,
+
+ 6016, 6037, 5852, 6039, 3554, 6040, 3555, 3556, 6017, 6052,
+ 6056, 3419, 0, 0, 0, 0, 0, 0, 0, 3466,
+ 6059, 3611, 3658, 3705, 6060, 6062, 6063, 3468, 6065, 6066,
+ 0, 0, 3609, 3610, 3634, 3656, 6067, 3680, 6068, 3681,
+ 6073, 6082, 6092, 6095, 3727, 6101, 3728, 6103, 3749, 5102,
+ 3773, 3774, 3797, 6106, 6111, 6115, 3775, 6116, 6122, 3820,
+ 6123, 6126, 6128, 3822, 6114, 6142, 6148, 3844, 3845, 6152,
+ 6153, 6154, 6155, 3869, 3890, 6158, 3891, 6162, 3914, 6163,
+ 6167, 3915, 3916, 3938, 6169, 6177, 4737, 6191, 3939, 6182,
+ 6194, 6197, 6198, 3961, 6204, 6203, 6205, 3963, 6206, 3985,
+
+ 4084, 6213, 3987, 6218, 6227, 4125, 4613, 6219, 4308, 4032,
+ 6228, 4033, 4615, 4085, 6238, 6229, 6240, 4784, 4166, 6239,
+ 4207, 6241, 6268, 4208, 4665, 4666, 4669, 7856, 6296, 6304,
+ 6308, 6311, 6314, 6317, 6320, 6323, 6326, 6329, 6332, 6335,
+ 6338, 6341, 6344, 6347, 6350, 6353, 6356, 6360, 6364, 6367,
+ 6370, 6373, 6376, 6379, 6382, 6385, 6388, 6392, 6396, 6399,
+ 6402, 6406, 6408, 6411, 6414, 6417, 6420, 6423, 6426, 6429,
+ 6432, 6436, 6438, 6441, 6445, 6450, 6454, 6457, 6461, 6464,
+ 6467, 6470, 6473, 6476, 6479, 6482, 6486, 6490, 6493, 6497,
+ 6501, 6506, 6510, 6512, 6516, 6519, 6523, 6526, 6529, 6533,
+
+ 6535, 6538, 6541, 6544, 6547, 6550, 6553, 6556, 6559, 6562,
+ 6566, 6568, 6571, 6574, 6577, 6581, 6583, 6586, 6589, 6594,
+ 6598, 6603, 6607, 6609, 6613, 6616, 6620, 6625, 6629, 6632,
+ 6635, 6638, 6641, 6644, 6647, 6650, 6654, 6658, 6661, 6665,
+ 6669, 6674, 6678, 6680, 6684, 6687, 6691, 6694, 6699, 6703,
+ 6708, 6712, 6714, 6718, 6721, 6725, 6728, 6731, 6734, 6738,
+ 6740, 6743, 6748, 6752, 6755, 6758, 6761, 6764, 6767, 6770,
+ 6773, 6776, 6780, 6782, 6785, 6788, 6791, 6795, 6797, 6800,
+ 6803, 6806, 6809, 6813, 6815, 6818, 6821, 6824, 6829, 6833,
+ 6838, 6842, 6844, 6848, 6851, 6855, 6860, 6864, 6867, 6870,
+
+ 6873, 6876, 6879, 6882, 6885, 6889, 6893, 6896, 6900, 6904,
+ 6909, 6913, 6915, 6919, 6922, 6926, 6929, 6934, 6938, 6943,
+ 6947, 6949, 6953, 6956, 6960, 6963, 6966, 6971, 6975, 6980,
+ 6984, 6986, 6990, 6993, 6997, 7000, 7003, 7006, 7010, 7012,
+ 7015, 7020, 7024, 7027, 7030, 7033, 7036, 7039, 7042, 7045,
+ 7048, 7051, 7054, 7057, 7061, 7063, 7066, 7069, 7072, 7075,
+ 7079, 7081, 7084, 7087, 7090, 7093, 7096, 7100, 7102, 7105,
+ 7108, 7111, 7114, 7117, 7121, 7123, 7126, 7129, 7132, 7135,
+ 7140, 7144, 7149, 7153, 7155, 7159, 7162, 7166, 7171, 7175,
+ 7178, 7181, 7184, 7187, 7190, 7193, 7196, 7199, 7202, 7206,
+
+ 7210, 7213, 7217, 7221, 7226, 7230, 7232, 7236, 7239, 7243,
+ 7246, 7251, 7255, 7260, 7264, 7266, 7270, 7273, 7277, 7280,
+ 7283, 7288, 7292, 7297, 7301, 7303, 7307, 7310, 7314, 7317,
+ 7320, 7325, 7329, 7334, 7338, 7340, 7344, 7347, 7351, 7354,
+ 7357, 7360, 7364, 7366, 7369, 7372, 7377, 7381, 7384, 7387,
+ 7390, 7393, 7396, 7399, 7402, 7405, 7408, 7411, 7414, 7418,
+ 7422, 7425, 7428, 7432, 7435, 7438, 7442, 7444, 7447, 7450,
+ 7454, 7456, 7459, 7462, 7465, 7469, 7471, 7474, 7477, 7480,
+ 7484, 7486, 7489, 7492, 7495, 7499, 7501, 7504, 7507, 7512,
+ 7516, 7521, 7525, 7527, 7531, 7534, 7538, 7543, 7547, 7550,
+
+ 7553, 7556, 7559, 7562, 7565, 7568, 7571, 7575, 7577, 7580,
+ 7584, 7589, 7593, 7594, 7597, 7602, 7606, 7611, 7615, 7616,
+ 7619, 7622, 7627, 7631, 7636, 7640, 7641, 7644, 7647, 7652,
+ 7656, 7661, 7665, 7666, 7669, 7672, 7677, 7681, 7686, 7690,
+ 7691, 7694, 7697, 7700, 7704, 7706, 7711, 7715, 7718, 7721,
+ 7724, 7727, 7730, 7733, 7737, 7742, 7746, 7747, 7750, 7753,
+ 7756, 7759, 7762, 7765, 7768, 7771, 7774, 7777, 7782, 7786,
+ 7789, 7792, 7795, 7799, 7803, 7807, 7811, 7815, 7818, 7821,
+ 7825, 7828, 7831, 7834, 7837, 7840, 7844, 7847
} ;
-static yyconst flex_int16_t yy_def[1924] =
+static yyconst flex_int16_t yy_def[2189] =
{ 0,
- 1463, 1, 1463, 1463, 1463, 1463, 1463, 1463, 1464, 1463,
- 1463, 1463, 1463, 1463, 14, 1463, 1463, 1463, 1463, 14,
- 20, 1465, 20, 20, 20, 20, 20, 20, 21, 21,
+ 1728, 1, 1728, 1728, 1728, 1728, 1728, 1728, 1729, 1728,
+ 1728, 1728, 1728, 1728, 14, 1728, 1728, 1728, 1728, 14,
+ 20, 1730, 20, 20, 20, 20, 20, 20, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 1463, 1463, 1463, 1466, 1463, 21, 21, 20,
- 1467, 50, 21, 21, 21, 1463, 1463, 1463, 1463, 1463,
- 1463, 49, 1465, 1465, 52, 52, 52, 21, 21, 21,
+ 21, 21, 1728, 1728, 1728, 1731, 1728, 21, 21, 20,
+ 1732, 50, 21, 21, 21, 1728, 1728, 1728, 1728, 1728,
+ 1728, 49, 1730, 1730, 52, 52, 52, 21, 21, 21,
21, 52, 21, 21, 52, 21, 21, 21, 52, 21,
21, 21, 21, 21, 52, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
@@ -816,8 +880,8 @@ static yyconst flex_int16_t yy_def[1924] =
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 1463, 1463, 21, 21, 154, 21, 21, 157, 1468, 1463,
- 54, 1463, 162, 1469, 21, 21, 158, 21, 21, 21,
+ 1728, 1728, 21, 21, 154, 21, 21, 157, 1733, 1728,
+ 54, 1728, 162, 1734, 21, 21, 158, 21, 21, 21,
158, 21, 21, 21, 21, 21, 21, 158, 21, 21,
21, 21, 21, 21, 21, 158, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
@@ -828,9 +892,9 @@ static yyconst flex_int16_t yy_def[1924] =
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 262, 263, 158, 1470, 268,
- 1471, 1472, 1463, 273, 1473, 1474, 1463, 1463, 1463, 1475,
- 1476, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 262, 263, 158, 1735, 268,
+ 1736, 1737, 1728, 273, 1738, 1739, 1728, 1728, 1728, 1740,
+ 1741, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
@@ -838,183 +902,211 @@ static yyconst flex_int16_t yy_def[1924] =
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 350, 21, 263, 265, 263, 265, 265, 357, 1477, 1463,
- 356, 1478, 1479, 1463, 1463, 1463, 1463, 1480, 1481, 1482,
- 1483, 1483, 1463, 1484, 1463, 375, 1485, 1476, 21, 21,
+ 350, 21, 263, 265, 263, 265, 265, 357, 1742, 1728,
+ 356, 1743, 1744, 1728, 1728, 1728, 1728, 1745, 1746, 1747,
+ 1748, 1748, 1728, 1749, 1728, 375, 1750, 1741, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 430, 431, 431, 436, 430, 357, 439,
- 1486, 1487, 1463, 443, 1488, 1463, 1489, 1490, 1463, 449,
- 1491, 1492, 1493, 1493, 1463, 1494, 1463, 457, 1495, 1481,
- 1463, 1463, 1496, 1497, 1463, 1463, 1463, 1463, 1498, 1499,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 432, 433, 433, 438, 432,
+ 357, 441, 1751, 1752, 1728, 445, 1753, 1728, 1754, 1755,
+ 1728, 451, 1756, 1757, 1758, 1758, 1728, 1759, 1728, 459,
+ 1760, 1746, 1728, 1728, 1761, 1762, 1728, 1728, 1728, 1728,
+ 1763, 1764, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 515, 21, 431, 433, 431,
- 431, 521, 439, 523, 1500, 1463, 1463, 1463, 1501, 1502,
- 1503, 1463, 1463, 1463, 1463, 1504, 1505, 1463, 1506, 1507,
- 1463, 1463, 1463, 1463, 1508, 1509, 1510, 1510, 1496, 1497,
- 1511, 1511, 1463, 1512, 1463, 555, 1513, 1514, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 522, 21, 433, 435, 433, 433, 528, 441,
+ 530, 1765, 1728, 1728, 1728, 1766, 1767, 1768, 1728, 1728,
+ 1728, 1728, 1769, 1770, 1728, 1771, 1772, 1728, 1728, 1728,
+ 1728, 1773, 1774, 1775, 1775, 1761, 1762, 1776, 1776, 1728,
+ 1777, 1728, 562, 1778, 1779, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 598, 598, 602, 523, 604, 1515, 1516, 1463, 608, 1517,
- 1463, 611, 1518, 1463, 1519, 1520, 1463, 617, 1521, 1522,
- 1522, 1463, 1523, 1463, 624, 1524, 1525, 1526, 1526, 1527,
- 1528, 1529, 1529, 1463, 1530, 1463, 636, 1531, 1532, 1463,
- 1533, 1463, 1534, 1535, 1463, 1463, 1463, 1463, 1536, 1537,
- 605, 651, 651, 651, 651, 651, 651, 651, 651, 651,
- 651, 651, 651, 651, 651, 651, 651, 651, 651, 651,
- 651, 651, 651, 651, 651, 651, 676, 676, 676, 651,
- 676, 681, 1538, 1463, 1463, 1463, 1539, 1463, 1463, 1540,
- 1541, 1542, 1463, 1463, 1463, 1463, 1543, 1544, 1463, 1545,
-
- 1546, 1463, 1463, 1463, 1463, 1547, 1548, 1463, 1549, 1463,
- 1550, 1551, 1463, 1463, 1463, 1463, 1552, 1553, 1554, 1463,
- 1555, 1556, 1556, 1557, 1558, 1559, 1559, 1463, 1560, 1463,
- 730, 1561, 1562, 1563, 1563, 1563, 1563, 1563, 1563, 1563,
- 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563, 1563,
- 1563, 1563, 1563, 752, 1563, 752, 756, 756, 758, 1564,
- 1565, 1463, 762, 1566, 1463, 765, 1567, 1463, 768, 1568,
- 1463, 1569, 1570, 1463, 774, 1571, 1572, 1572, 1463, 1573,
- 1463, 781, 1574, 1575, 1576, 1576, 1577, 1578, 1579, 1579,
- 1463, 1580, 1463, 793, 1581, 1582, 1583, 1463, 1584, 1585,
-
- 1585, 1586, 1587, 1588, 1588, 1463, 1589, 1463, 808, 1590,
- 1591, 1592, 1463, 1593, 1463, 1594, 1595, 1463, 1463, 1463,
- 1463, 1596, 1597, 1598, 1598, 1598, 1598, 1598, 1598, 1598,
- 1598, 1598, 1598, 1598, 1598, 1598, 1598, 837, 837, 839,
- 837, 837, 842, 1599, 1463, 1463, 1463, 1600, 1463, 1463,
- 1601, 1463, 1463, 1602, 1603, 1604, 1463, 1463, 1463, 1463,
- 1605, 1606, 1463, 1607, 1608, 1463, 1463, 1463, 1463, 1609,
- 1610, 1463, 1611, 1463, 1612, 1613, 1463, 1463, 1463, 1463,
- 1614, 1615, 1616, 1463, 1617, 1463, 1618, 1619, 1463, 1463,
- 1463, 1463, 1620, 1621, 1622, 1623, 1463, 1624, 1625, 1625,
-
- 1626, 1627, 1628, 1628, 1463, 1629, 1463, 907, 1630, 1631,
- 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632,
- 1632, 1632, 1632, 1632, 924, 1632, 1632, 1633, 1634, 1463,
- 930, 1635, 1463, 933, 1636, 1463, 936, 1637, 1463, 939,
- 1638, 1463, 1639, 1463, 1463, 945, 1640, 1641, 1641, 1463,
- 1642, 1463, 952, 1643, 1644, 1645, 1645, 1646, 1647, 1648,
- 1648, 1463, 1649, 1463, 964, 1650, 1651, 1652, 1463, 1653,
- 1654, 1654, 1655, 1656, 1657, 1657, 1463, 1658, 1463, 979,
- 1659, 1660, 1661, 1662, 1463, 1663, 1664, 1664, 1665, 1666,
- 1667, 1667, 1463, 1668, 1463, 995, 1669, 1670, 1671, 1463,
-
- 1672, 1463, 1673, 1674, 1463, 1463, 1463, 1463, 1675, 1676,
- 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,
- 1677, 1677, 1677, 1023, 1677, 1678, 1463, 1463, 1463, 1679,
- 1463, 1463, 1680, 1463, 1463, 1681, 1463, 1463, 1682, 1683,
- 1463, 1041, 1684, 1685, 1463, 1463, 1686, 1687, 1688, 1463,
- 1689, 1690, 1463, 1463, 1463, 1691, 1692, 1693, 1463, 1694,
- 1463, 1695, 1696, 1463, 1463, 1463, 1697, 1698, 1699, 1700,
- 1463, 1701, 1463, 1702, 1703, 1463, 1463, 1463, 1704, 1705,
- 1706, 1707, 1463, 1708, 1463, 1709, 1710, 1463, 1463, 1463,
- 1711, 1712, 1713, 1714, 1715, 1463, 1716, 1717, 1717, 1718,
-
- 1719, 1720, 1720, 1463, 1721, 1463, 1106, 1722, 1723, 1724,
- 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724,
- 1725, 1463, 1463, 1123, 1726, 1463, 1126, 1727, 1463, 1129,
- 1728, 1463, 1132, 1729, 1463, 1135, 1730, 1463, 1463, 1463,
- 1731, 1732, 1733, 1734, 1735, 1735, 1463, 1736, 1737, 1738,
- 1739, 1739, 1740, 1741, 1742, 1742, 1463, 1743, 1744, 1745,
- 1746, 1463, 1747, 1748, 1748, 1749, 1750, 1751, 1751, 1463,
- 1752, 1753, 1754, 1755, 1756, 1463, 1757, 1758, 1758, 1759,
- 1760, 1761, 1761, 1463, 1762, 1763, 1764, 1765, 1766, 1463,
- 1767, 1768, 1768, 1769, 1770, 1771, 1771, 1463, 1772, 1773,
-
- 1774, 1775, 1463, 1776, 1463, 1777, 1778, 1463, 1463, 1463,
- 1779, 1780, 1781, 1782, 1782, 1782, 1782, 1782, 1782, 1782,
- 1782, 1463, 1222, 1783, 1784, 1463, 1785, 1786, 1463, 1787,
- 1788, 1463, 1789, 1790, 1463, 1791, 1792, 1463, 1793, 1794,
- 1795, 1795, 1463, 1796, 1797, 1798, 1799, 1800, 1463, 1801,
- 1802, 1463, 1803, 1463, 1804, 1463, 1805, 1806, 1463, 1807,
- 1808, 1463, 1809, 1463, 1810, 1811, 1463, 1812, 1813, 1463,
- 1814, 1463, 1815, 1816, 1463, 1817, 1818, 1463, 1819, 1463,
- 1820, 1821, 1463, 1822, 1823, 1824, 1463, 1825, 1826, 1826,
- 1827, 1828, 1829, 1829, 1463, 1830, 1831, 1832, 1833, 1833,
-
- 1833, 1833, 1463, 1834, 1835, 1836, 1837, 1838, 1839, 1840,
- 1841, 1463, 1842, 1843, 1463, 1844, 1845, 1846, 1846, 1847,
- 1848, 1849, 1850, 1463, 1851, 1852, 1852, 1853, 1854, 1855,
- 1856, 1857, 1463, 1858, 1859, 1859, 1860, 1861, 1862, 1863,
- 1864, 1463, 1865, 1866, 1866, 1867, 1868, 1869, 1870, 1871,
- 1463, 1872, 1873, 1873, 1874, 1875, 1876, 1877, 1463, 1878,
- 1463, 1879, 1880, 1463, 1881, 1882, 1882, 1882, 1882, 1883,
- 1463, 1884, 1885, 1886, 1887, 1888, 1889, 1890, 1890, 1891,
- 1892, 1893, 1463, 1463, 1894, 1463, 1895, 1463, 1896, 1463,
- 1897, 1463, 1898, 1463, 1899, 1463, 1900, 1463, 1901, 1463,
-
- 1902, 1463, 1877, 1903, 1463, 1878, 1904, 1904, 1879, 1880,
- 1905, 1882, 1882, 1882, 1906, 1463, 1907, 1908, 1463, 1894,
- 1895, 1909, 1463, 1896, 1897, 1910, 1463, 1898, 1899, 1911,
- 1463, 1900, 1901, 1912, 1463, 1902, 1913, 1463, 1914, 1463,
- 1882, 1915, 1463, 1907, 1916, 1917, 1918, 1919, 1920, 1913,
- 1921, 1463, 1914, 1922, 1916, 1917, 1918, 1919, 1920, 1923,
- 1922, 1923, 0, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
-
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
-
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
-
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
-
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
-
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 616, 616,
+ 620, 530, 622, 1780, 1781, 1728, 626, 1782, 1728, 629,
+ 1783, 1728, 1784, 1785, 1728, 635, 1786, 1787, 1787, 1728,
+ 1788, 1728, 642, 1789, 1790, 1791, 1791, 1792, 1793, 1794,
+ 1794, 1728, 1795, 1728, 654, 1796, 1797, 1728, 1798, 1728,
+ 1799, 1800, 1728, 1728, 1728, 1728, 1801, 1802, 623, 669,
+ 669, 669, 669, 669, 669, 669, 669, 669, 669, 669,
+ 669, 669, 669, 669, 669, 669, 669, 669, 669, 669,
+ 669, 669, 669, 669, 669, 669, 669, 669, 669, 669,
+
+ 669, 669, 669, 669, 669, 669, 706, 706, 706, 669,
+ 706, 711, 1803, 1728, 1728, 1728, 1804, 1728, 1728, 1805,
+ 1806, 1807, 1728, 1728, 1728, 1728, 1808, 1809, 1728, 1810,
+ 1811, 1728, 1728, 1728, 1728, 1812, 1813, 1728, 1814, 1728,
+ 1815, 1816, 1728, 1728, 1728, 1728, 1817, 1818, 1819, 1728,
+ 1820, 1821, 1821, 1822, 1823, 1824, 1824, 1728, 1825, 1728,
+ 760, 1826, 1827, 1828, 1828, 1828, 1828, 1828, 1828, 1828,
+ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828,
+ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828,
+ 1828, 1828, 1828, 1828, 1828, 794, 1828, 794, 798, 798,
+
+ 800, 1829, 1830, 1728, 804, 1831, 1728, 807, 1832, 1728,
+ 810, 1833, 1728, 1834, 1835, 1728, 816, 1836, 1837, 1837,
+ 1728, 1838, 1728, 823, 1839, 1840, 1841, 1841, 1842, 1843,
+ 1844, 1844, 1728, 1845, 1728, 835, 1846, 1847, 1848, 1728,
+ 1849, 1850, 1850, 1851, 1852, 1853, 1853, 1728, 1854, 1728,
+ 850, 1855, 1856, 1857, 1728, 1858, 1728, 1859, 1860, 1728,
+ 1728, 1728, 1728, 1861, 1862, 1863, 1863, 1863, 1863, 1863,
+ 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
+ 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 889,
+ 889, 891, 889, 889, 894, 1864, 1728, 1728, 1728, 1865,
+
+ 1728, 1728, 1866, 1728, 1728, 1867, 1868, 1869, 1728, 1728,
+ 1728, 1728, 1870, 1871, 1728, 1872, 1873, 1728, 1728, 1728,
+ 1728, 1874, 1875, 1728, 1876, 1728, 1877, 1878, 1728, 1728,
+ 1728, 1728, 1879, 1880, 1881, 1728, 1882, 1728, 1883, 1884,
+ 1728, 1728, 1728, 1728, 1885, 1886, 1887, 1888, 1728, 1889,
+ 1890, 1890, 1891, 1892, 1893, 1893, 1728, 1894, 1728, 959,
+ 1895, 1896, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897,
+ 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897,
+ 1897, 1897, 1897, 1897, 1897, 1897, 986, 1897, 1897, 1898,
+ 1899, 1728, 992, 1900, 1728, 995, 1901, 1728, 998, 1902,
+
+ 1728, 1001, 1903, 1728, 1904, 1728, 1728, 1007, 1905, 1906,
+ 1906, 1728, 1907, 1728, 1014, 1908, 1909, 1910, 1910, 1911,
+ 1912, 1913, 1913, 1728, 1914, 1728, 1026, 1915, 1916, 1917,
+ 1728, 1918, 1919, 1919, 1920, 1921, 1922, 1922, 1728, 1923,
+ 1728, 1041, 1924, 1925, 1926, 1927, 1728, 1928, 1929, 1929,
+ 1930, 1931, 1932, 1932, 1728, 1933, 1728, 1057, 1934, 1935,
+ 1936, 1728, 1937, 1728, 1938, 1939, 1728, 1728, 1728, 1728,
+ 1940, 1941, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1095, 1942, 1943, 1728, 1728,
+
+ 1728, 1944, 1728, 1728, 1945, 1728, 1728, 1946, 1728, 1728,
+ 1947, 1948, 1728, 1113, 1949, 1950, 1728, 1728, 1951, 1952,
+ 1953, 1728, 1954, 1955, 1728, 1728, 1728, 1956, 1957, 1958,
+ 1728, 1959, 1728, 1960, 1961, 1728, 1728, 1728, 1962, 1963,
+ 1964, 1965, 1728, 1966, 1728, 1967, 1968, 1728, 1728, 1728,
+ 1969, 1970, 1971, 1972, 1728, 1973, 1728, 1974, 1975, 1728,
+ 1728, 1728, 1976, 1977, 1978, 1979, 1980, 1728, 1981, 1982,
+ 1982, 1983, 1984, 1985, 1985, 1728, 1986, 1728, 1178, 1987,
+ 1988, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989,
+ 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989,
+
+ 1989, 1989, 1989, 1989, 1990, 1728, 1728, 1207, 1991, 1728,
+ 1210, 1992, 1728, 1213, 1993, 1728, 1216, 1994, 1728, 1219,
+ 1995, 1728, 1728, 1728, 1996, 1997, 1998, 1999, 2000, 2000,
+ 1728, 2001, 2002, 2003, 2004, 2004, 2005, 2006, 2007, 2007,
+ 1728, 2008, 2009, 2010, 2011, 1728, 2012, 2013, 2013, 2014,
+ 2015, 2016, 2016, 1728, 2017, 2018, 2019, 2020, 2021, 1728,
+ 2022, 2023, 2023, 2024, 2025, 2026, 2026, 1728, 2027, 2028,
+ 2029, 2030, 2031, 1728, 2032, 2033, 2033, 2034, 2035, 2036,
+ 2036, 1728, 2037, 2038, 2039, 2040, 1728, 2041, 1728, 2042,
+ 2043, 1728, 1728, 1728, 2044, 2045, 2046, 2047, 2047, 2047,
+
+ 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
+ 2047, 2047, 2047, 2047, 2047, 2047, 2047, 1728, 1318, 2048,
+ 2049, 1728, 2050, 2051, 1728, 2052, 2053, 1728, 2054, 2055,
+ 1728, 2056, 2057, 1728, 2058, 2059, 2060, 2060, 1728, 2061,
+ 2062, 2063, 2064, 2065, 1728, 2066, 2067, 1728, 2068, 1728,
+ 2069, 1728, 2070, 2071, 1728, 2072, 2073, 1728, 2074, 1728,
+ 2075, 2076, 1728, 2077, 2078, 1728, 2079, 1728, 2080, 2081,
+ 1728, 2082, 2083, 1728, 2084, 1728, 2085, 2086, 1728, 2087,
+ 2088, 2089, 1728, 2090, 2091, 2091, 2092, 2093, 2094, 2094,
+ 1728, 2095, 2096, 2097, 2098, 2098, 2098, 2098, 2098, 2098,
+
+ 2098, 2098, 2098, 2098, 2098, 2098, 2098, 2098, 2098, 2098,
+ 2098, 1728, 2099, 2100, 2101, 2102, 2103, 2104, 2105, 2106,
+ 1728, 2107, 2108, 1728, 2109, 2110, 2111, 2111, 2112, 2113,
+ 2114, 2115, 1728, 2116, 2117, 2117, 2118, 2119, 2120, 2121,
+ 2122, 1728, 2123, 2124, 2124, 2125, 2126, 2127, 2128, 2129,
+ 1728, 2130, 2131, 2131, 2132, 2133, 2134, 2135, 2136, 1728,
+ 2137, 2138, 2138, 2139, 2140, 2141, 2142, 1728, 2143, 1728,
+ 2144, 2145, 1728, 2146, 2147, 2147, 2147, 2147, 2147, 2147,
+ 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
+ 2147, 2148, 1728, 2149, 2150, 2151, 2152, 2153, 2154, 2155,
+
+ 2155, 2156, 2157, 2158, 1728, 1728, 2159, 1728, 2160, 1728,
+ 2161, 1728, 2162, 1728, 2163, 1728, 2164, 1728, 2165, 1728,
+ 2166, 1728, 2167, 1728, 2142, 2168, 1728, 2143, 2169, 2169,
+ 2144, 2145, 2170, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
+ 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2171,
+ 1728, 2172, 2173, 1728, 2159, 2160, 2174, 1728, 2161, 2162,
+ 2175, 1728, 2163, 2164, 2176, 1728, 2165, 2166, 2177, 1728,
+ 2167, 2178, 1728, 2179, 1728, 2147, 2147, 2147, 2147, 2147,
+ 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2180, 1728,
+ 2172, 2181, 2182, 2183, 2184, 2185, 2178, 2186, 1728, 2179,
+
+ 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
+ 2147, 2147, 2187, 2181, 2182, 2183, 2184, 2185, 2188, 2147,
+ 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
+ 2187, 2188, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
+ 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
+ 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
+ 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
+ 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
+ 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
+ 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
+
+ 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
+ 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
+ 2147, 2147, 2147, 2147, 2147, 2147, 2147, 0, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728
} ;
-static yyconst flex_int16_t yy_nxt[7474] =
+static yyconst flex_uint16_t yy_nxt[7910] =
{ 0,
4, 5, 6, 7, 8, 9, 10, 11, 12, 12,
13, 14, 15, 15, 15, 15, 15, 15, 16, 17,
@@ -1025,822 +1117,870 @@ static yyconst flex_int16_t yy_nxt[7474] =
44, 212, 44, 44, 44, 57, 58, 44, 248, 44,
44, 44, 60, 61, 72, 44, 83, 84, 249, 44,
53, 44, 44, 44, 44, 206, 44, 44, 73, 85,
- 44, 117, 79, 1239, 86, 74, 80, 736, 195, 44,
+ 44, 117, 79, 1157, 86, 74, 80, 686, 195, 44,
- 118, 196, 81, 53, 197, 82, 198, 44, 48, 49,
+ 118, 196, 81, 687, 197, 82, 198, 44, 48, 49,
50, 50, 50, 50, 50, 50, 50, 51, 207, 201,
- 1304, 52, 53, 54, 202, 182, 55, 52, 52, 52,
+ 942, 52, 53, 54, 202, 182, 55, 52, 52, 52,
52, 52, 52, 53, 53, 53, 53, 53, 53, 53,
53, 53, 53, 53, 53, 53, 53, 53, 53, 54,
- 53, 44, 183, 75, 44, 451, 44, 44, 184, 236,
- 87, 451, 213, 76, 88, 344, 77, 214, 63, 56,
+ 53, 44, 183, 75, 44, 766, 44, 44, 184, 236,
+ 87, 53, 213, 76, 88, 344, 77, 214, 63, 56,
78, 63, 237, 63, 63, 208, 89, 44, 62, 52,
52, 52, 52, 52, 52, 52, 63, 242, 65, 345,
- 66, 67, 53, 738, 63, 68, 53, 342, 119, 343,
+ 66, 67, 53, 768, 63, 68, 53, 342, 119, 343,
69, 90, 209, 91, 70, 243, 71, 210, 92, 93,
- 120, 94, 121, 1139, 122, 95, 451, 123, 53, 55,
- 53, 53, 53, 53, 53, 53, 53, 53, 1463, 104,
- 105, 217, 53, 740, 218, 1227, 219, 245, 53, 53,
+ 120, 94, 121, 1335, 122, 95, 453, 123, 53, 55,
+ 53, 53, 53, 53, 53, 53, 53, 53, 1728, 104,
+ 105, 217, 53, 770, 218, 1161, 219, 245, 53, 53,
53, 53, 53, 53, 96, 106, 246, 97, 98, 107,
99, 53, 100, 108, 101, 109, 102, 111, 124, 103,
- 53, 112, 110, 125, 126, 129, 127, 128, 451, 130,
- 113, 114, 1463, 134, 115, 324, 116, 131, 141, 135,
+ 53, 112, 110, 125, 126, 129, 127, 128, 799, 130,
+ 113, 114, 1728, 134, 115, 324, 116, 131, 141, 135,
142, 136, 132, 137, 133, 146, 53, 138, 325, 139,
- 140, 53, 355, 147, 143, 53, 520, 148, 1463, 149,
-
- 44, 144, 743, 44, 53, 44, 44, 156, 156, 156,
- 156, 156, 156, 156, 1463, 417, 63, 53, 44, 63,
- 418, 63, 63, 495, 1230, 499, 44, 153, 153, 153,
- 153, 153, 153, 153, 63, 451, 496, 53, 153, 500,
- 1463, 744, 63, 53, 153, 153, 153, 153, 153, 153,
- 154, 155, 155, 155, 155, 155, 155, 1463, 53, 1233,
- 1463, 156, 380, 381, 382, 383, 451, 156, 156, 156,
+ 140, 53, 355, 147, 143, 53, 527, 148, 1728, 149,
+
+ 44, 144, 490, 44, 53, 44, 44, 156, 156, 156,
+ 156, 156, 156, 156, 1728, 417, 63, 53, 44, 63,
+ 418, 63, 63, 491, 500, 1070, 44, 153, 153, 153,
+ 153, 153, 153, 153, 63, 53, 708, 501, 153, 492,
+ 1728, 775, 63, 53, 153, 153, 153, 153, 153, 153,
+ 154, 155, 155, 155, 155, 155, 155, 1728, 53, 53,
+ 1728, 156, 380, 381, 382, 383, 1295, 156, 156, 156,
156, 156, 156, 49, 157, 157, 157, 157, 157, 157,
- 157, 277, 384, 1463, 53, 158, 1463, 1463, 1463, 279,
- 1236, 158, 158, 158, 158, 158, 158, 62, 158, 158,
+ 157, 277, 384, 1728, 53, 158, 1728, 1728, 1728, 279,
+ 1413, 158, 158, 158, 158, 158, 158, 62, 158, 158,
158, 158, 158, 158, 158, 161, 161, 161, 161, 161,
- 161, 161, 569, 1463, 1463, 435, 161, 380, 381, 382,
- 383, 570, 161, 161, 161, 161, 161, 161, 44, 265,
- 451, 44, 1239, 44, 44, 53, 678, 462, 462, 162,
- 163, 163, 163, 163, 163, 163, 44, 53, 1463, 451,
- 164, 463, 1463, 1203, 44, 265, 164, 164, 164, 164,
- 164, 164, 260, 572, 261, 261, 261, 261, 261, 261,
- 261, 365, 573, 53, 1463, 261, 1463, 463, 1463, 528,
- 1205, 261, 261, 261, 261, 261, 261, 262, 263, 263,
- 263, 263, 263, 263, 263, 277, 466, 735, 53, 264,
-
- 1463, 265, 1463, 1463, 468, 264, 264, 264, 264, 264,
+ 161, 161, 576, 1728, 1728, 437, 161, 1323, 504, 765,
+ 53, 577, 161, 161, 161, 161, 161, 161, 44, 265,
+ 767, 44, 505, 44, 44, 53, 1326, 464, 464, 162,
+ 163, 163, 163, 163, 163, 163, 44, 53, 1728, 53,
+ 164, 465, 1728, 774, 44, 265, 164, 164, 164, 164,
+ 164, 164, 260, 579, 261, 261, 261, 261, 261, 261,
+ 261, 365, 580, 53, 1728, 261, 1728, 465, 1728, 535,
+ 781, 261, 261, 261, 261, 261, 261, 262, 263, 263,
+ 263, 263, 263, 263, 263, 277, 468, 53, 1329, 264,
+
+ 1728, 265, 1728, 1728, 470, 264, 264, 264, 264, 264,
264, 352, 352, 352, 352, 352, 352, 352, 371, 372,
- 372, 372, 372, 372, 372, 538, 1463, 265, 266, 264,
- 264, 264, 264, 264, 264, 264, 1463, 1463, 737, 539,
- 264, 1463, 600, 53, 53, 751, 264, 264, 264, 264,
+ 372, 372, 372, 372, 372, 545, 1728, 265, 266, 264,
+ 264, 264, 264, 264, 264, 264, 688, 1728, 1332, 546,
+ 264, 380, 381, 382, 383, 689, 264, 264, 264, 264,
264, 264, 267, 268, 268, 268, 268, 268, 268, 268,
- 269, 757, 1463, 1463, 270, 539, 1006, 1463, 600, 1211,
+ 269, 779, 1335, 1728, 270, 546, 1728, 1728, 53, 1413,
270, 270, 270, 270, 270, 270, 53, 270, 270, 270,
270, 270, 270, 270, 273, 274, 274, 274, 274, 274,
- 274, 275, 533, 1209, 812, 276, 1463, 53, 745, 55,
-
- 686, 276, 276, 276, 276, 276, 276, 277, 278, 278,
- 278, 278, 278, 278, 278, 279, 53, 55, 1371, 280,
- 812, 281, 1463, 396, 55, 280, 280, 280, 280, 280,
- 280, 397, 438, 438, 438, 438, 438, 438, 438, 1304,
- 55, 538, 55, 601, 398, 55, 741, 281, 349, 349,
- 349, 349, 349, 349, 349, 1463, 53, 433, 55, 349,
- 399, 55, 1304, 55, 451, 349, 349, 349, 349, 349,
- 349, 350, 351, 351, 351, 351, 351, 351, 739, 55,
- 825, 1463, 352, 433, 1463, 1463, 824, 53, 352, 352,
+ 274, 275, 1728, 1728, 773, 276, 53, 777, 453, 53,
+
+ 453, 276, 276, 276, 276, 276, 276, 277, 278, 278,
+ 278, 278, 278, 278, 278, 279, 782, 53, 786, 280,
+ 1223, 281, 453, 396, 53, 280, 280, 280, 280, 280,
+ 280, 397, 440, 440, 440, 440, 440, 440, 440, 53,
+ 793, 545, 1323, 619, 398, 55, 771, 281, 349, 349,
+ 349, 349, 349, 349, 349, 1728, 53, 435, 618, 349,
+ 399, 453, 55, 55, 784, 349, 349, 349, 349, 349,
+ 349, 350, 351, 351, 351, 351, 351, 351, 690, 53,
+ 55, 1728, 352, 435, 618, 854, 1728, 691, 352, 352,
352, 352, 352, 352, 262, 353, 353, 353, 353, 353,
- 353, 353, 354, 354, 354, 354, 354, 354, 354, 542,
- 1463, 1463, 1249, 354, 1463, 55, 55, 689, 55, 354,
+ 353, 353, 354, 354, 354, 354, 354, 354, 354, 769,
+ 1728, 854, 1728, 354, 1326, 453, 1329, 55, 53, 354,
354, 354, 354, 354, 354, 356, 357, 357, 357, 357,
- 357, 357, 357, 55, 55, 834, 55, 358, 830, 831,
- 1463, 1045, 1254, 358, 358, 358, 358, 358, 358, 361,
+ 357, 357, 357, 540, 549, 55, 1728, 358, 453, 1332,
+ 872, 716, 719, 358, 358, 358, 358, 358, 358, 361,
358, 358, 358, 358, 358, 358, 358, 365, 366, 366,
- 366, 366, 366, 366, 366, 367, 646, 421, 640, 368,
- 1256, 369, 422, 1054, 648, 368, 368, 368, 368, 368,
- 368, 423, 641, 424, 425, 1463, 426, 453, 454, 454,
- 454, 454, 454, 454, 55, 640, 55, 369, 277, 373,
-
- 373, 373, 373, 373, 373, 373, 279, 1262, 641, 1463,
- 374, 1463, 55, 1264, 55, 642, 374, 374, 374, 374,
- 374, 374, 375, 376, 376, 376, 376, 376, 376, 643,
- 1065, 826, 1270, 377, 1272, 1463, 55, 1077, 55, 377,
- 377, 377, 377, 377, 377, 428, 642, 429, 429, 429,
- 429, 429, 429, 429, 55, 643, 55, 832, 429, 835,
- 1463, 752, 55, 754, 429, 429, 429, 429, 429, 429,
- 430, 431, 431, 431, 431, 431, 431, 431, 1278, 55,
- 55, 1280, 432, 1089, 433, 1211, 1463, 1312, 432, 432,
- 432, 432, 432, 432, 517, 517, 517, 517, 517, 517,
-
- 517, 547, 548, 548, 548, 548, 548, 548, 699, 750,
- 433, 434, 432, 432, 432, 432, 432, 432, 432, 53,
- 1139, 1463, 700, 432, 1463, 883, 55, 55, 699, 432,
- 432, 432, 432, 432, 432, 436, 437, 437, 437, 437,
- 437, 437, 1463, 1463, 55, 55, 438, 1463, 700, 55,
- 1463, 883, 438, 438, 438, 438, 438, 438, 267, 439,
- 439, 439, 439, 439, 439, 439, 694, 55, 1463, 1463,
- 440, 53, 911, 999, 847, 1359, 440, 440, 440, 440,
- 440, 440, 53, 440, 440, 440, 440, 440, 440, 440,
- 443, 444, 444, 444, 444, 444, 444, 53, 703, 999,
-
- 1361, 445, 1384, 55, 55, 55, 850, 445, 445, 445,
- 445, 445, 445, 449, 450, 450, 450, 450, 450, 450,
- 451, 55, 55, 55, 452, 1388, 912, 913, 915, 55,
- 452, 452, 452, 452, 452, 452, 365, 455, 455, 455,
- 455, 455, 455, 455, 367, 714, 1392, 55, 456, 1463,
- 55, 55, 917, 853, 456, 456, 456, 456, 456, 456,
- 457, 458, 458, 458, 458, 458, 458, 451, 55, 55,
- 1463, 459, 920, 918, 55, 1463, 55, 459, 459, 459,
- 459, 459, 459, 277, 464, 464, 464, 464, 464, 464,
- 464, 279, 55, 1396, 55, 465, 1463, 1016, 55, 55,
-
- 1022, 465, 465, 465, 465, 465, 465, 466, 467, 467,
- 467, 467, 467, 467, 467, 468, 55, 55, 1400, 469,
- 1463, 470, 1020, 1463, 1463, 469, 469, 469, 469, 469,
- 469, 551, 552, 552, 552, 552, 552, 552, 620, 621,
- 621, 621, 621, 621, 621, 1416, 1463, 470, 480, 1463,
- 1463, 1438, 481, 1463, 55, 482, 55, 708, 483, 708,
- 484, 485, 486, 487, 514, 514, 514, 514, 514, 514,
- 514, 709, 55, 1463, 55, 514, 1463, 55, 55, 1463,
- 746, 514, 514, 514, 514, 514, 514, 515, 516, 516,
- 516, 516, 516, 516, 53, 55, 55, 709, 517, 1463,
-
- 1463, 1070, 1463, 1236, 517, 517, 517, 517, 517, 517,
- 430, 518, 518, 518, 518, 518, 518, 518, 519, 519,
- 519, 519, 519, 519, 519, 1463, 1463, 1070, 1082, 519,
- 1463, 1233, 55, 1230, 55, 519, 519, 519, 519, 519,
- 519, 435, 521, 521, 521, 521, 521, 521, 521, 819,
- 55, 1463, 55, 522, 1082, 265, 1463, 821, 1227, 522,
- 522, 522, 522, 522, 522, 628, 629, 629, 629, 629,
- 629, 629, 632, 633, 633, 633, 633, 633, 633, 55,
- 710, 265, 522, 522, 522, 522, 522, 522, 522, 1463,
- 1304, 1211, 1202, 522, 711, 55, 1008, 55, 747, 522,
-
- 522, 522, 522, 522, 522, 523, 523, 523, 523, 523,
- 523, 523, 53, 55, 827, 1463, 524, 1115, 1202, 1089,
- 711, 1463, 524, 524, 524, 524, 524, 524, 53, 524,
- 524, 524, 524, 524, 524, 524, 365, 527, 527, 527,
- 527, 527, 527, 527, 528, 858, 710, 1463, 529, 451,
- 369, 1239, 890, 1029, 529, 529, 529, 529, 529, 529,
- 1463, 719, 720, 720, 720, 720, 720, 720, 722, 723,
- 723, 723, 723, 723, 723, 55, 369, 533, 534, 534,
- 534, 534, 534, 534, 534, 535, 1463, 1085, 1083, 536,
- 1077, 537, 451, 55, 749, 536, 536, 536, 536, 536,
-
- 536, 726, 727, 727, 727, 727, 727, 727, 53, 777,
- 778, 778, 778, 778, 778, 778, 55, 537, 365, 540,
- 540, 540, 540, 540, 540, 540, 528, 1236, 878, 1463,
- 541, 1073, 1463, 1463, 55, 55, 541, 541, 541, 541,
- 541, 541, 542, 543, 543, 543, 543, 543, 543, 543,
- 544, 829, 1071, 55, 545, 1463, 546, 1118, 1463, 1463,
- 545, 545, 545, 545, 545, 545, 785, 786, 786, 786,
- 786, 786, 786, 789, 790, 790, 790, 790, 790, 790,
- 813, 55, 546, 466, 553, 553, 553, 553, 553, 553,
- 553, 468, 1065, 1463, 814, 554, 1463, 451, 1233, 55,
-
- 813, 554, 554, 554, 554, 554, 554, 555, 556, 556,
- 556, 556, 556, 556, 1463, 867, 916, 867, 557, 1463,
- 814, 55, 1463, 1032, 557, 557, 557, 557, 557, 557,
- 595, 815, 596, 596, 596, 596, 596, 596, 596, 55,
- 1463, 1061, 1059, 596, 1119, 816, 1054, 55, 55, 596,
- 596, 596, 596, 596, 596, 597, 598, 598, 598, 598,
- 598, 598, 598, 451, 878, 55, 55, 599, 1217, 600,
- 1220, 816, 1035, 599, 599, 599, 599, 599, 599, 797,
- 798, 798, 798, 798, 798, 798, 800, 801, 801, 801,
- 801, 801, 801, 815, 55, 600, 597, 599, 599, 599,
-
- 599, 599, 599, 599, 1261, 890, 1230, 1463, 599, 1269,
- 1277, 858, 55, 1038, 599, 599, 599, 599, 599, 599,
- 435, 602, 602, 602, 602, 602, 602, 602, 1050, 1006,
- 1261, 921, 603, 1463, 1463, 1269, 1277, 1008, 603, 603,
- 603, 603, 603, 603, 53, 603, 603, 603, 603, 603,
- 603, 603, 604, 604, 604, 604, 604, 604, 604, 1045,
- 1463, 1045, 451, 605, 1358, 1387, 1391, 1227, 1227, 605,
- 605, 605, 605, 605, 605, 53, 605, 605, 605, 605,
- 605, 605, 605, 608, 609, 609, 609, 609, 609, 609,
- 1358, 1387, 1391, 1395, 610, 1399, 1437, 55, 55, 55,
-
- 610, 610, 610, 610, 610, 610, 365, 455, 455, 455,
- 455, 455, 455, 455, 528, 55, 55, 55, 456, 1395,
- 55, 1399, 1437, 863, 456, 456, 456, 456, 456, 456,
- 611, 612, 612, 612, 612, 612, 612, 864, 55, 1214,
- 1215, 613, 451, 55, 1141, 1246, 1122, 613, 613, 613,
- 613, 613, 613, 617, 618, 618, 618, 618, 618, 618,
- 451, 55, 1216, 864, 619, 1239, 1236, 55, 55, 55,
- 619, 619, 619, 619, 619, 619, 533, 622, 622, 622,
- 622, 622, 622, 622, 535, 55, 55, 55, 623, 1233,
- 1230, 55, 55, 1227, 623, 623, 623, 623, 623, 623,
-
- 624, 625, 625, 625, 625, 625, 625, 451, 1218, 55,
- 55, 626, 1122, 1367, 1299, 55, 55, 626, 626, 626,
- 626, 626, 626, 542, 634, 634, 634, 634, 634, 634,
- 634, 544, 1054, 55, 55, 635, 1368, 1006, 55, 55,
- 1230, 635, 635, 635, 635, 635, 635, 636, 637, 637,
- 637, 637, 637, 637, 451, 1065, 55, 55, 638, 1445,
- 1211, 1008, 819, 1233, 638, 638, 638, 638, 638, 638,
- 466, 644, 644, 644, 644, 644, 644, 644, 468, 1077,
- 1369, 1446, 645, 1447, 1448, 1445, 55, 1236, 645, 645,
- 645, 645, 645, 645, 646, 647, 647, 647, 647, 647,
-
- 647, 647, 648, 1089, 55, 1002, 649, 1446, 650, 1447,
- 1448, 1239, 649, 649, 649, 649, 649, 649, 804, 805,
- 805, 805, 805, 805, 805, 720, 720, 720, 720, 720,
- 720, 720, 55, 863, 650, 674, 674, 674, 674, 674,
- 674, 674, 1449, 1139, 1454, 1460, 674, 1463, 1000, 55,
- 55, 1304, 674, 674, 674, 674, 674, 674, 675, 675,
- 675, 675, 675, 675, 675, 914, 1209, 55, 1449, 675,
- 1454, 1460, 1091, 1463, 1211, 675, 675, 675, 675, 675,
- 675, 597, 676, 676, 676, 676, 676, 676, 676, 677,
- 677, 677, 677, 677, 677, 677, 1209, 451, 1038, 1079,
-
- 677, 451, 55, 1035, 1463, 1067, 677, 677, 677, 677,
- 677, 677, 435, 679, 679, 679, 679, 679, 679, 679,
- 55, 451, 1032, 1056, 680, 451, 1029, 1047, 451, 1300,
- 680, 680, 680, 680, 680, 680, 53, 680, 680, 680,
- 680, 680, 680, 680, 681, 681, 681, 681, 681, 681,
- 681, 1141, 451, 1122, 1038, 682, 1035, 1032, 1029, 1122,
- 1008, 682, 682, 682, 682, 682, 682, 53, 682, 682,
- 682, 682, 682, 682, 682, 533, 685, 685, 685, 685,
- 685, 685, 685, 686, 55, 872, 872, 687, 821, 537,
- 890, 1091, 874, 687, 687, 687, 687, 687, 687, 873,
-
- 1463, 1038, 55, 714, 886, 884, 875, 878, 1079, 55,
- 1035, 55, 703, 55, 828, 537, 542, 688, 688, 688,
- 688, 688, 688, 688, 689, 873, 1463, 55, 690, 55,
- 546, 55, 875, 55, 690, 690, 690, 690, 690, 690,
- 836, 833, 874, 341, 841, 841, 841, 841, 841, 841,
- 841, 55, 874, 884, 884, 55, 546, 694, 695, 695,
- 695, 695, 695, 695, 695, 696, 1463, 885, 1463, 697,
- 1114, 698, 872, 55, 886, 697, 697, 697, 697, 697,
- 697, 798, 798, 798, 798, 798, 798, 798, 887, 55,
- 1015, 867, 1463, 885, 1463, 886, 1067, 698, 533, 701,
-
- 701, 701, 701, 701, 701, 701, 686, 55, 1032, 1463,
- 702, 694, 863, 858, 887, 1414, 702, 702, 702, 702,
- 702, 702, 703, 704, 704, 704, 704, 704, 704, 704,
- 705, 1056, 1029, 1047, 706, 1463, 707, 944, 929, 1038,
- 706, 706, 706, 706, 706, 706, 896, 897, 897, 897,
- 897, 897, 897, 899, 900, 900, 900, 900, 900, 900,
- 1000, 55, 707, 542, 712, 712, 712, 712, 712, 712,
- 712, 689, 1035, 1032, 1001, 713, 1029, 1027, 929, 55,
- 1017, 713, 713, 713, 713, 713, 713, 714, 715, 715,
- 715, 715, 715, 715, 715, 716, 819, 1018, 1008, 717,
-
- 1001, 718, 821, 55, 55, 717, 717, 717, 717, 717,
- 717, 903, 904, 904, 904, 904, 904, 904, 646, 815,
- 813, 55, 55, 892, 1000, 1002, 55, 718, 646, 728,
- 728, 728, 728, 728, 728, 728, 648, 919, 1463, 1003,
- 729, 1117, 853, 880, 55, 1002, 729, 729, 729, 729,
- 729, 729, 730, 731, 731, 731, 731, 731, 731, 1463,
- 1019, 850, 869, 732, 1463, 1003, 847, 860, 944, 732,
- 732, 732, 732, 732, 732, 53, 53, 53, 53, 53,
- 53, 53, 929, 853, 850, 1463, 53, 55, 55, 55,
- 55, 55, 53, 53, 53, 53, 53, 53, 948, 949,
-
- 949, 949, 949, 949, 949, 55, 55, 55, 55, 55,
- 734, 752, 847, 753, 753, 753, 753, 753, 753, 753,
- 1011, 1012, 1013, 1014, 753, 1021, 1366, 55, 55, 55,
- 753, 753, 753, 753, 753, 753, 956, 957, 957, 957,
- 957, 957, 957, 1050, 1050, 55, 55, 55, 53, 754,
- 755, 755, 755, 755, 755, 755, 755, 1051, 1463, 1113,
- 1116, 755, 1221, 929, 821, 648, 714, 755, 755, 755,
- 755, 755, 755, 960, 961, 961, 961, 961, 961, 961,
- 892, 853, 542, 1051, 1463, 53, 676, 676, 676, 676,
- 676, 676, 676, 968, 969, 969, 969, 969, 969, 969,
-
- 971, 972, 972, 972, 972, 972, 972, 975, 976, 976,
- 976, 976, 976, 976, 984, 985, 985, 985, 985, 985,
- 985, 53, 677, 677, 677, 677, 677, 677, 677, 710,
- 708, 703, 880, 677, 850, 533, 699, 694, 869, 677,
- 677, 677, 677, 677, 677, 756, 353, 353, 353, 353,
- 353, 353, 353, 267, 758, 758, 758, 758, 758, 758,
- 758, 847, 860, 857, 773, 759, 761, 853, 850, 847,
- 845, 759, 759, 759, 759, 759, 759, 53, 759, 759,
- 759, 759, 759, 759, 759, 762, 763, 763, 763, 763,
- 763, 763, 761, 646, 821, 648, 764, 466, 642, 640,
-
- 716, 689, 764, 764, 764, 764, 764, 764, 533, 622,
- 622, 622, 622, 622, 622, 622, 686, 705, 686, 696,
- 623, 773, 761, 689, 686, 1059, 623, 623, 623, 623,
- 623, 623, 765, 766, 766, 766, 766, 766, 766, 1060,
- 761, 53, 53, 767, 53, 748, 53, 53, 742, 767,
- 767, 767, 767, 767, 767, 542, 634, 634, 634, 634,
- 634, 634, 634, 689, 648, 1060, 468, 635, 542, 716,
- 689, 365, 1059, 635, 635, 635, 635, 635, 635, 768,
- 769, 769, 769, 769, 769, 769, 1463, 538, 533, 705,
- 770, 686, 696, 693, 616, 607, 770, 770, 770, 770,
-
- 770, 770, 774, 775, 775, 775, 775, 775, 775, 451,
- 689, 686, 1463, 776, 684, 607, 597, 595, 673, 776,
- 776, 776, 776, 776, 776, 694, 779, 779, 779, 779,
- 779, 779, 779, 696, 672, 671, 670, 780, 669, 668,
- 667, 666, 665, 780, 780, 780, 780, 780, 780, 781,
- 782, 782, 782, 782, 782, 782, 451, 664, 663, 662,
- 783, 661, 660, 659, 658, 657, 783, 783, 783, 783,
- 783, 783, 703, 791, 791, 791, 791, 791, 791, 791,
- 705, 656, 655, 654, 792, 653, 652, 651, 466, 648,
- 792, 792, 792, 792, 792, 792, 793, 794, 794, 794,
-
- 794, 794, 794, 451, 468, 462, 544, 795, 528, 535,
- 616, 607, 528, 795, 795, 795, 795, 795, 795, 714,
- 806, 806, 806, 806, 806, 806, 806, 716, 607, 601,
- 601, 807, 594, 593, 592, 591, 590, 807, 807, 807,
- 807, 807, 807, 808, 809, 809, 809, 809, 809, 809,
- 451, 589, 588, 587, 810, 586, 338, 239, 585, 584,
- 810, 810, 810, 810, 810, 810, 646, 817, 817, 817,
- 817, 817, 817, 817, 648, 583, 582, 581, 818, 580,
- 579, 578, 577, 576, 818, 818, 818, 818, 818, 818,
- 819, 820, 820, 820, 820, 820, 820, 820, 821, 575,
-
- 574, 571, 822, 568, 823, 567, 566, 565, 822, 822,
- 822, 822, 822, 822, 987, 988, 988, 988, 988, 988,
- 988, 991, 992, 992, 992, 992, 992, 992, 1061, 1061,
- 823, 55, 1071, 837, 837, 837, 837, 837, 837, 837,
- 564, 563, 1062, 1463, 837, 562, 1072, 561, 560, 55,
- 837, 837, 837, 837, 837, 837, 838, 838, 838, 838,
- 838, 838, 838, 559, 468, 279, 451, 838, 1062, 1463,
- 365, 544, 1072, 838, 838, 838, 838, 838, 838, 839,
- 840, 840, 840, 840, 840, 840, 528, 535, 451, 532,
- 841, 448, 55, 442, 528, 526, 841, 841, 841, 841,
-
- 841, 841, 267, 842, 842, 842, 842, 842, 842, 842,
- 55, 442, 434, 428, 843, 513, 512, 511, 510, 1413,
- 843, 843, 843, 843, 843, 843, 53, 843, 843, 843,
- 843, 843, 843, 843, 694, 846, 846, 846, 846, 846,
- 846, 846, 847, 509, 508, 507, 848, 506, 698, 505,
- 504, 503, 848, 848, 848, 848, 848, 848, 897, 897,
- 897, 897, 897, 897, 897, 969, 969, 969, 969, 969,
- 969, 969, 1071, 502, 698, 703, 849, 849, 849, 849,
- 849, 849, 849, 850, 501, 1073, 1463, 851, 498, 707,
- 497, 1073, 1083, 851, 851, 851, 851, 851, 851, 1074,
-
- 494, 493, 492, 491, 490, 1463, 1084, 120, 489, 488,
- 479, 55, 1463, 1083, 478, 707, 714, 852, 852, 852,
- 852, 852, 852, 852, 853, 1074, 477, 1463, 854, 55,
- 718, 1463, 1084, 1085, 854, 854, 854, 854, 854, 854,
- 985, 985, 985, 985, 985, 985, 985, 1086, 1412, 476,
- 475, 474, 1085, 1463, 1203, 473, 718, 858, 859, 859,
- 859, 859, 859, 859, 859, 860, 1463, 472, 1204, 861,
- 471, 862, 277, 1086, 1203, 861, 861, 861, 861, 861,
- 861, 1095, 1096, 1096, 1096, 1096, 1096, 1096, 1463, 468,
- 279, 451, 1463, 1205, 1204, 1205, 367, 862, 694, 865,
-
- 865, 865, 865, 865, 865, 865, 847, 1206, 448, 1463,
- 866, 442, 442, 435, 1463, 435, 866, 866, 866, 866,
- 866, 866, 867, 868, 868, 868, 868, 868, 868, 868,
- 869, 427, 420, 1206, 870, 1463, 871, 419, 416, 415,
- 870, 870, 870, 870, 870, 870, 1098, 1099, 1099, 1099,
- 1099, 1099, 1099, 1102, 1103, 1103, 1103, 1103, 1103, 1103,
- 1249, 414, 871, 703, 876, 876, 876, 876, 876, 876,
- 876, 850, 413, 412, 1250, 877, 411, 410, 409, 408,
- 407, 877, 877, 877, 877, 877, 877, 878, 879, 879,
- 879, 879, 879, 879, 879, 880, 55, 55, 1249, 881,
-
- 1250, 882, 406, 405, 404, 881, 881, 881, 881, 881,
- 881, 403, 1463, 402, 55, 55, 1145, 1146, 1146, 1146,
- 1146, 1146, 1146, 1254, 401, 1110, 1111, 882, 714, 888,
- 888, 888, 888, 888, 888, 888, 853, 1255, 1463, 400,
- 889, 395, 394, 393, 392, 391, 889, 889, 889, 889,
- 889, 889, 890, 891, 891, 891, 891, 891, 891, 891,
- 892, 55, 1254, 1255, 893, 320, 894, 390, 389, 55,
- 893, 893, 893, 893, 893, 893, 1463, 388, 387, 55,
- 1151, 1152, 1152, 1152, 1152, 1152, 1152, 55, 386, 1256,
- 1112, 385, 894, 819, 905, 905, 905, 905, 905, 905,
-
- 905, 821, 1463, 1257, 379, 906, 1441, 279, 367, 275,
- 1256, 906, 906, 906, 906, 906, 906, 907, 908, 908,
- 908, 908, 908, 908, 1463, 364, 272, 360, 909, 1257,
- 266, 260, 143, 348, 909, 909, 909, 909, 909, 909,
- 55, 1262, 922, 922, 922, 922, 922, 922, 922, 347,
- 1463, 346, 341, 922, 320, 1263, 340, 339, 55, 922,
- 922, 922, 922, 922, 922, 923, 923, 923, 923, 923,
- 923, 923, 338, 337, 336, 335, 923, 334, 333, 332,
- 331, 1263, 923, 923, 923, 923, 923, 923, 601, 924,
- 924, 924, 924, 924, 924, 924, 330, 329, 328, 327,
-
- 925, 326, 433, 323, 322, 321, 925, 925, 925, 925,
- 925, 925, 1155, 1156, 1156, 1156, 1156, 1156, 1156, 1161,
- 1162, 1162, 1162, 1162, 1162, 1162, 320, 1262, 433, 925,
- 925, 925, 925, 925, 925, 925, 319, 318, 317, 316,
- 925, 1463, 315, 314, 313, 312, 925, 925, 925, 925,
- 925, 925, 267, 926, 926, 926, 926, 926, 926, 926,
- 311, 310, 309, 308, 927, 307, 306, 1463, 305, 304,
- 927, 927, 927, 927, 927, 927, 53, 927, 927, 927,
- 927, 927, 927, 927, 930, 931, 931, 931, 931, 931,
- 931, 303, 302, 301, 300, 932, 299, 298, 297, 143,
-
- 296, 932, 932, 932, 932, 932, 932, 694, 779, 779,
- 779, 779, 779, 779, 779, 847, 295, 294, 293, 780,
- 292, 291, 290, 289, 1264, 780, 780, 780, 780, 780,
- 780, 933, 934, 934, 934, 934, 934, 934, 1265, 288,
- 287, 286, 935, 285, 284, 283, 282, 279, 935, 935,
- 935, 935, 935, 935, 703, 791, 791, 791, 791, 791,
- 791, 791, 850, 267, 1265, 272, 792, 259, 258, 257,
- 256, 1264, 792, 792, 792, 792, 792, 792, 936, 937,
- 937, 937, 937, 937, 937, 1463, 255, 254, 253, 938,
- 252, 251, 250, 247, 244, 938, 938, 938, 938, 938,
-
- 938, 714, 806, 806, 806, 806, 806, 806, 806, 853,
- 241, 1463, 240, 807, 239, 238, 235, 234, 1270, 807,
- 807, 807, 807, 807, 807, 939, 940, 940, 940, 940,
- 940, 940, 1271, 233, 232, 231, 941, 230, 229, 228,
- 227, 226, 941, 941, 941, 941, 941, 941, 945, 946,
- 946, 946, 946, 946, 946, 451, 225, 224, 1271, 947,
- 223, 222, 221, 220, 216, 947, 947, 947, 947, 947,
- 947, 858, 950, 950, 950, 950, 950, 950, 950, 860,
- 215, 205, 204, 951, 203, 200, 199, 194, 193, 951,
- 951, 951, 951, 951, 951, 952, 953, 953, 953, 953,
-
- 953, 953, 451, 192, 191, 190, 954, 189, 188, 187,
- 186, 185, 954, 954, 954, 954, 954, 954, 867, 962,
- 962, 962, 962, 962, 962, 962, 869, 181, 180, 179,
- 963, 178, 177, 176, 175, 174, 963, 963, 963, 963,
- 963, 963, 964, 965, 965, 965, 965, 965, 965, 451,
- 173, 172, 171, 966, 170, 169, 168, 167, 166, 966,
- 966, 966, 966, 966, 966, 878, 977, 977, 977, 977,
- 977, 977, 977, 880, 165, 160, 151, 978, 150, 145,
- 59, 47, 45, 978, 978, 978, 978, 978, 978, 979,
- 980, 980, 980, 980, 980, 980, 451, 1463, 1463, 1463,
-
- 981, 1463, 1463, 1463, 1463, 1463, 981, 981, 981, 981,
- 981, 981, 890, 993, 993, 993, 993, 993, 993, 993,
- 892, 1463, 1463, 1463, 994, 1463, 1463, 1463, 1463, 1463,
- 994, 994, 994, 994, 994, 994, 995, 996, 996, 996,
- 996, 996, 996, 451, 1463, 1463, 1463, 997, 1463, 1463,
- 1463, 1463, 1463, 997, 997, 997, 997, 997, 997, 819,
- 1004, 1004, 1004, 1004, 1004, 1004, 1004, 821, 1463, 1463,
- 1463, 1005, 1463, 1463, 1463, 1463, 1463, 1005, 1005, 1005,
- 1005, 1005, 1005, 1006, 1007, 1007, 1007, 1007, 1007, 1007,
- 1007, 1008, 1463, 1463, 1463, 1009, 1463, 1010, 1463, 1463,
-
- 1463, 1009, 1009, 1009, 1009, 1009, 1009, 1164, 1165, 1165,
- 1165, 1165, 1165, 1165, 1168, 1169, 1169, 1169, 1169, 1169,
- 1169, 1463, 1463, 1010, 55, 601, 1023, 1023, 1023, 1023,
- 1023, 1023, 1023, 1463, 1463, 1463, 1463, 1024, 1463, 1463,
- 1463, 1463, 55, 1024, 1024, 1024, 1024, 1024, 1024, 53,
- 1024, 1024, 1024, 1024, 1024, 1024, 1024, 55, 267, 1025,
- 1025, 1025, 1025, 1025, 1025, 1025, 1175, 1176, 1176, 1176,
- 1176, 1176, 1176, 1463, 1463, 55, 858, 1028, 1028, 1028,
- 1028, 1028, 1028, 1028, 1029, 1463, 1463, 1463, 1030, 1463,
- 862, 1463, 1463, 1463, 1030, 1030, 1030, 1030, 1030, 1030,
-
- 1178, 1179, 1179, 1179, 1179, 1179, 1179, 1182, 1183, 1183,
- 1183, 1183, 1183, 1183, 1463, 1463, 862, 867, 1031, 1031,
- 1031, 1031, 1031, 1031, 1031, 1032, 1463, 1463, 1463, 1033,
- 1463, 871, 1463, 1463, 1463, 1033, 1033, 1033, 1033, 1033,
- 1033, 1189, 1190, 1190, 1190, 1190, 1190, 1190, 1192, 1193,
- 1193, 1193, 1193, 1193, 1193, 1463, 1463, 871, 878, 1034,
- 1034, 1034, 1034, 1034, 1034, 1034, 1035, 1463, 1463, 1463,
- 1036, 1463, 882, 1463, 1463, 1463, 1036, 1036, 1036, 1036,
- 1036, 1036, 1196, 1197, 1197, 1197, 1197, 1197, 1197, 1096,
- 1096, 1096, 1096, 1096, 1096, 1096, 55, 1463, 882, 890,
-
- 1037, 1037, 1037, 1037, 1037, 1037, 1037, 1038, 1463, 1270,
- 1272, 1039, 1463, 894, 55, 1463, 1463, 1039, 1039, 1039,
- 1039, 1039, 1039, 1463, 1273, 1219, 1241, 1242, 1242, 1242,
- 1242, 1242, 1242, 1463, 1272, 1463, 1463, 1463, 1278, 894,
- 1041, 1042, 1042, 1042, 1042, 1042, 1042, 1043, 1463, 1463,
- 1273, 1044, 1279, 1463, 1463, 1463, 1463, 1044, 1044, 1044,
- 1044, 1044, 1044, 1045, 1046, 1046, 1046, 1046, 1046, 1046,
- 1046, 1047, 1463, 1463, 1463, 1048, 1463, 1049, 1279, 1463,
- 1463, 1048, 1048, 1048, 1048, 1048, 1048, 1162, 1162, 1162,
- 1162, 1162, 1162, 1162, 1176, 1176, 1176, 1176, 1176, 1176,
-
- 1176, 1278, 1463, 1049, 858, 1052, 1052, 1052, 1052, 1052,
- 1052, 1052, 1029, 1463, 1463, 1463, 1053, 1463, 1463, 1463,
- 1463, 1463, 1053, 1053, 1053, 1053, 1053, 1053, 1054, 1055,
- 1055, 1055, 1055, 1055, 1055, 1055, 1056, 1463, 1463, 1463,
- 1057, 1463, 1058, 1463, 1463, 1280, 1057, 1057, 1057, 1057,
- 1057, 1057, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1281,
- 1463, 1463, 1463, 1463, 1280, 1463, 1312, 1463, 1058, 867,
- 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1032, 1463, 1463,
- 1313, 1064, 1463, 1463, 1463, 1281, 1463, 1064, 1064, 1064,
- 1064, 1064, 1064, 1065, 1066, 1066, 1066, 1066, 1066, 1066,
-
- 1066, 1067, 1463, 1463, 1463, 1068, 1313, 1069, 1463, 1463,
- 1463, 1068, 1068, 1068, 1068, 1068, 1068, 1286, 1287, 1287,
- 1287, 1287, 1287, 1287, 1289, 1290, 1290, 1290, 1290, 1290,
- 1290, 1312, 1463, 1069, 878, 1075, 1075, 1075, 1075, 1075,
- 1075, 1075, 1035, 1463, 1463, 1463, 1076, 1463, 1463, 1463,
- 1463, 1463, 1076, 1076, 1076, 1076, 1076, 1076, 1077, 1078,
- 1078, 1078, 1078, 1078, 1078, 1078, 1079, 1463, 1463, 1463,
- 1080, 1463, 1081, 1463, 1463, 1463, 1080, 1080, 1080, 1080,
- 1080, 1080, 1293, 1294, 1294, 1294, 1294, 1294, 1294, 1318,
- 1319, 1319, 1319, 1319, 1319, 1319, 1359, 1463, 1081, 890,
-
- 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1038, 1463, 1463,
- 1360, 1088, 1463, 1463, 1463, 1463, 55, 1088, 1088, 1088,
- 1088, 1088, 1088, 1089, 1090, 1090, 1090, 1090, 1090, 1090,
- 1090, 1091, 55, 1463, 55, 1092, 1360, 1093, 1463, 1463,
- 1463, 1092, 1092, 1092, 1092, 1092, 1092, 1301, 1463, 1463,
- 55, 1323, 1324, 1324, 1324, 1324, 1324, 1324, 1463, 1463,
- 1359, 1302, 1463, 1093, 1006, 1104, 1104, 1104, 1104, 1104,
- 1104, 1104, 1008, 1463, 1463, 1463, 1105, 1463, 1463, 1463,
- 1463, 1361, 1105, 1105, 1105, 1105, 1105, 1105, 1106, 1107,
- 1107, 1107, 1107, 1107, 1107, 1362, 1463, 1463, 1463, 1108,
-
- 1463, 1463, 1463, 1463, 1463, 1108, 1108, 1108, 1108, 1108,
- 1108, 55, 601, 1120, 1120, 1120, 1120, 1120, 1120, 1120,
- 1463, 1362, 1463, 1463, 927, 1463, 1463, 1463, 1463, 55,
- 927, 927, 927, 927, 927, 927, 53, 927, 927, 927,
- 927, 927, 927, 927, 55, 267, 1025, 1025, 1025, 1025,
- 1025, 1025, 1025, 1326, 1327, 1327, 1327, 1327, 1327, 1327,
- 1463, 1361, 55, 1123, 1124, 1124, 1124, 1124, 1124, 1124,
- 1463, 1463, 1463, 1463, 1125, 1463, 1463, 1463, 1463, 1463,
- 1125, 1125, 1125, 1125, 1125, 1125, 858, 950, 950, 950,
- 950, 950, 950, 950, 1029, 1463, 1463, 1463, 951, 1463,
-
- 1463, 1463, 1463, 1384, 951, 951, 951, 951, 951, 951,
- 1126, 1127, 1127, 1127, 1127, 1127, 1127, 1385, 1463, 1463,
- 1463, 1128, 1463, 1463, 1463, 1463, 1463, 1128, 1128, 1128,
- 1128, 1128, 1128, 867, 962, 962, 962, 962, 962, 962,
- 962, 1032, 1463, 1385, 1463, 963, 1463, 1463, 1463, 1463,
- 1384, 963, 963, 963, 963, 963, 963, 1129, 1130, 1130,
- 1130, 1130, 1130, 1130, 1463, 1463, 1463, 1463, 1131, 1463,
- 1463, 1463, 1463, 1463, 1131, 1131, 1131, 1131, 1131, 1131,
- 878, 977, 977, 977, 977, 977, 977, 977, 1035, 1463,
- 1463, 1463, 978, 1463, 1463, 1463, 1463, 1388, 978, 978,
-
- 978, 978, 978, 978, 1132, 1133, 1133, 1133, 1133, 1133,
- 1133, 1389, 1463, 1463, 1463, 1134, 1463, 1463, 1463, 1463,
- 1463, 1134, 1134, 1134, 1134, 1134, 1134, 890, 993, 993,
- 993, 993, 993, 993, 993, 1038, 1463, 1389, 1463, 994,
- 1463, 1463, 1463, 1463, 1388, 994, 994, 994, 994, 994,
- 994, 1135, 1136, 1136, 1136, 1136, 1136, 1136, 1463, 1463,
- 1463, 1463, 1137, 1463, 1463, 1463, 1463, 1463, 1137, 1137,
- 1137, 1137, 1137, 1137, 1139, 1140, 1140, 1140, 1140, 1140,
- 1140, 1140, 1141, 1463, 1463, 1463, 1142, 1463, 1143, 1463,
- 1463, 1463, 1142, 1142, 1142, 1142, 1142, 1142, 1332, 1333,
-
- 1333, 1333, 1333, 1333, 1333, 1335, 1336, 1336, 1336, 1336,
- 1336, 1336, 1392, 1463, 1143, 1045, 1147, 1147, 1147, 1147,
- 1147, 1147, 1147, 1047, 1463, 1463, 1393, 1148, 1463, 1463,
- 1463, 1463, 1463, 1148, 1148, 1148, 1148, 1148, 1148, 1054,
- 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1056, 1463, 1463,
- 1463, 1158, 1393, 1463, 1463, 1463, 1463, 1158, 1158, 1158,
- 1158, 1158, 1158, 1065, 1170, 1170, 1170, 1170, 1170, 1170,
- 1170, 1067, 1463, 1463, 1463, 1171, 1463, 1463, 1463, 1463,
- 1463, 1171, 1171, 1171, 1171, 1171, 1171, 1077, 1184, 1184,
- 1184, 1184, 1184, 1184, 1184, 1079, 1463, 1463, 1463, 1185,
-
- 1463, 1463, 1463, 1463, 1463, 1185, 1185, 1185, 1185, 1185,
- 1185, 1089, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1091,
- 1463, 1463, 1463, 1199, 1463, 1463, 1463, 1463, 1463, 1199,
- 1199, 1199, 1199, 1199, 1199, 1006, 1207, 1207, 1207, 1207,
- 1207, 1207, 1207, 1008, 1463, 1463, 1463, 1208, 1463, 1463,
- 1463, 1463, 1463, 1208, 1208, 1208, 1208, 1208, 1208, 1209,
- 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1211, 1463, 1463,
- 1463, 1212, 1463, 1213, 1463, 1463, 1463, 1212, 1212, 1212,
- 1212, 1212, 1212, 1341, 1342, 1342, 1342, 1342, 1342, 1342,
- 1344, 1345, 1345, 1345, 1345, 1345, 1345, 1463, 1463, 1213,
-
- 55, 601, 518, 518, 518, 518, 518, 518, 518, 1350,
- 1351, 1351, 1351, 1351, 1351, 1351, 1463, 1392, 55, 1222,
- 1223, 1223, 1223, 1223, 1223, 1223, 1224, 1463, 1463, 1463,
- 1225, 1463, 1463, 1463, 1463, 1463, 1225, 1225, 1225, 1225,
- 1225, 1225, 1045, 1226, 1226, 1226, 1226, 1226, 1226, 1226,
- 1227, 1463, 1463, 1463, 1228, 1463, 1049, 1463, 1463, 1463,
- 1228, 1228, 1228, 1228, 1228, 1228, 1353, 1354, 1354, 1354,
- 1354, 1354, 1354, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
- 1463, 1463, 1049, 1054, 1229, 1229, 1229, 1229, 1229, 1229,
- 1229, 1230, 1463, 1463, 1463, 1231, 1463, 1058, 1463, 1463,
-
- 1463, 1231, 1231, 1231, 1231, 1231, 1231, 1378, 1379, 1379,
- 1379, 1379, 1379, 1379, 1324, 1324, 1324, 1324, 1324, 1324,
- 1324, 1463, 1463, 1058, 1065, 1232, 1232, 1232, 1232, 1232,
- 1232, 1232, 1233, 1463, 1463, 1463, 1234, 1463, 1069, 1463,
- 1463, 1463, 1234, 1234, 1234, 1234, 1234, 1234, 1333, 1333,
- 1333, 1333, 1333, 1333, 1333, 1342, 1342, 1342, 1342, 1342,
- 1342, 1342, 1396, 1463, 1069, 1077, 1235, 1235, 1235, 1235,
- 1235, 1235, 1235, 1236, 1463, 1396, 1397, 1237, 1463, 1081,
- 1463, 1463, 1463, 1237, 1237, 1237, 1237, 1237, 1237, 1463,
- 1351, 1351, 1351, 1351, 1351, 1351, 1351, 1463, 1463, 1463,
-
- 1463, 1463, 1397, 1400, 1463, 1081, 1089, 1238, 1238, 1238,
- 1238, 1238, 1238, 1238, 1239, 1463, 1400, 1401, 1240, 1463,
- 1093, 1463, 1463, 1463, 1240, 1240, 1240, 1240, 1240, 1240,
- 1463, 1404, 1405, 1405, 1405, 1405, 1405, 1405, 1463, 1463,
- 1463, 1463, 1463, 1401, 1416, 1463, 1093, 1139, 1243, 1243,
- 1243, 1243, 1243, 1243, 1243, 1141, 1463, 1463, 1417, 1244,
- 1463, 1463, 1463, 1463, 1463, 1244, 1244, 1244, 1244, 1244,
- 1244, 1045, 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1227,
- 1463, 1463, 1463, 1252, 1417, 1463, 1463, 1463, 1463, 1252,
- 1252, 1252, 1252, 1252, 1252, 1054, 1258, 1258, 1258, 1258,
-
- 1258, 1258, 1258, 1230, 1463, 1463, 1463, 1259, 1463, 1463,
- 1463, 1463, 1463, 1259, 1259, 1259, 1259, 1259, 1259, 1065,
- 1266, 1266, 1266, 1266, 1266, 1266, 1266, 1233, 1463, 1463,
- 1463, 1267, 1463, 1463, 1463, 1463, 1463, 1267, 1267, 1267,
- 1267, 1267, 1267, 1077, 1274, 1274, 1274, 1274, 1274, 1274,
- 1274, 1236, 1463, 1463, 1463, 1275, 1463, 1463, 1463, 1463,
- 1463, 1275, 1275, 1275, 1275, 1275, 1275, 1089, 1282, 1282,
- 1282, 1282, 1282, 1282, 1282, 1239, 1463, 1463, 1463, 1283,
- 1463, 1463, 1463, 1463, 1463, 1283, 1283, 1283, 1283, 1283,
- 1283, 1209, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1211,
-
- 1463, 1463, 1463, 1296, 1463, 1463, 1463, 1463, 1463, 1296,
- 1296, 1296, 1296, 1296, 1296, 1139, 1303, 1303, 1303, 1303,
- 1303, 1303, 1303, 1304, 1463, 1463, 1463, 1305, 1463, 1143,
- 1463, 1463, 1416, 1305, 1305, 1305, 1305, 1305, 1305, 1407,
- 1408, 1408, 1408, 1408, 1408, 1408, 1463, 1418, 1419, 1419,
- 1419, 1419, 1419, 1419, 1463, 1143, 1045, 1147, 1147, 1147,
- 1147, 1147, 1147, 1147, 1227, 1463, 1463, 1463, 1148, 1463,
- 1463, 1463, 1463, 1463, 1148, 1148, 1148, 1148, 1148, 1148,
- 1054, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1230, 1463,
- 1463, 1463, 1158, 1463, 1463, 1463, 1463, 1463, 1158, 1158,
-
- 1158, 1158, 1158, 1158, 1065, 1170, 1170, 1170, 1170, 1170,
- 1170, 1170, 1233, 1463, 1463, 1463, 1171, 1463, 1463, 1463,
- 1463, 1463, 1171, 1171, 1171, 1171, 1171, 1171, 1077, 1184,
- 1184, 1184, 1184, 1184, 1184, 1184, 1236, 1463, 1463, 1463,
- 1185, 1463, 1463, 1463, 1463, 1463, 1185, 1185, 1185, 1185,
- 1185, 1185, 1089, 1198, 1198, 1198, 1198, 1198, 1198, 1198,
- 1239, 1463, 1463, 1463, 1199, 1463, 1463, 1463, 1463, 1463,
- 1199, 1199, 1199, 1199, 1199, 1199, 1139, 1314, 1314, 1314,
- 1314, 1314, 1314, 1314, 1304, 1463, 1463, 1463, 1315, 1463,
- 1463, 1463, 1463, 1463, 1315, 1315, 1315, 1315, 1315, 1315,
-
- 1209, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1211, 1463,
- 1463, 1463, 1364, 1463, 1463, 1463, 1463, 1463, 1364, 1364,
- 1364, 1364, 1364, 1364, 1139, 1243, 1243, 1243, 1243, 1243,
- 1243, 1243, 1304, 1463, 1463, 1463, 1244, 1463, 1463, 1463,
- 1463, 1463, 1244, 1244, 1244, 1244, 1244, 1244, 1422, 1423,
- 1423, 1423, 1423, 1423, 1423, 1426, 1427, 1427, 1427, 1427,
- 1427, 1427, 1430, 1431, 1431, 1431, 1431, 1431, 1431, 1434,
- 1435, 1435, 1435, 1435, 1435, 1435, 1405, 1405, 1405, 1405,
- 1405, 1405, 1405, 1438, 1438, 1442, 1443, 1443, 1443, 1443,
- 1443, 1443, 1463, 1463, 1463, 1463, 1463, 1439, 1463, 1419,
-
- 1419, 1419, 1419, 1419, 1419, 1419, 1423, 1423, 1423, 1423,
- 1423, 1423, 1423, 1427, 1427, 1427, 1427, 1427, 1427, 1427,
- 1463, 1463, 1463, 1439, 1463, 1431, 1431, 1431, 1431, 1431,
- 1431, 1431, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1451,
- 1452, 1452, 1452, 1452, 1452, 1452, 1443, 1443, 1443, 1443,
- 1443, 1443, 1443, 1452, 1452, 1452, 1452, 1452, 1452, 1452,
- 46, 1463, 1463, 1463, 1463, 46, 46, 46, 64, 1463,
- 64, 64, 64, 64, 64, 64, 64, 152, 1463, 152,
- 159, 159, 159, 271, 271, 271, 280, 280, 280, 359,
- 359, 359, 362, 362, 362, 363, 363, 363, 370, 370,
-
- 370, 368, 368, 368, 374, 374, 374, 378, 1463, 378,
- 441, 441, 441, 446, 446, 446, 447, 447, 447, 456,
- 456, 456, 460, 1463, 460, 461, 461, 461, 372, 372,
- 1463, 1463, 372, 465, 465, 465, 469, 469, 469, 362,
- 362, 362, 525, 525, 525, 529, 529, 529, 530, 530,
- 530, 531, 531, 531, 370, 370, 370, 536, 536, 536,
- 454, 454, 1463, 1463, 454, 541, 541, 541, 545, 545,
- 545, 549, 1463, 549, 550, 550, 550, 554, 554, 554,
- 558, 1463, 558, 606, 606, 606, 456, 456, 456, 614,
- 614, 614, 615, 615, 615, 623, 623, 623, 627, 1463,
-
- 627, 630, 1463, 630, 631, 631, 631, 635, 635, 635,
- 639, 1463, 639, 548, 548, 1463, 1463, 548, 552, 552,
- 1463, 1463, 552, 645, 645, 645, 649, 649, 649, 558,
- 558, 1463, 558, 530, 530, 530, 683, 683, 683, 687,
- 687, 687, 690, 690, 690, 691, 691, 691, 692, 692,
- 692, 697, 697, 697, 621, 621, 1463, 1463, 621, 702,
- 702, 702, 706, 706, 706, 627, 627, 1463, 627, 629,
- 629, 1463, 1463, 629, 630, 630, 1463, 630, 631, 631,
- 633, 633, 1463, 1463, 633, 713, 713, 713, 717, 717,
- 717, 639, 639, 1463, 639, 721, 1463, 721, 724, 1463,
-
- 724, 725, 725, 725, 729, 729, 729, 733, 1463, 733,
- 760, 760, 760, 623, 623, 623, 635, 635, 635, 771,
- 771, 771, 772, 772, 772, 780, 780, 780, 784, 1463,
- 784, 787, 1463, 787, 788, 788, 788, 792, 792, 792,
- 796, 1463, 796, 799, 1463, 799, 802, 1463, 802, 803,
- 803, 803, 807, 807, 807, 811, 1463, 811, 720, 1463,
- 1463, 720, 721, 721, 1463, 721, 723, 723, 1463, 1463,
- 723, 724, 724, 1463, 724, 725, 725, 727, 727, 1463,
- 1463, 727, 818, 818, 818, 822, 822, 822, 733, 733,
- 1463, 733, 53, 53, 53, 1463, 53, 53, 691, 691,
-
- 691, 844, 844, 844, 848, 848, 848, 851, 851, 851,
- 854, 854, 854, 855, 855, 855, 856, 856, 856, 861,
- 861, 861, 778, 778, 1463, 1463, 778, 866, 866, 866,
- 870, 870, 870, 784, 784, 1463, 784, 786, 786, 1463,
- 1463, 786, 787, 787, 1463, 787, 788, 788, 790, 790,
- 1463, 1463, 790, 877, 877, 877, 881, 881, 881, 796,
- 796, 1463, 796, 798, 1463, 1463, 798, 799, 799, 1463,
- 799, 801, 801, 1463, 1463, 801, 802, 802, 1463, 802,
- 803, 803, 805, 805, 1463, 1463, 805, 889, 889, 889,
- 893, 893, 893, 811, 811, 1463, 811, 895, 1463, 895,
-
- 898, 1463, 898, 901, 1463, 901, 902, 902, 902, 906,
- 906, 906, 910, 1463, 910, 53, 53, 53, 1463, 53,
- 53, 928, 928, 928, 780, 780, 780, 792, 792, 792,
- 807, 807, 807, 942, 942, 942, 943, 943, 943, 951,
- 951, 951, 955, 1463, 955, 958, 1463, 958, 959, 959,
- 959, 963, 963, 963, 967, 1463, 967, 970, 1463, 970,
- 973, 1463, 973, 974, 974, 974, 978, 978, 978, 982,
- 1463, 982, 983, 1463, 983, 986, 1463, 986, 989, 1463,
- 989, 990, 990, 990, 994, 994, 994, 998, 1463, 998,
- 895, 1463, 895, 897, 1463, 1463, 897, 898, 898, 1463,
-
- 898, 900, 900, 1463, 1463, 900, 901, 901, 1463, 901,
- 902, 902, 904, 904, 1463, 1463, 904, 1005, 1005, 1005,
- 1009, 1009, 1009, 910, 910, 1463, 910, 53, 53, 53,
- 1463, 53, 53, 855, 855, 855, 1026, 1026, 1026, 1030,
- 1030, 1030, 1033, 1033, 1033, 1036, 1036, 1036, 1039, 1039,
- 1039, 1040, 1040, 1040, 1048, 1048, 1048, 949, 949, 1463,
- 1463, 949, 1053, 1053, 1053, 1057, 1057, 1057, 955, 955,
- 1463, 955, 957, 957, 1463, 1463, 957, 958, 958, 1463,
- 958, 959, 959, 961, 961, 1463, 1463, 961, 1064, 1064,
- 1064, 1068, 1068, 1068, 967, 967, 1463, 967, 969, 1463,
-
- 1463, 969, 970, 970, 1463, 970, 972, 972, 1463, 1463,
- 972, 973, 973, 1463, 973, 974, 974, 976, 976, 1463,
- 1463, 976, 1076, 1076, 1076, 1080, 1080, 1080, 982, 982,
- 1463, 982, 983, 1463, 983, 985, 1463, 1463, 985, 986,
- 986, 1463, 986, 988, 988, 1463, 1463, 988, 989, 989,
- 1463, 989, 990, 990, 992, 992, 1463, 1463, 992, 1088,
- 1088, 1088, 1092, 1092, 1092, 998, 998, 1463, 998, 1094,
- 1463, 1094, 1097, 1463, 1097, 1100, 1463, 1100, 1101, 1101,
- 1101, 1105, 1105, 1105, 1109, 1463, 1109, 53, 53, 53,
- 1463, 53, 53, 1121, 1121, 1121, 951, 951, 951, 963,
-
- 963, 963, 978, 978, 978, 994, 994, 994, 1138, 1138,
- 1138, 1144, 1144, 1144, 1142, 1142, 1142, 1149, 1149, 1149,
- 1148, 1148, 1148, 1150, 1463, 1150, 1153, 1463, 1153, 1154,
- 1154, 1154, 1159, 1159, 1159, 1158, 1158, 1158, 1160, 1463,
- 1160, 1163, 1463, 1163, 1166, 1463, 1166, 1167, 1167, 1167,
- 1172, 1172, 1172, 1171, 1171, 1171, 1173, 1463, 1173, 1174,
- 1463, 1174, 1177, 1463, 1177, 1180, 1463, 1180, 1181, 1181,
- 1181, 1186, 1186, 1186, 1185, 1185, 1185, 1187, 1463, 1187,
- 1188, 1463, 1188, 1191, 1463, 1191, 1194, 1463, 1194, 1195,
- 1195, 1195, 1200, 1200, 1200, 1199, 1199, 1199, 1201, 1463,
-
- 1201, 1094, 1463, 1094, 1096, 1463, 1463, 1096, 1097, 1097,
- 1463, 1097, 1099, 1099, 1463, 1463, 1099, 1100, 1100, 1463,
- 1100, 1101, 1101, 1103, 1103, 1463, 1463, 1103, 1208, 1208,
- 1208, 1212, 1212, 1212, 1109, 1109, 1463, 1109, 53, 53,
- 53, 1463, 53, 53, 1040, 1040, 1040, 1228, 1228, 1228,
- 1231, 1231, 1231, 1234, 1234, 1234, 1237, 1237, 1237, 1240,
- 1240, 1240, 1245, 1245, 1245, 1244, 1244, 1244, 1247, 1463,
- 1247, 1248, 1248, 1248, 1146, 1146, 1463, 1463, 1146, 1252,
- 1252, 1252, 1253, 1253, 1253, 1150, 1150, 1463, 1150, 1152,
- 1152, 1463, 1463, 1152, 1153, 1153, 1463, 1153, 1154, 1154,
-
- 1156, 1156, 1463, 1463, 1156, 1259, 1259, 1259, 1260, 1260,
- 1260, 1160, 1160, 1463, 1160, 1162, 1463, 1463, 1162, 1163,
- 1163, 1463, 1163, 1165, 1165, 1463, 1463, 1165, 1166, 1166,
- 1463, 1166, 1167, 1167, 1169, 1169, 1463, 1463, 1169, 1267,
- 1267, 1267, 1268, 1268, 1268, 1173, 1173, 1463, 1173, 1174,
- 1463, 1174, 1176, 1463, 1463, 1176, 1177, 1177, 1463, 1177,
- 1179, 1179, 1463, 1463, 1179, 1180, 1180, 1463, 1180, 1181,
- 1181, 1183, 1183, 1463, 1463, 1183, 1275, 1275, 1275, 1276,
- 1276, 1276, 1187, 1187, 1463, 1187, 1188, 1463, 1188, 1190,
- 1463, 1463, 1190, 1191, 1191, 1463, 1191, 1193, 1193, 1463,
-
- 1463, 1193, 1194, 1194, 1463, 1194, 1195, 1195, 1197, 1197,
- 1463, 1463, 1197, 1283, 1283, 1283, 1284, 1284, 1284, 1201,
- 1201, 1463, 1201, 1285, 1463, 1285, 1288, 1463, 1288, 1291,
- 1463, 1291, 1292, 1292, 1292, 1297, 1463, 1297, 1296, 1296,
- 1296, 1298, 1463, 1298, 53, 53, 53, 1463, 53, 53,
- 1306, 1463, 1306, 1305, 1305, 1305, 1307, 1463, 1307, 1148,
- 1148, 1148, 1308, 1463, 1308, 1158, 1158, 1158, 1309, 1463,
- 1309, 1171, 1171, 1171, 1310, 1463, 1310, 1185, 1185, 1185,
- 1311, 1463, 1311, 1199, 1199, 1199, 1242, 1242, 1463, 1463,
- 1242, 1315, 1315, 1315, 1316, 1316, 1316, 370, 370, 370,
-
- 1247, 1247, 1463, 1247, 1317, 1317, 1317, 1320, 1463, 1320,
- 1321, 1321, 1321, 1322, 1322, 1322, 1325, 1463, 1325, 1328,
- 1463, 1328, 1329, 1329, 1329, 1330, 1330, 1330, 1331, 1463,
- 1331, 1334, 1463, 1334, 1337, 1463, 1337, 1338, 1338, 1338,
- 1339, 1339, 1339, 1340, 1463, 1340, 1343, 1463, 1343, 1346,
- 1463, 1346, 1347, 1347, 1347, 1348, 1348, 1348, 1349, 1463,
- 1349, 1352, 1463, 1352, 1355, 1463, 1355, 1356, 1356, 1356,
- 1357, 1357, 1357, 1285, 1463, 1285, 1287, 1463, 1463, 1287,
- 1288, 1288, 1463, 1288, 1290, 1290, 1463, 1463, 1290, 1291,
- 1291, 1463, 1291, 1292, 1292, 1294, 1294, 1463, 1463, 1294,
-
- 1364, 1364, 1364, 1365, 1463, 1365, 1298, 1298, 1463, 1298,
- 53, 53, 53, 1463, 53, 53, 1370, 1370, 1370, 1244,
- 1244, 1244, 1372, 1463, 1372, 1373, 1463, 1373, 1374, 1463,
- 1374, 1375, 1463, 1375, 1376, 1463, 1376, 1377, 1463, 1377,
- 1380, 1463, 1380, 1381, 1381, 1381, 1382, 1382, 1382, 1383,
- 1463, 1383, 1319, 1319, 1463, 1463, 1319, 1320, 1320, 1463,
- 1320, 1321, 1321, 1386, 1463, 1386, 1324, 1463, 1463, 1324,
- 1325, 1325, 1463, 1325, 1327, 1327, 1463, 1463, 1327, 1328,
- 1328, 1463, 1328, 1329, 1329, 1390, 1463, 1390, 1331, 1463,
- 1331, 1333, 1463, 1463, 1333, 1334, 1334, 1463, 1334, 1336,
-
- 1336, 1463, 1463, 1336, 1337, 1337, 1463, 1337, 1338, 1338,
- 1394, 1463, 1394, 1340, 1463, 1340, 1342, 1463, 1463, 1342,
- 1343, 1343, 1463, 1343, 1345, 1345, 1463, 1463, 1345, 1346,
- 1346, 1463, 1346, 1347, 1347, 1398, 1463, 1398, 1349, 1463,
- 1349, 1351, 1463, 1463, 1351, 1352, 1352, 1463, 1352, 1354,
- 1354, 1463, 1463, 1354, 1355, 1355, 1463, 1355, 1356, 1356,
- 1402, 1463, 1402, 1403, 1463, 1403, 1406, 1463, 1406, 1409,
- 1463, 1409, 1410, 1410, 1410, 1411, 1463, 1411, 53, 53,
- 53, 1463, 53, 53, 1415, 1463, 1415, 1317, 1463, 1317,
- 1322, 1463, 1322, 1330, 1463, 1330, 1339, 1463, 1339, 1348,
-
- 1463, 1348, 1357, 1463, 1357, 1379, 1379, 1463, 1463, 1379,
- 1380, 1380, 1463, 1380, 1381, 1381, 1371, 1463, 1371, 1420,
- 1463, 1420, 1421, 1463, 1421, 1424, 1463, 1424, 1425, 1463,
- 1425, 1428, 1463, 1428, 1429, 1463, 1429, 1432, 1463, 1432,
- 1433, 1463, 1433, 1436, 1463, 1436, 1405, 1463, 1463, 1405,
- 1408, 1408, 1463, 1463, 1408, 1440, 1463, 1440, 1382, 1463,
- 1382, 1444, 1463, 1444, 1419, 1463, 1463, 1419, 1423, 1463,
- 1463, 1423, 1427, 1463, 1463, 1427, 1431, 1463, 1463, 1431,
- 1435, 1463, 1463, 1435, 1450, 1463, 1450, 1453, 1463, 1453,
- 1443, 1463, 1463, 1443, 1455, 1463, 1455, 1456, 1463, 1456,
-
- 1457, 1463, 1457, 1458, 1463, 1458, 1459, 1463, 1459, 1452,
- 1463, 1463, 1452, 1461, 1463, 1461, 1462, 1463, 1462, 3,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463
+ 366, 366, 366, 366, 366, 367, 664, 453, 1335, 368,
+ 453, 369, 1287, 1289, 666, 368, 368, 368, 368, 368,
+ 368, 455, 456, 456, 456, 456, 456, 456, 524, 524,
+ 524, 524, 524, 524, 524, 658, 778, 369, 277, 373,
+
+ 373, 373, 373, 373, 373, 373, 279, 53, 1068, 659,
+ 374, 1295, 55, 55, 1293, 776, 374, 374, 374, 374,
+ 374, 374, 375, 376, 376, 376, 376, 376, 376, 53,
+ 55, 55, 780, 377, 658, 659, 879, 866, 1493, 377,
+ 377, 377, 377, 377, 377, 421, 53, 422, 1728, 423,
+ 424, 554, 555, 555, 555, 555, 555, 555, 55, 425,
+ 785, 426, 427, 660, 428, 430, 660, 431, 431, 431,
+ 431, 431, 431, 431, 1728, 53, 55, 661, 431, 873,
+ 1728, 55, 1413, 55, 431, 431, 431, 431, 431, 431,
+ 432, 433, 433, 433, 433, 433, 433, 433, 1413, 55,
+
+ 876, 55, 434, 661, 435, 453, 1728, 1345, 434, 434,
+ 434, 434, 434, 434, 558, 559, 559, 559, 559, 559,
+ 559, 638, 639, 639, 639, 639, 639, 639, 729, 783,
+ 435, 436, 434, 434, 434, 434, 434, 434, 434, 53,
+ 1117, 1350, 730, 434, 1352, 55, 55, 55, 729, 434,
+ 434, 434, 434, 434, 434, 438, 439, 439, 439, 439,
+ 439, 439, 1728, 55, 55, 55, 440, 874, 730, 55,
+ 883, 55, 440, 440, 440, 440, 440, 440, 267, 441,
+ 441, 441, 441, 441, 441, 441, 1126, 55, 1728, 55,
+ 442, 1728, 884, 1728, 1728, 1358, 442, 442, 442, 442,
+
+ 442, 442, 53, 442, 442, 442, 442, 442, 442, 442,
+ 445, 446, 446, 446, 446, 446, 446, 1728, 724, 1728,
+ 1728, 447, 1360, 55, 55, 794, 899, 447, 447, 447,
+ 447, 447, 447, 451, 452, 452, 452, 452, 452, 452,
+ 453, 55, 55, 55, 454, 887, 1728, 55, 796, 1137,
+ 454, 454, 454, 454, 454, 454, 365, 457, 457, 457,
+ 457, 457, 457, 457, 367, 55, 1728, 935, 458, 1728,
+ 55, 55, 1728, 1366, 458, 458, 458, 458, 458, 458,
+ 459, 460, 460, 460, 460, 460, 460, 453, 55, 55,
+ 53, 461, 1728, 935, 963, 1728, 55, 461, 461, 461,
+
+ 461, 461, 461, 277, 466, 466, 466, 466, 466, 466,
+ 466, 279, 1368, 1149, 55, 467, 53, 1374, 55, 964,
+ 55, 467, 467, 467, 467, 467, 467, 468, 469, 469,
+ 469, 469, 469, 469, 469, 470, 55, 975, 55, 471,
+ 787, 472, 1376, 965, 788, 471, 471, 471, 471, 471,
+ 471, 582, 738, 583, 53, 789, 584, 585, 53, 738,
+ 586, 587, 791, 733, 792, 588, 739, 472, 482, 53,
+ 1161, 902, 483, 1728, 53, 484, 53, 740, 485, 740,
+ 486, 487, 488, 489, 521, 521, 521, 521, 521, 521,
+ 521, 741, 739, 1728, 1295, 521, 55, 55, 55, 1728,
+
+ 1421, 521, 521, 521, 521, 521, 521, 522, 523, 523,
+ 523, 523, 523, 523, 55, 55, 55, 741, 524, 1728,
+ 967, 969, 1061, 880, 524, 524, 524, 524, 524, 524,
+ 432, 525, 525, 525, 525, 525, 525, 525, 526, 526,
+ 526, 526, 526, 526, 526, 1223, 1468, 1470, 1061, 526,
+ 1506, 55, 55, 55, 55, 526, 526, 526, 526, 526,
+ 526, 437, 528, 528, 528, 528, 528, 528, 528, 55,
+ 55, 55, 55, 529, 1510, 265, 970, 976, 881, 529,
+ 529, 529, 529, 529, 529, 646, 647, 647, 647, 647,
+ 647, 647, 650, 651, 651, 651, 651, 651, 651, 55,
+
+ 855, 265, 529, 529, 529, 529, 529, 529, 529, 1728,
+ 744, 1728, 1728, 529, 856, 55, 1514, 55, 905, 529,
+ 529, 529, 529, 529, 529, 530, 530, 530, 530, 530,
+ 530, 530, 1518, 55, 867, 1728, 531, 1728, 1728, 1728,
+ 856, 979, 531, 531, 531, 531, 531, 531, 53, 531,
+ 531, 531, 531, 531, 531, 531, 365, 534, 534, 534,
+ 534, 534, 534, 534, 535, 1728, 1522, 1551, 536, 1728,
+ 369, 1573, 1155, 1149, 536, 536, 536, 536, 536, 536,
+ 749, 750, 750, 750, 750, 750, 750, 752, 753, 753,
+ 753, 753, 753, 753, 55, 1728, 369, 540, 541, 541,
+
+ 541, 541, 541, 541, 541, 542, 861, 453, 1332, 543,
+ 930, 544, 55, 1085, 863, 543, 543, 543, 543, 543,
+ 543, 756, 757, 757, 757, 757, 757, 757, 819, 820,
+ 820, 820, 820, 820, 820, 855, 55, 544, 365, 547,
+ 547, 547, 547, 547, 547, 547, 535, 1145, 1143, 1728,
+ 548, 1728, 1137, 1728, 55, 55, 548, 548, 548, 548,
+ 548, 548, 549, 550, 550, 550, 550, 550, 550, 550,
+ 551, 868, 453, 55, 552, 1728, 553, 1728, 982, 1728,
+ 552, 552, 552, 552, 552, 552, 827, 828, 828, 828,
+ 828, 828, 828, 831, 832, 832, 832, 832, 832, 832,
+
+ 857, 55, 553, 468, 560, 560, 560, 560, 560, 560,
+ 560, 470, 1329, 1728, 858, 561, 919, 55, 1133, 55,
+ 857, 561, 561, 561, 561, 561, 561, 562, 563, 563,
+ 563, 563, 563, 563, 1728, 55, 869, 1131, 564, 1728,
+ 858, 55, 1087, 55, 564, 564, 564, 564, 564, 564,
+ 613, 915, 614, 614, 614, 614, 614, 614, 614, 55,
+ 1728, 55, 1126, 614, 972, 916, 55, 55, 885, 614,
+ 614, 614, 614, 614, 614, 615, 616, 616, 616, 616,
+ 616, 616, 616, 453, 55, 55, 1326, 617, 1078, 618,
+ 910, 916, 1084, 617, 617, 617, 617, 617, 617, 839,
+
+ 840, 840, 840, 840, 840, 840, 842, 843, 843, 843,
+ 843, 843, 843, 55, 55, 618, 615, 617, 617, 617,
+ 617, 617, 617, 617, 1142, 910, 1122, 1728, 617, 1154,
+ 1728, 55, 55, 1101, 617, 617, 617, 617, 617, 617,
+ 437, 620, 620, 620, 620, 620, 620, 620, 871, 919,
+ 1142, 877, 621, 1728, 1728, 1154, 1728, 1104, 621, 621,
+ 621, 621, 621, 621, 53, 621, 621, 621, 621, 621,
+ 621, 621, 622, 622, 622, 622, 622, 622, 622, 930,
+ 1728, 1117, 453, 623, 1286, 1728, 1728, 1107, 1323, 623,
+ 623, 623, 623, 623, 623, 53, 623, 623, 623, 623,
+
+ 623, 623, 623, 626, 627, 627, 627, 627, 627, 627,
+ 1286, 1728, 1728, 1728, 628, 453, 1225, 55, 55, 55,
+ 628, 628, 628, 628, 628, 628, 365, 457, 457, 457,
+ 457, 457, 457, 457, 535, 55, 55, 55, 458, 1728,
+ 1082, 1086, 1089, 915, 458, 458, 458, 458, 458, 458,
+ 629, 630, 630, 630, 630, 630, 630, 1728, 942, 1342,
+ 1728, 631, 1206, 55, 55, 1335, 1110, 631, 631, 631,
+ 631, 631, 631, 635, 636, 636, 636, 636, 636, 636,
+ 453, 55, 55, 1728, 637, 1090, 1728, 55, 55, 1088,
+ 637, 637, 637, 637, 637, 637, 540, 640, 640, 640,
+
+ 640, 640, 640, 640, 542, 55, 55, 1091, 641, 1332,
+ 55, 1093, 55, 1329, 641, 641, 641, 641, 641, 641,
+ 642, 643, 643, 643, 643, 643, 643, 453, 55, 1326,
+ 55, 644, 1323, 1206, 55, 55, 55, 644, 644, 644,
+ 644, 644, 644, 549, 652, 652, 652, 652, 652, 652,
+ 652, 551, 55, 55, 55, 653, 1068, 55, 55, 55,
+ 1295, 653, 653, 653, 653, 653, 653, 654, 655, 655,
+ 655, 655, 655, 655, 453, 55, 55, 55, 656, 1187,
+ 1190, 55, 1191, 55, 656, 656, 656, 656, 656, 656,
+ 468, 662, 662, 662, 662, 662, 662, 662, 470, 55,
+
+ 1070, 55, 663, 1728, 1728, 55, 1194, 861, 663, 663,
+ 663, 663, 663, 663, 664, 665, 665, 665, 665, 665,
+ 665, 665, 666, 55, 1064, 1195, 667, 1062, 668, 1728,
+ 1728, 1163, 667, 667, 667, 667, 667, 667, 846, 847,
+ 847, 847, 847, 847, 847, 750, 750, 750, 750, 750,
+ 750, 750, 55, 55, 668, 704, 704, 704, 704, 704,
+ 704, 704, 1357, 453, 1365, 1373, 704, 1728, 55, 1110,
+ 55, 55, 704, 704, 704, 704, 704, 704, 705, 705,
+ 705, 705, 705, 705, 705, 878, 55, 968, 1357, 705,
+ 1365, 1373, 1199, 1728, 1151, 705, 705, 705, 705, 705,
+
+ 705, 615, 706, 706, 706, 706, 706, 706, 706, 707,
+ 707, 707, 707, 707, 707, 707, 1068, 453, 1107, 1467,
+ 707, 1509, 55, 55, 1070, 55, 707, 707, 707, 707,
+ 707, 707, 437, 709, 709, 709, 709, 709, 709, 709,
+ 55, 55, 1197, 55, 710, 1467, 1200, 1509, 1513, 978,
+ 710, 710, 710, 710, 710, 710, 53, 710, 710, 710,
+ 710, 710, 710, 710, 711, 711, 711, 711, 711, 711,
+ 711, 1117, 1126, 1139, 1513, 712, 453, 1104, 1128, 1323,
+ 1326, 712, 712, 712, 712, 712, 712, 53, 712, 712,
+ 712, 712, 712, 712, 712, 540, 715, 715, 715, 715,
+
+ 715, 715, 715, 716, 55, 55, 924, 717, 55, 544,
+ 55, 55, 55, 717, 717, 717, 717, 717, 717, 1137,
+ 925, 453, 55, 55, 1101, 1119, 55, 1329, 55, 55,
+ 55, 55, 980, 55, 870, 544, 549, 718, 718, 718,
+ 718, 718, 718, 718, 719, 882, 925, 886, 720, 55,
+ 553, 55, 1149, 1298, 720, 720, 720, 720, 720, 720,
+ 1332, 875, 453, 1225, 888, 893, 893, 893, 893, 893,
+ 893, 893, 55, 924, 926, 1517, 553, 724, 725, 725,
+ 725, 725, 725, 725, 725, 726, 55, 1728, 927, 727,
+ 55, 728, 926, 936, 936, 727, 727, 727, 727, 727,
+
+ 727, 1517, 341, 1161, 55, 1521, 1728, 937, 1728, 55,
+ 453, 1335, 1206, 1728, 927, 938, 1110, 728, 540, 731,
+ 731, 731, 731, 731, 731, 731, 716, 55, 1299, 939,
+ 732, 1521, 1728, 937, 1728, 55, 732, 732, 732, 732,
+ 732, 732, 733, 734, 734, 734, 734, 734, 734, 734,
+ 735, 1300, 1107, 55, 736, 939, 737, 1104, 1304, 938,
+ 736, 736, 736, 736, 736, 736, 840, 840, 840, 840,
+ 840, 840, 840, 1728, 948, 949, 949, 949, 949, 949,
+ 949, 1101, 737, 549, 742, 742, 742, 742, 742, 742,
+ 742, 719, 1223, 1206, 1572, 743, 1592, 1593, 55, 1728,
+
+ 1413, 743, 743, 743, 743, 743, 743, 744, 745, 745,
+ 745, 745, 745, 745, 745, 746, 55, 1070, 1301, 747,
+ 1572, 748, 1592, 1593, 863, 747, 747, 747, 747, 747,
+ 747, 951, 952, 952, 952, 952, 952, 952, 955, 956,
+ 956, 956, 956, 956, 956, 55, 55, 748, 664, 758,
+ 758, 758, 758, 758, 758, 758, 666, 1293, 942, 1163,
+ 759, 1110, 1594, 55, 55, 1295, 759, 759, 759, 759,
+ 759, 759, 760, 761, 761, 761, 761, 761, 761, 966,
+ 974, 744, 938, 762, 55, 55, 55, 55, 1594, 762,
+ 762, 762, 762, 762, 762, 53, 53, 53, 53, 53,
+
+ 53, 53, 55, 55, 55, 55, 53, 55, 55, 1062,
+ 55, 55, 53, 53, 53, 53, 53, 53, 971, 973,
+ 1595, 983, 981, 1063, 1293, 55, 55, 1062, 55, 55,
+ 764, 794, 1728, 795, 795, 795, 795, 795, 795, 795,
+ 977, 1728, 1077, 1073, 795, 1186, 1595, 55, 936, 1063,
+ 795, 795, 795, 795, 795, 795, 1010, 1011, 1011, 1011,
+ 1011, 1011, 1011, 1064, 1064, 55, 55, 1728, 53, 796,
+ 797, 797, 797, 797, 797, 797, 797, 1065, 1728, 930,
+ 1074, 797, 55, 55, 55, 1079, 1151, 797, 797, 797,
+ 797, 797, 797, 1018, 1019, 1019, 1019, 1019, 1019, 1019,
+
+ 55, 55, 1080, 1065, 1728, 53, 706, 706, 706, 706,
+ 706, 706, 706, 1022, 1023, 1023, 1023, 1023, 1023, 1023,
+ 1030, 1031, 1031, 1031, 1031, 1031, 1031, 1033, 1034, 1034,
+ 1034, 1034, 1034, 1034, 1037, 1038, 1038, 1038, 1038, 1038,
+ 1038, 53, 707, 707, 707, 707, 707, 707, 707, 1107,
+ 733, 926, 924, 707, 919, 1596, 1613, 1619, 1139, 707,
+ 707, 707, 707, 707, 707, 798, 353, 353, 353, 353,
+ 353, 353, 353, 267, 800, 800, 800, 800, 800, 800,
+ 800, 1596, 1613, 1619, 1104, 801, 724, 915, 910, 1128,
+ 1101, 801, 801, 801, 801, 801, 801, 53, 801, 801,
+
+ 801, 801, 801, 801, 801, 804, 805, 805, 805, 805,
+ 805, 805, 1119, 1006, 991, 1110, 806, 1107, 1104, 55,
+ 55, 55, 806, 806, 806, 806, 806, 806, 540, 640,
+ 640, 640, 640, 640, 640, 640, 716, 55, 55, 55,
+ 641, 1315, 1101, 1316, 55, 1122, 641, 641, 641, 641,
+ 641, 641, 807, 808, 808, 808, 808, 808, 808, 1123,
+ 1302, 1099, 55, 809, 991, 861, 55, 1070, 55, 809,
+ 809, 809, 809, 809, 809, 549, 652, 652, 652, 652,
+ 652, 652, 652, 719, 55, 1123, 55, 653, 863, 55,
+ 55, 55, 1122, 653, 653, 653, 653, 653, 653, 810,
+
+ 811, 811, 811, 811, 811, 811, 1728, 55, 55, 55,
+ 812, 664, 55, 1395, 1404, 1306, 812, 812, 812, 812,
+ 812, 812, 816, 817, 817, 817, 817, 817, 817, 453,
+ 55, 857, 1728, 818, 855, 944, 905, 55, 55, 818,
+ 818, 818, 818, 818, 818, 724, 821, 821, 821, 821,
+ 821, 821, 821, 726, 1401, 55, 55, 822, 932, 902,
+ 55, 55, 921, 822, 822, 822, 822, 822, 822, 823,
+ 824, 824, 824, 824, 824, 824, 453, 1409, 55, 55,
+ 825, 1476, 1477, 55, 55, 55, 825, 825, 825, 825,
+ 825, 825, 733, 833, 833, 833, 833, 833, 833, 833,
+
+ 735, 55, 55, 55, 834, 899, 1479, 912, 55, 1006,
+ 834, 834, 834, 834, 834, 834, 835, 836, 836, 836,
+ 836, 836, 836, 453, 991, 1478, 55, 837, 905, 902,
+ 1481, 55, 55, 837, 837, 837, 837, 837, 837, 744,
+ 848, 848, 848, 848, 848, 848, 848, 746, 899, 55,
+ 55, 849, 991, 1482, 55, 55, 1483, 849, 849, 849,
+ 849, 849, 849, 850, 851, 851, 851, 851, 851, 851,
+ 453, 863, 55, 55, 852, 666, 1486, 55, 1489, 55,
+ 852, 852, 852, 852, 852, 852, 664, 859, 859, 859,
+ 859, 859, 859, 859, 666, 55, 744, 55, 860, 944,
+
+ 905, 55, 549, 1536, 860, 860, 860, 860, 860, 860,
+ 861, 862, 862, 862, 862, 862, 862, 862, 863, 55,
+ 1546, 740, 864, 738, 865, 733, 932, 902, 864, 864,
+ 864, 864, 864, 864, 1046, 1047, 1047, 1047, 1047, 1047,
+ 1047, 1049, 1050, 1050, 1050, 1050, 1050, 1050, 1131, 55,
+ 865, 55, 1131, 889, 889, 889, 889, 889, 889, 889,
+ 540, 729, 1132, 724, 889, 921, 1728, 55, 55, 55,
+ 889, 889, 889, 889, 889, 889, 890, 890, 890, 890,
+ 890, 890, 890, 1081, 899, 912, 55, 890, 1132, 55,
+ 55, 55, 1728, 890, 890, 890, 890, 890, 890, 891,
+
+ 892, 892, 892, 892, 892, 892, 1189, 55, 55, 55,
+ 893, 1549, 55, 55, 55, 55, 893, 893, 893, 893,
+ 893, 893, 267, 894, 894, 894, 894, 894, 894, 894,
+ 55, 55, 55, 55, 895, 909, 1577, 1584, 815, 1396,
+ 895, 895, 895, 895, 895, 895, 53, 895, 895, 895,
+ 895, 895, 895, 895, 724, 898, 898, 898, 898, 898,
+ 898, 898, 899, 803, 905, 902, 900, 899, 728, 897,
+ 803, 664, 900, 900, 900, 900, 900, 900, 1053, 1054,
+ 1054, 1054, 1054, 1054, 1054, 949, 949, 949, 949, 949,
+ 949, 949, 55, 55, 728, 733, 901, 901, 901, 901,
+
+ 901, 901, 901, 902, 55, 55, 1133, 903, 863, 737,
+ 55, 55, 55, 903, 903, 903, 903, 903, 903, 666,
+ 1134, 468, 55, 55, 660, 1075, 1076, 55, 1083, 55,
+ 55, 55, 658, 1182, 1183, 737, 744, 904, 904, 904,
+ 904, 904, 904, 904, 905, 55, 1134, 55, 906, 55,
+ 748, 1537, 1133, 746, 906, 906, 906, 906, 906, 906,
+ 1092, 1143, 1094, 1185, 719, 735, 1728, 1031, 1031, 1031,
+ 1031, 1031, 1031, 1031, 1143, 1144, 748, 910, 911, 911,
+ 911, 911, 911, 911, 911, 912, 55, 55, 1728, 913,
+ 716, 914, 1728, 1145, 1145, 913, 913, 913, 913, 913,
+
+ 913, 1144, 726, 815, 55, 55, 803, 1146, 1728, 719,
+ 55, 716, 803, 1155, 1728, 1155, 1184, 914, 724, 917,
+ 917, 917, 917, 917, 917, 917, 899, 1156, 55, 1728,
+ 918, 53, 53, 1146, 1728, 53, 918, 918, 918, 918,
+ 918, 918, 919, 920, 920, 920, 920, 920, 920, 920,
+ 921, 1581, 790, 1156, 922, 1728, 923, 55, 55, 1157,
+ 922, 922, 922, 922, 922, 922, 1047, 1047, 1047, 1047,
+ 1047, 1047, 1047, 1158, 53, 55, 55, 53, 1157, 55,
+ 55, 772, 923, 733, 928, 928, 928, 928, 928, 928,
+ 928, 902, 1728, 1310, 1192, 929, 666, 55, 55, 1158,
+
+ 470, 929, 929, 929, 929, 929, 929, 930, 931, 931,
+ 931, 931, 931, 931, 931, 932, 1311, 1490, 1728, 933,
+ 549, 934, 746, 719, 365, 933, 933, 933, 933, 933,
+ 933, 1167, 1168, 1168, 1168, 1168, 1168, 1168, 1170, 1171,
+ 1171, 1171, 1171, 1171, 1171, 1287, 55, 934, 744, 940,
+ 940, 940, 940, 940, 940, 940, 905, 545, 540, 1288,
+ 941, 735, 716, 726, 55, 1201, 941, 941, 941, 941,
+ 941, 941, 942, 943, 943, 943, 943, 943, 943, 943,
+ 944, 1202, 1203, 723, 945, 1288, 946, 55, 55, 55,
+ 945, 945, 945, 945, 945, 945, 1174, 1175, 1175, 1175,
+
+ 1175, 1175, 1175, 634, 625, 55, 55, 55, 55, 1287,
+ 1289, 719, 946, 861, 957, 957, 957, 957, 957, 957,
+ 957, 863, 1193, 1728, 1290, 958, 55, 1544, 55, 55,
+ 1289, 958, 958, 958, 958, 958, 958, 959, 960, 960,
+ 960, 960, 960, 960, 1728, 1314, 55, 55, 961, 1728,
+ 1290, 55, 716, 55, 961, 961, 961, 961, 961, 961,
+ 55, 1188, 984, 984, 984, 984, 984, 984, 984, 55,
+ 1728, 55, 1602, 984, 1603, 55, 55, 55, 55, 984,
+ 984, 984, 984, 984, 984, 985, 985, 985, 985, 985,
+ 985, 985, 714, 55, 55, 55, 985, 1604, 55, 55,
+
+ 55, 55, 985, 985, 985, 985, 985, 985, 619, 986,
+ 986, 986, 986, 986, 986, 986, 55, 55, 55, 55,
+ 987, 1610, 435, 625, 615, 1491, 987, 987, 987, 987,
+ 987, 987, 1196, 1198, 1229, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1235, 1236, 1236, 1236, 1236, 1236, 1236, 435, 987,
+ 987, 987, 987, 987, 987, 987, 613, 703, 702, 701,
+ 987, 700, 55, 55, 55, 55, 987, 987, 987, 987,
+ 987, 987, 267, 988, 988, 988, 988, 988, 988, 988,
+ 55, 55, 55, 55, 989, 1624, 699, 1626, 1627, 1535,
+ 989, 989, 989, 989, 989, 989, 53, 989, 989, 989,
+
+ 989, 989, 989, 989, 992, 993, 993, 993, 993, 993,
+ 993, 698, 697, 696, 695, 994, 694, 693, 55, 55,
+ 55, 994, 994, 994, 994, 994, 994, 724, 821, 821,
+ 821, 821, 821, 821, 821, 899, 55, 55, 55, 822,
+ 692, 685, 1642, 55, 1345, 822, 822, 822, 822, 822,
+ 822, 995, 996, 996, 996, 996, 996, 996, 1346, 1634,
+ 684, 55, 997, 683, 682, 55, 1643, 55, 997, 997,
+ 997, 997, 997, 997, 733, 833, 833, 833, 833, 833,
+ 833, 833, 902, 55, 1346, 55, 834, 681, 1644, 55,
+ 55, 1345, 834, 834, 834, 834, 834, 834, 998, 999,
+
+ 999, 999, 999, 999, 999, 1728, 1635, 55, 55, 1000,
+ 680, 679, 1646, 678, 55, 1000, 1000, 1000, 1000, 1000,
+ 1000, 744, 848, 848, 848, 848, 848, 848, 848, 905,
+ 677, 1728, 55, 849, 676, 675, 55, 55, 1350, 849,
+ 849, 849, 849, 849, 849, 1001, 1002, 1002, 1002, 1002,
+ 1002, 1002, 1351, 1636, 55, 55, 1003, 1655, 55, 1657,
+ 674, 673, 1003, 1003, 1003, 1003, 1003, 1003, 1007, 1008,
+ 1008, 1008, 1008, 1008, 1008, 453, 55, 672, 1351, 1009,
+ 671, 1659, 55, 55, 55, 1009, 1009, 1009, 1009, 1009,
+ 1009, 910, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 912,
+
+ 55, 55, 55, 1013, 670, 1661, 55, 669, 468, 1013,
+ 1013, 1013, 1013, 1013, 1013, 1014, 1015, 1015, 1015, 1015,
+ 1015, 1015, 453, 1669, 55, 1662, 1016, 666, 470, 55,
+ 464, 55, 1016, 1016, 1016, 1016, 1016, 1016, 919, 1024,
+ 1024, 1024, 1024, 1024, 1024, 1024, 921, 55, 1663, 55,
+ 1025, 551, 1672, 55, 55, 535, 1025, 1025, 1025, 1025,
+ 1025, 1025, 1026, 1027, 1027, 1027, 1027, 1027, 1027, 453,
+ 542, 55, 55, 1028, 634, 625, 1680, 1681, 55, 1028,
+ 1028, 1028, 1028, 1028, 1028, 930, 1039, 1039, 1039, 1039,
+ 1039, 1039, 1039, 932, 535, 625, 55, 1040, 619, 55,
+
+ 55, 1686, 619, 1040, 1040, 1040, 1040, 1040, 1040, 1041,
+ 1042, 1042, 1042, 1042, 1042, 1042, 453, 55, 55, 612,
+ 1043, 1687, 611, 55, 55, 55, 1043, 1043, 1043, 1043,
+ 1043, 1043, 942, 1055, 1055, 1055, 1055, 1055, 1055, 1055,
+ 944, 55, 55, 55, 1056, 1693, 1690, 55, 55, 610,
+ 1056, 1056, 1056, 1056, 1056, 1056, 1057, 1058, 1058, 1058,
+ 1058, 1058, 1058, 453, 609, 55, 55, 1059, 608, 607,
+ 55, 1700, 55, 1059, 1059, 1059, 1059, 1059, 1059, 861,
+ 1066, 1066, 1066, 1066, 1066, 1066, 1066, 863, 55, 1694,
+ 55, 1067, 606, 605, 55, 1708, 55, 1067, 1067, 1067,
+
+ 1067, 1067, 1067, 1068, 1069, 1069, 1069, 1069, 1069, 1069,
+ 1069, 1070, 55, 604, 55, 1071, 603, 1072, 602, 338,
+ 239, 1071, 1071, 1071, 1071, 1071, 1071, 1239, 1240, 1240,
+ 1240, 1240, 1240, 1240, 1245, 1246, 1246, 1246, 1246, 1246,
+ 1246, 55, 55, 1072, 55, 619, 1095, 1095, 1095, 1095,
+ 1095, 1095, 1095, 601, 600, 599, 598, 1096, 597, 55,
+ 55, 596, 55, 1096, 1096, 1096, 1096, 1096, 1096, 53,
+ 1096, 1096, 1096, 1096, 1096, 1096, 1096, 55, 267, 1097,
+ 1097, 1097, 1097, 1097, 1097, 1097, 1248, 1249, 1249, 1249,
+ 1249, 1249, 1249, 55, 55, 55, 910, 1100, 1100, 1100,
+
+ 1100, 1100, 1100, 1100, 1101, 595, 594, 593, 1102, 592,
+ 914, 55, 55, 591, 1102, 1102, 1102, 1102, 1102, 1102,
+ 1252, 1253, 1253, 1253, 1253, 1253, 1253, 1259, 1260, 1260,
+ 1260, 1260, 1260, 1260, 55, 1710, 914, 919, 1103, 1103,
+ 1103, 1103, 1103, 1103, 1103, 1104, 590, 589, 581, 1105,
+ 578, 923, 55, 575, 574, 1105, 1105, 1105, 1105, 1105,
+ 1105, 1262, 1263, 1263, 1263, 1263, 1263, 1263, 1266, 1267,
+ 1267, 1267, 1267, 1267, 1267, 55, 1714, 923, 930, 1106,
+ 1106, 1106, 1106, 1106, 1106, 1106, 1107, 573, 572, 571,
+ 1108, 570, 934, 55, 569, 568, 1108, 1108, 1108, 1108,
+
+ 1108, 1108, 1273, 1274, 1274, 1274, 1274, 1274, 1274, 1276,
+ 1277, 1277, 1277, 1277, 1277, 1277, 55, 55, 934, 942,
+ 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1110, 567, 566,
+ 470, 1111, 279, 946, 55, 55, 453, 1111, 1111, 1111,
+ 1111, 1111, 1111, 1280, 1281, 1281, 1281, 1281, 1281, 1281,
+ 1168, 1168, 1168, 1168, 1168, 1168, 1168, 365, 551, 946,
+ 1113, 1114, 1114, 1114, 1114, 1114, 1114, 1115, 535, 542,
+ 453, 1116, 539, 450, 444, 55, 55, 1116, 1116, 1116,
+ 1116, 1116, 1116, 1117, 1118, 1118, 1118, 1118, 1118, 1118,
+ 1118, 1119, 55, 55, 55, 1120, 55, 1121, 55, 1350,
+
+ 55, 1120, 1120, 1120, 1120, 1120, 1120, 1308, 1305, 535,
+ 55, 533, 444, 1728, 55, 436, 55, 55, 55, 430,
+ 520, 1303, 519, 1121, 910, 1124, 1124, 1124, 1124, 1124,
+ 1124, 1124, 1101, 1312, 1583, 55, 1125, 1402, 1717, 1728,
+ 55, 55, 1125, 1125, 1125, 1125, 1125, 1125, 1126, 1127,
+ 1127, 1127, 1127, 1127, 1127, 1127, 1128, 55, 55, 55,
+ 1129, 518, 1130, 517, 516, 55, 1129, 1129, 1129, 1129,
+ 1129, 1129, 1309, 1313, 515, 55, 1337, 1338, 1338, 1338,
+ 1338, 1338, 1338, 55, 1352, 55, 1307, 514, 1130, 919,
+ 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1104, 1353, 513,
+
+ 1403, 1136, 512, 55, 511, 55, 510, 1136, 1136, 1136,
+ 1136, 1136, 1136, 1137, 1138, 1138, 1138, 1138, 1138, 1138,
+ 1138, 1139, 1405, 55, 1353, 1140, 509, 1141, 1352, 508,
+ 507, 1140, 1140, 1140, 1140, 1140, 1140, 1317, 506, 503,
+ 502, 499, 1728, 1246, 1246, 1246, 1246, 1246, 1246, 1246,
+ 498, 1358, 55, 1141, 930, 1147, 1147, 1147, 1147, 1147,
+ 1147, 1147, 1107, 497, 496, 1359, 1148, 495, 1728, 120,
+ 55, 494, 1148, 1148, 1148, 1148, 1148, 1148, 1149, 1150,
+ 1150, 1150, 1150, 1150, 1150, 1150, 1151, 1408, 1358, 1360,
+ 1152, 1359, 1153, 1360, 493, 481, 1152, 1152, 1152, 1152,
+
+ 1152, 1152, 1728, 1361, 480, 479, 478, 1728, 1260, 1260,
+ 1260, 1260, 1260, 1260, 1260, 477, 1366, 55, 1153, 942,
+ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1110, 1728, 1361,
+ 1367, 1160, 476, 1728, 475, 55, 474, 1160, 1160, 1160,
+ 1160, 1160, 1160, 1161, 1162, 1162, 1162, 1162, 1162, 1162,
+ 1162, 1163, 1475, 1366, 1368, 1164, 1367, 1165, 1368, 473,
+ 277, 1164, 1164, 1164, 1164, 1164, 1164, 1728, 1369, 470,
+ 279, 453, 1728, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
+ 367, 1374, 55, 1165, 1068, 1176, 1176, 1176, 1176, 1176,
+ 1176, 1176, 1070, 1728, 1369, 1375, 1177, 450, 1728, 444,
+
+ 55, 1374, 1177, 1177, 1177, 1177, 1177, 1177, 1178, 1179,
+ 1179, 1179, 1179, 1179, 1179, 1728, 444, 1547, 437, 1180,
+ 437, 1375, 55, 429, 55, 1180, 1180, 1180, 1180, 1180,
+ 1180, 55, 619, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
+ 55, 1728, 55, 420, 989, 1715, 419, 1719, 416, 55,
+ 989, 989, 989, 989, 989, 989, 53, 989, 989, 989,
+ 989, 989, 989, 989, 55, 267, 1097, 1097, 1097, 1097,
+ 1097, 1097, 1097, 415, 55, 55, 1376, 1376, 55, 55,
+ 414, 1421, 55, 1207, 1208, 1208, 1208, 1208, 1208, 1208,
+ 1377, 1728, 55, 55, 1209, 1422, 55, 55, 1399, 413,
+
+ 1209, 1209, 1209, 1209, 1209, 1209, 910, 1012, 1012, 1012,
+ 1012, 1012, 1012, 1012, 1101, 1400, 1377, 1728, 1013, 412,
+ 411, 1422, 410, 1421, 1013, 1013, 1013, 1013, 1013, 1013,
+ 1210, 1211, 1211, 1211, 1211, 1211, 1211, 1728, 409, 408,
+ 407, 1212, 406, 405, 404, 403, 55, 1212, 1212, 1212,
+ 1212, 1212, 1212, 919, 1024, 1024, 1024, 1024, 1024, 1024,
+ 1024, 1104, 402, 1728, 55, 1025, 401, 400, 395, 394,
+ 1468, 1025, 1025, 1025, 1025, 1025, 1025, 1213, 1214, 1214,
+ 1214, 1214, 1214, 1214, 1469, 1698, 393, 392, 1215, 391,
+ 320, 390, 389, 55, 1215, 1215, 1215, 1215, 1215, 1215,
+
+ 930, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1107, 388,
+ 1469, 55, 1040, 387, 386, 385, 379, 1468, 1040, 1040,
+ 1040, 1040, 1040, 1040, 1216, 1217, 1217, 1217, 1217, 1217,
+ 1217, 1728, 1723, 279, 367, 1218, 275, 364, 272, 360,
+ 266, 1218, 1218, 1218, 1218, 1218, 1218, 942, 1055, 1055,
+ 1055, 1055, 1055, 1055, 1055, 1110, 260, 1728, 143, 1056,
+ 348, 347, 346, 341, 1470, 1056, 1056, 1056, 1056, 1056,
+ 1056, 1219, 1220, 1220, 1220, 1220, 1220, 1220, 1471, 320,
+ 340, 339, 1221, 338, 337, 336, 335, 334, 1221, 1221,
+ 1221, 1221, 1221, 1221, 1223, 1224, 1224, 1224, 1224, 1224,
+
+ 1224, 1224, 1225, 333, 1471, 332, 1226, 331, 1227, 330,
+ 329, 328, 1226, 1226, 1226, 1226, 1226, 1226, 1382, 1383,
+ 1383, 1383, 1383, 1383, 1383, 1385, 1386, 1386, 1386, 1386,
+ 1386, 1386, 55, 327, 1227, 1117, 1231, 1231, 1231, 1231,
+ 1231, 1231, 1231, 1119, 326, 323, 322, 1232, 321, 320,
+ 55, 1406, 319, 1232, 1232, 1232, 1232, 1232, 1232, 1126,
+ 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1128, 1407, 318,
+ 317, 1242, 316, 315, 314, 313, 312, 1242, 1242, 1242,
+ 1242, 1242, 1242, 1137, 1254, 1254, 1254, 1254, 1254, 1254,
+ 1254, 1139, 311, 310, 309, 1255, 308, 307, 306, 305,
+
+ 304, 1255, 1255, 1255, 1255, 1255, 1255, 1149, 1268, 1268,
+ 1268, 1268, 1268, 1268, 1268, 1151, 303, 302, 301, 1269,
+ 300, 299, 298, 297, 143, 1269, 1269, 1269, 1269, 1269,
+ 1269, 1161, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1163,
+ 296, 295, 294, 1283, 293, 292, 291, 290, 289, 1283,
+ 1283, 1283, 1283, 1283, 1283, 1068, 1291, 1291, 1291, 1291,
+ 1291, 1291, 1291, 1070, 288, 287, 286, 1292, 285, 284,
+ 283, 282, 279, 1292, 1292, 1292, 1292, 1292, 1292, 1293,
+ 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1295, 267, 272,
+ 259, 1296, 258, 1297, 55, 55, 1470, 1296, 1296, 1296,
+
+ 1296, 1296, 1296, 1389, 1390, 1390, 1390, 1390, 1390, 1390,
+ 1728, 55, 55, 55, 257, 55, 55, 55, 256, 1297,
+ 55, 619, 525, 525, 525, 525, 525, 525, 525, 55,
+ 255, 1534, 1576, 55, 55, 55, 1728, 1506, 55, 1318,
+ 1319, 1319, 1319, 1319, 1319, 1319, 1320, 1397, 1410, 1660,
+ 1321, 1507, 1586, 254, 253, 55, 1321, 1321, 1321, 1321,
+ 1321, 1321, 1117, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+ 1323, 55, 55, 55, 1324, 252, 1121, 1507, 251, 250,
+ 1324, 1324, 1324, 1324, 1324, 1324, 247, 1480, 244, 55,
+ 55, 1427, 1428, 1428, 1428, 1428, 1428, 1428, 241, 240,
+
+ 1398, 1411, 1121, 1126, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1325, 1326, 239, 238, 235, 1327, 234, 1130, 233, 232,
+ 231, 1327, 1327, 1327, 1327, 1327, 1327, 1432, 1433, 1433,
+ 1433, 1433, 1433, 1433, 1435, 1436, 1436, 1436, 1436, 1436,
+ 1436, 230, 229, 1130, 1137, 1328, 1328, 1328, 1328, 1328,
+ 1328, 1328, 1329, 228, 227, 226, 1330, 225, 1141, 224,
+ 223, 222, 1330, 1330, 1330, 1330, 1330, 1330, 1441, 1442,
+ 1442, 1442, 1442, 1442, 1442, 1444, 1445, 1445, 1445, 1445,
+ 1445, 1445, 221, 220, 1141, 1149, 1331, 1331, 1331, 1331,
+ 1331, 1331, 1331, 1332, 216, 215, 205, 1333, 204, 1153,
+
+ 203, 200, 199, 1333, 1333, 1333, 1333, 1333, 1333, 1450,
+ 1451, 1451, 1451, 1451, 1451, 1451, 1453, 1454, 1454, 1454,
+ 1454, 1454, 1454, 194, 193, 1153, 1161, 1334, 1334, 1334,
+ 1334, 1334, 1334, 1334, 1335, 192, 191, 190, 1336, 189,
+ 1165, 188, 187, 186, 1336, 1336, 1336, 1336, 1336, 1336,
+ 1459, 1460, 1460, 1460, 1460, 1460, 1460, 1462, 1463, 1463,
+ 1463, 1463, 1463, 1463, 1506, 55, 1165, 1223, 1339, 1339,
+ 1339, 1339, 1339, 1339, 1339, 1225, 185, 181, 1728, 1340,
+ 180, 179, 178, 55, 177, 1340, 1340, 1340, 1340, 1340,
+ 1340, 1117, 1347, 1347, 1347, 1347, 1347, 1347, 1347, 1323,
+
+ 176, 1579, 175, 1348, 1728, 174, 173, 172, 171, 1348,
+ 1348, 1348, 1348, 1348, 1348, 1126, 1354, 1354, 1354, 1354,
+ 1354, 1354, 1354, 1326, 170, 169, 168, 1355, 167, 166,
+ 165, 160, 151, 1355, 1355, 1355, 1355, 1355, 1355, 1137,
+ 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1329, 150, 145,
+ 59, 1363, 47, 45, 1728, 1728, 1728, 1363, 1363, 1363,
+ 1363, 1363, 1363, 1149, 1370, 1370, 1370, 1370, 1370, 1370,
+ 1370, 1332, 1728, 1728, 1728, 1371, 1728, 1728, 1728, 1728,
+ 1728, 1371, 1371, 1371, 1371, 1371, 1371, 1161, 1378, 1378,
+ 1378, 1378, 1378, 1378, 1378, 1335, 1728, 1728, 1728, 1379,
+
+ 1728, 1728, 1728, 1728, 1728, 1379, 1379, 1379, 1379, 1379,
+ 1379, 1293, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1295,
+ 1728, 1728, 1728, 1392, 1728, 1728, 1728, 1728, 1728, 1392,
+ 1392, 1392, 1392, 1392, 1392, 1223, 1412, 1412, 1412, 1412,
+ 1412, 1412, 1412, 1413, 1728, 1728, 1728, 1414, 1728, 1227,
+ 1728, 1728, 1728, 1414, 1414, 1414, 1414, 1414, 1414, 1383,
+ 1383, 1383, 1383, 1383, 1383, 1383, 1500, 1501, 1501, 1501,
+ 1501, 1501, 1501, 1510, 55, 1227, 1117, 1231, 1231, 1231,
+ 1231, 1231, 1231, 1231, 1323, 1728, 1728, 1511, 1232, 1728,
+ 1728, 1728, 55, 1728, 1232, 1232, 1232, 1232, 1232, 1232,
+
+ 1126, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1326, 1728,
+ 1580, 1728, 1242, 1511, 1728, 1728, 1728, 1728, 1242, 1242,
+ 1242, 1242, 1242, 1242, 1137, 1254, 1254, 1254, 1254, 1254,
+ 1254, 1254, 1329, 1728, 1728, 1728, 1255, 1728, 1728, 1728,
+ 1728, 1728, 1255, 1255, 1255, 1255, 1255, 1255, 1149, 1268,
+ 1268, 1268, 1268, 1268, 1268, 1268, 1332, 1728, 1728, 1728,
+ 1269, 1728, 1728, 1728, 1728, 1728, 1269, 1269, 1269, 1269,
+ 1269, 1269, 1161, 1282, 1282, 1282, 1282, 1282, 1282, 1282,
+ 1335, 1728, 1728, 1728, 1283, 1728, 1728, 1728, 1728, 1728,
+ 1283, 1283, 1283, 1283, 1283, 1283, 1223, 1423, 1423, 1423,
+
+ 1423, 1423, 1423, 1423, 1413, 1728, 1728, 1728, 1424, 1728,
+ 1728, 1728, 55, 1728, 1424, 1424, 1424, 1424, 1424, 1424,
+ 1293, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1295, 55,
+ 55, 55, 1473, 1728, 1510, 1728, 1728, 1728, 1473, 1473,
+ 1473, 1473, 1473, 1473, 1487, 55, 1728, 55, 1728, 55,
+ 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1728, 1484, 1728,
+ 1728, 1488, 1514, 55, 1485, 1223, 1339, 1339, 1339, 1339,
+ 1339, 1339, 1339, 1413, 1728, 1548, 1515, 1340, 1728, 1728,
+ 1728, 1728, 1514, 1340, 1340, 1340, 1340, 1340, 1340, 1442,
+ 1442, 1442, 1442, 1442, 1442, 1442, 1728, 1518, 1518, 1728,
+
+ 1728, 1728, 1515, 1451, 1451, 1451, 1451, 1451, 1451, 1451,
+ 1522, 1519, 1728, 1460, 1460, 1460, 1460, 1460, 1460, 1460,
+ 1522, 1728, 1728, 1728, 1523, 1526, 1527, 1527, 1527, 1527,
+ 1527, 1527, 1728, 55, 1728, 55, 55, 1519, 1728, 1529,
+ 1530, 1530, 1530, 1530, 1530, 1530, 55, 55, 55, 1728,
+ 1523, 55, 55, 55, 55, 1551, 1728, 1551, 55, 55,
+ 1728, 55, 1538, 1539, 55, 55, 55, 1543, 1728, 1552,
+ 55, 1728, 1728, 1540, 1541, 1542, 55, 55, 1728, 55,
+ 1728, 1545, 1553, 1554, 1554, 1554, 1554, 1554, 1554, 1728,
+ 1728, 1728, 1728, 1622, 1582, 1552, 1587, 1728, 1557, 1558,
+
+ 1558, 1558, 1558, 1558, 1558, 1561, 1562, 1562, 1562, 1562,
+ 1562, 1562, 1565, 1566, 1566, 1566, 1566, 1566, 1566, 1569,
+ 1570, 1570, 1570, 1570, 1570, 1570, 1527, 1527, 1527, 1527,
+ 1527, 1527, 1527, 1573, 1573, 55, 55, 55, 1589, 1590,
+ 1590, 1590, 1590, 1590, 1590, 1728, 1728, 1574, 1728, 1728,
+ 1728, 1728, 1728, 55, 55, 55, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1578, 1585, 1588, 1554, 1554, 1554, 1554, 1554,
+ 1554, 1554, 1728, 1574, 1728, 1558, 1558, 1558, 1558, 1558,
+ 1558, 1558, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1566,
+ 1566, 1566, 1566, 1566, 1566, 1566, 1570, 1570, 1570, 1570,
+
+ 1570, 1570, 1570, 1598, 1599, 1599, 1599, 1599, 1599, 1599,
+ 55, 55, 1728, 55, 55, 55, 55, 55, 1590, 1590,
+ 1590, 1590, 1590, 1590, 1590, 55, 55, 1728, 55, 55,
+ 1605, 55, 55, 55, 55, 55, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1611, 55, 55, 1601, 55, 1606, 55, 55,
+ 1607, 1608, 1609, 1612, 1599, 1599, 1599, 1599, 1599, 1599,
+ 1599, 55, 1620, 1628, 55, 55, 55, 55, 55, 55,
+ 1728, 55, 55, 1621, 55, 55, 55, 55, 1728, 55,
+ 1623, 1625, 55, 55, 1728, 1728, 55, 55, 1629, 55,
+ 55, 55, 55, 55, 55, 55, 1647, 1630, 1637, 1728,
+
+ 55, 55, 1638, 1645, 55, 1633, 1641, 1639, 1728, 55,
+ 55, 1640, 55, 1648, 1649, 55, 1650, 1651, 1728, 55,
+ 55, 1728, 55, 55, 55, 55, 1652, 1728, 55, 1728,
+ 55, 55, 55, 55, 1728, 55, 1653, 55, 55, 1654,
+ 1728, 55, 55, 55, 1658, 1656, 1666, 1665, 1728, 55,
+ 55, 55, 1664, 55, 1670, 55, 1675, 55, 1667, 1668,
+ 1677, 55, 55, 55, 55, 1728, 1671, 55, 1673, 55,
+ 1674, 55, 55, 1676, 1728, 55, 55, 1728, 55, 55,
+ 55, 55, 55, 1678, 1728, 55, 55, 1728, 1682, 55,
+ 55, 55, 1683, 1728, 55, 1679, 55, 1685, 1684, 1688,
+
+ 55, 1728, 1689, 55, 55, 1691, 55, 55, 1728, 55,
+ 1695, 1692, 55, 55, 55, 55, 1728, 1728, 55, 1696,
+ 1697, 55, 55, 1728, 55, 55, 1701, 55, 55, 1699,
+ 55, 55, 55, 55, 1704, 1702, 55, 55, 55, 1728,
+ 55, 1706, 1709, 1703, 1705, 55, 55, 55, 55, 55,
+ 55, 1728, 1707, 1728, 55, 55, 55, 1711, 1728, 1728,
+ 1728, 1728, 1728, 1716, 1712, 55, 55, 55, 55, 1728,
+ 1728, 1728, 1713, 1728, 1718, 1721, 1722, 55, 1728, 1728,
+ 1726, 1727, 1728, 1720, 1728, 1724, 1728, 1725, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 55, 46, 1728, 1728, 1728,
+
+ 1728, 46, 46, 46, 64, 1728, 64, 64, 64, 64,
+ 64, 64, 64, 152, 1728, 152, 159, 159, 159, 271,
+ 271, 271, 280, 280, 280, 359, 359, 359, 362, 362,
+ 362, 363, 363, 363, 370, 370, 370, 368, 368, 368,
+ 374, 374, 374, 378, 1728, 378, 443, 443, 443, 448,
+ 448, 448, 449, 449, 449, 458, 458, 458, 462, 1728,
+ 462, 463, 463, 463, 372, 372, 1728, 1728, 372, 467,
+ 467, 467, 471, 471, 471, 362, 362, 362, 532, 532,
+ 532, 536, 536, 536, 537, 537, 537, 538, 538, 538,
+ 370, 370, 370, 543, 543, 543, 456, 456, 1728, 1728,
+
+ 456, 548, 548, 548, 552, 552, 552, 556, 1728, 556,
+ 557, 557, 557, 561, 561, 561, 565, 1728, 565, 624,
+ 624, 624, 458, 458, 458, 632, 632, 632, 633, 633,
+ 633, 641, 641, 641, 645, 1728, 645, 648, 1728, 648,
+ 649, 649, 649, 653, 653, 653, 657, 1728, 657, 555,
+ 555, 1728, 1728, 555, 559, 559, 1728, 1728, 559, 663,
+ 663, 663, 667, 667, 667, 565, 565, 1728, 565, 537,
+ 537, 537, 713, 713, 713, 717, 717, 717, 720, 720,
+ 720, 721, 721, 721, 722, 722, 722, 727, 727, 727,
+ 639, 639, 1728, 1728, 639, 732, 732, 732, 736, 736,
+
+ 736, 645, 645, 1728, 645, 647, 647, 1728, 1728, 647,
+ 648, 648, 1728, 648, 649, 649, 651, 651, 1728, 1728,
+ 651, 743, 743, 743, 747, 747, 747, 657, 657, 1728,
+ 657, 751, 1728, 751, 754, 1728, 754, 755, 755, 755,
+ 759, 759, 759, 763, 1728, 763, 802, 802, 802, 641,
+ 641, 641, 653, 653, 653, 813, 813, 813, 814, 814,
+ 814, 822, 822, 822, 826, 1728, 826, 829, 1728, 829,
+ 830, 830, 830, 834, 834, 834, 838, 1728, 838, 841,
+ 1728, 841, 844, 1728, 844, 845, 845, 845, 849, 849,
+ 849, 853, 1728, 853, 750, 1728, 1728, 750, 751, 751,
+
+ 1728, 751, 753, 753, 1728, 1728, 753, 754, 754, 1728,
+ 754, 755, 755, 757, 757, 1728, 1728, 757, 860, 860,
+ 860, 864, 864, 864, 763, 763, 1728, 763, 53, 53,
+ 53, 1728, 53, 53, 721, 721, 721, 896, 896, 896,
+ 900, 900, 900, 903, 903, 903, 906, 906, 906, 907,
+ 907, 907, 908, 908, 908, 913, 913, 913, 820, 820,
+ 1728, 1728, 820, 918, 918, 918, 922, 922, 922, 826,
+ 826, 1728, 826, 828, 828, 1728, 1728, 828, 829, 829,
+ 1728, 829, 830, 830, 832, 832, 1728, 1728, 832, 929,
+ 929, 929, 933, 933, 933, 838, 838, 1728, 838, 840,
+
+ 1728, 1728, 840, 841, 841, 1728, 841, 843, 843, 1728,
+ 1728, 843, 844, 844, 1728, 844, 845, 845, 847, 847,
+ 1728, 1728, 847, 941, 941, 941, 945, 945, 945, 853,
+ 853, 1728, 853, 947, 1728, 947, 950, 1728, 950, 953,
+ 1728, 953, 954, 954, 954, 958, 958, 958, 962, 1728,
+ 962, 53, 53, 53, 1728, 53, 53, 990, 990, 990,
+ 822, 822, 822, 834, 834, 834, 849, 849, 849, 1004,
+ 1004, 1004, 1005, 1005, 1005, 1013, 1013, 1013, 1017, 1728,
+ 1017, 1020, 1728, 1020, 1021, 1021, 1021, 1025, 1025, 1025,
+ 1029, 1728, 1029, 1032, 1728, 1032, 1035, 1728, 1035, 1036,
+
+ 1036, 1036, 1040, 1040, 1040, 1044, 1728, 1044, 1045, 1728,
+ 1045, 1048, 1728, 1048, 1051, 1728, 1051, 1052, 1052, 1052,
+ 1056, 1056, 1056, 1060, 1728, 1060, 947, 1728, 947, 949,
+ 1728, 1728, 949, 950, 950, 1728, 950, 952, 952, 1728,
+ 1728, 952, 953, 953, 1728, 953, 954, 954, 956, 956,
+ 1728, 1728, 956, 1067, 1067, 1067, 1071, 1071, 1071, 962,
+ 962, 1728, 962, 53, 53, 53, 1728, 53, 53, 907,
+ 907, 907, 1098, 1098, 1098, 1102, 1102, 1102, 1105, 1105,
+ 1105, 1108, 1108, 1108, 1111, 1111, 1111, 1112, 1112, 1112,
+ 1120, 1120, 1120, 1011, 1011, 1728, 1728, 1011, 1125, 1125,
+
+ 1125, 1129, 1129, 1129, 1017, 1017, 1728, 1017, 1019, 1019,
+ 1728, 1728, 1019, 1020, 1020, 1728, 1020, 1021, 1021, 1023,
+ 1023, 1728, 1728, 1023, 1136, 1136, 1136, 1140, 1140, 1140,
+ 1029, 1029, 1728, 1029, 1031, 1728, 1728, 1031, 1032, 1032,
+ 1728, 1032, 1034, 1034, 1728, 1728, 1034, 1035, 1035, 1728,
+ 1035, 1036, 1036, 1038, 1038, 1728, 1728, 1038, 1148, 1148,
+ 1148, 1152, 1152, 1152, 1044, 1044, 1728, 1044, 1045, 1728,
+ 1045, 1047, 1728, 1728, 1047, 1048, 1048, 1728, 1048, 1050,
+ 1050, 1728, 1728, 1050, 1051, 1051, 1728, 1051, 1052, 1052,
+ 1054, 1054, 1728, 1728, 1054, 1160, 1160, 1160, 1164, 1164,
+
+ 1164, 1060, 1060, 1728, 1060, 1166, 1728, 1166, 1169, 1728,
+ 1169, 1172, 1728, 1172, 1173, 1173, 1173, 1177, 1177, 1177,
+ 1181, 1728, 1181, 53, 53, 53, 1728, 53, 53, 1205,
+ 1205, 1205, 1013, 1013, 1013, 1025, 1025, 1025, 1040, 1040,
+ 1040, 1056, 1056, 1056, 1222, 1222, 1222, 1228, 1228, 1228,
+ 1226, 1226, 1226, 1233, 1233, 1233, 1232, 1232, 1232, 1234,
+ 1728, 1234, 1237, 1728, 1237, 1238, 1238, 1238, 1243, 1243,
+ 1243, 1242, 1242, 1242, 1244, 1728, 1244, 1247, 1728, 1247,
+ 1250, 1728, 1250, 1251, 1251, 1251, 1256, 1256, 1256, 1255,
+ 1255, 1255, 1257, 1728, 1257, 1258, 1728, 1258, 1261, 1728,
+
+ 1261, 1264, 1728, 1264, 1265, 1265, 1265, 1270, 1270, 1270,
+ 1269, 1269, 1269, 1271, 1728, 1271, 1272, 1728, 1272, 1275,
+ 1728, 1275, 1278, 1728, 1278, 1279, 1279, 1279, 1284, 1284,
+ 1284, 1283, 1283, 1283, 1285, 1728, 1285, 1166, 1728, 1166,
+ 1168, 1728, 1728, 1168, 1169, 1169, 1728, 1169, 1171, 1171,
+ 1728, 1728, 1171, 1172, 1172, 1728, 1172, 1173, 1173, 1175,
+ 1175, 1728, 1728, 1175, 1292, 1292, 1292, 1296, 1296, 1296,
+ 1181, 1181, 1728, 1181, 53, 53, 53, 1728, 53, 53,
+ 1112, 1112, 1112, 1324, 1324, 1324, 1327, 1327, 1327, 1330,
+ 1330, 1330, 1333, 1333, 1333, 1336, 1336, 1336, 1341, 1341,
+
+ 1341, 1340, 1340, 1340, 1343, 1728, 1343, 1344, 1344, 1344,
+ 1230, 1230, 1728, 1728, 1230, 1348, 1348, 1348, 1349, 1349,
+ 1349, 1234, 1234, 1728, 1234, 1236, 1236, 1728, 1728, 1236,
+ 1237, 1237, 1728, 1237, 1238, 1238, 1240, 1240, 1728, 1728,
+ 1240, 1355, 1355, 1355, 1356, 1356, 1356, 1244, 1244, 1728,
+ 1244, 1246, 1728, 1728, 1246, 1247, 1247, 1728, 1247, 1249,
+ 1249, 1728, 1728, 1249, 1250, 1250, 1728, 1250, 1251, 1251,
+ 1253, 1253, 1728, 1728, 1253, 1363, 1363, 1363, 1364, 1364,
+ 1364, 1257, 1257, 1728, 1257, 1258, 1728, 1258, 1260, 1728,
+ 1728, 1260, 1261, 1261, 1728, 1261, 1263, 1263, 1728, 1728,
+
+ 1263, 1264, 1264, 1728, 1264, 1265, 1265, 1267, 1267, 1728,
+ 1728, 1267, 1371, 1371, 1371, 1372, 1372, 1372, 1271, 1271,
+ 1728, 1271, 1272, 1728, 1272, 1274, 1728, 1728, 1274, 1275,
+ 1275, 1728, 1275, 1277, 1277, 1728, 1728, 1277, 1278, 1278,
+ 1728, 1278, 1279, 1279, 1281, 1281, 1728, 1728, 1281, 1379,
+ 1379, 1379, 1380, 1380, 1380, 1285, 1285, 1728, 1285, 1381,
+ 1728, 1381, 1384, 1728, 1384, 1387, 1728, 1387, 1388, 1388,
+ 1388, 1393, 1728, 1393, 1392, 1392, 1392, 1394, 1728, 1394,
+ 53, 53, 53, 1728, 53, 53, 1415, 1728, 1415, 1414,
+ 1414, 1414, 1416, 1728, 1416, 1232, 1232, 1232, 1417, 1728,
+
+ 1417, 1242, 1242, 1242, 1418, 1728, 1418, 1255, 1255, 1255,
+ 1419, 1728, 1419, 1269, 1269, 1269, 1420, 1728, 1420, 1283,
+ 1283, 1283, 1338, 1338, 1728, 1728, 1338, 1424, 1424, 1424,
+ 1425, 1425, 1425, 370, 370, 370, 1343, 1343, 1728, 1343,
+ 1426, 1426, 1426, 1429, 1728, 1429, 1430, 1430, 1430, 1431,
+ 1431, 1431, 1434, 1728, 1434, 1437, 1728, 1437, 1438, 1438,
+ 1438, 1439, 1439, 1439, 1440, 1728, 1440, 1443, 1728, 1443,
+ 1446, 1728, 1446, 1447, 1447, 1447, 1448, 1448, 1448, 1449,
+ 1728, 1449, 1452, 1728, 1452, 1455, 1728, 1455, 1456, 1456,
+ 1456, 1457, 1457, 1457, 1458, 1728, 1458, 1461, 1728, 1461,
+
+ 1464, 1728, 1464, 1465, 1465, 1465, 1466, 1466, 1466, 1381,
+ 1728, 1381, 1383, 1728, 1728, 1383, 1384, 1384, 1728, 1384,
+ 1386, 1386, 1728, 1728, 1386, 1387, 1387, 1728, 1387, 1388,
+ 1388, 1390, 1390, 1728, 1728, 1390, 1473, 1473, 1473, 1474,
+ 1728, 1474, 1394, 1394, 1728, 1394, 53, 53, 53, 1728,
+ 53, 53, 1492, 1492, 1492, 1340, 1340, 1340, 1494, 1728,
+ 1494, 1495, 1728, 1495, 1496, 1728, 1496, 1497, 1728, 1497,
+ 1498, 1728, 1498, 1499, 1728, 1499, 1502, 1728, 1502, 1503,
+ 1503, 1503, 1504, 1504, 1504, 1505, 1728, 1505, 1428, 1428,
+ 1728, 1728, 1428, 1429, 1429, 1728, 1429, 1430, 1430, 1508,
+
+ 1728, 1508, 1433, 1728, 1728, 1433, 1434, 1434, 1728, 1434,
+ 1436, 1436, 1728, 1728, 1436, 1437, 1437, 1728, 1437, 1438,
+ 1438, 1512, 1728, 1512, 1440, 1728, 1440, 1442, 1728, 1728,
+ 1442, 1443, 1443, 1728, 1443, 1445, 1445, 1728, 1728, 1445,
+ 1446, 1446, 1728, 1446, 1447, 1447, 1516, 1728, 1516, 1449,
+ 1728, 1449, 1451, 1728, 1728, 1451, 1452, 1452, 1728, 1452,
+ 1454, 1454, 1728, 1728, 1454, 1455, 1455, 1728, 1455, 1456,
+ 1456, 1520, 1728, 1520, 1458, 1728, 1458, 1460, 1728, 1728,
+ 1460, 1461, 1461, 1728, 1461, 1463, 1463, 1728, 1728, 1463,
+ 1464, 1464, 1728, 1464, 1465, 1465, 1524, 1728, 1524, 1525,
+
+ 1728, 1525, 1528, 1728, 1528, 1531, 1728, 1531, 1532, 1532,
+ 1532, 1533, 1728, 1533, 53, 53, 53, 1728, 53, 53,
+ 1550, 1728, 1550, 1426, 1728, 1426, 1431, 1728, 1431, 1439,
+ 1728, 1439, 1448, 1728, 1448, 1457, 1728, 1457, 1466, 1728,
+ 1466, 1501, 1501, 1728, 1728, 1501, 1502, 1502, 1728, 1502,
+ 1503, 1503, 1493, 1728, 1493, 1555, 1728, 1555, 1556, 1728,
+ 1556, 1559, 1728, 1559, 1560, 1728, 1560, 1563, 1728, 1563,
+ 1564, 1728, 1564, 1567, 1728, 1567, 1568, 1728, 1568, 1571,
+ 1728, 1571, 1527, 1728, 1728, 1527, 1530, 1530, 1728, 1728,
+ 1530, 1575, 1728, 1575, 1504, 1728, 1504, 1591, 1728, 1591,
+
+ 1554, 1728, 1728, 1554, 1558, 1728, 1728, 1558, 1562, 1728,
+ 1728, 1562, 1566, 1728, 1728, 1566, 1570, 1728, 1728, 1570,
+ 1597, 1728, 1597, 1600, 1728, 1600, 1590, 1728, 1728, 1590,
+ 1614, 1728, 1614, 1615, 1728, 1615, 1616, 1728, 1616, 1617,
+ 1728, 1617, 1618, 1728, 1618, 1599, 1728, 1728, 1599, 1631,
+ 1728, 1631, 1632, 1728, 1632, 3, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728
} ;
-static yyconst flex_int16_t yy_chk[7474] =
+static yyconst flex_int16_t yy_chk[7910] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -1851,819 +1991,867 @@ static yyconst flex_int16_t yy_chk[7474] =
7, 106, 7, 7, 9, 17, 17, 9, 138, 9,
9, 4, 19, 19, 24, 7, 27, 27, 138, 4,
15, 10, 9, 7, 10, 102, 10, 10, 24, 28,
- 9, 34, 26, 1240, 28, 24, 26, 653, 94, 10,
+ 9, 34, 26, 1278, 28, 24, 26, 586, 94, 10,
- 34, 94, 26, 653, 95, 26, 95, 10, 14, 14,
+ 34, 94, 26, 586, 95, 26, 95, 10, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 102, 98,
- 1244, 14, 14, 14, 98, 83, 14, 14, 14, 14,
+ 1279, 14, 14, 14, 98, 83, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 16, 83, 25, 16, 1245, 16, 16, 83, 129,
- 29, 1246, 107, 25, 29, 252, 25, 107, 22, 16,
+ 14, 16, 83, 25, 16, 671, 16, 16, 83, 129,
+ 29, 671, 107, 25, 29, 252, 25, 107, 22, 16,
25, 22, 129, 22, 22, 103, 29, 16, 20, 20,
20, 20, 20, 20, 20, 20, 22, 134, 23, 252,
- 23, 23, 20, 655, 22, 23, 655, 251, 35, 251,
+ 23, 23, 20, 673, 22, 23, 673, 251, 35, 251,
23, 30, 103, 30, 23, 134, 23, 103, 30, 30,
- 35, 30, 35, 1247, 35, 30, 1248, 35, 20, 21,
+ 35, 30, 35, 1283, 35, 30, 1284, 35, 20, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 32,
- 32, 110, 21, 657, 110, 1252, 110, 136, 21, 21,
+ 32, 110, 21, 675, 110, 1285, 110, 136, 21, 21,
21, 21, 21, 21, 31, 32, 136, 31, 31, 32,
- 31, 657, 31, 32, 31, 32, 31, 33, 36, 31,
- 155, 33, 32, 36, 36, 37, 36, 36, 1253, 37,
+ 31, 675, 31, 32, 31, 32, 31, 33, 36, 31,
+ 155, 33, 32, 36, 36, 37, 36, 36, 710, 37,
33, 33, 163, 38, 33, 222, 33, 37, 39, 38,
39, 38, 37, 38, 37, 41, 155, 38, 222, 38,
- 38, 267, 267, 41, 39, 435, 435, 41, 163, 41,
+ 38, 267, 267, 41, 39, 437, 437, 41, 163, 41,
- 44, 39, 660, 44, 660, 44, 44, 62, 62, 62,
+ 44, 39, 397, 44, 710, 44, 44, 62, 62, 62,
62, 62, 62, 62, 274, 339, 63, 351, 44, 63,
- 339, 63, 63, 410, 1259, 413, 44, 48, 48, 48,
- 48, 48, 48, 48, 63, 1260, 410, 661, 48, 413,
- 274, 661, 63, 351, 48, 48, 48, 48, 48, 48,
- 49, 49, 49, 49, 49, 49, 49, 376, 437, 1267,
- 444, 49, 284, 284, 284, 284, 1268, 49, 49, 49,
+ 339, 63, 63, 397, 410, 1292, 44, 48, 48, 48,
+ 48, 48, 48, 48, 63, 619, 619, 410, 48, 397,
+ 274, 680, 63, 351, 48, 48, 48, 48, 48, 48,
+ 49, 49, 49, 49, 49, 49, 49, 376, 439, 680,
+ 446, 49, 284, 284, 284, 284, 1296, 49, 49, 49,
49, 49, 49, 50, 50, 50, 50, 50, 50, 50,
- 50, 464, 284, 376, 437, 50, 444, 450, 458, 464,
- 1275, 50, 50, 50, 50, 50, 50, 52, 52, 52,
+ 50, 466, 284, 376, 439, 50, 446, 452, 460, 466,
+ 1321, 50, 50, 50, 50, 50, 50, 52, 52, 52,
52, 52, 52, 52, 52, 54, 54, 54, 54, 54,
- 54, 54, 484, 450, 458, 355, 54, 559, 559, 559,
- 559, 484, 54, 54, 54, 54, 54, 54, 56, 355,
- 1276, 56, 1283, 56, 56, 601, 601, 371, 372, 56,
- 56, 56, 56, 56, 56, 56, 56, 516, 556, 1284,
- 56, 371, 372, 1288, 56, 355, 56, 56, 56, 56,
- 56, 56, 153, 486, 153, 153, 153, 153, 153, 153,
- 153, 540, 486, 516, 556, 153, 609, 371, 372, 540,
- 1291, 153, 153, 153, 153, 153, 153, 154, 154, 154,
- 154, 154, 154, 154, 154, 550, 644, 652, 652, 154,
-
- 612, 154, 609, 550, 644, 154, 154, 154, 154, 154,
+ 54, 54, 486, 452, 460, 355, 54, 1324, 413, 670,
+ 670, 486, 54, 54, 54, 54, 54, 54, 56, 355,
+ 672, 56, 413, 56, 56, 672, 1327, 371, 372, 56,
+ 56, 56, 56, 56, 56, 56, 56, 523, 563, 679,
+ 56, 371, 372, 679, 56, 355, 56, 56, 56, 56,
+ 56, 56, 153, 488, 153, 153, 153, 153, 153, 153,
+ 153, 547, 488, 523, 563, 153, 627, 371, 372, 547,
+ 686, 153, 153, 153, 153, 153, 153, 154, 154, 154,
+ 154, 154, 154, 154, 154, 557, 662, 686, 1330, 154,
+
+ 630, 154, 627, 557, 662, 154, 154, 154, 154, 154,
154, 266, 266, 266, 266, 266, 266, 266, 277, 277,
- 277, 277, 277, 277, 277, 453, 612, 154, 156, 156,
- 156, 156, 156, 156, 156, 156, 618, 625, 654, 453,
- 156, 637, 678, 654, 671, 671, 156, 156, 156, 156,
+ 277, 277, 277, 277, 277, 455, 630, 154, 156, 156,
+ 156, 156, 156, 156, 156, 156, 587, 636, 1333, 455,
+ 156, 566, 566, 566, 566, 587, 156, 156, 156, 156,
156, 156, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 680, 618, 625, 157, 453, 1292, 637, 678, 1296,
+ 157, 684, 1336, 636, 157, 455, 643, 655, 684, 1340,
157, 157, 157, 157, 157, 157, 158, 158, 158, 158,
158, 158, 158, 158, 160, 160, 160, 160, 160, 160,
- 160, 160, 701, 1298, 719, 160, 731, 680, 662, 734,
-
- 701, 160, 160, 160, 160, 160, 160, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 662, 734, 1304, 162,
- 719, 162, 731, 309, 736, 162, 162, 162, 162, 162,
- 162, 309, 361, 361, 361, 361, 361, 361, 361, 1305,
- 748, 454, 736, 520, 309, 737, 658, 162, 260, 260,
- 260, 260, 260, 260, 260, 454, 658, 520, 748, 260,
- 309, 735, 1315, 737, 1316, 260, 260, 260, 260, 260,
- 260, 262, 262, 262, 262, 262, 262, 262, 656, 735,
- 737, 454, 262, 520, 763, 766, 735, 656, 262, 262,
+ 160, 160, 643, 655, 678, 160, 678, 682, 1341, 682,
+
+ 1342, 160, 160, 160, 160, 160, 160, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 687, 691, 691, 162,
+ 1343, 162, 1344, 309, 687, 162, 162, 162, 162, 162,
+ 162, 309, 361, 361, 361, 361, 361, 361, 361, 701,
+ 701, 456, 1348, 527, 309, 764, 676, 162, 260, 260,
+ 260, 260, 260, 260, 260, 456, 676, 527, 708, 260,
+ 309, 1349, 766, 764, 689, 260, 260, 260, 260, 260,
+ 260, 262, 262, 262, 262, 262, 262, 262, 588, 689,
+ 766, 456, 262, 527, 708, 749, 761, 588, 262, 262,
262, 262, 262, 262, 263, 263, 263, 263, 263, 263,
- 263, 263, 265, 265, 265, 265, 265, 265, 265, 712,
- 763, 766, 1320, 265, 769, 742, 746, 712, 743, 265,
+ 263, 263, 265, 265, 265, 265, 265, 265, 265, 674,
+ 805, 749, 761, 265, 1355, 1356, 1363, 772, 674, 265,
265, 265, 265, 265, 265, 268, 268, 268, 268, 268,
- 268, 268, 268, 742, 746, 746, 743, 268, 742, 743,
- 769, 1321, 1325, 268, 268, 268, 268, 268, 268, 270,
+ 268, 268, 268, 731, 742, 772, 805, 268, 1364, 1371,
+ 772, 731, 742, 268, 268, 268, 268, 268, 268, 270,
270, 270, 270, 270, 270, 270, 270, 273, 273, 273,
- 273, 273, 273, 273, 273, 273, 817, 344, 547, 273,
- 1328, 273, 344, 1329, 817, 273, 273, 273, 273, 273,
- 273, 344, 547, 344, 344, 775, 344, 365, 365, 365,
- 365, 365, 365, 365, 749, 548, 738, 273, 278, 278,
-
- 278, 278, 278, 278, 278, 278, 278, 1334, 547, 548,
- 278, 775, 749, 1337, 738, 551, 278, 278, 278, 278,
- 278, 278, 279, 279, 279, 279, 279, 279, 279, 551,
- 1338, 738, 1343, 279, 1346, 548, 744, 1347, 747, 279,
- 279, 279, 279, 279, 279, 349, 552, 349, 349, 349,
- 349, 349, 349, 349, 744, 551, 747, 744, 349, 747,
- 552, 753, 755, 755, 349, 349, 349, 349, 349, 349,
- 350, 350, 350, 350, 350, 350, 350, 350, 1352, 753,
- 755, 1355, 350, 1356, 350, 1364, 552, 1380, 350, 350,
- 350, 350, 350, 350, 434, 434, 434, 434, 434, 434,
-
- 434, 462, 462, 462, 462, 462, 462, 462, 620, 670,
- 350, 352, 352, 352, 352, 352, 352, 352, 352, 670,
- 1381, 782, 620, 352, 794, 797, 824, 836, 621, 352,
+ 273, 273, 273, 273, 273, 273, 859, 1372, 1379, 273,
+ 1380, 273, 1384, 1387, 859, 273, 273, 273, 273, 273,
+ 273, 365, 365, 365, 365, 365, 365, 365, 436, 436,
+ 436, 436, 436, 436, 436, 554, 683, 273, 278, 278,
+
+ 278, 278, 278, 278, 278, 278, 278, 683, 1388, 554,
+ 278, 1392, 765, 779, 1394, 681, 278, 278, 278, 278,
+ 278, 278, 279, 279, 279, 279, 279, 279, 279, 681,
+ 765, 779, 685, 279, 555, 554, 779, 765, 1413, 279,
+ 279, 279, 279, 279, 279, 344, 685, 344, 555, 344,
+ 344, 464, 464, 464, 464, 464, 464, 464, 773, 344,
+ 690, 344, 344, 558, 344, 349, 559, 349, 349, 349,
+ 349, 349, 349, 349, 555, 690, 773, 558, 349, 773,
+ 559, 776, 1414, 787, 349, 349, 349, 349, 349, 349,
+ 350, 350, 350, 350, 350, 350, 350, 350, 1424, 776,
+
+ 776, 787, 350, 558, 350, 1425, 559, 1429, 350, 350,
+ 350, 350, 350, 350, 468, 468, 468, 468, 468, 468,
+ 468, 540, 540, 540, 540, 540, 540, 540, 638, 688,
+ 350, 352, 352, 352, 352, 352, 352, 352, 352, 688,
+ 1430, 1434, 638, 352, 1437, 783, 774, 788, 639, 352,
352, 352, 352, 352, 352, 356, 356, 356, 356, 356,
- 356, 356, 621, 809, 824, 836, 356, 782, 620, 825,
- 794, 797, 356, 356, 356, 356, 356, 356, 357, 357,
- 357, 357, 357, 357, 357, 357, 865, 825, 621, 809,
- 357, 840, 825, 896, 865, 1406, 357, 357, 357, 357,
- 357, 357, 358, 358, 358, 358, 358, 358, 358, 358,
- 360, 360, 360, 360, 360, 360, 360, 840, 876, 896,
+ 356, 356, 639, 783, 774, 788, 356, 774, 638, 784,
+ 783, 790, 356, 356, 356, 356, 356, 356, 357, 357,
+ 357, 357, 357, 357, 357, 357, 1438, 784, 639, 790,
+ 357, 808, 784, 811, 817, 1443, 357, 357, 357, 357,
- 1409, 360, 1420, 826, 827, 829, 876, 360, 360, 360,
+ 357, 357, 358, 358, 358, 358, 358, 358, 358, 358,
+ 360, 360, 360, 360, 360, 360, 360, 808, 917, 811,
+ 817, 360, 1446, 791, 789, 795, 917, 360, 360, 360,
360, 360, 360, 364, 364, 364, 364, 364, 364, 364,
- 364, 826, 827, 829, 364, 1424, 826, 827, 829, 831,
+ 364, 791, 789, 795, 364, 789, 824, 797, 797, 1447,
364, 364, 364, 364, 364, 364, 366, 366, 366, 366,
- 366, 366, 366, 366, 366, 888, 1428, 831, 366, 908,
- 832, 834, 831, 888, 366, 366, 366, 366, 366, 366,
- 367, 367, 367, 367, 367, 367, 367, 367, 832, 834,
- 931, 367, 834, 832, 920, 908, 915, 367, 367, 367,
+ 366, 366, 366, 366, 366, 797, 836, 839, 366, 851,
+ 866, 867, 824, 1452, 366, 366, 366, 366, 366, 366,
+ 367, 367, 367, 367, 367, 367, 367, 367, 866, 867,
+ 892, 367, 836, 839, 867, 851, 868, 367, 367, 367,
+
367, 367, 367, 373, 373, 373, 373, 373, 373, 373,
- 373, 373, 920, 1432, 915, 373, 931, 915, 921, 918,
-
- 920, 373, 373, 373, 373, 373, 373, 375, 375, 375,
- 375, 375, 375, 375, 375, 375, 921, 918, 1436, 375,
- 934, 375, 918, 937, 940, 375, 375, 375, 375, 375,
- 375, 466, 466, 466, 466, 466, 466, 466, 533, 533,
- 533, 533, 533, 533, 533, 1444, 934, 375, 396, 937,
- 940, 1453, 396, 946, 922, 396, 923, 628, 396, 629,
- 396, 396, 396, 396, 428, 428, 428, 428, 428, 428,
- 428, 628, 922, 629, 923, 428, 953, 927, 1014, 946,
- 663, 428, 428, 428, 428, 428, 428, 430, 430, 430,
- 430, 430, 430, 430, 663, 927, 1014, 628, 430, 629,
-
- 965, 968, 953, 1237, 430, 430, 430, 430, 430, 430,
- 431, 431, 431, 431, 431, 431, 431, 431, 433, 433,
- 433, 433, 433, 433, 433, 980, 965, 968, 984, 433,
- 996, 1234, 1022, 1231, 1114, 433, 433, 433, 433, 433,
- 433, 436, 436, 436, 436, 436, 436, 436, 436, 1004,
- 1022, 980, 1114, 436, 984, 436, 996, 1004, 1228, 436,
- 436, 436, 436, 436, 436, 538, 538, 538, 538, 538,
- 538, 538, 542, 542, 542, 542, 542, 542, 542, 739,
- 632, 436, 438, 438, 438, 438, 438, 438, 438, 1042,
- 1225, 1212, 1095, 438, 632, 1017, 1208, 739, 666, 438,
-
- 438, 438, 438, 438, 438, 439, 439, 439, 439, 439,
- 439, 439, 666, 1017, 739, 1042, 439, 1017, 1095, 1201,
- 632, 1107, 439, 439, 439, 439, 439, 439, 440, 440,
- 440, 440, 440, 440, 440, 440, 443, 443, 443, 443,
- 443, 443, 443, 443, 443, 1052, 633, 1107, 443, 1200,
- 443, 1199, 1195, 1052, 443, 443, 443, 443, 443, 443,
- 633, 640, 640, 640, 640, 640, 640, 640, 642, 642,
- 642, 642, 642, 642, 642, 1118, 443, 449, 449, 449,
- 449, 449, 449, 449, 449, 449, 633, 1194, 1191, 449,
- 1187, 449, 1186, 1118, 669, 449, 449, 449, 449, 449,
-
- 449, 646, 646, 646, 646, 646, 646, 646, 669, 694,
- 694, 694, 694, 694, 694, 694, 741, 449, 455, 455,
- 455, 455, 455, 455, 455, 455, 455, 1185, 1181, 1124,
- 455, 1180, 1127, 1130, 741, 1020, 455, 455, 455, 455,
- 455, 455, 457, 457, 457, 457, 457, 457, 457, 457,
- 457, 741, 1177, 1020, 457, 1124, 457, 1020, 1127, 1130,
- 457, 457, 457, 457, 457, 457, 699, 699, 699, 699,
- 699, 699, 699, 703, 703, 703, 703, 703, 703, 703,
- 722, 830, 457, 467, 467, 467, 467, 467, 467, 467,
- 467, 467, 1173, 1133, 722, 467, 1136, 1172, 1171, 830,
-
- 723, 467, 467, 467, 467, 467, 467, 468, 468, 468,
- 468, 468, 468, 468, 723, 1063, 830, 1167, 468, 1133,
- 722, 1021, 1136, 1063, 468, 468, 468, 468, 468, 468,
- 514, 726, 514, 514, 514, 514, 514, 514, 514, 1021,
- 723, 1166, 1163, 514, 1021, 726, 1160, 1117, 1113, 514,
- 514, 514, 514, 514, 514, 515, 515, 515, 515, 515,
- 515, 515, 515, 1159, 1075, 1117, 1113, 515, 1113, 515,
- 1117, 726, 1075, 515, 515, 515, 515, 515, 515, 708,
- 708, 708, 708, 708, 708, 708, 710, 710, 710, 710,
- 710, 710, 710, 727, 835, 515, 517, 517, 517, 517,
-
- 517, 517, 517, 517, 1161, 1087, 1158, 727, 517, 1175,
- 1189, 1154, 835, 1087, 517, 517, 517, 517, 517, 517,
- 521, 521, 521, 521, 521, 521, 521, 521, 1153, 1207,
- 1161, 835, 521, 727, 1223, 1175, 1189, 1207, 521, 521,
- 521, 521, 521, 521, 522, 522, 522, 522, 522, 522,
- 522, 522, 523, 523, 523, 523, 523, 523, 523, 1251,
- 1223, 1150, 1149, 523, 1286, 1323, 1332, 1251, 1148, 523,
- 523, 523, 523, 523, 523, 524, 524, 524, 524, 524,
- 524, 524, 524, 526, 526, 526, 526, 526, 526, 526,
- 1286, 1323, 1332, 1341, 526, 1350, 1404, 1110, 1111, 1214,
-
- 526, 526, 526, 526, 526, 526, 527, 527, 527, 527,
- 527, 527, 527, 527, 527, 1110, 1111, 1214, 527, 1341,
- 1112, 1350, 1404, 777, 527, 527, 527, 527, 527, 527,
- 528, 528, 528, 528, 528, 528, 528, 777, 1112, 1110,
- 1111, 528, 1144, 1215, 1142, 1141, 1138, 528, 528, 528,
- 528, 528, 528, 532, 532, 532, 532, 532, 532, 532,
- 532, 1215, 1112, 777, 532, 1137, 1134, 1216, 1217, 1115,
- 532, 532, 532, 532, 532, 532, 534, 534, 534, 534,
- 534, 534, 534, 534, 534, 1216, 1217, 1115, 534, 1131,
- 1128, 1218, 1300, 1125, 534, 534, 534, 534, 534, 534,
-
- 535, 535, 535, 535, 535, 535, 535, 535, 1115, 1218,
- 1300, 535, 1121, 1300, 1218, 1301, 1369, 535, 535, 535,
- 535, 535, 535, 543, 543, 543, 543, 543, 543, 543,
- 543, 543, 1258, 1301, 1369, 543, 1301, 1109, 1302, 1412,
- 1258, 543, 543, 543, 543, 543, 543, 544, 544, 544,
- 544, 544, 544, 544, 544, 1266, 1302, 1412, 544, 1418,
- 1108, 1105, 1101, 1266, 544, 544, 544, 544, 544, 544,
- 553, 553, 553, 553, 553, 553, 553, 553, 553, 1274,
- 1302, 1422, 553, 1426, 1430, 1418, 1414, 1274, 553, 553,
- 553, 553, 553, 553, 555, 555, 555, 555, 555, 555,
-
- 555, 555, 555, 1282, 1414, 1100, 555, 1422, 555, 1426,
- 1430, 1282, 555, 555, 555, 555, 555, 555, 714, 714,
- 714, 714, 714, 714, 714, 720, 720, 720, 720, 720,
- 720, 720, 828, 778, 555, 595, 595, 595, 595, 595,
- 595, 595, 1434, 1314, 1442, 1451, 595, 778, 1097, 1441,
- 828, 1314, 595, 595, 595, 595, 595, 595, 597, 597,
- 597, 597, 597, 597, 597, 828, 1363, 1441, 1434, 597,
- 1442, 1451, 1092, 778, 1363, 597, 597, 597, 597, 597,
- 597, 598, 598, 598, 598, 598, 598, 598, 598, 600,
- 600, 600, 600, 600, 600, 600, 1410, 1091, 1088, 1080,
-
- 600, 1079, 1219, 1076, 1410, 1068, 600, 600, 600, 600,
- 600, 600, 602, 602, 602, 602, 602, 602, 602, 602,
- 1219, 1067, 1064, 1057, 602, 1056, 1053, 1048, 1047, 1219,
- 602, 602, 602, 602, 602, 602, 603, 603, 603, 603,
- 603, 603, 603, 603, 604, 604, 604, 604, 604, 604,
- 604, 1044, 1043, 1040, 1039, 604, 1036, 1033, 1030, 1026,
- 1009, 604, 604, 604, 604, 604, 604, 605, 605, 605,
- 605, 605, 605, 605, 605, 608, 608, 608, 608, 608,
- 608, 608, 608, 608, 740, 785, 786, 608, 1005, 608,
- 998, 997, 789, 608, 608, 608, 608, 608, 608, 785,
-
- 786, 994, 740, 990, 989, 986, 789, 982, 981, 750,
- 978, 745, 974, 751, 740, 608, 611, 611, 611, 611,
- 611, 611, 611, 611, 611, 785, 786, 750, 611, 745,
- 611, 751, 789, 1016, 611, 611, 611, 611, 611, 611,
- 750, 745, 973, 751, 757, 757, 757, 757, 757, 757,
- 757, 1016, 790, 800, 801, 914, 611, 617, 617, 617,
- 617, 617, 617, 617, 617, 617, 790, 800, 801, 617,
- 1016, 617, 970, 914, 804, 617, 617, 617, 617, 617,
- 617, 798, 798, 798, 798, 798, 798, 798, 804, 1368,
- 914, 967, 790, 800, 801, 805, 966, 617, 622, 622,
-
- 622, 622, 622, 622, 622, 622, 622, 1368, 963, 805,
- 622, 959, 958, 955, 804, 1368, 622, 622, 622, 622,
- 622, 622, 624, 624, 624, 624, 624, 624, 624, 624,
- 624, 954, 951, 947, 624, 805, 624, 943, 942, 941,
- 624, 624, 624, 624, 624, 624, 813, 813, 813, 813,
- 813, 813, 813, 815, 815, 815, 815, 815, 815, 815,
- 899, 916, 624, 634, 634, 634, 634, 634, 634, 634,
- 634, 634, 938, 935, 899, 634, 932, 929, 928, 916,
- 916, 634, 634, 634, 634, 634, 634, 636, 636, 636,
- 636, 636, 636, 636, 636, 636, 910, 916, 909, 636,
-
- 899, 636, 906, 1019, 833, 636, 636, 636, 636, 636,
- 636, 819, 819, 819, 819, 819, 819, 819, 902, 901,
- 898, 1019, 833, 893, 900, 903, 917, 636, 647, 647,
- 647, 647, 647, 647, 647, 647, 647, 833, 900, 903,
- 647, 1019, 889, 881, 917, 904, 647, 647, 647, 647,
- 647, 647, 648, 648, 648, 648, 648, 648, 648, 904,
- 917, 877, 870, 648, 900, 903, 866, 861, 856, 648,
- 648, 648, 648, 648, 648, 651, 651, 651, 651, 651,
- 651, 651, 855, 854, 851, 904, 651, 911, 912, 913,
- 919, 1299, 651, 651, 651, 651, 651, 651, 858, 858,
-
- 858, 858, 858, 858, 858, 911, 912, 913, 919, 1299,
- 651, 674, 848, 674, 674, 674, 674, 674, 674, 674,
- 911, 912, 913, 913, 674, 919, 1299, 1015, 1018, 1119,
- 674, 674, 674, 674, 674, 674, 863, 863, 863, 863,
- 863, 863, 863, 948, 949, 1015, 1018, 1119, 674, 675,
- 675, 675, 675, 675, 675, 675, 675, 948, 949, 1015,
- 1018, 675, 1119, 844, 822, 818, 811, 675, 675, 675,
- 675, 675, 675, 867, 867, 867, 867, 867, 867, 867,
- 810, 807, 803, 948, 949, 675, 676, 676, 676, 676,
- 676, 676, 676, 872, 872, 872, 872, 872, 872, 872,
-
- 874, 874, 874, 874, 874, 874, 874, 878, 878, 878,
- 878, 878, 878, 878, 884, 884, 884, 884, 884, 884,
- 884, 676, 677, 677, 677, 677, 677, 677, 677, 802,
- 799, 796, 795, 677, 792, 788, 787, 784, 783, 677,
- 677, 677, 677, 677, 677, 679, 679, 679, 679, 679,
- 679, 679, 679, 681, 681, 681, 681, 681, 681, 681,
- 681, 780, 776, 773, 772, 681, 771, 770, 767, 764,
- 761, 681, 681, 681, 681, 681, 681, 682, 682, 682,
- 682, 682, 682, 682, 682, 684, 684, 684, 684, 684,
- 684, 684, 760, 733, 732, 729, 684, 725, 724, 721,
-
- 717, 713, 684, 684, 684, 684, 684, 684, 685, 685,
- 685, 685, 685, 685, 685, 685, 685, 706, 702, 697,
- 685, 692, 691, 690, 687, 956, 685, 685, 685, 685,
- 685, 685, 686, 686, 686, 686, 686, 686, 686, 956,
- 683, 673, 672, 686, 668, 667, 665, 664, 659, 686,
- 686, 686, 686, 686, 686, 688, 688, 688, 688, 688,
- 688, 688, 688, 688, 649, 956, 645, 688, 639, 638,
- 635, 631, 957, 688, 688, 688, 688, 688, 688, 689,
- 689, 689, 689, 689, 689, 689, 957, 630, 627, 626,
- 689, 623, 619, 616, 615, 614, 689, 689, 689, 689,
-
- 689, 689, 693, 693, 693, 693, 693, 693, 693, 693,
- 613, 610, 957, 693, 607, 606, 599, 596, 594, 693,
- 693, 693, 693, 693, 693, 695, 695, 695, 695, 695,
- 695, 695, 695, 695, 590, 586, 585, 695, 584, 583,
- 579, 578, 576, 695, 695, 695, 695, 695, 695, 696,
- 696, 696, 696, 696, 696, 696, 696, 575, 574, 573,
- 696, 572, 571, 570, 569, 568, 696, 696, 696, 696,
- 696, 696, 704, 704, 704, 704, 704, 704, 704, 704,
- 704, 567, 566, 565, 704, 562, 561, 560, 558, 557,
- 704, 704, 704, 704, 704, 704, 705, 705, 705, 705,
-
- 705, 705, 705, 705, 554, 549, 545, 705, 541, 536,
- 531, 530, 529, 705, 705, 705, 705, 705, 705, 715,
- 715, 715, 715, 715, 715, 715, 715, 715, 525, 519,
- 518, 715, 513, 512, 511, 510, 509, 715, 715, 715,
- 715, 715, 715, 716, 716, 716, 716, 716, 716, 716,
- 716, 508, 507, 506, 716, 505, 504, 503, 501, 498,
- 716, 716, 716, 716, 716, 716, 728, 728, 728, 728,
- 728, 728, 728, 728, 728, 497, 496, 495, 728, 494,
- 493, 492, 490, 489, 728, 728, 728, 728, 728, 728,
- 730, 730, 730, 730, 730, 730, 730, 730, 730, 488,
-
- 487, 485, 730, 483, 730, 482, 481, 480, 730, 730,
- 730, 730, 730, 730, 886, 886, 886, 886, 886, 886,
- 886, 890, 890, 890, 890, 890, 890, 890, 960, 961,
- 730, 752, 971, 752, 752, 752, 752, 752, 752, 752,
- 479, 477, 960, 961, 752, 476, 971, 474, 473, 752,
- 752, 752, 752, 752, 752, 752, 754, 754, 754, 754,
- 754, 754, 754, 472, 469, 465, 461, 754, 960, 961,
- 460, 459, 971, 754, 754, 754, 754, 754, 754, 756,
- 756, 756, 756, 756, 756, 756, 456, 452, 451, 448,
- 756, 447, 1367, 446, 445, 442, 756, 756, 756, 756,
-
- 756, 756, 758, 758, 758, 758, 758, 758, 758, 758,
- 1367, 441, 432, 429, 758, 427, 426, 425, 424, 1367,
- 758, 758, 758, 758, 758, 758, 759, 759, 759, 759,
- 759, 759, 759, 759, 762, 762, 762, 762, 762, 762,
- 762, 762, 762, 423, 422, 421, 762, 420, 762, 419,
- 418, 417, 762, 762, 762, 762, 762, 762, 897, 897,
- 897, 897, 897, 897, 897, 969, 969, 969, 969, 969,
- 969, 969, 972, 416, 762, 765, 765, 765, 765, 765,
- 765, 765, 765, 765, 414, 975, 972, 765, 412, 765,
- 411, 976, 987, 765, 765, 765, 765, 765, 765, 975,
-
- 409, 408, 405, 404, 402, 976, 987, 400, 399, 398,
- 393, 1366, 972, 988, 392, 765, 768, 768, 768, 768,
- 768, 768, 768, 768, 768, 975, 391, 988, 768, 1366,
- 768, 976, 987, 991, 768, 768, 768, 768, 768, 768,
- 985, 985, 985, 985, 985, 985, 985, 991, 1366, 389,
- 388, 387, 992, 988, 1098, 386, 768, 774, 774, 774,
- 774, 774, 774, 774, 774, 774, 992, 384, 1098, 774,
- 379, 774, 378, 991, 1099, 774, 774, 774, 774, 774,
- 774, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1099, 377,
- 374, 370, 992, 1102, 1098, 1103, 368, 774, 779, 779,
-
- 779, 779, 779, 779, 779, 779, 779, 1102, 363, 1103,
- 779, 362, 359, 354, 1099, 353, 779, 779, 779, 779,
- 779, 779, 781, 781, 781, 781, 781, 781, 781, 781,
- 781, 345, 343, 1102, 781, 1103, 781, 342, 337, 335,
- 781, 781, 781, 781, 781, 781, 1002, 1002, 1002, 1002,
- 1002, 1002, 1002, 1006, 1006, 1006, 1006, 1006, 1006, 1006,
- 1145, 333, 781, 791, 791, 791, 791, 791, 791, 791,
- 791, 791, 332, 331, 1145, 791, 330, 329, 328, 327,
- 325, 791, 791, 791, 791, 791, 791, 793, 793, 793,
- 793, 793, 793, 793, 793, 793, 1011, 1012, 1146, 793,
-
- 1145, 793, 324, 323, 318, 793, 793, 793, 793, 793,
- 793, 315, 1146, 314, 1011, 1012, 1045, 1045, 1045, 1045,
- 1045, 1045, 1045, 1151, 313, 1011, 1012, 793, 806, 806,
- 806, 806, 806, 806, 806, 806, 806, 1151, 1146, 310,
- 806, 303, 302, 300, 299, 298, 806, 806, 806, 806,
- 806, 806, 808, 808, 808, 808, 808, 808, 808, 808,
- 808, 1013, 1152, 1151, 808, 296, 808, 294, 293, 1413,
- 808, 808, 808, 808, 808, 808, 1152, 292, 290, 1013,
- 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1413, 286, 1155,
- 1013, 285, 808, 820, 820, 820, 820, 820, 820, 820,
-
- 820, 820, 1152, 1155, 283, 820, 1413, 280, 276, 275,
- 1156, 820, 820, 820, 820, 820, 820, 821, 821, 821,
- 821, 821, 821, 821, 1156, 272, 271, 269, 821, 1155,
- 264, 261, 259, 258, 821, 821, 821, 821, 821, 821,
- 837, 1164, 837, 837, 837, 837, 837, 837, 837, 256,
- 1156, 253, 249, 837, 245, 1164, 243, 241, 837, 837,
- 837, 837, 837, 837, 837, 838, 838, 838, 838, 838,
- 838, 838, 240, 238, 237, 236, 838, 235, 234, 233,
- 232, 1164, 838, 838, 838, 838, 838, 838, 839, 839,
- 839, 839, 839, 839, 839, 839, 230, 228, 226, 225,
-
- 839, 223, 839, 221, 220, 218, 839, 839, 839, 839,
- 839, 839, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1059,
- 1059, 1059, 1059, 1059, 1059, 1059, 215, 1165, 839, 841,
- 841, 841, 841, 841, 841, 841, 214, 213, 211, 209,
- 841, 1165, 208, 205, 204, 202, 841, 841, 841, 841,
- 841, 841, 842, 842, 842, 842, 842, 842, 842, 842,
- 201, 200, 199, 198, 842, 197, 196, 1165, 195, 194,
- 842, 842, 842, 842, 842, 842, 843, 843, 843, 843,
- 843, 843, 843, 843, 845, 845, 845, 845, 845, 845,
- 845, 193, 192, 191, 190, 845, 189, 188, 187, 186,
-
- 185, 845, 845, 845, 845, 845, 845, 846, 846, 846,
- 846, 846, 846, 846, 846, 846, 183, 182, 179, 846,
- 178, 177, 176, 175, 1168, 846, 846, 846, 846, 846,
- 846, 847, 847, 847, 847, 847, 847, 847, 1168, 174,
- 173, 172, 847, 170, 167, 166, 165, 164, 847, 847,
- 847, 847, 847, 847, 849, 849, 849, 849, 849, 849,
- 849, 849, 849, 161, 1168, 159, 849, 150, 149, 148,
- 147, 1169, 849, 849, 849, 849, 849, 849, 850, 850,
- 850, 850, 850, 850, 850, 1169, 146, 145, 144, 850,
- 142, 140, 139, 137, 135, 850, 850, 850, 850, 850,
-
- 850, 852, 852, 852, 852, 852, 852, 852, 852, 852,
- 133, 1169, 132, 852, 131, 130, 128, 127, 1178, 852,
- 852, 852, 852, 852, 852, 853, 853, 853, 853, 853,
- 853, 853, 1178, 126, 125, 124, 853, 123, 121, 119,
- 118, 117, 853, 853, 853, 853, 853, 853, 857, 857,
- 857, 857, 857, 857, 857, 857, 116, 115, 1178, 857,
- 114, 113, 112, 111, 109, 857, 857, 857, 857, 857,
- 857, 859, 859, 859, 859, 859, 859, 859, 859, 859,
- 108, 101, 100, 859, 99, 97, 96, 93, 92, 859,
- 859, 859, 859, 859, 859, 860, 860, 860, 860, 860,
-
- 860, 860, 860, 91, 90, 89, 860, 88, 87, 86,
- 85, 84, 860, 860, 860, 860, 860, 860, 868, 868,
- 868, 868, 868, 868, 868, 868, 868, 82, 81, 80,
- 868, 79, 78, 77, 76, 75, 868, 868, 868, 868,
- 868, 868, 869, 869, 869, 869, 869, 869, 869, 869,
- 74, 73, 72, 869, 71, 70, 69, 67, 66, 869,
- 869, 869, 869, 869, 869, 879, 879, 879, 879, 879,
- 879, 879, 879, 879, 65, 51, 43, 879, 42, 40,
- 18, 11, 8, 879, 879, 879, 879, 879, 879, 880,
- 880, 880, 880, 880, 880, 880, 880, 3, 0, 0,
-
- 880, 0, 0, 0, 0, 0, 880, 880, 880, 880,
- 880, 880, 891, 891, 891, 891, 891, 891, 891, 891,
- 891, 0, 0, 0, 891, 0, 0, 0, 0, 0,
- 891, 891, 891, 891, 891, 891, 892, 892, 892, 892,
- 892, 892, 892, 892, 0, 0, 0, 892, 0, 0,
- 0, 0, 0, 892, 892, 892, 892, 892, 892, 905,
- 905, 905, 905, 905, 905, 905, 905, 905, 0, 0,
- 0, 905, 0, 0, 0, 0, 0, 905, 905, 905,
- 905, 905, 905, 907, 907, 907, 907, 907, 907, 907,
- 907, 907, 0, 0, 0, 907, 0, 907, 0, 0,
-
- 0, 907, 907, 907, 907, 907, 907, 1061, 1061, 1061,
- 1061, 1061, 1061, 1061, 1065, 1065, 1065, 1065, 1065, 1065,
- 1065, 0, 0, 907, 924, 924, 924, 924, 924, 924,
- 924, 924, 924, 0, 0, 0, 0, 924, 0, 0,
- 0, 0, 924, 924, 924, 924, 924, 924, 924, 925,
- 925, 925, 925, 925, 925, 925, 925, 926, 926, 926,
- 926, 926, 926, 926, 926, 926, 1071, 1071, 1071, 1071,
- 1071, 1071, 1071, 0, 0, 926, 930, 930, 930, 930,
- 930, 930, 930, 930, 930, 0, 0, 0, 930, 0,
- 930, 0, 0, 0, 930, 930, 930, 930, 930, 930,
-
- 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1077, 1077, 1077,
- 1077, 1077, 1077, 1077, 0, 0, 930, 933, 933, 933,
- 933, 933, 933, 933, 933, 933, 0, 0, 0, 933,
- 0, 933, 0, 0, 0, 933, 933, 933, 933, 933,
- 933, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1085, 1085,
- 1085, 1085, 1085, 1085, 1085, 0, 0, 933, 936, 936,
- 936, 936, 936, 936, 936, 936, 936, 0, 0, 0,
- 936, 0, 936, 0, 0, 0, 936, 936, 936, 936,
- 936, 936, 1089, 1089, 1089, 1089, 1089, 1089, 1089, 1096,
- 1096, 1096, 1096, 1096, 1096, 1096, 1116, 0, 936, 939,
-
- 939, 939, 939, 939, 939, 939, 939, 939, 0, 1179,
- 1182, 939, 0, 939, 1116, 0, 0, 939, 939, 939,
- 939, 939, 939, 1179, 1182, 1116, 1139, 1139, 1139, 1139,
- 1139, 1139, 1139, 0, 1183, 0, 0, 0, 1192, 939,
- 944, 944, 944, 944, 944, 944, 944, 944, 1183, 1179,
- 1182, 944, 1192, 0, 0, 0, 0, 944, 944, 944,
- 944, 944, 944, 945, 945, 945, 945, 945, 945, 945,
- 945, 945, 0, 0, 1183, 945, 0, 945, 1192, 0,
- 0, 945, 945, 945, 945, 945, 945, 1162, 1162, 1162,
- 1162, 1162, 1162, 1162, 1176, 1176, 1176, 1176, 1176, 1176,
-
- 1176, 1193, 0, 945, 950, 950, 950, 950, 950, 950,
- 950, 950, 950, 0, 0, 1193, 950, 0, 0, 0,
- 0, 0, 950, 950, 950, 950, 950, 950, 952, 952,
- 952, 952, 952, 952, 952, 952, 952, 0, 0, 0,
- 952, 1193, 952, 0, 0, 1196, 952, 952, 952, 952,
- 952, 952, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1196,
- 0, 0, 0, 0, 1197, 0, 1241, 0, 952, 962,
- 962, 962, 962, 962, 962, 962, 962, 962, 1197, 0,
- 1241, 962, 0, 0, 0, 1196, 0, 962, 962, 962,
- 962, 962, 962, 964, 964, 964, 964, 964, 964, 964,
-
- 964, 964, 0, 0, 1197, 964, 1241, 964, 0, 0,
- 0, 964, 964, 964, 964, 964, 964, 1203, 1203, 1203,
- 1203, 1203, 1203, 1203, 1205, 1205, 1205, 1205, 1205, 1205,
- 1205, 1242, 0, 964, 977, 977, 977, 977, 977, 977,
- 977, 977, 977, 0, 0, 1242, 977, 0, 0, 0,
- 0, 0, 977, 977, 977, 977, 977, 977, 979, 979,
- 979, 979, 979, 979, 979, 979, 979, 0, 0, 0,
- 979, 1242, 979, 0, 0, 0, 979, 979, 979, 979,
- 979, 979, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1249,
- 1249, 1249, 1249, 1249, 1249, 1249, 1289, 0, 979, 993,
-
- 993, 993, 993, 993, 993, 993, 993, 993, 0, 0,
- 1289, 993, 0, 0, 0, 0, 1220, 993, 993, 993,
- 993, 993, 993, 995, 995, 995, 995, 995, 995, 995,
- 995, 995, 1221, 0, 1220, 995, 1289, 995, 0, 0,
- 0, 995, 995, 995, 995, 995, 995, 1220, 0, 0,
- 1221, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 0, 0,
- 1290, 1221, 0, 995, 1007, 1007, 1007, 1007, 1007, 1007,
- 1007, 1007, 1007, 0, 1290, 0, 1007, 0, 0, 0,
- 0, 1293, 1007, 1007, 1007, 1007, 1007, 1007, 1008, 1008,
- 1008, 1008, 1008, 1008, 1008, 1293, 0, 0, 0, 1008,
-
- 1290, 0, 0, 0, 0, 1008, 1008, 1008, 1008, 1008,
- 1008, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023,
- 0, 1293, 0, 0, 1023, 0, 0, 0, 0, 1023,
- 1023, 1023, 1023, 1023, 1023, 1023, 1024, 1024, 1024, 1024,
- 1024, 1024, 1024, 1024, 1025, 1025, 1025, 1025, 1025, 1025,
- 1025, 1025, 1025, 1256, 1256, 1256, 1256, 1256, 1256, 1256,
- 0, 1294, 1025, 1027, 1027, 1027, 1027, 1027, 1027, 1027,
- 0, 0, 0, 0, 1027, 1294, 0, 0, 0, 0,
- 1027, 1027, 1027, 1027, 1027, 1027, 1028, 1028, 1028, 1028,
- 1028, 1028, 1028, 1028, 1028, 0, 0, 0, 1028, 0,
-
- 0, 1294, 0, 1318, 1028, 1028, 1028, 1028, 1028, 1028,
- 1029, 1029, 1029, 1029, 1029, 1029, 1029, 1318, 0, 0,
- 0, 1029, 0, 0, 0, 0, 0, 1029, 1029, 1029,
- 1029, 1029, 1029, 1031, 1031, 1031, 1031, 1031, 1031, 1031,
- 1031, 1031, 0, 1318, 0, 1031, 0, 0, 0, 0,
- 1319, 1031, 1031, 1031, 1031, 1031, 1031, 1032, 1032, 1032,
- 1032, 1032, 1032, 1032, 1319, 0, 0, 0, 1032, 0,
- 0, 0, 0, 0, 1032, 1032, 1032, 1032, 1032, 1032,
- 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 0,
- 1319, 0, 1034, 0, 0, 0, 0, 1326, 1034, 1034,
-
- 1034, 1034, 1034, 1034, 1035, 1035, 1035, 1035, 1035, 1035,
- 1035, 1326, 0, 0, 0, 1035, 0, 0, 0, 0,
- 0, 1035, 1035, 1035, 1035, 1035, 1035, 1037, 1037, 1037,
- 1037, 1037, 1037, 1037, 1037, 1037, 0, 1326, 0, 1037,
- 0, 0, 0, 0, 1327, 1037, 1037, 1037, 1037, 1037,
- 1037, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1327, 0,
- 0, 0, 1038, 0, 0, 0, 0, 0, 1038, 1038,
- 1038, 1038, 1038, 1038, 1041, 1041, 1041, 1041, 1041, 1041,
- 1041, 1041, 1041, 0, 1327, 0, 1041, 0, 1041, 0,
- 0, 0, 1041, 1041, 1041, 1041, 1041, 1041, 1262, 1262,
-
- 1262, 1262, 1262, 1262, 1262, 1264, 1264, 1264, 1264, 1264,
- 1264, 1264, 1335, 0, 1041, 1046, 1046, 1046, 1046, 1046,
- 1046, 1046, 1046, 1046, 0, 0, 1335, 1046, 0, 0,
- 0, 0, 0, 1046, 1046, 1046, 1046, 1046, 1046, 1055,
- 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 0, 0,
- 0, 1055, 1335, 0, 0, 0, 0, 1055, 1055, 1055,
- 1055, 1055, 1055, 1066, 1066, 1066, 1066, 1066, 1066, 1066,
- 1066, 1066, 0, 0, 0, 1066, 0, 0, 0, 0,
- 0, 1066, 1066, 1066, 1066, 1066, 1066, 1078, 1078, 1078,
- 1078, 1078, 1078, 1078, 1078, 1078, 0, 0, 0, 1078,
-
- 0, 0, 0, 0, 0, 1078, 1078, 1078, 1078, 1078,
- 1078, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090,
- 0, 0, 0, 1090, 0, 0, 0, 0, 0, 1090,
- 1090, 1090, 1090, 1090, 1090, 1104, 1104, 1104, 1104, 1104,
- 1104, 1104, 1104, 1104, 0, 0, 0, 1104, 0, 0,
- 0, 0, 0, 1104, 1104, 1104, 1104, 1104, 1104, 1106,
- 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 0, 0,
- 0, 1106, 0, 1106, 0, 0, 0, 1106, 1106, 1106,
- 1106, 1106, 1106, 1270, 1270, 1270, 1270, 1270, 1270, 1270,
- 1272, 1272, 1272, 1272, 1272, 1272, 1272, 0, 0, 1106,
-
- 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1278,
- 1278, 1278, 1278, 1278, 1278, 1278, 0, 1336, 1120, 1122,
- 1122, 1122, 1122, 1122, 1122, 1122, 1122, 0, 0, 0,
- 1122, 1336, 0, 0, 0, 0, 1122, 1122, 1122, 1122,
- 1122, 1122, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- 1123, 0, 0, 0, 1123, 0, 1123, 1336, 0, 0,
- 1123, 1123, 1123, 1123, 1123, 1123, 1280, 1280, 1280, 1280,
- 1280, 1280, 1280, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
- 0, 0, 1123, 1126, 1126, 1126, 1126, 1126, 1126, 1126,
- 1126, 1126, 0, 0, 0, 1126, 0, 1126, 0, 0,
-
- 0, 1126, 1126, 1126, 1126, 1126, 1126, 1312, 1312, 1312,
- 1312, 1312, 1312, 1312, 1324, 1324, 1324, 1324, 1324, 1324,
- 1324, 0, 0, 1126, 1129, 1129, 1129, 1129, 1129, 1129,
- 1129, 1129, 1129, 0, 0, 0, 1129, 0, 1129, 0,
- 0, 0, 1129, 1129, 1129, 1129, 1129, 1129, 1333, 1333,
- 1333, 1333, 1333, 1333, 1333, 1342, 1342, 1342, 1342, 1342,
- 1342, 1342, 1344, 0, 1129, 1132, 1132, 1132, 1132, 1132,
- 1132, 1132, 1132, 1132, 0, 1345, 1344, 1132, 0, 1132,
- 0, 0, 0, 1132, 1132, 1132, 1132, 1132, 1132, 1345,
- 1351, 1351, 1351, 1351, 1351, 1351, 1351, 0, 0, 0,
-
- 0, 0, 1344, 1353, 0, 1132, 1135, 1135, 1135, 1135,
- 1135, 1135, 1135, 1135, 1135, 1345, 1354, 1353, 1135, 0,
- 1135, 0, 0, 0, 1135, 1135, 1135, 1135, 1135, 1135,
- 1354, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 0, 0,
- 0, 0, 0, 1353, 1378, 0, 1135, 1140, 1140, 1140,
- 1140, 1140, 1140, 1140, 1140, 1140, 1354, 0, 1378, 1140,
- 0, 0, 0, 0, 0, 1140, 1140, 1140, 1140, 1140,
- 1140, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147,
- 0, 0, 0, 1147, 1378, 0, 0, 0, 0, 1147,
- 1147, 1147, 1147, 1147, 1147, 1157, 1157, 1157, 1157, 1157,
-
- 1157, 1157, 1157, 1157, 0, 0, 0, 1157, 0, 0,
- 0, 0, 0, 1157, 1157, 1157, 1157, 1157, 1157, 1170,
- 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 0, 0,
- 0, 1170, 0, 0, 0, 0, 0, 1170, 1170, 1170,
- 1170, 1170, 1170, 1184, 1184, 1184, 1184, 1184, 1184, 1184,
- 1184, 1184, 0, 0, 0, 1184, 0, 0, 0, 0,
- 0, 1184, 1184, 1184, 1184, 1184, 1184, 1198, 1198, 1198,
- 1198, 1198, 1198, 1198, 1198, 1198, 0, 0, 0, 1198,
- 0, 0, 0, 0, 0, 1198, 1198, 1198, 1198, 1198,
- 1198, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1210,
-
- 0, 0, 0, 1210, 0, 0, 0, 0, 0, 1210,
- 1210, 1210, 1210, 1210, 1210, 1222, 1222, 1222, 1222, 1222,
- 1222, 1222, 1222, 1222, 0, 0, 0, 1222, 0, 1222,
- 0, 0, 1379, 1222, 1222, 1222, 1222, 1222, 1222, 1361,
- 1361, 1361, 1361, 1361, 1361, 1361, 1379, 1384, 1384, 1384,
- 1384, 1384, 1384, 1384, 0, 1222, 1226, 1226, 1226, 1226,
- 1226, 1226, 1226, 1226, 1226, 0, 0, 0, 1226, 0,
- 0, 0, 1379, 0, 1226, 1226, 1226, 1226, 1226, 1226,
- 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 0,
- 0, 0, 1229, 0, 0, 0, 0, 0, 1229, 1229,
-
- 1229, 1229, 1229, 1229, 1232, 1232, 1232, 1232, 1232, 1232,
- 1232, 1232, 1232, 0, 0, 0, 1232, 0, 0, 0,
- 0, 0, 1232, 1232, 1232, 1232, 1232, 1232, 1235, 1235,
- 1235, 1235, 1235, 1235, 1235, 1235, 1235, 0, 0, 0,
- 1235, 0, 0, 0, 0, 0, 1235, 1235, 1235, 1235,
- 1235, 1235, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238,
- 1238, 0, 0, 0, 1238, 0, 0, 0, 0, 0,
- 1238, 1238, 1238, 1238, 1238, 1238, 1243, 1243, 1243, 1243,
- 1243, 1243, 1243, 1243, 1243, 0, 0, 0, 1243, 0,
- 0, 0, 0, 0, 1243, 1243, 1243, 1243, 1243, 1243,
-
- 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 0,
- 0, 0, 1295, 0, 0, 0, 0, 0, 1295, 1295,
- 1295, 1295, 1295, 1295, 1303, 1303, 1303, 1303, 1303, 1303,
- 1303, 1303, 1303, 0, 0, 0, 1303, 0, 0, 0,
- 0, 0, 1303, 1303, 1303, 1303, 1303, 1303, 1388, 1388,
- 1388, 1388, 1388, 1388, 1388, 1392, 1392, 1392, 1392, 1392,
- 1392, 1392, 1396, 1396, 1396, 1396, 1396, 1396, 1396, 1400,
- 1400, 1400, 1400, 1400, 1400, 1400, 1405, 1405, 1405, 1405,
- 1405, 1405, 1405, 1407, 1408, 1416, 1416, 1416, 1416, 1416,
- 1416, 1416, 0, 0, 0, 0, 0, 1407, 1408, 1419,
-
- 1419, 1419, 1419, 1419, 1419, 1419, 1423, 1423, 1423, 1423,
- 1423, 1423, 1423, 1427, 1427, 1427, 1427, 1427, 1427, 1427,
- 0, 0, 0, 1407, 1408, 1431, 1431, 1431, 1431, 1431,
- 1431, 1431, 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1438,
- 1438, 1438, 1438, 1438, 1438, 1438, 1443, 1443, 1443, 1443,
- 1443, 1443, 1443, 1452, 1452, 1452, 1452, 1452, 1452, 1452,
- 1464, 0, 0, 0, 0, 1464, 1464, 1464, 1465, 0,
- 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1466, 0, 1466,
- 1467, 1467, 1467, 1468, 1468, 1468, 1469, 1469, 1469, 1470,
- 1470, 1470, 1471, 1471, 1471, 1472, 1472, 1472, 1473, 1473,
-
- 1473, 1474, 1474, 1474, 1475, 1475, 1475, 1476, 0, 1476,
- 1477, 1477, 1477, 1478, 1478, 1478, 1479, 1479, 1479, 1480,
- 1480, 1480, 1481, 0, 1481, 1482, 1482, 1482, 1483, 1483,
- 0, 0, 1483, 1484, 1484, 1484, 1485, 1485, 1485, 1486,
- 1486, 1486, 1487, 1487, 1487, 1488, 1488, 1488, 1489, 1489,
- 1489, 1490, 1490, 1490, 1491, 1491, 1491, 1492, 1492, 1492,
- 1493, 1493, 0, 0, 1493, 1494, 1494, 1494, 1495, 1495,
- 1495, 1496, 0, 1496, 1497, 1497, 1497, 1498, 1498, 1498,
- 1499, 0, 1499, 1500, 1500, 1500, 1501, 1501, 1501, 1502,
- 1502, 1502, 1503, 1503, 1503, 1504, 1504, 1504, 1505, 0,
-
- 1505, 1506, 0, 1506, 1507, 1507, 1507, 1508, 1508, 1508,
- 1509, 0, 1509, 1510, 1510, 0, 0, 1510, 1511, 1511,
- 0, 0, 1511, 1512, 1512, 1512, 1513, 1513, 1513, 1514,
- 1514, 0, 1514, 1515, 1515, 1515, 1516, 1516, 1516, 1517,
- 1517, 1517, 1518, 1518, 1518, 1519, 1519, 1519, 1520, 1520,
- 1520, 1521, 1521, 1521, 1522, 1522, 0, 0, 1522, 1523,
- 1523, 1523, 1524, 1524, 1524, 1525, 1525, 0, 1525, 1526,
- 1526, 0, 0, 1526, 1527, 1527, 0, 1527, 1528, 1528,
- 1529, 1529, 0, 0, 1529, 1530, 1530, 1530, 1531, 1531,
- 1531, 1532, 1532, 0, 1532, 1533, 0, 1533, 1534, 0,
-
- 1534, 1535, 1535, 1535, 1536, 1536, 1536, 1537, 0, 1537,
- 1538, 1538, 1538, 1539, 1539, 1539, 1540, 1540, 1540, 1541,
- 1541, 1541, 1542, 1542, 1542, 1543, 1543, 1543, 1544, 0,
- 1544, 1545, 0, 1545, 1546, 1546, 1546, 1547, 1547, 1547,
- 1548, 0, 1548, 1549, 0, 1549, 1550, 0, 1550, 1551,
- 1551, 1551, 1552, 1552, 1552, 1553, 0, 1553, 1554, 0,
- 0, 1554, 1555, 1555, 0, 1555, 1556, 1556, 0, 0,
- 1556, 1557, 1557, 0, 1557, 1558, 1558, 1559, 1559, 0,
- 0, 1559, 1560, 1560, 1560, 1561, 1561, 1561, 1562, 1562,
- 0, 1562, 1563, 1563, 1563, 0, 1563, 1563, 1564, 1564,
-
- 1564, 1565, 1565, 1565, 1566, 1566, 1566, 1567, 1567, 1567,
- 1568, 1568, 1568, 1569, 1569, 1569, 1570, 1570, 1570, 1571,
- 1571, 1571, 1572, 1572, 0, 0, 1572, 1573, 1573, 1573,
- 1574, 1574, 1574, 1575, 1575, 0, 1575, 1576, 1576, 0,
- 0, 1576, 1577, 1577, 0, 1577, 1578, 1578, 1579, 1579,
- 0, 0, 1579, 1580, 1580, 1580, 1581, 1581, 1581, 1582,
- 1582, 0, 1582, 1583, 0, 0, 1583, 1584, 1584, 0,
- 1584, 1585, 1585, 0, 0, 1585, 1586, 1586, 0, 1586,
- 1587, 1587, 1588, 1588, 0, 0, 1588, 1589, 1589, 1589,
- 1590, 1590, 1590, 1591, 1591, 0, 1591, 1592, 0, 1592,
-
- 1593, 0, 1593, 1594, 0, 1594, 1595, 1595, 1595, 1596,
- 1596, 1596, 1597, 0, 1597, 1598, 1598, 1598, 0, 1598,
- 1598, 1599, 1599, 1599, 1600, 1600, 1600, 1601, 1601, 1601,
- 1602, 1602, 1602, 1603, 1603, 1603, 1604, 1604, 1604, 1605,
- 1605, 1605, 1606, 0, 1606, 1607, 0, 1607, 1608, 1608,
- 1608, 1609, 1609, 1609, 1610, 0, 1610, 1611, 0, 1611,
- 1612, 0, 1612, 1613, 1613, 1613, 1614, 1614, 1614, 1615,
- 0, 1615, 1616, 0, 1616, 1617, 0, 1617, 1618, 0,
- 1618, 1619, 1619, 1619, 1620, 1620, 1620, 1621, 0, 1621,
- 1622, 0, 1622, 1623, 0, 0, 1623, 1624, 1624, 0,
-
- 1624, 1625, 1625, 0, 0, 1625, 1626, 1626, 0, 1626,
- 1627, 1627, 1628, 1628, 0, 0, 1628, 1629, 1629, 1629,
- 1630, 1630, 1630, 1631, 1631, 0, 1631, 1632, 1632, 1632,
- 0, 1632, 1632, 1633, 1633, 1633, 1634, 1634, 1634, 1635,
- 1635, 1635, 1636, 1636, 1636, 1637, 1637, 1637, 1638, 1638,
- 1638, 1639, 1639, 1639, 1640, 1640, 1640, 1641, 1641, 0,
- 0, 1641, 1642, 1642, 1642, 1643, 1643, 1643, 1644, 1644,
- 0, 1644, 1645, 1645, 0, 0, 1645, 1646, 1646, 0,
- 1646, 1647, 1647, 1648, 1648, 0, 0, 1648, 1649, 1649,
- 1649, 1650, 1650, 1650, 1651, 1651, 0, 1651, 1652, 0,
-
- 0, 1652, 1653, 1653, 0, 1653, 1654, 1654, 0, 0,
- 1654, 1655, 1655, 0, 1655, 1656, 1656, 1657, 1657, 0,
- 0, 1657, 1658, 1658, 1658, 1659, 1659, 1659, 1660, 1660,
- 0, 1660, 1661, 0, 1661, 1662, 0, 0, 1662, 1663,
- 1663, 0, 1663, 1664, 1664, 0, 0, 1664, 1665, 1665,
- 0, 1665, 1666, 1666, 1667, 1667, 0, 0, 1667, 1668,
- 1668, 1668, 1669, 1669, 1669, 1670, 1670, 0, 1670, 1671,
- 0, 1671, 1672, 0, 1672, 1673, 0, 1673, 1674, 1674,
- 1674, 1675, 1675, 1675, 1676, 0, 1676, 1677, 1677, 1677,
- 0, 1677, 1677, 1678, 1678, 1678, 1679, 1679, 1679, 1680,
-
- 1680, 1680, 1681, 1681, 1681, 1682, 1682, 1682, 1683, 1683,
- 1683, 1684, 1684, 1684, 1685, 1685, 1685, 1686, 1686, 1686,
- 1687, 1687, 1687, 1688, 0, 1688, 1689, 0, 1689, 1690,
- 1690, 1690, 1691, 1691, 1691, 1692, 1692, 1692, 1693, 0,
- 1693, 1694, 0, 1694, 1695, 0, 1695, 1696, 1696, 1696,
- 1697, 1697, 1697, 1698, 1698, 1698, 1699, 0, 1699, 1700,
- 0, 1700, 1701, 0, 1701, 1702, 0, 1702, 1703, 1703,
- 1703, 1704, 1704, 1704, 1705, 1705, 1705, 1706, 0, 1706,
- 1707, 0, 1707, 1708, 0, 1708, 1709, 0, 1709, 1710,
- 1710, 1710, 1711, 1711, 1711, 1712, 1712, 1712, 1713, 0,
-
- 1713, 1714, 0, 1714, 1715, 0, 0, 1715, 1716, 1716,
- 0, 1716, 1717, 1717, 0, 0, 1717, 1718, 1718, 0,
- 1718, 1719, 1719, 1720, 1720, 0, 0, 1720, 1721, 1721,
- 1721, 1722, 1722, 1722, 1723, 1723, 0, 1723, 1724, 1724,
- 1724, 0, 1724, 1724, 1725, 1725, 1725, 1726, 1726, 1726,
- 1727, 1727, 1727, 1728, 1728, 1728, 1729, 1729, 1729, 1730,
- 1730, 1730, 1731, 1731, 1731, 1732, 1732, 1732, 1733, 0,
- 1733, 1734, 1734, 1734, 1735, 1735, 0, 0, 1735, 1736,
- 1736, 1736, 1737, 1737, 1737, 1738, 1738, 0, 1738, 1739,
- 1739, 0, 0, 1739, 1740, 1740, 0, 1740, 1741, 1741,
-
- 1742, 1742, 0, 0, 1742, 1743, 1743, 1743, 1744, 1744,
- 1744, 1745, 1745, 0, 1745, 1746, 0, 0, 1746, 1747,
- 1747, 0, 1747, 1748, 1748, 0, 0, 1748, 1749, 1749,
- 0, 1749, 1750, 1750, 1751, 1751, 0, 0, 1751, 1752,
- 1752, 1752, 1753, 1753, 1753, 1754, 1754, 0, 1754, 1755,
- 0, 1755, 1756, 0, 0, 1756, 1757, 1757, 0, 1757,
- 1758, 1758, 0, 0, 1758, 1759, 1759, 0, 1759, 1760,
- 1760, 1761, 1761, 0, 0, 1761, 1762, 1762, 1762, 1763,
- 1763, 1763, 1764, 1764, 0, 1764, 1765, 0, 1765, 1766,
- 0, 0, 1766, 1767, 1767, 0, 1767, 1768, 1768, 0,
-
- 0, 1768, 1769, 1769, 0, 1769, 1770, 1770, 1771, 1771,
- 0, 0, 1771, 1772, 1772, 1772, 1773, 1773, 1773, 1774,
- 1774, 0, 1774, 1775, 0, 1775, 1776, 0, 1776, 1777,
- 0, 1777, 1778, 1778, 1778, 1779, 0, 1779, 1780, 1780,
- 1780, 1781, 0, 1781, 1782, 1782, 1782, 0, 1782, 1782,
- 1783, 0, 1783, 1784, 1784, 1784, 1785, 0, 1785, 1786,
- 1786, 1786, 1787, 0, 1787, 1788, 1788, 1788, 1789, 0,
- 1789, 1790, 1790, 1790, 1791, 0, 1791, 1792, 1792, 1792,
- 1793, 0, 1793, 1794, 1794, 1794, 1795, 1795, 0, 0,
- 1795, 1796, 1796, 1796, 1797, 1797, 1797, 1798, 1798, 1798,
-
- 1799, 1799, 0, 1799, 1800, 1800, 1800, 1801, 0, 1801,
- 1802, 1802, 1802, 1803, 1803, 1803, 1804, 0, 1804, 1805,
- 0, 1805, 1806, 1806, 1806, 1807, 1807, 1807, 1808, 0,
- 1808, 1809, 0, 1809, 1810, 0, 1810, 1811, 1811, 1811,
- 1812, 1812, 1812, 1813, 0, 1813, 1814, 0, 1814, 1815,
- 0, 1815, 1816, 1816, 1816, 1817, 1817, 1817, 1818, 0,
- 1818, 1819, 0, 1819, 1820, 0, 1820, 1821, 1821, 1821,
- 1822, 1822, 1822, 1823, 0, 1823, 1824, 0, 0, 1824,
- 1825, 1825, 0, 1825, 1826, 1826, 0, 0, 1826, 1827,
- 1827, 0, 1827, 1828, 1828, 1829, 1829, 0, 0, 1829,
-
- 1830, 1830, 1830, 1831, 0, 1831, 1832, 1832, 0, 1832,
- 1833, 1833, 1833, 0, 1833, 1833, 1834, 1834, 1834, 1835,
- 1835, 1835, 1836, 0, 1836, 1837, 0, 1837, 1838, 0,
- 1838, 1839, 0, 1839, 1840, 0, 1840, 1841, 0, 1841,
- 1842, 0, 1842, 1843, 1843, 1843, 1844, 1844, 1844, 1845,
- 0, 1845, 1846, 1846, 0, 0, 1846, 1847, 1847, 0,
- 1847, 1848, 1848, 1849, 0, 1849, 1850, 0, 0, 1850,
- 1851, 1851, 0, 1851, 1852, 1852, 0, 0, 1852, 1853,
- 1853, 0, 1853, 1854, 1854, 1855, 0, 1855, 1856, 0,
- 1856, 1857, 0, 0, 1857, 1858, 1858, 0, 1858, 1859,
-
- 1859, 0, 0, 1859, 1860, 1860, 0, 1860, 1861, 1861,
- 1862, 0, 1862, 1863, 0, 1863, 1864, 0, 0, 1864,
- 1865, 1865, 0, 1865, 1866, 1866, 0, 0, 1866, 1867,
- 1867, 0, 1867, 1868, 1868, 1869, 0, 1869, 1870, 0,
- 1870, 1871, 0, 0, 1871, 1872, 1872, 0, 1872, 1873,
- 1873, 0, 0, 1873, 1874, 1874, 0, 1874, 1875, 1875,
- 1876, 0, 1876, 1877, 0, 1877, 1878, 0, 1878, 1879,
- 0, 1879, 1880, 1880, 1880, 1881, 0, 1881, 1882, 1882,
- 1882, 0, 1882, 1882, 1883, 0, 1883, 1884, 0, 1884,
- 1885, 0, 1885, 1886, 0, 1886, 1887, 0, 1887, 1888,
-
- 0, 1888, 1889, 0, 1889, 1890, 1890, 0, 0, 1890,
- 1891, 1891, 0, 1891, 1892, 1892, 1893, 0, 1893, 1894,
- 0, 1894, 1895, 0, 1895, 1896, 0, 1896, 1897, 0,
- 1897, 1898, 0, 1898, 1899, 0, 1899, 1900, 0, 1900,
- 1901, 0, 1901, 1902, 0, 1902, 1903, 0, 0, 1903,
- 1904, 1904, 0, 0, 1904, 1905, 0, 1905, 1906, 0,
- 1906, 1907, 0, 1907, 1908, 0, 0, 1908, 1909, 0,
- 0, 1909, 1910, 0, 0, 1910, 1911, 0, 0, 1911,
- 1912, 0, 0, 1912, 1913, 0, 1913, 1914, 0, 1914,
- 1915, 0, 0, 1915, 1916, 0, 1916, 1917, 0, 1917,
-
- 1918, 0, 1918, 1919, 0, 1919, 1920, 0, 1920, 1921,
- 0, 0, 1921, 1922, 0, 1922, 1923, 0, 1923, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463, 1463,
- 1463, 1463, 1463
+ 373, 373, 1455, 1456, 868, 373, 892, 1461, 879, 868,
+ 869, 373, 373, 373, 373, 373, 373, 375, 375, 375,
+ 375, 375, 375, 375, 375, 375, 879, 879, 869, 375,
+ 692, 375, 1464, 869, 693, 375, 375, 375, 375, 375,
+ 375, 490, 646, 490, 692, 696, 490, 490, 693, 647,
+ 490, 490, 699, 928, 700, 490, 646, 375, 396, 696,
+ 1465, 928, 396, 647, 700, 396, 699, 650, 396, 651,
+ 396, 396, 396, 396, 430, 430, 430, 430, 430, 430,
+ 430, 650, 646, 651, 1473, 430, 780, 871, 873, 647,
+
+ 1502, 430, 430, 430, 430, 430, 430, 432, 432, 432,
+ 432, 432, 432, 432, 780, 871, 873, 650, 432, 651,
+ 871, 873, 948, 780, 432, 432, 432, 432, 432, 432,
+ 433, 433, 433, 433, 433, 433, 433, 433, 435, 435,
+ 435, 435, 435, 435, 435, 1503, 1528, 1531, 948, 435,
+ 1555, 781, 880, 874, 888, 435, 435, 435, 435, 435,
+ 435, 438, 438, 438, 438, 438, 438, 438, 438, 781,
+ 880, 874, 888, 438, 1559, 438, 874, 880, 781, 438,
+ 438, 438, 438, 438, 438, 545, 545, 545, 545, 545,
+ 545, 545, 549, 549, 549, 549, 549, 549, 549, 767,
+
+ 752, 438, 440, 440, 440, 440, 440, 440, 440, 960,
+ 940, 993, 996, 440, 752, 883, 1563, 767, 940, 440,
+ 440, 440, 440, 440, 440, 441, 441, 441, 441, 441,
+ 441, 441, 1567, 883, 767, 960, 441, 993, 996, 999,
+ 752, 883, 441, 441, 441, 441, 441, 441, 442, 442,
+ 442, 442, 442, 442, 442, 442, 445, 445, 445, 445,
+ 445, 445, 445, 445, 445, 999, 1571, 1591, 445, 1002,
+ 445, 1600, 1275, 1271, 445, 445, 445, 445, 445, 445,
+ 658, 658, 658, 658, 658, 658, 658, 660, 660, 660,
+ 660, 660, 660, 660, 973, 1002, 445, 451, 451, 451,
+
+ 451, 451, 451, 451, 451, 451, 1066, 1270, 1269, 451,
+ 1265, 451, 973, 973, 1066, 451, 451, 451, 451, 451,
+ 451, 664, 664, 664, 664, 664, 664, 664, 724, 724,
+ 724, 724, 724, 724, 724, 753, 768, 451, 457, 457,
+ 457, 457, 457, 457, 457, 457, 457, 1264, 1261, 753,
+ 457, 1008, 1257, 1015, 768, 886, 457, 457, 457, 457,
+ 457, 457, 459, 459, 459, 459, 459, 459, 459, 459,
+ 459, 768, 1256, 886, 459, 753, 459, 1008, 886, 1015,
+ 459, 459, 459, 459, 459, 459, 729, 729, 729, 729,
+ 729, 729, 729, 733, 733, 733, 733, 733, 733, 733,
+
+ 756, 769, 459, 469, 469, 469, 469, 469, 469, 469,
+ 469, 469, 1255, 1027, 756, 469, 1251, 975, 1250, 769,
+ 757, 469, 469, 469, 469, 469, 469, 470, 470, 470,
+ 470, 470, 470, 470, 757, 975, 769, 1247, 470, 1027,
+ 756, 785, 975, 876, 470, 470, 470, 470, 470, 470,
+ 521, 819, 521, 521, 521, 521, 521, 521, 521, 785,
+ 757, 876, 1244, 521, 876, 819, 972, 967, 785, 521,
+ 521, 521, 521, 521, 521, 522, 522, 522, 522, 522,
+ 522, 522, 522, 1243, 972, 967, 1242, 522, 967, 522,
+ 1238, 819, 972, 522, 522, 522, 522, 522, 522, 738,
+
+ 738, 738, 738, 738, 738, 738, 740, 740, 740, 740,
+ 740, 740, 740, 771, 777, 522, 524, 524, 524, 524,
+ 524, 524, 524, 524, 1030, 1124, 1237, 1042, 524, 1046,
+ 1058, 771, 777, 1124, 524, 524, 524, 524, 524, 524,
+ 528, 528, 528, 528, 528, 528, 528, 528, 771, 1135,
+ 1030, 777, 528, 1042, 1114, 1046, 1058, 1135, 528, 528,
+ 528, 528, 528, 528, 529, 529, 529, 529, 529, 529,
+ 529, 529, 530, 530, 530, 530, 530, 530, 530, 1147,
+ 1114, 1234, 1233, 530, 1167, 1179, 1208, 1147, 1232, 530,
+ 530, 530, 530, 530, 530, 531, 531, 531, 531, 531,
+
+ 531, 531, 531, 533, 533, 533, 533, 533, 533, 533,
+ 1167, 1179, 1208, 1211, 533, 1228, 1226, 970, 974, 977,
+ 533, 533, 533, 533, 533, 533, 534, 534, 534, 534,
+ 534, 534, 534, 534, 534, 970, 974, 977, 534, 1211,
+ 970, 974, 977, 820, 534, 534, 534, 534, 534, 534,
+ 535, 535, 535, 535, 535, 535, 535, 820, 1159, 1225,
+ 1214, 535, 1222, 976, 978, 1221, 1159, 535, 535, 535,
+ 535, 535, 535, 539, 539, 539, 539, 539, 539, 539,
+ 539, 976, 978, 820, 539, 978, 1214, 979, 981, 976,
+ 539, 539, 539, 539, 539, 539, 541, 541, 541, 541,
+
+ 541, 541, 541, 541, 541, 979, 981, 979, 541, 1218,
+ 983, 981, 984, 1215, 541, 541, 541, 541, 541, 541,
+ 542, 542, 542, 542, 542, 542, 542, 542, 983, 1212,
+ 984, 542, 1209, 1205, 985, 989, 1076, 542, 542, 542,
+ 542, 542, 542, 550, 550, 550, 550, 550, 550, 550,
+ 550, 550, 985, 989, 1076, 550, 1181, 1079, 1082, 1083,
+ 1180, 550, 550, 550, 550, 550, 550, 551, 551, 551,
+ 551, 551, 551, 551, 551, 1079, 1082, 1083, 551, 1079,
+ 1082, 1084, 1083, 1087, 551, 551, 551, 551, 551, 551,
+ 560, 560, 560, 560, 560, 560, 560, 560, 560, 1084,
+
+ 1177, 1087, 560, 1217, 1220, 1088, 1087, 1173, 560, 560,
+ 560, 560, 560, 560, 562, 562, 562, 562, 562, 562,
+ 562, 562, 562, 1088, 1172, 1088, 562, 1169, 562, 1217,
+ 1220, 1164, 562, 562, 562, 562, 562, 562, 744, 744,
+ 744, 744, 744, 744, 744, 750, 750, 750, 750, 750,
+ 750, 750, 872, 778, 562, 613, 613, 613, 613, 613,
+ 613, 613, 1245, 1163, 1259, 1273, 613, 1319, 1092, 1160,
+ 872, 778, 613, 613, 613, 613, 613, 613, 615, 615,
+ 615, 615, 615, 615, 615, 778, 1092, 872, 1245, 615,
+ 1259, 1273, 1092, 1319, 1152, 615, 615, 615, 615, 615,
+
+ 615, 616, 616, 616, 616, 616, 616, 616, 616, 618,
+ 618, 618, 618, 618, 618, 618, 1291, 1151, 1148, 1382,
+ 618, 1432, 882, 1090, 1291, 1093, 618, 618, 618, 618,
+ 618, 618, 620, 620, 620, 620, 620, 620, 620, 620,
+ 882, 1090, 1090, 1093, 620, 1382, 1093, 1432, 1441, 882,
+ 620, 620, 620, 620, 620, 620, 621, 621, 621, 621,
+ 621, 621, 621, 621, 622, 622, 622, 622, 622, 622,
+ 622, 1347, 1354, 1140, 1441, 622, 1139, 1136, 1129, 1347,
+ 1354, 622, 622, 622, 622, 622, 622, 623, 623, 623,
+ 623, 623, 623, 623, 623, 626, 626, 626, 626, 626,
+
+ 626, 626, 626, 626, 770, 884, 827, 626, 782, 626,
+ 786, 1182, 1186, 626, 626, 626, 626, 626, 626, 1362,
+ 827, 1128, 770, 884, 1125, 1120, 782, 1362, 786, 1182,
+ 1186, 775, 884, 792, 770, 626, 629, 629, 629, 629,
+ 629, 629, 629, 629, 629, 782, 827, 786, 629, 775,
+ 629, 792, 1370, 1182, 629, 629, 629, 629, 629, 629,
+ 1370, 775, 1119, 1116, 792, 799, 799, 799, 799, 799,
+ 799, 799, 793, 828, 831, 1450, 629, 635, 635, 635,
+ 635, 635, 635, 635, 635, 635, 1183, 828, 831, 635,
+ 793, 635, 832, 842, 843, 635, 635, 635, 635, 635,
+
+ 635, 1450, 793, 1378, 1183, 1459, 832, 842, 843, 1184,
+ 1115, 1378, 1112, 828, 831, 846, 1111, 635, 640, 640,
+ 640, 640, 640, 640, 640, 640, 640, 1184, 1183, 846,
+ 640, 1459, 832, 842, 843, 1189, 640, 640, 640, 640,
+ 640, 640, 642, 642, 642, 642, 642, 642, 642, 642,
+ 642, 1184, 1108, 1189, 642, 846, 642, 1105, 1189, 847,
+ 642, 642, 642, 642, 642, 642, 840, 840, 840, 840,
+ 840, 840, 840, 847, 855, 855, 855, 855, 855, 855,
+ 855, 1102, 642, 652, 652, 652, 652, 652, 652, 652,
+ 652, 652, 1423, 1098, 1526, 652, 1553, 1557, 1185, 847,
+
+ 1423, 652, 652, 652, 652, 652, 652, 654, 654, 654,
+ 654, 654, 654, 654, 654, 654, 1185, 1071, 1185, 654,
+ 1526, 654, 1553, 1557, 1067, 654, 654, 654, 654, 654,
+ 654, 857, 857, 857, 857, 857, 857, 857, 861, 861,
+ 861, 861, 861, 861, 861, 878, 870, 654, 665, 665,
+ 665, 665, 665, 665, 665, 665, 665, 1472, 1060, 1059,
+ 665, 1056, 1561, 878, 870, 1472, 665, 665, 665, 665,
+ 665, 665, 666, 666, 666, 666, 666, 666, 666, 870,
+ 878, 1052, 1051, 666, 887, 875, 877, 885, 1561, 666,
+ 666, 666, 666, 666, 666, 669, 669, 669, 669, 669,
+
+ 669, 669, 887, 875, 877, 885, 669, 966, 1078, 951,
+ 963, 881, 669, 669, 669, 669, 669, 669, 875, 877,
+ 1565, 887, 885, 951, 1532, 966, 1078, 952, 963, 881,
+ 669, 704, 1532, 704, 704, 704, 704, 704, 704, 704,
+ 881, 952, 966, 963, 704, 1078, 1565, 964, 1048, 951,
+ 704, 704, 704, 704, 704, 704, 910, 910, 910, 910,
+ 910, 910, 910, 955, 956, 964, 968, 952, 704, 705,
+ 705, 705, 705, 705, 705, 705, 705, 955, 956, 1044,
+ 964, 705, 1190, 1298, 968, 968, 1043, 705, 705, 705,
+ 705, 705, 705, 915, 915, 915, 915, 915, 915, 915,
+
+ 1190, 1298, 968, 955, 956, 705, 706, 706, 706, 706,
+ 706, 706, 706, 919, 919, 919, 919, 919, 919, 919,
+ 924, 924, 924, 924, 924, 924, 924, 926, 926, 926,
+ 926, 926, 926, 926, 930, 930, 930, 930, 930, 930,
+ 930, 706, 707, 707, 707, 707, 707, 707, 707, 1040,
+ 1036, 1035, 1032, 707, 1029, 1569, 1589, 1598, 1028, 707,
+ 707, 707, 707, 707, 707, 709, 709, 709, 709, 709,
+ 709, 709, 709, 711, 711, 711, 711, 711, 711, 711,
+ 711, 1569, 1589, 1598, 1025, 711, 1021, 1020, 1017, 1016,
+ 1013, 711, 711, 711, 711, 711, 711, 712, 712, 712,
+
+ 712, 712, 712, 712, 712, 714, 714, 714, 714, 714,
+ 714, 714, 1009, 1005, 1004, 1003, 714, 1000, 997, 1201,
+ 1202, 1187, 714, 714, 714, 714, 714, 714, 715, 715,
+ 715, 715, 715, 715, 715, 715, 715, 1201, 1202, 1187,
+ 715, 1201, 994, 1202, 1299, 1010, 715, 715, 715, 715,
+ 715, 715, 716, 716, 716, 716, 716, 716, 716, 1010,
+ 1187, 991, 1299, 716, 990, 962, 1300, 961, 1301, 716,
+ 716, 716, 716, 716, 716, 718, 718, 718, 718, 718,
+ 718, 718, 718, 718, 1300, 1010, 1301, 718, 958, 1192,
+ 1302, 1310, 1011, 718, 718, 718, 718, 718, 718, 719,
+
+ 719, 719, 719, 719, 719, 719, 1011, 1192, 1302, 1310,
+ 719, 954, 1307, 1302, 1310, 1192, 719, 719, 719, 719,
+ 719, 719, 723, 723, 723, 723, 723, 723, 723, 723,
+ 1307, 953, 1011, 723, 950, 945, 941, 1314, 1315, 723,
+ 723, 723, 723, 723, 723, 725, 725, 725, 725, 725,
+ 725, 725, 725, 725, 1307, 1314, 1315, 725, 933, 929,
+ 1396, 1397, 922, 725, 725, 725, 725, 725, 725, 726,
+ 726, 726, 726, 726, 726, 726, 726, 1315, 1396, 1397,
+ 726, 1396, 1397, 1398, 1399, 1401, 726, 726, 726, 726,
+ 726, 726, 734, 734, 734, 734, 734, 734, 734, 734,
+
+ 734, 1398, 1399, 1401, 734, 918, 1399, 913, 1402, 908,
+ 734, 734, 734, 734, 734, 734, 735, 735, 735, 735,
+ 735, 735, 735, 735, 907, 1398, 1402, 735, 906, 903,
+ 1402, 1403, 1404, 735, 735, 735, 735, 735, 735, 745,
+ 745, 745, 745, 745, 745, 745, 745, 745, 900, 1403,
+ 1404, 745, 896, 1403, 1406, 1409, 1404, 745, 745, 745,
+ 745, 745, 745, 746, 746, 746, 746, 746, 746, 746,
+ 746, 864, 1406, 1409, 746, 860, 1406, 1477, 1409, 1478,
+ 746, 746, 746, 746, 746, 746, 758, 758, 758, 758,
+ 758, 758, 758, 758, 758, 1477, 853, 1478, 758, 852,
+
+ 849, 1488, 845, 1477, 758, 758, 758, 758, 758, 758,
+ 760, 760, 760, 760, 760, 760, 760, 760, 760, 1488,
+ 1488, 844, 760, 841, 760, 838, 837, 834, 760, 760,
+ 760, 760, 760, 760, 936, 936, 936, 936, 936, 936,
+ 936, 938, 938, 938, 938, 938, 938, 938, 1018, 969,
+ 760, 794, 1019, 794, 794, 794, 794, 794, 794, 794,
+ 830, 829, 1018, 826, 794, 825, 1019, 969, 1081, 794,
+ 794, 794, 794, 794, 794, 794, 796, 796, 796, 796,
+ 796, 796, 796, 969, 822, 818, 1081, 796, 1018, 1534,
+ 1491, 1536, 1019, 796, 796, 796, 796, 796, 796, 798,
+
+ 798, 798, 798, 798, 798, 798, 1081, 1534, 1491, 1536,
+ 798, 1491, 1303, 1537, 1544, 1548, 798, 798, 798, 798,
+ 798, 798, 800, 800, 800, 800, 800, 800, 800, 800,
+ 1303, 1537, 1544, 1548, 800, 815, 1537, 1544, 814, 1303,
+ 800, 800, 800, 800, 800, 800, 801, 801, 801, 801,
+ 801, 801, 801, 801, 804, 804, 804, 804, 804, 804,
+ 804, 804, 804, 813, 812, 809, 804, 806, 804, 803,
+ 802, 763, 804, 804, 804, 804, 804, 804, 942, 942,
+ 942, 942, 942, 942, 942, 949, 949, 949, 949, 949,
+ 949, 949, 965, 971, 804, 807, 807, 807, 807, 807,
+
+ 807, 807, 807, 807, 1073, 1074, 1022, 807, 762, 807,
+ 965, 971, 1479, 807, 807, 807, 807, 807, 807, 759,
+ 1022, 755, 1073, 1074, 754, 965, 965, 982, 971, 980,
+ 1479, 1077, 751, 1073, 1074, 807, 810, 810, 810, 810,
+ 810, 810, 810, 810, 810, 982, 1022, 980, 810, 1077,
+ 810, 1479, 1023, 747, 810, 810, 810, 810, 810, 810,
+ 980, 1033, 982, 1077, 743, 736, 1023, 1031, 1031, 1031,
+ 1031, 1031, 1031, 1031, 1034, 1033, 810, 816, 816, 816,
+ 816, 816, 816, 816, 816, 816, 1576, 1075, 1034, 816,
+ 732, 816, 1023, 1037, 1038, 816, 816, 816, 816, 816,
+
+ 816, 1033, 727, 722, 1576, 1075, 721, 1037, 1038, 720,
+ 1541, 717, 713, 1049, 1034, 1050, 1075, 816, 821, 821,
+ 821, 821, 821, 821, 821, 821, 821, 1049, 1541, 1050,
+ 821, 703, 702, 1037, 1038, 698, 821, 821, 821, 821,
+ 821, 821, 823, 823, 823, 823, 823, 823, 823, 823,
+ 823, 1541, 697, 1049, 823, 1050, 823, 1085, 1196, 1053,
+ 823, 823, 823, 823, 823, 823, 1047, 1047, 1047, 1047,
+ 1047, 1047, 1047, 1053, 695, 1085, 1196, 694, 1054, 1410,
+ 1197, 677, 823, 833, 833, 833, 833, 833, 833, 833,
+ 833, 833, 1054, 1196, 1085, 833, 667, 1410, 1197, 1053,
+
+ 663, 833, 833, 833, 833, 833, 833, 835, 835, 835,
+ 835, 835, 835, 835, 835, 835, 1197, 1410, 1054, 835,
+ 657, 835, 656, 653, 649, 835, 835, 835, 835, 835,
+ 835, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1064, 1064,
+ 1064, 1064, 1064, 1064, 1064, 1170, 1094, 835, 848, 848,
+ 848, 848, 848, 848, 848, 848, 848, 648, 645, 1170,
+ 848, 644, 641, 637, 1094, 1094, 848, 848, 848, 848,
+ 848, 848, 850, 850, 850, 850, 850, 850, 850, 850,
+ 850, 1094, 1094, 634, 850, 1170, 850, 1587, 1486, 1086,
+ 850, 850, 850, 850, 850, 850, 1068, 1068, 1068, 1068,
+
+ 1068, 1068, 1068, 633, 632, 1587, 1486, 1086, 1200, 1171,
+ 1174, 631, 850, 862, 862, 862, 862, 862, 862, 862,
+ 862, 862, 1086, 1171, 1174, 862, 1200, 1486, 1612, 1080,
+ 1175, 862, 862, 862, 862, 862, 862, 863, 863, 863,
+ 863, 863, 863, 863, 1175, 1200, 1612, 1080, 863, 1171,
+ 1174, 1578, 628, 1579, 863, 863, 863, 863, 863, 863,
+ 889, 1080, 889, 889, 889, 889, 889, 889, 889, 1578,
+ 1175, 1579, 1578, 889, 1579, 1620, 1580, 1628, 889, 889,
+ 889, 889, 889, 889, 889, 890, 890, 890, 890, 890,
+ 890, 890, 625, 1620, 1580, 1628, 890, 1580, 1411, 1089,
+
+ 1585, 1091, 890, 890, 890, 890, 890, 890, 891, 891,
+ 891, 891, 891, 891, 891, 891, 1411, 1089, 1585, 1091,
+ 891, 1585, 891, 624, 617, 1411, 891, 891, 891, 891,
+ 891, 891, 1089, 1091, 1117, 1117, 1117, 1117, 1117, 1117,
+ 1117, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 891, 893,
+ 893, 893, 893, 893, 893, 893, 614, 612, 608, 602,
+ 893, 601, 1476, 1605, 1607, 1608, 893, 893, 893, 893,
+ 893, 893, 894, 894, 894, 894, 894, 894, 894, 894,
+ 1476, 1605, 1607, 1608, 894, 1605, 600, 1607, 1608, 1476,
+ 894, 894, 894, 894, 894, 894, 895, 895, 895, 895,
+
+ 895, 895, 895, 895, 897, 897, 897, 897, 897, 897,
+ 897, 599, 595, 594, 592, 897, 591, 590, 1633, 1634,
+ 1622, 897, 897, 897, 897, 897, 897, 898, 898, 898,
+ 898, 898, 898, 898, 898, 898, 1633, 1634, 1622, 898,
+ 589, 585, 1634, 1635, 1229, 898, 898, 898, 898, 898,
+ 898, 899, 899, 899, 899, 899, 899, 899, 1229, 1622,
+ 584, 1635, 899, 583, 582, 1636, 1635, 1623, 899, 899,
+ 899, 899, 899, 899, 901, 901, 901, 901, 901, 901,
+ 901, 901, 901, 1636, 1229, 1623, 901, 581, 1636, 1638,
+ 1640, 1230, 901, 901, 901, 901, 901, 901, 902, 902,
+
+ 902, 902, 902, 902, 902, 1230, 1623, 1638, 1640, 902,
+ 580, 579, 1638, 578, 1624, 902, 902, 902, 902, 902,
+ 902, 904, 904, 904, 904, 904, 904, 904, 904, 904,
+ 577, 1230, 1624, 904, 576, 575, 1645, 1647, 1235, 904,
+ 904, 904, 904, 904, 904, 905, 905, 905, 905, 905,
+ 905, 905, 1235, 1624, 1645, 1647, 905, 1645, 1649, 1647,
+ 574, 573, 905, 905, 905, 905, 905, 905, 909, 909,
+ 909, 909, 909, 909, 909, 909, 1649, 572, 1235, 909,
+ 569, 1649, 1651, 1652, 1657, 909, 909, 909, 909, 909,
+ 909, 911, 911, 911, 911, 911, 911, 911, 911, 911,
+
+ 1651, 1652, 1657, 911, 568, 1651, 1653, 567, 565, 911,
+ 911, 911, 911, 911, 911, 912, 912, 912, 912, 912,
+ 912, 912, 912, 1657, 1653, 1652, 912, 564, 561, 1660,
+ 556, 1664, 912, 912, 912, 912, 912, 912, 920, 920,
+ 920, 920, 920, 920, 920, 920, 920, 1660, 1653, 1664,
+ 920, 552, 1660, 1668, 1669, 548, 920, 920, 920, 920,
+ 920, 920, 921, 921, 921, 921, 921, 921, 921, 921,
+ 543, 1668, 1669, 921, 538, 537, 1668, 1669, 1674, 921,
+ 921, 921, 921, 921, 921, 931, 931, 931, 931, 931,
+ 931, 931, 931, 931, 536, 532, 1674, 931, 526, 1675,
+
+ 1677, 1674, 525, 931, 931, 931, 931, 931, 931, 932,
+ 932, 932, 932, 932, 932, 932, 932, 1675, 1677, 520,
+ 932, 1675, 519, 1679, 1682, 1683, 932, 932, 932, 932,
+ 932, 932, 943, 943, 943, 943, 943, 943, 943, 943,
+ 943, 1679, 1682, 1683, 943, 1682, 1679, 1684, 1689, 518,
+ 943, 943, 943, 943, 943, 943, 944, 944, 944, 944,
+ 944, 944, 944, 944, 517, 1684, 1689, 944, 516, 515,
+ 1694, 1689, 1698, 944, 944, 944, 944, 944, 944, 957,
+ 957, 957, 957, 957, 957, 957, 957, 957, 1694, 1684,
+ 1698, 957, 514, 513, 1700, 1698, 1703, 957, 957, 957,
+
+ 957, 957, 957, 959, 959, 959, 959, 959, 959, 959,
+ 959, 959, 1700, 512, 1703, 959, 511, 959, 510, 509,
+ 508, 959, 959, 959, 959, 959, 959, 1126, 1126, 1126,
+ 1126, 1126, 1126, 1126, 1131, 1131, 1131, 1131, 1131, 1131,
+ 1131, 1710, 1712, 959, 986, 986, 986, 986, 986, 986,
+ 986, 986, 986, 506, 503, 502, 501, 986, 500, 1710,
+ 1712, 499, 986, 986, 986, 986, 986, 986, 986, 987,
+ 987, 987, 987, 987, 987, 987, 987, 988, 988, 988,
+ 988, 988, 988, 988, 988, 988, 1133, 1133, 1133, 1133,
+ 1133, 1133, 1133, 1701, 1714, 988, 992, 992, 992, 992,
+
+ 992, 992, 992, 992, 992, 498, 497, 495, 992, 494,
+ 992, 1701, 1714, 493, 992, 992, 992, 992, 992, 992,
+ 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1143, 1143, 1143,
+ 1143, 1143, 1143, 1143, 1706, 1701, 992, 995, 995, 995,
+ 995, 995, 995, 995, 995, 995, 492, 491, 489, 995,
+ 487, 995, 1706, 485, 484, 995, 995, 995, 995, 995,
+ 995, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1149, 1149,
+ 1149, 1149, 1149, 1149, 1149, 1719, 1706, 995, 998, 998,
+ 998, 998, 998, 998, 998, 998, 998, 483, 482, 481,
+ 998, 479, 998, 1719, 478, 476, 998, 998, 998, 998,
+
+ 998, 998, 1155, 1155, 1155, 1155, 1155, 1155, 1155, 1157,
+ 1157, 1157, 1157, 1157, 1157, 1157, 1721, 1724, 998, 1001,
+ 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 475, 474,
+ 471, 1001, 467, 1001, 1721, 1724, 463, 1001, 1001, 1001,
+ 1001, 1001, 1001, 1161, 1161, 1161, 1161, 1161, 1161, 1161,
+ 1168, 1168, 1168, 1168, 1168, 1168, 1168, 462, 461, 1001,
+ 1006, 1006, 1006, 1006, 1006, 1006, 1006, 1006, 458, 454,
+ 453, 1006, 450, 449, 448, 1191, 1194, 1006, 1006, 1006,
+ 1006, 1006, 1006, 1007, 1007, 1007, 1007, 1007, 1007, 1007,
+ 1007, 1007, 1188, 1191, 1194, 1007, 1543, 1007, 1198, 1236,
+
+ 1308, 1007, 1007, 1007, 1007, 1007, 1007, 1194, 1191, 447,
+ 1188, 444, 443, 1236, 1543, 434, 1198, 1709, 1308, 431,
+ 429, 1188, 428, 1007, 1012, 1012, 1012, 1012, 1012, 1012,
+ 1012, 1012, 1012, 1198, 1543, 1709, 1012, 1308, 1709, 1236,
+ 1195, 1199, 1012, 1012, 1012, 1012, 1012, 1012, 1014, 1014,
+ 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1193, 1195, 1199,
+ 1014, 427, 1014, 426, 425, 1309, 1014, 1014, 1014, 1014,
+ 1014, 1014, 1195, 1199, 424, 1193, 1223, 1223, 1223, 1223,
+ 1223, 1223, 1223, 1309, 1239, 1311, 1193, 423, 1014, 1024,
+ 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1239, 422,
+
+ 1309, 1024, 421, 1311, 420, 1203, 419, 1024, 1024, 1024,
+ 1024, 1024, 1024, 1026, 1026, 1026, 1026, 1026, 1026, 1026,
+ 1026, 1026, 1311, 1203, 1239, 1026, 418, 1026, 1240, 417,
+ 416, 1026, 1026, 1026, 1026, 1026, 1026, 1203, 414, 412,
+ 411, 409, 1240, 1246, 1246, 1246, 1246, 1246, 1246, 1246,
+ 408, 1248, 1313, 1026, 1039, 1039, 1039, 1039, 1039, 1039,
+ 1039, 1039, 1039, 405, 404, 1248, 1039, 402, 1240, 400,
+ 1313, 399, 1039, 1039, 1039, 1039, 1039, 1039, 1041, 1041,
+ 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1313, 1249, 1252,
+ 1041, 1248, 1041, 1253, 398, 393, 1041, 1041, 1041, 1041,
+
+ 1041, 1041, 1249, 1252, 392, 391, 389, 1253, 1260, 1260,
+ 1260, 1260, 1260, 1260, 1260, 388, 1262, 1395, 1041, 1055,
+ 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1249, 1252,
+ 1262, 1055, 387, 1253, 386, 1395, 384, 1055, 1055, 1055,
+ 1055, 1055, 1055, 1057, 1057, 1057, 1057, 1057, 1057, 1057,
+ 1057, 1057, 1395, 1263, 1266, 1057, 1262, 1057, 1267, 379,
+ 378, 1057, 1057, 1057, 1057, 1057, 1057, 1263, 1266, 377,
+ 374, 370, 1267, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
+ 368, 1276, 1489, 1057, 1069, 1069, 1069, 1069, 1069, 1069,
+ 1069, 1069, 1069, 1263, 1266, 1276, 1069, 363, 1267, 362,
+
+ 1489, 1277, 1069, 1069, 1069, 1069, 1069, 1069, 1070, 1070,
+ 1070, 1070, 1070, 1070, 1070, 1277, 359, 1489, 354, 1070,
+ 353, 1276, 1707, 345, 1713, 1070, 1070, 1070, 1070, 1070,
+ 1070, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095,
+ 1707, 1277, 1713, 343, 1095, 1707, 342, 1713, 337, 1095,
+ 1095, 1095, 1095, 1095, 1095, 1095, 1096, 1096, 1096, 1096,
+ 1096, 1096, 1096, 1096, 1097, 1097, 1097, 1097, 1097, 1097,
+ 1097, 1097, 1097, 335, 1725, 1726, 1280, 1281, 1727, 1306,
+ 333, 1337, 1097, 1099, 1099, 1099, 1099, 1099, 1099, 1099,
+ 1280, 1281, 1725, 1726, 1099, 1337, 1727, 1306, 1306, 332,
+
+ 1099, 1099, 1099, 1099, 1099, 1099, 1100, 1100, 1100, 1100,
+ 1100, 1100, 1100, 1100, 1100, 1306, 1280, 1281, 1100, 331,
+ 330, 1337, 329, 1338, 1100, 1100, 1100, 1100, 1100, 1100,
+ 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1338, 328, 327,
+ 325, 1101, 324, 323, 318, 315, 1687, 1101, 1101, 1101,
+ 1101, 1101, 1101, 1103, 1103, 1103, 1103, 1103, 1103, 1103,
+ 1103, 1103, 314, 1338, 1687, 1103, 313, 310, 303, 302,
+ 1385, 1103, 1103, 1103, 1103, 1103, 1103, 1104, 1104, 1104,
+ 1104, 1104, 1104, 1104, 1385, 1687, 300, 299, 1104, 298,
+ 296, 294, 293, 1718, 1104, 1104, 1104, 1104, 1104, 1104,
+
+ 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 292,
+ 1385, 1718, 1106, 290, 286, 285, 283, 1386, 1106, 1106,
+ 1106, 1106, 1106, 1106, 1107, 1107, 1107, 1107, 1107, 1107,
+ 1107, 1386, 1718, 280, 276, 1107, 275, 272, 271, 269,
+ 264, 1107, 1107, 1107, 1107, 1107, 1107, 1109, 1109, 1109,
+ 1109, 1109, 1109, 1109, 1109, 1109, 261, 1386, 259, 1109,
+ 258, 256, 253, 249, 1389, 1109, 1109, 1109, 1109, 1109,
+ 1109, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1389, 245,
+ 243, 241, 1110, 240, 238, 237, 236, 235, 1110, 1110,
+ 1110, 1110, 1110, 1110, 1113, 1113, 1113, 1113, 1113, 1113,
+
+ 1113, 1113, 1113, 234, 1389, 233, 1113, 232, 1113, 230,
+ 228, 226, 1113, 1113, 1113, 1113, 1113, 1113, 1287, 1287,
+ 1287, 1287, 1287, 1287, 1287, 1289, 1289, 1289, 1289, 1289,
+ 1289, 1289, 1312, 225, 1113, 1118, 1118, 1118, 1118, 1118,
+ 1118, 1118, 1118, 1118, 223, 221, 220, 1118, 218, 215,
+ 1312, 1312, 214, 1118, 1118, 1118, 1118, 1118, 1118, 1127,
+ 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1312, 213,
+ 211, 1127, 209, 208, 205, 204, 202, 1127, 1127, 1127,
+ 1127, 1127, 1127, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
+ 1138, 1138, 201, 200, 199, 1138, 198, 197, 196, 195,
+
+ 194, 1138, 1138, 1138, 1138, 1138, 1138, 1150, 1150, 1150,
+ 1150, 1150, 1150, 1150, 1150, 1150, 193, 192, 191, 1150,
+ 190, 189, 188, 187, 186, 1150, 1150, 1150, 1150, 1150,
+ 1150, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162,
+ 185, 183, 182, 1162, 179, 178, 177, 176, 175, 1162,
+ 1162, 1162, 1162, 1162, 1162, 1176, 1176, 1176, 1176, 1176,
+ 1176, 1176, 1176, 1176, 174, 173, 172, 1176, 170, 167,
+ 166, 165, 164, 1176, 1176, 1176, 1176, 1176, 1176, 1178,
+ 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 161, 159,
+ 150, 1178, 149, 1178, 1475, 1535, 1390, 1178, 1178, 1178,
+
+ 1178, 1178, 1178, 1293, 1293, 1293, 1293, 1293, 1293, 1293,
+ 1390, 1650, 1475, 1535, 148, 1546, 1304, 1316, 147, 1178,
+ 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1650,
+ 146, 1475, 1535, 1546, 1304, 1316, 1390, 1427, 1204, 1206,
+ 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1304, 1316, 1650,
+ 1206, 1427, 1546, 145, 144, 1400, 1206, 1206, 1206, 1206,
+ 1206, 1206, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207,
+ 1207, 1305, 1317, 1400, 1207, 142, 1207, 1427, 140, 139,
+ 1207, 1207, 1207, 1207, 1207, 1207, 137, 1400, 135, 1305,
+ 1317, 1345, 1345, 1345, 1345, 1345, 1345, 1345, 133, 132,
+
+ 1305, 1317, 1207, 1210, 1210, 1210, 1210, 1210, 1210, 1210,
+ 1210, 1210, 131, 130, 128, 1210, 127, 1210, 126, 125,
+ 124, 1210, 1210, 1210, 1210, 1210, 1210, 1350, 1350, 1350,
+ 1350, 1350, 1350, 1350, 1352, 1352, 1352, 1352, 1352, 1352,
+ 1352, 123, 121, 1210, 1213, 1213, 1213, 1213, 1213, 1213,
+ 1213, 1213, 1213, 119, 118, 117, 1213, 116, 1213, 115,
+ 114, 113, 1213, 1213, 1213, 1213, 1213, 1213, 1358, 1358,
+ 1358, 1358, 1358, 1358, 1358, 1360, 1360, 1360, 1360, 1360,
+ 1360, 1360, 112, 111, 1213, 1216, 1216, 1216, 1216, 1216,
+ 1216, 1216, 1216, 1216, 109, 108, 101, 1216, 100, 1216,
+
+ 99, 97, 96, 1216, 1216, 1216, 1216, 1216, 1216, 1366,
+ 1366, 1366, 1366, 1366, 1366, 1366, 1368, 1368, 1368, 1368,
+ 1368, 1368, 1368, 93, 92, 1216, 1219, 1219, 1219, 1219,
+ 1219, 1219, 1219, 1219, 1219, 91, 90, 89, 1219, 88,
+ 1219, 87, 86, 85, 1219, 1219, 1219, 1219, 1219, 1219,
+ 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1376, 1376, 1376,
+ 1376, 1376, 1376, 1376, 1428, 1539, 1219, 1224, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 84, 82, 1428, 1224,
+ 81, 80, 79, 1539, 78, 1224, 1224, 1224, 1224, 1224,
+ 1224, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231,
+
+ 77, 1539, 76, 1231, 1428, 75, 74, 73, 72, 1231,
+ 1231, 1231, 1231, 1231, 1231, 1241, 1241, 1241, 1241, 1241,
+ 1241, 1241, 1241, 1241, 71, 70, 69, 1241, 67, 66,
+ 65, 51, 43, 1241, 1241, 1241, 1241, 1241, 1241, 1254,
+ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 42, 40,
+ 18, 1254, 11, 8, 3, 0, 0, 1254, 1254, 1254,
+ 1254, 1254, 1254, 1268, 1268, 1268, 1268, 1268, 1268, 1268,
+ 1268, 1268, 0, 0, 0, 1268, 0, 0, 0, 0,
+ 0, 1268, 1268, 1268, 1268, 1268, 1268, 1282, 1282, 1282,
+ 1282, 1282, 1282, 1282, 1282, 1282, 0, 0, 0, 1282,
+
+ 0, 0, 0, 0, 0, 1282, 1282, 1282, 1282, 1282,
+ 1282, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294,
+ 0, 0, 0, 1294, 0, 0, 0, 0, 0, 1294,
+ 1294, 1294, 1294, 1294, 1294, 1318, 1318, 1318, 1318, 1318,
+ 1318, 1318, 1318, 1318, 0, 0, 0, 1318, 0, 1318,
+ 0, 0, 0, 1318, 1318, 1318, 1318, 1318, 1318, 1383,
+ 1383, 1383, 1383, 1383, 1383, 1383, 1421, 1421, 1421, 1421,
+ 1421, 1421, 1421, 1435, 1540, 1318, 1322, 1322, 1322, 1322,
+ 1322, 1322, 1322, 1322, 1322, 0, 0, 1435, 1322, 0,
+ 0, 0, 1540, 0, 1322, 1322, 1322, 1322, 1322, 1322,
+
+ 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 0,
+ 1540, 0, 1325, 1435, 0, 0, 0, 0, 1325, 1325,
+ 1325, 1325, 1325, 1325, 1328, 1328, 1328, 1328, 1328, 1328,
+ 1328, 1328, 1328, 0, 0, 0, 1328, 0, 0, 0,
+ 0, 0, 1328, 1328, 1328, 1328, 1328, 1328, 1331, 1331,
+ 1331, 1331, 1331, 1331, 1331, 1331, 1331, 0, 0, 0,
+ 1331, 0, 0, 0, 0, 0, 1331, 1331, 1331, 1331,
+ 1331, 1331, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334,
+ 1334, 0, 0, 0, 1334, 0, 0, 0, 0, 0,
+ 1334, 1334, 1334, 1334, 1334, 1334, 1339, 1339, 1339, 1339,
+
+ 1339, 1339, 1339, 1339, 1339, 0, 0, 0, 1339, 0,
+ 0, 0, 1407, 0, 1339, 1339, 1339, 1339, 1339, 1339,
+ 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1405,
+ 1407, 1408, 1391, 0, 1436, 0, 0, 0, 1391, 1391,
+ 1391, 1391, 1391, 1391, 1407, 1490, 0, 1405, 1436, 1408,
+ 1433, 1433, 1433, 1433, 1433, 1433, 1433, 0, 1405, 0,
+ 0, 1408, 1444, 1490, 1405, 1412, 1412, 1412, 1412, 1412,
+ 1412, 1412, 1412, 1412, 1436, 1490, 1444, 1412, 0, 0,
+ 0, 0, 1445, 1412, 1412, 1412, 1412, 1412, 1412, 1442,
+ 1442, 1442, 1442, 1442, 1442, 1442, 1445, 1453, 1454, 0,
+
+ 0, 0, 1444, 1451, 1451, 1451, 1451, 1451, 1451, 1451,
+ 1462, 1453, 1454, 1460, 1460, 1460, 1460, 1460, 1460, 1460,
+ 1463, 0, 1445, 0, 1462, 1468, 1468, 1468, 1468, 1468,
+ 1468, 1468, 0, 1480, 1463, 1485, 1481, 1453, 1454, 1470,
+ 1470, 1470, 1470, 1470, 1470, 1470, 1482, 1483, 1484, 0,
+ 1462, 1480, 1487, 1485, 1481, 1500, 0, 1501, 1542, 1547,
+ 1463, 1603, 1480, 1481, 1482, 1483, 1484, 1485, 0, 1500,
+ 1487, 1501, 0, 1482, 1483, 1484, 1542, 1547, 0, 1603,
+ 0, 1487, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 0,
+ 0, 0, 0, 1603, 1542, 1500, 1547, 1501, 1510, 1510,
+
+ 1510, 1510, 1510, 1510, 1510, 1514, 1514, 1514, 1514, 1514,
+ 1514, 1514, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1522,
+ 1522, 1522, 1522, 1522, 1522, 1522, 1527, 1527, 1527, 1527,
+ 1527, 1527, 1527, 1529, 1530, 1538, 1545, 1549, 1551, 1551,
+ 1551, 1551, 1551, 1551, 1551, 0, 0, 1529, 1530, 0,
+ 0, 0, 0, 1538, 1545, 1549, 0, 0, 0, 0,
+ 0, 0, 1538, 1545, 1549, 1554, 1554, 1554, 1554, 1554,
+ 1554, 1554, 0, 1529, 1530, 1558, 1558, 1558, 1558, 1558,
+ 1558, 1558, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1566,
+ 1566, 1566, 1566, 1566, 1566, 1566, 1570, 1570, 1570, 1570,
+
+ 1570, 1570, 1570, 1573, 1573, 1573, 1573, 1573, 1573, 1573,
+ 1577, 1581, 0, 1582, 1583, 1586, 1588, 1584, 1590, 1590,
+ 1590, 1590, 1590, 1590, 1590, 1601, 1609, 0, 1577, 1581,
+ 1581, 1582, 1583, 1586, 1588, 1584, 0, 0, 0, 0,
+ 0, 0, 1586, 1601, 1609, 1577, 1602, 1581, 1604, 1606,
+ 1582, 1583, 1584, 1588, 1599, 1599, 1599, 1599, 1599, 1599,
+ 1599, 1610, 1601, 1609, 1602, 1611, 1604, 1606, 1621, 1625,
+ 0, 1626, 1627, 1602, 1629, 1630, 1637, 1639, 0, 1610,
+ 1604, 1606, 1641, 1611, 0, 0, 1621, 1625, 1610, 1626,
+ 1627, 1642, 1629, 1630, 1637, 1639, 1639, 1611, 1625, 0,
+
+ 1641, 1643, 1626, 1637, 1644, 1621, 1630, 1627, 0, 1642,
+ 1646, 1629, 1648, 1639, 1639, 1654, 1641, 1641, 0, 1643,
+ 1655, 0, 1644, 1665, 1656, 1658, 1642, 0, 1646, 0,
+ 1648, 1659, 1661, 1654, 0, 1662, 1643, 1663, 1655, 1644,
+ 0, 1665, 1656, 1658, 1648, 1646, 1656, 1655, 0, 1659,
+ 1661, 1666, 1654, 1662, 1658, 1663, 1663, 1667, 1656, 1656,
+ 1665, 1670, 1671, 1672, 1673, 0, 1659, 1676, 1661, 1666,
+ 1662, 1678, 1680, 1663, 0, 1667, 1681, 0, 1685, 1670,
+ 1671, 1672, 1673, 1666, 0, 1676, 1686, 0, 1670, 1678,
+ 1680, 1690, 1671, 0, 1681, 1667, 1685, 1673, 1672, 1676,
+
+ 1688, 0, 1678, 1691, 1686, 1680, 1692, 1693, 0, 1690,
+ 1685, 1681, 1696, 1695, 1697, 1699, 0, 0, 1688, 1686,
+ 1686, 1691, 1702, 0, 1692, 1693, 1690, 1704, 1708, 1688,
+ 1696, 1695, 1697, 1699, 1693, 1691, 1705, 1711, 1716, 0,
+ 1702, 1696, 1699, 1692, 1695, 1704, 1708, 1715, 1720, 1717,
+ 1722, 0, 1697, 0, 1705, 1711, 1716, 1702, 0, 0,
+ 0, 0, 0, 1708, 1704, 1715, 1720, 1717, 1722, 0,
+ 0, 0, 1705, 0, 1711, 1716, 1717, 1723, 0, 0,
+ 1723, 1723, 0, 1715, 0, 1720, 0, 1722, 0, 0,
+ 0, 0, 0, 0, 0, 1723, 1729, 0, 0, 0,
+
+ 0, 1729, 1729, 1729, 1730, 0, 1730, 1730, 1730, 1730,
+ 1730, 1730, 1730, 1731, 0, 1731, 1732, 1732, 1732, 1733,
+ 1733, 1733, 1734, 1734, 1734, 1735, 1735, 1735, 1736, 1736,
+ 1736, 1737, 1737, 1737, 1738, 1738, 1738, 1739, 1739, 1739,
+ 1740, 1740, 1740, 1741, 0, 1741, 1742, 1742, 1742, 1743,
+ 1743, 1743, 1744, 1744, 1744, 1745, 1745, 1745, 1746, 0,
+ 1746, 1747, 1747, 1747, 1748, 1748, 0, 0, 1748, 1749,
+ 1749, 1749, 1750, 1750, 1750, 1751, 1751, 1751, 1752, 1752,
+ 1752, 1753, 1753, 1753, 1754, 1754, 1754, 1755, 1755, 1755,
+ 1756, 1756, 1756, 1757, 1757, 1757, 1758, 1758, 0, 0,
+
+ 1758, 1759, 1759, 1759, 1760, 1760, 1760, 1761, 0, 1761,
+ 1762, 1762, 1762, 1763, 1763, 1763, 1764, 0, 1764, 1765,
+ 1765, 1765, 1766, 1766, 1766, 1767, 1767, 1767, 1768, 1768,
+ 1768, 1769, 1769, 1769, 1770, 0, 1770, 1771, 0, 1771,
+ 1772, 1772, 1772, 1773, 1773, 1773, 1774, 0, 1774, 1775,
+ 1775, 0, 0, 1775, 1776, 1776, 0, 0, 1776, 1777,
+ 1777, 1777, 1778, 1778, 1778, 1779, 1779, 0, 1779, 1780,
+ 1780, 1780, 1781, 1781, 1781, 1782, 1782, 1782, 1783, 1783,
+ 1783, 1784, 1784, 1784, 1785, 1785, 1785, 1786, 1786, 1786,
+ 1787, 1787, 0, 0, 1787, 1788, 1788, 1788, 1789, 1789,
+
+ 1789, 1790, 1790, 0, 1790, 1791, 1791, 0, 0, 1791,
+ 1792, 1792, 0, 1792, 1793, 1793, 1794, 1794, 0, 0,
+ 1794, 1795, 1795, 1795, 1796, 1796, 1796, 1797, 1797, 0,
+ 1797, 1798, 0, 1798, 1799, 0, 1799, 1800, 1800, 1800,
+ 1801, 1801, 1801, 1802, 0, 1802, 1803, 1803, 1803, 1804,
+ 1804, 1804, 1805, 1805, 1805, 1806, 1806, 1806, 1807, 1807,
+ 1807, 1808, 1808, 1808, 1809, 0, 1809, 1810, 0, 1810,
+ 1811, 1811, 1811, 1812, 1812, 1812, 1813, 0, 1813, 1814,
+ 0, 1814, 1815, 0, 1815, 1816, 1816, 1816, 1817, 1817,
+ 1817, 1818, 0, 1818, 1819, 0, 0, 1819, 1820, 1820,
+
+ 0, 1820, 1821, 1821, 0, 0, 1821, 1822, 1822, 0,
+ 1822, 1823, 1823, 1824, 1824, 0, 0, 1824, 1825, 1825,
+ 1825, 1826, 1826, 1826, 1827, 1827, 0, 1827, 1828, 1828,
+ 1828, 0, 1828, 1828, 1829, 1829, 1829, 1830, 1830, 1830,
+ 1831, 1831, 1831, 1832, 1832, 1832, 1833, 1833, 1833, 1834,
+ 1834, 1834, 1835, 1835, 1835, 1836, 1836, 1836, 1837, 1837,
+ 0, 0, 1837, 1838, 1838, 1838, 1839, 1839, 1839, 1840,
+ 1840, 0, 1840, 1841, 1841, 0, 0, 1841, 1842, 1842,
+ 0, 1842, 1843, 1843, 1844, 1844, 0, 0, 1844, 1845,
+ 1845, 1845, 1846, 1846, 1846, 1847, 1847, 0, 1847, 1848,
+
+ 0, 0, 1848, 1849, 1849, 0, 1849, 1850, 1850, 0,
+ 0, 1850, 1851, 1851, 0, 1851, 1852, 1852, 1853, 1853,
+ 0, 0, 1853, 1854, 1854, 1854, 1855, 1855, 1855, 1856,
+ 1856, 0, 1856, 1857, 0, 1857, 1858, 0, 1858, 1859,
+ 0, 1859, 1860, 1860, 1860, 1861, 1861, 1861, 1862, 0,
+ 1862, 1863, 1863, 1863, 0, 1863, 1863, 1864, 1864, 1864,
+ 1865, 1865, 1865, 1866, 1866, 1866, 1867, 1867, 1867, 1868,
+ 1868, 1868, 1869, 1869, 1869, 1870, 1870, 1870, 1871, 0,
+ 1871, 1872, 0, 1872, 1873, 1873, 1873, 1874, 1874, 1874,
+ 1875, 0, 1875, 1876, 0, 1876, 1877, 0, 1877, 1878,
+
+ 1878, 1878, 1879, 1879, 1879, 1880, 0, 1880, 1881, 0,
+ 1881, 1882, 0, 1882, 1883, 0, 1883, 1884, 1884, 1884,
+ 1885, 1885, 1885, 1886, 0, 1886, 1887, 0, 1887, 1888,
+ 0, 0, 1888, 1889, 1889, 0, 1889, 1890, 1890, 0,
+ 0, 1890, 1891, 1891, 0, 1891, 1892, 1892, 1893, 1893,
+ 0, 0, 1893, 1894, 1894, 1894, 1895, 1895, 1895, 1896,
+ 1896, 0, 1896, 1897, 1897, 1897, 0, 1897, 1897, 1898,
+ 1898, 1898, 1899, 1899, 1899, 1900, 1900, 1900, 1901, 1901,
+ 1901, 1902, 1902, 1902, 1903, 1903, 1903, 1904, 1904, 1904,
+ 1905, 1905, 1905, 1906, 1906, 0, 0, 1906, 1907, 1907,
+
+ 1907, 1908, 1908, 1908, 1909, 1909, 0, 1909, 1910, 1910,
+ 0, 0, 1910, 1911, 1911, 0, 1911, 1912, 1912, 1913,
+ 1913, 0, 0, 1913, 1914, 1914, 1914, 1915, 1915, 1915,
+ 1916, 1916, 0, 1916, 1917, 0, 0, 1917, 1918, 1918,
+ 0, 1918, 1919, 1919, 0, 0, 1919, 1920, 1920, 0,
+ 1920, 1921, 1921, 1922, 1922, 0, 0, 1922, 1923, 1923,
+ 1923, 1924, 1924, 1924, 1925, 1925, 0, 1925, 1926, 0,
+ 1926, 1927, 0, 0, 1927, 1928, 1928, 0, 1928, 1929,
+ 1929, 0, 0, 1929, 1930, 1930, 0, 1930, 1931, 1931,
+ 1932, 1932, 0, 0, 1932, 1933, 1933, 1933, 1934, 1934,
+
+ 1934, 1935, 1935, 0, 1935, 1936, 0, 1936, 1937, 0,
+ 1937, 1938, 0, 1938, 1939, 1939, 1939, 1940, 1940, 1940,
+ 1941, 0, 1941, 1942, 1942, 1942, 0, 1942, 1942, 1943,
+ 1943, 1943, 1944, 1944, 1944, 1945, 1945, 1945, 1946, 1946,
+ 1946, 1947, 1947, 1947, 1948, 1948, 1948, 1949, 1949, 1949,
+ 1950, 1950, 1950, 1951, 1951, 1951, 1952, 1952, 1952, 1953,
+ 0, 1953, 1954, 0, 1954, 1955, 1955, 1955, 1956, 1956,
+ 1956, 1957, 1957, 1957, 1958, 0, 1958, 1959, 0, 1959,
+ 1960, 0, 1960, 1961, 1961, 1961, 1962, 1962, 1962, 1963,
+ 1963, 1963, 1964, 0, 1964, 1965, 0, 1965, 1966, 0,
+
+ 1966, 1967, 0, 1967, 1968, 1968, 1968, 1969, 1969, 1969,
+ 1970, 1970, 1970, 1971, 0, 1971, 1972, 0, 1972, 1973,
+ 0, 1973, 1974, 0, 1974, 1975, 1975, 1975, 1976, 1976,
+ 1976, 1977, 1977, 1977, 1978, 0, 1978, 1979, 0, 1979,
+ 1980, 0, 0, 1980, 1981, 1981, 0, 1981, 1982, 1982,
+ 0, 0, 1982, 1983, 1983, 0, 1983, 1984, 1984, 1985,
+ 1985, 0, 0, 1985, 1986, 1986, 1986, 1987, 1987, 1987,
+ 1988, 1988, 0, 1988, 1989, 1989, 1989, 0, 1989, 1989,
+ 1990, 1990, 1990, 1991, 1991, 1991, 1992, 1992, 1992, 1993,
+ 1993, 1993, 1994, 1994, 1994, 1995, 1995, 1995, 1996, 1996,
+
+ 1996, 1997, 1997, 1997, 1998, 0, 1998, 1999, 1999, 1999,
+ 2000, 2000, 0, 0, 2000, 2001, 2001, 2001, 2002, 2002,
+ 2002, 2003, 2003, 0, 2003, 2004, 2004, 0, 0, 2004,
+ 2005, 2005, 0, 2005, 2006, 2006, 2007, 2007, 0, 0,
+ 2007, 2008, 2008, 2008, 2009, 2009, 2009, 2010, 2010, 0,
+ 2010, 2011, 0, 0, 2011, 2012, 2012, 0, 2012, 2013,
+ 2013, 0, 0, 2013, 2014, 2014, 0, 2014, 2015, 2015,
+ 2016, 2016, 0, 0, 2016, 2017, 2017, 2017, 2018, 2018,
+ 2018, 2019, 2019, 0, 2019, 2020, 0, 2020, 2021, 0,
+ 0, 2021, 2022, 2022, 0, 2022, 2023, 2023, 0, 0,
+
+ 2023, 2024, 2024, 0, 2024, 2025, 2025, 2026, 2026, 0,
+ 0, 2026, 2027, 2027, 2027, 2028, 2028, 2028, 2029, 2029,
+ 0, 2029, 2030, 0, 2030, 2031, 0, 0, 2031, 2032,
+ 2032, 0, 2032, 2033, 2033, 0, 0, 2033, 2034, 2034,
+ 0, 2034, 2035, 2035, 2036, 2036, 0, 0, 2036, 2037,
+ 2037, 2037, 2038, 2038, 2038, 2039, 2039, 0, 2039, 2040,
+ 0, 2040, 2041, 0, 2041, 2042, 0, 2042, 2043, 2043,
+ 2043, 2044, 0, 2044, 2045, 2045, 2045, 2046, 0, 2046,
+ 2047, 2047, 2047, 0, 2047, 2047, 2048, 0, 2048, 2049,
+ 2049, 2049, 2050, 0, 2050, 2051, 2051, 2051, 2052, 0,
+
+ 2052, 2053, 2053, 2053, 2054, 0, 2054, 2055, 2055, 2055,
+ 2056, 0, 2056, 2057, 2057, 2057, 2058, 0, 2058, 2059,
+ 2059, 2059, 2060, 2060, 0, 0, 2060, 2061, 2061, 2061,
+ 2062, 2062, 2062, 2063, 2063, 2063, 2064, 2064, 0, 2064,
+ 2065, 2065, 2065, 2066, 0, 2066, 2067, 2067, 2067, 2068,
+ 2068, 2068, 2069, 0, 2069, 2070, 0, 2070, 2071, 2071,
+ 2071, 2072, 2072, 2072, 2073, 0, 2073, 2074, 0, 2074,
+ 2075, 0, 2075, 2076, 2076, 2076, 2077, 2077, 2077, 2078,
+ 0, 2078, 2079, 0, 2079, 2080, 0, 2080, 2081, 2081,
+ 2081, 2082, 2082, 2082, 2083, 0, 2083, 2084, 0, 2084,
+
+ 2085, 0, 2085, 2086, 2086, 2086, 2087, 2087, 2087, 2088,
+ 0, 2088, 2089, 0, 0, 2089, 2090, 2090, 0, 2090,
+ 2091, 2091, 0, 0, 2091, 2092, 2092, 0, 2092, 2093,
+ 2093, 2094, 2094, 0, 0, 2094, 2095, 2095, 2095, 2096,
+ 0, 2096, 2097, 2097, 0, 2097, 2098, 2098, 2098, 0,
+ 2098, 2098, 2099, 2099, 2099, 2100, 2100, 2100, 2101, 0,
+ 2101, 2102, 0, 2102, 2103, 0, 2103, 2104, 0, 2104,
+ 2105, 0, 2105, 2106, 0, 2106, 2107, 0, 2107, 2108,
+ 2108, 2108, 2109, 2109, 2109, 2110, 0, 2110, 2111, 2111,
+ 0, 0, 2111, 2112, 2112, 0, 2112, 2113, 2113, 2114,
+
+ 0, 2114, 2115, 0, 0, 2115, 2116, 2116, 0, 2116,
+ 2117, 2117, 0, 0, 2117, 2118, 2118, 0, 2118, 2119,
+ 2119, 2120, 0, 2120, 2121, 0, 2121, 2122, 0, 0,
+ 2122, 2123, 2123, 0, 2123, 2124, 2124, 0, 0, 2124,
+ 2125, 2125, 0, 2125, 2126, 2126, 2127, 0, 2127, 2128,
+ 0, 2128, 2129, 0, 0, 2129, 2130, 2130, 0, 2130,
+ 2131, 2131, 0, 0, 2131, 2132, 2132, 0, 2132, 2133,
+ 2133, 2134, 0, 2134, 2135, 0, 2135, 2136, 0, 0,
+ 2136, 2137, 2137, 0, 2137, 2138, 2138, 0, 0, 2138,
+ 2139, 2139, 0, 2139, 2140, 2140, 2141, 0, 2141, 2142,
+
+ 0, 2142, 2143, 0, 2143, 2144, 0, 2144, 2145, 2145,
+ 2145, 2146, 0, 2146, 2147, 2147, 2147, 0, 2147, 2147,
+ 2148, 0, 2148, 2149, 0, 2149, 2150, 0, 2150, 2151,
+ 0, 2151, 2152, 0, 2152, 2153, 0, 2153, 2154, 0,
+ 2154, 2155, 2155, 0, 0, 2155, 2156, 2156, 0, 2156,
+ 2157, 2157, 2158, 0, 2158, 2159, 0, 2159, 2160, 0,
+ 2160, 2161, 0, 2161, 2162, 0, 2162, 2163, 0, 2163,
+ 2164, 0, 2164, 2165, 0, 2165, 2166, 0, 2166, 2167,
+ 0, 2167, 2168, 0, 0, 2168, 2169, 2169, 0, 0,
+ 2169, 2170, 0, 2170, 2171, 0, 2171, 2172, 0, 2172,
+
+ 2173, 0, 0, 2173, 2174, 0, 0, 2174, 2175, 0,
+ 0, 2175, 2176, 0, 0, 2176, 2177, 0, 0, 2177,
+ 2178, 0, 2178, 2179, 0, 2179, 2180, 0, 0, 2180,
+ 2181, 0, 2181, 2182, 0, 2182, 2183, 0, 2183, 2184,
+ 0, 2184, 2185, 0, 2185, 2186, 0, 0, 2186, 2187,
+ 0, 2187, 2188, 0, 2188, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
+
+ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728
} ;
/* The intent behind this definition is that it'll catch
@@ -2698,7 +2886,7 @@ static yyconst flex_int16_t yy_chk[7474] =
* We want to generate code that can be used by a reentrant parser
* generated by Bison or Berkeley YACC.
*/
-#line 45 "scanner.l"
+#line 67 "scanner.l"
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
@@ -2720,20 +2908,6 @@ static yyconst flex_int16_t yy_chk[7474] =
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#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>
@@ -2753,6 +2927,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
*
@@ -2772,10 +2948,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" */
@@ -2798,7 +2973,12 @@ void pcap_set_column(int, yyscan_t);
static int stoi(char *);
static inline int xdtoi(int);
-#line 2802 "scanner.c"
+/*
+ * Disable diagnostics in the code generated by Flex.
+ */
+DIAG_OFF_FLEX
+
+#line 2982 "scanner.c"
#define INITIAL 0
@@ -2825,8 +3005,8 @@ struct yyguts_t
size_t yy_buffer_stack_max; /**< capacity of stack. */
YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
char yy_hold_char;
- yy_size_t yy_n_chars;
- yy_size_t yyleng_r;
+ int yy_n_chars;
+ int yyleng_r;
char *yy_c_buf_p;
int yy_init;
int yy_start;
@@ -2873,23 +3053,23 @@ void pcap_set_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
FILE *pcap_get_in (yyscan_t yyscanner );
-void pcap_set_in (FILE * in_str ,yyscan_t yyscanner );
+void pcap_set_in (FILE * _in_str ,yyscan_t yyscanner );
FILE *pcap_get_out (yyscan_t yyscanner );
-void pcap_set_out (FILE * out_str ,yyscan_t yyscanner );
+void pcap_set_out (FILE * _out_str ,yyscan_t yyscanner );
-yy_size_t pcap_get_leng (yyscan_t yyscanner );
+ int pcap_get_leng (yyscan_t yyscanner );
char *pcap_get_text (yyscan_t yyscanner );
int pcap_get_lineno (yyscan_t yyscanner );
-void pcap_set_lineno (int line_number ,yyscan_t yyscanner );
+void pcap_set_lineno (int _line_number ,yyscan_t yyscanner );
int pcap_get_column (yyscan_t yyscanner );
-void pcap_set_column (int column_no ,yyscan_t yyscanner );
+void pcap_set_column (int _column_no ,yyscan_t yyscanner );
YYSTYPE * pcap_get_lval (yyscan_t yyscanner );
@@ -2907,6 +3087,10 @@ extern int pcap_wrap (yyscan_t yyscanner );
#endif
#endif
+#ifndef YY_NO_UNPUT
+
+#endif
+
#ifndef yytext_ptr
static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
#endif
@@ -2940,7 +3124,7 @@ static int input (yyscan_t yyscanner );
/* This used to be an fputs(), but since the string might contain NUL's,
* we now use fwrite().
*/
-#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
#endif
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
@@ -2964,7 +3148,7 @@ static int input (yyscan_t yyscanner );
else \
{ \
errno=0; \
- while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
{ \
if( errno != EINTR) \
{ \
@@ -3021,7 +3205,7 @@ extern int pcap_lex \
/* Code executed at the end of each rule. */
#ifndef YY_BREAK
-#define YY_BREAK break;
+#define YY_BREAK /*LINTED*/break;
#endif
#define YY_RULE_SETUP \
@@ -3031,9 +3215,9 @@ extern int pcap_lex \
*/
YY_DECL
{
- register yy_state_type yy_current_state;
- register char *yy_cp, *yy_bp;
- register int yy_act;
+ yy_state_type yy_current_state;
+ char *yy_cp, *yy_bp;
+ int yy_act;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yylval = yylval_param;
@@ -3065,11 +3249,11 @@ YY_DECL
}
{
-#line 240 "scanner.l"
+#line 254 "scanner.l"
-#line 3071 "scanner.c"
+#line 3255 "scanner.c"
- while ( 1 ) /* loops until end-of-file is reached */
+ while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
{
yy_cp = yyg->yy_c_buf_p;
@@ -3085,7 +3269,7 @@ YY_DECL
yy_match:
do
{
- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
+ YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
if ( yy_accept[yy_current_state] )
{
yyg->yy_last_accepting_state = yy_current_state;
@@ -3094,13 +3278,13 @@ yy_match:
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 1464 )
+ if ( yy_current_state >= 1729 )
yy_c = yy_meta[(unsigned int) yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
++yy_cp;
}
- while ( yy_current_state != 1463 );
+ while ( yy_current_state != 1728 );
yy_cp = yyg->yy_last_accepting_cpos;
yy_current_state = yyg->yy_last_accepting_state;
@@ -3122,257 +3306,257 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
YY_RULE_SETUP
-#line 241 "scanner.l"
+#line 255 "scanner.l"
return DST;
YY_BREAK
case 2:
YY_RULE_SETUP
-#line 242 "scanner.l"
+#line 256 "scanner.l"
return SRC;
YY_BREAK
case 3:
YY_RULE_SETUP
-#line 244 "scanner.l"
+#line 258 "scanner.l"
return LINK;
YY_BREAK
case 4:
YY_RULE_SETUP
-#line 245 "scanner.l"
+#line 259 "scanner.l"
return LINK;
YY_BREAK
case 5:
YY_RULE_SETUP
-#line 246 "scanner.l"
+#line 260 "scanner.l"
return ARP;
YY_BREAK
case 6:
YY_RULE_SETUP
-#line 247 "scanner.l"
+#line 261 "scanner.l"
return RARP;
YY_BREAK
case 7:
YY_RULE_SETUP
-#line 248 "scanner.l"
+#line 262 "scanner.l"
return IP;
YY_BREAK
case 8:
YY_RULE_SETUP
-#line 249 "scanner.l"
+#line 263 "scanner.l"
return SCTP;
YY_BREAK
case 9:
YY_RULE_SETUP
-#line 250 "scanner.l"
+#line 264 "scanner.l"
return TCP;
YY_BREAK
case 10:
YY_RULE_SETUP
-#line 251 "scanner.l"
+#line 265 "scanner.l"
return UDP;
YY_BREAK
case 11:
YY_RULE_SETUP
-#line 252 "scanner.l"
+#line 266 "scanner.l"
return ICMP;
YY_BREAK
case 12:
YY_RULE_SETUP
-#line 253 "scanner.l"
+#line 267 "scanner.l"
return IGMP;
YY_BREAK
case 13:
YY_RULE_SETUP
-#line 254 "scanner.l"
+#line 268 "scanner.l"
return IGRP;
YY_BREAK
case 14:
YY_RULE_SETUP
-#line 255 "scanner.l"
+#line 269 "scanner.l"
return PIM;
YY_BREAK
case 15:
YY_RULE_SETUP
-#line 256 "scanner.l"
+#line 270 "scanner.l"
return VRRP;
YY_BREAK
case 16:
YY_RULE_SETUP
-#line 257 "scanner.l"
+#line 271 "scanner.l"
return CARP;
YY_BREAK
case 17:
YY_RULE_SETUP
-#line 258 "scanner.l"
+#line 272 "scanner.l"
return RADIO;
YY_BREAK
case 18:
YY_RULE_SETUP
-#line 260 "scanner.l"
+#line 274 "scanner.l"
return IPV6;
YY_BREAK
case 19:
YY_RULE_SETUP
-#line 261 "scanner.l"
+#line 275 "scanner.l"
return ICMPV6;
YY_BREAK
case 20:
YY_RULE_SETUP
-#line 262 "scanner.l"
+#line 276 "scanner.l"
return AH;
YY_BREAK
case 21:
YY_RULE_SETUP
-#line 263 "scanner.l"
+#line 277 "scanner.l"
return ESP;
YY_BREAK
case 22:
YY_RULE_SETUP
-#line 265 "scanner.l"
+#line 279 "scanner.l"
return ATALK;
YY_BREAK
case 23:
YY_RULE_SETUP
-#line 266 "scanner.l"
+#line 280 "scanner.l"
return AARP;
YY_BREAK
case 24:
YY_RULE_SETUP
-#line 267 "scanner.l"
+#line 281 "scanner.l"
return DECNET;
YY_BREAK
case 25:
YY_RULE_SETUP
-#line 268 "scanner.l"
+#line 282 "scanner.l"
return LAT;
YY_BREAK
case 26:
YY_RULE_SETUP
-#line 269 "scanner.l"
+#line 283 "scanner.l"
return SCA;
YY_BREAK
case 27:
YY_RULE_SETUP
-#line 270 "scanner.l"
+#line 284 "scanner.l"
return MOPRC;
YY_BREAK
case 28:
YY_RULE_SETUP
-#line 271 "scanner.l"
+#line 285 "scanner.l"
return MOPDL;
YY_BREAK
case 29:
YY_RULE_SETUP
-#line 273 "scanner.l"
+#line 287 "scanner.l"
return ISO;
YY_BREAK
case 30:
YY_RULE_SETUP
-#line 274 "scanner.l"
+#line 288 "scanner.l"
return ESIS;
YY_BREAK
case 31:
YY_RULE_SETUP
-#line 275 "scanner.l"
+#line 289 "scanner.l"
return ESIS;
YY_BREAK
case 32:
YY_RULE_SETUP
-#line 276 "scanner.l"
+#line 290 "scanner.l"
return ISIS;
YY_BREAK
case 33:
YY_RULE_SETUP
-#line 277 "scanner.l"
+#line 291 "scanner.l"
return ISIS;
YY_BREAK
case 34:
YY_RULE_SETUP
-#line 278 "scanner.l"
+#line 292 "scanner.l"
return L1;
YY_BREAK
case 35:
YY_RULE_SETUP
-#line 279 "scanner.l"
+#line 293 "scanner.l"
return L2;
YY_BREAK
case 36:
YY_RULE_SETUP
-#line 280 "scanner.l"
+#line 294 "scanner.l"
return IIH;
YY_BREAK
case 37:
YY_RULE_SETUP
-#line 281 "scanner.l"
+#line 295 "scanner.l"
return LSP;
YY_BREAK
case 38:
YY_RULE_SETUP
-#line 282 "scanner.l"
+#line 296 "scanner.l"
return SNP;
YY_BREAK
case 39:
YY_RULE_SETUP
-#line 283 "scanner.l"
+#line 297 "scanner.l"
return CSNP;
YY_BREAK
case 40:
YY_RULE_SETUP
-#line 284 "scanner.l"
+#line 298 "scanner.l"
return PSNP;
YY_BREAK
case 41:
YY_RULE_SETUP
-#line 286 "scanner.l"
+#line 300 "scanner.l"
return CLNP;
YY_BREAK
case 42:
YY_RULE_SETUP
-#line 288 "scanner.l"
+#line 302 "scanner.l"
return STP;
YY_BREAK
case 43:
YY_RULE_SETUP
-#line 290 "scanner.l"
+#line 304 "scanner.l"
return IPX;
YY_BREAK
case 44:
YY_RULE_SETUP
-#line 292 "scanner.l"
+#line 306 "scanner.l"
return NETBEUI;
YY_BREAK
case 45:
YY_RULE_SETUP
-#line 294 "scanner.l"
+#line 308 "scanner.l"
return HOST;
YY_BREAK
case 46:
YY_RULE_SETUP
-#line 295 "scanner.l"
+#line 309 "scanner.l"
return NET;
YY_BREAK
case 47:
YY_RULE_SETUP
-#line 296 "scanner.l"
+#line 310 "scanner.l"
return NETMASK;
YY_BREAK
case 48:
YY_RULE_SETUP
-#line 297 "scanner.l"
+#line 311 "scanner.l"
return PORT;
YY_BREAK
case 49:
YY_RULE_SETUP
-#line 298 "scanner.l"
+#line 312 "scanner.l"
return PORTRANGE;
YY_BREAK
case 50:
YY_RULE_SETUP
-#line 299 "scanner.l"
+#line 313 "scanner.l"
return PROTO;
YY_BREAK
case 51:
YY_RULE_SETUP
-#line 300 "scanner.l"
+#line 314 "scanner.l"
{
#ifdef NO_PROTOCHAIN
bpf_error(yyextra, "%s not supported", yytext);
@@ -3383,353 +3567,353 @@ YY_RULE_SETUP
YY_BREAK
case 52:
YY_RULE_SETUP
-#line 308 "scanner.l"
+#line 322 "scanner.l"
return GATEWAY;
YY_BREAK
case 53:
YY_RULE_SETUP
-#line 310 "scanner.l"
+#line 324 "scanner.l"
return TYPE;
YY_BREAK
case 54:
YY_RULE_SETUP
-#line 311 "scanner.l"
+#line 325 "scanner.l"
return SUBTYPE;
YY_BREAK
case 55:
YY_RULE_SETUP
-#line 312 "scanner.l"
+#line 326 "scanner.l"
return DIR;
YY_BREAK
case 56:
YY_RULE_SETUP
-#line 313 "scanner.l"
+#line 327 "scanner.l"
return ADDR1;
YY_BREAK
case 57:
YY_RULE_SETUP
-#line 314 "scanner.l"
+#line 328 "scanner.l"
return ADDR2;
YY_BREAK
case 58:
YY_RULE_SETUP
-#line 315 "scanner.l"
+#line 329 "scanner.l"
return ADDR3;
YY_BREAK
case 59:
YY_RULE_SETUP
-#line 316 "scanner.l"
+#line 330 "scanner.l"
return ADDR4;
YY_BREAK
case 60:
YY_RULE_SETUP
-#line 317 "scanner.l"
+#line 331 "scanner.l"
return RA;
YY_BREAK
case 61:
YY_RULE_SETUP
-#line 318 "scanner.l"
+#line 332 "scanner.l"
return TA;
YY_BREAK
case 62:
YY_RULE_SETUP
-#line 320 "scanner.l"
+#line 334 "scanner.l"
return LESS;
YY_BREAK
case 63:
YY_RULE_SETUP
-#line 321 "scanner.l"
+#line 335 "scanner.l"
return GREATER;
YY_BREAK
case 64:
YY_RULE_SETUP
-#line 322 "scanner.l"
+#line 336 "scanner.l"
return CBYTE;
YY_BREAK
case 65:
YY_RULE_SETUP
-#line 323 "scanner.l"
+#line 337 "scanner.l"
return TK_BROADCAST;
YY_BREAK
case 66:
YY_RULE_SETUP
-#line 324 "scanner.l"
+#line 338 "scanner.l"
return TK_MULTICAST;
YY_BREAK
case 67:
YY_RULE_SETUP
-#line 326 "scanner.l"
+#line 340 "scanner.l"
return AND;
YY_BREAK
case 68:
YY_RULE_SETUP
-#line 327 "scanner.l"
+#line 341 "scanner.l"
return OR;
YY_BREAK
case 69:
YY_RULE_SETUP
-#line 328 "scanner.l"
+#line 342 "scanner.l"
return '!';
YY_BREAK
case 70:
YY_RULE_SETUP
-#line 330 "scanner.l"
+#line 344 "scanner.l"
return LEN;
YY_BREAK
case 71:
YY_RULE_SETUP
-#line 331 "scanner.l"
+#line 345 "scanner.l"
return INBOUND;
YY_BREAK
case 72:
YY_RULE_SETUP
-#line 332 "scanner.l"
+#line 346 "scanner.l"
return OUTBOUND;
YY_BREAK
case 73:
YY_RULE_SETUP
-#line 334 "scanner.l"
+#line 348 "scanner.l"
return VLAN;
YY_BREAK
case 74:
YY_RULE_SETUP
-#line 335 "scanner.l"
+#line 349 "scanner.l"
return MPLS;
YY_BREAK
case 75:
YY_RULE_SETUP
-#line 336 "scanner.l"
+#line 350 "scanner.l"
return PPPOED;
YY_BREAK
case 76:
YY_RULE_SETUP
-#line 337 "scanner.l"
+#line 351 "scanner.l"
return PPPOES;
YY_BREAK
case 77:
YY_RULE_SETUP
-#line 338 "scanner.l"
+#line 352 "scanner.l"
return GENEVE;
YY_BREAK
case 78:
YY_RULE_SETUP
-#line 340 "scanner.l"
+#line 354 "scanner.l"
return LANE;
YY_BREAK
case 79:
YY_RULE_SETUP
-#line 341 "scanner.l"
+#line 355 "scanner.l"
return LLC;
YY_BREAK
case 80:
YY_RULE_SETUP
-#line 342 "scanner.l"
+#line 356 "scanner.l"
return METAC;
YY_BREAK
case 81:
YY_RULE_SETUP
-#line 343 "scanner.l"
+#line 357 "scanner.l"
return BCC;
YY_BREAK
case 82:
YY_RULE_SETUP
-#line 344 "scanner.l"
+#line 358 "scanner.l"
return OAM;
YY_BREAK
case 83:
YY_RULE_SETUP
-#line 345 "scanner.l"
+#line 359 "scanner.l"
return OAMF4;
YY_BREAK
case 84:
YY_RULE_SETUP
-#line 346 "scanner.l"
+#line 360 "scanner.l"
return OAMF4EC;
YY_BREAK
case 85:
YY_RULE_SETUP
-#line 347 "scanner.l"
+#line 361 "scanner.l"
return OAMF4SC;
YY_BREAK
case 86:
YY_RULE_SETUP
-#line 348 "scanner.l"
+#line 362 "scanner.l"
return SC;
YY_BREAK
case 87:
YY_RULE_SETUP
-#line 349 "scanner.l"
+#line 363 "scanner.l"
return ILMIC;
YY_BREAK
case 88:
YY_RULE_SETUP
-#line 350 "scanner.l"
+#line 364 "scanner.l"
return VPI;
YY_BREAK
case 89:
YY_RULE_SETUP
-#line 351 "scanner.l"
+#line 365 "scanner.l"
return VCI;
YY_BREAK
case 90:
YY_RULE_SETUP
-#line 352 "scanner.l"
+#line 366 "scanner.l"
return CONNECTMSG;
YY_BREAK
case 91:
YY_RULE_SETUP
-#line 353 "scanner.l"
+#line 367 "scanner.l"
return METACONNECT;
YY_BREAK
case 92:
YY_RULE_SETUP
-#line 355 "scanner.l"
+#line 369 "scanner.l"
return PF_IFNAME;
YY_BREAK
case 93:
YY_RULE_SETUP
-#line 356 "scanner.l"
+#line 370 "scanner.l"
return PF_RSET;
YY_BREAK
case 94:
YY_RULE_SETUP
-#line 357 "scanner.l"
+#line 371 "scanner.l"
return PF_RNR;
YY_BREAK
case 95:
YY_RULE_SETUP
-#line 358 "scanner.l"
+#line 372 "scanner.l"
return PF_SRNR;
YY_BREAK
case 96:
YY_RULE_SETUP
-#line 359 "scanner.l"
+#line 373 "scanner.l"
return PF_REASON;
YY_BREAK
case 97:
YY_RULE_SETUP
-#line 360 "scanner.l"
+#line 374 "scanner.l"
return PF_ACTION;
YY_BREAK
case 98:
YY_RULE_SETUP
-#line 362 "scanner.l"
+#line 376 "scanner.l"
return FISU;
YY_BREAK
case 99:
YY_RULE_SETUP
-#line 363 "scanner.l"
+#line 377 "scanner.l"
return LSSU;
YY_BREAK
case 100:
YY_RULE_SETUP
-#line 364 "scanner.l"
+#line 378 "scanner.l"
return LSSU;
YY_BREAK
case 101:
YY_RULE_SETUP
-#line 365 "scanner.l"
+#line 379 "scanner.l"
return MSU;
YY_BREAK
case 102:
YY_RULE_SETUP
-#line 366 "scanner.l"
+#line 380 "scanner.l"
return HFISU;
YY_BREAK
case 103:
YY_RULE_SETUP
-#line 367 "scanner.l"
+#line 381 "scanner.l"
return HLSSU;
YY_BREAK
case 104:
YY_RULE_SETUP
-#line 368 "scanner.l"
+#line 382 "scanner.l"
return HMSU;
YY_BREAK
case 105:
YY_RULE_SETUP
-#line 369 "scanner.l"
+#line 383 "scanner.l"
return SIO;
YY_BREAK
case 106:
YY_RULE_SETUP
-#line 370 "scanner.l"
+#line 384 "scanner.l"
return OPC;
YY_BREAK
case 107:
YY_RULE_SETUP
-#line 371 "scanner.l"
+#line 385 "scanner.l"
return DPC;
YY_BREAK
case 108:
YY_RULE_SETUP
-#line 372 "scanner.l"
+#line 386 "scanner.l"
return SLS;
YY_BREAK
case 109:
YY_RULE_SETUP
-#line 373 "scanner.l"
+#line 387 "scanner.l"
return HSIO;
YY_BREAK
case 110:
YY_RULE_SETUP
-#line 374 "scanner.l"
+#line 388 "scanner.l"
return HOPC;
YY_BREAK
case 111:
YY_RULE_SETUP
-#line 375 "scanner.l"
+#line 389 "scanner.l"
return HDPC;
YY_BREAK
case 112:
YY_RULE_SETUP
-#line 376 "scanner.l"
+#line 390 "scanner.l"
return HSLS;
YY_BREAK
case 113:
/* rule 113 can match eol */
YY_RULE_SETUP
-#line 378 "scanner.l"
+#line 392 "scanner.l"
;
YY_BREAK
case 114:
YY_RULE_SETUP
-#line 379 "scanner.l"
+#line 393 "scanner.l"
return yytext[0];
YY_BREAK
case 115:
YY_RULE_SETUP
-#line 380 "scanner.l"
+#line 394 "scanner.l"
return GEQ;
YY_BREAK
case 116:
YY_RULE_SETUP
-#line 381 "scanner.l"
+#line 395 "scanner.l"
return LEQ;
YY_BREAK
case 117:
YY_RULE_SETUP
-#line 382 "scanner.l"
+#line 396 "scanner.l"
return NEQ;
YY_BREAK
case 118:
YY_RULE_SETUP
-#line 383 "scanner.l"
+#line 397 "scanner.l"
return '=';
YY_BREAK
case 119:
YY_RULE_SETUP
-#line 384 "scanner.l"
+#line 398 "scanner.l"
return LSH;
YY_BREAK
case 120:
YY_RULE_SETUP
-#line 385 "scanner.l"
+#line 399 "scanner.l"
return RSH;
YY_BREAK
case 121:
YY_RULE_SETUP
-#line 386 "scanner.l"
+#line 400 "scanner.l"
{ yylval->e = pcap_ether_aton(((char *)yytext)+1);
if (yylval->e == NULL)
bpf_error(yyextra, "malloc");
@@ -3737,7 +3921,7 @@ YY_RULE_SETUP
YY_BREAK
case 122:
YY_RULE_SETUP
-#line 390 "scanner.l"
+#line 404 "scanner.l"
{ yylval->e = pcap_ether_aton((char *)yytext);
if (yylval->e == NULL)
bpf_error(yyextra, "malloc");
@@ -3745,18 +3929,18 @@ YY_RULE_SETUP
YY_BREAK
case 123:
YY_RULE_SETUP
-#line 394 "scanner.l"
+#line 408 "scanner.l"
{ yylval->i = stoi((char *)yytext); return NUM; }
YY_BREAK
case 124:
YY_RULE_SETUP
-#line 395 "scanner.l"
+#line 409 "scanner.l"
{
yylval->s = sdup(yyextra, (char *)yytext); return HID; }
YY_BREAK
case 125:
YY_RULE_SETUP
-#line 397 "scanner.l"
+#line 411 "scanner.l"
{
#ifdef INET6
struct addrinfo hints, *res;
@@ -3776,157 +3960,302 @@ YY_RULE_SETUP
YY_BREAK
case 126:
YY_RULE_SETUP
-#line 413 "scanner.l"
+#line 427 "scanner.l"
{ bpf_error(yyextra, "bogus ethernet address %s", yytext); }
YY_BREAK
case 127:
YY_RULE_SETUP
-#line 414 "scanner.l"
+#line 428 "scanner.l"
{ yylval->i = 0; return NUM; }
YY_BREAK
case 128:
YY_RULE_SETUP
-#line 415 "scanner.l"
+#line 429 "scanner.l"
{ yylval->i = 1; return NUM; }
YY_BREAK
case 129:
YY_RULE_SETUP
-#line 416 "scanner.l"
+#line 430 "scanner.l"
{ yylval->i = 0; return NUM; }
YY_BREAK
case 130:
YY_RULE_SETUP
-#line 417 "scanner.l"
+#line 431 "scanner.l"
{ yylval->i = 3; return NUM; }
YY_BREAK
case 131:
YY_RULE_SETUP
-#line 418 "scanner.l"
+#line 432 "scanner.l"
{ yylval->i = 4; return NUM; }
YY_BREAK
case 132:
YY_RULE_SETUP
-#line 419 "scanner.l"
+#line 433 "scanner.l"
{ yylval->i = 5; return NUM; }
YY_BREAK
case 133:
YY_RULE_SETUP
-#line 420 "scanner.l"
+#line 434 "scanner.l"
{ yylval->i = 8; return NUM; }
YY_BREAK
case 134:
YY_RULE_SETUP
-#line 421 "scanner.l"
+#line 435 "scanner.l"
{ yylval->i = 9; return NUM; }
YY_BREAK
case 135:
YY_RULE_SETUP
-#line 422 "scanner.l"
+#line 436 "scanner.l"
{ yylval->i = 10; return NUM; }
YY_BREAK
case 136:
YY_RULE_SETUP
-#line 423 "scanner.l"
+#line 437 "scanner.l"
{ yylval->i = 11; return NUM; }
YY_BREAK
case 137:
YY_RULE_SETUP
-#line 424 "scanner.l"
+#line 438 "scanner.l"
{ yylval->i = 12; return NUM; }
YY_BREAK
case 138:
YY_RULE_SETUP
-#line 425 "scanner.l"
+#line 439 "scanner.l"
{ yylval->i = 13; return NUM; }
YY_BREAK
case 139:
YY_RULE_SETUP
-#line 426 "scanner.l"
+#line 440 "scanner.l"
{ yylval->i = 14; return NUM; }
YY_BREAK
case 140:
YY_RULE_SETUP
-#line 427 "scanner.l"
+#line 441 "scanner.l"
{ yylval->i = 15; return NUM; }
YY_BREAK
case 141:
YY_RULE_SETUP
-#line 428 "scanner.l"
+#line 442 "scanner.l"
{ yylval->i = 16; return NUM; }
YY_BREAK
case 142:
YY_RULE_SETUP
-#line 429 "scanner.l"
+#line 443 "scanner.l"
{ yylval->i = 17; return NUM; }
YY_BREAK
case 143:
YY_RULE_SETUP
-#line 430 "scanner.l"
+#line 444 "scanner.l"
{ yylval->i = 18; return NUM; }
YY_BREAK
case 144:
YY_RULE_SETUP
-#line 431 "scanner.l"
-{ yylval->i = 13; return NUM; }
+#line 446 "scanner.l"
+{ yylval->i = 0; return NUM; }
YY_BREAK
case 145:
YY_RULE_SETUP
-#line 432 "scanner.l"
-{ yylval->i = 0x01; return NUM; }
+#line 447 "scanner.l"
+{ yylval->i = 1; return NUM; }
YY_BREAK
case 146:
YY_RULE_SETUP
-#line 433 "scanner.l"
-{ yylval->i = 0x02; return NUM; }
+#line 449 "scanner.l"
+{ yylval->i = 128; return NUM; }
YY_BREAK
case 147:
YY_RULE_SETUP
-#line 434 "scanner.l"
-{ yylval->i = 0x04; return NUM; }
+#line 450 "scanner.l"
+{ yylval->i = 129; return NUM; }
YY_BREAK
case 148:
YY_RULE_SETUP
-#line 435 "scanner.l"
-{ yylval->i = 0x08; return NUM; }
+#line 451 "scanner.l"
+{ yylval->i = 130; return NUM; }
YY_BREAK
case 149:
YY_RULE_SETUP
-#line 436 "scanner.l"
-{ yylval->i = 0x10; return NUM; }
+#line 452 "scanner.l"
+{ yylval->i = 131; return NUM; }
YY_BREAK
case 150:
YY_RULE_SETUP
-#line 437 "scanner.l"
-{ yylval->i = 0x20; return NUM; }
+#line 453 "scanner.l"
+{ yylval->i = 132; return NUM; }
YY_BREAK
case 151:
YY_RULE_SETUP
-#line 438 "scanner.l"
+#line 454 "scanner.l"
+{ yylval->i = 133; return NUM; }
+ YY_BREAK
+case 152:
+YY_RULE_SETUP
+#line 455 "scanner.l"
+{ yylval->i = 134; return NUM; }
+ YY_BREAK
+case 153:
+YY_RULE_SETUP
+#line 456 "scanner.l"
+{ yylval->i = 135; return NUM; }
+ YY_BREAK
+case 154:
+YY_RULE_SETUP
+#line 457 "scanner.l"
+{ yylval->i = 136; return NUM; }
+ YY_BREAK
+case 155:
+YY_RULE_SETUP
+#line 458 "scanner.l"
+{ yylval->i = 137; return NUM; }
+ YY_BREAK
+case 156:
+YY_RULE_SETUP
+#line 459 "scanner.l"
+{ yylval->i = 138; return NUM; }
+ YY_BREAK
+case 157:
+YY_RULE_SETUP
+#line 460 "scanner.l"
+{ yylval->i = 139; return NUM; }
+ YY_BREAK
+case 158:
+YY_RULE_SETUP
+#line 461 "scanner.l"
+{ yylval->i = 140; return NUM; }
+ YY_BREAK
+case 159:
+YY_RULE_SETUP
+#line 462 "scanner.l"
+{ yylval->i = 141; return NUM; }
+ YY_BREAK
+case 160:
+YY_RULE_SETUP
+#line 463 "scanner.l"
+{ yylval->i = 142; return NUM; }
+ YY_BREAK
+case 161:
+YY_RULE_SETUP
+#line 464 "scanner.l"
+{ yylval->i = 143; return NUM; }
+ YY_BREAK
+case 162:
+YY_RULE_SETUP
+#line 465 "scanner.l"
+{ yylval->i = 144; return NUM; }
+ YY_BREAK
+case 163:
+YY_RULE_SETUP
+#line 466 "scanner.l"
+{ yylval->i = 145; return NUM; }
+ YY_BREAK
+case 164:
+YY_RULE_SETUP
+#line 467 "scanner.l"
+{ yylval->i = 146; return NUM; }
+ YY_BREAK
+case 165:
+YY_RULE_SETUP
+#line 468 "scanner.l"
+{ yylval->i = 147; return NUM; }
+ YY_BREAK
+case 166:
+YY_RULE_SETUP
+#line 469 "scanner.l"
+{ yylval->i = 148; return NUM; }
+ YY_BREAK
+case 167:
+YY_RULE_SETUP
+#line 470 "scanner.l"
+{ yylval->i = 149; return NUM; }
+ YY_BREAK
+case 168:
+YY_RULE_SETUP
+#line 471 "scanner.l"
+{ yylval->i = 151; return NUM; }
+ YY_BREAK
+case 169:
+YY_RULE_SETUP
+#line 472 "scanner.l"
+{ yylval->i = 152; return NUM; }
+ YY_BREAK
+case 170:
+YY_RULE_SETUP
+#line 473 "scanner.l"
+{ yylval->i = 153; return NUM; }
+ YY_BREAK
+case 171:
+YY_RULE_SETUP
+#line 475 "scanner.l"
+{ yylval->i = 13; return NUM; }
+ YY_BREAK
+case 172:
+YY_RULE_SETUP
+#line 476 "scanner.l"
+{ yylval->i = 0x01; return NUM; }
+ YY_BREAK
+case 173:
+YY_RULE_SETUP
+#line 477 "scanner.l"
+{ yylval->i = 0x02; return NUM; }
+ YY_BREAK
+case 174:
+YY_RULE_SETUP
+#line 478 "scanner.l"
+{ yylval->i = 0x04; return NUM; }
+ YY_BREAK
+case 175:
+YY_RULE_SETUP
+#line 479 "scanner.l"
+{ yylval->i = 0x08; return NUM; }
+ YY_BREAK
+case 176:
+YY_RULE_SETUP
+#line 480 "scanner.l"
+{ yylval->i = 0x10; return NUM; }
+ YY_BREAK
+case 177:
+YY_RULE_SETUP
+#line 481 "scanner.l"
+{ yylval->i = 0x20; return NUM; }
+ YY_BREAK
+case 178:
+YY_RULE_SETUP
+#line 482 "scanner.l"
+{ yylval->i = 0x40; return NUM; }
+ YY_BREAK
+case 179:
+YY_RULE_SETUP
+#line 483 "scanner.l"
+{ yylval->i = 0x80; return NUM; }
+ YY_BREAK
+case 180:
+YY_RULE_SETUP
+#line 484 "scanner.l"
{
yylval->s = sdup(yyextra, (char *)yytext); return ID; }
YY_BREAK
-case 152:
+case 181:
YY_RULE_SETUP
-#line 440 "scanner.l"
+#line 486 "scanner.l"
{ yylval->s = sdup(yyextra, (char *)yytext + 1); return ID; }
YY_BREAK
-case 153:
+case 182:
YY_RULE_SETUP
-#line 441 "scanner.l"
+#line 487 "scanner.l"
{
bpf_error(yyextra, "illegal token: %s", yytext); }
YY_BREAK
-case 154:
+case 183:
YY_RULE_SETUP
-#line 443 "scanner.l"
+#line 489 "scanner.l"
{ bpf_error(yyextra, "illegal char '%c'", *yytext); }
YY_BREAK
-case 155:
+case 184:
YY_RULE_SETUP
-#line 444 "scanner.l"
+#line 490 "scanner.l"
ECHO;
YY_BREAK
-#line 3930 "scanner.c"
+#line 4259 "scanner.c"
case YY_STATE_EOF(INITIAL):
yyterminate();
@@ -4071,9 +4400,9 @@ case YY_STATE_EOF(INITIAL):
static int yy_get_next_buffer (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
- register char *source = yyg->yytext_ptr;
- register int number_to_move, i;
+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ char *source = yyg->yytext_ptr;
+ int number_to_move, i;
int ret_val;
if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
@@ -4102,7 +4431,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
/* Try to read more data. */
/* First move last chars to start of buffer. */
- number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1);
for ( i = 0; i < number_to_move; ++i )
*(dest++) = *(source++);
@@ -4115,7 +4444,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else
{
- yy_size_t num_to_read =
+ int num_to_read =
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
while ( num_to_read <= 0 )
@@ -4129,7 +4458,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ( b->yy_is_our_buffer )
{
- yy_size_t new_size = b->yy_buf_size * 2;
+ int new_size = b->yy_buf_size * 2;
if ( new_size <= 0 )
b->yy_buf_size += b->yy_buf_size / 8;
@@ -4142,7 +4471,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
}
else
/* Can't grow it, we don't own it. */
- b->yy_ch_buf = 0;
+ b->yy_ch_buf = NULL;
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR(
@@ -4184,9 +4513,9 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else
ret_val = EOB_ACT_CONTINUE_SCAN;
- if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
/* Extend the array by 50%, plus the number we really need. */
- yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) pcap_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
@@ -4205,15 +4534,15 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
{
- register yy_state_type yy_current_state;
- register char *yy_cp;
+ yy_state_type yy_current_state;
+ char *yy_cp;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yy_current_state = yyg->yy_start;
for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
{
- register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
if ( yy_accept[yy_current_state] )
{
yyg->yy_last_accepting_state = yy_current_state;
@@ -4222,10 +4551,10 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 1464 )
+ if ( yy_current_state >= 1729 )
yy_c = yy_meta[(unsigned int) yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
}
return yy_current_state;
@@ -4238,11 +4567,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
*/
static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner)
{
- register int yy_is_jam;
+ int yy_is_jam;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
- register char *yy_cp = yyg->yy_c_buf_p;
+ char *yy_cp = yyg->yy_c_buf_p;
- register YY_CHAR yy_c = 1;
+ YY_CHAR yy_c = 1;
if ( yy_accept[yy_current_state] )
{
yyg->yy_last_accepting_state = yy_current_state;
@@ -4251,16 +4580,20 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 1464 )
+ if ( yy_current_state >= 1729 )
yy_c = yy_meta[(unsigned int) yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 1463);
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
+ yy_is_jam = (yy_current_state == 1728);
(void)yyg;
return yy_is_jam ? 0 : yy_current_state;
}
+#ifndef YY_NO_UNPUT
+
+#endif
+
#ifndef YY_NO_INPUT
#ifdef __cplusplus
static int yyinput (yyscan_t yyscanner)
@@ -4286,7 +4619,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else
{ /* need more input */
- yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+ int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
++yyg->yy_c_buf_p;
switch ( yy_get_next_buffer( yyscanner ) )
@@ -4310,7 +4643,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
case EOB_ACT_END_OF_FILE:
{
if ( pcap_wrap(yyscanner ) )
- return EOF;
+ return 0;
if ( ! yyg->yy_did_buffer_switch_on_eof )
YY_NEW_FILE;
@@ -4414,7 +4747,7 @@ static void pcap__load_buffer_state (yyscan_t yyscanner)
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in pcap__create_buffer()" );
- b->yy_buf_size = size;
+ b->yy_buf_size = (yy_size_t)size;
/* yy_ch_buf has to be 2 characters longer than the size given because
* we need to put in 2 end-of-buffer characters.
@@ -4566,7 +4899,7 @@ void pcap_pop_buffer_state (yyscan_t yyscanner)
*/
static void pcap_ensure_buffer_stack (yyscan_t yyscanner)
{
- yy_size_t num_to_alloc;
+ int num_to_alloc;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if (!yyg->yy_buffer_stack) {
@@ -4575,15 +4908,15 @@ static void pcap_ensure_buffer_stack (yyscan_t yyscanner)
* scanner will even need a stack. We use 2 instead of 1 to avoid an
* immediate realloc on the next call.
*/
- num_to_alloc = 1;
+ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
yyg->yy_buffer_stack = (struct yy_buffer_state**)pcap_alloc
(num_to_alloc * sizeof(struct yy_buffer_state*)
, yyscanner);
if ( ! yyg->yy_buffer_stack )
YY_FATAL_ERROR( "out of dynamic memory in pcap_ensure_buffer_stack()" );
-
+
memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
+
yyg->yy_buffer_stack_max = num_to_alloc;
yyg->yy_buffer_stack_top = 0;
return;
@@ -4592,7 +4925,7 @@ static void pcap_ensure_buffer_stack (yyscan_t yyscanner)
if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
/* Increase the buffer to prepare for a possible push. */
- int grow_size = 8 /* arbitrary grow size */;
+ yy_size_t grow_size = 8 /* arbitrary grow size */;
num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
yyg->yy_buffer_stack = (struct yy_buffer_state**)pcap_realloc
@@ -4612,7 +4945,7 @@ static void pcap_ensure_buffer_stack (yyscan_t yyscanner)
* @param base the character buffer
* @param size the size in bytes of the character buffer
* @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
+ * @return the newly allocated buffer state object.
*/
YY_BUFFER_STATE pcap__scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
{
@@ -4622,7 +4955,7 @@ YY_BUFFER_STATE pcap__scan_buffer (char * base, yy_size_t size , yyscan_t yysc
base[size-2] != YY_END_OF_BUFFER_CHAR ||
base[size-1] != YY_END_OF_BUFFER_CHAR )
/* They forgot to leave room for the EOB's. */
- return 0;
+ return NULL;
b = (YY_BUFFER_STATE) pcap_alloc(sizeof( struct yy_buffer_state ) ,yyscanner );
if ( ! b )
@@ -4631,7 +4964,7 @@ YY_BUFFER_STATE pcap__scan_buffer (char * base, yy_size_t size , yyscan_t yysc
b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
b->yy_buf_pos = b->yy_ch_buf = base;
b->yy_is_our_buffer = 0;
- b->yy_input_file = 0;
+ b->yy_input_file = NULL;
b->yy_n_chars = b->yy_buf_size;
b->yy_is_interactive = 0;
b->yy_at_bol = 1;
@@ -4654,7 +4987,7 @@ YY_BUFFER_STATE pcap__scan_buffer (char * base, yy_size_t size , yyscan_t yysc
YY_BUFFER_STATE pcap__scan_string (yyconst char * yystr , yyscan_t yyscanner)
{
- return pcap__scan_bytes(yystr,strlen(yystr) ,yyscanner);
+ return pcap__scan_bytes(yystr,(int) strlen(yystr) ,yyscanner);
}
/** Setup the input buffer state to scan the given bytes. The next call to pcap_lex() will
@@ -4664,15 +4997,15 @@ YY_BUFFER_STATE pcap__scan_string (yyconst char * yystr , yyscan_t yyscanner)
* @param yyscanner The scanner object.
* @return the newly allocated buffer state object.
*/
-YY_BUFFER_STATE pcap__scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner)
+YY_BUFFER_STATE pcap__scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
char *buf;
yy_size_t n;
- yy_size_t i;
+ int i;
/* Get memory for full buffer, including space for trailing EOB's. */
- n = _yybytes_len + 2;
+ n = (yy_size_t) (_yybytes_len + 2);
buf = (char *) pcap_alloc(n ,yyscanner );
if ( ! buf )
YY_FATAL_ERROR( "out of dynamic memory in pcap__scan_bytes()" );
@@ -4698,9 +5031,11 @@ YY_BUFFER_STATE pcap__scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_l
#define YY_EXIT_FAILURE 2
#endif
-static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+static void yynoreturn yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
{
- (void) fprintf( stderr, "%s\n", msg );
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+ (void) fprintf( stderr, "%s\n", msg );
exit( YY_EXIT_FAILURE );
}
@@ -4738,7 +5073,7 @@ YY_EXTRA_TYPE pcap_get_extra (yyscan_t yyscanner)
int pcap_get_lineno (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
+
if (! YY_CURRENT_BUFFER)
return 0;
@@ -4751,7 +5086,7 @@ int pcap_get_lineno (yyscan_t yyscanner)
int pcap_get_column (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
+
if (! YY_CURRENT_BUFFER)
return 0;
@@ -4779,7 +5114,7 @@ FILE *pcap_get_out (yyscan_t yyscanner)
/** Get the length of the current token.
* @param yyscanner The scanner object.
*/
-yy_size_t pcap_get_leng (yyscan_t yyscanner)
+int pcap_get_leng (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyleng;
@@ -4806,10 +5141,10 @@ void pcap_set_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
}
/** Set the current line number.
- * @param line_number
+ * @param _line_number line number
* @param yyscanner The scanner object.
*/
-void pcap_set_lineno (int line_number , yyscan_t yyscanner)
+void pcap_set_lineno (int _line_number , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
@@ -4817,14 +5152,14 @@ void pcap_set_lineno (int line_number , yyscan_t yyscanner)
if (! YY_CURRENT_BUFFER )
YY_FATAL_ERROR( "pcap_set_lineno called with no buffer" );
- yylineno = line_number;
+ yylineno = _line_number;
}
/** Set the current column.
- * @param line_number
+ * @param _column_no column number
* @param yyscanner The scanner object.
*/
-void pcap_set_column (int column_no , yyscan_t yyscanner)
+void pcap_set_column (int _column_no , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
@@ -4832,25 +5167,25 @@ void pcap_set_column (int column_no , yyscan_t yyscanner)
if (! YY_CURRENT_BUFFER )
YY_FATAL_ERROR( "pcap_set_column called with no buffer" );
- yycolumn = column_no;
+ yycolumn = _column_no;
}
/** Set the input stream. This does not discard the current
* input buffer.
- * @param in_str A readable stream.
+ * @param _in_str A readable stream.
* @param yyscanner The scanner object.
* @see pcap__switch_to_buffer
*/
-void pcap_set_in (FILE * in_str , yyscan_t yyscanner)
+void pcap_set_in (FILE * _in_str , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyin = in_str ;
+ yyin = _in_str ;
}
-void pcap_set_out (FILE * out_str , yyscan_t yyscanner)
+void pcap_set_out (FILE * _out_str , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyout = out_str ;
+ yyout = _out_str ;
}
int pcap_get_debug (yyscan_t yyscanner)
@@ -4859,10 +5194,10 @@ int pcap_get_debug (yyscan_t yyscanner)
return yy_flex_debug;
}
-void pcap_set_debug (int bdebug , yyscan_t yyscanner)
+void pcap_set_debug (int _bdebug , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yy_flex_debug = bdebug ;
+ yy_flex_debug = _bdebug ;
}
/* Accessor methods for yylval and yylloc */
@@ -4926,20 +5261,20 @@ int pcap_lex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
errno = EINVAL;
return 1;
}
-
+
*ptr_yy_globals = (yyscan_t) pcap_alloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
-
+
if (*ptr_yy_globals == NULL){
errno = ENOMEM;
return 1;
}
-
+
/* By setting to 0xAA, we expose bugs in
yy_init_globals. Leave at 0x00 for releases. */
memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
+
pcap_set_extra (yy_user_defined, *ptr_yy_globals);
-
+
return yy_init_globals ( *ptr_yy_globals );
}
@@ -4950,10 +5285,10 @@ static int yy_init_globals (yyscan_t yyscanner)
* This function is called from pcap_lex_destroy(), so don't allocate here.
*/
- yyg->yy_buffer_stack = 0;
+ yyg->yy_buffer_stack = NULL;
yyg->yy_buffer_stack_top = 0;
yyg->yy_buffer_stack_max = 0;
- yyg->yy_c_buf_p = (char *) 0;
+ yyg->yy_c_buf_p = NULL;
yyg->yy_init = 0;
yyg->yy_start = 0;
@@ -4966,8 +5301,8 @@ static int yy_init_globals (yyscan_t yyscanner)
yyin = stdin;
yyout = stdout;
#else
- yyin = (FILE *) 0;
- yyout = (FILE *) 0;
+ yyin = NULL;
+ yyout = NULL;
#endif
/* For future reference: Set errno on error, since we are called by
@@ -5013,7 +5348,10 @@ int pcap_lex_destroy (yyscan_t yyscanner)
#ifndef yytext_ptr
static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
{
- register int i;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+
+ int i;
for ( i = 0; i < n; ++i )
s1[i] = s2[i];
}
@@ -5022,7 +5360,7 @@ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yysca
#ifdef YY_NEED_STRLEN
static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
{
- register int n;
+ int n;
for ( n = 0; s[n]; ++n )
;
@@ -5032,11 +5370,16 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
void *pcap_alloc (yy_size_t size , yyscan_t yyscanner)
{
- return (void *) malloc( size );
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+ return malloc(size);
}
void *pcap_realloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+
/* The cast to (char *) in the following accommodates both
* implementations that use char* generic pointers, and those
* that use void* generic pointers. It works with the latter
@@ -5044,24 +5387,30 @@ void *pcap_realloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
* any pointer type to void*, and deal with argument conversions
* as though doing an assignment.
*/
- return (void *) realloc( (char *) ptr, size );
+ return realloc(ptr, size);
}
void pcap_free (void * ptr , yyscan_t yyscanner)
{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
free( (char *) ptr ); /* see pcap_realloc() for (char *) cast */
}
#define YYTABLES_NAME "yytables"
-#line 443 "scanner.l"
+#line 490 "scanner.l"
+/*
+ * 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';
@@ -5076,8 +5425,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/scanner.h b/scanner.h
index a8e5b0ae..dc464bd7 100644
--- a/scanner.h
+++ b/scanner.h
@@ -3,15 +3,34 @@
#define pcap_IN_HEADER 1
#line 6 "scanner.h"
-#line 2 "scanner.l"
/* 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"
-#line 15 "scanner.h"
+#line 34 "scanner.h"
#define YY_INT_ALIGNED short int
@@ -19,8 +38,8 @@
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 39
+#define YY_FLEX_MINOR_VERSION 6
+#define YY_FLEX_SUBMINOR_VERSION 1
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
@@ -99,25 +118,13 @@ typedef unsigned int flex_uint32_t;
#endif /* ! FLEXINT_H */
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else /* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif /* defined (__STDC__) */
-#endif /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
+/* TODO: this is always defined, so inline it */
#define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define yynoreturn __attribute__((__noreturn__))
#else
-#define yyconst
+#define yynoreturn
#endif
/* An opaque pointer. */
@@ -172,12 +179,12 @@ struct yy_buffer_state
/* Size of input buffer in bytes, not including room for EOB
* characters.
*/
- yy_size_t yy_buf_size;
+ int yy_buf_size;
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
*/
- yy_size_t yy_n_chars;
+ int yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to
@@ -200,7 +207,7 @@ struct yy_buffer_state
int yy_bs_lineno; /**< The line count. */
int yy_bs_column; /**< The column count. */
-
+
/* Whether to try to fill the input buffer when we reach the
* end of it.
*/
@@ -221,7 +228,7 @@ void pcap_pop_buffer_state (yyscan_t yyscanner );
YY_BUFFER_STATE pcap__scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
YY_BUFFER_STATE pcap__scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE pcap__scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner );
+YY_BUFFER_STATE pcap__scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
void *pcap_alloc (yy_size_t ,yyscan_t yyscanner );
void *pcap_realloc (void *,yy_size_t ,yyscan_t yyscanner );
@@ -229,7 +236,7 @@ void pcap_free (void * ,yyscan_t yyscanner );
/* Begin user sect3 */
-#define pcap_wrap(yyscanner) 1
+#define pcap_wrap(yyscanner) (/*CONSTCOND*/1)
#define YY_SKIP_YYWRAP
#define yytext_ptr yytext_r
@@ -268,23 +275,23 @@ void pcap_set_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
FILE *pcap_get_in (yyscan_t yyscanner );
-void pcap_set_in (FILE * in_str ,yyscan_t yyscanner );
+void pcap_set_in (FILE * _in_str ,yyscan_t yyscanner );
FILE *pcap_get_out (yyscan_t yyscanner );
-void pcap_set_out (FILE * out_str ,yyscan_t yyscanner );
+void pcap_set_out (FILE * _out_str ,yyscan_t yyscanner );
-yy_size_t pcap_get_leng (yyscan_t yyscanner );
+ int pcap_get_leng (yyscan_t yyscanner );
char *pcap_get_text (yyscan_t yyscanner );
int pcap_get_lineno (yyscan_t yyscanner );
-void pcap_set_lineno (int line_number ,yyscan_t yyscanner );
+void pcap_set_lineno (int _line_number ,yyscan_t yyscanner );
int pcap_get_column (yyscan_t yyscanner );
-void pcap_set_column (int column_no ,yyscan_t yyscanner );
+void pcap_set_column (int _column_no ,yyscan_t yyscanner );
YYSTYPE * pcap_get_lval (yyscan_t yyscanner );
@@ -356,9 +363,9 @@ extern int pcap_lex \
#undef YY_DECL
#endif
-#line 443 "scanner.l"
+#line 490 "scanner.l"
-#line 363 "scanner.h"
+#line 370 "scanner.h"
#undef pcap_IN_HEADER
#endif /* pcap_HEADER_H */
diff --git a/scanner.l b/scanner.l
index 1000b7a3..e0890b43 100644
--- a/scanner.l
+++ b/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"
}
/*
@@ -63,20 +85,6 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#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>
@@ -96,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
*
@@ -115,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" */
@@ -141,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]+)
@@ -428,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; }
@@ -435,6 +479,8 @@ tcp-rst { yylval->i = 0x04; return NUM; }
tcp-push { yylval->i = 0x08; return NUM; }
tcp-ack { yylval->i = 0x10; return NUM; }
tcp-urg { yylval->i = 0x20; return NUM; }
+tcp-ece { yylval->i = 0x40; return NUM; }
+tcp-cwr { yylval->i = 0x80; return NUM; }
[A-Za-z0-9]([-_.A-Za-z0-9]*[.A-Za-z0-9])? {
yylval->s = sdup(yyextra, (char *)yytext); return ID; }
"\\"[^ !()\n\t]+ { yylval->s = sdup(yyextra, (char *)yytext + 1); return ID; }
@@ -443,10 +489,14 @@ tcp-urg { yylval->i = 0x20; 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';
@@ -461,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/sf-pcap.c b/sf-pcap.c
index ac305d4b..96cb3080 100644
--- a/sf-pcap.c
+++ b/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/sf-pcap-ng.c b/sf-pcapng.c
index 0c02829e..8c8e93ec 100644
--- a/sf-pcap-ng.c
+++ b/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 */
};
@@ -214,19 +197,51 @@ typedef enum {
* Per-interface information.
*/
struct pcap_ng_if {
- u_int tsresol; /* time stamp resolution */
+ uint64_t 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 scale_factor; /* time stamp scale factor for power-of-10 tsresol */
+ 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 */
+ uint64_t 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);
}
@@ -409,13 +431,13 @@ 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)
+process_idb_options(pcap_t *p, struct block_cursor *cursor, uint64_t *tsresol,
+ uint64_t *tsoffset, int *is_binary, char *errbuf)
{
struct option_header *opthdr;
void *optvalue;
int saw_tsresol, saw_tsoffset;
- u_char tsresol_opt;
+ uint8_t tsresol_opt;
u_int i;
saw_tsresol = 0;
@@ -473,31 +495,42 @@ process_idb_options(pcap_t *p, struct block_cursor *cursor, u_int *tsresol,
/*
* Resolution is negative power of 2.
*/
+ uint8_t tsresol_shift = (tsresol_opt & 0x7F);
+
+ if (tsresol_shift > 63) {
+ /*
+ * Resolution is too high; 2^-{res}
+ * won't fit in a 64-bit value.
+ */
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Interface Description Block if_tsresol option resolution 2^-%u is too high",
+ tsresol_shift);
+ return (-1);
+ }
*is_binary = 1;
- *tsresol = 1 << (tsresol_opt & 0x7F);
+ *tsresol = ((uint64_t)1) << tsresol_shift;
} else {
/*
* Resolution is negative power of 10.
*/
- *is_binary = 0;
- *tsresol = 1;
- for (i = 0; i < tsresol_opt; i++)
- *tsresol *= 10;
- }
- if (*tsresol == 0) {
- /*
- * Resolution is too high.
- */
- if (tsresol_opt & 0x80) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "Interface Description Block if_tsresol option resolution 2^-%u is too high",
- tsresol_opt & 0x7F);
- } else {
+ if (tsresol_opt > 19) {
+ /*
+ * Resolution is too high; 2^-{res}
+ * won't fit in a 64-bit value (the
+ * largest power of 10 that fits
+ * in a 64-bit value is 10^19, as
+ * the largest 64-bit unsigned
+ * value is ~1.8*10^19).
+ */
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"Interface Description Block if_tsresol option resolution 10^-%u is too high",
tsresol_opt);
+ return (-1);
}
- return (-1);
+ *is_binary = 0;
+ *tsresol = 1;
+ for (i = 0; i < tsresol_opt; i++)
+ *tsresol *= 10;
}
break;
@@ -532,8 +565,8 @@ static int
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 tsresol;
+ uint64_t tsoffset;
int is_binary;
ps = p->priv;
@@ -567,7 +600,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 +732,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 +758,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 +767,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 +787,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 +818,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 +831,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 +839,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 +884,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 +900,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 +932,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 +981,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 +1011,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 +1073,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 +1109,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 +1174,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 +1289,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 +1328,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/sf-pcap-ng.h b/sf-pcapng.h
index 3c93498f..d99b0d4e 100644
--- a/sf-pcap-ng.h
+++ b/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/sockutils.c b/sockutils.c
index c05ff1a1..ef3fe764 100644
--- a/sockutils.c
+++ b/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) */
+ char message[SOCK_ERRBUF_SIZE]; /* We're forcing "ANSI" */
if (errbuf == NULL)
return;
- code = GetLastError();
-
- retval = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
+ retval = FormatMessageA(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/sockutils.h b/sockutils.h
index f50bbce8..1df1ef7b 100644
--- a/sockutils.h
+++ b/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/testprogs/.gitignore b/testprogs/.gitignore
new file mode 100644
index 00000000..b9178b4e
--- /dev/null
+++ b/testprogs/.gitignore
@@ -0,0 +1,13 @@
+Makefile
+*~
+*.dSYM
+*.o
+valgrindtest
+capturetest
+can_set_rfmon_test
+filtertest
+findalldevstest
+opentest
+reactivatetest
+selpolltest
+threadsignaltest
diff --git a/testprogs/BPF/1.txt b/testprogs/BPF/1.txt
new file mode 100644
index 00000000..66086952
--- /dev/null
+++ b/testprogs/BPF/1.txt
@@ -0,0 +1,2 @@
+# common block merging, same block elimination, result propogation
+host 192.168.1.1
diff --git a/testprogs/BPF/2.txt b/testprogs/BPF/2.txt
new file mode 100644
index 00000000..e9bc1165
--- /dev/null
+++ b/testprogs/BPF/2.txt
@@ -0,0 +1,2 @@
+# common block merging
+port 80
diff --git a/testprogs/BPF/3.txt b/testprogs/BPF/3.txt
new file mode 100644
index 00000000..6c08d3d0
--- /dev/null
+++ b/testprogs/BPF/3.txt
@@ -0,0 +1 @@
+tcp[tcpflags]&tcp-syn != 0 or tcp[tcpflags]&tcp-fin != 0 or tcp[tcpflags]&tcp-rst != 0
diff --git a/testprogs/BPF/4.txt b/testprogs/BPF/4.txt
new file mode 100644
index 00000000..3fd2e663
--- /dev/null
+++ b/testprogs/BPF/4.txt
@@ -0,0 +1,2 @@
+# or pullup
+ether[12:2] = 0x800 or ether[12:2] = 0x8100 or ether[0] & 0x80 != 0 or ether[12:2] = 0x9100
diff --git a/testprogs/BPF/5.txt b/testprogs/BPF/5.txt
new file mode 100644
index 00000000..23fc0ca5
--- /dev/null
+++ b/testprogs/BPF/5.txt
@@ -0,0 +1 @@
+vlan 186 and ip
diff --git a/testprogs/BPF/6.txt b/testprogs/BPF/6.txt
new file mode 100644
index 00000000..694c185b
--- /dev/null
+++ b/testprogs/BPF/6.txt
@@ -0,0 +1 @@
+ip and ((icmp and dst host 1.1.1.1 and not host 2.2.2.2) or (host 1.1.1.1 and src host 3.3.3.3))
diff --git a/testprogs/BPF/7.txt b/testprogs/BPF/7.txt
new file mode 100644
index 00000000..33978a4e
--- /dev/null
+++ b/testprogs/BPF/7.txt
@@ -0,0 +1 @@
+not vlan and tcp port 80
diff --git a/testprogs/CMakeLists.txt b/testprogs/CMakeLists.txt
new file mode 100644
index 00000000..b8ef9b7d
--- /dev/null
+++ b/testprogs/CMakeLists.txt
@@ -0,0 +1,40 @@
+if(MSVC)
+ file(GLOB PROJECT_SOURCE_LIST_WIN32_C ${pcap_SOURCE_DIR}/missing/getopt.c)
+ include_directories(${pcap_SOURCE_DIR}/missing)
+endif(MSVC)
+
+add_custom_target(testprogs)
+
+macro(add_test_executable _executable)
+ add_executable(${_executable} EXCLUDE_FROM_ALL
+ ${_executable}.c ${PROJECT_SOURCE_LIST_WIN32_C})
+ if(NOT C_ADDITIONAL_FLAGS STREQUAL "")
+ set_target_properties(${_executable} PROPERTIES
+ COMPILE_FLAGS ${C_ADDITIONAL_FLAGS})
+ endif()
+ if(WIN32)
+ target_link_libraries(${_executable}
+ ${ARGN} ${LIBRARY_NAME} ${PCAP_LINK_LIBRARIES})
+ else(WIN32)
+ target_link_libraries(${_executable}
+ ${ARGN} ${LIBRARY_NAME}_static ${PCAP_LINK_LIBRARIES})
+ endif(WIN32)
+ add_dependencies(testprogs ${_executable})
+endmacro()
+
+add_test_executable(can_set_rfmon_test)
+add_test_executable(capturetest)
+add_test_executable(filtertest)
+add_test_executable(findalldevstest)
+add_test_executable(opentest)
+add_test_executable(reactivatetest)
+
+if(NOT WIN32)
+ add_test_executable(selpolltest)
+endif()
+
+add_test_executable(threadsignaltest ${CMAKE_THREAD_LIBS_INIT})
+
+if(NOT WIN32)
+ add_test_executable(valgrindtest)
+endif()
diff --git a/testprogs/Makefile.in b/testprogs/Makefile.in
new file mode 100644
index 00000000..ec0a4720
--- /dev/null
+++ b/testprogs/Makefile.in
@@ -0,0 +1,144 @@
+# Copyright (c) 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.
+
+#
+# Various configurable paths (remember to edit Makefile.in, not Makefile)
+#
+
+# Top level hierarchy
+prefix = @prefix@
+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
+libdir = @libdir@
+# Pathname of directory to install the man pages
+mandir = @mandir@
+
+# VPATH
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+#
+# You shouldn't need to edit anything below.
+#
+
+LD = /usr/bin/ld
+CC = @CC@
+AR = @AR@
+LN_S = @LN_S@
+MKDEP = @MKDEP@
+CCOPT = @V_CCOPT@
+INCLS = -I. -I.. -I@srcdir@ -I@srcdir@/.. @V_INCLS@
+DEFS = @DEFS@ @V_DEFS@
+ADDLOBJS = @ADDLOBJS@
+ADDLARCHIVEOBJS = @ADDLARCHIVEOBJS@
+LIBS = @LIBS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+CROSSFLAGS=
+CFLAGS = @CFLAGS@ ${CROSSFLAGS}
+LDFLAGS = @LDFLAGS@ ${CROSSFLAGS}
+DYEXT = @DYEXT@
+V_RPATH_OPT = @V_RPATH_OPT@
+DEPENDENCY_CFLAG = @DEPENDENCY_CFLAG@
+EXTRA_NETWORK_LIBS=@EXTRA_NETWORK_LIBS@
+
+# Standard CFLAGS for building test programs
+FULL_CFLAGS = $(CCOPT) $(INCLS) $(DEFS) $(CFLAGS)
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+# Explicitly define compilation rule since SunOS 4's make doesn't like gcc.
+# Also, gcc does not remove the .o before forking 'as', which can be a
+# problem if you don't own the file but can write to the directory.
+.c.o:
+ @rm -f $@
+ $(CC) $(FULL_CFLAGS) -c $(srcdir)/$*.c
+
+SRC = @VALGRINDTEST_SRC@ \
+ capturetest.c \
+ can_set_rfmon_test.c \
+ filtertest.c \
+ findalldevstest.c \
+ opentest.c \
+ reactivatetest.c \
+ selpolltest.c \
+ threadsignaltest.c
+
+TESTS = $(SRC:.c=)
+
+TAGFILES = \
+ $(SRC) $(HDR)
+
+CLEANFILES = $(OBJ) $(TESTS)
+
+all: $(TESTS)
+
+capturetest: $(srcdir)/capturetest.c ../libpcap.a
+ $(CC) $(FULL_CFLAGS) -I. -L. -o capturetest $(srcdir)/capturetest.c ../libpcap.a $(LIBS)
+
+can_set_rfmon_test: $(srcdir)/can_set_rfmon_test.c ../libpcap.a
+ $(CC) $(FULL_CFLAGS) -I. -L. -o can_set_rfmon_test $(srcdir)/can_set_rfmon_test.c ../libpcap.a $(LIBS)
+
+filtertest: $(srcdir)/filtertest.c ../libpcap.a
+ $(CC) $(FULL_CFLAGS) -I. -L. -o filtertest $(srcdir)/filtertest.c ../libpcap.a $(EXTRA_NETWORK_LIBS) $(LIBS)
+
+findalldevstest: $(srcdir)/findalldevstest.c ../libpcap.a
+ $(CC) $(FULL_CFLAGS) -I. -L. -o findalldevstest $(srcdir)/findalldevstest.c ../libpcap.a $(EXTRA_NETWORK_LIBS) $(LIBS)
+
+opentest: $(srcdir)/opentest.c ../libpcap.a
+ $(CC) $(FULL_CFLAGS) -I. -L. -o opentest $(srcdir)/opentest.c ../libpcap.a $(LIBS)
+
+reactivatetest: $(srcdir)/reactivatetest.c ../libpcap.a
+ $(CC) $(FULL_CFLAGS) -I. -L. -o reactivatetest $(srcdir)/reactivatetest.c ../libpcap.a $(LIBS)
+
+selpolltest: $(srcdir)/selpolltest.c ../libpcap.a
+ $(CC) $(FULL_CFLAGS) -I. -L. -o selpolltest $(srcdir)/selpolltest.c ../libpcap.a $(LIBS)
+
+threadsignaltest: $(srcdir)/threadsignaltest.c ../libpcap.a
+ $(CC) $(FULL_CFLAGS) -I. -L. -o threadsignaltest $(srcdir)/threadsignaltest.c ../libpcap.a $(LIBS) $(PTHREAD_LIBS)
+
+valgrindtest: $(srcdir)/valgrindtest.c ../libpcap.a
+ $(CC) $(FULL_CFLAGS) -I. -L. -o valgrindtest $(srcdir)/valgrindtest.c ../libpcap.a $(LIBS)
+
+clean:
+ rm -f $(CLEANFILES)
+ rm -rf *.dSYM
+
+distclean: clean
+ rm -f Makefile config.cache config.log config.status \
+ config.h stamp-h stamp-h.in
+ rm -rf autom4te.cache
+
+install:
+
+uninstall:
+
+tags: $(TAGFILES)
+ ctags -wtd $(TAGFILES)
+
+depend:
+ ../$(MKDEP) -c "$(CC)" -m "$(DEPENDENCY_CFLAG)" $(CFLAGS) $(DEFS) $(INCLS) $(SRC)
diff --git a/tests/can_set_rfmon_test.c b/testprogs/can_set_rfmon_test.c
index f1644e66..f6188ba1 100644
--- a/tests/can_set_rfmon_test.c
+++ b/testprogs/can_set_rfmon_test.c
@@ -19,6 +19,8 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
+#include "varattrs.h"
+
#ifndef lint
static const char copyright[] _U_ =
"@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
@@ -32,10 +34,12 @@ The Regents of the University of California. All rights reserved.\n";
#include <pcap.h>
+#include "pcap/funcattrs.h"
+
static const char *program_name;
/* Forwards */
-static void error(const char *, ...);
+static void PCAP_NORETURN error(PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(1,2);
int
main(int argc, char **argv)
diff --git a/tests/capturetest.c b/testprogs/capturetest.c
index 14b1554b..d625cb4a 100644
--- a/tests/capturetest.c
+++ b/testprogs/capturetest.c
@@ -19,6 +19,8 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
+#include "varattrs.h"
+
#ifndef lint
static const char copyright[] _U_ =
"@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
@@ -31,65 +33,22 @@ The Regents of the University of California. All rights reserved.\n";
#include <stdarg.h>
#include <limits.h>
#ifdef _WIN32
-#include "getopt.h"
+ #include "getopt.h"
#else
-#include <unistd.h>
+ #include <unistd.h>
#endif
#include <errno.h>
#include <sys/types.h>
#include <pcap.h>
-static char *program_name;
+#include "pcap/funcattrs.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
+#ifdef _WIN32
+ #include "portability.h"
#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 countme(u_char *, const struct pcap_pkthdr *, const u_char *);
@@ -110,6 +69,7 @@ main(int argc, char **argv)
int timeout = 1000;
int immediate = 0;
int nonblock = 0;
+ pcap_if_t *devlist;
bpf_u_int32 localnet, netmask;
struct bpf_program fcode;
char ebuf[PCAP_ERRBUF_SIZE];
@@ -164,9 +124,12 @@ main(int argc, char **argv)
}
if (device == NULL) {
- device = pcap_lookupdev(ebuf);
- if (device == NULL)
+ if (pcap_findalldevs(&devlist, ebuf) == -1)
error("%s", ebuf);
+ if (devlist == NULL)
+ error("no interfaces available for capture");
+ device = strdup(devlist->name);
+ pcap_freealldevs(devlist);
}
*ebuf = '\0';
pd = pcap_create(device, ebuf);
@@ -244,11 +207,13 @@ main(int argc, char **argv)
program_name, pcap_geterr(pd));
}
pcap_close(pd);
+ pcap_freecode(&fcode);
+ free(cmdbuf);
exit(status == -1 ? 1 : 0);
}
static void
-countme(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
+countme(u_char *user, const struct pcap_pkthdr *h _U_, const u_char *sp _U_)
{
int *counterp = (int *)user;
diff --git a/tests/filtertest.c b/testprogs/filtertest.c
index d4440eb0..7e2d6d6e 100644
--- a/tests/filtertest.c
+++ b/testprogs/filtertest.c
@@ -19,6 +19,8 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
+#include "varattrs.h"
+
#ifndef lint
static const char copyright[] _U_ =
"@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
@@ -26,7 +28,7 @@ The Regents of the University of California. All rights reserved.\n";
#endif
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <pcap.h>
@@ -35,68 +37,35 @@ The Regents of the University of California. All rights reserved.\n";
#include <string.h>
#include <stdarg.h>
#ifdef _WIN32
-#include "getopt.h"
+ #include "getopt.h"
+ #include "unix.h"
#else
-#include <unistd.h>
+ #include <unistd.h>
#endif
#include <fcntl.h>
#include <errno.h>
#ifdef _WIN32
#include <winsock2.h>
- typedef unsigned __int32 in_addr_t;
+ #include <ws2tcpip.h>
#else
+ #include <sys/socket.h>
#include <arpa/inet.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
+#include "pcap/funcattrs.h"
+
+#ifdef BDEBUG
/*
- * 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.
+ * We have pcap_set_optimizer_debug() and pcap_set_print_dot_graph() in
+ * libpcap; declare them (they're not declared by any libpcap header,
+ * because they're special hacks, only available if libpcap was configured
+ * to include them, and only intended for use by libpcap developers trying
+ * to debug the optimizer for filter expressions).
*/
-#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)
+PCAP_API void pcap_set_optimizer_debug(int);
+PCAP_API void pcap_set_print_dot_graph(int);
#endif
static char *program_name;
@@ -106,10 +75,6 @@ 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()".
@@ -230,32 +195,27 @@ main(int argc, char **argv)
{
char *cp;
int op;
-#ifndef BDEBUG
int dflag;
-#endif
+ int gflag;
char *infile;
int Oflag;
long snaplen;
char *p;
int dlt;
+ int have_fcode = 0;
bpf_u_int32 netmask = PCAP_NETMASK_UNKNOWN;
char *cmdbuf;
pcap_t *pd;
struct bpf_program fcode;
#ifdef _WIN32
- if(wsockinit() != 0) return 1;
+ if (pcap_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
+ gflag = 0;
+
infile = NULL;
Oflag = 1;
snaplen = 68;
@@ -266,13 +226,21 @@ main(int argc, char **argv)
program_name = argv[0];
opterr = 0;
- while ((op = getopt(argc, argv, "dF:m:Os:")) != -1) {
+ while ((op = getopt(argc, argv, "dF:gm:Os:")) != -1) {
switch (op) {
case 'd':
++dflag;
break;
+ case 'g':
+#ifdef BDEBUG
+ ++gflag;
+#else
+ error("libpcap and filtertest not built with optimizer debugging enabled");
+#endif
+ break;
+
case 'F':
infile = optarg;
break;
@@ -282,12 +250,23 @@ main(int argc, char **argv)
break;
case 'm': {
- in_addr_t addr;
+ bpf_u_int32 addr;
- addr = inet_addr(optarg);
- if (addr == (in_addr_t)(-1))
+ switch (inet_pton(AF_INET, optarg, &addr)) {
+
+ case 0:
error("invalid netmask %s", optarg);
- netmask = addr;
+ break;
+
+ case -1:
+ error("invalid netmask %s: %s", optarg,
+ pcap_strerror(errno));
+ break;
+
+ case 1:
+ netmask = addr;
+ break;
+ }
break;
}
@@ -326,6 +305,11 @@ main(int argc, char **argv)
else
cmdbuf = copy_argv(&argv[optind+1]);
+#ifdef BDEBUG
+ pcap_set_optimizer_debug(dflag);
+ pcap_set_print_dot_graph(gflag);
+#endif
+
pd = pcap_open_dead(dlt, snaplen);
if (pd == NULL)
error("Can't open fake pcap_t");
@@ -333,21 +317,28 @@ main(int argc, char **argv)
if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)
error("%s", pcap_geterr(pd));
+ have_fcode = 1;
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 = ' ';
+ if (cmdbuf != NULL) {
+ // 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);
+ // only show machine code if BDEBUG defined, since dflag > 3
+ printf("machine codes for filter: %s\n", cmdbuf);
+ } else
+ printf("machine codes for empty filter:\n");
#endif
bpf_dump(&fcode, dflag);
+ free(cmdbuf);
+ if (have_fcode)
+ pcap_freecode (&fcode);
pcap_close(pd);
exit(0);
}
@@ -358,7 +349,11 @@ usage(void)
(void)fprintf(stderr, "%s, with %s\n", program_name,
pcap_lib_version());
(void)fprintf(stderr,
+#ifdef BDEBUG
+ "Usage: %s [-dgO] [ -F file ] [ -m netmask] [ -s snaplen ] dlt [ expression ]\n",
+#else
"Usage: %s [-dO] [ -F file ] [ -m netmask] [ -s snaplen ] dlt [ expression ]\n",
+#endif
program_name);
exit(1);
}
diff --git a/testprogs/findalldevstest.c b/testprogs/findalldevstest.c
new file mode 100644
index 00000000..e535e254
--- /dev/null
+++ b/testprogs/findalldevstest.c
@@ -0,0 +1,311 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#ifdef _WIN32
+ #include <winsock2.h>
+ #include <ws2tcpip.h>
+ #include <windows.h>
+#else
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <netdb.h>
+ #include <unistd.h>
+#endif
+
+#include <pcap.h>
+
+#include "pcap/funcattrs.h"
+
+static int ifprint(pcap_if_t *d);
+static char *iptos(bpf_u_int32 in);
+
+#ifdef _WIN32
+#include "portability.h"
+
+/*
+ * Generate a string for a Win32-specific error (i.e. an error generated when
+ * calling a Win32 API).
+ * For errors occurred during standard C calls, we still use pcap_strerror()
+ */
+#define ERRBUF_SIZE 1024
+static const char *
+win32_strerror(DWORD error)
+{
+ static char errbuf[ERRBUF_SIZE+1];
+ size_t errlen;
+
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
+ ERRBUF_SIZE, NULL);
+
+ /*
+ * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
+ * message. Get rid of it.
+ */
+ errlen = strlen(errbuf);
+ if (errlen >= 2) {
+ errbuf[errlen - 1] = '\0';
+ errbuf[errlen - 2] = '\0';
+ errlen -= 2;
+ }
+ return errbuf;
+}
+
+static char *
+getpass(const char *prompt)
+{
+ HANDLE console_handle = GetStdHandle(STD_INPUT_HANDLE);
+ DWORD console_mode, save_console_mode;
+ static char password[128+1];
+ char *p;
+
+ fprintf(stderr, "%s", prompt);
+
+ /*
+ * Turn off echoing.
+ */
+ if (!GetConsoleMode(console_handle, &console_mode)) {
+ fprintf(stderr, "Can't get console mode: %s\n",
+ win32_strerror(GetLastError()));
+ exit(1);
+ }
+ save_console_mode = console_mode;
+ console_mode &= ~ENABLE_ECHO_INPUT;
+ if (!SetConsoleMode(console_handle, console_mode)) {
+ fprintf(stderr, "Can't set console mode: %s\n",
+ win32_strerror(GetLastError()));
+ exit(1);
+ }
+ if (fgets(password, sizeof password, stdin) == NULL) {
+ fprintf(stderr, "\n");
+ SetConsoleMode(console_handle, save_console_mode);
+ exit(1);
+ }
+ fprintf(stderr, "\n");
+ SetConsoleMode(console_handle, save_console_mode);
+ p = strchr(password, '\n');
+ if (p != NULL)
+ *p = '\0';
+ return password;
+}
+#endif
+
+int main(int argc, char **argv)
+{
+ pcap_if_t *alldevs;
+ pcap_if_t *d;
+ bpf_u_int32 net, mask;
+ int exit_status = 0;
+ char errbuf[PCAP_ERRBUF_SIZE+1];
+#ifdef ENABLE_REMOTE
+ struct pcap_rmtauth auth;
+ char username[128+1];
+ char *p;
+ char *password;
+#endif
+
+#ifdef ENABLE_REMOTE
+ if (argc >= 2)
+ {
+ if (pcap_findalldevs_ex(argv[1], NULL, &alldevs, errbuf) == -1)
+ {
+ /*
+ * OK, try it with a user name and password.
+ */
+ fprintf(stderr, "User name: ");
+ if (fgets(username, sizeof username, stdin) == NULL)
+ exit(1);
+ p = strchr(username, '\n');
+ if (p != NULL)
+ *p = '\0';
+ password = getpass("Password: ");
+ auth.type = RPCAP_RMTAUTH_PWD;
+ auth.username = username;
+ auth.password = password;
+ if (pcap_findalldevs_ex(argv[1], &auth, &alldevs, errbuf) == -1)
+ {
+ fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
+ exit(1);
+ }
+ }
+ }
+ else
+#endif
+ {
+ 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 (alldevs != NULL)
+ {
+ if (pcap_lookupnet(alldevs->name, &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));
+ }
+ }
+
+ pcap_freealldevs(alldevs);
+ exit(exit_status);
+}
+
+static int ifprint(pcap_if_t *d)
+{
+ pcap_addr_t *a;
+ char ipv4_buf[INET_ADDRSTRLEN];
+ char ipv6_buf[INET6_ADDRSTRLEN];
+ 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 = ", ";
+ }
+ if (d->flags & PCAP_IF_WIRELESS) {
+ printf("%sWIRELESS", sep);
+ switch (d->flags & PCAP_IF_CONNECTION_STATUS) {
+
+ case PCAP_IF_CONNECTION_STATUS_UNKNOWN:
+ printf(" (association status unknown)");
+ break;
+
+ case PCAP_IF_CONNECTION_STATUS_CONNECTED:
+ printf(" (associated)");
+ break;
+
+ case PCAP_IF_CONNECTION_STATUS_DISCONNECTED:
+ printf(" (not associated)");
+ break;
+
+ case PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE:
+ break;
+ }
+ } else {
+ switch (d->flags & PCAP_IF_CONNECTION_STATUS) {
+
+ case PCAP_IF_CONNECTION_STATUS_UNKNOWN:
+ printf(" (connection status unknown)");
+ break;
+
+ case PCAP_IF_CONNECTION_STATUS_CONNECTED:
+ printf(" (connected)");
+ break;
+
+ case PCAP_IF_CONNECTION_STATUS_DISCONNECTED:
+ printf(" (disconnected)");
+ break;
+
+ case PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE:
+ break;
+ }
+ }
+ 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_ntop(AF_INET,
+ &((struct sockaddr_in *)(a->addr))->sin_addr,
+ ipv4_buf, sizeof ipv4_buf));
+ if (a->netmask)
+ printf("\t\tNetmask: %s\n",
+ inet_ntop(AF_INET,
+ &((struct sockaddr_in *)(a->netmask))->sin_addr,
+ ipv4_buf, sizeof ipv4_buf));
+ if (a->broadaddr)
+ printf("\t\tBroadcast Address: %s\n",
+ inet_ntop(AF_INET,
+ &((struct sockaddr_in *)(a->broadaddr))->sin_addr,
+ ipv4_buf, sizeof ipv4_buf));
+ if (a->dstaddr)
+ printf("\t\tDestination Address: %s\n",
+ inet_ntop(AF_INET,
+ &((struct sockaddr_in *)(a->dstaddr))->sin_addr,
+ ipv4_buf, sizeof ipv4_buf));
+ 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,
+ ipv6_buf, sizeof ipv6_buf));
+ if (a->netmask)
+ printf("\t\tNetmask: %s\n",
+ inet_ntop(AF_INET6,
+ ((struct sockaddr_in6 *)(a->netmask))->sin6_addr.s6_addr,
+ ipv6_buf, sizeof ipv6_buf));
+ if (a->broadaddr)
+ printf("\t\tBroadcast Address: %s\n",
+ inet_ntop(AF_INET6,
+ ((struct sockaddr_in6 *)(a->broadaddr))->sin6_addr.s6_addr,
+ ipv6_buf, sizeof ipv6_buf));
+ if (a->dstaddr)
+ printf("\t\tDestination Address: %s\n",
+ inet_ntop(AF_INET6,
+ ((struct sockaddr_in6 *)(a->dstaddr))->sin6_addr.s6_addr,
+ ipv6_buf, sizeof ipv6_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/tests/opentest.c b/testprogs/opentest.c
index b6d634f0..bad38eb0 100644
--- a/tests/opentest.c
+++ b/testprogs/opentest.c
@@ -19,6 +19,8 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
+#include "varattrs.h"
+
#ifndef lint
static const char copyright[] _U_ =
"@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
@@ -31,64 +33,21 @@ The Regents of the University of California. All rights reserved.\n";
#include <string.h>
#include <stdarg.h>
#ifdef _WIN32
-#include "getopt.h"
+ #include "getopt.h"
#else
-#include <unistd.h>
+ #include <unistd.h>
#endif
#include <errno.h>
-#define MAXIMUM_SNAPLEN 65535
-
-static char *program_name;
+#include "pcap/funcattrs.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
+#ifdef _WIN32
+ #include "portability.h"
#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
+#define MAXIMUM_SNAPLEN 65535
-#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);
@@ -102,6 +61,7 @@ main(int argc, char **argv)
register char *cp, *device;
int dorfmon, dopromisc, snaplen, useactivate, bufsize;
char ebuf[PCAP_ERRBUF_SIZE];
+ pcap_if_t *devlist;
pcap_t *pd;
int status = 0;
@@ -163,9 +123,12 @@ main(int argc, char **argv)
}
if (device == NULL) {
- device = pcap_lookupdev(ebuf);
- if (device == NULL)
- error("pcap_lookupdev failed: %s", ebuf);
+ if (pcap_findalldevs(&devlist, ebuf) == -1)
+ error("%s", ebuf);
+ if (devlist == NULL)
+ error("no interfaces available for capture");
+ device = strdup(devlist->name);
+ pcap_freealldevs(devlist);
}
if (useactivate) {
pd = pcap_create(device, ebuf);
diff --git a/testprogs/pcap_compile_test.c b/testprogs/pcap_compile_test.c
new file mode 100644
index 00000000..924ec732
--- /dev/null
+++ b/testprogs/pcap_compile_test.c
@@ -0,0 +1,11 @@
+ pcap = pcap_open_dead(link, snaplen);
+ /* todo: hook together argv to a single string */
+ prog = argv[0];
+ if (pcap_compile(pcap, &p, prog, optimize, 0) < 0) {
+ fprintf(stderr, pcap_geterr(pcap));
+ exit(1);
+ }
+ bpf_dump(&p, option);
+ pcap_freecode(&p);
+ pcap_close(pcap);
+
diff --git a/tests/reactivatetest.c b/testprogs/reactivatetest.c
index 2e1b7b67..d7f3e322 100644
--- a/tests/reactivatetest.c
+++ b/testprogs/reactivatetest.c
@@ -19,6 +19,8 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
+#include "varattrs.h"
+
#ifndef lint
static const char copyright[] _U_ =
"@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
@@ -31,8 +33,10 @@ The Regents of the University of California. All rights reserved.\n";
#include <string.h>
#include <stdarg.h>
+#include "pcap/funcattrs.h"
+
/* Forwards */
-static void error(const char *, ...);
+static void PCAP_NORETURN error(PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(1,2);
int
main(void)
diff --git a/tests/selpolltest.c b/testprogs/selpolltest.c
index 4c1415b6..329281dc 100644
--- a/tests/selpolltest.c
+++ b/testprogs/selpolltest.c
@@ -19,6 +19,8 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
+#include "varattrs.h"
+
#ifndef lint
static const char copyright[] _U_ =
"@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
@@ -48,56 +50,9 @@ The Regents of the University of California. All rights reserved.\n";
#endif
#include <poll.h>
-char *program_name;
+#include "pcap/funcattrs.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 countme(u_char *, const struct pcap_pkthdr *, const u_char *);
@@ -115,15 +70,19 @@ main(int argc, char **argv)
bpf_u_int32 localnet, netmask;
register char *cp, *cmdbuf, *device;
int doselect, dopoll, dotimeout, dononblock;
+ const char *mechanism;
struct bpf_program fcode;
char ebuf[PCAP_ERRBUF_SIZE];
+ pcap_if_t *devlist;
int selectable_fd;
+ struct timeval *required_timeout;
int status;
int packet_count;
device = NULL;
doselect = 0;
dopoll = 0;
+ mechanism = NULL;
dotimeout = 0;
dononblock = 0;
if ((cp = strrchr(argv[0], '/')) != NULL)
@@ -141,10 +100,12 @@ main(int argc, char **argv)
case 's':
doselect = 1;
+ mechanism = "select() and pcap_dispatch()";
break;
case 'p':
dopoll = 1;
+ mechanism = "poll() and pcap_dispatch()";
break;
case 't':
@@ -170,9 +131,12 @@ main(int argc, char **argv)
return 1;
}
if (device == NULL) {
- device = pcap_lookupdev(ebuf);
- if (device == NULL)
+ if (pcap_findalldevs(&devlist, ebuf) == -1)
error("%s", ebuf);
+ if (devlist == NULL)
+ error("no interfaces available for capture");
+ device = strdup(devlist->name);
+ pcap_freealldevs(devlist);
}
*ebuf = '\0';
pd = pcap_open_live(device, 65535, 0, 1000, ebuf);
@@ -189,58 +153,112 @@ main(int argc, char **argv)
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 (doselect || dopoll) {
+ /*
+ * We need either an FD on which to do select()/poll()
+ * or, if there isn't one, a timeout to use in select()/
+ * poll().
+ */
+ selectable_fd = pcap_get_selectable_fd(pd);
+ if (selectable_fd == -1) {
+ printf("Listening on %s, using %s, with a timeout\n",
+ device, mechanism);
+ required_timeout = pcap_get_required_select_timeout(pd);
+ if (required_timeout == NULL)
+ error("select()/poll() isn't supported on %s, even with a timeout",
+ device);
+
+ /*
+ * As we won't be notified by select() or poll()
+ * that a read can be done, we'll have to periodically
+ * try reading from the device every time the required
+ * timeout expires, and we don't want those attempts
+ * to block if nothing has arrived in that interval,
+ * so we want to force non-blocking mode.
+ */
+ dononblock = 1;
+ } else {
+ printf("Listening on %s, using %s\n", device,
+ mechanism);
+ required_timeout = NULL;
+ }
+ } else
+ printf("Listening on %s, using pcap_dispatch()\n", device);
+
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 (selectable_fd != -1) {
+ FD_SET(selectable_fd, &setread);
+ FD_ZERO(&setexcept);
+ FD_SET(selectable_fd, &setexcept);
+ }
if (dotimeout) {
seltimeout.tv_sec = 0;
- seltimeout.tv_usec = 1000;
+ if (required_timeout != NULL &&
+ required_timeout->tv_usec < 1000)
+ seltimeout.tv_usec = required_timeout->tv_usec;
+ else
+ seltimeout.tv_usec = 1000;
status = select(selectable_fd + 1, &setread,
NULL, &setexcept, &seltimeout);
- } else {
+ } else if (required_timeout != NULL) {
+ seltimeout = *required_timeout;
status = select(selectable_fd + 1, &setread,
+ NULL, &setexcept, &seltimeout);
+ } else {
+ status = select((selectable_fd == -1) ?
+ 0 : 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");
+ if (selectable_fd == -1) {
+ if (status != 0)
+ printf("Select returned a descriptor\n");
+ } 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);
+ /*
+ * Don't report this if we're using a
+ * required timeout and we got no packets,
+ * because that could be a very short timeout,
+ * and we don't want to spam the user with
+ * a ton of "no packets" reports.
+ */
+ if (status != 0 || packet_count != 0 ||
+ required_timeout != NULL) {
+ printf("%d packets seen, %d packets counted after select returns\n",
+ status, packet_count);
+ }
}
}
} else if (dopoll) {
@@ -252,41 +270,59 @@ main(int argc, char **argv)
fd.events = POLLIN;
if (dotimeout)
polltimeout = 1;
+ else if (required_timeout != NULL &&
+ required_timeout->tv_usec >= 1000)
+ polltimeout = required_timeout->tv_usec/1000;
else
polltimeout = -1;
- status = poll(&fd, 1, polltimeout);
+ status = poll(&fd, (selectable_fd == -1) ? 0 : 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");
+ if (selectable_fd == -1) {
+ if (status != 0)
+ printf("Poll returned a descriptor\n");
+ } 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);
+ /*
+ * Don't report this if we're using a
+ * required timeout and we got no packets,
+ * because that could be a very short timeout,
+ * and we don't want to spam the user with
+ * a ton of "no packets" reports.
+ */
+ if (status != 0 || packet_count != 0 ||
+ required_timeout != NULL) {
+ printf("%d packets seen, %d packets counted after poll returns\n",
+ status, packet_count);
+ }
}
}
} else {
@@ -321,7 +357,7 @@ main(int argc, char **argv)
}
static void
-countme(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
+countme(u_char *user, const struct pcap_pkthdr *h _U_, const u_char *sp _U_)
{
int *counterp = (int *)user;
diff --git a/testprogs/threadsignaltest.c b/testprogs/threadsignaltest.c
new file mode 100644
index 00000000..a60bb495
--- /dev/null
+++ b/testprogs/threadsignaltest.c
@@ -0,0 +1,393 @@
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include "varattrs.h"
+
+#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 <winsock2.h>
+ #include <windows.h>
+
+ #define THREAD_HANDLE HANDLE
+ #define THREAD_FUNC_ARG_TYPE LPVOID
+ #define THREAD_FUNC_RETURN_TYPE DWORD __stdcall
+
+ #include "getopt.h"
+#else
+ #include <pthread.h>
+ #include <signal.h>
+ #include <unistd.h>
+
+ #define THREAD_HANDLE pthread_t
+ #define THREAD_FUNC_ARG_TYPE void *
+ #define THREAD_FUNC_RETURN_TYPE void *
+#endif
+#include <errno.h>
+#include <sys/types.h>
+
+#include <pcap.h>
+
+#include "pcap/funcattrs.h"
+
+#ifdef _WIN32
+ #include "portability.h"
+#endif
+
+static char *program_name;
+
+/* 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;
+
+#ifdef _WIN32
+/*
+ * Generate a string for a Win32-specific error (i.e. an error generated when
+ * calling a Win32 API).
+ * For errors occurred during standard C calls, we still use pcap_strerror()
+ */
+#define ERRBUF_SIZE 1024
+static const char *
+win32_strerror(DWORD error)
+{
+ static char errbuf[ERRBUF_SIZE+1];
+ size_t errlen;
+
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
+ ERRBUF_SIZE, NULL);
+
+ /*
+ * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
+ * message. Get rid of it.
+ */
+ errlen = strlen(errbuf);
+ if (errlen >= 2) {
+ errbuf[errlen - 1] = '\0';
+ errbuf[errlen - 2] = '\0';
+ errlen -= 2;
+ }
+ return errbuf;
+}
+#else
+static void
+catch_sigusr1(int sig _U_)
+{
+ printf("Got SIGUSR1\n");
+}
+#endif
+
+static void
+sleep_secs(int secs)
+{
+#ifdef _WIN32
+ Sleep(secs*1000);
+#else
+ unsigned secs_remaining;
+
+ if (secs <= 0)
+ return;
+ secs_remaining = secs;
+ while (secs_remaining != 0)
+ secs_remaining = sleep(secs_remaining);
+#endif
+}
+
+static THREAD_FUNC_RETURN_TYPE
+capture_thread_func(THREAD_FUNC_ARG_TYPE arg)
+{
+ char *device = arg;
+ int packet_count;
+ int status;
+#ifndef _WIN32
+ struct sigaction action;
+ sigset_t mask;
+#endif
+
+#ifndef _WIN32
+ sigemptyset(&mask);
+ action.sa_handler = catch_sigusr1;
+ action.sa_mask = mask;
+ action.sa_flags = 0;
+ if (sigaction(SIGUSR1, &action, NULL) == -1)
+ error("Can't catch SIGUSR1: %s", strerror(errno));
+#endif
+
+ 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);
+ } else
+ printf("No packets seen by pcap_dispatch\n");
+ }
+ 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');
+ printf("Loop got broken\n");
+ }
+ (void)fflush(stdout);
+ if (status == -1) {
+ /*
+ * Error. Report it.
+ */
+ (void)fprintf(stderr, "%s: pcap_loop: %s\n",
+ program_name, pcap_geterr(pd));
+ }
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ register int op;
+ register char *cp, *cmdbuf, *device;
+ int immediate = 0;
+ pcap_if_t *devlist;
+ bpf_u_int32 localnet, netmask;
+ struct bpf_program fcode;
+ char ebuf[PCAP_ERRBUF_SIZE];
+ int status;
+ THREAD_HANDLE capture_thread;
+#ifndef _WIN32
+ void *retval;
+#endif
+
+ 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:")) != -1) {
+ switch (op) {
+
+ case 'i':
+ device = optarg;
+ break;
+
+ default:
+ usage();
+ /* NOTREACHED */
+ }
+ }
+
+ if (device == NULL) {
+ if (pcap_findalldevs(&devlist, ebuf) == -1)
+ error("%s", ebuf);
+ if (devlist == NULL)
+ error("no interfaces available for capture");
+ device = strdup(devlist->name);
+ pcap_freealldevs(devlist);
+ }
+ *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, 5*60*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));
+ }
+ 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));
+
+#ifdef _WIN32
+ capture_thread = CreateThread(NULL, 0, capture_thread_func, device,
+ 0, NULL);
+ if (capture_thread == NULL)
+ error("Can't create capture thread: %s",
+ win32_strerror(GetLastError()));
+#else
+ status = pthread_create(&capture_thread, NULL, capture_thread_func,
+ device);
+ if (status != 0)
+ error("Can't create capture thread: %s", strerror(status));
+#endif
+ sleep_secs(60);
+ pcap_breakloop(pd);
+#ifdef _WIN32
+ printf("Setting event\n");
+ if (!SetEvent(pcap_getevent(pd)))
+ error("Can't set event for pcap_t: %s",
+ win32_strerror(GetLastError()));
+ if (WaitForSingleObject(capture_thread, INFINITE) == WAIT_FAILED)
+ error("Wait for thread termination failed: %s",
+ win32_strerror(GetLastError()));
+ CloseHandle(capture_thread);
+#else
+ printf("Sending SIGUSR1\n");
+ status = pthread_kill(capture_thread, SIGUSR1);
+ if (status != 0)
+ warning("Can't interrupt capture thread: %s", strerror(status));
+ status = pthread_join(capture_thread, &retval);
+ if (status != 0)
+ error("Wait for thread termination failed: %s",
+ strerror(status));
+#endif
+
+ pcap_close(pd);
+ pcap_freecode(&fcode);
+ exit(status == -1 ? 1 : 0);
+}
+
+static void
+countme(u_char *user, const struct pcap_pkthdr *h _U_, const u_char *sp _U_)
+{
+ int *counterp = (int *)user;
+
+ (*counterp)++;
+}
+
+static void
+usage(void)
+{
+ (void)fprintf(stderr, "Usage: %s [ -m ] [ -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/testprogs/unix.h b/testprogs/unix.h
new file mode 100644
index 00000000..68ef4cb9
--- /dev/null
+++ b/testprogs/unix.h
@@ -0,0 +1,58 @@
+/*
+ * 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 unix_h
+#define unix_h
+
+/*
+ * Definitions to make MSVC C runtime library structures and functions
+ * look like the UNIX structures and functions they are intended to
+ * resemble.
+ */
+#ifdef _MSC_VER
+ #define stat _stat
+ #define fstat _fstat
+
+ #define open _open
+ #define O_RDONLY _O_RDONLY
+ #define O_WRONLY _O_WRONLY
+ #define O_RDWR _O_RDWR
+ #define O_BINARY _O_BINARY
+ #define O_CREAT _O_CREAT
+ #define O_TRUNC _O_TRUNC
+ #define read _read
+ #define write _write
+ #define close _close
+#endif
+
+#endif
diff --git a/tests/valgrindtest.c b/testprogs/valgrindtest.c
index 011fe117..104ef6a9 100644
--- a/tests/valgrindtest.c
+++ b/testprogs/valgrindtest.c
@@ -19,6 +19,8 @@
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
+#include "varattrs.h"
+
/*
* This doesn't actually test libpcap itself; it tests whether
* valgrind properly handles the APIs libpcap uses. If it doesn't,
@@ -33,14 +35,14 @@
*
* https://bugs.kde.org/show_bug.cgi?id=318203
*
- * and valgrind bug 312989 for OS X:
+ * and valgrind bug 312989 for macOS:
*
* 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
+ * The unofficial FreeBSD port has similar issues to the official macOS
* port, for similar reasons.
*/
#ifndef lint
@@ -50,7 +52,7 @@ The Regents of the University of California. All rights reserved.\n";
#endif
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include <stdio.h>
@@ -64,8 +66,10 @@ The Regents of the University of California. All rights reserved.\n";
#include <sys/types.h>
#include <sys/stat.h>
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
-/* BSD-flavored OS - use BPF */
+#include "pcap/funcattrs.h"
+
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(_AIX) || defined(sun)
+/* OS with BPF - use BPF */
#define USE_BPF
#elif defined(linux)
/* Linux - use socket filters */
@@ -99,55 +103,6 @@ The Regents of the University of California. All rights reserved.\n";
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);
@@ -278,7 +233,8 @@ main(int argc, char **argv)
int dorfmon, useactivate;
char ebuf[PCAP_ERRBUF_SIZE];
char *infile;
- char *cmdbuf;
+ const char *cmdbuf;
+ pcap_if_t *devlist;
pcap_t *pd;
int status = 0;
int pcap_fd;
@@ -333,11 +289,12 @@ main(int argc, char **argv)
* 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 (pcap_findalldevs(&devlist, ebuf) == -1)
+ error("%s", ebuf);
+ if (devlist == NULL)
+ error("no interfaces available for capture");
+ device = strdup(devlist->name);
+ pcap_freealldevs(devlist);
}
if (infile != NULL) {
diff --git a/testprogs/visopts.py b/testprogs/visopts.py
new file mode 100755
index 00000000..03aa804e
--- /dev/null
+++ b/testprogs/visopts.py
@@ -0,0 +1,310 @@
+#!/usr/bin/env python
+
+"""
+This program parse the output from pcap_compile() to visualize the CFG after
+each optimize phase.
+
+Usage guide:
+1. Enable optimizier debugging code when configure libpcap,
+ and build libpcap & the test programs
+ ./configure --enable-optimizer-dbg
+ make
+ make testprogs
+2. Run filtertest to compile BPF expression and produce the CFG as a
+ DOT graph, save to output a.txt
+ testprogs/filtertest -g EN10MB host 192.168.1.1 > a.txt
+3. Send a.txt to this program's standard input
+ cat a.txt | testprogs/visopts.py
+4. Step 2&3 can be merged:
+ testprogs/filtertest -g EN10MB host 192.168.1.1 | testprogs/visopts.py
+5. The standard output is something like this:
+ generated files under directory: /tmp/visopts-W9ekBw
+ the directory will be removed when this programs finished.
+ open this link: http://localhost:39062/expr1.html
+6. Using open link at the 3rd line `http://localhost:39062/expr1.html'
+
+Note:
+1. The CFG is translated to SVG an document, expr1.html embeded them as external
+ document. If you open expr1.html as local file using file:// protocol, some
+ browsers will deny such requests so the web pages will not shown properly.
+ For chrome, you can run it using following command to avoid this:
+ chromium --disable-web-security
+ That's why this program start a localhost http server.
+2. expr1.html use jquery from http://ajax.googleapis.com, so you need internet
+ access to show the web page.
+"""
+
+import sys, os
+import string
+import subprocess
+import json
+
+html_template = string.Template("""
+<html>
+ <head>
+ <title>BPF compiler optimization phases for $expr </title>
+ <style type="text/css">
+ .hc {
+ /* half width container */
+ display: inline-block;
+ float: left;
+ width: 50%;
+ }
+ </style>
+
+ <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"/></script>
+ <!--script type="text/javascript" src="./jquery.min.js"/></script-->
+ <script type="text/javascript">
+ var expr = '$expr';
+ var exprid = 1;
+ var gcount = $gcount;
+ var logs = JSON.parse('$logs');
+ logs[gcount] = "";
+
+ var leftsvg = null;
+ var rightsvg = null;
+
+ function gurl(index) {
+ index += 1;
+ if (index < 10)
+ s = "00" + index;
+ else if (index < 100)
+ s = "0" + index;
+ else
+ s = "" + index;
+ return "./expr" + exprid + "_g" + s + ".svg"
+ }
+
+ function annotate_svgs() {
+ if (!leftsvg || !rightsvg) return;
+
+ $$.each([$$(leftsvg), $$(rightsvg)], function() {
+ $$(this).find("[id|='block'][opacity]").each(function() {
+ $$(this).removeAttr('opacity');
+ });
+ });
+
+ $$(leftsvg).find("[id|='block']").each(function() {
+ var has = $$(rightsvg).find("#" + this.id).length != 0;
+ if (!has) $$(this).attr("opacity", "0.4");
+ else {
+ $$(this).click(function() {
+ var target = $$(rightsvg).find("#" + this.id);
+ var offset = $$("#rightsvgc").offset().top + target.position().top;
+ window.scrollTo(0, offset);
+ target.focus();
+ });
+ }
+ });
+ $$(rightsvg).find("[id|='block']").each(function() {
+ var has = $$(leftsvg).find("#" + this.id).length != 0;
+ if (!has) $$(this).attr("opacity", "0.4");
+ else {
+ $$(this).click(function() {
+ var target = $$(leftsvg).find("#" + this.id);
+ var offset = $$("#leftsvgc").offset().top + target.position().top;
+ window.scrollTo(0, offset);
+ target.focus();
+ });
+ }
+ });
+ }
+
+ function init_svgroot(svg) {
+ svg.setAttribute("width", "100%");
+ svg.setAttribute("height", "100%");
+ }
+ function wait_leftsvg() {
+ if (leftsvg) return;
+ var doc = document.getElementById("leftsvgc").getSVGDocument();
+ if (doc == null) {
+ setTimeout(wait_leftsvg, 500);
+ return;
+ }
+ leftsvg = doc.documentElement;
+ //console.log(leftsvg);
+ // initialize it
+ init_svgroot(leftsvg);
+ annotate_svgs();
+ }
+ function wait_rightsvg() {
+ if (rightsvg) return;
+ var doc = document.getElementById("rightsvgc").getSVGDocument();
+ if (doc == null) {
+ setTimeout(wait_rightsvg, 500);
+ return;
+ }
+ rightsvg = doc.documentElement;
+ //console.log(rightsvg);
+ // initialize it
+ init_svgroot(rightsvg);
+ annotate_svgs();
+ }
+ function load_left(index) {
+ var url = gurl(index);
+ var frag = "<embed id='leftsvgc' type='image/svg+xml' pluginspage='http://www.adobe.com/svg/viewer/install/' src='" + url + "'/>";
+ $$("#lsvg").html(frag);
+ $$("#lcomment").html(logs[index]);
+ $$("#lsvglink").attr("href", url);
+ leftsvg = null;
+ wait_leftsvg();
+ }
+ function load_right(index) {
+ var url = gurl(index);
+ var frag = "<embed id='rightsvgc' type='image/svg+xml' pluginspage='http://www.adobe.com/svg/viewer/install/' src='" + url + "'/>";
+ $$("#rsvg").html(frag);
+ $$("#rcomment").html(logs[index]);
+ $$("#rsvglink").attr("href", url);
+ rightsvg = null;
+ wait_rightsvg();
+ }
+
+ $$(document).ready(function() {
+ for (var i = 0; i < gcount; i++) {
+ var opt = "<option value='" + i + "'>loop" + i + " -- " + logs[i] + "</option>";
+ $$("#lselect").append(opt);
+ $$("#rselect").append(opt);
+ }
+ var on_selected = function() {
+ var index = parseInt($$(this).children("option:selected").val());
+ if (this.id == "lselect")
+ load_left(index);
+ else
+ load_right(index);
+ }
+ $$("#lselect").change(on_selected);
+ $$("#rselect").change(on_selected);
+
+ $$("#backward").click(function() {
+ var index = parseInt($$("#lselect option:selected").val());
+ if (index <= 0) return;
+ $$("#lselect").val(index - 1).change();
+ $$("#rselect").val(index).change();
+ });
+ $$("#forward").click(function() {
+ var index = parseInt($$("#rselect option:selected").val());
+ if (index >= gcount - 1) return;
+ $$("#lselect").val(index).change();
+ $$("#rselect").val(index + 1).change();
+ });
+
+ if (gcount >= 1) $$("#lselect").val(0).change();
+ if (gcount >= 2) $$("#rselect").val(1).change();
+ });
+ </script>
+ </head>
+ <body style="width: 96%">
+ <div>
+ <h1>$expr</h1>
+ <div style="text-align: center;">
+ <button id="backward" type="button">&lt;&lt;</button>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ <button id="forward" type="button">&gt;&gt;</button>
+ </div>
+ </div>
+ <br/>
+ <div style="clear: both;">
+ <div class="hc lc">
+ <select id="lselect"></select>
+ <a id="lsvglink" target="_blank">open this svg in browser</a>
+ <p id="lcomment"></p>
+ </div>
+ <div class="hc rc">
+ <select id="rselect"></select>
+ <a id="rsvglink" target="_blank">open this svg in browser</a>
+ <p id="rcomment"></p>
+ </div>
+ </div>
+ <br/>
+ <div style="clear: both;">
+ <div id="lsvg" class="hc lc"></div>
+ <div id="rsvg" class="hc rc"></div>
+ </div>
+ </body>
+</html>
+""")
+
+def write_html(expr, gcount, logs):
+ logs = map(lambda s: s.strip().replace("\n", "<br/>"), logs)
+
+ global html_template
+ html = html_template.safe_substitute(expr=expr.encode("string-escape"), gcount=gcount, logs=json.dumps(logs).encode("string-escape"))
+ with file("expr1.html", "wt") as f:
+ f.write(html)
+
+def render_on_html(infile):
+ expr = None
+ gid = 1
+ log = ""
+ dot = ""
+ indot = 0
+ logs = []
+
+ for line in infile:
+ if line.startswith("machine codes for filter:"):
+ expr = line[len("machine codes for filter:"):].strip()
+ break
+ elif line.startswith("digraph BPF {"):
+ indot = 1
+ dot = line
+ elif indot:
+ dot += line
+ if line.startswith("}"):
+ indot = 2
+ else:
+ log += line
+
+ if indot == 2:
+ p = subprocess.Popen(['dot', '-Tsvg'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+ svg = p.communicate(dot)[0]
+ with file("expr1_g%03d.svg" % (gid), "wt") as f:
+ f.write(svg)
+
+ logs.append(log)
+ gid += 1
+ log = ""
+ dot = ""
+ indot = 0
+
+ if indot != 0:
+ #unterminated dot graph for expression
+ return False
+ if expr is None:
+ # BPF parser encounter error(s)
+ return False
+ write_html(expr, gid - 1, logs)
+ return True
+
+def run_httpd():
+ import SimpleHTTPServer
+ import SocketServer
+
+ class MySocketServer(SocketServer.TCPServer):
+ allow_reuse_address = True
+ Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
+ httpd = MySocketServer(("localhost", 0), Handler)
+ print "open this link: http://localhost:%d/expr1.html" % (httpd.server_address[1])
+ try:
+ httpd.serve_forever()
+ except KeyboardInterrupt as e:
+ pass
+
+def main():
+ import tempfile
+ import atexit
+ import shutil
+ os.chdir(tempfile.mkdtemp(prefix="visopts-"))
+ atexit.register(shutil.rmtree, os.getcwd())
+ print "generated files under directory: %s" % os.getcwd()
+ print " the directory will be removed when this programs finished."
+
+ if not render_on_html(sys.stdin):
+ return 1
+ run_httpd()
+ return 0
+
+if __name__ == "__main__":
+ if '-h' in sys.argv or '--help' in sys.argv:
+ print __doc__
+ exit(0)
+ exit(main())
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
deleted file mode 100644
index fc7919ed..00000000
--- a/tests/CMakeLists.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-cmake_minimum_required( VERSION 2.8.8 )
-
-project( pcap_tests )
-
-######################################
-# Register targets
-######################################
-
-if( MSVC )
- file(GLOB PROJECT_SOURCE_LIST_WIN32_C
- ${pcap_SOURCE_DIR}/missing/getopt.c
- )
-endif( MSVC )
-
-ADD_EXECUTABLE (can_set_rfmon_test can_set_rfmon_test.c ${PROJECT_SOURCE_LIST_WIN32_C} )
-target_link_libraries ( can_set_rfmon_test pcap )
-
-ADD_EXECUTABLE (capturetest capturetest.c ${PROJECT_SOURCE_LIST_WIN32_C} )
-target_link_libraries ( capturetest pcap )
-
-ADD_EXECUTABLE (filtertest filtertest.c ${PROJECT_SOURCE_LIST_WIN32_C} )
-target_link_libraries ( filtertest pcap )
-
-ADD_EXECUTABLE (indalldevstest findalldevstest.c ${PROJECT_SOURCE_LIST_WIN32_C} )
-target_link_libraries ( indalldevstest pcap )
-
-ADD_EXECUTABLE (opentest opentest.c ${PROJECT_SOURCE_LIST_WIN32_C} )
-target_link_libraries ( opentest pcap )
-
-#ADD_EXECUTABLE (pcap_compile_test pcap_compile_test.c ${PROJECT_SOURCE_LIST_WIN32_C} )
-#target_link_libraries ( pcap_compile_test pcap )
-
-ADD_EXECUTABLE (reactivatetest reactivatetest.c ${PROJECT_SOURCE_LIST_WIN32_C} )
-target_link_libraries ( reactivatetest pcap )
-
-if( NOT WIN32 )
- ADD_EXECUTABLE (selpolltest selpolltest.c ${PROJECT_SOURCE_LIST_WIN32_C} )
- target_link_libraries ( selpolltest pcap )
-endif()
-
-ADD_EXECUTABLE (valgrindtest valgrindtest.c ${PROJECT_SOURCE_LIST_WIN32_C} )
-target_link_libraries ( valgrindtest pcap )
diff --git a/tests/findalldevstest.c b/tests/findalldevstest.c
deleted file mode 100644
index 5925bf6a..00000000
--- a/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/tests/shb-option-too-long.pcapng b/tests/shb-option-too-long.pcapng
new file mode 100644
index 00000000..f7739747
--- /dev/null
+++ b/tests/shb-option-too-long.pcapng
Binary files differ
diff --git a/varattrs.h b/varattrs.h
new file mode 100644
index 00000000..05bfe8cd
--- /dev/null
+++ b/varattrs.h
@@ -0,0 +1,59 @@
+/* -*- 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 varattrs_h
+#define varattrs_h
+
+#include <pcap/compiler-tests.h>
+
+/*
+ * Attributes to apply to variables, using various compiler-specific
+ * extensions.
+ */
+
+#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
diff --git a/version.c b/version.c
deleted file mode 100644
index 15f6baf5..00000000
--- a/version.c
+++ /dev/null
@@ -1,3 +0,0 @@
-#include <pcap/export-defs.h>
-PCAP_API_DEF
-char pcap_version[] = "1.8.1";