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