81 switch (sa->sa_family) {
84 struct sockaddr_in *sin = (
struct sockaddr_in *)(
void *) sa;
85 uint32_t addr = ntohl(sin->sin_addr.s_addr);
93 struct sockaddr_in6 *sin = (
struct sockaddr_in6 *)(
void *) sa;
94 if (IN6_IS_ADDR_V4MAPPED(&sin->sin6_addr)) {
95 uint32_t v4_addr = ntohl(*((uint32_t*)(
void *)(sin->sin6_addr.s6_addr + 12)));
101 return IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr);
110 switch (sa->sa_family) {
115 struct sockaddr_in *sin = (
struct sockaddr_in *)(
void *) sa;
116 uint32_t addr = ntohl(sin->sin_addr.s_addr);
124 struct sockaddr_in6 *sin = (
struct sockaddr_in6 *)(
void *) sa;
125 if (IN6_IS_ADDR_V4MAPPED(&sin->sin6_addr)) {
126 uint32_t v4_addr = ntohl(*((uint32_t*)(
void *)(sin->sin6_addr.s6_addr + 12)));
132 return IN6_IS_ADDR_LOOPBACK(&sin->sin6_addr);
231 assert(ip_version == 0 || ip_version == 4 || ip_version == 6);
233#define WORKING_BUFFER_SIZE 15000
237 size_t len_remaining = *
len;
240 PIP_ADAPTER_ADDRESSES pAddresses = NULL;
242 ULONG Iterations = 0;
244 PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
245 PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
248 outBufLen = WORKING_BUFFER_SIZE;
251 pAddresses = (IP_ADAPTER_ADDRESSES *) malloc(outBufLen);
252 if (pAddresses == NULL) {
254 (
"Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n");
258 ULONG family = ip_version == 4 ? AF_INET
259 : ip_version == 6 ? AF_INET6
262 GetAdaptersAddresses(family, 0, NULL, pAddresses, &outBufLen);
264 if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
271 }
while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES));
273 if (dwRetVal == NO_ERROR) {
275 pCurrAddresses = pAddresses;
276 while (pCurrAddresses) {
278 pUnicast = pCurrAddresses->FirstUnicastAddress;
279 while (pUnicast != NULL) {
280 if (len_remaining <
sizeof(addrs[0])) {
281 printf(
"Warning: insufficient space for all addresses.\n");
284 size_t sa_len = pUnicast->Address.lpSockaddr->sa_family == AF_INET ?
sizeof(
struct sockaddr_in) : sizeof(struct sockaddr_in6);
285 memcpy(addrs, pUnicast->Address.lpSockaddr, sa_len);
287 *
len += sizeof(addrs[0]);
288 len_remaining -= sizeof(addrs[0]);
289 pUnicast = pUnicast->Next;
292 pCurrAddresses = pCurrAddresses->Next;
295 printf(
"Call to GetAdaptersAddresses failed with error: %ld\n",
297 if (dwRetVal == ERROR_NO_DATA)
298 printf(
"\tNo addresses were found for the requested parameters\n");
301 get_win32_error(dwRetVal));
314 size_t available_len = *
len;
316 struct ifaddrs* a = NULL;
318 struct ifaddrs* p = a;
320 if (p->ifa_addr == NULL ||
321 (ip_version == 0 && (p->ifa_addr->sa_family != AF_INET &&
322 p->ifa_addr->sa_family != AF_INET6)) ||
323 (ip_version == 4 && p->ifa_addr->sa_family != AF_INET) ||
324 (ip_version == 6 && p->ifa_addr->sa_family != AF_INET6)) {
328 if (available_len <
sizeof addrs[0]) {
330 "Warning: insufficient space for all addresses.\n");
333 size_t sa_len = p->ifa_addr->sa_family == AF_INET
334 ?
sizeof(
struct sockaddr_in)
335 : sizeof(struct sockaddr_in6);
336 memcpy(addrs, p->ifa_addr, sa_len);
338 *
len += sizeof(addrs[0]);
339 available_len -= sizeof(addrs[0]);
429 const void *src = NULL;
430 if (sa->sa_family == AF_INET6) {
431 snprintf(buf, n,
"[");
432 src = &((
struct sockaddr_in6 *)(
void *) sa)->sin6_addr;
433 }
else if (sa->sa_family == AF_INET) {
434 src = &((
struct sockaddr_in *)(
void *) sa)->sin_addr;
436 snprintf(buf, n,
"(unknown)");
439 if (inet_ntop(sa->sa_family, src, buf + strlen(buf), n - strlen(buf)) == NULL) {
440 perror(
"get_sockaddr_str");
441 snprintf(buf, n,
"(error)");
445 if (sa->sa_family == AF_INET6) {
446 snprintf(buf + strlen(buf), n - strlen(buf),
"]");