#endif
#ifdef PRIVSEP_GETIFADDRS
-#define IFA_NADDRS 3
+#define IFA_NADDRS 4
static ssize_t
ps_root_dogetifaddrs(void **rdata, size_t *rlen)
{
- struct ifaddrs *ifaddrs, *ifa, *ifa_next;
+ struct ifaddrs *ifaddrs, *ifa;
size_t len;
uint8_t *buf, *sap;
socklen_t salen;
- void *ifa_data;
if (getifaddrs(&ifaddrs) == -1)
return -1;
len += ALIGN(sa_len(ifa->ifa_netmask));
if (ifa->ifa_broadaddr != NULL)
len += ALIGN(sa_len(ifa->ifa_broadaddr));
+#ifdef BSD
+ /*
+ * On BSD we need to carry ifa_data so we can access
+ * if_data->ifi_link_state
+ */
+ if (ifa->ifa_addr != NULL &&
+ ifa->ifa_addr->sa_family == AF_LINK)
+ len += ALIGN(sizeof(struct if_data));
+#endif
}
/* Use calloc to set everything to zero.
*rlen = len;
for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
- /* Don't carry ifa_data or ifa_next. */
- ifa_data = ifa->ifa_data;
- ifa_next = ifa->ifa_next;
- ifa->ifa_data = NULL;
- ifa->ifa_next = NULL;
memcpy(buf, ifa, sizeof(*ifa));
buf += ALIGN(sizeof(*ifa));
- ifa->ifa_data = ifa_data;
- ifa->ifa_next = ifa_next;
strlcpy((char *)buf, ifa->ifa_name, IFNAMSIZ);
buf += ALIGN(IFNAMSIZ);
#define COPYINSA(addr) \
do { \
- salen = sa_len((addr)); \
+ if ((addr) != NULL) \
+ salen = sa_len((addr)); \
+ else \
+ salen = 0; \
if (salen != 0) { \
memcpy(sap, &salen, sizeof(salen)); \
memcpy(buf, (addr), salen); \
sap += sizeof(salen); \
} while (0 /*CONSTCOND */)
- if (ifa->ifa_addr != NULL)
- COPYINSA(ifa->ifa_addr);
- if (ifa->ifa_netmask != NULL)
- COPYINSA(ifa->ifa_netmask);
- if (ifa->ifa_broadaddr != NULL)
- COPYINSA(ifa->ifa_broadaddr);
+ COPYINSA(ifa->ifa_addr);
+ COPYINSA(ifa->ifa_netmask);
+ COPYINSA(ifa->ifa_broadaddr);
+
+#ifdef BSD
+ if (ifa->ifa_addr != NULL &&
+ ifa->ifa_addr->sa_family == AF_LINK)
+ {
+ salen = (socklen_t)sizeof(struct if_data);
+ memcpy(buf, ifa->ifa_data, salen);
+ buf += ALIGN(salen);
+ } else
+#endif
+ salen = 0;
+ memcpy(sap, &salen, sizeof(salen));
}
freeifaddrs(ifaddrs);
COPYOUTSA(ifa->ifa_addr);
COPYOUTSA(ifa->ifa_netmask);
COPYOUTSA(ifa->ifa_broadaddr);
+
+ memcpy(&salen, sap, sizeof(salen));
+ if (len < salen)
+ goto err;
+ if (salen != 0) {
+ ifa->ifa_data = bp;
+ bp += ALIGN(salen);
+ len -= ALIGN(salen);
+ } else
+ ifa->ifa_data = NULL;
+
if (len != 0)
ifa->ifa_next = (struct ifaddrs *)(void *)bp;
else