static Boolean getInterfaceInfo(char* ifaceName, InterfaceInfo* ifaceInfo) { int res; res = interfaceExists(ifaceName); if (res == -1) { return FALSE; } else if (res == 0) { ERROR("Interface %s does not exist.\n", ifaceName); return FALSE; } res = getInterfaceAddress(ifaceName, ifaceInfo->addressFamily, &ifaceInfo->afAddress); if (res == -1) { return FALSE; } ifaceInfo->hasAfAddress = res; res = getHwAddress(ifaceName, (unsigned char*)ifaceInfo->hwAddress, 6); if (res == -1) { return FALSE; } ifaceInfo->hasHwAddress = res; res = getInterfaceFlags(ifaceName, &ifaceInfo->flags); if (res == -1) { return FALSE; } return TRUE; }
os_result os_sockQueryIPv6Interfaces ( os_ifAttributes *ifList, unsigned int listSize, unsigned int *validElements) { os_result result = os_resultSuccess; ULONG filter; PIP_ADAPTER_ADDRESSES pAddresses = NULL; PIP_ADAPTER_ADDRESSES pCurrAddress = NULL; PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL; ULONG outBufLen = WORKING_BUFFER_SIZE; ULONG retVal; int iterations = 0; int listIndex = 0; filter = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER; do { pAddresses = (IP_ADAPTER_ADDRESSES *) os_malloc(outBufLen); if (!pAddresses) { os_report(OS_ERROR, "os_sockQueryIPv6Interfaces", __FILE__, __LINE__, 0, "Failed to allocate %d bytes for Adapter addresses", outBufLen); return os_resultFail; } retVal = GetAdaptersAddresses(AF_INET6, filter, NULL, pAddresses, &outBufLen); if (retVal == ERROR_BUFFER_OVERFLOW) { os_free(pAddresses); pAddresses = NULL; outBufLen <<= 1; /* double the buffer just to be save.*/ } else { break; } iterations++; } while ((retVal == ERROR_BUFFER_OVERFLOW) && (iterations < MAX_TRIES)); if (retVal != ERROR_SUCCESS) { if (pAddresses) { os_free(pAddresses); pAddresses = NULL; } os_report(OS_ERROR, "os_sockQueryIPv6Interfaces", __FILE__, __LINE__, 0, "Failed to GetAdaptersAddresses"); return os_resultFail; } for (pCurrAddress = pAddresses; pCurrAddress; pCurrAddress = pCurrAddress->Next) { DWORD ipv6IfIndex = 0; IP_ADAPTER_PREFIX *firstPrefix = NULL; if (pCurrAddress->Length >= sizeof(IP_ADAPTER_ADDRESSES)) { ipv6IfIndex = pCurrAddress->Ipv6IfIndex; firstPrefix = pCurrAddress->FirstPrefix; } if (((ipv6IfIndex == 1) && (pCurrAddress->IfType != IF_TYPE_SOFTWARE_LOOPBACK)) || (pCurrAddress->IfType == IF_TYPE_TUNNEL)) { continue; } if (pCurrAddress->OperStatus != IfOperStatusUp) { continue; } for (pUnicast = pCurrAddress->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) { IP_ADAPTER_PREFIX *prefix; IN6_ADDR mask; struct sockaddr_in6 *sa6; struct sockaddr_in6 ipv6Netmask; if (pUnicast->Address.lpSockaddr->sa_family != AF_INET6) { continue; } snprintf(ifList[listIndex].name, OS_IFNAMESIZE, "%wS", pCurrAddress->FriendlyName); // Get interface flags. ifList[listIndex].flags = getInterfaceFlags(pCurrAddress); ifList[listIndex].interfaceIndexNo = (os_uint) pCurrAddress->Ipv6IfIndex; memcpy(&ifList[listIndex].address, pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength); memcpy(&ifList[listIndex].broadcast_address, pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength); memcpy(&ifList[listIndex].network_mask, pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength); sa6 = (struct sockaddr_in6 *)&ifList[listIndex].network_mask; memset(&sa6->sin6_addr.s6_addr, 0xFF, sizeof(sa6->sin6_addr.s6_addr)); for (prefix = firstPrefix; prefix; prefix = prefix->Next) { unsigned int l, i; if ((prefix->PrefixLength == 0) || (prefix->PrefixLength > 128) || (pUnicast->Address.iSockaddrLength != prefix->Address.iSockaddrLength) || (memcmp(pUnicast->Address.lpSockaddr, prefix->Address.lpSockaddr, pUnicast->Address.iSockaddrLength) == 0)){ continue; } memset(&ipv6Netmask, 0, sizeof(ipv6Netmask)); ipv6Netmask.sin6_family = AF_INET6; l = prefix->PrefixLength; for (i = 0; l > 0; l -= 8, i++) { ipv6Netmask.sin6_addr.s6_addr[i] = (l >= 8) ? 0xFF : ((0xFF << (8-l)) & 0xFF); } for (i = 0; i < 16; i++) { mask.s6_addr[i] = ((struct sockaddr_in6 *)pUnicast->Address.lpSockaddr)->sin6_addr.s6_addr[i] & ipv6Netmask.sin6_addr.s6_addr[i]; } if (memcmp(((struct sockaddr_in6 *)prefix->Address.lpSockaddr)->sin6_addr.s6_addr, mask.s6_addr, sizeof(ipv6Netmask.sin6_addr)) == 0) { memcpy(&sa6->sin6_addr.s6_addr, &ipv6Netmask.sin6_addr.s6_addr, sizeof(sa6->sin6_addr.s6_addr)); } } listIndex++; } } for (pCurrAddress = pAddresses; pCurrAddress; pCurrAddress = pCurrAddress->Next) { if (pCurrAddress->OperStatus != IfOperStatusUp) { snprintf(ifList[listIndex].name, OS_IFNAMESIZE, "%wS", pCurrAddress->FriendlyName); // Get interface flags. ifList[listIndex].flags = getInterfaceFlags(pCurrAddress); ifList[listIndex].interfaceIndexNo = 0; memset (&ifList[listIndex].address, 0, sizeof(ifList[listIndex].address)); memset (&ifList[listIndex].broadcast_address, 0, sizeof (ifList[listIndex].broadcast_address)); memset (&ifList[listIndex].network_mask, 0, sizeof (ifList[listIndex].network_mask)); listIndex++; } } if (pAddresses) { os_free(pAddresses); } *validElements = listIndex; return result; }
os_result os_sockQueryInterfaces( os_ifAttributes *ifList, unsigned int listSize, unsigned int *validElements) { os_result result = os_resultSuccess; DWORD filter; PIP_ADAPTER_ADDRESSES pAddresses = NULL; PIP_ADAPTER_ADDRESSES pCurrAddress = NULL; PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL; unsigned long outBufLen = WORKING_BUFFER_SIZE; int retVal; int iterations = 0; int listIndex = 0; filter = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER; do { pAddresses = (IP_ADAPTER_ADDRESSES *) os_malloc(outBufLen); if (!pAddresses) { os_report(OS_ERROR, "os_sockQueryInterfaces", __FILE__, __LINE__, 0, "Failed to allocate %d bytes for Adapter addresses", outBufLen); return os_resultFail; } retVal = GetAdaptersAddresses(AF_INET, filter, NULL, pAddresses, &outBufLen); if (retVal == ERROR_BUFFER_OVERFLOW) { os_free(pAddresses); pAddresses = NULL; outBufLen <<= 1; /* double the buffer just to be save.*/ } else { break; } iterations++; } while ((retVal == ERROR_BUFFER_OVERFLOW) && (iterations < MAX_TRIES)); if (retVal != ERROR_SUCCESS) { if (pAddresses) { os_free(pAddresses); pAddresses = NULL; } os_report(OS_ERROR, "os_sockQueryInterfaces", __FILE__, __LINE__, 0, "Failed to GetAdaptersAddresses"); return os_resultFail; } for (pCurrAddress = pAddresses; pCurrAddress; pCurrAddress = pCurrAddress->Next) { IP_ADAPTER_PREFIX *firstPrefix = NULL; if (pCurrAddress->Length >= sizeof(IP_ADAPTER_ADDRESSES)) { firstPrefix = pCurrAddress->FirstPrefix; } if (pCurrAddress->OperStatus != IfOperStatusUp) { continue; } for (pUnicast = pCurrAddress->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) { unsigned int ipv4Index; struct sockaddr_in ipv4Netmask; if (pUnicast->Address.lpSockaddr->sa_family != AF_INET) { continue; } ipv4Index = 0; memset(&ipv4Netmask, 0, sizeof(ipv4Netmask)); if (addressToIndexAndMask((struct sockaddr *) pUnicast->Address.lpSockaddr, &ipv4Index, (struct sockaddr *) &ipv4Netmask) != os_resultSuccess) { continue; } snprintf(ifList[listIndex].name, OS_IFNAMESIZE, "%wS", pCurrAddress->FriendlyName); // Get interface flags. ifList[listIndex].flags = getInterfaceFlags(pCurrAddress); ifList[listIndex].interfaceIndexNo = ipv4Index; memcpy(&ifList[listIndex].address, pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength); memcpy(&ifList[listIndex].broadcast_address, pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength); memcpy(&ifList[listIndex].network_mask, pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength); ((struct sockaddr_in *)(&(ifList[listIndex].broadcast_address)))->sin_addr.s_addr = ((struct sockaddr_in *)(&(ifList[listIndex].address)))->sin_addr.s_addr | ~(ipv4Netmask.sin_addr.s_addr); ((struct sockaddr_in *)&(ifList[listIndex].network_mask))->sin_addr.s_addr = ipv4Netmask.sin_addr.s_addr; listIndex++; } } for (pCurrAddress = pAddresses; pCurrAddress; pCurrAddress = pCurrAddress->Next) { if (pCurrAddress->OperStatus != IfOperStatusUp) { snprintf(ifList[listIndex].name, OS_IFNAMESIZE, "%wS", pCurrAddress->FriendlyName); // Get interface flags. ifList[listIndex].flags = getInterfaceFlags(pCurrAddress); ifList[listIndex].interfaceIndexNo = 0; memset (&ifList[listIndex].address, 0, sizeof(ifList[listIndex].address)); memset (&ifList[listIndex].broadcast_address, 0, sizeof (ifList[listIndex].broadcast_address)); memset (&ifList[listIndex].network_mask, 0, sizeof (ifList[listIndex].network_mask)); listIndex++; } } if (pAddresses) { os_free(pAddresses); } *validElements = listIndex; return result; }