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