Exemple #1
0
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;
}
Exemple #4
0
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;
}
Exemple #5
0
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;
}
Exemple #6
0
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;
}
Exemple #7
0
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;
}
Exemple #9
0
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;
}
Exemple #10
0
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;
}
Exemple #14
0
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;
}
Exemple #15
0
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;
}
Exemple #16
0
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;   
}
Exemple #17
0
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; 
}
Exemple #19
0
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;
}