• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1cmake_minimum_required( VERSION 2.8.8 )
2
3project( pcap )
4#
5# Call the library "wpcap" on Windows, for backwards compatibility.
6#
7if( WIN32 )
8    set( LIBRARY_NAME wpcap )
9else()
10    set( LIBRARY_NAME pcap )
11endif()
12
13###################################################################
14#   Parameters
15###################################################################
16
17option (INET6 "Enable IPv6" ON)
18if( MSVC )
19    option (USE_STATIC_RT "Use static Runtime" ON)
20endif( MSVC )
21option (BUILD_SHARED_LIBS "Build shared libraries" ON)
22if( WIN32 )
23    set(PACKET_DLL_DIR "" CACHE PATH "Path to directory with include and lib subdirectories for packet.dll")
24endif( 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#
30if( WIN32 )
31    set( HAVE_REMOTE 1 )
32endif( WIN32 )
33
34######################################
35# Project settings
36######################################
37
38add_definitions( -DHAVE_CONFIG_H )
39
40include_directories(
41    ${CMAKE_CURRENT_BINARY_DIR}
42    ${pcap_SOURCE_DIR}
43)
44
45if( 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    )
58endif( WIN32)
59
60add_definitions( -DBUILDING_PCAP )
61
62if( MSVC )
63    add_definitions( -D__STDC__ )
64    add_definitions( -D_CRT_SECURE_NO_WARNINGS )
65    add_definitions( "-D_U_=" )
66elseif( CMAKE_COMPILER_IS_GNUCXX )
67    add_definitions( "-D_U_=__attribute__((unused))" )
68else(MSVC)
69    add_definitions( "-D_U_=" )
70endif( MSVC )
71
72if( 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)
98endif( MSVC )
99
100###################################################################
101#   Detect available platform features
102###################################################################
103
104include(CheckIncludeFile)
105include(CheckFunctionExists)
106include(CheckStructHasMember)
107include(CheckTypeSize)
108
109#
110# Header files.
111#
112check_include_file( inttypes.h HAVE_INTTYPES_H )
113check_include_file( stdint.h HAVE_STDINT_H )
114check_include_file( unistd.h HAVE_UNISTD_H )
115if( NOT HAVE_UNISTD_H )
116    add_definitions( -DYY_NO_UNISTD_H )
117endif( NOT HAVE_UNISTD_H )
118check_include_file( bitypes.h HAVE_SYS_BITYPES_H )
119check_include_file( limits.h HAVE_LIMITS_H )
120
121#
122# Functions.
123#
124check_function_exists( strerror HAVE_STRERROR )
125check_function_exists( strlcpy HAVE_STRLCPY )
126check_function_exists( snprintf HAVE_SNPRINTF )
127check_function_exists( vsnprintf HAVE_VSNPRINTF )
128check_function_exists( strtok_r HAVE_STRTOK_R )
129
130if (WIN32)
131    #
132    # Check for Windows-only functions, such as packet.dll functions.
133    #
134    check_function_exists( PacketIsLoopbackAdapter HAVE_PACKET_IS_LOOPBACK_ADAPTER )
135endif()
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#
144check_struct_has_member("struct sockaddr_storage" ss_family sys/socket.h  HAVE_SOCKADDR_STORAGE)
145set(CMAKE_EXTRA_INCLUDE_FILES unistd.h sys/socket.h)
146check_type_size("socklen_t" SOCKLEN_T)
147set(CMAKE_EXTRA_INCLUDE_FILES unistd.h)
148
149#
150# Structure fields.
151#
152check_struct_has_member("struct sockaddr" sa_len sys/socket.h HAVE_SOCKADDR_SA_LEN )
153
154if( INET6 )
155    MESSAGE( STATUS "Use IPv6" )
156endif( INET6 )
157
158if( WIN32 )
159    add_definitions( -DHAVE_ADDRINFO )
160endif( WIN32 )
161
162######################################
163# External dependencies
164######################################
165
166######################################
167# Input files
168######################################
169
170set(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
187if( WIN32 )
188    set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} missing/win_snprintf.c )
189else()
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 )
196endif( WIN32 )
197
198if( HAVE_REMOTE )
199    set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C}
200        pcap-new.c pcap-rpcap.c sockutils.c)
201endif( HAVE_REMOTE )
202
203#
204# Determine the main pcap-XXX.c file to use.
205#
206if( WIN32 )
207    #
208    # WinPcap.
209    #
210    set( PCAP_TYPE win32 )
211else()
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()
268endif( WIN32 )
269message(STATUS "Packet capture mechanism type: ${PCAP_TYPE}")
270set(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#
277if( 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 )
349endif()
350
351file(GLOB PROJECT_SOURCE_LIST_CORE_H
352    *.h
353    pcap/*.h
354)
355set( PROJECT_SOURCE_LIST_H ${PROJECT_SOURCE_LIST_H} ${PROJECT_SOURCE_LIST_CORE_H} )
356
357if( 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} )
362endif( 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#
373find_program(LEX_EXECUTABLE NAMES flex win_flex lex)
374if( ${LEX_EXECUTABLE} STREQUAL "LEX_EXECUTABLE-NOTFOUND" )
375    message(FATAL_ERROR "Neither flex nor win_flex nor lex was found." )
376endif()
377message(STATUS "Lexical analyzer generator: ${LEX_EXECUTABLE}")
378
379add_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#
392set_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#
405find_program(YACC_EXECUTABLE NAMES bison win_bison byacc yacc)
406if( ${YACC_EXECUTABLE} STREQUAL "YACC_EXECUTABLE-NOTFOUND" )
407    message(FATAL_ERROR "Neither bison nor win_bison nor byacc nor yacc was found." )
408endif()
409message(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#
416get_filename_component(YACC_NAME ${YACC_EXECUTABLE} NAME_WE)
417if( "${YACC_NAME}" STREQUAL "bison" OR "${YACC_NAME}" STREQUAL "win_bison" )
418    set( YACC_COMPATIBILITY_FLAG "-y" )
419endif()
420add_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#
431set_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
440if( 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    )
454else( 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)
480endif( WIN32 )
481
482#
483# Since pcap_version.h does not exists yet when cmake is run, mark
484# it as generated.
485#
486set_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#
493set(PROJECT_SOURCE_LIST_H ${PROJECT_SOURCE_LIST_H} ${CMAKE_CURRENT_BINARY_DIR}/pcap_version.h)
494
495source_group("Source Files" FILES ${PROJECT_SOURCE_LIST_C})
496source_group("Header Files" FILES ${PROJECT_SOURCE_LIST_H})
497
498######################################
499# Register targets
500######################################
501
502add_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
509if( WIN32 )
510    target_link_libraries ( ${LIBRARY_NAME}
511        packet
512        ws2_32
513    )
514endif( WIN32 )
515
516######################################
517# Write out the config.h file
518######################################
519
520configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmakeconfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
521