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.
2637 lines
50 KiB
2637 lines
50 KiB
/*++
|
|
|
|
Copyright (c) 1997-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
rrbuild.c
|
|
|
|
Abstract:
|
|
|
|
Domain Name System (DNS) Library
|
|
|
|
Build resource record routines.
|
|
|
|
Author:
|
|
|
|
Jim Gilroy (jamesg) January, 1997
|
|
|
|
Revision History:
|
|
|
|
Jing Chen (t-jingc) June, 1998
|
|
|
|
--*/
|
|
|
|
|
|
#include "local.h"
|
|
|
|
|
|
|
|
//
|
|
// Type specific record build routines
|
|
//
|
|
|
|
PDNS_RECORD
|
|
A_RecordBuild(
|
|
IN DWORD Argc,
|
|
IN PCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build A record from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
|
|
if ( Argc != 1 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
|
|
precord = Dns_AllocateRecord( sizeof(DNS_A_DATA) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
if ( ! Dns_Ip4StringToAddress_A(
|
|
&precord->Data.A.IpAddress,
|
|
Argv[0] ) )
|
|
{
|
|
Dns_RecordFree( precord );
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return NULL;
|
|
}
|
|
|
|
return( precord );
|
|
}
|
|
|
|
|
|
PDNS_RECORD
|
|
A_RecordBuildW(
|
|
IN DWORD Argc,
|
|
IN PWCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build A record from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
|
|
if ( Argc != 1 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
|
|
precord = Dns_AllocateRecord( sizeof(DNS_A_DATA) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
if ( ! Dns_Ip4StringToAddress_W(
|
|
&precord->Data.A.IpAddress,
|
|
Argv[0] ) )
|
|
{
|
|
Dns_RecordFree( precord );
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return NULL;
|
|
}
|
|
|
|
return( precord );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Ptr_RecordBuild(
|
|
IN DWORD Argc,
|
|
IN PCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build PTR compatible record from string data.
|
|
Includes: NS, PTR, CNAME, MB, MR, MG, MD, MF
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
|
|
if ( Argc != 1 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
|
|
precord = Dns_AllocateRecord( sizeof(DNS_PTR_DATA) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
precord->Data.PTR.pNameHost = Argv[0];
|
|
|
|
return( precord );
|
|
}
|
|
|
|
|
|
PDNS_RECORD
|
|
Ptr_RecordBuildW(
|
|
IN DWORD Argc,
|
|
IN PWCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build PTR compatible record from string data.
|
|
Includes: NS, PTR, CNAME, MB, MR, MG, MD, MF
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
|
|
if ( Argc != 1 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
|
|
precord = Dns_AllocateRecord( sizeof(DNS_PTR_DATA) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
precord->Data.PTR.pNameHost = (PDNS_NAME) Argv[0];
|
|
|
|
return( precord );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Mx_RecordBuild(
|
|
IN DWORD Argc,
|
|
IN PCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build MX compatible record from string data.
|
|
Includes: MX, RT, AFSDB
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
DWORD temp;
|
|
|
|
if ( Argc != 2 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
precord = Dns_AllocateRecord( sizeof(DNS_MX_DATA) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// MX preference value
|
|
// RT preference
|
|
// AFSDB subtype
|
|
//
|
|
|
|
temp = strtoul( Argv[0], NULL, 10 );
|
|
if ( temp > MAXWORD )
|
|
{
|
|
temp = MAXWORD;
|
|
}
|
|
precord->Data.MX.wPreference = (USHORT) temp;
|
|
|
|
//
|
|
// MX exchange
|
|
// RT exchange
|
|
// AFSDB hostname
|
|
//
|
|
|
|
precord->Data.MX.pNameExchange = Argv[1];
|
|
|
|
return( precord );
|
|
}
|
|
|
|
|
|
PDNS_RECORD
|
|
Mx_RecordBuildW(
|
|
IN DWORD Argc,
|
|
IN PWCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build MX compatible record from string data.
|
|
Includes: MX, RT, AFSDB
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
DWORD temp;
|
|
|
|
if ( Argc != 2 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
precord = Dns_AllocateRecord( sizeof(DNS_MX_DATA) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// MX preference value
|
|
// RT preference
|
|
// AFSDB subtype
|
|
//
|
|
|
|
temp = wcstoul( Argv[0], NULL, 10 );
|
|
if ( temp > MAXWORD )
|
|
{
|
|
temp = MAXWORD;
|
|
}
|
|
precord->Data.MX.wPreference = (USHORT) temp;
|
|
|
|
//
|
|
// MX exchange
|
|
// RT exchange
|
|
// AFSDB hostname
|
|
//
|
|
|
|
precord->Data.MX.pNameExchange = (PDNS_NAME) Argv[1];
|
|
|
|
return( precord );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Soa_RecordBuild(
|
|
IN DWORD Argc,
|
|
IN PCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build SOA record from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
PDWORD pdword;
|
|
|
|
if ( Argc != 7 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
precord = Dns_AllocateRecord( sizeof(DNS_SOA_DATA) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// read primary server and responsible party
|
|
//
|
|
|
|
precord->Data.SOA.pNamePrimaryServer = Argv[0];
|
|
Argc--;
|
|
Argv++;
|
|
precord->Data.SOA.pNameAdministrator = Argv[0];
|
|
Argc--;
|
|
Argv++;
|
|
|
|
//
|
|
// read integer data
|
|
//
|
|
|
|
pdword = &precord->Data.SOA.dwSerialNo;
|
|
|
|
while( Argc-- )
|
|
{
|
|
*pdword = strtoul( Argv[0], NULL, 10 );
|
|
pdword++;
|
|
Argv++;
|
|
}
|
|
|
|
return( precord );
|
|
}
|
|
|
|
|
|
PDNS_RECORD
|
|
Soa_RecordBuildW(
|
|
IN DWORD Argc,
|
|
IN PWCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build SOA record from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
PDWORD pdword;
|
|
|
|
if ( Argc != 7 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
precord = Dns_AllocateRecord( sizeof(DNS_SOA_DATA) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// read primary server and responsible party
|
|
//
|
|
|
|
precord->Data.SOA.pNamePrimaryServer = (PDNS_NAME) Argv[0];
|
|
Argc--;
|
|
Argv++;
|
|
precord->Data.SOA.pNameAdministrator = (PDNS_NAME) Argv[0];
|
|
Argc--;
|
|
Argv++;
|
|
|
|
//
|
|
// read integer data
|
|
//
|
|
|
|
pdword = &precord->Data.SOA.dwSerialNo;
|
|
|
|
while( Argc-- )
|
|
{
|
|
*pdword = wcstoul( Argv[0], NULL, 10 );
|
|
pdword++;
|
|
Argv++;
|
|
}
|
|
|
|
return( precord );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Minfo_RecordBuild(
|
|
IN DWORD Argc,
|
|
IN PCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build MINFO and RP records from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
|
|
if ( Argc != 2 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
precord = Dns_AllocateRecord( sizeof(DNS_MINFO_DATA) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// MINFO responsible mailbox
|
|
// RP responsible person mailbox
|
|
|
|
precord->Data.MINFO.pNameMailbox = Argv[0];
|
|
Argc--;
|
|
Argv++;
|
|
|
|
//
|
|
// MINFO errors to mailbox
|
|
// RP text RR location
|
|
|
|
precord->Data.MINFO.pNameErrorsMailbox = Argv[0];
|
|
Argc--;
|
|
Argv++;
|
|
|
|
return( precord );
|
|
}
|
|
|
|
|
|
PDNS_RECORD
|
|
Minfo_RecordBuildW(
|
|
IN DWORD Argc,
|
|
IN PWCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build MINFO and RP records from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
|
|
if ( Argc != 2 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
precord = Dns_AllocateRecord( sizeof(DNS_MINFO_DATA) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// MINFO responsible mailbox
|
|
// RP responsible person mailbox
|
|
|
|
precord->Data.MINFO.pNameMailbox = (PDNS_NAME) Argv[0];
|
|
Argc--;
|
|
Argv++;
|
|
|
|
//
|
|
// MINFO errors to mailbox
|
|
// RP text RR location
|
|
|
|
precord->Data.MINFO.pNameErrorsMailbox = (PDNS_NAME) Argv[0];
|
|
Argc--;
|
|
Argv++;
|
|
|
|
return( precord );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Txt_RecordBuild(
|
|
IN DWORD Argc,
|
|
IN PCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build TXT compatible records from string data.
|
|
Includes: TXT, X25, HINFO, ISDN
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
WORD dataLength;
|
|
PCHAR * pstringPtr;
|
|
|
|
if ( Argc < 1 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// allocate space for a pointer for each data string
|
|
//
|
|
|
|
precord = Dns_AllocateRecord( (WORD)DNS_TEXT_RECORD_LENGTH(Argc) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
precord->Data.TXT.dwStringCount = Argc;
|
|
|
|
//
|
|
// read as many strings as we have
|
|
//
|
|
// DCR_FIX: no checking for string limits
|
|
// - string count limits on HINFO, X25, ISDN
|
|
// - 256 length on strings
|
|
// - 64K on overall size
|
|
//
|
|
|
|
pstringPtr = (PCHAR *) precord->Data.TXT.pStringArray;
|
|
while ( Argc-- )
|
|
{
|
|
*pstringPtr = Argv[0];
|
|
pstringPtr++;
|
|
Argv++;
|
|
}
|
|
return( precord );
|
|
}
|
|
|
|
|
|
PDNS_RECORD
|
|
Txt_RecordBuildW(
|
|
IN DWORD Argc,
|
|
IN PWCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build TXT compatible records from string data.
|
|
Includes: TXT, X25, HINFO, ISDN
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
WORD dataLength;
|
|
LPWSTR * pstringPtr;
|
|
|
|
if ( Argc < 1 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// allocate space for a pointer for each data string
|
|
//
|
|
|
|
precord = Dns_AllocateRecord( (WORD)DNS_TEXT_RECORD_LENGTH(Argc) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
precord->Data.TXT.dwStringCount = Argc;
|
|
|
|
//
|
|
// read as many strings as we have
|
|
//
|
|
// DCR_FIX: no checking for string limits
|
|
// - string count limits on HINFO, X25, ISDN
|
|
// - 256 length on strings
|
|
// - 64K on overall size
|
|
//
|
|
|
|
pstringPtr = (LPWSTR *) precord->Data.TXT.pStringArray;
|
|
while ( Argc-- )
|
|
{
|
|
*pstringPtr = Argv[0];
|
|
pstringPtr++;
|
|
Argv++;
|
|
}
|
|
return( precord );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Aaaa_RecordBuild(
|
|
IN DWORD Argc,
|
|
IN PCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build AAAA record from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
|
|
if ( Argc != 1 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
precord = Dns_AllocateRecord( sizeof(DNS_AAAA_DATA) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// read IP6 address
|
|
//
|
|
|
|
if ( ! Dns_Ip6StringToAddress_A(
|
|
(PIP6_ADDRESS) &precord->Data.AAAA.Ip6Address,
|
|
Argv[0] ) )
|
|
{
|
|
Dns_RecordFree( precord );
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return NULL;
|
|
}
|
|
return( precord );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Aaaa_RecordBuildW(
|
|
IN DWORD Argc,
|
|
IN PWCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build AAAA record from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
|
|
if ( Argc != 1 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
|
|
precord = Dns_AllocateRecord( sizeof(DNS_AAAA_DATA) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// convert IPv6 string to address
|
|
//
|
|
|
|
if ( ! Dns_Ip6StringToAddress_W(
|
|
&precord->Data.AAAA.Ip6Address,
|
|
Argv[0]
|
|
) )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
Dns_RecordFree( precord );
|
|
return NULL;
|
|
}
|
|
|
|
return( precord );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Srv_RecordBuild(
|
|
IN DWORD Argc,
|
|
IN PCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build SRV record from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
PWORD pword;
|
|
|
|
if ( Argc != 4 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
precord = Dns_AllocateRecord( sizeof(DNS_SRV_DATA) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// read integer data
|
|
//
|
|
|
|
pword = &precord->Data.SRV.wPriority;
|
|
|
|
while( Argc-- > 1 )
|
|
{
|
|
DWORD temp;
|
|
|
|
temp = strtoul( Argv[0], NULL, 10 );
|
|
if ( temp > MAXWORD )
|
|
{
|
|
temp = MAXWORD;
|
|
}
|
|
*pword++ = (WORD) temp;
|
|
Argv++;
|
|
}
|
|
|
|
//
|
|
// target host
|
|
//
|
|
|
|
precord->Data.SRV.pNameTarget = Argv[0];
|
|
|
|
return( precord );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Srv_RecordBuildW(
|
|
IN DWORD Argc,
|
|
IN PWCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build SRV record from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
PWORD pword;
|
|
|
|
if ( Argc != 4 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
precord = Dns_AllocateRecord( sizeof(DNS_SRV_DATA) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// read integer data
|
|
//
|
|
|
|
pword = &precord->Data.SRV.wPriority;
|
|
|
|
while( Argc-- > 1 )
|
|
{
|
|
DWORD temp;
|
|
|
|
temp = wcstoul( Argv[0], NULL, 10 );
|
|
if ( temp > MAXWORD )
|
|
{
|
|
temp = MAXWORD;
|
|
}
|
|
*pword++ = (WORD) temp;
|
|
Argv++;
|
|
}
|
|
|
|
//
|
|
// target host
|
|
//
|
|
|
|
precord->Data.SRV.pNameTarget = (PDNS_NAME) Argv[0];
|
|
|
|
return( precord );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Atma_RecordBuild(
|
|
IN DWORD Argc,
|
|
IN PCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build ATMA record from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
PBYTE pbyte;
|
|
|
|
if ( Argc != 2 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
|
|
precord = Dns_AllocateRecord( sizeof(DNS_ATMA_DATA) +
|
|
DNS_ATMA_MAX_ADDR_LENGTH );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// read integer data
|
|
//
|
|
|
|
pbyte = &precord->Data.ATMA.AddressType;
|
|
|
|
*pbyte = (BYTE) strtoul( Argv[0], NULL, 10 );
|
|
pbyte++;
|
|
Argv++;
|
|
|
|
if ( precord->Data.ATMA.AddressType == DNS_ATMA_FORMAT_E164 )
|
|
{
|
|
UINT length = strlen( Argv[0] );
|
|
UINT iter;
|
|
|
|
if ( length > DNS_ATMA_MAX_ADDR_LENGTH )
|
|
{
|
|
length = DNS_ATMA_MAX_ADDR_LENGTH;
|
|
}
|
|
for ( iter = 0; iter < length; iter++ )
|
|
{
|
|
precord->Data.ATMA.Address[iter] = Argv[0][iter];
|
|
}
|
|
|
|
precord->wDataLength = (WORD) length;
|
|
}
|
|
else
|
|
{
|
|
UINT length = strlen( Argv[0] );
|
|
UINT iter;
|
|
|
|
length /= 2;
|
|
|
|
if ( length != DNS_ATMA_MAX_ADDR_LENGTH )
|
|
{
|
|
Dns_RecordListFree( precord );
|
|
return NULL;
|
|
}
|
|
|
|
for ( iter = 0; iter < length; iter++ )
|
|
{
|
|
char temp[3];
|
|
|
|
temp[0] = Argv[0][(2*iter)];
|
|
temp[1] = Argv[0][(2*iter) + 1];
|
|
temp[2] = 0;
|
|
|
|
precord->Data.ATMA.Address[iter] = (char) strtoul( temp, NULL, 16 );
|
|
}
|
|
|
|
precord->wDataLength = (WORD) length;
|
|
}
|
|
|
|
return( precord );
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Atma_RecordBuildW(
|
|
IN DWORD Argc,
|
|
IN PWCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build ATMA record from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
PBYTE pbyte;
|
|
CHAR addrBuffer[256];
|
|
DWORD bufLength;
|
|
|
|
if ( Argc != 2 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
precord = Dns_AllocateRecord( sizeof(DNS_ATMA_DATA) +
|
|
DNS_ATMA_MAX_ADDR_LENGTH );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// read integer data
|
|
//
|
|
|
|
pbyte = &precord->Data.ATMA.AddressType;
|
|
|
|
*pbyte = (BYTE) wcstoul( Argv[0], NULL, 10 );
|
|
pbyte++;
|
|
Argv++;
|
|
|
|
//
|
|
// copy ATMA address string to wire
|
|
//
|
|
|
|
bufLength = DNS_ATMA_MAX_ADDR_LENGTH+1;
|
|
|
|
if ( ! Dns_StringCopy(
|
|
addrBuffer,
|
|
& bufLength,
|
|
(PCHAR) Argv[0],
|
|
0, // length unknown
|
|
DnsCharSetUnicode,
|
|
DnsCharSetWire
|
|
) )
|
|
{
|
|
Dns_RecordListFree( precord );
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// read address into record buffer
|
|
//
|
|
// DCR_CLEANUP: this is duplicate code with above function,
|
|
// functionalize and fix; also remove this loop
|
|
// and do a memcopy
|
|
//
|
|
|
|
if ( precord->Data.ATMA.AddressType == DNS_ATMA_FORMAT_E164 )
|
|
{
|
|
UINT length = strlen( addrBuffer );
|
|
UINT iter;
|
|
|
|
if ( length > DNS_ATMA_MAX_ADDR_LENGTH )
|
|
{
|
|
length = DNS_ATMA_MAX_ADDR_LENGTH;
|
|
}
|
|
|
|
for ( iter = 0; iter < length; iter++ )
|
|
{
|
|
precord->Data.ATMA.Address[iter] = addrBuffer[iter];
|
|
}
|
|
|
|
precord->wDataLength = (WORD) length;
|
|
}
|
|
else
|
|
{
|
|
UINT length = strlen( addrBuffer );
|
|
UINT iter;
|
|
|
|
length /= 2;
|
|
|
|
if ( length != DNS_ATMA_MAX_ADDR_LENGTH )
|
|
{
|
|
Dns_RecordListFree( precord );
|
|
return NULL;
|
|
}
|
|
|
|
for ( iter = 0; iter < length; iter++ )
|
|
{
|
|
char temp[3];
|
|
|
|
temp[0] = addrBuffer[(2*iter)];
|
|
temp[1] = addrBuffer[(2*iter) + 1];
|
|
temp[2] = 0;
|
|
|
|
precord->Data.ATMA.Address[iter] = (char) strtoul( temp, NULL, 16 );
|
|
}
|
|
|
|
precord->wDataLength = (WORD) length;
|
|
}
|
|
|
|
return( precord );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Wins_RecordBuild(
|
|
IN DWORD Argc,
|
|
IN PCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build WINS record from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
DWORD ipCount = Argc - 3;
|
|
PDWORD pdword;
|
|
PIP4_ADDRESS pip;
|
|
|
|
if ( Argc < 4 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
|
|
precord = Dns_AllocateRecord( (WORD) DNS_WINS_RECORD_LENGTH((WORD) ipCount) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// read integer data
|
|
//
|
|
// DCR_ENHANCE: could check for non-conversion in strtoul
|
|
//
|
|
|
|
pdword = &precord->Data.WINS.dwMappingFlag;
|
|
|
|
while ( Argc > ipCount )
|
|
{
|
|
*pdword = (DWORD) strtoul( Argv[0], NULL, 10 );
|
|
pdword++;
|
|
Argv++;
|
|
Argc--;
|
|
}
|
|
|
|
*pdword = ipCount;
|
|
|
|
//
|
|
// convert IP addresses
|
|
//
|
|
|
|
pip = precord->Data.WINS.WinsServers;
|
|
|
|
while ( Argc-- )
|
|
{
|
|
if ( ! Dns_Ip4StringToAddress_A(
|
|
pip,
|
|
Argv[0] ) )
|
|
{
|
|
Dns_RecordFree( precord );
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return NULL;
|
|
}
|
|
pip++;
|
|
Argv++;
|
|
}
|
|
|
|
return( precord );
|
|
}
|
|
|
|
|
|
PDNS_RECORD
|
|
Wins_RecordBuildW(
|
|
IN DWORD Argc,
|
|
IN PWCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build WINS record from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
DWORD ipCount = Argc - 3;
|
|
PDWORD pdword;
|
|
PIP4_ADDRESS pip;
|
|
char szAddr[256];
|
|
|
|
if ( Argc < 4 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
|
|
precord = Dns_AllocateRecord( (WORD) DNS_WINS_RECORD_LENGTH((WORD) ipCount) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// read integer data
|
|
//
|
|
// DCR_ENHANCE: could check for non-conversion in strtoul
|
|
//
|
|
|
|
pdword = &precord->Data.WINS.dwMappingFlag;
|
|
|
|
while ( Argc-- > 1 )
|
|
{
|
|
*pdword = (DWORD) wcstoul( Argv[0], NULL, 10 );
|
|
pdword++;
|
|
Argv++;
|
|
}
|
|
|
|
*pdword = ipCount;
|
|
|
|
//
|
|
// convert IP addresses
|
|
//
|
|
|
|
pip = precord->Data.WINS.WinsServers;
|
|
|
|
while ( Argc-- )
|
|
{
|
|
if ( ! Dns_Ip4StringToAddress_W(
|
|
pip,
|
|
Argv[0] ) )
|
|
{
|
|
Dns_RecordFree( precord );
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return NULL;
|
|
}
|
|
pip++;
|
|
Argv++;
|
|
}
|
|
|
|
return( precord );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Winsr_RecordBuild(
|
|
IN DWORD Argc,
|
|
IN PCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build WINSR record from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
PDWORD pdword;
|
|
|
|
if ( Argc != 4 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
|
|
precord = Dns_AllocateRecord( sizeof(DNS_WINSR_DATA) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// read integer data
|
|
//
|
|
// DCR_ENHANCE: could check for non-conversion in strtoul
|
|
//
|
|
|
|
pdword = &precord->Data.WINSR.dwMappingFlag;
|
|
|
|
while( Argc-- > 1 )
|
|
{
|
|
*pdword = (WORD) strtoul( Argv[0], NULL, 10 );
|
|
pdword++;
|
|
Argv++;
|
|
}
|
|
|
|
//
|
|
// result domain
|
|
//
|
|
|
|
precord->Data.WINSR.pNameResultDomain = Argv[0];
|
|
|
|
return( precord );
|
|
}
|
|
|
|
|
|
PDNS_RECORD
|
|
Winsr_RecordBuildW(
|
|
IN DWORD Argc,
|
|
IN PWCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build WINSR record from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
PDWORD pdword;
|
|
|
|
if ( Argc != 4 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
|
|
precord = Dns_AllocateRecord( sizeof(DNS_WINSR_DATA) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// read integer data
|
|
//
|
|
// DCR_ENHANCE: could check for non-conversion in strtoul
|
|
//
|
|
|
|
pdword = &precord->Data.WINSR.dwMappingFlag;
|
|
|
|
while( Argc-- > 1 )
|
|
{
|
|
*pdword = (WORD) wcstoul( Argv[0], NULL, 10 );
|
|
pdword++;
|
|
Argv++;
|
|
}
|
|
|
|
//
|
|
// result domain
|
|
//
|
|
|
|
precord->Data.WINSR.pNameResultDomain = (PDNS_NAME) Argv[0];
|
|
|
|
return( precord );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Wks_RecordBuild(
|
|
IN DWORD Argc,
|
|
IN PCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build WKS record from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
DWORD byteCount = 0;
|
|
DWORD i;
|
|
PCHAR pch;
|
|
WSADATA wsaData;
|
|
DNS_STATUS status;
|
|
struct protoent * pProtoent;
|
|
|
|
|
|
if ( Argc < 3 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
|
|
i = 2;
|
|
while ( i < Argc)
|
|
{
|
|
byteCount += strlen( Argv[i] ) + 1;
|
|
i++;
|
|
}
|
|
byteCount++; //bBitMasks[0] : string length
|
|
|
|
//
|
|
// allocate space for WKS
|
|
//
|
|
|
|
precord = Dns_AllocateRecord( (WORD)DNS_WKS_RECORD_LENGTH(byteCount) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// get protocol number:
|
|
//
|
|
|
|
// start winsock:
|
|
//
|
|
// DCR: this is busted, winsock should be started by now
|
|
status = WSAStartup( DNS_WINSOCK_VERSION, &wsaData );
|
|
if ( status == SOCKET_ERROR )
|
|
{
|
|
Dns_RecordFree( precord );
|
|
status = WSAGetLastError();
|
|
SetLastError( status );
|
|
return( NULL );
|
|
}
|
|
|
|
pProtoent = getprotobyname( Argv[0] );
|
|
|
|
if ( ! pProtoent || pProtoent->p_proto >= MAXUCHAR )
|
|
{
|
|
Dns_RecordFree( precord );
|
|
status = WSAGetLastError();
|
|
SetLastError( status );
|
|
return( NULL );
|
|
}
|
|
|
|
precord->Data.WKS.chProtocol = (UCHAR) pProtoent->p_proto;
|
|
|
|
//
|
|
// get ipAddresss:
|
|
//
|
|
|
|
precord->Data.WKS.IpAddress = inet_addr( Argv[1] );
|
|
|
|
//
|
|
// get the services, put all in one string
|
|
//
|
|
|
|
pch = precord->Data.WKS.BitMask;
|
|
|
|
(UCHAR) *pch = (UCHAR) byteCount-1; //string length
|
|
pch++;
|
|
|
|
|
|
i = 2;
|
|
strcpy( pch, Argv[i] );
|
|
while ( ++i < Argc )
|
|
{
|
|
strcat( pch, " " );
|
|
strcat( pch, Argv[i] );
|
|
}
|
|
|
|
return( precord );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Wks_RecordBuildW(
|
|
IN DWORD Argc,
|
|
IN PWCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build WKS record from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
DWORD byteCount = 0;
|
|
DWORD i;
|
|
PWCHAR pch;
|
|
WSADATA wsaData;
|
|
DNS_STATUS status;
|
|
struct protoent * pProtoent;
|
|
char szAddr[256];
|
|
WCHAR tcpStr[4], udpStr[4], space[2];
|
|
|
|
if ( Argc < 3 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
|
|
i = 2;
|
|
while ( i < Argc)
|
|
{
|
|
byteCount += wcslen( Argv[i] ) + 1;
|
|
i++;
|
|
}
|
|
byteCount++; //bBitMasks[0] : string length
|
|
|
|
//
|
|
// allocate space for WKS
|
|
//
|
|
|
|
precord = Dns_AllocateRecord( (WORD)DNS_WKS_RECORD_LENGTH(byteCount) );
|
|
if ( !precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// get protocol number
|
|
//
|
|
|
|
status = WSAStartup( DNS_WINSOCK_VERSION, &wsaData );
|
|
if ( status == SOCKET_ERROR )
|
|
{
|
|
Dns_RecordFree( precord );
|
|
status = WSAGetLastError();
|
|
SetLastError( status );
|
|
return( NULL );
|
|
}
|
|
|
|
|
|
#if 0
|
|
//
|
|
// DCR_FIX: WKS build
|
|
//
|
|
|
|
if ( ! Dns_CopyStringEx( szAddr, 0, (PCHAR) Argv[0], 0, TRUE, FALSE ) )
|
|
{
|
|
Dns_RecordListFree( precord );
|
|
return NULL;
|
|
}
|
|
|
|
pProtoent = getprotobyname( szAddr );
|
|
|
|
if ( ! pProtoent || pProtoent->p_proto >= MAXUCHAR )
|
|
{
|
|
Dns_RecordFree( precord );
|
|
status = WSAGetLastError();
|
|
SetLastError( status );
|
|
return( NULL );
|
|
}
|
|
|
|
precord->Data.WKS.chProtocol = (UCHAR) pProtoent->p_proto;
|
|
|
|
//
|
|
// IP Address
|
|
//
|
|
|
|
if ( ! Dns_CopyStringEx( szAddr, 0, (PCHAR) Argv[0], 0, TRUE, FALSE ) )
|
|
{
|
|
Dns_RecordListFree( precord );
|
|
return NULL;
|
|
}
|
|
|
|
precord->Data.WKS.IpAddress = inet_addr( szAddr );
|
|
|
|
//
|
|
// get the services, put all in one string
|
|
//
|
|
|
|
pch = (PWCHAR) precord->Data.WKS.bBitMask;
|
|
|
|
(UCHAR) *pch = (UCHAR) byteCount-1;
|
|
pch++;
|
|
|
|
i = 2;
|
|
if ( ! Dns_NameCopy(
|
|
(PBYTE) space,
|
|
0,
|
|
" ",
|
|
0,
|
|
DnsCharSetUnicode,
|
|
DnsCharSetWire ) )
|
|
{
|
|
Dns_RecordListFree( precord );
|
|
return NULL;
|
|
}
|
|
|
|
wcscpy( pch, Argv[i] );
|
|
while ( ++i < Argc )
|
|
{
|
|
wcscat( pch, space );
|
|
wcscat( pch, Argv[i] );
|
|
}
|
|
#endif
|
|
|
|
return( precord );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Key_RecordBuild(
|
|
IN DWORD Argc,
|
|
IN PCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build KEY record from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD prec;
|
|
int keyStringLength;
|
|
DWORD keyLength = 0;
|
|
|
|
if ( Argc != 4 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return NULL;
|
|
}
|
|
|
|
keyStringLength = strlen( Argv[ 3 ] );
|
|
|
|
prec = Dns_AllocateRecord( (WORD)
|
|
sizeof( DNS_KEY_DATA ) + keyStringLength );
|
|
if ( !prec )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
prec->Data.KEY.wFlags = (WORD) strtoul( *( Argv++ ), NULL, 0 );
|
|
prec->Data.KEY.chProtocol = (BYTE) strtoul( *( Argv++ ), NULL, 10 );
|
|
prec->Data.KEY.chAlgorithm = (BYTE) strtoul( *( Argv++ ), NULL, 10 );
|
|
Argc -= 3;
|
|
|
|
Dns_SecurityBase64StringToKey(
|
|
prec->Data.KEY.Key,
|
|
&keyLength,
|
|
*Argv,
|
|
keyStringLength );
|
|
Argc--;
|
|
Argv++;
|
|
|
|
prec->wDataLength = (WORD) ( SIZEOF_KEY_FIXED_DATA + keyLength );
|
|
|
|
return prec;
|
|
} // Key_RecordBuild
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Key_RecordBuildW(
|
|
IN DWORD Argc,
|
|
IN PWCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build KEY record from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD prec;
|
|
int keyStringLength;
|
|
DWORD keyLength = 0;
|
|
|
|
if ( Argc != 4 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return NULL;
|
|
}
|
|
|
|
keyStringLength = wcslen( Argv[ 3 ] );
|
|
|
|
prec = Dns_AllocateRecord( (WORD)
|
|
sizeof( DNS_KEY_DATA ) + keyStringLength / 2 );
|
|
if ( !prec )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
prec->Data.KEY.wFlags = (WORD) wcstoul( *( Argv++ ), NULL, 0 );
|
|
prec->Data.KEY.chProtocol = (BYTE) wcstoul( *( Argv++ ), NULL, 10 );
|
|
prec->Data.KEY.chAlgorithm = (BYTE) wcstoul( *( Argv++ ), NULL, 10 );
|
|
Argc -= 3;
|
|
|
|
#if 0
|
|
// JJW: MUST COPY BUFFER???
|
|
Dns_SecurityBase64StringToKey(
|
|
prec->Data.KEY.Key,
|
|
&keyLength,
|
|
*Argv,
|
|
keyStringLength );
|
|
#endif
|
|
Argc--;
|
|
Argv++;
|
|
|
|
prec->wDataLength = (WORD) ( SIZEOF_KEY_FIXED_DATA + keyLength );
|
|
|
|
return prec;
|
|
} // Key_RecordBuildW
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Sig_RecordBuild(
|
|
IN DWORD Argc,
|
|
IN PCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build SIG record from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD prec;
|
|
int sigStringLength;
|
|
DWORD sigLength = 0;
|
|
|
|
if ( Argc != 9 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return NULL;
|
|
}
|
|
|
|
sigStringLength = strlen( Argv[8] );
|
|
|
|
prec = Dns_AllocateRecord( (WORD)
|
|
( sizeof(DNS_SIG_DATA) + sigStringLength ) );
|
|
if ( !prec )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
prec->Data.SIG.wTypeCovered = Dns_RecordTypeForName( *( Argv++ ), 0 );
|
|
prec->Data.SIG.chAlgorithm = (BYTE) strtoul( *( Argv++ ), NULL, 10 );
|
|
prec->Data.Sig.chLabelCount = (BYTE) strtoul( *( Argv++ ), NULL, 10 );
|
|
prec->Data.SIG.dwOriginalTtl = ( DWORD ) strtoul( *( Argv++ ), NULL, 10 );
|
|
prec->Data.SIG.dwExpiration = Dns_ParseSigTime( *( Argv++ ), 0 );
|
|
prec->Data.SIG.dwTimeSigned = Dns_ParseSigTime( *( Argv++ ), 0 );
|
|
prec->Data.SIG.wKeyTag = (WORD) strtoul( *( Argv++ ), NULL, 10 );
|
|
prec->Data.SIG.pNameSigner = *( Argv++ );
|
|
|
|
Argc -= 8;
|
|
|
|
//
|
|
// Validate signature times.
|
|
//
|
|
|
|
if ( prec->Data.SIG.dwExpiration == 0 ||
|
|
prec->Data.SIG.dwTimeSigned == 0 ||
|
|
prec->Data.SIG.dwTimeSigned >= prec->Data.SIG.dwExpiration )
|
|
{
|
|
Dns_RecordFree( prec );
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Parse signature.
|
|
//
|
|
|
|
if ( Dns_SecurityBase64StringToKey(
|
|
prec->Data.SIG.Signature,
|
|
&sigLength,
|
|
*Argv,
|
|
sigStringLength ) != ERROR_SUCCESS )
|
|
{
|
|
Dns_RecordFree( prec );
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return NULL;
|
|
}
|
|
|
|
Argc--;
|
|
Argv++;
|
|
|
|
prec->wDataLength = (WORD) ( sizeof( DNS_SIG_DATA ) - 4 + sigLength );
|
|
|
|
return prec;
|
|
} // Sig_RecordBuild
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Sig_RecordBuildW(
|
|
IN DWORD Argc,
|
|
IN PWCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build SIG record from string data.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD prec;
|
|
int sigStringLength;
|
|
DWORD sigLength = 0;
|
|
PCHAR pch;
|
|
|
|
if ( Argc != 8 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return NULL;
|
|
}
|
|
|
|
sigStringLength = wcslen( Argv[ 7 ] );
|
|
|
|
prec = Dns_AllocateRecord( (WORD)
|
|
( sizeof( DNS_SIG_DATA ) + sigStringLength ) );
|
|
if ( !prec )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
#if 0
|
|
// JJW: how to convert all args here???
|
|
prec->Data.SIG.wTypeCovered = Dns_RecordTypeForName( *( Argv++ ), 0 );
|
|
prec->Data.SIG.chAlgorithm = (BYTE) strtoul( *( Argv++ ), NULL, 10 );
|
|
prec->Data.Sig.chLabelCount = (BYTE) strtoul( *( Argv++ ), NULL, 10 );
|
|
prec->Data.SIG.dwOriginalTtl = ( DWORD ) strtoul( *( Argv++ ), NULL, 10 );
|
|
prec->Data.SIG.dwExpiration = Dns_ParseSigTime( *( Argv++ ), 0 );
|
|
prec->Data.SIG.dwTimeSigned = Dns_ParseSigTime( *( Argv++ ), 0 );
|
|
prec->Data.SIG.wKeyTag = (WORD) strtoul( *( Argv++ ), NULL, 10 );
|
|
prec->Data.SIG.pNameSigner = *( Argv++ );
|
|
|
|
Argc -= 8;
|
|
|
|
Dns_SecurityBase64StringToKey(
|
|
prec->Data.SIG.Signature,
|
|
&sigLength,
|
|
*Argv,
|
|
sigStringLength );
|
|
#endif
|
|
Argc--;
|
|
Argv++;
|
|
|
|
prec->wDataLength = (WORD) ( sizeof( DNS_SIG_DATA ) - 4 + sigLength );
|
|
|
|
return prec;
|
|
} // Sig_RecordBuildW
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Nxt_RecordBuild(
|
|
IN DWORD Argc,
|
|
IN PCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build NXT record from string data.
|
|
|
|
First arg is next name, followed by list of record types at that name.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD prec;
|
|
int typeIdx = 0;
|
|
|
|
if ( Argc < 2 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return NULL;
|
|
}
|
|
prec = Dns_AllocateRecord( (WORD) (
|
|
sizeof( LPTSTR ) + sizeof(WORD) * Argc ) );
|
|
if ( !prec )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
prec->Data.NXT.pNameNext = *( Argv++ );
|
|
--Argc;
|
|
|
|
prec->Data.NXT.wNumTypes = 0;
|
|
while ( Argc-- )
|
|
{
|
|
++prec->Data.NXT.wNumTypes;
|
|
prec->Data.NXT.wTypes[ typeIdx++ ] =
|
|
Dns_RecordTypeForName( *( Argv++ ), 0 );
|
|
}
|
|
|
|
return prec;
|
|
} // Nxt_RecordBuild
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Nxt_RecordBuildW(
|
|
IN DWORD Argc,
|
|
IN PWCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build NXT record from string data.
|
|
|
|
First arg is next name, followed by list of record types at that name.
|
|
|
|
Arguments:
|
|
|
|
Argc -- count of data Arguments
|
|
|
|
Argv -- argv array of data string pointers
|
|
|
|
Return Value:
|
|
|
|
Ptr to new record if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD prec;
|
|
int typeIdx = 0;
|
|
|
|
if ( Argc < 2 )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return NULL;
|
|
}
|
|
prec = Dns_AllocateRecord( (WORD) (
|
|
sizeof( LPTSTR ) + sizeof(WORD) * ( Argc - 1 ) ) );
|
|
if ( !prec )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
prec->Data.NXT.pNameNext = ( PDNS_NAME ) ( *( Argv++ ) );
|
|
--Argc;
|
|
|
|
#if 0
|
|
// JJW: convert type string???
|
|
while ( Argc-- )
|
|
{
|
|
prec->Data.NXT.wTypes[ typeIdx++ ] =
|
|
Dns_RecordTypeForName( *( Argv++ ), 0 );
|
|
}
|
|
#endif
|
|
|
|
return prec;
|
|
} // Nxt_RecordBuildW
|
|
|
|
|
|
|
|
//
|
|
// RR build routines jump table
|
|
//
|
|
|
|
typedef PDNS_RECORD (* RR_BUILD_FUNCTION)(
|
|
DWORD,
|
|
PCHAR * );
|
|
|
|
//extern RR_BUILD_FUNCTION RRBuildTable[];
|
|
|
|
typedef PDNS_RECORD (* RR_BUILD_FUNCTION_W)(
|
|
DWORD,
|
|
PWCHAR * );
|
|
|
|
//extern RR_BUILD_FUNCTION_W RRBuildTableW[];
|
|
|
|
|
|
RR_BUILD_FUNCTION RRBuildTable[] =
|
|
{
|
|
NULL, // ZERO
|
|
A_RecordBuild, // A
|
|
Ptr_RecordBuild, // NS
|
|
Ptr_RecordBuild, // MD
|
|
Ptr_RecordBuild, // MF
|
|
Ptr_RecordBuild, // CNAME
|
|
Soa_RecordBuild, // SOA
|
|
Ptr_RecordBuild, // MB
|
|
Ptr_RecordBuild, // MG
|
|
Ptr_RecordBuild, // MR
|
|
NULL, // NULL
|
|
Wks_RecordBuild, // WKS
|
|
Ptr_RecordBuild, // PTR
|
|
Txt_RecordBuild, // HINFO
|
|
Minfo_RecordBuild, // MINFO
|
|
Mx_RecordBuild, // MX
|
|
Txt_RecordBuild, // TXT
|
|
Minfo_RecordBuild, // RP
|
|
Mx_RecordBuild, // AFSDB
|
|
Txt_RecordBuild, // X25
|
|
Txt_RecordBuild, // ISDN
|
|
Mx_RecordBuild, // RT
|
|
NULL, // NSAP
|
|
NULL, // NSAPPTR
|
|
Sig_RecordBuild, // SIG
|
|
Key_RecordBuild, // KEY
|
|
NULL, // PX
|
|
NULL, // GPOS
|
|
Aaaa_RecordBuild, // AAAA
|
|
NULL, // LOC
|
|
Nxt_RecordBuild, // NXT
|
|
NULL, // EID
|
|
NULL, // NIMLOC
|
|
Srv_RecordBuild, // SRV
|
|
Atma_RecordBuild, // ATMA
|
|
NULL, // NAPTR
|
|
NULL, // KX
|
|
NULL, // CERT
|
|
NULL, // A6
|
|
NULL, // DNAME
|
|
NULL, // SINK
|
|
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)
|
|
|
|
//
|
|
// Pseudo record types
|
|
//
|
|
|
|
NULL, // TKEY
|
|
NULL, // TSIG
|
|
|
|
//
|
|
// MS only types
|
|
//
|
|
|
|
Wins_RecordBuild, // WINS
|
|
Winsr_RecordBuild, // WINSR
|
|
};
|
|
|
|
|
|
RR_BUILD_FUNCTION_W RRBuildTableW[] =
|
|
{
|
|
NULL, // ZERO
|
|
A_RecordBuildW, // A
|
|
Ptr_RecordBuildW, // NS
|
|
Ptr_RecordBuildW, // MD
|
|
Ptr_RecordBuildW, // MF
|
|
Ptr_RecordBuildW, // CNAME
|
|
Soa_RecordBuildW, // SOA
|
|
Ptr_RecordBuildW, // MB
|
|
Ptr_RecordBuildW, // MG
|
|
Ptr_RecordBuildW, // MR
|
|
NULL, // NULL
|
|
Wks_RecordBuildW, // WKS
|
|
Ptr_RecordBuildW, // PTR
|
|
Txt_RecordBuildW, // HINFO
|
|
Minfo_RecordBuildW, // MINFO
|
|
Mx_RecordBuildW, // MX
|
|
Txt_RecordBuildW, // TXT
|
|
Minfo_RecordBuildW, // RP
|
|
Mx_RecordBuildW, // AFSDB
|
|
Txt_RecordBuildW, // X25
|
|
Txt_RecordBuildW, // ISDN
|
|
Mx_RecordBuildW, // RT
|
|
NULL, // NSAP
|
|
NULL, // NSAPPTR
|
|
Sig_RecordBuildW, // SIG
|
|
Key_RecordBuildW, // KEY
|
|
NULL, // PX
|
|
NULL, // GPOS
|
|
Aaaa_RecordBuildW, // AAAA
|
|
NULL, // LOC
|
|
Nxt_RecordBuildW, // NXT
|
|
NULL, // EID
|
|
NULL, // NIMLOC
|
|
Srv_RecordBuildW, // SRV
|
|
Atma_RecordBuildW, // ATMA
|
|
NULL, // NAPTR
|
|
NULL, // KX
|
|
NULL, // CERT
|
|
NULL, // A6
|
|
NULL, // DNAME
|
|
NULL, // SINK
|
|
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)
|
|
|
|
//
|
|
// Pseudo record types
|
|
//
|
|
|
|
NULL, // TKEY
|
|
NULL, // TSIG
|
|
|
|
//
|
|
// MS only types
|
|
//
|
|
|
|
Wins_RecordBuildW, // WINS
|
|
Winsr_RecordBuildW, // WINSR
|
|
};
|
|
|
|
|
|
|
|
//
|
|
// Public build routine
|
|
//
|
|
|
|
PDNS_RECORD
|
|
Dns_RecordBuild_A(
|
|
IN OUT PDNS_RRSET pRRSet,
|
|
IN LPSTR pszOwner,
|
|
IN WORD wType,
|
|
IN BOOL fAdd,
|
|
IN UCHAR Section,
|
|
IN INT Argc,
|
|
IN PCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build record from data strings.
|
|
|
|
Arguments:
|
|
|
|
pRRSet -- ptr to RR set structure being built
|
|
|
|
pszOwner -- DNS name of RR owner
|
|
|
|
wType -- record type
|
|
|
|
fAdd -- add\delete, exist\no-exist flag
|
|
|
|
Section -- RR section for record
|
|
|
|
Argc -- count of data strings
|
|
|
|
Argv -- argv array of ptrs to data strings
|
|
|
|
Return Value:
|
|
|
|
Ptr to record built.
|
|
NULL on error.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
WORD index;
|
|
|
|
IF_DNSDBG( INIT )
|
|
{
|
|
DNS_PRINT((
|
|
"Dns_RecordBuild()\n"
|
|
"\trrset = %p\n"
|
|
"\towner = %s\n"
|
|
"\ttype = %d\n"
|
|
"\tfAdd = %d\n"
|
|
"\tsection = %d\n"
|
|
"\targc = %d\n",
|
|
pRRSet,
|
|
pszOwner,
|
|
wType,
|
|
fAdd,
|
|
Section,
|
|
Argc ));
|
|
}
|
|
|
|
//
|
|
// every record MUST have owner name
|
|
//
|
|
|
|
if ( !pszOwner )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// if no data, no dispatch required
|
|
//
|
|
|
|
if ( Argc == 0 )
|
|
{
|
|
precord = Dns_AllocateRecord( 0 );
|
|
if ( ! precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
}
|
|
|
|
// have data, dispatch to type specific build routine
|
|
|
|
else
|
|
{
|
|
index = INDEX_FOR_TYPE( wType );
|
|
DNS_ASSERT( index <= MAX_RECORD_TYPE_INDEX );
|
|
|
|
if ( !index || !RRBuildTable[ index ] )
|
|
{
|
|
// can NOT build unknown types
|
|
|
|
SetLastError( DNS_ERROR_INVALID_TYPE );
|
|
DNS_PRINT((
|
|
"ERROR: can not build record of type %d\n",
|
|
wType ));
|
|
return( NULL );
|
|
}
|
|
|
|
precord = RRBuildTable[ index ](
|
|
Argc,
|
|
Argv );
|
|
if ( ! precord )
|
|
{
|
|
DNS_PRINT((
|
|
"ERROR: Record build routine failure for record type %d.\n"
|
|
"\tstatus = %d\n\n",
|
|
wType,
|
|
GetLastError() ));
|
|
if ( !GetLastError() )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
}
|
|
return( NULL );
|
|
}
|
|
}
|
|
|
|
//
|
|
// fill out record structure
|
|
//
|
|
|
|
precord->pName = pszOwner;
|
|
precord->wType = wType;
|
|
precord->Flags.S.Section = Section;
|
|
precord->Flags.S.Delete = !fAdd;
|
|
precord->Flags.S.CharSet = DnsCharSetAnsi;
|
|
|
|
IF_DNSDBG( INIT )
|
|
{
|
|
DnsDbg_Record(
|
|
"New record built\n",
|
|
precord );
|
|
}
|
|
|
|
//
|
|
// link into existing RR set (if any)
|
|
//
|
|
|
|
if ( pRRSet )
|
|
{
|
|
DNS_RRSET_ADD( *pRRSet, precord );
|
|
}
|
|
return( precord );
|
|
}
|
|
|
|
|
|
|
|
PDNS_RECORD
|
|
Dns_RecordBuild_W(
|
|
IN OUT PDNS_RRSET pRRSet,
|
|
IN LPWSTR pszOwner,
|
|
IN WORD wType,
|
|
IN BOOL fAdd,
|
|
IN UCHAR Section,
|
|
IN INT Argc,
|
|
IN PWCHAR * Argv
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Build record from data strings.
|
|
|
|
Arguments:
|
|
|
|
pRRSet -- ptr to RR set structure being built
|
|
|
|
pszOwner -- DNS name of RR owner
|
|
|
|
wType -- record type
|
|
|
|
fAdd -- add\delete, exist\no-exist flag
|
|
|
|
Section -- RR section for record
|
|
|
|
Argc -- count of data strings
|
|
|
|
Argv -- argv array of ptrs to data strings
|
|
|
|
Return Value:
|
|
|
|
Ptr to record built.
|
|
NULL on error.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RECORD precord;
|
|
WORD index;
|
|
|
|
DNSDBG( INIT, (
|
|
"Dns_RecordBuild()\n"
|
|
"\trrset = %p\n"
|
|
"\towner = %S\n"
|
|
"\ttype = %d\n"
|
|
"\tfAdd = %d\n"
|
|
"\tsection = %d\n"
|
|
"\targc = %d\n",
|
|
pRRSet,
|
|
pszOwner,
|
|
wType,
|
|
fAdd,
|
|
Section,
|
|
Argc ));
|
|
|
|
//
|
|
// every record MUST have owner name
|
|
//
|
|
|
|
if ( !pszOwner )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// if no data, no dispatch required
|
|
//
|
|
|
|
if ( Argc == 0 )
|
|
{
|
|
precord = Dns_AllocateRecord( 0 );
|
|
if ( ! precord )
|
|
{
|
|
return( NULL );
|
|
}
|
|
}
|
|
|
|
// have data, dispatch to type specific build routine
|
|
|
|
else
|
|
{
|
|
index = INDEX_FOR_TYPE( wType );
|
|
DNS_ASSERT( index <= MAX_RECORD_TYPE_INDEX );
|
|
|
|
if ( !index || !RRBuildTableW[ index ] )
|
|
{
|
|
// can NOT build unknown types
|
|
|
|
SetLastError( DNS_ERROR_INVALID_TYPE );
|
|
DNS_PRINT((
|
|
"ERROR: can not build record of type %d\n",
|
|
wType ));
|
|
return( NULL );
|
|
}
|
|
|
|
precord = RRBuildTableW[ index ](
|
|
Argc,
|
|
Argv );
|
|
if ( ! precord )
|
|
{
|
|
DNS_PRINT((
|
|
"ERROR: Record build routine failure for record type %d.\n"
|
|
"\tstatus = %d\n\n",
|
|
wType,
|
|
GetLastError() ));
|
|
|
|
if ( !GetLastError() )
|
|
{
|
|
SetLastError( ERROR_INVALID_DATA );
|
|
}
|
|
return( NULL );
|
|
}
|
|
}
|
|
|
|
//
|
|
// fill out record structure
|
|
//
|
|
|
|
precord->pName = (PDNS_NAME) pszOwner;
|
|
precord->wType = wType;
|
|
precord->Flags.S.Section = Section;
|
|
precord->Flags.S.Delete = !fAdd;
|
|
precord->Flags.S.CharSet = DnsCharSetUnicode;
|
|
|
|
IF_DNSDBG( INIT )
|
|
{
|
|
DnsDbg_Record(
|
|
"New record built\n",
|
|
precord );
|
|
}
|
|
|
|
//
|
|
// link into existing RR set (if any)
|
|
//
|
|
|
|
if ( pRRSet )
|
|
{
|
|
DNS_RRSET_ADD( *pRRSet, precord );
|
|
}
|
|
return( precord );
|
|
}
|
|
|
|
|
|
//
|
|
// End rrbuild.c
|
|
//
|