From b6457c2d26fce16e1568be8a7b455c99ff94e04d Mon Sep 17 00:00:00 2001 From: christos Date: Thu, 17 Aug 2023 13:11:04 +0000 Subject: [PATCH] Import libpcap-1.10.4 (previous was 1.9.1) Friday, April 7, 2023 / The Tcpdump Group Summary for 1.10.4 libpcap release Source code: Fix spaces before tabs in indentation. rpcap: Fix name of launchd service. Documentation: Document use of rpcapd with systemd, launchd, inetd, and xinetd. Building and testing: Require at least pkg-config 0.17.0, as we use --static. Get rid of the remains of gnuc.h. Require at least autoconf 2.69. Update config.{guess,sub}, timestamps 2023-01-01,2023-01-21. Thursday, January 12, 2023 / The Tcpdump Group Summary for 1.10.3 libpcap release Source code: Sort the PUBHDR variable in Makefile.in in "ls" order. Fix typo in comment in pflog.h. Remove two no-longer-present files from .gitignore. Update code and comments for handling failure to set promiscuous mode based on new information. Building and testing: install: Fixed not to install the non-public pcap-util.h header. pcap-config: add a --version flag. Makefile.in: Add some missing files in the distclean target. Saturday, December 31, 2022 / The Tcpdump Group Summary for 1.10.2 libpcap release Source code: Use __builtin_unreachable() in PCAP_UNREACHABLE. Use AS_HELP_STRING macro instead of AC_HELP_STRING in the configure scripts, to avoid deprecation warnings. Change availability tags in pcap.h to make it easier to arrange for it to be used in Darwin releases. Use AS_HELP_STRING for --enable-remote. Fix some formatting string issues found by cppcheck. Various small code and comment cleanups. Use PCAP_ERROR (defined as -1) rather than explicit -1 for functions the documentation says return PCAP_ERROR. Remove unused code from the filter compiler. Use _declspec(deprecated(msg)) rather than __pragma(deprecated) for Windows deprecation warnings, so the message that was specified shows up. diag-control.h: define PCAP_DO_PRAGMA() iff we're going to use it. Use "%d" to print some signed ints. Use the Wayback Machine for a removed document in a comment. Add some const qualifiers. RDMA: Use PRIu64 to print a uint64_t. "Dead" pcap_ts from pcap_open_dead() and ..._with_tstamp_precision(): Don't crash if pcap_breakloop() is called. Savefiles: Fix pcap_dispatch() to return number of packets processed, rather than 0, even at EOF. If we get an error writing the packet header, don't write the packet data. Put PFLOG UID and PID values in the header into host byte order when reading a LINKTYPE_PFLOG file. Put CAN ID field in CAN pseudo-headers for LINUX_SLL2, as we do for LINUX_SLL. Fix inorrectly-computed "real" length for isochronous USB transfers when reading savefiles. Don't crash if pcap_can_set_rfmon() is called. Fix pcap_offline_read() loop. Capture: Never process more than INT_MAX packets in a pcap_dispatch() call, to avoid integer overflow (issue #1087). Improve error messages for "no such device" and "permission denied" errors. SITA: Fix a typo in a variable name. Packet filtering: Get PFLOG header length from the length value in the header. Support all the direction, reason, and action types supported by all systems that support PFLOG. Don't require PFLOG support on the target machine in order to support PFLOG filtering (also fixes issue #1076). Expand abbreviations into "proto X" properly. gencode.c: Update a comment about the VLAN TPID test. Add the minimum and maximum matching DLTs to an error message. Linux: Fix memory leak in capture device open (pull request #1038). Fix detection of CAN/CAN FD packets in direction check (issue #1051). Fix double-free crashes on errors such as running on a kernel with CONFIG_PACKET_MMAP not configured (issue #1054). Use DLT_CAN_SOCKETCAN for CANbus interfaces (issue #1052; includes changes from pull request #1035). Make sure the CANFD_FDF can be relied on to indicate whether a CANbus packet is a CAN frame or a CAN FD frame Improve error message for "out of memory" errors for kernel filters (see issue #1089). Fix pcap_findalldevs() to find usbmon devices. Fix handling of VLAN tagged packets if the link-layer type is changed from DLT_LINUX_SLL to DLT_LINUX_SLL2 (see issue #1105). Always turn on PACKET_AUXDATA (see issue #1105). We require 2.6.27 or later, so PACKET_RESERVE is available. Make sure there's reserved space for a DLT_LINUX_SLL2 header when capturing. Correctly compute the "real" length for isochronous USB transfers. Don't have an eventfd descriptor open in non-blocking mode, so as not to waste descriptors. netfilter: Squelch a narrowing warning (To be look at before 2038). BPF capture (*BSD, macOS, AIX, Solaris 11): Fix case where a device open might fail, rather than falling back to a smaller buffer size, when the initial buffer size is too big. Use an unsigned device number to iterate over BPF devices, to squelch a compiler warning. NetBSD: Fix handling of LINKTYPE_HDLC/DLT_HDLC. rpcap: Fix unaligned accesses in rpcapd (pull request #1037). Fix code to process port number. Clean up findalldevs code in rpcapd. Clean up bufferizing code. Fix a file descriptor/handle leak in pcap_findalldevs_ex() (Coverity CID 1507240). Improve error messages for host and port resolution errors. Fix connect code not to fail if both IPv4 and IPv6 addresses are tried. Improve connect failure error message. Provide an error message for a bad authentication reply size. For link-layer types with host-endian fields in the header, fix those fields if capturing from a server with a different byte order. Suppress temporarily the warnings with "enable remote packet capture". Windows: Add support for NdisMediumIP (pull request #1027). Don't require applications using pcap to be built with VS 2015 or later. Use the correct string for the DLL VersionInfo. Remove unnecessary DllMain() function. Correctly handle ERROR_INVALID_FUNCTION from PacketGetTimestampModes() (indicate that WinPcap or an older version of Npcap is probably installed). Fix use-after-free in some cases when a pcap_t is closed. Make sure an error is returned by pcap_create_interface() if PacketOpenAdapter() fails. Return an error if the driver reports 0 timestamp modes supported. Close the ADAPTER handle for some errors in pcap_create_interface(). Get rid of old umaintained VS project files. Fix deprecation warning for pcap_handle(). Npcap is now at npcap.com, not npcap.org. Make sure "no such device" and "no permission to open device" errors show up in pcap_activate(), not pcap_create() (fixes, among other things, tcpdump -i ). npcap: squelch deprecation warnings for kernel dump mode. Haiku: Implement pcap_lib_version(), as now required. Handle negative or too-large snaplen values. Fix various build issues and warnings. Building and testing: Update configure-time universal build checks for macOS. Update config.guess and config.sub. If we look for an SSL library with pkg-config in configure script, try pkg-config first. If we have pkg-config and Homebrew, try to set pkg-config up to find Homebrew packages. Handle some Autoconf/make errors better. Use "git archive" for the "make releasetar" process. Remove the release candidate rcX targets. Fix compiling on Solaris 9/SPARC and 11/AMD64. Address assorted compiler warnings. Fix cross-building on Linux for Windows with mingw32 for Win64 (pull request #1031). Properly set installation directory on Windows when not compiling with MSVC. Fix configure script checks for compiler flags. Give more details if check for usable (F)Lex fails. Fix compiling with GCC 4.6.4. Don't use add_compile_options() with CMake, as we currently don't require 2.8.12, where it first appeared. Don't provide -L/usr/lib for pkg-config --libs in pkg-config. Fix error message for inadequate Bison/Berkeley YACC. configure: correctly do some DPDK checks. Only use pkg-config when checking for DPDK. Allow the path in which DPDK is installed to be specified. Use pkg-config first when checking for libibverbs. CMake: fix check for libibverbs with Sun's C compiler. Have CMake warn if no capture mechanism can be found. Don't do stuff requiring 3.19 or later on earlier CMakes. Squelch some CMake warnings. Fix diag-control.h to handle compiling with clang-cl (issues #1101 and #1115). Cleanup various leftover cruft in the configure script. Fix building without protochain support. (GH #852) Check for a usable YACC (or Bison) and {F}lex in CMake, as we do in autotools. Only check for a C++ compiler on Haiku, as that's the only platform with C++ code, and make sure they generate code for the same instruction set bit-width (both 32-bit or both 64-bit) (issue #1112). On Solaris, check the target bit-width and set PKG_CONFIG_PATH appropriately, to handle the mess that is the D-Bus library package (issue #1112). Fix generation of pcap-config and libpcap.pc files (issue #1062). pcap-config: don't assume the system library directory is /usr/lib. pcap-config: add a --static-pcap-only flag. Cirrus CI: Use the same configuration as for the main branch. Add four libpcap test files. Update Npcap SDK to 1.13. Makefile.in: Use TEST_DIST, like for tcpdump. Remove awk code from mkdep. Cirrus CI: Add the libssl-dev package in the Linux task. Cirrus CI: Add the openssl@3 brew package in the macOS task. Get "make shellcheck" to pass again. CMake: Build valgrindtest only if Autoconf would. CMake: use ${CMAKE_INSTALL_SBINDIR} rather than just sbin. CMake: use NUL: as the null device on Windows. autoconf: fix typo in test of macOS version. Makefile.in: Add two missing files in EXTRA_DIST. autotools, cmake: provide an rpath option if necessary. configure: get rid of the attempt to auto-run PKG_PROG_PKG_CONFIG. configure: use PKG_CHECK_MODULES to run pkg-config. Documentation: Add README.solaris.md. Add SCTP to pcap-filter(7). Note that = and == are the same operator in filters (issue #1044). Update INSTALL.md, README.md, and README.solaris.md. Update and clean up CONTRIBUTING.md. Trim documentation of support for now-dead UN*Xe and older versions of other UN*Xes. Move the "how to allocate a LINKTYPE_/DLT_ value" documentation to the web site. Clean up man pages. Move README.capture-module to the web site. Improve some protocol details in pcap-filter(7). Refine "relop" notes in pcap-filter(7). In pcap-filter(7) "domain" is an id. Discuss backward compatibility in pcap-filter(7). Other improvements to pcap-filter(7). Document pcap_breakloop(3PCAP) interaction with threads better. Document PCAP_ERROR_NOT_ACTIVATED for more routines. Wednesday, June 9, 2021: Summary for 1.10.1 libpcap release: Packet filtering: Fix "type XXX subtype YYY" giving a parse error Source code: Add PCAP_AVAILABLE_1_11. Building and testing: Rename struct bpf_aux_data to avoid NetBSD compile errors Squelch some compiler warnings Squelch some Bison warnings Fix cross-builds with older kernels lacking BPF_MOD and BPF_XOR Fix Bison detection for minor version 0. Fix parallel build with FreeBSD make. Get DLT_MATCHING_MAX right in gencode.c on NetBSD. Define timeradd() and timersub() if necessary. Fix Cygwin/MSYS target directories. Fix symlinking with DESTDIR. Fix generation of libpcap.pc with CMake when not building a shared library. Check for Arm64 as well as x86-64 when looking for packet.lib on Windows. Documentation: Refine Markdown in README.md. Improve the description of portrange in filters. README.linux.md isn't Markdown, rename it just README.linux. pcapng: Support reading version 1.2, which some writers produce, and which is the same as 1.0 (some new block types were added, but that's not sufficient reason to bump the minor version number, as code that understands those new block types can handle them in a 1.0 file) Linux: Drop support for text-mode USB captures, as we require a 2.6.27 or later kernel (credit to Chaoyuan Peng for noting the sscanf vulnerabilities in the text-mode code that got me to realize that we didn't need this code any more) Bluetooth: fix non-blocking mode. Don't assume that all compilers used to build for Linux support the __atomic builtins Windows: Add more information in "interface disappeared" error messages, in the hopes of trying to figure out the cause. Treat ERROR_DEVICE_REMOVED as "device was removed". Indicate in the error message which "device was removed" error occurred. Report the Windows error status if PacketSendPacket() fails. Use %lu for ULONGs in error message formats. Don't treat the inability to find airpcap.dll as an error. Ignore spurious error reports by Microsoft Surface mobile telephony modem driver rpcap: Clean up error checking and error messages for server address lookup. Tuesday, December 29, 2020 Summary for 1.10.0 libpcap release Add support for capturing on DPDK devices Label most APIs by the first release in which they're available Fix some memory leaks, including in pcap_compile() Add pcap_datalink_val_to_description_or_dlt() Handle the pcap private data in a fashion that makes fewer assumptions about memory layouts (might fix GitHub issue #940 on ARM) Fix some thread safety issues pcap_findalldevs(): don't sort interfaces by unit number Always return a list of supported time-stamp types, even if only host time stamps are supported Increase the maximum snaplen for LINKTYPE_USBPCAP/DLT_USBPCAP Report the DLT description in error messages Add pcap_init() for first-time initialization and global option setting; it's not required, but may be used Remove (unused) SITA support Capture file reading: Correctly handle pcapng captures with more than one IDB with a snspshot length greater than the supported maximum Capture file writing: Create the file in pcap_dump_open_append() if it doesn't exist Packet filtering: Fix "unknown ether proto 'aarp'" Add a new filter "ifindex" for DLT_LINUX_SLL2 files on all platforms and live Linux captures Add a hack to the optimizer to try to catch certain optimizer loops (should prevent GitHub issue #112) Show special Linux BPF offsets symbolically in bpf_image() and bpf_dump() Added support for ICMPv6 types 1-4 as tokens with names Remove undocumented and rather old "ether proto" protocols Catch invalid IPv4 addresses in filters Don't assume ARM supports unaligned accesses Security and other issues found by analysis: Fix various security issues reported by Charles Smith at Tangible Security Fix various security issues reported by Include Security Fix some issues found by cppcheck. Add some overflow checks in the optimizer rpcap: Support rpcap-over-TLS Redo protocol version negotiation to avoid problems with old servers (it still works with servers using the old negotiation, as well as servers not supporting negotiation) Error handling cleanups Add some new authentication libpcap error codes for specific errors Fix some inetd issues in rpcapd Fix rpcapd core dumps with invalid configuration file On UN*X, don't have rpcapd tell the client why authentication failed, so a brute-force attacker can't distinguish between "unknown user name" and "known user name, wrong password" Allow rpcapd to rebind more rapidly (GitHub issue #765) Documentation: Improve man pages, including adding backward compatibility notes Building and testing: Require, and assume, some level of C99 support in the C compiler Require Visual Studio 2015 or later if using Visual Studio Fix configure script issues, including with libnl on Linux Fix CMake issues Squelch complaints from Bison about "%define api.pure" being deprecated Fix compilation of pcap-tc.c Linux: Require PF_PACKET support, and kernel 2.6.27 or later Handle systems without AF_INET or AF_UNIX socket support Get rid of Wireless Extensions for turning monitor mode on Proper memory sync for PACKET_MMAP (may prevent GitHub issue #898) Drop support for libnl 1 and 2. Return error on interface going away, but not if it just went down but is still present Set socket protocol only after packet ring configured, reducing bogus packet drop reports Get ifdrop stats from sysfs. When adjusting BPF programs, do not subtract the SLL[2]_HDR_LEN if the location is negative (special metadata offset), to preserve references to metadata; see https://github.com/the-tcpdump-group/tcpdump/issues/480#issuecomment-486827278 Report a warning for unknown ARPHRD types Have pcap_breakloop() forcibly break out of a sleeping capture loop Add support for DSA data link types For raw USB bus capture, use the snapshot length to set the buffer size, and set the len field to reflect the length in the URB (GitHub issue #808) With a timeout of zero, wait indefinitely Clean up support for some non-GNU libc C libraries Add DLT_LINUX_SLL2 for cooked-mode captures Probe CONFIGURATION descriptor of connected USB devices Treat EPERM on ethtool ioctls as meaning "not supported", as permissions checks are done before checking whether the ioctl is supported at all macOS: Cope with getting EPWROFF from SIOCGIFMEDIA Treat EPERM on SIOCGIFMEDIA as meaning "not supported", as permissions checks are done before checking whether the ioctl is supported at all Treat ENXIO when reading packets as meaning "the interface was removed" Report "the interface disappeared", not "the interface went down", if the interface was removed during a capture FreeBSD: Treat ENXIO as meaning "the interface was removed" Report "the interface disappeared", not "the interface went down", if the interface was removed during a capture NetBSD: Treat ENXIO as meaning "the interface was removed" Report "the interface disappeared", not "the interface went down", if the interface was removed during a capture OpenBSD: Treat EIO as meaning "the interface was removed" Report "the interface disappeared", not "the interface went down", if the interface was removed during a capture DragonFly BSD: Treat ENXIO as meaning "the interface was removed" Report "the interface disappeared", not "the interface went down", if the interface was removed during a capture Solaris: Treat ENXIO as meaning "the interface was removed" Report "the interface disappeared", not "the interface went down", if the interface was removed during a capture AIX: Fix loading of BPF kernel extension Treat ENXIO as meaning "the interface was removed" Report "the interface disappeared", not "the interface went down", if the interface was removed during a capture Windows: Make the snapshot length work even if pcap_setfilter() isn't called Fix compilation on Cygwin/MSYS Add pcap_handle(), and deprecate pcap_fileno() Report PCAP_ERROR_NO_SUCH_DEVICE for a non-existent device Return an appropriate error message for device removed or device unusable due to a suspend/resume Report a warning for unknown NdisMedium types Have pcap_breakloop() forcibly break out of a sleeping capture loop Clean up building DLL Handle CRT mismatch for pcap_dump_fopen() Map NdisMediumWirelessWan to DLT_RAW Add AirPcap support in a module, rather than using WinPcap/Npcap's support for it Report the system error for PacketSetHwFilter() failures Add support for getting and setting packet time stamp types with Npcap Have pcap_init() allow selecting whether the API should use local code page strings or UTF-8 strings (including error messages) Haiku: Add capture support --- external/bsd/libpcap/dist/CHANGES | 486 +- external/bsd/libpcap/dist/CMakeLists.txt | 1627 +++- external/bsd/libpcap/dist/CONTRIBUTING.md | 6 +- external/bsd/libpcap/dist/CREDITS | 83 +- external/bsd/libpcap/dist/INSTALL.md | 481 +- external/bsd/libpcap/dist/Makefile-devel-adds | 4 +- external/bsd/libpcap/dist/Makefile.in | 177 +- external/bsd/libpcap/dist/README.md | 73 +- external/bsd/libpcap/dist/TODO | 2 - external/bsd/libpcap/dist/VERSION | 2 +- external/bsd/libpcap/dist/aclocal.m4 | 584 +- external/bsd/libpcap/dist/charconv.c | 217 + external/bsd/libpcap/dist/charconv.h | 44 + .../dist/cmake/Modules/FindAirPcap.cmake | 69 + .../libpcap/dist/cmake/Modules/FindDAG.cmake | 7 + .../dist/cmake/Modules/FindPacket.cmake | 63 +- .../libpcap/dist/cmake/Modules/FindSNF.cmake | 6 + .../libpcap/dist/cmake/Modules/Finddpdk.cmake | 118 + external/bsd/libpcap/dist/cmakeconfig.h.in | 85 +- external/bsd/libpcap/dist/config.h.in | 96 +- external/bsd/libpcap/dist/configure | 6974 ++++++++++++----- external/bsd/libpcap/dist/configure.ac | 1694 ++-- external/bsd/libpcap/dist/diag-control.h | 241 +- external/bsd/libpcap/dist/doc/README.Win32.md | 199 +- external/bsd/libpcap/dist/doc/README.aix | 24 +- external/bsd/libpcap/dist/doc/README.dag | 6 +- external/bsd/libpcap/dist/doc/README.hpux | 10 +- external/bsd/libpcap/dist/doc/README.linux | 36 + external/bsd/libpcap/dist/doc/README.septel | 4 +- external/bsd/libpcap/dist/doc/README.sita | 13 +- .../bsd/libpcap/dist/doc/README.solaris.md | 58 + external/bsd/libpcap/dist/extract.h | 302 +- external/bsd/libpcap/dist/fmtutils.c | 308 +- external/bsd/libpcap/dist/fmtutils.h | 8 + external/bsd/libpcap/dist/ftmacros.h | 28 +- external/bsd/libpcap/dist/grammar.y.in | 871 ++ external/bsd/libpcap/dist/libpcap.pc.in | 5 +- external/bsd/libpcap/dist/missing/asprintf.c | 2 +- external/bsd/libpcap/dist/missing/getopt.c | 17 +- .../bsd/libpcap/dist/missing/win_asprintf.c | 4 +- external/bsd/libpcap/dist/mkdep | 55 +- external/bsd/libpcap/dist/msdos/makefile | 8 +- external/bsd/libpcap/dist/msdos/readme.dos | 8 +- .../libpcap/dist/org.tcpdump.chmod_bpf.plist | 2 +- external/bsd/libpcap/dist/pcap-airpcap.c | 1054 +++ external/bsd/libpcap/dist/pcap-airpcap.h | 36 + external/bsd/libpcap/dist/pcap-dll.rc | 6 +- external/bsd/libpcap/dist/pcap-dpdk.c | 1086 +++ external/bsd/libpcap/dist/pcap-dpdk.h | 28 + .../bsd/libpcap/dist/pcap-filter.manmisc.in | 651 +- external/bsd/libpcap/dist/pcap-haiku.cpp | 305 + .../bsd/libpcap/dist/pcap-linktype.manmisc.in | 8 +- external/bsd/libpcap/dist/pcap-netmap.c | 7 +- external/bsd/libpcap/dist/pcap-new.c | 54 +- external/bsd/libpcap/dist/pcap-npf.c | 809 +- external/bsd/libpcap/dist/pcap-rdmasniff.c | 63 +- .../bsd/libpcap/dist/pcap-savefile.manfile.in | 8 +- external/bsd/libpcap/dist/pcap-sita.html | 50 +- external/bsd/libpcap/dist/pcap-tc.c | 178 +- .../bsd/libpcap/dist/pcap-tstamp.manmisc.in | 61 +- external/bsd/libpcap/dist/pcap-types.h | 1 - .../bsd/libpcap/dist/pcap-usb-linux-common.c | 130 + .../bsd/libpcap/dist/pcap-usb-linux-common.h | 26 + external/bsd/libpcap/dist/pcap-util.c | 474 ++ external/bsd/libpcap/dist/pcap-util.h | 55 + .../bsd/libpcap/dist/pcap/can_socketcan.h | 7 +- .../bsd/libpcap/dist/pcap/compiler-tests.h | 52 +- external/bsd/libpcap/dist/pcap/dlt.h | 210 +- external/bsd/libpcap/dist/pcap/funcattrs.h | 130 +- .../bsd/libpcap/dist/pcap/pcap-inttypes.h | 85 +- external/bsd/libpcap/dist/pcap/socket.h | 9 - .../bsd/libpcap/dist/pcap_compile.3pcap.in | 26 +- .../bsd/libpcap/dist/pcap_datalink.3pcap.in | 15 +- .../pcap_get_required_select_timeout.3pcap | 156 +- .../dist/pcap_get_tstamp_precision.3pcap.in | 12 +- external/bsd/libpcap/dist/pcap_init.3pcap | 99 + .../libpcap/dist/pcap_list_datalinks.3pcap.in | 22 +- .../dist/pcap_list_tstamp_types.3pcap.in | 21 +- .../bsd/libpcap/dist/pcap_open_dead.3pcap.in | 25 +- .../dist/pcap_set_immediate_mode.3pcap.in | 32 +- .../dist/pcap_set_protocol_linux.3pcap | 20 +- .../dist/pcap_set_tstamp_precision.3pcap.in | 20 +- .../dist/pcap_set_tstamp_type.3pcap.in | 22 +- external/bsd/libpcap/dist/pflog.h | 157 + external/bsd/libpcap/dist/portability.h | 70 +- external/bsd/libpcap/dist/rpcap-protocol.c | 6 +- external/bsd/libpcap/dist/rpcap-protocol.h | 56 +- .../bsd/libpcap/dist/rpcapd/CMakeLists.txt | 39 +- external/bsd/libpcap/dist/rpcapd/Makefile.in | 7 +- external/bsd/libpcap/dist/rpcapd/daemon.c | 803 +- external/bsd/libpcap/dist/rpcapd/daemon.h | 8 +- external/bsd/libpcap/dist/rpcapd/fileconf.c | 32 +- external/bsd/libpcap/dist/rpcapd/log.c | 2 +- .../dist/rpcapd/org.tcpdump.rpcapd.plist | 4 +- .../dist/rpcapd/rpcapd-config.manfile.in | 8 +- external/bsd/libpcap/dist/rpcapd/rpcapd.c | 172 +- .../libpcap/dist/rpcapd/rpcapd.manadmin.in | 131 +- external/bsd/libpcap/dist/rpcapd/win32-svc.c | 13 +- external/bsd/libpcap/dist/rpcapd/win32-svc.h | 2 +- external/bsd/libpcap/dist/sf-pcapng.c | 114 +- external/bsd/libpcap/dist/sockutils.h | 31 +- external/bsd/libpcap/dist/sslutils.c | 239 + external/bsd/libpcap/dist/sslutils.h | 66 + .../bsd/libpcap/dist/testprogs/CMakeLists.txt | 13 +- .../bsd/libpcap/dist/testprogs/Makefile.in | 56 +- .../dist/testprogs/can_set_rfmon_test.c | 1 - .../bsd/libpcap/dist/testprogs/capturetest.c | 89 +- .../bsd/libpcap/dist/testprogs/filtertest.c | 44 +- .../dist/testprogs/findalldevstest-perf.c | 97 + .../libpcap/dist/testprogs/findalldevstest.c | 29 +- .../dist/testprogs/fuzz/CMakeLists.txt | 43 + .../libpcap/dist/testprogs/fuzz/fuzz_both.c | 101 + .../dist/testprogs/fuzz/fuzz_both.options | 2 + .../libpcap/dist/testprogs/fuzz/fuzz_filter.c | 43 + .../dist/testprogs/fuzz/fuzz_filter.options | 2 + .../libpcap/dist/testprogs/fuzz/fuzz_pcap.c | 80 + .../dist/testprogs/fuzz/fuzz_pcap.options | 2 + .../bsd/libpcap/dist/testprogs/fuzz/onefile.c | 54 + .../bsd/libpcap/dist/testprogs/nonblocktest.c | 187 + .../bsd/libpcap/dist/testprogs/opentest.c | 19 +- .../libpcap/dist/testprogs/reactivatetest.c | 1 - .../bsd/libpcap/dist/testprogs/selpolltest.c | 66 +- .../libpcap/dist/testprogs/threadsignaltest.c | 58 +- .../bsd/libpcap/dist/testprogs/valgrindtest.c | 34 +- .../bsd/libpcap/dist/testprogs/visopts.py | 317 + .../bsd/libpcap/dist/testprogs/writecaptest.c | 556 ++ .../dist/tests/pcap-invalid-version-1.pcap | Bin 0 -> 530 bytes .../dist/tests/pcap-invalid-version-2.pcap | Bin 0 -> 530 bytes .../dist/tests/pcapng-invalid-vers-1.pcapng | Bin 0 -> 260 bytes .../dist/tests/pcapng-invalid-vers-2.pcapng | Bin 0 -> 260 bytes 130 files changed, 19847 insertions(+), 5167 deletions(-) create mode 100644 external/bsd/libpcap/dist/charconv.c create mode 100644 external/bsd/libpcap/dist/charconv.h create mode 100644 external/bsd/libpcap/dist/cmake/Modules/FindAirPcap.cmake create mode 100644 external/bsd/libpcap/dist/cmake/Modules/Finddpdk.cmake create mode 100644 external/bsd/libpcap/dist/doc/README.linux create mode 100644 external/bsd/libpcap/dist/doc/README.solaris.md create mode 100644 external/bsd/libpcap/dist/grammar.y.in create mode 100644 external/bsd/libpcap/dist/pcap-airpcap.c create mode 100644 external/bsd/libpcap/dist/pcap-airpcap.h create mode 100644 external/bsd/libpcap/dist/pcap-dpdk.c create mode 100644 external/bsd/libpcap/dist/pcap-dpdk.h create mode 100644 external/bsd/libpcap/dist/pcap-haiku.cpp create mode 100644 external/bsd/libpcap/dist/pcap-usb-linux-common.c create mode 100644 external/bsd/libpcap/dist/pcap-usb-linux-common.h create mode 100644 external/bsd/libpcap/dist/pcap-util.c create mode 100644 external/bsd/libpcap/dist/pcap-util.h create mode 100644 external/bsd/libpcap/dist/pcap_init.3pcap create mode 100644 external/bsd/libpcap/dist/pflog.h create mode 100644 external/bsd/libpcap/dist/sslutils.c create mode 100644 external/bsd/libpcap/dist/sslutils.h create mode 100644 external/bsd/libpcap/dist/testprogs/findalldevstest-perf.c create mode 100644 external/bsd/libpcap/dist/testprogs/fuzz/CMakeLists.txt create mode 100644 external/bsd/libpcap/dist/testprogs/fuzz/fuzz_both.c create mode 100644 external/bsd/libpcap/dist/testprogs/fuzz/fuzz_both.options create mode 100644 external/bsd/libpcap/dist/testprogs/fuzz/fuzz_filter.c create mode 100644 external/bsd/libpcap/dist/testprogs/fuzz/fuzz_filter.options create mode 100644 external/bsd/libpcap/dist/testprogs/fuzz/fuzz_pcap.c create mode 100644 external/bsd/libpcap/dist/testprogs/fuzz/fuzz_pcap.options create mode 100644 external/bsd/libpcap/dist/testprogs/fuzz/onefile.c create mode 100644 external/bsd/libpcap/dist/testprogs/nonblocktest.c create mode 100755 external/bsd/libpcap/dist/testprogs/visopts.py create mode 100644 external/bsd/libpcap/dist/testprogs/writecaptest.c create mode 100644 external/bsd/libpcap/dist/tests/pcap-invalid-version-1.pcap create mode 100644 external/bsd/libpcap/dist/tests/pcap-invalid-version-2.pcap create mode 100644 external/bsd/libpcap/dist/tests/pcapng-invalid-vers-1.pcapng create mode 100644 external/bsd/libpcap/dist/tests/pcapng-invalid-vers-2.pcapng diff --git a/external/bsd/libpcap/dist/CHANGES b/external/bsd/libpcap/dist/CHANGES index 89e739c46fa2..c574a278064f 100644 --- a/external/bsd/libpcap/dist/CHANGES +++ b/external/bsd/libpcap/dist/CHANGES @@ -1,3 +1,446 @@ +Friday, April 7, 2023 / The Tcpdump Group + Summary for 1.10.4 libpcap release + Source code: + Fix spaces before tabs in indentation. + rpcap: + Fix name of launchd service. + Documentation: + Document use of rpcapd with systemd, launchd, inetd, and xinetd. + Building and testing: + Require at least pkg-config 0.17.0, as we use --static. + Get rid of the remains of gnuc.h. + Require at least autoconf 2.69. + Update config.{guess,sub}, timestamps 2023-01-01,2023-01-21. + +Thursday, January 12, 2023 / The Tcpdump Group + Summary for 1.10.3 libpcap release + Source code: + Sort the PUBHDR variable in Makefile.in in "ls" order. + Fix typo in comment in pflog.h. + Remove two no-longer-present files from .gitignore. + Update code and comments for handling failure to set promiscuous + mode based on new information. + Building and testing: + install: Fixed not to install the non-public pcap-util.h header. + pcap-config: add a --version flag. + Makefile.in: Add some missing files in the distclean target. + +Saturday, December 31, 2022 / The Tcpdump Group + Summary for 1.10.2 libpcap release + Source code: + Use __builtin_unreachable() in PCAP_UNREACHABLE. + Use AS_HELP_STRING macro instead of AC_HELP_STRING in the + configure scripts, to avoid deprecation warnings. + Change availability tags in pcap.h to make it easier to + arrange for it to be used in Darwin releases. + Use AS_HELP_STRING for --enable-remote. + Fix some formatting string issues found by cppcheck. + Various small code and comment cleanups. + Use PCAP_ERROR (defined as -1) rather than explicit -1 for + functions the documentation says return PCAP_ERROR. + Remove unused code from the filter compiler. + Use _declspec(deprecated(msg)) rather than __pragma(deprecated) + for Windows deprecation warnings, so the message that was + specified shows up. + diag-control.h: define PCAP_DO_PRAGMA() iff we're going to use it. + Use "%d" to print some signed ints. + Use the Wayback Machine for a removed document in a comment. + Add some const qualifiers. + RDMA: Use PRIu64 to print a uint64_t. + "Dead" pcap_ts from pcap_open_dead() and ..._with_tstamp_precision(): + Don't crash if pcap_breakloop() is called. + Savefiles: + Fix pcap_dispatch() to return number of packets processed, rather + than 0, even at EOF. + If we get an error writing the packet header, don't write the + packet data. + Put PFLOG UID and PID values in the header into host byte order + when reading a LINKTYPE_PFLOG file. + Put CAN ID field in CAN pseudo-headers for LINUX_SLL2, as we do + for LINUX_SLL. + Fix inorrectly-computed "real" length for isochronous USB + transfers when reading savefiles. + Don't crash if pcap_can_set_rfmon() is called. + Fix pcap_offline_read() loop. + Capture: + Never process more than INT_MAX packets in a pcap_dispatch() call, + to avoid integer overflow (issue #1087). + Improve error messages for "no such device" and "permission + denied" errors. + SITA: Fix a typo in a variable name. + Packet filtering: + Get PFLOG header length from the length value in the header. + Support all the direction, reason, and action types supported by + all systems that support PFLOG. + Don't require PFLOG support on the target machine in order to + support PFLOG filtering (also fixes issue #1076). + Expand abbreviations into "proto X" properly. + gencode.c: Update a comment about the VLAN TPID test. + Add the minimum and maximum matching DLTs to an error message. + Linux: + Fix memory leak in capture device open (pull request #1038). + Fix detection of CAN/CAN FD packets in direction check (issue + #1051). + Fix double-free crashes on errors such as running on a kernel with + CONFIG_PACKET_MMAP not configured (issue #1054). + Use DLT_CAN_SOCKETCAN for CANbus interfaces (issue #1052; includes + changes from pull request #1035). + Make sure the CANFD_FDF can be relied on to indicate whether a + CANbus packet is a CAN frame or a CAN FD frame + Improve error message for "out of memory" errors for kernel + filters (see issue #1089). + Fix pcap_findalldevs() to find usbmon devices. + Fix handling of VLAN tagged packets if the link-layer type is + changed from DLT_LINUX_SLL to DLT_LINUX_SLL2 (see issue #1105). + Always turn on PACKET_AUXDATA (see issue #1105). + We require 2.6.27 or later, so PACKET_RESERVE is available. + Make sure there's reserved space for a DLT_LINUX_SLL2 header + when capturing. + Correctly compute the "real" length for isochronous USB transfers. + Don't have an eventfd descriptor open in non-blocking mode, so as + not to waste descriptors. + netfilter: Squelch a narrowing warning (To be look at before 2038). + BPF capture (*BSD, macOS, AIX, Solaris 11): + Fix case where a device open might fail, rather than falling back + to a smaller buffer size, when the initial buffer size is too + big. + Use an unsigned device number to iterate over BPF devices, to + squelch a compiler warning. + NetBSD: + Fix handling of LINKTYPE_HDLC/DLT_HDLC. + rpcap: + Fix unaligned accesses in rpcapd (pull request #1037). + Fix code to process port number. + Clean up findalldevs code in rpcapd. + Clean up bufferizing code. + Fix a file descriptor/handle leak in pcap_findalldevs_ex() + (Coverity CID 1507240). + Improve error messages for host and port resolution errors. + Fix connect code not to fail if both IPv4 and IPv6 addresses are + tried. + Improve connect failure error message. + Provide an error message for a bad authentication reply size. + For link-layer types with host-endian fields in the header, fix + those fields if capturing from a server with a different byte + order. + Suppress temporarily the warnings with "enable remote packet capture". + Windows: + Add support for NdisMediumIP (pull request #1027). + Don't require applications using pcap to be built with VS 2015 or + later. + Use the correct string for the DLL VersionInfo. + Remove unnecessary DllMain() function. + Correctly handle ERROR_INVALID_FUNCTION from + PacketGetTimestampModes() (indicate that WinPcap or an older + version of Npcap is probably installed). + Fix use-after-free in some cases when a pcap_t is closed. + Make sure an error is returned by pcap_create_interface() if + PacketOpenAdapter() fails. + Return an error if the driver reports 0 timestamp modes supported. + Close the ADAPTER handle for some errors in + pcap_create_interface(). + Get rid of old umaintained VS project files. + Fix deprecation warning for pcap_handle(). + Npcap is now at npcap.com, not npcap.org. + Make sure "no such device" and "no permission to open device" + errors show up in pcap_activate(), not pcap_create() (fixes, + among other things, tcpdump -i ). + npcap: squelch deprecation warnings for kernel dump mode. + Haiku: + Implement pcap_lib_version(), as now required. + Handle negative or too-large snaplen values. + Fix various build issues and warnings. + Building and testing: + Update configure-time universal build checks for macOS. + Update config.guess and config.sub. + If we look for an SSL library with pkg-config in configure script, + try pkg-config first. + If we have pkg-config and Homebrew, try to set pkg-config up to + find Homebrew packages. + Handle some Autoconf/make errors better. + Use "git archive" for the "make releasetar" process. + Remove the release candidate rcX targets. + Fix compiling on Solaris 9/SPARC and 11/AMD64. + Address assorted compiler warnings. + Fix cross-building on Linux for Windows with mingw32 for Win64 + (pull request #1031). + Properly set installation directory on Windows when not compiling + with MSVC. + Fix configure script checks for compiler flags. + Give more details if check for usable (F)Lex fails. + Fix compiling with GCC 4.6.4. + Don't use add_compile_options() with CMake, as we currently don't + require 2.8.12, where it first appeared. + Don't provide -L/usr/lib for pkg-config --libs in pkg-config. + Fix error message for inadequate Bison/Berkeley YACC. + configure: correctly do some DPDK checks. + Only use pkg-config when checking for DPDK. + Allow the path in which DPDK is installed to be specified. + Use pkg-config first when checking for libibverbs. + CMake: fix check for libibverbs with Sun's C compiler. + Have CMake warn if no capture mechanism can be found. + Don't do stuff requiring 3.19 or later on earlier CMakes. + Squelch some CMake warnings. + Fix diag-control.h to handle compiling with clang-cl (issues + #1101 and #1115). + Cleanup various leftover cruft in the configure script. + Fix building without protochain support. (GH #852) + Check for a usable YACC (or Bison) and {F}lex in CMake, as we do + in autotools. + Only check for a C++ compiler on Haiku, as that's the only + platform with C++ code, and make sure they generate code for + the same instruction set bit-width (both 32-bit or both 64-bit) + (issue #1112). + On Solaris, check the target bit-width and set PKG_CONFIG_PATH + appropriately, to handle the mess that is the D-Bus library + package (issue #1112). + Fix generation of pcap-config and libpcap.pc files (issue #1062). + pcap-config: don't assume the system library directory is /usr/lib. + pcap-config: add a --static-pcap-only flag. + Cirrus CI: Use the same configuration as for the main branch. + Add four libpcap test files. + Update Npcap SDK to 1.13. + Makefile.in: Use TEST_DIST, like for tcpdump. + Remove awk code from mkdep. + Cirrus CI: Add the libssl-dev package in the Linux task. + Cirrus CI: Add the openssl@3 brew package in the macOS task. + Get "make shellcheck" to pass again. + CMake: Build valgrindtest only if Autoconf would. + CMake: use ${CMAKE_INSTALL_SBINDIR} rather than just sbin. + CMake: use NUL: as the null device on Windows. + autoconf: fix typo in test of macOS version. + Makefile.in: Add two missing files in EXTRA_DIST. + autotools, cmake: provide an rpath option if necessary. + configure: get rid of the attempt to auto-run PKG_PROG_PKG_CONFIG. + configure: use PKG_CHECK_MODULES to run pkg-config. + Documentation: + Add README.solaris.md. + Add SCTP to pcap-filter(7). + Note that = and == are the same operator in filters (issue #1044). + Update INSTALL.md, README.md, and README.solaris.md. + Update and clean up CONTRIBUTING.md. + Trim documentation of support for now-dead UN*Xe and older + versions of other UN*Xes. + Move the "how to allocate a LINKTYPE_/DLT_ value" documentation to + the web site. + Clean up man pages. + Move README.capture-module to the web site. + Improve some protocol details in pcap-filter(7). + Refine "relop" notes in pcap-filter(7). + In pcap-filter(7) "domain" is an id. + Discuss backward compatibility in pcap-filter(7). + Other improvements to pcap-filter(7). + Document pcap_breakloop(3PCAP) interaction with threads better. + Document PCAP_ERROR_NOT_ACTIVATED for more routines. + +Wednesday, June 9, 2021: + Summary for 1.10.1 libpcap release: + Packet filtering: + Fix "type XXX subtype YYY" giving a parse error + Source code: + Add PCAP_AVAILABLE_1_11. + Building and testing: + Rename struct bpf_aux_data to avoid NetBSD compile errors + Squelch some compiler warnings + Squelch some Bison warnings + Fix cross-builds with older kernels lacking BPF_MOD and BPF_XOR + Fix Bison detection for minor version 0. + Fix parallel build with FreeBSD make. + Get DLT_MATCHING_MAX right in gencode.c on NetBSD. + Define timeradd() and timersub() if necessary. + Fix Cygwin/MSYS target directories. + Fix symlinking with DESTDIR. + Fix generation of libpcap.pc with CMake when not building a shared + library. + Check for Arm64 as well as x86-64 when looking for packet.lib on + Windows. + Documentation: + Refine Markdown in README.md. + Improve the description of portrange in filters. + README.linux.md isn't Markdown, rename it just README.linux. + pcapng: + Support reading version 1.2, which some writers produce, and which + is the same as 1.0 (some new block types were added, but + that's not sufficient reason to bump the minor version number, + as code that understands those new block types can handle them + in a 1.0 file) + Linux: + Drop support for text-mode USB captures, as we require a 2.6.27 + or later kernel (credit to Chaoyuan Peng for noting the + sscanf vulnerabilities in the text-mode code that got me to + realize that we didn't need this code any more) + Bluetooth: fix non-blocking mode. + Don't assume that all compilers used to build for Linux support + the __atomic builtins + Windows: + Add more information in "interface disappeared" error messages, in + the hopes of trying to figure out the cause. + Treat ERROR_DEVICE_REMOVED as "device was removed". + Indicate in the error message which "device was removed" error + occurred. + Report the Windows error status if PacketSendPacket() fails. + Use %lu for ULONGs in error message formats. + Don't treat the inability to find airpcap.dll as an error. + Ignore spurious error reports by Microsoft Surface mobile + telephony modem driver + rpcap: + Clean up error checking and error messages for server address + lookup. + +Tuesday, December 29, 2020 + Summary for 1.10.0 libpcap release + Add support for capturing on DPDK devices + Label most APIs by the first release in which they're available + Fix some memory leaks, including in pcap_compile() + Add pcap_datalink_val_to_description_or_dlt() + Handle the pcap private data in a fashion that makes fewer + assumptions about memory layouts (might fix GitHub issue #940 + on ARM) + Fix some thread safety issues + pcap_findalldevs(): don't sort interfaces by unit number + Always return a list of supported time-stamp types, even if only + host time stamps are supported + Increase the maximum snaplen for LINKTYPE_USBPCAP/DLT_USBPCAP + Report the DLT description in error messages + Add pcap_init() for first-time initialization and global option + setting; it's not required, but may be used + Remove (unused) SITA support + Capture file reading: + Correctly handle pcapng captures with more than one IDB with a + snspshot length greater than the supported maximum + Capture file writing: + Create the file in pcap_dump_open_append() if it doesn't exist + Packet filtering: + Fix "unknown ether proto 'aarp'" + Add a new filter "ifindex" for DLT_LINUX_SLL2 files on all + platforms and live Linux captures + Add a hack to the optimizer to try to catch certain optimizer + loops (should prevent GitHub issue #112) + Show special Linux BPF offsets symbolically in bpf_image() and + bpf_dump() + Added support for ICMPv6 types 1-4 as tokens with names + Remove undocumented and rather old "ether proto" protocols + Catch invalid IPv4 addresses in filters + Don't assume ARM supports unaligned accesses + Security and other issues found by analysis: + Fix various security issues reported by Charles Smith at Tangible + Security + Fix various security issues reported by Include Security + Fix some issues found by cppcheck. + Add some overflow checks in the optimizer + rpcap: + Support rpcap-over-TLS + Redo protocol version negotiation to avoid problems with old + servers (it still works with servers using the old negotiation, + as well as servers not supporting negotiation) + Error handling cleanups + Add some new authentication libpcap error codes for specific + errors + Fix some inetd issues in rpcapd + Fix rpcapd core dumps with invalid configuration file + On UN*X, don't have rpcapd tell the client why authentication + failed, so a brute-force attacker can't distinguish between + "unknown user name" and "known user name, wrong password" + Allow rpcapd to rebind more rapidly (GitHub issue #765) + Documentation: + Improve man pages, including adding backward compatibility notes + Building and testing: + Require, and assume, some level of C99 support in the C compiler + Require Visual Studio 2015 or later if using Visual Studio + Fix configure script issues, including with libnl on Linux + Fix CMake issues + Squelch complaints from Bison about "%define api.pure" being + deprecated + Fix compilation of pcap-tc.c + Linux: + Require PF_PACKET support, and kernel 2.6.27 or later + Handle systems without AF_INET or AF_UNIX socket support + Get rid of Wireless Extensions for turning monitor mode on + Proper memory sync for PACKET_MMAP (may prevent GitHub issue + #898) + Drop support for libnl 1 and 2. + Return error on interface going away, but not if it just went + down but is still present + Set socket protocol only after packet ring configured, + reducing bogus packet drop reports + Get ifdrop stats from sysfs. + When adjusting BPF programs, do not subtract the + SLL[2]_HDR_LEN if the location is negative (special metadata + offset), to preserve references to metadata; see + https://github.com/the-tcpdump-group/tcpdump/issues/480#issuecomment-486827278 + Report a warning for unknown ARPHRD types + Have pcap_breakloop() forcibly break out of a sleeping + capture loop + Add support for DSA data link types + For raw USB bus capture, use the snapshot length to set the + buffer size, and set the len field to reflect the length + in the URB (GitHub issue #808) + With a timeout of zero, wait indefinitely + Clean up support for some non-GNU libc C libraries + Add DLT_LINUX_SLL2 for cooked-mode captures + Probe CONFIGURATION descriptor of connected USB devices + Treat EPERM on ethtool ioctls as meaning "not supported", as + permissions checks are done before checking whether the + ioctl is supported at all + macOS: + Cope with getting EPWROFF from SIOCGIFMEDIA + Treat EPERM on SIOCGIFMEDIA as meaning "not supported", as + permissions checks are done before checking whether the + ioctl is supported at all + Treat ENXIO when reading packets as meaning "the interface + was removed" + Report "the interface disappeared", not "the interface went + down", if the interface was removed during a capture + FreeBSD: + Treat ENXIO as meaning "the interface was removed" + Report "the interface disappeared", not "the interface went + down", if the interface was removed during a capture + NetBSD: + Treat ENXIO as meaning "the interface was removed" + Report "the interface disappeared", not "the interface went + down", if the interface was removed during a capture + OpenBSD: + Treat EIO as meaning "the interface was removed" + Report "the interface disappeared", not "the interface went + down", if the interface was removed during a capture + DragonFly BSD: + Treat ENXIO as meaning "the interface was removed" + Report "the interface disappeared", not "the interface went + down", if the interface was removed during a capture + Solaris: + Treat ENXIO as meaning "the interface was removed" + Report "the interface disappeared", not "the interface went + down", if the interface was removed during a capture + AIX: + Fix loading of BPF kernel extension + Treat ENXIO as meaning "the interface was removed" + Report "the interface disappeared", not "the interface went + down", if the interface was removed during a capture + Windows: + Make the snapshot length work even if pcap_setfilter() + isn't called + Fix compilation on Cygwin/MSYS + Add pcap_handle(), and deprecate pcap_fileno() + Report PCAP_ERROR_NO_SUCH_DEVICE for a non-existent device + Return an appropriate error message for device removed or + device unusable due to a suspend/resume + Report a warning for unknown NdisMedium types + Have pcap_breakloop() forcibly break out of a sleeping + capture loop + Clean up building DLL + Handle CRT mismatch for pcap_dump_fopen() + Map NdisMediumWirelessWan to DLT_RAW + Add AirPcap support in a module, rather than using + WinPcap/Npcap's support for it + Report the system error for PacketSetHwFilter() failures + Add support for getting and setting packet time stamp types + with Npcap + Have pcap_init() allow selecting whether the API should use + local code page strings or UTF-8 strings (including error + messages) + Haiku: + Add capture support + Sunday, July 22, 2018 Summary for 1.9.1 libpcap release Mention pcap_get_required_select_timeout() in the main pcap man page @@ -26,7 +469,7 @@ Sunday, July 22, 2018 need to be Fix reading of capture statistics for Linux USB Fix packet size values for Linux USB packets (GitHub issue #808) - Check only VID in VLAN test in filterss (GitHub issue #461) + Check only VID in VLAN test in filters (GitHub issue #461) Fix pcap_list_datalinks on 802.11 devices on macOS Fix overflows with very large snapshot length in pcap file Improve parsing of rpcapd configuration file (GitHub issue #767) @@ -67,7 +510,6 @@ Sunday, July 22, 2018 Boost the TPACKET_V3 timeout to the maximum if a timeout of 0 was specified Five CVE-2019-15161, CVE-2019-15162, CVE-2019-15163, CVE-2019-15164, CVE-2019-15165 - Fixes for CVE-2018-16301, errors in pcapng reading. PCAPNG reader applies some sanity checks before doing malloc(). Sunday, June 24, 2018, by mcr@sandelman.ca @@ -75,7 +517,7 @@ Sunday, June 24, 2018, by mcr@sandelman.ca 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 + Changes to BSD 3-clause license to 2-clause license Additions to TCP header parsing, per RFC3168 Add CMake build process (extensive number of changes) Assign a value for OpenBSD DLT_OPENFLOW. @@ -93,7 +535,7 @@ Sunday, June 24, 2018, by mcr@sandelman.ca 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 + Added DLT_VSOCK for https://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 @@ -275,7 +717,7 @@ Summary for 1.5.0 libpcap release than the mcr repository Checks added for malloc()/realloc()/etc. failures Fixed build on Solaris 11 - Support filtering filtering E1 SS7 traffic on MTP2 layer Annex A + Support filtering E1 SS7 traffic on MTP2 layer Annex A Use "ln -s" to link man pages by default Add support for getting nanosecond-resolution time stamps when capturing and reading capture files @@ -336,7 +778,7 @@ Summary for 1.3.0 libpcap release Friday December 9, 2011. guy@alum.mit.edu. Summary for 1.2.1 libpcap release Update README file. - Fix typoes in README.linux file. + Fix typos in README.linux file. Clean up some compiler warnings. Fix Linux compile problems and tests for ethtool.h. Treat Debian/kFreeBSD and GNU/Hurd as systems with GNU @@ -369,7 +811,7 @@ Summary for 1.2 libpcap release Noted real nature of LINKTYPE_ARCNET. Add a link-layer type for DVB-CI. Fix configure-script discovery of VLAN acceleration support. - see http://netoptimizer.blogspot.com/2010/09/tcpdump-vs-vlan-tags.html + see https://netoptimizer.blogspot.com/2010/09/tcpdump-vs-vlan-tags.html Linux, HP-UX, AIX, NetBSD and OpenBSD compilation/conflict fixes. Protect against including AIX 5.x's having been included. Add DLT_DBUS, for raw D-Bus messages. @@ -568,7 +1010,7 @@ Tue. September 19, 2006. ken@xelerance.com. Summary for 0.9.5 libpcap release beginning+link-layer Add DLT/LINKTYPE for carrying FRF.16 Multi-link Frame Relay Fix allocation of buffer for list of link-layer types - Added a new DLT and LINKTYPE value for ARINC 653 Interpartition Communcation Messages + Added a new DLT and LINKTYPE value for ARINC 653 Interpartition Communication Messages Fixed a typo in a DLT value: it should start with DLT_ and not LINKTYPE_ Redefined DLT_CAN20B and LINKTYPE_CAN20B as #190 (as this is the right value for CAN). Added definition for DLT_A429 and LINKTYPE_A429 as #184. @@ -582,7 +1024,7 @@ Tue. September 19, 2006. ken@xelerance.com. Summary for 0.9.5 libpcap release Add support to build libpcap.lib and wpcap.dll under Cygnus and MingW32. -Mon. September 5, 2005. ken@xelerance.com. Summary for 0.9.4 libpcap release +Mon. September 5, 2005. ken@xelerance.com. Summary for 0.9.4 libpcap release Support for radiotap on Linux (Mike Kershaw) Fixes for HP-UX @@ -593,7 +1035,7 @@ Mon. September 5, 2005. ken@xelerance.com. Summary for 0.9.4 libpcap release parts of the filter expression to look at the PPP headers and headers in the PPP payload -Tue. July 5, 2005. ken@xelerance.com. Summary for 0.9.3 libpcap release +Tue. July 5, 2005. ken@xelerance.com. Summary for 0.9.3 libpcap release Fixes for compiling on nearly every platform, including improved 64bit support @@ -632,16 +1074,16 @@ Wed. November 12, 2003. mcr@sandelman.ottawa.on.ca. Summary for 0.8 release Tuesday, February 25, 2003. fenner@research.att.com. 0.7.2 release - Support link types that use 802.2 always, never, and sometimes. - Don't decrease the size of the BPF buffer from the default. - Support frame relay. - Handle 32-bit timestamps in DLPI, and pass the right buffer size. - Handle Linux systems with modern kernel but without - SOL_PACKET in the userland headers. - Linux support for ARPHRD_RAWHDLC. - Handle 32-bit timestamps in snoop. - Support eg (Octane/O2xxx/O3xxx Gigabit) devices. - Add new reserved DLT types. + Support link types that use 802.2 always, never, and sometimes. + Don't decrease the size of the BPF buffer from the default. + Support frame relay. + Handle 32-bit timestamps in DLPI, and pass the right buffer size. + Handle Linux systems with modern kernel but without + SOL_PACKET in the userland headers. + Linux support for ARPHRD_RAWHDLC. + Handle 32-bit timestamps in snoop. + Support eg (Octane/O2xxx/O3xxx Gigabit) devices. + Add new reserved DLT types. Monday October 23, 2001. mcr@sandelman.ottawa.on.ca. Summary for 0.7 release @@ -682,7 +1124,7 @@ Tuesday January 9, 2001. guy@alum.mit.edu. Summary for 0.6 release Header files fixed to allow use in C++ programs. - Removed dependancy on native headers for packet layout. + Removed dependency on native headers for packet layout. Removed Linux specific headers that were shipped. Security fixes: Strcpy replaced with strlcpy, sprintf replaced @@ -820,7 +1262,7 @@ v0.3 Sat Nov 30 20:56:27 PST 1996 v0.2.1 Sun Jul 14 03:02:26 PDT 1996 -- Fixes for HP-UX 10. Thanks in part to to Thomas Wolfram +- Fixes for HP-UX 10. Thanks in part to Thomas Wolfram (wolf@prz.tu-berlin.de) and Rick Jones (raj@hpisrdq.cup.hp.com) - Added support for SINIX. Thanks to Andrej Borsenkow diff --git a/external/bsd/libpcap/dist/CMakeLists.txt b/external/bsd/libpcap/dist/CMakeLists.txt index 55b93f14d74c..58c5159905d0 100644 --- a/external/bsd/libpcap/dist/CMakeLists.txt +++ b/external/bsd/libpcap/dist/CMakeLists.txt @@ -1,4 +1,11 @@ -cmake_minimum_required(VERSION 2.8.6) +if(WIN32) + # + # We need 3.12 or later, so that we can set policy CMP0074; see + # below. + cmake_minimum_required(VERSION 3.12) +else(WIN32) + cmake_minimum_required(VERSION 2.8.6) +endif(WIN32) # # Apple doesn't build with an install_name starting with @rpath, and @@ -9,44 +16,308 @@ if(POLICY CMP0042) cmake_policy(SET CMP0042 OLD) endif() +# +# Squelch noise about quoted strings in if() statements. +# WE KNOW WHAT WE'RE DOING, WE'RE DOING EVERYTHING THE WAY THAT NEWER +# VERSIONS OF CMAKE EXPECT BY DEFAULT, DON'T WASTE OUR TIME WITH NOISE. +# +if(POLICY CMP0054) + cmake_policy(SET CMP0054 NEW) +endif() + +# +# We want find_file() and find_library() to honor {packagename}_ROOT, +# as that appears to be the only way, with the Visual Studio 2019 IDE +# and its CMake support, to tell CMake where to look for the Npcap +# or WinPcap SDK. +# +if(POLICY CMP0074) + cmake_policy(SET CMP0074 NEW) +endif() + +# +# We want check_include_file() to honor CMAKE_REQUIRED_LIBRARIES; see +# the big comment before the check_include_file() test for +# infiniband/verbs.h for the reason. +# +if(POLICY CMP0075) + cmake_policy(SET CMP0075 NEW) +endif() + set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules) -project(pcap) +# +# We only need a C++ compiler for Haiku; all code except for its +# pcap module is in C. +# +# We do that by specifying just C in the project() call and, after +# that finishes, checking for Haiku and, if we're building for +# Haiku, use enable_language() to check for C++. This means that +# we don't require a C++ compiler on platforms other than Haiku. +# +# CMAKE_SYSTEM_NAME is set by project(), so we can't do this by +# testing CMAKE_SYSTEM_NAME and then passing different language +# lists to project() based on the system. +# +project(pcap C) # -# Try to enable as many C99 features as we can. -# At minimum, we want C++/C99-style // comments. +# For getting raw lists of --libs and --libs --static information from a +# pkg-config module. # -# Newer versions of compilers might default to supporting C99, but older -# versions may require a special flag. +# In CMake up to 2.8.12, pkg_check_modules() sets: # -# 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. +# _LIBRARIES, which is a list of library names to which, on +# a UN*X, -l can be prefixed - i.e., names, without extensions, +# rather than full paths to the file. +# _LIBRARY_DIRS, which is a list of paths to directories +# containing the libraries, to which, on a UN*X, -L can be +# prefixed. +# _LDFLAGS, which is a list of *all* required linker flags +# _LDFLAGS_OTHER, which is a list of all linker flags other +# than -l and -L flags # -# 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. +# In 3.0 (at least as of 3.0.2), it also sets: # -# See the CMake documentation for the CMAKE__COMPILER_ID variables -# for a list of compiler IDs. +# _LINK_LIBRARIES, which is a list of full paths to the +# library files. # -# 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. +# but if is _STATIC, _LINK_LIBRARIES is +# currently not set by CMake. # -# 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. +# Unfortunately, pkg_check_modules() sets the +# PKG_CONFIG_ALLOW_SYSTEM_LIBS environment variable when running +# pkg-config, so the output of --libs, etc. may include a -L for the +# system library, which we do *NOT* want to put in our libpcap.pc and +# pcap-config files. # +# So we just run pkg-config ourselves, so that we get its output +# directly without any processing by CMake. +# +macro(pkg_get_link_info _prefix _package) + if (PKG_CONFIG_EXECUTABLE) + # + # Get the --libs information. + # + # We force PKG_CONFIG_ALLOW_SYSTEM_LIBS to be undefined, as + # at least some versions of CMake appear to define it in + # pkg_check_modules() before running pkg-config and *not* undefine + # it after running it. + # + unset(ENV{PKG_CONFIG_ALLOW_SYSTEM_LIBS}) + set(_pkg_config_result "") + execute_process( + COMMAND ${PKG_CONFIG_EXECUTABLE} "--libs" ${_package} + OUTPUT_VARIABLE _pkg_config_result + RESULT_VARIABLE _pkg_config_failed + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if (_pkg_config_failed) + # + # pkg-config failed; assume that means that there is no such + # package for it to find. XXX - what do we do here? + # + set(${_prefix}_FOUND_WITH_PKG_CONFIG FALSE) + else() + # + # pkg-config succeeded; replace CR and LF with spaces. + # + string(REGEX REPLACE "[\r\n]" " " ${_prefix}_LIBS "${_pkg_config_result}") + + # + # Now get the --libs --static information. + # + set(_pkg_config_result "") + execute_process( + COMMAND ${PKG_CONFIG_EXECUTABLE} "--libs" "--static" ${_package} + OUTPUT_VARIABLE _pkg_config_result + RESULT_VARIABLE _pkg_config_failed + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if (_pkg_config_failed) + # + # pkg-config failed; assume that means that there is no such + # package for it to find. XXX - what do we do here? + # + set(${_prefix}_FOUND_WITH_PKG_CONFIG FALSE) + else() + # + # pkg-config succeeded; replace CR and LF with spaces. + # + string(REGEX REPLACE "[\r\n]" " " ${_prefix}_LIBS_STATIC "${_pkg_config_result}") + + # + # List this package in its PACKAGE_NAME variable. + # + set(${_prefix}_PACKAGE_NAME "${_package}") + + # + # It worked. + # + set(${_prefix}_FOUND_WITH_PKG_CONFIG TRUE) + endif() + endif() + endif() +endmacro() + +macro(get_link_info_from_library_path _library_prefix _library_name) + if(NOT ${_library_prefix}_LIBRARY STREQUAL "${_library_prefix}_LIBRARY-NOTFOUND") + get_filename_component(_lib_directory "${${_library_prefix}_LIBRARY}}" DIRECTORY) + + # + # The closest thing to a list of "system library directories" in + # which the linker will, by default, search for libraries appears to + # be CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES, so that's what we use + # when we're trying to construct a -L argument, for insertion into + # pcap-config and libpcap.pc, for a library upon which we depend. + # + # In some versions of CMake it appears to have duplicate entries, + # but that shouldn't affect a search for a directory in that list. + # + list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${_lib_directory}" _lib_index) + if(_lib_index EQUAL -1) + # + # No, so add a -L flag to get the linker to search in that + # directory. + # + set(${_library_prefix}_LIBS "-L${_lib_directory}") + set(${_library_prefix}_LIBS_STATIC "-L${_lib_directory}") + set(${_libraryprefix}_LIBS_PRIVATE "-L${_lib_directory}") + endif() + set(${_library_prefix}_LIBS "${${_library_prefix}_LIBS} -l${_library_name}") + set(${_library_prefix}_LIBS_STATIC "${${_library_prefix}_LIBS} -l${_library_name}") + set(${_library_prefix}_LIBS_PRIVATE "${${_library_prefix}_LIBS} -l${_library_name}") + endif() +endmacro() + +if(CMAKE_SYSTEM_NAME STREQUAL "Haiku") + enable_language(CXX) + + # + # OK, this is a royal pain. + # + # CMake will try to determine the sizes of some data types, including + # void *, early in the process of configuration; apparently, it's done + # as part of processing the project() command. + # + # At least as of CMake 2.8.6, it does so by checking the size of + # "void *" in C, setting CMAKE_C_SIZEOF_DATA_PTR based on that, + # setting CMAKE_SIZEOF_VOID_P to that, and then checking the size + # of "void *" in C++, setting CMAKE_CXX_SIZEOF_DATA_PTR based on + # that, and then setting CMAKE_SIZEOF_VOID_P to *that*. + # + # The compile tests include whatever C flags may have been provided + # to CMake in the CFLAGS and CXXFLAGS environment variables. + # + # If you set an architecture flag such as -m32 or -m64 in CFLAGS + # but *not* in CXXFLAGS, the size for C++ will win, and hilarity + # will ensue. + # + # Or if, at least on Solaris, you have a newer version of GCC + # installed, but *not* a newer version of G++, and you have Oracle + # Studio installed, it will find GCC, which will default to building + # 64-bit, and Oracle Studio's C++ compiler, which will default to + # building 32-bit, the size for C++ will win, and, again, hilarity + # will ensue. + # + # So we make sure both languages have the same pointer sizes with + # the flags they're given; if they don't, it means that the + # compilers for the languages will, with those flags, not produce + # code that can be linked together. + # + # This is unlikely to happen on Haiku, but it *has* happened on + # Solaris; we do this for future-proofing, in case we ever need + # C++ on a platform where that can happen. + # + if(NOT ${CMAKE_C_SIZEOF_DATA_PTR} EQUAL ${CMAKE_CXX_SIZEOF_DATA_PTR}) + message(FATAL_ERROR +"C compiler ${CMAKE_C_COMPILER} produces code with \ +${CMAKE_C_SIZEOF_DATA_PTR}-byte pointers while C++ compiler \ +${CMAKE_CXX_COMPILER} produces code with \ +${CMAKE_CXX_SIZEOF_DATA_PTR}-byte pointers. \ +This prevents code in these languages from being combined.") + endif() +endif() + +# +# Show the bit width for which we're compiling. +# This can help debug problems if you're dealing with a compiler that +# defaults to generating 32-bit code even when running on a 64-bit +# platform, and where that platform may provide only 64-bit versions of +# libraries that we might use (looking at *you*, Oracle Studio!). +# +if(CMAKE_SIZEOF_VOID_P EQUAL 4) + message(STATUS "Building 32-bit") +elseif(CMAKE_SIZEOF_VOID_P EQUAL 8) + message(STATUS "Building 64-bit") +endif() + +# +# Solaris pkg-config is annoying. For at least one package (D-Bus, I'm +# looking at *you*!), there are separate include files for 32-bit and +# 64-bit builds (I guess using "unsigned long long" as a 64-bit integer +# type on a 64-bit build is like crossing the beams or soething), and +# there are two separate .pc files, so if we're doing a 32-bit build we +# should make sure we look in /usr/lib/pkgconfig for .pc files and if +# we're doing a 64-bit build we should make sure we look in +# /usr/lib/amd64/pkgconfig for .pc files. +# +if(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION MATCHES "5[.][0-9.]*") + # + # Note: string(REPLACE) does not appear to support using ENV{...} + # as an argument, so we set a variable and then use set() to set + # the environment variable. + # + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + # + # 64-bit build. If /usr/lib/pkgconfig appears in the path, + # prepend /usr/lib/amd64/pkgconfig to it; otherwise, + # put /usr/lib/amd64 at the end. + # + if((NOT DEFINED ENV{PKG_CONFIG_PATH}) OR "$ENV{PKG_CONFIG_PATH}" EQUAL "") + # + # Not set, or empty. Set it to /usr/lib/amd64/pkgconfig. + # + set(fixed_path "/usr/lib/amd64/pkgconfig") + elseif("$ENV{PKG_CONFIG_PATH}" MATCHES "/usr/lib/pkgconfig") + # + # It contains /usr/lib/pkgconfig. Prepend + # /usr/lib/amd64/pkgconfig to /usr/lib/pkgconfig. + # + string(REPLACE "/usr/lib/pkgconfig" + "/usr/lib/amd64/pkgconfig:/usr/lib/pkgconfig" + fixed_path "$ENV{PKG_CONFIG_PATH}") + else() + # + # Not empty, but doesn't contain /usr/lib/pkgconfig. + # Append /usr/lib/amd64/pkgconfig to it. + # + set(fixed_path "$ENV{PKG_CONFIG_PATH}:/usr/lib/amd64/pkgconfig") + endif() + set(ENV{PKG_CONFIG_PATH} "${fixed_path}") + elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) + # + # 32-bit build. If /usr/amd64/lib/pkgconfig appears in the path, + # prepend /usr/lib/pkgconfig to it. + # + if("$ENV{PKG_CONFIG_PATH}" MATCHES "/usr/lib/amd64/pkgconfig") + # + # It contains /usr/lib/amd64/pkgconfig. Prepend + # /usr/lib/pkgconfig to /usr/lib/amd64/pkgconfig. + # + string(REPLACE "/usr/lib/amd64/pkgconfig" + "/usr/lib/pkgconfig:/usr/lib/amd64/pkgconfig" + fixed_path "$ENV{PKG_CONFIG_PATH}") + set(ENV{PKG_CONFIG_PATH} "${fixed_path}") + endif() + endif() +endif() + include(CheckCCompilerFlag) + +# +# For checking if a compiler flag works and adding it if it does. +# macro(check_and_add_compiler_option _option) message(STATUS "Checking C compiler flag ${_option}") string(REPLACE "=" "-" _temp_option_variable ${_option}) @@ -57,23 +328,105 @@ macro(check_and_add_compiler_option _option) endif() endmacro() +# +# If we're building with Visual Studio, we require Visual Studio 2015, +# in order to get sufficient C99 compatibility. Check for that. +# +# If not, try the appropriate flag for the compiler to enable C99 +# features. +# 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() +if(MSVC) + if(MSVC_VERSION LESS 1900) + message(FATAL_ERROR "Visual Studio 2015 or later is required") + endif() + + # + # Treat source files as being in UTF-8 with MSVC if it's not using + # the Clang front end. + # We assume that UTF-8 source is OK with other compilers and with + # MSVC if it's using the Clang front end. + # + if(NOT ${CMAKE_C_COMPILER} MATCHES "clang*") + set(C_ADDITIONAL_FLAGS "${C_ADDITIONAL_FLAGS} /utf-8") + endif(NOT ${CMAKE_C_COMPILER} MATCHES "clang*") +else(MSVC) + # + # For checking if a compiler flag works, failing if it doesn't, + # and adding it otherwise. + # + macro(require_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}") + else() + message(FATAL_ERROR "C99 support is required, but the compiler doesn't support a compiler flag to enable it") + endif() + endmacro() + + # + # 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__COMPILER_ID variables + # for a list of compiler IDs. + # + # XXX - this just tests whether the option works, fails if it doesn't, + # and adds it if it does. We don't test whether it's necessary in order + # to get the C99 features that we use, or whether, if it's used, it + # enables all the features that we require. + # + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR + CMAKE_C_COMPILER_ID MATCHES "Clang") + require_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. + # + require_and_add_compiler_option("-qlanglvl=extc99") + elseif(CMAKE_C_COMPILER_ID MATCHES "HP") + require_and_add_compiler_option("-AC99") + elseif(CMAKE_C_COMPILER_ID MATCHES "Sun") + require_and_add_compiler_option("-xc99") + elseif(CMAKE_C_COMPILER_ID MATCHES "Intel") + require_and_add_compiler_option("-c99") + endif() +endif(MSVC) + +# +# If we're building with MinGW, we need to specify _WIN32_WINNT as +# 0x0600 ("NT 6.0", a/k/a Vista/Windows Server 2008) or higher +# in order to get the full IPv6 API, including inet_ntop(), and we +# need to specify it as 0x0601 ("NT 6.1", a/k/a Windows 7) or higher +# in order to get NdisMediumIP. +# +# NOTE: pcap does *NOT* work with msvcrt.dll; it must link with +# a newer version of the C library, i.e. Visual Studio 2015 or +# later, as it depends on C99 features introduced in VS 2015. +# +if(MINGW) + add_definitions(-D_WIN32_WINNT=0x0601) +endif(MINGW) # # Build all runtimes in the top-level binary directory; that way, @@ -106,10 +459,14 @@ if(WIN32) option(USE_STATIC_RT "Use static Runtime" ON) endif(WIN32) option(BUILD_SHARED_LIBS "Build shared libraries" ON) +set(dpdk_ROOT "" CACHE PATH "Path to directory with include and lib subdirectories for DPDK") if(WIN32) - set(PACKET_DLL_DIR "" CACHE PATH "Path to directory with include and lib subdirectories for packet.dll") + set(Packet_ROOT "" CACHE PATH "Path to directory with include and lib subdirectories for packet.dll") + set(AirPcap_ROOT "" CACHE PATH "Path to directory with include and lib subdirectories for airpcap.dll") endif(WIN32) +option(ENABLE_PROFILING "Enable code profiling" OFF) + # To pacify those who hate the protochain instruction option(NO_PROTOCHAIN "Disable protochain instruction" OFF) @@ -131,16 +488,19 @@ else() 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() # # Additional capture modules. # -option(DISABLE_USB "Disable USB sniffing support" OFF) +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + option(DISABLE_LINUX_USBMON "Disable Linux usbmon USB sniffing support" OFF) +endif() option(DISABLE_BLUETOOTH "Disable Bluetooth sniffing support" OFF) option(DISABLE_NETMAP "Disable netmap support" OFF) +option(DISABLE_DPDK "Disable DPDK support" OFF) + # # We don't support D-Bus sniffing on macOS; see # @@ -221,25 +581,26 @@ if(WIN32) endif(IS_DIRECTORY ${CMAKE_HOME_DIRECTORY}/../../Common) find_package(Packet) - if(PACKET_FOUND) + if(Packet_FOUND) set(HAVE_PACKET32 TRUE) - include_directories(${PACKET_INCLUDE_DIRS}) + include_directories(${Packet_INCLUDE_DIRS}) # # Check whether we have the NPcap PacketIsLoopbackAdapter() # function. # cmake_push_check_state() - set(CMAKE_REQUIRED_LIBRARIES ${PACKET_LIBRARIES}) + set(CMAKE_REQUIRED_LIBRARIES ${Packet_LIBRARIES}) check_function_exists(PacketIsLoopbackAdapter HAVE_PACKET_IS_LOOPBACK_ADAPTER) + check_function_exists(PacketGetTimestampModes HAVE_PACKET_GET_TIMESTAMP_MODES) cmake_pop_check_state() - endif(PACKET_FOUND) + endif(Packet_FOUND) message(STATUS "checking for Npcap's version.h") - check_symbol_exists(WINPCAP_PRODUCT_NAME "../../version.h" HAVE_VERSION_H) + check_symbol_exists(WINPCAP_PRODUCT_NAME "${CMAKE_SOURCE_DIR}/../../version.h" HAVE_VERSION_H) if(HAVE_VERSION_H) - message(STATUS "HAVE version.h") + message(STATUS "HAVE version.h") else(HAVE_VERSION_H) - message(STATUS "MISSING version.h") + message(STATUS "MISSING version.h") endif(HAVE_VERSION_H) endif(WIN32) @@ -294,41 +655,49 @@ 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 -#include -#include -#include + check_include_file(netinet/if_ether.h HAVE_NETINET_IF_ETHER_H) +endif(NOT WIN32) -int +# +# Functions. +# +# First, check for the __atomic_load_n() and __atomic_store_n() +# builtins. +# +# We can't use check_function_exists(), as it tries to declare +# the function, and attempting to declare a compiler builtin +# can produce an error. +# +# We don't use check_symbol_exists(), as it expects a header +# file to be specified to declare the function, but there isn't +# such a header file. +# +# So we use check_c_source_compiles(). +# +check_c_source_compiles( +"int main(void) { - return PF_NAT+PF_NONAT+PF_BINAT+PF_NOBINAT+PF_RDR+PF_NORDR; + int i = 17; + return __atomic_load_n(&i, __ATOMIC_RELAXED); } " - 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) + HAVE___ATOMIC_LOAD_N) +check_c_source_compiles( +"int +main(void) +{ + int i; + __atomic_store_n(&i, 17, __ATOMIC_RELAXED); + return 0; +} +" + HAVE___ATOMIC_STORE_N) # -# Functions. +# Now check for various system functions. # check_function_exists(strerror HAVE_STRERROR) check_function_exists(strerror_r HAVE_STRERROR_R) @@ -356,14 +725,28 @@ main(void) endif(NOT HAVE_GNU_STRERROR_R) else(HAVE_STRERROR_R) # - # We don't have strerror_r; do we have strerror_s? + # We don't have strerror_r; do we have _wcserror_s? # - check_function_exists(strerror_s HAVE_STRERROR_S) + check_function_exists(_wcserror_s HAVE__WCSERROR_S) endif(HAVE_STRERROR_R) + +# +# Make sure we have vsnprintf() and snprintf(); we require them. +# We use check_symbol_exists(), as they aren't necessarily external +# functions - in Visual Studio, for example, they're inline functions +# calling a common external function. +# +check_symbol_exists(vsnprintf "stdio.h" HAVE_VSNPRINTF) +if(NOT HAVE_VSNPRINTF) + message(FATAL_ERROR "vsnprintf() is required but wasn't found") +endif(NOT HAVE_VSNPRINTF) +check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF) +if(NOT HAVE_SNPRINTF) + message(FATAL_ERROR "snprintf() is required but wasn't found") +endif() + check_function_exists(strlcpy HAVE_STRLCPY) check_function_exists(strlcat HAVE_STRLCAT) -check_function_exists(snprintf HAVE_SNPRINTF) -check_function_exists(vsnprintf HAVE_VSNPRINTF) check_function_exists(asprintf HAVE_ASPRINTF) check_function_exists(vasprintf HAVE_VASPRINTF) check_function_exists(strtok_r HAVE_STRTOK_R) @@ -397,6 +780,10 @@ endif() # that's been set, it skips the test, so we need different variables. # set(PCAP_LINK_LIBRARIES "") +set(LIBS "") +set(LIBS_STATIC "") +set(REQUIRES_PRIVATE "") +set(LIBS_PRIVATE "") include(CheckLibraryExists) if(WIN32) # @@ -432,11 +819,25 @@ else(WIN32) # OK, we found it in libsocket. # set(PCAP_LINK_LIBRARIES socket nsl ${PCAP_LINK_LIBRARIES}) + set(LIBS "-lsocket -lnsl ${LIBS}") + set(LIBS_STATIC "-lsocket -lnsl ${LIBS_STATIC}") + set(LIBS_PRIVATE "-lsocket -lnsl ${LIBS_PRIVATE}") else(LIBSOCKET_HAS_GETADDRINFO) - # - # We didn't find it. - # - message(FATAL_ERROR "getaddrinfo is required, but wasn't found") + check_library_exists(network getaddrinfo "" LIBNETWORK_HAS_GETADDRINFO) + if(LIBNETWORK_HAS_GETADDRINFO) + # + # OK, we found it in libnetwork (Haiku). + # + set(PCAP_LINK_LIBRARIES network ${PCAP_LINK_LIBRARIES}) + set(LIBS "-lnetwork ${LIBS}") + set(LIBS_STATIC "-lnetwork ${LIBS_STATIC}") + set(LIBS_PRIVATE "-lnetwork ${LIBS_PRIVATE}") + else(LIBNETWORK_HAS_GETADDRINFO) + # + # We didn't find it. + # + message(FATAL_ERROR "getaddrinfo is required, but wasn't found") + endif(LIBNETWORK_HAS_GETADDRINFO) endif(LIBSOCKET_HAS_GETADDRINFO) # @@ -452,6 +853,9 @@ else(WIN32) # Yes - link with it as well. # set(PCAP_LINK_LIBRARIES xnet ${PCAP_LINK_LIBRARIES}) + set(LIBSC "-lxnet ${LIBS_LIBS}") + set(LIBS_STATIC "-lxnet ${LIBS_STATIC}") + set(LIBS_PRIVATE "-lxnet ${LIBS_PRIVATE}") endif(LIBXNET_HAS_RECVMSG) endif(NOT STDLIBS_HAVE_GETADDRINFO) @@ -461,8 +865,20 @@ else(WIN32) check_library_exists(str putmsg "" LIBSTR_HAS_PUTMSG) if(LIBSTR_HAS_PUTMSG) set(PCAP_LINK_LIBRARIES str ${PCAP_LINK_LIBRARIES}) + set(LIBS "-lstr ${LIBS}") + set(LIBS_STATIC "-lstr ${LIBS_STATIC}") + set(LIBS_PRIVATE "-lstr ${LIBS_PRIVATE}") endif(LIBSTR_HAS_PUTMSG) endif(NOT STDLIBS_HAVE_PUTMSG) + + # Haiku has getpass in libbsd + check_function_exists(getpass STDLIBS_HAVE_GETPASS) + if(NOT STDLIBS_HAVE_GETPASS) + check_library_exists(bsd getpass "" LIBBSD_HAS_GETPASS) + if(LIBBSD_HAS_GETPASS) + set(PCAP_LINK_LIBRARIES bsd ${PCAP_LINK_LIBRARIES}) + endif(LIBBSD_HAS_GETPASS) + endif(NOT STDLIBS_HAVE_GETPASS) endif(WIN32) # @@ -812,6 +1228,195 @@ if(NOT WIN32) endif(NOT CMAKE_USE_PTHREADS_INIT) endif(NOT WIN32) +if(ENABLE_PROFILING) + if(NOT MSVC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pg") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") + endif() +endif() + +# +# Based on +# +# https://github.com/commonmark/cmark/blob/master/FindAsan.cmake +# +# The MIT License (MIT) +# +# Copyright (c) 2013 Matthew Arsenault +# +# 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. +# +# Test if the each of the sanitizers in the ENABLE_SANITIZERS list are +# supported by the compiler, and, if so, adds the appropriate flags to +# CMAKE_C_FLAGS, CMAKE_CXX_FLAGS, and SANITIZER_FLAGS. If not, it fails. +# +# Do this last, in the hope that it will prevent configuration on Linux +# from somehow deciding it doesn't need -lpthread when building rpcapd +# (it does require it, but somehow, in some mysterious fashion that no +# obvious CMake debugging flag reveals, it doesn't realize that if we +# turn sanitizer stuff on). +# +set(SANITIZER_FLAGS "") +foreach(sanitizer IN LISTS ENABLE_SANITIZERS) + # Set -Werror to catch "argument unused during compilation" warnings + + message(STATUS "Checking sanitizer ${sanitizer}") + set(sanitizer_variable "sanitize_${sanitizer}") + set(CMAKE_REQUIRED_FLAGS "-Werror -fsanitize=${sanitizer}") + check_c_compiler_flag("-fsanitize=${sanitizer}" ${sanitizer_variable}) + if(${${sanitizer_variable}}) + set(SANITIZER_FLAGS "${SANITIZER_FLAGS} -fsanitize=${sanitizer}") + message(STATUS "${sanitizer} sanitizer supported using -fsanitizer=${sanitizer}") + else() + # + # Try the versions supported prior to Clang 3.2. + # If the sanitizer is "address", try -fsanitize-address. + # If it's "undefined", try -fcatch-undefined-behavior. + # Otherwise, give up. + # + set(sanitizer_variable "OLD_${sanitizer_variable}") + if ("${sanitizer}" STREQUAL "address") + set(CMAKE_REQUIRED_FLAGS "-Werror -fsanitize-address") + check_c_compiler_flag("-fsanitize-address" ${sanitizer_variable}) + if(${${sanitizer_variable}}) + set(SANITIZER_FLAGS "${SANITIZER_FLAGS} -fsanitize-address") + message(STATUS "${sanitizer} sanitizer supported using -fsanitize-address") + else() + message(FATAL_ERROR "${sanitizer} isn't a supported sanitizer") + endif() + elseif("${sanitizer}" STREQUAL "undefined") + set(CMAKE_REQUIRED_FLAGS "-Werror -fcatch-undefined-behavior") + check_c_compiler_flag("-fcatch-undefined-behavior" ${sanitizer_variable}) + if(${${sanitizer_variable}}) + set(SANITIZER_FLAGS "${SANITIZER_FLAGS} -fcatch-undefined-behavior") + message(STATUS "${sanitizer} sanitizer supported using catch-undefined-behavior") + else() + message(FATAL_ERROR "${sanitizer} isn't a supported sanitizer") + endif() + else() + message(FATAL_ERROR "${sanitizer} isn't a supported sanitizer") + endif() + endif() + + unset(CMAKE_REQUIRED_FLAGS) +endforeach() + +if(NOT "${SANITIZER_FLAGS}" STREQUAL "") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O1 -g ${SANITIZER_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O1 -g ${SANITIZER_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls") +endif() + +# +# OpenSSL/libressl. +# +find_package(OpenSSL) +if(OPENSSL_FOUND) + # + # We have OpenSSL. + # + include_directories(SYSTEM ${OPENSSL_INCLUDE_DIR}) + set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${OPENSSL_LIBRARIES}) + + # + # The find_package() module CMake provides for OpenSSL uses does not + # give us a defined indication of whether it found OpenSSL with + # pkg-config or not. We need to know that as, if it was found with + # pkg-config, we should set the Requires.private value in libpcap.pc + # to include its package name, openssl, otherwise we should add the + # names for the static libraries to Libs.private. + # + # On UN*X, FindOpenSSL happens to use pkg-config to find OpenSSL, but + # it doesn't appear to be documented as doing so; therefore, we don't + # assume that, if we got here, we have pkg-config. + # + # So we use pkg_get_link_info() to run pkg-config ourselves, both + # because FindOpenSSL doesn't set the OPENSSL_LDFLAGS or + # OPENSSL_STATIC_LDFLAGS variables and because, for reasons explained + # in the comment before the pkg_get_link_info() macro, even if it did, + # it wouldn't be what we want anyway. + # + if (PKG_CONFIG_EXECUTABLE) + pkg_get_link_info(OPENSSL openssl) + if (OPENSSL_FOUND_WITH_PKG_CONFIG) + # + # pkg-config failed; assume that means that there is no openssl + # package for it to find. Just add OPENSSL_LIBRARIES to + # LIBS_PRIVATE AND LIBS_STATIC, as that's the + # best we can do. XXX - need list of -l and -L flags to add.... + # + set(LIBS "${LIBS} ${OPENSSL_LIBS}") + set(LIBS_STATIC "${LIBS_STATIC} ${OPENSSL_LIBS_STATIC}") + set(REQUIRES_PRIVATE "${REQUIRES_PRIVATE} ${OPENSSL_PACKAGE_NAME}") + endif() + else() + # Get it from OPENSSL_LIBRARIES + foreach(_lib IN LISTS OPENSSL_LIBRARIES) + # + # Get the directory in which the library resides. + # + get_filename_component(_lib_directory "${_lib}" DIRECTORY) + + # + # Is the library directory in CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES? + # (See comment above on why we use that.) + # + list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${_lib_directory}" _lib_index) + if(_lib_index EQUAL -1) + # + # No, so add a -L flag to get the linker to search in that + # directory. + # + set(LIBS "${LIBS} -L${_lib_directory}") + set(LIBS_STATIC "${LIBS_STATIC} -L${_lib_directory}") + set(LIBS_PRIVATE "${LIBS_PRIVATE} -L${_lib_directory}") + endif() + + # + # Get the file name of the library, without the extension. + # + get_filename_component(_lib_filename "${_lib}" NAME_WE) + + # + # Strip off the "lib" prefix to get the library name, and + # add a -l flag based on that. + # + string(REGEX REPLACE "^lib" "" _library_name "${_lib_filename}") + set(LIBS "${LIBS} -l${_library_name}") + set(LIBS_STATIC "${LIBS_STATIC} -l${_library_name}") + set(LIBS_PRIVATE "${LIBS_PRIVATE} -l${_library_name}") + endforeach() + endif() + set(HAVE_OPENSSL YES) +endif(OPENSSL_FOUND) + +# +# Additional linker flags. +# +set(LINKER_FLAGS "${SANITIZER_FLAGS}") +if(ENABLE_PROFILING) + if(MSVC) + set(LINKER_FLAGS " /PROFILE") + else() + set(LINKER_FLAGS " -pg") + endif() +endif() + ###################################### # Input files ###################################### @@ -826,6 +1431,8 @@ set(PROJECT_SOURCE_LIST_C nametoaddr.c optimize.c pcap-common.c + pcap-usb-linux-common.c + pcap-util.c pcap.c savefile.c sf-pcapng.c @@ -834,52 +1441,16 @@ set(PROJECT_SOURCE_LIST_C if(WIN32) # - # For now, we assume we don't have snprintf() or that it's not one - # that behaves enough like C99's snprintf() for our purposes (i.e., - # it doesn't null-terminate the string if it truncates it to fit in - # the buffer), so we have to provide our own (a wrapper around - # _snprintf() that null-terminates the buffer). + # We add the character set conversion routines; they're Windows-only + # for now. # - # We also assume we don't have asprintf(), and provide an implementation + # We assume we don't have asprintf(), and provide an implementation # that uses _vscprintf() to determine how big the string needs to be. # set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} - missing/win_snprintf.c missing/win_asprintf.c) + charconv.c missing/win_asprintf.c) else() - # - # Either: - # - # we have snprintf() and vsnprintf(), and have asprintf() and - # vasprintf(); - # - # we have snprintf() and vsnprintf(), but don't have asprintf() - # or vasprintf(); - # - # we have neither snprintf() nor vsnprintf(), and don't have - # asprintf() or vasprintf(), either. - # - # We assume that if we have asprintf() we have vasprintf(), as well - # as snprintf() and vsnprintf(), and that if we have snprintf() we - # have vsnprintf(). - # - # For the first case, we don't need any replacement routines. - # For the second case, we need replacement asprintf()/vasprintf() - # routines. - # For the third case, we need replacement snprintf()/vsnprintf() and - # asprintf()/vasprintf() routines. - # - if(NOT HAVE_SNPRINTF) - # - # We assume we have none of them; missing/snprintf.c supplies - # all of them. - # - set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/snprintf.c) - elif(NOT HAVE_ASPRINTF) - # - # We assume we have snprintf()/vsnprintf() but lack - # asprintf()/vasprintf(); missing/asprintf.c supplies - # the latter (using vsnprintf()). - # + if(NOT HAVE_ASPRINTF) set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/asprintf.c) endif() if(NOT HAVE_STRLCAT) @@ -985,6 +1556,7 @@ else() 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) + check_include_file(config/HaikuConfig.h HAVE_CONFIG_HAIKUCONFIG_H) if(BPF_H_DEFINES_BIOCSETIF) # @@ -1028,28 +1600,38 @@ else() # DLPI on pre-Solaris 11 SunOS 5, HP-UX, possibly others. # set(PCAP_TYPE dlpi) + elseif(HAVE_CONFIG_HAIKUCONFIG_H) + # + # Haiku. + # + set(PCAP_TYPE haiku) else() # # Nothing we support. # set(PCAP_TYPE null) + message(WARNING +"cannot determine packet capture interface +(see the INSTALL.md file for more info)") endif() endif() endif(WIN32) message(STATUS "Packet capture mechanism type: ${PCAP_TYPE}") +find_package(PkgConfig QUIET) + # # Do capture-mechanism-dependent tests. # if(WIN32) if(PCAP_TYPE STREQUAL "npf") # - # Link with packet.dll before WinSock2. + # Link with packet.dll before Winsock2. # - set(PCAP_LINK_LIBRARIES ${PACKET_LIBRARIES} ${PCAP_LINK_LIBRARIES}) + 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") + message(FATAL_ERROR "${PCAP_TYPE} is not a valid pcap type") endif() else(WIN32) if(PCAP_TYPE STREQUAL "dlpi") @@ -1085,6 +1667,9 @@ else(WIN32) # XXX - add -L/lib # set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} dlpi) + set(LIBS "${LIBS} -ldlpi") + set(LIBS_STATIC "${LIBS_STATIC} -ldlpi") + set(LIBS_PRIVATE "${LIBS_PRIVATE} -ldlpi") set(PCAP_TYPE libdlpi) endif() @@ -1109,70 +1694,45 @@ else(WIN32) # # Do we have libnl? + # We only want version 3. Version 2 was, apparently, + # short-lived, and version 1 is source and binary + # incompatible with version 3, and it appears that, + # these days, everybody's using version 3. We're + # not supporting older versions of the Linux kernel; + # let's drop support for older versions of libnl, too. # 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) + pkg_check_modules(LIBNL libnl-genl-3.0) + if(LIBNL_FOUND) + set(PCAP_LINK_LIBRARIES ${LIBNL_LIBRARIES} ${PCAP_LINK_LIBRARIES}) + # - # Yes, we have libnl 3.x. + # Get raw link flags from pkg-config. # - 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") + pkg_get_link_info(LIBNL libnl-genl-3.0) + set(LIBS "${LIBNL_LIBS} ${LIBS}") + set(LIBS_STATIC "${LIBNL_LIBS_STATIC} ${LIBS_STATIC}") + set(REQUIRES_PRIVATE "${LIBNL_PACKAGE_NAME} ${REQUIRES_PRIVATE}") else() - # - # Try libnl 2.x. - # cmake_push_check_state() - set(CMAKE_REQUIRED_LIBRARIES nl) + 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 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? + # Yes, we have libnl 3.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() + set(PCAP_LINK_LIBRARIES nl-genl-3 nl-3 ${PCAP_LINK_LIBRARIES}) + include_directories("/usr/include/libnl3") + set(LIBS "-lnl-genl-3 -lnl-3 ${LIBS}") + set(LIBS_STATIC "-lnl-genl-3 -lnl-3 ${LIBS_STATIC}") + set(LIBS_PRIVATE "-lnl-genl-3 -lnl-3 ${LIBS_PRIVATE}") endif() endif() + else() + unset(HAVE_LIBNL CACHE) # check_function_exists stores results in cache 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") # @@ -1196,13 +1756,23 @@ else(WIN32) check_type_size("struct BPF_TIMEVAL" STRUCT_BPF_TIMEVAL) endif() cmake_pop_check_state() + elseif(PCAP_TYPE STREQUAL "haiku") + # + # Check for some headers just in case. + # + check_include_files("net/if.h;net/if_dl.h;net/if_types.h" HAVE_NET_IF_TYPES_H) + set(PCAP_SRC pcap-${PCAP_TYPE}.cpp) elseif(PCAP_TYPE STREQUAL "null") else() message(FATAL_ERROR "${PCAP_TYPE} is not a valid pcap type") endif() endif(WIN32) -set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-${PCAP_TYPE}.c) +if(NOT DEFINED PCAP_SRC) +set(PCAP_SRC pcap-${PCAP_TYPE}.c) +endif() + +set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} ${PCAP_SRC}) # # Now figure out how we get a list of interfaces and addresses, @@ -1239,6 +1809,9 @@ if(NOT WIN32) check_library_exists(socket getifaddrs "" SOCKET_HAS_GETIFADDRS) if(SOCKET_HAS_GETIFADDRS) set(PCAP_LINK_LIBRARIES socket ${PCAP_LINK_LIBRARIES}) + set(LIBS "-lsocket ${LIBS}") + set(LIBS_STATIC "-lsocket ${LIBS_STATIC}") + set(LIBS_PRIVATE "-lsocket ${LIBS_PRIVATE}") set(HAVE_GETIFADDRS TRUE) endif() endif() @@ -1308,13 +1881,14 @@ 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) +# +# Various Linux-specific mechanisms. +# +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + # Check for usbmon USB sniffing support. + if(NOT DISABLE_LINUX_USBMON) + set(PCAP_SUPPORT_LINUX_USBMON 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 available? # If so, we might need it for . @@ -1342,10 +1916,9 @@ if(NOT DISABLE_USB) endif(HAVE_LINUX_COMPILER_H) endif() endif() -endif() -# Check for netfilter sniffing support. -if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + # + # Check for netfilter sniffing support. # # Life's too short to deal with trying to get this to compile # if you don't get the right types defined with @@ -1401,6 +1974,51 @@ main(void) endif(PCAP_SUPPORT_NETMAP) endif() +# Check for DPDK sniffing support +if(NOT DISABLE_DPDK) + find_package(dpdk) + if(dpdk_FOUND) + # + # We call rte_eth_dev_count_avail(), and older versions of DPDK + # didn't have it, so check for it. + # + cmake_push_check_state() + set(CMAKE_REQUIRED_INCLUDES ${dpdk_INCLUDE_DIRS}) + set(CMAKE_REQUIRED_LIBRARIES ${dpdk_LIBRARIES}) + check_function_exists(rte_eth_dev_count_avail HAVE_RTE_ETH_DEV_COUNT_AVAIL) + cmake_pop_check_state() + if(HAVE_RTE_ETH_DEV_COUNT_AVAIL) + set(DPDK_C_FLAGS "-march=native") + set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} ${DPDK_C_FLAGS}) + include_directories(AFTER ${dpdk_INCLUDE_DIRS}) + link_directories(AFTER ${dpdk_LIBRARIES}) + set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${dpdk_LIBRARIES}) + set(LIBS "${LIBS} ${dpdk_LIBS}") + set(LIBS_STATIC "${LIBS_STATIC} ${dpdk_LIBS_STATIC}") + set(REQUIRES_PRIVATE "${REQUIRES_PRIVATE} ${dpdk_PACKAGE_NAME}") + set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-dpdk.c) + set(PCAP_SUPPORT_DPDK TRUE) + + # + # Check whether the rte_ether.h file defines + # struct ether_addr or struct rte_ether_addr. + # + # ("API compatibility? That's for losers!") + # + cmake_push_check_state() + set(CMAKE_REQUIRED_INCLUDES ${dpdk_INCLUDE_DIRS}) + set(CMAKE_EXTRA_INCLUDE_FILES rte_ether.h) + check_type_size("struct rte_ether_addr" STRUCT_RTE_ETHER_ADDR) + cmake_pop_check_state() + endif() + else() + message(WARNING, +"We couldn't find DPDK with pkg-config. If you want DPDK support, +make sure that pkg-config is installed, that DPDK 18.02.2 or later is +installed, and that DPDK provides a .pc file.") + endif() +endif() + # Check for Bluetooth sniffing support if(NOT DISABLE_BLUETOOTH) if(CMAKE_SYSTEM_NAME STREQUAL "Linux") @@ -1439,9 +2057,11 @@ main(void) endif(HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL) endif(HAVE_BLUETOOTH_BLUETOOTH_H) endif() +else() + unset(PCAP_SUPPORT_BT_MONITOR CACHE) endif() -# Check for Bluetooth sniffing support +# Check for D-Bus sniffing support if(NOT DISABLE_DBUS) # # We don't support D-Bus sniffing on macOS; see @@ -1451,7 +2071,6 @@ if(NOT DISABLE_DBUS) 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) @@ -1479,22 +2098,80 @@ if(NOT DISABLE_DBUS) list(APPEND DBUS_LIBRARY_FULLPATHS ${_libfullpath}) endforeach() set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${DBUS_LIBRARY_FULLPATHS}) + + # + # Get library information for DPDK. + # + pkg_get_link_info(DBUS dbus-1) + set(LIBS "${LIBS} ${DBUS_LIBS}") + set(LIBS_STATIC "${LIBS_STATIC} ${DBUS_LIBS_STATIC}") + set(REQUIRES_PRIVATE "${REQUIRES_PRIVATE} ${DBUS_PACKAGE_NAME}") 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) + pkg_check_modules(LIBIBVERBS libibverbs) + if(LIBIBVERBS_FOUND) + # + # pkg-config found it; remember its pkg-config name. + # + set(LIBIBVERBS_REQUIRES_PRIVATE ${LIBIBVERBS_PACKAGE_NAME}) + + # + # Get static linking information for it. + # + pkg_get_link_info(LIBIBVERBS libibverbs) + else() + # + # pkg-config didn't find it; try to look for it ourselves + # + check_library_exists(ibverbs ibv_get_device_list "" LIBIBVERBS_HAS_IBV_GET_DEVICE_LIST) + if(LIBIBVERBS_HAS_IBV_GET_DEVICE_LIST) + set(LIBIBVERBS_FOUND TRUE) + set(LIBIBVERBS_LIBRARIES ibverbs) + # XXX - at least on Ubuntu 20.04, there are many more + # libraries needed; is there any platform where + # libibverbs is available but where pkg-config + # isn't available or libibverbs doesn't use it? + # If not, we should only use pkg-config for it. + set(LIBIBVERBS_STATIC_LIBRARIES ibverbs) + set(LIBIBVERBS_LIBS -libverbs) + set(LIBIBVERBS_LIBS_STATIC -libverbs) + set(LIBIBVERBS_LIBS_PRIVATE -libverbs) + endif() + endif() + if(LIBIBVERBS_FOUND) + # + # For unknown reasons, check_include_file() doesn't just attempt + # to compile a test program that includes the header in + # question, it also attempts to link it. + # + # For unknown reasons, at least some of the static inline + # functions defined in infiniband/verbs.h are not inlined by the + # Sun^WOracle Studio C compiler, so the compiler generates code + # for them as part of the object code resulting from compiling + # the test program. At lest some of those functions call + # routines in -libverbs, so, in order to keep the compile and + # link from failing, even though the header file exists and is + # usable, we need to link with -libverbs. + # + cmake_push_check_state() + set(CMAKE_REQUIRED_LIBRARIES ${LIBIBVERBS_LIBRARIES}) 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}) + set(PCAP_LINK_LIBRARIES ${LIBIBVERBS_LIBRARIES} ${PCAP_LINK_LIBRARIES}) + set(LIBS "${LIBIBVERBS_LIBS} ${LIBS}") + set(LIBS_STATIC "${LIBIBVERBS_LIBS_STATIC} ${LIBS_STATIC}") + set(LIBS_PRIVATE "${LIBIBVERBS_LIBS_PRIVATE} ${LIBS_PRIVATE}") + set(REQUIRES_PRIVATE "${REQUIRES_PRIVATE} ${LIBIBVERBS_PACKAGE_NAME}") endif(PCAP_SUPPORT_RDMASNIFF) endif(HAVE_INFINIBAND_VERBS_H) - endif(LIBIBVERBS_HAS_IBV_GET_DEVICE_LIST) + cmake_pop_check_state() + endif(LIBIBVERBS_FOUND) endif(NOT DISABLE_RDMA) # @@ -1532,12 +2209,18 @@ if(NOT DISABLE_DAG) 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}) + set(LIBS "${LIBS} ${DAG_LIBS}") + set(LIBS_STATIC "${LIBS_STATIC} ${DAG_LIBS_STATIC}") + set(LIBS_PRIVATE "${LIBS_PRIVATE} ${DAG_LIBS_PRIVATE}") 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}) + set(LIBS "${LIBS} ${CMAKE_THREAD_LIBS_INIT}") + set(LIBS_STATIC "${LIBS_STATIC} ${CMAKE_THREAD_LIBS_INIT}") + set(LIBS_PRIVATE "${LIBS_PRIVATE} ${CMAKE_THREAD_LIBS_INIT}") endif() endif() endif() @@ -1583,6 +2266,30 @@ if(NOT DISABLE_SNF) 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}) + set(LIBS "${LIBS_STATIC} ${SNF_LIBS}") + set(LIBS_STATIC "${LIBS_STATIC} ${SNF_LIBS_STATIC}") + set(LIBS_PRIVATE "${LIBS_PRIVATE} ${SNF_LIBS_PRIVATE}") + endif() +endif() + +# Check for Riverbed AirPcap support. +if(NOT DISABLE_AIRPCAP) + # + # Try to find the AirPcap header file and library. + # + find_package(AirPcap) + + # + # Did we succeed? + # + if(AirPcap_FOUND) + # + # Yes. + # + include_directories(AFTER ${AirPcap_INCLUDE_DIRS}) + set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-airpcap.c) + set(HAVE_AIRPCAP_API TRUE) + set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${AirPcap_LIBRARIES}) endif() endif() @@ -1603,7 +2310,7 @@ if(NOT DISABLE_TC) 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++") + set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${TC_LIBRARIES} ${CMAKE_USE_PTHREADS_INIT} stdc++) endif() endif() @@ -1629,7 +2336,7 @@ if(ENABLE_REMOTE) 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) + pcap-new.c pcap-rpcap.c rpcap-protocol.c sockutils.c sslutils.c) endif(ENABLE_REMOTE) ################################################################### @@ -1698,6 +2405,20 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.devel OR EXISTS ${CMAKE_BINARY_DIR}/.deve # structure members. # check_and_add_compiler_option(-wd4820) + # + # We do *not* care about every single place the compiler would + # have inserted Spectre mitigation if only we had told it to + # do so with /Qspectre. Maybe it's worth it, as that's in + # Bison-generated code that we don't control. + # + # XXX - add /Qspectre if that is really worth doing. + # + check_and_add_compiler_option(-wd5045) + + # + # Treat all (remaining) warnings as errors. + # + check_and_add_compiler_option(-WX) else() # # Other compilers, including MSVC with a Clang front end and @@ -1705,21 +2426,23 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.devel OR EXISTS ${CMAKE_BINARY_DIR}/.deve # 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(-Wdocumentation) check_and_add_compiler_option(-Wformat-nonliteral) + check_and_add_compiler_option(-Wmissing-noreturn) + check_and_add_compiler_option(-Wmissing-prototypes) + check_and_add_compiler_option(-Wmissing-variable-declarations) + check_and_add_compiler_option(-Wpointer-arith) + check_and_add_compiler_option(-Wpointer-sign) + check_and_add_compiler_option(-Wshadow) + check_and_add_compiler_option(-Wsign-compare) + check_and_add_compiler_option(-Wshorten-64-to-32) + check_and_add_compiler_option(-Wstrict-prototypes) check_and_add_compiler_option(-Wunreachable-code) + check_and_add_compiler_option(-Wunused-parameter) + check_and_add_compiler_option(-Wused-but-marked-unused) endif() endif() @@ -1771,6 +2494,19 @@ if(NOT MSVC) endif() endif(NOT MSVC) +# +# Extra compiler options for the build matrix scripts to request -Werror or +# its equivalent if required. The CMake variable name cannot be CFLAGS +# because that is already used for a different purpose in CMake. Example +# usage: cmake -DEXTRA_CFLAGS='-Wall -Wextra -Werror' ... +# +if(NOT "${EXTRA_CFLAGS}" STREQUAL "") + foreach(_extra_cflag ${EXTRA_CFLAGS}) + check_and_add_compiler_option("${_extra_cflag}") + endforeach(_extra_cflag) + message(STATUS "Added extra compile options (${EXTRA_CFLAGS})") +endif() + # # Flex/Lex and YACC/Berkeley YACC/Bison. # From a mail message to the CMake mailing list by Andy Cedilnik of @@ -1786,6 +2522,28 @@ if(LEX_EXECUTABLE STREQUAL "LEX_EXECUTABLE-NOTFOUND") endif() message(STATUS "Lexical analyzer generator: ${LEX_EXECUTABLE}") +# +# Make sure {f}lex supports the -P, --header-file, and --nounput flags +# and supports processing our scanner.l. +# +if(WIN32) + set(NULL_DEVICE "NUL:") +else() + set(NULL_DEVICE "/dev/null") +endif() +execute_process(COMMAND ${LEX_EXECUTABLE} -P pcap_ --header-file=${NULL_DEVICE} --nounput -t ${pcap_SOURCE_DIR}/scanner.l + OUTPUT_QUIET RESULT_VARIABLE EXIT_STATUS) +if(NOT EXIT_STATUS EQUAL 0) + message(FATAL_ERROR "${LEX_EXECUTABLE} is insufficient to compile libpcap. +libpcap requires Flex 2.5.31 or later, or a compatible version of lex. +If a suitable version of Lex/Flex is available as a non-standard command +and/or not in the PATH, you can specify it using the LEX environment +variable. That said, on some systems the error can mean that Flex/Lex is +actually acceptable, but m4 is not. Likewise, if a suitable version of +m4 (such as GNU M4) is available but has not been detected, you can +specify it using the M4 environment variable.") +endif() + add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/scanner.c ${CMAKE_CURRENT_BINARY_DIR}/scanner.h SOURCE ${pcap_SOURCE_DIR}/scanner.l @@ -1816,22 +2574,56 @@ find_program(YACC_EXECUTABLE NAMES bison win_bison byacc yacc) if(YACC_EXECUTABLE STREQUAL "YACC_EXECUTABLE-NOTFOUND") message(FATAL_ERROR "Neither bison nor win_bison nor byacc nor yacc was found.") endif() + +if(YACC_EXECUTABLE MATCHES "byacc" OR YACC_EXECUTABLE MATCHES "yacc") + # + # Make sure this is Berkeley YACC, not AT&T YACC; + # the latter doesn't support reentrant parsers. + # Run it with "-V"; that succeeds and reports the + # version number with Berkeley YACC, but will + # (probably) fail with various vendor flavors + # of AT&T YACC. + # + # Hopefully this also eliminates any versions + # of Berkeley YACC that don't support reentrant + # parsers, if there are any. + # + execute_process(COMMAND ${YACC_EXECUTABLE} -V OUTPUT_QUIET + RESULT_VARIABLE EXIT_STATUS) + if(NOT EXIT_STATUS EQUAL 0) + message(FATAL_ERROR "${YACC_EXECUTABLE} is insufficient to compile libpcap. +libpcap requires Bison, a newer version of Berkeley YACC with support +for reentrant parsers, or another YACC compatible with them.") + endif() + # + # Berkeley YACC doesn't support "%define api.pure", so use + # "%pure-parser". + # + set(REENTRANT_PARSER "%pure-parser") +else() + # + # Bison prior to 2.4(.1) doesn't support "%define api.pure", so use + # "%pure-parser". + # + execute_process(COMMAND ${YACC_EXECUTABLE} -V OUTPUT_VARIABLE bison_full_version) + string(REGEX MATCH "[1-9][0-9]*[.][0-9]+" bison_major_minor ${bison_full_version}) + if (bison_major_minor VERSION_LESS "2.4") + set(REENTRANT_PARSER "%pure-parser") + else() + set(REENTRANT_PARSER "%define api.pure") + endif() +endif() + message(STATUS "Parser generator: ${YACC_EXECUTABLE}") # # Create custom command for the scanner. -# Find out whether it's Bison or not by looking at the last component -# of the path (without a .exe extension, if this is Windows). # -get_filename_component(YACC_NAME ${YACC_EXECUTABLE} NAME_WE) -if("${YACC_NAME}" STREQUAL "bison" OR "${YACC_NAME}" STREQUAL "win_bison") - set(YACC_COMPATIBILITY_FLAG "-y") -endif() add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/grammar.c ${CMAKE_CURRENT_BINARY_DIR}/grammar.h - SOURCE ${pcap_SOURCE_DIR}/grammar.y - COMMAND ${YACC_EXECUTABLE} ${YACC_COMPATIBILITY_FLAG} -p pcap_ -o ${CMAKE_CURRENT_BINARY_DIR}/grammar.c -d ${pcap_SOURCE_DIR}/grammar.y - DEPENDS ${pcap_SOURCE_DIR}/grammar.y + SOURCE ${pcap_BINARY_DIR}/grammar.y + COMMAND ${YACC_EXECUTABLE} -p pcap_ -o ${CMAKE_CURRENT_BINARY_DIR}/grammar.c -d ${pcap_BINARY_DIR}/grammar.y + DEPENDS ${pcap_BINARY_DIR}/grammar.y ) # @@ -1868,6 +2660,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "AIX") # we use them to load the BPF module. # set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} odm cfg) + set(LIBS "${LIBS} -lodm -lcfg") + set(LIBS_STATIC "${LIBS_STATIC} -lodm -lcfg") + set(LIBS_PRIVATE "${LIBS_PRIVATE} -lodm -lcfg") endif() elseif(CMAKE_SYSTEM_NAME STREQUAL "HP-UX") if(CMAKE_SYSTEM_VERSION MATCHES "[A-Z.]*9\.[0-9]*") @@ -1906,7 +2701,7 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "IRIX" OR CMAKE_SYSTEM_NAME STREQUAL "IRIX64") set(MAN_MISC_INFO 5) elseif(CMAKE_SYSTEM_NAME STREQUAL "OSF1") # - # DEC OSF/1, a/k/a Digial UNIX, a/k/a Tru64 UNIX. + # DEC OSF/1, a/k/a Digital 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. @@ -1939,6 +2734,11 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION MATCHES "5[.] set(MAN_MISC_INFO 5) set(MAN_DEVICES 7D) endif() +elseif(CMAKE_SYSTEM_NAME STREQUAL "Haiku") + # + # Haiku needs _BSD_SOURCE for the _IO* macros because it doesn't use them. + # + add_definitions(-D_BSD_SOURCE) endif() source_group("Source Files" FILES ${PROJECT_SOURCE_LIST_C}) @@ -1969,7 +2769,7 @@ add_subdirectory(testprogs) # # See # -# http://public.kitware.com/pipermail/cmake/2013-August/055510.html +# https://public.kitware.com/pipermail/cmake/2013-August/055510.html # add_custom_target(SerializeTarget DEPENDS @@ -2000,6 +2800,10 @@ if(BUILD_SHARED_LIBS) # set_target_properties(${LIBRARY_NAME} PROPERTIES DEFINE_SYMBOL pcap_EXPORTS) + if(NOT "${LINKER_FLAGS}" STREQUAL "") + set_target_properties(${LIBRARY_NAME} PROPERTIES + LINK_FLAGS "${LINKER_FLAGS}") + endif() endif(BUILD_SHARED_LIBS) add_library(${LIBRARY_NAME}_static STATIC @@ -2142,21 +2946,25 @@ if(APPLE AND "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "") # captures.) # set(OSX_LIBRARY_ARCHITECTURES "x86_64;i386;ppc") - else() + elseif(SYSTEM_VERSION_MAJOR GREATER 10 AND SYSTEM_VERSION_MAJOR LESS 19) # - # Post-Snow Leopard. Build for x86-64 and 32-bit x86, - # with x86-64 first. (That's what Apple does) - # XXX - update if and when Apple drops support - # for 32-bit x86 code and if and when Apple adds - # ARM-based Macs. (You're on your own for iOS etc.) + # Post-Snow Leopard, pre-Catalina. Build for x86-64 + # and 32-bit x86, with x86-64 first. (That's what Apple does) # - # XXX - check whether we *can* build for i386 and, if not, - # suggest that the user install the /usr/include headers if - # they want to build fat. + # First, check whether we're building with OpenSSL. + # If so, don't bother trying to build fat. # - cmake_push_check_state() - set(CMAKE_REQUIRED_FLAGS "-arch i386") - check_c_source_compiles( + if(HAVE_OPENSSL) + set(X86_32_BIT_SUPPORTED NO) + set(OSX_LIBRARY_ARCHITECTURES "x86_64") + message(WARNING "We're assuming the OpenSSL libraries are 64-bit only, so we're not compiling for 32-bit x86") + else() + # + # Now, check whether we *can* build for i386. + # + cmake_push_check_state() + set(CMAKE_REQUIRED_FLAGS "-arch i386") + check_c_source_compiles( "int main(void) { @@ -2164,20 +2972,80 @@ main(void) } " X86_32_BIT_SUPPORTED) - cmake_pop_check_state() - if(X86_32_BIT_SUPPORTED) - set(OSX_LIBRARY_ARCHITECTURES "x86_64;i386") + cmake_pop_check_state() + if(X86_32_BIT_SUPPORTED) + set(OSX_LIBRARY_ARCHITECTURES "x86_64;i386") + else() + set(OSX_LIBRARY_ARCHITECTURES "x86_64") + # + # We can't build fat; suggest that the user install the + # /usr/include headers if they want to build fat. + # + if(SYSTEM_VERSION_MAJOR LESS 18) + # + # Pre-Mojave; the command-line tools should be sufficient to + # enable 32-bit x86 builds. + # + message(WARNING "Compiling for 32-bit x86 gives an error; try installing the command-line tools") + else() + message(WARNING "Compiling for 32-bit x86 gives an error; try installing the command-line tools and, after that, installing the /usr/include headers from the /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg package") + endif() + endif() + endif() + elseif(SYSTEM_VERSION_MAJOR EQUAL 19) + # + # Catalina. Build libraries and executables + # only for x86-64. (That's what Apple does; + # 32-bit x86 binaries are not supported on + # Catalina.) + # + set(OSX_LIBRARY_ARCHITECTURES "x86_64") + else() + # + # Post-Catalina. Build libraries and + # executables for x86-64 and ARM64. + # (That's what Apple does, except they + # build for arm64e, which may include + # some of the pointer-checking extensions.) + # + # If we're building with libssl, make sure + # we can build fat with it (i.e., that it + # was built fat); if we can't, don't set + # the target architectures, and just + # build for the host we're on. + # + # Otherwise, just add both of them. + # + if(HAVE_OPENSSL) + cmake_push_check_state() + set(CMAKE_REQUIRED_FLAGS "-arch x86_64 -arch arm64") + set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) + set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES}) + # + # We must test whether this compiles and links, so + # check_symbol_exists() isn't sufficient. + # + # SSL_library_init() may be a macro that's #defined + # to be the real function to call, so we have to + # include , and check_function_exists() + # isn't sufficient. + # + check_c_source_compiles( +"#include +int +main(void) +{ + SSL_library_init(); + return 0; +} +" + FAT_SSL_BUILDS_SUPPORTED) + cmake_pop_check_state() + if(FAT_SSL_BUILDS_SUPPORTED) + set(OSX_LIBRARY_ARCHITECTURES "x86_64;arm64") + endif() else() - set(OSX_LIBRARY_ARCHITECTURES "x86_64") - if(SYSTEM_VERSION_MAJOR LESS 18) - # - # Pre-Mojave; the command-line tools should be sufficient to - # enable 32-bit x86 builds. - # - message(WARNING "Compiling for 32-bit x86 gives an error; try installing the command-line tools") - else() - message(WARNING "Compiling for 32-bit x86 gives an error; try installing the command-line tools and, after that, installing the /usr/include headers from the /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg package") - endif() + set(OSX_LIBRARY_ARCHITECTURES "x86_64;arm64") endif() endif() if(BUILD_SHARED_LIBS) @@ -2194,6 +3062,12 @@ endif() configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmakeconfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) +###################################### +# Write out the grammar.y file +###################################### + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/grammar.y.in ${CMAKE_CURRENT_BINARY_DIR}/grammar.y @ONLY) + ###################################### # Install pcap library, include files, and man pages ###################################### @@ -2209,25 +3083,24 @@ 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) + # + # If we haven't found an ln executable with MinGW, we don't try + # generating and installing the man pages, so if we get here, + # we've found that executable. + set(LINK_COMMAND "\"${LINK_EXECUTABLE}\" \"-s\" \"${SOURCE}\" \"${TARGET}\"") 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}\") + "message(STATUS \"Symlinking: \$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${MANDIR}/${SOURCE} to ${TARGET}\") execute_process( COMMAND \"${CMAKE_COMMAND}\" \"-E\" \"remove\" \"${TARGET}\" - WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/${MANDIR} + WORKING_DIRECTORY \$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${MANDIR} ) execute_process( COMMAND ${LINK_COMMAND} - WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/${MANDIR} + WORKING_DIRECTORY \$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${MANDIR} RESULT_VARIABLE EXIT_STATUS ) if(NOT EXIT_STATUS EQUAL 0) @@ -2271,6 +3144,7 @@ set(MAN3PCAP_NOEXPAND pcap_get_required_select_timeout.3pcap pcap_get_selectable_fd.3pcap pcap_geterr.3pcap + pcap_init.3pcap pcap_inject.3pcap pcap_is_swapped.3pcap pcap_lib_version.3pcap @@ -2298,33 +3172,42 @@ set(MAN3PCAP_NOEXPAND pcap_tstamp_type_name_to_val.3pcap pcap_tstamp_type_val_to_name.3pcap ) -set(MANFILE_EXPAND pcap-savefile.manfile.in) +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(BUILD_SHARED_LIBS) + set(LIBRARIES_TO_INSTALL "${LIBRARY_NAME}" "${LIBRARY_NAME_STATIC}") +else(BUILD_SHARED_LIBS) + set(LIBRARIES_TO_INSTALL "${LIBRARY_NAME_STATIC}") +endif(BUILD_SHARED_LIBS) -if(WIN32) +if(WIN32 OR CYGWIN OR MSYS) + # + # XXX - according to the CMake documentation, WIN32 is set if + # the target is Windows; would there ever be a case where + # CYGWIN or MSYS are set but WIN32 *isn't* set? + # if(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8) # - # Install 64-bit code built with MSVC in the amd64 subdirectories, + # Install 64-bit code built with MSVC in the x64 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) + install(TARGETS ${LIBRARIES_TO_INSTALL} + RUNTIME DESTINATION bin/x64 + LIBRARY DESTINATION lib/x64 + ARCHIVE DESTINATION lib/x64) if(NOT MINGW) install(FILES $/${LIBRARY_NAME_STATIC}.pdb - DESTINATION bin/amd64 OPTIONAL) + DESTINATION bin/x64 OPTIONAL) if(BUILD_SHARED_LIBS) install(FILES $ - DESTINATION bin/amd64 OPTIONAL) + DESTINATION bin/x64 OPTIONAL) endif(BUILD_SHARED_LIBS) endif(NOT MINGW) else(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8) @@ -2333,22 +3216,22 @@ if(WIN32) # in the top-level directories, as those are where they # expect it to be. # - install(TARGETS ${LIBRARY_NAME} ${LIBRARY_NAME_STATIC} + install(TARGETS ${LIBRARIES_TO_INSTALL} RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) - if(NOT MINGW) + if(MSVC) install(FILES $/${LIBRARY_NAME_STATIC}.pdb DESTINATION bin OPTIONAL) if(BUILD_SHARED_LIBS) install(FILES $ DESTINATION bin OPTIONAL) endif(BUILD_SHARED_LIBS) - endif(NOT MINGW) + endif(MSVC) endif(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8) -else(WIN32) - install(TARGETS ${LIBRARY_NAME} ${LIBRARY_NAME_STATIC} DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}) -endif(WIN32) +else(WIN32 OR CYGWIN OR MSYS) + install(TARGETS ${LIBRARIES_TO_INSTALL} DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}) +endif(WIN32 OR CYGWIN OR MSYS) install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/pcap/ DESTINATION include/pcap) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pcap.h DESTINATION include) @@ -2358,41 +3241,73 @@ 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 "") + set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}") + + # + # If this is a platform where we need to have the .pc file and + # pcap-config script supply an rpath option to specify the directory + # in which the libpcap shared library is installed, and the install + # prefix /usr (meaning we're not installing a system library), + # provide the rpath option. + # + # (We must check CMAKE_INSTALL_PREFIX, as the library directory + # isn't necessarily /usr/lib in this case - for example, Linux + # distributions for 64-bit platforms that also provide support for + # binaries for a 32-bit version of the platform may put the 64-bit + # libraries, the 32-bit libraries, or both in directories other than + # /usr/lib.) + # + # In AIX, do we have to do this? + # + # In Darwin-based OSes, the full paths of the shared libraries with + # which the program was linked are stored in the executable, so we + # don't need to provide an rpath option. + # + # With the HP-UX linker, directories specified with -L are, by + # default, added to the run-time search path, so we don't need to + # supply them. + # + # For Tru64 UNIX, "-rpath" works with DEC's^WCompaq's^WHP's C + # compiler for Alpha, but isn't documented as working with GCC, and + # no GCC-compatible option is documented as working with the DEC + # compiler. If anybody needs this on Tru64/Alpha, they're welcome + # to figure out a way to make it work. + # + # This must *not* depend on the compiler, as, on platforms where + # there's a GCC-compatible compiler and a vendor compiler, we need + # to work with both. + # + if(NOT CMAKE_INSTALL_PREFIX STREQUAL "/usr") + 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") + # + # Platforms where the "native" C compiler is GCC or accepts + # compatible command-line arguments, and the "native" linker + # is the GNU linker or accepts compatible command-line + # arguments. + # + set(RPATH "-Wl,-rpath,\${libdir}") + elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION MATCHES "5[.][0-9.]*") + # + # SunOS 5.x. + # + # Sun/Oracle's linker, the GNU linker, and GNU-compatible + # linkers all support -R. + # + set(RPATH "-Wl,-R,\${libdir}") + else() + # + # No option needed to set the RPATH. + # + set(RPATH "") + endif() endif() - set(LIBS "") - foreach(LIB ${PCAP_LINK_LIBRARIES}) - set(LIBS "${LIBS} -l${LIB}") - endforeach(LIB) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pcap-config.in ${CMAKE_CURRENT_BINARY_DIR}/pcap-config @ONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpcap.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libpcap.pc @ONLY) install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/pcap-config DESTINATION bin) @@ -2404,54 +3319,64 @@ if(NOT MSVC) # 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_CURRENT_SOURCE_DIR}/${MANPAGE}) - endforeach(MANPAGE) - install(FILES ${MAN1} DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) - - set(MAN3PCAP "") - foreach(MANPAGE ${MAN3PCAP_NOEXPAND}) - set(MAN3PCAP ${MAN3PCAP} ${CMAKE_CURRENT_SOURCE_DIR}/${MANPAGE}) - endforeach(MANPAGE) - foreach(TEMPLATE_MANPAGE ${MAN3PCAP_EXPAND}) - string(REPLACE ".in" "" MANPAGE ${TEMPLATE_MANPAGE}) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY) - set(MAN3PCAP ${MAN3PCAP} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE}) - endforeach(TEMPLATE_MANPAGE) - install(FILES ${MAN3PCAP} DESTINATION ${CMAKE_INSTALL_MANDIR}/man3) - 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_CURRENT_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY) - set(MANFILE ${MANFILE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE}) - endforeach(TEMPLATE_MANPAGE) - install(FILES ${MANFILE} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_FILE_FORMATS}) - - set(MANMISC "") - foreach(TEMPLATE_MANPAGE ${MANMISC_EXPAND}) - string(REPLACE ".manmisc.in" ".${MAN_MISC_INFO}" MANPAGE ${TEMPLATE_MANPAGE}) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY) - set(MANMISC ${MANMISC} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE}) - endforeach(TEMPLATE_MANPAGE) - install(FILES ${MANMISC} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_MISC_INFO}) + # If this is MinGW, maybe we have a UN*X-style ln command and + # maybe we don't. (No, we do *NOT* require MSYS!) If we don't + # have it, don't do the man pages. + # + if(MINGW) + find_program(LINK_EXECUTABLE ln) + endif(MINGW) + if(UNIX OR (MINGW AND LINK_EXECUTABLE)) + set(MAN1 "") + foreach(MANPAGE ${MAN1_NOEXPAND}) + set(MAN1 ${MAN1} ${CMAKE_CURRENT_SOURCE_DIR}/${MANPAGE}) + endforeach(MANPAGE) + install(FILES ${MAN1} DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) + + set(MAN3PCAP "") + foreach(MANPAGE ${MAN3PCAP_NOEXPAND}) + set(MAN3PCAP ${MAN3PCAP} ${CMAKE_CURRENT_SOURCE_DIR}/${MANPAGE}) + endforeach(MANPAGE) + foreach(TEMPLATE_MANPAGE ${MAN3PCAP_EXPAND}) + string(REPLACE ".in" "" MANPAGE ${TEMPLATE_MANPAGE}) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY) + set(MAN3PCAP ${MAN3PCAP} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE}) + endforeach(TEMPLATE_MANPAGE) + install(FILES ${MAN3PCAP} DESTINATION ${CMAKE_INSTALL_MANDIR}/man3) + install_manpage_symlink(pcap_datalink_val_to_name.3pcap pcap_datalink_val_to_description.3pcap ${CMAKE_INSTALL_MANDIR}/man3) + install_manpage_symlink(pcap_datalink_val_to_name.3pcap pcap_datalink_val_to_description_or_dlt.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_CURRENT_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY) + set(MANFILE ${MANFILE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE}) + endforeach(TEMPLATE_MANPAGE) + install(FILES ${MANFILE} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_FILE_FORMATS}) + + set(MANMISC "") + foreach(TEMPLATE_MANPAGE ${MANMISC_EXPAND}) + string(REPLACE ".manmisc.in" ".${MAN_MISC_INFO}" MANPAGE ${TEMPLATE_MANPAGE}) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY) + set(MANMISC ${MANMISC} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE}) + endforeach(TEMPLATE_MANPAGE) + install(FILES ${MANMISC} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_MISC_INFO}) + endif(UNIX OR (MINGW AND LINK_EXECUTABLE)) endif(NOT MSVC) # uninstall target diff --git a/external/bsd/libpcap/dist/CONTRIBUTING.md b/external/bsd/libpcap/dist/CONTRIBUTING.md index 69b597260f79..fb22c5e38159 100644 --- a/external/bsd/libpcap/dist/CONTRIBUTING.md +++ b/external/bsd/libpcap/dist/CONTRIBUTING.md @@ -14,10 +14,10 @@ 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) +* 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 + (`uname -a`, compiler name and version, CPU type etc.) +* `configure` or `cmake` flags if any were used * statement of the problem * steps to reproduce diff --git a/external/bsd/libpcap/dist/CREDITS b/external/bsd/libpcap/dist/CREDITS index f7abc1f3222e..4b820ee7b9ac 100644 --- a/external/bsd/libpcap/dist/CREDITS +++ b/external/bsd/libpcap/dist/CREDITS @@ -3,29 +3,43 @@ This file lists people who have contributed to libpcap. The current maintainers (in alphabetical order): Denis Ovsienko Francois-Xavier Le Bail - Guy Harris + Guy Harris Michael Richardson Additional people who have contributed patches (in alphabetical order): + Adrian Budau Akos Vandra Alan Bawden Albert Chin + Alexander Galanin Alexander 'Leo' Bergolth Alexey Kuznetsov + Alex Smith <44322503+MadAlexUK at users dot noreply dot github dot com> + Alfredo Alvarez Fernandez Ali Abdulkadir Alon Bar-Lev + Anders Broman Andres Perera Andrew Brown Ani Sinha + Anthony Kirby Antti Kantee Arien Vijn Arkadiusz Miskiewicz Armando L. Caro Jr. Assar Westerlund + Atzm Watanabe + Baptiste Peugnez + Baruch Siach Bill Parker + Biswapriyo Nath + blazeable + bleader Brent Cook Brian Ginsbach + B. Scott Michel + Cedric Cellier Charles M. Hannum Chris G. Demetriou Chris Lightfoot @@ -34,24 +48,38 @@ Additional people who have contributed patches (in alphabetical order): Christian Bell Christian Peron Christian Svensson + Christopher K Lee + Daniel Borkmann Daniele Orlandi + Daniel Lublin + Daniel Miller + Dario Lombardo Darren Lim Darren Reed + Dave Barach David Clark David Kaelbling + David Karoly David Ward David Young Dean Gaudet dhruv + Dmytro Ovdiienko Don Ebright Dug Song Dustin Spicuzza dzejarczech Edward Sheldrake + Eli Schwartz Eric Anderson Erik de Castro Lopo + Fedor Sakharov + Felix Janda Felix Obenhuber + fghzxm Florent Drouin + Florian Fainelli + François Revol Franz Schaefer frederich Fulko Hew @@ -59,6 +87,7 @@ Additional people who have contributed patches (in alphabetical order): Gabor Tatarka Garrett Cooper George Neville-Neil + Gerald Combs Gerard Garcia Gianluca Varenni Gilbert Hoyek @@ -71,83 +100,115 @@ Additional people who have contributed patches (in alphabetical order): Gustavo Zacarias Hagen Paul Pfeifer Henri Doreau + Hiroaki KAWAI Hyung Sik Yoon Igor Khristophorov + Jakub Sitnicki Jakub Zawadzki + James Ko Jan-Philip Velders Jason R. Thorpe Javier Achirica Jean-Louis Charton Jean Tourrilhes Jefferson Ogata + Jerome Duval Jesper Dangaard Brouer Jesper Peterson Jesse Gross + JHA + jingyu yang Jiri Slaby + João Valverde Joerg Mayer John Bankier Jon Lindgren Jon Smirl Jorge Boncompte [DTI2] + jromanr Juergen Schoenwaelder Julien Moutinho Jung-uk Kim Kazushi Sugyo + Kevin Boulain Klaus Klein Koryn Grant Kris Katterjohn Krzysztof Halasa Lennert Buytenhek + Li kunyu + lixiaoyan Lorenzo Cavallaro Loris Degioanni Love Hörnquist-Åstrand Luis MartinGarcia + lxy <391861737 at qq dot com> Maciej W. Rozycki Mansour Behabadi Marcus Felipe Pereira + Mario J. Rugiero Mark C. Brown Mark Johnston + Mark Marshall Mark Pizzolato Markus Mayer Martin Husemann Márton Németh + Matt Eaton Matthew Luckie + Matthias Hannig + Matwey V. Kornilov + maxice8 Max Laier Michal Kubecek Michal Labedzki + Michal Ruprich Michal Sekletar Mike Frysinger Mike Kershaw Mike Wiacek + Milosz Kaniewski Miroslav Lichvar Monroe Williams + Myricom Help + Nan Xiao + nic-kaczinsky <68271784+nic-kaczinsky at users dot noreply dot github dot com> + Nick Kelsey Nicolas Dade Niko Delarich N. Leiten + nnposter Octavian Cerna Olaf Kirch Ollie Wild + Ondřej Hošek Onno van der Linden + Orgad Shaneh + Ørjan Malde Paolo Abeni Patrick Marie - Patrick McHardy + Patrick McHardy Paul Mundt Pavel Kankovsky + Pawel Brzezinski Pawel Pokrywka Peter Fales Peter Jeremy Peter Volkov + Petr Vorel + Philippe Antoine Phil Wood Rafal Maszkowski + ramin Richard Stearn Rick Jones Robert Edmonds Roberto Mariani - Rongxi Li Roland Dreier Romain Francoise + Rongxi Li Sagun Shakya Scott Barron Scott Gifford @@ -155,23 +216,39 @@ Additional people who have contributed patches (in alphabetical order): Sebastian Krahmer Sebastien Roy Sepherosa Ziehau + Shane Kerr Shaun Clowes + solofox Solomon Peachy Stefan Hudson Stephen Donnelly + Steve Karg + stubbfel Takashi Yamamoto Tanaka Shin-ya + Thomas Habets + Thomas Petazzoni Tobias Poschwatta + Tomasz Moń + Tommy Beadle Tony Li Torsten Landschoff + Tymoteusz Blazejczyk Uns Lider Uwe Girlich + Vitaly Lavrov + Vivien Didelot + Vladimir Gladkov + Vladimir Marek + Walter Schell Wesley Shields Xianjie Zhang Xin Li Xue Jiang Qing + Yang Luo Yen Yen Lim Yoann Vandoorselaere + Yogesh Prasad Yvan Vanhullebus The original LBL crew: diff --git a/external/bsd/libpcap/dist/INSTALL.md b/external/bsd/libpcap/dist/INSTALL.md index 3a303fe0a6ce..d0a19d811a8b 100644 --- a/external/bsd/libpcap/dist/INSTALL.md +++ b/external/bsd/libpcap/dist/INSTALL.md @@ -1,105 +1,120 @@ -To build libpcap, run "./configure" (a shell script). The configure -script will determine your system attributes and generate an -appropriate Makefile from Makefile.in. Next run "make". If everything -goes well you can su to root and run "make install". However, you need -not install libpcap if you just want to build tcpdump; just make sure -the tcpdump and libpcap directory trees have the same parent -directory. +# libpcap installation notes +Libpcap can be built either with the configure script and `make`, or +with CMake and any build system supported by CMake. + +To build libpcap with the configure script and `make`: + +* Run `./configure` (a shell script). The configure script will +determine your system attributes and generate an appropriate `Makefile` +from `Makefile.in`. The configure script has a number of options to +control the configuration of libpcap; `./configure --help`` will show +them. + +* Next, run `make`. If everything goes well, you can +`su` to root and run `make install`. However, you need not install +libpcap if you just want to build tcpdump; just make sure the tcpdump +and libpcap directory trees have the same parent directory. + +To build libpcap with CMake and the build system of your choice, from +the command line: + +* Create a build directory into which CMake will put the build files it +generates; CMake does not work as well with builds done in the source +code directory as does the configure script. The build directory may be +created as a subdirectory of the source directory or as a directory +outside the source directory. + +* Change to the build directory and run CMake with the path from the +build directory to the source directory as an argument. The `-G` flag +can be used to select the CMake "generator" appropriate for the build +system you're using; various `-D` flags can be used to control the +configuration of libpcap. + +* Run the build tool. If everything goes well, you can `su` to root and +run the build tool with the `install` target. Building tcpdump from a +libpcap in a build directory is not supported. + +An `uninstall` target is supported with both `./configure` and CMake. + +***DO NOT*** run the build as root; there is no need to do so, running +anything as root that doesn't need to be run as root increases the risk +of damaging your system, and running the build as root will put files in +the build directory that are owned by root and that probably cannot be +overwritten, removed, or replaced except by root, which could cause +permission errors in subsequent builds. If configure says: configure: warning: cannot determine packet capture interface - configure: warning: (see INSTALL for more info) + configure: warning: (see INSTALL.md file for more info) + +or CMake says: + + cannot determine packet capture interface + + (see the INSTALL.md file for more info) then your system either does not support packet capture or your system does support packet capture but libpcap does not support that particular type. (If you have HP-UX, see below.) If your system uses a packet capture not supported by libpcap, please send us patches; don't forget to include an autoconf fragment suitable for use in -configure.ac. - -It is possible to override the default packet capture type, although -the circumstance where this works are limited. For example if you have -installed bpf under SunOS 4 and wish to build a snit libpcap: - - ./configure --with-pcap=snit +`configure.ac`. -Another example is to force a supported packet capture type in the case -where the configure scripts fails to detect it. +It is possible to override the default packet capture type with the +`--with-pcap`` option to `./configure` or the `-DPCAP_TYPE` option to +CMake, although the circumstances where this works are limited. One +possible reason to do that would be to force a supported packet capture +type in the case where the configure or CMake scripts fails to detect +it. -You will need an ANSI C compiler to build libpcap. The configure script -will abort if your compiler is not ANSI compliant. If this happens, use -the generally available GNU C compiler (GCC). +You will need a C99 compiler to build libpcap. The configure script +will abort if your compiler is not C99 compliant. If this happens, use +the generally available GNU C compiler (GCC) or Clang. You will need either Flex 2.5.31 or later, or a version of Lex compatible with it (if any exist), to build libpcap. The configure -script will abort if there isn't any such program. If you have an older -version of Flex, or don't have a compatible version of Lex, the current -version of flex is available at flex.sourceforge.net. +script will abort if there isn't any such program; CMake fails if Flex +or Lex cannot be found, but doesn't ensure that it's compatible with +Flex 2.5.31 or later. If you have an older version of Flex, or don't +have a compatible version of Lex, the current version of Flex is +available [here](https://github.com/westes/flex). You will need either Bison, Berkeley YACC, or a version of YACC compatible with them (if any exist), to build libpcap. The configure -script will abort if there isn't any such program. If you don't have -any such program, the current version of Bison can be found at -http://ftp.gnu.org/gnu/bison/ and the current version of Berkeley YACC -can be found at http://invisible-island.net/byacc/. +script will abort if there isn't any such program; CMake fails if Bison +or some form of YACC cannot be found, but doesn't ensure that it's +compatible with Bison or Berkeley YACC. If you don't have any such +program, the current version of Bison can be found +[here](https://ftp.gnu.org/gnu/bison/) and the current version of +Berkeley YACC can be found [here](https://invisible-island.net/byacc/). Sometimes the stock C compiler does not interact well with Flex and -Bison. The list of problems includes undefined references for alloca. +Bison. The list of problems includes undefined references for alloca(3). You can get around this by installing GCC. -If you use Solaris, there is a bug with bufmod(7) that is fixed in -Solaris 2.3.2 (aka SunOS 5.3.2). Setting a snapshot length with the -broken bufmod(7) results in data be truncated from the FRONT of the -packet instead of the end. The work around is to not set a snapshot -length but this results in performance problems since the entire packet -is copied to user space. If you must run an older version of Solaris, -there is a patch available from Sun; ask for bugid 1149065. After -installing the patch, use "setenv BUFMOD_FIXED" to enable use of -bufmod(7). However, we recommend you run a more current release of -Solaris. +## Linux specifics +On Linux, libpcap will not work if the kernel does not have the packet +socket option enabled; see [this file](doc/README.linux) for more +information. +## Solaris specifics If you use the SPARCompiler, you must be careful to not use the -/usr/ucb/cc interface. If you do, you will get bogus warnings and -perhaps errors. Either make sure your path has /opt/SUNWspro/bin -before /usr/ucb or else: +`/usr/ucb/cc` interface. If you do, you will get bogus warnings and +perhaps errors. Either make sure your path has `/opt/SUNWspro/bin` +before `/usr/ucb` or else: setenv CC /opt/SUNWspro/bin/cc -before running configure. (You might have to do a "make distclean" -if you already ran configure once). - -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 -libpcap can do. - -If you get an error like: - - tcpdump: recv_ack: bind error 0x??? - -when using DLPI, look for the DL_ERROR_ACK error return values, usually -in /usr/include/sys/dlpi.h, and find the corresponding value. +before running configure. (You might have to do a `make distclean` +if you already ran `configure` once). -Under {DEC OSF/1, Digital UNIX, Tru64 UNIX}, packet capture must be -enabled before it can be used. For instructions on how to enable packet -filter support, see: - - ftp://ftp.digital.com/pub/Digital/dec-faq/Digital-UNIX - -Look for the "How do I configure the Berkeley Packet Filter and capture -tcpdump traces?" item. - -Once you enable packet filter support, your OSF system will support bpf -natively. - -Under Ultrix, packet capture must be enabled before it can be used. For -instructions on how to enable packet filter support, see: - - ftp://ftp.digital.com/pub/Digital/dec-faq/ultrix +See [this file](doc/README.solaris.md) for more up to date +Solaris-related information. +## HP-UX specifics If you use HP-UX, you must have at least version 9 and either the -version of cc that supports ANSI C (cc -Aa) or else use the GNU C +version of `cc` that supports C99 (`cc -AC99`) or else use the GNU C compiler. You must also buy the optional streams package. If you don't have: @@ -113,10 +128,10 @@ need to install the "9.X LAN and DLPI drivers cumulative" patch The DLPI streams package is standard starting with HP-UX 10. The HP implementation of DLPI is a little bit eccentric. Unlike -Solaris, you must attach /dev/dlpi instead of the specific /dev/* +Solaris, you must attach `/dev/dlpi` instead of the specific `/dev/*` network pseudo device entry in order to capture packets. The PPA is based on the ifnet "index" number. Under HP-UX 9, it is necessary to -read /dev/kmem and the kernel symbol file (/hp-ux). Under HP-UX 10, +read `/dev/kmem` and the kernel symbol file (`/hp-ux`). Under HP-UX 10, DLPI can provide information for determining the PPA. It does not seem to be possible to trace the loopback interface. Unlike other DLPI implementations, PHYS implies MULTI and SAP and you get an error if you @@ -137,216 +152,126 @@ doing echo 'lanc_outbound_promisc_flag/W 1' | adb -w /stand/vmunix /dev/mem -You would have to arrange that this happen on reboots; the right way to +You would have to arrange that this happens on reboots; the right way to do that would probably be to put it into an executable script file -"/sbin/init.d/outbound_promisc" and making -"/sbin/rc2.d/S350outbound_promisc" a symbolic link to that script. +`/sbin/init.d/outbound_promisc` and making +`/sbin/rc2.d/S350outbound_promisc` a symbolic link to that script. Finally, testing shows that there can't be more than one simultaneous DLPI user per network interface. -If you use Linux, this version of libpcap is known to compile and run -under Red Hat 4.0 with the 2.0.25 kernel. It may work with earlier 2.X -versions but is guaranteed not to work with 1.X kernels. Running more -than one libpcap program at a time, on a system with a 2.0.X kernel, can -cause problems since promiscuous mode is implemented by twiddling the -interface flags from the libpcap application; the packet capture -mechanism in the 2.2 and later kernels doesn't have this problem. Also, -packet timestamps aren't very good. This appears to be due to haphazard -handling of the timestamp in the kernel. - -Note well: there is rumoured to be a version of tcpdump floating around -called 3.0.3 that includes libpcap and is supposed to support Linux. -You should be advised that neither the Network Research Group at LBNL -nor the Tcpdump Group ever generated a release with this version number. -The LBNL Network Research Group notes with interest that a standard -cracker trick to get people to install trojans is to distribute bogus -packages that have a version number higher than the current release. -They also noted with annoyance that 90% of the Linux related bug reports -they got are due to changes made to unofficial versions of their page. -If you are having trouble but aren't using a version that came from -tcpdump.org, please try that before submitting a bug report! +See [this file](doc/README.hpux) for more information specific to HP-UX. -On Linux, libpcap will not work if the kernel does not have the packet -socket option enabled; see the README.linux file for information about -this. +## AIX specifics +See [this file](doc/README.aix) for information on installing libpcap and +configuring your system to be able to support libpcap. + +## other specifics +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 +libpcap can do. -If you use AIX, you may not be able to build libpcap from this release. -We do not have an AIX system in house so it's impossible for us to test -AIX patches submitted to us. We are told that you must link against -/lib/pse.exp, that you must use AIX cc or a GNU C compiler newer than -2.7.2, and that you may need to run strload before running a libpcap -application. +If you get an error like: -Read the README.aix file for information on installing libpcap and -configuring your system to be able to support libpcap. + tcpdump: recv_ack: bind error 0x??? -If you use NeXTSTEP, you will not be able to build libpcap from this -release. - -If you use SINIX, you should be able to build libpcap from this -release. It is known to compile and run on SINIX-Y/N 5.42 with the C-DS -V1.0 or V1.1 compiler. But note that in some releases of SINIX, yacc -emits incorrect code; if grammar.y fails to compile, change every -occurence of: - - #ifdef YYDEBUG - -to: - #if YYDEBUG - -Another workaround is to use flex and bison. - -If you use SCO, you might have trouble building libpcap from this -release. We do not have a machine running SCO and have not had reports -of anyone successfully building on it; the current release of libpcap -does not compile on SCO OpenServer 5. Although SCO apparently supports -DLPI to some extent, the DLPI in OpenServer 5 is very non-standard, and -it appears that completely new code would need to be written to capture -network traffic. SCO do not appear to provide tcpdump binaries for -OpenServer 5 or OpenServer 6 as part of SCO Skunkware: - - http://www.sco.com/skunkware/ - -If you use UnixWare, you might be able to build libpcap from this -release, or you might not. We do not have a machine running UnixWare, -so we have not tested it; however, SCO provide packages for libpcap -0.6.2 and tcpdump 3.7.1 in the UnixWare 7/Open UNIX 8 part of SCO -Skunkware, and the source package for libpcap 0.6.2 is not changed from -the libpcap 0.6.2 source release, so this release of libpcap might also -build without changes on UnixWare 7. - -If linking tcpdump fails with "Undefined: _alloca" when using bison on -a Sun4, your version of Bison is broken. In any case version 1.16 or -higher is recommended (1.14 is known to cause problems 1.16 is known to -work). Either pick up a current version from: - - http://ftp.gnu.org/gnu/bison/ - -or hack around it by inserting the lines: - - #ifdef __GNUC__ - #define alloca __builtin_alloca - #else - #ifdef sparc - #include - #else - char *alloca (); - #endif - #endif - -right after the (100 line!) GNU license comment in bison.simple, remove -grammar.[co] and fire up make again. - -If you use SunOS 4, your kernel must support streams NIT. If you run a -libpcap program and it dies with: - - /dev/nit: No such device - -You must add streams NIT support to your kernel configuration, run -config and boot the new kernel. - -FILES ------ -CHANGES - description of differences between releases -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.md - this file -LICENSE - the license under which tcpdump is distributed -Makefile.in - compilation rules (input to the configure script) -README.md - description of distribution -doc/README.aix - notes on using libpcap on AIX -doc/README.dag - notes on using libpcap to capture on Endace DAG devices -doc/README.hpux - notes on using libpcap on HP-UX -doc/README.linux.md - notes on using libpcap on Linux -doc/README.macos - notes on using libpcap on macOS -doc/README.septel - notes on using libpcap to capture on Intel/Septel devices -doc/README.sita - notes on using libpcap to capture on SITA devices -doc/README.tru64 - notes on using libpcap on Digital/Tru64 UNIX -doc/README.Win32 - notes on using libpcap on Win32 systems (with Npcap) -VERSION - version of this release -acconfig.h - support for post-2.13 autoconf -aclocal.m4 - autoconf macros -arcnet.h - ARCNET definitions -atmuni31.h - ATM Q.2931 definitions -bpf_dump.c - BPF program printing routines -bpf_filter.c - BPF filtering routines -bpf_image.c - BPF disassembly routine -config.guess - autoconf support -config.h.in - autoconf input -config.sub - autoconf support -configure - configure script (run this first) -configure.ac - configure script source -dlpisubs.c - DLPI-related functions for pcap-dlpi.c and pcap-libdlpi.c -dlpisubs.h - DLPI-related function declarations -etherent.c - /etc/ethers support routines -ethertype.h - Ethernet protocol types and names definitions -fad-getad.c - pcap_findalldevs() for systems with getifaddrs() -fad-gifc.c - pcap_findalldevs() for systems with only SIOCGIFLIST -fad-glifc.c - pcap_findalldevs() for systems with SIOCGLIFCONF -filtertest.c - test program for BPF compiler -findalldevstest.c - test program for pcap_findalldevs() -gencode.c - BPF code generation routines -gencode.h - BPF code generation definitions -grammar.y - filter string grammar -ieee80211.h - 802.11 definitions -install-sh - BSD style install script -lbl/os-*.h - OS-dependent defines and prototypes -llc.h - 802.2 LLC SAP definitions -missing/* - replacements for missing library functions -mkdep - construct Makefile dependency list -msdos/* - drivers for MS-DOS capture support -nametoaddr.c - hostname to address routines -nlpid.h - OSI network layer protocol identifier definitions -net - symlink to bpf/net -optimize.c - BPF optimization routines -pcap/bluetooth.h - public definition of DLT_BLUETOOTH_HCI_H4_WITH_PHDR header -pcap/bpf.h - BPF definitions -pcap/namedb.h - public libpcap name database definitions -pcap/pcap.h - public libpcap definitions -pcap/sll.h - public definition of DLT_LINUX_SLL header -pcap/usb.h - public definition of DLT_USB header -pcap-bpf.c - BSD Packet Filter support -pcap-bpf.h - header for backwards compatibility -pcap-bt-linux.c - Bluetooth capture support for Linux -pcap-bt-linux.h - Bluetooth capture support for Linux -pcap-dag.c - Endace DAG device capture support -pcap-dag.h - Endace DAG device capture support -pcap-dlpi.c - Data Link Provider Interface support -pcap-dos.c - MS-DOS capture support -pcap-dos.h - headers for MS-DOS capture support -pcap-enet.c - enet support -pcap-int.h - internal libpcap definitions -pcap-libdlpi.c - Data Link Provider Interface support for systems with libdlpi -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 -pcap-septel.c - Intel/Septel device capture support -pcap-septel.h - Intel/Septel device capture support -pcap-sita.c - SITA device capture support -pcap-sita.h - SITA device capture support -pcap-sita.html - SITA device capture documentation -pcap-stdinc.h - includes and #defines for compiling on Win32 systems -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.3pcap - manual entry for the library -pcap.c - pcap utility routines -pcap.h - header for backwards compatibility -pcap_*.3pcap - manual entries for library functions -pcap-filter.4 - manual entry for filter syntax -pcap-linktype.4 - manual entry for link-layer header types -ppp.h - Point to Point Protocol definitions -savefile.c - offline support -scanner.l - filter string scanner -sunatmpos.h - definitions for SunATM capturing -Win32 - headers and routines for building on Win32 systems +when using DLPI, look for the DL_ERROR_ACK error return values, usually +in `/usr/include/sys/dlpi.h`, and find the corresponding value. + +## Description of files + CHANGES - description of differences between releases + ChmodBPF/* - macOS startup item to set ownership and permissions on /dev/bpf* + CMakeLists.txt - CMake file + CONTRIBUTING.md - guidelines for contributing + CREDITS - people that have helped libpcap along + INSTALL.md - this file + LICENSE - the license under which tcpdump is distributed + Makefile.in - compilation rules (input to the configure script) + 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 - 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.solaris.md - notes on using libpcap on Solaris + doc/README.Win32.md - notes on using libpcap on Win32 systems (with Npcap) + VERSION - version of this release + aclocal.m4 - autoconf macros + arcnet.h - ARCNET definitions + atmuni31.h - ATM Q.2931 definitions + bpf_dump.c - BPF program printing routines + bpf_filter.c - BPF filtering routines + bpf_image.c - BPF disassembly routine + config.guess - autoconf support + config.h.in - autoconf input + config.sub - autoconf support + configure - configure script (run this first) + configure.ac - configure script source + dlpisubs.c - DLPI-related functions for pcap-dlpi.c and pcap-libdlpi.c + dlpisubs.h - DLPI-related function declarations + etherent.c - /etc/ethers support routines + ethertype.h - Ethernet protocol types and names definitions + fad-getad.c - pcap_findalldevs() for systems with getifaddrs() + fad-gifc.c - pcap_findalldevs() for systems with only SIOCGIFLIST + fad-glifc.c - pcap_findalldevs() for systems with SIOCGLIFCONF + testprogs/filtertest.c - test program for BPF compiler + testprogs/findalldevstest.c - test program for pcap_findalldevs() + gencode.c - BPF code generation routines + gencode.h - BPF code generation definitions + grammar.y - filter string grammar + ieee80211.h - 802.11 definitions + install-sh - BSD style install script + lbl/os-*.h - OS-dependent defines and prototypes + llc.h - 802.2 LLC SAP definitions + missing/* - replacements for missing library functions + mkdep - construct Makefile dependency list + msdos/* - drivers for MS-DOS capture support + nametoaddr.c - hostname to address routines + nlpid.h - OSI network layer protocol identifier definitions + optimize.c - BPF optimization routines + pcap/bluetooth.h - public definition of DLT_BLUETOOTH_HCI_H4_WITH_PHDR header + pcap/bpf.h - BPF definitions + pcap/namedb.h - public libpcap name database definitions + pcap/pcap.h - public libpcap definitions + pcap/sll.h - public definitions of DLT_LINUX_SLL and DLT_LINUX_SLL2 headers + pcap/usb.h - public definition of DLT_USB header + pcap-bpf.c - BSD Packet Filter support + pcap-bpf.h - header for backwards compatibility + pcap-bt-linux.c - Bluetooth capture support for Linux + pcap-bt-linux.h - Bluetooth capture support for Linux + pcap-dag.c - Endace DAG device capture support + pcap-dag.h - Endace DAG device capture support + pcap-dlpi.c - Data Link Provider Interface support + pcap-dos.c - MS-DOS capture support + pcap-dos.h - headers for MS-DOS capture support + pcap-enet.c - enet support + pcap-int.h - internal libpcap definitions + pcap-libdlpi.c - Data Link Provider Interface support for systems with libdlpi + pcap-linux.c - Linux packet socket support + pcap-namedb.h - header for backwards compatibility + pcap-nit.c - SunOS Network Interface Tap support + pcap-npf.c - Npcap 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-septel.c - Intel/Septel device capture support + pcap-septel.h - Intel/Septel device capture support + pcap-sita.c - SITA device capture support + pcap-sita.h - SITA device capture support + pcap-sita.html - SITA device capture documentation + 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.3pcap - manual entry for the library + pcap.c - pcap utility routines + pcap.h - header for backwards compatibility + pcap_*.3pcap - manual entries for library functions + pcap-filter.manmisc.in - manual entry for filter syntax + pcap-linktype.manmisc.in - manual entry for link-layer header types + ppp.h - Point to Point Protocol definitions + savefile.c - offline support + scanner.l - filter string scanner + sunatmpos.h - definitions for SunATM capturing diff --git a/external/bsd/libpcap/dist/Makefile-devel-adds b/external/bsd/libpcap/dist/Makefile-devel-adds index fea63bbce3a7..7cfd6c91d8e0 100644 --- a/external/bsd/libpcap/dist/Makefile-devel-adds +++ b/external/bsd/libpcap/dist/Makefile-devel-adds @@ -3,12 +3,12 @@ # From autoconf.info . Works best with GNU Make. # ${srcdir}/configure: configure.ac aclocal.m4 - cd ${srcdir} && autoconf + (cd ${srcdir} && autoconf) # autoheader might not change config.h.in, so touch a stamp file. ${srcdir}/config.h.in: ${srcdir}/stamp-h.in ${srcdir}/stamp-h.in: configure.ac aclocal.m4 - cd ${srcdir} && autoheader + (cd ${srcdir} && autoheader) echo timestamp > ${srcdir}/stamp-h.in config.h: stamp-h diff --git a/external/bsd/libpcap/dist/Makefile.in b/external/bsd/libpcap/dist/Makefile.in index 5a6b165da3f0..3468e204c756 100644 --- a/external/bsd/libpcap/dist/Makefile.in +++ b/external/bsd/libpcap/dist/Makefile.in @@ -1,5 +1,5 @@ # Copyright (c) 1993, 1994, 1995, 1996 -# The Regents of the University of California. All rights reserved. +# 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 @@ -38,6 +38,7 @@ mandir = @mandir@ # VPATH srcdir = @srcdir@ +top_srcdir = @top_srcdir@ VPATH = @srcdir@ # @@ -60,16 +61,16 @@ CROSSFLAGS= CFLAGS = @CFLAGS@ ${CROSSFLAGS} LDFLAGS = @LDFLAGS@ ${CROSSFLAGS} DYEXT = @DYEXT@ -V_RPATH_OPT = @V_RPATH_OPT@ +RPATH = @RPATH@ 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 for building members of a shared library FULL_CFLAGS = $(CCOPT) @V_LIB_CCOPT_FAT@ $(SHLIB_CCOPT) $(INCLS) $(DEFS) $(CFLAGS) +CXXFLAGS = $(CCOPT) @V_LIB_CCOPT_FAT@ $(SHLIB_CCOPT) $(INCLS) $(DEFS) $(CFLAGS) INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -77,7 +78,7 @@ INSTALL_DATA = @INSTALL_DATA@ RANLIB = @RANLIB@ LEX = @LEX@ -YACC = @YACC@ +BISON_BYACC = @BISON_BYACC@ # 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 @@ -86,40 +87,48 @@ 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@ @NETMAP_SRC@ @RDMA_SRC@ -FSRC = @V_FINDALLDEVS@ -SSRC = @SSRC@ -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 +PLATFORM_C_SRC = @PLATFORM_C_SRC@ +PLATFORM_CXX_SRC = @PLATFORM_CXX_SRC@ +MODULE_C_SRC = @MODULE_C_SRC@ +REMOTE_C_SRC = @REMOTE_C_SRC@ +COMMON_C_SRC = pcap.c gencode.c optimize.c nametoaddr.c etherent.c \ + fmtutils.c pcap-util.c \ + savefile.c sf-pcap.c sf-pcapng.c pcap-common.c \ + pcap-usb-linux-common.c bpf_image.c bpf_filter.c bpf_dump.c +GENERATED_C_SRC = scanner.c grammar.c LIBOBJS = @LIBOBJS@ -SRC = $(PSRC) $(FSRC) $(CSRC) $(SSRC) $(GENSRC) +SRC = $(PLATFORM_C_SRC) $(PLATFORM_CXX_SRC) \ + $(MODULE_C_SRC) $(REMOTE_C_SRC) $(COMMON_C_SRC) \ + $(GENERATED_C_SRC) # We would like to say "OBJ = $(SRC:.c=.o)" but Ultrix's make cannot -# hack the extra indirection -OBJ = $(PSRC:.c=.o) $(FSRC:.c=.o) $(CSRC:.c=.o) $(SSRC:.c=.o) $(GENSRC:.c=.o) $(LIBOBJS) +# hack the extra indirection, and we have to handle PLATFORM_CXX_SRC +# differently from the defines for C source +OBJ = $(PLATFORM_C_SRC:.c=.o) $(PLATFORM_CXX_SRC:.cpp=.o) \ + $(MODULE_C_SRC:.c=.o) $(REMOTE_C_SRC:.c=.o) $(COMMON_C_SRC:.c=.o) \ + $(GENERATED_C_SRC:.c=.o) \ + $(LIBOBJS) + PUBHDR = \ pcap.h \ pcap-bpf.h \ pcap-namedb.h \ - pcap/bpf.h \ pcap/bluetooth.h \ + pcap/bpf.h \ pcap/can_socketcan.h \ pcap/compiler-tests.h \ pcap/dlt.h \ pcap/funcattrs.h \ - pcap/pcap-inttypes.h \ pcap/ipnet.h \ pcap/namedb.h \ pcap/nflog.h \ + pcap/pcap-inttypes.h \ pcap/pcap.h \ pcap/sll.h \ pcap/socket.h \ - pcap/vlan.h \ - pcap/usb.h + pcap/usb.h \ + pcap/vlan.h HDR = $(PUBHDR) \ arcnet.h \ @@ -139,6 +148,9 @@ HDR = $(PUBHDR) \ pcap-int.h \ pcap-rpcap.h \ pcap-types.h \ + pcap-usb-linux-common.h \ + pcap-util.h \ + pflog.h \ portability.h \ ppp.h \ rpcap-protocol.h \ @@ -154,7 +166,7 @@ TAGFILES = \ $(SRC) $(HDR) CLEANFILES = $(OBJ) libpcap.a libpcap.so.`cat $(srcdir)/VERSION` \ - $(PROG)-`cat $(srcdir)/VERSION`.tar.gz $(GENSRC) $(GENHDR) \ + $(PROG)-`cat $(srcdir)/VERSION`.tar.gz $(GENERATED_C_SRC) $(GENHDR) \ lex.yy.c pcap-config libpcap.pc MAN1 = pcap-config.1 @@ -193,6 +205,7 @@ MAN3PCAP_NOEXPAND = \ pcap_get_required_select_timeout.3pcap \ pcap_get_selectable_fd.3pcap \ pcap_geterr.3pcap \ + pcap_init.3pcap \ pcap_inject.3pcap \ pcap_is_swapped.3pcap \ pcap_lib_version.3pcap \ @@ -241,15 +254,27 @@ EXTRA_DIST = \ Makefile.in \ Makefile-devel-adds \ README.md \ - doc \ + doc/README.Win32.md \ + doc/README.aix \ + doc/README.dag \ + doc/README.hpux \ + doc/README.linux \ + doc/README.macos \ + doc/README.septel \ + doc/README.sita \ + doc/README.solaris.md \ CONTRIBUTING.md \ TODO \ VERSION \ aclocal.m4 \ + charconv.c \ + charconv.h \ chmod_bpf \ cmake_uninstall.cmake.in \ cmakeconfig.h.in \ + cmake/Modules/FindAirPcap.cmake \ cmake/Modules/FindDAG.cmake \ + cmake/Modules/Finddpdk.cmake \ cmake/Modules/FindFseeko.cmake \ cmake/Modules/FindLFS.cmake \ cmake/Modules/FindPacket.cmake \ @@ -266,7 +291,7 @@ EXTRA_DIST = \ fad-getad.c \ fad-gifc.c \ fad-glifc.c \ - grammar.y \ + grammar.y.in \ install-sh \ lbl/os-aix4.h \ lbl/os-aix7.h \ @@ -280,12 +305,10 @@ EXTRA_DIST = \ missing/asprintf.c \ missing/getopt.c \ missing/getopt.h \ - missing/snprintf.c \ missing/strlcat.c \ missing/strlcpy.c \ missing/strtok_r.c \ missing/win_asprintf.c \ - missing/win_snprintf.c \ mkdep \ msdos/bin2c.c \ msdos/makefile \ @@ -298,6 +321,8 @@ EXTRA_DIST = \ msdos/readme.dos \ nomkdep \ org.tcpdump.chmod_bpf.plist \ + pcap-airpcap.c \ + pcap-airpcap.h \ pcap-bpf.c \ pcap-bt-linux.c \ pcap-bt-linux.h \ @@ -312,7 +337,10 @@ EXTRA_DIST = \ pcap-dlpi.c \ pcap-dos.c \ pcap-dos.h \ + pcap-dpdk.c \ + pcap-dpdk.h \ pcap-enet.c \ + pcap-haiku.cpp \ pcap-int.h \ pcap-libdlpi.c \ pcap-linux.c \ @@ -367,6 +395,8 @@ EXTRA_DIST = \ rpcapd/win32-svc.h \ sockutils.c \ sockutils.h \ + sslutils.c \ + sslutils.h \ scanner.l \ testprogs/CMakeLists.txt \ testprogs/Makefile.in \ @@ -374,16 +404,30 @@ EXTRA_DIST = \ testprogs/capturetest.c \ testprogs/filtertest.c \ testprogs/findalldevstest.c \ + testprogs/findalldevstest-perf.c \ + testprogs/fuzz/CMakeLists.txt \ + testprogs/fuzz/fuzz_both.c \ + testprogs/fuzz/fuzz_both.options \ + testprogs/fuzz/fuzz_filter.c \ + testprogs/fuzz/fuzz_filter.options \ + testprogs/fuzz/fuzz_pcap.c \ + testprogs/fuzz/fuzz_pcap.options \ + testprogs/fuzz/onefile.c \ + testprogs/nonblocktest.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 + testprogs/visopts.py \ + testprogs/writecaptest.c + +TEST_DIST = `git ls-files tests | grep -v 'tests/\..*'` + +RELEASE_FILES = $(COMMON_C_SRC) $(HDR) $(MAN1) $(MAN3PCAP_EXPAND) \ + $(MAN3PCAP_NOEXPAND) $(MANFILE) $(MANMISC) $(EXTRA_DIST) \ + $(TEST_DIST) all: libpcap.a shared $(BUILD_RPCAPD) libpcap.pc pcap-config @@ -480,8 +524,27 @@ scanner.h: scanner.c scanner.o: scanner.c grammar.h $(CC) $(FULL_CFLAGS) -c scanner.c -grammar.c: $(srcdir)/grammar.y - $(YACC) -p pcap_ -o grammar.c -d $< +# +# Generate the grammar.y file. +# +# Some Makes, e.g. AIX Make and Solaris Make, can't handle "--file=$@.tmp:$<"; +# for example, the Solaris 9 make man page says +# +# Because make assigns $< and $* as it would for implicit rules +# (according to the suffixes list and the directory contents), +# they may be unreliable when used within explicit target entries. +# +# and this is an explicit target entry. +# +# Therefore, instead of using $<, we explicitly put in $(srcdir)/libpcap.pc.in. +# +grammar.y: $(srcdir)/grammar.y.in ./config.status + @rm -f $@ $@.tmp + ./config.status --file=$@.tmp:$(srcdir)/grammar.y.in + mv $@.tmp $@ + +grammar.c: grammar.y + $(BISON_BYACC) -p pcap_ -o grammar.c -d $< grammar.h: grammar.c ## Recover from the removal of $@ @if test -f $@; then :; else \ @@ -528,7 +591,6 @@ 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. @@ -543,13 +605,13 @@ pcap-config: $(srcdir)/pcap-config.in ./config.status # Remote pcap daemon. # build-rpcapd: libpcap.a - cd rpcapd; $(MAKE) + (cd rpcapd; $(MAKE)) # # Test programs - not built by default, and not installed. # testprogs: FORCE - cd testprogs; $(MAKE) + (cd testprogs; $(MAKE)) FORCE: @@ -681,7 +743,7 @@ install-archive-shareda: # install-rpcapd: - cd rpcapd; $(MAKE) DESTDIR=$(DESTDIR) install + (cd rpcapd; $(MAKE) DESTDIR=$(DESTDIR) install) uninstall: uninstall-shared uninstall-rpcapd rm -f $(DESTDIR)$(libdir)/libpcap.a @@ -695,6 +757,7 @@ uninstall: uninstall-shared uninstall-rpcapd for i in $(MAN3PCAP); do \ rm -f $(DESTDIR)$(mandir)/man3/$$i; done rm -f $(DESTDIR)$(mandir)/man3/pcap_datalink_val_to_description.3pcap + rm -f $(DESTDIR)$(mandir)/man3/pcap_datalink_val_to_description_or_dlt.3pcap rm -f $(DESTDIR)$(mandir)/man3/pcap_dump_fopen.3pcap rm -f $(DESTDIR)$(mandir)/man3/pcap_freealldevs.3pcap rm -f $(DESTDIR)$(mandir)/man3/pcap_perror.3pcap @@ -737,21 +800,21 @@ uninstall-shared-shareda: uninstall-shared-none: uninstall-rpcapd: - cd rpcapd; $(MAKE) DESTDIR=$(DESTDIR) uninstall + (cd rpcapd; $(MAKE) DESTDIR=$(DESTDIR) uninstall) clean: rm -f $(CLEANFILES) - cd rpcapd; $(MAKE) clean - cd testprogs; $(MAKE) clean + (cd rpcapd; $(MAKE) clean) + (cd testprogs; $(MAKE) clean) distclean: clean - rm -f Makefile config.cache config.log config.status \ - config.h gnuc.h net os-proto.h libpcap.pc \ - pcap-config stamp-h stamp-h.in + rm -f Makefile grammar.y config.cache config.log config.status \ + config.h config.h.in~ configure~ configure.ac~ \ + 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 + (cd rpcapd; $(MAKE) distclean) + (cd testprogs; $(MAKE) distclean) extags: $(TAGFILES) ctags $(TAGFILES) @@ -760,15 +823,21 @@ tags: $(TAGFILES) ctags -wtd $(TAGFILES) releasetar: - @cwd=`pwd` ; dir=`basename $$cwd` ; name=$(PROG)-`cat VERSION` ; \ - mkdir $$name; \ - 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) - $(MKDEP) -c "$(CC)" -m "$(DEPENDENCY_CFLAG)" $(CFLAGS) $(DEFS) $(INCLS) $(SRC) - cd rpcapd; $(MAKE) depend - cd testprogs; $(MAKE) depend + @TAG=$(PROG)-`cat VERSION` && \ + if git show-ref --tags --quiet --verify -- "refs/tags/$$TAG"; then \ + git archive --prefix="$$TAG"/ -o "$$TAG".tar.gz "$$TAG" \ + $(RELEASE_FILES) && \ + echo "Archive build from tag $$TAG."; \ + else \ + git archive --prefix="$$TAG"/ -o "$$TAG".tar.gz HEAD \ + $(RELEASE_FILES) && \ + echo "No $$TAG tag. Archive build from HEAD."; \ + fi + +depend: $(GENERATED_C_SRC) $(GENHDR) + $(MKDEP) -c "$(CC)" -m "$(DEPENDENCY_CFLAG)" -s "$(srcdir)" $(CFLAGS) $(DEFS) $(INCLS) $(SRC) + (cd rpcapd; $(MAKE) depend) + (cd testprogs; $(MAKE) depend) + +shellcheck: + shellcheck -f gcc -e SC2006 build.sh build_matrix.sh build_common.sh diff --git a/external/bsd/libpcap/dist/README.md b/external/bsd/libpcap/dist/README.md index 78cc3c4b41b5..e38b9a15d6b3 100644 --- a/external/bsd/libpcap/dist/README.md +++ b/external/bsd/libpcap/dist/README.md @@ -1,22 +1,17 @@ -To report a security issue please send an e-mail to security@tcpdump.org. +# LIBPCAP 1.x.y by [The Tcpdump Group](https://www.tcpdump.org) -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. +**To report a security issue please send an e-mail to security@tcpdump.org.** -The directory doc/ has README files about specific operating systems and -options. +To report bugs and other problems, contribute patches, request a +feature, provide generic feedback etc please see the +[guidelines for contributing](CONTRIBUTING.md). -LIBPCAP 1.x.y -Now maintained by "The Tcpdump Group" -https://www.tcpdump.org +The [documentation directory](doc/) has README files about specific +operating systems and options. Anonymous Git is available via: - https://github.com/the-tcpdump-group/libpcap.git -formerly from Lawrence Berkeley National Laboratory - Network Research Group - ftp://ftp.ee.lbl.gov/old/libpcap-0.4a7.tar.Z + https://github.com/the-tcpdump-group/libpcap.git This directory contains source code for libpcap, a system-independent interface for user-level packet capture. libpcap provides a portable @@ -28,7 +23,14 @@ require this functionality, we've created this system-independent API to ease in porting and to alleviate the need for several system-dependent packet capture modules in each application. -For some platforms there are README.{system} files that discuss issues +```text +formerly from Lawrence Berkeley National Laboratory + Network Research Group + ftp://ftp.ee.lbl.gov/old/libpcap-0.4a7.tar.Z +``` + +### Support for particular platforms and BPF +For some platforms there are `README.{system}` files that discuss issues with the OS's interface for packet capture on those platforms, such as how to enable support for that interface in the OS, if it's not built in by default. @@ -36,22 +38,10 @@ by default. The libpcap interface supports a filtering mechanism based on the architecture in the BSD packet filter. BPF is described in the 1993 Winter Usenix paper ``The BSD Packet Filter: A New Architecture for -User-level Packet Capture''. A compressed PostScript version can be -found at - - ftp://ftp.ee.lbl.gov/papers/bpf-usenix93.ps.Z - -or - - https://www.tcpdump.org/papers/bpf-usenix93.ps.Z - -and a gzipped version can be found at - - https://www.tcpdump.org/papers/bpf-usenix93.ps.gz - -A PDF version can be found at - - https://www.tcpdump.org/papers/bpf-usenix93.pdf +User-level Packet Capture'' +([compressed PostScript](https://www.tcpdump.org/papers/bpf-usenix93.ps.Z), +[gzipped PostScript](https://www.tcpdump.org/papers/bpf-usenix93.ps.gz), +[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,32 +52,25 @@ 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 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: - - https://www.tcpdump.org/other/bpfext42.tar.Z +BSD, macOS, and Solaris 11; 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). 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. +See the [Linux-specific README](doc/README.linux) for more information. -Note to Linux distributions and *BSD systems that include libpcap: +### Note to Linux distributions and *BSD systems that include libpcap: There's now a rule to make a shared library, which should work on Linux and *BSD, among other platforms. -It sets the soname of the library to "libpcap.so.1"; this is what it -should be, *NOT* libpcap.so.1.x or libpcap.so.1.x.y or something such as +It sets the soname of the library to `libpcap.so.1`; this is what it +should be, **NOT** `libpcap.so.1.x` or `libpcap.so.1.x.y` or something such as that. 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. - -Current versions can be found at https://www.tcpdump.org. - - - The TCPdump group diff --git a/external/bsd/libpcap/dist/TODO b/external/bsd/libpcap/dist/TODO index aae24c22d251..65e166b60bc1 100644 --- a/external/bsd/libpcap/dist/TODO +++ b/external/bsd/libpcap/dist/TODO @@ -31,5 +31,3 @@ Less urgent items + too many functions. There are a lot of functions for everything which violates the KISS principle. Why do we need pcap_strerror, pcap_perror and pcap_geterr? - + the manpage has a brief description of each function but where is the - big picture? Seems like you need to buy UNP for that... diff --git a/external/bsd/libpcap/dist/VERSION b/external/bsd/libpcap/dist/VERSION index 9ab8337f3962..18b311420650 100644 --- a/external/bsd/libpcap/dist/VERSION +++ b/external/bsd/libpcap/dist/VERSION @@ -1 +1 @@ -1.9.1 +1.10.4 diff --git a/external/bsd/libpcap/dist/aclocal.m4 b/external/bsd/libpcap/dist/aclocal.m4 index aa91e846ed6b..9ec93c28d5e5 100644 --- a/external/bsd/libpcap/dist/aclocal.m4 +++ b/external/bsd/libpcap/dist/aclocal.m4 @@ -232,34 +232,27 @@ AC_DEFUN(AC_LBL_C_INIT, ]) dnl -dnl Check whether, if you pass an unknown warning option to the -dnl compiler, it fails or just prints a warning message and succeeds. -dnl Set ac_lbl_unknown_warning_option_error to the appropriate flag -dnl to force an error if it would otherwise just print a warning message -dnl and succeed. +dnl Save the values of various variables that affect compilation and +dnl linking, and that we don't ourselves modify persistently; done +dnl before a test involving compiling or linking is done, so that we +dnl can restore those variables after the test is done. dnl -AC_DEFUN(AC_LBL_CHECK_UNKNOWN_WARNING_OPTION_ERROR, - [ - AC_MSG_CHECKING([whether the compiler fails when given an unknown warning option]) +AC_DEFUN(AC_LBL_SAVE_CHECK_STATE, +[ save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Wxyzzy-this-will-never-succeed-xyzzy" - AC_TRY_COMPILE( - [], - [return 0], - [ - AC_MSG_RESULT([no]) - # - # We're assuming this is clang, where - # -Werror=unknown-warning-option is the appropriate - # option to force the compiler to fail. - # - ac_lbl_unknown_warning_option_error="-Werror=unknown-warning-option" - ], - [ - AC_MSG_RESULT([yes]) - ]) + save_LIBS="$LIBS" + save_LDFLAGS="$LDFLAGS" +]) + +dnl +dnl Restore the values of variables saved by AC_LBL_SAVE_CHECK_STATE. +dnl +AC_DEFUN(AC_LBL_RESTORE_CHECK_STATE, +[ CFLAGS="$save_CFLAGS" - ]) + LIBS="$save_LIBS" + LDFLAGS="$save_LDFLAGS" +]) dnl dnl Check whether the compiler option specified as the second argument @@ -271,28 +264,42 @@ 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 should also be supplied; it's a message describing 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]) save_CFLAGS="$CFLAGS" - if expr "x$2" : "x-W.*" >/dev/null - then - CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error $2" - elif expr "x$2" : "x-f.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror $2" - elif expr "x$2" : "x-m.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror $2" - else - CFLAGS="$CFLAGS $2" - fi - AC_TRY_COMPILE( - [], - [return 0], + CFLAGS="$CFLAGS $2" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([[int main(void) { return 0; }]])], [ AC_MSG_RESULT([yes]) can_add_to_cflags=yes @@ -332,6 +339,7 @@ AC_DEFUN(AC_LBL_CHECK_COMPILER_OPT, AC_MSG_RESULT([no]) CFLAGS="$save_CFLAGS" ]) + ac_c_werror_flag="$save_ac_c_werror_flag" ]) dnl @@ -425,14 +433,14 @@ AC_DEFUN(AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT, 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' + MKDEP='${top_srcdir}/mkdep' else AC_MSG_RESULT([no]) # # We can't run mkdep, so have "make depend" do # nothing. # - MKDEP='${srcdir}/nomkdep' + MKDEP='${top_srcdir}/nomkdep' fi rm -rf conftest* else @@ -441,7 +449,7 @@ AC_DEFUN(AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT, # We can't run mkdep, so have "make depend" do # nothing. # - MKDEP='${srcdir}/nomkdep' + MKDEP='${top_srcdir}/nomkdep' fi AC_SUBST(DEPENDENCY_CFLAG) AC_SUBST(MKDEP) @@ -460,7 +468,6 @@ dnl V_SHLIB_CCOPT (modified to build position-independent code) dnl V_SHLIB_CMD dnl V_SHLIB_OPT dnl V_SONAME_OPT -dnl V_RPATH_OPT dnl AC_DEFUN(AC_LBL_SHLIBS_INIT, [AC_PREREQ(2.50) @@ -484,11 +491,12 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT, aix*) ;; - freebsd*|netbsd*|openbsd*|dragonfly*|linux*|osf*|midipix*) - # - # Platforms where the linker is the GNU linker - # or accepts command-line arguments like - # those the GNU linker accepts. + freebsd*|netbsd*|openbsd*|dragonfly*|linux*|osf*|haiku*|midipix*) + # + # Platforms where the C compiler is GCC or accepts + # compatible command-line arguments, and the linker + # is the GNU linker or accepts compatible command-line + # arguments. # # Some instruction sets require -fPIC on some # operating systems. Check for them. If you @@ -509,12 +517,11 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT, esac V_SHLIB_CCOPT="$V_SHLIB_CCOPT $PIC_OPT" V_SONAME_OPT="-Wl,-soname," - V_RPATH_OPT="-Wl,-rpath," ;; hpux*) V_SHLIB_CCOPT="$V_SHLIB_CCOPT -fpic" - # + # # XXX - this assumes GCC is using the HP linker, # rather than the GNU linker, and that the "+h" # option is used on all HP-UX platforms, both .sl @@ -522,7 +529,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT, # V_SONAME_OPT="-Wl,+h," # - # By default, directories specifed with -L + # By default, directories specified with -L # are added to the run-time search path, so # we don't add them in pcap-config. # @@ -531,11 +538,12 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT, solaris*) V_SHLIB_CCOPT="$V_SHLIB_CCOPT -fpic" # - # XXX - this assumes GCC is using the Sun linker, - # rather than the GNU linker. + # Sun/Oracle's C compiler, GCC, and GCC-compatible + # compilers support -Wl,{comma-separated list of options}, + # and we use the C compiler, not ld, for all linking, + # including linking to produce a shared library. # V_SONAME_OPT="-Wl,-h," - V_RPATH_OPT="-Wl,-R," ;; esac else @@ -557,7 +565,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT, # "-Wl,-soname,{soname}" option, with the soname part # of the option, while on other platforms the C compiler # driver takes it as a regular option with the soname - # following the option. The same applies to V_RPATH_OPT. + # following the option. # case "$host_os" in @@ -568,13 +576,17 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT, freebsd*|netbsd*|openbsd*|dragonfly*|linux*) # - # "cc" is GCC. + # Platforms where the C compiler is GCC or accepts + # compatible command-line arguments, and the linker + # is the GNU linker or accepts compatible command-line + # arguments. + # + # XXX - does 64-bit SPARC require -fPIC? # V_SHLIB_CCOPT="$V_SHLIB_CCOPT -fpic" V_SHLIB_CMD="\$(CC)" V_SHLIB_OPT="-shared" V_SONAME_OPT="-Wl,-soname," - V_RPATH_OPT="-Wl,-rpath," ;; hpux*) @@ -583,29 +595,33 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT, V_SHLIB_OPT="-b" V_SONAME_OPT="+h " # - # By default, directories specifed with -L + # By default, directories specified with -L # are added to the run-time search path, so # we don't add them in pcap-config. # ;; osf*) - # + # # Presumed to be DEC OSF/1, Digital UNIX, or # Tru64 UNIX. # V_SHLIB_CMD="\$(CC)" V_SHLIB_OPT="-shared" V_SONAME_OPT="-soname " - V_RPATH_OPT="-rpath " ;; solaris*) V_SHLIB_CCOPT="$V_SHLIB_CCOPT -Kpic" V_SHLIB_CMD="\$(CC)" V_SHLIB_OPT="-G" - V_SONAME_OPT="-h " - V_RPATH_OPT="-R" + # + # Sun/Oracle's C compiler, GCC, and GCC-compatible + # compilers support -Wl,{comma-separated list of options}, + # and we use the C compiler, not ld, for all linking, + # including linking to produce a shared library. + # + V_SONAME_OPT="-Wl,-h," ;; esac fi @@ -662,6 +678,46 @@ AC_DEFUN(AC_LBL_C_INLINE, fi AC_DEFINE_UNQUOTED(inline, $ac_cv_lbl_inline, [Define as token for inline if inlining supported])]) +# +# Test whether we have __atomic_load_n() and __atomic_store_n(). +# +# We use AC_TRY_LINK because AC_TRY_COMPILE will succeed, as the +# compiler will just think that those functions are undefined, +# and perhaps warn about that, but not fail to compile. +# +AC_DEFUN(AC_PCAP_C___ATOMICS, + [ + AC_MSG_CHECKING(for __atomic_load_n) + AC_CACHE_VAL(ac_cv_have___atomic_load_n, + AC_TRY_LINK([], + [ + int i = 17; + int j; + j = __atomic_load_n(&i, __ATOMIC_RELAXED); + ], + ac_have___atomic_load_n=yes, + ac_have___atomic_load_n=no)) + AC_MSG_RESULT($ac_have___atomic_load_n) + if test $ac_have___atomic_load_n = yes ; then + AC_DEFINE(HAVE___ATOMIC_LOAD_N, 1, + [define if __atomic_load_n is supported by the compiler]) + fi + + AC_MSG_CHECKING(for __atomic_store_n) + AC_CACHE_VAL(ac_cv_have___atomic_store_n, + AC_TRY_LINK([], + [ + int i; + __atomic_store_n(&i, 17, __ATOMIC_RELAXED); + ], + ac_have___atomic_store_n=yes, + ac_have___atomic_store_n=no)) + AC_MSG_RESULT($ac_have___atomic_store_n) + if test $ac_have___atomic_store_n = yes ; then + AC_DEFINE(HAVE___ATOMIC_STORE_N, 1, + [define if __atomic_store_n is supported by the compiler]) + fi]) + dnl dnl If using gcc, make sure we have ANSI ioctl definitions dnl @@ -752,106 +808,6 @@ AC_DEFUN(AC_LBL_HAVE_RUN_PATH, AC_MSG_RESULT($ac_cv_lbl_have_run_path) ]) -dnl -dnl Checks to see if unaligned memory accesses fail -dnl -dnl usage: -dnl -dnl AC_LBL_UNALIGNED_ACCESS -dnl -dnl results: -dnl -dnl LBL_ALIGN (DEFINED) -dnl -AC_DEFUN(AC_LBL_UNALIGNED_ACCESS, - [AC_MSG_CHECKING(if unaligned accesses fail) - AC_CACHE_VAL(ac_cv_lbl_unaligned_fail, - [case "$host_cpu" in - - # - # These are CPU types where: - # - # the CPU faults on an unaligned access, but at least some - # OSes that support that CPU catch the fault and simulate - # the unaligned access (e.g., Alpha/{Digital,Tru64} UNIX) - - # the simulation is slow, so we don't want to use it; - # - # the CPU, I infer (from the old - # - # XXX: should also check that they don't do weird things (like on arm) - # - # comment) doesn't fault on unaligned accesses, but doesn't - # do a normal unaligned fetch, either (e.g., presumably, ARM); - # - # for whatever reason, the test program doesn't work - # (this has been claimed to be the case for several of those - # CPUs - I don't know what the problem is; the problem - # was reported as "the test program dumps core" for SuperH, - # but that's what the test program is *supposed* to do - - # it dumps core before it writes anything, so the test - # for an empty output file should find an empty output - # file and conclude that unaligned accesses don't work). - # - # This run-time test won't work if you're cross-compiling, so - # in order to support cross-compiling for a particular CPU, - # we have to wire in the list of CPU types anyway, as far as - # I know, so perhaps we should just have a set of CPUs on - # which we know it doesn't work, a set of CPUs on which we - # know it does work, and have the script just fail on other - # cpu types and update it when such a failure occurs. - # - alpha*|arm*|bfin*|hp*|mips*|sh*|sparc*|ia64|nv1) - ac_cv_lbl_unaligned_fail=yes - ;; - - *) - cat >conftest.c < -# include -# include - unsigned char a[[5]] = { 1, 2, 3, 4, 5 }; - main() { - unsigned int i; - pid_t pid; - int status; - /* avoid "core dumped" message */ - pid = fork(); - if (pid < 0) - exit(2); - if (pid > 0) { - /* parent */ - pid = waitpid(pid, &status, 0); - if (pid < 0) - exit(3); - exit(!WIFEXITED(status)); - } - /* child */ - i = *(unsigned int *)&a[[1]]; - printf("%d\n", i); - exit(0); - } -EOF - ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS \ - conftest.c $LIBS >/dev/null 2>&1 - if test ! -x conftest ; then - dnl failed to compile for some reason - ac_cv_lbl_unaligned_fail=yes - else - ./conftest >conftest.out - if test ! -s conftest.out ; then - ac_cv_lbl_unaligned_fail=yes - else - ac_cv_lbl_unaligned_fail=no - fi - fi - rm -f -r conftest* core core.conftest - ;; - esac]) - AC_MSG_RESULT($ac_cv_lbl_unaligned_fail) - if test $ac_cv_lbl_unaligned_fail = yes ; then - AC_DEFINE(LBL_ALIGN,1,[if unaligned access fails]) - fi]) - dnl dnl If the file .devel exists: dnl Add some warning flags if the compiler supports them @@ -877,16 +833,16 @@ AC_DEFUN(AC_LBL_DEVEL, # Skip all the warning option stuff on some compilers. # if test "$ac_lbl_cc_dont_try_gcc_dashW" != yes; then - AC_LBL_CHECK_UNKNOWN_WARNING_OPTION_ERROR() AC_LBL_CHECK_COMPILER_OPT($1, -W) AC_LBL_CHECK_COMPILER_OPT($1, -Wall) AC_LBL_CHECK_COMPILER_OPT($1, -Wcomma) - AC_LBL_CHECK_COMPILER_OPT($1, -Wdeclaration-after-statement) AC_LBL_CHECK_COMPILER_OPT($1, -Wdocumentation) AC_LBL_CHECK_COMPILER_OPT($1, -Wformat-nonliteral) AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-noreturn) AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-prototypes) AC_LBL_CHECK_COMPILER_OPT($1, -Wmissing-variable-declarations) + AC_LBL_CHECK_COMPILER_OPT($1, -Wpointer-arith) + AC_LBL_CHECK_COMPILER_OPT($1, -Wpointer-sign) AC_LBL_CHECK_COMPILER_OPT($1, -Wshadow) AC_LBL_CHECK_COMPILER_OPT($1, -Wsign-compare) AC_LBL_CHECK_COMPILER_OPT($1, -Wstrict-prototypes) @@ -930,6 +886,7 @@ testme(unsigned short a) } ], [generates warnings from ntohs()]) + AC_LBL_CHECK_COMPILER_OPT($1, -Wshorten-64-to-32) fi AC_LBL_CHECK_DEPENDENCY_GENERATION_OPT() # @@ -1057,9 +1014,22 @@ AC_DEFUN(AC_LBL_LIBRARY_NET, [ ], [ # - # We didn't find it. + # Not found in libsocket; test for it in libnetwork, which + # is where it is in Haiku. # - AC_MSG_ERROR([getaddrinfo is required, but wasn't found]) + AC_CHECK_LIB(network, getaddrinfo, + [ + # + # OK, we found it in libnetwork. + # + LIBS="-lnetwork $LIBS" + ], + [ + # + # We didn't find it. + # + AC_MSG_ERROR([getaddrinfo is required, but wasn't found]) + ]) ], -lnsl) # @@ -1077,3 +1047,281 @@ AC_DEFUN(AC_LBL_LIBRARY_NET, [ # DLPI needs putmsg under HPUX so test for -lstr while we're at it AC_SEARCH_LIBS(putmsg, str) ]) + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +dnl serial 11 (pkg-config-0.29) +dnl +dnl Copyright © 2004 Scott James Remnant . +dnl Copyright © 2012-2015 Dan Nicholson +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +dnl 02111-1307, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a +dnl configuration script generated by Autoconf, you may include it under +dnl the same distribution terms that you use for the rest of that +dnl program. + +dnl PKG_PREREQ(MIN-VERSION) +dnl ----------------------- +dnl Since: 0.29 +dnl +dnl Verify that the version of the pkg-config macros are at least +dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's +dnl installed version of pkg-config, this checks the developer's version +dnl of pkg.m4 when generating configure. +dnl +dnl To ensure that this macro is defined, also add: +dnl m4_ifndef([PKG_PREREQ], +dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) +dnl +dnl See the "Since" comment for each macro you use to see what version +dnl of the macros you require. +m4_defun([PKG_PREREQ], +[m4_define([PKG_MACROS_VERSION], [0.29]) +m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, + [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) +])dnl PKG_PREREQ + +dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) +dnl ---------------------------------- +dnl Since: 0.16 +dnl +dnl Search for the pkg-config tool and set the PKG_CONFIG variable to +dnl first found in the path. Checks that the version of pkg-config found +dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.17.0 is +dnl used since that's the first version where --static was supported. +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.17.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])dnl PKG_PROG_PKG_CONFIG + +dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------------------------------- +dnl Since: 0.18 +dnl +dnl Check to see whether a particular set of modules exists. Similar to +dnl PKG_CHECK_MODULES(), but does not set variables or print errors. +AC_DEFUN([PKG_CHECK_EXISTS], +[ +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +dnl _PKG_CONFIG([VARIABLE], [FLAGS], [MODULES]) +dnl --------------------------------------------- +dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting +dnl pkg_failed based on the result. +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG $2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])dnl _PKG_CONFIG + +dnl _PKG_SHORT_ERRORS_SUPPORTED +dnl --------------------------- +dnl Internal check to see if pkg-config supports short errors. +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[ +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])dnl _PKG_SHORT_ERRORS_SUPPORTED + + +dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl -------------------------------------------------------------- +dnl Since: 0.4.0 +AC_DEFUN([PKG_CHECK_MODULES], +[ +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $2, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $2, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS_STATIC], [static-link linker flags for $2, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $2 with pkg-config]) +PKG_CHECK_EXISTS($2, + [ + # + # The package was found, so try to get its C flags and + # libraries. + # + _PKG_CONFIG([$1][_CFLAGS], [--cflags], [$2]) + _PKG_CONFIG([$1][_LIBS], [--libs], [$2]) + _PKG_CONFIG([$1][_LIBS_STATIC], [--libs --static], [$2]) + + m4_define([_PKG_TEXT], [ +Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + + if test $pkg_failed = yes; then + # + # That failed - report an error. + # + AC_MSG_RESULT([error]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) + elif test $pkg_failed = untried; then + # + # We don't have pkg-config, so it didn't work. + # + AC_MSG_RESULT([not found (pkg-config not found)]) + else + # + # We found the package. + # + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + $1[]_LIBS_STATIC=$pkg_cv_[]$1[]_LIBS_STATIC + AC_MSG_RESULT([found]) + $3 + fi[]dnl + ], + [ + # + # The package isn't present. + # + AC_MSG_RESULT([not found]) + ]) +])dnl PKG_CHECK_MODULES + + +dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl --------------------------------------------------------------------- +dnl Since: 0.29 +dnl +dnl Checks for existence of MODULES and gathers its build flags with +dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags +dnl and VARIABLE-PREFIX_LIBS from --libs. +AC_DEFUN([PKG_CHECK_MODULES_STATIC], +[ +_save_PKG_CONFIG=$PKG_CONFIG +PKG_CONFIG="$PKG_CONFIG --static" +PKG_CHECK_MODULES($@) +PKG_CONFIG=$_save_PKG_CONFIG[]dnl +])dnl PKG_CHECK_MODULES_STATIC + + +dnl PKG_INSTALLDIR([DIRECTORY]) +dnl ------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable pkgconfigdir as the location where a module +dnl should install pkg-config .pc files. By default the directory is +dnl $libdir/pkgconfig, but the default can be changed by passing +dnl DIRECTORY. The user can override through the --with-pkgconfigdir +dnl parameter. +AC_DEFUN([PKG_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([pkgconfigdir], + [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, + [with_pkgconfigdir=]pkg_default) +AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_INSTALLDIR + + +dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) +dnl -------------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable noarch_pkgconfigdir as the location where a +dnl module should install arch-independent pkg-config .pc files. By +dnl default the directory is $datadir/pkgconfig, but the default can be +dnl changed by passing DIRECTORY. The user can override through the +dnl --with-noarch-pkgconfigdir parameter. +AC_DEFUN([PKG_NOARCH_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([noarch-pkgconfigdir], + [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, + [with_noarch_pkgconfigdir=]pkg_default) +AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_NOARCH_INSTALLDIR + + +dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------- +dnl Since: 0.28 +dnl +dnl Retrieves the value of the pkg-config variable for the given module. +AC_DEFUN([PKG_CHECK_VAR], +[ +AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + +_PKG_CONFIG([$1], [--variable="][$3]["], [$2]) +AS_VAR_COPY([$1], [pkg_cv_][$1]) + +AS_VAR_IF([$1], [""], [$5], [$4])dnl +])dnl PKG_CHECK_VAR diff --git a/external/bsd/libpcap/dist/charconv.c b/external/bsd/libpcap/dist/charconv.c new file mode 100644 index 000000000000..5f97509ab4e3 --- /dev/null +++ b/external/bsd/libpcap/dist/charconv.c @@ -0,0 +1,217 @@ +/* -*- 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. + */ + +#ifdef _WIN32 +#include +#include + +#include /* Needed for PCAP_ERRBUF_SIZE */ + +#include "charconv.h" + +wchar_t * +cp_to_utf_16le(UINT codepage, const char *cp_string, DWORD flags) +{ + int utf16le_len; + wchar_t *utf16le_string; + + /* + * Map from the specified code page to UTF-16LE. + * First, find out how big a buffer we'll need. + */ + utf16le_len = MultiByteToWideChar(codepage, flags, cp_string, -1, + NULL, 0); + if (utf16le_len == 0) { + /* + * Error. Fail with EINVAL. + */ + errno = EINVAL; + return (NULL); + } + + /* + * Now attempt to allocate a buffer for that. + */ + utf16le_string = malloc(utf16le_len * sizeof (wchar_t)); + if (utf16le_string == NULL) { + /* + * Not enough memory; assume errno has been + * set, and fail. + */ + return (NULL); + } + + /* + * Now convert. + */ + utf16le_len = MultiByteToWideChar(codepage, flags, cp_string, -1, + utf16le_string, utf16le_len); + if (utf16le_len == 0) { + /* + * Error. Fail with EINVAL. + * XXX - should this ever happen, given that + * we already ran the string through + * MultiByteToWideChar() to find out how big + * a buffer we needed? + */ + free(utf16le_string); + errno = EINVAL; + return (NULL); + } + return (utf16le_string); +} + +char * +utf_16le_to_cp(UINT codepage, const wchar_t *utf16le_string) +{ + int cp_len; + char *cp_string; + + /* + * Map from UTF-16LE to the specified code page. + * First, find out how big a buffer we'll need. + * We convert composite characters to precomposed characters, + * as that's what Windows expects. + */ + cp_len = WideCharToMultiByte(codepage, WC_COMPOSITECHECK, + utf16le_string, -1, NULL, 0, NULL, NULL); + if (cp_len == 0) { + /* + * Error. Fail with EINVAL. + */ + errno = EINVAL; + return (NULL); + } + + /* + * Now attempt to allocate a buffer for that. + */ + cp_string = malloc(cp_len * sizeof (char)); + if (cp_string == NULL) { + /* + * Not enough memory; assume errno has been + * set, and fail. + */ + return (NULL); + } + + /* + * Now convert. + */ + cp_len = WideCharToMultiByte(codepage, WC_COMPOSITECHECK, + utf16le_string, -1, cp_string, cp_len, NULL, NULL); + if (cp_len == 0) { + /* + * Error. Fail with EINVAL. + * XXX - should this ever happen, given that + * we already ran the string through + * WideCharToMultiByte() to find out how big + * a buffer we needed? + */ + free(cp_string); + errno = EINVAL; + return (NULL); + } + return (cp_string); +} + +/* + * Convert an error message string from UTF-8 to the local code page, as + * best we can. + * + * The buffer is assumed to be PCAP_ERRBUF_SIZE bytes long; we truncate + * if it doesn't fit. + */ +void +utf_8_to_acp_truncated(char *errbuf) +{ + wchar_t *utf_16_errbuf; + int retval; + DWORD err; + + /* + * Do this by converting to UTF-16LE and then to the local + * code page. That means we get to use Microsoft's + * conversion routines, rather than having to understand + * all the code pages ourselves, *and* that this routine + * can convert in place. + */ + + /* + * Map from UTF-8 to UTF-16LE. + * First, find out how big a buffer we'll need. + * Convert any invalid characters to REPLACEMENT CHARACTER. + */ + utf_16_errbuf = cp_to_utf_16le(CP_UTF8, errbuf, 0); + if (utf_16_errbuf == NULL) { + /* + * Error. Give up. + */ + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "Can't convert error string to the local code page"); + return; + } + + /* + * Now, convert that to the local code page. + * Use the current thread's code page. For unconvertable + * characters, let it pick the "best fit" character. + * + * XXX - we'd like some way to do what utf_16le_to_utf_8_truncated() + * does if the buffer isn't big enough, but we don't want to have + * to handle all local code pages ourselves; doing so requires + * knowledge of all those code pages, including knowledge of how + * characters are formed in thoe code pages so that we can avoid + * cutting a multi-byte character into pieces. + * + * Converting to an un-truncated string using Windows APIs, and + * then copying to the buffer, still requires knowledge of how + * characters are formed in the target code page. + */ + retval = WideCharToMultiByte(CP_THREAD_ACP, 0, utf_16_errbuf, -1, + errbuf, PCAP_ERRBUF_SIZE, NULL, NULL); + if (retval == 0) { + err = GetLastError(); + free(utf_16_errbuf); + if (err == ERROR_INSUFFICIENT_BUFFER) + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "The error string, in the local code page, didn't fit in the buffer"); + else + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "Can't convert error string to the local code page"); + return; + } + free(utf_16_errbuf); +} +#endif diff --git a/external/bsd/libpcap/dist/charconv.h b/external/bsd/libpcap/dist/charconv.h new file mode 100644 index 000000000000..93103d461ef7 --- /dev/null +++ b/external/bsd/libpcap/dist/charconv.h @@ -0,0 +1,44 @@ +/* -*- 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 charconv_h +#define charconv_h + +#ifdef _WIN32 +extern wchar_t *cp_to_utf_16le(UINT codepage, const char *cp_string, DWORD flags); +extern char *utf_16le_to_cp(UINT codepage, const wchar_t *utf16le_string); +extern void utf_8_to_acp_truncated(char *); +#endif + +#endif /* charconv_h */ diff --git a/external/bsd/libpcap/dist/cmake/Modules/FindAirPcap.cmake b/external/bsd/libpcap/dist/cmake/Modules/FindAirPcap.cmake new file mode 100644 index 000000000000..56c71b7bf10d --- /dev/null +++ b/external/bsd/libpcap/dist/cmake/Modules/FindAirPcap.cmake @@ -0,0 +1,69 @@ +# +# FindAirPcap +# ========== +# +# Find the AirPcap library and include files. +# +# This module defines the following variables: +# +# AirPcap_INCLUDE_DIR - absolute path to the directory containing airpcap.h. +# +# AirPcap_LIBRARY - relative or absolute path to the AirPcap library to +# link with. An absolute path is will be used if the +# AirPcap library is not located in the compiler's +# default search path. + +# AirPcap_FOUND - TRUE if the AirPcap library *and* header are found. +# +# Hints and Backward Compatibility +# ================================ +# +# To tell this module where to look, a user may set the environment variable +# AirPcap_ROOT to point cmake to the *root* of a directory with include and +# lib subdirectories for airpcap.dll (e.g Airpcap_Devpack). +# Alternatively, AirPcap_ROOT may also be set from the CMake command +# line or GUI (e.g cmake -DAirPcap_ROOT=C:\path\to\airpcap_sdk [...]) +# + +# The 64-bit airpcap.lib is located under /x64 +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + # + # For the WinPcap and Npcap SDKs, the Lib subdirectory of the top-level + # directory contains 32-bit libraries; the 64-bit libraries are in the + # Lib/x64 directory. + # + # The only way to *FORCE* CMake to look in the Lib/x64 directory + # without searching in the Lib directory first appears to be to set + # CMAKE_LIBRARY_ARCHITECTURE to "x64". + # + # In newer versions of CMake, CMAKE_LIBRARY_ARCHITECTURE is set according to + # the language, e.g., CMAKE__LIBRARY_ARCHITECTURE. So, set the new + # variable, CMAKE_C_LIBRARY_ARCHITECTURE, so that CMAKE_LIBRARY_ARCHITECTURE + # inherits the correct value. + # + set(CMAKE_C_LIBRARY_ARCHITECTURE "x64") + set(CMAKE_LIBRARY_ARCHITECTURE "x64") +endif() + +# Find the header +find_path(AirPcap_INCLUDE_DIR airpcap.h + PATH_SUFFIXES include +) + +# Find the library +find_library(AirPcap_LIBRARY + NAMES airpcap +) + +# Set AirPcap_FOUND to TRUE if AirPcap_INCLUDE_DIR and AirPcap_LIBRARY are TRUE. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(AirPcap + DEFAULT_MSG + AirPcap_INCLUDE_DIR + AirPcap_LIBRARY +) + +mark_as_advanced(AirPcap_INCLUDE_DIR AirPcap_LIBRARY) + +set(AirPcap_INCLUDE_DIRS ${AirPcap_INCLUDE_DIR}) +set(AirPcap_LIBRARIES ${AirPcap_LIBRARY}) diff --git a/external/bsd/libpcap/dist/cmake/Modules/FindDAG.cmake b/external/bsd/libpcap/dist/cmake/Modules/FindDAG.cmake index ef1352844558..f41b90a24963 100644 --- a/external/bsd/libpcap/dist/cmake/Modules/FindDAG.cmake +++ b/external/bsd/libpcap/dist/cmake/Modules/FindDAG.cmake @@ -14,6 +14,12 @@ find_path(DAG_INCLUDE_DIR dagapi.h) find_library(DAG_LIBRARY dag) find_library(DAGCONF_LIBRARY dagconf) +# +# Get link information from the _LIBRARY paths. +# +get_link_info_from_library_path(DAG dag) +get_link_info_from_library_path(DAGCONF dagconf) + include(FindPackageHandleStandardArgs) find_package_handle_standard_args(DAG DEFAULT_MSG @@ -30,3 +36,4 @@ mark_as_advanced( set(DAG_INCLUDE_DIRS ${DAG_INCLUDE_DIR}) set(DAG_LIBRARIES ${DAG_LIBRARY} ${DAGCONF_LIBRARY}) +set(DAG_STATIC_LIBRARIES ${DAG_LIBRARY} ${DAGCONF_LIBRARY}) diff --git a/external/bsd/libpcap/dist/cmake/Modules/FindPacket.cmake b/external/bsd/libpcap/dist/cmake/Modules/FindPacket.cmake index f114875bf873..8224cd3f3e5c 100644 --- a/external/bsd/libpcap/dist/cmake/Modules/FindPacket.cmake +++ b/external/bsd/libpcap/dist/cmake/Modules/FindPacket.cmake @@ -28,24 +28,23 @@ # # This module defines the following variables: # -# PACKET_INCLUDE_DIR - absolute path to the directory containing Packet32.h. +# Packet_INCLUDE_DIR - absolute path to the directory containing Packet32.h. # -# PACKET_LIBRARY - relative or absolute path to the Packet library to +# 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. +# default search path. -# PACKET_FOUND - TRUE if the Packet library *and* header are found. +# 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 [...]) +# Packet_ROOT to point cmake to the *root* of a directory with include and +# lib subdirectories for packet.dll (e.g WpdPack or npcap-sdk). +# Alternatively, Packet_ROOT may also be set from cmake command line or GUI +# (e.g cmake -DPacket_ROOT=C:\path\to\packet [...]) # # The 64-bit Packet.lib is located under /x64 @@ -59,30 +58,52 @@ if(CMAKE_SIZEOF_VOID_P EQUAL 8) # without searching in the Lib directory first appears to be to set # CMAKE_LIBRARY_ARCHITECTURE to "x64". # - set(CMAKE_LIBRARY_ARCHITECTURE "x64") + # In newer versions of CMake, CMAKE_LIBRARY_ARCHITECTURE is set according to + # the language, e.g., CMAKE__LIBRARY_ARCHITECTURE. So, set the new + # variable, CMAKE_C_LIBRARY_ARCHITECTURE, so that CMAKE_LIBRARY_ARCHITECTURE + # inherits the correct value. + # + set(archdetect_c_code " + #ifndef _M_ARM64 + #error Not ARM64 + #endif + int main() { return 0; } + ") + + file(WRITE "${CMAKE_BINARY_DIR}/archdetect.c" "${archdetect_c_code}") + try_compile( + IsArm64 + "${CMAKE_BINARY_DIR}/archdetect" + "${CMAKE_BINARY_DIR}/archdetect.c" + ) + if(IsArm64) + set(CMAKE_C_LIBRARY_ARCHITECTURE "ARM64") + set(CMAKE_LIBRARY_ARCHITECTURE "ARM64") + else() + set(CMAKE_C_LIBRARY_ARCHITECTURE "x64") + set(CMAKE_LIBRARY_ARCHITECTURE "x64") + endif() endif() # Find the header -find_path(PACKET_INCLUDE_DIR Packet32.h - HINTS "${PACKET_DLL_DIR}" ENV PACKET_DLL_DIR +find_path(Packet_INCLUDE_DIR Packet32.h PATH_SUFFIXES include Include ) # Find the library -find_library(PACKET_LIBRARY +find_library(Packet_LIBRARY NAMES Packet packet - HINTS "${PACKET_DLL_DIR}" ENV PACKET_DLL_DIR ) -# Set PACKET_FOUND to TRUE if PACKET_INCLUDE_DIR and PACKET_LIBRARY are TRUE. +# Set Packet_FOUND to TRUE if Packet_INCLUDE_DIR and Packet_LIBRARY are TRUE. include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(PACKET +find_package_handle_standard_args(Packet DEFAULT_MSG - PACKET_INCLUDE_DIR - PACKET_LIBRARY + Packet_INCLUDE_DIR + Packet_LIBRARY ) -mark_as_advanced(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}) +set(Packet_INCLUDE_DIRS ${Packet_INCLUDE_DIR}) +set(Packet_LIBRARIES ${Packet_LIBRARY}) diff --git a/external/bsd/libpcap/dist/cmake/Modules/FindSNF.cmake b/external/bsd/libpcap/dist/cmake/Modules/FindSNF.cmake index 76dcced417fe..d873b5aa74f8 100644 --- a/external/bsd/libpcap/dist/cmake/Modules/FindSNF.cmake +++ b/external/bsd/libpcap/dist/cmake/Modules/FindSNF.cmake @@ -8,6 +8,11 @@ find_path(SNF_INCLUDE_DIR snf.h /opt/snf) # Try to find the library find_library(SNF_LIBRARY snf /opt/snf) +# +# Get link information from the _LIBRARY paths. +# +get_link_info_from_library_path(SNF snf) + include(FindPackageHandleStandardArgs) find_package_handle_standard_args(SNF DEFAULT_MSG @@ -22,3 +27,4 @@ mark_as_advanced( set(SNF_INCLUDE_DIRS ${SNF_INCLUDE_DIR}) set(SNF_LIBRARIES ${SNF_LIBRARY}) +set(SNF_STATIC_LIBRARIES ${SNF_LIBRARY}) diff --git a/external/bsd/libpcap/dist/cmake/Modules/Finddpdk.cmake b/external/bsd/libpcap/dist/cmake/Modules/Finddpdk.cmake new file mode 100644 index 000000000000..323262afa642 --- /dev/null +++ b/external/bsd/libpcap/dist/cmake/Modules/Finddpdk.cmake @@ -0,0 +1,118 @@ +# Try to find dpdk +# +# Once done, this will define +# +# dpdk_FOUND +# dpdk_INCLUDE_DIRS +# dpdk_LIBRARIES +# dpdk_STATIC_LIBRARIES +# dpdk_LIBS_STATIC +# dpdk_REQUIRES_PRIVATE +# dpdk_PACKAGE_NAME + +# +# We only try to find DPDK using pkg-config; DPDK is *SO* +# complicated - DPDK 19.02, for example, has about 117(!) +# libraries, and the precise set of libraries required has +# changed over time - so attempting to guess which libraries +# you need, and hardcoding that in an attempt to find the +# libraries without DPDK, rather than relying on DPDK to +# tell you, with a .pc file, what libraries are needed, +# is *EXTREMELY* fragile and has caused some bug reports, +# so we're just not going to do it. +# +# If that causes a problem, the only thing we will do is +# accept an alternative way of finding the appropriate +# library set for the installed version of DPDK that is +# as robust as pkg-config (i.e., it had better work as well +# as pkg-config with *ALL* versions of DPDK that provide a +# libdpdk.pc file). +# +# If dpdk_ROOT is set, add ${dpdk_ROOT}/pkgconfig +# to PKG_CONFIG_PATH, so we look for the .pc file there, +# first. +# +if(PKG_CONFIG_FOUND) + set(save_PKG_CONFIG_PATH $ENV{PKG_CONFIG_PATH}) + if(dpdk_ROOT) + set(ENV{PKG_CONFIG_PATH} "${dpdk_ROOT}/pkgconfig:$ENV{PKG_CONFIG_PATH}") + endif() + pkg_check_modules(dpdk QUIET libdpdk) + if(dpdk_FOUND) + # + # Get link information for DPDK. + # + pkg_get_link_info(dpdk libdpdk) + endif() + set(ENV{PKG_CONFIG_PATH} "${save_PKG_CONFIG_PATH}") +endif() + +mark_as_advanced(dpdk_INCLUDE_DIRS dpdk_LIBRARIES dpdk_STATIC_LIBRARIES dpdk_REQUIRES_PRIVATE) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(dpdk DEFAULT_MSG + dpdk_INCLUDE_DIRS + dpdk_LIBRARIES) + +if(dpdk_FOUND) + # + # This depends on CMake support for "imported targets", + # which are not supported until CMake 3.19. + # + # Ubuntu 20.04 provides CMake 3.16.3, so we are *NOT* + # going to require CMake 3.19. If you want to use + # Shiny New Features(TM), wait until all the OSes on + # which a build might conceivably be done, and that + # provide CMake, provide 3.19 or later. + # + # Just don't do this stuff on earlier versions. If that + # breaks something, figure out a way to do it *without* + # "imported targets", and either do this that way, or, + # at least, do it that way on older versions of CMake. + # + # (One good thing about autotools is that only the builders + # of a package, and people doing configure-script development, + # have to care about the autoconf etc. version; you don't + # even need to have autotools installed in order to be able + # to run an autotools-generated configure script, you just + # need an environment UN*Xy enough, and modern enough, to + # run the stuff in the script. + # + # This is *NOT* the case for CMake; not only do you need + # CMake in order to build a package using CMake, you need + # a version recent enough to run the stuff the package's + # CMake files use. + # + # Please keep this in mind when changing any CMake files, + # and keep in mind what versions of CMake come with, for + # example, commonly-used versions of commonly-used + # Linux distributiions.) + # + if(NOT CMAKE_VERSION VERSION_LESS 3.19) + if(NOT TARGET dpdk::cflags) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64|x86_64|AMD64") + set(rte_cflags "-march=core2") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm|ARM") + set(rte_cflags "-march=armv7-a") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|AARCH64") + set(rte_cflags "-march=armv8-a+crc") + endif() + add_library(dpdk::cflags INTERFACE IMPORTED) + if (rte_cflags) + set_target_properties(dpdk::cflags PROPERTIES + INTERFACE_COMPILE_OPTIONS "${rte_cflags}") + endif() + endif() + + if(NOT TARGET dpdk::dpdk) + add_library(dpdk::dpdk INTERFACE IMPORTED) + find_package(Threads QUIET) + list(APPEND dpdk_LIBRARIES + Threads::Threads + dpdk::cflags) + set_target_properties(dpdk::dpdk PROPERTIES + INTERFACE_LINK_LIBRARIES "${dpdk_LIBRARIES}" + INTERFACE_INCLUDE_DIRECTORIES "${dpdk_INCLUDE_DIRS}") + endif() + endif() +endif() diff --git a/external/bsd/libpcap/dist/cmakeconfig.h.in b/external/bsd/libpcap/dist/cmakeconfig.h.in index 1639925e35d6..4ac85cc5303a 100644 --- a/external/bsd/libpcap/dist/cmakeconfig.h.in +++ b/external/bsd/libpcap/dist/cmakeconfig.h.in @@ -15,9 +15,15 @@ /* define if we have the AIX getprotobyname_r() */ #cmakedefine HAVE_AIX_GETPROTOBYNAME_R 1 +/* define if you have the AirPcap API */ +#cmakedefine HAVE_AIRPCAP_API 1 + /* Define to 1 if you have the `asprintf' function. */ #cmakedefine HAVE_ASPRINTF 1 +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_CONFIG_HAIKUCONFIG_H 1 + /* define if you have the DAG API */ #cmakedefine HAVE_DAG_API 1 @@ -69,45 +75,21 @@ /* if libnl exists */ #cmakedefine HAVE_LIBNL 1 -/* if libnl exists and is version 2.x */ -#cmakedefine HAVE_LIBNL_2_x 1 - -/* if libnl exists and is version 3.x */ -#cmakedefine HAVE_LIBNL_3_x 1 - -/* libnl has NLE_FAILURE */ -#cmakedefine HAVE_LIBNL_NLE 1 - -/* libnl has new-style socket api */ -#cmakedefine HAVE_LIBNL_SOCKETS 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LIMITS_H 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_LINUX_COMPILER_H 1 -/* Define to 1 if you have the 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 header file. */ -#cmakedefine HAVE_LINUX_IF_BONDING_H 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_LINUX_NET_TSTAMP_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_LINUX_SOCKET_H 1 -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LINUX_SOCKIOS_H 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_LINUX_USBDEVICE_FS_H 1 @@ -135,12 +117,12 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_NET_PFILT_H 1 -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NET_PFVAR_H 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_NET_RAW_H 1 +/* Use OpenSSL */ +#cmakedefine HAVE_OPENSSL 1 + /* if there's an os_proto.h for this platform, to use additional prototypes */ #cmakedefine HAVE_OS_PROTO_H 1 @@ -153,9 +135,6 @@ /* Define to 1 if you have a POSIX-style `strerror_r' function. */ #cmakedefine HAVE_POSIX_STRERROR_R 1 -/* define if net/pfvar.h defines PF_NAT through PF_NORDR */ -#cmakedefine HAVE_PF_NAT_THROUGH_PF_NORDR 1 - /* define if you have the Septel API */ #cmakedefine HAVE_SEPTEL_API 1 @@ -186,9 +165,6 @@ /* Define to 1 if you have the `strerror' function. */ #cmakedefine HAVE_STRERROR 1 -/* Define to 1 if you have the `strerror_s' function. */ -#cmakedefine HAVE_STRERROR_S 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STRINGS_H 1 @@ -216,6 +192,9 @@ /* Define to 1 if `msg_flags' is a member of `struct msghdr'. */ #cmakedefine HAVE_STRUCT_MSGHDR_MSG_FLAGS 1 +/* Define to 1 if the system has the type `struct rte_ether_addr'. */ +#cmakedefine HAVE_STRUCT_RTE_ETHER_ADDR 1 + /* Define to 1 if `hci_channel' is a member of `struct sockaddr_hci'. */ #cmakedefine HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL 1 @@ -228,9 +207,6 @@ /* 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 @@ -272,7 +248,19 @@ #cmakedefine HAVE_VSNPRINTF 1 /* Define to 1 if you have the `vsyslog' function. */ -#undef HAVE_VSYSLOG +#cmakedefine HAVE_VSYSLOG 1 + +/* Define to 1 if you have the `_wcserror_s' function. */ +#cmakedefine HAVE__WCSERROR_S 1 + +/* define if __atomic_load_n is supported by the compiler */ +#cmakedefine HAVE___ATOMIC_LOAD_N 1 + +/* define if __atomic_store_n is supported by the compiler */ +#cmakedefine HAVE___ATOMIC_STORE_N 1 + +/* Define to 1 if you have the `PacketGetTimestampModes' function. */ +#cmakedefine HAVE_PACKET_GET_TIMESTAMP_MODES 1 /* Define to 1 if you have the `PacketIsLoopbackAdapter' function. */ #cmakedefine HAVE_PACKET_IS_LOOPBACK_ADAPTER 1 @@ -280,12 +268,6 @@ /* IPv6 */ #cmakedefine INET6 1 -/* if unaligned access fails */ -#cmakedefine LBL_ALIGN 1 - -/* path for device for USB sniffing */ -#cmakedefine LINUX_USB_MON_DEV "@LINUX_USB_MON_DEV@" - /* Define to 1 if netinet/ether.h declares `ether_hostton' */ #cmakedefine NETINET_ETHER_H_DECLARES_ETHER_HOSTTON 1 @@ -301,7 +283,7 @@ /* 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. */ +/* Define to the DLL-preferred version string of this package. */ #cmakedefine PACKAGE_VERSION_DLL @PACKAGE_VERSION_DLL@ /* Define to the full name of this package. */ @@ -328,24 +310,21 @@ /* support D-Bus sniffing */ #cmakedefine PCAP_SUPPORT_DBUS 1 +/* target host supports DPDK */ +#cmakedefine PCAP_SUPPORT_DPDK 1 + +/* target host supports Linux usbmon for USB sniffing */ +#cmakedefine PCAP_SUPPORT_LINUX_USBMON 1 + /* target host supports netfilter sniffing */ #cmakedefine PCAP_SUPPORT_NETFILTER 1 /* target host supports netmap */ #cmakedefine PCAP_SUPPORT_NETMAP 1 -/* use packet ring capture support on Linux if available */ -#cmakedefine PCAP_SUPPORT_PACKET_RING 1 - /* target host supports RDMA sniffing */ #cmakedefine PCAP_SUPPORT_RDMASNIFF 1 -/* target host supports USB sniffing */ -#cmakedefine PCAP_SUPPORT_USB 1 - -/* include ACN support */ -#cmakedefine SITA 1 - /* Define to 1 if you have the ANSI C header files. */ #cmakedefine STDC_HEADERS 1 diff --git a/external/bsd/libpcap/dist/config.h.in b/external/bsd/libpcap/dist/config.h.in index 94db7bbc4177..282a95591b7d 100644 --- a/external/bsd/libpcap/dist/config.h.in +++ b/external/bsd/libpcap/dist/config.h.in @@ -18,6 +18,9 @@ /* Define to 1 if you have the `asprintf' function. */ #undef HAVE_ASPRINTF +/* Define to 1 if you have the header file. */ +#undef HAVE_CONFIG_HAIKUCONFIG_H + /* Define to 1 if you have the header file. */ #undef HAVE_DAGAPI_H @@ -69,8 +72,8 @@ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H -/* Define to 1 if you have the `dag' library (-ldag). */ -#undef HAVE_LIBDAG +/* Define to 1 if you have the `bsd' library (-lbsd). */ +#undef HAVE_LIBBSD /* if libdlpi exists */ #undef HAVE_LIBDLPI @@ -78,45 +81,21 @@ /* if libnl exists */ #undef HAVE_LIBNL -/* if libnl exists and is version 2.x */ -#undef HAVE_LIBNL_2_x - -/* if libnl exists and is version 3.x */ -#undef HAVE_LIBNL_3_x - -/* libnl has NLE_FAILURE */ -#undef HAVE_LIBNL_NLE - -/* libnl has new-style socket api */ -#undef HAVE_LIBNL_SOCKETS - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIMITS_H - /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_COMPILER_H -/* Define to 1 if you have the 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 header file. */ -#undef HAVE_LINUX_IF_BONDING_H - /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_NET_TSTAMP_H /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_SOCKET_H -/* Define to 1 if you have the header file. */ -#undef HAVE_LINUX_SOCKIOS_H - /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_USBDEVICE_FS_H @@ -135,27 +114,33 @@ /* Define to 1 if you have the header file. */ #undef HAVE_NET_ENET_H +/* Define to 1 if you have the header file. */ +#undef HAVE_NET_IF_DL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NET_IF_H + /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_MEDIA_H +/* Define to 1 if you have the header file. */ +#undef HAVE_NET_IF_TYPES_H + /* Define to 1 if you have the header file. */ #undef HAVE_NET_NIT_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_PFILT_H -/* Define to 1 if you have the header file. */ -#undef HAVE_NET_PFVAR_H - /* Define to 1 if you have the header file. */ #undef HAVE_NET_RAW_H +/* Use OpenSSL */ +#undef HAVE_OPENSSL + /* if there's an os_proto.h for this platform, to use additional prototypes */ #undef HAVE_OS_PROTO_H -/* define if net/pfvar.h defines PF_NAT through PF_NORDR */ -#undef HAVE_PF_NAT_THROUGH_PF_NORDR - /* Define to 1 if you have a POSIX-style `strerror_r' function. */ #undef HAVE_POSIX_STRERROR_R @@ -165,9 +150,6 @@ /* define if you have the Myricom SNF API */ #undef HAVE_SNF_API -/* Define to 1 if you have the `snprintf' function. */ -#undef HAVE_SNPRINTF - /* Define to 1 if the system has the type `socklen_t'. */ #undef HAVE_SOCKLEN_T @@ -189,9 +171,6 @@ /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR -/* Define to 1 if you have the `strerror_s' function. */ -#undef HAVE_STRERROR_S - /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H @@ -219,6 +198,9 @@ /* Define to 1 if `msg_flags' is a member of `struct msghdr'. */ #undef HAVE_STRUCT_MSGHDR_MSG_FLAGS +/* Define to 1 if the system has the type `struct rte_ether_addr'. */ +#undef HAVE_STRUCT_RTE_ETHER_ADDR + /* Define to 1 if `hci_channel' is a member of `struct sockaddr_hci'. */ #undef HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL @@ -231,9 +213,6 @@ /* 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 @@ -271,20 +250,20 @@ /* Define to 1 if you have the `vasprintf' function. */ #undef HAVE_VASPRINTF -/* Define to 1 if you have the `vsnprintf' function. */ -#undef HAVE_VSNPRINTF - /* Define to 1 if you have the `vsyslog' function. */ #undef HAVE_VSYSLOG -/* IPv6 */ -#undef INET6 +/* Define to 1 if you have the `_wcserror_s' function. */ +#undef HAVE__WCSERROR_S + +/* define if __atomic_load_n is supported by the compiler */ +#undef HAVE___ATOMIC_LOAD_N -/* if unaligned access fails */ -#undef LBL_ALIGN +/* define if __atomic_store_n is supported by the compiler */ +#undef HAVE___ATOMIC_STORE_N -/* path for device for USB sniffing */ -#undef LINUX_USB_MON_DEV +/* IPv6 */ +#undef INET6 /* Define to 1 if netinet/ether.h declares `ether_hostton' */ #undef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON @@ -325,23 +304,26 @@ /* support D-Bus sniffing */ #undef PCAP_SUPPORT_DBUS +/* target host supports DPDK */ +#undef PCAP_SUPPORT_DPDK + +/* target host supports Linux usbmon for USB sniffing */ +#undef PCAP_SUPPORT_LINUX_USBMON + /* target host supports netfilter sniffing */ #undef PCAP_SUPPORT_NETFILTER /* 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 +/* The size of `const void *', as computed by sizeof. */ +#undef SIZEOF_CONST_VOID_P -/* include ACN support */ -#undef SITA +/* The size of `void *', as computed by sizeof. */ +#undef SIZEOF_VOID_P /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS diff --git a/external/bsd/libpcap/dist/configure b/external/bsd/libpcap/dist/configure index fa15fc7314eb..4f8fd5ac4a96 100755 --- a/external/bsd/libpcap/dist/configure +++ b/external/bsd/libpcap/dist/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for pcap 1.9.1. +# Generated by GNU Autoconf 2.69 for pcap 1.10.4. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -577,8 +577,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='pcap' PACKAGE_TARNAME='pcap' -PACKAGE_VERSION='1.9.1' -PACKAGE_STRING='pcap 1.9.1' +PACKAGE_VERSION='1.10.4' +PACKAGE_STRING='pcap 1.10.4' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -620,65 +620,74 @@ ac_includes_default="\ #endif" ac_subst_vars='LTLIBOBJS +RPCAPD_LIBS +INSTALL_RPCAPD +BUILD_RPCAPD +PTHREAD_LIBS +REMOTE_C_SRC +MODULE_C_SRC +PLATFORM_CXX_SRC +PLATFORM_C_SRC +ADDLARCHIVEOBJS +ADDLOBJS +RPATH +V_SONAME_OPT +V_SHLIB_OPT +V_SHLIB_CMD +V_SHLIB_CCOPT INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM -RDMA_SRC PCAP_SUPPORT_RDMASNIFF -DBUS_SRC +LIBIBVERBS_LIBS_STATIC +LIBIBVERBS_LIBS +LIBIBVERBS_CFLAGS PCAP_SUPPORT_DBUS -PKGCONFIG -BT_MONITOR_SRC -BT_SRC +DBUS_LIBS_STATIC +DBUS_LIBS +DBUS_CFLAGS PCAP_SUPPORT_BT -NETMAP_SRC +PCAP_SUPPORT_DPDK +DPDK_LIBS_STATIC +DPDK_LIBS +DPDK_CFLAGS PCAP_SUPPORT_NETMAP -NETFILTER_SRC PCAP_SUPPORT_NETFILTER -USB_SRC -PCAP_SUPPORT_USB -EXTRA_NETWORK_LIBS -RPCAPD_LIBS -INSTALL_RPCAPD -BUILD_RPCAPD -PTHREAD_LIBS +PCAP_SUPPORT_LINUX_USBMON +MKDEP +DEPENDENCY_CFLAG +LN_S +AR +RANLIB MAN_ADMIN_COMMANDS MAN_MISC_INFO MAN_FILE_FORMATS MAN_DEVICES DYEXT -SSRC -ADDLARCHIVEOBJS -ADDLOBJS -V_YACC -V_RPATH_OPT -V_SONAME_OPT -V_SHLIB_OPT -V_SHLIB_CMD -V_SHLIB_CCOPT -V_PCAP -V_LEX -V_INCLS -V_FINDALLDEVS -V_DEFS V_PROG_LDFLAGS_FAT V_PROG_CCOPT_FAT V_LIB_LDFLAGS_FAT V_LIB_CCOPT_FAT -V_CCOPT -MKDEP -DEPENDENCY_CFLAG -LN_S -AR -RANLIB -YFLAGS -YACC +REENTRANT_PARSER +BISON_BYACC LEXLIB LEX_OUTPUT_ROOT LEX -PCAP_SUPPORT_PACKET_RING +OPENSSL_LIBS_STATIC +OPENSSL_LIBS +OPENSSL_CFLAGS +LIBNL_LIBS_STATIC +LIBNL_LIBS +LIBNL_CFLAGS +BREW +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG VALGRINDTEST_SRC LIBOBJS +ac_ct_CXX +CXXFLAGS +CXX EGREP GREP CPP @@ -702,6 +711,12 @@ build_os build_vendor build_cpu build +LIBS_PRIVATE +REQUIRES_PRIVATE +LIBS_STATIC +V_INCLS +V_DEFS +V_CCOPT target_alias host_alias build_alias @@ -721,7 +736,6 @@ infodir docdir oldincludedir includedir -runstatedir localstatedir sharedstatedir sysconfdir @@ -747,10 +761,8 @@ enable_option_checking with_gcc enable_largefile enable_protochain -with_sita with_pcap with_libnl -enable_packet_ring enable_ipv6 with_dag with_dag_includes @@ -767,6 +779,7 @@ enable_universal enable_shared enable_usb enable_netmap +with_dpdk enable_bluetooth enable_dbus enable_rdma @@ -780,8 +793,27 @@ LDFLAGS LIBS CPPFLAGS CPP -YACC -YFLAGS' +CXX +CXXFLAGS +CCC +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +LIBNL_CFLAGS +LIBNL_LIBS +LIBNL_LIBS_STATIC +OPENSSL_CFLAGS +OPENSSL_LIBS +OPENSSL_LIBS_STATIC +DPDK_CFLAGS +DPDK_LIBS +DPDK_LIBS_STATIC +DBUS_CFLAGS +DBUS_LIBS +DBUS_LIBS_STATIC +LIBIBVERBS_CFLAGS +LIBIBVERBS_LIBS +LIBIBVERBS_LIBS_STATIC' # Initialize some variables set by options. @@ -820,7 +852,6 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1073,15 +1104,6 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) - ac_prev=runstatedir ;; - -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ - | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ - | --run=* | --ru=* | --r=*) - runstatedir=$ac_optarg ;; - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1219,7 +1241,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir + libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1332,7 +1354,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 pcap 1.9.1 to adapt to many kinds of systems. +\`configure' configures pcap 1.10.4 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1372,7 +1394,6 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1399,7 +1420,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of pcap 1.9.1:";; + short | recursive ) echo "Configuration of pcap 1.10.4:";; esac cat <<\_ACEOF @@ -1409,17 +1430,15 @@ Optional Features: --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-largefile omit support for large files --disable-protochain disable \"protochain\" insn - --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 macOS --enable-shared build shared libraries [default=yes, if support available] - --enable-usb enable USB capture support [default=yes, if support - available] + --enable-usb enable Linux usbmon 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 @@ -1433,7 +1452,6 @@ Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --without-gcc don't use gcc - --with-sita include SITA support --with-pcap=TYPE use packet capture TYPE --without-libnl disable libnl support [default=yes, on Linux, if present] @@ -1454,6 +1472,8 @@ Optional Packages: --with-turbocap[=DIR] include Riverbed TurboCap support (located in directory DIR, if supplied). [default=yes, if present] + --with-dpdk[=DIR] include DPDK support (located in directory DIR, if + supplied). [default=yes, if present] Some influential environment variables: CC C compiler command @@ -1464,12 +1484,39 @@ Some influential environment variables: CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor - YACC The `Yet Another Compiler Compiler' implementation to use. - Defaults to the first program found out of: `bison -y', `byacc', - `yacc'. - YFLAGS The list of arguments that will be passed by default to $YACC. - This script will default YFLAGS to the empty string to avoid a - default value of `-d' given by some make applications. + CXX C++ compiler command + CXXFLAGS C++ compiler flags + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + LIBNL_CFLAGS + C compiler flags for libnl-genl-3.0, overriding pkg-config + LIBNL_LIBS linker flags for libnl-genl-3.0, overriding pkg-config + LIBNL_LIBS_STATIC + static-link linker flags for libnl-genl-3.0, overriding + pkg-config + OPENSSL_CFLAGS + C compiler flags for openssl, overriding pkg-config + OPENSSL_LIBS + linker flags for openssl, overriding pkg-config + OPENSSL_LIBS_STATIC + static-link linker flags for openssl, overriding pkg-config + DPDK_CFLAGS C compiler flags for libdpdk, overriding pkg-config + DPDK_LIBS linker flags for libdpdk, overriding pkg-config + DPDK_LIBS_STATIC + static-link linker flags for libdpdk, overriding pkg-config + DBUS_CFLAGS C compiler flags for dbus-1, overriding pkg-config + DBUS_LIBS linker flags for dbus-1, overriding pkg-config + DBUS_LIBS_STATIC + static-link linker flags for dbus-1, overriding pkg-config + LIBIBVERBS_CFLAGS + C compiler flags for libibverbs, overriding pkg-config + LIBIBVERBS_LIBS + linker flags for libibverbs, overriding pkg-config + LIBIBVERBS_LIBS_STATIC + static-link linker flags for libibverbs, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -1537,7 +1584,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -pcap configure 1.9.1 +pcap configure 1.10.4 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1589,13 +1636,13 @@ 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 () +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () { 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;; @@ -1603,37 +1650,216 @@ case "(($ac_try" in 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 + (eval "$ac_link") 2>&5 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 : + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { 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_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : ac_retval=0 else - $as_echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - ac_retval=1 + ac_retval=$ac_status 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_run + +# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES +# -------------------------------------------- +# Tries to find the compile-time value of EXPR in a program that includes +# INCLUDES, setting VAR accordingly. Returns whether the value could be +# computed +ac_fn_c_compute_int () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=0 ac_mid=0 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid; break +else + as_fn_arith $ac_mid + 1 && ac_lo=$as_val + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) < 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=-1 ac_mid=-1 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=$ac_mid; break +else + as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + ac_lo= ac_hi= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid +else + as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in #(( +?*) eval "$3=\$ac_lo"; ac_retval=0 ;; +'') ac_retval=1 ;; +esac + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +static long int longval () { return $2; } +static unsigned long int ulongval () { return $2; } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (($2) < 0) + { + long int i = longval (); + if (i != ($2)) + return 1; + fprintf (f, "%ld", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ($2)) + return 1; + fprintf (f, "%lu", i); + } + /* Do not output a trailing newline, as this causes \r\n confusion + on some platforms. */ + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + echo >>conftest.val; read $3 &5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } else - # Is the header compilable? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 -$as_echo_n "checking $2 usability... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - ac_header_compiler=yes + eval "$3=yes" else - ac_header_compiler=no + eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 -$as_echo_n "checking $2 presence... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <$2> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - ac_header_preproc=yes -else - ac_header_preproc=no fi -rm -f conftest.err conftest.i conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } +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 -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( - yes:no: ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; - no:yes:* ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; +} # ac_fn_c_check_header_compile + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; esac - { $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 +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 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_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 else - eval "$3=\$ac_header_compiler" -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval -} # ac_fn_c_check_header_mongrel +} # ac_fn_cxx_try_compile -# ac_fn_c_try_run LINENO -# ---------------------- +# ac_fn_cxx_try_run LINENO +# ------------------------ # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. -ac_fn_c_try_run () +ac_fn_cxx_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" @@ -1799,38 +2007,277 @@ fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval -} # ac_fn_c_try_run +} # ac_fn_cxx_try_run -# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ac_fn_cxx_compute_int LINENO EXPR VAR INCLUDES +# ---------------------------------------------- +# Tries to find the compile-time value of EXPR in a program that includes +# INCLUDES, setting VAR accordingly. Returns whether the value could be +# computed +ac_fn_cxx_compute_int () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_lo=0 ac_mid=0 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_hi=$ac_mid; break +else + as_fn_arith $ac_mid + 1 && ac_lo=$as_val + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) < 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_hi=-1 ac_mid=-1 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_lo=$ac_mid; break +else + as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + ac_lo= ac_hi= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_hi=$ac_mid +else + as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in #(( +?*) eval "$3=\$ac_lo"; ac_retval=0 ;; +'') ac_retval=1 ;; +esac + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +static long int longval () { return $2; } +static unsigned long int ulongval () { return $2; } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (($2) < 0) + { + long int i = longval (); + if (i != ($2)) + return 1; + fprintf (f, "%ld", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ($2)) + return 1; + fprintf (f, "%lu", i); + } + /* Do not output a trailing newline, as this causes \r\n confusion + on some platforms. */ + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_run "$LINENO"; then : + echo >>conftest.val; read $3 &5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" + ac_header_compiler=yes else - eval "$3=no" + ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $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=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } +fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno -} # ac_fn_c_check_header_compile +} # ac_fn_c_check_header_mongrel # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- @@ -2059,7 +2506,7 @@ 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 pcap $as_me 1.9.1, which was +It was created by pcap $as_me 1.10.4, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2410,6 +2857,86 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu +# +# These are the variables that are used in Makefile, pcap-config, and +# libpcap.pc. +# +# CFLAGS: inherited from the environment, not modified by us (except +# temporarily during tests that involve compilation). Used only when +# compiling C source. +# +# CXXFLAGS: inherited from the environment, not modified by us. Used only +# when compiling C++ source. +# +# LDFLAGS: inherited from the environment, not modified by us. +# +# LIBS: inherited from the environment; we add libraries required by +# libpcap. Librares that the core libpcap code requires are added +# first; libraries required by additional pcap modules are first +# added to ADDITIONAL_LIBS, and only added to LIBS at the end, after +# we're finished doing configuration tests for the modules. +# +# LIBS_STATIC: libraries with which a program using the libpcap *static* +# library needs to be linked. This is a superset of LIBS, used in +# pcap-config, so that "pcap-config --libs --static" will report them. +# Initialized to LIBS. +# +# REQUIRES_PRIVATE: pkg-config package names for additional libraries +# with which a program using the libpcap *static* library needs to be +# linked and for which a .pc file exists. This is used in libpcap.pc, +# so that "pkg-config --libs --static" will report them, and so that +# those libraries will be determined using the library's .pc file, not +# from our .pc file. Initialized to an empty string. +# +# V_CCOPT: additional compiler flags other than -I and -D flags +# needed when compiling libpcap. Used in Makefile for both C and +# C++ source. +# +# V_DEFS: additional -D compiler flags needed when compiling +# libpcap. Used in Makefile for both C and C++ source. +# +# V_INCLS: additional -I compiler flags needed when compiling +# libpcap. Used in Makefile for both C and C++ source. +# +# ADDITIONAL_LIBS: additional libraries with which the libpcap dynamic +# library needs to be linked. Used in Makwfile; not used in pcap-config +# or libpcap.pc, as, in all platforms on which we run, if a dynamic +# library is linked with other dynamic libraries, a program using +# that dynamic library doesn't have to link with those libraries - +# they will be automatically loaded at run time. Initialized to an +# empty string. +# +# ADDITIONAL_LIBS_STATIC: additional libraries with which a program +# using the libpcap *static* library needs to be linked. This is used +# in pcap-config, so that "pcap-config --libs --static" will report +# them. Initialized to an empty string. +# +# REQUIRES_PRIVATE: pkg-config package names for additional libraries +# with which a program using the libpcap *static* library needs to be +# linked and for which a .pc file exists. This is used in libpcap.pc, +# so that "pkg-config --libs --static" will report them, and so that +# those libraries will be determined using the library's .pc file, not +# from our .pc file. Initialized to an empty string. +# +# LIBS_PRIVATE: pkg-config package names for additional libraries with +# which a program using the libpcap *static* library needs to be linked +# and for which a .pc file does not exist. This is used in libpcap.pc, +# so that "pkg-config --libs --static" will report them (those libraries +# cannot be determined using the library's .pc file, as there is no such +# file, so it has to come from our .pc file. Initialized to an empty +# string. +# +LIBS_STATIC="" +REQUIRES_PRIVATE="" +LIBS_PRIVATE="" + + + + + + + + ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then @@ -2624,8 +3151,9 @@ fi fi # -# Try to enable as many C99 features as we can. -# At minimum, we want C++/C99-style // comments. +# We require C99 or later. +# Try to get it, which may involve adding compiler flags; +# if that fails, give up. # ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -3594,14 +4122,784 @@ fi if test "$ac_cv_prog_cc_c99" = "no"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: The C compiler does not support C99; there may be compiler errors" >&5 -$as_echo "$as_me: WARNING: The C compiler does not support C99; there may be compiler errors" >&2;} + as_fn_error $? "The C compiler does not support C99" "$LINENO" 5 fi +# +# Get the size of a void *, to determine whether this is a 32-bit +# or 64-bit build. +# + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +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 how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +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 grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$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 + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5 +$as_echo_n "checking size of void *... " >&6; } +if ${ac_cv_sizeof_void_p+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_void_p" = yes; 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 77 "cannot compute sizeof (void *) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_void_p=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 +$as_echo "$ac_cv_sizeof_void_p" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_VOID_P $ac_cv_sizeof_void_p +_ACEOF + + +ac_lbl_c_sizeof_void_p="$ac_cv_sizeof_void_p" + +# +# We only need a C++ compiler for Haiku; all code except for its +# pcap module is in C. +# +case "$host_os" in +haiku*) + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +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_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=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 +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +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 + + + # + # Make sure C and C++ have the same pointer sizes with the flags + # they're given; if they don't, it means that the compilers for the + # languages will, with those flags, not produce code that can be + # linked together. + # + # We have to use different data types, because the results of + # a test are cached, so if we test for the size of a given type + # in C, the subsequent test in C++ will use the cached variable. + # We trick autoconf by testing the size of a "void *" in C and a + # "const void *" in C++. + # + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of const void *" >&5 +$as_echo_n "checking size of const void *... " >&6; } +if ${ac_cv_sizeof_const_void_p+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_cxx_compute_int "$LINENO" "(long int) (sizeof (const void *))" "ac_cv_sizeof_const_void_p" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_const_void_p" = yes; 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 77 "cannot compute sizeof (const void *) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_const_void_p=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_const_void_p" >&5 +$as_echo "$ac_cv_sizeof_const_void_p" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_CONST_VOID_P $ac_cv_sizeof_const_void_p +_ACEOF + + + ac_lbl_cxx_sizeof_void_p="$ac_cv_sizeof_const_void_p" + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +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 + + if test "$ac_lbl_cxx_sizeof_void_p" -eq 0; then + as_fn_error $? "No C++ compiler was found" "$LINENO" 5 + fi + if test "$ac_lbl_c_sizeof_void_p" -ne "$ac_lbl_cxx_sizeof_void_p"; then + as_fn_error $? "C compiler $CC produces code with $ac_lbl_c_sizeof_void_p-byte pointers +while C++ compiler $CXX produces code with $ac_lbl_cxx_sizeof_void_p-byte pointers. This prevents +code in those languages from being combined." "$LINENO" 5 + fi + ;; +esac + + + + - - - if test "$GCC" = yes ; then # # -Werror forces warnings to be errors. @@ -3617,28 +4915,36 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -fvisibility=hidden option" >&5 $as_echo_n "checking whether the compiler supports the -fvisibility=hidden option... " >&6; } save_CFLAGS="$CFLAGS" - if expr "x-fvisibility=hidden" : "x-W.*" >/dev/null - then - CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -fvisibility=hidden" - elif expr "x-fvisibility=hidden" : "x-f.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -fvisibility=hidden" - elif expr "x-fvisibility=hidden" : "x-m.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -fvisibility=hidden" - else - CFLAGS="$CFLAGS -fvisibility=hidden" - fi - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -return 0 - ; - return 0; -} + CFLAGS="$CFLAGS -fvisibility=hidden" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -3694,6 +5000,7 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag="$save_ac_c_werror_flag" else V_INCLS="$V_INCLS -I/usr/local/include" @@ -3717,28 +5024,36 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -fvisibility=hidden option" >&5 $as_echo_n "checking whether the compiler supports the -fvisibility=hidden option... " >&6; } save_CFLAGS="$CFLAGS" - if expr "x-fvisibility=hidden" : "x-W.*" >/dev/null - then - CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -fvisibility=hidden" - elif expr "x-fvisibility=hidden" : "x-f.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -fvisibility=hidden" - elif expr "x-fvisibility=hidden" : "x-m.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -fvisibility=hidden" - else - CFLAGS="$CFLAGS -fvisibility=hidden" - fi + CFLAGS="$CFLAGS -fvisibility=hidden" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -int -main () -{ -return 0 - ; - return 0; -} +int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -3794,6 +5109,7 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag="$save_ac_c_werror_flag" ;; @@ -3879,28 +5195,36 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -xldscope=hidden option" >&5 $as_echo_n "checking whether the compiler supports the -xldscope=hidden option... " >&6; } save_CFLAGS="$CFLAGS" - if expr "x-xldscope=hidden" : "x-W.*" >/dev/null - then - CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -xldscope=hidden" - elif expr "x-xldscope=hidden" : "x-f.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -xldscope=hidden" - elif expr "x-xldscope=hidden" : "x-m.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -xldscope=hidden" - else - CFLAGS="$CFLAGS -xldscope=hidden" - fi + CFLAGS="$CFLAGS -xldscope=hidden" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -int -main () -{ -return 0 - ; - return 0; -} +int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -3956,6 +5280,7 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag="$save_ac_c_werror_flag" ;; @@ -4018,11 +5343,12 @@ $as_echo "#define const /**/" >>confdefs.h aix*) ;; - freebsd*|netbsd*|openbsd*|dragonfly*|linux*|osf*|midipix*) - # - # Platforms where the linker is the GNU linker - # or accepts command-line arguments like - # those the GNU linker accepts. + freebsd*|netbsd*|openbsd*|dragonfly*|linux*|osf*|haiku*|midipix*) + # + # Platforms where the C compiler is GCC or accepts + # compatible command-line arguments, and the linker + # is the GNU linker or accepts compatible command-line + # arguments. # # Some instruction sets require -fPIC on some # operating systems. Check for them. If you @@ -4043,12 +5369,11 @@ $as_echo "#define const /**/" >>confdefs.h esac V_SHLIB_CCOPT="$V_SHLIB_CCOPT $PIC_OPT" V_SONAME_OPT="-Wl,-soname," - V_RPATH_OPT="-Wl,-rpath," ;; hpux*) V_SHLIB_CCOPT="$V_SHLIB_CCOPT -fpic" - # + # # XXX - this assumes GCC is using the HP linker, # rather than the GNU linker, and that the "+h" # option is used on all HP-UX platforms, both .sl @@ -4056,7 +5381,7 @@ $as_echo "#define const /**/" >>confdefs.h # V_SONAME_OPT="-Wl,+h," # - # By default, directories specifed with -L + # By default, directories specified with -L # are added to the run-time search path, so # we don't add them in pcap-config. # @@ -4065,11 +5390,12 @@ $as_echo "#define const /**/" >>confdefs.h solaris*) V_SHLIB_CCOPT="$V_SHLIB_CCOPT -fpic" # - # XXX - this assumes GCC is using the Sun linker, - # rather than the GNU linker. + # Sun/Oracle's C compiler, GCC, and GCC-compatible + # compilers support -Wl,{comma-separated list of options}, + # and we use the C compiler, not ld, for all linking, + # including linking to produce a shared library. # V_SONAME_OPT="-Wl,-h," - V_RPATH_OPT="-Wl,-R," ;; esac else @@ -4091,7 +5417,7 @@ $as_echo "#define const /**/" >>confdefs.h # "-Wl,-soname,{soname}" option, with the soname part # of the option, while on other platforms the C compiler # driver takes it as a regular option with the soname - # following the option. The same applies to V_RPATH_OPT. + # following the option. # case "$host_os" in @@ -4102,13 +5428,17 @@ $as_echo "#define const /**/" >>confdefs.h freebsd*|netbsd*|openbsd*|dragonfly*|linux*) # - # "cc" is GCC. + # Platforms where the C compiler is GCC or accepts + # compatible command-line arguments, and the linker + # is the GNU linker or accepts compatible command-line + # arguments. + # + # XXX - does 64-bit SPARC require -fPIC? # V_SHLIB_CCOPT="$V_SHLIB_CCOPT -fpic" V_SHLIB_CMD="\$(CC)" V_SHLIB_OPT="-shared" V_SONAME_OPT="-Wl,-soname," - V_RPATH_OPT="-Wl,-rpath," ;; hpux*) @@ -4117,29 +5447,33 @@ $as_echo "#define const /**/" >>confdefs.h V_SHLIB_OPT="-b" V_SONAME_OPT="+h " # - # By default, directories specifed with -L + # By default, directories specified with -L # are added to the run-time search path, so # we don't add them in pcap-config. # ;; osf*) - # + # # Presumed to be DEC OSF/1, Digital UNIX, or # Tru64 UNIX. # V_SHLIB_CMD="\$(CC)" V_SHLIB_OPT="-shared" V_SONAME_OPT="-soname " - V_RPATH_OPT="-rpath " ;; solaris*) V_SHLIB_CCOPT="$V_SHLIB_CCOPT -Kpic" V_SHLIB_CMD="\$(CC)" V_SHLIB_OPT="-G" - V_SONAME_OPT="-h " - V_RPATH_OPT="-R" + # + # Sun/Oracle's C compiler, GCC, and GCC-compatible + # compilers support -Wl,{comma-separated list of options}, + # and we use the C compiler, not ld, for all linking, + # including linking to produce a shared library. + # + V_SONAME_OPT="-Wl,-h," ;; esac fi @@ -4167,217 +5501,11 @@ else static inline struct iltest * foo() - { - static struct iltest xxx; - - return &xxx; - } -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_lbl_cc_inline=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if test "$ac_lbl_cc_inline" = yes ; then - break; - fi - done - if test "$ac_lbl_cc_inline" = yes ; then - ac_cv_lbl_inline=$ac_lbl_inline - fi -fi - - CFLAGS="$save_CFLAGS" - if test ! -z "$ac_cv_lbl_inline" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lbl_inline" >&5 -$as_echo "$ac_cv_lbl_inline" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - -cat >>confdefs.h <<_ACEOF -#define inline $ac_cv_lbl_inline -_ACEOF - - -# -# 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 - /* 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 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) - 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 - /* 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 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) - 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 - /* 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 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) - 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 - /* 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 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) - 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 - /* 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 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; + { + static struct iltest xxx; + + return &xxx; + } int main () { @@ -4387,378 +5515,298 @@ main () } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_sys_large_files=1; break + ac_lbl_cc_inline=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_cv_sys_large_files=unknown - break -done + if test "$ac_lbl_cc_inline" = yes ; then + break; + fi + done + if test "$ac_lbl_cc_inline" = yes ; then + ac_cv_lbl_inline=$ac_lbl_inline + fi 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 + CFLAGS="$save_CFLAGS" + if test ! -z "$ac_cv_lbl_inline" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lbl_inline" >&5 +$as_echo "$ac_cv_lbl_inline" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + 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 /* for off_t */ - #include -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 /* for off_t */ - #include -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 +#define inline $ac_cv_lbl_inline _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 - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -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 how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __atomic_load_n" >&5 +$as_echo_n "checking for __atomic_load_n... " >&6; } + if ${ac_cv_have___atomic_load_n+:} false; then : $as_echo_n "(cached) " >&6 else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : +# 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 - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break + ac_retval=1 fi -rm -f conftest.err conftest.i conftest.$ac_ext + # 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 -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : +} # ac_fn_c_try_link +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int +main () +{ + + int i = 17; + int j; + j = __atomic_load_n(&i, __ATOMIC_RELAXED); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_have___atomic_load_n=yes else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } + ac_have___atomic_load_n=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -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}: result: $ac_have___atomic_load_n" >&5 +$as_echo "$ac_have___atomic_load_n" >&6; } + if test $ac_have___atomic_load_n = yes ; then +$as_echo "#define HAVE___ATOMIC_LOAD_N 1" >>confdefs.h -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __atomic_store_n" >&5 +$as_echo_n "checking for __atomic_store_n... " >&6; } + if ${ac_cv_have___atomic_store_n+:} false; then : $as_echo_n "(cached) " >&6 else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_GREP" || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ - $ac_path_GREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi +int +main () +{ + + int i; + __atomic_store_n(&i, 17, __ATOMIC_RELAXED); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_have___atomic_store_n=yes else - ac_cv_path_GREP=$GREP + ac_have___atomic_store_n=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_have___atomic_store_n" >&5 +$as_echo "$ac_have___atomic_store_n" >&6; } + if test $ac_have___atomic_store_n = yes ; then + +$as_echo "#define HAVE___ATOMIC_STORE_N 1" >>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 -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" +if test "$enable_largefile" != no; then -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; 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 - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_EGREP" || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac + 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 + /* 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 () +{ - $ac_path_EGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + ; + 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 - ac_cv_path_EGREP=$EGREP + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* 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 + /* 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 - - 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_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : +{ $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 -#include -#include -#include - +#include + /* 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 () { @@ -4768,115 +5816,123 @@ main () } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no + ac_cv_sys_large_files=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include +#define _LARGE_FILES 1 +#include + /* 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 (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=1; break fi -rm -f conftest* - +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_large_files=unknown + break +done fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - +{ $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 -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : +;; +esac +rm -rf conftest* + fi -else - ac_cv_header_stdc=no -fi -rm -f conftest* fi -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; 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 + while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +#include /* for off_t */ + #include int main () { - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; +int (*fp) (FILE *, off_t, int) = fseeko; + return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); + ; return 0; } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext +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 /* for off_t */ + #include +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_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h +{ $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* -fi +# 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 -# On IRIX 5.3, sys/types and inttypes.h are conflicting. -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$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 +$as_echo "#define HAVE_FSEEKO 1" >>confdefs.h fi -done - -for ac_header in sys/ioccom.h sys/sockio.h limits.h +for ac_header in sys/ioccom.h sys/sockio.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" @@ -4901,74 +5957,65 @@ fi done -for ac_header in net/pfvar.h -do : - ac_fn_c_check_header_compile "$LINENO" "net/pfvar.h" "ac_cv_header_net_pfvar_h" "#include -#include -#include -" -if test "x$ac_cv_header_net_pfvar_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_NET_PFVAR_H 1 -_ACEOF -fi -done + save_CFLAGS="$CFLAGS" + save_LIBS="$LIBS" + save_LDFLAGS="$LDFLAGS" -if test "$ac_cv_header_net_pfvar_h" = yes; then +case "$host_os" in +haiku*) # - # Check for various PF actions. + # Haiku needs _BSD_SOURCE for the _IO* macros because it doesn't use them. # - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether net/pfvar.h defines PF_NAT through PF_NORDR" >&5 -$as_echo_n "checking whether net/pfvar.h defines PF_NAT through PF_NORDR... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + CFLAGS="$CFLAGS -D_BSD_SOURCE" + # + # Haiku has getpass in libbsd. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpass in -lbsd" >&5 +$as_echo_n "checking for getpass in -lbsd... " >&6; } +if ${ac_cv_lib_bsd_getpass+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lbsd $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include - #include - #include - #include + +/* 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 getpass (); int main () { -return PF_NAT+PF_NONAT+PF_BINAT+PF_NOBINAT+PF_RDR+PF_NORDR; +return getpass (); ; 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_PF_NAT_THROUGH_PF_NORDR 1" >>confdefs.h - - +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_bsd_getpass=yes else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + ac_cv_lib_bsd_getpass=no 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 +LIBS=$ac_check_lib_save_LIBS fi - -case "$host_os" in -linux*|uclinux*) - for ac_header in linux/sockios.h linux/if_bonding.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" " -#include -#include - -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_getpass" >&5 +$as_echo "$ac_cv_lib_bsd_getpass" >&6; } +if test "x$ac_cv_lib_bsd_getpass" = xyes; then : cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +#define HAVE_LIBBSD 1 _ACEOF -fi + LIBS="-lbsd $LIBS" -done +fi ;; esac @@ -5019,6 +6066,11 @@ $as_echo "$ac_cv_lbl_gcc_fixincludes" >&6; } fi fi + CFLAGS="$save_CFLAGS" + LIBS="$save_LIBS" + LDFLAGS="$save_LDFLAGS" + + for ac_func in strerror do : ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror" @@ -5058,7 +6110,7 @@ main(void) _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - # GNU-style + # GNU-style { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -5079,14 +6131,14 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else # - # We don't have strerror_r; do we have strerror_s? + # We don't have strerror_r; do we have _wcserror_s? # - for ac_func in strerror_s + for ac_func in _wcserror_s do : - ac_fn_c_check_func "$LINENO" "strerror_s" "ac_cv_func_strerror_s" -if test "x$ac_cv_func_strerror_s" = xyes; then : + ac_fn_c_check_func "$LINENO" "_wcserror_s" "ac_cv_func__wcserror_s" +if test "x$ac_cv_func__wcserror_s" = xyes; then : cat >>confdefs.h <<_ACEOF -#define HAVE_STRERROR_S 1 +#define HAVE__WCSERROR_S 1 _ACEOF fi @@ -5112,41 +6164,22 @@ done # -# Either: -# -# we have snprintf() and vsnprintf(), and have asprintf() and -# vasprintf(); +# Make sure we have vsnprintf() and snprintf(); we require them. # -# we have snprintf() and vsnprintf(), but don't have asprintf() -# or vasprintf(); -# -# we have neither snprintf() nor vsnprintf(), and don't have -# asprintf() or vasprintf(), either. -# -# We assume that if we have asprintf() we have vasprintf(), as well -# as snprintf() and vsnprintf(), and that if we have snprintf() we -# have vsnprintf(). -# -# For the first case, we don't need any replacement routines. -# For the second case, we need replacement asprintf()/vasprintf() -# routines. -# For the third case, we need replacement snprintf()/vsnprintf() and -# asprintf()/vasprintf() routines. -# -needsnprintf=no -for ac_func in vsnprintf snprintf -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" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF +ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf" +if test "x$ac_cv_func_vsnprintf" = xyes; then : else - needsnprintf=yes + as_fn_error $? "vsnprintf() is required but wasn't found" "$LINENO" 5 +fi + +ac_fn_c_check_func "$LINENO" "snprintf" "ac_cv_func_snprintf" +if test "x$ac_cv_func_snprintf" = xyes; then : + +else + as_fn_error $? "snprintf() is required but wasn't found" "$LINENO" 5 fi -done + needasprintf=no for ac_func in vasprintf asprintf @@ -5163,23 +6196,7 @@ else fi done -if test $needsnprintf = yes; then - # - # We assume we have none of them; missing/snprintf.c supplies - # all of them. - # - case " $LIBOBJS " in - *" snprintf.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS snprintf.$ac_objext" - ;; -esac - -elif test $needasprintf = yes; then - # - # We assume we have snprintf()/vsnprintf() but lack - # asprintf()/vasprintf(); missing/asprintf.c supplies - # the latter (using vsnprintf()). - # +if test $needasprintf = yes; then case " $LIBOBJS " in *" asprintf.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS asprintf.$ac_objext" @@ -5356,9 +6373,61 @@ if test "x$ac_cv_lib_socket_getaddrinfo" = xyes; then : else # - # We didn't find it. + # Not found in libsocket; test for it in libnetwork, which + # is where it is in Haiku. # - as_fn_error $? "getaddrinfo is required, but wasn't found" "$LINENO" 5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in -lnetwork" >&5 +$as_echo_n "checking for getaddrinfo in -lnetwork... " >&6; } +if ${ac_cv_lib_network_getaddrinfo+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnetwork $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 getaddrinfo (); +int +main () +{ +return getaddrinfo (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_network_getaddrinfo=yes +else + ac_cv_lib_network_getaddrinfo=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_network_getaddrinfo" >&5 +$as_echo "$ac_cv_lib_network_getaddrinfo" >&6; } +if test "x$ac_cv_lib_network_getaddrinfo" = xyes; then : + + # + # OK, we found it in libnetwork. + # + LIBS="-lnetwork $LIBS" + +else + + # + # We didn't find it. + # + as_fn_error $? "getaddrinfo is required, but wasn't found" "$LINENO" 5 + +fi + fi @@ -5836,7 +6905,7 @@ fi # This test fails if we don't have # (if we have ether_hostton(), we should have # networking, and if we have networking, we should - # have ) or if we do but it doesn't + # have ) or if we do but it doesn't # declare ether_hostton(). # # Unset ac_cv_have_decl_ether_hostton so we don't @@ -6101,25 +7170,6 @@ $as_echo "${enable_protochain}" >&6; } # VALGRINDTEST_SRC= -# -# SITA support is mutually exclusive with native capture support; -# "--with-sita" selects SITA support. -# - -# Check whether --with-sita was given. -if test "${with_sita+set}" = set; then : - withval=$with_sita; - if test ! "x$withval" = "xno" ; then - -$as_echo "#define SITA 1" >>confdefs.h - - { $as_echo "$as_me:${as_lineno-$LINENO}: Enabling SITA ACN support" >&5 -$as_echo "$as_me: Enabling SITA ACN support" >&6;} - V_PCAP=sita - fi - -else - # Check whether --with-pcap was given. if test "${with_pcap+set}" = set; then : @@ -6252,6 +7302,18 @@ _ACEOF fi +done + + for ac_header in config/HaikuConfig.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "config/HaikuConfig.h" "ac_cv_header_config_HaikuConfig_h" "$ac_includes_default" +if test "x$ac_cv_header_config_HaikuConfig_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_CONFIG_HAIKUCONFIG_H 1 +_ACEOF + +fi + done @@ -6270,78 +7332,298 @@ done # 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 + 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 + 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 + elif test "$ac_cv_header_config_HaikuConfig_h" = yes; then + # + # Haiku. + # + V_PCAP=haiku + 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.md file for more info)" >&5 +$as_echo "$as_me: WARNING: (see the INSTALL.md file 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; } + + +# +# Do we have pkg-config? +# + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.17.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + +# +# Do we have the brew command from Homebrew? +# +# Extract the first word of "brew", so it can be a program name with args. +set dummy brew; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_BREW+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $BREW in + [\\/]* | ?:[\\/]*) + ac_cv_path_BREW="$BREW" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_BREW="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +BREW=$ac_cv_path_BREW +if test -n "$BREW"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BREW" >&5 +$as_echo "$BREW" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +# +# Solaris pkg-config is annoying. For at least one package (D-Bus, I'm +# looking at *you*!), there are separate include files for 32-bit and +# 64-bit builds (I guess using "unsigned long long" as a 64-bit integer +# type on a 64-bit build is like crossing the beams or soething), and +# there are two separate .pc files, so if we're doing a 32-bit build we +# should make sure we look in /usr/lib/pkgconfig for .pc files and if +# we're doing a 64-bit build we should make sure we look in +# /usr/lib/amd64/pkgconfig for .pc files. +# +case "$host_os" in + +solaris*) + if test "$ac_cv_sizeof_void_p" -eq 8; then # - # 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. + # 64-bit build. If the path is empty, set it to + # /usr/lib/amd64/pkgconfig; otherwise, if + # /usr/lib/pkgconfig appears in the path, prepend + # /usr/lib/amd64/pkgconfig to it; otherwise, put + # /usr/lib/amd64/pkgconfig at the end. # - V_PCAP=dlpi - else + if test -z "$PKG_CONFIG_PATH"; then + # + # Not set, or empty. Set it to + # /usr/lib/amd64/pkgconfig. + # + PKG_CONFIG_PATH=/usr/lib/amd64/pkgconfig + elif test ! -z `echo "$PKG_CONFIG_PATH" | grep "/usr/lib/pkgconfig"`; then + # + # It contains /usr/lib/pkgconfig. Prepend + # /usr/lib/amd64/pkgconfig to /usr/lib/pkgconfig. + # + PKG_CONFIG_PATH=`echo "$PKG_CONFIG_PATH" | sed "s;/usr/lib/pkgconfig;/usr/lib/amd64/pkgconfig:/usr/lib/pkgconfig;"` + else + # + # Not empty, but doesn't contain /usr/lib/pkgconfig. + # Append /usr/lib/amd64/pkgconfig to it. + # + PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/lib/amd64/pkgconfig" + fi + export PKG_CONFIG_PATH + elif test "$ac_cv_sizeof_void_p" -eq 4; then # - # Nothing we support. + # 32-bit build. If /usr/amd64/lib/pkgconfig appears + # in the path, prepend /usr/lib/pkgconfig to it. # - 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;} + if test ! -z `echo "$PKG_CONFIG_PATH" | grep "/usr/lib/amd64/pkgconfig"`; then + # + # It contains /usr/lib/amd64/pkgconfig. Prepend + # /usr/lib/pkgconfig to /usr/lib/amd64/pkgconfig. + # + PKG_CONFIG_PATH=`echo "$PKG_CONFIG_PATH" | sed "s;/usr/lib/amd64/pkgconfig;/usr/lib/pkgconfig:/usr/lib/amd64/pkgconfig;"` + export PKG_CONFIG_PATH + fi 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; } - +esac # -# Do capture-mechanism-dependent tests. +# Handle each capture type. # case "$V_PCAP" in dlpi) - # - # Needed for common functions used by pcap-[dlpi,libdlpi].c - # - SSRC="dlpisubs.c" - # # Checks for some header files. # @@ -6370,7 +7652,7 @@ done # Also, due to the bug above applications that link to libpcap with # libdlpi will have to add "-L/lib" option to "configure". # - saved_ldflags=$LDFLAGS + save_LDFLAGS="$LDFLAGS" LDFLAGS="$LIBS -L/lib" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlpi_walk in -ldlpi" >&5 $as_echo_n "checking for dlpi_walk in -ldlpi... " >&6; } @@ -6411,16 +7693,32 @@ $as_echo "$ac_cv_lib_dlpi_dlpi_walk" >&6; } if test "x$ac_cv_lib_dlpi_dlpi_walk" = xyes; then : LIBS="-ldlpi $LIBS" + LIBS_STATIC="-ldlpi $LIBS_STATIC" + LIBS_PRIVATE="-ldlpi $LIBS_PRIVATE" V_PCAP=libdlpi + # + # Capture module plus common code needed for + # common functions used by pcap-[dlpi,libdlpi].c + # + PLATFORM_C_SRC="pcap-libdlpi.c dlpisubs.c" + $as_echo "#define HAVE_LIBDLPI 1" >>confdefs.h else - V_PCAP=dlpi + + V_PCAP=dlpi + + # + # Capture module plus common code needed for + # common functions used by pcap-[dlpi,libdlpi].c + # + PLATFORM_C_SRC="pcap-dlpi.c dlpisubs.c" + fi - LDFLAGS=$saved_ldflags + LDFLAGS="$save_LDFLAGS" # # Checks whether is usable, to catch weird SCO @@ -6482,7 +7780,43 @@ fi ;; +enet) + # + # Capture module + # + PLATFORM_C_SRC="pcap-enet.c" + ;; + +haiku) + # + # Capture module + # + PLATFORM_CXX_SRC="pcap-haiku.cpp" + + # + # Just for the sake of it. + # + for ac_header in net/if.h net/if_dl.h net/if_types.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 + + ;; + linux) + # + # Capture module + # + PLATFORM_C_SRC="pcap-linux.c" + # # Do we have the wireless extensions? # @@ -6506,6 +7840,12 @@ done # # Do we have libnl? + # We only want version 3. Version 2 was, apparently, + # short-lived, and version 1 is source and binary + # incompatible with version 3, and it appears that, + # these days, everybody's using version 3. We're + # not supporting older versions of the Linux kernel; + # let's drop support for older versions of libnl, too. # # Check whether --with-libnl was given. @@ -6517,161 +7857,178 @@ fi if test x$with_libnl != xno ; then - have_any_nl="no" + # + # Check for libnl-genl-3.0 with pkg-config. + # - incdir=-I/usr/include/libnl3 - libnldir= - case "$with_libnl" in - yes|if_available) - ;; +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libnl-genl-3.0 with pkg-config" >&5 +$as_echo_n "checking for libnl-genl-3.0 with pkg-config... " >&6; } - *) - if test -d $withval; then - libnldir=-L${withval}/lib/.libs - incdir=-I${withval}/include - fi - ;; - esac +if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnl-genl-3.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libnl-genl-3.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then - # - # Try libnl 3.x first. - # - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_socket_alloc in -lnl-3" >&5 -$as_echo_n "checking for nl_socket_alloc in -lnl-3... " >&6; } -if ${ac_cv_lib_nl_3_nl_socket_alloc+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lnl-3 ${incdir} ${libnldir} -lnl-genl-3 -lnl-3 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + # + # The package was found, so try to get its C flags and + # libraries. + # + if test -n "$LIBNL_CFLAGS"; then + pkg_cv_LIBNL_CFLAGS="$LIBNL_CFLAGS" + elif test -n "$PKG_CONFIG"; then -/* 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 nl_socket_alloc (); -int -main () -{ -return nl_socket_alloc (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_nl_3_nl_socket_alloc=yes +if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnl-genl-3.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libnl-genl-3.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBNL_CFLAGS=`$PKG_CONFIG --cflags "libnl-genl-3.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else - ac_cv_lib_nl_3_nl_socket_alloc=no + pkg_failed=yes fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + else + pkg_failed=untried fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_3_nl_socket_alloc" >&5 -$as_echo "$ac_cv_lib_nl_3_nl_socket_alloc" >&6; } -if test "x$ac_cv_lib_nl_3_nl_socket_alloc" = xyes; then : - - # - # Yes, we have libnl 3.x. - # - LIBS="${libnldir} -lnl-genl-3 -lnl-3 $LIBS" - -$as_echo "#define HAVE_LIBNL 1" >>confdefs.h - - -$as_echo "#define HAVE_LIBNL_3_x 1" >>confdefs.h - + if test -n "$LIBNL_LIBS"; then + pkg_cv_LIBNL_LIBS="$LIBNL_LIBS" + elif test -n "$PKG_CONFIG"; then -$as_echo "#define HAVE_LIBNL_NLE 1" >>confdefs.h - - -$as_echo "#define HAVE_LIBNL_SOCKETS 1" >>confdefs.h - - V_INCLS="$V_INCLS ${incdir}" - have_any_nl="yes" +if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnl-genl-3.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libnl-genl-3.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBNL_LIBS=`$PKG_CONFIG --libs "libnl-genl-3.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + if test -n "$LIBNL_LIBS_STATIC"; then + pkg_cv_LIBNL_LIBS_STATIC="$LIBNL_LIBS_STATIC" + elif test -n "$PKG_CONFIG"; then +if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnl-genl-3.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libnl-genl-3.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBNL_LIBS_STATIC=`$PKG_CONFIG --libs --static "libnl-genl-3.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried fi - if test x$have_any_nl = xno ; then - # - # Try libnl 2.x - # - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_socket_alloc in -lnl" >&5 -$as_echo_n "checking for nl_socket_alloc in -lnl... " >&6; } -if ${ac_cv_lib_nl_nl_socket_alloc+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lnl $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 nl_socket_alloc (); -int -main () -{ -return nl_socket_alloc (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_nl_nl_socket_alloc=yes + if test $pkg_failed = yes; then + # + # That failed - report an error. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: result: error" >&5 +$as_echo "error" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes else - ac_cv_lib_nl_nl_socket_alloc=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + _pkg_short_errors_supported=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_nl_socket_alloc" >&5 -$as_echo "$ac_cv_lib_nl_nl_socket_alloc" >&6; } -if test "x$ac_cv_lib_nl_nl_socket_alloc" = xyes; then : + if test $_pkg_short_errors_supported = yes; then + LIBNL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libnl-genl-3.0" 2>&1` + else + LIBNL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libnl-genl-3.0" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBNL_PKG_ERRORS" >&5 - # - # Yes, we have libnl 2.x. - # - LIBS="${libnldir} -lnl-genl -lnl $LIBS" + as_fn_error $? "Package requirements (libnl-genl-3.0) were not met: -$as_echo "#define HAVE_LIBNL 1" >>confdefs.h +$LIBNL_PKG_ERRORS +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. -$as_echo "#define HAVE_LIBNL_2_x 1" >>confdefs.h +Alternatively, you may set the environment variables LIBNL_CFLAGS +and LIBNL_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 + elif test $pkg_failed = untried; then + # + # We don't have pkg-config, so it didn't work. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found (pkg-config not found)" >&5 +$as_echo "not found (pkg-config not found)" >&6; } + else + # + # We found the package. + # + LIBNL_CFLAGS=$pkg_cv_LIBNL_CFLAGS + LIBNL_LIBS=$pkg_cv_LIBNL_LIBS + LIBNL_LIBS_STATIC=$pkg_cv_LIBNL_LIBS_STATIC + { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5 +$as_echo "found" >&6; } + + pkg_config_found_libnl=yes + V_INCLS="$V_INCLS $LIBNL_CFLAGS" + ADDITIONAL_LIBS="$LIBNL_LIBS $ADDITIONAL_LIBS" + ADDITIONAL_LIBS_STATIC="$LIBNL_LIBS_STATIC $ADDITIONAL_LIBS_STATIC" + REQUIRES_PRIVATE="libnl-genl-3.0 $REQUIRES_PRIVATE" -$as_echo "#define HAVE_LIBNL_NLE 1" >>confdefs.h +$as_echo "#define HAVE_LIBNL 1" >>confdefs.h -$as_echo "#define HAVE_LIBNL_SOCKETS 1" >>confdefs.h + fi +else - have_any_nl="yes" + # + # The package isn't present. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 +$as_echo "not found" >&6; } fi - fi - if test x$have_any_nl = xno ; then + if test x$pkg_config_found_libnl != xyes; then # - # No, we don't; do we have libnl 1.x? + # OK, either we don't have pkg-config or there + # wasn't a .pc file for it; Check for it directly. # - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_handle_alloc in -lnl" >&5 -$as_echo_n "checking for nl_handle_alloc in -lnl... " >&6; } -if ${ac_cv_lib_nl_nl_handle_alloc+:} false; then : + case "$with_libnl" in + + yes|if_available) + incdir=-I/usr/include/libnl3 + libnldir= + ;; + + *) + if test -d $withval; then + libnldir=-L${withval}/lib + incdir=-I${withval}/include + fi + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_socket_alloc in -lnl-3" >&5 +$as_echo_n "checking for nl_socket_alloc in -lnl-3... " >&6; } +if ${ac_cv_lib_nl_3_nl_socket_alloc+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lnl $LIBS" +LIBS="-lnl-3 ${incdir} ${libnldir} -lnl-genl-3 -lnl-3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -6681,88 +8038,54 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char nl_handle_alloc (); +char nl_socket_alloc (); int main () { -return nl_handle_alloc (); +return nl_socket_alloc (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_nl_nl_handle_alloc=yes + ac_cv_lib_nl_3_nl_socket_alloc=yes else - ac_cv_lib_nl_nl_handle_alloc=no + ac_cv_lib_nl_3_nl_socket_alloc=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_nl_nl_handle_alloc" >&5 -$as_echo "$ac_cv_lib_nl_nl_handle_alloc" >&6; } -if test "x$ac_cv_lib_nl_nl_handle_alloc" = xyes; then : - - # - # Yes. - # - LIBS="${libnldir} -lnl $LIBS" - -$as_echo "#define HAVE_LIBNL 1" >>confdefs.h - - have_any_nl="yes" - -fi - - fi - - if test x$have_any_nl = xno ; then - # - # No, we don't have libnl at all. - # - if test x$with_libnl = xyes ; then - as_fn_error $? "libnl support requested but libnl not found" "$LINENO" 5 - fi - fi - fi - - for ac_header in linux/ethtool.h -do : - ac_fn_c_check_header_compile "$LINENO" "linux/ethtool.h" "ac_cv_header_linux_ethtool_h" " -$ac_includes_default -#include - -" -if test "x$ac_cv_header_linux_ethtool_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LINUX_ETHTOOL_H 1 -_ACEOF - -fi - -done +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_3_nl_socket_alloc" >&5 +$as_echo "$ac_cv_lib_nl_3_nl_socket_alloc" >&6; } +if test "x$ac_cv_lib_nl_3_nl_socket_alloc" = xyes; then : + # + # Yes, we have libnl 3.x. + # + ADDITIONAL_LIBS="${libnldir} -lnl-genl-3 -lnl-3 $ADDITIONAL_LIBS" + ADDITIONAL_LIBS_STATIC="${libnldir} -lnl-genl-3 -lnl-3 $ADDITIONAL_LIBS_STATIC" + LIBS_PRIVATE="${libnldir} -lnl-genl-3 -lnl-3 $LIBS_PRIVATE" - # - # Check to see if struct tpacket_stats is defined in - # . 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 +$as_echo "#define HAVE_LIBNL 1" >>confdefs.h -" -if test "x$ac_cv_type_struct_tpacket_stats" = xyes; then : + V_INCLS="$V_INCLS ${incdir}" -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_TPACKET_STATS 1 -_ACEOF +else + # + # No, we don't have libnl at all. + # Fail if the user explicitly requested + # it. + # + if test x$with_libnl = xyes ; then + as_fn_error $? "libnl support requested but libnl not found" "$LINENO" 5 + fi fi + fi + fi # # Check to see if the tpacket_auxdata struct has a tp_vlan_tci member. @@ -6789,6 +8112,11 @@ fi ;; bpf) + # + # Capture module + # + PLATFORM_C_SRC="pcap-bpf.c" + # # Check whether we have the *BSD-style ioctls. # @@ -6828,12 +8156,44 @@ fi ;; +pf) + # + # Capture module + # + PLATFORM_C_SRC="pcap-pf.c" + ;; + +snit) + # + # Capture module + # + PLATFORM_C_SRC="pcap-snit.c" + ;; + +snoop) + # + # Capture module + # + PLATFORM_C_SRC="pcap-snoop.c" + ;; + dag) # # --with-pcap=dag is the only way to get here, and it means # "DAG support but nothing else" # V_DEFS="$V_DEFS -DDAG_ONLY" + PLATFORM_C_SRC="pcap-dag.c" + xxx_only=yes + ;; + +dpdk) + # + # --with-pcap=dpdk is the only way to get here, and it means + # "DPDK support but nothing else" + # + V_DEFS="$V_DEFS -DDPDK_ONLY" + PLATFORM_C_SRC="pcap-dpdk.c" xxx_only=yes ;; @@ -6843,6 +8203,7 @@ septel) # "Septel support but nothing else" # V_DEFS="$V_DEFS -DSEPTEL_ONLY" + PLATFORM_C_SRC="pcap-septel.c" xxx_only=yes ;; @@ -6852,10 +8213,15 @@ snf) # "SNF support but nothing else" # V_DEFS="$V_DEFS -DSNF_ONLY" + PLATFORM_C_SRC="pcap-snf.c" xxx_only=yes ;; null) + # + # Capture module + # + PLATFORM_C_SRC="pcap-null.c" ;; *) @@ -6879,7 +8245,7 @@ if test "x$ac_cv_header_ifaddrs_h" = xyes; then : # We have the header, so we use "getifaddrs()" to # get the list of interfaces. # - V_FINDALLDEVS=fad-getad.c + PLATFORM_C_SRC="$PLATFORM_C_SRC fad-getad.c" else @@ -6948,18 +8314,15 @@ fi { $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 + PLATFORM_C_SRC="$PLATFORM_C_SRC fad-glifc.c" else - V_FINDALLDEVS=fad-gifc.c + PLATFORM_C_SRC="$PLATFORM_C_SRC fad-gifc.c" fi fi fi -fi - - case "$host_os" in linux*) for ac_header in linux/net_tstamp.h @@ -6981,21 +8344,6 @@ $as_echo "$as_me: no hardware timestamp support implemented for $host_os" >&6;} ;; esac -# Check whether --enable-packet-ring was given. -if test "${enable_packet_ring+set}" = set; then : - enableval=$enable_packet_ring; -else - enable_packet_ring=yes -fi - - -if test "x$enable_packet_ring" != "xno" ; then - -$as_echo "#define PCAP_SUPPORT_PACKET_RING 1" >>confdefs.h - - -fi - # # Check for socklen_t. # @@ -7105,10 +8453,21 @@ if test "$want_dag" != no; then if test -z "$dag_lib_dir"; then dag_lib_dir="$dag_root/lib" + # + # Handle multiarch systems. + # + if test -d "$dag_lib_dir/$host" + then + dag_lib_dir="$dag_lib_dir/$host" + fi fi - V_INCLS="$V_INCLS -I$dag_include_dir" + save_CFLAGS="$CFLAGS" + save_LIBS="$LIBS" + save_LDFLAGS="$LDFLAGS" + + CFLAGS="$CFLAGS -I$dag_include_dir" for ac_header in dagapi.h do : ac_fn_c_check_header_mongrel "$LINENO" "dagapi.h" "ac_cv_header_dagapi_h" "$ac_includes_default" @@ -7122,16 +8481,27 @@ fi done + CFLAGS="$save_CFLAGS" + LIBS="$save_LIBS" + LDFLAGS="$save_LDFLAGS" + + if test "$ac_cv_header_dagapi_h" = yes; then + V_INCLS="$V_INCLS -I$dag_include_dir" + if test $V_PCAP != dag ; then - SSRC="$SSRC pcap-dag.c" + MODULE_C_SRC="$MODULE_C_SRC pcap-dag.c" fi # 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 + + save_CFLAGS="$CFLAGS" + save_LIBS="$LIBS" + save_LDFLAGS="$LDFLAGS" + LDFLAGS="-L$dag_lib_dir" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dag_attach_stream in -ldag" >&5 $as_echo_n "checking for dag_attach_stream in -ldag... " >&6; } @@ -7170,11 +8540,15 @@ 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 : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBDAG 1 -_ACEOF - LIBS="-ldag $LIBS" + # + # We assume that if we have libdag we have + # libdagconf, as they're installed at the + # same time from the same package. + # + ADDITIONAL_LIBS="-L$dag_lib_dir $ADDITIONAL_LIBS -ldag -ldagconf" + ADDITIONAL_LIBS_STATIC="-L$dag_lib_dir $ADDITIONAL_LIBS_STATIC -ldag -ldagconf" + LIBS_PRIVATE="-L$dag_lib_dir $LIBS_PRIVATE -ldag -ldagconf" else as_fn_error $? "DAG library lacks streams support" "$LINENO" 5 @@ -7309,20 +8683,27 @@ $as_echo "#define HAVE_DAG_GET_STREAM_ERF_TYPES 1" >>confdefs.h fi - LDFLAGS=$saved_ldflags + CFLAGS="$save_CFLAGS" + LIBS="$save_LIBS" + LDFLAGS="$save_LDFLAGS" + # # 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 $as_echo "#define HAVE_DAG_LARGE_STREAMS_API 1" >>confdefs.h + + save_CFLAGS="$CFLAGS" + save_LIBS="$LIBS" + save_LDFLAGS="$LDFLAGS" + + LIBS="$LIBS -ldag -ldagconf" + LDFLAGS="$LDFLAGS -L$dag_lib_dir" { $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; } if ${ac_cv_lib_vdag_vdag_set_device_info+:} false; then : @@ -7365,6 +8746,11 @@ else ac_dag_have_vdag="0" fi + + CFLAGS="$save_CFLAGS" + LIBS="$save_LIBS" + LDFLAGS="$save_LDFLAGS" + if test "$ac_dag_have_vdag" = 1; then $as_echo "#define HAVE_DAG_VDAG 1" >>confdefs.h @@ -7372,7 +8758,9 @@ $as_echo "#define HAVE_DAG_VDAG 1" >>confdefs.h 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" + ADDITIONAL_LIBS="$ADDITIONAL_LIBS $PTHREAD_LIBS" + ADDITIONAL_LIBS_STATIC="$ADDITIONAL_LIBS_STATIC $PTHREAD_LIBS" + LIBS_PRIVATE="$LIBS_PRIVATE $PTHREAD_LIBS" fi fi @@ -7380,7 +8768,6 @@ $as_echo "#define HAVE_DAG_VDAG 1" >>confdefs.h $as_echo "#define HAVE_DAG_API 1" >>confdefs.h else - if test "$V_PCAP" = dag; then # User requested "dag" capture type but we couldn't # find the DAG API support. @@ -7388,10 +8775,11 @@ $as_echo "#define HAVE_DAG_API 1" >>confdefs.h fi if test "$want_dag" = yes; then - # User wanted DAG support but we couldn't find it. + # User wanted DAG support but we couldn't find it. as_fn_error $? "DAG support requested with --with-dag, but the DAG headers weren't found at $dag_include_dir: make sure the DAG support is installed, specify a different path or paths if necessary, or don't request DAG support" "$LINENO" 5 fi fi + CFLAGS="$save_CFLAGS" fi @@ -7457,7 +8845,7 @@ $as_echo "yes ($septel_include_dir)" >&6; } ADDLARCHIVEOBJS="$ADDLARCHIVEOBJS $septel_tools_dir/asciibin.o $septel_tools_dir/bit2byte.o $septel_tools_dir/confirm.o $septel_tools_dir/fmtmsg.o $septel_tools_dir/gct_unix.o $septel_tools_dir/hqueue.o $septel_tools_dir/ident.o $septel_tools_dir/mem.o $septel_tools_dir/pack.o $septel_tools_dir/parse.o $septel_tools_dir/pool.o $septel_tools_dir/sdlsig.o $septel_tools_dir/strtonum.o $septel_tools_dir/timer.o $septel_tools_dir/trace.o" if test "$V_PCAP" != septel ; then - SSRC="$SSRC pcap-septel.c" + MODULE_C_SRC="$MODULE_C_SRC pcap-septel.c" fi @@ -7474,7 +8862,7 @@ $as_echo "no" >&6; } fi if test "$want_septel" = yes; then - # User wanted Septel support but we couldn't find it. + # User wanted Septel support but we couldn't find it. as_fn_error $? "Septel support requested with --with-septel, but the Septel headers weren't found at $septel_include_dir: make sure the Septel support is installed, specify a different path or paths if necessary, or don't request Septel support" "$LINENO" 5 fi fi @@ -7558,11 +8946,22 @@ $as_echo_n "checking whether we have Myricom Sniffer API... " >&6; } if test -z "$snf_lib_dir"; then snf_lib_dir="$snf_root/lib" + # + # Handle multiarch systems. + # + if test -d "$snf_lib_dir/$host" + then + snf_lib_dir="$snf_lib_dir/$host" + fi fi if test -f "$snf_include_dir/snf.h"; then # We found a header; make sure we can link with the library - saved_ldflags=$LDFLAGS + + save_CFLAGS="$CFLAGS" + save_LIBS="$LIBS" + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -L$snf_lib_dir" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for snf_init in -lsnf" >&5 $as_echo_n "checking for snf_init in -lsnf... " >&6; } @@ -7604,7 +9003,11 @@ if test "x$ac_cv_lib_snf_snf_init" = xyes; then : ac_cv_lbl_snf_api="yes" fi - LDFLAGS="$saved_ldflags" + + CFLAGS="$save_CFLAGS" + LIBS="$save_LIBS" + LDFLAGS="$save_LDFLAGS" + if test "$ac_cv_lbl_snf_api" = no; then as_fn_error $? "SNF API cannot correctly be linked; check config.log" "$LINENO" 5 fi @@ -7615,11 +9018,12 @@ fi $as_echo "yes ($snf_root)" >&6; } V_INCLS="$V_INCLS -I$snf_include_dir" - LIBS="$LIBS -lsnf" - LDFLAGS="$LDFLAGS -L$snf_lib_dir" + ADDITIONAL_LIBS="$ADDITIONAL_LIBS -L$snf_lib_dir -lsnf" + ADDITIONAL_LIBS_STATIC="$ADDITIONAL_LIBS_STATIC -L$snf_lib_dir -lsnf" + LIBS_PRIVATE="$LIBS_PRIVATE -L$snf_lib_dir -lsnf" if test "$V_PCAP" != snf ; then - SSRC="$SSRC pcap-snf.c" + MODULE_C_SRC="$MODULE_C_SRC pcap-snf.c" fi @@ -7682,12 +9086,16 @@ if test "$want_turbocap" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether TurboCap is supported" >&5 $as_echo_n "checking whether TurboCap is supported... " >&6; } + save_CFLAGS="$CFLAGS" save_LIBS="$LIBS" + save_LDFLAGS="$LDFLAGS" + if test ! -z "$turbocap_root"; then TURBOCAP_CFLAGS="-I$turbocap_root/include" - TURBOCAP_LIBS="-L$turbocap_root/lib" + TURBOCAP_LDFLAGS="-L$turbocap_root/lib" CFLAGS="$CFLAGS $TURBOCAP_CFLAGS" + LDFLAGS="$LDFLAGS $TURBOCAP_LDFLAGS" fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -7712,14 +9120,20 @@ if ac_fn_c_try_compile "$LINENO"; then : fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$save_CFLAGS" + LIBS="$save_LIBS" + LDFLAGS="$save_LDFLAGS" + if test $ac_cv_lbl_turbocap_api = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - SSRC="$SSRC pcap-tc.c" + MODULE_C_SRC="$MODULE_C_SRC pcap-tc.c" V_INCLS="$V_INCLS $TURBOCAP_CFLAGS" - LIBS="$LIBS $TURBOCAP_LIBS -lTcApi -lpthread -lstdc++" + ADDITIONAL_LIBS="$ADDITIONAL_LIBS $TURBOCAP_LDFLAGS -lTcApi -lpthread -lstdc++" + ADDITIONAL_LIBS_STATIC="$ADDITIONAL_LIBS_STATIC $TURBOCAP_LDFLAGS -lTcApi -lpthread -lstdc++" + LIBS_PRIVATE="$LIBS_PRIVATE $TURBOCAP_LDFLAGS -lTcApi -lpthread -lstdc++" $as_echo "#define HAVE_TC_API 1" >>confdefs.h @@ -7729,7 +9143,7 @@ $as_echo "#define HAVE_TC_API 1" >>confdefs.h $as_echo "no" >&6; } if test "$want_turbocap" = yes; then - # User wanted Turbo support but we couldn't find it. + # User wanted Turbo support but we couldn't find it. as_fn_error $? "TurboCap support requested with --with-turbocap, but the TurboCap headers weren't found: make sure the TurboCap support is installed or don't request TurboCap support" "$LINENO" 5 fi fi @@ -7814,65 +9228,405 @@ if test "x$ac_cv_lib_crypt_crypt" = xyes; then : else - as_fn_error $? "rpcapd requires crypt(), but we didn't find it" "$LINENO" 5 + 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 + +" +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 + +" +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 + + + # + # Optionally, we may want to support SSL. + # Check for OpenSSL/libressl. + # + # First, try looking for it with pkg-config, if we have it. + # + # Homebrew's pkg-config does not, by default, look for + # pkg-config files for packages it has installed. + # Furthermore, at least for OpenSSL, they appear to be + # dumped in package-specific directories whose paths are + # not only package-specific but package-version-specific. + # + # So the only way to find openssl is to get the value of + # PKG_CONFIG_PATH from "brew --env openssl" and add that + # to PKG_CONFIG_PATH. (No, we can't just assume it's under + # /usr/local; Homebrew have conveniently chosen to put it + # under /opt/homebrew on ARM.) + # + # That's the nice thing about Homebrew - it makes things easier! + # Thanks! + # + save_PKG_CONFIG_PATH="$PKG_CONFIG_PATH" + if test -n "$BREW"; then + openssl_pkgconfig_dir=`$BREW --env --plain openssl | sed -n 's/PKG_CONFIG_PATH: //p'` + PKG_CONFIG_PATH="$openssl_pkgconfig_dir:$PKG_CONFIG_PATH" + fi + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for openssl with pkg-config" >&5 +$as_echo_n "checking for openssl with pkg-config... " >&6; } + +if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"openssl\""; } >&5 + ($PKG_CONFIG --exists --print-errors "openssl") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + + # + # The package was found, so try to get its C flags and + # libraries. + # + if test -n "$OPENSSL_CFLAGS"; then + pkg_cv_OPENSSL_CFLAGS="$OPENSSL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + +if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"openssl\""; } >&5 + ($PKG_CONFIG --exists --print-errors "openssl") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_OPENSSL_CFLAGS=`$PKG_CONFIG --cflags "openssl" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + if test -n "$OPENSSL_LIBS"; then + pkg_cv_OPENSSL_LIBS="$OPENSSL_LIBS" + elif test -n "$PKG_CONFIG"; then + +if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"openssl\""; } >&5 + ($PKG_CONFIG --exists --print-errors "openssl") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_OPENSSL_LIBS=`$PKG_CONFIG --libs "openssl" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + if test -n "$OPENSSL_LIBS_STATIC"; then + pkg_cv_OPENSSL_LIBS_STATIC="$OPENSSL_LIBS_STATIC" + elif test -n "$PKG_CONFIG"; then + +if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"openssl\""; } >&5 + ($PKG_CONFIG --exists --print-errors "openssl") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_OPENSSL_LIBS_STATIC=`$PKG_CONFIG --libs --static "openssl" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + + if test $pkg_failed = yes; then + # + # That failed - report an error. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: result: error" >&5 +$as_echo "error" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + OPENSSL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "openssl" 2>&1` + else + OPENSSL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "openssl" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$OPENSSL_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (openssl) were not met: + +$OPENSSL_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + + +Alternatively, you may set the environment variables OPENSSL_CFLAGS +and OPENSSL_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 + elif test $pkg_failed = untried; then + # + # We don't have pkg-config, so it didn't work. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found (pkg-config not found)" >&5 +$as_echo "not found (pkg-config not found)" >&6; } + else + # + # We found the package. + # + OPENSSL_CFLAGS=$pkg_cv_OPENSSL_CFLAGS + OPENSSL_LIBS=$pkg_cv_OPENSSL_LIBS + OPENSSL_LIBS_STATIC=$pkg_cv_OPENSSL_LIBS_STATIC + { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5 +$as_echo "found" >&6; } + + # + # We found OpenSSL/libressl. + # + HAVE_OPENSSL=yes + REQUIRES_PRIVATE="$REQUIRES_PRIVATE openssl" + + fi +else + + # + # The package isn't present. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 +$as_echo "not found" >&6; } + +fi + + PKG_CONFIG_PATH="$save_PKG_CONFIG_PATH" + + # + # If it wasn't found, and we have Homebrew installed, see + # if it's in Homebrew. + # + if test "x$HAVE_OPENSSL" != "xyes" -a -n "$BREW"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for openssl in Homebrew" >&5 +$as_echo_n "checking for openssl in Homebrew... " >&6; } + # + # The brew man page lies when it speaks of + # $BREW --prefix --installed + # outputting nothing. In Homebrew 3.3.16, + # it produces output regardless of whether + # the formula is installed or not, so we + # send the standard output and error to + # the bit bucket. + # + if $BREW --prefix --installed openssl >/dev/null 2>&1; then + # + # Yes. Get the include directory and library + # directory. (No, we can't just assume it's + # under /usr/local; Homebrew have conveniently + # chosen to put it under /opt/homebrew on ARM.) + # + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + HAVE_OPENSSL=yes + openssl_path=`$BREW --prefix openssl` + OPENSSL_CFLAGS="-I$openssl_path/include" + OPENSSL_LIBS="-L$openssl_path/lib -lssl -lcrypto" + OPENSSL_LIBS_STATIC="-L$openssl_path/lib -lssl -lcrypto" + OPENSSL_LIBS_PRIVATE="-L$openssl_path/lib -lssl -lcrypto" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + + # + # If it wasn't found, and /usr/local/include and /usr/local/lib + # exist, check if it's in /usr/local. (We check whether they + # exist because, if they don't exist, the compiler will warn + # about that and then ignore the argument, so they test + # using just the system header files and libraries.) + # + # We include the standard include file to 1) make sure that + # it's installed (if it's just a shared library for the + # benefit of existing programs, that's not useful) and 2) + # because SSL_library_init() is a library routine in some + # versions and a #defined wrapper around OPENSSL_init_ssl() + # in others. + # + if test "x$HAVE_OPENSSL" != "xyes" -a -d "/usr/local/include" -a -d "/usr/local/lib"; then + + save_CFLAGS="$CFLAGS" + save_LIBS="$LIBS" + save_LDFLAGS="$LDFLAGS" + + CFLAGS="$CFLAGS -I/usr/local/include" + LIBS="$LIBS -L/usr/local/lib -lssl -lcrypto" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we have OpenSSL/libressl in /usr/local that we can use" >&5 +$as_echo_n "checking whether we have OpenSSL/libressl in /usr/local that we can use... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main () +{ + +SSL_library_init(); +return 0; + + ; + 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; } + HAVE_OPENSSL=yes + OPENSSL_CFLAGS="-I/usr/local/include" + OPENSSL_LIBS="-L/usr/local/lib -lssl -lcrypto" + OPENSSL_LIBS_STATIC="-L/usr/local/lib -lssl -lcrypto" + OPENSSL_LIBS_PRIVATE="-L/usr/local/lib -lssl -lcrypto" +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_exeext conftest.$ac_ext + CFLAGS="$save_CFLAGS" + LIBS="$save_LIBS" + LDFLAGS="$save_LDFLAGS" -fi - + fi # - # OK, we have crypt(). Do we have getspnam()? + # If it wasn't found, check if it's a system library. # - 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 + # We include the standard include file to 1) make sure that + # it's installed (if it's just a shared library for the + # benefit of existing programs, that's not useful) and 2) + # because SSL_library_init() is a library routine in some + # versions and a #defined wrapper around OPENSSL_init_ssl() + # in others. + # + if test "x$HAVE_OPENSSL" != "xyes"; then -fi -done + save_CFLAGS="$CFLAGS" + save_LIBS="$LIBS" + save_LDFLAGS="$LDFLAGS" + LIBS="$LIBS -lssl -lcrypto" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we have a system OpenSSL/libressl that we can use" >&5 +$as_echo_n "checking whether we have a system OpenSSL/libressl that we can use... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ - # - # 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 +#include -" -if test "x$ac_cv_member_struct_msghdr_msg_control" = xyes; then : +int +main () +{ -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_MSGHDR_MSG_CONTROL 1 +SSL_library_init(); +return 0; + + ; + 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; } + HAVE_OPENSSL=yes + OPENSSL_LIBS="-lssl -lcrypto" + OPENSSL_LIBS_STATIC="-lssl -lcrypto" + OPENSSL_LIBS_PRIVATE="-lssl -lcrypto" +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_exeext conftest.$ac_ext - ac_fn_c_check_member "$LINENO" "struct msghdr" "msg_flags" "ac_cv_member_struct_msghdr_msg_flags" " - #include \"ftmacros.h\" - #include - -" -if test "x$ac_cv_member_struct_msghdr_msg_flags" = xyes; then : + CFLAGS="$save_CFLAGS" + LIBS="$save_LIBS" + LDFLAGS="$save_LDFLAGS" -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_MSGHDR_MSG_FLAGS 1 -_ACEOF + fi + # + # OK, did we find it? + # + if test "x$HAVE_OPENSSL" = "xyes"; then -fi +$as_echo "#define HAVE_OPENSSL 1" >>confdefs.h + V_INCLS="$V_INCLS $OPENSSL_CFLAGS" + ADDITIONAL_LIBS="$ADDITIONAL_LIBS $OPENSSL_LIBS" + ADDITIONAL_LIBS_STATIC="$ADDITIONAL_LIBS_STATIC $OPENSSL_LIBS_STATIC" + LIBS_PRIVATE="$LIBS_PRIVATE $OPENSSL_LIBS_PRIVATE" + REQUIRES_PRIVATE="$REQUIRES_PRIVATE $OPENSSL_REQUIRES_PRIVATE" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: OpenSSL not found" >&5 +$as_echo "$as_me: OpenSSL not found" >&6;} + fi $as_echo "#define ENABLE_REMOTE /**/" >>confdefs.h - SSRC="$SSRC pcap-new.c pcap-rpcap.c rpcap-protocol.c sockutils.c" + REMOTE_C_SRC="$REMOTE_C_SRC pcap-new.c pcap-rpcap.c rpcap-protocol.c sockutils.c sslutils.c" BUILD_RPCAPD=build-rpcapd INSTALL_RPCAPD=install-rpcapd ;; @@ -8096,23 +9850,38 @@ fi $as_echo "$tcpdump_cv_capable_lex" >&6; } if test $tcpdump_cv_capable_lex = insufficient ; then as_fn_error $? "$LEX is insufficient to compile libpcap. - libpcap requires Flex 2.5.31 or later, or a compatible version of lex." "$LINENO" 5 + libpcap requires Flex 2.5.31 or later, or a compatible version of lex. + If a suitable version of Lex/Flex is available as a non-standard command + and/or not in the PATH, you can specify it using the LEX environment + variable. That said, on some systems the error can mean that Flex/Lex is + actually acceptable, but m4 is not. Likewise, if a suitable version of + m4 (such as GNU M4) is available but has not been detected, you can + specify it using the M4 environment variable." "$LINENO" 5 fi # # Look for yacc/bison/byacc. +# If it's Bison, we do not want -y, as 1) we will be using -o to cause +# the output for XXX.y to be written to XXX.c and 2) we don't want +# it to issue warnings about stuff not supported by POSIX YACC - we +# want to use that stuff, and don't care whether plain YACC supports +# it or not, we require either Bison or Berkeley YACC. +# +BISON_BYACC="" # -for ac_prog in 'bison -y' byacc +# Look for Bison. +# +for ac_prog in bison do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_YACC+:} false; then : +if ${ac_cv_prog_BISON_BYACC+:} false; then : $as_echo_n "(cached) " >&6 else - if test -n "$YACC"; then - ac_cv_prog_YACC="$YACC" # Let the user override the test. + if test -n "$BISON_BYACC"; then + ac_cv_prog_BISON_BYACC="$BISON_BYACC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH @@ -8121,7 +9890,7 @@ do test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_YACC="$ac_prog" + ac_cv_prog_BISON_BYACC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -8131,44 +9900,131 @@ IFS=$as_save_IFS fi fi -YACC=$ac_cv_prog_YACC -if test -n "$YACC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5 -$as_echo "$YACC" >&6; } +BISON_BYACC=$ac_cv_prog_BISON_BYACC +if test -n "$BISON_BYACC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BISON_BYACC" >&5 +$as_echo "$BISON_BYACC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi - test -n "$YACC" && break + test -n "$BISON_BYACC" && break +done + +if test x"$BISON_BYACC" != x; then + # + # We found Bison. + # + # Bison prior to 2.4(.1) doesn't support "%define api.pure", so use + # "%pure-parser". + # + bison_major_version=`$BISON_BYACC -V | sed -n 's/.* \([1-9][0-9]*\)\.[0-9][0-9.]*/\1/p'` + bison_minor_version=`$BISON_BYACC -V | sed -n 's/.* [1-9][0-9]*\.\([0-9]+\).*/\1/p'` + if test "$bison_major_version" -lt 2 -o \ + \( "$bison_major_version" -eq 2 -a "$bison_major_version" -lt 4 \) + then + REENTRANT_PARSER="%pure-parser" + else + REENTRANT_PARSER="%define api.pure" + fi +else + # + # We didn't find Bison; check for Berkeley YACC, under the + # names byacc and yacc. + # + for ac_prog in byacc yacc +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_BISON_BYACC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$BISON_BYACC"; then + ac_cv_prog_BISON_BYACC="$BISON_BYACC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_BISON_BYACC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi done -test -n "$YACC" || YACC="yacc" + done +IFS=$as_save_IFS +fi +fi +BISON_BYACC=$ac_cv_prog_BISON_BYACC +if test -n "$BISON_BYACC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BISON_BYACC" >&5 +$as_echo "$BISON_BYACC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi -# -# Make sure it supports the -p flag and supports processing our -# grammar.y. -# -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for capable yacc/bison" >&5 -$as_echo_n "checking for capable yacc/bison... " >&6; } + + test -n "$BISON_BYACC" && break +done + + if test x"$BISON_BYACC" != x; then + # + # Make sure this is Berkeley YACC, not AT&T YACC; + # the latter doesn't support reentrant parsers. + # Run it with "-V"; that succeeds and reports the + # version number with Berkeley YACC, but will + # (probably) fail with various vendor flavors + # of AT&T YACC. + # + # Hopefully this also eliminates any versions + # of Berkeley YACC that don't support reentrant + # parsers, if there are any. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for capable yacc" >&5 +$as_echo_n "checking for capable yacc... " >&6; } if ${tcpdump_cv_capable_yacc+:} false; then : $as_echo_n "(cached) " >&6 else - if $YACC -p pcap_ -o /dev/null $srcdir/grammar.y >/dev/null 2>&1; then - tcpdump_cv_capable_yacc=yes - else - tcpdump_cv_capable_yacc=insufficient - fi + if $BISON_BYACC -V >/dev/null 2>&1; then + tcpdump_cv_capable_yacc=yes + else + tcpdump_cv_capable_yacc=insufficient + fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcpdump_cv_capable_yacc" >&5 $as_echo "$tcpdump_cv_capable_yacc" >&6; } -if test $tcpdump_cv_capable_yacc = insufficient ; then - as_fn_error $? "$YACC is insufficient to compile libpcap. + if test $tcpdump_cv_capable_yacc = insufficient ; then + as_fn_error $? "$BISON_BYACC is insufficient to compile libpcap. + libpcap requires Bison, a newer version of Berkeley YACC with support + for reentrant parsers, or another YACC compatible with them." "$LINENO" 5 + fi + else + # + # OK, we found neither byacc nor yacc. + # + as_fn_error $? "Neither bison, byacc, nor yacc was found. libpcap requires Bison, a newer version of Berkeley YACC with support for reentrant parsers, or another YACC compatible with them." "$LINENO" 5 + fi + + # + # Berkeley YACC doesn't support "%define api.pure", so use + # "%pure-parser". + # + REENTRANT_PARSER="%pure-parser" fi + + # # Do various checks for various OSes and versions of those OSes. # @@ -8266,7 +10122,7 @@ fi V_PROG_LDFLAGS_FAT="-arch ppc -arch ppc64" ;; - darwin8.[456]|darwin.[456].*) + darwin8.[456]|darwin8.[456].*) # # Tiger, subsequent to Intel support but prior # to x86-64 support. Build libraries and @@ -8331,26 +10187,26 @@ fi V_PROG_LDFLAGS_FAT="-arch x86_64 -arch i386" ;; - darwin*) + darwin1[1-8]*) # - # Post-Snow Leopard. Build libraries for x86-64 - # and 32-bit x86, with x86-64 first, and build - # executables only for x86-64. (That's what - # Apple does.) This requires no special flags - # for programs. - # XXX - update if and when Apple drops support - # for 32-bit x86 code and if and when Apple adds - # ARM-based Macs. (You're on your own for iOS - # etc.) - # - # XXX - check whether we *can* build for - # i386 and, if not, suggest that the user - # install the /usr/include headers if they - # want to build fat. + # Post-Snow Leopard, pre-Catalina. Build + # libraries for x86-64 and 32-bit x86, with + # x86-64 first, and build executables only for + # x86-64. (That's what Apple does.) This + # requires no special flags for programs. + # + # We check whether we *can* build for i386 and, + # if not, suggest that the user install the + # /usr/include headers if they want to build + # fat. # { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether building for 32-bit x86 is supported" >&5 $as_echo_n "checking whether building for 32-bit x86 is supported... " >&6; } - save_CFLAGS="$CFLAGS" + + save_CFLAGS="$CFLAGS" + save_LIBS="$LIBS" + save_LDFLAGS="$LDFLAGS" + CFLAGS="$CFLAGS -arch i386" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -8363,12 +10219,24 @@ return 0; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - V_LIB_CCOPT_FAT="-arch x86_64 -arch i386" - V_LIB_LDFLAGS_FAT="-arch x86_64 -arch i386" + V_LIB_CCOPT_FAT="-arch x86_64" + V_LIB_LDFLAGS_FAT="-arch x86_64" + + # + # OpenSSL installation on macOS seems + # to install only the libs for 64-bit + # x86 - at least that's what Brew does: + # only configure 32-bit builds if we + # don't have OpenSSL. + # + if test "$HAVE_OPENSSL" != yes; then + V_LIB_CCOPT_FAT="$V_LIB_CCOPT_FAT -arch i386" + V_LIB_LDFLAGS_FAT="$V_LIB_LDFLAGS_FAT -arch i386" + fi else @@ -8400,8 +10268,97 @@ $as_echo "$as_me: WARNING: Compiling for 32-bit x86 gives an error; try installi esac fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS="$save_CFLAGS" +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + CFLAGS="$save_CFLAGS" + LIBS="$save_LIBS" + LDFLAGS="$save_LDFLAGS" + + ;; + + darwin19*) + # + # Catalina. Build libraries and executables + # only for x86-64. (That's what Apple does; + # 32-bit x86 binaries are not supported on + # Catalina.) + # + V_LIB_CCOPT_FAT="-arch x86_64" + V_LIB_LDFLAGS_FAT="-arch x86_64" + V_PROG_CCOPT_FAT="-arch x86_64" + V_PROG_LDFLAGS_FAT="-arch x86_64" + ;; + + darwin*) + # + # Post-Catalina. Build libraries and + # executables for x86-64 and ARM64. + # (That's what Apple does, except they + # build for arm64e, which may include + # some of the pointer-checking extensions.) + # + # If we're building with libssl, make sure + # we can build fat with it (i.e., that it + # was built fat); if we can't, don't set + # the target architectures, and just + # build for the host we're on. + # + # Otherwise, just add both of them. + # + if test "$HAVE_OPENSSL" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether building fat with libssl is supported" >&5 +$as_echo_n "checking whether building fat with libssl is supported... " >&6; } + + save_CFLAGS="$CFLAGS" + save_LIBS="$LIBS" + save_LDFLAGS="$LDFLAGS" + + CFLAGS="$CFLAGS -arch x86_64 -arch arm64" + LDFLAGS="$LDFLAGS $OPENSSL_LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + +int +main () +{ + + SSL_library_init(); + return 0; + + ; + 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; } + V_LIB_CCOPT_FAT="-arch x86_64 -arch arm64" + V_LIB_LDFLAGS_FAT="-arch x86_64 -arch arm64" + V_PROG_CCOPT_FAT="-arch x86_64 -arch arm64" + V_PROG_LDFLAGS_FAT="-arch x86_64 -arch arm64" + +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_exeext conftest.$ac_ext + + CFLAGS="$save_CFLAGS" + LIBS="$save_LIBS" + LDFLAGS="$save_LDFLAGS" + + else + V_LIB_CCOPT_FAT="-arch x86_64 -arch arm64" + V_LIB_LDFLAGS_FAT="-arch x86_64 -arch arm64" + V_PROG_CCOPT_FAT="-arch x86_64 -arch arm64" + V_PROG_LDFLAGS_FAT="-arch x86_64 -arch arm64" + fi ;; esac fi @@ -8473,23 +10430,15 @@ irix*) MAN_MISC_INFO=5 ;; -linux*|freebsd*|netbsd*|openbsd*|dragonfly*|kfreebsd*|gnu*|midipix*) +linux*|freebsd*|netbsd*|openbsd*|dragonfly*|kfreebsd*|gnu*|haiku*|midipix*) DYEXT="so" - - # - # Compiler assumed to be GCC; run-time linker may require a -R - # flag. - # - if test "$libdir" != "/usr/lib"; then - V_RFLAGS=-Wl,-R$libdir - fi ;; osf*) DYEXT="so" # - # DEC OSF/1, a/k/a Digial UNIX, a/k/a Tru64 UNIX. + # DEC OSF/1, a/k/a Digital 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. @@ -8567,6 +10516,15 @@ $as_echo "#define HAVE_SOLARIS 1" >>confdefs.h ;; esac + + + + + + + + + # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; @@ -8755,94 +10713,66 @@ esac AR=$ac_ct_AR fi else - AR="$ac_cv_prog_AR" -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 -$as_echo_n "checking whether ln -s works... " >&6; } -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 -$as_echo "no, using $LN_S" >&6; } -fi - - - -rm -f os-proto.h - if test "${LBL_CFLAGS+set}" = set; then - V_CCOPT="$V_CCOPT ${LBL_CFLAGS}" - fi - if test -f .devel ; then - # - # Skip all the warning option stuff on some compilers. - # - if test "$ac_lbl_cc_dont_try_gcc_dashW" != yes; then - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler fails when given an unknown warning option" >&5 -$as_echo_n "checking whether the compiler fails when given an unknown warning option... " >&6; } - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Wxyzzy-this-will-never-succeed-xyzzy" - 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: no" >&5 -$as_echo "no" >&6; } - # - # We're assuming this is clang, where - # -Werror=unknown-warning-option is the appropriate - # option to force the compiler to fail. - # - ac_lbl_unknown_warning_option_error="-Werror=unknown-warning-option" - -else + AR="$ac_cv_prog_AR" +fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS="$save_CFLAGS" + +rm -f os-proto.h + if test "${LBL_CFLAGS+set}" = set; then + V_CCOPT="$V_CCOPT ${LBL_CFLAGS}" + fi + if test -f .devel ; then + # + # Skip all the warning option stuff on some compilers. + # + if test "$ac_lbl_cc_dont_try_gcc_dashW" != yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -W option" >&5 $as_echo_n "checking whether the compiler supports the -W option... " >&6; } save_CFLAGS="$CFLAGS" - if expr "x-W" : "x-W.*" >/dev/null - then - CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -W" - elif expr "x-W" : "x-f.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -W" - elif expr "x-W" : "x-m.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -W" - else - CFLAGS="$CFLAGS -W" - fi + CFLAGS="$CFLAGS -W" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -int -main () -{ -return 0 - ; - return 0; -} +int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -8898,33 +10828,42 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag="$save_ac_c_werror_flag" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wall option" >&5 $as_echo_n "checking whether the compiler supports the -Wall option... " >&6; } save_CFLAGS="$CFLAGS" - if expr "x-Wall" : "x-W.*" >/dev/null - then - CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wall" - elif expr "x-Wall" : "x-f.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -Wall" - elif expr "x-Wall" : "x-m.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -Wall" - else - CFLAGS="$CFLAGS -Wall" - fi + CFLAGS="$CFLAGS -Wall" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -int -main () -{ -return 0 - ; - return 0; -} +int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -8980,33 +10919,42 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag="$save_ac_c_werror_flag" { $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 + CFLAGS="$CFLAGS -Wcomma" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -int -main () -{ -return 0 - ; - return 0; -} +int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -9062,33 +11010,42 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag="$save_ac_c_werror_flag" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wdeclaration-after-statement option" >&5 -$as_echo_n "checking whether the compiler supports the -Wdeclaration-after-statement option... " >&6; } + { $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-Wdeclaration-after-statement" : "x-W.*" >/dev/null - then - CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wdeclaration-after-statement" - elif expr "x-Wdeclaration-after-statement" : "x-f.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -Wdeclaration-after-statement" - elif expr "x-Wdeclaration-after-statement" : "x-m.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -Wdeclaration-after-statement" - else - CFLAGS="$CFLAGS -Wdeclaration-after-statement" - fi + CFLAGS="$CFLAGS -Wdocumentation" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -int -main () -{ -return 0 - ; - return 0; -} +int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -9104,8 +11061,8 @@ $as_echo "yes" >&6; } 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; } + { $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. */ @@ -9133,7 +11090,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test x"$can_add_to_cflags" = "xyes" then - V_CCOPT="$V_CCOPT -Wdeclaration-after-statement" + V_CCOPT="$V_CCOPT -Wdocumentation" fi else @@ -9144,33 +11101,42 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag="$save_ac_c_werror_flag" - { $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; } + { $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-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 + CFLAGS="$CFLAGS -Wformat-nonliteral" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -int -main () -{ -return 0 - ; - return 0; -} +int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -9186,8 +11152,8 @@ $as_echo "yes" >&6; } 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; } + { $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. */ @@ -9215,7 +11181,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test x"$can_add_to_cflags" = "xyes" then - V_CCOPT="$V_CCOPT -Wdocumentation" + V_CCOPT="$V_CCOPT -Wformat-nonliteral" fi else @@ -9226,33 +11192,42 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag="$save_ac_c_werror_flag" - { $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; } + { $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-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 + CFLAGS="$CFLAGS -Wmissing-noreturn" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -int -main () -{ -return 0 - ; - return 0; -} +int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -9268,8 +11243,8 @@ $as_echo "yes" >&6; } 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; } + { $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. */ @@ -9297,7 +11272,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test x"$can_add_to_cflags" = "xyes" then - V_CCOPT="$V_CCOPT -Wformat-nonliteral" + V_CCOPT="$V_CCOPT -Wmissing-noreturn" fi else @@ -9308,33 +11283,133 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag="$save_ac_c_werror_flag" - { $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; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wmissing-prototypes option" >&5 +$as_echo_n "checking whether the compiler supports the -Wmissing-prototypes 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 + CFLAGS="$CFLAGS -Wmissing-prototypes" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +int main(void) { return 0; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : -int -main () -{ -return 0 - ; - return 0; -} + { $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" + if test x"$can_add_to_cflags" = "xyes" + then + V_CCOPT="$V_CCOPT -Wmissing-prototypes" + 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 + ac_c_werror_flag="$save_ac_c_werror_flag" + + + { $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" + CFLAGS="$CFLAGS -Wmissing-variable-declarations" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -9350,8 +11425,8 @@ $as_echo "yes" >&6; } 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; } + { $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. */ @@ -9379,7 +11454,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test x"$can_add_to_cflags" = "xyes" then - V_CCOPT="$V_CCOPT -Wmissing-noreturn" + V_CCOPT="$V_CCOPT -Wmissing-variable-declarations" fi else @@ -9390,33 +11465,42 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag="$save_ac_c_werror_flag" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wmissing-prototypes option" >&5 -$as_echo_n "checking whether the compiler supports the -Wmissing-prototypes option... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wpointer-arith option" >&5 +$as_echo_n "checking whether the compiler supports the -Wpointer-arith option... " >&6; } save_CFLAGS="$CFLAGS" - if expr "x-Wmissing-prototypes" : "x-W.*" >/dev/null - then - CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wmissing-prototypes" - elif expr "x-Wmissing-prototypes" : "x-f.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -Wmissing-prototypes" - elif expr "x-Wmissing-prototypes" : "x-m.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -Wmissing-prototypes" - else - CFLAGS="$CFLAGS -Wmissing-prototypes" - fi + CFLAGS="$CFLAGS -Wpointer-arith" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -int -main () -{ -return 0 - ; - return 0; -} +int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -9432,8 +11516,8 @@ $as_echo "yes" >&6; } 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; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wpointer-arith " >&5 +$as_echo_n "checking whether -Wpointer-arith ... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -9461,7 +11545,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test x"$can_add_to_cflags" = "xyes" then - V_CCOPT="$V_CCOPT -Wmissing-prototypes" + V_CCOPT="$V_CCOPT -Wpointer-arith" fi else @@ -9472,33 +11556,42 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag="$save_ac_c_werror_flag" - { $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; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wpointer-sign option" >&5 +$as_echo_n "checking whether the compiler supports the -Wpointer-sign 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 + CFLAGS="$CFLAGS -Wpointer-sign" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -int -main () -{ -return 0 - ; - return 0; -} +int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -9514,8 +11607,8 @@ $as_echo "yes" >&6; } 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; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wpointer-sign " >&5 +$as_echo_n "checking whether -Wpointer-sign ... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -9543,7 +11636,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test x"$can_add_to_cflags" = "xyes" then - V_CCOPT="$V_CCOPT -Wmissing-variable-declarations" + V_CCOPT="$V_CCOPT -Wpointer-sign" fi else @@ -9554,33 +11647,42 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag="$save_ac_c_werror_flag" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wshadow option" >&5 $as_echo_n "checking whether the compiler supports the -Wshadow option... " >&6; } save_CFLAGS="$CFLAGS" - if expr "x-Wshadow" : "x-W.*" >/dev/null - then - CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wshadow" - elif expr "x-Wshadow" : "x-f.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -Wshadow" - elif expr "x-Wshadow" : "x-m.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -Wshadow" - else - CFLAGS="$CFLAGS -Wshadow" - fi + CFLAGS="$CFLAGS -Wshadow" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -int -main () -{ -return 0 - ; - return 0; -} +int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -9636,33 +11738,42 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag="$save_ac_c_werror_flag" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wsign-compare option" >&5 $as_echo_n "checking whether the compiler supports the -Wsign-compare option... " >&6; } save_CFLAGS="$CFLAGS" - if expr "x-Wsign-compare" : "x-W.*" >/dev/null - then - CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wsign-compare" - elif expr "x-Wsign-compare" : "x-f.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -Wsign-compare" - elif expr "x-Wsign-compare" : "x-m.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -Wsign-compare" - else - CFLAGS="$CFLAGS -Wsign-compare" - fi + CFLAGS="$CFLAGS -Wsign-compare" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -int -main () -{ -return 0 - ; - return 0; -} +int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -9718,33 +11829,42 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag="$save_ac_c_werror_flag" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wstrict-prototypes option" >&5 $as_echo_n "checking whether the compiler supports the -Wstrict-prototypes option... " >&6; } save_CFLAGS="$CFLAGS" - if expr "x-Wstrict-prototypes" : "x-W.*" >/dev/null - then - CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wstrict-prototypes" - elif expr "x-Wstrict-prototypes" : "x-f.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -Wstrict-prototypes" - elif expr "x-Wstrict-prototypes" : "x-m.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -Wstrict-prototypes" - else - CFLAGS="$CFLAGS -Wstrict-prototypes" - fi + CFLAGS="$CFLAGS -Wstrict-prototypes" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -int -main () -{ -return 0 - ; - return 0; -} +int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -9800,33 +11920,42 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag="$save_ac_c_werror_flag" { $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 + CFLAGS="$CFLAGS -Wunused-parameter" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -int -main () -{ -return 0 - ; - return 0; -} +int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -9882,33 +12011,42 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag="$save_ac_c_werror_flag" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wused-but-marked-unused option" >&5 $as_echo_n "checking whether the compiler supports the -Wused-but-marked-unused option... " >&6; } save_CFLAGS="$CFLAGS" - if expr "x-Wused-but-marked-unused" : "x-W.*" >/dev/null - then - CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wused-but-marked-unused" - elif expr "x-Wused-but-marked-unused" : "x-f.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -Wused-but-marked-unused" - elif expr "x-Wused-but-marked-unused" : "x-m.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -Wused-but-marked-unused" - else - CFLAGS="$CFLAGS -Wused-but-marked-unused" - fi + CFLAGS="$CFLAGS -Wused-but-marked-unused" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -int -main () -{ -return 0 - ; - return 0; -} +int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -9964,6 +12102,7 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag="$save_ac_c_werror_flag" # Warns about safeguards added in case the enums are # extended @@ -9996,28 +12135,36 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wunreachable-code option" >&5 $as_echo_n "checking whether the compiler supports the -Wunreachable-code option... " >&6; } save_CFLAGS="$CFLAGS" - if expr "x-Wunreachable-code" : "x-W.*" >/dev/null - then - CFLAGS="$CFLAGS $ac_lbl_unknown_warning_option_error -Wunreachable-code" - elif expr "x-Wunreachable-code" : "x-f.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -Wunreachable-code" - elif expr "x-Wunreachable-code" : "x-m.*" >/dev/null - then - CFLAGS="$CFLAGS -Werror -Wunreachable-code" - else - CFLAGS="$CFLAGS -Wunreachable-code" - fi + CFLAGS="$CFLAGS -Wunreachable-code" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -int -main () -{ -return 0 - ; - return 0; -} +int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -10037,13 +12184,104 @@ $as_echo "yes" >&6; } $as_echo_n "checking whether -Wunreachable-code generates warnings from ntohs()... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include - -unsigned short -testme(unsigned short a) -{ - return ntohs(a); -} +#include + +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 + + { $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 + ac_c_werror_flag="$save_ac_c_werror_flag" + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the -Wshorten-64-to-32 option" >&5 +$as_echo_n "checking whether the compiler supports the -Wshorten-64-to-32 option... " >&6; } + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wshorten-64-to-32" + # + # XXX - yes, this depends on the way AC_LANG_WERROR works, + # but no mechanism is provided to turn AC_LANG_WERROR on + # *and then turn it back off*, so that we *only* do it when + # testing compiler options - 15 years after somebody asked + # for it: + # + # https://autoconf.gnu.narkive.com/gTAVmfKD/how-to-cancel-flags-set-by-ac-lang-werror + # + save_ac_c_werror_flag="$ac_c_werror_flag" + ac_c_werror_flag=yes + # + # We use AC_LANG_SOURCE() so that we can control the complete + # content of the program being compiled. We do not, for example, + # want the default "int main()" that AC_LANG_PROGRAM() generates, + # as it will generate a warning with -Wold-style-definition, meaning + # that we would treat it as not working, as the test will fail if + # *any* error output, including a warning due to the flag we're + # testing, is generated; see + # + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # https://www.postgresql.org/message-id/2192993.1591682589%40sss.pgh.pa.us + # + # This may, as per those two messages, be fixed in autoconf 2.70, + # but we only require 2.64 or newer for now. + # + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int main(void) { 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 -Wshorten-64-to-32 " >&5 +$as_echo_n "checking whether -Wshorten-64-to-32 ... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ _ACEOF if ac_fn_c_try_compile "$LINENO"; then : @@ -10069,7 +12307,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" if test x"$can_add_to_cflags" = "xyes" then - V_CCOPT="$V_CCOPT -Wunreachable-code" + V_CCOPT="$V_CCOPT -Wshorten-64-to-32" fi else @@ -10080,6 +12318,7 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag="$save_ac_c_werror_flag" fi @@ -10161,7 +12400,7 @@ _ACEOF { $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" - MKDEP='${srcdir}/mkdep' + MKDEP='${top_srcdir}/mkdep' else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } @@ -10169,7 +12408,7 @@ $as_echo "no" >&6; } # We can't run mkdep, so have "make depend" do # nothing. # - MKDEP='${srcdir}/nomkdep' + MKDEP='${top_srcdir}/nomkdep' fi rm -rf conftest* else @@ -10179,7 +12418,7 @@ $as_echo "no" >&6; } # We can't run mkdep, so have "make depend" do # nothing. # - MKDEP='${srcdir}/nomkdep' + MKDEP='${top_srcdir}/nomkdep' fi @@ -10268,131 +12507,9 @@ _ACEOF fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if unaligned accesses fail" >&5 -$as_echo_n "checking if unaligned accesses fail... " >&6; } - if ${ac_cv_lbl_unaligned_fail+:} false; then : - $as_echo_n "(cached) " >&6 -else - case "$host_cpu" in - - # - # These are CPU types where: - # - # the CPU faults on an unaligned access, but at least some - # OSes that support that CPU catch the fault and simulate - # the unaligned access (e.g., Alpha/{Digital,Tru64} UNIX) - - # the simulation is slow, so we don't want to use it; - # - # the CPU, I infer (from the old - # - # XXX: should also check that they don't do weird things (like on arm) - # - # comment) doesn't fault on unaligned accesses, but doesn't - # do a normal unaligned fetch, either (e.g., presumably, ARM); - # - # for whatever reason, the test program doesn't work - # (this has been claimed to be the case for several of those - # CPUs - I don't know what the problem is; the problem - # was reported as "the test program dumps core" for SuperH, - # but that's what the test program is *supposed* to do - - # it dumps core before it writes anything, so the test - # for an empty output file should find an empty output - # file and conclude that unaligned accesses don't work). - # - # This run-time test won't work if you're cross-compiling, so - # in order to support cross-compiling for a particular CPU, - # we have to wire in the list of CPU types anyway, as far as - # I know, so perhaps we should just have a set of CPUs on - # which we know it doesn't work, a set of CPUs on which we - # know it does work, and have the script just fail on other - # cpu types and update it when such a failure occurs. - # - alpha*|arm*|bfin*|hp*|mips*|sh*|sparc*|ia64|nv1) - ac_cv_lbl_unaligned_fail=yes - ;; - - *) - cat >conftest.c < -# include -# include - unsigned char a[5] = { 1, 2, 3, 4, 5 }; - main() { - unsigned int i; - pid_t pid; - int status; - /* avoid "core dumped" message */ - pid = fork(); - if (pid < 0) - exit(2); - if (pid > 0) { - /* parent */ - pid = waitpid(pid, &status, 0); - if (pid < 0) - exit(3); - exit(!WIFEXITED(status)); - } - /* child */ - i = *(unsigned int *)&a[1]; - printf("%d\n", i); - exit(0); - } -EOF - ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS \ - conftest.c $LIBS >/dev/null 2>&1 - if test ! -x conftest ; then - ac_cv_lbl_unaligned_fail=yes - else - ./conftest >conftest.out - if test ! -s conftest.out ; then - ac_cv_lbl_unaligned_fail=yes - else - ac_cv_lbl_unaligned_fail=no - fi - fi - rm -f -r conftest* core core.conftest - ;; - esac -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lbl_unaligned_fail" >&5 -$as_echo "$ac_cv_lbl_unaligned_fail" >&6; } - if test $ac_cv_lbl_unaligned_fail = yes ; then - -$as_echo "#define LBL_ALIGN 1" >>confdefs.h - - fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# +# Various Linux-specific mechanisms. +# # Check whether --enable-usb was given. if test "${enable_usb+set}" = set; then : enableval=$enable_usb; @@ -10401,39 +12518,38 @@ else fi -if test "xxx_only" = yes; then - # User requested something-else-only pcap, so they don't - # want USB support. - enable_usb=no -fi - -if test "x$enable_usb" != "xno" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for USB sniffing support" >&5 -$as_echo_n "checking for USB sniffing support... " >&6; } - case "$host_os" in - linux*) +# +# If somebody requested an XXX-only pcap, that doesn't include +# additional mechanisms. +# +if test "xxx_only" != yes; then + case "$host_os" in + linux*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Linux usbmon USB sniffing support" >&5 +$as_echo_n "checking for Linux usbmon USB sniffing support... " >&6; } + if test "x$enable_usb" != "xno" ; then -$as_echo "#define PCAP_SUPPORT_USB 1" >>confdefs.h +$as_echo "#define PCAP_SUPPORT_LINUX_USBMON 1" >>confdefs.h - USB_SRC=pcap-usb-linux.c - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + MODULE_C_SRC="$MODULE_C_SRC pcap-usb-linux.c" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - ac_usb_dev_name=`udevinfo -q name -p /sys/class/usb_device/usbmon 2>/dev/null` - if test $? -ne 0 ; then - ac_usb_dev_name="usbmon" - fi - -cat >>confdefs.h <<_ACEOF -#define LINUX_USB_MON_DEV "/dev/$ac_usb_dev_name" -_ACEOF - - { $as_echo "$as_me:${as_lineno-$LINENO}: Device for USB sniffing is /dev/$ac_usb_dev_name" >&5 -$as_echo "$as_me: Device for USB sniffing is /dev/$ac_usb_dev_name" >&6;} - # - # Do we have a version of available? - # If so, we might need it for . - # - for ac_header in linux/compiler.h + # + # Note: if the directory for special files is *EVER* somewhere + # other than the UN*X standard of /dev (which will break any + # software that looks for /dev/null or /dev/tty, for example, + # so doing that is *REALLY* not a good idea), please provide + # some mechanism to determine that directory at *run time*, + # rather than *configure time*, so that it works when doinga + # a cross-build, and that works with *multiple* distributions, + # with our without udev, and with multiple versions of udev, + # with udevinfo or udevadm or any other mechanism to get the + # special files directory. + # + # Do we have a version of available? + # If so, we might need it for . + # + for ac_header in linux/compiler.h do : ac_fn_c_check_header_mongrel "$LINENO" "linux/compiler.h" "ac_cv_header_linux_compiler_h" "$ac_includes_default" if test "x$ac_cv_header_linux_compiler_h" = xyes; then : @@ -10445,11 +12561,11 @@ fi done - if test "$ac_cv_header_linux_compiler_h" = yes; then - # - # Yes - include it when testing for . - # - for ac_header in linux/usbdevice_fs.h + if test "$ac_cv_header_linux_compiler_h" = yes; then + # + # Yes - include it when testing for . + # + for ac_header in linux/usbdevice_fs.h do : ac_fn_c_check_header_compile "$LINENO" "linux/usbdevice_fs.h" "ac_cv_header_linux_usbdevice_fs_h" "#include " @@ -10462,8 +12578,8 @@ fi done - else - for ac_header in linux/usbdevice_fs.h + else + for ac_header in linux/usbdevice_fs.h do : ac_fn_c_check_header_mongrel "$LINENO" "linux/usbdevice_fs.h" "ac_cv_header_linux_usbdevice_fs_h" "$ac_includes_default" if test "x$ac_cv_header_linux_usbdevice_fs_h" = xyes; then : @@ -10475,20 +12591,20 @@ fi done - fi - if test "$ac_cv_header_linux_usbdevice_fs_h" = yes; then - # - # 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". - # - 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 - #endif - #include + fi + if test "$ac_cv_header_linux_usbdevice_fs_h" = yes; then + # + # 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". + # + 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 + #endif + #include " if test "x$ac_cv_member_struct_usbdevfs_ctrltransfer_bRequestType" = xyes; then : @@ -10500,44 +12616,23 @@ _ACEOF fi - fi - ;; - freebsd*) - # - # This just uses BPF in FreeBSD 8.4 and later; we don't need - # to check for anything special for capturing. - # - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes, in FreeBSD 8.4 and later" >&5 -$as_echo "yes, in FreeBSD 8.4 and later" >&6; } - ;; - - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - ;; -esac -fi - - + fi -if test "xxx_only" != yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the platform could support netfilter sniffing" >&5 -$as_echo_n "checking whether the platform could support netfilter sniffing... " >&6; } - case "$host_os" in - linux*) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - # - # 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. - # - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we can compile the netfilter support" >&5 + # + # 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. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we can compile the netfilter support" >&5 $as_echo_n "checking whether we can compile the netfilter support... " >&6; } - if ${ac_cv_netfilter_can_compile+:} false; then : + if ${ac_cv_netfilter_can_compile+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -10569,20 +12664,16 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_netfilter_can_compile" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_netfilter_can_compile" >&5 $as_echo "$ac_cv_netfilter_can_compile" >&6; } - if test $ac_cv_netfilter_can_compile = yes ; then + if test $ac_cv_netfilter_can_compile = yes ; then $as_echo "#define PCAP_SUPPORT_NETFILTER 1" >>confdefs.h - NETFILTER_SRC=pcap-netfilter-linux.c - fi - ;; - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - ;; - esac + MODULE_C_SRC="$MODULE_C_SRC pcap-netfilter-linux.c" + fi + ;; + esac fi @@ -10621,24 +12712,393 @@ 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 +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 + + MODULE_C_SRC="$MODULE_C_SRC pcap-netmap.c" + fi + +fi + +# Check for DPDK support. + +# Check whether --with-dpdk was given. +if test "${with_dpdk+set}" = set; then : + withval=$with_dpdk; + if test "$withval" = no + then + # User doesn't want DPDK support. + want_dpdk=no + elif test "$withval" = yes + then + # User wants DPDK support but hasn't specified a directory. + want_dpdk=yes + else + # User wants DPDK support and has specified a directory, + # so use the provided value. + want_dpdk=yes + dpdk_dir=$withval + fi + +else + + if test "$V_PCAP" = dpdk; then + # User requested DPDK-only libpcap, so we'd better have + # the DPDK API. + want_dpdk=yes + elif test "xxx_only" = yes; then + # User requested something-else-only pcap, so they don't + # want DPDK support. + want_dpdk=no + else + # + # Use DPDK API if present, otherwise don't + # + want_dpdk=ifpresent + fi + +fi + + +if test "$want_dpdk" != no; then + # + # The user didn't explicitly say they don't want DPDK, + # so see if we have it. + # + # We only try to find it using pkg-config; DPDK is *SO* + # complicated - DPDK 19.02, for example, has about 117(!) + # libraries, and the precise set of libraries required has + # changed over time - so attempting to guess which libraries + # you need, and hardcoding that in an attempt to find the + # libraries without DPDK, rather than relying on DPDK to + # tell you, with a .pc file, what libraries are needed, + # is *EXTREMELY* fragile and has caused some bug reports, + # so we're just not going to do it. + # + # If that causes a problem, the only thing we will do is + # accept an alternative way of finding the appropriate + # library set for the installed version of DPDK that is + # as robust as pkg-config (i.e., it had better work as well + # as pkg-config with *ALL* versions of DPDK that provide a + # libdpdk.pc file). + # + # If --with-dpdk={path} was specified, add {path}/pkgconfig + # to PKG_CONFIG_PATH, so we look for the .pc file there, + # first. + # + save_PKG_CONFIG_PATH="$PKG_CONFIG_PATH" + if test -n "$dpdk_dir"; then + PKG_CONFIG_PATH="$dpdk_dir:$PKG_CONFIG_PATH" + fi + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libdpdk with pkg-config" >&5 +$as_echo_n "checking for libdpdk with pkg-config... " >&6; } + +if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdpdk\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libdpdk") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + + # + # The package was found, so try to get its C flags and + # libraries. + # + if test -n "$DPDK_CFLAGS"; then + pkg_cv_DPDK_CFLAGS="$DPDK_CFLAGS" + elif test -n "$PKG_CONFIG"; then + +if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdpdk\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libdpdk") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_DPDK_CFLAGS=`$PKG_CONFIG --cflags "libdpdk" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + if test -n "$DPDK_LIBS"; then + pkg_cv_DPDK_LIBS="$DPDK_LIBS" + elif test -n "$PKG_CONFIG"; then + +if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdpdk\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libdpdk") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_DPDK_LIBS=`$PKG_CONFIG --libs "libdpdk" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + if test -n "$DPDK_LIBS_STATIC"; then + pkg_cv_DPDK_LIBS_STATIC="$DPDK_LIBS_STATIC" + elif test -n "$PKG_CONFIG"; then + +if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdpdk\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libdpdk") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_DPDK_LIBS_STATIC=`$PKG_CONFIG --libs --static "libdpdk" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + + if test $pkg_failed = yes; then + # + # That failed - report an error. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: result: error" >&5 +$as_echo "error" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + DPDK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libdpdk" 2>&1` + else + DPDK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libdpdk" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$DPDK_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (libdpdk) were not met: + +$DPDK_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + + +Alternatively, you may set the environment variables DPDK_CFLAGS +and DPDK_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 + elif test $pkg_failed = untried; then + # + # We don't have pkg-config, so it didn't work. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found (pkg-config not found)" >&5 +$as_echo "not found (pkg-config not found)" >&6; } + else + # + # We found the package. + # + DPDK_CFLAGS=$pkg_cv_DPDK_CFLAGS + DPDK_LIBS=$pkg_cv_DPDK_LIBS + DPDK_LIBS_STATIC=$pkg_cv_DPDK_LIBS_STATIC + { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5 +$as_echo "found" >&6; } + + found_dpdk=yes + + fi +else + + # + # The package isn't present. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 +$as_echo "not found" >&6; } + +fi + + PKG_CONFIG_PATH="$save_PKG_CONFIG_PATH" + + # + # Did we find DPDK? + # + if test "$found_dpdk" = yes; then + # + # Found it. + # + # We call rte_eth_dev_count_avail(), and older versions + # of DPDK didn't have it, so check for it. + # + + save_CFLAGS="$CFLAGS" + save_LIBS="$LIBS" + save_LDFLAGS="$LDFLAGS" + + CFLAGS="$CFLAGS $DPDK_CFLAGS" + LIBS="$LIBS $DPDK_LIBS" + ac_fn_c_check_func "$LINENO" "rte_eth_dev_count_avail" "ac_cv_func_rte_eth_dev_count_avail" +if test "x$ac_cv_func_rte_eth_dev_count_avail" = xyes; then : + +fi + + + CFLAGS="$save_CFLAGS" + LIBS="$save_LIBS" + LDFLAGS="$save_LDFLAGS" + + fi + + if test "$ac_cv_func_rte_eth_dev_count_avail" = yes; then + # + # We found a usable DPDK. + # + # Check whether the rte_ether.h file defines + # struct ether_addr or struct rte_ether_addr. + # + # ("API compatibility? That's for losers!") + # + + save_CFLAGS="$CFLAGS" + save_LIBS="$LIBS" + save_LDFLAGS="$LDFLAGS" + + CFLAGS="$CFLAGS $DPDK_CFLAGS" + LIBS="$LIBS $DPDK_LIBS" + ac_fn_c_check_type "$LINENO" "struct rte_ether_addr" "ac_cv_type_struct_rte_ether_addr" " + #include + +" +if test "x$ac_cv_type_struct_rte_ether_addr" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_RTE_ETHER_ADDR 1 +_ACEOF + + 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 + CFLAGS="$save_CFLAGS" + LIBS="$save_LIBS" + LDFLAGS="$save_LDFLAGS" - NETMAP_SRC=pcap-netmap.c - fi + # + # We can build with DPDK. + # + V_INCLS="$V_INCLS $DPDK_CFLAGS" + ADDITIONAL_LIBS="$ADDITIONAL_LIBS $DPDK_LIBS" + ADDITIONAL_LIBS_STATIC="$ADDITIONAL_LIBS_STATIC $DPDK_LIBS_STATIC" + REQUIRES_PRIVATE="$REQUIRES_PRIVATE libdpdk" + +$as_echo "#define PCAP_SUPPORT_DPDK 1" >>confdefs.h + + if test $V_PCAP != dpdk ; then + MODULE_C_SRC="$MODULE_C_SRC pcap-dpdk.c" + fi + else + # + # We didn't find a usable DPDK. + # If we required it (with --with-dpdk or --with-pcap=dpdk), + # fail with an appropriate message telling the user what + # the problem was, otherwise note the problem with a + # warning. + # + if test "$found_dpdk" != yes; then + # + # Not found with pkg-config. Note that we + # require that DPDK must be findable with + # pkg-config. + # + if test "$V_PCAP" = dpdk; then + # + # User requested DPDK-only capture support. + # + as_fn_error $? "DPDK support requested with --with-pcap=dpdk, but +we couldn't find DPDK with pkg-config. Make sure that pkg-config is +installed, that DPDK 18.02.2 or later is installed, and that DPDK +provides a .pc file." "$LINENO" 5 + fi + + if test "$want_dpdk" = yes; then + # + # User requested that libpcap include + # DPDK capture support. + # + as_fn_error $? "DPDK support requested with --with-dpdk, but we +couldn't find DPDK with pkg-config. Make sure that pkg-config +is installed, that DPDK 18.02.2 or later is installed, and that +DPDK provides .pc file." "$LINENO" 5 + fi + + # + # User didn't indicate whether they wanted DPDK + # or not; just warn why we didn't find it. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: We couldn't find DPDK with pkg-config. If +you want DPDK support, make sure that pkg-config is installed, +that DPDK 18.02.2 or later is installed, and that DPDK provides a +.pc file." >&5 +$as_echo "$as_me: WARNING: We couldn't find DPDK with pkg-config. If +you want DPDK support, make sure that pkg-config is installed, +that DPDK 18.02.2 or later is installed, and that DPDK provides a +.pc file." >&2;} + elif test "$ac_cv_func_rte_eth_dev_count_avail" != yes; then + # + # Found with pkg-config, but we couldn't compile + # a program that calls rte_eth_dev_count(); we + # probably have the developer package installed, + # but don't have a sufficiently recent version + # of DPDK. Note that we need a sufficiently + # recent version of DPDK. + # + if test "$V_PCAP" = dpdk; then + # + # User requested DPDK-only capture support. + # + as_fn_error $? "DPDK support requested with --with-pcap=dpdk, but we +can't compile libpcap with DPDK. Make sure that DPDK 18.02.2 or later +is installed." "$LINENO" 5 + fi + + if test "$want_dpdk" = yes; then + # + # User requested that libpcap include + # DPDK capture support. + # + as_fn_error $? "DPDK support requested with --with-dpdk, but +we can't compile libpcap with DPDK. Make sure that DPDK 18.02.2 +or later is DPDK is installed." "$LINENO" 5 + fi + # + # User didn't indicate whether they wanted DPDK + # or not; just warn why we didn't find it. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: DPDK was found, but we can't compile libpcap with it. +Make sure that DPDK 18.02.2 or later is installed." >&5 +$as_echo "$as_me: WARNING: DPDK was found, but we can't compile libpcap with it. +Make sure that DPDK 18.02.2 or later is installed." >&2;} + fi + fi fi @@ -10669,7 +13129,7 @@ if test "x$ac_cv_header_bluetooth_bluetooth_h" = xyes; then : $as_echo "#define PCAP_SUPPORT_BT 1" >>confdefs.h - BT_SRC=pcap-bt-linux.c + MODULE_C_SRC="$MODULE_C_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 @@ -10721,7 +13181,7 @@ $as_echo "yes" >&6; } $as_echo "#define PCAP_SUPPORT_BT_MONITOR /**/" >>confdefs.h - BT_MONITOR_SRC=pcap-bt-monitor-linux.c + MODULE_C_SRC="$MODULE_C_SRC pcap-bt-monitor-linux.c" else @@ -10763,8 +13223,6 @@ $as_echo "$as_me: no Bluetooth sniffing support implemented for $host_os" >&6;} ;; esac - - fi # Check whether --enable-dbus was given. @@ -10814,66 +13272,138 @@ if test "x$enable_dbus" != "xno"; then fi if test "x$enable_dbus" != "xno"; then - # Extract the first word of "pkg-config", so it can be a program name with args. -set dummy pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_PKGCONFIG+:} false; then : - $as_echo_n "(cached) " >&6 + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dbus-1 with pkg-config" >&5 +$as_echo_n "checking for dbus-1 with pkg-config... " >&6; } + +if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-1\""; } >&5 + ($PKG_CONFIG --exists --print-errors "dbus-1") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + + # + # The package was found, so try to get its C flags and + # libraries. + # + if test -n "$DBUS_CFLAGS"; then + pkg_cv_DBUS_CFLAGS="$DBUS_CFLAGS" + elif test -n "$PKG_CONFIG"; then + +if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-1\""; } >&5 + ($PKG_CONFIG --exists --print-errors "dbus-1") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_DBUS_CFLAGS=`$PKG_CONFIG --cflags "dbus-1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else - if test -n "$PKGCONFIG"; then - ac_cv_prog_PKGCONFIG="$PKGCONFIG" # Let the user override the test. + pkg_failed=yes +fi + else + pkg_failed=untried +fi + if test -n "$DBUS_LIBS"; then + pkg_cv_DBUS_LIBS="$DBUS_LIBS" + elif test -n "$PKG_CONFIG"; then + +if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-1\""; } >&5 + ($PKG_CONFIG --exists --print-errors "dbus-1") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_DBUS_LIBS=`$PKG_CONFIG --libs "dbus-1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_PKGCONFIG="pkg-config" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS + pkg_failed=yes +fi + else + pkg_failed=untried +fi + if test -n "$DBUS_LIBS_STATIC"; then + pkg_cv_DBUS_LIBS_STATIC="$DBUS_LIBS_STATIC" + elif test -n "$PKG_CONFIG"; then - test -z "$ac_cv_prog_PKGCONFIG" && ac_cv_prog_PKGCONFIG="no" +if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-1\""; } >&5 + ($PKG_CONFIG --exists --print-errors "dbus-1") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_DBUS_LIBS_STATIC=`$PKG_CONFIG --libs --static "dbus-1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes fi + else + pkg_failed=untried fi -PKGCONFIG=$ac_cv_prog_PKGCONFIG -if test -n "$PKGCONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKGCONFIG" >&5 -$as_echo "$PKGCONFIG" >&6; } + + + + if test $pkg_failed = yes; then + # + # That failed - report an error. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: result: error" >&5 +$as_echo "error" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + _pkg_short_errors_supported=no fi + if test $_pkg_short_errors_supported = yes; then + DBUS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "dbus-1" 2>&1` + else + DBUS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "dbus-1" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$DBUS_PKG_ERRORS" >&5 - if test "x$PKGCONFIG" != "xno"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for D-Bus" >&5 -$as_echo_n "checking for D-Bus... " >&6; } - if "$PKGCONFIG" dbus-1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - DBUS_CFLAGS=`"$PKGCONFIG" --cflags dbus-1` - DBUS_LIBS=`"$PKGCONFIG" --libs dbus-1` - save_CFLAGS="$CFLAGS" - save_LIBS="$LIBS" - CFLAGS="$CFLAGS $DBUS_CFLAGS" - LIBS="$LIBS $DBUS_LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the D-Bus library defines dbus_connection_read_write" >&5 + if test "x$enable_dbus" = "xyes"; then + as_fn_error $? "--enable-dbus was given, but the dbus-1 package is not installed" "$LINENO" 5 + fi + + elif test $pkg_failed = untried; then + # + # We don't have pkg-config, so it didn't work. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found (pkg-config not found)" >&5 +$as_echo "not found (pkg-config not found)" >&6; } + else + # + # We found the package. + # + DBUS_CFLAGS=$pkg_cv_DBUS_CFLAGS + DBUS_LIBS=$pkg_cv_DBUS_LIBS + DBUS_LIBS_STATIC=$pkg_cv_DBUS_LIBS_STATIC + { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5 +$as_echo "found" >&6; } + + + save_CFLAGS="$CFLAGS" + save_LIBS="$LIBS" + save_LDFLAGS="$LDFLAGS" + + CFLAGS="$CFLAGS $DBUS_CFLAGS" + LIBS="$LIBS $DBUS_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the D-Bus library defines dbus_connection_read_write" >&5 $as_echo_n "checking whether the D-Bus library defines dbus_connection_read_write... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include - #include - #include + #include + #include - #include + #include int main () { @@ -10884,35 +13414,44 @@ return dbus_connection_read_write(NULL, 0); _ACEOF if ac_fn_c_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define PCAP_SUPPORT_DBUS 1" >>confdefs.h - DBUS_SRC=pcap-dbus.c - V_INCLS="$V_INCLS $DBUS_CFLAGS" + MODULE_C_SRC="$MODULE_C_SRC pcap-dbus.c" + V_INCLS="$V_INCLS $DBUS_CFLAGS" + ADDITIONAL_LIBS="$ADDITIONAL_LIBS $DBUS_LIBS" + ADDITIONAL_LIBS_STATIC="$ADDITIONAL_LIBS_STATIC $DBUS_LIBS_STATIC" + REQUIRES_PRIVATE="$REQUIRES_PRIVATE dbus-1" else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - if test "x$enable_dbus" = "xyes"; then - as_fn_error $? "--enable-dbus was given, but the D-Bus library doesn't define dbus_connection_read_write()" "$LINENO" 5 - fi - LIBS="$save_LIBS" + if test "x$enable_dbus" = "xyes"; then + as_fn_error $? "--enable-dbus was given, but the D-Bus library doesn't define dbus_connection_read_write()" "$LINENO" 5 + fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext - CFLAGS="$save_CFLAGS" - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - if test "x$enable_dbus" = "xyes"; then - as_fn_error $? "--enable-dbus was given, but the dbus-1 package is not installed" "$LINENO" 5 - fi - fi + + CFLAGS="$save_CFLAGS" + LIBS="$save_LIBS" + LDFLAGS="$save_LDFLAGS" + + fi +else + + # + # The package isn't present. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 +$as_echo "not found" >&6; } + +fi fi @@ -10932,7 +13471,144 @@ if test "xxx_only" = yes; then fi if test "x$enable_rdma" != "xno"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ibv_get_device_list in -libverbs" >&5 + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libibverbs with pkg-config" >&5 +$as_echo_n "checking for libibverbs with pkg-config... " >&6; } + +if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libibverbs\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libibverbs") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + + # + # The package was found, so try to get its C flags and + # libraries. + # + if test -n "$LIBIBVERBS_CFLAGS"; then + pkg_cv_LIBIBVERBS_CFLAGS="$LIBIBVERBS_CFLAGS" + elif test -n "$PKG_CONFIG"; then + +if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libibverbs\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libibverbs") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBIBVERBS_CFLAGS=`$PKG_CONFIG --cflags "libibverbs" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + if test -n "$LIBIBVERBS_LIBS"; then + pkg_cv_LIBIBVERBS_LIBS="$LIBIBVERBS_LIBS" + elif test -n "$PKG_CONFIG"; then + +if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libibverbs\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libibverbs") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBIBVERBS_LIBS=`$PKG_CONFIG --libs "libibverbs" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + if test -n "$LIBIBVERBS_LIBS_STATIC"; then + pkg_cv_LIBIBVERBS_LIBS_STATIC="$LIBIBVERBS_LIBS_STATIC" + elif test -n "$PKG_CONFIG"; then + +if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libibverbs\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libibverbs") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBIBVERBS_LIBS_STATIC=`$PKG_CONFIG --libs --static "libibverbs" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + + if test $pkg_failed = yes; then + # + # That failed - report an error. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: result: error" >&5 +$as_echo "error" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBIBVERBS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libibverbs" 2>&1` + else + LIBIBVERBS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libibverbs" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBIBVERBS_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (libibverbs) were not met: + +$LIBIBVERBS_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + + +Alternatively, you may set the environment variables LIBIBVERBS_CFLAGS +and LIBIBVERBS_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 + elif test $pkg_failed = untried; then + # + # We don't have pkg-config, so it didn't work. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found (pkg-config not found)" >&5 +$as_echo "not found (pkg-config not found)" >&6; } + else + # + # We found the package. + # + LIBIBVERBS_CFLAGS=$pkg_cv_LIBIBVERBS_CFLAGS + LIBIBVERBS_LIBS=$pkg_cv_LIBIBVERBS_LIBS + LIBIBVERBS_LIBS_STATIC=$pkg_cv_LIBIBVERBS_LIBS_STATIC + { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5 +$as_echo "found" >&6; } + + found_libibverbs=yes + LIBIBVERBS_REQUIRES_PRIVATE="libibverbs" + + fi +else + + # + # The package isn't present. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 +$as_echo "not found" >&6; } + +fi + + + if test "x$found_libibverbs" != "xyes"; 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 @@ -10970,6 +13646,30 @@ fi $as_echo "$ac_cv_lib_ibverbs_ibv_get_device_list" >&6; } if test "x$ac_cv_lib_ibverbs_ibv_get_device_list" = xyes; then : + found_libibverbs=yes + LIBIBVERBS_CFLAGS="" + LIBIBVERBS_LIBS="-libverbs" + # XXX - at least on Ubuntu 20.04, there are many more + # libraries needed; is there any platform where + # libibverbs is available but where pkg-config isn't + # available or libibverbs doesn't use it? If not, + # we should only use pkg-config for it. + LIBIBVERBS_LIBS_STATIC="-libverbs" + LIBIBVERBS_LIBS_PRIVATE="-libverbs" + + +fi + + fi + + if test "x$found_libibverbs" = "xyes"; then + + save_CFLAGS="$CFLAGS" + save_LIBS="$LIBS" + save_LDFLAGS="$LDFLAGS" + + CFLAGS="$CFLAGS $LIBIBVERBS_CFLAGS" + LIBS="$LIBS $LIBIBVERBS_LIBS" 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 : @@ -11006,11 +13706,7 @@ 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" + found_usable_libibverbs=yes else @@ -11026,10 +13722,80 @@ fi + CFLAGS="$save_CFLAGS" + LIBS="$save_LIBS" + LDFLAGS="$save_LDFLAGS" + + fi + + if test "x$found_usable_libibverbs" = "xyes" + then + +$as_echo "#define PCAP_SUPPORT_RDMASNIFF /**/" >>confdefs.h + + MODULE_C_SRC="$MODULE_C_SRC pcap-rdmasniff.c" + CFLAGS="$LIBIBVERBS_CFLAGS $CFLAGS" + ADDITIONAL_LIBS="$LIBIBVERBS_LIBS $ADDITIONAL_LIBS" + ADDITIONAL_LIBS_STATIC="$LIBIBVERBS_LIBS_STATIC $ADDITIONAL_LIBS_STATIC" + LIBS_PRIVATE="$LIBIBVERBS_LIBS_PRIVATE $LIBS_PRIVATE" + REQUIRES_PRIVATE="$REQUIRES_PRIVATE $LIBIBVERBS_REQUIRES_PRIVATE" + fi + fi +# +# If this is a platform where we need to have the .pc file and +# pcap-config script supply an rpath option to specify the directory +# in which the libpcap shared library is installed, and the install +# prefix /usr (meaning we're not installing a system library), provide +# the rpath option. +# +# (We must check $prefix, as $libdir isn't necessarily /usr/lib in this +# case - for example, Linux distributions for 64-bit platforms that +# also provide support for binaries for a 32-bit version of the +# platform may put the 64-bit libraries, the 32-bit libraries, or both +# in directories other than /usr/lib.) +# +# In AIX, do we have to do this? +# +# In Darwin-based OSes, the full paths of the shared libraries with +# which the program was linked are stored in the executable, so we don't +# need to provide an rpath option. +# +# With the HP-UX linker, directories specified with -L are, by default, +# added to the run-time search path, so we don't need to supply them. +# +# For Tru64 UNIX, "-rpath" works with DEC's^WCompaq's^WHP's C compiler +# for Alpha, but isn't documented as working with GCC, and no GCC- +# compatible option is documented as working with the DEC compiler. +# If anybody needs this on Tru64/Alpha, they're welcome to figure out a +# way to make it work. +# +# This must *not* depend on the compiler, as, on platforms where there's +# a GCC-compatible compiler and a vendor compiler, we need to work with +# both. +# +if test "$prefix" != "/usr"; then + case "$host_os" in + freebsd*|netbsd*|openbsd*|dragonfly*|linux*|haiku*|midipix*|gnu*) + # + # Platforms where the "native" C compiler is GCC or + # accepts compatible command-line arguments, and the + # "native" linker is the GNU linker or accepts + # compatible command-line arguments. + # + RPATH="-Wl,-rpath,\${libdir}" + ;; + solaris*) + # + # Sun/Oracle's linker, the GNU linker, and + # GNU-compatible linkers all support -R. + # + RPATH="-Wl,-R,\${libdir}" + ;; + esac fi # Find a good install program. We prefer a C program (faster), @@ -11129,9 +13895,32 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' ac_config_headers="$ac_config_headers config.h" + + + + + + + + + + + + + + + + +# +# We're done with configuration operations; add ADDITIONAL_LIBS and +# ADDITIONAL_LIBS_STATIC to LIBS and LIBS_STATIC, respectively. +# +LIBS="$ADDITIONAL_LIBS $LIBS" +LIBS_STATIC="$ADDITIONAL_LIBS_STATIC $LIBS_STATIC" + 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_immediate_mode.3pcap pcap_set_tstamp_precision.3pcap pcap_set_tstamp_type.3pcap rpcapd/Makefile rpcapd/rpcapd.manadmin rpcapd/rpcapd-config.manfile testprogs/Makefile" +ac_config_files="$ac_config_files Makefile grammar.y 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_immediate_mode.3pcap pcap_set_tstamp_precision.3pcap pcap_set_tstamp_type.3pcap rpcapd/Makefile rpcapd/rpcapd.manadmin rpcapd/rpcapd-config.manfile testprogs/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -11639,7 +14428,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 pcap $as_me 1.9.1, which was +This file was extended by pcap $as_me 1.10.4, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -11705,7 +14494,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="\\ -pcap config.status 1.9.1 +pcap config.status 1.10.4 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -11835,6 +14624,7 @@ do "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "grammar.y") CONFIG_FILES="$CONFIG_FILES grammar.y" ;; "pcap-filter.manmisc") CONFIG_FILES="$CONFIG_FILES pcap-filter.manmisc" ;; "pcap-linktype.manmisc") CONFIG_FILES="$CONFIG_FILES pcap-linktype.manmisc" ;; "pcap-tstamp.manmisc") CONFIG_FILES="$CONFIG_FILES pcap-tstamp.manmisc" ;; @@ -12413,7 +15203,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;} "default-1":C) if test -f .devel; then echo timestamp > stamp-h cat $srcdir/Makefile-devel-adds >> Makefile - make depend + make depend || exit 1 fi ;; esac diff --git a/external/bsd/libpcap/dist/configure.ac b/external/bsd/libpcap/dist/configure.ac index eba2723954a6..ec601c8445e9 100644 --- a/external/bsd/libpcap/dist/configure.ac +++ b/external/bsd/libpcap/dist/configure.ac @@ -8,32 +8,157 @@ dnl # # See # -# http://ftp.gnu.org/gnu/config/README +# https://ftp.gnu.org/gnu/config/README # # for the URLs to use to fetch new versions of config.guess and # config.sub. # -AC_PREREQ(2.64) +AC_PREREQ(2.69) AC_INIT(pcap, m4_esyscmd_s([cat VERSION])) AC_CONFIG_SRCDIR(pcap.c) AC_SUBST(PACKAGE_NAME) +# +# These are the variables that are used in Makefile, pcap-config, and +# libpcap.pc. +# +# CFLAGS: inherited from the environment, not modified by us (except +# temporarily during tests that involve compilation). Used only when +# compiling C source. +# +# CXXFLAGS: inherited from the environment, not modified by us. Used only +# when compiling C++ source. +# +# LDFLAGS: inherited from the environment, not modified by us. +# +# LIBS: inherited from the environment; we add libraries required by +# libpcap. Librares that the core libpcap code requires are added +# first; libraries required by additional pcap modules are first +# added to ADDITIONAL_LIBS, and only added to LIBS at the end, after +# we're finished doing configuration tests for the modules. +# +# LIBS_STATIC: libraries with which a program using the libpcap *static* +# library needs to be linked. This is a superset of LIBS, used in +# pcap-config, so that "pcap-config --libs --static" will report them. +# Initialized to LIBS. +# +# REQUIRES_PRIVATE: pkg-config package names for additional libraries +# with which a program using the libpcap *static* library needs to be +# linked and for which a .pc file exists. This is used in libpcap.pc, +# so that "pkg-config --libs --static" will report them, and so that +# those libraries will be determined using the library's .pc file, not +# from our .pc file. Initialized to an empty string. +# +# V_CCOPT: additional compiler flags other than -I and -D flags +# needed when compiling libpcap. Used in Makefile for both C and +# C++ source. +# +# V_DEFS: additional -D compiler flags needed when compiling +# libpcap. Used in Makefile for both C and C++ source. +# +# V_INCLS: additional -I compiler flags needed when compiling +# libpcap. Used in Makefile for both C and C++ source. +# +# ADDITIONAL_LIBS: additional libraries with which the libpcap dynamic +# library needs to be linked. Used in Makwfile; not used in pcap-config +# or libpcap.pc, as, in all platforms on which we run, if a dynamic +# library is linked with other dynamic libraries, a program using +# that dynamic library doesn't have to link with those libraries - +# they will be automatically loaded at run time. Initialized to an +# empty string. +# +# ADDITIONAL_LIBS_STATIC: additional libraries with which a program +# using the libpcap *static* library needs to be linked. This is used +# in pcap-config, so that "pcap-config --libs --static" will report +# them. Initialized to an empty string. +# +# REQUIRES_PRIVATE: pkg-config package names for additional libraries +# with which a program using the libpcap *static* library needs to be +# linked and for which a .pc file exists. This is used in libpcap.pc, +# so that "pkg-config --libs --static" will report them, and so that +# those libraries will be determined using the library's .pc file, not +# from our .pc file. Initialized to an empty string. +# +# LIBS_PRIVATE: pkg-config package names for additional libraries with +# which a program using the libpcap *static* library needs to be linked +# and for which a .pc file does not exist. This is used in libpcap.pc, +# so that "pkg-config --libs --static" will report them (those libraries +# cannot be determined using the library's .pc file, as there is no such +# file, so it has to come from our .pc file. Initialized to an empty +# string. +# +LIBS_STATIC="" +REQUIRES_PRIVATE="" +LIBS_PRIVATE="" + +AC_SUBST(V_CCOPT) +AC_SUBST(V_DEFS) +AC_SUBST(V_INCLS) +AC_SUBST(LIBS_STATIC) +AC_SUBST(REQUIRES_PRIVATE) +AC_SUBST(LIBS_PRIVATE) + AC_CANONICAL_SYSTEM AC_LBL_C_INIT_BEFORE_CC(V_CCOPT, V_INCLS) # -# Try to enable as many C99 features as we can. -# At minimum, we want C++/C99-style // comments. +# We require C99 or later. +# Try to get it, which may involve adding compiler flags; +# if that fails, give up. # AC_PROG_CC_C99 if test "$ac_cv_prog_cc_c99" = "no"; then - AC_MSG_WARN([The C compiler does not support C99; there may be compiler errors]) + AC_MSG_ERROR([The C compiler does not support C99]) fi + +# +# Get the size of a void *, to determine whether this is a 32-bit +# or 64-bit build. +# +AC_CHECK_SIZEOF([void *]) +ac_lbl_c_sizeof_void_p="$ac_cv_sizeof_void_p" + +# +# We only need a C++ compiler for Haiku; all code except for its +# pcap module is in C. +# +case "$host_os" in +haiku*) + AC_PROG_CXX + + # + # Make sure C and C++ have the same pointer sizes with the flags + # they're given; if they don't, it means that the compilers for the + # languages will, with those flags, not produce code that can be + # linked together. + # + # We have to use different data types, because the results of + # a test are cached, so if we test for the size of a given type + # in C, the subsequent test in C++ will use the cached variable. + # We trick autoconf by testing the size of a "void *" in C and a + # "const void *" in C++. + # + AC_LANG_PUSH([C++]) + AC_CHECK_SIZEOF([const void *]) + ac_lbl_cxx_sizeof_void_p="$ac_cv_sizeof_const_void_p" + AC_LANG_POP([C++]) + if test "$ac_lbl_cxx_sizeof_void_p" -eq 0; then + AC_MSG_ERROR([No C++ compiler was found]) + fi + if test "$ac_lbl_c_sizeof_void_p" -ne "$ac_lbl_cxx_sizeof_void_p"; then + AC_MSG_ERROR([C compiler $CC produces code with $ac_lbl_c_sizeof_void_p-byte pointers +while C++ compiler $CXX produces code with $ac_lbl_cxx_sizeof_void_p-byte pointers. This prevents +code in those languages from being combined.]) + fi + ;; +esac + AC_LBL_C_INIT(V_CCOPT, V_INCLS) AC_LBL_SHLIBS_INIT AC_LBL_C_INLINE +AC_PCAP_C___ATOMICS # # Try to arrange for large file support. @@ -50,41 +175,25 @@ 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/sockio.h limits.h) +AC_CHECK_HEADERS(sys/ioccom.h sys/sockio.h) AC_CHECK_HEADERS(netpacket/packet.h) -AC_CHECK_HEADERS(net/pfvar.h, , , [#include -#include -#include ]) -if test "$ac_cv_header_net_pfvar_h" = yes; then - # - # Check for various PF actions. - # - AC_MSG_CHECKING(whether net/pfvar.h defines PF_NAT through PF_NORDR) - AC_TRY_COMPILE( - [#include - #include - #include - #include ], - [return PF_NAT+PF_NONAT+PF_BINAT+PF_NOBINAT+PF_RDR+PF_NORDR;], - [ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_PF_NAT_THROUGH_PF_NORDR, 1, - [define if net/pfvar.h defines PF_NAT through PF_NORDR]) - ], - AC_MSG_RESULT(no)) -fi +AC_LBL_SAVE_CHECK_STATE case "$host_os" in -linux*|uclinux*) - AC_CHECK_HEADERS(linux/sockios.h linux/if_bonding.h,,, - [ -#include -#include - ]) +haiku*) + # + # Haiku needs _BSD_SOURCE for the _IO* macros because it doesn't use them. + # + CFLAGS="$CFLAGS -D_BSD_SOURCE" + # + # Haiku has getpass in libbsd. + # + AC_CHECK_LIB(bsd, getpass) ;; esac AC_LBL_FIXINCLUDES +AC_LBL_RESTORE_CHECK_STATE AC_CHECK_FUNCS(strerror) AC_CHECK_FUNC(strerror_r, @@ -111,7 +220,7 @@ main(void) ) ], [ - # GNU-style + # GNU-style AC_MSG_RESULT(yes) AC_DEFINE(HAVE_GNU_STRERROR_R,, [Define to 1 if you have a GNU-style `strerror_r' function.]) @@ -124,9 +233,9 @@ main(void) ], [ # - # We don't have strerror_r; do we have strerror_s? + # We don't have strerror_r; do we have _wcserror_s? # - AC_CHECK_FUNCS(strerror_s) + AC_CHECK_FUNCS(_wcserror_s) ]) # @@ -135,45 +244,17 @@ main(void) AC_CHECK_FUNCS(vsyslog) # -# Either: +# Make sure we have vsnprintf() and snprintf(); we require them. # -# we have snprintf() and vsnprintf(), and have asprintf() and -# vasprintf(); -# -# we have snprintf() and vsnprintf(), but don't have asprintf() -# or vasprintf(); -# -# we have neither snprintf() nor vsnprintf(), and don't have -# asprintf() or vasprintf(), either. -# -# We assume that if we have asprintf() we have vasprintf(), as well -# as snprintf() and vsnprintf(), and that if we have snprintf() we -# have vsnprintf(). -# -# For the first case, we don't need any replacement routines. -# For the second case, we need replacement asprintf()/vasprintf() -# routines. -# For the third case, we need replacement snprintf()/vsnprintf() and -# asprintf()/vasprintf() routines. -# -needsnprintf=no -AC_CHECK_FUNCS(vsnprintf snprintf,, - [needsnprintf=yes]) +AC_CHECK_FUNC(vsnprintf,, + AC_MSG_ERROR([vsnprintf() is required but wasn't found])) +AC_CHECK_FUNC(snprintf,, + AC_MSG_ERROR([snprintf() is required but wasn't found])) + needasprintf=no AC_CHECK_FUNCS(vasprintf asprintf,, [needasprintf=yes]) -if test $needsnprintf = yes; then - # - # We assume we have none of them; missing/snprintf.c supplies - # all of them. - # - AC_LIBOBJ([snprintf]) -elif test $needasprintf = yes; then - # - # We assume we have snprintf()/vsnprintf() but lack - # asprintf()/vasprintf(); missing/asprintf.c supplies - # the latter (using vsnprintf()). - # +if test $needasprintf = yes; then AC_LIBOBJ([asprintf]) fi @@ -455,7 +536,7 @@ if test "$ac_cv_func_ether_hostton" = yes; then # This test fails if we don't have # (if we have ether_hostton(), we should have # networking, and if we have networking, we should - # have ) or if we do but it doesn't + # have ) or if we do but it doesn't # declare ether_hostton(). # # Unset ac_cv_have_decl_ether_hostton so we don't @@ -590,7 +671,7 @@ AC_CHECK_HEADER(pthread.h, dnl to pacify those who hate protochain insn AC_MSG_CHECKING(if --disable-protochain option is specified) AC_ARG_ENABLE(protochain, -AC_HELP_STRING([--disable-protochain],[disable \"protochain\" insn])) +AS_HELP_STRING([--disable-protochain],[disable \"protochain\" insn])) case "x$enable_protochain" in xyes) enable_protochain=enabled ;; xno) enable_protochain=disabled ;; @@ -609,22 +690,8 @@ AC_MSG_RESULT(${enable_protochain}) # VALGRINDTEST_SRC= -# -# SITA support is mutually exclusive with native capture support; -# "--with-sita" selects SITA support. -# -AC_ARG_WITH(sita, -AC_HELP_STRING([--with-sita],[include SITA support]), -[ - if test ! "x$withval" = "xno" ; then - AC_DEFINE(SITA,1,[include ACN support]) - AC_MSG_NOTICE(Enabling SITA ACN support) - V_PCAP=sita - fi -], -[ AC_ARG_WITH(pcap, -AC_HELP_STRING([--with-pcap=TYPE],[use packet capture TYPE])) +AS_HELP_STRING([--with-pcap=TYPE],[use packet capture TYPE])) if test ! -z "$with_pcap" ; then V_PCAP="$withval" else @@ -688,6 +755,7 @@ else 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) + AC_CHECK_HEADERS(config/HaikuConfig.h) if test "$ac_cv_lbl_bpf_h_defines_biocsetif" = yes; then # @@ -713,16 +781,11 @@ else # 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 - # + # + # DEC OSF/1, Digital UNIX, Tru64 UNIX + # V_PCAP=pf elif test "$ac_cv_header_net_enet_h" = yes; then # @@ -749,13 +812,18 @@ else # DLPI on pre-Solaris 11 SunOS 5, HP-UX, possibly others. # V_PCAP=dlpi + elif test "$ac_cv_header_config_HaikuConfig_h" = yes; then + # + # Haiku. + # + V_PCAP=haiku 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)) + AC_MSG_WARN((see the INSTALL.md file for more info)) fi fi AC_MSG_CHECKING(packet capture type) @@ -763,15 +831,77 @@ AC_MSG_RESULT($V_PCAP) AC_SUBST(VALGRINDTEST_SRC) # -# Do capture-mechanism-dependent tests. +# Do we have pkg-config? +# +PKG_PROG_PKG_CONFIG + +# +# Do we have the brew command from Homebrew? +# +AC_PATH_PROG([BREW], [brew]) + +# +# Solaris pkg-config is annoying. For at least one package (D-Bus, I'm +# looking at *you*!), there are separate include files for 32-bit and +# 64-bit builds (I guess using "unsigned long long" as a 64-bit integer +# type on a 64-bit build is like crossing the beams or soething), and +# there are two separate .pc files, so if we're doing a 32-bit build we +# should make sure we look in /usr/lib/pkgconfig for .pc files and if +# we're doing a 64-bit build we should make sure we look in +# /usr/lib/amd64/pkgconfig for .pc files. +# +case "$host_os" in + +solaris*) + if test "$ac_cv_sizeof_void_p" -eq 8; then + # + # 64-bit build. If the path is empty, set it to + # /usr/lib/amd64/pkgconfig; otherwise, if + # /usr/lib/pkgconfig appears in the path, prepend + # /usr/lib/amd64/pkgconfig to it; otherwise, put + # /usr/lib/amd64/pkgconfig at the end. + # + if test -z "$PKG_CONFIG_PATH"; then + # + # Not set, or empty. Set it to + # /usr/lib/amd64/pkgconfig. + # + PKG_CONFIG_PATH=/usr/lib/amd64/pkgconfig + elif test ! -z `echo "$PKG_CONFIG_PATH" | grep "/usr/lib/pkgconfig"`; then + # + # It contains /usr/lib/pkgconfig. Prepend + # /usr/lib/amd64/pkgconfig to /usr/lib/pkgconfig. + # + PKG_CONFIG_PATH=`echo "$PKG_CONFIG_PATH" | sed "s;/usr/lib/pkgconfig;/usr/lib/amd64/pkgconfig:/usr/lib/pkgconfig;"` + else + # + # Not empty, but doesn't contain /usr/lib/pkgconfig. + # Append /usr/lib/amd64/pkgconfig to it. + # + PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/lib/amd64/pkgconfig" + fi + export PKG_CONFIG_PATH + elif test "$ac_cv_sizeof_void_p" -eq 4; then + # + # 32-bit build. If /usr/amd64/lib/pkgconfig appears + # in the path, prepend /usr/lib/pkgconfig to it. + # + if test ! -z `echo "$PKG_CONFIG_PATH" | grep "/usr/lib/amd64/pkgconfig"`; then + # + # It contains /usr/lib/amd64/pkgconfig. Prepend + # /usr/lib/pkgconfig to /usr/lib/amd64/pkgconfig. + # + PKG_CONFIG_PATH=`echo "$PKG_CONFIG_PATH" | sed "s;/usr/lib/amd64/pkgconfig;/usr/lib/pkgconfig:/usr/lib/amd64/pkgconfig;"` + export PKG_CONFIG_PATH + fi + fi +esac + +# +# Handle each capture type. # case "$V_PCAP" in dlpi) - # - # Needed for common functions used by pcap-[dlpi,libdlpi].c - # - SSRC="dlpisubs.c" - # # Checks for some header files. # @@ -788,16 +918,32 @@ dlpi) # Also, due to the bug above applications that link to libpcap with # libdlpi will have to add "-L/lib" option to "configure". # - saved_ldflags=$LDFLAGS + save_LDFLAGS="$LDFLAGS" LDFLAGS="$LIBS -L/lib" AC_CHECK_LIB(dlpi, dlpi_walk, [ LIBS="-ldlpi $LIBS" + LIBS_STATIC="-ldlpi $LIBS_STATIC" + LIBS_PRIVATE="-ldlpi $LIBS_PRIVATE" V_PCAP=libdlpi + + # + # Capture module plus common code needed for + # common functions used by pcap-[dlpi,libdlpi].c + # + PLATFORM_C_SRC="pcap-libdlpi.c dlpisubs.c" AC_DEFINE(HAVE_LIBDLPI,1,[if libdlpi exists]) ], - V_PCAP=dlpi) - LDFLAGS=$saved_ldflags + [ + V_PCAP=dlpi + + # + # Capture module plus common code needed for + # common functions used by pcap-[dlpi,libdlpi].c + # + PLATFORM_C_SRC="pcap-dlpi.c dlpisubs.c" + ]) + LDFLAGS="$save_LDFLAGS" # # Checks whether is usable, to catch weird SCO @@ -832,7 +978,31 @@ dlpi) ]) ;; +enet) + # + # Capture module + # + PLATFORM_C_SRC="pcap-enet.c" + ;; + +haiku) + # + # Capture module + # + PLATFORM_CXX_SRC="pcap-haiku.cpp" + + # + # Just for the sake of it. + # + AC_CHECK_HEADERS(net/if.h net/if_dl.h net/if_types.h) + ;; + linux) + # + # Capture module + # + PLATFORM_C_SRC="pcap-linux.c" + # # Do we have the wireless extensions? # @@ -845,107 +1015,74 @@ linux) # # Do we have libnl? + # We only want version 3. Version 2 was, apparently, + # short-lived, and version 1 is source and binary + # incompatible with version 3, and it appears that, + # these days, everybody's using version 3. We're + # not supporting older versions of the Linux kernel; + # let's drop support for older versions of libnl, too. # AC_ARG_WITH(libnl, - AC_HELP_STRING([--without-libnl],[disable libnl support @<:@default=yes, on Linux, if present@:>@]), + AS_HELP_STRING([--without-libnl],[disable libnl support @<:@default=yes, on Linux, if present@:>@]), with_libnl=$withval,with_libnl=if_available) if test x$with_libnl != xno ; then - have_any_nl="no" - - incdir=-I/usr/include/libnl3 - libnldir= - 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. + # Check for libnl-genl-3.0 with pkg-config. # - AC_CHECK_LIB(nl-3, nl_socket_alloc, - [ - # - # Yes, we have libnl 3.x. - # - LIBS="${libnldir} -lnl-genl-3 -lnl-3 $LIBS" + PKG_CHECK_MODULES(LIBNL, libnl-genl-3.0, + [ + pkg_config_found_libnl=yes + V_INCLS="$V_INCLS $LIBNL_CFLAGS" + ADDITIONAL_LIBS="$LIBNL_LIBS $ADDITIONAL_LIBS" + ADDITIONAL_LIBS_STATIC="$LIBNL_LIBS_STATIC $ADDITIONAL_LIBS_STATIC" + REQUIRES_PRIVATE="libnl-genl-3.0 $REQUIRES_PRIVATE" AC_DEFINE(HAVE_LIBNL,1,[if libnl exists]) - AC_DEFINE(HAVE_LIBNL_3_x,1,[if libnl exists and is version 3.x]) - AC_DEFINE(HAVE_LIBNL_NLE,1,[libnl has NLE_FAILURE]) - AC_DEFINE(HAVE_LIBNL_SOCKETS,1,[libnl has new-style socket api]) - V_INCLS="$V_INCLS ${incdir}" - have_any_nl="yes" - ],[], ${incdir} ${libnldir} -lnl-genl-3 -lnl-3 ) + ]) - if test x$have_any_nl = xno ; then + if test x$pkg_config_found_libnl != xyes; then # - # Try libnl 2.x + # OK, either we don't have pkg-config or there + # wasn't a .pc file for it; Check for it directly. # - AC_CHECK_LIB(nl, nl_socket_alloc, + case "$with_libnl" in + + yes|if_available) + incdir=-I/usr/include/libnl3 + libnldir= + ;; + + *) + if test -d $withval; then + libnldir=-L${withval}/lib + incdir=-I${withval}/include + fi + ;; + esac + + AC_CHECK_LIB(nl-3, nl_socket_alloc, [ # - # Yes, we have libnl 2.x. + # Yes, we have libnl 3.x. # - LIBS="${libnldir} -lnl-genl -lnl $LIBS" + ADDITIONAL_LIBS="${libnldir} -lnl-genl-3 -lnl-3 $ADDITIONAL_LIBS" + ADDITIONAL_LIBS_STATIC="${libnldir} -lnl-genl-3 -lnl-3 $ADDITIONAL_LIBS_STATIC" + LIBS_PRIVATE="${libnldir} -lnl-genl-3 -lnl-3 $LIBS_PRIVATE" AC_DEFINE(HAVE_LIBNL,1,[if libnl exists]) - AC_DEFINE(HAVE_LIBNL_2_x,1,[if libnl exists and is version 2.x]) - AC_DEFINE(HAVE_LIBNL_NLE,1,[libnl has NLE_FAILURE]) - AC_DEFINE(HAVE_LIBNL_SOCKETS,1,[libnl has new-style socket api]) - have_any_nl="yes" - ]) - fi - - if test x$have_any_nl = xno ; then - # - # No, we don't; do we have libnl 1.x? - # - AC_CHECK_LIB(nl, nl_handle_alloc, - [ + V_INCLS="$V_INCLS ${incdir}" + ],[ # - # Yes. + # No, we don't have libnl at all. + # Fail if the user explicitly requested + # it. # - LIBS="${libnldir} -lnl $LIBS" - AC_DEFINE(HAVE_LIBNL,1,[if libnl exists]) - have_any_nl="yes" - ]) - fi - - if test x$have_any_nl = xno ; then - # - # No, we don't have libnl at all. - # - if test x$with_libnl = xyes ; then - AC_MSG_ERROR([libnl support requested but libnl not found]) - fi + if test x$with_libnl = xyes ; then + AC_MSG_ERROR([libnl support requested but libnl not found]) + fi + ], ${incdir} ${libnldir} -lnl-genl-3 -lnl-3 ) fi fi - AC_CHECK_HEADERS(linux/ethtool.h,,, - [ -AC_INCLUDES_DEFAULT -#include - ]) - - # - # Check to see if struct tpacket_stats is defined in - # . If so, then pcap-linux.c can use this - # to report proper statistics. - # - # -Scott Barron - # - AC_CHECK_TYPES(struct tpacket_stats,,, - [ - #include - ]) - # # Check to see if the tpacket_auxdata struct has a tp_vlan_tci member. # @@ -962,6 +1099,11 @@ AC_INCLUDES_DEFAULT ;; bpf) + # + # Capture module + # + PLATFORM_C_SRC="pcap-bpf.c" + # # Check whether we have the *BSD-style ioctls. # @@ -981,12 +1123,44 @@ bpf) ]) ;; +pf) + # + # Capture module + # + PLATFORM_C_SRC="pcap-pf.c" + ;; + +snit) + # + # Capture module + # + PLATFORM_C_SRC="pcap-snit.c" + ;; + +snoop) + # + # Capture module + # + PLATFORM_C_SRC="pcap-snoop.c" + ;; + dag) # # --with-pcap=dag is the only way to get here, and it means # "DAG support but nothing else" # V_DEFS="$V_DEFS -DDAG_ONLY" + PLATFORM_C_SRC="pcap-dag.c" + xxx_only=yes + ;; + +dpdk) + # + # --with-pcap=dpdk is the only way to get here, and it means + # "DPDK support but nothing else" + # + V_DEFS="$V_DEFS -DDPDK_ONLY" + PLATFORM_C_SRC="pcap-dpdk.c" xxx_only=yes ;; @@ -996,6 +1170,7 @@ septel) # "Septel support but nothing else" # V_DEFS="$V_DEFS -DSEPTEL_ONLY" + PLATFORM_C_SRC="pcap-septel.c" xxx_only=yes ;; @@ -1005,10 +1180,15 @@ snf) # "SNF support but nothing else" # V_DEFS="$V_DEFS -DSNF_ONLY" + PLATFORM_C_SRC="pcap-snf.c" xxx_only=yes ;; null) + # + # Capture module + # + PLATFORM_C_SRC="pcap-null.c" ;; *) @@ -1033,7 +1213,7 @@ then # We have the header, so we use "getifaddrs()" to # get the list of interfaces. # - V_FINDALLDEVS=fad-getad.c + PLATFORM_C_SRC="$PLATFORM_C_SRC fad-getad.c" ],[ # # We don't have the header - give up. @@ -1077,13 +1257,12 @@ then 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 + PLATFORM_C_SRC="$PLATFORM_C_SRC fad-glifc.c" else - V_FINDALLDEVS=fad-gifc.c + PLATFORM_C_SRC="$PLATFORM_C_SRC fad-gifc.c" fi ]) fi -]) dnl check for hardware timestamp support case "$host_os" in @@ -1095,15 +1274,6 @@ linux*) ;; 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. # @@ -1114,7 +1284,7 @@ AC_CHECK_TYPES(socklen_t,,, ]) AC_ARG_ENABLE(ipv6, -AC_HELP_STRING([--enable-ipv6],[build IPv6-capable version @<:@default=yes@:>@]), +AS_HELP_STRING([--enable-ipv6],[build IPv6-capable version @<:@default=yes@:>@]), [], [enable_ipv6=yes]) if test "$enable_ipv6" != "no"; then @@ -1127,7 +1297,7 @@ fi # Check for Endace DAG card support. AC_ARG_WITH([dag], -AC_HELP_STRING([--with-dag@<:@=DIR@:>@],[include Endace DAG support (located in directory DIR, if supplied). @<:@default=yes, if present@:>@]), +AS_HELP_STRING([--with-dag@<:@=DIR@:>@],[include Endace DAG support (located in directory DIR, if supplied). @<:@default=yes, if present@:>@]), [ if test "$withval" = no then @@ -1160,7 +1330,7 @@ AC_HELP_STRING([--with-dag@<:@=DIR@:>@],[include Endace DAG support (located in ]) AC_ARG_WITH([dag-includes], -AC_HELP_STRING([--with-dag-includes=IDIR],[Endace DAG include directory, if not DIR/include]), +AS_HELP_STRING([--with-dag-includes=IDIR],[Endace DAG include directory, if not DIR/include]), [ # User wants DAG support and has specified a header directory, so use the provided value. want_dag=yes @@ -1168,7 +1338,7 @@ AC_HELP_STRING([--with-dag-includes=IDIR],[Endace DAG include directory, if not ],[]) AC_ARG_WITH([dag-libraries], -AC_HELP_STRING([--with-dag-libraries=LDIR],[Endace DAG library directory, if not DIR/lib]), +AS_HELP_STRING([--with-dag-libraries=LDIR],[Endace DAG library directory, if not DIR/lib]), [ # User wants DAG support and has specified a library directory, so use the provided value. want_dag=yes @@ -1188,57 +1358,77 @@ if test "$want_dag" != no; then if test -z "$dag_lib_dir"; then dag_lib_dir="$dag_root/lib" + # + # Handle multiarch systems. + # + if test -d "$dag_lib_dir/$host" + then + dag_lib_dir="$dag_lib_dir/$host" + fi fi - V_INCLS="$V_INCLS -I$dag_include_dir" - + AC_LBL_SAVE_CHECK_STATE + CFLAGS="$CFLAGS -I$dag_include_dir" AC_CHECK_HEADERS([dagapi.h]) + AC_LBL_RESTORE_CHECK_STATE if test "$ac_cv_header_dagapi_h" = yes; then + V_INCLS="$V_INCLS -I$dag_include_dir" + if test $V_PCAP != dag ; then - SSRC="$SSRC pcap-dag.c" + MODULE_C_SRC="$MODULE_C_SRC pcap-dag.c" fi # 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 + AC_LBL_SAVE_CHECK_STATE LDFLAGS="-L$dag_lib_dir" AC_CHECK_LIB([dag], [dag_attach_stream], - [], + [ + # + # We assume that if we have libdag we have + # libdagconf, as they're installed at the + # same time from the same package. + # + ADDITIONAL_LIBS="-L$dag_lib_dir $ADDITIONAL_LIBS -ldag -ldagconf" + ADDITIONAL_LIBS_STATIC="-L$dag_lib_dir $ADDITIONAL_LIBS_STATIC -ldag -ldagconf" + LIBS_PRIVATE="-L$dag_lib_dir $LIBS_PRIVATE -ldag -ldagconf" + ], [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], [ AC_DEFINE(HAVE_DAG_GET_STREAM_ERF_TYPES, 1, [define if you have dag_get_stream_erf_types()])]) - - LDFLAGS=$saved_ldflags + AC_LBL_RESTORE_CHECK_STATE # # 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_LBL_SAVE_CHECK_STATE + LIBS="$LIBS -ldag -ldagconf" + LDFLAGS="$LDFLAGS -L$dag_lib_dir" AC_CHECK_LIB([vdag],[vdag_set_device_info], [ac_dag_have_vdag="1"], [ac_dag_have_vdag="0"]) + AC_LBL_RESTORE_CHECK_STATE if test "$ac_dag_have_vdag" = 1; then AC_DEFINE(HAVE_DAG_VDAG, 1, [define if you have vdag_set_device_info()]) 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" + ADDITIONAL_LIBS="$ADDITIONAL_LIBS $PTHREAD_LIBS" + ADDITIONAL_LIBS_STATIC="$ADDITIONAL_LIBS_STATIC $PTHREAD_LIBS" + LIBS_PRIVATE="$LIBS_PRIVATE $PTHREAD_LIBS" fi fi AC_DEFINE(HAVE_DAG_API, 1, [define if you have the DAG API]) else - if test "$V_PCAP" = dag; then # User requested "dag" capture type but we couldn't # find the DAG API support. @@ -1246,14 +1436,15 @@ if test "$want_dag" != no; then fi if test "$want_dag" = yes; then - # User wanted DAG support but we couldn't find it. + # User wanted DAG support but we couldn't find it. AC_MSG_ERROR([DAG support requested with --with-dag, but the DAG headers weren't found at $dag_include_dir: make sure the DAG support is installed, specify a different path or paths if necessary, or don't request DAG support]) fi fi + CFLAGS="$save_CFLAGS" fi AC_ARG_WITH(septel, -AC_HELP_STRING([--with-septel@<:@=DIR@:>@],[include Septel support (located in directory DIR, if supplied). @<:@default=yes, if present@:>@]), +AS_HELP_STRING([--with-septel@<:@=DIR@:>@],[include Septel support (located in directory DIR, if supplied). @<:@default=yes, if present@:>@]), [ if test "$withval" = no then @@ -1308,7 +1499,7 @@ if test "$with_septel" != no; then ADDLARCHIVEOBJS="$ADDLARCHIVEOBJS $septel_tools_dir/asciibin.o $septel_tools_dir/bit2byte.o $septel_tools_dir/confirm.o $septel_tools_dir/fmtmsg.o $septel_tools_dir/gct_unix.o $septel_tools_dir/hqueue.o $septel_tools_dir/ident.o $septel_tools_dir/mem.o $septel_tools_dir/pack.o $septel_tools_dir/parse.o $septel_tools_dir/pool.o $septel_tools_dir/sdlsig.o $septel_tools_dir/strtonum.o $septel_tools_dir/timer.o $septel_tools_dir/trace.o" if test "$V_PCAP" != septel ; then - SSRC="$SSRC pcap-septel.c" + MODULE_C_SRC="$MODULE_C_SRC pcap-septel.c" fi AC_DEFINE(HAVE_SEPTEL_API, 1, [define if you have the Septel API]) @@ -1322,7 +1513,7 @@ if test "$with_septel" != no; then fi if test "$want_septel" = yes; then - # User wanted Septel support but we couldn't find it. + # User wanted Septel support but we couldn't find it. AC_MSG_ERROR([Septel support requested with --with-septel, but the Septel headers weren't found at $septel_include_dir: make sure the Septel support is installed, specify a different path or paths if necessary, or don't request Septel support]) fi fi @@ -1330,7 +1521,7 @@ fi # Check for Myricom SNF support. AC_ARG_WITH([snf], -AC_HELP_STRING([--with-snf@<:@=DIR@:>@],[include Myricom SNF support (located in directory DIR, if supplied). @<:@default=yes, if present@:>@]), +AS_HELP_STRING([--with-snf@<:@=DIR@:>@],[include Myricom SNF support (located in directory DIR, if supplied). @<:@default=yes, if present@:>@]), [ if test "$withval" = no then @@ -1363,7 +1554,7 @@ AC_HELP_STRING([--with-snf@<:@=DIR@:>@],[include Myricom SNF support (located in ]) AC_ARG_WITH([snf-includes], -AC_HELP_STRING([--with-snf-includes=IDIR],[Myricom SNF include directory, if not DIR/include]), +AS_HELP_STRING([--with-snf-includes=IDIR],[Myricom SNF include directory, if not DIR/include]), [ # User wants SNF with specific header directory want_snf=yes @@ -1371,7 +1562,7 @@ AC_HELP_STRING([--with-snf-includes=IDIR],[Myricom SNF include directory, if not ],[]) AC_ARG_WITH([snf-libraries], -AC_HELP_STRING([--with-snf-libraries=LDIR],[Myricom SNF library directory, if not DIR/lib]), +AS_HELP_STRING([--with-snf-libraries=LDIR],[Myricom SNF library directory, if not DIR/lib]), [ # User wants SNF with specific lib directory want_snf=yes @@ -1394,14 +1585,21 @@ if test "$with_snf" != no; then if test -z "$snf_lib_dir"; then snf_lib_dir="$snf_root/lib" + # + # Handle multiarch systems. + # + if test -d "$snf_lib_dir/$host" + then + snf_lib_dir="$snf_lib_dir/$host" + fi fi if test -f "$snf_include_dir/snf.h"; then # We found a header; make sure we can link with the library - saved_ldflags=$LDFLAGS + AC_LBL_SAVE_CHECK_STATE LDFLAGS="$LDFLAGS -L$snf_lib_dir" AC_CHECK_LIB([snf], [snf_init], [ac_cv_lbl_snf_api="yes"]) - LDFLAGS="$saved_ldflags" + AC_LBL_RESTORE_CHECK_STATE if test "$ac_cv_lbl_snf_api" = no; then AC_MSG_ERROR(SNF API cannot correctly be linked; check config.log) fi @@ -1411,11 +1609,12 @@ if test "$with_snf" != no; then AC_MSG_RESULT([yes ($snf_root)]) V_INCLS="$V_INCLS -I$snf_include_dir" - LIBS="$LIBS -lsnf" - LDFLAGS="$LDFLAGS -L$snf_lib_dir" + ADDITIONAL_LIBS="$ADDITIONAL_LIBS -L$snf_lib_dir -lsnf" + ADDITIONAL_LIBS_STATIC="$ADDITIONAL_LIBS_STATIC -L$snf_lib_dir -lsnf" + LIBS_PRIVATE="$LIBS_PRIVATE -L$snf_lib_dir -lsnf" if test "$V_PCAP" != snf ; then - SSRC="$SSRC pcap-snf.c" + MODULE_C_SRC="$MODULE_C_SRC pcap-snf.c" fi AC_DEFINE(HAVE_SNF_API, 1, [define if you have the Myricom SNF API]) @@ -1436,7 +1635,7 @@ fi # Check for Riverbed TurboCap support. AC_ARG_WITH([turbocap], -AC_HELP_STRING([--with-turbocap@<:@=DIR@:>@],[include Riverbed TurboCap support (located in directory DIR, if supplied). @<:@default=yes, if present@:>@]), +AS_HELP_STRING([--with-turbocap@<:@=DIR@:>@],[include Riverbed TurboCap support (located in directory DIR, if supplied). @<:@default=yes, if present@:>@]), [ if test "$withval" = no then @@ -1469,12 +1668,12 @@ if test "$want_turbocap" != no; then AC_MSG_CHECKING(whether TurboCap is supported) - save_CFLAGS="$CFLAGS" - save_LIBS="$LIBS" + AC_LBL_SAVE_CHECK_STATE if test ! -z "$turbocap_root"; then TURBOCAP_CFLAGS="-I$turbocap_root/include" - TURBOCAP_LIBS="-L$turbocap_root/lib" + TURBOCAP_LDFLAGS="-L$turbocap_root/lib" CFLAGS="$CFLAGS $TURBOCAP_CFLAGS" + LDFLAGS="$LDFLAGS $TURBOCAP_LDFLAGS" fi AC_TRY_COMPILE( @@ -1488,20 +1687,22 @@ if test "$want_turbocap" != no; then ], ac_cv_lbl_turbocap_api=yes) - CFLAGS="$save_CFLAGS" + AC_LBL_RESTORE_CHECK_STATE if test $ac_cv_lbl_turbocap_api = yes; then AC_MSG_RESULT(yes) - SSRC="$SSRC pcap-tc.c" + MODULE_C_SRC="$MODULE_C_SRC pcap-tc.c" V_INCLS="$V_INCLS $TURBOCAP_CFLAGS" - LIBS="$LIBS $TURBOCAP_LIBS -lTcApi -lpthread -lstdc++" + ADDITIONAL_LIBS="$ADDITIONAL_LIBS $TURBOCAP_LDFLAGS -lTcApi -lpthread -lstdc++" + ADDITIONAL_LIBS_STATIC="$ADDITIONAL_LIBS_STATIC $TURBOCAP_LDFLAGS -lTcApi -lpthread -lstdc++" + LIBS_PRIVATE="$LIBS_PRIVATE $TURBOCAP_LDFLAGS -lTcApi -lpthread -lstdc++" AC_DEFINE(HAVE_TC_API, 1, [define if you have the TurboCap API]) else AC_MSG_RESULT(no) if test "$want_turbocap" = yes; then - # User wanted Turbo support but we couldn't find it. + # User wanted Turbo support but we couldn't find it. AC_MSG_ERROR([TurboCap support requested with --with-turbocap, but the TurboCap headers weren't found: make sure the TurboCap support is installed or don't request TurboCap support]) fi fi @@ -1513,10 +1714,11 @@ 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) +AC_ARG_ENABLE([remote], + [AS_HELP_STRING([--enable-remote], + [enable remote packet capture @<:@default=no@:>@])], + [], + [enableval=no]) case "$enableval" in yes) AC_MSG_RESULT(yes) AC_WARN([Remote packet capture may expose libpcap-based applications]) @@ -1567,9 +1769,165 @@ yes) AC_MSG_RESULT(yes) #include ]) + # + # Optionally, we may want to support SSL. + # Check for OpenSSL/libressl. + # + # First, try looking for it with pkg-config, if we have it. + # + # Homebrew's pkg-config does not, by default, look for + # pkg-config files for packages it has installed. + # Furthermore, at least for OpenSSL, they appear to be + # dumped in package-specific directories whose paths are + # not only package-specific but package-version-specific. + # + # So the only way to find openssl is to get the value of + # PKG_CONFIG_PATH from "brew --env openssl" and add that + # to PKG_CONFIG_PATH. (No, we can't just assume it's under + # /usr/local; Homebrew have conveniently chosen to put it + # under /opt/homebrew on ARM.) + # + # That's the nice thing about Homebrew - it makes things easier! + # Thanks! + # + save_PKG_CONFIG_PATH="$PKG_CONFIG_PATH" + if test -n "$BREW"; then + openssl_pkgconfig_dir=`$BREW --env --plain openssl | sed -n 's/PKG_CONFIG_PATH: //p'` + PKG_CONFIG_PATH="$openssl_pkgconfig_dir:$PKG_CONFIG_PATH" + fi + PKG_CHECK_MODULES(OPENSSL, openssl, + [ + # + # We found OpenSSL/libressl. + # + HAVE_OPENSSL=yes + REQUIRES_PRIVATE="$REQUIRES_PRIVATE openssl" + ]) + PKG_CONFIG_PATH="$save_PKG_CONFIG_PATH" + + # + # If it wasn't found, and we have Homebrew installed, see + # if it's in Homebrew. + # + if test "x$HAVE_OPENSSL" != "xyes" -a -n "$BREW"; then + AC_MSG_CHECKING(for openssl in Homebrew) + # + # The brew man page lies when it speaks of + # $BREW --prefix --installed + # outputting nothing. In Homebrew 3.3.16, + # it produces output regardless of whether + # the formula is installed or not, so we + # send the standard output and error to + # the bit bucket. + # + if $BREW --prefix --installed openssl >/dev/null 2>&1; then + # + # Yes. Get the include directory and library + # directory. (No, we can't just assume it's + # under /usr/local; Homebrew have conveniently + # chosen to put it under /opt/homebrew on ARM.) + # + AC_MSG_RESULT(yes) + HAVE_OPENSSL=yes + openssl_path=`$BREW --prefix openssl` + OPENSSL_CFLAGS="-I$openssl_path/include" + OPENSSL_LIBS="-L$openssl_path/lib -lssl -lcrypto" + OPENSSL_LIBS_STATIC="-L$openssl_path/lib -lssl -lcrypto" + OPENSSL_LIBS_PRIVATE="-L$openssl_path/lib -lssl -lcrypto" + else + AC_MSG_RESULT(no) + fi + fi + + # + # If it wasn't found, and /usr/local/include and /usr/local/lib + # exist, check if it's in /usr/local. (We check whether they + # exist because, if they don't exist, the compiler will warn + # about that and then ignore the argument, so they test + # using just the system header files and libraries.) + # + # We include the standard include file to 1) make sure that + # it's installed (if it's just a shared library for the + # benefit of existing programs, that's not useful) and 2) + # because SSL_library_init() is a library routine in some + # versions and a #defined wrapper around OPENSSL_init_ssl() + # in others. + # + if test "x$HAVE_OPENSSL" != "xyes" -a -d "/usr/local/include" -a -d "/usr/local/lib"; then + AC_LBL_SAVE_CHECK_STATE + CFLAGS="$CFLAGS -I/usr/local/include" + LIBS="$LIBS -L/usr/local/lib -lssl -lcrypto" + AC_MSG_CHECKING(whether we have OpenSSL/libressl in /usr/local that we can use) + AC_TRY_LINK( + [ +#include + ], + [ +SSL_library_init(); +return 0; + ], + [ + AC_MSG_RESULT(yes) + HAVE_OPENSSL=yes + OPENSSL_CFLAGS="-I/usr/local/include" + OPENSSL_LIBS="-L/usr/local/lib -lssl -lcrypto" + OPENSSL_LIBS_STATIC="-L/usr/local/lib -lssl -lcrypto" + OPENSSL_LIBS_PRIVATE="-L/usr/local/lib -lssl -lcrypto" + ], + AC_MSG_RESULT(no)) + AC_LBL_RESTORE_CHECK_STATE + fi + + # + # If it wasn't found, check if it's a system library. + # + # We include the standard include file to 1) make sure that + # it's installed (if it's just a shared library for the + # benefit of existing programs, that's not useful) and 2) + # because SSL_library_init() is a library routine in some + # versions and a #defined wrapper around OPENSSL_init_ssl() + # in others. + # + if test "x$HAVE_OPENSSL" != "xyes"; then + AC_LBL_SAVE_CHECK_STATE + LIBS="$LIBS -lssl -lcrypto" + AC_MSG_CHECKING(whether we have a system OpenSSL/libressl that we can use) + AC_TRY_LINK( + [ +#include + ], + [ +SSL_library_init(); +return 0; + ], + [ + AC_MSG_RESULT(yes) + HAVE_OPENSSL=yes + OPENSSL_LIBS="-lssl -lcrypto" + OPENSSL_LIBS_STATIC="-lssl -lcrypto" + OPENSSL_LIBS_PRIVATE="-lssl -lcrypto" + ], + AC_MSG_RESULT(no)) + AC_LBL_RESTORE_CHECK_STATE + fi + + # + # OK, did we find it? + # + if test "x$HAVE_OPENSSL" = "xyes"; then + AC_DEFINE([HAVE_OPENSSL], [1], [Use OpenSSL]) + V_INCLS="$V_INCLS $OPENSSL_CFLAGS" + ADDITIONAL_LIBS="$ADDITIONAL_LIBS $OPENSSL_LIBS" + ADDITIONAL_LIBS_STATIC="$ADDITIONAL_LIBS_STATIC $OPENSSL_LIBS_STATIC" + LIBS_PRIVATE="$LIBS_PRIVATE $OPENSSL_LIBS_PRIVATE" + REQUIRES_PRIVATE="$REQUIRES_PRIVATE $OPENSSL_REQUIRES_PRIVATE" + else + AC_MSG_NOTICE(OpenSSL not found) + fi + 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" + REMOTE_C_SRC="$REMOTE_C_SRC pcap-new.c pcap-rpcap.c rpcap-protocol.c sockutils.c sslutils.c" BUILD_RPCAPD=build-rpcapd INSTALL_RPCAPD=install-rpcapd ;; @@ -1579,7 +1937,7 @@ 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])) +AS_HELP_STRING([--enable-optimizer-dbg],[build optimizer debugging code])) if test "$enable_optimizer_dbg" = "yes"; then AC_DEFINE(BDEBUG,1,[Enable optimizer debugging]) fi @@ -1587,7 +1945,7 @@ 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])) +AS_HELP_STRING([--enable-yydebug],[build parser debugging code])) if test "$enable_yydebug" = "yes"; then AC_DEFINE(YYDEBUG,1,[Enable parser debugging]) fi @@ -1613,29 +1971,91 @@ AC_CACHE_CHECK([for capable lex], tcpdump_cv_capable_lex, fi) if test $tcpdump_cv_capable_lex = insufficient ; then AC_MSG_ERROR([$LEX is insufficient to compile libpcap. - libpcap requires Flex 2.5.31 or later, or a compatible version of lex.]) + libpcap requires Flex 2.5.31 or later, or a compatible version of lex. + If a suitable version of Lex/Flex is available as a non-standard command + and/or not in the PATH, you can specify it using the LEX environment + variable. That said, on some systems the error can mean that Flex/Lex is + actually acceptable, but m4 is not. Likewise, if a suitable version of + m4 (such as GNU M4) is available but has not been detected, you can + specify it using the M4 environment variable.]) fi # # Look for yacc/bison/byacc. +# If it's Bison, we do not want -y, as 1) we will be using -o to cause +# the output for XXX.y to be written to XXX.c and 2) we don't want +# it to issue warnings about stuff not supported by POSIX YACC - we +# want to use that stuff, and don't care whether plain YACC supports +# it or not, we require either Bison or Berkeley YACC. # -AC_PROG_YACC - +BISON_BYACC="" # -# Make sure it supports the -p flag and supports processing our -# grammar.y. +# Look for Bison. # -AC_CACHE_CHECK([for capable yacc/bison], tcpdump_cv_capable_yacc, - if $YACC -p pcap_ -o /dev/null $srcdir/grammar.y >/dev/null 2>&1; then - tcpdump_cv_capable_yacc=yes +AC_CHECK_PROGS(BISON_BYACC, bison) +if test x"$BISON_BYACC" != x; then + # + # We found Bison. + # + # Bison prior to 2.4(.1) doesn't support "%define api.pure", so use + # "%pure-parser". + # + bison_major_version=`$BISON_BYACC -V | sed -n 's/.* \(@<:@1-9@:>@@<:@0-9@:>@*\)\.@<:@0-9@:>@@<:@0-9.@:>@*/\1/p'` + bison_minor_version=`$BISON_BYACC -V | sed -n 's/.* @<:@1-9@:>@@<:@0-9@:>@*\.\(@<:@0-9@:>@+\).*/\1/p'` + if test "$bison_major_version" -lt 2 -o \ + \( "$bison_major_version" -eq 2 -a "$bison_major_version" -lt 4 \) + then + REENTRANT_PARSER="%pure-parser" else - tcpdump_cv_capable_yacc=insufficient - fi) -if test $tcpdump_cv_capable_yacc = insufficient ; then - AC_MSG_ERROR([$YACC is insufficient to compile libpcap. + REENTRANT_PARSER="%define api.pure" + fi +else + # + # We didn't find Bison; check for Berkeley YACC, under the + # names byacc and yacc. + # + AC_CHECK_PROGS(BISON_BYACC, byacc yacc) + if test x"$BISON_BYACC" != x; then + # + # Make sure this is Berkeley YACC, not AT&T YACC; + # the latter doesn't support reentrant parsers. + # Run it with "-V"; that succeeds and reports the + # version number with Berkeley YACC, but will + # (probably) fail with various vendor flavors + # of AT&T YACC. + # + # Hopefully this also eliminates any versions + # of Berkeley YACC that don't support reentrant + # parsers, if there are any. + # + AC_CACHE_CHECK([for capable yacc], tcpdump_cv_capable_yacc, + if $BISON_BYACC -V >/dev/null 2>&1; then + tcpdump_cv_capable_yacc=yes + else + tcpdump_cv_capable_yacc=insufficient + fi) + if test $tcpdump_cv_capable_yacc = insufficient ; then + AC_MSG_ERROR([$BISON_BYACC is insufficient to compile libpcap. + libpcap requires Bison, a newer version of Berkeley YACC with support + for reentrant parsers, or another YACC compatible with them.]) + fi + else + # + # OK, we found neither byacc nor yacc. + # + AC_MSG_ERROR([Neither bison, byacc, nor yacc was found. libpcap requires Bison, a newer version of Berkeley YACC with support for reentrant parsers, or another YACC compatible with them.]) + fi + + # + # Berkeley YACC doesn't support "%define api.pure", so use + # "%pure-parser". + # + REENTRANT_PARSER="%pure-parser" fi +AC_SUBST(BISON_BYACC) +AC_SUBST(REENTRANT_PARSER) # # Do various checks for various OSes and versions of those OSes. @@ -1698,7 +2118,7 @@ darwin*) DYEXT="dylib" V_CCOPT="$V_CCOPT -fno-common" AC_ARG_ENABLE(universal, - AC_HELP_STRING([--disable-universal],[don't build universal on macOS])) + AS_HELP_STRING([--disable-universal],[don't build universal on macOS])) if test "$enable_universal" != "no"; then case "$host_os" in @@ -1728,7 +2148,7 @@ darwin*) V_PROG_LDFLAGS_FAT="-arch ppc -arch ppc64" ;; - darwin8.[[456]]|darwin.[[456]].*) + darwin8.[[456]]|darwin8.[[456]].*) # # Tiger, subsequent to Intel support but prior # to x86-64 support. Build libraries and @@ -1793,33 +2213,41 @@ darwin*) V_PROG_LDFLAGS_FAT="-arch x86_64 -arch i386" ;; - darwin*) + darwin1[[1-8]]*) + # + # Post-Snow Leopard, pre-Catalina. Build + # libraries for x86-64 and 32-bit x86, with + # x86-64 first, and build executables only for + # x86-64. (That's what Apple does.) This + # requires no special flags for programs. # - # Post-Snow Leopard. Build libraries for x86-64 - # and 32-bit x86, with x86-64 first, and build - # executables only for x86-64. (That's what - # Apple does.) This requires no special flags - # for programs. - # XXX - update if and when Apple drops support - # for 32-bit x86 code and if and when Apple adds - # ARM-based Macs. (You're on your own for iOS - # etc.) - # - # XXX - check whether we *can* build for - # i386 and, if not, suggest that the user - # install the /usr/include headers if they - # want to build fat. + # We check whether we *can* build for i386 and, + # if not, suggest that the user install the + # /usr/include headers if they want to build + # fat. # AC_MSG_CHECKING(whether building for 32-bit x86 is supported) - save_CFLAGS="$CFLAGS" + AC_LBL_SAVE_CHECK_STATE CFLAGS="$CFLAGS -arch i386" - AC_TRY_COMPILE( + AC_TRY_LINK( [], [return 0;], [ AC_MSG_RESULT(yes) - V_LIB_CCOPT_FAT="-arch x86_64 -arch i386" - V_LIB_LDFLAGS_FAT="-arch x86_64 -arch i386" + V_LIB_CCOPT_FAT="-arch x86_64" + V_LIB_LDFLAGS_FAT="-arch x86_64" + + # + # OpenSSL installation on macOS seems + # to install only the libs for 64-bit + # x86 - at least that's what Brew does: + # only configure 32-bit builds if we + # don't have OpenSSL. + # + if test "$HAVE_OPENSSL" != yes; then + V_LIB_CCOPT_FAT="$V_LIB_CCOPT_FAT -arch i386" + V_LIB_LDFLAGS_FAT="$V_LIB_LDFLAGS_FAT -arch i386" + fi ], [ AC_MSG_RESULT(no) @@ -1846,7 +2274,67 @@ darwin*) ;; esac ]) - CFLAGS="$save_CFLAGS" + AC_LBL_RESTORE_CHECK_STATE + ;; + + darwin19*) + # + # Catalina. Build libraries and executables + # only for x86-64. (That's what Apple does; + # 32-bit x86 binaries are not supported on + # Catalina.) + # + V_LIB_CCOPT_FAT="-arch x86_64" + V_LIB_LDFLAGS_FAT="-arch x86_64" + V_PROG_CCOPT_FAT="-arch x86_64" + V_PROG_LDFLAGS_FAT="-arch x86_64" + ;; + + darwin*) + # + # Post-Catalina. Build libraries and + # executables for x86-64 and ARM64. + # (That's what Apple does, except they + # build for arm64e, which may include + # some of the pointer-checking extensions.) + # + # If we're building with libssl, make sure + # we can build fat with it (i.e., that it + # was built fat); if we can't, don't set + # the target architectures, and just + # build for the host we're on. + # + # Otherwise, just add both of them. + # + if test "$HAVE_OPENSSL" = yes; then + AC_MSG_CHECKING(whether building fat with libssl is supported) + AC_LBL_SAVE_CHECK_STATE + CFLAGS="$CFLAGS -arch x86_64 -arch arm64" + LDFLAGS="$LDFLAGS $OPENSSL_LIBS" + AC_TRY_LINK( + [ + #include + ], + [ + SSL_library_init(); + return 0; + ], + [ + AC_MSG_RESULT(yes) + V_LIB_CCOPT_FAT="-arch x86_64 -arch arm64" + V_LIB_LDFLAGS_FAT="-arch x86_64 -arch arm64" + V_PROG_CCOPT_FAT="-arch x86_64 -arch arm64" + V_PROG_LDFLAGS_FAT="-arch x86_64 -arch arm64" + ], + [AC_MSG_RESULT(no)] + ) + AC_LBL_RESTORE_CHECK_STATE + else + V_LIB_CCOPT_FAT="-arch x86_64 -arch arm64" + V_LIB_LDFLAGS_FAT="-arch x86_64 -arch arm64" + V_PROG_CCOPT_FAT="-arch x86_64 -arch arm64" + V_PROG_LDFLAGS_FAT="-arch x86_64 -arch arm64" + fi ;; esac fi @@ -1920,23 +2408,15 @@ irix*) MAN_MISC_INFO=5 ;; -linux*|freebsd*|netbsd*|openbsd*|dragonfly*|kfreebsd*|gnu*|midipix*) +linux*|freebsd*|netbsd*|openbsd*|dragonfly*|kfreebsd*|gnu*|haiku*|midipix*) DYEXT="so" - - # - # Compiler assumed to be GCC; run-time linker may require a -R - # flag. - # - if test "$libdir" != "/usr/lib"; then - V_RFLAGS=-Wl,-R$libdir - fi ;; osf*) DYEXT="so" # - # DEC OSF/1, a/k/a Digial UNIX, a/k/a Tru64 UNIX. + # DEC OSF/1, a/k/a Digital 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. @@ -1991,9 +2471,18 @@ solaris*) esac ;; esac +AC_SUBST(V_LIB_CCOPT_FAT) +AC_SUBST(V_LIB_LDFLAGS_FAT) +AC_SUBST(V_PROG_CCOPT_FAT) +AC_SUBST(V_PROG_LDFLAGS_FAT) +AC_SUBST(DYEXT) +AC_SUBST(MAN_DEVICES) +AC_SUBST(MAN_FILE_FORMATS) +AC_SUBST(MAN_MISC_INFO) +AC_SUBST(MAN_ADMIN_COMMANDS) AC_ARG_ENABLE(shared, -AC_HELP_STRING([--enable-shared],[build shared libraries @<:@default=yes, if support available@:>@])) +AS_HELP_STRING([--enable-shared],[build shared libraries @<:@default=yes, if support available@:>@])) test "x$enable_shared" = "xno" && DYEXT="none" AC_PROG_RANLIB @@ -2040,126 +2529,82 @@ AC_CHECK_MEMBERS([dl_hp_ppa_info_t.dl_module_id_1],,, #include ]) -AC_LBL_UNALIGNED_ACCESS - -AC_SUBST(V_CCOPT) -AC_SUBST(V_LIB_CCOPT_FAT) -AC_SUBST(V_LIB_LDFLAGS_FAT) -AC_SUBST(V_PROG_CCOPT_FAT) -AC_SUBST(V_PROG_LDFLAGS_FAT) -AC_SUBST(V_DEFS) -AC_SUBST(V_FINDALLDEVS) -AC_SUBST(V_INCLS) -AC_SUBST(V_LEX) -AC_SUBST(V_PCAP) -AC_SUBST(V_SHLIB_CCOPT) -AC_SUBST(V_SHLIB_CMD) -AC_SUBST(V_SHLIB_OPT) -AC_SUBST(V_SONAME_OPT) -AC_SUBST(V_RPATH_OPT) -AC_SUBST(V_YACC) -AC_SUBST(ADDLOBJS) -AC_SUBST(ADDLARCHIVEOBJS) -AC_SUBST(SSRC) -AC_SUBST(DYEXT) -AC_SUBST(MAN_DEVICES) -AC_SUBST(MAN_FILE_FORMATS) -AC_SUBST(MAN_MISC_INFO) -AC_SUBST(MAN_ADMIN_COMMANDS) -AC_SUBST(PTHREAD_LIBS) -AC_SUBST(BUILD_RPCAPD) -AC_SUBST(INSTALL_RPCAPD) -AC_SUBST(RPCAPD_LIBS) -AC_SUBST(EXTRA_NETWORK_LIBS) - +# +# Various Linux-specific mechanisms. +# AC_ARG_ENABLE([usb], -[AC_HELP_STRING([--enable-usb],[enable USB capture support @<:@default=yes, if support available@:>@])], +[AS_HELP_STRING([--enable-usb],[enable Linux usbmon USB capture support @<:@default=yes, if support available@:>@])], [], [enable_usb=yes]) -if test "xxx_only" = yes; then - # User requested something-else-only pcap, so they don't - # want USB support. - enable_usb=no -fi - -if test "x$enable_usb" != "xno" ; then - dnl check for USB sniffing support - AC_MSG_CHECKING(for USB sniffing support) - case "$host_os" in - linux*) - AC_DEFINE(PCAP_SUPPORT_USB, 1, [target host supports USB sniffing]) - USB_SRC=pcap-usb-linux.c - AC_MSG_RESULT(yes) - ac_usb_dev_name=`udevinfo -q name -p /sys/class/usb_device/usbmon 2>/dev/null` - if test $? -ne 0 ; then - ac_usb_dev_name="usbmon" - fi - AC_DEFINE_UNQUOTED(LINUX_USB_MON_DEV, "/dev/$ac_usb_dev_name", [path for device for USB sniffing]) - AC_MSG_NOTICE(Device for USB sniffing is /dev/$ac_usb_dev_name) - # - # Do we have a version of available? - # If so, we might need it for . - # - AC_CHECK_HEADERS(linux/compiler.h) - if test "$ac_cv_header_linux_compiler_h" = yes; then - # - # Yes - include it when testing for . - # - AC_CHECK_HEADERS(linux/usbdevice_fs.h,,,[#include ]) - else - AC_CHECK_HEADERS(linux/usbdevice_fs.h) - fi - if test "$ac_cv_header_linux_usbdevice_fs_h" = yes; then - # - # 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". - # - AC_CHECK_MEMBERS([struct usbdevfs_ctrltransfer.bRequestType],,, - [ - AC_INCLUDES_DEFAULT - #ifdef HAVE_LINUX_COMPILER_H - #include - #endif - #include - ]) - fi - ;; - freebsd*) - # - # This just uses BPF in FreeBSD 8.4 and later; we don't need - # to check for anything special for capturing. - # - AC_MSG_RESULT([yes, in FreeBSD 8.4 and later]) - ;; - - *) - AC_MSG_RESULT(no) - ;; -esac -fi -AC_SUBST(PCAP_SUPPORT_USB) -AC_SUBST(USB_SRC) - -dnl check for netfilter sniffing support +# +# If somebody requested an XXX-only pcap, that doesn't include +# additional mechanisms. +# if test "xxx_only" != yes; then - AC_MSG_CHECKING(whether the platform could support netfilter sniffing) - case "$host_os" in - linux*) - AC_MSG_RESULT(yes) - # - # 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. - # - AC_MSG_CHECKING(whether we can compile the netfilter support) - AC_CACHE_VAL(ac_cv_netfilter_can_compile, - AC_TRY_COMPILE([ + case "$host_os" in + linux*) + dnl check for USB sniffing support + AC_MSG_CHECKING(for Linux usbmon USB sniffing support) + if test "x$enable_usb" != "xno" ; then + AC_DEFINE(PCAP_SUPPORT_LINUX_USBMON, 1, [target host supports Linux usbmon for USB sniffing]) + MODULE_C_SRC="$MODULE_C_SRC pcap-usb-linux.c" + AC_MSG_RESULT(yes) + # + # Note: if the directory for special files is *EVER* somewhere + # other than the UN*X standard of /dev (which will break any + # software that looks for /dev/null or /dev/tty, for example, + # so doing that is *REALLY* not a good idea), please provide + # some mechanism to determine that directory at *run time*, + # rather than *configure time*, so that it works when doinga + # a cross-build, and that works with *multiple* distributions, + # with our without udev, and with multiple versions of udev, + # with udevinfo or udevadm or any other mechanism to get the + # special files directory. + # + # Do we have a version of available? + # If so, we might need it for . + # + AC_CHECK_HEADERS(linux/compiler.h) + if test "$ac_cv_header_linux_compiler_h" = yes; then + # + # Yes - include it when testing for . + # + AC_CHECK_HEADERS(linux/usbdevice_fs.h,,,[#include ]) + else + AC_CHECK_HEADERS(linux/usbdevice_fs.h) + fi + if test "$ac_cv_header_linux_usbdevice_fs_h" = yes; then + # + # 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". + # + AC_CHECK_MEMBERS([struct usbdevfs_ctrltransfer.bRequestType],,, + [ + AC_INCLUDES_DEFAULT + #ifdef HAVE_LINUX_COMPILER_H + #include + #endif + #include + ]) + fi + else + AC_MSG_RESULT(no) + fi + + # + # 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. + # + AC_MSG_CHECKING(whether we can compile the netfilter support) + AC_CACHE_VAL(ac_cv_netfilter_can_compile, + AC_TRY_COMPILE([ AC_INCLUDES_DEFAULT #include #include @@ -2170,26 +2615,23 @@ AC_INCLUDES_DEFAULT #include #include #include ], - [], - 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, - [target host supports netfilter sniffing]) - NETFILTER_SRC=pcap-netfilter-linux.c - fi - ;; - *) - AC_MSG_RESULT(no) - ;; - esac + [], + 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, + [target host supports netfilter sniffing]) + MODULE_C_SRC="$MODULE_C_SRC pcap-netfilter-linux.c" + fi + ;; + esac fi +AC_SUBST(PCAP_SUPPORT_LINUX_USBMON) 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@:>@])], +[AS_HELP_STRING([--enable-netmap],[enable netmap support @<:@default=yes, if support available@:>@])], [], [enable_netmap=yes]) @@ -2213,15 +2655,218 @@ AC_INCLUDES_DEFAULT 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 + MODULE_C_SRC="$MODULE_C_SRC pcap-netmap.c" fi AC_SUBST(PCAP_SUPPORT_NETMAP) - AC_SUBST(NETMAP_SRC) fi +# Check for DPDK support. +AC_ARG_WITH([dpdk], +AS_HELP_STRING([--with-dpdk@<:@=DIR@:>@],[include DPDK support (located in directory DIR, if supplied). @<:@default=yes, if present@:>@]), +[ + if test "$withval" = no + then + # User doesn't want DPDK support. + want_dpdk=no + elif test "$withval" = yes + then + # User wants DPDK support but hasn't specified a directory. + want_dpdk=yes + else + # User wants DPDK support and has specified a directory, + # so use the provided value. + want_dpdk=yes + dpdk_dir=$withval + fi +],[ + if test "$V_PCAP" = dpdk; then + # User requested DPDK-only libpcap, so we'd better have + # the DPDK API. + want_dpdk=yes + elif test "xxx_only" = yes; then + # User requested something-else-only pcap, so they don't + # want DPDK support. + want_dpdk=no + else + # + # Use DPDK API if present, otherwise don't + # + want_dpdk=ifpresent + fi +]) + +if test "$want_dpdk" != no; then + # + # The user didn't explicitly say they don't want DPDK, + # so see if we have it. + # + # We only try to find it using pkg-config; DPDK is *SO* + # complicated - DPDK 19.02, for example, has about 117(!) + # libraries, and the precise set of libraries required has + # changed over time - so attempting to guess which libraries + # you need, and hardcoding that in an attempt to find the + # libraries without DPDK, rather than relying on DPDK to + # tell you, with a .pc file, what libraries are needed, + # is *EXTREMELY* fragile and has caused some bug reports, + # so we're just not going to do it. + # + # If that causes a problem, the only thing we will do is + # accept an alternative way of finding the appropriate + # library set for the installed version of DPDK that is + # as robust as pkg-config (i.e., it had better work as well + # as pkg-config with *ALL* versions of DPDK that provide a + # libdpdk.pc file). + # + # If --with-dpdk={path} was specified, add {path}/pkgconfig + # to PKG_CONFIG_PATH, so we look for the .pc file there, + # first. + # + save_PKG_CONFIG_PATH="$PKG_CONFIG_PATH" + if test -n "$dpdk_dir"; then + PKG_CONFIG_PATH="$dpdk_dir:$PKG_CONFIG_PATH" + fi + PKG_CHECK_MODULES(DPDK, libdpdk, + [ + found_dpdk=yes + ]) + PKG_CONFIG_PATH="$save_PKG_CONFIG_PATH" + + # + # Did we find DPDK? + # + if test "$found_dpdk" = yes; then + # + # Found it. + # + # We call rte_eth_dev_count_avail(), and older versions + # of DPDK didn't have it, so check for it. + # + AC_LBL_SAVE_CHECK_STATE + CFLAGS="$CFLAGS $DPDK_CFLAGS" + LIBS="$LIBS $DPDK_LIBS" + AC_CHECK_FUNC(rte_eth_dev_count_avail) + AC_LBL_RESTORE_CHECK_STATE + fi + + if test "$ac_cv_func_rte_eth_dev_count_avail" = yes; then + # + # We found a usable DPDK. + # + # Check whether the rte_ether.h file defines + # struct ether_addr or struct rte_ether_addr. + # + # ("API compatibility? That's for losers!") + # + AC_LBL_SAVE_CHECK_STATE + CFLAGS="$CFLAGS $DPDK_CFLAGS" + LIBS="$LIBS $DPDK_LIBS" + AC_CHECK_TYPES(struct rte_ether_addr,,, + [ + #include + ]) + AC_LBL_RESTORE_CHECK_STATE + + # + # We can build with DPDK. + # + V_INCLS="$V_INCLS $DPDK_CFLAGS" + ADDITIONAL_LIBS="$ADDITIONAL_LIBS $DPDK_LIBS" + ADDITIONAL_LIBS_STATIC="$ADDITIONAL_LIBS_STATIC $DPDK_LIBS_STATIC" + REQUIRES_PRIVATE="$REQUIRES_PRIVATE libdpdk" + AC_DEFINE(PCAP_SUPPORT_DPDK, 1, [target host supports DPDK]) + if test $V_PCAP != dpdk ; then + MODULE_C_SRC="$MODULE_C_SRC pcap-dpdk.c" + fi + else + # + # We didn't find a usable DPDK. + # If we required it (with --with-dpdk or --with-pcap=dpdk), + # fail with an appropriate message telling the user what + # the problem was, otherwise note the problem with a + # warning. + # + if test "$found_dpdk" != yes; then + # + # Not found with pkg-config. Note that we + # require that DPDK must be findable with + # pkg-config. + # + if test "$V_PCAP" = dpdk; then + # + # User requested DPDK-only capture support. + # + AC_MSG_ERROR( +[DPDK support requested with --with-pcap=dpdk, but +we couldn't find DPDK with pkg-config. Make sure that pkg-config is +installed, that DPDK 18.02.2 or later is installed, and that DPDK +provides a .pc file.]) + fi + + if test "$want_dpdk" = yes; then + # + # User requested that libpcap include + # DPDK capture support. + # + AC_MSG_ERROR( +[DPDK support requested with --with-dpdk, but we +couldn't find DPDK with pkg-config. Make sure that pkg-config +is installed, that DPDK 18.02.2 or later is installed, and that +DPDK provides .pc file.]) + fi + + # + # User didn't indicate whether they wanted DPDK + # or not; just warn why we didn't find it. + # + AC_MSG_WARN( +[We couldn't find DPDK with pkg-config. If +you want DPDK support, make sure that pkg-config is installed, +that DPDK 18.02.2 or later is installed, and that DPDK provides a +.pc file.]) + elif test "$ac_cv_func_rte_eth_dev_count_avail" != yes; then + # + # Found with pkg-config, but we couldn't compile + # a program that calls rte_eth_dev_count(); we + # probably have the developer package installed, + # but don't have a sufficiently recent version + # of DPDK. Note that we need a sufficiently + # recent version of DPDK. + # + if test "$V_PCAP" = dpdk; then + # + # User requested DPDK-only capture support. + # + AC_MSG_ERROR( +[DPDK support requested with --with-pcap=dpdk, but we +can't compile libpcap with DPDK. Make sure that DPDK 18.02.2 or later +is installed.]) + fi + + if test "$want_dpdk" = yes; then + # + # User requested that libpcap include + # DPDK capture support. + # + AC_MSG_ERROR( +[DPDK support requested with --with-dpdk, but +we can't compile libpcap with DPDK. Make sure that DPDK 18.02.2 +or later is DPDK is installed.]) + fi + + # + # User didn't indicate whether they wanted DPDK + # or not; just warn why we didn't find it. + # + AC_MSG_WARN( +[DPDK was found, but we can't compile libpcap with it. +Make sure that DPDK 18.02.2 or later is installed.]) + fi + fi +fi +AC_SUBST(PCAP_SUPPORT_DPDK) AC_ARG_ENABLE([bluetooth], -[AC_HELP_STRING([--enable-bluetooth],[enable Bluetooth support @<:@default=yes, if support available@:>@])], +[AS_HELP_STRING([--enable-bluetooth],[enable Bluetooth support @<:@default=yes, if support available@:>@])], [], [enable_bluetooth=ifsupportavailable]) @@ -2242,7 +2887,7 @@ if test "x$enable_bluetooth" != "xno" ; then # sniffing. # AC_DEFINE(PCAP_SUPPORT_BT, 1, [target host supports Bluetooth sniffing]) - BT_SRC=pcap-bt-linux.c + MODULE_C_SRC="$MODULE_C_SRC pcap-bt-linux.c" AC_MSG_NOTICE(Bluetooth sniffing is supported) ac_lbl_bluetooth_available=yes @@ -2269,7 +2914,7 @@ if test "x$enable_bluetooth" != "xno" ; then AC_MSG_RESULT(yes) AC_DEFINE(PCAP_SUPPORT_BT_MONITOR,, [target host supports Bluetooth Monitor]) - BT_MONITOR_SRC=pcap-bt-monitor-linux.c + MODULE_C_SRC="$MODULE_C_SRC pcap-bt-monitor-linux.c" ], [ AC_MSG_RESULT(no) @@ -2301,12 +2946,10 @@ if test "x$enable_bluetooth" != "xno" ; then ;; esac AC_SUBST(PCAP_SUPPORT_BT) - AC_SUBST(BT_SRC) - AC_SUBST(BT_MONITOR_SRC) fi AC_ARG_ENABLE([dbus], -[AC_HELP_STRING([--enable-dbus],[enable D-Bus capture support @<:@default=yes, if support available@:>@])], +[AS_HELP_STRING([--enable-dbus],[enable D-Bus capture support @<:@default=yes, if support available@:>@])], [], [enable_dbus=ifavailable]) @@ -2349,53 +2992,47 @@ if test "x$enable_dbus" != "xno"; then fi if test "x$enable_dbus" != "xno"; then - AC_CHECK_PROG([PKGCONFIG], [pkg-config], [pkg-config], [no]) - if test "x$PKGCONFIG" != "xno"; then - AC_MSG_CHECKING([for D-Bus]) - if "$PKGCONFIG" dbus-1; then - AC_MSG_RESULT([yes]) - DBUS_CFLAGS=`"$PKGCONFIG" --cflags dbus-1` - DBUS_LIBS=`"$PKGCONFIG" --libs dbus-1` - save_CFLAGS="$CFLAGS" - save_LIBS="$LIBS" - CFLAGS="$CFLAGS $DBUS_CFLAGS" - LIBS="$LIBS $DBUS_LIBS" - AC_MSG_CHECKING(whether the D-Bus library defines dbus_connection_read_write) - AC_TRY_LINK( - [#include + PKG_CHECK_MODULES(DBUS, dbus-1, + [ + AC_LBL_SAVE_CHECK_STATE + CFLAGS="$CFLAGS $DBUS_CFLAGS" + LIBS="$LIBS $DBUS_LIBS" + AC_MSG_CHECKING(whether the D-Bus library defines dbus_connection_read_write) + AC_TRY_LINK( + [#include - #include - #include + #include + #include - #include ], - [return dbus_connection_read_write(NULL, 0);], - [ - AC_MSG_RESULT([yes]) - AC_DEFINE(PCAP_SUPPORT_DBUS, 1, [support D-Bus sniffing]) - DBUS_SRC=pcap-dbus.c - V_INCLS="$V_INCLS $DBUS_CFLAGS" - ], - [ - AC_MSG_RESULT([no]) - if test "x$enable_dbus" = "xyes"; then - AC_MSG_ERROR([--enable-dbus was given, but the D-Bus library doesn't define dbus_connection_read_write()]) - fi - LIBS="$save_LIBS" - ]) - CFLAGS="$save_CFLAGS" - else + #include ], + [return dbus_connection_read_write(NULL, 0);], + [ + AC_MSG_RESULT([yes]) + AC_DEFINE(PCAP_SUPPORT_DBUS, 1, [support D-Bus sniffing]) + MODULE_C_SRC="$MODULE_C_SRC pcap-dbus.c" + V_INCLS="$V_INCLS $DBUS_CFLAGS" + ADDITIONAL_LIBS="$ADDITIONAL_LIBS $DBUS_LIBS" + ADDITIONAL_LIBS_STATIC="$ADDITIONAL_LIBS_STATIC $DBUS_LIBS_STATIC" + REQUIRES_PRIVATE="$REQUIRES_PRIVATE dbus-1" + ], + [ AC_MSG_RESULT([no]) if test "x$enable_dbus" = "xyes"; then - AC_MSG_ERROR([--enable-dbus was given, but the dbus-1 package is not installed]) + AC_MSG_ERROR([--enable-dbus was given, but the D-Bus library doesn't define dbus_connection_read_write()]) fi + ]) + AC_LBL_RESTORE_CHECK_STATE + ], + [ + if test "x$enable_dbus" = "xyes"; then + AC_MSG_ERROR([--enable-dbus was given, but the dbus-1 package is not installed]) fi - fi + ]) AC_SUBST(PCAP_SUPPORT_DBUS) - AC_SUBST(DBUS_SRC) fi AC_ARG_ENABLE([rdma], -[AC_HELP_STRING([--enable-rdma],[enable RDMA capture support @<:@default=yes, if support available@:>@])], +[AS_HELP_STRING([--enable-rdma],[enable RDMA capture support @<:@default=yes, if support available@:>@])], [], [enable_rdma=ifavailable]) @@ -2406,7 +3043,33 @@ if test "xxx_only" = yes; then fi if test "x$enable_rdma" != "xno"; then - AC_CHECK_LIB(ibverbs, ibv_get_device_list, [ + PKG_CHECK_MODULES(LIBIBVERBS, libibverbs, + [ + found_libibverbs=yes + LIBIBVERBS_REQUIRES_PRIVATE="libibverbs" + ]) + + if test "x$found_libibverbs" != "xyes"; then + AC_CHECK_LIB(ibverbs, ibv_get_device_list, + [ + found_libibverbs=yes + LIBIBVERBS_CFLAGS="" + LIBIBVERBS_LIBS="-libverbs" + # XXX - at least on Ubuntu 20.04, there are many more + # libraries needed; is there any platform where + # libibverbs is available but where pkg-config isn't + # available or libibverbs doesn't use it? If not, + # we should only use pkg-config for it. + LIBIBVERBS_LIBS_STATIC="-libverbs" + LIBIBVERBS_LIBS_PRIVATE="-libverbs" + ] + ) + fi + + if test "x$found_libibverbs" = "xyes"; then + AC_LBL_SAVE_CHECK_STATE + CFLAGS="$CFLAGS $LIBIBVERBS_CFLAGS" + LIBS="$LIBS $LIBIBVERBS_LIBS" AC_CHECK_HEADER(infiniband/verbs.h, [ # # ibv_create_flow may be defined as a static inline @@ -2430,30 +3093,117 @@ if test "x$enable_rdma" != "xno"; then ], [ AC_MSG_RESULT([yes]) - AC_DEFINE(PCAP_SUPPORT_RDMASNIFF, , [target host supports RDMA sniffing]) - RDMA_SRC=pcap-rdmasniff.c - LIBS="-libverbs $LIBS" + found_usable_libibverbs=yes ], [ AC_MSG_RESULT([no]) ] ) ]) - ]) + AC_LBL_RESTORE_CHECK_STATE + fi + + if test "x$found_usable_libibverbs" = "xyes" + then + AC_DEFINE(PCAP_SUPPORT_RDMASNIFF, , [target host supports RDMA sniffing]) + MODULE_C_SRC="$MODULE_C_SRC pcap-rdmasniff.c" + CFLAGS="$LIBIBVERBS_CFLAGS $CFLAGS" + ADDITIONAL_LIBS="$LIBIBVERBS_LIBS $ADDITIONAL_LIBS" + ADDITIONAL_LIBS_STATIC="$LIBIBVERBS_LIBS_STATIC $ADDITIONAL_LIBS_STATIC" + LIBS_PRIVATE="$LIBIBVERBS_LIBS_PRIVATE $LIBS_PRIVATE" + REQUIRES_PRIVATE="$REQUIRES_PRIVATE $LIBIBVERBS_REQUIRES_PRIVATE" + fi AC_SUBST(PCAP_SUPPORT_RDMASNIFF) - AC_SUBST(RDMA_SRC) +fi + +# +# If this is a platform where we need to have the .pc file and +# pcap-config script supply an rpath option to specify the directory +# in which the libpcap shared library is installed, and the install +# prefix /usr (meaning we're not installing a system library), provide +# the rpath option. +# +# (We must check $prefix, as $libdir isn't necessarily /usr/lib in this +# case - for example, Linux distributions for 64-bit platforms that +# also provide support for binaries for a 32-bit version of the +# platform may put the 64-bit libraries, the 32-bit libraries, or both +# in directories other than /usr/lib.) +# +# In AIX, do we have to do this? +# +# In Darwin-based OSes, the full paths of the shared libraries with +# which the program was linked are stored in the executable, so we don't +# need to provide an rpath option. +# +# With the HP-UX linker, directories specified with -L are, by default, +# added to the run-time search path, so we don't need to supply them. +# +# For Tru64 UNIX, "-rpath" works with DEC's^WCompaq's^WHP's C compiler +# for Alpha, but isn't documented as working with GCC, and no GCC- +# compatible option is documented as working with the DEC compiler. +# If anybody needs this on Tru64/Alpha, they're welcome to figure out a +# way to make it work. +# +# This must *not* depend on the compiler, as, on platforms where there's +# a GCC-compatible compiler and a vendor compiler, we need to work with +# both. +# +if test "$prefix" != "/usr"; then + case "$host_os" in + + freebsd*|netbsd*|openbsd*|dragonfly*|linux*|haiku*|midipix*|gnu*) + # + # Platforms where the "native" C compiler is GCC or + # accepts compatible command-line arguments, and the + # "native" linker is the GNU linker or accepts + # compatible command-line arguments. + # + RPATH="-Wl,-rpath,\${libdir}" + ;; + + solaris*) + # + # Sun/Oracle's linker, the GNU linker, and + # GNU-compatible linkers all support -R. + # + RPATH="-Wl,-R,\${libdir}" + ;; + esac fi AC_PROG_INSTALL AC_CONFIG_HEADER(config.h) +AC_SUBST(V_SHLIB_CCOPT) +AC_SUBST(V_SHLIB_CMD) +AC_SUBST(V_SHLIB_OPT) +AC_SUBST(V_SONAME_OPT) +AC_SUBST(RPATH) +AC_SUBST(ADDLOBJS) +AC_SUBST(ADDLARCHIVEOBJS) +AC_SUBST(PLATFORM_C_SRC) +AC_SUBST(PLATFORM_CXX_SRC) +AC_SUBST(MODULE_C_SRC) +AC_SUBST(REMOTE_C_SRC) +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(BUILD_RPCAPD) +AC_SUBST(INSTALL_RPCAPD) +AC_SUBST(RPCAPD_LIBS) + +# +# We're done with configuration operations; add ADDITIONAL_LIBS and +# ADDITIONAL_LIBS_STATIC to LIBS and LIBS_STATIC, respectively. +# +LIBS="$ADDITIONAL_LIBS $LIBS" +LIBS_STATIC="$ADDITIONAL_LIBS_STATIC $LIBS_STATIC" + AC_OUTPUT_COMMANDS([if test -f .devel; then echo timestamp > stamp-h cat $srcdir/Makefile-devel-adds >> Makefile - make depend + make depend || exit 1 fi]) -AC_OUTPUT(Makefile pcap-filter.manmisc pcap-linktype.manmisc +AC_OUTPUT(Makefile grammar.y 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 diff --git a/external/bsd/libpcap/dist/diag-control.h b/external/bsd/libpcap/dist/diag-control.h index cfc581b37b57..ae2641b45969 100644 --- a/external/bsd/libpcap/dist/diag-control.h +++ b/external/bsd/libpcap/dist/diag-control.h @@ -37,35 +37,56 @@ #include "pcap/compiler-tests.h" -#ifndef _MSC_VER +#if PCAP_IS_AT_LEAST_CLANG_VERSION(2,8) || PCAP_IS_AT_LEAST_GNUC_VERSION(4,6) /* * 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. + * We use it only if we have a compiler that supports it; see below + * for the code that uses it and the #defines that control whether + * that code is used. */ #define PCAP_DO_PRAGMA(x) _Pragma (#x) #endif /* - * Suppress Flex warnings. + * Suppress "enum value not explicitly handled in switch" warnings. + * We may have to build on multiple different Windows SDKs, so we + * may not be able to include all enum values in a switch, as they + * won't necessarily be defined on all the SDKs, and, unlike + * #defines, there's no easy way to test whether a given enum has + * a given value. It *could* be done by the configure script or + * CMake tests. */ #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 \ + #define DIAG_OFF_ENUM_SWITCH \ __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) + __pragma(warning(disable:4061)) + #define DIAG_ON_ENUM_SWITCH \ + __pragma(warning(pop)) +#else + #define DIAG_OFF_ENUM_SWITCH + #define DIAG_ON_ENUM_SWITCH +#endif + +/* + * Suppress "switch statement has only a default case" warnings. + * There's a switch in bpf_filter.c that only has additional + * cases on Linux. + */ +#if defined(_MSC_VER) + #define DIAG_OFF_DEFAULT_ONLY_SWITCH \ + __pragma(warning(push)) \ + __pragma(warning(disable:4065)) + #define DIAG_ON_DEFAULT_ONLY_SWITCH \ + __pragma(warning(pop)) +#else + #define DIAG_OFF_DEFAULT_ONLY_SWITCH + #define DIAG_ON_DEFAULT_ONLY_SWITCH +#endif + +/* + * Suppress Flex, narrowing, and deprecation warnings. + */ +#if 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". @@ -74,16 +95,78 @@ * at least according to the GCC 7.3 documentation. Apparently, Flex * generates code that upsets at least some versions of Clang's * -Wdocumentation. + * + * (This could be clang-cl, which defines _MSC_VER, so test this + * before testing _MSC_VER.) */ #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 "-Wshorten-64-to-32") \ 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) + + /* + * Suppress the only narrowing warnings you get from Clang. + */ + #define DIAG_OFF_NARROWING \ + PCAP_DO_PRAGMA(clang diagnostic push) \ + PCAP_DO_PRAGMA(clang diagnostic ignored "-Wshorten-64-to-32") + + #define DIAG_ON_NARROWING \ + PCAP_DO_PRAGMA(clang diagnostic pop) + + /* + * Suppress deprecation warnings. + */ + #define DIAG_OFF_DEPRECATION \ + PCAP_DO_PRAGMA(clang diagnostic push) \ + PCAP_DO_PRAGMA(clang diagnostic ignored "-Wdeprecated-declarations") + #define DIAG_ON_DEPRECATION \ + PCAP_DO_PRAGMA(clang diagnostic pop) + #define DIAG_OFF_FORMAT_TRUNCATION + #define DIAG_ON_FORMAT_TRUNCATION +#elif 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)) + + /* + * Suppress narrowing warnings. + */ + #define DIAG_OFF_NARROWING \ + __pragma(warning(push)) \ + __pragma(warning(disable:4242)) \ + __pragma(warning(disable:4311)) + #define DIAG_ON_NARROWING \ + __pragma(warning(pop)) + + /* + * Suppress deprecation warnings. + */ + #define DIAG_OFF_DEPRECATION \ + __pragma(warning(push)) \ + __pragma(warning(disable:4996)) + #define DIAG_ON_DEPRECATION \ + __pragma(warning(pop)) + #define DIAG_OFF_FORMAT_TRUNCATION + #define DIAG_ON_FORMAT_TRUNCATION #elif PCAP_IS_AT_LEAST_GNUC_VERSION(4,6) /* * This is GCC 4.6 or later, or a compiler claiming to be that. @@ -97,6 +180,37 @@ PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wunreachable-code") #define DIAG_ON_FLEX \ PCAP_DO_PRAGMA(GCC diagnostic pop) + + /* + * GCC currently doesn't issue any narrowing warnings. + */ + #define DIAG_OFF_NARROWING + #define DIAG_ON_NARROWING + + /* + * Suppress deprecation warnings. + */ + #define DIAG_OFF_DEPRECATION \ + PCAP_DO_PRAGMA(GCC diagnostic push) \ + PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wdeprecated-declarations") + #define DIAG_ON_DEPRECATION \ + PCAP_DO_PRAGMA(GCC diagnostic pop) + + /* + * Suppress format-truncation= warnings. + * GCC 7.1 had introduced this warning option. Earlier versions (at least + * one particular copy of GCC 4.6.4) treat the request as a warning. + */ + #if PCAP_IS_AT_LEAST_GNUC_VERSION(7,1) + #define DIAG_OFF_FORMAT_TRUNCATION \ + PCAP_DO_PRAGMA(GCC diagnostic push) \ + PCAP_DO_PRAGMA(GCC diagnostic ignored "-Wformat-truncation=") + #define DIAG_ON_FORMAT_TRUNCATION \ + PCAP_DO_PRAGMA(GCC diagnostic pop) + #else + #define DIAG_OFF_FORMAT_TRUNCATION + #define DIAG_ON_FORMAT_TRUNCATION + #endif #else /* * Neither Visual Studio, nor Clang 2.8 or later, nor GCC 4.6 or later @@ -105,6 +219,12 @@ */ #define DIAG_OFF_FLEX #define DIAG_ON_FLEX + #define DIAG_OFF_NARROWING + #define DIAG_ON_NARROWING + #define DIAG_OFF_DEPRECATION + #define DIAG_ON_DEPRECATION + #define DIAG_OFF_FORMAT_TRUNCATION + #define DIAG_ON_FORMAT_TRUNCATION #endif #ifdef YYBYACC @@ -124,96 +244,95 @@ * In addition, the generated code may have functions with unreachable * code, so suppress warnings about those. */ - #if defined(_MSC_VER) + #if PCAP_IS_AT_LEAST_CLANG_VERSION(2,8) /* - * This is Microsoft Visual Studio; we can use - * __pragma(warning(disable:XXXX)) and __pragma(warning(push/pop)). + * This is Clang 2.8 or later (including clang-cl, so test this + * before _MSC_VER); we can use "clang diagnostic ignored -Wxxx". */ #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) + PCAP_DO_PRAGMA(clang diagnostic ignored "-Wshadow") \ + PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunreachable-code") + #elif defined(_MSC_VER) /* - * This is Clang 2.8 or later; we can use "clang diagnostic - * ignored -Wxxx" and "clang diagnostic push/pop". + * This is Microsoft Visual Studio; we can use + * __pragma(warning(disable:XXXX)). */ #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) + __pragma(warning(disable:4702)) #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). + * We can use "GCC diagnostic ignored -Wxxx" (introduced in 4.2, + * but it may not actually work very well prior to 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. + * The generated code may have functions with unreachable code and + * switches with only a default case, so suppress warnings about those. */ - #if defined(_MSC_VER) + #if PCAP_IS_AT_LEAST_CLANG_VERSION(2,8) + /* + * This is Clang 2.8 or later (including clang-cl, so test this + * before _MSC_VER); we can use "clang diagnostic ignored -Wxxx". + */ + #define DIAG_OFF_BISON_BYACC \ + PCAP_DO_PRAGMA(clang diagnostic ignored "-Wunreachable-code") + #elif defined(_MSC_VER) /* * This is Microsoft Visual Studio; we can use - * __pragma(warning(disable:XXXX)) and __pragma(warning(push/pop)). + * __pragma(warning(disable:XXXX)). * * Suppress some /Wall warnings. */ #define DIAG_OFF_BISON_BYACC \ - __pragma(warning(push)) \ + __pragma(warning(disable:4065)) \ __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). + * We can use "GCC diagnostic ignored -Wxxx" (introduced in 4.2, + * but it may not actually work very well prior to 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 +/* + * GCC needs this on AIX for longjmp(). + */ +#if PCAP_IS_AT_LEAST_GNUC_VERSION(5,1) + /* + * Beware that the effect of this builtin is more than just squelching the + * warning! GCC trusts it enough for the process to segfault if the control + * flow reaches the builtin (an infinite empty loop in the same context would + * squelch the warning and ruin the process too, albeit in a different way). + * So please remember to use this very carefully. + */ + #define PCAP_UNREACHABLE __builtin_unreachable(); +#else + #define PCAP_UNREACHABLE +#endif + #endif /* _diag_control_h */ diff --git a/external/bsd/libpcap/dist/doc/README.Win32.md b/external/bsd/libpcap/dist/doc/README.Win32.md index 8de25c85a95c..018796517ddf 100644 --- a/external/bsd/libpcap/dist/doc/README.Win32.md +++ b/external/bsd/libpcap/dist/doc/README.Win32.md @@ -1,3 +1,198 @@ -Win32 used to build with Visual Studio 6, but we now use cmake. +Building libpcap on Windows with Visual Studio +============================================== -This file needs to be adopted by a windows expert developer. +Unlike the UN*Xes on which libpcap can capture network traffic, Windows +has no network traffic capture mechanism that libpcap can use. +Therefore, libpcap requires a driver, and a library to access the +driver, provided by the Npcap or WinPcap projects. + +Those projects include versions of libpcap built to use that driver and +library; these instructions are for people who want to build libpcap +source releases, or libpcap from the Git repository, as a replacement +for the version provided with Npcap or WinPcap. + +Npcap and WinPcap SDK +--------------------- + +In order to build libpcap, you will need to download Npcap and its +software development kit (SDK) or WinPcap and its software development +kit. + +Npcap is currently being developed and maintained, and offers many +additional capabilities that WinPcap does not. + +WinPcap is no longer being developed or maintained; it should be used +only if there is some other requirement to use it rather than Npcap, +such as a requirement to support versions of Windows earlier than +Windows Vista, which is the earliest version supported by Npcap. + +Npcap and its SDK can be downloaded from its home page: + + https://npcap.com + +The SDK is a ZIP archive; create a folder on your C: drive, e.g. +C:\npcap-sdk, and put the contents of the ZIP archive into that folder. + +The WinPcap installer can be downloaded from + + https://www.winpcap.org/install/default.htm + +and the WinPcap Developer's Kit can be downloaded from + + https://www.winpcap.org/devel.htm + +Required build tools +-------------------- + +The Developer's Kit is a ZIP archive; it contains a folder named +WpdPack, which you should place on your C: drive, e.g. C:\WpdPack. + +Building libpcap on Windows requires Visual Studio 2015 or later. The +Community Edition of Visual Studio can be downloaded at no cost from + + https://visualstudio.microsoft.com + +Additional tools are also required. Chocolatey is a package manager for +Windows with which those tools, and other tools, can be installed; it +can be downloaded from + + https://chocolatey.org + +It is a command-line tool; a GUI tool, Chocolatey GUI, is provided as a +Chocolatey package, which can be installed from the command line: + + choco install chocolateygui + +For convenience, the "choco install" command can be run with the "-y" +flag, forcing it to automatically answer all questions asked of the user +with "yes": + + choco install -y chocolateygui + +The required tools are: + +### CMake ### + +libpcap does not provide supported project files for Visual Studio +(there are currently unsupported project files provided, but we do not +guarantee that they will work or that we will continue to provide them). +It does provide files for CMake, which is a cross-platform tool that +runs on UN*Xes and on Windows and that can generate project files for +UN*X Make, the Ninja build system, and Visual Studio, among other build +systems. + +Visual Studio 2015 does not provide CMake; an installer can be +downloaded from + + https://cmake.org/download/ + +When you run the installer, you should choose to add CMake to the system +PATH for all users and to create the desktop icon. + +CMake can also be installed as the Chocolatey package "cmake": + + choco install -y cmake + +Visual Studio 2017 and later provide CMake, so you will not need to +install CMake if you have installed Visual Studio 2017 or later. They +include built-in support for CMake-based projects: + + https://devblogs.microsoft.com/cppblog/cmake-support-in-visual-studio/ + +For Visual Studio 2017, make sure "Visual C++ tools for CMake" is +installed; for Visual Studio 2019, make sure "C++ CMake tools for +Windows" is installed. + +### winflexbison ### + +libpcap uses the Flex lexical-analyzer generator and the Bison or +Berkeley YACC parser generators to generate the parser for filter +expressions. Windows versions of Flex and Bison can be downloaded from + + https://sourceforge.net/projects/winflexbison/ + +The downloaded file is a ZIP archive; create a folder on your C: drive, +e.g. C:\Program Files\winflexbison, and put the contents of the ZIP +archive into that folder. Then add that folder to the system PATH +environment variable. + +Git +--- + +An optional tool, required only if you will be building from a Git +repository rather than from a release source tarball, is Git. Git is +provided as an optional installation component, "Git for Windows", with +Visual Studio 2017 and later. + +Building from the Visual Studio GUI +----------------------------------- + +### Visual Studio 2017 ### + +Open the folder containing the libpcap source with Open > Folder. +Visual Studio will run CMake; however, you will need to indicate where +the Npcap or WinPcap SDK is installed. + +To do this, go to Project > "Change CMake Settings" > pcap and: + +Choose which configuration type to build, if you don't want the default +Debug build. + +In the CMakeSettings.json tab, change cmakeCommandArgs to include + + -DPacket_ROOT={path-to-sdk} + +where {path-to-sdk} is the path of the directory containing the Npcap or +WinPcap SDK. Note that backslashes in the path must be specified as two +backslashes. + +Save the configuration changes with File > "Save CMakeSettings.json" or +with control-S. + +Visual Studio will then re-run CMake. If that completes without errors, +you can build with CMake > "Build All". + +### Visual Studio 2019 ### + +Open the folder containing the libpcap source with Open > Folder. +Visual Studio will run CMake; however, you will need to indicate where +the Npcap or WinPcap SDK is installed. + +To do this, go to Project > "CMake Settings for pcap" and: + +Choose which configuration type to build, if you don't want the default +Debug build. + +Scroll down to "Cmake variables and cache", scroll through the list +looking for the entry for Packet_ROOT, and either type in the path of +the directory containing the Npcap or WinPcap SDK or use the "Browse..." +button to browse for that directory. + +Save the configuration changes with File > "Save CMakeSettings.json" or +with control-S. + +Visual Studio will then re-run CMake. If that completes without errors, +you can build with Build > "Build All". + +Building from the command line +------------------------------ + +Start the appropriate Native Tools command line prompt. + +Change to the directory into which you want to build libpcap, possibly +after creating it first. One choice is to create it as a subdirectory +of the libpcap source directory. + +Run the command + + cmake "-DPacket_ROOT={path-to-sdk}" {path-to-libpcap-source} + +where {path-to-sdk} is the path of the directory containing the Npcap or +WinPcap SDK and {path-to-libpcap-source} is the pathname of the +top-level source directory for libpcap. + +Run the command + + msbuild/m pcap.sln + +to compile libpcap. diff --git a/external/bsd/libpcap/dist/doc/README.aix b/external/bsd/libpcap/dist/doc/README.aix index 92e513ff7413..868999476af9 100644 --- a/external/bsd/libpcap/dist/doc/README.aix +++ b/external/bsd/libpcap/dist/doc/README.aix @@ -1,3 +1,25 @@ +# Compiling libpcap on AIX + +* Autoconf is expected to work everywhere. +* Neither AIX lex nor AIX yacc nor AIX m4 are suitable. + +## AIX 7.1 + +* libpcap build fails with rpcapd enabled. +* GNU M4 1.4.17 works. +* flex 2.6.4 and GNU Bison 3.5.1 work. +* CMake 3.16.0 works. +* GCC 8.3.0 works, XL C 12.1.0 works. + +## AIX 7.2 + +* libpcap build fails with rpcapd enabled. +* GNU M4 1.4.17 works. +* flex 2.5.35 and GNU Bison 3.0.4 work. +* GCC 7.2.0 works, XL C 13.1.3 works. + +## Other AIX-related information + Using BPF: (1) AIX 4.x's version of BPF is undocumented and somewhat unstandard; the @@ -27,7 +49,7 @@ Using BPF: If you fix the problems yourself, please submit a patch by forking the branch at - https://github.com/the-tcpdump-group/libpcap/issues + https://github.com/the-tcpdump-group/libpcap/tree/master and issuing a pull request, so we can incorporate the fixes into the next release. diff --git a/external/bsd/libpcap/dist/doc/README.dag b/external/bsd/libpcap/dist/doc/README.dag index 7ea25040eb1a..fd2c4b741bd7 100644 --- a/external/bsd/libpcap/dist/doc/README.dag +++ b/external/bsd/libpcap/dist/doc/README.dag @@ -1,7 +1,7 @@ The following instructions apply if you have a Linux or FreeBSD platform and want libpcap to support the DAG range of passive network monitoring cards from -Endace (http://www.endace.com, see below for further contact details). +Endace (https://www.endace.com, see below for further contact details). 1) Install and build the DAG software distribution by following the instructions supplied with that package. Current Endace customers can download @@ -22,7 +22,7 @@ If 'configure' reports that there is no DAG API, the directory may have been incorrectly specified or the DAG software was not built before configuring libpcap. -See also the libpcap INSTALL.txt file for further libpcap configuration +See also the libpcap INSTALL.md file for further libpcap configuration options. Building libpcap at this stage will include support for both the native packet @@ -117,6 +117,6 @@ Please submit bug reports via . Please also visit our Web site at: - http://www.endace.com/ + https://www.endace.com/ For more information about Endace DAG cards contact . diff --git a/external/bsd/libpcap/dist/doc/README.hpux b/external/bsd/libpcap/dist/doc/README.hpux index 65ecff97c249..4b3801b4387a 100644 --- a/external/bsd/libpcap/dist/doc/README.hpux +++ b/external/bsd/libpcap/dist/doc/README.hpux @@ -8,7 +8,7 @@ Note that packet-capture programs such as tcpdump may, on HP-UX, not be able to see packets sent from the machine on which they're running. Some articles on groups.google.com discussing this are: - http://groups.google.com/groups?selm=82ld3v%2480i%241%40mamenchi.zrz.TU-Berlin.DE + https://groups.google.com/groups?selm=82ld3v%2480i%241%40mamenchi.zrz.TU-Berlin.DE which says: @@ -69,7 +69,7 @@ which says: and - http://groups.google.com/groups?selm=38AA973E.96BE7DF7%40cc.uit.no + https://groups.google.com/groups?selm=38AA973E.96BE7DF7%40cc.uit.no which says: @@ -118,7 +118,7 @@ And another message to tcpdump-workers@tcpdump.org, from Rick Jones: Another posting: - http://groups.google.com/groups?selm=7d6gvn%24b3%241%40ocean.cup.hp.com + https://groups.google.com/groups?selm=7d6gvn%24b3%241%40ocean.cup.hp.com indicates that you need to install the optional STREAMS product to do captures on HP-UX 9.x: @@ -159,7 +159,7 @@ An additional note, from Jost Martin, for HP-UX 10.20: of an interface A: You need to get PHNE_20892,PHNE_20725 and PHCO_10947 (or newer, this is as of 4.4.00) and its dependencies. Then you can - enable the feature as descibed below: + enable the feature as described below: Patch Name: PHNE_20892 Patch Description: s700 10.20 PCI 100Base-T cumulative patch @@ -195,7 +195,7 @@ Here's the "hack_ip_stack" script: -----------------------------------Cut Here------------------------------------- #!/sbin/sh # -# nettune: hack kernel parms for safety +# nettune: hack kernel params for safety OKAY=0 ERROR=-1 diff --git a/external/bsd/libpcap/dist/doc/README.linux b/external/bsd/libpcap/dist/doc/README.linux new file mode 100644 index 000000000000..eba43aeb16c3 --- /dev/null +++ b/external/bsd/libpcap/dist/doc/README.linux @@ -0,0 +1,36 @@ +Currently, libpcap supports packet capturing on Linux 2.6.27 and later; +earlier versions are not supported. + +You must configure 2.6.x kernels with the CONFIG_PACKET_MMAP option for +this protocol. 3.x and later kernels do not require that. + +Note that, by default, libpcap will, if libnl is present, build with it; +it uses libnl to support monitor mode on mac80211 devices. There is a +configuration option to disable building with libnl, but, if that option +is chosen, the monitor-mode APIs (as used by tcpdump's "-I" flag, and as +will probably be used by other applications in the future) won't work +properly on mac80211 devices. + +Linux's run-time linker allows shared libraries to be linked with other +shared libraries, which means that if an older version of a shared +library doesn't require routines from some other shared library, and a +later version of the shared library does require those routines, the +later version of the shared library can be linked with that other shared +library and, if it's otherwise binary-compatible with the older version, +can replace that older version without breaking applications built with +the older version, and without breaking configure scripts or the build +procedure for applications whose configure script doesn't use the +pcap-config script if they build with the shared library. (The build +procedure for applications whose configure scripts use the pcap-config +script if present will not break even if they build with the static +library.) + +Statistics: +Statistics reported by pcap are platform specific. The statistics +reported by pcap_stats on Linux are as follows: + +ps_recv Number of packets that were accepted by the pcap filter +ps_drop Number of packets that had passed filtering but were not + passed on to pcap due to things like buffer shortage, etc. + This is useful because these are packets you are interested in + but won't be reported by, for example, tcpdump output. diff --git a/external/bsd/libpcap/dist/doc/README.septel b/external/bsd/libpcap/dist/doc/README.septel index fa2c0c9a40d9..d7fb5c7c61a7 100644 --- a/external/bsd/libpcap/dist/doc/README.septel +++ b/external/bsd/libpcap/dist/doc/README.septel @@ -1,6 +1,6 @@ The following instructions apply if you have a Linux platform and want libpcap to support the Septel range of passive network monitoring cards -from Intel (http://www.intel.com) +from Intel (https://www.intel.com) 1) Install and build the Septel software distribution by following the instructions supplied with that package. @@ -25,7 +25,7 @@ If 'configure' reports that there is no Septel API, the directory may have been incorrectly specified or the Septel software was not built before configuring libpcap. -See also the libpcap INSTALL.txt file for further libpcap configuration +See also the libpcap INSTALL.md file for further libpcap configuration options. Building libpcap at this stage will include support for both the native diff --git a/external/bsd/libpcap/dist/doc/README.sita b/external/bsd/libpcap/dist/doc/README.sita index 5a65822ecedb..c85e0d8ceab4 100644 --- a/external/bsd/libpcap/dist/doc/README.sita +++ b/external/bsd/libpcap/dist/doc/README.sita @@ -1,18 +1,25 @@ +NOTE: this is not currently supported; the configure script doesn't +support --with-sita, and CMake doesn't support enabling SITA ACN +support. The code currently does not compile; it should really be +implemented as an additional remote capture mechanism, using a URL, +rather than as a separate version of libpcap that supports only the ACN +product, but the infrastructure for that isn't yet available. + The following instructions apply if you have a Linux platform and want libpcap to support the 'ACN' WAN/LAN router product from SITA -(http://www.sita.aero) +(https://www.sita.aero) This might also work on non-Linux Unix-compatible platforms, but that has not been tested. -See also the libpcap INSTALL.txt file for further libpcap configuration +See also the libpcap INSTALL.md file for further libpcap configuration options. These additions/extensions have been made to PCAP to allow it to capture packets from a SITA ACN device (and potentially others). To enable its support you need to ensure that the distribution has -a correct configure.ac file; that can be created if neccessay by +a correct configure.ac file; that can be created if necessary by using the normal autoconf procedure of: aclocal diff --git a/external/bsd/libpcap/dist/doc/README.solaris.md b/external/bsd/libpcap/dist/doc/README.solaris.md new file mode 100644 index 000000000000..06ba789dfc4c --- /dev/null +++ b/external/bsd/libpcap/dist/doc/README.solaris.md @@ -0,0 +1,58 @@ +# Compiling libpcap on Solaris and related OSes + +* Autoconf works everywhere. +* Neither Solaris lex nor Solaris yacc are suitable. +* Neither illumos lex nor illumos yacc are suitable. +* Solaris m4 and illumos m4 are suitable. + +## OmniOS r151042/AMD64 + +* flex 2.6.4 and GNU Bison 3.8.2 work. +* CMake 3.23.1 works. +* GCC 11.2.0 and Clang 14.0.3 work. + +## OpenIndiana 2021.04/AMD64 + +* flex 2.6.4 and GNU Bison 3.7.6 work. +* CMake 3.21.1 works. +* GCC 7.5.0 and GCC 10.3.0 work, Clang 9.0.1 works. + +For reference, the tests were done using a system installed from +`OI-hipster-text-20210430.iso` plus the following packages: +```shell +xargs -L1 pkg install < #include +#include "portability.h" /* - * Macros to extract possibly-unaligned big-endian integral values. + * If we have versions of GCC or Clang that support an __attribute__ + * to say "if we're building with unsigned behavior sanitization, + * don't complain about undefined behavior in this function", we + * label these functions with that attribute - we *know* it's undefined + * in the C standard, but we *also* know it does what we want with + * the ISA we're targeting and the compiler we're using. + * + * For GCC 4.9.0 and later, we use __attribute__((no_sanitize_undefined)); + * pre-5.0 GCC doesn't have __has_attribute, and I'm not sure whether + * GCC or Clang first had __attribute__((no_sanitize(XXX)). + * + * For Clang, we check for __attribute__((no_sanitize(XXX)) with + * __has_attribute, as there are versions of Clang that support + * __attribute__((no_sanitize("undefined")) but don't support + * __attribute__((no_sanitize_undefined)). + * + * We define this here, rather than in funcattrs.h, because we + * only want it used here, we don't want it to be broadly used. + * (Any printer will get this defined, but this should at least + * make it harder for people to find.) */ -#ifdef LBL_ALIGN +#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 409) +#define UNALIGNED_OK __attribute__((no_sanitize_undefined)) +#elif __has_attribute(no_sanitize) +#define UNALIGNED_OK __attribute__((no_sanitize("undefined"))) +#else +#define UNALIGNED_OK +#endif + +#if (defined(__i386__) || defined(_M_IX86) || defined(__X86__) || defined(__x86_64__) || defined(_M_X64)) || \ + (defined(__m68k__) && (!defined(__mc68000__) && !defined(__mc68010__))) || \ + (defined(__ppc__) || defined(__ppc64__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PPC64)) || \ + (defined(__s390__) || defined(__s390x__) || defined(__zarch__)) /* - * The processor doesn't natively handle unaligned loads. + * The processor natively handles unaligned loads, so we can just + * cast the pointer and fetch through it. + * + * XXX - are those all the x86 tests we need? + * XXX - are those the only 68k tests we need not to generated + * unaligned accesses if the target is the 68000 or 68010? + * XXX - are there any tests we don't need, because some definitions are for + * compilers that also predefine the GCC symbols? + * XXX - do we need to test for both 32-bit and 64-bit versions of those + * architectures in all cases? */ -#if PCAP_IS_AT_LEAST_GNUC_VERSION(2,0) && \ +UNALIGNED_OK static inline uint16_t +EXTRACT_BE_U_2(const void *p) +{ + return ((uint16_t)ntohs(*(const uint16_t *)(p))); +} + +UNALIGNED_OK static inline int16_t +EXTRACT_BE_S_2(const void *p) +{ + return ((int16_t)ntohs(*(const int16_t *)(p))); +} + +UNALIGNED_OK static inline uint32_t +EXTRACT_BE_U_4(const void *p) +{ + return ((uint32_t)ntohl(*(const uint32_t *)(p))); +} + +UNALIGNED_OK static inline int32_t +EXTRACT_BE_S_4(const void *p) +{ + return ((int32_t)ntohl(*(const int32_t *)(p))); +} + +UNALIGNED_OK static inline uint64_t +EXTRACT_BE_U_8(const void *p) +{ + return ((uint64_t)(((uint64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 | + ((uint64_t)ntohl(*((const uint32_t *)(p) + 1))) << 0)); + +} + +UNALIGNED_OK static inline int64_t +EXTRACT_BE_S_8(const void *p) +{ + return ((int64_t)(((int64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 | + ((uint64_t)ntohl(*((const uint32_t *)(p) + 1))) << 0)); + +} +#elif PCAP_IS_AT_LEAST_GNUC_VERSION(2,0) && \ (defined(__alpha) || defined(__alpha__) || \ defined(__mips) || defined(__mips__)) /* @@ -48,11 +127,11 @@ * cast the pointer to point to one of those, and fetch through it; * the GCC manual doesn't appear to explicitly say that * __attribute__((packed)) causes the compiler to generate unaligned-safe - * code, but it apppears to do so. + * code, but it appears to do so. * * We do this in case the compiler can generate code using those * instructions to do an unaligned load and pass stuff to "ntohs()" or - * "ntohl()", which might be better than than the code to fetch the + * "ntohl()", which might be better than the code to fetch the * bytes one at a time and assemble them. (That might not be the * case on a little-endian platform, such as DEC's MIPS machines and * Alpha machines, where "ntohs()" and "ntohl()" might not be done @@ -92,46 +171,91 @@ typedef struct { uint16_t val; } __attribute__((packed)) unaligned_uint16_t; +typedef struct { + int16_t val; +} __attribute__((packed)) unaligned_int16_t; + typedef struct { uint32_t val; } __attribute__((packed)) unaligned_uint32_t; -static inline uint16_t -EXTRACT_16BITS(const void *p) +typedef struct { + int32_t val; +} __attribute__((packed)) unaligned_int32_t; + +UNALIGNED_OK static inline uint16_t +EXTRACT_BE_U_2(const void *p) { return ((uint16_t)ntohs(((const unaligned_uint16_t *)(p))->val)); } -static inline uint32_t -EXTRACT_32BITS(const void *p) +UNALIGNED_OK static inline int16_t +EXTRACT_BE_S_2(const void *p) +{ + return ((int16_t)ntohs(((const unaligned_int16_t *)(p))->val)); +} + +UNALIGNED_OK static inline uint32_t +EXTRACT_BE_U_4(const void *p) { return ((uint32_t)ntohl(((const unaligned_uint32_t *)(p))->val)); } -static inline uint64_t -EXTRACT_64BITS(const void *p) +UNALIGNED_OK static inline int32_t +EXTRACT_BE_S_4(const void *p) +{ + return ((int32_t)ntohl(((const unaligned_int32_t *)(p))->val)); +} + +UNALIGNED_OK static inline uint64_t +EXTRACT_BE_U_8(const void *p) { - return ((uint64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 | \ + return ((uint64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 | ((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 1)->val)) << 0)); } -#else /* have to do it a byte at a time */ +UNALIGNED_OK static inline int64_t +EXTRACT_BE_S_8(const void *p) +{ + return ((int64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 | + ((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 1)->val)) << 0)); +} +#else /* - * This isn't a GCC-compatible compiler, we don't have __attribute__, + * This architecture doesn't natively support unaligned loads, and either + * this isn't a GCC-compatible compiler, we don't have __attribute__, * or we do but we don't know of any better way with this instruction * set to do unaligned loads, so do unaligned loads of big-endian * quantities the hard way - fetch the bytes one at a time and * assemble them. + * + * XXX - ARM is a special case. ARMv1 through ARMv5 didn't suppory + * unaligned loads; ARMv6 and later support it *but* have a bit in + * the system control register that the OS can set and that causes + * unaligned loads to fault rather than succeeding. + * + * At least some OSes may set that flag, so we do *not* treat ARM + * as supporting unaligned loads. If your OS supports them on ARM, + * and you want to use them, please update the tests in the #if above + * to check for ARM *and* for your OS. */ -#define EXTRACT_16BITS(p) \ +#define EXTRACT_BE_U_2(p) \ ((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 0)) << 8) | \ ((uint16_t)(*((const uint8_t *)(p) + 1)) << 0))) -#define EXTRACT_32BITS(p) \ +#define EXTRACT_BE_S_2(p) \ + ((int16_t)(((uint16_t)(*((const uint8_t *)(p) + 0)) << 8) | \ + ((uint16_t)(*((const uint8_t *)(p) + 1)) << 0))) +#define EXTRACT_BE_U_4(p) \ ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 24) | \ ((uint32_t)(*((const uint8_t *)(p) + 1)) << 16) | \ ((uint32_t)(*((const uint8_t *)(p) + 2)) << 8) | \ ((uint32_t)(*((const uint8_t *)(p) + 3)) << 0))) -#define EXTRACT_64BITS(p) \ +#define EXTRACT_BE_S_4(p) \ + ((int32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 24) | \ + ((uint32_t)(*((const uint8_t *)(p) + 1)) << 16) | \ + ((uint32_t)(*((const uint8_t *)(p) + 2)) << 8) | \ + ((uint32_t)(*((const uint8_t *)(p) + 3)) << 0))) +#define EXTRACT_BE_U_8(p) \ ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 56) | \ ((uint64_t)(*((const uint8_t *)(p) + 1)) << 48) | \ ((uint64_t)(*((const uint8_t *)(p) + 2)) << 40) | \ @@ -140,47 +264,67 @@ EXTRACT_64BITS(const void *p) ((uint64_t)(*((const uint8_t *)(p) + 5)) << 16) | \ ((uint64_t)(*((const uint8_t *)(p) + 6)) << 8) | \ ((uint64_t)(*((const uint8_t *)(p) + 7)) << 0))) -#endif /* must special-case unaligned accesses */ -#else /* LBL_ALIGN */ +#define EXTRACT_BE_S_8(p) \ + ((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 56) | \ + ((uint64_t)(*((const uint8_t *)(p) + 1)) << 48) | \ + ((uint64_t)(*((const uint8_t *)(p) + 2)) << 40) | \ + ((uint64_t)(*((const uint8_t *)(p) + 3)) << 32) | \ + ((uint64_t)(*((const uint8_t *)(p) + 4)) << 24) | \ + ((uint64_t)(*((const uint8_t *)(p) + 5)) << 16) | \ + ((uint64_t)(*((const uint8_t *)(p) + 6)) << 8) | \ + ((uint64_t)(*((const uint8_t *)(p) + 7)) << 0))) + /* - * The processor natively handles unaligned loads, so we can just - * cast the pointer and fetch through it. + * Extract an IPv4 address, which is in network byte order, and not + * necessarily aligned, and provide the result in host byte order. */ -static inline uint16_t -EXTRACT_16BITS(const void *p) -{ - return ((uint16_t)ntohs(*(const uint16_t *)(p))); -} - -static inline uint32_t -EXTRACT_32BITS(const void *p) -{ - return ((uint32_t)ntohl(*(const uint32_t *)(p))); -} - -static inline uint64_t -EXTRACT_64BITS(const void *p) -{ - return ((uint64_t)(((uint64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 | \ - ((uint64_t)ntohl(*((const uint32_t *)(p) + 1))) << 0)); - -} - -#endif /* LBL_ALIGN */ +#define EXTRACT_IPV4_TO_HOST_ORDER(p) \ + ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 24) | \ + ((uint32_t)(*((const uint8_t *)(p) + 1)) << 16) | \ + ((uint32_t)(*((const uint8_t *)(p) + 2)) << 8) | \ + ((uint32_t)(*((const uint8_t *)(p) + 3)) << 0))) +#endif /* unaligned access checks */ -#define EXTRACT_24BITS(p) \ +/* + * Non-power-of-2 sizes. + */ +#define EXTRACT_BE_U_3(p) \ ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 16) | \ ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ ((uint32_t)(*((const uint8_t *)(p) + 2)) << 0))) -#define EXTRACT_40BITS(p) \ +#define EXTRACT_BE_S_3(p) \ + (((*((const uint8_t *)(p) + 0)) & 0x80) ? \ + ((int32_t)(((uint32_t)(*((const uint8_t *)(p) + 0)) << 16) | \ + ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ + ((uint32_t)(*((const uint8_t *)(p) + 2)) << 0))) : \ + ((int32_t)(0xFF000000U | \ + ((uint32_t)(*((const uint8_t *)(p) + 0)) << 16) | \ + ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ + ((uint32_t)(*((const uint8_t *)(p) + 2)) << 0)))) + +#define EXTRACT_BE_U_5(p) \ ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 32) | \ ((uint64_t)(*((const uint8_t *)(p) + 1)) << 24) | \ ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ ((uint64_t)(*((const uint8_t *)(p) + 3)) << 8) | \ ((uint64_t)(*((const uint8_t *)(p) + 4)) << 0))) -#define EXTRACT_48BITS(p) \ +#define EXTRACT_BE_S_5(p) \ + (((*((const uint8_t *)(p) + 0)) & 0x80) ? \ + ((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 32) | \ + ((uint64_t)(*((const uint8_t *)(p) + 1)) << 24) | \ + ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ + ((uint64_t)(*((const uint8_t *)(p) + 3)) << 8) | \ + ((uint64_t)(*((const uint8_t *)(p) + 4)) << 0))) : \ + ((int64_t)(INT64_T_CONSTANT(0xFFFFFF0000000000U) | \ + ((uint64_t)(*((const uint8_t *)(p) + 0)) << 32) | \ + ((uint64_t)(*((const uint8_t *)(p) + 1)) << 24) | \ + ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ + ((uint64_t)(*((const uint8_t *)(p) + 3)) << 8) | \ + ((uint64_t)(*((const uint8_t *)(p) + 4)) << 0)))) + +#define EXTRACT_BE_U_6(p) \ ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 40) | \ ((uint64_t)(*((const uint8_t *)(p) + 1)) << 32) | \ ((uint64_t)(*((const uint8_t *)(p) + 2)) << 24) | \ @@ -188,7 +332,23 @@ EXTRACT_64BITS(const void *p) ((uint64_t)(*((const uint8_t *)(p) + 4)) << 8) | \ ((uint64_t)(*((const uint8_t *)(p) + 5)) << 0))) -#define EXTRACT_56BITS(p) \ +#define EXTRACT_BE_S_6(p) \ + (((*((const uint8_t *)(p) + 0)) & 0x80) ? \ + ((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 40) | \ + ((uint64_t)(*((const uint8_t *)(p) + 1)) << 32) | \ + ((uint64_t)(*((const uint8_t *)(p) + 2)) << 24) | \ + ((uint64_t)(*((const uint8_t *)(p) + 3)) << 16) | \ + ((uint64_t)(*((const uint8_t *)(p) + 4)) << 8) | \ + ((uint64_t)(*((const uint8_t *)(p) + 5)) << 0))) : \ + ((int64_t)(INT64_T_CONSTANT(0xFFFFFFFF00000000U) | \ + ((uint64_t)(*((const uint8_t *)(p) + 0)) << 40) | \ + ((uint64_t)(*((const uint8_t *)(p) + 1)) << 32) | \ + ((uint64_t)(*((const uint8_t *)(p) + 2)) << 24) | \ + ((uint64_t)(*((const uint8_t *)(p) + 3)) << 16) | \ + ((uint64_t)(*((const uint8_t *)(p) + 4)) << 8) | \ + ((uint64_t)(*((const uint8_t *)(p) + 5)) << 0)))) + +#define EXTRACT_BE_U_7(p) \ ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 48) | \ ((uint64_t)(*((const uint8_t *)(p) + 1)) << 40) | \ ((uint64_t)(*((const uint8_t *)(p) + 2)) << 32) | \ @@ -197,24 +357,53 @@ EXTRACT_64BITS(const void *p) ((uint64_t)(*((const uint8_t *)(p) + 5)) << 8) | \ ((uint64_t)(*((const uint8_t *)(p) + 6)) << 0))) +#define EXTRACT_BE_S_7(p) \ + (((*((const uint8_t *)(p) + 0)) & 0x80) ? \ + ((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 0)) << 48) | \ + ((uint64_t)(*((const uint8_t *)(p) + 1)) << 40) | \ + ((uint64_t)(*((const uint8_t *)(p) + 2)) << 32) | \ + ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ + ((uint64_t)(*((const uint8_t *)(p) + 4)) << 16) | \ + ((uint64_t)(*((const uint8_t *)(p) + 5)) << 8) | \ + ((uint64_t)(*((const uint8_t *)(p) + 6)) << 0))) : \ + ((int64_t)(INT64_T_CONSTANT(0xFFFFFFFFFF000000U) | \ + ((uint64_t)(*((const uint8_t *)(p) + 0)) << 48) | \ + ((uint64_t)(*((const uint8_t *)(p) + 1)) << 40) | \ + ((uint64_t)(*((const uint8_t *)(p) + 2)) << 32) | \ + ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ + ((uint64_t)(*((const uint8_t *)(p) + 4)) << 16) | \ + ((uint64_t)(*((const uint8_t *)(p) + 5)) << 8) | \ + ((uint64_t)(*((const uint8_t *)(p) + 6)) << 0)))) + /* * Macros to extract possibly-unaligned little-endian integral values. * XXX - do loads on little-endian machines that support unaligned loads? */ -#define EXTRACT_LE_8BITS(p) (*(p)) -#define EXTRACT_LE_16BITS(p) \ +#define EXTRACT_LE_U_2(p) \ ((uint16_t)(((uint16_t)(*((const uint8_t *)(p) + 1)) << 8) | \ ((uint16_t)(*((const uint8_t *)(p) + 0)) << 0))) -#define EXTRACT_LE_32BITS(p) \ +#define EXTRACT_LE_S_2(p) \ + ((int16_t)(((uint16_t)(*((const uint8_t *)(p) + 1)) << 8) | \ + ((uint16_t)(*((const uint8_t *)(p) + 0)) << 0))) +#define EXTRACT_LE_U_4(p) \ ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 3)) << 24) | \ ((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \ ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ ((uint32_t)(*((const uint8_t *)(p) + 0)) << 0))) -#define EXTRACT_LE_24BITS(p) \ +#define EXTRACT_LE_S_4(p) \ + ((int32_t)(((uint32_t)(*((const uint8_t *)(p) + 3)) << 24) | \ + ((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \ + ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ + ((uint32_t)(*((const uint8_t *)(p) + 0)) << 0))) +#define EXTRACT_LE_U_3(p) \ ((uint32_t)(((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \ ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ ((uint32_t)(*((const uint8_t *)(p) + 0)) << 0))) -#define EXTRACT_LE_64BITS(p) \ +#define EXTRACT_LE_S_3(p) \ + ((int32_t)(((uint32_t)(*((const uint8_t *)(p) + 2)) << 16) | \ + ((uint32_t)(*((const uint8_t *)(p) + 1)) << 8) | \ + ((uint32_t)(*((const uint8_t *)(p) + 0)) << 0))) +#define EXTRACT_LE_U_8(p) \ ((uint64_t)(((uint64_t)(*((const uint8_t *)(p) + 7)) << 56) | \ ((uint64_t)(*((const uint8_t *)(p) + 6)) << 48) | \ ((uint64_t)(*((const uint8_t *)(p) + 5)) << 40) | \ @@ -223,3 +412,12 @@ EXTRACT_64BITS(const void *p) ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ ((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \ ((uint64_t)(*((const uint8_t *)(p) + 0)) << 0))) +#define EXTRACT_LE_S_8(p) \ + ((int64_t)(((uint64_t)(*((const uint8_t *)(p) + 7)) << 56) | \ + ((uint64_t)(*((const uint8_t *)(p) + 6)) << 48) | \ + ((uint64_t)(*((const uint8_t *)(p) + 5)) << 40) | \ + ((uint64_t)(*((const uint8_t *)(p) + 4)) << 32) | \ + ((uint64_t)(*((const uint8_t *)(p) + 3)) << 24) | \ + ((uint64_t)(*((const uint8_t *)(p) + 2)) << 16) | \ + ((uint64_t)(*((const uint8_t *)(p) + 1)) << 8) | \ + ((uint64_t)(*((const uint8_t *)(p) + 0)) << 0))) diff --git a/external/bsd/libpcap/dist/fmtutils.c b/external/bsd/libpcap/dist/fmtutils.c index 091e0d35eede..2d3576244107 100644 --- a/external/bsd/libpcap/dist/fmtutils.c +++ b/external/bsd/libpcap/dist/fmtutils.c @@ -47,12 +47,220 @@ #include #include -#include +#include "pcap-int.h" #include "portability.h" #include "fmtutils.h" +#ifdef _WIN32 +#include "charconv.h" +#endif + +/* + * Set the encoding. + */ +#ifdef _WIN32 +/* + * True if we shouold use UTF-8. + */ +static int use_utf_8; + +void +pcap_fmt_set_encoding(unsigned int opts) +{ + if (opts == PCAP_CHAR_ENC_UTF_8) + use_utf_8 = 1; +} +#else +void +pcap_fmt_set_encoding(unsigned int opts _U_) +{ + /* + * Nothing to do here. + */ +} +#endif + +#ifdef _WIN32 +/* + * Convert a null-terminated UTF-16LE string to UTF-8, putting it into + * a buffer starting at the specified location and stopping if we go + * past the specified size. This will only put out complete UTF-8 + * sequences. + * + * We do this ourselves because Microsoft doesn't offer a "convert and + * stop at a UTF-8 character boundary if we run out of space" routine. + */ +#define IS_LEADING_SURROGATE(c) \ + ((c) >= 0xd800 && (c) < 0xdc00) +#define IS_TRAILING_SURROGATE(c) \ + ((c) >= 0xdc00 && (c) < 0xe000) +#define SURROGATE_VALUE(leading, trailing) \ + (((((leading) - 0xd800) << 10) | ((trailing) - 0xdc00)) + 0x10000) +#define REPLACEMENT_CHARACTER 0x0FFFD + +static char * +utf_16le_to_utf_8_truncated(const wchar_t *utf_16, char *utf_8, + size_t utf_8_len) +{ + wchar_t c, c2; + uint32_t uc; + + if (utf_8_len == 0) { + /* + * Not even enough room for a trailing '\0'. + * Don't put anything into the buffer. + */ + return (utf_8); + } + + while ((c = *utf_16++) != '\0') { + if (IS_LEADING_SURROGATE(c)) { + /* + * Leading surrogate. Must be followed by + * a trailing surrogate. + */ + c2 = *utf_16; + if (c2 == '\0') { + /* + * Oops, string ends with a lead + * surrogate. Try to drop in + * a REPLACEMENT CHARACTER, and + * don't move the string pointer, + * so on the next trip through + * the loop we grab the terminating + * '\0' and quit. + */ + uc = REPLACEMENT_CHARACTER; + } else { + /* + * OK, we can consume this 2-octet + * value. + */ + utf_16++; + if (IS_TRAILING_SURROGATE(c2)) { + /* + * Trailing surrogate. + * This calculation will, + * for c being a leading + * surrogate and c2 being + * a trailing surrogate, + * produce a value between + * 0x100000 and 0x10ffff, + * so it's always going to be + * a valid Unicode code point. + */ + uc = SURROGATE_VALUE(c, c2); + } else { + /* + * Not a trailing surroage; + * try to drop in a + * REPLACEMENT CHARACTER. + */ + uc = REPLACEMENT_CHARACTER; + } + } + } else { + /* + * Not a leading surrogate. + */ + if (IS_TRAILING_SURROGATE(c)) { + /* + * Trailing surrogate without + * a preceding leading surrogate. + * Try to drop in a REPLACEMENT + * CHARACTER. + */ + uc = REPLACEMENT_CHARACTER; + } else { + /* + * This is a valid BMP character; + * drop it in. + */ + uc = c; + } + } + + /* + * OK, uc is a valid Unicode character; how + * many bytes worth of UTF-8 does it require? + */ + if (uc < 0x0080) { + /* 1 byte. */ + if (utf_8_len < 2) { + /* + * Not enough room for that byte + * plus a trailing '\0'. + */ + break; + } + *utf_8++ = (char)uc; + utf_8_len--; + } else if (uc < 0x0800) { + /* 2 bytes. */ + if (utf_8_len < 3) { + /* + * Not enough room for those bytes + * plus a trailing '\0'. + */ + break; + } + *utf_8++ = ((uc >> 6) & 0x3F) | 0xC0; + *utf_8++ = ((uc >> 0) & 0x3F) | 0x80; + utf_8_len -= 2; + } else if (uc < 0x010000) { + /* 3 bytes. */ + if (utf_8_len < 4) { + /* + * Not enough room for those bytes + * plus a trailing '\0'. + */ + break; + } + *utf_8++ = ((uc >> 12) & 0x0F) | 0xE0; + *utf_8++ = ((uc >> 6) & 0x3F) | 0x80; + *utf_8++ = ((uc >> 0) & 0x3F) | 0x80; + utf_8_len -= 3; + } else { + /* 4 bytes. */ + if (utf_8_len < 5) { + /* + * Not enough room for those bytes + * plus a trailing '\0'. + */ + break; + } + *utf_8++ = ((uc >> 18) & 0x03) | 0xF0; + *utf_8++ = ((uc >> 12) & 0x3F) | 0x80; + *utf_8++ = ((uc >> 6) & 0x3F) | 0x80; + *utf_8++ = ((uc >> 0) & 0x3F) | 0x80; + utf_8_len -= 3; + } + } + + /* + * OK, we have enough room for (at least) a trailing '\0'. + * (We started out with enough room, thanks to the test + * for a zero-length buffer at the beginning, and if + * there wasn't enough room for any character we wanted + * to put into the buffer *plus* a trailing '\0', + * we'd have quit before putting it into the buffer, + * and thus would have left enough room for the trailing + * '\0'.) + * + * Drop it in. + */ + *utf_8 = '\0'; + + /* + * Return a pointer to the terminating '\0', in case we + * want to drop something in after that. + */ + return (utf_8); +} +#endif /* _WIN32 */ + /* * Generate an error message based on a format, arguments, and an * errno, with a message for the errno after the formatted output. @@ -62,13 +270,21 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum, const char *fmt, ...) { va_list ap; + + va_start(ap, fmt); + pcap_vfmt_errmsg_for_errno(errbuf, errbuflen, errnum, fmt, ap); + va_end(ap); +} + +void +pcap_vfmt_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; - va_start(ap, fmt); - pcap_vsnprintf(errbuf, errbuflen, fmt, ap); - va_end(ap); + (void)vsnprintf(errbuf, errbuflen, fmt, ap); msglen = strlen(errbuf); /* @@ -84,24 +300,40 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum, *p++ = ':'; *p++ = ' '; *p = '\0'; - msglen += 2; errbuflen_remaining -= 2; /* * Now append the string for the error code. */ -#if defined(HAVE_STRERROR_S) +#if defined(HAVE__WCSERROR_S) /* - * We have a Windows-style strerror_s(). + * We have a Windows-style _wcserror_s(). + * Generate a UTF-16LE error message. */ - errno_t err = strerror_s(p, errbuflen_remaining, errnum); + wchar_t utf_16_errbuf[PCAP_ERRBUF_SIZE]; + errno_t err = _wcserror_s(utf_16_errbuf, PCAP_ERRBUF_SIZE, errnum); if (err != 0) { /* * It doesn't appear to be documented anywhere obvious - * what the error returns from strerror_s(). + * what the error returns from _wcserror_s(). */ - pcap_snprintf(p, errbuflen_remaining, "Error %d", errnum); + snprintf(p, errbuflen_remaining, "Error %d", errnum); + return; } + + /* + * Now convert it from UTF-16LE to UTF-8, dropping it in the + * remaining space in the buffer, and truncating it - cleanly, + * on a UTF-8 character boundary - if it doesn't fit. + */ + utf_16le_to_utf_8_truncated(utf_16_errbuf, p, errbuflen_remaining); + + /* + * Now, if we're not in UTF-8 mode, convert errbuf to the + * local code page. + */ + if (!use_utf_8) + utf_8_to_acp_truncated(errbuf); #elif defined(HAVE_GNU_STRERROR_R) /* * We have a GNU-style strerror_r(), which is *not* guaranteed to @@ -113,7 +345,7 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum, */ char strerror_buf[PCAP_ERRBUF_SIZE]; char *errstring = strerror_r(errnum, strerror_buf, PCAP_ERRBUF_SIZE); - pcap_snprintf(p, errbuflen_remaining, "%s", errstring); + snprintf(p, errbuflen_remaining, "%s", errstring); #elif defined(HAVE_POSIX_STRERROR_R) /* * We have a POSIX-style strerror_r(), which is guaranteed to fill @@ -125,22 +357,22 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum, * UNIX 03 says this isn't guaranteed to produce a * fallback error message. */ - pcap_snprintf(p, errbuflen_remaining, "Unknown error: %d", + 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, + snprintf(p, errbuflen_remaining, "Message for error %d is too long", errnum); } #else /* - * We have neither strerror_s() nor strerror_r(), so we're + * We have neither _wcserror_s() nor strerror_r(), so we're * stuck with using pcap_strerror(). */ - pcap_snprintf(p, errbuflen_remaining, "%s", pcap_strerror(errnum)); + snprintf(p, errbuflen_remaining, "%s", pcap_strerror(errnum)); #endif } @@ -154,15 +386,24 @@ pcap_fmt_errmsg_for_win32_err(char *errbuf, size_t errbuflen, DWORD errnum, const char *fmt, ...) { va_list ap; + + va_start(ap, fmt); + pcap_vfmt_errmsg_for_win32_err(errbuf, errbuflen, errnum, fmt, ap); + va_end(ap); +} + +void +pcap_vfmt_errmsg_for_win32_err(char *errbuf, size_t errbuflen, DWORD errnum, + const char *fmt, va_list ap) +{ size_t msglen; char *p; size_t errbuflen_remaining; DWORD retval; - char win32_errbuf[PCAP_ERRBUF_SIZE+1]; + wchar_t utf_16_errbuf[PCAP_ERRBUF_SIZE]; + size_t utf_8_len; - va_start(ap, fmt); - pcap_vsnprintf(errbuf, errbuflen, fmt, ap); - va_end(ap); + vsnprintf(errbuf, errbuflen, fmt, ap); msglen = strlen(errbuf); /* @@ -197,18 +438,39 @@ pcap_fmt_errmsg_for_win32_err(char *errbuf, size_t errbuflen, DWORD errnum, * get the message translated if it's in a language they don't * happen to understand. */ - retval = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_MAX_WIDTH_MASK, + retval = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, errnum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - win32_errbuf, PCAP_ERRBUF_SIZE, NULL); + utf_16_errbuf, PCAP_ERRBUF_SIZE, NULL); if (retval == 0) { /* * Failed. */ - pcap_snprintf(p, errbuflen_remaining, + snprintf(p, errbuflen_remaining, "Couldn't get error message for error (%lu)", errnum); return; } - pcap_snprintf(p, errbuflen_remaining, "%s (%lu)", win32_errbuf, errnum); + /* + * Now convert it from UTF-16LE to UTF-8. + */ + p = utf_16le_to_utf_8_truncated(utf_16_errbuf, p, errbuflen_remaining); + + /* + * Now append the error number, if it fits. + */ + utf_8_len = p - errbuf; + errbuflen_remaining -= utf_8_len; + if (utf_8_len == 0) { + /* The message was empty. */ + snprintf(p, errbuflen_remaining, "(%lu)", errnum); + } else + snprintf(p, errbuflen_remaining, " (%lu)", errnum); + + /* + * Now, if we're not in UTF-8 mode, convert errbuf to the + * local code page. + */ + if (!use_utf_8) + utf_8_to_acp_truncated(errbuf); } #endif diff --git a/external/bsd/libpcap/dist/fmtutils.h b/external/bsd/libpcap/dist/fmtutils.h index 838948bcd3d6..4fa344865205 100644 --- a/external/bsd/libpcap/dist/fmtutils.h +++ b/external/bsd/libpcap/dist/fmtutils.h @@ -34,18 +34,26 @@ #ifndef fmtutils_h #define fmtutils_h +#include /* we declare varargs functions */ + #include "pcap/funcattrs.h" #ifdef __cplusplus extern "C" { #endif +void pcap_fmt_set_encoding(unsigned int); + void pcap_fmt_errmsg_for_errno(char *, size_t, int, PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(4, 5); +void pcap_vfmt_errmsg_for_errno(char *, size_t, int, + PCAP_FORMAT_STRING(const char *), va_list) PCAP_PRINTFLIKE(4, 0); #ifdef _WIN32 void pcap_fmt_errmsg_for_win32_err(char *, size_t, DWORD, PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(4, 5); +void pcap_vfmt_errmsg_for_win32_err(char *, size_t, DWORD, + PCAP_FORMAT_STRING(const char *), va_list) PCAP_PRINTFLIKE(4, 0); #endif #ifdef __cplusplus diff --git a/external/bsd/libpcap/dist/ftmacros.h b/external/bsd/libpcap/dist/ftmacros.h index cd3daebdf175..7975463b3a69 100644 --- a/external/bsd/libpcap/dist/ftmacros.h +++ b/external/bsd/libpcap/dist/ftmacros.h @@ -45,7 +45,12 @@ * namespace to the maximum extent possible"? */ #if defined(sun) || defined(__sun) - #define __EXTENSIONS__ + /* + * On Solaris Clang defines __EXTENSIONS__ automatically. + */ + #ifndef __EXTENSIONS__ + #define __EXTENSIONS__ + #endif /* * We also need to define _XPG4_2 in order to get @@ -83,14 +88,18 @@ * 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) +#else /* * Turn on _GNU_SOURCE to get everything GNU libc has to offer, - * including asprintf(). + * including asprintf(), if we're using GNU libc. * * Unfortunately, one thing it has to offer is a strerror_r() * that's not POSIX-compliant, but we deal with that in * pcap_fmt_errmsg_for_errno(). + * + * We don't limit this to, for example, Linux and Cygwin, because + * this might, for example, be GNU/HURD or one of Debian's kFreeBSD + * OSes ("GNU/FreeBSD"). */ #define _GNU_SOURCE @@ -101,9 +110,18 @@ * 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. + * + * But, if it's already defined, don't define it, so that we don't + * get a warning of it being redefined if it's defined as, for + * example, 1. */ - #define _DEFAULT_SOURCE - #define _BSD_SOURCE + #ifndef _DEFAULT_SOURCE + #define _DEFAULT_SOURCE + #endif + /* Avoid redefining _BSD_SOURCE if it's already defined as for ex. 1 */ + #ifndef _BSD_SOURCE + #define _BSD_SOURCE + #endif #endif #endif diff --git a/external/bsd/libpcap/dist/grammar.y.in b/external/bsd/libpcap/dist/grammar.y.in new file mode 100644 index 000000000000..b6a3d18382ee --- /dev/null +++ b/external/bsd/libpcap/dist/grammar.y.in @@ -0,0 +1,871 @@ +/* + * We want a reentrant parser. + */ +@REENTRANT_PARSER@ + +/* + * We also want a reentrant scanner, so we have to pass the + * handle for the reentrant scanner to the parser, and the + * parser has to pass it to the lexical analyzer. + * + * We use void * rather than yyscan_t because, at least with some + * versions of Flex and Bison, if you use yyscan_t in %parse-param and + * %lex-param, you have to include scanner.h before grammar.h to get + * yyscan_t declared, and you have to include grammar.h before scanner.h + * to get YYSTYPE declared. Using void * breaks the cycle; the Flex + * documentation says yyscan_t is just a void *. + */ +%parse-param {void *yyscanner} +%lex-param {void *yyscanner} + +/* + * According to bison documentation, shift/reduce conflicts are not an issue + * in most parsers as long as the number does not evolve over time: + * https://www.gnu.org/software/bison/manual/html_node/Expect-Decl.html + * So, following the advice use %expect to check the amount of shift/reduce + * warnings. + * + * This doesn't appear to work in Berkeley YACC - 1.9 20170709; it still + * warns of 38 shift/reduce conflicts. + * + * The Berkeley YACC documentation: + * + * https://invisible-island.net/byacc/manpage/yacc.html + * + * claims that "Bison's support for "%expect" is broken in more than one + * release.", but doesn't give details. Hopefully, that only means that + * you get warnings even if you have the expected number of shift/reduce + * conflicts, not that anything else fails. + */ +%expect 38 + +/* + * And we need to pass the compiler state to the scanner. + */ +%parse-param { compiler_state_t *cstate } + +%{ +/* + * Copyright (c) 1988, 1989, 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. + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +/* + * grammar.h requires gencode.h and sometimes breaks in a polluted namespace + * (see ftmacros.h), so include it early. + */ +#include "gencode.h" +#include "grammar.h" + +#include + +#ifndef _WIN32 +#include +#include + +#if __STDC__ +struct mbuf; +struct rtentry; +#endif + +#include +#include +#endif /* _WIN32 */ + +#include + +#include "diag-control.h" + +#include "pcap-int.h" + +#include "scanner.h" + +#include "llc.h" +#include "ieee80211.h" +#include "pflog.h" +#include + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +#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 */ + const char *s; /* string */ +}; + +static const struct tok ieee80211_types[] = { + { IEEE80211_FC0_TYPE_DATA, "data" }, + { IEEE80211_FC0_TYPE_MGT, "mgt" }, + { IEEE80211_FC0_TYPE_MGT, "management" }, + { IEEE80211_FC0_TYPE_CTL, "ctl" }, + { IEEE80211_FC0_TYPE_CTL, "control" }, + { 0, NULL } +}; +static const struct tok ieee80211_mgt_subtypes[] = { + { IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assocreq" }, + { IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assoc-req" }, + { IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assocresp" }, + { IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assoc-resp" }, + { IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassocreq" }, + { IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassoc-req" }, + { IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassocresp" }, + { IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassoc-resp" }, + { IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probereq" }, + { IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probe-req" }, + { IEEE80211_FC0_SUBTYPE_PROBE_RESP, "proberesp" }, + { IEEE80211_FC0_SUBTYPE_PROBE_RESP, "probe-resp" }, + { IEEE80211_FC0_SUBTYPE_BEACON, "beacon" }, + { IEEE80211_FC0_SUBTYPE_ATIM, "atim" }, + { IEEE80211_FC0_SUBTYPE_DISASSOC, "disassoc" }, + { IEEE80211_FC0_SUBTYPE_DISASSOC, "disassociation" }, + { IEEE80211_FC0_SUBTYPE_AUTH, "auth" }, + { IEEE80211_FC0_SUBTYPE_AUTH, "authentication" }, + { IEEE80211_FC0_SUBTYPE_DEAUTH, "deauth" }, + { IEEE80211_FC0_SUBTYPE_DEAUTH, "deauthentication" }, + { 0, NULL } +}; +static const struct tok ieee80211_ctl_subtypes[] = { + { IEEE80211_FC0_SUBTYPE_PS_POLL, "ps-poll" }, + { IEEE80211_FC0_SUBTYPE_RTS, "rts" }, + { IEEE80211_FC0_SUBTYPE_CTS, "cts" }, + { IEEE80211_FC0_SUBTYPE_ACK, "ack" }, + { IEEE80211_FC0_SUBTYPE_CF_END, "cf-end" }, + { IEEE80211_FC0_SUBTYPE_CF_END_ACK, "cf-end-ack" }, + { 0, NULL } +}; +static const struct tok ieee80211_data_subtypes[] = { + { IEEE80211_FC0_SUBTYPE_DATA, "data" }, + { IEEE80211_FC0_SUBTYPE_CF_ACK, "data-cf-ack" }, + { IEEE80211_FC0_SUBTYPE_CF_POLL, "data-cf-poll" }, + { IEEE80211_FC0_SUBTYPE_CF_ACPL, "data-cf-ack-poll" }, + { IEEE80211_FC0_SUBTYPE_NODATA, "null" }, + { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK, "cf-ack" }, + { IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "cf-poll" }, + { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "cf-ack-poll" }, + { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_DATA, "qos-data" }, + { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK, "qos-data-cf-ack" }, + { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_POLL, "qos-data-cf-poll" }, + { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACPL, "qos-data-cf-ack-poll" }, + { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA, "qos" }, + { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "qos-cf-poll" }, + { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "qos-cf-ack-poll" }, + { 0, NULL } +}; +static const struct tok llc_s_subtypes[] = { + { LLC_RR, "rr" }, + { LLC_RNR, "rnr" }, + { LLC_REJ, "rej" }, + { 0, NULL } +}; +static const struct tok llc_u_subtypes[] = { + { LLC_UI, "ui" }, + { LLC_UA, "ua" }, + { LLC_DISC, "disc" }, + { LLC_DM, "dm" }, + { LLC_SABME, "sabme" }, + { LLC_TEST, "test" }, + { LLC_XID, "xid" }, + { LLC_FRMR, "frmr" }, + { 0, NULL } +}; +struct type2tok { + int type; + const struct tok *tok; +}; +static const struct type2tok ieee80211_type_subtypes[] = { + { IEEE80211_FC0_TYPE_MGT, ieee80211_mgt_subtypes }, + { IEEE80211_FC0_TYPE_CTL, ieee80211_ctl_subtypes }, + { IEEE80211_FC0_TYPE_DATA, ieee80211_data_subtypes }, + { 0, NULL } +}; + +static int +str2tok(const char *str, const struct tok *toks) +{ + int i; + + for (i = 0; toks[i].s != NULL; i++) { + if (pcap_strcasecmp(toks[i].s, str) == 0) { + /* + * Just in case somebody is using this to + * generate values of -1/0xFFFFFFFF. + * That won't work, as it's indistinguishable + * from an error. + */ + if (toks[i].v == -1) + abort(); + return (toks[i].v); + } + } + return (-1); +} + +static const struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF }; + +static void +yyerror(void *yyscanner _U_, compiler_state_t *cstate, const char *msg) +{ + bpf_set_error(cstate, "can't parse filter expression: %s", msg); +} + +static const struct tok pflog_reasons[] = { + { PFRES_MATCH, "match" }, + { PFRES_BADOFF, "bad-offset" }, + { PFRES_FRAG, "fragment" }, + { PFRES_SHORT, "short" }, + { PFRES_NORM, "normalize" }, + { PFRES_MEMORY, "memory" }, + { PFRES_TS, "bad-timestamp" }, + { PFRES_CONGEST, "congestion" }, + { PFRES_IPOPTIONS, "ip-option" }, + { PFRES_PROTCKSUM, "proto-cksum" }, + { PFRES_BADSTATE, "state-mismatch" }, + { PFRES_STATEINS, "state-insert" }, + { PFRES_MAXSTATES, "state-limit" }, + { PFRES_SRCLIMIT, "src-limit" }, + { PFRES_SYNPROXY, "synproxy" }, +#if defined(__FreeBSD__) + { PFRES_MAPFAILED, "map-failed" }, +#elif defined(__NetBSD__) + { PFRES_STATELOCKED, "state-locked" }, +#elif defined(__OpenBSD__) + { PFRES_TRANSLATE, "translate" }, + { PFRES_NOROUTE, "no-route" }, +#elif defined(__APPLE__) + { PFRES_DUMMYNET, "dummynet" }, +#endif + { 0, NULL } +}; + +static int +pfreason_to_num(compiler_state_t *cstate, const char *reason) +{ + int i; + + i = str2tok(reason, pflog_reasons); + if (i == -1) + bpf_set_error(cstate, "unknown PF reason \"%s\"", reason); + return (i); +} + +static const struct tok pflog_actions[] = { + { PF_PASS, "pass" }, + { PF_PASS, "accept" }, /* alias for "pass" */ + { PF_DROP, "drop" }, + { PF_DROP, "block" }, /* alias for "drop" */ + { PF_SCRUB, "scrub" }, + { PF_NOSCRUB, "noscrub" }, + { PF_NAT, "nat" }, + { PF_NONAT, "nonat" }, + { PF_BINAT, "binat" }, + { PF_NOBINAT, "nobinat" }, + { PF_RDR, "rdr" }, + { PF_NORDR, "nordr" }, + { PF_SYNPROXY_DROP, "synproxy-drop" }, +#if defined(__FreeBSD__) + { PF_DEFER, "defer" }, +#elif defined(__OpenBSD__) + { PF_DEFER, "defer" }, + { PF_MATCH, "match" }, + { PF_DIVERT, "divert" }, + { PF_RT, "rt" }, + { PF_AFRT, "afrt" }, +#elif defined(__APPLE__) + { PF_DUMMYNET, "dummynet" }, + { PF_NODUMMYNET, "nodummynet" }, + { PF_NAT64, "nat64" }, + { PF_NONAT64, "nonat64" }, +#endif + { 0, NULL }, +}; + +static int +pfaction_to_num(compiler_state_t *cstate, const char *action) +{ + int i; + + i = str2tok(action, pflog_actions); + if (i == -1) + bpf_set_error(cstate, "unknown PF action \"%s\"", action); + return (i); +} + +/* + * For calls that might return an "an error occurred" value. + */ +#define CHECK_INT_VAL(val) if (val == -1) YYABORT +#define CHECK_PTR_VAL(val) if (val == NULL) YYABORT + +DIAG_OFF_BISON_BYACC +%} + +%union { + int i; + bpf_u_int32 h; + char *s; + struct stmt *stmt; + struct arth *a; + struct { + struct qual q; + int atmfieldtype; + int mtp3fieldtype; + struct block *b; + } blk; + struct block *rblk; +} + +%type expr id nid pid term rterm qid +%type head +%type pqual dqual aqual ndaqual +%type arth narth +%type byteop pname relop irelop +%type pnum +%type and or paren not null prog +%type other pfvar p80211 pllc +%type atmtype atmmultitype +%type atmfield +%type atmfieldvalue atmvalue atmlistvalue +%type mtp2type +%type mtp3field +%type mtp3fieldvalue mtp3value mtp3listvalue + + +%token DST SRC HOST GATEWAY +%token NET NETMASK PORT PORTRANGE LESS GREATER PROTO PROTOCHAIN CBYTE +%token ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP CARP +%token ATALK AARP DECNET LAT SCA MOPRC MOPDL +%token TK_BROADCAST TK_MULTICAST +%token NUM INBOUND OUTBOUND +%token IFINDEX +%token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION +%token TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4 RA TA +%token LINK +%token GEQ LEQ NEQ +%token ID EID HID HID6 AID +%token LSH RSH +%token LEN +%token IPV6 ICMPV6 AH ESP +%token VLAN MPLS +%token PPPOED PPPOES GENEVE +%token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP +%token STP +%token IPX +%token NETBEUI +%token LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC +%token OAM OAMF4 CONNECTMSG METACONNECT +%token VPI VCI +%token RADIO +%token FISU LSSU MSU HFISU HLSSU HMSU +%token SIO OPC DPC SLS HSIO HOPC HDPC HSLS +%token LEX_ERROR + +%type ID EID AID +%type HID HID6 +%type NUM +%type action reason type subtype type_subtype dir + +%left OR AND +%nonassoc '!' +%left '|' +%left '&' +%left LSH RSH +%left '+' '-' +%left '*' '/' +%nonassoc UMINUS +%% +prog: null expr +{ + CHECK_INT_VAL(finish_parse(cstate, $2.b)); +} + | null + ; +null: /* null */ { $$.q = qerr; } + ; +expr: term + | expr and term { gen_and($1.b, $3.b); $$ = $3; } + | expr and id { gen_and($1.b, $3.b); $$ = $3; } + | expr or term { gen_or($1.b, $3.b); $$ = $3; } + | expr or id { gen_or($1.b, $3.b); $$ = $3; } + ; +and: AND { $$ = $0; } + ; +or: OR { $$ = $0; } + ; +id: nid + | pnum { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, $1, + $$.q = $0.q))); } + | paren pid ')' { $$ = $2; } + ; +nid: ID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_scode(cstate, $1, $$.q = $0.q))); } + | HID '/' NUM { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, NULL, $3, + $$.q = $0.q))); } + | HID NETMASK HID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, $3, 0, + $$.q = $0.q))); } + | HID { + CHECK_PTR_VAL($1); + /* Decide how to parse HID based on proto */ + $$.q = $0.q; + if ($$.q.addr == Q_PORT) { + bpf_set_error(cstate, "'port' modifier applied to ip host"); + YYABORT; + } else if ($$.q.addr == Q_PORTRANGE) { + bpf_set_error(cstate, "'portrange' modifier applied to ip host"); + YYABORT; + } else if ($$.q.addr == Q_PROTO) { + bpf_set_error(cstate, "'proto' modifier applied to ip host"); + YYABORT; + } else if ($$.q.addr == Q_PROTOCHAIN) { + bpf_set_error(cstate, "'protochain' modifier applied to ip host"); + YYABORT; + } + CHECK_PTR_VAL(($$.b = gen_ncode(cstate, $1, 0, $$.q))); + } + | HID6 '/' NUM { + CHECK_PTR_VAL($1); +#ifdef INET6 + CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, NULL, $3, + $$.q = $0.q))); +#else + bpf_set_error(cstate, "'ip6addr/prefixlen' not supported " + "in this configuration"); + YYABORT; +#endif /*INET6*/ + } + | HID6 { + CHECK_PTR_VAL($1); +#ifdef INET6 + CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, 0, 128, + $$.q = $0.q))); +#else + bpf_set_error(cstate, "'ip6addr' not supported " + "in this configuration"); + YYABORT; +#endif /*INET6*/ + } + | EID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_ecode(cstate, $1, $$.q = $0.q))); } + | AID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_acode(cstate, $1, $$.q = $0.q))); } + | not id { gen_not($2.b); $$ = $2; } + ; +not: '!' { $$ = $0; } + ; +paren: '(' { $$ = $0; } + ; +pid: nid + | qid and id { gen_and($1.b, $3.b); $$ = $3; } + | qid or id { gen_or($1.b, $3.b); $$ = $3; } + ; +qid: pnum { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, $1, + $$.q = $0.q))); } + | pid + ; +term: rterm + | not term { gen_not($2.b); $$ = $2; } + ; +head: pqual dqual aqual { QSET($$.q, $1, $2, $3); } + | pqual dqual { QSET($$.q, $1, $2, Q_DEFAULT); } + | pqual aqual { QSET($$.q, $1, Q_DEFAULT, $2); } + | pqual PROTO { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); } + | pqual PROTOCHAIN { +#ifdef NO_PROTOCHAIN + bpf_set_error(cstate, "protochain not supported"); + YYABORT; +#else + QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN); +#endif + } + | pqual ndaqual { QSET($$.q, $1, Q_DEFAULT, $2); } + ; +rterm: head id { $$ = $2; } + | paren expr ')' { $$.b = $2.b; $$.q = $1.q; } + | pname { CHECK_PTR_VAL(($$.b = gen_proto_abbrev(cstate, $1))); $$.q = qerr; } + | arth relop arth { CHECK_PTR_VAL(($$.b = gen_relation(cstate, $2, $1, $3, 0))); + $$.q = qerr; } + | arth irelop arth { CHECK_PTR_VAL(($$.b = gen_relation(cstate, $2, $1, $3, 1))); + $$.q = qerr; } + | other { $$.b = $1; $$.q = qerr; } + | atmtype { CHECK_PTR_VAL(($$.b = gen_atmtype_abbrev(cstate, $1))); $$.q = qerr; } + | atmmultitype { CHECK_PTR_VAL(($$.b = gen_atmmulti_abbrev(cstate, $1))); $$.q = qerr; } + | atmfield atmvalue { $$.b = $2.b; $$.q = qerr; } + | mtp2type { CHECK_PTR_VAL(($$.b = gen_mtp2type_abbrev(cstate, $1))); $$.q = qerr; } + | mtp3field mtp3value { $$.b = $2.b; $$.q = qerr; } + ; +/* protocol level qualifiers */ +pqual: pname + | { $$ = Q_DEFAULT; } + ; +/* 'direction' qualifiers */ +dqual: SRC { $$ = Q_SRC; } + | DST { $$ = Q_DST; } + | SRC OR DST { $$ = Q_OR; } + | DST OR SRC { $$ = Q_OR; } + | SRC AND DST { $$ = Q_AND; } + | DST AND SRC { $$ = Q_AND; } + | ADDR1 { $$ = Q_ADDR1; } + | ADDR2 { $$ = Q_ADDR2; } + | ADDR3 { $$ = Q_ADDR3; } + | ADDR4 { $$ = Q_ADDR4; } + | RA { $$ = Q_RA; } + | TA { $$ = Q_TA; } + ; +/* address type qualifiers */ +aqual: HOST { $$ = Q_HOST; } + | NET { $$ = Q_NET; } + | PORT { $$ = Q_PORT; } + | PORTRANGE { $$ = Q_PORTRANGE; } + ; +/* non-directional address type qualifiers */ +ndaqual: GATEWAY { $$ = Q_GATEWAY; } + ; +pname: LINK { $$ = Q_LINK; } + | IP { $$ = Q_IP; } + | ARP { $$ = Q_ARP; } + | RARP { $$ = Q_RARP; } + | SCTP { $$ = Q_SCTP; } + | TCP { $$ = Q_TCP; } + | UDP { $$ = Q_UDP; } + | ICMP { $$ = Q_ICMP; } + | IGMP { $$ = Q_IGMP; } + | IGRP { $$ = Q_IGRP; } + | PIM { $$ = Q_PIM; } + | VRRP { $$ = Q_VRRP; } + | CARP { $$ = Q_CARP; } + | ATALK { $$ = Q_ATALK; } + | AARP { $$ = Q_AARP; } + | DECNET { $$ = Q_DECNET; } + | LAT { $$ = Q_LAT; } + | SCA { $$ = Q_SCA; } + | MOPDL { $$ = Q_MOPDL; } + | MOPRC { $$ = Q_MOPRC; } + | IPV6 { $$ = Q_IPV6; } + | ICMPV6 { $$ = Q_ICMPV6; } + | AH { $$ = Q_AH; } + | ESP { $$ = Q_ESP; } + | ISO { $$ = Q_ISO; } + | ESIS { $$ = Q_ESIS; } + | ISIS { $$ = Q_ISIS; } + | L1 { $$ = Q_ISIS_L1; } + | L2 { $$ = Q_ISIS_L2; } + | IIH { $$ = Q_ISIS_IIH; } + | LSP { $$ = Q_ISIS_LSP; } + | SNP { $$ = Q_ISIS_SNP; } + | PSNP { $$ = Q_ISIS_PSNP; } + | CSNP { $$ = Q_ISIS_CSNP; } + | CLNP { $$ = Q_CLNP; } + | STP { $$ = Q_STP; } + | IPX { $$ = Q_IPX; } + | NETBEUI { $$ = Q_NETBEUI; } + | RADIO { $$ = Q_RADIO; } + ; +other: pqual TK_BROADCAST { CHECK_PTR_VAL(($$ = gen_broadcast(cstate, $1))); } + | pqual TK_MULTICAST { CHECK_PTR_VAL(($$ = gen_multicast(cstate, $1))); } + | LESS NUM { CHECK_PTR_VAL(($$ = gen_less(cstate, $2))); } + | GREATER NUM { CHECK_PTR_VAL(($$ = gen_greater(cstate, $2))); } + | CBYTE NUM byteop NUM { CHECK_PTR_VAL(($$ = gen_byteop(cstate, $3, $2, $4))); } + | INBOUND { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 0))); } + | OUTBOUND { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 1))); } + | IFINDEX NUM { CHECK_PTR_VAL(($$ = gen_ifindex(cstate, $2))); } + | VLAN pnum { CHECK_PTR_VAL(($$ = gen_vlan(cstate, $2, 1))); } + | VLAN { CHECK_PTR_VAL(($$ = gen_vlan(cstate, 0, 0))); } + | MPLS pnum { CHECK_PTR_VAL(($$ = gen_mpls(cstate, $2, 1))); } + | MPLS { CHECK_PTR_VAL(($$ = gen_mpls(cstate, 0, 0))); } + | PPPOED { CHECK_PTR_VAL(($$ = gen_pppoed(cstate))); } + | PPPOES pnum { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, $2, 1))); } + | PPPOES { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, 0, 0))); } + | GENEVE pnum { CHECK_PTR_VAL(($$ = gen_geneve(cstate, $2, 1))); } + | GENEVE { CHECK_PTR_VAL(($$ = gen_geneve(cstate, 0, 0))); } + | pfvar { $$ = $1; } + | pqual p80211 { $$ = $2; } + | pllc { $$ = $1; } + ; + +pfvar: PF_IFNAME ID { CHECK_PTR_VAL($2); CHECK_PTR_VAL(($$ = gen_pf_ifname(cstate, $2))); } + | PF_RSET ID { CHECK_PTR_VAL($2); CHECK_PTR_VAL(($$ = gen_pf_ruleset(cstate, $2))); } + | PF_RNR NUM { CHECK_PTR_VAL(($$ = gen_pf_rnr(cstate, $2))); } + | PF_SRNR NUM { CHECK_PTR_VAL(($$ = gen_pf_srnr(cstate, $2))); } + | PF_REASON reason { CHECK_PTR_VAL(($$ = gen_pf_reason(cstate, $2))); } + | PF_ACTION action { CHECK_PTR_VAL(($$ = gen_pf_action(cstate, $2))); } + ; + +p80211: TYPE type SUBTYPE subtype + { CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2 | $4, + IEEE80211_FC0_TYPE_MASK | + IEEE80211_FC0_SUBTYPE_MASK))); + } + | TYPE type { CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2, + IEEE80211_FC0_TYPE_MASK))); + } + | SUBTYPE type_subtype { CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2, + IEEE80211_FC0_TYPE_MASK | + IEEE80211_FC0_SUBTYPE_MASK))); + } + | DIR dir { CHECK_PTR_VAL(($$ = gen_p80211_fcdir(cstate, $2))); } + ; + +type: NUM { if (($1 & (~IEEE80211_FC0_TYPE_MASK)) != 0) { + bpf_set_error(cstate, "invalid 802.11 type value 0x%02x", $1); + YYABORT; + } + $$ = (int)$1; + } + | ID { CHECK_PTR_VAL($1); + $$ = str2tok($1, ieee80211_types); + if ($$ == -1) { + bpf_set_error(cstate, "unknown 802.11 type name \"%s\"", $1); + YYABORT; + } + } + ; + +subtype: NUM { if (($1 & (~IEEE80211_FC0_SUBTYPE_MASK)) != 0) { + bpf_set_error(cstate, "invalid 802.11 subtype value 0x%02x", $1); + YYABORT; + } + $$ = (int)$1; + } + | ID { const struct tok *types = NULL; + int i; + CHECK_PTR_VAL($1); + for (i = 0;; i++) { + if (ieee80211_type_subtypes[i].tok == NULL) { + /* Ran out of types */ + bpf_set_error(cstate, "unknown 802.11 type"); + YYABORT; + } + if ($-1 == ieee80211_type_subtypes[i].type) { + types = ieee80211_type_subtypes[i].tok; + break; + } + } + + $$ = str2tok($1, types); + if ($$ == -1) { + bpf_set_error(cstate, "unknown 802.11 subtype name \"%s\"", $1); + YYABORT; + } + } + ; + +type_subtype: ID { int i; + CHECK_PTR_VAL($1); + for (i = 0;; i++) { + if (ieee80211_type_subtypes[i].tok == NULL) { + /* Ran out of types */ + bpf_set_error(cstate, "unknown 802.11 type name"); + YYABORT; + } + $$ = str2tok($1, ieee80211_type_subtypes[i].tok); + if ($$ != -1) { + $$ |= ieee80211_type_subtypes[i].type; + break; + } + } + } + ; + +pllc: LLC { CHECK_PTR_VAL(($$ = gen_llc(cstate))); } + | LLC ID { CHECK_PTR_VAL($2); + if (pcap_strcasecmp($2, "i") == 0) { + CHECK_PTR_VAL(($$ = gen_llc_i(cstate))); + } else if (pcap_strcasecmp($2, "s") == 0) { + CHECK_PTR_VAL(($$ = gen_llc_s(cstate))); + } else if (pcap_strcasecmp($2, "u") == 0) { + CHECK_PTR_VAL(($$ = gen_llc_u(cstate))); + } else { + int subtype; + + subtype = str2tok($2, llc_s_subtypes); + if (subtype != -1) { + CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, subtype))); + } else { + subtype = str2tok($2, llc_u_subtypes); + if (subtype == -1) { + bpf_set_error(cstate, "unknown LLC type name \"%s\"", $2); + YYABORT; + } + CHECK_PTR_VAL(($$ = gen_llc_u_subtype(cstate, subtype))); + } + } + } + /* sigh, "rnr" is already a keyword for PF */ + | LLC PF_RNR { CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, LLC_RNR))); } + ; + +dir: NUM { $$ = (int)$1; } + | ID { CHECK_PTR_VAL($1); + if (pcap_strcasecmp($1, "nods") == 0) + $$ = IEEE80211_FC1_DIR_NODS; + else if (pcap_strcasecmp($1, "tods") == 0) + $$ = IEEE80211_FC1_DIR_TODS; + else if (pcap_strcasecmp($1, "fromds") == 0) + $$ = IEEE80211_FC1_DIR_FROMDS; + else if (pcap_strcasecmp($1, "dstods") == 0) + $$ = IEEE80211_FC1_DIR_DSTODS; + else { + bpf_set_error(cstate, "unknown 802.11 direction"); + YYABORT; + } + } + ; + +reason: NUM { $$ = $1; } + | ID { CHECK_PTR_VAL($1); CHECK_INT_VAL(($$ = pfreason_to_num(cstate, $1))); } + ; + +action: ID { CHECK_PTR_VAL($1); CHECK_INT_VAL(($$ = pfaction_to_num(cstate, $1))); } + ; + +relop: '>' { $$ = BPF_JGT; } + | GEQ { $$ = BPF_JGE; } + | '=' { $$ = BPF_JEQ; } + ; +irelop: LEQ { $$ = BPF_JGT; } + | '<' { $$ = BPF_JGE; } + | NEQ { $$ = BPF_JEQ; } + ; +arth: pnum { CHECK_PTR_VAL(($$ = gen_loadi(cstate, $1))); } + | narth + ; +narth: pname '[' arth ']' { CHECK_PTR_VAL(($$ = gen_load(cstate, $1, $3, 1))); } + | pname '[' arth ':' NUM ']' { CHECK_PTR_VAL(($$ = gen_load(cstate, $1, $3, $5))); } + | arth '+' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_ADD, $1, $3))); } + | arth '-' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_SUB, $1, $3))); } + | arth '*' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_MUL, $1, $3))); } + | arth '/' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_DIV, $1, $3))); } + | arth '%' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_MOD, $1, $3))); } + | arth '&' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_AND, $1, $3))); } + | arth '|' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_OR, $1, $3))); } + | arth '^' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_XOR, $1, $3))); } + | arth LSH arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_LSH, $1, $3))); } + | arth RSH arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_RSH, $1, $3))); } + | '-' arth %prec UMINUS { CHECK_PTR_VAL(($$ = gen_neg(cstate, $2))); } + | paren narth ')' { $$ = $2; } + | LEN { CHECK_PTR_VAL(($$ = gen_loadlen(cstate))); } + ; +byteop: '&' { $$ = '&'; } + | '|' { $$ = '|'; } + | '<' { $$ = '<'; } + | '>' { $$ = '>'; } + | '=' { $$ = '='; } + ; +pnum: NUM + | paren pnum ')' { $$ = $2; } + ; +atmtype: LANE { $$ = A_LANE; } + | METAC { $$ = A_METAC; } + | BCC { $$ = A_BCC; } + | OAMF4EC { $$ = A_OAMF4EC; } + | OAMF4SC { $$ = A_OAMF4SC; } + | SC { $$ = A_SC; } + | ILMIC { $$ = A_ILMIC; } + ; +atmmultitype: OAM { $$ = A_OAM; } + | OAMF4 { $$ = A_OAMF4; } + | CONNECTMSG { $$ = A_CONNECTMSG; } + | METACONNECT { $$ = A_METACONNECT; } + ; + /* ATM field types quantifier */ +atmfield: VPI { $$.atmfieldtype = A_VPI; } + | VCI { $$.atmfieldtype = A_VCI; } + ; +atmvalue: atmfieldvalue + | relop NUM { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $0.atmfieldtype, $2, $1, 0))); } + | irelop NUM { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $0.atmfieldtype, $2, $1, 1))); } + | paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; } + ; +atmfieldvalue: NUM { + $$.atmfieldtype = $0.atmfieldtype; + if ($$.atmfieldtype == A_VPI || + $$.atmfieldtype == A_VCI) + CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $$.atmfieldtype, $1, BPF_JEQ, 0))); + } + ; +atmlistvalue: atmfieldvalue + | atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; } + ; + /* MTP2 types quantifier */ +mtp2type: FISU { $$ = M_FISU; } + | LSSU { $$ = M_LSSU; } + | MSU { $$ = M_MSU; } + | HFISU { $$ = MH_FISU; } + | HLSSU { $$ = MH_LSSU; } + | HMSU { $$ = MH_MSU; } + ; + /* MTP3 field types quantifier */ +mtp3field: SIO { $$.mtp3fieldtype = M_SIO; } + | OPC { $$.mtp3fieldtype = M_OPC; } + | DPC { $$.mtp3fieldtype = M_DPC; } + | SLS { $$.mtp3fieldtype = M_SLS; } + | HSIO { $$.mtp3fieldtype = MH_SIO; } + | HOPC { $$.mtp3fieldtype = MH_OPC; } + | HDPC { $$.mtp3fieldtype = MH_DPC; } + | HSLS { $$.mtp3fieldtype = MH_SLS; } + ; +mtp3value: mtp3fieldvalue + | relop NUM { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $0.mtp3fieldtype, $2, $1, 0))); } + | irelop NUM { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $0.mtp3fieldtype, $2, $1, 1))); } + | paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; } + ; +mtp3fieldvalue: NUM { + $$.mtp3fieldtype = $0.mtp3fieldtype; + if ($$.mtp3fieldtype == M_SIO || + $$.mtp3fieldtype == M_OPC || + $$.mtp3fieldtype == M_DPC || + $$.mtp3fieldtype == M_SLS || + $$.mtp3fieldtype == MH_SIO || + $$.mtp3fieldtype == MH_OPC || + $$.mtp3fieldtype == MH_DPC || + $$.mtp3fieldtype == MH_SLS) + CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $$.mtp3fieldtype, $1, BPF_JEQ, 0))); + } + ; +mtp3listvalue: mtp3fieldvalue + | mtp3listvalue or mtp3fieldvalue { gen_or($1.b, $3.b); $$ = $3; } + ; +%% diff --git a/external/bsd/libpcap/dist/libpcap.pc.in b/external/bsd/libpcap/dist/libpcap.pc.in index d74cbc55dddd..629e662ab09e 100644 --- a/external/bsd/libpcap/dist/libpcap.pc.in +++ b/external/bsd/libpcap/dist/libpcap.pc.in @@ -13,6 +13,7 @@ libdir="@libdir@" Name: libpcap Description: Platform-independent network traffic capture library Version: @PACKAGE_VERSION@ -Libs: -L${libdir} -l@PACKAGE_NAME@ -Libs.private: @LIBS@ +Requires.private: @REQUIRES_PRIVATE@ +Libs: -L${libdir} @RPATH@ -l@PACKAGE_NAME@ +Libs.private: @LIBS_PRIVATE@ Cflags: -I${includedir} diff --git a/external/bsd/libpcap/dist/missing/asprintf.c b/external/bsd/libpcap/dist/missing/asprintf.c index 3aa55ed9d65d..b65310e1db21 100644 --- a/external/bsd/libpcap/dist/missing/asprintf.c +++ b/external/bsd/libpcap/dist/missing/asprintf.c @@ -20,7 +20,7 @@ pcap_vasprintf(char **strp, const char *format, va_list args) int ret; /* - * XXX - the C99 standard says, in section 7.19.6.5 "Thes + * XXX - the C99 standard says, in section 7.19.6.5 "The * nprintf function": * * The snprintf function is equivalent to fprintf, except that diff --git a/external/bsd/libpcap/dist/missing/getopt.c b/external/bsd/libpcap/dist/missing/getopt.c index 7c897c6f5936..c535776d849c 100644 --- a/external/bsd/libpcap/dist/missing/getopt.c +++ b/external/bsd/libpcap/dist/missing/getopt.c @@ -80,9 +80,18 @@ getopt(int nargc, char * const *nargv, const char *ostr) place = EMSG; return (-1); } - } /* option letter okay? */ - if ((optopt = (int)*place++) == (int)':' || - !(oli = strchr(ostr, optopt))) { + } + optopt = (int)*place++; + if (optopt == (int)':') { /* option letter okay? */ + if (!*place) + ++optind; + if (opterr && *ostr != ':') + (void)fprintf(stderr, + "%s: illegal option -- %c\n", __progname, optopt); + return (BADCH); + } + oli = strchr(ostr, optopt); + if (!oli) { /* * if the user didn't specify '-' as an option, * assume it means -1. @@ -114,7 +123,7 @@ getopt(int nargc, char * const *nargv, const char *ostr) __progname, optopt); return (BADCH); } - else /* white space */ + else /* white space */ optarg = nargv[optind]; place = EMSG; ++optind; diff --git a/external/bsd/libpcap/dist/missing/win_asprintf.c b/external/bsd/libpcap/dist/missing/win_asprintf.c index cce6296065fc..e4bd13c61920 100644 --- a/external/bsd/libpcap/dist/missing/win_asprintf.c +++ b/external/bsd/libpcap/dist/missing/win_asprintf.c @@ -23,7 +23,7 @@ pcap_vasprintf(char **strp, const char *format, va_list args) *strp = NULL; return (-1); } - ret = pcap_vsnprintf(str, str_size, format, args); + ret = vsnprintf(str, str_size, format, args); if (ret == -1) { free(str); *strp = NULL; @@ -31,7 +31,7 @@ pcap_vasprintf(char **strp, const char *format, va_list args) } *strp = str; /* - * pcap_vsnprintf() shouldn't truncate the string, as we have + * vsnprintf() shouldn't truncate the string, as we have * allocated a buffer large enough to hold the string, so its * return value should be the number of characters printed. */ diff --git a/external/bsd/libpcap/dist/mkdep b/external/bsd/libpcap/dist/mkdep index 1486b185aa43..f85a447a79c6 100755 --- a/external/bsd/libpcap/dist/mkdep +++ b/external/bsd/libpcap/dist/mkdep @@ -16,7 +16,10 @@ MAKE=Makefile # default makefile name is "Makefile" CC=cc # default C compiler is "cc" DEPENDENCY_CFLAG=-M # default dependency-generation flag is -M +SOURCE_DIRECTORY=. # default source directory is the current directory +# No command-line flags seen yet. +flags="" while : do case "$1" in # -c allows you to specify the C compiler @@ -39,13 +42,29 @@ while : -p) SED='s;\.o;;' shift ;; + + # -s allows you to specify the source directory + -s) + SOURCE_DIRECTORY=$2 + shift; shift ;; + + # -include takes an argument + -include) + flags="$flags $1 $2" + shift; shift ;; + + # other command-line flag + -*) + flags="$flags $1" + shift ;; + *) break ;; esac done if [ $# = 0 ] ; then - echo 'usage: mkdep [-p] [-c cc] [-f makefile] [-m dependency-cflag] [flags] file ...' + echo 'usage: mkdep [-p] [-c cc] [-f makefile] [-m dependency-cflag] [-s source-directory] [flags] file ...' exit 1 fi @@ -73,33 +92,23 @@ _EOF_ # hack can't deal with anything that requires a search path, and doesn't # even try for anything using bracket (<>) syntax. # -# egrep '^#include[ ]*".*"' /dev/null $* | +# grep -E '^#include[[:blank:]]*".*"' /dev/null $* | # sed -e 's/:[^"]*"\([^"]*\)".*/: \1/' -e 's/\.c/.o/' | +# +# Construct a list of source files with paths relative to the source directory. +# +sources="" +for srcfile in $* +do + sources="$sources $SOURCE_DIRECTORY/$srcfile" +done + # XXX this doesn't work with things like "-DDECLWAITSTATUS=union\ wait" -$CC $DEPENDENCY_CFLAG $* | +$CC $DEPENDENCY_CFLAG $flags $sources | sed " s; \./; ;g - $SED" | -awk '{ - if ($1 != prev) { - if (rec != "") - print rec; - rec = $0; - prev = $1; - } - else { - if (length(rec $2) > 78) { - print rec; - rec = $0; - } - else - rec = rec " " $2 - } -} -END { - print rec -}' >> $TMP + $SED" >> $TMP cat << _EOF_ >> $TMP diff --git a/external/bsd/libpcap/dist/msdos/makefile b/external/bsd/libpcap/dist/msdos/makefile index 599a619f402e..84819aae3f0c 100644 --- a/external/bsd/libpcap/dist/msdos/makefile +++ b/external/bsd/libpcap/dist/msdos/makefile @@ -104,7 +104,7 @@ clean: # pkt_rx0.obj: msdos\pkt_rx0.asm -bpf_filt.obj: bpf_filt.c pcap-int.h pcap.h pcap-bpf.h gnuc.h +bpf_filt.obj: bpf_filt.c pcap-int.h pcap.h pcap-bpf.h bpf_imag.obj: bpf_imag.c pcap-int.h pcap.h pcap-bpf.h @@ -134,7 +134,7 @@ nametoad.obj: nametoad.c pcap-int.h pcap.h pcap-bpf.h gencode.h \ pcap-dos.obj: pcap-dos.c pcap.h pcap-bpf.h pcap-dos.h pcap-int.h \ msdos\pktdrvr.h -pktdrvr.obj: msdos\pktdrvr.c gnuc.h pcap-dos.h pcap-int.h \ +pktdrvr.obj: msdos\pktdrvr.c pcap-dos.h pcap-int.h \ pcap.h pcap-bpf.h msdos\pktdrvr.h msdos\pkt_stub.inc ndis2.obj: msdos\ndis2.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \ @@ -142,7 +142,7 @@ ndis2.obj: msdos\ndis2.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \ pkt_rx0.o32: msdos\pkt_rx0.asm -bpf_filt.o32: bpf_filt.c pcap-int.h pcap.h pcap-bpf.h gnuc.h +bpf_filt.o32: bpf_filt.c pcap-int.h pcap.h pcap-bpf.h bpf_imag.o32: bpf_imag.c pcap-int.h pcap.h pcap-bpf.h @@ -172,7 +172,7 @@ nametoad.o32: nametoad.c pcap-int.h pcap.h pcap-bpf.h gencode.h \ pcap-dos.o32: pcap-dos.c pcap.h pcap-bpf.h pcap-dos.h pcap-int.h \ msdos\pktdrvr.h -pktdrvr.o32: msdos\pktdrvr.c gnuc.h pcap-dos.h pcap-int.h \ +pktdrvr.o32: msdos\pktdrvr.c pcap-dos.h pcap-int.h \ pcap.h pcap-bpf.h msdos\pktdrvr.h msdos\pkt_stub.inc ndis2.o32: msdos\ndis2.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \ diff --git a/external/bsd/libpcap/dist/msdos/readme.dos b/external/bsd/libpcap/dist/msdos/readme.dos index b95483fc9b4a..ec056dd0bd61 100644 --- a/external/bsd/libpcap/dist/msdos/readme.dos +++ b/external/bsd/libpcap/dist/msdos/readme.dos @@ -24,7 +24,7 @@ Note for djgpp users: If you got the libpcap from the official site www.tcpdump, then that distribution does NOT contain any sources for building 32-bit drivers. Instead get the full version at - http://www.watt-32.net/pcap/libpcap.zip + https://www.watt-32.net/pcap/libpcap.zip and set "USE_32BIT_DRIVERS = 1" in msdos\common.dj. @@ -51,12 +51,12 @@ The following packages and tools must be present for all targets. receive network data. It's mostly used to access the 'hosts' file and other features. Get 'watt32s*.zip' at: - http://www.watt-32.net + https://www.watt-32.net 2. Exception handler and disassember library (libexc.a) is needed if "USE_EXCEPT = 1" in common.dj. Available at: - http://www.watt-32.net/misc/exc_dx07.zip + https://www.watt-32.net/misc/exc_dx07.zip 3. Flex & Bison is used to generate parser for the filter handler pcap_compile: @@ -65,7 +65,7 @@ The following packages and tools must be present for all targets. 4. NASM assembler v 0.98 or later is required when building djgpp and Watcom targets: - http://www.nasm.us/ + https://www.nasm.us/ 5. sed (Stream Editor) is required for doing `make depend'. It's available at: diff --git a/external/bsd/libpcap/dist/org.tcpdump.chmod_bpf.plist b/external/bsd/libpcap/dist/org.tcpdump.chmod_bpf.plist index 8ad685261a3f..f6fdfec77fa8 100644 --- a/external/bsd/libpcap/dist/org.tcpdump.chmod_bpf.plist +++ b/external/bsd/libpcap/dist/org.tcpdump.chmod_bpf.plist @@ -1,5 +1,5 @@ - + Label diff --git a/external/bsd/libpcap/dist/pcap-airpcap.c b/external/bsd/libpcap/dist/pcap-airpcap.c new file mode 100644 index 000000000000..510e4c4e6a27 --- /dev/null +++ b/external/bsd/libpcap/dist/pcap-airpcap.c @@ -0,0 +1,1054 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2010 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 +#endif + +#include "pcap-int.h" + +#include + +#include "pcap-airpcap.h" + +/* Default size of the buffer we allocate in userland. */ +#define AIRPCAP_DEFAULT_USER_BUFFER_SIZE 256000 + +/* Default size of the buffer for the AirPcap adapter. */ +#define AIRPCAP_DEFAULT_KERNEL_BUFFER_SIZE 1000000 + +// +// We load the AirPcap DLL dynamically, so that the code will +// work whether you have it installed or not, and there don't +// have to be two different versions of the library, one linked +// to the AirPcap library and one not linked to it. +// +static pcap_code_handle_t airpcap_lib; + +typedef PCHAR (*AirpcapGetLastErrorHandler)(PAirpcapHandle); +typedef BOOL (*AirpcapGetDeviceListHandler)(PAirpcapDeviceDescription *, PCHAR); +typedef VOID (*AirpcapFreeDeviceListHandler)(PAirpcapDeviceDescription); +typedef PAirpcapHandle (*AirpcapOpenHandler)(PCHAR, PCHAR); +typedef VOID (*AirpcapCloseHandler)(PAirpcapHandle); +typedef BOOL (*AirpcapSetDeviceMacFlagsHandler)(PAirpcapHandle, UINT); +typedef BOOL (*AirpcapSetLinkTypeHandler)(PAirpcapHandle, AirpcapLinkType); +typedef BOOL (*AirpcapGetLinkTypeHandler)(PAirpcapHandle, PAirpcapLinkType); +typedef BOOL (*AirpcapSetKernelBufferHandler)(PAirpcapHandle, UINT); +typedef BOOL (*AirpcapSetFilterHandler)(PAirpcapHandle, PVOID, UINT); +typedef BOOL (*AirpcapSetMinToCopyHandler)(PAirpcapHandle, UINT); +typedef BOOL (*AirpcapGetReadEventHandler)(PAirpcapHandle, HANDLE *); +typedef BOOL (*AirpcapReadHandler)(PAirpcapHandle, PBYTE, UINT, PUINT); +typedef BOOL (*AirpcapWriteHandler)(PAirpcapHandle, PCHAR, ULONG); +typedef BOOL (*AirpcapGetStatsHandler)(PAirpcapHandle, PAirpcapStats); + +static AirpcapGetLastErrorHandler p_AirpcapGetLastError; +static AirpcapGetDeviceListHandler p_AirpcapGetDeviceList; +static AirpcapFreeDeviceListHandler p_AirpcapFreeDeviceList; +static AirpcapOpenHandler p_AirpcapOpen; +static AirpcapCloseHandler p_AirpcapClose; +static AirpcapSetDeviceMacFlagsHandler p_AirpcapSetDeviceMacFlags; +static AirpcapSetLinkTypeHandler p_AirpcapSetLinkType; +static AirpcapGetLinkTypeHandler p_AirpcapGetLinkType; +static AirpcapSetKernelBufferHandler p_AirpcapSetKernelBuffer; +static AirpcapSetFilterHandler p_AirpcapSetFilter; +static AirpcapSetMinToCopyHandler p_AirpcapSetMinToCopy; +static AirpcapGetReadEventHandler p_AirpcapGetReadEvent; +static AirpcapReadHandler p_AirpcapRead; +static AirpcapWriteHandler p_AirpcapWrite; +static AirpcapGetStatsHandler p_AirpcapGetStats; + +typedef enum LONG +{ + AIRPCAP_API_UNLOADED = 0, + AIRPCAP_API_LOADED, + AIRPCAP_API_CANNOT_LOAD, + AIRPCAP_API_LOADING +} AIRPCAP_API_LOAD_STATUS; + +static AIRPCAP_API_LOAD_STATUS airpcap_load_status; + +/* + * NOTE: this function should be called by the pcap functions that can + * theoretically deal with the AirPcap library for the first time, + * namely listing the adapters and creating a pcap_t for an adapter. + * All the other ones (activate, close, read, write, set parameters) + * work on a pcap_t for an AirPcap device, meaning we've already + * created the pcap_t and thus have loaded the functions, so we do + * not need to call this function. + */ +static AIRPCAP_API_LOAD_STATUS +load_airpcap_functions(void) +{ + AIRPCAP_API_LOAD_STATUS current_status; + + /* + * We don't use a mutex because there's no place that + * we can guarantee we'll be called before any threads + * other than the main thread exists. (For example, + * this might be a static library, so we can't arrange + * to be called by DllMain(), and there's no guarantee + * that the application called pcap_init() - which is + * supposed to be called only from one thread - so + * we can't arrange to be called from it.) + * + * If nobody's tried to load it yet, mark it as + * loading; in any case, return the status before + * we modified it. + */ + current_status = InterlockedCompareExchange((LONG *)&airpcap_load_status, + AIRPCAP_API_LOADING, AIRPCAP_API_UNLOADED); + + /* + * If the status was AIRPCAP_API_UNLOADED, we've set it + * to AIRPCAP_API_LOADING, because we're going to be + * the ones to load the library but current_status is + * AIRPCAP_API_UNLOADED. + * + * if it was AIRPCAP_API_LOADING, meaning somebody else + * was trying to load it, spin until they finish and + * set the status to a value reflecting whether they + * succeeded. + */ + while (current_status == AIRPCAP_API_LOADING) { + current_status = InterlockedCompareExchange((LONG*)&airpcap_load_status, + AIRPCAP_API_LOADING, AIRPCAP_API_LOADING); + Sleep(10); + } + + /* + * At this point, current_status is either: + * + * AIRPCAP_API_LOADED, in which case another thread + * loaded the library, so we're done; + * + * AIRPCAP_API_CANNOT_LOAD, in which another thread + * tried and failed to load the library, so we're + * done - we won't try it ourselves; + * + * AIRPCAP_API_LOADING, in which case *we're* the + * ones loading it, and should now try to do so. + */ + if (current_status == AIRPCAP_API_LOADED) + return AIRPCAP_API_LOADED; + + if (current_status == AIRPCAP_API_CANNOT_LOAD) + return AIRPCAP_API_CANNOT_LOAD; + + /* + * Start out assuming we can't load it. + */ + current_status = AIRPCAP_API_CANNOT_LOAD; + + airpcap_lib = pcap_load_code("airpcap.dll"); + if (airpcap_lib != NULL) { + /* + * OK, we've loaded the library; now try to find the + * functions we need in it. + */ + p_AirpcapGetLastError = (AirpcapGetLastErrorHandler) pcap_find_function(airpcap_lib, "AirpcapGetLastError"); + p_AirpcapGetDeviceList = (AirpcapGetDeviceListHandler) pcap_find_function(airpcap_lib, "AirpcapGetDeviceList"); + p_AirpcapFreeDeviceList = (AirpcapFreeDeviceListHandler) pcap_find_function(airpcap_lib, "AirpcapFreeDeviceList"); + p_AirpcapOpen = (AirpcapOpenHandler) pcap_find_function(airpcap_lib, "AirpcapOpen"); + p_AirpcapClose = (AirpcapCloseHandler) pcap_find_function(airpcap_lib, "AirpcapClose"); + p_AirpcapSetDeviceMacFlags = (AirpcapSetDeviceMacFlagsHandler) pcap_find_function(airpcap_lib, "AirpcapSetDeviceMacFlags"); + p_AirpcapSetLinkType = (AirpcapSetLinkTypeHandler) pcap_find_function(airpcap_lib, "AirpcapSetLinkType"); + p_AirpcapGetLinkType = (AirpcapGetLinkTypeHandler) pcap_find_function(airpcap_lib, "AirpcapGetLinkType"); + p_AirpcapSetKernelBuffer = (AirpcapSetKernelBufferHandler) pcap_find_function(airpcap_lib, "AirpcapSetKernelBuffer"); + p_AirpcapSetFilter = (AirpcapSetFilterHandler) pcap_find_function(airpcap_lib, "AirpcapSetFilter"); + p_AirpcapSetMinToCopy = (AirpcapSetMinToCopyHandler) pcap_find_function(airpcap_lib, "AirpcapSetMinToCopy"); + p_AirpcapGetReadEvent = (AirpcapGetReadEventHandler) pcap_find_function(airpcap_lib, "AirpcapGetReadEvent"); + p_AirpcapRead = (AirpcapReadHandler) pcap_find_function(airpcap_lib, "AirpcapRead"); + p_AirpcapWrite = (AirpcapWriteHandler) pcap_find_function(airpcap_lib, "AirpcapWrite"); + p_AirpcapGetStats = (AirpcapGetStatsHandler) pcap_find_function(airpcap_lib, "AirpcapGetStats"); + + // + // Make sure that we found everything + // + if (p_AirpcapGetLastError != NULL && + p_AirpcapGetDeviceList != NULL && + p_AirpcapFreeDeviceList != NULL && + p_AirpcapOpen != NULL && + p_AirpcapClose != NULL && + p_AirpcapSetDeviceMacFlags != NULL && + p_AirpcapSetLinkType != NULL && + p_AirpcapGetLinkType != NULL && + p_AirpcapSetKernelBuffer != NULL && + p_AirpcapSetFilter != NULL && + p_AirpcapSetMinToCopy != NULL && + p_AirpcapGetReadEvent != NULL && + p_AirpcapRead != NULL && + p_AirpcapWrite != NULL && + p_AirpcapGetStats != NULL) { + /* + * We have all we need. + */ + current_status = AIRPCAP_API_LOADED; + } + } + + if (current_status != AIRPCAP_API_LOADED) { + /* + * We failed; if we found the DLL, close the + * handle for it. + */ + if (airpcap_lib != NULL) { + FreeLibrary(airpcap_lib); + airpcap_lib = NULL; + } + } + + /* + * Now set the status appropriately - and atomically. + */ + InterlockedExchange((LONG *)&airpcap_load_status, current_status); + + return current_status; +} + +/* + * Private data for capturing on AirPcap devices. + */ +struct pcap_airpcap { + PAirpcapHandle adapter; + int filtering_in_kernel; + int nonblock; + int read_timeout; + HANDLE read_event; + struct pcap_stat stat; +}; + +static int +airpcap_setfilter(pcap_t *p, struct bpf_program *fp) +{ + struct pcap_airpcap *pa = p->priv; + + if (!p_AirpcapSetFilter(pa->adapter, fp->bf_insns, + fp->bf_len * sizeof(struct bpf_insn))) { + /* + * Kernel filter not installed. + * + * XXX - we don't know whether this failed because: + * + * the kernel rejected the filter program as invalid, + * in which case we should fall back on userland + * filtering; + * + * the kernel rejected the filter program as too big, + * in which case we should again fall back on + * userland filtering; + * + * there was some other problem, in which case we + * should probably report an error; + * + * So we just fall back on userland filtering in + * all cases. + */ + + /* + * install_bpf_program() validates the program. + * + * XXX - what if we already have a filter in the kernel? + */ + if (install_bpf_program(p, fp) < 0) + return (-1); + pa->filtering_in_kernel = 0; /* filtering in userland */ + return (0); + } + + /* + * It worked. + */ + pa->filtering_in_kernel = 1; /* filtering in the kernel */ + + /* + * Discard any previously-received packets, as they might have + * passed whatever filter was formerly in effect, but might + * not pass this filter (BIOCSETF discards packets buffered + * in the kernel, so you can lose packets in any case). + */ + p->cc = 0; + return (0); +} + +static int +airpcap_set_datalink(pcap_t *p, int dlt) +{ + struct pcap_airpcap *pa = p->priv; + AirpcapLinkType type; + + switch (dlt) { + + case DLT_IEEE802_11_RADIO: + type = AIRPCAP_LT_802_11_PLUS_RADIO; + break; + + case DLT_PPI: + type = AIRPCAP_LT_802_11_PLUS_PPI; + break; + + case DLT_IEEE802_11: + type = AIRPCAP_LT_802_11; + break; + + default: + /* This can't happen; just return. */ + return (0); + } + if (!p_AirpcapSetLinkType(pa->adapter, type)) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "AirpcapSetLinkType() failed: %s", + p_AirpcapGetLastError(pa->adapter)); + return (-1); + } + p->linktype = dlt; + return (0); +} + +static int +airpcap_getnonblock(pcap_t *p) +{ + struct pcap_airpcap *pa = p->priv; + + return (pa->nonblock); +} + +static int +airpcap_setnonblock(pcap_t *p, int nonblock) +{ + struct pcap_airpcap *pa = p->priv; + int newtimeout; + + if (nonblock) { + /* + * Set the packet buffer timeout to -1 for non-blocking + * mode. + */ + newtimeout = -1; + } else { + /* + * Restore the timeout set when the device was opened. + * (Note that this may be -1, in which case we're not + * really leaving non-blocking mode. However, although + * the timeout argument to pcap_set_timeout() and + * pcap_open_live() is an int, you're not supposed to + * supply a negative value, so that "shouldn't happen".) + */ + newtimeout = p->opt.timeout; + } + pa->read_timeout = newtimeout; + pa->nonblock = (newtimeout == -1); + return (0); +} + +static int +airpcap_stats(pcap_t *p, struct pcap_stat *ps) +{ + struct pcap_airpcap *pa = p->priv; + AirpcapStats tas; + + /* + * Try to get statistics. + */ + if (!p_AirpcapGetStats(pa->adapter, &tas)) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "AirpcapGetStats() failed: %s", + p_AirpcapGetLastError(pa->adapter)); + return (-1); + } + + ps->ps_drop = tas.Drops; + ps->ps_recv = tas.Recvs; + ps->ps_ifdrop = tas.IfDrops; + + return (0); +} + +/* + * Win32-only routine for getting statistics. + * + * This way is definitely safer than passing the pcap_stat * from the userland. + * In fact, there could happen than the user allocates a variable which is not + * big enough for the new structure, and the library will write in a zone + * which is not allocated to this variable. + * + * In this way, we're pretty sure we are writing on memory allocated to this + * variable. + * + * XXX - but this is the wrong way to handle statistics. Instead, we should + * have an API that returns data in a form like the Options section of a + * pcapng Interface Statistics Block: + * + * https://xml2rfc.tools.ietf.org/cgi-bin/xml2rfc.cgi?url=https://raw.githubusercontent.com/pcapng/pcapng/master/draft-tuexen-opsawg-pcapng.xml&modeAsFormat=html/ascii&type=ascii#rfc.section.4.6 + * + * which would let us add new statistics straightforwardly and indicate which + * statistics we are and are *not* providing, rather than having to provide + * possibly-bogus values for statistics we can't provide. + */ +static struct pcap_stat * +airpcap_stats_ex(pcap_t *p, int *pcap_stat_size) +{ + struct pcap_airpcap *pa = p->priv; + AirpcapStats tas; + + *pcap_stat_size = sizeof (p->stat); + + /* + * Try to get statistics. + */ + if (!p_AirpcapGetStats(pa->adapter, &tas)) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "AirpcapGetStats() failed: %s", + p_AirpcapGetLastError(pa->adapter)); + return (NULL); + } + + p->stat.ps_recv = tas.Recvs; + p->stat.ps_drop = tas.Drops; + p->stat.ps_ifdrop = tas.IfDrops; + /* + * Just in case this is ever compiled for a target other than + * Windows, which is extremely unlikely at best. + */ +#ifdef _WIN32 + p->stat.ps_capt = tas.Capt; +#endif + return (&p->stat); +} + +/* Set the dimension of the kernel-level capture buffer */ +static int +airpcap_setbuff(pcap_t *p, int dim) +{ + struct pcap_airpcap *pa = p->priv; + + if (!p_AirpcapSetKernelBuffer(pa->adapter, dim)) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "AirpcapSetKernelBuffer() failed: %s", + p_AirpcapGetLastError(pa->adapter)); + return (-1); + } + return (0); +} + +/* Set the driver working mode */ +static int +airpcap_setmode(pcap_t *p, int mode) +{ + if (mode != MODE_CAPT) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "Only MODE_CAPT is supported on an AirPcap adapter"); + return (-1); + } + return (0); +} + +/*set the minimum amount of data that will release a read call*/ +static int +airpcap_setmintocopy(pcap_t *p, int size) +{ + struct pcap_airpcap *pa = p->priv; + + if (!p_AirpcapSetMinToCopy(pa->adapter, size)) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "AirpcapSetMinToCopy() failed: %s", + p_AirpcapGetLastError(pa->adapter)); + return (-1); + } + return (0); +} + +static HANDLE +airpcap_getevent(pcap_t *p) +{ + struct pcap_airpcap *pa = p->priv; + + return (pa->read_event); +} + +static int +airpcap_oid_get_request(pcap_t *p, bpf_u_int32 oid _U_, void *data _U_, + size_t *lenp _U_) +{ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "Getting OID values is not supported on an AirPcap adapter"); + return (PCAP_ERROR); +} + +static int +airpcap_oid_set_request(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_, + size_t *lenp _U_) +{ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "Setting OID values is not supported on an AirPcap adapter"); + return (PCAP_ERROR); +} + +static u_int +airpcap_sendqueue_transmit(pcap_t *p, pcap_send_queue *queue _U_, int sync _U_) +{ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "Cannot queue packets for transmission on an AirPcap adapter"); + return (0); +} + +static int +airpcap_setuserbuffer(pcap_t *p, int size) +{ + unsigned char *new_buff; + + if (size <= 0) { + /* Bogus parameter */ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "Error: invalid size %d",size); + return (-1); + } + + /* Allocate the buffer */ + new_buff = (unsigned char *)malloc(sizeof(char)*size); + + if (!new_buff) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "Error: not enough memory"); + return (-1); + } + + free(p->buffer); + + p->buffer = new_buff; + p->bufsize = size; + + return (0); +} + +static int +airpcap_live_dump(pcap_t *p, char *filename _U_, int maxsize _U_, + int maxpacks _U_) +{ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "AirPcap adapters don't support live dump"); + return (-1); +} + +static int +airpcap_live_dump_ended(pcap_t *p, int sync _U_) +{ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "AirPcap adapters don't support live dump"); + return (-1); +} + +static PAirpcapHandle +airpcap_get_airpcap_handle(pcap_t *p) +{ + struct pcap_airpcap *pa = p->priv; + + return (pa->adapter); +} + +static int +airpcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) +{ + struct pcap_airpcap *pa = p->priv; + int cc; + int n; + register u_char *bp, *ep; + UINT bytes_read; + u_char *datap; + + cc = p->cc; + if (cc == 0) { + /* + * 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); + } + + // + // If we're not in non-blocking mode, wait for data to + // arrive. + // + if (pa->read_timeout != -1) { + WaitForSingleObject(pa->read_event, + (pa->read_timeout ==0 )? INFINITE: pa->read_timeout); + } + + // + // Read the data. + // p_AirpcapRead doesn't block. + // + if (!p_AirpcapRead(pa->adapter, (PBYTE)p->buffer, + p->bufsize, &bytes_read)) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "AirpcapRead() failed: %s", + p_AirpcapGetLastError(pa->adapter)); + return (-1); + } + cc = bytes_read; + bp = (u_char *)p->buffer; + } else + bp = p->bp; + + /* + * Loop through each packet. + * + * This assumes that a single buffer of packets will have + * <= INT_MAX packets, so the packet count doesn't overflow. + */ +#define bhp ((AirpcapBpfHeader *)bp) + n = 0; + ep = bp + cc; + for (;;) { + register u_int caplen, hdrlen; + + /* + * 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 (p->break_loop) { + if (n == 0) { + p->break_loop = 0; + return (PCAP_ERROR_BREAK); + } else { + p->bp = bp; + p->cc = (int) (ep - bp); + return (n); + } + } + if (bp >= ep) + break; + + caplen = bhp->Caplen; + hdrlen = bhp->Hdrlen; + datap = bp + hdrlen; + /* + * Short-circuit evaluation: if using BPF filter + * in the AirPcap adapter, no need to do it now - + * we already know the packet passed the filter. + */ + if (pa->filtering_in_kernel || + p->fcode.bf_insns == NULL || + pcap_filter(p->fcode.bf_insns, datap, bhp->Originallen, caplen)) { + struct pcap_pkthdr pkthdr; + + pkthdr.ts.tv_sec = bhp->TsSec; + pkthdr.ts.tv_usec = bhp->TsUsec; + pkthdr.caplen = caplen; + pkthdr.len = bhp->Originallen; + (*callback)(user, &pkthdr, datap); + bp += AIRPCAP_WORDALIGN(caplen + hdrlen); + if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt)) { + p->bp = bp; + p->cc = (int)(ep - bp); + return (n); + } + } else { + /* + * Skip this packet. + */ + bp += AIRPCAP_WORDALIGN(caplen + hdrlen); + } + } +#undef bhp + p->cc = 0; + return (n); +} + +static int +airpcap_inject(pcap_t *p, const void *buf, int size) +{ + struct pcap_airpcap *pa = p->priv; + + /* + * XXX - the second argument to AirpcapWrite() *should* have + * been declared as a const pointer - a write function that + * stomps on what it writes is *extremely* rude - but such + * is life. We assume it is, in fact, not going to write on + * our buffer. + */ + if (!p_AirpcapWrite(pa->adapter, (void *)buf, size)) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "AirpcapWrite() failed: %s", + p_AirpcapGetLastError(pa->adapter)); + return (-1); + } + + /* + * We assume it all got sent if "AirpcapWrite()" succeeded. + * "pcap_inject()" is expected to return the number of bytes + * sent. + */ + return (size); +} + +static void +airpcap_cleanup(pcap_t *p) +{ + struct pcap_airpcap *pa = p->priv; + + if (pa->adapter != NULL) { + p_AirpcapClose(pa->adapter); + pa->adapter = NULL; + } + pcap_cleanup_live_common(p); +} + +static void +airpcap_breakloop(pcap_t *p) +{ + HANDLE read_event; + + pcap_breakloop_common(p); + struct pcap_airpcap *pa = p->priv; + + /* XXX - what if either of these fail? */ + /* + * XXX - will SetEvent() force a wakeup and, if so, will + * the AirPcap read code handle that sanely? + */ + if (!p_AirpcapGetReadEvent(pa->adapter, &read_event)) + return; + SetEvent(read_event); +} + +static int +airpcap_activate(pcap_t *p) +{ + struct pcap_airpcap *pa = p->priv; + char *device = p->opt.device; + char airpcap_errbuf[AIRPCAP_ERRBUF_SIZE]; + BOOL status; + AirpcapLinkType link_type; + + pa->adapter = p_AirpcapOpen(device, airpcap_errbuf); + if (pa->adapter == NULL) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s", airpcap_errbuf); + return (PCAP_ERROR); + } + + /* + * Set monitor mode appropriately. + * Always turn off the "ACK frames sent to the card" mode. + */ + if (p->opt.rfmon) { + status = p_AirpcapSetDeviceMacFlags(pa->adapter, + AIRPCAP_MF_MONITOR_MODE_ON); + } else + status = p_AirpcapSetDeviceMacFlags(pa->adapter, + AIRPCAP_MF_ACK_FRAMES_ON); + if (!status) { + p_AirpcapClose(pa->adapter); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "AirpcapSetDeviceMacFlags() failed: %s", + p_AirpcapGetLastError(pa->adapter)); + 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 (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) + p->snapshot = MAXIMUM_SNAPLEN; + + /* + * If the buffer size wasn't explicitly set, default to + * AIRPCAP_DEFAULT_KERNEL_BUFFER_SIZE. + */ + if (p->opt.buffer_size == 0) + p->opt.buffer_size = AIRPCAP_DEFAULT_KERNEL_BUFFER_SIZE; + + if (!p_AirpcapSetKernelBuffer(pa->adapter, p->opt.buffer_size)) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "AirpcapSetKernelBuffer() failed: %s", + p_AirpcapGetLastError(pa->adapter)); + goto bad; + } + + if(!p_AirpcapGetReadEvent(pa->adapter, &pa->read_event)) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "AirpcapGetReadEvent() failed: %s", + p_AirpcapGetLastError(pa->adapter)); + goto bad; + } + + /* Set the buffer size */ + p->bufsize = AIRPCAP_DEFAULT_USER_BUFFER_SIZE; + p->buffer = malloc(p->bufsize); + if (p->buffer == NULL) { + 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 (!p_AirpcapSetMinToCopy(pa->adapter, 0)) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "AirpcapSetMinToCopy() failed: %s", + p_AirpcapGetLastError(pa->adapter)); + goto bad; + } + } else { + /* + * Tell the driver to copy the buffer only if it contains + * at least 16K. + */ + if (!p_AirpcapSetMinToCopy(pa->adapter, 16000)) { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "AirpcapSetMinToCopy() failed: %s", + p_AirpcapGetLastError(pa->adapter)); + goto bad; + } + } + + /* + * Find out what the default link-layer header type is, + * and set p->datalink to that. + * + * We don't force it to another value because there + * might be some programs using WinPcap/Npcap that, + * when capturing on AirPcap devices, assume the + * default value set with the AirPcap configuration + * program is what you get. + * + * The out-of-the-box default appears to be radiotap. + */ + if (!p_AirpcapGetLinkType(pa->adapter, &link_type)) { + /* That failed. */ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "AirpcapGetLinkType() failed: %s", + p_AirpcapGetLastError(pa->adapter)); + goto bad; + } + switch (link_type) { + + case AIRPCAP_LT_802_11_PLUS_RADIO: + p->linktype = DLT_IEEE802_11_RADIO; + break; + + case AIRPCAP_LT_802_11_PLUS_PPI: + p->linktype = DLT_PPI; + break; + + case AIRPCAP_LT_802_11: + p->linktype = DLT_IEEE802_11; + break; + + case AIRPCAP_LT_UNKNOWN: + default: + /* OK, what? */ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "AirpcapGetLinkType() returned unknown link type %u", + link_type); + goto bad; + } + + /* + * Now provide a list of all the supported types; we + * assume they all work. We put radiotap at the top, + * followed by PPI, followed by "no radio metadata". + */ + p->dlt_list = (u_int *) malloc(sizeof(u_int) * 3); + if (p->dlt_list == NULL) + goto bad; + p->dlt_list[0] = DLT_IEEE802_11_RADIO; + p->dlt_list[1] = DLT_PPI; + p->dlt_list[2] = DLT_IEEE802_11; + p->dlt_count = 3; + + p->read_op = airpcap_read; + p->inject_op = airpcap_inject; + p->setfilter_op = airpcap_setfilter; + p->setdirection_op = NULL; /* Not implemented. */ + p->set_datalink_op = airpcap_set_datalink; + p->getnonblock_op = airpcap_getnonblock; + p->setnonblock_op = airpcap_setnonblock; + p->breakloop_op = airpcap_breakloop; + p->stats_op = airpcap_stats; + p->stats_ex_op = airpcap_stats_ex; + p->setbuff_op = airpcap_setbuff; + p->setmode_op = airpcap_setmode; + p->setmintocopy_op = airpcap_setmintocopy; + p->getevent_op = airpcap_getevent; + p->oid_get_request_op = airpcap_oid_get_request; + p->oid_set_request_op = airpcap_oid_set_request; + p->sendqueue_transmit_op = airpcap_sendqueue_transmit; + p->setuserbuffer_op = airpcap_setuserbuffer; + p->live_dump_op = airpcap_live_dump; + p->live_dump_ended_op = airpcap_live_dump_ended; + p->get_airpcap_handle_op = airpcap_get_airpcap_handle; + p->cleanup_op = airpcap_cleanup; + + return (0); + bad: + airpcap_cleanup(p); + return (PCAP_ERROR); +} + +/* + * Monitor mode is supported. + */ +static int +airpcap_can_set_rfmon(pcap_t *p) +{ + return (1); +} + +int +device_is_airpcap(const char *device, char *ebuf) +{ + static const char airpcap_prefix[] = "\\\\.\\airpcap"; + + /* + * We don't determine this by calling AirpcapGetDeviceList() + * and looking at the list, as that appears to be a costly + * operation. + * + * Instead, we just check whether it begins with "\\.\airpcap". + */ + if (strncmp(device, airpcap_prefix, sizeof airpcap_prefix - 1) == 0) { + /* + * Yes, it's an AirPcap device. + */ + return (1); + } + + /* + * No, it's not an AirPcap device. + */ + return (0); +} + +pcap_t * +airpcap_create(const char *device, char *ebuf, int *is_ours) +{ + int ret; + pcap_t *p; + + /* + * This can be called before we've tried loading the library, + * so do so if we haven't already tried to do so. + */ + if (load_airpcap_functions() != AIRPCAP_API_LOADED) { + /* + * We assume this means that we don't have the AirPcap + * software installed, which probably means we don't + * have an AirPcap device. + * + * Don't treat that as an error. + */ + *is_ours = 0; + return (NULL); + } + + /* + * Is this an AirPcap device? + */ + ret = device_is_airpcap(device, ebuf); + if (ret == 0) { + /* No. */ + *is_ours = 0; + return (NULL); + } + + /* + * Yes. + */ + *is_ours = 1; + p = PCAP_CREATE_COMMON(ebuf, struct pcap_airpcap); + if (p == NULL) + return (NULL); + + p->activate_op = airpcap_activate; + p->can_set_rfmon_op = airpcap_can_set_rfmon; + return (p); +} + +/* + * Add all AirPcap devices. + */ +int +airpcap_findalldevs(pcap_if_list_t *devlistp, char *errbuf) +{ + AirpcapDeviceDescription *airpcap_devices, *airpcap_device; + char airpcap_errbuf[AIRPCAP_ERRBUF_SIZE]; + + /* + * This can be called before we've tried loading the library, + * so do so if we haven't already tried to do so. + */ + if (load_airpcap_functions() != AIRPCAP_API_LOADED) { + /* + * XXX - unless the error is "no such DLL", report this + * as an error rather than as "no AirPcap devices"? + */ + return (0); + } + + if (!p_AirpcapGetDeviceList(&airpcap_devices, airpcap_errbuf)) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "AirpcapGetDeviceList() failed: %s", airpcap_errbuf); + return (-1); + } + + for (airpcap_device = airpcap_devices; airpcap_device != NULL; + airpcap_device = airpcap_device->next) { + if (add_dev(devlistp, airpcap_device->Name, 0, + airpcap_device->Description, errbuf) == NULL) { + /* + * Failure. + */ + p_AirpcapFreeDeviceList(airpcap_devices); + return (-1); + } + } + p_AirpcapFreeDeviceList(airpcap_devices); + return (0); +} diff --git a/external/bsd/libpcap/dist/pcap-airpcap.h b/external/bsd/libpcap/dist/pcap-airpcap.h new file mode 100644 index 000000000000..aa1164ed4c89 --- /dev/null +++ b/external/bsd/libpcap/dist/pcap-airpcap.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2010 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. + * + */ + +pcap_t *airpcap_create(const char *, char *, int *); +int airpcap_findalldevs(pcap_if_list_t *devlistp, char *errbuf); +int device_is_airpcap(const char *device, char *ebuf); diff --git a/external/bsd/libpcap/dist/pcap-dll.rc b/external/bsd/libpcap/dist/pcap-dll.rc index fc4f42b26ef0..85de542f085f 100644 --- a/external/bsd/libpcap/dist/pcap-dll.rc +++ b/external/bsd/libpcap/dist/pcap-dll.rc @@ -20,12 +20,12 @@ 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 "FileVersion", PACKAGE_VERSION VALUE "InternalName", PACKAGE_NAME VALUE "LegalCopyright", "Copyright (c) The TCPdump Group" VALUE "LegalTrademarks", "" - VALUE "OriginalFilename", "wpcap.dll" - VALUE "ProductName", PACKAGE_NAME + VALUE "OriginalFilename", PACKAGE_NAME ".dll" + VALUE "ProductName", "libpcap" VALUE "ProductVersion", PACKAGE_VERSION END END diff --git a/external/bsd/libpcap/dist/pcap-dpdk.c b/external/bsd/libpcap/dist/pcap-dpdk.c new file mode 100644 index 000000000000..025a67482c0f --- /dev/null +++ b/external/bsd/libpcap/dist/pcap-dpdk.c @@ -0,0 +1,1086 @@ +/* + * Copyright (C) 2018 jingle YANG. 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. + */ + +/* +Date: Dec 16, 2018 + +Description: +1. Pcap-dpdk provides libpcap the ability to use DPDK with the device name as dpdk:{portid}, such as dpdk:0. +2. DPDK is a set of libraries and drivers for fast packet processing. (https://www.dpdk.org/) +3. The testprogs/capturetest provides 6.4Gbps/800,000 pps on Intel 10-Gigabit X540-AT2 with DPDK 18.11. + +Limitations: +1. DPDK support will be on if DPDK is available. Please set DIR for --with-dpdk[=DIR] with ./configure or -DDPDK_DIR[=DIR] with cmake if DPDK is installed manually. +2. Only support link libdpdk.so dynamically, because the libdpdk.a will not work correctly. +3. Only support read operation, and packet injection has not been supported yet. + +Usage: +1. Compile DPDK as shared library and install.(https://github.com/DPDK/dpdk.git) + +You shall modify the file $RTE_SDK/$RTE_TARGET/.config and set: +CONFIG_RTE_BUILD_SHARED_LIB=y +By the following command: +sed -i 's/CONFIG_RTE_BUILD_SHARED_LIB=n/CONFIG_RTE_BUILD_SHARED_LIB=y/' $RTE_SDK/$RTE_TARGET/.config + +2. Launch l2fwd that is one of DPDK examples correctly, and get device information. + +You shall learn how to bind nic with DPDK-compatible driver by $RTE_SDK/usertools/dpdk-devbind.py, such as igb_uio. +And enable hugepages by dpdk-setup.sh + +Then launch the l2fwd with dynamic driver support. For example: +$RTE_SDK/examples/l2fwd/$RTE_TARGET/l2fwd -dlibrte_pmd_e1000.so -dlibrte_pmd_ixgbe.so -dlibrte_mempool_ring.so -- -p 0x1 + +3. Compile libpcap with dpdk options. + +If DPDK has not been found automatically, you shall export DPDK environment variable which are used for compiling DPDK. And then pass $RTE_SDK/$RTE_TARGET to --with-dpdk or -DDPDK_DIR + +export RTE_SDK={your DPDK base directory} +export RTE_TARGET={your target name} + +3.1 With configure + +./configure --with-dpdk=$RTE_SDK/$RTE_TARGET && make -s all && make -s testprogs && make install + +3.2 With cmake + +mkdir -p build && cd build && cmake -DDPDK_DIR=$RTE_SDK/$RTE_TARGET ../ && make -s all && make -s testprogs && make install + +4. Link your own program with libpcap, and use DPDK with the device name as dpdk:{portid}, such as dpdk:0. +And you shall set DPDK configure options by environment variable DPDK_CFG +For example, the testprogs/capturetest could be lanched by: + +env DPDK_CFG="--log-level=debug -l0 -dlibrte_pmd_e1000.so -dlibrte_pmd_ixgbe.so -dlibrte_mempool_ring.so" ./capturetest -i dpdk:0 +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include /* for INT_MAX */ +#include + +#include + +//header for calling dpdk +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pcap-int.h" +#include "pcap-dpdk.h" + +/* + * Deal with API changes that break source compatibility. + */ + +#ifdef HAVE_STRUCT_RTE_ETHER_ADDR +#define ETHER_ADDR_TYPE struct rte_ether_addr +#else +#define ETHER_ADDR_TYPE struct ether_addr +#endif + +#define DPDK_DEF_LOG_LEV RTE_LOG_ERR +// +// This is set to 0 if we haven't initialized DPDK yet, 1 if we've +// successfully initialized it, a negative value, which is the negative +// of the rte_errno from rte_eal_init(), if we tried to initialize it +// and got an error. +// +static int is_dpdk_pre_inited=0; +#define DPDK_LIB_NAME "libpcap_dpdk" +#define DPDK_DESC "Data Plane Development Kit (DPDK) Interface" +#define DPDK_ERR_PERM_MSG "permission denied, DPDK needs root permission" +#define DPDK_ARGC_MAX 64 +#define DPDK_CFG_MAX_LEN 1024 +#define DPDK_DEV_NAME_MAX 32 +#define DPDK_DEV_DESC_MAX 512 +#define DPDK_CFG_ENV_NAME "DPDK_CFG" +#define DPDK_DEF_MIN_SLEEP_MS 1 +static char dpdk_cfg_buf[DPDK_CFG_MAX_LEN]; +#define DPDK_MAC_ADDR_SIZE 32 +#define DPDK_DEF_MAC_ADDR "00:00:00:00:00:00" +#define DPDK_PCI_ADDR_SIZE 16 +#define DPDK_DEF_CFG "--log-level=error -l0 -dlibrte_pmd_e1000.so -dlibrte_pmd_ixgbe.so -dlibrte_mempool_ring.so" +#define DPDK_PREFIX "dpdk:" +#define DPDK_PORTID_MAX 65535U +#define MBUF_POOL_NAME "mbuf_pool" +#define DPDK_TX_BUF_NAME "tx_buffer" +//The number of elements in the mbuf pool. +#define DPDK_NB_MBUFS 8192U +#define MEMPOOL_CACHE_SIZE 256 +#define MAX_PKT_BURST 32 +// Configurable number of RX/TX ring descriptors +#define RTE_TEST_RX_DESC_DEFAULT 1024 +#define RTE_TEST_TX_DESC_DEFAULT 1024 + +static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; +static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; + +#ifdef RTE_ETHER_MAX_JUMBO_FRAME_LEN +#define RTE_ETH_PCAP_SNAPLEN RTE_ETHER_MAX_JUMBO_FRAME_LEN +#else +#define RTE_ETH_PCAP_SNAPLEN ETHER_MAX_JUMBO_FRAME_LEN +#endif + +static struct rte_eth_dev_tx_buffer *tx_buffer; + +struct dpdk_ts_helper{ + struct timeval start_time; + uint64_t start_cycles; + uint64_t hz; +}; +struct pcap_dpdk{ + pcap_t * orig; + uint16_t portid; // portid of DPDK + int must_clear_promisc; + uint64_t bpf_drop; + int nonblock; + struct timeval required_select_timeout; + struct timeval prev_ts; + struct rte_eth_stats prev_stats; + struct timeval curr_ts; + struct rte_eth_stats curr_stats; + uint64_t pps; + uint64_t bps; + struct rte_mempool * pktmbuf_pool; + struct dpdk_ts_helper ts_helper; + ETHER_ADDR_TYPE eth_addr; + char mac_addr[DPDK_MAC_ADDR_SIZE]; + char pci_addr[DPDK_PCI_ADDR_SIZE]; + unsigned char pcap_tmp_buf[RTE_ETH_PCAP_SNAPLEN]; +}; + +static struct rte_eth_conf port_conf = { + .rxmode = { + .split_hdr_size = 0, + }, + .txmode = { + .mq_mode = ETH_MQ_TX_NONE, + }, +}; + +static void dpdk_fmt_errmsg_for_rte_errno(char *, size_t, int, + PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(4, 5); + +/* + * Generate an error message based on a format, arguments, and an + * rte_errno, with a message for the rte_errno after the formatted output. + */ +static void dpdk_fmt_errmsg_for_rte_errno(char *errbuf, size_t errbuflen, + int errnum, const char *fmt, ...) +{ + va_list ap; + size_t msglen; + char *p; + size_t errbuflen_remaining; + + va_start(ap, fmt); + 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. + * rte_strerror() is thread-safe, at least as of dpdk 18.11, + * unlike strerror() - it uses strerror_r() rather than strerror() + * for UN*X errno values, and prints to what I assume is a per-thread + * buffer (based on the "PER_LCORE" in "RTE_DEFINE_PER_LCORE" used + * to declare the buffers statically) for DPDK errors. + */ + snprintf(p, errbuflen_remaining, "%s", rte_strerror(errnum)); +} + +static int dpdk_init_timer(struct pcap_dpdk *pd){ + gettimeofday(&(pd->ts_helper.start_time),NULL); + pd->ts_helper.start_cycles = rte_get_timer_cycles(); + pd->ts_helper.hz = rte_get_timer_hz(); + if (pd->ts_helper.hz == 0){ + return -1; + } + return 0; +} +static inline void calculate_timestamp(struct dpdk_ts_helper *helper,struct timeval *ts) +{ + uint64_t cycles; + // delta + struct timeval cur_time; + cycles = rte_get_timer_cycles() - helper->start_cycles; + cur_time.tv_sec = (time_t)(cycles/helper->hz); + cur_time.tv_usec = (suseconds_t)((cycles%helper->hz)*1e6/helper->hz); + timeradd(&(helper->start_time), &cur_time, ts); +} + +static uint32_t dpdk_gather_data(unsigned char *data, uint32_t len, struct rte_mbuf *mbuf) +{ + uint32_t total_len = 0; + while (mbuf && (total_len+mbuf->data_len) < len ){ + rte_memcpy(data+total_len, rte_pktmbuf_mtod(mbuf,void *),mbuf->data_len); + total_len+=mbuf->data_len; + mbuf=mbuf->next; + } + return total_len; +} + + +static int dpdk_read_with_timeout(pcap_t *p, struct rte_mbuf **pkts_burst, const uint16_t burst_cnt){ + struct pcap_dpdk *pd = (struct pcap_dpdk*)(p->priv); + int nb_rx = 0; + int timeout_ms = p->opt.timeout; + int sleep_ms = 0; + if (pd->nonblock){ + // In non-blocking mode, just read once, no matter how many packets are captured. + nb_rx = (int)rte_eth_rx_burst(pd->portid, 0, pkts_burst, burst_cnt); + }else{ + // In blocking mode, read many times until packets are captured or timeout or break_loop is set. + // if timeout_ms == 0, it may be blocked forever. + while (timeout_ms == 0 || sleep_ms < timeout_ms){ + nb_rx = (int)rte_eth_rx_burst(pd->portid, 0, pkts_burst, burst_cnt); + if (nb_rx){ // got packets within timeout_ms + break; + }else{ // no packet arrives at this round. + if (p->break_loop){ + break; + } + // sleep for a very short while. + // block sleep is the only choice, since usleep() will impact performance dramatically. + rte_delay_us_block(DPDK_DEF_MIN_SLEEP_MS*1000); + sleep_ms += DPDK_DEF_MIN_SLEEP_MS; + } + } + } + return nb_rx; +} + +static int pcap_dpdk_dispatch(pcap_t *p, int max_cnt, pcap_handler cb, u_char *cb_arg) +{ + struct pcap_dpdk *pd = (struct pcap_dpdk*)(p->priv); + int burst_cnt = 0; + int nb_rx = 0; + struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; + struct rte_mbuf *m; + struct pcap_pkthdr pcap_header; + // In DPDK, pkt_len is sum of lengths for all segments. And data_len is for one segment + uint32_t pkt_len = 0; + uint32_t caplen = 0; + u_char *bp = NULL; + int i=0; + unsigned int gather_len =0; + int pkt_cnt = 0; + u_char *large_buffer=NULL; + int timeout_ms = p->opt.timeout; + + /* + * This can conceivably process more than INT_MAX packets, + * which would overflow the packet count, causing it either + * to look like a negative number, and thus cause us to + * return a value that looks like an error, or overflow + * back into positive territory, and thus cause us to + * return a too-low count. + * + * Therefore, if the packet count is unlimited, we clip + * it at INT_MAX; this routine is not expected to + * process packets indefinitely, so that's not an issue. + */ + if (PACKET_COUNT_IS_UNLIMITED(max_cnt)) + max_cnt = INT_MAX; + + if (max_cnt < MAX_PKT_BURST){ + burst_cnt = max_cnt; + }else{ + burst_cnt = MAX_PKT_BURST; + } + + while( pkt_cnt < max_cnt){ + if (p->break_loop){ + p->break_loop = 0; + return PCAP_ERROR_BREAK; + } + // read once in non-blocking mode, or try many times waiting for timeout_ms. + // if timeout_ms == 0, it will be blocked until one packet arrives or break_loop is set. + nb_rx = dpdk_read_with_timeout(p, pkts_burst, burst_cnt); + if (nb_rx == 0){ + if (pd->nonblock){ + RTE_LOG(DEBUG, USER1, "dpdk: no packets available in non-blocking mode.\n"); + }else{ + if (p->break_loop){ + RTE_LOG(DEBUG, USER1, "dpdk: no packets available and break_loop is set in blocking mode.\n"); + p->break_loop = 0; + return PCAP_ERROR_BREAK; + + } + RTE_LOG(DEBUG, USER1, "dpdk: no packets available for timeout %d ms in blocking mode.\n", timeout_ms); + } + // break if dpdk reads 0 packet, no matter in blocking(timeout) or non-blocking mode. + break; + } + pkt_cnt += nb_rx; + for ( i = 0; i < nb_rx; i++) { + m = pkts_burst[i]; + calculate_timestamp(&(pd->ts_helper),&(pcap_header.ts)); + pkt_len = rte_pktmbuf_pkt_len(m); + // caplen = min(pkt_len, p->snapshot); + // caplen will not be changed, no matter how long the rte_pktmbuf + caplen = pkt_len < (uint32_t)p->snapshot ? pkt_len: (uint32_t)p->snapshot; + pcap_header.caplen = caplen; + pcap_header.len = pkt_len; + // volatile prefetch + rte_prefetch0(rte_pktmbuf_mtod(m, void *)); + bp = NULL; + if (m->nb_segs == 1) + { + bp = rte_pktmbuf_mtod(m, u_char *); + }else{ + // use fast buffer pcap_tmp_buf if pkt_len is small, no need to call malloc and free + if ( pkt_len <= RTE_ETH_PCAP_SNAPLEN) + { + gather_len = dpdk_gather_data(pd->pcap_tmp_buf, RTE_ETH_PCAP_SNAPLEN, m); + bp = pd->pcap_tmp_buf; + }else{ + // need call free later + large_buffer = (u_char *)malloc(caplen*sizeof(u_char)); + gather_len = dpdk_gather_data(large_buffer, caplen, m); + bp = large_buffer; + } + + } + if (bp){ + if (p->fcode.bf_insns==NULL || pcap_filter(p->fcode.bf_insns, bp, pcap_header.len, pcap_header.caplen)){ + cb(cb_arg, &pcap_header, bp); + }else{ + pd->bpf_drop++; + } + } + //free all pktmbuf + rte_pktmbuf_free(m); + if (large_buffer){ + free(large_buffer); + large_buffer=NULL; + } + } + } + return pkt_cnt; +} + +static int pcap_dpdk_inject(pcap_t *p, const void *buf _U_, int size _U_) +{ + //not implemented yet + pcap_strlcpy(p->errbuf, + "dpdk error: Inject function has not been implemented yet", + PCAP_ERRBUF_SIZE); + return PCAP_ERROR; +} + +static void pcap_dpdk_close(pcap_t *p) +{ + struct pcap_dpdk *pd = p->priv; + if (pd==NULL) + { + return; + } + if (pd->must_clear_promisc) + { + rte_eth_promiscuous_disable(pd->portid); + } + rte_eth_dev_stop(pd->portid); + rte_eth_dev_close(pd->portid); + pcap_cleanup_live_common(p); +} + +static void nic_stats_display(struct pcap_dpdk *pd) +{ + uint16_t portid = pd->portid; + struct rte_eth_stats stats; + rte_eth_stats_get(portid, &stats); + RTE_LOG(INFO,USER1, "portid:%d, RX-packets: %-10"PRIu64" RX-errors: %-10"PRIu64 + " RX-bytes: %-10"PRIu64" RX-Imissed: %-10"PRIu64"\n", portid, stats.ipackets, stats.ierrors, + stats.ibytes,stats.imissed); + RTE_LOG(INFO,USER1, "portid:%d, RX-PPS: %-10"PRIu64" RX-Mbps: %.2lf\n", portid, pd->pps, pd->bps/1e6f ); +} + +static int pcap_dpdk_stats(pcap_t *p, struct pcap_stat *ps) +{ + struct pcap_dpdk *pd = p->priv; + calculate_timestamp(&(pd->ts_helper), &(pd->curr_ts)); + rte_eth_stats_get(pd->portid,&(pd->curr_stats)); + if (ps){ + ps->ps_recv = pd->curr_stats.ipackets; + ps->ps_drop = pd->curr_stats.ierrors; + ps->ps_drop += pd->bpf_drop; + ps->ps_ifdrop = pd->curr_stats.imissed; + } + uint64_t delta_pkt = pd->curr_stats.ipackets - pd->prev_stats.ipackets; + struct timeval delta_tm; + timersub(&(pd->curr_ts),&(pd->prev_ts), &delta_tm); + uint64_t delta_usec = delta_tm.tv_sec*1e6+delta_tm.tv_usec; + uint64_t delta_bit = (pd->curr_stats.ibytes-pd->prev_stats.ibytes)*8; + RTE_LOG(DEBUG, USER1, "delta_usec: %-10"PRIu64" delta_pkt: %-10"PRIu64" delta_bit: %-10"PRIu64"\n", delta_usec, delta_pkt, delta_bit); + pd->pps = (uint64_t)(delta_pkt*1e6f/delta_usec); + pd->bps = (uint64_t)(delta_bit*1e6f/delta_usec); + nic_stats_display(pd); + pd->prev_stats = pd->curr_stats; + pd->prev_ts = pd->curr_ts; + return 0; +} + +static int pcap_dpdk_setnonblock(pcap_t *p, int nonblock){ + struct pcap_dpdk *pd = (struct pcap_dpdk*)(p->priv); + pd->nonblock = nonblock; + return 0; +} + +static int pcap_dpdk_getnonblock(pcap_t *p){ + struct pcap_dpdk *pd = (struct pcap_dpdk*)(p->priv); + return pd->nonblock; +} +static int check_link_status(uint16_t portid, struct rte_eth_link *plink) +{ + // wait up to 9 seconds to get link status + rte_eth_link_get(portid, plink); + return plink->link_status == ETH_LINK_UP; +} +static void eth_addr_str(ETHER_ADDR_TYPE *addrp, char* mac_str, int len) +{ + int offset=0; + if (addrp == NULL){ + snprintf(mac_str, len-1, DPDK_DEF_MAC_ADDR); + return; + } + for (int i=0; i<6; i++) + { + if (offset >= len) + { // buffer overflow + return; + } + if (i==0) + { + snprintf(mac_str+offset, len-1-offset, "%02X",addrp->addr_bytes[i]); + offset+=2; // FF + }else{ + snprintf(mac_str+offset, len-1-offset, ":%02X", addrp->addr_bytes[i]); + offset+=3; // :FF + } + } + return; +} +// return portid by device name, otherwise return -1 +static uint16_t portid_by_device(char * device) +{ + uint16_t ret = DPDK_PORTID_MAX; + int len = strlen(device); + int prefix_len = strlen(DPDK_PREFIX); + unsigned long ret_ul = 0L; + char *pEnd; + if (len<=prefix_len || strncmp(device, DPDK_PREFIX, prefix_len)) // check prefix dpdk: + { + return ret; + } + //check all chars are digital + for (int i=prefix_len; device[i]; i++){ + if (device[i]<'0' || device[i]>'9'){ + return ret; + } + } + ret_ul = strtoul(&(device[prefix_len]), &pEnd, 10); + if (pEnd == &(device[prefix_len]) || *pEnd != '\0'){ + return ret; + } + // too large for portid + if (ret_ul >= DPDK_PORTID_MAX){ + return ret; + } + ret = (uint16_t)ret_ul; + return ret; +} + +static int parse_dpdk_cfg(char* dpdk_cfg,char** dargv) +{ + int cnt=0; + memset(dargv,0,sizeof(dargv[0])*DPDK_ARGC_MAX); + //current process name + int skip_space = 1; + int i=0; + RTE_LOG(INFO, USER1,"dpdk cfg: %s\n",dpdk_cfg); + // find first non space char + // The last opt is NULL + for (i=0;dpdk_cfg[i] && cntpriv; + pd->orig = p; + int ret = PCAP_ERROR; + uint16_t nb_ports=0; + uint16_t portid= DPDK_PORTID_MAX; + unsigned nb_mbufs = DPDK_NB_MBUFS; + struct rte_eth_rxconf rxq_conf; + struct rte_eth_txconf txq_conf; + struct rte_eth_conf local_port_conf = port_conf; + struct rte_eth_dev_info dev_info; + int is_port_up = 0; + struct rte_eth_link link; + do{ + //init EAL; fail if we have insufficient permission + char dpdk_pre_init_errbuf[PCAP_ERRBUF_SIZE]; + ret = dpdk_pre_init(dpdk_pre_init_errbuf, 0); + if (ret < 0) + { + // This returns a negative value on an error. + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "Can't open device %s: %s", + p->opt.device, dpdk_pre_init_errbuf); + // ret is set to the correct error + break; + } + if (ret == 0) + { + // This means DPDK isn't available on this machine. + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "Can't open device %s: DPDK is not available on this machine", + p->opt.device); + return PCAP_ERROR_NO_SUCH_DEVICE; + } + + ret = dpdk_init_timer(pd); + if (ret<0) + { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "dpdk error: Init timer is zero with device %s", + p->opt.device); + ret = PCAP_ERROR; + break; + } + + nb_ports = rte_eth_dev_count_avail(); + if (nb_ports == 0) + { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "dpdk error: No Ethernet ports"); + ret = PCAP_ERROR; + break; + } + + portid = portid_by_device(p->opt.device); + if (portid == DPDK_PORTID_MAX){ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "dpdk error: portid is invalid. device %s", + p->opt.device); + ret = PCAP_ERROR_NO_SUCH_DEVICE; + break; + } + + pd->portid = portid; + + if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) + { + p->snapshot = MAXIMUM_SNAPLEN; + } + // create the mbuf pool + pd->pktmbuf_pool = rte_pktmbuf_pool_create(MBUF_POOL_NAME, nb_mbufs, + MEMPOOL_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, + rte_socket_id()); + if (pd->pktmbuf_pool == NULL) + { + dpdk_fmt_errmsg_for_rte_errno(p->errbuf, + PCAP_ERRBUF_SIZE, rte_errno, + "dpdk error: Cannot init mbuf pool"); + ret = PCAP_ERROR; + break; + } + // config dev + rte_eth_dev_info_get(portid, &dev_info); + if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE) + { + local_port_conf.txmode.offloads |=DEV_TX_OFFLOAD_MBUF_FAST_FREE; + } + // only support 1 queue + ret = rte_eth_dev_configure(portid, 1, 1, &local_port_conf); + if (ret < 0) + { + dpdk_fmt_errmsg_for_rte_errno(p->errbuf, + PCAP_ERRBUF_SIZE, -ret, + "dpdk error: Cannot configure device: port=%u", + portid); + ret = PCAP_ERROR; + break; + } + // adjust rx tx + ret = rte_eth_dev_adjust_nb_rx_tx_desc(portid, &nb_rxd, &nb_txd); + if (ret < 0) + { + dpdk_fmt_errmsg_for_rte_errno(p->errbuf, + PCAP_ERRBUF_SIZE, -ret, + "dpdk error: Cannot adjust number of descriptors: port=%u", + portid); + ret = PCAP_ERROR; + break; + } + // get MAC addr + rte_eth_macaddr_get(portid, &(pd->eth_addr)); + eth_addr_str(&(pd->eth_addr), pd->mac_addr, DPDK_MAC_ADDR_SIZE-1); + + // init one RX queue + rxq_conf = dev_info.default_rxconf; + rxq_conf.offloads = local_port_conf.rxmode.offloads; + ret = rte_eth_rx_queue_setup(portid, 0, nb_rxd, + rte_eth_dev_socket_id(portid), + &rxq_conf, + pd->pktmbuf_pool); + if (ret < 0) + { + dpdk_fmt_errmsg_for_rte_errno(p->errbuf, + PCAP_ERRBUF_SIZE, -ret, + "dpdk error: rte_eth_rx_queue_setup:port=%u", + portid); + ret = PCAP_ERROR; + break; + } + + // init one TX queue + txq_conf = dev_info.default_txconf; + txq_conf.offloads = local_port_conf.txmode.offloads; + ret = rte_eth_tx_queue_setup(portid, 0, nb_txd, + rte_eth_dev_socket_id(portid), + &txq_conf); + if (ret < 0) + { + dpdk_fmt_errmsg_for_rte_errno(p->errbuf, + PCAP_ERRBUF_SIZE, -ret, + "dpdk error: rte_eth_tx_queue_setup:port=%u", + portid); + ret = PCAP_ERROR; + break; + } + // Initialize TX buffers + tx_buffer = rte_zmalloc_socket(DPDK_TX_BUF_NAME, + RTE_ETH_TX_BUFFER_SIZE(MAX_PKT_BURST), 0, + rte_eth_dev_socket_id(portid)); + if (tx_buffer == NULL) + { + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "dpdk error: Cannot allocate buffer for tx on port %u", portid); + ret = PCAP_ERROR; + break; + } + rte_eth_tx_buffer_init(tx_buffer, MAX_PKT_BURST); + // Start device + ret = rte_eth_dev_start(portid); + if (ret < 0) + { + dpdk_fmt_errmsg_for_rte_errno(p->errbuf, + PCAP_ERRBUF_SIZE, -ret, + "dpdk error: rte_eth_dev_start:port=%u", + portid); + ret = PCAP_ERROR; + break; + } + // set promiscuous mode + if (p->opt.promisc){ + pd->must_clear_promisc=1; + rte_eth_promiscuous_enable(portid); + } + // check link status + is_port_up = check_link_status(portid, &link); + if (!is_port_up){ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "dpdk error: link is down, port=%u",portid); + ret = PCAP_ERROR_IFACE_NOT_UP; + break; + } + // reset statistics + rte_eth_stats_reset(pd->portid); + calculate_timestamp(&(pd->ts_helper), &(pd->prev_ts)); + rte_eth_stats_get(pd->portid,&(pd->prev_stats)); + // format pcap_t + pd->portid = portid; + p->fd = pd->portid; + if (p->snapshot <=0 || p->snapshot> MAXIMUM_SNAPLEN) + { + p->snapshot = MAXIMUM_SNAPLEN; + } + p->linktype = DLT_EN10MB; // Ethernet, the 10MB is historical. + p->selectable_fd = p->fd; + p->read_op = pcap_dpdk_dispatch; + p->inject_op = pcap_dpdk_inject; + // using pcap_filter currently, though DPDK provides their own BPF function. Because DPDK BPF needs load a ELF file as a filter. + p->setfilter_op = install_bpf_program; + p->setdirection_op = NULL; + p->set_datalink_op = NULL; + p->getnonblock_op = pcap_dpdk_getnonblock; + p->setnonblock_op = pcap_dpdk_setnonblock; + p->stats_op = pcap_dpdk_stats; + p->cleanup_op = pcap_dpdk_close; + p->breakloop_op = pcap_breakloop_common; + // set default timeout + pd->required_select_timeout.tv_sec = 0; + pd->required_select_timeout.tv_usec = DPDK_DEF_MIN_SLEEP_MS*1000; + p->required_select_timeout = &pd->required_select_timeout; + ret = 0; // OK + }while(0); + + if (ret <= PCAP_ERROR) // all kinds of error code + { + pcap_cleanup_live_common(p); + }else{ + rte_eth_dev_get_name_by_port(portid,pd->pci_addr); + RTE_LOG(INFO, USER1,"Port %d device: %s, MAC:%s, PCI:%s\n", portid, p->opt.device, pd->mac_addr, pd->pci_addr); + RTE_LOG(INFO, USER1,"Port %d Link Up. Speed %u Mbps - %s\n", + portid, link.link_speed, + (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? + ("full-duplex") : ("half-duplex\n")); + } + return ret; +} + +// device name for dpdk should be in the form as dpdk:number, such as dpdk:0 +pcap_t * pcap_dpdk_create(const char *device, char *ebuf, int *is_ours) +{ + pcap_t *p=NULL; + *is_ours = 0; + + *is_ours = !strncmp(device, "dpdk:", 5); + if (! *is_ours) + return NULL; + //memset will happen + p = PCAP_CREATE_COMMON(ebuf, struct pcap_dpdk); + + if (p == NULL) + return NULL; + p->activate_op = pcap_dpdk_activate; + return p; +} + +int pcap_dpdk_findalldevs(pcap_if_list_t *devlistp, char *ebuf) +{ + int ret=0; + unsigned int nb_ports = 0; + char dpdk_name[DPDK_DEV_NAME_MAX]; + char dpdk_desc[DPDK_DEV_DESC_MAX]; + ETHER_ADDR_TYPE eth_addr; + char mac_addr[DPDK_MAC_ADDR_SIZE]; + char pci_addr[DPDK_PCI_ADDR_SIZE]; + do{ + // init EAL; return "DPDK not available" if we + // have insufficient permission + char dpdk_pre_init_errbuf[PCAP_ERRBUF_SIZE]; + ret = dpdk_pre_init(dpdk_pre_init_errbuf, 1); + if (ret < 0) + { + // This returns a negative value on an error. + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "Can't look for DPDK devices: %s", + dpdk_pre_init_errbuf); + ret = PCAP_ERROR; + break; + } + if (ret == 0) + { + // This means DPDK isn't available on this machine. + // That just means "don't return any devices". + break; + } + nb_ports = rte_eth_dev_count_avail(); + if (nb_ports == 0) + { + // That just means "don't return any devices". + ret = 0; + break; + } + for (unsigned int i=0; i= \fIlength\fP. +\fBlen >= \fIlength\fP .fi .in -.5i .IP "\fBip proto \fIprotocol\fR" True if the packet is an IPv4 packet (see -.IR ip (4P)) +.BR ip (4P)) of protocol type \fIprotocol\fP. -\fIProtocol\fP can be a number or one of the names -\fBicmp\fP, \fBicmp6\fP, \fBigmp\fP, \fBigrp\fP, \fBpim\fP, \fBah\fP, -\fBesp\fP, \fBvrrp\fP, \fBudp\fP, or \fBtcp\fP. -Note that the identifiers \fBtcp\fP, \fBudp\fP, and \fBicmp\fP are also -keywords and must be escaped via backslash (\\). +\fIProtocol\fP can be a number or one of the names recognized by +.BR getprotobyname (3) +(as in e.g. `\fBgetent\fR(1) protocols'), typically from an entry in +.IR \%/etc/protocols , +for example: +.BR ah , +.BR esp , +.B eigrp +(only in Linux, FreeBSD, NetBSD, DragonFly BSD, and macOS), +.BR icmp , +.BR igmp , +.B igrp +(only in OpenBSD), +.BR pim , +.BR sctp , +.BR tcp , +.B udp +or +.BR vrrp . +Note that most of these example identifiers +are also keywords and must be escaped via backslash (\\). Note that this primitive does not chase the protocol header chain. +.IP "\fBicmp\fR" +Abbreviation for: +.in +.5i +.nf +\fBip proto\fR 1 +.fi +.in -.5i .IP "\fBip6 proto \fIprotocol\fR" True if the packet is an IPv6 packet of protocol type \fIprotocol\fP. +(See `\fBip proto\fP' above for the meaning of \fIprotocol\fR.) +Note that the IPv6 variant of ICMP uses a different protocol number, named +.B \%ipv6-icmp +in AIX, FreeBSD, illumos, Linux, macOS, NetBSD, OpenBSD, Solaris and Windows. Note that this primitive does not chase the protocol header chain. +.IP "\fBicmp6\fR" +Abbreviation for: +.in +.5i +.nf +\fBip6 proto\fR 58 +.fi +.in -.5i .IP "\fBproto \fIprotocol\fR" True if the packet is an IPv4 or IPv6 packet of protocol type -\fIprotocol\fP. Note that this primitive does not chase the protocol +\fIprotocol\fP. (See `\fBip proto\fP' above for the meaning of +\fIprotocol\fP.) Note that this primitive does not chase the protocol header chain. -.IP "\fBtcp\fR, \fBudp\fR, \fBicmp\fR" +.IP "\fBah\fR, \fBesp\fR, \fBpim\fR, \fBsctp\fR, \fBtcp\fR, \fBudp\fR" Abbreviations for: .in +.5i .nf -\fBproto \fIp\fR\fB +\fBproto \\\fIprotocol\fR .fi .in -.5i -where \fIp\fR is one of the above protocols. +where \fIprotocol\fR is one of the above protocols. .IP "\fBip6 protochain \fIprotocol\fR" True if the packet is IPv6 packet, and contains protocol header with type \fIprotocol\fR in its protocol header chain. +(See `\fBip proto\fP' above for the meaning of \fIprotocol\fP.) For example, .in +.5i .nf -\fBip6 protochain 6\fR +\fBip6 protochain\fR 6 .fi .in -.5i matches any IPv6 packet with TCP protocol header in the protocol header chain. @@ -330,13 +367,15 @@ filter engines in the kernel, so this can be somewhat slow, and may cause more packets to be dropped. .IP "\fBip protochain \fIprotocol\fR" Equivalent to \fBip6 protochain \fIprotocol\fR, but this is for IPv4. +(See `\fBip proto\fP' above for the meaning of \fIprotocol\fP.) .IP "\fBprotochain \fIprotocol\fR" True if the packet is an IPv4 or IPv6 packet of protocol type -\fIprotocol\fP. Note that this primitive chases the protocol +\fIprotocol\fP. (See `\fBip proto\fP' above for the meaning of +\fIprotocol\fP.) Note that this primitive chases the protocol header chain. .IP "\fBether broadcast\fR" True if the packet is an Ethernet broadcast packet. -The \fIether\fP +The \fBether\fP keyword is optional. .IP "\fBip broadcast\fR" True if the packet is an IPv4 broadcast packet. @@ -353,7 +392,7 @@ check will not work correctly. True if the packet is an Ethernet multicast packet. The \fBether\fP keyword is optional. -This is shorthand for `\fBether[0] & 1 != 0\fP'. +This is shorthand for `\fBether[\fP0\fB] & \fP1\fB != \fP0'. .IP "\fBip multicast\fR" True if the packet is an IPv4 multicast packet. .IP "\fBip6 multicast\fR" @@ -361,15 +400,15 @@ True if the packet is an IPv6 multicast packet. .IP "\fBether proto \fIprotocol\fR" True if the packet is of ether type \fIprotocol\fR. \fIProtocol\fP can be a number or one of the names -\fBip\fP, \fBip6\fP, \fBarp\fP, \fBrarp\fP, \fBatalk\fP, \fBaarp\fP, -\fBdecnet\fP, \fBsca\fP, \fBlat\fP, \fBmopdl\fP, \fBmoprc\fP, -\fBiso\fP, \fBstp\fP, \fBipx\fP, or \fBnetbeui\fP. -Note these identifiers are also keywords +\fBaarp\fP, \fBarp\fP, \fBatalk\fP, \fBdecnet\fP, \fBip\fP, \fBip6\fP, +\fBipx\fP, \fBiso\fP, \fBlat\fP, \fBloopback\fP, \fBmopdl\fP, \fBmoprc\fP, \fBnetbeui\fP, +\fBrarp\fP, \fBsca\fP or \fBstp\fP. +Note these identifiers (except \fBloopback\fP) are also keywords and must be escaped via backslash (\\). .IP -[In the case of FDDI (e.g., `\fBfddi proto arp\fR'), Token Ring -(e.g., `\fBtr proto arp\fR'), and IEEE 802.11 wireless LANS (e.g., -`\fBwlan proto arp\fR'), for most of those protocols, the +[In the case of FDDI (e.g., `\fBfddi proto \\arp\fR'), Token Ring +(e.g., `\fBtr proto \\arp\fR'), and IEEE 802.11 wireless LANs (e.g., +`\fBwlan proto \\arp\fR'), for most of those protocols, the protocol identification comes from the 802.2 Logical Link Control (LLC) header, which is usually layered on top of the FDDI, Token Ring, or 802.11 header. @@ -419,34 +458,34 @@ IPX, and the IPX etype in a SNAP frame. Abbreviations for: .in +.5i .nf -\fBether proto \fIp\fR +\fBether proto \\\fIprotocol\fR .fi .in -.5i -where \fIp\fR is one of the above protocols. +where \fIprotocol\fR is one of the above protocols. .IP "\fBlat\fR, \fBmoprc\fR, \fBmopdl\fR" Abbreviations for: .in +.5i .nf -\fBether proto \fIp\fR +\fBether proto \\\fIprotocol\fR .fi .in -.5i -where \fIp\fR is one of the above protocols. +where \fIprotocol\fR is one of the above protocols. Note that not all applications using .BR pcap (3PCAP) currently know how to parse these protocols. -.IP "\fBdecnet src \fIhost\fR" -True if the DECNET source address is -.IR host , -which may be an address of the form ``10.123'', or a DECNET host +.IP "\fBdecnet src \fIdecnetaddr\fR" +True if the DECnet source address is +.IR decnetaddr , +which may be an address of the form ``10.123'', or a DECnet host name. -[DECNET host name support is only available on ULTRIX systems -that are configured to run DECNET.] -.IP "\fBdecnet dst \fIhost\fR" -True if the DECNET destination address is -.IR host . -.IP "\fBdecnet host \fIhost\fR" -True if either the DECNET source or destination address is -.IR host . +[DECnet host name support is only available on ULTRIX systems +that are configured to run DECnet.] +.IP "\fBdecnet dst \fIdecnetaddr\fR" +True if the DECnet destination address is +.IR decnetaddr . +.IP "\fBdecnet host \fIdecnetaddr\fR" +True if either the DECnet source or destination address is +.IR decnetaddr . .IP \fBllc\fP True if the packet has an 802.2 LLC header. This includes: .IP @@ -460,7 +499,7 @@ Token Ring packets (no check is done for LLC frames); FDDI packets (no check is done for LLC frames); .IP LLC-encapsulated ATM packets, for SunATM on Solaris. -.IP "\fBllc\fP \Fitype\fR" +.IP "\fBllc\fP \fItype\fR" True if the packet has an 802.2 LLC header and has the specified .IR type . .I type @@ -535,11 +574,11 @@ modifier. .IP "\fBreason \fIcode\fR" True if the packet was logged with the specified PF reason code. The known codes are: -.BR match , -.BR bad-offset , -.BR fragment , -.BR short , -.BR normalize , +.BR \%match , +.BR \%bad-offset , +.BR \%fragment , +.BR \%short , +.BR \%normalize , and .B memory (applies only to packets logged by OpenBSD's or FreeBSD's @@ -639,27 +678,28 @@ then valid \fIwlan_subtype\fRs are: .IP If the specified \fIwlan_type\fR is \fBdata\fP, then valid \fIwlan_subtype\fRs are: -\fBdata\fP, -\fBdata-cf-ack\fP, -\fBdata-cf-poll\fP, -\fBdata-cf-ack-poll\fP, -\fBnull\fP, -\fBcf-ack\fP, -\fBcf-poll\fP, -\fBcf-ack-poll\fP, -\fBqos-data\fP, -\fBqos-data-cf-ack\fP, -\fBqos-data-cf-poll\fP, -\fBqos-data-cf-ack-poll\fP, -\fBqos\fP, -\fBqos-cf-poll\fP and -\fBqos-cf-ack-poll\fP. +.BR \%data , +.BR \%data-cf-ack , +.BR \%data-cf-poll , +.BR \%data-cf-ack-poll , +.BR \%null , +.BR \%cf-ack , +.BR \%cf-poll , +.BR \%cf-ack-poll , +.BR \%qos-data , +.BR \%qos-data-cf-ack , +.BR \%qos-data-cf-poll , +.BR \%qos-data-cf-ack-poll , +.BR \%qos , +.B \%qos-cf-poll +and +.BR \%qos-cf-ack-poll . .IP "\fBsubtype \fIwlan_subtype\fR" True if the IEEE 802.11 frame subtype matches the specified \fIwlan_subtype\fR and frame has the type to which the specified \fIwlan_subtype\fR belongs. -.IP "\fBdir \fIdir\fR" +.IP "\fBdir \fIdirection\fR" True if the IEEE 802.11 frame direction matches the specified -.IR dir . +.IR direction . Valid directions are: .BR nods , .BR tods , @@ -668,51 +708,51 @@ Valid directions are: or a numeric value. .IP "\fBvlan \fI[vlan_id]\fR" True if the packet is an IEEE 802.1Q VLAN packet. -If \fI[vlan_id]\fR is specified, only true if the packet has the specified +If the optional \fIvlan_id\fR is specified, only true if the packet has the specified \fIvlan_id\fR. -Note that the first \fBvlan\fR keyword encountered in \fIexpression\fR -changes the decoding offsets for the remainder of \fIexpression\fR on -the assumption that the packet is a VLAN packet. The \fBvlan -\fI[vlan_id]\fR expression may be used more than once, to filter on VLAN -hierarchies. Each use of that expression increments the filter offsets +Note that the first \fBvlan\fR keyword encountered in an expression +changes the decoding offsets for the remainder of the expression on +the assumption that the packet is a VLAN packet. The `\fBvlan +\fI[vlan_id]\fR` keyword may be used more than once, to filter on VLAN +hierarchies. Each use of that keyword increments the filter offsets by 4. .IP For example: .in +.5i .nf -\fBvlan 100 && vlan 200\fR +\fBvlan\fP 100 \fB&& vlan\fR 200 .fi .in -.5i filters on VLAN 200 encapsulated within VLAN 100, and .in +.5i .nf -\fBvlan && vlan 300 && ip\fR +\fBvlan && vlan \fP300 \fB&& ip\fR .fi .in -.5i -filters IPv4 protocols encapsulated in VLAN 300 encapsulated within any +filters IPv4 protocol encapsulated in VLAN 300 encapsulated within any higher order VLAN. .IP "\fBmpls \fI[label_num]\fR" True if the packet is an MPLS packet. -If \fI[label_num]\fR is specified, only true is the packet has the specified +If the optional \fIlabel_num\fR is specified, only true if the packet has the specified \fIlabel_num\fR. -Note that the first \fBmpls\fR keyword encountered in \fIexpression\fR -changes the decoding offsets for the remainder of \fIexpression\fR on +Note that the first \fBmpls\fR keyword encountered in an expression +changes the decoding offsets for the remainder of the expression on the assumption that the packet is a MPLS-encapsulated IP packet. The -\fBmpls \fI[label_num]\fR expression may be used more than once, to -filter on MPLS hierarchies. Each use of that expression increments the +`\fBmpls \fI[label_num]\fR` keyword may be used more than once, to +filter on MPLS hierarchies. Each use of that keyword increments the filter offsets by 4. .IP For example: .in +.5i .nf -\fBmpls 100000 && mpls 1024\fR +\fBmpls\fP 100000 \fB&& mpls\fR 1024 .fi .in -.5i filters packets with an outer label of 100000 and an inner label of 1024, and .in +.5i .nf -\fBmpls && mpls 1024 && host 192.9.200.1\fR +\fBmpls && mpls\fP 1024 \fB&& host\fR 192.9.200.1 .fi .in -.5i filters packets to or from 192.9.200.1 with an inner label of 1024 and @@ -723,34 +763,34 @@ type 0x8863). .IP "\fBpppoes \fI[session_id]\fR" True if the packet is a PPP-over-Ethernet Session packet (Ethernet type 0x8864). -If \fI[session_id]\fR is specified, only true if the packet has the specified +If the optional \fIsession_id\fR is specified, only true if the packet has the specified \fIsession_id\fR. -Note that the first \fBpppoes\fR keyword encountered in \fIexpression\fR -changes the decoding offsets for the remainder of \fIexpression\fR on +Note that the first \fBpppoes\fR keyword encountered in an expression +changes the decoding offsets for the remainder of the expression on the assumption that the packet is a PPPoE session packet. .IP For example: .in +.5i .nf -\fBpppoes 0x27 && ip\fR +\fBpppoes\fP 0x27 \fB&& ip\fR .fi .in -.5i -filters IPv4 protocols encapsulated in PPPoE session id 0x27. +filters IPv4 protocol encapsulated in PPPoE session id 0x27. .IP "\fBgeneve \fI[vni]\fR" -True if the packet is a Geneve packet (UDP port 6081). If \fI[vni]\fR +True if the packet is a Geneve packet (UDP port 6081). If the optional \fIvni\fR is specified, only true if the packet has the specified \fIvni\fR. Note that when the \fBgeneve\fR keyword is encountered in -\fIexpression\fR, it changes the decoding offsets for the remainder of -\fIexpression\fR on the assumption that the packet is a Geneve packet. +an expression, it changes the decoding offsets for the remainder of +the expression on the assumption that the packet is a Geneve packet. .IP For example: .in +.5i .nf -\fBgeneve 0xb && ip\fR +\fBgeneve\fP 0xb \fB&& ip\fR .fi .in -.5i -filters IPv4 protocols encapsulated in Geneve with VNI 0xb. This will -match both IP directly encapsulated in Geneve as well as IP contained +filters IPv4 protocol encapsulated in Geneve with VNI 0xb. This will +match both IPv4 directly encapsulated in Geneve as well as IPv4 contained inside an Ethernet frame. .IP "\fBiso proto \fIprotocol\fR" True if the packet is an OSI packet of protocol type \fIprotocol\fP. @@ -760,10 +800,10 @@ True if the packet is an OSI packet of protocol type \fIprotocol\fP. Abbreviations for: .in +.5i .nf -\fBiso proto \fIp\fR +\fBiso proto \\\fIprotocol\fR .fi .in -.5i -where \fIp\fR is one of the above protocols. +where \fIprotocol\fR is one of the above protocols. .IP "\fBl1\fR, \fBl2\fR, \fBiih\fR, \fBlsp\fR, \fBsnp\fR, \fBcsnp\fR, \fBpsnp\fR" Abbreviations for IS-IS PDU types. .IP "\fBvpi\fP \fIn\fR" @@ -777,8 +817,8 @@ virtual channel identifier of .IP \fBlane\fP True if the packet is an ATM packet, for SunATM on Solaris, and is an ATM LANE packet. -Note that the first \fBlane\fR keyword encountered in \fIexpression\fR -changes the tests done in the remainder of \fIexpression\fR +Note that the first \fBlane\fR keyword encountered in an expression +changes the tests done in the remainder of the expression on the assumption that the packet is either a LANE emulated Ethernet packet or a LANE LE Control packet. If \fBlane\fR isn't specified, the tests are done under the assumption that the packet is an @@ -815,82 +855,175 @@ Connect Ack, Release, or Release Done message. True if the packet is an ATM packet, for SunATM on Solaris, and is on a meta signaling circuit and is a Q.2931 Setup, Call Proceeding, Connect, Release, or Release Done message. -.IP "\fIexpr relop expr\fR" -True if the relation holds, where \fIrelop\fR is one of >, <, >=, <=, =, -!=, and \fIexpr\fR is an arithmetic expression composed of integer -constants (expressed in standard C syntax), the normal binary operators -[+, -, *, /, %, &, |, ^, <<, >>], a length operator, and special packet data +.IP "\fIexpr1 relop expr2\fR" +True if the relation holds. \fIRelop\fR is one of +.RB { > , +.BR < , +.BR >= , +.BR <= , +.BR = , +.BR == , +.BR != } +(where +.B = +means the same as +.BR == ). +Each of \fIexpr1\fR and \fIexpr2\fR is an arithmetic expression composed of +integer constants (expressed in standard C syntax), the normal binary operators +.RB { + , +.BR - , +.BR * , +.BR / , +.BR % , +.BR & , +.BR | , +.BR ^ , +.BR << , +.BR >> }, +a length operator, and special packet data accessors. Note that all comparisons are unsigned, so that, for example, 0x80000000 and 0xffffffff are > 0. .IP -The % and ^ operators are currently only supported for filtering in the -kernel on Linux with 3.7 and later kernels; on all other systems, if +The +.B % +and +.B ^ +operators are currently only supported for filtering in the kernel on +particular operating systems (for example: FreeBSD, Linux with 3.7 and later +kernels, NetBSD); on all other systems (for example: AIX, illumos, Solaris, +OpenBSD), if those operators are used, filtering will be done in user mode, which will increase the overhead of capturing packets and may cause more packets to be dropped. .IP +The length operator, indicated by the keyword \fBlen\fP, gives the +length of the packet. +.IP To access data inside the packet, use the following syntax: .in +.5i .nf \fIproto\fB [ \fIexpr\fB : \fIsize\fB ]\fR .fi .in -.5i -\fIProto\fR is one of \fBether, fddi, tr, wlan, ppp, slip, link, -ip, arp, rarp, tcp, udp, icmp, ip6\fR or \fBradio\fR, and +.I Proto +is one of +.BR arp , +.BR atalk , +.BR carp , +.BR decnet , +.BR ether , +.BR fddi , +.BR icmp , +.BR icmp6 , +.BR igmp , +.BR igrp , +.BR ip , +.BR ip6 , +.BR lat , +.BR link , +.BR mopdl , +.BR moprc , +.BR pim , +.BR ppp , +.BR radio , +.BR rarp , +.BR sca , +.BR sctp , +.BR slip , +.BR tcp , +.BR tr , +.BR udp , +.B vrrp +or +.BR wlan , +and indicates the protocol layer for the index operation. -(\fBether, fddi, wlan, tr, ppp, slip\fR and \fBlink\fR all refer to the +.RB ( ether , +.BR fddi , +.BR link , +.BR ppp , +.BR slip , +.B tr +and +.BR wlan +all refer to the link layer. \fBradio\fR refers to the "radio header" added to some 802.11 captures.) -Note that \fItcp, udp\fR and other upper-layer protocol types only +Note that \fBtcp\fR, \fBudp\fR and other upper-layer protocol types only apply to IPv4, not IPv6 (this will be fixed in the future). The byte offset, relative to the indicated protocol layer, is given by \fIexpr\fR. \fISize\fR is optional and indicates the number of bytes in the field of interest; it can be either one, two, or four, and defaults to one. -The length operator, indicated by the keyword \fBlen\fP, gives the -length of the packet. -For example, `\fBether[0] & 1 != 0\fP' catches all multicast traffic. -The expression `\fBip[0] & 0xf != 5\fP' +For example, `\fBether[\fP0\fB] &\fP 1 \fB!=\fP 0' catches all multicast traffic. +The expression `\fBip[\fP0\fB] &\fP 0xf \fB!=\fP 5' catches all IPv4 packets with options. The expression -`\fBip[6:2] & 0x1fff = 0\fP' +`\fBip[\fP6:2\fB] &\fP 0x1fff \fB=\fP 0' catches only unfragmented IPv4 datagrams and frag zero of fragmented IPv4 datagrams. This check is implicitly applied to the \fBtcp\fP and \fBudp\fP index operations. -For instance, \fBtcp[0]\fP always means the first +For instance, \fBtcp[\fP0\fB]\fP always means the first byte of the TCP \fIheader\fP, and never means the first byte of an intervening fragment. - +.IP 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), \fBicmp6type (ICMP v6 type field) -\fBicmpcode\fP (ICMP code field), \fBicmp6code\fP (ICMP v6 code field), and +available: \fBicmptype\fP (ICMP type field), \fBicmp6type\fP (ICMPv6 type field), +\fBicmpcode\fP (ICMP code field), \fBicmp6code\fP (ICMPv6 code field) and \fBtcpflags\fP (TCP flags field). - -The following ICMP type field values are available: \fBicmp-echoreply\fP, -\fBicmp-unreach\fP, \fBicmp-sourcequench\fP, \fBicmp-redirect\fP, -\fBicmp-echo\fP, \fBicmp-routeradvert\fP, \fBicmp-routersolicit\fP, -\fBicmp-timxceed\fP, \fBicmp-paramprob\fP, \fBicmp-tstamp\fP, -\fBicmp-tstampreply\fP, \fBicmp-ireq\fP, \fBicmp-ireqreply\fP, -\fBicmp-maskreq\fP, \fBicmp-maskreply\fP. - -The following 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. - +.IP +The following ICMP type field values are available: +.BR \%icmp-echoreply , +.BR \%icmp-unreach , +.BR \%icmp-sourcequench , +.BR \%icmp-redirect , +.BR \%icmp-echo , +.BR \%icmp-routeradvert , +.BR \%icmp-routersolicit , +.BR \%icmp-timxceed , +.BR \%icmp-paramprob , +.BR \%icmp-tstamp , +.BR \%icmp-tstampreply , +.BR \%icmp-ireq , +.BR \%icmp-ireqreply , +.BR \%icmp-maskreq , +.BR \%icmp-maskreply . +.IP +The following ICMPv6 type field values are available: +.BR \%icmp6-destinationunreach , +.BR \%icmp6-packettoobig , +.BR \%icmp6-timeexceeded , +.BR \%icmp6-parameterproblem , +.BR \%icmp6-echo , +.BR \%icmp6-echoreply , +.BR \%icmp6-multicastlistenerquery , +.BR \%icmp6-multicastlistenerreportv1 , +.BR \%icmp6-multicastlistenerdone , +.BR \%icmp6-routersolicit , +.BR \%icmp6-routeradvert , +.BR \%icmp6-neighborsolicit , +.BR \%icmp6-neighboradvert , +.BR \%icmp6-redirect , +.BR \%icmp6-routerrenum , +.BR \%icmp6-nodeinformationquery , +.BR \%icmp6-nodeinformationresponse , +.BR \%icmp6-ineighbordiscoverysolicit , +.BR \%icmp6-ineighbordiscoveryadvert , +.BR \%icmp6-multicastlistenerreportv2 , +.BR \%icmp6-homeagentdiscoveryrequest , +.BR \%icmp6-homeagentdiscoveryreply , +.BR \%icmp6-mobileprefixsolicit , +.BR \%icmp6-mobileprefixadvert , +.BR \%icmp6-certpathsolicit , +.BR \%icmp6-certpathadvert , +.BR \%icmp6-multicastrouteradvert , +.BR \%icmp6-multicastroutersolicit , +.BR \%icmp6-multicastrouterterm . +.IP The following TCP flags field values are available: \fBtcp-fin\fP, \fBtcp-syn\fP, \fBtcp-rst\fP, \fBtcp-push\fP, \fBtcp-ack\fP, \fBtcp-urg\fP, \fBtcp-ece\fP, @@ -906,7 +1039,7 @@ Concatenation (`\fB&&\fP' or `\fBand\fP'). .IP Alternation (`\fB||\fP' or `\fBor\fP'). .LP -Negation has highest precedence. +Negation has the highest precedence. Alternation and concatenation have equal precedence and associate left to right. Note that explicit \fBand\fR tokens, not juxtaposition, @@ -917,67 +1050,64 @@ is assumed. For example, .in +.5i .nf -\fBnot host vs and ace\fR +\fBnot host\fP vs \fBand\fR ace .fi .in -.5i is short for .in +.5i .nf -\fBnot host vs and host ace\fR +\fBnot host\fP vs \fBand host\fR ace .fi .in -.5i which should not be confused with .in +.5i .nf -\fBnot ( host vs or ace )\fR +\fBnot (host \fPvs\fB or \fPace\fB)\fR .fi .in -.5i .SH EXAMPLES .LP -To select all packets arriving at or departing from \fIsundown\fP: +To select all packets arriving at or departing from `sundown': .RS .nf -\fBhost sundown\fP +\fBhost\fP sundown .fi .RE .LP -To select traffic between \fIhelios\fR and either \fIhot\fR or \fIace\fR: +To select traffic between `helios' and either `hot' or `ace': .RS .nf -\fBhost helios and \\( hot or ace \\)\fP +\fBhost\fP helios \fBand (\fPhot \fBor\fP ace\fB)\fP .fi .RE .LP -To select all IP packets between \fIace\fR and any host except \fIhelios\fR: +To select all IPv4 packets between `ace' and any host except `helios': .RS .nf -\fBip host ace and not helios\fP +\fBip host\fP ace \fBand not\fP helios .fi .RE .LP To select all traffic between local hosts and hosts at Berkeley: .RS .nf -.B -net ucb-ether +\fBnet\fP ucb-ether .fi .RE .LP -To select all ftp traffic through internet gateway \fIsnup\fP: +To select all FTP traffic through Internet gateway `snup': .RS .nf -.B -gateway snup and (port ftp or ftp-data) +\fBgateway\fP snup \fBand (port\fP ftp \fBor\fP ftp-data\fB)\fP .fi .RE .LP -To select traffic neither sourced from nor destined for local hosts +To select IPv4 traffic neither sourced from nor destined for local hosts (if you gateway to one other net, this stuff should never make it onto your local net). .RS .nf -.B -ip and not net \fIlocalnet\fP +\fBip and not net \fPlocalnet .fi .RE .LP @@ -985,8 +1115,17 @@ To select the start and end packets (the SYN and FIN packets) of each TCP conversation that involves a non-local host. .RS .nf +\fBtcp[tcpflags] & (tcp-syn|tcp-fin) !=\fP 0 \fBand not src and dst net\fP localnet +.fi +.RE +.LP +To select the TCP packets with flags RST and ACK both set. +(i.e. select only the RST and ACK flags in the flags field, and if the result +is "RST and ACK both set", match) +.RS +.nf .B -tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 and not src and dst net \fIlocalnet\fP +tcp[tcpflags] & (tcp-rst|tcp-ack) == (tcp-rst|tcp-ack) .fi .RE .LP @@ -995,26 +1134,23 @@ packets that contain data, not, for example, SYN and FIN packets and ACK-only packets. (IPv6 is left as an exercise for the reader.) .RS .nf -.B -tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0) +\fBtcp port\fP 80 \fBand (((ip[\fP2:2\fB] - ((ip[\fP0\fB]&\fP0xf\fB)<<\fP2\fB)) - ((tcp[\fP12\fB]&\fP0xf0\fB)>>\fP2\fB)) != \fP0\fB) .fi .RE .LP -To select IP packets longer than 576 bytes sent through gateway \fIsnup\fP: +To select IPv4 packets longer than 576 bytes sent through gateway `snup': .RS .nf -.B -gateway snup and ip[2:2] > 576 +\fBgateway\fP snup \fBand ip[\fP2:2\fB] >\fP 576 .fi .RE .LP -To select IP broadcast or multicast packets that were +To select IPv4 broadcast or multicast packets that were .I not sent via Ethernet broadcast or multicast: .RS .nf -.B -ether[0] & 1 = 0 and ip[16] >= 224 +\fBether[\fP0\fB] &\fP 1 \fB=\fP 0 \fBand ip[\fP16\fB] >=\fP 224 .fi .RE .LP @@ -1024,16 +1160,28 @@ ping packets): .nf .B icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply +.B +icmp6[icmp6type] != icmp6-echo and icmp6[icmp6type] != icmp6-echoreply .fi .RE -.SH "SEE ALSO" -pcap(3PCAP) +.SH BACKWARD COMPATIBILITY +The ICMPv6 type code names, as well as the +.B tcp-ece +and +.B tcp-cwr +TCP flag names became available in libpcap 1.9.0. +.PP +The +.B geneve +keyword became available in libpcap 1.8.0. +.SH SEE ALSO +.BR pcap (3PCAP) .SH BUGS -To report a security issue please send an e-mail to security@tcpdump.org. +To report a security issue please send an e-mail to \%security@tcpdump.org. .LP To report bugs and other problems, contribute patches, request a feature, provide generic feedback etc please see the file -.I CONTRIBUTING +.I CONTRIBUTING.md in the libpcap source tree root. .LP Filter expressions on fields other than those in Token Ring headers will @@ -1042,10 +1190,11 @@ not correctly handle source-routed Token Ring packets. Filter expressions on fields other than those in 802.11 headers will not correctly handle 802.11 data packets with both To DS and From DS set. .LP -.BR "ip6 proto" +`\fBip6 proto\fP' should chase header chain, but at this moment it does not. -.BR "ip6 protochain" -is supplied for this behavior. +`\fBip6 protochain\fP' +is supplied for this behavior. For example, to match IPv6 fragments: +`\fBip6 protochain\fP 44' .LP Arithmetic expression against transport layer headers, like \fBtcp[0]\fP, does not work against IPv6 packets. diff --git a/external/bsd/libpcap/dist/pcap-haiku.cpp b/external/bsd/libpcap/dist/pcap-haiku.cpp new file mode 100644 index 000000000000..8ae9119c2ccf --- /dev/null +++ b/external/bsd/libpcap/dist/pcap-haiku.cpp @@ -0,0 +1,305 @@ +/* + * Copyright 2006-2010, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Axel Dörfler, axeld@pinc-software.de + * James Woodcock + */ + + +#include "config.h" +#include "pcap-int.h" + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + + +/* + * Private data for capturing on Haiku sockets. + */ +struct pcap_haiku { + struct pcap_stat stat; + char *device; /* device name */ +}; + + +bool +prepare_request(struct ifreq& request, const char* name) +{ + if (strlen(name) >= IF_NAMESIZE) + return false; + + strcpy(request.ifr_name, name); + return true; +} + + +static int +pcap_read_haiku(pcap_t* handle, int maxPackets _U_, pcap_handler callback, + u_char* userdata) +{ + // Receive a single packet + + u_char* buffer = (u_char*)handle->buffer + handle->offset; + struct sockaddr_dl from; + ssize_t bytesReceived; + do { + if (handle->break_loop) { + // Clear the break loop flag, and return -2 to indicate our + // reasoning + handle->break_loop = 0; + return -2; + } + + socklen_t fromLength = sizeof(from); + bytesReceived = recvfrom(handle->fd, buffer, handle->bufsize, MSG_TRUNC, + (struct sockaddr*)&from, &fromLength); + } while (bytesReceived < 0 && errno == B_INTERRUPTED); + + if (bytesReceived < 0) { + if (errno == B_WOULD_BLOCK) { + // there is no packet for us + return 0; + } + + snprintf(handle->errbuf, sizeof(handle->errbuf), + "recvfrom: %s", strerror(errno)); + return -1; + } + + int32 captureLength = bytesReceived; + if (captureLength > handle->snapshot) + captureLength = handle->snapshot; + + // run the packet filter + if (handle->fcode.bf_insns) { + if (pcap_filter(handle->fcode.bf_insns, buffer, bytesReceived, + captureLength) == 0) { + // packet got rejected + return 0; + } + } + + // fill in pcap_header + pcap_pkthdr header; + header.caplen = captureLength; + header.len = bytesReceived; + header.ts.tv_usec = system_time() % 1000000; + header.ts.tv_sec = system_time() / 1000000; + // TODO: get timing from packet!!! + + /* Call the user supplied callback function */ + callback(userdata, &header, buffer); + return 1; +} + + +static int +pcap_inject_haiku(pcap_t *handle, const void *buffer, int size) +{ + // we don't support injecting packets yet + // TODO: use the AF_LINK protocol (we need another socket for this) to + // inject the packets + strlcpy(handle->errbuf, "Sending packets isn't supported yet", + PCAP_ERRBUF_SIZE); + return -1; +} + + +static int +pcap_stats_haiku(pcap_t *handle, struct pcap_stat *stats) +{ + struct pcap_haiku* handlep = (struct pcap_haiku*)handle->priv; + ifreq request; + int socket = ::socket(AF_INET, SOCK_DGRAM, 0); + if (socket < 0) { + return -1; + } + prepare_request(request, handlep->device); + if (ioctl(socket, SIOCGIFSTATS, &request, sizeof(struct ifreq)) < 0) { + snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "pcap_stats: %s", + strerror(errno)); + close(socket); + return -1; + } + + close(socket); + handlep->stat.ps_recv += request.ifr_stats.receive.packets; + handlep->stat.ps_drop += request.ifr_stats.receive.dropped; + *stats = handlep->stat; + return 0; +} + + +static int +pcap_activate_haiku(pcap_t *handle) +{ + struct pcap_haiku* handlep = (struct pcap_haiku*)handle->priv; + + const char* device = handle->opt.device; + + handle->read_op = pcap_read_haiku; + handle->setfilter_op = install_bpf_program; /* no kernel filtering */ + handle->inject_op = pcap_inject_haiku; + handle->stats_op = pcap_stats_haiku; + + // use default hooks where possible + handle->getnonblock_op = pcap_getnonblock_fd; + handle->setnonblock_op = pcap_setnonblock_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 (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN) + handle->snapshot = MAXIMUM_SNAPLEN; + + handlep->device = strdup(device); + if (handlep->device == NULL) { + pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, + errno, "strdup"); + return PCAP_ERROR; + } + + handle->bufsize = 65536; + // TODO: should be determined by interface MTU + + // allocate buffer for monitoring the device + handle->buffer = (u_char*)malloc(handle->bufsize); + if (handle->buffer == NULL) { + pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, + errno, "buffer malloc"); + return PCAP_ERROR; + } + + handle->offset = 0; + handle->linktype = DLT_EN10MB; + // TODO: check interface type! + + return 0; +} + + +// #pragma mark - pcap API + + +extern "C" pcap_t * +pcap_create_interface(const char *device, char *errorBuffer) +{ + // TODO: handle promiscuous mode! + + // we need a socket to talk to the networking stack + int socket = ::socket(AF_INET, SOCK_DGRAM, 0); + if (socket < 0) { + snprintf(errorBuffer, PCAP_ERRBUF_SIZE, + "The networking stack doesn't seem to be available.\n"); + return NULL; + } + + struct ifreq request; + if (!prepare_request(request, device)) { + snprintf(errorBuffer, PCAP_ERRBUF_SIZE, + "Interface name \"%s\" is too long.", device); + close(socket); + return NULL; + } + + // check if the interface exist + if (ioctl(socket, SIOCGIFINDEX, &request, sizeof(request)) < 0) { + snprintf(errorBuffer, PCAP_ERRBUF_SIZE, + "Interface \"%s\" does not exist.\n", device); + close(socket); + return NULL; + } + + close(socket); + // no longer needed after this point + + // get link level interface for this interface + + socket = ::socket(AF_LINK, SOCK_DGRAM, 0); + if (socket < 0) { + snprintf(errorBuffer, PCAP_ERRBUF_SIZE, "No link level: %s\n", + strerror(errno)); + return NULL; + } + + // start monitoring + if (ioctl(socket, SIOCSPACKETCAP, &request, sizeof(struct ifreq)) < 0) { + snprintf(errorBuffer, PCAP_ERRBUF_SIZE, "Cannot start monitoring: %s\n", + strerror(errno)); + close(socket); + return NULL; + } + + struct wrapper_struct { pcap_t __common; struct pcap_haiku __private; }; + pcap_t* handle = pcap_create_common(errorBuffer, + sizeof (struct wrapper_struct), + offsetof (struct wrapper_struct, __private)); + + if (handle == NULL) { + snprintf(errorBuffer, PCAP_ERRBUF_SIZE, "malloc: %s", strerror(errno)); + close(socket); + return NULL; + } + + handle->selectable_fd = socket; + handle->fd = socket; + + handle->activate_op = pcap_activate_haiku; + + return handle; +} + +static int +can_be_bound(const char *name _U_) +{ + return 1; +} + +static int +get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf) +{ + /* TODO */ + 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); +} + +extern "C" int +pcap_platform_finddevs(pcap_if_list_t* _allDevices, char* errorBuffer) +{ + return pcap_findalldevs_interfaces(_allDevices, errorBuffer, can_be_bound, + get_if_flags); +} + +/* + * Libpcap version string. + */ +extern "C" const char * +pcap_lib_version(void) +{ + return (PCAP_VERSION_STRING); +} diff --git a/external/bsd/libpcap/dist/pcap-linktype.manmisc.in b/external/bsd/libpcap/dist/pcap-linktype.manmisc.in index 777e9dc73d7d..736a91c71453 100644 --- a/external/bsd/libpcap/dist/pcap-linktype.manmisc.in +++ b/external/bsd/libpcap/dist/pcap-linktype.manmisc.in @@ -18,7 +18,7 @@ .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" -.TH PCAP-LINKTYPE @MAN_MISC_INFO@ "7 April 2014" +.TH PCAP-LINKTYPE @MAN_MISC_INFO@ "6 April 2020" .SH NAME pcap-linktype \- link-layer header types supported by libpcap .SH DESCRIPTION @@ -38,11 +38,11 @@ so they are sometimes called "DLT_ values". The values stored in the link-layer header type field in the savefile header are, in most but not all cases, the same as the values returned by -.BR pcap_datalink() . +.BR pcap_datalink (). The names for those values begin with .BR LINKTYPE_ . .PP The link-layer header types supported by libpcap are described at -https://www.tcpdump.org/linktypes.html. +https://www.tcpdump.org/linktypes.html . .SH SEE ALSO -pcap(3PCAP) +.BR pcap (3PCAP) diff --git a/external/bsd/libpcap/dist/pcap-netmap.c b/external/bsd/libpcap/dist/pcap-netmap.c index b2301a7fd8de..27d36e5bb6d3 100644 --- a/external/bsd/libpcap/dist/pcap-netmap.c +++ b/external/bsd/libpcap/dist/pcap-netmap.c @@ -29,7 +29,6 @@ #endif #include -#include #include #include #include @@ -82,7 +81,7 @@ pcap_netmap_filter(u_char *arg, struct pcap_pkthdr *h, const u_char *buf) const struct bpf_insn *pc = p->fcode.bf_insns; ++pn->rx_pkts; - if (pc == NULL || bpf_filter(pc, buf, h->len, h->caplen)) + if (pc == NULL || pcap_filter(pc, buf, h->len, h->caplen)) pn->cb(pn->cb_arg, h, buf); } @@ -117,7 +116,7 @@ pcap_netmap_dispatch(pcap_t *p, int cnt, pcap_handler cb, u_char *user) /* XXX need to check the NIOCTXSYNC/poll */ static int -pcap_netmap_inject(pcap_t *p, const void *buf, size_t size) +pcap_netmap_inject(pcap_t *p, const void *buf, int size) { struct pcap_netmap *pn = p->priv; struct nm_desc *d = pn->d; @@ -287,7 +286,7 @@ pcap_netmap_create(const char *device, char *ebuf, int *is_ours) *is_ours = (!strncmp(device, "netmap:", 7) || !strncmp(device, "vale", 4)); if (! *is_ours) return NULL; - p = pcap_create_common(ebuf, sizeof (struct pcap_netmap)); + p = PCAP_CREATE_COMMON(ebuf, struct pcap_netmap); if (p == NULL) return (NULL); p->activate_op = pcap_netmap_activate; diff --git a/external/bsd/libpcap/dist/pcap-new.c b/external/bsd/libpcap/dist/pcap-new.c index e61cf6ab2e9b..76388a998fd5 100644 --- a/external/bsd/libpcap/dist/pcap-new.c +++ b/external/bsd/libpcap/dist/pcap-new.c @@ -36,6 +36,7 @@ #endif #include "ftmacros.h" +#include "diag-control.h" /* * sockutils.h may include on Windows, and pcap-int.h will @@ -88,7 +89,7 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t if (strlen(source) > PCAP_BUF_SIZE) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string is too long. Cannot handle it correctly."); + snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string is too long. Cannot handle it correctly."); return -1; } @@ -119,7 +120,7 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t if (*alldevs == NULL) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, + snprintf(errbuf, PCAP_ERRBUF_SIZE, "No interfaces found! Make sure libpcap/Npcap is properly installed" " on the local machine."); return -1; @@ -209,7 +210,7 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t } /* Save the path for future reference */ - pcap_snprintf(path, sizeof(path), "%s", name); + snprintf(path, sizeof(path), "%s", name); pathlen = strlen(path); #ifdef _WIN32 @@ -224,7 +225,7 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t if (filehandle == INVALID_HANDLE_VALUE) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error when listing files: does folder '%s' exist?", path); + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error when listing files: does folder '%s' exist?", path); return -1; } @@ -237,7 +238,10 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t if (filedata == NULL) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error when listing files: does folder '%s' exist?", path); + DIAG_OFF_FORMAT_TRUNCATION + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error when listing files: does folder '%s' exist?", path); + DIAG_ON_FORMAT_TRUNCATION + closedir(unixdir); return -1; } #endif @@ -249,11 +253,13 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t /* Skip the file if the pathname won't fit in the buffer */ if (pathlen + strlen(filedata.cFileName) >= sizeof(filename)) continue; - pcap_snprintf(filename, sizeof(filename), "%s%s", path, filedata.cFileName); + snprintf(filename, sizeof(filename), "%s%s", path, filedata.cFileName); #else if (pathlen + strlen(filedata->d_name) >= sizeof(filename)) continue; - pcap_snprintf(filename, sizeof(filename), "%s%s", path, filedata->d_name); + DIAG_OFF_FORMAT_TRUNCATION + snprintf(filename, sizeof(filename), "%s%s", path, filedata->d_name); + DIAG_ON_FORMAT_TRUNCATION #endif fp = pcap_open_offline(filename, errbuf); @@ -268,6 +274,11 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t PCAP_ERRBUF_SIZE, errno, "malloc() failed"); pcap_freealldevs(*alldevs); +#ifdef _WIN32 + FindClose(filehandle); +#else + closedir(unixdir); +#endif return -1; } @@ -297,6 +308,11 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t if (pcap_createsrcstr(tmpstring, PCAP_SRC_FILE, NULL, NULL, filename, errbuf) == -1) { pcap_freealldevs(*alldevs); +#ifdef _WIN32 + FindClose(filehandle); +#else + closedir(unixdir); +#endif return -1; } @@ -307,6 +323,11 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t PCAP_ERRBUF_SIZE, errno, "malloc() failed"); pcap_freealldevs(*alldevs); +#ifdef _WIN32 + FindClose(filehandle); +#else + closedir(unixdir); +#endif return -1; } @@ -321,6 +342,11 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t PCAP_ERRBUF_SIZE, errno, "malloc() failed"); pcap_freealldevs(*alldevs); +#ifdef _WIN32 + FindClose(filehandle); +#else + closedir(unixdir); +#endif return -1; } @@ -334,9 +360,11 @@ int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t #endif -#ifdef _WIN32 /* Close the search handle. */ +#ifdef _WIN32 FindClose(filehandle); +#else + closedir(unixdir); #endif return 0; @@ -370,7 +398,7 @@ pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, if (strlen(source) > PCAP_BUF_SIZE) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string is too long. Cannot handle it correctly."); + snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string is too long. Cannot handle it correctly."); return NULL; } @@ -444,17 +472,19 @@ pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, return fp; fail: + DIAG_OFF_FORMAT_TRUNCATION if (status == PCAP_ERROR) - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", + 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)", + snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", name, pcap_statustostr(status), fp->errbuf); else - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", + snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", name, pcap_statustostr(status)); + DIAG_ON_FORMAT_TRUNCATION pcap_close(fp); return NULL; } diff --git a/external/bsd/libpcap/dist/pcap-npf.c b/external/bsd/libpcap/dist/pcap-npf.c index da4641f379c8..99b5981e5a57 100644 --- a/external/bsd/libpcap/dist/pcap-npf.c +++ b/external/bsd/libpcap/dist/pcap-npf.c @@ -36,11 +36,23 @@ #endif #include +#include /* for INT_MAX */ #define PCAP_DONT_INCLUDE_PCAP_BPF_H #include #include #include +/* + * XXX - Packet32.h defines bpf_program, so we can't include + * , which also defines it; that's why we define + * PCAP_DONT_INCLUDE_PCAP_BPF_H, + * + * However, no header in the WinPcap or Npcap SDKs defines the + * macros for BPF code, so we have to define them ourselves. + */ +#define BPF_RET 0x06 +#define BPF_K 0x00 + /* Old-school MinGW have these headers in a different place. */ #if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) @@ -55,6 +67,10 @@ #include #endif /* HAVE_DAG_API */ +#include "diag-control.h" + +#include "pcap-airpcap.h" + 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_npf(pcap_t *); @@ -155,7 +171,7 @@ oid_get_request(ADAPTER *adapter, bpf_u_int32 oid, void *data, size_t *lenp, */ oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp); if (oid_data_arg == NULL) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Couldn't allocate argument buffer for PacketRequest"); return (PCAP_ERROR); } @@ -240,13 +256,13 @@ pcap_stats_npf(pcap_t *p, struct pcap_stat *ps) * have an API that returns data in a form like the Options section of a * pcapng Interface Statistics Block: * - * http://xml2rfc.tools.ietf.org/cgi-bin/xml2rfc.cgi?url=https://raw.githubusercontent.com/pcapng/pcapng/master/draft-tuexen-opsawg-pcapng.xml&modeAsFormat=html/ascii&type=ascii#rfc.section.4.6 + * https://xml2rfc.tools.ietf.org/cgi-bin/xml2rfc.cgi?url=https://raw.githubusercontent.com/pcapng/pcapng/master/draft-tuexen-opsawg-pcapng.xml&modeAsFormat=html/ascii&type=ascii#rfc.section.4.6 * * which would let us add new statistics straightforwardly and indicate which * statistics we are and are *not* providing, rather than having to provide * possibly-bogus values for statistics we can't provide. */ -struct pcap_stat * +static struct pcap_stat * pcap_stats_ex_npf(pcap_t *p, int *pcap_stat_size) { struct pcap_win *pw = p->priv; @@ -269,7 +285,12 @@ pcap_stats_ex_npf(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 ENABLE_REMOTE + /* + * Just in case this is ever compiled for a target other than + * Windows, which is somewhere between extremely unlikely and + * impossible. + */ +#ifdef _WIN32 p->stat.ps_capt = bstats.bs_capt; #endif return (&p->stat); @@ -283,7 +304,7 @@ pcap_setbuff_npf(pcap_t *p, int dim) if(PacketSetBuff(pw->adapter,dim)==FALSE) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer"); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer"); return (-1); } return (0); @@ -297,7 +318,7 @@ pcap_setmode_npf(pcap_t *p, int mode) if(PacketSetMode(pw->adapter,mode)==FALSE) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized"); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized"); return (-1); } @@ -312,7 +333,7 @@ pcap_setmintocopy_npf(pcap_t *p, int size) if(PacketSetMinToCopy(pw->adapter, size)==FALSE) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size"); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size"); return (-1); } return (0); @@ -350,7 +371,7 @@ pcap_oid_set_request_npf(pcap_t *p, bpf_u_int32 oid, const void *data, */ oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp); if (oid_data_arg == NULL) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Couldn't allocate argument buffer for PacketRequest"); return (PCAP_ERROR); } @@ -383,12 +404,6 @@ pcap_sendqueue_transmit_npf(pcap_t *p, pcap_send_queue *queue, int sync) struct pcap_win *pw = p->priv; u_int res; - 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(pw->adapter, queue->buffer, queue->len, @@ -396,7 +411,7 @@ pcap_sendqueue_transmit_npf(pcap_t *p, pcap_send_queue *queue, int sync) if(res != queue->len){ pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE, - GetLastError(), "Error opening adapter"); + GetLastError(), "Error queueing packets"); } return (res); @@ -409,7 +424,7 @@ pcap_setuserbuffer_npf(pcap_t *p, int size) if (size<=0) { /* Bogus parameter */ - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error: invalid size %d",size); return (-1); } @@ -418,7 +433,7 @@ pcap_setuserbuffer_npf(pcap_t *p, int size) new_buff=(unsigned char*)malloc(sizeof(char)*size); if (!new_buff) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error: not enough memory"); return (-1); } @@ -431,6 +446,31 @@ pcap_setuserbuffer_npf(pcap_t *p, int size) return (0); } +#ifdef HAVE_NPCAP_PACKET_API +/* + * Kernel dump mode isn't supported in Npcap; calls to PacketSetDumpName(), + * PacketSetDumpLimits(), and PacketIsDumpEnded() will get compile-time + * deprecation warnings. + * + * Avoid calling them; just return errors indicating that kernel dump + * mode isn't supported in Npcap. + */ +static int +pcap_live_dump_npf(pcap_t *p, char *filename _U_, int maxsize _U_, + int maxpacks _U_) +{ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "Npcap doesn't support kernel dump mode"); + return (-1); +} +static int +pcap_live_dump_ended_npf(pcap_t *p, int sync) +{ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "Npcap doesn't support kernel dump mode"); + return (-1); +} +#else /* HAVE_NPCAP_PACKET_API */ static int pcap_live_dump_npf(pcap_t *p, char *filename, int maxsize, int maxpacks) { @@ -440,7 +480,7 @@ pcap_live_dump_npf(pcap_t *p, char *filename, int maxsize, int maxpacks) /* Set the packet driver in dump mode */ res = PacketSetMode(pw->adapter, PACKET_MODE_DUMP); if(res == FALSE){ - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error setting dump mode"); return (-1); } @@ -448,7 +488,7 @@ pcap_live_dump_npf(pcap_t *p, char *filename, int maxsize, int maxpacks) /* Set the name of the dump file */ res = PacketSetDumpName(pw->adapter, filename, (int)strlen(filename)); if(res == FALSE){ - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error setting kernel dump file name"); return (-1); } @@ -456,8 +496,8 @@ pcap_live_dump_npf(pcap_t *p, char *filename, int maxsize, int maxpacks) /* Set the limits of the dump file */ res = PacketSetDumpLimits(pw->adapter, maxsize, maxpacks); if(res == FALSE) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "Error setting dump limit"); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "Error setting dump limit"); return (-1); } @@ -471,31 +511,36 @@ pcap_live_dump_ended_npf(pcap_t *p, int sync) return (PacketIsDumpEnded(pw->adapter, (BOOLEAN)sync)); } +#endif /* HAVE_NPCAP_PACKET_API */ +#ifdef HAVE_AIRPCAP_API static PAirpcapHandle pcap_get_airpcap_handle_npf(pcap_t *p) { -#ifdef HAVE_AIRPCAP_API struct pcap_win *pw = p->priv; return (PacketGetAirPcapHandle(pw->adapter)); -#else +} +#else /* HAVE_AIRPCAP_API */ +static PAirpcapHandle +pcap_get_airpcap_handle_npf(pcap_t *p _U_) +{ return (NULL); -#endif /* HAVE_AIRPCAP_API */ } +#endif /* HAVE_AIRPCAP_API */ static int pcap_read_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) { PACKET Packet; int cc; - int n = 0; + int n; register u_char *bp, *ep; u_char *datap; struct pcap_win *pw = p->priv; cc = p->cc; - if (p->cc == 0) { + if (cc == 0) { /* * Has "pcap_breakloop()" been called? */ @@ -525,27 +570,53 @@ pcap_read_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) { /* * Did the device go away? - * If so, the error we get is ERROR_GEN_FAILURE. + * If so, the error we get can either be + * ERROR_GEN_FAILURE or ERROR_DEVICE_REMOVED. */ DWORD errcode = GetLastError(); - if (errcode == ERROR_GEN_FAILURE) { + if (errcode == ERROR_GEN_FAILURE || + errcode == ERROR_DEVICE_REMOVED) { /* * The device on which we're capturing * went away, or it became unusable * by NPF due to a suspend/resume. * + * ERROR_GEN_FAILURE comes from + * STATUS_UNSUCCESSFUL, as well as some + * other NT status codes that the Npcap + * driver is unlikely to return. * XXX - hopefully no other error * conditions are indicated by this. * + * ERROR_DEVICE_REMOVED comes from + * STATUS_DEVICE_REMOVED. + * + * We report the Windows status code + * name and the corresponding NT status + * code name, for the benefit of attempts + * to debug cases where this error is + * reported when the device *wasn't* + * removed, either because it's not + * removable, it's removable but wasn't + * removed, or it's a device that doesn't + * correspond to a physical device. + * * XXX - we really should return an * appropriate error for that, but * pcap_dispatch() etc. aren't * documented as having error returns * other than PCAP_ERROR or PCAP_ERROR_BREAK. */ - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "The interface disappeared"); + const char *errcode_msg; + + if (errcode == ERROR_GEN_FAILURE) + errcode_msg = "ERROR_GEN_FAILURE/STATUS_UNSUCCESSFUL"; + else + errcode_msg = "ERROR_DEVICE_REMOVED/STATUS_DEVICE_REMOVED"; + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "The interface disappeared (error code %s)", + errcode_msg); } else { pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE, errcode, @@ -563,11 +634,15 @@ pcap_read_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) /* * Loop through each packet. + * + * This assumes that a single buffer of packets will have + * <= INT_MAX packets, so the packet count doesn't overflow. */ #define bhp ((struct bpf_hdr *)bp) + n = 0; ep = bp + cc; for (;;) { - register int caplen, hdrlen; + register u_int caplen, hdrlen; /* * Has "pcap_breakloop()" been called? @@ -601,13 +676,13 @@ pcap_read_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) * in kernel, no need to do it now - we already know * the packet passed the filter. * - * XXX - bpf_filter() should always return TRUE if + * XXX - pcap_filter() should always return TRUE if * handed a null pointer for the program, but it might * just try to "run" the filter, so we check here. */ if (pw->filtering_in_kernel || p->fcode.bf_insns == NULL || - bpf_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) { + pcap_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) { #ifdef ENABLE_REMOTE switch (p->rmt_samp.method) { @@ -706,7 +781,7 @@ pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user) */ PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize); if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed"); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed"); return (-1); } @@ -721,6 +796,21 @@ pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user) endofbuf = (char*)header + cc; + /* + * This can conceivably process more than INT_MAX packets, + * which would overflow the packet count, causing it either + * to look like a negative number, and thus cause us to + * return a value that looks like an error, or overflow + * back into positive territory, and thus cause us to + * return a too-low count. + * + * Therefore, if the packet count is unlimited, we clip + * it at INT_MAX; this routine is not expected to + * process packets indefinitely, so that's not an issue. + */ + if (PACKET_COUNT_IS_UNLIMITED(cnt)) + cnt = INT_MAX; + /* * Cycle through the packets */ @@ -811,10 +901,10 @@ pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user) } } - /* No underlaying filtering system. We need to filter on our own */ + /* No underlying filtering system. We need to filter on our own */ if (p->fcode.bf_insns) { - if (bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0) + if (pcap_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0) { /* Move to next packet */ header = (dag_record_t*)((char*)header + erf_record_len); @@ -822,7 +912,7 @@ pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user) } } - /* Fill the header for the user suppplied callback function */ + /* Fill the header for the user supplied callback function */ pcap_header.caplen = caplen; pcap_header.len = packet_len; @@ -848,14 +938,15 @@ 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_npf(pcap_t *p, const void *buf, size_t size) +pcap_inject_npf(pcap_t *p, const void *buf, int size) { struct pcap_win *pw = p->priv; PACKET pkt; PacketInitPacket(&pkt, (PVOID)buf, size); if(PacketSendPacket(pw->adapter,&pkt,TRUE) == FALSE) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketSendPacket failed"); + pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE, + GetLastError(), "send error: PacketSendPacket failed"); return (-1); } @@ -864,7 +955,7 @@ pcap_inject_npf(pcap_t *p, const void *buf, size_t size) * "pcap_inject()" is expected to return the number of bytes * sent. */ - return ((int)size); + return (size); } static void @@ -883,6 +974,48 @@ pcap_cleanup_npf(pcap_t *p) pcap_cleanup_live_common(p); } +static void +pcap_breakloop_npf(pcap_t *p) +{ + pcap_breakloop_common(p); + struct pcap_win *pw = p->priv; + + /* XXX - what if this fails? */ + SetEvent(PacketGetReadEvent(pw->adapter)); +} + +/* + * These are NTSTATUS values: + * + * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/87fba13e-bf06-450e-83b1-9241dc81e781 + * + * with the "Customer" bit set. If a driver returns them, they are not + * mapped to Windows error values in userland; they're returned by + * GetLastError(). + * + * Note that "driver" here includes the Npcap NPF driver, as various + * versions would take NT status values and set the "Customer" bit + * before returning the status code. The commit message for the + * change that started doing that is + * + * Returned a customer-defined NTSTATUS in OID requests to avoid + * NTSTATUS-to-Win32 Error code translation. + * + * but I don't know why the goal was to avoid that translation. + * + * Attempting to set the hardware filter on a Microsoft Surface Pro's + * Mobile Broadband Adapter returns an error that appears to be + * NDIS_STATUS_NOT_SUPPORTED ORed with the "Customer" bit, so it's + * probably indicating that it doesn't support that. + * + * It is likely that there are other devices which throw spurious errors, + * at which point this will need refactoring to efficiently check against + * a list, but for now we can just check this one value. Perhaps the + * right way to do this is compare against various NDIS errors with + * the "customer" bit ORed in. + */ +#define NT_STATUS_CUSTOMER_DEFINED 0x20000000 + static int pcap_activate_npf(pcap_t *p) { @@ -890,6 +1023,8 @@ pcap_activate_npf(pcap_t *p) NetType type; int res; int status = 0; + struct bpf_insn total_insn; + struct bpf_program total_prog; if (p->opt.rfmon) { /* @@ -921,7 +1056,7 @@ pcap_activate_npf(pcap_t *p) } } - /* Init WinSock */ + /* Init Winsock if it hasn't already been initialized */ pcap_wsockinit(); pw->adapter = PacketOpenAdapter(p->opt.device); @@ -933,12 +1068,30 @@ pcap_activate_npf(pcap_t *p) /* * What error did we get when trying to open the adapter? */ - if (errcode == ERROR_BAD_UNIT) { + switch (errcode) { + + case ERROR_BAD_UNIT: /* * There's no such device. + * There's nothing to add, so clear the error + * message. */ + p->errbuf[0] = '\0'; return (PCAP_ERROR_NO_SUCH_DEVICE); - } else { + + case ERROR_ACCESS_DENIED: + /* + * There is, but we don't have permission to + * use it. + * + * XXX - we currently get ERROR_BAD_UNIT if the + * user says "no" to the UAC prompt. + */ + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "The helper program for \"Admin-only Mode\" must be allowed to make changes to your device"); + return (PCAP_ERROR_PERM_DENIED); + + default: /* * Unknown - report details. */ @@ -963,10 +1116,9 @@ pcap_activate_npf(pcap_t *p) /*Set the linktype*/ switch (type.LinkType) { - case NdisMediumWan: - p->linktype = DLT_EN10MB; - break; - + /* + * NDIS-defined medium types. + */ case NdisMedium802_3: p->linktype = DLT_EN10MB; /* @@ -990,12 +1142,19 @@ pcap_activate_npf(pcap_t *p) } break; + case NdisMedium802_5: + /* + * Token Ring. + */ + p->linktype = DLT_IEEE802; + break; + case NdisMediumFddi: p->linktype = DLT_FDDI; break; - case NdisMedium802_5: - p->linktype = DLT_IEEE802; + case NdisMediumWan: + p->linktype = DLT_EN10MB; break; case NdisMediumArcnetRaw: @@ -1010,18 +1169,29 @@ pcap_activate_npf(pcap_t *p) p->linktype = DLT_ATM_RFC1483; break; - case NdisMediumCHDLC: - p->linktype = DLT_CHDLC; + case NdisMediumWirelessWan: + p->linktype = DLT_RAW; break; - case NdisMediumPPPSerial: - p->linktype = DLT_PPP_SERIAL; + case NdisMediumIP: + p->linktype = DLT_RAW; break; + /* + * Npcap-defined medium types. + */ case NdisMediumNull: p->linktype = DLT_NULL; break; + case NdisMediumCHDLC: + p->linktype = DLT_CHDLC; + break; + + case NdisMediumPPPSerial: + p->linktype = DLT_PPP_SERIAL; + break; + case NdisMediumBare80211: p->linktype = DLT_IEEE802_11; break; @@ -1034,12 +1204,6 @@ pcap_activate_npf(pcap_t *p) p->linktype = DLT_PPI; break; -#ifdef NdisMediumWirelessWan - case NdisMediumWirelessWan: - p->linktype = DLT_RAW; - break; -#endif - default: /* * An unknown medium type is assumed to supply Ethernet @@ -1053,13 +1217,72 @@ pcap_activate_npf(pcap_t *p) * some programs will report the warning. */ p->linktype = DLT_EN10MB; - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Unknown NdisMedium value %d, defaulting to DLT_EN10MB", type.LinkType); status = PCAP_WARNING; break; } +#ifdef HAVE_PACKET_GET_TIMESTAMP_MODES + /* + * Set the timestamp type. + * (Yes, we require PacketGetTimestampModes(), not just + * PacketSetTimestampMode(). If we have the former, we + * have the latter, unless somebody's using a version + * of Npcap that they've hacked to provide the former + * but not the latter; if they've done that, either + * they're confused or they're trolling us.) + */ + switch (p->opt.tstamp_type) { + + case PCAP_TSTAMP_HOST_HIPREC_UNSYNCED: + /* + * Better than low-res, but *not* synchronized with + * the OS clock. + */ + if (!PacketSetTimestampMode(pw->adapter, TIMESTAMPMODE_SINGLE_SYNCHRONIZATION)) + { + pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE, + GetLastError(), "Cannot set the time stamp mode to TIMESTAMPMODE_SINGLE_SYNCHRONIZATION"); + goto bad; + } + break; + + case PCAP_TSTAMP_HOST_LOWPREC: + /* + * Low-res, but synchronized with the OS clock. + */ + if (!PacketSetTimestampMode(pw->adapter, TIMESTAMPMODE_QUERYSYSTEMTIME)) + { + pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE, + GetLastError(), "Cannot set the time stamp mode to TIMESTAMPMODE_QUERYSYSTEMTIME"); + goto bad; + } + break; + + case PCAP_TSTAMP_HOST_HIPREC: + /* + * High-res, and synchronized with the OS clock. + */ + if (!PacketSetTimestampMode(pw->adapter, TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE)) + { + pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE, + GetLastError(), "Cannot set the time stamp mode to TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE"); + goto bad; + } + break; + + case PCAP_TSTAMP_HOST: + /* + * XXX - do whatever the default is, for now. + * Set to the highest resolution that's synchronized + * with the system clock? + */ + break; + } +#endif /* HAVE_PACKET_GET_TIMESTAMP_MODES */ + /* * Turn a negative snapshot value (invalid), a snapshot value of * 0 (unspecified), or a value bigger than the normal maximum @@ -1077,17 +1300,66 @@ pcap_activate_npf(pcap_t *p) 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; + DWORD errcode = GetLastError(); + + /* + * Suppress spurious error generated by non-compiant + * MS Surface mobile adapters that appear to + * return NDIS_STATUS_NOT_SUPPORTED for attempts + * to set the hardware filter. + * + * It appears to be reporting NDIS_STATUS_NOT_SUPPORTED, + * but with the NT status value "Customer" bit set; + * the Npcap NPF driver sets that bit in some cases. + * + * If we knew that this meant "promiscuous mode + * isn't supported", we could add a "promiscuous + * mode isn't supported" error code and return + * that, but: + * + * 1) we don't know that it means that + * rather than meaning "we reject attempts + * to set the filter, even though the NDIS + * specifications say you shouldn't do that" + * + * and + * + * 2) other interface types that don't + * support promiscuous mode, at least + * on UN*Xes, just silently ignore + * attempts to set promiscuous mode + * + * and rejecting it with an error could disrupt + * attempts to capture, as many programs (tcpdump, + * *shark) default to promiscuous mode. + * + * Alternatively, we could return the "promiscuous + * mode not supported" *warning* value, so that + * correct code will either ignore it or report + * it and continue capturing. (This may require + * a pcap_init() flag to request that return + * value, so that old incorrect programs that + * assume a non-zero return from pcap_activate() + * is an error don't break.) + */ + if (errcode != (NDIS_STATUS_NOT_SUPPORTED|NT_STATUS_CUSTOMER_DEFINED)) + { + pcap_fmt_errmsg_for_win32_err(p->errbuf, + PCAP_ERRBUF_SIZE, errcode, + "failed to set hardware filter to promiscuous mode"); + goto bad; + } } } else { - /* 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. + /* + * 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 | @@ -1095,8 +1367,19 @@ pcap_activate_npf(pcap_t *p) 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; + DWORD errcode = GetLastError(); + + /* + * Suppress spurious error generated by non-compiant + * MS Surface mobile adapters. + */ + if (errcode != (NDIS_STATUS_NOT_SUPPORTED|NT_STATUS_CUSTOMER_DEFINED)) + { + pcap_fmt_errmsg_for_win32_err(p->errbuf, + PCAP_ERRBUF_SIZE, errcode, + "failed to set hardware filter to non-promiscuous mode"); + goto bad; + } } } @@ -1112,12 +1395,12 @@ pcap_activate_npf(pcap_t *p) * If the buffer size wasn't explicitly set, default to * WIN32_DEFAULT_KERNEL_BUFFER_SIZE. */ - if (p->opt.buffer_size == 0) - p->opt.buffer_size = WIN32_DEFAULT_KERNEL_BUFFER_SIZE; + if (p->opt.buffer_size == 0) + p->opt.buffer_size = WIN32_DEFAULT_KERNEL_BUFFER_SIZE; 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"); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer"); goto bad; } @@ -1166,7 +1449,7 @@ pcap_activate_npf(pcap_t *p) int postype = 0; char keyname[512]; - pcap_snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s", + snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s", "SYSTEM\\CurrentControlSet\\Services\\DAG", strstr(_strlwr(p->opt.device), "dag")); do @@ -1205,6 +1488,29 @@ pcap_activate_npf(pcap_t *p) #endif /* HAVE_DAG_API */ } + /* + * If there's no filter program installed, there's + * no indication to the kernel of what the snapshot + * length should be, so no snapshotting is done. + * + * Therefore, when we open the device, we install + * an "accept everything" filter with the specified + * snapshot length. + */ + total_insn.code = (u_short)(BPF_RET | BPF_K); + total_insn.jt = 0; + total_insn.jf = 0; + total_insn.k = p->snapshot; + + total_prog.bf_len = 1; + total_prog.bf_insns = &total_insn; + if (!PacketSetBpf(pw->adapter, &total_prog)) { + pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE, + GetLastError(), "PacketSetBpf"); + status = PCAP_ERROR; + goto bad; + } + PacketSetReadTimeout(pw->adapter, p->opt.timeout); /* disable loopback capture if requested */ @@ -1212,7 +1518,7 @@ pcap_activate_npf(pcap_t *p) { if (!PacketSetLoopbackBehavior(pw->adapter, NPF_DISABLE_LOOPBACK)) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Unable to disable the capture of loopback packets."); goto bad; } @@ -1241,6 +1547,7 @@ pcap_activate_npf(pcap_t *p) p->getnonblock_op = pcap_getnonblock_npf; p->setnonblock_op = pcap_setnonblock_npf; p->stats_op = pcap_stats_npf; + p->breakloop_op = pcap_breakloop_npf; p->stats_ex_op = pcap_stats_ex_npf; p->setbuff_op = pcap_setbuff_npf; p->setmode_op = pcap_setmode_npf; @@ -1283,17 +1590,295 @@ pcap_can_set_rfmon_npf(pcap_t *p) return (PacketIsMonitorModeSupported(p->opt.device) == 1); } +/* + * Get a list of time stamp types. + */ +#ifdef HAVE_PACKET_GET_TIMESTAMP_MODES +static int +get_ts_types(const char *device, pcap_t *p, char *ebuf) +{ + char *device_copy = NULL; + ADAPTER *adapter = NULL; + ULONG num_ts_modes; + BOOL ret; + DWORD error = ERROR_SUCCESS; + ULONG *modes = NULL; + int status = 0; + + do { + /* + * First, find out how many time stamp modes we have. + * To do that, we have to open the adapter. + * + * XXX - PacketOpenAdapter() takes a non-const pointer + * as an argument, so we make a copy of the argument and + * pass that to it. + */ + device_copy = strdup(device); + if (device_copy == NULL) { + pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, errno, "malloc"); + status = -1; + break; + } + + adapter = PacketOpenAdapter(device_copy); + if (adapter == NULL) + { + error = GetLastError(); + /* + * If we can't open the device now, we won't be + * able to later, either. + * + * If the error is something that indicates + * that the device doesn't exist, or that they + * don't have permission to open the device - or + * perhaps that they don't have permission to get + * a list of devices, if PacketOpenAdapter() does + * that - the user will find that out when they try + * to activate the device; just return an empty + * list of time stamp types. + * + * Treating either of those as errors will, for + * example, cause "tcpdump -i " to fail, + * because it first tries to pass the interface + * name to pcap_create() and pcap_activate(), + * in order to handle OSes where interfaces can + * have names that are just numbers (stand up + * and say hello, Linux!), and, if pcap_activate() + * fails with a "no such device" error, checks + * whether the interface name is a valid number + * and, if so, tries to use it as an index in + * the list of interfaces. + * + * That means pcap_create() must succeed even + * for interfaces that don't exist, with the + * failure occurring at pcap_activate() time. + */ + if (error == ERROR_BAD_UNIT || + error == ERROR_ACCESS_DENIED) { + p->tstamp_type_count = 0; + p->tstamp_type_list = NULL; + status = 0; + } else { + pcap_fmt_errmsg_for_win32_err(ebuf, + PCAP_ERRBUF_SIZE, error, + "Error opening adapter"); + status = -1; + } + break; + } + + /* + * Get the total number of time stamp modes. + * + * The buffer for PacketGetTimestampModes() is + * a sequence of 1 or more ULONGs. What's + * passed to PacketGetTimestampModes() should have + * the total number of ULONGs in the first ULONG; + * what's returned *from* PacketGetTimestampModes() + * has the total number of time stamp modes in + * the first ULONG. + * + * Yes, that means if there are N time stamp + * modes, the first ULONG should be set to N+1 + * on input, and will be set to N on output. + * + * We first make a call to PacketGetTimestampModes() + * with a pointer to a single ULONG set to 1; the + * call should fail with ERROR_MORE_DATA (unless + * there are *no* modes, but that should never + * happen), and that ULONG should be set to the + * number of modes. + */ + num_ts_modes = 1; + ret = PacketGetTimestampModes(adapter, &num_ts_modes); + if (!ret) { + /* + * OK, it failed. Did it fail with + * ERROR_MORE_DATA? + */ + error = GetLastError(); + if (error != ERROR_MORE_DATA) { + /* + * No, did it fail with ERROR_INVALID_FUNCTION? + */ + if (error == ERROR_INVALID_FUNCTION) { + /* + * This is probably due to + * the driver with which Packet.dll + * communicates being older, or + * being a WinPcap driver, so + * that it doesn't support + * BIOCGTIMESTAMPMODES. + * + * Tell the user to try uninstalling + * Npcap - and WinPcap if installed - + * and re-installing it, to flush + * out all older drivers. + */ + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "PacketGetTimestampModes() failed with ERROR_INVALID_FUNCTION; try uninstalling Npcap, and WinPcap if installed, and re-installing it from npcap.com"); + status = -1; + break; + } + + /* + * No, some other error. Fail. + */ + pcap_fmt_errmsg_for_win32_err(ebuf, + PCAP_ERRBUF_SIZE, error, + "Error calling PacketGetTimestampModes"); + status = -1; + break; + } + } + /* else (ret == TRUE) + * Unexpected success. Let's act like we got ERROR_MORE_DATA. + * If it doesn't work, we'll hit some other error condition farther on. + */ + + /* If the driver reports no modes supported *and* + * ERROR_MORE_DATA, something is seriously wrong. + * We *could* ignore the error and continue without supporting + * settable timestamp modes, but that would hide a bug. + */ + if (num_ts_modes == 0) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "PacketGetTimestampModes() reports 0 modes supported."); + status = -1; + break; + } + + /* + * Yes, so we now know how many types to fetch. + * + * The buffer needs to have one ULONG for the + * count and num_ts_modes ULONGs for the + * num_ts_modes time stamp types. + */ + modes = (ULONG *)malloc((1 + num_ts_modes) * sizeof(ULONG)); + if (modes == NULL) { + /* Out of memory. */ + pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, errno, "malloc"); + status = -1; + break; + } + modes[0] = 1 + num_ts_modes; + if (!PacketGetTimestampModes(adapter, modes)) { + pcap_fmt_errmsg_for_win32_err(ebuf, + PCAP_ERRBUF_SIZE, GetLastError(), + "Error calling PacketGetTimestampModes"); + status = -1; + break; + } + if (modes[0] != num_ts_modes) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "First PacketGetTimestampModes() call gives %lu modes, second call gives %lu modes", + num_ts_modes, modes[0]); + status = -1; + break; + } + + /* + * Allocate a buffer big enough for + * PCAP_TSTAMP_HOST (default) plus + * the explicitly specified modes. + */ + p->tstamp_type_list = malloc((1 + num_ts_modes) * sizeof(u_int)); + if (p->tstamp_type_list == NULL) { + pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, errno, "malloc"); + status = -1; + break; + } + u_int num_ts_types = 0; + p->tstamp_type_list[num_ts_types] = + PCAP_TSTAMP_HOST; + num_ts_types++; + for (ULONG i = 0; i < num_ts_modes; i++) { + switch (modes[i + 1]) { + + case TIMESTAMPMODE_SINGLE_SYNCHRONIZATION: + /* + * Better than low-res, + * but *not* synchronized + * with the OS clock. + */ + p->tstamp_type_list[num_ts_types] = + PCAP_TSTAMP_HOST_HIPREC_UNSYNCED; + num_ts_types++; + break; + + case TIMESTAMPMODE_QUERYSYSTEMTIME: + /* + * Low-res, but synchronized + * with the OS clock. + */ + p->tstamp_type_list[num_ts_types] = + PCAP_TSTAMP_HOST_LOWPREC; + num_ts_types++; + break; + + case TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE: + /* + * High-res, and synchronized + * with the OS clock. + */ + p->tstamp_type_list[num_ts_types] = + PCAP_TSTAMP_HOST_HIPREC; + num_ts_types++; + break; + + default: + /* + * Unknown, so we can't + * report it. + */ + break; + } + } + p->tstamp_type_count = num_ts_types; + } while (0); + + /* Clean up temporary allocations */ + if (device_copy != NULL) { + free(device_copy); + } + if (modes != NULL) { + free(modes); + } + if (adapter != NULL) { + PacketCloseAdapter(adapter); + } + + return status; +} +#else /* HAVE_PACKET_GET_TIMESTAMP_MODES */ +static int +get_ts_types(const char *device _U_, pcap_t *p _U_, char *ebuf _U_) +{ + /* + * Nothing to fetch, so it always "succeeds". + */ + return 0; +} +#endif /* HAVE_PACKET_GET_TIMESTAMP_MODES */ + pcap_t * pcap_create_interface(const char *device _U_, char *ebuf) { pcap_t *p; - p = pcap_create_common(ebuf, sizeof(struct pcap_win)); + p = PCAP_CREATE_COMMON(ebuf, struct pcap_win); if (p == NULL) return (NULL); p->activate_op = pcap_activate_npf; p->can_set_rfmon_op = pcap_can_set_rfmon_npf; + + if (get_ts_types(device, p, ebuf) == -1) { + pcap_close(p); + return (NULL); + } return (p); } @@ -1356,7 +1941,7 @@ pcap_setfilter_npf(pcap_t *p, struct bpf_program *fp) } /* - * We filter at user level, since the kernel driver does't process the packets + * We filter at user level, since the kernel driver doesn't process the packets */ static int pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) { @@ -1500,8 +2085,8 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf) #ifdef OID_GEN_PHYSICAL_MEDIUM_EX OID_GEN_PHYSICAL_MEDIUM_EX, #endif - OID_GEN_PHYSICAL_MEDIUM - }; + 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 */ @@ -1554,7 +2139,7 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf) *flags |= PCAP_IF_WIRELESS; /* - * A "network assosiation state" makes no sense for airpcap. + * A "network association state" makes no sense for airpcap. */ *flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE; PacketCloseAdapter(adapter); @@ -1596,6 +2181,12 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf) * running. */ break; + + default: + /* + * Unknown. + */ + break; } } else { /* @@ -1632,7 +2223,13 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf) if (status == 0) { /* * We got the physical medium. + * + * XXX - we might want to check for NdisPhysicalMediumWiMax + * and NdisPhysicalMediumNative802_15_4 being + * part of the enum, and check for those in the "wireless" + * case. */ +DIAG_OFF_ENUM_SWITCH switch (phys_medium) { case NdisPhysicalMediumWirelessLan: @@ -1649,10 +2246,11 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf) default: /* - * Not wireless. + * Not wireless or unknown */ break; } +DIAG_ON_ENUM_SWITCH } #endif @@ -1683,6 +2281,13 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf) */ *flags |= PCAP_IF_CONNECTION_STATUS_DISCONNECTED; break; + + case MediaConnectStateUnknown: + default: + /* + * It's unknown whether it's connected or not. + */ + break; } } #else @@ -1765,7 +2370,7 @@ pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf) AdaptersName = (char*) malloc(NameLength); if (AdaptersName == NULL) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot allocate enough memory to list the adapters."); + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot allocate enough memory to list the adapters."); return (-1); } @@ -1793,7 +2398,7 @@ pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf) desc++; /* - * Found it - "desc" points to the first of the two + * Found it - "desc" points to the first of the two * nulls at the end of the list of names, so the * first byte of the list of descriptions is two bytes * after it. @@ -1806,6 +2411,20 @@ pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf) name = &AdaptersName[0]; while (*name != '\0') { bpf_u_int32 flags = 0; + +#ifdef HAVE_AIRPCAP_API + /* + * Is this an AirPcap device? + * If so, ignore it; it'll get added later, by the + * AirPcap code. + */ + if (device_is_airpcap(name, errbuf) == 1) { + name += strlen(name) + 1; + desc += strlen(desc) + 1; + continue; + } +#endif + #ifdef HAVE_PACKET_IS_LOOPBACK_ADAPTER /* * Is this a loopback interface? @@ -1861,10 +2480,26 @@ pcap_lookupdev(char *errbuf) DWORD dwVersion; DWORD dwWindowsMajorVersion; -#pragma warning (push) -#pragma warning (disable: 4996) /* disable MSVC's GetVersion() deprecated warning here */ + /* + * We disable this in "new API" mode, because 1) in WinPcap/Npcap, + * it may return UTF-16 strings, for backwards-compatibility + * reasons, and we're also disabling the hack to make that work, + * for not-going-past-the-end-of-a-string reasons, and 2) we + * want its behavior to be consistent. + * + * In addition, it's not thread-safe, so we've marked it as + * deprecated. + */ + if (pcap_new_api) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "pcap_lookupdev() is deprecated and is not supported in programs calling pcap_init()"); + return (NULL); + } + +/* disable MSVC's GetVersion() deprecated warning here */ +DIAG_OFF_DEPRECATION dwVersion = GetVersion(); /* get the OS version */ -#pragma warning (pop) +DIAG_ON_DEPRECATION dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) { @@ -1895,7 +2530,7 @@ pcap_lookupdev(char *errbuf) if(TAdaptersName == NULL) { - (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure"); + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure"); return NULL; } @@ -2056,7 +2691,7 @@ pcap_lib_version(void) /* * Generate the version string. */ - char *packet_version_string = PacketGetVersion(); + const char *packet_version_string = PacketGetVersion(); if (strcmp(WINPCAP_VER_STRING, packet_version_string) == 0) { /* diff --git a/external/bsd/libpcap/dist/pcap-rdmasniff.c b/external/bsd/libpcap/dist/pcap-rdmasniff.c index c50fe3fd693f..d63ca898877b 100644 --- a/external/bsd/libpcap/dist/pcap-rdmasniff.c +++ b/external/bsd/libpcap/dist/pcap-rdmasniff.c @@ -38,6 +38,7 @@ #include #include #include +#include /* for INT_MAX */ #include #if !defined(IBV_FLOW_ATTR_SNIFFER) @@ -57,7 +58,7 @@ struct pcap_rdmasniff { struct ibv_flow * flow; struct ibv_mr * mr; u_char * oneshot_buffer; - unsigned port_num; + unsigned long port_num; int cq_event; u_int packets_recv; }; @@ -136,15 +137,30 @@ rdmasniff_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u priv->cq_event = 1; } - while (count < max_packets || PACKET_COUNT_IS_UNLIMITED(max_packets)) { + /* + * This can conceivably process more than INT_MAX packets, + * which would overflow the packet count, causing it either + * to look like a negative number, and thus cause us to + * return a value that looks like an error, or overflow + * back into positive territory, and thus cause us to + * return a too-low count. + * + * Therefore, if the packet count is unlimited, we clip + * it at INT_MAX; this routine is not expected to + * process packets indefinitely, so that's not an issue. + */ + if (PACKET_COUNT_IS_UNLIMITED(max_packets)) + max_packets = INT_MAX; + + while (count < 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, + fprintf(stderr, "failed WC wr_id %" PRIu64 " status %d/%s\n", + wc.wr_id, wc.status, ibv_wc_status_str(wc.status)); continue; } @@ -156,7 +172,7 @@ rdmasniff_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u 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)) { + pcap_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) { callback(user, &pkth, pktd); ++priv->packets_recv; ++count; @@ -197,21 +213,21 @@ rdmasniff_activate(pcap_t *handle) priv->context = ibv_open_device(priv->rdma_device); if (!priv->context) { - pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, + 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, + 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, + snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to create comp channel for device %s", handle->opt.device); goto error; } @@ -219,7 +235,7 @@ rdmasniff_activate(pcap_t *handle) priv->cq = ibv_create_cq(priv->context, RDMASNIFF_NUM_RECEIVES, NULL, priv->channel, 0); if (!priv->cq) { - pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, + snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to create CQ for device %s", handle->opt.device); goto error; } @@ -233,7 +249,7 @@ rdmasniff_activate(pcap_t *handle) 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, + snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to create QP for device %s", handle->opt.device); goto error; } @@ -242,7 +258,7 @@ rdmasniff_activate(pcap_t *handle) 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, + snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to modify QP to INIT for device %s", handle->opt.device); goto error; } @@ -250,7 +266,7 @@ rdmasniff_activate(pcap_t *handle) 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, + snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to modify QP to RTR for device %s", handle->opt.device); goto error; } @@ -261,7 +277,7 @@ rdmasniff_activate(pcap_t *handle) 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, + snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to create flow for device %s", handle->opt.device); goto error; } @@ -269,21 +285,21 @@ rdmasniff_activate(pcap_t *handle) handle->bufsize = RDMASNIFF_NUM_RECEIVES * RDMASNIFF_RECEIVE_SIZE; handle->buffer = malloc(handle->bufsize); if (!handle->buffer) { - pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, + 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, + 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, + snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to register MR for device %s", handle->opt.device); goto error; } @@ -361,14 +377,18 @@ rdmasniff_create(const char *device, char *ebuf, int *is_ours) int numdev; size_t namelen; const char *port; - unsigned port_num; + unsigned long port_num; int i; pcap_t *p = NULL; *is_ours = 0; dev_list = ibv_get_device_list(&numdev); - if (!dev_list || !numdev) { + if (!dev_list) { + return NULL; + } + if (!numdev) { + ibv_free_device_list(dev_list); return NULL; } @@ -391,7 +411,7 @@ rdmasniff_create(const char *device, char *ebuf, int *is_ours) !strncmp(device, dev_list[i]->name, namelen)) { *is_ours = 1; - p = pcap_create_common(ebuf, sizeof (struct pcap_rdmasniff)); + p = PCAP_CREATE_COMMON(ebuf, struct pcap_rdmasniff); if (p) { p->activate_op = rdmasniff_activate; priv = p->priv; @@ -415,7 +435,7 @@ rdmasniff_findalldevs(pcap_if_list_t *devlistp, char *err_str) int ret = 0; dev_list = ibv_get_device_list(&numdev); - if (!dev_list || !numdev) { + if (!dev_list) { return 0; } @@ -426,11 +446,10 @@ rdmasniff_findalldevs(pcap_if_list_t *devlistp, char *err_str) */ if (!add_dev(devlistp, dev_list[i]->name, 0, "RDMA sniffer", err_str)) { ret = -1; - goto out; + break; } } -out: ibv_free_device_list(dev_list); return ret; } diff --git a/external/bsd/libpcap/dist/pcap-savefile.manfile.in b/external/bsd/libpcap/dist/pcap-savefile.manfile.in index 748d7afcfc55..a7ae9afbce48 100644 --- a/external/bsd/libpcap/dist/pcap-savefile.manfile.in +++ b/external/bsd/libpcap/dist/pcap-savefile.manfile.in @@ -17,7 +17,7 @@ .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" -.TH PCAP-SAVEFILE @MAN_FILE_FORMATS@ "8 March 2015" +.TH PCAP-SAVEFILE @MAN_FILE_FORMATS@ "24 April 2020" .SH NAME pcap-savefile \- libpcap savefile format .SH DESCRIPTION @@ -51,6 +51,8 @@ Link-layer header type .TE .RE .PP +The per-file header length is 24 octets. +.PP All fields in the per-file header are in the byte order of the host writing the file. Normally, the first field in the per-file header is a 4-byte magic number, with the value 0xa1b2c3d4. The magic number, when @@ -117,6 +119,8 @@ Un-truncated length of the packet data .TE .RE .PP +The per-packet header length is 16 octets. +.PP All fields in the per-packet header are in the byte order of the host writing the file. The per-packet header begins with a time stamp giving the approximate time the packet was captured; the time stamp consists of @@ -130,4 +134,4 @@ the packet not been truncated by the snapshot length. The two lengths will be equal if the number of bytes of packet data are less than or equal to the snapshot length. .SH SEE ALSO -pcap(3PCAP) +.BR pcap (3PCAP) diff --git a/external/bsd/libpcap/dist/pcap-sita.html b/external/bsd/libpcap/dist/pcap-sita.html index 4a8fe1a27e8a..04f51292f03c 100644 --- a/external/bsd/libpcap/dist/pcap-sita.html +++ b/external/bsd/libpcap/dist/pcap-sita.html @@ -22,7 +22,7 @@

SUMMARY

    Note: This document is part of the libpcap Git and was derived from 'pcap.3' (circa Aug/07).

    - The ACN provides a customized/distributed version of this library that alows SMPs to + The ACN provides a customized/distributed version of this library that allows SMPs to interact with the various IOPs within the site providing a standard mechanism to capture LAN and WAN message traffic.

    @@ -31,7 +31,7 @@

    SUMMARY

    SMP The Supervisory Management Processor where Wireshark (or equivalent) - runs in conjuction with a libpcap front-end. + runs in conjunction with a libpcap front-end. IOP @@ -43,7 +43,7 @@

    SUMMARY

    Each IOP will be capable of supporting multiple connections from an SMP enabling monitoring of more than one interface at a time, each through - its own seperate connection. The IOP is responsible to ensure and report + its own separate connection. The IOP is responsible to ensure and report an error if any attempt is made to monitor the same interface more than once.

    There are three applications that will be supported by the ACN version of libpcap. @@ -52,16 +52,16 @@

    SUMMARY

    - - + + - + - + @@ -121,8 +121,8 @@

    ROUTINES

    @@ -322,7 +322,7 @@

    ROUTINES

    @@ -370,7 +370,7 @@

    ROUTINES

    If the IOP detects that its communication session with an SMP has closed, it will terminate any monitoring in progress, release any resources and close its end of the session. - It will not maintain persistance of any information or prior mode of operation. + It will not maintain persistence of any information or prior mode of operation.
    Application Capture Termination
    wireshark
    Application Capture Termination
    wireshark pcap_dispatch(all packets in one buffer of capture only) pcap_breakloop()
    tshark
    tshark pcap_dispatch(one buffer of capture only) Since a CTRL-C was used to terminate the application, pcap_breakloop() is never called.
    tcpdump
    tcpdump pcap_loop(all packets in the next buffer, and loop forever) pcap_breakloop()
    IOP -> SMP After any required processing is complete, the IOP will return a - null terminated string containing an error message if one occured. - If no error occured, a empty string is still returned. + null terminated string containing an error message if one occurred. + If no error occurred, a empty string is still returned. Errors are:
    • "Interface (xxx) does not exist." @@ -298,7 +298,7 @@

      ROUTINES

    The SMP reads only the next packet from the reverse channel of the connection between the SMP and the IOP that provides the captured data (via calling pcap_dispatch() - with a count of 1) and returns seperate pointers to both the + with a count of 1) and returns separate pointers to both the packet header and packet data by invoking an internal callback.
    IOP -> SMP The IOP returns a null terminated error string if it failed to accept the filter. - If no error occured, then a NULL terminated empty string is returned instead. + If no error occurred, then a NULL terminated empty string is returned instead. Errors are:
    • "Invalid BPF." @@ -362,7 +362,7 @@

      ROUTINES

    SMP -> IOP The SMP closes the file descriptor, and if the descriptor is that of - the comminucation session with an IOP, it too is terminated. + the communication session with an IOP, it too is terminated.
    IOP
    @@ -442,7 +442,7 @@

    SMP/IOP Inter-Process Communication Protocol

    IOP -> SMP The IOP returns a list of sequences of information as defined by the return parameter of this function call (as shown in the following table). - Elements are specified by providing an unsigned byte preceeding the actual data that contains length information. + Elements are specified by providing an unsigned byte preceding the actual data that contains length information.

    @@ -635,7 +635,7 @@

    SMP/IOP Inter-Process Communication Protocol

    BPF program 'n' 8 bytes of each command (repeated 'n' times).
    - Each command consists of that C-style structure which contains: + Each command consists of that C-style structure which contains:

    @@ -719,7 +719,7 @@

    SMP/IOP Inter-Process Communication Protocol

    -
    ps_ifdrop 4The number of packets dropped by the network inteface + The number of packets dropped by the network interface (regardless of whether they would have passed the input filter).
    @@ -771,13 +771,13 @@

    Packet Trace Data Format

    - - - - - - - + + + + + + +
     [Packet Header]  [Packet Data]  [Packet Header]  [Packet Data]  [Packet Header]  [Packet Data] ... [Packet Header]  [Packet Data]  [Packet Header]  [Packet Data]  [Packet Header]  [Packet Data] ...
    @@ -839,7 +839,7 @@

    ACN Custom Packet Header

      PCAP, Wireshark and Tcpdump enhancements have been added to the ACN to support monitoring of its ports, however each of these facilities were focused on capturing - and displaying traffic from LAN interfaces. The SITA extentions to these facilities + and displaying traffic from LAN interfaces. The SITA extensions to these facilities are used to also provide the ability to capture, filter, and display information from an ACN's WAN ports.

      @@ -849,7 +849,7 @@

      ACN Custom Packet Header

      • For Ethernet (like) devices, the packet format is unchanged from the standard Pcap format. -
      • For WAN devices, the packet contains a 5 byte header that preceeds the actual captured data +
      • For WAN devices, the packet contains a 5 byte header that precedes the actual captured data described by the following table:

      diff --git a/external/bsd/libpcap/dist/pcap-tc.c b/external/bsd/libpcap/dist/pcap-tc.c index 65fb0e2b4aa7..1d753b5477ad 100644 --- a/external/bsd/libpcap/dist/pcap-tc.c +++ b/external/bsd/libpcap/dist/pcap-tc.c @@ -126,7 +126,6 @@ static void TcCleanup(pcap_t *p); static int TcInject(pcap_t *p, const void *buf, int size); static int TcRead(pcap_t *p, int cnt, pcap_handler callback, u_char *user); static int TcStats(pcap_t *p, struct pcap_stat *ps); -static int TcSetFilter(pcap_t *p, struct bpf_program *fp); #ifdef _WIN32 static struct pcap_stat *TcStatsEx(pcap_t *p, int *pcap_stat_size); static int TcSetBuff(pcap_t *p, int dim); @@ -253,58 +252,6 @@ typedef struct _PPI_HEADER #pragma pack(pop) #ifdef _WIN32 -// -// This wrapper around loadlibrary appends the system folder (usually c:\windows\system32) -// to the relative path of the DLL, so that the DLL is always loaded from an absolute path -// (It's no longer possible to load airpcap.dll from the application folder). -// This solves the DLL Hijacking issue discovered in August 2010 -// http://blog.metasploit.com/2010/08/exploiting-dll-hijacking-flaws.html -// -HMODULE LoadLibrarySafe(LPCTSTR lpFileName) -{ - TCHAR path[MAX_PATH]; - TCHAR fullFileName[MAX_PATH]; - UINT res; - HMODULE hModule = NULL; - do - { - res = GetSystemDirectory(path, MAX_PATH); - - if (res == 0) - { - // - // some bad failure occurred; - // - break; - } - - if (res > MAX_PATH) - { - // - // the buffer was not big enough - // - SetLastError(ERROR_INSUFFICIENT_BUFFER); - break; - } - - if (res + 1 + _tcslen(lpFileName) + 1 < MAX_PATH) - { - memcpy(fullFileName, path, res * sizeof(TCHAR)); - fullFileName[res] = _T('\\'); - memcpy(&fullFileName[res + 1], lpFileName, (_tcslen(lpFileName) + 1) * sizeof(TCHAR)); - - hModule = LoadLibrary(fullFileName); - } - else - { - SetLastError(ERROR_INSUFFICIENT_BUFFER); - } - - }while(FALSE); - - return hModule; -} - /* * NOTE: this function should be called by the pcap functions that can theoretically * deal with the Tc library for the first time, namely listing the adapters and @@ -341,34 +288,34 @@ TC_API_LOAD_STATUS LoadTcFunctions(void) currentStatus = TC_API_CANNOT_LOAD; - g_TcFunctions.hTcApiDllHandle = LoadLibrarySafe("TcApi.dll"); + g_TcFunctions.hTcApiDllHandle = pcap_load_code("TcApi.dll"); if (g_TcFunctions.hTcApiDllHandle == NULL) break; - g_TcFunctions.QueryPortList = (TcFcnQueryPortList) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcQueryPortList"); - g_TcFunctions.FreePortList = (TcFcnFreePortList) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcFreePortList"); + g_TcFunctions.QueryPortList = (TcFcnQueryPortList) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcQueryPortList"); + g_TcFunctions.FreePortList = (TcFcnFreePortList) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcFreePortList"); - g_TcFunctions.StatusGetString = (TcFcnStatusGetString) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcStatusGetString"); + g_TcFunctions.StatusGetString = (TcFcnStatusGetString) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcStatusGetString"); - g_TcFunctions.PortGetName = (TcFcnPortGetName) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcPortGetName"); - g_TcFunctions.PortGetDescription = (TcFcnPortGetDescription) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcPortGetDescription"); + g_TcFunctions.PortGetName = (TcFcnPortGetName) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcPortGetName"); + g_TcFunctions.PortGetDescription = (TcFcnPortGetDescription) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcPortGetDescription"); - g_TcFunctions.InstanceOpenByName = (TcFcnInstanceOpenByName) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceOpenByName"); - g_TcFunctions.InstanceClose = (TcFcnInstanceClose) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceClose"); - g_TcFunctions.InstanceSetFeature = (TcFcnInstanceSetFeature) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceSetFeature"); - g_TcFunctions.InstanceQueryFeature = (TcFcnInstanceQueryFeature) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceQueryFeature"); - g_TcFunctions.InstanceReceivePackets = (TcFcnInstanceReceivePackets) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceReceivePackets"); - g_TcFunctions.InstanceGetReceiveWaitHandle = (TcFcnInstanceGetReceiveWaitHandle)GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceGetReceiveWaitHandle"); - g_TcFunctions.InstanceTransmitPackets = (TcFcnInstanceTransmitPackets)GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceTransmitPackets"); - g_TcFunctions.InstanceQueryStatistics = (TcFcnInstanceQueryStatistics)GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcInstanceQueryStatistics"); + g_TcFunctions.InstanceOpenByName = (TcFcnInstanceOpenByName) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceOpenByName"); + g_TcFunctions.InstanceClose = (TcFcnInstanceClose) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceClose"); + g_TcFunctions.InstanceSetFeature = (TcFcnInstanceSetFeature) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceSetFeature"); + g_TcFunctions.InstanceQueryFeature = (TcFcnInstanceQueryFeature) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceQueryFeature"); + g_TcFunctions.InstanceReceivePackets = (TcFcnInstanceReceivePackets) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceReceivePackets"); + g_TcFunctions.InstanceGetReceiveWaitHandle = (TcFcnInstanceGetReceiveWaitHandle)pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceGetReceiveWaitHandle"); + g_TcFunctions.InstanceTransmitPackets = (TcFcnInstanceTransmitPackets)pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceTransmitPackets"); + g_TcFunctions.InstanceQueryStatistics = (TcFcnInstanceQueryStatistics)pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcInstanceQueryStatistics"); - g_TcFunctions.PacketsBufferCreate = (TcFcnPacketsBufferCreate) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferCreate"); - g_TcFunctions.PacketsBufferDestroy = (TcFcnPacketsBufferDestroy) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferDestroy"); - g_TcFunctions.PacketsBufferQueryNextPacket = (TcFcnPacketsBufferQueryNextPacket)GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferQueryNextPacket"); - g_TcFunctions.PacketsBufferCommitNextPacket = (TcFcnPacketsBufferCommitNextPacket)GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferCommitNextPacket"); + g_TcFunctions.PacketsBufferCreate = (TcFcnPacketsBufferCreate) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferCreate"); + g_TcFunctions.PacketsBufferDestroy = (TcFcnPacketsBufferDestroy) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferDestroy"); + g_TcFunctions.PacketsBufferQueryNextPacket = (TcFcnPacketsBufferQueryNextPacket)pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferQueryNextPacket"); + g_TcFunctions.PacketsBufferCommitNextPacket = (TcFcnPacketsBufferCommitNextPacket)pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcPacketsBufferCommitNextPacket"); - g_TcFunctions.StatisticsDestroy = (TcFcnStatisticsDestroy) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcStatisticsDestroy"); - g_TcFunctions.StatisticsUpdate = (TcFcnStatisticsUpdate) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcStatisticsUpdate"); - g_TcFunctions.StatisticsQueryValue = (TcFcnStatisticsQueryValue) GetProcAddress(g_TcFunctions.hTcApiDllHandle, "TcStatisticsQueryValue"); + g_TcFunctions.StatisticsDestroy = (TcFcnStatisticsDestroy) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcStatisticsDestroy"); + g_TcFunctions.StatisticsUpdate = (TcFcnStatisticsUpdate) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcStatisticsUpdate"); + g_TcFunctions.StatisticsQueryValue = (TcFcnStatisticsQueryValue) pcap_find_function(g_TcFunctions.hTcApiDllHandle, "TcStatisticsQueryValue"); if ( g_TcFunctions.QueryPortList == NULL || g_TcFunctions.FreePortList == NULL @@ -552,7 +499,7 @@ TcActivate(pcap_t *p) if (pt->PpiPacket == NULL) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error allocating memory"); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error allocating memory"); return PCAP_ERROR; } @@ -587,7 +534,7 @@ TcActivate(pcap_t *p) if (status != TC_SUCCESS) { /* Adapter detected but we are not able to open it. Return failure. */ - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error opening TurboCap adapter: %s", g_TcFunctions.StatusGetString(status)); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error opening TurboCap adapter: %s", g_TcFunctions.StatusGetString(status)); return PCAP_ERROR; } @@ -619,7 +566,7 @@ TcActivate(pcap_t *p) if (status != TC_SUCCESS) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error enabling reception on a TurboCap instance: %s", g_TcFunctions.StatusGetString(status)); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error enabling reception on a TurboCap instance: %s", g_TcFunctions.StatusGetString(status)); goto bad; } @@ -658,12 +605,12 @@ TcActivate(pcap_t *p) if (status != TC_SUCCESS) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error setting the read timeout a TurboCap instance: %s", g_TcFunctions.StatusGetString(status)); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error setting the read timeout a TurboCap instance: %s", g_TcFunctions.StatusGetString(status)); goto bad; } p->read_op = TcRead; - p->setfilter_op = TcSetFilter; + p->setfilter_op = install_bpf_program; p->setdirection_op = NULL; /* Not implemented. */ p->set_datalink_op = TcSetDatalink; p->getnonblock_op = TcGetNonBlock; @@ -756,7 +703,7 @@ TcCreate(const char *device, char *ebuf, int *is_ours) /* OK, it's probably ours. */ *is_ours = 1; - p = pcap_create_common(ebuf, sizeof (struct pcap_tc)); + p = PCAP_CREATE_COMMON(ebuf, struct pcap_tc); if (p == NULL) return NULL; @@ -791,14 +738,14 @@ static int TcSetDatalink(pcap_t *p, int dlt) static int TcGetNonBlock(pcap_t *p) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Non-blocking mode isn't supported for TurboCap ports"); return -1; } static int TcSetNonBlock(pcap_t *p, int nonblock) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Non-blocking mode isn't supported for TurboCap ports"); return -1; } @@ -840,7 +787,7 @@ static int TcInject(pcap_t *p, const void *buf, int size) if (size >= 0xFFFF) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: the TurboCap API does not support packets larger than 64k"); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: the TurboCap API does not support packets larger than 64k"); return -1; } @@ -848,7 +795,7 @@ static int TcInject(pcap_t *p, const void *buf, int size) if (status != TC_SUCCESS) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcPacketsBufferCreate failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcPacketsBufferCreate failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status); return -1; } @@ -868,12 +815,12 @@ static int TcInject(pcap_t *p, const void *buf, int size) if (status != TC_SUCCESS) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcInstanceTransmitPackets failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcInstanceTransmitPackets failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status); } } else { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcPacketsBufferCommitNextPacket failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: TcPacketsBufferCommitNextPacket failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status); } g_TcFunctions.PacketsBufferDestroy(buffer); @@ -913,7 +860,7 @@ static int TcRead(pcap_t *p, int cnt, pcap_handler callback, u_char *user) status = g_TcFunctions.InstanceReceivePackets(pt->TcInstance, &pt->TcPacketsBuffer); if (status != TC_SUCCESS) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error, TcInstanceReceivePackets failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error, TcInstanceReceivePackets failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status); return -1; } } @@ -963,14 +910,14 @@ static int TcRead(pcap_t *p, int cnt, pcap_handler callback, u_char *user) if (status != TC_SUCCESS) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error, TcPacketsBufferQueryNextPacket failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error, TcPacketsBufferQueryNextPacket failure: %s (%08x)", g_TcFunctions.StatusGetString(status), status); return -1; } - /* No underlaying filtering system. We need to filter on our own */ + /* No underlying filtering system. We need to filter on our own */ if (p->fcode.bf_insns) { - filterResult = bpf_filter(p->fcode.bf_insns, data, tcHeader.Length, tcHeader.CapturedLength); + filterResult = pcap_filter(p->fcode.bf_insns, data, tcHeader.Length, tcHeader.CapturedLength); if (filterResult == 0) { @@ -1053,7 +1000,7 @@ TcStats(pcap_t *p, struct pcap_stat *ps) if (status != TC_SUCCESS) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcInstanceQueryStatistics: %s (%08x)", g_TcFunctions.StatusGetString(status), status); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcInstanceQueryStatistics: %s (%08x)", g_TcFunctions.StatusGetString(status), status); return -1; } @@ -1062,7 +1009,7 @@ TcStats(pcap_t *p, struct pcap_stat *ps) status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_TOTAL_RX_PACKETS, &counter); if (status != TC_SUCCESS) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status); return -1; } if (counter <= (ULONGLONG)0xFFFFFFFF) @@ -1077,7 +1024,7 @@ TcStats(pcap_t *p, struct pcap_stat *ps) status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_RX_DROPPED_PACKETS, &counter); if (status != TC_SUCCESS) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status); return -1; } if (counter <= (ULONGLONG)0xFFFFFFFF) @@ -1100,27 +1047,6 @@ TcStats(pcap_t *p, struct pcap_stat *ps) } -/* - * We filter at user level, since the kernel driver does't process the packets - */ -static int -TcSetFilter(pcap_t *p, struct bpf_program *fp) -{ - if(!fp) - { - strncpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf)); - return -1; - } - - /* Install a user level filter */ - if (install_bpf_program(p, fp) < 0) - { - return -1; - } - - return 0; -} - #ifdef _WIN32 static struct pcap_stat * TcStatsEx(pcap_t *p, int *pcap_stat_size) @@ -1136,7 +1062,7 @@ TcStatsEx(pcap_t *p, int *pcap_stat_size) if (status != TC_SUCCESS) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcInstanceQueryStatistics: %s (%08x)", g_TcFunctions.StatusGetString(status), status); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcInstanceQueryStatistics: %s (%08x)", g_TcFunctions.StatusGetString(status), status); return NULL; } @@ -1145,7 +1071,7 @@ TcStatsEx(pcap_t *p, int *pcap_stat_size) status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_TOTAL_RX_PACKETS, &counter); if (status != TC_SUCCESS) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status); return NULL; } if (counter <= (ULONGLONG)0xFFFFFFFF) @@ -1160,7 +1086,7 @@ TcStatsEx(pcap_t *p, int *pcap_stat_size) status = g_TcFunctions.StatisticsQueryValue(statistics, TC_COUNTER_INSTANCE_RX_DROPPED_PACKETS, &counter); if (status != TC_SUCCESS) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error in TcStatisticsQueryValue: %s (%08x)", g_TcFunctions.StatusGetString(status), status); return NULL; } if (counter <= (ULONGLONG)0xFFFFFFFF) @@ -1198,7 +1124,7 @@ TcSetMode(pcap_t *p, int mode) { if (mode != MODE_CAPT) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Mode %u not supported by TurboCap devices. TurboCap only supports capture.", mode); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Mode %d not supported by TurboCap devices. TurboCap only supports capture.", mode); return -1; } @@ -1213,7 +1139,7 @@ TcSetMinToCopy(pcap_t *p, int size) if (size < 0) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Mintocopy cannot be less than 0."); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Mintocopy cannot be less than 0."); return -1; } @@ -1221,7 +1147,7 @@ TcSetMinToCopy(pcap_t *p, int size) if (status != TC_SUCCESS) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error setting the mintocopy: %s (%08x)", g_TcFunctions.StatusGetString(status), status); + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "TurboCap error setting the mintocopy: %s (%08x)", g_TcFunctions.StatusGetString(status), status); } return 0; @@ -1238,7 +1164,7 @@ TcGetReceiveWaitHandle(pcap_t *p) static int TcOidGetRequest(pcap_t *p, bpf_u_int32 oid _U_, void *data _U_, size_t *lenp _U_) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "An OID get request cannot be performed on a TurboCap device"); return PCAP_ERROR; } @@ -1247,7 +1173,7 @@ static int TcOidSetRequest(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_, size_t *lenp _U_) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "An OID set request cannot be performed on a TurboCap device"); return PCAP_ERROR; } @@ -1255,7 +1181,7 @@ TcOidSetRequest(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_, static u_int TcSendqueueTransmit(pcap_t *p, pcap_send_queue *queue _U_, int sync _U_) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Packets cannot be bulk transmitted on a TurboCap device"); return 0; } @@ -1263,7 +1189,7 @@ TcSendqueueTransmit(pcap_t *p, pcap_send_queue *queue _U_, int sync _U_) static int TcSetUserBuffer(pcap_t *p, int size _U_) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "The user buffer cannot be set on a TurboCap device"); return -1; } @@ -1271,7 +1197,7 @@ TcSetUserBuffer(pcap_t *p, int size _U_) static int TcLiveDump(pcap_t *p, char *filename _U_, int maxsize _U_, int maxpacks _U_) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Live packet dumping cannot be performed on a TurboCap device"); return -1; } @@ -1279,7 +1205,7 @@ TcLiveDump(pcap_t *p, char *filename _U_, int maxsize _U_, int maxpacks _U_) static int TcLiveDumpEnded(pcap_t *p, int sync _U_) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Live packet dumping cannot be performed on a TurboCap device"); return -1; } diff --git a/external/bsd/libpcap/dist/pcap-tstamp.manmisc.in b/external/bsd/libpcap/dist/pcap-tstamp.manmisc.in index 6437e80e64e7..eea8c1d29ee3 100644 --- a/external/bsd/libpcap/dist/pcap-tstamp.manmisc.in +++ b/external/bsd/libpcap/dist/pcap-tstamp.manmisc.in @@ -19,7 +19,7 @@ .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" -.TH PCAP-TSTAMP @MAN_MISC_INFO@ "8 March 2015" +.TH PCAP-TSTAMP @MAN_MISC_INFO@ "14 July 2020" .SH NAME pcap-tstamp \- packet time stamps in libpcap .SH DESCRIPTION @@ -58,7 +58,20 @@ single adjustment; different CPU cores on a multi-core or multi-processor system might be running at different speeds, or might not have time counters all synchronized, so packets time-stamped by different cores might not have -consistent time stamps. +consistent time stamps; +.IP +some time sources, such as those that supply POSIX "seconds since the +Epoch" time, do not count leap seconds, meaning that the seconds +portion +.RB ( tv_sec ) +of the time stamp might not be incremented for a leap second, so that +the fraction-of-a-second part of the time stamp might roll over past +zero but the second part would not change, or the clock might run +slightly more slowly for a period before the leap second. +.LP +For these reasons, time differences between packet time stamps will not +necessarily accurately reflect the time differences between the receipt +or transmission times of the packets. .LP In addition, packets time-stamped by different cores might be time-stamped in one order and added to the queue of packets for libpcap @@ -73,6 +86,9 @@ the host operating system. Those time stamps might not, however, be synchronized with the host operating system's clock, so that, for example, the time stamp of a packet might not correspond to the time stamp of an event on the host triggered by the arrival of that packet. +If they are synchronized with the host operating system's clock, some of +the issues listed above with time stamps supplied by the host operating +system may also apply to time stamps supplied by the capture device. .LP Depending on the capture device and the software on the host, libpcap might allow different types of time stamp to be used. The @@ -87,15 +103,15 @@ The list might be empty, in which case no choice of time stamp type is offered for that capture device. If the list is not empty, the .BR pcap_set_tstamp_type (3PCAP) routine can be used after a -.B pcap_create() +.BR pcap_create () call and before a -.B pcap_activate() +.BR pcap_activate () call to specify the type of time stamp to be used on the device. The time stamp types are listed here; the first value is the #define to use in code, the second value is the value returned by -.B pcap_tstamp_type_val_to_name(3PCAP) +.BR pcap_tstamp_type_val_to_name (3PCAP) and accepted by -.BR pcap_tstamp_type_name_to_val(3PCAP) . +.BR pcap_tstamp_type_name_to_val (3PCAP) . .RS 5 .TP 5 .BR PCAP_TSTAMP_HOST " - " host @@ -110,9 +126,14 @@ system's clock. .TP 5 .BR PCAP_TSTAMP_HOST_HIPREC " - " host_hiprec Time stamp provided by the host on which the capture is being done. -This is a high-precision time stamp; it might or might not be -synchronized with the host operating system's clock. It might be more -expensive to fetch than +This is a high-precision time stamp, synchronized with the host +operating system's clock. It might be more expensive to fetch than +.BR PCAP_TSTAMP_HOST_LOWPREC . +.TP 5 +.BR PCAP_TSTAMP_HOST_HIPREC_UNSYNCED " - " host_hiprec_unsynced +Time stamp provided by the host on which the capture is being done. +This is a high-precision time stamp, not synchronized with the host +operating system's clock. It might be more expensive to fetch than .BR PCAP_TSTAMP_HOST_LOWPREC . .TP 5 .BR PCAP_TSTAMP_ADAPTER " - " adapter @@ -126,6 +147,18 @@ done. This is a high-precision time stamp; it is not synchronized with the host operating system's clock. .RE .LP +Time stamps synchronized with the system clock can go backwards, as the +system clock can go backwards. If a clock is not in sync with the +system clock, that could be because the system clock isn't keeping +accurate time, because the other clock isn't keeping accurate time, or +both. +.LP +Host-provided time stamps generally correspond to the time when the +time-stamping code sees the packet; this could be some unknown amount of +time after the first or last bit of the packet is received by the +network adapter, due to batching of interrupts for packet arrival, +queueing delays, etc.. +.LP By default, when performing a live capture or reading from a savefile, time stamps are supplied as seconds since January 1, 1970, 00:00:00 UTC, and microseconds since that seconds value, even if higher-resolution @@ -137,15 +170,15 @@ discarded. The .BR pcap_set_tstamp_precision (3PCAP) routine can be used after a -.B pcap_create() +.BR pcap_create () call and after a -.B pcap_activate() +.BR pcap_activate () call to specify the resolution of the time stamps to get for the device. If the hardware or software cannot supply a higher-resolution time stamp, the -.B pcap_set_tstamp_precision() +.BR pcap_set_tstamp_precision () call will fail, and the time stamps supplied after the -.B pcap_activate() +.BR pcap_activate () call will have microsecond resolution. .LP When opening a savefile, the @@ -165,4 +198,4 @@ the time stamp supplied by the hardware or operating system and, when reading a savefile, this does not indicate the actual precision of time stamps in the file. .SH SEE ALSO -pcap(3PCAP) +.BR pcap (3PCAP) diff --git a/external/bsd/libpcap/dist/pcap-types.h b/external/bsd/libpcap/dist/pcap-types.h index 9614f9f1de51..7d0fe81ff71a 100644 --- a/external/bsd/libpcap/dist/pcap-types.h +++ b/external/bsd/libpcap/dist/pcap-types.h @@ -35,7 +35,6 @@ * Get u_int defined, by hook or by crook. */ #ifdef _WIN32 - /* * This defines u_int. */ diff --git a/external/bsd/libpcap/dist/pcap-usb-linux-common.c b/external/bsd/libpcap/dist/pcap-usb-linux-common.c new file mode 100644 index 000000000000..fb4a8c19be75 --- /dev/null +++ b/external/bsd/libpcap/dist/pcap-usb-linux-common.c @@ -0,0 +1,130 @@ +/* + * 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-usb-linux-common.c - common code for everything that needs to + * deal with Linux USB captures. + */ + +#include "pcap/pcap.h" +#include "pcap/usb.h" + +#include "pcap-usb-linux-common.h" + +/* + * Compute, from the data provided by the Linux USB memory-mapped capture + * mechanism, the amount of packet data that would have been provided + * had the capture mechanism not chopped off any data at the end, if, in + * fact, it did so. + * + * Set the "unsliced length" field of the packet header to that value. + */ +void +fix_linux_usb_mmapped_length(struct pcap_pkthdr *pkth, const u_char *bp) +{ + const pcap_usb_header_mmapped *hdr; + u_int bytes_left; + + /* + * All callers of this routine must ensure that pkth->caplen is + * >= sizeof (pcap_usb_header_mmapped). + */ + bytes_left = pkth->caplen; + bytes_left -= sizeof (pcap_usb_header_mmapped); + + hdr = (const pcap_usb_header_mmapped *) bp; + if (!hdr->data_flag && hdr->transfer_type == URB_ISOCHRONOUS && + hdr->event_type == URB_COMPLETE && + (hdr->endpoint_number & URB_TRANSFER_IN) && + pkth->len == sizeof(pcap_usb_header_mmapped) + + (hdr->ndesc * sizeof (usb_isodesc)) + hdr->urb_len) { + usb_isodesc *descs; + u_int pre_truncation_data_len, pre_truncation_len; + + descs = (usb_isodesc *) (bp + sizeof(pcap_usb_header_mmapped)); + + /* + * We have data (yes, data_flag is 0 if we *do* have data), + * and this is a "this is complete" incoming isochronous + * transfer event, and the length was calculated based + * on the URB length. + * + * That's not correct, because the data isn't contiguous, + * and the isochronous descriptos show how it's scattered. + * + * Find the end of the last chunk of data in the buffer + * referred to by the isochronous descriptors; that indicates + * how far into the buffer the data would have gone. + * + * Make sure we don't run past the end of the captured data + * while processing the isochronous descriptors. + */ + pre_truncation_data_len = 0; + for (uint32_t desc = 0; + desc < hdr->ndesc && bytes_left >= sizeof (usb_isodesc); + desc++, bytes_left -= sizeof (usb_isodesc)) { + u_int desc_end; + + if (descs[desc].len != 0) { + desc_end = descs[desc].offset + descs[desc].len; + if (desc_end > pre_truncation_data_len) + pre_truncation_data_len = desc_end; + } + } + + /* + * Now calculate the total length based on that data + * length. + */ + pre_truncation_len = sizeof(pcap_usb_header_mmapped) + + (hdr->ndesc * sizeof (usb_isodesc)) + + pre_truncation_data_len; + + /* + * If that's greater than or equal to the captured length, + * use that as the length. + */ + if (pre_truncation_len >= pkth->caplen) + pkth->len = pre_truncation_len; + + /* + * If the captured length is greater than the length, + * use the captured length. + * + * For completion events for incoming isochronous transfers, + * it's based on data_len, which is calculated the same way + * we calculated pre_truncation_data_len above, except that + * it has access to all the isochronous descriptors, not + * just the ones that the kernel were able to provide us or, + * for a capture file, that weren't sliced off by a snapshot + * length. + * + * However, it might have been reduced by the USB capture + * mechanism arbitrarily limiting the amount of data it + * provides to userland, or by the libpcap capture code + * limiting it to being no more than the snapshot, so + * we don't want to just use it all the time; we only + * do so to try to get a better estimate of the actual + * length - and to make sure the on-the-network length + * is always >= the captured length. + */ + if (pkth->caplen > pkth->len) + pkth->len = pkth->caplen; + } +} diff --git a/external/bsd/libpcap/dist/pcap-usb-linux-common.h b/external/bsd/libpcap/dist/pcap-usb-linux-common.h new file mode 100644 index 000000000000..8cff7ba1cf6b --- /dev/null +++ b/external/bsd/libpcap/dist/pcap-usb-linux-common.h @@ -0,0 +1,26 @@ +/* + * 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-usb-linux-common.h - common code for everything that needs to + * deal with Linux USB captures. + */ + +extern void fix_linux_usb_mmapped_length(struct pcap_pkthdr *pkth, + const u_char *bp); diff --git a/external/bsd/libpcap/dist/pcap-util.c b/external/bsd/libpcap/dist/pcap-util.c new file mode 100644 index 000000000000..8b5669e90b9a --- /dev/null +++ b/external/bsd/libpcap/dist/pcap-util.c @@ -0,0 +1,474 @@ +/* + * 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.c - common code for pcap and pcapng files + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "pcap-int.h" +#include "extract.h" +#include "pcap-usb-linux-common.h" + +#include "pcap-util.h" + +#include "pflog.h" +#include "pcap/can_socketcan.h" +#include "pcap/sll.h" +#include "pcap/usb.h" +#include "pcap/nflog.h" + +/* + * Most versions of the DLT_PFLOG pseudo-header have UID and PID fields + * that are saved in host byte order. + * + * When reading a DLT_PFLOG packet, we need to convert those fields from + * the byte order of the host that wrote the file to this host's byte + * order. + */ +static void +swap_pflog_header(const struct pcap_pkthdr *hdr, u_char *buf) +{ + u_int caplen = hdr->caplen; + u_int length = hdr->len; + u_int pfloghdr_length; + struct pfloghdr *pflhdr = (struct pfloghdr *)buf; + + if (caplen < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid) || + length < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid)) { + /* Not enough data to have the uid field */ + return; + } + + pfloghdr_length = pflhdr->length; + + if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, uid) + sizeof pflhdr->uid)) { + /* Header doesn't include uid field */ + return; + } + pflhdr->uid = SWAPLONG(pflhdr->uid); + + if (caplen < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid) || + length < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid)) { + /* Not enough data to have the pid field */ + return; + } + if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, pid) + sizeof pflhdr->pid)) { + /* Header doesn't include pid field */ + return; + } + pflhdr->pid = SWAPLONG(pflhdr->pid); + + if (caplen < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid) || + length < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid)) { + /* Not enough data to have the rule_uid field */ + return; + } + if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, rule_uid) + sizeof pflhdr->rule_uid)) { + /* Header doesn't include rule_uid field */ + return; + } + pflhdr->rule_uid = SWAPLONG(pflhdr->rule_uid); + + if (caplen < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid) || + length < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid)) { + /* Not enough data to have the rule_pid field */ + return; + } + if (pfloghdr_length < (u_int) (offsetof(struct pfloghdr, rule_pid) + sizeof pflhdr->rule_pid)) { + /* Header doesn't include rule_pid field */ + return; + } + pflhdr->rule_pid = SWAPLONG(pflhdr->rule_pid); +} + +/* + * DLT_LINUX_SLL packets with a protocol type of LINUX_SLL_P_CAN or + * LINUX_SLL_P_CANFD have SocketCAN headers in front of the payload, + * with the CAN ID being in host byte order. + * + * When reading a DLT_LINUX_SLL packet, we need to check for those + * packets and convert the CAN ID from the byte order of the host that + * wrote the file to this host's byte order. + */ +static void +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; + uint16_t protocol; + pcap_can_socketcan_hdr *chdr; + + if (caplen < (u_int) sizeof(struct sll_header) || + length < (u_int) sizeof(struct sll_header)) { + /* Not enough data to have the protocol field */ + return; + } + + protocol = EXTRACT_BE_U_2(&shdr->sll_protocol); + if (protocol != LINUX_SLL_P_CAN && protocol != LINUX_SLL_P_CANFD) + return; + + /* + * SocketCAN packet; fix up the packet's header. + */ + chdr = (pcap_can_socketcan_hdr *)(buf + sizeof(struct sll_header)); + if (caplen < (u_int) sizeof(struct sll_header) + sizeof(chdr->can_id) || + length < (u_int) sizeof(struct sll_header) + sizeof(chdr->can_id)) { + /* Not enough data to have the CAN ID */ + return; + } + chdr->can_id = SWAPLONG(chdr->can_id); +} + +/* + * The same applies for DLT_LINUX_SLL2. + */ +static void +swap_linux_sll2_header(const struct pcap_pkthdr *hdr, u_char *buf) +{ + u_int caplen = hdr->caplen; + u_int length = hdr->len; + struct sll2_header *shdr = (struct sll2_header *)buf; + uint16_t protocol; + pcap_can_socketcan_hdr *chdr; + + if (caplen < (u_int) sizeof(struct sll2_header) || + length < (u_int) sizeof(struct sll2_header)) { + /* Not enough data to have the protocol field */ + return; + } + + protocol = EXTRACT_BE_U_2(&shdr->sll2_protocol); + if (protocol != LINUX_SLL_P_CAN && protocol != LINUX_SLL_P_CANFD) + return; + + /* + * SocketCAN packet; fix up the packet's header. + */ + chdr = (pcap_can_socketcan_hdr *)(buf + sizeof(struct sll2_header)); + if (caplen < (u_int) sizeof(struct sll2_header) + sizeof(chdr->can_id) || + length < (u_int) sizeof(struct sll2_header) + sizeof(chdr->can_id)) { + /* Not enough data to have the CAN ID */ + return; + } + chdr->can_id = SWAPLONG(chdr->can_id); +} + +/* + * The DLT_USB_LINUX and DLT_USB_LINUX_MMAPPED headers are in host + * byte order when capturing (it's supplied directly from a + * memory-mapped buffer shared by the kernel). + * + * When reading a DLT_USB_LINUX or DLT_USB_LINUX_MMAPPED packet, we + * need to convert it from the byte order of the host that wrote the + * file to this host's byte order. + */ +static void +swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf, + int header_len_64_bytes) +{ + pcap_usb_header_mmapped *uhdr = (pcap_usb_header_mmapped *)buf; + bpf_u_int32 offset = 0; + + /* + * "offset" is the offset *past* the field we're swapping; + * we skip the field *before* checking to make sure + * the captured data length includes the entire field. + */ + + /* + * The URB id is a totally opaque value; do we really need to + * convert it to the reading host's byte order??? + */ + offset += 8; /* skip past id */ + if (hdr->caplen < offset) + return; + uhdr->id = SWAPLL(uhdr->id); + + offset += 4; /* skip past various 1-byte fields */ + + offset += 2; /* skip past bus_id */ + if (hdr->caplen < offset) + return; + uhdr->bus_id = SWAPSHORT(uhdr->bus_id); + + offset += 2; /* skip past various 1-byte fields */ + + offset += 8; /* skip past ts_sec */ + if (hdr->caplen < offset) + return; + uhdr->ts_sec = SWAPLL(uhdr->ts_sec); + + offset += 4; /* skip past ts_usec */ + if (hdr->caplen < offset) + return; + uhdr->ts_usec = SWAPLONG(uhdr->ts_usec); + + offset += 4; /* skip past status */ + if (hdr->caplen < offset) + return; + uhdr->status = SWAPLONG(uhdr->status); + + offset += 4; /* skip past urb_len */ + if (hdr->caplen < offset) + return; + uhdr->urb_len = SWAPLONG(uhdr->urb_len); + + offset += 4; /* skip past data_len */ + if (hdr->caplen < offset) + return; + uhdr->data_len = SWAPLONG(uhdr->data_len); + + if (uhdr->transfer_type == URB_ISOCHRONOUS) { + offset += 4; /* skip past s.iso.error_count */ + if (hdr->caplen < offset) + return; + uhdr->s.iso.error_count = SWAPLONG(uhdr->s.iso.error_count); + + offset += 4; /* skip past s.iso.numdesc */ + if (hdr->caplen < offset) + return; + uhdr->s.iso.numdesc = SWAPLONG(uhdr->s.iso.numdesc); + } else + offset += 8; /* skip USB setup header */ + + /* + * With the old header, there are no isochronous descriptors + * after the header. + * + * With the new header, the actual number of descriptors in + * the header is not s.iso.numdesc, it's ndesc - only the + * first N descriptors, for some value of N, are put into + * the header, and ndesc is set to the actual number copied. + * In addition, if s.iso.numdesc is negative, no descriptors + * are captured, and ndesc is set to 0. + */ + if (header_len_64_bytes) { + /* + * This is either the "version 1" header, with + * 16 bytes of additional fields at the end, or + * a "version 0" header from a memory-mapped + * capture, with 16 bytes of zeroed-out padding + * at the end. Byte swap them as if this were + * a "version 1" header. + */ + offset += 4; /* skip past interval */ + if (hdr->caplen < offset) + return; + uhdr->interval = SWAPLONG(uhdr->interval); + + offset += 4; /* skip past start_frame */ + if (hdr->caplen < offset) + return; + uhdr->start_frame = SWAPLONG(uhdr->start_frame); + + offset += 4; /* skip past xfer_flags */ + if (hdr->caplen < offset) + return; + uhdr->xfer_flags = SWAPLONG(uhdr->xfer_flags); + + offset += 4; /* skip past ndesc */ + if (hdr->caplen < offset) + return; + uhdr->ndesc = SWAPLONG(uhdr->ndesc); + + if (uhdr->transfer_type == URB_ISOCHRONOUS) { + /* swap the values in struct linux_usb_isodesc */ + usb_isodesc *pisodesc; + uint32_t i; + + pisodesc = (usb_isodesc *)(void *)(buf+offset); + for (i = 0; i < uhdr->ndesc; i++) { + offset += 4; /* skip past status */ + if (hdr->caplen < offset) + return; + pisodesc->status = SWAPLONG(pisodesc->status); + + offset += 4; /* skip past offset */ + if (hdr->caplen < offset) + return; + pisodesc->offset = SWAPLONG(pisodesc->offset); + + offset += 4; /* skip past len */ + if (hdr->caplen < offset) + return; + pisodesc->len = SWAPLONG(pisodesc->len); + + offset += 4; /* skip past padding */ + + pisodesc++; + } + } + } +} + +/* + * The DLT_NFLOG "packets" have a mixture of big-endian and host-byte-order + * data. They begin with a fixed-length header with big-endian fields, + * followed by a set of TLVs, where the type and length are in host + * byte order but the values are either big-endian or are a raw byte + * sequence that's the same regardless of the host's byte order. + * + * When reading a DLT_NFLOG packet, we need to convert the type and + * length values from the byte order of the host that wrote the file + * to the byte order of this host. + */ +static void +swap_nflog_header(const struct pcap_pkthdr *hdr, u_char *buf) +{ + u_char *p = buf; + nflog_hdr_t *nfhdr = (nflog_hdr_t *)buf; + nflog_tlv_t *tlv; + u_int caplen = hdr->caplen; + u_int length = hdr->len; + uint16_t size; + + if (caplen < (u_int) sizeof(nflog_hdr_t) || + length < (u_int) sizeof(nflog_hdr_t)) { + /* Not enough data to have any TLVs. */ + return; + } + + if (nfhdr->nflog_version != 0) { + /* Unknown NFLOG version */ + return; + } + + length -= sizeof(nflog_hdr_t); + caplen -= sizeof(nflog_hdr_t); + p += sizeof(nflog_hdr_t); + + while (caplen >= sizeof(nflog_tlv_t)) { + tlv = (nflog_tlv_t *) p; + + /* Swap the type and length. */ + tlv->tlv_type = SWAPSHORT(tlv->tlv_type); + tlv->tlv_length = SWAPSHORT(tlv->tlv_length); + + /* Get the length of the TLV. */ + size = tlv->tlv_length; + if (size % 4 != 0) + size += 4 - size % 4; + + /* Is the TLV's length less than the minimum? */ + if (size < sizeof(nflog_tlv_t)) { + /* Yes. Give up now. */ + return; + } + + /* Do we have enough data for the full TLV? */ + if (caplen < size || length < size) { + /* No. */ + return; + } + + /* Skip over the TLV. */ + length -= size; + caplen -= size; + p += size; + } +} + +static void +swap_pseudo_headers(int linktype, struct pcap_pkthdr *hdr, u_char *data) +{ + /* + * Convert pseudo-headers from the byte order of + * the host on which the file was saved to our + * byte order, as necessary. + */ + switch (linktype) { + + case DLT_PFLOG: + swap_pflog_header(hdr, data); + break; + + case DLT_LINUX_SLL: + swap_linux_sll_header(hdr, data); + break; + + case DLT_LINUX_SLL2: + swap_linux_sll2_header(hdr, data); + break; + + case DLT_USB_LINUX: + swap_linux_usb_header(hdr, data, 0); + break; + + case DLT_USB_LINUX_MMAPPED: + swap_linux_usb_header(hdr, data, 1); + break; + + case DLT_NFLOG: + swap_nflog_header(hdr, data); + break; + } +} + +void +pcap_post_process(int linktype, int swapped, struct pcap_pkthdr *hdr, + u_char *data) +{ + if (swapped) + swap_pseudo_headers(linktype, hdr, data); + + fixup_pcap_pkthdr(linktype, hdr, data); +} + +void +fixup_pcap_pkthdr(int linktype, struct pcap_pkthdr *hdr, const u_char *data) +{ + const pcap_usb_header_mmapped *usb_hdr; + + usb_hdr = (const pcap_usb_header_mmapped *) data; + if (linktype == DLT_USB_LINUX_MMAPPED && + hdr->caplen >= sizeof (pcap_usb_header_mmapped)) { + /* + * In older versions of libpcap, in memory-mapped captures, + * the "on-the-bus length" for completion events for + * incoming isochronous transfers was miscalculated; it + * needed to be calculated based on the* offsets and lengths + * in the descriptors, not on the raw URB length, but it + * wasn't. + * + * If this packet contains transferred data (yes, data_flag + * is 0 if we *do* have data), and the total on-the-network + * length is equal to the value calculated from the raw URB + * length, then it might be one of those transfers. + * + * We only do this if we have the full USB pseudo-header. + */ + if (!usb_hdr->data_flag && + hdr->len == sizeof(pcap_usb_header_mmapped) + + (usb_hdr->ndesc * sizeof (usb_isodesc)) + usb_hdr->urb_len) { + /* + * It might need fixing; fix it if it's a completion + * event for an incoming isochronous transfer. + */ + fix_linux_usb_mmapped_length(hdr, data); + } + } +} diff --git a/external/bsd/libpcap/dist/pcap-util.h b/external/bsd/libpcap/dist/pcap-util.h new file mode 100644 index 000000000000..de958191cbef --- /dev/null +++ b/external/bsd/libpcap/dist/pcap-util.h @@ -0,0 +1,55 @@ +/* + * 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-util.h - common code for various files + */ + +/* + * We use the "receiver-makes-right" approach to byte order; + * because time is at a premium when we are writing the file. + * In other words, the pcap_file_header and pcap_pkthdr, + * records are written in host byte order. + * Note that the bytes of packet data are written out in the order in + * which they were received, so multi-byte fields in packets are not + * written in host byte order, they're written in whatever order the + * sending machine put them in. + * + * We also use this for fixing up packet data headers from a remote + * capture, where the server may have a different byte order from the + * client. + * + * ntoh[ls] aren't sufficient because we might need to swap on a big-endian + * machine (if the file was written in little-end order). + */ +#define SWAPLONG(y) \ + (((((u_int)(y))&0xff)<<24) | \ + ((((u_int)(y))&0xff00)<<8) | \ + ((((u_int)(y))&0xff0000)>>8) | \ + ((((u_int)(y))>>24)&0xff)) +#define SWAPSHORT(y) \ + ((u_short)(((((u_int)(y))&0xff)<<8) | \ + ((((u_int)(y))&0xff00)>>8))) + +extern void pcap_post_process(int linktype, int swapped, + struct pcap_pkthdr *hdr, u_char *data); + +extern void fixup_pcap_pkthdr(int linktype, struct pcap_pkthdr *hdr, + const u_char *data); + diff --git a/external/bsd/libpcap/dist/pcap/can_socketcan.h b/external/bsd/libpcap/dist/pcap/can_socketcan.h index 332d9ff5d5a9..0cb3584a8497 100644 --- a/external/bsd/libpcap/dist/pcap/can_socketcan.h +++ b/external/bsd/libpcap/dist/pcap/can_socketcan.h @@ -48,9 +48,14 @@ typedef struct { uint32_t can_id; uint8_t payload_length; - uint8_t pad; + uint8_t fd_flags; uint8_t reserved1; uint8_t reserved2; } pcap_can_socketcan_hdr; +/* Bits in the fd_flags field */ +#define CANFD_BRS 0x01 /* bit rate switch (second bitrate for payload data) */ +#define CANFD_ESI 0x02 /* error state indicator of the transmitting node */ +#define CANFD_FDF 0x04 /* mark CAN FD for dual use of CAN format */ + #endif diff --git a/external/bsd/libpcap/dist/pcap/compiler-tests.h b/external/bsd/libpcap/dist/pcap/compiler-tests.h index ea5962c7bf5e..2d98a7070511 100644 --- a/external/bsd/libpcap/dist/pcap/compiler-tests.h +++ b/external/bsd/libpcap/dist/pcap/compiler-tests.h @@ -38,7 +38,7 @@ /* * This was introduced by Clang: * - * http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute + * https://clang.llvm.org/docs/LanguageExtensions.html#has-attribute * * in some version (which version?); it has been picked up by GCC 5.0. */ @@ -80,9 +80,11 @@ */ #if ! defined(__GNUC__) -#define PCAP_IS_AT_LEAST_GNUC_VERSION(major, minor) 0 + /* Not GCC and not "just like GCC" */ + #define PCAP_IS_AT_LEAST_GNUC_VERSION(major, minor) 0 #else -#define PCAP_IS_AT_LEAST_GNUC_VERSION(major, minor) \ + /* GCC or "just like GCC" */ + #define PCAP_IS_AT_LEAST_GNUC_VERSION(major, minor) \ (__GNUC__ > (major) || \ (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) #endif @@ -92,9 +94,11 @@ */ #if !defined(__clang__) -#define PCAP_IS_AT_LEAST_CLANG_VERSION(major, minor) 0 + /* Not Clang */ + #define PCAP_IS_AT_LEAST_CLANG_VERSION(major, minor) 0 #else -#define PCAP_IS_AT_LEAST_CLANG_VERSION(major, minor) \ + /* Clang */ + #define PCAP_IS_AT_LEAST_CLANG_VERSION(major, minor) \ (__clang_major__ > (major) || \ (__clang_major__ == (major) && __clang_minor__ >= (minor))) #endif @@ -118,13 +122,15 @@ */ #if ! defined(__SUNPRO_C) -#define PCAP_IS_AT_LEAST_SUNC_VERSION(major,minor) 0 + /* Not Sun/Oracle C */ + #define PCAP_IS_AT_LEAST_SUNC_VERSION(major,minor) 0 #else -#define PCAP_SUNPRO_VERSION_TO_BCD(major, minor) \ + /* Sun/Oracle C */ + #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) \ + #define PCAP_IS_AT_LEAST_SUNC_VERSION(major,minor) \ (__SUNPRO_C >= PCAP_SUNPRO_VERSION_TO_BCD((major), (minor))) #endif @@ -133,13 +139,31 @@ * * The version number in __xlC__ has the major version in the * upper 8 bits and the minor version in the lower 8 bits. + * On AIX __xlC__ is always defined, __ibmxl__ becomes defined in XL C 16.1. + * On Linux since XL C 13.1.6 __xlC__ is not defined by default anymore, but + * __ibmxl__ is defined since at least XL C 13.1.1. */ -#if ! defined(__xlC__) -#define PCAP_IS_AT_LEAST_XL_C_VERSION(major,minor) 0 +#if ! defined(__xlC__) && ! defined(__ibmxl__) + /* Not XL C */ + #define PCAP_IS_AT_LEAST_XL_C_VERSION(major,minor) 0 #else -#define PCAP_IS_AT_LEAST_XL_C_VERSION(major, minor) \ + /* XL C */ + #if defined(__ibmxl__) + /* + * Later Linux version of XL C; use __ibmxl_version__ to test + * the version. + */ + #define PCAP_IS_AT_LEAST_XL_C_VERSION(major, minor) \ + (__ibmxl_version__ > (major) || \ + (__ibmxl_version__ == (major) && __ibmxl_release__ >= (minor))) + #else /* __ibmxl__ */ + /* + * __ibmxl__ not defined; use __xlC__ to test the version. + */ + #define PCAP_IS_AT_LEAST_XL_C_VERSION(major, minor) \ (__xlC__ >= (((major) << 8) | (minor))) + #endif /* __ibmxl__ */ #endif /* @@ -154,9 +178,11 @@ */ #if ! defined(__HP_aCC) -#define PCAP_IS_AT_LEAST_HP_C_VERSION(major,minor) 0 + /* Not HP C */ + #define PCAP_IS_AT_LEAST_HP_C_VERSION(major,minor) 0 #else -#define PCAP_IS_AT_LEAST_HP_C_VERSION(major,minor) \ + /* HP C */ + #define PCAP_IS_AT_LEAST_HP_C_VERSION(major,minor) \ (__HP_aCC >= ((major)*10000 + (minor)*100)) #endif diff --git a/external/bsd/libpcap/dist/pcap/dlt.h b/external/bsd/libpcap/dist/pcap/dlt.h index 8dacf024044c..0da6de236ab6 100644 --- a/external/bsd/libpcap/dist/pcap/dlt.h +++ b/external/bsd/libpcap/dist/pcap/dlt.h @@ -104,6 +104,67 @@ #define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ #endif +/* + * NetBSD uses 15 for HIPPI. + * + * From a quick look at sys/net/if_hippi.h and sys/net/if_hippisubr.c + * in an older version of NetBSD , the header appears to be: + * + * a 1-byte ULP field (ULP-id)? + * + * a 1-byte flags field; + * + * a 2-byte "offsets" field; + * + * a 4-byte "D2 length" field (D2_Size?); + * + * a 4-byte "destination switch" field (or a 1-byte field + * containing the Forwarding Class, Double_Wide, and Message_Type + * sub fields, followed by a 3-byte Destination_Switch_Address + * field?, HIPPI-LE 3.4-style?); + * + * a 4-byte "source switch" field (or a 1-byte field containing the + * Destination_Address_type and Source_Address_Type fields, followed + * by a 3-byte Source_Switch_Address field, HIPPI-LE 3.4-style?); + * + * a 2-byte reserved field; + * + * a 6-byte destination address field; + * + * a 2-byte "local admin" field; + * + * a 6-byte source address field; + * + * followed by an 802.2 LLC header. + * + * This looks somewhat like something derived from the HIPPI-FP 4.4 + * Header_Area, followed an HIPPI-FP 4.4 D1_Area containing a D1 data set + * with the header in HIPPI-LE 3.4 (ANSI X3.218-1993), followed by an + * HIPPI-FP 4.4 D2_Area (with no Offset) containing the 802.2 LLC header + * and payload? Or does the "offsets" field contain the D2_Offset, + * with that many bytes of offset before the payload? + * + * See http://wotug.org/parallel/standards/hippi/ for an archive of + * HIPPI specifications. + * + * RFC 2067 imposes some additional restrictions. It says that the + * Offset is always zero + * + * HIPPI is long-gone, and the source files found in an older version + * of NetBSD don't appear to be in the main CVS branch, so we may never + * see a capture with this link-layer type. + */ +#if defined(__NetBSD__) +#define DLT_HIPPI 15 /* HIPPI */ +#endif + +/* + * NetBSD uses 16 for DLT_HDLC; see below. + * BSD/OS uses it for PPP; see above. + * As far as I know, no other OS uses it for anything; don't use it + * for anything else. + */ + /* * 17 was used for DLT_PFLOG in OpenBSD; it no longer is. * @@ -136,7 +197,7 @@ #define DLT_PFSYNC 18 #endif -#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ +#define DLT_ATM_CLIP 19 /* Linux Classical IP over ATM */ /* * Apparently Redback uses this for its SmartEdge 400/800. I hope @@ -219,7 +280,8 @@ * that the AF_ type in the link-layer header is in network byte order. * * DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so - * we don't use 12 for it in OSes other than OpenBSD. + * we don't use 12 for it in OSes other than OpenBSD; instead, we + * use the same value as LINKTYPE_LOOP. */ #ifdef __OpenBSD__ #define DLT_LOOP 12 @@ -230,7 +292,7 @@ /* * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other - * than OpenBSD. + * than OpenBSD; instead, we use the same value as LINKTYPE_ENC. */ #ifdef __OpenBSD__ #define DLT_ENC 13 @@ -239,12 +301,22 @@ #endif /* - * Values between 110 and 112 are reserved for use in capture file headers + * Values 110 and 111 are reserved for use in capture file headers * as link-layer types corresponding to DLT_ types that might differ * between platforms; don't use those values for new DLT_ types * other than the corresponding DLT_ types. */ +/* + * NetBSD uses 16 for (Cisco) "HDLC framing". For other platforms, + * we define it to have the same value as LINKTYPE_NETBSD_HDLC. + */ +#if defined(__NetBSD__) +#define DLT_HDLC 16 /* Cisco HDLC */ +#else +#define DLT_HDLC 112 +#endif + /* * Linux cooked sockets. */ @@ -465,7 +537,7 @@ #define DLT_DOCSIS 143 /* - * Linux-IrDA packets. Protocol defined at http://www.irda.org. + * Linux-IrDA packets. Protocol defined at https://www.irda.org. * Those packets include IrLAP headers and above (IrLMP...), but * don't include Phy framing (SOF/EOF/CRC & byte stuffing), because Phy * framing can be handled by the hardware and depend on the bitrate. @@ -473,7 +545,7 @@ * interface (irdaX), but not on a raw serial port. * Note the capture is done in "Linux-cooked" mode, so each packet include * a fake packet header (struct sll_header). This is because IrDA packet - * decoding is dependant on the direction of the packet (incomming or + * decoding is dependent on the direction of the packet (incoming or * outgoing). * When/if other platform implement IrDA capture, we may revisit the * issue and define a real DLT_IRDA... @@ -565,7 +637,7 @@ * input packets such as port scans, packets from old lost connections, * etc. to force the connection to stay up). * - * The first byte of the PPP header (0xff03) is modified to accomodate + * The first byte of the PPP header (0xff03) is modified to accommodate * the direction - 0x00 = IN, 0x01 = OUT. */ #define DLT_PPP_PPPD 166 @@ -607,7 +679,7 @@ /* * Link types requested by Gregor Maier of Endace * Measurement Systems. They add an ERF header (see - * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of + * https://www.endace.com/support/EndaceRecordFormat.pdf) in front of * the link-layer header. */ #define DLT_ERF_ETH 175 /* Ethernet */ @@ -651,7 +723,7 @@ * DLT_ requested by Gianluca Varenni . * Every frame contains a 32bit A429 label. * More documentation on Arinc 429 can be found at - * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf + * https://web.archive.org/web/20040616233302/https://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf */ #define DLT_A429 184 @@ -750,7 +822,7 @@ /* * Various link-layer types, with a pseudo-header, for SITA - * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com). + * (https://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com). */ #define DLT_SITA 196 @@ -817,8 +889,11 @@ * PPP, with a one-byte direction pseudo-header prepended - zero means * "received by this host", non-zero (any non-zero value) means "sent by * this host" - as per Will Barker . + * + * Don't confuse this with DLT_PPP_WITH_DIRECTION, which is an old + * name for what is now called DLT_PPP_PPPD. */ -#define DLT_PPP_WITH_DIR 204 /* Don't confuse with DLT_PPP_WITH_DIRECTION */ +#define DLT_PPP_WITH_DIR 204 /* * Cisco HDLC, with a one-byte direction pseudo-header prepended - zero @@ -862,7 +937,7 @@ /* * Media Oriented Systems Transport (MOST) bus for multimedia - * transport - http://www.mostcooperation.com/ - as requested + * transport - https://www.mostcooperation.com/ - as requested * by Hannes Kaelber . */ #define DLT_MOST 211 @@ -1048,16 +1123,16 @@ /* * Raw D-Bus: * - * http://www.freedesktop.org/wiki/Software/dbus + * https://www.freedesktop.org/wiki/Software/dbus * * messages: * - * http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages + * https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages * * starting with the endianness flag, followed by the message type, etc., * but without the authentication handshake before the message sequence: * - * http://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol + * https://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol * * Requested by Martin Vidner . */ @@ -1075,7 +1150,7 @@ * DVB-CI (DVB Common Interface for communication between a PC Card * module and a DVB receiver). See * - * http://www.kaiser.cx/pcap-dvbci.html + * https://www.kaiser.cx/pcap-dvbci.html * * for the specification. * @@ -1211,15 +1286,17 @@ #define DLT_BLUETOOTH_LE_LL 251 /* - * DLT type for upper-protocol layer PDU saves from wireshark. + * DLT type for upper-protocol layer PDU saves from Wireshark. + * + * the actual contents are determined by two TAGs, one or more of + * which is stored with each packet: * - * the actual contents are determined by two TAGs stored with each - * packet: - * EXP_PDU_TAG_LINKTYPE the link type (LINKTYPE_ value) of the - * original packet. + * EXP_PDU_TAG_DISSECTOR_NAME the name of the Wireshark dissector + * that can make sense of the data stored. * - * EXP_PDU_TAG_PROTO_NAME the name of the wireshark dissector - * that can make sense of the data stored. + * EXP_PDU_TAG_HEUR_DISSECTOR_NAME the name of the Wireshark heuristic + * dissector that can make sense of the + * data stored. */ #define DLT_WIRESHARK_UPPER_PDU 252 @@ -1364,9 +1441,9 @@ /* * per: Stefanha at gmail.com for - * http://lists.sandelman.ca/pipermail/tcpdump-workers/2017-May/000772.html + * https://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 + * for: https://qemu-project.org/Features/VirtioVsock */ #define DLT_VSOCK 271 @@ -1378,7 +1455,7 @@ /* * Excentis DOCSIS 3.1 RF sniffer (XRA-31) * per: bruno.verstuyft at excentis.com - * http://www.xra31.com/xra-header + * https://www.xra31.com/xra-header */ #define DLT_DOCSIS31_XRA31 273 @@ -1390,7 +1467,7 @@ /* * DisplayPort AUX channel monitoring data as specified by VESA - * DisplayPort(DP) Standard preceeded by a pseudo-header. + * DisplayPort(DP) Standard preceded by a pseudo-header. * per dirk.eibach at gdsys.cc */ #define DLT_DISPLAYPORT_AUX 275 @@ -1400,6 +1477,83 @@ */ #define DLT_LINUX_SLL2 276 +/* + * Sercos Monitor, per Manuel Jacob + */ +#define DLT_SERCOS_MONITOR 277 + +/* + * OpenVizsla http://openvizsla.org is open source USB analyzer hardware. + * It consists of FPGA with attached USB phy and FTDI chip for streaming + * the data to the host PC. + * + * Current OpenVizsla data encapsulation format is described here: + * https://github.com/matwey/libopenvizsla/wiki/OpenVizsla-protocol-description + * + */ +#define DLT_OPENVIZSLA 278 + +/* + * The Elektrobit High Speed Capture and Replay (EBHSCR) protocol is produced + * by a PCIe Card for interfacing high speed automotive interfaces. + * + * The specification for this frame format can be found at: + * https://www.elektrobit.com/ebhscr + * + * for Guenter.Ebermann at elektrobit.com + * + */ +#define DLT_EBHSCR 279 + +/* + * The https://fd.io vpp graph dispatch tracer produces pcap trace files + * in the format documented here: + * https://fdio-vpp.readthedocs.io/en/latest/gettingstarted/developers/vnet.html#graph-dispatcher-pcap-tracing + */ +#define DLT_VPP_DISPATCH 280 + +/* + * Broadcom Ethernet switches (ROBO switch) 4 bytes proprietary tagging format. + */ +#define DLT_DSA_TAG_BRCM 281 +#define DLT_DSA_TAG_BRCM_PREPEND 282 + +/* + * IEEE 802.15.4 with pseudo-header and optional meta-data TLVs, PHY payload + * exactly as it appears in the spec (no padding, no nothing), and FCS if + * specified by FCS Type TLV; requested by James Ko . + * Specification at https://github.com/jkcko/ieee802.15.4-tap + */ +#define DLT_IEEE802_15_4_TAP 283 + +/* + * Marvell (Ethertype) Distributed Switch Architecture proprietary tagging format. + */ +#define DLT_DSA_TAG_DSA 284 +#define DLT_DSA_TAG_EDSA 285 + +/* + * Payload of lawful intercept packets using the ELEE protocol; + * https://socket.hr/draft-dfranusic-opsawg-elee-00.xml + * https://xml2rfc.tools.ietf.org/cgi-bin/xml2rfc.cgi?url=https://socket.hr/draft-dfranusic-opsawg-elee-00.xml&modeAsFormat=html/ascii + */ +#define DLT_ELEE 286 + +/* + * Serial frames transmitted between a host and a Z-Wave chip. + */ +#define DLT_Z_WAVE_SERIAL 287 + +/* + * USB 2.0, 1.1, and 1.0 packets as transmitted over the cable. + */ +#define DLT_USB_2_0 288 + +/* + * ATSC Link-Layer Protocol (A/330) packets. + */ +#define DLT_ATSC_ALP 289 + /* * In case the code that includes this file (directly or indirectly) * has also included OS files that happen to define DLT_MATCHING_MAX, @@ -1410,7 +1564,7 @@ #ifdef DLT_MATCHING_MAX #undef DLT_MATCHING_MAX #endif -#define DLT_MATCHING_MAX 276 /* highest value in the "matching" range */ +#define DLT_MATCHING_MAX 289 /* highest value in the "matching" range */ /* * DLT and savefile link type values are split into a class and diff --git a/external/bsd/libpcap/dist/pcap/funcattrs.h b/external/bsd/libpcap/dist/pcap/funcattrs.h index e64da93aa4ce..374094992308 100644 --- a/external/bsd/libpcap/dist/pcap/funcattrs.h +++ b/external/bsd/libpcap/dist/pcap/funcattrs.h @@ -118,14 +118,14 @@ #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 + * GCC 3.4 and later, or some compiler asserting compatibility with + * GCC 3.4 and later, or XL C 13.0 and 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.5 and 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.) */ @@ -146,6 +146,88 @@ #define PCAP_API PCAP_API_DEF extern +/* + * Definitions to 1) indicate what version of libpcap first had a given + * API and 2) allow upstream providers whose build environments allow + * APIs to be designated as "first available in this release" to do so + * by appropriately defining them. + * + * Yes, that's you, Apple. :-) Please define PCAP_AVAILABLE_MACOS() + * as necessary to make various APIs "weak exports" to make it easier + * for software that's distributed in binary form and that uses libpcap + * to run on multiple macOS versions and use new APIs when available. + * (Yes, such third-party software exists - Wireshark provides binary + * packages for macOS, for example. tcpdump doesn't count, as that's + * provided by Apple, so each release can come with a version compiled + * to use the APIs present in that release.) + * + * The non-macOS versioning is based on + * + * https://en.wikipedia.org/wiki/Darwin_(operating_system)#Release_history + * + * If there are any corrections, please submit it upstream to the + * libpcap maintainers, preferably as a pull request on + * + * https://github.com/the-tcpdump-group/libpcap + * + * We don't define it ourselves because, if you're building and + * installing libpcap on macOS yourself, the APIs will be available + * no matter what OS version you're installing it on. + * + * For other platforms, we don't define them, leaving it up to + * others to do so based on their OS versions, if appropriate. + * + * We start with libpcap 0.4, as that was the last LBL release, and + * I've never seen earlier releases. + */ +#ifdef __APPLE__ +#include +/* + * When building as part of macOS, define this as __API_AVAILABLE(__VA_ARGS__). + * + * XXX - if there's some #define to indicate that this is being built + * as part of the macOS build process, we could make that Just Work. + */ +#define PCAP_AVAILABLE(...) +#define PCAP_AVAILABLE_0_4 PCAP_AVAILABLE(macos(10.0)) /* Did any version of Mac OS X ship with this? */ +#define PCAP_AVAILABLE_0_5 PCAP_AVAILABLE(macos(10.0)) /* Did any version of Mac OS X ship with this? */ +#define PCAP_AVAILABLE_0_6 PCAP_AVAILABLE(macos(10.1)) +#define PCAP_AVAILABLE_0_7 PCAP_AVAILABLE(macos(10.4)) +#define PCAP_AVAILABLE_0_8 PCAP_AVAILABLE(macos(10.4)) +#define PCAP_AVAILABLE_0_9 PCAP_AVAILABLE(macos(10.5), ios(1.0)) +#define PCAP_AVAILABLE_1_0 PCAP_AVAILABLE(macos(10.6), ios(4.0)) +/* #define PCAP_AVAILABLE_1_1 no routines added to the API */ +#define PCAP_AVAILABLE_1_2 PCAP_AVAILABLE(macos(10.9), ios(6.0)) +/* #define PCAP_AVAILABLE_1_3 no routines added to the API */ +/* #define PCAP_AVAILABLE_1_4 no routines added to the API */ +#define PCAP_AVAILABLE_1_5 PCAP_AVAILABLE(macos(10.10), ios(7.0), watchos(1.0)) +/* #define PCAP_AVAILABLE_1_6 no routines added to the API */ +#define PCAP_AVAILABLE_1_7 PCAP_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) +#define PCAP_AVAILABLE_1_8 PCAP_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)) /* only Windows adds routines to the API; XXX - what version first had it? */ +#define PCAP_AVAILABLE_1_9 PCAP_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)) +#define PCAP_AVAILABLE_1_10 /* not in macOS yet */ +#define PCAP_AVAILABLE_1_11 /* not released yet, so not in macOS yet */ +#else /* __APPLE__ */ +#define PCAP_AVAILABLE_0_4 +#define PCAP_AVAILABLE_0_5 +#define PCAP_AVAILABLE_0_6 +#define PCAP_AVAILABLE_0_7 +#define PCAP_AVAILABLE_0_8 +#define PCAP_AVAILABLE_0_9 +#define PCAP_AVAILABLE_1_0 +/* #define PCAP_AVAILABLE_1_1 no routines added to the API */ +#define PCAP_AVAILABLE_1_2 +/* #define PCAP_AVAILABLE_1_3 no routines added to the API */ +/* #define PCAP_AVAILABLE_1_4 no routines added to the API */ +#define PCAP_AVAILABLE_1_5 +/* #define PCAP_AVAILABLE_1_6 no routines added to the API */ +#define PCAP_AVAILABLE_1_7 +#define PCAP_AVAILABLE_1_8 +#define PCAP_AVAILABLE_1_9 +#define PCAP_AVAILABLE_1_10 +#define PCAP_AVAILABLE_1_11 +#endif /* __APPLE__ */ + /* * PCAP_NORETURN, before a function declaration, means "this function * never returns". (It must go before the function declaration, e.g. @@ -164,11 +246,11 @@ || PCAP_IS_AT_LEAST_XL_C_VERSION(10,1) \ || PCAP_IS_AT_LEAST_HP_C_VERSION(6,10) /* - * Compiler with support for __attribute((noreturn)), or GCC 2.5 or - * later, or some compiler asserting compatibility with GCC 2.5 or - * later, or Solaris Studio 12 (Sun C 5.9) or later, or IBM XL C 10.1 - * or later (do any earlier versions of XL C support this?), or HP aCC - * A.06.10 or later. + * Compiler with support for __attribute((noreturn)), or GCC 2.5 and + * later, or some compiler asserting compatibility with 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)) @@ -194,8 +276,8 @@ || PCAP_IS_AT_LEAST_XL_C_VERSION(10,1) \ || PCAP_IS_AT_LEAST_HP_C_VERSION(6,10) /* - * Compiler with support for it, or GCC 2.3 or later, or some compiler - * asserting compatibility with GCC 2.3 or later, or IBM XL C 10.1 + * Compiler with support for it, or GCC 2.3 and later, or some compiler + * asserting compatibility with 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. */ @@ -208,23 +290,21 @@ * 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.) + * The argument is a string giving the warning message to use if the + * compiler supports that. */ #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 or later, or Sun/Oracle C 12.4 (Sun C 5.13) or later. + * or GCC 4.5 and later, or Sun/Oracle C 12.4 (Sun C 5.13) and 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))) + #define PCAP_DEPRECATED(msg) __attribute__((deprecated(msg))) #elif PCAP_IS_AT_LEAST_GNUC_VERSION(3,1) /* * GCC 3.1 through 4.4. @@ -232,18 +312,18 @@ * 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) + #define PCAP_DEPRECATED(msg) __attribute__((deprecated)) +#elif defined(_MSC_VER) && !defined(BUILDING_PCAP) /* - * MSVC from Visual Studio 2008 or later, and we're not building - * libpcap itself. + * MSVC, and we're not building libpcap itself; it's VS 2015 + * and later, so we have __declspec(deprecated(...)). * * 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)) + #define PCAP_DEPRECATED(msg) _declspec(deprecated(msg)) #else - #define PCAP_DEPRECATED(func, msg) + #define PCAP_DEPRECATED(msg) #endif /* @@ -251,11 +331,7 @@ */ #ifdef _MSC_VER #include - #if _MSC_VER > 1400 - #define PCAP_FORMAT_STRING(p) _Printf_format_string_ p - #else - #define PCAP_FORMAT_STRING(p) __format_string p - #endif + #define PCAP_FORMAT_STRING(p) _Printf_format_string_ p #else #define PCAP_FORMAT_STRING(p) p #endif diff --git a/external/bsd/libpcap/dist/pcap/pcap-inttypes.h b/external/bsd/libpcap/dist/pcap/pcap-inttypes.h index 8b1eb8b9be84..8c7b4f651ede 100644 --- a/external/bsd/libpcap/dist/pcap/pcap-inttypes.h +++ b/external/bsd/libpcap/dist/pcap/pcap-inttypes.h @@ -32,8 +32,13 @@ #define pcap_pcap_inttypes_h /* - * Get the integer types and PRi[doux]64 values from C99 - * defined, by hook or by crook. + * If we're compiling with Visual Studio, make sure the C99 integer + * types are defined, by hook or by crook. + * + * XXX - verify that we have at least C99 support on UN*Xes? + * + * What about MinGW or various DOS toolchains? We're currently assuming + * sufficient C99 support there. */ #if defined(_MSC_VER) /* @@ -47,6 +52,10 @@ #else /* * Earlier VS; we have to define this stuff ourselves. + * We don't support building libpcap with earlier versions of VS, + * but SDKs for Npcap have to support building applications using + * earlier versions of VS, so we work around this by defining + * those types ourselves, as some files use them. */ typedef unsigned char uint8_t; typedef signed char int8_t; @@ -62,67 +71,31 @@ typedef long long int64_t; #endif #endif - +#else /* defined(_MSC_VER) */ /* - * These may be defined by . + * Not Visual Studio. + * Include to get the integer types and PRi[doux]64 values + * defined. * - * 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. + * If the compiler is MinGW, we assume we have - and + * support for %zu in the formatted printing functions. * - * XXX - we currently aren't using any of these, but this allows - * their use in the future. + * If the target is UN*X, we assume we have a C99-or-later development + * environment, and thus have - and support for %zu in + * the formatted printing functions. + * + * If the target is MS-DOS, we assume we have - and support + * for %zu in the formatted printing functions. + * + * I.e., assume we have and that it suffices. */ - #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 /* - * MSVC's support library doesn't support %zu to print a size_t until - * Visual Studio 2017, but supports %Iu earlier, so use that. + * XXX - somehow make sure we have enough C99 support with other + * compilers and support libraries? */ - #define PRIsize "Iu" -#elif defined(__MINGW32__) || !defined(_WIN32) - /* - * Compiler is MinGW or target is UN*X or MS-DOS. Just use - * . - */ - #include - /* - * Assume the support library supports %zu; it's required by C99. - */ - #define PRIsize "zu" -#endif + #include +#endif /* defined(_MSC_VER) */ #endif /* pcap/pcap-inttypes.h */ diff --git a/external/bsd/libpcap/dist/pcap/socket.h b/external/bsd/libpcap/dist/pcap/socket.h index 6f27cba12f91..ee2e393e1b69 100644 --- a/external/bsd/libpcap/dist/pcap/socket.h +++ b/external/bsd/libpcap/dist/pcap/socket.h @@ -48,15 +48,6 @@ #include #include - /* - * Winsock doesn't have this UN*X type; it's used in the UN*X - * sockets API. - * - * XXX - do we need to worry about UN*Xes so old that *they* - * don't have it, either? - */ - typedef int socklen_t; - /* * Winsock doesn't have this POSIX type; it's used for the * tv_usec value of struct timeval. diff --git a/external/bsd/libpcap/dist/pcap_compile.3pcap.in b/external/bsd/libpcap/dist/pcap_compile.3pcap.in index 824f52b32e7e..67001fa49322 100644 --- a/external/bsd/libpcap/dist/pcap_compile.3pcap.in +++ b/external/bsd/libpcap/dist/pcap_compile.3pcap.in @@ -33,17 +33,17 @@ const char *str, int optimize, bpf_u_int32 netmask); .ft .fi .SH DESCRIPTION -.B pcap_compile() +.BR pcap_compile () is used to compile the string .I str into a filter program. See -.BR pcap-filter (@MAN_MISC_INFO@) +.BR \%pcap-filter (@MAN_MISC_INFO@) for the syntax of that string. -.I program +.I fp is a pointer to a .I bpf_program struct and is filled in by -.BR pcap_compile() . +.BR pcap_compile (). .I optimize controls whether optimization on the resulting code is performed. .I netmask @@ -59,24 +59,26 @@ 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() +.BR 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() +.BR 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 +.BR pcap_compile () +returns +.B 0 +on success and .B PCAP_ERROR on failure. If .B PCAP_ERROR is returned, -.B pcap_geterr(3PCAP) +.BR pcap_geterr (3PCAP) or -.B pcap_perror(3PCAP) +.BR pcap_perror (3PCAP) may be called with .I p as an argument to fetch or display the error text. @@ -86,4 +88,6 @@ The .B PCAP_NETMASK_UNKNOWN constant became available in libpcap release 1.1.0. .SH SEE ALSO -pcap(3PCAP), pcap_setfilter(3PCAP), pcap_freecode(3PCAP), +.BR pcap (3PCAP), +.BR pcap_setfilter (3PCAP), +.BR pcap_freecode (3PCAP) diff --git a/external/bsd/libpcap/dist/pcap_datalink.3pcap.in b/external/bsd/libpcap/dist/pcap_datalink.3pcap.in index 26203683eddf..abb737508420 100644 --- a/external/bsd/libpcap/dist/pcap_datalink.3pcap.in +++ b/external/bsd/libpcap/dist/pcap_datalink.3pcap.in @@ -31,19 +31,19 @@ int pcap_datalink(pcap_t *p); .ft .fi .SH DESCRIPTION -.B pcap_datalink() +.BR pcap_datalink () returns the link-layer header type for the live capture or ``savefile'' specified by .IR p . .PP It must not be called on a pcap descriptor created by -.B \%pcap_create(3PCAP) +.BR \%pcap_create (3PCAP) that has not yet been activated by -.BR \%pcap_activate(3PCAP) . +.BR \%pcap_activate (3PCAP). .PP .I https://www.tcpdump.org/linktypes.html lists the values -.B pcap_datalink() +.BR pcap_datalink () can return and describes the packet formats that correspond to those values. .PP @@ -55,14 +55,17 @@ any given link-layer header type, such as for Ethernet. For example, the "any" device on Linux will have a link-layer header type of .B DLT_LINUX_SLL +or +.B DLT_LINUX_SLL2 even if all devices on the system at the time the "any" device is opened have some other data link type, such as .B DLT_EN10MB for Ethernet. .SH RETURN VALUE -.B pcap_datalink() +.BR pcap_datalink () returns the link-layer header type on success and .B PCAP_ERROR_NOT_ACTIVATED if called on a capture handle that has been created but not activated. .SH SEE ALSO -pcap(3PCAP), pcap-linktype(@MAN_MISC_INFO@) +.BR pcap (3PCAP), +.BR pcap-linktype (@MAN_MISC_INFO@) diff --git a/external/bsd/libpcap/dist/pcap_get_required_select_timeout.3pcap b/external/bsd/libpcap/dist/pcap_get_required_select_timeout.3pcap index e58cb4e78d5c..37af180352ed 100644 --- a/external/bsd/libpcap/dist/pcap_get_required_select_timeout.3pcap +++ b/external/bsd/libpcap/dist/pcap_get_required_select_timeout.3pcap @@ -17,10 +17,10 @@ .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" -.TH PCAP_GET_REQUIRED_SELECT_TIMEOUT 3PCAP "25 July 2018" +.TH PCAP_GET_REQUIRED_SELECT_TIMEOUT 3PCAP "29 January 2020" .SH NAME -pcap_get_required_select_timeout \- get a file descriptor on which a -select() can be done for a live capture +pcap_get_required_select_timeout \- get a timeout to be used when doing +select() for a live capture .SH SYNOPSIS .nf .ft B @@ -28,53 +28,98 @@ select() can be done for a live capture .ft .LP .ft B -struct timeval *pcap_get_required_select_timeout(pcap_t *p); +const struct timeval *pcap_get_required_select_timeout(pcap_t *p); .ft .fi .SH DESCRIPTION -.B pcap_get_required_select_timeout() +.BR 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(2) , -.BR poll(2) , -.BR epoll_wait(2) , +.BR select (2), +.BR poll (2), +.BR epoll_wait (2), and -.B kevent() -calls if -.B pcap_get_selectable_fd(3PCAP) +.BR kevent (2) +calls, or +.B NULL +if there is no such timeout. +If a +.RB non- NULL +value is returned, it must be used regardless of whether +.BR pcap_get_selectable_fd (3PCAP) returns -.BR PCAP_ERROR . +.B \-1 +for any descriptor on which those calls are being done. +.BR pcap_get_required_select_timeout () +should be called for all +.BR pcap_t s +before a call to +.BR select (), +.BR poll (), +.BR epoll_wait (), +or +.BR kevent (), +and any timeouts used for those calls should be updated as appropriate +given the new value of the timeout. +.PP +For +.BR kevent (), +one +.B EVFILT_TIMER +filter per selectable descriptor can be used, rather than using the +timeout argument to +.BR kevent (); +if the +.B EVFILT_TIMER +event for a particular selectable descriptor signals an event, +.BR pcap_dispatch (3PCAP) +should be called for the corresponding +.BR pcap_t . .PP -The timeout that should be used in those calls must be no larger than +On Linux systems with +.BR timerfd_create (2), +one timer object created by +.BR timerfd_create () +per selectable descriptor can be used, rather than using the timeout +argument to +.BR epoll_wait (); +if the +timer object for a particular selectable descriptor signals an event, +.BR pcap_dispatch (3PCAP) +should be called for the corresponding +.BR pcap_t . +.PP +Otherwise, a timeout value no larger than the smallest of all timeouts returned by -.B \%pcap_get_required_select_timeout() -for devices from which packets will be captured. +.BR \%pcap_get_required_select_timeout () +for devices from which packets will be captured and any other timeouts +to be used in the call should be used as the timeout for the call, and, +when the call returns, +.BR pcap_dispatch (3PCAP) +should be called for all +.BR pcap_t s +for which a +.RB non- NULL +timeout was returned, regardless of whether it's indicated as having +anything to read from it or not. .PP -The device for which -.B pcap_get_selectable_fd() -returned -.B PCAP_ERROR -must be put in non-blocking mode with -.BR pcap_setnonblock(3PCAP) , -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. +All devices with a +.RB non- NULL +timeout must be put in non-blocking mode with +.BR pcap_setnonblock (3PCAP). .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(3PCAP) +.BR pcap_dispatch () or -.B pcap_next_ex(3PCAP) -will return 0 in this case, but will not block. +.BR pcap_next_ex (3PCAP) +will return +.B 0 +in this case, but will not block. .PP -.B pcap_get_required_select_timeout() +.BR pcap_get_required_select_timeout () is not available on Windows. .SH RETURN VALUE A pointer to a @@ -85,14 +130,41 @@ is returned. .SH BACKWARD COMPATIBILITY This function became available in libpcap release 1.9.0. In previous releases, -.BR select() , -.BR poll() , -.BR epoll_wait() , +.BR select (), +.BR poll (), +.BR epoll_wait (), and -.B kevent() -cannot be used on any capture source for which -.B pcap_get_selectable_fd -returns \-1. +.BR kevent () +could not be used for devices that don't provide a selectable file +descriptor (in other words, on any capture source for that +.BR pcap_get_selectable_fd () +returns +.BR \-1 ). +.PP +In libpcap release 1.10.0 and later, the timeout value can change from +call to call, so +.BR pcap_get_required_select_timeout () +must be called before each call to +.BR select (), +.BR poll (), +.BR epoll_wait (), +or +.BR kevent (), +and the new value must be used to calculate timeouts for the call. Code +that does that will also work with libpcap 1.9.x releases, so code +using +.BR pcap_get_required_select_timeout () +should be changed to call it for each call to +.BR select (), +.BR poll (), +.BR epoll_wait (), +or +.BR kevent () +even if the code must also work with libpcap 1.9.x. .SH SEE ALSO -pcap(3PCAP), pcap_get_selectable_fd(3PCAP), select(2), poll(2), -epoll_wait(2), kqueue(2) +.BR pcap (3PCAP), +.BR pcap_get_selectable_fd (3PCAP), +.BR select (2), +.BR poll (2), +.BR epoll_wait (2), +.BR kqueue (2) diff --git a/external/bsd/libpcap/dist/pcap_get_tstamp_precision.3pcap.in b/external/bsd/libpcap/dist/pcap_get_tstamp_precision.3pcap.in index 2e72e0bac14f..46451446ba55 100644 --- a/external/bsd/libpcap/dist/pcap_get_tstamp_precision.3pcap.in +++ b/external/bsd/libpcap/dist/pcap_get_tstamp_precision.3pcap.in @@ -19,7 +19,7 @@ .\"IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED .\"WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -.TH PCAP_GET_TSTAMP_PRECISION 3PCAP "18 December 2013" +.TH PCAP_GET_TSTAMP_PRECISION 3PCAP "23 August 2018" .SH NAME pcap_get_tstamp_precision \- get the time stamp precision returned in captures @@ -34,11 +34,11 @@ int pcap_get_tstamp_precision(pcap_t *p); .ft .fi .SH DESCRIPTION -.B pcap_get_tstamp_precision() +.BR pcap_get_tstamp_precision () returns the precision of the time stamp returned in packet captures on the pcap descriptor. .SH RETURN VALUE -.B pcap_get_tstamp_precision() +.BR pcap_get_tstamp_precision () returns .B PCAP_TSTAMP_PRECISION_MICRO or @@ -51,6 +51,6 @@ This function became available in libpcap release 1.5.1. In previous releases, time stamps from a capture device or savefile are always given in seconds and microseconds. .SH SEE ALSO -pcap(3PCAP), -pcap_set_tstamp_precision(3PCAP), -pcap-tstamp(@MAN_MISC_INFO@) +.BR pcap (3PCAP), +.BR pcap_set_tstamp_precision (3PCAP), +.BR \%pcap-tstamp (@MAN_MISC_INFO@) diff --git a/external/bsd/libpcap/dist/pcap_init.3pcap b/external/bsd/libpcap/dist/pcap_init.3pcap new file mode 100644 index 000000000000..a807d0ecd86c --- /dev/null +++ b/external/bsd/libpcap/dist/pcap_init.3pcap @@ -0,0 +1,99 @@ +.\" 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_INIT 3PCAP "4 May 2022" +.SH NAME +pcap_init \- initialize the library +.SH SYNOPSIS +.nf +.ft B +#include +.ft +.LP +.nf +.ft B +char errbuf[PCAP_ERRBUF_SIZE]; +.ft +.LP +.ft B +int pcap_init(unsigned int opts, char *errbuf); +.ft +.fi +.SH DESCRIPTION +.BR pcap_init () +is used to initialize the Packet Capture library. +.I opts +specifies options for the library; +currently, the options are: +.TP +.B PCAP_CHAR_ENC_LOCAL +Treat all strings supplied as arguments, and return all strings to the +caller, as being in the local character encoding. +.TP +.B PCAP_CHAR_ENC_UTF_8 +Treat all strings supplied as arguments, and return all strings to the +caller, as being in UTF-8. +.PP +On UNIX-like systems, the local character encoding is assumed to be +UTF-8, so no character encoding transformations are done. +.PP +On Windows, the local character encoding is the local ANSI code page. +.PP +If +.BR pcap_init () +is not called, strings are treated as being in the local ANSI code page +on Windows, +.BR pcap_lookupdev (3PCAP) +will succeed if there is a device on which to capture, and +.BR pcap_create (3PCAP) +makes an attempt to check whether the string passed as an argument is a +UTF-16LE string - note that this attempt is unsafe, as it may run past +the end of the string - to handle +.BR pcap_lookupdev () +returning a UTF-16LE string. Programs that don't call +.BR pcap_init () +should, on Windows, call +.BR pcap_wsockinit () +to initialize Winsock; this is not necessary if +.BR pcap_init () +is called, as +.BR pcap_init () +will initialize Winsock itself on Windows. +.SH RETURN VALUE +.BR pcap_init () +returns +.B 0 +on success and +.B PCAP_ERROR +on failure. +If +.B PCAP_ERROR +is returned, +.I errbuf +is filled in with an appropriate error message. +.I errbuf +is assumed to be able to hold at least +.B PCAP_ERRBUF_SIZE +chars. +.SH BACKWARD COMPATIBILITY +This function became available in libpcap release 1.9.0. In previous +releases, on Windows, all strings supplied as arguments, and all strings +returned to the caller, are in the local character encoding. +.SH SEE ALSO +.BR pcap (3PCAP) diff --git a/external/bsd/libpcap/dist/pcap_list_datalinks.3pcap.in b/external/bsd/libpcap/dist/pcap_list_datalinks.3pcap.in index 60ba478f7466..d6e314997aa1 100644 --- a/external/bsd/libpcap/dist/pcap_list_datalinks.3pcap.in +++ b/external/bsd/libpcap/dist/pcap_list_datalinks.3pcap.in @@ -33,25 +33,25 @@ void pcap_free_datalinks(int *dlt_list); .ft .fi .SH DESCRIPTION -.B pcap_list_datalinks() +.BR pcap_list_datalinks () is used to get a list of the supported link-layer header types of the interface associated with the pcap descriptor. -.B pcap_list_datalinks() +.BR pcap_list_datalinks () allocates an array to hold the list and sets .IR *dlt_buf to point to that array. .LP The caller is responsible for freeing the array with -.BR pcap_free_datalinks() , +.BR pcap_free_datalinks (), which frees the list of link-layer header types pointed to by .IR dlt_list . .LP It must not be called on a pcap descriptor created by -.B \%pcap_create(3PCAP) +.BR \%pcap_create (3PCAP) that has not yet been activated by -.BR \%pcap_activate(3PCAP) . +.BR \%pcap_activate (3PCAP). .SH RETURN VALUE -.B pcap_list_datalinks() +.BR pcap_list_datalinks () returns the number of link-layer header types in the array on success, .B PCAP_ERROR_NOT_ACTIVATED if called on a capture handle that has been created but not activated, @@ -61,13 +61,13 @@ on other errors. If .B PCAP_ERROR is returned, -.B pcap_geterr(3PCAP) +.BR pcap_geterr (3PCAP) or -.B \%pcap_perror(3PCAP) +.BR \%pcap_perror (3PCAP) may be called with .I p as an argument to fetch or display the error text. .SH SEE ALSO -pcap(3PCAP), -pcap_datalink_val_to_name(3PCAP), -pcap-linktype(@MAN_MISC_INFO@) +.BR pcap (3PCAP), +.BR pcap_datalink_val_to_name (3PCAP), +.BR pcap-linktype (@MAN_MISC_INFO@) diff --git a/external/bsd/libpcap/dist/pcap_list_tstamp_types.3pcap.in b/external/bsd/libpcap/dist/pcap_list_tstamp_types.3pcap.in index e2487f704fd8..8b6174f4c498 100644 --- a/external/bsd/libpcap/dist/pcap_list_tstamp_types.3pcap.in +++ b/external/bsd/libpcap/dist/pcap_list_tstamp_types.3pcap.in @@ -18,7 +18,7 @@ .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" -.TH PCAP_LIST_TSTAMP_TYPES 3PCAP "22 August 2018" +.TH PCAP_LIST_TSTAMP_TYPES 3PCAP "8 September 2019" .SH NAME pcap_list_tstamp_types, pcap_free_tstamp_types \- get a list of time stamp types supported by a capture device, and free that list @@ -34,23 +34,23 @@ void pcap_free_tstamp_types(int *tstamp_types); .ft .fi .SH DESCRIPTION -.B pcap_list_tstamp_types() +.BR pcap_list_tstamp_types () is used to get a list of the supported time stamp types of the interface associated with the pcap descriptor. -.B pcap_list_tstamp_types() +.BR pcap_list_tstamp_types () allocates an array to hold the list and sets .I *tstamp_typesp to point to the array. See -.BR pcap-tstamp (@MAN_MISC_INFO@) +.BR \%pcap-tstamp (@MAN_MISC_INFO@) for a list of all the time stamp types. .PP The caller is responsible for freeing the array with -.BR pcap_free_tstamp_types() , +.BR pcap_free_tstamp_types (), which frees the list pointed to by .IR tstamp_types . .SH RETURN VALUE -.B pcap_list_tstamp_types() +.BR pcap_list_tstamp_types () returns the number of time stamp types in the array on success and .B PCAP_ERROR on failure. @@ -65,9 +65,9 @@ one or more types). If .B PCAP_ERROR is returned, -.B pcap_geterr(3PCAP) +.BR pcap_geterr (3PCAP) or -.B pcap_perror(3PCAP) +.BR pcap_perror (3PCAP) may be called with .I p as an argument to fetch or display the error text. @@ -77,5 +77,6 @@ These functions became available in libpcap release 1.2.1. In previous releases, the time stamp type cannot be set; only the default time stamp type offered by a capture source is available. .SH SEE ALSO -pcap(3PCAP), pcap_tstamp_type_val_to_name(3PCAP), -pcap-tstamp(@MAN_MISC_INFO@) +.BR pcap (3PCAP), +.BR pcap_tstamp_type_val_to_name (3PCAP), +.BR \%pcap-tstamp (@MAN_MISC_INFO@) diff --git a/external/bsd/libpcap/dist/pcap_open_dead.3pcap.in b/external/bsd/libpcap/dist/pcap_open_dead.3pcap.in index 97a97f3ac8c0..ced7d6cf1c3e 100644 --- a/external/bsd/libpcap/dist/pcap_open_dead.3pcap.in +++ b/external/bsd/libpcap/dist/pcap_open_dead.3pcap.in @@ -35,18 +35,18 @@ pcap_t *pcap_open_dead_with_tstamp_precision(int linktype, int snaplen, .fi .SH DESCRIPTION .PP -.B pcap_open_dead() +.BR pcap_open_dead () and -.B pcap_open_dead_with_tstamp_precision() +.BR pcap_open_dead_with_tstamp_precision () are used for creating a .B pcap_t structure to use when calling the other functions in libpcap. It is typically used when just using libpcap for compiling BPF code; it can also be used if using -.BR pcap_dump_open(3PCAP) , -.BR pcap_dump(3PCAP) , +.BR pcap_dump_open (3PCAP), +.BR pcap_dump (3PCAP), and -.B pcap_dump_close(3PCAP) +.BR pcap_dump_close (3PCAP) to write a savefile if there is no .B pcap_t that supplies the packets to be written. @@ -60,11 +60,11 @@ specifies the snapshot length for the .BR pcap_t . .PP When -.BR pcap_open_dead_with_tstamp_precision() , +.BR pcap_open_dead_with_tstamp_precision (), is used to create a .B pcap_t for use with -.BR pcap_dump_open() , +.BR pcap_dump_open (), .I precision specifies the time stamp precision for packets; .B PCAP_TSTAMP_PRECISION_MICRO @@ -73,6 +73,13 @@ seconds and microseconds, and .B PCAP_TSTAMP_PRECISION_NANO should be specified if the packets to be written have time stamps in seconds and nanoseconds. Its value does not affect -.BR pcap_compile(3PCAP) . +.BR pcap_compile (3PCAP). +.SH BACKWARD COMPATIBILITY +The +.BR pcap_open_dead_with_tstamp_precision () +function became available in libpcap release 1.5.1. In previous +releases, there was no mechanism to open a savefile for writing with +time stamps given in seconds and nanoseconds. .SH SEE ALSO -pcap(3PCAP), \%pcap-linktype(@MAN_MISC_INFO@) +.BR pcap (3PCAP), +.BR \%pcap-linktype (@MAN_MISC_INFO@) diff --git a/external/bsd/libpcap/dist/pcap_set_immediate_mode.3pcap.in b/external/bsd/libpcap/dist/pcap_set_immediate_mode.3pcap.in index 2fe45c5439f2..95c9cffbded7 100644 --- a/external/bsd/libpcap/dist/pcap_set_immediate_mode.3pcap.in +++ b/external/bsd/libpcap/dist/pcap_set_immediate_mode.3pcap.in @@ -18,7 +18,7 @@ .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" -.TH PCAP_SET_IMMEDIATE_MODE 3PCAP "22 August 2018" +.TH PCAP_SET_IMMEDIATE_MODE 3PCAP "23 August 2018" .SH NAME pcap_set_immediate_mode \- set immediate mode for a not-yet-activated capture handle @@ -32,7 +32,7 @@ int pcap_set_immediate_mode(pcap_t *p, int immediate_mode); .ft .fi .SH DESCRIPTION -.B pcap_set_immediate_mode() +.BR pcap_set_immediate_mode () sets whether immediate mode should be set on a capture handle when the handle is activated. In immediate mode, packets are always delivered as soon as they arrive, with no buffering. @@ -40,8 +40,10 @@ If .I immediate_mode is non-zero, immediate mode will be set, otherwise it will not be set. .SH RETURN VALUE -.B pcap_set_immediate_mode() -returns 0 on success or +.BR pcap_set_immediate_mode () +returns +.B 0 +on success or .B PCAP_ERROR_ACTIVATED if called on a capture handle that has been activated. .SH BACKWARD COMPATIBILITY @@ -54,11 +56,11 @@ immediate mode must be turned on with a .B BIOCIMMEDIATE .BR ioctl (2), as documented in -.BR bpf(@MAN_DEVICES@) , +.BR bpf (@MAN_DEVICES@), on the descriptor returned by -.B pcap_fileno(3PCAP), +.BR pcap_fileno (3PCAP), after -.BR pcap_activate(3PCAP) +.BR pcap_activate (3PCAP) is called; .IP on Solaris 10 and earlier versions of Solaris, immediate mode must be @@ -68,28 +70,30 @@ don't assume it's sufficient); .IP on Digital UNIX/Tru64 UNIX, immediate mode must be turned on by doing a .B BIOCMBIC -.BR ioctl , +.BR ioctl (), as documented in -.BR packetfilter(7) , +.BR packetfilter (7), to clear the .B ENBATCH flag on the descriptor returned by -.B pcap_fileno(3PCAP), +.BR pcap_fileno (3PCAP), after -.BR pcap_activate(3PCAP) +.BR pcap_activate (3PCAP) is called; .IP on Windows, immediate mode must be turned on by calling -.B pcap_setmintocopy() +.BR pcap_setmintocopy () with a size of 0. .PP On Linux, with previous releases of libpcap, capture devices are always in immediate mode; however, in 1.5.0 and later, they are, by default, .B not in immediate mode, so if -.B pcap_set_immediate_mode() +.BR pcap_set_immediate_mode () is available, it should be used. .PP On other platforms, capture devices are always in immediate mode. .SH SEE ALSO -pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP) +.BR pcap (3PCAP), +.BR pcap_create (3PCAP), +.BR pcap_activate (3PCAP) diff --git a/external/bsd/libpcap/dist/pcap_set_protocol_linux.3pcap b/external/bsd/libpcap/dist/pcap_set_protocol_linux.3pcap index 873017ba9886..a891d7492aec 100644 --- a/external/bsd/libpcap/dist/pcap_set_protocol_linux.3pcap +++ b/external/bsd/libpcap/dist/pcap_set_protocol_linux.3pcap @@ -17,7 +17,7 @@ .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" -.TH PCAP_SET_PROTOCOL_LINUX 3PCAP "24 August 2017" +.TH PCAP_SET_PROTOCOL_LINUX 3PCAP "22 August 2018" .SH NAME pcap_set_protocol_linux \- set capture protocol for a not-yet-activated capture handle @@ -32,7 +32,7 @@ int pcap_set_protocol_linux(pcap_t *p, int protocol); .fi .SH DESCRIPTION On network interface devices on Linux, -.B pcap_set_protocol_linux() +.BR 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 @@ -48,21 +48,25 @@ 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(3PCAP) . +.BR pcap_setfilter (3PCAP). .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() +.BR pcap_setfilter () but can be filtered by specifying the socket-layer protocol type using -.BR pcap_set_protocol_linux() . +.BR pcap_set_protocol_linux (). .SH RETURN VALUE -.B pcap_set_protocol_linux() -returns 0 on success or +.BR pcap_set_protocol_linux () +returns +.B 0 +on success or .B PCAP_ERROR_ACTIVATED if called on a capture handle that has been activated. .SH BACKWARD COMPATIBILITY This function became available in libpcap release 1.9.0. .SH SEE ALSO -pcap(3PCAP), pcap_create(3PCAP), pcap_activate(3PCAP) +.BR pcap (3PCAP), +.BR pcap_create (3PCAP), +.BR pcap_activate (3PCAP) diff --git a/external/bsd/libpcap/dist/pcap_set_tstamp_precision.3pcap.in b/external/bsd/libpcap/dist/pcap_set_tstamp_precision.3pcap.in index dc2b4b3d2a5e..1889f43dffae 100644 --- a/external/bsd/libpcap/dist/pcap_set_tstamp_precision.3pcap.in +++ b/external/bsd/libpcap/dist/pcap_set_tstamp_precision.3pcap.in @@ -19,7 +19,7 @@ .\"IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED .\"WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -.TH PCAP_SET_TSTAMP_PRECISION 3PCAP "5 February 2015" +.TH PCAP_SET_TSTAMP_PRECISION 3PCAP "23 August 2018" .SH NAME pcap_set_tstamp_precision \- set the time stamp precision returned in captures @@ -34,22 +34,24 @@ int pcap_set_tstamp_precision(pcap_t *p, int tstamp_precision); .ft .fi .SH DESCRIPTION -.B pcap_set_tstamp_precision() +.BR pcap_set_tstamp_precision () sets the precision of the time stamp desired for packets captured on the pcap descriptor to the type specified by .IR tstamp_precision . It must be called on a pcap descriptor created by -.B pcap_create(3PCAP) +.BR pcap_create (3PCAP) that has not yet been activated by -.BR pcap_activate(3PCAP) . +.BR pcap_activate (3PCAP). Two time stamp precisions are supported, microseconds and nanoseconds. One can use options .B PCAP_TSTAMP_PRECISION_MICRO and .B PCAP_TSTAMP_PRECISION_NANO to request desired precision. By default, time stamps are in microseconds. .SH RETURN VALUE -.B pcap_set_tstamp_precision() -returns 0 on success if the specified time stamp precision is expected to be +.BR pcap_set_tstamp_precision () +returns +.B 0 +on success if the specified time stamp precision is expected to be supported by the capture device, .B PCAP_ERROR_TSTAMP_PRECISION_NOTSUP if the capture device does not support the requested time stamp @@ -61,6 +63,6 @@ This function became available in libpcap release 1.5.1. In previous releases, time stamps from a capture device or savefile are always given in seconds and microseconds. .SH SEE ALSO -pcap(3PCAP), -pcap_get_tstamp_precision(3PCAP), -pcap-tstamp(@MAN_MISC_INFO@) +.BR pcap (3PCAP), +.BR pcap_get_tstamp_precision (3PCAP), +.BR \%pcap-tstamp (@MAN_MISC_INFO@) diff --git a/external/bsd/libpcap/dist/pcap_set_tstamp_type.3pcap.in b/external/bsd/libpcap/dist/pcap_set_tstamp_type.3pcap.in index 9833f46a3c43..cd2dc71ced7d 100644 --- a/external/bsd/libpcap/dist/pcap_set_tstamp_type.3pcap.in +++ b/external/bsd/libpcap/dist/pcap_set_tstamp_type.3pcap.in @@ -18,7 +18,7 @@ .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" -.TH PCAP_SET_TSTAMP_TYPE 3PCAP "22 August 2018" +.TH PCAP_SET_TSTAMP_TYPE 3PCAP "8 September 2019" .SH NAME pcap_set_tstamp_type \- set the time stamp type to be used by a capture device @@ -33,23 +33,25 @@ int pcap_set_tstamp_type(pcap_t *p, int tstamp_type); .ft .fi .SH DESCRIPTION -.B pcap_set_tstamp_type() +.BR pcap_set_tstamp_type () 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 -.B pcap_create(3PCAP) +.BR pcap_create (3PCAP) that has not yet been activated by -.BR pcap_activate(3PCAP) . -.B pcap_list_tstamp_types(3PCAP) +.BR pcap_activate (3PCAP). +.BR pcap_list_tstamp_types (3PCAP) will give a list of the time stamp types supported by a given capture device. See -.BR pcap-tstamp (@MAN_MISC_INFO@) +.BR \%pcap-tstamp (@MAN_MISC_INFO@) for a list of all the time stamp types. .SH RETURN VALUE -.B pcap_set_tstamp_type() -returns 0 on success if the specified time stamp type is expected to be +.BR pcap_set_tstamp_type () +returns +.B 0 +on success if the specified time stamp type is expected to be supported by the capture device, .B PCAP_WARNING_TSTAMP_TYPE_NOTSUP if the specified time stamp type is not supported by the @@ -66,5 +68,5 @@ This function became available in libpcap release 1.2.1. In previous releases, the time stamp type cannot be set; only the default time stamp type offered by a capture source is available. .SH SEE ALSO -pcap(3PCAP), -pcap_tstamp_type_name_to_val(3PCAP) +.BR pcap (3PCAP), +.BR pcap_tstamp_type_name_to_val (3PCAP) diff --git a/external/bsd/libpcap/dist/pflog.h b/external/bsd/libpcap/dist/pflog.h new file mode 100644 index 000000000000..b49d04fc8ac0 --- /dev/null +++ b/external/bsd/libpcap/dist/pflog.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 1982, 1986, 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. + */ + +/* + * pflog headers, at least as they exist now. + */ +#define PFLOG_IFNAMSIZ 16 +#define PFLOG_RULESET_NAME_SIZE 16 + +/* + * Direction values. + */ +#define PF_INOUT 0 +#define PF_IN 1 +#define PF_OUT 2 +#if defined(__OpenBSD__) +#define PF_FWD 3 +#endif + +/* + * Reason values. + */ +#define PFRES_MATCH 0 +#define PFRES_BADOFF 1 +#define PFRES_FRAG 2 +#define PFRES_SHORT 3 +#define PFRES_NORM 4 +#define PFRES_MEMORY 5 +#define PFRES_TS 6 +#define PFRES_CONGEST 7 +#define PFRES_IPOPTIONS 8 +#define PFRES_PROTCKSUM 9 +#define PFRES_BADSTATE 10 +#define PFRES_STATEINS 11 +#define PFRES_MAXSTATES 12 +#define PFRES_SRCLIMIT 13 +#define PFRES_SYNPROXY 14 +#if defined(__FreeBSD__) +#define PFRES_MAPFAILED 15 +#elif defined(__NetBSD__) +#define PFRES_STATELOCKED 15 +#elif defined(__OpenBSD__) +#define PFRES_TRANSLATE 15 +#define PFRES_NOROUTE 16 +#elif defined(__APPLE__) +#define PFRES_DUMMYNET 15 +#endif + +/* + * Action values. + */ +#define PF_PASS 0 +#define PF_DROP 1 +#define PF_SCRUB 2 +#define PF_NOSCRUB 3 +#define PF_NAT 4 +#define PF_NONAT 5 +#define PF_BINAT 6 +#define PF_NOBINAT 7 +#define PF_RDR 8 +#define PF_NORDR 9 +#define PF_SYNPROXY_DROP 10 +#if defined(__FreeBSD__) +#define PF_DEFER 11 +#elif defined(__OpenBSD__) +#define PF_DEFER 11 +#define PF_MATCH 12 +#define PF_DIVERT 13 +#define PF_RT 14 +#define PF_AFRT 15 +#elif defined(__APPLE__) +#define PF_DUMMYNET 11 +#define PF_NODUMMYNET 12 +#define PF_NAT64 13 +#define PF_NONAT64 14 +#endif + +struct pf_addr { + union { + struct in_addr v4; + struct in6_addr v6; + uint8_t addr8[16]; + uint16_t addr16[8]; + uint32_t addr32[4]; + } pfa; /* 128-bit address */ +#define v4 pfa.v4 +#define v6 pfa.v6 +#define addr8 pfa.addr8 +#define addr16 pfa.addr16 +#define addr32 pfa.addr32 +}; + +struct pfloghdr { + uint8_t length; + uint8_t af; + uint8_t action; + uint8_t reason; + char ifname[PFLOG_IFNAMSIZ]; + char ruleset[PFLOG_RULESET_NAME_SIZE]; + uint32_t rulenr; + uint32_t subrulenr; + uint32_t uid; + int32_t pid; + uint32_t rule_uid; + int32_t rule_pid; + uint8_t dir; +#if defined(__OpenBSD__) + uint8_t rewritten; + uint8_t naf; + uint8_t pad[1]; +#else + uint8_t pad[3]; +#endif +#if defined(__FreeBSD__) + uint32_t ridentifier; + uint8_t reserve; + uint8_t pad2[3]; +#elif defined(__OpenBSD__) + struct pf_addr saddr; + struct pf_addr daddr; + uint16_t sport; + uint16_t dport; +#endif +}; + + + diff --git a/external/bsd/libpcap/dist/portability.h b/external/bsd/libpcap/dist/portability.h index 543846e8bd25..84d0778a5c77 100644 --- a/external/bsd/libpcap/dist/portability.h +++ b/external/bsd/libpcap/dist/portability.h @@ -52,7 +52,7 @@ extern "C" { #if defined(_MSC_VER) || defined(__MINGW32__) /* * strncat_s() is supported at least back to Visual - * Studio 2005. + * Studio 2005; we require Visual Studio 2015 or later. */ #define pcap_strlcat(x, y, z) \ strncat_s((x), (z), (y), _TRUNCATE) @@ -70,7 +70,7 @@ extern "C" { #if defined(_MSC_VER) || defined(__MINGW32__) /* * strncpy_s() is supported at least back to Visual - * Studio 2005. + * Studio 2005; we require Visual Studio 2015 or later. */ #define pcap_strlcpy(x, y, z) \ strncpy_s((x), (z), (y), _TRUNCATE) @@ -83,8 +83,6 @@ extern "C" { #endif #ifdef _MSC_VER - #define isascii __isascii - /* * If has been included, and _DEBUG is defined, and * __STDC__ is zero, will define strdup() to call @@ -97,43 +95,9 @@ extern "C" { #endif /* - * On Windows, snprintf(), with that name and with C99 behavior - i.e., - * guaranteeing that the formatted string is null-terminated - didn't - * appear until Visual Studio 2015. Prior to that, the C runtime had - * only _snprintf(), which *doesn't* guarantee that the string is - * null-terminated if it is truncated due to the buffer being too - * small. We therefore can't just define snprintf to be _snprintf - * and define vsnprintf to be _vsnprintf, as we're relying on null- - * termination of strings in all cases. - * - * We also want to allow this to be built with versions of Visual Studio - * prior to VS 2015, so we can't rely on snprintf() being present. - * - * And we want to make sure that, if we support plugins in the future, - * a routine with C99 snprintf() behavior will be available to them. - * We also don't want it to collide with the C library snprintf() if - * there is one. - * - * So we make pcap_snprintf() and pcap_vsnprintf() available, either by - * #defining them to be snprintf or vsnprintf, respectively, or by - * defining our own versions and exporting them. - */ -#ifdef HAVE_SNPRINTF -#define pcap_snprintf snprintf -#else -extern int pcap_snprintf(char *, size_t, PCAP_FORMAT_STRING(const char *), ...) - PCAP_PRINTFLIKE(3, 4); -#endif - -#ifdef HAVE_VSNPRINTF -#define pcap_vsnprintf vsnprintf -#else -extern int pcap_vsnprintf(char *, size_t, const char *, va_list ap); -#endif - -/* - * We also want asprintf(), for some cases where we use it to construct - * dynamically-allocated variable-length strings. + * We want asprintf(), for some cases where we use it to construct + * dynamically-allocated variable-length strings; it's present on + * some, but not all, platforms. */ #ifdef HAVE_ASPRINTF #define pcap_asprintf asprintf @@ -148,6 +112,30 @@ extern int pcap_asprintf(char **, PCAP_FORMAT_STRING(const char *), ...) extern int pcap_vasprintf(char **, const char *, va_list ap); #endif +/* For Solaris before 11. */ +#ifndef timeradd +#define timeradd(a, b, result) \ + do { \ + (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \ + if ((result)->tv_usec >= 1000000) { \ + ++(result)->tv_sec; \ + (result)->tv_usec -= 1000000; \ + } \ + } while (0) +#endif /* timeradd */ +#ifndef timersub +#define timersub(a, b, result) \ + do { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000; \ + } \ + } while (0) +#endif /* timersub */ + #ifdef HAVE_STRTOK_R #define pcap_strtok_r strtok_r #else diff --git a/external/bsd/libpcap/dist/rpcap-protocol.c b/external/bsd/libpcap/dist/rpcap-protocol.c index 692f7c5c0d6b..0cdc0ba323b7 100644 --- a/external/bsd/libpcap/dist/rpcap-protocol.c +++ b/external/bsd/libpcap/dist/rpcap-protocol.c @@ -61,6 +61,8 @@ * * \param sock: the socket we are currently using. * + * \param ssl: if compiled with openssl, the optional ssl handler to use with the above socket. + * * \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 @@ -78,7 +80,7 @@ * error message is returned in the 'errbuf' variable. */ int -rpcap_senderror(SOCKET sock, uint8 ver, unsigned short errcode, const char *error, char *errbuf) +rpcap_senderror(SOCKET sock, SSL *ssl, 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 */ @@ -99,7 +101,7 @@ rpcap_senderror(SOCKET sock, uint8 ver, unsigned short errcode, const char *erro RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errbuf, PCAP_ERRBUF_SIZE)) return -1; - if (sock_send(sock, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) < 0) + if (sock_send(sock, ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) < 0) return -1; return 0; diff --git a/external/bsd/libpcap/dist/rpcap-protocol.h b/external/bsd/libpcap/dist/rpcap-protocol.h index 8ae8b62d13bf..a93b0a8b4328 100644 --- a/external/bsd/libpcap/dist/rpcap-protocol.h +++ b/external/bsd/libpcap/dist/rpcap-protocol.h @@ -132,10 +132,12 @@ * XXX - use the C99 types? Microsoft's newer versions of Visual Studio * support them. */ +#ifndef __HAIKU__ 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 */ +#endif /* Common header for all the RPCAP messages */ struct rpcap_header @@ -154,6 +156,25 @@ struct rpcap_header * Older servers don't provide this; they support only version 0. */ struct rpcap_authreply +{ + uint8 minvers; /* Minimum version supported */ + uint8 maxvers; /* Maximum version supported */ + uint8 pad[2]; /* Pad to 4-byte boundary **/ + uint32 byte_order_magic; /* RPCAP_BYTE_ORDER_MAGIC, in server byte order */ +}; + +/* + * Any resemblance between this and the pcap file magic number + * is purely coincidental, trust me. + */ +#define RPCAP_BYTE_ORDER_MAGIC 0xa1b2c3d4U +#define RPCAP_BYTE_ORDER_MAGIC_SWAPPED 0xd4c3b2a1U + +/* + * Older version of authentication reply, without byte order indication + * and padding. + */ +struct rpcap_authreply_old { uint8 minvers; /* Minimum version supported */ uint8 maxvers; /* Maximum version supported */ @@ -259,7 +280,7 @@ struct rpcap_findalldevs_ifaddr struct rpcap_openreply { int32 linktype; /* Link type */ - int32 tzoff; /* Timezone offset */ + int32 tzoff; /* Timezone offset - not used by newer clients */ }; /* Format of the message that starts a remote capture (startcap command) */ @@ -287,10 +308,14 @@ struct rpcap_startcapreply */ struct rpcap_pkthdr { + /* + * This protocol needs to be updated with a new version before + * 2038-01-19 03:14:07 UTC. + */ 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 len; /* Real length of this packet (off wire) */ uint32 npkt; /* Ordinal number of the packet (i.e. the first one captured has '1', the second one '2', etc) */ }; @@ -302,7 +327,7 @@ struct rpcap_filter 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 */ +/* Structure that keeps a single BPF instruction; it is repeated 'ninsn' times according to the 'rpcap_filterbpf' header */ struct rpcap_filterbpf_insn { uint16 code; /* opcode of the instruction */ @@ -346,17 +371,17 @@ struct rpcap_sampling */ #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_ERROR 0x01 /* Message that keeps an error notification */ +#define RPCAP_MSG_FINDALLIF_REQ 0x02 /* Request to list all the remote interfaces */ +#define RPCAP_MSG_OPEN_REQ 0x03 /* Request to open a remote device */ +#define RPCAP_MSG_STARTCAP_REQ 0x04 /* Request to start a capture on a remote device */ +#define RPCAP_MSG_UPDATEFILTER_REQ 0x05 /* Send a compiled filter into the remote device */ +#define RPCAP_MSG_CLOSE 0x06 /* Close the connection with the remote peer */ +#define RPCAP_MSG_PACKET 0x07 /* This is a 'data' message, which carries a network packet */ +#define RPCAP_MSG_AUTH_REQ 0x08 /* Message that keeps the authentication parameters */ +#define RPCAP_MSG_STATS_REQ 0x09 /* It requires to have network statistics */ +#define RPCAP_MSG_ENDCAP_REQ 0x0A /* Stops the current capture, keeping the device open */ +#define RPCAP_MSG_SETSAMPLING_REQ 0x0B /* 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 */ @@ -415,9 +440,10 @@ struct rpcap_sampling *********************************************************/ #include "sockutils.h" +#include "sslutils.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); +extern int rpcap_senderror(SOCKET sock, SSL *ssl, uint8 ver, uint16 errcode, const char *error, char *errbuf); #endif diff --git a/external/bsd/libpcap/dist/rpcapd/CMakeLists.txt b/external/bsd/libpcap/dist/rpcapd/CMakeLists.txt index 1821c8566ed4..8b30be3c7c4c 100644 --- a/external/bsd/libpcap/dist/rpcapd/CMakeLists.txt +++ b/external/bsd/libpcap/dist/rpcapd/CMakeLists.txt @@ -50,8 +50,8 @@ if(WIN32 OR ((CMAKE_USE_PTHREADS_INIT OR PTHREADS_FOUND) AND HAVE_CRYPT)) if(WIN32) set(RPCAPD_EXTRA_SOURCES win32-svc.c + ${pcap_SOURCE_DIR}/charconv.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) @@ -63,6 +63,7 @@ if(WIN32 OR ((CMAKE_USE_PTHREADS_INIT OR PTHREADS_FOUND) AND HAVE_CRYPT)) rpcapd.c ${pcap_SOURCE_DIR}/rpcap-protocol.c ${pcap_SOURCE_DIR}/sockutils.c + ${pcap_SOURCE_DIR}/sslutils.c ${pcap_SOURCE_DIR}/fmtutils.c ${RPCAPD_EXTRA_SOURCES} ) @@ -71,6 +72,11 @@ if(WIN32 OR ((CMAKE_USE_PTHREADS_INIT OR PTHREADS_FOUND) AND HAVE_CRYPT)) set_target_properties(rpcapd PROPERTIES COMPILE_FLAGS ${C_ADDITIONAL_FLAGS}) endif() + if(NOT "${SANITIZER_FLAGS}" STREQUAL "") + set_target_properties(rpcapd PROPERTIES + LINK_FLAGS "${SANITIZER_FLAGS}") + endif() + # # By default, build rpcapd universal with the appropriate set of # architectures for the OS on which we're doing the build. @@ -129,11 +135,32 @@ if(WIN32 OR ((CMAKE_USE_PTHREADS_INIT OR PTHREADS_FOUND) AND HAVE_CRYPT)) set(MANFILE_EXPAND rpcapd-config.manfile.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) + if(WIN32) + # + # XXX - where should the install target put rpcapd on Windows? + # + # Note that if an installer package is being produced + # from the results of the build, the installer package + # will determine where it goes. + # + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + install(TARGETS rpcapd DESTINATION bin/amd64) + else(CMAKE_SIZEOF_VOID_P EQUAL 8) + install(TARGETS rpcapd DESTINATION bin) + endif(CMAKE_SIZEOF_VOID_P EQUAL 8) + else(WIN32) + # + # On UN*X, we put it in the sbin directory. + # + # XXX - the Linux Filesystem Hierarchy Standard says /usr/sbin + # is for daemons, but some other systems use /usr/libexec instead. + # However, since some users might, instead of having rpcapd be + # launched by inetd/xinetd/launchd/systemd, just run it on a + # machine when remote capture is to be done, a case can be made + # for the sbin directory even on systems with /usr/libexec. + # + install(TARGETS rpcapd DESTINATION ${CMAKE_INSTALL_SBINDIR}) + endif(WIN32) # On UN*X, and on Windows when not using MSVC, generate process man # pages and arrange that they be installed. diff --git a/external/bsd/libpcap/dist/rpcapd/Makefile.in b/external/bsd/libpcap/dist/rpcapd/Makefile.in index 88e632a26250..b0145cf23612 100644 --- a/external/bsd/libpcap/dist/rpcapd/Makefile.in +++ b/external/bsd/libpcap/dist/rpcapd/Makefile.in @@ -1,5 +1,5 @@ # Copyright (c) 1993, 1994, 1995, 1996 -# The Regents of the University of California. All rights reserved. +# 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 @@ -38,6 +38,7 @@ mandir = @mandir@ # VPATH srcdir = @srcdir@ +top_srcdir = @top_srcdir@ VPATH = @srcdir@ # @@ -84,7 +85,7 @@ SRC = daemon.c \ log.c \ rpcapd.c -OBJ = $(SRC:.c=.o) ../rpcap-protocol.o ../sockutils.o ../fmtutils.o +OBJ = $(SRC:.c=.o) ../rpcap-protocol.o ../sockutils.o ../fmtutils.o ../sslutils.o PUBHDR = HDR = $(PUBHDR) log.h @@ -138,4 +139,4 @@ tags: $(TAGFILES) ctags -wtd $(TAGFILES) depend: - ../$(MKDEP) -c "$(CC)" -m "$(DEPENDENCY_CFLAG)" $(CFLAGS) $(DEFS) $(INCLS) $(SRC) + $(MKDEP) -c "$(CC)" -m "$(DEPENDENCY_CFLAG)" -s "$(srcdir)" $(CFLAGS) $(DEFS) $(INCLS) $(SRC) diff --git a/external/bsd/libpcap/dist/rpcapd/daemon.c b/external/bsd/libpcap/dist/rpcapd/daemon.c index 209dba225ea6..9b0f82851526 100644 --- a/external/bsd/libpcap/dist/rpcapd/daemon.c +++ b/external/bsd/libpcap/dist/rpcapd/daemon.c @@ -39,6 +39,7 @@ #include // for the errno variable #include // for malloc(), free(), ... #include // for strlen(), ... +#include // for INT_MAX #ifdef _WIN32 #include // for threads @@ -64,6 +65,11 @@ #include "daemon.h" #include "log.h" +#ifdef HAVE_OPENSSL +#include +#include "sslutils.h" +#endif + // // Timeout, in seconds, when we're waiting for a client to send us an // authentication request; if they don't send us a request within that @@ -90,6 +96,7 @@ struct daemon_slpars { SOCKET sockctrl; //!< SOCKET ID of the control connection + SSL *ssl; //!< Optional SSL handler for the controlling sockets int isactive; //!< Not null if the daemon has to run in active mode int nullAuthAllowed; //!< '1' if we permit NULL authentication, '0' otherwise }; @@ -105,6 +112,7 @@ struct daemon_slpars struct session { SOCKET sockctrl; SOCKET sockdata; + SSL *ctrl_ssl, *data_ssl; // optional SSL handlers for sockctrl and sockdata. uint8 protocol_version; pcap_t *fp; unsigned int TotCapt; @@ -117,7 +125,7 @@ struct session { }; // Locally defined functions -static int daemon_msg_err(SOCKET sockctrl, uint32 plen); +static int daemon_msg_err(SOCKET sockctrl, SSL *, uint32 plen); static int daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen); static int daemon_AuthUserPwd(char *username, char *password, char *errbuf); @@ -128,13 +136,13 @@ static int daemon_msg_open_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, char *source, size_t sourcelen); static int daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, char *source, struct session **sessionp, - struct rpcap_sampling *samp_param); + struct rpcap_sampling *samp_param, int uses_ssl); static int daemon_msg_endcap_req(uint8 ver, struct daemon_slpars *pars, struct session *session); static int daemon_msg_updatefilter_req(uint8 ver, struct daemon_slpars *pars, struct session *session, uint32 plen); -static int daemon_unpackapplyfilter(SOCKET sockctrl, struct session *session, uint32 *plenp, char *errbuf); +static int daemon_unpackapplyfilter(SOCKET sockctrl, SSL *, struct session *session, uint32 *plenp, char *errbuf); static int daemon_msg_stats_req(uint8 ver, struct daemon_slpars *pars, struct session *session, uint32 plen, struct pcap_stat *stats, @@ -151,21 +159,69 @@ static void *daemon_thrdatamain(void *ptr); static void noop_handler(int sign); #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); +static int rpcapd_recv_msg_header(SOCKET sock, SSL *, struct rpcap_header *headerp); +static int rpcapd_recv(SOCKET sock, SSL *, char *buffer, size_t toread, uint32 *plen, char *errmsgbuf); +static int rpcapd_discard(SOCKET sock, SSL *, uint32 len); static void session_close(struct session *); +// +// TLS record layer header; used when processing the first message from +// the client, in case we aren't doing TLS but they are. +// +struct tls_record_header { + uint8 type; // ContentType - will be 22, for Handshake + uint8 version_major; // TLS protocol major version + uint8 version_injor; // TLS protocol minor version + // This is *not* aligned on a 2-byte boundary; we just + // declare it as two bytes. Don't assume any particular + // compiler's mechanism for saying "packed"! + uint8 length_hi; // Upper 8 bits of payload length + uint8 length_lo; // Low 8 bits of payload length +}; + +#define TLS_RECORD_HEADER_LEN 5 // Don't use sizeof in case it's padded + +#define TLS_RECORD_TYPE_ALERT 21 +#define TLS_RECORD_TYPE_HANDSHAKE 22 + +// +// TLS alert message. +// +struct tls_alert { + uint8 alert_level; + uint8 alert_description; +}; + +#define TLS_ALERT_LEN 2 + +#define TLS_ALERT_LEVEL_FATAL 2 +#define TLS_ALERT_HANDSHAKE_FAILURE 40 + static int is_url(const char *source); +/* + * Maximum sizes for fixed-bit-width values. + */ +#ifndef UINT16_MAX +#define UINT16_MAX 65535U +#endif + +#ifndef UINT32_MAX +#define UINT32_MAX 4294967295U +#endif + int daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, - int nullAuthAllowed) + int nullAuthAllowed, int uses_ssl) { + uint8 first_octet; + struct tls_record_header tls_header; + struct tls_alert tls_alert; 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 host_port_check_status; + SSL *ssl = NULL; int nrecv; struct rpcap_header header; // RPCAP message general header uint32 plen; // payload length from header @@ -192,8 +248,177 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, *errbuf = 0; // Initialize errbuf + // + // Peek into the socket to determine whether the client sent us + // a TLS handshake message or a non-TLS rpcapd message. + // + // The first byte of an rpcapd request is the version number; + // the first byte of a TLS handshake message is 22. The + // first request to an rpcapd server must be an authentication + // request or a close request, and must have a version number + // of 0, so it will be possible to distinguish between an + // initial plaintext request to a server and an initial TLS + // handshake message. + // + nrecv = sock_recv(sockctrl, NULL, (char *)&first_octet, 1, + SOCK_EOF_ISNT_ERROR|SOCK_MSG_PEEK, errbuf, PCAP_ERRBUF_SIZE); + if (nrecv == -1) + { + // Fatal error. + rpcapd_log(LOGPRIO_ERROR, "Peek from client failed: %s", errbuf); + goto end; + } + if (nrecv == 0) + { + // Client closed the connection. + goto end; + } + +#ifdef HAVE_OPENSSL + // + // We have to upgrade to TLS as soon as possible, so that the + // whole protocol goes through the encrypted tunnel, including + // early error messages. + // + // Even in active mode, the other end has to initiate the TLS + // handshake as we still are the server as far as TLS is concerned, + // so we don't check isactive. + // + if (uses_ssl) + { + // + // We're expecting a TLS handshake message. If this + // isn't one, assume it's a non-TLS rpcapd message. + // + // The first octet of a TLS handshake is + // TLS_RECORD_TYPE_HANDSHAKE. + // + if (first_octet != TLS_RECORD_TYPE_HANDSHAKE) + { + // + // We assume this is a non-TLS rpcapd message. + // + // Read the message header from the client. + // + nrecv = rpcapd_recv_msg_header(sockctrl, NULL, &header); + if (nrecv == -1) + { + // Fatal error. + goto end; + } + if (nrecv == -2) + { + // Client closed the connection. + goto end; + } + plen = header.plen; + + // Discard the rest of the message. + if (rpcapd_discard(sockctrl, NULL, plen) == -1) + { + // Network error. + goto end; + } + + // + // Send an authentication error, indicating + // that we require TLS. + // + if (rpcap_senderror(sockctrl, NULL, header.ver, + PCAP_ERR_TLS_REQUIRED, + "TLS is required by this server", errbuf) == -1) + { + // That failed; log a message and give up. + rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); + goto end; + } + + // Shut the session down. + goto end; + } + ssl = ssl_promotion(1, sockctrl, errbuf, PCAP_ERRBUF_SIZE); + if (! ssl) + { + rpcapd_log(LOGPRIO_ERROR, "TLS handshake on control connection failed: %s", + errbuf); + goto end; + } + } + else +#endif + { + // + // We're expecting a non-TLS rpcapd message. If this + // looks, instead, like a TLS handshake message, send + // a TLS handshake_failed alert. + // + // The first octet of a TLS handshake is + // TLS_RECORD_TYPE_HANDSHAKE. + // + if (first_octet == TLS_RECORD_TYPE_HANDSHAKE) + { + // + // TLS handshake. + // Read the record header. + // + nrecv = sock_recv(sockctrl, ssl, (char *) &tls_header, + sizeof tls_header, SOCK_RECEIVEALL_YES|SOCK_EOF_ISNT_ERROR, + errbuf, PCAP_ERRBUF_SIZE); + if (nrecv == -1) + { + // Network error. + rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf); + goto end; + } + if (nrecv == 0) + { + // Immediate EOF + goto end; + } + plen = (tls_header.length_hi << 8U) | tls_header.length_lo; + + // Discard the rest of the message. + if (rpcapd_discard(sockctrl, NULL, plen) == -1) + { + // Network error. + goto end; + } + + // + // Send a TLS handshake failure alert. + // Use the same version the client sent us. + // + tls_header.type = TLS_RECORD_TYPE_ALERT; + tls_header.length_hi = 0; + tls_header.length_lo = TLS_ALERT_LEN; + + if (sock_send(sockctrl, NULL, (char *) &tls_header, + TLS_RECORD_HEADER_LEN, errbuf, PCAP_ERRBUF_SIZE) == -1) + { + // That failed; log a message and give up. + rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); + goto end; + } + + tls_alert.alert_level = TLS_ALERT_LEVEL_FATAL; + tls_alert.alert_description = TLS_ALERT_HANDSHAKE_FAILURE; + if (sock_send(sockctrl, NULL, (char *) &tls_alert, + TLS_ALERT_LEN, errbuf, PCAP_ERRBUF_SIZE) == -1) + { + // That failed; log a message and give up. + rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); + goto end; + } + // + // Give up anyway. + // + goto end; + } + } + // Set parameters structure pars.sockctrl = sockctrl; + pars.ssl = ssl; pars.isactive = isactive; // active mode pars.nullAuthAllowed = nullAuthAllowed; @@ -224,8 +449,9 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, if (getpeername(pars.sockctrl, (struct sockaddr *)&from, &fromlen) == -1) { - sock_geterror("getpeername()", errmsgbuf, PCAP_ERRBUF_SIZE); - if (rpcap_senderror(pars.sockctrl, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1) + sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE, + "getpeername() failed"); + if (rpcap_senderror(pars.sockctrl, pars.ssl, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1) rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); goto end; } @@ -248,7 +474,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, // // Sorry, we can't let you in. // - if (rpcap_senderror(pars.sockctrl, 0, PCAP_ERR_HOSTNOAUTH, errmsgbuf, errbuf) == -1) + if (rpcap_senderror(pars.sockctrl, pars.ssl, 0, PCAP_ERR_HOSTNOAUTH, errmsgbuf, errbuf) == -1) rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); goto end; } @@ -295,11 +521,12 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, FD_SET(pars.sockctrl, &rfds); - retval = select(pars.sockctrl + 1, &rfds, NULL, NULL, &tv); + retval = select((int)pars.sockctrl + 1, &rfds, NULL, NULL, &tv); if (retval == -1) { - sock_geterror("select() failed", errmsgbuf, PCAP_ERRBUF_SIZE); - if (rpcap_senderror(pars.sockctrl, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1) + sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE, + "select() failed"); + if (rpcap_senderror(pars.sockctrl, pars.ssl, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1) rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); goto end; } @@ -308,7 +535,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, // So, this was a fake connection. Drop it down if (retval == 0) { - if (rpcap_senderror(pars.sockctrl, 0, PCAP_ERR_INITTIMEOUT, "The RPCAP initial timeout has expired", errbuf) == -1) + if (rpcap_senderror(pars.sockctrl, pars.ssl, 0, PCAP_ERR_INITTIMEOUT, "The RPCAP initial timeout has expired", errbuf) == -1) rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); goto end; } @@ -317,7 +544,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, // // Read the message header from the client. // - nrecv = rpcapd_recv_msg_header(pars.sockctrl, &header); + nrecv = rpcapd_recv_msg_header(pars.sockctrl, pars.ssl, &header); if (nrecv == -1) { // Fatal error. @@ -340,7 +567,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, // // Send it back to them with their version. // - if (rpcap_senderror(pars.sockctrl, header.ver, + if (rpcap_senderror(pars.sockctrl, pars.ssl, header.ver, PCAP_ERR_WRONGVER, "RPCAP version in requests in the authentication phase must be 0", errbuf) == -1) @@ -352,7 +579,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, // Discard the rest of the message and drop the // connection. - (void)rpcapd_discard(pars.sockctrl, plen); + (void)rpcapd_discard(pars.sockctrl, pars.ssl, plen); goto end; } @@ -385,7 +612,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, // Discard the rest of the message, if // there is anything more. // - (void)rpcapd_discard(pars.sockctrl, plen); + (void)rpcapd_discard(pars.sockctrl, pars.ssl, plen); // We're done with this client. goto end; @@ -397,7 +624,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, // 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, plen); + (void)daemon_msg_err(pars.sockctrl, pars.ssl, plen); goto end; case RPCAP_MSG_FINDALLIF_REQ: @@ -414,20 +641,21 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, 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); + 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); + snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Message of type %u sent before authentication was completed", header.type); } - if (rpcap_senderror(pars.sockctrl, header.ver, - PCAP_ERR_WRONGMSG, errmsgbuf, errbuf) == -1) + if (rpcap_senderror(pars.sockctrl, pars.ssl, + header.ver, 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, plen) == -1) + if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1) { // Network error. goto end; @@ -449,20 +677,21 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, 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); + 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); + snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message of type %u received from client", header.type); } - if (rpcap_senderror(pars.sockctrl, header.ver, - PCAP_ERR_WRONGMSG, errmsgbuf, errbuf) == -1) + if (rpcap_senderror(pars.sockctrl, pars.ssl, + header.ver, 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, plen) == -1) + if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1) { // Fatal error. goto end; @@ -473,15 +702,16 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, // // Unknown message type. // - pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Unknown message type %u", header.type); - if (rpcap_senderror(pars.sockctrl, header.ver, - PCAP_ERR_WRONGMSG, errmsgbuf, errbuf) == -1) + snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Unknown message type %u", header.type); + if (rpcap_senderror(pars.sockctrl, pars.ssl, + header.ver, 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, plen) == -1) + if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1) { // Fatal error. goto end; @@ -519,7 +749,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, // // 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)))) + if ((!pars.isactive) && (session == NULL || session->sockdata == 0)) { // Check for the initial timeout FD_ZERO(&rfds); @@ -528,13 +758,18 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, tv.tv_usec = 0; FD_SET(pars.sockctrl, &rfds); - - retval = select(pars.sockctrl + 1, &rfds, NULL, NULL, &tv); +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + retval = 1; +#else + retval = select((int)pars.sockctrl + 1, &rfds, NULL, NULL, &tv); +#endif if (retval == -1) { - sock_geterror("select() failed", errmsgbuf, PCAP_ERRBUF_SIZE); - if (rpcap_senderror(pars.sockctrl, 0, - PCAP_ERR_NETW, errmsgbuf, errbuf) == -1) + sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE, + "select() failed"); + if (rpcap_senderror(pars.sockctrl, pars.ssl, + 0, PCAP_ERR_NETW, + errmsgbuf, errbuf) == -1) rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); goto end; } @@ -543,8 +778,8 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, // So, this was a fake connection. Drop it down if (retval == 0) { - if (rpcap_senderror(pars.sockctrl, 0, - PCAP_ERR_INITTIMEOUT, + if (rpcap_senderror(pars.sockctrl, pars.ssl, + 0, PCAP_ERR_INITTIMEOUT, "The RPCAP initial timeout has expired", errbuf) == -1) rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); @@ -555,7 +790,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, // // Read the message header from the client. // - nrecv = rpcapd_recv_msg_header(pars.sockctrl, &header); + nrecv = rpcapd_recv_msg_header(pars.sockctrl, pars.ssl, &header); if (nrecv == -1) { // Fatal error. @@ -581,7 +816,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, // so they don't reject it as having the wrong // version. // - if (rpcap_senderror(pars.sockctrl, + if (rpcap_senderror(pars.sockctrl, pars.ssl, header.ver, PCAP_ERR_WRONGVER, "RPCAP version in message isn't supported by the server", errbuf) == -1) @@ -592,7 +827,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, } // Discard the rest of the message. - (void)rpcapd_discard(pars.sockctrl, plen); + (void)rpcapd_discard(pars.sockctrl, pars.ssl, plen); // Give up on them. goto end; } @@ -601,7 +836,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, { case RPCAP_MSG_ERROR: // The other endpoint reported an error { - (void)daemon_msg_err(pars.sockctrl, plen); + (void)daemon_msg_err(pars.sockctrl, pars.ssl, plen); // Do nothing; just exit; the error code is already into the errbuf // XXX - actually exit.... break; @@ -647,7 +882,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, { // They never told us what device // to capture on! - if (rpcap_senderror(pars.sockctrl, + if (rpcap_senderror(pars.sockctrl, pars.ssl, header.ver, PCAP_ERR_STARTCAPTURE, "No capture device was specified", @@ -658,7 +893,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); goto end; } - if (rpcapd_discard(pars.sockctrl, plen) == -1) + if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1) { goto end; } @@ -666,7 +901,8 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, } if (daemon_msg_startcap_req(header.ver, &pars, - plen, source, &session, &samp_param) == -1) + plen, source, &session, &samp_param, + uses_ssl) == -1) { // Fatal error; a message has // been logged, so just give up. @@ -689,8 +925,9 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, } else { - if (rpcap_senderror(pars.sockctrl, - header.ver, PCAP_ERR_UPDATEFILTER, + if (rpcap_senderror(pars.sockctrl, pars.ssl, + header.ver, + PCAP_ERR_UPDATEFILTER, "Device not opened. Cannot update filter", errbuf) == -1) { @@ -757,8 +994,9 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, } else { - rpcap_senderror(pars.sockctrl, - header.ver, PCAP_ERR_ENDCAPTURE, + rpcap_senderror(pars.sockctrl, pars.ssl, + header.ver, + PCAP_ERR_ENDCAPTURE, "Device not opened. Cannot close the capture", errbuf); } @@ -784,7 +1022,8 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, // 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, header.ver, + if (rpcap_senderror(pars.sockctrl, pars.ssl, + header.ver, PCAP_ERR_WRONGMSG, "RPCAP_MSG_AUTH_REQ request sent after authentication was completed", errbuf) == -1) @@ -793,7 +1032,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, goto end; } // Discard the rest of the message. - if (rpcapd_discard(pars.sockctrl, plen) == -1) + if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1) { // Fatal error. goto end; @@ -816,21 +1055,22 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, 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); + 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); + snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message of type %u received from client", header.type); } - if (rpcap_senderror(pars.sockctrl, header.ver, - PCAP_ERR_WRONGMSG, errmsgbuf, errbuf) == -1) + if (rpcap_senderror(pars.sockctrl, pars.ssl, + header.ver, 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, plen) == -1) + if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1) { // Fatal error. goto end; @@ -842,15 +1082,16 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, // 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, header.ver, - PCAP_ERR_WRONGMSG, errbuf, errmsgbuf) == -1) + snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Unknown message type %u", header.type); + if (rpcap_senderror(pars.sockctrl, pars.ssl, + header.ver, 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, plen) == -1) + if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1) { // Fatal error. goto end; @@ -870,6 +1111,21 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, session = NULL; } + if (passiveClients) { + free(passiveClients); + } + // + // Finish using the SSL handle for the control socket, if we + // have an SSL connection, and close the control socket. + // +#ifdef HAVE_OPENSSL + if (ssl) + { + // Finish using the SSL handle for the socket. + // This must be done *before* the socket is closed. + ssl_finish(ssl); + } +#endif sock_close(sockctrl, NULL, 0); // Print message and return @@ -882,7 +1138,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, * This handles the RPCAP_MSG_ERR message. */ static int -daemon_msg_err(SOCKET sockctrl, uint32 plen) +daemon_msg_err(SOCKET sockctrl, SSL *ssl, uint32 plen) { char errbuf[PCAP_ERRBUF_SIZE]; char remote_errbuf[PCAP_ERRBUF_SIZE]; @@ -893,7 +1149,7 @@ daemon_msg_err(SOCKET sockctrl, uint32 plen) * 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, + if (sock_recv(sockctrl, ssl, remote_errbuf, PCAP_ERRBUF_SIZE - 1, SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, PCAP_ERRBUF_SIZE) == -1) { @@ -901,7 +1157,7 @@ daemon_msg_err(SOCKET sockctrl, uint32 plen) rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf); return -1; } - if (rpcapd_discard(sockctrl, plen - (PCAP_ERRBUF_SIZE - 1)) == -1) + if (rpcapd_discard(sockctrl, ssl, plen - (PCAP_ERRBUF_SIZE - 1)) == -1) { // Network error. return -1; @@ -919,7 +1175,7 @@ daemon_msg_err(SOCKET sockctrl, uint32 plen) } else { - if (sock_recv(sockctrl, remote_errbuf, plen, + if (sock_recv(sockctrl, ssl, remote_errbuf, plen, SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, PCAP_ERRBUF_SIZE) == -1) { @@ -971,7 +1227,7 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen) int sendbufidx = 0; // index which keeps the number of bytes currently buffered struct rpcap_authreply *authreply; // authentication reply message - status = rpcapd_recv(pars->sockctrl, (char *) &auth, sizeof(struct rpcap_auth), &plen, errmsgbuf); + status = rpcapd_recv(pars->sockctrl, pars->ssl, (char *) &auth, sizeof(struct rpcap_auth), &plen, errmsgbuf); if (status == -1) { return -1; @@ -988,10 +1244,10 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen) if (!pars->nullAuthAllowed) { // Send the client an error reply. - pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, + snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Authentication failed; NULL authentication not permitted."); - if (rpcap_senderror(pars->sockctrl, 0, - PCAP_ERR_AUTH_FAILED, errmsgbuf, errbuf) == -1) + if (rpcap_senderror(pars->sockctrl, pars->ssl, + 0, PCAP_ERR_AUTH_FAILED, errmsgbuf, errbuf) == -1) { // That failed; log a message and give up. rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); @@ -1015,7 +1271,7 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen) PCAP_ERRBUF_SIZE, errno, "malloc() failed"); goto error; } - status = rpcapd_recv(pars->sockctrl, username, usernamelen, &plen, errmsgbuf); + status = rpcapd_recv(pars->sockctrl, pars->ssl, username, usernamelen, &plen, errmsgbuf); if (status == -1) { free(username); @@ -1037,7 +1293,7 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen) free(username); goto error; } - status = rpcapd_recv(pars->sockctrl, passwd, passwdlen, &plen, errmsgbuf); + status = rpcapd_recv(pars->sockctrl, pars->ssl, passwd, passwdlen, &plen, errmsgbuf); if (status == -1) { free(username); @@ -1060,8 +1316,8 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen) // free(username); free(passwd); - if (rpcap_senderror(pars->sockctrl, 0, - PCAP_ERR_AUTH_FAILED, errmsgbuf, errbuf) == -1) + if (rpcap_senderror(pars->sockctrl, pars->ssl, + 0, PCAP_ERR_AUTH_FAILED, errmsgbuf, errbuf) == -1) { // That failed; log a message and give up. rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); @@ -1088,10 +1344,10 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen) } default: - pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, + snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Authentication type not recognized."); - if (rpcap_senderror(pars->sockctrl, 0, - PCAP_ERR_AUTH_TYPE_NOTSUP, errmsgbuf, errbuf) == -1) + if (rpcap_senderror(pars->sockctrl, pars->ssl, + 0, PCAP_ERR_AUTH_TYPE_NOTSUP, errmsgbuf, errbuf) == -1) { // That failed; log a message and give up. rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); @@ -1115,22 +1371,27 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen) goto error; // - // Indicate to our peer what versions we support. + // Indicate to our peer what versions we support and what our + // version of the byte-order magic is (which will tell the + // client whether our byte order differs from theirs, in which + // case they will need to byte-swap some fields in some + // link-layer types' headers). // memset(authreply, 0, sizeof(struct rpcap_authreply)); authreply->minvers = RPCAP_MIN_VERSION; authreply->maxvers = RPCAP_MAX_VERSION; + authreply->byte_order_magic = RPCAP_BYTE_ORDER_MAGIC; // Send the reply. - if (sock_send(pars->sockctrl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) + if (sock_send(pars->sockctrl, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) { - // That failed; log a messsage and give up. + // 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, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) { return -1; } @@ -1138,8 +1399,8 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen) return 0; error: - if (rpcap_senderror(pars->sockctrl, 0, PCAP_ERR_AUTH, errmsgbuf, - errbuf) == -1) + if (rpcap_senderror(pars->sockctrl, pars->ssl, 0, PCAP_ERR_AUTH, + errmsgbuf, errbuf) == -1) { // That failed; log a message and give up. rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); @@ -1148,7 +1409,7 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen) error_noreply: // Check if all the data has been read; if not, discard the data in excess - if (rpcapd_discard(pars->sockctrl, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) { return -1; } @@ -1184,7 +1445,7 @@ daemon_AuthUserPwd(char *username, char *password, char *errbuf) if (LogonUser(username, ".", password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &Token) == 0) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed"); + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed"); error = GetLastError(); if (error != ERROR_LOGON_FAILURE) { @@ -1201,7 +1462,7 @@ daemon_AuthUserPwd(char *username, char *password, char *errbuf) // I didn't test it. if (ImpersonateLoggedOnUser(Token) == 0) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed"); + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed"); pcap_fmt_errmsg_for_win32_err(errmsgbuf, PCAP_ERRBUF_SIZE, GetLastError(), "ImpersonateLoggedOnUser() failed"); rpcapd_log(LOGPRIO_ERROR, "%s", errmsgbuf); @@ -1216,7 +1477,7 @@ daemon_AuthUserPwd(char *username, char *password, char *errbuf) /* * See * - * http://www.unixpapa.com/incnote/passwd.html + * https://www.unixpapa.com/incnote/passwd.html * * We use the Solaris/Linux shadow password authentication if * we have getspnam(), otherwise we just do traditional @@ -1243,7 +1504,7 @@ daemon_AuthUserPwd(char *username, char *password, char *errbuf) // This call is needed to get the uid if ((user = getpwnam(username)) == NULL) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed"); + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed"); return -1; } @@ -1251,7 +1512,7 @@ daemon_AuthUserPwd(char *username, char *password, char *errbuf) // 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"); + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed"); return -1; } user_password = usersp->sp_pwdp; @@ -1279,7 +1540,7 @@ daemon_AuthUserPwd(char *username, char *password, char *errbuf) if (crypt_password == NULL) { error = errno; - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed"); + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed"); if (error == 0) { // It didn't set errno. @@ -1294,7 +1555,7 @@ daemon_AuthUserPwd(char *username, char *password, char *errbuf) } if (strcmp(user_password, crypt_password) != 0) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed"); + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed"); return -1; } @@ -1324,6 +1585,21 @@ daemon_AuthUserPwd(char *username, char *password, char *errbuf) } +/* + * Make sure that the reply length won't overflow 32 bits if we add the + * specified amount to it. If it won't, add that amount to it. + * + * We check whether replylen + itemlen > UINT32_MAX, but subtract itemlen + * from both sides, to prevent overflow. + */ +#define CHECK_AND_INCREASE_REPLY_LEN(itemlen) \ + if (replylen > UINT32_MAX - (itemlen)) { \ + pcap_strlcpy(errmsgbuf, "Reply length doesn't fit in 32 bits", \ + sizeof (errmsgbuf)); \ + goto error; \ + } \ + replylen += (uint32)(itemlen) + static int daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen) { @@ -1334,12 +1610,11 @@ daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen) 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 uint32 replylen; // length of reply payload 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, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) { // Network error. return -1; @@ -1351,7 +1626,8 @@ daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen) if (alldevs == NULL) { - if (rpcap_senderror(pars->sockctrl, ver, PCAP_ERR_NOREMOTEIF, + if (rpcap_senderror(pars->sockctrl, pars->ssl, ver, + 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) @@ -1369,13 +1645,30 @@ daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen) { nif++; - if (d->description) - replylen += strlen(d->description); - if (d->name) - replylen += strlen(d->name); + if (d->description) { + size_t stringlen = strlen(d->description); + if (stringlen > UINT16_MAX) { + pcap_strlcpy(errmsgbuf, + "Description length doesn't fit in 16 bits", + sizeof (errmsgbuf)); + goto error; + } + CHECK_AND_INCREASE_REPLY_LEN(stringlen); + } + if (d->name) { + size_t stringlen = strlen(d->name); + if (stringlen > UINT16_MAX) { + pcap_strlcpy(errmsgbuf, + "Name length doesn't fit in 16 bits", + sizeof (errmsgbuf)); + goto error; + } + CHECK_AND_INCREASE_REPLY_LEN(stringlen); + } - replylen += sizeof(struct rpcap_findalldevs_if); + CHECK_AND_INCREASE_REPLY_LEN(sizeof(struct rpcap_findalldevs_if)); + uint16_t naddrs = 0; for (address = d->addresses; address != NULL; address = address->next) { /* @@ -1387,7 +1680,14 @@ daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen) #ifdef AF_INET6 case AF_INET6: #endif - replylen += (sizeof(struct rpcap_sockaddr) * 4); + CHECK_AND_INCREASE_REPLY_LEN(sizeof(struct rpcap_sockaddr) * 4); + if (naddrs == UINT16_MAX) { + pcap_strlcpy(errmsgbuf, + "Number of interfaces doesn't fit in 16 bits", + sizeof (errmsgbuf)); + goto error; + } + naddrs++; break; default: @@ -1396,7 +1696,7 @@ daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen) } } - // RPCAP findalldevs command + // RPCAP findalldevs reply if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) @@ -1410,23 +1710,36 @@ daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen) { 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)); + // Note: the findalldevs_if entries are *not* neatly + // aligned on 4-byte boundaries, because they're + // preceded by strings that aren't padded to 4-byte + // boundaries, so we cannot just cast output buffer + // boundaries to struct rpcap_findalldevs_if pointers + // and store into them - we must fill in a structure and + // then copy the structure to the buffer, as not all + // systems support unaligned access (some, such as + // SPARC, crash; others, such as Arm, may just ignore + // the lower-order bits). + struct rpcap_findalldevs_if findalldevs_if; - if (d->description) ldescr = (short) strlen(d->description); - else ldescr = 0; - if (d->name) lname = (short) strlen(d->name); - else lname = 0; + /* + * We've already established that the string lengths + * fit in 16 bits. + */ + if (d->description) + ldescr = (uint16) strlen(d->description); + else + ldescr = 0; + if (d->name) + lname = (uint16) strlen(d->name); + else + lname = 0; - findalldevs_if->desclen = htons(ldescr); - findalldevs_if->namelen = htons(lname); - findalldevs_if->flags = htonl(d->flags); + findalldevs_if.desclen = htons(ldescr); + findalldevs_if.namelen = htons(lname); + findalldevs_if.flags = htonl(d->flags); + uint16_t naddrs = 0; for (address = d->addresses; address != NULL; address = address->next) { /* @@ -1438,14 +1751,20 @@ daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen) #ifdef AF_INET6 case AF_INET6: #endif - findalldevs_if->naddr++; + naddrs++; break; default: break; } } - findalldevs_if->naddr = htons(findalldevs_if->naddr); + findalldevs_if.naddr = htons(naddrs); + findalldevs_if.dummy = 0; + + if (sock_bufferize(&findalldevs_if, sizeof(struct rpcap_findalldevs_if), sendbuf, + &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errmsgbuf, + PCAP_ERRBUF_SIZE) == -1) + goto error; if (sock_bufferize(d->name, lname, sendbuf, &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errmsgbuf, @@ -1506,7 +1825,7 @@ daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen) pcap_freealldevs(alldevs); // Send a final command that says "now send it!" - if (sock_send(pars->sockctrl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) + if (sock_send(pars->sockctrl, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) { rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); return -1; @@ -1518,8 +1837,8 @@ daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen) if (alldevs) pcap_freealldevs(alldevs); - if (rpcap_senderror(pars->sockctrl, ver, PCAP_ERR_FINDALLIF, - errmsgbuf, errbuf) == -1) + if (rpcap_senderror(pars->sockctrl, pars->ssl, ver, + PCAP_ERR_FINDALLIF, errmsgbuf, errbuf) == -1) { rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); return -1; @@ -1545,11 +1864,11 @@ daemon_msg_open_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, if (plen > sourcelen - 1) { - pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Source string too long"); + snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Source string too long"); goto error; } - nread = sock_recv(pars->sockctrl, source, plen, + nread = sock_recv(pars->sockctrl, pars->ssl, source, plen, SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, PCAP_ERRBUF_SIZE); if (nread == -1) { @@ -1563,7 +1882,7 @@ daemon_msg_open_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, // If so, reject it. if (is_url(source)) { - pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Source string refers to a remote device"); + snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Source string refers to a remote device"); goto error; } @@ -1571,7 +1890,7 @@ daemon_msg_open_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, // 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 */, + 0 /* no promisc */, 1000 /* fake timeout */, errmsgbuf)) == NULL) goto error; @@ -1592,13 +1911,20 @@ daemon_msg_open_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, memset(openreply, 0, sizeof(struct rpcap_openreply)); openreply->linktype = htonl(pcap_datalink(fp)); - openreply->tzoff = 0; /* This is always 0 for live captures */ + /* + * This is always 0 for live captures; we no longer support it + * as something we read from capture files and supply to + * clients, but we have to send it over the wire, as open + * replies are expected to have 8 bytes of payload by + * existing clients. + */ + openreply->tzoff = 0; // We're done with the pcap_t. pcap_close(fp); // Send the reply. - if (sock_send(pars->sockctrl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) + if (sock_send(pars->sockctrl, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) { rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); return -1; @@ -1606,7 +1932,7 @@ daemon_msg_open_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, return 0; error: - if (rpcap_senderror(pars->sockctrl, ver, PCAP_ERR_OPEN, + if (rpcap_senderror(pars->sockctrl, pars->ssl, ver, PCAP_ERR_OPEN, errmsgbuf, errbuf) == -1) { // That failed; log a message and give up. @@ -1615,7 +1941,7 @@ daemon_msg_open_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, } // Check if all the data has been read; if not, discard the data in excess - if (rpcapd_discard(pars->sockctrl, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) { return -1; } @@ -1629,7 +1955,7 @@ daemon_msg_open_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, static int daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, char *source, struct session **sessionp, - struct rpcap_sampling *samp_param _U_) + struct rpcap_sampling *samp_param _U_, int uses_ssl) { char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client @@ -1654,7 +1980,7 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, addrinfo = NULL; - status = rpcapd_recv(pars->sockctrl, (char *) &startcapreq, + status = rpcapd_recv(pars->sockctrl, pars->ssl, (char *) &startcapreq, sizeof(struct rpcap_startcapreq), &plen, errmsgbuf); if (status == -1) { @@ -1667,15 +1993,25 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, startcapreq.flags = ntohs(startcapreq.flags); + // Check that the client does not ask for UDP is the server has been asked + // to enforce encryption, as SSL is not supported yet with UDP: + if (uses_ssl && (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_DGRAM)) + { + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "SSL not supported with UDP forward of remote packets"); + goto error; + } + // Create a session structure session = malloc(sizeof(struct session)); if (session == NULL) { - pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Can't allocate session structure"); + snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Can't allocate session structure"); goto error; } session->sockdata = INVALID_SOCKET; + session->ctrl_ssl = session->data_ssl = NULL; // We don't have a thread yet. session->have_thread = 0; // @@ -1726,7 +2062,8 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, saddrlen = sizeof(struct sockaddr_storage); if (getpeername(pars->sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1) { - sock_geterror("getpeername()", errmsgbuf, PCAP_ERRBUF_SIZE); + sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE, + "getpeername() failed"); goto error; } @@ -1737,38 +2074,40 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, // 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)); + 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); + sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE, + "getnameinfo() failed"); goto error; } if (sock_initaddress(peerhost, portdata, &hints, &addrinfo, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) goto error; - if ((session->sockdata = sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET) + if ((session->sockdata = sock_open(peerhost, 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) + // Make the server socket pick up a free network port for us + if (sock_initaddress(NULL, NULL, &hints, &addrinfo, errmsgbuf, PCAP_ERRBUF_SIZE) == -1) goto error; - if ((session->sockdata = sock_open(addrinfo, SOCKOPEN_SERVER, 1 /* max 1 connection in queue */, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET) + if ((session->sockdata = sock_open(NULL, 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(session->sockdata, (struct sockaddr *) &saddr, &saddrlen) == -1) { - sock_geterror("getsockname()", errmsgbuf, PCAP_ERRBUF_SIZE); + sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE, + "getsockname() failed"); goto error; } @@ -1776,7 +2115,8 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, if (getnameinfo((struct sockaddr *) &saddr, saddrlen, NULL, 0, portdata, sizeof(portdata), NI_NUMERICSERV)) { - sock_geterror("getnameinfo()", errmsgbuf, PCAP_ERRBUF_SIZE); + sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE, + "getnameinfo() failed"); goto error; } } @@ -1787,10 +2127,11 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, // Needed to send an error on the ctrl connection session->sockctrl = pars->sockctrl; + session->ctrl_ssl = pars->ssl; session->protocol_version = ver; // Now I can set the filter - ret = daemon_unpackapplyfilter(pars->sockctrl, session, &plen, errmsgbuf); + ret = daemon_unpackapplyfilter(pars->sockctrl, pars->ssl, session, &plen, errmsgbuf); if (ret == -1) { // Fatal error. A message has been logged; just give up. @@ -1825,7 +2166,7 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, startcapreply->portdata = htons(port); } - if (sock_send(pars->sockctrl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) + if (sock_send(pars->sockctrl, pars->ssl, 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); @@ -1843,7 +2184,8 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, if (socktemp == INVALID_SOCKET) { - sock_geterror("accept()", errbuf, PCAP_ERRBUF_SIZE); + sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE, + "accept() failed"); rpcapd_log(LOGPRIO_ERROR, "Accept of data connection failed: %s", errbuf); goto error; @@ -1854,13 +2196,30 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, session->sockdata = socktemp; } + SSL *ssl = NULL; + if (uses_ssl) + { +#ifdef HAVE_OPENSSL + /* In both active or passive cases, wait for the client to initiate the + * TLS handshake. Yes during that time the control socket will not be + * served, but the same was true from the above call to accept(). */ + ssl = ssl_promotion(1, session->sockdata, errbuf, PCAP_ERRBUF_SIZE); + if (! ssl) + { + rpcapd_log(LOGPRIO_ERROR, "TLS handshake failed: %s", errbuf); + goto error; + } +#endif + } + session->data_ssl = ssl; + // Now we have to create a new thread to receive packets #ifdef _WIN32 session->thread = (HANDLE)_beginthreadex(NULL, 0, daemon_thrdatamain, (void *) session, 0, NULL); if (session->thread == 0) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error creating the data thread"); + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error creating the data thread"); goto error; } #else @@ -1876,7 +2235,7 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, session->have_thread = 1; // Check if all the data has been read; if not, discard the data in excess - if (rpcapd_discard(pars->sockctrl, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) goto fatal_error; *sessionp = session; @@ -1898,8 +2257,8 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, free(session); } - if (rpcap_senderror(pars->sockctrl, ver, PCAP_ERR_STARTCAPTURE, - errmsgbuf, errbuf) == -1) + if (rpcap_senderror(pars->sockctrl, pars->ssl, ver, + PCAP_ERR_STARTCAPTURE, errmsgbuf, errbuf) == -1) { // That failed; log a message and give up. rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); @@ -1907,7 +2266,7 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, } // Check if all the data has been read; if not, discard the data in excess - if (rpcapd_discard(pars->sockctrl, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) { // Network error. return -1; @@ -1942,7 +2301,7 @@ daemon_msg_endcap_req(uint8 ver, struct daemon_slpars *pars, rpcap_createhdr(&header, ver, RPCAP_MSG_ENDCAP_REPLY, 0, 0); - if (sock_send(pars->sockctrl, (char *) &header, sizeof(struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1) + if (sock_send(pars->sockctrl, pars->ssl, (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); @@ -1970,7 +2329,7 @@ daemon_msg_endcap_req(uint8 ver, struct daemon_slpars *pars, #define RPCAP_BPF_MAXINSNS 8192 static int -daemon_unpackapplyfilter(SOCKET sockctrl, struct session *session, uint32 *plenp, char *errmsgbuf) +daemon_unpackapplyfilter(SOCKET sockctrl, SSL *ctrl_ssl, struct session *session, uint32 *plenp, char *errmsgbuf) { int status; struct rpcap_filter filter; @@ -1979,7 +2338,7 @@ daemon_unpackapplyfilter(SOCKET sockctrl, struct session *session, uint32 *plenp struct bpf_program bf_prog; unsigned int i; - status = rpcapd_recv(sockctrl, (char *) &filter, + status = rpcapd_recv(sockctrl, ctrl_ssl, (char *) &filter, sizeof(struct rpcap_filter), plenp, errmsgbuf); if (status == -1) { @@ -1994,14 +2353,14 @@ daemon_unpackapplyfilter(SOCKET sockctrl, struct session *session, uint32 *plenp if (ntohs(filter.filtertype) != RPCAP_UPDATEFILTER_BPF) { - pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Only BPF/NPF filters are currently supported"); + snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Only BPF/NPF filters are currently supported"); return -2; } if (bf_prog.bf_len > RPCAP_BPF_MAXINSNS) { - pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, - "Filter program is larger than the maximum size of %u instructions", + snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, + "Filter program is larger than the maximum size of %d instructions", RPCAP_BPF_MAXINSNS); return -2; } @@ -2017,7 +2376,7 @@ daemon_unpackapplyfilter(SOCKET sockctrl, struct session *session, uint32 *plenp for (i = 0; i < bf_prog.bf_len; i++) { - status = rpcapd_recv(sockctrl, (char *) &insn, + status = rpcapd_recv(sockctrl, ctrl_ssl, (char *) &insn, sizeof(struct rpcap_filterbpf_insn), plenp, errmsgbuf); if (status == -1) { @@ -2036,15 +2395,18 @@ daemon_unpackapplyfilter(SOCKET sockctrl, struct session *session, uint32 *plenp bf_insn++; } + // + // XXX - pcap_setfilter() should do the validation for us. + // if (bpf_validate(bf_prog.bf_insns, bf_prog.bf_len) == 0) { - pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "The filter contains bogus instructions"); + 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)); + snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "RPCAP error: %s", pcap_geterr(session->fp)); return -2; } @@ -2060,7 +2422,7 @@ daemon_msg_updatefilter_req(uint8 ver, struct daemon_slpars *pars, int ret; // status of daemon_unpackapplyfilter() struct rpcap_header header; // keeps the answer to the updatefilter command - ret = daemon_unpackapplyfilter(pars->sockctrl, session, &plen, errmsgbuf); + ret = daemon_unpackapplyfilter(pars->sockctrl, pars->ssl, session, &plen, errmsgbuf); if (ret == -1) { // Fatal error. A message has been logged; just give up. @@ -2073,7 +2435,7 @@ daemon_msg_updatefilter_req(uint8 ver, struct daemon_slpars *pars, } // Check if all the data has been read; if not, discard the data in excess - if (rpcapd_discard(pars->sockctrl, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) { // Network error. return -1; @@ -2082,9 +2444,9 @@ daemon_msg_updatefilter_req(uint8 ver, struct daemon_slpars *pars, // A response is needed, otherwise the other host does not know that everything went well rpcap_createhdr(&header, ver, RPCAP_MSG_UPDATEFILTER_REPLY, 0, 0); - if (sock_send(pars->sockctrl, (char *) &header, sizeof (struct rpcap_header), pcap_geterr(session->fp), PCAP_ERRBUF_SIZE)) + if (sock_send(pars->sockctrl, pars->ssl, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE)) { - // That failed; log a messsage and give up. + // That failed; log a message and give up. rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); return -1; } @@ -2092,11 +2454,11 @@ daemon_msg_updatefilter_req(uint8 ver, struct daemon_slpars *pars, return 0; error: - if (rpcapd_discard(pars->sockctrl, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) { return -1; } - rpcap_senderror(pars->sockctrl, ver, PCAP_ERR_UPDATEFILTER, + rpcap_senderror(pars->sockctrl, pars->ssl, ver, PCAP_ERR_UPDATEFILTER, errmsgbuf, NULL); return 0; @@ -2115,7 +2477,7 @@ daemon_msg_setsampling_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, struct rpcap_sampling rpcap_samp; int status; - status = rpcapd_recv(pars->sockctrl, (char *) &rpcap_samp, sizeof(struct rpcap_sampling), &plen, errmsgbuf); + status = rpcapd_recv(pars->sockctrl, pars->ssl, (char *) &rpcap_samp, sizeof(struct rpcap_sampling), &plen, errmsgbuf); if (status == -1) { return -1; @@ -2132,14 +2494,14 @@ daemon_msg_setsampling_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, // A response is needed, otherwise the other host does not know that everything went well rpcap_createhdr(&header, ver, RPCAP_MSG_SETSAMPLING_REPLY, 0, 0); - if (sock_send(pars->sockctrl, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1) + if (sock_send(pars->sockctrl, pars->ssl, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1) { - // That failed; log a messsage and give up. + // That failed; log a message and give up. rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); return -1; } - if (rpcapd_discard(pars->sockctrl, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) { return -1; } @@ -2147,7 +2509,7 @@ daemon_msg_setsampling_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, return 0; error: - if (rpcap_senderror(pars->sockctrl, ver, PCAP_ERR_SETSAMPLING, + if (rpcap_senderror(pars->sockctrl, pars->ssl, ver, PCAP_ERR_SETSAMPLING, errmsgbuf, errbuf) == -1) { // That failed; log a message and give up. @@ -2156,7 +2518,7 @@ daemon_msg_setsampling_req(uint8 ver, struct daemon_slpars *pars, uint32 plen, } // Check if all the data has been read; if not, discard the data in excess - if (rpcapd_discard(pars->sockctrl, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) { return -1; } @@ -2176,7 +2538,7 @@ daemon_msg_stats_req(uint8 ver, struct daemon_slpars *pars, 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, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) { // Network error. return -1; @@ -2199,7 +2561,7 @@ daemon_msg_stats_req(uint8 ver, struct daemon_slpars *pars, { if (pcap_stats(session->fp, stats) == -1) { - pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "%s", pcap_geterr(session->fp)); + snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "%s", pcap_geterr(session->fp)); goto error; } @@ -2220,7 +2582,7 @@ daemon_msg_stats_req(uint8 ver, struct daemon_slpars *pars, } // Send the packet - if (sock_send(pars->sockctrl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) + if (sock_send(pars->sockctrl, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) { rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); return -1; @@ -2229,7 +2591,7 @@ daemon_msg_stats_req(uint8 ver, struct daemon_slpars *pars, return 0; error: - rpcap_senderror(pars->sockctrl, ver, PCAP_ERR_GETSTATS, + rpcap_senderror(pars->sockctrl, pars->ssl, ver, PCAP_ERR_GETSTATS, errmsgbuf, NULL); return 0; } @@ -2288,7 +2650,21 @@ daemon_thrdatamain(void *ptr) // // So we don't need to make sure that sendbufsize will overflow. // + // However, we *do* need to make sure its value fits in an int, + // because sock_send() can't send more than INT_MAX bytes (it could + // do so on 64-bit UN*Xes, but can't do so on Windows, not even + // 64-bit Windows, as the send() buffer size argument is an int + // in Winsock). + // sendbufsize = sizeof(struct rpcap_header) + sizeof(struct rpcap_pkthdr) + pcap_snapshot(session->fp); + if (sendbufsize > INT_MAX) + { + rpcapd_log(LOGPRIO_ERROR, + "Buffer size for this child thread would be larger than %d", + INT_MAX); + sendbuf = NULL; // we haven't allocated a buffer, so nothing to free + goto error; + } sendbuf = (char *) malloc (sendbufsize); if (sendbuf == NULL) { @@ -2335,7 +2711,7 @@ daemon_thrdatamain(void *ptr) // Bufferize the general header if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, - &sendbufidx, sendbufsize, SOCKBUF_CHECKONLY, errbuf, + &sendbufidx, (int)sendbufsize, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) == -1) { rpcapd_log(LOGPRIO_ERROR, @@ -2352,7 +2728,7 @@ daemon_thrdatamain(void *ptr) // Bufferize the pkt header if (sock_bufferize(NULL, sizeof(struct rpcap_pkthdr), NULL, - &sendbufidx, sendbufsize, SOCKBUF_CHECKONLY, errbuf, + &sendbufidx, (int)sendbufsize, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) == -1) { rpcapd_log(LOGPRIO_ERROR, @@ -2364,12 +2740,16 @@ daemon_thrdatamain(void *ptr) 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); + // + // This protocol needs to be updated with a new version + // before 2038-01-19 03:14:07 UTC. + // + net_pkt_header->timestamp_sec = htonl((uint32)pkt_header->ts.tv_sec); + net_pkt_header->timestamp_usec = htonl((uint32)pkt_header->ts.tv_usec); // Bufferize the pkt data if (sock_bufferize((char *) pkt_data, pkt_header->caplen, - sendbuf, &sendbufidx, sendbufsize, SOCKBUF_BUFFERIZE, + sendbuf, &sendbufidx, (int)sendbufsize, SOCKBUF_BUFFERIZE, errbuf, PCAP_ERRBUF_SIZE) == -1) { rpcapd_log(LOGPRIO_ERROR, @@ -2381,7 +2761,7 @@ daemon_thrdatamain(void *ptr) // 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); + status = sock_send(session->sockdata, session->data_ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE); if (status < 0) { if (status == -1) @@ -2412,8 +2792,8 @@ daemon_thrdatamain(void *ptr) // The latter just means that the client told us to stop // capturing, so there's no error to report. // - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error reading the packets: %s", pcap_geterr(session->fp)); - rpcap_senderror(session->sockctrl, session->protocol_version, + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error reading the packets: %s", pcap_geterr(session->fp)); + rpcap_senderror(session->sockctrl, session->ctrl_ssl, session->protocol_version, PCAP_ERR_READEX, errbuf, NULL); } @@ -2461,19 +2841,25 @@ daemon_seraddr(struct sockaddr_storage *sockaddrin, struct rpcap_sockaddr *socka if (sockaddrin == NULL) return; // Warning: we support only AF_INET and AF_INET6 + // + // Note: as noted above, the output structures are not + // neatly aligned on 4-byte boundaries, so we must fill + // in an aligned structure and then copy it to the output + // buffer with memcpy(). switch (sockaddrin->ss_family) { case AF_INET: { struct sockaddr_in *sockaddrin_ipv4; - struct rpcap_sockaddr_in *sockaddrout_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)); + + 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)); + memcpy(sockaddrout, &sockaddrout_ipv4, sizeof(struct rpcap_sockaddr_in)); break; } @@ -2481,15 +2867,16 @@ daemon_seraddr(struct sockaddr_storage *sockaddrin, struct rpcap_sockaddr *socka case AF_INET6: { struct sockaddr_in6 *sockaddrin_ipv6; - struct rpcap_sockaddr_in6 *sockaddrout_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); + + 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); + memcpy(sockaddrout, &sockaddrout_ipv6, sizeof(struct rpcap_sockaddr_in6)); break; } #endif @@ -2502,6 +2889,7 @@ daemon_seraddr(struct sockaddr_storage *sockaddrin, struct rpcap_sockaddr *socka */ void sleep_secs(int secs) { +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION #ifdef _WIN32 Sleep(secs*1000); #else @@ -2513,18 +2901,19 @@ void sleep_secs(int secs) while (secs_remaining != 0) secs_remaining = sleep(secs_remaining); #endif +#endif } /* * Read the header of a message. */ static int -rpcapd_recv_msg_header(SOCKET sock, struct rpcap_header *headerp) +rpcapd_recv_msg_header(SOCKET sock, SSL *ssl, 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), + nread = sock_recv(sock, ssl, (char *) headerp, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES|SOCK_EOF_ISNT_ERROR, errbuf, PCAP_ERRBUF_SIZE); if (nread == -1) { @@ -2551,7 +2940,7 @@ rpcapd_recv_msg_header(SOCKET sock, struct rpcap_header *headerp) * error. */ static int -rpcapd_recv(SOCKET sock, char *buffer, size_t toread, uint32 *plen, char *errmsgbuf) +rpcapd_recv(SOCKET sock, SSL *ssl, char *buffer, size_t toread, uint32 *plen, char *errmsgbuf) { int nread; char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors @@ -2559,10 +2948,10 @@ rpcapd_recv(SOCKET sock, char *buffer, size_t toread, uint32 *plen, char *errmsg if (toread > *plen) { // Tell the client and continue. - pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Message payload is too short"); + snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Message payload is too short"); return -2; } - nread = sock_recv(sock, buffer, toread, + nread = sock_recv(sock, ssl, buffer, toread, SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, PCAP_ERRBUF_SIZE); if (nread == -1) { @@ -2580,13 +2969,13 @@ rpcapd_recv(SOCKET sock, char *buffer, size_t toread, uint32 *plen, char *errmsg * error. */ static int -rpcapd_discard(SOCKET sock, uint32 len) +rpcapd_discard(SOCKET sock, SSL *ssl, 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) + if (sock_discard(sock, ssl, len, errbuf, PCAP_ERRBUF_SIZE) == -1) { // Network error. rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf); @@ -2669,6 +3058,16 @@ static void session_close(struct session *session) #endif } +#ifdef HAVE_OPENSSL + if (session->data_ssl) + { + // Finish using the SSL handle for the socket. + // This must be done *before* the socket is closed. + ssl_finish(session->data_ssl); + session->data_ssl = NULL; + } +#endif + if (session->sockdata != INVALID_SOCKET) { sock_close(session->sockdata, NULL, 0); diff --git a/external/bsd/libpcap/dist/rpcapd/daemon.h b/external/bsd/libpcap/dist/rpcapd/daemon.h index 74e17da5a505..dbbdb62ca1db 100644 --- a/external/bsd/libpcap/dist/rpcapd/daemon.h +++ b/external/bsd/libpcap/dist/rpcapd/daemon.h @@ -33,13 +33,19 @@ #ifndef __DAEMON_H__ #define __DAEMON_H__ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "sslutils.h" + // // Returns 1 if the client closed the control connection explicitly, 0 // otherwise; the return value is used only by callers that call us // for active mode. // int daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, - int nullAuthAllowed); + int nullAuthAllowed, int uses_ssl); void sleep_secs(int secs); diff --git a/external/bsd/libpcap/dist/rpcapd/fileconf.c b/external/bsd/libpcap/dist/rpcapd/fileconf.c index 2f15c014204f..c051f887ead6 100644 --- a/external/bsd/libpcap/dist/rpcapd/fileconf.c +++ b/external/bsd/libpcap/dist/rpcapd/fileconf.c @@ -39,7 +39,6 @@ #include #include -#include #include #include // for PCAP_ERRBUF_SIZE @@ -59,6 +58,16 @@ static char *skipws(char *ptr); +/* + * Locale-independent version checks for alphabetical and alphanumerical + * characters that also can handle being handed a char value that might + * be negative. + */ +#define FILECONF_ISALPHA(c) \ + (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z')) +#define FILECONF_ISALNUM(c) \ + (FILECONF_ISALPHA(c) || ((c) >= '0' && (c) <= '9')) + void fileconf_read(void) { FILE *fp; @@ -135,8 +144,7 @@ void fileconf_read(void) // Is the next character alphabetic? If not, // this isn't a valid parameter name. // - if (!isascii((unsigned char)*ptr) || - !isalpha((unsigned char)*ptr)) + if (FILECONF_ISALPHA(*ptr)) { rpcapd_log(LOGPRIO_ERROR, "%s, line %u doesn't have a valid parameter name", @@ -150,8 +158,7 @@ void fileconf_read(void) // That's the name of the parameter being set. // param = ptr; - while (isascii((unsigned char)*ptr) && - (isalnum((unsigned char)*ptr) || *ptr == '-' || *ptr == '_')) + while (FILECONF_ISALNUM(*ptr) || *ptr == '-' || *ptr == '_') ptr++; // @@ -234,13 +241,15 @@ void fileconf_read(void) ptr += toklen; // skip to the terminator if (toklen == 0) { - if (isascii((unsigned char)*ptr) && - (isspace((unsigned char)*ptr) || *ptr == '#' || *ptr == '\0')) + if (*ptr == ' ' || *ptr == '\t' || + *ptr == '\r' || *ptr == '\n' || + *ptr == '#' || *ptr == '\0') { // // The first character it saw // was a whitespace character - // or a comment character. + // or a comment character, + // or we ran out of characters. // This means that there's // no value. // @@ -377,7 +386,7 @@ void fileconf_read(void) // // Append this to the host list. - // Save the curren end-of-string for the + // Save the current end-of-string for the // host list, in case the new host doesn't // fit, so that we can discard the partially- // copied host name. @@ -498,8 +507,7 @@ int fileconf_save(const char *savefile) fprintf(fp, "# Hosts which are allowed to connect to this server (passive mode)\n"); fprintf(fp, "# Format: PassiveClient = \n\n"); - strncpy(temphostlist, hostlist, MAX_HOST_LIST); - temphostlist[MAX_HOST_LIST] = 0; + pcap_strlcpy(temphostlist, hostlist, sizeof (temphostlist)); token = pcap_strtok_r(temphostlist, RPCAP_HOSTLIST_SEP, &lasts); while(token != NULL) @@ -548,7 +556,7 @@ int fileconf_save(const char *savefile) // static char *skipws(char *ptr) { - while (isascii((unsigned char)*ptr) && isspace((unsigned char)*ptr)) { + while (*ptr == ' ' || *ptr == '\t' || *ptr == '\r' || *ptr == '\n') { if (*ptr == '\r' || *ptr == '\n') return NULL; *ptr++ = '\0'; diff --git a/external/bsd/libpcap/dist/rpcapd/log.c b/external/bsd/libpcap/dist/rpcapd/log.c index 7b5fee57caaf..f26c145e6ca1 100644 --- a/external/bsd/libpcap/dist/rpcapd/log.c +++ b/external/bsd/libpcap/dist/rpcapd/log.c @@ -229,7 +229,7 @@ static void rpcapd_vlog_systemlog(log_priority priority, const char *message, */ char logbuf[1024+1]; - pcap_vsnprintf(logbuf, sizeof logbuf, message, ap); + vsnprintf(logbuf, sizeof logbuf, message, ap); syslog(syslog_priority, "%s", logbuf); #endif } diff --git a/external/bsd/libpcap/dist/rpcapd/org.tcpdump.rpcapd.plist b/external/bsd/libpcap/dist/rpcapd/org.tcpdump.rpcapd.plist index db3223a70317..c485787552df 100644 --- a/external/bsd/libpcap/dist/rpcapd/org.tcpdump.rpcapd.plist +++ b/external/bsd/libpcap/dist/rpcapd/org.tcpdump.rpcapd.plist @@ -1,11 +1,11 @@ - + Disabled Label - com.tcpdump.rpcapd + org.tcpdump.rpcapd Program /usr/local/libexec/rpcapd ProgramArguments diff --git a/external/bsd/libpcap/dist/rpcapd/rpcapd-config.manfile.in b/external/bsd/libpcap/dist/rpcapd/rpcapd-config.manfile.in index 1a87529d8abf..267b48e5e642 100644 --- a/external/bsd/libpcap/dist/rpcapd/rpcapd-config.manfile.in +++ b/external/bsd/libpcap/dist/rpcapd/rpcapd-config.manfile.in @@ -21,7 +21,7 @@ .SH NAME rpcapd-config \- rpcapd configuration file format .SH DESCRIPTION -An +An .B rpcapd configuration file allows parameters to be set for .BR rpcapd (@MAN_ADMIN_COMMANDS@). @@ -42,7 +42,7 @@ are: .TP .B ActiveClient .I value -is a host name or IP addresse, followed by a comma, +is a host name or IP address, followed by a comma, semicolon, or space, followed by a port name and address or .BR DEFAULT . .B DEFAULT @@ -54,7 +54,7 @@ should connect in active mode. .TP .B PassiveClient .I value -is a host name or IP addresse, followed by a comma, +is a host name or IP address, followed by a comma, semicolon, or space, followed by a port name and address or .BR DEFAULT . .B DEFAULT @@ -75,4 +75,4 @@ means that null authentication is permitted; .B No means that it is not permitted. .SH SEE ALSO -rpcapd(@MAN_ADMIN_COMMANDS@) +.BR rpcapd (@MAN_ADMIN_COMMANDS@) diff --git a/external/bsd/libpcap/dist/rpcapd/rpcapd.c b/external/bsd/libpcap/dist/rpcapd/rpcapd.c index 430acdc88e86..4c1b74549a45 100644 --- a/external/bsd/libpcap/dist/rpcapd/rpcapd.c +++ b/external/bsd/libpcap/dist/rpcapd/rpcapd.c @@ -35,10 +35,12 @@ #endif #include "ftmacros.h" +#include "diag-control.h" #include // for the errno variable #include // for strtok, etc #include // for malloc(), free(), ... +#include // for fprintf(), stderr, FILE etc #include // for PCAP_ERRBUF_SIZE #include // for signal() @@ -53,6 +55,10 @@ #include "daemon.h" // the true main() method of this daemon #include "log.h" +#ifdef HAVE_OPENSSL +#include "sslutils.h" +#endif + #ifdef _WIN32 #include // for thread stuff #include "win32-svc.h" // for Win32 service stuff @@ -86,6 +92,7 @@ static HANDLE state_change_event; //!< event to signal that a state change shou #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 +static int uses_ssl; //!< '1' to use TLS over the data socket extern char *optarg; // for getopt() @@ -112,7 +119,7 @@ static unsigned __stdcall main_passive_serviceloop_thread(void *ptr); /*! \brief Prints the usage screen if it is launched in console mode. */ -static void printusage(void) +static void printusage(FILE * f) { const char *usagetext = "USAGE:" @@ -145,14 +152,23 @@ static void printusage(void) " -i run in inetd mode (UNIX only)\n\n" #endif " -D log debugging messages\n\n" +#ifdef HAVE_OPENSSL + " -S encrypt all communication with SSL (implements rpcaps://)\n" + " -C enable compression\n" + " -K uses the SSL private key in this file (default: key.pem)\n" + " -X uses the certificate from this file (default: cert.pem)\n" +#endif " -s save the current configuration to file\n\n" " -f 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); + (void)fprintf(f, "RPCAPD, a remote packet capture daemon.\n" + "Compiled with %s\n", pcap_lib_version()); +#if defined(HAVE_OPENSSL) && defined(SSLEAY_VERSION) + (void)fprintf(f, "Compiled with %s\n", SSLeay_version(SSLEAY_VERSION)); +#endif + (void)fprintf(f, "\n%s", usagetext); } @@ -172,6 +188,9 @@ int main(int argc, char *argv[]) #ifndef _WIN32 struct sigaction action; #endif +#ifdef HAVE_OPENSSL + int enable_compression = 0; +#endif savefile[0] = 0; loadfile[0] = 0; @@ -180,8 +199,8 @@ int main(int argc, char *argv[]) // Initialize errbuf memset(errbuf, 0, sizeof(errbuf)); - strncpy(address, RPCAP_DEFAULT_NETADDR, MAX_LINE); - strncpy(port, RPCAP_DEFAULT_NETPORT, MAX_LINE); + pcap_strlcpy(address, RPCAP_DEFAULT_NETADDR, sizeof (address)); + pcap_strlcpy(port, RPCAP_DEFAULT_NETPORT, sizeof (port)); // Prepare to open a new server socket memset(&mainhints, 0, sizeof(struct addrinfo)); @@ -191,7 +210,15 @@ int main(int argc, char *argv[]) mainhints.ai_socktype = SOCK_STREAM; // Getting the proper command line options - while ((retval = getopt(argc, argv, "b:dDhip:4l:na:s:f:v")) != -1) +# ifdef HAVE_OPENSSL +# define SSL_CLOPTS "SK:X:C" +# else +# define SSL_CLOPTS "" +# endif + +# define CLOPTS "b:dDhip:4l:na:s:f:v" SSL_CLOPTS + + while ((retval = getopt(argc, argv, CLOPTS)) != -1) { switch (retval) { @@ -200,10 +227,10 @@ int main(int argc, char *argv[]) rpcapd_log_set(log_to_systemlog, log_debug_messages); break; case 'b': - strncpy(address, optarg, MAX_LINE); + pcap_strlcpy(address, optarg, sizeof (address)); break; case 'p': - strncpy(port, optarg, MAX_LINE); + pcap_strlcpy(port, optarg, sizeof (port)); break; case '4': mainhints.ai_family = PF_INET; // IPv4 server only @@ -215,7 +242,7 @@ int main(int argc, char *argv[]) break; case 'i': #ifdef _WIN32 - printusage(); + printusage(stderr); exit(1); #else isrunbyinetd = 1; @@ -231,7 +258,7 @@ int main(int argc, char *argv[]) break; case 'l': { - strncpy(hostlist, optarg, sizeof(hostlist)); + pcap_strlcpy(hostlist, optarg, sizeof(hostlist)); break; } case 'a': @@ -246,12 +273,12 @@ int main(int argc, char *argv[]) { tmpport = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts); - pcap_strlcpy(activelist[i].address, tmpaddress, MAX_LINE); + pcap_strlcpy(activelist[i].address, tmpaddress, sizeof (activelist[i].address)); if ((tmpport == NULL) || (strcmp(tmpport, "DEFAULT") == 0)) // the user choose a custom port - pcap_strlcpy(activelist[i].port, RPCAP_DEFAULT_NETPORT_ACTIVE, MAX_LINE); + pcap_strlcpy(activelist[i].port, RPCAP_DEFAULT_NETPORT_ACTIVE, sizeof (activelist[i].port)); else - pcap_strlcpy(activelist[i].port, tmpport, MAX_LINE); + pcap_strlcpy(activelist[i].port, tmpport, sizeof (activelist[i].port)); tmpaddress = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts); @@ -266,13 +293,27 @@ int main(int argc, char *argv[]) break; } case 'f': - pcap_strlcpy(loadfile, optarg, MAX_LINE); + pcap_strlcpy(loadfile, optarg, sizeof (loadfile)); break; case 's': - pcap_strlcpy(savefile, optarg, MAX_LINE); + pcap_strlcpy(savefile, optarg, sizeof (savefile)); break; +#ifdef HAVE_OPENSSL + case 'S': + uses_ssl = 1; + break; + case 'C': + enable_compression = 1; + break; + case 'K': + ssl_set_keyfile(optarg); + break; + case 'X': + ssl_set_certfile(optarg); + break; +#endif case 'h': - printusage(); + printusage(stdout); exit(0); /*NOTREACHED*/ default: @@ -289,6 +330,16 @@ int main(int argc, char *argv[]) } #endif + // + // We want UTF-8 error messages. + // + if (pcap_init(PCAP_CHAR_ENC_UTF_8, errbuf) == -1) + { + rpcapd_log(LOGPRIO_ERROR, "%s", errbuf); + exit(-1); + } + pcap_fmt_set_encoding(PCAP_CHAR_ENC_UTF_8); + if (sock_init(errbuf, PCAP_ERRBUF_SIZE) == -1) { rpcapd_log(LOGPRIO_ERROR, "%s", errbuf); @@ -302,7 +353,7 @@ int main(int argc, char *argv[]) if (loadfile[0]) fileconf_read(); -#ifdef WIN32 +#ifdef _WIN32 // // Create a handle to signal the main loop to tell it to do // something. @@ -310,8 +361,8 @@ int main(int argc, char *argv[]) state_change_event = CreateEvent(NULL, FALSE, FALSE, NULL); if (state_change_event == NULL) { - sock_geterror("Can't create state change event", errbuf, - PCAP_ERRBUF_SIZE); + sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE, + "Can't create state change event"); rpcapd_log(LOGPRIO_ERROR, "%s", errbuf); exit(2); } @@ -321,8 +372,8 @@ int main(int argc, char *argv[]) // if (!SetConsoleCtrlHandler(main_ctrl_event, TRUE)) { - sock_geterror("Can't set control handler", errbuf, - PCAP_ERRBUF_SIZE); + sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE, + "Can't set control handler"); rpcapd_log(LOGPRIO_ERROR, "%s", errbuf); exit(2); } @@ -342,6 +393,17 @@ int main(int argc, char *argv[]) signal(SIGPIPE, SIG_IGN); #endif +# ifdef HAVE_OPENSSL + if (uses_ssl) { + if (ssl_init_once(1, enable_compression, errbuf, PCAP_ERRBUF_SIZE) < 0) + { + rpcapd_log(LOGPRIO_ERROR, "Can't initialize SSL: %s", + errbuf); + exit(2); + } + } +# endif + #ifndef _WIN32 if (isrunbyinetd) { @@ -365,8 +427,8 @@ int main(int argc, char *argv[]) sockctrl = dup(0); if (sockctrl == -1) { - sock_geterror("Can't dup standard input", errbuf, - PCAP_ERRBUF_SIZE); + sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE, + "Can't dup standard input"); rpcapd_log(LOGPRIO_ERROR, "%s", errbuf); exit(2); } @@ -399,7 +461,7 @@ int main(int argc, char *argv[]) exit(0); } (void)daemon_serviceloop(sockctrl, 0, hostlist_copy, - nullAuthAllowed); + nullAuthAllowed, uses_ssl); // // Nothing more to do. @@ -442,7 +504,7 @@ int main(int argc, char *argv[]) // 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 + // created. From this point on, the number of threads active are always one more compared // to the number you're expecting // Second child continues @@ -454,7 +516,7 @@ int main(int argc, char *argv[]) // // If this call succeeds, it is blocking on Win32 // - if (svc_start() != 1) + if (!svc_start()) rpcapd_log(LOGPRIO_DEBUG, "Unable to start the service"); // When the previous call returns, the entire application has to be stopped. @@ -561,7 +623,7 @@ void main_startup(void) SOCKET sock; struct listen_sock *sock_info; - if ((sock = sock_open(tempaddrinfo, SOCKOPEN_SERVER, SOCKET_MAXCONN, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET) + if ((sock = sock_open(NULL, tempaddrinfo, SOCKOPEN_SERVER, SOCKET_MAXCONN, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET) { switch (tempaddrinfo->ai_family) { @@ -674,8 +736,8 @@ send_state_change_event(void) if (!SetEvent(state_change_event)) { - sock_geterror("SetEvent on shutdown event failed", errbuf, - PCAP_ERRBUF_SIZE); + sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE, + "SetEvent on shutdown event failed"); rpcapd_log(LOGPRIO_ERROR, "%s", errbuf); } } @@ -842,15 +904,15 @@ accept_connections(void) event = WSACreateEvent(); if (event == WSA_INVALID_EVENT) { - sock_geterror("Can't create socket event", errbuf, - PCAP_ERRBUF_SIZE); + sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE, + "Can't create socket event"); rpcapd_log(LOGPRIO_ERROR, "%s", errbuf); exit(2); } if (WSAEventSelect(sock_info->sock, event, FD_ACCEPT) == SOCKET_ERROR) { - sock_geterror("Can't setup socket event", errbuf, - PCAP_ERRBUF_SIZE); + sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE, + "Can't setup socket event"); rpcapd_log(LOGPRIO_ERROR, "%s", errbuf); exit(2); } @@ -868,8 +930,8 @@ accept_connections(void) WSA_INFINITE, FALSE); if (ret == WSA_WAIT_FAILED) { - sock_geterror("WSAWaitForMultipleEvents failed", errbuf, - PCAP_ERRBUF_SIZE); + sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE, + "WSAWaitForMultipleEvents failed"); rpcapd_log(LOGPRIO_ERROR, "%s", errbuf); exit(2); } @@ -908,8 +970,8 @@ accept_connections(void) if (WSAEnumNetworkEvents(sock_info->sock, events[i], &network_events) == SOCKET_ERROR) { - sock_geterror("WSAEnumNetworkEvents failed", - errbuf, PCAP_ERRBUF_SIZE); + sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE, + "WSAEnumNetworkEvents failed"); rpcapd_log(LOGPRIO_ERROR, "%s", errbuf); exit(2); } @@ -918,15 +980,15 @@ accept_connections(void) // // Did an error occur? // - if (network_events.iErrorCode[FD_ACCEPT_BIT] != 0) - { + if (network_events.iErrorCode[FD_ACCEPT_BIT] != 0) + { // // Yes - report it and keep going. // - sock_fmterror("Socket error", + sock_fmterrmsg(errbuf, + PCAP_ERRBUF_SIZE, network_events.iErrorCode[FD_ACCEPT_BIT], - errbuf, - PCAP_ERRBUF_SIZE); + "Socket error"); rpcapd_log(LOGPRIO_ERROR, "%s", errbuf); continue; } @@ -1100,7 +1162,7 @@ accept_connection(SOCKET listen_sock) break; } - // The accept() call can return this error when a signal is catched + // The accept() call can return this error when a signal is caught // In this case, we have simply to ignore this error code // Stevens, pg 124 #ifdef _WIN32 @@ -1112,7 +1174,7 @@ accept_connection(SOCKET listen_sock) // 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); + sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE, "accept() failed"); rpcapd_log(LOGPRIO_ERROR, "Accept of control connection from client failed: %s", errbuf); return; @@ -1136,14 +1198,16 @@ accept_connection(SOCKET listen_sock) // if (WSAEventSelect(sockctrl, NULL, 0) == SOCKET_ERROR) { - sock_geterror("WSAEventSelect()", errbuf, PCAP_ERRBUF_SIZE); + sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE, + "WSAEventSelect() failed"); rpcapd_log(LOGPRIO_ERROR, "%s", errbuf); sock_close(sockctrl, NULL, 0); return; } if (ioctlsocket(sockctrl, FIONBIO, &off) == SOCKET_ERROR) { - sock_geterror("ioctlsocket(FIONBIO)", errbuf, PCAP_ERRBUF_SIZE); + sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE, + "ioctlsocket(FIONBIO) failed"); rpcapd_log(LOGPRIO_ERROR, "%s", errbuf); sock_close(sockctrl, NULL, 0); return; @@ -1236,7 +1300,7 @@ accept_connection(SOCKET listen_sock) exit(0); } (void)daemon_serviceloop(sockctrl, 0, hostlist_copy, - nullAuthAllowed); + nullAuthAllowed, uses_ssl); exit(0); } @@ -1296,13 +1360,15 @@ main_active(void *ptr) { int activeclose; - if ((sockctrl = sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET) + if ((sockctrl = sock_open(activepars->address, addrinfo, SOCKOPEN_CLIENT, 0, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET) { rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf); - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error connecting to host %s, port %s, using protocol %s", + DIAG_OFF_FORMAT_TRUNCATION + 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"); + DIAG_ON_FORMAT_TRUNCATION rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf); @@ -1324,10 +1390,10 @@ main_active(void *ptr) // daemon_serviceloop() will free the copy. // activeclose = daemon_serviceloop(sockctrl, 1, - hostlist_copy, nullAuthAllowed); + hostlist_copy, nullAuthAllowed, uses_ssl); } - // If the connection is closed by the user explicitely, don't try to connect to it again + // If the connection is closed by the user explicitly, don't try to connect to it again // just exit the program if (activeclose == 1) break; @@ -1352,7 +1418,7 @@ unsigned __stdcall main_passive_serviceloop_thread(void *ptr) // told by the client to close. // (void)daemon_serviceloop(params.sockctrl, 0, params.hostlist, - nullAuthAllowed); + nullAuthAllowed, uses_ssl); return 0; } diff --git a/external/bsd/libpcap/dist/rpcapd/rpcapd.manadmin.in b/external/bsd/libpcap/dist/rpcapd/rpcapd.manadmin.in index 0a9d4e031a3c..f3ab6ea4a99a 100644 --- a/external/bsd/libpcap/dist/rpcapd/rpcapd.manadmin.in +++ b/external/bsd/libpcap/dist/rpcapd/rpcapd.manadmin.in @@ -30,7 +30,7 @@ .\" (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" +.TH RPCAPD @MAN_ADMIN_COMMANDS@ "20 January 2023" .SH NAME rpcapd \- capture daemon to be controlled by a remote libpcap application .SH SYNOPSIS @@ -48,7 +48,6 @@ rpcapd .B \-l .I host_list ] -.br .ti +8 [ .B \-a @@ -62,17 +61,30 @@ rpcapd ] [ .B \-i ] -.br .ti +8 [ .B \-D ] [ .B \-s .I config_file -] [ +] +[ .B \-f .I config_file ] +[ +.B \-S +] +.ti +8 +[ +.B \-K +.I ssl_keyfile +] [ +.B \-X +.I ssl_certfile +] [ +.B \-C +] .br .ad .SH DESCRIPTION @@ -84,7 +96,9 @@ 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. +The client then sends the appropriate commands to +.B rpcapd +to start the capture. .LP In active mode, .B rpcapd @@ -103,26 +117,34 @@ 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 +The user can create a configuration file in the same directory as 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, +.B rpcapd +to execute the commands, it needs to be restarted on Win32, i.e. +the configuration file is parsed only at the beginning. The UNIX +version of +.B rpcapd +will reread the configuration file upon receiving a +HUP signal. 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". +they can launch +.B rpcapd +with the desired flags plus +.BR "-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. +The installation process places the +.B rpcapd +executable 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 +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 @@ -134,7 +156,9 @@ flag (in order to make it run as a service) and the flag. .SH Starting rpcapd on Win32 .LP -The rpcapd executable can be launched directly, i.e. it can run in the +The +.B 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 @@ -149,6 +173,46 @@ 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. +.LP +If your system supports +.BR systemd (1) +and the corresponding +.B rpcapd.socket +and +.B rpcapd@.service +service files have been +installed, the rpcapd service can be enabled by enabling the +.B rpcapd.socket +unit. +.LP +If your system supports +.BR launchd (@MAN_ADMIN_COMMANDS@) +and the +.B org.tcpdump.rpcapd.plist +file has been installed, the rpcapd service can be enabled by loading +the +.B org.tcpdump.rpcapd +service. +.LP +If your system supports +.BR inetd (@MAN_ADMIN_COMMANDS@) +and the +.B rpcapd.inetd.conf +entry has been added to +.BR inetd.conf (@MAN_FILE_FORMATS@), +the rpcapd service can be enabled by telling +.B inetd +to reread its configuration file. +.LP +If your system supports +.BR xinetd (@MAN_ADMIN_COMMANDS@) +and the +.B rpcapd.xinetd.conf +entry has been added to +.BR xinetd.conf (@MAN_FILE_FORMATS@), +the rpcapd service can be enabled by telling +.B xinetd +to reread its configuration file. .SH OPTIONS .TP .BI \-b " address" @@ -172,13 +236,13 @@ By default, .B rpcapd listens on both IPv4 and IPv6 addresses. .TP -.BI -l " host_list" +.BI \-l " host_list" Only allow hosts specified in the .I host_list argument to connect to this server. .I host_list is a list of host names or IP addresses, separated by commas. -We suggest that you use use host names rather than literal IP addresses +We suggest that you use host names rather than literal IP addresses in order to avoid problems with different address families. .TP .B \-n @@ -202,8 +266,8 @@ is specified, 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 +Run in daemon mode (UNIX only) or as a service (Win32 only). +Warning (Win32): this flag is specified automatically when the service is started from the control panel. .TP .B \-i @@ -222,12 +286,37 @@ in the format specified by Load the current configuration from .I config_file in the format specified by -.BR rpcapd-config (@MAN_FILE_FORMATS@); -all switches specified from the command line are ignored. +.BR rpcapd-config (@MAN_FILE_FORMATS@) +and ignore all flags specified on the command line. .TP .B \-h Print this help screen. +.LP +If +.B rpcapd +was compiled with SSL support, the following options are also +available: +.TP +.B \-S +Require that SSL be used on connections. +.TP +.B \-C +With SSL enabled, XXX - I'm not sure how *fetching* the list of +compression mechanisms does anything to compression. +.TP +.B \-S +.I ssl_keyfile +With SSL enabled, use +.I ssl_keyfile +as the SSL key file. +.TP +.B \-X +.I ssl_certfile +With SSL enabled, use +.I ssl_certfile +as the SSL certificate file. .br .ad .SH "SEE ALSO" -pcap(3PCAP), rpcapd-config(@MAN_FILE_FORMATS@) +.BR pcap (3PCAP), +.BR rpcapd-config (@MAN_FILE_FORMATS@) diff --git a/external/bsd/libpcap/dist/rpcapd/win32-svc.c b/external/bsd/libpcap/dist/rpcapd/win32-svc.c index 3a19910d77ab..49b6804bfd93 100644 --- a/external/bsd/libpcap/dist/rpcapd/win32-svc.c +++ b/external/bsd/libpcap/dist/rpcapd/win32-svc.c @@ -38,15 +38,18 @@ #include "fileconf.h" #include "log.h" +#include "win32-svc.h" // for Win32 service stuff + static SERVICE_STATUS_HANDLE service_status_handle; static SERVICE_STATUS service_status; static void WINAPI svc_main(DWORD argc, char **argv); +static void WINAPI svc_control_handler(DWORD Opcode); static void update_svc_status(DWORD state, DWORD progress_indicator); -int svc_start(void) +BOOL svc_start(void) { - int rc; + BOOL rc; SERVICE_TABLE_ENTRY ste[] = { { PROGRAM_NAME, svc_main }, @@ -65,7 +68,8 @@ int svc_start(void) return rc; // FALSE if this is not started as a service } -void WINAPI svc_control_handler(DWORD Opcode) +static void WINAPI +svc_control_handler(DWORD Opcode) { switch(Opcode) { @@ -130,7 +134,8 @@ void WINAPI svc_control_handler(DWORD Opcode) return; } -void WINAPI svc_main(DWORD argc, char **argv) +static void WINAPI +svc_main(DWORD argc, char **argv) { service_status_handle = RegisterServiceCtrlHandler(PROGRAM_NAME, svc_control_handler); diff --git a/external/bsd/libpcap/dist/rpcapd/win32-svc.h b/external/bsd/libpcap/dist/rpcapd/win32-svc.h index 3f511d2c5587..60b25ecff19e 100644 --- a/external/bsd/libpcap/dist/rpcapd/win32-svc.h +++ b/external/bsd/libpcap/dist/rpcapd/win32-svc.h @@ -30,4 +30,4 @@ * */ -int svc_start(void); +BOOL svc_start(void); diff --git a/external/bsd/libpcap/dist/sf-pcapng.c b/external/bsd/libpcap/dist/sf-pcapng.c index afaeb0566571..058a7244d62a 100644 --- a/external/bsd/libpcap/dist/sf-pcapng.c +++ b/external/bsd/libpcap/dist/sf-pcapng.c @@ -34,6 +34,7 @@ #include #include "pcap-int.h" +#include "pcap-util.h" #include "pcap-common.h" @@ -101,7 +102,8 @@ struct section_header_block { /* * Current version number. If major_version isn't PCAP_NG_VERSION_MAJOR, - * that means that this code can't read the file. + * or if minor_version isn't PCAP_NG_VERSION_MINOR or 2, that means that + * this code can't read the file. */ #define PCAP_NG_VERSION_MAJOR 1 #define PCAP_NG_VERSION_MINOR 0 @@ -197,6 +199,7 @@ typedef enum { * Per-interface information. */ struct pcap_ng_if { + uint32_t snaplen; /* snapshot length */ uint64_t tsresol; /* time stamp resolution */ tstamp_scale_type_t scale_type; /* how to scale */ uint64_t scale_factor; /* time stamp scale factor for power-of-10 tsresol */ @@ -265,8 +268,8 @@ read_bytes(FILE *fp, void *buf, size_t bytes_to_read, int fail_on_eof, } else { if (amt_read == 0 && !fail_on_eof) return (0); /* EOF */ - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, - "truncated pcapng dump file; tried to read %" PRIsize " bytes, only got %" PRIsize, + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "truncated pcapng dump file; tried to read %zu bytes, only got %zu", bytes_to_read, amt_read); } return (-1); @@ -301,8 +304,8 @@ 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 pcapng dump file has a length of %u < %" PRIsize, + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "block in pcapng dump file has a length of %u < %zu", bhdr.total_length, sizeof(struct block_header) + sizeof(struct block_trailer)); return (-1); @@ -315,8 +318,8 @@ read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf) /* * No. Report that as an error. */ - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, - "block in pcapng dump file has a length of %u that is not a multiple of 4" PRIsize, + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "block in pcapng dump file has a length of %u that is not a multiple of 4", bhdr.total_length); return (-1); } @@ -332,13 +335,13 @@ read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf) void *bigger_buffer; if (bhdr.total_length > ps->max_blocksize) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "pcapng block size %u > maximum %u", bhdr.total_length, + snprintf(errbuf, PCAP_ERRBUF_SIZE, "pcapng block size %u > maximum %u", bhdr.total_length, 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"); + snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory"); return (-1); } p->buffer = bigger_buffer; @@ -369,7 +372,7 @@ read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf) /* * No. */ - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, + snprintf(errbuf, PCAP_ERRBUF_SIZE, "block total length in header and trailer don't match"); return (-1); } @@ -394,7 +397,7 @@ get_from_block_data(struct block_cursor *cursor, size_t chunk_size, * the block data. */ if (cursor->data_remaining < chunk_size) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, + snprintf(errbuf, PCAP_ERRBUF_SIZE, "block of type %u in pcapng dump file is too short", cursor->block_type); return (NULL); @@ -495,7 +498,7 @@ process_idb_options(pcap_t *p, struct block_cursor *cursor, uint64_t *tsresol, case OPT_ENDOFOPT: if (opthdr->option_length != 0) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Interface Description Block has opt_endofopt option with length %u != 0", opthdr->option_length); return (-1); @@ -504,13 +507,13 @@ process_idb_options(pcap_t *p, struct block_cursor *cursor, uint64_t *tsresol, case IF_TSRESOL: if (opthdr->option_length != 1) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Interface Description Block has if_tsresol option with length %u != 1", opthdr->option_length); return (-1); } if (saw_tsresol) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Interface Description Block has more than one if_tsresol option"); return (-1); } @@ -527,7 +530,7 @@ process_idb_options(pcap_t *p, struct block_cursor *cursor, uint64_t *tsresol, * Resolution is too high; 2^-{res} * won't fit in a 64-bit value. */ - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Interface Description Block if_tsresol option resolution 2^-%u is too high", tsresol_shift); return (-1); @@ -547,7 +550,7 @@ process_idb_options(pcap_t *p, struct block_cursor *cursor, uint64_t *tsresol, * the largest 64-bit unsigned * value is ~1.8*10^19). */ - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Interface Description Block if_tsresol option resolution 10^-%u is too high", tsresol_opt); return (-1); @@ -561,13 +564,13 @@ process_idb_options(pcap_t *p, struct block_cursor *cursor, uint64_t *tsresol, case IF_TSOFFSET: if (opthdr->option_length != 8) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Interface Description Block has if_tsoffset option with length %u != 8", opthdr->option_length); return (-1); } if (saw_tsoffset) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, + snprintf(errbuf, PCAP_ERRBUF_SIZE, "Interface Description Block has more than one if_tsoffset option"); return (-1); } @@ -587,7 +590,8 @@ process_idb_options(pcap_t *p, struct block_cursor *cursor, uint64_t *tsresol, } static int -add_interface(pcap_t *p, struct block_cursor *cursor, char *errbuf) +add_interface(pcap_t *p, struct interface_description_block *idbp, + struct block_cursor *cursor, char *errbuf) { struct pcap_ng_sf *ps; uint64_t tsresol; @@ -644,7 +648,7 @@ add_interface(pcap_t *p, struct block_cursor *cursor, char *errbuf) * possible 32-bit power of 2, as we do * size doubling. */ - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, + snprintf(errbuf, PCAP_ERRBUF_SIZE, "more than %u interfaces in the file", 0x80000000U); return (0); @@ -675,7 +679,7 @@ add_interface(pcap_t *p, struct block_cursor *cursor, char *errbuf) * (unsigned) value divided by * sizeof (struct pcap_ng_if). */ - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, + snprintf(errbuf, PCAP_ERRBUF_SIZE, "more than %u interfaces in the file", 0xFFFFFFFFU / ((u_int)sizeof (struct pcap_ng_if))); return (0); @@ -687,7 +691,7 @@ add_interface(pcap_t *p, struct block_cursor *cursor, char *errbuf) * We ran out of memory. * Give up. */ - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, + snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory for per-interface information (%u interfaces)", ps->ifcount); return (0); @@ -696,6 +700,8 @@ add_interface(pcap_t *p, struct block_cursor *cursor, char *errbuf) ps->ifaces = new_ifaces; } + ps->ifaces[ps->ifcount - 1].snaplen = idbp->snaplen; + /* * Set the default time stamp resolution and offset. */ @@ -858,8 +864,8 @@ pcap_ng_check_header(const uint8_t *magic, FILE *fp, u_int precision, */ if (total_length < sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer) || (total_length > BT_SHB_INSANE_MAX)) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, - "Section Header Block in pcapng dump file has invalid length %" PRIsize " < _%u_ < %u (BT_SHB_INSANE_MAX)", + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "Section Header Block in pcapng dump file has invalid length %zu < _%u_ < %u (BT_SHB_INSANE_MAX)", sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer), total_length, BT_SHB_INSANE_MAX); @@ -872,7 +878,7 @@ pcap_ng_check_header(const uint8_t *magic, FILE *fp, u_int precision, * OK, this is a good pcapng file. * Allocate a pcap_t for it. */ - p = pcap_open_offline_common(errbuf, sizeof (struct pcap_ng_sf)); + p = PCAP_OPEN_OFFLINE_COMMON(errbuf, struct pcap_ng_sf); if (p == NULL) { /* Allocation failed. */ *err = 1; @@ -895,7 +901,7 @@ pcap_ng_check_header(const uint8_t *magic, FILE *fp, u_int precision, break; default: - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, + snprintf(errbuf, PCAP_ERRBUF_SIZE, "unknown time stamp resolution %u", precision); free(p); *err = 1; @@ -925,7 +931,7 @@ pcap_ng_check_header(const uint8_t *magic, FILE *fp, u_int precision, p->bufsize = total_length; p->buffer = malloc(p->bufsize); if (p->buffer == NULL) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory"); + snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory"); free(p); *err = 1; return (NULL); @@ -958,10 +964,24 @@ pcap_ng_check_header(const uint8_t *magic, FILE *fp, u_int precision, * XXX - we don't care about the section length. */ } - /* currently only SHB version 1.0 is supported */ + /* Currently only SHB versions 1.0 and 1.2 are supported; + version 1.2 is treated as being the same as version 1.0. + See the current version of the pcapng specification. + + Version 1.2 is written by some programs that write additional + block types (which can be read by any code that handles them, + regardless of whether the minor version if 0 or 2, so that's + not a reason to change the minor version number). + + XXX - the pcapng specification says that readers should + just ignore sections with an unsupported version number; + presumably they can also report an error if they skip + all the way to the end of the file without finding + any versions that they support. */ if (! (shbp->major_version == PCAP_NG_VERSION_MAJOR && - shbp->minor_version == PCAP_NG_VERSION_MINOR)) { - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, + (shbp->minor_version == PCAP_NG_VERSION_MINOR || + shbp->minor_version == 2))) { + snprintf(errbuf, PCAP_ERRBUF_SIZE, "unsupported pcapng savefile version %u.%u", shbp->major_version, shbp->minor_version); goto fail; @@ -984,7 +1004,7 @@ pcap_ng_check_header(const uint8_t *magic, FILE *fp, u_int precision, status = read_block(fp, p, &cursor, errbuf); if (status == 0) { /* EOF - no IDB in this file */ - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, + snprintf(errbuf, PCAP_ERRBUF_SIZE, "the capture file has no Interface Description Blocks"); goto fail; } @@ -1013,7 +1033,7 @@ pcap_ng_check_header(const uint8_t *magic, FILE *fp, u_int precision, /* * Try to add this interface. */ - if (!add_interface(p, &cursor, errbuf)) + if (!add_interface(p, idbp, &cursor, errbuf)) goto fail; goto done; @@ -1026,7 +1046,7 @@ pcap_ng_check_header(const uint8_t *magic, FILE *fp, u_int precision, * not valid, as we don't know what link-layer * encapsulation the packet has. */ - pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, + snprintf(errbuf, PCAP_ERRBUF_SIZE, "the capture file has a packet block before any Interface Description Blocks"); goto fail; @@ -1039,7 +1059,6 @@ pcap_ng_check_header(const uint8_t *magic, FILE *fp, u_int precision, } done: - p->tzoff = 0; /* XXX - not used in pcap */ p->linktype = linktype_to_dlt(idbp->linktype); p->snapshot = pcap_adjust_snapshot(p->linktype, idbp->snaplen); p->linktype_ext = 0; @@ -1076,7 +1095,7 @@ pcap_ng_cleanup(pcap_t *p) /* * 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 + * in hdr and a pointer to the contents in data. Return 1 on success, 0 * if there were no more packets, and -1 on an error. */ static int @@ -1105,7 +1124,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data) */ status = read_block(fp, p, &cursor, p->errbuf); if (status == 0) - return (1); /* EOF */ + return (0); /* EOF */ if (status == -1) return (-1); /* error */ switch (cursor.block_type) { @@ -1231,7 +1250,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data) * interfaces? */ if (p->linktype != idbp->linktype) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "an interface has a type %u different from the type of the first interface", idbp->linktype); return (-1); @@ -1243,8 +1262,8 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data) */ if ((bpf_u_int32)p->snapshot != pcap_adjust_snapshot(p->linktype, idbp->snaplen)) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "an interface has a snapshot length %u different from the type of the first interface", + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + "an interface has a snapshot length %u different from the snapshot length of the first interface", idbp->snaplen); return (-1); } @@ -1252,7 +1271,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data) /* * Try to add this interface. */ - if (!add_interface(p, &cursor, p->errbuf)) + if (!add_interface(p, idbp, &cursor, p->errbuf)) return (-1); break; @@ -1295,7 +1314,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data) /* * Byte order changes. */ - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "the file has sections with different byte orders"); return (-1); @@ -1303,7 +1322,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data) /* * Not a valid SHB. */ - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "the file has a section with a bad byte order magic field"); return (-1); } @@ -1313,7 +1332,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data) * we handle. */ if (shbp->major_version != PCAP_NG_VERSION_MAJOR) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown pcapng savefile major version number %u", shbp->major_version); return (-1); @@ -1347,14 +1366,14 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data) /* * Yes. Fail. */ - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "a packet arrived on interface %u, but there's no Interface Description Block for that interface", interface_id); return (-1); } if (hdr->caplen > (bpf_u_int32)p->snapshot) { - pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, + snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "invalid packet capture length %u, bigger than " "snaplen of %d", hdr->caplen, p->snapshot); return (-1); @@ -1493,8 +1512,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data) if (*data == NULL) return (-1); - if (p->swapped) - swap_pseudo_headers(p->linktype, hdr, *data); + pcap_post_process(p->linktype, p->swapped, hdr, *data); - return (0); + return (1); } diff --git a/external/bsd/libpcap/dist/sockutils.h b/external/bsd/libpcap/dist/sockutils.h index 8a45b3df423f..a488d8fcb4ff 100644 --- a/external/bsd/libpcap/dist/sockutils.h +++ b/external/bsd/libpcap/dist/sockutils.h @@ -37,6 +37,10 @@ #pragma once #endif +#include /* we declare varargs functions */ + +#include "pcap/funcattrs.h" + #include "pcap/socket.h" #ifndef _WIN32 @@ -52,6 +56,8 @@ #define closesocket(a) close(a) #endif +#include "sslutils.h" // for SSL type, whatever that turns out to be + /* * MingW headers include this definition, but only for Windows XP and above. * MSDN states that this function is available for most versions on Windows. @@ -104,6 +110,8 @@ int WSAAPI getnameinfo(const struct sockaddr*,socklen_t,char*,DWORD, #define SOCK_EOF_ISNT_ERROR 0x00000000 /* Return 0 on EOF */ #define SOCK_EOF_IS_ERROR 0x00000002 /* Return an error on EOF */ +#define SOCK_MSG_PEEK 0x00000004 /* Return data but leave it in the socket queue */ + /* * \} */ @@ -123,28 +131,33 @@ extern "C" { int sock_init(char *errbuf, int errbuflen); void sock_cleanup(void); -void sock_fmterror(const char *caller, int errcode, char *errbuf, int errbuflen); -void sock_geterror(const char *caller, char *errbuf, int errbufsize); +int sock_geterrcode(void); +void sock_vfmterrmsg(char *errbuf, size_t errbuflen, int errcode, + PCAP_FORMAT_STRING(const char *fmt), va_list ap) PCAP_PRINTFLIKE(4, 0); +void sock_fmterrmsg(char *errbuf, size_t errbuflen, int errcode, + PCAP_FORMAT_STRING(const char *fmt), ...) PCAP_PRINTFLIKE(4, 5); +void sock_geterrmsg(char *errbuf, size_t errbuflen, + PCAP_FORMAT_STRING(const char *fmt), ...) PCAP_PRINTFLIKE(3, 4); int sock_initaddress(const char *address, const char *port, struct addrinfo *hints, struct addrinfo **addrinfo, char *errbuf, int errbuflen); -int sock_recv(SOCKET sock, void *buffer, size_t size, int receiveall, +int sock_recv(SOCKET sock, SSL *, void *buffer, size_t size, int receiveall, char *errbuf, int errbuflen); -int sock_recv_dgram(SOCKET sock, void *buffer, size_t size, +int sock_recv_dgram(SOCKET sock, SSL *, void *buffer, size_t size, char *errbuf, int errbuflen); -SOCKET sock_open(struct addrinfo *addrinfo, int server, int nconn, char *errbuf, int errbuflen); +SOCKET sock_open(const char *host, struct addrinfo *addrinfo, int server, int nconn, char *errbuf, int errbuflen); int sock_close(SOCKET sock, char *errbuf, int errbuflen); -int sock_send(SOCKET sock, const char *buffer, size_t size, +int sock_send(SOCKET sock, SSL *, 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 sock, int size, char *errbuf, int errbuflen); +int sock_bufferize(const void *data, int size, char *outbuf, int *offset, int totsize, int checkonly, char *errbuf, int errbuflen); +int sock_discard(SOCKET sock, SSL *, 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); int sock_getmyinfo(SOCKET sock, char *address, int addrlen, char *port, int portlen, int flags, char *errbuf, int errbuflen); -int sock_getascii_addrport(const struct sockaddr_storage *sockaddr, char *address, int addrlen, char *port, int portlen, int flags, char *errbuf, int errbuflen); +int sock_getascii_addrport(const struct sockaddr_storage *sockaddr, char *address, int addrlen, char *port, int portlen, int flags, char *errbuf, size_t errbuflen); int sock_present2network(const char *address, struct sockaddr_storage *sockaddr, int addr_family, char *errbuf, int errbuflen); #ifdef __cplusplus diff --git a/external/bsd/libpcap/dist/sslutils.c b/external/bsd/libpcap/dist/sslutils.c new file mode 100644 index 000000000000..7274cc34c580 --- /dev/null +++ b/external/bsd/libpcap/dist/sslutils.c @@ -0,0 +1,239 @@ +/* + * 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 +#endif + +#ifdef HAVE_OPENSSL +#include + +#include "portability.h" + +#include "sslutils.h" + +static const char *ssl_keyfile = ""; //!< file containing the private key in PEM format +static const char *ssl_certfile = ""; //!< file containing the server's certificate in PEM format +static const char *ssl_rootfile = ""; //!< file containing the list of CAs trusted by the client +// TODO: a way to set ssl_rootfile from the command line, or an envvar? + +// TODO: lock? +static SSL_CTX *ctx; + +void ssl_set_certfile(const char *certfile) +{ + ssl_certfile = certfile; +} + +void ssl_set_keyfile(const char *keyfile) +{ + ssl_keyfile = keyfile; +} + +int ssl_init_once(int is_server, int enable_compression, char *errbuf, size_t errbuflen) +{ + static int inited = 0; + if (inited) return 0; + + SSL_library_init(); + SSL_load_error_strings(); + OpenSSL_add_ssl_algorithms(); + if (enable_compression) + SSL_COMP_get_compression_methods(); + + SSL_METHOD const *meth = + is_server ? SSLv23_server_method() : SSLv23_client_method(); + ctx = SSL_CTX_new(meth); + if (! ctx) + { + snprintf(errbuf, errbuflen, "Cannot get a new SSL context: %s", ERR_error_string(ERR_get_error(), NULL)); + goto die; + } + + SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); + + if (is_server) + { + char const *certfile = ssl_certfile[0] ? ssl_certfile : "cert.pem"; + if (1 != SSL_CTX_use_certificate_file(ctx, certfile, SSL_FILETYPE_PEM)) + { + snprintf(errbuf, errbuflen, "Cannot read certificate file %s: %s", certfile, ERR_error_string(ERR_get_error(), NULL)); + goto die; + } + + char const *keyfile = ssl_keyfile[0] ? ssl_keyfile : "key.pem"; + if (1 != SSL_CTX_use_PrivateKey_file(ctx, keyfile, SSL_FILETYPE_PEM)) + { + snprintf(errbuf, errbuflen, "Cannot read private key file %s: %s", keyfile, ERR_error_string(ERR_get_error(), NULL)); + goto die; + } + } + else + { + if (ssl_rootfile[0]) + { + if (! SSL_CTX_load_verify_locations(ctx, ssl_rootfile, 0)) + { + snprintf(errbuf, errbuflen, "Cannot read CA list from %s", ssl_rootfile); + goto die; + } + } + else + { + SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); + } + } + +#if 0 + if (! RAND_load_file(RANDOM, 1024*1024)) + { + snprintf(errbuf, errbuflen, "Cannot init random"); + goto die; + } + + if (is_server) + { + SSL_CTX_set_session_id_context(ctx, (void *)&s_server_session_id_context, sizeof(s_server_session_id_context)); + } +#endif + + inited = 1; + return 0; + +die: + return -1; +} + +SSL *ssl_promotion(int is_server, SOCKET s, char *errbuf, size_t errbuflen) +{ + if (ssl_init_once(is_server, 1, errbuf, errbuflen) < 0) { + return NULL; + } + + SSL *ssl = SSL_new(ctx); // TODO: also a DTLS context + SSL_set_fd(ssl, (int)s); + + if (is_server) { + if (SSL_accept(ssl) <= 0) { + snprintf(errbuf, errbuflen, "SSL_accept(): %s", + ERR_error_string(ERR_get_error(), NULL)); + return NULL; + } + } else { + if (SSL_connect(ssl) <= 0) { + snprintf(errbuf, errbuflen, "SSL_connect(): %s", + ERR_error_string(ERR_get_error(), NULL)); + return NULL; + } + } + + return ssl; +} + +// Finish using an SSL handle; shut down the connection and free the +// handle. +void ssl_finish(SSL *ssl) +{ + // + // We won't be using this again, so we can just send the + // shutdown alert and free up the handle, and have our + // caller close the socket. + // + // XXX - presumably, if the connection is shut down on + // our side, either our peer won't have a problem sending + // their shutdown alert or will not treat such a problem + // as an error. If this causes errors to be reported, + // fix that as appropriate. + // + SSL_shutdown(ssl); + SSL_free(ssl); +} + +// Same return value as sock_send: +// 0 on OK, -1 on error but closed connection (-2). +int ssl_send(SSL *ssl, char const *buffer, int size, char *errbuf, size_t errbuflen) +{ + int status = SSL_write(ssl, buffer, size); + if (status > 0) + { + // "SSL_write() will only return with success, when the complete contents (...) has been written." + return 0; + } + else + { + int ssl_err = SSL_get_error(ssl, status); // TODO: does it pop the error? + if (ssl_err == SSL_ERROR_ZERO_RETURN) + { + return -2; + } + else if (ssl_err == SSL_ERROR_SYSCALL) + { +#ifndef _WIN32 + if (errno == ECONNRESET || errno == EPIPE) return -2; +#endif + } + snprintf(errbuf, errbuflen, "SSL_write(): %s", + ERR_error_string(ERR_get_error(), NULL)); + return -1; + } +} + +// Returns the number of bytes read, or -1 on syserror, or -2 on SSL error. +int ssl_recv(SSL *ssl, char *buffer, int size, char *errbuf, size_t errbuflen) +{ + int status = SSL_read(ssl, buffer, size); + if (status <= 0) + { + int ssl_err = SSL_get_error(ssl, status); + if (ssl_err == SSL_ERROR_ZERO_RETURN) + { + return 0; + } + else if (ssl_err == SSL_ERROR_SYSCALL) + { + return -1; + } + else + { + // Should not happen + snprintf(errbuf, errbuflen, "SSL_read(): %s", + ERR_error_string(ERR_get_error(), NULL)); + return -2; + } + } + else + { + return status; + } +} + +#endif // HAVE_OPENSSL diff --git a/external/bsd/libpcap/dist/sslutils.h b/external/bsd/libpcap/dist/sslutils.h new file mode 100644 index 000000000000..6316364ecfc2 --- /dev/null +++ b/external/bsd/libpcap/dist/sslutils.h @@ -0,0 +1,66 @@ +/* + * 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 __SSLUTILS_H__ +#define __SSLUTILS_H__ + +#ifdef HAVE_OPENSSL +#include "pcap/socket.h" // for SOCKET +#include +#include + +/* + * Utility functions + */ + +void ssl_set_certfile(const char *certfile); +void ssl_set_keyfile(const char *keyfile); +int ssl_init_once(int is_server, int enable_compression, char *errbuf, size_t errbuflen); +SSL *ssl_promotion(int is_server, SOCKET s, char *errbuf, size_t errbuflen); +void ssl_finish(SSL *ssl); +int ssl_send(SSL *, char const *buffer, int size, char *errbuf, size_t errbuflen); +int ssl_recv(SSL *, char *buffer, int size, char *errbuf, size_t errbuflen); + +// The SSL parameters are used +#define _U_NOSSL_ + +#else // HAVE_OPENSSL + +// This saves us from a lot of ifdefs: +#define SSL void const + +// The SSL parameters are unused +#define _U_NOSSL_ _U_ + +#endif // HAVE_OPENSSL + +#endif // __SSLUTILS_H__ diff --git a/external/bsd/libpcap/dist/testprogs/CMakeLists.txt b/external/bsd/libpcap/dist/testprogs/CMakeLists.txt index b8ef9b7d0510..567f42aa6ed7 100644 --- a/external/bsd/libpcap/dist/testprogs/CMakeLists.txt +++ b/external/bsd/libpcap/dist/testprogs/CMakeLists.txt @@ -19,6 +19,10 @@ macro(add_test_executable _executable) target_link_libraries(${_executable} ${ARGN} ${LIBRARY_NAME}_static ${PCAP_LINK_LIBRARIES}) endif(WIN32) + if(NOT "${LINKER_FLAGS}" STREQUAL "") + set_target_properties(${_executable} PROPERTIES + LINK_FLAGS "${LINKER_FLAGS}") + endif() add_dependencies(testprogs ${_executable}) endmacro() @@ -26,8 +30,10 @@ add_test_executable(can_set_rfmon_test) add_test_executable(capturetest) add_test_executable(filtertest) add_test_executable(findalldevstest) +add_test_executable(findalldevstest-perf) add_test_executable(opentest) add_test_executable(reactivatetest) +add_test_executable(writecaptest) if(NOT WIN32) add_test_executable(selpolltest) @@ -35,6 +41,11 @@ endif() add_test_executable(threadsignaltest ${CMAKE_THREAD_LIBS_INIT}) -if(NOT WIN32) +# Same as in configure.ac. +if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR + CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR + CMAKE_SYSTEM_NAME STREQUAL "Linux") add_test_executable(valgrindtest) endif() + +add_subdirectory(fuzz) diff --git a/external/bsd/libpcap/dist/testprogs/Makefile.in b/external/bsd/libpcap/dist/testprogs/Makefile.in index ec0a47208464..d3fd328ce9a8 100644 --- a/external/bsd/libpcap/dist/testprogs/Makefile.in +++ b/external/bsd/libpcap/dist/testprogs/Makefile.in @@ -1,5 +1,5 @@ # Copyright (c) 1993, 1994, 1995, 1996 -# The Regents of the University of California. All rights reserved. +# 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 @@ -38,6 +38,7 @@ mandir = @mandir@ # VPATH srcdir = @srcdir@ +top_srcdir = @top_srcdir@ VPATH = @srcdir@ # @@ -62,7 +63,6 @@ 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) @@ -79,14 +79,17 @@ INSTALL_DATA = @INSTALL_DATA@ $(CC) $(FULL_CFLAGS) -c $(srcdir)/$*.c SRC = @VALGRINDTEST_SRC@ \ - capturetest.c \ can_set_rfmon_test.c \ + capturetest.c \ filtertest.c \ + findalldevstest-perf.c \ findalldevstest.c \ opentest.c \ + nonblocktest.c \ reactivatetest.c \ selpolltest.c \ - threadsignaltest.c + threadsignaltest.c \ + writecaptest.c TESTS = $(SRC:.c=) @@ -98,31 +101,56 @@ CLEANFILES = $(OBJ) $(TESTS) all: $(TESTS) capturetest: $(srcdir)/capturetest.c ../libpcap.a - $(CC) $(FULL_CFLAGS) -I. -L. -o capturetest $(srcdir)/capturetest.c ../libpcap.a $(LIBS) + $(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) + $(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) + $(CC) $(FULL_CFLAGS) -I. -L. -o filtertest $(srcdir)/filtertest.c \ + ../libpcap.a $(LIBS) findalldevstest: $(srcdir)/findalldevstest.c ../libpcap.a - $(CC) $(FULL_CFLAGS) -I. -L. -o findalldevstest $(srcdir)/findalldevstest.c ../libpcap.a $(EXTRA_NETWORK_LIBS) $(LIBS) + $(CC) $(FULL_CFLAGS) -I. -L. -o findalldevstest \ + $(srcdir)/findalldevstest.c \ + ../libpcap.a $(LIBS) + +findalldevstest-perf: $(srcdir)/findalldevstest-perf.c ../libpcap.a + $(CC) $(FULL_CFLAGS) -I. -L. -o findalldevstest-perf \ + $(srcdir)/findalldevstest-perf.c \ + ../libpcap.a $(LIBS) opentest: $(srcdir)/opentest.c ../libpcap.a - $(CC) $(FULL_CFLAGS) -I. -L. -o opentest $(srcdir)/opentest.c ../libpcap.a $(LIBS) + $(CC) $(FULL_CFLAGS) -I. -L. -o opentest $(srcdir)/opentest.c \ + ../libpcap.a $(LIBS) + +nonblocktest: $(srcdir)/nonblocktest.c ../libpcap.a + $(CC) $(FULL_CFLAGS) -I. -L. -o nonblocktest $(srcdir)/nonblocktest.c \ + ../libpcap.a $(LIBS) reactivatetest: $(srcdir)/reactivatetest.c ../libpcap.a - $(CC) $(FULL_CFLAGS) -I. -L. -o reactivatetest $(srcdir)/reactivatetest.c ../libpcap.a $(LIBS) + $(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) + $(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) + $(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) + $(CC) $(FULL_CFLAGS) -I. -L. -o valgrindtest $(srcdir)/valgrindtest.c \ + ../libpcap.a $(LIBS) + +writecaptest: $(srcdir)/writecaptest.c ../libpcap.a + $(CC) $(FULL_CFLAGS) -I. -L. -o writecaptest $(srcdir)/writecaptest.c \ + ../libpcap.a $(LIBS) clean: rm -f $(CLEANFILES) @@ -141,4 +169,4 @@ tags: $(TAGFILES) ctags -wtd $(TAGFILES) depend: - ../$(MKDEP) -c "$(CC)" -m "$(DEPENDENCY_CFLAG)" $(CFLAGS) $(DEFS) $(INCLS) $(SRC) + $(MKDEP) -c "$(CC)" -m "$(DEPENDENCY_CFLAG)" -s "$(srcdir)" $(CFLAGS) $(DEFS) $(INCLS) $(SRC) diff --git a/external/bsd/libpcap/dist/testprogs/can_set_rfmon_test.c b/external/bsd/libpcap/dist/testprogs/can_set_rfmon_test.c index f6188ba1399e..96816f9b977c 100644 --- a/external/bsd/libpcap/dist/testprogs/can_set_rfmon_test.c +++ b/external/bsd/libpcap/dist/testprogs/can_set_rfmon_test.c @@ -70,7 +70,6 @@ main(int argc, char **argv) else error("%s: pcap_can_set_rfmon failed: %s", argv[1], pcap_statustostr(status)); - return 1; } printf("%s: Monitor mode %s be set\n", argv[1], status ? "can" : "cannot"); return 0; diff --git a/external/bsd/libpcap/dist/testprogs/capturetest.c b/external/bsd/libpcap/dist/testprogs/capturetest.c index d625cb4ab2b7..4eadd3367968 100644 --- a/external/bsd/libpcap/dist/testprogs/capturetest.c +++ b/external/bsd/libpcap/dist/testprogs/capturetest.c @@ -38,6 +38,9 @@ The Regents of the University of California. All rights reserved.\n"; #include #endif #include +#ifndef _WIN32 + #include +#endif #include #include @@ -58,6 +61,37 @@ static void warning(const char *, ...) PCAP_PRINTFLIKE(1, 2); static char *copy_argv(char **); static pcap_t *pd; +#ifndef _WIN32 +static int breaksigint = 0; +#endif + +#ifndef _WIN32 +static void +sigint_handler(int signum _U_) +{ + if (breaksigint) + pcap_breakloop(pd); +} +#endif + +#ifdef _WIN32 +/* + * We don't have UN*X-style signals, so we don't have anything to test. + */ +#define B_OPTION "" +#define R_OPTION "" +#define S_OPTION "" +#else +/* + * We do have UN*X-style signals (we assume that "not Windows" means "UN*X"). + */ +#define B_OPTION "b" +#define R_OPTION "r" +#define S_OPTION "s" +#endif + +#define COMMAND_OPTIONS B_OPTION "i:mn" R_OPTION S_OPTION "t:" +#define USAGE_OPTIONS "-" B_OPTION "mn" R_OPTION S_OPTION int main(int argc, char **argv) @@ -69,6 +103,10 @@ main(int argc, char **argv) int timeout = 1000; int immediate = 0; int nonblock = 0; +#ifndef _WIN32 + int sigrestart = 0; + int catchsigint = 0; +#endif pcap_if_t *devlist; bpf_u_int32 localnet, netmask; struct bpf_program fcode; @@ -83,9 +121,15 @@ main(int argc, char **argv) program_name = argv[0]; opterr = 0; - while ((op = getopt(argc, argv, "i:mnt:")) != -1) { + while ((op = getopt(argc, argv, COMMAND_OPTIONS)) != -1) { switch (op) { +#ifndef _WIN32 + case 'b': + breaksigint = 1; + break; +#endif + case 'i': device = optarg; break; @@ -98,6 +142,16 @@ main(int argc, char **argv) nonblock = 1; break; +#ifndef _WIN32 + case 'r': + sigrestart = 1; + break; + + case 's': + catchsigint = 1; + break; +#endif + case 't': longarg = strtol(optarg, &p, 10); if (p == optarg || *p != '\0') { @@ -132,6 +186,28 @@ main(int argc, char **argv) pcap_freealldevs(devlist); } *ebuf = '\0'; + +#ifndef _WIN32 + /* + * If we were told to catch SIGINT, do so. + */ + if (catchsigint) { + struct sigaction action; + + action.sa_handler = sigint_handler; + sigemptyset(&action.sa_mask); + + /* + * Should SIGINT interrupt, or restart, system calls? + */ + action.sa_flags = sigrestart ? SA_RESTART : 0; + + if (sigaction(SIGINT, &action, NULL) == -1) + error("Can't catch SIGINT: %s\n", + strerror(errno)); + } +#endif + pd = pcap_create(device, ebuf); if (pd == NULL) error("%s", ebuf); @@ -188,6 +264,10 @@ main(int argc, char **argv) if (status != 0) { printf("%d packets seen, %d packets counted after pcap_dispatch returns\n", status, packet_count); + struct pcap_stat ps; + pcap_stats(pd, &ps); + printf("%d ps_recv, %d ps_drop, %d ps_ifdrop\n", + ps.ps_recv, ps.ps_drop, ps.ps_ifdrop); } } if (status == -2) { @@ -197,13 +277,14 @@ main(int argc, char **argv) * Print an extra newline, just in case. */ putchar('\n'); + printf("Broken out of loop from SIGINT handler\n"); } (void)fflush(stdout); if (status == -1) { /* * Error. Report it. */ - (void)fprintf(stderr, "%s: pcap_loop: %s\n", + (void)fprintf(stderr, "%s: pcap_dispatch: %s\n", program_name, pcap_geterr(pd)); } pcap_close(pd); @@ -223,7 +304,7 @@ countme(u_char *user, const struct pcap_pkthdr *h _U_, const u_char *sp _U_) static void usage(void) { - (void)fprintf(stderr, "Usage: %s [ -mn ] [ -i interface ] [ -t timeout] [expression]\n", + (void)fprintf(stderr, "Usage: %s [ " USAGE_OPTIONS " ] [ -i interface ] [ -t timeout] [expression]\n", program_name); exit(1); } @@ -271,7 +352,7 @@ static char * copy_argv(register char **argv) { register char **p; - register u_int len = 0; + register size_t len = 0; char *buf; char *src, *dst; diff --git a/external/bsd/libpcap/dist/testprogs/filtertest.c b/external/bsd/libpcap/dist/testprogs/filtertest.c index 7e2d6d6e186d..15556d045cf7 100644 --- a/external/bsd/libpcap/dist/testprogs/filtertest.c +++ b/external/bsd/libpcap/dist/testprogs/filtertest.c @@ -36,6 +36,7 @@ The Regents of the University of California. All rights reserved.\n"; #include #include #include +#include #ifdef _WIN32 #include "getopt.h" #include "unix.h" @@ -56,6 +57,8 @@ The Regents of the University of California. All rights reserved.\n"; #include "pcap/funcattrs.h" +#define MAXIMUM_SNAPLEN 262144 + #ifdef BDEBUG /* * We have pcap_set_optimizer_debug() and pcap_set_print_dot_graph() in @@ -99,11 +102,21 @@ read_infile(char *fname) if (fstat(fd, &buf) < 0) error("can't stat %s: %s", fname, pcap_strerror(errno)); + /* + * _read(), on Windows, has an unsigned int byte count and an + * int return value, so we can't handle a file bigger than + * INT_MAX - 1 bytes (and have no reason to do so; a filter *that* + * big will take forever to compile). (The -1 is for the '\0' at + * the end of the string.) + */ + if (buf.st_size > INT_MAX - 1) + error("%s is larger than %d bytes; that's too large", fname, + INT_MAX - 1); cp = malloc((u_int)buf.st_size + 1); if (cp == NULL) error("malloc(%d) for %s: %s", (u_int)buf.st_size + 1, fname, pcap_strerror(errno)); - cc = read(fd, cp, (u_int)buf.st_size); + cc = (int)read(fd, cp, (u_int)buf.st_size); if (cc < 0) error("read %s: %s", fname, pcap_strerror(errno)); if (cc != buf.st_size) @@ -163,7 +176,7 @@ static char * copy_argv(register char **argv) { register char **p; - register u_int len = 0; + register size_t len = 0; char *buf; char *src, *dst; @@ -196,13 +209,14 @@ main(int argc, char **argv) char *cp; int op; int dflag; +#ifdef BDEBUG int gflag; +#endif char *infile; int Oflag; - long snaplen; + int snaplen; char *p; int dlt; - int have_fcode = 0; bpf_u_int32 netmask = PCAP_NETMASK_UNKNOWN; char *cmdbuf; pcap_t *pd; @@ -214,11 +228,13 @@ main(int argc, char **argv) #endif /* _WIN32 */ dflag = 1; +#ifdef BDEBUG gflag = 0; +#endif infile = NULL; Oflag = 1; - snaplen = 68; + snaplen = MAXIMUM_SNAPLEN; if ((cp = strrchr(argv[0], '/')) != NULL) program_name = cp + 1; @@ -272,13 +288,19 @@ main(int argc, char **argv) case 's': { char *end; + long long_snaplen; - snaplen = strtol(optarg, &end, 0); + long_snaplen = strtol(optarg, &end, 0); if (optarg == end || *end != '\0' - || snaplen < 0 || snaplen > 65535) + || long_snaplen < 0 + || long_snaplen > MAXIMUM_SNAPLEN) error("invalid snaplen %s", optarg); - else if (snaplen == 0) - snaplen = 65535; + else { + if (snaplen == 0) + snaplen = MAXIMUM_SNAPLEN; + else + snaplen = (int)long_snaplen; + } break; } @@ -317,7 +339,6 @@ 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"); @@ -337,8 +358,7 @@ main(int argc, char **argv) bpf_dump(&fcode, dflag); free(cmdbuf); - if (have_fcode) - pcap_freecode (&fcode); + pcap_freecode (&fcode); pcap_close(pd); exit(0); } diff --git a/external/bsd/libpcap/dist/testprogs/findalldevstest-perf.c b/external/bsd/libpcap/dist/testprogs/findalldevstest-perf.c new file mode 100644 index 000000000000..16f53cdc5967 --- /dev/null +++ b/external/bsd/libpcap/dist/testprogs/findalldevstest-perf.c @@ -0,0 +1,97 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#ifdef _WIN32 + #include + #include + #include +#else + #include + #include +#endif + +#include + +#include "varattrs.h" +#include "pcap/funcattrs.h" +#include "portability.h" + +int main(int argc _U_, char **argv _U_) +{ + pcap_if_t *alldevs; + int exit_status = 0; + char errbuf[PCAP_ERRBUF_SIZE+1]; +#ifdef _WIN32 + FILETIME start_ktime, start_utime, end_ktime, end_utime; + FILETIME dummy1, dummy2; + ULARGE_INTEGER start_kticks, end_kticks, start_uticks, end_uticks; + ULONGLONG ktime, utime, tottime; +#else + struct rusage start_rusage, end_rusage; + struct timeval ktime, utime, tottime; +#endif + +#ifdef _WIN32 + if (!GetProcessTimes(GetCurrentProcess(), &dummy1, &dummy2, + &start_ktime, &start_utime)) + { + fprintf(stderr, "GetProcessTimes() fails at start\n"); + exit(1); + } + start_kticks.LowPart = start_ktime.dwLowDateTime; + start_kticks.HighPart = start_ktime.dwHighDateTime; + start_uticks.LowPart = start_utime.dwLowDateTime; + start_uticks.HighPart = start_utime.dwHighDateTime; +#else + if (getrusage(RUSAGE_SELF, &start_rusage) == -1) { + fprintf(stderr, "getrusage() fails at start\n"); + exit(1); + } +#endif + for (int i = 0; i < 500; i++) + { + if (pcap_findalldevs(&alldevs, errbuf) == -1) + { + fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf); + exit(1); + } + pcap_freealldevs(alldevs); + } + +#ifdef _WIN32 + if (!GetProcessTimes(GetCurrentProcess(), &dummy1, &dummy2, + &end_ktime, &end_utime)) + { + fprintf(stderr, "GetProcessTimes() fails at end\n"); + exit(1); + } + end_kticks.LowPart = end_ktime.dwLowDateTime; + end_kticks.HighPart = end_ktime.dwHighDateTime; + end_uticks.LowPart = end_utime.dwLowDateTime; + end_uticks.HighPart = end_utime.dwHighDateTime; + ktime = end_kticks.QuadPart - start_kticks.QuadPart; + utime = end_uticks.QuadPart - start_uticks.QuadPart; + tottime = ktime + utime; + printf("Total CPU secs: kernel %g, user %g, total %g\n", + ((double)ktime) / 10000000.0, + ((double)utime) / 10000000.0, + ((double)tottime) / 10000000.0); +#else + if (getrusage(RUSAGE_SELF, &end_rusage) == -1) { + fprintf(stderr, "getrusage() fails at end\n"); + exit(1); + } + timersub(&end_rusage.ru_stime, &start_rusage.ru_stime, &ktime); + timersub(&end_rusage.ru_utime, &start_rusage.ru_utime, &utime); + timeradd(&ktime, &utime, &tottime); + printf("Total CPU secs: kernel %g, user %g, total %g\n", + (double)ktime.tv_sec + ((double)ktime.tv_usec / 1000000.0), + (double)utime.tv_sec + ((double)utime.tv_usec / 1000000.0), + (double)tottime.tv_sec + ((double)tottime.tv_usec / 1000000.0)); +#endif + exit(exit_status); +} diff --git a/external/bsd/libpcap/dist/testprogs/findalldevstest.c b/external/bsd/libpcap/dist/testprogs/findalldevstest.c index e535e25462fb..062932090381 100644 --- a/external/bsd/libpcap/dist/testprogs/findalldevstest.c +++ b/external/bsd/libpcap/dist/testprogs/findalldevstest.c @@ -19,6 +19,7 @@ #include +#include "varattrs.h" #include "pcap/funcattrs.h" static int ifprint(pcap_if_t *d); @@ -94,7 +95,11 @@ getpass(const char *prompt) } #endif +#ifdef ENABLE_REMOTE int main(int argc, char **argv) +#else +int main(int argc _U_, char **argv _U_) +#endif { pcap_if_t *alldevs; pcap_if_t *d; @@ -152,8 +157,24 @@ int main(int argc, char **argv) { if (pcap_lookupnet(alldevs->name, &net, &mask, errbuf) < 0) { - fprintf(stderr,"Error in pcap_lookupnet: %s\n",errbuf); - exit_status = 2; + /* + * XXX - this doesn't distinguish between "a real error + * occurred" and "this interface doesn't *have* an IPv4 + * address". The latter shouldn't be treated as an error. + * + * We look for the interface name, followed by a colon and + * a space, and, if we find it,w e see if what follows it + * is "no IPv4 address assigned". + */ + size_t devnamelen = strlen(alldevs->name); + if (strncmp(errbuf, alldevs->name, devnamelen) == 0 && + strncmp(errbuf + devnamelen, ": ", 2) == 0 && + strcmp(errbuf + devnamelen + 2, "no IPv4 address assigned") == 0) + printf("Preferred device is not on an IPv4 network\n"); + else { + fprintf(stderr,"Error in pcap_lookupnet: %s\n",errbuf); + exit_status = 2; + } } else { @@ -300,12 +321,12 @@ static int ifprint(pcap_if_t *d) #define IPTOSBUFFERS 12 static char *iptos(bpf_u_int32 in) { - static char output[IPTOSBUFFERS][3*4+3+1]; + static char output[IPTOSBUFFERS][sizeof("255.255.255.255")]; static short which; u_char *p; p = (u_char *)∈ which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1); - sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); + snprintf(output[which], sizeof(output[which]), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); return output[which]; } diff --git a/external/bsd/libpcap/dist/testprogs/fuzz/CMakeLists.txt b/external/bsd/libpcap/dist/testprogs/fuzz/CMakeLists.txt new file mode 100644 index 000000000000..67250cca4349 --- /dev/null +++ b/external/bsd/libpcap/dist/testprogs/fuzz/CMakeLists.txt @@ -0,0 +1,43 @@ +add_executable(fuzz_pcap onefile.c fuzz_pcap.c) +target_link_libraries(fuzz_pcap ${ARGN} ${LIBRARY_NAME}_static ${PCAP_LINK_LIBRARIES}) +if(NOT "${SANITIZER_FLAGS}" STREQUAL "") + set_target_properties(fuzz_pcap PROPERTIES + LINK_FLAGS "${SANITIZER_FLAGS}") +endif() + +add_executable(fuzz_filter onefile.c fuzz_filter.c) +target_link_libraries(fuzz_filter ${ARGN} ${LIBRARY_NAME}_static ${PCAP_LINK_LIBRARIES}) +if(NOT "${SANITIZER_FLAGS}" STREQUAL "") + set_target_properties(fuzz_filter PROPERTIES + LINK_FLAGS "${SANITIZER_FLAGS}") +endif() + +add_executable(fuzz_both onefile.c fuzz_both.c) +target_link_libraries(fuzz_both ${ARGN} ${LIBRARY_NAME}_static ${PCAP_LINK_LIBRARIES}) +if(NOT "${SANITIZER_FLAGS}" STREQUAL "") + set_target_properties(fuzz_both PROPERTIES + LINK_FLAGS "${SANITIZER_FLAGS}") +endif() + +if(ENABLE_REMOTE AND "$ENV{CFLAGS}" MATCHES "-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION") +add_executable(fuzz_rclient onefile.c fuzz_rclient.c) +target_link_libraries(fuzz_rclient ${ARGN} ${LIBRARY_NAME}_static ${PCAP_LINK_LIBRARIES}) +if(NOT "${SANITIZER_FLAGS}" STREQUAL "") + set_target_properties(fuzz_rclient PROPERTIES + LINK_FLAGS "${SANITIZER_FLAGS}") +endif() + +add_executable(fuzz_rserver onefile.c fuzz_rserver.c ../../rpcapd/daemon.c) +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) + set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} crypt) +endif(HAVE_CRYPT_IN_SYSTEM_LIBRARIES) +target_link_libraries(fuzz_rserver ${ARGN} ${LIBRARY_NAME}_static ${PCAP_LINK_LIBRARIES}) + +if(NOT "${SANITIZER_FLAGS}" STREQUAL "") + set_target_properties(fuzz_rserver PROPERTIES + LINK_FLAGS "${SANITIZER_FLAGS}") +endif() +endif(ENABLE_REMOTE AND "$ENV{CFLAGS}" MATCHES "-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION") diff --git a/external/bsd/libpcap/dist/testprogs/fuzz/fuzz_both.c b/external/bsd/libpcap/dist/testprogs/fuzz/fuzz_both.c new file mode 100644 index 000000000000..59e3d404103d --- /dev/null +++ b/external/bsd/libpcap/dist/testprogs/fuzz/fuzz_both.c @@ -0,0 +1,101 @@ +#include +#include +#include +#include +#include + +#include + +FILE * outfile = NULL; + +static int bufferToFile(const char * name, const uint8_t *Data, size_t Size) { + FILE * fd; + if (remove(name) != 0) { + if (errno != ENOENT) { + printf("failed remove, errno=%d\n", errno); + return -1; + } + } + fd = fopen(name, "wb"); + if (fd == NULL) { + printf("failed open, errno=%d\n", errno); + return -2; + } + if (fwrite (Data, 1, Size, fd) != Size) { + fclose(fd); + return -3; + } + fclose(fd); + return 0; +} + +void fuzz_openFile(const char * name) { + if (outfile != NULL) { + fclose(outfile); + } + outfile = fopen(name, "w"); +} + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + pcap_t * pkts; + char errbuf[PCAP_ERRBUF_SIZE]; + const u_char *pkt; + struct pcap_pkthdr *header; + int r; + size_t filterSize; + char * filter; + struct bpf_program bpf; + + + //initialize output file + if (outfile == NULL) { + outfile = fopen("/dev/null", "w"); + if (outfile == NULL) { + return 0; + } + } + + if (Size < 1) { + return 0; + } + filterSize = Data[0]; + if (Size < 1+filterSize || filterSize == 0) { + return 0; + } + + //rewrite buffer to a file as libpcap does not have buffer inputs + if (bufferToFile("/tmp/fuzz.pcap", Data+1+filterSize, Size-(1+filterSize)) < 0) { + return 0; + } + + //initialize structure + pkts = pcap_open_offline("/tmp/fuzz.pcap", errbuf); + if (pkts == NULL) { + fprintf(outfile, "Couldn't open pcap file %s\n", errbuf); + return 0; + } + + filter = malloc(filterSize); + memcpy(filter, Data+1, filterSize); + //null terminate string + filter[filterSize-1] = 0; + + if (pcap_compile(pkts, &bpf, filter, 1, PCAP_NETMASK_UNKNOWN) == 0) { + //loop over packets + r = pcap_next_ex(pkts, &header, &pkt); + while (r > 0) { + //checks filter + fprintf(outfile, "packet length=%d/%d filter=%d\n",header->caplen, header->len, pcap_offline_filter(&bpf, header, pkt)); + r = pcap_next_ex(pkts, &header, &pkt); + } + //close structure + pcap_close(pkts); + pcap_freecode(&bpf); + } + else { + pcap_close(pkts); + } + free(filter); + + return 0; +} diff --git a/external/bsd/libpcap/dist/testprogs/fuzz/fuzz_both.options b/external/bsd/libpcap/dist/testprogs/fuzz/fuzz_both.options new file mode 100644 index 000000000000..0824b19fab47 --- /dev/null +++ b/external/bsd/libpcap/dist/testprogs/fuzz/fuzz_both.options @@ -0,0 +1,2 @@ +[libfuzzer] +max_len = 65535 diff --git a/external/bsd/libpcap/dist/testprogs/fuzz/fuzz_filter.c b/external/bsd/libpcap/dist/testprogs/fuzz/fuzz_filter.c new file mode 100644 index 000000000000..de350672797f --- /dev/null +++ b/external/bsd/libpcap/dist/testprogs/fuzz/fuzz_filter.c @@ -0,0 +1,43 @@ +#include +#include +#include + +#include + +void fuzz_openFile(const char * name){ + //do nothing +} + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + pcap_t * pkts; + struct bpf_program bpf; + char * filter; + + //we need at least 1 byte for linktype + if (Size < 1) { + return 0; + } + + //initialize structure snaplen = 65535 + pkts = pcap_open_dead(Data[Size-1], 0xFFFF); + if (pkts == NULL) { + printf("pcap_open_dead failed\n"); + return 0; + } + filter = malloc(Size); + memcpy(filter, Data, Size); + //null terminate string + filter[Size-1] = 0; + + if (pcap_compile(pkts, &bpf, filter, 1, PCAP_NETMASK_UNKNOWN) == 0) { + pcap_setfilter(pkts, &bpf); + pcap_close(pkts); + pcap_freecode(&bpf); + } + else { + pcap_close(pkts); + } + free(filter); + + return 0; +} diff --git a/external/bsd/libpcap/dist/testprogs/fuzz/fuzz_filter.options b/external/bsd/libpcap/dist/testprogs/fuzz/fuzz_filter.options new file mode 100644 index 000000000000..9fda93fcb340 --- /dev/null +++ b/external/bsd/libpcap/dist/testprogs/fuzz/fuzz_filter.options @@ -0,0 +1,2 @@ +[libfuzzer] +max_len = 4096 diff --git a/external/bsd/libpcap/dist/testprogs/fuzz/fuzz_pcap.c b/external/bsd/libpcap/dist/testprogs/fuzz/fuzz_pcap.c new file mode 100644 index 000000000000..fba5312fcaf2 --- /dev/null +++ b/external/bsd/libpcap/dist/testprogs/fuzz/fuzz_pcap.c @@ -0,0 +1,80 @@ +#include +#include +#include +#include + +#include + +FILE * outfile = NULL; + +static int bufferToFile(const char * name, const uint8_t *Data, size_t Size) { + FILE * fd; + if (remove(name) != 0) { + if (errno != ENOENT) { + printf("failed remove, errno=%d\n", errno); + return -1; + } + } + fd = fopen(name, "wb"); + if (fd == NULL) { + printf("failed open, errno=%d\n", errno); + return -2; + } + if (fwrite (Data, 1, Size, fd) != Size) { + fclose(fd); + return -3; + } + fclose(fd); + return 0; +} + +void fuzz_openFile(const char * name) { + if (outfile != NULL) { + fclose(outfile); + } + outfile = fopen(name, "w"); +} + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + pcap_t * pkts; + char errbuf[PCAP_ERRBUF_SIZE]; + const u_char *pkt; + struct pcap_pkthdr *header; + struct pcap_stat stats; + int r; + + //initialize output file + if (outfile == NULL) { + outfile = fopen("/dev/null", "w"); + if (outfile == NULL) { + return 0; + } + } + + //rewrite buffer to a file as libpcap does not have buffer inputs + if (bufferToFile("/tmp/fuzz.pcap", Data, Size) < 0) { + return 0; + } + + //initialize structure + pkts = pcap_open_offline("/tmp/fuzz.pcap", errbuf); + if (pkts == NULL) { + fprintf(outfile, "Couldn't open pcap file %s\n", errbuf); + return 0; + } + + //loop over packets + r = pcap_next_ex(pkts, &header, &pkt); + while (r > 0) { + //TODO pcap_offline_filter + fprintf(outfile, "packet length=%d/%d\n",header->caplen, header->len); + r = pcap_next_ex(pkts, &header, &pkt); + } + if (pcap_stats(pkts, &stats) == 0) { + fprintf(outfile, "number of packets=%d\n", stats.ps_recv); + } + //close structure + pcap_close(pkts); + + return 0; +} diff --git a/external/bsd/libpcap/dist/testprogs/fuzz/fuzz_pcap.options b/external/bsd/libpcap/dist/testprogs/fuzz/fuzz_pcap.options new file mode 100644 index 000000000000..0824b19fab47 --- /dev/null +++ b/external/bsd/libpcap/dist/testprogs/fuzz/fuzz_pcap.options @@ -0,0 +1,2 @@ +[libfuzzer] +max_len = 65535 diff --git a/external/bsd/libpcap/dist/testprogs/fuzz/onefile.c b/external/bsd/libpcap/dist/testprogs/fuzz/onefile.c new file mode 100644 index 000000000000..690a63bdc433 --- /dev/null +++ b/external/bsd/libpcap/dist/testprogs/fuzz/onefile.c @@ -0,0 +1,54 @@ +#include +#include +#include + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size); +void fuzz_openFile(const char * name); + +int main(int argc, char** argv) +{ + FILE * fp; + uint8_t *Data; + size_t Size; + + if (argc == 3) { + fuzz_openFile(argv[2]); + } else if (argc != 2) { + return 1; + } + //opens the file, get its size, and reads it into a buffer + fp = fopen(argv[1], "rb"); + if (fp == NULL) { + return 2; + } + if (fseek(fp, 0L, SEEK_END) != 0) { + fclose(fp); + return 2; + } + Size = ftell(fp); + if (Size == (size_t) -1) { + fclose(fp); + return 2; + } + if (fseek(fp, 0L, SEEK_SET) != 0) { + fclose(fp); + return 2; + } + Data = malloc(Size); + if (Data == NULL) { + fclose(fp); + return 2; + } + if (fread(Data, Size, 1, fp) != 1) { + fclose(fp); + free(Data); + return 2; + } + + //launch fuzzer + LLVMFuzzerTestOneInput(Data, Size); + free(Data); + fclose(fp); + return 0; +} + diff --git a/external/bsd/libpcap/dist/testprogs/nonblocktest.c b/external/bsd/libpcap/dist/testprogs/nonblocktest.c new file mode 100644 index 000000000000..72700a3b64a1 --- /dev/null +++ b/external/bsd/libpcap/dist/testprogs/nonblocktest.c @@ -0,0 +1,187 @@ +/* + * 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" + +/* + * Tests for pcap_set_nonblock / pcap_get_nonblock: + * - idempotency + * - set/get are symmetric + * - get returns the same before/after activate + * - pcap_breakloop works after setting nonblock on and then off + * + * Really this is meant to + * be run manually under strace, to check for extra + * calls to eventfd or close. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static pcap_t *pd; +static char *program_name = "nonblocktest"; +/* Forwards */ +static void PCAP_NORETURN usage(void); +static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2); +static void warning(const char *, ...) PCAP_PRINTFLIKE(1, 2); + +/* 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); + } +} + +static void +usage(void) +{ + (void)fprintf(stderr, "Usage: %s [ -i interface ]\n", + program_name); + exit(1); +} + +static void +breakme(u_char *user _U_, const struct pcap_pkthdr *h _U_, const u_char *sp _U_) +{ + warning("using pcap_breakloop()"); + pcap_breakloop(pd); +} + +int +main(int argc, char **argv) +{ + int status, op, i, ret; + char *device; + pcap_if_t *devlist; + char ebuf[PCAP_ERRBUF_SIZE]; + + device = NULL; + while ((op = getopt(argc, argv, "i:sptnq")) != -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); + warning("listening on %s", device); + pcap_freealldevs(devlist); + } + *ebuf = '\0'; + pd = pcap_create(device, ebuf); + if (pd == NULL) + error("%s", ebuf); + else if (*ebuf) + warning("%s", ebuf); + /* set nonblock before activate */ + if (pcap_setnonblock(pd, 1, ebuf) < 0) + error("pcap_setnonblock failed: %s", ebuf); + /* getnonblock just returns "not activated yet" */ + ret = pcap_getnonblock(pd, ebuf); + if (ret != PCAP_ERROR_NOT_ACTIVATED) + error("pcap_getnonblock unexpectedly succeeded"); + if ((status = pcap_activate(pd)) < 0) + error("pcap_activate failed"); + ret = pcap_getnonblock(pd, ebuf); + if (ret != 1) + error( "pcap_getnonblock did not return nonblocking" ); + + /* Set nonblock multiple times, ensure with strace that it's a noop */ + for (i=0; i<10; i++) { + if (pcap_setnonblock(pd, 1, ebuf) < 0) + error("pcap_setnonblock failed: %s", ebuf); + ret = pcap_getnonblock(pd, ebuf); + if (ret != 1) + error( "pcap_getnonblock did not return nonblocking" ); + } + /* Set block multiple times, ensure with strace that it's a noop */ + for (i=0; i<10; i++) { + if (pcap_setnonblock(pd, 0, ebuf) < 0) + error("pcap_setnonblock failed: %s", ebuf); + ret = pcap_getnonblock(pd, ebuf); + if (ret != 0) + error( "pcap_getnonblock did not return blocking" ); + } + + /* Now pcap_loop forever, with a callback that + * uses pcap_breakloop to get out of forever */ + pcap_loop(pd, -1, breakme, NULL); + + /* Now test that pcap_setnonblock fails if we can't open the + * eventfd. */ + if (pcap_setnonblock(pd, 1, ebuf) < 0) + error("pcap_setnonblock failed: %s", ebuf); + while (1) { + ret = open("/dev/null", O_RDONLY); + if (ret < 0) + break; + } + ret = pcap_setnonblock(pd, 0, ebuf); + if (ret == 0) + error("pcap_setnonblock succeeded even though file table is full"); + else + warning("pcap_setnonblock failed as expected: %s", ebuf); +} diff --git a/external/bsd/libpcap/dist/testprogs/opentest.c b/external/bsd/libpcap/dist/testprogs/opentest.c index bad38eb0e9fb..a441dda1268f 100644 --- a/external/bsd/libpcap/dist/testprogs/opentest.c +++ b/external/bsd/libpcap/dist/testprogs/opentest.c @@ -45,7 +45,7 @@ The Regents of the University of California. All rights reserved.\n"; #include "portability.h" #endif -#define MAXIMUM_SNAPLEN 65535 +#define MAXIMUM_SNAPLEN 262144 static char *program_name; @@ -81,7 +81,7 @@ main(int argc, char **argv) switch (op) { case 'i': - device = optarg; + device = strdup(optarg); break; case 'I': @@ -95,13 +95,19 @@ main(int argc, char **argv) case 's': { char *end; + long long_snaplen; - snaplen = strtol(optarg, &end, 0); + long_snaplen = strtol(optarg, &end, 0); if (optarg == end || *end != '\0' - || snaplen < 0 || snaplen > MAXIMUM_SNAPLEN) + || long_snaplen < 0 + || long_snaplen > MAXIMUM_SNAPLEN) error("invalid snaplen %s", optarg); - else if (snaplen == 0) - snaplen = MAXIMUM_SNAPLEN; + else { + if (snaplen == 0) + snaplen = MAXIMUM_SNAPLEN; + else + snaplen = (int)long_snaplen; + } break; } @@ -186,6 +192,7 @@ main(int argc, char **argv) else printf("%s opened successfully\n", device); } + free(device); pcap_close(pd); exit(status < 0 ? 1 : 0); } diff --git a/external/bsd/libpcap/dist/testprogs/reactivatetest.c b/external/bsd/libpcap/dist/testprogs/reactivatetest.c index d7f3e322c175..a9c987aa5015 100644 --- a/external/bsd/libpcap/dist/testprogs/reactivatetest.c +++ b/external/bsd/libpcap/dist/testprogs/reactivatetest.c @@ -51,7 +51,6 @@ main(void) if (pd == NULL) { error("Neither lo0 nor lo could be opened: %s", ebuf); - return 2; } } status = pcap_activate(pd); diff --git a/external/bsd/libpcap/dist/testprogs/selpolltest.c b/external/bsd/libpcap/dist/testprogs/selpolltest.c index 329281dc24bc..ab7f8f462a0a 100644 --- a/external/bsd/libpcap/dist/testprogs/selpolltest.c +++ b/external/bsd/libpcap/dist/testprogs/selpolltest.c @@ -69,13 +69,13 @@ main(int argc, char **argv) register int op; bpf_u_int32 localnet, netmask; register char *cp, *cmdbuf, *device; - int doselect, dopoll, dotimeout, dononblock; + int doselect, dopoll, dotimeout, dononblock, quiet; const char *mechanism; struct bpf_program fcode; char ebuf[PCAP_ERRBUF_SIZE]; pcap_if_t *devlist; - int selectable_fd; - struct timeval *required_timeout; + int selectable_fd = -1; + const struct timeval *required_timeout; int status; int packet_count; @@ -85,13 +85,14 @@ main(int argc, char **argv) mechanism = NULL; dotimeout = 0; dononblock = 0; + quiet = 0; if ((cp = strrchr(argv[0], '/')) != NULL) program_name = cp + 1; else program_name = argv[0]; opterr = 0; - while ((op = getopt(argc, argv, "i:sptn")) != -1) { + while ((op = getopt(argc, argv, "i:sptnq")) != -1) { switch (op) { case 'i': @@ -116,6 +117,10 @@ main(int argc, char **argv) dononblock = 1; break; + case 'q': + quiet = 1; + break; + default: usage(); /* NOTREACHED */ @@ -196,6 +201,7 @@ main(int argc, char **argv) for (;;) { fd_set setread, setexcept; struct timeval seltimeout; + struct timeval *timeoutp; FD_ZERO(&setread); if (selectable_fd != -1) { @@ -203,6 +209,7 @@ main(int argc, char **argv) FD_ZERO(&setexcept); FD_SET(selectable_fd, &setexcept); } + required_timeout = pcap_get_required_select_timeout(pd); if (dotimeout) { seltimeout.tv_sec = 0; if (required_timeout != NULL && @@ -210,37 +217,34 @@ main(int argc, char **argv) seltimeout.tv_usec = required_timeout->tv_usec; else seltimeout.tv_usec = 1000; - status = select(selectable_fd + 1, &setread, - NULL, &setexcept, &seltimeout); + timeoutp = &seltimeout; } else if (required_timeout != NULL) { seltimeout = *required_timeout; - status = select(selectable_fd + 1, &setread, - NULL, &setexcept, &seltimeout); + timeoutp = &seltimeout; } else { - status = select((selectable_fd == -1) ? - 0 : selectable_fd + 1, &setread, - NULL, &setexcept, NULL); + timeoutp = NULL; } + status = select((selectable_fd == -1) ? + 0 : selectable_fd + 1, &setread, NULL, &setexcept, + timeoutp); if (status == -1) { printf("Select returns error (%s)\n", strerror(errno)); } else { - if (selectable_fd == -1) { - if (status != 0) - printf("Select returned a descriptor\n"); - } else { + if (!quiet) { if (status == 0) printf("Select timed out: "); - else + 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 (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, @@ -268,11 +272,12 @@ main(int argc, char **argv) fd.fd = selectable_fd; fd.events = POLLIN; + required_timeout = pcap_get_required_select_timeout(pd); if (dotimeout) polltimeout = 1; else if (required_timeout != NULL && required_timeout->tv_usec >= 1000) - polltimeout = required_timeout->tv_usec/1000; + polltimeout = (int)(required_timeout->tv_usec/1000); else polltimeout = -1; status = poll(&fd, (selectable_fd == -1) ? 0 : 1, polltimeout); @@ -280,10 +285,7 @@ main(int argc, char **argv) printf("Poll returns error (%s)\n", strerror(errno)); } else { - if (selectable_fd == -1) { - if (status != 0) - printf("Poll returned a descriptor\n"); - } else { + if (!quiet) { if (status == 0) printf("Poll timed out\n"); else { @@ -349,7 +351,7 @@ main(int argc, char **argv) /* * Error. Report it. */ - (void)fprintf(stderr, "%s: pcap_loop: %s\n", + (void)fprintf(stderr, "%s: pcap_dispatch: %s\n", program_name, pcap_geterr(pd)); } pcap_close(pd); @@ -367,7 +369,7 @@ countme(u_char *user, const struct pcap_pkthdr *h _U_, const u_char *sp _U_) static void usage(void) { - (void)fprintf(stderr, "Usage: %s [ -sptn ] [ -i interface ] [expression]\n", + (void)fprintf(stderr, "Usage: %s [ -sptnq ] [ -i interface ] [expression]\n", program_name); exit(1); } @@ -415,7 +417,7 @@ static char * copy_argv(register char **argv) { register char **p; - register u_int len = 0; + register size_t len = 0; char *buf; char *src, *dst; diff --git a/external/bsd/libpcap/dist/testprogs/threadsignaltest.c b/external/bsd/libpcap/dist/testprogs/threadsignaltest.c index a60bb49523fb..c9ade76fe5b5 100644 --- a/external/bsd/libpcap/dist/testprogs/threadsignaltest.c +++ b/external/bsd/libpcap/dist/testprogs/threadsignaltest.c @@ -157,7 +157,7 @@ capture_thread_func(THREAD_FUNC_ARG_TYPE arg) } else printf("No packets seen by pcap_dispatch\n"); } - if (status == -2) { + if (status == PCAP_ERROR_BREAK) { /* * We got interrupted, so perhaps we didn't * manage to finish a line we were printing. @@ -167,11 +167,11 @@ capture_thread_func(THREAD_FUNC_ARG_TYPE arg) printf("Loop got broken\n"); } (void)fflush(stdout); - if (status == -1) { + if (status == PCAP_ERROR) { /* * Error. Report it. */ - (void)fprintf(stderr, "%s: pcap_loop: %s\n", + (void)fprintf(stderr, "%s: pcap_dispatch: %s\n", program_name, pcap_geterr(pd)); } return 0; @@ -182,7 +182,7 @@ main(int argc, char **argv) { register int op; register char *cp, *cmdbuf, *device; - int immediate = 0; + int do_wakeup = 1; pcap_if_t *devlist; bpf_u_int32 localnet, netmask; struct bpf_program fcode; @@ -200,13 +200,17 @@ main(int argc, char **argv) program_name = argv[0]; opterr = 0; - while ((op = getopt(argc, argv, "i:")) != -1) { + while ((op = getopt(argc, argv, "i:n")) != -1) { switch (op) { case 'i': device = optarg; break; + case 'n': + do_wakeup = 0; + break; + default: usage(); /* NOTREACHED */ @@ -229,12 +233,6 @@ main(int argc, char **argv) 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", @@ -280,21 +278,39 @@ main(int argc, char **argv) error("Can't create capture thread: %s", strerror(status)); #endif sleep_secs(60); + printf("Doing pcap_breakloop()\n"); pcap_breakloop(pd); + if (do_wakeup) { + /* + * Force a wakeup in the capture thread. + * + * On some platforms, with some devices,, pcap_breakloop() + * can't do that itself. On Windows, poke the device's + * event handle; on UN*X, send a SIGUSR1 to the thread. + */ +#ifdef _WIN32 + printf("Setting event\n"); + if (!SetEvent(pcap_getevent(pd))) + error("Can't set event for pcap_t: %s", + win32_strerror(GetLastError())); +#else + printf("Sending SIGUSR1\n"); + status = pthread_kill(capture_thread, SIGUSR1); + if (status != 0) + warning("Can't interrupt capture thread: %s", + strerror(status)); +#endif + } + + /* + * Now wait for the capture thread to terminate. + */ #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", @@ -317,7 +333,7 @@ countme(u_char *user, const struct pcap_pkthdr *h _U_, const u_char *sp _U_) static void usage(void) { - (void)fprintf(stderr, "Usage: %s [ -m ] [ -i interface ] [ -t timeout] [expression]\n", + (void)fprintf(stderr, "Usage: %s [ -n ] [ -i interface ] [ expression ]\n", program_name); exit(1); } @@ -365,7 +381,7 @@ static char * copy_argv(register char **argv) { register char **p; - register u_int len = 0; + register size_t len = 0; char *buf; char *src, *dst; diff --git a/external/bsd/libpcap/dist/testprogs/valgrindtest.c b/external/bsd/libpcap/dist/testprogs/valgrindtest.c index 104ef6a9feaa..55055ca3d9ba 100644 --- a/external/bsd/libpcap/dist/testprogs/valgrindtest.c +++ b/external/bsd/libpcap/dist/testprogs/valgrindtest.c @@ -59,6 +59,7 @@ The Regents of the University of California. All rights reserved.\n"; #include #include #include +#include #include #include #include @@ -99,6 +100,23 @@ The Regents of the University of California. All rights reserved.\n"; #endif +/* + * Squelch a warning. + * + * We include system headers to be able to directly set the filter to + * a program with uninitialized content, to make sure what we're testing + * is Valgrind's checking of the system call to set the filter, and we + * also include to open the device in the first place, and that + * means that we may get collisions between their definitions of + * BPF_STMT and BPF_JUMP - and do, in fact, get them on Linux (the + * definitions may be semantically the same, but that's not sufficient to + * avoid the warnings, as the preprocessor doesn't know that u_short is + * just unsigned short). + * + * So we undefine BPF_STMT and BPF_JUMP to avoid the warning. + */ +#undef BPF_STMT +#undef BPF_JUMP #include static char *program_name; @@ -132,11 +150,21 @@ read_infile(char *fname) if (fstat(fd, &buf) < 0) error("can't stat %s: %s", fname, pcap_strerror(errno)); + /* + * _read(), on Windows, has an unsigned int byte count and an + * int return value, so we can't handle a file bigger than + * INT_MAX - 1 bytes (and have no reason to do so; a filter *that* + * big will take forever to compile). (The -1 is for the '\0' at + * the end of the string.) + */ + if (buf.st_size > INT_MAX - 1) + error("%s is larger than %d bytes; that's too large", fname, + INT_MAX - 1); cp = malloc((u_int)buf.st_size + 1); if (cp == NULL) error("malloc(%d) for %s: %s", (u_int)buf.st_size + 1, fname, pcap_strerror(errno)); - cc = read(fd, cp, (u_int)buf.st_size); + cc = (int)read(fd, cp, (u_int)buf.st_size); if (cc < 0) error("read %s: %s", fname, pcap_strerror(errno)); if (cc != buf.st_size) @@ -196,7 +224,7 @@ static char * copy_argv(register char **argv) { register char **p; - register u_int len = 0; + register size_t len = 0; char *buf; char *src, *dst; @@ -421,7 +449,7 @@ usage(void) (void)fprintf(stderr, "%s, with %s\n", program_name, pcap_lib_version()); (void)fprintf(stderr, - "Usage: %s [-aI] [ -F file ] [ -I interface ] [ expression ]\n", + "Usage: %s [-aI] [ -F file ] [ -i interface ] [ expression ]\n", program_name); exit(1); } diff --git a/external/bsd/libpcap/dist/testprogs/visopts.py b/external/bsd/libpcap/dist/testprogs/visopts.py new file mode 100755 index 000000000000..97eafffff4f0 --- /dev/null +++ b/external/bsd/libpcap/dist/testprogs/visopts.py @@ -0,0 +1,317 @@ +#!/usr/bin/env python + +""" +This program parses the output from pcap_compile() to visualize the CFG after +each optimize phase. + +Usage guide: +1. Enable optimizer 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 + (Graphviz must be installed) +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. Open the URL at the 3rd line in a browser. + +Note: +1. The CFG is translated to SVG images, expr1.html embeds them as external + documents. If you open expr1.html as local file using file:// protocol, some + browsers will deny such requests so the web page will not work properly. + For Chrome, you can run it using the following command to avoid this: + chromium --disable-web-security + That's why this program starts a localhost HTTP server. +2. expr1.html uses jQuery from https://ajax.googleapis.com, so it needs Internet + access to work. +""" + +import sys, os +import string +import subprocess +import json + +html_template = string.Template(""" + + + BPF compiler optimization phases for $expr + + + + + + + +

      +

      $expr

      +
      + +          + +
      +
      +
      + +
      +
      +
      +
      +
      + + +""") + +def write_html(expr, gcount, logs): + logs = map(lambda s: s.strip().replace("\n", "
      "), 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: + try: + p = subprocess.Popen(['dot', '-Tsvg'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) + except OSError as ose: + print "Failed to run 'dot':", ose + print "(Is Graphviz installed?)" + exit(1) + + 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 program has 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/external/bsd/libpcap/dist/testprogs/writecaptest.c b/external/bsd/libpcap/dist/testprogs/writecaptest.c new file mode 100644 index 000000000000..4db532c6e621 --- /dev/null +++ b/external/bsd/libpcap/dist/testprogs/writecaptest.c @@ -0,0 +1,556 @@ +/* + * 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 +#include +#include +#include +#include +#ifdef _WIN32 + #include "getopt.h" +#else + #include +#endif +#include +#ifndef _WIN32 + #include +#endif +#include + +#include + +#include "pcap/funcattrs.h" + +#ifdef _WIN32 + #include "portability.h" +#endif + +static char *program_name; + +/* Forwards */ +static void PCAP_NORETURN usage(void); +static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2); +static void warning(const char *, ...) PCAP_PRINTFLIKE(1, 2); +static char *copy_argv(char **); + +static pcap_t *pd; + +#ifdef _WIN32 +static BOOL WINAPI +stop_capture(DWORD ctrltype _U_) +{ + pcap_breakloop(pd); + return TRUE; +} +#else +static void +stop_capture(int signum _U_) +{ + pcap_breakloop(pd); +} +#endif + +static long +parse_interface_number(const char *device) +{ + const char *p; + long devnum; + char *end; + + /* + * Search for a colon, terminating any scheme at the beginning + * of the device. + */ + p = strchr(device, ':'); + if (p != NULL) { + /* + * We found it. Is it followed by "//"? + */ + p++; /* skip the : */ + if (strncmp(p, "//", 2) == 0) { + /* + * Yes. Search for the next /, at the end of the + * authority part of the URL. + */ + p += 2; /* skip the // */ + p = strchr(p, '/'); + if (p != NULL) { + /* + * OK, past the / is the path. + */ + device = p + 1; + } + } + } + devnum = strtol(device, &end, 10); + if (device != end && *end == '\0') { + /* + * It's all-numeric, but is it a valid number? + */ + if (devnum <= 0) { + /* + * No, it's not an ordinal. + */ + error("Invalid adapter index"); + } + return (devnum); + } else { + /* + * It's not all-numeric; return -1, so our caller + * knows that. + */ + return (-1); + } +} + +static char * +find_interface_by_number(long devnum) +{ + pcap_if_t *dev, *devlist; + long i; + char ebuf[PCAP_ERRBUF_SIZE]; + char *device; + int status; + + status = pcap_findalldevs(&devlist, ebuf); + if (status < 0) + error("%s", ebuf); + /* + * Look for the devnum-th entry in the list of devices (1-based). + */ + for (i = 0, dev = devlist; i < devnum-1 && dev != NULL; + i++, dev = dev->next) + ; + if (dev == NULL) + error("Invalid adapter index"); + device = strdup(dev->name); + pcap_freealldevs(devlist); + return (device); +} + +static pcap_t * +open_interface(const char *device, int snaplen_set, int snaplen, char *ebuf) +{ + pcap_t *pc; + int status; + char *cp; + + pc = pcap_create(device, ebuf); + if (pc == NULL) { + /* + * If this failed with "No such device", that means + * the interface doesn't exist; return NULL, so that + * the caller can see whether the device name is + * actually an interface index. + */ + if (strstr(ebuf, "No such device") != NULL) + return (NULL); + error("%s", ebuf); + } + if (snaplen_set) { + status = pcap_set_snaplen(pc, snaplen); + if (status != 0) + error("%s: pcap_set_snaplen failed: %s", + device, pcap_statustostr(status)); + } + status = pcap_set_timeout(pc, 100); + if (status != 0) + error("%s: pcap_set_timeout failed: %s", + device, pcap_statustostr(status)); + status = pcap_activate(pc); + if (status < 0) { + /* + * pcap_activate() failed. + */ + cp = pcap_geterr(pc); + if (status == PCAP_ERROR) + error("%s", cp); + else if (status == PCAP_ERROR_NO_SUCH_DEVICE) { + /* + * Return an error for our caller to handle. + */ + snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s\n(%s)", + device, pcap_statustostr(status), cp); + } else if (status == PCAP_ERROR_PERM_DENIED && *cp != '\0') + error("%s: %s\n(%s)", device, + pcap_statustostr(status), cp); + else + error("%s: %s", device, + pcap_statustostr(status)); + pcap_close(pc); + return (NULL); + } else if (status > 0) { + /* + * pcap_activate() succeeded, but it's warning us + * of a problem it had. + */ + cp = pcap_geterr(pc); + if (status == PCAP_WARNING) + warning("%s", cp); + else if (status == PCAP_WARNING_PROMISC_NOTSUP && + *cp != '\0') + warning("%s: %s\n(%s)", device, + pcap_statustostr(status), cp); + else + warning("%s: %s", device, + pcap_statustostr(status)); + } + return (pc); +} + +#define COMMAND_OPTIONS "DLi:s:w:y:" + +int +main(int argc, char **argv) +{ + int op; + char *cp, *cmdbuf = NULL, *device, *end, *savefile = NULL; + int snaplen = 0; + int snaplen_set = 0; + pcap_if_t *devlist; + long devnum; + int show_interfaces = 0; + int show_dlt_types = 0; + int ndlts; + int *dlts; + bpf_u_int32 localnet, netmask; + struct bpf_program fcode; + char ebuf[PCAP_ERRBUF_SIZE]; +#ifndef _WIN32 + struct sigaction action; +#endif + int dlt; + const char *dlt_name = NULL; + int status; + pcap_dumper_t *pdd; + + device = NULL; + if ((cp = strrchr(argv[0], '/')) != NULL) + program_name = cp + 1; + else + program_name = argv[0]; + + opterr = 0; + while ((op = getopt(argc, argv, COMMAND_OPTIONS)) != -1) { + switch (op) { + + case 'D': + show_interfaces = 1; + break; + + case 'L': + show_dlt_types = 1; + break; + + case 'i': + device = optarg; + break; + + case 's': + snaplen = (int)strtol(optarg, &end, 0); + if (optarg == end || *end != '\0' || snaplen < 0) + error("invalid snaplen %s (must be >= 0)", + optarg); + snaplen_set = 1; + break; + + case 'w': + savefile = optarg; + break; + + case 'y': + dlt_name = optarg; + break; + + default: + usage(); + /* NOTREACHED */ + } + } + + if (show_interfaces) { + pcap_if_t *dev; + int i; + + if (pcap_findalldevs(&devlist, ebuf) < 0) + error("%s", ebuf); + for (i = 0, dev = devlist; dev != NULL; i++, dev = dev->next) { + printf("%d.%s", i+1, dev->name); + if (dev->description != NULL) + printf(" (%s)", dev->description); + printf("\n"); + } + pcap_freealldevs(devlist); + return (0); + } + + 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); + } + if (show_dlt_types) { + pd = pcap_create(device, ebuf); + if (pd == NULL) + error("%s", ebuf); + status = pcap_activate(pd); + if (status < 0) { + /* + * pcap_activate() failed. + */ + error("%s: %s\n(%s)", device, + pcap_statustostr(status), pcap_geterr(pd)); + } + ndlts = pcap_list_datalinks(pd, &dlts); + if (ndlts < 0) { + /* + * pcap_list_datalinks() failed. + */ + error("%s: %s\n(%s)", device, + pcap_statustostr(status), pcap_geterr(pd)); + } + for (int i = 0; i < ndlts; i++) { + dlt_name = pcap_datalink_val_to_name(dlts[i]); + if (dlt_name == NULL) + printf("DLT %d", dlts[i]); + else + printf("%s", dlt_name); + printf("\n"); + } + pcap_free_datalinks(dlts); + pcap_close(pd); + return 0; + } + + if (savefile == NULL) + error("no savefile specified"); + + *ebuf = '\0'; + + pd = open_interface(device, snaplen_set, snaplen, ebuf); + if (pd == NULL) { + /* + * That failed because the interface couldn't be found. + * + * If we can get a list of interfaces, and the interface name + * is purely numeric, try to use it as a 1-based index + * in the list of interfaces. + */ + devnum = parse_interface_number(device); + if (devnum == -1) { + /* + * It's not a number; just report + * the open error and fail. + */ + error("%s", ebuf); + } + + /* + * OK, it's a number; try to find the + * interface with that index, and try + * to open it. + * + * find_interface_by_number() exits if it + * couldn't be found. + */ + device = find_interface_by_number(devnum); + pd = open_interface(device, snaplen_set, snaplen, ebuf); + if (pd == NULL) + error("%s", ebuf); + } + + if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) { + localnet = 0; + netmask = 0; + warning("%s", ebuf); + } + + if (dlt_name != NULL) { + dlt = pcap_datalink_name_to_val(dlt_name); + if (dlt == PCAP_ERROR) + error("%s isn't a valid DLT name", dlt_name); + if (pcap_set_datalink(pd, dlt) == PCAP_ERROR) + error("%s: %s", device, pcap_geterr(pd)); + } + + /* + * Don't set a filter unless we were given one on the + * command line; if capturing doesn't work, or doesn't + * use the snapshot length, without a filter, that's + * a bug. + */ + if (optind < argc) { + 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)); + } + + pdd = pcap_dump_open(pd, savefile); + if (pdd == NULL) + error("%s", pcap_geterr(pd)); + +#ifdef _WIN32 + SetConsoleCtrlHandler(stop_capture, TRUE); +#else + action.sa_handler = stop_capture; + sigemptyset(&action.sa_mask); + action.sa_flags = 0; + if (sigaction(SIGINT, &action, NULL) == -1) + error("Can't catch SIGINT: %s\n", strerror(errno)); +#endif + + printf("Listening on %s, link-type ", device); + dlt = pcap_datalink(pd); + dlt_name = pcap_datalink_val_to_name(dlt); + if (dlt_name == NULL) + printf("DLT %d", dlt); + else + printf("%s", dlt_name); + printf("\n"); + for (;;) { + status = pcap_dispatch(pd, -1, pcap_dump, (u_char *)pdd); + if (status < 0) + break; + if (status != 0) { + printf("%d packets seen\n", status); + struct pcap_stat ps; + pcap_stats(pd, &ps); + printf("%d ps_recv, %d ps_drop, %d ps_ifdrop\n", + ps.ps_recv, ps.ps_drop, ps.ps_ifdrop); + } + } + 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("Broken out of loop from SIGINT handler\n"); + } + (void)fflush(stdout); + if (status == -1) { + /* + * Error. Report it. + */ + (void)fprintf(stderr, "%s: pcap_dispatch: %s\n", + program_name, pcap_geterr(pd)); + } + pcap_close(pd); + if (cmdbuf != NULL) { + pcap_freecode(&fcode); + free(cmdbuf); + } + exit(status == -1 ? 1 : 0); +} + +static void +usage(void) +{ + (void)fprintf(stderr, "Usage: %s -D -L [ -i interface ] [ -s snaplen ] [ -w file ] [ -y dlt ] [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 size_t 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/external/bsd/libpcap/dist/tests/pcap-invalid-version-1.pcap b/external/bsd/libpcap/dist/tests/pcap-invalid-version-1.pcap new file mode 100644 index 0000000000000000000000000000000000000000..9dd0429d22f757ea4382660620dc0e32c4caa78a GIT binary patch literal 530 zcmca|c+)~g1{MYw`2U}Qff2~r?tk7tx`dhG6_5kM#>PNlwhc2iPF!)w|NjAH{xd=NU=pZaN<&J6af@cJ78BzN7B&Wk$6|~VIJg)b7#RNlU%3AN ze@>u!ZZ-xc{|g5{@Q5+Ut>s^Swl_**#+wk%6K`*2Y+kcSx`9WD!KlgdQ}fMMmii?- zTBrYgtdbIX?8)7U)gq3EKCjT8UtCtgLRFj3oc<-qy6|Ge2h%CeM0l~uqXjqBWlGoY;mBd(8> zJpF&3#wn)9pFH2E7&+~}f8@dRS2AaA`+x7arMZ~TJI?kNaS|_ literal 0 HcmV?d00001 diff --git a/external/bsd/libpcap/dist/tests/pcap-invalid-version-2.pcap b/external/bsd/libpcap/dist/tests/pcap-invalid-version-2.pcap new file mode 100644 index 0000000000000000000000000000000000000000..4217d1e7a9ec8a556e803b892736e2f1b368b8fe GIT binary patch literal 530 zcmca|c+)~A237_b`2U}Qff2~r?tk7tx`dhG6_5kM#>PNlwhc2iPF!)w|NjAH{xd=NU=pZaN<&J6af@cJ78BzN7B&Wk$6|~VIJg)b7#RNlU%3AN ze@>u!ZZ-xc{|g5{@Q5+Ut>s^Swl_**#+wk%6K`*2Y+kcSx`9WD!KlgdQ}fMMmii?- zTBrYgtdbIX?8)7U)gq3EKCjT8UtCtgLRFj3oc<-qy6|Ge2h%CeM0l~uqXjqBWlGoY;mBd(8> zJpF&3#wn)9pFH2E7&+~}f8@dRS2AaA`+x7arMZ~TJI?oV&r)M literal 0 HcmV?d00001 diff --git a/external/bsd/libpcap/dist/tests/pcapng-invalid-vers-1.pcapng b/external/bsd/libpcap/dist/tests/pcapng-invalid-vers-1.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..7bbb7ab0cdae497f32c0965666b163113bf1993e GIT binary patch literal 260 zcmd<$<>fMAU|{gI(UxLhU}X3Y1uP7F46Z4eCCP~e3Wj=y26|>dML+;j%Lv2@Q2PIW z1_n-`2pfK8`fEfMAU|{gI(UxLlU}X3Y1uP7F46Z4eCCP~e3Wj=y26|>dML+;j%Lv2@Q2PIW z1_n-`2pfK8`fE{}eH*o*} literal 0 HcmV?d00001