]> The Tcpdump Group git mirrors - libpcap/commitdiff
Address a few compiler warnings on Haiku. 1172/head
authorDenis Ovsienko <[email protected]>
Sat, 22 Apr 2023 21:18:43 +0000 (22:18 +0100)
committerDenis Ovsienko <[email protected]>
Sun, 23 Apr 2023 16:21:05 +0000 (17:21 +0100)
In gencode.c instead of casting pointer types copy the data to squelch 4
previously known warnings from GCC and Clang.  (Oddly enough, Haiku is
the only OS that unconditionally puts a 32-bit array into the union
inside struct in6_addr, yet the only OS where these warnings appeared.)

In pcap.c add a temporary workaround for ioctl() to squelch two other
Clang warnings:

pcap.c:1619:6: error: missing field 'size' initializer
  [-Werror,-Wmissing-field-initializers]
pcap.c:1638:6: error: missing field 'size' initializer
  [-Werror,-Wmissing-field-initializers]

With these changes GCC builds are now warning-free, so in build.sh set
LIBPCAP_TAINTED for Clang only and update the comment to show the
current remaining warnings.

CHANGES
build.sh
gencode.c
pcap.c

diff --git a/CHANGES b/CHANGES
index 30217e7d2a066447e15125c694938fa20c73dab6..86db3d592c6466e2a9e40840d7772ea1fce57651 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,7 @@ DayOfTheWeek, Month DD, YYYY / The Tcpdump Group
       Remove an always-false pointer test from snf_read().
       Clean up DECnet address handling.
       Finalize moving of bpf_filter.c. (GH #1166)
+      Address a few compiler warnings on Haiku.
     Link-layer types:
       Add LINKTYPE_ETW/DLT_ETW.
       Add LINKTYPE_NETANALYZER_NG/DLT_NETANALYZER_NG (pull request
index 956cfe2fba9c651314656662ebe3c9facf6b1304..110ce251052481799d4120ad50f96316d13856c0 100755 (executable)
--- a/build.sh
+++ b/build.sh
@@ -87,21 +87,16 @@ suncc-5.1[45]/SunOS-5.11)
     # "./filtertest.c", line 281: warning: statement not reached
     LIBPCAP_TAINTED=yes
     ;;
-*/Haiku-*)
-    # (The warnings below come from GCC and Clang in CMake builds after installing
-    # all system updates.)
-    # gencode.c:4143:9: warning: converting a packed 'struct in6_addr' pointer
-    #   (alignment 1) to a 'uint32_t' {aka 'unsigned int'} pointer (alignment 4) may
-    #   result in an unaligned pointer value [-Waddress-of-packed-member]
-    # gencode.c:4144:9: warning: converting a packed 'struct in6_addr' pointer
-    #   (alignment 1) to a 'uint32_t' {aka 'unsigned int'} pointer (alignment 4) may
-    #   result in an unaligned pointer value [-Waddress-of-packed-member]
-    # gencode.c:7189:9: warning: converting a packed 'struct in6_addr' pointer
-    #   (alignment 1) to a 'uint32_t' {aka 'unsigned int'} pointer (alignment 4) may
-    #   result in an unaligned pointer value [-Waddress-of-packed-member]
-    # gencode.c:7190:9: warning: converting a packed 'struct in6_addr' pointer
-    #   (alignment 1) to a 'uint32_t' {aka 'unsigned int'} pointer (alignment 4) may
-    #   result in an unaligned pointer value [-Waddress-of-packed-member]
+clang-*/Haiku-*)
+    # pcap-haiku.c:82:26: error: implicit conversion loses integer precision:
+    #   'ssize_t' (aka 'long') to 'int32_t' (aka 'int')
+    #   [-Werror,-Wshorten-64-to-32]
+    # pcap-haiku.c:88:51: error: implicit conversion loses integer precision:
+    #   'ssize_t' (aka 'long') to 'u_int' (aka 'unsigned int')
+    #   [-Werror,-Wshorten-64-to-32]
+    # pcap-haiku.c:98:15: error: implicit conversion loses integer precision:
+    #   'ssize_t' (aka 'long') to 'bpf_u_int32' (aka 'unsigned int')
+    #   [-Werror,-Wshorten-64-to-32]
     LIBPCAP_TAINTED=yes
     ;;
 esac
