11e09a8abSHajimu UMEMOTO /* $KAME: getifaddrs.c,v 1.9 2001/08/20 02:31:20 itojun Exp $ */ 223ba0142SJun-ichiro itojun Hagino 323ba0142SJun-ichiro itojun Hagino /* 423ba0142SJun-ichiro itojun Hagino * Copyright (c) 1995, 1999 523ba0142SJun-ichiro itojun Hagino * Berkeley Software Design, Inc. All rights reserved. 623ba0142SJun-ichiro itojun Hagino * 723ba0142SJun-ichiro itojun Hagino * Redistribution and use in source and binary forms, with or without 823ba0142SJun-ichiro itojun Hagino * modification, are permitted provided that the following conditions 923ba0142SJun-ichiro itojun Hagino * are met: 1023ba0142SJun-ichiro itojun Hagino * 1. Redistributions of source code must retain the above copyright 1123ba0142SJun-ichiro itojun Hagino * notice, this list of conditions and the following disclaimer. 1223ba0142SJun-ichiro itojun Hagino * 1323ba0142SJun-ichiro itojun Hagino * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND 1423ba0142SJun-ichiro itojun Hagino * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1523ba0142SJun-ichiro itojun Hagino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1623ba0142SJun-ichiro itojun Hagino * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE 1723ba0142SJun-ichiro itojun Hagino * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1823ba0142SJun-ichiro itojun Hagino * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 1923ba0142SJun-ichiro itojun Hagino * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2023ba0142SJun-ichiro itojun Hagino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2123ba0142SJun-ichiro itojun Hagino * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2223ba0142SJun-ichiro itojun Hagino * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2323ba0142SJun-ichiro itojun Hagino * SUCH DAMAGE. 2423ba0142SJun-ichiro itojun Hagino * 2523ba0142SJun-ichiro itojun Hagino * BSDI getifaddrs.c,v 2.12 2000/02/23 14:51:59 dab Exp 2623ba0142SJun-ichiro itojun Hagino */ 2723ba0142SJun-ichiro itojun Hagino /* 2823ba0142SJun-ichiro itojun Hagino * NOTE: SIOCGIFCONF case is not LP64 friendly. it also does not perform 2923ba0142SJun-ichiro itojun Hagino * try-and-error for region size. 3023ba0142SJun-ichiro itojun Hagino */ 31333fc21eSDavid E. O'Brien 32333fc21eSDavid E. O'Brien #include <sys/cdefs.h> 33333fc21eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 34333fc21eSDavid E. O'Brien 35d201fe46SDaniel Eischen #include "namespace.h" 3623ba0142SJun-ichiro itojun Hagino #include <sys/types.h> 3723ba0142SJun-ichiro itojun Hagino #include <sys/ioctl.h> 3823ba0142SJun-ichiro itojun Hagino #include <sys/socket.h> 3923ba0142SJun-ichiro itojun Hagino #include <net/if.h> 4023ba0142SJun-ichiro itojun Hagino #ifdef NET_RT_IFLIST 4123ba0142SJun-ichiro itojun Hagino #include <sys/param.h> 4223ba0142SJun-ichiro itojun Hagino #include <net/route.h> 4323ba0142SJun-ichiro itojun Hagino #include <sys/sysctl.h> 4423ba0142SJun-ichiro itojun Hagino #include <net/if_dl.h> 4523ba0142SJun-ichiro itojun Hagino #endif 4623ba0142SJun-ichiro itojun Hagino 472cbe834aSHajimu UMEMOTO #include <errno.h> 4823ba0142SJun-ichiro itojun Hagino #include <ifaddrs.h> 4923ba0142SJun-ichiro itojun Hagino #include <stdlib.h> 5023ba0142SJun-ichiro itojun Hagino #include <string.h> 51d201fe46SDaniel Eischen #include "un-namespace.h" 5223ba0142SJun-ichiro itojun Hagino 5323ba0142SJun-ichiro itojun Hagino #if !defined(AF_LINK) 5423ba0142SJun-ichiro itojun Hagino #define SA_LEN(sa) sizeof(struct sockaddr) 5523ba0142SJun-ichiro itojun Hagino #endif 5623ba0142SJun-ichiro itojun Hagino 5723ba0142SJun-ichiro itojun Hagino #if !defined(SA_LEN) 5823ba0142SJun-ichiro itojun Hagino #define SA_LEN(sa) (sa)->sa_len 5923ba0142SJun-ichiro itojun Hagino #endif 6023ba0142SJun-ichiro itojun Hagino 6123ba0142SJun-ichiro itojun Hagino #define SALIGN (sizeof(long) - 1) 6223ba0142SJun-ichiro itojun Hagino #define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : (SALIGN + 1)) 6323ba0142SJun-ichiro itojun Hagino 6423ba0142SJun-ichiro itojun Hagino #ifndef ALIGNBYTES 6523ba0142SJun-ichiro itojun Hagino /* 6623ba0142SJun-ichiro itojun Hagino * On systems with a routing socket, ALIGNBYTES should match the value 6723ba0142SJun-ichiro itojun Hagino * that the kernel uses when building the messages. 6823ba0142SJun-ichiro itojun Hagino */ 6923ba0142SJun-ichiro itojun Hagino #define ALIGNBYTES XXX 7023ba0142SJun-ichiro itojun Hagino #endif 7123ba0142SJun-ichiro itojun Hagino #ifndef ALIGN 7223ba0142SJun-ichiro itojun Hagino #define ALIGN(p) (((u_long)(p) + ALIGNBYTES) &~ ALIGNBYTES) 7323ba0142SJun-ichiro itojun Hagino #endif 7423ba0142SJun-ichiro itojun Hagino 752cbe834aSHajimu UMEMOTO #define MAX_SYSCTL_TRY 5 762cbe834aSHajimu UMEMOTO 7723ba0142SJun-ichiro itojun Hagino int 7823ba0142SJun-ichiro itojun Hagino getifaddrs(struct ifaddrs **pif) 7923ba0142SJun-ichiro itojun Hagino { 8023ba0142SJun-ichiro itojun Hagino int icnt = 1; 8123ba0142SJun-ichiro itojun Hagino int dcnt = 0; 8223ba0142SJun-ichiro itojun Hagino int ncnt = 0; 832cbe834aSHajimu UMEMOTO int ntry = 0; 8423ba0142SJun-ichiro itojun Hagino int mib[6]; 8523ba0142SJun-ichiro itojun Hagino size_t needed; 8623ba0142SJun-ichiro itojun Hagino char *buf; 8723ba0142SJun-ichiro itojun Hagino char *next; 8823ba0142SJun-ichiro itojun Hagino struct ifaddrs *cif = 0; 8923ba0142SJun-ichiro itojun Hagino char *p, *p0; 9023ba0142SJun-ichiro itojun Hagino struct rt_msghdr *rtm; 91*ca1672daSBjoern A. Zeeb struct if_msghdrl *ifm; 92*ca1672daSBjoern A. Zeeb struct ifa_msghdrl *ifam; 9323ba0142SJun-ichiro itojun Hagino struct sockaddr_dl *dl; 9423ba0142SJun-ichiro itojun Hagino struct sockaddr *sa; 9523ba0142SJun-ichiro itojun Hagino struct ifaddrs *ifa, *ift; 96*ca1672daSBjoern A. Zeeb struct if_data *if_data; 971e09a8abSHajimu UMEMOTO u_short idx = 0; 9823ba0142SJun-ichiro itojun Hagino int i; 9923ba0142SJun-ichiro itojun Hagino size_t len, alen; 10023ba0142SJun-ichiro itojun Hagino char *data; 10123ba0142SJun-ichiro itojun Hagino char *names; 10223ba0142SJun-ichiro itojun Hagino 10323ba0142SJun-ichiro itojun Hagino mib[0] = CTL_NET; 10423ba0142SJun-ichiro itojun Hagino mib[1] = PF_ROUTE; 10523ba0142SJun-ichiro itojun Hagino mib[2] = 0; /* protocol */ 10623ba0142SJun-ichiro itojun Hagino mib[3] = 0; /* wildcard address family */ 107*ca1672daSBjoern A. Zeeb mib[4] = NET_RT_IFLISTL;/* extra fields for extensible msghdr structs */ 10823ba0142SJun-ichiro itojun Hagino mib[5] = 0; /* no flags */ 1092cbe834aSHajimu UMEMOTO do { 1102cbe834aSHajimu UMEMOTO /* 1112cbe834aSHajimu UMEMOTO * We'll try to get addresses several times in case that 1122cbe834aSHajimu UMEMOTO * the number of addresses is unexpectedly increased during 1132cbe834aSHajimu UMEMOTO * the two sysctl calls. This should rarely happen, but we'll 1142cbe834aSHajimu UMEMOTO * try to do our best for applications that assume success of 1152cbe834aSHajimu UMEMOTO * this library (which should usually be the case). 1162cbe834aSHajimu UMEMOTO * Portability note: since FreeBSD does not add margin of 1172cbe834aSHajimu UMEMOTO * memory at the first sysctl, the possibility of failure on 1182cbe834aSHajimu UMEMOTO * the second sysctl call is a bit higher. 1192cbe834aSHajimu UMEMOTO */ 1202cbe834aSHajimu UMEMOTO 12123ba0142SJun-ichiro itojun Hagino if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) 12223ba0142SJun-ichiro itojun Hagino return (-1); 12323ba0142SJun-ichiro itojun Hagino if ((buf = malloc(needed)) == NULL) 12423ba0142SJun-ichiro itojun Hagino return (-1); 12523ba0142SJun-ichiro itojun Hagino if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { 1262cbe834aSHajimu UMEMOTO if (errno != ENOMEM || ++ntry >= MAX_SYSCTL_TRY) { 12723ba0142SJun-ichiro itojun Hagino free(buf); 12823ba0142SJun-ichiro itojun Hagino return (-1); 12923ba0142SJun-ichiro itojun Hagino } 1302cbe834aSHajimu UMEMOTO free(buf); 1312cbe834aSHajimu UMEMOTO buf = NULL; 1322cbe834aSHajimu UMEMOTO } 1332cbe834aSHajimu UMEMOTO } while (buf == NULL); 13423ba0142SJun-ichiro itojun Hagino 13523ba0142SJun-ichiro itojun Hagino for (next = buf; next < buf + needed; next += rtm->rtm_msglen) { 1361e09a8abSHajimu UMEMOTO rtm = (struct rt_msghdr *)(void *)next; 13723ba0142SJun-ichiro itojun Hagino if (rtm->rtm_version != RTM_VERSION) 13823ba0142SJun-ichiro itojun Hagino continue; 13923ba0142SJun-ichiro itojun Hagino switch (rtm->rtm_type) { 14023ba0142SJun-ichiro itojun Hagino case RTM_IFINFO: 141*ca1672daSBjoern A. Zeeb ifm = (struct if_msghdrl *)(void *)rtm; 14223ba0142SJun-ichiro itojun Hagino if (ifm->ifm_addrs & RTA_IFP) { 1431e09a8abSHajimu UMEMOTO idx = ifm->ifm_index; 14423ba0142SJun-ichiro itojun Hagino ++icnt; 145*ca1672daSBjoern A. Zeeb if_data = IF_MSGHDRL_IFM_DATA(ifm); 146*ca1672daSBjoern A. Zeeb dcnt += if_data->ifi_datalen; 147*ca1672daSBjoern A. Zeeb dl = (struct sockaddr_dl *)IF_MSGHDRL_RTA(ifm); 1481e09a8abSHajimu UMEMOTO dcnt += SA_RLEN((struct sockaddr *)(void*)dl) + 14923ba0142SJun-ichiro itojun Hagino ALIGNBYTES; 15023ba0142SJun-ichiro itojun Hagino ncnt += dl->sdl_nlen + 1; 15123ba0142SJun-ichiro itojun Hagino } else 1521e09a8abSHajimu UMEMOTO idx = 0; 15323ba0142SJun-ichiro itojun Hagino break; 15423ba0142SJun-ichiro itojun Hagino 15523ba0142SJun-ichiro itojun Hagino case RTM_NEWADDR: 156*ca1672daSBjoern A. Zeeb ifam = (struct ifa_msghdrl *)(void *)rtm; 1571e09a8abSHajimu UMEMOTO if (idx && ifam->ifam_index != idx) 15823ba0142SJun-ichiro itojun Hagino abort(); /* this cannot happen */ 15923ba0142SJun-ichiro itojun Hagino 16023ba0142SJun-ichiro itojun Hagino #define RTA_MASKS (RTA_NETMASK | RTA_IFA | RTA_BRD) 1611e09a8abSHajimu UMEMOTO if (idx == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0) 16223ba0142SJun-ichiro itojun Hagino break; 163*ca1672daSBjoern A. Zeeb p = (char *)IFA_MSGHDRL_RTA(ifam); 16423ba0142SJun-ichiro itojun Hagino ++icnt; 165*ca1672daSBjoern A. Zeeb if_data = IFA_MSGHDRL_IFAM_DATA(ifam); 166*ca1672daSBjoern A. Zeeb dcnt += if_data->ifi_datalen + ALIGNBYTES; 167*ca1672daSBjoern A. Zeeb 16823ba0142SJun-ichiro itojun Hagino /* Scan to look for length of address */ 16923ba0142SJun-ichiro itojun Hagino alen = 0; 17023ba0142SJun-ichiro itojun Hagino for (p0 = p, i = 0; i < RTAX_MAX; i++) { 17123ba0142SJun-ichiro itojun Hagino if ((RTA_MASKS & ifam->ifam_addrs & (1 << i)) 17223ba0142SJun-ichiro itojun Hagino == 0) 17323ba0142SJun-ichiro itojun Hagino continue; 1741e09a8abSHajimu UMEMOTO sa = (struct sockaddr *)(void *)p; 17523ba0142SJun-ichiro itojun Hagino len = SA_RLEN(sa); 17623ba0142SJun-ichiro itojun Hagino if (i == RTAX_IFA) { 17723ba0142SJun-ichiro itojun Hagino alen = len; 17823ba0142SJun-ichiro itojun Hagino break; 17923ba0142SJun-ichiro itojun Hagino } 18023ba0142SJun-ichiro itojun Hagino p += len; 18123ba0142SJun-ichiro itojun Hagino } 18223ba0142SJun-ichiro itojun Hagino for (p = p0, i = 0; i < RTAX_MAX; i++) { 18323ba0142SJun-ichiro itojun Hagino if ((RTA_MASKS & ifam->ifam_addrs & (1 << i)) 18423ba0142SJun-ichiro itojun Hagino == 0) 18523ba0142SJun-ichiro itojun Hagino continue; 1861e09a8abSHajimu UMEMOTO sa = (struct sockaddr *)(void *)p; 18723ba0142SJun-ichiro itojun Hagino len = SA_RLEN(sa); 18823ba0142SJun-ichiro itojun Hagino if (i == RTAX_NETMASK && SA_LEN(sa) == 0) 18923ba0142SJun-ichiro itojun Hagino dcnt += alen; 19023ba0142SJun-ichiro itojun Hagino else 19123ba0142SJun-ichiro itojun Hagino dcnt += len; 19223ba0142SJun-ichiro itojun Hagino p += len; 19323ba0142SJun-ichiro itojun Hagino } 19423ba0142SJun-ichiro itojun Hagino break; 19523ba0142SJun-ichiro itojun Hagino } 19623ba0142SJun-ichiro itojun Hagino } 19723ba0142SJun-ichiro itojun Hagino 19823ba0142SJun-ichiro itojun Hagino if (icnt + dcnt + ncnt == 1) { 19923ba0142SJun-ichiro itojun Hagino *pif = NULL; 20023ba0142SJun-ichiro itojun Hagino free(buf); 20123ba0142SJun-ichiro itojun Hagino return (0); 20223ba0142SJun-ichiro itojun Hagino } 20323ba0142SJun-ichiro itojun Hagino data = malloc(sizeof(struct ifaddrs) * icnt + dcnt + ncnt); 20423ba0142SJun-ichiro itojun Hagino if (data == NULL) { 20523ba0142SJun-ichiro itojun Hagino free(buf); 20623ba0142SJun-ichiro itojun Hagino return(-1); 20723ba0142SJun-ichiro itojun Hagino } 20823ba0142SJun-ichiro itojun Hagino 2091e09a8abSHajimu UMEMOTO ifa = (struct ifaddrs *)(void *)data; 21023ba0142SJun-ichiro itojun Hagino data += sizeof(struct ifaddrs) * icnt; 21123ba0142SJun-ichiro itojun Hagino names = data + dcnt; 21223ba0142SJun-ichiro itojun Hagino 21323ba0142SJun-ichiro itojun Hagino memset(ifa, 0, sizeof(struct ifaddrs) * icnt); 21423ba0142SJun-ichiro itojun Hagino ift = ifa; 21523ba0142SJun-ichiro itojun Hagino 2161e09a8abSHajimu UMEMOTO idx = 0; 21723ba0142SJun-ichiro itojun Hagino for (next = buf; next < buf + needed; next += rtm->rtm_msglen) { 2181e09a8abSHajimu UMEMOTO rtm = (struct rt_msghdr *)(void *)next; 21923ba0142SJun-ichiro itojun Hagino if (rtm->rtm_version != RTM_VERSION) 22023ba0142SJun-ichiro itojun Hagino continue; 22123ba0142SJun-ichiro itojun Hagino switch (rtm->rtm_type) { 22223ba0142SJun-ichiro itojun Hagino case RTM_IFINFO: 223*ca1672daSBjoern A. Zeeb ifm = (struct if_msghdrl *)(void *)rtm; 224*ca1672daSBjoern A. Zeeb if ((ifm->ifm_addrs & RTA_IFP) == 0) { 225*ca1672daSBjoern A. Zeeb idx = 0; 226*ca1672daSBjoern A. Zeeb break; 227*ca1672daSBjoern A. Zeeb } 228*ca1672daSBjoern A. Zeeb 2291e09a8abSHajimu UMEMOTO idx = ifm->ifm_index; 230*ca1672daSBjoern A. Zeeb dl = (struct sockaddr_dl *)IF_MSGHDRL_RTA(ifm); 23123ba0142SJun-ichiro itojun Hagino 23223ba0142SJun-ichiro itojun Hagino cif = ift; 23323ba0142SJun-ichiro itojun Hagino ift->ifa_name = names; 23423ba0142SJun-ichiro itojun Hagino ift->ifa_flags = (int)ifm->ifm_flags; 235*ca1672daSBjoern A. Zeeb memcpy(names, dl->sdl_data, (size_t)dl->sdl_nlen); 23623ba0142SJun-ichiro itojun Hagino names[dl->sdl_nlen] = 0; 23723ba0142SJun-ichiro itojun Hagino names += dl->sdl_nlen + 1; 23823ba0142SJun-ichiro itojun Hagino 2391e09a8abSHajimu UMEMOTO ift->ifa_addr = (struct sockaddr *)(void *)data; 240*ca1672daSBjoern A. Zeeb memcpy(data, dl, (size_t)SA_LEN((struct sockaddr *) 2411e09a8abSHajimu UMEMOTO (void *)dl)); 2421e09a8abSHajimu UMEMOTO data += SA_RLEN((struct sockaddr *)(void *)dl); 24323ba0142SJun-ichiro itojun Hagino 244*ca1672daSBjoern A. Zeeb if_data = IF_MSGHDRL_IFM_DATA(ifm); 24523ba0142SJun-ichiro itojun Hagino /* ifm_data needs to be aligned */ 24623ba0142SJun-ichiro itojun Hagino ift->ifa_data = data = (void *)ALIGN(data); 247*ca1672daSBjoern A. Zeeb memcpy(data, if_data, if_data->ifi_datalen); 248*ca1672daSBjoern A. Zeeb data += if_data->ifi_datalen; 24923ba0142SJun-ichiro itojun Hagino 25023ba0142SJun-ichiro itojun Hagino ift = (ift->ifa_next = ift + 1); 25123ba0142SJun-ichiro itojun Hagino break; 25223ba0142SJun-ichiro itojun Hagino 25323ba0142SJun-ichiro itojun Hagino case RTM_NEWADDR: 254*ca1672daSBjoern A. Zeeb ifam = (struct ifa_msghdrl *)(void *)rtm; 2551e09a8abSHajimu UMEMOTO if (idx && ifam->ifam_index != idx) 25623ba0142SJun-ichiro itojun Hagino abort(); /* this cannot happen */ 25723ba0142SJun-ichiro itojun Hagino 2581e09a8abSHajimu UMEMOTO if (idx == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0) 25923ba0142SJun-ichiro itojun Hagino break; 26023ba0142SJun-ichiro itojun Hagino ift->ifa_name = cif->ifa_name; 26123ba0142SJun-ichiro itojun Hagino ift->ifa_flags = cif->ifa_flags; 26223ba0142SJun-ichiro itojun Hagino ift->ifa_data = NULL; 263*ca1672daSBjoern A. Zeeb 264*ca1672daSBjoern A. Zeeb p = (char *)IFA_MSGHDRL_RTA(ifam); 26523ba0142SJun-ichiro itojun Hagino /* Scan to look for length of address */ 26623ba0142SJun-ichiro itojun Hagino alen = 0; 26723ba0142SJun-ichiro itojun Hagino for (p0 = p, i = 0; i < RTAX_MAX; i++) { 26823ba0142SJun-ichiro itojun Hagino if ((RTA_MASKS & ifam->ifam_addrs & (1 << i)) 26923ba0142SJun-ichiro itojun Hagino == 0) 27023ba0142SJun-ichiro itojun Hagino continue; 2711e09a8abSHajimu UMEMOTO sa = (struct sockaddr *)(void *)p; 27223ba0142SJun-ichiro itojun Hagino len = SA_RLEN(sa); 27323ba0142SJun-ichiro itojun Hagino if (i == RTAX_IFA) { 27423ba0142SJun-ichiro itojun Hagino alen = len; 27523ba0142SJun-ichiro itojun Hagino break; 27623ba0142SJun-ichiro itojun Hagino } 27723ba0142SJun-ichiro itojun Hagino p += len; 27823ba0142SJun-ichiro itojun Hagino } 27923ba0142SJun-ichiro itojun Hagino for (p = p0, i = 0; i < RTAX_MAX; i++) { 28023ba0142SJun-ichiro itojun Hagino if ((RTA_MASKS & ifam->ifam_addrs & (1 << i)) 28123ba0142SJun-ichiro itojun Hagino == 0) 28223ba0142SJun-ichiro itojun Hagino continue; 2831e09a8abSHajimu UMEMOTO sa = (struct sockaddr *)(void *)p; 28423ba0142SJun-ichiro itojun Hagino len = SA_RLEN(sa); 28523ba0142SJun-ichiro itojun Hagino switch (i) { 28623ba0142SJun-ichiro itojun Hagino case RTAX_IFA: 2871e09a8abSHajimu UMEMOTO ift->ifa_addr = 2881e09a8abSHajimu UMEMOTO (struct sockaddr *)(void *)data; 28923ba0142SJun-ichiro itojun Hagino memcpy(data, p, len); 29023ba0142SJun-ichiro itojun Hagino data += len; 29123ba0142SJun-ichiro itojun Hagino break; 29223ba0142SJun-ichiro itojun Hagino 29323ba0142SJun-ichiro itojun Hagino case RTAX_NETMASK: 29423ba0142SJun-ichiro itojun Hagino ift->ifa_netmask = 2951e09a8abSHajimu UMEMOTO (struct sockaddr *)(void *)data; 29623ba0142SJun-ichiro itojun Hagino if (SA_LEN(sa) == 0) { 29723ba0142SJun-ichiro itojun Hagino memset(data, 0, alen); 29823ba0142SJun-ichiro itojun Hagino data += alen; 29923ba0142SJun-ichiro itojun Hagino break; 30023ba0142SJun-ichiro itojun Hagino } 30123ba0142SJun-ichiro itojun Hagino memcpy(data, p, len); 30223ba0142SJun-ichiro itojun Hagino data += len; 30323ba0142SJun-ichiro itojun Hagino break; 30423ba0142SJun-ichiro itojun Hagino 30523ba0142SJun-ichiro itojun Hagino case RTAX_BRD: 30623ba0142SJun-ichiro itojun Hagino ift->ifa_broadaddr = 3071e09a8abSHajimu UMEMOTO (struct sockaddr *)(void *)data; 30823ba0142SJun-ichiro itojun Hagino memcpy(data, p, len); 30923ba0142SJun-ichiro itojun Hagino data += len; 31023ba0142SJun-ichiro itojun Hagino break; 31123ba0142SJun-ichiro itojun Hagino } 31223ba0142SJun-ichiro itojun Hagino p += len; 31323ba0142SJun-ichiro itojun Hagino } 31423ba0142SJun-ichiro itojun Hagino 315*ca1672daSBjoern A. Zeeb if_data = IFA_MSGHDRL_IFAM_DATA(ifam); 31623ba0142SJun-ichiro itojun Hagino /* ifam_data needs to be aligned */ 31723ba0142SJun-ichiro itojun Hagino ift->ifa_data = data = (void *)ALIGN(data); 318*ca1672daSBjoern A. Zeeb memcpy(data, if_data, if_data->ifi_datalen); 319*ca1672daSBjoern A. Zeeb data += if_data->ifi_datalen; 32023ba0142SJun-ichiro itojun Hagino 32123ba0142SJun-ichiro itojun Hagino ift = (ift->ifa_next = ift + 1); 32223ba0142SJun-ichiro itojun Hagino break; 32323ba0142SJun-ichiro itojun Hagino } 32423ba0142SJun-ichiro itojun Hagino } 32523ba0142SJun-ichiro itojun Hagino 32623ba0142SJun-ichiro itojun Hagino free(buf); 32723ba0142SJun-ichiro itojun Hagino 32823ba0142SJun-ichiro itojun Hagino if (--ift >= ifa) { 32923ba0142SJun-ichiro itojun Hagino ift->ifa_next = NULL; 33023ba0142SJun-ichiro itojun Hagino *pif = ifa; 33123ba0142SJun-ichiro itojun Hagino } else { 33223ba0142SJun-ichiro itojun Hagino *pif = NULL; 33323ba0142SJun-ichiro itojun Hagino free(ifa); 33423ba0142SJun-ichiro itojun Hagino } 33523ba0142SJun-ichiro itojun Hagino return (0); 33623ba0142SJun-ichiro itojun Hagino } 33723ba0142SJun-ichiro itojun Hagino 33823ba0142SJun-ichiro itojun Hagino void 33923ba0142SJun-ichiro itojun Hagino freeifaddrs(struct ifaddrs *ifp) 34023ba0142SJun-ichiro itojun Hagino { 3411e09a8abSHajimu UMEMOTO 34223ba0142SJun-ichiro itojun Hagino free(ifp); 34323ba0142SJun-ichiro itojun Hagino } 344