if(WIN32) # # We need 3.12 or later, so that we can set policy CMP0074; see below. cmake_minimum_required(VERSION 3.12) else(WIN32) cmake_minimum_required(VERSION 3.12) endif(WIN32) # # Squelch noise about quoted strings in if() statements. WE KNOW WHAT WE'RE # DOING, WE'RE DOING EVERYTHING THE WAY THAT NEWER VERSIONS OF CMAKE EXPECT BY # DEFAULT, DON'T WASTE OUR TIME WITH NOISE. # if(POLICY CMP0054) cmake_policy(SET CMP0054 NEW) endif() # # We want find_file() and find_library() to honor {packagename}_ROOT, as that # appears to be the only way, with the Visual Studio 2019 IDE and its CMake # support, to tell CMake where to look for the Npcap or WinPcap SDK. # if(POLICY CMP0074) cmake_policy(SET CMP0074 NEW) endif() project(pcap) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake/Modules) include(CheckCCompilerFlag) # # For checking if a compiler flag works and adding it if it does. # macro(check_and_add_compiler_option _option) message(STATUS "Checking C compiler flag ${_option}") string(REPLACE "=" "-" _temp_option_variable ${_option}) string(REGEX REPLACE "^-" "" _option_variable ${_temp_option_variable}) check_c_compiler_flag("${_option}" ${_option_variable}) if(${${_option_variable}}) set(C_ADDITIONAL_FLAGS "${C_ADDITIONAL_FLAGS} ${_option}") endif() endmacro() # # If we're building with Visual Studio, we require Visual Studio 2015, in order # to get sufficient C99 compatibility. Check for that. # # If not, try the appropriate flag for the compiler to enable C99 features. # set(C_ADDITIONAL_FLAGS "") if(MSVC) if(MSVC_VERSION LESS 1900) message(FATAL_ERROR "Visual Studio 2015 or later is required") endif() # # Treat source files as being in UTF-8 with MSVC if it's not using the Clang # front end. We assume that UTF-8 source is OK with other compilers and with # MSVC if it's using the Clang front end. # if(NOT ${CMAKE_C_COMPILER} MATCHES "clang*") set(C_ADDITIONAL_FLAGS "${C_ADDITIONAL_FLAGS} /utf-8") endif(NOT ${CMAKE_C_COMPILER} MATCHES "clang*") else(MSVC) # # For checking if a compiler flag works, failing if it doesn't, and adding it # otherwise. # macro(require_and_add_compiler_option _option) message(STATUS "Checking C compiler flag ${_option}") string(REPLACE "=" "-" _temp_option_variable ${_option}) string(REGEX REPLACE "^-" "" _option_variable ${_temp_option_variable}) check_c_compiler_flag("${_option}" ${_option_variable}) if(${${_option_variable}}) set(C_ADDITIONAL_FLAGS "${C_ADDITIONAL_FLAGS} ${_option}") else() message( FATAL_ERROR "C99 support is required, but the compiler doesn't support a compiler flag to enable it" ) endif() endmacro() # # Try to enable as many C99 features as we can. At minimum, we want # C++/C99-style // comments. # # Newer versions of compilers might default to supporting C99, but older # versions may require a special flag. # # Prior to CMake 3.1, setting CMAKE_C_STANDARD will not have any effect, so, # unless and until we require CMake 3.1 or later, we have to do it ourselves # on pre-3.1 CMake, so we just do it ourselves on all versions of CMake. # # Note: with CMake 3.1 through 3.5, the only compilers for which CMake handles # CMAKE_C_STANDARD are GCC and Clang. 3.6 adds support only for Intel C; 3.9 # adds support for PGI C, Sun C, and IBM XL C, and 3.10 adds support for Cray # C and IAR C, but no version of CMake has support for HP C. Therefore, even # if we use CMAKE_C_STANDARD with compilers for which CMake supports it, we # may still have to do it ourselves on other compilers. # # See the CMake documentation for the CMAKE__COMPILER_ID variables for a # list of compiler IDs. # # XXX - this just tests whether the option works, fails if it doesn't, and # adds it if it does. We don't test whether it's necessary in order to get # the C99 features that we use, or whether, if it's used, it enables all the # features that we require. # if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") require_and_add_compiler_option("-std=gnu99") elseif(CMAKE_C_COMPILER_ID MATCHES "XL") # # We want support for extensions picked up for GNU C compatibility, so we # use -qlanglvl=extc99. # require_and_add_compiler_option("-qlanglvl=extc99") elseif(CMAKE_C_COMPILER_ID MATCHES "HP") require_and_add_compiler_option("-AC99") elseif(CMAKE_C_COMPILER_ID MATCHES "Sun") require_and_add_compiler_option("-xc99") elseif(CMAKE_C_COMPILER_ID MATCHES "Intel") require_and_add_compiler_option("-c99") endif() endif(MSVC) # # If we're building with MinGW, we need to specify _WIN32_WINNT as 0x0600 ("NT # 6.0", a/k/a Vista/Windows Server 2008) in order to get the full IPv6 API, # including inet_ntop(). # # NOTE: pcap does *NOT* work with msvcrt.dll; it must link with a newer version # of the C library, i.e. Visual Studio 2015 or later, as it depends on C99 # features introduced in VS 2015. # if(MINGW) add_definitions(-D_WIN32_WINNT=0x0600) endif(MINGW) # # Build all runtimes in the top-level binary directory; that way, on Windows, # the executables will be in the same directory as the DLLs, so the system will # find pcap.dll when any of the executables are run. # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/run) # ############################################################################## # Parameters # ############################################################################## if(WIN32) # # On Windows, allow the library name to be overridden, for the benefit of # projects that combine libpcap with their own kernel-mode code to support # capturing. # set(LIBRARY_NAME pcap CACHE STRING "Library name") else() # # On UN*X, it's always been libpcap. # set(LIBRARY_NAME pcap) endif() option(INET6 "Enable IPv6" ON) if(WIN32) option(USE_STATIC_RT "Use static Runtime" ON) endif(WIN32) option(BUILD_SHARED_LIBS "Build shared libraries" ON) if(WIN32) set(Packet_ROOT "" CACHE PATH "Path to directory with include and lib subdirectories for packet.dll") set(AirPcap_ROOT "" CACHE PATH "Path to directory with include and lib subdirectories for airpcap.dll") endif(WIN32) option(ENABLE_PROFILING "Enable code profiling" OFF) # To pacify those who hate the protochain instruction option(NO_PROTOCHAIN "Disable protochain instruction" OFF) # # Start out with the capture mechanism type unspecified; the user can explicitly # specify it and, if they don't, we'll pick an appropriate one. # set(PCAP_TYPE "" CACHE STRING "Packet capture type") # # Default to having remote capture support on Windows and, for now, to not # having it on UN*X. # if(WIN32) option(ENABLE_REMOTE "Enable remote capture" ON) else() option(ENABLE_REMOTE "Enable remote capture" OFF) endif(WIN32) if(CMAKE_SYSTEM_NAME STREQUAL "Linux") option(BUILD_WITH_LIBNL "Build with libnl" ON) endif() # # Additional capture modules. # if(CMAKE_SYSTEM_NAME STREQUAL "Linux") option(DISABLE_LINUX_USBMON "Disable Linux usbmon USB sniffing support" OFF) endif() option(DISABLE_BLUETOOTH "Disable Bluetooth sniffing support" OFF) option(DISABLE_NETMAP "Disable netmap support" OFF) option(DISABLE_DPDK "Disable DPDK support" ON) # # We don't support D-Bus sniffing on macOS; see # # https://bugs.freedesktop.org/show_bug.cgi?id=74029 # if(APPLE) option(DISABLE_DBUS "Disable D-Bus sniffing support" ON) else(APPLE) option(DISABLE_DBUS "Disable D-Bus sniffing support" OFF) endif(APPLE) option(DISABLE_RDMA "Disable RDMA sniffing support" ON) option(DISABLE_DAG "Disable Endace DAG card support" OFF) option(DISABLE_SEPTEL "Disable Septel card support" OFF) set(SEPTEL_ROOT "${PROJECT_SOURCE_DIR}/../septel" CACHE PATH "Path to directory with include and lib subdirectories for Septel API" ) option(DISABLE_SNF "Disable Myricom SNF support" OFF) option(DISABLE_TC "Disable Riverbed TurboCap support" OFF) # # Debugging options. # option(BDEBUG "Build optimizer debugging code" OFF) option(YYDEBUG "Build parser debugging code" OFF) # ############################################################################## # Versioning # ############################################################################## # Get, parse, format and set pcap's version string from [pcap_root]/VERSION for # later use. # Get MAJOR, MINOR, PATCH & SUFFIX file(STRINGS ${pcap_SOURCE_DIR}/VERSION PACKAGE_VERSION LIMIT_COUNT 1 # Read only the first line ) # Get "just" MAJOR string(REGEX MATCH "^([0-9]+)" PACKAGE_VERSION_MAJOR "${PACKAGE_VERSION}") # Get MAJOR, MINOR & PATCH string(REGEX MATCH "^([0-9]+.)?([0-9]+.)?([0-9]+)" PACKAGE_VERSION_NOSUFFIX "${PACKAGE_VERSION}") if(WIN32) # Convert PCAP_VERSION_NOSUFFIX to Windows preferred version format string(REPLACE "." "," PACKAGE_VERSION_PREDLL ${PACKAGE_VERSION_NOSUFFIX}) # Append NANO (used for Windows internal versioning) to PCAP_VERSION_PREDLL 0 # means unused. set(PACKAGE_VERSION_DLL ${PACKAGE_VERSION_PREDLL},0) endif(WIN32) set(PACKAGE_NAME "${LIBRARY_NAME}") set(PACKAGE_STRING "${LIBRARY_NAME} ${PACKAGE_VERSION}") # ############################################################################## # Project settings # ############################################################################## add_definitions(-DHAVE_CONFIG_H) include_directories(${CMAKE_CURRENT_BINARY_DIR} ${pcap_SOURCE_DIR} ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/pcap) include(CheckFunctionExists) include(CMakePushCheckState) include(CheckSymbolExists) if(WIN32) if(IS_DIRECTORY ${CMAKE_HOME_DIRECTORY}/../../Common) include_directories(${CMAKE_HOME_DIRECTORY}/../../Common) endif(IS_DIRECTORY ${CMAKE_HOME_DIRECTORY}/../../Common) find_package(Packet) if(PACKET_FOUND) set(HAVE_PACKET32 TRUE) include_directories(${PACKET_INCLUDE_DIRS}) # # Check whether we have the NPcap PacketIsLoopbackAdapter() function. # cmake_push_check_state() set(CMAKE_REQUIRED_LIBRARIES ${PACKET_LIBRARIES}) check_function_exists(PacketIsLoopbackAdapter HAVE_PACKET_IS_LOOPBACK_ADAPTER) cmake_pop_check_state() endif(PACKET_FOUND) message(STATUS "checking for Npcap's version.h") check_symbol_exists(WINPCAP_PRODUCT_NAME "../../version.h" HAVE_VERSION_H) if(HAVE_VERSION_H) message(STATUS "HAVE version.h") else(HAVE_VERSION_H) message(STATUS "MISSING version.h") endif(HAVE_VERSION_H) endif(WIN32) if(MSVC) add_definitions(-D__STDC__) add_definitions(-D_CRT_SECURE_NO_WARNINGS) endif(MSVC) if(USE_STATIC_RT) message(STATUS "Use STATIC runtime") if(MSVC) foreach( RT_FLAG CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) string(REGEX REPLACE "/MD" "/MT" ${RT_FLAG} "${${RT_FLAG}}") endforeach(RT_FLAG) elseif(MINGW) set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libgcc") endif() else(USE_STATIC_RT) message(STATUS "Use DYNAMIC runtime") endif(USE_STATIC_RT) # ############################################################################## # Detect available platform features # ############################################################################## include(CheckIncludeFile) include(CheckIncludeFiles) include(CheckStructHasMember) include(CheckTypeSize) # # Tests are a bit expensive with Visual Studio on Windows, so, on Windows, we # skip tests for UN*X-only headers and functions. # # # Header files. # check_include_file(inttypes.h HAVE_INTTYPES_H) check_include_file(stdint.h HAVE_STDINT_H) check_include_file(unistd.h HAVE_UNISTD_H) if(NOT HAVE_UNISTD_H) add_definitions(-DYY_NO_UNISTD_H) endif(NOT HAVE_UNISTD_H) check_include_file(bitypes.h HAVE_SYS_BITYPES_H) if(NOT WIN32) check_include_file(sys/ioccom.h HAVE_SYS_IOCCOM_H) check_include_file(sys/sockio.h HAVE_SYS_SOCKIO_H) check_include_file(sys/select.h HAVE_SYS_SELECT_H) check_include_file(netpacket/packet.h HAVE_NETPACKET_PACKET_H) check_include_files("sys/types.h;sys/socket.h;net/if.h;net/pfvar.h" HAVE_NET_PFVAR_H) if(HAVE_NET_PFVAR_H) # # Check for various PF actions. # check_c_source_compiles( "#include #include #include #include int main(void) { return PF_NAT+PF_NONAT+PF_BINAT+PF_NOBINAT+PF_RDR+PF_NORDR; } " HAVE_PF_NAT_THROUGH_PF_NORDR) endif(HAVE_NET_PFVAR_H) check_include_file(netinet/if_ether.h HAVE_NETINET_IF_ETHER_H) endif(NOT WIN32) # # Functions. # check_function_exists(strerror HAVE_STRERROR) check_function_exists(strerror_r HAVE_STRERROR_R) if(HAVE_STRERROR_R) # # We have strerror_r; if we define _GNU_SOURCE, is it a POSIX-compliant # strerror_r() or a GNU strerror_r()? # check_c_source_compiles( "#define _GNU_SOURCE #include /* Define it GNU-style; that will cause an error if it's not GNU-style */ extern char *strerror_r(int, char *, size_t); int main(void) { return 0; } " HAVE_GNU_STRERROR_R) if(NOT HAVE_GNU_STRERROR_R) set(HAVE_POSIX_STRERROR_R YES) endif(NOT HAVE_GNU_STRERROR_R) else(HAVE_STRERROR_R) # # We don't have strerror_r; do we have _wcserror_s? # check_function_exists(_wcserror_s HAVE__WCSERROR_S) endif(HAVE_STRERROR_R) # # Make sure we have vsnprintf() and snprintf(); we require them. We use # check_symbol_exists(), as they aren't necessarily external functions - in # Visual Studio, for example, they're inline functions calling a common external # function. # check_symbol_exists(vsnprintf "stdio.h" HAVE_VSNPRINTF) if(NOT HAVE_VSNPRINTF) message(FATAL_ERROR "vsnprintf() is required but wasn't found") endif(NOT HAVE_VSNPRINTF) check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF) if(NOT HAVE_SNPRINTF) message(FATAL_ERROR "snprintf() is required but wasn't found") endif() check_function_exists(strlcpy HAVE_STRLCPY) check_function_exists(strlcat HAVE_STRLCAT) check_function_exists(asprintf HAVE_ASPRINTF) check_function_exists(vasprintf HAVE_VASPRINTF) check_function_exists(strtok_r HAVE_STRTOK_R) if(NOT WIN32) check_function_exists(vsyslog HAVE_VSYSLOG) endif() # # These tests are for network applications that need socket functions and # getaddrinfo()/getnameinfo()-ish functions. We now require getaddrinfo() and # getnameinfo(). On UN*X systems, we also prefer versions of recvmsg() that # conform to the Single UNIX Specification, so that we can check whether a # datagram received with recvmsg() was truncated when received due to the buffer # being too small. # # On Windows, getaddrinfo() is in the ws2_32 library. # On most UN*X systems, they're available in the system library. # # Under Solaris, we need to link with libsocket and libnsl to get getaddrinfo() # and getnameinfo() and, if we have libxnet, we need to link with libxnet before # libsocket to get a version of recvmsg() that conforms to the Single UNIX # Specification. # # We use getaddrinfo() because we want a portable thread-safe way of getting # information for a host name or port; there exist _r versions of # gethostbyname() and getservbyname() on some platforms, but not on all # platforms. # # NOTE: if you hand check_library_exists as its last argument a variable that's # been set, it skips the test, so we need different variables. # set(PCAP_LINK_LIBRARIES "") include(CheckLibraryExists) if(WIN32) # # We need winsock2.h and ws2tcpip.h. # cmake_push_check_state() set(CMAKE_REQUIRED_LIBRARIES ws2_32) check_symbol_exists(getaddrinfo "winsock2.h;ws2tcpip.h" LIBWS2_32_HAS_GETADDRINFO) cmake_pop_check_state() if(LIBWS2_32_HAS_GETADDRINFO) set(PCAP_LINK_LIBRARIES ws2_32 ${PCAP_LINK_LIBRARIES}) else(LIBWS2_32_HAS_GETADDRINFO) message(FATAL_ERROR "getaddrinfo is required, but wasn't found") endif(LIBWS2_32_HAS_GETADDRINFO) else(WIN32) # # UN*X. First try the system libraries, then try the libraries for Solaris # and possibly other systems that picked up the System V library split. # check_function_exists(getaddrinfo STDLIBS_HAVE_GETADDRINFO) if(NOT STDLIBS_HAVE_GETADDRINFO) # # Not found in the standard system libraries. Try libsocket, which requires # libnsl. # cmake_push_check_state() set(CMAKE_REQUIRED_LIBRARIES nsl) check_library_exists(socket getaddrinfo "" LIBSOCKET_HAS_GETADDRINFO) cmake_pop_check_state() if(LIBSOCKET_HAS_GETADDRINFO) # # OK, we found it in libsocket. # set(PCAP_LINK_LIBRARIES socket nsl ${PCAP_LINK_LIBRARIES}) else(LIBSOCKET_HAS_GETADDRINFO) check_library_exists(network getaddrinfo "" LIBNETWORK_HAS_GETADDRINFO) if(LIBNETWORK_HAS_GETADDRINFO) # # OK, we found it in libnetwork (Haiku). # set(PCAP_LINK_LIBRARIES network ${PCAP_LINK_LIBRARIES}) else(LIBNETWORK_HAS_GETADDRINFO) # # We didn't find it. # message(FATAL_ERROR "getaddrinfo is required, but wasn't found") endif(LIBNETWORK_HAS_GETADDRINFO) endif(LIBSOCKET_HAS_GETADDRINFO) # # OK, do we have recvmsg() in libxnet? We also link with libsocket and # libnsl. # cmake_push_check_state() set(CMAKE_REQUIRED_LIBRARIES socket nsl) check_library_exists(xnet recvmsg "" LIBXNET_HAS_RECVMSG) cmake_pop_check_state() if(LIBXNET_HAS_RECVMSG) # # Yes - link with it as well. # set(PCAP_LINK_LIBRARIES xnet ${PCAP_LINK_LIBRARIES}) endif(LIBXNET_HAS_RECVMSG) endif(NOT STDLIBS_HAVE_GETADDRINFO) # DLPI needs putmsg under HPUX so test for -lstr while we're at it check_function_exists(putmsg STDLIBS_HAVE_PUTMSG) if(NOT STDLIBS_HAVE_PUTMSG) check_library_exists(str putmsg "" LIBSTR_HAS_PUTMSG) if(LIBSTR_HAS_PUTMSG) set(PCAP_LINK_LIBRARIES str ${PCAP_LINK_LIBRARIES}) endif(LIBSTR_HAS_PUTMSG) endif(NOT STDLIBS_HAVE_PUTMSG) endif(WIN32) # # Check for reentrant versions of getnetbyname_r(), as provided by Linux # (glibc), Solaris/IRIX, and AIX (with three different APIs!). If we don't find # one, we just use getnetbyname(), which uses thread-specific data on many # platforms, but doesn't use it on NetBSD or OpenBSD, and may not use it on # older versions of other platforms. # # Only do the check if we have a declaration of getnetbyname_r(); without it, we # can't check which API it has. (We assume that if there's a declaration, it # has a prototype, so that the API can be checked.) # cmake_push_check_state() set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LINK_LIBRARIES}) check_symbol_exists(getnetbyname_r netdb.h NETDB_H_DECLARES_GETNETBYNAME_R) if(NETDB_H_DECLARES_GETNETBYNAME_R) check_c_source_compiles( "#include int main(void) { struct netent netent_buf; char buf[1024]; struct netent *resultp; int h_errnoval; return getnetbyname_r((const char *)0, &netent_buf, buf, sizeof buf, &resultp, &h_errnoval); } " HAVE_LINUX_GETNETBYNAME_R) if(NOT HAVE_LINUX_GETNETBYNAME_R) check_c_source_compiles( "#include int main(void) { struct netent netent_buf; char buf[1024]; return getnetbyname_r((const char *)0, &netent_buf, buf, (int)sizeof buf) != NULL; } " HAVE_SOLARIS_IRIX_GETNETBYNAME_R) if(NOT HAVE_SOLARIS_IRIX_GETNETBYNAME_R) check_c_source_compiles( "#include int main(void) { struct netent netent_buf; struct netent_data net_data; return getnetbyname_r((const char *)0, &netent_buf, &net_data); } " HAVE_AIX_GETNETBYNAME_R) endif(NOT HAVE_SOLARIS_IRIX_GETNETBYNAME_R) endif(NOT HAVE_LINUX_GETNETBYNAME_R) endif(NETDB_H_DECLARES_GETNETBYNAME_R) cmake_pop_check_state() # # Check for reentrant versions of getprotobyname_r(), as provided by Linux # (glibc), Solaris/IRIX, and AIX (with three different APIs!). If we don't find # one, we just use getprotobyname(), which uses thread-specific data on many # platforms, but doesn't use it on NetBSD or OpenBSD, and may not use it on # older versions of other platforms. # # Only do the check if we have a declaration of getprotobyname_r(); without it, # we can't check which API it has. (We assume that if there's a declaration, it # has a prototype, so that the API can be checked.) # cmake_push_check_state() set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LINK_LIBRARIES}) check_symbol_exists(getprotobyname_r netdb.h NETDB_H_DECLARES_GETPROTOBYNAME_R) if(NETDB_H_DECLARES_GETPROTOBYNAME_R) check_c_source_compiles( "#include int main(void) { struct protoent protoent_buf; char buf[1024]; struct protoent *resultp; return getprotobyname_r((const char *)0, &protoent_buf, buf, sizeof buf, &resultp); } " HAVE_LINUX_GETPROTOBYNAME_R) if(NOT HAVE_LINUX_GETPROTOBYNAME_R) check_c_source_compiles( "#include int main(void) { struct protoent protoent_buf; char buf[1024]; return getprotobyname_r((const char *)0, &protoent_buf, buf, (int)sizeof buf) != NULL; } " HAVE_SOLARIS_IRIX_GETPROTOBYNAME_R) if(NOT HAVE_SOLARIS_IRIX_GETPROTOBYNAME_R) check_c_source_compiles( "#include int main(void) { struct protoent protoent_buf; struct protoent_data proto_data; return getprotobyname_r((const char *)0, &protoent_buf, &proto_data); } " HAVE_AIX_GETPROTOBYNAME_R) endif(NOT HAVE_SOLARIS_IRIX_GETPROTOBYNAME_R) endif(NOT HAVE_LINUX_GETPROTOBYNAME_R) endif(NETDB_H_DECLARES_GETPROTOBYNAME_R) cmake_pop_check_state() # # Data types. # # XXX - there's no check_type() macro that's like check_type_size() except that # it only checks for the existence of the structure type, so we use # check_type_size() and ignore the size. # cmake_push_check_state() if(WIN32) set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h) else(WIN32) set(CMAKE_EXTRA_INCLUDE_FILES unistd.h sys/socket.h) endif(WIN32) check_type_size("struct sockaddr_storage" STRUCT_SOCKADDR_STORAGE) check_type_size("socklen_t" SOCKLEN_T) cmake_pop_check_state() # # Structure fields. # if(WIN32) check_struct_has_member("struct sockaddr" sa_len winsock2.h HAVE_STRUCT_SOCKADDR_SA_LEN) else(WIN32) check_struct_has_member("struct sockaddr" sa_len sys/socket.h HAVE_STRUCT_SOCKADDR_SA_LEN) endif(WIN32) # # Do we have ffs(), and is it declared in ? # check_function_exists(ffs HAVE_FFS) if(HAVE_FFS) # # OK, we have ffs(). Is it declared in ? # # This test fails if we don't have or if we do but it doesn't # declare ffs(). # check_symbol_exists(ffs strings.h STRINGS_H_DECLARES_FFS) endif() # # This requires the libraries that we require, as ether_hostton might be in one # of those libraries. That means we have to do this after we check for those # libraries. # # You are in a twisty little maze of UN*Xes, all different. Some might not have # ether_hostton(). Some might have it and declare it in . Some # might have it and declare it in Some might have it and # declare it in . Some might have it and declare it in # . Some might have it and declare it in . Some # might have it and not declare it in any header file. # # Before you is a C compiler. # cmake_push_check_state() set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LINK_LIBRARIES}) check_function_exists(ether_hostton HAVE_ETHER_HOSTTON) if(HAVE_ETHER_HOSTTON) # # OK, we have ether_hostton(). Is it declared in ? # # This test fails if we don't have or if we do but it doesn't # declare ether_hostton(). # check_symbol_exists(ether_hostton net/ethernet.h NET_ETHERNET_H_DECLARES_ETHER_HOSTTON) if(NET_ETHERNET_H_DECLARES_ETHER_HOSTTON) # # Yes - we have it declared. # set(HAVE_DECL_ETHER_HOSTTON TRUE) endif() # # Did that succeed? # if(NOT HAVE_DECL_ETHER_HOSTTON) # # No - how about , as on Linux? # # This test fails if we don't have or if we do but it # doesn't declare ether_hostton(). # check_symbol_exists(ether_hostton netinet/ether.h NETINET_ETHER_H_DECLARES_ETHER_HOSTTON) if(NETINET_ETHER_H_DECLARES_ETHER_HOSTTON) # # Yes - we have it declared. # set(HAVE_DECL_ETHER_HOSTTON TRUE) endif() endif() # # Did that succeed? # if(NOT HAVE_DECL_ETHER_HOSTTON) # # No - how about , as on Solaris 10 and later? # # This test fails if we don't have or if we do but it # doesn't declare ether_hostton(). # check_symbol_exists(ether_hostton sys/ethernet.h SYS_ETHERNET_H_DECLARES_ETHER_HOSTTON) if(SYS_ETHERNET_H_DECLARES_ETHER_HOSTTON) # # Yes - we have it declared. # set(HAVE_DECL_ETHER_HOSTTON TRUE) endif() endif() # # Did that succeed? # if(NOT HAVE_DECL_ETHER_HOSTTON) # # No, how about , as on AIX? # # This test fails if we don't have or if we do but it doesn't # declare ether_hostton(). # check_symbol_exists(ether_hostton arpa/inet.h ARPA_INET_H_DECLARES_ETHER_HOSTTON) if(ARPA_INET_H_DECLARES_ETHER_HOSTTON) # # Yes - we have it declared. # set(HAVE_DECL_ETHER_HOSTTON TRUE) endif() endif() # # Did that succeed? # if(NOT HAVE_DECL_ETHER_HOSTTON) # # No, how about ? On some platforms, it requires # and , and we always include it with both of them, # so test it with both of them. # # This test fails if we don't have and the headers we # include before it, or if we do but doesn't declare # ether_hostton(). # 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) if(NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON) # # Yes - we have it declared. # set(HAVE_DECL_ETHER_HOSTTON TRUE) endif() endif() # # After all that, is ether_hostton() declared? # if(NOT HAVE_DECL_ETHER_HOSTTON) # # No, we'll have to declare it ourselves. Do we have "struct ether_addr" if # we include ? # # XXX - there's no check_type() macro that's like check_type_size() except # that it only checks for the existence of the structure type, so we use # check_type_size() and ignore the size. # cmake_push_check_state() set(CMAKE_EXTRA_INCLUDE_FILES sys/types.h sys/socket.h net/if.h netinet/in.h netinet/if_ether.h) check_type_size("struct ether_addr" STRUCT_ETHER_ADDR) cmake_pop_check_state() endif() endif() cmake_pop_check_state() # # Large file support on UN*X, a/k/a LFS. # if(NOT WIN32) include(FindLFS) if(LFS_FOUND) # # Add the required #defines. # add_definitions(${LFS_DEFINITIONS}) endif() # # Check for fseeko as well. # include(FindFseeko) if(FSEEKO_FOUND) set(HAVE_FSEEKO ON) # # Add the required #defines. # add_definitions(${FSEEKO_DEFINITIONS}) endif() endif() if(INET6) message(STATUS "Support IPv6") endif(INET6) # # Pthreads. We might need them, because some libraries we use might use them, # but we don't necessarily need them. That's only on UN*X; on Windows, if they # use threads, we assume they're native Windows threads. # if(NOT WIN32) set(CMAKE_THREAD_PREFER_PTHREAD ON) find_package(Threads) if(NOT CMAKE_USE_PTHREADS_INIT) # # If it's not pthreads, we won't use it; we use it for libraries that # require it. # set(CMAKE_THREAD_LIBS_INIT "") endif(NOT CMAKE_USE_PTHREADS_INIT) endif(NOT WIN32) if(ENABLE_PROFILING) if(NOT MSVC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pg") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") endif() endif() # # Based on # # https://github.com/commonmark/cmark/blob/master/FindAsan.cmake # # The MIT License (MIT) # # Copyright (c) 2013 Matthew Arsenault # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. # # Test if the each of the sanitizers in the ENABLE_SANITIZERS list are supported # by the compiler, and, if so, adds the appropriate flags to CMAKE_C_FLAGS, # CMAKE_CXX_FLAGS, and SANITIZER_FLAGS. If not, it fails. # # Do this last, in the hope that it will prevent configuration on Linux from # somehow deciding it doesn't need -lpthread when building rpcapd (it does # require it, but somehow, in some mysterious fashion that no obvious CMake # debugging flag reveals, it doesn't realize that if we turn sanitizer stuff # on). # set(SANITIZER_FLAGS "") foreach(sanitizer IN LISTS ENABLE_SANITIZERS) # Set -Werror to catch "argument unused during compilation" warnings message(STATUS "Checking sanitizer ${sanitizer}") set(sanitizer_variable "sanitize_${sanitizer}") set(CMAKE_REQUIRED_FLAGS "-Werror -fsanitize=${sanitizer}") check_c_compiler_flag("-fsanitize=${sanitizer}" ${sanitizer_variable}) if(${${sanitizer_variable}}) set(SANITIZER_FLAGS "${SANITIZER_FLAGS} -fsanitize=${sanitizer}") message( STATUS "${sanitizer} sanitizer supported using -fsanitizer=${sanitizer}") else() # # Try the versions supported prior to Clang 3.2. If the sanitizer is # "address", try -fsanitize-address. If it's "undefined", try # -fcatch-undefined-behavior. Otherwise, give up. # set(sanitizer_variable "OLD_${sanitizer_variable}") if("${sanitizer}" STREQUAL "address") set(CMAKE_REQUIRED_FLAGS "-Werror -fsanitize-address") check_c_compiler_flag("-fsanitize-address" ${sanitizer_variable}) if(${${sanitizer_variable}}) set(SANITIZER_FLAGS "${SANITIZER_FLAGS} -fsanitize-address") message( STATUS "${sanitizer} sanitizer supported using -fsanitize-address") else() message(FATAL_ERROR "${sanitizer} isn't a supported sanitizer") endif() elseif("${sanitizer}" STREQUAL "undefined") set(CMAKE_REQUIRED_FLAGS "-Werror -fcatch-undefined-behavior") check_c_compiler_flag("-fcatch-undefined-behavior" ${sanitizer_variable}) if(${${sanitizer_variable}}) set(SANITIZER_FLAGS "${SANITIZER_FLAGS} -fcatch-undefined-behavior") message( STATUS "${sanitizer} sanitizer supported using catch-undefined-behavior") else() message(FATAL_ERROR "${sanitizer} isn't a supported sanitizer") endif() else() message(FATAL_ERROR "${sanitizer} isn't a supported sanitizer") endif() endif() unset(CMAKE_REQUIRED_FLAGS) endforeach() if(NOT "${SANITIZER_FLAGS}" STREQUAL "") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O1 -g ${SANITIZER_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls" ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O1 -g ${SANITIZER_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls" ) endif() # # OpenSSL/libressl. # find_package(OpenSSL) if(OPENSSL_FOUND) # # We have OpenSSL. # include_directories(SYSTEM ${OPENSSL_INCLUDE_DIR}) set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${OPENSSL_LIBRARIES}) set(HAVE_OPENSSL YES) endif(OPENSSL_FOUND) # # Additional linker flags. # set(LINKER_FLAGS "${SANITIZER_FLAGS}") if(ENABLE_PROFILING) if(MSVC) set(LINKER_FLAGS " /PROFILE") else() set(LINKER_FLAGS " -pg") endif() endif() # ############################################################################## # Input files # ############################################################################## set(PROJECT_SOURCE_LIST_C bpf_dump.c bpf_filter.c bpf_image.c etherent.c fmtutils.c gencode.c nametoaddr.c optimize.c pcap-common.c pcap.c savefile.c sf-pcapng.c sf-pcap.c) if(WIN32) # # We add the character set conversion routines; they're Windows-only for now. # # We assume we don't have asprintf(), and provide an implementation that uses # _vscprintf() to determine how big the string needs to be. # set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} charconv.c missing/win_asprintf.c) else() if(NOT HAVE_ASPRINTF) set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/asprintf.c) endif() if(NOT HAVE_STRLCAT) set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/strlcat.c) endif(NOT HAVE_STRLCAT) if(NOT HAVE_STRLCPY) set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/strlcpy.c) endif(NOT HAVE_STRLCPY) if(NOT HAVE_STRTOK_R) set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/strtok_r.c) endif(NOT HAVE_STRTOK_R) endif(WIN32) # # Determine the main pcap-XXX.c file to use, and the libraries with which we # need to link libpcap, if any. # if(WIN32) # # Windows. # # Has the user explicitly specified a capture type? # if(PCAP_TYPE STREQUAL "") # # The user didn't explicitly specify a capture mechanism. Check whether we # have packet.dll. # if(HAVE_PACKET32) # # We have packet.dll. Set the capture type to NPF. # set(PCAP_TYPE npf) else() # # We don't have any capture type we know about, so just use the null # capture type, and only support reading (and writing) capture files. # set(PCAP_TYPE null) endif() endif() else() # # UN*X. # # Figure out what type of packet capture mechanism we have, and what libraries # we'd need to link libpcap with, if any. # # # Has the user explicitly specified a capture type? # if(PCAP_TYPE STREQUAL "") # # Check for a bunch of headers for various packet capture mechanisms. # check_include_files("sys/types.h;net/bpf.h" HAVE_NET_BPF_H) if(HAVE_NET_BPF_H) # # Does it define BIOCSETIF? I.e., is it a header for an LBL/BSD-style # capture mechanism, or is it just a header for a BPF filter engine? Some # versions of Arch Linux, for example, have a net/bpf.h that doesn't # define BIOCSETIF; as it's a Linux, it should use packet sockets, # instead. # # We need: # # sys/types.h, because FreeBSD 10's net/bpf.h requires that various # BSD-style integer types be defined; # # sys/time.h, because AIX 5.2 and 5.3's net/bpf.h doesn't include it but # does use struct timeval in ioctl definitions; # # sys/ioctl.h and, if we have it, sys/ioccom.h, because net/bpf.h defines # ioctls; # # net/if.h, because it defines some structures used in ioctls defined by # net/bpf.h; # # sys/socket.h, because OpenBSD 5.9's net/bpf.h defines some structure # fields as being struct sockaddrs; # # and net/bpf.h doesn't necessarily include all of those headers itself. # if(HAVE_SYS_IOCCOM_H) 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) else(HAVE_SYS_IOCCOM_H) 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) endif(HAVE_SYS_IOCCOM_H) endif(HAVE_NET_BPF_H) check_include_file(net/pfilt.h HAVE_NET_PFILT_H) check_include_file(net/enet.h HAVE_NET_ENET_H) check_include_file(net/nit.h HAVE_NET_NIT_H) check_include_file(sys/net/nit.h HAVE_SYS_NET_NIT_H) check_include_file(linux/socket.h HAVE_LINUX_SOCKET_H) check_include_file(net/raw.h HAVE_NET_RAW_H) check_include_file(sys/dlpi.h HAVE_SYS_DLPI_H) check_include_file(config/HaikuConfig.h HAVE_CONFIG_HAIKUCONFIG_H) if(BPF_H_DEFINES_BIOCSETIF) # # BPF. Check this before DLPI, so that we pick BPF on Solaris 11 and # later. # set(PCAP_TYPE bpf) elseif(HAVE_LINUX_SOCKET_H) # # No prizes for guessing this one. # set(PCAP_TYPE linux) elseif(HAVE_NET_PFILT_H) # # DEC OSF/1, Digital UNIX, Tru64 UNIX # set(PCAP_TYPE pf) elseif(HAVE_NET_ENET_H) # # Stanford Enetfilter. # set(PCAP_TYPE enet) elseif(HAVE_NET_NIT_H) # # SunOS 4.x STREAMS NIT. # set(PCAP_TYPE snit) elseif(HAVE_SYS_NET_NIT_H) # # Pre-SunOS 4.x non-STREAMS NIT. # set(PCAP_TYPE nit) elseif(HAVE_NET_RAW_H) # # IRIX snoop. # set(PCAP_TYPE snoop) elseif(HAVE_SYS_DLPI_H) # # DLPI on pre-Solaris 11 SunOS 5, HP-UX, possibly others. # set(PCAP_TYPE dlpi) elseif(HAVE_CONFIG_HAIKUCONFIG_H) # # Haiku. # set(PCAP_TYPE haiku) else() # # Nothing we support. # set(PCAP_TYPE null) endif() endif() endif(WIN32) message(STATUS "Packet capture mechanism type: ${PCAP_TYPE}") find_package(PkgConfig QUIET) # # Do capture-mechanism-dependent tests. # if(WIN32) if(PCAP_TYPE STREQUAL "npf") # # Link with packet.dll before Winsock2. # set(PCAP_LINK_LIBRARIES ${PACKET_LIBRARIES} ${PCAP_LINK_LIBRARIES}) elseif(PCAP_TYPE STREQUAL "null") else() message(FATAL_ERROR "${PCAP_TYPE} is not a valid pcap type") endif() else(WIN32) if(PCAP_TYPE STREQUAL "dlpi") # # Needed for common functions used by pcap-[dlpi,libdlpi].c # set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} dlpisubs.c) # # Checks for some header files. # check_include_file(sys/bufmod.h HAVE_SYS_BUFMOD_H) check_include_file(sys/dlpi_ext.h HAVE_SYS_DLPI_EXT_H) # # Checks to see if Solaris has the public libdlpi(3LIB) library. Note: The # existence of /usr/include/libdlpi.h does not mean it is the public # libdlpi(3LIB) version. Before libdlpi was made public, a private version # also existed, which did not have the same APIs. Due to a gcc bug, the # default search path for 32-bit libraries does not include /lib, we add it # explicitly here. [http://bugs.opensolaris.org/view_bug.do?bug_id=6619485]. # Also, due to the bug above applications that link to libpcap with libdlpi # will have to add "-L/lib" option to "configure". # cmake_push_check_state() set(CMAKE_REQUIRED_FLAGS "-L/lib") set(CMAKE_REQUIRED_LIBRARIES dlpi) check_function_exists(dlpi_walk HAVE_LIBDLPI) cmake_pop_check_state() if(HAVE_LIBDLPI) # # XXX - add -L/lib # set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} dlpi) set(PCAP_TYPE libdlpi) endif() # # This check is for Solaris with DLPI support for passive modes. See # dlpi(7P) for more details. # # XXX - there's no check_type() macro that's like check_type_size() except # that it only checks for the existence of the structure type, so we use # check_type_size() and ignore the size. # cmake_push_check_state() set(CMAKE_EXTRA_INCLUDE_FILES sys/types.h sys/dlpi.h) check_type_size(dl_passive_req_t DL_PASSIVE_REQ_T) cmake_pop_check_state() elseif(PCAP_TYPE STREQUAL "linux") # # Do we have the wireless extensions? linux/wireless.h requires # sys/socket.h. # check_include_files("sys/socket.h;linux/wireless.h" HAVE_LINUX_WIRELESS_H) # # Do we have libnl? We only want version 3. Version 2 was, apparently, # short-lived, and version 1 is source and binary incompatible with version # 3, and it appears that, these days, everybody's using version 3. We're # not supporting older versions of the Linux kernel; let's drop support for # older versions of libnl, too. # if(BUILD_WITH_LIBNL) pkg_check_modules(LIBNL libnl-3.0) if(LIBNL_FOUND) set(PCAP_LINK_LIBRARIES ${LIBNL_LIBRARIES} ${PCAP_LINK_LIBRARIES}) include_directories(${LIBNL_INCLUDE_DIRS}) else() cmake_push_check_state() set(CMAKE_REQUIRED_LIBRARIES nl-3) check_function_exists(nl_socket_alloc HAVE_LIBNL) cmake_pop_check_state() if(HAVE_LIBNL) # # Yes, we have libnl 3.x. # set(PCAP_LINK_LIBRARIES nl-genl-3 nl-3 ${PCAP_LINK_LIBRARIES}) include_directories("/usr/include/libnl3") endif() endif() else() unset(HAVE_LIBNL CACHE) # check_function_exists stores results in cache endif() check_struct_has_member( "struct tpacket_auxdata" tp_vlan_tci linux/if_packet.h HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TCI) elseif(PCAP_TYPE STREQUAL "bpf") # # Check whether we have the *BSD-style ioctls. # check_include_files("sys/types.h;net/if_media.h" HAVE_NET_IF_MEDIA_H) # # Check whether we have struct BPF_TIMEVAL. # # XXX - there's no check_type() macro that's like check_type_size() except # that it only checks for the existence of the structure type, so we use # check_type_size() and ignore the size. # cmake_push_check_state() if(HAVE_SYS_IOCCOM_H) set(CMAKE_EXTRA_INCLUDE_FILES sys/types.h sys/ioccom.h net/bpf.h) check_type_size("struct BPF_TIMEVAL" STRUCT_BPF_TIMEVAL) else() set(CMAKE_EXTRA_INCLUDE_FILES sys/types.h net/bpf.h) check_type_size("struct BPF_TIMEVAL" STRUCT_BPF_TIMEVAL) endif() cmake_pop_check_state() elseif(PCAP_TYPE STREQUAL "haiku") # # Check for some headers just in case. # check_include_files("net/if.h;net/if_dl.h;net/if_types.h" HAVE_NET_IF_TYPES_H) set(PCAP_SRC pcap-${PCAP_TYPE}.cpp) elseif(PCAP_TYPE STREQUAL "null") else() message(FATAL_ERROR "${PCAP_TYPE} is not a valid pcap type") endif() endif(WIN32) if(NOT DEFINED PCAP_SRC) set(PCAP_SRC pcap-${PCAP_TYPE}.c) endif() set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} ${PCAP_SRC}) # # Now figure out how we get a list of interfaces and addresses, if we support # capturing. Don't bother if we don't support capturing. # if(NOT WIN32) # # UN*X - figure out what type of interface list mechanism we have. # # If the capture type is null, that means we can't capture, so we can't open # any capture devices, so we won't return any interfaces. # if(NOT PCAP_TYPE STREQUAL "null") cmake_push_check_state() set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LINK_LIBRARIES}) check_function_exists(getifaddrs HAVE_GETIFADDRS) cmake_pop_check_state() if(NOT HAVE_GETIFADDRS) # # It's not in the libraries that, at this point, we've found we need to # link libpcap with. # # It's in libsocket on Solaris and possibly other OSes; as long as we're # not linking with libxnet, check there. # # NOTE: if you hand check_library_exists as its last argument a variable # that's been set, it skips the test, so we need different variables. # if(NOT LIBXNET_HAS_GETHOSTBYNAME) check_library_exists(socket getifaddrs "" SOCKET_HAS_GETIFADDRS) if(SOCKET_HAS_GETIFADDRS) set(PCAP_LINK_LIBRARIES socket ${PCAP_LINK_LIBRARIES}) set(HAVE_GETIFADDRS TRUE) endif() endif() endif() if(HAVE_GETIFADDRS) # # We have "getifaddrs()"; make sure we have as well, just in # case some platform is really weird. It may require that sys/types.h be # included first, so include it first. # check_include_files("sys/types.h;ifaddrs.h" HAVE_IFADDRS_H) if(HAVE_IFADDRS_H) # # We have the header, so we use "getifaddrs()" to get the list of # interfaces. # set(FINDALLDEVS_TYPE getad) else() # # We don't have the header - give up. XXX - we could also fall back on # some other mechanism, but, for now, this'll catch this problem so that # we can at least try to figure out something to do on systems with # "getifaddrs()" but without "ifaddrs.h", if there is something we can # do on those systems. # message( FATAL_ERROR "Your system has getifaddrs() but doesn't have a usable ." ) endif() else() # # Well, we don't have "getifaddrs()", at least not with the libraries with # which we've decided we need to link libpcap with, so we have to use some # other mechanism. # # Note that this may happen on Solaris, which has getifaddrs(), but in # -lsocket, not in -lxnet, so we won't find it if we link with -lxnet, # which we want to do for other reasons. # # For now, we use either the SIOCGIFCONF ioctl or the SIOCGLIFCONF ioctl, # preferring the latter if we have it; the latter is a Solarisism that # first appeared in Solaris 8. (Solaris's getifaddrs() appears to be # built atop SIOCGLIFCONF; using it directly avoids a not-all-that-useful # middleman.) # try_compile(HAVE_SIOCGLIFCONF ${CMAKE_CURRENT_BINARY_DIR} "${pcap_SOURCE_DIR}/cmake/have_siocglifconf.c") if(HAVE_SIOCGLIFCONF) set(FINDALLDEVS_TYPE glifc) else() set(FINDALLDEVS_TYPE gifc) endif() endif() message(STATUS "Find-interfaces mechanism type: ${FINDALLDEVS_TYPE}") set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} fad-${FINDALLDEVS_TYPE}.c) endif() endif() # Check for hardware timestamp support. if(CMAKE_SYSTEM_NAME STREQUAL "Linux") check_include_file(linux/net_tstamp.h HAVE_LINUX_NET_TSTAMP_H) endif() # # Check for additional native sniffing capabilities. # # # Various Linux-specific mechanisms. # if(CMAKE_SYSTEM_NAME STREQUAL "Linux") # Check for usbmon USB sniffing support. if(NOT DISABLE_LINUX_USBMON) set(PCAP_SUPPORT_LINUX_USBMON TRUE) set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-usb-linux.c) set(LINUX_USB_MON_DEV /dev/usbmon) # # Do we have a version of available? If so, we might need # it for . # check_include_files("linux/compiler.h" HAVE_LINUX_COMPILER_H) if(HAVE_LINUX_COMPILER_H) # # Yes - include it when testing for . # check_include_files("linux/compiler.h;linux/usbdevice_fs.h" HAVE_LINUX_USBDEVICE_FS_H) else(HAVE_LINUX_COMPILER_H) check_include_files("linux/usbdevice_fs.h" HAVE_LINUX_USBDEVICE_FS_H) endif(HAVE_LINUX_COMPILER_H) if(HAVE_LINUX_USBDEVICE_FS_H) # # OK, does it define bRequestType? Older versions of the kernel define # fields with names like "requesttype, "request", and "value", rather than # "bRequestType", "bRequest", and "wValue". # if(HAVE_LINUX_COMPILER_H) check_struct_has_member( "struct usbdevfs_ctrltransfer" bRequestType "linux/compiler.h;linux/usbdevice_fs.h" HAVE_STRUCT_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE) else(HAVE_LINUX_COMPILER_H) check_struct_has_member( "struct usbdevfs_ctrltransfer" bRequestType "linux/usbdevice_fs.h" HAVE_STRUCT_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE) endif(HAVE_LINUX_COMPILER_H) endif() endif() # # Check for netfilter sniffing support. # # Life's too short to deal with trying to get this to compile if you don't get # the right types defined with __KERNEL_STRICT_NAMES getting defined by some # other include. # # Check whether the includes Just Work. If not, don't turn on netfilter # support. # check_c_source_compiles( "#include #include #include #include #include #include #include #include int main(void) { return 0; } " PCAP_SUPPORT_NETFILTER) if(PCAP_SUPPORT_NETFILTER) set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-netfilter-linux.c) endif(PCAP_SUPPORT_NETFILTER) endif() # Check for netmap sniffing support. if(NOT DISABLE_NETMAP) # # Check whether net/netmap_user.h is usable if NETMAP_WITH_LIBS is defined; # it's not usable on DragonFly BSD 4.6 if NETMAP_WITH_LIBS is defined, for # example, as it includes a non-existent malloc.h header. # check_c_source_compiles( "#define NETMAP_WITH_LIBS #include int main(void) { return 0; } " PCAP_SUPPORT_NETMAP) if(PCAP_SUPPORT_NETMAP) set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-netmap.c) endif(PCAP_SUPPORT_NETMAP) endif() # Check for DPDK sniffing support if(NOT DISABLE_DPDK) find_package(dpdk) if(dpdk_FOUND) # # We include rte_bus.h, and older versions of DPDK didn't have it, so check # for it. # # Also, we call rte_eth_dev_count_avail(), and older versions of DPDK didn't # have it, so check for it. # cmake_push_check_state() set(CMAKE_REQUIRED_INCLUDES ${dpdk_INCLUDE_DIRS}) check_include_file(rte_bus.h HAVE_RTE_BUS_H) set(CMAKE_REQUIRED_LIBRARIES ${dpdk_LIBRARIES}) check_function_exists(rte_eth_dev_count_avail HAVE_RTE_ETH_DEV_COUNT_AVAIL) cmake_pop_check_state() if(HAVE_RTE_BUS_H AND HAVE_RTE_ETH_DEV_COUNT_AVAIL) set(DPDK_C_FLAGS "-march=native") set(DPDK_LIB dpdk rt m numa dl) set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} ${DPDK_C_FLAGS}) include_directories(AFTER ${dpdk_INCLUDE_DIRS}) link_directories(AFTER ${dpdk_LIBRARIES}) set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${dpdk_LIBRARIES}) set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-dpdk.c) set(PCAP_SUPPORT_DPDK TRUE) # # Check whether the rte_ether.h file defines struct ether_addr or struct # rte_ether_addr. # # ("API compatibility? That's for losers!") # cmake_push_check_state() set(CMAKE_REQUIRED_INCLUDES ${dpdk_INCLUDE_DIRS}) set(CMAKE_EXTRA_INCLUDE_FILES rte_ether.h) check_type_size("struct rte_ether_addr" STRUCT_RTE_ETHER_ADDR) cmake_pop_check_state() endif() endif() endif() # Check for Bluetooth sniffing support if(NOT DISABLE_BLUETOOTH) if(CMAKE_SYSTEM_NAME STREQUAL "Linux") check_include_file(bluetooth/bluetooth.h HAVE_BLUETOOTH_BLUETOOTH_H) if(HAVE_BLUETOOTH_BLUETOOTH_H) set(PCAP_SUPPORT_BT TRUE) set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-bt-linux.c) # # OK, does struct sockaddr_hci have an hci_channel member? # check_struct_has_member( "struct sockaddr_hci" hci_channel "bluetooth/bluetooth.h;bluetooth/hci.h" HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL) if(HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL) # # OK, is HCI_CHANNEL_MONITOR defined? # check_c_source_compiles( "#include #include int main(void) { u_int i = HCI_CHANNEL_MONITOR; return 0; } " PCAP_SUPPORT_BT_MONITOR) if(PCAP_SUPPORT_BT_MONITOR) # # Yes, so we can also support Bluetooth monitor sniffing. # set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-bt-monitor-linux.c) endif(PCAP_SUPPORT_BT_MONITOR) endif(HAVE_STRUCT_SOCKADDR_HCI_HCI_CHANNEL) endif(HAVE_BLUETOOTH_BLUETOOTH_H) endif() else() unset(PCAP_SUPPORT_BT_MONITOR CACHE) endif() # Check for D-Bus sniffing support if(NOT DISABLE_DBUS) # # We don't support D-Bus sniffing on macOS; see # # https://bugs.freedesktop.org/show_bug.cgi?id=74029 # if(APPLE) message( FATAL_ERROR "Due to freedesktop.org bug 74029, D-Bus capture support is not available on macOS" ) endif(APPLE) pkg_check_modules(DBUS dbus-1) if(DBUS_FOUND) set(PCAP_SUPPORT_DBUS TRUE) set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-dbus.c) include_directories(${DBUS_INCLUDE_DIRS}) # # This "helpfully" supplies DBUS_LIBRARIES as a bunch of library names - not # paths - and DBUS_LIBRARY_DIRS as a bunch of directories. # # CMake *really* doesn't like the notion of specifying "here are the # directories in which to look for libraries" except in find_library() # calls; it *really* prefers using full paths to library files, rather than # library names. # # Find the libraries and add their full paths. # set(DBUS_LIBRARY_FULLPATHS) foreach(_lib IN LISTS DBUS_LIBRARIES) # # Try to find this library, so we get its full path. # find_library(_libfullpath ${_lib} HINTS ${DBUS_LIBRARY_DIRS}) list(APPEND DBUS_LIBRARY_FULLPATHS ${_libfullpath}) endforeach() set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${DBUS_LIBRARY_FULLPATHS}) endif(DBUS_FOUND) endif(NOT DISABLE_DBUS) # Check for RDMA sniffing support if(NOT DISABLE_RDMA) check_library_exists(ibverbs ibv_get_device_list "" LIBIBVERBS_HAS_IBV_GET_DEVICE_LIST) if(LIBIBVERBS_HAS_IBV_GET_DEVICE_LIST) check_include_file(infiniband/verbs.h HAVE_INFINIBAND_VERBS_H) if(HAVE_INFINIBAND_VERBS_H) check_symbol_exists(ibv_create_flow infiniband/verbs.h PCAP_SUPPORT_RDMASNIFF) if(PCAP_SUPPORT_RDMASNIFF) set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-rdmasniff.c) set(PCAP_LINK_LIBRARIES ibverbs ${PCAP_LINK_LIBRARIES}) endif(PCAP_SUPPORT_RDMASNIFF) endif(HAVE_INFINIBAND_VERBS_H) endif(LIBIBVERBS_HAS_IBV_GET_DEVICE_LIST) endif(NOT DISABLE_RDMA) # # Check for sniffing capabilities using third-party APIs. # # Check for Endace DAG card support. if(NOT DISABLE_DAG) # # Try to find the DAG header file and library. # find_package(DAG) # # Did we succeed? # if(DAG_FOUND) # # Yes. Check for various DAG API functions. # cmake_push_check_state() set(CMAKE_REQUIRED_INCLUDES ${DAG_INCLUDE_DIRS}) set(CMAKE_REQUIRED_LIBRARIES ${DAG_LIBRARIES}) check_function_exists(dag_attach_stream HAVE_DAG_STREAMS_API) if(NOT HAVE_DAG_STREAMS_API) message(FATAL_ERROR "DAG library lacks streams support") endif() check_function_exists(dag_attach_stream64 HAVE_DAG_LARGE_STREAMS_API) check_function_exists(dag_get_erf_types HAVE_DAG_GET_ERF_TYPES) check_function_exists(dag_get_stream_erf_types HAVE_DAG_GET_STREAM_ERF_TYPES) cmake_pop_check_state() include_directories(AFTER ${DAG_INCLUDE_DIRS}) set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-dag.c) set(HAVE_DAG_API TRUE) set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${DAG_LIBRARIES}) if(HAVE_DAG_LARGE_STREAMS_API) get_filename_component(DAG_LIBRARY_DIR ${DAG_LIBRARY} PATH) check_library_exists(vdag vdag_set_device_info ${DAG_LIBRARY_DIR} HAVE_DAG_VDAG) if(HAVE_DAG_VDAG) set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) endif() endif() endif() endif() # Check for Septel card support. set(PROJECT_EXTERNAL_OBJECT_LIST "") if(NOT DISABLE_SEPTEL) # # Do we have the msg.h header? # set(SEPTEL_INCLUDE_DIRS "${SEPTEL_ROOT}/INC") cmake_push_check_state() set(CMAKE_REQUIRED_INCLUDES ${SEPTEL_INCLUDE_DIRS}) check_include_file(msg.h HAVE_INC_MSG_H) cmake_pop_check_state() if(HAVE_INC_MSG_H) # # Yes. # include_directories(AFTER ${SEPTEL_INCLUDE_DIRS}) set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-septel.c) 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" ) set(HAVE_SEPTEL_API TRUE) endif() endif() # Check for Myricom SNF support. if(NOT DISABLE_SNF) # # Try to find the SNF header file and library. # find_package(SNF) # # Did we succeed? # if(SNF_FOUND) # # Yes. # include_directories(AFTER ${SNF_INCLUDE_DIRS}) set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-snf.c) set(HAVE_SNF_API TRUE) set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${SNF_LIBRARIES}) endif() endif() # Check for Riverbed AirPcap support. if(NOT DISABLE_AIRPCAP) # # Try to find the AirPcap header file and library. # find_package(AirPcap) # # Did we succeed? # if(AIRPCAP_FOUND) # # Yes. # include_directories(AFTER ${AIRPCAP_INCLUDE_DIRS}) set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-airpcap.c) set(HAVE_AIRPCAP_API TRUE) set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${AIRPCAP_LIBRARIES}) endif() endif() # Check for Riverbed TurboCap support. if(NOT DISABLE_TC) # # Try to find the TurboCap header file and library. # find_package(TC) # # Did we succeed? # if(TC_FOUND) # # Yes. # include_directories(AFTER ${TC_INCLUDE_DIRS}) set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-tc.c) set(HAVE_TC_API TRUE) set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${TC_LIBRARIES} ${CMAKE_USE_PTHREADS_INIT} stdc++) endif() endif() # # Remote capture support. # if(ENABLE_REMOTE) # # Check for various members of struct msghdr. We need to include ftmacros.h on # some platforms, to make sure we get the POSIX/Single USER Specification # version of struct msghdr, which has those members, rather than the # backwards-compatible version, which doesn't. That's not a system header # file, and at least some versions of CMake include it as , which # won't check the current directory, so we add the top-level source directory # to the list of include directories when we do the check. # cmake_push_check_state() set(CMAKE_REQUIRED_INCLUDES ${PROJECT_SOURCE_DIR}) check_struct_has_member("struct msghdr" msg_control "ftmacros.h;sys/socket.h" HAVE_STRUCT_MSGHDR_MSG_CONTROL) check_struct_has_member("struct msghdr" msg_flags "ftmacros.h;sys/socket.h" HAVE_STRUCT_MSGHDR_MSG_FLAGS) cmake_pop_check_state() set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-new.c pcap-rpcap.c rpcap-protocol.c sockutils.c sslutils.c) endif(ENABLE_REMOTE) # ############################################################################## # Warning options # ############################################################################## # # Check and add warning options if we have a .devel file. # if(EXISTS ${PROJECT_SOURCE_DIR}/.devel OR EXISTS ${CMAKE_BINARY_DIR}/.devel) # # Warning options. # if(MSVC AND NOT ${CMAKE_C_COMPILER} MATCHES "clang*") # # MSVC, with Microsoft's front end and code generator. "MSVC" is also set # for Microsoft's compiler with a Clang front end and their code generator # ("Clang/C2"), so we check for clang.exe and treat that differently. # check_and_add_compiler_option(-Wall) # # Disable some pointless warnings that /Wall turns on. # # Unfortunately, MSVC does not appear to have an equivalent to # "__attribute__((unused))" to mark a particular function parameter as being # known to be unused, so that the compiler won't warn about it (for example, # the function might have that parameter because a pointer to it is being # used, and the signature of that function includes that parameter). C++ # lets you give a parameter a type but no name, but C doesn't have that. # check_and_add_compiler_option(-wd4100) # # In theory, we care whether somebody uses f() rather than f(void) to # declare a function with no arguments, but, in practice, there are places # in the Windows header files that appear to do that, so we squelch that # warning. # check_and_add_compiler_option(-wd4255) # # Windows FD_SET() generates this, so we suppress it. # check_and_add_compiler_option(-wd4548) # # Perhaps testing something #defined to be 0 with #ifdef is an error, and it # should be tested with #if, but perhaps it's not, and Microsoft does that # in its headers, so we squelch that warning. # check_and_add_compiler_option(-wd4574) # # The Windows headers also test not-defined values in #if, so we don't want # warnings about that, either. # check_and_add_compiler_option(-wd4668) # # We do *not* care whether some function is, or isn't, going to be expanded # inline. # check_and_add_compiler_option(-wd4710) check_and_add_compiler_option(-wd4711) # # We do *not* care whether we're adding padding bytes after structure # members. # check_and_add_compiler_option(-wd4820) # # We do *not* care about every single place the compiler would have inserted # Spectre mitigation if only we had told it to do so with /Qspectre. Maybe # it's worth it, as that's in Bison-generated code that we don't control. # # XXX - add /Qspectre if that is really worth doing. # check_and_add_compiler_option(-wd5045) # # Treat all (remaining) warnings as errors. # check_and_add_compiler_option(-WX) else() # # Other compilers, including MSVC with a Clang front end and Microsoft's # code generator. We currently treat them as if they might support # GCC-style -W options. # check_and_add_compiler_option(-Wall) check_and_add_compiler_option(-Wcomma) # Warns about safeguards added in case the enums are extended # check_and_add_compiler_option(-Wcovered-switch-default) check_and_add_compiler_option(-Wdocumentation) check_and_add_compiler_option(-Wformat-nonliteral) check_and_add_compiler_option(-Wmissing-noreturn) check_and_add_compiler_option(-Wmissing-prototypes) check_and_add_compiler_option(-Wmissing-variable-declarations) check_and_add_compiler_option(-Wpointer-arith) check_and_add_compiler_option(-Wpointer-sign) check_and_add_compiler_option(-Wshadow) check_and_add_compiler_option(-Wsign-compare) check_and_add_compiler_option(-Wshorten-64-to-32) check_and_add_compiler_option(-Wstrict-prototypes) check_and_add_compiler_option(-Wunreachable-code) check_and_add_compiler_option(-Wunused-parameter) check_and_add_compiler_option(-Wused-but-marked-unused) endif() endif() # # Suppress some warnings we get with MSVC even without /Wall. # if(MSVC AND NOT ${CMAKE_C_COMPILER} MATCHES "clang*") # # Yes, we have some functions that never return but that have a non-void # return type. That's because, on some platforms, they *do* return values # but, on other platforms, including Windows, they just fail and longjmp out # by calling bpf_error(). # check_and_add_compiler_option(-wd4646) endif() file(GLOB PROJECT_SOURCE_LIST_H *.h pcap/*.h) # # Try to have the compiler default to hiding symbols, so that only symbols # explicitly exported with PCAP_API will be visible outside (shared) libraries. # # Not necessary with MSVC, as that's the default. # # XXX - we don't use ADD_COMPILER_EXPORT_FLAGS, because, as of CMake 2.8.12.2, # it doesn't know about Sun C/Oracle Studio, and, as of CMake 2.8.6, it only # sets the C++ compiler flags, rather than allowing an arbitrary variable to be # set with the "hide symbols not explicitly exported" flag. # if(NOT MSVC) if(CMAKE_C_COMPILER_ID MATCHES "SunPro") # # Sun C/Oracle Studio. # check_and_add_compiler_option(-xldscope=hidden) else() # # Try this for all other compilers; it's what GCC uses, and a number of # other compilers, such as Clang and Intel C, use it as well. # check_and_add_compiler_option(-fvisibility=hidden) endif() endif(NOT MSVC) # # Flex/Lex and YACC/Berkeley YACC/Bison. From a mail message to the CMake # mailing list by Andy Cedilnik of Kitware. # # # Try to find Flex, a Windows version of Flex, or Lex. # find_program(LEX_EXECUTABLE NAMES flex win_flex lex) if(LEX_EXECUTABLE STREQUAL "LEX_EXECUTABLE-NOTFOUND") message(FATAL_ERROR "Neither flex nor win_flex nor lex was found.") endif() message(STATUS "Lexical analyzer generator: ${LEX_EXECUTABLE}") add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/scanner.c ${CMAKE_CURRENT_BINARY_DIR}/scanner.h SOURCE ${pcap_SOURCE_DIR}/scanner.l COMMAND ${LEX_EXECUTABLE} -P pcap_ --header-file=scanner.h --nounput -o${CMAKE_CURRENT_BINARY_DIR}/scanner.c ${pcap_SOURCE_DIR}/scanner.l DEPENDS ${pcap_SOURCE_DIR}/scanner.l) # # Since scanner.c does not exist yet when cmake is run, mark it as generated. # # Since scanner.c includes grammar.h, mark that as a dependency. # set_source_files_properties( ${CMAKE_CURRENT_BINARY_DIR}/scanner.c PROPERTIES GENERATED TRUE OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/grammar.h) # # Add scanner.c to the list of sources. # # set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} # ${CMAKE_CURRENT_BINARY_DIR}/scanner.c) # # Try to find YACC or Bison. # find_program(YACC_EXECUTABLE NAMES bison win_bison byacc yacc) if(YACC_EXECUTABLE STREQUAL "YACC_EXECUTABLE-NOTFOUND") message( FATAL_ERROR "Neither bison nor win_bison nor byacc nor yacc was found.") endif() if(YACC_EXECUTABLE MATCHES "byacc" OR YACC_EXECUTABLE MATCHES "yacc") # # Berkeley YACC doesn't support "%define api.pure", so use "%pure-parser". # set(REENTRANT_PARSER "%pure-parser") else() # # Bison prior to 2.4(.1) doesn't support "%define api.pure", so use # "%pure-parser". # execute_process(COMMAND ${YACC_EXECUTABLE} -V OUTPUT_VARIABLE bison_full_version) string(REGEX MATCH "[1-9][0-9]*[.][1-9][0-9]*" bison_major_minor ${bison_full_version}) if(bison_major_minor VERSION_LESS "2.4") set(REENTRANT_PARSER "%pure-parser") else() set(REENTRANT_PARSER "%define api.pure") endif() endif() message(STATUS "Parser generator: ${YACC_EXECUTABLE}") # # Create custom command for the scanner. Find out whether it's Bison or not by # looking at the last component of the path (without a .exe extension, if this # is Windows). # get_filename_component(YACC_NAME ${YACC_EXECUTABLE} NAME_WE) if("${YACC_NAME}" STREQUAL "bison" OR "${YACC_NAME}" STREQUAL "win_bison") set(YACC_COMPATIBILITY_FLAG "-y") endif() add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/grammar.c ${CMAKE_CURRENT_BINARY_DIR}/grammar.h SOURCE ${pcap_BINARY_DIR}/grammar.y COMMAND ${YACC_EXECUTABLE} ${YACC_COMPATIBILITY_FLAG} -p pcap_ -o ${CMAKE_CURRENT_BINARY_DIR}/grammar.c -d ${pcap_BINARY_DIR}/grammar.y DEPENDS ${pcap_BINARY_DIR}/grammar.y) # # Since grammar.c does not exists yet when cmake is run, mark it as generated. # set_source_files_properties( ${CMAKE_CURRENT_BINARY_DIR}/grammar.c PROPERTIES GENERATED TRUE OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/scanner.h) # # Add grammar.c to the list of sources. # # set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} # ${CMAKE_CURRENT_BINARY_DIR}/grammar.c) # # Assume, by default, no support for shared libraries and V7/BSD convention for # man pages (devices in section 4, file formats in section 5, miscellaneous info # in section 7, administrative commands and daemons in section 8). Individual # cases can override this. Individual cases can override this. # set(MAN_DEVICES 4) set(MAN_FILE_FORMATS 5) set(MAN_MISC_INFO 7) set(MAN_ADMIN_COMMANDS 8) if(CMAKE_SYSTEM_NAME STREQUAL "AIX") # Workaround to enable certain features set(_SUN TRUE) if(PCAP_TYPE STREQUAL "bpf") # # If we're using BPF, we need libodm and libcfg, as we use them to load the # BPF module. # set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} odm cfg) endif() elseif(CMAKE_SYSTEM_NAME STREQUAL "HP-UX") if(CMAKE_SYSTEM_VERSION MATCHES "[A-Z.]*9\.[0-9]*") # # HP-UX 9.x. # set(HAVE_HPUX9 TRUE) elseif(CMAKE_SYSTEM_VERSION MATCHES "[A-Z.]*10\.0") # # HP-UX 10.0. # elseif(CMAKE_SYSTEM_VERSION MATCHES "[A-Z.]*10\.1") # # HP-UX 10.1. # else() # # HP-UX 10.20 and later. # set(HAVE_HPUX10_20_OR_LATER TRUE) endif() # # Use System V conventions for man pages. # set(MAN_ADMIN_COMMANDS 1m) set(MAN_FILE_FORMATS 4) set(MAN_MISC_INFO 5) elseif(CMAKE_SYSTEM_NAME STREQUAL "IRIX" OR CMAKE_SYSTEM_NAME STREQUAL "IRIX64") # # Use IRIX conventions for man pages; they're the same as the System V # conventions, except that they use section 8 for administrative commands and # daemons. # set(MAN_FILE_FORMATS 4) set(MAN_MISC_INFO 5) elseif(CMAKE_SYSTEM_NAME STREQUAL "OSF1") # # DEC OSF/1, a/k/a Digial UNIX, a/k/a Tru64 UNIX. Use Tru64 UNIX conventions # for man pages; they're the same as the System V conventions except that they # use section 8 for administrative commands and daemons. # set(MAN_FILE_FORMATS 4) set(MAN_MISC_INFO 5) set(MAN_DEVICES 7) elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION MATCHES "5[.][0-9.]*") # # SunOS 5.x. # set(HAVE_SOLARIS TRUE) # # Make sure errno is thread-safe, in case we're called in a multithreaded # program. We don't guarantee that two threads can use the *same* pcap_t # safely, but the current version does guarantee that you can use different # pcap_t's in different threads, and even that pcap_compile() is thread-safe # (it wasn't thread-safe in some older versions). # add_definitions(-D_TS_ERRNO) if(CMAKE_SYSTEM_VERSION STREQUAL "5.12") else() # # Use System V conventions for man pages. # set(MAN_ADMIN_COMMANDS 1m) set(MAN_FILE_FORMATS 4) set(MAN_MISC_INFO 5) set(MAN_DEVICES 7D) endif() elseif(CMAKE_SYSTEM_NAME STREQUAL "Haiku") # # Haiku needs _BSD_SOURCE for the _IO* macros because it doesn't use them. # add_definitions(-D_BSD_SOURCE) endif() source_group("Source Files" FILES ${PROJECT_SOURCE_LIST_C}) source_group("Header Files" FILES ${PROJECT_SOURCE_LIST_H}) if(WIN32) # # Add pcap-dll.rc to the list of sources. # set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} ${pcap_SOURCE_DIR}/pcap-dll.rc) endif(WIN32) # # Add subdirectories after we've set various variables, so they pick up pick up # those variables. # if(ENABLE_REMOTE) add_subdirectory(rpcapd) endif(ENABLE_REMOTE) # add_subdirectory(testprogs) # ############################################################################## # Register targets # ############################################################################## # # Special target to serialize the building of the generated source. # # See # # https://public.kitware.com/pipermail/cmake/2013-August/055510.html # add_custom_target(SerializeTarget DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/grammar.c ${CMAKE_CURRENT_BINARY_DIR}/scanner.c) set_source_files_properties(${PROJECT_EXTERNAL_OBJECT_LIST} PROPERTIES EXTERNAL_OBJECT TRUE) if(BUILD_SHARED_LIBS) add_library( ${LIBRARY_NAME} SHARED ${PROJECT_SOURCE_LIST_C} ${CMAKE_CURRENT_BINARY_DIR}/grammar.c ${CMAKE_CURRENT_BINARY_DIR}/scanner.c ${PROJECT_EXTERNAL_OBJECT_LIST}) add_dependencies(${LIBRARY_NAME} SerializeTarget) set_target_properties(${LIBRARY_NAME} PROPERTIES COMPILE_DEFINITIONS BUILDING_PCAP) target_include_directories(${LIBRARY_NAME} INTERFACE ${PROJECT_SOURCE_DIR}/pcap ${PROJECT_SOURCE_DIR}) export(TARGETS ${LIBRARY_NAME} FILE ${CMAKE_CURRENT_BINARY_DIR}/pcap-targets.cmake) # # No matter what the library is called - it might be called "wpcap" in a # Windows build - the symbol to define to indicate that we're building the # library, rather than a program using the library, and thus that we're # exporting functions defined in our public header files, rather than # importing those functions, is pcap_EXPORTS. # set_target_properties(${LIBRARY_NAME} PROPERTIES DEFINE_SYMBOL pcap_EXPORTS) if(NOT "${LINKER_FLAGS}" STREQUAL "") set_target_properties(${LIBRARY_NAME} PROPERTIES LINK_FLAGS "${LINKER_FLAGS}") endif() endif() add_library( ${LIBRARY_NAME}_static STATIC ${PROJECT_SOURCE_LIST_C} ${CMAKE_CURRENT_BINARY_DIR}/grammar.c ${CMAKE_CURRENT_BINARY_DIR}/scanner.c ${PROJECT_EXTERNAL_OBJECT_LIST}) add_dependencies(${LIBRARY_NAME}_static SerializeTarget) set_target_properties(${LIBRARY_NAME}_static PROPERTIES COMPILE_DEFINITIONS BUILDING_PCAP) target_link_libraries(${LIBRARY_NAME}_static ${PCAP_LINK_LIBRARIES}) if(WIN32) if(BUILD_SHARED_LIBS) set_target_properties( ${LIBRARY_NAME} PROPERTIES VERSION ${PACKAGE_VERSION_NOSUFFIX} # only MAJOR and MINOR are # needed ) endif(BUILD_SHARED_LIBS) if(MSVC) # XXX For DLLs, the TARGET_PDB_FILE generator expression can be used to # locate its PDB file's output directory for installation. cmake doesn't # offer a generator expression for PDB files generated by the compiler # (static libraries). So instead of considering any possible output there is # (there are many), this will search for the PDB file in the compiler's # initial output directory, which is always # ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles\wpcap_static.dir regardless of # architecture, build generator etc. Quite hackish indeed. set(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY $) set_target_properties( ${LIBRARY_NAME}_static PROPERTIES COMPILE_PDB_NAME ${LIBRARY_NAME}_static OUTPUT_NAME "${LIBRARY_NAME}_static") elseif(MINGW) # # For compatibility, build the shared library without the "lib" prefix on # MinGW as well. # set_target_properties(${LIBRARY_NAME} PROPERTIES PREFIX "" OUTPUT_NAME "${LIBRARY_NAME}") set_target_properties(${LIBRARY_NAME}_static PROPERTIES OUTPUT_NAME "${LIBRARY_NAME}") endif() else(WIN32) # UN*X if(BUILD_SHARED_LIBS) if(APPLE) set_target_properties(${LIBRARY_NAME} PROPERTIES VERSION ${PACKAGE_VERSION} SOVERSION A) else(APPLE) set_target_properties( ${LIBRARY_NAME} PROPERTIES VERSION ${PACKAGE_VERSION} SOVERSION ${PACKAGE_VERSION_MAJOR}) endif(APPLE) endif(BUILD_SHARED_LIBS) set_target_properties(${LIBRARY_NAME}_static PROPERTIES OUTPUT_NAME "${LIBRARY_NAME}") endif(WIN32) if(BUILD_SHARED_LIBS) if(NOT C_ADDITIONAL_FLAGS STREQUAL "") set_target_properties(${LIBRARY_NAME} PROPERTIES COMPILE_FLAGS ${C_ADDITIONAL_FLAGS}) endif() target_link_libraries(${LIBRARY_NAME} ${PCAP_LINK_LIBRARIES}) endif(BUILD_SHARED_LIBS) if(NOT C_ADDITIONAL_FLAGS STREQUAL "") set_target_properties(${LIBRARY_NAME}_static PROPERTIES COMPILE_FLAGS ${C_ADDITIONAL_FLAGS}) endif() # # On macOS, build libpcap for the appropriate architectures, if # CMAKE_OSX_ARCHITECTURES isn't set (if it is, let that control the # architectures for which to build it). # if(APPLE AND "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "") # # Get the major version of Darwin. # string(REGEX MATCH "^([0-9]+)" SYSTEM_VERSION_MAJOR "${CMAKE_SYSTEM_VERSION}") if(SYSTEM_VERSION_MAJOR LESS 8) # # Pre-Tiger. Build only for 32-bit PowerPC. # set(OSX_LIBRARY_ARCHITECTURES "ppc") elseif(SYSTEM_VERSION_MAJOR EQUAL 8) # # Tiger. Is this prior to, or with, Intel support? # # Get the minor version of Darwin. # string(REPLACE "${SYSTEM_VERSION_MAJOR}." "" SYSTEM_MINOR_AND_PATCH_VERSION ${CMAKE_SYSTEM_VERSION}) string(REGEX MATCH "^([0-9]+)" SYSTEM_VERSION_MINOR "${SYSTEM_MINOR_AND_PATCH_VERSION}") if(SYSTEM_VERSION_MINOR LESS 4) # # Prior to Intel support. Build for 32-bit PowerPC and 64-bit PowerPC, # with 32-bit PowerPC first. (I'm guessing that's what Apple does.) # set(OSX_LIBRARY_ARCHITECTURES "ppc;ppc64") elseif(SYSTEM_VERSION_MINOR LESS 7) # # With Intel support but prior to x86-64 support. Build for 32-bit # PowerPC, 64-bit PowerPC, and 32-bit x86, with 32-bit PowerPC first. (I'm # guessing that's what Apple does.) # set(OSX_LIBRARY_ARCHITECTURES "ppc;ppc64;i386") else() # # With Intel support including x86-64 support. Build for 32-bit PowerPC, # 64-bit PowerPC, 32-bit x86, and x86-64, with 32-bit PowerPC first. (I'm # guessing that's what Apple does.) # set(OSX_LIBRARY_ARCHITECTURES "ppc;ppc64;i386;x86_64") endif() elseif(SYSTEM_VERSION_MAJOR EQUAL 9) # # Leopard. Build for 32-bit PowerPC, 64-bit PowerPC, 32-bit x86, and # x86-64, with 32-bit PowerPC first. (That's what Apple does.) # set(OSX_LIBRARY_ARCHITECTURES "ppc;ppc64;i386;x86_64") elseif(SYSTEM_VERSION_MAJOR EQUAL 10) # # Snow Leopard. Build for x86-64, 32-bit x86, and 32-bit PowerPC, with # x86-64 first. (That's what Apple does, even though Snow Leopard doesn't # run on PPC, so PPC libpcap runs under Rosetta, and Rosetta doesn't support # BPF ioctls, so PPC programs can't do live captures.) # set(OSX_LIBRARY_ARCHITECTURES "x86_64;i386;ppc") else() # # Post-Snow Leopard. Build for x86-64 and 32-bit x86, with x86-64 first. # (That's what Apple does) XXX - update if and when Apple drops support for # 32-bit x86 code and if and when Apple adds ARM-based Macs. (You're on # your own for iOS etc.) # # First, check whether we're building with OpenSSL. If so, don't bother # trying to build fat. # if(HAVE_OPENSSL) set(X86_32_BIT_SUPPORTED NO) set(OSX_LIBRARY_ARCHITECTURES "x86_64") message( WARNING "We're assuming the OpenSSL libraries are 64-bit only, so we're not compiling for 32-bit x86" ) else() # # Now, check whether we *can* build for i386. # cmake_push_check_state() set(CMAKE_REQUIRED_FLAGS "-arch i386") check_c_source_compiles( "int main(void) { return 0; } " X86_32_BIT_SUPPORTED) cmake_pop_check_state() if(X86_32_BIT_SUPPORTED) set(OSX_LIBRARY_ARCHITECTURES "x86_64;i386") else() set(OSX_LIBRARY_ARCHITECTURES "x86_64") # # We can't build fat; suggest that the user install the /usr/include # headers if they want to build fat. # if(SYSTEM_VERSION_MAJOR LESS 18) # # Pre-Mojave; the command-line tools should be sufficient to enable # 32-bit x86 builds. # message( WARNING "Compiling for 32-bit x86 gives an error; try installing the command-line tools" ) else() 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" ) endif() endif() endif() endif() if(BUILD_SHARED_LIBS) set_target_properties( ${LIBRARY_NAME} PROPERTIES OSX_ARCHITECTURES "${OSX_LIBRARY_ARCHITECTURES}") endif(BUILD_SHARED_LIBS) set_target_properties( ${LIBRARY_NAME}_static PROPERTIES OSX_ARCHITECTURES "${OSX_LIBRARY_ARCHITECTURES}") endif() # ############################################################################## # Write out the config.h file # ############################################################################## configure_file(${PROJECT_SOURCE_DIR}/cmakeconfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/pcap_config.h) # ############################################################################## # Write out the grammar.y file # ############################################################################## configure_file(${PROJECT_SOURCE_DIR}/grammar.y.in ${CMAKE_CURRENT_BINARY_DIR}/grammar.y @ONLY) # ############################################################################## # Install pcap library, include files, and man pages # ############################################################################## # # "Define GNU standard installation directories", which actually are also # defined, to some degree, by autotools, and at least some of which are general # UN*X conventions. # include(GNUInstallDirs) set(LIBRARY_NAME_STATIC ${LIBRARY_NAME}_static) function(install_manpage_symlink SOURCE TARGET MANDIR) if(MINGW) # # If we haven't found an ln executable with MinGW, we don't try generating # and installing the man pages, so if we get here, we've found that # executable. set(LINK_COMMAND "\"${LINK_EXECUTABLE}\" \"-s\" \"${SOURCE}\" \"${TARGET}\"") else(MINGW) set(LINK_COMMAND "\"${CMAKE_COMMAND}\" \"-E\" \"create_symlink\" \"${SOURCE}\" \"${TARGET}\"" ) endif(MINGW) install( CODE "message(STATUS \"Symlinking: ${CMAKE_INSTALL_PREFIX}/${MANDIR}/${SOURCE} to ${TARGET}\") execute_process( COMMAND \"${CMAKE_COMMAND}\" \"-E\" \"remove\" \"${TARGET}\" WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/${MANDIR} ) execute_process( COMMAND ${LINK_COMMAND} WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/${MANDIR} RESULT_VARIABLE EXIT_STATUS ) if(NOT EXIT_STATUS EQUAL 0) message(FATAL_ERROR \"Could not create symbolic link from ${CMAKE_INSTALL_PREFIX}/${MANDIR}/${SOURCE} to ${TARGET}\") endif() set(CMAKE_INSTALL_MANIFEST_FILES \${CMAKE_INSTALL_MANIFEST_FILES} ${CMAKE_INSTALL_PREFIX}/${MANDIR}/${TARGET})" ) endfunction(install_manpage_symlink) set(MAN1_NOEXPAND pcap-config.1) set(MAN3PCAP_EXPAND pcap.3pcap.in pcap_compile.3pcap.in pcap_datalink.3pcap.in pcap_dump_open.3pcap.in pcap_get_tstamp_precision.3pcap.in pcap_list_datalinks.3pcap.in pcap_list_tstamp_types.3pcap.in pcap_open_dead.3pcap.in pcap_open_offline.3pcap.in pcap_set_immediate_mode.3pcap.in pcap_set_tstamp_precision.3pcap.in pcap_set_tstamp_type.3pcap.in) set(MAN3PCAP_NOEXPAND pcap_activate.3pcap pcap_breakloop.3pcap pcap_can_set_rfmon.3pcap pcap_close.3pcap pcap_create.3pcap pcap_datalink_name_to_val.3pcap pcap_datalink_val_to_name.3pcap pcap_dump.3pcap pcap_dump_close.3pcap pcap_dump_file.3pcap pcap_dump_flush.3pcap pcap_dump_ftell.3pcap pcap_file.3pcap pcap_fileno.3pcap pcap_findalldevs.3pcap pcap_freecode.3pcap pcap_get_required_select_timeout.3pcap pcap_get_selectable_fd.3pcap pcap_geterr.3pcap pcap_init.3pcap pcap_inject.3pcap pcap_is_swapped.3pcap pcap_lib_version.3pcap pcap_lookupdev.3pcap pcap_lookupnet.3pcap pcap_loop.3pcap pcap_major_version.3pcap pcap_next_ex.3pcap pcap_offline_filter.3pcap pcap_open_live.3pcap pcap_set_buffer_size.3pcap pcap_set_datalink.3pcap pcap_set_promisc.3pcap pcap_set_protocol_linux.3pcap pcap_set_rfmon.3pcap pcap_set_snaplen.3pcap pcap_set_timeout.3pcap pcap_setdirection.3pcap pcap_setfilter.3pcap pcap_setnonblock.3pcap pcap_snapshot.3pcap pcap_stats.3pcap pcap_statustostr.3pcap pcap_strerror.3pcap pcap_tstamp_type_name_to_val.3pcap pcap_tstamp_type_val_to_name.3pcap) set(MANFILE_EXPAND pcap-savefile.manfile.in) set(MANMISC_EXPAND pcap-filter.manmisc.in pcap-linktype.manmisc.in pcap-tstamp.manmisc.in) if(NOT BUILD_SHARED_LIBS) unset(LIBRARY_NAME) endif(NOT BUILD_SHARED_LIBS) if(WIN32) if(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8) # # Install 64-bit code built with MSVC in the x64 subdirectories, as that's # where it expects it to be. # install( TARGETS ${LIBRARY_NAME} ${LIBRARY_NAME_STATIC} RUNTIME DESTINATION bin/x64 LIBRARY DESTINATION lib/x64 ARCHIVE DESTINATION lib/x64) if(NOT MINGW) install( FILES $/${LIBRARY_NAME_STATIC}.pdb DESTINATION bin/x64 OPTIONAL) if(BUILD_SHARED_LIBS) install( FILES $ DESTINATION bin/x64 OPTIONAL) endif(BUILD_SHARED_LIBS) endif(NOT MINGW) else(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8) # # Install 32-bit code, and 64-bit code not built with MSVC in the top-level # directories, as those are where they expect it to be. # install( TARGETS ${LIBRARY_NAME} ${LIBRARY_NAME_STATIC} RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) if(NOT MINGW) install( FILES $/${LIBRARY_NAME_STATIC}.pdb DESTINATION bin OPTIONAL) if(BUILD_SHARED_LIBS) install( FILES $ DESTINATION bin OPTIONAL) endif(BUILD_SHARED_LIBS) endif(NOT MINGW) endif(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8) else(WIN32) install(TARGETS ${LIBRARY_NAME} ${LIBRARY_NAME_STATIC} DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}) endif(WIN32) install(DIRECTORY ${PROJECT_SOURCE_DIR}/pcap/ DESTINATION include/pcap) install(FILES ${PROJECT_SOURCE_DIR}/pcap.h DESTINATION include) install(FILES ${PROJECT_SOURCE_DIR}/pcap-bpf.h DESTINATION include) install(FILES ${PROJECT_SOURCE_DIR}/pcap-namedb.h DESTINATION include) # On UN*X, and on Windows when not using MSVC, generate libpcap.pc and # pcap-config and process man pages and arrange that they be installed. if(NOT MSVC) set(PACKAGE_NAME ${LIBRARY_NAME}) set(prefix ${CMAKE_INSTALL_PREFIX}) set(exec_prefix "\${prefix}") set(includedir "\${prefix}/include") set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}") if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR CMAKE_SYSTEM_NAME STREQUAL "NetBSD" OR CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR CMAKE_SYSTEM_NAME STREQUAL "DragonFly BSD" OR CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "OSF1") # # Platforms where the linker is the GNU linker or accepts command-line # arguments like those the GNU linker accepts. # set(V_RPATH_OPT "-Wl,-rpath,") elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION MATCHES "5[.][0-9.]*") # # SunOS 5.x. # # XXX - this assumes GCC is using the Sun linker, rather than the GNU # linker. # set(V_RPATH_OPT "-Wl,-R,") else() # # No option needed to set the RPATH. # set(V_RPATH_OPT "") endif() set(LIBS "") foreach(LIB ${PCAP_LINK_LIBRARIES}) set(LIBS "${LIBS} -l${LIB}") endforeach(LIB) configure_file(${PROJECT_SOURCE_DIR}/pcap-config.in ${CMAKE_CURRENT_BINARY_DIR}/pcap-config @ONLY) configure_file(${PROJECT_SOURCE_DIR}/libpcap.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libpcap.pc @ONLY) install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/pcap-config DESTINATION bin) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpcap.pc DESTINATION lib/pkgconfig) # # Man pages. # # For each section of the manual for which we have man pages that require # macro expansion, do the expansion. # # If this is MinGW, maybe we have a UN*X-style ln command and maybe we don't. # (No, we do *NOT* require MSYS!) If we don't have it, don't do the man # pages. # if(MINGW) find_program(LINK_EXECUTABLE ln) endif(MINGW) if(UNIX OR (MINGW AND LINK_EXECUTABLE)) set(MAN1 "") foreach(MANPAGE ${MAN1_NOEXPAND}) set(MAN1 ${MAN1} ${PROJECT_SOURCE_DIR}/${MANPAGE}) endforeach(MANPAGE) install(FILES ${MAN1} DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) set(MAN3PCAP "") foreach(MANPAGE ${MAN3PCAP_NOEXPAND}) set(MAN3PCAP ${MAN3PCAP} ${PROJECT_SOURCE_DIR}/${MANPAGE}) endforeach(MANPAGE) foreach(TEMPLATE_MANPAGE ${MAN3PCAP_EXPAND}) string(REPLACE ".in" "" MANPAGE ${TEMPLATE_MANPAGE}) configure_file(${PROJECT_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY) set(MAN3PCAP ${MAN3PCAP} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE}) endforeach(TEMPLATE_MANPAGE) install(FILES ${MAN3PCAP} DESTINATION ${CMAKE_INSTALL_MANDIR}/man3) install_manpage_symlink( pcap_datalink_val_to_name.3pcap pcap_datalink_val_to_description.3pcap ${CMAKE_INSTALL_MANDIR}/man3) install_manpage_symlink( pcap_datalink_val_to_name.3pcap pcap_datalink_val_to_description_or_dlt.3pcap ${CMAKE_INSTALL_MANDIR}/man3) install_manpage_symlink(pcap_dump_open.3pcap pcap_dump_fopen.3pcap ${CMAKE_INSTALL_MANDIR}/man3) install_manpage_symlink(pcap_findalldevs.3pcap pcap_freealldevs.3pcap ${CMAKE_INSTALL_MANDIR}/man3) install_manpage_symlink(pcap_geterr.3pcap pcap_perror.3pcap ${CMAKE_INSTALL_MANDIR}/man3) install_manpage_symlink(pcap_inject.3pcap pcap_sendpacket.3pcap ${CMAKE_INSTALL_MANDIR}/man3) install_manpage_symlink(pcap_list_datalinks.3pcap pcap_free_datalinks.3pcap ${CMAKE_INSTALL_MANDIR}/man3) install_manpage_symlink( pcap_list_tstamp_types.3pcap pcap_free_tstamp_types.3pcap ${CMAKE_INSTALL_MANDIR}/man3) install_manpage_symlink(pcap_loop.3pcap pcap_dispatch.3pcap ${CMAKE_INSTALL_MANDIR}/man3) install_manpage_symlink(pcap_major_version.3pcap pcap_minor_version.3pcap ${CMAKE_INSTALL_MANDIR}/man3) install_manpage_symlink(pcap_next_ex.3pcap pcap_next.3pcap ${CMAKE_INSTALL_MANDIR}/man3) install_manpage_symlink( pcap_open_dead.3pcap pcap_open_dead_with_tstamp_precision.3pcap ${CMAKE_INSTALL_MANDIR}/man3) install_manpage_symlink( pcap_open_offline.3pcap pcap_open_offline_with_tstamp_precision.3pcap ${CMAKE_INSTALL_MANDIR}/man3) install_manpage_symlink(pcap_open_offline.3pcap pcap_fopen_offline.3pcap ${CMAKE_INSTALL_MANDIR}/man3) install_manpage_symlink( pcap_open_offline.3pcap pcap_fopen_offline_with_tstamp_precision.3pcap ${CMAKE_INSTALL_MANDIR}/man3) install_manpage_symlink( pcap_tstamp_type_val_to_name.3pcap pcap_tstamp_type_val_to_description.3pcap ${CMAKE_INSTALL_MANDIR}/man3) install_manpage_symlink(pcap_setnonblock.3pcap pcap_getnonblock.3pcap ${CMAKE_INSTALL_MANDIR}/man3) set(MANFILE "") foreach(TEMPLATE_MANPAGE ${MANFILE_EXPAND}) string(REPLACE ".manfile.in" ".${MAN_FILE_FORMATS}" MANPAGE ${TEMPLATE_MANPAGE}) configure_file(${PROJECT_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY) set(MANFILE ${MANFILE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE}) endforeach(TEMPLATE_MANPAGE) install(FILES ${MANFILE} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_FILE_FORMATS}) set(MANMISC "") foreach(TEMPLATE_MANPAGE ${MANMISC_EXPAND}) string(REPLACE ".manmisc.in" ".${MAN_MISC_INFO}" MANPAGE ${TEMPLATE_MANPAGE}) configure_file(${PROJECT_SOURCE_DIR}/${TEMPLATE_MANPAGE} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE} @ONLY) set(MANMISC ${MANMISC} ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE}) endforeach(TEMPLATE_MANPAGE) install(FILES ${MANMISC} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${MAN_MISC_INFO}) endif(UNIX OR (MINGW AND LINK_EXECUTABLE)) endif(NOT MSVC)