1864 lines
36 KiB
C
1864 lines
36 KiB
C
/*++
|
||
|
||
Copyright (c) 1996-2001 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
straddr.c
|
||
|
||
Abstract:
|
||
|
||
Domain Name System (DNS) Library
|
||
|
||
Routines to string to\from address conversions.
|
||
|
||
Author:
|
||
|
||
Jim Gilroy (jamesg) December 1996
|
||
|
||
Revision History:
|
||
|
||
jamesg June 2000 New IP6 parsing.
|
||
jamesg Oct 2000 Created this module.
|
||
|
||
--*/
|
||
|
||
|
||
#include "local.h"
|
||
#include "ws2tcpip.h" // IP6 inaddr definitions
|
||
|
||
|
||
|
||
//
|
||
// String to address
|
||
//
|
||
|
||
BOOL
|
||
Dns_Ip6StringToAddress_A(
|
||
OUT PIP6_ADDRESS pIp6Addr,
|
||
IN PCSTR pString
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Convert string to IP6 address.
|
||
|
||
Arguments:
|
||
|
||
pAddress -- ptr to IP6 address to be filled in
|
||
|
||
pString -- string with IP6 address
|
||
|
||
Return Value:
|
||
|
||
TRUE if successful.
|
||
FALSE otherwise.
|
||
|
||
--*/
|
||
{
|
||
DNS_STATUS status;
|
||
PCHAR pstringEnd = NULL;
|
||
|
||
|
||
DNSDBG( PARSE2, (
|
||
"Dns_Ip6StringToAddress_A( %s )\n",
|
||
pString ));
|
||
|
||
//
|
||
// convert to IP6 address
|
||
//
|
||
|
||
status = RtlIpv6StringToAddressA(
|
||
pString,
|
||
& pstringEnd,
|
||
(PIN6_ADDR) pIp6Addr );
|
||
|
||
return( status == NO_ERROR && *pstringEnd==0 );
|
||
}
|
||
|
||
|
||
|
||
BOOL
|
||
Dns_Ip6StringToAddressEx_A(
|
||
OUT PIP6_ADDRESS pIp6Addr,
|
||
IN PCSTR pchString,
|
||
IN DWORD dwStringLength
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Convert string to IP6 address.
|
||
|
||
This version handles non-NULL-terminated strings
|
||
for DNS server file load.
|
||
|
||
Arguments:
|
||
|
||
pAddress -- ptr to IP6 address to be filled in
|
||
|
||
pchString -- string with IP6 address
|
||
|
||
dwStringLength -- string length
|
||
|
||
Return Value:
|
||
|
||
TRUE if successful.
|
||
FALSE otherwise.
|
||
|
||
--*/
|
||
{
|
||
CHAR tempBuf[ IP6_ADDRESS_STRING_BUFFER_LENGTH ];
|
||
PCSTR pstring;
|
||
|
||
DNSDBG( PARSE2, (
|
||
"Dns_Ip6StringToAddressEx_A( %.*s )\n"
|
||
"\tpchString = %p\n",
|
||
dwStringLength,
|
||
pchString,
|
||
pchString ));
|
||
|
||
//
|
||
// copy string if given length
|
||
// if no length assume NULL terminated
|
||
//
|
||
|
||
pstring = pchString;
|
||
|
||
if ( dwStringLength )
|
||
{
|
||
DWORD bufLength = IP6_ADDRESS_STRING_BUFFER_LENGTH;
|
||
|
||
if ( ! Dns_StringCopy(
|
||
tempBuf,
|
||
& bufLength,
|
||
(PCHAR) pstring,
|
||
dwStringLength,
|
||
DnsCharSetAnsi,
|
||
DnsCharSetAnsi ) )
|
||
{
|
||
return( FALSE );
|
||
}
|
||
pstring = tempBuf;
|
||
}
|
||
|
||
// convert to IP6 address
|
||
|
||
return Dns_Ip6StringToAddress_A(
|
||
pIp6Addr,
|
||
pstring );
|
||
}
|
||
|
||
|
||
|
||
BOOL
|
||
Dns_Ip6StringToAddress_W(
|
||
OUT PIP6_ADDRESS pIp6Addr,
|
||
IN PCWSTR pwString
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Build IP6 address from wide string.
|
||
|
||
Arguments:
|
||
|
||
pwString -- unicode IP6 string
|
||
|
||
pIp6Addr -- addr to recv IP6 address
|
||
|
||
Return Value:
|
||
|
||
TRUE if successful conversion.
|
||
FALSE on bad string.
|
||
|
||
--*/
|
||
{
|
||
DNS_STATUS status;
|
||
PWCHAR pstringEnd = NULL;
|
||
|
||
DNSDBG( PARSE2, (
|
||
"Dns_Ip6StringToAddress_W( %S )\n",
|
||
pwString ));
|
||
|
||
//
|
||
// convert to IP6 address
|
||
//
|
||
|
||
status = RtlIpv6StringToAddressW(
|
||
pwString,
|
||
& pstringEnd,
|
||
(PIN6_ADDR) pIp6Addr );
|
||
|
||
return( status == NO_ERROR && *pstringEnd==0 );
|
||
}
|
||
|
||
|
||
|
||
BOOL
|
||
Dns_Ip4StringToAddress_A(
|
||
OUT PIP4_ADDRESS pIp4Addr,
|
||
IN PCSTR pString
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Build IP4 address from narrow string.
|
||
|
||
Arguments:
|
||
|
||
pIp4Addr -- addr to recv IP6 address
|
||
|
||
pString -- unicode IP4 string
|
||
|
||
Return Value:
|
||
|
||
TRUE if successful conversion.
|
||
FALSE on bad string.
|
||
|
||
--*/
|
||
{
|
||
IP4_ADDRESS ip;
|
||
|
||
// if inet_addr() returns error, verify then error out
|
||
|
||
ip = inet_addr( pString );
|
||
|
||
if ( ip == INADDR_BROADCAST &&
|
||
strcmp( pString, "255.255.255.255" ) != 0 )
|
||
{
|
||
return( FALSE );
|
||
}
|
||
|
||
*pIp4Addr = ip;
|
||
|
||
return( TRUE );
|
||
}
|
||
|
||
|
||
|
||
BOOL
|
||
Dns_Ip4StringToAddressEx_A(
|
||
OUT PIP4_ADDRESS pIp4Addr,
|
||
IN PCSTR pchString,
|
||
IN DWORD dwStringLength
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Build IP4 address from narrow string.
|
||
|
||
This version handles non-NULL terminated strings
|
||
|
||
Arguments:
|
||
|
||
pIp4Addr -- addr to recv IP6 address
|
||
|
||
pString -- unicode IP4 string
|
||
|
||
dwStringLength -- string length; 0 if NULL terminated
|
||
|
||
Return Value:
|
||
|
||
TRUE if successful conversion.
|
||
FALSE on bad string.
|
||
|
||
--*/
|
||
{
|
||
CHAR tempBuf[ IP4_ADDRESS_STRING_BUFFER_LENGTH ];
|
||
PCSTR pstring;
|
||
|
||
DNSDBG( PARSE2, (
|
||
"Dns_Ip4StringToAddressEx_A( %.*s )\n"
|
||
"\tpchString = %p\n",
|
||
dwStringLength,
|
||
pchString,
|
||
pchString ));
|
||
|
||
//
|
||
// copy string if given length
|
||
// if no length assume NULL terminated
|
||
//
|
||
|
||
pstring = pchString;
|
||
|
||
if ( dwStringLength )
|
||
{
|
||
DWORD bufLength = IP4_ADDRESS_STRING_BUFFER_LENGTH;
|
||
|
||
if ( ! Dns_StringCopy(
|
||
tempBuf,
|
||
& bufLength,
|
||
(PCHAR) pstring,
|
||
dwStringLength,
|
||
DnsCharSetAnsi,
|
||
DnsCharSetAnsi ) )
|
||
{
|
||
return( FALSE );
|
||
}
|
||
pstring = tempBuf;
|
||
}
|
||
|
||
return Dns_Ip4StringToAddress_A(
|
||
pIp4Addr,
|
||
pstring );
|
||
}
|
||
|
||
|
||
|
||
BOOL
|
||
Dns_Ip4StringToAddress_W(
|
||
OUT PIP4_ADDRESS pIp4Addr,
|
||
IN PCWSTR pwString
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Build IP4 address from wide string.
|
||
|
||
Arguments:
|
||
|
||
pIp4Addr -- addr to recv IP6 address
|
||
|
||
pwString -- unicode IP6 string
|
||
|
||
Return Value:
|
||
|
||
TRUE if successful conversion.
|
||
FALSE on bad string.
|
||
|
||
--*/
|
||
{
|
||
CHAR bufAddr[ IP4_ADDRESS_STRING_BUFFER_LENGTH ];
|
||
DWORD bufLength = IP4_ADDRESS_STRING_BUFFER_LENGTH;
|
||
|
||
// convert to narrow string
|
||
// - UTF8 quicker and just fine for numeric
|
||
|
||
if ( ! Dns_StringCopy(
|
||
bufAddr,
|
||
& bufLength,
|
||
(PCHAR) pwString,
|
||
0, // length unknown
|
||
DnsCharSetUnicode,
|
||
DnsCharSetUtf8
|
||
) )
|
||
{
|
||
return( FALSE );
|
||
}
|
||
|
||
return Dns_Ip4StringToAddress_A(
|
||
pIp4Addr,
|
||
bufAddr );
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// Combined IP4/IP6 string-to-address
|
||
//
|
||
|
||
BOOL
|
||
Dns_StringToAddress_W(
|
||
OUT PCHAR pAddrBuf,
|
||
IN OUT PDWORD pBufLength,
|
||
IN PCWSTR pString,
|
||
IN OUT PDWORD pAddrFamily
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Build address (IP4 or IP6) from address string.
|
||
|
||
Arguments:
|
||
|
||
pAddrBuf -- buffer to receive address
|
||
|
||
pBufLength -- ptr to address length
|
||
input - length of buffer
|
||
output - length of address found
|
||
|
||
pString -- address string
|
||
|
||
pAddrFamily -- ptr to address family
|
||
input - zero for any family or particular family to check
|
||
output - family found; zero if no conversion
|
||
|
||
Return Value:
|
||
|
||
TRUE if successful.
|
||
FALSE on error. GetLastError() for status.
|
||
|
||
--*/
|
||
{
|
||
return Dns_StringToAddressEx(
|
||
pAddrBuf,
|
||
pBufLength,
|
||
(PCSTR) pString,
|
||
pAddrFamily,
|
||
TRUE, // unicode
|
||
FALSE // forward
|
||
);
|
||
}
|
||
|
||
BOOL
|
||
Dns_StringToAddress_A(
|
||
OUT PCHAR pAddrBuf,
|
||
IN OUT PDWORD pBufLength,
|
||
IN PCSTR pString,
|
||
IN OUT PDWORD pAddrFamily
|
||
)
|
||
{
|
||
return Dns_StringToAddressEx(
|
||
pAddrBuf,
|
||
pBufLength,
|
||
pString,
|
||
pAddrFamily,
|
||
FALSE, // ANSI
|
||
FALSE // forward
|
||
);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// Address to string
|
||
//
|
||
|
||
PWCHAR
|
||
Dns_Ip6AddressToString_W(
|
||
OUT PWCHAR pwString,
|
||
IN PIP6_ADDRESS pIp6Addr
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Convert IP6 address to string format.
|
||
|
||
Arguments:
|
||
|
||
pwString -- buffer to hold string; MUST be at least
|
||
IPV6_ADDRESS_STRING_LENGTH+1 in length
|
||
|
||
pAddress -- IP6 address to convert to string
|
||
|
||
Return Value:
|
||
|
||
Ptr to next location in buffer (the terminating NULL).
|
||
|
||
--*/
|
||
{
|
||
// DCR: could be macro
|
||
|
||
return RtlIpv6AddressToStringW(
|
||
(PIN6_ADDR) pIp6Addr,
|
||
pwString );
|
||
}
|
||
|
||
|
||
|
||
PCHAR
|
||
Dns_Ip6AddressToString_A(
|
||
OUT PCHAR pchString,
|
||
IN PIP6_ADDRESS pIp6Addr
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Convert IP6 address to string format.
|
||
|
||
Arguments:
|
||
|
||
pchString -- buffer to hold string; MUST be at least
|
||
IPV6_ADDRESS_STRING_LENGTH+1 in length
|
||
|
||
pAddress -- IP6 address to convert to string
|
||
|
||
Return Value:
|
||
|
||
Ptr to next location in buffer (the terminating NULL).
|
||
|
||
--*/
|
||
{
|
||
// DCR: could be macro
|
||
|
||
return RtlIpv6AddressToStringA(
|
||
(PIN6_ADDR) pIp6Addr,
|
||
pchString );
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// Address to string -- IP4
|
||
//
|
||
|
||
PWCHAR
|
||
Dns_Ip4AddressToString_W(
|
||
OUT PWCHAR pwString,
|
||
IN PIP4_ADDRESS pIp4Addr
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Convert IP4 address to string format.
|
||
|
||
Arguments:
|
||
|
||
pwString -- buffer to hold string; MUST be at least
|
||
IPV6_ADDRESS_STRING_LENGTH+1 in length
|
||
|
||
pAddress -- IP4 address to convert to string
|
||
|
||
Return Value:
|
||
|
||
Ptr to next location in buffer (the terminating NULL).
|
||
|
||
--*/
|
||
{
|
||
IP4_ADDRESS ip = *pIp4Addr;
|
||
|
||
//
|
||
// convert IP4 address to string
|
||
// - address is in net order, lead byte in low memory
|
||
//
|
||
|
||
pwString += wsprintfW(
|
||
pwString,
|
||
L"%u.%u.%u.%u",
|
||
(UCHAR) (ip & 0x000000ff),
|
||
(UCHAR) ((ip & 0x0000ff00) >> 8),
|
||
(UCHAR) ((ip & 0x00ff0000) >> 16),
|
||
(UCHAR) ((ip & 0xff000000) >> 24)
|
||
);
|
||
|
||
return( pwString );
|
||
}
|
||
|
||
|
||
|
||
PCHAR
|
||
Dns_Ip4AddressToString_A(
|
||
OUT PCHAR pString,
|
||
IN PIP4_ADDRESS pIp4Addr
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Convert IP4 address to string format.
|
||
|
||
Arguments:
|
||
|
||
pchString -- buffer to hold string; MUST be at least
|
||
IPV6_ADDRESS_STRING_LENGTH+1 in length
|
||
|
||
pAddress -- IP4 address to convert to string
|
||
|
||
Return Value:
|
||
|
||
Ptr to next location in buffer (the terminating NULL).
|
||
|
||
--*/
|
||
{
|
||
IP4_ADDRESS ip = *pIp4Addr;
|
||
|
||
//
|
||
// convert IP4 address to string
|
||
// - address is in net order, lead byte in low memory
|
||
//
|
||
|
||
pString += sprintf(
|
||
pString,
|
||
"%u.%u.%u.%u",
|
||
(UCHAR) (ip & 0x000000ff),
|
||
(UCHAR) ((ip & 0x0000ff00) >> 8),
|
||
(UCHAR) ((ip & 0x00ff0000) >> 16),
|
||
(UCHAR) ((ip & 0xff000000) >> 24)
|
||
);
|
||
|
||
return( pString );
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// Address-to-string -- combined IP4/6
|
||
//
|
||
|
||
PCHAR
|
||
Dns_AddressToString_A(
|
||
OUT PCHAR pchString,
|
||
IN OUT PDWORD pStringLength,
|
||
IN PBYTE pAddr,
|
||
IN DWORD AddrLength,
|
||
IN DWORD AddrFamily
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Convert address to string format.
|
||
|
||
Arguments:
|
||
|
||
pchString -- buffer to hold string; MUST be at least
|
||
IPV6_ADDRESS_STRING_LENGTH+1 in length
|
||
|
||
pStringLength -- string buffer length
|
||
|
||
pAddr -- ptr to address
|
||
|
||
AddrLength -- address length
|
||
|
||
AddrFamily -- address family (AF_INET, AF_INET6)
|
||
|
||
Return Value:
|
||
|
||
Ptr to next location in buffer (the terminating NULL).
|
||
NULL if no conversion.
|
||
|
||
--*/
|
||
{
|
||
DWORD length = *pStringLength;
|
||
|
||
// dispatch to conversion routine for this type
|
||
|
||
if ( AddrFamily == AF_INET )
|
||
{
|
||
if ( length < IP_ADDRESS_STRING_LENGTH+1 )
|
||
{
|
||
length = IP_ADDRESS_STRING_LENGTH+1;
|
||
goto Failed;
|
||
}
|
||
return Dns_Ip4AddressToString_A(
|
||
pchString,
|
||
(PIP4_ADDRESS) pAddr );
|
||
}
|
||
|
||
if ( AddrFamily == AF_INET6 )
|
||
{
|
||
if ( length < IP6_ADDRESS_STRING_LENGTH+1 )
|
||
{
|
||
length = IP6_ADDRESS_STRING_LENGTH+1;
|
||
goto Failed;
|
||
}
|
||
return Dns_Ip6AddressToString_A(
|
||
pchString,
|
||
(PIP6_ADDRESS) pAddr );
|
||
}
|
||
|
||
Failed:
|
||
|
||
*pStringLength = length;
|
||
|
||
return NULL;
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// Reverse lookup address-to-name IP4
|
||
//
|
||
|
||
PCHAR
|
||
Dns_Ip4AddressToReverseName_A(
|
||
OUT PCHAR pBuffer,
|
||
IN IP_ADDRESS IpAddress
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Write reverse lookup name, given corresponding IP
|
||
|
||
Arguments:
|
||
|
||
pBuffer -- ptr to buffer for reverse lookup name;
|
||
MUST contain at least DNS_MAX_REVERSE_NAME_BUFFER_LENGTH bytes
|
||
|
||
IpAddress -- IP address to create
|
||
|
||
Return Value:
|
||
|
||
Ptr to next location in buffer.
|
||
|
||
--*/
|
||
{
|
||
DNSDBG( TRACE, ( "Dns_Ip4AddressToReverseName_A()\n" ));
|
||
|
||
//
|
||
// write digits for each octect in IP address
|
||
// - note, it is in net order so lowest octect, is in highest memory
|
||
//
|
||
|
||
pBuffer += sprintf(
|
||
pBuffer,
|
||
"%u.%u.%u.%u.in-addr.arpa.",
|
||
(UCHAR) ((IpAddress & 0xff000000) >> 24),
|
||
(UCHAR) ((IpAddress & 0x00ff0000) >> 16),
|
||
(UCHAR) ((IpAddress & 0x0000ff00) >> 8),
|
||
(UCHAR) (IpAddress & 0x000000ff) );
|
||
|
||
return( pBuffer );
|
||
}
|
||
|
||
|
||
|
||
PWCHAR
|
||
Dns_Ip4AddressToReverseName_W(
|
||
OUT PWCHAR pBuffer,
|
||
IN IP_ADDRESS IpAddress
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Write reverse lookup name, given corresponding IP
|
||
|
||
Arguments:
|
||
|
||
pBuffer -- ptr to buffer for reverse lookup name;
|
||
MUST contain at least DNS_MAX_REVERSE_NAME_BUFFER_LENGTH wide chars
|
||
|
||
IpAddress -- IP address to create
|
||
|
||
Return Value:
|
||
|
||
Ptr to next location in buffer.
|
||
|
||
--*/
|
||
{
|
||
DNSDBG( TRACE, ( "Dns_Ip4AddressToReverseName_W()\n" ));
|
||
|
||
//
|
||
// write digits for each octect in IP address
|
||
// - note, it is in net order so lowest octect, is in highest memory
|
||
//
|
||
|
||
pBuffer += wsprintfW(
|
||
pBuffer,
|
||
L"%u.%u.%u.%u.in-addr.arpa.",
|
||
(UCHAR) ((IpAddress & 0xff000000) >> 24),
|
||
(UCHAR) ((IpAddress & 0x00ff0000) >> 16),
|
||
(UCHAR) ((IpAddress & 0x0000ff00) >> 8),
|
||
(UCHAR) (IpAddress & 0x000000ff) );
|
||
|
||
return( pBuffer );
|
||
}
|
||
|
||
|
||
|
||
PCHAR
|
||
Dns_Ip4AddressToReverseNameAlloc_A(
|
||
IN IP_ADDRESS IpAddress
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Create reverse lookup name string, given corresponding IP.
|
||
|
||
Caller must free the string.
|
||
|
||
Arguments:
|
||
|
||
IpAddress -- IP address to create
|
||
|
||
Return Value:
|
||
|
||
Ptr to new reverse lookup string.
|
||
|
||
--*/
|
||
{
|
||
PCHAR pch;
|
||
PCHAR pchend;
|
||
|
||
DNSDBG( TRACE, ( "Dns_Ip4AddressToReverseNameAlloc_A()\n" ));
|
||
|
||
//
|
||
// allocate space for string
|
||
//
|
||
|
||
pch = ALLOCATE_HEAP( DNS_MAX_REVERSE_NAME_BUFFER_LENGTH );
|
||
if ( !pch )
|
||
{
|
||
return( NULL );
|
||
}
|
||
|
||
//
|
||
// write string for IP
|
||
//
|
||
|
||
pchend = Dns_Ip4AddressToReverseName_A( pch, IpAddress );
|
||
if ( !pchend )
|
||
{
|
||
FREE_HEAP( pch );
|
||
return( NULL );
|
||
}
|
||
|
||
return( pch );
|
||
}
|
||
|
||
|
||
|
||
PWCHAR
|
||
Dns_Ip4AddressToReverseNameAlloc_W(
|
||
IN IP_ADDRESS IpAddress
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Create reverse lookup name string, given corresponding IP.
|
||
|
||
Caller must free the string.
|
||
|
||
Arguments:
|
||
|
||
IpAddress -- IP address to create
|
||
|
||
Return Value:
|
||
|
||
Ptr to new reverse lookup string.
|
||
|
||
--*/
|
||
{
|
||
PWCHAR pch;
|
||
PWCHAR pchend;
|
||
|
||
DNSDBG( TRACE, ( "Dns_Ip4AddressToReverseNameAlloc_W()\n" ));
|
||
|
||
//
|
||
// allocate space for string
|
||
//
|
||
|
||
pch = ALLOCATE_HEAP( DNS_MAX_REVERSE_NAME_BUFFER_LENGTH * sizeof(WCHAR) );
|
||
if ( !pch )
|
||
{
|
||
return( NULL );
|
||
}
|
||
|
||
//
|
||
// write string for IP
|
||
//
|
||
|
||
pchend = Dns_Ip4AddressToReverseName_W( pch, IpAddress );
|
||
if ( !pchend )
|
||
{
|
||
FREE_HEAP( pch );
|
||
return( NULL );
|
||
}
|
||
|
||
return( pch );
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// Reverse lookup address-to-name -- IP6
|
||
//
|
||
|
||
PCHAR
|
||
Dns_Ip6AddressToReverseName_A(
|
||
OUT PCHAR pBuffer,
|
||
IN IP6_ADDRESS Ip6Addr
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Write reverse lookup name, given corresponding IP6 address
|
||
|
||
Arguments:
|
||
|
||
pBuffer -- ptr to buffer for reverse lookup name;
|
||
MUST contain at least DNS_MAX_IP6_REVERSE_NAME_BUFFER_LENGTH bytes
|
||
|
||
Ip6Addr -- IP6 address to create reverse string for
|
||
|
||
Return Value:
|
||
|
||
Ptr to next location in buffer.
|
||
|
||
--*/
|
||
{
|
||
DWORD i;
|
||
|
||
DNSDBG( TRACE, ( "Dns_Ip6AddressToReverseName_A()\n" ));
|
||
|
||
//
|
||
// write digit for each nibble in IP6 address
|
||
//
|
||
// note we are reversing net order here
|
||
// since address is in net order and we are filling
|
||
// in least to most significant order
|
||
// - go DOWN through DWORDS
|
||
// - go DOWN through the BYTES
|
||
// - but we must put the lowest (least significant) nibble
|
||
// first as our bits are not in "bit net order"
|
||
// which is sending the highest bit in the byte first
|
||
//
|
||
|
||
#if 0
|
||
i = 4;
|
||
|
||
while ( i-- )
|
||
{
|
||
DWORD thisDword = Ip6Address.IP6Dword[i];
|
||
|
||
pBuffer += sprintf(
|
||
pBuffer,
|
||
"%u.%u.%u.%u.%u.%u.%u.%u.",
|
||
(thisDword & 0x0f000000) >> 24,
|
||
(thisDword & 0xf0000000) >> 28,
|
||
(thisDword & 0x000f0000) >> 16,
|
||
(thisDword & 0x00f00000) >> 20,
|
||
(thisDword & 0x00000f00) >> 8,
|
||
(thisDword & 0x0000f000) >> 12,
|
||
(thisDword & 0x0000000f) ,
|
||
(thisDword & 0x000000f0) >> 4
|
||
);
|
||
}
|
||
#endif
|
||
i = 16;
|
||
|
||
while ( i-- )
|
||
{
|
||
BYTE thisByte = Ip6Addr.IP6Byte[i];
|
||
|
||
pBuffer += sprintf(
|
||
pBuffer,
|
||
"%x.%x.",
|
||
(thisByte & 0x0f),
|
||
(thisByte & 0xf0) >> 4
|
||
);
|
||
}
|
||
|
||
pBuffer += sprintf(
|
||
pBuffer,
|
||
"ip6.int." );
|
||
|
||
return( pBuffer );
|
||
}
|
||
|
||
|
||
|
||
PWCHAR
|
||
Dns_Ip6AddressToReverseName_W(
|
||
OUT PWCHAR pBuffer,
|
||
IN IP6_ADDRESS Ip6Addr
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Write reverse lookup name, given corresponding IP6 address
|
||
|
||
Arguments:
|
||
|
||
pBuffer -- ptr to buffer for reverse lookup name;
|
||
MUST contain at least DNS_MAX_IP6_REVERSE_NAME_BUFFER_LENGTH wide chars
|
||
|
||
Ip6Addr -- IP6 address to create reverse string for
|
||
|
||
Return Value:
|
||
|
||
Ptr to next location in buffer.
|
||
|
||
--*/
|
||
{
|
||
DWORD i;
|
||
|
||
DNSDBG( TRACE, ( "Dns_Ip6AddressToReverseName_W()\n" ));
|
||
|
||
//
|
||
// write digit for each nibble in IP6 address
|
||
// - in net order so lowest nibble is in highest memory
|
||
//
|
||
|
||
i = 16;
|
||
|
||
while ( i-- )
|
||
{
|
||
BYTE thisByte = Ip6Addr.IP6Byte[i];
|
||
|
||
pBuffer += wsprintfW(
|
||
pBuffer,
|
||
L"%x.%x.",
|
||
(thisByte & 0x0f),
|
||
(thisByte & 0xf0) >> 4
|
||
);
|
||
}
|
||
|
||
pBuffer += wsprintfW(
|
||
pBuffer,
|
||
L"ip6.int." );
|
||
|
||
return( pBuffer );
|
||
}
|
||
|
||
|
||
|
||
PCHAR
|
||
Dns_Ip6AddressToReverseNameAlloc_A(
|
||
IN IP6_ADDRESS Ip6Addr
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Create reverse lookup name given corresponding IP.
|
||
|
||
Caller must free the string.
|
||
|
||
Arguments:
|
||
|
||
Ip6Addr -- IP6 address to create reverse name for
|
||
|
||
Return Value:
|
||
|
||
Ptr to new reverse lookup name string.
|
||
|
||
--*/
|
||
{
|
||
PCHAR pch;
|
||
PCHAR pchend;
|
||
|
||
DNSDBG( TRACE, ( "Dns_Ip6AddressToReverseNameAlloc_A()\n" ));
|
||
|
||
//
|
||
// allocate space for string
|
||
//
|
||
|
||
pch = ALLOCATE_HEAP( DNS_MAX_IP6_REVERSE_NAME_BUFFER_LENGTH );
|
||
if ( !pch )
|
||
{
|
||
return( NULL );
|
||
}
|
||
|
||
//
|
||
// write string for IP
|
||
//
|
||
|
||
pchend = Dns_Ip6AddressToReverseName_A( pch, Ip6Addr );
|
||
if ( !pchend )
|
||
{
|
||
FREE_HEAP( pch );
|
||
return( NULL );
|
||
}
|
||
|
||
return( pch );
|
||
}
|
||
|
||
|
||
|
||
PWCHAR
|
||
Dns_Ip6AddressToReverseNameAlloc_W(
|
||
IN IP6_ADDRESS Ip6Addr
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Create reverse lookup name given corresponding IP.
|
||
|
||
Caller must free the string.
|
||
|
||
Arguments:
|
||
|
||
Ip6Addr -- IP6 address to create reverse name for
|
||
|
||
Return Value:
|
||
|
||
Ptr to new reverse lookup name string.
|
||
|
||
--*/
|
||
{
|
||
PWCHAR pch;
|
||
PWCHAR pchend;
|
||
|
||
DNSDBG( TRACE, ( "Dns_Ip6AddressToReverseNameAlloc_W()\n" ));
|
||
|
||
//
|
||
// allocate space for string
|
||
//
|
||
|
||
pch = (PWCHAR) ALLOCATE_HEAP(
|
||
DNS_MAX_IP6_REVERSE_NAME_BUFFER_LENGTH * sizeof(WCHAR) );
|
||
if ( !pch )
|
||
{
|
||
return( NULL );
|
||
}
|
||
|
||
//
|
||
// write string for IP
|
||
//
|
||
|
||
pchend = Dns_Ip6AddressToReverseName_W( pch, Ip6Addr );
|
||
if ( !pchend )
|
||
{
|
||
FREE_HEAP( pch );
|
||
return( NULL );
|
||
}
|
||
|
||
return( pch );
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// Reverse name-to-address -- IP4
|
||
//
|
||
|
||
BOOL
|
||
Dns_Ip4ReverseNameToAddress_A(
|
||
OUT PIP4_ADDRESS pIp4Addr,
|
||
IN PCSTR pszName
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Get IP for reverse lookup name.
|
||
|
||
Arguments:
|
||
|
||
pIp4Addr -- addr to receive IP address if found
|
||
|
||
pszName -- name to lookup
|
||
|
||
Return Value:
|
||
|
||
TRUE -- if reverse lookup name converted to IP
|
||
FALSE -- if not IP4 reverse lookup name
|
||
|
||
--*/
|
||
{
|
||
#define SIZE_IP4REV (sizeof(".in-addr.arpa")-1)
|
||
|
||
CHAR nameBuffer[ DNS_MAX_IP4_REVERSE_NAME_BUFFER_LENGTH+1 ];
|
||
DWORD nameLength;
|
||
IP_ADDRESS ip;
|
||
PCHAR pch;
|
||
DWORD i;
|
||
DWORD byte;
|
||
|
||
DNSDBG( TRACE, (
|
||
"Dns_Ip4ReverseNameToAddress_A( %s )\n",
|
||
pszName ));
|
||
|
||
//
|
||
// validate name
|
||
// fail if
|
||
// - too long
|
||
// - too short
|
||
// - not in in-addr.arpa domain
|
||
//
|
||
|
||
nameLength = strlen( pszName );
|
||
|
||
if ( nameLength > DNS_MAX_IP4_REVERSE_NAME_BUFFER_LENGTH )
|
||
{
|
||
return( FALSE );
|
||
}
|
||
if ( pszName[nameLength-1] == '.' )
|
||
{
|
||
nameLength--;
|
||
}
|
||
if ( nameLength <= SIZE_IP4REV )
|
||
{
|
||
return( FALSE );
|
||
}
|
||
nameLength -= SIZE_IP4REV;
|
||
|
||
if ( _strnicmp( ".in-addr.arpa", &pszName[nameLength], SIZE_IP4REV ) != 0 )
|
||
{
|
||
return( FALSE );
|
||
}
|
||
|
||
//
|
||
// copy reverse dotted decimal piece of name
|
||
//
|
||
|
||
RtlCopyMemory(
|
||
nameBuffer,
|
||
pszName,
|
||
nameLength );
|
||
|
||
nameBuffer[nameLength] = 0;
|
||
|
||
//
|
||
// read digits
|
||
//
|
||
|
||
ip = 0;
|
||
i = 0;
|
||
|
||
pch = nameBuffer + nameLength;
|
||
|
||
while ( 1 )
|
||
{
|
||
--pch;
|
||
|
||
if ( *pch == '.' )
|
||
{
|
||
*pch = 0;
|
||
pch++;
|
||
}
|
||
else if ( pch == nameBuffer )
|
||
{
|
||
}
|
||
else
|
||
{
|
||
continue;
|
||
}
|
||
|
||
// convert byte
|
||
|
||
byte = strtoul( pch, NULL, 10 );
|
||
if ( byte > 255 )
|
||
{
|
||
return( FALSE );
|
||
}
|
||
if ( i > 3 )
|
||
{
|
||
return( FALSE );
|
||
}
|
||
ip |= byte << (8*i);
|
||
|
||
// terminate at string beginning
|
||
// or continue back up string
|
||
|
||
if ( pch == nameBuffer )
|
||
{
|
||
break;
|
||
}
|
||
i++;
|
||
pch--;
|
||
}
|
||
|
||
*pIp4Addr = ip;
|
||
|
||
DNSDBG( TRACE, (
|
||
"Success on Dns_Ip4ReverseNameToAddress_A( %s ) => %s\n",
|
||
pszName,
|
||
IP_STRING(ip) ));
|
||
|
||
return( TRUE );
|
||
}
|
||
|
||
|
||
|
||
BOOL
|
||
Dns_Ip4ReverseNameToAddress_W(
|
||
OUT PIP4_ADDRESS pIp4Addr,
|
||
IN PCWSTR pwsName
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Get IP for reverse lookup name.
|
||
|
||
Arguments:
|
||
|
||
pIp4Addr -- addr to receive IP address if found
|
||
|
||
pszName -- name to lookup
|
||
|
||
Return Value:
|
||
|
||
TRUE -- if reverse lookup name converted to IP
|
||
FALSE -- if not IP4 reverse lookup name
|
||
|
||
--*/
|
||
{
|
||
CHAR nameBuffer[ DNS_MAX_IP4_REVERSE_NAME_BUFFER_LENGTH+1 ];
|
||
DWORD bufLength;
|
||
DWORD nameLengthUtf8;
|
||
|
||
|
||
DNSDBG( TRACE, (
|
||
"Dns_Ip4ReverseNameToAddress_W( %S )\n",
|
||
pwsName ));
|
||
|
||
//
|
||
// convert to UTF8
|
||
// - use UTF8 since conversion to it is trivial and it
|
||
// is identical to ANSI for all reverse lookup names
|
||
//
|
||
|
||
bufLength = DNS_MAX_IP4_REVERSE_NAME_BUFFER_LENGTH + 1;
|
||
|
||
nameLengthUtf8 = Dns_StringCopy(
|
||
nameBuffer,
|
||
& bufLength,
|
||
(PCHAR) pwsName,
|
||
0, // NULL terminated
|
||
DnsCharSetUnicode,
|
||
DnsCharSetUtf8 );
|
||
if ( nameLengthUtf8 == 0 )
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// call ANSI routine to do conversion
|
||
//
|
||
|
||
return Dns_Ip4ReverseNameToAddress_A(
|
||
pIp4Addr,
|
||
(PCSTR) nameBuffer );
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// Reverse name-to-address -- IP6
|
||
//
|
||
|
||
BOOL
|
||
Dns_Ip6ReverseNameToAddress_A(
|
||
OUT PIP6_ADDRESS pIp6Addr,
|
||
IN PCSTR pszName
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Get IP6 address for reverse lookup name.
|
||
|
||
Arguments:
|
||
|
||
pIp6Addr -- addr to receive IP address if found
|
||
|
||
pszName -- name to lookup
|
||
|
||
Return Value:
|
||
|
||
TRUE -- if reverse lookup name converted to IP
|
||
FALSE -- if not IP4 reverse lookup name
|
||
|
||
--*/
|
||
{
|
||
#define SIZE_IP6REV (sizeof(".ip6.int")-1)
|
||
|
||
CHAR nameBuffer[ DNS_MAX_IP6_REVERSE_NAME_BUFFER_LENGTH+1 ];
|
||
DWORD nameLength;
|
||
PCHAR pch;
|
||
BYTE byteArray[16];
|
||
DWORD byteCount;
|
||
DWORD nibble;
|
||
DWORD highNibble;
|
||
BOOL fisLow;
|
||
|
||
DNSDBG( TRACE, ( "Dns_Ip6ReverseNameToAddress_A()\n" ));
|
||
|
||
//
|
||
// validate name
|
||
// fail if
|
||
// - too long
|
||
// - too short
|
||
// - not in in6.int domain
|
||
//
|
||
|
||
nameLength = strlen( pszName );
|
||
|
||
if ( nameLength > DNS_MAX_IP6_REVERSE_NAME_BUFFER_LENGTH )
|
||
{
|
||
return( FALSE );
|
||
}
|
||
if ( pszName[nameLength-1] == '.' )
|
||
{
|
||
nameLength--;
|
||
}
|
||
if ( nameLength <= SIZE_IP6REV )
|
||
{
|
||
return( FALSE );
|
||
}
|
||
nameLength -= SIZE_IP6REV;
|
||
|
||
if ( _strnicmp( ".ip6.int", &pszName[nameLength], SIZE_IP6REV ) != 0 )
|
||
{
|
||
return( FALSE );
|
||
}
|
||
|
||
//
|
||
// copy name
|
||
//
|
||
|
||
RtlCopyMemory(
|
||
nameBuffer,
|
||
pszName,
|
||
nameLength );
|
||
|
||
nameBuffer[nameLength] = 0;
|
||
|
||
//
|
||
// clear IP6 address
|
||
// - need for partial reverse lookup name
|
||
//
|
||
|
||
RtlZeroMemory(
|
||
byteArray,
|
||
sizeof(byteArray) );
|
||
|
||
//
|
||
// read digits
|
||
//
|
||
|
||
byteCount = 0;
|
||
fisLow = FALSE;
|
||
|
||
pch = nameBuffer + nameLength;
|
||
|
||
while ( 1 )
|
||
{
|
||
if ( byteCount > 15 )
|
||
{
|
||
return( FALSE );
|
||
}
|
||
|
||
--pch;
|
||
|
||
if ( *pch == '.' )
|
||
{
|
||
*pch = 0;
|
||
pch++;
|
||
}
|
||
else if ( pch == nameBuffer )
|
||
{
|
||
}
|
||
else
|
||
{
|
||
// DCR: multi-digit nibbles in reverse name -- error?
|
||
continue;
|
||
}
|
||
|
||
// convert nibble
|
||
// - zero test special as
|
||
// A) faster
|
||
// B) strtoul() uses for error case
|
||
|
||
if ( *pch == '0' )
|
||
{
|
||
nibble = 0;
|
||
}
|
||
else
|
||
{
|
||
nibble = strtoul( pch, NULL, 16 );
|
||
if ( nibble == 0 || nibble > 15 )
|
||
{
|
||
return( FALSE );
|
||
}
|
||
}
|
||
|
||
// save high nibble
|
||
// on low nibble, write byte to IP6 address
|
||
|
||
if ( !fisLow )
|
||
{
|
||
highNibble = nibble;
|
||
fisLow = TRUE;
|
||
}
|
||
else
|
||
{
|
||
//byteArray[byteCount++] = (BYTE) (lowNibble | (nibble << 4));
|
||
|
||
pIp6Addr->IP6Byte[byteCount++] = (BYTE) ( (highNibble<<4) | nibble );
|
||
fisLow = FALSE;
|
||
}
|
||
|
||
// terminate at string beginning
|
||
// or continue back up string
|
||
|
||
if ( pch == nameBuffer )
|
||
{
|
||
break;
|
||
}
|
||
pch--;
|
||
}
|
||
|
||
//*pIp6Addr = *(PIP6_ADDRESS) byteArray;
|
||
|
||
DNSDBG( TRACE, (
|
||
"Success on Dns_Ip6ReverseNameToAddress_A( %s )\n",
|
||
pszName ));
|
||
|
||
return( TRUE );
|
||
}
|
||
|
||
|
||
|
||
BOOL
|
||
Dns_Ip6ReverseNameToAddress_W(
|
||
OUT PIP6_ADDRESS pIp6Addr,
|
||
IN PCWSTR pwsName
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Get IP for reverse lookup name.
|
||
|
||
Arguments:
|
||
|
||
pIp6Addr -- addr to receive IP address if found
|
||
|
||
pszName -- name to lookup
|
||
|
||
Return Value:
|
||
|
||
TRUE -- if reverse lookup name converted to IP
|
||
FALSE -- if not IP6 reverse lookup name
|
||
|
||
--*/
|
||
{
|
||
CHAR nameBuffer[ DNS_MAX_IP6_REVERSE_NAME_BUFFER_LENGTH+1 ];
|
||
DWORD bufLength;
|
||
DWORD nameLengthUtf8;
|
||
|
||
|
||
DNSDBG( TRACE, (
|
||
"Dns_Ip6ReverseNameToAddress_W( %S )\n",
|
||
pwsName ));
|
||
|
||
//
|
||
// convert to UTF8
|
||
// - use UTF8 since conversion to it is trivial and it
|
||
// is identical to ANSI for all reverse lookup names
|
||
//
|
||
|
||
bufLength = DNS_MAX_IP6_REVERSE_NAME_BUFFER_LENGTH + 1;
|
||
|
||
nameLengthUtf8 = Dns_StringCopy(
|
||
nameBuffer,
|
||
& bufLength,
|
||
(PCHAR) pwsName,
|
||
0, // NULL terminated
|
||
DnsCharSetUnicode,
|
||
DnsCharSetUtf8 );
|
||
if ( nameLengthUtf8 == 0 )
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// call ANSI routine to do conversion
|
||
//
|
||
|
||
return Dns_Ip6ReverseNameToAddress_A(
|
||
pIp6Addr,
|
||
(PCSTR) nameBuffer );
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// Combined IP4/IP6 reverse-name-to-address
|
||
//
|
||
|
||
BOOL
|
||
Dns_ReverseNameToAddress_W(
|
||
OUT PCHAR pAddrBuf,
|
||
IN OUT PDWORD pBufLength,
|
||
IN PCWSTR pString,
|
||
IN OUT PDWORD pAddrFamily
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Build address (IP4 or IP6) from reverse lookup name.
|
||
|
||
Arguments:
|
||
|
||
pAddrBuf -- buffer to receive address
|
||
|
||
pBufLength -- ptr to address length
|
||
input - length of buffer
|
||
output - length of address found
|
||
|
||
pString -- address string
|
||
|
||
pAddrFamily -- ptr to address family
|
||
input - zero for any family or particular family to check
|
||
output - family found; zero if no conversion
|
||
|
||
Return Value:
|
||
|
||
TRUE if successful.
|
||
FALSE on error. GetLastError() for status.
|
||
|
||
--*/
|
||
{
|
||
return Dns_StringToAddressEx(
|
||
pAddrBuf,
|
||
pBufLength,
|
||
(PCSTR) pString,
|
||
pAddrFamily,
|
||
TRUE, // unicode
|
||
TRUE // reverse
|
||
);
|
||
}
|
||
|
||
BOOL
|
||
Dns_ReverseNameToAddress_A(
|
||
OUT PCHAR pAddrBuf,
|
||
IN OUT PDWORD pBufLength,
|
||
IN PCSTR pString,
|
||
IN OUT PDWORD pAddrFamily
|
||
)
|
||
{
|
||
return Dns_StringToAddressEx(
|
||
pAddrBuf,
|
||
pBufLength,
|
||
pString,
|
||
pAddrFamily,
|
||
FALSE, // ANSI
|
||
TRUE // reverse
|
||
);
|
||
}
|
||
|
||
|
||
|
||
|
||
//
|
||
// Combined string-to-address private workhorse
|
||
//
|
||
|
||
BOOL
|
||
Dns_StringToAddressEx(
|
||
OUT PCHAR pAddrBuf,
|
||
IN OUT PDWORD pBufLength,
|
||
IN PCSTR pString,
|
||
IN OUT PDWORD pAddrFamily,
|
||
IN BOOL fUnicode,
|
||
IN BOOL fReverse
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Build address (IP4 or IP6 from string)
|
||
|
||
This routine is capable of all string-to-address
|
||
conversions and is the backbone of all the
|
||
combined string-to-address conversion routines.
|
||
|
||
Arguments:
|
||
|
||
pAddrBuf -- buffer to receive address
|
||
|
||
pBufLength -- ptr to address length
|
||
input - length of buffer
|
||
output - length of address found
|
||
|
||
pString -- address string
|
||
|
||
pAddrFamily -- ptr to address family
|
||
input - zero for any family or particular family to check
|
||
output - family found; zero if no conversion
|
||
|
||
fUnicode -- unicode string
|
||
|
||
fReverse -- reverse lookup string
|
||
|
||
Return Value:
|
||
|
||
TRUE if successful.
|
||
FALSE on error.
|
||
|
||
--*/
|
||
{
|
||
DNS_STATUS status = NO_ERROR;
|
||
DWORD length = 0;
|
||
INT family = *pAddrFamily;
|
||
DWORD bufLength = *pBufLength;
|
||
BOOL fconvert;
|
||
PCSTR preverseString;
|
||
CHAR nameBuffer[ DNS_MAX_REVERSE_NAME_BUFFER_LENGTH+1 ];
|
||
|
||
DNSDBG( TRACE, (
|
||
"Dns_StringToAddressEx( %S%s )\n",
|
||
fUnicode ? pString : "",
|
||
fUnicode ? "" : pString ));
|
||
|
||
//
|
||
// convert reverse to ANSI
|
||
//
|
||
// reverse lookups are done in ANSI; convert here to avoid
|
||
// double string conversion to check both IP4 and IP6
|
||
//
|
||
|
||
if ( fReverse )
|
||
{
|
||
preverseString = pString;
|
||
|
||
if ( fUnicode )
|
||
{
|
||
DWORD bufLength = DNS_MAX_REVERSE_NAME_BUFFER_LENGTH;
|
||
|
||
if ( ! Dns_StringCopy(
|
||
nameBuffer,
|
||
& bufLength,
|
||
(PCHAR) pString,
|
||
0, // NULL terminated
|
||
DnsCharSetUnicode,
|
||
DnsCharSetUtf8 ) )
|
||
{
|
||
return FALSE;
|
||
}
|
||
preverseString = nameBuffer;
|
||
}
|
||
}
|
||
|
||
//
|
||
// check IP4
|
||
//
|
||
|
||
if ( family == 0 ||
|
||
family == AF_INET )
|
||
{
|
||
IP4_ADDRESS ip;
|
||
|
||
if ( fReverse )
|
||
{
|
||
fconvert = Dns_Ip4ReverseNameToAddress_A(
|
||
& ip,
|
||
preverseString );
|
||
}
|
||
else
|
||
{
|
||
if ( fUnicode )
|
||
{
|
||
fconvert = Dns_Ip4StringToAddress_W(
|
||
& ip,
|
||
(PCWSTR)pString );
|
||
}
|
||
else
|
||
{
|
||
fconvert = Dns_Ip4StringToAddress_A(
|
||
& ip,
|
||
pString );
|
||
}
|
||
}
|
||
if ( fconvert )
|
||
{
|
||
length = sizeof(IP4_ADDRESS);
|
||
family = AF_INET;
|
||
|
||
if ( bufLength < length )
|
||
{
|
||
status = ERROR_MORE_DATA;
|
||
}
|
||
else
|
||
{
|
||
* (PIP4_ADDRESS) pAddrBuf = ip;
|
||
}
|
||
|
||
DNSDBG( INIT2, (
|
||
"Converted string to IP4 address %s\n",
|
||
IP_STRING(ip) ));
|
||
goto Done;
|
||
}
|
||
}
|
||
|
||
//
|
||
// check IP6
|
||
//
|
||
|
||
if ( family == 0 ||
|
||
family == AF_INET6 )
|
||
{
|
||
IP6_ADDRESS ip;
|
||
|
||
if ( fReverse )
|
||
{
|
||
fconvert = Dns_Ip6ReverseNameToAddress_A(
|
||
& ip,
|
||
preverseString );
|
||
}
|
||
else
|
||
{
|
||
if ( fUnicode )
|
||
{
|
||
fconvert = Dns_Ip6StringToAddress_W(
|
||
& ip,
|
||
(PCWSTR)pString );
|
||
}
|
||
else
|
||
{
|
||
fconvert = Dns_Ip6StringToAddress_A(
|
||
& ip,
|
||
pString );
|
||
}
|
||
}
|
||
if ( fconvert )
|
||
{
|
||
length = sizeof(IP6_ADDRESS);
|
||
|
||
if ( bufLength < length )
|
||
{
|
||
status = ERROR_MORE_DATA;
|
||
}
|
||
else
|
||
{
|
||
family = AF_INET6;
|
||
* (PIP6_ADDRESS) pAddrBuf = ip;
|
||
}
|
||
|
||
IF_DNSDBG( INIT2 )
|
||
{
|
||
DnsDbg_Ip6Address(
|
||
"Converted string to IP6 address: ",
|
||
(PIP6_ADDRESS) pAddrBuf,
|
||
"\n" );
|
||
}
|
||
goto Done;
|
||
}
|
||
}
|
||
|
||
length = 0;
|
||
family = 0;
|
||
status = DNS_ERROR_INVALID_IP_ADDRESS;
|
||
|
||
Done:
|
||
|
||
if ( status )
|
||
{
|
||
SetLastError( status );
|
||
}
|
||
|
||
*pAddrFamily = family;
|
||
*pBufLength = length;
|
||
|
||
DNSDBG( TRACE, (
|
||
"Leave Dns_StringToAddressEx()\n"
|
||
"\tstatus = %d\n"
|
||
"\tptr = %p\n"
|
||
"\tlength = %d\n"
|
||
"\tfamily = %d\n",
|
||
status,
|
||
pAddrBuf,
|
||
length,
|
||
family ));
|
||
|
||
return( status==ERROR_SUCCESS );
|
||
}
|
||
|
||
|
||
//
|
||
// End straddr.c
|
||
//
|