kernel-pfroute: Properly enumerate sockaddrs in interface messages

The ifa_msghdr and rt_msghdr structs are not compatible (at least not on
FreeBSD).
This commit is contained in:
Tobias Brunner
2013-07-17 17:45:18 +02:00
parent 5310f485d9
commit b308a97944
@@ -601,11 +601,11 @@ METHOD(enumerator_t, rt_enumerate, bool,
} }
/** /**
* Create a safe enumerator over sockaddrs in ifa/ifam/rt_msg * Create an enumerator over sockaddrs in rt/if messages
*/ */
static enumerator_t *create_rtmsg_enumerator(void *hdr, size_t hdrlen) static enumerator_t *create_rt_enumerator(int types, int remaining,
struct sockaddr *addr)
{ {
struct rt_msghdr *rthdr = hdr;
rt_enumerator_t *this; rt_enumerator_t *this;
INIT(this, INIT(this,
@@ -613,13 +613,31 @@ static enumerator_t *create_rtmsg_enumerator(void *hdr, size_t hdrlen)
.enumerate = (void*)_rt_enumerate, .enumerate = (void*)_rt_enumerate,
.destroy = (void*)free, .destroy = (void*)free,
}, },
.types = rthdr->rtm_addrs, .types = types,
.remaining = rthdr->rtm_msglen - hdrlen, .remaining = remaining,
.addr = hdr + hdrlen, .addr = addr,
); );
return &this->public; return &this->public;
} }
/**
* Create a safe enumerator over sockaddrs in rt_msghdr
*/
static enumerator_t *create_rtmsg_enumerator(struct rt_msghdr *hdr)
{
return create_rt_enumerator(hdr->rtm_addrs, hdr->rtm_msglen - sizeof(*hdr),
(struct sockaddr *)(hdr + 1));
}
/**
* Create a safe enumerator over sockaddrs in ifa_msghdr
*/
static enumerator_t *create_ifamsg_enumerator(struct ifa_msghdr *hdr)
{
return create_rt_enumerator(hdr->ifam_addrs, hdr->ifam_msglen - sizeof(*hdr),
(struct sockaddr *)(hdr + 1));
}
/** /**
* Process an RTM_*ADDR message from the kernel * Process an RTM_*ADDR message from the kernel
*/ */
@@ -636,7 +654,7 @@ static void process_addr(private_kernel_pfroute_net_t *this,
char *ifname = NULL; char *ifname = NULL;
int type; int type;
enumerator = create_rtmsg_enumerator(ifa, sizeof(*ifa)); enumerator = create_ifamsg_enumerator(ifa);
while (enumerator->enumerate(enumerator, &type, &sockaddr)) while (enumerator->enumerate(enumerator, &type, &sockaddr))
{ {
if (type == RTAX_IFA) if (type == RTAX_IFA)
@@ -1483,8 +1501,7 @@ retry:
{ {
continue; continue;
} }
enumerator = create_rtmsg_enumerator(this->reply, enumerator = create_rtmsg_enumerator(this->reply);
sizeof(*this->reply));
while (enumerator->enumerate(enumerator, &type, &addr)) while (enumerator->enumerate(enumerator, &type, &addr))
{ {
if (nexthop) if (nexthop)