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