int system_getdns(const char* name, char primary[40], char secondary[40]) { ULONG idx = 0; DWORD dwRetVal = 0; ULONG outBufLen = 0; WCHAR wAdapterName[256] = {0}; PIP_PER_ADAPTER_INFO pPerAdapterInfo; MultiByteToWideChar(CP_ACP, 0, name, -1, wAdapterName, 256); if(NO_ERROR!=GetAdapterIndex(wAdapterName, &idx)) return -1; outBufLen = sizeof(IP_PER_ADAPTER_INFO); pPerAdapterInfo = (PIP_PER_ADAPTER_INFO)malloc(outBufLen); if(ERROR_BUFFER_OVERFLOW==GetPerAdapterInfo(idx, pPerAdapterInfo, &outBufLen)) { free(pPerAdapterInfo); pPerAdapterInfo = (PIP_PER_ADAPTER_INFO)malloc(outBufLen); } if ((dwRetVal = GetPerAdapterInfo(idx, pPerAdapterInfo, &outBufLen)) == ERROR_SUCCESS) { secondary[0] = '\0'; strncpy(primary, pPerAdapterInfo->DnsServerList.IpAddress.String, 39); if(pPerAdapterInfo->DnsServerList.Next) strncpy(secondary, pPerAdapterInfo->DnsServerList.Next->IpAddress.String, 39); } free(pPerAdapterInfo); return dwRetVal==ERROR_SUCCESS?0:-(int)dwRetVal; }
void NetPlatform_addAddress(const char* interfaceName, char* addrBytes, int prefixLen, int addrFam, struct Log* logger, struct Except* eh) { unsigned long ifIndex; WinFail_check(eh, GetAdapterIndex(interfaceName, &ifIndex)); MIB_UNICASTIPADDRESS_ROW ipRow; InitializeUnicastIpAddressEntry(&ipRow); ipRow.InterfaceIndex = ifIndex; ipRow.Address.si_family = addrFamily; if (addrFam == Socket_AF_INET6) { Bits_memcpy(&ipRow.Address.Ipv6.sin6_addr, addr, 16); } else if (addrFam == Socket_AF_INET) { Bits_memcpy(&ipRow.Address.Ipv4.sin_addr, addr, 4); } else { Assert_always(0); } ipRow.OnLinkPrefixLength = prefixLen; WinFail_check(eh, CreateUnicastIpAddressEntry(&ipRow)); }
static unsigned /* type matching if_nametoindex() */ _pgm_getadaptersaddresses_nametoindex ( const sa_family_t iffamily, const char* ifname ) { pgm_return_val_if_fail (NULL != ifname, 0); ULONG ifIndex; DWORD dwSize = DEFAULT_BUFFER_SIZE, dwRet; IP_ADAPTER_ADDRESSES *pAdapterAddresses = NULL, *adapter; char szAdapterName[IF_NAMESIZE]; /* first see if GetAdapterIndex is working, */ pgm_strncpy_s (szAdapterName, sizeof (szAdapterName), ifname, _TRUNCATE); dwRet = GetAdapterIndex ((LPWSTR)szAdapterName, &ifIndex); if (NO_ERROR == dwRet) return ifIndex; /* fallback to finding index via iterating adapter list */ /* loop to handle interfaces coming online causing a buffer overflow * between first call to list buffer length and second call to enumerate. */ for (unsigned i = MAX_TRIES; i; i--) { pAdapterAddresses = (IP_ADAPTER_ADDRESSES*)_pgm_heap_alloc (dwSize); dwRet = GetAdaptersAddresses (AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME | GAA_FLAG_SKIP_MULTICAST, NULL, pAdapterAddresses, &dwSize); if (ERROR_BUFFER_OVERFLOW == dwRet) { _pgm_heap_free (pAdapterAddresses); pAdapterAddresses = NULL; } else { break; } } switch (dwRet) { case ERROR_SUCCESS: break; case ERROR_BUFFER_OVERFLOW: pgm_warn (_("GetAdaptersAddresses repeatedly failed with ERROR_BUFFER_OVERFLOW")); if (pAdapterAddresses) _pgm_heap_free (pAdapterAddresses); return 0; default: pgm_warn (_("GetAdaptersAddresses failed")); if (pAdapterAddresses) _pgm_heap_free (pAdapterAddresses); return 0; } for (adapter = pAdapterAddresses; adapter; adapter = adapter->Next) { if (0 == strcmp (szAdapterName, adapter->AdapterName)) { ifIndex = AF_INET6 == iffamily ? adapter->Ipv6IfIndex : adapter->IfIndex; _pgm_heap_free (pAdapterAddresses); return ifIndex; } } if (pAdapterAddresses) _pgm_heap_free (pAdapterAddresses); return 0; }
IPSTATE GetIPState(LPCTSTR pszAdapter, LPTSTR pszAddress, UINT cchAddress) { HRESULT hr = S_OK; IPSTATE state = IPSTATE_DHCP; ULONG ulAdapterIndex; PIP_ADAPTER_INFO paiBuffer = NULL; ULONG cbBuffer = 0; DWORD dwError; PIP_ADAPTER_INFO paiCurrent; PIP_PER_ADAPTER_INFO pper = NULL; // Check inputs CBRAEx(NULL != pszAdapter, E_INVALIDARG); // Get the adapter index CBR(NO_ERROR == GetAdapterIndex(const_cast<LPWSTR>(pszAdapter), &ulAdapterIndex)); // Get the status of all connected adapters cbBuffer = sizeof(IP_ADAPTER_INFO); paiBuffer = (PIP_ADAPTER_INFO)LocalAlloc(LMEM_FIXED, cbBuffer); CPR(paiBuffer); while (ERROR_BUFFER_OVERFLOW == (dwError = GetAdaptersInfo(paiBuffer, &cbBuffer))) { PIP_ADAPTER_INFO paiTemp = (PIP_ADAPTER_INFO)LocalReAlloc(paiBuffer, cbBuffer, LMEM_MOVEABLE); CPR(paiTemp); paiBuffer = paiTemp; } CBR(NO_ERROR == dwError); // Find our adapter index for (paiCurrent = paiBuffer; paiCurrent; paiCurrent = paiCurrent->Next) { if (paiCurrent->Index == ulAdapterIndex) { break; } } CBR(NULL != paiCurrent); // did we find it? CBR(NULL != paiCurrent->CurrentIpAddress); // Is this adapter using DHCP? if (!paiCurrent->DhcpEnabled) { state = IPSTATE_CONNECTED; } else { // Get the per-adapter info cbBuffer = sizeof(IP_PER_ADAPTER_INFO); pper = (PIP_PER_ADAPTER_INFO)LocalAlloc(LMEM_FIXED, cbBuffer); CPR(pper); while (ERROR_BUFFER_OVERFLOW == (dwError = GetPerAdapterInfo(ulAdapterIndex, pper, &cbBuffer))) { PIP_PER_ADAPTER_INFO pperTemp = (PIP_PER_ADAPTER_INFO)LocalReAlloc(pper, cbBuffer, LMEM_MOVEABLE); CPR(pperTemp); pper = pperTemp; } CBR(NO_ERROR == dwError); // Are we using an automatic IP? if (pper->AutoconfigActive || IsAutoIPAddr(paiCurrent->CurrentIpAddress->IpAddress.String)) { state = IPSTATE_AUTOIP; } } // Optionally copy the IP address string to the output if (NULL != pszAddress && 0 != cchAddress) { UINT cchInput = strlen(paiCurrent->CurrentIpAddress->IpAddress.String); if (cchInput >= cchAddress) { cchInput = cchAddress - 1; } MultiByteToWideChar(CP_ACP, 0, paiCurrent->CurrentIpAddress->IpAddress.String, cchInput, pszAddress, cchAddress); pszAddress[cchAddress-1] = TEXT('\0'); } Error: LocalFree(pper); LocalFree(paiBuffer); return (SUCCEEDED(hr) ? state : IPSTATE_DISCONNECTED); }