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.
989 lines
20 KiB
989 lines
20 KiB
/*++
|
|
|
|
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(IP4_ADDRESS) )
|
|
{
|
|
PrintRoutine(
|
|
pContext,
|
|
"\tIP address = %s\n",
|
|
IP4_STRING(pRecord->Data.A.IpAddress) );
|
|
}
|
|
else if ( dataLength % sizeof(DNS_A_DATA) )
|
|
{
|
|
printBadDataLength( PrintRoutine, pContext, pRecord );
|
|
}
|
|
else // multiple records
|
|
{
|
|
PIP4_ADDRESS pip = &pRecord->Data.A.IpAddress;
|
|
|
|
DnsPrint_Lock();
|
|
while ( dataLength )
|
|
{
|
|
PrintRoutine(
|
|
pContext,
|
|
"\tIP address = %s\n",
|
|
IP4_STRING(*pip) );
|
|
dataLength -= sizeof(IP4_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,
|
|
(PIP6_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
|
|
//
|
|
|
|
typedef VOID (* RR_PRINT_FUNCTION)(
|
|
PRINT_ROUTINE,
|
|
PPRINT_CONTEXT,
|
|
PDNS_RECORD );
|
|
|
|
// extern RR_PRINT_FUNCTION RRPrintTable[];
|
|
|
|
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 that make set (section)
|
|
|
|
if ( pPreviousRecord &&
|
|
(!pRecord->pName || pPreviousRecord->pName == pRecord->pName) &&
|
|
pPreviousRecord->wType == type &&
|
|
pPreviousRecord->Flags.S.Section == pRecord->Flags.S.Section )
|
|
{
|
|
PrintRoutine(
|
|
pContext,
|
|
" Next record in set:\n"
|
|
"\tPtr = %p, pNext = %p\n"
|
|
"\tFlags = %08x\n"
|
|
"\tTTL = %d\n"
|
|
"\tReserved = %d\n"
|
|
"\tDataLength = %d\n",
|
|
pRecord,
|
|
pRecord->pNext,
|
|
pRecord->Flags.DW,
|
|
pRecord->dwTtl,
|
|
pRecord->dwReserved,
|
|
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 = %08x\n"
|
|
"\t\tSection = %d\n"
|
|
"\t\tDelete = %d\n"
|
|
"\t\tCharSet = %d\n"
|
|
"\tTTL = %d\n"
|
|
"\tReserved = %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,
|
|
pRecord->dwReserved,
|
|
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
|
|
//
|