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

  1. /*++
  2. Copyright (c) 1995-2000 Microsoft Corporation
  3. Module Name:
  4. print.c
  5. Abstract:
  6. Domain Name System (DNS) Server RPC Library
  7. Print routines for RPC types
  8. Author:
  9. Jim Gilroy (jamesg) September 1995
  10. Revision History:
  11. --*/
  12. #include "dnsclip.h"
  13. #include <time.h>
  14. #define DNS_NOT_APPLICABLE "N/A"
  15. #define DNS_NOT_APPLICABLE_W L"N/A"
  16. #define DNS_NOT_PERFORMED "not since restart"
  17. //
  18. // Winsock version: copied from socket.c
  19. //
  20. #ifndef DNS_WINSOCK2
  21. #define DNS_WINSOCK_VERSION (0x0101) // Winsock 1.1
  22. #else // Winsock2
  23. #define DNS_WINSOCK_VERSION (0x0002) // Winsock 2.0
  24. #endif
  25. //
  26. // Tagged memory stat strings
  27. //
  28. // NT5 shipped version
  29. //
  30. LPSTR MemTagStringsNT5[] =
  31. {
  32. MEMTAG_NAME_NONE ,
  33. MEMTAG_NAME_RECORD ,
  34. MEMTAG_NAME_NODE ,
  35. MEMTAG_NAME_NAME ,
  36. MEMTAG_NAME_ZONE ,
  37. MEMTAG_NAME_UPDATE ,
  38. MEMTAG_NAME_TIMEOUT ,
  39. MEMTAG_NAME_STUFF ,
  40. MEMTAG_NAME_NODEHASH ,
  41. MEMTAG_NAME_DS_DN ,
  42. MEMTAG_NAME_DS_MOD ,
  43. MEMTAG_NAME_DS_RECORD ,
  44. MEMTAG_NAME_NODE_COPY ,
  45. MEMTAG_NAME_PACKET_UDP ,
  46. MEMTAG_NAME_PACKET_TCP ,
  47. MEMTAG_NAME_DNSLIB ,
  48. MEMTAG_NAME_TABLE ,
  49. MEMTAG_NAME_SOCKET ,
  50. MEMTAG_NAME_CONNECTION ,
  51. MEMTAG_NAME_REGISTRY ,
  52. MEMTAG_NAME_RPC ,
  53. MEMTAG_NAME_NBSTAT ,
  54. MEMTAG_NAME_FILEBUF ,
  55. MEMTAG_NAME_DS_OTHER ,
  56. MEMTAG_NAME_THREAD ,
  57. MEMTAG_NAME_UPDATE_LIST ,
  58. MEMTAG_NAME_SAFE ,
  59. NULL, // safety
  60. NULL,
  61. NULL,
  62. NULL
  63. };
  64. // NT5 SP1 version
  65. LPSTR MemTagStrings[] =
  66. {
  67. MEMTAG_NAME_NONE ,
  68. MEMTAG_NAME_PACKET_UDP ,
  69. MEMTAG_NAME_PACKET_TCP ,
  70. MEMTAG_NAME_NAME ,
  71. MEMTAG_NAME_ZONE ,
  72. MEMTAG_NAME_UPDATE ,
  73. MEMTAG_NAME_UPDATE_LIST ,
  74. MEMTAG_NAME_TIMEOUT ,
  75. MEMTAG_NAME_NODEHASH ,
  76. MEMTAG_NAME_DS_DN ,
  77. MEMTAG_NAME_DS_MOD , // 10
  78. MEMTAG_NAME_DS_RECORD ,
  79. MEMTAG_NAME_DS_OTHER ,
  80. MEMTAG_NAME_THREAD ,
  81. MEMTAG_NAME_NBSTAT ,
  82. MEMTAG_NAME_DNSLIB ,
  83. MEMTAG_NAME_TABLE ,
  84. MEMTAG_NAME_SOCKET ,
  85. MEMTAG_NAME_CONNECTION ,
  86. MEMTAG_NAME_REGISTRY ,
  87. MEMTAG_NAME_RPC , // 20
  88. MEMTAG_NAME_STUFF ,
  89. MEMTAG_NAME_FILEBUF ,
  90. MEMTAG_NAME_REMOTE ,
  91. MEMTAG_NAME_SAFE ,
  92. MEMTAG_NAME_RECORD ,
  93. MEMTAG_NAME_RECORD_FILE ,
  94. MEMTAG_NAME_RECORD_DS ,
  95. MEMTAG_NAME_RECORD_AXFR ,
  96. MEMTAG_NAME_RECORD_IXFR ,
  97. MEMTAG_NAME_RECORD_DYNUP , // 30
  98. MEMTAG_NAME_RECORD_ADMIN ,
  99. MEMTAG_NAME_RECORD_AUTO ,
  100. MEMTAG_NAME_RECORD_CACHE ,
  101. MEMTAG_NAME_RECORD_NOEXIST ,
  102. MEMTAG_NAME_RECORD_WINS ,
  103. MEMTAG_NAME_RECORD_WINSPTR ,
  104. MEMTAG_NAME_RECORD_COPY ,
  105. MEMTAG_NAME_NODE ,
  106. MEMTAG_NAME_NODE_FILE ,
  107. MEMTAG_NAME_NODE_DS , // 40
  108. MEMTAG_NAME_NODE_AXFR ,
  109. MEMTAG_NAME_NODE_IXFR ,
  110. MEMTAG_NAME_NODE_DYNUP ,
  111. MEMTAG_NAME_NODE_ADMIN ,
  112. MEMTAG_NAME_NODE_AUTO ,
  113. MEMTAG_NAME_NODE_CACHE ,
  114. MEMTAG_NAME_NODE_NOEXIST ,
  115. MEMTAG_NAME_NODE_WINS ,
  116. MEMTAG_NAME_NODE_WINSPTR ,
  117. MEMTAG_NAME_NODE_COPY ,
  118. NULL, // safety
  119. NULL,
  120. NULL,
  121. NULL
  122. };
  123. VOID
  124. Dns_SystemHourToSystemTime(
  125. IN DWORD dwHourTime,
  126. IN OUT PSYSTEMTIME pSystemTime
  127. )
  128. /*++
  129. Routine Description:
  130. Converts system time in hours to SYSTEMTIME format.
  131. Arguments:
  132. dwHourTime -- system time in hours (hours since 1601)
  133. pSystemTime -- ptr to SYSTEMTIME to set
  134. Return Value:
  135. None
  136. --*/
  137. {
  138. #define FILE_TIME_INTERVALS_IN_HOUR (36000000000)
  139. LONGLONG fileTime;
  140. fileTime = (LONGLONG)dwHourTime * FILE_TIME_INTERVALS_IN_HOUR;
  141. FileTimeToSystemTime( (PFILETIME)&fileTime, pSystemTime );
  142. }
  143. PWSTR
  144. utf8ToUnicode(
  145. IN PSTR pszInputStr,
  146. IN DWORD dwInputLength
  147. )
  148. /*++
  149. Routine Description:
  150. Takes a UTF-8 string and allocates a Unicode copy of the string.
  151. The caller must call use FREE_HEAP to deallocate the Unicode string.
  152. Arguments:
  153. pszInputStr -- input string, optionally NULL terminated
  154. dwInputLength -- pass zero if pszInputStr is NULL terminated
  155. Return Value:
  156. NULL-terminated Unicode output string
  157. --*/
  158. {
  159. PWSTR pwszoutput;
  160. if ( pszInputStr == NULL )
  161. {
  162. pszInputStr = "";
  163. dwInputLength = 0;
  164. }
  165. pwszoutput = Dns_StringCopyAllocate(
  166. pszInputStr,
  167. dwInputLength,
  168. DnsCharSetUtf8, // UTF8 in
  169. DnsCharSetUnicode // unicode out
  170. );
  171. return pwszoutput;
  172. } // utf8ToUnicode
  173. PWSTR
  174. getUnicodeForUtf8(
  175. IN PSTR pUtf8
  176. )
  177. /*++
  178. Routine Description:
  179. Takes a UTF-8 string and allocates a Unicode copy of the string.
  180. Caller must free resulting unicode string.
  181. Arguments:
  182. pUtf8 -- UTF8 string
  183. Return Value:
  184. Ptr to unicode string.
  185. NULL on alloc failure or invalid UTF8 string.
  186. --*/
  187. {
  188. return Dns_StringCopyAllocate(
  189. pUtf8,
  190. 0, // NULL terminated
  191. DnsCharSetUtf8, // UTF8 in
  192. DnsCharSetUnicode // unicode out
  193. );
  194. }
  195. //
  196. // Print server info
  197. //
  198. VOID
  199. DnsPrint_RpcServerInfo(
  200. IN PRINT_ROUTINE PrintRoutine,
  201. IN OUT PPRINT_CONTEXT pPrintContext,
  202. IN LPSTR pszHeader,
  203. IN PDNS_RPC_SERVER_INFO pServerInfo
  204. )
  205. {
  206. char szTime[ 80 ] = DNS_NOT_PERFORMED;
  207. PWSTR pnameServer = NULL;
  208. PWSTR pnameForest = NULL;
  209. PWSTR pnameDomain = NULL;
  210. PWSTR pnameForestDp = NULL;
  211. PWSTR pnameDomainDp = NULL;
  212. DnsPrint_Lock();
  213. if ( pszHeader )
  214. {
  215. PrintRoutine( pPrintContext, pszHeader );
  216. }
  217. if ( ! pServerInfo )
  218. {
  219. PrintRoutine( pPrintContext, "NULL server info ptr.\n" );
  220. }
  221. else
  222. {
  223. int majorVer = pServerInfo->dwVersion & 0x000000FF;
  224. int minorVer = ( pServerInfo->dwVersion & 0x0000FF00 ) >> 8;
  225. int buildNum = pServerInfo->dwVersion >> 16;
  226. pnameServer = getUnicodeForUtf8( pServerInfo->pszServerName );
  227. pnameForest = getUnicodeForUtf8( pServerInfo->pszForestName );
  228. pnameDomain = getUnicodeForUtf8( pServerInfo->pszDomainName );
  229. pnameForestDp = getUnicodeForUtf8( pServerInfo->pszForestDirectoryPartition );
  230. pnameDomainDp = getUnicodeForUtf8( pServerInfo->pszDomainDirectoryPartition );
  231. PrintRoutine( pPrintContext,
  232. "Server info\n"
  233. "\tserver name = %S\n",
  234. pnameServer );
  235. //
  236. // Sanitize build number for older versions where build number is wacked.
  237. //
  238. if ( buildNum < 1 || buildNum > 5000 )
  239. {
  240. PrintRoutine( pPrintContext,
  241. "\tversion = %08lX (%d.%d)\n",
  242. pServerInfo->dwVersion,
  243. majorVer,
  244. minorVer );
  245. }
  246. else
  247. {
  248. PrintRoutine( pPrintContext,
  249. "\tversion = %08lX (%d.%d build %d)\n",
  250. pServerInfo->dwVersion,
  251. majorVer,
  252. minorVer,
  253. buildNum );
  254. }
  255. PrintRoutine( pPrintContext,
  256. "\tDS container = %S\n"
  257. "\tforest name = %S\n"
  258. "\tdomain name = %S\n"
  259. "\tbuiltin domain partition = %S\n"
  260. "\tbuiltin forest partition = %S\n",
  261. pServerInfo->pszDsContainer ?
  262. pServerInfo->pszDsContainer : DNS_NOT_APPLICABLE_W,
  263. pnameForest ? pnameForest : DNS_NOT_APPLICABLE_W,
  264. pnameDomain ? pnameDomain : DNS_NOT_APPLICABLE_W,
  265. pnameForestDp ? pnameForestDp : DNS_NOT_APPLICABLE_W,
  266. pnameDomainDp ? pnameDomainDp : DNS_NOT_APPLICABLE_W
  267. );
  268. #if DBG
  269. PrintRoutine( pPrintContext,
  270. "\tAD forest behavior ver = %2d (DBG only)\n"
  271. "\tAD domain behavior ver = %2d (DBG only)\n"
  272. "\tAD DSA behavior ver = %2d (DBG only)\n",
  273. pServerInfo->dwDsForestVersion,
  274. pServerInfo->dwDsDomainVersion,
  275. pServerInfo->dwDsDsaVersion );
  276. #endif
  277. if ( pServerInfo->dwLastScavengeTime )
  278. {
  279. time_t t = pServerInfo->dwLastScavengeTime;
  280. strcpy( szTime, ctime( &t ) );
  281. szTime[ strlen( szTime ) - 1 ] = '\0';
  282. }
  283. PrintRoutine( pPrintContext,
  284. "\tlast scavenge cycle = %s (%d)\n",
  285. szTime,
  286. pServerInfo->dwLastScavengeTime );
  287. PrintRoutine( pPrintContext,
  288. " Configuration:\n"
  289. "\tdwLogLevel = %p\n"
  290. "\tdwDebugLevel = %p\n"
  291. "\tdwRpcProtocol = %p\n"
  292. "\tdwNameCheckFlag = %p\n"
  293. "\tcAddressAnswerLimit = %d\n"
  294. "\tdwRecursionRetry = %d\n"
  295. "\tdwRecursionTimeout = %d\n"
  296. "\tdwDsPollingInterval = %d\n",
  297. pServerInfo->dwLogLevel,
  298. pServerInfo->dwDebugLevel,
  299. pServerInfo->dwRpcProtocol,
  300. pServerInfo->dwNameCheckFlag,
  301. pServerInfo->cAddressAnswerLimit,
  302. pServerInfo->dwRecursionRetry,
  303. pServerInfo->dwRecursionTimeout,
  304. pServerInfo->dwDsPollingInterval );
  305. PrintRoutine( pPrintContext,
  306. " Configuration Flags:\n"
  307. "\tfBootMethod = %d\n"
  308. "\tfAdminConfigured = %d\n"
  309. "\tfAllowUpdate = %d\n"
  310. "\tfDsAvailable = %d\n"
  311. "\tfAutoReverseZones = %d\n"
  312. "\tfAutoCacheUpdate = %d\n"
  313. "\tfSlave = %d\n"
  314. "\tfNoRecursion = %d\n"
  315. "\tfRoundRobin = %d\n"
  316. "\tfStrictFileParsing = %d\n"
  317. "\tfLooseWildcarding = %d\n"
  318. "\tfBindSecondaries = %d\n"
  319. "\tfWriteAuthorityNs = %d\n"
  320. "\tfLocalNetPriority = %d\n",
  321. pServerInfo->fBootMethod,
  322. pServerInfo->fAdminConfigured,
  323. pServerInfo->fAllowUpdate,
  324. pServerInfo->fDsAvailable,
  325. pServerInfo->fAutoReverseZones,
  326. pServerInfo->fAutoCacheUpdate,
  327. pServerInfo->fSlave,
  328. pServerInfo->fNoRecursion,
  329. pServerInfo->fRoundRobin,
  330. pServerInfo->fStrictFileParsing,
  331. pServerInfo->fLooseWildcarding,
  332. pServerInfo->fBindSecondaries,
  333. pServerInfo->fWriteAuthorityNs,
  334. pServerInfo->fLocalNetPriority );
  335. PrintRoutine(
  336. pPrintContext,
  337. " Aging Configuration:\n"
  338. "\tScavengingInterval = %d\n"
  339. "\tDefaultAgingState = %d\n"
  340. "\tDefaultRefreshInterval = %d\n"
  341. "\tDefaultNoRefreshInterval = %d\n",
  342. pServerInfo->dwScavengingInterval,
  343. pServerInfo->fDefaultAgingState,
  344. pServerInfo->dwDefaultRefreshInterval,
  345. pServerInfo->dwDefaultNoRefreshInterval
  346. );
  347. DnsPrint_Ip4Array(
  348. PrintRoutine,
  349. pPrintContext,
  350. " ServerAddresses:\n",
  351. "\tAddr",
  352. pServerInfo->aipServerAddrs );
  353. DnsPrint_Ip4Array(
  354. PrintRoutine,
  355. pPrintContext,
  356. " ListenAddresses:\n",
  357. "\tAddr",
  358. pServerInfo->aipListenAddrs );
  359. DnsPrint_Ip4Array(
  360. PrintRoutine,
  361. pPrintContext,
  362. " Forwarders:\n",
  363. "\tAddr",
  364. pServerInfo->aipForwarders );
  365. PrintRoutine(
  366. pPrintContext,
  367. "\tforward timeout = %d\n"
  368. "\tslave = %d\n",
  369. pServerInfo->dwForwardTimeout,
  370. pServerInfo->fSlave );
  371. }
  372. DnsPrint_Unlock();
  373. FREE_HEAP( pnameServer );
  374. FREE_HEAP( pnameForest );
  375. FREE_HEAP( pnameDomain );
  376. FREE_HEAP( pnameForestDp );
  377. FREE_HEAP( pnameDomainDp );
  378. }
  379. //
  380. // Print zone Zone debug utilities
  381. //
  382. PSTR
  383. truncateStringA(
  384. PSTR pszSource,
  385. PSTR pszDest,
  386. int iDestLength )
  387. {
  388. if ( pszSource )
  389. {
  390. int len = strlen( pszSource );
  391. if ( len < iDestLength )
  392. {
  393. strcpy( pszDest, pszSource );
  394. }
  395. else
  396. {
  397. strncpy( pszDest, pszSource, iDestLength - 4 );
  398. strcpy( pszDest + iDestLength - 4, "..." );
  399. }
  400. }
  401. else
  402. {
  403. *pszDest = '\0';
  404. }
  405. return pszDest;
  406. }
  407. PWSTR
  408. truncateStringW(
  409. PWSTR pwszSource,
  410. PWSTR pwszDest,
  411. int iDestLength )
  412. {
  413. if ( pwszSource )
  414. {
  415. int len = wcslen( pwszSource );
  416. if ( len < iDestLength )
  417. {
  418. wcscpy( pwszDest, pwszSource );
  419. }
  420. else
  421. {
  422. wcsncpy( pwszDest, pwszSource, iDestLength - 4 );
  423. wcscpy( pwszDest + iDestLength - 4, L"..." );
  424. pwszDest[ iDestLength - 1 ] = '\0';
  425. }
  426. }
  427. else
  428. {
  429. *pwszDest = L'\0';
  430. }
  431. return pwszDest;
  432. }
  433. #define DNS_DPDISP_REAL_CUSTOM_NAME 0x0001
  434. #define DNS_DPDISP_BLANK_STRING_FOR_LEGACY 0x0002
  435. LPSTR
  436. partitionDisplayName(
  437. IN DWORD dwPartitionFlags,
  438. IN LPSTR pszPartitionFqdn,
  439. IN DWORD dwNameBuffLen,
  440. OUT LPSTR pszNameBuff,
  441. IN DWORD dwFlags
  442. )
  443. /*++
  444. Routine Description:
  445. Formats directory partition for display. If the flags indicate that
  446. the partition is a built-in partition, the name will be substituted
  447. for a descriptive string.
  448. Arguments:
  449. dwPartitionFlags -- DP flags from the DNS server
  450. pszPartitionFqdn -- FQDN of the partition
  451. dwNameBuffLen -- length of the output name buffer
  452. pszNameBuff -- pointer to the output name buffer
  453. dwFlags - use DNS_DPDISP_XXX constants
  454. Return Value:
  455. Pointer to pszNameBuff
  456. --*/
  457. {
  458. //
  459. // Substitute name if this is a built-in partition.
  460. //
  461. if ( dwPartitionFlags & DNS_DP_DOMAIN_DEFAULT )
  462. {
  463. pszPartitionFqdn = "AD-Domain";
  464. }
  465. else if ( dwPartitionFlags & DNS_DP_FOREST_DEFAULT )
  466. {
  467. pszPartitionFqdn = "AD-Forest";
  468. }
  469. else if ( dwPartitionFlags & DNS_DP_LEGACY || !pszPartitionFqdn )
  470. {
  471. pszPartitionFqdn =
  472. ( dwFlags & DNS_DPDISP_BLANK_STRING_FOR_LEGACY ) ? "" : "AD-Legacy";
  473. }
  474. else if ( !( dwFlags & DNS_DPDISP_REAL_CUSTOM_NAME ) )
  475. {
  476. pszPartitionFqdn = "AD-Custom";
  477. }
  478. truncateStringA( pszPartitionFqdn, pszNameBuff, dwNameBuffLen );
  479. return pszNameBuff;
  480. } // partitionDisplayName
  481. LPSTR
  482. zoneTypeString(
  483. IN DWORD dwZoneType,
  484. IN DWORD dwOutBuffLen,
  485. OUT LPSTR pszOutBuff
  486. )
  487. /*++
  488. Routine Description:
  489. Convert DWORD zone type into display string.
  490. Arguments:
  491. dwZoneType -- zone type
  492. dwOutBuffLen -- length of the output name buffer
  493. pszOutBuff -- pointer to the output name buffer
  494. Return Value:
  495. Pointer to pszOutBuff
  496. --*/
  497. {
  498. PSTR pszZoneType = NULL;
  499. CHAR szBuff[ 10 ];
  500. switch ( dwZoneType )
  501. {
  502. case DNS_ZONE_TYPE_CACHE:
  503. pszZoneType = "Cache";
  504. break;
  505. case DNS_ZONE_TYPE_PRIMARY:
  506. pszZoneType = "Primary";
  507. break;
  508. case DNS_ZONE_TYPE_SECONDARY:
  509. pszZoneType = "Secondary";
  510. break;
  511. case DNS_ZONE_TYPE_STUB:
  512. pszZoneType = "Stub";
  513. break;
  514. case DNS_ZONE_TYPE_FORWARDER:
  515. pszZoneType = "Forwarder";
  516. break;
  517. default:
  518. _itoa( dwZoneType, szBuff, 10 );
  519. pszZoneType = szBuff;
  520. break;
  521. }
  522. truncateStringA( pszZoneType, pszOutBuff, dwOutBuffLen );
  523. return pszOutBuff;
  524. } // zoneTypeString
  525. VOID
  526. DnsPrint_RpcZone(
  527. IN PRINT_ROUTINE PrintRoutine,
  528. IN OUT PPRINT_CONTEXT pPrintContext,
  529. IN LPSTR pszHeader,
  530. IN PDNS_RPC_ZONE pZone
  531. )
  532. {
  533. PWSTR pnamePartition = NULL;
  534. DnsPrint_Lock();
  535. if ( ! pZone )
  536. {
  537. PrintRoutine( pPrintContext,
  538. "%sNULL zone info ptr.\n",
  539. ( pszHeader ? pszHeader : "" ) );
  540. }
  541. else
  542. {
  543. CHAR szpartition[ 15 ];
  544. CHAR sztype[ 10 ];
  545. // print zone per line
  546. if ( pszHeader && *pszHeader )
  547. {
  548. PrintRoutine( pPrintContext,
  549. "%s\n",
  550. pszHeader ? pszHeader : "" );
  551. }
  552. PrintRoutine( pPrintContext, " %-30S", pZone->pszZoneName );
  553. if ( pZone->Flags.DsIntegrated )
  554. {
  555. partitionDisplayName(
  556. pZone->dwDpFlags,
  557. pZone->pszDpFqdn,
  558. sizeof( szpartition ),
  559. szpartition,
  560. 0 );
  561. }
  562. else
  563. {
  564. strcpy( szpartition, "File" );
  565. }
  566. pnamePartition = getUnicodeForUtf8( szpartition );
  567. PrintRoutine( pPrintContext,
  568. " %-9s %-14S %s%s%s%s%s%s\n",
  569. zoneTypeString(
  570. pZone->ZoneType,
  571. sizeof( sztype ),
  572. sztype ),
  573. pnamePartition, // szpartition,
  574. pZone->Flags.Update == 2 ?
  575. "Secure " :
  576. ( pZone->Flags.Update == 1 ?
  577. "Update " : "" ),
  578. pZone->Flags.Reverse ? "Rev " : "",
  579. pZone->Flags.AutoCreated ? "Auto " : "",
  580. pZone->Flags.Aging ? "Aging " : "",
  581. pZone->Flags.Paused ? "Paused " : "",
  582. pZone->Flags.Shutdown ? "Down " : "" );
  583. }
  584. DnsPrint_Unlock();
  585. FREE_HEAP( pnamePartition );
  586. }
  587. VOID
  588. DNS_API_FUNCTION
  589. DnsPrint_RpcZoneList(
  590. IN PRINT_ROUTINE PrintRoutine,
  591. IN OUT PPRINT_CONTEXT pPrintContext,
  592. IN LPSTR pszHeader,
  593. IN PDNS_RPC_ZONE_LIST pZoneList
  594. )
  595. {
  596. DWORD i;
  597. DnsPrint_Lock();
  598. if ( pszHeader )
  599. {
  600. PrintRoutine( pPrintContext, "%s\n", pszHeader );
  601. }
  602. if ( !pZoneList )
  603. {
  604. PrintRoutine( pPrintContext, "NULL zone list pointer.\n" );
  605. }
  606. else
  607. {
  608. PrintRoutine( pPrintContext, "\tZone count = %d\n\n", pZoneList->dwZoneCount );
  609. PrintRoutine( pPrintContext,
  610. " Zone name Type Storage Properties\n\n" );
  611. if ( pZoneList->dwZoneCount )
  612. {
  613. DnsPrint_RpcZone(
  614. PrintRoutine, pPrintContext,
  615. NULL, // print default header
  616. pZoneList->ZoneArray[0] );
  617. }
  618. for ( i=1; i<pZoneList->dwZoneCount; i++ )
  619. {
  620. DnsPrint_RpcZone(
  621. PrintRoutine, pPrintContext,
  622. NULL, // print default header
  623. pZoneList->ZoneArray[i] );
  624. }
  625. PrintRoutine( pPrintContext, "\n" );
  626. }
  627. DnsPrint_Unlock();
  628. }
  629. //
  630. // Directory parition debug utilities
  631. //
  632. VOID
  633. DnsPrint_RpcDpEnum(
  634. IN PRINT_ROUTINE PrintRoutine,
  635. IN OUT PPRINT_CONTEXT pPrintContext,
  636. IN LPSTR pszHeader,
  637. IN PDNS_RPC_DP_ENUM pDp
  638. )
  639. {
  640. PWSTR pnameDpFqdn = NULL;
  641. if ( !pDp )
  642. {
  643. PrintRoutine( pPrintContext, "NULL DP enum ptr\n" );
  644. }
  645. else
  646. {
  647. pnameDpFqdn = getUnicodeForUtf8( pDp->pszDpFqdn );
  648. PrintRoutine( pPrintContext,
  649. " %-40S %s%s%s%s%s%s\n",
  650. pnameDpFqdn, // pDp->pszDpFqdn,
  651. pDp->dwFlags & DNS_DP_ENLISTED ? "Enlisted " : "Not-Enlisted ",
  652. pDp->dwFlags & DNS_DP_DELETED ? "Deleted " : "",
  653. pDp->dwFlags & DNS_DP_AUTOCREATED ? "Auto " : "",
  654. pDp->dwFlags & DNS_DP_LEGACY ? "Legacy " : "",
  655. pDp->dwFlags & DNS_DP_DOMAIN_DEFAULT ? "Domain " : "",
  656. pDp->dwFlags & DNS_DP_FOREST_DEFAULT ? "Forest " : "" );
  657. }
  658. FREE_HEAP( pnameDpFqdn );
  659. } // DnsPrint_RpcDpEnum
  660. VOID
  661. DnsPrint_RpcDpInfo(
  662. IN PRINT_ROUTINE PrintRoutine,
  663. IN OUT PPRINT_CONTEXT pPrintContext,
  664. IN LPSTR pszHeader,
  665. IN PDNS_RPC_DP_INFO pDp,
  666. IN BOOL fTruncateLongStrings
  667. )
  668. {
  669. PWSTR pnameDpFqdn = NULL;
  670. DnsPrint_Lock();
  671. if ( !pDp )
  672. {
  673. PrintRoutine( pPrintContext,
  674. "%sNULL DP info ptr.\n",
  675. ( pszHeader ? pszHeader : "" ) );
  676. }
  677. else
  678. {
  679. WCHAR wsz[ 80 ];
  680. pnameDpFqdn = getUnicodeForUtf8( pDp->pszDpFqdn );
  681. PrintRoutine( pPrintContext,
  682. "%s\n"
  683. " DNS root: %S\n"
  684. " Flags: 0x%X %s%s%s%s%s%s\n"
  685. " State: %d\n"
  686. " Zone count: %d\n"
  687. " DP head: %S\n"
  688. " Crossref: ",
  689. pszHeader ? pszHeader : "",
  690. pnameDpFqdn, // pDp->pszDpFqdn,
  691. pDp->dwFlags,
  692. pDp->dwFlags & DNS_DP_ENLISTED ? "Enlisted " : "Not-Enlisted ",
  693. pDp->dwFlags & DNS_DP_DELETED ? "Deleted " : "",
  694. pDp->dwFlags & DNS_DP_AUTOCREATED ? "Auto " : "",
  695. pDp->dwFlags & DNS_DP_LEGACY ? "Legacy " : "",
  696. pDp->dwFlags & DNS_DP_DOMAIN_DEFAULT ? "Domain " : "",
  697. pDp->dwFlags & DNS_DP_FOREST_DEFAULT ? "Forest " : "",
  698. pDp->dwState,
  699. pDp->dwZoneCount,
  700. pDp->pszDpDn,
  701. pDp->pszCrDn );
  702. if ( fTruncateLongStrings )
  703. {
  704. truncateStringW( pDp->pszCrDn, wsz, 64 );
  705. PrintRoutine( pPrintContext, "%S", wsz );
  706. }
  707. else
  708. {
  709. PrintRoutine( pPrintContext, "%S", pDp->pszCrDn );
  710. }
  711. PrintRoutine( pPrintContext,
  712. "\n Replicas: %d\n",
  713. pDp->dwReplicaCount );
  714. if ( pDp->dwReplicaCount && pDp->ReplicaArray )
  715. {
  716. DWORD i;
  717. for ( i = 0;
  718. i < pDp->dwReplicaCount && pDp->ReplicaArray[ i ];
  719. ++i )
  720. {
  721. if ( fTruncateLongStrings )
  722. {
  723. truncateStringW(
  724. pDp->ReplicaArray[ i ]->pszReplicaDn,
  725. wsz,
  726. 74 );
  727. PrintRoutine( pPrintContext, " %S\n", wsz );
  728. }
  729. else
  730. {
  731. PrintRoutine( pPrintContext, " %S\n",
  732. pDp->ReplicaArray[ i ]->pszReplicaDn ?
  733. pDp->ReplicaArray[ i ]->pszReplicaDn : L"NULL" );
  734. }
  735. }
  736. }
  737. }
  738. DnsPrint_Unlock();
  739. FREE_HEAP( pnameDpFqdn );
  740. } // DnsPrint_RpcDpInfo
  741. VOID
  742. DNS_API_FUNCTION
  743. DnsPrint_RpcDpList(
  744. IN PRINT_ROUTINE PrintRoutine,
  745. IN OUT PPRINT_CONTEXT pPrintContext,
  746. IN LPSTR pszHeader,
  747. IN PDNS_RPC_DP_LIST pDpList
  748. )
  749. {
  750. DWORD i;
  751. DnsPrint_Lock();
  752. if ( pszHeader )
  753. {
  754. PrintRoutine( pPrintContext, "%s\n", pszHeader );
  755. }
  756. if ( !pDpList )
  757. {
  758. PrintRoutine( pPrintContext, "NULL directory partition list pointer.\n" );
  759. }
  760. else
  761. {
  762. PrintRoutine( pPrintContext, "\tDirectory partition count = %d\n\n", pDpList->dwDpCount );
  763. for ( i = 0; i < pDpList->dwDpCount && pDpList->DpArray[ i ]; ++i )
  764. {
  765. DnsPrint_RpcDpEnum(
  766. PrintRoutine, pPrintContext,
  767. NULL, // print default header
  768. pDpList->DpArray[ i ] );
  769. }
  770. PrintRoutine( pPrintContext, "\n" );
  771. }
  772. DnsPrint_Unlock();
  773. } // DnsPrint_RpcDpList
  774. VOID
  775. DnsPrint_RpcZoneInfo(
  776. IN PRINT_ROUTINE PrintRoutine,
  777. IN OUT PPRINT_CONTEXT pPrintContext,
  778. IN LPSTR pszHeader,
  779. IN PDNS_RPC_ZONE_INFO pZoneInfo
  780. )
  781. {
  782. CHAR szdpName[ 300 ]; // don't want truncation
  783. PWSTR pnameZone = NULL;
  784. PWSTR pnameFile = NULL;
  785. PWSTR pnameDp = NULL;
  786. DnsPrint_Lock();
  787. PrintRoutine( pPrintContext, (pszHeader ? pszHeader : "") );
  788. if ( ! pZoneInfo )
  789. {
  790. PrintRoutine( pPrintContext, "NULL zone info ptr.\n" );
  791. }
  792. else
  793. {
  794. pnameZone = getUnicodeForUtf8( pZoneInfo->pszZoneName );
  795. pnameFile = getUnicodeForUtf8( pZoneInfo->pszDataFile );
  796. PrintRoutine( pPrintContext,
  797. "Zone info:\n"
  798. "\tptr = %p\n"
  799. "\tzone name = %S\n"
  800. "\tzone type = %d\n"
  801. "\tupdate = %d\n"
  802. "\tDS integrated = %d\n"
  803. "\tdata file = %S\n"
  804. "\tusing WINS = %d\n"
  805. "\tusing Nbstat = %d\n"
  806. "\taging = %d\n"
  807. "\t refresh interval = %lu\n"
  808. "\t no refresh = %lu\n"
  809. "\t scavenge available = %lu\n",
  810. pZoneInfo,
  811. pnameZone, // pZoneInfo->pszZoneName,
  812. pZoneInfo->dwZoneType,
  813. pZoneInfo->fAllowUpdate,
  814. pZoneInfo->fUseDatabase,
  815. pnameFile, // pZoneInfo->pszDataFile,
  816. pZoneInfo->fUseWins,
  817. pZoneInfo->fUseNbstat,
  818. pZoneInfo->fAging,
  819. pZoneInfo->dwRefreshInterval,
  820. pZoneInfo->dwNoRefreshInterval,
  821. pZoneInfo->dwAvailForScavengeTime
  822. );
  823. DnsPrint_Ip4Array(
  824. PrintRoutine, pPrintContext,
  825. "\tZone Masters\n",
  826. "\tMaster",
  827. pZoneInfo->aipMasters );
  828. if ( pZoneInfo->dwZoneType == DNS_ZONE_TYPE_STUB )
  829. {
  830. DnsPrint_Ip4Array(
  831. PrintRoutine, pPrintContext,
  832. "\tZone Local Masters\n",
  833. "\tLocal Master",
  834. pZoneInfo->aipLocalMasters );
  835. }
  836. DnsPrint_Ip4Array(
  837. PrintRoutine, pPrintContext,
  838. "\tZone Secondaries\n",
  839. "\tSecondary",
  840. pZoneInfo->aipSecondaries );
  841. PrintRoutine( pPrintContext,
  842. "\tsecure secs = %d\n",
  843. pZoneInfo->fSecureSecondaries );
  844. if ( pZoneInfo->fUseDatabase )
  845. {
  846. partitionDisplayName(
  847. pZoneInfo->dwDpFlags,
  848. pZoneInfo->pszDpFqdn,
  849. sizeof( szdpName ),
  850. szdpName,
  851. DNS_DPDISP_REAL_CUSTOM_NAME ),
  852. pnameDp = getUnicodeForUtf8( szdpName );
  853. PrintRoutine( pPrintContext,
  854. "\tdirectory partition = %S flags %08X\n"
  855. "\tzone DN = %S\n",
  856. pnameDp,
  857. pZoneInfo->dwDpFlags,
  858. pZoneInfo->pwszZoneDn );
  859. }
  860. if ( pZoneInfo->aipScavengeServers )
  861. {
  862. DnsPrint_Ip4Array(
  863. PrintRoutine, pPrintContext,
  864. "\tScavenge Servers\n",
  865. "\tServer",
  866. pZoneInfo->aipScavengeServers );
  867. }
  868. if ( pZoneInfo->dwZoneType == DNS_ZONE_TYPE_FORWARDER )
  869. {
  870. PrintRoutine( pPrintContext,
  871. "\tforwarder timeout = %d\n"
  872. "\tforwarder slave = %d\n",
  873. pZoneInfo->dwForwarderTimeout,
  874. pZoneInfo->fForwarderSlave );
  875. }
  876. if ( pZoneInfo->dwZoneType == DNS_ZONE_TYPE_SECONDARY ||
  877. pZoneInfo->dwZoneType == DNS_ZONE_TYPE_STUB )
  878. {
  879. char szTime1[ 60 ] = DNS_NOT_PERFORMED;
  880. char szTime2[ 60 ] = DNS_NOT_PERFORMED;
  881. if ( pZoneInfo->dwLastSuccessfulXfr )
  882. {
  883. time_t t = pZoneInfo->dwLastSuccessfulXfr;
  884. strcpy( szTime1, ctime( &t ) );
  885. szTime1[ strlen( szTime1 ) - 1 ] = '\0';
  886. }
  887. if ( pZoneInfo->dwLastSuccessfulSoaCheck )
  888. {
  889. time_t t = pZoneInfo->dwLastSuccessfulSoaCheck;
  890. strcpy( szTime2, ctime( &t ) );
  891. szTime2[ strlen( szTime2 ) - 1 ] = '\0';
  892. }
  893. PrintRoutine( pPrintContext,
  894. "\tlast successful xfr = %s (%d)\n"
  895. "\tlast SOA check = %s (%d)\n",
  896. szTime1,
  897. pZoneInfo->dwLastSuccessfulXfr,
  898. szTime2,
  899. pZoneInfo->dwLastSuccessfulSoaCheck );
  900. }
  901. }
  902. DnsPrint_Unlock();
  903. FREE_HEAP( pnameZone );
  904. FREE_HEAP( pnameFile );
  905. FREE_HEAP( pnameDp );
  906. }
  907. VOID
  908. DnsPrint_RpcZoneInfoList(
  909. IN PRINT_ROUTINE PrintRoutine,
  910. IN OUT PPRINT_CONTEXT pPrintContext,
  911. IN LPSTR pszHeader,
  912. IN DWORD dwZoneCount,
  913. IN PDNS_RPC_ZONE_INFO apZoneInfo[]
  914. )
  915. {
  916. DWORD i;
  917. DnsPrint_Lock();
  918. PrintRoutine( pPrintContext, (pszHeader ? pszHeader : "") );
  919. PrintRoutine( pPrintContext, "Zone Count = %d\n", dwZoneCount );
  920. if ( dwZoneCount != 0 && apZoneInfo != NULL )
  921. {
  922. for (i=0; i<dwZoneCount; i++)
  923. {
  924. DnsPrint_RpcZoneInfo(
  925. PrintRoutine, pPrintContext,
  926. NULL,
  927. apZoneInfo[i] );
  928. }
  929. }
  930. DnsPrint_Unlock();
  931. }
  932. //
  933. // Print domain node and record buffers
  934. //
  935. VOID
  936. DnssrvCopyRpcNameToBuffer(
  937. IN PSTR pResult,
  938. IN PDNS_RPC_NAME pName
  939. )
  940. /*++
  941. Routine Description:
  942. Copy RPC name to buffer.
  943. Arguments:
  944. pResult -- result buffer; assumed to be at least DNS_MAX_NAME_LENGTH
  945. pName -- RPC name
  946. Return Value:
  947. None
  948. --*/
  949. {
  950. DWORD length = pName->cchNameLength;
  951. strncpy( pResult, pName->achName, length );
  952. pResult[ length ] = 0;
  953. }
  954. VOID
  955. DnsPrint_RpcName(
  956. IN PRINT_ROUTINE PrintRoutine,
  957. IN OUT PPRINT_CONTEXT pPrintContext,
  958. IN LPSTR pszHeader,
  959. IN PDNS_RPC_NAME pName,
  960. IN LPSTR pszTrailer
  961. )
  962. /*++
  963. Routine Description:
  964. Prints RPC name.
  965. Arguments:
  966. PrintRoutine -- printf like routine to print with
  967. pszHeader -- header string
  968. pName -- RPC name
  969. pszTrailer -- trailer string
  970. Return Value:
  971. None
  972. --*/
  973. {
  974. PWSTR pname = NULL;
  975. PWSTR pnameAlloc = NULL;
  976. //
  977. // print name to given length
  978. //
  979. if ( !pszHeader )
  980. {
  981. pszHeader = "";
  982. }
  983. if ( !pszTrailer )
  984. {
  985. pszTrailer = "";
  986. }
  987. if ( ! pName )
  988. {
  989. pname = L"(NULL DNS name ptr)";
  990. }
  991. else if ( pName->cchNameLength > 0 )
  992. {
  993. pname = pnameAlloc = utf8ToUnicode( pName->achName, pName->cchNameLength );
  994. if ( !pname )
  995. {
  996. pname = L"<OUT OF MEMORY>";
  997. }
  998. }
  999. else // @ for empty node name
  1000. {
  1001. pname = L"@";
  1002. }
  1003. PrintRoutine( pPrintContext,
  1004. "%s%S%s",
  1005. pszHeader,
  1006. pname,
  1007. pszTrailer );
  1008. FREE_HEAP( pnameAlloc );
  1009. }
  1010. VOID
  1011. DnsPrint_RpcNode(
  1012. IN PRINT_ROUTINE PrintRoutine,
  1013. IN OUT PPRINT_CONTEXT pPrintContext,
  1014. IN LPSTR pszHeader,
  1015. IN PDNS_RPC_NODE pNode
  1016. )
  1017. /*++
  1018. Routine Description:
  1019. Prints RPC node.
  1020. Arguments:
  1021. PrintRoutine -- printf like routine to print with
  1022. pszHeader -- header string
  1023. pNode -- RPC node to print
  1024. Return Value:
  1025. None
  1026. --*/
  1027. {
  1028. DnsPrint_Lock();
  1029. PrintRoutine( pPrintContext, (pszHeader ? pszHeader : "RPC Node:") );
  1030. if ( ! pNode )
  1031. {
  1032. PrintRoutine( pPrintContext, "NULL RPC node ptr.\n" );
  1033. }
  1034. else
  1035. {
  1036. PrintRoutine( pPrintContext,
  1037. "\n"
  1038. "\tptr = %p\n"
  1039. "\twLength = %d\n"
  1040. "\twRecordCount = %d\n"
  1041. "\tdwChildCount = %d\n"
  1042. "\tdwFlags = %p\n",
  1043. pNode,
  1044. pNode->wLength,
  1045. pNode->wRecordCount,
  1046. pNode->dwChildCount,
  1047. pNode->dwFlags );
  1048. DnsPrint_RpcName(
  1049. PrintRoutine,
  1050. pPrintContext,
  1051. "\tNode Name = ",
  1052. & pNode->dnsNodeName,
  1053. "\n" );
  1054. }
  1055. DnsPrint_Unlock();
  1056. }
  1057. VOID
  1058. DnsPrint_RpcRecord(
  1059. IN PRINT_ROUTINE PrintRoutine,
  1060. IN OUT PPRINT_CONTEXT pPrintContext,
  1061. IN LPSTR pszHeader,
  1062. IN BOOL fDetail,
  1063. IN PDNS_FLAT_RECORD pRecord
  1064. )
  1065. /*++
  1066. Routine Description:
  1067. Prints RPC record.
  1068. Arguments:
  1069. PrintRoutine -- printf like routine to print with
  1070. pszHeader -- header string
  1071. fDetail -- if TRUE print detailed record info
  1072. pRecord -- RPC record to print
  1073. Return Value:
  1074. None
  1075. --*/
  1076. {
  1077. PCHAR ptypeString;
  1078. PDNS_RPC_RECORD_DATA pdata;
  1079. WORD type;
  1080. WORD dataLength;
  1081. SYSTEMTIME sysTime;
  1082. CHAR szBuff[ 5000 ];
  1083. DnsPrint_Lock();
  1084. PrintRoutine( pPrintContext, (pszHeader ? pszHeader : "" ) );
  1085. if ( ! pRecord )
  1086. {
  1087. PrintRoutine( pPrintContext, "NULL record ptr.\n" );
  1088. goto Done;
  1089. }
  1090. //
  1091. // record fixed fields
  1092. //
  1093. type = pRecord->wType;
  1094. ptypeString = Dns_RecordStringForType( type );
  1095. if ( !ptypeString )
  1096. {
  1097. ptypeString = "UNKNOWN";
  1098. }
  1099. pdata = &pRecord->Data;
  1100. dataLength = pRecord->wDataLength;
  1101. if ( fDetail )
  1102. {
  1103. Dns_SystemHourToSystemTime(
  1104. pRecord->dwTimeStamp,
  1105. &sysTime );
  1106. PrintRoutine( pPrintContext,
  1107. " %s Record info:\n"
  1108. "\tptr = %p\n"
  1109. "\twType = %s (%u)\n"
  1110. "\twDataLength = %u\n"
  1111. "\tdwFlags = %lx\n"
  1112. "\trank = %x\n"
  1113. "\tdwSerial = %p\n"
  1114. "\tdwTtlSeconds = %u\n"
  1115. "\tdwTimeStamp = %lu ([%2d:%2d:%2d] [%2d/%2d/%2d])\n",
  1116. ptypeString,
  1117. pRecord,
  1118. ptypeString,
  1119. type,
  1120. pRecord->wDataLength,
  1121. pRecord->dwFlags,
  1122. (UCHAR)(pRecord->dwFlags & DNS_RPC_FLAG_RANK),
  1123. pRecord->dwSerial,
  1124. pRecord->dwTtlSeconds,
  1125. pRecord->dwTimeStamp,
  1126. sysTime.wHour,
  1127. sysTime.wMinute,
  1128. sysTime.wSecond,
  1129. sysTime.wMonth,
  1130. sysTime.wDay,
  1131. sysTime.wYear
  1132. );
  1133. }
  1134. //
  1135. // print record type and data
  1136. // - as single line data where possible
  1137. if ( !fDetail )
  1138. {
  1139. if ( pRecord->dwTimeStamp )
  1140. {
  1141. PrintRoutine( pPrintContext,
  1142. " [Aging:%lu]",
  1143. pRecord->dwTimeStamp );
  1144. }
  1145. PrintRoutine( pPrintContext,
  1146. " %lu",
  1147. pRecord->dwTtlSeconds );
  1148. }
  1149. PrintRoutine( pPrintContext,
  1150. " %s\t",
  1151. ptypeString );
  1152. //
  1153. // print type data
  1154. //
  1155. switch ( type )
  1156. {
  1157. case DNS_TYPE_A:
  1158. PrintRoutine( pPrintContext,
  1159. "%d.%d.%d.%d\n",
  1160. * ( (PUCHAR) &(pdata->A) + 0 ),
  1161. * ( (PUCHAR) &(pdata->A) + 1 ),
  1162. * ( (PUCHAR) &(pdata->A) + 2 ),
  1163. * ( (PUCHAR) &(pdata->A) + 3 )
  1164. );
  1165. break;
  1166. case DNS_TYPE_PTR:
  1167. case DNS_TYPE_NS:
  1168. case DNS_TYPE_CNAME:
  1169. case DNS_TYPE_MD:
  1170. case DNS_TYPE_MB:
  1171. case DNS_TYPE_MF:
  1172. case DNS_TYPE_MG:
  1173. case DNS_TYPE_MR:
  1174. //
  1175. // these RRs contain single indirection
  1176. //
  1177. DnsPrint_RpcName(
  1178. PrintRoutine, pPrintContext,
  1179. NULL,
  1180. & pdata->NS.nameNode,
  1181. "\n" );
  1182. break;
  1183. case DNS_TYPE_MX:
  1184. case DNS_TYPE_RT:
  1185. case DNS_TYPE_AFSDB:
  1186. //
  1187. // these RR contain
  1188. // - one preference value
  1189. // - one domain name
  1190. //
  1191. PrintRoutine( pPrintContext,
  1192. "%d ",
  1193. pdata->MX.wPreference
  1194. );
  1195. DnsPrint_RpcName(
  1196. PrintRoutine, pPrintContext,
  1197. NULL,
  1198. & pdata->MX.nameExchange,
  1199. "\n" );
  1200. break;
  1201. case DNS_TYPE_SOA:
  1202. if ( fDetail )
  1203. {
  1204. DnsPrint_RpcName(
  1205. PrintRoutine, pPrintContext,
  1206. "\n\tPrimaryNameServer: ",
  1207. & pdata->SOA.namePrimaryServer,
  1208. "\n" );
  1209. // responsible party name, immediately follows primary server name
  1210. DnsPrint_RpcName(
  1211. PrintRoutine, pPrintContext,
  1212. "\tResponsibleParty: ",
  1213. (PDNS_RPC_NAME)
  1214. (pdata->SOA.namePrimaryServer.achName
  1215. + pdata->SOA.namePrimaryServer.cchNameLength),
  1216. "\n" );
  1217. PrintRoutine( pPrintContext,
  1218. "\tSerialNo = %lu\n"
  1219. "\tRefresh = %lu\n"
  1220. "\tRetry = %lu\n"
  1221. "\tExpire = %lu\n"
  1222. "\tMinimumTTL = %lu\n",
  1223. pdata->SOA.dwSerialNo,
  1224. pdata->SOA.dwRefresh,
  1225. pdata->SOA.dwRetry,
  1226. pdata->SOA.dwExpire,
  1227. pdata->SOA.dwMinimumTtl );
  1228. break;
  1229. }
  1230. else
  1231. {
  1232. DnsPrint_RpcName(
  1233. PrintRoutine, pPrintContext,
  1234. NULL,
  1235. & pdata->SOA.namePrimaryServer,
  1236. NULL );
  1237. // responsible party name, immediately follows primary server name
  1238. DnsPrint_RpcName(
  1239. PrintRoutine, pPrintContext,
  1240. " ",
  1241. (PDNS_RPC_NAME)
  1242. (pdata->SOA.namePrimaryServer.achName
  1243. + pdata->SOA.namePrimaryServer.cchNameLength),
  1244. NULL );
  1245. PrintRoutine( pPrintContext,
  1246. " %lu"
  1247. " %lu"
  1248. " %lu"
  1249. " %lu"
  1250. " %lu\n",
  1251. pdata->SOA.dwSerialNo,
  1252. pdata->SOA.dwRefresh,
  1253. pdata->SOA.dwRetry,
  1254. pdata->SOA.dwExpire,
  1255. pdata->SOA.dwMinimumTtl );
  1256. break;
  1257. }
  1258. case DNS_TYPE_AAAA:
  1259. {
  1260. CHAR ip6String[ IP6_ADDRESS_STRING_LENGTH+1 ];
  1261. Dns_Ip6AddressToString_A(
  1262. ip6String,
  1263. &pdata->AAAA.ipv6Address
  1264. );
  1265. PrintRoutine( pPrintContext,
  1266. "%s\n",
  1267. ip6String );
  1268. }
  1269. break;
  1270. case DNS_TYPE_HINFO:
  1271. case DNS_TYPE_ISDN:
  1272. case DNS_TYPE_X25:
  1273. case DNS_TYPE_TEXT:
  1274. {
  1275. //
  1276. // all these are simply text string(s)
  1277. //
  1278. // TXT strings will be printed one per line
  1279. //
  1280. PCHAR pch = (PCHAR) &pdata->TXT.stringData;
  1281. PCHAR pchStop = pch + dataLength;
  1282. UCHAR cch;
  1283. while ( pch < pchStop )
  1284. {
  1285. cch = (UCHAR) *pch++;
  1286. if ( type == DNS_TYPE_TEXT )
  1287. {
  1288. PrintRoutine( pPrintContext,
  1289. "\t%.*s\n",
  1290. cch,
  1291. pch );
  1292. }
  1293. else
  1294. {
  1295. PrintRoutine( pPrintContext,
  1296. "\"%.*s\" ",
  1297. cch,
  1298. pch );
  1299. }
  1300. pch += cch;
  1301. }
  1302. if ( type != DNS_TYPE_TEXT )
  1303. {
  1304. PrintRoutine( pPrintContext,"\n");
  1305. }
  1306. ASSERT( pch == pchStop );
  1307. break;
  1308. }
  1309. case DNS_TYPE_MINFO:
  1310. case DNS_TYPE_RP:
  1311. //
  1312. // these RRs contain two domain names
  1313. //
  1314. DnsPrint_RpcName(
  1315. PrintRoutine, pPrintContext,
  1316. NULL,
  1317. & pdata->MINFO.nameMailBox,
  1318. NULL );
  1319. // errors to mailbox name, immediately follows mail box
  1320. DnsPrint_RpcName(
  1321. PrintRoutine, pPrintContext,
  1322. " ",
  1323. (PDNS_RPC_NAME)
  1324. ( pdata->MINFO.nameMailBox.achName
  1325. + pdata->MINFO.nameMailBox.cchNameLength ),
  1326. "\n" );
  1327. break;
  1328. case DNS_TYPE_WKS:
  1329. {
  1330. INT i;
  1331. if ( fDetail )
  1332. {
  1333. PrintRoutine( pPrintContext,
  1334. "WKS: Address %d.%d.%d.%d\n"
  1335. "\tProtocol %d\n"
  1336. "\tBitmask\n",
  1337. * ( (PUCHAR) &(pdata->WKS.ipAddress) + 0 ),
  1338. * ( (PUCHAR) &(pdata->WKS.ipAddress) + 1 ),
  1339. * ( (PUCHAR) &(pdata->WKS.ipAddress) + 2 ),
  1340. * ( (PUCHAR) &(pdata->WKS.ipAddress) + 3 ),
  1341. pdata->WKS.chProtocol
  1342. );
  1343. for ( i = 0;
  1344. i < (INT)( dataLength
  1345. - sizeof( pdata->WKS.ipAddress )
  1346. - sizeof( pdata->WKS.chProtocol ) );
  1347. i++ )
  1348. {
  1349. PrintRoutine( pPrintContext,
  1350. "\t\tbyte[%d] = %x\n",
  1351. i,
  1352. (UCHAR) pdata->WKS.bBitMask[i] );
  1353. }
  1354. break;
  1355. }
  1356. else
  1357. {
  1358. DNS_STATUS status;
  1359. struct protoent * pProtoent;
  1360. WSADATA wsaData;
  1361. PrintRoutine( pPrintContext,
  1362. "%d.%d.%d.%d ",
  1363. * ( (PUCHAR) &(pdata->WKS.ipAddress) + 0 ),
  1364. * ( (PUCHAR) &(pdata->WKS.ipAddress) + 1 ),
  1365. * ( (PUCHAR) &(pdata->WKS.ipAddress) + 2 ),
  1366. * ( (PUCHAR) &(pdata->WKS.ipAddress) + 3 )
  1367. );
  1368. //
  1369. // get protocol number:
  1370. //
  1371. // start winsock:
  1372. status = WSAStartup( DNS_WINSOCK_VERSION, &wsaData );
  1373. if ( status == SOCKET_ERROR )
  1374. {
  1375. status = WSAGetLastError();
  1376. SetLastError( status );
  1377. PrintRoutine( pPrintContext,
  1378. "ERROR: WSAGetLastError()\n"
  1379. );
  1380. ASSERT(FALSE);
  1381. }
  1382. pProtoent = getprotobynumber( pdata->WKS.chProtocol );
  1383. if ( ! pProtoent || pProtoent->p_proto >= MAXUCHAR )
  1384. {
  1385. status = WSAGetLastError();
  1386. SetLastError( status );
  1387. PrintRoutine( pPrintContext, "ERROR: getprotobyname()\n" );
  1388. ASSERT(FALSE);
  1389. }
  1390. PrintRoutine( pPrintContext,
  1391. "%s\t",
  1392. pProtoent->p_name
  1393. );
  1394. //bBitMask[0] : string length, not printed:
  1395. for ( i = 1;
  1396. i < (INT)( dataLength
  1397. - sizeof( pdata->WKS.ipAddress )
  1398. - sizeof( pdata->WKS.chProtocol ) );
  1399. i++ )
  1400. {
  1401. PrintRoutine( pPrintContext,
  1402. "%c",
  1403. (UCHAR) pdata->WKS.bBitMask[i] );
  1404. }
  1405. PrintRoutine( pPrintContext,"\n");
  1406. break;
  1407. }
  1408. }
  1409. case DNS_TYPE_NULL:
  1410. {
  1411. INT i;
  1412. for ( i = 0; i < dataLength; i++ )
  1413. {
  1414. // print one DWORD per line
  1415. if ( !(i%16) )
  1416. {
  1417. PrintRoutine( pPrintContext, "\n\t" );
  1418. }
  1419. PrintRoutine( pPrintContext,
  1420. "%02x ",
  1421. (UCHAR) pdata->Null.bData[i] );
  1422. }
  1423. PrintRoutine( pPrintContext, "\n" );
  1424. break;
  1425. }
  1426. case DNS_TYPE_SRV:
  1427. //
  1428. // SRV <priority> <weight> <port> <target host>
  1429. //
  1430. PrintRoutine( pPrintContext,
  1431. "%d %d %d ",
  1432. pdata->SRV.wPriority,
  1433. pdata->SRV.wWeight,
  1434. pdata->SRV.wPort
  1435. );
  1436. DnsPrint_RpcName(
  1437. PrintRoutine, pPrintContext,
  1438. NULL,
  1439. & pdata->SRV.nameTarget,
  1440. "\n" );
  1441. break;
  1442. case DNS_TYPE_WINS:
  1443. {
  1444. DWORD i;
  1445. CHAR flagName[ WINS_FLAG_MAX_LENGTH ];
  1446. //
  1447. // WINS
  1448. // - scope/domain mapping flag
  1449. // - WINS server list
  1450. //
  1451. Dns_WinsRecordFlagString(
  1452. pdata->WINS.dwMappingFlag,
  1453. flagName );
  1454. PrintRoutine( pPrintContext,
  1455. "%s %d %d ",
  1456. flagName,
  1457. //pdata->WINS.dwMappingFlag,
  1458. pdata->WINS.dwLookupTimeout,
  1459. pdata->WINS.dwCacheTimeout
  1460. );
  1461. if ( fDetail )
  1462. {
  1463. PrintRoutine( pPrintContext, " WINS Servers:\n" );
  1464. }
  1465. for( i=0; i<pdata->WINS.cWinsServerCount; i++ )
  1466. {
  1467. PrintRoutine( pPrintContext,
  1468. "%d.%d.%d.%d%c",
  1469. * ( (PUCHAR) &(pdata->WINS.aipWinsServers[i]) + 0 ),
  1470. * ( (PUCHAR) &(pdata->WINS.aipWinsServers[i]) + 1 ),
  1471. * ( (PUCHAR) &(pdata->WINS.aipWinsServers[i]) + 2 ),
  1472. * ( (PUCHAR) &(pdata->WINS.aipWinsServers[i]) + 3 ),
  1473. fDetail ? '\n' : ' '
  1474. );
  1475. }
  1476. if ( !fDetail )
  1477. {
  1478. PrintRoutine( pPrintContext, "\n" );
  1479. }
  1480. break;
  1481. }
  1482. case DNS_TYPE_NBSTAT:
  1483. {
  1484. CHAR flagName[ WINS_FLAG_MAX_LENGTH ];
  1485. //
  1486. // NBSTAT
  1487. // - scope/domain mapping flag
  1488. // - optionally a result domain
  1489. //
  1490. Dns_WinsRecordFlagString(
  1491. pdata->WINS.dwMappingFlag,
  1492. flagName );
  1493. PrintRoutine( pPrintContext,
  1494. "%s %d %d ",
  1495. flagName,
  1496. //pdata->WINS.dwMappingFlag,
  1497. pdata->NBSTAT.dwLookupTimeout,
  1498. pdata->NBSTAT.dwCacheTimeout
  1499. );
  1500. if ( dataLength > sizeof(pdata->NBSTAT.dwMappingFlag) )
  1501. {
  1502. DnsPrint_RpcName(
  1503. PrintRoutine, pPrintContext,
  1504. NULL,
  1505. & pdata->NBSTAT.nameResultDomain,
  1506. "\n" );
  1507. }
  1508. break;
  1509. }
  1510. case DNS_TYPE_KEY:
  1511. {
  1512. int keyLength = dataLength - SIZEOF_KEY_FIXED_DATA;
  1513. PrintRoutine( pPrintContext,
  1514. "0x%04X %d %d ",
  1515. ( int ) pdata->KEY.wFlags,
  1516. ( int ) pdata->KEY.chProtocol,
  1517. ( int ) pdata->KEY.chAlgorithm );
  1518. if ( keyLength > 0 && keyLength < sizeof( szBuff ) / 2 )
  1519. {
  1520. PCHAR p = Dns_SecurityKeyToBase64String(
  1521. ( PBYTE ) pdata + SIZEOF_KEY_FIXED_DATA,
  1522. keyLength,
  1523. szBuff );
  1524. if ( p )
  1525. {
  1526. *p = '\0'; // NULL terminate key string
  1527. }
  1528. PrintRoutine( pPrintContext, szBuff );
  1529. }
  1530. else
  1531. {
  1532. PrintRoutine( pPrintContext, "KEY = %d bytes", keyLength );
  1533. }
  1534. PrintRoutine( pPrintContext, "\n" );
  1535. break;
  1536. }
  1537. case DNS_TYPE_SIG:
  1538. {
  1539. CHAR szSigExp[ 30 ];
  1540. CHAR szSigInc[ 30 ];
  1541. INT sigOffset =
  1542. SIZEOF_SIG_FIXED_DATA +
  1543. pdata->SIG.nameSigner.cchNameLength +
  1544. sizeof( pdata->SIG.nameSigner.cchNameLength );
  1545. INT sigLength = dataLength - sigOffset;
  1546. ptypeString = Dns_RecordStringForType( pdata->SIG.wTypeCovered );
  1547. if ( !ptypeString )
  1548. {
  1549. ptypeString = "UNKNOWN-TYPE";
  1550. }
  1551. PrintRoutine( pPrintContext,
  1552. "%s %d %d %d %s %s %d ",
  1553. ptypeString,
  1554. ( int ) pdata->SIG.chAlgorithm,
  1555. ( int ) pdata->SIG.chLabelCount,
  1556. ( int ) pdata->SIG.dwOriginalTtl,
  1557. Dns_SigTimeString(
  1558. pdata->SIG.dwSigExpiration,
  1559. szSigExp ),
  1560. Dns_SigTimeString(
  1561. pdata->SIG.dwSigInception,
  1562. szSigInc ),
  1563. ( int ) pdata->SIG.wKeyTag );
  1564. DnsPrint_RpcName(
  1565. PrintRoutine, pPrintContext,
  1566. NULL,
  1567. &pdata->SIG.nameSigner,
  1568. " " );
  1569. if ( sigLength > 0 && sigLength < sizeof( szBuff ) / 2 )
  1570. {
  1571. PCHAR p = Dns_SecurityKeyToBase64String(
  1572. ( PBYTE ) pdata + sigOffset,
  1573. sigLength,
  1574. szBuff );
  1575. if ( p )
  1576. {
  1577. *p = '\0'; // NULL terminate key string
  1578. }
  1579. PrintRoutine( pPrintContext, szBuff );
  1580. }
  1581. else
  1582. {
  1583. PrintRoutine( pPrintContext, "SIG = %d bytes", sigLength );
  1584. }
  1585. PrintRoutine( pPrintContext, "\n" );
  1586. break;
  1587. }
  1588. case DNS_TYPE_NXT:
  1589. {
  1590. INT typeIdx;
  1591. DnsPrint_RpcName(
  1592. PrintRoutine, pPrintContext,
  1593. NULL,
  1594. ( PDNS_RPC_NAME ) ( ( PBYTE ) &pdata->NXT +
  1595. ( pdata->NXT.wNumTypeWords + 1 ) * sizeof( WORD ) ),
  1596. NULL );
  1597. for ( typeIdx = 0; typeIdx < pdata->NXT.wNumTypeWords; ++typeIdx )
  1598. {
  1599. ptypeString =
  1600. Dns_RecordStringForType( pdata->NXT.wTypeWords[ typeIdx ] );
  1601. if ( !ptypeString )
  1602. {
  1603. ptypeString = "UNKNOWN-TYPE";
  1604. }
  1605. PrintRoutine( pPrintContext,
  1606. " %s",
  1607. ptypeString );
  1608. }
  1609. PrintRoutine( pPrintContext, "\n" );
  1610. break;
  1611. }
  1612. default:
  1613. PrintRoutine( pPrintContext,
  1614. "Unknown resource record type (%d) at %p.\n",
  1615. type,
  1616. pRecord );
  1617. break;
  1618. }
  1619. Done:
  1620. DnsPrint_Unlock();
  1621. }
  1622. PDNS_RPC_NAME
  1623. DNS_API_FUNCTION
  1624. DnsPrint_RpcRecordsInBuffer(
  1625. IN PRINT_ROUTINE PrintRoutine,
  1626. IN OUT PPRINT_CONTEXT pPrintContext,
  1627. IN LPSTR pszHeader,
  1628. IN BOOL fDetail,
  1629. IN DWORD dwBufferLength,
  1630. IN BYTE abBuffer[]
  1631. )
  1632. /*++
  1633. Routine Description:
  1634. Prints RPC buffer.
  1635. Arguments:
  1636. PrintRoutine -- printf like routine to print with
  1637. pszHeader -- header string
  1638. fDetail -- if TRUE print detailed record info
  1639. dwBufferLength -- buffer length
  1640. abBuffer -- ptr to RPC buffer
  1641. Return Value:
  1642. Ptr to last RPC node name in buffer.
  1643. NULL on error.
  1644. --*/
  1645. {
  1646. PBYTE pcurrent;
  1647. PBYTE pstop;
  1648. PDNS_RPC_NAME plastName = NULL;
  1649. INT recordCount;
  1650. PCHAR precordHeader;
  1651. DnsPrint_Lock();
  1652. PrintRoutine( pPrintContext, (pszHeader ? pszHeader : "") );
  1653. if ( !abBuffer )
  1654. {
  1655. PrintRoutine( pPrintContext, "NULL record buffer ptr.\n" );
  1656. goto Done;
  1657. }
  1658. #if 0
  1659. else
  1660. {
  1661. PrintRoutine( pPrintContext,
  1662. "Record buffer of length %d at %p:\n",
  1663. dwBufferLength,
  1664. abBuffer );
  1665. }
  1666. #endif
  1667. //
  1668. // find stop byte
  1669. //
  1670. ASSERT( DNS_IS_DWORD_ALIGNED(abBuffer) );
  1671. pstop = abBuffer + dwBufferLength;
  1672. pcurrent = abBuffer;
  1673. //
  1674. // loop until out of nodes
  1675. //
  1676. while ( pcurrent < pstop )
  1677. {
  1678. //
  1679. // print owner node
  1680. // - if NOT printing detail and no records
  1681. // (essentially domain nodes) then no node print
  1682. //
  1683. plastName = &((PDNS_RPC_NODE)pcurrent)->dnsNodeName;
  1684. recordCount = ((PDNS_RPC_NODE)pcurrent)->wRecordCount;
  1685. if ( fDetail )
  1686. {
  1687. DnsPrint_RpcNode(
  1688. PrintRoutine, pPrintContext,
  1689. NULL,
  1690. (PDNS_RPC_NODE)pcurrent );
  1691. if ( recordCount == 0 )
  1692. {
  1693. PrintRoutine( pPrintContext,"\n");
  1694. }
  1695. }
  1696. else
  1697. {
  1698. #ifndef DBG
  1699. if ( recordCount != 0 )
  1700. #endif
  1701. {
  1702. DnsPrint_RpcName(
  1703. PrintRoutine, pPrintContext,
  1704. NULL,
  1705. plastName,
  1706. NULL );
  1707. #ifdef DBG
  1708. if ( recordCount == 0 )
  1709. {
  1710. PrintRoutine( pPrintContext, "\t\t(node)\n" );
  1711. }
  1712. #endif
  1713. }
  1714. }
  1715. pcurrent += ((PDNS_RPC_NODE)pcurrent)->wLength;
  1716. pcurrent = DNS_NEXT_DWORD_PTR(pcurrent);
  1717. //
  1718. // for each node, print all records in list
  1719. //
  1720. if ( !recordCount )
  1721. {
  1722. continue;
  1723. }
  1724. precordHeader = "";
  1725. while( recordCount-- )
  1726. {
  1727. if ( pcurrent >= pstop )
  1728. {
  1729. PrintRoutine( pPrintContext,
  1730. "ERROR: Bogus buffer at %p\n"
  1731. "\tExpect record at %p past buffer end at %p\n"
  1732. "\twith %d records remaining.\n",
  1733. abBuffer,
  1734. (PDNS_RPC_RECORD) pcurrent,
  1735. pstop,
  1736. recordCount+1 );
  1737. ASSERT( FALSE );
  1738. break;
  1739. }
  1740. DnsPrint_RpcRecord(
  1741. PrintRoutine, pPrintContext,
  1742. precordHeader,
  1743. fDetail,
  1744. (PDNS_RPC_RECORD)pcurrent );
  1745. precordHeader = "\t\t";
  1746. pcurrent += ((PDNS_RPC_RECORD)pcurrent)->wDataLength
  1747. + SIZEOF_DNS_RPC_RECORD_HEADER;
  1748. pcurrent = DNS_NEXT_DWORD_PTR(pcurrent);
  1749. }
  1750. }
  1751. Done:
  1752. DnsPrint_Unlock();
  1753. return( plastName );
  1754. }
  1755. VOID
  1756. DNS_API_FUNCTION
  1757. DnsPrint_Node(
  1758. IN PRINT_ROUTINE PrintRoutine,
  1759. IN OUT PPRINT_CONTEXT pPrintContext,
  1760. IN LPSTR pszHeader,
  1761. IN PDNS_NODE pNode,
  1762. IN BOOLEAN fPrintRecords
  1763. )
  1764. {
  1765. DnsPrint_Lock();
  1766. PrintRoutine( pPrintContext, (pszHeader ? pszHeader : "") );
  1767. if ( !pNode )
  1768. {
  1769. PrintRoutine( pPrintContext, " NULL DNS node ptr.\n" );
  1770. goto Unlock;
  1771. }
  1772. else
  1773. {
  1774. // DCR: WARNING: char set on RPC name print -- it's probably UTF8 if not unicode
  1775. PrintRoutine( pPrintContext,
  1776. "%s\n"
  1777. "\tName = %s%S\n"
  1778. "\tPtr = %p, pNext = %p\n"
  1779. "\tFlags = %p\n"
  1780. "\tRec ptr = %p\n",
  1781. pszHeader ? "" : "DNS node",
  1782. (PSTR) (pNode->Flags.S.Unicode ? "" : (PSTR) pNode->pName),
  1783. (PWSTR) (pNode->Flags.S.Unicode ? pNode->pName : L""),
  1784. pNode,
  1785. pNode->pNext,
  1786. pNode->Flags.W,
  1787. pNode->pRecord );
  1788. }
  1789. //
  1790. // if desired print record list
  1791. //
  1792. if ( pNode->pRecord && fPrintRecords )
  1793. {
  1794. DnsPrint_RecordSet(
  1795. PrintRoutine, pPrintContext,
  1796. "\trecords:\n",
  1797. pNode->pRecord );
  1798. }
  1799. Unlock:
  1800. DnsPrint_Unlock();
  1801. }
  1802. VOID
  1803. DNS_API_FUNCTION
  1804. DnsPrint_NodeList(
  1805. IN PRINT_ROUTINE PrintRoutine,
  1806. IN OUT PPRINT_CONTEXT pPrintContext,
  1807. IN LPSTR pszHeader,
  1808. IN PDNS_NODE pNode,
  1809. IN BOOLEAN fPrintRecords
  1810. )
  1811. {
  1812. DnsPrint_Lock();
  1813. PrintRoutine( pPrintContext, (pszHeader ? pszHeader : "") );
  1814. if ( !pNode )
  1815. {
  1816. PrintRoutine( pPrintContext, " NULL node list pointer.\n" );
  1817. }
  1818. else
  1819. {
  1820. do
  1821. {
  1822. DnsPrint_Node(
  1823. PrintRoutine, pPrintContext,
  1824. NULL,
  1825. pNode,
  1826. fPrintRecords );
  1827. }
  1828. while ( pNode = pNode->pNext );
  1829. }
  1830. DnsPrint_Unlock();
  1831. }
  1832. //
  1833. // RPC Type union printing
  1834. //
  1835. VOID
  1836. DnsPrint_RpcIpArrayPlusParameters(
  1837. IN PRINT_ROUTINE PrintRoutine,
  1838. IN OUT PPRINT_CONTEXT pPrintContext,
  1839. IN LPSTR pszHeader,
  1840. IN LPSTR pszStructureName,
  1841. IN LPSTR pszParam1Name,
  1842. IN DWORD dwParam1,
  1843. IN LPSTR pszParam2Name,
  1844. IN DWORD dwParam2,
  1845. IN LPSTR pszIpArrayHeader,
  1846. IN PIP4_ARRAY pIpArray
  1847. )
  1848. /*++
  1849. Routine Description:
  1850. Print info that contains up to two params and IP_ARRAY.
  1851. This is kludgy, but there are several RPC types that contain an
  1852. IP array and some flags. This does the right thing for all those
  1853. cases.
  1854. Arguments:
  1855. pszParam1Name -- name of parameter;
  1856. pszParam2Name -- name of parameter; serves as flag as to whether
  1857. param2 is printed
  1858. pszIpArrayHeader -- name of IP array, passed to DnsPrint_Ip4Array
  1859. as header; should be full header line
  1860. ex. "\tMasters:\n"
  1861. Return Value:
  1862. None.
  1863. --*/
  1864. {
  1865. if ( !pszHeader )
  1866. {
  1867. pszHeader = "";
  1868. }
  1869. DnsPrint_Lock();
  1870. PrintRoutine( pPrintContext,
  1871. "%s%s\n"
  1872. "\t%s = %d (%p)\n",
  1873. pszHeader,
  1874. pszStructureName,
  1875. pszParam1Name,
  1876. dwParam1, dwParam1 );
  1877. if ( pszParam2Name )
  1878. {
  1879. PrintRoutine( pPrintContext,
  1880. "\t%s = %d (%p)\n",
  1881. pszParam2Name,
  1882. dwParam2, dwParam2 );
  1883. }
  1884. DnsPrint_Ip4Array(
  1885. PrintRoutine, pPrintContext,
  1886. pszIpArrayHeader,
  1887. "\t\t",
  1888. pIpArray );
  1889. DnsPrint_Unlock();
  1890. }
  1891. VOID
  1892. DnsPrint_RpcUnion(
  1893. IN PRINT_ROUTINE PrintRoutine,
  1894. IN OUT PPRINT_CONTEXT pPrintContext,
  1895. IN LPSTR pszHeader,
  1896. IN DWORD dwTypeId,
  1897. IN PVOID pData
  1898. )
  1899. {
  1900. PWSTR pstr1 = NULL;
  1901. PWSTR pstr2 = NULL;
  1902. PWSTR pstr3 = NULL;
  1903. PWSTR pstr4 = NULL;
  1904. if ( !pszHeader )
  1905. {
  1906. pszHeader = "";
  1907. }
  1908. if ( !pData &&
  1909. dwTypeId != DNSSRV_TYPEID_NULL &&
  1910. dwTypeId != DNSSRV_TYPEID_DWORD )
  1911. {
  1912. PrintRoutine( pPrintContext,
  1913. "%sNull RPC data ptr of type %d.\n",
  1914. pszHeader,
  1915. dwTypeId );
  1916. return;
  1917. }
  1918. switch ( dwTypeId )
  1919. {
  1920. case DNSSRV_TYPEID_NULL:
  1921. PrintRoutine( pPrintContext,
  1922. "%sPointer: %p\n",
  1923. pszHeader,
  1924. pData );
  1925. break;
  1926. case DNSSRV_TYPEID_DWORD:
  1927. PrintRoutine( pPrintContext,
  1928. "%sDword: %d (%p)\n",
  1929. pszHeader,
  1930. (DWORD)(UINT_PTR)pData, pData );
  1931. break;
  1932. case DNSSRV_TYPEID_LPSTR:
  1933. // note: all TYPEID_LPSTRs i see are UTF8 strings
  1934. pstr1 = getUnicodeForUtf8( pData );
  1935. PrintRoutine( pPrintContext,
  1936. "%sString: %S\n",
  1937. pszHeader,
  1938. pstr1 );
  1939. break;
  1940. case DNSSRV_TYPEID_LPWSTR:
  1941. PrintRoutine( pPrintContext,
  1942. "%sWideString: %S\n",
  1943. pszHeader,
  1944. (PWSTR)pData );
  1945. break;
  1946. case DNSSRV_TYPEID_IPARRAY:
  1947. DnsPrint_Ip4Array(
  1948. PrintRoutine, pPrintContext,
  1949. pszHeader,
  1950. NULL,
  1951. (PIP4_ARRAY) pData );
  1952. break;
  1953. case DNSSRV_TYPEID_BUFFER:
  1954. PrintRoutine( pPrintContext,
  1955. "%sBuffer: length = %d, data ptr = %p\n",
  1956. pszHeader,
  1957. ((PDNS_RPC_BUFFER) pData)->dwLength,
  1958. ((PDNS_RPC_BUFFER) pData)->Buffer );
  1959. break;
  1960. case DNSSRV_TYPEID_SERVER_INFO:
  1961. DnsPrint_RpcServerInfo(
  1962. PrintRoutine, pPrintContext,
  1963. pszHeader,
  1964. (PDNS_RPC_SERVER_INFO) pData );
  1965. break;
  1966. case DNSSRV_TYPEID_STATS:
  1967. DnsPrint_RpcSingleStat(
  1968. PrintRoutine, pPrintContext,
  1969. pszHeader,
  1970. (PDNSSRV_STAT) pData );
  1971. break;
  1972. case DNSSRV_TYPEID_ZONE:
  1973. PrintRoutine( pPrintContext,
  1974. "%s\n",
  1975. pszHeader);
  1976. DnsPrint_RpcZone(
  1977. PrintRoutine, pPrintContext,
  1978. NULL, //print default header
  1979. (PDNS_RPC_ZONE) pData );
  1980. break;
  1981. case DNSSRV_TYPEID_FORWARDERS:
  1982. DnsPrint_RpcIpArrayPlusParameters(
  1983. PrintRoutine, pPrintContext,
  1984. pszHeader,
  1985. "Forwarders Info:",
  1986. "Slave",
  1987. ((PDNS_RPC_FORWARDERS)pData)->fSlave,
  1988. "Timeout",
  1989. ((PDNS_RPC_FORWARDERS)pData)->dwForwardTimeout,
  1990. "\tForwarders:\n",
  1991. ((PDNS_RPC_FORWARDERS)pData)->aipForwarders );
  1992. break;
  1993. case DNSSRV_TYPEID_ZONE_INFO:
  1994. DnsPrint_RpcZoneInfo(
  1995. PrintRoutine, pPrintContext,
  1996. pszHeader,
  1997. (PDNS_RPC_ZONE_INFO) pData );
  1998. break;
  1999. case DNSSRV_TYPEID_ZONE_SECONDARIES:
  2000. DnsPrint_RpcIpArrayPlusParameters(
  2001. PrintRoutine, pPrintContext,
  2002. pszHeader,
  2003. "Zone Secondary Info:",
  2004. "Secure Secondaries",
  2005. ((PDNS_RPC_ZONE_SECONDARIES)pData)->fSecureSecondaries,
  2006. NULL,
  2007. 0,
  2008. "\tSecondaries:\n",
  2009. ((PDNS_RPC_ZONE_SECONDARIES)pData)->aipSecondaries );
  2010. break;
  2011. case DNSSRV_TYPEID_ZONE_TYPE_RESET:
  2012. DnsPrint_RpcIpArrayPlusParameters(
  2013. PrintRoutine, pPrintContext,
  2014. pszHeader,
  2015. "Zone Type Reset Info:",
  2016. "ZoneType",
  2017. ((PDNS_RPC_ZONE_TYPE_RESET)pData)->dwZoneType,
  2018. NULL,
  2019. 0,
  2020. "\tMasters:\n",
  2021. ((PDNS_RPC_ZONE_TYPE_RESET)pData)->aipMasters );
  2022. break;
  2023. case DNSSRV_TYPEID_ZONE_DATABASE:
  2024. pstr1 = getUnicodeForUtf8( ((PDNS_RPC_ZONE_DATABASE)pData)->pszFileName );
  2025. PrintRoutine( pPrintContext,
  2026. "%sZone Dbase Info:\n"
  2027. "\tDS Integrated = %d\n"
  2028. "\tFile Name = %S\n",
  2029. pszHeader,
  2030. ((PDNS_RPC_ZONE_DATABASE)pData)->fDsIntegrated,
  2031. pstr1 // ((PDNS_RPC_ZONE_DATABASE)pData)->pszFileName
  2032. );
  2033. break;
  2034. case DNSSRV_TYPEID_ZONE_CREATE:
  2035. pstr1 = getUnicodeForUtf8( ((PDNS_RPC_ZONE_CREATE_INFO)pData)->pszZoneName );
  2036. pstr2 = getUnicodeForUtf8( ((PDNS_RPC_ZONE_CREATE_INFO)pData)->pszDataFile );
  2037. pstr3 = getUnicodeForUtf8( ((PDNS_RPC_ZONE_CREATE_INFO)pData)->pszAdmin );
  2038. pstr4 = getUnicodeForUtf8( ((PDNS_RPC_ZONE_CREATE_INFO)pData)->pszDpFqdn );
  2039. PrintRoutine( pPrintContext,
  2040. "%sZone Create Info:\n"
  2041. "\tZone Name = %S\n"
  2042. "\tType = %d\n"
  2043. "\tAllow Update = %d\n"
  2044. "\tDS Integrated = %d\n"
  2045. "\tFile Name = %S\n"
  2046. "\tLoad Existing = %d\n"
  2047. "\tFlags = 0x%08X\n"
  2048. "\tAdmin Name = %S\n"
  2049. "\tDirPart Flags = 0x%08X\n"
  2050. "\tDirPart FQDN = %S\n",
  2051. pszHeader,
  2052. pstr1, // ((PDNS_RPC_ZONE_CREATE_INFO)pData)->pszZoneName,
  2053. ((PDNS_RPC_ZONE_CREATE_INFO)pData)->dwZoneType,
  2054. ((PDNS_RPC_ZONE_CREATE_INFO)pData)->fAllowUpdate,
  2055. ((PDNS_RPC_ZONE_CREATE_INFO)pData)->fDsIntegrated,
  2056. pstr2, // ((PDNS_RPC_ZONE_CREATE_INFO)pData)->pszDataFile,
  2057. ((PDNS_RPC_ZONE_CREATE_INFO)pData)->fLoadExisting,
  2058. ((PDNS_RPC_ZONE_CREATE_INFO)pData)->dwFlags,
  2059. pstr3, // ((PDNS_RPC_ZONE_CREATE_INFO)pData)->pszAdmin,
  2060. ((PDNS_RPC_ZONE_CREATE_INFO)pData)->dwDpFlags,
  2061. pstr4 // ((PDNS_RPC_ZONE_CREATE_INFO)pData)->pszDpFqdn
  2062. );
  2063. break;
  2064. case DNSSRV_TYPEID_NAME_AND_PARAM:
  2065. // DCR: WARNING: not sure of name char set in NAME_AND_PARAM type
  2066. pstr1 = getUnicodeForUtf8( ((PDNS_RPC_NAME_AND_PARAM)pData)->pszNodeName );
  2067. PrintRoutine( pPrintContext,
  2068. "%sName and Parameter:\n"
  2069. "\tParam = %d (%p)\n"
  2070. "\tName = %S\n",
  2071. pszHeader,
  2072. ((PDNS_RPC_NAME_AND_PARAM)pData)->dwParam,
  2073. ((PDNS_RPC_NAME_AND_PARAM)pData)->dwParam,
  2074. pstr1 // ((PDNS_RPC_NAME_AND_PARAM)pData)->pszNodeName
  2075. );
  2076. break;
  2077. case DNSSRV_TYPEID_ZONE_LIST:
  2078. DnsPrint_RpcZoneList(
  2079. PrintRoutine, pPrintContext,
  2080. NULL,
  2081. (PDNS_RPC_ZONE_LIST)pData );
  2082. break;
  2083. default:
  2084. PrintRoutine( pPrintContext,
  2085. "%s\n"
  2086. "WARNING: Unknown RPC structure typeid = %d at %p\n",
  2087. pszHeader,
  2088. dwTypeId,
  2089. pData );
  2090. break;
  2091. }
  2092. FREE_HEAP( pstr1 );
  2093. FREE_HEAP( pstr2 );
  2094. FREE_HEAP( pstr3 );
  2095. FREE_HEAP( pstr4 );
  2096. }
  2097. //
  2098. // Stat validity table.
  2099. //
  2100. // Contains match of stat ID and lengths as of this build of RPC client.
  2101. //
  2102. typedef struct StatsValidityTableEntry
  2103. {
  2104. DWORD Id;
  2105. WORD wLength;
  2106. };
  2107. struct StatsValidityTableEntry StatsValidityTable[] =
  2108. {
  2109. DNSSRV_STATID_TIME, sizeof(DNSSRV_TIME_STATS),
  2110. DNSSRV_STATID_QUERY, sizeof(DNSSRV_QUERY_STATS),
  2111. DNSSRV_STATID_QUERY2, sizeof(DNSSRV_QUERY2_STATS),
  2112. DNSSRV_STATID_RECURSE, sizeof(DNSSRV_RECURSE_STATS),
  2113. DNSSRV_STATID_MASTER, sizeof(DNSSRV_MASTER_STATS),
  2114. DNSSRV_STATID_SECONDARY, sizeof(DNSSRV_SECONDARY_STATS),
  2115. DNSSRV_STATID_WINS, sizeof(DNSSRV_WINS_STATS),
  2116. DNSSRV_STATID_NBSTAT, sizeof(DNSSRV_NBSTAT_STATS),
  2117. DNSSRV_STATID_WIRE_UPDATE, sizeof(DNSSRV_UPDATE_STATS),
  2118. DNSSRV_STATID_NONWIRE_UPDATE, sizeof(DNSSRV_UPDATE_STATS),
  2119. DNSSRV_STATID_SKWANSEC, sizeof(DNSSRV_SKWANSEC_STATS),
  2120. DNSSRV_STATID_DS, sizeof(DNSSRV_DS_STATS),
  2121. DNSSRV_STATID_MEMORY, sizeof(DNSSRV_MEMORY_STATS),
  2122. DNSSRV_STATID_PACKET, sizeof(DNSSRV_PACKET_STATS),
  2123. DNSSRV_STATID_DBASE, sizeof(DNSSRV_DBASE_STATS),
  2124. DNSSRV_STATID_RECORD, sizeof(DNSSRV_RECORD_STATS),
  2125. DNSSRV_STATID_TIMEOUT, sizeof(DNSSRV_TIMEOUT_STATS),
  2126. DNSSRV_STATID_ERRORS, sizeof(DNSSRV_ERROR_STATS),
  2127. DNSSRV_STATID_CACHE, sizeof(DNSSRV_CACHE_STATS),
  2128. DNSSRV_STATID_PRIVATE, sizeof(DNSSRV_PRIVATE_STATS),
  2129. 0, 0, // termination
  2130. };
  2131. DNS_STATUS
  2132. DNS_API_FUNCTION
  2133. DnssrvValidityCheckStatistic(
  2134. IN PDNSSRV_STAT pStat
  2135. )
  2136. /*++
  2137. Routine Description:
  2138. Validity check stat struct received from server.
  2139. Arguments:
  2140. pStat -- ptr to stat buffer
  2141. Return Value:
  2142. ERROR_SUCCESS if valid.
  2143. DNS_ERROR_INVALID_TYPE if unknown stat id.
  2144. ERROR_INVALID_DATA if invalid data.
  2145. --*/
  2146. {
  2147. DWORD i;
  2148. DWORD id;
  2149. //
  2150. // find stat ID in table, and verify length match
  2151. //
  2152. i = 0;
  2153. while ( id = StatsValidityTable[i].Id )
  2154. {
  2155. if ( pStat->Header.StatId == id )
  2156. {
  2157. if ( pStat->Header.wLength ==
  2158. StatsValidityTable[i].wLength - sizeof(DNSSRV_STAT_HEADER) )
  2159. {
  2160. return( ERROR_SUCCESS );
  2161. }
  2162. return( ERROR_INVALID_DATA );
  2163. }
  2164. i++;
  2165. }
  2166. return( DNS_ERROR_INVALID_TYPE );
  2167. }
  2168. //
  2169. // Stat printing.
  2170. //
  2171. VOID
  2172. DnsPrint_RpcStatRaw(
  2173. IN PRINT_ROUTINE PrintRoutine,
  2174. IN OUT PPRINT_CONTEXT pPrintContext,
  2175. IN LPSTR pszHeader,
  2176. IN PDNSSRV_STAT pStat,
  2177. IN DNS_STATUS Status
  2178. )
  2179. /*++
  2180. Routine Description:
  2181. Debug print flat stat structure.
  2182. Arguments:
  2183. PrintRoutine -- printf like print routine to use
  2184. pszHeader -- header message to print
  2185. pStat -- ptr to stat buffer
  2186. Status -- status result of validity check; if not ERROR_SUCCESS,
  2187. appropriate error message is printed
  2188. Return Value:
  2189. None.
  2190. --*/
  2191. {
  2192. PDWORD pdword;
  2193. INT i;
  2194. PCHAR pstatEnd;
  2195. DnsPrint_Lock();
  2196. if ( pszHeader )
  2197. {
  2198. PrintRoutine( pPrintContext, pszHeader );
  2199. }
  2200. //
  2201. // validity check stat
  2202. //
  2203. if ( Status != ERROR_SUCCESS )
  2204. {
  2205. if ( Status == DNS_ERROR_INVALID_TYPE )
  2206. {
  2207. PrintRoutine( pPrintContext,
  2208. "Stat ID = %p, is not valid for version of the DNS RPC client.\n",
  2209. pStat->Header.StatId );
  2210. }
  2211. else if ( Status == ERROR_INVALID_DATA )
  2212. {
  2213. PrintRoutine( pPrintContext,
  2214. "Stat data length %d is invalid for stat ID = %p\n",
  2215. pStat->Header.wLength,
  2216. pStat->Header.StatId );
  2217. }
  2218. PrintRoutine( pPrintContext,
  2219. "WARNING: DNS RPC client must match version of server for statistics\n"
  2220. "\tprinting to be formatted appropriately.\n"
  2221. "Update this tool or the DNS server as necessary to match versions.\n" );
  2222. }
  2223. //
  2224. // print stat buffer raw
  2225. //
  2226. PrintRoutine( pPrintContext,
  2227. "Stat ID %p:\n",
  2228. pStat->Header.StatId );
  2229. pdword = (PDWORD) pStat->Buffer;
  2230. pstatEnd = pStat->Header.wLength + (PCHAR)pdword;
  2231. i = 0;
  2232. while ( (PCHAR)pdword < pstatEnd )
  2233. {
  2234. PrintRoutine( pPrintContext,
  2235. " stat[%d] = %10lu\n",
  2236. i,
  2237. *pdword );
  2238. pdword++;
  2239. i++;
  2240. }
  2241. DnsPrint_Unlock();
  2242. }
  2243. VOID
  2244. DnsPrint_RpcStatsBuffer(
  2245. IN PRINT_ROUTINE PrintRoutine,
  2246. IN OUT PPRINT_CONTEXT pPrintContext,
  2247. IN LPSTR pszHeader,
  2248. IN PDNS_RPC_BUFFER pBuffer
  2249. )
  2250. /*++
  2251. Routine Description:
  2252. Debug print stats buffer.
  2253. Arguments:
  2254. pBuffer -- buffer containing stats to print
  2255. Return Value:
  2256. None.
  2257. --*/
  2258. {
  2259. PDNSSRV_STAT pstat;
  2260. PCHAR pch;
  2261. PCHAR pchstop;
  2262. DnsPrint_Lock();
  2263. if ( pszHeader )
  2264. {
  2265. PrintRoutine( pPrintContext, pszHeader );
  2266. }
  2267. pch = pBuffer->Buffer;
  2268. pchstop = pch + pBuffer->dwLength;
  2269. while ( pch < pchstop )
  2270. {
  2271. pstat = (PDNSSRV_STAT) pch;
  2272. pch = (PCHAR) GET_NEXT_STAT_IN_BUFFER( pstat );
  2273. if ( pch > pchstop )
  2274. {
  2275. PrintRoutine( pPrintContext, "ERROR: invalid stats buffer!!!\n" );
  2276. break;
  2277. }
  2278. DnsPrint_RpcSingleStat(
  2279. PrintRoutine, pPrintContext,
  2280. NULL,
  2281. pstat );
  2282. }
  2283. PrintRoutine( pPrintContext, "\n\n" );
  2284. DnsPrint_Unlock();
  2285. }
  2286. VOID
  2287. printStatTypeArray(
  2288. IN PRINT_ROUTINE PrintRoutine,
  2289. IN OUT PPRINT_CONTEXT pPrintContext,
  2290. IN LPSTR pszHeader,
  2291. IN PDWORD pArray
  2292. )
  2293. /*++
  2294. Routine Description:
  2295. Debug print stats type array.
  2296. Arguments:
  2297. Return Value:
  2298. None.
  2299. --*/
  2300. {
  2301. register DWORD i;
  2302. PrintRoutine( pPrintContext,
  2303. "%s\n",
  2304. pszHeader );
  2305. //
  2306. // print counts for all types
  2307. // - skip mixed and unknown bins until end
  2308. //
  2309. for ( i=0; i<STATS_TYPE_MAX; i++ )
  2310. {
  2311. if ( i == STATS_TYPE_MIXED || i == STATS_TYPE_UNKNOWN )
  2312. {
  2313. continue;
  2314. }
  2315. PrintRoutine( pPrintContext,
  2316. " %-10s = %d\n",
  2317. Dns_RecordStringForType( (WORD)i ),
  2318. pArray[i] );
  2319. }
  2320. PrintRoutine( pPrintContext,
  2321. " %-10s = %d\n",
  2322. "Unknown",
  2323. pArray[STATS_TYPE_UNKNOWN] );
  2324. PrintRoutine( pPrintContext,
  2325. " %-10s = %d\n"
  2326. "\n",
  2327. "Mixed",
  2328. pArray[STATS_TYPE_MIXED] );
  2329. }
  2330. VOID
  2331. DnsPrint_RpcSingleStat(
  2332. IN PRINT_ROUTINE PrintRoutine,
  2333. IN OUT PPRINT_CONTEXT pPrintContext,
  2334. IN LPSTR pszHeader,
  2335. IN PDNSSRV_STAT pStat
  2336. )
  2337. /*++
  2338. Routine Description:
  2339. Debug print stats structure.
  2340. Arguments:
  2341. None.
  2342. Return Value:
  2343. None.
  2344. --*/
  2345. {
  2346. DNS_STATUS status;
  2347. //
  2348. // validity check stat
  2349. //
  2350. status = DnssrvValidityCheckStatistic( pStat );
  2351. if ( status != ERROR_SUCCESS )
  2352. {
  2353. DnsPrint_RpcStatRaw(
  2354. PrintRoutine, pPrintContext,
  2355. pszHeader,
  2356. pStat,
  2357. status );
  2358. return;
  2359. }
  2360. DnsPrint_Lock();
  2361. if ( pszHeader )
  2362. {
  2363. PrintRoutine( pPrintContext, pszHeader );
  2364. }
  2365. //
  2366. // switch on stats type
  2367. //
  2368. switch ( pStat->Header.StatId )
  2369. {
  2370. case DNSSRV_STATID_TIME:
  2371. {
  2372. PDNSSRV_TIME_STATS pstat = (PDNSSRV_TIME_STATS)pStat;
  2373. SYSTEMTIME localTime;
  2374. CHAR szdate[30];
  2375. CHAR sztime[20];
  2376. SystemTimeToTzSpecificLocalTime(
  2377. NULL, // use local time
  2378. (PSYSTEMTIME) & pstat->ServerStartTime,
  2379. & localTime );
  2380. GetDateFormat(
  2381. LOCALE_SYSTEM_DEFAULT,
  2382. LOCALE_NOUSEROVERRIDE,
  2383. // (PSYSTEMTIME) &pstat->ServerStartTime,
  2384. & localTime,
  2385. NULL,
  2386. szdate,
  2387. 30 );
  2388. GetTimeFormat(
  2389. LOCALE_SYSTEM_DEFAULT,
  2390. LOCALE_NOUSEROVERRIDE,
  2391. // (PSYSTEMTIME) &pstat->ServerStartTime,
  2392. & localTime,
  2393. NULL,
  2394. sztime,
  2395. 20 );
  2396. PrintRoutine( pPrintContext,
  2397. "\n"
  2398. "DNS Server Time Statistics\n"
  2399. "--------------------------\n"
  2400. "Server start time %s %s\n"
  2401. "Seconds since start %10lu\n",
  2402. szdate,
  2403. sztime,
  2404. pstat->SecondsSinceServerStart
  2405. );
  2406. SystemTimeToTzSpecificLocalTime(
  2407. NULL, // use local time
  2408. (PSYSTEMTIME) & pstat->LastClearTime,
  2409. & localTime );
  2410. GetDateFormat(
  2411. LOCALE_SYSTEM_DEFAULT,
  2412. LOCALE_NOUSEROVERRIDE,
  2413. // (PSYSTEMTIME) &pstat->LastClearTime,
  2414. & localTime,
  2415. NULL,
  2416. szdate,
  2417. 30 );
  2418. GetTimeFormat(
  2419. LOCALE_SYSTEM_DEFAULT,
  2420. LOCALE_NOUSEROVERRIDE,
  2421. // (PSYSTEMTIME) &pstat->LastClearTime,
  2422. & localTime,
  2423. NULL,
  2424. sztime,
  2425. 20 );
  2426. PrintRoutine( pPrintContext,
  2427. "Stats last cleared %s %s\n"
  2428. "Seconds since clear %10lu\n",
  2429. szdate,
  2430. sztime,
  2431. pstat->SecondsSinceLastClear
  2432. );
  2433. break;
  2434. }
  2435. case DNSSRV_STATID_QUERY:
  2436. {
  2437. PDNSSRV_QUERY_STATS pstat = (PDNSSRV_QUERY_STATS)pStat;
  2438. PrintRoutine( pPrintContext,
  2439. "\n"
  2440. "Queries and Responses:\n"
  2441. "----------------------\n"
  2442. "Total:\n"
  2443. " Queries Received = %10lu\n"
  2444. " Responses Sent = %10lu\n"
  2445. "UDP:\n"
  2446. " Queries Recvd = %10lu\n"
  2447. " Responses Sent = %10lu\n"
  2448. " Queries Sent = %10lu\n"
  2449. " Responses Recvd = %10lu\n"
  2450. "TCP:\n"
  2451. " Client Connects = %10lu\n"
  2452. " Queries Recvd = %10lu\n"
  2453. " Responses Sent = %10lu\n"
  2454. " Queries Sent = %10lu\n"
  2455. " Responses Recvd = %10lu\n",
  2456. pstat->UdpQueries + pstat->TcpQueries,
  2457. pstat->UdpResponses + pstat->TcpResponses,
  2458. pstat->UdpQueries,
  2459. pstat->UdpResponses,
  2460. pstat->UdpQueriesSent,
  2461. pstat->UdpResponsesReceived,
  2462. pstat->TcpClientConnections,
  2463. pstat->TcpQueries,
  2464. pstat->TcpResponses,
  2465. pstat->TcpQueriesSent,
  2466. pstat->TcpResponsesReceived
  2467. );
  2468. break;
  2469. }
  2470. case DNSSRV_STATID_QUERY2:
  2471. {
  2472. PDNSSRV_QUERY2_STATS pstat = (PDNSSRV_QUERY2_STATS)pStat;
  2473. PrintRoutine( pPrintContext,
  2474. "\n"
  2475. "Queries:\n"
  2476. "--------\n"
  2477. "Total = %10lu\n"
  2478. " Notify = %10lu\n"
  2479. " Update = %10lu\n"
  2480. " TKeyNego = %10lu\n"
  2481. " Standard = %10lu\n"
  2482. " A = %10lu\n"
  2483. " NS = %10lu\n"
  2484. " SOA = %10lu\n"
  2485. " MX = %10lu\n"
  2486. " PTR = %10lu\n"
  2487. " SRV = %10lu\n"
  2488. " ALL = %10lu\n"
  2489. " IXFR = %10lu\n"
  2490. " AXFR = %10lu\n"
  2491. " OTHER = %10lu\n",
  2492. pstat->TotalQueries,
  2493. pstat->Notify,
  2494. pstat->Update,
  2495. pstat->TKeyNego,
  2496. pstat->Standard,
  2497. pstat->TypeA,
  2498. pstat->TypeNs,
  2499. pstat->TypeSoa,
  2500. pstat->TypeMx,
  2501. pstat->TypePtr,
  2502. pstat->TypeSrv,
  2503. pstat->TypeAll,
  2504. pstat->TypeIxfr,
  2505. pstat->TypeAxfr,
  2506. pstat->TypeOther
  2507. );
  2508. break;
  2509. }
  2510. case DNSSRV_STATID_RECURSE:
  2511. {
  2512. PDNSSRV_RECURSE_STATS pstat = (PDNSSRV_RECURSE_STATS)pStat;
  2513. PrintRoutine( pPrintContext,
  2514. "\n"
  2515. "Recursion:\n"
  2516. "----------\n"
  2517. "Query:\n"
  2518. " Queries Recursed = %10lu\n"
  2519. " Original Questions = %10lu\n"
  2520. " Additional Question = %10lu\n"
  2521. " Total Questions = %10lu\n"
  2522. " Retries = %10lu\n"
  2523. " Total Passes = %10lu\n"
  2524. " ToForwarders = %10lu\n"
  2525. " Sends = %10lu\n",
  2526. pstat->QueriesRecursed,
  2527. pstat->OriginalQuestionRecursed,
  2528. pstat->AdditionalRecursed,
  2529. pstat->TotalQuestionsRecursed,
  2530. pstat->Retries,
  2531. pstat->LookupPasses,
  2532. pstat->Forwards,
  2533. pstat->Sends );
  2534. PrintRoutine( pPrintContext,
  2535. "\n"
  2536. "Response:\n"
  2537. " TotalResponses = %10lu\n"
  2538. " Unmatched = %10lu\n"
  2539. " Mismatched = %10lu\n"
  2540. " FromForwarder = %10lu\n"
  2541. " Authoritative = %10lu\n"
  2542. " NotAuthoritative = %10lu\n"
  2543. " Answer = %10lu\n"
  2544. " Empty = %10lu\n"
  2545. " NameError = %10lu\n"
  2546. " Rcode = %10lu\n"
  2547. " Delegation = %10lu\n"
  2548. " NonZoneData = %10lu\n"
  2549. " Unsecure = %10lu\n"
  2550. " BadPacket = %10lu\n"
  2551. "Process Response:\n"
  2552. " Forward Response = %10lu\n"
  2553. " Continue Recursion = %10lu\n"
  2554. " Continue Lookup = %10lu\n"
  2555. " Next Lookup = %10lu\n",
  2556. pstat->Responses,
  2557. pstat->ResponseUnmatched,
  2558. pstat->ResponseMismatched,
  2559. pstat->ResponseFromForwarder,
  2560. pstat->ResponseAuthoritative,
  2561. pstat->ResponseNotAuth,
  2562. pstat->ResponseAnswer,
  2563. pstat->ResponseEmpty,
  2564. pstat->ResponseNameError,
  2565. pstat->ResponseRcode,
  2566. pstat->ResponseDelegation,
  2567. pstat->ResponseNonZoneData,
  2568. pstat->ResponseUnsecure,
  2569. pstat->ResponseBadPacket,
  2570. pstat->SendResponseDirect,
  2571. pstat->ContinueCurrentRecursion,
  2572. pstat->ContinueCurrentLookup,
  2573. pstat->ContinueNextLookup );
  2574. PrintRoutine( pPrintContext,
  2575. "\n"
  2576. "Timeouts:\n"
  2577. " Send Timeouts = %10lu\n"
  2578. " Final Queued = %10lu\n"
  2579. " Final Expired = %10lu\n"
  2580. "\n"
  2581. "Failures:\n"
  2582. " Recurse Failures = %10lu\n"
  2583. " Into Authority = %10lu\n"
  2584. " Previous Zone = %10lu\n"
  2585. " Retry Limit = %10lu\n"
  2586. " Partial (HaveAnswer) = %10lu\n"
  2587. " Cache Update = %10lu\n"
  2588. " Server Failure Resp = %10lu\n"
  2589. " Total Failures = %10lu\n",
  2590. pstat->PacketTimeout,
  2591. pstat->FinalTimeoutQueued,
  2592. pstat->FinalTimeoutExpired,
  2593. pstat->RecursePassFailure,
  2594. pstat->FailureReachAuthority,
  2595. pstat->FailureReachPreviousResponse,
  2596. pstat->FailureRetryCount,
  2597. pstat->PartialFailure,
  2598. pstat->CacheUpdateFailure,
  2599. pstat->ServerFailure,
  2600. pstat->Failures
  2601. );
  2602. PrintRoutine( pPrintContext,
  2603. "\n"
  2604. "TCP Recursion:\n"
  2605. " Try = %10lu\n"
  2606. " Query = %10lu\n"
  2607. " Response = %10lu\n"
  2608. " Disconnects = %10lu\n"
  2609. "\n"
  2610. "Cache Update Queries:\n"
  2611. " Query = %10lu\n"
  2612. " Response = %10lu\n"
  2613. " Retry = %10lu\n"
  2614. " Free = %10lu\n"
  2615. " Root NS Query = %10lu\n"
  2616. " Root NS Response = %10lu\n"
  2617. " Suspended Query = %10lu\n"
  2618. " Resume Suspended = %10lu\n"
  2619. "\n",
  2620. pstat->TcpTry,
  2621. pstat->TcpQuery,
  2622. pstat->TcpResponse,
  2623. pstat->TcpDisconnect,
  2624. pstat->CacheUpdateAlloc,
  2625. pstat->CacheUpdateResponse,
  2626. pstat->CacheUpdateRetry,
  2627. pstat->CacheUpdateFree,
  2628. pstat->RootNsQuery,
  2629. pstat->RootNsResponse,
  2630. pstat->SuspendedQuery,
  2631. pstat->ResumeSuspendedQuery );
  2632. PrintRoutine( pPrintContext,
  2633. "\n"
  2634. "Other:\n"
  2635. " Discarded duplicates = %10lu\n"
  2636. "\n",
  2637. pstat->DiscardedDuplicateQueries );
  2638. break;
  2639. }
  2640. case DNSSRV_STATID_MASTER:
  2641. {
  2642. PDNSSRV_MASTER_STATS pstat = (PDNSSRV_MASTER_STATS)pStat;
  2643. PrintRoutine( pPrintContext,
  2644. "\n"
  2645. "Master Stats:\n"
  2646. "-------------\n"
  2647. "Notifies Sent = %10lu\n"
  2648. "\n"
  2649. "Requests = %10lu\n"
  2650. " NameError = %10lu\n"
  2651. " FormError = %10lu\n"
  2652. " Refused = %10lu\n"
  2653. " AxfrLimit = %10lu\n"
  2654. " Security = %10lu\n"
  2655. " Shutdown = %10lu\n"
  2656. " ZoneLocked = %10lu\n"
  2657. " ServerFailure = %10lu\n"
  2658. " Failure = %10lu\n"
  2659. " Success = %10lu\n"
  2660. "\n"
  2661. "AXFR Request = %10lu\n"
  2662. " Success = %10lu\n"
  2663. " In IXFR = %10lu\n"
  2664. "\n"
  2665. "IXFR Request = %10lu\n"
  2666. " Success Update = %10lu\n"
  2667. " UDP Request = %10lu\n"
  2668. " Success = %10lu\n"
  2669. " Force TCP = %10lu\n"
  2670. " Force Full = %10lu\n"
  2671. " TCP Request = %10lu\n"
  2672. " Success = %10lu\n"
  2673. " Do Full = %10lu\n"
  2674. "\n",
  2675. pstat->NotifySent,
  2676. pstat->Request,
  2677. pstat->NameError,
  2678. pstat->FormError,
  2679. pstat->Refused,
  2680. pstat->AxfrLimit,
  2681. pstat->RefuseSecurity,
  2682. pstat->RefuseShutdown,
  2683. pstat->RefuseZoneLocked,
  2684. pstat->RefuseServerFailure,
  2685. pstat->Failure,
  2686. (pstat->AxfrSuccess + pstat->IxfrUpdateSuccess),
  2687. pstat->AxfrRequest,
  2688. pstat->AxfrSuccess,
  2689. pstat->IxfrAxfr,
  2690. pstat->IxfrRequest,
  2691. pstat->IxfrUpdateSuccess,
  2692. pstat->IxfrUdpRequest,
  2693. pstat->IxfrUdpSuccess,
  2694. pstat->IxfrUdpForceTcp,
  2695. pstat->IxfrUdpForceAxfr,
  2696. pstat->IxfrTcpRequest,
  2697. pstat->IxfrTcpSuccess,
  2698. pstat->IxfrAxfr
  2699. );
  2700. break;
  2701. }
  2702. case DNSSRV_STATID_SECONDARY:
  2703. {
  2704. PDNSSRV_SECONDARY_STATS pstat = (PDNSSRV_SECONDARY_STATS)pStat;
  2705. PrintRoutine( pPrintContext,
  2706. "\n"
  2707. "Secondary Stats:\n"
  2708. "----------------\n"
  2709. "NOTIFY:\n"
  2710. " Received = %10lu\n"
  2711. " Invalid = %10lu\n"
  2712. " Primary = %10lu\n"
  2713. " No Version = %10lu\n"
  2714. " New Version = %10lu\n"
  2715. " Current Version = %10lu\n"
  2716. " Old Version = %10lu\n"
  2717. " Master Unknown = %10lu\n"
  2718. "\n"
  2719. "SOA Query:\n"
  2720. " Request = %10lu\n"
  2721. " Response = %10lu\n"
  2722. " Invalid = %10lu\n"
  2723. " NameError = %10lu\n"
  2724. "\n"
  2725. "AXFR:\n"
  2726. " AXFR Request = %10lu\n"
  2727. " AXFR in IXFR = %10lu\n"
  2728. " Response = %10lu\n"
  2729. " Success = %10lu\n"
  2730. " Refused = %10lu\n"
  2731. " Invalid = %10lu\n"
  2732. "\n"
  2733. "Stub zone AXFR:\n"
  2734. " Stub AXFR Request = %10lu\n"
  2735. " Response = %10lu\n"
  2736. " Success = %10lu\n"
  2737. " Refused = %10lu\n"
  2738. " Invalid = %10lu\n"
  2739. "\n"
  2740. "IXFR UDP:\n"
  2741. " Request = %10lu\n"
  2742. " Response = %10lu\n"
  2743. " Success = %10lu\n"
  2744. " UseTcp = %10lu\n"
  2745. " UseAxfr = %10lu\n"
  2746. " New Primary = %10lu\n"
  2747. " Refused = %10lu\n"
  2748. " Wrong Server = %10lu\n"
  2749. " FormError = %10lu\n"
  2750. " Invalid = %10lu\n"
  2751. "\n"
  2752. "IXFR TCP:\n"
  2753. " Request = %10lu\n"
  2754. " Response = %10lu\n"
  2755. " Success = %10lu\n"
  2756. " AXFR = %10lu\n"
  2757. " FormError = %10lu\n"
  2758. " Refused = %10lu\n"
  2759. " Invalid = %10lu\n"
  2760. "\n",
  2761. pstat->NotifyReceived,
  2762. pstat->NotifyInvalid,
  2763. pstat->NotifyPrimary,
  2764. pstat->NotifyNoVersion,
  2765. pstat->NotifyNewVersion,
  2766. pstat->NotifyCurrentVersion,
  2767. pstat->NotifyOldVersion,
  2768. pstat->NotifyMasterUnknown,
  2769. pstat->SoaRequest,
  2770. pstat->SoaResponse,
  2771. pstat->SoaResponseInvalid,
  2772. pstat->SoaResponseNameError,
  2773. pstat->AxfrRequest,
  2774. pstat->IxfrTcpAxfr,
  2775. pstat->AxfrResponse,
  2776. pstat->AxfrSuccess,
  2777. pstat->AxfrRefused,
  2778. pstat->AxfrInvalid,
  2779. pstat->StubAxfrRequest,
  2780. pstat->StubAxfrResponse,
  2781. pstat->StubAxfrSuccess,
  2782. pstat->StubAxfrRefused,
  2783. pstat->StubAxfrInvalid,
  2784. pstat->IxfrUdpRequest,
  2785. pstat->IxfrUdpResponse,
  2786. pstat->IxfrUdpSuccess,
  2787. pstat->IxfrUdpUseTcp,
  2788. pstat->IxfrUdpUseAxfr,
  2789. pstat->IxfrUdpNewPrimary,
  2790. pstat->IxfrUdpRefused,
  2791. pstat->IxfrUdpWrongServer,
  2792. pstat->IxfrUdpFormerr,
  2793. pstat->IxfrUdpInvalid,
  2794. pstat->IxfrTcpRequest,
  2795. pstat->IxfrTcpResponse,
  2796. pstat->IxfrTcpSuccess,
  2797. pstat->IxfrTcpAxfr,
  2798. pstat->IxfrTcpFormerr,
  2799. pstat->IxfrTcpRefused,
  2800. pstat->IxfrTcpInvalid
  2801. );
  2802. break;
  2803. }
  2804. case DNSSRV_STATID_WINS:
  2805. {
  2806. PDNSSRV_WINS_STATS pstat = (PDNSSRV_WINS_STATS)pStat;
  2807. PrintRoutine( pPrintContext,
  2808. "\n"
  2809. "WINS Referrals:\n"
  2810. "---------------\n"
  2811. "Forward:\n"
  2812. " Lookups = %10lu\n"
  2813. " Responses = %10lu\n"
  2814. "Reverse:\n"
  2815. " Lookups = %10lu\n"
  2816. " Responses = %10lu\n",
  2817. pstat->WinsLookups,
  2818. pstat->WinsResponses,
  2819. pstat->WinsReverseLookups,
  2820. pstat->WinsReverseResponses
  2821. );
  2822. break;
  2823. }
  2824. case DNSSRV_STATID_NBSTAT:
  2825. {
  2826. PDNSSRV_NBSTAT_STATS pstat = (PDNSSRV_NBSTAT_STATS)pStat;
  2827. PrintRoutine( pPrintContext,
  2828. "\n"
  2829. "Nbstat Memory Usage:\n"
  2830. "--------------------\n"
  2831. "Nbstat Buffers:\n"
  2832. " Alloc = %10lu\n"
  2833. " Free = %10lu\n"
  2834. " NetAllocs = %10lu\n"
  2835. " Memory = %10lu\n"
  2836. " Used = %10lu\n"
  2837. " Returned = %10lu\n"
  2838. " InUse = %10lu\n"
  2839. " InFreeList = %10lu\n"
  2840. "\n",
  2841. pstat->NbstatAlloc,
  2842. pstat->NbstatFree,
  2843. pstat->NbstatNetAllocs,
  2844. pstat->NbstatMemory,
  2845. pstat->NbstatUsed,
  2846. pstat->NbstatReturn,
  2847. pstat->NbstatInUse,
  2848. pstat->NbstatInFreeList
  2849. );
  2850. break;
  2851. }
  2852. case DNSSRV_STATID_WIRE_UPDATE:
  2853. case DNSSRV_STATID_NONWIRE_UPDATE:
  2854. {
  2855. PDNSSRV_UPDATE_STATS pstat = (PDNSSRV_UPDATE_STATS)pStat;
  2856. PrintRoutine( pPrintContext,
  2857. "\n"
  2858. "%s:\n"
  2859. "--------------------------\n"
  2860. "Updates Received = %10lu\n"
  2861. " Forwarded = %10lu\n"
  2862. " Empty (PreCon Only) = %10lu\n"
  2863. " NoOps (Dups) = %10lu\n"
  2864. " Rejected = %10lu\n"
  2865. " Completed = %10lu\n"
  2866. " Timed Out = %10lu\n"
  2867. " In Queue = %10lu\n"
  2868. "\n"
  2869. "Updates Rejected = %10lu\n"
  2870. " FormError = %10lu\n"
  2871. " NameError = %10lu\n"
  2872. " NotImpl = %10lu (Non-Update Zone)\n"
  2873. " Refused = %10lu\n"
  2874. " NonSecure Packet = %10lu\n"
  2875. " AccessDenied = %10lu\n"
  2876. " YxDomain = %10lu\n"
  2877. " YxRRSet = %10lu\n"
  2878. " NxRRSet = %10lu\n"
  2879. " NotAuth = %10lu\n"
  2880. " NotZone = %10lu\n"
  2881. "\n"
  2882. #if 0 // unused counters
  2883. "Update Collisions = %10lu\n"
  2884. " Read = %10lu\n"
  2885. " Write = %10lu\n"
  2886. " In LDAP = %10lu\n"
  2887. "\n"
  2888. #endif
  2889. "Queue\n"
  2890. " Queued = %10lu\n"
  2891. " Retried = %10lu\n"
  2892. " Timeout = %10lu\n"
  2893. " In Queue = %10lu\n"
  2894. "\n"
  2895. "Secure Update\n"
  2896. " Success = %10lu\n"
  2897. " Continue = %10lu\n"
  2898. " Failure = %10lu\n"
  2899. " DS Write Failure = %10lu\n"
  2900. "\n"
  2901. "Update Forwarding\n"
  2902. " Forwards = %10lu\n"
  2903. " TCP Forwards = %10lu\n"
  2904. " Responses = %10lu\n"
  2905. " Timed Out = %10lu\n"
  2906. " In Queue = %10lu\n"
  2907. "\n",
  2908. pStat->Header.StatId == DNSSRV_STATID_WIRE_UPDATE ?
  2909. "Packet Dynamic Update" :
  2910. "Internal Dynamic Update",
  2911. pstat->Received,
  2912. pstat->Forwards,
  2913. pstat->Empty,
  2914. pstat->NoOps,
  2915. pstat->Rejected,
  2916. pstat->Completed,
  2917. pstat->Timeout,
  2918. pstat->InQueue,
  2919. pstat->Rejected,
  2920. pstat->FormErr,
  2921. pstat->NxDomain,
  2922. pstat->NotImpl,
  2923. pstat->Refused,
  2924. pstat->RefusedNonSecure,
  2925. pstat->RefusedAccessDenied,
  2926. pstat->YxDomain,
  2927. pstat->YxRrset,
  2928. pstat->NxRrset,
  2929. pstat->NotAuth,
  2930. pstat->NotZone,
  2931. #if 0 // unused counters
  2932. pstat->Collisions,
  2933. pstat->CollisionsRead,
  2934. pstat->CollisionsWrite,
  2935. pstat->CollisionsDsWrite,
  2936. #endif
  2937. pstat->Queued,
  2938. pstat->Retry,
  2939. pstat->Timeout,
  2940. pstat->InQueue,
  2941. pstat->SecureSuccess,
  2942. pstat->SecureContinue,
  2943. pstat->SecureFailure,
  2944. pstat->SecureDsWriteFailure,
  2945. pstat->Forwards,
  2946. pstat->TcpForwards,
  2947. pstat->ForwardResponses,
  2948. pstat->ForwardTimeouts,
  2949. pstat->ForwardInQueue
  2950. );
  2951. printStatTypeArray(
  2952. PrintRoutine, pPrintContext,
  2953. "Update Types:",
  2954. pstat->UpdateType );
  2955. break;
  2956. }
  2957. case DNSSRV_STATID_DS:
  2958. {
  2959. PDNSSRV_DS_STATS pstat = (PDNSSRV_DS_STATS)pStat;
  2960. PrintRoutine( pPrintContext,
  2961. "\n"
  2962. "DS Integration:\n"
  2963. "---------------\n"
  2964. "DS Reads:\n"
  2965. " Nodes Read Total = %10lu\n"
  2966. " Records Read Total = %10lu\n"
  2967. " Nodes Loaded = %10lu\n"
  2968. " Records Loaded = %10lu\n"
  2969. "\n"
  2970. " Update Searches = %10lu\n"
  2971. " Update Nodes Read = %10lu\n"
  2972. " Update Records Read = %10lu\n"
  2973. "\n"
  2974. "DS Writes:\n"
  2975. " Nodes Added = %10lu\n"
  2976. " Nodes Modified = %10lu\n"
  2977. " Nodes Tombstoned = %10lu\n"
  2978. " Nodes Final Delete = %10lu\n"
  2979. " Node Write Suppressed = %10lu\n"
  2980. " RR Sets Added = %10lu\n"
  2981. " RR Sets Replaced = %10lu\n"
  2982. " Serial Writes = %10lu\n"
  2983. "\n"
  2984. " Update Lists = %10lu\n"
  2985. " Update Nodes = %10lu\n"
  2986. " Suppressed = %10lu\n"
  2987. " Writes = %10lu\n"
  2988. " Tombstones = %10lu\n"
  2989. " Write causes:\n"
  2990. " Record Change = %10lu\n"
  2991. " Aging Refresh = %10lu\n"
  2992. " Aging On = %10lu\n"
  2993. " Aging Off = %10lu\n"
  2994. " Write sources:\n"
  2995. " Packet = %10lu\n"
  2996. " Precon Only = %10lu\n"
  2997. " Admin = %10lu\n"
  2998. " Auto Config = %10lu\n"
  2999. " Scavenge = %10lu\n",
  3000. pstat->DsTotalNodesRead,
  3001. pstat->DsTotalRecordsRead,
  3002. pstat->DsNodesLoaded,
  3003. pstat->DsRecordsLoaded,
  3004. pstat->DsUpdateSearches,
  3005. pstat->DsUpdateNodesRead,
  3006. pstat->DsUpdateRecordsRead,
  3007. pstat->DsNodesAdded,
  3008. pstat->DsNodesModified,
  3009. pstat->DsNodesTombstoned,
  3010. pstat->DsNodesDeleted,
  3011. pstat->DsWriteSuppressed,
  3012. pstat->DsRecordsAdded,
  3013. pstat->DsRecordsReplaced,
  3014. pstat->DsSerialWrites,
  3015. pstat->UpdateLists,
  3016. pstat->UpdateNodes,
  3017. pstat->UpdateSuppressed,
  3018. pstat->UpdateWrites,
  3019. pstat->UpdateTombstones,
  3020. pstat->UpdateRecordChange,
  3021. pstat->UpdateAgingRefresh,
  3022. pstat->UpdateAgingOn,
  3023. pstat->UpdateAgingOff,
  3024. pstat->UpdatePacket,
  3025. pstat->UpdatePacketPrecon,
  3026. pstat->UpdateAdmin,
  3027. pstat->UpdateAutoConfig,
  3028. pstat->UpdateScavenge
  3029. );
  3030. PrintRoutine( pPrintContext,
  3031. "\n"
  3032. "Tombstones:\n"
  3033. " Written = %10lu\n"
  3034. " Read = %10lu\n"
  3035. " Deleted = %10lu\n"
  3036. "\n"
  3037. "Write Performance:\n"
  3038. " Total = %10lu\n"
  3039. " Total Time = %10lu\n"
  3040. " Average = %10lu\n"
  3041. " < 10ms = %10lu\n"
  3042. " < 100ms = %10lu\n"
  3043. " < 1s = %10lu\n"
  3044. " < 10s = %10lu\n"
  3045. " < 100s = %10lu\n"
  3046. " > 100s = %10lu\n"
  3047. " Max = %10lu\n"
  3048. "Search Performance:\n"
  3049. " Total (ms) = %10lu\n"
  3050. "\n"
  3051. "Failures:\n"
  3052. " FailedDeleteDsEntries = %10lu\n"
  3053. " FailedReadRecords = %10lu\n"
  3054. " FailedLdapModify = %10lu\n"
  3055. " FailedLdapAdd = %10lu\n"
  3056. "\n"
  3057. "Polling:\n"
  3058. " PollingPassesWithErrors = %10lu\n"
  3059. "\n"
  3060. "LDAP:\n"
  3061. " Reconnects = %10lu\n"
  3062. "\n",
  3063. pstat->DsNodesTombstoned,
  3064. pstat->DsTombstonesRead,
  3065. pstat->DsNodesDeleted,
  3066. pstat->LdapTimedWrites,
  3067. pstat->LdapWriteTimeTotal,
  3068. pstat->LdapWriteAverage,
  3069. pstat->LdapWriteBucket0,
  3070. pstat->LdapWriteBucket1,
  3071. pstat->LdapWriteBucket2,
  3072. pstat->LdapWriteBucket3,
  3073. pstat->LdapWriteBucket4,
  3074. pstat->LdapWriteBucket5,
  3075. pstat->LdapWriteMax,
  3076. pstat->LdapSearchTime,
  3077. pstat->FailedDeleteDsEntries,
  3078. pstat->FailedReadRecords,
  3079. pstat->FailedLdapModify,
  3080. pstat->FailedLdapAdd,
  3081. pstat->PollingPassesWithDsErrors,
  3082. pstat->LdapReconnects );
  3083. printStatTypeArray(
  3084. PrintRoutine, pPrintContext,
  3085. "DS Write Types:",
  3086. pstat->DsWriteType );
  3087. break;
  3088. }
  3089. case DNSSRV_STATID_SKWANSEC:
  3090. {
  3091. PDNSSRV_SKWANSEC_STATS pstat = (PDNSSRV_SKWANSEC_STATS)pStat;
  3092. PrintRoutine( pPrintContext,
  3093. "\n"
  3094. "Security Stats:\n"
  3095. "---------------\n"
  3096. "\n"
  3097. "Security Context:\n"
  3098. " Create = %10lu\n"
  3099. " Free = %10lu\n"
  3100. " Timeout = %10lu\n"
  3101. " Queue Length = %10lu\n"
  3102. " Queued = %10lu\n"
  3103. " In Nego = %10lu\n"
  3104. " Nego Complete = %10lu\n"
  3105. " DeQueued = %10lu\n"
  3106. "\n"
  3107. "Security Packet Contexts:\n"
  3108. " Alloc = %10lu\n"
  3109. " Free = %10lu\n"
  3110. "\n"
  3111. "TKEY:\n"
  3112. " Invalid = %10lu\n"
  3113. " BadTime = %10lu\n"
  3114. "\n"
  3115. "TSIG:\n"
  3116. " Formerr = %10lu\n"
  3117. " Echo = %10lu\n"
  3118. " BadKey = %10lu\n"
  3119. " Verify Success = %10lu\n"
  3120. " Verify Failed = %10lu\n"
  3121. "\n",
  3122. pstat->SecContextCreate,
  3123. pstat->SecContextFree,
  3124. pstat->SecContextTimeout,
  3125. pstat->SecContextQueueLength,
  3126. pstat->SecContextQueue,
  3127. pstat->SecContextQueueInNego,
  3128. pstat->SecContextQueueNegoComplete,
  3129. pstat->SecContextDequeue,
  3130. pstat->SecPackAlloc,
  3131. pstat->SecPackFree,
  3132. pstat->SecTkeyInvalid,
  3133. pstat->SecTkeyBadTime,
  3134. pstat->SecTsigFormerr,
  3135. pstat->SecTsigEcho,
  3136. pstat->SecTsigBadKey,
  3137. pstat->SecTsigVerifySuccess,
  3138. pstat->SecTsigVerifyFailed
  3139. );
  3140. break;
  3141. }
  3142. case DNSSRV_STATID_MEMORY:
  3143. {
  3144. PDNSSRV_MEMORY_STATS pstat = (PDNSSRV_MEMORY_STATS) pStat;
  3145. DWORD i;
  3146. LPSTR * pnameArray;
  3147. DWORD count;
  3148. pnameArray = MemTagStrings;
  3149. count = MEMTAG_COUNT;
  3150. PrintRoutine( pPrintContext,
  3151. "\n"
  3152. "Memory Stats:\n"
  3153. "-------------\n"
  3154. "Memory:\n"
  3155. " Total Memory = %10lu\n"
  3156. " Alloc Count = %10lu\n"
  3157. " Free Count = %10lu\n"
  3158. "\n"
  3159. "Standard Allocs:\n"
  3160. " Used = %10lu\n"
  3161. " Returned = %10lu\n"
  3162. " InUse = %10lu\n"
  3163. " Memory = %10lu\n"
  3164. "\n"
  3165. "Standard To Heap:\n"
  3166. " Alloc = %10lu\n"
  3167. " Free = %10lu\n"
  3168. " InUse = %10lu\n"
  3169. " Memory = %10lu\n"
  3170. "\n"
  3171. "Standard Blocks:\n"
  3172. " Alloc = %10lu\n"
  3173. " Used = %10lu\n"
  3174. " Returned = %10lu\n"
  3175. " InUse = %10lu\n"
  3176. " FreeList = %10lu\n"
  3177. " FreeList Memory = %10lu\n"
  3178. " Total Memory = %10lu\n"
  3179. "\n"
  3180. "Tagged Allocations:\n",
  3181. pstat->Memory,
  3182. pstat->Alloc,
  3183. pstat->Free,
  3184. pstat->StdUsed,
  3185. pstat->StdReturn,
  3186. pstat->StdInUse,
  3187. pstat->StdMemory,
  3188. pstat->StdToHeapAlloc,
  3189. pstat->StdToHeapFree,
  3190. pstat->StdToHeapInUse,
  3191. pstat->StdToHeapMemory,
  3192. pstat->StdBlockAlloc,
  3193. pstat->StdBlockUsed,
  3194. pstat->StdBlockReturn,
  3195. pstat->StdBlockInUse,
  3196. pstat->StdBlockFreeList,
  3197. pstat->StdBlockFreeListMemory,
  3198. pstat->StdBlockMemory
  3199. );
  3200. for ( i=0; i<count; i++ )
  3201. {
  3202. PrintRoutine( pPrintContext,
  3203. " %s\n"
  3204. " Alloc = %10lu\n"
  3205. " Free = %10lu\n"
  3206. " InUse = %10lu\n"
  3207. " Mem = %10lu\n",
  3208. pnameArray[ i ],
  3209. pstat->MemTags[ i ].Alloc,
  3210. pstat->MemTags[ i ].Free,
  3211. pstat->MemTags[ i ].Alloc - pstat->MemTags[i].Free,
  3212. pstat->MemTags[ i ].Memory );
  3213. }
  3214. break;
  3215. }
  3216. case DNSSRV_STATID_DBASE:
  3217. {
  3218. PDNSSRV_DBASE_STATS pstat = (PDNSSRV_DBASE_STATS)pStat;
  3219. PrintRoutine( pPrintContext,
  3220. "\n"
  3221. "Database Nodes:\n"
  3222. "---------------\n"
  3223. "Nodes:\n"
  3224. " Used = %10lu\n"
  3225. " Returned = %10lu\n"
  3226. " InUse = %10lu\n"
  3227. " Memory = %10lu\n"
  3228. "\n",
  3229. pstat->NodeUsed,
  3230. pstat->NodeReturn,
  3231. pstat->NodeInUse,
  3232. pstat->NodeMemory
  3233. );
  3234. break;
  3235. }
  3236. case DNSSRV_STATID_RECORD:
  3237. {
  3238. PDNSSRV_RECORD_STATS pstat = (PDNSSRV_RECORD_STATS)pStat;
  3239. PrintRoutine( pPrintContext,
  3240. "\n"
  3241. "Records:\n"
  3242. "--------\n"
  3243. "Flow:\n"
  3244. " Used = %10lu\n"
  3245. " Returned = %10lu\n"
  3246. " InUse = %10lu\n"
  3247. " SlowFree Queued = %10lu\n"
  3248. " SlowFree Completed = %10lu\n"
  3249. " Memory = %10lu\n"
  3250. "\n"
  3251. "Caching:\n"
  3252. " Total = %10lu\n"
  3253. " Timeouts = %10lu\n"
  3254. " In Use = %10lu\n"
  3255. "\n",
  3256. pstat->Used,
  3257. pstat->Return,
  3258. pstat->InUse,
  3259. pstat->SlowFreeQueued,
  3260. pstat->SlowFreeFinished,
  3261. pstat->Memory,
  3262. pstat->CacheTotal,
  3263. pstat->CacheTimeouts,
  3264. pstat->CacheCurrent );
  3265. break;
  3266. }
  3267. case DNSSRV_STATID_PACKET:
  3268. {
  3269. PDNSSRV_PACKET_STATS pstat = (PDNSSRV_PACKET_STATS)pStat;
  3270. PrintRoutine( pPrintContext,
  3271. "\n"
  3272. "Packet Memory Usage:\n"
  3273. "--------------------\n"
  3274. "UDP Messages:\n"
  3275. " Alloc = %10lu\n"
  3276. " Free = %10lu\n"
  3277. " NetAllocs = %10lu\n"
  3278. " Memory = %10lu\n"
  3279. " Used = %10lu\n"
  3280. " Returned = %10lu\n"
  3281. " InUse = %10lu\n"
  3282. " InFreeList = %10lu\n",
  3283. pstat->UdpAlloc,
  3284. pstat->UdpFree,
  3285. pstat->UdpNetAllocs,
  3286. pstat->UdpMemory,
  3287. pstat->UdpUsed,
  3288. pstat->UdpReturn,
  3289. pstat->UdpInUse,
  3290. pstat->UdpInFreeList
  3291. );
  3292. //
  3293. // NS List stats added after Whistler beta 2.
  3294. //
  3295. PrintRoutine( pPrintContext,
  3296. " NsListUsed = %10lu\n"
  3297. " NsListReturned = %10lu\n"
  3298. " NsListInUse = %10lu\n",
  3299. pstat->PacketsForNsListUsed,
  3300. pstat->PacketsForNsListReturned,
  3301. pstat->PacketsForNsListInUse );
  3302. PrintRoutine( pPrintContext,
  3303. "\n"
  3304. "TCP Messages:\n"
  3305. " Alloc = %10lu\n"
  3306. " Realloc = %10lu\n"
  3307. " Free = %10lu\n"
  3308. " NetAllocs = %10lu\n"
  3309. " Memory = %10lu\n"
  3310. "\n"
  3311. "Recursion Messages:\n"
  3312. " Used = %10lu\n"
  3313. " Returned = %10lu\n"
  3314. "\n",
  3315. pstat->TcpAlloc,
  3316. pstat->TcpRealloc,
  3317. pstat->TcpFree,
  3318. pstat->TcpNetAllocs,
  3319. pstat->TcpMemory,
  3320. pstat->RecursePacketUsed,
  3321. pstat->RecursePacketReturn
  3322. );
  3323. break;
  3324. }
  3325. case DNSSRV_STATID_TIMEOUT:
  3326. {
  3327. PDNSSRV_TIMEOUT_STATS pstat = (PDNSSRV_TIMEOUT_STATS)pStat;
  3328. PrintRoutine( pPrintContext,
  3329. "\n"
  3330. "Timeout:\n"
  3331. "--------\n"
  3332. "Nodes Queued\n"
  3333. " Total = %10lu\n"
  3334. " Direct = %10lu\n"
  3335. " FromReference = %10lu\n"
  3336. " FromChildDelete = %10lu\n"
  3337. " Dup Already Queued = %10lu\n"
  3338. "Nodes Checked\n"
  3339. " Total = %10lu\n"
  3340. " RecentAccess = %10lu\n"
  3341. " ActiveRecord = %10lu\n"
  3342. " CanNotDelete = %10lu\n"
  3343. " Deleted = %10lu\n"
  3344. "TimeoutBlocks\n"
  3345. " Created = %10lu\n"
  3346. " Deleted = %10lu\n"
  3347. "Delayed Frees\n"
  3348. " Queued = %10lu\n"
  3349. " WithFunction = %10lu\n"
  3350. " Executed = %10lu\n"
  3351. " WithFunction = %10lu\n",
  3352. pstat->SetTotal,
  3353. pstat->SetDirect,
  3354. pstat->SetFromDereference,
  3355. pstat->SetFromChildDelete,
  3356. pstat->AlreadyInSystem,
  3357. pstat->Checks,
  3358. pstat->RecentAccess,
  3359. pstat->ActiveRecord,
  3360. pstat->CanNotDelete,
  3361. pstat->Deleted,
  3362. pstat->ArrayBlocksCreated,
  3363. pstat->ArrayBlocksDeleted,
  3364. pstat->DelayedFreesQueued,
  3365. pstat->DelayedFreesQueuedWithFunction,
  3366. pstat->DelayedFreesExecuted,
  3367. pstat->DelayedFreesExecutedWithFunction
  3368. );
  3369. break;
  3370. }
  3371. case DNSSRV_STATID_ERRORS:
  3372. {
  3373. PDNSSRV_ERROR_STATS pstat = (PDNSSRV_ERROR_STATS)pStat;
  3374. PrintRoutine( pPrintContext,
  3375. "\n"
  3376. "Error Stats:\n"
  3377. "--------------\n"
  3378. "\n"
  3379. " NoError = %10lu\n"
  3380. " FormError = %10lu\n"
  3381. " ServFail = %10lu\n"
  3382. " NxDomain = %10lu\n"
  3383. " NotImpl = %10lu\n"
  3384. " Refused = %10lu\n"
  3385. " YxDomain = %10lu\n"
  3386. " YxRRSet = %10lu\n"
  3387. " NxRRSet = %10lu\n"
  3388. " NotAuth = %10lu\n"
  3389. " NotZone = %10lu\n"
  3390. " Max = %10lu\n"
  3391. " BadSig = %10lu\n"
  3392. " BadKey = %10lu\n"
  3393. " BadTime = %10lu\n"
  3394. " UnknownError = %10lu\n"
  3395. "\n",
  3396. pstat->NoError,
  3397. pstat->FormError,
  3398. pstat->ServFail,
  3399. pstat->NxDomain,
  3400. pstat->NotImpl,
  3401. pstat->Refused,
  3402. pstat->YxDomain,
  3403. pstat->YxRRSet,
  3404. pstat->NxRRSet,
  3405. pstat->NotAuth,
  3406. pstat->NotZone,
  3407. pstat->Max,
  3408. pstat->BadSig,
  3409. pstat->BadKey,
  3410. pstat->BadTime,
  3411. pstat->UnknownError
  3412. );
  3413. break;
  3414. }
  3415. case DNSSRV_STATID_CACHE:
  3416. {
  3417. PDNSSRV_CACHE_STATS pstat = ( PDNSSRV_CACHE_STATS ) pStat;
  3418. PrintRoutine( pPrintContext,
  3419. "\n"
  3420. "Cache Stats:\n"
  3421. "------------\n"
  3422. " Checks where cache exceeded limit = %10lu\n"
  3423. " Successful cache enforcement passes = %10lu\n"
  3424. " Failed cache enforcement passes = %10lu\n"
  3425. " Passes that required aggressive free = %10lu\n"
  3426. " Passes where nothing was freed = %10lu\n\n",
  3427. pstat->CacheExceededLimitChecks,
  3428. pstat->SuccessfulFreePasses,
  3429. pstat->FailedFreePasses,
  3430. pstat->PassesRequiringAggressiveFree,
  3431. pstat->PassesWithNoFrees );
  3432. break;
  3433. }
  3434. case DNSSRV_STATID_PRIVATE:
  3435. {
  3436. PDNSSRV_PRIVATE_STATS pstat = (PDNSSRV_PRIVATE_STATS)pStat;
  3437. PrintRoutine( pPrintContext,
  3438. "\n"
  3439. "Private Stats:\n"
  3440. "--------------\n"
  3441. "\n"
  3442. "Record Sources:\n"
  3443. " RR File = %10lu\n"
  3444. " RR File Free = %10lu\n"
  3445. " RR DS = %10lu\n"
  3446. " RR DS Free = %10lu\n"
  3447. " RR Admin = %10lu\n"
  3448. " RR Admin Free = %10lu\n"
  3449. " RR DynUp = %10lu\n"
  3450. " RR DynUp Free = %10lu\n"
  3451. " RR Axfr = %10lu\n"
  3452. " RR Axfr Free = %10lu\n"
  3453. " RR Ixfr = %10lu\n"
  3454. " RR Ixfr Free = %10lu\n"
  3455. " RR Copy = %10lu\n"
  3456. " RR Copy Free = %10lu\n"
  3457. " RR Cache = %10lu\n"
  3458. " RR Cache Free = %10lu\n"
  3459. #if 0
  3460. " RR NoExist = %10lu\n"
  3461. " RR NoExist Free = %10lu\n"
  3462. " RR Wins = %10lu\n"
  3463. " RR Wins Free = %10lu\n"
  3464. " RR WinsPtr = %10lu\n"
  3465. " RR WinsPtr Free = %10lu\n"
  3466. " RR Auto = %10lu\n"
  3467. " RR Auto Free = %10lu\n"
  3468. " RR Unknown = %10lu\n"
  3469. " RR Unknown Free = %10lu\n"
  3470. #endif
  3471. "\n"
  3472. "UDP Sockets:\n"
  3473. " PnP Socket Delete = %10lu\n"
  3474. " Recvfrom Failure = %10lu\n"
  3475. " ConnResets = %10lu\n"
  3476. " ConnReset Overflow = %10lu\n"
  3477. " GQCS Failure = %10lu\n"
  3478. " GQCS Failure wCntxt = %10lu\n"
  3479. " GQCS ConnReset = %10lu\n"
  3480. " Indicate Recv Fail = %10lu\n"
  3481. " Restart Recv Pass = %10lu\n"
  3482. "\n"
  3483. "TCP Connections:\n"
  3484. " ConnectAttempt = %10lu\n"
  3485. " ConnectFailure = %10lu\n"
  3486. " Connect = %10lu\n"
  3487. " Query = %10lu\n"
  3488. " Disconnect = %10lu\n"
  3489. "\n"
  3490. "Security stats:\n"
  3491. " Verified Old Sig = %10lu\n"
  3492. " Failed Old Sig = %10lu\n"
  3493. " Big TimeSkew Bypass = %10lu\n"
  3494. "\n",
  3495. pstat->RecordFile,
  3496. pstat->RecordFileFree,
  3497. pstat->RecordDs,
  3498. pstat->RecordDsFree,
  3499. pstat->RecordAdmin,
  3500. pstat->RecordAdminFree,
  3501. pstat->RecordDynUp,
  3502. pstat->RecordDynUpFree,
  3503. pstat->RecordAxfr,
  3504. pstat->RecordAxfrFree,
  3505. pstat->RecordIxfr,
  3506. pstat->RecordIxfrFree,
  3507. pstat->RecordCopy,
  3508. pstat->RecordCopyFree,
  3509. pstat->RecordCache,
  3510. pstat->RecordCacheFree,
  3511. #if 0
  3512. pstat->RecordNoExist,
  3513. pstat->RecordNoExistFree,
  3514. pstat->RecordWins,
  3515. pstat->RecordWinsFree,
  3516. pstat->RecordWinsPtr,
  3517. pstat->RecordWinsPtrFree,
  3518. pstat->RecordAuto,
  3519. pstat->RecordAutoFree,
  3520. pstat->RecordUnknown,
  3521. pstat->RecordUnknownFree,
  3522. #endif
  3523. pstat->UdpSocketPnpDelete,
  3524. pstat->UdpRecvFailure,
  3525. pstat->UdpConnResets,
  3526. pstat->UdpConnResetRetryOverflow,
  3527. pstat->UdpGQCSFailure,
  3528. pstat->UdpGQCSFailureWithContext,
  3529. pstat->UdpGQCSConnReset,
  3530. pstat->UdpIndicateRecvFailures,
  3531. pstat->UdpRestartRecvOnSockets,
  3532. pstat->TcpConnectAttempt,
  3533. pstat->TcpConnectFailure,
  3534. pstat->TcpConnect,
  3535. pstat->TcpQuery,
  3536. pstat->TcpDisconnect,
  3537. pstat->SecTsigVerifyOldSig,
  3538. pstat->SecTsigVerifyOldFailed,
  3539. pstat->SecBigTimeSkewBypass
  3540. );
  3541. break;
  3542. }
  3543. default:
  3544. DnsPrint_RpcStatRaw(
  3545. PrintRoutine, pPrintContext,
  3546. NULL,
  3547. pStat,
  3548. DNS_ERROR_INVALID_TYPE );
  3549. break;
  3550. } // end switch
  3551. DnsPrint_Unlock();
  3552. }
  3553. //
  3554. // End of print.c
  3555. //