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
--