xref: /src/contrib/libpcap/CMakeLists.txt (revision 16cef5f7a65588def71db4fdfa961f959847e3b6)
1if(WIN32)
2    #
3    # We need 3.12 or later, so that we can set policy CMP0074; see
4    # below.
5    #
6    cmake_minimum_required(VERSION 3.12)
7else(WIN32)
8    #
9    # For now:
10    #
11    #  if this is a version of CMake less than 3.5, require only
12    #  2.8.12, just in case somebody is configuring with CMake
13    #  on a "long-term support" version # of some OS and that
14    #  version supplies an older version of CMake;
15    #
16    #  otherwise, if it's a version less than 3.10, require only
17    #  3.5, just in case somebody is configuring with CMake
18    #  on a "long-term support" version # of some OS and that
19    #  version supplies an older version of CMake;
20    #
21    #  otherwise, require 3.10, so we don't get messages warning
22    #  that support for versions of CMake lower than 3.10 is
23    #  deprecated.
24    #
25    if(CMAKE_VERSION VERSION_LESS "3.5")
26        cmake_minimum_required(VERSION 2.8.12)
27    elseif(CMAKE_VERSION VERSION_LESS "3.10")
28        cmake_minimum_required(VERSION 3.5)
29    else()
30        cmake_minimum_required(VERSION 3.10)
31    endif()
32endif(WIN32)
33
34#
35# Apple doesn't build with an install_name starting with @rpath, and
36# neither do we with autotools; don't do so with CMake, either, and
37# suppress warnings about that.
38#
39# Setting CMAKE_MACOSX_RPATH to FALSE uses the old behavior,
40# but removes the POLICY CMP0042 OLD deprecated warning.
41# See https://cmake.org/cmake/help/latest/policy/CMP0042.html
42#
43if (NOT DEFINED CMAKE_MACOSX_RPATH)
44    set(CMAKE_MACOSX_RPATH FALSE)
45endif()
46if(POLICY CMP0042)
47    cmake_policy(SET CMP0042 NEW)
48endif()
49
50#
51# Squelch noise about quoted strings in if() statements.
52# WE KNOW WHAT WE'RE DOING, WE'RE DOING EVERYTHING THE WAY THAT NEWER
53# VERSIONS OF CMAKE EXPECT BY DEFAULT, DON'T WASTE OUR TIME WITH NOISE.
54#
55if(POLICY CMP0054)
56    cmake_policy(SET CMP0054 NEW)
57endif()
58
59#
60# We want find_file() and find_library() to honor {packagename}_ROOT,
61# as that appears to be the only way, with the Visual Studio 2019 IDE
62# and its CMake support, to tell CMake where to look for the Npcap
63# or WinPcap SDK.
64#
65if(POLICY CMP0074)
66    cmake_policy(SET CMP0074 NEW)
67endif()
68
69#
70# We want check_include_file() to honor CMAKE_REQUIRED_LIBRARIES; see
71# the big comment before the check_include_file() test for
72# infiniband/verbs.h for the reason.
73#
74if(POLICY CMP0075)
75    cmake_policy(SET CMP0075 NEW)
76endif()
77
78set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
79
80#
81# We explicitly indicate what languages are used in libpcap to avoid
82# checking for a C++ compiler.
83#
84# One reason to avoid that check is that there's no need to waste
85# configuration time performing it.
86#
87# Another reason is that:
88#
89# CMake will try to determine the sizes of some data types, including
90# void *, early in the process of configuration; apparently, it's done
91# as part of processing the project() command.
92#
93# At least as of CMake 2.8.6, it does so by checking the size of
94# "void *" in C, setting CMAKE_C_SIZEOF_DATA_PTR based on that,
95# setting CMAKE_SIZEOF_VOID_P to that, and then checking the size
96# of "void *" in C++, setting CMAKE_CXX_SIZEOF_DATA_PTR based on
97# that, and then setting CMAKE_SIZEOF_VOID_P to *that*.
98#
99# The compile tests include whatever C flags may have been provided
100# to CMake in the CFLAGS and CXXFLAGS environment variables.
101#
102# If you set an architecture flag such as -m32 or -m64 in CFLAGS
103# but *not* in CXXFLAGS, the size for C++ will win, and hilarity
104# will ensue.
105#
106# Or if, at least on Solaris, you have a newer version of GCC
107# installed, but *not* a newer version of G++, and you have Oracle
108# Studio installed, it will find GCC, which will default to building
109# 64-bit, and Oracle Studio's C++ compiler, which will default to
110# building 32-bit, the size for C++ will win, and, again, hilarity
111# will ensue.
112#
113project(pcap C)
114
115#
116# Setting CMAKE_MACOSX_RPATH to FALSE causes the installed
117# libpcap.A.dylib to have just libpcap.A.dylib as the install
118# name;  Apple built libpcap with an install_name of /usr/lib/libpcap.A.dylib
119# (back when they still shipped individual system dylibs rather than
120# shipping a pre-built shared library cache, at least), and we do the
121# same with autotools; do the same with CMake.
122#
123if (NOT DEFINED CMAKE_INSTALL_NAME_DIR)
124    set(CMAKE_INSTALL_NAME_DIR ${CMAKE_INSTALL_PREFIX}/lib)
125endif()
126
127#
128# For getting raw lists of --libs and --libs --static information from a
129# pkg-config module.
130#
131# In CMake up to 2.8.12, pkg_check_modules() sets:
132#
133#    <XPREFIX>_LIBRARIES, which is a list of library names to which, on
134#      a UN*X, -l can be prefixed - i.e., names, without extensions,
135#      rather than full paths to the file.
136#    <XPREFIX>_LIBRARY_DIRS, which is a list of paths to directories
137#      containing the libraries, to which, on a UN*X, -L can be
138#      prefixed.
139#    <XPREFIX>_LDFLAGS, which is a list of *all* required linker flags
140#    <XPREFIX>_LDFLAGS_OTHER, which is a list of all linker flags other
141#      than -l and -L flags
142#
143# In 3.0 (at least as of 3.0.2), it also sets:
144#
145#    <XPREFIX>_LINK_LIBRARIES, which is a list of full paths to the
146#      library files.
147#
148# but if <XPREFIX> is <PREFIX>_STATIC, <XPREFIX>_LINK_LIBRARIES is
149# currently not set by CMake.
150#
151# Unfortunately, pkg_check_modules() sets the
152# PKG_CONFIG_ALLOW_SYSTEM_LIBS environment variable when running
153# pkg-config, so the output of --libs, etc. may include a -L for the
154# system library, which we do *NOT* want to put in our libpcap.pc and
155# pcap-config files.
156#
157# So we just run pkg-config ourselves, so that we get its output
158# directly without any processing by CMake.
159#
160macro(pkg_get_link_info _prefix _package)
161  if (PKG_CONFIG_EXECUTABLE)
162    #
163    # Get the --libs information.
164    #
165    # We force PKG_CONFIG_ALLOW_SYSTEM_LIBS to be undefined, as
166    # at least some versions of CMake appear to define it in
167    # pkg_check_modules() before running pkg-config and *not* undefine
168    # it after running it.
169    #
170    unset(ENV{PKG_CONFIG_ALLOW_SYSTEM_LIBS})
171    set(_pkg_config_result "")
172    execute_process(
173      COMMAND ${PKG_CONFIG_EXECUTABLE} "--libs" ${_package}
174      OUTPUT_VARIABLE _pkg_config_result
175      RESULT_VARIABLE _pkg_config_failed
176      OUTPUT_STRIP_TRAILING_WHITESPACE)
177
178    if (_pkg_config_failed)
179      #
180      # pkg-config failed; assume that means that there is no such
181      # package for it to find.  XXX - what do we do here?
182      #
183      set(${_prefix}_FOUND_WITH_PKG_CONFIG FALSE)
184    else()
185      #
186      # pkg-config succeeded; replace CR and LF with spaces.
187      #
188      string(REGEX REPLACE "[\r\n]" " " ${_prefix}_LIBS "${_pkg_config_result}")
189
190      #
191      # Now get the --libs --static information.
192      #
193      set(_pkg_config_result "")
194      execute_process(
195        COMMAND ${PKG_CONFIG_EXECUTABLE} "--libs" "--static" ${_package}
196        OUTPUT_VARIABLE _pkg_config_result
197        RESULT_VARIABLE _pkg_config_failed
198        OUTPUT_STRIP_TRAILING_WHITESPACE)
199
200      if (_pkg_config_failed)
201        #
202        # pkg-config failed; assume that means that there is no such
203        # package for it to find.  XXX - what do we do here?
204        #
205        set(${_prefix}_FOUND_WITH_PKG_CONFIG FALSE)
206      else()
207        #
208        # pkg-config succeeded; replace CR and LF with spaces.
209        #
210        string(REGEX REPLACE "[\r\n]" " " ${_prefix}_LIBS_STATIC "${_pkg_config_result}")
211
212        #
213        # List this package in its PACKAGE_NAME variable.
214        #
215        set(${_prefix}_PACKAGE_NAME "${_package}")
216
217        #
218        # It worked.
219        #
220        set(${_prefix}_FOUND_WITH_PKG_CONFIG TRUE)
221      endif()
222    endif()
223  endif()
224endmacro()
225
226macro(get_link_info_from_library_path  _library_prefix _library_name)
227  if(NOT ${_library_prefix}_LIBRARY STREQUAL "${_library_prefix}_LIBRARY-NOTFOUND")
228    get_filename_component(_lib_directory "${${_library_prefix}_LIBRARY}}" DIRECTORY)
229
230    #
231    # The closest thing to a list of "system library directories" in
232    # which the linker will, by default, search for libraries appears to
233    # be CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES, so that's what we use
234    # when we're trying to construct a -L argument, for insertion into
235    # pcap-config and libpcap.pc, for a library upon which we depend.
236    #
237    # In some versions of CMake it appears to have duplicate entries,
238    # but that shouldn't affect a search for a directory in that list.
239    #
240    list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${_lib_directory}" _lib_index)
241    if(_lib_index EQUAL -1)
242      #
243      # No, so add a -L flag to get the linker to search in that
244      # directory.
245      #
246      set(${_library_prefix}_LIBS "-L${_lib_directory}")
247      set(${_library_prefix}_LIBS_STATIC "-L${_lib_directory}")
248      set(${_libraryprefix}_LIBS_PRIVATE "-L${_lib_directory}")
249    endif()
250    set(${_library_prefix}_LIBS "${${_library_prefix}_LIBS} -l${_library_name}")
251    set(${_library_prefix}_LIBS_STATIC "${${_library_prefix}_LIBS} -l${_library_name}")
252    set(${_library_prefix}_LIBS_PRIVATE "${${_library_prefix}_LIBS} -l${_library_name}")
253  endif()
254endmacro()
255
256#
257# Show the bit width for which we're compiling.
258# This can help debug problems if you're dealing with a compiler that
259# defaults to generating 32-bit code even when running on a 64-bit
260# platform, and where that platform may provide only 64-bit versions of
261# libraries that we might use (looking at *you*, Oracle Studio!).
262#
263if(CMAKE_SIZEOF_VOID_P EQUAL 4)
264  message(STATUS "Building 32-bit")
265elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
266  message(STATUS "Building 64-bit")
267endif()
268
269#
270# Solaris pkg-config is annoying.  For at least one package (D-Bus, I'm
271# looking at *you*!), there are separate include files for 32-bit and
272# 64-bit builds (I guess using "unsigned long long" as a 64-bit integer
273# type on a 64-bit build is like crossing the beams or something), and
274# there are two separate .pc files, so if we're doing a 32-bit build we
275# should make sure we look in /usr/lib/pkgconfig for .pc files and if
276# we're doing a 64-bit build we should make sure we look in
277# /usr/lib/amd64/pkgconfig for .pc files.
278#
279if(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION MATCHES "5[.][0-9.]*")
280    #
281    # Note: string(REPLACE) does not appear to support using ENV{...}
282    # as an argument, so we set a variable and then use set() to set
283    # the environment variable.
284    #
285    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
286        #
287        # 64-bit build.  If /usr/lib/pkgconfig appears in the path,
288        # prepend /usr/lib/amd64/pkgconfig to it; otherwise,
289        # put /usr/lib/amd64 at the end.
290        #
291        if((NOT DEFINED ENV{PKG_CONFIG_PATH}) OR "$ENV{PKG_CONFIG_PATH}" EQUAL "")
292            #
293            # Not set, or empty.  Set it to /usr/lib/amd64/pkgconfig.
294            #
295            set(fixed_path "/usr/lib/amd64/pkgconfig")
296        elseif("$ENV{PKG_CONFIG_PATH}" MATCHES "/usr/lib/pkgconfig")
297            #
298            # It contains /usr/lib/pkgconfig.  Prepend
299            # /usr/lib/amd64/pkgconfig to /usr/lib/pkgconfig.
300            #
301            string(REPLACE "/usr/lib/pkgconfig"
302                "/usr/lib/amd64/pkgconfig:/usr/lib/pkgconfig"
303                fixed_path "$ENV{PKG_CONFIG_PATH}")
304        else()
305            #
306            # Not empty, but doesn't contain /usr/lib/pkgconfig.
307            # Append /usr/lib/amd64/pkgconfig to it.
308            #
309            set(fixed_path "$ENV{PKG_CONFIG_PATH}:/usr/lib/amd64/pkgconfig")
310        endif()
311        set(ENV{PKG_CONFIG_PATH} "${fixed_path}")
312    elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
313        #
314        # 32-bit build.  If /usr/amd64/lib/pkgconfig appears in the path,
315        # prepend /usr/lib/pkgconfig to it.
316        #
317        if("$ENV{PKG_CONFIG_PATH}" MATCHES "/usr/lib/amd64/pkgconfig")
318            #
319            # It contains /usr/lib/amd64/pkgconfig.  Prepend
320            # /usr/lib/pkgconfig to /usr/lib/amd64/pkgconfig.
321            #
322            string(REPLACE "/usr/lib/amd64/pkgconfig"
323                "/usr/lib/pkgconfig:/usr/lib/amd64/pkgconfig"
324                fixed_path "$ENV{PKG_CONFIG_PATH}")
325            set(ENV{PKG_CONFIG_PATH} "${fixed_path}")
326        endif()
327    endif()
328endif()
329
330include(CheckCCompilerFlag)
331
332#
333# For checking if a compiler flag works and adding it if it does.
334#
335macro(check_and_add_compiler_option _option)
336    message(STATUS "Checking C compiler flag ${_option}")
337    string(REPLACE "=" "-" _temp_option_variable ${_option})
338    string(REGEX REPLACE "^-" "" _option_variable ${_temp_option_variable})
339    check_c_compiler_flag("${_option}" ${_option_variable})
340    if(${${_option_variable}})
341        set(C_ADDITIONAL_FLAGS "${C_ADDITIONAL_FLAGS} ${_option}")
342    endif()
343endmacro()
344
345#
346# If we're building with Visual Studio, we require Visual Studio 2015,
347# in order to get sufficient C99 compatibility.  Check for that.
348#
349# If not, try the appropriate flag for the compiler to enable C99
350# features.
351#
352set(C_ADDITIONAL_FLAGS "")
353if(MSVC)
354    if(MSVC_VERSION LESS 1900)
355        message(FATAL_ERROR "Visual Studio 2015 or later is required")
356    endif()
357
358    #
359    # Treat source files as being in UTF-8 with MSVC if it's not using
360    # the Clang front end.
361    # We assume that UTF-8 source is OK with other compilers and with
362    # MSVC if it's using the Clang front end.
363    #
364    if(NOT ${CMAKE_C_COMPILER} MATCHES "clang*")
365        set(C_ADDITIONAL_FLAGS "${C_ADDITIONAL_FLAGS} /utf-8")
366    endif(NOT ${CMAKE_C_COMPILER} MATCHES "clang*")
367else(MSVC)
368    #
369    # For checking if a compiler flag works, failing if it doesn't,
370    # and adding it otherwise.
371    #
372    macro(require_and_add_compiler_option _option)
373        message(STATUS "Checking C compiler flag ${_option}")
374        string(REPLACE "=" "-" _temp_option_variable ${_option})
375        string(REGEX REPLACE "^-" "" _option_variable ${_temp_option_variable})
376        check_c_compiler_flag("${_option}" ${_option_variable})
377        if(${${_option_variable}})
378            set(C_ADDITIONAL_FLAGS "${C_ADDITIONAL_FLAGS} ${_option}")
379        else()
380            message(FATAL_ERROR "C99 support is required, but the compiler doesn't support a compiler flag to enable it")
381        endif()
382    endmacro()
383
384    #
385    # Try to enable as many C99 features as we can.
386    # At minimum, we want C++/C99-style // comments.
387    #
388    # Newer versions of compilers might default to supporting C99, but
389    # older versions may require a special flag.
390    #
391    # Prior to CMake 3.1, setting CMAKE_C_STANDARD will not have any effect,
392    # so, unless and until we require CMake 3.1 or later, we have to do it
393    # ourselves on pre-3.1 CMake, so we just do it ourselves on all versions
394    # of CMake.
395    #
396    # Note: with CMake 3.1 through 3.5, the only compilers for which CMake
397    # handles CMAKE_C_STANDARD are GCC and Clang.  3.6 adds support only
398    # for Intel C; 3.9 adds support for PGI C, Sun C, and IBM XL C, and
399    # 3.10 adds support for Cray C and IAR C, but no version of CMake has
400    # support for HP C.  Therefore, even if we use CMAKE_C_STANDARD with
401    # compilers for which CMake supports it, we may still have to do it
402    # ourselves on other compilers.
403    #
404    # See the CMake documentation for the CMAKE_<LANG>_COMPILER_ID variables
405    # for a list of compiler IDs.
406    #
407    # XXX - this just tests whether the option works, fails if it doesn't,
408    # and adds it if it does.  We don't test whether it's necessary in order
409    # to get the C99 features that we use, or whether, if it's used, it
410    # enables all the features that we require.
411    #
412    if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR
413       CMAKE_C_COMPILER_ID MATCHES "Clang")
414        require_and_add_compiler_option("-std=gnu99")
415    elseif(CMAKE_C_COMPILER_ID MATCHES "XL")
416        #
417        # We want support for extensions picked up for GNU C compatibility,
418        # so we use -qlanglvl=extc99.
419        #
420        require_and_add_compiler_option("-qlanglvl=extc99")
421    elseif(CMAKE_C_COMPILER_ID MATCHES "HP")
422        require_and_add_compiler_option("-AC99")
423    elseif(CMAKE_C_COMPILER_ID MATCHES "Sun")
424        require_and_add_compiler_option("-xc99")
425    elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
426        require_and_add_compiler_option("-c99")
427    endif()
428endif(MSVC)
429
430#
431# If we're building with MinGW, we need to specify _WIN32_WINNT as
432# 0x0600 ("NT 6.0", a/k/a Vista/Windows Server 2008) or higher
433# in order to get the full IPv6 API, including inet_ntop(), and we
434# need to specify it as 0x0601 ("NT 6.1", a/k/a Windows 7) or higher
435# in order to get NdisMediumIP.
436#
437# NOTE: pcap does *NOT* work with msvcrt.dll; it must link with
438# a newer version of the C library, i.e. Visual Studio 2015 or
439# later, as it depends on C99 features introduced in VS 2015.
440#
441if(MINGW)
442    add_definitions(-D_WIN32_WINNT=0x0601)
443endif(MINGW)
444
445#
446# Build all runtimes in the top-level binary directory; that way,
447# on Windows, the executables will be in the same directory as
448# the DLLs, so the system will find pcap.dll when any of the
449# executables are run.
450#
451set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/run)
452
453###################################################################
454#   Parameters
455###################################################################
456
457if(WIN32)
458    #
459    # On Windows, allow the library name to be overridden, for the
460    # benefit of projects that combine libpcap with their own
461    # kernel-mode code to support capturing.
462    #
463    set(LIBRARY_NAME pcap CACHE STRING "Library name")
464else()
465    #
466    # On UN*X, it's always been libpcap.
467    #
468    set(LIBRARY_NAME pcap)
469endif()
470
471option(INET6 "Enable IPv6" ON)
472if(WIN32)
473    option(USE_STATIC_RT "Use static Runtime" ON)
474endif(WIN32)
475option(BUILD_SHARED_LIBS "Build shared libraries" ON)
476set(dpdk_ROOT "" CACHE PATH "Path to directory with include and lib subdirectories for DPDK")
477if(WIN32)
478    set(Packet_ROOT "" CACHE PATH "Path to directory with include and lib subdirectories for packet.dll")
479    set(AirPcap_ROOT "" CACHE PATH "Path to directory with include and lib subdirectories for airpcap.dll")
480endif(WIN32)
481
482option(ENABLE_PROFILING "Enable code profiling" OFF)
483
484# To pacify those who hate the protochain instruction
485option(NO_PROTOCHAIN "Disable protochain instruction" OFF)
486
487#
488# Start out with the capture mechanism type unspecified; the user
489# can explicitly specify it and, if they don't, we'll pick an
490# appropriate one.
491#
492set(PCAP_TYPE "" CACHE STRING "Packet capture type")
493
494#
495# Default to having remote capture support on Windows and, for now, to
496# not having it on UN*X.
497#
498if(WIN32)
499    option(ENABLE_REMOTE "Enable remote capture" ON)
500else()
501    option(ENABLE_REMOTE "Enable remote capture" OFF)
502endif(WIN32)
503
504if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
505    option(BUILD_WITH_LIBNL "Build with libnl" ON)
506endif()
507
508#
509# Additional capture modules.
510#
511if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
512    option(DISABLE_LINUX_USBMON "Disable Linux usbmon USB sniffing support" OFF)
513endif()
514option(DISABLE_BLUETOOTH "Disable Bluetooth sniffing support" OFF)
515option(DISABLE_NETMAP "Disable netmap support" OFF)
516
517#
518# Require that DPDK support be explicitly enabled, as the code is
519# immensely hard to keep compiling for every random API change
520# the DPDK folks make.
521#
522set(DISABLE_DPDK ON)
523
524#
525# We don't support D-Bus sniffing on macOS; see
526#
527# https://bugs.freedesktop.org/show_bug.cgi?id=74029
528#
529if(APPLE)
530    option(DISABLE_DBUS "Disable D-Bus sniffing support" ON)
531else(APPLE)
532    option(DISABLE_DBUS "Disable D-Bus sniffing support" OFF)
533endif(APPLE)
534option(DISABLE_RDMA "Disable RDMA sniffing support" OFF)
535
536option(DISABLE_DAG "Disable Endace DAG card support" OFF)
537
538option(DISABLE_SEPTEL "Disable Septel card support" OFF)
539set(SEPTEL_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../septel" CACHE PATH "Path to directory with include and lib subdirectories for Septel API")
540
541option(DISABLE_SNF "Disable Myricom SNF support" OFF)
542
543option(DISABLE_TC "Disable Riverbed TurboCap support" OFF)
544
545#
546# Debugging options.
547#
548option(BDEBUG "Build optimizer debugging code" OFF)
549option(YYDEBUG "Build parser debugging code" OFF)
550
551###################################################################
552#   Versioning
553###################################################################
554
555# Get, parse, format and set pcap's version string from [pcap_root]/VERSION
556# for later use.
557
558# Get MAJOR, MINOR, PATCH & SUFFIX
559file(STRINGS ${pcap_SOURCE_DIR}/VERSION
560    PACKAGE_VERSION
561    LIMIT_COUNT 1 # Read only the first line
562)
563
564# Get "just" MAJOR
565string(REGEX MATCH "^([0-9]+)" PACKAGE_VERSION_MAJOR "${PACKAGE_VERSION}")
566
567# Get MAJOR, MINOR & PATCH
568string(REGEX MATCH "^([0-9]+.)?([0-9]+.)?([0-9]+)" PACKAGE_VERSION_NOSUFFIX "${PACKAGE_VERSION}")
569
570if(WIN32)
571    # Convert PCAP_VERSION_NOSUFFIX to Windows preferred version format
572    string(REPLACE "." "," PACKAGE_VERSION_PREDLL ${PACKAGE_VERSION_NOSUFFIX})
573
574    # Append NANO (used for Windows internal versioning) to PCAP_VERSION_PREDLL
575    # 0 means unused.
576    set(PACKAGE_VERSION_DLL ${PACKAGE_VERSION_PREDLL},0)
577endif(WIN32)
578
579set(PACKAGE_NAME "${LIBRARY_NAME}")
580set(PACKAGE_STRING "${LIBRARY_NAME} ${PACKAGE_VERSION}")
581
582######################################
583# Project settings
584######################################
585
586include_directories(
587    ${CMAKE_CURRENT_BINARY_DIR}
588    ${pcap_SOURCE_DIR}
589)
590
591include(CheckFunctionExists)
592include(CMakePushCheckState)
593include(CheckSymbolExists)
594include(CheckIncludeFile)
595
596if(WIN32)
597
598    if(IS_DIRECTORY ${CMAKE_HOME_DIRECTORY}/../../Common)
599        include_directories(${CMAKE_HOME_DIRECTORY}/../../Common)
600    endif(IS_DIRECTORY ${CMAKE_HOME_DIRECTORY}/../../Common)
601
602    find_package(Packet)
603    if(Packet_FOUND)
604        set(HAVE_PACKET32 TRUE)
605        include_directories(${Packet_INCLUDE_DIRS})
606        #
607        # Check whether we have the NPcap PacketIsLoopbackAdapter()
608        # function.
609        #
610        cmake_push_check_state()
611        set(CMAKE_REQUIRED_LIBRARIES ${Packet_LIBRARIES})
612        set(CMAKE_REQUIRED_INCLUDES ${Packet_INCLUDE_DIRS})
613        check_function_exists(PacketIsLoopbackAdapter HAVE_PACKET_IS_LOOPBACK_ADAPTER)
614        check_function_exists(PacketGetTimestampModes HAVE_PACKET_GET_TIMESTAMP_MODES)
615        check_function_exists(PacketGetInfo HAVE_PACKET_GET_INFO)
616        check_include_file(npcap-bpf.h HAVE_NPCAP_BPF_H)
617        cmake_pop_check_state()
618    endif(Packet_FOUND)
619
620    message(STATUS "checking for Npcap's version.h")
621    check_symbol_exists(WINPCAP_PRODUCT_NAME "${CMAKE_SOURCE_DIR}/../../version.h" HAVE_VERSION_H)
622    if(HAVE_VERSION_H)
623        message(STATUS "HAVE version.h")
624    else(HAVE_VERSION_H)
625        message(STATUS "MISSING version.h")
626    endif(HAVE_VERSION_H)
627
628endif(WIN32)
629
630if(MSVC)
631    add_definitions(-D__STDC__)
632    add_definitions(-D_CRT_SECURE_NO_WARNINGS)
633endif(MSVC)
634
635if(USE_STATIC_RT)
636    message(STATUS "Use STATIC runtime")
637        if(MSVC)
638            foreach(RT_FLAG
639                CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
640                CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
641                string(REGEX REPLACE "/MD" "/MT" ${RT_FLAG} "${${RT_FLAG}}")
642            endforeach(RT_FLAG)
643        elseif(MINGW)
644            set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libgcc")
645        endif()
646else (USE_STATIC_RT)
647    message(STATUS "Use DYNAMIC runtime")
648endif(USE_STATIC_RT)
649
650###################################################################
651#   Detect available platform features
652###################################################################
653
654include(CheckIncludeFiles)
655include(CheckStructHasMember)
656include(CheckTypeSize)
657
658#
659# Tests are a bit expensive with Visual Studio on Windows, so, on
660# Windows, we skip tests for UN*X-only headers and functions.
661#
662
663#
664# Header files.
665#
666check_include_file(inttypes.h HAVE_INTTYPES_H)
667check_include_file(stdint.h HAVE_STDINT_H)
668check_include_file(unistd.h HAVE_UNISTD_H)
669if(NOT HAVE_UNISTD_H)
670    add_definitions(-DYY_NO_UNISTD_H)
671endif(NOT HAVE_UNISTD_H)
672check_include_file(bitypes.h HAVE_SYS_BITYPES_H)
673if(NOT WIN32)
674    check_include_file(sys/ioccom.h HAVE_SYS_IOCCOM_H)
675    check_include_file(sys/sockio.h HAVE_SYS_SOCKIO_H)
676    check_include_file(sys/select.h HAVE_SYS_SELECT_H)
677
678    check_include_file(netpacket/packet.h HAVE_NETPACKET_PACKET_H)
679    check_include_file(netinet/if_ether.h HAVE_NETINET_IF_ETHER_H)
680endif(NOT WIN32)
681
682#
683# Functions.
684#
685# First, check for the __atomic_load_n() and __atomic_store_n()
686# builtins.
687#
688# We can't use check_function_exists(), as it tries to declare
689# the function, and attempting to declare a compiler builtin
690# can produce an error.
691#
692# We don't use check_symbol_exists(), as it expects a header
693# file to be specified to declare the function, but there isn't
694# such a header file.
695#
696# So we use check_c_source_compiles().
697#
698check_c_source_compiles(
699"int
700main(void)
701{
702	int i = 17;
703	return __atomic_load_n(&i, __ATOMIC_RELAXED);
704}
705"
706            HAVE___ATOMIC_LOAD_N)
707check_c_source_compiles(
708"int
709main(void)
710{
711	int i;
712	__atomic_store_n(&i, 17, __ATOMIC_RELAXED);
713	return 0;
714}
715"
716            HAVE___ATOMIC_STORE_N)
717
718#
719# Now check for various system functions.
720#
721check_function_exists(strerror_r HAVE_STRERROR_R)
722if(HAVE_STRERROR_R)
723    #
724    # We have strerror_r; if we define _GNU_SOURCE, is it a
725    # POSIX-compliant strerror_r() or a GNU strerror_r()?
726    #
727    check_c_source_compiles(
728"#define _GNU_SOURCE
729#include <string.h>
730
731/* Define it GNU-style; that will cause an error if it's not GNU-style */
732extern char *strerror_r(int, char *, size_t);
733
734int
735main(void)
736{
737	return 0;
738}
739"
740            HAVE_GNU_STRERROR_R)
741    if(NOT HAVE_GNU_STRERROR_R)
742        set(HAVE_POSIX_STRERROR_R YES)
743    endif(NOT HAVE_GNU_STRERROR_R)
744else(HAVE_STRERROR_R)
745    #
746    # We don't have strerror_r; do we have _wcserror_s?
747    #
748    check_function_exists(_wcserror_s HAVE__WCSERROR_S)
749endif(HAVE_STRERROR_R)
750
751#
752# Make sure we have vsnprintf() and snprintf(); we require them.
753# We use check_symbol_exists(), as they aren't necessarily external
754# functions - in Visual Studio, for example, they're inline functions
755# calling a common external function.
756#
757check_symbol_exists(vsnprintf "stdio.h" HAVE_VSNPRINTF)
758if(NOT HAVE_VSNPRINTF)
759    message(FATAL_ERROR "vsnprintf() is required but wasn't found")
760endif(NOT HAVE_VSNPRINTF)
761check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF)
762if(NOT HAVE_SNPRINTF)
763    message(FATAL_ERROR "snprintf() is required but wasn't found")
764endif()
765
766check_function_exists(strlcpy HAVE_STRLCPY)
767check_function_exists(strlcat HAVE_STRLCAT)
768check_function_exists(asprintf HAVE_ASPRINTF)
769check_function_exists(vasprintf HAVE_VASPRINTF)
770check_function_exists(strtok_r HAVE_STRTOK_R)
771if(NOT WIN32)
772    check_function_exists(vsyslog HAVE_VSYSLOG)
773endif()
774
775#
776# Look for various networking-related libraries that we may need.
777#
778# We need getaddrinfo() to translate host names in filters to IP
779# addresses. We use getaddrinfo() because we want a portable
780# thread-safe way of getting information for a host name or port;
781# there exist _r versions of gethostbyname() and getservbyname() on
782# some platforms, but not on all platforms.
783#
784# We may also need socket() and other socket functions to support:
785#
786#   Local packet capture with capture mechanisms that use sockets.
787#
788#   Local capture device enumeration if a socket call is needed to
789#   enumerate devices or get device attributes.
790#
791#   Packet capture from services that put captured packets on the
792#   network, such as rpcap servers.
793#
794# We may also need getnameinfo() for packet capture from services
795# that put packets on the network.
796#
797set(PCAP_LINK_LIBRARIES "")
798set(LIBS "")
799set(LIBS_STATIC "")
800set(REQUIRES_PRIVATE "")
801set(LIBS_PRIVATE "")
802include(CheckLibraryExists)
803if(WIN32)
804    #
805    # Windows.
806    #
807    # We need winsock2.h and ws2tcpip.h.
808    #
809    # On Windows, getaddrinfo() is in the ws2_32 library.
810    #
811    cmake_push_check_state()
812    set(CMAKE_REQUIRED_LIBRARIES ws2_32)
813    check_symbol_exists(getaddrinfo "winsock2.h;ws2tcpip.h" LIBWS2_32_HAS_GETADDRINFO)
814    cmake_pop_check_state()
815    if(LIBWS2_32_HAS_GETADDRINFO)
816        set(PCAP_LINK_LIBRARIES ws2_32 ${PCAP_LINK_LIBRARIES})
817    else(LIBWS2_32_HAS_GETADDRINFO)
818        message(FATAL_ERROR "getaddrinfo is required, but wasn't found")
819    endif(LIBWS2_32_HAS_GETADDRINFO)
820else(WIN32)
821    #
822    # UN*X.
823    #
824    # Most UN*Xes have getaddrinfo(), and the other routines we may
825    # need, in the default searched libraries (e.g., libc).
826    # Check there first.
827    #
828    # NOTE: if you hand check_library_exists as its last argument a
829    # variable that's been set, it skips the test, so we need different
830    # variables for different libraries.
831    #
832    check_function_exists(getaddrinfo STDLIBS_HAVE_GETADDRINFO)
833    if(NOT STDLIBS_HAVE_GETADDRINFO)
834	#
835	# Not found in the standard system libraries.
836	#
837	# In some versions of Solaris, we need to link with libsocket
838	# and libnsl, so check in libsocket and also link with liblnsl
839	# when doing this test.
840	#
841	# Linking with libsocket and libnsl will find all the routines
842	# we need.
843	#
844        cmake_push_check_state()
845        set(CMAKE_REQUIRED_LIBRARIES nsl)
846        check_library_exists(socket getaddrinfo "" LIBSOCKET_HAS_GETADDRINFO)
847        cmake_pop_check_state()
848        if(LIBSOCKET_HAS_GETADDRINFO)
849            #
850            # OK, we found it in libsocket.
851            #
852            set(PCAP_LINK_LIBRARIES socket nsl ${PCAP_LINK_LIBRARIES})
853            set(LIBS "-lsocket -lnsl ${LIBS}")
854            set(LIBS_STATIC "-lsocket -lnsl ${LIBS_STATIC}")
855            set(LIBS_PRIVATE "-lsocket -lnsl ${LIBS_PRIVATE}")
856        else(LIBSOCKET_HAS_GETADDRINFO)
857	    #
858	    # Not found in libsocket; test for it in libnetwork, which
859	    # is where it is in Haiku.
860	    #
861	    # Linking with libnetwork will find all the routines we
862	    # need.
863	    #
864            check_library_exists(network getaddrinfo "" LIBNETWORK_HAS_GETADDRINFO)
865            if(LIBNETWORK_HAS_GETADDRINFO)
866                #
867		# OK, we found it in libnetwork.
868                #
869                set(PCAP_LINK_LIBRARIES network ${PCAP_LINK_LIBRARIES})
870                set(LIBS "-lnetwork ${LIBS}")
871                set(LIBS_STATIC "-lnetwork ${LIBS_STATIC}")
872                set(LIBS_PRIVATE "-lnetwork ${LIBS_PRIVATE}")
873            else(LIBNETWORK_HAS_GETADDRINFO)
874                #
875                # We didn't find it.
876                #
877                message(FATAL_ERROR "getaddrinfo is required, but wasn't found")
878            endif(LIBNETWORK_HAS_GETADDRINFO)
879        endif(LIBSOCKET_HAS_GETADDRINFO)
880
881	#
882	# We require a version of recvmsg() that conforms to the Single
883	# UNIX Specification, so that we can check whether a datagram
884	# received with recvmsg() was truncated when received due to the
885	# buffer being too small.
886	#
887	# On most systems, the version of recvmsg() in the libraries
888	# found above conforms to the SUS.
889	#
890	# On at least some versions of Solaris, it does not conform to
891	# the SUS, and we need the version in libxnet, which does
892	# conform.
893	#
894	# Check whether libxnet exists and has a version of recvmsg();
895	# if it does, link with libxnet before we link with libsocket,
896	# to get that version.
897	#
898	# This test also links with libsocket and libnsl.
899	#
900        cmake_push_check_state()
901        set(CMAKE_REQUIRED_LIBRARIES socket nsl)
902        check_library_exists(xnet recvmsg "" LIBXNET_HAS_RECVMSG)
903        cmake_pop_check_state()
904        if(LIBXNET_HAS_RECVMSG)
905            #
906	    # libxnet has recvmsg(); link with it as well.
907            #
908            set(PCAP_LINK_LIBRARIES xnet ${PCAP_LINK_LIBRARIES})
909            set(LIBSC "-lxnet ${LIBS_LIBS}")
910            set(LIBS_STATIC "-lxnet ${LIBS_STATIC}")
911            set(LIBS_PRIVATE "-lxnet ${LIBS_PRIVATE}")
912        endif(LIBXNET_HAS_RECVMSG)
913    endif(NOT STDLIBS_HAVE_GETADDRINFO)
914
915    #
916    # DLPI needs putmsg under HP-UX, so test for -lstr while we're at it.
917    #
918    check_function_exists(putmsg STDLIBS_HAVE_PUTMSG)
919    if(NOT STDLIBS_HAVE_PUTMSG)
920        check_library_exists(str putmsg "" LIBSTR_HAS_PUTMSG)
921        if(LIBSTR_HAS_PUTMSG)
922            set(PCAP_LINK_LIBRARIES str ${PCAP_LINK_LIBRARIES})
923            set(LIBS "-lstr ${LIBS}")
924            set(LIBS_STATIC "-lstr ${LIBS_STATIC}")
925            set(LIBS_PRIVATE "-lstr ${LIBS_PRIVATE}")
926        endif(LIBSTR_HAS_PUTMSG)
927    endif(NOT STDLIBS_HAVE_PUTMSG)
928
929    # Haiku has getpass in libbsd
930    check_function_exists(getpass STDLIBS_HAVE_GETPASS)
931    if(NOT STDLIBS_HAVE_GETPASS)
932        check_library_exists(bsd getpass "" LIBBSD_HAS_GETPASS)
933        if(LIBBSD_HAS_GETPASS)
934            set(PCAP_LINK_LIBRARIES bsd ${PCAP_LINK_LIBRARIES})
935        endif(LIBBSD_HAS_GETPASS)
936    endif(NOT STDLIBS_HAVE_GETPASS)
937endif(WIN32)
938
939#
940# Check for reentrant versions of getnetbyname_r(), as provided by
941# Linux (glibc), Solaris/IRIX, and AIX (with three different APIs!).
942# If we don't find one, we just use getnetbyname(), which uses
943# thread-specific data on many platforms, but doesn't use it on
944# NetBSD or OpenBSD, and may not use it on older versions of other
945# platforms.
946#
947# Only do the check if we have a declaration of getnetbyname_r();
948# without it, we can't check which API it has.  (We assume that
949# if there's a declaration, it has a prototype, so that the API
950# can be checked.)
951#
952cmake_push_check_state()
953set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LINK_LIBRARIES})
954check_symbol_exists(getnetbyname_r netdb.h NETDB_H_DECLARES_GETNETBYNAME_R)
955if(NETDB_H_DECLARES_GETNETBYNAME_R)
956    check_c_source_compiles(
957"#include <netdb.h>
958
959int
960main(void)
961{
962    struct netent netent_buf;
963    char buf[1024];
964    struct netent *resultp;
965    int h_errnoval;
966
967    return getnetbyname_r((const char *)0, &netent_buf, buf, sizeof buf, &resultp, &h_errnoval);
968}
969"
970        HAVE_LINUX_GETNETBYNAME_R)
971    if(NOT HAVE_LINUX_GETNETBYNAME_R)
972        check_c_source_compiles(
973"#include <netdb.h>
974
975int
976main(void)
977{
978    struct netent netent_buf;
979    char buf[1024];
980
981    return getnetbyname_r((const char *)0, &netent_buf, buf, (int)sizeof buf) != NULL;
982}
983"
984            HAVE_SOLARIS_IRIX_GETNETBYNAME_R)
985        if(NOT HAVE_SOLARIS_IRIX_GETNETBYNAME_R)
986            check_c_source_compiles(
987"#include <netdb.h>
988
989int
990main(void)
991{
992    struct netent netent_buf;
993    struct netent_data net_data;
994
995    return getnetbyname_r((const char *)0, &netent_buf, &net_data);
996}
997"
998                HAVE_AIX_GETNETBYNAME_R)
999        endif(NOT HAVE_SOLARIS_IRIX_GETNETBYNAME_R)
1000    endif(NOT HAVE_LINUX_GETNETBYNAME_R)
1001endif(NETDB_H_DECLARES_GETNETBYNAME_R)
1002cmake_pop_check_state()
1003
1004#
1005# Check for reentrant versions of getprotobyname_r(), as provided by
1006# Linux (glibc), Solaris/IRIX, and AIX (with three different APIs!).
1007# If we don't find one, we just use getprotobyname(), which uses
1008# thread-specific data on many platforms, but doesn't use it on
1009# NetBSD or OpenBSD, and may not use it on older versions of other
1010# platforms.
1011#
1012# Only do the check if we have a declaration of getprotobyname_r();
1013# without it, we can't check which API it has.  (We assume that
1014# if there's a declaration, it has a prototype, so that the API
1015# can be checked.)
1016#
1017cmake_push_check_state()
1018set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LINK_LIBRARIES})
1019check_symbol_exists(getprotobyname_r netdb.h NETDB_H_DECLARES_GETPROTOBYNAME_R)
1020if(NETDB_H_DECLARES_GETPROTOBYNAME_R)
1021    check_c_source_compiles(
1022"#include <netdb.h>
1023
1024int
1025main(void)
1026{
1027    struct protoent protoent_buf;
1028    char buf[1024];
1029    struct protoent *resultp;
1030
1031    return getprotobyname_r((const char *)0, &protoent_buf, buf, sizeof buf, &resultp);
1032}
1033"
1034        HAVE_LINUX_GETPROTOBYNAME_R)
1035    if(NOT HAVE_LINUX_GETPROTOBYNAME_R)
1036        check_c_source_compiles(
1037"#include <netdb.h>
1038
1039int
1040main(void)
1041{
1042    struct protoent protoent_buf;
1043    char buf[1024];
1044
1045    return getprotobyname_r((const char *)0, &protoent_buf, buf, (int)sizeof buf) != NULL;
1046}
1047"
1048            HAVE_SOLARIS_IRIX_GETPROTOBYNAME_R)
1049        if(NOT HAVE_SOLARIS_IRIX_GETPROTOBYNAME_R)
1050            check_c_source_compiles(
1051"#include <netdb.h>
1052
1053int
1054main(void)
1055{
1056    struct protoent protoent_buf;
1057    struct protoent_data proto_data;
1058
1059    return getprotobyname_r((const char *)0, &protoent_buf, &proto_data);
1060}
1061"
1062                HAVE_AIX_GETPROTOBYNAME_R)
1063        endif(NOT HAVE_SOLARIS_IRIX_GETPROTOBYNAME_R)
1064    endif(NOT HAVE_LINUX_GETPROTOBYNAME_R)
1065endif(NETDB_H_DECLARES_GETPROTOBYNAME_R)
1066cmake_pop_check_state()
1067
1068#
1069# Data types.
1070#
1071# XXX - there's no check_type() macro that's like check_type_size()
1072# except that it only checks for the existence of the structure type,
1073# so we use check_type_size() and ignore the size.
1074#
1075cmake_push_check_state()
1076if(WIN32)
1077    set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h)
1078else(WIN32)
1079    set(CMAKE_EXTRA_INCLUDE_FILES unistd.h sys/socket.h)
1080endif(WIN32)
1081check_type_size("struct sockaddr_storage" STRUCT_SOCKADDR_STORAGE)
1082check_type_size("socklen_t" SOCKLEN_T)
1083cmake_pop_check_state()
1084
1085#
1086# Structure fields.
1087#
1088if(WIN32)
1089    check_struct_has_member("struct sockaddr" sa_len winsock2.h HAVE_STRUCT_SOCKADDR_SA_LEN)
1090else(WIN32)
1091    check_struct_has_member("struct sockaddr" sa_len sys/socket.h HAVE_STRUCT_SOCKADDR_SA_LEN)
1092endif(WIN32)
1093
1094#
1095# Do we have ffs(), and is it declared in <strings.h>?
1096#
1097check_function_exists(ffs HAVE_FFS)
1098if(HAVE_FFS)
1099    #
1100    # OK, we have ffs().  Is it declared in <strings.h>?
1101    #
1102    # This test fails if we don't have <strings.h> or if we do
1103    # but it doesn't declare ffs().
1104    #
1105    check_symbol_exists(ffs strings.h STRINGS_H_DECLARES_FFS)
1106endif()
1107
1108#
1109# This requires the libraries that we require, as ether_hostton might be
1110# in one of those libraries.  That means we have to do this after
1111# we check for those libraries.
1112#
1113# You are in a twisty little maze of UN*Xes, all different.
1114# Some might not have ether_hostton().
1115# Some might have it and declare it in <net/ethernet.h>.
1116# Some might have it and declare it in <netinet/ether.h>
1117# Some might have it and declare it in <sys/ethernet.h>.
1118# Some might have it and declare it in <arpa/inet.h>.
1119# Some might have it and declare it in <netinet/if_ether.h>.
1120# Some might have it and not declare it in any header file.
1121#
1122# Before you is a C compiler.
1123#
1124cmake_push_check_state()
1125set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LINK_LIBRARIES})
1126check_function_exists(ether_hostton HAVE_ETHER_HOSTTON)
1127if(HAVE_ETHER_HOSTTON)
1128    #
1129    # OK, we have ether_hostton().  Is it declared in <net/ethernet.h>?
1130    #
1131    # This test fails if we don't have <net/ethernet.h> or if we do
1132    # but it doesn't declare ether_hostton().
1133    #
1134    check_symbol_exists(ether_hostton net/ethernet.h NET_ETHERNET_H_DECLARES_ETHER_HOSTTON)
1135    if(NET_ETHERNET_H_DECLARES_ETHER_HOSTTON)
1136        #
1137        # Yes - we have it declared.
1138        #
1139        set(HAVE_DECL_ETHER_HOSTTON TRUE)
1140    endif()
1141    #
1142    # Did that succeed?
1143    #
1144    if(NOT HAVE_DECL_ETHER_HOSTTON)
1145        #
1146        # No - how about <netinet/ether.h>, as on Linux?
1147        #
1148        # This test fails if we don't have <netinet/ether.h>
1149        # or if we do but it doesn't declare ether_hostton().
1150        #
1151        check_symbol_exists(ether_hostton netinet/ether.h NETINET_ETHER_H_DECLARES_ETHER_HOSTTON)
1152        if(NETINET_ETHER_H_DECLARES_ETHER_HOSTTON)
1153            #
1154            # Yes - we have it declared.
1155            #
1156            set(HAVE_DECL_ETHER_HOSTTON TRUE)
1157        endif()
1158    endif()
1159    #
1160    # Did that succeed?
1161    #
1162    if(NOT HAVE_DECL_ETHER_HOSTTON)
1163        #
1164        # No - how about <sys/ethernet.h>, as on Solaris 10 and later?
1165        #
1166        # This test fails if we don't have <sys/ethernet.h>
1167        # or if we do but it doesn't declare ether_hostton().
1168        #
1169        check_symbol_exists(ether_hostton sys/ethernet.h SYS_ETHERNET_H_DECLARES_ETHER_HOSTTON)
1170        if(SYS_ETHERNET_H_DECLARES_ETHER_HOSTTON)
1171            #
1172            # Yes - we have it declared.
1173            #
1174            set(HAVE_DECL_ETHER_HOSTTON TRUE)
1175        endif()
1176    endif()
1177    #
1178    # Did that succeed?
1179    #
1180    if(NOT HAVE_DECL_ETHER_HOSTTON)
1181        #
1182        # No, how about <arpa/inet.h>, as on AIX?
1183        #
1184        # This test fails if we don't have <arpa/inet.h>
1185        # or if we do but it doesn't declare ether_hostton().
1186        #
1187        check_symbol_exists(ether_hostton arpa/inet.h ARPA_INET_H_DECLARES_ETHER_HOSTTON)
1188        if(ARPA_INET_H_DECLARES_ETHER_HOSTTON)
1189            #
1190            # Yes - we have it declared.
1191            #
1192            set(HAVE_DECL_ETHER_HOSTTON TRUE)
1193        endif()
1194    endif()
1195    #
1196    # Did that succeed?
1197    #
1198    if(NOT HAVE_DECL_ETHER_HOSTTON)
1199        #
1200        # No, how about <netinet/if_ether.h>?
1201        # On some platforms, it requires <net/if.h> and
1202        # <netinet/in.h>, and we always include it with
1203        # both of them, so test it with both of them.
1204        #
1205        # This test fails if we don't have <netinet/if_ether.h>
1206        # and the headers we include before it, or if we do but
1207        # <netinet/if_ether.h> doesn't declare ether_hostton().
1208        #
1209        check_symbol_exists(ether_hostton "sys/types.h;sys/socket.h;net/if.h;netinet/in.h;netinet/if_ether.h" NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON)
1210        if(NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON)
1211            #
1212            # Yes - we have it declared.
1213            #
1214            set(HAVE_DECL_ETHER_HOSTTON TRUE)
1215        endif()
1216    endif()
1217    #
1218    # After all that, is ether_hostton() declared?
1219    #
1220    if(NOT HAVE_DECL_ETHER_HOSTTON)
1221        #
1222        # No, we'll have to declare it ourselves.
1223        # Do we have "struct ether_addr" if we include <netinet/if_ether.h>?
1224        #
1225        # XXX - there's no check_type() macro that's like check_type_size()
1226        # except that it only checks for the existence of the structure type,
1227        # so we use check_type_size() and ignore the size.
1228        #
1229        cmake_push_check_state()
1230        set(CMAKE_EXTRA_INCLUDE_FILES sys/types.h sys/socket.h net/if.h netinet/in.h netinet/if_ether.h)
1231        check_type_size("struct ether_addr" STRUCT_ETHER_ADDR)
1232        cmake_pop_check_state()
1233    endif()
1234endif()
1235cmake_pop_check_state()
1236
1237#
1238# Large file support on UN*X, a/k/a LFS.
1239#
1240if(NOT WIN32)
1241  include(FindLFS)
1242  if(LFS_FOUND)
1243    #
1244    # Add the required #defines.
1245    #
1246    add_definitions(${LFS_DEFINITIONS})
1247  endif()
1248
1249  #
1250  # Check for fseeko as well.
1251  #
1252  include(FindFseeko)
1253  if(FSEEKO_FOUND)
1254    set(HAVE_FSEEKO ON)
1255
1256    #
1257    # Add the required #defines.
1258    #
1259    add_definitions(${FSEEKO_DEFINITIONS})
1260  endif()
1261endif()
1262
1263#
1264# Find and print the size of time_t.
1265#
1266cmake_push_check_state()
1267set(CMAKE_EXTRA_INCLUDE_FILES time.h)
1268check_type_size("time_t" SIZEOF_TIME_T)
1269if(SIZEOF_TIME_T EQUAL 4)
1270  message(STATUS "32-bit time_t")
1271elseif(SIZEOF_TIME_T EQUAL 8)
1272  message(STATUS "64-bit time_t")
1273endif()
1274cmake_pop_check_state()
1275
1276if(INET6)
1277    message(STATUS "Support IPv6")
1278endif(INET6)
1279
1280#
1281# Pthreads.
1282# We might need them, because some libraries we use might use them,
1283# but we don't necessarily need them.
1284# That's only on UN*X; on Windows, if they use threads, we assume
1285# they're native Windows threads.
1286#
1287if(NOT WIN32)
1288  set(CMAKE_THREAD_PREFER_PTHREAD ON)
1289  find_package(Threads)
1290  if(NOT CMAKE_USE_PTHREADS_INIT)
1291    #
1292    # If it's not pthreads, we won't use it; we use it for libraries
1293    # that require it.
1294    #
1295    set(CMAKE_THREAD_LIBS_INIT "")
1296  endif(NOT CMAKE_USE_PTHREADS_INIT)
1297endif(NOT WIN32)
1298
1299if(ENABLE_PROFILING)
1300    if(NOT MSVC)
1301        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pg")
1302    endif()
1303endif()
1304
1305#
1306# Based on
1307#
1308#    https://github.com/commonmark/cmark/blob/master/FindAsan.cmake
1309#
1310# The MIT License (MIT)
1311#
1312# Copyright (c) 2013 Matthew Arsenault
1313#
1314# Permission is hereby granted, free of charge, to any person obtaining a copy
1315# of this software and associated documentation files (the "Software"), to deal
1316# in the Software without restriction, including without limitation the rights
1317# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1318# copies of the Software, and to permit persons to whom the Software is
1319# furnished to do so, subject to the following conditions:
1320#
1321# The above copyright notice and this permission notice shall be included in
1322# all copies or substantial portions of the Software.
1323#
1324# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1325# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1326# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1327# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1328# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1329# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1330# THE SOFTWARE.
1331#
1332# Test if the each of the sanitizers in the ENABLE_SANITIZERS list are
1333# supported by the compiler, and, if so, adds the appropriate flags to
1334# CMAKE_C_FLAGS, and SANITIZER_FLAGS.  If not, it fails.
1335#
1336# Do this last, in the hope that it will prevent configuration on Linux
1337# from somehow deciding it doesn't need -lpthread when building rpcapd
1338# (it does require it, but somehow, in some mysterious fashion that no
1339# obvious CMake debugging flag reveals, it doesn't realize that if we
1340# turn sanitizer stuff on).
1341#
1342# Note: apparently, some projects have decided that ENABLE_SANITIZERS
1343# is a Boolean, with OFF meaning "no sanitizers" and ON meaning "all
1344# sanitizers".  Whoever decided that didn't put it up as a common
1345# CMake idiom, as far as I can tell; we only discovered this because
1346# JetBrains' CLion "helpfully" appears to pass -DENABLE_SANITIZERS=OFF
1347# to CMake by default, which causes CMake to fail on libpcap.  Thanks!
1348#
1349# We thus also allow a setting of OFF to mean "no sanitizers" and ON to
1350# mean "all supported sanitizers that we know about and that can all
1351# be used together".
1352#
1353macro(test_sanitizer _sanitizer _sanitizer_flag)
1354    message(STATUS "Checking sanitizer ${_sanitizer}")
1355    set(sanitizer_variable "sanitize_${_sanitizer}")
1356    # Set -Werror to catch "argument unused during compilation" warnings
1357    set(CMAKE_REQUIRED_FLAGS "-Werror -fsanitize=${_sanitizer}")
1358    check_c_compiler_flag("-fsanitize=${_sanitizer}" ${sanitizer_variable})
1359    if(${${sanitizer_variable}})
1360        set(${_sanitizer_flag} "-fsanitize=${_sanitizer}")
1361    else()
1362        #
1363        # Try the versions supported prior to Clang 3.2.
1364        # If the sanitizer is "address", try -fsanitize-address.
1365        # If it's "undefined", try -fcatch-undefined-behavior.
1366        # Otherwise, give up.
1367        #
1368        set(sanitizer_variable "OLD_${sanitizer_variable}")
1369        if ("${_sanitizer}" STREQUAL "address")
1370            set(CMAKE_REQUIRED_FLAGS "-Werror -fsanitize-address")
1371            check_c_compiler_flag("-fsanitize-address" ${sanitizer_variable})
1372            if(${${sanitizer_variable}})
1373                set(${_sanitizer_flag} "-fsanitize-address")
1374            endif()
1375        elseif("${_sanitizer}" STREQUAL "undefined")
1376            set(CMAKE_REQUIRED_FLAGS "-Werror -fcatch-undefined-behavior")
1377            check_c_compiler_flag("-fcatch-undefined-behavior" ${sanitizer_variable})
1378            if(${${sanitizer_variable}})
1379                set(${_sanitizer_flag} "-fcatch-undefined-behavior")
1380            endif()
1381        endif()
1382    endif()
1383    unset(CMAKE_REQUIRED_FLAGS)
1384endmacro(test_sanitizer)
1385
1386set(SANITIZER_FLAGS "")
1387if("${ENABLE_SANITIZERS}")
1388    #
1389    # This appears to indicate that ENABLE_SANITIZERS was set to a
1390    # string value that is "one of the true constants", meaning
1391    # "1, ON, YES, TRUE, Y, or a non-zero number".
1392    #
1393    # It does not appear to happen for other settings, including
1394    # setting it to a list of one or more sanitizers.
1395    #
1396    # This setting means "enable all sanitizers that the compiler
1397    # supports".
1398    #
1399    foreach(sanitizer "address" "undefined")
1400        unset(SANITIZER_FLAG)
1401        test_sanitizer(${sanitizer} SANITIZER_FLAG)
1402        if(SANITIZER_FLAG)
1403            message(STATUS "${sanitizer} sanitizer supported using ${SANITIZER_FLAG}")
1404            set(SANITIZER_FLAGS "${SANITIZER_FLAGS} ${SANITIZER_FLAG}")
1405        else()
1406            message(STATUS "${sanitizer} isn't a supported sanitizer")
1407        endif()
1408    endforeach()
1409    if("${SANITIZER_FLAGS}" STREQUAL "")
1410        message(FATAL_ERROR "No supported sanitizers found")
1411    endif()
1412else()
1413    #
1414    # This appears to indicate that ENABLE_SANITIZERS was either:
1415    #
1416    #   not set;
1417    #   set to a set to a string value that is not "one of the true
1418    #   constants", meaning "1, ON, YES, TRUE, Y, or a non-zero number".
1419    #
1420    # The latter includes setting it to "one of the false constants",
1421    # meaning the string "is 0, OFF, NO, FALSE, N, IGNORE, NOTFOUND,
1422    # the empty string, or ends in the suffix -NOTFOUND."
1423    #
1424    # It also includes setting it to a list of one or more sanitizers.
1425    #
1426    # We want to treat "not set" and "set to one of the false constants"
1427    # as meaning "do not enable any sanitizers".
1428    #
1429    # We want to treat "set to a list of one or more sanitizers" as
1430    # meaning "enable all the sanitizers in the list".
1431    #
1432    # This requires that we distinguish between those two cases.
1433    #
1434    if(ENABLE_SANITIZERS)
1435        #
1436        # This appears to indicate that ENABLE_SANITIZERS was set to
1437        # a string value that is "not one of the false constants".
1438        #
1439        # We already know it's "not one of the true constants", so
1440        # we treat it as a list of sanitizers.
1441        #
1442        foreach(sanitizer IN LISTS ENABLE_SANITIZERS)
1443            unset(SANITIZER_FLAG)
1444            test_sanitizer(${sanitizer} SANITIZER_FLAG)
1445            if(SANITIZER_FLAG)
1446                message(STATUS "${sanitizer} sanitizer supported using ${SANITIZER_FLAG}")
1447                set(SANITIZER_FLAGS "${SANITIZER_FLAGS} ${SANITIZER_FLAG}")
1448            else()
1449                message(FATAL_ERROR "${sanitizer} isn't a supported sanitizer")
1450            endif()
1451        endforeach()
1452    else()
1453        #
1454        # This appears to indicate that ENABLE_SANITIZERS was either:
1455        #
1456        #   not set;
1457        #   set to a value that's "one of the false constants";
1458        #
1459        # so we don't enable any sanitizers.
1460        #
1461        message(STATUS "Not enabling sanitizers")
1462    endif()
1463endif()
1464
1465if(NOT "${SANITIZER_FLAGS}" STREQUAL "")
1466  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O1 -g ${SANITIZER_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls")
1467endif()
1468
1469if(ENABLE_REMOTE)
1470  #
1471  # OpenSSL/libressl.
1472  #
1473  find_package(OpenSSL)
1474  if(OPENSSL_FOUND)
1475    #
1476    # We have OpenSSL.
1477    #
1478    include_directories(SYSTEM ${OPENSSL_INCLUDE_DIR})
1479    set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${OPENSSL_LIBRARIES})
1480
1481    #
1482    # The find_package() module CMake provides for OpenSSL uses does not
1483    # give us a defined indication of whether it found OpenSSL with
1484    # pkg-config or not.  We need to know that as, if it was found with
1485    # pkg-config, we should set the Requires.private value in libpcap.pc
1486    # to include its package name, openssl, otherwise we should add the
1487    # names for the static libraries to Libs.private.
1488    #
1489    # On UN*X, FindOpenSSL happens to use pkg-config to find OpenSSL, but
1490    # it doesn't appear to be documented as doing so; therefore, we don't
1491    # assume that, if we got here, we have pkg-config.
1492    #
1493    # So we use pkg_get_link_info() to run pkg-config ourselves, both
1494    # because FindOpenSSL doesn't set the OPENSSL_LDFLAGS or
1495    # OPENSSL_STATIC_LDFLAGS variables and because, for reasons explained
1496    # in the comment before the pkg_get_link_info() macro, even if it did,
1497    # it wouldn't be what we want anyway.
1498    #
1499    if (PKG_CONFIG_EXECUTABLE)
1500      pkg_get_link_info(OPENSSL openssl)
1501      if (OPENSSL_FOUND_WITH_PKG_CONFIG)
1502        #
1503        # pkg-config failed; assume that means that there is no openssl
1504        # package for it to find.  Just add OPENSSL_LIBRARIES to
1505        # LIBS_PRIVATE AND LIBS_STATIC, as that's the
1506        # best we can do. XXX - need list of -l and -L flags to add....
1507        #
1508        set(LIBS "${LIBS} ${OPENSSL_LIBS}")
1509        set(LIBS_STATIC "${LIBS_STATIC} ${OPENSSL_LIBS_STATIC}")
1510        set(REQUIRES_PRIVATE "${REQUIRES_PRIVATE} ${OPENSSL_PACKAGE_NAME}")
1511      endif()
1512    else()
1513      # Get it from OPENSSL_LIBRARIES
1514      foreach(_lib IN LISTS OPENSSL_LIBRARIES)
1515        #
1516        # Get the directory in which the library resides.
1517        #
1518        get_filename_component(_lib_directory "${_lib}" DIRECTORY)
1519
1520        #
1521        # Is the library directory in CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES?
1522        # (See comment above on why we use that.)
1523        #
1524        list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${_lib_directory}" _lib_index)
1525        if(_lib_index EQUAL -1)
1526          #
1527          # No, so add a -L flag to get the linker to search in that
1528          # directory.
1529          #
1530          set(LIBS "${LIBS} -L${_lib_directory}")
1531          set(LIBS_STATIC "${LIBS_STATIC} -L${_lib_directory}")
1532          set(LIBS_PRIVATE "${LIBS_PRIVATE} -L${_lib_directory}")
1533        endif()
1534
1535        #
1536        # Get the file name of the library, without the extension.
1537        #
1538        get_filename_component(_lib_filename "${_lib}" NAME_WE)
1539
1540        #
1541        # Strip off the "lib" prefix to get the library name, and
1542        # add a -l flag based on that.
1543        #
1544        string(REGEX REPLACE "^lib" "" _library_name "${_lib_filename}")
1545        set(LIBS "${LIBS} -l${_library_name}")
1546        set(LIBS_STATIC "${LIBS_STATIC} -l${_library_name}")
1547        set(LIBS_PRIVATE "${LIBS_PRIVATE} -l${_library_name}")
1548      endforeach()
1549    endif()
1550    set(HAVE_OPENSSL YES)
1551  endif(OPENSSL_FOUND)
1552endif(ENABLE_REMOTE)
1553
1554#
1555# On macOS, build libpcap for the appropriate architectures, if
1556# CMAKE_OSX_ARCHITECTURES isn't set (if it is, let that control
1557# the architectures for which to build it).
1558#
1559if(APPLE AND "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "")
1560    #
1561    # Get the major version of Darwin.
1562    #
1563    string(REGEX MATCH "^([0-9]+)" SYSTEM_VERSION_MAJOR "${CMAKE_SYSTEM_VERSION}")
1564
1565    if(SYSTEM_VERSION_MAJOR LESS 8)
1566        #
1567        # Pre-Tiger.
1568        #
1569        # Build libraries and executables only for 32-bit PowerPC, as
1570        # that's all that is supported.
1571        #
1572        set(OSX_LIBRARY_ARCHITECTURES "ppc")
1573        set(OSX_EXECUTABLE_ARCHITECTURES "ppc")
1574    elseif(SYSTEM_VERSION_MAJOR EQUAL 8)
1575        #
1576        # Tiger.  Is this prior to, or with, Intel support?
1577        #
1578        # Get the minor version of Darwin.
1579        #
1580        string(REPLACE "${SYSTEM_VERSION_MAJOR}." "" SYSTEM_MINOR_AND_PATCH_VERSION ${CMAKE_SYSTEM_VERSION})
1581        string(REGEX MATCH "^([0-9]+)" SYSTEM_VERSION_MINOR "${SYSTEM_MINOR_AND_PATCH_VERSION}")
1582        if(SYSTEM_VERSION_MINOR LESS 4)
1583            #
1584            # Prior to Intel support.
1585            #
1586            # Build libraries and executables for 32-bit PowerPC and
1587            # 64-bit PowerPC, with 32-bit PowerPC first, as those
1588            # are both supported.  (I'm guessing that's what Apple
1589            # does.)
1590            #
1591            set(OSX_LIBRARY_ARCHITECTURES "ppc;ppc64")
1592            set(OSX_EXECUTABLE_ARCHITECTURES "ppc;ppc64")
1593        elseif(SYSTEM_VERSION_MINOR LESS 7)
1594            #
1595            # With Intel support but prior to x86-64 support.
1596            #
1597            # Build for 32-bit PowerPC, 64-bit PowerPC, and 32-bit x86,
1598            # with 32-bit PowerPC first, as those are all supported.
1599            # (I'm guessing that's what Apple does.)
1600            #
1601            set(OSX_LIBRARY_ARCHITECTURES "ppc;ppc64;i386")
1602            set(OSX_EXECUTABLE_ARCHITECTURES "ppc;ppc64;i386")
1603        else()
1604            #
1605            # With Intel support including x86-64 support.
1606            #
1607            # Build for 32-bit PowerPC, 64-bit PowerPC, 32-bit x86,
1608            # and x86-64, with 32-bit PowerPC first, as those are
1609            # all supported.  (I'm guessing that's what Apple does.)
1610            #
1611            set(OSX_LIBRARY_ARCHITECTURES "ppc;ppc64;i386;x86_64")
1612            set(OSX_EXECUTABLE_ARCHITECTURES "ppc;ppc64;i386;x86_64")
1613        endif()
1614    elseif(SYSTEM_VERSION_MAJOR EQUAL 9)
1615        #
1616        # Leopard.
1617        #
1618        # Build libraries and executables for 32-bit PowerPC, 64-bit
1619        # PowerPC, 32-bit x86, and x86-64, with 32-bit PowerPC
1620        # first, as those are all supported.  (That's what Apple
1621        # does.)
1622        #
1623        set(OSX_LIBRARY_ARCHITECTURES "ppc;ppc64;i386;x86_64")
1624        set(OSX_EXECUTABLE_ARCHITECTURES "ppc;ppc64;i386;x86_64")
1625    elseif(SYSTEM_VERSION_MAJOR EQUAL 10)
1626        #
1627        # Snow Leopard.
1628        #
1629        # Build libraries for x86-64, 32-bit x86, and 32-bit PowerPC,
1630        # with x86-64 first, because 32-bit PowerPC executables are
1631        # supported with Rosetta.  (That's what Apple does, even though
1632        # Snow Leopard doesn't run on PPC, so PPC libpcap runs under
1633        # Rosetta, and Rosetta doesn't support BPF ioctls, so PPC
1634        # executables can't do live captures.)
1635        #
1636        set(OSX_LIBRARY_ARCHITECTURES "x86_64;i386;ppc")
1637
1638        #
1639        # Build executables only for 32-bit x86 and 64-bit x86, as PPC
1640        # machines are no longer supported.
1641        #
1642        set(OSX_EXECUTABLE_ARCHITECTURES "x86_64;i386")
1643    elseif(SYSTEM_VERSION_MAJOR GREATER 10 AND SYSTEM_VERSION_MAJOR LESS 19)
1644        #
1645        # Post-Snow Leopard, pre-Catalina.
1646        #
1647        # Build libraries for 64-bit x86 and 32-bit x86, with 64-bit x86
1648        # first, as PPC machines are no longer supported, but 32-bit
1649        # x86 executables are.  (That's what Apple does.)
1650        #
1651        # First, check whether we're building with OpenSSL.
1652        # If so, don't bother trying to build fat.
1653        #
1654        if(HAVE_OPENSSL)
1655          set(X86_32_BIT_SUPPORTED NO)
1656          set(OSX_LIBRARY_ARCHITECTURES "x86_64")
1657          set(OSX_EXECUTABLE_ARCHITECTURES "x86_64")
1658          message(WARNING "We're assuming the OpenSSL libraries are 64-bit only, so we're not compiling for 32-bit x86")
1659        else()
1660          #
1661          # Now, check whether we *can* build for i386.
1662          #
1663          cmake_push_check_state()
1664          set(CMAKE_REQUIRED_FLAGS "-arch i386")
1665          check_c_source_compiles(
1666"int
1667main(void)
1668{
1669    return 0;
1670}
1671"
1672                   X86_32_BIT_SUPPORTED)
1673          cmake_pop_check_state()
1674          if(X86_32_BIT_SUPPORTED)
1675              set(OSX_LIBRARY_ARCHITECTURES "x86_64;i386")
1676          else()
1677              set(OSX_LIBRARY_ARCHITECTURES "x86_64")
1678              #
1679              # We can't build fat; suggest that the user install the
1680              # /usr/include headers if they want to build fat.
1681              #
1682              if(SYSTEM_VERSION_MAJOR LESS 18)
1683                  #
1684                  # Pre-Mojave; the command-line tools should be sufficient to
1685                  # enable 32-bit x86 builds.
1686                  #
1687                  message(WARNING "Compiling for 32-bit x86 gives an error; try installing the command-line tools")
1688              else()
1689                  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")
1690              endif()
1691          endif()
1692        endif()
1693
1694        #
1695        # Build executables only for 64-bit x86, as 32-bit x86 machines
1696        # are no longer supported.
1697        #
1698        set(OSX_EXECUTABLE_ARCHITECTURES "x86_64")
1699    elseif(SYSTEM_VERSION_MAJOR EQUAL 19)
1700        #
1701        # Catalina.
1702        #
1703        # Build libraries and executables only for x86-64, as 32-bit
1704        # executables are no longer supported.  (That's what Apple
1705        # does.)
1706        #
1707        set(OSX_LIBRARY_ARCHITECTURES "x86_64")
1708        set(OSX_EXECUTABLE_ARCHITECTURES "x86_64")
1709    else()
1710        #
1711        # Post-Catalina.  Build libraries and
1712        # executables for x86-64 and ARM64.
1713        # (That's what Apple does, except they
1714        # build for arm64e, which may include
1715        # some of the pointer-checking extensions.)
1716        #
1717        # If we're building with libssl, make sure
1718        # we can build fat with it (i.e., that it
1719        # was built fat); if we can't, don't set
1720        # the target architectures, and just
1721        # build for the host we're on.
1722        #
1723        # Otherwise, just add both of them.
1724        #
1725        if(HAVE_OPENSSL)
1726          cmake_push_check_state()
1727          set(CMAKE_REQUIRED_FLAGS "-arch x86_64 -arch arm64")
1728          set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
1729          set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
1730          #
1731          # We must test whether this compiles and links, so
1732          # check_symbol_exists() isn't sufficient.
1733          #
1734          # SSL_library_init() may be a macro that's #defined
1735          # to be the real function to call, so we have to
1736          # include <openssl/ssl.h>, and check_function_exists()
1737          # isn't sufficient.
1738          #
1739          check_c_source_compiles(
1740"#include <openssl/ssl.h>
1741int
1742main(void)
1743{
1744    SSL_library_init();
1745    return 0;
1746}
1747"
1748              FAT_SSL_BUILDS_SUPPORTED)
1749          cmake_pop_check_state()
1750          if(FAT_SSL_BUILDS_SUPPORTED)
1751            set(OSX_LIBRARY_ARCHITECTURES "x86_64;arm64")
1752            set(OSX_EXECUTABLE_ARCHITECTURES "x86_64;arm64")
1753          endif()
1754        else()
1755          set(OSX_LIBRARY_ARCHITECTURES "x86_64;arm64")
1756          set(OSX_EXECUTABLE_ARCHITECTURES "x86_64;arm64")
1757        endif()
1758    endif()
1759endif()
1760
1761#
1762# Additional linker flags.
1763#
1764set(LINKER_FLAGS "${SANITIZER_FLAGS}")
1765if(ENABLE_PROFILING)
1766    if(MSVC)
1767        set(LINKER_FLAGS " /PROFILE")
1768    else()
1769        set(LINKER_FLAGS " -pg")
1770    endif()
1771endif()
1772
1773######################################
1774# Input files
1775######################################
1776
1777set(PROJECT_SOURCE_LIST_C
1778    bpf_dump.c
1779    bpf_filter.c
1780    bpf_image.c
1781    etherent.c
1782    fmtutils.c
1783    gencode.c
1784    nametoaddr.c
1785    optimize.c
1786    pcap-common.c
1787    pcap-util.c
1788    pcap.c
1789    savefile.c
1790    sf-pcapng.c
1791    sf-pcap.c
1792)
1793
1794if(WIN32)
1795    #
1796    # We add the character set conversion routines; they're Windows-only
1797    # for now.
1798    #
1799    # We assume we don't have asprintf(), and provide an implementation
1800    # that uses _vscprintf() to determine how big the string needs to be.
1801    #
1802    set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C}
1803        charconv.c missing/win_asprintf.c)
1804else()
1805    if(NOT HAVE_ASPRINTF)
1806        set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/asprintf.c)
1807    endif()
1808    if(NOT HAVE_STRLCAT)
1809        set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/strlcat.c)
1810    endif(NOT HAVE_STRLCAT)
1811    if(NOT HAVE_STRLCPY)
1812        set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/strlcpy.c)
1813    endif(NOT HAVE_STRLCPY)
1814    if(NOT HAVE_STRTOK_R)
1815        set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/strtok_r.c)
1816    endif(NOT HAVE_STRTOK_R)
1817endif(WIN32)
1818
1819#
1820# Determine the main pcap-XXX.c file to use, and the libraries with
1821# which we need to link libpcap, if any.
1822#
1823if(WIN32)
1824    #
1825    # Windows.
1826    #
1827    # Has the user explicitly specified a capture type?
1828    #
1829    if(PCAP_TYPE STREQUAL "")
1830        #
1831        # The user didn't explicitly specify a capture mechanism.
1832        # Check whether we have packet.dll.
1833        #
1834        if(HAVE_PACKET32)
1835            #
1836            # We have packet.dll.
1837            # Set the capture type to NPF.
1838            #
1839            set(PCAP_TYPE npf)
1840        else()
1841            #
1842            # We don't have any capture type we know about.
1843            # Report an error, and tell the user to configure with
1844            # -DPCAP_TYPE=null if they want a libpcap that can't
1845            # capture but that can read capture files.  That way,
1846            # nobody gets surprised by getting a no-capture
1847            # libpcap without asking for that.
1848            #
1849            message(FATAL_ERROR "No supported packet capture interface was found.
1850In order to build a version of libpcap that supports packet capture
1851on Windows, you will need to install Npcap and the Npcap SDK, or
1852WinPcap and the WinPcap SDK, and run cmake with -DPacket_ROOT={path of SDK},
1853where {path of SDK} is the path name of the top-level directory of the SDK.
1854That argument may have to be quoted if the path contains blanks.
1855If you want a libpcap that cannot capture packets but that can read
1856pcap and pcapng files, run cmake with -DPCAP_TYPE=null.")
1857        endif()
1858    endif()
1859else()
1860    #
1861    # UN*X.
1862    #
1863    # Figure out what type of packet capture mechanism we have, and
1864    # what libraries we'd need to link libpcap with, if any.
1865    #
1866
1867    #
1868    # Has the user explicitly specified a capture type?
1869    #
1870    if(PCAP_TYPE STREQUAL "")
1871        #
1872        # Check for a bunch of headers for various packet capture mechanisms.
1873        #
1874        check_include_files("sys/types.h;net/bpf.h" HAVE_NET_BPF_H)
1875        if(HAVE_NET_BPF_H)
1876            #
1877            # Does it define BIOCSETIF?
1878            # I.e., is it a header for an LBL/BSD-style capture
1879            # mechanism, or is it just a header for a BPF filter
1880            # engine?  Some versions of Arch Linux, for example,
1881            # have a net/bpf.h that doesn't define BIOCSETIF;
1882            # as it's a Linux, it should use packet sockets,
1883            # instead.
1884            #
1885            # We need:
1886            #
1887            #  sys/types.h, because FreeBSD 10's net/bpf.h
1888            #  requires that various BSD-style integer types
1889            #  be defined;
1890            #
1891            #  sys/time.h, because AIX 5.2 and 5.3's net/bpf.h
1892            #  doesn't include it but does use struct timeval
1893            #  in ioctl definitions;
1894            #
1895            #  sys/ioctl.h and, if we have it, sys/ioccom.h,
1896            #  because net/bpf.h defines ioctls;
1897            #
1898            #  net/if.h, because it defines some structures
1899            #  used in ioctls defined by net/bpf.h;
1900            #
1901            #  sys/socket.h, because OpenBSD 5.9's net/bpf.h
1902            #  defines some structure fields as being
1903            #  struct sockaddrs;
1904            #
1905            # and net/bpf.h doesn't necessarily include all
1906            # of those headers itself.
1907            #
1908            if(HAVE_SYS_IOCCOM_H)
1909                check_symbol_exists(BIOCSETIF "sys/types.h;sys/time.h;sys/ioctl.h;sys/socket.h;sys/ioccom.h;net/bpf.h;net/if.h" BPF_H_DEFINES_BIOCSETIF)
1910            else(HAVE_SYS_IOCCOM_H)
1911                check_symbol_exists(BIOCSETIF "sys/types.h;sys/time.h;sys/ioctl.h;sys/socket.h;net/bpf.h;net/if.h" BPF_H_DEFINES_BIOCSETIF)
1912            endif(HAVE_SYS_IOCCOM_H)
1913        endif(HAVE_NET_BPF_H)
1914        check_include_file(net/pfilt.h HAVE_NET_PFILT_H)
1915        check_include_file(net/enet.h HAVE_NET_ENET_H)
1916        check_include_file(net/nit.h HAVE_NET_NIT_H)
1917        check_include_file(sys/net/nit.h HAVE_SYS_NET_NIT_H)
1918        check_include_file(linux/socket.h HAVE_LINUX_SOCKET_H)
1919        check_include_file(net/raw.h HAVE_NET_RAW_H)
1920        check_include_file(sys/dlpi.h HAVE_SYS_DLPI_H)
1921        check_include_file(config/HaikuConfig.h HAVE_CONFIG_HAIKUCONFIG_H)
1922
1923        if(BPF_H_DEFINES_BIOCSETIF)
1924            #
1925            # BPF.
1926            # Check this before DLPI, so that we pick BPF on
1927            # Solaris 11 and later.
1928            #
1929            set(PCAP_TYPE bpf)
1930        elseif(HAVE_LINUX_SOCKET_H)
1931            #
1932            # No prizes for guessing this one.
1933            #
1934            set(PCAP_TYPE linux)
1935        elseif(HAVE_NET_PFILT_H)
1936            #
1937            # DEC OSF/1, Digital UNIX, Tru64 UNIX
1938            #
1939            set(PCAP_TYPE pf)
1940        elseif(HAVE_NET_ENET_H)
1941            #
1942            # Stanford Enetfilter.
1943            #
1944            set(PCAP_TYPE enet)
1945        elseif(HAVE_NET_NIT_H)
1946            #
1947            # SunOS 4.x STREAMS NIT.
1948            #
1949            set(PCAP_TYPE snit)
1950        elseif(HAVE_SYS_NET_NIT_H)
1951            #
1952            # Pre-SunOS 4.x non-STREAMS NIT.
1953            #
1954            set(PCAP_TYPE nit)
1955        elseif(HAVE_NET_RAW_H)
1956            #
1957            # IRIX snoop.
1958            #
1959            set(PCAP_TYPE snoop)
1960        elseif(HAVE_SYS_DLPI_H)
1961            #
1962            # DLPI on pre-Solaris 11 SunOS 5, HP-UX, possibly others.
1963            #
1964            set(PCAP_TYPE dlpi)
1965        elseif(HAVE_CONFIG_HAIKUCONFIG_H)
1966            #
1967            # Haiku.
1968            #
1969            set(PCAP_TYPE haiku)
1970        else()
1971            #
1972            # We don't have any capture type we know about.
1973            # Report an error, and tell the user to configure with
1974            # -DPCAP_TYPE=null if they want a libpcap that can't
1975            # capture but that can read capture files.  That way,
1976            # nobody gets surprised by getting a no-capture
1977            # libpcap without asking for that.
1978            #
1979            message(FATAL_ERROR "No supported packet capture interface was found.
1980See the INSTALL.md file for information on packet capture support in
1981various operating systems.
1982If you want a libpcap that cannot capture packets but that can read
1983pcap and pcapng files, run cmake with -DPCAP_TYPE=null.")
1984        endif()
1985    endif()
1986endif(WIN32)
1987message(STATUS "Packet capture mechanism type: ${PCAP_TYPE}")
1988
1989find_package(PkgConfig QUIET)
1990
1991#
1992# Do capture-mechanism-dependent tests.
1993#
1994if(WIN32)
1995    if(PCAP_TYPE STREQUAL "npf")
1996        #
1997        # Link with packet.dll before Winsock2.
1998        #
1999        set(PCAP_LINK_LIBRARIES ${Packet_LIBRARIES} ${PCAP_LINK_LIBRARIES})
2000    elseif(PCAP_TYPE STREQUAL "null")
2001    else()
2002        message(FATAL_ERROR "${PCAP_TYPE} is not a valid pcap type")
2003    endif()
2004else(WIN32)
2005    if(PCAP_TYPE STREQUAL "dlpi")
2006        #
2007        # Needed for common functions used by pcap-[dlpi,libdlpi].c
2008        #
2009        set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} dlpisubs.c)
2010
2011        #
2012        # Checks for some header files.
2013        #
2014        check_include_file(sys/bufmod.h HAVE_SYS_BUFMOD_H)
2015        check_include_file(sys/dlpi_ext.h HAVE_SYS_DLPI_EXT_H)
2016        check_include_file(zone.h HAVE_ZONE_H)
2017
2018        #
2019        # Checks to see if Solaris has the public libdlpi(3LIB) library.
2020        # Note: The existence of /usr/include/libdlpi.h does not mean it is the
2021        # public libdlpi(3LIB) version. Before libdlpi was made public, a
2022        # private version also existed, which did not have the same APIs.
2023        # Due to a gcc bug, the default search path for 32-bit libraries does
2024        # not include /lib, we add it explicitly here.
2025        # [http://bugs.opensolaris.org/view_bug.do?bug_id=6619485].
2026        # Also, due to the bug above applications that link to libpcap with
2027        # libdlpi will have to add "-L/lib" option to "configure".
2028        #
2029        cmake_push_check_state()
2030        set(CMAKE_REQUIRED_FLAGS "-L/lib")
2031        set(CMAKE_REQUIRED_LIBRARIES dlpi)
2032        check_function_exists(dlpi_walk HAVE_LIBDLPI)
2033        cmake_pop_check_state()
2034        if(HAVE_LIBDLPI)
2035            #
2036            # XXX - add -L/lib
2037            #
2038            set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} dlpi)
2039            set(LIBS "${LIBS} -ldlpi")
2040            set(LIBS_STATIC "${LIBS_STATIC} -ldlpi")
2041            set(LIBS_PRIVATE "${LIBS_PRIVATE} -ldlpi")
2042            set(PCAP_TYPE libdlpi)
2043        endif()
2044
2045        #
2046        # This check is for Solaris with DLPI support for passive modes.
2047        # See dlpi(7P) for more details.
2048        #
2049        # XXX - there's no check_type() macro that's like check_type_size()
2050        # except that it only checks for the existence of the structure type,
2051        # so we use check_type_size() and ignore the size.
2052        #
2053        cmake_push_check_state()
2054        set(CMAKE_EXTRA_INCLUDE_FILES sys/types.h sys/dlpi.h)
2055        check_type_size(dl_passive_req_t DL_PASSIVE_REQ_T)
2056        cmake_pop_check_state()
2057    elseif(PCAP_TYPE STREQUAL "linux")
2058        #
2059        # Do we have libnl?
2060        # We only want version 3.  Version 2 was, apparently,
2061        # short-lived, and version 1 is source and binary
2062        # incompatible with version 3, and it appears that,
2063        # these days, everybody's using version 3.  We're
2064        # not supporting older versions of the Linux kernel;
2065        # let's drop support for older versions of libnl, too.
2066        #
2067        if(BUILD_WITH_LIBNL)
2068            pkg_check_modules(LIBNL libnl-genl-3.0)
2069            if(LIBNL_FOUND)
2070                set(HAVE_LIBNL TRUE)
2071                include_directories(${LIBNL_INCLUDE_DIRS})
2072                set(PCAP_LINK_LIBRARIES ${LIBNL_LIBRARIES} ${PCAP_LINK_LIBRARIES})
2073
2074                #
2075                # Get raw link flags from pkg-config.
2076                #
2077                pkg_get_link_info(LIBNL libnl-genl-3.0)
2078                set(LIBS "${LIBNL_LIBS} ${LIBS}")
2079                set(LIBS_STATIC "${LIBNL_LIBS_STATIC} ${LIBS_STATIC}")
2080                set(REQUIRES_PRIVATE "${LIBNL_PACKAGE_NAME} ${REQUIRES_PRIVATE}")
2081            else()
2082                cmake_push_check_state()
2083                set(CMAKE_REQUIRED_LIBRARIES nl-3)
2084                check_function_exists(nl_socket_alloc HAVE_LIBNL)
2085                cmake_pop_check_state()
2086                if(HAVE_LIBNL)
2087                    #
2088                    # Yes, we have libnl 3.x.
2089                    #
2090                    set(PCAP_LINK_LIBRARIES nl-genl-3 nl-3 ${PCAP_LINK_LIBRARIES})
2091                    include_directories("/usr/include/libnl3")
2092                    set(LIBS "-lnl-genl-3 -lnl-3 ${LIBS}")
2093                    set(LIBS_STATIC "-lnl-genl-3 -lnl-3 ${LIBS_STATIC}")
2094                    set(LIBS_PRIVATE "-lnl-genl-3 -lnl-3 ${LIBS_PRIVATE}")
2095                endif()
2096            endif()
2097        else()
2098            unset(HAVE_LIBNL CACHE) # check_function_exists stores results in cache
2099        endif()
2100
2101        check_struct_has_member("struct tpacket_auxdata" tp_vlan_tci linux/if_packet.h HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI)
2102    elseif(PCAP_TYPE STREQUAL "bpf")
2103        #
2104        # Check whether we have the *BSD-style ioctls.
2105        #
2106        check_include_files("sys/types.h;net/if_media.h" HAVE_NET_IF_MEDIA_H)
2107
2108        #
2109        # Check whether we have struct BPF_TIMEVAL.
2110        #
2111        # XXX - there's no check_type() macro that's like check_type_size()
2112        # except that it only checks for the existence of the structure type,
2113        # so we use check_type_size() and ignore the size.
2114        #
2115        cmake_push_check_state()
2116        if(HAVE_SYS_IOCCOM_H)
2117            set(CMAKE_EXTRA_INCLUDE_FILES sys/types.h sys/ioccom.h net/bpf.h)
2118            check_type_size("struct BPF_TIMEVAL" STRUCT_BPF_TIMEVAL)
2119        else()
2120            set(CMAKE_EXTRA_INCLUDE_FILES  sys/types.h net/bpf.h)
2121            check_type_size("struct BPF_TIMEVAL" STRUCT_BPF_TIMEVAL)
2122        endif()
2123        cmake_pop_check_state()
2124
2125        #
2126        # Check whether there's a inet/ipnet.h header and,
2127        # if so, whether it defines IPNET_ANY_LINK - if so,
2128        # we assume we have the "any" device (that's a
2129        # Solaris header, and later versions of Solaris
2130        # have an "any" device).
2131        #
2132        # Attempting to include it at compile time could
2133        # be a pain, as it's a kernel header.
2134        #
2135        message(STATUS "Checking whether the Solaris \"any\" device is supported")
2136        if(EXISTS /usr/include/inet/ipnet.h)
2137            file(STRINGS /usr/include/inet/ipnet.h IPNET_ANY_LINK_LINES REGEX IPNET_ANY_LINK)
2138            if(NOT IPNET_ANY_LINK_LINES STREQUAL "")
2139                set(HAVE_SOLARIS_ANY_DEVICE TRUE)
2140            endif()
2141        endif()
2142        if(HAVE_SOLARIS_ANY_DEVICE)
2143            message(STATUS "Checking whether the Solaris \"any\" device is supported - supported")
2144        else()
2145            message(STATUS "Checking whether the Solaris \"any\" device is supported - not supported")
2146        endif()
2147    elseif(PCAP_TYPE STREQUAL "haiku")
2148        #
2149        # Check for some headers just in case.
2150        #
2151        check_include_files("net/if.h;net/if_dl.h;net/if_types.h" HAVE_NET_IF_TYPES_H)
2152        set(PCAP_SRC pcap-${PCAP_TYPE}.c)
2153    elseif(PCAP_TYPE STREQUAL "null")
2154    else()
2155        message(FATAL_ERROR "${PCAP_TYPE} is not a valid pcap type")
2156    endif()
2157endif(WIN32)
2158
2159if(NOT DEFINED PCAP_SRC)
2160set(PCAP_SRC pcap-${PCAP_TYPE}.c)
2161endif()
2162
2163set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} ${PCAP_SRC})
2164
2165#
2166# Now figure out how we get a list of interfaces and addresses,
2167# if we support capturing.  Don't bother if we don't support
2168# capturing.
2169#
2170if(NOT WIN32)
2171    #
2172    # UN*X - figure out what type of interface list mechanism we
2173    # have.
2174    #
2175    # If the capture type is null, that means we can't capture,
2176    # so we can't open any capture devices, so we won't return
2177    # any interfaces.
2178    #
2179    if(NOT PCAP_TYPE STREQUAL "null")
2180        cmake_push_check_state()
2181        set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LINK_LIBRARIES})
2182        check_function_exists(getifaddrs HAVE_GETIFADDRS)
2183        cmake_pop_check_state()
2184        if(NOT HAVE_GETIFADDRS)
2185            #
2186            # It's not in the libraries that, at this point, we've
2187            # found we need to link libpcap with.
2188            #
2189            # It's in libsocket on Solaris and possibly other OSes;
2190            # as long as we're not linking with libxnet, check there.
2191            #
2192            # NOTE: if you hand check_library_exists as its last
2193            # argument a variable that's been set, it skips the test,
2194            # so we need different variables.
2195            #
2196            if(NOT LIBXNET_HAS_GETHOSTBYNAME)
2197                check_library_exists(socket getifaddrs "" SOCKET_HAS_GETIFADDRS)
2198                if(SOCKET_HAS_GETIFADDRS)
2199                    set(PCAP_LINK_LIBRARIES socket ${PCAP_LINK_LIBRARIES})
2200                    set(LIBS "-lsocket ${LIBS}")
2201                    set(LIBS_STATIC "-lsocket ${LIBS_STATIC}")
2202                    set(LIBS_PRIVATE "-lsocket ${LIBS_PRIVATE}")
2203                    set(HAVE_GETIFADDRS TRUE)
2204                endif()
2205            endif()
2206        endif()
2207        if(HAVE_GETIFADDRS)
2208            #
2209            # We have "getifaddrs()"; make sure we have <ifaddrs.h>
2210            # as well, just in case some platform is really weird.
2211            # It may require that sys/types.h be included first,
2212            # so include it first.
2213            #
2214            check_include_files("sys/types.h;ifaddrs.h" HAVE_IFADDRS_H)
2215            if(HAVE_IFADDRS_H)
2216                #
2217                # We have the header, so we use "getifaddrs()" to
2218                # get the list of interfaces.
2219                #
2220                set(FINDALLDEVS_TYPE getad)
2221            else()
2222                #
2223                # We don't have the header - give up.
2224                # XXX - we could also fall back on some other
2225                # mechanism, but, for now, this'll catch this
2226                # problem so that we can at least try to figure
2227                # out something to do on systems with "getifaddrs()"
2228                # but without "ifaddrs.h", if there is something
2229                # we can do on those systems.
2230                #
2231                message(FATAL_ERROR "Your system has getifaddrs() but doesn't have a usable <ifaddrs.h>.")
2232            endif()
2233        else()
2234            #
2235            # Well, we don't have "getifaddrs()", at least not with the
2236            # libraries with which we've decided we need to link
2237            # libpcap with, so we have to use some other mechanism.
2238            #
2239            # Note that this may happen on Solaris, which has
2240            # getifaddrs(), but in -lsocket, not in -lxnet, so we
2241            # won't find it if we link with -lxnet, which we want
2242            # to do for other reasons.
2243            #
2244            # For now, we use either the SIOCGIFCONF ioctl or the
2245            # SIOCGLIFCONF ioctl, preferring the latter if we have
2246            # it; the latter is a Solarisism that first appeared
2247            # in Solaris 8.  (Solaris's getifaddrs() appears to
2248            # be built atop SIOCGLIFCONF; using it directly
2249            # avoids a not-all-that-useful middleman.)
2250            #
2251            try_compile(HAVE_SIOCGLIFCONF ${CMAKE_CURRENT_BINARY_DIR} "${pcap_SOURCE_DIR}/cmake/have_siocglifconf.c" )
2252            if(HAVE_SIOCGLIFCONF)
2253                set(FINDALLDEVS_TYPE glifc)
2254            else()
2255                set(FINDALLDEVS_TYPE gifc)
2256            endif()
2257        endif()
2258        message(STATUS "Find-interfaces mechanism type: ${FINDALLDEVS_TYPE}")
2259        set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} fad-${FINDALLDEVS_TYPE}.c)
2260    endif()
2261endif()
2262
2263# Check for hardware timestamp support.
2264if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
2265    check_include_file(linux/net_tstamp.h HAVE_LINUX_NET_TSTAMP_H)
2266endif()
2267
2268#
2269# Check for additional native sniffing capabilities.
2270#
2271
2272#
2273# Various Linux-specific mechanisms.
2274#
2275if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
2276    # Check for usbmon USB sniffing support.
2277    if(NOT DISABLE_LINUX_USBMON)
2278        set(PCAP_SUPPORT_LINUX_USBMON TRUE)
2279        set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-usb-linux.c)
2280        #
2281        # Do we have a version of <linux/compiler.h> available?
2282        # If so, we might need it for <linux/usbdevice_fs.h>.
2283        #
2284        check_include_files("linux/compiler.h" HAVE_LINUX_COMPILER_H)
2285        if(HAVE_LINUX_COMPILER_H)
2286            #
2287            # Yes - include it when testing for <linux/usbdevice_fs.h>.
2288            #
2289            check_include_files("linux/compiler.h;linux/usbdevice_fs.h" HAVE_LINUX_USBDEVICE_FS_H)
2290        else(HAVE_LINUX_COMPILER_H)
2291            check_include_files("linux/usbdevice_fs.h" HAVE_LINUX_USBDEVICE_FS_H)
2292        endif(HAVE_LINUX_COMPILER_H)
2293        if(HAVE_LINUX_USBDEVICE_FS_H)
2294            #
2295            # OK, does it define bRequestType?  Older versions of the kernel
2296            # define fields with names like "requesttype, "request", and
2297            # "value", rather than "bRequestType", "bRequest", and
2298            # "wValue".
2299            #
2300            if(HAVE_LINUX_COMPILER_H)
2301                check_struct_has_member("struct usbdevfs_ctrltransfer" bRequestType "linux/compiler.h;linux/usbdevice_fs.h" HAVE_STRUCT_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE)
2302            else(HAVE_LINUX_COMPILER_H)
2303                check_struct_has_member("struct usbdevfs_ctrltransfer" bRequestType "linux/usbdevice_fs.h" HAVE_STRUCT_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE)
2304            endif(HAVE_LINUX_COMPILER_H)
2305        endif()
2306    endif()
2307
2308    #
2309    # Check for netfilter sniffing support.
2310    #
2311    # Life's too short to deal with trying to get this to compile
2312    # if you don't get the right types defined with
2313    # __KERNEL_STRICT_NAMES getting defined by some other include.
2314    #
2315    # Check whether the includes Just Work.  If not, don't turn on
2316    # netfilter support.
2317    #
2318    check_c_source_compiles(
2319"#include <sys/socket.h>
2320#include <netinet/in.h>
2321#include <linux/types.h>
2322
2323#include <linux/netlink.h>
2324#include <linux/netfilter.h>
2325#include <linux/netfilter/nfnetlink.h>
2326#include <linux/netfilter/nfnetlink_log.h>
2327#include <linux/netfilter/nfnetlink_queue.h>
2328
2329int
2330main(void)
2331{
2332    return 0;
2333}
2334"
2335        PCAP_SUPPORT_NETFILTER)
2336    if(PCAP_SUPPORT_NETFILTER)
2337        set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-netfilter-linux.c)
2338    endif(PCAP_SUPPORT_NETFILTER)
2339endif()
2340
2341# Check for netmap sniffing support.
2342if(NOT DISABLE_NETMAP)
2343    #
2344    # Check whether net/netmap_user.h is usable if NETMAP_WITH_LIBS is
2345    # defined; it's not usable on DragonFly BSD 4.6 if NETMAP_WITH_LIBS
2346    # is defined, for example, as it includes a nonexistent malloc.h
2347    # header.
2348    #
2349    check_c_source_compiles(
2350"#define NETMAP_WITH_LIBS
2351#include <net/netmap_user.h>
2352
2353int
2354main(void)
2355{
2356    return 0;
2357}
2358"
2359        PCAP_SUPPORT_NETMAP)
2360    if(PCAP_SUPPORT_NETMAP)
2361        set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-netmap.c)
2362    endif(PCAP_SUPPORT_NETMAP)
2363endif()
2364
2365# Check for DPDK sniffing support
2366if(NOT DISABLE_DPDK)
2367    find_package(dpdk)
2368    if(dpdk_FOUND)
2369        #
2370        # We call rte_eth_dev_count_avail(), and older versions of DPDK
2371        # didn't have it, so check for it.
2372        #
2373        cmake_push_check_state()
2374        set(CMAKE_REQUIRED_INCLUDES ${dpdk_INCLUDE_DIRS})
2375        set(CMAKE_REQUIRED_LIBRARIES ${dpdk_LIBRARIES})
2376        check_function_exists(rte_eth_dev_count_avail HAVE_RTE_ETH_DEV_COUNT_AVAIL)
2377        cmake_pop_check_state()
2378        if(HAVE_RTE_ETH_DEV_COUNT_AVAIL)
2379            set(DPDK_C_FLAGS "-march=native")
2380            set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${DPDK_C_FLAGS}")
2381            include_directories(AFTER ${dpdk_INCLUDE_DIRS})
2382            link_directories(AFTER ${dpdk_LIBRARIES})
2383            set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${dpdk_LIBRARIES})
2384            set(LIBS "${LIBS} ${dpdk_LIBS}")
2385            set(LIBS_STATIC "${LIBS_STATIC} ${dpdk_LIBS_STATIC}")
2386            set(REQUIRES_PRIVATE "${REQUIRES_PRIVATE} ${dpdk_PACKAGE_NAME}")
2387            set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-dpdk.c)
2388            set(PCAP_SUPPORT_DPDK TRUE)
2389
2390            #
2391            # Check whether the rte_ether.h file defines
2392            # struct ether_addr or struct rte_ether_addr.
2393            #
2394            # ("API compatibility?  That's for losers!")
2395            #
2396            cmake_push_check_state()
2397            set(CMAKE_REQUIRED_INCLUDES ${dpdk_INCLUDE_DIRS})
2398            set(CMAKE_EXTRA_INCLUDE_FILES rte_ether.h)
2399            check_type_size("struct rte_ether_addr" STRUCT_RTE_ETHER_ADDR)
2400            cmake_pop_check_state()
2401        endif()
2402    else()
2403      message(WARNING,
2404"We couldn't find DPDK with pkg-config.  If you want DPDK support,
2405make sure that pkg-config is installed, that DPDK 18.02.2 or later is
2406installed, and that DPDK provides a .pc file.")
2407    endif()
2408endif()
2409
2410# Check for Bluetooth sniffing support
2411if(NOT DISABLE_BLUETOOTH)
2412    if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
2413        check_include_file(bluetooth/bluetooth.h HAVE_BLUETOOTH_BLUETOOTH_H)
2414        if(HAVE_BLUETOOTH_BLUETOOTH_H)
2415            set(PCAP_SUPPORT_BT TRUE)
2416            set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-bt-linux.c)
2417            #
2418            # OK, does struct sockaddr_hci have an hci_channel
2419            # member?
2420            #
2421            check_struct_has_member("struct sockaddr_hci" hci_channel "bluetooth/bluetooth.h;bluetooth/hci.h" HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL)
2422            if(HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL)
2423                #
2424                # OK, is HCI_CHANNEL_MONITOR defined?
2425                #
2426               check_c_source_compiles(
2427"#include <bluetooth/bluetooth.h>
2428#include <bluetooth/hci.h>
2429
2430int
2431main(void)
2432{
2433    int i = HCI_CHANNEL_MONITOR;
2434    return 0;
2435}
2436"
2437                   PCAP_SUPPORT_BT_MONITOR)
2438               if(PCAP_SUPPORT_BT_MONITOR)
2439                   #
2440                   # Yes, so we can also support Bluetooth monitor
2441                   # sniffing.
2442                   #
2443                   set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-bt-monitor-linux.c)
2444               endif(PCAP_SUPPORT_BT_MONITOR)
2445            endif(HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL)
2446        endif(HAVE_BLUETOOTH_BLUETOOTH_H)
2447    endif()
2448else()
2449    unset(PCAP_SUPPORT_BT_MONITOR CACHE)
2450endif()
2451
2452# Check for D-Bus sniffing support
2453if(NOT DISABLE_DBUS)
2454    #
2455    # We don't support D-Bus sniffing on macOS; see
2456    #
2457    # https://bugs.freedesktop.org/show_bug.cgi?id=74029
2458    #
2459    if(APPLE)
2460        message(FATAL_ERROR "Due to freedesktop.org bug 74029, D-Bus capture support is not available on macOS")
2461    endif(APPLE)
2462    pkg_check_modules(DBUS dbus-1)
2463    if(DBUS_FOUND)
2464        set(PCAP_SUPPORT_DBUS TRUE)
2465        set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-dbus.c)
2466        include_directories(${DBUS_INCLUDE_DIRS})
2467
2468        #
2469        # This "helpfully" supplies DBUS_LIBRARIES as a bunch of
2470        # library names - not paths - and DBUS_LIBRARY_DIRS as
2471        # a bunch of directories.
2472        #
2473        # CMake *really* doesn't like the notion of specifying "here are
2474        # the directories in which to look for libraries" except in
2475        # find_library() calls; it *really* prefers using full paths to
2476        # library files, rather than library names.
2477        #
2478        # Find the libraries and add their full paths.
2479        #
2480        set(DBUS_LIBRARY_FULLPATHS)
2481        foreach(_lib IN LISTS DBUS_LIBRARIES)
2482            #
2483            # Try to find this library, so we get its full path.
2484            #
2485            find_library(_libfullpath ${_lib} HINTS ${DBUS_LIBRARY_DIRS})
2486            list(APPEND DBUS_LIBRARY_FULLPATHS ${_libfullpath})
2487        endforeach()
2488        set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${DBUS_LIBRARY_FULLPATHS})
2489
2490        #
2491        # Get library information for DPDK.
2492        #
2493        pkg_get_link_info(DBUS dbus-1)
2494        set(LIBS "${LIBS} ${DBUS_LIBS}")
2495        set(LIBS_STATIC "${LIBS_STATIC} ${DBUS_LIBS_STATIC}")
2496        set(REQUIRES_PRIVATE "${REQUIRES_PRIVATE} ${DBUS_PACKAGE_NAME}")
2497    endif(DBUS_FOUND)
2498endif(NOT DISABLE_DBUS)
2499
2500# Check for RDMA sniffing support
2501if(NOT DISABLE_RDMA)
2502    pkg_check_modules(LIBIBVERBS libibverbs)
2503    if(LIBIBVERBS_FOUND)
2504        #
2505        # pkg-config found it; remember its pkg-config name.
2506        #
2507        set(LIBIBVERBS_REQUIRES_PRIVATE ${LIBIBVERBS_PACKAGE_NAME})
2508
2509        #
2510        # Get static linking information for it.
2511        #
2512        pkg_get_link_info(LIBIBVERBS libibverbs)
2513    else()
2514        #
2515        # pkg-config didn't find it; try to look for it ourselves
2516        #
2517        check_library_exists(ibverbs ibv_get_device_list "" LIBIBVERBS_HAS_IBV_GET_DEVICE_LIST)
2518        if(LIBIBVERBS_HAS_IBV_GET_DEVICE_LIST)
2519            set(LIBIBVERBS_FOUND TRUE)
2520            set(LIBIBVERBS_LIBRARIES ibverbs)
2521            # XXX - at least on Ubuntu 20.04, there are many more
2522            # libraries needed; is there any platform where
2523            # libibverbs is available but where pkg-config
2524            # isn't available or libibverbs doesn't use it?
2525            # If not, we should only use pkg-config for it.
2526            set(LIBIBVERBS_STATIC_LIBRARIES ibverbs)
2527            set(LIBIBVERBS_LIBS -libverbs)
2528            set(LIBIBVERBS_LIBS_STATIC -libverbs)
2529            set(LIBIBVERBS_LIBS_PRIVATE -libverbs)
2530        endif()
2531    endif()
2532    if(LIBIBVERBS_FOUND)
2533        #
2534        # For unknown reasons, check_include_file() doesn't just attempt
2535        # to compile a test program that includes the header in
2536        # question, it also attempts to link it.
2537        #
2538        # For unknown reasons, at least some of the static inline
2539        # functions defined in infiniband/verbs.h are not inlined by the
2540        # Sun^WOracle Studio C compiler, so the compiler generates code
2541        # for them as part of the object code resulting from compiling
2542        # the test program. At lest some of those functions call
2543        # routines in -libverbs, so, in order to keep the compile and
2544        # link from failing, even though the header file exists and is
2545        # usable, we need to link with -libverbs.
2546        #
2547        cmake_push_check_state()
2548        set(CMAKE_REQUIRED_LIBRARIES ${LIBIBVERBS_LIBRARIES})
2549        check_include_file(infiniband/verbs.h HAVE_INFINIBAND_VERBS_H)
2550        if(HAVE_INFINIBAND_VERBS_H)
2551            check_symbol_exists(ibv_create_flow infiniband/verbs.h PCAP_SUPPORT_RDMASNIFF)
2552            if(PCAP_SUPPORT_RDMASNIFF)
2553                set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-rdmasniff.c)
2554                set(PCAP_LINK_LIBRARIES ${LIBIBVERBS_LIBRARIES} ${PCAP_LINK_LIBRARIES})
2555                set(LIBS "${LIBIBVERBS_LIBS} ${LIBS}")
2556                set(LIBS_STATIC "${LIBIBVERBS_LIBS_STATIC} ${LIBS_STATIC}")
2557                set(LIBS_PRIVATE "${LIBIBVERBS_LIBS_PRIVATE} ${LIBS_PRIVATE}")
2558                set(REQUIRES_PRIVATE "${REQUIRES_PRIVATE} ${LIBIBVERBS_PACKAGE_NAME}")
2559            endif(PCAP_SUPPORT_RDMASNIFF)
2560        endif(HAVE_INFINIBAND_VERBS_H)
2561        cmake_pop_check_state()
2562    endif(LIBIBVERBS_FOUND)
2563endif(NOT DISABLE_RDMA)
2564
2565#
2566# Check for sniffing capabilities using third-party APIs.
2567#
2568
2569# Check for Endace DAG card support.
2570if(NOT DISABLE_DAG)
2571    #
2572    # Try to find the DAG header file and library.
2573    #
2574    find_package(DAG)
2575
2576    #
2577    # Did we succeed?
2578    #
2579    if(DAG_FOUND)
2580        #
2581        # Yes.
2582        # Check for various DAG API functions.
2583        #
2584        cmake_push_check_state()
2585        set(CMAKE_REQUIRED_INCLUDES ${DAG_INCLUDE_DIRS})
2586        set(CMAKE_REQUIRED_LIBRARIES ${DAG_LIBRARIES})
2587        check_function_exists(dag_attach_stream HAVE_DAG_STREAMS_API)
2588        if(NOT HAVE_DAG_STREAMS_API)
2589            message(FATAL_ERROR "DAG library lacks streams support")
2590        endif()
2591        check_function_exists(dag_attach_stream64 HAVE_DAG_LARGE_STREAMS_API)
2592        check_function_exists(dag_get_erf_types HAVE_DAG_GET_ERF_TYPES)
2593        check_function_exists(dag_get_stream_erf_types HAVE_DAG_GET_STREAM_ERF_TYPES)
2594        cmake_pop_check_state()
2595
2596        include_directories(AFTER ${DAG_INCLUDE_DIRS})
2597        set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-dag.c)
2598        set(HAVE_DAG_API TRUE)
2599        set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${DAG_LIBRARIES})
2600        set(LIBS "${LIBS} ${DAG_LIBS}")
2601        set(LIBS_STATIC "${LIBS_STATIC} ${DAG_LIBS_STATIC}")
2602        set(LIBS_PRIVATE "${LIBS_PRIVATE} ${DAG_LIBS_PRIVATE}")
2603
2604        if(HAVE_DAG_LARGE_STREAMS_API)
2605            get_filename_component(DAG_LIBRARY_DIR ${DAG_LIBRARY} PATH)
2606            check_library_exists(vdag vdag_set_device_info ${DAG_LIBRARY_DIR} HAVE_DAG_VDAG)
2607            if(HAVE_DAG_VDAG)
2608                set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
2609                set(LIBS "${LIBS} ${CMAKE_THREAD_LIBS_INIT}")
2610                set(LIBS_STATIC "${LIBS_STATIC} ${CMAKE_THREAD_LIBS_INIT}")
2611                set(LIBS_PRIVATE "${LIBS_PRIVATE} ${CMAKE_THREAD_LIBS_INIT}")
2612            endif()
2613        endif()
2614    endif()
2615endif()
2616
2617# Check for Septel card support.
2618set(PROJECT_EXTERNAL_OBJECT_LIST "")
2619if(NOT DISABLE_SEPTEL)
2620    #
2621    # Do we have the msg.h header?
2622    #
2623    set(SEPTEL_INCLUDE_DIRS "${SEPTEL_ROOT}/INC")
2624    cmake_push_check_state()
2625    set(CMAKE_REQUIRED_INCLUDES ${SEPTEL_INCLUDE_DIRS})
2626    check_include_file(msg.h HAVE_INC_MSG_H)
2627    cmake_pop_check_state()
2628    if(HAVE_INC_MSG_H)
2629        #
2630        # Yes.
2631        #
2632        include_directories(AFTER ${SEPTEL_INCLUDE_DIRS})
2633        set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-septel.c)
2634        set(PROJECT_EXTERNAL_OBJECT_LIST ${PROJECT_EXTERNAL_OBJECT_LIST} "${SEPTEL_ROOT}/asciibin.o ${SEPTEL_ROOT}/bit2byte.o ${SEPTEL_ROOT}/confirm.o ${SEPTEL_ROOT}/fmtmsg.o ${SEPTEL_ROOT}/gct_unix.o ${SEPTEL_ROOT}/hqueue.o ${SEPTEL_ROOT}/ident.o ${SEPTEL_ROOT}/mem.o ${SEPTEL_ROOT}/pack.o ${SEPTEL_ROOT}/parse.o ${SEPTEL_ROOT}/pool.o ${SEPTEL_ROOT}/sdlsig.o ${SEPTEL_ROOT}/strtonum.o ${SEPTEL_ROOT}/timer.o ${SEPTEL_ROOT}/trace.o")
2635        set(HAVE_SEPTEL_API TRUE)
2636    endif()
2637endif()
2638
2639# Check for Myricom SNF support.
2640if(NOT DISABLE_SNF)
2641    #
2642    # Try to find the SNF header file and library.
2643    #
2644    find_package(SNF)
2645
2646    #
2647    # Did we succeed?
2648    #
2649    if(SNF_FOUND)
2650        #
2651        # Yes.
2652        #
2653        include_directories(AFTER ${SNF_INCLUDE_DIRS})
2654        set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-snf.c)
2655        set(HAVE_SNF_API TRUE)
2656        set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${SNF_LIBRARIES})
2657        set(LIBS "${LIBS_STATIC} ${SNF_LIBS}")
2658        set(LIBS_STATIC "${LIBS_STATIC} ${SNF_LIBS_STATIC}")
2659        set(LIBS_PRIVATE "${LIBS_PRIVATE} ${SNF_LIBS_PRIVATE}")
2660    endif()
2661endif()
2662
2663# Check for Riverbed AirPcap support.
2664if(NOT DISABLE_AIRPCAP)
2665    #
2666    # Try to find the AirPcap header file and library.
2667    #
2668    find_package(AirPcap)
2669
2670    #
2671    # Did we succeed?
2672    #
2673    if(AirPcap_FOUND)
2674        #
2675        # Yes.
2676        #
2677        include_directories(AFTER ${AirPcap_INCLUDE_DIRS})
2678        set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-airpcap.c)
2679        set(HAVE_AIRPCAP_API TRUE)
2680        set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${AirPcap_LIBRARIES})
2681    endif()
2682endif()
2683
2684# Check for Riverbed TurboCap support.
2685if(NOT DISABLE_TC)
2686    #
2687    # Try to find the TurboCap header file and library.
2688    #
2689    find_package(TC)
2690
2691    #
2692    # Did we succeed?
2693    #
2694    if(TC_FOUND)
2695        #
2696        # Yes.
2697        #
2698        include_directories(AFTER ${TC_INCLUDE_DIRS})
2699        set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-tc.c)
2700        set(HAVE_TC_API TRUE)
2701        set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${TC_LIBRARIES} ${CMAKE_USE_PTHREADS_INIT} stdc++)
2702    endif()
2703endif()
2704
2705#
2706# Remote capture support.
2707#
2708
2709if(ENABLE_REMOTE)
2710    #
2711    # Check for various members of struct msghdr.
2712    # We need to include ftmacros.h on some platforms, to make sure we
2713    # get the POSIX/Single USER Specification version of struct msghdr,
2714    # which has those members, rather than the backwards-compatible
2715    # version, which doesn't.  That's not a system header file, and
2716    # at least some versions of CMake include it as <ftmacros.h>, which
2717    # won't check the current directory, so we add the top-level
2718    # source directory to the list of include directories when we do
2719    # the check.
2720    #
2721    cmake_push_check_state()
2722    set(CMAKE_REQUIRED_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR})
2723    check_struct_has_member("struct msghdr" msg_control "ftmacros.h;sys/socket.h" HAVE_STRUCT_MSGHDR_MSG_CONTROL)
2724    check_struct_has_member("struct msghdr" msg_flags "ftmacros.h;sys/socket.h" HAVE_STRUCT_MSGHDR_MSG_FLAGS)
2725    cmake_pop_check_state()
2726    set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C}
2727        pcap-new.c pcap-rpcap.c rpcap-protocol.c sockutils.c)
2728    if(OPENSSL_FOUND)
2729        set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} sslutils.c)
2730    endif()
2731endif(ENABLE_REMOTE)
2732
2733###################################################################
2734#   Warning options
2735###################################################################
2736
2737#
2738# Check and add warning options if we have a .devel file.
2739#
2740if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.devel OR EXISTS ${CMAKE_BINARY_DIR}/.devel)
2741    #
2742    # Warning options.
2743    #
2744    if(MSVC AND NOT ${CMAKE_C_COMPILER} MATCHES "clang*")
2745        #
2746        # MSVC, with Microsoft's front end and code generator.
2747        # "MSVC" is also set for Microsoft's compiler with a Clang
2748        # front end and their code generator ("Clang/C2"), so we
2749        # check for clang.exe and treat that differently.
2750        #
2751        check_and_add_compiler_option(-Wall)
2752        #
2753        # Disable some pointless warnings that /Wall turns on.
2754        #
2755        # Unfortunately, MSVC does not appear to have an equivalent
2756        # to "__attribute__((unused))" to mark a particular function
2757        # parameter as being known to be unused, so that the compiler
2758        # won't warn about it (for example, the function might have
2759        # that parameter because a pointer to it is being used, and
2760        # the signature of that function includes that parameter).
2761        # C++ lets you give a parameter a type but no name, but C
2762        # doesn't have that.
2763        #
2764        check_and_add_compiler_option(-wd4100)
2765        #
2766        # In theory, we care whether somebody uses f() rather than
2767        # f(void) to declare a function with no arguments, but, in
2768        # practice, there are places in the Windows header files
2769        # that appear to do that, so we squelch that warning.
2770        #
2771        check_and_add_compiler_option(-wd4255)
2772        #
2773        # Windows FD_SET() generates this, so we suppress it.
2774        #
2775        check_and_add_compiler_option(-wd4548)
2776        #
2777        # Perhaps testing something #defined to be 0 with #ifdef is an
2778        # error, and it should be tested with #if, but perhaps it's
2779        # not, and Microsoft does that in its headers, so we squelch
2780        # that warning.
2781        #
2782        check_and_add_compiler_option(-wd4574)
2783        #
2784        # The Windows headers also test not-defined values in #if, so
2785        # we don't want warnings about that, either.
2786        #
2787        check_and_add_compiler_option(-wd4668)
2788        #
2789        # We do *not* care whether some function is, or isn't, going to be
2790        # expanded inline.
2791        #
2792        check_and_add_compiler_option(-wd4710)
2793        check_and_add_compiler_option(-wd4711)
2794        #
2795        # We do *not* care whether we're adding padding bytes after
2796        # structure members.
2797        #
2798        check_and_add_compiler_option(-wd4820)
2799        #
2800        # We do *not* care about every single place the compiler would
2801        # have inserted Spectre mitigation if only we had told it to
2802        # do so with /Qspectre.  Maybe it's worth it, as that's in
2803        # Bison-generated code that we don't control.
2804        #
2805        # XXX - add /Qspectre if that is really worth doing.
2806        #
2807        check_and_add_compiler_option(-wd5045)
2808
2809        #
2810        # Treat all (remaining) warnings as errors.
2811        #
2812        check_and_add_compiler_option(-WX)
2813    else()
2814        #
2815        # Other compilers, including MSVC with a Clang front end and
2816        # Microsoft's code generator.  We currently treat them as if
2817        # they might support GCC-style -W options.
2818        #
2819        check_and_add_compiler_option(-W)
2820        check_and_add_compiler_option(-Wall)
2821        check_and_add_compiler_option(-Wcomma)
2822        # Warns about safeguards added in case the enums are extended
2823        # check_and_add_compiler_option(-Wcovered-switch-default)
2824        check_and_add_compiler_option(-Wdocumentation)
2825        check_and_add_compiler_option(-Wformat-nonliteral)
2826        check_and_add_compiler_option(-Wmissing-noreturn)
2827        check_and_add_compiler_option(-Wmissing-prototypes)
2828        check_and_add_compiler_option(-Wmissing-variable-declarations)
2829        check_and_add_compiler_option(-Wnull-pointer-subtraction)
2830        check_and_add_compiler_option(-Wpointer-arith)
2831        check_and_add_compiler_option(-Wpointer-sign)
2832        check_and_add_compiler_option(-Wshadow)
2833        check_and_add_compiler_option(-Wshorten-64-to-32)
2834        check_and_add_compiler_option(-Wsign-compare)
2835        check_and_add_compiler_option(-Wstrict-prototypes)
2836        check_and_add_compiler_option(-Wundef)
2837        check_and_add_compiler_option(-Wunreachable-code)
2838        check_and_add_compiler_option(-Wunused-but-set-parameter)
2839        check_and_add_compiler_option(-Wunused-but-set-variable)
2840        check_and_add_compiler_option(-Wunused-parameter)
2841        check_and_add_compiler_option(-Wused-but-marked-unused)
2842    endif()
2843endif()
2844
2845#
2846# Suppress some warnings we get with MSVC even without /Wall.
2847#
2848if(MSVC AND NOT ${CMAKE_C_COMPILER} MATCHES "clang*")
2849    #
2850    # Yes, we have some functions that never return but that
2851    # have a non-void return type.  That's because, on some
2852    # platforms, they *do* return values but, on other
2853    # platforms, including Windows, they just fail and
2854    # longjmp out by calling bpf_error().
2855    #
2856    check_and_add_compiler_option(-wd4646)
2857endif()
2858
2859file(GLOB PROJECT_SOURCE_LIST_H
2860    *.h
2861    pcap/*.h
2862)
2863
2864#
2865# Try to have the compiler default to hiding symbols, so that only
2866# symbols explicitly exported with PCAP_API will be visible outside
2867# (shared) libraries.
2868#
2869# Not necessary with MSVC, as that's the default.
2870#
2871# XXX - we don't use ADD_COMPILER_EXPORT_FLAGS, because, as of CMake
2872# 2.8.12.2, it doesn't know about Sun C/Oracle Studio, and, as of
2873# CMake 2.8.6, it only sets the C++ compiler flags, rather than
2874# allowing an arbitrary variable to be set with the "hide symbols
2875# not explicitly exported" flag.
2876#
2877if(NOT MSVC)
2878    if(CMAKE_C_COMPILER_ID MATCHES "SunPro")
2879        #
2880        # Sun C/Oracle Studio.
2881        #
2882        check_and_add_compiler_option(-xldscope=hidden)
2883    else()
2884        #
2885        # Try this for all other compilers; it's what GCC uses,
2886        # and a number of other compilers, such as Clang and Intel C,
2887        # use it as well.
2888        #
2889        check_and_add_compiler_option(-fvisibility=hidden)
2890    endif()
2891endif(NOT MSVC)
2892
2893#
2894# Extra compiler options for the build matrix scripts to request -Werror or
2895# its equivalent if required.  The CMake variable name cannot be CFLAGS
2896# because that is already used for a different purpose in CMake.  Example
2897# usage: cmake -DEXTRA_CFLAGS='-Wall -Wextra -Werror' ...
2898#
2899if(NOT "${EXTRA_CFLAGS}" STREQUAL "")
2900    # The meaning of EXTRA_CFLAGS is "use the exact specified options, or the
2901    # build risks failing to fail", not "try every specified option, omit those
2902    # that do not work and use the rest".  Thus use add_compile_options(), not
2903    # foreach()/check_and_add_compiler_option().  Another reason to do that is
2904    # that the effect lasts in testprogs/ and testprogs/fuzz/.
2905    string(REPLACE " " ";" _extra_cflags_list ${EXTRA_CFLAGS})
2906    add_compile_options(${_extra_cflags_list})
2907    message(STATUS "Added extra compile options (${EXTRA_CFLAGS})")
2908endif()
2909
2910#
2911# Flex/Lex and YACC/Berkeley YACC/Bison.
2912# From a mail message to the CMake mailing list by Andy Cedilnik of
2913# Kitware.
2914#
2915
2916#
2917# Try to find Flex, a Windows version of Flex, or Lex.
2918#
2919find_program(LEX_EXECUTABLE NAMES flex win_flex lex)
2920if(LEX_EXECUTABLE STREQUAL "LEX_EXECUTABLE-NOTFOUND")
2921    message(FATAL_ERROR "Neither flex nor win_flex nor lex was found.")
2922endif()
2923message(STATUS "Lexical analyzer generator: ${LEX_EXECUTABLE}")
2924
2925#
2926# Make sure {f}lex supports the -P, --header-file, and --nounput flags
2927# and supports processing our scanner.l.
2928#
2929if(WIN32)
2930    set(NULL_DEVICE "NUL:")
2931else()
2932    set(NULL_DEVICE "/dev/null")
2933endif()
2934execute_process(COMMAND ${LEX_EXECUTABLE} -P pcap_ --header-file=${NULL_DEVICE} --nounput -t ${pcap_SOURCE_DIR}/scanner.l
2935    OUTPUT_QUIET RESULT_VARIABLE EXIT_STATUS)
2936if(NOT EXIT_STATUS EQUAL 0)
2937    message(FATAL_ERROR "${LEX_EXECUTABLE} is insufficient to compile libpcap.
2938libpcap requires Flex 2.5.31 or later, or a compatible version of lex.
2939If a suitable version of Lex/Flex is available as a non-standard command
2940and/or not in the PATH, you can specify it using the LEX environment
2941variable. That said, on some systems the error can mean that Flex/Lex is
2942actually acceptable, but m4 is not. Likewise, if a suitable version of
2943m4 (such as GNU M4) is available but has not been detected, you can
2944specify it using the M4 environment variable.")
2945endif()
2946
2947add_custom_command(
2948    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/scanner.c ${CMAKE_CURRENT_BINARY_DIR}/scanner.h
2949    COMMAND ${LEX_EXECUTABLE} -P pcap_ --header-file=scanner.h --nounput -o${CMAKE_CURRENT_BINARY_DIR}/scanner.c ${pcap_SOURCE_DIR}/scanner.l
2950    DEPENDS ${pcap_SOURCE_DIR}/scanner.l
2951)
2952
2953#
2954# Since scanner.c does not exist yet when cmake is run, mark
2955# it as generated.
2956#
2957# Since scanner.c includes grammar.h, mark that as a dependency.
2958#
2959set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/scanner.c PROPERTIES
2960    GENERATED TRUE
2961    OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/grammar.h
2962)
2963
2964#
2965# Add scanner.c to the list of sources.
2966#
2967#set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} ${CMAKE_CURRENT_BINARY_DIR}/scanner.c)
2968
2969#
2970# Try to find YACC or Bison.
2971#
2972find_program(YACC_EXECUTABLE NAMES bison win_bison byacc yacc)
2973if(YACC_EXECUTABLE STREQUAL "YACC_EXECUTABLE-NOTFOUND")
2974    message(FATAL_ERROR "Neither bison nor win_bison nor byacc nor yacc was found.")
2975endif()
2976
2977if(YACC_EXECUTABLE MATCHES "byacc" OR YACC_EXECUTABLE MATCHES "yacc")
2978    #
2979    # Make sure this is Berkeley YACC, not AT&T YACC;
2980    # the latter doesn't support reentrant parsers.
2981    # Run it with "-V"; that succeeds and reports the
2982    # version number with Berkeley YACC, but will
2983    # (probably) fail with various vendor flavors
2984    # of AT&T YACC.
2985    #
2986    # Hopefully this also eliminates any versions
2987    # of Berkeley YACC that don't support reentrant
2988    # parsers, if there are any.
2989    #
2990    execute_process(COMMAND ${YACC_EXECUTABLE} -V OUTPUT_QUIET
2991        RESULT_VARIABLE EXIT_STATUS)
2992    if(NOT EXIT_STATUS EQUAL 0)
2993        message(FATAL_ERROR "${YACC_EXECUTABLE} is insufficient to compile libpcap.
2994libpcap requires Bison, a newer version of Berkeley YACC with support
2995for reentrant parsers, or another YACC compatible with them.")
2996    endif()
2997    #
2998    # Berkeley YACC doesn't support "%define api.pure", so use
2999    # "%pure-parser".
3000    #
3001    set(REENTRANT_PARSER "%pure-parser")
3002else()
3003    #
3004    # Bison prior to 2.4(.1) doesn't support "%define api.pure", so use
3005    # "%pure-parser".
3006    #
3007    execute_process(COMMAND ${YACC_EXECUTABLE} -V OUTPUT_VARIABLE bison_full_version)
3008    string(REGEX MATCH "[1-9][0-9]*[.][0-9]+" bison_major_minor ${bison_full_version})
3009    if (bison_major_minor VERSION_LESS "2.4")
3010        set(REENTRANT_PARSER "%pure-parser")
3011    else()
3012        set(REENTRANT_PARSER "%define api.pure")
3013    endif()
3014endif()
3015
3016message(STATUS "Parser generator: ${YACC_EXECUTABLE}")
3017
3018#
3019# Create custom command for the scanner.
3020#
3021add_custom_command(
3022    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/grammar.c ${CMAKE_CURRENT_BINARY_DIR}/grammar.h
3023    COMMAND ${YACC_EXECUTABLE} -p pcap_ -o ${CMAKE_CURRENT_BINARY_DIR}/grammar.c -d ${pcap_BINARY_DIR}/grammar.y
3024    DEPENDS ${pcap_BINARY_DIR}/grammar.y
3025)
3026
3027#
3028# Since grammar.c does not exists yet when cmake is run, mark
3029# it as generated.
3030#
3031set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/grammar.c PROPERTIES
3032    GENERATED TRUE
3033    OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/scanner.h
3034)
3035
3036#
3037# Add grammar.c to the list of sources.
3038#
3039#set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} ${CMAKE_CURRENT_BINARY_DIR}/grammar.c)
3040
3041#
3042# Assume, by default, no support for shared libraries and V7/BSD
3043# convention for man pages (devices in section 4, file formats in
3044# section 5, miscellaneous info in section 7, administrative commands
3045# and daemons in section 8).  Individual cases can override this.
3046# Individual cases can override this.
3047#
3048set(MAN_DEVICES 4)
3049set(MAN_FILE_FORMATS 5)
3050set(MAN_MISC_INFO 7)
3051set(MAN_ADMIN_COMMANDS 8)
3052if(CMAKE_SYSTEM_NAME STREQUAL "AIX")
3053    # Workaround to enable certain features
3054    set(_SUN TRUE)
3055    if(PCAP_TYPE STREQUAL "bpf")
3056        #
3057        # If we're using BPF, we need libodm and libcfg, as
3058        # we use them to load the BPF module.
3059        #
3060        set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} odm cfg)
3061        set(LIBS "${LIBS} -lodm -lcfg")
3062        set(LIBS_STATIC "${LIBS_STATIC} -lodm -lcfg")
3063        set(LIBS_PRIVATE "${LIBS_PRIVATE} -lodm -lcfg")
3064    endif()
3065elseif(CMAKE_SYSTEM_NAME STREQUAL "HP-UX")
3066    if(CMAKE_SYSTEM_VERSION MATCHES "[A-Z.]*9\.[0-9]*")
3067        #
3068        # HP-UX 9.x.
3069        #
3070        set(HAVE_HPUX9 TRUE)
3071    elseif(CMAKE_SYSTEM_VERSION MATCHES "[A-Z.]*10\.0")
3072        #
3073        # HP-UX 10.0.
3074        #
3075    elseif(CMAKE_SYSTEM_VERSION MATCHES "[A-Z.]*10\.1")
3076        #
3077        # HP-UX 10.1.
3078        #
3079    else()
3080        #
3081        # HP-UX 10.20 and later.
3082        #
3083        set(HAVE_HPUX10_20_OR_LATER TRUE)
3084    endif()
3085
3086    #
3087    # Use System V conventions for man pages.
3088    #
3089    set(MAN_ADMIN_COMMANDS 1m)
3090    set(MAN_FILE_FORMATS 4)
3091    set(MAN_MISC_INFO 5)
3092elseif(CMAKE_SYSTEM_NAME STREQUAL "IRIX" OR CMAKE_SYSTEM_NAME STREQUAL "IRIX64")
3093    #
3094    # Use IRIX conventions for man pages; they're the same as the
3095    # System V conventions, except that they use section 8 for
3096    # administrative commands and daemons.
3097    #
3098    set(MAN_FILE_FORMATS 4)
3099    set(MAN_MISC_INFO 5)
3100elseif(CMAKE_SYSTEM_NAME STREQUAL "OSF1")
3101    #
3102    # DEC OSF/1, a/k/a Digital UNIX, a/k/a Tru64 UNIX.
3103    # Use Tru64 UNIX conventions for man pages; they're the same as the
3104    # System V conventions except that they use section 8 for
3105    # administrative commands and daemons.
3106    #
3107    set(MAN_FILE_FORMATS 4)
3108    set(MAN_MISC_INFO 5)
3109    set(MAN_DEVICES 7)
3110elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION MATCHES "5[.][0-9.]*")
3111    #
3112    # SunOS 5.x.
3113    #
3114    set(HAVE_SOLARIS TRUE)
3115    #
3116    # Make sure errno is thread-safe, in case we're called in
3117    # a multithreaded program.  We don't guarantee that two
3118    # threads can use the *same* pcap_t safely, but the
3119    # current version does guarantee that you can use different
3120    # pcap_t's in different threads, and even that pcap_compile()
3121    # is thread-safe (it wasn't thread-safe in some older versions).
3122    #
3123    add_definitions(-D_TS_ERRNO)
3124
3125    if(CMAKE_SYSTEM_VERSION STREQUAL "5.12")
3126    else()
3127        #
3128        # Use System V conventions for man pages.
3129        #
3130        set(MAN_ADMIN_COMMANDS 1m)
3131        set(MAN_FILE_FORMATS 4)
3132        set(MAN_MISC_INFO 5)
3133        set(MAN_DEVICES 7D)
3134    endif()
3135elseif(CMAKE_SYSTEM_NAME STREQUAL "Haiku")
3136    #
3137    # Haiku needs _BSD_SOURCE for the _IO* macros because it doesn't use them.
3138    #
3139    add_definitions(-D_BSD_SOURCE)
3140endif()
3141
3142source_group("Source Files" FILES ${PROJECT_SOURCE_LIST_C})
3143source_group("Header Files" FILES ${PROJECT_SOURCE_LIST_H})
3144
3145if(WIN32)
3146    #
3147    # Add pcap-dll.rc to the list of sources.
3148    #
3149    set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} ${pcap_SOURCE_DIR}/pcap-dll.rc)
3150endif(WIN32)
3151
3152#
3153# Add subdirectories after we've set various variables, so they pick up
3154# pick up those variables.
3155#
3156if(ENABLE_REMOTE)
3157    add_subdirectory(rpcapd)
3158endif(ENABLE_REMOTE)
3159add_subdirectory(testprogs)
3160
3161######################################
3162# Register targets
3163######################################
3164
3165#
3166# Special target to serialize the building of the generated source.
3167#
3168# See
3169#
3170#  https://public.kitware.com/pipermail/cmake/2013-August/055510.html
3171#
3172add_custom_target(SerializeTarget
3173    DEPENDS
3174    ${CMAKE_CURRENT_BINARY_DIR}/grammar.c
3175    ${CMAKE_CURRENT_BINARY_DIR}/scanner.c
3176)
3177
3178set_source_files_properties(${PROJECT_EXTERNAL_OBJECT_LIST} PROPERTIES
3179    EXTERNAL_OBJECT TRUE)
3180
3181if(BUILD_SHARED_LIBS)
3182    add_library(${LIBRARY_NAME} SHARED
3183        ${PROJECT_SOURCE_LIST_C}
3184        ${CMAKE_CURRENT_BINARY_DIR}/grammar.c
3185        ${CMAKE_CURRENT_BINARY_DIR}/scanner.c
3186        ${PROJECT_EXTERNAL_OBJECT_LIST}
3187    )
3188    target_include_directories(${LIBRARY_NAME} PUBLIC
3189        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
3190        $<INSTALL_INTERFACE:include>
3191    )
3192    add_dependencies(${LIBRARY_NAME} SerializeTarget)
3193    set_target_properties(${LIBRARY_NAME} PROPERTIES
3194        COMPILE_DEFINITIONS BUILDING_PCAP)
3195    #
3196    # No matter what the library is called - it might be called "wpcap"
3197    # in a Windows build - the symbol to define to indicate that we're
3198    # building the library, rather than a program using the library,
3199    # and thus that we're exporting functions defined in our public
3200    # header files, rather than importing those functions, is
3201    # pcap_EXPORTS.
3202    #
3203    set_target_properties(${LIBRARY_NAME} PROPERTIES
3204        DEFINE_SYMBOL pcap_EXPORTS)
3205    if(NOT "${LINKER_FLAGS}" STREQUAL "")
3206        set_target_properties(${LIBRARY_NAME} PROPERTIES
3207            LINK_FLAGS "${LINKER_FLAGS}")
3208    endif()
3209endif(BUILD_SHARED_LIBS)
3210
3211add_library(${LIBRARY_NAME}_static STATIC
3212    ${PROJECT_SOURCE_LIST_C}
3213    ${CMAKE_CURRENT_BINARY_DIR}/grammar.c
3214    ${CMAKE_CURRENT_BINARY_DIR}/scanner.c
3215    ${PROJECT_EXTERNAL_OBJECT_LIST}
3216)
3217target_include_directories(${LIBRARY_NAME}_static PUBLIC
3218    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
3219    $<INSTALL_INTERFACE:include>
3220)
3221add_dependencies(${LIBRARY_NAME}_static SerializeTarget)
3222set_target_properties(${LIBRARY_NAME}_static PROPERTIES
3223    COMPILE_DEFINITIONS BUILDING_PCAP)
3224
3225if(WIN32)
3226    if(BUILD_SHARED_LIBS)
3227        set_target_properties(${LIBRARY_NAME} PROPERTIES
3228            VERSION ${PACKAGE_VERSION_NOSUFFIX} # only MAJOR and MINOR are needed
3229        )
3230    endif(BUILD_SHARED_LIBS)
3231    if(MSVC)
3232        # XXX For DLLs, the TARGET_PDB_FILE generator expression can be used to locate
3233        # its PDB file's output directory for installation.
3234        # cmake doesn't offer a generator expression for PDB files generated by the
3235        # compiler (static libraries).
3236        # So instead of considering any possible output there is (there are many),
3237        # this will search for the PDB file in the compiler's initial output directory,
3238        # which is always ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles\wpcap_static.dir
3239        # regardless of architecture, build generator etc.
3240        # Quite hackish indeed.
3241        set(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY $<TARGET_FILE_DIR:${LIBRARY_NAME}_static>)
3242        set_target_properties(${LIBRARY_NAME}_static PROPERTIES
3243            COMPILE_PDB_NAME ${LIBRARY_NAME}_static
3244            OUTPUT_NAME "${LIBRARY_NAME}_static"
3245        )
3246    elseif(MINGW)
3247        #
3248        # For compatibility, build the shared library without the "lib" prefix on
3249        # MinGW as well.
3250        #
3251        set_target_properties(${LIBRARY_NAME} PROPERTIES
3252            PREFIX ""
3253            OUTPUT_NAME "${LIBRARY_NAME}"
3254        )
3255        set_target_properties(${LIBRARY_NAME}_static PROPERTIES
3256            OUTPUT_NAME "${LIBRARY_NAME}"
3257        )
3258    endif()
3259else(WIN32) # UN*X
3260    if(BUILD_SHARED_LIBS)
3261        if(APPLE)
3262            set_target_properties(${LIBRARY_NAME} PROPERTIES
3263                VERSION ${PACKAGE_VERSION}
3264                SOVERSION A
3265            )
3266        else(APPLE)
3267            set_target_properties(${LIBRARY_NAME} PROPERTIES
3268                VERSION ${PACKAGE_VERSION}
3269                SOVERSION ${PACKAGE_VERSION_MAJOR}
3270            )
3271        endif(APPLE)
3272    endif(BUILD_SHARED_LIBS)
3273    set_target_properties(${LIBRARY_NAME}_static PROPERTIES
3274        OUTPUT_NAME "${LIBRARY_NAME}"
3275    )
3276endif(WIN32)
3277
3278if(BUILD_SHARED_LIBS)
3279    if(NOT C_ADDITIONAL_FLAGS STREQUAL "")
3280        set_target_properties(${LIBRARY_NAME} PROPERTIES COMPILE_FLAGS ${C_ADDITIONAL_FLAGS})
3281    endif()
3282
3283    #
3284    # If this is macOS and we've picked the default architectures on
3285    # which to build, build the library on them.
3286    #
3287    if(APPLE AND "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "")
3288        set_target_properties(${LIBRARY_NAME} PROPERTIES
3289            OSX_ARCHITECTURES "${OSX_LIBRARY_ARCHITECTURES}")
3290    endif()
3291    target_link_libraries(${LIBRARY_NAME} ${PCAP_LINK_LIBRARIES})
3292endif(BUILD_SHARED_LIBS)
3293
3294if(NOT C_ADDITIONAL_FLAGS STREQUAL "")
3295    set_target_properties(${LIBRARY_NAME}_static PROPERTIES COMPILE_FLAGS ${C_ADDITIONAL_FLAGS})
3296endif()
3297
3298#
3299# If this is macOS and we've picked the default architectures on
3300# which to build, build the library on them.
3301#
3302if(APPLE AND "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "")
3303    set_target_properties(${LIBRARY_NAME}_static PROPERTIES
3304        OSX_ARCHITECTURES "${OSX_LIBRARY_ARCHITECTURES}")
3305endif()
3306
3307######################################
3308# Write out the config.h file
3309######################################
3310
3311configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmakeconfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
3312
3313######################################
3314# Write out the grammar.y file
3315######################################
3316
3317configure_file(${CMAKE_CURRENT_SOURCE_DIR}/grammar.y.in ${CMAKE_CURRENT_BINARY_DIR}/grammar.y @ONLY)
3318
3319######################################
3320# Install pcap library, include files, and man pages
3321######################################
3322
3323#
3324# "Define GNU standard installation directories", which actually
3325# are also defined, to some degree, by autotools, and at least
3326# some of which are general UN*X conventions.
3327#
3328include(GNUInstallDirs)
3329
3330set(LIBRARY_NAME_STATIC ${LIBRARY_NAME}_static)
3331
3332function(install_manpage_symlink SOURCE TARGET MANDIR)
3333    if(MINGW)
3334        #
3335        # If we haven't found an ln executable with MinGW, we don't try
3336        # generating and installing the man pages, so if we get here,
3337        # we've found that executable.
3338        set(LINK_COMMAND "\"${LINK_EXECUTABLE}\" \"-s\" \"${SOURCE}\" \"${TARGET}\"")
3339    else(MINGW)
3340        set(LINK_COMMAND "\"${CMAKE_COMMAND}\" \"-E\" \"create_symlink\" \"${SOURCE}\" \"${TARGET}\"")
3341    endif(MINGW)
3342
3343    install(CODE "
3344         if(NOT ${CMAKE_INSTALL_MESSAGE} STREQUAL \"NEVER\")
3345             message(STATUS \"Symlinking: \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${MANDIR}/${SOURCE} to ${TARGET}\")
3346         endif()
3347         execute_process(
3348            COMMAND \"${CMAKE_COMMAND}\" \"-E\" \"remove\" \"${TARGET}\"
3349            WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${MANDIR}
3350          )
3351         execute_process(
3352            COMMAND ${LINK_COMMAND}
3353            WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${MANDIR}
3354            RESULT_VARIABLE EXIT_STATUS
3355          )
3356          if(NOT EXIT_STATUS EQUAL 0)
3357              message(FATAL_ERROR \"Could not create symbolic link from \${CMAKE_INSTALL_PREFIX}/${MANDIR}/${SOURCE} to ${TARGET}\")
3358          endif()
3359          set(CMAKE_INSTALL_MANIFEST_FILES \${CMAKE_INSTALL_MANIFEST_FILES} \${CMAKE_INSTALL_PREFIX}/${MANDIR}/${TARGET})")
3360endfunction(install_manpage_symlink)
3361
3362set(MAN1_NOEXPAND pcap-config.1)
3363set(MAN3PCAP_EXPAND
3364    pcap.3pcap.in
3365    pcap_compile.3pcap.in
3366    pcap_datalink.3pcap.in
3367    pcap_dump_open.3pcap.in
3368    pcap_get_tstamp_precision.3pcap.in
3369    pcap_list_datalinks.3pcap.in
3370    pcap_list_tstamp_types.3pcap.in
3371    pcap_open_dead.3pcap.in
3372    pcap_open_offline.3pcap.in
3373    pcap_set_immediate_mode.3pcap.in
3374    pcap_set_tstamp_precision.3pcap.in
3375    pcap_set_tstamp_type.3pcap.in
3376)
3377set(MAN3PCAP_NOEXPAND
3378    pcap_activate.3pcap
3379    pcap_breakloop.3pcap
3380    pcap_can_set_rfmon.3pcap
3381    pcap_close.3pcap
3382    pcap_create.3pcap
3383    pcap_datalink_name_to_val.3pcap
3384    pcap_datalink_val_to_name.3pcap
3385    pcap_dump.3pcap
3386    pcap_dump_close.3pcap
3387    pcap_dump_file.3pcap
3388    pcap_dump_flush.3pcap
3389    pcap_dump_ftell.3pcap
3390    pcap_file.3pcap
3391    pcap_fileno.3pcap
3392    pcap_findalldevs.3pcap
3393    pcap_freecode.3pcap
3394    pcap_get_required_select_timeout.3pcap
3395    pcap_get_selectable_fd.3pcap
3396    pcap_geterr.3pcap
3397    pcap_init.3pcap
3398    pcap_inject.3pcap
3399    pcap_is_swapped.3pcap
3400    pcap_lib_version.3pcap
3401    pcap_lookupdev.3pcap
3402    pcap_lookupnet.3pcap
3403    pcap_loop.3pcap
3404    pcap_major_version.3pcap
3405    pcap_next_ex.3pcap
3406    pcap_offline_filter.3pcap
3407    pcap_open_live.3pcap
3408    pcap_set_buffer_size.3pcap
3409    pcap_set_datalink.3pcap
3410    pcap_set_promisc.3pcap
3411    pcap_set_protocol_linux.3pcap
3412    pcap_set_rfmon.3pcap
3413    pcap_set_snaplen.3pcap
3414    pcap_set_timeout.3pcap
3415    pcap_setdirection.3pcap
3416    pcap_setfilter.3pcap
3417    pcap_setnonblock.3pcap
3418    pcap_snapshot.3pcap
3419    pcap_stats.3pcap
3420    pcap_statustostr.3pcap
3421    pcap_strerror.3pcap
3422    pcap_tstamp_type_name_to_val.3pcap
3423    pcap_tstamp_type_val_to_name.3pcap
3424)
3425set(MANFILE_EXPAND
3426    pcap-savefile.manfile.in
3427)
3428set(MANMISC_EXPAND
3429    pcap-filter.manmisc.in
3430    pcap-linktype.manmisc.in
3431    pcap-tstamp.manmisc.in
3432)
3433
3434if(BUILD_SHARED_LIBS)
3435    set(LIBRARIES_TO_INSTALL "${LIBRARY_NAME}" "${LIBRARY_NAME_STATIC}")
3436else(BUILD_SHARED_LIBS)
3437    set(LIBRARIES_TO_INSTALL "${LIBRARY_NAME_STATIC}")
3438endif(BUILD_SHARED_LIBS)
3439
3440if(WIN32 OR CYGWIN OR MSYS)
3441    #
3442    # XXX - according to the CMake documentation, WIN32 is set if
3443    # the target is Windows; would there ever be a case where
3444    # CYGWIN or MSYS are set but WIN32 *isn't* set?
3445    #
3446    if(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8)
3447        #
3448        # Install 64-bit code built with MSVC in the x64 subdirectories,
3449        # as that's where it expects it to be.
3450        #
3451        install(TARGETS ${LIBRARIES_TO_INSTALL}
3452                RUNTIME DESTINATION bin/x64
3453                LIBRARY DESTINATION lib/x64
3454                ARCHIVE DESTINATION lib/x64)
3455        if(NOT MINGW)
3456            install(FILES $<TARGET_FILE_DIR:${LIBRARY_NAME_STATIC}>/${LIBRARY_NAME_STATIC}.pdb
3457                    DESTINATION bin/x64 OPTIONAL)
3458            if(BUILD_SHARED_LIBS)
3459                install(FILES $<TARGET_PDB_FILE:${LIBRARY_NAME}>
3460                        DESTINATION bin/x64 OPTIONAL)
3461            endif(BUILD_SHARED_LIBS)
3462        endif(NOT MINGW)
3463    else(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8)
3464        #
3465        # Install 32-bit code, and 64-bit code not built with MSVC
3466        # in the top-level directories, as those are where they
3467        # expect it to be.
3468        #
3469        install(TARGETS ${LIBRARIES_TO_INSTALL}
3470                RUNTIME DESTINATION bin
3471                LIBRARY DESTINATION lib
3472                ARCHIVE DESTINATION lib)
3473        if(MSVC)
3474            install(FILES $<TARGET_FILE_DIR:${LIBRARY_NAME_STATIC}>/${LIBRARY_NAME_STATIC}.pdb
3475                    DESTINATION bin OPTIONAL)
3476            if(BUILD_SHARED_LIBS)
3477                install(FILES $<TARGET_PDB_FILE:${LIBRARY_NAME}>
3478                        DESTINATION bin OPTIONAL)
3479            endif(BUILD_SHARED_LIBS)
3480        endif(MSVC)
3481    endif(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8)
3482else(WIN32 OR CYGWIN OR MSYS)
3483    install(TARGETS ${LIBRARIES_TO_INSTALL} DESTINATION ${CMAKE_INSTALL_LIBDIR})
3484endif(WIN32 OR CYGWIN OR MSYS)
3485
3486install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/pcap/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/pcap)
3487install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pcap.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
3488install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pcap-bpf.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
3489install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pcap-namedb.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
3490
3491# On UN*X, and on Windows when not using MSVC, generate libpcap.pc and
3492# pcap-config and process man pages and arrange that they be installed.
3493if(NOT MSVC)
3494    set(prefix ${CMAKE_INSTALL_PREFIX})
3495    set(exec_prefix "\${prefix}")
3496    set(includedir "\${prefix}/include")
3497    set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
3498
3499    #
3500    # If this is a platform where we need to have the .pc file and
3501    # pcap-config script supply an rpath option to specify the directory
3502    # in which the libpcap shared library is installed, and the install
3503    # prefix /usr (meaning we're not installing a system library),
3504    # provide the rpath option.
3505    #
3506    # (We must check CMAKE_INSTALL_PREFIX, as the library directory
3507    # isn't  necessarily /usr/lib in this case - for example, Linux
3508    # distributions for 64-bit platforms that also provide support for
3509    # binaries for a 32-bit version of the platform may put the 64-bit
3510    # libraries, the 32-bit libraries, or both in directories other than
3511    # /usr/lib.)
3512    #
3513    # In AIX, do we have to do this?
3514    #
3515    # In Darwin-based OSes, the full paths of the shared libraries with
3516    # which the program was linked are stored in the executable, so we
3517    # don't need to provide an rpath option.
3518    #
3519    # With the HP-UX linker, directories specified with -L are, by
3520    # default, added to the run-time search path, so we don't need to
3521    # supply them.
3522    #
3523    # For Tru64 UNIX, "-rpath" works with DEC's^WCompaq's^WHP's C
3524    # compiler for Alpha, but isn't documented as working with GCC, and
3525    # no GCC-compatible option is documented as working with the DEC
3526    # compiler.  If anybody needs this on Tru64/Alpha, they're welcome
3527    # to figure out a way to make it work.
3528    #
3529    # This must *not* depend on the compiler, as, on platforms where
3530    # there's a GCC-compatible compiler and a vendor compiler, we need
3531    # to work with both.
3532    #
3533    if(NOT CMAKE_INSTALL_PREFIX STREQUAL "/usr")
3534        if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
3535           CMAKE_SYSTEM_NAME STREQUAL "NetBSD" OR
3536           CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR
3537           CMAKE_SYSTEM_NAME STREQUAL "DragonFly BSD" OR
3538           CMAKE_SYSTEM_NAME STREQUAL "Linux")
3539            #
3540            # Platforms where the "native" C compiler is GCC or accepts
3541            # compatible command-line arguments, and the "native" linker
3542            # is the GNU linker or accepts compatible command-line
3543            # arguments.
3544            #
3545            set(RPATH "-Wl,-rpath,\${libdir}")
3546        elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION MATCHES "5[.][0-9.]*")
3547            #
3548            # SunOS 5.x.
3549            #
3550            # Sun/Oracle's linker, the GNU linker, and GNU-compatible
3551            # linkers all support -R.
3552            #
3553            set(RPATH "-Wl,-R,\${libdir}")
3554        else()
3555            #
3556            # No option needed to set the RPATH.
3557            #
3558            set(RPATH "")
3559        endif()
3560    endif()
3561    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pcap-config.in ${CMAKE_CURRENT_BINARY_DIR}/pcap-config @ONLY)
3562    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpcap.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libpcap.pc @ONLY)
3563    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/pcap-config DESTINATION bin)
3564    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpcap.pc DESTINATION lib/pkgconfig)
3565
3566    #
3567    # Man pages.
3568    #
3569    # For each section of the manual for which we have man pages
3570    # that require macro expansion, do the expansion.
3571    #
3572    # If this is MinGW, maybe we have a UN*X-style ln command and
3573    # maybe we don't.  (No, we do *NOT* require MSYS!)  If we don't
3574    # have it, don't do the man pages.
3575    #
3576    if(MINGW)
3577        find_program(LINK_EXECUTABLE ln)
3578    endif(MINGW)
3579    if(UNIX OR (MINGW AND LINK_EXECUTABLE))
3580        set(MAN1 "")
3581        foreach(MANPAGE ${MAN1_NOEXPAND})
3582            set(MAN1 ${MAN1} ${CMAKE_CURRENT_SOURCE_DIR}/${MANPAGE})
3583        endforeach(MANPAGE)
3584        install(FILES ${MAN1} DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
3585
3586        set(MAN3PCAP "")
3587        foreach(MANPAGE ${MAN3PCAP_NOEXPAND})
3588            set(MAN3PCAP ${MAN3PCAP} ${CMAKE_CURRENT_SOURCE_DIR}/${MANPAGE})
3589        endforeach(MANPAGE)
3590        foreach(TEMPLATE_MANPAGE ${MAN3PCAP_EXPAND})
3591            string(REPLACE ".in" "" MANPAGE ${TEMPLATE_MANPAGE})
3592            configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY)
3593            set(MAN3PCAP ${MAN3PCAP} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE})
3594        endforeach(TEMPLATE_MANPAGE)
3595        install(FILES ${MAN3PCAP} DESTINATION ${CMAKE_INSTALL_MANDIR}/man3)
3596        install_manpage_symlink(pcap_datalink_val_to_name.3pcap pcap_datalink_val_to_description.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
3597        install_manpage_symlink(pcap_datalink_val_to_name.3pcap pcap_datalink_val_to_description_or_dlt.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
3598        install_manpage_symlink(pcap_dump_open.3pcap pcap_dump_fopen.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
3599        install_manpage_symlink(pcap_findalldevs.3pcap pcap_freealldevs.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
3600        install_manpage_symlink(pcap_geterr.3pcap pcap_perror.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
3601        install_manpage_symlink(pcap_inject.3pcap pcap_sendpacket.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
3602        install_manpage_symlink(pcap_list_datalinks.3pcap pcap_free_datalinks.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
3603        install_manpage_symlink(pcap_list_tstamp_types.3pcap pcap_free_tstamp_types.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
3604        install_manpage_symlink(pcap_loop.3pcap pcap_dispatch.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
3605        install_manpage_symlink(pcap_major_version.3pcap pcap_minor_version.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
3606        install_manpage_symlink(pcap_next_ex.3pcap pcap_next.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
3607        install_manpage_symlink(pcap_open_dead.3pcap pcap_open_dead_with_tstamp_precision.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
3608        install_manpage_symlink(pcap_open_offline.3pcap pcap_open_offline_with_tstamp_precision.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
3609        install_manpage_symlink(pcap_open_offline.3pcap pcap_fopen_offline.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
3610        install_manpage_symlink(pcap_open_offline.3pcap pcap_fopen_offline_with_tstamp_precision.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
3611        install_manpage_symlink(pcap_tstamp_type_val_to_name.3pcap pcap_tstamp_type_val_to_description.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
3612        install_manpage_symlink(pcap_setnonblock.3pcap pcap_getnonblock.3pcap ${CMAKE_INSTALL_MANDIR}/man3)
3613
3614        set(MANFILE "")
3615        foreach(TEMPLATE_MANPAGE ${MANFILE_EXPAND})
3616            string(REPLACE ".manfile.in" ".${MAN_FILE_FORMATS}" MANPAGE ${TEMPLATE_MANPAGE})
3617            configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY)
3618            set(MANFILE ${MANFILE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE})
3619        endforeach(TEMPLATE_MANPAGE)
3620        install(FILES ${MANFILE} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_FILE_FORMATS})
3621
3622        set(MANMISC "")
3623        foreach(TEMPLATE_MANPAGE ${MANMISC_EXPAND})
3624            string(REPLACE ".manmisc.in" ".${MAN_MISC_INFO}" MANPAGE ${TEMPLATE_MANPAGE})
3625            configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY)
3626            set(MANMISC ${MANMISC} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE})
3627        endforeach(TEMPLATE_MANPAGE)
3628        install(FILES ${MANMISC} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_MISC_INFO})
3629    endif(UNIX OR (MINGW AND LINK_EXECUTABLE))
3630endif(NOT MSVC)
3631
3632# uninstall target
3633configure_file(
3634    "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
3635    "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
3636    IMMEDIATE @ONLY)
3637
3638add_custom_target(uninstall
3639    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
3640