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