1109 lines
24 KiB
C
1109 lines
24 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1998 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
dconvert.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Domain Name System (DNS) Server -- Admin Client Library
|
|||
|
|
|||
|
RPC record conversion routines.
|
|||
|
Convert DNS_RECORD records into RPC buffer.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Jing Chen (t-jingc) June, 1998
|
|||
|
reverse functions of rconvert.c
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
|
|||
|
#include "dnsclip.h"
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// size of string in RPC format
|
|||
|
//
|
|||
|
|
|||
|
#define STRING_UTF8_BUF_SIZE( string, fUnicode ) \
|
|||
|
Dns_GetBufferLengthForStringCopy( \
|
|||
|
(string), \
|
|||
|
0, \
|
|||
|
((fUnicode) ? DnsCharSetUnicode : DnsCharSetUtf8), \
|
|||
|
DnsCharSetUtf8 )
|
|||
|
#if 0
|
|||
|
// with comments
|
|||
|
Dns_GetBufferLengthForStringCopy( \
|
|||
|
(string), \ // string
|
|||
|
0, \ // unknown length
|
|||
|
((fUnicode) ? DnsCharSetUnicode : DnsCharSetUtf8), \ // in string
|
|||
|
DnsCharSetUtf8 ) // RPC string always UTF8
|
|||
|
#endif
|
|||
|
|
|||
|
//
|
|||
|
// Writing strings to RPC buffer format
|
|||
|
//
|
|||
|
|
|||
|
#define WRITE_STRING_TO_RPC_BUF(buf, psz, len, funicode) \
|
|||
|
Dns_StringCopy( \
|
|||
|
(buf), \
|
|||
|
NULL, \
|
|||
|
(psz), \
|
|||
|
(len), \
|
|||
|
((funicode) ? DnsCharSetUnicode : DnsCharSetUtf8), \
|
|||
|
DnsCharSetUtf8 )
|
|||
|
#if 0
|
|||
|
// with commments
|
|||
|
Dns_StringCopy( \
|
|||
|
(buf), \ // buffer
|
|||
|
NULL, \ // adequate buffer length
|
|||
|
(psz), \ // string
|
|||
|
(len), \ // string length (if known)
|
|||
|
((funicode) ? DnsCharSetUnicode : DnsCharSet), \ // input format
|
|||
|
DnsCharSetUtf8 ) // RPC buffer always in UTF8
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// size of name in RPC format
|
|||
|
//
|
|||
|
|
|||
|
#define NAME_UTF8_BUF_SIZE( string, fUnicode ) \
|
|||
|
Dns_GetBufferLengthForStringCopy( \
|
|||
|
(string), \
|
|||
|
0, \
|
|||
|
((fUnicode) ? DnsCharSetUnicode : DnsCharSetUtf8), \
|
|||
|
DnsCharSetUtf8 )
|
|||
|
#if 0
|
|||
|
// with comments
|
|||
|
Dns_GetBufferLengthForStringCopy( \
|
|||
|
(string), \ // string
|
|||
|
0, \ // unknown length
|
|||
|
((fUnicode) ? DnsCharSetUnicode : DnsCharSetUtf8), \ // in string
|
|||
|
DnsCharSetUtf8 ) // RPC string always UTF8
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Writing names to RPC buffer format
|
|||
|
//
|
|||
|
|
|||
|
#define WRITE_NAME_TO_RPC_BUF(buf, psz, len, funicode) \
|
|||
|
Dns_StringCopy( \
|
|||
|
(buf), \
|
|||
|
NULL, \
|
|||
|
(psz), \
|
|||
|
(len), \
|
|||
|
((funicode) ? DnsCharSetUnicode : DnsCharSetUtf8), \
|
|||
|
DnsCharSetUtf8 )
|
|||
|
#if 0
|
|||
|
// with commments
|
|||
|
Dns_StringCopy( \
|
|||
|
(buf), \ // buffer
|
|||
|
NULL, \ // adequate buffer length
|
|||
|
(psz), \ // string
|
|||
|
(len), \ // string length (if known)
|
|||
|
((funicode) ? DnsCharSetUnicode : DnsCharSet), \ // input format
|
|||
|
DnsCharSetUtf8 ) // RPC buffer always in UTF8
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Private protos
|
|||
|
//
|
|||
|
|
|||
|
PDNS_RPC_RECORD
|
|||
|
Rpc_AllocateRecord(
|
|||
|
IN DWORD BufferLength
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// RPC buffer conversion functions
|
|||
|
//
|
|||
|
|
|||
|
PDNS_RPC_RECORD
|
|||
|
ADnsRecordConvert(
|
|||
|
IN PDNS_RECORD pRR
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Convert A record from DNS Record to RPC buffer.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pRR - record being read
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Ptr to new RPC buffer if successful.
|
|||
|
NULL on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PDNS_RPC_RECORD prpcRR;
|
|||
|
|
|||
|
DNS_ASSERT( pRR->wDataLength == sizeof(IP_ADDRESS) );
|
|||
|
|
|||
|
prpcRR = Rpc_AllocateRecord( sizeof(IP_ADDRESS) );
|
|||
|
if ( !prpcRR )
|
|||
|
{
|
|||
|
return( NULL );
|
|||
|
}
|
|||
|
prpcRR->Data.A.ipAddress = pRR->Data.A.IpAddress;
|
|||
|
|
|||
|
return( prpcRR);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
PDNS_RPC_RECORD
|
|||
|
PtrDnsRecordConvert(
|
|||
|
IN PDNS_RECORD pRR
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Process PTR compatible record from wire.
|
|||
|
Includes: NS, PTR, CNAME, MB, MR, MG, MD, MF
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pRR - record being read
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Ptr to new RPC buffer if successful.
|
|||
|
NULL on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PDNS_RPC_RECORD prpcRR;
|
|||
|
DWORD length;
|
|||
|
BOOL funicode = IS_UNICODE_RECORD( pRR );
|
|||
|
|
|||
|
//
|
|||
|
// PTR data is another domain name
|
|||
|
//
|
|||
|
// determine required buffer length and allocate
|
|||
|
//
|
|||
|
|
|||
|
length = NAME_UTF8_BUF_SIZE(pRR->Data.PTR.pNameHost, funicode);
|
|||
|
|
|||
|
prpcRR = Rpc_AllocateRecord( sizeof(DNS_RPC_NAME) + length );
|
|||
|
if ( !prpcRR )
|
|||
|
{
|
|||
|
return( NULL );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// write hostname into buffer, immediately following PTR data struct
|
|||
|
//
|
|||
|
|
|||
|
prpcRR->Data.PTR.nameNode.cchNameLength = (UCHAR)length;
|
|||
|
|
|||
|
WRITE_NAME_TO_RPC_BUF(
|
|||
|
prpcRR->Data.PTR.nameNode.achName, // buffer
|
|||
|
pRR->Data.PTR.pNameHost,
|
|||
|
0,
|
|||
|
funicode );
|
|||
|
|
|||
|
return( prpcRR );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
PDNS_RPC_RECORD
|
|||
|
SoaDnsRecordConvert(
|
|||
|
IN PDNS_RECORD pRR
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Convert SOA record from DNS Record to RPC buffer.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pRR - ptr to record being read
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Ptr to new RPC buffer if successful.
|
|||
|
NULL on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PDNS_RPC_RECORD prpcRR;
|
|||
|
DWORD length1;
|
|||
|
DWORD length2;
|
|||
|
PDNS_RPC_NAME pnamePrimary;
|
|||
|
PDNS_RPC_NAME pnameAdmin;
|
|||
|
BOOL funicode = IS_UNICODE_RECORD( pRR );
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// determine required buffer length and allocate
|
|||
|
//
|
|||
|
|
|||
|
length1 = NAME_UTF8_BUF_SIZE( pRR->Data.SOA.pNamePrimaryServer, funicode );
|
|||
|
|
|||
|
length2 = NAME_UTF8_BUF_SIZE( pRR->Data.SOA.pNameAdministrator, funicode );
|
|||
|
|
|||
|
prpcRR = Rpc_AllocateRecord(
|
|||
|
SIZEOF_SOA_FIXED_DATA + sizeof(DNS_RPC_NAME) * 2 +
|
|||
|
length1 + length2 );
|
|||
|
if ( !prpcRR )
|
|||
|
{
|
|||
|
return( NULL );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// copy fixed fields
|
|||
|
//
|
|||
|
|
|||
|
RtlCopyMemory(
|
|||
|
(PCHAR) & prpcRR->Data.SOA.dwSerialNo,
|
|||
|
(PCHAR) & pRR->Data.SOA.dwSerialNo,
|
|||
|
SIZEOF_SOA_FIXED_DATA );
|
|||
|
|
|||
|
//
|
|||
|
// copy names into RR buffer
|
|||
|
// - primary server immediately follows SOA data struct
|
|||
|
// - responsible party follows primary server
|
|||
|
//
|
|||
|
|
|||
|
pnamePrimary = &prpcRR->Data.SOA.namePrimaryServer;
|
|||
|
pnamePrimary->cchNameLength = (UCHAR) length1;
|
|||
|
|
|||
|
pnameAdmin = DNS_GET_NEXT_NAME( pnamePrimary );
|
|||
|
pnameAdmin->cchNameLength = (UCHAR) length2;
|
|||
|
|
|||
|
WRITE_NAME_TO_RPC_BUF(
|
|||
|
pnamePrimary->achName,
|
|||
|
pRR->Data.Soa.pNamePrimaryServer,
|
|||
|
0,
|
|||
|
funicode );
|
|||
|
|
|||
|
WRITE_NAME_TO_RPC_BUF(
|
|||
|
pnameAdmin->achName,
|
|||
|
pRR->Data.Soa.pNameAdministrator,
|
|||
|
0,
|
|||
|
funicode );
|
|||
|
|
|||
|
return( prpcRR );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
PDNS_RPC_RECORD
|
|||
|
TxtDnsRecordConvert(
|
|||
|
IN PDNS_RECORD pRR
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Read TXT compatible record from wire.
|
|||
|
Includes: TXT, X25, HINFO, ISDN
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pRR - record being read
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Ptr to new RPC buffer if successful.
|
|||
|
NULL on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PDNS_RPC_RECORD prpcRR;
|
|||
|
DWORD bufLength;
|
|||
|
DWORD length;
|
|||
|
INT count;
|
|||
|
PCHAR pch;
|
|||
|
PCHAR * ppstring;
|
|||
|
BOOL funicode = IS_UNICODE_RECORD( pRR );
|
|||
|
|
|||
|
//
|
|||
|
// determine required buffer length and allocate
|
|||
|
// - allocate space for each string
|
|||
|
// - and ptr for each string
|
|||
|
//
|
|||
|
|
|||
|
bufLength = 0;
|
|||
|
count = pRR->Data.TXT.dwStringCount;
|
|||
|
ppstring = pRR->Data.TXT.pStringArray;
|
|||
|
|
|||
|
while ( count-- )
|
|||
|
{
|
|||
|
//
|
|||
|
// Note: sizeof(DNS_RPC_NAME) is two: 1 char for the length value
|
|||
|
// and 1 char for the first char in the name. The max string length
|
|||
|
// is 255 because we store the string length in a single byte.
|
|||
|
//
|
|||
|
length = STRING_UTF8_BUF_SIZE( *ppstring++, funicode );
|
|||
|
if ( length > 255 )
|
|||
|
{
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
bufLength += sizeof(DNS_RPC_NAME) + length - 1;
|
|||
|
}
|
|||
|
|
|||
|
// allocate
|
|||
|
|
|||
|
prpcRR = Rpc_AllocateRecord( bufLength );
|
|||
|
if ( !prpcRR )
|
|||
|
{
|
|||
|
return( NULL );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// go back through list copying strings to buffer
|
|||
|
// - ptrs to strings are saved to argv like data section
|
|||
|
// ppstring walks through this section
|
|||
|
// - first string written immediately following data section
|
|||
|
// - each subsequent string immediately follows predecessor
|
|||
|
// pchbuffer keeps ptr to position to write strings
|
|||
|
//
|
|||
|
// DEVNOTE: this is a mess
|
|||
|
//
|
|||
|
|
|||
|
pch = (PCHAR) &prpcRR->Data.TXT;
|
|||
|
ppstring = pRR->Data.TXT.pStringArray;
|
|||
|
count = pRR->Data.TXT.dwStringCount;
|
|||
|
|
|||
|
while ( count-- )
|
|||
|
{
|
|||
|
length = STRING_UTF8_BUF_SIZE( *ppstring, funicode );
|
|||
|
(UCHAR) *pch++ += (UCHAR) length; //+1 for TXT type only
|
|||
|
|
|||
|
length = WRITE_STRING_TO_RPC_BUF(
|
|||
|
pch,
|
|||
|
*ppstring++,
|
|||
|
0,
|
|||
|
funicode
|
|||
|
);
|
|||
|
pch += length;
|
|||
|
#if DBG
|
|||
|
DNS_PRINT((
|
|||
|
"Read text string %s\n",
|
|||
|
* (ppstring - 1)
|
|||
|
));
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
return( prpcRR );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
PDNS_RPC_RECORD
|
|||
|
MinfoDnsRecordConvert(
|
|||
|
IN PDNS_RECORD pRR
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Read MINFO record from wire.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pRR - record being read
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Ptr to new RPC buffer if successful.
|
|||
|
NULL on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PDNS_RPC_RECORD prpcRR;
|
|||
|
DWORD length1;
|
|||
|
DWORD length2;
|
|||
|
PDNS_RPC_NAME prpcName1;
|
|||
|
PDNS_RPC_NAME prpcName2;
|
|||
|
BOOL funicode = IS_UNICODE_RECORD( pRR );
|
|||
|
|
|||
|
//
|
|||
|
// determine required buffer length and allocate
|
|||
|
//
|
|||
|
|
|||
|
length1 = NAME_UTF8_BUF_SIZE( pRR->Data.MINFO.pNameMailbox, funicode );
|
|||
|
length2 = NAME_UTF8_BUF_SIZE( pRR->Data.MINFO.pNameErrorsMailbox, funicode );
|
|||
|
|
|||
|
prpcRR = Rpc_AllocateRecord( sizeof(DNS_RPC_NAME) * 2 + length1 + length2 );
|
|||
|
if ( !prpcRR )
|
|||
|
{
|
|||
|
return( NULL );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// copy names into RR buffer
|
|||
|
// - mailbox immediately follows MINFO data struct
|
|||
|
// - errors mailbox immediately follows primary server
|
|||
|
//
|
|||
|
|
|||
|
prpcName1 = &prpcRR->Data.MINFO.nameMailBox;
|
|||
|
prpcName1->cchNameLength = (UCHAR) length1;
|
|||
|
|
|||
|
prpcName2 = DNS_GET_NEXT_NAME( prpcName1);
|
|||
|
prpcName2->cchNameLength = (UCHAR) length2;
|
|||
|
|
|||
|
WRITE_NAME_TO_RPC_BUF(
|
|||
|
prpcName1->achName,
|
|||
|
pRR->Data.MINFO.pNameMailbox,
|
|||
|
0,
|
|||
|
funicode );
|
|||
|
|
|||
|
WRITE_NAME_TO_RPC_BUF(
|
|||
|
prpcName2->achName,
|
|||
|
pRR->Data.MINFO.pNameErrorsMailbox,
|
|||
|
0,
|
|||
|
funicode );
|
|||
|
|
|||
|
return( prpcRR );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
PDNS_RPC_RECORD
|
|||
|
MxDnsRecordConvert(
|
|||
|
IN PDNS_RECORD pRR
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
convert MX compatible record.
|
|||
|
Includes: MX, RT, AFSDB
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pRR - record being read
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Ptr to new RPC buffer if successful.
|
|||
|
NULL on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PDNS_RPC_RECORD prpcRR;
|
|||
|
PDNS_RPC_NAME prpcName;
|
|||
|
DWORD length;
|
|||
|
BOOL funicode = IS_UNICODE_RECORD( pRR );
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// determine required buffer length and allocate
|
|||
|
//
|
|||
|
|
|||
|
length = NAME_UTF8_BUF_SIZE( pRR->Data.MX.pNameExchange, funicode );
|
|||
|
|
|||
|
prpcRR = Rpc_AllocateRecord(
|
|||
|
SIZEOF_MX_FIXED_DATA + sizeof(DNS_RPC_NAME) + length );
|
|||
|
if ( !prpcRR )
|
|||
|
{
|
|||
|
return( NULL );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// copy preference
|
|||
|
//
|
|||
|
|
|||
|
prpcRR->Data.MX.wPreference = pRR->Data.MX.wPreference;
|
|||
|
|
|||
|
//
|
|||
|
// write hostname into buffer, immediately following MX struct
|
|||
|
//
|
|||
|
|
|||
|
prpcName = &prpcRR->Data.MX.nameExchange;
|
|||
|
prpcName->cchNameLength = (UCHAR) length;
|
|||
|
|
|||
|
WRITE_NAME_TO_RPC_BUF(
|
|||
|
prpcName->achName,
|
|||
|
pRR->Data.MX.pNameExchange,
|
|||
|
0,
|
|||
|
funicode );
|
|||
|
|
|||
|
return( prpcRR );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
PDNS_RPC_RECORD
|
|||
|
SigDnsRecordConvert(
|
|||
|
IN PDNS_RECORD pRR
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Convert SIG record.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pRR - record being read
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Ptr to new RPC buffer if successful.
|
|||
|
NULL on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PDNS_RPC_RECORD prpcRR;
|
|||
|
PDNS_RPC_NAME prpcName;
|
|||
|
DWORD nameLength;
|
|||
|
DWORD sigLength;
|
|||
|
BOOL funicode = IS_UNICODE_RECORD( pRR );
|
|||
|
PBYTE pSig;
|
|||
|
|
|||
|
nameLength = NAME_UTF8_BUF_SIZE( pRR->Data.SIG.pNameSigner, funicode );
|
|||
|
|
|||
|
sigLength = (DWORD)(pRR->wDataLength -
|
|||
|
( pRR->Data.SIG.Signature - ( PBYTE ) &pRR->Data.SIG ));
|
|||
|
|
|||
|
prpcRR = Rpc_AllocateRecord(
|
|||
|
SIZEOF_SIG_FIXED_DATA + 1 + nameLength + sigLength );
|
|||
|
if ( !prpcRR )
|
|||
|
{
|
|||
|
return( NULL );
|
|||
|
}
|
|||
|
|
|||
|
prpcRR->Data.SIG.wTypeCovered = pRR->Data.SIG.wTypeCovered;
|
|||
|
prpcRR->Data.SIG.chAlgorithm = pRR->Data.SIG.chAlgorithm;
|
|||
|
prpcRR->Data.SIG.chLabelCount = pRR->Data.SIG.chLabelCount;
|
|||
|
prpcRR->Data.SIG.dwOriginalTtl = pRR->Data.SIG.dwOriginalTtl;
|
|||
|
prpcRR->Data.SIG.dwSigExpiration = pRR->Data.SIG.dwExpiration;
|
|||
|
prpcRR->Data.SIG.dwSigInception = pRR->Data.SIG.dwTimeSigned;
|
|||
|
prpcRR->Data.SIG.wKeyTag = pRR->Data.SIG.wKeyTag;
|
|||
|
|
|||
|
prpcName = &prpcRR->Data.SIG.nameSigner;
|
|||
|
prpcName->cchNameLength = ( UCHAR ) nameLength;
|
|||
|
|
|||
|
WRITE_NAME_TO_RPC_BUF(
|
|||
|
prpcName->achName,
|
|||
|
pRR->Data.SIG.pNameSigner,
|
|||
|
0,
|
|||
|
funicode );
|
|||
|
|
|||
|
pSig = ( PBYTE ) DNS_GET_NEXT_NAME( prpcName );
|
|||
|
|
|||
|
RtlCopyMemory( pSig, pRR->Data.SIG.Signature, sigLength );
|
|||
|
|
|||
|
return prpcRR;
|
|||
|
} // SigDnsRecordConvert
|
|||
|
|
|||
|
|
|||
|
|
|||
|
PDNS_RPC_RECORD
|
|||
|
NxtDnsRecordConvert(
|
|||
|
IN PDNS_RECORD pRR
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Convert NXT record.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pRR - record being read
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Ptr to new RPC buffer if successful.
|
|||
|
NULL on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PDNS_RPC_RECORD prpcRR;
|
|||
|
PDNS_RPC_NAME prpcName;
|
|||
|
DWORD nameLength;
|
|||
|
BOOL funicode = IS_UNICODE_RECORD( pRR );
|
|||
|
|
|||
|
//
|
|||
|
// Allocate the RPC record.
|
|||
|
//
|
|||
|
|
|||
|
nameLength = NAME_UTF8_BUF_SIZE( pRR->Data.NXT.pNameNext, funicode );
|
|||
|
|
|||
|
prpcRR = Rpc_AllocateRecord(
|
|||
|
nameLength + 1 +
|
|||
|
( pRR->Data.NXT.wNumTypes + 1 ) * sizeof( WORD ) );
|
|||
|
if ( !prpcRR )
|
|||
|
{
|
|||
|
return( NULL );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Copy the type array.
|
|||
|
//
|
|||
|
|
|||
|
prpcRR->Data.Nxt.wNumTypeWords = pRR->Data.NXT.wNumTypes;
|
|||
|
|
|||
|
RtlCopyMemory(
|
|||
|
prpcRR->Data.Nxt.wTypeWords,
|
|||
|
pRR->Data.NXT.wTypes,
|
|||
|
pRR->Data.NXT.wNumTypes * sizeof( WORD ) );
|
|||
|
|
|||
|
//
|
|||
|
// Write the next name.
|
|||
|
//
|
|||
|
|
|||
|
prpcName = ( PDNS_RPC_NAME ) (
|
|||
|
( PBYTE ) &prpcRR->Data.NXT.wTypeWords +
|
|||
|
prpcRR->Data.Nxt.wNumTypeWords * sizeof( WORD ) );
|
|||
|
prpcName->cchNameLength = ( UCHAR ) nameLength;
|
|||
|
WRITE_NAME_TO_RPC_BUF(
|
|||
|
prpcName->achName,
|
|||
|
pRR->Data.NXT.pNameNext,
|
|||
|
0,
|
|||
|
funicode );
|
|||
|
|
|||
|
return prpcRR;
|
|||
|
} // NxtDnsRecordConvert
|
|||
|
|
|||
|
|
|||
|
|
|||
|
PDNS_RPC_RECORD
|
|||
|
FlatDnsRecordConvert(
|
|||
|
IN PDNS_RECORD pRR
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Convert memory copy compatible record.
|
|||
|
Includes AAAA and WINS types.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pRR - record being read
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Ptr to new RPC buffer if successful.
|
|||
|
NULL on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PDNS_RPC_RECORD prpcRR;
|
|||
|
DWORD bufLength;
|
|||
|
|
|||
|
//
|
|||
|
// determine required buffer length and allocate
|
|||
|
//
|
|||
|
|
|||
|
bufLength = pRR->wDataLength;
|
|||
|
|
|||
|
prpcRR = Rpc_AllocateRecord( bufLength );
|
|||
|
if ( !prpcRR )
|
|||
|
{
|
|||
|
return( NULL );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// copy packet data to record
|
|||
|
//
|
|||
|
|
|||
|
RtlCopyMemory(
|
|||
|
& prpcRR->Data,
|
|||
|
& pRR->Data,
|
|||
|
bufLength );
|
|||
|
|
|||
|
return( prpcRR );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
PDNS_RPC_RECORD
|
|||
|
SrvDnsRecordConvert(
|
|||
|
IN PDNS_RECORD pRR
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
convert SRV record.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pRR - record being read
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Ptr to new RPC buffer if successful.
|
|||
|
NULL on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PDNS_RPC_RECORD prpcRR;
|
|||
|
PDNS_RPC_NAME prpcName;
|
|||
|
DWORD length;
|
|||
|
BOOL funicode = IS_UNICODE_RECORD( pRR );
|
|||
|
|
|||
|
//
|
|||
|
// determine required buffer length and allocate
|
|||
|
//
|
|||
|
|
|||
|
length = NAME_UTF8_BUF_SIZE( pRR->Data.SRV.pNameTarget, funicode );
|
|||
|
|
|||
|
prpcRR = Rpc_AllocateRecord(
|
|||
|
SIZEOF_SRV_FIXED_DATA + sizeof(DNS_RPC_NAME) + length );
|
|||
|
if ( !prpcRR )
|
|||
|
{
|
|||
|
return( NULL );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// copy SRV fixed fields
|
|||
|
//
|
|||
|
|
|||
|
prpcRR->Data.SRV.wPriority = pRR->Data.SRV.wPriority;
|
|||
|
prpcRR->Data.SRV.wWeight = pRR->Data.SRV.wWeight;
|
|||
|
prpcRR->Data.SRV.wPort = pRR->Data.SRV.wPort;
|
|||
|
|
|||
|
//
|
|||
|
// write hostname into buffer, immediately following SRV struct
|
|||
|
//
|
|||
|
|
|||
|
prpcName = &prpcRR->Data.SRV.nameTarget;
|
|||
|
prpcName->cchNameLength = (UCHAR) length;
|
|||
|
|
|||
|
WRITE_NAME_TO_RPC_BUF(
|
|||
|
prpcName->achName,
|
|||
|
pRR->Data.SRV.pNameTarget,
|
|||
|
0,
|
|||
|
funicode );
|
|||
|
|
|||
|
return( prpcRR );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
PDNS_RPC_RECORD
|
|||
|
NbstatDnsRecordConvert(
|
|||
|
IN PDNS_RECORD pRR
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Read WINSR record from wire.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pRR - record being read
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Ptr to new RPC buffer if successful.
|
|||
|
NULL on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PDNS_RPC_RECORD prpcRR;
|
|||
|
PDNS_RPC_NAME prpcName;
|
|||
|
DWORD length;
|
|||
|
BOOL funicode = IS_UNICODE_RECORD( pRR );
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// determine required buffer length and allocate
|
|||
|
//
|
|||
|
|
|||
|
length = NAME_UTF8_BUF_SIZE( pRR->Data.WINSR.pNameResultDomain, funicode );
|
|||
|
|
|||
|
prpcRR = Rpc_AllocateRecord(
|
|||
|
SIZEOF_NBSTAT_FIXED_DATA + sizeof(DNS_RPC_NAME) + length );
|
|||
|
if ( !prpcRR )
|
|||
|
{
|
|||
|
return( NULL );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// copy WINSR fixed fields
|
|||
|
//
|
|||
|
|
|||
|
prpcRR->Data.WINSR.dwMappingFlag = pRR->Data.WINSR.dwMappingFlag;
|
|||
|
prpcRR->Data.WINSR.dwLookupTimeout = pRR->Data.WINSR.dwLookupTimeout;
|
|||
|
prpcRR->Data.WINSR.dwCacheTimeout = pRR->Data.WINSR.dwCacheTimeout;
|
|||
|
|
|||
|
//
|
|||
|
// write hostname into buffer, immediately following WINSR struct
|
|||
|
//
|
|||
|
|
|||
|
prpcName = &prpcRR->Data.WINSR.nameResultDomain;
|
|||
|
prpcName->cchNameLength = (UCHAR) length;
|
|||
|
|
|||
|
WRITE_NAME_TO_RPC_BUF(
|
|||
|
prpcName->achName,
|
|||
|
pRR->Data.WINSR.pNameResultDomain,
|
|||
|
0,
|
|||
|
funicode );
|
|||
|
|
|||
|
return( prpcRR );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Jump table for DNS_RECORD => RPC buffer conversion.
|
|||
|
//
|
|||
|
|
|||
|
typedef PDNS_RPC_RECORD (* RECORD_TO_RPC_CONVERT_FUNCTION)( PDNS_RECORD );
|
|||
|
|
|||
|
RECORD_TO_RPC_CONVERT_FUNCTION RecordToRpcConvertTable[] =
|
|||
|
{
|
|||
|
NULL, // ZERO
|
|||
|
ADnsRecordConvert, // A
|
|||
|
PtrDnsRecordConvert, // NS
|
|||
|
PtrDnsRecordConvert, // MD
|
|||
|
PtrDnsRecordConvert, // MF
|
|||
|
PtrDnsRecordConvert, // CNAME
|
|||
|
SoaDnsRecordConvert, // SOA
|
|||
|
PtrDnsRecordConvert, // MB
|
|||
|
PtrDnsRecordConvert, // MG
|
|||
|
PtrDnsRecordConvert, // MR
|
|||
|
NULL, // NULL
|
|||
|
FlatDnsRecordConvert, // WKS
|
|||
|
PtrDnsRecordConvert, // PTR
|
|||
|
TxtDnsRecordConvert, // HINFO
|
|||
|
MinfoDnsRecordConvert, // MINFO
|
|||
|
MxDnsRecordConvert, // MX
|
|||
|
TxtDnsRecordConvert, // TXT
|
|||
|
MinfoDnsRecordConvert, // RP
|
|||
|
MxDnsRecordConvert, // AFSDB
|
|||
|
TxtDnsRecordConvert, // X25
|
|||
|
TxtDnsRecordConvert, // ISDN
|
|||
|
MxDnsRecordConvert, // RT
|
|||
|
NULL, // NSAP
|
|||
|
NULL, // NSAPPTR
|
|||
|
SigDnsRecordConvert, // SIG
|
|||
|
NULL, // KEY
|
|||
|
NULL, // PX
|
|||
|
NULL, // GPOS
|
|||
|
FlatDnsRecordConvert, // AAAA
|
|||
|
NULL, // 29
|
|||
|
NxtDnsRecordConvert, // 30
|
|||
|
NULL, // 31
|
|||
|
NULL, // 32
|
|||
|
SrvDnsRecordConvert, // SRV
|
|||
|
NULL, // ATMA
|
|||
|
NULL, // 35
|
|||
|
NULL, // 36
|
|||
|
NULL, // 37
|
|||
|
NULL, // 38
|
|||
|
NULL, // 39
|
|||
|
NULL, // 40
|
|||
|
NULL, // OPT
|
|||
|
NULL, // 42
|
|||
|
NULL, // 43
|
|||
|
NULL, // 44
|
|||
|
NULL, // 45
|
|||
|
NULL, // 46
|
|||
|
NULL, // 47
|
|||
|
NULL, // 48
|
|||
|
|
|||
|
//
|
|||
|
// NOTE: last type indexed by type ID MUST be set
|
|||
|
// as MAX_SELF_INDEXED_TYPE #define in record.h
|
|||
|
// (see note above in record info table)
|
|||
|
|
|||
|
// note these follow, but require OFFSET_TO_WINS_RR subtraction
|
|||
|
// from actual type value
|
|||
|
|
|||
|
NULL, // TKEY
|
|||
|
NULL, // TSIG
|
|||
|
FlatDnsRecordConvert, // WINS
|
|||
|
NbstatDnsRecordConvert // WINS-R
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
|
|||
|
PDNS_RPC_RECORD
|
|||
|
Rpc_AllocateRecord(
|
|||
|
IN DWORD BufferLength
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Allocate RPC record structure.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
wBufferLength - desired buffer length (beyond structure header)
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Ptr to buffer.
|
|||
|
NULL on error.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PDNS_RPC_RECORD prr;
|
|||
|
|
|||
|
if ( BufferLength > MAXWORD )
|
|||
|
{
|
|||
|
return( NULL );
|
|||
|
}
|
|||
|
|
|||
|
prr = ALLOCATE_HEAP( SIZEOF_DNS_RPC_RECORD_HEADER + BufferLength );
|
|||
|
if ( !prr )
|
|||
|
{
|
|||
|
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
|||
|
return( NULL );
|
|||
|
}
|
|||
|
|
|||
|
// set datalength to buffer length
|
|||
|
|
|||
|
prr->wDataLength = (WORD) BufferLength;
|
|||
|
|
|||
|
return( prr );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
PDNS_RPC_RECORD
|
|||
|
DnsConvertRecordToRpcBuffer(
|
|||
|
IN PDNS_RECORD pRecord
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Convert standard DNS record to RPC buffer.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pRecord -- DNS Record to be converted.
|
|||
|
|
|||
|
//fUnicode -- flag, write records into unicode
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Ptr to new RPC buffer if successful.
|
|||
|
NULL on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PDNS_RPC_RECORD prpcRecord;
|
|||
|
WORD index;
|
|||
|
WORD type;
|
|||
|
RECORD_TO_RPC_CONVERT_FUNCTION pFunc;
|
|||
|
|
|||
|
|
|||
|
DNS_ASSERT( DNS_IS_DWORD_ALIGNED(pRecord) );
|
|||
|
IF_DNSDBG( RPC2 )
|
|||
|
{
|
|||
|
DNS_PRINT((
|
|||
|
"Enter DnsConvertRecordToRpcBuffer()\n"
|
|||
|
"\tpRecord = %p\n",
|
|||
|
pRecord ));
|
|||
|
}
|
|||
|
|
|||
|
//DNS_RRSET_INIT( rrset );
|
|||
|
|
|||
|
//
|
|||
|
// convert record
|
|||
|
// set unicode flag if converting
|
|||
|
//
|
|||
|
|
|||
|
//if ( fUnicode )
|
|||
|
//{
|
|||
|
//SET_RPC_UNICODE( pRecord );
|
|||
|
//}
|
|||
|
|
|||
|
type = pRecord->wType;
|
|||
|
index = INDEX_FOR_TYPE( type );
|
|||
|
DNS_ASSERT( index <= MAX_RECORD_TYPE_INDEX );
|
|||
|
|
|||
|
if ( !index || !(pFunc = RecordToRpcConvertTable[ index ]) )
|
|||
|
{
|
|||
|
// if unknown type try flat record copy -- best we can
|
|||
|
// do to protect if server added new types since admin built
|
|||
|
|
|||
|
DNS_PRINT((
|
|||
|
"ERROR: no DNS_RECORD to RPC conversion routine for type %d.\n"
|
|||
|
"\tusing flat conversion routine.\n",
|
|||
|
type ));
|
|||
|
pFunc = FlatDnsRecordConvert;
|
|||
|
}
|
|||
|
|
|||
|
prpcRecord = (*pFunc)( pRecord );
|
|||
|
if ( ! prpcRecord )
|
|||
|
{
|
|||
|
DNS_PRINT((
|
|||
|
"ERROR: Record build routine failure for record type %d.\n"
|
|||
|
"\tstatus = %p\n\n",
|
|||
|
type,
|
|||
|
GetLastError() ));
|
|||
|
return(NULL);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// fill out record structure
|
|||
|
//
|
|||
|
|
|||
|
prpcRecord->wType = type;
|
|||
|
prpcRecord->dwTtlSeconds = pRecord->dwTtl;
|
|||
|
|
|||
|
//
|
|||
|
// DEVNOTE: data types (root hint, glue set)
|
|||
|
// - need way to default that works for NT4
|
|||
|
// (JJW: this is probably an obsolete B*GB*G)
|
|||
|
//
|
|||
|
/*
|
|||
|
if ( prpcRecord->dwFlags & DNS_RPC_RECORD_FLAG_CACHE_DATA )
|
|||
|
{
|
|||
|
precord->Flags.S.Section = DNSREC_CACHE_DATA;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
precord->Flags.S.Section = DNSREC_ZONE_DATA;
|
|||
|
}
|
|||
|
*/
|
|||
|
|
|||
|
IF_DNSDBG( INIT )
|
|||
|
{
|
|||
|
DNS_PRINT((
|
|||
|
"New RPC buffer built\n"
|
|||
|
));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
IF_DNSDBG( RPC2 )
|
|||
|
{
|
|||
|
/*
|
|||
|
DnsDbg_RecordSet(
|
|||
|
"Finished DnsConvertRpcBufferToRecords() ",
|
|||
|
rrset.pFirstRR );
|
|||
|
*/
|
|||
|
DNS_PRINT((
|
|||
|
"Finished DnsConvertRpcBufferToRecords() "
|
|||
|
));
|
|||
|
}
|
|||
|
|
|||
|
return(prpcRecord);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// End dconvert.c
|
|||
|
//
|