]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Detect OS IPv6 support using AF_INET6 only. 1036/head
authorDenis Ovsienko <[email protected]>
Tue, 21 Feb 2023 08:02:28 +0000 (08:02 +0000)
committerDenis Ovsienko <[email protected]>
Wed, 22 Feb 2023 20:05:58 +0000 (20:05 +0000)
tcpdump source code has not been using struct in6_addr since commit
0c9cfdc in 2019, so lose the conditional structure declaration, which is
a no-op.

Since commit de7c619 in 2015 netdissect-stdinc.h on Windows defines
HAVE_OS_IPV6_SUPPORT if AF_INET6 if defined, which makes it equivalent
to AF_INET6.  On Unix-like systems taking struct in6_addr out of scope
would make HAVE_OS_IPV6_SUPPORT equivalent to AF_INET6, thus after
removing struct in6_addr remove HAVE_OS_IPV6_SUPPORT together with
Autoconf and CMake checks that define it.  Leave an unrelated CMake
workaround in place for later debugging.

On Windows do not define AF_INET6 if it is not defined, which makes
AF_INET6 a universal indicator of the OS IPv6 support on all supported
OSes.  The few remaining use cases that genuinely need AF_INET6 use it
to make OS API calls, so if the macro is not defined, it most likely
means such an API call in the best case would return just a well-formed
error status.  With this in mind, in win32_gethostbyaddr() and
ip6addr_string() guard all IPv6-specific code with #ifdef AF_INET6.  In
tcpdump.c add a comment to note why a guard is not required for
Casper-specific conditional code that uses AF_INET6.

This way when the OS does not support IPv6, IPv6 addresses will not
resolve to names, which is expected.  Other than that, tcpdump should be
able to process IPv6 addresses the usual way regardless if the OS would
be able to process the packets with these addresses.

CHANGES
CMakeLists.txt
addrtoname.c
cmakeconfig.h.in
configure.ac
netdissect-stdinc.h
tcpdump.c

diff --git a/CHANGES b/CHANGES
index 75929a20e4dd8aecdc9b4d18e9efe676834872ce..8af3559d05a6a56ce59568bd3eba321a733b7233 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -48,6 +48,7 @@ DayOfTheWeek, Month DD, YYYY / The Tcpdump Group
       At build time require a proof of suitable snprintf(3) implementation in
         libc (and document Solaris 9 as unsupported because of that).
       Autoconf: Remove detection of early IPv6 stacks.
+      Detect OS IPv6 support using AF_INET6 only.
 
 DayOfTheWeek, Month DD, YYYY / The Tcpdump Group
   Summary for 4.99.4 tcpdump release (so far!)
index 6e530e7b11b0b5f9a39390be3bbda2855721b540..fa865703b6c49bb84fca4d9d67703814f40d482f 100644 (file)
@@ -633,22 +633,10 @@ cmake_pop_check_state()
 #
 
 #
-# Check for IPv6 support.
-# We just check for AF_INET6 and struct in6_addr.
+# FIXME: This check does not influence the build logic, but without it CMake
+# 3.18.4 fails trying to make the next check_type_size() check later on.
 #
-cmake_push_check_state()
-if(WIN32)
-    set(CMAKE_EXTRA_INCLUDE_FILES sys/types.h ws2tcpip.h)
-    check_symbol_exists(AF_INET6 "sys/types.h;ws2tcpip.h" HAVE_AF_INET6)
-else(WIN32)
-    set(CMAKE_EXTRA_INCLUDE_FILES sys/types.h sys/socket.h netinet/in.h)
-    check_symbol_exists(AF_INET6 "sys/types.h;sys/socket.h;netinet/in.h" HAVE_AF_INET6)
-endif(WIN32)
 check_type_size("struct in6_addr" HAVE_STRUCT_IN6_ADDR)
-cmake_pop_check_state()
-if(HAVE_AF_INET6 AND HAVE_STRUCT_IN6_ADDR)
-    set(HAVE_OS_IPV6_SUPPORT TRUE)
-endif(HAVE_AF_INET6 AND HAVE_STRUCT_IN6_ADDR)
 
 ######################################
 # External dependencies
index 914665c2315a2d8b8fed7bdf1b6c2a4edb8692ab..b83d1ee2500f2283f9aa11d051b0e73d526df053 100644 (file)
@@ -148,14 +148,15 @@ win32_gethostbyaddr(const char *addr, int len, int type)
        static struct hostent host;
        static char hostbuf[NI_MAXHOST];
        char hname[NI_MAXHOST];
-       struct sockaddr_in6 addr6;
 
        host.h_name = hostbuf;
        switch (type) {
        case AF_INET:
                return gethostbyaddr(addr, len, type);
                break;
-       case AF_INET6:
+#ifdef AF_INET6
+       case AF_INET6: {
+               struct sockaddr_in6 addr6;
                memset(&addr6, 0, sizeof(addr6));
                addr6.sin6_family = AF_INET6;
                memcpy(&addr6.sin6_addr, addr, len);
@@ -167,6 +168,8 @@ win32_gethostbyaddr(const char *addr, int len, int type)
                        return &host;
                }
                break;
+       }
+#endif /* AF_INET6 */
        default:
                return NULL;
        }