index 7b818ec458b0cc621b7930e90ae7a8a04ce4cfe0..f6a2cac2e94f6b830f1d859c181778798d0039f1 100644 (file)
--- a/gencode.c
+++ b/gencode.c
@@ -4102,7 +4102,16 @@ gen_hostop6(compiler_state_t *cstate, struct in6_addr *addr,
 {
        struct block *b0, *b1;
        u_int offset;
-       uint32_t *a, *m;
+       /*
+        * Code below needs to access four separate 32-bit parts of the 128-bit
+        * IPv6 address and mask.  In some OSes this is as simple as using the
+        * s6_addr32 pseudo-member of struct in6_addr, which contains a union of
+        * 8-, 16- and 32-bit arrays.  In other OSes this is not the case, as
+        * far as libpcap sees it.  Hence copy the data before use to avoid
+        * potential unaligned memory access and the associated compiler
+        * warnings (whether genuine or not).
+        */
+       bpf_u_int32 a[4], m[4];
 
        switch (dir) {
 
@@ -4156,8 +4165,8 @@ gen_hostop6(compiler_state_t *cstate, struct in6_addr *addr,
                /*NOTREACHED*/
        }
        /* this order is important */
-       a = (uint32_t *)addr;
-       m = (uint32_t *)mask;
+       memcpy(a, addr, sizeof(a));
+       memcpy(m, mask, sizeof(m));
        b1 = gen_mcmp(cstate, OR_LINKPL, offset + 12, BPF_W, ntohl(a[3]), ntohl(m[3]));
        b0 = gen_mcmp(cstate, OR_LINKPL, offset + 8, BPF_W, ntohl(a[2]), ntohl(m[2]));
        gen_and(b0, b1);
@@ -7186,7 +7195,7 @@ gen_mcode6(compiler_state_t *cstate, const char *s1, const char *s2,
        struct in6_addr *addr;
        struct in6_addr mask;
        struct block *b;
-       uint32_t *a, *m;
+       bpf_u_int32 a[4], m[4]; /* Same as in gen_hostop6(). */
 
        /*
         * Catch errors reported by us and routines below us, and return NULL
@@ -7215,8 +7224,8 @@ gen_mcode6(compiler_state_t *cstate, const char *s1, const char *s2,
                        (0xff << (8 - masklen % 8)) & 0xff;
        }
 
-       a = (uint32_t *)addr;
-       m = (uint32_t *)&mask;
+       memcpy(a, addr, sizeof(a));
+       memcpy(m, &mask, sizeof(m));
        if ((a[0] & ~m[0]) || (a[1] & ~m[1])
         || (a[2] & ~m[2]) || (a[3] & ~m[3])) {
                bpf_error(cstate, "non-network bits set in \"%s/%d\"", s1, masklen);
diff --git a/pcap.c b/pcap.c
index 44ce8a01f686e33bda848d91e4d6eba384afa97a..6e012da34d94eed1994d3e9ee747faf18b6b8c8b 100644 (file)
--- a/pcap.c
+++ b/pcap.c
@@ -1616,7 +1616,19 @@ pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp,
        ifr.ifr_addr.sa_family = AF_INET;
 #endif
        (void)pcap_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+#if defined(__HAIKU__) && defined(__clang__)
+       /*
+        * In Haiku R1/beta4 <unistd.h> ioctl() is a macro that needs to take 4
+        * arguments to initialize its intermediate 2-member structure fully so
+        * that Clang does not generate a -Wmissing-field-initializers warning
+        * (which manifests only when it runs with -Werror).  This workaround
+        * can be removed as soon as there is a Haiku release that fixes the
+        * problem.  See also https://review.haiku-os.org/c/haiku/+/6369
+        */
+       if (ioctl(fd, SIOCGIFADDR, (char *)&ifr, sizeof(ifr)) < 0) {
+#else
        if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
+#endif /* __HAIKU__ && __clang__ */
                if (errno == EADDRNOTAVAIL) {
                        (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
                            "%s: no IPv4 address assigned", device);
@@ -1635,7 +1647,12 @@ pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp,
        ifr.ifr_addr.sa_family = AF_INET;
 #endif
        (void)pcap_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+#if defined(__HAIKU__) && defined(__clang__)
+       /* Same as above. */
+       if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr, sizeof(ifr)) < 0) {
+#else
        if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
+#endif /* __HAIKU__ && __clang__ */
                pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
                    errno, "SIOCGIFNETMASK: %s", device);
                (void)close(fd);