Home | History | Annotate | Download | only in libpcap
      1 cmake_minimum_required( VERSION 2.8.8 )
      2 
      3 project( pcap )
      4 #
      5 # Call the library "wpcap" on Windows, for backwards compatibility.
      6 #
      7 if( WIN32 )
      8     set( LIBRARY_NAME wpcap )
      9 else()
     10     set( LIBRARY_NAME pcap )
     11 endif()
     12 
     13 ###################################################################
     14 #   Parameters
     15 ###################################################################
     16 
     17 option (INET6 "Enable IPv6" ON)
     18 if( MSVC )
     19     option (USE_STATIC_RT "Use static Runtime" ON)
     20 endif( MSVC )
     21 option (BUILD_SHARED_LIBS "Build shared libraries" ON)
     22 if( WIN32 )
     23     set(PACKET_DLL_DIR "" CACHE PATH "Path to directory with include and lib subdirectories for packet.dll")
     24 endif( WIN32 )
     25 
     26 #
     27 # XXX - this should be an option, defaulting to "yes" for Windows and to
     28 # "no", for now, on UN*X.
     29 #
     30 if( WIN32 )
     31     set( HAVE_REMOTE 1 )
     32 endif( WIN32 )
     33 
     34 ######################################
     35 # Project settings
     36 ######################################
     37 
     38 add_definitions( -DHAVE_CONFIG_H )
     39 
     40 include_directories(
     41     ${CMAKE_CURRENT_BINARY_DIR}
     42     ${pcap_SOURCE_DIR}
     43 )
     44 
     45 if( WIN32 )
     46     if( NOT "${PACKET_DLL_DIR}" STREQUAL "" )
     47         include_directories("${PACKET_DLL_DIR}/Include")
     48         if( CMAKE_CL_64 )
     49             link_directories("${PACKET_DLL_DIR}/Lib/x64")
     50         else( CMAKE_CL_64 )
     51             link_directories("${PACKET_DLL_DIR}/Lib")
     52         endif( CMAKE_CL_64 )
     53     endif()
     54     include_directories(
     55         ../Common/
     56         Win32/Include
     57     )
     58 endif( WIN32)
     59 
     60 add_definitions( -DBUILDING_PCAP )
     61 
     62 if( MSVC )
     63     add_definitions( -D__STDC__ )
     64     add_definitions( -D_CRT_SECURE_NO_WARNINGS )
     65     add_definitions( "-D_U_=" )
     66 elseif( CMAKE_COMPILER_IS_GNUCXX )
     67     add_definitions( "-D_U_=__attribute__((unused))" )
     68 else(MSVC)
     69     add_definitions( "-D_U_=" )
     70 endif( MSVC )
     71 
     72 if( MSVC )
     73     if (USE_STATIC_RT)
     74         MESSAGE( STATUS "Use STATIC runtime" )
     75         set(NAME_RT MT)
     76         set (CMAKE_CXX_FLAGS_MINSIZEREL     "${CMAKE_CXX_FLAGS_MINSIZEREL} /MT")
     77         set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MT")
     78         set (CMAKE_CXX_FLAGS_RELEASE        "${CMAKE_CXX_FLAGS_RELEASE} /MT")
     79         set (CMAKE_CXX_FLAGS_DEBUG          "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
     80 
     81         set (CMAKE_C_FLAGS_MINSIZEREL       "${CMAKE_C_FLAGS_MINSIZEREL} /MT")
     82         set (CMAKE_C_FLAGS_RELWITHDEBINFO   "${CMAKE_C_FLAGS_RELWITHDEBINFO} /MT")
     83         set (CMAKE_C_FLAGS_RELEASE          "${CMAKE_C_FLAGS_RELEASE} /MT")
     84         set (CMAKE_C_FLAGS_DEBUG            "${CMAKE_C_FLAGS_DEBUG} /MTd")
     85     else (USE_STATIC_RT)
     86         MESSAGE( STATUS "Use DYNAMIC runtime" )
     87         set(NAME_RT MD)
     88         set (CMAKE_CXX_FLAGS_MINSIZEREL     "${CMAKE_CXX_FLAGS_MINSIZEREL} /MD")
     89         set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MD")
     90         set (CMAKE_CXX_FLAGS_RELEASE        "${CMAKE_CXX_FLAGS_RELEASE} /MD")
     91         set (CMAKE_CXX_FLAGS_DEBUG          "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
     92 
     93         set (CMAKE_C_FLAGS_MINSIZEREL       "${CMAKE_C_FLAGS_MINSIZEREL} /MD")
     94         set (CMAKE_C_FLAGS_RELWITHDEBINFO   "${CMAKE_C_FLAGS_RELWITHDEBINFO} /MD")
     95         set (CMAKE_C_FLAGS_RELEASE          "${CMAKE_C_FLAGS_RELEASE} /MD")
     96         set (CMAKE_C_FLAGS_DEBUG            "${CMAKE_C_FLAGS_DEBUG} /MDd")
     97    endif (USE_STATIC_RT)
     98 endif( MSVC )
     99 
    100 ###################################################################
    101 #   Detect available platform features
    102 ###################################################################
    103 
    104 include(CheckIncludeFile)
    105 include(CheckFunctionExists)
    106 include(CheckStructHasMember)
    107 include(CheckTypeSize)
    108 
    109 #
    110 # Header files.
    111 #
    112 check_include_file( inttypes.h HAVE_INTTYPES_H )
    113 check_include_file( stdint.h HAVE_STDINT_H )
    114 check_include_file( unistd.h HAVE_UNISTD_H )
    115 if( NOT HAVE_UNISTD_H )
    116     add_definitions( -DYY_NO_UNISTD_H )
    117 endif( NOT HAVE_UNISTD_H )
    118 check_include_file( bitypes.h HAVE_SYS_BITYPES_H )
    119 check_include_file( limits.h HAVE_LIMITS_H )
    120 
    121 #
    122 # Functions.
    123 #
    124 check_function_exists( strerror HAVE_STRERROR )
    125 check_function_exists( strlcpy HAVE_STRLCPY )
    126 check_function_exists( snprintf HAVE_SNPRINTF )
    127 check_function_exists( vsnprintf HAVE_VSNPRINTF )
    128 check_function_exists( strtok_r HAVE_STRTOK_R )
    129 
    130 if (WIN32)
    131     #
    132     # Check for Windows-only functions, such as packet.dll functions.
    133     #
    134     check_function_exists( PacketIsLoopbackAdapter HAVE_PACKET_IS_LOOPBACK_ADAPTER )
    135 endif()
    136 
    137 #
    138 # Data types.
    139 #
    140 # XXX - there's no check_struct() macro that's like check_struct_has_member()
    141 # except that it only checks for the existence of the structure type,
    142 # so we use check_struct_has_member() and look for ss_family.
    143 #
    144 check_struct_has_member("struct sockaddr_storage" ss_family sys/socket.h  HAVE_SOCKADDR_STORAGE)
    145 set(CMAKE_EXTRA_INCLUDE_FILES unistd.h sys/socket.h)
    146 check_type_size("socklen_t" SOCKLEN_T)
    147 set(CMAKE_EXTRA_INCLUDE_FILES unistd.h)
    148 
    149 #
    150 # Structure fields.
    151 #
    152 check_struct_has_member("struct sockaddr" sa_len sys/socket.h HAVE_SOCKADDR_SA_LEN )
    153 
    154 if( INET6 )
    155     MESSAGE( STATUS "Use IPv6" )
    156 endif( INET6 )
    157 
    158 if( WIN32 )
    159     add_definitions( -DHAVE_ADDRINFO )
    160 endif( WIN32 )
    161 
    162 ######################################
    163 # External dependencies
    164 ######################################
    165 
    166 ######################################
    167 # Input files
    168 ######################################
    169 
    170 set(PROJECT_SOURCE_LIST_C
    171     bpf_dump.c
    172     bpf_image.c
    173     etherent.c
    174     fad-helpers.c
    175     gencode.c
    176     inet.c
    177     nametoaddr.c
    178     optimize.c
    179     pcap-common.c
    180     pcap.c
    181     savefile.c
    182     sf-pcap-ng.c
    183     sf-pcap.c
    184     bpf/net/bpf_filter.c
    185 )
    186 
    187 if( WIN32 )
    188     set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/win_snprintf.c )
    189 else()
    190     if( NOT HAVE_SNPRINTF )
    191         set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/snprintf.c )
    192     endif( NOT HAVE_SNPRINTF )
    193     if( NOT HAVE_STRTOK_R )
    194         set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/strtok_r.c )
    195     endif( NOT HAVE_STRTOK_R )
    196 endif( WIN32 )
    197 
    198 if( HAVE_REMOTE )
    199     set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C}
    200         pcap-new.c pcap-rpcap.c sockutils.c)
    201 endif( HAVE_REMOTE )
    202 
    203 #
    204 # Determine the main pcap-XXX.c file to use.
    205 #
    206 if( WIN32 )
    207     #
    208     # WinPcap.
    209     #
    210     set( PCAP_TYPE win32 )
    211 else()
    212     #
    213     # UN*X - figure out what type of packet capture mechanism we
    214     # have.
    215     #
    216     if( EXISTS /dev/bpf )
    217 	#
    218 	# Cloning BPF device.
    219 	#
    220 	set( PCAP_TYPE bpf )
    221 	AC_DEFINE(HAVE_CLONING_BPF,1,[define if you have a cloning BPF device])
    222     elseif( EXISTS /dev/bpf0 )
    223 	set( PCAP_TYPE bpf )
    224 
    225         #
    226         # XXX - many more BPF checks.
    227         #
    228     elseif( EXISTS /usr/include/net/pfilt.h )
    229         #
    230         # DEC OSF/1, Digital UNIX, Tru64 UNIX
    231         #
    232 	set( PCAP_TYPE pf )
    233     elseif( EXISTS /dev/enet )
    234         set( PCAP_TYPE enet )
    235     elseif( EXISTS /dev/nit )
    236         set( PCAP_TYPE snit )
    237     elseif( EXISTS /usr/include/sys/net/nit.h )
    238         set( PCAP_TYPE nit )
    239     elseif( EXISTS /usr/include/linux/socket.h )
    240         set( PCAP_TYPE linux )
    241 
    242 	#
    243 	# Do we have the wireless extensions?
    244 	#
    245         check_include_file( linux/wireless.h HAVE_LINUX_WIRELESS_H )
    246 
    247         #
    248         # XXX - many more Linux checks.
    249 	#
    250     elseif( EXISTS /usr/include/net/raw.h )
    251         set( PCAP_TYPE snoop )
    252     elseif( EXISTS /usr/include/odmi.h )
    253         #
    254         # On AIX, the BPF devices might not yet be present - they're
    255         # created the first time libpcap runs after booting.
    256         # We check for odmi.h instead.
    257         #
    258         set( PCAP_TYPE bpf )
    259     elseif( /usr/include/sys/dlpi.h )
    260         set( PCAP_TYPE dlpi )
    261 
    262         #
    263         # XXX - many more DLPI checks.
    264         #
    265     else()
    266 	set( PCAP_TYPE null )
    267     endif()
    268 endif( WIN32 )
    269 message(STATUS "Packet capture mechanism type: ${PCAP_TYPE}")
    270 set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-${PCAP_TYPE}.c)
    271 
    272 #
    273 # Now figure out how we get a list of interfaces and addresses,
    274 # if we support capturing.  Don't bother if we don't support
    275 # capturing.
    276 #
    277 if( NOT WIN32 )
    278     #
    279     # UN*X - figure out what type of interface list mechanism we
    280     # have.
    281     #
    282     if( ${PCAP_TYPE} STREQUAL "null" )
    283         #
    284         # We can't capture, so we can't open any capture
    285         # devices, so we won't return any interfaces.
    286         #
    287         set( FINDALLDEVS_TYPE null )
    288     else()
    289         check_function_exists( getifaddrs HAVE_GETIFADDRS )
    290         if( ${HAVE_GETIFADDRS} )
    291             #
    292             # We have "getifaddrs()"; make sure we have <ifaddrs.h>
    293             # as well, just in case some platform is really weird.
    294             #
    295             check_include_file( ifaddrs.h HAVE_IFADDRS_H )
    296             if( ${HAVE_IFADDRS_H} )
    297                 #
    298                 # We have the header, so we use "getifaddrs()" to
    299                 # get the list of interfaces.
    300                 #
    301                 set( FINDALLDEVS_TYPE getad )
    302             else()
    303                 #
    304                 # We don't have the header - give up.
    305                 # XXX - we could also fall back on some other
    306                 # mechanism, but, for now, this'll catch this
    307                 # problem so that we can at least try to figure
    308                 # out something to do on systems with "getifaddrs()"
    309                 # but without "ifaddrs.h", if there is something
    310                 # we can do on those systems.
    311                 #
    312                 message(FATAL_ERROR "Your system has getifaddrs() but doesn't have a usable <ifaddrs.h>." )
    313             endif()
    314         else()
    315             #
    316             # Well, we don't have "getifaddrs()", so we have to use
    317             # some other mechanism; determine what that mechanism is.
    318             #
    319             # The first thing we use is the type of capture mechanism,
    320             # which is somewhat of a proxy for the OS we're using.
    321             #
    322             if( ${PCAP_TYPE} STREQUAL "dlpi" OR ${PCAP_TYPE} STREQUAL "libdlpi" )
    323                 #
    324                 # This might be Solaris 8 or later, with
    325                 # SIOCGLIFCONF, or it might be some other OS
    326                 # or some older version of Solaris, with
    327                 # just SIOCGIFCONF.
    328                 #
    329                 try_compile( HAVE_SIOCGLIFCONF ${CMAKE_CURRENT_BINARY_DIR} "${pcap_SOURCE_DIR}/config/have_siocglifconf.c"  )
    330                 message( STATUS "HAVE_SIOCGLIFCONF = ${HAVE_SIOCGLIFCONF}" )
    331                 if( HAVE_SIOCGLIFCONF )
    332                     set( FINDALLDEVS_TYPE glifc )
    333                 else()
    334                     set( FINDALLDEVS_TYPE gifc )
    335                 endif()
    336             else()
    337                 #
    338                 # Assume we just have SIOCGIFCONF.
    339                 # (XXX - on at least later Linux kernels, there's
    340                 # another mechanism, and we should be using that
    341                 # instead.)
    342                 #
    343                 set( FINDALLDEVS_TYPE gifc )
    344             endif()
    345         endif()
    346     endif()
    347     message(STATUS "Find-interfaces mechanism type: ${FINDALLDEVS_TYPE}")
    348     set( PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} fad-${FINDALLDEVS_TYPE}.c )
    349 endif()
    350 
    351 file(GLOB PROJECT_SOURCE_LIST_CORE_H
    352     *.h
    353     pcap/*.h
    354 )
    355 set( PROJECT_SOURCE_LIST_H ${PROJECT_SOURCE_LIST_H} ${PROJECT_SOURCE_LIST_CORE_H} )
    356 
    357 if( WIN32 )
    358     file(GLOB PROJECT_SOURCE_LIST_WIN32_H
    359         Win32/Include/*.h
    360     )
    361     set( PROJECT_SOURCE_LIST_H ${PROJECT_SOURCE_LIST_H} ${PROJECT_SOURCE_LIST_WIN32_H} )
    362 endif( WIN32 )
    363 
    364 #
    365 # {Flex} and YACC/Berkeley YACC/Bison.
    366 # From a mail message to the CMake mailing list by Andy Cedilnik of
    367 # Kitware.
    368 #
    369 
    370 #
    371 # Try to find Flex, a Windows version of Flex, or Lex.
    372 #
    373 find_program(LEX_EXECUTABLE NAMES flex win_flex lex)
    374 if( ${LEX_EXECUTABLE} STREQUAL "LEX_EXECUTABLE-NOTFOUND" )
    375     message(FATAL_ERROR "Neither flex nor win_flex nor lex was found." )
    376 endif()
    377 message(STATUS "Lexical analyzer generator: ${LEX_EXECUTABLE}")
    378 
    379 add_custom_command(
    380     OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/scanner.c ${CMAKE_CURRENT_BINARY_DIR}/scanner.h
    381     SOURCE ${pcap_SOURCE_DIR}/scanner.l
    382     COMMAND ${LEX_EXECUTABLE} -P pcap_ --header-file=scanner.h --nounput -o${CMAKE_CURRENT_BINARY_DIR}/scanner.c ${pcap_SOURCE_DIR}/scanner.l
    383     DEPENDS ${pcap_SOURCE_DIR}/scanner.l
    384 )
    385 
    386 #
    387 # Since scanner.c does not exist yet when cmake is run, mark
    388 # it as generated.
    389 #
    390 # Since scanner.c includes grammar.h, mark that as a dependency.
    391 #
    392 set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/scanner.c PROPERTIES
    393     GENERATED TRUE
    394     OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/scanner.h
    395 )
    396 
    397 #
    398 # Add scanner.c to the list of sources.
    399 #
    400 #set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} ${CMAKE_CURRENT_BINARY_DIR}/scanner.c)
    401 
    402 #
    403 # Try to find YACC or Bison.
    404 #
    405 find_program(YACC_EXECUTABLE NAMES bison win_bison byacc yacc)
    406 if( ${YACC_EXECUTABLE} STREQUAL "YACC_EXECUTABLE-NOTFOUND" )
    407     message(FATAL_ERROR "Neither bison nor win_bison nor byacc nor yacc was found." )
    408 endif()
    409 message(STATUS "Parser generator: ${YACC_EXECUTABLE}")
    410 
    411 #
    412 # Create custom command for the scanner.
    413 # Find out whether it's Bison or notby looking at the last component
    414 # of the path (without a .exe extension, if this is Windows).
    415 #
    416 get_filename_component(YACC_NAME ${YACC_EXECUTABLE} NAME_WE)
    417 if( "${YACC_NAME}" STREQUAL "bison" OR "${YACC_NAME}" STREQUAL "win_bison" )
    418     set( YACC_COMPATIBILITY_FLAG "-y" )
    419 endif()
    420 add_custom_command(
    421     OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/grammar.c ${CMAKE_CURRENT_BINARY_DIR}/grammar.h
    422     SOURCE ${pcap_SOURCE_DIR}/grammar.y
    423     COMMAND ${YACC_EXECUTABLE} ${YACC_COMPATIBILITY_FLAG} -p pcap_ -o ${CMAKE_CURRENT_BINARY_DIR}/grammar.c -d ${pcap_SOURCE_DIR}/grammar.y
    424     DEPENDS ${pcap_SOURCE_DIR}/grammar.y
    425 )
    426 
    427 #
    428 # Since grammar.c does not exists yet when cmake is run, mark
    429 # it as generated.
    430 #
    431 set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/grammar.c PROPERTIES
    432     GENERATED TRUE
    433 )
    434 
    435 #
    436 # Add grammar.c to the list of sources.
    437 #
    438 #set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} ${CMAKE_CURRENT_BINARY_DIR}/grammar.c)
    439 
    440 if( WIN32 )
    441     #
    442     # CMake does not love Windows.
    443     #
    444     file(TO_NATIVE_PATH "${pcap_SOURCE_DIR}/GenVersion.bat" GenVersion_path)
    445     file(TO_NATIVE_PATH "${pcap_SOURCE_DIR}/VERSION" VERSION_path)
    446     file(TO_NATIVE_PATH "${pcap_SOURCE_DIR}/pcap_version.h.in" version_h_in_path)
    447     file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/pcap_version.h" version_h_path)
    448     add_custom_command(
    449         OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pcap_version.h
    450         SOURCE ${pcap_SOURCE_DIR}/VERSION ${pcap_SOURCE_DIR}/pcap_version.h.in
    451         COMMAND ${GenVersion_path} ${VERSION_path} ${version_h_in_path} ${version_h_path}
    452         DEPENDS ${pcap_SOURCE_DIR}/VERSION ${pcap_SOURCE_DIR}/pcap_version.h.in
    453     )
    454 else( WIN32 )
    455     add_custom_command(
    456         OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/version.c
    457         SOURCE ${pcap_SOURCE_DIR}/VERSION
    458         COMMAND ${pcap_SOURCE_DIR}/gen_version_c.sh ${pcap_SOURCE_DIR}/VERSION ${CMAKE_CURRENT_BINARY_DIR}/version.c
    459         DEPENDS ${pcap_SOURCE_DIR}/VERSION
    460     )
    461     add_custom_command(
    462         OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pcap_version.h
    463         SOURCE ${pcap_SOURCE_DIR}/VERSION
    464         COMMAND ${pcap_SOURCE_DIR}/gen_version_header.sh ${pcap_SOURCE_DIR}/VERSION ${pcap_SOURCE_DIR}/pcap_version.h.in ${CMAKE_CURRENT_BINARY_DIR}/pcap_version.h
    465         DEPENDS ${pcap_SOURCE_DIR}/VERSION
    466     )
    467 
    468     #
    469     # Since version.c does not exists yet when cmake is run, mark
    470     # it as generated.
    471     #
    472     set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/version.c PROPERTIES
    473         GENERATED TRUE
    474     )
    475 
    476     #
    477     # Add version.c to the list of sources.
    478     #
    479     set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} ${CMAKE_CURRENT_BINARY_DIR}/version.c)
    480 endif( WIN32 )
    481 
    482 #
    483 # Since pcap_version.h does not exists yet when cmake is run, mark
    484 # it as generated.
    485 #
    486 set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/pcap_version.h PROPERTIES
    487     GENERATED TRUE
    488 )
    489 
    490 #
    491 # Add pcap_version.h to the list of headers.
    492 #
    493 set(PROJECT_SOURCE_LIST_H ${PROJECT_SOURCE_LIST_H} ${CMAKE_CURRENT_BINARY_DIR}/pcap_version.h)
    494 
    495 source_group("Source Files" FILES ${PROJECT_SOURCE_LIST_C})
    496 source_group("Header Files" FILES ${PROJECT_SOURCE_LIST_H})
    497 
    498 ######################################
    499 # Register targets
    500 ######################################
    501 
    502 add_library(${LIBRARY_NAME}
    503     ${PROJECT_SOURCE_LIST_C}
    504     ${CMAKE_CURRENT_BINARY_DIR}/grammar.c
    505     ${CMAKE_CURRENT_BINARY_DIR}/scanner.c
    506     ${PROJECT_SOURCE_LIST_H}
    507 )
    508 
    509 if( WIN32 )
    510     target_link_libraries ( ${LIBRARY_NAME}
    511         packet
    512         ws2_32
    513     )
    514 endif( WIN32 )
    515 
    516 ######################################
    517 # Write out the config.h file
    518 ######################################
    519 
    520 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmakeconfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
    521