openbgpd (4.6-3) 0002-Do-not-break-strict-aliasing-rules-in-addr2sa.patch

Summary

 bgpd/util.c |   33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

    
download this patch

Patch contents

From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Bobbio?= <lunar@debian.org>
Date: Sun, 24 Jul 2011 23:06:49 +0200
Subject: [PATCH] Do not break strict-aliasing rules in addr2sa()

---
 bgpd/util.c |   33 ++++++++++++++++++---------------
 1 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/bgpd/util.c b/bgpd/util.c
index 7763458..c5a10ed 100644
--- a/bgpd/util.c
+++ b/bgpd/util.c
@@ -441,32 +441,35 @@ af2aid(sa_family_t af, u_int8_t safi, u_int8_t *aid)
 struct sockaddr *
 addr2sa(struct bgpd_addr *addr, u_int16_t port)
 {
-	static struct sockaddr_storage	 ss;
-	struct sockaddr_in		*sa_in = (struct sockaddr_in *)&ss;
-	struct sockaddr_in6		*sa_in6 = (struct sockaddr_in6 *)&ss;
+	static union {
+		struct sockaddr			sa;
+		struct sockaddr_in		sa_in;
+		struct sockaddr_in6		sa_in6;
+		struct sockaddr_storage		sa_stor;
+	} sa;
 
 	if (addr->aid == AID_UNSPEC)
 		return (NULL);
 
-	bzero(&ss, sizeof(ss));
+	bzero(&sa.sa_stor, sizeof(sa.sa_stor));
 	switch (addr->aid) {
 	case AID_INET:
-		sa_in->sin_family = AF_INET;
-		sa_in->sin_len = sizeof(struct sockaddr_in);
-		sa_in->sin_addr.s_addr = addr->v4.s_addr;
-		sa_in->sin_port = htons(port);
+		sa.sa_in.sin_family = AF_INET;
+		sa.sa_in.sin_len = sizeof(struct sockaddr_in);
+		sa.sa_in.sin_addr.s_addr = addr->v4.s_addr;
+		sa.sa_in.sin_port = htons(port);
 		break;
 	case AID_INET6:
-		sa_in6->sin6_family = AF_INET6;
-		sa_in6->sin6_len = sizeof(struct sockaddr_in6);
-		memcpy(&sa_in6->sin6_addr, &addr->v6,
-		    sizeof(sa_in6->sin6_addr));
-		sa_in6->sin6_port = htons(port);
-		sa_in6->sin6_scope_id = addr->scope_id;
+		sa.sa_in6.sin6_family = AF_INET6;
+		sa.sa_in6.sin6_len = sizeof(struct sockaddr_in6);
+		memcpy(&sa.sa_in6.sin6_addr, &addr->v6,
+		    sizeof(sa.sa_in6.sin6_addr));
+		sa.sa_in6.sin6_port = htons(port);
+		sa.sa_in6.sin6_scope_id = addr->scope_id;
 		break;
 	}
 
-	return ((struct sockaddr *)&ss);
+	return &sa.sa;
 }
 
 void
--