@@ -358,6 +361,7 @@ ip6addr_string(netdissect_options *ndo, const u_char *ap)
        /*
         * Do not print names if -n was given.
         */
+#ifdef AF_INET6
        if (!ndo->ndo_nflag) {
 #ifdef HAVE_CASPER
                if (capdns != NULL) {
@@ -383,6 +387,7 @@ ip6addr_string(netdissect_options *ndo, const u_char *ap)
                        return (p->name);
                }
        }
+#endif /* AF_INET6 */
        cp = addrtostr6(ap, ntop_buf, sizeof(ntop_buf));
        p->name = strdup(cp);
        if (p->name == NULL)
index 05df2d2763a4ccec2bbb04ae6422293390718ba1..58450a8ae418b993412cab469eead320d216fb82 100644 (file)
@@ -78,9 +78,6 @@
 /* Define to 1 if you have the <openssl/evp.h> header file. */
 #cmakedefine HAVE_OPENSSL_EVP_H 1
 
-/* define if the OS provides AF_INET6 and struct in6_addr */
-#cmakedefine HAVE_OS_IPV6_SUPPORT 1
-
 /* if there's an os_proto.h for this platform, to use additional prototypes */
 #cmakedefine HAVE_OS_PROTO_H 1
 
index 2b12f58f8da989b121e164e8318c4b215e332167..ee26ffc0adc0e5c3d4a8942747c159052d63fc9c 100644 (file)
@@ -261,47 +261,6 @@ fi
 #
 AC_LBL_LIBRARY_NET
 
-#
-# Check whether AF_INET6 and struct in6_addr are defined.
-# If they aren't both defined, we don't have sufficient OS
-# support for IPv6, so we don't look for IPv6 support libraries,
-# and we define AF_INET6 and struct in6_addr ourselves.
-#
-AC_MSG_CHECKING([whether the operating system supports IPv6])
-AC_COMPILE_IFELSE(
-    [
-      AC_LANG_SOURCE(
-       [[
-#include <string.h>
-/* AF_INET6 available check */
-#include <sys/types.h>
-#ifdef _WIN32
-#include <ws2tcpip.h>
-#else
-#include <sys/socket.h>
-#include <netinet/in.h>
-#endif
-#ifdef AF_INET6
-void
-foo(struct in6_addr *addr)
-{
- memset(addr, 0, sizeof (struct in6_addr));
-}
-#else
-#error "AF_INET6 not defined"
-#endif
-       ]])
-    ],
-    [
-       AC_MSG_RESULT(yes)
-       AC_DEFINE(HAVE_OS_IPV6_SUPPORT, 1,
-           [define if the OS provides AF_INET6 and struct in6_addr])
-    ],
-    [
-       AC_MSG_RESULT(no)
-    ]
-)
-
 AC_REPLACE_FUNCS(strlcat strlcpy strsep getservent getopt_long)
 AC_CHECK_FUNCS(fork vfork)
 AC_CHECK_FUNCS(setlinebuf)
index e81c90bd590b080dfb3f66ef24dfc5ae982d90b8..baf5dd8fd3a3c69cbc25d43d70734565ff0acb1e 100644 (file)
 #define inline __inline
 #endif
 
-#if defined(AF_INET6) && !defined(HAVE_OS_IPV6_SUPPORT)
-#define HAVE_OS_IPV6_SUPPORT
-#endif
-
 #ifndef INET6_ADDRSTRLEN
 #define INET6_ADDRSTRLEN 46
 #endif
@@ -319,28 +315,6 @@ typedef char *caddr_t;
   }
 #endif
 
-/*
- * If the OS doesn't define AF_INET6 and struct in6_addr:
- *
- * define AF_INET6, so we can use it internally as a "this is an
- * IPv6 address" indication;
- *
- * define struct in6_addr so that we can use it for IPv6 addresses.
- */
-#ifndef HAVE_OS_IPV6_SUPPORT
-#ifndef AF_INET6
-#define AF_INET6       24
-
-struct in6_addr {
-       union {
-               __uint8_t   __u6_addr8[16];
-               __uint16_t  __u6_addr16[8];
-               __uint32_t  __u6_addr32[4];
-       } __u6_addr;                    /* 128-bit IP6 address */
-};
-#endif
-#endif
-
 #ifndef NI_MAXHOST
 #define        NI_MAXHOST      1025
 #endif
index 7538a49c3ca2944ccfcdaf9aa32fe221622a8946..726245402ee8e4b66ecbe371b79c2539480ceede 100644 (file)
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -916,6 +916,7 @@ capdns_setup(void)
        if (cap_dns_type_limit(capdnsloc, types, 1) < 0)
                error("unable to limit access to system.dns service");
        families[0] = AF_INET;
+       /* Casper is a feature of FreeBSD, which defines AF_INET6. */
        families[1] = AF_INET6;
        if (cap_dns_family_limit(capdnsloc, families, 2) < 0)
                error("unable to limit access to system.dns service");