123ba0142SJun-ichiro itojun Hagino /* $FreeBSD$ */ 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 */ 3123ba0142SJun-ichiro itojun Hagino #include <sys/types.h> 3223ba0142SJun-ichiro itojun Hagino #include <sys/ioctl.h> 3323ba0142SJun-ichiro itojun Hagino #include <sys/socket.h> 3423ba0142SJun-ichiro itojun Hagino #include <net/if.h> 3523ba0142SJun-ichiro itojun Hagino #ifdef NET_RT_IFLIST 3623ba0142SJun-ichiro itojun Hagino #include <sys/param.h> 3723ba0142SJun-ichiro itojun Hagino #include <net/route.h> 3823ba0142SJun-ichiro itojun Hagino #include <sys/sysctl.h> 3923ba0142SJun-ichiro itojun Hagino #include <net/if_dl.h> 4023ba0142SJun-ichiro itojun Hagino #endif 4123ba0142SJun-ichiro itojun Hagino 4223ba0142SJun-ichiro itojun Hagino #include <errno.h> 4323ba0142SJun-ichiro itojun Hagino #include <ifaddrs.h> 4423ba0142SJun-ichiro itojun Hagino #include <stdlib.h> 4523ba0142SJun-ichiro itojun Hagino #include <string.h> 4623ba0142SJun-ichiro itojun Hagino 4723ba0142SJun-ichiro itojun Hagino #if !defined(AF_LINK) 4823ba0142SJun-ichiro itojun Hagino #define SA_LEN(sa) sizeof(struct sockaddr) 4923ba0142SJun-ichiro itojun Hagino #endif 5023ba0142SJun-ichiro itojun Hagino 5123ba0142SJun-ichiro itojun Hagino #if !defined(SA_LEN) 5223ba0142SJun-ichiro itojun Hagino #define SA_LEN(sa) (sa)->sa_len 5323ba0142SJun-ichiro itojun Hagino #endif 5423ba0142SJun-ichiro itojun Hagino 5523ba0142SJun-ichiro itojun Hagino #define SALIGN (sizeof(long) - 1) 5623ba0142SJun-ichiro itojun Hagino #define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : (SALIGN + 1)) 5723ba0142SJun-ichiro itojun Hagino 5823ba0142SJun-ichiro itojun Hagino #ifndef ALIGNBYTES 5923ba0142SJun-ichiro itojun Hagino /* 6023ba0142SJun-ichiro itojun Hagino * On systems with a routing socket, ALIGNBYTES should match the value 6123ba0142SJun-ichiro itojun Hagino * that the kernel uses when building the messages. 6223ba0142SJun-ichiro itojun Hagino */ 6323ba0142SJun-ichiro itojun Hagino #define ALIGNBYTES XXX 6423ba0142SJun-ichiro itojun Hagino #endif 6523ba0142SJun-ichiro itojun Hagino #ifndef ALIGN 6623ba0142SJun-ichiro itojun Hagino #define ALIGN(p) (((u_long)(p) + ALIGNBYTES) &~ ALIGNBYTES) 6723ba0142SJun-ichiro itojun Hagino #endif 6823ba0142SJun-ichiro itojun Hagino 6923ba0142SJun-ichiro itojun Hagino #if _BSDI_VERSION >= 199701 7023ba0142SJun-ichiro itojun Hagino #define HAVE_IFM_DATA 7123ba0142SJun-ichiro itojun Hagino #endif 7223ba0142SJun-ichiro itojun Hagino 7323ba0142SJun-ichiro itojun Hagino #if _BSDI_VERSION >= 199802 7423ba0142SJun-ichiro itojun Hagino #define HAVE_IFAM_DATA 7523ba0142SJun-ichiro itojun Hagino #endif 7623ba0142SJun-ichiro itojun Hagino 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; 8323ba0142SJun-ichiro itojun Hagino #ifdef NET_RT_IFLIST 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; 9123ba0142SJun-ichiro itojun Hagino struct if_msghdr *ifm; 9223ba0142SJun-ichiro itojun Hagino struct ifa_msghdr *ifam; 9323ba0142SJun-ichiro itojun Hagino struct sockaddr_dl *dl; 9423ba0142SJun-ichiro itojun Hagino struct sockaddr *sa; 9523ba0142SJun-ichiro itojun Hagino struct ifaddrs *ifa, *ift; 9623ba0142SJun-ichiro itojun Hagino u_short index = 0; 9723ba0142SJun-ichiro itojun Hagino #else /* NET_RT_IFLIST */ 9823ba0142SJun-ichiro itojun Hagino char buf[1024]; 9923ba0142SJun-ichiro itojun Hagino int m, sock; 10023ba0142SJun-ichiro itojun Hagino struct ifconf ifc; 10123ba0142SJun-ichiro itojun Hagino struct ifreq *ifr; 10223ba0142SJun-ichiro itojun Hagino struct ifreq *lifr; 10323ba0142SJun-ichiro itojun Hagino #endif /* NET_RT_IFLIST */ 10423ba0142SJun-ichiro itojun Hagino int i; 10523ba0142SJun-ichiro itojun Hagino size_t len, alen; 10623ba0142SJun-ichiro itojun Hagino char *data; 10723ba0142SJun-ichiro itojun Hagino char *names; 10823ba0142SJun-ichiro itojun Hagino 10923ba0142SJun-ichiro itojun Hagino #ifdef NET_RT_IFLIST 11023ba0142SJun-ichiro itojun Hagino mib[0] = CTL_NET; 11123ba0142SJun-ichiro itojun Hagino mib[1] = PF_ROUTE; 11223ba0142SJun-ichiro itojun Hagino mib[2] = 0; /* protocol */ 11323ba0142SJun-ichiro itojun Hagino mib[3] = 0; /* wildcard address family */ 11423ba0142SJun-ichiro itojun Hagino mib[4] = NET_RT_IFLIST; 11523ba0142SJun-ichiro itojun Hagino mib[5] = 0; /* no flags */ 11623ba0142SJun-ichiro itojun Hagino if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) 11723ba0142SJun-ichiro itojun Hagino return (-1); 11823ba0142SJun-ichiro itojun Hagino if ((buf = malloc(needed)) == NULL) 11923ba0142SJun-ichiro itojun Hagino return (-1); 12023ba0142SJun-ichiro itojun Hagino if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { 12123ba0142SJun-ichiro itojun Hagino free(buf); 12223ba0142SJun-ichiro itojun Hagino return (-1); 12323ba0142SJun-ichiro itojun Hagino } 12423ba0142SJun-ichiro itojun Hagino 12523ba0142SJun-ichiro itojun Hagino for (next = buf; next < buf + needed; next += rtm->rtm_msglen) { 12623ba0142SJun-ichiro itojun Hagino rtm = (struct rt_msghdr *)next; 12723ba0142SJun-ichiro itojun Hagino if (rtm->rtm_version != RTM_VERSION) 12823ba0142SJun-ichiro itojun Hagino continue; 12923ba0142SJun-ichiro itojun Hagino switch (rtm->rtm_type) { 13023ba0142SJun-ichiro itojun Hagino case RTM_IFINFO: 13123ba0142SJun-ichiro itojun Hagino ifm = (struct if_msghdr *)rtm; 13223ba0142SJun-ichiro itojun Hagino if (ifm->ifm_addrs & RTA_IFP) { 13323ba0142SJun-ichiro itojun Hagino index = ifm->ifm_index; 13423ba0142SJun-ichiro itojun Hagino ++icnt; 13523ba0142SJun-ichiro itojun Hagino dl = (struct sockaddr_dl *)(ifm + 1); 13623ba0142SJun-ichiro itojun Hagino dcnt += SA_RLEN((struct sockaddr *)dl) + 13723ba0142SJun-ichiro itojun Hagino ALIGNBYTES; 13823ba0142SJun-ichiro itojun Hagino #ifdef HAVE_IFM_DATA 13923ba0142SJun-ichiro itojun Hagino dcnt += sizeof(ifm->ifm_data); 14023ba0142SJun-ichiro itojun Hagino #endif /* HAVE_IFM_DATA */ 14123ba0142SJun-ichiro itojun Hagino ncnt += dl->sdl_nlen + 1; 14223ba0142SJun-ichiro itojun Hagino } else 14323ba0142SJun-ichiro itojun Hagino index = 0; 14423ba0142SJun-ichiro itojun Hagino break; 14523ba0142SJun-ichiro itojun Hagino 14623ba0142SJun-ichiro itojun Hagino case RTM_NEWADDR: 14723ba0142SJun-ichiro itojun Hagino ifam = (struct ifa_msghdr *)rtm; 14823ba0142SJun-ichiro itojun Hagino if (index && ifam->ifam_index != index) 14923ba0142SJun-ichiro itojun Hagino abort(); /* this cannot happen */ 15023ba0142SJun-ichiro itojun Hagino 15123ba0142SJun-ichiro itojun Hagino #define RTA_MASKS (RTA_NETMASK | RTA_IFA | RTA_BRD) 15223ba0142SJun-ichiro itojun Hagino if (index == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0) 15323ba0142SJun-ichiro itojun Hagino break; 15423ba0142SJun-ichiro itojun Hagino p = (char *)(ifam + 1); 15523ba0142SJun-ichiro itojun Hagino ++icnt; 15623ba0142SJun-ichiro itojun Hagino #ifdef HAVE_IFAM_DATA 15723ba0142SJun-ichiro itojun Hagino dcnt += sizeof(ifam->ifam_data) + ALIGNBYTES; 15823ba0142SJun-ichiro itojun Hagino #endif /* HAVE_IFAM_DATA */ 15923ba0142SJun-ichiro itojun Hagino /* Scan to look for length of address */ 16023ba0142SJun-ichiro itojun Hagino alen = 0; 16123ba0142SJun-ichiro itojun Hagino for (p0 = p, i = 0; i < RTAX_MAX; i++) { 16223ba0142SJun-ichiro itojun Hagino if ((RTA_MASKS & ifam->ifam_addrs & (1 << i)) 16323ba0142SJun-ichiro itojun Hagino == 0) 16423ba0142SJun-ichiro itojun Hagino continue; 16523ba0142SJun-ichiro itojun Hagino sa = (struct sockaddr *)p; 16623ba0142SJun-ichiro itojun Hagino len = SA_RLEN(sa); 16723ba0142SJun-ichiro itojun Hagino if (i == RTAX_IFA) { 16823ba0142SJun-ichiro itojun Hagino alen = len; 16923ba0142SJun-ichiro itojun Hagino break; 17023ba0142SJun-ichiro itojun Hagino } 17123ba0142SJun-ichiro itojun Hagino p += len; 17223ba0142SJun-ichiro itojun Hagino } 17323ba0142SJun-ichiro itojun Hagino for (p = p0, i = 0; i < RTAX_MAX; i++) { 17423ba0142SJun-ichiro itojun Hagino if ((RTA_MASKS & ifam->ifam_addrs & (1 << i)) 17523ba0142SJun-ichiro itojun Hagino == 0) 17623ba0142SJun-ichiro itojun Hagino continue; 17723ba0142SJun-ichiro itojun Hagino sa = (struct sockaddr *)p; 17823ba0142SJun-ichiro itojun Hagino len = SA_RLEN(sa); 17923ba0142SJun-ichiro itojun Hagino if (i == RTAX_NETMASK && SA_LEN(sa) == 0) 18023ba0142SJun-ichiro itojun Hagino dcnt += alen; 18123ba0142SJun-ichiro itojun Hagino else 18223ba0142SJun-ichiro itojun Hagino dcnt += len; 18323ba0142SJun-ichiro itojun Hagino p += len; 18423ba0142SJun-ichiro itojun Hagino } 18523ba0142SJun-ichiro itojun Hagino break; 18623ba0142SJun-ichiro itojun Hagino } 18723ba0142SJun-ichiro itojun Hagino } 18823ba0142SJun-ichiro itojun Hagino #else /* NET_RT_IFLIST */ 18923ba0142SJun-ichiro itojun Hagino ifc.ifc_buf = buf; 19023ba0142SJun-ichiro itojun Hagino ifc.ifc_len = sizeof(buf); 19123ba0142SJun-ichiro itojun Hagino 19223ba0142SJun-ichiro itojun Hagino if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) 19323ba0142SJun-ichiro itojun Hagino return (-1); 19423ba0142SJun-ichiro itojun Hagino i = ioctl(sock, SIOCGIFCONF, (char *)&ifc); 19523ba0142SJun-ichiro itojun Hagino close(sock); 19623ba0142SJun-ichiro itojun Hagino if (i < 0) 19723ba0142SJun-ichiro itojun Hagino return (-1); 19823ba0142SJun-ichiro itojun Hagino 19923ba0142SJun-ichiro itojun Hagino ifr = ifc.ifc_req; 20023ba0142SJun-ichiro itojun Hagino lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len]; 20123ba0142SJun-ichiro itojun Hagino 20223ba0142SJun-ichiro itojun Hagino while (ifr < lifr) { 20323ba0142SJun-ichiro itojun Hagino struct sockaddr *sa; 20423ba0142SJun-ichiro itojun Hagino 20523ba0142SJun-ichiro itojun Hagino sa = &ifr->ifr_addr; 20623ba0142SJun-ichiro itojun Hagino ++icnt; 20723ba0142SJun-ichiro itojun Hagino dcnt += SA_RLEN(sa); 20823ba0142SJun-ichiro itojun Hagino ncnt += sizeof(ifr->ifr_name) + 1; 20923ba0142SJun-ichiro itojun Hagino 21023ba0142SJun-ichiro itojun Hagino ifr = (struct ifreq *)(((char *)sa) + SA_LEN(sa)); 21123ba0142SJun-ichiro itojun Hagino } 21223ba0142SJun-ichiro itojun Hagino #endif /* NET_RT_IFLIST */ 21323ba0142SJun-ichiro itojun Hagino 21423ba0142SJun-ichiro itojun Hagino if (icnt + dcnt + ncnt == 1) { 21523ba0142SJun-ichiro itojun Hagino *pif = NULL; 21623ba0142SJun-ichiro itojun Hagino free(buf); 21723ba0142SJun-ichiro itojun Hagino return (0); 21823ba0142SJun-ichiro itojun Hagino } 21923ba0142SJun-ichiro itojun Hagino data = malloc(sizeof(struct ifaddrs) * icnt + dcnt + ncnt); 22023ba0142SJun-ichiro itojun Hagino if (data == NULL) { 22123ba0142SJun-ichiro itojun Hagino free(buf); 22223ba0142SJun-ichiro itojun Hagino return(-1); 22323ba0142SJun-ichiro itojun Hagino } 22423ba0142SJun-ichiro itojun Hagino 22523ba0142SJun-ichiro itojun Hagino ifa = (struct ifaddrs *)data; 22623ba0142SJun-ichiro itojun Hagino data += sizeof(struct ifaddrs) * icnt; 22723ba0142SJun-ichiro itojun Hagino names = data + dcnt; 22823ba0142SJun-ichiro itojun Hagino 22923ba0142SJun-ichiro itojun Hagino memset(ifa, 0, sizeof(struct ifaddrs) * icnt); 23023ba0142SJun-ichiro itojun Hagino ift = ifa; 23123ba0142SJun-ichiro itojun Hagino 23223ba0142SJun-ichiro itojun Hagino #ifdef NET_RT_IFLIST 23323ba0142SJun-ichiro itojun Hagino index = 0; 23423ba0142SJun-ichiro itojun Hagino for (next = buf; next < buf + needed; next += rtm->rtm_msglen) { 23523ba0142SJun-ichiro itojun Hagino rtm = (struct rt_msghdr *)next; 23623ba0142SJun-ichiro itojun Hagino if (rtm->rtm_version != RTM_VERSION) 23723ba0142SJun-ichiro itojun Hagino continue; 23823ba0142SJun-ichiro itojun Hagino switch (rtm->rtm_type) { 23923ba0142SJun-ichiro itojun Hagino case RTM_IFINFO: 24023ba0142SJun-ichiro itojun Hagino ifm = (struct if_msghdr *)rtm; 24123ba0142SJun-ichiro itojun Hagino if (ifm->ifm_addrs & RTA_IFP) { 24223ba0142SJun-ichiro itojun Hagino index = ifm->ifm_index; 24323ba0142SJun-ichiro itojun Hagino dl = (struct sockaddr_dl *)(ifm + 1); 24423ba0142SJun-ichiro itojun Hagino 24523ba0142SJun-ichiro itojun Hagino cif = ift; 24623ba0142SJun-ichiro itojun Hagino ift->ifa_name = names; 24723ba0142SJun-ichiro itojun Hagino ift->ifa_flags = (int)ifm->ifm_flags; 24823ba0142SJun-ichiro itojun Hagino memcpy(names, dl->sdl_data, dl->sdl_nlen); 24923ba0142SJun-ichiro itojun Hagino names[dl->sdl_nlen] = 0; 25023ba0142SJun-ichiro itojun Hagino names += dl->sdl_nlen + 1; 25123ba0142SJun-ichiro itojun Hagino 25223ba0142SJun-ichiro itojun Hagino ift->ifa_addr = (struct sockaddr *)data; 25323ba0142SJun-ichiro itojun Hagino memcpy(data, dl, SA_LEN((struct sockaddr *)dl)); 25423ba0142SJun-ichiro itojun Hagino data += SA_RLEN((struct sockaddr *)dl); 25523ba0142SJun-ichiro itojun Hagino 25623ba0142SJun-ichiro itojun Hagino #ifdef HAVE_IFM_DATA 25723ba0142SJun-ichiro itojun Hagino /* ifm_data needs to be aligned */ 25823ba0142SJun-ichiro itojun Hagino ift->ifa_data = data = (void *)ALIGN(data); 25923ba0142SJun-ichiro itojun Hagino memcpy(data, &ifm->ifm_data, sizeof(ifm->ifm_data)); 26023ba0142SJun-ichiro itojun Hagino data += sizeof(ifm->ifm_data); 26123ba0142SJun-ichiro itojun Hagino #else /* HAVE_IFM_DATA */ 26223ba0142SJun-ichiro itojun Hagino ift->ifa_data = NULL; 26323ba0142SJun-ichiro itojun Hagino #endif /* HAVE_IFM_DATA */ 26423ba0142SJun-ichiro itojun Hagino 26523ba0142SJun-ichiro itojun Hagino ift = (ift->ifa_next = ift + 1); 26623ba0142SJun-ichiro itojun Hagino } else 26723ba0142SJun-ichiro itojun Hagino index = 0; 26823ba0142SJun-ichiro itojun Hagino break; 26923ba0142SJun-ichiro itojun Hagino 27023ba0142SJun-ichiro itojun Hagino case RTM_NEWADDR: 27123ba0142SJun-ichiro itojun Hagino ifam = (struct ifa_msghdr *)rtm; 27223ba0142SJun-ichiro itojun Hagino if (index && ifam->ifam_index != index) 27323ba0142SJun-ichiro itojun Hagino abort(); /* this cannot happen */ 27423ba0142SJun-ichiro itojun Hagino 27523ba0142SJun-ichiro itojun Hagino if (index == 0 || (ifam->ifam_addrs & RTA_MASKS) == 0) 27623ba0142SJun-ichiro itojun Hagino break; 27723ba0142SJun-ichiro itojun Hagino ift->ifa_name = cif->ifa_name; 27823ba0142SJun-ichiro itojun Hagino ift->ifa_flags = cif->ifa_flags; 27923ba0142SJun-ichiro itojun Hagino ift->ifa_data = NULL; 28023ba0142SJun-ichiro itojun Hagino p = (char *)(ifam + 1); 28123ba0142SJun-ichiro itojun Hagino /* Scan to look for length of address */ 28223ba0142SJun-ichiro itojun Hagino alen = 0; 28323ba0142SJun-ichiro itojun Hagino for (p0 = p, i = 0; i < RTAX_MAX; i++) { 28423ba0142SJun-ichiro itojun Hagino if ((RTA_MASKS & ifam->ifam_addrs & (1 << i)) 28523ba0142SJun-ichiro itojun Hagino == 0) 28623ba0142SJun-ichiro itojun Hagino continue; 28723ba0142SJun-ichiro itojun Hagino sa = (struct sockaddr *)p; 28823ba0142SJun-ichiro itojun Hagino len = SA_RLEN(sa); 28923ba0142SJun-ichiro itojun Hagino if (i == RTAX_IFA) { 29023ba0142SJun-ichiro itojun Hagino alen = len; 29123ba0142SJun-ichiro itojun Hagino break; 29223ba0142SJun-ichiro itojun Hagino } 29323ba0142SJun-ichiro itojun Hagino p += len; 29423ba0142SJun-ichiro itojun Hagino } 29523ba0142SJun-ichiro itojun Hagino for (p = p0, i = 0; i < RTAX_MAX; i++) { 29623ba0142SJun-ichiro itojun Hagino if ((RTA_MASKS & ifam->ifam_addrs & (1 << i)) 29723ba0142SJun-ichiro itojun Hagino == 0) 29823ba0142SJun-ichiro itojun Hagino continue; 29923ba0142SJun-ichiro itojun Hagino sa = (struct sockaddr *)p; 30023ba0142SJun-ichiro itojun Hagino len = SA_RLEN(sa); 30123ba0142SJun-ichiro itojun Hagino switch (i) { 30223ba0142SJun-ichiro itojun Hagino case RTAX_IFA: 30323ba0142SJun-ichiro itojun Hagino ift->ifa_addr = (struct sockaddr *)data; 30423ba0142SJun-ichiro itojun Hagino memcpy(data, p, len); 30523ba0142SJun-ichiro itojun Hagino data += len; 30623ba0142SJun-ichiro itojun Hagino break; 30723ba0142SJun-ichiro itojun Hagino 30823ba0142SJun-ichiro itojun Hagino case RTAX_NETMASK: 30923ba0142SJun-ichiro itojun Hagino ift->ifa_netmask = 31023ba0142SJun-ichiro itojun Hagino (struct sockaddr *)data; 31123ba0142SJun-ichiro itojun Hagino if (SA_LEN(sa) == 0) { 31223ba0142SJun-ichiro itojun Hagino memset(data, 0, alen); 31323ba0142SJun-ichiro itojun Hagino data += alen; 31423ba0142SJun-ichiro itojun Hagino break; 31523ba0142SJun-ichiro itojun Hagino } 31623ba0142SJun-ichiro itojun Hagino memcpy(data, p, len); 31723ba0142SJun-ichiro itojun Hagino data += len; 31823ba0142SJun-ichiro itojun Hagino break; 31923ba0142SJun-ichiro itojun Hagino 32023ba0142SJun-ichiro itojun Hagino case RTAX_BRD: 32123ba0142SJun-ichiro itojun Hagino ift->ifa_broadaddr = 32223ba0142SJun-ichiro itojun Hagino (struct sockaddr *)data; 32323ba0142SJun-ichiro itojun Hagino memcpy(data, p, len); 32423ba0142SJun-ichiro itojun Hagino data += len; 32523ba0142SJun-ichiro itojun Hagino break; 32623ba0142SJun-ichiro itojun Hagino } 32723ba0142SJun-ichiro itojun Hagino p += len; 32823ba0142SJun-ichiro itojun Hagino } 32923ba0142SJun-ichiro itojun Hagino 33023ba0142SJun-ichiro itojun Hagino #ifdef HAVE_IFAM_DATA 33123ba0142SJun-ichiro itojun Hagino /* ifam_data needs to be aligned */ 33223ba0142SJun-ichiro itojun Hagino ift->ifa_data = data = (void *)ALIGN(data); 33323ba0142SJun-ichiro itojun Hagino memcpy(data, &ifam->ifam_data, sizeof(ifam->ifam_data)); 33423ba0142SJun-ichiro itojun Hagino data += sizeof(ifam->ifam_data); 33523ba0142SJun-ichiro itojun Hagino #endif /* HAVE_IFAM_DATA */ 33623ba0142SJun-ichiro itojun Hagino 33723ba0142SJun-ichiro itojun Hagino ift = (ift->ifa_next = ift + 1); 33823ba0142SJun-ichiro itojun Hagino break; 33923ba0142SJun-ichiro itojun Hagino } 34023ba0142SJun-ichiro itojun Hagino } 34123ba0142SJun-ichiro itojun Hagino 34223ba0142SJun-ichiro itojun Hagino free(buf); 34323ba0142SJun-ichiro itojun Hagino #else /* NET_RT_IFLIST */ 34423ba0142SJun-ichiro itojun Hagino ifr = ifc.ifc_req; 34523ba0142SJun-ichiro itojun Hagino lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len]; 34623ba0142SJun-ichiro itojun Hagino 34723ba0142SJun-ichiro itojun Hagino while (ifr < lifr) { 34823ba0142SJun-ichiro itojun Hagino struct sockaddr *sa; 34923ba0142SJun-ichiro itojun Hagino 35023ba0142SJun-ichiro itojun Hagino ift->ifa_name = names; 35123ba0142SJun-ichiro itojun Hagino names[sizeof(ifr->ifr_name)] = 0; 35223ba0142SJun-ichiro itojun Hagino strncpy(names, ifr->ifr_name, sizeof(ifr->ifr_name)); 35323ba0142SJun-ichiro itojun Hagino while (*names++) 35423ba0142SJun-ichiro itojun Hagino ; 35523ba0142SJun-ichiro itojun Hagino 35623ba0142SJun-ichiro itojun Hagino ift->ifa_addr = (struct sockaddr *)data; 35723ba0142SJun-ichiro itojun Hagino sa = &ifr->ifr_addr; 35823ba0142SJun-ichiro itojun Hagino memcpy(data, sa, SA_LEN(sa)); 35923ba0142SJun-ichiro itojun Hagino data += SA_RLEN(sa); 36023ba0142SJun-ichiro itojun Hagino 36123ba0142SJun-ichiro itojun Hagino ifr = (struct ifreq *)(((char *)sa) + SA_LEN(sa)); 36223ba0142SJun-ichiro itojun Hagino ift = (ift->ifa_next = ift + 1); 36323ba0142SJun-ichiro itojun Hagino } 36423ba0142SJun-ichiro itojun Hagino #endif /* NET_RT_IFLIST */ 36523ba0142SJun-ichiro itojun Hagino if (--ift >= ifa) { 36623ba0142SJun-ichiro itojun Hagino ift->ifa_next = NULL; 36723ba0142SJun-ichiro itojun Hagino *pif = ifa; 36823ba0142SJun-ichiro itojun Hagino } else { 36923ba0142SJun-ichiro itojun Hagino *pif = NULL; 37023ba0142SJun-ichiro itojun Hagino free(ifa); 37123ba0142SJun-ichiro itojun Hagino } 37223ba0142SJun-ichiro itojun Hagino return (0); 37323ba0142SJun-ichiro itojun Hagino } 37423ba0142SJun-ichiro itojun Hagino 37523ba0142SJun-ichiro itojun Hagino void 37623ba0142SJun-ichiro itojun Hagino freeifaddrs(struct ifaddrs *ifp) 37723ba0142SJun-ichiro itojun Hagino { 37823ba0142SJun-ichiro itojun Hagino free(ifp); 37923ba0142SJun-ichiro itojun Hagino } 380