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