Leaked source code of windows server 2003
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.
 
 
 
 
 
 

4216 lines
117 KiB

/*++
Copyright (c) 1995-2000 Microsoft Corporation
Module Name:
print.c
Abstract:
Domain Name System (DNS) Server RPC Library
Print routines for RPC types
Author:
Jim Gilroy (jamesg) September 1995
Revision History:
--*/
#include "dnsclip.h"
#include <time.h>
#define DNS_NOT_APPLICABLE "N/A"
#define DNS_NOT_APPLICABLE_W L"N/A"
#define DNS_NOT_PERFORMED "not since restart"
//
// Winsock version: copied from socket.c
//
#ifndef DNS_WINSOCK2
#define DNS_WINSOCK_VERSION (0x0101) // Winsock 1.1
#else // Winsock2
#define DNS_WINSOCK_VERSION (0x0002) // Winsock 2.0
#endif
//
// Tagged memory stat strings
//
// NT5 shipped version
//
LPSTR MemTagStringsNT5[] =
{
MEMTAG_NAME_NONE ,
MEMTAG_NAME_RECORD ,
MEMTAG_NAME_NODE ,
MEMTAG_NAME_NAME ,
MEMTAG_NAME_ZONE ,
MEMTAG_NAME_UPDATE ,
MEMTAG_NAME_TIMEOUT ,
MEMTAG_NAME_STUFF ,
MEMTAG_NAME_NODEHASH ,
MEMTAG_NAME_DS_DN ,
MEMTAG_NAME_DS_MOD ,
MEMTAG_NAME_DS_RECORD ,
MEMTAG_NAME_NODE_COPY ,
MEMTAG_NAME_PACKET_UDP ,
MEMTAG_NAME_PACKET_TCP ,
MEMTAG_NAME_DNSLIB ,
MEMTAG_NAME_TABLE ,
MEMTAG_NAME_SOCKET ,
MEMTAG_NAME_CONNECTION ,
MEMTAG_NAME_REGISTRY ,
MEMTAG_NAME_RPC ,
MEMTAG_NAME_NBSTAT ,
MEMTAG_NAME_FILEBUF ,
MEMTAG_NAME_DS_OTHER ,
MEMTAG_NAME_THREAD ,
MEMTAG_NAME_UPDATE_LIST ,
MEMTAG_NAME_SAFE ,
NULL, // safety
NULL,
NULL,
NULL
};
// NT5 SP1 version
LPSTR MemTagStrings[] =
{
MEMTAG_NAME_NONE ,
MEMTAG_NAME_PACKET_UDP ,
MEMTAG_NAME_PACKET_TCP ,
MEMTAG_NAME_NAME ,
MEMTAG_NAME_ZONE ,
MEMTAG_NAME_UPDATE ,
MEMTAG_NAME_UPDATE_LIST ,
MEMTAG_NAME_TIMEOUT ,
MEMTAG_NAME_NODEHASH ,
MEMTAG_NAME_DS_DN ,
MEMTAG_NAME_DS_MOD , // 10
MEMTAG_NAME_DS_RECORD ,
MEMTAG_NAME_DS_OTHER ,
MEMTAG_NAME_THREAD ,
MEMTAG_NAME_NBSTAT ,
MEMTAG_NAME_DNSLIB ,
MEMTAG_NAME_TABLE ,
MEMTAG_NAME_SOCKET ,
MEMTAG_NAME_CONNECTION ,
MEMTAG_NAME_REGISTRY ,
MEMTAG_NAME_RPC , // 20
MEMTAG_NAME_STUFF ,
MEMTAG_NAME_FILEBUF ,
MEMTAG_NAME_REMOTE ,
MEMTAG_NAME_SAFE ,
MEMTAG_NAME_RECORD ,
MEMTAG_NAME_RECORD_FILE ,
MEMTAG_NAME_RECORD_DS ,
MEMTAG_NAME_RECORD_AXFR ,
MEMTAG_NAME_RECORD_IXFR ,
MEMTAG_NAME_RECORD_DYNUP , // 30
MEMTAG_NAME_RECORD_ADMIN ,
MEMTAG_NAME_RECORD_AUTO ,
MEMTAG_NAME_RECORD_CACHE ,
MEMTAG_NAME_RECORD_NOEXIST ,
MEMTAG_NAME_RECORD_WINS ,
MEMTAG_NAME_RECORD_WINSPTR ,
MEMTAG_NAME_RECORD_COPY ,
MEMTAG_NAME_NODE ,
MEMTAG_NAME_NODE_FILE ,
MEMTAG_NAME_NODE_DS , // 40
MEMTAG_NAME_NODE_AXFR ,
MEMTAG_NAME_NODE_IXFR ,
MEMTAG_NAME_NODE_DYNUP ,
MEMTAG_NAME_NODE_ADMIN ,
MEMTAG_NAME_NODE_AUTO ,
MEMTAG_NAME_NODE_CACHE ,
MEMTAG_NAME_NODE_NOEXIST ,
MEMTAG_NAME_NODE_WINS ,
MEMTAG_NAME_NODE_WINSPTR ,
MEMTAG_NAME_NODE_COPY ,
NULL, // safety
NULL,
NULL,
NULL
};
VOID
Dns_SystemHourToSystemTime(
IN DWORD dwHourTime,
IN OUT PSYSTEMTIME pSystemTime
)
/*++
Routine Description:
Converts system time in hours to SYSTEMTIME format.
Arguments:
dwHourTime -- system time in hours (hours since 1601)
pSystemTime -- ptr to SYSTEMTIME to set
Return Value:
None
--*/
{
#define FILE_TIME_INTERVALS_IN_HOUR (36000000000)
LONGLONG fileTime;
fileTime = (LONGLONG)dwHourTime * FILE_TIME_INTERVALS_IN_HOUR;
FileTimeToSystemTime( (PFILETIME)&fileTime, pSystemTime );
}
PWSTR
utf8ToUnicode(
IN PSTR pszInputStr,
IN DWORD dwInputLength
)
/*++
Routine Description:
Takes a UTF-8 string and allocates a Unicode copy of the string.
The caller must call use FREE_HEAP to deallocate the Unicode string.
Arguments:
pszInputStr -- input string, optionally NULL terminated
dwInputLength -- pass zero if pszInputStr is NULL terminated
Return Value:
NULL-terminated Unicode output string
--*/
{
PWSTR pwszoutput;
if ( pszInputStr == NULL )
{
pszInputStr = "";
dwInputLength = 0;
}
pwszoutput = Dns_StringCopyAllocate(
pszInputStr,
dwInputLength,
DnsCharSetUtf8, // UTF8 in
DnsCharSetUnicode // unicode out
);
return pwszoutput;
} // utf8ToUnicode
PWSTR
getUnicodeForUtf8(
IN PSTR pUtf8
)
/*++
Routine Description:
Takes a UTF-8 string and allocates a Unicode copy of the string.
Caller must free resulting unicode string.
Arguments:
pUtf8 -- UTF8 string
Return Value:
Ptr to unicode string.
NULL on alloc failure or invalid UTF8 string.
--*/
{
return Dns_StringCopyAllocate(
pUtf8,
0, // NULL terminated
DnsCharSetUtf8, // UTF8 in
DnsCharSetUnicode // unicode out
);
}
//
// Print server info
//
VOID
DnsPrint_RpcServerInfo(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pPrintContext,
IN LPSTR pszHeader,
IN PDNS_RPC_SERVER_INFO pServerInfo
)
{
char szTime[ 80 ] = DNS_NOT_PERFORMED;
PWSTR pnameServer = NULL;
PWSTR pnameForest = NULL;
PWSTR pnameDomain = NULL;
PWSTR pnameForestDp = NULL;
PWSTR pnameDomainDp = NULL;
DnsPrint_Lock();
if ( pszHeader )
{
PrintRoutine( pPrintContext, pszHeader );
}
if ( ! pServerInfo )
{
PrintRoutine( pPrintContext, "NULL server info ptr.\n" );
}
else
{
int majorVer = pServerInfo->dwVersion & 0x000000FF;
int minorVer = ( pServerInfo->dwVersion & 0x0000FF00 ) >> 8;
int buildNum = pServerInfo->dwVersion >> 16;
pnameServer = getUnicodeForUtf8( pServerInfo->pszServerName );
pnameForest = getUnicodeForUtf8( pServerInfo->pszForestName );
pnameDomain = getUnicodeForUtf8( pServerInfo->pszDomainName );
pnameForestDp = getUnicodeForUtf8( pServerInfo->pszForestDirectoryPartition );
pnameDomainDp = getUnicodeForUtf8( pServerInfo->pszDomainDirectoryPartition );
PrintRoutine( pPrintContext,
"Server info\n"
"\tserver name = %S\n",
pnameServer );
//
// Sanitize build number for older versions where build number is wacked.
//
if ( buildNum < 1 || buildNum > 5000 )
{
PrintRoutine( pPrintContext,
"\tversion = %08lX (%d.%d)\n",
pServerInfo->dwVersion,
majorVer,
minorVer );
}
else
{
PrintRoutine( pPrintContext,
"\tversion = %08lX (%d.%d build %d)\n",
pServerInfo->dwVersion,
majorVer,
minorVer,
buildNum );
}
PrintRoutine( pPrintContext,
"\tDS container = %S\n"
"\tforest name = %S\n"
"\tdomain name = %S\n"
"\tbuiltin domain partition = %S\n"
"\tbuiltin forest partition = %S\n",
pServerInfo->pszDsContainer ?
pServerInfo->pszDsContainer : DNS_NOT_APPLICABLE_W,
pnameForest ? pnameForest : DNS_NOT_APPLICABLE_W,
pnameDomain ? pnameDomain : DNS_NOT_APPLICABLE_W,
pnameForestDp ? pnameForestDp : DNS_NOT_APPLICABLE_W,
pnameDomainDp ? pnameDomainDp : DNS_NOT_APPLICABLE_W
);
#if DBG
PrintRoutine( pPrintContext,
"\tAD forest behavior ver = %2d (DBG only)\n"
"\tAD domain behavior ver = %2d (DBG only)\n"
"\tAD DSA behavior ver = %2d (DBG only)\n",
pServerInfo->dwDsForestVersion,
pServerInfo->dwDsDomainVersion,
pServerInfo->dwDsDsaVersion );
#endif
if ( pServerInfo->dwLastScavengeTime )
{
time_t t = pServerInfo->dwLastScavengeTime;
strcpy( szTime, ctime( &t ) );
szTime[ strlen( szTime ) - 1 ] = '\0';
}
PrintRoutine( pPrintContext,
"\tlast scavenge cycle = %s (%d)\n",
szTime,
pServerInfo->dwLastScavengeTime );
PrintRoutine( pPrintContext,
" Configuration:\n"
"\tdwLogLevel = %p\n"
"\tdwDebugLevel = %p\n"
"\tdwRpcProtocol = %p\n"
"\tdwNameCheckFlag = %p\n"
"\tcAddressAnswerLimit = %d\n"
"\tdwRecursionRetry = %d\n"
"\tdwRecursionTimeout = %d\n"
"\tdwDsPollingInterval = %d\n",
pServerInfo->dwLogLevel,
pServerInfo->dwDebugLevel,
pServerInfo->dwRpcProtocol,
pServerInfo->dwNameCheckFlag,
pServerInfo->cAddressAnswerLimit,
pServerInfo->dwRecursionRetry,
pServerInfo->dwRecursionTimeout,
pServerInfo->dwDsPollingInterval );
PrintRoutine( pPrintContext,
" Configuration Flags:\n"
"\tfBootMethod = %d\n"
"\tfAdminConfigured = %d\n"
"\tfAllowUpdate = %d\n"
"\tfDsAvailable = %d\n"
"\tfAutoReverseZones = %d\n"
"\tfAutoCacheUpdate = %d\n"
"\tfSlave = %d\n"
"\tfNoRecursion = %d\n"
"\tfRoundRobin = %d\n"
"\tfStrictFileParsing = %d\n"
"\tfLooseWildcarding = %d\n"
"\tfBindSecondaries = %d\n"
"\tfWriteAuthorityNs = %d\n"
"\tfLocalNetPriority = %d\n",
pServerInfo->fBootMethod,
pServerInfo->fAdminConfigured,
pServerInfo->fAllowUpdate,
pServerInfo->fDsAvailable,
pServerInfo->fAutoReverseZones,
pServerInfo->fAutoCacheUpdate,
pServerInfo->fSlave,
pServerInfo->fNoRecursion,
pServerInfo->fRoundRobin,
pServerInfo->fStrictFileParsing,
pServerInfo->fLooseWildcarding,
pServerInfo->fBindSecondaries,
pServerInfo->fWriteAuthorityNs,
pServerInfo->fLocalNetPriority );
PrintRoutine(
pPrintContext,
" Aging Configuration:\n"
"\tScavengingInterval = %d\n"
"\tDefaultAgingState = %d\n"
"\tDefaultRefreshInterval = %d\n"
"\tDefaultNoRefreshInterval = %d\n",
pServerInfo->dwScavengingInterval,
pServerInfo->fDefaultAgingState,
pServerInfo->dwDefaultRefreshInterval,
pServerInfo->dwDefaultNoRefreshInterval
);
DnsPrint_Ip4Array(
PrintRoutine,
pPrintContext,
" ServerAddresses:\n",
"\tAddr",
pServerInfo->aipServerAddrs );
DnsPrint_Ip4Array(
PrintRoutine,
pPrintContext,
" ListenAddresses:\n",
"\tAddr",
pServerInfo->aipListenAddrs );
DnsPrint_Ip4Array(
PrintRoutine,
pPrintContext,
" Forwarders:\n",
"\tAddr",
pServerInfo->aipForwarders );
PrintRoutine(
pPrintContext,
"\tforward timeout = %d\n"
"\tslave = %d\n",
pServerInfo->dwForwardTimeout,
pServerInfo->fSlave );
}
DnsPrint_Unlock();
FREE_HEAP( pnameServer );
FREE_HEAP( pnameForest );
FREE_HEAP( pnameDomain );
FREE_HEAP( pnameForestDp );
FREE_HEAP( pnameDomainDp );
}
//
// Print zone Zone debug utilities
//
PSTR
truncateStringA(
PSTR pszSource,
PSTR pszDest,
int iDestLength )
{
if ( pszSource )
{
int len = strlen( pszSource );
if ( len < iDestLength )
{
strcpy( pszDest, pszSource );
}
else
{
strncpy( pszDest, pszSource, iDestLength - 4 );
strcpy( pszDest + iDestLength - 4, "..." );
}
}
else
{
*pszDest = '\0';
}
return pszDest;
}
PWSTR
truncateStringW(
PWSTR pwszSource,
PWSTR pwszDest,
int iDestLength )
{
if ( pwszSource )
{
int len = wcslen( pwszSource );
if ( len < iDestLength )
{
wcscpy( pwszDest, pwszSource );
}
else
{
wcsncpy( pwszDest, pwszSource, iDestLength - 4 );
wcscpy( pwszDest + iDestLength - 4, L"..." );
pwszDest[ iDestLength - 1 ] = '\0';
}
}
else
{
*pwszDest = L'\0';
}
return pwszDest;
}
#define DNS_DPDISP_REAL_CUSTOM_NAME 0x0001
#define DNS_DPDISP_BLANK_STRING_FOR_LEGACY 0x0002
LPSTR
partitionDisplayName(
IN DWORD dwPartitionFlags,
IN LPSTR pszPartitionFqdn,
IN DWORD dwNameBuffLen,
OUT LPSTR pszNameBuff,
IN DWORD dwFlags
)
/*++
Routine Description:
Formats directory partition for display. If the flags indicate that
the partition is a built-in partition, the name will be substituted
for a descriptive string.
Arguments:
dwPartitionFlags -- DP flags from the DNS server
pszPartitionFqdn -- FQDN of the partition
dwNameBuffLen -- length of the output name buffer
pszNameBuff -- pointer to the output name buffer
dwFlags - use DNS_DPDISP_XXX constants
Return Value:
Pointer to pszNameBuff
--*/
{
//
// Substitute name if this is a built-in partition.
//
if ( dwPartitionFlags & DNS_DP_DOMAIN_DEFAULT )
{
pszPartitionFqdn = "AD-Domain";
}
else if ( dwPartitionFlags & DNS_DP_FOREST_DEFAULT )
{
pszPartitionFqdn = "AD-Forest";
}
else if ( dwPartitionFlags & DNS_DP_LEGACY || !pszPartitionFqdn )
{
pszPartitionFqdn =
( dwFlags & DNS_DPDISP_BLANK_STRING_FOR_LEGACY ) ? "" : "AD-Legacy";
}
else if ( !( dwFlags & DNS_DPDISP_REAL_CUSTOM_NAME ) )
{
pszPartitionFqdn = "AD-Custom";
}
truncateStringA( pszPartitionFqdn, pszNameBuff, dwNameBuffLen );
return pszNameBuff;
} // partitionDisplayName
LPSTR
zoneTypeString(
IN DWORD dwZoneType,
IN DWORD dwOutBuffLen,
OUT LPSTR pszOutBuff
)
/*++
Routine Description:
Convert DWORD zone type into display string.
Arguments:
dwZoneType -- zone type
dwOutBuffLen -- length of the output name buffer
pszOutBuff -- pointer to the output name buffer
Return Value:
Pointer to pszOutBuff
--*/
{
PSTR pszZoneType = NULL;
CHAR szBuff[ 10 ];
switch ( dwZoneType )
{
case DNS_ZONE_TYPE_CACHE:
pszZoneType = "Cache";
break;
case DNS_ZONE_TYPE_PRIMARY:
pszZoneType = "Primary";
break;
case DNS_ZONE_TYPE_SECONDARY:
pszZoneType = "Secondary";
break;
case DNS_ZONE_TYPE_STUB:
pszZoneType = "Stub";
break;
case DNS_ZONE_TYPE_FORWARDER:
pszZoneType = "Forwarder";
break;
default:
_itoa( dwZoneType, szBuff, 10 );
pszZoneType = szBuff;
break;
}
truncateStringA( pszZoneType, pszOutBuff, dwOutBuffLen );
return pszOutBuff;
} // zoneTypeString
VOID
DnsPrint_RpcZone(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pPrintContext,
IN LPSTR pszHeader,
IN PDNS_RPC_ZONE pZone
)
{
PWSTR pnamePartition = NULL;
DnsPrint_Lock();
if ( ! pZone )
{
PrintRoutine( pPrintContext,
"%sNULL zone info ptr.\n",
( pszHeader ? pszHeader : "" ) );
}
else
{
CHAR szpartition[ 15 ];
CHAR sztype[ 10 ];
// print zone per line
if ( pszHeader && *pszHeader )
{
PrintRoutine( pPrintContext,
"%s\n",
pszHeader ? pszHeader : "" );
}
PrintRoutine( pPrintContext, " %-30S", pZone->pszZoneName );
if ( pZone->Flags.DsIntegrated )
{
partitionDisplayName(
pZone->dwDpFlags,
pZone->pszDpFqdn,
sizeof( szpartition ),
szpartition,
0 );
}
else
{
strcpy( szpartition, "File" );
}
pnamePartition = getUnicodeForUtf8( szpartition );
PrintRoutine( pPrintContext,
" %-9s %-14S %s%s%s%s%s%s\n",
zoneTypeString(
pZone->ZoneType,
sizeof( sztype ),
sztype ),
pnamePartition, // szpartition,
pZone->Flags.Update == 2 ?
"Secure " :
( pZone->Flags.Update == 1 ?
"Update " : "" ),
pZone->Flags.Reverse ? "Rev " : "",
pZone->Flags.AutoCreated ? "Auto " : "",
pZone->Flags.Aging ? "Aging " : "",
pZone->Flags.Paused ? "Paused " : "",
pZone->Flags.Shutdown ? "Down " : "" );
}
DnsPrint_Unlock();
FREE_HEAP( pnamePartition );
}
VOID
DNS_API_FUNCTION
DnsPrint_RpcZoneList(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pPrintContext,
IN LPSTR pszHeader,
IN PDNS_RPC_ZONE_LIST pZoneList
)
{
DWORD i;
DnsPrint_Lock();
if ( pszHeader )
{
PrintRoutine( pPrintContext, "%s\n", pszHeader );
}
if ( !pZoneList )
{
PrintRoutine( pPrintContext, "NULL zone list pointer.\n" );
}
else
{
PrintRoutine( pPrintContext, "\tZone count = %d\n\n", pZoneList->dwZoneCount );
PrintRoutine( pPrintContext,
" Zone name Type Storage Properties\n\n" );
if ( pZoneList->dwZoneCount )
{
DnsPrint_RpcZone(
PrintRoutine, pPrintContext,
NULL, // print default header
pZoneList->ZoneArray[0] );
}
for ( i=1; i<pZoneList->dwZoneCount; i++ )
{
DnsPrint_RpcZone(
PrintRoutine, pPrintContext,
NULL, // print default header
pZoneList->ZoneArray[i] );
}
PrintRoutine( pPrintContext, "\n" );
}
DnsPrint_Unlock();
}
//
// Directory parition debug utilities
//
VOID
DnsPrint_RpcDpEnum(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pPrintContext,
IN LPSTR pszHeader,
IN PDNS_RPC_DP_ENUM pDp
)
{
PWSTR pnameDpFqdn = NULL;
if ( !pDp )
{
PrintRoutine( pPrintContext, "NULL DP enum ptr\n" );
}
else
{
pnameDpFqdn = getUnicodeForUtf8( pDp->pszDpFqdn );
PrintRoutine( pPrintContext,
" %-40S %s%s%s%s%s%s\n",
pnameDpFqdn, // pDp->pszDpFqdn,
pDp->dwFlags & DNS_DP_ENLISTED ? "Enlisted " : "Not-Enlisted ",
pDp->dwFlags & DNS_DP_DELETED ? "Deleted " : "",
pDp->dwFlags & DNS_DP_AUTOCREATED ? "Auto " : "",
pDp->dwFlags & DNS_DP_LEGACY ? "Legacy " : "",
pDp->dwFlags & DNS_DP_DOMAIN_DEFAULT ? "Domain " : "",
pDp->dwFlags & DNS_DP_FOREST_DEFAULT ? "Forest " : "" );
}
FREE_HEAP( pnameDpFqdn );
} // DnsPrint_RpcDpEnum
VOID
DnsPrint_RpcDpInfo(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pPrintContext,
IN LPSTR pszHeader,
IN PDNS_RPC_DP_INFO pDp,
IN BOOL fTruncateLongStrings
)
{
PWSTR pnameDpFqdn = NULL;
DnsPrint_Lock();
if ( !pDp )
{
PrintRoutine( pPrintContext,
"%sNULL DP info ptr.\n",
( pszHeader ? pszHeader : "" ) );
}
else
{
WCHAR wsz[ 80 ];
pnameDpFqdn = getUnicodeForUtf8( pDp->pszDpFqdn );
PrintRoutine( pPrintContext,
"%s\n"
" DNS root: %S\n"
" Flags: 0x%X %s%s%s%s%s%s\n"
" State: %d\n"
" Zone count: %d\n"
" DP head: %S\n"
" Crossref: ",
pszHeader ? pszHeader : "",
pnameDpFqdn, // pDp->pszDpFqdn,
pDp->dwFlags,
pDp->dwFlags & DNS_DP_ENLISTED ? "Enlisted " : "Not-Enlisted ",
pDp->dwFlags & DNS_DP_DELETED ? "Deleted " : "",
pDp->dwFlags & DNS_DP_AUTOCREATED ? "Auto " : "",
pDp->dwFlags & DNS_DP_LEGACY ? "Legacy " : "",
pDp->dwFlags & DNS_DP_DOMAIN_DEFAULT ? "Domain " : "",
pDp->dwFlags & DNS_DP_FOREST_DEFAULT ? "Forest " : "",
pDp->dwState,
pDp->dwZoneCount,
pDp->pszDpDn,
pDp->pszCrDn );
if ( fTruncateLongStrings )
{
truncateStringW( pDp->pszCrDn, wsz, 64 );
PrintRoutine( pPrintContext, "%S", wsz );
}
else
{
PrintRoutine( pPrintContext, "%S", pDp->pszCrDn );
}
PrintRoutine( pPrintContext,
"\n Replicas: %d\n",
pDp->dwReplicaCount );
if ( pDp->dwReplicaCount && pDp->ReplicaArray )
{
DWORD i;
for ( i = 0;
i < pDp->dwReplicaCount && pDp->ReplicaArray[ i ];
++i )
{
if ( fTruncateLongStrings )
{
truncateStringW(
pDp->ReplicaArray[ i ]->pszReplicaDn,
wsz,
74 );
PrintRoutine( pPrintContext, " %S\n", wsz );
}
else
{
PrintRoutine( pPrintContext, " %S\n",
pDp->ReplicaArray[ i ]->pszReplicaDn ?
pDp->ReplicaArray[ i ]->pszReplicaDn : L"NULL" );
}
}
}
}
DnsPrint_Unlock();
FREE_HEAP( pnameDpFqdn );
} // DnsPrint_RpcDpInfo
VOID
DNS_API_FUNCTION
DnsPrint_RpcDpList(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pPrintContext,
IN LPSTR pszHeader,
IN PDNS_RPC_DP_LIST pDpList
)
{
DWORD i;
DnsPrint_Lock();
if ( pszHeader )
{
PrintRoutine( pPrintContext, "%s\n", pszHeader );
}
if ( !pDpList )
{
PrintRoutine( pPrintContext, "NULL directory partition list pointer.\n" );
}
else
{
PrintRoutine( pPrintContext, "\tDirectory partition count = %d\n\n", pDpList->dwDpCount );
for ( i = 0; i < pDpList->dwDpCount && pDpList->DpArray[ i ]; ++i )
{
DnsPrint_RpcDpEnum(
PrintRoutine, pPrintContext,
NULL, // print default header
pDpList->DpArray[ i ] );
}
PrintRoutine( pPrintContext, "\n" );
}
DnsPrint_Unlock();
} // DnsPrint_RpcDpList
VOID
DnsPrint_RpcZoneInfo(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pPrintContext,
IN LPSTR pszHeader,
IN PDNS_RPC_ZONE_INFO pZoneInfo
)
{
CHAR szdpName[ 300 ]; // don't want truncation
PWSTR pnameZone = NULL;
PWSTR pnameFile = NULL;
PWSTR pnameDp = NULL;
DnsPrint_Lock();
PrintRoutine( pPrintContext, (pszHeader ? pszHeader : "") );
if ( ! pZoneInfo )
{
PrintRoutine( pPrintContext, "NULL zone info ptr.\n" );
}
else
{
pnameZone = getUnicodeForUtf8( pZoneInfo->pszZoneName );
pnameFile = getUnicodeForUtf8( pZoneInfo->pszDataFile );
PrintRoutine( pPrintContext,
"Zone info:\n"
"\tptr = %p\n"
"\tzone name = %S\n"
"\tzone type = %d\n"
"\tupdate = %d\n"
"\tDS integrated = %d\n"
"\tdata file = %S\n"
"\tusing WINS = %d\n"
"\tusing Nbstat = %d\n"
"\taging = %d\n"
"\t refresh interval = %lu\n"
"\t no refresh = %lu\n"
"\t scavenge available = %lu\n",
pZoneInfo,
pnameZone, // pZoneInfo->pszZoneName,
pZoneInfo->dwZoneType,
pZoneInfo->fAllowUpdate,
pZoneInfo->fUseDatabase,
pnameFile, // pZoneInfo->pszDataFile,
pZoneInfo->fUseWins,
pZoneInfo->fUseNbstat,
pZoneInfo->fAging,
pZoneInfo->dwRefreshInterval,
pZoneInfo->dwNoRefreshInterval,
pZoneInfo->dwAvailForScavengeTime
);
DnsPrint_Ip4Array(
PrintRoutine, pPrintContext,
"\tZone Masters\n",
"\tMaster",
pZoneInfo->aipMasters );
if ( pZoneInfo->dwZoneType == DNS_ZONE_TYPE_STUB )
{
DnsPrint_Ip4Array(
PrintRoutine, pPrintContext,
"\tZone Local Masters\n",
"\tLocal Master",
pZoneInfo->aipLocalMasters );
}
DnsPrint_Ip4Array(
PrintRoutine, pPrintContext,
"\tZone Secondaries\n",
"\tSecondary",
pZoneInfo->aipSecondaries );
PrintRoutine( pPrintContext,
"\tsecure secs = %d\n",
pZoneInfo->fSecureSecondaries );
if ( pZoneInfo->fUseDatabase )
{
partitionDisplayName(
pZoneInfo->dwDpFlags,
pZoneInfo->pszDpFqdn,
sizeof( szdpName ),
szdpName,
DNS_DPDISP_REAL_CUSTOM_NAME ),
pnameDp = getUnicodeForUtf8( szdpName );
PrintRoutine( pPrintContext,
"\tdirectory partition = %S flags %08X\n"
"\tzone DN = %S\n",
pnameDp,
pZoneInfo->dwDpFlags,
pZoneInfo->pwszZoneDn );
}
if ( pZoneInfo->aipScavengeServers )
{
DnsPrint_Ip4Array(
PrintRoutine, pPrintContext,
"\tScavenge Servers\n",
"\tServer",
pZoneInfo->aipScavengeServers );
}
if ( pZoneInfo->dwZoneType == DNS_ZONE_TYPE_FORWARDER )
{
PrintRoutine( pPrintContext,
"\tforwarder timeout = %d\n"
"\tforwarder slave = %d\n",
pZoneInfo->dwForwarderTimeout,
pZoneInfo->fForwarderSlave );
}
if ( pZoneInfo->dwZoneType == DNS_ZONE_TYPE_SECONDARY ||
pZoneInfo->dwZoneType == DNS_ZONE_TYPE_STUB )
{
char szTime1[ 60 ] = DNS_NOT_PERFORMED;
char szTime2[ 60 ] = DNS_NOT_PERFORMED;
if ( pZoneInfo->dwLastSuccessfulXfr )
{
time_t t = pZoneInfo->dwLastSuccessfulXfr;
strcpy( szTime1, ctime( &t ) );
szTime1[ strlen( szTime1 ) - 1 ] = '\0';
}
if ( pZoneInfo->dwLastSuccessfulSoaCheck )
{
time_t t = pZoneInfo->dwLastSuccessfulSoaCheck;
strcpy( szTime2, ctime( &t ) );
szTime2[ strlen( szTime2 ) - 1 ] = '\0';
}
PrintRoutine( pPrintContext,
"\tlast successful xfr = %s (%d)\n"
"\tlast SOA check = %s (%d)\n",
szTime1,
pZoneInfo->dwLastSuccessfulXfr,
szTime2,
pZoneInfo->dwLastSuccessfulSoaCheck );
}
}
DnsPrint_Unlock();
FREE_HEAP( pnameZone );
FREE_HEAP( pnameFile );
FREE_HEAP( pnameDp );
}
VOID
DnsPrint_RpcZoneInfoList(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pPrintContext,
IN LPSTR pszHeader,
IN DWORD dwZoneCount,
IN PDNS_RPC_ZONE_INFO apZoneInfo[]
)
{
DWORD i;
DnsPrint_Lock();
PrintRoutine( pPrintContext, (pszHeader ? pszHeader : "") );
PrintRoutine( pPrintContext, "Zone Count = %d\n", dwZoneCount );
if ( dwZoneCount != 0 && apZoneInfo != NULL )
{
for (i=0; i<dwZoneCount; i++)
{
DnsPrint_RpcZoneInfo(
PrintRoutine, pPrintContext,
NULL,
apZoneInfo[i] );
}
}
DnsPrint_Unlock();
}
//
// Print domain node and record buffers
//
VOID
DnssrvCopyRpcNameToBuffer(
IN PSTR pResult,
IN PDNS_RPC_NAME pName
)
/*++
Routine Description:
Copy RPC name to buffer.
Arguments:
pResult -- result buffer; assumed to be at least DNS_MAX_NAME_LENGTH
pName -- RPC name
Return Value:
None
--*/
{
DWORD length = pName->cchNameLength;
strncpy( pResult, pName->achName, length );
pResult[ length ] = 0;
}
VOID
DnsPrint_RpcName(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pPrintContext,
IN LPSTR pszHeader,
IN PDNS_RPC_NAME pName,
IN LPSTR pszTrailer
)
/*++
Routine Description:
Prints RPC name.
Arguments:
PrintRoutine -- printf like routine to print with
pszHeader -- header string
pName -- RPC name
pszTrailer -- trailer string
Return Value:
None
--*/
{
PWSTR pname = NULL;
PWSTR pnameAlloc = NULL;
//
// print name to given length
//
if ( !pszHeader )
{
pszHeader = "";
}
if ( !pszTrailer )
{
pszTrailer = "";
}
if ( ! pName )
{
pname = L"(NULL DNS name ptr)";
}
else if ( pName->cchNameLength > 0 )
{
pname = pnameAlloc = utf8ToUnicode( pName->achName, pName->cchNameLength );
if ( !pname )
{
pname = L"<OUT OF MEMORY>";
}
}
else // @ for empty node name
{
pname = L"@";
}
PrintRoutine( pPrintContext,
"%s%S%s",
pszHeader,
pname,
pszTrailer );
FREE_HEAP( pnameAlloc );
}
VOID
DnsPrint_RpcNode(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pPrintContext,
IN LPSTR pszHeader,
IN PDNS_RPC_NODE pNode
)
/*++
Routine Description:
Prints RPC node.
Arguments:
PrintRoutine -- printf like routine to print with
pszHeader -- header string
pNode -- RPC node to print
Return Value:
None
--*/
{
DnsPrint_Lock();
PrintRoutine( pPrintContext, (pszHeader ? pszHeader : "RPC Node:") );
if ( ! pNode )
{
PrintRoutine( pPrintContext, "NULL RPC node ptr.\n" );
}
else
{
PrintRoutine( pPrintContext,
"\n"
"\tptr = %p\n"
"\twLength = %d\n"
"\twRecordCount = %d\n"
"\tdwChildCount = %d\n"
"\tdwFlags = %p\n",
pNode,
pNode->wLength,
pNode->wRecordCount,
pNode->dwChildCount,
pNode->dwFlags );
DnsPrint_RpcName(
PrintRoutine,
pPrintContext,
"\tNode Name = ",
& pNode->dnsNodeName,
"\n" );
}
DnsPrint_Unlock();
}
VOID
DnsPrint_RpcRecord(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pPrintContext,
IN LPSTR pszHeader,
IN BOOL fDetail,
IN PDNS_FLAT_RECORD pRecord
)
/*++
Routine Description:
Prints RPC record.
Arguments:
PrintRoutine -- printf like routine to print with
pszHeader -- header string
fDetail -- if TRUE print detailed record info
pRecord -- RPC record to print
Return Value:
None
--*/
{
PCHAR ptypeString;
PDNS_RPC_RECORD_DATA pdata;
WORD type;
WORD dataLength;
SYSTEMTIME sysTime;
CHAR szBuff[ 5000 ];
DnsPrint_Lock();
PrintRoutine( pPrintContext, (pszHeader ? pszHeader : "" ) );
if ( ! pRecord )
{
PrintRoutine( pPrintContext, "NULL record ptr.\n" );
goto Done;
}
//
// record fixed fields
//
type = pRecord->wType;
ptypeString = Dns_RecordStringForType( type );
if ( !ptypeString )
{
ptypeString = "UNKNOWN";
}
pdata = &pRecord->Data;
dataLength = pRecord->wDataLength;
if ( fDetail )
{
Dns_SystemHourToSystemTime(
pRecord->dwTimeStamp,
&sysTime );
PrintRoutine( pPrintContext,
" %s Record info:\n"
"\tptr = %p\n"
"\twType = %s (%u)\n"
"\twDataLength = %u\n"
"\tdwFlags = %lx\n"
"\trank = %x\n"
"\tdwSerial = %p\n"
"\tdwTtlSeconds = %u\n"
"\tdwTimeStamp = %lu ([%2d:%2d:%2d] [%2d/%2d/%2d])\n",
ptypeString,
pRecord,
ptypeString,
type,
pRecord->wDataLength,
pRecord->dwFlags,
(UCHAR)(pRecord->dwFlags & DNS_RPC_FLAG_RANK),
pRecord->dwSerial,
pRecord->dwTtlSeconds,
pRecord->dwTimeStamp,
sysTime.wHour,
sysTime.wMinute,
sysTime.wSecond,
sysTime.wMonth,
sysTime.wDay,
sysTime.wYear
);
}
//
// print record type and data
// - as single line data where possible
if ( !fDetail )
{
if ( pRecord->dwTimeStamp )
{
PrintRoutine( pPrintContext,
" [Aging:%lu]",
pRecord->dwTimeStamp );
}
PrintRoutine( pPrintContext,
" %lu",
pRecord->dwTtlSeconds );
}
PrintRoutine( pPrintContext,
" %s\t",
ptypeString );
//
// print type data
//
switch ( type )
{
case DNS_TYPE_A:
PrintRoutine( pPrintContext,
"%d.%d.%d.%d\n",
* ( (PUCHAR) &(pdata->A) + 0 ),
* ( (PUCHAR) &(pdata->A) + 1 ),
* ( (PUCHAR) &(pdata->A) + 2 ),
* ( (PUCHAR) &(pdata->A) + 3 )
);
break;
case DNS_TYPE_PTR:
case DNS_TYPE_NS:
case DNS_TYPE_CNAME:
case DNS_TYPE_MD:
case DNS_TYPE_MB:
case DNS_TYPE_MF:
case DNS_TYPE_MG:
case DNS_TYPE_MR:
//
// these RRs contain single indirection
//
DnsPrint_RpcName(
PrintRoutine, pPrintContext,
NULL,
& pdata->NS.nameNode,
"\n" );
break;
case DNS_TYPE_MX:
case DNS_TYPE_RT:
case DNS_TYPE_AFSDB:
//
// these RR contain
// - one preference value
// - one domain name
//
PrintRoutine( pPrintContext,
"%d ",
pdata->MX.wPreference
);
DnsPrint_RpcName(
PrintRoutine, pPrintContext,
NULL,
& pdata->MX.nameExchange,
"\n" );
break;
case DNS_TYPE_SOA:
if ( fDetail )
{
DnsPrint_RpcName(
PrintRoutine, pPrintContext,
"\n\tPrimaryNameServer: ",
& pdata->SOA.namePrimaryServer,
"\n" );
// responsible party name, immediately follows primary server name
DnsPrint_RpcName(
PrintRoutine, pPrintContext,
"\tResponsibleParty: ",
(PDNS_RPC_NAME)
(pdata->SOA.namePrimaryServer.achName
+ pdata->SOA.namePrimaryServer.cchNameLength),
"\n" );
PrintRoutine( pPrintContext,
"\tSerialNo = %lu\n"
"\tRefresh = %lu\n"
"\tRetry = %lu\n"
"\tExpire = %lu\n"
"\tMinimumTTL = %lu\n",
pdata->SOA.dwSerialNo,
pdata->SOA.dwRefresh,
pdata->SOA.dwRetry,
pdata->SOA.dwExpire,
pdata->SOA.dwMinimumTtl );
break;
}
else
{
DnsPrint_RpcName(
PrintRoutine, pPrintContext,
NULL,
& pdata->SOA.namePrimaryServer,
NULL );
// responsible party name, immediately follows primary server name
DnsPrint_RpcName(
PrintRoutine, pPrintContext,
" ",
(PDNS_RPC_NAME)
(pdata->SOA.namePrimaryServer.achName
+ pdata->SOA.namePrimaryServer.cchNameLength),
NULL );
PrintRoutine( pPrintContext,
" %lu"
" %lu"
" %lu"
" %lu"
" %lu\n",
pdata->SOA.dwSerialNo,
pdata->SOA.dwRefresh,
pdata->SOA.dwRetry,
pdata->SOA.dwExpire,
pdata->SOA.dwMinimumTtl );
break;
}
case DNS_TYPE_AAAA:
{
CHAR ip6String[ IP6_ADDRESS_STRING_LENGTH+1 ];
Dns_Ip6AddressToString_A(
ip6String,
&pdata->AAAA.ipv6Address
);
PrintRoutine( pPrintContext,
"%s\n",
ip6String );
}
break;
case DNS_TYPE_HINFO:
case DNS_TYPE_ISDN:
case DNS_TYPE_X25:
case DNS_TYPE_TEXT:
{
//
// all these are simply text string(s)
//
// TXT strings will be printed one per line
//
PCHAR pch = (PCHAR) &pdata->TXT.stringData;
PCHAR pchStop = pch + dataLength;
UCHAR cch;
while ( pch < pchStop )
{
cch = (UCHAR) *pch++;
if ( type == DNS_TYPE_TEXT )
{
PrintRoutine( pPrintContext,
"\t%.*s\n",
cch,
pch );
}
else
{
PrintRoutine( pPrintContext,
"\"%.*s\" ",
cch,
pch );
}
pch += cch;
}
if ( type != DNS_TYPE_TEXT )
{
PrintRoutine( pPrintContext,"\n");
}
ASSERT( pch == pchStop );
break;
}
case DNS_TYPE_MINFO:
case DNS_TYPE_RP:
//
// these RRs contain two domain names
//
DnsPrint_RpcName(
PrintRoutine, pPrintContext,
NULL,
& pdata->MINFO.nameMailBox,
NULL );
// errors to mailbox name, immediately follows mail box
DnsPrint_RpcName(
PrintRoutine, pPrintContext,
" ",
(PDNS_RPC_NAME)
( pdata->MINFO.nameMailBox.achName
+ pdata->MINFO.nameMailBox.cchNameLength ),
"\n" );
break;
case DNS_TYPE_WKS:
{
INT i;
if ( fDetail )
{
PrintRoutine( pPrintContext,
"WKS: Address %d.%d.%d.%d\n"
"\tProtocol %d\n"
"\tBitmask\n",
* ( (PUCHAR) &(pdata->WKS.ipAddress) + 0 ),
* ( (PUCHAR) &(pdata->WKS.ipAddress) + 1 ),
* ( (PUCHAR) &(pdata->WKS.ipAddress) + 2 ),
* ( (PUCHAR) &(pdata->WKS.ipAddress) + 3 ),
pdata->WKS.chProtocol
);
for ( i = 0;
i < (INT)( dataLength
- sizeof( pdata->WKS.ipAddress )
- sizeof( pdata->WKS.chProtocol ) );
i++ )
{
PrintRoutine( pPrintContext,
"\t\tbyte[%d] = %x\n",
i,
(UCHAR) pdata->WKS.bBitMask[i] );
}
break;
}
else
{
DNS_STATUS status;
struct protoent * pProtoent;
WSADATA wsaData;
PrintRoutine( pPrintContext,
"%d.%d.%d.%d ",
* ( (PUCHAR) &(pdata->WKS.ipAddress) + 0 ),
* ( (PUCHAR) &(pdata->WKS.ipAddress) + 1 ),
* ( (PUCHAR) &(pdata->WKS.ipAddress) + 2 ),
* ( (PUCHAR) &(pdata->WKS.ipAddress) + 3 )
);
//
// get protocol number:
//
// start winsock:
status = WSAStartup( DNS_WINSOCK_VERSION, &wsaData );
if ( status == SOCKET_ERROR )
{
status = WSAGetLastError();
SetLastError( status );
PrintRoutine( pPrintContext,
"ERROR: WSAGetLastError()\n"
);
ASSERT(FALSE);
}
pProtoent = getprotobynumber( pdata->WKS.chProtocol );
if ( ! pProtoent || pProtoent->p_proto >= MAXUCHAR )
{
status = WSAGetLastError();
SetLastError( status );
PrintRoutine( pPrintContext, "ERROR: getprotobyname()\n" );
ASSERT(FALSE);
}
PrintRoutine( pPrintContext,
"%s\t",
pProtoent->p_name
);
//bBitMask[0] : string length, not printed:
for ( i = 1;
i < (INT)( dataLength
- sizeof( pdata->WKS.ipAddress )
- sizeof( pdata->WKS.chProtocol ) );
i++ )
{
PrintRoutine( pPrintContext,
"%c",
(UCHAR) pdata->WKS.bBitMask[i] );
}
PrintRoutine( pPrintContext,"\n");
break;
}
}
case DNS_TYPE_NULL:
{
INT i;
for ( i = 0; i < dataLength; i++ )
{
// print one DWORD per line
if ( !(i%16) )
{
PrintRoutine( pPrintContext, "\n\t" );
}
PrintRoutine( pPrintContext,
"%02x ",
(UCHAR) pdata->Null.bData[i] );
}
PrintRoutine( pPrintContext, "\n" );
break;
}
case DNS_TYPE_SRV:
//
// SRV <priority> <weight> <port> <target host>
//
PrintRoutine( pPrintContext,
"%d %d %d ",
pdata->SRV.wPriority,
pdata->SRV.wWeight,
pdata->SRV.wPort
);
DnsPrint_RpcName(
PrintRoutine, pPrintContext,
NULL,
& pdata->SRV.nameTarget,
"\n" );
break;
case DNS_TYPE_WINS:
{
DWORD i;
CHAR flagName[ WINS_FLAG_MAX_LENGTH ];
//
// WINS
// - scope/domain mapping flag
// - WINS server list
//
Dns_WinsRecordFlagString(
pdata->WINS.dwMappingFlag,
flagName );
PrintRoutine( pPrintContext,
"%s %d %d ",
flagName,
//pdata->WINS.dwMappingFlag,
pdata->WINS.dwLookupTimeout,
pdata->WINS.dwCacheTimeout
);
if ( fDetail )
{
PrintRoutine( pPrintContext, " WINS Servers:\n" );
}
for( i=0; i<pdata->WINS.cWinsServerCount; i++ )
{
PrintRoutine( pPrintContext,
"%d.%d.%d.%d%c",
* ( (PUCHAR) &(pdata->WINS.aipWinsServers[i]) + 0 ),
* ( (PUCHAR) &(pdata->WINS.aipWinsServers[i]) + 1 ),
* ( (PUCHAR) &(pdata->WINS.aipWinsServers[i]) + 2 ),
* ( (PUCHAR) &(pdata->WINS.aipWinsServers[i]) + 3 ),
fDetail ? '\n' : ' '
);
}
if ( !fDetail )
{
PrintRoutine( pPrintContext, "\n" );
}
break;
}
case DNS_TYPE_NBSTAT:
{
CHAR flagName[ WINS_FLAG_MAX_LENGTH ];
//
// NBSTAT
// - scope/domain mapping flag
// - optionally a result domain
//
Dns_WinsRecordFlagString(
pdata->WINS.dwMappingFlag,
flagName );
PrintRoutine( pPrintContext,
"%s %d %d ",
flagName,
//pdata->WINS.dwMappingFlag,
pdata->NBSTAT.dwLookupTimeout,
pdata->NBSTAT.dwCacheTimeout
);
if ( dataLength > sizeof(pdata->NBSTAT.dwMappingFlag) )
{
DnsPrint_RpcName(
PrintRoutine, pPrintContext,
NULL,
& pdata->NBSTAT.nameResultDomain,
"\n" );
}
break;
}
case DNS_TYPE_KEY:
{
int keyLength = dataLength - SIZEOF_KEY_FIXED_DATA;
PrintRoutine( pPrintContext,
"0x%04X %d %d ",
( int ) pdata->KEY.wFlags,
( int ) pdata->KEY.chProtocol,
( int ) pdata->KEY.chAlgorithm );
if ( keyLength > 0 && keyLength < sizeof( szBuff ) / 2 )
{
PCHAR p = Dns_SecurityKeyToBase64String(
( PBYTE ) pdata + SIZEOF_KEY_FIXED_DATA,
keyLength,
szBuff );
if ( p )
{
*p = '\0'; // NULL terminate key string
}
PrintRoutine( pPrintContext, szBuff );
}
else
{
PrintRoutine( pPrintContext, "KEY = %d bytes", keyLength );
}
PrintRoutine( pPrintContext, "\n" );
break;
}
case DNS_TYPE_SIG:
{
CHAR szSigExp[ 30 ];
CHAR szSigInc[ 30 ];
INT sigOffset =
SIZEOF_SIG_FIXED_DATA +
pdata->SIG.nameSigner.cchNameLength +
sizeof( pdata->SIG.nameSigner.cchNameLength );
INT sigLength = dataLength - sigOffset;
ptypeString = Dns_RecordStringForType( pdata->SIG.wTypeCovered );
if ( !ptypeString )
{
ptypeString = "UNKNOWN-TYPE";
}
PrintRoutine( pPrintContext,
"%s %d %d %d %s %s %d ",
ptypeString,
( int ) pdata->SIG.chAlgorithm,
( int ) pdata->SIG.chLabelCount,
( int ) pdata->SIG.dwOriginalTtl,
Dns_SigTimeString(
pdata->SIG.dwSigExpiration,
szSigExp ),
Dns_SigTimeString(
pdata->SIG.dwSigInception,
szSigInc ),
( int ) pdata->SIG.wKeyTag );
DnsPrint_RpcName(
PrintRoutine, pPrintContext,
NULL,
&pdata->SIG.nameSigner,
" " );
if ( sigLength > 0 && sigLength < sizeof( szBuff ) / 2 )
{
PCHAR p = Dns_SecurityKeyToBase64String(
( PBYTE ) pdata + sigOffset,
sigLength,
szBuff );
if ( p )
{
*p = '\0'; // NULL terminate key string
}
PrintRoutine( pPrintContext, szBuff );
}
else
{
PrintRoutine( pPrintContext, "SIG = %d bytes", sigLength );
}
PrintRoutine( pPrintContext, "\n" );
break;
}
case DNS_TYPE_NXT:
{
INT typeIdx;
DnsPrint_RpcName(
PrintRoutine, pPrintContext,
NULL,
( PDNS_RPC_NAME ) ( ( PBYTE ) &pdata->NXT +
( pdata->NXT.wNumTypeWords + 1 ) * sizeof( WORD ) ),
NULL );
for ( typeIdx = 0; typeIdx < pdata->NXT.wNumTypeWords; ++typeIdx )
{
ptypeString =
Dns_RecordStringForType( pdata->NXT.wTypeWords[ typeIdx ] );
if ( !ptypeString )
{
ptypeString = "UNKNOWN-TYPE";
}
PrintRoutine( pPrintContext,
" %s",
ptypeString );
}
PrintRoutine( pPrintContext, "\n" );
break;
}
default:
PrintRoutine( pPrintContext,
"Unknown resource record type (%d) at %p.\n",
type,
pRecord );
break;
}
Done:
DnsPrint_Unlock();
}
PDNS_RPC_NAME
DNS_API_FUNCTION
DnsPrint_RpcRecordsInBuffer(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pPrintContext,
IN LPSTR pszHeader,
IN BOOL fDetail,
IN DWORD dwBufferLength,
IN BYTE abBuffer[]
)
/*++
Routine Description:
Prints RPC buffer.
Arguments:
PrintRoutine -- printf like routine to print with
pszHeader -- header string
fDetail -- if TRUE print detailed record info
dwBufferLength -- buffer length
abBuffer -- ptr to RPC buffer
Return Value:
Ptr to last RPC node name in buffer.
NULL on error.
--*/
{
PBYTE pcurrent;
PBYTE pstop;
PDNS_RPC_NAME plastName = NULL;
INT recordCount;
PCHAR precordHeader;
DnsPrint_Lock();
PrintRoutine( pPrintContext, (pszHeader ? pszHeader : "") );
if ( !abBuffer )
{
PrintRoutine( pPrintContext, "NULL record buffer ptr.\n" );
goto Done;
}
#if 0
else
{
PrintRoutine( pPrintContext,
"Record buffer of length %d at %p:\n",
dwBufferLength,
abBuffer );
}
#endif
//
// find stop byte
//
ASSERT( DNS_IS_DWORD_ALIGNED(abBuffer) );
pstop = abBuffer + dwBufferLength;
pcurrent = abBuffer;
//
// loop until out of nodes
//
while ( pcurrent < pstop )
{
//
// print owner node
// - if NOT printing detail and no records
// (essentially domain nodes) then no node print
//
plastName = &((PDNS_RPC_NODE)pcurrent)->dnsNodeName;
recordCount = ((PDNS_RPC_NODE)pcurrent)->wRecordCount;
if ( fDetail )
{
DnsPrint_RpcNode(
PrintRoutine, pPrintContext,
NULL,
(PDNS_RPC_NODE)pcurrent );
if ( recordCount == 0 )
{
PrintRoutine( pPrintContext,"\n");
}
}
else
{
#ifndef DBG
if ( recordCount != 0 )
#endif
{
DnsPrint_RpcName(
PrintRoutine, pPrintContext,
NULL,
plastName,
NULL );
#ifdef DBG
if ( recordCount == 0 )
{
PrintRoutine( pPrintContext, "\t\t(node)\n" );
}
#endif
}
}
pcurrent += ((PDNS_RPC_NODE)pcurrent)->wLength;
pcurrent = DNS_NEXT_DWORD_PTR(pcurrent);
//
// for each node, print all records in list
//
if ( !recordCount )
{
continue;
}
precordHeader = "";
while( recordCount-- )
{
if ( pcurrent >= pstop )
{
PrintRoutine( pPrintContext,
"ERROR: Bogus buffer at %p\n"
"\tExpect record at %p past buffer end at %p\n"
"\twith %d records remaining.\n",
abBuffer,
(PDNS_RPC_RECORD) pcurrent,
pstop,
recordCount+1 );
ASSERT( FALSE );
break;
}
DnsPrint_RpcRecord(
PrintRoutine, pPrintContext,
precordHeader,
fDetail,
(PDNS_RPC_RECORD)pcurrent );
precordHeader = "\t\t";
pcurrent += ((PDNS_RPC_RECORD)pcurrent)->wDataLength
+ SIZEOF_DNS_RPC_RECORD_HEADER;
pcurrent = DNS_NEXT_DWORD_PTR(pcurrent);
}
}
Done:
DnsPrint_Unlock();
return( plastName );
}
VOID
DNS_API_FUNCTION
DnsPrint_Node(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pPrintContext,
IN LPSTR pszHeader,
IN PDNS_NODE pNode,
IN BOOLEAN fPrintRecords
)
{
DnsPrint_Lock();
PrintRoutine( pPrintContext, (pszHeader ? pszHeader : "") );
if ( !pNode )
{
PrintRoutine( pPrintContext, " NULL DNS node ptr.\n" );
goto Unlock;
}
else
{
// DCR: WARNING: char set on RPC name print -- it's probably UTF8 if not unicode
PrintRoutine( pPrintContext,
"%s\n"
"\tName = %s%S\n"
"\tPtr = %p, pNext = %p\n"
"\tFlags = %p\n"
"\tRec ptr = %p\n",
pszHeader ? "" : "DNS node",
(PSTR) (pNode->Flags.S.Unicode ? "" : (PSTR) pNode->pName),
(PWSTR) (pNode->Flags.S.Unicode ? pNode->pName : L""),
pNode,
pNode->pNext,
pNode->Flags.W,
pNode->pRecord );
}
//
// if desired print record list
//
if ( pNode->pRecord && fPrintRecords )
{
DnsPrint_RecordSet(
PrintRoutine, pPrintContext,
"\trecords:\n",
pNode->pRecord );
}
Unlock:
DnsPrint_Unlock();
}
VOID
DNS_API_FUNCTION
DnsPrint_NodeList(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pPrintContext,
IN LPSTR pszHeader,
IN PDNS_NODE pNode,
IN BOOLEAN fPrintRecords
)
{
DnsPrint_Lock();
PrintRoutine( pPrintContext, (pszHeader ? pszHeader : "") );
if ( !pNode )
{
PrintRoutine( pPrintContext, " NULL node list pointer.\n" );
}
else
{
do
{
DnsPrint_Node(
PrintRoutine, pPrintContext,
NULL,
pNode,
fPrintRecords );
}
while ( pNode = pNode->pNext );
}
DnsPrint_Unlock();
}
//
// RPC Type union printing
//
VOID
DnsPrint_RpcIpArrayPlusParameters(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pPrintContext,
IN LPSTR pszHeader,
IN LPSTR pszStructureName,
IN LPSTR pszParam1Name,
IN DWORD dwParam1,
IN LPSTR pszParam2Name,
IN DWORD dwParam2,
IN LPSTR pszIpArrayHeader,
IN PIP4_ARRAY pIpArray
)
/*++
Routine Description:
Print info that contains up to two params and IP_ARRAY.
This is kludgy, but there are several RPC types that contain an
IP array and some flags. This does the right thing for all those
cases.
Arguments:
pszParam1Name -- name of parameter;
pszParam2Name -- name of parameter; serves as flag as to whether
param2 is printed
pszIpArrayHeader -- name of IP array, passed to DnsPrint_Ip4Array
as header; should be full header line
ex. "\tMasters:\n"
Return Value:
None.
--*/
{
if ( !pszHeader )
{
pszHeader = "";
}
DnsPrint_Lock();
PrintRoutine( pPrintContext,
"%s%s\n"
"\t%s = %d (%p)\n",
pszHeader,
pszStructureName,
pszParam1Name,
dwParam1, dwParam1 );
if ( pszParam2Name )
{
PrintRoutine( pPrintContext,
"\t%s = %d (%p)\n",
pszParam2Name,
dwParam2, dwParam2 );
}
DnsPrint_Ip4Array(
PrintRoutine, pPrintContext,
pszIpArrayHeader,
"\t\t",
pIpArray );
DnsPrint_Unlock();
}
VOID
DnsPrint_RpcUnion(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pPrintContext,
IN LPSTR pszHeader,
IN DWORD dwTypeId,
IN PVOID pData
)
{
PWSTR pstr1 = NULL;
PWSTR pstr2 = NULL;
PWSTR pstr3 = NULL;
PWSTR pstr4 = NULL;
if ( !pszHeader )
{
pszHeader = "";
}
if ( !pData &&
dwTypeId != DNSSRV_TYPEID_NULL &&
dwTypeId != DNSSRV_TYPEID_DWORD )
{
PrintRoutine( pPrintContext,
"%sNull RPC data ptr of type %d.\n",
pszHeader,
dwTypeId );
return;
}
switch ( dwTypeId )
{
case DNSSRV_TYPEID_NULL:
PrintRoutine( pPrintContext,
"%sPointer: %p\n",
pszHeader,
pData );
break;
case DNSSRV_TYPEID_DWORD:
PrintRoutine( pPrintContext,
"%sDword: %d (%p)\n",
pszHeader,
(DWORD)(UINT_PTR)pData, pData );
break;
case DNSSRV_TYPEID_LPSTR:
// note: all TYPEID_LPSTRs i see are UTF8 strings
pstr1 = getUnicodeForUtf8( pData );
PrintRoutine( pPrintContext,
"%sString: %S\n",
pszHeader,
pstr1 );
break;
case DNSSRV_TYPEID_LPWSTR:
PrintRoutine( pPrintContext,
"%sWideString: %S\n",
pszHeader,
(PWSTR)pData );
break;
case DNSSRV_TYPEID_IPARRAY:
DnsPrint_Ip4Array(
PrintRoutine, pPrintContext,
pszHeader,
NULL,
(PIP4_ARRAY) pData );
break;
case DNSSRV_TYPEID_BUFFER:
PrintRoutine( pPrintContext,
"%sBuffer: length = %d, data ptr = %p\n",
pszHeader,
((PDNS_RPC_BUFFER) pData)->dwLength,
((PDNS_RPC_BUFFER) pData)->Buffer );
break;
case DNSSRV_TYPEID_SERVER_INFO:
DnsPrint_RpcServerInfo(
PrintRoutine, pPrintContext,
pszHeader,
(PDNS_RPC_SERVER_INFO) pData );
break;
case DNSSRV_TYPEID_STATS:
DnsPrint_RpcSingleStat(
PrintRoutine, pPrintContext,
pszHeader,
(PDNSSRV_STAT) pData );
break;
case DNSSRV_TYPEID_ZONE:
PrintRoutine( pPrintContext,
"%s\n",
pszHeader);
DnsPrint_RpcZone(
PrintRoutine, pPrintContext,
NULL, //print default header
(PDNS_RPC_ZONE) pData );
break;
case DNSSRV_TYPEID_FORWARDERS:
DnsPrint_RpcIpArrayPlusParameters(
PrintRoutine, pPrintContext,
pszHeader,
"Forwarders Info:",
"Slave",
((PDNS_RPC_FORWARDERS)pData)->fSlave,
"Timeout",
((PDNS_RPC_FORWARDERS)pData)->dwForwardTimeout,
"\tForwarders:\n",
((PDNS_RPC_FORWARDERS)pData)->aipForwarders );
break;
case DNSSRV_TYPEID_ZONE_INFO:
DnsPrint_RpcZoneInfo(
PrintRoutine, pPrintContext,
pszHeader,
(PDNS_RPC_ZONE_INFO) pData );
break;
case DNSSRV_TYPEID_ZONE_SECONDARIES:
DnsPrint_RpcIpArrayPlusParameters(
PrintRoutine, pPrintContext,
pszHeader,
"Zone Secondary Info:",
"Secure Secondaries",
((PDNS_RPC_ZONE_SECONDARIES)pData)->fSecureSecondaries,
NULL,
0,
"\tSecondaries:\n",
((PDNS_RPC_ZONE_SECONDARIES)pData)->aipSecondaries );
break;
case DNSSRV_TYPEID_ZONE_TYPE_RESET:
DnsPrint_RpcIpArrayPlusParameters(
PrintRoutine, pPrintContext,
pszHeader,
"Zone Type Reset Info:",
"ZoneType",
((PDNS_RPC_ZONE_TYPE_RESET)pData)->dwZoneType,
NULL,
0,
"\tMasters:\n",
((PDNS_RPC_ZONE_TYPE_RESET)pData)->aipMasters );
break;
case DNSSRV_TYPEID_ZONE_DATABASE:
pstr1 = getUnicodeForUtf8( ((PDNS_RPC_ZONE_DATABASE)pData)->pszFileName );
PrintRoutine( pPrintContext,
"%sZone Dbase Info:\n"
"\tDS Integrated = %d\n"
"\tFile Name = %S\n",
pszHeader,
((PDNS_RPC_ZONE_DATABASE)pData)->fDsIntegrated,
pstr1 // ((PDNS_RPC_ZONE_DATABASE)pData)->pszFileName
);
break;
case DNSSRV_TYPEID_ZONE_CREATE:
pstr1 = getUnicodeForUtf8( ((PDNS_RPC_ZONE_CREATE_INFO)pData)->pszZoneName );
pstr2 = getUnicodeForUtf8( ((PDNS_RPC_ZONE_CREATE_INFO)pData)->pszDataFile );
pstr3 = getUnicodeForUtf8( ((PDNS_RPC_ZONE_CREATE_INFO)pData)->pszAdmin );
pstr4 = getUnicodeForUtf8( ((PDNS_RPC_ZONE_CREATE_INFO)pData)->pszDpFqdn );
PrintRoutine( pPrintContext,
"%sZone Create Info:\n"
"\tZone Name = %S\n"
"\tType = %d\n"
"\tAllow Update = %d\n"
"\tDS Integrated = %d\n"
"\tFile Name = %S\n"
"\tLoad Existing = %d\n"
"\tFlags = 0x%08X\n"
"\tAdmin Name = %S\n"
"\tDirPart Flags = 0x%08X\n"
"\tDirPart FQDN = %S\n",
pszHeader,
pstr1, // ((PDNS_RPC_ZONE_CREATE_INFO)pData)->pszZoneName,
((PDNS_RPC_ZONE_CREATE_INFO)pData)->dwZoneType,
((PDNS_RPC_ZONE_CREATE_INFO)pData)->fAllowUpdate,
((PDNS_RPC_ZONE_CREATE_INFO)pData)->fDsIntegrated,
pstr2, // ((PDNS_RPC_ZONE_CREATE_INFO)pData)->pszDataFile,
((PDNS_RPC_ZONE_CREATE_INFO)pData)->fLoadExisting,
((PDNS_RPC_ZONE_CREATE_INFO)pData)->dwFlags,
pstr3, // ((PDNS_RPC_ZONE_CREATE_INFO)pData)->pszAdmin,
((PDNS_RPC_ZONE_CREATE_INFO)pData)->dwDpFlags,
pstr4 // ((PDNS_RPC_ZONE_CREATE_INFO)pData)->pszDpFqdn
);
break;
case DNSSRV_TYPEID_NAME_AND_PARAM:
// DCR: WARNING: not sure of name char set in NAME_AND_PARAM type
pstr1 = getUnicodeForUtf8( ((PDNS_RPC_NAME_AND_PARAM)pData)->pszNodeName );
PrintRoutine( pPrintContext,
"%sName and Parameter:\n"
"\tParam = %d (%p)\n"
"\tName = %S\n",
pszHeader,
((PDNS_RPC_NAME_AND_PARAM)pData)->dwParam,
((PDNS_RPC_NAME_AND_PARAM)pData)->dwParam,
pstr1 // ((PDNS_RPC_NAME_AND_PARAM)pData)->pszNodeName
);
break;
case DNSSRV_TYPEID_ZONE_LIST:
DnsPrint_RpcZoneList(
PrintRoutine, pPrintContext,
NULL,
(PDNS_RPC_ZONE_LIST)pData );
break;
default:
PrintRoutine( pPrintContext,
"%s\n"
"WARNING: Unknown RPC structure typeid = %d at %p\n",
pszHeader,
dwTypeId,
pData );
break;
}
FREE_HEAP( pstr1 );
FREE_HEAP( pstr2 );
FREE_HEAP( pstr3 );
FREE_HEAP( pstr4 );
}
//
// Stat validity table.
//
// Contains match of stat ID and lengths as of this build of RPC client.
//
typedef struct StatsValidityTableEntry
{
DWORD Id;
WORD wLength;
};
struct StatsValidityTableEntry StatsValidityTable[] =
{
DNSSRV_STATID_TIME, sizeof(DNSSRV_TIME_STATS),
DNSSRV_STATID_QUERY, sizeof(DNSSRV_QUERY_STATS),
DNSSRV_STATID_QUERY2, sizeof(DNSSRV_QUERY2_STATS),
DNSSRV_STATID_RECURSE, sizeof(DNSSRV_RECURSE_STATS),
DNSSRV_STATID_MASTER, sizeof(DNSSRV_MASTER_STATS),
DNSSRV_STATID_SECONDARY, sizeof(DNSSRV_SECONDARY_STATS),
DNSSRV_STATID_WINS, sizeof(DNSSRV_WINS_STATS),
DNSSRV_STATID_NBSTAT, sizeof(DNSSRV_NBSTAT_STATS),
DNSSRV_STATID_WIRE_UPDATE, sizeof(DNSSRV_UPDATE_STATS),
DNSSRV_STATID_NONWIRE_UPDATE, sizeof(DNSSRV_UPDATE_STATS),
DNSSRV_STATID_SKWANSEC, sizeof(DNSSRV_SKWANSEC_STATS),
DNSSRV_STATID_DS, sizeof(DNSSRV_DS_STATS),
DNSSRV_STATID_MEMORY, sizeof(DNSSRV_MEMORY_STATS),
DNSSRV_STATID_PACKET, sizeof(DNSSRV_PACKET_STATS),
DNSSRV_STATID_DBASE, sizeof(DNSSRV_DBASE_STATS),
DNSSRV_STATID_RECORD, sizeof(DNSSRV_RECORD_STATS),
DNSSRV_STATID_TIMEOUT, sizeof(DNSSRV_TIMEOUT_STATS),
DNSSRV_STATID_ERRORS, sizeof(DNSSRV_ERROR_STATS),
DNSSRV_STATID_CACHE, sizeof(DNSSRV_CACHE_STATS),
DNSSRV_STATID_PRIVATE, sizeof(DNSSRV_PRIVATE_STATS),
0, 0, // termination
};
DNS_STATUS
DNS_API_FUNCTION
DnssrvValidityCheckStatistic(
IN PDNSSRV_STAT pStat
)
/*++
Routine Description:
Validity check stat struct received from server.
Arguments:
pStat -- ptr to stat buffer
Return Value:
ERROR_SUCCESS if valid.
DNS_ERROR_INVALID_TYPE if unknown stat id.
ERROR_INVALID_DATA if invalid data.
--*/
{
DWORD i;
DWORD id;
//
// find stat ID in table, and verify length match
//
i = 0;
while ( id = StatsValidityTable[i].Id )
{
if ( pStat->Header.StatId == id )
{
if ( pStat->Header.wLength ==
StatsValidityTable[i].wLength - sizeof(DNSSRV_STAT_HEADER) )
{
return( ERROR_SUCCESS );
}
return( ERROR_INVALID_DATA );
}
i++;
}
return( DNS_ERROR_INVALID_TYPE );
}
//
// Stat printing.
//
VOID
DnsPrint_RpcStatRaw(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pPrintContext,
IN LPSTR pszHeader,
IN PDNSSRV_STAT pStat,
IN DNS_STATUS Status
)
/*++
Routine Description:
Debug print flat stat structure.
Arguments:
PrintRoutine -- printf like print routine to use
pszHeader -- header message to print
pStat -- ptr to stat buffer
Status -- status result of validity check; if not ERROR_SUCCESS,
appropriate error message is printed
Return Value:
None.
--*/
{
PDWORD pdword;
INT i;
PCHAR pstatEnd;
DnsPrint_Lock();
if ( pszHeader )
{
PrintRoutine( pPrintContext, pszHeader );
}
//
// validity check stat
//
if ( Status != ERROR_SUCCESS )
{
if ( Status == DNS_ERROR_INVALID_TYPE )
{
PrintRoutine( pPrintContext,
"Stat ID = %p, is not valid for version of the DNS RPC client.\n",
pStat->Header.StatId );
}
else if ( Status == ERROR_INVALID_DATA )
{
PrintRoutine( pPrintContext,
"Stat data length %d is invalid for stat ID = %p\n",
pStat->Header.wLength,
pStat->Header.StatId );
}
PrintRoutine( pPrintContext,
"WARNING: DNS RPC client must match version of server for statistics\n"
"\tprinting to be formatted appropriately.\n"
"Update this tool or the DNS server as necessary to match versions.\n" );
}
//
// print stat buffer raw
//
PrintRoutine( pPrintContext,
"Stat ID %p:\n",
pStat->Header.StatId );
pdword = (PDWORD) pStat->Buffer;
pstatEnd = pStat->Header.wLength + (PCHAR)pdword;
i = 0;
while ( (PCHAR)pdword < pstatEnd )
{
PrintRoutine( pPrintContext,
" stat[%d] = %10lu\n",
i,
*pdword );
pdword++;
i++;
}
DnsPrint_Unlock();
}
VOID
DnsPrint_RpcStatsBuffer(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pPrintContext,
IN LPSTR pszHeader,
IN PDNS_RPC_BUFFER pBuffer
)
/*++
Routine Description:
Debug print stats buffer.
Arguments:
pBuffer -- buffer containing stats to print
Return Value:
None.
--*/
{
PDNSSRV_STAT pstat;
PCHAR pch;
PCHAR pchstop;
DnsPrint_Lock();
if ( pszHeader )
{
PrintRoutine( pPrintContext, pszHeader );
}
pch = pBuffer->Buffer;
pchstop = pch + pBuffer->dwLength;
while ( pch < pchstop )
{
pstat = (PDNSSRV_STAT) pch;
pch = (PCHAR) GET_NEXT_STAT_IN_BUFFER( pstat );
if ( pch > pchstop )
{
PrintRoutine( pPrintContext, "ERROR: invalid stats buffer!!!\n" );
break;
}
DnsPrint_RpcSingleStat(
PrintRoutine, pPrintContext,
NULL,
pstat );
}
PrintRoutine( pPrintContext, "\n\n" );
DnsPrint_Unlock();
}
VOID
printStatTypeArray(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pPrintContext,
IN LPSTR pszHeader,
IN PDWORD pArray
)
/*++
Routine Description:
Debug print stats type array.
Arguments:
Return Value:
None.
--*/
{
register DWORD i;
PrintRoutine( pPrintContext,
"%s\n",
pszHeader );
//
// print counts for all types
// - skip mixed and unknown bins until end
//
for ( i=0; i<STATS_TYPE_MAX; i++ )
{
if ( i == STATS_TYPE_MIXED || i == STATS_TYPE_UNKNOWN )
{
continue;
}
PrintRoutine( pPrintContext,
" %-10s = %d\n",
Dns_RecordStringForType( (WORD)i ),
pArray[i] );
}
PrintRoutine( pPrintContext,
" %-10s = %d\n",
"Unknown",
pArray[STATS_TYPE_UNKNOWN] );
PrintRoutine( pPrintContext,
" %-10s = %d\n"
"\n",
"Mixed",
pArray[STATS_TYPE_MIXED] );
}
VOID
DnsPrint_RpcSingleStat(
IN PRINT_ROUTINE PrintRoutine,
IN OUT PPRINT_CONTEXT pPrintContext,
IN LPSTR pszHeader,
IN PDNSSRV_STAT pStat
)
/*++
Routine Description:
Debug print stats structure.
Arguments:
None.
Return Value:
None.
--*/
{
DNS_STATUS status;
//
// validity check stat
//
status = DnssrvValidityCheckStatistic( pStat );
if ( status != ERROR_SUCCESS )
{
DnsPrint_RpcStatRaw(
PrintRoutine, pPrintContext,
pszHeader,
pStat,
status );
return;
}
DnsPrint_Lock();
if ( pszHeader )
{
PrintRoutine( pPrintContext, pszHeader );
}
//
// switch on stats type
//
switch ( pStat->Header.StatId )
{
case DNSSRV_STATID_TIME:
{
PDNSSRV_TIME_STATS pstat = (PDNSSRV_TIME_STATS)pStat;
SYSTEMTIME localTime;
CHAR szdate[30];
CHAR sztime[20];
SystemTimeToTzSpecificLocalTime(
NULL, // use local time
(PSYSTEMTIME) & pstat->ServerStartTime,
& localTime );
GetDateFormat(
LOCALE_SYSTEM_DEFAULT,
LOCALE_NOUSEROVERRIDE,
// (PSYSTEMTIME) &pstat->ServerStartTime,
& localTime,
NULL,
szdate,
30 );
GetTimeFormat(
LOCALE_SYSTEM_DEFAULT,
LOCALE_NOUSEROVERRIDE,
// (PSYSTEMTIME) &pstat->ServerStartTime,
& localTime,
NULL,
sztime,
20 );
PrintRoutine( pPrintContext,
"\n"
"DNS Server Time Statistics\n"
"--------------------------\n"
"Server start time %s %s\n"
"Seconds since start %10lu\n",
szdate,
sztime,
pstat->SecondsSinceServerStart
);
SystemTimeToTzSpecificLocalTime(
NULL, // use local time
(PSYSTEMTIME) & pstat->LastClearTime,
& localTime );
GetDateFormat(
LOCALE_SYSTEM_DEFAULT,
LOCALE_NOUSEROVERRIDE,
// (PSYSTEMTIME) &pstat->LastClearTime,
& localTime,
NULL,
szdate,
30 );
GetTimeFormat(
LOCALE_SYSTEM_DEFAULT,
LOCALE_NOUSEROVERRIDE,
// (PSYSTEMTIME) &pstat->LastClearTime,
& localTime,
NULL,
sztime,
20 );
PrintRoutine( pPrintContext,
"Stats last cleared %s %s\n"
"Seconds since clear %10lu\n",
szdate,
sztime,
pstat->SecondsSinceLastClear
);
break;
}
case DNSSRV_STATID_QUERY:
{
PDNSSRV_QUERY_STATS pstat = (PDNSSRV_QUERY_STATS)pStat;
PrintRoutine( pPrintContext,
"\n"
"Queries and Responses:\n"
"----------------------\n"
"Total:\n"
" Queries Received = %10lu\n"
" Responses Sent = %10lu\n"
"UDP:\n"
" Queries Recvd = %10lu\n"
" Responses Sent = %10lu\n"
" Queries Sent = %10lu\n"
" Responses Recvd = %10lu\n"
"TCP:\n"
" Client Connects = %10lu\n"
" Queries Recvd = %10lu\n"
" Responses Sent = %10lu\n"
" Queries Sent = %10lu\n"
" Responses Recvd = %10lu\n",
pstat->UdpQueries + pstat->TcpQueries,
pstat->UdpResponses + pstat->TcpResponses,
pstat->UdpQueries,
pstat->UdpResponses,
pstat->UdpQueriesSent,
pstat->UdpResponsesReceived,
pstat->TcpClientConnections,
pstat->TcpQueries,
pstat->TcpResponses,
pstat->TcpQueriesSent,
pstat->TcpResponsesReceived
);
break;
}
case DNSSRV_STATID_QUERY2:
{
PDNSSRV_QUERY2_STATS pstat = (PDNSSRV_QUERY2_STATS)pStat;
PrintRoutine( pPrintContext,
"\n"
"Queries:\n"
"--------\n"
"Total = %10lu\n"
" Notify = %10lu\n"
" Update = %10lu\n"
" TKeyNego = %10lu\n"
" Standard = %10lu\n"
" A = %10lu\n"
" NS = %10lu\n"
" SOA = %10lu\n"
" MX = %10lu\n"
" PTR = %10lu\n"
" SRV = %10lu\n"
" ALL = %10lu\n"
" IXFR = %10lu\n"
" AXFR = %10lu\n"
" OTHER = %10lu\n",
pstat->TotalQueries,
pstat->Notify,
pstat->Update,
pstat->TKeyNego,
pstat->Standard,
pstat->TypeA,
pstat->TypeNs,
pstat->TypeSoa,
pstat->TypeMx,
pstat->TypePtr,
pstat->TypeSrv,
pstat->TypeAll,
pstat->TypeIxfr,
pstat->TypeAxfr,
pstat->TypeOther
);
break;
}
case DNSSRV_STATID_RECURSE:
{
PDNSSRV_RECURSE_STATS pstat = (PDNSSRV_RECURSE_STATS)pStat;
PrintRoutine( pPrintContext,
"\n"
"Recursion:\n"
"----------\n"
"Query:\n"
" Queries Recursed = %10lu\n"
" Original Questions = %10lu\n"
" Additional Question = %10lu\n"
" Total Questions = %10lu\n"
" Retries = %10lu\n"
" Total Passes = %10lu\n"
" ToForwarders = %10lu\n"
" Sends = %10lu\n",
pstat->QueriesRecursed,
pstat->OriginalQuestionRecursed,
pstat->AdditionalRecursed,
pstat->TotalQuestionsRecursed,
pstat->Retries,
pstat->LookupPasses,
pstat->Forwards,
pstat->Sends );
PrintRoutine( pPrintContext,
"\n"
"Response:\n"
" TotalResponses = %10lu\n"
" Unmatched = %10lu\n"
" Mismatched = %10lu\n"
" FromForwarder = %10lu\n"
" Authoritative = %10lu\n"
" NotAuthoritative = %10lu\n"
" Answer = %10lu\n"
" Empty = %10lu\n"
" NameError = %10lu\n"
" Rcode = %10lu\n"
" Delegation = %10lu\n"
" NonZoneData = %10lu\n"
" Unsecure = %10lu\n"
" BadPacket = %10lu\n"
"Process Response:\n"
" Forward Response = %10lu\n"
" Continue Recursion = %10lu\n"
" Continue Lookup = %10lu\n"
" Next Lookup = %10lu\n",
pstat->Responses,
pstat->ResponseUnmatched,
pstat->ResponseMismatched,
pstat->ResponseFromForwarder,
pstat->ResponseAuthoritative,
pstat->ResponseNotAuth,
pstat->ResponseAnswer,
pstat->ResponseEmpty,
pstat->ResponseNameError,
pstat->ResponseRcode,
pstat->ResponseDelegation,
pstat->ResponseNonZoneData,
pstat->ResponseUnsecure,
pstat->ResponseBadPacket,
pstat->SendResponseDirect,
pstat->ContinueCurrentRecursion,
pstat->ContinueCurrentLookup,
pstat->ContinueNextLookup );
PrintRoutine( pPrintContext,
"\n"
"Timeouts:\n"
" Send Timeouts = %10lu\n"
" Final Queued = %10lu\n"
" Final Expired = %10lu\n"
"\n"
"Failures:\n"
" Recurse Failures = %10lu\n"
" Into Authority = %10lu\n"
" Previous Zone = %10lu\n"
" Retry Limit = %10lu\n"
" Partial (HaveAnswer) = %10lu\n"
" Cache Update = %10lu\n"
" Server Failure Resp = %10lu\n"
" Total Failures = %10lu\n",
pstat->PacketTimeout,
pstat->FinalTimeoutQueued,
pstat->FinalTimeoutExpired,
pstat->RecursePassFailure,
pstat->FailureReachAuthority,
pstat->FailureReachPreviousResponse,
pstat->FailureRetryCount,
pstat->PartialFailure,
pstat->CacheUpdateFailure,
pstat->ServerFailure,
pstat->Failures
);
PrintRoutine( pPrintContext,
"\n"
"TCP Recursion:\n"
" Try = %10lu\n"
" Query = %10lu\n"
" Response = %10lu\n"
" Disconnects = %10lu\n"
"\n"
"Cache Update Queries:\n"
" Query = %10lu\n"
" Response = %10lu\n"
" Retry = %10lu\n"
" Free = %10lu\n"
" Root NS Query = %10lu\n"
" Root NS Response = %10lu\n"
" Suspended Query = %10lu\n"
" Resume Suspended = %10lu\n"
"\n",
pstat->TcpTry,
pstat->TcpQuery,
pstat->TcpResponse,
pstat->TcpDisconnect,
pstat->CacheUpdateAlloc,
pstat->CacheUpdateResponse,
pstat->CacheUpdateRetry,
pstat->CacheUpdateFree,
pstat->RootNsQuery,
pstat->RootNsResponse,
pstat->SuspendedQuery,
pstat->ResumeSuspendedQuery );
PrintRoutine( pPrintContext,
"\n"
"Other:\n"
" Discarded duplicates = %10lu\n"
"\n",
pstat->DiscardedDuplicateQueries );
break;
}
case DNSSRV_STATID_MASTER:
{
PDNSSRV_MASTER_STATS pstat = (PDNSSRV_MASTER_STATS)pStat;
PrintRoutine( pPrintContext,
"\n"
"Master Stats:\n"
"-------------\n"
"Notifies Sent = %10lu\n"
"\n"
"Requests = %10lu\n"
" NameError = %10lu\n"
" FormError = %10lu\n"
" Refused = %10lu\n"
" AxfrLimit = %10lu\n"
" Security = %10lu\n"
" Shutdown = %10lu\n"
" ZoneLocked = %10lu\n"
" ServerFailure = %10lu\n"
" Failure = %10lu\n"
" Success = %10lu\n"
"\n"
"AXFR Request = %10lu\n"
" Success = %10lu\n"
" In IXFR = %10lu\n"
"\n"
"IXFR Request = %10lu\n"
" Success Update = %10lu\n"
" UDP Request = %10lu\n"
" Success = %10lu\n"
" Force TCP = %10lu\n"
" Force Full = %10lu\n"
" TCP Request = %10lu\n"
" Success = %10lu\n"
" Do Full = %10lu\n"
"\n",
pstat->NotifySent,
pstat->Request,
pstat->NameError,
pstat->FormError,
pstat->Refused,
pstat->AxfrLimit,
pstat->RefuseSecurity,
pstat->RefuseShutdown,
pstat->RefuseZoneLocked,
pstat->RefuseServerFailure,
pstat->Failure,
(pstat->AxfrSuccess + pstat->IxfrUpdateSuccess),
pstat->AxfrRequest,
pstat->AxfrSuccess,
pstat->IxfrAxfr,
pstat->IxfrRequest,
pstat->IxfrUpdateSuccess,
pstat->IxfrUdpRequest,
pstat->IxfrUdpSuccess,
pstat->IxfrUdpForceTcp,
pstat->IxfrUdpForceAxfr,
pstat->IxfrTcpRequest,
pstat->IxfrTcpSuccess,
pstat->IxfrAxfr
);
break;
}
case DNSSRV_STATID_SECONDARY:
{
PDNSSRV_SECONDARY_STATS pstat = (PDNSSRV_SECONDARY_STATS)pStat;
PrintRoutine( pPrintContext,
"\n"
"Secondary Stats:\n"
"----------------\n"
"NOTIFY:\n"
" Received = %10lu\n"
" Invalid = %10lu\n"
" Primary = %10lu\n"
" No Version = %10lu\n"
" New Version = %10lu\n"
" Current Version = %10lu\n"
" Old Version = %10lu\n"
" Master Unknown = %10lu\n"
"\n"
"SOA Query:\n"
" Request = %10lu\n"
" Response = %10lu\n"
" Invalid = %10lu\n"
" NameError = %10lu\n"
"\n"
"AXFR:\n"
" AXFR Request = %10lu\n"
" AXFR in IXFR = %10lu\n"
" Response = %10lu\n"
" Success = %10lu\n"
" Refused = %10lu\n"
" Invalid = %10lu\n"
"\n"
"Stub zone AXFR:\n"
" Stub AXFR Request = %10lu\n"
" Response = %10lu\n"
" Success = %10lu\n"
" Refused = %10lu\n"
" Invalid = %10lu\n"
"\n"
"IXFR UDP:\n"
" Request = %10lu\n"
" Response = %10lu\n"
" Success = %10lu\n"
" UseTcp = %10lu\n"
" UseAxfr = %10lu\n"
" New Primary = %10lu\n"
" Refused = %10lu\n"
" Wrong Server = %10lu\n"
" FormError = %10lu\n"
" Invalid = %10lu\n"
"\n"
"IXFR TCP:\n"
" Request = %10lu\n"
" Response = %10lu\n"
" Success = %10lu\n"
" AXFR = %10lu\n"
" FormError = %10lu\n"
" Refused = %10lu\n"
" Invalid = %10lu\n"
"\n",
pstat->NotifyReceived,
pstat->NotifyInvalid,
pstat->NotifyPrimary,
pstat->NotifyNoVersion,
pstat->NotifyNewVersion,
pstat->NotifyCurrentVersion,
pstat->NotifyOldVersion,
pstat->NotifyMasterUnknown,
pstat->SoaRequest,
pstat->SoaResponse,
pstat->SoaResponseInvalid,
pstat->SoaResponseNameError,
pstat->AxfrRequest,
pstat->IxfrTcpAxfr,
pstat->AxfrResponse,
pstat->AxfrSuccess,
pstat->AxfrRefused,
pstat->AxfrInvalid,
pstat->StubAxfrRequest,
pstat->StubAxfrResponse,
pstat->StubAxfrSuccess,
pstat->StubAxfrRefused,
pstat->StubAxfrInvalid,
pstat->IxfrUdpRequest,
pstat->IxfrUdpResponse,
pstat->IxfrUdpSuccess,
pstat->IxfrUdpUseTcp,
pstat->IxfrUdpUseAxfr,
pstat->IxfrUdpNewPrimary,
pstat->IxfrUdpRefused,
pstat->IxfrUdpWrongServer,
pstat->IxfrUdpFormerr,
pstat->IxfrUdpInvalid,
pstat->IxfrTcpRequest,
pstat->IxfrTcpResponse,
pstat->IxfrTcpSuccess,
pstat->IxfrTcpAxfr,
pstat->IxfrTcpFormerr,
pstat->IxfrTcpRefused,
pstat->IxfrTcpInvalid
);
break;
}
case DNSSRV_STATID_WINS:
{
PDNSSRV_WINS_STATS pstat = (PDNSSRV_WINS_STATS)pStat;
PrintRoutine( pPrintContext,
"\n"
"WINS Referrals:\n"
"---------------\n"
"Forward:\n"
" Lookups = %10lu\n"
" Responses = %10lu\n"
"Reverse:\n"
" Lookups = %10lu\n"
" Responses = %10lu\n",
pstat->WinsLookups,
pstat->WinsResponses,
pstat->WinsReverseLookups,
pstat->WinsReverseResponses
);
break;
}
case DNSSRV_STATID_NBSTAT:
{
PDNSSRV_NBSTAT_STATS pstat = (PDNSSRV_NBSTAT_STATS)pStat;
PrintRoutine( pPrintContext,
"\n"
"Nbstat Memory Usage:\n"
"--------------------\n"
"Nbstat Buffers:\n"
" Alloc = %10lu\n"
" Free = %10lu\n"
" NetAllocs = %10lu\n"
" Memory = %10lu\n"
" Used = %10lu\n"
" Returned = %10lu\n"
" InUse = %10lu\n"
" InFreeList = %10lu\n"
"\n",
pstat->NbstatAlloc,
pstat->NbstatFree,
pstat->NbstatNetAllocs,
pstat->NbstatMemory,
pstat->NbstatUsed,
pstat->NbstatReturn,
pstat->NbstatInUse,
pstat->NbstatInFreeList
);
break;
}
case DNSSRV_STATID_WIRE_UPDATE:
case DNSSRV_STATID_NONWIRE_UPDATE:
{
PDNSSRV_UPDATE_STATS pstat = (PDNSSRV_UPDATE_STATS)pStat;
PrintRoutine( pPrintContext,
"\n"
"%s:\n"
"--------------------------\n"
"Updates Received = %10lu\n"
" Forwarded = %10lu\n"
" Empty (PreCon Only) = %10lu\n"
" NoOps (Dups) = %10lu\n"
" Rejected = %10lu\n"
" Completed = %10lu\n"
" Timed Out = %10lu\n"
" In Queue = %10lu\n"
"\n"
"Updates Rejected = %10lu\n"
" FormError = %10lu\n"
" NameError = %10lu\n"
" NotImpl = %10lu (Non-Update Zone)\n"
" Refused = %10lu\n"
" NonSecure Packet = %10lu\n"
" AccessDenied = %10lu\n"
" YxDomain = %10lu\n"
" YxRRSet = %10lu\n"
" NxRRSet = %10lu\n"
" NotAuth = %10lu\n"
" NotZone = %10lu\n"
"\n"
#if 0 // unused counters
"Update Collisions = %10lu\n"
" Read = %10lu\n"
" Write = %10lu\n"
" In LDAP = %10lu\n"
"\n"
#endif
"Queue\n"
" Queued = %10lu\n"
" Retried = %10lu\n"
" Timeout = %10lu\n"
" In Queue = %10lu\n"
"\n"
"Secure Update\n"
" Success = %10lu\n"
" Continue = %10lu\n"
" Failure = %10lu\n"
" DS Write Failure = %10lu\n"
"\n"
"Update Forwarding\n"
" Forwards = %10lu\n"
" TCP Forwards = %10lu\n"
" Responses = %10lu\n"
" Timed Out = %10lu\n"
" In Queue = %10lu\n"
"\n",
pStat->Header.StatId == DNSSRV_STATID_WIRE_UPDATE ?
"Packet Dynamic Update" :
"Internal Dynamic Update",
pstat->Received,
pstat->Forwards,
pstat->Empty,
pstat->NoOps,
pstat->Rejected,
pstat->Completed,
pstat->Timeout,
pstat->InQueue,
pstat->Rejected,
pstat->FormErr,
pstat->NxDomain,
pstat->NotImpl,
pstat->Refused,
pstat->RefusedNonSecure,
pstat->RefusedAccessDenied,
pstat->YxDomain,
pstat->YxRrset,
pstat->NxRrset,
pstat->NotAuth,
pstat->NotZone,
#if 0 // unused counters
pstat->Collisions,
pstat->CollisionsRead,
pstat->CollisionsWrite,
pstat->CollisionsDsWrite,
#endif
pstat->Queued,
pstat->Retry,
pstat->Timeout,
pstat->InQueue,
pstat->SecureSuccess,
pstat->SecureContinue,
pstat->SecureFailure,
pstat->SecureDsWriteFailure,
pstat->Forwards,
pstat->TcpForwards,
pstat->ForwardResponses,
pstat->ForwardTimeouts,
pstat->ForwardInQueue
);
printStatTypeArray(
PrintRoutine, pPrintContext,
"Update Types:",
pstat->UpdateType );
break;
}
case DNSSRV_STATID_DS:
{
PDNSSRV_DS_STATS pstat = (PDNSSRV_DS_STATS)pStat;
PrintRoutine( pPrintContext,
"\n"
"DS Integration:\n"
"---------------\n"
"DS Reads:\n"
" Nodes Read Total = %10lu\n"
" Records Read Total = %10lu\n"
" Nodes Loaded = %10lu\n"
" Records Loaded = %10lu\n"
"\n"
" Update Searches = %10lu\n"
" Update Nodes Read = %10lu\n"
" Update Records Read = %10lu\n"
"\n"
"DS Writes:\n"
" Nodes Added = %10lu\n"
" Nodes Modified = %10lu\n"
" Nodes Tombstoned = %10lu\n"
" Nodes Final Delete = %10lu\n"
" Node Write Suppressed = %10lu\n"
" RR Sets Added = %10lu\n"
" RR Sets Replaced = %10lu\n"
" Serial Writes = %10lu\n"
"\n"
" Update Lists = %10lu\n"
" Update Nodes = %10lu\n"
" Suppressed = %10lu\n"
" Writes = %10lu\n"
" Tombstones = %10lu\n"
" Write causes:\n"
" Record Change = %10lu\n"
" Aging Refresh = %10lu\n"
" Aging On = %10lu\n"
" Aging Off = %10lu\n"
" Write sources:\n"
" Packet = %10lu\n"
" Precon Only = %10lu\n"
" Admin = %10lu\n"
" Auto Config = %10lu\n"
" Scavenge = %10lu\n",
pstat->DsTotalNodesRead,
pstat->DsTotalRecordsRead,
pstat->DsNodesLoaded,
pstat->DsRecordsLoaded,
pstat->DsUpdateSearches,
pstat->DsUpdateNodesRead,
pstat->DsUpdateRecordsRead,
pstat->DsNodesAdded,
pstat->DsNodesModified,
pstat->DsNodesTombstoned,
pstat->DsNodesDeleted,
pstat->DsWriteSuppressed,
pstat->DsRecordsAdded,
pstat->DsRecordsReplaced,
pstat->DsSerialWrites,
pstat->UpdateLists,
pstat->UpdateNodes,
pstat->UpdateSuppressed,
pstat->UpdateWrites,
pstat->UpdateTombstones,
pstat->UpdateRecordChange,
pstat->UpdateAgingRefresh,
pstat->UpdateAgingOn,
pstat->UpdateAgingOff,
pstat->UpdatePacket,
pstat->UpdatePacketPrecon,
pstat->UpdateAdmin,
pstat->UpdateAutoConfig,
pstat->UpdateScavenge
);
PrintRoutine( pPrintContext,
"\n"
"Tombstones:\n"
" Written = %10lu\n"
" Read = %10lu\n"
" Deleted = %10lu\n"
"\n"
"Write Performance:\n"
" Total = %10lu\n"
" Total Time = %10lu\n"
" Average = %10lu\n"
" < 10ms = %10lu\n"
" < 100ms = %10lu\n"
" < 1s = %10lu\n"
" < 10s = %10lu\n"
" < 100s = %10lu\n"
" > 100s = %10lu\n"
" Max = %10lu\n"
"Search Performance:\n"
" Total (ms) = %10lu\n"
"\n"
"Failures:\n"
" FailedDeleteDsEntries = %10lu\n"
" FailedReadRecords = %10lu\n"
" FailedLdapModify = %10lu\n"
" FailedLdapAdd = %10lu\n"
"\n"
"Polling:\n"
" PollingPassesWithErrors = %10lu\n"
"\n"
"LDAP:\n"
" Reconnects = %10lu\n"
"\n",
pstat->DsNodesTombstoned,
pstat->DsTombstonesRead,
pstat->DsNodesDeleted,
pstat->LdapTimedWrites,
pstat->LdapWriteTimeTotal,
pstat->LdapWriteAverage,
pstat->LdapWriteBucket0,
pstat->LdapWriteBucket1,
pstat->LdapWriteBucket2,
pstat->LdapWriteBucket3,
pstat->LdapWriteBucket4,
pstat->LdapWriteBucket5,
pstat->LdapWriteMax,
pstat->LdapSearchTime,
pstat->FailedDeleteDsEntries,
pstat->FailedReadRecords,
pstat->FailedLdapModify,
pstat->FailedLdapAdd,
pstat->PollingPassesWithDsErrors,
pstat->LdapReconnects );
printStatTypeArray(
PrintRoutine, pPrintContext,
"DS Write Types:",
pstat->DsWriteType );
break;
}
case DNSSRV_STATID_SKWANSEC:
{
PDNSSRV_SKWANSEC_STATS pstat = (PDNSSRV_SKWANSEC_STATS)pStat;
PrintRoutine( pPrintContext,
"\n"
"Security Stats:\n"
"---------------\n"
"\n"
"Security Context:\n"
" Create = %10lu\n"
" Free = %10lu\n"
" Timeout = %10lu\n"
" Queue Length = %10lu\n"
" Queued = %10lu\n"
" In Nego = %10lu\n"
" Nego Complete = %10lu\n"
" DeQueued = %10lu\n"
"\n"
"Security Packet Contexts:\n"
" Alloc = %10lu\n"
" Free = %10lu\n"
"\n"
"TKEY:\n"
" Invalid = %10lu\n"
" BadTime = %10lu\n"
"\n"
"TSIG:\n"
" Formerr = %10lu\n"
" Echo = %10lu\n"
" BadKey = %10lu\n"
" Verify Success = %10lu\n"
" Verify Failed = %10lu\n"
"\n",
pstat->SecContextCreate,
pstat->SecContextFree,
pstat->SecContextTimeout,
pstat->SecContextQueueLength,
pstat->SecContextQueue,
pstat->SecContextQueueInNego,
pstat->SecContextQueueNegoComplete,
pstat->SecContextDequeue,
pstat->SecPackAlloc,
pstat->SecPackFree,
pstat->SecTkeyInvalid,
pstat->SecTkeyBadTime,
pstat->SecTsigFormerr,
pstat->SecTsigEcho,
pstat->SecTsigBadKey,
pstat->SecTsigVerifySuccess,
pstat->SecTsigVerifyFailed
);
break;
}
case DNSSRV_STATID_MEMORY:
{
PDNSSRV_MEMORY_STATS pstat = (PDNSSRV_MEMORY_STATS) pStat;
DWORD i;
LPSTR * pnameArray;
DWORD count;
pnameArray = MemTagStrings;
count = MEMTAG_COUNT;
PrintRoutine( pPrintContext,
"\n"
"Memory Stats:\n"
"-------------\n"
"Memory:\n"
" Total Memory = %10lu\n"
" Alloc Count = %10lu\n"
" Free Count = %10lu\n"
"\n"
"Standard Allocs:\n"
" Used = %10lu\n"
" Returned = %10lu\n"
" InUse = %10lu\n"
" Memory = %10lu\n"
"\n"
"Standard To Heap:\n"
" Alloc = %10lu\n"
" Free = %10lu\n"
" InUse = %10lu\n"
" Memory = %10lu\n"
"\n"
"Standard Blocks:\n"
" Alloc = %10lu\n"
" Used = %10lu\n"
" Returned = %10lu\n"
" InUse = %10lu\n"
" FreeList = %10lu\n"
" FreeList Memory = %10lu\n"
" Total Memory = %10lu\n"
"\n"
"Tagged Allocations:\n",
pstat->Memory,
pstat->Alloc,
pstat->Free,
pstat->StdUsed,
pstat->StdReturn,
pstat->StdInUse,
pstat->StdMemory,
pstat->StdToHeapAlloc,
pstat->StdToHeapFree,
pstat->StdToHeapInUse,
pstat->StdToHeapMemory,
pstat->StdBlockAlloc,
pstat->StdBlockUsed,
pstat->StdBlockReturn,
pstat->StdBlockInUse,
pstat->StdBlockFreeList,
pstat->StdBlockFreeListMemory,
pstat->StdBlockMemory
);
for ( i=0; i<count; i++ )
{
PrintRoutine( pPrintContext,
" %s\n"
" Alloc = %10lu\n"
" Free = %10lu\n"
" InUse = %10lu\n"
" Mem = %10lu\n",
pnameArray[ i ],
pstat->MemTags[ i ].Alloc,
pstat->MemTags[ i ].Free,
pstat->MemTags[ i ].Alloc - pstat->MemTags[i].Free,
pstat->MemTags[ i ].Memory );
}
break;
}
case DNSSRV_STATID_DBASE:
{
PDNSSRV_DBASE_STATS pstat = (PDNSSRV_DBASE_STATS)pStat;
PrintRoutine( pPrintContext,
"\n"
"Database Nodes:\n"
"---------------\n"
"Nodes:\n"
" Used = %10lu\n"
" Returned = %10lu\n"
" InUse = %10lu\n"
" Memory = %10lu\n"
"\n",
pstat->NodeUsed,
pstat->NodeReturn,
pstat->NodeInUse,
pstat->NodeMemory
);
break;
}
case DNSSRV_STATID_RECORD:
{
PDNSSRV_RECORD_STATS pstat = (PDNSSRV_RECORD_STATS)pStat;
PrintRoutine( pPrintContext,
"\n"
"Records:\n"
"--------\n"
"Flow:\n"
" Used = %10lu\n"
" Returned = %10lu\n"
" InUse = %10lu\n"
" SlowFree Queued = %10lu\n"
" SlowFree Completed = %10lu\n"
" Memory = %10lu\n"
"\n"
"Caching:\n"
" Total = %10lu\n"
" Timeouts = %10lu\n"
" In Use = %10lu\n"
"\n",
pstat->Used,
pstat->Return,
pstat->InUse,
pstat->SlowFreeQueued,
pstat->SlowFreeFinished,
pstat->Memory,
pstat->CacheTotal,
pstat->CacheTimeouts,
pstat->CacheCurrent );
break;
}
case DNSSRV_STATID_PACKET:
{
PDNSSRV_PACKET_STATS pstat = (PDNSSRV_PACKET_STATS)pStat;
PrintRoutine( pPrintContext,
"\n"
"Packet Memory Usage:\n"
"--------------------\n"
"UDP Messages:\n"
" Alloc = %10lu\n"
" Free = %10lu\n"
" NetAllocs = %10lu\n"
" Memory = %10lu\n"
" Used = %10lu\n"
" Returned = %10lu\n"
" InUse = %10lu\n"
" InFreeList = %10lu\n",
pstat->UdpAlloc,
pstat->UdpFree,
pstat->UdpNetAllocs,
pstat->UdpMemory,
pstat->UdpUsed,
pstat->UdpReturn,
pstat->UdpInUse,
pstat->UdpInFreeList
);
//
// NS List stats added after Whistler beta 2.
//
PrintRoutine( pPrintContext,
" NsListUsed = %10lu\n"
" NsListReturned = %10lu\n"
" NsListInUse = %10lu\n",
pstat->PacketsForNsListUsed,
pstat->PacketsForNsListReturned,
pstat->PacketsForNsListInUse );
PrintRoutine( pPrintContext,
"\n"
"TCP Messages:\n"
" Alloc = %10lu\n"
" Realloc = %10lu\n"
" Free = %10lu\n"
" NetAllocs = %10lu\n"
" Memory = %10lu\n"
"\n"
"Recursion Messages:\n"
" Used = %10lu\n"
" Returned = %10lu\n"
"\n",
pstat->TcpAlloc,
pstat->TcpRealloc,
pstat->TcpFree,
pstat->TcpNetAllocs,
pstat->TcpMemory,
pstat->RecursePacketUsed,
pstat->RecursePacketReturn
);
break;
}
case DNSSRV_STATID_TIMEOUT:
{
PDNSSRV_TIMEOUT_STATS pstat = (PDNSSRV_TIMEOUT_STATS)pStat;
PrintRoutine( pPrintContext,
"\n"
"Timeout:\n"
"--------\n"
"Nodes Queued\n"
" Total = %10lu\n"
" Direct = %10lu\n"
" FromReference = %10lu\n"
" FromChildDelete = %10lu\n"
" Dup Already Queued = %10lu\n"
"Nodes Checked\n"
" Total = %10lu\n"
" RecentAccess = %10lu\n"
" ActiveRecord = %10lu\n"
" CanNotDelete = %10lu\n"
" Deleted = %10lu\n"
"TimeoutBlocks\n"
" Created = %10lu\n"
" Deleted = %10lu\n"
"Delayed Frees\n"
" Queued = %10lu\n"
" WithFunction = %10lu\n"
" Executed = %10lu\n"
" WithFunction = %10lu\n",
pstat->SetTotal,
pstat->SetDirect,
pstat->SetFromDereference,
pstat->SetFromChildDelete,
pstat->AlreadyInSystem,
pstat->Checks,
pstat->RecentAccess,
pstat->ActiveRecord,
pstat->CanNotDelete,
pstat->Deleted,
pstat->ArrayBlocksCreated,
pstat->ArrayBlocksDeleted,
pstat->DelayedFreesQueued,
pstat->DelayedFreesQueuedWithFunction,
pstat->DelayedFreesExecuted,
pstat->DelayedFreesExecutedWithFunction
);
break;
}
case DNSSRV_STATID_ERRORS:
{
PDNSSRV_ERROR_STATS pstat = (PDNSSRV_ERROR_STATS)pStat;
PrintRoutine( pPrintContext,
"\n"
"Error Stats:\n"
"--------------\n"
"\n"
" NoError = %10lu\n"
" FormError = %10lu\n"
" ServFail = %10lu\n"
" NxDomain = %10lu\n"
" NotImpl = %10lu\n"
" Refused = %10lu\n"
" YxDomain = %10lu\n"
" YxRRSet = %10lu\n"
" NxRRSet = %10lu\n"
" NotAuth = %10lu\n"
" NotZone = %10lu\n"
" Max = %10lu\n"
" BadSig = %10lu\n"
" BadKey = %10lu\n"
" BadTime = %10lu\n"
" UnknownError = %10lu\n"
"\n",
pstat->NoError,
pstat->FormError,
pstat->ServFail,
pstat->NxDomain,
pstat->NotImpl,
pstat->Refused,
pstat->YxDomain,
pstat->YxRRSet,
pstat->NxRRSet,
pstat->NotAuth,
pstat->NotZone,
pstat->Max,
pstat->BadSig,
pstat->BadKey,
pstat->BadTime,
pstat->UnknownError
);
break;
}
case DNSSRV_STATID_CACHE:
{
PDNSSRV_CACHE_STATS pstat = ( PDNSSRV_CACHE_STATS ) pStat;
PrintRoutine( pPrintContext,
"\n"
"Cache Stats:\n"
"------------\n"
" Checks where cache exceeded limit = %10lu\n"
" Successful cache enforcement passes = %10lu\n"
" Failed cache enforcement passes = %10lu\n"
" Passes that required aggressive free = %10lu\n"
" Passes where nothing was freed = %10lu\n\n",
pstat->CacheExceededLimitChecks,
pstat->SuccessfulFreePasses,
pstat->FailedFreePasses,
pstat->PassesRequiringAggressiveFree,
pstat->PassesWithNoFrees );
break;
}
case DNSSRV_STATID_PRIVATE:
{
PDNSSRV_PRIVATE_STATS pstat = (PDNSSRV_PRIVATE_STATS)pStat;
PrintRoutine( pPrintContext,
"\n"
"Private Stats:\n"
"--------------\n"
"\n"
"Record Sources:\n"
" RR File = %10lu\n"
" RR File Free = %10lu\n"
" RR DS = %10lu\n"
" RR DS Free = %10lu\n"
" RR Admin = %10lu\n"
" RR Admin Free = %10lu\n"
" RR DynUp = %10lu\n"
" RR DynUp Free = %10lu\n"
" RR Axfr = %10lu\n"
" RR Axfr Free = %10lu\n"
" RR Ixfr = %10lu\n"
" RR Ixfr Free = %10lu\n"
" RR Copy = %10lu\n"
" RR Copy Free = %10lu\n"
" RR Cache = %10lu\n"
" RR Cache Free = %10lu\n"
#if 0
" RR NoExist = %10lu\n"
" RR NoExist Free = %10lu\n"
" RR Wins = %10lu\n"
" RR Wins Free = %10lu\n"
" RR WinsPtr = %10lu\n"
" RR WinsPtr Free = %10lu\n"
" RR Auto = %10lu\n"
" RR Auto Free = %10lu\n"
" RR Unknown = %10lu\n"
" RR Unknown Free = %10lu\n"
#endif
"\n"
"UDP Sockets:\n"
" PnP Socket Delete = %10lu\n"
" Recvfrom Failure = %10lu\n"
" ConnResets = %10lu\n"
" ConnReset Overflow = %10lu\n"
" GQCS Failure = %10lu\n"
" GQCS Failure wCntxt = %10lu\n"
" GQCS ConnReset = %10lu\n"
" Indicate Recv Fail = %10lu\n"
" Restart Recv Pass = %10lu\n"
"\n"
"TCP Connections:\n"
" ConnectAttempt = %10lu\n"
" ConnectFailure = %10lu\n"
" Connect = %10lu\n"
" Query = %10lu\n"
" Disconnect = %10lu\n"
"\n"
"Security stats:\n"
" Verified Old Sig = %10lu\n"
" Failed Old Sig = %10lu\n"
" Big TimeSkew Bypass = %10lu\n"
"\n",
pstat->RecordFile,
pstat->RecordFileFree,
pstat->RecordDs,
pstat->RecordDsFree,
pstat->RecordAdmin,
pstat->RecordAdminFree,
pstat->RecordDynUp,
pstat->RecordDynUpFree,
pstat->RecordAxfr,
pstat->RecordAxfrFree,
pstat->RecordIxfr,
pstat->RecordIxfrFree,
pstat->RecordCopy,
pstat->RecordCopyFree,
pstat->RecordCache,
pstat->RecordCacheFree,
#if 0
pstat->RecordNoExist,
pstat->RecordNoExistFree,
pstat->RecordWins,
pstat->RecordWinsFree,
pstat->RecordWinsPtr,
pstat->RecordWinsPtrFree,
pstat->RecordAuto,
pstat->RecordAutoFree,
pstat->RecordUnknown,
pstat->RecordUnknownFree,
#endif
pstat->UdpSocketPnpDelete,
pstat->UdpRecvFailure,
pstat->UdpConnResets,
pstat->UdpConnResetRetryOverflow,
pstat->UdpGQCSFailure,
pstat->UdpGQCSFailureWithContext,
pstat->UdpGQCSConnReset,
pstat->UdpIndicateRecvFailures,
pstat->UdpRestartRecvOnSockets,
pstat->TcpConnectAttempt,
pstat->TcpConnectFailure,
pstat->TcpConnect,
pstat->TcpQuery,
pstat->TcpDisconnect,
pstat->SecTsigVerifyOldSig,
pstat->SecTsigVerifyOldFailed,
pstat->SecBigTimeSkewBypass
);
break;
}
default:
DnsPrint_RpcStatRaw(
PrintRoutine, pPrintContext,
NULL,
pStat,
DNS_ERROR_INVALID_TYPE );
break;
} // end switch
DnsPrint_Unlock();
}
//
// End of print.c
//