DWORD DNSUpdateAddUpdateSection( PDNS_UPDATE_REQUEST pDNSRequest, PDNS_RR_RECORD pDNSRecord ) { DWORD dwError = 0; WORD wNumUpdates = 0; wNumUpdates = pDNSRequest->wUpdates; dwError = DNSReallocMemory( pDNSRequest->ppUpdateRRSet, (PVOID *)&pDNSRequest->ppUpdateRRSet, (wNumUpdates + 1) * sizeof(PDNS_RR_RECORD)); BAIL_ON_LWDNS_ERROR(dwError); *(pDNSRequest->ppUpdateRRSet + wNumUpdates) = pDNSRecord; pDNSRequest->wUpdates += 1; error: return dwError; }
DWORD DNSUpdateAddPRSection( PDNS_UPDATE_REQUEST pDNSRequest, PDNS_RR_RECORD pDNSRecord ) { DWORD dwError = 0; DWORD dwNumPRs = 0; dwNumPRs = pDNSRequest->wPRs; dwError = DNSReallocMemory( pDNSRequest->ppPRRRSet, (PVOID *)&pDNSRequest->ppPRRRSet, (dwNumPRs + 1) *sizeof(PDNS_RR_RECORD)); BAIL_ON_LWDNS_ERROR(dwError); *(pDNSRequest->ppPRRRSet + dwNumPRs) = pDNSRecord; pDNSRequest->wPRs += 1; error: return dwError; }
DWORD DNSUpdateAddZoneSection( PDNS_UPDATE_REQUEST pDNSRequest, PDNS_ZONE_RECORD pDNSZone ) { DWORD dwError = 0; DWORD dwNumZones = 0; dwNumZones = pDNSRequest->wZones; dwError = DNSReallocMemory( (PBYTE)pDNSRequest->ppZoneRRSet, (PVOID *)&pDNSRequest->ppZoneRRSet, (dwNumZones + 1)*sizeof(PDNS_ZONE_RECORD)); BAIL_ON_LWDNS_ERROR(dwError); *(pDNSRequest->ppZoneRRSet + dwNumZones) = pDNSZone; pDNSRequest->wZones += 1; error: return dwError; }
DWORD DNSMarshallBuffer( HANDLE hDNSSendBuffer, PBYTE pDNSSendBuffer, DWORD dwBufferSize, PDWORD pdwBytesWritten ) { DWORD dwError = 0; PBYTE pTemp = NULL; PDNS_SENDBUFFER_CONTEXT pDNSContext = NULL; DWORD dwRemaining = 0; pDNSContext = (PDNS_SENDBUFFER_CONTEXT)hDNSSendBuffer; dwRemaining = pDNSContext->dwBufferSize - pDNSContext->dwBufferOffset; if (dwRemaining < dwBufferSize) { DWORD dwNewSize = (pDNSContext->dwBufferSize + (dwBufferSize - dwRemaining) + 256); dwError = DNSReallocMemory( pDNSContext->pSendBuffer, (PVOID*)&pDNSContext->pSendBuffer, dwNewSize); BAIL_ON_LWDNS_ERROR(dwError); pDNSContext->dwBufferSize = dwNewSize; } pTemp = pDNSContext->pSendBuffer + pDNSContext->dwBufferOffset; memcpy(pTemp, pDNSSendBuffer, dwBufferSize); pDNSContext->dwBytesWritten += dwBufferSize; pDNSContext->dwBufferOffset += dwBufferSize; *pdwBytesWritten = dwBufferSize; cleanup: return dwError; error: *pdwBytesWritten = 0; goto cleanup; }
DWORD DNSUnmarshallBuffer( HANDLE hDNSRecvBuffer, PBYTE pDNSRecvBuffer, DWORD dwBufferSize, PDWORD pdwBytesRead ) { DWORD dwError = 0; PBYTE pTemp = NULL; PDNS_RECEIVEBUFFER_CONTEXT pDNSContext = NULL; DWORD dwRemaining = 0; pDNSContext = (PDNS_RECEIVEBUFFER_CONTEXT)hDNSRecvBuffer; dwRemaining = pDNSContext->dwBufferSize - pDNSContext->dwBytesRead; if (dwRemaining < dwBufferSize) { DWORD dwNewSize = (pDNSContext->dwBufferSize + (dwBufferSize - dwRemaining) + 256); dwError = DNSReallocMemory( pDNSContext->pRecvBuffer, (PVOID*)&pDNSContext->pRecvBuffer, dwNewSize); BAIL_ON_LWDNS_ERROR(dwError); pDNSContext->dwBufferSize = dwNewSize; } pTemp = pDNSContext->pRecvBuffer + pDNSContext->dwBytesRead; memcpy(pDNSRecvBuffer, pTemp, dwBufferSize); pDNSContext->dwBytesRead += dwBufferSize; *pdwBytesRead = dwBufferSize; cleanup: return dwError; error: *pdwBytesRead = 0; 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; }