diff --git a/hostport.c b/hostport.c
index 54c1d74..8280da2 100644
--- a/hostport.c
+++ b/hostport.c
@@ -249,40 +249,29 @@ static int prefixmatch(void *a1, void *a2, uint8_t len) {
 }
 
 int addressmatches(struct list *hostports, struct sockaddr *addr, uint8_t checkport) {
-    struct sockaddr_in6 *sa6 = NULL;
-    struct in_addr *a4 = NULL;
+    union sockaddr_u u;
+    struct sockaddr_in sa4;
     struct addrinfo *res;
     struct list_node *entry;
     struct hostportres *hp = NULL;
 
-    if (addr->sa_family == AF_INET6) {
-        sa6 = (struct sockaddr_in6 *)addr;
-        if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr)) {
-            a4 = (struct in_addr *)&sa6->sin6_addr.s6_addr[12];
-	    sa6 = NULL;
-	}
-    } else
-	a4 = &((struct sockaddr_in *)addr)->sin_addr;
-
+    set_sockaddr_u(&u, addr, &sa4);
     for (entry = list_first(hostports); entry; entry = list_next(entry)) {
 	hp = (struct hostportres *)entry->data;
 	for (res = hp->addrinfo; res; res = res->ai_next)
 	    if (hp->prefixlen == 255) {
-		if ((a4 && res->ai_family == AF_INET &&
-		     !memcmp(a4, &((struct sockaddr_in *)res->ai_addr)->sin_addr, 4) &&
-		     (!checkport || ((struct sockaddr_in *)res->ai_addr)->sin_port ==
-		      ((struct sockaddr_in *)addr)->sin_port)) ||
-		    (sa6 && res->ai_family == AF_INET6 &&
-		     !memcmp(&sa6->sin6_addr,
-			     &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 16) &&
-		     (!checkport || ((struct sockaddr_in6 *)res->ai_addr)->sin6_port ==
-		      ((struct sockaddr_in6 *)addr)->sin6_port)))
+		if ((u.sa->sa_family == AF_INET && res->ai_family == AF_INET &&
+		     !memcmp(&u.sa4->sin_addr, &((struct sockaddr_in *)res->ai_addr)->sin_addr, 4) &&
+		     (!checkport || ((struct sockaddr_in *)res->ai_addr)->sin_port == u.sa4->sin_port)) ||
+		    (res->ai_family == AF_INET6 &&
+		     !memcmp(&u.sa6->sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 16) &&
+		     (!checkport || ((struct sockaddr_in6 *)res->ai_addr)->sin6_port == u.sa6->sin6_port)))
 		    return 1;
 	    } else {
-		if ((a4 && res->ai_family == AF_INET &&
-		     prefixmatch(a4, &((struct sockaddr_in *)res->ai_addr)->sin_addr, hp->prefixlen)) ||
-		    (sa6 && res->ai_family == AF_INET6 &&
-		     prefixmatch(&sa6->sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, hp->prefixlen)))
+		if ((u.sa->sa_family == AF_INET && res->ai_family == AF_INET &&
+		     prefixmatch(&u.sa4->sin_addr, &((struct sockaddr_in *)res->ai_addr)->sin_addr, hp->prefixlen)) ||
+		    (res->ai_family == AF_INET6 &&
+		     prefixmatch(&u.sa6->sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, hp->prefixlen)))
 		    return 1;
 	    }
     }
diff --git a/udp.c b/udp.c
index 4740fd0..a141f72 100644
--- a/udp.c
+++ b/udp.c
@@ -104,14 +104,21 @@ void removeudpclientfromreplyq(struct client *c) {
 }
 
 static int addr_equal(struct sockaddr *a, struct sockaddr *b) {
+    union {
+	struct sockaddr *sa;
+	struct sockaddr_in *sa4;
+	struct sockaddr_in6 *sa6;
+    } ua, ub;
+    ua.sa = a;
+    ub.sa = b;
     switch (a->sa_family) {
     case AF_INET:
-	return !memcmp(&((struct sockaddr_in*)a)->sin_addr,
-		       &((struct sockaddr_in*)b)->sin_addr,
+	return !memcmp(&ua.sa4->sin_addr,
+		       &ub.sa4->sin_addr,
 		       sizeof(struct in_addr));
     case AF_INET6:
-	return IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6*)a)->sin6_addr,
-				  &((struct sockaddr_in6*)b)->sin6_addr);
+	return IN6_ARE_ADDR_EQUAL(&ua.sa6->sin6_addr,
+				  &ub.sa6->sin6_addr);
     default:
 	/* Must not reach */
 	return 0;
