windows-nt/Source/XPSP1/NT/ds/dns/dnslib/rrwrite.c

740 lines
13 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1997-2000 Microsoft Corporation
Module Name:
rrwrite.c
Abstract:
Domain Name System (DNS) Library
Write resource record to packet routines.
Author:
Jim Gilroy (jamesg) January, 1997
Revision History:
--*/
#include "local.h"
PCHAR
ARecordWrite(
IN OUT PDNS_RECORD pRR,
IN PCHAR pch,
IN PCHAR pchEnd
)
/*++
Routine Description:
Write A record data to packet.
Arguments:
pRR - ptr to record to write
pch - ptr to position in buffer to write
pchEnd - end of buffer position
Return Value:
Ptr to next byte in buffer to write.
NULL on error. (Error code through GetLastError())
--*/
{
if ( pch + sizeof(IP_ADDRESS) > pchEnd )
{
SetLastError( ERROR_MORE_DATA );
return( NULL );
}
*(UNALIGNED DWORD *) pch = pRR->Data.A.IpAddress;
return ( pch + sizeof(IP_ADDRESS) );
}
PCHAR
PtrRecordWrite(
IN OUT PDNS_RECORD pRR,
IN PCHAR pch,
IN PCHAR pchEnd
)
/*++
Routine Description:
Write PTR compatible record data to packet.
Includes: PTR, CNAME, MB, MR, MG, MD, MF
Arguments:
pRR - ptr to record to write
pch - ptr to position in buffer to write
pchEnd - end of buffer position
Return Value:
Ptr to next byte in buffer to write.
NULL on error. (Error code through GetLastError())
--*/
{
//
// write name to packet
// - no compression in data
//
pch = Dns_WriteDottedNameToPacket(
pch,
pchEnd,
pRR->Data.PTR.pNameHost,
NULL,
0,
IS_UNICODE_RECORD(pRR) );
if ( !pch )
{
SetLastError( ERROR_MORE_DATA );
}
return( pch );
}
PCHAR
SoaRecordWrite(
IN OUT PDNS_RECORD pRR,
IN PCHAR pch,
IN PCHAR pchEnd
)
/*++
Routine Description:
Write SOA compatible to wire.
Arguments:
pRR - ptr to record to write
pch - ptr to position in buffer to write
pchEnd - end of buffer position
Return Value:
Ptr to next byte in buffer to write.
NULL on error. (Error code through GetLastError())
--*/
{
PCHAR pchdone;
PDWORD pdword;
//
// SOA names: primary server, responsible party
//
pch = Dns_WriteDottedNameToPacket(
pch,
pchEnd,
pRR->Data.SOA.pNamePrimaryServer,
NULL,
0,
IS_UNICODE_RECORD(pRR) );
if ( !pch )
{
SetLastError( ERROR_MORE_DATA );
return( NULL );
}
pch = Dns_WriteDottedNameToPacket(
pch,
pchEnd,
pRR->Data.SOA.pNameAdministrator,
NULL,
0,
IS_UNICODE_RECORD(pRR) );
if ( !pch )
{
SetLastError( ERROR_MORE_DATA );
return( NULL );
}
//
// SOA integer fields
//
pchdone = pch + SIZEOF_SOA_FIXED_DATA;
if ( pchdone > pchEnd )
{
SetLastError( ERROR_MORE_DATA );
return( NULL );
}
pdword = &pRR->Data.SOA.dwSerialNo;
while( pch < pchdone )
{
*(UNALIGNED DWORD *) pch = htonl( *pdword++ );
pch += sizeof( DWORD );
}
return( pch );
}
PCHAR
MxRecordWrite(
IN OUT PDNS_RECORD pRR,
IN PCHAR pch,
IN PCHAR pchEnd
)
/*++
Routine Description:
Write MX compatible record to wire.
Includes: MX, RT, AFSDB
Arguments:
pRR - ptr to record to write
pch - ptr to position in buffer to write
pchEnd - end of buffer position
Return Value:
Ptr to next byte in buffer to write.
NULL on error. (Error code through GetLastError())
--*/
{
//
// MX preference value
// RT preference
// AFSDB subtype
//
if ( pch + sizeof(WORD) > pchEnd )
{
SetLastError( ERROR_MORE_DATA );
return( NULL );
}
*(UNALIGNED WORD *) pch = htons( pRR->Data.MX.wPreference );
pch += sizeof( WORD );
//
// MX exchange
// RT exchange
// AFSDB hostname
//
pch = Dns_WriteDottedNameToPacket(
pch,
pchEnd,
pRR->Data.MX.pNameExchange,
NULL,
0,
IS_UNICODE_RECORD(pRR) );
if ( !pch )
{
SetLastError( ERROR_MORE_DATA );
}
return( pch );
}
PCHAR
TxtRecordWrite(
IN OUT PDNS_RECORD pRR,
IN PCHAR pch,
IN PCHAR pchEnd
)
/*++
Routine Description:
Write TXT compatible record to wire.
Includes: TXT, HINFO, ISDN, X25 types.
Arguments:
pRR - ptr to record to write
pch - ptr to position in buffer to write
pchEnd - end of buffer position
Return Value:
Ptr to next byte in buffer to write.
NULL on error. (Error code through GetLastError())
--*/
{
WORD i;
PCHAR * ppstring;
//
// write all available text strings
//
i = (WORD) pRR->Data.TXT.dwStringCount;
if ( ! Dns_IsStringCountValidForTextType( pRR->wType, i ) )
{
SetLastError( ERROR_INVALID_DATA );
return( NULL );
}
ppstring = pRR->Data.TXT.pStringArray;
while ( i-- )
{
pch = Dns_WriteStringToPacket(
pch,
pchEnd,
*ppstring,
IS_UNICODE_RECORD(pRR) );
if ( !pch )
{
SetLastError( ERROR_MORE_DATA );
break;
}
ppstring++;
}
return( pch );
}
PCHAR
HinfoRecordWrite(
IN OUT PDNS_RECORD pRR,
IN PCHAR pch,
IN PCHAR pchEnd
)
/*++
Routine Description:
Write HINFO (string like) record to wire.
Includes: HINFO, ISDN, X25 types.
Arguments:
pRR - ptr to record to write
pch - ptr to position in buffer to write
pchEnd - end of buffer position
Return Value:
Ptr to next byte in buffer to write.
NULL on error. (Error code through GetLastError())
--*/
{
WORD i;
PCHAR * ppstring;
//
// write all available text strings
//
// DCR: ISDN HINFO write -- not sure works
// not sure this works, because NULL may need to
// be written for ISDN or even HINFO
//
i = 2;
if ( pRR->wType == DNS_TYPE_X25 )
{
i=1;
}
ppstring = (PSTR *) & pRR->Data.TXT;
while ( i-- )
{
if ( ! *ppstring )
{
break;
}
pch = Dns_WriteStringToPacket(
pch,
pchEnd,
*ppstring,
IS_UNICODE_RECORD(pRR) );
if ( !pch )
{
SetLastError( ERROR_MORE_DATA );
break;
}
ppstring++;
}
return( pch );
}
PCHAR
MinfoRecordWrite(
IN OUT PDNS_RECORD pRR,
IN PCHAR pch,
IN PCHAR pchEnd
)
/*++
Routine Description:
Write MINFO compatible to wire.
Includes MINFO and RP types.
Arguments:
pRR - ptr to record to write
pch - ptr to position in buffer to write
pchEnd - end of buffer position
Return Value:
Ptr to next byte in buffer to write.
NULL on error. (Error code through GetLastError())
--*/
{
//
// MINFO responsible mailbox
// RP responsible person mailbox
pch = Dns_WriteDottedNameToPacket(
pch,
pchEnd,
pRR->Data.MINFO.pNameMailbox,
NULL,
0,
IS_UNICODE_RECORD(pRR) );
if ( !pch )
{
SetLastError( ERROR_MORE_DATA );
return( NULL );
}
//
// MINFO errors to mailbox
// RP text RR location
pch = Dns_WriteDottedNameToPacket(
pch,
pchEnd,
pRR->Data.MINFO.pNameErrorsMailbox,
NULL,
0,
IS_UNICODE_RECORD(pRR) );
if ( !pch )
{
SetLastError( ERROR_MORE_DATA );
return( NULL );
}
return( pch );
}
PCHAR
FlatRecordWrite(
IN OUT PDNS_RECORD pRR,
IN PCHAR pch,
IN PCHAR pchEnd
)
/*++
Routine Description:
Write flat record type data to packet.
Flat types include:
AAAA
WINS
Arguments:
pRR - ptr to record to write
pch - ptr to position in buffer to write
pchEnd - end of buffer position
Return Value:
Ptr to next byte in buffer to write.
NULL on error. (Error code through GetLastError())
--*/
{
WORD length = pRR->wDataLength;
if ( pch + length > pchEnd )
{
SetLastError( ERROR_MORE_DATA );
return( NULL );
}
memcpy(
pch,
(PCHAR)&pRR->Data,
length );
pch += length;
return( pch );
}
PCHAR
SrvRecordWrite(
IN OUT PDNS_RECORD pRR,
IN PCHAR pch,
IN PCHAR pchEnd
)
/*++
Routine Description:
Write SRV record to wire.
Arguments:
pRR - ptr to record to write
pch - ptr to position in buffer to write
pchEnd - end of buffer position
Return Value:
Ptr to next byte in buffer to write.
NULL on error. (Error code through GetLastError())
--*/
{
PCHAR pchname;
PWORD pword;
//
// SRV integer values
//
pchname = pch + SIZEOF_SRV_FIXED_DATA;
if ( pchname > pchEnd )
{
SetLastError( ERROR_MORE_DATA );
return( NULL );
}
pword = &pRR->Data.SRV.wPriority;
while ( pch < pchname )
{
*(UNALIGNED WORD *) pch = htons( *pword++ );
pch += sizeof(WORD);
}
//
// SRV target host
//
pch = Dns_WriteDottedNameToPacket(
pch,
pchEnd,
pRR->Data.SRV.pNameTarget,
NULL,
0,
IS_UNICODE_RECORD(pRR) );
if ( !pch )
{
SetLastError( ERROR_MORE_DATA );
}
return( pch );
}
PCHAR
AtmaRecordWrite(
IN OUT PDNS_RECORD pRR,
IN PCHAR pch,
IN PCHAR pchEnd
)
/*++
Routine Description:
Write ATMA record to wire.
Arguments:
pRR - ptr to record to write
pch - ptr to position in buffer to write
pchEnd - end of buffer position
Return Value:
Ptr to next byte in buffer to write.
NULL on error. (Error code through GetLastError())
--*/
{
PBYTE pbyte;
//
// ATMA integer values
//
if ( ( pch + sizeof( DNS_ATMA_DATA ) + DNS_ATMA_MAX_ADDR_LENGTH ) >
pchEnd )
{
SetLastError( ERROR_MORE_DATA );
return( NULL );
}
pbyte = &pRR->Data.ATMA.AddressType;
*(BYTE *) pch = *pbyte;
pch += sizeof( BYTE );
//
// write ATMA address
//
memcpy( pch,
(PCHAR)&pRR->Data.ATMA.Address,
pRR->wDataLength );
pch += pRR->wDataLength;
return( pch );
}
//
// stubs until read to go
//
PCHAR
TkeyRecordWrite(
IN OUT PDNS_RECORD pRR,
IN PCHAR pch,
IN PCHAR pchEnd
)
{
return( NULL );
}
PCHAR
TsigRecordWrite(
IN OUT PDNS_RECORD pRR,
IN PCHAR pch,
IN PCHAR pchEnd
)
{
return( NULL );
}
//
// RR write to packet jump table
//
RR_WRITE_FUNCTION RRWriteTable[] =
{
NULL, // ZERO
ARecordWrite, // A
PtrRecordWrite, // NS
PtrRecordWrite, // MD
PtrRecordWrite, // MF
PtrRecordWrite, // CNAME
SoaRecordWrite, // SOA
PtrRecordWrite, // MB
PtrRecordWrite, // MG
PtrRecordWrite, // MR
NULL, // NULL
NULL, //WksRecordWrite, // WKS
PtrRecordWrite, // PTR
TxtRecordWrite, // HINFO
MinfoRecordWrite, // MINFO
MxRecordWrite, // MX
TxtRecordWrite, // TXT
MinfoRecordWrite, // RP
MxRecordWrite, // AFSDB
TxtRecordWrite, // X25
TxtRecordWrite, // ISDN
MxRecordWrite, // RT
NULL, // NSAP
NULL, // NSAPPTR
NULL, // SIG
NULL, // KEY
NULL, // PX
NULL, // GPOS
FlatRecordWrite, // AAAA
NULL, // LOC
NULL, // NXT
NULL, // EID
NULL, // NIMLOC
SrvRecordWrite, // SRV
AtmaRecordWrite, // 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
//
TkeyRecordWrite, // TKEY
TsigRecordWrite, // TSIG
//
// MS only types
//
FlatRecordWrite, // WINS
NULL, // WINSR
};
//
// End rrwire.c
//