Example #1
0
BOOLEAN
WINAPI
Dns_Ip4ReverseNameToAddress_W(OUT PIN_ADDR Address,
                              IN LPWSTR Name)
{
    CHAR AnsiName[32];
    ULONG Size = sizeof(AnsiName);
    INT ErrorCode;

    /* Make a copy of the name in ANSI */
    ErrorCode = Dns_StringCopy(&AnsiName,
                               &Size,
                               Name,
                               0,
                               UnicodeString,
                               AnsiString);
    if (ErrorCode)
    {
        /* Copy made sucesfully, now convert it */
        ErrorCode = Dns_Ip4ReverseNameToAddress_A(Address, AnsiName);
    }

    /* Return either 0 bytes copied (failure == false) or conversion status */
    return ErrorCode;
}
Example #2
0
PHOSTENT
WINAPI
SaBlob_CreateHostent(IN OUT PULONG_PTR BufferPosition,
                     IN OUT PSIZE_T FreeBufferSpace,
                     IN OUT PSIZE_T HostEntrySize,
                     IN PDNS_BLOB Blob,
                     IN DWORD StringType,
                     IN BOOLEAN Relative,
                     IN BOOLEAN BufferAllocated)
{
    PDNS_ARRAY DnsAddrArray = Blob->DnsAddrArray;
    ULONG AliasCount = Blob->AliasCount;
    WORD AddressFamily = AF_UNSPEC;
    ULONG AddressCount = 0, AddressSize = 0, TotalSize, NamePointerSize;
    ULONG AliasPointerSize;
    PDNS_FAMILY_INFO FamilyInfo = NULL;
    ULONG StringLength = 0;
    ULONG i;
    ULONG HostentSize = 0;
    PHOSTENT Hostent = NULL;
    ULONG_PTR HostentPtr;
    PVOID CurrentAddress;

    /* Check if we actually have any addresses */
    if (DnsAddrArray)
    {
        /* Get the address family */
        AddressFamily = DnsAddrArray->Addresses[0].AddressFamily;

        /* Get family information */
        FamilyInfo = FamilyInfo_GetForFamily(AddressFamily);

        /* Save the current address count and their size */
        AddressCount = DnsAddrArray->UsedAddresses;
        AddressSize = FamilyInfo->AddressSize;
    }

    /* Calculate total size for all the addresses, and their pointers */
    TotalSize = AddressSize * AddressCount;
    NamePointerSize = AddressCount * sizeof(PVOID) + sizeof(PVOID);

    /* Check if we have a name */
    if (Blob->Name)
    {
        /* Find out the size we'll need for a copy */
        StringLength = (Dns_GetBufferLengthForStringCopy(Blob->Name,
                                                         0,
                                                         UnicodeString,
                                                         StringType) + 1) & ~1;
    }

    /*  Now do the same for the aliases */
    for (i = AliasCount; i; i--)
    {
        /* Find out the size we'll need for a copy */
        HostentSize += (Dns_GetBufferLengthForStringCopy(Blob->Aliases[i],
                                                         0,
                                                         UnicodeString,
                                                         StringType) + 1) & ~1;
    }

    /* Find out how much the pointers will take */
    AliasPointerSize = AliasCount * sizeof(PVOID) + sizeof(PVOID);

    /* Calculate Hostent Size */
    HostentSize += TotalSize +
                   NamePointerSize +
                   AliasPointerSize +
                   StringLength +
                   sizeof(HOSTENT);

    /* Check if we already have a buffer */
    if (!BufferAllocated)
    {
        /* We don't, allocate space ourselves */
        HostentPtr = (ULONG_PTR)Dns_AllocZero(HostentSize);
    }
    else
    {
        /* We do, so allocate space in the buffer */
        HostentPtr = (ULONG_PTR)FlatBuf_Arg_ReserveAlignPointer(BufferPosition,
                                                                FreeBufferSpace,
                                                                HostentSize);
    }

    /* Make sure we got space */
    if (HostentPtr)
    {
        /* Initialize it */
        Hostent = Hostent_Init((PVOID)&HostentPtr,
                               AddressFamily,
                               AddressSize,
                               AddressCount,
                               AliasCount);
    }

    /* Loop the addresses */
    for (i = 0; i < AddressCount; i++)
    {
        /* Get the pointer of the current address */
        CurrentAddress = (PVOID)((ULONG_PTR)&DnsAddrArray->Addresses[i] +
                                             FamilyInfo->AddressOffset);

        /* Write the pointer */
        Hostent->h_addr_list[i] = (PCHAR)HostentPtr;

        /* Copy the address */
        RtlCopyMemory((PVOID)HostentPtr, CurrentAddress, AddressSize);

        /* Advance the buffer */
        HostentPtr += AddressSize;
    }

    /* Check if we have a name */
    if (Blob->Name)
    {
        /* Align our current position */
        HostentPtr += 1 & ~1;

        /* Save our name here */
        Hostent->h_name = (LPSTR)HostentPtr;

        /* Now copy it in the blob */
        HostentPtr += Dns_StringCopy((PVOID)HostentPtr,
                                     NULL,
                                     Blob->Name,
                                     0,
                                     UnicodeString,
                                     StringType);
    }

    /* Loop the Aliases */
    for (i = AliasCount; i; i--)
    {
        /* Align our current position */
        HostentPtr += 1 & ~1;

        /* Save our alias here */
        Hostent->h_aliases[i] = (LPSTR)HostentPtr;

        /* Now copy it in the blob */
        HostentPtr += Dns_StringCopy((PVOID)HostentPtr,
                                     NULL,
                                     Blob->Aliases[i],
                                     0,
                                     UnicodeString,
                                     StringType);
    }

    /* Check if the caller didn't have a buffer */
    if (!BufferAllocated)
    {
        /* Return the size; not needed if we had a blob, since it's internal */
        *HostEntrySize = *BufferPosition - (ULONG_PTR)HostentPtr;
    }

    /* Convert to Offsets if requested */
    if(Relative) Hostent_ConvertToOffsets(Hostent);

    /* Return the full, complete, hostent */
    return Hostent;
}
Example #3
0
BOOLEAN
WINAPI
Dns_StringToDnsAddrEx(OUT PDNS_ADDRESS DnsAddr,
                      IN PVOID AddressName,
                      IN DWORD AddressFamily,
                      IN BOOLEAN Unicode,
                      IN BOOLEAN Reverse)
{
    IN6_ADDR Addr;
    BOOLEAN Return;
    INT ErrorCode = ERROR_SUCCESS;
    CHAR AnsiName[INET6_ADDRSTRLEN + sizeof("ip6.arpa.")];
    ULONG Size = sizeof(AnsiName);

    /* First check if this is a reverse address string */
    if ((Reverse) && (Unicode))
    {
        /* Convert it right now to ANSI as an optimization */
        Dns_StringCopy(AnsiName,
                       &Size,
                       AddressName,
                       0,
                       UnicodeString,
                       AnsiString);

        /* Use the ANSI Name instead */
        AddressName = AnsiName;
    }

    /* 
     * If the caller doesn't know what the family is, we'll assume IPv4 and
     * check if we failed or not. If the caller told us it's IPv4, then just
     * do IPv4...
     */
    if ((AddressFamily == AF_UNSPEC) || (AddressFamily == AF_INET))
    {
        /* Now check if the caller gave us the reverse name or not */
        if (Reverse)
        {
            /* Get the Address */
            Return = Dns_Ip4ReverseNameToAddress_A((PIN_ADDR)&Addr, AddressName);
        }
        else
        {
            /* Check if the caller gave us unicode or not */
            if (Unicode)
            {
                /* Get the Address */
                Return = Dns_Ip4StringToAddress_W((PIN_ADDR)&Addr, AddressName);
            }
            else
            {
                /* Get the Address */
                Return = Dns_Ip4StringToAddress_A((PIN_ADDR)&Addr, AddressName);
            }
        }

        /* Check if we suceeded */
        if (Return)
        {
            /* Build the IPv4 Address */
            DnsAddr_BuildFromIp4(DnsAddr, *(PIN_ADDR)&Addr, 0);

            /* So we don't go in the code below... */
            AddressFamily = AF_INET;
        }
    }

    /* If we are here, either AF_INET6 was specified or IPv4 failed */
    if ((AddressFamily == AF_UNSPEC) || (AddressFamily == AF_INET6))
    {
        /* Now check if the caller gave us the reverse name or not */
        if (Reverse)
        {
            /* Get the Address */
            Return = Dns_Ip6ReverseNameToAddress_A(&Addr, AddressName);
            if (Return)
            {
                /* Build the IPv6 Address */
                DnsAddr_BuildFromIp6(DnsAddr, &Addr, 0, 0);
            }
            else
            {
                goto Quickie;
            }
        }
        else
        {
            /* Check if the caller gave us unicode or not */
            if (Unicode)
            {
                /* Get the Address */
                if (NT_SUCCESS(RtlIpv6StringToAddressExW(AddressName,
                                                         &DnsAddr->Ip6Address.sin6_addr,
                                                         &DnsAddr->Ip6Address.sin6_scope_id,
                                                         &DnsAddr->Ip6Address.sin6_port)))
                    Return = TRUE;
                else
                    Return = FALSE;
            }
            else
            {
                /* Get the Address */
                if (NT_SUCCESS(RtlIpv6StringToAddressExA(AddressName,
                                                         &DnsAddr->Ip6Address.sin6_addr,
                                                         &DnsAddr->Ip6Address.sin6_scope_id,
                                                         &DnsAddr->Ip6Address.sin6_port)))
                   Return = TRUE;
                else
                   Return = FALSE;
            }
        }

        /* Check if we suceeded */
        if (Return)
        {
            /* Finish setting up the structure */
            DnsAddr->Ip6Address.sin6_family = AF_INET6;
            DnsAddr->AddressLength = sizeof(SOCKADDR_IN6);
        }
    }
    else if (AddressFamily != AF_INET)
    {
        /* You're like.. ATM or something? Get outta here! */
        RtlZeroMemory(DnsAddr, sizeof(DNS_ADDRESS));
        SetLastError(WSA_INVALID_PARAMETER);
    }

Quickie:
    /* Return success or failure */
    return (ErrorCode == ERROR_SUCCESS);
}
Example #4
0
BOOLEAN
WINAPI
Dns_StringToAddressEx(OUT PVOID Address,
                      IN OUT PULONG AddressSize,
                      IN PVOID AddressName,
                      IN OUT PDWORD AddressFamily,
                      IN BOOLEAN Unicode,
                      IN BOOLEAN Reverse)
{
    DWORD Af = *AddressFamily;
    ULONG AddrSize = *AddressSize;
    IN6_ADDR Addr;
    BOOLEAN Return;
    INT ErrorCode;
    CHAR AnsiName[INET6_ADDRSTRLEN + sizeof("ip6.arpa.")];
    ULONG Size = sizeof(AnsiName);

    /* First check if this is a reverse address string */
    if (Reverse)
    {
        /* Convert it right now to ANSI as an optimization */
        Dns_StringCopy(AnsiName,
                       &Size,
                       AddressName,
                       0,
                       UnicodeString,
                       AnsiString);

        /* Use the ANSI Name instead */
        AddressName = AnsiName;
    }

    /* 
     * If the caller doesn't know what the family is, we'll assume IPv4 and
     * check if we failed or not. If the caller told us it's IPv4, then just
     * do IPv4...
     */
    if ((Af == AF_UNSPEC) || (Af == AF_INET))
    {
        /* Now check if the caller gave us the reverse name or not */
        if (Reverse)
        {
            /* Get the Address */
            Return = Dns_Ip4ReverseNameToAddress_A((PIN_ADDR)&Addr, AddressName);
        }
        else
        {
            /* Check if the caller gave us unicode or not */
            if (Unicode)
            {
                /* Get the Address */
                Return = Dns_Ip4StringToAddress_W((PIN_ADDR)&Addr, AddressName);
            }
            else
            {
                /* Get the Address */
                Return = Dns_Ip4StringToAddress_A((PIN_ADDR)&Addr, AddressName);
            }
        }

        /* Check if we suceeded */
        if (Return)
        {
            /* Save address family */
            Af = AF_INET;

            /* Check if the address size matches */
            if (AddrSize < sizeof(IN_ADDR))
            {
                /* Invalid match, set error code */
                ErrorCode = ERROR_MORE_DATA;
            }
            else
            {
                /* It matches, save the address! */
                *(PIN_ADDR)Address = *(PIN_ADDR)&Addr;
            }
        }
    }

    /* If we are here, either AF_INET6 was specified or IPv4 failed */
    if ((Af == AF_UNSPEC) || (Af == AF_INET6))
    {
        /* Now check if the caller gave us the reverse name or not */
        if (Reverse)
        {
            /* Get the Address */
            Return = Dns_Ip6ReverseNameToAddress_A(&Addr, AddressName);
        }
        else
        {
            /* Check if the caller gave us unicode or not */
            if (Unicode)
            {
                /* Get the Address */
                Return = Dns_Ip6StringToAddress_W(&Addr, AddressName);
            }
            else
            {
                /* Get the Address */
                Return = Dns_Ip6StringToAddress_A(&Addr, AddressName);
            }
        }

        /* Check if we suceeded */
        if (Return)
        {
            /* Save address family */
            Af = AF_INET6;

            /* Check if the address size matches */
            if (AddrSize < sizeof(IN6_ADDR))
            {
                /* Invalid match, set error code */
                ErrorCode = ERROR_MORE_DATA;
            }
            else
            {
                /* It matches, save the address! */
                *(PIN6_ADDR)Address = Addr;
            }
        }
    }
    else if (Af != AF_INET)
    {
        /* You're like.. ATM or something? Get outta here! */
        Af = AF_UNSPEC;
        ErrorCode = WSA_INVALID_PARAMETER;
    }

    /* Set error if we had one */
    if (ErrorCode) SetLastError(ErrorCode);

    /* Return the address family and size */
    *AddressFamily = Af;
    *AddressSize = AddrSize;

    /* Return success or failure */
    return (ErrorCode == ERROR_SUCCESS);
}