diff --git a/util.c b/util.c
index 5235d8a..9c5c140 100644
--- a/util.c
+++ b/util.c
@@ -49,6 +49,20 @@ void printfchars(char *prefixfmt, char *prefix, char *charfmt, char *chars, int
     printf("\n");
 }
 
+void set_sockaddr_u(union sockaddr_u *u,
+		    struct sockaddr *addr,
+		    struct sockaddr_in *sa4) {
+    u->sa = addr;
+    if (u->sa->sa_family == AF_INET6
+	&& IN6_IS_ADDR_V4MAPPED(&u->sa6->sin6_addr)) {
+	memset(&sa4, 0, sizeof(sa4));
+	sa4->sin_family = AF_INET;
+	sa4->sin_port = u->sa6->sin6_port;
+	memcpy(&sa4->sin_addr, &u->sa6->sin6_addr.s6_addr[12], sizeof(struct in_addr));
+	u->sa4 = sa4;
+    }
+}
+
 void port_set(struct sockaddr *sa, uint16_t port) {
     switch (sa->sa_family) {
     case AF_INET:
@@ -87,22 +101,14 @@ struct sockaddr *addr_copy(struct sockaddr *in) {
 }
 
 char *addr2string(struct sockaddr *addr) {
-    struct sockaddr_in6 *sa6;
+    union sockaddr_u u;
     struct sockaddr_in sa4;
     static char addr_buf[2][INET6_ADDRSTRLEN];
     static int i = 0;
+
     i = !i;
-    if (addr->sa_family == AF_INET6) {
-	sa6 = (struct sockaddr_in6 *)addr;
-	if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr)) {
-	    memset(&sa4, 0, sizeof(sa4));
-	    sa4.sin_family = AF_INET;
-	    sa4.sin_port = sa6->sin6_port;
-	    memcpy(&sa4.sin_addr, &sa6->sin6_addr.s6_addr[12], 4);
-	    addr = (struct sockaddr *)&sa4;
-	}
-    }
-    if (getnameinfo(addr, SOCKADDRP_SIZE(addr), addr_buf[i], sizeof(addr_buf[i]),
+    set_sockaddr_u(&u, addr, &sa4);
+    if (getnameinfo(u.sa, SOCKADDRP_SIZE(u.sa), addr_buf[i], sizeof(addr_buf[i]),
                     NULL, 0, NI_NUMERICHOST)) {
         debug(DBG_WARN, "getnameinfo failed");
         return "getnameinfo_failed";
diff --git a/util.h b/util.h
index d8d002c..e88f012 100644
--- a/util.h
+++ b/util.h
@@ -9,6 +9,12 @@
 			      sizeof(struct sockaddr_in) :	\
 			      sizeof(struct sockaddr_in6))
 
+union sockaddr_u {
+    struct sockaddr *sa;
+    struct sockaddr_in *sa4;
+    struct sockaddr_in6 *sa6;
+};
+
 char *stringcopy(const char *s, int len);
 char *addr2string(struct sockaddr *addr);
 struct sockaddr *addr_copy(struct sockaddr *in);
@@ -18,6 +24,7 @@ void printfchars(char *prefixfmt, char *prefix, char *charfmt, char *chars, int
 void disable_DF_bit(int socket, struct addrinfo *res);
 int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only);
 int connecttcp(struct addrinfo *addrinfo, struct addrinfo *src, uint16_t timeout);
+void set_sockaddr_u(union sockaddr_u *u, struct sockaddr *addr, struct sockaddr_in *sa4);
 
 
 /* Local Variables: */
