Source code of Windows XP (NT5)
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.

1258 lines
28 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. nt4api.c
  5. Abstract:
  6. Domain Name System (DNS) Server -- Admin Client API
  7. DNS NT4 API that are not direct calls to RPC stubs.
  8. Author:
  9. Jim Gilroy (jamesg) 14-Oct-1995
  10. Environment:
  11. User Mode - Win32
  12. Revision History:
  13. --*/
  14. #include "dnsclip.h"
  15. VOID
  16. DNS_API_FUNCTION
  17. Dns4_FreeZoneInfo(
  18. IN OUT PDNS4_ZONE_INFO pZoneInfo
  19. )
  20. /*++
  21. Routine Description:
  22. Deep free of DNS4_ZONE_INFO structure.
  23. Arguments:
  24. pZoneInfo -- ptr to zone info to free
  25. Return Value:
  26. None
  27. --*/
  28. {
  29. if ( !pZoneInfo )
  30. {
  31. return;
  32. }
  33. //
  34. // free substructures
  35. // - name string
  36. // - data file string
  37. // - secondary IP array
  38. // - WINS server array
  39. //
  40. if ( pZoneInfo->pszZoneName )
  41. {
  42. MIDL_user_free( pZoneInfo->pszZoneName );
  43. }
  44. if ( pZoneInfo->pszDataFile )
  45. {
  46. MIDL_user_free( pZoneInfo->pszDataFile );
  47. }
  48. if ( pZoneInfo->aipMasters )
  49. {
  50. MIDL_user_free( pZoneInfo->aipMasters );
  51. }
  52. if ( pZoneInfo->aipSecondaries )
  53. {
  54. MIDL_user_free( pZoneInfo->aipSecondaries );
  55. }
  56. //
  57. // free DNS4_ZONE_INFO struct itself
  58. //
  59. MIDL_user_free( pZoneInfo );
  60. }
  61. DNS_STATUS
  62. DNS_API_FUNCTION
  63. Dns4_ResetZoneMaster(
  64. IN LPCSTR Server,
  65. IN DNS_HANDLE hZone,
  66. IN IP_ADDRESS ipMaster
  67. )
  68. /*++
  69. Routine Description:
  70. Reset one zone master
  71. --*/
  72. {
  73. IP_ADDRESS ipBuf = ipMaster;
  74. return Dns4_ResetZoneMasters(
  75. Server,
  76. hZone,
  77. 1,
  78. & ipBuf );
  79. }
  80. DNS_STATUS
  81. DNS_API_FUNCTION
  82. Dns4_EnumZoneInfo(
  83. IN LPCSTR Server,
  84. OUT PDWORD pdwZoneCount,
  85. IN DWORD dwArrayCount,
  86. IN OUT PDNS4_ZONE_INFO apZones[]
  87. )
  88. /*++
  89. Routine Description:
  90. Get zone info for all zones on server.
  91. Arguments:
  92. Server -- server name
  93. pdwZoneCount -- addr to recv number of zones on server
  94. dwArrayCount -- size of zone info ptr array
  95. apZones -- array to be filled with zone info ptrs
  96. Return Value:
  97. None
  98. --*/
  99. {
  100. DNS_STATUS status;
  101. PDNS_HANDLE ahZones;
  102. INT i;
  103. DWORD zoneCount = 0;
  104. IF_DNSDBG( STUB )
  105. {
  106. DNS_PRINT((
  107. "Enter DnsEnumZoneInfo()\n"
  108. "\tServer = %s\n"
  109. "\tpdwZoneCount = %p\n"
  110. "\tdwArrayCount = %d\n"
  111. "\tapZones = %p\n",
  112. Server,
  113. pdwZoneCount,
  114. dwArrayCount,
  115. apZones ));
  116. DnsDbg_DwordArray(
  117. "Zone array",
  118. NULL,
  119. dwArrayCount,
  120. (PDWORD)apZones );
  121. }
  122. //
  123. // allocate space
  124. // - allocate for as many entries as caller is allowing zones
  125. // zones
  126. ahZones = (PDNS_HANDLE) MIDL_user_allocate(
  127. dwArrayCount * sizeof(DNS_HANDLE) );
  128. if ( !ahZones )
  129. {
  130. return( DNS_ERROR_NO_MEMORY );
  131. }
  132. IF_DNSDBG( STUB )
  133. {
  134. DNS_PRINT((
  135. "Allocated zone HANDLE block at %p for up to %d zones\n",
  136. ahZones,
  137. dwArrayCount ));
  138. DnsDbg_DwordArray(
  139. "Zone handle array",
  140. NULL,
  141. dwArrayCount,
  142. ahZones );
  143. }
  144. //
  145. // get zone handles
  146. //
  147. status = Dns4_EnumZoneHandles(
  148. Server,
  149. & zoneCount,
  150. dwArrayCount,
  151. ahZones
  152. );
  153. IF_DNSDBG( STUB )
  154. {
  155. DNS_PRINT((
  156. "Under call to DnsEnumZoneHandles() completed.\n"
  157. "\tstatus = %d (%p)\n"
  158. "\tzone count = %d\n",
  159. status, status,
  160. zoneCount ));
  161. DnsDbg_DwordArray(
  162. "Zone handle array",
  163. NULL,
  164. (zoneCount < dwArrayCount) ? zoneCount+1 : dwArrayCount,
  165. ahZones );
  166. }
  167. *pdwZoneCount = zoneCount;
  168. if ( status != ERROR_SUCCESS )
  169. {
  170. return( status );
  171. }
  172. //
  173. // get info for each zone
  174. //
  175. for( i=0; i<(INT)zoneCount; i++ )
  176. {
  177. apZones[i] = NULL;
  178. status = Dns4_GetZoneInfo(
  179. Server,
  180. ahZones[i],
  181. & apZones[i] );
  182. if ( status != ERROR_SUCCESS )
  183. {
  184. goto cleanup;
  185. }
  186. }
  187. IF_DNSDBG( STUB )
  188. {
  189. Dns4_Dbg_RpcZoneInfoList(
  190. "Leaving DnsEnumZoneInfo() ",
  191. *pdwZoneCount,
  192. apZones );
  193. }
  194. cleanup:
  195. IF_DNSDBG( STUB )
  196. {
  197. if ( status != ERROR_SUCCESS )
  198. {
  199. DNS_PRINT((
  200. "Leaving DnsEnumZoneInfo(), status = %d\n",
  201. status ));
  202. }
  203. }
  204. MIDL_user_free( ahZones );
  205. return( status );
  206. }
  207. //
  208. // NT4 type print
  209. //
  210. VOID
  211. Dns4_Print_RpcServerInfo(
  212. IN PRINT_ROUTINE PrintRoutine,
  213. IN LPSTR pszHeader,
  214. IN PDNS4_RPC_SERVER_INFO pServerInfo
  215. )
  216. {
  217. DnsPrint_Lock();
  218. if ( pszHeader )
  219. {
  220. PrintRoutine( pszHeader );
  221. }
  222. if ( ! pServerInfo )
  223. {
  224. PrintRoutine( "NULL server info ptr.\n" );
  225. }
  226. else
  227. {
  228. PrintRoutine(
  229. "Server info:\n"
  230. "\tptr = %p\n"
  231. "\tversion = %p\n"
  232. "\tboot registry = %d\n",
  233. pServerInfo,
  234. pServerInfo->dwVersion,
  235. pServerInfo->fBootRegistry );
  236. DnsPrint_IpArray(
  237. PrintRoutine,
  238. NULL,
  239. "\tServerAddresses:\n",
  240. "\tAddr",
  241. pServerInfo->aipServerAddrs );
  242. DnsPrint_IpArray(
  243. PrintRoutine,
  244. NULL,
  245. "\tListenAddresses:\n",
  246. "\tAddr",
  247. pServerInfo->aipListenAddrs );
  248. DnsPrint_IpArray(
  249. PrintRoutine,
  250. NULL,
  251. "\tForwarders:\n",
  252. "\tAddr",
  253. pServerInfo->aipForwarders );
  254. PrintRoutine(
  255. "\tforward timeout = %d\n"
  256. "\tslave = %d\n",
  257. pServerInfo->dwForwardTimeout,
  258. pServerInfo->fSlave );
  259. }
  260. DnsPrint_Unlock();
  261. }
  262. VOID
  263. Dns4_Print_RpcStatistics(
  264. IN PRINT_ROUTINE PrintRoutine,
  265. IN LPSTR pszHeader,
  266. IN PDNS4_STATISTICS pStatistics
  267. )
  268. /*++
  269. Routine Description:
  270. Debug print statistics.
  271. Arguments:
  272. None.
  273. Return Value:
  274. None.
  275. --*/
  276. {
  277. CHAR szdate[30];
  278. CHAR sztime[20];
  279. DnsPrint_Lock();
  280. if ( pszHeader )
  281. {
  282. PrintRoutine( pszHeader );
  283. }
  284. GetDateFormat(
  285. LOCALE_SYSTEM_DEFAULT,
  286. LOCALE_NOUSEROVERRIDE,
  287. (PSYSTEMTIME) &pStatistics->ServerStartTime,
  288. NULL,
  289. szdate,
  290. 30 );
  291. GetTimeFormat(
  292. LOCALE_SYSTEM_DEFAULT,
  293. LOCALE_NOUSEROVERRIDE,
  294. (PSYSTEMTIME) &pStatistics->ServerStartTime,
  295. NULL,
  296. sztime,
  297. 20 );
  298. PrintRoutine(
  299. "\n"
  300. "DNS Statistics\n"
  301. "--------------\n"
  302. "\tServer start time %s %s\n",
  303. szdate,
  304. sztime );
  305. GetDateFormat(
  306. LOCALE_SYSTEM_DEFAULT,
  307. LOCALE_NOUSEROVERRIDE,
  308. (PSYSTEMTIME) &pStatistics->LastClearTime,
  309. NULL,
  310. szdate,
  311. 30 );
  312. GetTimeFormat(
  313. LOCALE_SYSTEM_DEFAULT,
  314. LOCALE_NOUSEROVERRIDE,
  315. (PSYSTEMTIME) &pStatistics->LastClearTime,
  316. NULL,
  317. sztime,
  318. 20 );
  319. PrintRoutine(
  320. "\tStats last cleared %s %s\n"
  321. "\tSeconds since clear %d\n",
  322. szdate,
  323. sztime,
  324. pStatistics->SecondsSinceLastClear
  325. );
  326. //
  327. // query and response counts
  328. //
  329. PrintRoutine(
  330. "\n"
  331. "Queries and Responses:\n"
  332. "----------------------\n"
  333. "Total:\n"
  334. "\tQueries Received = %d\n"
  335. "\tResponses Sent = %d\n"
  336. "UDP:\n"
  337. "\tQueries Recvd = %d\n"
  338. "\tResponses Sent = %d\n"
  339. "\tQueries Sent = %d\n"
  340. "\tResponses Recvd = %d\n"
  341. "TCP:\n"
  342. "\tClient Connects = %d\n"
  343. "\tQueries Recvd = %d\n"
  344. "\tResponses Sent = %d\n"
  345. "\tQueries Sent = %d\n"
  346. "\tResponses Recvd = %d\n",
  347. pStatistics->UdpQueries + pStatistics->TcpQueries,
  348. pStatistics->UdpResponses + pStatistics->TcpResponses,
  349. pStatistics->UdpQueries,
  350. pStatistics->UdpResponses,
  351. pStatistics->UdpQueriesSent,
  352. pStatistics->UdpResponsesReceived,
  353. pStatistics->TcpClientConnections,
  354. pStatistics->TcpQueries,
  355. pStatistics->TcpResponses,
  356. pStatistics->TcpQueriesSent,
  357. pStatistics->TcpResponsesReceived
  358. );
  359. PrintRoutine(
  360. "\n"
  361. "Recursion:\n"
  362. "----------\n"
  363. "\tPackets = %d\n"
  364. "\tLookups = %d\n"
  365. "\tQuestions = %d\n"
  366. "\tPasses = %d\n"
  367. "\tForwards = %d\n"
  368. "\tSends = %d\n"
  369. "\tResponses = %d\n"
  370. "\tTimeouts = %d\n"
  371. "\tFailures = %d\n"
  372. "\tIncomplete = %d\n",
  373. pStatistics->RecursePacketUsed,
  374. pStatistics->RecurseLookups,
  375. pStatistics->RecurseQuestions,
  376. pStatistics->RecursePasses,
  377. pStatistics->RecurseForwards,
  378. pStatistics->RecurseLookups,
  379. pStatistics->RecurseResponses,
  380. pStatistics->RecurseTimeouts,
  381. pStatistics->RecurseFailures,
  382. pStatistics->RecursePartialFailures
  383. );
  384. PrintRoutine(
  385. "TCP Recursion:\n"
  386. "\tTry = %d\n"
  387. "\tQuery = %d\n"
  388. "\tResponse = %d\n"
  389. "Root Query:\n"
  390. "\tQuery = %d\n"
  391. "\tResponse = %d\n",
  392. pStatistics->RecurseTcpTry,
  393. pStatistics->RecurseTcpQuery,
  394. pStatistics->RecurseTcpResponse,
  395. pStatistics->RecurseRootQuery,
  396. pStatistics->RecurseRootResponse
  397. );
  398. PrintRoutine(
  399. "\n"
  400. "WINS Referrals:\n"
  401. "---------------\n"
  402. "Forward:\n"
  403. "\tLookups = %d\n"
  404. "\tResponses = %d\n"
  405. "Reverse:\n"
  406. "\tLookups = %d\n"
  407. "\tResponses = %d\n",
  408. pStatistics->WinsLookups,
  409. pStatistics->WinsResponses,
  410. pStatistics->WinsReverseLookups,
  411. pStatistics->WinsReverseResponses
  412. );
  413. PrintRoutine(
  414. "\n"
  415. "Secondary Zone Transfer:\n"
  416. "------------------------\n"
  417. "SOA Queries = %d\n"
  418. "SOA Responses = %d\n"
  419. "Notifies Recvd = %d\n"
  420. "AXFR Requests = %d\n"
  421. "AXFR Rejected = %d\n"
  422. "AXFR Failed = %d\n"
  423. "AXFR Successful = %d\n",
  424. pStatistics->SecSoaQueries,
  425. pStatistics->SecSoaResponses,
  426. pStatistics->SecNotifyReceived,
  427. pStatistics->SecAxfrRequested,
  428. pStatistics->SecAxfrRejected,
  429. pStatistics->SecAxfrFailed,
  430. pStatistics->SecAxfrSuccessful
  431. );
  432. PrintRoutine(
  433. "\n"
  434. "Master Zone Transfer:\n"
  435. "---------------------\n"
  436. "Notifies Sent = %d\n"
  437. "AXFR Requests Recvd = %d\n"
  438. "AXFR Invalid Requests = %d\n"
  439. "AXFR Denied (Security) = %d\n"
  440. "AXFR Refused = %d\n"
  441. "AXFR Failed = %d\n"
  442. "AXFR Successful = %d\n",
  443. pStatistics->MasterNotifySent,
  444. pStatistics->MasterAxfrReceived,
  445. pStatistics->MasterAxfrInvalid,
  446. pStatistics->MasterAxfrDenied,
  447. pStatistics->MasterAxfrRefused,
  448. pStatistics->MasterAxfrFailed,
  449. pStatistics->MasterAxfrSuccessful
  450. );
  451. //
  452. // Database stats
  453. //
  454. PrintRoutine(
  455. "\n"
  456. "Database:\n"
  457. "---------\n"
  458. "Nodes\n"
  459. " InUse = %d\n"
  460. " Memory = %d\n"
  461. "Records\n"
  462. " InUse = %d\n"
  463. " Memory = %d\n"
  464. "Database Total\n"
  465. " Memory = %d\n",
  466. pStatistics->NodeInUse,
  467. pStatistics->NodeMemory,
  468. pStatistics->RecordInUse,
  469. pStatistics->RecordMemory,
  470. pStatistics->DatabaseMemory
  471. );
  472. PrintRoutine(
  473. "\n"
  474. "RR Caching:\n"
  475. "\tTotal = %d\n"
  476. "\tCurrent = %d\n"
  477. "\tTimeouts = %d\n",
  478. pStatistics->CacheRRTotal,
  479. pStatistics->CacheRRCurrent,
  480. pStatistics->CacheRRTimeouts
  481. );
  482. PrintRoutine(
  483. "\n"
  484. "Domain Nodes:\n"
  485. "\tAlloc = %d\n"
  486. "\tFree = %d\n"
  487. "\tNetAllocs = %d\n"
  488. "\tMemory = %d\n"
  489. "\n"
  490. "\tUsed = %d\n"
  491. "\tReturned = %d\n"
  492. "\tInUse = %d\n"
  493. "\n"
  494. "\tStd Alloc = %d\n"
  495. "\tStd Used = %d\n"
  496. "\tStd Return = %d\n"
  497. "\tInFreeList = %d\n",
  498. pStatistics->NodeAlloc,
  499. pStatistics->NodeFree,
  500. pStatistics->NodeNetAllocs,
  501. pStatistics->NodeMemory,
  502. pStatistics->NodeUsed,
  503. pStatistics->NodeReturn,
  504. pStatistics->NodeInUse,
  505. pStatistics->NodeStdAlloc,
  506. pStatistics->NodeStdUsed,
  507. pStatistics->NodeStdReturn,
  508. pStatistics->NodeInFreeList
  509. );
  510. PrintRoutine(
  511. "\n"
  512. "Records:\n"
  513. "\tAlloc = %d\n"
  514. "\tFree = %d\n"
  515. "\tNetAllocs = %d\n"
  516. "\tMemory = %d\n"
  517. "\n"
  518. "\tUsed = %d\n"
  519. "\tReturned = %d\n"
  520. "\tInUse = %d\n"
  521. "\n"
  522. "\tStd Alloc = %d\n"
  523. "\tStd Used = %d\n"
  524. "\tStd Return = %d\n"
  525. "\tInFreeList = %d\n",
  526. pStatistics->RecordAlloc,
  527. pStatistics->RecordFree,
  528. pStatistics->RecordNetAllocs,
  529. pStatistics->RecordMemory,
  530. pStatistics->RecordUsed,
  531. pStatistics->RecordReturn,
  532. pStatistics->RecordInUse,
  533. pStatistics->RecordStdAlloc,
  534. pStatistics->RecordStdUsed,
  535. pStatistics->RecordStdReturn,
  536. pStatistics->RecordInFreeList
  537. );
  538. PrintRoutine(
  539. "\n"
  540. "Packet Memory Usage:\n"
  541. "--------------------\n"
  542. "UDP Messages:\n"
  543. "\tAlloc = %d\n"
  544. "\tFree = %d\n"
  545. "\tNetAllocs = %d\n"
  546. "\tMemory = %d\n"
  547. "\tUsed = %d\n"
  548. "\tReturned = %d\n"
  549. "\tInUse = %d\n"
  550. "\tInFreeList = %d\n"
  551. "\n",
  552. pStatistics->UdpAlloc,
  553. pStatistics->UdpFree,
  554. pStatistics->UdpNetAllocs,
  555. pStatistics->UdpMemory,
  556. pStatistics->UdpUsed,
  557. pStatistics->UdpReturn,
  558. pStatistics->UdpInUse,
  559. pStatistics->UdpInFreeList
  560. );
  561. PrintRoutine(
  562. "TCP Messages:\n"
  563. "\tAlloc = %d\n"
  564. "\tRealloc = %d\n"
  565. "\tFree = %d\n"
  566. "\tNetAllocs = %d\n"
  567. "\tMemory = %d\n"
  568. "\n",
  569. pStatistics->TcpAlloc,
  570. pStatistics->TcpRealloc,
  571. pStatistics->TcpFree,
  572. pStatistics->TcpNetAllocs,
  573. pStatistics->TcpMemory
  574. );
  575. PrintRoutine(
  576. "Recursion Messages:\n"
  577. "\tUsed = %d\n"
  578. "\tReturned = %d\n"
  579. "\n",
  580. pStatistics->RecursePacketUsed,
  581. pStatistics->RecursePacketReturn
  582. );
  583. PrintRoutine(
  584. "\n"
  585. "Nbstat Memory Usage:\n"
  586. "--------------------\n"
  587. "Nbstat Buffers:\n"
  588. "\tAlloc = %d\n"
  589. "\tFree = %d\n"
  590. "\tNetAllocs = %d\n"
  591. "\tMemory = %d\n"
  592. "\tUsed = %d\n"
  593. "\tReturned = %d\n"
  594. "\tInUse = %d\n"
  595. "\tInFreeList = %d\n"
  596. "\n",
  597. pStatistics->NbstatAlloc,
  598. pStatistics->NbstatFree,
  599. pStatistics->NbstatNetAllocs,
  600. pStatistics->NbstatMemory,
  601. pStatistics->NbstatUsed,
  602. pStatistics->NbstatReturn,
  603. pStatistics->NbstatInUse,
  604. pStatistics->NbstatInFreeList
  605. );
  606. DnsPrint_Unlock();
  607. }
  608. VOID
  609. Dns4_Print_RpcZoneHandleList(
  610. IN PRINT_ROUTINE PrintRoutine,
  611. IN LPSTR pszHeader,
  612. IN DWORD dwZoneCount,
  613. IN DNS_HANDLE ahZones[]
  614. )
  615. {
  616. DWORD i;
  617. DnsPrint_Lock();
  618. if ( pszHeader )
  619. {
  620. PrintRoutine( pszHeader );
  621. }
  622. PrintRoutine( "Zone Count = %d\n", dwZoneCount );
  623. if ( dwZoneCount != 0 && ahZones != NULL )
  624. {
  625. for( i=0; i<dwZoneCount; i++ )
  626. {
  627. PrintRoutine( "\thZones[%d] => %p\n", i, ahZones[i] );
  628. }
  629. }
  630. }
  631. VOID
  632. Dns4_Print_RpcZoneInfo(
  633. IN PRINT_ROUTINE PrintRoutine,
  634. IN LPSTR pszHeader,
  635. IN PDNS4_ZONE_INFO pZoneInfo
  636. )
  637. {
  638. DnsPrint_Lock();
  639. PrintRoutine( (pszHeader ? pszHeader : "") );
  640. if ( ! pZoneInfo )
  641. {
  642. PrintRoutine( "NULL zone info ptr.\n" );
  643. }
  644. else
  645. {
  646. PrintRoutine(
  647. "Zone info:\n"
  648. "\tptr = %p\n"
  649. "\thZone = %p\n"
  650. "\tzone name = %s\n"
  651. "\tzone type = %d\n"
  652. "\tusing dbase = %d\n"
  653. "\tdata file = %s\n"
  654. "\tusing WINS = %d\n"
  655. "\tusing Nbstat = %d\n",
  656. pZoneInfo,
  657. pZoneInfo->hZone,
  658. pZoneInfo->pszZoneName,
  659. pZoneInfo->dwZoneType,
  660. pZoneInfo->fUseDatabase,
  661. pZoneInfo->pszDataFile,
  662. pZoneInfo->fUseWins,
  663. pZoneInfo->fUseNbstat
  664. );
  665. DnsPrint_IpArray(
  666. PrintRoutine,
  667. NULL,
  668. "\tZones Masters\n",
  669. "\tMaster",
  670. pZoneInfo->aipMasters );
  671. DnsPrint_IpArray(
  672. PrintRoutine,
  673. NULL,
  674. "\tZone Secondaries\n",
  675. "\tSecondary",
  676. pZoneInfo->aipSecondaries );
  677. PrintRoutine(
  678. "\tsecure secs = %d\n",
  679. pZoneInfo->fSecureSecondaries
  680. );
  681. }
  682. DnsPrint_Unlock();
  683. }
  684. VOID
  685. Dns4_Print_RpcZoneInfoList(
  686. IN PRINT_ROUTINE PrintRoutine,
  687. IN LPSTR pszHeader,
  688. IN DWORD dwZoneCount,
  689. IN PDNS4_ZONE_INFO apZoneInfo[]
  690. )
  691. {
  692. DWORD i;
  693. DnsPrint_Lock();
  694. PrintRoutine( (pszHeader ? pszHeader : "") );
  695. PrintRoutine( "Zone Count = %d\n", dwZoneCount );
  696. if ( dwZoneCount != 0 && apZoneInfo != NULL )
  697. {
  698. for (i=0; i<dwZoneCount; i++)
  699. {
  700. PrintRoutine( "\n[%d]", i );
  701. Dns4_Print_RpcZoneInfo(
  702. PrintRoutine,
  703. NULL,
  704. apZoneInfo[i] );
  705. }
  706. }
  707. DnsPrint_Unlock();
  708. }
  709. VOID
  710. Dns4_Print_RpcRecord(
  711. IN PRINT_ROUTINE PrintRoutine,
  712. IN LPSTR pszHeader,
  713. IN PDNS4_RPC_RECORD pRecord
  714. )
  715. {
  716. PCHAR pRecordString;
  717. PDNS4_RPC_RECORD pnt4Record;
  718. WORD type;
  719. DnsPrint_Lock();
  720. PrintRoutine( (pszHeader ? pszHeader : "" ) );
  721. if ( ! pRecord )
  722. {
  723. PrintRoutine( "NULL record ptr.\n" );
  724. goto Done;
  725. }
  726. //
  727. // record fixed fields
  728. //
  729. type = pRecord->wType;
  730. pRecordString = Dns_RecordStringForType( type );
  731. if ( !pRecordString )
  732. {
  733. pRecordString = "UNKNOWN";
  734. }
  735. PrintRoutine(
  736. " %s Record (NT4):\n"
  737. "\tptr = %p\n"
  738. "\thRecord = %p\n"
  739. "\twLength = %u\n"
  740. "\twDataLength = %u\n"
  741. "\twType = %s (%u)\n"
  742. "\twClass = %u\n"
  743. "\tdwFlags = %lx\n"
  744. "\tdwTtlSeconds = %u\n",
  745. pRecordString,
  746. pRecord,
  747. pRecord->hRecord,
  748. pRecord->wRecordLength,
  749. pRecord->wDataLength,
  750. pRecordString,
  751. type,
  752. pRecord->wClass,
  753. pRecord->dwFlags,
  754. pRecord->dwTtlSeconds
  755. );
  756. //
  757. // print record type and data
  758. // - as single line data where possible
  759. PrintRoutine(
  760. " %s ",
  761. pRecordString );
  762. switch ( type )
  763. {
  764. case DNS_TYPE_A:
  765. PrintRoutine(
  766. "%d.%d.%d.%d\n",
  767. * ( (PUCHAR) &(pRecord->Data.A) + 0 ),
  768. * ( (PUCHAR) &(pRecord->Data.A) + 1 ),
  769. * ( (PUCHAR) &(pRecord->Data.A) + 2 ),
  770. * ( (PUCHAR) &(pRecord->Data.A) + 3 )
  771. );
  772. break;
  773. case DNS_TYPE_PTR:
  774. case DNS_TYPE_NS:
  775. case DNS_TYPE_CNAME:
  776. case DNS_TYPE_MD:
  777. case DNS_TYPE_MB:
  778. case DNS_TYPE_MF:
  779. case DNS_TYPE_MG:
  780. case DNS_TYPE_MR:
  781. //
  782. // these RRs contain single indirection
  783. //
  784. DnsPrint_RpcName(
  785. PrintRoutine,
  786. NULL,
  787. & pRecord->Data.NS.nameNode,
  788. "\n" );
  789. break;
  790. case DNS_TYPE_MX:
  791. case DNS_TYPE_RT:
  792. case DNS_TYPE_AFSDB:
  793. //
  794. // these RR contain
  795. // - one preference value
  796. // - one domain name
  797. //
  798. PrintRoutine(
  799. "%d ",
  800. pRecord->Data.MX.wPreference
  801. );
  802. DnsPrint_RpcName(
  803. PrintRoutine,
  804. NULL,
  805. & pRecord->Data.MX.nameExchange,
  806. "\n" );
  807. break;
  808. case DNS_TYPE_SOA:
  809. DnsPrint_RpcName(
  810. PrintRoutine,
  811. "\n\tPrimaryNameServer: ",
  812. & pRecord->Data.SOA.namePrimaryServer,
  813. "\n" );
  814. // responsible party name, immediately follows primary server name
  815. DnsPrint_RpcName(
  816. PrintRoutine,
  817. "\tResponsibleParty: ",
  818. (PDNS_RPC_NAME)
  819. (pRecord->Data.SOA.namePrimaryServer.achName
  820. + pRecord->Data.SOA.namePrimaryServer.cchNameLength),
  821. "\n" );
  822. PrintRoutine(
  823. "\tSerialNo = %lu\n"
  824. "\tRefresh = %lu\n"
  825. "\tRetry = %lu\n"
  826. "\tExpire = %lu\n"
  827. "\tMinimumTTL = %lu\n",
  828. pRecord->Data.SOA.dwSerialNo,
  829. pRecord->Data.SOA.dwRefresh,
  830. pRecord->Data.SOA.dwRetry,
  831. pRecord->Data.SOA.dwExpire,
  832. pRecord->Data.SOA.dwMinimumTtl );
  833. break;
  834. case DNS_TYPE_MINFO:
  835. case DNS_TYPE_RP:
  836. //
  837. // these RRs contain two domain names
  838. //
  839. DnsPrint_RpcName(
  840. PrintRoutine,
  841. "\n\tMailBox: ",
  842. & pRecord->Data.MINFO.nameMailBox,
  843. NULL );
  844. // errors to mailbox name, immediately follows mail box
  845. DnsPrint_RpcName(
  846. PrintRoutine,
  847. "\tErrorsToMailbox: ",
  848. (PDNS_RPC_NAME)
  849. ( pRecord->Data.MINFO.nameMailBox.achName
  850. + pRecord->Data.MINFO.nameMailBox.cchNameLength ),
  851. "\n" );
  852. break;
  853. case DNS_TYPE_AAAA:
  854. case DNS_TYPE_HINFO:
  855. case DNS_TYPE_ISDN:
  856. case DNS_TYPE_X25:
  857. case DNS_TYPE_TEXT:
  858. {
  859. //
  860. // all these are simply text string(s)
  861. //
  862. PCHAR pch = (PCHAR) &pRecord->Data.TXT.stringData;
  863. PCHAR pchStop = pch + pRecord->wDataLength;
  864. UCHAR cch;
  865. while ( pch < pchStop )
  866. {
  867. cch = (UCHAR) *pch++;
  868. PrintRoutine(
  869. "\t%.*s\n",
  870. cch,
  871. pch );
  872. pch += cch;
  873. }
  874. ASSERT( pch == pchStop );
  875. break;
  876. }
  877. case DNS_TYPE_WKS:
  878. {
  879. INT i;
  880. PrintRoutine(
  881. "WKS: Address %d.%d.%d.%d\n"
  882. "\tProtocol %d\n"
  883. "\tBitmask\n",
  884. * ( (PUCHAR) &(pRecord->Data.WKS.ipAddress) + 0 ),
  885. * ( (PUCHAR) &(pRecord->Data.WKS.ipAddress) + 1 ),
  886. * ( (PUCHAR) &(pRecord->Data.WKS.ipAddress) + 2 ),
  887. * ( (PUCHAR) &(pRecord->Data.WKS.ipAddress) + 3 ),
  888. pRecord->Data.WKS.chProtocol
  889. );
  890. for ( i = 0;
  891. i < (INT)( pRecord->wDataLength
  892. - sizeof( pRecord->Data.WKS.ipAddress )
  893. - sizeof( pRecord->Data.WKS.chProtocol ) );
  894. i++ )
  895. {
  896. PrintRoutine(
  897. "\t\tbyte[%d] = %x\n",
  898. i,
  899. (UCHAR) pRecord->Data.WKS.bBitMask[i] );
  900. }
  901. break;
  902. }
  903. case DNS_TYPE_NULL:
  904. {
  905. INT i;
  906. for ( i = 0; i < pRecord->wDataLength; i++ )
  907. {
  908. // print one DWORD per line
  909. if ( !(i%16) )
  910. {
  911. PrintRoutine( "\n\t" );
  912. }
  913. PrintRoutine(
  914. "%02x ",
  915. (UCHAR) pRecord->Data.Null.bData[i] );
  916. }
  917. PrintRoutine( "\n" );
  918. break;
  919. }
  920. case DNS_TYPE_SRV:
  921. //
  922. // SRV <priority> <weight> <port> <target host>
  923. //
  924. PrintRoutine(
  925. "%d %d %d ",
  926. pRecord->Data.SRV.wPriority,
  927. pRecord->Data.SRV.wWeight,
  928. pRecord->Data.SRV.wPort
  929. );
  930. DnsPrint_RpcName(
  931. PrintRoutine,
  932. NULL,
  933. & pRecord->Data.SRV.nameTarget,
  934. "\n" );
  935. break;
  936. case DNS_TYPE_WINS:
  937. {
  938. DWORD i;
  939. //
  940. // WINS
  941. // - scope/domain mapping flag
  942. // - WINS server list
  943. //
  944. PrintRoutine( "%08lx\n", pRecord->Data.WINS.dwMappingFlag );
  945. #if 0
  946. //
  947. // DEVNOTE: WINS mapping strings
  948. // JJW: this is probably an obsolete B*GB*G
  949. //
  950. "%s\t",
  951. Dns_WinsMappingFlagString( pRecord->Data.WINS.dwMappingFlag )
  952. #endif
  953. for( i=0; i<pRecord->Data.WINS.cWinsServerCount; i++ )
  954. {
  955. PrintRoutine(
  956. "%d.%d.%d.%d\n",
  957. * ( (PUCHAR) &(pRecord->Data.WINS.aipWinsServers[i]) + 0 ),
  958. * ( (PUCHAR) &(pRecord->Data.WINS.aipWinsServers[i]) + 1 ),
  959. * ( (PUCHAR) &(pRecord->Data.WINS.aipWinsServers[i]) + 2 ),
  960. * ( (PUCHAR) &(pRecord->Data.WINS.aipWinsServers[i]) + 3 )
  961. );
  962. }
  963. break;
  964. }
  965. case DNS_TYPE_NBSTAT:
  966. //
  967. // NBSTAT
  968. // - scope/domain mapping flag
  969. // - optionally a result domain
  970. //
  971. PrintRoutine( "%08lx\n", pRecord->Data.NBSTAT.dwMappingFlag );
  972. if ( pRecord->wDataLength > sizeof(pRecord->Data.NBSTAT.dwMappingFlag) )
  973. {
  974. DnsPrint_RpcName(
  975. PrintRoutine,
  976. NULL,
  977. & pRecord->Data.NBSTAT.nameResultDomain,
  978. "\n" );
  979. }
  980. break;
  981. default:
  982. PrintRoutine(
  983. "Unknown resource record type (%d) at %p.\n",
  984. pRecord->wType,
  985. pRecord );
  986. break;
  987. }
  988. Done:
  989. DnsPrint_Unlock();
  990. }
  991. VOID
  992. DNS_API_FUNCTION
  993. Dns4_Print_RpcRecordsInBuffer(
  994. IN PRINT_ROUTINE PrintRoutine,
  995. IN LPSTR pszHeader,
  996. IN DWORD dwBufferLength,
  997. IN BYTE abBuffer[]
  998. )
  999. {
  1000. PBYTE pbCurrent;
  1001. PBYTE pbStop;
  1002. INT cRecordCount;
  1003. DnsPrint_Lock();
  1004. PrintRoutine( (pszHeader ? pszHeader : "") );
  1005. if ( !abBuffer )
  1006. {
  1007. PrintRoutine( "NULL record buffer ptr.\n" );
  1008. goto Done;
  1009. }
  1010. else
  1011. {
  1012. PrintRoutine(
  1013. "Record buffer of length %d at %p:\n",
  1014. dwBufferLength,
  1015. abBuffer );
  1016. }
  1017. //
  1018. // find stop byte
  1019. //
  1020. ASSERT( DNS_IS_DWORD_ALIGNED(abBuffer) );
  1021. pbStop = abBuffer + dwBufferLength;
  1022. pbCurrent = abBuffer;
  1023. //
  1024. // loop until out of nodes
  1025. //
  1026. while( pbCurrent < pbStop )
  1027. {
  1028. //
  1029. // print owner node
  1030. // determine record count
  1031. // find first record
  1032. //
  1033. DnsPrint_RpcNode(
  1034. PrintRoutine,
  1035. NULL,
  1036. (PDNS_RPC_NODE)pbCurrent );
  1037. cRecordCount = ((PDNS_RPC_NODE)pbCurrent)->wRecordCount;
  1038. pbCurrent += ((PDNS_RPC_NODE)pbCurrent)->wLength;
  1039. pbCurrent = DNS_NEXT_DWORD_PTR(pbCurrent);
  1040. //
  1041. // for each node, print all records in list
  1042. //
  1043. while( cRecordCount-- )
  1044. {
  1045. if ( pbCurrent >= pbStop )
  1046. {
  1047. PrintRoutine(
  1048. "ERROR: Bogus buffer at %p\n"
  1049. "\tExpect record at %p past buffer end at %p\n"
  1050. "\twith %d records remaining.\n",
  1051. abBuffer,
  1052. (PDNS_RPC_RECORD) pbCurrent,
  1053. pbStop,
  1054. cRecordCount+1 );
  1055. ASSERT( FALSE );
  1056. break;
  1057. }
  1058. Dns4_Print_RpcRecord(
  1059. PrintRoutine,
  1060. "",
  1061. (PDNS4_RPC_RECORD) pbCurrent );
  1062. pbCurrent += ((PDNS4_RPC_RECORD)pbCurrent)->wDataLength
  1063. + SIZEOF_DNS4_RPC_RECORD_HEADER;
  1064. pbCurrent = DNS_NEXT_DWORD_PTR(pbCurrent);
  1065. }
  1066. }
  1067. Done:
  1068. DnsPrint_Unlock();
  1069. }
  1070. //
  1071. // End of nt4api.c
  1072. //