VOID DNSFreeSendBufferContext( HANDLE hSendBuffer ) { PDNS_SENDBUFFER_CONTEXT pSendBufferContext = NULL; pSendBufferContext = (PDNS_SENDBUFFER_CONTEXT)hSendBuffer; if (pSendBufferContext->pSendBuffer) { DNSFreeMemory(pSendBufferContext->pSendBuffer); } if (pSendBufferContext) { DNSFreeMemory(pSendBufferContext); } }
VOID DNSFreeSendBuffer( HANDLE hDNSSendBuffer ) { PDNS_SENDBUFFER_CONTEXT pDNSContext = NULL; pDNSContext = (PDNS_SENDBUFFER_CONTEXT)hDNSSendBuffer; if (pDNSContext){ DNSFreeMemory(pDNSContext->pSendBuffer); DNSFreeMemory(pDNSContext); } return; }
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; }
VOID DNSFreeReceiveBufferContext( HANDLE hRecvBuffer ) { PDNS_RECEIVEBUFFER_CONTEXT pRecvBufferContext = NULL; pRecvBufferContext = (PDNS_RECEIVEBUFFER_CONTEXT)hRecvBuffer; if (pRecvBufferContext->pRecvBuffer) { DNSFreeMemory(pRecvBufferContext->pRecvBuffer); } if (pRecvBufferContext) { DNSFreeMemory(pRecvBufferContext); } }
VOID DNSUpdateFreeRequest( PDNS_UPDATE_REQUEST pDNSRequest ) { if (pDNSRequest->ppZoneRRSet) { DNSFreeZoneRecordList( pDNSRequest->ppZoneRRSet, pDNSRequest->wZones); } if (pDNSRequest->ppPRRRSet) { DNSFreeRecordList( pDNSRequest->ppPRRRSet, pDNSRequest->wPRs); } if (pDNSRequest->ppUpdateRRSet) { DNSFreeRecordList( pDNSRequest->ppUpdateRRSet, pDNSRequest->wUpdates); } if (pDNSRequest->ppAdditionalRRSet) { DNSFreeRecordList( pDNSRequest->ppAdditionalRRSet, pDNSRequest->wAdditionals); } DNSFreeMemory(pDNSRequest); }
VOID DNSFreeNetworkInterface( PLW_INTERFACE_INFO pInterfaceInfo ) { DNSFreeNetworkInterfaceContents(pInterfaceInfo); DNSFreeMemory(pInterfaceInfo); }
VOID DNSDLinkedListFree( PDNSDLINKEDLIST pList ) { while (pList) { PDNSDLINKEDLIST pTmp = pList; pList = pList->pNext; DNSFreeMemory(pTmp); } }
VOID DNSStdFreeResponse( PDNS_RESPONSE pDNSResponse ) { if (pDNSResponse->ppQuestionRRSet) { DNSFreeQuestionRecordList( pDNSResponse->ppQuestionRRSet, pDNSResponse->wQuestions); } if (pDNSResponse->ppAnswerRRSet) { DNSFreeRecordList( pDNSResponse->ppAnswerRRSet, pDNSResponse->wAnswers); } if (pDNSResponse->ppAuthorityRRSet) { DNSFreeRecordList( pDNSResponse->ppAuthorityRRSet, pDNSResponse->wAuthoritys); } if (pDNSResponse->ppAdditionalRRSet) { DNSFreeRecordList( pDNSResponse->ppAdditionalRRSet, pDNSResponse->wAdditionals); } if (pDNSResponse->pDNSOutBuffer) { DNSFreeMemory(pDNSResponse->pDNSOutBuffer); } DNSFreeMemory(pDNSResponse); }
VOID DNSUpdateFreeResponse( PDNS_UPDATE_RESPONSE pDNSResponse ) { if (pDNSResponse->ppZoneRRSet) { DNSFreeZoneRecordList( pDNSResponse->ppZoneRRSet, pDNSResponse->wZones); } if (pDNSResponse->ppPRRRSet) { DNSFreeRecordList( pDNSResponse->ppPRRRSet, pDNSResponse->wPRs); } if (pDNSResponse->ppUpdateRRSet) { DNSFreeRecordList( pDNSResponse->ppUpdateRRSet, pDNSResponse->wUpdates); } if (pDNSResponse->ppAdditionalRRSet) { DNSFreeRecordList( pDNSResponse->ppAdditionalRRSet, pDNSResponse->wAdditionals); } if (pDNSResponse->pDNSOutBuffer) { DNSFreeMemory(pDNSResponse->pDNSOutBuffer); } DNSFreeMemory(pDNSResponse); }
VOID DNSFreeNetworkInterfaces( PLW_INTERFACE_INFO pInterfaceInfoArray, DWORD dwNumInterfaces ) { DWORD iItf = 0; for (; iItf < dwNumInterfaces; iItf++) { PLW_INTERFACE_INFO pInterfaceInfo = NULL; pInterfaceInfo = &pInterfaceInfoArray[iItf]; DNSFreeNetworkInterfaceContents(pInterfaceInfo); } DNSFreeMemory(pInterfaceInfoArray); }
DWORD DNSUDPClose( HANDLE hBindServer ) { DWORD dwError = 0; PDNS_CONNECTION_CONTEXT pDNSContext = NULL; pDNSContext = (PDNS_CONNECTION_CONTEXT)hBindServer; if (pDNSContext->s >= 0) { close(pDNSContext->s); } DNSFreeMemory(pDNSContext); return dwError; }
BOOLEAN DNSDLinkedListDelete( PDNSDLINKEDLIST* ppList, PVOID pItem ) { BOOLEAN bFound = FALSE; PDNSDLINKEDLIST pList = (ppList ? *ppList : NULL); PDNSDLINKEDLIST pCandidate = NULL; while (pList) { if (pList->pItem == pItem) { pCandidate = pList; bFound = TRUE; break; } pList = pList->pNext; } if (bFound) { if (pCandidate->pNext) { // Connect the next neighbor to our previous neighbor pCandidate->pNext->pPrev = pCandidate->pPrev; } if (pCandidate->pPrev) { // Connect the previous neighbor to our next neighbor pCandidate->pPrev->pNext = pCandidate->pNext; } if (*ppList == pCandidate) { *ppList = pCandidate->pNext; } pCandidate->pItem = NULL; DNSFreeMemory(pCandidate); } return bFound; }
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 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 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; }
DWORD DNSUpdateGenerateSignature( PCtxtHandle pGSSContext, PDNS_UPDATE_REQUEST pDNSUpdateRequest, PCSTR pszKeyName ) { DWORD dwError = 0; DWORD dwMinorStatus = 0; HANDLE hSendBuffer = (HANDLE)NULL; PBYTE pMessageBuffer = NULL; DWORD dwMessageSize = 0; DWORD dwTimeSigned = 0; WORD wFudge = 0; gss_buffer_desc MsgDesc = {0}; gss_buffer_desc MicDesc = {0}; PDNS_RR_RECORD pDNSTSIGRecord = NULL; dwError = DNSBuildMessageBuffer( pDNSUpdateRequest, pszKeyName, &dwTimeSigned, &wFudge, &pMessageBuffer, &dwMessageSize); BAIL_ON_LWDNS_ERROR(dwError); MsgDesc.value = pMessageBuffer; MsgDesc.length = dwMessageSize; MicDesc.value = NULL; MicDesc.length = 0; dwError = gss_get_mic( (OM_uint32 *)&dwMinorStatus, *pGSSContext, 0, &MsgDesc, &MicDesc); lwdns_display_status("gss_init_context", dwError, dwMinorStatus); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSCreateTSIGRecord( pszKeyName, dwTimeSigned, wFudge, pDNSUpdateRequest->wIdentification, MicDesc.value, MicDesc.length, &pDNSTSIGRecord); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSUpdateAddAdditionalSection( pDNSUpdateRequest, pDNSTSIGRecord); BAIL_ON_LWDNS_ERROR(dwError); pDNSTSIGRecord = NULL; cleanup: gss_release_buffer(&dwMinorStatus, &MicDesc); if (pDNSTSIGRecord) { DNSFreeRecord(pDNSTSIGRecord); } if (hSendBuffer) { DNSFreeSendBufferContext(hSendBuffer); } if (pMessageBuffer) { DNSFreeMemory(pMessageBuffer); } return(dwError); error: 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; }