/* * Note: This function reads the string without updating the index */ static DWORD DNSUnmarshallDomainNameAtOffset( HANDLE hRecvBuffer, WORD wOffset, PDNS_DOMAIN_LABEL * ppDomainLabel ) { DWORD dwError = 0; PDNS_DOMAIN_LABEL pLabel = NULL; BYTE uLen = 0; DWORD dwCurrent = 0; PDNS_RECEIVEBUFFER_CONTEXT pRecvContext = NULL; CHAR szLabel[65]; pRecvContext = (PDNS_RECEIVEBUFFER_CONTEXT)hRecvBuffer; dwCurrent = wOffset; memcpy(&uLen, pRecvContext->pRecvBuffer+dwCurrent, sizeof(char)); switch (uLen & 0xC0) { case 0x00: dwCurrent++; memset(szLabel, 0, sizeof(szLabel)); memcpy(szLabel, pRecvContext->pRecvBuffer+dwCurrent, uLen); dwCurrent += uLen; dwError = DNSAllocateMemory( sizeof(DNS_DOMAIN_LABEL), (PVOID *)&pLabel); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSAllocateString(szLabel, &pLabel->pszLabel); BAIL_ON_LWDNS_ERROR(dwError); break; default: dwError = LWDNS_ERROR_BAD_RESPONSE; BAIL_ON_LWDNS_ERROR(dwError); break; } *ppDomainLabel = pLabel; cleanup: return dwError; error: *ppDomainLabel = NULL; if (pLabel) { DNSFreeLabel(pLabel); } goto cleanup; }
static DWORD DNSGetInfoUsingGetIfAddrs( PLW_DLINKED_LIST* ppInterfaceList ) { DWORD dwError = 0; PLW_DLINKED_LIST pInterfaceList = NULL; struct ifaddrs* pInterfaces = NULL; struct ifaddrs* pIter = NULL; PLW_INTERFACE_INFO pInterfaceInfo = NULL; if (getifaddrs(&pInterfaces) < 0) { dwError = errno; BAIL_ON_LWDNS_ERROR(dwError); } for (pIter = pInterfaces; pIter; pIter = pIter->ifa_next) { if (IsNullOrEmptyString(pIter->ifa_name)) { LWDNS_LOG_VERBOSE("Skipping network interface with no name"); continue; } LWDNS_LOG_VERBOSE("Considering network interface [%s]", pIter->ifa_name); if (pIter->ifa_addr->sa_family != AF_INET) { if (pIter->ifa_addr->sa_family != AF_INET6) { LWDNS_LOG_VERBOSE("Skipping network interface [%s] because it is not AF_INET/AF_INET6 family", pIter->ifa_name); continue; } } if (!(pIter->ifa_flags & IFF_UP)) { LWDNS_LOG_VERBOSE("Skipping in-active network interface [%s]", pIter->ifa_name); continue; } if (pIter->ifa_flags & IFF_LOOPBACK) { LWDNS_LOG_VERBOSE("Skipping loopback network interface [%s]", pIter->ifa_name); continue; } #ifdef LW_SKIP_ALIASED_INTERFACES if (DNSInterfaceIsInList(pIter->ifa_name, pInterfaceList)) { LWDNS_LOG_VERBOSE("Skipping aliased network interface [%s]", pIter->ifa_name); continue; } #endif dwError = DNSAllocateMemory( sizeof(LW_INTERFACE_INFO), (PVOID*)&pInterfaceInfo); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSAllocateString( pIter->ifa_name, &pInterfaceInfo->pszName); BAIL_ON_LWDNS_ERROR(dwError); if (pIter->ifa_addr) { if (pIter->ifa_addr->sa_family == AF_INET) { memcpy(&pInterfaceInfo->ipAddr, pIter->ifa_addr, sizeof(*pIter->ifa_addr)); } #ifndef HAVE_HPUX_OS else if (pIter->ifa_addr->sa_family == AF_INET6) { pInterfaceInfo->bIPV6Enabled = TRUE; memcpy(&pInterfaceInfo->ipv6Addr, pIter->ifa_addr, sizeof(struct sockaddr_in6)); } #endif } pInterfaceInfo->dwFlags = pIter->ifa_flags; dwError = LwDLinkedListAppend( &pInterfaceList, pInterfaceInfo); BAIL_ON_LWDNS_ERROR(dwError); LWDNS_LOG_VERBOSE("Added network interface [Name:%s] to list", pInterfaceInfo->pszName); pInterfaceInfo = NULL; } *ppInterfaceList = pInterfaceList; cleanup: if (pInterfaces) { freeifaddrs(pInterfaces); } return dwError; error: if (pInterfaceList) { DNSFreeInterfaceLinkedList(pInterfaceList); } if (pInterfaceInfo) { DNSFreeNetworkInterface(pInterfaceInfo); } *ppInterfaceList = NULL; goto cleanup; }
DWORD DNSUnmarshallDomainName( HANDLE hRecvBuffer, PDNS_DOMAIN_NAME * ppDomainName ) { DWORD dwError = 0; PDNS_DOMAIN_LABEL pLabel = NULL; PDNS_DOMAIN_NAME pDomainName = NULL; BYTE uLen = 0; DWORD dwRead = 0; BYTE uLen1, uLen2 = 0; WORD wOffset = 0; BOOLEAN bDone = FALSE; dwError = DNSAllocateMemory( sizeof(DNS_DOMAIN_NAME), (PVOID *)&pDomainName); BAIL_ON_LWDNS_ERROR(dwError); do { dwError = DNSUnmarshallBuffer( hRecvBuffer, &uLen1, sizeof(char), &dwRead); BAIL_ON_LWDNS_ERROR(dwError); switch (uLen1 & 0xC0) { case 0xC0: /* pointer to string */ dwError = DNSUnmarshallBuffer( hRecvBuffer, &uLen2, sizeof(char), &dwRead); BAIL_ON_LWDNS_ERROR(dwError); wOffset = ntohs((((WORD)(uLen1) << 8)|uLen2) & 0x3FFF); dwError = DNSUnmarshallDomainNameAtOffset( hRecvBuffer, wOffset, &pLabel); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSAppendLabel( pDomainName->pLabelList, pLabel, &pDomainName->pLabelList); BAIL_ON_LWDNS_ERROR(dwError); pLabel = NULL; break; case 0x00: /* string component */ { CHAR szLabel[65]; dwError = DNSReceiveBufferMoveBackIndex(hRecvBuffer, 1); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSUnmarshallBuffer( hRecvBuffer, &uLen, sizeof(char), &dwRead); BAIL_ON_LWDNS_ERROR(dwError); if (uLen == 0) { bDone = TRUE; break; } memset(szLabel, 0, sizeof(szLabel)); dwError = DNSUnmarshallBuffer( hRecvBuffer, (PBYTE)szLabel, uLen, &dwRead); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSAllocateMemory( sizeof(DNS_DOMAIN_LABEL), (PVOID *)&pLabel); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSAllocateString(szLabel, &pLabel->pszLabel); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSAppendLabel( pDomainName->pLabelList, pLabel, &pDomainName->pLabelList); BAIL_ON_LWDNS_ERROR(dwError); pLabel = NULL; } break; default: /* unexpected */ dwError = LWDNS_ERROR_BAD_RESPONSE; BAIL_ON_LWDNS_ERROR(dwError); break; } } while (!bDone); *ppDomainName = pDomainName; cleanup: return(dwError); error: if (pDomainName) { DNSFreeDomainName(pDomainName); } if (pLabel) { DNSFreeLabel(pLabel); } *ppDomainName = NULL; goto cleanup; }