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