|
|
/*++
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 A_RecordWrite( 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(IP4_ADDRESS) > pchEnd ) { SetLastError( ERROR_MORE_DATA ); return( NULL ); }
*(UNALIGNED DWORD *) pch = pRR->Data.A.IpAddress;
return ( pch + sizeof(IP4_ADDRESS) ); }
PCHAR Ptr_RecordWrite( 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 Soa_RecordWrite( 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 Mx_RecordWrite( 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 Txt_RecordWrite( 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 Hinfo_RecordWrite( 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 Minfo_RecordWrite( 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 Flat_RecordWrite( 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 Srv_RecordWrite( 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 Atma_RecordWrite( 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 Tkey_RecordWrite( IN OUT PDNS_RECORD pRR, IN PCHAR pch, IN PCHAR pchEnd ) { return( NULL ); }
PCHAR Tsig_RecordWrite( IN OUT PDNS_RECORD pRR, IN PCHAR pch, IN PCHAR pchEnd ) { return( NULL ); }
//
// RR write to packet jump table
//
RR_WRITE_FUNCTION RR_WriteTable[] = { NULL, // ZERO
A_RecordWrite, // A
Ptr_RecordWrite, // NS
Ptr_RecordWrite, // MD
Ptr_RecordWrite, // MF
Ptr_RecordWrite, // CNAME
Soa_RecordWrite, // SOA
Ptr_RecordWrite, // MB
Ptr_RecordWrite, // MG
Ptr_RecordWrite, // MR
NULL, // NULL
NULL, //Wks_RecordWrite, // WKS
Ptr_RecordWrite, // PTR
Txt_RecordWrite, // HINFO
Minfo_RecordWrite, // MINFO
Mx_RecordWrite, // MX
Txt_RecordWrite, // TXT
Minfo_RecordWrite, // RP
Mx_RecordWrite, // AFSDB
Txt_RecordWrite, // X25
Txt_RecordWrite, // ISDN
Mx_RecordWrite, // RT
NULL, // NSAP
NULL, // NSAPPTR
NULL, // SIG
NULL, // KEY
NULL, // PX
NULL, // GPOS
Flat_RecordWrite, // AAAA
NULL, // LOC
NULL, // NXT
NULL, // EID
NULL, // NIMLOC
Srv_RecordWrite, // SRV
Atma_RecordWrite, // 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
//
Tkey_RecordWrite, // TKEY
Tsig_RecordWrite, // TSIG
//
// MS only types
//
Flat_RecordWrite, // WINS
NULL, // WINSR
};
//
// End rrwire.c
//
|