]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
datatype: avoid cast-align warning with struct sockaddr result from getaddrinfo()
authorThomas Haller <thaller@redhat.com>
Tue, 29 Aug 2023 12:53:32 +0000 (14:53 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 29 Aug 2023 17:52:20 +0000 (19:52 +0200)
With CC=clang we get

    datatype.c:625:11: error: cast from 'struct sockaddr *' to 'struct sockaddr_in *' increases required alignment from 2 to 4 [-Werror,-Wcast-align]
                    addr = ((struct sockaddr_in *)ai->ai_addr)->sin_addr;
                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    datatype.c:690:11: error: cast from 'struct sockaddr *' to 'struct sockaddr_in6 *' increases required alignment from 2 to 4 [-Werror,-Wcast-align]
                    addr = ((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr;
                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    datatype.c:826:11: error: cast from 'struct sockaddr *' to 'struct sockaddr_in *' increases required alignment from 2 to 4 [-Werror,-Wcast-align]
                    port = ((struct sockaddr_in *)ai->ai_addr)->sin_port;
                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Fix that by casting to (void*) first. Also, add an assertion that the
type is as expected.

For inet_service_type_parse(), differentiate between AF_INET and
AF_INET6. It might not have been a problem in practice, because the
struct offsets of sin_port/sin6_port are identical.

Signed-off-by: Thomas Haller <thaller@redhat.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/datatype.c

index dd6a5fbf5df8037c36b1d526ed27f9520ef050d6..ba1192c8359577eb6fefb4ae1adc73dbdda492d9 100644 (file)
@@ -622,7 +622,8 @@ static struct error_record *ipaddr_type_parse(struct parse_ctx *ctx,
                        return error(&sym->location,
                                     "Hostname resolves to multiple addresses");
                }
-               addr = ((struct sockaddr_in *)ai->ai_addr)->sin_addr;
+               assert(ai->ai_addr->sa_family == AF_INET);
+               addr = ((struct sockaddr_in *) (void *) ai->ai_addr)->sin_addr;
                freeaddrinfo(ai);
        }
 
@@ -687,7 +688,9 @@ static struct error_record *ip6addr_type_parse(struct parse_ctx *ctx,
                        return error(&sym->location,
                                     "Hostname resolves to multiple addresses");
                }
-               addr = ((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr;
+
+               assert(ai->ai_addr->sa_family == AF_INET6);
+               addr = ((struct sockaddr_in6 *)(void *)ai->ai_addr)->sin6_addr;
                freeaddrinfo(ai);
        }
 
@@ -823,7 +826,12 @@ static struct error_record *inet_service_type_parse(struct parse_ctx *ctx,
                        return error(&sym->location, "Could not resolve service: %s",
                                     gai_strerror(err));
 
-               port = ((struct sockaddr_in *)ai->ai_addr)->sin_port;
+               if (ai->ai_addr->sa_family == AF_INET) {
+                       port = ((struct sockaddr_in *)(void *)ai->ai_addr)->sin_port;
+               } else {
+                       assert(ai->ai_addr->sa_family == AF_INET6);
+                       port = ((struct sockaddr_in6 *)(void *)ai->ai_addr)->sin6_port;
+               }
                freeaddrinfo(ai);
        }