DWORD DNSUpdateCreateUpdateRequest( PDNS_UPDATE_REQUEST * ppDNSRequest ) { DWORD dwError = 0; PDNS_UPDATE_REQUEST pDNSRequest = NULL; dwError = DNSAllocateMemory( sizeof(DNS_UPDATE_REQUEST), (PVOID *)&pDNSRequest); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSGenerateIdentifier(&pDNSRequest->wIdentification); BAIL_ON_LWDNS_ERROR(dwError); pDNSRequest->wParameter = 0x2800; *ppDNSRequest = pDNSRequest; cleanup: return dwError; error: if (pDNSRequest){ DNSUpdateFreeRequest(pDNSRequest); } *ppDNSRequest = NULL; goto cleanup; }
DWORD DNSDLinkedListPrepend( PDNSDLINKEDLIST* ppList, PVOID pItem ) { DWORD dwError = 0; PDNSDLINKEDLIST pList = NULL; dwError = DNSAllocateMemory(sizeof(DNSDLINKEDLIST), (PVOID*)&pList); BAIL_ON_LWDNS_ERROR(dwError); pList->pItem = pItem; if (*ppList) { (*ppList)->pPrev = pList; pList->pNext = *ppList; *ppList = pList; } else { *ppList = pList; } cleanup: return dwError; error: if (pList) { DNSFreeMemory(pList); } goto cleanup; }
static DWORD DNSStdAllocateResponse( PDNS_RESPONSE * ppDNSResponse ) { DWORD dwError = 0; PDNS_RESPONSE pDNSResponse = NULL; dwError = DNSAllocateMemory( sizeof(DNS_RESPONSE), (PVOID *)&pDNSResponse); BAIL_ON_LWDNS_ERROR(dwError); *ppDNSResponse = pDNSResponse; cleanup: return dwError; error: *ppDNSResponse = NULL; if (pDNSResponse) { DNSStdFreeResponse(pDNSResponse); } goto cleanup; }
DWORD DNSUDPOpen( PCSTR pszNameServer, PHANDLE phDNSServer ) { DWORD dwError = 0; unsigned long ulAddress; struct hostent *pHost = NULL; PDNS_CONNECTION_CONTEXT pDNSContext = NULL; dwError = DNSAllocateMemory( sizeof(DNS_CONNECTION_CONTEXT), (PVOID *)&pDNSContext); BAIL_ON_LWDNS_ERROR(dwError); pDNSContext->hType = DNS_UDP; ulAddress = inet_addr (pszNameServer); if (INADDR_NONE == ulAddress) { pHost = gethostbyname (pszNameServer); if (NULL == pHost) { dwError = h_errno; BAIL_ON_HERRNO_ERROR(dwError); } memcpy((char*)&ulAddress, pHost->h_addr, pHost->h_length); } // Create a socket for sending data pDNSContext->s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //------------------------------------------- // Set up the RecvAddr structure with the IP address of // the receiver (in this example case "123.456.789.1") // and the specified port number. // pDNSContext->RecvAddr.sin_family = AF_INET; pDNSContext->RecvAddr.sin_port = htons(DNS_UDP_PORT); pDNSContext->RecvAddr.sin_addr.s_addr = ulAddress; *phDNSServer = (HANDLE)pDNSContext; cleanup: return dwError; error: *phDNSServer = (HANDLE)NULL; if (pDNSContext) { DNSClose((HANDLE)pDNSContext); } goto cleanup; }
static DWORD DNSUpdateAllocateResponse( PDNS_UPDATE_RESPONSE * ppDNSResponse ) { DWORD dwError = 0; PDNS_UPDATE_RESPONSE pDNSResponse = NULL; dwError = DNSAllocateMemory( sizeof(DNS_UPDATE_RESPONSE), (PVOID *)&pDNSResponse); BAIL_ON_LWDNS_ERROR(dwError); *ppDNSResponse = pDNSResponse; cleanup: return(dwError); error: *ppDNSResponse = NULL; goto cleanup; }
DWORD DNSCreateSendBuffer( HANDLE * phDNSSendBuffer ) { DWORD dwError = 0; PDNS_SENDBUFFER_CONTEXT pDNSContext = NULL; dwError = DNSAllocateMemory( sizeof(DNS_SENDBUFFER_CONTEXT), (PVOID *)&pDNSContext); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSAllocateMemory( SENDBUFFER_SIZE, (PVOID *)&pDNSContext->pSendBuffer); BAIL_ON_LWDNS_ERROR(dwError); pDNSContext->dwBufferSize = SENDBUFFER_SIZE; // // We will offset into the buffer by 2 bytes // If we are doing a TCP write; we will fill in these // two bytes and send + 2 bytes // If we are doing a UDP write; we will start our send // +2 bytes and only send dwWritten; // pDNSContext->dwBufferOffset += 2; *phDNSSendBuffer = (HANDLE)pDNSContext; cleanup: return dwError; error: if (pDNSContext) { DNSFreeSendBuffer((HANDLE)pDNSContext); } *phDNSSendBuffer = (HANDLE)NULL; goto cleanup; }
DWORD DNSCreateReceiveBuffer( HANDLE * phDNSRecvBuffer ) { DWORD dwError = 0; PDNS_RECEIVEBUFFER_CONTEXT pDNSContext = NULL; dwError = DNSAllocateMemory( sizeof(DNS_RECEIVEBUFFER_CONTEXT), (PVOID *)&pDNSContext); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSAllocateMemory( RECVBUFFER_SIZE, (PVOID *)&pDNSContext->pRecvBuffer); BAIL_ON_LWDNS_ERROR(dwError); pDNSContext->dwBufferSize = RECVBUFFER_SIZE; *phDNSRecvBuffer = (HANDLE)pDNSContext; cleanup: return dwError; error: if (pDNSContext) { DNSFreeReceiveBufferContext((HANDLE)pDNSContext); } *phDNSRecvBuffer = (HANDLE)NULL; goto cleanup; }
DWORD DNSUnmarshallRData( HANDLE hRecvBuffer, DWORD dwSize, PBYTE* ppRData, PDWORD pdwRead ) { DWORD dwError = 0; PBYTE pMemory = NULL; dwError = DNSAllocateMemory( dwSize, (PVOID *)&pMemory); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSUnmarshallBuffer( hRecvBuffer, (PBYTE)pMemory, dwSize, pdwRead); BAIL_ON_LWDNS_ERROR(dwError); *ppRData = pMemory; cleanup: return(dwError); error: if (pMemory) { DNSFreeMemory(pMemory); } *ppRData = NULL; goto cleanup; }
static DWORD DNSGetInfoUsingIoctl( PLW_DLINKED_LIST* ppInterfaceList ) { DWORD dwError = 0; SOCKET fd = -1; DWORD dwBufLen = 0; DWORD dwLastBufLen = 0; PBYTE pBuffer = NULL; PBYTE pIter = NULL; struct ifconf ifc = {0}; PLW_DLINKED_LIST pInterfaceList = NULL; PLW_INTERFACE_INFO pInterfaceInfo = NULL; fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) { dwError = errno; BAIL_ON_LWDNS_ERROR(dwError); } dwBufLen = 64 * sizeof(struct ifreq); dwError = DNSAllocateMemory( dwBufLen, (PVOID*)&pBuffer); BAIL_ON_LWDNS_ERROR(dwError); do { DWORD dwNewSize = 0; ifc.ifc_len = dwBufLen; ifc.ifc_buf = (caddr_t)pBuffer; // On some systems, the ioctl returns success // even if the buffer is insufficient. So, we // retry until the buffer length consolidates if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) { if ((errno != EINVAL) || (dwLastBufLen)) { dwError = errno; BAIL_ON_LWDNS_ERROR(dwError); } } else { if (dwLastBufLen == ifc.ifc_len) { break; } dwLastBufLen = ifc.ifc_len; } dwNewSize = dwLastBufLen + 32 * sizeof(struct ifreq); dwError = DNSReallocMemory( pBuffer, (PVOID*)&pBuffer, dwNewSize); BAIL_ON_LWDNS_ERROR(dwError); dwBufLen = dwNewSize; } while (TRUE); for (pIter = pBuffer; pIter < pBuffer + dwBufLen;) { CHAR szItfName[IFNAMSIZ+1]; PSTR pszIpAddress = NULL; DWORD dwFlags = 0; struct ifreq* pInterfaceRecord = NULL; struct ifreq interfaceRecordCopy; struct sockaddr * pSA = NULL; DWORD dwLen = 0; #ifdef LW_SKIP_ALIASED_INTERFACES PSTR pszIndex = NULL; #endif pInterfaceRecord = (struct ifreq*)pIter; #ifdef AF_LINK if (pInterfaceRecord->ifr_addr.sa_family == AF_LINK) { #if defined(__LWI_AIX__) dwLen = DNS_MAX(sizeof(struct sockaddr_dl), ((struct sockaddr_dl*)&pInterfaceRecord->ifr_addr)->sdl_len); #else /* Solaris etc. */ dwLen = sizeof(struct sockaddr_dl); #endif } else { #endif switch (pInterfaceRecord->ifr_addr.sa_family) { #ifdef HAVE_SOCKADDR_SA_LEN dwLen = DNS_MAX(sizeof(struct sockaddr), pInterfaceRecord->ifr_addr.sa_len); #else #ifdef AF_INET6 case AF_INET6: #ifdef __LWI_HP_UX__ dwLen = sizeof(short) + sizeof(short) + sizeof(uint32_t) + (sizeof(uint8_t) * 16); #else dwLen = sizeof(struct sockaddr_in6); #endif break; #endif case AF_INET: default: dwLen = sizeof(struct sockaddr); break; } #endif /* HAVE_SOCKADDR_SA_LEN */ #ifdef AF_LINK } #endif pIter += sizeof(pInterfaceRecord->ifr_name) + dwLen; #ifdef LW_SKIP_ALIASED_INTERFACES // On Solaris, the name for an aliased interface contains // a colon. if ((pszIndex = strchr(pInterfaceRecord->ifr_name, ':'))) { *pszIndex = '\0'; } #endif memset(szItfName, 0, sizeof(szItfName)); memcpy(szItfName, pInterfaceRecord->ifr_name, IFNAMSIZ); LWDNS_LOG_VERBOSE("Considering network interface [%s]", szItfName); pSA = (struct sockaddr*)&pInterfaceRecord->ifr_addr; if (pSA->sa_family != AF_INET) { LWDNS_LOG_VERBOSE("Skipping network interface [%s] [family:%d] because it is not AF_INET family", szItfName, pSA->sa_family); continue; } interfaceRecordCopy = *pInterfaceRecord; if (ioctl(fd, SIOCGIFFLAGS, &interfaceRecordCopy) < 0) { dwError = errno; BAIL_ON_LWDNS_ERROR(dwError); } dwFlags = interfaceRecordCopy.ifr_flags; if (dwFlags & IFF_LOOPBACK) { LWDNS_LOG_VERBOSE("Skipping loopback network interface [%s]", szItfName); continue; } if (!(dwFlags & IFF_UP)) { LWDNS_LOG_VERBOSE("Skipping in-active network interface [%s]", szItfName); continue; } #ifdef LW_SKIP_ALIASED_INTERFACES if (DNSInterfaceIsInList(szItfName, pInterfaceList)) { LWDNS_LOG_VERBOSE("Skipping aliased network interface [%s]", IsNullOrEmptyString(szItfName) ? "" : szItfName); continue; } #endif dwError = DNSAllocateMemory( sizeof(LW_INTERFACE_INFO), (PVOID*)&pInterfaceInfo); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSAllocateMemory( IF_NAMESIZE, (PVOID*)&pInterfaceInfo->pszName); BAIL_ON_LWDNS_ERROR(dwError); strncpy(pInterfaceInfo->pszName, pInterfaceRecord->ifr_name, IF_NAMESIZE-1); pInterfaceInfo->dwFlags = dwFlags; if (ioctl(fd, SIOCGIFADDR, &interfaceRecordCopy, sizeof(struct ifreq)) < 0) { dwError = errno; BAIL_ON_LWDNS_ERROR(dwError); } // From the above logic, we consider only // AF_INET addresses at this point. memcpy(&pInterfaceInfo->ipAddr, &pInterfaceRecord->ifr_addr, sizeof(struct sockaddr_in)); dwError = LwDLinkedListAppend( &pInterfaceList, pInterfaceInfo); BAIL_ON_LWDNS_ERROR(dwError); pszIpAddress = inet_ntoa(((struct sockaddr_in*)&pInterfaceInfo->ipAddr)->sin_addr); LWDNS_LOG_VERBOSE("Added network interface [Name:%s; Address:%s] to list", (IsNullOrEmptyString(pInterfaceInfo->pszName) ? "" : pInterfaceInfo->pszName), (IsNullOrEmptyString(pszIpAddress) ? "" : pszIpAddress)); pInterfaceInfo = NULL; } *ppInterfaceList = pInterfaceList; cleanup: if (fd >= 0) { close(fd); } if (pBuffer) { DNSFreeMemory(pBuffer); } return dwError; error: if (pInterfaceInfo) { DNSFreeNetworkInterface(pInterfaceInfo); } if (pInterfaceList) { DNSFreeInterfaceLinkedList(pInterfaceList); } 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; }
/* * 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; }
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; }
static DWORD DNSStdUnmarshallAdditionalSection( HANDLE hReceiveBuffer, WORD wAdditionals, PDNS_RR_RECORD ** pppDNSAdditionalsRRRecords ) { DWORD dwError = 0; DWORD i = 0; PDNS_RR_RECORD pDNSRRRecord = NULL; PDNS_RR_RECORD * ppDNSAdditionalRRRecords = NULL; PBYTE pRData = NULL; DNS_RR_HEADER RRHeader = {0}; PDNS_RR_HEADER pRRHeader = &RRHeader; dwError = DNSAllocateMemory( wAdditionals * sizeof(PDNS_RR_RECORD), (PVOID *)&ppDNSAdditionalRRRecords); BAIL_ON_LWDNS_ERROR(dwError); for (i = 0; i < wAdditionals; i++) { DWORD dwRead = 0; memset(pRRHeader, 0, sizeof(DNS_RR_HEADER)); dwError = DNSUnmarshallRRHeader( hReceiveBuffer, pRRHeader); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSUnmarshallRData( hReceiveBuffer, pRRHeader->wRDataSize, &pRData, &dwRead); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSAllocateMemory( sizeof(DNS_RR_RECORD), (PVOID *)&pDNSRRRecord); BAIL_ON_LWDNS_ERROR(dwError); memcpy(&pDNSRRRecord->RRHeader, pRRHeader, sizeof(DNS_RR_HEADER)); pRRHeader->pDomainName = NULL; pDNSRRRecord->pRData = pRData; pRData = NULL; *(ppDNSAdditionalRRRecords + i) = pDNSRRRecord; pDNSRRRecord = NULL; } *pppDNSAdditionalsRRRecords = ppDNSAdditionalRRRecords; cleanup: return dwError; error: if (pRData) { DNSFreeMemory(pRData); } if (pDNSRRRecord) { DNSFreeRecord(pDNSRRRecord); } if (pRRHeader && pRRHeader->pDomainName) { DNSFreeDomainName(pRRHeader->pDomainName); } if (ppDNSAdditionalRRRecords) { DNSFreeRecordList( ppDNSAdditionalRRRecords, wAdditionals); } *pppDNSAdditionalsRRRecords = NULL; goto cleanup; }
static DWORD DNSBuildInterfaceArray( PLW_DLINKED_LIST pInterfaceList, PLW_INTERFACE_INFO* ppInterfaceInfoArray, PDWORD pdwNumInterfaces ) { DWORD dwError = 0; DWORD dwNumInterfaces = 0; PLW_INTERFACE_INFO pInterfaceInfoArray = NULL; PLW_DLINKED_LIST pIter = NULL; DWORD i = 0; for (pIter = pInterfaceList; pIter; pIter = pIter->pNext) { dwNumInterfaces++; } if (!dwNumInterfaces) { goto done; } dwError = DNSAllocateMemory( sizeof(LW_INTERFACE_INFO) * dwNumInterfaces, (PVOID*)&pInterfaceInfoArray); BAIL_ON_LWDNS_ERROR(dwError); for (pIter = pInterfaceList; pIter; pIter = pIter->pNext, i++) { PLW_INTERFACE_INFO pSrcInfo = NULL; PLW_INTERFACE_INFO pDstInfo = NULL; pSrcInfo = (PLW_INTERFACE_INFO)pIter->pItem; pDstInfo = &pInterfaceInfoArray[i]; memcpy(pDstInfo, pSrcInfo, sizeof(LW_INTERFACE_INFO)); memset(pSrcInfo, 0, sizeof(LW_INTERFACE_INFO)); } done: *ppInterfaceInfoArray = pInterfaceInfoArray; *pdwNumInterfaces = dwNumInterfaces; cleanup: return dwError; error: if (pInterfaceInfoArray) { DNSFreeNetworkInterfaces( pInterfaceInfoArray, dwNumInterfaces); } *ppInterfaceInfoArray = NULL; *pdwNumInterfaces = 0; goto cleanup; }
static size_t DNSGetSystemErrorString( DWORD dwConvertError, PSTR pszBuffer, size_t stBufSize ) { DWORD dwError = LWDNS_ERROR_SUCCESS; size_t stResult = 0; PSTR pszTempBuffer = NULL; int result = DNSStrError(dwConvertError, pszBuffer, stBufSize); if (result == EINVAL) { stResult = DNSGetUnmappedErrorString( dwConvertError, pszBuffer, stBufSize); goto cleanup; } while (result != 0) { if (result == ERANGE) { // Guess stBufSize = stBufSize * 2 + 10; } else { stResult = DNSGetUnmappedErrorString( dwConvertError, pszBuffer, stBufSize); goto cleanup; } LWDNS_SAFE_FREE_MEMORY(pszTempBuffer); dwError = DNSAllocateMemory( stBufSize, (PVOID*)&pszTempBuffer); BAIL_ON_LWDNS_ERROR(dwError); result = DNSStrError(dwConvertError, pszTempBuffer, stBufSize); } if (pszTempBuffer != NULL) { stResult = strlen(pszTempBuffer) + 1; } else { stResult = strlen(pszBuffer) + 1; } cleanup: LWDNS_SAFE_FREE_MEMORY(pszTempBuffer); return stResult; error: stResult = 0; goto cleanup; }
DWORD DNSUpdateUnmarshallZoneSection( HANDLE hReceiveBuffer, WORD wZones, PDNS_ZONE_RECORD ** pppDNSZoneRecords ) { DWORD dwError = 0; DWORD i = 0; PDNS_ZONE_RECORD pDNSZoneRecord = NULL; PDNS_ZONE_RECORD * ppDNSZoneRecords = NULL; dwError = DNSAllocateMemory( wZones * sizeof(PDNS_ZONE_RECORD), (PVOID *)&ppDNSZoneRecords); BAIL_ON_LWDNS_ERROR(dwError); for (i = 0; i < wZones; i++) { DWORD dwRead = 0; WORD wnZoneClass = 0; WORD wnZoneType = 0; dwError = DNSAllocateMemory( sizeof(DNS_ZONE_RECORD), (PVOID *)&pDNSZoneRecord); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSUnmarshallDomainName( hReceiveBuffer, &pDNSZoneRecord->pDomainName); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSUnmarshallBuffer( hReceiveBuffer, (PBYTE)&wnZoneType, (DWORD)sizeof(WORD), &dwRead); BAIL_ON_LWDNS_ERROR(dwError); pDNSZoneRecord->wZoneType = ntohs(wnZoneType); dwError = DNSUnmarshallBuffer( hReceiveBuffer, (PBYTE)&wnZoneClass, (DWORD)sizeof(WORD), &dwRead); BAIL_ON_LWDNS_ERROR(dwError); pDNSZoneRecord->wZoneClass = ntohs(wnZoneClass); *(ppDNSZoneRecords + i) = pDNSZoneRecord; pDNSZoneRecord = NULL; } *pppDNSZoneRecords = ppDNSZoneRecords; cleanup: return(dwError); error: if (pDNSZoneRecord) { DNSFreeZoneRecord(pDNSZoneRecord); } if (ppDNSZoneRecords) { DNSFreeZoneRecordList( ppDNSZoneRecords, wZones); } *pppDNSZoneRecords = NULL; goto cleanup; }
DWORD DNSBuildMessageBuffer( PDNS_UPDATE_REQUEST pDNSUpdateRequest, PCSTR pszKeyName, DWORD * pdwTimeSigned, WORD * pwFudge, PBYTE * ppMessageBuffer, PDWORD pdwMessageSize ) { DWORD dwError = 0; PBYTE pSrcBuffer = NULL; DWORD dwReqMsgSize = 0; DWORD dwAlgorithmLen = 0; DWORD dwNameLen = 0; PBYTE pMessageBuffer = NULL; DWORD dwMessageSize = 0; PBYTE pOffset = NULL; WORD wnError, wError = 0; WORD wnFudge = 0; WORD wFudge = DNS_ONE_HOUR_IN_SECS; WORD wnOtherLen = 0, wOtherLen = 0; DWORD dwBytesCopied = 0; WORD wnClass = 0, wClass = DNS_CLASS_ANY; DWORD dwnTTL = 0, dwTTL = 0; DWORD dwnTimeSigned, dwTimeSigned = 0; HANDLE hSendBuffer = (HANDLE)NULL; PDNS_DOMAIN_NAME pDomainName = NULL; PDNS_DOMAIN_NAME pAlgorithmName = NULL; //PBYTE pOtherLen = NULL; WORD wTimePrefix = 0; WORD wnTimePrefix = 0; dwError = DNSDomainNameFromString(pszKeyName, &pDomainName); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSGetDomainNameLength(pDomainName, &dwNameLen); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSDomainNameFromString(DNS_GSS_ALGORITHM, &pAlgorithmName); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSGetDomainNameLength(pAlgorithmName, &dwAlgorithmLen); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSUpdateBuildRequestMessage( pDNSUpdateRequest, &hSendBuffer); BAIL_ON_LWDNS_ERROR(dwError); dwReqMsgSize = DNSGetSendBufferContextSize(hSendBuffer); dwMessageSize += dwReqMsgSize; dwMessageSize += dwNameLen; dwMessageSize += sizeof(WORD); //CLASS dwMessageSize += sizeof(DWORD); //TTL dwMessageSize += dwAlgorithmLen; dwMessageSize += (sizeof(WORD) + sizeof(DWORD)); //Time Signed dwMessageSize += sizeof(WORD); //Fudge dwMessageSize += sizeof(WORD); //wError dwMessageSize += sizeof(WORD); //Other Len dwMessageSize += wOtherLen; dwError = DNSAllocateMemory( dwMessageSize, (PVOID *)&pMessageBuffer); BAIL_ON_LWDNS_ERROR(dwError); pOffset = pMessageBuffer; pSrcBuffer = DNSGetSendBufferContextBuffer(hSendBuffer); memcpy(pOffset, pSrcBuffer, dwReqMsgSize); pOffset += dwReqMsgSize; dwError = DNSCopyDomainName(pOffset, pDomainName, &dwBytesCopied); BAIL_ON_LWDNS_ERROR(dwError); pOffset += dwBytesCopied; wnClass = htons(wClass); memcpy(pOffset, &wnClass, sizeof(WORD)); pOffset += sizeof(WORD); dwnTTL = htonl(dwTTL); memcpy(pOffset, &dwnTTL, sizeof(DWORD)); pOffset += sizeof(DWORD); dwError = DNSCopyDomainName(pOffset, pAlgorithmName, &dwBytesCopied); BAIL_ON_LWDNS_ERROR(dwError); pOffset += dwBytesCopied; wnTimePrefix = htons(wTimePrefix); memcpy(pOffset, &wnTimePrefix, sizeof(WORD)); pOffset += sizeof(WORD); time((time_t*)&dwTimeSigned); dwnTimeSigned = htonl(dwTimeSigned); memcpy(pOffset, &dwnTimeSigned, sizeof(DWORD)); pOffset += sizeof(DWORD); wnFudge = htons(wFudge); memcpy(pOffset, &wnFudge, sizeof(WORD)); pOffset += sizeof(WORD); wnError = htons(wError); memcpy(pOffset, &wnError, sizeof(WORD)); pOffset += sizeof(WORD); wnOtherLen = htons(wOtherLen); memcpy(pOffset, &wnOtherLen, sizeof(WORD)); pOffset += sizeof(WORD); *ppMessageBuffer = pMessageBuffer; *pdwMessageSize = dwMessageSize; *pdwTimeSigned = dwTimeSigned; *pwFudge = wFudge; cleanup: if (pAlgorithmName) { DNSFreeDomainName(pAlgorithmName); } if (pDomainName) { DNSFreeDomainName(pDomainName); } if (hSendBuffer != (HANDLE)NULL) { DNSFreeSendBufferContext(hSendBuffer); } return(dwError); error: if (pMessageBuffer) { DNSFreeMemory(pMessageBuffer); } *ppMessageBuffer = NULL; *pdwMessageSize = 0; *pdwTimeSigned = dwTimeSigned; *pwFudge = wFudge; goto cleanup; }
static DWORD DNSStdUnmarshallQuestionSection( HANDLE hReceiveBuffer, WORD wQuestions, PDNS_QUESTION_RECORD ** pppDNSQuestionRecords ) { DWORD dwError = 0; DWORD i = 0; PDNS_QUESTION_RECORD pDNSQuestionRecord = NULL; PDNS_QUESTION_RECORD * ppDNSQuestionRecords = NULL; dwError = DNSAllocateMemory( wQuestions * sizeof(PDNS_QUESTION_RECORD), (PVOID *)&ppDNSQuestionRecords); BAIL_ON_LWDNS_ERROR(dwError); for (i = 0; i < wQuestions; i++) { DWORD dwRead = 0; WORD wnQueryClass = 0; WORD wnQueryType = 0; dwError = DNSAllocateMemory( sizeof(DNS_QUESTION_RECORD), (PVOID *)&pDNSQuestionRecord); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSUnmarshallDomainName( hReceiveBuffer, &pDNSQuestionRecord->pDomainName); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSUnmarshallBuffer( hReceiveBuffer, (PBYTE)&wnQueryType, (DWORD)sizeof(WORD), &dwRead); BAIL_ON_LWDNS_ERROR(dwError); pDNSQuestionRecord->wQueryType = ntohs(wnQueryType); dwError = DNSUnmarshallBuffer( hReceiveBuffer, (PBYTE)&wnQueryClass, (DWORD)sizeof(WORD), &dwRead); BAIL_ON_LWDNS_ERROR(dwError); pDNSQuestionRecord->wQueryClass = ntohs(wnQueryClass); *(ppDNSQuestionRecords + i) = pDNSQuestionRecord; pDNSQuestionRecord = NULL; } *pppDNSQuestionRecords = ppDNSQuestionRecords; cleanup: return dwError; error: if (ppDNSQuestionRecords) { DNSFreeQuestionRecordList( ppDNSQuestionRecords, wQuestions); } if (pDNSQuestionRecord) { DNSFreeQuestionRecord(pDNSQuestionRecord); } *pppDNSQuestionRecords = NULL; goto cleanup; }
DWORD DNSTCPOpen( PCSTR pszNameServer, PHANDLE phDNSServer ) { DWORD dwError = 0; unsigned long ulAddress = 0; struct hostent * pHost = NULL; PDNS_CONNECTION_CONTEXT pDNSContext = NULL; int err = 0; int connErr = 0; socklen_t connErrLen = 0; fd_set wmask; struct timeval timeOut; dwError = DNSAllocateMemory( sizeof(DNS_CONNECTION_CONTEXT), (PVOID *)&pDNSContext); BAIL_ON_LWDNS_ERROR(dwError); pDNSContext->s = -1; pDNSContext->hType = DNS_TCP; ulAddress = inet_addr (pszNameServer); if (INADDR_NONE == ulAddress) { pHost = gethostbyname (pszNameServer); if (!pHost) { dwError = h_errno; BAIL_ON_HERRNO_ERROR(dwError); } memcpy((char *)&ulAddress, pHost->h_addr, pHost->h_length); } // create the socket // pDNSContext->s = socket (PF_INET, SOCK_STREAM, 0); if (INVALID_SOCKET == pDNSContext->s) { dwError = errno; BAIL_ON_LWDNS_ERROR(dwError); } pDNSContext->RecvAddr.sin_family = AF_INET; pDNSContext->RecvAddr.sin_addr.s_addr = ulAddress; pDNSContext->RecvAddr.sin_port = htons (DNS_TCP_PORT); /* Enable nonblock on this socket for the duration of the connect */ err = fcntl(pDNSContext->s, F_GETFL, 0); if (err == -1) { dwError = errno; BAIL_ON_LWDNS_ERROR(dwError); } /* enable nonblock on this socket. Either err is status or current flags */ err = fcntl(pDNSContext->s, F_SETFL, err | O_NONBLOCK); if (err == -1) { dwError = errno; BAIL_ON_LWDNS_ERROR(dwError); } // connect to remote endpoint // err = connect(pDNSContext->s, (PSOCKADDR) &pDNSContext->RecvAddr, sizeof(pDNSContext->RecvAddr)); if (err == -1 && errno == EINPROGRESS) { dwError = 0; for (;;) { FD_ZERO(&wmask); FD_SET(pDNSContext->s, &wmask); memset(&timeOut, 0, sizeof(timeOut)); timeOut.tv_sec = LW_UPDATE_DNS_TIMEOUT; timeOut.tv_usec = 0; err = select(pDNSContext->s + 1, 0, &wmask, 0, &timeOut); if (err == -1) { if (errno != EINTR) { dwError = errno; BAIL_ON_LWDNS_ERROR(dwError); } } else if (err == 0) { /* select() timed out */ dwError = ETIMEDOUT; BAIL_ON_LWDNS_ERROR(dwError); } else if (err > 0) { connErrLen = (socklen_t) sizeof(connErr); err = getsockopt( pDNSContext->s, SOL_SOCKET, SO_ERROR, &connErr, &connErrLen); if (err == -1) { dwError = errno; BAIL_ON_LWDNS_ERROR(dwError); } else if (connErr != 0) { dwError = connErr; BAIL_ON_LWDNS_ERROR(dwError); } /* socket connected successfully */ break; } } } else if (err == -1) { dwError = errno; BAIL_ON_LWDNS_ERROR(dwError); } /* Disable nonblock on this socket. Either err is status or current flags */ err = fcntl(pDNSContext->s, F_GETFL, 0); if (err == -1) { dwError = errno; BAIL_ON_LWDNS_ERROR(dwError); } err = fcntl(pDNSContext->s, F_SETFL, err & ~O_NONBLOCK); if (err == -1) { dwError = errno; BAIL_ON_LWDNS_ERROR(dwError); } *phDNSServer = (HANDLE)pDNSContext; cleanup: return dwError; error: *phDNSServer = (HANDLE)NULL; if (pDNSContext) { DNSClose((HANDLE)pDNSContext); } goto cleanup; }