2802 lines
50 KiB
C
2802 lines
50 KiB
C
/*++
|
||
|
||
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 RR build routine prototypes
|
||
//
|
||
|
||
PDNS_RECORD
|
||
ARecordBuild(
|
||
IN DWORD Argc,
|
||
IN PCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
ARecordBuildW(
|
||
IN DWORD Argc,
|
||
IN PWCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
PtrRecordBuild(
|
||
IN DWORD Argc,
|
||
IN PCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
PtrRecordBuildW(
|
||
IN DWORD Argc,
|
||
IN PWCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
MxRecordBuild(
|
||
IN DWORD Argc,
|
||
IN PCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
MxRecordBuildW(
|
||
IN DWORD Argc,
|
||
IN PWCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
SoaRecordBuild(
|
||
IN DWORD Argc,
|
||
IN PCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
SoaRecordBuildW(
|
||
IN DWORD Argc,
|
||
IN PWCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
TxtRecordBuild(
|
||
IN DWORD Argc,
|
||
IN PCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
TxtRecordBuildW(
|
||
IN DWORD Argc,
|
||
IN PWCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
MinfoRecordBuild(
|
||
IN DWORD Argc,
|
||
IN PCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
MinfoRecordBuildW(
|
||
IN DWORD Argc,
|
||
IN PWCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
SrvRecordBuild(
|
||
IN DWORD Argc,
|
||
IN PCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
SrvRecordBuildW(
|
||
IN DWORD Argc,
|
||
IN PWCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
AtmaRecordBuild(
|
||
IN DWORD Argc,
|
||
IN PCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
AtmaRecordBuildW(
|
||
IN DWORD Argc,
|
||
IN PWCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
AaaaRecordBuild(
|
||
IN DWORD Argc,
|
||
IN PCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
AaaaRecordBuildW(
|
||
IN DWORD Argc,
|
||
IN PWCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
WinsRecordBuild(
|
||
IN DWORD Argc,
|
||
IN PCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
WinsRecordBuildW(
|
||
IN DWORD Argc,
|
||
IN PWCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
WinsrRecordBuild(
|
||
IN DWORD Argc,
|
||
IN PCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
WinsrRecordBuildW(
|
||
IN DWORD Argc,
|
||
IN PWCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
WksRecordBuild(
|
||
IN DWORD Argc,
|
||
IN PCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
WksRecordBuildW(
|
||
IN DWORD Argc,
|
||
IN PWCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
SigRecordBuild(
|
||
IN DWORD Argc,
|
||
IN PCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
SigRecordBuildW(
|
||
IN DWORD Argc,
|
||
IN PWCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
KeyRecordBuild(
|
||
IN DWORD Argc,
|
||
IN PCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
KeyRecordBuildW(
|
||
IN DWORD Argc,
|
||
IN PWCHAR * Argv
|
||
);
|
||
|
||
PDNS_RECORD
|
||
NxtRecordBuild(
|
||
IN DWORD Argc,
|
||
IN PCHAR * Argv
|
||
);
|
||
PDNS_RECORD
|
||
NxtRecordBuildW(
|
||
IN DWORD Argc,
|
||
IN PWCHAR * Argv
|
||
);
|
||
|
||
|
||
|
||
//
|
||
// RR build routines jump table
|
||
//
|
||
|
||
RR_BUILD_FUNCTION RRBuildTable[] =
|
||
{
|
||
NULL, // ZERO
|
||
ARecordBuild, // A
|
||
PtrRecordBuild, // NS
|
||
PtrRecordBuild, // MD
|
||
PtrRecordBuild, // MF
|
||
PtrRecordBuild, // CNAME
|
||
SoaRecordBuild, // SOA
|
||
PtrRecordBuild, // MB
|
||
PtrRecordBuild, // MG
|
||
PtrRecordBuild, // MR
|
||
NULL, // NULL
|
||
WksRecordBuild, // WKS
|
||
PtrRecordBuild, // PTR
|
||
TxtRecordBuild, // HINFO
|
||
MinfoRecordBuild, // MINFO
|
||
MxRecordBuild, // MX
|
||
TxtRecordBuild, // TXT
|
||
MinfoRecordBuild, // RP
|
||
MxRecordBuild, // AFSDB
|
||
TxtRecordBuild, // X25
|
||
TxtRecordBuild, // ISDN
|
||
MxRecordBuild, // RT
|
||
NULL, // NSAP
|
||
NULL, // NSAPPTR
|
||
SigRecordBuild, // SIG
|
||
KeyRecordBuild, // KEY
|
||
NULL, // PX
|
||
NULL, // GPOS
|
||
AaaaRecordBuild, // AAAA
|
||
NULL, // LOC
|
||
NxtRecordBuild, // NXT
|
||
NULL, // EID
|
||
NULL, // NIMLOC
|
||
SrvRecordBuild, // SRV
|
||
AtmaRecordBuild, // 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
|
||
//
|
||
|
||
WinsRecordBuild, // WINS
|
||
WinsrRecordBuild, // WINSR
|
||
};
|
||
|
||
|
||
RR_BUILD_FUNCTION_W RRBuildTableW[] =
|
||
{
|
||
NULL, // ZERO
|
||
ARecordBuildW, // A
|
||
PtrRecordBuildW, // NS
|
||
PtrRecordBuildW, // MD
|
||
PtrRecordBuildW, // MF
|
||
PtrRecordBuildW, // CNAME
|
||
SoaRecordBuildW, // SOA
|
||
PtrRecordBuildW, // MB
|
||
PtrRecordBuildW, // MG
|
||
PtrRecordBuildW, // MR
|
||
NULL, // NULL
|
||
WksRecordBuildW, // WKS
|
||
PtrRecordBuildW, // PTR
|
||
TxtRecordBuildW, // HINFO
|
||
MinfoRecordBuildW, // MINFO
|
||
MxRecordBuildW, // MX
|
||
TxtRecordBuildW, // TXT
|
||
MinfoRecordBuildW, // RP
|
||
MxRecordBuildW, // AFSDB
|
||
TxtRecordBuildW, // X25
|
||
TxtRecordBuildW, // ISDN
|
||
MxRecordBuildW, // RT
|
||
NULL, // NSAP
|
||
NULL, // NSAPPTR
|
||
SigRecordBuildW, // SIG
|
||
KeyRecordBuildW, // KEY
|
||
NULL, // PX
|
||
NULL, // GPOS
|
||
AaaaRecordBuildW, // AAAA
|
||
NULL, // LOC
|
||
NxtRecordBuildW, // NXT
|
||
NULL, // EID
|
||
NULL, // NIMLOC
|
||
SrvRecordBuildW, // SRV
|
||
AtmaRecordBuildW, // 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
|
||
//
|
||
|
||
WinsRecordBuildW, // WINS
|
||
WinsrRecordBuildW, // WINSR
|
||
};
|
||
|
||
|
||
|
||
PDNS_RECORD
|
||
ARecordBuild(
|
||
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
|
||
ARecordBuildW(
|
||
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
|
||
PtrRecordBuild(
|
||
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
|
||
PtrRecordBuildW(
|
||
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
|
||
MxRecordBuild(
|
||
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
|
||
MxRecordBuildW(
|
||
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
|
||
SoaRecordBuild(
|
||
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
|
||
SoaRecordBuildW(
|
||
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
|
||
MinfoRecordBuild(
|
||
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
|
||
MinfoRecordBuildW(
|
||
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
|
||
TxtRecordBuild(
|
||
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
|
||
TxtRecordBuildW(
|
||
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
|
||
AaaaRecordBuild(
|
||
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
|
||
AaaaRecordBuildW(
|
||
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
|
||
SrvRecordBuild(
|
||
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
|
||
SrvRecordBuildW(
|
||
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
|
||
AtmaRecordBuild(
|
||
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
|
||
AtmaRecordBuildW(
|
||
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
|
||
WinsRecordBuild(
|
||
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;
|
||
PIP_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
|
||
WinsRecordBuildW(
|
||
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;
|
||
PIP_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
|
||
WinsrRecordBuild(
|
||
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
|
||
WinsrRecordBuildW(
|
||
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
|
||
WksRecordBuild(
|
||
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
|
||
WksRecordBuildW(
|
||
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
|
||
KeyRecordBuild(
|
||
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;
|
||
} // KeyRecordBuild
|
||
|
||
|
||
|
||
PDNS_RECORD
|
||
KeyRecordBuildW(
|
||
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;
|
||
} // KeyRecordBuildW
|
||
|
||
|
||
|
||
PDNS_RECORD
|
||
SigRecordBuild(
|
||
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;
|
||
} // SigRecordBuild
|
||
|
||
|
||
|
||
PDNS_RECORD
|
||
SigRecordBuildW(
|
||
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;
|
||
} // SigRecordBuildW
|
||
|
||
|
||
|
||
PDNS_RECORD
|
||
NxtRecordBuild(
|
||
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;
|
||
} // NxtRecordBuild
|
||
|
||
|
||
|
||
PDNS_RECORD
|
||
NxtRecordBuildW(
|
||
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;
|
||
} // NxtRecordBuildW
|
||
|
||
|
||
|
||
//
|
||
// 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
|
||
//
|