diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libc/net/getifaddrs.c | 117 |
1 files changed, 5 insertions, 112 deletions
diff --git a/src/lib/libc/net/getifaddrs.c b/src/lib/libc/net/getifaddrs.c index ee8f1cb5ab..63fc42e59e 100644 --- a/src/lib/libc/net/getifaddrs.c +++ b/src/lib/libc/net/getifaddrs.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: getifaddrs.c,v 1.7 2002/01/02 23:00:10 deraadt Exp $ */ | 1 | /* $OpenBSD: getifaddrs.c,v 1.8 2002/08/09 06:11:53 itojun Exp $ */ |
| 2 | 2 | ||
| 3 | /* | 3 | /* |
| 4 | * Copyright (c) 1995, 1999 | 4 | * Copyright (c) 1995, 1999 |
| @@ -32,12 +32,10 @@ | |||
| 32 | #include <sys/ioctl.h> | 32 | #include <sys/ioctl.h> |
| 33 | #include <sys/socket.h> | 33 | #include <sys/socket.h> |
| 34 | #include <net/if.h> | 34 | #include <net/if.h> |
| 35 | #ifdef NET_RT_IFLIST | ||
| 36 | #include <sys/param.h> | 35 | #include <sys/param.h> |
| 37 | #include <net/route.h> | 36 | #include <net/route.h> |
| 38 | #include <sys/sysctl.h> | 37 | #include <sys/sysctl.h> |
| 39 | #include <net/if_dl.h> | 38 | #include <net/if_dl.h> |
| 40 | #endif | ||
| 41 | 39 | ||
| 42 | #include <errno.h> | 40 | #include <errno.h> |
| 43 | #include <ifaddrs.h> | 41 | #include <ifaddrs.h> |
| @@ -45,48 +43,15 @@ | |||
| 45 | #include <string.h> | 43 | #include <string.h> |
| 46 | #include <unistd.h> | 44 | #include <unistd.h> |
| 47 | 45 | ||
| 48 | #if !defined(AF_LINK) | ||
| 49 | #define SA_LEN(sa) sizeof(struct sockaddr) | ||
| 50 | #endif | ||
| 51 | |||
| 52 | #if !defined(SA_LEN) | ||
| 53 | #define SA_LEN(sa) (sa)->sa_len | ||
| 54 | #endif | ||
| 55 | |||
| 56 | #define SALIGN (sizeof(long) - 1) | 46 | #define SALIGN (sizeof(long) - 1) |
| 57 | #define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : (SALIGN + 1)) | 47 | #define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : (SALIGN + 1)) |
| 58 | 48 | ||
| 59 | #ifndef ALIGNBYTES | ||
| 60 | /* | ||
| 61 | * On systems with a routing socket, ALIGNBYTES should match the value | ||
| 62 | * that the kernel uses when building the messages. | ||
| 63 | */ | ||
| 64 | #define ALIGNBYTES XXX | ||
| 65 | #endif | ||
| 66 | #ifndef ALIGN | ||
| 67 | #define ALIGN(p) (((u_long)(p) + ALIGNBYTES) &~ ALIGNBYTES) | ||
| 68 | #endif | ||
| 69 | |||
| 70 | #if _BSDI_VERSION >= 199701 | ||
| 71 | #define HAVE_IFM_DATA | ||
| 72 | #endif | ||
| 73 | |||
| 74 | #if _BSDI_VERSION >= 199802 | ||
| 75 | /* ifam_data is very specific to recent versions of bsdi */ | ||
| 76 | #define HAVE_IFAM_DATA | ||
| 77 | #endif | ||
| 78 | |||
| 79 | #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) | ||
| 80 | #define HAVE_IFM_DATA | ||
| 81 | #endif | ||
| 82 | |||
| 83 | int | 49 | int |
| 84 | getifaddrs(struct ifaddrs **pif) | 50 | getifaddrs(struct ifaddrs **pif) |
| 85 | { | 51 | { |
| 86 | int icnt = 1; | 52 | int icnt = 1; |
| 87 | int dcnt = 0; | 53 | int dcnt = 0; |
| 88 | int ncnt = 0; | 54 | int ncnt = 0; |
| 89 | #ifdef NET_RT_IFLIST | ||
| 90 | int mib[6]; | 55 | int mib[6]; |
| 91 | size_t needed; | 56 | size_t needed; |
| 92 | char *buf; | 57 | char *buf; |
| @@ -100,19 +65,11 @@ getifaddrs(struct ifaddrs **pif) | |||
| 100 | struct sockaddr *sa; | 65 | struct sockaddr *sa; |
| 101 | u_short index = 0; | 66 | u_short index = 0; |
| 102 | size_t len, alen; | 67 | size_t len, alen; |
| 103 | #else /* NET_RT_IFLIST */ | ||
| 104 | char buf[1024]; | ||
| 105 | int sock; | ||
| 106 | struct ifconf ifc; | ||
| 107 | struct ifreq *ifr; | ||
| 108 | struct ifreq *lifr; | ||
| 109 | #endif /* NET_RT_IFLIST */ | ||
| 110 | struct ifaddrs *ifa, *ift; | 68 | struct ifaddrs *ifa, *ift; |
| 111 | int i; | 69 | int i; |
| 112 | char *data; | 70 | char *data; |
| 113 | char *names; | 71 | char *names; |
| 114 | 72 | ||
| 115 | #ifdef NET_RT_IFLIST | ||
| 116 | mib[0] = CTL_NET; | 73 | mib[0] = CTL_NET; |
| 117 | mib[1] = PF_ROUTE; | 74 | mib[1] = PF_ROUTE; |
| 118 | mib[2] = 0; /* protocol */ | 75 | mib[2] = 0; /* protocol */ |
| @@ -141,9 +98,7 @@ getifaddrs(struct ifaddrs **pif) | |||
| 141 | dl = (struct sockaddr_dl *)(ifm + 1); | 98 | dl = (struct sockaddr_dl *)(ifm + 1); |
| 142 | dcnt += SA_RLEN((struct sockaddr *)dl) + | 99 | dcnt += SA_RLEN((struct sockaddr *)dl) + |
| 143 | ALIGNBYTES; | 100 | ALIGNBYTES; |
| 144 | #ifdef HAVE_IFM_DATA | ||
| 145 | dcnt += sizeof(ifm->ifm_data); | 101 | dcnt += sizeof(ifm->ifm_data); |
| 146 | #endif /* HAVE_IFM_DATA */ | ||
| 147 | ncnt += dl->sdl_nlen + 1; | 102 | ncnt += dl->sdl_nlen + 1; |
| 148 | } else | 103 | } else |
| 149 | index = 0; | 104 | index = 0; |
| @@ -159,9 +114,6 @@ getifaddrs(struct ifaddrs **pif) | |||
| 159 | break; | 114 | break; |
| 160 | p = (char *)(ifam + 1); | 115 | p = (char *)(ifam + 1); |
| 161 | ++icnt; | 116 | ++icnt; |
| 162 | #ifdef HAVE_IFAM_DATA | ||
| 163 | dcnt += sizeof(ifam->ifam_data) + ALIGNBYTES; | ||
| 164 | #endif /* HAVE_IFAM_DATA */ | ||
| 165 | /* Scan to look for length of address */ | 117 | /* Scan to look for length of address */ |
| 166 | alen = 0; | 118 | alen = 0; |
| 167 | for (p0 = p, i = 0; i < RTAX_MAX; i++) { | 119 | for (p0 = p, i = 0; i < RTAX_MAX; i++) { |
| @@ -182,7 +134,7 @@ getifaddrs(struct ifaddrs **pif) | |||
| 182 | continue; | 134 | continue; |
| 183 | sa = (struct sockaddr *)p; | 135 | sa = (struct sockaddr *)p; |
| 184 | len = SA_RLEN(sa); | 136 | len = SA_RLEN(sa); |
| 185 | if (i == RTAX_NETMASK && SA_LEN(sa) == 0) | 137 | if (i == RTAX_NETMASK && sa->sa_len == 0) |
| 186 | dcnt += alen; | 138 | dcnt += alen; |
| 187 | else | 139 | else |
| 188 | dcnt += len; | 140 | dcnt += len; |
| @@ -191,34 +143,6 @@ getifaddrs(struct ifaddrs **pif) | |||
| 191 | break; | 143 | break; |
| 192 | } | 144 | } |
| 193 | } | 145 | } |
| 194 | #else /* NET_RT_IFLIST */ | ||
| 195 | ifc.ifc_buf = buf; | ||
| 196 | ifc.ifc_len = sizeof(buf); | ||
| 197 | |||
| 198 | if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) | ||
| 199 | return (-1); | ||
| 200 | i = ioctl(sock, SIOCGIFCONF, (char *)&ifc); | ||
| 201 | close(sock); | ||
| 202 | if (i < 0) | ||
| 203 | return (-1); | ||
| 204 | |||
| 205 | ifr = ifc.ifc_req; | ||
| 206 | lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len]; | ||
| 207 | |||
| 208 | while (ifr < lifr) { | ||
| 209 | struct sockaddr *sa; | ||
| 210 | |||
| 211 | sa = &ifr->ifr_addr; | ||
| 212 | ++icnt; | ||
| 213 | dcnt += SA_RLEN(sa); | ||
| 214 | ncnt += sizeof(ifr->ifr_name) + 1; | ||
| 215 | |||
| 216 | if (SA_LEN(sa) < sizeof(*sa)) | ||
| 217 | ifr = (struct ifreq *)(((char *)sa) + sizeof(*sa)); | ||
| 218 | else | ||
| 219 | ifr = (struct ifreq *)(((char *)sa) + SA_LEN(sa)); | ||
| 220 | } | ||
| 221 | #endif /* NET_RT_IFLIST */ | ||
| 222 | 146 | ||
| 223 | if (icnt + dcnt + ncnt == 1) { | 147 | if (icnt + dcnt + ncnt == 1) { |
| 224 | *pif = NULL; | 148 | *pif = NULL; |
| @@ -238,7 +162,6 @@ getifaddrs(struct ifaddrs **pif) | |||
| 238 | memset(ifa, 0, sizeof(struct ifaddrs) * icnt); | 162 | memset(ifa, 0, sizeof(struct ifaddrs) * icnt); |
| 239 | ift = ifa; | 163 | ift = ifa; |
| 240 | 164 | ||
| 241 | #ifdef NET_RT_IFLIST | ||
| 242 | index = 0; | 165 | index = 0; |
| 243 | for (next = buf; next < buf + needed; next += rtm->rtm_msglen) { | 166 | for (next = buf; next < buf + needed; next += rtm->rtm_msglen) { |
| 244 | rtm = (struct rt_msghdr *)next; | 167 | rtm = (struct rt_msghdr *)next; |
| @@ -259,17 +182,14 @@ getifaddrs(struct ifaddrs **pif) | |||
| 259 | names += dl->sdl_nlen + 1; | 182 | names += dl->sdl_nlen + 1; |
| 260 | 183 | ||
| 261 | ift->ifa_addr = (struct sockaddr *)data; | 184 | ift->ifa_addr = (struct sockaddr *)data; |
| 262 | memcpy(data, dl, SA_LEN((struct sockaddr *)dl)); | 185 | memcpy(data, dl, |
| 186 | ((struct sockaddr *)dl)->sa_len); | ||
| 263 | data += SA_RLEN((struct sockaddr *)dl); | 187 | data += SA_RLEN((struct sockaddr *)dl); |
| 264 | 188 | ||
| 265 | #ifdef HAVE_IFM_DATA | ||
| 266 | /* ifm_data needs to be aligned */ | 189 | /* ifm_data needs to be aligned */ |
| 267 | ift->ifa_data = data = (void *)ALIGN(data); | 190 | ift->ifa_data = data = (void *)ALIGN(data); |
| 268 | memcpy(data, &ifm->ifm_data, sizeof(ifm->ifm_data)); | 191 | memcpy(data, &ifm->ifm_data, sizeof(ifm->ifm_data)); |
| 269 | data += sizeof(ifm->ifm_data); | 192 | data += sizeof(ifm->ifm_data); |
| 270 | #else /* HAVE_IFM_DATA */ | ||
| 271 | ift->ifa_data = NULL; | ||
| 272 | #endif /* HAVE_IFM_DATA */ | ||
| 273 | 193 | ||
| 274 | ift = (ift->ifa_next = ift + 1); | 194 | ift = (ift->ifa_next = ift + 1); |
| 275 | } else | 195 | } else |
| @@ -317,7 +237,7 @@ getifaddrs(struct ifaddrs **pif) | |||
| 317 | case RTAX_NETMASK: | 237 | case RTAX_NETMASK: |
| 318 | ift->ifa_netmask = | 238 | ift->ifa_netmask = |
| 319 | (struct sockaddr *)data; | 239 | (struct sockaddr *)data; |
| 320 | if (SA_LEN(sa) == 0) { | 240 | if (sa->sa_len == 0) { |
| 321 | memset(data, 0, alen); | 241 | memset(data, 0, alen); |
| 322 | data += alen; | 242 | data += alen; |
| 323 | break; | 243 | break; |
| @@ -336,12 +256,6 @@ getifaddrs(struct ifaddrs **pif) | |||
| 336 | p += len; | 256 | p += len; |
| 337 | } | 257 | } |
| 338 | 258 | ||
| 339 | #ifdef HAVE_IFAM_DATA | ||
| 340 | /* ifam_data needs to be aligned */ | ||
| 341 | ift->ifa_data = data = (void *)ALIGN(data); | ||
| 342 | memcpy(data, &ifam->ifam_data, sizeof(ifam->ifam_data)); | ||
| 343 | data += sizeof(ifam->ifam_data); | ||
| 344 | #endif /* HAVE_IFAM_DATA */ | ||
| 345 | 259 | ||
| 346 | ift = (ift->ifa_next = ift + 1); | 260 | ift = (ift->ifa_next = ift + 1); |
| 347 | break; | 261 | break; |
| @@ -349,27 +263,6 @@ getifaddrs(struct ifaddrs **pif) | |||
| 349 | } | 263 | } |
| 350 | 264 | ||
| 351 | free(buf); | 265 | free(buf); |
| 352 | #else /* NET_RT_IFLIST */ | ||
| 353 | ifr = ifc.ifc_req; | ||
| 354 | lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len]; | ||
| 355 | |||
| 356 | while (ifr < lifr) { | ||
| 357 | struct sockaddr *sa; | ||
| 358 | |||
| 359 | ift->ifa_name = names; | ||
| 360 | strlcpy(names, ifr->ifr_name, sizeof(ifr->ifr_name)); | ||
| 361 | while (*names++) | ||
| 362 | ; | ||
| 363 | |||
| 364 | ift->ifa_addr = (struct sockaddr *)data; | ||
| 365 | sa = &ifr->ifr_addr; | ||
| 366 | memcpy(data, sa, SA_LEN(sa)); | ||
| 367 | data += SA_RLEN(sa); | ||
| 368 | |||
| 369 | ifr = (struct ifreq *)(((char *)sa) + SA_LEN(sa)); | ||
| 370 | ift = (ift->ifa_next = ift + 1); | ||
| 371 | } | ||
| 372 | #endif /* NET_RT_IFLIST */ | ||
| 373 | if (--ift >= ifa) { | 266 | if (--ift >= ifa) { |
| 374 | ift->ifa_next = NULL; | 267 | ift->ifa_next = NULL; |
| 375 | *pif = ifa; | 268 | *pif = ifa; |
