You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1338 lines
26 KiB
1338 lines
26 KiB
/*++
|
|
|
|
Copyright (c) 1996-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
rralloc.c
|
|
|
|
Abstract:
|
|
|
|
Domain Name System (DNS) Library
|
|
|
|
Resource record allocation \ creation routines.
|
|
|
|
Author:
|
|
|
|
Jim Gilroy (jamesg) January, 1997
|
|
|
|
Environment:
|
|
|
|
User Mode - Win32
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "local.h"
|
|
|
|
#define SET_FLAGS(Flags, value) \
|
|
( *(PWORD)&(Flags) = value )
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
WINAPI
|
|
Dns_AllocateRecord(
|
|
IN WORD wBufferLength
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Allocate record structure.
|
|
|
|
Arguments:
|
|
|
|
wBufferLength - desired buffer length (beyond structure header)
|
|
|
|
Return Value:
|
|
|
|
Ptr to message buffer.
|
|
NULL on error.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD prr;
|
|
|
|
prr = ALLOCATE_HEAP( SIZEOF_DNS_RECORD_HEADER + wBufferLength );
|
|
if ( prr == NULL )
|
|
{
|
|
SetLastError( DNS_ERROR_NO_MEMORY );
|
|
return( NULL );
|
|
}
|
|
RtlZeroMemory(
|
|
prr,
|
|
SIZEOF_DNS_RECORD_HEADER );
|
|
|
|
// as first cut, set datalength to buffer length
|
|
|
|
prr->wDataLength = wBufferLength;
|
|
return( prr );
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
WINAPI
|
|
Dns_RecordFree(
|
|
IN OUT PDNS_RECORD pRecord
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Free a record
|
|
|
|
Arguments:
|
|
|
|
pRecord -- record list to free
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
DNSDBG( HEAP, ( "Dns_RecordFree( %p )\n", pRecord ));
|
|
|
|
// handle NULL for convenience
|
|
|
|
if ( !pRecord )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// free owner name?
|
|
|
|
if ( FLAG_FreeOwner( pRecord ) )
|
|
{
|
|
FREE_HEAP( pRecord->pName );
|
|
}
|
|
|
|
//
|
|
// free data -- but only if flag set
|
|
//
|
|
// note: even if we fix copy functions to do atomic
|
|
// allocations, we'll still have to have free to
|
|
// handle RPC allocations
|
|
// (unless we very cleverly, treated RPC as flat blob, then
|
|
// did fix up (to offsets before and afterward)
|
|
//
|
|
|
|
if ( FLAG_FreeData( pRecord ) )
|
|
{
|
|
switch( pRecord->wType )
|
|
{
|
|
case DNS_TYPE_A:
|
|
break;
|
|
|
|
case DNS_TYPE_PTR:
|
|
case DNS_TYPE_NS:
|
|
case DNS_TYPE_CNAME:
|
|
case DNS_TYPE_MB:
|
|
case DNS_TYPE_MD:
|
|
case DNS_TYPE_MF:
|
|
case DNS_TYPE_MG:
|
|
case DNS_TYPE_MR:
|
|
|
|
if ( pRecord->Data.PTR.pNameHost )
|
|
{
|
|
FREE_HEAP( pRecord->Data.PTR.pNameHost );
|
|
}
|
|
break;
|
|
|
|
case DNS_TYPE_SOA:
|
|
|
|
if ( pRecord->Data.SOA.pNamePrimaryServer )
|
|
{
|
|
FREE_HEAP( pRecord->Data.SOA.pNamePrimaryServer );
|
|
}
|
|
if ( pRecord->Data.SOA.pNameAdministrator )
|
|
{
|
|
FREE_HEAP( pRecord->Data.SOA.pNameAdministrator );
|
|
}
|
|
break;
|
|
|
|
case DNS_TYPE_MINFO:
|
|
case DNS_TYPE_RP:
|
|
|
|
if ( pRecord->Data.MINFO.pNameMailbox )
|
|
{
|
|
FREE_HEAP( pRecord->Data.MINFO.pNameMailbox );
|
|
}
|
|
if ( pRecord->Data.MINFO.pNameErrorsMailbox )
|
|
{
|
|
FREE_HEAP( pRecord->Data.MINFO.pNameErrorsMailbox );
|
|
}
|
|
break;
|
|
|
|
case DNS_TYPE_MX:
|
|
case DNS_TYPE_AFSDB:
|
|
case DNS_TYPE_RT:
|
|
|
|
if ( pRecord->Data.MX.pNameExchange )
|
|
{
|
|
FREE_HEAP( pRecord->Data.MX.pNameExchange );
|
|
}
|
|
break;
|
|
|
|
case DNS_TYPE_HINFO:
|
|
case DNS_TYPE_ISDN:
|
|
case DNS_TYPE_TEXT:
|
|
case DNS_TYPE_X25:
|
|
|
|
{
|
|
DWORD iter;
|
|
DWORD count = pRecord->Data.TXT.dwStringCount;
|
|
|
|
for ( iter = 0; iter < count; iter++ )
|
|
{
|
|
if ( pRecord->Data.TXT.pStringArray[iter] )
|
|
{
|
|
FREE_HEAP( pRecord->Data.TXT.pStringArray[iter] );
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case DNS_TYPE_SRV:
|
|
|
|
if ( pRecord->Data.SRV.pNameTarget )
|
|
{
|
|
FREE_HEAP( pRecord->Data.SRV.pNameTarget );
|
|
}
|
|
break;
|
|
|
|
case DNS_TYPE_WINSR:
|
|
|
|
if ( pRecord->Data.WINSR.pNameResultDomain )
|
|
{
|
|
FREE_HEAP( pRecord->Data.WINSR.pNameResultDomain );
|
|
}
|
|
break;
|
|
|
|
default:
|
|
|
|
// other types -- A, AAAA, ATMA, WINS, NULL,
|
|
// have no internal pointers
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
// for catching heap problems
|
|
|
|
pRecord->pNext = DNS_BAD_PTR;
|
|
pRecord->pName = DNS_BAD_PTR;
|
|
|
|
FREE_HEAP( pRecord );
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
WINAPI
|
|
Dns_RecordListFree(
|
|
IN OUT PDNS_RECORD pRecord
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Free list of records.
|
|
|
|
Arguments:
|
|
|
|
pRecord -- record list to free
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD pnext;
|
|
|
|
DNSDBG( TRACE, (
|
|
"Dns_RecordListFree( %p )\n",
|
|
pRecord ));
|
|
|
|
//
|
|
// loop through and free every RR in list
|
|
//
|
|
|
|
while ( pRecord )
|
|
{
|
|
pnext = pRecord->pNext;
|
|
|
|
Dns_RecordFree( pRecord );
|
|
|
|
pRecord = pnext;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
WINAPI
|
|
Dns_RecordListFreeEx(
|
|
IN OUT PDNS_RECORD pRecord,
|
|
IN BOOL fFreeOwner
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Free list of records.
|
|
|
|
DCR: RecordListFreeEx (no free owner option) is probably useless
|
|
|
|
Note: owner name is freed ONLY when indicated by flag;
|
|
other ptrs are considered to be either
|
|
1) internal as when records read from wire or copied
|
|
2) external and to be freed by record creator
|
|
|
|
Arguments:
|
|
|
|
pRecord -- record list to free
|
|
|
|
fFreeOwner -- flag indicating owner name should be freed
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD pnext;
|
|
|
|
DNSDBG( TRACE, (
|
|
"Dns_RecordListFreeEx( %p, %d )\n",
|
|
pRecord,
|
|
fFreeOwner ));
|
|
|
|
//
|
|
// loop through and free every RR in list
|
|
//
|
|
|
|
while ( pRecord )
|
|
{
|
|
pnext = pRecord->pNext;
|
|
|
|
// free owner name?
|
|
// - if "FreeOwner" flag NOT set, then don't free
|
|
|
|
if ( !fFreeOwner )
|
|
{
|
|
FLAG_FreeOwner( pRecord ) = FALSE;
|
|
}
|
|
|
|
// free record
|
|
|
|
Dns_RecordFree( pRecord );
|
|
|
|
pRecord = pnext;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Special record type creation routines
|
|
//
|
|
|
|
PDNS_RECORD
|
|
CreateRecordBasic(
|
|
IN PDNS_NAME pOwnerName,
|
|
IN BOOL fCopyName,
|
|
IN WORD wType,
|
|
IN WORD wDataLength,
|
|
IN DWORD AllocLength,
|
|
IN DWORD Ttl,
|
|
IN DNS_CHARSET NameCharSet,
|
|
IN DNS_CHARSET RecordCharSet
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create record of arbitary type.
|
|
|
|
Helper function to wrap up
|
|
- record alloc
|
|
- name alloc
|
|
- basic setup
|
|
|
|
Arguments:
|
|
|
|
pOwnerName -- owner name
|
|
|
|
fCopyName -- TRUE - make copy of owner name
|
|
FALSE - use directly
|
|
|
|
wType -- type
|
|
|
|
AllocLength -- allocaction length, including any imbedded data
|
|
|
|
wDataLength -- data length to set
|
|
|
|
Ttl -- TTL
|
|
|
|
NameCharSet -- character set of name
|
|
|
|
RecordCharSet -- character set for resulting record
|
|
|
|
Return Value:
|
|
|
|
Ptr to PTR record.
|
|
NULL on error.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
PDNS_RECORD prr;
|
|
PCHAR pname;
|
|
DWORD bufLength;
|
|
|
|
//
|
|
// alloc record
|
|
//
|
|
|
|
prr = Dns_AllocateRecord( (WORD)AllocLength );
|
|
if ( !prr )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// copy owner name
|
|
//
|
|
|
|
if ( fCopyName && pOwnerName )
|
|
{
|
|
pname = Dns_NameCopyAllocate(
|
|
pOwnerName,
|
|
0, // length unknown
|
|
NameCharSet,
|
|
RecordCharSet );
|
|
if ( !pname )
|
|
{
|
|
FREE_HEAP( prr );
|
|
return( NULL );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pname = pOwnerName;
|
|
}
|
|
|
|
//
|
|
// set fields
|
|
// - name, type and charset
|
|
// - TTL, section left zero
|
|
// - FreeData is specifically off
|
|
//
|
|
|
|
prr->pName = pname;
|
|
prr->wType = wType;
|
|
prr->wDataLength = wDataLength;
|
|
SET_FREE_OWNER(prr);
|
|
prr->Flags.S.CharSet = RecordCharSet;
|
|
prr->dwTtl = Ttl;
|
|
|
|
return( prr );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Dns_CreateFlatRecord(
|
|
IN PDNS_NAME pOwnerName,
|
|
IN WORD wType,
|
|
IN PCHAR pData,
|
|
IN DWORD DataLength,
|
|
IN DWORD Ttl,
|
|
IN DNS_CHARSET NameCharSet,
|
|
IN DNS_CHARSET RecordCharSet
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create flat record.
|
|
|
|
Arguments:
|
|
|
|
pOwnerName -- owner name
|
|
|
|
wType -- record type
|
|
|
|
pData -- ptr to data for record
|
|
|
|
DataLength -- length (in bytes) of data
|
|
|
|
Ttl -- TTL
|
|
|
|
NameCharSet -- character set of name
|
|
|
|
RecordCharSet -- character set for resulting record
|
|
|
|
Return Value:
|
|
|
|
Ptr to PTR record.
|
|
NULL on error.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD prr;
|
|
|
|
//
|
|
// determine record size
|
|
// - record buffer will include hostname
|
|
//
|
|
|
|
prr = CreateRecordBasic(
|
|
pOwnerName,
|
|
TRUE, // copy name
|
|
wType,
|
|
(WORD) DataLength, // datalength
|
|
DataLength, // alloc datalength
|
|
Ttl,
|
|
NameCharSet,
|
|
RecordCharSet );
|
|
if ( !prr )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// copy in data
|
|
//
|
|
|
|
RtlCopyMemory(
|
|
(PBYTE) &prr->Data,
|
|
pData,
|
|
DataLength );
|
|
|
|
return( prr );
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Reverse record creation
|
|
//
|
|
|
|
PDNS_RECORD
|
|
Dns_CreatePtrTypeRecord(
|
|
IN PDNS_NAME pOwnerName,
|
|
IN BOOL fCopyName,
|
|
IN PDNS_NAME pTargetName,
|
|
IN WORD wType,
|
|
IN DWORD Ttl,
|
|
IN DNS_CHARSET NameCharSet,
|
|
IN DNS_CHARSET RecordCharSet
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create PTR type (single-indirection) record.
|
|
|
|
This can be used to create any "PTR-type" record:
|
|
PTR, CNAME, NS, etc.
|
|
|
|
Arguments:
|
|
|
|
pOwnerName -- owner name
|
|
|
|
fCopyName -- TRUE - make copy of owner name
|
|
FALSE - use directly
|
|
|
|
pTargetName -- target name
|
|
|
|
Ttl -- TTL
|
|
|
|
NameCharSet -- character set of name
|
|
|
|
RecordCharSet -- character set for resulting record
|
|
|
|
Return Value:
|
|
|
|
Ptr to PTR record.
|
|
NULL on error.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
PDNS_RECORD prr;
|
|
PCHAR pname;
|
|
DWORD bufLength;
|
|
|
|
//
|
|
// determine record size
|
|
// - record buffer will include hostname
|
|
//
|
|
|
|
bufLength = Dns_GetBufferLengthForNameCopy(
|
|
pTargetName,
|
|
0, // length unknown
|
|
NameCharSet,
|
|
RecordCharSet );
|
|
if ( !bufLength )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// create record
|
|
//
|
|
|
|
prr = CreateRecordBasic(
|
|
pOwnerName,
|
|
fCopyName,
|
|
wType,
|
|
sizeof(DNS_PTR_DATA), // data length
|
|
(sizeof(DNS_PTR_DATA) + bufLength), // alloc length
|
|
Ttl,
|
|
NameCharSet,
|
|
RecordCharSet );
|
|
if ( !prr )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// write target name into buffer, immediately following PTR data struct
|
|
//
|
|
|
|
prr->Data.PTR.pNameHost = (PCHAR)&prr->Data + sizeof(DNS_PTR_DATA);
|
|
|
|
Dns_NameCopy(
|
|
prr->Data.PTR.pNameHost,
|
|
NULL,
|
|
pTargetName,
|
|
0,
|
|
NameCharSet,
|
|
RecordCharSet
|
|
);
|
|
|
|
return( prr );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Dns_CreatePtrRecordEx(
|
|
IN PDNS_ADDR pAddr,
|
|
IN PDNS_NAME pszHostName,
|
|
IN DWORD Ttl,
|
|
IN DNS_CHARSET NameCharSet,
|
|
IN DNS_CHARSET RecordCharSet
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create PTR record from IP address and hostname.
|
|
|
|
Arguments:
|
|
|
|
pAddr -- addr (IP4 or IP6) to map into PTR
|
|
|
|
pszHostName -- host name, FULL FQDN
|
|
|
|
Ttl -- TTL
|
|
|
|
NameCharSet -- character set of name
|
|
|
|
RecordCharSet -- character set for resulting record
|
|
|
|
Return Value:
|
|
|
|
Ptr to PTR record.
|
|
NULL on error.
|
|
|
|
--*/
|
|
{
|
|
PCHAR pname = NULL;
|
|
DWORD family;
|
|
|
|
//
|
|
// create reverse lookup name
|
|
// - note this is external allocation
|
|
//
|
|
|
|
family = DnsAddr_Family( pAddr );
|
|
|
|
if ( family == AF_INET )
|
|
{
|
|
IP4_ADDRESS ip = DnsAddr_GetIp4(pAddr);
|
|
|
|
if ( RecordCharSet == DnsCharSetUnicode )
|
|
{
|
|
pname = (PCHAR) Dns_Ip4AddressToReverseNameAlloc_W( ip );
|
|
}
|
|
else
|
|
{
|
|
pname = Dns_Ip4AddressToReverseNameAlloc_A( ip );
|
|
}
|
|
}
|
|
else if ( family == AF_INET6 )
|
|
{
|
|
PIP6_ADDRESS p6 = DnsAddr_GetIp6Ptr(pAddr);
|
|
|
|
if ( RecordCharSet == DnsCharSetUnicode )
|
|
{
|
|
pname = (PCHAR) Dns_Ip6AddressToReverseNameAlloc_W( *p6 );
|
|
}
|
|
else
|
|
{
|
|
pname = Dns_Ip6AddressToReverseNameAlloc_A( *p6 );
|
|
}
|
|
}
|
|
|
|
if ( !pname )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// build record
|
|
//
|
|
|
|
return Dns_CreatePtrTypeRecord(
|
|
pname,
|
|
FALSE, // don't copy IP
|
|
pszHostName, // target name
|
|
DNS_TYPE_PTR,
|
|
Ttl,
|
|
NameCharSet,
|
|
RecordCharSet );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Dns_CreatePtrRecordExEx(
|
|
IN PDNS_ADDR pAddr,
|
|
IN PSTR pszHostName,
|
|
IN PSTR pszDomainName,
|
|
IN DWORD Ttl,
|
|
IN DNS_CHARSET NameCharSet,
|
|
IN DNS_CHARSET RecordCharSet
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create PTR record from hostname and domain name.
|
|
|
|
Helper function for DHCP registrations when hostname
|
|
and domain name are separate and both required.
|
|
|
|
Arguments:
|
|
|
|
pAddr -- addr (IP4 or IP6) to map into PTR
|
|
|
|
pszHostName -- host name (single label)
|
|
|
|
pszDomainName -- domain name
|
|
|
|
Ttl -- TTL
|
|
|
|
NameCharSet -- character set of name
|
|
|
|
RecordCharSet -- character set for resulting record
|
|
|
|
Return Value:
|
|
|
|
Ptr to PTR record.
|
|
NULL on error.
|
|
|
|
--*/
|
|
{
|
|
WCHAR nameBuffer[ DNS_MAX_NAME_BUFFER_LENGTH ];
|
|
|
|
DNSDBG( TRACE, (
|
|
"Dns_CreatePtrRecordExEx()\n" ));
|
|
|
|
//
|
|
// build appended name
|
|
//
|
|
// DCR: could require just host name and check that
|
|
// either domain exists or hostname is full
|
|
//
|
|
|
|
if ( !pszHostName || !pszDomainName )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if ( NameCharSet != DnsCharSetUnicode )
|
|
{
|
|
if ( ! Dns_NameAppend_A(
|
|
(PCHAR) nameBuffer,
|
|
DNS_MAX_NAME_BUFFER_LENGTH,
|
|
pszHostName,
|
|
pszDomainName ) )
|
|
{
|
|
DNS_ASSERT( FALSE );
|
|
return NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( ! Dns_NameAppend_W(
|
|
(PWCHAR) nameBuffer,
|
|
DNS_MAX_NAME_BUFFER_LENGTH,
|
|
(PWSTR) pszHostName,
|
|
(PWSTR) pszDomainName ) )
|
|
{
|
|
DNS_ASSERT( FALSE );
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
//
|
|
// build record
|
|
//
|
|
|
|
return Dns_CreatePtrRecordEx(
|
|
pAddr,
|
|
(PCHAR) nameBuffer,
|
|
Ttl,
|
|
NameCharSet,
|
|
RecordCharSet
|
|
);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Forward record creation
|
|
//
|
|
|
|
PDNS_RECORD
|
|
Dns_CreateARecord(
|
|
IN PDNS_NAME pOwnerName,
|
|
IN IP4_ADDRESS Ip4Addr,
|
|
IN DWORD Ttl,
|
|
IN DNS_CHARSET NameCharSet,
|
|
IN DNS_CHARSET RecordCharSet
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create A record.
|
|
|
|
Arguments:
|
|
|
|
pOwnerName -- owner name
|
|
|
|
Ip4Addr -- IP address
|
|
|
|
Ttl -- TTL
|
|
|
|
NameCharSet -- character set of name
|
|
|
|
RecordCharSet -- character set for resulting record
|
|
|
|
Return Value:
|
|
|
|
Ptr to PTR record.
|
|
NULL on error.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD prr;
|
|
|
|
//
|
|
// determine record size
|
|
// - record buffer will include hostname
|
|
//
|
|
|
|
prr = CreateRecordBasic(
|
|
pOwnerName,
|
|
TRUE, // copy name
|
|
DNS_TYPE_A,
|
|
sizeof(DNS_A_DATA),
|
|
sizeof(DNS_A_DATA),
|
|
Ttl,
|
|
NameCharSet,
|
|
RecordCharSet );
|
|
if ( !prr )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// set IP
|
|
//
|
|
|
|
prr->Data.A.IpAddress = Ip4Addr;
|
|
|
|
return( prr );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Dns_CreateAAAARecord(
|
|
IN PDNS_NAME pOwnerName,
|
|
IN IP6_ADDRESS Ip6Addr,
|
|
IN DWORD Ttl,
|
|
IN DNS_CHARSET NameCharSet,
|
|
IN DNS_CHARSET RecordCharSet
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create A record.
|
|
|
|
Arguments:
|
|
|
|
pOwnerName -- owner name
|
|
|
|
Ip6Addr -- IP6 address
|
|
|
|
Ttl -- TTL
|
|
|
|
NameCharSet -- character set of name
|
|
|
|
RecordCharSet -- character set for resulting record
|
|
|
|
Return Value:
|
|
|
|
Ptr to PTR record.
|
|
NULL on error.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD prr;
|
|
|
|
//
|
|
// determine record size
|
|
// - record buffer will include hostname
|
|
//
|
|
|
|
prr = CreateRecordBasic(
|
|
pOwnerName,
|
|
TRUE, // copy name
|
|
DNS_TYPE_AAAA,
|
|
sizeof(DNS_AAAA_DATA),
|
|
sizeof(DNS_AAAA_DATA),
|
|
Ttl,
|
|
NameCharSet,
|
|
RecordCharSet );
|
|
if ( !prr )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// set IP
|
|
//
|
|
|
|
prr->Data.AAAA.Ip6Address = Ip6Addr;
|
|
|
|
return( prr );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Dns_CreateAAAARecordFromDnsAddr(
|
|
IN PDNS_NAME pOwnerName,
|
|
IN PDNS_ADDR pAddr,
|
|
IN DWORD Ttl,
|
|
IN DNS_CHARSET NameCharSet,
|
|
IN DNS_CHARSET RecordCharSet
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create A record.
|
|
|
|
Arguments:
|
|
|
|
pOwnerName -- owner name
|
|
|
|
pAddr -- Ptr to DNS_ADDR
|
|
|
|
Ttl -- TTL
|
|
|
|
NameCharSet -- character set of name
|
|
|
|
RecordCharSet -- character set for resulting record
|
|
|
|
Return Value:
|
|
|
|
Ptr to PTR record.
|
|
NULL on error.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD prr;
|
|
|
|
//
|
|
// determine record size
|
|
// - record buffer will include hostname
|
|
//
|
|
|
|
prr = Dns_CreateAAAARecord(
|
|
pOwnerName,
|
|
* (PIP6_ADDRESS) &pAddr->SockaddrIn6.sin6_addr,
|
|
Ttl,
|
|
NameCharSet,
|
|
RecordCharSet
|
|
);
|
|
if ( !prr )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// slap scope into reserved field
|
|
//
|
|
|
|
prr->dwReserved = pAddr->SockaddrIn6.sin6_scope_id;
|
|
|
|
return( prr );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Dns_CreateForwardRecord(
|
|
IN PDNS_NAME pOwnerName,
|
|
IN WORD wType, OPTIONAL
|
|
IN PDNS_ADDR pAddr,
|
|
IN DWORD Ttl,
|
|
IN DNS_CHARSET NameCharSet,
|
|
IN DNS_CHARSET RecordCharSet
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create forward lookup record.
|
|
|
|
This is just a shim to avoid duplicating selection logic.
|
|
|
|
Arguments:
|
|
|
|
pOwnerName -- owner name
|
|
|
|
wType -- type, if specified; zero for getting type from pAddr
|
|
|
|
pAddr -- ptr to DNS_ADDR
|
|
|
|
Ttl -- TTL
|
|
|
|
NameCharSet -- character set of name
|
|
|
|
RecordCharSet -- character set for resulting record
|
|
|
|
Return Value:
|
|
|
|
Ptr to PTR record.
|
|
NULL on error.
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// build desired type
|
|
//
|
|
|
|
if ( DnsAddr_IsIp4( pAddr ) )
|
|
{
|
|
if ( wType == 0 || wType == DNS_TYPE_A )
|
|
{
|
|
return Dns_CreateARecord(
|
|
pOwnerName,
|
|
DnsAddr_GetIp4( pAddr ),
|
|
Ttl,
|
|
NameCharSet,
|
|
RecordCharSet );
|
|
}
|
|
|
|
}
|
|
else if ( DnsAddr_IsIp6( pAddr ) )
|
|
{
|
|
if ( wType == 0 || wType == DNS_TYPE_AAAA )
|
|
{
|
|
return Dns_CreateAAAARecordFromDnsAddr(
|
|
pOwnerName,
|
|
pAddr,
|
|
Ttl,
|
|
NameCharSet,
|
|
RecordCharSet );
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Dns_CreateForwardRecordFromIp6(
|
|
IN PDNS_NAME pOwnerName,
|
|
IN PIP6_ADDRESS pIp,
|
|
IN DWORD Ttl,
|
|
IN DNS_CHARSET NameCharSet,
|
|
IN DNS_CHARSET RecordCharSet
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create forward lookup record.
|
|
|
|
This is just a shim to avoid duplicating selection logic.
|
|
|
|
Arguments:
|
|
|
|
pOwnerName -- owner name
|
|
|
|
pIp -- IP6 address
|
|
|
|
Ttl -- TTL
|
|
|
|
NameCharSet -- character set of name
|
|
|
|
RecordCharSet -- character set for resulting record
|
|
|
|
Return Value:
|
|
|
|
Ptr to PTR record.
|
|
NULL on error.
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// build desired type
|
|
//
|
|
|
|
if ( IP6_IS_ADDR_V4MAPPED( pIp ) )
|
|
{
|
|
return Dns_CreateARecord(
|
|
pOwnerName,
|
|
IP6_GET_V4_ADDR( pIp ),
|
|
Ttl,
|
|
NameCharSet,
|
|
RecordCharSet );
|
|
}
|
|
else
|
|
{
|
|
return Dns_CreateAAAARecord(
|
|
pOwnerName,
|
|
*pIp,
|
|
Ttl,
|
|
NameCharSet,
|
|
RecordCharSet );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Dns_CreateForwardRecordForSockaddr(
|
|
IN PDNS_NAME pOwnerName,
|
|
IN PSOCKADDR pSockaddr,
|
|
IN DWORD Ttl,
|
|
IN DNS_CHARSET NameCharSet,
|
|
IN DNS_CHARSET RecordCharSet
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create forward lookup record.
|
|
|
|
This is just a shim to avoid duplicating selection logic.
|
|
|
|
Arguments:
|
|
|
|
pOwnerName -- owner name
|
|
|
|
pSockaddr -- ptr to sockaddr
|
|
|
|
Ttl -- TTL
|
|
|
|
NameCharSet -- character set of name
|
|
|
|
RecordCharSet -- character set for resulting record
|
|
|
|
Return Value:
|
|
|
|
Ptr to PTR record.
|
|
NULL on error.
|
|
|
|
--*/
|
|
{
|
|
PFAMILY_INFO pinfo;
|
|
|
|
DNSDBG( TRACE, (
|
|
"Dns_CreateForwardRecordForSockaddr()\n" ));
|
|
|
|
pinfo = FamilyInfo_GetForSockaddr( pSockaddr );
|
|
if ( !pinfo )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// build flat record of desired type
|
|
//
|
|
|
|
return Dns_CreateFlatRecord(
|
|
pOwnerName,
|
|
pinfo->DnsType,
|
|
(PBYTE)pSockaddr + pinfo->OffsetToAddrInSockaddr,
|
|
pinfo->LengthAddr,
|
|
Ttl,
|
|
NameCharSet,
|
|
RecordCharSet );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Dns_CreateRecordForIpString_W(
|
|
IN PCWSTR pwsName,
|
|
IN WORD wType, OPTIONAL
|
|
IN DWORD Ttl
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create record for IP string query.
|
|
|
|
Arguments:
|
|
|
|
pwsName -- name that may be IP string query
|
|
|
|
wType -- type of query; OPTIONAL, if zero type
|
|
derived from string
|
|
|
|
Return Value:
|
|
|
|
Ptr to record for query, if query name\type is IP.
|
|
NULL if query not for IP.
|
|
|
|
--*/
|
|
{
|
|
DNS_ADDR addr;
|
|
PDNS_RECORD prr;
|
|
|
|
|
|
DNSDBG( TRACE, (
|
|
"\nDns_CreateRecordForIpString( %S, wType = %d )\n",
|
|
pwsName,
|
|
wType ));
|
|
|
|
if ( !pwsName )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// support A or AAAA queries for IP strings
|
|
// - IP4 strings must be in w.x.y.z form otherwise
|
|
// we convert the all numeric names also
|
|
//
|
|
|
|
if ( wType == DNS_TYPE_A ||
|
|
wType == 0 )
|
|
{
|
|
IP4_ADDRESS ip4;
|
|
PCWSTR pdot;
|
|
DWORD count;
|
|
|
|
if ( ! Dns_Ip4StringToAddress_W(
|
|
& ip4,
|
|
(PWSTR) pwsName ) )
|
|
{
|
|
goto Try6;
|
|
}
|
|
|
|
// verify three dot form w.x.y.z
|
|
|
|
pdot = pwsName;
|
|
count = 3;
|
|
while ( count-- )
|
|
{
|
|
pdot = wcschr( pdot, L'.' );
|
|
if ( !pdot || !*++pdot )
|
|
{
|
|
goto Try6;
|
|
}
|
|
}
|
|
|
|
DnsAddr_BuildFromIp4(
|
|
&addr,
|
|
ip4,
|
|
0 );
|
|
|
|
wType = DNS_TYPE_A;
|
|
goto Build;
|
|
}
|
|
|
|
Try6:
|
|
|
|
if ( wType == DNS_TYPE_AAAA ||
|
|
wType == 0 )
|
|
{
|
|
// this will convert any form,
|
|
// but set type==AAAA to fail record build if
|
|
// did NOT build IP6
|
|
|
|
if ( Dns_StringToDnsAddr_W(
|
|
& addr,
|
|
(PWSTR) pwsName ) )
|
|
{
|
|
wType = DNS_TYPE_AAAA;
|
|
goto Build;
|
|
}
|
|
}
|
|
|
|
return NULL; // no match
|
|
|
|
|
|
Build:
|
|
|
|
//
|
|
// name is IP string -- build record
|
|
//
|
|
|
|
prr = Dns_CreateForwardRecord(
|
|
(PDNS_NAME) pwsName,
|
|
wType,
|
|
& addr,
|
|
Ttl,
|
|
DnsCharSetUnicode,
|
|
DnsCharSetUnicode );
|
|
|
|
DNSDBG( TRACE, (
|
|
"Create record %p for IP string %S type %d.\n",
|
|
prr,
|
|
pwsName,
|
|
wType ));
|
|
|
|
return prr;
|
|
}
|
|
|
|
//
|
|
// End rralloc.c
|
|
//
|
|
|
|
|