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