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