From: Tobias Brunner Date: Tue, 18 Jun 2013 14:55:03 +0000 (+0200) Subject: kernel-pfroute: struct sockaddr arguments are 4 byte aligned X-Git-Tag: 5.1.0dr1~80^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aa33d2e6eb2f7508d0650132e481758d6372825e;p=thirdparty%2Fstrongswan.git kernel-pfroute: struct sockaddr arguments are 4 byte aligned This was noticed on Mac OS X where, if the default route is returned, RTA_NETMASK has sa_len set to 0, but skipping zero bytes to read the next address makes no sense, of course. Using 0 for sa_len seems a bit strange, in particular, because struct sockaddr has by definition a minimum length of 16 bytes. But it seems FreeBSD actually does the same. --- diff --git a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c index acb21d3711..0dfb2957ad 100644 --- a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c +++ b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c @@ -40,6 +40,10 @@ #error Cannot compile this plugin on systems where 'struct sockaddr' has no sa_len member. #endif +/** properly align sockaddrs */ +#define SA_ALIGN 4 +#define SA_LEN(len) ((len) > 0 ? (((len)+SA_ALIGN-1) & ~(SA_ALIGN-1)) : SA_ALIGN) + /** delay before firing roam events (ms) */ #define ROAM_DELAY 100 @@ -344,8 +348,8 @@ METHOD(enumerator_t, rt_enumerate, bool, this->types &= ~type; *addr = this->addr; *xtype = i; - this->remaining -= this->addr->sa_len; - this->addr = (void*)this->addr + this->addr->sa_len; + this->remaining -= SA_LEN(this->addr->sa_len); + this->addr = (char*)this->addr + SA_LEN(this->addr->sa_len); return TRUE; } } @@ -941,7 +945,7 @@ static void add_rt_addr(struct rt_msghdr *hdr, int type, host_t *addr) len = *addr->get_sockaddr_len(addr); memcpy((char*)hdr + hdr->rtm_msglen, addr->get_sockaddr(addr), len); - hdr->rtm_msglen += len; + hdr->rtm_msglen += SA_LEN(len); hdr->rtm_addrs |= type; } } @@ -976,7 +980,7 @@ static void add_rt_ifname(struct rt_msghdr *hdr, int type, char *name) { memcpy(sdl.sdl_data, name, sdl.sdl_nlen); memcpy((char*)hdr + hdr->rtm_msglen, &sdl, sdl.sdl_len); - hdr->rtm_msglen += sdl.sdl_len; + hdr->rtm_msglen += SA_LEN(sdl.sdl_len); hdr->rtm_addrs |= type; } }