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 4723ba0142SJun-ichiro itojun Hagino #include <ifaddrs.h> 4823ba0142SJun-ichiro itojun Hagino #include <stdlib.h> 4923ba0142SJun-ichiro itojun Hagino #include <string.h> 50d201fe46SDaniel Eischen #include "un-namespace.h" 5123ba0142SJun-ichiro itojun Hagino 5223ba0142SJun-ichiro itojun Hagino #if !defined(AF_LINK) 5323ba0142SJun-ichiro itojun Hagino #define SA_LEN(sa) sizeof(struct sockaddr) 5423ba0142SJun-ichiro itojun Hagino #endif 5523ba0142SJun-ichiro itojun Hagino 5623ba0142SJun-ichiro itojun Hagino #if !defined(SA_LEN) 5723ba0142SJun-ichiro itojun Hagino #define SA_LEN(sa) (sa)->sa_len 5823ba0142SJun-ichiro itojun Hagino #endif 5923ba0142SJun-ichiro itojun Hagino 6023ba0142SJun-ichiro itojun Hagino #define SALIGN (sizeof(long) - 1) 6123ba0142SJun-ichiro itojun Hagino #define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : (SALIGN + 1)) 6223ba0142SJun-ichiro itojun Hagino 6323ba0142SJun-ichiro itojun Hagino #ifndef ALIGNBYTES 6423ba0142SJun-ichiro itojun Hagino /* 6523ba0142SJun-ichiro itojun Hagino * On systems with a routing socket, ALIGNBYTES should match the value 6623ba0142SJun-ichiro itojun Hagino * that the kernel uses when building the messages. 6723ba0142SJun-ichiro itojun Hagino */ 6823ba0142SJun-ichiro itojun Hagino #define ALIGNBYTES XXX 6923ba0142SJun-ichiro itojun Hagino #endif 7023ba0142SJun-ichiro itojun Hagino #ifndef ALIGN 7123ba0142SJun-ichiro itojun Hagino #define ALIGN(p) (((u_long)(p) + ALIGNBYTES) &~ ALIGNBYTES) 7223ba0142SJun-ichiro itojun Hagino #endif 7323ba0142SJun-ichiro itojun Hagino 7423ba0142SJun-ichiro itojun Hagino #if _BSDI_VERSION >= 199701 7523ba0142SJun-ichiro itojun Hagino #define HAVE_IFM_DATA 7623ba0142SJun-ichiro itojun Hagino #endif 7723ba0142SJun-ichiro itojun Hagino 7823ba0142SJun-ichiro itojun Hagino #if _BSDI_VERSION >= 199802 797363d0e7SHajimu UMEMOTO /* ifam_data is very specific to recent versions of bsdi */ 8023ba0142SJun-ichiro itojun Hagino #define HAVE_IFAM_DATA 8123ba0142SJun-ichiro itojun Hagino #endif 8223ba0142SJun-ichiro itojun Hagino 837363d0e7SHajimu UMEMOTO #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) 847363d0e7SHajimu UMEMOTO #define HAVE_IFM_DATA 857363d0e7SHajimu UMEMOTO #endif 867363d0e7SHajimu UMEMOTO 8723ba0142SJun-ichiro itojun Hagino int 8823ba0142SJun-ichiro itojun Hagino getifaddrs(struct ifaddrs **pif) 8923ba0142SJun-ichiro itojun Hagino { 9023ba0142SJun-ichiro itojun Hagino int icnt = 1; 9123ba0142SJun-ichiro itojun Hagino int dcnt = 0; 9223ba0142SJun-ichiro itojun Hagino int ncnt = 0; 9323ba0142SJun-ichiro itojun Hagino #ifdef NET_RT_IFLIST 9423ba0142SJun-ichiro itojun Hagino int mib[6]; 9523ba0142SJun-ichiro itojun Hagino size_t needed; 9623ba0142SJun-ichiro itojun Hagino char *buf; 9723ba0142SJun-ichiro itojun Hagino char *next; 9823ba0142SJun-ichiro itojun Hagino struct ifaddrs *cif = 0; 9923ba0142SJun-ichiro itojun Hagino char *p, *p0; 10023ba0142SJun-ichiro itojun Hagino struct rt_msghdr *rtm; 10123ba0142SJun-ichiro itojun Hagino struct if_msghdr *ifm; 10223ba0142SJun-ichiro itojun Hagino struct ifa_msghdr *ifam; 10323ba0142SJun-ichiro itojun Hagino struct sockaddr_dl *dl; 10423ba0142SJun-ichiro itojun Hagino struct sockaddr *sa; 10523ba0142SJun-ichiro itojun Hagino struct ifaddrs *ifa, *ift; 1061e09a8abSHajimu UMEMOTO u_short idx = 0; 10723ba0142SJun-ichiro itojun Hagino #else /* NET_RT_IFLIST */ 10823ba0142SJun-ichiro itojun Hagino char buf[1024]; 10923ba0142SJun-ichiro itojun Hagino int m, sock; 11023ba0142SJun-ichiro itojun Hagino struct ifconf ifc; 11123ba0142SJun-ichiro itojun Hagino struct ifreq *ifr; 11223ba0142SJun-ichiro itojun Hagino struct ifreq *lifr; 11323ba0142SJun-ichiro itojun Hagino #endif /* NET_RT_IFLIST */ 11423ba0142SJun-ichiro itojun Hagino int i; 11523ba0142SJun-ichiro itojun Hagino size_t len, alen; 11623ba0142SJun-ichiro itojun Hagino char *data; 11723ba0142SJun-ichiro itojun Hagino char *names; 11823ba0142SJun-ichiro itojun Hagino 11923ba0142SJun-ichiro itojun Hagino #ifdef NET_RT_IFLIST 12023ba0142SJun-ichiro itojun Hagino mib[0] = CTL_NET; 12123ba0142SJun-ichiro itojun Hagino mib[1] = PF_ROUTE; 12223ba0142SJun-ichiro itojun Hagino mib[2] = 0; /* protocol */ 12323ba0142SJun-ichiro itojun Hagino mib[3] = 0; /* wildcard address family */ 12423ba0142SJun-ichiro itojun Hagino mib[4] = NET_RT_IFLIST; 12523ba0142SJun-ichiro itojun Hagino mib[5] = 0; /* no flags */ 12623ba0142SJun-ichiro itojun Hagino if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) 12723ba0142SJun-ichiro itojun Hagino return (-1); 12823ba0142SJun-ichiro itojun Hagino if ((buf = malloc(needed)) == NULL) 12923ba0142SJun-ichiro itojun Hagino return (-1); 13023ba0142SJun-ichiro itojun Hagino if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { 13123ba0142SJun-ichiro itojun Hagino free(buf); 13223ba0142SJun-ichiro itojun Hagino return (-1); 13323ba0142SJun-ichiro itojun Hagino } 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: 1411e09a8abSHajimu UMEMOTO ifm = (struct if_msghdr *)(void *)rtm; 14223ba0142SJun-ichiro itojun Hagino if (ifm->ifm_addrs & RTA_IFP) { 1431e09a8abSHajimu UMEMOTO idx = ifm->ifm_index; 14423ba0142SJun-ichiro itojun Hagino ++icnt; 1451e09a8abSHajimu UMEMOTO dl = (struct sockaddr_dl *)(void *)(ifm + 1); 1461e09a8abSHajimu UMEMOTO dcnt += SA_RLEN((struct sockaddr *)(void*)dl) + 14723ba0142SJun-ichiro itojun Hagino ALIGNBYTES; 14823ba0142SJun-ichiro itojun Hagino #ifdef HAVE_IFM_DATA 14923ba0142SJun-ichiro itojun Hagino dcnt += sizeof(ifm->ifm_data); 15023ba0142SJun-ichiro itojun Hagino #endif /* HAVE_IFM_DATA */ 15123ba0142SJun-ichiro itojun Hagino ncnt += dl->sdl_nlen + 1; 15223ba0142SJun-ichiro itojun Hagino } else 1531e09a8abSHajimu UMEMOTO idx = 0; 15423ba0142SJun-ichiro itojun Hagino break; 15523ba0142SJun-ichiro itojun Hagino 15623ba0142SJun-ichiro itojun Hagino case RTM_NEWADDR: 1571e09a8abSHajimu UMEMOTO ifam = (struct ifa_msghdr *)(void *)rtm; 1581e09a8abSHajimu UMEMOTO if (idx && ifam->ifam_index != idx) 15923ba0142SJun-ichiro itojun Hagino abort(); /* this cannot happen */ 16023ba0142SJun-ichiro itojun Hagino 16123ba0142SJun-ichiro itojun Hagino #define RTA_MASKS (RTA_NETMASK | RTA_IFA | RTA_BRD) 1621e09a8abSHajimu UMEMOTO if (idx == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0) 16323ba0142SJun-ichiro itojun Hagino break; 1641e09a8abSHajimu UMEMOTO p = (char *)(void *)(ifam + 1); 16523ba0142SJun-ichiro itojun Hagino ++icnt; 16623ba0142SJun-ichiro itojun Hagino #ifdef HAVE_IFAM_DATA 16723ba0142SJun-ichiro itojun Hagino dcnt += sizeof(ifam->ifam_data) + ALIGNBYTES; 16823ba0142SJun-ichiro itojun Hagino #endif /* HAVE_IFAM_DATA */ 16923ba0142SJun-ichiro itojun Hagino /* Scan to look for length of address */ 17023ba0142SJun-ichiro itojun Hagino alen = 0; 17123ba0142SJun-ichiro itojun Hagino for (p0 = p, i = 0; i < RTAX_MAX; i++) { 17223ba0142SJun-ichiro itojun Hagino if ((RTA_MASKS & ifam->ifam_addrs & (1 << i)) 17323ba0142SJun-ichiro itojun Hagino == 0) 17423ba0142SJun-ichiro itojun Hagino continue; 1751e09a8abSHajimu UMEMOTO sa = (struct sockaddr *)(void *)p; 17623ba0142SJun-ichiro itojun Hagino len = SA_RLEN(sa); 17723ba0142SJun-ichiro itojun Hagino if (i == RTAX_IFA) { 17823ba0142SJun-ichiro itojun Hagino alen = len; 17923ba0142SJun-ichiro itojun Hagino break; 18023ba0142SJun-ichiro itojun Hagino } 18123ba0142SJun-ichiro itojun Hagino p += len; 18223ba0142SJun-ichiro itojun Hagino } 18323ba0142SJun-ichiro itojun Hagino for (p = p0, i = 0; i < RTAX_MAX; i++) { 18423ba0142SJun-ichiro itojun Hagino if ((RTA_MASKS & ifam->ifam_addrs & (1 << i)) 18523ba0142SJun-ichiro itojun Hagino == 0) 18623ba0142SJun-ichiro itojun Hagino continue; 1871e09a8abSHajimu UMEMOTO sa = (struct sockaddr *)(void *)p; 18823ba0142SJun-ichiro itojun Hagino len = SA_RLEN(sa); 18923ba0142SJun-ichiro itojun Hagino if (i == RTAX_NETMASK && SA_LEN(sa) == 0) 19023ba0142SJun-ichiro itojun Hagino dcnt += alen; 19123ba0142SJun-ichiro itojun Hagino else 19223ba0142SJun-ichiro itojun Hagino dcnt += len; 19323ba0142SJun-ichiro itojun Hagino p += len; 19423ba0142SJun-ichiro itojun Hagino } 19523ba0142SJun-ichiro itojun Hagino break; 19623ba0142SJun-ichiro itojun Hagino } 19723ba0142SJun-ichiro itojun Hagino } 19823ba0142SJun-ichiro itojun Hagino #else /* NET_RT_IFLIST */ 19923ba0142SJun-ichiro itojun Hagino ifc.ifc_buf = buf; 20023ba0142SJun-ichiro itojun Hagino ifc.ifc_len = sizeof(buf); 20123ba0142SJun-ichiro itojun Hagino 202d201fe46SDaniel Eischen if ((sock = _socket(AF_INET, SOCK_STREAM, 0)) < 0) 20323ba0142SJun-ichiro itojun Hagino return (-1); 204d201fe46SDaniel Eischen i = _ioctl(sock, SIOCGIFCONF, (char *)&ifc); 205d201fe46SDaniel Eischen _close(sock); 20623ba0142SJun-ichiro itojun Hagino if (i < 0) 20723ba0142SJun-ichiro itojun Hagino return (-1); 20823ba0142SJun-ichiro itojun Hagino 20923ba0142SJun-ichiro itojun Hagino ifr = ifc.ifc_req; 21023ba0142SJun-ichiro itojun Hagino lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len]; 21123ba0142SJun-ichiro itojun Hagino 21223ba0142SJun-ichiro itojun Hagino while (ifr < lifr) { 21323ba0142SJun-ichiro itojun Hagino struct sockaddr *sa; 21423ba0142SJun-ichiro itojun Hagino 21523ba0142SJun-ichiro itojun Hagino sa = &ifr->ifr_addr; 21623ba0142SJun-ichiro itojun Hagino ++icnt; 21723ba0142SJun-ichiro itojun Hagino dcnt += SA_RLEN(sa); 21823ba0142SJun-ichiro itojun Hagino ncnt += sizeof(ifr->ifr_name) + 1; 21923ba0142SJun-ichiro itojun Hagino 2201e09a8abSHajimu UMEMOTO if (SA_LEN(sa) < sizeof(*sa)) 2211e09a8abSHajimu UMEMOTO ifr = (struct ifreq *)(((char *)sa) + sizeof(*sa)); 2221e09a8abSHajimu UMEMOTO else 22323ba0142SJun-ichiro itojun Hagino ifr = (struct ifreq *)(((char *)sa) + SA_LEN(sa)); 22423ba0142SJun-ichiro itojun Hagino } 22523ba0142SJun-ichiro itojun Hagino #endif /* NET_RT_IFLIST */ 22623ba0142SJun-ichiro itojun Hagino 22723ba0142SJun-ichiro itojun Hagino if (icnt + dcnt + ncnt == 1) { 22823ba0142SJun-ichiro itojun Hagino *pif = NULL; 22923ba0142SJun-ichiro itojun Hagino free(buf); 23023ba0142SJun-ichiro itojun Hagino return (0); 23123ba0142SJun-ichiro itojun Hagino } 23223ba0142SJun-ichiro itojun Hagino data = malloc(sizeof(struct ifaddrs) * icnt + dcnt + ncnt); 23323ba0142SJun-ichiro itojun Hagino if (data == NULL) { 23423ba0142SJun-ichiro itojun Hagino free(buf); 23523ba0142SJun-ichiro itojun Hagino return(-1); 23623ba0142SJun-ichiro itojun Hagino } 23723ba0142SJun-ichiro itojun Hagino 2381e09a8abSHajimu UMEMOTO ifa = (struct ifaddrs *)(void *)data; 23923ba0142SJun-ichiro itojun Hagino data += sizeof(struct ifaddrs) * icnt; 24023ba0142SJun-ichiro itojun Hagino names = data + dcnt; 24123ba0142SJun-ichiro itojun Hagino 24223ba0142SJun-ichiro itojun Hagino memset(ifa, 0, sizeof(struct ifaddrs) * icnt); 24323ba0142SJun-ichiro itojun Hagino ift = ifa; 24423ba0142SJun-ichiro itojun Hagino 24523ba0142SJun-ichiro itojun Hagino #ifdef NET_RT_IFLIST 2461e09a8abSHajimu UMEMOTO idx = 0; 24723ba0142SJun-ichiro itojun Hagino for (next = buf; next < buf + needed; next += rtm->rtm_msglen) { 2481e09a8abSHajimu UMEMOTO rtm = (struct rt_msghdr *)(void *)next; 24923ba0142SJun-ichiro itojun Hagino if (rtm->rtm_version != RTM_VERSION) 25023ba0142SJun-ichiro itojun Hagino continue; 25123ba0142SJun-ichiro itojun Hagino switch (rtm->rtm_type) { 25223ba0142SJun-ichiro itojun Hagino case RTM_IFINFO: 2531e09a8abSHajimu UMEMOTO ifm = (struct if_msghdr *)(void *)rtm; 25423ba0142SJun-ichiro itojun Hagino if (ifm->ifm_addrs & RTA_IFP) { 2551e09a8abSHajimu UMEMOTO idx = ifm->ifm_index; 2561e09a8abSHajimu UMEMOTO dl = (struct sockaddr_dl *)(void *)(ifm + 1); 25723ba0142SJun-ichiro itojun Hagino 25823ba0142SJun-ichiro itojun Hagino cif = ift; 25923ba0142SJun-ichiro itojun Hagino ift->ifa_name = names; 26023ba0142SJun-ichiro itojun Hagino ift->ifa_flags = (int)ifm->ifm_flags; 2611e09a8abSHajimu UMEMOTO memcpy(names, dl->sdl_data, 2621e09a8abSHajimu UMEMOTO (size_t)dl->sdl_nlen); 26323ba0142SJun-ichiro itojun Hagino names[dl->sdl_nlen] = 0; 26423ba0142SJun-ichiro itojun Hagino names += dl->sdl_nlen + 1; 26523ba0142SJun-ichiro itojun Hagino 2661e09a8abSHajimu UMEMOTO ift->ifa_addr = (struct sockaddr *)(void *)data; 2671e09a8abSHajimu UMEMOTO memcpy(data, dl, 2681e09a8abSHajimu UMEMOTO (size_t)SA_LEN((struct sockaddr *) 2691e09a8abSHajimu UMEMOTO (void *)dl)); 2701e09a8abSHajimu UMEMOTO data += SA_RLEN((struct sockaddr *)(void *)dl); 27123ba0142SJun-ichiro itojun Hagino 27223ba0142SJun-ichiro itojun Hagino #ifdef HAVE_IFM_DATA 27323ba0142SJun-ichiro itojun Hagino /* ifm_data needs to be aligned */ 27423ba0142SJun-ichiro itojun Hagino ift->ifa_data = data = (void *)ALIGN(data); 27523ba0142SJun-ichiro itojun Hagino memcpy(data, &ifm->ifm_data, sizeof(ifm->ifm_data)); 27623ba0142SJun-ichiro itojun Hagino data += sizeof(ifm->ifm_data); 27723ba0142SJun-ichiro itojun Hagino #else /* HAVE_IFM_DATA */ 27823ba0142SJun-ichiro itojun Hagino ift->ifa_data = NULL; 27923ba0142SJun-ichiro itojun Hagino #endif /* HAVE_IFM_DATA */ 28023ba0142SJun-ichiro itojun Hagino 28123ba0142SJun-ichiro itojun Hagino ift = (ift->ifa_next = ift + 1); 28223ba0142SJun-ichiro itojun Hagino } else 2831e09a8abSHajimu UMEMOTO idx = 0; 28423ba0142SJun-ichiro itojun Hagino break; 28523ba0142SJun-ichiro itojun Hagino 28623ba0142SJun-ichiro itojun Hagino case RTM_NEWADDR: 2871e09a8abSHajimu UMEMOTO ifam = (struct ifa_msghdr *)(void *)rtm; 2881e09a8abSHajimu UMEMOTO if (idx && ifam->ifam_index != idx) 28923ba0142SJun-ichiro itojun Hagino abort(); /* this cannot happen */ 29023ba0142SJun-ichiro itojun Hagino 2911e09a8abSHajimu UMEMOTO if (idx == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0) 29223ba0142SJun-ichiro itojun Hagino break; 29323ba0142SJun-ichiro itojun Hagino ift->ifa_name = cif->ifa_name; 29423ba0142SJun-ichiro itojun Hagino ift->ifa_flags = cif->ifa_flags; 29523ba0142SJun-ichiro itojun Hagino ift->ifa_data = NULL; 2961e09a8abSHajimu UMEMOTO p = (char *)(void *)(ifam + 1); 29723ba0142SJun-ichiro itojun Hagino /* Scan to look for length of address */ 29823ba0142SJun-ichiro itojun Hagino alen = 0; 29923ba0142SJun-ichiro itojun Hagino for (p0 = p, i = 0; i < RTAX_MAX; i++) { 30023ba0142SJun-ichiro itojun Hagino if ((RTA_MASKS & ifam->ifam_addrs & (1 << i)) 30123ba0142SJun-ichiro itojun Hagino == 0) 30223ba0142SJun-ichiro itojun Hagino continue; 3031e09a8abSHajimu UMEMOTO sa = (struct sockaddr *)(void *)p; 30423ba0142SJun-ichiro itojun Hagino len = SA_RLEN(sa); 30523ba0142SJun-ichiro itojun Hagino if (i == RTAX_IFA) { 30623ba0142SJun-ichiro itojun Hagino alen = len; 30723ba0142SJun-ichiro itojun Hagino break; 30823ba0142SJun-ichiro itojun Hagino } 30923ba0142SJun-ichiro itojun Hagino p += len; 31023ba0142SJun-ichiro itojun Hagino } 31123ba0142SJun-ichiro itojun Hagino for (p = p0, i = 0; i < RTAX_MAX; i++) { 31223ba0142SJun-ichiro itojun Hagino if ((RTA_MASKS & ifam->ifam_addrs & (1 << i)) 31323ba0142SJun-ichiro itojun Hagino == 0) 31423ba0142SJun-ichiro itojun Hagino continue; 3151e09a8abSHajimu UMEMOTO sa = (struct sockaddr *)(void *)p; 31623ba0142SJun-ichiro itojun Hagino len = SA_RLEN(sa); 31723ba0142SJun-ichiro itojun Hagino switch (i) { 31823ba0142SJun-ichiro itojun Hagino case RTAX_IFA: 3191e09a8abSHajimu UMEMOTO ift->ifa_addr = 3201e09a8abSHajimu UMEMOTO (struct sockaddr *)(void *)data; 32123ba0142SJun-ichiro itojun Hagino memcpy(data, p, len); 32223ba0142SJun-ichiro itojun Hagino data += len; 32323ba0142SJun-ichiro itojun Hagino break; 32423ba0142SJun-ichiro itojun Hagino 32523ba0142SJun-ichiro itojun Hagino case RTAX_NETMASK: 32623ba0142SJun-ichiro itojun Hagino ift->ifa_netmask = 3271e09a8abSHajimu UMEMOTO (struct sockaddr *)(void *)data; 32823ba0142SJun-ichiro itojun Hagino if (SA_LEN(sa) == 0) { 32923ba0142SJun-ichiro itojun Hagino memset(data, 0, alen); 33023ba0142SJun-ichiro itojun Hagino data += alen; 33123ba0142SJun-ichiro itojun Hagino break; 33223ba0142SJun-ichiro itojun Hagino } 33323ba0142SJun-ichiro itojun Hagino memcpy(data, p, len); 33423ba0142SJun-ichiro itojun Hagino data += len; 33523ba0142SJun-ichiro itojun Hagino break; 33623ba0142SJun-ichiro itojun Hagino 33723ba0142SJun-ichiro itojun Hagino case RTAX_BRD: 33823ba0142SJun-ichiro itojun Hagino ift->ifa_broadaddr = 3391e09a8abSHajimu UMEMOTO (struct sockaddr *)(void *)data; 34023ba0142SJun-ichiro itojun Hagino memcpy(data, p, len); 34123ba0142SJun-ichiro itojun Hagino data += len; 34223ba0142SJun-ichiro itojun Hagino break; 34323ba0142SJun-ichiro itojun Hagino } 34423ba0142SJun-ichiro itojun Hagino p += len; 34523ba0142SJun-ichiro itojun Hagino } 34623ba0142SJun-ichiro itojun Hagino 34723ba0142SJun-ichiro itojun Hagino #ifdef HAVE_IFAM_DATA 34823ba0142SJun-ichiro itojun Hagino /* ifam_data needs to be aligned */ 34923ba0142SJun-ichiro itojun Hagino ift->ifa_data = data = (void *)ALIGN(data); 35023ba0142SJun-ichiro itojun Hagino memcpy(data, &ifam->ifam_data, sizeof(ifam->ifam_data)); 35123ba0142SJun-ichiro itojun Hagino data += sizeof(ifam->ifam_data); 35223ba0142SJun-ichiro itojun Hagino #endif /* HAVE_IFAM_DATA */ 35323ba0142SJun-ichiro itojun Hagino 35423ba0142SJun-ichiro itojun Hagino ift = (ift->ifa_next = ift + 1); 35523ba0142SJun-ichiro itojun Hagino break; 35623ba0142SJun-ichiro itojun Hagino } 35723ba0142SJun-ichiro itojun Hagino } 35823ba0142SJun-ichiro itojun Hagino 35923ba0142SJun-ichiro itojun Hagino free(buf); 36023ba0142SJun-ichiro itojun Hagino #else /* NET_RT_IFLIST */ 36123ba0142SJun-ichiro itojun Hagino ifr = ifc.ifc_req; 36223ba0142SJun-ichiro itojun Hagino lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len]; 36323ba0142SJun-ichiro itojun Hagino 36423ba0142SJun-ichiro itojun Hagino while (ifr < lifr) { 36523ba0142SJun-ichiro itojun Hagino struct sockaddr *sa; 36623ba0142SJun-ichiro itojun Hagino 36723ba0142SJun-ichiro itojun Hagino ift->ifa_name = names; 36823ba0142SJun-ichiro itojun Hagino names[sizeof(ifr->ifr_name)] = 0; 36923ba0142SJun-ichiro itojun Hagino strncpy(names, ifr->ifr_name, sizeof(ifr->ifr_name)); 37023ba0142SJun-ichiro itojun Hagino while (*names++) 37123ba0142SJun-ichiro itojun Hagino ; 37223ba0142SJun-ichiro itojun Hagino 37323ba0142SJun-ichiro itojun Hagino ift->ifa_addr = (struct sockaddr *)data; 37423ba0142SJun-ichiro itojun Hagino sa = &ifr->ifr_addr; 37523ba0142SJun-ichiro itojun Hagino memcpy(data, sa, SA_LEN(sa)); 37623ba0142SJun-ichiro itojun Hagino data += SA_RLEN(sa); 37723ba0142SJun-ichiro itojun Hagino 37823ba0142SJun-ichiro itojun Hagino ifr = (struct ifreq *)(((char *)sa) + SA_LEN(sa)); 37923ba0142SJun-ichiro itojun Hagino ift = (ift->ifa_next = ift + 1); 38023ba0142SJun-ichiro itojun Hagino } 38123ba0142SJun-ichiro itojun Hagino #endif /* NET_RT_IFLIST */ 38223ba0142SJun-ichiro itojun Hagino if (--ift >= ifa) { 38323ba0142SJun-ichiro itojun Hagino ift->ifa_next = NULL; 38423ba0142SJun-ichiro itojun Hagino *pif = ifa; 38523ba0142SJun-ichiro itojun Hagino } else { 38623ba0142SJun-ichiro itojun Hagino *pif = NULL; 38723ba0142SJun-ichiro itojun Hagino free(ifa); 38823ba0142SJun-ichiro itojun Hagino } 38923ba0142SJun-ichiro itojun Hagino return (0); 39023ba0142SJun-ichiro itojun Hagino } 39123ba0142SJun-ichiro itojun Hagino 39223ba0142SJun-ichiro itojun Hagino void 39323ba0142SJun-ichiro itojun Hagino freeifaddrs(struct ifaddrs *ifp) 39423ba0142SJun-ichiro itojun Hagino { 3951e09a8abSHajimu UMEMOTO 39623ba0142SJun-ichiro itojun Hagino free(ifp); 39723ba0142SJun-ichiro itojun Hagino } 398