1259 lines
28 KiB
C
1259 lines
28 KiB
C
/*++
|
||
|
||
Copyright (c) 1995 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
nt4api.c
|
||
|
||
Abstract:
|
||
|
||
Domain Name System (DNS) Server -- Admin Client API
|
||
|
||
DNS NT4 API that are not direct calls to RPC stubs.
|
||
|
||
Author:
|
||
|
||
Jim Gilroy (jamesg) 14-Oct-1995
|
||
|
||
Environment:
|
||
|
||
User Mode - Win32
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
|
||
#include "dnsclip.h"
|
||
|
||
|
||
|
||
VOID
|
||
DNS_API_FUNCTION
|
||
Dns4_FreeZoneInfo(
|
||
IN OUT PDNS4_ZONE_INFO pZoneInfo
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Deep free of DNS4_ZONE_INFO structure.
|
||
|
||
Arguments:
|
||
|
||
pZoneInfo -- ptr to zone info to free
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
if ( !pZoneInfo )
|
||
{
|
||
return;
|
||
}
|
||
|
||
//
|
||
// free substructures
|
||
// - name string
|
||
// - data file string
|
||
// - secondary IP array
|
||
// - WINS server array
|
||
//
|
||
|
||
if ( pZoneInfo->pszZoneName )
|
||
{
|
||
MIDL_user_free( pZoneInfo->pszZoneName );
|
||
}
|
||
if ( pZoneInfo->pszDataFile )
|
||
{
|
||
MIDL_user_free( pZoneInfo->pszDataFile );
|
||
}
|
||
if ( pZoneInfo->aipMasters )
|
||
{
|
||
MIDL_user_free( pZoneInfo->aipMasters );
|
||
}
|
||
if ( pZoneInfo->aipSecondaries )
|
||
{
|
||
MIDL_user_free( pZoneInfo->aipSecondaries );
|
||
}
|
||
|
||
//
|
||
// free DNS4_ZONE_INFO struct itself
|
||
//
|
||
|
||
MIDL_user_free( pZoneInfo );
|
||
}
|
||
|
||
|
||
|
||
DNS_STATUS
|
||
DNS_API_FUNCTION
|
||
Dns4_ResetZoneMaster(
|
||
IN LPCSTR Server,
|
||
IN DNS_HANDLE hZone,
|
||
IN IP_ADDRESS ipMaster
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Reset one zone master
|
||
|
||
--*/
|
||
{
|
||
IP_ADDRESS ipBuf = ipMaster;
|
||
|
||
return Dns4_ResetZoneMasters(
|
||
Server,
|
||
hZone,
|
||
1,
|
||
& ipBuf );
|
||
}
|
||
|
||
|
||
|
||
DNS_STATUS
|
||
DNS_API_FUNCTION
|
||
Dns4_EnumZoneInfo(
|
||
IN LPCSTR Server,
|
||
OUT PDWORD pdwZoneCount,
|
||
IN DWORD dwArrayCount,
|
||
IN OUT PDNS4_ZONE_INFO apZones[]
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Get zone info for all zones on server.
|
||
|
||
Arguments:
|
||
|
||
Server -- server name
|
||
pdwZoneCount -- addr to recv number of zones on server
|
||
dwArrayCount -- size of zone info ptr array
|
||
apZones -- array to be filled with zone info ptrs
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
DNS_STATUS status;
|
||
PDNS_HANDLE ahZones;
|
||
INT i;
|
||
DWORD zoneCount = 0;
|
||
|
||
IF_DNSDBG( STUB )
|
||
{
|
||
DNS_PRINT((
|
||
"Enter DnsEnumZoneInfo()\n"
|
||
"\tServer = %s\n"
|
||
"\tpdwZoneCount = %p\n"
|
||
"\tdwArrayCount = %d\n"
|
||
"\tapZones = %p\n",
|
||
Server,
|
||
pdwZoneCount,
|
||
dwArrayCount,
|
||
apZones ));
|
||
DnsDbg_DwordArray(
|
||
"Zone array",
|
||
NULL,
|
||
dwArrayCount,
|
||
(PDWORD)apZones );
|
||
}
|
||
|
||
//
|
||
// allocate space
|
||
// - allocate for as many entries as caller is allowing zones
|
||
// zones
|
||
|
||
ahZones = (PDNS_HANDLE) MIDL_user_allocate(
|
||
dwArrayCount * sizeof(DNS_HANDLE) );
|
||
if ( !ahZones )
|
||
{
|
||
return( DNS_ERROR_NO_MEMORY );
|
||
}
|
||
IF_DNSDBG( STUB )
|
||
{
|
||
DNS_PRINT((
|
||
"Allocated zone HANDLE block at %p for up to %d zones\n",
|
||
ahZones,
|
||
dwArrayCount ));
|
||
DnsDbg_DwordArray(
|
||
"Zone handle array",
|
||
NULL,
|
||
dwArrayCount,
|
||
ahZones );
|
||
}
|
||
|
||
//
|
||
// get zone handles
|
||
//
|
||
|
||
status = Dns4_EnumZoneHandles(
|
||
Server,
|
||
& zoneCount,
|
||
dwArrayCount,
|
||
ahZones
|
||
);
|
||
IF_DNSDBG( STUB )
|
||
{
|
||
DNS_PRINT((
|
||
"Under call to DnsEnumZoneHandles() completed.\n"
|
||
"\tstatus = %d (%p)\n"
|
||
"\tzone count = %d\n",
|
||
status, status,
|
||
zoneCount ));
|
||
DnsDbg_DwordArray(
|
||
"Zone handle array",
|
||
NULL,
|
||
(zoneCount < dwArrayCount) ? zoneCount+1 : dwArrayCount,
|
||
ahZones );
|
||
}
|
||
|
||
*pdwZoneCount = zoneCount;
|
||
if ( status != ERROR_SUCCESS )
|
||
{
|
||
return( status );
|
||
}
|
||
|
||
|
||
//
|
||
// get info for each zone
|
||
//
|
||
|
||
for( i=0; i<(INT)zoneCount; i++ )
|
||
{
|
||
apZones[i] = NULL;
|
||
status = Dns4_GetZoneInfo(
|
||
Server,
|
||
ahZones[i],
|
||
& apZones[i] );
|
||
|
||
if ( status != ERROR_SUCCESS )
|
||
{
|
||
goto cleanup;
|
||
}
|
||
}
|
||
|
||
IF_DNSDBG( STUB )
|
||
{
|
||
Dns4_Dbg_RpcZoneInfoList(
|
||
"Leaving DnsEnumZoneInfo() ",
|
||
*pdwZoneCount,
|
||
apZones );
|
||
}
|
||
|
||
cleanup:
|
||
|
||
IF_DNSDBG( STUB )
|
||
{
|
||
if ( status != ERROR_SUCCESS )
|
||
{
|
||
DNS_PRINT((
|
||
"Leaving DnsEnumZoneInfo(), status = %d\n",
|
||
status ));
|
||
}
|
||
}
|
||
MIDL_user_free( ahZones );
|
||
return( status );
|
||
}
|
||
|
||
|
||
|
||
|
||
//
|
||
// NT4 type print
|
||
//
|
||
|
||
VOID
|
||
Dns4_Print_RpcServerInfo(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN LPSTR pszHeader,
|
||
IN PDNS4_RPC_SERVER_INFO pServerInfo
|
||
)
|
||
{
|
||
DnsPrint_Lock();
|
||
if ( pszHeader )
|
||
{
|
||
PrintRoutine( pszHeader );
|
||
}
|
||
|
||
if ( ! pServerInfo )
|
||
{
|
||
PrintRoutine( "NULL server info ptr.\n" );
|
||
}
|
||
else
|
||
{
|
||
PrintRoutine(
|
||
"Server info:\n"
|
||
"\tptr = %p\n"
|
||
"\tversion = %p\n"
|
||
"\tboot registry = %d\n",
|
||
pServerInfo,
|
||
pServerInfo->dwVersion,
|
||
pServerInfo->fBootRegistry );
|
||
|
||
DnsPrint_IpArray(
|
||
PrintRoutine,
|
||
NULL,
|
||
"\tServerAddresses:\n",
|
||
"\tAddr",
|
||
pServerInfo->aipServerAddrs );
|
||
|
||
DnsPrint_IpArray(
|
||
PrintRoutine,
|
||
NULL,
|
||
"\tListenAddresses:\n",
|
||
"\tAddr",
|
||
pServerInfo->aipListenAddrs );
|
||
|
||
DnsPrint_IpArray(
|
||
PrintRoutine,
|
||
NULL,
|
||
"\tForwarders:\n",
|
||
"\tAddr",
|
||
pServerInfo->aipForwarders );
|
||
|
||
PrintRoutine(
|
||
"\tforward timeout = %d\n"
|
||
"\tslave = %d\n",
|
||
pServerInfo->dwForwardTimeout,
|
||
pServerInfo->fSlave );
|
||
}
|
||
DnsPrint_Unlock();
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
Dns4_Print_RpcStatistics(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN LPSTR pszHeader,
|
||
IN PDNS4_STATISTICS pStatistics
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Debug print statistics.
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
CHAR szdate[30];
|
||
CHAR sztime[20];
|
||
|
||
DnsPrint_Lock();
|
||
if ( pszHeader )
|
||
{
|
||
PrintRoutine( pszHeader );
|
||
}
|
||
|
||
GetDateFormat(
|
||
LOCALE_SYSTEM_DEFAULT,
|
||
LOCALE_NOUSEROVERRIDE,
|
||
(PSYSTEMTIME) &pStatistics->ServerStartTime,
|
||
NULL,
|
||
szdate,
|
||
30 );
|
||
GetTimeFormat(
|
||
LOCALE_SYSTEM_DEFAULT,
|
||
LOCALE_NOUSEROVERRIDE,
|
||
(PSYSTEMTIME) &pStatistics->ServerStartTime,
|
||
NULL,
|
||
sztime,
|
||
20 );
|
||
PrintRoutine(
|
||
"\n"
|
||
"DNS Statistics\n"
|
||
"--------------\n"
|
||
"\tServer start time %s %s\n",
|
||
szdate,
|
||
sztime );
|
||
|
||
GetDateFormat(
|
||
LOCALE_SYSTEM_DEFAULT,
|
||
LOCALE_NOUSEROVERRIDE,
|
||
(PSYSTEMTIME) &pStatistics->LastClearTime,
|
||
NULL,
|
||
szdate,
|
||
30 );
|
||
GetTimeFormat(
|
||
LOCALE_SYSTEM_DEFAULT,
|
||
LOCALE_NOUSEROVERRIDE,
|
||
(PSYSTEMTIME) &pStatistics->LastClearTime,
|
||
NULL,
|
||
sztime,
|
||
20 );
|
||
PrintRoutine(
|
||
"\tStats last cleared %s %s\n"
|
||
"\tSeconds since clear %d\n",
|
||
szdate,
|
||
sztime,
|
||
pStatistics->SecondsSinceLastClear
|
||
);
|
||
|
||
//
|
||
// query and response counts
|
||
//
|
||
|
||
PrintRoutine(
|
||
"\n"
|
||
"Queries and Responses:\n"
|
||
"----------------------\n"
|
||
"Total:\n"
|
||
"\tQueries Received = %d\n"
|
||
"\tResponses Sent = %d\n"
|
||
"UDP:\n"
|
||
"\tQueries Recvd = %d\n"
|
||
"\tResponses Sent = %d\n"
|
||
"\tQueries Sent = %d\n"
|
||
"\tResponses Recvd = %d\n"
|
||
"TCP:\n"
|
||
"\tClient Connects = %d\n"
|
||
"\tQueries Recvd = %d\n"
|
||
"\tResponses Sent = %d\n"
|
||
"\tQueries Sent = %d\n"
|
||
"\tResponses Recvd = %d\n",
|
||
pStatistics->UdpQueries + pStatistics->TcpQueries,
|
||
pStatistics->UdpResponses + pStatistics->TcpResponses,
|
||
pStatistics->UdpQueries,
|
||
pStatistics->UdpResponses,
|
||
pStatistics->UdpQueriesSent,
|
||
pStatistics->UdpResponsesReceived,
|
||
pStatistics->TcpClientConnections,
|
||
pStatistics->TcpQueries,
|
||
pStatistics->TcpResponses,
|
||
pStatistics->TcpQueriesSent,
|
||
pStatistics->TcpResponsesReceived
|
||
);
|
||
|
||
PrintRoutine(
|
||
"\n"
|
||
"Recursion:\n"
|
||
"----------\n"
|
||
"\tPackets = %d\n"
|
||
"\tLookups = %d\n"
|
||
"\tQuestions = %d\n"
|
||
"\tPasses = %d\n"
|
||
"\tForwards = %d\n"
|
||
"\tSends = %d\n"
|
||
"\tResponses = %d\n"
|
||
"\tTimeouts = %d\n"
|
||
"\tFailures = %d\n"
|
||
"\tIncomplete = %d\n",
|
||
pStatistics->RecursePacketUsed,
|
||
pStatistics->RecurseLookups,
|
||
pStatistics->RecurseQuestions,
|
||
pStatistics->RecursePasses,
|
||
pStatistics->RecurseForwards,
|
||
pStatistics->RecurseLookups,
|
||
pStatistics->RecurseResponses,
|
||
pStatistics->RecurseTimeouts,
|
||
pStatistics->RecurseFailures,
|
||
pStatistics->RecursePartialFailures
|
||
);
|
||
|
||
PrintRoutine(
|
||
"TCP Recursion:\n"
|
||
"\tTry = %d\n"
|
||
"\tQuery = %d\n"
|
||
"\tResponse = %d\n"
|
||
"Root Query:\n"
|
||
"\tQuery = %d\n"
|
||
"\tResponse = %d\n",
|
||
pStatistics->RecurseTcpTry,
|
||
pStatistics->RecurseTcpQuery,
|
||
pStatistics->RecurseTcpResponse,
|
||
pStatistics->RecurseRootQuery,
|
||
pStatistics->RecurseRootResponse
|
||
);
|
||
|
||
PrintRoutine(
|
||
"\n"
|
||
"WINS Referrals:\n"
|
||
"---------------\n"
|
||
"Forward:\n"
|
||
"\tLookups = %d\n"
|
||
"\tResponses = %d\n"
|
||
"Reverse:\n"
|
||
"\tLookups = %d\n"
|
||
"\tResponses = %d\n",
|
||
pStatistics->WinsLookups,
|
||
pStatistics->WinsResponses,
|
||
pStatistics->WinsReverseLookups,
|
||
pStatistics->WinsReverseResponses
|
||
);
|
||
|
||
PrintRoutine(
|
||
"\n"
|
||
"Secondary Zone Transfer:\n"
|
||
"------------------------\n"
|
||
"SOA Queries = %d\n"
|
||
"SOA Responses = %d\n"
|
||
"Notifies Recvd = %d\n"
|
||
"AXFR Requests = %d\n"
|
||
"AXFR Rejected = %d\n"
|
||
"AXFR Failed = %d\n"
|
||
"AXFR Successful = %d\n",
|
||
pStatistics->SecSoaQueries,
|
||
pStatistics->SecSoaResponses,
|
||
pStatistics->SecNotifyReceived,
|
||
pStatistics->SecAxfrRequested,
|
||
pStatistics->SecAxfrRejected,
|
||
pStatistics->SecAxfrFailed,
|
||
pStatistics->SecAxfrSuccessful
|
||
);
|
||
|
||
PrintRoutine(
|
||
"\n"
|
||
"Master Zone Transfer:\n"
|
||
"---------------------\n"
|
||
"Notifies Sent = %d\n"
|
||
"AXFR Requests Recvd = %d\n"
|
||
"AXFR Invalid Requests = %d\n"
|
||
"AXFR Denied (Security) = %d\n"
|
||
"AXFR Refused = %d\n"
|
||
"AXFR Failed = %d\n"
|
||
"AXFR Successful = %d\n",
|
||
pStatistics->MasterNotifySent,
|
||
pStatistics->MasterAxfrReceived,
|
||
pStatistics->MasterAxfrInvalid,
|
||
pStatistics->MasterAxfrDenied,
|
||
pStatistics->MasterAxfrRefused,
|
||
pStatistics->MasterAxfrFailed,
|
||
pStatistics->MasterAxfrSuccessful
|
||
);
|
||
|
||
//
|
||
// Database stats
|
||
//
|
||
|
||
PrintRoutine(
|
||
"\n"
|
||
"Database:\n"
|
||
"---------\n"
|
||
"Nodes\n"
|
||
" InUse = %d\n"
|
||
" Memory = %d\n"
|
||
"Records\n"
|
||
" InUse = %d\n"
|
||
" Memory = %d\n"
|
||
"Database Total\n"
|
||
" Memory = %d\n",
|
||
pStatistics->NodeInUse,
|
||
pStatistics->NodeMemory,
|
||
pStatistics->RecordInUse,
|
||
pStatistics->RecordMemory,
|
||
pStatistics->DatabaseMemory
|
||
);
|
||
|
||
PrintRoutine(
|
||
"\n"
|
||
"RR Caching:\n"
|
||
"\tTotal = %d\n"
|
||
"\tCurrent = %d\n"
|
||
"\tTimeouts = %d\n",
|
||
pStatistics->CacheRRTotal,
|
||
pStatistics->CacheRRCurrent,
|
||
pStatistics->CacheRRTimeouts
|
||
);
|
||
|
||
PrintRoutine(
|
||
"\n"
|
||
"Domain Nodes:\n"
|
||
"\tAlloc = %d\n"
|
||
"\tFree = %d\n"
|
||
"\tNetAllocs = %d\n"
|
||
"\tMemory = %d\n"
|
||
"\n"
|
||
"\tUsed = %d\n"
|
||
"\tReturned = %d\n"
|
||
"\tInUse = %d\n"
|
||
"\n"
|
||
"\tStd Alloc = %d\n"
|
||
"\tStd Used = %d\n"
|
||
"\tStd Return = %d\n"
|
||
"\tInFreeList = %d\n",
|
||
pStatistics->NodeAlloc,
|
||
pStatistics->NodeFree,
|
||
pStatistics->NodeNetAllocs,
|
||
pStatistics->NodeMemory,
|
||
pStatistics->NodeUsed,
|
||
pStatistics->NodeReturn,
|
||
pStatistics->NodeInUse,
|
||
pStatistics->NodeStdAlloc,
|
||
pStatistics->NodeStdUsed,
|
||
pStatistics->NodeStdReturn,
|
||
pStatistics->NodeInFreeList
|
||
);
|
||
|
||
PrintRoutine(
|
||
"\n"
|
||
"Records:\n"
|
||
"\tAlloc = %d\n"
|
||
"\tFree = %d\n"
|
||
"\tNetAllocs = %d\n"
|
||
"\tMemory = %d\n"
|
||
"\n"
|
||
"\tUsed = %d\n"
|
||
"\tReturned = %d\n"
|
||
"\tInUse = %d\n"
|
||
"\n"
|
||
"\tStd Alloc = %d\n"
|
||
"\tStd Used = %d\n"
|
||
"\tStd Return = %d\n"
|
||
"\tInFreeList = %d\n",
|
||
pStatistics->RecordAlloc,
|
||
pStatistics->RecordFree,
|
||
pStatistics->RecordNetAllocs,
|
||
pStatistics->RecordMemory,
|
||
pStatistics->RecordUsed,
|
||
pStatistics->RecordReturn,
|
||
pStatistics->RecordInUse,
|
||
pStatistics->RecordStdAlloc,
|
||
pStatistics->RecordStdUsed,
|
||
pStatistics->RecordStdReturn,
|
||
pStatistics->RecordInFreeList
|
||
);
|
||
|
||
PrintRoutine(
|
||
"\n"
|
||
"Packet Memory Usage:\n"
|
||
"--------------------\n"
|
||
"UDP Messages:\n"
|
||
"\tAlloc = %d\n"
|
||
"\tFree = %d\n"
|
||
"\tNetAllocs = %d\n"
|
||
"\tMemory = %d\n"
|
||
"\tUsed = %d\n"
|
||
"\tReturned = %d\n"
|
||
"\tInUse = %d\n"
|
||
"\tInFreeList = %d\n"
|
||
"\n",
|
||
pStatistics->UdpAlloc,
|
||
pStatistics->UdpFree,
|
||
pStatistics->UdpNetAllocs,
|
||
pStatistics->UdpMemory,
|
||
pStatistics->UdpUsed,
|
||
pStatistics->UdpReturn,
|
||
pStatistics->UdpInUse,
|
||
pStatistics->UdpInFreeList
|
||
);
|
||
|
||
PrintRoutine(
|
||
"TCP Messages:\n"
|
||
"\tAlloc = %d\n"
|
||
"\tRealloc = %d\n"
|
||
"\tFree = %d\n"
|
||
"\tNetAllocs = %d\n"
|
||
"\tMemory = %d\n"
|
||
"\n",
|
||
pStatistics->TcpAlloc,
|
||
pStatistics->TcpRealloc,
|
||
pStatistics->TcpFree,
|
||
pStatistics->TcpNetAllocs,
|
||
pStatistics->TcpMemory
|
||
);
|
||
|
||
PrintRoutine(
|
||
"Recursion Messages:\n"
|
||
"\tUsed = %d\n"
|
||
"\tReturned = %d\n"
|
||
"\n",
|
||
pStatistics->RecursePacketUsed,
|
||
pStatistics->RecursePacketReturn
|
||
);
|
||
|
||
PrintRoutine(
|
||
"\n"
|
||
"Nbstat Memory Usage:\n"
|
||
"--------------------\n"
|
||
"Nbstat Buffers:\n"
|
||
"\tAlloc = %d\n"
|
||
"\tFree = %d\n"
|
||
"\tNetAllocs = %d\n"
|
||
"\tMemory = %d\n"
|
||
"\tUsed = %d\n"
|
||
"\tReturned = %d\n"
|
||
"\tInUse = %d\n"
|
||
"\tInFreeList = %d\n"
|
||
"\n",
|
||
pStatistics->NbstatAlloc,
|
||
pStatistics->NbstatFree,
|
||
pStatistics->NbstatNetAllocs,
|
||
pStatistics->NbstatMemory,
|
||
pStatistics->NbstatUsed,
|
||
pStatistics->NbstatReturn,
|
||
pStatistics->NbstatInUse,
|
||
pStatistics->NbstatInFreeList
|
||
);
|
||
DnsPrint_Unlock();
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
Dns4_Print_RpcZoneHandleList(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN LPSTR pszHeader,
|
||
IN DWORD dwZoneCount,
|
||
IN DNS_HANDLE ahZones[]
|
||
)
|
||
{
|
||
DWORD i;
|
||
|
||
DnsPrint_Lock();
|
||
if ( pszHeader )
|
||
{
|
||
PrintRoutine( pszHeader );
|
||
}
|
||
PrintRoutine( "Zone Count = %d\n", dwZoneCount );
|
||
|
||
if ( dwZoneCount != 0 && ahZones != NULL )
|
||
{
|
||
for( i=0; i<dwZoneCount; i++ )
|
||
{
|
||
PrintRoutine( "\thZones[%d] => %p\n", i, ahZones[i] );
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
Dns4_Print_RpcZoneInfo(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN LPSTR pszHeader,
|
||
IN PDNS4_ZONE_INFO pZoneInfo
|
||
)
|
||
{
|
||
DnsPrint_Lock();
|
||
PrintRoutine( (pszHeader ? pszHeader : "") );
|
||
|
||
if ( ! pZoneInfo )
|
||
{
|
||
PrintRoutine( "NULL zone info ptr.\n" );
|
||
}
|
||
else
|
||
{
|
||
PrintRoutine(
|
||
"Zone info:\n"
|
||
"\tptr = %p\n"
|
||
"\thZone = %p\n"
|
||
"\tzone name = %s\n"
|
||
"\tzone type = %d\n"
|
||
"\tusing dbase = %d\n"
|
||
"\tdata file = %s\n"
|
||
"\tusing WINS = %d\n"
|
||
"\tusing Nbstat = %d\n",
|
||
pZoneInfo,
|
||
pZoneInfo->hZone,
|
||
pZoneInfo->pszZoneName,
|
||
pZoneInfo->dwZoneType,
|
||
pZoneInfo->fUseDatabase,
|
||
pZoneInfo->pszDataFile,
|
||
pZoneInfo->fUseWins,
|
||
pZoneInfo->fUseNbstat
|
||
);
|
||
|
||
DnsPrint_IpArray(
|
||
PrintRoutine,
|
||
NULL,
|
||
"\tZones Masters\n",
|
||
"\tMaster",
|
||
pZoneInfo->aipMasters );
|
||
|
||
DnsPrint_IpArray(
|
||
PrintRoutine,
|
||
NULL,
|
||
"\tZone Secondaries\n",
|
||
"\tSecondary",
|
||
pZoneInfo->aipSecondaries );
|
||
|
||
PrintRoutine(
|
||
"\tsecure secs = %d\n",
|
||
pZoneInfo->fSecureSecondaries
|
||
);
|
||
}
|
||
DnsPrint_Unlock();
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
Dns4_Print_RpcZoneInfoList(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN LPSTR pszHeader,
|
||
IN DWORD dwZoneCount,
|
||
IN PDNS4_ZONE_INFO apZoneInfo[]
|
||
)
|
||
{
|
||
DWORD i;
|
||
|
||
DnsPrint_Lock();
|
||
PrintRoutine( (pszHeader ? pszHeader : "") );
|
||
PrintRoutine( "Zone Count = %d\n", dwZoneCount );
|
||
|
||
if ( dwZoneCount != 0 && apZoneInfo != NULL )
|
||
{
|
||
for (i=0; i<dwZoneCount; i++)
|
||
{
|
||
PrintRoutine( "\n[%d]", i );
|
||
Dns4_Print_RpcZoneInfo(
|
||
PrintRoutine,
|
||
NULL,
|
||
apZoneInfo[i] );
|
||
}
|
||
}
|
||
DnsPrint_Unlock();
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
Dns4_Print_RpcRecord(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN LPSTR pszHeader,
|
||
IN PDNS4_RPC_RECORD pRecord
|
||
)
|
||
{
|
||
PCHAR pRecordString;
|
||
PDNS4_RPC_RECORD pnt4Record;
|
||
WORD type;
|
||
|
||
DnsPrint_Lock();
|
||
PrintRoutine( (pszHeader ? pszHeader : "" ) );
|
||
|
||
if ( ! pRecord )
|
||
{
|
||
PrintRoutine( "NULL record ptr.\n" );
|
||
goto Done;
|
||
}
|
||
|
||
//
|
||
// record fixed fields
|
||
//
|
||
|
||
type = pRecord->wType;
|
||
pRecordString = Dns_RecordStringForType( type );
|
||
if ( !pRecordString )
|
||
{
|
||
pRecordString = "UNKNOWN";
|
||
}
|
||
PrintRoutine(
|
||
" %s Record (NT4):\n"
|
||
"\tptr = %p\n"
|
||
"\thRecord = %p\n"
|
||
"\twLength = %u\n"
|
||
"\twDataLength = %u\n"
|
||
"\twType = %s (%u)\n"
|
||
"\twClass = %u\n"
|
||
"\tdwFlags = %lx\n"
|
||
"\tdwTtlSeconds = %u\n",
|
||
pRecordString,
|
||
pRecord,
|
||
pRecord->hRecord,
|
||
pRecord->wRecordLength,
|
||
pRecord->wDataLength,
|
||
pRecordString,
|
||
type,
|
||
pRecord->wClass,
|
||
pRecord->dwFlags,
|
||
pRecord->dwTtlSeconds
|
||
);
|
||
|
||
//
|
||
// print record type and data
|
||
// - as single line data where possible
|
||
|
||
PrintRoutine(
|
||
" %s ",
|
||
pRecordString );
|
||
|
||
switch ( type )
|
||
{
|
||
case DNS_TYPE_A:
|
||
|
||
PrintRoutine(
|
||
"%d.%d.%d.%d\n",
|
||
* ( (PUCHAR) &(pRecord->Data.A) + 0 ),
|
||
* ( (PUCHAR) &(pRecord->Data.A) + 1 ),
|
||
* ( (PUCHAR) &(pRecord->Data.A) + 2 ),
|
||
* ( (PUCHAR) &(pRecord->Data.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,
|
||
NULL,
|
||
& pRecord->Data.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(
|
||
"%d ",
|
||
pRecord->Data.MX.wPreference
|
||
);
|
||
DnsPrint_RpcName(
|
||
PrintRoutine,
|
||
NULL,
|
||
& pRecord->Data.MX.nameExchange,
|
||
"\n" );
|
||
break;
|
||
|
||
case DNS_TYPE_SOA:
|
||
|
||
DnsPrint_RpcName(
|
||
PrintRoutine,
|
||
"\n\tPrimaryNameServer: ",
|
||
& pRecord->Data.SOA.namePrimaryServer,
|
||
"\n" );
|
||
|
||
// responsible party name, immediately follows primary server name
|
||
|
||
DnsPrint_RpcName(
|
||
PrintRoutine,
|
||
"\tResponsibleParty: ",
|
||
(PDNS_RPC_NAME)
|
||
(pRecord->Data.SOA.namePrimaryServer.achName
|
||
+ pRecord->Data.SOA.namePrimaryServer.cchNameLength),
|
||
"\n" );
|
||
|
||
PrintRoutine(
|
||
"\tSerialNo = %lu\n"
|
||
"\tRefresh = %lu\n"
|
||
"\tRetry = %lu\n"
|
||
"\tExpire = %lu\n"
|
||
"\tMinimumTTL = %lu\n",
|
||
pRecord->Data.SOA.dwSerialNo,
|
||
pRecord->Data.SOA.dwRefresh,
|
||
pRecord->Data.SOA.dwRetry,
|
||
pRecord->Data.SOA.dwExpire,
|
||
pRecord->Data.SOA.dwMinimumTtl );
|
||
break;
|
||
|
||
case DNS_TYPE_MINFO:
|
||
case DNS_TYPE_RP:
|
||
|
||
//
|
||
// these RRs contain two domain names
|
||
//
|
||
|
||
DnsPrint_RpcName(
|
||
PrintRoutine,
|
||
"\n\tMailBox: ",
|
||
& pRecord->Data.MINFO.nameMailBox,
|
||
NULL );
|
||
|
||
// errors to mailbox name, immediately follows mail box
|
||
|
||
DnsPrint_RpcName(
|
||
PrintRoutine,
|
||
"\tErrorsToMailbox: ",
|
||
(PDNS_RPC_NAME)
|
||
( pRecord->Data.MINFO.nameMailBox.achName
|
||
+ pRecord->Data.MINFO.nameMailBox.cchNameLength ),
|
||
"\n" );
|
||
break;
|
||
|
||
case DNS_TYPE_AAAA:
|
||
case DNS_TYPE_HINFO:
|
||
case DNS_TYPE_ISDN:
|
||
case DNS_TYPE_X25:
|
||
case DNS_TYPE_TEXT:
|
||
{
|
||
//
|
||
// all these are simply text string(s)
|
||
//
|
||
|
||
PCHAR pch = (PCHAR) &pRecord->Data.TXT.stringData;
|
||
PCHAR pchStop = pch + pRecord->wDataLength;
|
||
UCHAR cch;
|
||
|
||
while ( pch < pchStop )
|
||
{
|
||
cch = (UCHAR) *pch++;
|
||
|
||
PrintRoutine(
|
||
"\t%.*s\n",
|
||
cch,
|
||
pch );
|
||
|
||
pch += cch;
|
||
}
|
||
ASSERT( pch == pchStop );
|
||
break;
|
||
}
|
||
|
||
case DNS_TYPE_WKS:
|
||
{
|
||
INT i;
|
||
|
||
PrintRoutine(
|
||
"WKS: Address %d.%d.%d.%d\n"
|
||
"\tProtocol %d\n"
|
||
"\tBitmask\n",
|
||
* ( (PUCHAR) &(pRecord->Data.WKS.ipAddress) + 0 ),
|
||
* ( (PUCHAR) &(pRecord->Data.WKS.ipAddress) + 1 ),
|
||
* ( (PUCHAR) &(pRecord->Data.WKS.ipAddress) + 2 ),
|
||
* ( (PUCHAR) &(pRecord->Data.WKS.ipAddress) + 3 ),
|
||
pRecord->Data.WKS.chProtocol
|
||
);
|
||
|
||
for ( i = 0;
|
||
i < (INT)( pRecord->wDataLength
|
||
- sizeof( pRecord->Data.WKS.ipAddress )
|
||
- sizeof( pRecord->Data.WKS.chProtocol ) );
|
||
i++ )
|
||
{
|
||
PrintRoutine(
|
||
"\t\tbyte[%d] = %x\n",
|
||
i,
|
||
(UCHAR) pRecord->Data.WKS.bBitMask[i] );
|
||
}
|
||
break;
|
||
}
|
||
|
||
case DNS_TYPE_NULL:
|
||
{
|
||
INT i;
|
||
|
||
for ( i = 0; i < pRecord->wDataLength; i++ )
|
||
{
|
||
// print one DWORD per line
|
||
|
||
if ( !(i%16) )
|
||
{
|
||
PrintRoutine( "\n\t" );
|
||
}
|
||
PrintRoutine(
|
||
"%02x ",
|
||
(UCHAR) pRecord->Data.Null.bData[i] );
|
||
}
|
||
PrintRoutine( "\n" );
|
||
break;
|
||
}
|
||
|
||
case DNS_TYPE_SRV:
|
||
|
||
//
|
||
// SRV <priority> <weight> <port> <target host>
|
||
//
|
||
|
||
PrintRoutine(
|
||
"%d %d %d ",
|
||
pRecord->Data.SRV.wPriority,
|
||
pRecord->Data.SRV.wWeight,
|
||
pRecord->Data.SRV.wPort
|
||
);
|
||
DnsPrint_RpcName(
|
||
PrintRoutine,
|
||
NULL,
|
||
& pRecord->Data.SRV.nameTarget,
|
||
"\n" );
|
||
break;
|
||
|
||
case DNS_TYPE_WINS:
|
||
{
|
||
DWORD i;
|
||
|
||
//
|
||
// WINS
|
||
// - scope/domain mapping flag
|
||
// - WINS server list
|
||
//
|
||
|
||
PrintRoutine( "%08lx\n", pRecord->Data.WINS.dwMappingFlag );
|
||
#if 0
|
||
//
|
||
// DEVNOTE: WINS mapping strings
|
||
// JJW: this is probably an obsolete B*GB*G
|
||
//
|
||
|
||
"%s\t",
|
||
Dns_WinsMappingFlagString( pRecord->Data.WINS.dwMappingFlag )
|
||
#endif
|
||
|
||
for( i=0; i<pRecord->Data.WINS.cWinsServerCount; i++ )
|
||
{
|
||
PrintRoutine(
|
||
"%d.%d.%d.%d\n",
|
||
* ( (PUCHAR) &(pRecord->Data.WINS.aipWinsServers[i]) + 0 ),
|
||
* ( (PUCHAR) &(pRecord->Data.WINS.aipWinsServers[i]) + 1 ),
|
||
* ( (PUCHAR) &(pRecord->Data.WINS.aipWinsServers[i]) + 2 ),
|
||
* ( (PUCHAR) &(pRecord->Data.WINS.aipWinsServers[i]) + 3 )
|
||
);
|
||
}
|
||
break;
|
||
}
|
||
|
||
case DNS_TYPE_NBSTAT:
|
||
|
||
//
|
||
// NBSTAT
|
||
// - scope/domain mapping flag
|
||
// - optionally a result domain
|
||
//
|
||
|
||
PrintRoutine( "%08lx\n", pRecord->Data.NBSTAT.dwMappingFlag );
|
||
|
||
if ( pRecord->wDataLength > sizeof(pRecord->Data.NBSTAT.dwMappingFlag) )
|
||
{
|
||
DnsPrint_RpcName(
|
||
PrintRoutine,
|
||
NULL,
|
||
& pRecord->Data.NBSTAT.nameResultDomain,
|
||
"\n" );
|
||
}
|
||
break;
|
||
|
||
default:
|
||
PrintRoutine(
|
||
"Unknown resource record type (%d) at %p.\n",
|
||
pRecord->wType,
|
||
pRecord );
|
||
break;
|
||
}
|
||
|
||
Done:
|
||
DnsPrint_Unlock();
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
DNS_API_FUNCTION
|
||
Dns4_Print_RpcRecordsInBuffer(
|
||
IN PRINT_ROUTINE PrintRoutine,
|
||
IN LPSTR pszHeader,
|
||
IN DWORD dwBufferLength,
|
||
IN BYTE abBuffer[]
|
||
)
|
||
{
|
||
PBYTE pbCurrent;
|
||
PBYTE pbStop;
|
||
INT cRecordCount;
|
||
|
||
DnsPrint_Lock();
|
||
PrintRoutine( (pszHeader ? pszHeader : "") );
|
||
|
||
if ( !abBuffer )
|
||
{
|
||
PrintRoutine( "NULL record buffer ptr.\n" );
|
||
goto Done;
|
||
}
|
||
else
|
||
{
|
||
PrintRoutine(
|
||
"Record buffer of length %d at %p:\n",
|
||
dwBufferLength,
|
||
abBuffer );
|
||
}
|
||
|
||
//
|
||
// find stop byte
|
||
//
|
||
|
||
ASSERT( DNS_IS_DWORD_ALIGNED(abBuffer) );
|
||
|
||
pbStop = abBuffer + dwBufferLength;
|
||
pbCurrent = abBuffer;
|
||
|
||
//
|
||
// loop until out of nodes
|
||
//
|
||
|
||
while( pbCurrent < pbStop )
|
||
{
|
||
//
|
||
// print owner node
|
||
// determine record count
|
||
// find first record
|
||
//
|
||
|
||
DnsPrint_RpcNode(
|
||
PrintRoutine,
|
||
NULL,
|
||
(PDNS_RPC_NODE)pbCurrent );
|
||
|
||
cRecordCount = ((PDNS_RPC_NODE)pbCurrent)->wRecordCount;
|
||
pbCurrent += ((PDNS_RPC_NODE)pbCurrent)->wLength;
|
||
pbCurrent = DNS_NEXT_DWORD_PTR(pbCurrent);
|
||
|
||
//
|
||
// for each node, print all records in list
|
||
//
|
||
|
||
while( cRecordCount-- )
|
||
{
|
||
if ( pbCurrent >= pbStop )
|
||
{
|
||
PrintRoutine(
|
||
"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) pbCurrent,
|
||
pbStop,
|
||
cRecordCount+1 );
|
||
|
||
ASSERT( FALSE );
|
||
break;
|
||
}
|
||
|
||
Dns4_Print_RpcRecord(
|
||
PrintRoutine,
|
||
"",
|
||
(PDNS4_RPC_RECORD) pbCurrent );
|
||
|
||
pbCurrent += ((PDNS4_RPC_RECORD)pbCurrent)->wDataLength
|
||
+ SIZEOF_DNS4_RPC_RECORD_HEADER;
|
||
pbCurrent = DNS_NEXT_DWORD_PTR(pbCurrent);
|
||
}
|
||
}
|
||
|
||
Done:
|
||
DnsPrint_Unlock();
|
||
}
|
||
|
||
|
||
//
|
||
// End of nt4api.c
|
||
//
|