976 lines
19 KiB
C
976 lines
19 KiB
C
/*++
|
||
|
||
Copyright (c) 1997-2000 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
rrprint.c
|
||
|
||
Abstract:
|
||
|
||
Domain Name System (DNS) Library
|
||
|
||
Print resource record routines.
|
||
|
||
Author:
|
||
|
||
Jim Gilroy (jamesg) February, 1997
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
|
||
#include "local.h"
|
||
|
||
//
|
||
// Private prototypes
|
||
//
|
||
|
||
VOID
|
||
printBadDataLength(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN OUT PPRINT_CONTEXT pContext,
|
||
IN PDNS_RECORD pRecord
|
||
);
|
||
|
||
|
||
|
||
VOID
|
||
ARecordPrint(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN OUT PPRINT_CONTEXT pContext,
|
||
IN PDNS_RECORD pRecord
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Print A records.
|
||
|
||
Arguments:
|
||
|
||
PrintRoutine -- routine to print with
|
||
|
||
pRecord -- record to print
|
||
|
||
Return Value:
|
||
|
||
TRUE if record data equal
|
||
FALSE otherwise
|
||
|
||
--*/
|
||
{
|
||
WORD dataLength = pRecord->wDataLength;
|
||
|
||
if ( dataLength == sizeof(IP_ADDRESS) )
|
||
{
|
||
PrintRoutine(
|
||
pContext,
|
||
"\tIP address = %s\n",
|
||
IP_STRING(pRecord->Data.A.IpAddress) );
|
||
}
|
||
else if ( dataLength % sizeof(DNS_A_DATA) )
|
||
{
|
||
printBadDataLength( PrintRoutine, pContext, pRecord );
|
||
}
|
||
else // multiple records
|
||
{
|
||
PIP_ADDRESS pip = &pRecord->Data.A.IpAddress;
|
||
DnsPrint_Lock();
|
||
while ( dataLength )
|
||
{
|
||
PrintRoutine(
|
||
pContext,
|
||
"\tIP address = %s\n",
|
||
IP_STRING(*pip) );
|
||
dataLength -= sizeof(IP_ADDRESS);
|
||
pip++;
|
||
}
|
||
DnsPrint_Unlock();
|
||
}
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
PtrRecordPrint(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN OUT PPRINT_CONTEXT pContext,
|
||
IN PDNS_RECORD pRecord
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Print PTR compatible record.
|
||
Includes: NS, PTR, CNAME, MB, MR, MG, MD, MF
|
||
|
||
Arguments:
|
||
|
||
PrintRoutine -- routine to print with
|
||
|
||
pRecord -- record to print
|
||
|
||
Return Value:
|
||
|
||
TRUE if record data equal
|
||
FALSE otherwise
|
||
|
||
--*/
|
||
{
|
||
PrintRoutine(
|
||
pContext,
|
||
"\tHostName = %s%S\n",
|
||
RECSTRING_UTF8( pRecord, pRecord->Data.PTR.pNameHost ),
|
||
RECSTRING_WIDE( pRecord, pRecord->Data.PTR.pNameHost )
|
||
);
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
MxRecordPrint(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN OUT PPRINT_CONTEXT pContext,
|
||
IN PDNS_RECORD pRecord
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Print MX compatible record.
|
||
Includes: MX, RT, AFSDB
|
||
|
||
Arguments:
|
||
|
||
PrintRoutine -- routine to print with
|
||
|
||
pRecord -- record to print
|
||
|
||
Return Value:
|
||
|
||
TRUE if record data equal
|
||
FALSE otherwise
|
||
|
||
--*/
|
||
{
|
||
PrintRoutine(
|
||
pContext,
|
||
"\tPreference = %d\n"
|
||
"\tExchange = %s%S\n",
|
||
pRecord->Data.MX.wPreference,
|
||
RECSTRING_UTF8( pRecord, pRecord->Data.MX.pNameExchange ),
|
||
RECSTRING_WIDE( pRecord, pRecord->Data.MX.pNameExchange )
|
||
);
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
SoaRecordPrint(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN OUT PPRINT_CONTEXT pContext,
|
||
IN PDNS_RECORD pRecord
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Print SOA record.
|
||
|
||
Arguments:
|
||
|
||
PrintRoutine -- routine to print with
|
||
|
||
pRecord -- record to print
|
||
|
||
Return Value:
|
||
|
||
TRUE if record data equal
|
||
FALSE otherwise
|
||
|
||
--*/
|
||
{
|
||
PrintRoutine(
|
||
pContext,
|
||
"\tPrimary = %s%S\n"
|
||
"\tAdmin = %s%S\n"
|
||
"\tSerial = %d\n"
|
||
"\tRefresh = %d\n"
|
||
"\tRetry = %d\n"
|
||
"\tExpire = %d\n"
|
||
"\tDefault TTL = %d\n",
|
||
RECSTRING_UTF8( pRecord, pRecord->Data.SOA.pNamePrimaryServer ),
|
||
RECSTRING_WIDE( pRecord, pRecord->Data.SOA.pNamePrimaryServer ),
|
||
RECSTRING_UTF8( pRecord, pRecord->Data.SOA.pNameAdministrator ),
|
||
RECSTRING_WIDE( pRecord, pRecord->Data.SOA.pNameAdministrator ),
|
||
pRecord->Data.SOA.dwSerialNo,
|
||
pRecord->Data.SOA.dwRefresh,
|
||
pRecord->Data.SOA.dwRetry,
|
||
pRecord->Data.SOA.dwExpire,
|
||
pRecord->Data.SOA.dwDefaultTtl );
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
MinfoRecordPrint(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN OUT PPRINT_CONTEXT pContext,
|
||
IN PDNS_RECORD pRecord
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Print MINFO and RP records.
|
||
|
||
Arguments:
|
||
|
||
PrintRoutine -- routine to print with
|
||
|
||
pRecord -- record to print
|
||
|
||
Return Value:
|
||
|
||
TRUE if record data equal
|
||
FALSE otherwise
|
||
|
||
--*/
|
||
{
|
||
PrintRoutine(
|
||
pContext,
|
||
"\tMailbox = %s%S\n"
|
||
"\tErrorsMbox = %s%S\n",
|
||
RECSTRING_UTF8( pRecord, pRecord->Data.MINFO.pNameMailbox ),
|
||
RECSTRING_WIDE( pRecord, pRecord->Data.MINFO.pNameMailbox ),
|
||
RECSTRING_UTF8( pRecord, pRecord->Data.MINFO.pNameErrorsMailbox ),
|
||
RECSTRING_WIDE( pRecord, pRecord->Data.MINFO.pNameErrorsMailbox )
|
||
);
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
TxtRecordPrint(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN OUT PPRINT_CONTEXT pContext,
|
||
IN PDNS_RECORD pRecord
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Print TXT compatible records.
|
||
Includes: TXT, X25, HINFO, ISDN
|
||
|
||
Arguments:
|
||
|
||
PrintRoutine -- routine to print with
|
||
|
||
pRecord -- record to print
|
||
|
||
Return Value:
|
||
|
||
TRUE if record data equal
|
||
FALSE otherwise
|
||
|
||
--*/
|
||
{
|
||
LPTSTR * ppstring;
|
||
INT i;
|
||
INT count;
|
||
|
||
count = pRecord->Data.TXT.dwStringCount;
|
||
ppstring = pRecord->Data.TXT.pStringArray;
|
||
|
||
DnsPrint_Lock();
|
||
PrintRoutine(
|
||
pContext,
|
||
"\tStringCount = %d\n",
|
||
count );
|
||
|
||
for( i=1; i<=count; i++ )
|
||
{
|
||
PrintRoutine(
|
||
pContext,
|
||
"\tString[%d] = %s%S\n",
|
||
i,
|
||
RECSTRING_UTF8( pRecord, *ppstring ),
|
||
RECSTRING_WIDE( pRecord, *ppstring )
|
||
);
|
||
ppstring++;
|
||
}
|
||
DnsPrint_Unlock();
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
AaaaRecordPrint(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN OUT PPRINT_CONTEXT pContext,
|
||
IN PDNS_RECORD pRecord
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Print flat data records.
|
||
Includes AAAA type.
|
||
|
||
Arguments:
|
||
|
||
PrintRoutine -- routine to print with
|
||
|
||
pRecord -- record to print
|
||
|
||
Return Value:
|
||
|
||
TRUE if record data equal
|
||
FALSE otherwise
|
||
|
||
--*/
|
||
{
|
||
CHAR ip6String[ IP6_ADDRESS_STRING_LENGTH ];
|
||
|
||
Dns_Ip6AddressToString_A(
|
||
ip6String,
|
||
(PDNS_IP6_ADDRESS) &pRecord->Data.AAAA.Ip6Address );
|
||
|
||
PrintRoutine(
|
||
pContext,
|
||
"\tIP6 Address = %s\n",
|
||
ip6String );
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
SrvRecordPrint(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN OUT PPRINT_CONTEXT pContext,
|
||
IN PDNS_RECORD pRecord
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Print SRV record.
|
||
|
||
Arguments:
|
||
|
||
PrintRoutine -- routine to print with
|
||
|
||
pRecord -- record to print
|
||
|
||
Return Value:
|
||
|
||
TRUE if record data equal
|
||
FALSE otherwise
|
||
|
||
--*/
|
||
{
|
||
PrintRoutine(
|
||
pContext,
|
||
"\tPriority = %d\n"
|
||
"\tWeight = %d\n"
|
||
"\tPort = %d\n"
|
||
"\tTarget Host = %s%S\n",
|
||
pRecord->Data.SRV.wPriority,
|
||
pRecord->Data.SRV.wWeight,
|
||
pRecord->Data.SRV.wPort,
|
||
RECSTRING_UTF8( pRecord, pRecord->Data.SRV.pNameTarget ),
|
||
RECSTRING_WIDE( pRecord, pRecord->Data.SRV.pNameTarget )
|
||
);
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
AtmaRecordPrint(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN OUT PPRINT_CONTEXT pContext,
|
||
IN PDNS_RECORD pRecord
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Print ATMA record.
|
||
|
||
Arguments:
|
||
|
||
PrintRoutine -- routine to print with
|
||
|
||
pRecord -- record to print
|
||
|
||
Return Value:
|
||
|
||
TRUE if record data equal
|
||
FALSE otherwise
|
||
|
||
--*/
|
||
{
|
||
PrintRoutine(
|
||
pContext,
|
||
"\tAddress type = %d\n",
|
||
pRecord->Data.ATMA.AddressType );
|
||
|
||
if ( pRecord->Data.ATMA.Address &&
|
||
pRecord->Data.ATMA.AddressType == DNS_ATMA_FORMAT_E164 )
|
||
{
|
||
PrintRoutine(
|
||
pContext,
|
||
"\tAddress = %s\n",
|
||
pRecord->Data.ATMA.Address );
|
||
}
|
||
else if ( pRecord->Data.ATMA.Address )
|
||
{
|
||
DnsPrint_RawOctets(
|
||
PrintRoutine,
|
||
pContext,
|
||
"\tAddress = ",
|
||
"\t ", // no line header
|
||
pRecord->Data.ATMA.Address,
|
||
pRecord->wDataLength - 1
|
||
);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
TsigRecordPrint(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN OUT PPRINT_CONTEXT pContext,
|
||
IN PDNS_RECORD pRecord
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Print TSIG record.
|
||
|
||
Arguments:
|
||
|
||
PrintRoutine -- routine to print with
|
||
|
||
pRecord -- record to print
|
||
|
||
Return Value:
|
||
|
||
TRUE if record data equal
|
||
FALSE otherwise
|
||
|
||
--*/
|
||
{
|
||
DnsPrint_Lock();
|
||
|
||
if ( pRecord->Data.TSIG.bPacketPointers )
|
||
{
|
||
DnsPrint_PacketName(
|
||
PrintRoutine,
|
||
pContext,
|
||
"\tAlgorithm = ",
|
||
pRecord->Data.TSIG.pAlgorithmPacket,
|
||
NULL, // no packet context
|
||
NULL,
|
||
"\n" );
|
||
}
|
||
else
|
||
{
|
||
PrintRoutine(
|
||
pContext,
|
||
"\tAlgorithm = %s%S\n",
|
||
RECSTRING_UTF8( pRecord, pRecord->Data.TSIG.pNameAlgorithm ),
|
||
RECSTRING_WIDE( pRecord, pRecord->Data.TSIG.pNameAlgorithm )
|
||
);
|
||
}
|
||
|
||
PrintRoutine(
|
||
pContext,
|
||
"\tSigned Time = %I64u\n"
|
||
"\tFudge Time = %u\n"
|
||
"\tSig Length = %u\n"
|
||
"\tSig Ptr = %p\n"
|
||
"\tXid = %u\n"
|
||
"\tError = %u\n"
|
||
"\tOtherLength = %u\n"
|
||
"\tOther Ptr = %p\n",
|
||
pRecord->Data.TSIG.i64CreateTime,
|
||
pRecord->Data.TSIG.wFudgeTime,
|
||
pRecord->Data.TSIG.wSigLength,
|
||
pRecord->Data.TSIG.pSignature,
|
||
pRecord->Data.TSIG.wOriginalXid,
|
||
pRecord->Data.TSIG.wError,
|
||
pRecord->Data.TSIG.wOtherLength,
|
||
pRecord->Data.TSIG.pOtherData
|
||
);
|
||
|
||
if ( pRecord->Data.TSIG.pSignature )
|
||
{
|
||
DnsPrint_RawOctets(
|
||
PrintRoutine,
|
||
pContext,
|
||
"Signature:",
|
||
NULL, // no line header
|
||
pRecord->Data.TSIG.pSignature,
|
||
pRecord->Data.TSIG.wSigLength
|
||
);
|
||
}
|
||
|
||
if ( pRecord->Data.TSIG.pOtherData )
|
||
{
|
||
DnsPrint_RawOctets(
|
||
PrintRoutine,
|
||
pContext,
|
||
"Other Data:",
|
||
NULL, // no line header
|
||
pRecord->Data.TSIG.pOtherData,
|
||
pRecord->Data.TSIG.wOtherLength
|
||
);
|
||
}
|
||
|
||
DnsPrint_Unlock();
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
TkeyRecordPrint(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN OUT PPRINT_CONTEXT pContext,
|
||
IN PDNS_RECORD pRecord
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Print TKEY record.
|
||
|
||
Arguments:
|
||
|
||
PrintRoutine -- routine to print with
|
||
|
||
pRecord -- record to print
|
||
|
||
Return Value:
|
||
|
||
TRUE if record data equal
|
||
FALSE otherwise
|
||
|
||
--*/
|
||
{
|
||
DnsPrint_Lock();
|
||
|
||
if ( pRecord->Data.TKEY.bPacketPointers )
|
||
{
|
||
DnsPrint_PacketName(
|
||
PrintRoutine,
|
||
pContext,
|
||
"\tAlgorithm = ",
|
||
pRecord->Data.TKEY.pAlgorithmPacket,
|
||
NULL, // no packet context
|
||
NULL,
|
||
"\n" );
|
||
}
|
||
else
|
||
{
|
||
PrintRoutine(
|
||
pContext,
|
||
"\tAlgorithm = %s%S\n",
|
||
RECSTRING_UTF8( pRecord, pRecord->Data.TKEY.pNameAlgorithm ),
|
||
RECSTRING_WIDE( pRecord, pRecord->Data.TKEY.pNameAlgorithm )
|
||
);
|
||
}
|
||
|
||
PrintRoutine(
|
||
pContext,
|
||
"\tCreate Time = %d\n"
|
||
"\tExpire Time = %d\n"
|
||
"\tMode = %d\n"
|
||
"\tError = %d\n"
|
||
"\tKey Length = %d\n"
|
||
"\tKey Ptr = %p\n"
|
||
"\tOtherLength = %d\n"
|
||
"\tOther Ptr = %p\n",
|
||
pRecord->Data.TKEY.dwCreateTime,
|
||
pRecord->Data.TKEY.dwExpireTime,
|
||
pRecord->Data.TKEY.wMode,
|
||
pRecord->Data.TKEY.wError,
|
||
pRecord->Data.TKEY.wKeyLength,
|
||
pRecord->Data.TKEY.pKey,
|
||
pRecord->Data.TKEY.wOtherLength,
|
||
pRecord->Data.TKEY.pOtherData
|
||
);
|
||
|
||
if ( pRecord->Data.TKEY.pKey )
|
||
{
|
||
DnsPrint_RawOctets(
|
||
PrintRoutine,
|
||
pContext,
|
||
"Key:",
|
||
NULL, // no line header
|
||
pRecord->Data.TKEY.pKey,
|
||
pRecord->Data.TKEY.wKeyLength
|
||
);
|
||
}
|
||
|
||
if ( pRecord->Data.TKEY.pOtherData )
|
||
{
|
||
DnsPrint_RawOctets(
|
||
PrintRoutine,
|
||
pContext,
|
||
"Other Data:",
|
||
NULL, // no line header
|
||
pRecord->Data.TKEY.pOtherData,
|
||
pRecord->Data.TKEY.wOtherLength
|
||
);
|
||
}
|
||
|
||
DnsPrint_Unlock();
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// RR Print Dispatch Table
|
||
//
|
||
|
||
RR_PRINT_FUNCTION RRPrintTable[] =
|
||
{
|
||
NULL, // ZERO
|
||
ARecordPrint, // A
|
||
PtrRecordPrint, // NS
|
||
PtrRecordPrint, // MD
|
||
PtrRecordPrint, // MF
|
||
PtrRecordPrint, // CNAME
|
||
SoaRecordPrint, // SOA
|
||
PtrRecordPrint, // MB
|
||
PtrRecordPrint, // MG
|
||
PtrRecordPrint, // MR
|
||
NULL, // NULL
|
||
NULL, //WksRecordPrint, // WKS
|
||
PtrRecordPrint, // PTR
|
||
TxtRecordPrint, // HINFO
|
||
MinfoRecordPrint, // MINFO
|
||
MxRecordPrint, // MX
|
||
TxtRecordPrint, // TXT
|
||
MinfoRecordPrint, // RP
|
||
MxRecordPrint, // AFSDB
|
||
TxtRecordPrint, // X25
|
||
TxtRecordPrint, // ISDN
|
||
MxRecordPrint, // RT
|
||
NULL, // NSAP
|
||
NULL, // NSAPPTR
|
||
NULL, // SIG
|
||
NULL, // KEY
|
||
NULL, // PX
|
||
NULL, // GPOS
|
||
AaaaRecordPrint, // AAAA
|
||
NULL, // LOC
|
||
NULL, // NXT
|
||
NULL, // EID
|
||
NULL, // NIMLOC
|
||
SrvRecordPrint, // SRV
|
||
AtmaRecordPrint, // 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
|
||
//
|
||
|
||
TkeyRecordPrint, // TKEY
|
||
TsigRecordPrint, // TSIG
|
||
|
||
//
|
||
// MS only types
|
||
//
|
||
|
||
NULL, // WINS
|
||
NULL, // WINSR
|
||
};
|
||
|
||
|
||
|
||
//
|
||
// Generic print record functions
|
||
//
|
||
|
||
VOID
|
||
DnsPrint_Record(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN OUT PPRINT_CONTEXT pContext,
|
||
IN LPSTR pszHeader,
|
||
IN PDNS_RECORD pRecord,
|
||
IN PDNS_RECORD pPreviousRecord OPTIONAL
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Print record.
|
||
|
||
Arguments:
|
||
|
||
PrintRoutine -- routine to print with
|
||
|
||
pszHeader -- header message
|
||
|
||
pRecord -- record to print
|
||
|
||
pPreviousRecord -- previous record in RR set (if any)
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
WORD type = pRecord->wType;
|
||
WORD dataLength = pRecord->wDataLength;
|
||
WORD index;
|
||
|
||
DnsPrint_Lock();
|
||
|
||
if ( pszHeader )
|
||
{
|
||
PrintRoutine(
|
||
pContext,
|
||
pszHeader );
|
||
}
|
||
|
||
if ( !pRecord )
|
||
{
|
||
PrintRoutine(
|
||
pContext,
|
||
"ERROR: Null record ptr to print!\n" );
|
||
goto Unlock;
|
||
}
|
||
|
||
//
|
||
// print record info
|
||
//
|
||
// same as previous -- skip duplicated info
|
||
// must match
|
||
// - name ptr (or have no name)
|
||
// - type
|
||
// - flags (hence section)
|
||
|
||
if ( pPreviousRecord &&
|
||
(!pRecord->pName || pPreviousRecord->pName == pRecord->pName) &&
|
||
pPreviousRecord->wType == type &&
|
||
*(PWORD)&pPreviousRecord->Flags.DW == *(PWORD)&pRecord->Flags.DW )
|
||
{
|
||
PrintRoutine(
|
||
pContext,
|
||
" Next record in set:\n"
|
||
"\tPtr = %p, pNext = %p\n"
|
||
"\tTTL = %d\n"
|
||
"\tDataLength = %d\n",
|
||
pRecord,
|
||
pRecord->pNext,
|
||
pRecord->dwTtl,
|
||
dataLength );
|
||
}
|
||
|
||
//
|
||
// different from previous -- full print
|
||
//
|
||
|
||
else
|
||
{
|
||
PrintRoutine(
|
||
pContext,
|
||
" Record:\n"
|
||
"\tPtr = %p, pNext = %p\n"
|
||
"\tOwner = %s%S\n"
|
||
"\tType = %s (%d)\n"
|
||
"\tFlags = %hx\n"
|
||
"\t\tSection = %d\n"
|
||
"\t\tDelete = %d\n"
|
||
"\t\tCharSet = %d\n"
|
||
"\tTTL = %d\n"
|
||
"\tDataLength = %d\n",
|
||
pRecord,
|
||
pRecord->pNext,
|
||
RECSTRING_UTF8( pRecord, pRecord->pName ),
|
||
RECSTRING_WIDE( pRecord, pRecord->pName ),
|
||
Dns_RecordStringForType( type ),
|
||
type,
|
||
pRecord->Flags.DW,
|
||
pRecord->Flags.S.Section,
|
||
pRecord->Flags.S.Delete,
|
||
pRecord->Flags.S.CharSet,
|
||
pRecord->dwTtl,
|
||
dataLength );
|
||
}
|
||
|
||
//
|
||
// if no data -- done
|
||
//
|
||
|
||
if ( ! dataLength )
|
||
{
|
||
goto Unlock;
|
||
}
|
||
|
||
//
|
||
// print data
|
||
//
|
||
|
||
index = INDEX_FOR_TYPE( type );
|
||
DNS_ASSERT( index <= MAX_RECORD_TYPE_INDEX );
|
||
|
||
if ( index && RRPrintTable[ index ] )
|
||
{
|
||
RRPrintTable[ index ](
|
||
PrintRoutine,
|
||
pContext,
|
||
pRecord );
|
||
}
|
||
else if ( !index )
|
||
{
|
||
PrintRoutine(
|
||
pContext,
|
||
"\tUnknown type: can not print data\n" );
|
||
}
|
||
else
|
||
{
|
||
// DCR: should do raw bytes print
|
||
PrintRoutine(
|
||
pContext,
|
||
"\tNo print routine for this type\n" );
|
||
}
|
||
|
||
Unlock:
|
||
|
||
DnsPrint_Unlock();
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
printBadDataLength(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN OUT PPRINT_CONTEXT pContext,
|
||
IN PDNS_RECORD pRecord
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Prints waring on bad data in record.
|
||
|
||
Arguments:
|
||
|
||
PrintRoutine -- routine to print with
|
||
|
||
pRecord -- record with bad data
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
PrintRoutine(
|
||
pContext,
|
||
"\tERROR: Invalid record data length for this type.\n" );
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
DnsPrint_RecordSet(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN OUT PPRINT_CONTEXT pContext,
|
||
IN LPSTR pszHeader,
|
||
IN PDNS_RECORD pRecord
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Print record set.
|
||
|
||
Arguments:
|
||
|
||
PrintRoutine -- routine to print with
|
||
|
||
pRecord -- record set to print
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
PDNS_RECORD pprevious;
|
||
|
||
DnsPrint_Lock();
|
||
if ( pszHeader )
|
||
{
|
||
PrintRoutine(
|
||
pContext,
|
||
pszHeader );
|
||
}
|
||
if ( !pRecord )
|
||
{
|
||
PrintRoutine(
|
||
pContext,
|
||
" No Records in list.\n" );
|
||
goto Unlock;
|
||
}
|
||
|
||
//
|
||
// print all records in set
|
||
//
|
||
|
||
pprevious = NULL;
|
||
|
||
while ( pRecord )
|
||
{
|
||
DnsPrint_Record(
|
||
PrintRoutine,
|
||
pContext,
|
||
NULL,
|
||
pRecord,
|
||
pprevious );
|
||
|
||
pprevious = pRecord;
|
||
pRecord = pRecord->pNext;
|
||
}
|
||
PrintRoutine(
|
||
pContext,
|
||
"\n" );
|
||
|
||
Unlock:
|
||
|
||
DnsPrint_Unlock();
|
||
}
|
||
|
||
//
|
||
// End rrprint.c
|
||
//
|