]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libpcap/CMakeLists.txt
Update the Arm Optimized Routine library to v23.01
[FreeBSD/FreeBSD.git] / contrib / libpcap / CMakeLists.txt
1 if(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)
6 else(WIN32)
7     cmake_minimum_required(VERSION 2.8.6)
8 endif(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 #
15 if(POLICY CMP0042)
16     cmake_policy(SET CMP0042 OLD)
17 endif()
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 #
24 if(POLICY CMP0054)
25     cmake_policy(SET CMP0054 NEW)
26 endif()
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 #
34 if(POLICY CMP0074)
35     cmake_policy(SET CMP0074 NEW)
36 endif()
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 #
43 if(POLICY CMP0075)
44     cmake_policy(SET CMP0075 NEW)
45 endif()
46
47 set(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 #
62 project(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 #
97 macro(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()
161 endmacro()
162
163 macro(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()
191 endmacro()
192
193 if(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. \
238 This prevents code in these languages from being combined.")
239     endif()
240 endif()
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 #
249 if(CMAKE_SIZEOF_VOID_P EQUAL 4)
250   message(STATUS "Building 32-bit")
251 elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
252   message(STATUS "Building 64-bit")
253 endif()
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 #
265 if(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()
314 endif()
315
316 include(CheckCCompilerFlag)
317
318 #
319 # For checking if a compiler flag works and adding it if it does.
320 #
321 macro(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()
329 endmacro()
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 #
338 set(C_ADDITIONAL_FLAGS "")
339 if(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*")
353 else(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()
414 endif(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 #
427 if(MINGW)
428     add_definitions(-D_WIN32_WINNT=0x0601)
429 endif(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 #
437 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/run)
438
439 ###################################################################
440 #   Parameters
441 ###################################################################
442
443 if(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")
450 else()
451     #
452     # On UN*X, it's always been libpcap.
453     #
454     set(LIBRARY_NAME pcap)
455 endif()
456
457 option(INET6 "Enable IPv6" ON)
458 if(WIN32)
459     option(USE_STATIC_RT "Use static Runtime" ON)
460 endif(WIN32)
461 option(BUILD_SHARED_LIBS "Build shared libraries" ON)
462 set(dpdk_ROOT "" CACHE PATH "Path to directory with include and lib subdirectories for DPDK")
463 if(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")
466 endif(WIN32)
467
468 option(ENABLE_PROFILING "Enable code profiling" OFF)
469
470 # To pacify those who hate the protochain instruction
471 option(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 #
478 set(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 #
484 if(WIN32)
485     option(ENABLE_REMOTE "Enable remote capture" ON)
486 else()
487     option(ENABLE_REMOTE "Enable remote capture" OFF)
488 endif(WIN32)
489
490 if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
491     option(BUILD_WITH_LIBNL "Build with libnl" ON)
492 endif()
493
494 #
495 # Additional capture modules.
496 #
497 if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
498     option(DISABLE_LINUX_USBMON "Disable Linux usbmon USB sniffing support" OFF)
499 endif()
500 option(DISABLE_BLUETOOTH "Disable Bluetooth sniffing support" OFF)
501 option(DISABLE_NETMAP "Disable netmap support" OFF)
502 option(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 #
509 if(APPLE)
510     option(DISABLE_DBUS "Disable D-Bus sniffing support" ON)
511 else(APPLE)
512     option(DISABLE_DBUS "Disable D-Bus sniffing support" OFF)
513 endif(APPLE)
514 option(DISABLE_RDMA "Disable RDMA sniffing support" OFF)
515
516 option(DISABLE_DAG "Disable Endace DAG card support" OFF)
517
518 option(DISABLE_SEPTEL "Disable Septel card support" OFF)
519 set(SEPTEL_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../septel" CACHE PATH "Path to directory with include and lib subdirectories for Septel API")
520
521 option(DISABLE_SNF "Disable Myricom SNF support" OFF)
522
523 option(DISABLE_TC "Disable Riverbed TurboCap support" OFF)
524
525 #
526 # Debugging options.
527 #
528 option(BDEBUG "Build optimizer debugging code" OFF)
529 option(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
539 file(STRINGS ${pcap_SOURCE_DIR}/VERSION
540     PACKAGE_VERSION
541     LIMIT_COUNT 1 # Read only the first line
542 )
543
544 # Get "just" MAJOR
545 string(REGEX MATCH "^([0-9]+)" PACKAGE_VERSION_MAJOR "${PACKAGE_VERSION}")
546
547 # Get MAJOR, MINOR & PATCH
548 string(REGEX MATCH "^([0-9]+.)?([0-9]+.)?([0-9]+)" PACKAGE_VERSION_NOSUFFIX "${PACKAGE_VERSION}")
549
550 if(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)
557 endif(WIN32)
558
559 set(PACKAGE_NAME "${LIBRARY_NAME}")
560 set(PACKAGE_STRING "${LIBRARY_NAME} ${PACKAGE_VERSION}")
561
562 ######################################
563 # Project settings
564 ######################################
565
566 add_definitions(-DHAVE_CONFIG_H)
567
568 include_directories(
569     ${CMAKE_CURRENT_BINARY_DIR}
570     ${pcap_SOURCE_DIR}
571 )
572
573 include(CheckFunctionExists)
574 include(CMakePushCheckState)
575 include(CheckSymbolExists)
576
577 if(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
606 endif(WIN32)
607
608 if(MSVC)
609     add_definitions(-D__STDC__)
610     add_definitions(-D_CRT_SECURE_NO_WARNINGS)
611 endif(MSVC)
612
613 if(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()
626 else (USE_STATIC_RT)
627     message(STATUS "Use DYNAMIC runtime")
628 endif(USE_STATIC_RT)
629
630 ###################################################################
631 #   Detect available platform features
632 ###################################################################
633
634 include(CheckIncludeFile)
635 include(CheckIncludeFiles)
636 include(CheckStructHasMember)
637 include(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 #
647 check_include_file(inttypes.h HAVE_INTTYPES_H)
648 check_include_file(stdint.h HAVE_STDINT_H)
649 check_include_file(unistd.h HAVE_UNISTD_H)
650 if(NOT HAVE_UNISTD_H)
651     add_definitions(-DYY_NO_UNISTD_H)
652 endif(NOT HAVE_UNISTD_H)
653 check_include_file(bitypes.h HAVE_SYS_BITYPES_H)
654 if(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)
661 endif(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 #
679 check_c_source_compiles(
680 "int
681 main(void)
682 {
683         int i = 17;
684         return __atomic_load_n(&i, __ATOMIC_RELAXED);
685 }
686 "
687             HAVE___ATOMIC_LOAD_N)
688 check_c_source_compiles(
689 "int
690 main(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 #
702 check_function_exists(strerror HAVE_STRERROR)
703 check_function_exists(strerror_r HAVE_STRERROR_R)
704 if(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 */
714 extern char *strerror_r(int, char *, size_t);
715
716 int
717 main(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)
726 else(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)
731 endif(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 #
739 check_symbol_exists(vsnprintf "stdio.h" HAVE_VSNPRINTF)
740 if(NOT HAVE_VSNPRINTF)
741     message(FATAL_ERROR "vsnprintf() is required but wasn't found")
742 endif(NOT HAVE_VSNPRINTF)
743 check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF)
744 if(NOT HAVE_SNPRINTF)
745     message(FATAL_ERROR "snprintf() is required but wasn't found")
746 endif()
747
748 check_function_exists(strlcpy HAVE_STRLCPY)
749 check_function_exists(strlcat HAVE_STRLCAT)
750 check_function_exists(asprintf HAVE_ASPRINTF)
751 check_function_exists(vasprintf HAVE_VASPRINTF)
752 check_function_exists(strtok_r HAVE_STRTOK_R)
753 if(NOT WIN32)
754     check_function_exists(vsyslog HAVE_VSYSLOG)
755 endif()
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 #
782 set(PCAP_LINK_LIBRARIES "")
783 set(LIBS "")
784 set(LIBS_STATIC "")
785 set(REQUIRES_PRIVATE "")
786 set(LIBS_PRIVATE "")
787 include(CheckLibraryExists)
788 if(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)
801 else(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)
882 endif(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 #
897 cmake_push_check_state()
898 set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LINK_LIBRARIES})
899 check_symbol_exists(getnetbyname_r netdb.h NETDB_H_DECLARES_GETNETBYNAME_R)
900 if(NETDB_H_DECLARES_GETNETBYNAME_R)
901     check_c_source_compiles(
902 "#include <netdb.h>
903
904 int
905 main(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
920 int
921 main(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
934 int
935 main(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)
946 endif(NETDB_H_DECLARES_GETNETBYNAME_R)
947 cmake_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 #
962 cmake_push_check_state()
963 set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LINK_LIBRARIES})
964 check_symbol_exists(getprotobyname_r netdb.h NETDB_H_DECLARES_GETPROTOBYNAME_R)
965 if(NETDB_H_DECLARES_GETPROTOBYNAME_R)
966     check_c_source_compiles(
967 "#include <netdb.h>
968
969 int
970 main(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
984 int
985 main(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
998 int
999 main(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)
1010 endif(NETDB_H_DECLARES_GETPROTOBYNAME_R)
1011 cmake_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 #
1020 cmake_push_check_state()
1021 if(WIN32)
1022     set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h)
1023 else(WIN32)
1024     set(CMAKE_EXTRA_INCLUDE_FILES unistd.h sys/socket.h)
1025 endif(WIN32)
1026 check_type_size("struct sockaddr_storage" STRUCT_SOCKADDR_STORAGE)
1027 check_type_size("socklen_t" SOCKLEN_T)
1028 cmake_pop_check_state()
1029
1030 #
1031 # Structure fields.
1032 #
1033 if(WIN32)
1034     check_struct_has_member("struct sockaddr" sa_len winsock2.h HAVE_STRUCT_SOCKADDR_SA_LEN)
1035 else(WIN32)
1036     check_struct_has_member("struct sockaddr" sa_len sys/socket.h HAVE_STRUCT_SOCKADDR_SA_LEN)
1037 endif(WIN32)
1038
1039 #
1040 # Do we have ffs(), and is it declared in <strings.h>?
1041 #
1042 check_function_exists(ffs HAVE_FFS)
1043 if(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)
1051 endif()
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 #
1069 cmake_push_check_state()
1070 set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LINK_LIBRARIES})
1071 check_function_exists(ether_hostton HAVE_ETHER_HOSTTON)
1072 if(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()
1179 endif()
1180 cmake_pop_check_state()
1181
1182 #
1183 # Large file support on UN*X, a/k/a LFS.
1184 #
1185 if(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()
1206 endif()
1207
1208 if(INET6)
1209     message(STATUS "Support IPv6")
1210 endif(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 #
1219 if(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)
1229 endif(NOT WIN32)
1230
1231 if(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()
1236 endif()
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 #
1275 set(SANITIZER_FLAGS "")
1276 foreach(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)
1318 endforeach()
1319
1320 if(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")
1323 endif()
1324
1325 #
1326 # OpenSSL/libressl.
1327 #
1328 find_package(OpenSSL)
1329 if(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)
1406 endif(OPENSSL_FOUND)
1407
1408 #
1409 # Additional linker flags.
1410 #
1411 set(LINKER_FLAGS "${SANITIZER_FLAGS}")
1412 if(ENABLE_PROFILING)
1413     if(MSVC)
1414         set(LINKER_FLAGS " /PROFILE")
1415     else()
1416         set(LINKER_FLAGS " -pg")
1417     endif()
1418 endif()
1419
1420 ######################################
1421 # Input files
1422 ######################################
1423
1424 set(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
1442 if(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)
1452 else()
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)
1465 endif(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 #
1471 if(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()
1497 else()
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()
1618 endif(WIN32)
1619 message(STATUS "Packet capture mechanism type: ${PCAP_TYPE}")
1620
1621 find_package(PkgConfig QUIET)
1622
1623 #
1624 # Do capture-mechanism-dependent tests.
1625 #
1626 if(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()
1636 else(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()
1769 endif(WIN32)
1770
1771 if(NOT DEFINED PCAP_SRC)
1772 set(PCAP_SRC pcap-${PCAP_TYPE}.c)
1773 endif()
1774
1775 set(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 #
1782 if(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()
1873 endif()
1874
1875 # Check for hardware timestamp support.
1876 if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
1877     check_include_file(linux/net_tstamp.h HAVE_LINUX_NET_TSTAMP_H)
1878 endif()
1879
1880 #
1881 # Check for additional native sniffing capabilities.
1882 #
1883
1884 #
1885 # Various Linux-specific mechanisms.
1886 #
1887 if(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
1941 int
1942 main(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)
1951 endif()
1952
1953 # Check for netmap sniffing support.
1954 if(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
1965 int
1966 main(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)
1975 endif()
1976
1977 # Check for DPDK sniffing support
1978 if(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,
2017 make sure that pkg-config is installed, that DPDK 18.02.2 or later is
2018 installed, and that DPDK provides a .pc file.")
2019     endif()
2020 endif()
2021
2022 # Check for Bluetooth sniffing support
2023 if(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
2042 int
2043 main(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()
2060 else()
2061     unset(PCAP_SUPPORT_BT_MONITOR CACHE)
2062 endif()
2063
2064 # Check for D-Bus sniffing support
2065 if(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)
2110 endif(NOT DISABLE_DBUS)
2111
2112 # Check for RDMA sniffing support
2113 if(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)
2175 endif(NOT DISABLE_RDMA)
2176
2177 #
2178 # Check for sniffing capabilities using third-party APIs.
2179 #
2180
2181 # Check for Endace DAG card support.
2182 if(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()
2227 endif()
2228
2229 # Check for Septel card support.
2230 set(PROJECT_EXTERNAL_OBJECT_LIST "")
2231 if(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()
2249 endif()
2250
2251 # Check for Myricom SNF support.
2252 if(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()
2273 endif()
2274
2275 # Check for Riverbed AirPcap support.
2276 if(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()
2294 endif()
2295
2296 # Check for Riverbed TurboCap support.
2297 if(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()
2315 endif()
2316
2317 #
2318 # Remote capture support.
2319 #
2320
2321 if(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)
2340 endif(ENABLE_REMOTE)
2341
2342 ###################################################################
2343 #   Warning options
2344 ###################################################################
2345
2346 #
2347 # Check and add warning options if we have a .devel file.
2348 #
2349 if(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()
2447 endif()
2448
2449 #
2450 # Suppress some warnings we get with MSVC even without /Wall.
2451 #
2452 if(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)
2461 endif()
2462
2463 file(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 #
2481 if(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()
2495 endif(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 #
2503 if(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})")
2508 endif()
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 #
2519 find_program(LEX_EXECUTABLE NAMES flex win_flex lex)
2520 if(LEX_EXECUTABLE STREQUAL "LEX_EXECUTABLE-NOTFOUND")
2521     message(FATAL_ERROR "Neither flex nor win_flex nor lex was found.")
2522 endif()
2523 message(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 #
2529 if(WIN32)
2530     set(NULL_DEVICE "NUL:")
2531 else()
2532     set(NULL_DEVICE "/dev/null")
2533 endif()
2534 execute_process(COMMAND ${LEX_EXECUTABLE} -P pcap_ --header-file=${NULL_DEVICE} --nounput -t ${pcap_SOURCE_DIR}/scanner.l
2535     OUTPUT_QUIET RESULT_VARIABLE EXIT_STATUS)
2536 if(NOT EXIT_STATUS EQUAL 0)
2537     message(FATAL_ERROR "${LEX_EXECUTABLE} is insufficient to compile libpcap.
2538 libpcap requires Flex 2.5.31 or later, or a compatible version of lex.
2539 If a suitable version of Lex/Flex is available as a non-standard command
2540 and/or not in the PATH, you can specify it using the LEX environment
2541 variable. That said, on some systems the error can mean that Flex/Lex is
2542 actually acceptable, but m4 is not. Likewise, if a suitable version of
2543 m4 (such as GNU M4) is available but has not been detected, you can
2544 specify it using the M4 environment variable.")
2545 endif()
2546
2547 add_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 #
2560 set_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 #
2573 find_program(YACC_EXECUTABLE NAMES bison win_bison byacc yacc)
2574 if(YACC_EXECUTABLE STREQUAL "YACC_EXECUTABLE-NOTFOUND")
2575     message(FATAL_ERROR "Neither bison nor win_bison nor byacc nor yacc was found.")
2576 endif()
2577
2578 if(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.
2595 libpcap requires Bison, a newer version of Berkeley YACC with support
2596 for 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")
2603 else()
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()
2615 endif()
2616
2617 message(STATUS "Parser generator: ${YACC_EXECUTABLE}")
2618
2619 #
2620 # Create custom command for the scanner.
2621 #
2622 add_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 #
2633 set_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 #
2650 set(MAN_DEVICES 4)
2651 set(MAN_FILE_FORMATS 5)
2652 set(MAN_MISC_INFO 7)
2653 set(MAN_ADMIN_COMMANDS 8)
2654 if(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()
2667 elseif(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)
2694 elseif(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)
2702 elseif(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)
2712 elseif(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()
2737 elseif(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)
2742 endif()
2743
2744 source_group("Source Files" FILES ${PROJECT_SOURCE_LIST_C})
2745 source_group("Header Files" FILES ${PROJECT_SOURCE_LIST_H})
2746
2747 if(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)
2752 endif(WIN32)
2753
2754 #
2755 # Add subdirectories after we've set various variables, so they pick up
2756 # pick up those variables.
2757 #
2758 if(ENABLE_REMOTE)
2759     add_subdirectory(rpcapd)
2760 endif(ENABLE_REMOTE)
2761 add_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 #
2774 add_custom_target(SerializeTarget
2775     DEPENDS
2776     ${CMAKE_CURRENT_BINARY_DIR}/grammar.c
2777     ${CMAKE_CURRENT_BINARY_DIR}/scanner.c
2778 )
2779
2780 set_source_files_properties(${PROJECT_EXTERNAL_OBJECT_LIST} PROPERTIES
2781     EXTERNAL_OBJECT TRUE)
2782
2783 if(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()
2807 endif(BUILD_SHARED_LIBS)
2808
2809 add_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 )
2815 add_dependencies(${LIBRARY_NAME}_static SerializeTarget)
2816 set_target_properties(${LIBRARY_NAME}_static PROPERTIES
2817     COMPILE_DEFINITIONS BUILDING_PCAP)
2818
2819 if(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()
2853 else(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     )
2870 endif(WIN32)
2871
2872 if(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})
2877 endif(BUILD_SHARED_LIBS)
2878
2879 if(NOT C_ADDITIONAL_FLAGS STREQUAL "")
2880     set_target_properties(${LIBRARY_NAME}_static PROPERTIES COMPILE_FLAGS ${C_ADDITIONAL_FLAGS})
2881 endif()
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 #
2888 if(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
2969 main(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>
3035 int
3036 main(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}")
3057 endif()
3058
3059 ######################################
3060 # Write out the config.h file
3061 ######################################
3062
3063 configure_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
3069 configure_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 #
3080 include(GNUInstallDirs)
3081
3082 set(LIBRARY_NAME_STATIC ${LIBRARY_NAME}_static)
3083
3084 function(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})")
3110 endfunction(install_manpage_symlink)
3111
3112 set(MAN1_NOEXPAND pcap-config.1)
3113 set(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 )
3127 set(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 )
3175 set(MANFILE_EXPAND
3176     pcap-savefile.manfile.in
3177 )
3178 set(MANMISC_EXPAND
3179     pcap-filter.manmisc.in
3180     pcap-linktype.manmisc.in
3181     pcap-tstamp.manmisc.in
3182 )
3183
3184 if(BUILD_SHARED_LIBS)
3185     set(LIBRARIES_TO_INSTALL "${LIBRARY_NAME}" "${LIBRARY_NAME_STATIC}")
3186 else(BUILD_SHARED_LIBS)
3187     set(LIBRARIES_TO_INSTALL "${LIBRARY_NAME_STATIC}")
3188 endif(BUILD_SHARED_LIBS)
3189
3190 if(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)
3232 else(WIN32 OR CYGWIN OR MSYS)
3233     install(TARGETS ${LIBRARIES_TO_INSTALL} DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR})
3234 endif(WIN32 OR CYGWIN OR MSYS)
3235
3236 install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/pcap/ DESTINATION include/pcap)
3237 install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pcap.h DESTINATION include)
3238 install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pcap-bpf.h DESTINATION include)
3239 install(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.
3243 if(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))
3380 endif(NOT MSVC)
3381
3382 # uninstall target
3383 configure_file(
3384     "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
3385     "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
3386     IMMEDIATE @ONLY)
3387
3388 add_custom_target(uninstall
3389     COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)