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.

6692 lines
147 KiB

  1. /*++
  2. Copyright (c) 1997-2001 Microsoft Corporation
  3. Module Name:
  4. print.c
  5. Abstract:
  6. Domain Name System (DNS) Library
  7. Print routines.
  8. Author:
  9. Jim Gilroy (jamesg) February 8, 1997
  10. Revision History:
  11. --*/
  12. #include "local.h"
  13. #include "svcguid.h" // RnR guids
  14. #include "..\dnsapi\dnsapip.h" // Private query stuff
  15. #include "..\resolver\idl\resrpc.h" // Resolver interface structs
  16. //
  17. // Print globals
  18. //
  19. CRITICAL_SECTION DnsAtomicPrintCs;
  20. PCRITICAL_SECTION pDnsAtomicPrintCs = NULL;
  21. //
  22. // Empty string for simple switching of UTF-8/Unicode print
  23. // (macros in dnslib.h)
  24. //
  25. DWORD DnsEmptyString = 0;
  26. //
  27. // Indenting
  28. //
  29. // Serve up as many indenting tabs as indent level indicates
  30. //
  31. CHAR IndentString[] = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
  32. #define INDENT_STRING( level ) (IndentString + (sizeof(IndentString) - 1 - (level)))
  33. //
  34. // Print Locking
  35. //
  36. // Unless caller initilizes print locking by supplying lock,
  37. // print locking is disabled.
  38. //
  39. VOID
  40. DnsPrint_InitLocking(
  41. IN PCRITICAL_SECTION pLock
  42. )
  43. /*++
  44. Routine Description:
  45. Setup DNS printing to use a lock.
  46. Can use already initialized lock from caller, or will
  47. create default lock.
  48. Arguments:
  49. pLock - ptr to CS to use as lock; if NULL, create one
  50. Return Value:
  51. None
  52. --*/
  53. {
  54. if ( pLock )
  55. {
  56. pDnsAtomicPrintCs = pLock;
  57. }
  58. else if ( !pDnsAtomicPrintCs )
  59. {
  60. InitializeCriticalSection( &DnsAtomicPrintCs );
  61. pDnsAtomicPrintCs = &DnsAtomicPrintCs;
  62. }
  63. }
  64. VOID
  65. DnsPrint_Lock(
  66. VOID
  67. )
  68. /*++
  69. Routine Description:
  70. Lock to get atomic DNS print.
  71. --*/
  72. {
  73. if ( pDnsAtomicPrintCs )
  74. {
  75. EnterCriticalSection( pDnsAtomicPrintCs );
  76. }
  77. }
  78. VOID
  79. DnsPrint_Unlock(
  80. VOID
  81. )
  82. /*++
  83. Routine Description:
  84. Unlock to debug print.
  85. --*/
  86. {
  87. if ( pDnsAtomicPrintCs )
  88. {
  89. LeaveCriticalSection( pDnsAtomicPrintCs );
  90. }
  91. }
  92. //
  93. // Print routines for general types and structures
  94. //
  95. VOID
  96. DnsPrint_String(
  97. IN PRINT_ROUTINE PrintRoutine,
  98. IN OUT PPRINT_CONTEXT pContext,
  99. IN PSTR pszHeader OPTIONAL,
  100. IN PSTR pszString,
  101. IN BOOL fUnicode,
  102. IN PSTR pszTrailer OPTIONAL
  103. )
  104. /*++
  105. Routine Description:
  106. Print DNS string given in either Unicode or UTF-8 format.
  107. --*/
  108. {
  109. if ( !pszHeader )
  110. {
  111. pszHeader = "";
  112. }
  113. if ( !pszTrailer )
  114. {
  115. pszTrailer = "";
  116. }
  117. if ( ! pszString )
  118. {
  119. PrintRoutine(
  120. pContext,
  121. "%s(NULL DNS string ptr)%s",
  122. pszHeader,
  123. pszTrailer );
  124. }
  125. else if (fUnicode)
  126. {
  127. PrintRoutine(
  128. pContext,
  129. "%s%S%s",
  130. pszHeader,
  131. (PWSTR ) pszString,
  132. pszTrailer );
  133. }
  134. else
  135. {
  136. PrintRoutine(
  137. pContext,
  138. "%s%s%s",
  139. pszHeader,
  140. (PSTR ) pszString,
  141. pszTrailer );
  142. }
  143. }
  144. VOID
  145. DnsPrint_StringCharSet(
  146. IN PRINT_ROUTINE PrintRoutine,
  147. IN OUT PPRINT_CONTEXT pContext,
  148. IN PSTR pszHeader OPTIONAL,
  149. IN PSTR pszString,
  150. IN DNS_CHARSET CharSet,
  151. IN PSTR pszTrailer OPTIONAL
  152. )
  153. /*++
  154. Routine Description:
  155. Print string of given CHARSET.
  156. --*/
  157. {
  158. DnsPrint_String(
  159. PrintRoutine,
  160. pContext,
  161. pszHeader,
  162. pszString,
  163. (CharSet == DnsCharSetUnicode),
  164. pszTrailer );
  165. }
  166. VOID
  167. DnsPrint_UnicodeStringBytes(
  168. IN PRINT_ROUTINE PrintRoutine,
  169. IN OUT PPRINT_CONTEXT pContext,
  170. IN PSTR pszHeader,
  171. IN PWCHAR pUnicode,
  172. IN DWORD Length
  173. )
  174. /*++
  175. Routine Description:
  176. Print chars (WORDs) of unicode string.
  177. --*/
  178. {
  179. DWORD i;
  180. PrintRoutine(
  181. pContext,
  182. "%s\r\n"
  183. "\twide string %S\r\n"
  184. "\tlength %d\r\n"
  185. "\tbytes ",
  186. pszHeader,
  187. pUnicode,
  188. Length );
  189. for ( i=0; i<Length; i++ )
  190. {
  191. PrintRoutine(
  192. pContext,
  193. "%04hx ",
  194. pUnicode[i] );
  195. }
  196. printf( "\r\n" );
  197. }
  198. VOID
  199. DnsPrint_Utf8StringBytes(
  200. IN PRINT_ROUTINE PrintRoutine,
  201. IN OUT PPRINT_CONTEXT pContext,
  202. IN PSTR pszHeader,
  203. IN PCHAR pUtf8,
  204. IN DWORD Length
  205. )
  206. /*++
  207. Routine Description:
  208. Print bytes of UTF8 string.
  209. --*/
  210. {
  211. DWORD i;
  212. PrintRoutine(
  213. pContext,
  214. "%s\r\n"
  215. "\tUTF8 string %s\r\n"
  216. "\tlength %d\r\n"
  217. "\tbytes ",
  218. pszHeader,
  219. pUtf8,
  220. Length );
  221. for ( i=0; i<Length; i++ )
  222. {
  223. PrintRoutine(
  224. pContext,
  225. "%02x ",
  226. (UCHAR) pUtf8[i] );
  227. }
  228. printf( "\r\n" );
  229. }
  230. VOID
  231. DnsPrint_StringArray(
  232. IN PRINT_ROUTINE PrintRoutine,
  233. IN OUT PPRINT_CONTEXT pContext,
  234. IN PSTR pszHeader,
  235. IN PSTR * StringArray,
  236. IN DWORD Count, OPTIONAL
  237. IN BOOL fUnicode
  238. )
  239. /*++
  240. Routine Description:
  241. Print string array.
  242. --*/
  243. {
  244. DWORD i = 0;
  245. PCHAR pstr;
  246. if ( !pszHeader )
  247. {
  248. pszHeader = "StringArray:";
  249. }
  250. if ( !StringArray )
  251. {
  252. PrintRoutine(
  253. pContext,
  254. "%s NULL pointer!\r\n",
  255. pszHeader );
  256. }
  257. DnsPrint_Lock();
  258. if ( Count )
  259. {
  260. PrintRoutine(
  261. pContext,
  262. "%s Count = %d\r\n",
  263. pszHeader,
  264. Count );
  265. }
  266. else
  267. {
  268. PrintRoutine(
  269. pContext,
  270. "%s\r\n",
  271. pszHeader );
  272. }
  273. //
  274. // print args
  275. // - stop at Count (if given)
  276. // OR
  277. // - on NULL arg (if no count given)
  278. //
  279. while ( (!Count || i < Count) )
  280. {
  281. pstr = StringArray[i++];
  282. if ( !pstr && !Count )
  283. {
  284. break;
  285. }
  286. PrintRoutine(
  287. pContext,
  288. (fUnicode) ? "\t%S\r\n" : "\t%s\r\n",
  289. pstr );
  290. }
  291. DnsPrint_Unlock();
  292. }
  293. VOID
  294. DnsPrint_Argv(
  295. IN PRINT_ROUTINE PrintRoutine,
  296. IN OUT PPRINT_CONTEXT pContext,
  297. IN PSTR pszHeader,
  298. IN CHAR ** Argv,
  299. IN DWORD Argc, OPTIONAL
  300. IN BOOL fUnicode
  301. )
  302. /*++
  303. Routine Description:
  304. Print Argv array.
  305. --*/
  306. {
  307. //
  308. // this is just special case of string print
  309. //
  310. DnsPrint_StringArray(
  311. PrintRoutine,
  312. pContext,
  313. pszHeader
  314. ? pszHeader
  315. : "Argv:",
  316. Argv,
  317. Argc,
  318. fUnicode );
  319. }
  320. VOID
  321. DnsPrint_DwordArray(
  322. IN PRINT_ROUTINE PrintRoutine,
  323. IN OUT PPRINT_CONTEXT pContext,
  324. IN PSTR pszHeader,
  325. IN PSTR pszName,
  326. IN DWORD dwCount,
  327. IN PDWORD adwArray
  328. )
  329. /*++
  330. Routine Description:
  331. Print DWORD array.
  332. --*/
  333. {
  334. DWORD i;
  335. DnsPrint_Lock();
  336. if ( pszHeader )
  337. {
  338. PrintRoutine(
  339. pContext,
  340. pszHeader );
  341. }
  342. if ( !pszName )
  343. {
  344. pszName = "DWORD";
  345. }
  346. PrintRoutine(
  347. pContext,
  348. "%s Array Count = %d\r\n",
  349. pszName,
  350. dwCount );
  351. for( i=0; i<dwCount; i++ )
  352. {
  353. PrintRoutine(
  354. pContext,
  355. "\t%s[%d] => 0x%p (%d)\r\n",
  356. pszName,
  357. i,
  358. adwArray[i],
  359. adwArray[i] );
  360. }
  361. DnsPrint_Unlock();
  362. }
  363. VOID
  364. DnsPrint_Ip4AddressArray(
  365. IN PRINT_ROUTINE PrintRoutine,
  366. IN OUT PPRINT_CONTEXT pContext,
  367. IN PSTR pszHeader,
  368. IN PSTR pszName,
  369. IN DWORD dwIpAddrCount,
  370. IN PIP4_ADDRESS pIpAddrs
  371. )
  372. /*++
  373. Routine Description:
  374. Print IP address array.
  375. --*/
  376. {
  377. DWORD i;
  378. DnsPrint_Lock();
  379. if ( !pszName )
  380. {
  381. pszName = "IP Addr";
  382. }
  383. PrintRoutine(
  384. pContext,
  385. "%s Addr Count = %d\r\n",
  386. pszHeader ? pszHeader : "",
  387. dwIpAddrCount );
  388. if ( dwIpAddrCount != 0 && pIpAddrs != NULL )
  389. {
  390. // print array with count
  391. // use character print so works even if NOT DWORD aligned
  392. for( i=0; i<dwIpAddrCount; i++ )
  393. {
  394. PrintRoutine(
  395. pContext,
  396. "\t%s[%d] => %d.%d.%d.%d\r\n",
  397. pszName,
  398. i,
  399. * ( (PUCHAR) &pIpAddrs[i] + 0 ),
  400. * ( (PUCHAR) &pIpAddrs[i] + 1 ),
  401. * ( (PUCHAR) &pIpAddrs[i] + 2 ),
  402. * ( (PUCHAR) &pIpAddrs[i] + 3 ) );
  403. }
  404. }
  405. #if 0
  406. // this spins if printing zero length IP_ARRAY struct
  407. else if ( pIpAddrs != NULL )
  408. {
  409. // print NULL terminated array (ex. hostents IPs)
  410. i = 0;
  411. while ( pIpAddrs[i] )
  412. {
  413. PrintRoutine(
  414. pContext,
  415. "\t%s[%d] => %s\r\n",
  416. pszName,
  417. i,
  418. inet_ntoa( *(struct in_addr *) &pIpAddrs[i] ) );
  419. }
  420. }
  421. #endif
  422. DnsPrint_Unlock();
  423. }
  424. VOID
  425. DnsPrint_Ip4Array(
  426. IN PRINT_ROUTINE PrintRoutine,
  427. IN OUT PPRINT_CONTEXT pContext,
  428. IN PSTR pszHeader,
  429. IN PSTR pszName,
  430. IN PIP4_ARRAY pIpArray
  431. )
  432. /*++
  433. Routine Description:
  434. Print IP address array struct
  435. Just pass through to more generic print routine.
  436. --*/
  437. {
  438. // protect against NULL case
  439. if ( !pIpArray )
  440. {
  441. PrintRoutine(
  442. pContext,
  443. "%s\tNULL IP Array.\r\n",
  444. pszHeader ? pszHeader : "" );
  445. }
  446. // call uncoupled IP array routine
  447. else
  448. {
  449. DnsPrint_Ip4AddressArray(
  450. PrintRoutine,
  451. pContext,
  452. pszHeader,
  453. pszName,
  454. pIpArray->AddrCount,
  455. pIpArray->AddrArray );
  456. }
  457. }
  458. VOID
  459. DnsPrint_Ip6Address(
  460. IN PRINT_ROUTINE PrintRoutine,
  461. IN OUT PPRINT_CONTEXT pContext,
  462. IN PSTR pszHeader,
  463. IN PIP6_ADDRESS pIp6Addr,
  464. IN PSTR pszTrailer
  465. )
  466. /*++
  467. Routine Description:
  468. Print IP6 address.
  469. Arguments:
  470. PrintRoutine -- print routine to call
  471. pContext -- first argument to print routine
  472. pszHeader -- header to print
  473. NOTE: unlike other print routines this routine
  474. requires header to contain newline,tab, etc if
  475. multiline print is desired; the reason is to allow
  476. use of this routine for single line print
  477. pIp6Address -- ptr to IP6 address to print
  478. pszTrailer -- trailer to print
  479. NOTE: again this routine is designed to allow single
  480. line print; if newline required after print, send
  481. newline in trailer
  482. Return Value:
  483. Ptr to next location in buffer (the terminating NULL).
  484. --*/
  485. {
  486. CHAR buffer[ IP6_ADDRESS_STRING_BUFFER_LENGTH ];
  487. if ( !pszHeader )
  488. {
  489. pszHeader = "IP6 Addr: ";
  490. }
  491. if ( !pszTrailer )
  492. {
  493. pszTrailer = "\r\n";
  494. }
  495. if ( !pIp6Addr )
  496. {
  497. PrintRoutine(
  498. pContext,
  499. "%s NULL IP6 address ptr.%s",
  500. pszHeader,
  501. pszTrailer );
  502. return;
  503. }
  504. // convert IP6 address to string
  505. Dns_Ip6AddressToString_A(
  506. buffer,
  507. pIp6Addr );
  508. PrintRoutine(
  509. pContext,
  510. "%s%s%s",
  511. pszHeader,
  512. buffer,
  513. pszTrailer );
  514. }
  515. VOID
  516. DnsPrint_Ip6Array(
  517. IN PRINT_ROUTINE PrintRoutine,
  518. IN OUT PPRINT_CONTEXT pContext,
  519. IN PSTR pszHeader,
  520. IN PSTR pszName,
  521. IN PIP6_ARRAY pIpArray
  522. )
  523. /*++
  524. Routine Description:
  525. Print IP address array struct
  526. Just pass through to more generic print routine.
  527. --*/
  528. {
  529. DWORD i;
  530. CHAR buffer[ IP6_ADDRESS_STRING_BUFFER_LENGTH ];
  531. if ( !pszName )
  532. {
  533. pszName = "IP";
  534. }
  535. if ( !pszHeader )
  536. {
  537. pszHeader = "IP Array";
  538. }
  539. // protect against NULL case
  540. if ( !pIpArray )
  541. {
  542. PrintRoutine(
  543. pContext,
  544. "%s \tNULL IP Array.\n",
  545. pszHeader );
  546. return;
  547. }
  548. DnsPrint_Lock();
  549. PrintRoutine(
  550. pContext,
  551. "%s\n"
  552. "\tPtr = %p\n"
  553. "\tMaxCount = %d\n"
  554. "\tAddrCount = %d\n",
  555. pszHeader,
  556. pIpArray,
  557. pIpArray->MaxCount,
  558. pIpArray->AddrCount );
  559. for( i=0; i<pIpArray->AddrCount; i++ )
  560. {
  561. // convert IP6 address to string
  562. Dns_Ip6AddressToString_A(
  563. buffer,
  564. & pIpArray->AddrArray[i] );
  565. PrintRoutine(
  566. pContext,
  567. "\t%s[%d] => %s\n",
  568. pszName,
  569. i,
  570. buffer );
  571. }
  572. DnsPrint_Unlock();
  573. }
  574. //
  575. // Print routines for DNS types and structures
  576. //
  577. VOID
  578. DnsPrint_DnsAddrLine(
  579. IN PRINT_ROUTINE PrintRoutine,
  580. IN OUT PPRINT_CONTEXT pContext,
  581. IN PSTR pszHeader,
  582. IN PDNS_ADDR pAddr,
  583. IN PSTR pszTrailer
  584. )
  585. /*++
  586. Routine Description:
  587. Print DNS_ADDR
  588. Arguments:
  589. PrintRoutine -- print routine to call
  590. pContext -- first argument to print routine
  591. pszHeader -- header to print
  592. NOTE: unlike other print routines this routine
  593. requires header to contain newline,tab, etc if
  594. multiline print is desired; the reason is to allow
  595. use of this routine for single line print
  596. pDnsAddr -- ptr to addr to print
  597. pszTrailer -- trailer to print
  598. NOTE: again this routine is designed to allow single
  599. line print; if newline required after print, send
  600. newline in trailer
  601. Return Value:
  602. Ptr to next location in buffer (the terminating NULL).
  603. --*/
  604. {
  605. CHAR buffer[ DNS_ADDR_STRING_BUFFER_LENGTH ];
  606. if ( !pszHeader )
  607. {
  608. pszHeader = "DnsAddr: ";
  609. }
  610. if ( !pszTrailer )
  611. {
  612. pszTrailer = "\r\n";
  613. }
  614. if ( !pAddr )
  615. {
  616. PrintRoutine(
  617. pContext,
  618. "%s NULL DNS_ADDR ptr.%s",
  619. pszHeader,
  620. pszTrailer );
  621. return;
  622. }
  623. // convert DNS_ADDR to string
  624. DnsAddr_WriteStructString_A( buffer, pAddr );
  625. PrintRoutine(
  626. pContext,
  627. "%s%s%s",
  628. pszHeader,
  629. buffer,
  630. pszTrailer );
  631. }
  632. VOID
  633. DnsPrint_DnsAddr(
  634. IN PRINT_ROUTINE PrintRoutine,
  635. IN OUT PPRINT_CONTEXT pContext,
  636. IN PSTR pszHeader,
  637. IN DWORD Indent,
  638. IN PDNS_ADDR pSab
  639. )
  640. /*++
  641. Routine Description:
  642. Print sockaddr blob structure and length used in call.
  643. --*/
  644. {
  645. PSTR pindent = INDENT_STRING( Indent );
  646. if ( !pszHeader )
  647. {
  648. pszHeader = "Sockaddr Blob:";
  649. }
  650. if ( !pSab )
  651. {
  652. PrintRoutine(
  653. pContext,
  654. "%s%s\tNULL SockaddrBlob passed to print.\r\n",
  655. pindent,
  656. pszHeader );
  657. return;
  658. }
  659. DnsPrint_Lock();
  660. DnsPrint_Sockaddr(
  661. PrintRoutine,
  662. pContext,
  663. pszHeader,
  664. Indent,
  665. & pSab->Sockaddr,
  666. pSab->SockaddrLength
  667. );
  668. PrintRoutine(
  669. pContext,
  670. "%s\tsockaddr len = %d\n"
  671. "%s\tprefix len = %d\n"
  672. "%s\tflags = %08x\n"
  673. "%s\tstatus = %d\n"
  674. "%s\tpriority = %d\n",
  675. pindent, pSab->SockaddrLength,
  676. pindent, pSab->SubnetLength,
  677. pindent, pSab->Flags,
  678. pindent, pSab->Status,
  679. pindent, pSab->Priority );
  680. DnsPrint_Unlock();
  681. }
  682. VOID
  683. DnsPrint_DnsAddrArray(
  684. IN PRINT_ROUTINE PrintRoutine,
  685. IN OUT PPRINT_CONTEXT pContext,
  686. IN PSTR pszHeader,
  687. IN PSTR pszName,
  688. IN PDNS_ADDR_ARRAY pArray
  689. )
  690. /*++
  691. Routine Description:
  692. Print IP address array struct
  693. Just pass through to more generic print routine.
  694. --*/
  695. {
  696. DWORD i;
  697. CHAR buffer[ DNS_ADDR_STRING_BUFFER_LENGTH ];
  698. if ( !pszName )
  699. {
  700. pszName = "Addr";
  701. }
  702. if ( !pszHeader )
  703. {
  704. pszHeader = "IP Array";
  705. }
  706. // protect against NULL case
  707. if ( !pArray )
  708. {
  709. PrintRoutine(
  710. pContext,
  711. "%s \tNULL IP Array.\n",
  712. pszHeader );
  713. return;
  714. }
  715. DnsPrint_Lock();
  716. PrintRoutine(
  717. pContext,
  718. "%s\n"
  719. "\tPtr = %p\n"
  720. "\tMaxCount = %d\n"
  721. "\tAddrCount = %d\n",
  722. pszHeader,
  723. pArray,
  724. pArray->MaxCount,
  725. pArray->AddrCount );
  726. for( i=0; i<pArray->AddrCount; i++ )
  727. {
  728. // convert DNS_ADDR to string
  729. DnsAddr_WriteStructString_A(
  730. buffer,
  731. & pArray->AddrArray[i] );
  732. PrintRoutine(
  733. pContext,
  734. "\t%s[%d] => %s\n",
  735. pszName,
  736. i,
  737. buffer );
  738. }
  739. DnsPrint_Unlock();
  740. }
  741. //
  742. // DNS message stuff
  743. //
  744. INT
  745. Dns_WritePacketNameToBuffer(
  746. OUT PCHAR pBuffer,
  747. OUT PCHAR * ppBufferOut,
  748. IN PBYTE pMsgName,
  749. IN PDNS_HEADER pMsgHead, OPTIONAL
  750. IN PBYTE pMsgEnd OPTIONAL
  751. )
  752. /*++
  753. Routine Description:
  754. Write packet name into buffer.
  755. Arguments:
  756. pBuffer - buffer to print to, MUST be twice DNS_MAX_NAME_LENGTH
  757. to avoid overflows on bad packets
  758. ppBufferOut - ptr to terminating NULL in buffer conversion, this
  759. is position at which additional printing to buffer
  760. could resume
  761. pMsgName - ptr to name in packet to print
  762. pMsgHead - ptr to DNS message; need for offsetting, if not given
  763. names are not printed past first offset
  764. pMsgEnd - ptr to end of message, specifically byte immediately after
  765. message
  766. Return Value:
  767. Count of bytes in packet name occupied.
  768. This offset from pMsgName is the next field in the packet.
  769. Zero return indicates error in message name.
  770. --*/
  771. {
  772. register PUCHAR pchbuf;
  773. register PUCHAR pchmsg;
  774. register UCHAR cch;
  775. PCHAR pbufStop;
  776. PCHAR pnextLabel;
  777. UCHAR compressionType;
  778. WORD offset;
  779. PCHAR pbyteAfterFirstOffset = NULL;
  780. //
  781. // no message end specified?
  782. // make it max ptr so we can do single test for ptr validity
  783. // rather than testing for pMsgEnd existence first
  784. //
  785. if ( !pMsgEnd )
  786. {
  787. pMsgEnd = (PVOID)(INT_PTR)(-1);
  788. }
  789. //
  790. // loop until copy as printable name, or hit compression or name error
  791. //
  792. // buffer must be twice max label length
  793. // - allow extra chars for label length byte and compression printing
  794. // - but stop printing when within a label of end as label (or error
  795. // message) is copied in one blob without end check
  796. //
  797. pchbuf = pBuffer;
  798. pbufStop = pchbuf + 2*DNS_MAX_NAME_LENGTH - DNS_MAX_LABEL_LENGTH - 10;
  799. pchmsg = pMsgName;
  800. while ( 1 )
  801. {
  802. // bounds checking to survive bad packet
  803. //
  804. // DEVNOTE: note this is not strictly a bad packet (could be just a
  805. // heck of a lot of labels) and we could
  806. // a) let packet processing proceed without printing
  807. // or
  808. // b) require buffer that could contain max legal DNS name
  809. // but not worth the effort
  810. if ( pchbuf >= pbufStop )
  811. {
  812. pchbuf += sprintf(
  813. pchbuf,
  814. "[ERROR name exceeds safe print buffer length]\r\n" );
  815. pchmsg = pMsgName;
  816. break;
  817. }
  818. cch = (UCHAR) *pchmsg++;
  819. compressionType = cch & 0xC0;
  820. DNSDBG( OFF, (
  821. "byte = (%d) (0x%02x)\r\n"
  822. "compress flag = (%d) (0x%02x)\r\n",
  823. cch, cch,
  824. compressionType, compressionType ));
  825. //
  826. // normal length byte
  827. // - write length field
  828. // - copy label to print buffer
  829. //
  830. if ( compressionType == 0 )
  831. {
  832. pchbuf += sprintf( pchbuf, "(%d)", (INT)cch );
  833. // terminate at root name
  834. if ( ! cch )
  835. {
  836. break;
  837. }
  838. // check that within packet
  839. pnextLabel = pchmsg + cch;
  840. if ( pnextLabel >= pMsgEnd )
  841. {
  842. pchbuf += sprintf(
  843. pchbuf,
  844. "[ERROR length byte: 0x%02X at %p leads outside message]\r\n",
  845. cch,
  846. pchmsg );
  847. // force zero byte return
  848. pchmsg = pMsgName;
  849. break;
  850. }
  851. // copy label to output string
  852. memcpy(
  853. pchbuf,
  854. pchmsg,
  855. cch );
  856. pchbuf += cch;
  857. pchmsg = pnextLabel;
  858. continue;
  859. }
  860. //
  861. // valid compression
  862. //
  863. else if ( compressionType == (UCHAR)0xC0 )
  864. {
  865. // check that compression word not straddling message end
  866. if ( pchmsg >= pMsgEnd )
  867. {
  868. pchbuf += sprintf(
  869. pchbuf,
  870. "[ERROR compression word at %p is outside message]\r\n",
  871. pchmsg );
  872. // force zero byte return
  873. pchmsg = pMsgName;
  874. break;
  875. }
  876. // calculate offset
  877. offset = cch; // high byte
  878. offset <<= 8;
  879. offset |= *pchmsg++; // low byte
  880. pchbuf += sprintf(
  881. pchbuf,
  882. "[%04hX]",
  883. offset );
  884. if ( pMsgHead )
  885. {
  886. //
  887. // on first compression, save ptr to byte immediately after
  888. // name, so can calculate next byte
  889. //
  890. // save ptr to next byte in mess, to calculate actual length
  891. // name takes up in packet
  892. //
  893. if ( ! pbyteAfterFirstOffset )
  894. {
  895. pbyteAfterFirstOffset = pchmsg;
  896. }
  897. //
  898. // jump to offset for continuation of name
  899. // - clear two highest bits to get length
  900. //
  901. offset = offset ^ 0xC000;
  902. DNS_ASSERT( (offset & 0xC000) == 0 );
  903. pnextLabel = (PCHAR)pMsgHead + offset;
  904. if ( pnextLabel >= pchmsg - sizeof(WORD) )
  905. {
  906. pchbuf += sprintf(
  907. pchbuf,
  908. "[ERROR offset at %p to higher byte in packet %p]\r\n",
  909. pchmsg - sizeof(WORD),
  910. pnextLabel );
  911. break;
  912. }
  913. pchmsg = pnextLabel;
  914. continue;
  915. }
  916. // if no ptr to message head, can not continue at offset
  917. // NULL terminate previous label
  918. else
  919. {
  920. *pchbuf++ = 0;
  921. break;
  922. }
  923. }
  924. //
  925. // invalid compression
  926. // - force zero byte return to indicate error
  927. else
  928. {
  929. pchbuf += sprintf(
  930. pchbuf,
  931. "[ERROR length byte: 0x%02X]",
  932. cch );
  933. pchmsg = pMsgName;
  934. break;
  935. }
  936. }
  937. //
  938. // return ptr to next position in output buffer
  939. //
  940. if ( ppBufferOut )
  941. {
  942. *ppBufferOut = pchbuf;
  943. }
  944. //
  945. // return number of bytes read from message
  946. //
  947. if ( pbyteAfterFirstOffset )
  948. {
  949. pchmsg = pbyteAfterFirstOffset;
  950. }
  951. return (INT)( pchmsg - pMsgName );
  952. }
  953. INT
  954. DnsPrint_PacketName(
  955. IN PRINT_ROUTINE PrintRoutine,
  956. IN OUT PPRINT_CONTEXT pContext,
  957. IN PSTR pszHeader, OPTIONAL
  958. IN PBYTE pMsgName,
  959. IN PDNS_HEADER pMsgHead, OPTIONAL
  960. IN PBYTE pMsgEnd, OPTIONAL
  961. IN PSTR pszTrailer OPTIONAL
  962. )
  963. /*++
  964. Routine Description:
  965. Print DNS name given in packet format.
  966. Arguments:
  967. PrintRoutine - routine to print with
  968. pszHeader - header to print
  969. pMsgHead - ptr to DNS message; need for offsetting, if not given
  970. names are not printed past first offset
  971. pMsgName - ptr to name in packet to print
  972. pMsgEnd - ptr to end of message; OPTIONAL, but needed to protect
  973. against AV accessing bad packet names
  974. pszTrailer - trailer to print after name
  975. Return Value:
  976. Count of bytes in packet name occupied.
  977. This offset from pMsgName is the next field in the packet.
  978. Zero return indicates error in message name.
  979. --*/
  980. {
  981. INT countNameBytes;
  982. // name buffer, allow space for full name, plus parens on length
  983. // fields plus several compression flags
  984. CHAR PrintName[ 2*DNS_MAX_NAME_LENGTH ];
  985. if ( ! pMsgName )
  986. {
  987. PrintRoutine(
  988. pContext,
  989. "%s(NULL packet name ptr)%s\r\n",
  990. pszHeader ? pszHeader : "",
  991. pszTrailer ? pszTrailer : ""
  992. );
  993. return 0;
  994. }
  995. //
  996. // build packet name into buffer, then print
  997. //
  998. countNameBytes = Dns_WritePacketNameToBuffer(
  999. PrintName,
  1000. NULL,
  1001. pMsgName,
  1002. pMsgHead,
  1003. pMsgEnd
  1004. );
  1005. PrintRoutine(
  1006. pContext,
  1007. "%s%s%s",
  1008. pszHeader ? pszHeader : "",
  1009. PrintName,
  1010. pszTrailer ? pszTrailer : ""
  1011. );
  1012. return( countNameBytes );
  1013. }
  1014. VOID
  1015. DnsPrint_Message(
  1016. IN PRINT_ROUTINE PrintRoutine,
  1017. IN OUT PPRINT_CONTEXT pContext,
  1018. IN PSTR pszHeader,
  1019. IN PDNS_MSG_BUF pMsg
  1020. )
  1021. /*++
  1022. Routine Description:
  1023. Print DNS message buffer.
  1024. Includes context information as well as actual DNS message.
  1025. --*/
  1026. {
  1027. PDNS_HEADER pmsgHeader;
  1028. PCHAR pchRecord;
  1029. PBYTE pmsgEnd;
  1030. INT i;
  1031. INT isection;
  1032. INT cchName;
  1033. WORD wLength;
  1034. WORD wOffset;
  1035. WORD wXid;
  1036. WORD wQuestionCount;
  1037. WORD wAnswerCount;
  1038. WORD wNameServerCount;
  1039. WORD wAdditionalCount;
  1040. WORD countSectionRR;
  1041. BOOL fFlipped = FALSE;
  1042. DnsPrint_Lock();
  1043. if ( pszHeader )
  1044. {
  1045. PrintRoutine(
  1046. pContext,
  1047. "%s\r\n",
  1048. pszHeader );
  1049. }
  1050. // get message info
  1051. //
  1052. // note: length may not be correctly set while building message,
  1053. // so make pmsgEnd greater of given length and pCurrent ptr
  1054. // but allow for case where set back to pre-OPT length
  1055. //
  1056. wLength = pMsg->MessageLength;
  1057. pmsgHeader = &pMsg->MessageHead;
  1058. pmsgEnd = ((PBYTE)pmsgHeader) + wLength;
  1059. if ( pmsgEnd < pMsg->pCurrent &&
  1060. pmsgEnd != pMsg->pPreOptEnd )
  1061. {
  1062. pmsgEnd = pMsg->pCurrent;
  1063. }
  1064. //
  1065. // print header info
  1066. //
  1067. PrintRoutine(
  1068. pContext,
  1069. "%s %s info at %p\r\n"
  1070. " Socket = %d 4=%d 6=%d\r\n"
  1071. " Remote addr %s\r\n"
  1072. " fam = %d\n"
  1073. " port = %d\n"
  1074. " len = %d\n"
  1075. " Buf length = 0x%04x\r\n"
  1076. " Msg length = 0x%04x\r\n"
  1077. " Message:\r\n",
  1078. ( pMsg->fTcp
  1079. ? "TCP"
  1080. : "UDP" ),
  1081. ( pmsgHeader->IsResponse
  1082. ? "response"
  1083. : "question" ),
  1084. pMsg,
  1085. pMsg->Socket,
  1086. pMsg->Socket4,
  1087. pMsg->Socket6,
  1088. MSG_REMOTE_IPADDR_STRING( pMsg ),
  1089. MSG_REMOTE_FAMILY( pMsg ),
  1090. MSG_REMOTE_IP_PORT( pMsg ),
  1091. pMsg->RemoteAddress.SockaddrLength,
  1092. pMsg->BufferLength,
  1093. wLength
  1094. );
  1095. PrintRoutine(
  1096. pContext,
  1097. " XID 0x%04hx\r\n"
  1098. " Flags 0x%04hx\r\n"
  1099. " QR 0x%lx (%s)\r\n"
  1100. " OPCODE 0x%lx (%s)\r\n"
  1101. " AA 0x%lx\r\n"
  1102. " TC 0x%lx\r\n"
  1103. " RD 0x%lx\r\n"
  1104. " RA 0x%lx\r\n"
  1105. " Z 0x%lx\r\n"
  1106. " RCODE 0x%lx (%s)\r\n"
  1107. " QCOUNT 0x%hx\r\n"
  1108. " ACOUNT 0x%hx\r\n"
  1109. " NSCOUNT 0x%hx\r\n"
  1110. " ARCOUNT 0x%hx\r\n",
  1111. pmsgHeader->Xid,
  1112. ntohs((*((PWORD)pmsgHeader + 1))),
  1113. pmsgHeader->IsResponse,
  1114. (pmsgHeader->IsResponse ? "response" : "question"),
  1115. pmsgHeader->Opcode,
  1116. Dns_OpcodeString( pmsgHeader->Opcode ),
  1117. pmsgHeader->Authoritative,
  1118. pmsgHeader->Truncation,
  1119. pmsgHeader->RecursionDesired,
  1120. pmsgHeader->RecursionAvailable,
  1121. pmsgHeader->Reserved,
  1122. pmsgHeader->ResponseCode,
  1123. Dns_ResponseCodeString( pmsgHeader->ResponseCode ),
  1124. pmsgHeader->QuestionCount,
  1125. pmsgHeader->AnswerCount,
  1126. pmsgHeader->NameServerCount,
  1127. pmsgHeader->AdditionalCount );
  1128. //
  1129. // determine if byte flipped and get correct count
  1130. //
  1131. wXid = pmsgHeader->Xid;
  1132. wQuestionCount = pmsgHeader->QuestionCount;
  1133. wAnswerCount = pmsgHeader->AnswerCount;
  1134. wNameServerCount = pmsgHeader->NameServerCount;
  1135. wAdditionalCount = pmsgHeader->AdditionalCount;
  1136. if ( wQuestionCount )
  1137. {
  1138. fFlipped = wQuestionCount & 0xff00;
  1139. }
  1140. else if ( wNameServerCount )
  1141. {
  1142. fFlipped = wNameServerCount & 0xff00;
  1143. }
  1144. if ( fFlipped )
  1145. {
  1146. wXid = ntohs( wXid );
  1147. wQuestionCount = ntohs( wQuestionCount );
  1148. wAnswerCount = ntohs( wAnswerCount );
  1149. wNameServerCount = ntohs( wNameServerCount );
  1150. wAdditionalCount = ntohs( wAdditionalCount );
  1151. }
  1152. //
  1153. // catch record flipping problems -- all are flipped or none at all
  1154. // and no record count should be > 256 EXCEPT answer count
  1155. // during FAST zone transfer
  1156. //
  1157. DNS_ASSERT( ! (wQuestionCount & 0xff00) );
  1158. DNS_ASSERT( ! (wNameServerCount & 0xff00) );
  1159. DNS_ASSERT( ! (wAdditionalCount & 0xff00) );
  1160. #if 0
  1161. //
  1162. // stop here if WINS response -- don't have parsing ready
  1163. //
  1164. if ( pmsgHeader->IsResponse && IS_WINS_XID(wXid) )
  1165. {
  1166. PrintRoutine(
  1167. pContext,
  1168. " WINS Response packet.\r\n\r\n" );
  1169. goto Unlock;
  1170. }
  1171. #endif
  1172. //
  1173. // print questions and resource records
  1174. //
  1175. pchRecord = (PCHAR)(pmsgHeader + 1);
  1176. for ( isection=0; isection<4; isection++)
  1177. {
  1178. PrintRoutine(
  1179. pContext,
  1180. " %s Section:\r\n",
  1181. Dns_SectionNameString( isection, pmsgHeader->Opcode ) );
  1182. if ( isection==0 )
  1183. {
  1184. countSectionRR = wQuestionCount;
  1185. }
  1186. else if ( isection==1 )
  1187. {
  1188. countSectionRR = wAnswerCount;
  1189. }
  1190. else if ( isection==2 )
  1191. {
  1192. countSectionRR = wNameServerCount;
  1193. }
  1194. else if ( isection==3 )
  1195. {
  1196. countSectionRR = wAdditionalCount;
  1197. }
  1198. for ( i=0; i < countSectionRR; i++ )
  1199. {
  1200. //
  1201. // verify not overrunning length
  1202. // - check against pCurrent as well as message length
  1203. // so can print packets while being built
  1204. //
  1205. wOffset = (WORD)(pchRecord - (PCHAR)pmsgHeader);
  1206. if ( wOffset >= wLength
  1207. &&
  1208. pchRecord >= pMsg->pCurrent )
  1209. {
  1210. PrintRoutine(
  1211. pContext,
  1212. "ERROR: BOGUS PACKET:\r\n"
  1213. "\tFollowing RR (offset %d) past packet length (%d).\r\n",
  1214. wOffset,
  1215. wLength
  1216. );
  1217. goto Unlock;
  1218. }
  1219. //
  1220. // print RR name
  1221. //
  1222. PrintRoutine(
  1223. pContext,
  1224. " Name Offset = 0x%04x\r\n",
  1225. wOffset
  1226. );
  1227. cchName = DnsPrint_PacketName(
  1228. PrintRoutine,
  1229. pContext,
  1230. " Name \"",
  1231. pchRecord,
  1232. pmsgHeader,
  1233. pmsgEnd,
  1234. "\"\r\n" );
  1235. if ( ! cchName )
  1236. {
  1237. PrintRoutine(
  1238. pContext,
  1239. "ERROR: Invalid name length, stop packet print\r\n" );
  1240. DNS_ASSERT( FALSE );
  1241. break;
  1242. }
  1243. pchRecord += cchName;
  1244. // print question or resource record
  1245. if ( isection == 0 )
  1246. {
  1247. PrintRoutine(
  1248. pContext,
  1249. " QTYPE %d\r\n"
  1250. " QCLASS %d\r\n",
  1251. FlipUnalignedWord( pchRecord ),
  1252. FlipUnalignedWord( pchRecord + sizeof(WORD) )
  1253. );
  1254. pchRecord += sizeof( DNS_WIRE_QUESTION );
  1255. }
  1256. else
  1257. {
  1258. pchRecord += DnsPrint_PacketRecord(
  1259. PrintRoutine,
  1260. pContext,
  1261. NULL,
  1262. (PDNS_WIRE_RECORD) pchRecord,
  1263. pmsgHeader,
  1264. pmsgEnd
  1265. );
  1266. }
  1267. }
  1268. }
  1269. // check that at proper end of packet
  1270. wOffset = (WORD)(pchRecord - (PCHAR)pmsgHeader);
  1271. if ( pchRecord < pMsg->pCurrent || wOffset < wLength )
  1272. {
  1273. PrintRoutine(
  1274. pContext,
  1275. "WARNING: message continues beyond these records\r\n"
  1276. "\tpch = %p, pCurrent = %p, %d bytes\r\n"
  1277. "\toffset = %d, msg length = %d, %d bytes\r\n",
  1278. pchRecord,
  1279. pMsg->pCurrent,
  1280. pMsg->pCurrent - pchRecord,
  1281. wOffset,
  1282. wLength,
  1283. wLength - wOffset );
  1284. }
  1285. PrintRoutine(
  1286. pContext,
  1287. " Message length = %04x\n\r\n",
  1288. wOffset );
  1289. Unlock:
  1290. DnsPrint_Unlock();
  1291. } // DnsPrint_Message
  1292. INT
  1293. DnsPrint_PacketRecord(
  1294. IN PRINT_ROUTINE PrintRoutine,
  1295. IN OUT PPRINT_CONTEXT pContext,
  1296. IN PSTR pszHeader,
  1297. IN PDNS_WIRE_RECORD pMsgRR,
  1298. IN PDNS_HEADER pMsgHead, OPTIONAL
  1299. IN PBYTE pMsgEnd OPTIONAL
  1300. )
  1301. /*++
  1302. Routine Description:
  1303. Print RR in packet format.
  1304. Arguments:
  1305. pszHeader - Header message/name for RR.
  1306. pMsgRR - resource record to print
  1307. pMsgHead - ptr to DNS message; need for offsetting, if not given
  1308. names are not printed past first offset
  1309. pMsgEnd - ptr to end of message, specifically byte immediately after
  1310. message
  1311. Return Value:
  1312. Number of bytes in record.
  1313. --*/
  1314. {
  1315. PCHAR pdata = (PCHAR)(pMsgRR + 1);
  1316. PCHAR pdataStop;
  1317. WORD dlen = FlipUnalignedWord( &pMsgRR->DataLength );
  1318. WORD type;
  1319. PCHAR pRRString;
  1320. DnsPrint_Lock();
  1321. //
  1322. // print RR fixed fields
  1323. //
  1324. type = FlipUnalignedWord( &pMsgRR->RecordType );
  1325. pRRString = Dns_RecordStringForType( type );
  1326. if ( pszHeader )
  1327. {
  1328. PrintRoutine(
  1329. pContext,
  1330. "%s\r\n",
  1331. pszHeader );
  1332. }
  1333. PrintRoutine(
  1334. pContext,
  1335. " TYPE %s (%u)\r\n"
  1336. " CLASS %u\r\n"
  1337. " TTL %lu\r\n"
  1338. " DLEN %u\r\n"
  1339. " DATA ",
  1340. pRRString,
  1341. type,
  1342. FlipUnalignedWord( &pMsgRR->RecordClass ),
  1343. FlipUnalignedDword( &pMsgRR->TimeToLive ),
  1344. dlen );
  1345. //
  1346. // update records may not have data
  1347. //
  1348. if ( dlen == 0 )
  1349. {
  1350. PrintRoutine(
  1351. pContext,
  1352. "(none)\r\n" );
  1353. goto Done;
  1354. }
  1355. // stop byte after RR data
  1356. pdataStop = pdata + dlen;
  1357. if ( pMsgEnd < pdataStop )
  1358. {
  1359. PrintRoutine(
  1360. pContext,
  1361. "ERROR: record at %p extends past end of packet!\n"
  1362. "\tpmsg = %p\n"
  1363. "\tpmsgEnd = %p\n"
  1364. "\trecord end = %p\n",
  1365. pMsgRR,
  1366. pMsgHead,
  1367. pMsgEnd,
  1368. pdataStop );
  1369. goto Done;
  1370. }
  1371. //
  1372. // print RR data
  1373. //
  1374. switch ( type )
  1375. {
  1376. case DNS_TYPE_A:
  1377. PrintRoutine(
  1378. pContext,
  1379. "%d.%d.%d.%d\r\n",
  1380. * (PUCHAR)( pdata + 0 ),
  1381. * (PUCHAR)( pdata + 1 ),
  1382. * (PUCHAR)( pdata + 2 ),
  1383. * (PUCHAR)( pdata + 3 )
  1384. );
  1385. break;
  1386. case DNS_TYPE_AAAA:
  1387. {
  1388. IP6_ADDRESS ip6;
  1389. RtlCopyMemory(
  1390. &ip6,
  1391. pdata,
  1392. sizeof(ip6) );
  1393. PrintRoutine(
  1394. pContext,
  1395. "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
  1396. ip6.IP6Word[0],
  1397. ip6.IP6Word[1],
  1398. ip6.IP6Word[2],
  1399. ip6.IP6Word[3],
  1400. ip6.IP6Word[4],
  1401. ip6.IP6Word[5],
  1402. ip6.IP6Word[6],
  1403. ip6.IP6Word[7]
  1404. );
  1405. break;
  1406. }
  1407. case DNS_TYPE_PTR:
  1408. case DNS_TYPE_NS:
  1409. case DNS_TYPE_CNAME:
  1410. case DNS_TYPE_MD:
  1411. case DNS_TYPE_MB:
  1412. case DNS_TYPE_MF:
  1413. case DNS_TYPE_MG:
  1414. case DNS_TYPE_MR:
  1415. //
  1416. // these RRs contain single domain name
  1417. //
  1418. DnsPrint_PacketName(
  1419. PrintRoutine,
  1420. pContext,
  1421. NULL,
  1422. pdata,
  1423. pMsgHead,
  1424. pMsgEnd,
  1425. "\r\n" );
  1426. break;
  1427. case DNS_TYPE_MX:
  1428. case DNS_TYPE_RT:
  1429. case DNS_TYPE_AFSDB:
  1430. //
  1431. // these RR contain
  1432. // - one preference value
  1433. // - one domain name
  1434. //
  1435. PrintRoutine(
  1436. pContext,
  1437. "%d ",
  1438. FlipUnalignedWord( pdata )
  1439. );
  1440. DnsPrint_PacketName(
  1441. PrintRoutine,
  1442. pContext,
  1443. NULL,
  1444. pdata + sizeof(WORD),
  1445. pMsgHead,
  1446. pMsgEnd,
  1447. "\r\n" );
  1448. break;
  1449. case DNS_TYPE_SOA:
  1450. pdata += DnsPrint_PacketName(
  1451. PrintRoutine,
  1452. pContext,
  1453. "\r\n\t\tPrimaryServer: ",
  1454. pdata,
  1455. pMsgHead,
  1456. pMsgEnd,
  1457. NULL );
  1458. pdata += DnsPrint_PacketName(
  1459. PrintRoutine,
  1460. pContext,
  1461. "\r\n\t\tAdministrator: ",
  1462. pdata,
  1463. pMsgHead,
  1464. pMsgEnd,
  1465. "\r\n" );
  1466. PrintRoutine(
  1467. pContext,
  1468. "\t\tSerialNo = %d\r\n"
  1469. "\t\tRefresh = %d\r\n"
  1470. "\t\tRetry = %d\r\n"
  1471. "\t\tExpire = %d\r\n"
  1472. "\t\tMinimumTTL = %d\r\n",
  1473. FlipUnalignedDword( pdata ),
  1474. FlipUnalignedDword( (PDWORD)pdata+1 ),
  1475. FlipUnalignedDword( (PDWORD)pdata+2 ),
  1476. FlipUnalignedDword( (PDWORD)pdata+3 ),
  1477. FlipUnalignedDword( (PDWORD)pdata+4 )
  1478. );
  1479. break;
  1480. case DNS_TYPE_MINFO:
  1481. case DNS_TYPE_RP:
  1482. //
  1483. // these RRs contain two domain names
  1484. //
  1485. pdata += DnsPrint_PacketName(
  1486. PrintRoutine,
  1487. pContext,
  1488. NULL,
  1489. pdata,
  1490. pMsgHead,
  1491. pMsgEnd,
  1492. NULL );
  1493. DnsPrint_PacketName(
  1494. PrintRoutine,
  1495. pContext,
  1496. " ",
  1497. pdata,
  1498. pMsgHead,
  1499. pMsgEnd,
  1500. "\r\n" );
  1501. break;
  1502. case DNS_TYPE_TEXT:
  1503. case DNS_TYPE_HINFO:
  1504. case DNS_TYPE_ISDN:
  1505. case DNS_TYPE_X25:
  1506. {
  1507. //
  1508. // all these are simply text string(s)
  1509. //
  1510. PCHAR pch = pdata;
  1511. PCHAR pchStop = pch + dlen;
  1512. UCHAR cch;
  1513. while ( pch < pchStop )
  1514. {
  1515. cch = (UCHAR) *pch++;
  1516. PrintRoutine(
  1517. pContext,
  1518. "\t%.*s\r\n",
  1519. cch,
  1520. pch );
  1521. pch += cch;
  1522. }
  1523. if ( pch != pchStop )
  1524. {
  1525. PrintRoutine(
  1526. pContext,
  1527. "ERROR: Bad RR. "
  1528. "Text strings do not add to RR length.\r\n" );
  1529. }
  1530. break;
  1531. }
  1532. case DNS_TYPE_WKS:
  1533. {
  1534. INT i;
  1535. PrintRoutine(
  1536. pContext,
  1537. "WKS: Address %d.%d.%d.%d\r\n"
  1538. "\t\tProtocol %d\r\n"
  1539. "\t\tBitmask\r\n",
  1540. * (PUCHAR)( pdata + 0 ),
  1541. * (PUCHAR)( pdata + 1 ),
  1542. * (PUCHAR)( pdata + 2 ),
  1543. * (PUCHAR)( pdata + 3 ),
  1544. * (PUCHAR)( pdata + 4 ) );
  1545. pdata += SIZEOF_WKS_FIXED_DATA;
  1546. for ( i=0; i < (INT)(dlen-SIZEOF_WKS_FIXED_DATA); i++ )
  1547. {
  1548. PrintRoutine(
  1549. pContext,
  1550. "\t\t\tbyte[%d] = %x\r\n",
  1551. i,
  1552. (UCHAR) pdata[i] );
  1553. }
  1554. break;
  1555. }
  1556. case DNS_TYPE_NULL:
  1557. DnsPrint_RawOctets(
  1558. PrintRoutine,
  1559. pContext,
  1560. NULL,
  1561. "\t\t",
  1562. pdata,
  1563. dlen );
  1564. break;
  1565. case DNS_TYPE_SRV:
  1566. // SRV <priority> <weight> <port> <target host>
  1567. PrintRoutine(
  1568. pContext,
  1569. "\t\tPriority = %d\r\n"
  1570. "\t\tWeight = %d\r\n"
  1571. "\t\tPort = %d\r\n",
  1572. FlipUnalignedWord( pdata ),
  1573. FlipUnalignedWord( (PWORD)pdata+1 ),
  1574. FlipUnalignedWord( (PWORD)pdata+2 )
  1575. );
  1576. DnsPrint_PacketName(
  1577. PrintRoutine,
  1578. pContext,
  1579. "\t\tTarget host ",
  1580. pdata + 3*sizeof(WORD),
  1581. pMsgHead,
  1582. pMsgEnd,
  1583. "\r\n" );
  1584. break;
  1585. case DNS_TYPE_OPT:
  1586. //
  1587. // OPT
  1588. // - RR class is buffer size
  1589. // - RR TTL contains
  1590. // <extended RCODE> low byte
  1591. // <version> second byte
  1592. // <flags-zero> high word
  1593. //
  1594. {
  1595. BYTE version;
  1596. BYTE extendedRcode;
  1597. DWORD fullRcode = 0;
  1598. WORD flags;
  1599. extendedRcode = *( (PBYTE) &pMsgRR->TimeToLive );
  1600. version = *( (PBYTE) &pMsgRR->TimeToLive + 1 );
  1601. flags = *( (PWORD) &pMsgRR->TimeToLive + 1 );
  1602. if ( pMsgHead->ResponseCode )
  1603. {
  1604. fullRcode = ((DWORD)extendedRcode << 4) +
  1605. (DWORD)pMsgHead->ResponseCode;
  1606. }
  1607. PrintRoutine(
  1608. pContext,
  1609. "\t\tBuffer Size = %d\r\n"
  1610. "\t\tRcode Ext = %d (%x)\r\n"
  1611. "\t\tRcode Full = %d\r\n"
  1612. "\t\tVersion = %d\r\n"
  1613. "\t\tFlags = %x\r\n",
  1614. FlipUnalignedWord( &pMsgRR->RecordClass ),
  1615. extendedRcode, extendedRcode,
  1616. fullRcode,
  1617. version,
  1618. flags );
  1619. }
  1620. break;
  1621. case DNS_TYPE_TKEY:
  1622. {
  1623. DWORD beginTime;
  1624. DWORD expireTime;
  1625. WORD keyLength;
  1626. WORD mode;
  1627. WORD extRcode;
  1628. WORD otherLength;
  1629. otherLength = (WORD)DnsPrint_PacketName(
  1630. PrintRoutine,
  1631. pContext,
  1632. "\r\n\t\tAlgorithm: ",
  1633. pdata,
  1634. pMsgHead,
  1635. pMsgEnd,
  1636. NULL );
  1637. if ( !otherLength )
  1638. {
  1639. PrintRoutine(
  1640. pContext,
  1641. "Invalid algorithm name in TKEY RR!\r\n" );
  1642. }
  1643. pdata += otherLength;
  1644. beginTime = InlineFlipUnalignedDword( pdata );
  1645. pdata += sizeof(DWORD);
  1646. expireTime = InlineFlipUnalignedDword( pdata );
  1647. pdata += sizeof(DWORD);
  1648. mode = InlineFlipUnalignedWord( pdata );
  1649. pdata += sizeof(WORD);
  1650. extRcode = InlineFlipUnalignedWord( pdata );
  1651. pdata += sizeof(WORD);
  1652. keyLength = InlineFlipUnalignedWord( pdata );
  1653. pdata += sizeof(WORD);
  1654. PrintRoutine(
  1655. pContext,
  1656. "\r\n"
  1657. "\t\tCreate time = %d\r\n"
  1658. "\t\tExpire time = %d\r\n"
  1659. "\t\tMode = %d\r\n"
  1660. "\t\tExtended RCODE = %d\r\n"
  1661. "\t\tKey Length = %d\r\n",
  1662. beginTime,
  1663. expireTime,
  1664. mode,
  1665. extRcode,
  1666. keyLength );
  1667. if ( pdata + keyLength > pdataStop )
  1668. {
  1669. PrintRoutine(
  1670. pContext,
  1671. "Invalid key length: exceeds record data!\r\n" );
  1672. break;
  1673. }
  1674. DnsPrint_RawOctets(
  1675. PrintRoutine,
  1676. pContext,
  1677. "\t\tKey:",
  1678. "\t\t ", // line header
  1679. pdata,
  1680. keyLength );
  1681. pdata += keyLength;
  1682. if ( pdata + sizeof(WORD) > pdataStop )
  1683. {
  1684. break;
  1685. }
  1686. otherLength = InlineFlipUnalignedWord( pdata );
  1687. pdata += sizeof(WORD);
  1688. PrintRoutine(
  1689. pContext,
  1690. "\r\n"
  1691. "\t\tOther Length = %d\r\n",
  1692. otherLength );
  1693. if ( pdata + otherLength > pdataStop )
  1694. {
  1695. PrintRoutine(
  1696. pContext,
  1697. "Invalid other data length: exceeds record data!\r\n" );
  1698. break;
  1699. }
  1700. DnsPrint_RawOctets(
  1701. PrintRoutine,
  1702. pContext,
  1703. "\t\tOther Data:",
  1704. "\t\t ", // line header
  1705. pdata,
  1706. otherLength );
  1707. break;
  1708. }
  1709. case DNS_TYPE_TSIG:
  1710. {
  1711. ULONGLONG signTime;
  1712. WORD fudgeTime;
  1713. WORD sigLength;
  1714. WORD extRcode;
  1715. WORD wOriginalId;
  1716. WORD otherLength;
  1717. otherLength = (WORD) DnsPrint_PacketName(
  1718. PrintRoutine,
  1719. pContext,
  1720. "\r\n\t\tAlgorithm: ",
  1721. pdata,
  1722. pMsgHead,
  1723. pMsgEnd,
  1724. NULL );
  1725. if ( !otherLength )
  1726. {
  1727. PrintRoutine(
  1728. pContext,
  1729. "Invalid algorithm name in TSIG RR!\r\n" );
  1730. }
  1731. pdata += otherLength;
  1732. signTime = InlineFlipUnaligned48Bits( pdata );
  1733. pdata += sizeof(DWORD) + sizeof(WORD);
  1734. fudgeTime = InlineFlipUnalignedWord( pdata );
  1735. pdata += sizeof(WORD);
  1736. sigLength = InlineFlipUnalignedWord( pdata );
  1737. pdata += sizeof(WORD);
  1738. PrintRoutine(
  1739. pContext,
  1740. "\r\n"
  1741. "\t\tSigned time = %I64u\r\n"
  1742. "\t\tFudge time = %u\r\n"
  1743. "\t\tSig Length = %u\r\n",
  1744. signTime,
  1745. fudgeTime,
  1746. sigLength );
  1747. if ( pdata + sigLength > pdataStop )
  1748. {
  1749. PrintRoutine(
  1750. pContext,
  1751. "Invalid signature length: exceeds record data!\r\n" );
  1752. break;
  1753. }
  1754. DnsPrint_RawOctets(
  1755. PrintRoutine,
  1756. pContext,
  1757. "\t\tSignature:",
  1758. "\t\t ", // line header
  1759. pdata,
  1760. sigLength );
  1761. pdata += sigLength;
  1762. if ( pdata + sizeof(DWORD) > pdataStop )
  1763. {
  1764. break;
  1765. }
  1766. wOriginalId = InlineFlipUnalignedWord( pdata );
  1767. pdata += sizeof(WORD);
  1768. extRcode = InlineFlipUnalignedWord( pdata );
  1769. pdata += sizeof(WORD);
  1770. otherLength = InlineFlipUnalignedWord( pdata );
  1771. pdata += sizeof(WORD);
  1772. PrintRoutine(
  1773. pContext,
  1774. "\r\n"
  1775. "\t\tOriginal XID = %x\r\n"
  1776. "\t\tExtended RCODE = %u\r\n"
  1777. "\t\tOther Length = %u\r\n",
  1778. wOriginalId,
  1779. extRcode,
  1780. otherLength );
  1781. if ( pdata + otherLength > pdataStop )
  1782. {
  1783. PrintRoutine(
  1784. pContext,
  1785. "Invalid other data length: exceeds record data!\r\n" );
  1786. break;
  1787. }
  1788. DnsPrint_RawOctets(
  1789. PrintRoutine,
  1790. pContext,
  1791. "\t\tOther Data:",
  1792. "\t\t ", // line header
  1793. pdata,
  1794. otherLength );
  1795. break;
  1796. }
  1797. case DNS_TYPE_WINS:
  1798. {
  1799. DWORD i;
  1800. DWORD winsFlags;
  1801. DWORD lookupTimeout;
  1802. DWORD cacheTimeout;
  1803. DWORD winsCount;
  1804. CHAR flagString[ WINS_FLAG_MAX_LENGTH ];
  1805. //
  1806. // WINS
  1807. // - scope/domain mapping flag
  1808. // - lookup timeout
  1809. // - cache timeout
  1810. // - WINS server count
  1811. // - WINS server list
  1812. //
  1813. winsFlags = FlipUnalignedDword( pdata );
  1814. pdata += sizeof(DWORD);
  1815. lookupTimeout = FlipUnalignedDword( pdata );
  1816. pdata += sizeof(DWORD);
  1817. cacheTimeout = FlipUnalignedDword( pdata );
  1818. pdata += sizeof(DWORD);
  1819. winsCount = FlipUnalignedDword( pdata );
  1820. pdata += sizeof(DWORD);
  1821. Dns_WinsRecordFlagString(
  1822. winsFlags,
  1823. flagString );
  1824. PrintRoutine(
  1825. pContext,
  1826. "\r\n"
  1827. "\t\tWINS flags = %s (%08x)\r\n"
  1828. "\t\tLookup timeout = %d\r\n"
  1829. "\t\tCaching TTL = %d\r\n",
  1830. flagString,
  1831. winsFlags,
  1832. lookupTimeout,
  1833. cacheTimeout );
  1834. if ( pdata + (winsCount * SIZEOF_IP4_ADDRESS) > pdataStop )
  1835. {
  1836. PrintRoutine(
  1837. pContext,
  1838. "ERROR: WINS server count leads beyond record data length!\n"
  1839. "\tpmsg = %p\n"
  1840. "\tpmsgEnd = %p\n"
  1841. "\tpRR = %p\n"
  1842. "\trecord data end = %p\n"
  1843. "\twins count = %d\n"
  1844. "\tend of wins IPs = %p\n",
  1845. pMsgHead,
  1846. pMsgEnd,
  1847. pMsgRR,
  1848. pdataStop,
  1849. winsCount,
  1850. pdata + (winsCount * SIZEOF_IP4_ADDRESS)
  1851. );
  1852. goto Done;
  1853. }
  1854. DnsPrint_Ip4AddressArray(
  1855. PrintRoutine,
  1856. pContext,
  1857. NULL,
  1858. "\tWINS",
  1859. winsCount,
  1860. (PIP4_ADDRESS) pdata );
  1861. break;
  1862. }
  1863. case DNS_TYPE_WINSR:
  1864. {
  1865. DWORD winsFlags;
  1866. DWORD lookupTimeout;
  1867. DWORD cacheTimeout;
  1868. CHAR flagString[ WINS_FLAG_MAX_LENGTH ];
  1869. //
  1870. // NBSTAT
  1871. // - scope/domain mapping flag
  1872. // - lookup timeout
  1873. // - cache timeout
  1874. // - result domain -- optional
  1875. //
  1876. winsFlags = FlipUnalignedDword( pdata );
  1877. pdata += sizeof(DWORD);
  1878. lookupTimeout = FlipUnalignedDword( pdata );
  1879. pdata += sizeof(DWORD);
  1880. cacheTimeout = FlipUnalignedDword( pdata );
  1881. pdata += sizeof(DWORD);
  1882. Dns_WinsRecordFlagString(
  1883. winsFlags,
  1884. flagString );
  1885. PrintRoutine(
  1886. pContext,
  1887. "\r\n"
  1888. "\t\tWINS-R flags = %s (%08x)\r\n"
  1889. "\t\tLookup timeout = %d\r\n"
  1890. "\t\tCaching TTL = %d\r\n",
  1891. flagString,
  1892. winsFlags,
  1893. lookupTimeout,
  1894. cacheTimeout );
  1895. DnsPrint_PacketName(
  1896. PrintRoutine,
  1897. pContext,
  1898. "\t\tResult domain = ",
  1899. pdata,
  1900. pMsgHead,
  1901. pMsgEnd,
  1902. "\r\n" );
  1903. break;
  1904. }
  1905. case DNS_TYPE_KEY:
  1906. {
  1907. WORD flags;
  1908. BYTE protocol;
  1909. BYTE algorithm;
  1910. INT keyLength;
  1911. CHAR szKeyFlags[ 100 ];
  1912. keyLength = dlen - SIZEOF_KEY_FIXED_DATA;
  1913. flags = FlipUnalignedWord( pdata );
  1914. pdata += sizeof( WORD );
  1915. protocol = * ( PBYTE ) pdata;
  1916. ++pdata;
  1917. algorithm = * ( PBYTE ) pdata;
  1918. ++pdata;
  1919. PrintRoutine(
  1920. pContext,
  1921. "\r\n"
  1922. "\t\tKEY flags = 0x%04x %s\r\n"
  1923. "\t\tKEY protocol = %s (%d)\r\n"
  1924. "\t\tKEY algorithm = %s (%d)\r\n",
  1925. (INT) flags,
  1926. Dns_KeyFlagString( szKeyFlags, flags ),
  1927. Dns_GetKeyProtocolString( protocol ),
  1928. (INT) protocol,
  1929. Dns_GetDnssecAlgorithmString( algorithm ),
  1930. (INT) algorithm );
  1931. DnsPrint_RawOctets(
  1932. PrintRoutine,
  1933. pContext,
  1934. "\t\tPublic key:",
  1935. "\t\t ", // line header
  1936. pdata,
  1937. keyLength );
  1938. break;
  1939. }
  1940. case DNS_TYPE_SIG:
  1941. {
  1942. WORD typeCovered;
  1943. BYTE algorithm;
  1944. BYTE labelCount;
  1945. DWORD originalTTL;
  1946. DWORD sigInception;
  1947. DWORD sigExpiration;
  1948. WORD keyTag;
  1949. CHAR szSigInception[ 100 ];
  1950. CHAR szSigExpiration[ 100 ];
  1951. INT sigLength;
  1952. typeCovered = FlipUnalignedWord( pdata );
  1953. pdata += sizeof( WORD );
  1954. algorithm = * ( PBYTE ) pdata;
  1955. ++pdata;
  1956. labelCount = * ( PBYTE ) pdata;
  1957. ++pdata;
  1958. originalTTL = FlipUnalignedDword( pdata );
  1959. pdata += sizeof( DWORD );
  1960. sigExpiration = FlipUnalignedDword( pdata );
  1961. pdata += sizeof( DWORD );
  1962. sigInception = FlipUnalignedDword( pdata );
  1963. pdata += sizeof( DWORD );
  1964. keyTag = FlipUnalignedWord( pdata );
  1965. pdata += sizeof( WORD );
  1966. PrintRoutine(
  1967. pContext,
  1968. "\r\n"
  1969. "\t\tSIG type covered = %s\r\n"
  1970. "\t\tSIG algorithm = %s (%d)\r\n"
  1971. "\t\tSIG label count = %d\r\n"
  1972. "\t\tSIG original TTL = %d\r\n"
  1973. "\t\tSIG expiration = %s\r\n"
  1974. "\t\tSIG inception = %s\r\n"
  1975. "\t\tSIG key tag = %d\r\n",
  1976. Dns_RecordStringForType( typeCovered ),
  1977. Dns_GetDnssecAlgorithmString( ( BYTE ) algorithm ),
  1978. ( INT ) algorithm,
  1979. ( INT ) labelCount,
  1980. ( INT ) originalTTL,
  1981. Dns_SigTimeString( sigExpiration, szSigExpiration ),
  1982. Dns_SigTimeString( sigInception, szSigInception ),
  1983. ( INT ) keyTag );
  1984. pdata += DnsPrint_PacketName(
  1985. PrintRoutine,
  1986. pContext,
  1987. "\t\tSIG signer's name = ",
  1988. pdata,
  1989. pMsgHead,
  1990. pMsgEnd,
  1991. "\r\n" );
  1992. sigLength = ( INT ) ( pdataStop - pdata );
  1993. DnsPrint_RawOctets(
  1994. PrintRoutine,
  1995. pContext,
  1996. "\t\tSignature:",
  1997. "\t\t ", // line header
  1998. pdata,
  1999. sigLength );
  2000. break;
  2001. }
  2002. case DNS_TYPE_NXT:
  2003. {
  2004. INT bitmapLength;
  2005. INT byteIdx;
  2006. INT bitIdx;
  2007. pdata += DnsPrint_PacketName(
  2008. PrintRoutine,
  2009. pContext,
  2010. "\r\n\t\tNXT next name = ",
  2011. pdata,
  2012. pMsgHead,
  2013. pMsgEnd,
  2014. "\r\n" );
  2015. bitmapLength = ( INT ) ( pdataStop - pdata );
  2016. PrintRoutine( pContext, "\t\tNXT types covered = " );
  2017. for ( byteIdx = 0; byteIdx < bitmapLength; ++byteIdx )
  2018. {
  2019. for ( bitIdx = ( byteIdx ? 0 : 1 ); bitIdx < 8; ++bitIdx )
  2020. {
  2021. PCHAR pszType;
  2022. if ( !( pdata[ byteIdx ] & ( 1 << bitIdx ) ) )
  2023. {
  2024. continue; // Bit value is zero - do not write string.
  2025. }
  2026. pszType = Dns_RecordStringForType( byteIdx * 8 + bitIdx );
  2027. if ( !pszType )
  2028. {
  2029. ASSERT( FALSE );
  2030. continue; // This type has no string - do not write.
  2031. }
  2032. PrintRoutine( pContext, "%s ", pszType );
  2033. }
  2034. }
  2035. PrintRoutine( pContext, "\r\n" );
  2036. break;
  2037. }
  2038. default:
  2039. PrintRoutine(
  2040. pContext,
  2041. "Unknown resource record type %d at %p.\r\n",
  2042. type,
  2043. pMsgRR );
  2044. DnsPrint_RawOctets(
  2045. PrintRoutine,
  2046. pContext,
  2047. NULL,
  2048. "\t\t",
  2049. pdata,
  2050. dlen );
  2051. break;
  2052. }
  2053. Done:
  2054. DnsPrint_Unlock();
  2055. return( sizeof(DNS_WIRE_RECORD) + dlen );
  2056. }
  2057. //
  2058. // Print related utilities
  2059. //
  2060. INT
  2061. Dns_WriteFormattedSystemTimeToBuffer(
  2062. OUT PCHAR pBuffer,
  2063. IN PSYSTEMTIME pSystemTime
  2064. )
  2065. /*++
  2066. Routine Description:
  2067. Write SYSTEMTIME structure to buffer.
  2068. Arguments:
  2069. pBuffer -- buffer to write into, assumed to have at least 50
  2070. bytes available
  2071. pSystemTime -- system time to convert; assumed to be local, no
  2072. time zone conversion is done
  2073. Return Value:
  2074. Bytes in formatted string.
  2075. --*/
  2076. {
  2077. PCHAR pend = pBuffer + 60;
  2078. PCHAR pstart = pBuffer;
  2079. INT count;
  2080. pBuffer += GetDateFormat(
  2081. LOCALE_SYSTEM_DEFAULT,
  2082. LOCALE_NOUSEROVERRIDE,
  2083. (PSYSTEMTIME) pSystemTime,
  2084. NULL,
  2085. pBuffer,
  2086. (int)(pend - pBuffer) );
  2087. // Replace NULL from GetDateFormat with a space.
  2088. *( pBuffer - 1 ) = ' ';
  2089. pBuffer += GetTimeFormat(
  2090. LOCALE_SYSTEM_DEFAULT,
  2091. LOCALE_NOUSEROVERRIDE,
  2092. (PSYSTEMTIME) pSystemTime,
  2093. NULL,
  2094. pBuffer,
  2095. (int)(pend - pBuffer) );
  2096. if ( pBuffer <= pstart+1 )
  2097. {
  2098. return( 0 );
  2099. }
  2100. return (INT)( pBuffer - pstart );
  2101. }
  2102. //
  2103. // Response code print
  2104. //
  2105. #define DNS_RCODE_UNKNOWN (DNS_RCODE_BADTIME + 1)
  2106. PCHAR ResponseCodeStringTable[] =
  2107. {
  2108. "NOERROR",
  2109. "FORMERR",
  2110. "SERVFAIL",
  2111. "NXDOMAIN",
  2112. "NOTIMP",
  2113. "REFUSED",
  2114. "YXDOMAIN",
  2115. "YXRRSET",
  2116. "NXRRSET",
  2117. "NOTAUTH",
  2118. "NOTZONE",
  2119. "11 - unknown\r\n",
  2120. "12 - unknown\r\n",
  2121. "13 - unknown\r\n",
  2122. "14 - unknown\r\n",
  2123. "15 - unknown\r\n",
  2124. // DNS RCODEs stop at 15 -- these extended errors are available for security
  2125. "BADSIG",
  2126. "BADKEY",
  2127. "BADTIME",
  2128. "UNKNOWN"
  2129. };
  2130. PCHAR
  2131. Dns_ResponseCodeString(
  2132. IN INT ResponseCode
  2133. )
  2134. /*++
  2135. Routine Description:
  2136. Get string corresponding to a response code.
  2137. Arguments:
  2138. ResponseCode - response code
  2139. Return Value:
  2140. Ptr to string for code.
  2141. --*/
  2142. {
  2143. if ( ResponseCode > DNS_RCODE_UNKNOWN )
  2144. {
  2145. ResponseCode = DNS_RCODE_UNKNOWN;
  2146. }
  2147. return( ResponseCodeStringTable[ ResponseCode ] );
  2148. }
  2149. //
  2150. // More detailed RCODE strings
  2151. //
  2152. PCHAR ResponseCodeExplanationStringTable[] =
  2153. {
  2154. "NOERROR: no error",
  2155. "FORMERR: format error",
  2156. "SERVFAIL: server failure",
  2157. "NXDOMAIN: name error",
  2158. "NOTIMP: not implemented",
  2159. "REFUSED",
  2160. "YXDOMAIN: name exists that should not",
  2161. "YXRRSET: RR set exists that should not",
  2162. "NXRRSET: required RR set does not exist",
  2163. "NOTAUTH: not authoritative",
  2164. "NOTZONE: name not in zone",
  2165. "11 - unknown",
  2166. "12 - unknown",
  2167. "13 - unknown",
  2168. "14 - unknown",
  2169. "15 - unknown",
  2170. // DNS RCODEs stop at 15 -- these extended errors are available for security
  2171. "BADSIG: bad signature",
  2172. "BADKEY: bad signature",
  2173. "BADTIME: invalid or expired time on signature or key",
  2174. "UNKNOWN"
  2175. };
  2176. PCHAR
  2177. Dns_ResponseCodeExplanationString(
  2178. IN INT ResponseCode
  2179. )
  2180. /*++
  2181. Routine Description:
  2182. Get string corresponding to a response code.
  2183. Basically for use by packet debug routine above.
  2184. Arguments:
  2185. ResponseCode - response code
  2186. Return Value:
  2187. Ptr to string for code.
  2188. --*/
  2189. {
  2190. if ( ResponseCode > DNS_RCODE_UNKNOWN )
  2191. {
  2192. ResponseCode = DNS_RCODE_UNKNOWN;
  2193. }
  2194. return( ResponseCodeExplanationStringTable[ ResponseCode ] );
  2195. }
  2196. PCHAR
  2197. Dns_KeyFlagString(
  2198. IN OUT PCHAR pszBuff,
  2199. IN WORD Flags
  2200. )
  2201. /*++
  2202. Routine Description:
  2203. Formats a human-readable string based on the flags value
  2204. (DNSSEC KEY RR flags). See RFC2535 section 3.2.1.
  2205. Arguments:
  2206. pszBuff - buffer to dump string into should be min 100 chars
  2207. flags - flag value to generate string for
  2208. Return Value:
  2209. pszBuff
  2210. --*/
  2211. {
  2212. BOOL fZoneKey = FALSE;
  2213. *pszBuff = '\0';
  2214. // "type" bits
  2215. if ( ( Flags & 0xC000 ) == 0xC000 )
  2216. {
  2217. strcat( pszBuff, "NOKEY " );
  2218. }
  2219. else if ( ( Flags & 0xC000 ) == 0x8000 )
  2220. {
  2221. strcat( pszBuff, "NOAUTH " );
  2222. }
  2223. else if ( ( Flags & 0xC000 ) == 0x4000 )
  2224. {
  2225. strcat( pszBuff, "NOCONF " );
  2226. }
  2227. else
  2228. {
  2229. strcat( pszBuff, "NOAUTH NOCONF " );
  2230. }
  2231. // extended bit
  2232. if ( Flags & 0x1000 )
  2233. {
  2234. strcat( pszBuff, "EXTEND " );
  2235. }
  2236. // name type bits
  2237. if ( ( Flags & 0x0300 ) == 0x0300 )
  2238. {
  2239. strcat( pszBuff, "RESNT " ); // reserved name type
  2240. }
  2241. else if ( ( Flags & 0x0200 ) == 0x0100 )
  2242. {
  2243. strcat( pszBuff, "ENTITY " );
  2244. }
  2245. else if ( ( Flags & 0x0100 ) == 0x4000 )
  2246. {
  2247. strcat( pszBuff, "ZONE " );
  2248. fZoneKey = TRUE;
  2249. }
  2250. else
  2251. {
  2252. strcat( pszBuff, "USER " );
  2253. }
  2254. // signatory bits
  2255. if ( fZoneKey )
  2256. {
  2257. strcat( pszBuff, ( Flags & 0x0008 ) ? "MODEA " : "MODEB " );
  2258. if ( Flags & 0x0004 )
  2259. {
  2260. strcat( pszBuff, "STRONG " );
  2261. }
  2262. if ( Flags & 0x0002 )
  2263. {
  2264. strcat( pszBuff, "UNIQ " );
  2265. }
  2266. }
  2267. else
  2268. {
  2269. if ( Flags & 0x0008 )
  2270. {
  2271. strcat( pszBuff, "ZCTRL " );
  2272. }
  2273. if ( Flags & 0x0004 )
  2274. {
  2275. strcat( pszBuff, "STRONG " );
  2276. }
  2277. if ( Flags & 0x0002 )
  2278. {
  2279. strcat( pszBuff, "UNIQ " );
  2280. }
  2281. }
  2282. return pszBuff;
  2283. }
  2284. //
  2285. // Opcode print
  2286. //
  2287. PCHAR OpcodeStringTable[] =
  2288. {
  2289. "QUERY",
  2290. "IQUERY",
  2291. "SRV_STATUS",
  2292. "UNKNOWN",
  2293. "NOTIFY",
  2294. "UPDATE",
  2295. "UNKNOWN?"
  2296. };
  2297. CHAR OpcodeCharacterTable[] =
  2298. {
  2299. 'Q',
  2300. 'I',
  2301. 'S',
  2302. 'K',
  2303. 'N',
  2304. 'U',
  2305. '?'
  2306. };
  2307. #define DNS_OPCODE_UNSPEC (DNS_OPCODE_UPDATE + 1)
  2308. PCHAR
  2309. Dns_OpcodeString(
  2310. IN INT Opcode
  2311. )
  2312. /*++
  2313. Routine Description:
  2314. Get string corresponding to a response code.
  2315. Arguments:
  2316. Opcode - response code
  2317. Return Value:
  2318. Ptr to string for code.
  2319. --*/
  2320. {
  2321. if ( Opcode > DNS_OPCODE_UNSPEC )
  2322. {
  2323. Opcode = DNS_OPCODE_UNSPEC;
  2324. }
  2325. return( OpcodeStringTable[ Opcode ] );
  2326. }
  2327. CHAR
  2328. Dns_OpcodeCharacter(
  2329. IN INT Opcode
  2330. )
  2331. /*++
  2332. Routine Description:
  2333. Get string corresponding to an opcode.
  2334. Arguments:
  2335. Opcode - response code
  2336. Return Value:
  2337. Ptr to string for code.
  2338. --*/
  2339. {
  2340. if ( Opcode > DNS_OPCODE_UNSPEC )
  2341. {
  2342. Opcode = DNS_OPCODE_UNSPEC;
  2343. }
  2344. return( OpcodeCharacterTable[ Opcode ] );
  2345. }
  2346. //
  2347. // Section names
  2348. //
  2349. // With update get a new set of section names.
  2350. // Provide single interface to putting a name on them.
  2351. //
  2352. PSTR SectionNameArray[5] =
  2353. {
  2354. "Question",
  2355. "Answer",
  2356. "Authority",
  2357. "Additional",
  2358. "ERROR: Invalid Section"
  2359. };
  2360. PSTR UpdateSectionNameArray[5] =
  2361. {
  2362. "Zone",
  2363. "Prerequisite",
  2364. "Update",
  2365. "Additional",
  2366. "ERROR: Invalid Section"
  2367. };
  2368. PCHAR
  2369. Dns_SectionNameString(
  2370. IN INT iSection,
  2371. IN INT iOpcode
  2372. )
  2373. /*++
  2374. Routine Description:
  2375. Get string corresponding to name of RR section id.
  2376. For use by packet debug routine above.
  2377. Arguments:
  2378. iSection - section id (0-3 for Question-Additional)
  2379. iOpcode - opcode
  2380. Return Value:
  2381. Ptr to string for section name.
  2382. --*/
  2383. {
  2384. if ( iSection >= 4 )
  2385. {
  2386. iSection = 4;
  2387. }
  2388. if ( iOpcode == DNS_OPCODE_UPDATE )
  2389. {
  2390. return( UpdateSectionNameArray[iSection] );
  2391. }
  2392. else
  2393. {
  2394. return( SectionNameArray[iSection] );
  2395. }
  2396. }
  2397. VOID
  2398. DnsPrint_MessageNoContext(
  2399. IN PRINT_ROUTINE PrintRoutine,
  2400. IN OUT PPRINT_CONTEXT pContext,
  2401. IN PSTR pszHeader,
  2402. IN PDNS_HEADER pMsgHead,
  2403. IN WORD wLength OPTIONAL
  2404. )
  2405. /*++
  2406. Routine Description:
  2407. Print DNS message buffer.
  2408. Includes context information as well as actual DNS message.
  2409. --*/
  2410. {
  2411. PCHAR pchRecord;
  2412. PBYTE pmsgEnd;
  2413. INT i;
  2414. INT isection;
  2415. INT cchName;
  2416. WORD wOffset;
  2417. WORD wXid;
  2418. WORD wQuestionCount;
  2419. WORD wAnswerCount;
  2420. WORD wNameServerCount;
  2421. WORD wAdditionalCount;
  2422. WORD countSectionRR;
  2423. BOOL fFlipped = FALSE;
  2424. //
  2425. // processing limits
  2426. // - if length given set stop limit
  2427. // - if length not given set wLength so checks against
  2428. // length overrun always fail (are ok)
  2429. //
  2430. if ( wLength )
  2431. {
  2432. pmsgEnd = ((PBYTE)pMsgHead) + wLength;
  2433. }
  2434. else
  2435. {
  2436. wLength = MAXWORD;
  2437. pmsgEnd = NULL;
  2438. }
  2439. DnsPrint_Lock();
  2440. if ( pszHeader )
  2441. {
  2442. PrintRoutine( pContext, "%s\r\n", pszHeader );
  2443. }
  2444. PrintRoutine(
  2445. pContext,
  2446. "DNS message header at %p\r\n",
  2447. pMsgHead );
  2448. PrintRoutine(
  2449. pContext,
  2450. " XID 0x%04hx\r\n"
  2451. " Flags 0x%04hx\r\n"
  2452. " QR 0x%lx (%s)\r\n"
  2453. " OPCODE 0x%lx (%s)\r\n"
  2454. " AA 0x%lx\r\n"
  2455. " TC 0x%lx\r\n"
  2456. " RD 0x%lx\r\n"
  2457. " RA 0x%lx\r\n"
  2458. " Z 0x%lx\r\n"
  2459. " RCODE 0x%lx (%s)\r\n"
  2460. " QCOUNT 0x%hx\r\n"
  2461. " ACOUNT 0x%hx\r\n"
  2462. " NSCOUNT 0x%hx\r\n"
  2463. " ARCOUNT 0x%hx\r\n",
  2464. pMsgHead->Xid,
  2465. ntohs((*((PWORD)pMsgHead + 1))),
  2466. pMsgHead->IsResponse,
  2467. (pMsgHead->IsResponse ? "response" : "question"),
  2468. pMsgHead->Opcode,
  2469. Dns_OpcodeString( pMsgHead->Opcode ),
  2470. pMsgHead->Authoritative,
  2471. pMsgHead->Truncation,
  2472. pMsgHead->RecursionDesired,
  2473. pMsgHead->RecursionAvailable,
  2474. pMsgHead->Reserved,
  2475. pMsgHead->ResponseCode,
  2476. Dns_ResponseCodeString( pMsgHead->ResponseCode ),
  2477. pMsgHead->QuestionCount,
  2478. pMsgHead->AnswerCount,
  2479. pMsgHead->NameServerCount,
  2480. pMsgHead->AdditionalCount );
  2481. //
  2482. // determine if byte flipped and get correct count
  2483. //
  2484. wXid = pMsgHead->Xid;
  2485. wQuestionCount = pMsgHead->QuestionCount;
  2486. wAnswerCount = pMsgHead->AnswerCount;
  2487. wNameServerCount = pMsgHead->NameServerCount;
  2488. wAdditionalCount = pMsgHead->AdditionalCount;
  2489. if ( wQuestionCount )
  2490. {
  2491. fFlipped = wQuestionCount & 0xff00;
  2492. }
  2493. else if ( wNameServerCount )
  2494. {
  2495. fFlipped = wNameServerCount & 0xff00;
  2496. }
  2497. if ( fFlipped )
  2498. {
  2499. wXid = ntohs( wXid );
  2500. wQuestionCount = ntohs( wQuestionCount );
  2501. wAnswerCount = ntohs( wAnswerCount );
  2502. wNameServerCount = ntohs( wNameServerCount );
  2503. wAdditionalCount = ntohs( wAdditionalCount );
  2504. }
  2505. //
  2506. // catch record flipping problems -- all are flipped or none at all
  2507. // and no record count should be > 256 EXCEPT answer count
  2508. // during FAST zone transfer
  2509. //
  2510. DNS_ASSERT( ! (wQuestionCount & 0xff00) );
  2511. DNS_ASSERT( ! (wNameServerCount & 0xff00) );
  2512. DNS_ASSERT( ! (wAdditionalCount & 0xff00) );
  2513. #if 0
  2514. //
  2515. // stop here if WINS response -- don't have parsing ready
  2516. //
  2517. if ( pMsgHead->IsResponse && IS_WINS_XID(wXid) )
  2518. {
  2519. PrintRoutine( pContext, " WINS Response packet.\r\n\r\n" );
  2520. goto Unlock;
  2521. }
  2522. #endif
  2523. //
  2524. // print questions and resource records
  2525. //
  2526. pchRecord = (PCHAR)(pMsgHead + 1);
  2527. for ( isection=0; isection<4; isection++)
  2528. {
  2529. PrintRoutine(
  2530. pContext,
  2531. " %s Section:\r\n",
  2532. Dns_SectionNameString( isection, pMsgHead->Opcode ) );
  2533. if ( isection==0 )
  2534. {
  2535. countSectionRR = wQuestionCount;
  2536. }
  2537. else if ( isection==1 )
  2538. {
  2539. countSectionRR = wAnswerCount;
  2540. }
  2541. else if ( isection==2 )
  2542. {
  2543. countSectionRR = wNameServerCount;
  2544. }
  2545. else if ( isection==3 )
  2546. {
  2547. countSectionRR = wAdditionalCount;
  2548. }
  2549. for ( i=0; i < countSectionRR; i++ )
  2550. {
  2551. //
  2552. // verify not overrunning length
  2553. // - check against pCurrent as well as message length
  2554. // so can print packets while being built
  2555. //
  2556. wOffset = (WORD)(pchRecord - (PCHAR)pMsgHead);
  2557. if ( wOffset >= wLength )
  2558. {
  2559. PrintRoutine(
  2560. pContext,
  2561. "ERROR: BOGUS PACKET:\r\n"
  2562. "\tFollowing RR (offset %d) past packet length (%d).\r\n",
  2563. wOffset,
  2564. wLength
  2565. );
  2566. goto Unlock;
  2567. }
  2568. //
  2569. // print RR name
  2570. //
  2571. PrintRoutine(
  2572. pContext,
  2573. " Name Offset = 0x%04x\r\n",
  2574. wOffset
  2575. );
  2576. cchName = DnsPrint_PacketName(
  2577. PrintRoutine,
  2578. pContext,
  2579. " Name \"",
  2580. pchRecord,
  2581. pMsgHead,
  2582. pmsgEnd,
  2583. "\"\r\n" );
  2584. if ( !cchName )
  2585. {
  2586. PrintRoutine(
  2587. pContext,
  2588. "ERROR: Invalid name length, stop packet print\r\n" );
  2589. DNS_ASSERT( FALSE );
  2590. break;
  2591. }
  2592. pchRecord += cchName;
  2593. // print question or resource record
  2594. if ( isection == 0 )
  2595. {
  2596. PrintRoutine(
  2597. pContext,
  2598. " QTYPE %d\r\n"
  2599. " QCLASS %d\r\n",
  2600. FlipUnalignedWord( pchRecord ),
  2601. FlipUnalignedWord( pchRecord + sizeof(WORD) )
  2602. );
  2603. pchRecord += sizeof( DNS_WIRE_QUESTION );
  2604. }
  2605. else
  2606. {
  2607. pchRecord += DnsPrint_PacketRecord(
  2608. PrintRoutine,
  2609. pContext,
  2610. NULL,
  2611. (PDNS_WIRE_RECORD) pchRecord,
  2612. pMsgHead,
  2613. pmsgEnd
  2614. );
  2615. }
  2616. }
  2617. }
  2618. // check that at proper end of packet
  2619. wOffset = (WORD)(pchRecord - (PCHAR)pMsgHead);
  2620. PrintRoutine(
  2621. pContext,
  2622. " Message length = %04x\r\n\r\n",
  2623. wOffset );
  2624. // print warning if given message length and did not end up
  2625. // at end of message
  2626. // note: pmsgEnd test in case passed wLength==0, in which case
  2627. // wLength set to MAXDWORD above
  2628. if ( pmsgEnd && wOffset < wLength )
  2629. {
  2630. PrintRoutine(
  2631. pContext,
  2632. "WARNING: message continues beyond these records\r\n"
  2633. "\tpch = %p\r\n"
  2634. "\toffset = %d, msg length = %d, %d bytes\r\n",
  2635. pchRecord,
  2636. wOffset,
  2637. wLength,
  2638. wLength - wOffset );
  2639. DnsPrint_RawOctets(
  2640. PrintRoutine,
  2641. pContext,
  2642. "Remaining bytes:",
  2643. NULL,
  2644. pchRecord,
  2645. (wLength - wOffset) );
  2646. }
  2647. Unlock:
  2648. DnsPrint_Unlock();
  2649. } // DnsPrint_MessageNoContext
  2650. DWORD
  2651. DnsStringPrint_Guid(
  2652. OUT PCHAR pBuffer,
  2653. IN PGUID pGuid
  2654. )
  2655. /*++
  2656. Routine Description:
  2657. Print GUID to buffer.
  2658. Arguments:
  2659. pBuffer - buffer to print to
  2660. buffer must be big enough for GUID string
  2661. GUID_STRING_BUFFER_LENGTH covers it
  2662. pGuid - GUID to print
  2663. Return Value:
  2664. Count of bytes printed to string.
  2665. --*/
  2666. {
  2667. if ( !pGuid )
  2668. {
  2669. *pBuffer = 0;
  2670. return 0;
  2671. }
  2672. return sprintf(
  2673. pBuffer,
  2674. "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
  2675. pGuid->Data1,
  2676. pGuid->Data2,
  2677. pGuid->Data3,
  2678. *(PWORD) &pGuid->Data4[0],
  2679. pGuid->Data4[2],
  2680. pGuid->Data4[3],
  2681. pGuid->Data4[4],
  2682. pGuid->Data4[5],
  2683. pGuid->Data4[6],
  2684. pGuid->Data4[7] );
  2685. }
  2686. VOID
  2687. DnsPrint_Guid(
  2688. IN PRINT_ROUTINE PrintRoutine,
  2689. IN OUT PPRINT_CONTEXT pContext,
  2690. IN PSTR pszHeader,
  2691. IN PGUID pGuid
  2692. )
  2693. /*++
  2694. Routine Description:
  2695. Print GUID
  2696. Arguments:
  2697. pszHeader - Header message/name for RR.
  2698. pGuid -- ptr to GUID to print
  2699. Return Value:
  2700. None.
  2701. --*/
  2702. {
  2703. CHAR guidBuffer[ GUID_STRING_BUFFER_LENGTH ];
  2704. if ( !pszHeader )
  2705. {
  2706. pszHeader = "Guid";
  2707. }
  2708. if ( !pGuid )
  2709. {
  2710. PrintRoutine(
  2711. pContext,
  2712. "%s: NULL GUID pointer!\r\n",
  2713. pszHeader );
  2714. }
  2715. // convert GUID to string
  2716. DnsStringPrint_Guid(
  2717. guidBuffer,
  2718. pGuid );
  2719. PrintRoutine(
  2720. pContext,
  2721. "%s: (%p) %s\r\n",
  2722. pszHeader,
  2723. pGuid,
  2724. guidBuffer );
  2725. }
  2726. DWORD
  2727. DnsStringPrint_RawOctets(
  2728. OUT PCHAR pBuffer,
  2729. IN PCHAR pchData,
  2730. IN DWORD dwLength,
  2731. IN PSTR pszLineHeader,
  2732. IN DWORD dwLineLength
  2733. )
  2734. /*++
  2735. Routine Description:
  2736. Print raw octect data to sting
  2737. Arguments:
  2738. pBuffer - buffer to print to
  2739. pchData - data to print
  2740. dwLength - length of data to print
  2741. pszLineHeader - header on each line.
  2742. dwLineLength - number of bytes to print on line; default is
  2743. Return Value:
  2744. Count of bytes printed to string.
  2745. --*/
  2746. {
  2747. INT i;
  2748. INT lineCount = 0;
  2749. PCHAR pch = pBuffer;
  2750. *pch = 0;
  2751. //
  2752. // catch NULL pointer
  2753. // - return is null terminated
  2754. // - but indicate no bytes written
  2755. //
  2756. if ( !pchData )
  2757. {
  2758. return 0;
  2759. }
  2760. //
  2761. // write each byte in hex
  2762. // - if dwLineLength set break into lines with count
  2763. // or optional header
  2764. //
  2765. for ( i = 0; i < (INT)dwLength; i++ )
  2766. {
  2767. if ( dwLineLength && (i % dwLineLength) == 0 )
  2768. {
  2769. if ( pszLineHeader )
  2770. {
  2771. pch += sprintf( pch, "\r\n%s", pszLineHeader );
  2772. }
  2773. else
  2774. {
  2775. pch += sprintf( pch, "\r\n%3d> ", i );
  2776. }
  2777. lineCount++;
  2778. }
  2779. pch += sprintf( pch, "%02x ", (UCHAR)pchData[i] );
  2780. }
  2781. return( (DWORD)(pch - pBuffer) );
  2782. }
  2783. VOID
  2784. DnsPrint_RawBinary(
  2785. IN PRINT_ROUTINE PrintRoutine,
  2786. IN OUT PPRINT_CONTEXT pContext,
  2787. IN PSTR pszHeader,
  2788. IN PSTR pszLineHeader,
  2789. IN PCHAR pchData,
  2790. IN DWORD dwLength,
  2791. IN DWORD PrintSize
  2792. )
  2793. /*++
  2794. Routine Description:
  2795. Print raw data.
  2796. Arguments:
  2797. pszHeader - Header message/name for RR.
  2798. pszLineHeader - Header on each line.
  2799. pchData - data to print
  2800. dwLength - length of data to print
  2801. PrintSize - size to print in
  2802. size(QWORD)
  2803. size(DWORD)
  2804. size(WORD)
  2805. defaults to bytes
  2806. Return Value:
  2807. None.
  2808. --*/
  2809. {
  2810. DWORD i;
  2811. DWORD lineCount = 0;
  2812. CHAR buf[ 2000 ];
  2813. PCHAR pch = buf;
  2814. PCHAR pbyte;
  2815. PCHAR pend;
  2816. DnsPrint_Lock();
  2817. if ( pszHeader )
  2818. {
  2819. PrintRoutine(
  2820. pContext,
  2821. "%s",
  2822. pszHeader );
  2823. }
  2824. buf[0] = 0;
  2825. //
  2826. // print bytes
  2827. // - write 16 bytes a line
  2828. // - buffer up 10 lines for speed
  2829. //
  2830. // note: we'll write a partial (<16 byte) line the first
  2831. // time if data is unaligned with PrintSize, then we'll
  2832. // write at 16 a pop
  2833. //
  2834. if ( PrintSize == 0 )
  2835. {
  2836. PrintSize = 1;
  2837. }
  2838. i = 0;
  2839. pch = buf;
  2840. pend = (PBYTE)pchData + dwLength;
  2841. while ( i < dwLength )
  2842. {
  2843. DWORD lineBytes = (i%16);
  2844. if ( lineBytes==0 || lineBytes > (16-PrintSize) )
  2845. {
  2846. if ( lineCount > 10 )
  2847. {
  2848. PrintRoutine( pContext, buf );
  2849. lineCount = 0;
  2850. pch = buf;
  2851. }
  2852. if ( pszLineHeader )
  2853. {
  2854. pch += sprintf( pch, "\r\n%s", pszLineHeader );
  2855. }
  2856. else
  2857. {
  2858. pch += sprintf( pch, "\r\n\t%3d> ", i );
  2859. }
  2860. lineCount++;
  2861. //if ( i >= 128 && dlen > 256 )
  2862. //{
  2863. // PrintRoutine( pContext, "skipping remaining bytes ...\r\n" ));
  2864. //}
  2865. }
  2866. pbyte = &pchData[i];
  2867. if ( PrintSize == sizeof(QWORD) &&
  2868. POINTER_IS_ALIGNED( pbyte, ALIGN_QUAD ) &&
  2869. pbyte + sizeof(QWORD) <= pend )
  2870. {
  2871. pch += sprintf( pch, "%I64x ", *(PQWORD)pbyte );
  2872. i += sizeof(QWORD);
  2873. }
  2874. else if ( PrintSize == sizeof(DWORD) &&
  2875. POINTER_IS_ALIGNED( pbyte, ALIGN_DWORD ) &&
  2876. pbyte + sizeof(DWORD) <= pend )
  2877. {
  2878. pch += sprintf( pch, "%08x ", *(PDWORD)pbyte );
  2879. i += sizeof(DWORD);
  2880. }
  2881. else if ( PrintSize == sizeof(WORD) &&
  2882. POINTER_IS_ALIGNED( pbyte, ALIGN_WORD ) &&
  2883. pbyte + sizeof(WORD) <= pend )
  2884. {
  2885. pch += sprintf( pch, "%04x ", *(PWORD)pbyte );
  2886. i += sizeof(WORD);
  2887. }
  2888. else // default to byte print
  2889. {
  2890. pch += sprintf( pch, "%02x ", *pbyte );
  2891. i++;
  2892. }
  2893. }
  2894. // print remaining bytes in buffer
  2895. PrintRoutine(
  2896. pContext,
  2897. "%s\r\n",
  2898. buf );
  2899. DnsPrint_Unlock();
  2900. }
  2901. VOID
  2902. DnsPrint_RawOctets(
  2903. IN PRINT_ROUTINE PrintRoutine,
  2904. IN OUT PPRINT_CONTEXT pContext,
  2905. IN PSTR pszHeader,
  2906. IN PSTR pszLineHeader,
  2907. IN PCHAR pchData,
  2908. IN DWORD dwLength
  2909. )
  2910. /*++
  2911. Routine Description:
  2912. Print raw octect data.
  2913. Arguments:
  2914. pszHeader - Header message/name for RR.
  2915. pszLineHeader - Header on each line.
  2916. pchData - data to print
  2917. dwLength - length of data to print
  2918. Return Value:
  2919. None.
  2920. --*/
  2921. {
  2922. INT i;
  2923. INT lineCount = 0;
  2924. CHAR buf[ 2000 ];
  2925. PCHAR pch = buf;
  2926. DnsPrint_Lock();
  2927. if ( pszHeader )
  2928. {
  2929. PrintRoutine(
  2930. pContext,
  2931. "%s",
  2932. pszHeader );
  2933. }
  2934. buf[0] = 0;
  2935. // buffer every 20 lines for speed
  2936. for ( i = 0; i < (INT)dwLength; i++ )
  2937. {
  2938. if ( !(i%16) )
  2939. {
  2940. if ( lineCount > 10 )
  2941. {
  2942. PrintRoutine( pContext, buf );
  2943. lineCount = 0;
  2944. pch = buf;
  2945. }
  2946. if ( pszLineHeader )
  2947. {
  2948. pch += sprintf( pch, "\r\n%s", pszLineHeader );
  2949. }
  2950. else
  2951. {
  2952. pch += sprintf( pch, "\r\n%3d> ", i );
  2953. }
  2954. lineCount++;
  2955. //if ( i >= 128 && dlen > 256 )
  2956. //{
  2957. // PrintRoutine( pContext, "skipping remaining bytes ...\r\n" ));
  2958. //}
  2959. }
  2960. pch += sprintf( pch, "%02x ", (UCHAR)pchData[i] );
  2961. }
  2962. // print remaining bytes in buffer
  2963. PrintRoutine(
  2964. pContext,
  2965. "%s\r\n",
  2966. buf );
  2967. DnsPrint_Unlock();
  2968. }
  2969. VOID
  2970. DnsPrint_ParsedRecord(
  2971. IN PRINT_ROUTINE PrintRoutine,
  2972. IN OUT PPRINT_CONTEXT pContext,
  2973. IN PSTR pszHeader,
  2974. IN PDNS_PARSED_RR pParsedRR
  2975. )
  2976. /*++
  2977. Routine Description:
  2978. Print parsed RR structure.
  2979. Arguments:
  2980. pszHeader - Header message/name for RR.
  2981. pParsedRR - parsed RR to print
  2982. Return Value:
  2983. None.
  2984. --*/
  2985. {
  2986. if ( !pszHeader )
  2987. {
  2988. pszHeader = "Parsed RR:";
  2989. }
  2990. if ( !pParsedRR )
  2991. {
  2992. PrintRoutine(
  2993. pContext,
  2994. "%s %s\r\n",
  2995. pszHeader,
  2996. "NULL ParsedRR ptr." );
  2997. return;
  2998. }
  2999. PrintRoutine(
  3000. pContext,
  3001. "%s\r\n"
  3002. "\tpchName = %p\r\n"
  3003. "\tpchRR = %p\r\n"
  3004. "\tpchData = %p\r\n"
  3005. "\tpchNextRR = %p\r\n"
  3006. "\twType = %d\r\n"
  3007. "\twClass = %d\r\n"
  3008. "\tTTL = %d\r\n"
  3009. "\twDataLength = %d\r\n",
  3010. pszHeader,
  3011. pParsedRR->pchName,
  3012. pParsedRR->pchRR,
  3013. pParsedRR->pchData,
  3014. pParsedRR->pchNextRR,
  3015. pParsedRR->Type,
  3016. pParsedRR->Class,
  3017. pParsedRR->Ttl,
  3018. pParsedRR->DataLength
  3019. );
  3020. }
  3021. //
  3022. // Winsock RnR structures
  3023. //
  3024. VOID
  3025. DnsPrint_FdSet(
  3026. IN PRINT_ROUTINE PrintRoutine,
  3027. IN OUT PPRINT_CONTEXT pContext,
  3028. IN PSTR pszHeader,
  3029. IN struct fd_set * pfd_set
  3030. )
  3031. /*++
  3032. Routine Description:
  3033. Print sockets in FD_SET.
  3034. --*/
  3035. {
  3036. INT count;
  3037. INT i;
  3038. DNS_ASSERT( pfd_set );
  3039. count = (INT) pfd_set->fd_count;
  3040. DnsPrint_Lock();
  3041. PrintRoutine(
  3042. pContext,
  3043. "%s (count = %d)\r\n",
  3044. pszHeader ? pszHeader : "FD_SET:",
  3045. count );
  3046. for (i=0; i<count; i++)
  3047. {
  3048. PrintRoutine(
  3049. pContext,
  3050. "\tsocket[%d] = %d\r\n",
  3051. i,
  3052. pfd_set->fd_array[i] );
  3053. }
  3054. DnsPrint_Unlock();
  3055. }
  3056. VOID
  3057. DnsPrint_Sockaddr(
  3058. IN PRINT_ROUTINE PrintRoutine,
  3059. IN OUT PPRINT_CONTEXT pContext,
  3060. IN PSTR pszHeader,
  3061. IN DWORD Indent,
  3062. IN PSOCKADDR pSockaddr,
  3063. IN INT iSockaddrLength
  3064. )
  3065. /*++
  3066. Routine Description:
  3067. Print sockaddr structure and length used in call.
  3068. --*/
  3069. {
  3070. PSTR pindent = INDENT_STRING( Indent );
  3071. if ( !pszHeader )
  3072. {
  3073. pszHeader = "Sockaddr:";
  3074. }
  3075. if ( !pSockaddr )
  3076. {
  3077. PrintRoutine(
  3078. pContext,
  3079. "%s%s\tNULL Sockaddr passed to print.\r\n",
  3080. pindent,
  3081. pszHeader );
  3082. return;
  3083. }
  3084. DnsPrint_Lock();
  3085. PrintRoutine(
  3086. pContext,
  3087. "%s%s\r\n"
  3088. "%s\tpointer = %p\r\n"
  3089. "%s\tlength = %d\r\n"
  3090. "%s\tsa_family = %d\r\n",
  3091. pindent, pszHeader,
  3092. pindent, pSockaddr,
  3093. pindent, iSockaddrLength,
  3094. pindent, pSockaddr->sa_family
  3095. );
  3096. switch ( pSockaddr->sa_family )
  3097. {
  3098. case AF_INET:
  3099. {
  3100. PSOCKADDR_IN psin = (PSOCKADDR_IN) pSockaddr;
  3101. PrintRoutine(
  3102. pContext,
  3103. "%s\tsin_port = %04x\r\n"
  3104. "%s\tsin_addr = %s (%08x)\r\n"
  3105. "%s\tsin_zero = %08x %08x\r\n",
  3106. pindent, psin->sin_port,
  3107. pindent, inet_ntoa( psin->sin_addr ),
  3108. psin->sin_addr.s_addr,
  3109. pindent, *(PDWORD) &psin->sin_zero[0],
  3110. *(PDWORD) &psin->sin_zero[4]
  3111. );
  3112. break;
  3113. }
  3114. case AF_INET6:
  3115. {
  3116. PSOCKADDR_IN6 psin = (PSOCKADDR_IN6) pSockaddr;
  3117. CHAR buffer[ IP6_ADDRESS_STRING_BUFFER_LENGTH ];
  3118. Dns_Ip6AddressToString_A(
  3119. buffer,
  3120. (PIP6_ADDRESS) &psin->sin6_addr );
  3121. PrintRoutine(
  3122. pContext,
  3123. "%s\tsin6_port = %04x\r\n"
  3124. "%s\tsin6_flowinfo = %08x\r\n"
  3125. "%s\tsin6_addr = %s\r\n"
  3126. "%s\tsin6_scope_id = %08x\r\n",
  3127. pindent, psin->sin6_port,
  3128. pindent, psin->sin6_flowinfo,
  3129. pindent, buffer,
  3130. pindent, psin->sin6_scope_id
  3131. );
  3132. break;
  3133. }
  3134. default:
  3135. // print unknown in WORDs
  3136. // limit print as this is probably a busted sockaddr due to bug
  3137. {
  3138. DnsPrint_RawBinary(
  3139. PrintRoutine,
  3140. pContext,
  3141. "\tdata: ",
  3142. pindent, // line header
  3143. pSockaddr->sa_data,
  3144. iSockaddrLength < 100
  3145. ? iSockaddrLength
  3146. : 100,
  3147. sizeof(WORD)
  3148. );
  3149. break;
  3150. }
  3151. }
  3152. DnsPrint_Unlock();
  3153. }
  3154. VOID
  3155. DnsPrint_AddrInfoEx(
  3156. IN PRINT_ROUTINE PrintRoutine,
  3157. IN OUT PPRINT_CONTEXT pContext,
  3158. IN PSTR pszHeader,
  3159. IN DWORD Indent,
  3160. IN PADDRINFO pAddrInfo,
  3161. IN BOOL fUnicode
  3162. )
  3163. /*++
  3164. Routine Description:
  3165. Print ADDRINFO structure.
  3166. --*/
  3167. {
  3168. PSTR pindent = INDENT_STRING( Indent );
  3169. if ( !pszHeader )
  3170. {
  3171. pszHeader = "AddrInfo:";
  3172. }
  3173. if ( !pAddrInfo )
  3174. {
  3175. PrintRoutine(
  3176. pContext,
  3177. "%s%s NULL AddrInfo.\n",
  3178. pindent,
  3179. pszHeader );
  3180. return;
  3181. }
  3182. DnsPrint_Lock();
  3183. PrintRoutine(
  3184. pContext,
  3185. "%s%s\n"
  3186. "%s\tPtr = %p\n"
  3187. "%s\tNext Ptr = %p\n"
  3188. "%s\tFlags = %08x\n"
  3189. "%s\tFamily = %d\n"
  3190. "%s\tSockType = %d\n"
  3191. "%s\tProtocol = %d\n"
  3192. "%s\tAddrLength = %d\n"
  3193. "%s\tName = %s%S\n",
  3194. pindent, pszHeader,
  3195. pindent, pAddrInfo,
  3196. pindent, pAddrInfo->ai_next,
  3197. pindent, pAddrInfo->ai_flags,
  3198. pindent, pAddrInfo->ai_family,
  3199. pindent, pAddrInfo->ai_socktype,
  3200. pindent, pAddrInfo->ai_protocol,
  3201. pindent, pAddrInfo->ai_addrlen,
  3202. pindent,
  3203. (fUnicode) ? "" : pAddrInfo->ai_canonname,
  3204. (fUnicode) ? pAddrInfo->ai_canonname : ""
  3205. );
  3206. DnsPrint_Sockaddr(
  3207. PrintRoutine,
  3208. pContext,
  3209. NULL,
  3210. Indent + 1,
  3211. pAddrInfo->ai_addr,
  3212. pAddrInfo->ai_addrlen );
  3213. DnsPrint_Unlock();
  3214. }
  3215. VOID
  3216. DnsPrint_AddrInfoListEx(
  3217. IN PRINT_ROUTINE PrintRoutine,
  3218. IN OUT PPRINT_CONTEXT pContext,
  3219. IN PSTR pszHeader,
  3220. IN DWORD Indent,
  3221. IN PADDRINFO pAddrInfo,
  3222. IN BOOL fUnicode
  3223. )
  3224. /*++
  3225. Routine Description:
  3226. Print ADDRINFO structure.
  3227. --*/
  3228. {
  3229. PADDRINFO paddr = pAddrInfo;
  3230. PSTR pindent = INDENT_STRING( Indent );
  3231. //
  3232. // list header
  3233. //
  3234. if ( !pszHeader )
  3235. {
  3236. pszHeader = "AddrInfo List:";
  3237. }
  3238. if ( !paddr )
  3239. {
  3240. PrintRoutine(
  3241. pContext,
  3242. "%s%s NULL AddrInfo List.\r\n",
  3243. pindent,
  3244. pszHeader );
  3245. return;
  3246. }
  3247. DnsPrint_Lock();
  3248. PrintRoutine(
  3249. pContext,
  3250. "%s%s\n",
  3251. pindent, pszHeader
  3252. );
  3253. //
  3254. // print each ADDRINFO in list
  3255. //
  3256. while ( paddr )
  3257. {
  3258. DnsPrint_AddrInfoEx(
  3259. PrintRoutine,
  3260. pContext,
  3261. NULL,
  3262. Indent,
  3263. paddr,
  3264. fUnicode );
  3265. paddr = paddr->ai_next;
  3266. }
  3267. PrintRoutine(
  3268. pContext,
  3269. "End of AddrInfo list\n\n"
  3270. );
  3271. DnsPrint_Unlock();
  3272. }
  3273. VOID
  3274. DnsPrint_SocketAddress(
  3275. IN PRINT_ROUTINE PrintRoutine,
  3276. IN OUT PPRINT_CONTEXT pContext,
  3277. IN PSTR pszHeader,
  3278. IN DWORD Indent,
  3279. IN PSOCKET_ADDRESS pSocketAddress
  3280. )
  3281. /*++
  3282. Routine Description:
  3283. Print SOCKET_ADDRESS structure.
  3284. --*/
  3285. {
  3286. PSTR pindent = INDENT_STRING( Indent );
  3287. if ( !pszHeader )
  3288. {
  3289. pszHeader = "SocketAddress:";
  3290. }
  3291. if ( !pSocketAddress )
  3292. {
  3293. PrintRoutine(
  3294. pContext,
  3295. "%s%s NULL SocketAddress.\r\n",
  3296. pindent,
  3297. pszHeader );
  3298. return;
  3299. }
  3300. DnsPrint_Lock();
  3301. PrintRoutine(
  3302. pContext,
  3303. "%s%s\n"
  3304. "%s\tpSockaddr = %p\r\n"
  3305. "%s\tiSockaddrLength = %d\r\n",
  3306. pindent, pszHeader,
  3307. pindent, pSocketAddress->lpSockaddr,
  3308. pindent, pSocketAddress->iSockaddrLength );
  3309. DnsPrint_Sockaddr(
  3310. PrintRoutine,
  3311. pContext,
  3312. NULL,
  3313. Indent,
  3314. pSocketAddress->lpSockaddr,
  3315. pSocketAddress->iSockaddrLength );
  3316. DnsPrint_Unlock();
  3317. }
  3318. VOID
  3319. DnsPrint_CsAddr(
  3320. IN PRINT_ROUTINE PrintRoutine,
  3321. IN OUT PPRINT_CONTEXT pContext,
  3322. IN PSTR pszHeader,
  3323. IN DWORD Indent,
  3324. IN PCSADDR_INFO pCsAddr
  3325. )
  3326. /*++
  3327. Routine Description:
  3328. Print CSADDR_INFO structure.
  3329. Arguments:
  3330. PrintRoutine - routine to print with
  3331. pParam - ptr to print context
  3332. pszHeader - header
  3333. Indent - indent count, for formatting CSADDR inside larger struct
  3334. pCsAddr - ptr to CSADDRINFO to print
  3335. Return Value:
  3336. None.
  3337. --*/
  3338. {
  3339. PSTR pindent = INDENT_STRING( Indent );
  3340. if ( !pszHeader )
  3341. {
  3342. pszHeader = "CSAddrInfo:";
  3343. }
  3344. if ( !pCsAddr )
  3345. {
  3346. PrintRoutine(
  3347. pContext,
  3348. "%s%s \tNULL CSADDR_INFO ptr.\r\n",
  3349. pindent, pszHeader
  3350. );
  3351. return;
  3352. }
  3353. // print the struct
  3354. DnsPrint_Lock();
  3355. PrintRoutine(
  3356. pContext,
  3357. "%s%s\r\n"
  3358. "%s\tPtr = %p\n"
  3359. "%s\tSocketType = %d\n"
  3360. "%s\tProtocol = %d\n",
  3361. pindent, pszHeader,
  3362. pindent, pCsAddr,
  3363. pindent, pCsAddr->iSocketType,
  3364. pindent, pCsAddr->iProtocol
  3365. );
  3366. DnsPrint_SocketAddress(
  3367. PrintRoutine,
  3368. pContext,
  3369. "LocalAddress:",
  3370. Indent,
  3371. & pCsAddr->LocalAddr
  3372. );
  3373. DnsPrint_SocketAddress(
  3374. PrintRoutine,
  3375. pContext,
  3376. "RemoteAddress:",
  3377. Indent,
  3378. & pCsAddr->RemoteAddr
  3379. );
  3380. DnsPrint_Unlock();
  3381. }
  3382. VOID
  3383. DnsPrint_AfProtocolsArray(
  3384. IN PRINT_ROUTINE PrintRoutine,
  3385. IN OUT PPRINT_CONTEXT pContext,
  3386. IN PSTR pszHeader,
  3387. IN PAFPROTOCOLS pProtocolArray,
  3388. IN DWORD ProtocolCount
  3389. )
  3390. /*++
  3391. Routine Description:
  3392. Print AFPROTOCOLS array.
  3393. Arguments:
  3394. PrintRoutine - routine to print with
  3395. pszHeader - header
  3396. pProtocolArray - protocols array
  3397. ProtocolCount - array count
  3398. Return Value:
  3399. None.
  3400. --*/
  3401. {
  3402. DWORD i;
  3403. if ( !pszHeader )
  3404. {
  3405. pszHeader = "AFPROTOCOLS Array:";
  3406. }
  3407. // print
  3408. // - array + count
  3409. // - each protocol element
  3410. DnsPrint_Lock();
  3411. PrintRoutine(
  3412. pContext,
  3413. "%s\r\n"
  3414. "\tProtocol Array = %p\r\n"
  3415. "\tProtocol Count = %d\r\n",
  3416. pszHeader,
  3417. pProtocolArray,
  3418. ProtocolCount );
  3419. if ( pProtocolArray )
  3420. {
  3421. for ( i=0; i<ProtocolCount; i++ )
  3422. {
  3423. PrintRoutine(
  3424. pContext,
  3425. "\t\tfamily = %d; proto = %d\r\n",
  3426. pProtocolArray[i].iAddressFamily,
  3427. pProtocolArray[i].iProtocol );
  3428. }
  3429. }
  3430. DnsPrint_Unlock();
  3431. }
  3432. VOID
  3433. DnsPrint_WsaQuerySet(
  3434. IN PRINT_ROUTINE PrintRoutine,
  3435. IN OUT PPRINT_CONTEXT pContext,
  3436. IN PSTR pszHeader,
  3437. IN LPWSAQUERYSET pQuerySet,
  3438. IN BOOL fUnicode
  3439. )
  3440. /*++
  3441. Routine Description:
  3442. Print WSAQUERYSET structure.
  3443. Arguments:
  3444. PrintRoutine - routine to print with
  3445. pszHeader - header
  3446. pQuerySet - ptr to WSAQUERYSET to print
  3447. fUnicode - TRUE if WSAQUERYSET is wide (WSAQUERYSETW)
  3448. FALSE if ANSI
  3449. Return Value:
  3450. None.
  3451. --*/
  3452. {
  3453. CHAR serviceGuidBuffer[ GUID_STRING_BUFFER_LENGTH ];
  3454. CHAR nameSpaceGuidBuffer[ GUID_STRING_BUFFER_LENGTH ];
  3455. DWORD i;
  3456. if ( !pszHeader )
  3457. {
  3458. pszHeader = "WSAQuerySet:";
  3459. }
  3460. if ( !pQuerySet )
  3461. {
  3462. PrintRoutine(
  3463. pContext,
  3464. "%s NULL QuerySet ptr\r\n",
  3465. pszHeader );
  3466. return;
  3467. }
  3468. // convert GUIDs to strings
  3469. DnsStringPrint_Guid(
  3470. serviceGuidBuffer,
  3471. pQuerySet->lpServiceClassId
  3472. );
  3473. DnsStringPrint_Guid(
  3474. nameSpaceGuidBuffer,
  3475. pQuerySet->lpNSProviderId
  3476. );
  3477. // print the struct
  3478. DnsPrint_Lock();
  3479. PrintRoutine(
  3480. pContext,
  3481. "%s\r\n"
  3482. "\tSize = %d\r\n"
  3483. "\tServiceInstanceName = %S%s\r\n"
  3484. "\tService GUID = (%p) %s\r\n"
  3485. "\tWSA version = %p %x %d\r\n"
  3486. "\tComment = %S%s\r\n"
  3487. "\tName Space = %d %s\r\n"
  3488. "\tName Space GUID = (%p) %s\r\n"
  3489. "\tContext = %S%s\r\n"
  3490. "\tNumberOfProtocols = %d\r\n"
  3491. "\tProtocol Array = %p\r\n"
  3492. "\tQueryString = %S%s\r\n"
  3493. "\tCS Addr Count = %d\r\n"
  3494. "\tCS Addr Array = %p\r\n"
  3495. "\tOutput Flags = %08x\r\n"
  3496. "\tpBlob = %p\r\n",
  3497. pszHeader,
  3498. pQuerySet->dwSize,
  3499. DNSSTRING_WIDE( fUnicode, pQuerySet->lpszServiceInstanceName ),
  3500. DNSSTRING_ANSI( fUnicode, pQuerySet->lpszServiceInstanceName ),
  3501. pQuerySet->lpServiceClassId,
  3502. serviceGuidBuffer,
  3503. pQuerySet->lpVersion,
  3504. ( pQuerySet->lpVersion ) ? pQuerySet->lpVersion->dwVersion : 0,
  3505. ( pQuerySet->lpVersion ) ? pQuerySet->lpVersion->ecHow : 0,
  3506. DNSSTRING_WIDE( fUnicode, pQuerySet->lpszComment ),
  3507. DNSSTRING_ANSI( fUnicode, pQuerySet->lpszComment ),
  3508. pQuerySet->dwNameSpace,
  3509. Dns_GetRnrNameSpaceIdString( pQuerySet->dwNameSpace ),
  3510. pQuerySet->lpNSProviderId,
  3511. nameSpaceGuidBuffer,
  3512. DNSSTRING_WIDE( fUnicode, pQuerySet->lpszContext ),
  3513. DNSSTRING_ANSI( fUnicode, pQuerySet->lpszContext ),
  3514. pQuerySet->dwNumberOfProtocols,
  3515. pQuerySet->lpafpProtocols,
  3516. DNSSTRING_WIDE( fUnicode, pQuerySet->lpszQueryString ),
  3517. DNSSTRING_ANSI( fUnicode, pQuerySet->lpszQueryString ),
  3518. pQuerySet->dwNumberOfCsAddrs,
  3519. pQuerySet->lpcsaBuffer,
  3520. pQuerySet->dwOutputFlags,
  3521. pQuerySet->lpBlob
  3522. );
  3523. // print address-family\protocols array
  3524. if ( pQuerySet->lpafpProtocols )
  3525. {
  3526. DnsPrint_AfProtocolsArray(
  3527. PrintRoutine,
  3528. pContext,
  3529. "\tAFPROTOCOLS Array:",
  3530. pQuerySet->lpafpProtocols,
  3531. pQuerySet->dwNumberOfProtocols );
  3532. }
  3533. // print CSADDR_INFO array
  3534. if ( pQuerySet->dwNumberOfCsAddrs &&
  3535. pQuerySet->lpcsaBuffer )
  3536. {
  3537. PrintRoutine(
  3538. pContext,
  3539. "--- CS_ADDR array:\r\n" );
  3540. for ( i=0; i<pQuerySet->dwNumberOfCsAddrs; i++ )
  3541. {
  3542. DnsPrint_CsAddr(
  3543. PrintRoutine,
  3544. pContext,
  3545. NULL,
  3546. 1, // indent one level
  3547. & pQuerySet->lpcsaBuffer[i] );
  3548. }
  3549. }
  3550. // print blob (the hostent)
  3551. //
  3552. // DCR_FIX0: need some sort of test for blob type?
  3553. // - most blobs are hostent, but some are servent
  3554. //
  3555. if ( pQuerySet->lpBlob )
  3556. {
  3557. GUID ianaGuid = SVCID_INET_SERVICEBYNAME;
  3558. PrintRoutine(
  3559. pContext,
  3560. "--- BLOB:\n"
  3561. "\tcbSize = %d\r\n"
  3562. "\tpBlobData = %p\r\n",
  3563. pQuerySet->lpBlob->cbSize,
  3564. pQuerySet->lpBlob->pBlobData
  3565. );
  3566. // note: can't print blob as hostent
  3567. // 1) may not be hostent
  3568. // 2) is passed with offsets rather than pointers
  3569. DnsPrint_RawBinary(
  3570. PrintRoutine,
  3571. pContext,
  3572. NULL,
  3573. "\t\t",
  3574. pQuerySet->lpBlob->pBlobData,
  3575. pQuerySet->lpBlob->cbSize,
  3576. sizeof(DWORD)
  3577. );
  3578. }
  3579. DnsPrint_Unlock();
  3580. }
  3581. VOID
  3582. DnsPrint_WsaNsClassInfo(
  3583. IN PRINT_ROUTINE PrintRoutine,
  3584. IN OUT PPRINT_CONTEXT pContext,
  3585. IN PSTR pszHeader,
  3586. IN PWSANSCLASSINFO pInfo,
  3587. IN BOOL fUnicode
  3588. )
  3589. /*++
  3590. Routine Description:
  3591. Print WSACLASSINFO structure.
  3592. Arguments:
  3593. PrintRoutine - routine to print with
  3594. pszHeader - header
  3595. pInfo - ptr to WSACLASSINFO to print
  3596. fUnicode - TRUE if WSACLASSINFO is wide (WSACLASSINFOW)
  3597. FALSE if ANSI
  3598. Return Value:
  3599. None.
  3600. --*/
  3601. {
  3602. if ( !pszHeader )
  3603. {
  3604. pszHeader = "WSANsClassInfo:";
  3605. }
  3606. if ( !pInfo )
  3607. {
  3608. PrintRoutine(
  3609. pContext,
  3610. "%s NULL NsClassInfo ptr\r\n",
  3611. pszHeader );
  3612. return;
  3613. }
  3614. // print the struct
  3615. DnsPrint_Lock();
  3616. PrintRoutine(
  3617. pContext,
  3618. "%s\r\n"
  3619. "\tPtr = %d\r\n"
  3620. "\tName = %S%s\r\n"
  3621. "\tName Space = %d\r\n"
  3622. "\tValue Type = %d\r\n"
  3623. "\tValue Size = %d\r\n"
  3624. "\tpValue = %p\r\n",
  3625. pszHeader,
  3626. pInfo,
  3627. DNSSTRING_WIDE( fUnicode, pInfo->lpszName ),
  3628. DNSSTRING_ANSI( fUnicode, pInfo->lpszName ),
  3629. pInfo->dwNameSpace,
  3630. pInfo->dwValueType,
  3631. pInfo->dwValueSize,
  3632. pInfo->lpValue
  3633. );
  3634. if ( pInfo->lpValue )
  3635. {
  3636. PrintRoutine(
  3637. pContext,
  3638. "--- Value:\r\n"
  3639. );
  3640. DnsPrint_RawBinary(
  3641. PrintRoutine,
  3642. pContext,
  3643. NULL,
  3644. "\t\t",
  3645. pInfo->lpValue,
  3646. pInfo->dwValueSize,
  3647. sizeof(BYTE) // print in bytes
  3648. );
  3649. }
  3650. DnsPrint_Unlock();
  3651. }
  3652. VOID
  3653. DnsPrint_WsaServiceClassInfo(
  3654. IN PRINT_ROUTINE PrintRoutine,
  3655. IN OUT PPRINT_CONTEXT pContext,
  3656. IN PSTR pszHeader,
  3657. IN LPWSASERVICECLASSINFO pInfo,
  3658. IN BOOL fUnicode
  3659. )
  3660. /*++
  3661. Routine Description:
  3662. Print WSASERVICECLASSINFO structure.
  3663. Arguments:
  3664. PrintRoutine - routine to print with
  3665. pszHeader - header
  3666. pInfo - ptr to WSASERVICECLASSINFO to print
  3667. fUnicode - TRUE if WSASERVICECLASSINFO is wide (WSASERVICECLASSINFOW)
  3668. FALSE if ANSI
  3669. Return Value:
  3670. None.
  3671. --*/
  3672. {
  3673. CHAR serviceClassGuidBuffer[ GUID_STRING_BUFFER_LENGTH ];
  3674. if ( !pszHeader )
  3675. {
  3676. pszHeader = "WSAServiceClassInfo:";
  3677. }
  3678. if ( !pInfo )
  3679. {
  3680. PrintRoutine(
  3681. pContext,
  3682. "%s NULL ServiceClassInfo ptr\r\n",
  3683. pszHeader );
  3684. return;
  3685. }
  3686. // convert GUID to strings
  3687. DnsStringPrint_Guid(
  3688. serviceClassGuidBuffer,
  3689. pInfo->lpServiceClassId
  3690. );
  3691. // print the struct
  3692. DnsPrint_Lock();
  3693. PrintRoutine(
  3694. pContext,
  3695. "%s\r\n"
  3696. "\tPtr = %p\r\n"
  3697. "\tClass GUID = (%p) %s\r\n"
  3698. "\tClassName = %S%s\r\n"
  3699. "\tClass Info Count = %d\r\n"
  3700. "\tClass Info Array = %p\r\n",
  3701. pszHeader,
  3702. pInfo,
  3703. serviceClassGuidBuffer,
  3704. DNSSTRING_WIDE( fUnicode, pInfo->lpszServiceClassName ),
  3705. DNSSTRING_ANSI( fUnicode, pInfo->lpszServiceClassName ),
  3706. pInfo->dwCount,
  3707. pInfo->lpClassInfos
  3708. );
  3709. if ( pInfo->lpClassInfos )
  3710. {
  3711. DWORD i;
  3712. for ( i=0; i<pInfo->dwCount; i++ )
  3713. {
  3714. DnsPrint_WsaNsClassInfo(
  3715. PrintRoutine,
  3716. pContext,
  3717. NULL, // default header
  3718. & pInfo->lpClassInfos[i],
  3719. fUnicode
  3720. );
  3721. }
  3722. }
  3723. DnsPrint_Unlock();
  3724. }
  3725. VOID
  3726. DnsPrint_Hostent(
  3727. IN PRINT_ROUTINE PrintRoutine,
  3728. IN OUT PPRINT_CONTEXT pContext,
  3729. IN PSTR pszHeader,
  3730. IN PHOSTENT pHostent,
  3731. IN BOOL fUnicode
  3732. )
  3733. /*++
  3734. Routine Description:
  3735. Print hostent structure.
  3736. Arguments:
  3737. PrintRoutine - routine to print with
  3738. pszHeader - header
  3739. pHostent - ptr to hostent
  3740. fUnicode - TRUE if hostent is unicode
  3741. FALSE if ANSI
  3742. Return Value:
  3743. None.
  3744. --*/
  3745. {
  3746. if ( !pszHeader )
  3747. {
  3748. pszHeader = "Hostent:";
  3749. }
  3750. if ( !pHostent )
  3751. {
  3752. PrintRoutine(
  3753. pContext,
  3754. "%s %s\r\n",
  3755. pszHeader,
  3756. "NULL Hostent ptr." );
  3757. return;
  3758. }
  3759. // print the struct
  3760. DnsPrint_Lock();
  3761. PrintRoutine(
  3762. pContext,
  3763. "%s\r\n"
  3764. "\th_name = %p %S%s\n"
  3765. "\th_aliases = %p\n"
  3766. "\th_addrtype = %d\n"
  3767. "\th_length = %d\n"
  3768. "\th_addrlist = %p\n",
  3769. pszHeader,
  3770. pHostent->h_name,
  3771. DNSSTRING_WIDE( fUnicode, pHostent->h_name ),
  3772. DNSSTRING_ANSI( fUnicode, pHostent->h_name ),
  3773. pHostent->h_aliases,
  3774. pHostent->h_addrtype,
  3775. pHostent->h_length,
  3776. pHostent->h_addr_list
  3777. );
  3778. // print the aliases
  3779. if ( pHostent->h_aliases )
  3780. {
  3781. PSTR * paliasArray = pHostent->h_aliases;
  3782. PSTR palias;
  3783. while ( palias = *paliasArray++ )
  3784. {
  3785. PrintRoutine(
  3786. pContext,
  3787. "\tAlias = (%p) %S%s\n",
  3788. palias,
  3789. DNSSTRING_WIDE( fUnicode, palias ),
  3790. DNSSTRING_ANSI( fUnicode, palias ) );
  3791. }
  3792. }
  3793. // print the addresses
  3794. if ( pHostent->h_addr_list )
  3795. {
  3796. PCHAR * ppaddr = pHostent->h_addr_list;
  3797. PCHAR pip;
  3798. INT i = 0;
  3799. INT family = pHostent->h_addrtype;
  3800. INT addrLength = pHostent->h_length;
  3801. CHAR stringBuf[ IP6_ADDRESS_STRING_BUFFER_LENGTH ];
  3802. while ( pip = ppaddr[i] )
  3803. {
  3804. DWORD bufLength = IP6_ADDRESS_STRING_BUFFER_LENGTH;
  3805. Dns_AddressToString_A(
  3806. stringBuf,
  3807. & bufLength,
  3808. pip,
  3809. addrLength,
  3810. family );
  3811. PrintRoutine(
  3812. pContext,
  3813. "\tAddr[%d] = %s \t(ptr=%p)\n",
  3814. i,
  3815. stringBuf,
  3816. pip );
  3817. i++;
  3818. }
  3819. }
  3820. DnsPrint_Unlock();
  3821. }
  3822. //
  3823. // IP help types (iptypes.h)
  3824. //
  3825. VOID
  3826. DnsPrint_IpAdapterAddress(
  3827. IN PRINT_ROUTINE PrintRoutine,
  3828. IN OUT PPRINT_CONTEXT pContext,
  3829. IN PSTR pszHeader,
  3830. IN PVOID pAddr,
  3831. IN BOOL fUnicast,
  3832. IN BOOL fPrintList
  3833. )
  3834. /*++
  3835. Routine Description:
  3836. Print IP_ADAPTER_XXX_ADDRESS structures
  3837. This prints:
  3838. PIP_ADAPTER_UNICAST_ADDRESS
  3839. PIP_ADAPTER_ANYCAST_ADDRESS
  3840. PIP_ADAPTER_MULTICAST_ADDRESS
  3841. PIP_ADAPTER_DNS_SERVER_ADDRESS
  3842. fUnicast --
  3843. TRUE for UNICAST,
  3844. FALSE for all other types which are identical.
  3845. fPrintList --
  3846. TRUE to print all addresses.
  3847. FALSE to print just this address.
  3848. --*/
  3849. {
  3850. PIP_ADAPTER_UNICAST_ADDRESS paddr = (PIP_ADAPTER_UNICAST_ADDRESS) pAddr;
  3851. DWORD count = 0;
  3852. if ( !pszHeader )
  3853. {
  3854. pszHeader = "IpAdapterAddress:";
  3855. }
  3856. if ( !paddr )
  3857. {
  3858. PrintRoutine(
  3859. pContext,
  3860. "%s\tNULL IpAdapterAddress passed to print.\n",
  3861. pszHeader );
  3862. return;
  3863. }
  3864. DnsPrint_Lock();
  3865. if ( fPrintList )
  3866. {
  3867. PrintRoutine(
  3868. pContext,
  3869. "%s List:\n",
  3870. pszHeader );
  3871. }
  3872. while ( paddr )
  3873. {
  3874. if ( fPrintList )
  3875. {
  3876. PrintRoutine(
  3877. pContext,
  3878. "%s [%d]:\n",
  3879. pszHeader,
  3880. count );
  3881. }
  3882. else
  3883. {
  3884. PrintRoutine(
  3885. pContext,
  3886. "%s\n",
  3887. pszHeader );
  3888. }
  3889. PrintRoutine(
  3890. pContext,
  3891. "\tPointer = %p\n"
  3892. "\tLength = %d\n"
  3893. "\tFlags = %08x\n"
  3894. "\tpNext = %p\n",
  3895. paddr,
  3896. paddr->Length,
  3897. paddr->Flags,
  3898. paddr->Next
  3899. );
  3900. DnsPrint_SocketAddress(
  3901. PrintRoutine,
  3902. pContext,
  3903. "\tSocketAddress:",
  3904. 1, // indent
  3905. & paddr->Address
  3906. );
  3907. if ( fUnicast )
  3908. {
  3909. PrintRoutine(
  3910. pContext,
  3911. "\tPrefixOrigin = %d\n"
  3912. "\tSuffixOrigin = %d\n"
  3913. "\tDadState = %d\n"
  3914. "\tValidLifetime = %u\n"
  3915. "\tPrefLifetime = %u\n"
  3916. "\tLeaseLifetime = %u\n",
  3917. paddr->PrefixOrigin,
  3918. paddr->SuffixOrigin,
  3919. paddr->DadState,
  3920. paddr->ValidLifetime,
  3921. paddr->PreferredLifetime,
  3922. paddr->LeaseLifetime
  3923. );
  3924. }
  3925. // print next in list (if desired)
  3926. // - hard stop at 50 addresses
  3927. paddr = paddr->Next;
  3928. if ( !fPrintList || count > 50 )
  3929. {
  3930. break;
  3931. }
  3932. count++;
  3933. }
  3934. if ( fPrintList )
  3935. {
  3936. PrintRoutine(
  3937. pContext,
  3938. "End of %s List\n",
  3939. pszHeader );
  3940. }
  3941. DnsPrint_Unlock();
  3942. }
  3943. VOID
  3944. DnsPrint_IpAdapterList(
  3945. IN PRINT_ROUTINE PrintRoutine,
  3946. IN OUT PPRINT_CONTEXT pContext,
  3947. IN PSTR pszHeader,
  3948. IN PIP_ADAPTER_ADDRESSES pAdapt,
  3949. IN BOOL fPrintAddrs,
  3950. IN BOOL fPrintList
  3951. )
  3952. /*++
  3953. Routine Description:
  3954. Print IP_ADAPTER_ADDRESSES structure
  3955. Arguments:
  3956. fPrintAddressLists -- TRUE to print address list subfields.
  3957. fPrintList --
  3958. TRUE to print list of adapters,
  3959. FALSE to print just this adapter
  3960. --*/
  3961. {
  3962. if ( !pszHeader )
  3963. {
  3964. pszHeader = "IpAdapter:";
  3965. }
  3966. if ( !pAdapt )
  3967. {
  3968. PrintRoutine(
  3969. pContext,
  3970. "%s\tNULL IpAdapter passed to print.\n",
  3971. pszHeader );
  3972. return;
  3973. }
  3974. DnsPrint_Lock();
  3975. if ( fPrintList )
  3976. {
  3977. PrintRoutine(
  3978. pContext,
  3979. "%s List:\n",
  3980. pszHeader );
  3981. }
  3982. while ( pAdapt )
  3983. {
  3984. PrintRoutine(
  3985. pContext,
  3986. "%s\n"
  3987. "\tPointer = %p\n"
  3988. "\tLength = %d\n"
  3989. "\tIfIndex = %d\n"
  3990. "\tpNext = %p\n"
  3991. "\tAdapterName = %s\n"
  3992. "\tUnicastList = %p\n"
  3993. "\tAnycastList = %p\n"
  3994. "\tMulticastList = %p\n"
  3995. "\tDnsServerList = %p\n"
  3996. "\tDnsSuffix = %S\n"
  3997. "\tDescription = %S\n"
  3998. "\tFriendlyName = %S\n"
  3999. "\tPhysicalAddr Ptr = %p\n"
  4000. "\tPhysicalLength = %d\n"
  4001. "\tFlags = %d\n"
  4002. "\tMtu = %d\n"
  4003. "\tIfType = %d\n"
  4004. "\tOperStatus = %d\n"
  4005. "\tIfIndex6 = %d\n",
  4006. pszHeader,
  4007. pAdapt,
  4008. pAdapt->Length,
  4009. pAdapt->IfIndex,
  4010. pAdapt->Next,
  4011. pAdapt->AdapterName,
  4012. pAdapt->FirstUnicastAddress,
  4013. pAdapt->FirstAnycastAddress,
  4014. pAdapt->FirstMulticastAddress,
  4015. pAdapt->FirstDnsServerAddress,
  4016. pAdapt->DnsSuffix,
  4017. pAdapt->Description,
  4018. pAdapt->FriendlyName,
  4019. pAdapt->PhysicalAddress,
  4020. pAdapt->PhysicalAddressLength,
  4021. pAdapt->Flags,
  4022. pAdapt->Mtu,
  4023. pAdapt->IfType,
  4024. (INT) pAdapt->OperStatus,
  4025. pAdapt->Ipv6IfIndex );
  4026. PrintRoutine(
  4027. pContext,
  4028. "\tZoneIndices = %d inf=%d lnk=%d sub=%d adm=%d site=%d %d %d\n"
  4029. "\t %d %d %d %d %d %d %d %d\n",
  4030. pAdapt->ZoneIndices[0],
  4031. pAdapt->ZoneIndices[1],
  4032. pAdapt->ZoneIndices[2],
  4033. pAdapt->ZoneIndices[3],
  4034. pAdapt->ZoneIndices[4],
  4035. pAdapt->ZoneIndices[5],
  4036. pAdapt->ZoneIndices[6],
  4037. pAdapt->ZoneIndices[7],
  4038. pAdapt->ZoneIndices[8],
  4039. pAdapt->ZoneIndices[9],
  4040. pAdapt->ZoneIndices[10],
  4041. pAdapt->ZoneIndices[11],
  4042. pAdapt->ZoneIndices[12],
  4043. pAdapt->ZoneIndices[13],
  4044. pAdapt->ZoneIndices[14],
  4045. pAdapt->ZoneIndices[15] );
  4046. DnsPrint_RawBinary(
  4047. PrintRoutine,
  4048. pContext,
  4049. NULL, // no header
  4050. "\tPhysical Address", // line header
  4051. pAdapt->PhysicalAddress,
  4052. pAdapt->PhysicalAddressLength,
  4053. 0 // no alignment, write in bytes
  4054. );
  4055. if ( fPrintAddrs )
  4056. {
  4057. if ( pAdapt->FirstUnicastAddress )
  4058. {
  4059. DnsPrint_IpAdapterAddress(
  4060. PrintRoutine,
  4061. pContext,
  4062. "Adapter Unicast Addrs",
  4063. pAdapt->FirstUnicastAddress,
  4064. TRUE, // unicast
  4065. TRUE // print list
  4066. );
  4067. }
  4068. if ( pAdapt->FirstAnycastAddress )
  4069. {
  4070. DnsPrint_IpAdapterAddress(
  4071. PrintRoutine,
  4072. pContext,
  4073. "Adapter Anycast Addrs",
  4074. pAdapt->FirstAnycastAddress,
  4075. FALSE, // not unicast
  4076. TRUE // print list
  4077. );
  4078. }
  4079. if ( pAdapt->FirstMulticastAddress )
  4080. {
  4081. DnsPrint_IpAdapterAddress(
  4082. PrintRoutine,
  4083. pContext,
  4084. "Adapter Multicast Addrs",
  4085. pAdapt->FirstMulticastAddress,
  4086. FALSE, // not unicast
  4087. TRUE // print list
  4088. );
  4089. }
  4090. if ( pAdapt->FirstDnsServerAddress )
  4091. {
  4092. DnsPrint_IpAdapterAddress(
  4093. PrintRoutine,
  4094. pContext,
  4095. "Adapter DnsServer Addrs",
  4096. pAdapt->FirstDnsServerAddress,
  4097. FALSE, // not unicast
  4098. TRUE // print list
  4099. );
  4100. }
  4101. }
  4102. // get next
  4103. pAdapt = pAdapt->Next;
  4104. if ( !fPrintList )
  4105. {
  4106. break;
  4107. }
  4108. }
  4109. PrintRoutine(
  4110. pContext,
  4111. "End of %s%s\n"
  4112. "\n",
  4113. pszHeader,
  4114. fPrintList ? " List" : "" );
  4115. DnsPrint_Unlock();
  4116. }
  4117. //
  4118. // Query print routines
  4119. //
  4120. VOID
  4121. DnsPrint_QueryBlob(
  4122. IN PRINT_ROUTINE PrintRoutine,
  4123. IN OUT PPRINT_CONTEXT pContext,
  4124. IN PSTR pszHeader,
  4125. IN PQUERY_BLOB pBlob
  4126. )
  4127. /*++
  4128. Routine Description:
  4129. Print query blob.
  4130. Arguments:
  4131. PrintRoutine - routine to print with
  4132. pContext - print context
  4133. pszHeader - header
  4134. pBlob - query info
  4135. Return Value:
  4136. None.
  4137. --*/
  4138. {
  4139. DWORD i;
  4140. if ( !pszHeader )
  4141. {
  4142. pszHeader = "Query Blob:";
  4143. }
  4144. if ( !pBlob )
  4145. {
  4146. PrintRoutine(
  4147. pContext,
  4148. "%s %s\n",
  4149. pszHeader,
  4150. "NULL Query Blob ptr." );
  4151. return;
  4152. }
  4153. // print the struct
  4154. DnsPrint_Lock();
  4155. PrintRoutine(
  4156. pContext,
  4157. "\tname orig %S\n"
  4158. "\tname query %S\n"
  4159. "\ttype %d\n"
  4160. "\tflags %08x\n"
  4161. "\tname length %d\n"
  4162. "\tname attributes %08x\n"
  4163. "\tquery count %d\n"
  4164. "\tname flags %08x\n"
  4165. "\tfappendedName %d\n"
  4166. "\tstatus %d\n"
  4167. "\trcode %d\n"
  4168. "\tnetfail status %d\n"
  4169. "\tcache negative %d\n"
  4170. "\tno ip local %d\n"
  4171. "\trecords %p\n"
  4172. "\tlocal records %p\n"
  4173. "\tnetwork info %p\n"
  4174. "\tserver list %p\n"
  4175. "\tserver4 list %p\n"
  4176. "\tpmsg %p\n"
  4177. "\tevent %p\n",
  4178. pBlob->pNameOrig,
  4179. pBlob->pNameQuery,
  4180. pBlob->wType,
  4181. pBlob->Flags,
  4182. pBlob->NameLength,
  4183. pBlob->NameAttributes,
  4184. pBlob->QueryCount,
  4185. pBlob->NameFlags,
  4186. pBlob->fAppendedName,
  4187. pBlob->Status,
  4188. pBlob->Rcode,
  4189. pBlob->NetFailureStatus,
  4190. pBlob->fCacheNegative,
  4191. pBlob->fNoIpLocal,
  4192. pBlob->pRecords,
  4193. pBlob->pLocalRecords,
  4194. pBlob->pNetInfo,
  4195. pBlob->pServerList,
  4196. pBlob->pServerList4,
  4197. pBlob->pRecvMsg,
  4198. pBlob->hEvent
  4199. );
  4200. // DCR_FIX0: cleanup when results in use
  4201. DnsPrint_RecordSet(
  4202. PrintRoutine,
  4203. pContext,
  4204. "Records:\n",
  4205. pBlob->pRecords );
  4206. // DCR_FIX0: use results when ready
  4207. DnsPrint_Unlock();
  4208. }
  4209. VOID
  4210. DnsPrint_QueryResults(
  4211. IN PRINT_ROUTINE PrintRoutine,
  4212. IN OUT PPRINT_CONTEXT pContext,
  4213. IN PSTR pszHeader,
  4214. IN PDNS_RESULTS pResults
  4215. )
  4216. /*++
  4217. Routine Description:
  4218. Print query results.
  4219. Arguments:
  4220. PrintRoutine - routine to print with
  4221. pContext - print context
  4222. pszHeader - header
  4223. pResults - results info
  4224. Return Value:
  4225. None.
  4226. --*/
  4227. {
  4228. DWORD i;
  4229. if ( !pszHeader )
  4230. {
  4231. pszHeader = "Results:";
  4232. }
  4233. if ( !pResults )
  4234. {
  4235. PrintRoutine(
  4236. pContext,
  4237. "%s %s\n",
  4238. pszHeader,
  4239. "NULL Results ptr." );
  4240. return;
  4241. }
  4242. // print the struct
  4243. DnsPrint_Lock();
  4244. PrintRoutine(
  4245. pContext,
  4246. "\tstatus %d\n"
  4247. "\trcode %d\n"
  4248. "\tserver %s\n"
  4249. "\tpanswer %p\n"
  4250. "\tpalias %p\n"
  4251. "\tpauthority %p\n"
  4252. "\tpadditional %p\n"
  4253. "\tpsig %p\n"
  4254. "\tpmsg %p\n",
  4255. pResults->Status,
  4256. pResults->Rcode,
  4257. IP4_STRING( pResults->ServerAddr ),
  4258. pResults->pAnswerRecords,
  4259. pResults->pAliasRecords,
  4260. pResults->pAuthorityRecords,
  4261. pResults->pAdditionalRecords,
  4262. pResults->pSigRecords,
  4263. pResults->pMessage
  4264. );
  4265. DnsPrint_RecordSet(
  4266. PrintRoutine,
  4267. pContext,
  4268. "\tAnswer records:\n",
  4269. pResults->pAnswerRecords );
  4270. DnsPrint_RecordSet(
  4271. PrintRoutine,
  4272. pContext,
  4273. "\tAlias records:\n",
  4274. pResults->pAliasRecords );
  4275. DnsPrint_RecordSet(
  4276. PrintRoutine,
  4277. pContext,
  4278. "\tAuthority records:\n",
  4279. pResults->pAuthorityRecords );
  4280. DnsPrint_RecordSet(
  4281. PrintRoutine,
  4282. pContext,
  4283. "\tAdditional records:\n",
  4284. pResults->pAdditionalRecords );
  4285. DnsPrint_RecordSet(
  4286. PrintRoutine,
  4287. pContext,
  4288. "\tSignature records:\n",
  4289. pResults->pSigRecords );
  4290. DnsPrint_Unlock();
  4291. }
  4292. VOID
  4293. DnsPrint_ParsedMessage(
  4294. IN PRINT_ROUTINE PrintRoutine,
  4295. IN OUT PPRINT_CONTEXT pContext,
  4296. IN PSTR pszHeader,
  4297. IN PDNS_PARSED_MESSAGE pParsed
  4298. )
  4299. /*++
  4300. Routine Description:
  4301. Print parsed message.
  4302. Arguments:
  4303. PrintRoutine - routine to print with
  4304. pContext - print context
  4305. pszHeader - header
  4306. pResults - query info
  4307. Return Value:
  4308. None.
  4309. --*/
  4310. {
  4311. DWORD i;
  4312. if ( !pszHeader )
  4313. {
  4314. pszHeader = "Parsed Message:";
  4315. }
  4316. if ( !pParsed )
  4317. {
  4318. PrintRoutine(
  4319. pContext,
  4320. "%s %s\n",
  4321. pszHeader,
  4322. "NULL Parsed Message ptr." );
  4323. return;
  4324. }
  4325. // print the struct
  4326. DnsPrint_Lock();
  4327. PrintRoutine(
  4328. pContext,
  4329. "\tstatus %d (%08x)\n"
  4330. "\tchar set %d\n",
  4331. pParsed->Status, pParsed->Status,
  4332. pParsed->CharSet
  4333. );
  4334. PrintRoutine(
  4335. pContext,
  4336. "\tquestion:\n"
  4337. "\t\tname %S%s\n"
  4338. "\t\ttype %d\n"
  4339. "\t\tclass %d\n",
  4340. PRINT_STRING_WIDE_CHARSET( pParsed->pQuestionName, pParsed->CharSet ),
  4341. PRINT_STRING_ANSI_CHARSET( pParsed->pQuestionName, pParsed->CharSet ),
  4342. pParsed->QuestionType,
  4343. pParsed->QuestionClass
  4344. );
  4345. DnsPrint_RecordSet(
  4346. PrintRoutine,
  4347. pContext,
  4348. "Answer records:\n",
  4349. pParsed->pAnswerRecords );
  4350. DnsPrint_RecordSet(
  4351. PrintRoutine,
  4352. pContext,
  4353. "Alias records:\n",
  4354. pParsed->pAliasRecords );
  4355. DnsPrint_RecordSet(
  4356. PrintRoutine,
  4357. pContext,
  4358. "Authority records:\n",
  4359. pParsed->pAuthorityRecords );
  4360. DnsPrint_RecordSet(
  4361. PrintRoutine,
  4362. pContext,
  4363. "Additional records:\n",
  4364. pParsed->pAdditionalRecords );
  4365. DnsPrint_RecordSet(
  4366. PrintRoutine,
  4367. pContext,
  4368. "Signature records:\n",
  4369. pParsed->pSigRecords );
  4370. DnsPrint_Unlock();
  4371. }
  4372. VOID
  4373. DnsPrint_QueryInfo(
  4374. IN PRINT_ROUTINE PrintRoutine,
  4375. IN OUT PPRINT_CONTEXT pContext,
  4376. IN PSTR pszHeader,
  4377. IN PDNS_QUERY_INFO pQueryInfo
  4378. )
  4379. /*++
  4380. Routine Description:
  4381. Print query info
  4382. Arguments:
  4383. PrintRoutine - routine to print with
  4384. pContext - print context
  4385. pszHeader - header
  4386. pQueryInfo - query info
  4387. Return Value:
  4388. None.
  4389. --*/
  4390. {
  4391. DWORD i;
  4392. if ( !pszHeader )
  4393. {
  4394. pszHeader = "Query Info:";
  4395. }
  4396. if ( !pQueryInfo )
  4397. {
  4398. PrintRoutine(
  4399. pContext,
  4400. "%s %s\n",
  4401. pszHeader,
  4402. "NULL Query Info ptr." );
  4403. return;
  4404. }
  4405. // print the struct
  4406. DnsPrint_Lock();
  4407. PrintRoutine(
  4408. pContext,
  4409. "%s\n"
  4410. "\tpointer %p\n"
  4411. "\tstatus %d (%08x)\n"
  4412. "\tchar set %d\n"
  4413. "\tname %S%s\n"
  4414. "\tname resv. %s\n"
  4415. "\ttype %d\n"
  4416. "\trcode %d\n"
  4417. "\tflags %08x\n"
  4418. "\tpanswer %p\n"
  4419. "\tpalias %p\n"
  4420. "\tpauthority %p\n"
  4421. "\tpadditional %p\n"
  4422. //"\tpsig %p\n"
  4423. "\tevent %p\n"
  4424. "\tserver list %p\n"
  4425. "\tserver4 list %p\n"
  4426. "\tpmsg %p\n",
  4427. pszHeader,
  4428. pQueryInfo,
  4429. pQueryInfo->Status, pQueryInfo->Status,
  4430. pQueryInfo->CharSet,
  4431. PRINT_STRING_WIDE_CHARSET( pQueryInfo->pName, pQueryInfo->CharSet ),
  4432. PRINT_STRING_ANSI_CHARSET( pQueryInfo->pName, pQueryInfo->CharSet ),
  4433. pQueryInfo->pReservedName,
  4434. pQueryInfo->Type,
  4435. pQueryInfo->Rcode,
  4436. pQueryInfo->Flags,
  4437. pQueryInfo->pAnswerRecords,
  4438. pQueryInfo->pAliasRecords,
  4439. pQueryInfo->pAuthorityRecords,
  4440. pQueryInfo->pAdditionalRecords,
  4441. //pQueryInfo->pSigRecords,
  4442. pQueryInfo->hEvent,
  4443. pQueryInfo->pServerList,
  4444. pQueryInfo->pServerListIp4,
  4445. pQueryInfo->pMessage
  4446. );
  4447. DnsPrint_RecordSet(
  4448. PrintRoutine,
  4449. pContext,
  4450. "Answer records:\n",
  4451. pQueryInfo->pAnswerRecords );
  4452. DnsPrint_RecordSet(
  4453. PrintRoutine,
  4454. pContext,
  4455. "Alias records:\n",
  4456. pQueryInfo->pAliasRecords );
  4457. DnsPrint_RecordSet(
  4458. PrintRoutine,
  4459. pContext,
  4460. "Authority records:\n",
  4461. pQueryInfo->pAuthorityRecords );
  4462. DnsPrint_RecordSet(
  4463. PrintRoutine,
  4464. pContext,
  4465. "Additional records:\n",
  4466. pQueryInfo->pAdditionalRecords );
  4467. //DnsPrint_RecordSet(
  4468. // "Signature records:\n",
  4469. // pQueryInfo->pSigRecords );
  4470. DnsPrint_Unlock();
  4471. }
  4472. VOID
  4473. DnsPrint_EnvarInfo(
  4474. IN PRINT_ROUTINE PrintRoutine,
  4475. IN OUT PPRINT_CONTEXT pContext,
  4476. IN PSTR pszHeader,
  4477. IN PENVAR_DWORD_INFO pEnvar
  4478. )
  4479. /*++
  4480. Routine Description:
  4481. Print envar data
  4482. Arguments:
  4483. PrintRoutine - routine to print with
  4484. pContext - print context
  4485. pszHeader -- header to print with
  4486. pEnvar -- ptr to envar info
  4487. Return Value:
  4488. ERROR_SUCCESS if successful.
  4489. ErrorCode on failure.
  4490. --*/
  4491. {
  4492. PrintRoutine(
  4493. pContext,
  4494. "%s\n"
  4495. "\tId = %d\n"
  4496. "\tValue = %p\n"
  4497. "\tfFound = %d\n",
  4498. pszHeader ? pszHeader : "Envar Info:",
  4499. pEnvar->Id,
  4500. pEnvar->Value,
  4501. pEnvar->fFound
  4502. );
  4503. }
  4504. //
  4505. // Network info print routines.
  4506. //
  4507. VOID
  4508. DnsPrint_NetworkInfo(
  4509. IN PRINT_ROUTINE PrintRoutine,
  4510. IN OUT PPRINT_CONTEXT pPrintContext,
  4511. IN LPSTR pszHeader,
  4512. IN PDNS_NETINFO pNetworkInfo
  4513. )
  4514. /*++
  4515. Routine Description:
  4516. Prints and validates network info structure.
  4517. Should also touch all the memory and AV when bogus.
  4518. Arguments:
  4519. pNetworkInfo -- network info to print
  4520. Return Value:
  4521. None.
  4522. --*/
  4523. {
  4524. DWORD i;
  4525. if ( !pszHeader )
  4526. {
  4527. pszHeader = "NetworkInfo:";
  4528. }
  4529. if ( !pNetworkInfo )
  4530. {
  4531. PrintRoutine(
  4532. pPrintContext,
  4533. "%s NULL NetworkInfo.\n",
  4534. pszHeader );
  4535. return;
  4536. }
  4537. DnsPrint_Lock();
  4538. PrintRoutine(
  4539. pPrintContext,
  4540. "%s\n"
  4541. "\tpointer = %p\n"
  4542. "\tpszHostName = %S\n"
  4543. "\tpszDomainName = %S\n"
  4544. "\tpSearchList = %p\n"
  4545. "\tTimeStamp = %d\n"
  4546. "\tTag = %d\n"
  4547. "\tInfoFlags = %08x\n"
  4548. "\tReturnFlags = %08x\n"
  4549. "\tAdapterIndex = %d\n"
  4550. "\tAdapterCount = %d\n"
  4551. "\tAdapterArraySize = %d\n",
  4552. pszHeader,
  4553. pNetworkInfo,
  4554. pNetworkInfo->pszHostName,
  4555. pNetworkInfo->pszDomainName,
  4556. pNetworkInfo->pSearchList,
  4557. pNetworkInfo->TimeStamp,
  4558. pNetworkInfo->Tag,
  4559. pNetworkInfo->InfoFlags,
  4560. pNetworkInfo->ReturnFlags,
  4561. pNetworkInfo->AdapterIndex,
  4562. pNetworkInfo->AdapterCount,
  4563. pNetworkInfo->MaxAdapterCount );
  4564. // print search list
  4565. DnsPrint_SearchList(
  4566. PrintRoutine,
  4567. pPrintContext,
  4568. "Search List: ",
  4569. pNetworkInfo->pSearchList );
  4570. // print server lists
  4571. for ( i=0; i < pNetworkInfo->AdapterCount; i++ )
  4572. {
  4573. CHAR header[60];
  4574. sprintf( header, "AdapterInfo[%d]:", i );
  4575. DnsPrint_AdapterInfo(
  4576. PrintRoutine,
  4577. pPrintContext,
  4578. header,
  4579. NetInfo_GetAdapterByIndex( pNetworkInfo, i ) );
  4580. }
  4581. PrintRoutine(
  4582. pPrintContext,
  4583. "\n" );
  4584. DnsPrint_Unlock();
  4585. }
  4586. VOID
  4587. DnsPrint_AdapterInfo(
  4588. IN PRINT_ROUTINE PrintRoutine,
  4589. IN OUT PPRINT_CONTEXT pPrintContext,
  4590. IN LPSTR pszHeader,
  4591. IN PDNS_ADAPTER pAdapter
  4592. )
  4593. /*++
  4594. Routine Description:
  4595. Prints and validates DNS adapter info.
  4596. Should also touch all the memory and AV when bogus.
  4597. Arguments:
  4598. pAdapter -- DNS adapter to print
  4599. Return Value:
  4600. None.
  4601. --*/
  4602. {
  4603. DWORD i;
  4604. PDNS_ADDR_ARRAY pserverArray;
  4605. CHAR buffer[ DNS_ADDR_STRING_BUFFER_LENGTH ];
  4606. if ( !pszHeader )
  4607. {
  4608. pszHeader = "Adapter Info:";
  4609. }
  4610. if ( !pAdapter )
  4611. {
  4612. PrintRoutine(
  4613. pPrintContext,
  4614. "%s NULL Adapter info.\n",
  4615. pszHeader );
  4616. return;
  4617. }
  4618. DnsPrint_Lock();
  4619. PrintRoutine(
  4620. pPrintContext,
  4621. "%s\n"
  4622. "\tpointer = %p\n"
  4623. "\tGuid Name = %S\n"
  4624. "\tDomain = %S\n"
  4625. "\tLocalAddrs = %p\n"
  4626. "\tDnsAddrs = %p\n"
  4627. "\tInterfaceIndex = %d\n"
  4628. "\tInterfaceIndex6 = %d\n"
  4629. "\tInfoFlags = %08x\n"
  4630. "\tStatus = %d\n"
  4631. "\tRunFlags = %08x\n"
  4632. "\tSite = %d\n",
  4633. pszHeader,
  4634. pAdapter,
  4635. pAdapter->pszAdapterGuidName,
  4636. pAdapter->pszAdapterDomain,
  4637. pAdapter->pLocalAddrs,
  4638. pAdapter->pDnsAddrs,
  4639. pAdapter->InterfaceIndex,
  4640. pAdapter->InterfaceIndex6,
  4641. pAdapter->InfoFlags,
  4642. pAdapter->Status,
  4643. pAdapter->RunFlags,
  4644. pAdapter->Site );
  4645. // DNS server info
  4646. pserverArray = pAdapter->pDnsAddrs;
  4647. if ( pserverArray )
  4648. {
  4649. for ( i=0; i < pserverArray->AddrCount; i++ )
  4650. {
  4651. PDNS_ADDR pserver = &pserverArray->AddrArray[i];
  4652. DnsAddr_WriteStructString_A(
  4653. buffer,
  4654. pserver );
  4655. PrintRoutine(
  4656. pPrintContext,
  4657. "\tDNS Server [%d]:\n"
  4658. "\t\tAddress = %s\n"
  4659. "\t\tPriority = %d\n"
  4660. "\t\tFlags = %08x\n"
  4661. "\t\tStatus = %u\n",
  4662. i,
  4663. buffer,
  4664. pserver->Priority,
  4665. pserver->Flags,
  4666. pserver->Status
  4667. );
  4668. }
  4669. }
  4670. // IP address info
  4671. if ( pAdapter->pLocalAddrs )
  4672. {
  4673. DnsPrint_DnsAddrArray(
  4674. PrintRoutine,
  4675. pPrintContext,
  4676. "\tLocal Addrs",
  4677. "\tAddr",
  4678. pAdapter->pLocalAddrs );
  4679. }
  4680. DnsPrint_Unlock();
  4681. }
  4682. VOID
  4683. DnsPrint_SearchList(
  4684. IN PRINT_ROUTINE PrintRoutine,
  4685. IN OUT PPRINT_CONTEXT pPrintContext,
  4686. IN LPSTR pszHeader,
  4687. IN PSEARCH_LIST pSearchList
  4688. )
  4689. /*++
  4690. Routine Description:
  4691. Prints and validates DNS search list.
  4692. Should also touch all the memory and AV when bogus.
  4693. Arguments:
  4694. pSearchList -- search list to print
  4695. Return Value:
  4696. None.
  4697. --*/
  4698. {
  4699. DWORD i;
  4700. if ( !pszHeader )
  4701. {
  4702. pszHeader = "DNS Search List:";
  4703. }
  4704. if ( ! pSearchList )
  4705. {
  4706. PrintRoutine(
  4707. pPrintContext,
  4708. "%s NULL search list.\n",
  4709. pszHeader );
  4710. return;
  4711. }
  4712. DnsPrint_Lock();
  4713. PrintRoutine(
  4714. pPrintContext,
  4715. "%s\n"
  4716. "\tpointer = %p\n"
  4717. "\tNameCount = %d\n"
  4718. "\tMaxNameCount = %d\n"
  4719. "\tCurrentIndex = %d\n"
  4720. "\tSearchListNames:\n",
  4721. pszHeader,
  4722. pSearchList,
  4723. pSearchList->NameCount,
  4724. pSearchList->MaxNameCount,
  4725. pSearchList->CurrentNameIndex
  4726. );
  4727. for ( i=0; i < pSearchList->NameCount; i++ )
  4728. {
  4729. PrintRoutine(
  4730. pPrintContext,
  4731. "\t\t%S (Flags: %08x)\n",
  4732. pSearchList->SearchNameArray[i].pszName,
  4733. pSearchList->SearchNameArray[i].Flags );
  4734. }
  4735. DnsPrint_Unlock();
  4736. }
  4737. VOID
  4738. DnsPrint_HostentBlob(
  4739. IN PRINT_ROUTINE PrintRoutine,
  4740. IN OUT PPRINT_CONTEXT pContext,
  4741. IN PSTR pszHeader,
  4742. IN PHOSTENT_BLOB pBlob
  4743. )
  4744. /*++
  4745. Routine Description:
  4746. Print hostent structure.
  4747. Arguments:
  4748. PrintRoutine - routine to print with
  4749. pszHeader - header
  4750. pBlob - ptr to hostent blob
  4751. Return Value:
  4752. None.
  4753. --*/
  4754. {
  4755. DWORD i;
  4756. if ( !pszHeader )
  4757. {
  4758. pszHeader = "Hostent Blob:";
  4759. }
  4760. if ( !pBlob )
  4761. {
  4762. PrintRoutine(
  4763. pContext,
  4764. "%s %s\n",
  4765. pszHeader,
  4766. "NULL Hostent blob ptr." );
  4767. return;
  4768. }
  4769. // print the struct
  4770. DnsPrint_Lock();
  4771. PrintRoutine(
  4772. pContext,
  4773. "%s\n"
  4774. "\tPtr = %p\n"
  4775. "\tpHostent = %p\n"
  4776. "\tfAllocatedBlob = %d\n"
  4777. "\tfAllocatedBuf = %d\n"
  4778. "\tpBuffer = %p\n"
  4779. "\tBufferLength = %d\n"
  4780. "\tAvailLength = %d\n"
  4781. "\tpAvailBuffer = %p\n"
  4782. "\tpCurrent = %p\n"
  4783. "\tBytesLeft = %d\n"
  4784. "\tMaxAliasCount = %d\n"
  4785. "\tAliasCount = %d\n"
  4786. "\tMaxAddrCount = %d\n"
  4787. "\tAddrCount = %d\n"
  4788. "\tfWroteName = %d\n"
  4789. "\tfUnicode = %d\n"
  4790. "\tCharSet = %d\n",
  4791. pszHeader,
  4792. pBlob,
  4793. pBlob->pHostent,
  4794. pBlob->fAllocatedBlob,
  4795. pBlob->fAllocatedBuf,
  4796. pBlob->pBuffer,
  4797. pBlob->BufferLength,
  4798. pBlob->AvailLength,
  4799. pBlob->pAvailBuffer,
  4800. pBlob->pCurrent,
  4801. pBlob->BytesLeft,
  4802. pBlob->MaxAliasCount,
  4803. pBlob->AliasCount,
  4804. pBlob->MaxAddrCount,
  4805. pBlob->AddrCount,
  4806. pBlob->fWroteName,
  4807. pBlob->fUnicode,
  4808. pBlob->CharSet
  4809. );
  4810. // print the hostent
  4811. if ( pBlob->pHostent )
  4812. {
  4813. DnsPrint_Hostent(
  4814. PrintRoutine,
  4815. pContext,
  4816. NULL,
  4817. pBlob->pHostent,
  4818. pBlob->fUnicode
  4819. );
  4820. }
  4821. DnsPrint_Unlock();
  4822. }
  4823. VOID
  4824. DnsPrint_SaBlob(
  4825. IN PRINT_ROUTINE PrintRoutine,
  4826. IN OUT PPRINT_CONTEXT pContext,
  4827. IN PSTR pszHeader,
  4828. IN PSABLOB pBlob
  4829. )
  4830. /*++
  4831. Routine Description:
  4832. Print sockaddr blob structure.
  4833. Arguments:
  4834. PrintRoutine - routine to print with
  4835. pszHeader - header
  4836. pBlob - ptr to hostent blob
  4837. Return Value:
  4838. None.
  4839. --*/
  4840. {
  4841. DWORD i;
  4842. if ( !pszHeader )
  4843. {
  4844. pszHeader = "SockaddrBlob:";
  4845. }
  4846. if ( !pBlob )
  4847. {
  4848. PrintRoutine(
  4849. pContext,
  4850. "%s %s\n",
  4851. pszHeader,
  4852. "NULL SockaddrBlob ptr." );
  4853. return;
  4854. }
  4855. // print the struct
  4856. DnsPrint_Lock();
  4857. PrintRoutine(
  4858. pContext,
  4859. "%s\n"
  4860. "\tPtr = %p\n"
  4861. "\tpName = %S\n"
  4862. "\tpHostent = %p\n"
  4863. "\tAliasCount = %d\n",
  4864. pszHeader,
  4865. pBlob,
  4866. pBlob->pName,
  4867. pBlob->pHostent,
  4868. pBlob->AliasCount
  4869. );
  4870. // print the aliases
  4871. for ( i=0; i<pBlob->AliasCount; i++ )
  4872. {
  4873. PWSTR palias = pBlob->AliasArray[i];
  4874. PrintRoutine(
  4875. pContext,
  4876. "\tAlias = (%p) %S\n",
  4877. palias,
  4878. palias );
  4879. }
  4880. // print the addresses
  4881. DnsPrint_DnsAddrArray(
  4882. PrintRoutine,
  4883. pContext,
  4884. "\tSockaddrs:",
  4885. "\t\tAddr",
  4886. pBlob->pAddrArray );
  4887. DnsPrint_Unlock();
  4888. }
  4889. //
  4890. // Update info print routines
  4891. //
  4892. VOID
  4893. DnsPrint_UpdateBlob(
  4894. IN PRINT_ROUTINE PrintRoutine,
  4895. IN OUT PPRINT_CONTEXT pContext,
  4896. IN PSTR pszHeader,
  4897. IN PUPDATE_BLOB pBlob
  4898. )
  4899. /*++
  4900. Routine Description:
  4901. Print update blob.
  4902. Arguments:
  4903. PrintRoutine - routine to print with
  4904. pContext - print context
  4905. pszHeader - header
  4906. pBlob - update info
  4907. Return Value:
  4908. None.
  4909. --*/
  4910. {
  4911. DWORD i;
  4912. if ( !pszHeader )
  4913. {
  4914. pszHeader = "Update Blob:";
  4915. }
  4916. if ( !pBlob )
  4917. {
  4918. PrintRoutine(
  4919. pContext,
  4920. "%s %s\n",
  4921. pszHeader,
  4922. "NULL Update Blob ptr." );
  4923. return;
  4924. }
  4925. // print the struct
  4926. DnsPrint_Lock();
  4927. PrintRoutine(
  4928. pContext,
  4929. "%s\n"
  4930. "\tBlob ptr %p\n"
  4931. "\tpRecords %p\n"
  4932. "\tFlags %08x\n"
  4933. "\ttest mode %d\n"
  4934. "\tsave msg %d\n"
  4935. "\thCreds %p\n"
  4936. "\tpExtraInfo %p\n"
  4937. "\tpNetInfo %p\n"
  4938. "\tpszZone %s\n"
  4939. "\tpszServerName %s\n"
  4940. "\tserver list %p\n"
  4941. "\tserver4 list %p\n"
  4942. "\tpRecvMsg %p\n",
  4943. pszHeader,
  4944. pBlob,
  4945. pBlob->pRecords,
  4946. pBlob->Flags,
  4947. pBlob->fUpdateTestMode,
  4948. pBlob->fSaveRecvMsg,
  4949. pBlob->hCreds,
  4950. pBlob->pExtraInfo,
  4951. pBlob->pNetInfo,
  4952. pBlob->pszZone,
  4953. pBlob->pszServerName,
  4954. pBlob->pServerList,
  4955. pBlob->pServ4List,
  4956. pBlob->pMsgRecv
  4957. );
  4958. DnsPrint_RecordSet(
  4959. PrintRoutine,
  4960. pContext,
  4961. "\tUpdate Records:\n",
  4962. pBlob->pRecords );
  4963. if ( pBlob->pServerList )
  4964. {
  4965. DnsPrint_DnsAddrArray(
  4966. PrintRoutine,
  4967. pContext,
  4968. "Server List",
  4969. NULL,
  4970. pBlob->pServerList );
  4971. }
  4972. if ( pBlob->pServ4List )
  4973. {
  4974. DnsPrint_Ip4Array(
  4975. PrintRoutine,
  4976. pContext,
  4977. "Server4 List",
  4978. NULL,
  4979. pBlob->pServ4List );
  4980. }
  4981. if ( !DnsAddr_IsEmpty( &pBlob->FailedServer ) )
  4982. {
  4983. DnsPrint_DnsAddrLine(
  4984. PrintRoutine,
  4985. pContext,
  4986. "Failed Server Addr",
  4987. & pBlob->FailedServer,
  4988. NULL );
  4989. }
  4990. #if 1
  4991. if ( pBlob->pExtraInfo )
  4992. {
  4993. DnsPrint_ExtraInfo(
  4994. PrintRoutine,
  4995. pContext,
  4996. NULL,
  4997. pBlob->pExtraInfo );
  4998. }
  4999. #endif
  5000. DnsPrint_Unlock();
  5001. }
  5002. VOID
  5003. DnsPrint_ExtraInfo(
  5004. IN PRINT_ROUTINE PrintRoutine,
  5005. IN OUT PPRINT_CONTEXT pContext,
  5006. IN PSTR pszHeader,
  5007. IN PDNS_EXTRA_INFO pInfo
  5008. )
  5009. /*++
  5010. Routine Description:
  5011. Print update extra info.
  5012. Arguments:
  5013. PrintRoutine - routine to print with
  5014. pContext - print context
  5015. pszHeader - header
  5016. pInfo - extra info
  5017. Return Value:
  5018. None.
  5019. --*/
  5020. {
  5021. if ( !pszHeader )
  5022. {
  5023. pszHeader = "Update Extra Info:";
  5024. }
  5025. if ( !pInfo )
  5026. {
  5027. PrintRoutine(
  5028. pContext,
  5029. "%s %s\n",
  5030. pszHeader,
  5031. "NULL Update Extra Info ptr." );
  5032. return;
  5033. }
  5034. // print the struct(s)
  5035. DnsPrint_Lock();
  5036. while ( pInfo )
  5037. {
  5038. PrintRoutine(
  5039. pContext,
  5040. "%s\n"
  5041. "\tinfo ptr %p\n"
  5042. "\tnext ptr %p\n"
  5043. "\tid %d\n",
  5044. pszHeader,
  5045. pInfo,
  5046. pInfo->pNext,
  5047. pInfo->Id
  5048. );
  5049. switch ( pInfo->Id )
  5050. {
  5051. case DNS_EXINFO_ID_RESULTS_V1:
  5052. // print the struct
  5053. PrintRoutine(
  5054. pContext,
  5055. "\tstatus %d\n"
  5056. "\trcode %d\n"
  5057. "\tserver IP %08x %s\n",
  5058. pInfo->ResultsV1.Status,
  5059. pInfo->ResultsV1.Rcode,
  5060. pInfo->ResultsV1.ServerIp4,
  5061. IP4_STRING( pInfo->ResultsV1.ServerIp4 )
  5062. );
  5063. break;
  5064. case DNS_EXINFO_ID_RESULTS_BASIC:
  5065. DnsPrint_ResultsBasic(
  5066. PrintRoutine,
  5067. pContext,
  5068. NULL,
  5069. (PBASIC_RESULTS) & pInfo->ResultsBasic
  5070. );
  5071. break;
  5072. case DNS_EXINFO_ID_SERVER_LIST:
  5073. DnsPrint_DnsAddrArray(
  5074. PrintRoutine,
  5075. pContext,
  5076. "ServerList:",
  5077. NULL,
  5078. pInfo->pServerList
  5079. );
  5080. break;
  5081. case DNS_EXINFO_ID_SERVER_LIST_IP4:
  5082. DnsPrint_Ip4Array(
  5083. PrintRoutine,
  5084. pContext,
  5085. "ServerList IP4:",
  5086. NULL,
  5087. pInfo->pServerList4
  5088. );
  5089. break;
  5090. default:
  5091. // verify this is results blob
  5092. PrintRoutine(
  5093. pContext,
  5094. "\tUnknown update info ID = %d\n",
  5095. pInfo->Id );
  5096. break;
  5097. }
  5098. pInfo = pInfo->pNext;
  5099. }
  5100. DnsPrint_Unlock();
  5101. }
  5102. #if 0
  5103. VOID
  5104. DnsPrint_UpdateResults(
  5105. IN PRINT_ROUTINE PrintRoutine,
  5106. IN OUT PPRINT_CONTEXT pContext,
  5107. IN PSTR pszHeader,
  5108. IN PDNS_UPDATE_RESULT_INFO pResults
  5109. )
  5110. /*++
  5111. Routine Description:
  5112. Print update results.
  5113. Arguments:
  5114. PrintRoutine - routine to print with
  5115. pContext - print context
  5116. pszHeader - header
  5117. pResults - results info
  5118. Return Value:
  5119. None.
  5120. --*/
  5121. {
  5122. if ( !pszHeader )
  5123. {
  5124. pszHeader = "Update Results:";
  5125. }
  5126. if ( !pResults )
  5127. {
  5128. PrintRoutine(
  5129. pContext,
  5130. "%s %s\n",
  5131. pszHeader,
  5132. "NULL Update Results ptr." );
  5133. return;
  5134. }
  5135. // verify this is results blob
  5136. if ( pResults->Id != DNS_UPDATE_INFO_ID_RESULT_INFO )
  5137. {
  5138. PrintRoutine(
  5139. pContext,
  5140. "%s ptr=%p is NOT valid update results id=%d\n",
  5141. pszHeader,
  5142. pResults,
  5143. pResults->Id );
  5144. return;
  5145. }
  5146. // print the struct
  5147. PrintRoutine(
  5148. pContext,
  5149. "%s\n"
  5150. "\tresults ptr %p\n"
  5151. "\tstatus %d\n"
  5152. "\trcode %d\n"
  5153. "\tserver IP %08x %s\n",
  5154. pszHeader,
  5155. pResults,
  5156. pResults->Status,
  5157. pResults->Rcode,
  5158. pResults->ServerIp,
  5159. IP4_STRING( pResults->ServerIp ),
  5160. );
  5161. }
  5162. #endif
  5163. VOID
  5164. DnsPrint_ResultsBasic(
  5165. IN PRINT_ROUTINE PrintRoutine,
  5166. IN OUT PPRINT_CONTEXT pContext,
  5167. IN PSTR pszHeader,
  5168. IN PBASIC_RESULTS pResults
  5169. )
  5170. /*++
  5171. Routine Description:
  5172. Print query results.
  5173. Arguments:
  5174. PrintRoutine - routine to print with
  5175. pContext - print context
  5176. pszHeader - header
  5177. pResults - results info
  5178. Return Value:
  5179. None.
  5180. --*/
  5181. {
  5182. DWORD i;
  5183. CHAR addrString[DNS_ADDR_STRING_BUFFER_LENGTH];
  5184. if ( !pszHeader )
  5185. {
  5186. pszHeader = "Results:";
  5187. }
  5188. if ( !pResults )
  5189. {
  5190. PrintRoutine(
  5191. pContext,
  5192. "%s %s\n",
  5193. pszHeader,
  5194. "NULL Results ptr." );
  5195. return;
  5196. }
  5197. // print the struct
  5198. DnsAddr_WriteStructString_A(
  5199. addrString,
  5200. & pResults->ServerAddr );
  5201. DnsPrint_Lock();
  5202. PrintRoutine(
  5203. pContext,
  5204. "\tStatus %d\n"
  5205. "\tRcode %d\n"
  5206. "\tServer %s\n",
  5207. pResults->Status,
  5208. pResults->Rcode,
  5209. addrString
  5210. );
  5211. DnsPrint_Unlock();
  5212. }
  5213. VOID
  5214. DnsPrint_ResultBlob(
  5215. IN PRINT_ROUTINE PrintRoutine,
  5216. IN OUT PPRINT_CONTEXT pContext,
  5217. IN PSTR pszHeader,
  5218. IN PRESULT_BLOB pResults
  5219. )
  5220. /*++
  5221. Routine Description:
  5222. Print query results.
  5223. Arguments:
  5224. PrintRoutine - routine to print with
  5225. pContext - print context
  5226. pszHeader - header
  5227. pResults - results info
  5228. Return Value:
  5229. None.
  5230. --*/
  5231. {
  5232. DWORD i;
  5233. CHAR addrString[DNS_ADDR_STRING_BUFFER_LENGTH];
  5234. if ( !pszHeader )
  5235. {
  5236. pszHeader = "Results:";
  5237. }
  5238. if ( !pResults )
  5239. {
  5240. PrintRoutine(
  5241. pContext,
  5242. "%s %s\n",
  5243. pszHeader,
  5244. "NULL Results ptr." );
  5245. return;
  5246. }
  5247. // print the struct
  5248. DnsAddr_WriteStructString_A(
  5249. addrString,
  5250. & pResults->ServerAddr );
  5251. DnsPrint_Lock();
  5252. PrintRoutine(
  5253. pContext,
  5254. "\tStatus %d\n"
  5255. "\tRcode %d\n"
  5256. "\tfHaveResponse %d\n"
  5257. "\tServer %s\n"
  5258. "\tpRecords %p\n"
  5259. "\tpMessage %p\n",
  5260. pResults->Status,
  5261. pResults->Rcode,
  5262. pResults->fHaveResponse,
  5263. addrString,
  5264. pResults->pRecords,
  5265. pResults->pMessage
  5266. );
  5267. if ( pResults->pRecords )
  5268. {
  5269. DnsPrint_RecordSet(
  5270. PrintRoutine,
  5271. pContext,
  5272. "\tRecords:\n",
  5273. pResults->pRecords );
  5274. }
  5275. DnsPrint_Unlock();
  5276. }
  5277. VOID
  5278. DnsPrint_SendBlob(
  5279. IN PRINT_ROUTINE PrintRoutine,
  5280. IN OUT PPRINT_CONTEXT pContext,
  5281. IN PSTR pszHeader,
  5282. IN PSEND_BLOB pBlob
  5283. )
  5284. /*++
  5285. Routine Description:
  5286. Print update blob.
  5287. Arguments:
  5288. PrintRoutine - routine to print with
  5289. pContext - print context
  5290. pszHeader - header
  5291. pBlob - send blob
  5292. Return Value:
  5293. None.
  5294. --*/
  5295. {
  5296. DWORD i;
  5297. if ( !pszHeader )
  5298. {
  5299. pszHeader = "Send Blob:";
  5300. }
  5301. if ( !pBlob )
  5302. {
  5303. PrintRoutine(
  5304. pContext,
  5305. "%s %s\n",
  5306. pszHeader,
  5307. "NULL Send Blob ptr." );
  5308. return;
  5309. }
  5310. // print the struct
  5311. DnsPrint_Lock();
  5312. PrintRoutine(
  5313. pContext,
  5314. "%s\n"
  5315. "\tBlob ptr %p\n"
  5316. "\tpNetInfo %p\n"
  5317. "\tpServerArray %p\n"
  5318. "\tpServ4Array %p\n"
  5319. "\tpSendMsg %p\n"
  5320. "\tFlags %08x\n"
  5321. "\tfSaveRecvMsg %d\n"
  5322. "\tfSaveRecords %d\n",
  5323. pszHeader,
  5324. pBlob,
  5325. pBlob->pNetInfo,
  5326. pBlob->pServerList,
  5327. pBlob->pServ4List,
  5328. pBlob->pSendMsg,
  5329. pBlob->Flags,
  5330. pBlob->fSaveResponse,
  5331. pBlob->fSaveRecords
  5332. );
  5333. if ( pBlob->pServerList )
  5334. {
  5335. DnsPrint_DnsAddrArray(
  5336. PrintRoutine,
  5337. pContext,
  5338. "Server List",
  5339. NULL,
  5340. pBlob->pServerList );
  5341. }
  5342. if ( pBlob->pServ4List )
  5343. {
  5344. DnsPrint_Ip4Array(
  5345. PrintRoutine,
  5346. pContext,
  5347. "Server IP4 List",
  5348. NULL,
  5349. pBlob->pServ4List );
  5350. }
  5351. DnsPrint_ResultBlob(
  5352. PrintRoutine,
  5353. pContext,
  5354. "\tSend Results:\n",
  5355. &pBlob->Results );
  5356. DnsPrint_Unlock();
  5357. }
  5358. //
  5359. // End of print.c
  5360. //