Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2384 lines
58 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. #include <tdint.h>
  4. #include <tcp.h>
  5. #include <tcpconn.h>
  6. #include <addr.h>
  7. #include <udp.h>
  8. #include <raw.h>
  9. #include <winsock.h>
  10. #include <tcb.h>
  11. //#define CONN_INDEX(c) ((c) & 0xffffff)
  12. //#define CONN_INST(c) ((uchar)((c) >> 24))
  13. FLAG_INFO FlagsTcb[] =
  14. {
  15. { WINDOW_SET, "Window_Set" },
  16. { CLIENT_OPTIONS, "Client_Options" },
  17. { CONN_ACCEPTED, "Connection_Accepted" },
  18. { ACTIVE_OPEN, "Active_Open" },
  19. { DISC_NOTIFIED, "Disc_Notified" },
  20. { IN_DELAY_Q, "In_Delay_Q" },
  21. { RCV_CMPLTING, "Receives_Completing" },
  22. { IN_RCV_IND, "In_Receive_Indication" },
  23. { NEED_RCV_CMPLT, "Need_To_Have_Rcvs_Completed" },
  24. { NEED_ACK, "Need_To_Send_Ack" },
  25. { NEED_OUTPUT, "Need_To_Output" },
  26. { ACK_DELAYED, "Delayed_Ack" },
  27. { PMTU_BH_PROBE, "PMTU_BH_Probe" },
  28. { BSD_URGENT, "BSD_Urgent" },
  29. { IN_DELIV_URG, "In_Deliver_Urgent" },
  30. { URG_VALID, "Urgent_Valid" },
  31. { FIN_NEEDED, "Fin_Needed" },
  32. { NAGLING, "Nagling" },
  33. { IN_TCP_SEND, "In_Tcp_Send" },
  34. { FLOW_CNTLD, "Flow_Controlled" },
  35. { DISC_PENDING, "Disconnect_Pending" },
  36. { TW_PENDING, "Timed_Wait_Pending" },
  37. { FORCE_OUTPUT, "Force_Output" },
  38. { SEND_AFTER_RCV, "Send_After_Receive" },
  39. { GC_PENDING, "Graceful_Close_Pending" },
  40. { KEEPALIVE, "KeepAlive" },
  41. { URG_INLINE, "Urgent_Inline" },
  42. { FIN_OUTSTANDING, "Fin_Outstanding" },
  43. { FIN_SENT, "Fin_Sent" },
  44. { NEED_RST, "Need_Rst" },
  45. { IN_TCB_TABLE, "In_Tcb_Table" },
  46. { IN_TWTCB_TABLE, "IN_TWTCB_TABLE" },
  47. { IN_TWQUEUE, "IN_TWQUEUE" },
  48. { 0, NULL }
  49. };
  50. FLAG_INFO FlagsFastChk[] =
  51. {
  52. { TCP_FLAG_SLOW, "Need_Slow_Path" },
  53. { TCP_FLAG_IN_RCV, "In_Receive_Path" },
  54. { TCP_FLAG_FASTREC, "FastXmit_In_Progress" },
  55. { 0, NULL }
  56. };
  57. FLAG_INFO FlagsAO[] =
  58. {
  59. { AO_RAW_FLAG, "Raw" },
  60. { AO_DHCP_FLAG, "DHCP" },
  61. { AO_VALID_FLAG, "Valid" },
  62. { AO_BUSY_FLAG, "Busy" },
  63. { AO_OOR_FLAG, "Out_of_Resources" },
  64. { AO_QUEUED_FLAG, "On_PendingQ" },
  65. { AO_XSUM_FLAG, "Use_Xsums" },
  66. { AO_SEND_FLAG, "Send_Pending" },
  67. { AO_OPTIONS_FLAG, "Options_Pending" },
  68. { AO_DELETE_FLAG, "Delete_Pending" },
  69. { AO_BROADCAST_FLAG ,"BCast_Enabled" },
  70. { AO_CONNUDP_FLAG, "Connected_UDP" },
  71. { 0, NULL }
  72. };
  73. ENUM_INFO StateTcb[] =
  74. {
  75. { TCB_CLOSED, "Closed" },
  76. { TCB_LISTEN, "Listening" },
  77. { TCB_SYN_SENT, "Syn_Sent" },
  78. { TCB_SYN_RCVD, "Syn_Received" },
  79. { TCB_ESTAB, "Established" },
  80. { TCB_FIN_WAIT1, "Fin_Wait_1" },
  81. { TCB_FIN_WAIT2, "Fin_Wait_2" },
  82. { TCB_CLOSE_WAIT, "Close_Wait" },
  83. { TCB_CLOSING, "Closing" },
  84. { TCB_LAST_ACK, "Last_Ack" },
  85. { TCB_TIME_WAIT, "Time_Wait" },
  86. { 0, NULL }
  87. };
  88. ENUM_INFO CloseReason[] =
  89. {
  90. { TCB_CLOSE_RST, "RST_Received" },
  91. { TCB_CLOSE_ABORTED, "Local_Abort" },
  92. { TCB_CLOSE_TIMEOUT, "Timed_Out" },
  93. { TCB_CLOSE_REFUSED, "Refused" },
  94. { TCB_CLOSE_UNREACH, "Dest_Unreachable" },
  95. { TCB_CLOSE_SUCCESS, "Sucessful_Close" },
  96. { 0, NULL }
  97. };
  98. ENUM_INFO FsContext2[] =
  99. {
  100. { TDI_TRANSPORT_ADDRESS_FILE, "Transport_Address" },
  101. { TDI_CONNECTION_FILE, "Connection" },
  102. { TDI_CONTROL_CHANNEL_FILE, "Control_Channel" },
  103. { 0, NULL }
  104. };
  105. ENUM_INFO Prot[] =
  106. {
  107. { PROTOCOL_UDP, "Udp" },
  108. { PROTOCOL_TCP, "Tcp" },
  109. { PROTOCOL_RAW, "Raw" },
  110. { 0, NULL }
  111. };
  112. VOID
  113. DumpTcpTCB(
  114. ULONG TcbAddr,
  115. VERBOSITY Verbosity
  116. );
  117. VOID
  118. SearchTCB(
  119. ULONG addressToSearch,
  120. VERBOSITY Verbosity
  121. );
  122. VOID
  123. DumpTcpConn(
  124. ULONG TcpConnAddr,
  125. VERBOSITY Verbosity
  126. );
  127. VOID
  128. DumpTcpConnBlock
  129. (
  130. ULONG TcpConnBlockAddr,
  131. VERBOSITY Verbosity
  132. );
  133. VOID
  134. DumpTcpAO(
  135. ULONG TcpAOAddr,
  136. VERBOSITY Verbosity
  137. );
  138. VOID
  139. Tcptcbtable(
  140. VERBOSITY Verbosity
  141. );
  142. VOID
  143. syntcbtable(
  144. VERBOSITY Verbosity
  145. );
  146. VOID
  147. Tcptwtcbtable(
  148. VERBOSITY Verbosity
  149. );
  150. VOID
  151. DumpTcpConnTable
  152. (
  153. VERBOSITY Verbosity
  154. );
  155. VOID
  156. TcpConnTableStats
  157. (
  158. VERBOSITY Verbosity
  159. );
  160. VOID
  161. TcpAOTableStats
  162. (
  163. VERBOSITY Verbosity
  164. );
  165. VOID
  166. TcpTwqStats
  167. (
  168. VERBOSITY Verbosity
  169. );
  170. VOID
  171. DumpIrp(
  172. PVOID IrpToDump,
  173. BOOLEAN FullOutput
  174. );
  175. DECLARE_API( irp )
  176. /*++
  177. Routine Description:
  178. Dumps the specified Irp
  179. Arguments:
  180. args - Address
  181. Return Value:
  182. None
  183. --*/
  184. {
  185. ULONG irpToDump;
  186. char buf[128];
  187. buf[0] = '\0';
  188. if (*args) {
  189. sscanf(args, "%lx %s", &irpToDump, buf);
  190. DumpIrp((PUCHAR)irpToDump, (BOOLEAN) (buf[0] != '\0'));
  191. }
  192. }
  193. VOID
  194. DumpTcpIrp(
  195. ULONG _objAddr
  196. );
  197. DECLARE_API( tcpfile )
  198. /*++
  199. Routine Description:
  200. Dumps the specified Irp
  201. Arguments:
  202. args - Address
  203. Return Value:
  204. None
  205. --*/
  206. {
  207. ULONG irpToDump;
  208. if (*args) {
  209. sscanf(args, "%lx", &irpToDump);
  210. DumpTcpIrp(irpToDump);
  211. }
  212. }
  213. DECLARE_API( tcb )
  214. {
  215. ULONG addressToDump = 0;
  216. ULONG result;
  217. if ( *args ) {
  218. sscanf(args, "%lx", &addressToDump);
  219. }
  220. DumpTcpTCB( addressToDump, VERBOSITY_NORMAL );
  221. }
  222. DECLARE_API( tcbsrch )
  223. {
  224. ULONG addressToSearch = 0;
  225. ULONG result;
  226. if ( *args ) {
  227. sscanf(args, "%lx", &addressToSearch);
  228. }
  229. SearchTCB( addressToSearch, VERBOSITY_NORMAL );
  230. }
  231. DECLARE_API( tcpconntable )
  232. {
  233. char buf[128];
  234. buf[0] = '\0';
  235. if ( *args ) {
  236. sscanf(args, "%s", buf);
  237. }
  238. if (buf[0] == '\0') {
  239. DumpTcpConnTable( VERBOSITY_NORMAL );
  240. } else {
  241. DumpTcpConnTable( VERBOSITY_FULL );
  242. }
  243. }
  244. DECLARE_API( tcpconnstats )
  245. {
  246. TcpConnTableStats( VERBOSITY_NORMAL );
  247. }
  248. DECLARE_API( tcbtable )
  249. {
  250. char buf[128];
  251. buf[0] = '\0';
  252. if ( *args ) {
  253. sscanf(args, "%s", buf);
  254. }
  255. if (buf[0] == '\0') {
  256. Tcptcbtable( VERBOSITY_NORMAL );
  257. } else {
  258. Tcptcbtable( VERBOSITY_FULL );
  259. }
  260. }
  261. DECLARE_API( syntable )
  262. {
  263. char buf[128];
  264. buf[0] = '\0';
  265. if ( *args ) {
  266. sscanf(args, "%s", buf);
  267. }
  268. if (buf[0] == '\0') {
  269. syntcbtable( VERBOSITY_NORMAL );
  270. } else {
  271. syntcbtable( VERBOSITY_FULL );
  272. }
  273. }
  274. DECLARE_API( twtcbtable )
  275. {
  276. char buf[128];
  277. buf[0] = '\0';
  278. if ( *args ) {
  279. sscanf(args, "%s", buf);
  280. }
  281. if (buf[0] == '\0') {
  282. Tcptwtcbtable( VERBOSITY_NORMAL );
  283. } else {
  284. Tcptwtcbtable( VERBOSITY_FULL );
  285. }
  286. }
  287. DECLARE_API( tcpaostats )
  288. {
  289. TcpAOTableStats( VERBOSITY_NORMAL );
  290. }
  291. DECLARE_API( tcptwqstats )
  292. {
  293. TcpTwqStats( VERBOSITY_NORMAL );
  294. }
  295. DECLARE_API( tcpconn )
  296. {
  297. ULONG addressToDump = 0;
  298. ULONG result;
  299. char buf[128];
  300. buf[0] = '\0';
  301. if ( *args ) {
  302. sscanf(args, "%lx %s", &addressToDump, buf);
  303. }
  304. if (buf[0] == '\0') {
  305. DumpTcpConn( addressToDump, VERBOSITY_NORMAL );
  306. } else {
  307. DumpTcpConn( addressToDump, VERBOSITY_FULL );
  308. }
  309. }
  310. DECLARE_API( tcpconnblock )
  311. {
  312. ULONG addressToDump = 0;
  313. ULONG result;
  314. char buf[128];
  315. buf[0] = '\0';
  316. if ( *args ) {
  317. sscanf(args, "%lx %s", &addressToDump, buf);
  318. }
  319. if (buf[0] == '\0') {
  320. DumpTcpConnBlock( addressToDump, VERBOSITY_NORMAL );
  321. } else {
  322. DumpTcpConnBlock( addressToDump, VERBOSITY_FULL );
  323. }
  324. }
  325. DECLARE_API( ao )
  326. {
  327. ULONG addressToDump = 0;
  328. ULONG result;
  329. if ( *args ) {
  330. sscanf(args, "%lx", &addressToDump);
  331. }
  332. DumpTcpAO( addressToDump, VERBOSITY_NORMAL );
  333. }
  334. #ifdef _obj
  335. # undef _obj
  336. # undef _objAddr
  337. # undef _objType
  338. # undef _objTypeName
  339. #endif
  340. #define _obj Tcb
  341. #define _objAddr TcbToDump
  342. #define _objType TCB
  343. #define _objTypeName "TCB"
  344. VOID
  345. DumpTcpTCB
  346. (
  347. ULONG _objAddr,
  348. VERBOSITY Verbosity
  349. )
  350. /*++
  351. Routine Description:
  352. Dumps the fields of the specified DEVICE_CONTEXT structure
  353. Arguments:
  354. DeviceToDump - The device context object to display
  355. Full - Display a partial listing if 0, full listing otherwise.
  356. Return Value:
  357. None
  358. --*/
  359. {
  360. _objType _obj;
  361. ULONG result;
  362. unsigned int index;
  363. BOOL bActive;
  364. if ( !ReadMemory( _objAddr,
  365. &_obj,
  366. sizeof( _obj ),
  367. &result ))
  368. {
  369. dprintf("%08lx: Could not read %s structure.\n", _objAddr, _objTypeName );
  370. return;
  371. }
  372. #if DBG
  373. CHECK_SIGNATURE( tcb_sig, tcb_signature );
  374. #endif
  375. if ( Verbosity == VERBOSITY_ONE_LINER )
  376. {
  377. dprintf( "NOT IMPLEMENTED" );
  378. return;
  379. }
  380. dprintf( "%s @ %08lx\n", _objTypeName, _objAddr );
  381. PrintStartStruct();
  382. PrintFieldName( "tcb_next" );
  383. dprint_addr_list( ( ULONG )_obj.tcb_next,
  384. FIELD_OFFSET( TCB, tcb_next ));
  385. PrintLock( tcb_lock );
  386. PrintULong( tcb_senduna );
  387. PrintULong( tcb_sendnext );
  388. PrintULong( tcb_sendmax );
  389. PrintULong( tcb_sendwin );
  390. PrintULong( tcb_unacked );
  391. PrintULong( tcb_maxwin );
  392. PrintULong( tcb_cwin );
  393. PrintULong( tcb_ssthresh );
  394. PrintULong( tcb_phxsum );
  395. PrintPtr( tcb_cursend );
  396. PrintPtr( tcb_sendbuf );
  397. PrintULong( tcb_sendofs );
  398. PrintULong( tcb_sendsize );
  399. PrintLLTcp( tcb_sendq );
  400. PrintULong( tcb_rcvnext );
  401. PrintULong( tcb_rcvwin );
  402. PrintULong( tcb_sendwl1 );
  403. PrintULong( tcb_sendwl2 );
  404. PrintPtr( tcb_currcv );
  405. PrintULong( tcb_indicated );
  406. PrintFlags( tcb_flags, FlagsTcb );
  407. PrintFlags( tcb_fastchk, FlagsFastChk );
  408. PrintSymbolPtr( tcb_rcvhndlr );
  409. PrintIPAddress( tcb_daddr );
  410. PrintIPAddress( tcb_saddr );
  411. PrintHTONUShort( tcb_dport );
  412. PrintHTONUShort( tcb_sport );
  413. #if TRACE_EVENT
  414. PrintPtr( tcb_cpcontext ); // CP HOOK context.
  415. #endif
  416. PrintUShort( tcb_mss );
  417. PrintUShort( tcb_rexmit );
  418. PrintULong( tcb_refcnt );
  419. PrintULong( tcb_rttseq );
  420. PrintUShort( tcb_smrtt );
  421. PrintUShort( tcb_delta );
  422. PrintUShort( tcb_remmss );
  423. PrintUChar( tcb_slowcount );
  424. PrintXEnum( tcb_state, StateTcb );
  425. PrintUChar( tcb_rexmitcnt );
  426. PrintUChar( tcb_pending );
  427. PrintUChar( tcb_kacount );
  428. PrintXULong( tcb_error );
  429. PrintULong( tcb_rtt );
  430. PrintULong( tcb_defaultwin );
  431. PrintPtr( tcb_raq );
  432. PrintPtr( tcb_rcvhead );
  433. PrintPtr( tcb_rcvtail );
  434. PrintULong( tcb_pendingcnt );
  435. PrintPtr( tcb_pendhead );
  436. PrintPtr( tcb_pendtail );
  437. PrintPtr( tcb_connreq );
  438. PrintPtr( tcb_conncontext );
  439. PrintULong( tcb_bcountlow );
  440. PrintULong( tcb_bcounthi );
  441. PrintULong( tcb_totaltime );
  442. PrintPtr( tcb_aonext );
  443. PrintPtr( tcb_conn );
  444. PrintLLTcp( tcb_delayq );
  445. PrintXEnum( tcb_closereason, CloseReason );
  446. PrintUChar( tcb_bhprobecnt );
  447. PrintSymbolPtr( tcb_rcvind );
  448. PrintPtr( tcb_ricontext );
  449. PrintPtr( tcb_opt.ioi_options );
  450. PrintIPAddress( tcb_opt.ioi_addr );
  451. PrintUChar( tcb_opt.ioi_optlength );
  452. PrintUChar( tcb_opt.ioi_ttl );
  453. PrintUChar( tcb_opt.ioi_tos );
  454. PrintUChar( tcb_opt.ioi_flags );
  455. PrintUChar( tcb_opt.ioi_hdrincl );
  456. PrintULong( tcb_opt.ioi_GPCHandle );
  457. PrintULong( tcb_opt.ioi_uni );
  458. PrintULong( tcb_opt.ioi_TcpChksum );
  459. PrintULong( tcb_opt.ioi_UdpChksum );
  460. PrintPtr( tcb_rce );
  461. PrintPtr( tcb_discwait );
  462. PrintPtr( tcb_exprcv );
  463. PrintPtr( tcb_urgpending );
  464. PrintULong( tcb_urgcnt );
  465. PrintULong( tcb_urgind );
  466. PrintULong( tcb_urgstart );
  467. PrintULong( tcb_urgend );
  468. PrintULong( tcb_walkcount );
  469. PrintLLTcp( tcb_TWQueue ); // Place to hang all the timed_waits
  470. PrintUShort( tcb_dup ); // For Fast recovery algorithm
  471. PrintUShort( tcb_force ); // Force next send after fast send
  472. PrintULong( tcb_tcpopts ); // rfc 1323 and 2018 options holder
  473. PrintPtr( tcb_SackBlock ); // Sacks which needs to be sent
  474. PrintPtr( tcb_SackRcvd ); // Sacks which needs to be proces
  475. PrintUShort( tcb_sndwinscale ); // send window scale
  476. PrintUShort( tcb_rcvwinscale ); // receive window scale
  477. PrintULong( tcb_tsrecent ); // time stamp recent
  478. PrintULong( tcb_lastack ); // ack number in the last segment sent
  479. PrintULong( tcb_tsupdatetime ); // Time when tsrecent was updated
  480. // used for invalidating TS
  481. PrintPtr( tcb_chainedrcvind ); //for chained receives
  482. PrintPtr( tcb_chainedrcvcontext );
  483. PrintULong( tcb_delackticks );
  484. PrintULong( tcb_GPCCachedIF);
  485. PrintULong( tcb_GPCCachedLink);
  486. PrintPtr( tcb_GPCCachedRTE );
  487. #if DBG
  488. PrintULong( tcb_LargeSend );
  489. #endif
  490. PrintULong( tcb_moreflag );
  491. PrintULong( tcb_partition );
  492. PrintXULong( tcb_connid );
  493. #if ACK_DEBUG
  494. PrintULong( tcb_history_index );
  495. for (index = 0; index < NUM_ACK_HISTORY_ITEMS; index++) {
  496. dprintf("[%2i] seq:%lu unacked:%lu\n",
  497. index,
  498. Tcb.tcb_ack_history[index].sequence,
  499. Tcb.tcb_ack_history[index].unacked);
  500. }
  501. #endif // ACK_DEBUG
  502. #if REFERENCE_DEBUG
  503. PrintULong ( tcb_refhistory_index );
  504. for (index = 0; index < MAX_REFERENCE_HISTORY; index++) {
  505. if (index == _obj.tcb_refhistory_index) {
  506. dprintf( "*");
  507. }
  508. dprintf( "[%2d]\t: Ref %d File ", index, _obj.tcb_refhistory[index].Count );
  509. dprint_ansi_string( _obj.tcb_refhistory[index].File );
  510. dprintf( ",%d Caller ", _obj.tcb_refhistory[index].Line );
  511. dprintSymbolPtr( (_obj.tcb_refhistory[index].Caller), EOL );
  512. }
  513. #endif // REFERENCE_DEBUG
  514. PrintEndStruct();
  515. }
  516. #ifdef _obj
  517. # undef _obj
  518. # undef _objAddr
  519. # undef _objType
  520. # undef _objTypeName
  521. #endif
  522. #define _obj TcpConn
  523. #define _objAddr TcpConnToDump
  524. #define _objType TCPConn
  525. #define _objTypeName "TCPConn"
  526. VOID
  527. DumpTcpConn
  528. (
  529. ULONG _objAddr,
  530. VERBOSITY Verbosity
  531. )
  532. /*++
  533. Routine Description:
  534. Dumps the fields of the specified DEVICE_CONTEXT structure
  535. Arguments:
  536. DeviceToDump - The device context object to display
  537. Full - Display a partial listing if 0, full listing otherwise.
  538. Return Value:
  539. None
  540. --*/
  541. {
  542. _objType _obj;
  543. ULONG result;
  544. unsigned int index;
  545. BOOL bActive;
  546. if ( !ReadMemory( _objAddr,
  547. &_obj,
  548. sizeof( _obj ),
  549. &result ))
  550. {
  551. dprintf("%08lx: Could not read %s structure.\n", _objAddr, _objTypeName );
  552. return;
  553. }
  554. #if DBG
  555. CHECK_SIGNATURE( tc_sig, tc_signature );
  556. #endif
  557. if ( Verbosity == VERBOSITY_ONE_LINER )
  558. {
  559. dprintf( "NOT IMPLEMENTED" );
  560. return;
  561. }
  562. dprintf( "%s @ %08lx\n", _objTypeName, _objAddr );
  563. PrintStartStruct();
  564. PrintLLTcp( tc_q );
  565. PrintPtr( tc_tcb );
  566. PrintPtr( tc_ao );
  567. PrintUChar( tc_inst );
  568. PrintUChar( tc_flags );
  569. PrintUShort( tc_refcnt );
  570. PrintPtr( tc_context );
  571. PrintSymbolPtr( tc_rtn );
  572. PrintPtr( tc_rtncontext );
  573. PrintSymbolPtr( tc_donertn );
  574. PrintFlags( tc_tcbflags, FlagsTcb );
  575. PrintULong( tc_tcbkatime );
  576. PrintULong( tc_tcbkainterval );
  577. PrintULong( tc_window );
  578. PrintPtr( tc_LastTCB );
  579. PrintPtr( tc_ConnBlock );
  580. PrintXULong( tc_connid );
  581. PrintEndStruct();
  582. if (Verbosity == VERBOSITY_FULL) {
  583. if (_obj.tc_tcb) {
  584. DumpTcpTCB( (ULONG)_obj.tc_tcb, VERBOSITY_NORMAL );
  585. }
  586. if (_obj.tc_ao) {
  587. DumpTcpAO( (ULONG)_obj.tc_ao, VERBOSITY_NORMAL );
  588. }
  589. }
  590. }
  591. #ifdef _obj
  592. # undef _obj
  593. # undef _objAddr
  594. # undef _objType
  595. # undef _objTypeName
  596. #endif
  597. #define _obj AddressObject
  598. #define _objAddr AddrObjToDump
  599. #define _objType AddrObj
  600. #define _objTypeName "AddrObj"
  601. VOID
  602. DumpTcpAO
  603. (
  604. ULONG _objAddr,
  605. VERBOSITY Verbosity
  606. )
  607. /*++
  608. Routine Description:
  609. Dumps the fields of the specified DEVICE_CONTEXT structure
  610. Arguments:
  611. DeviceToDump - The device context object to display
  612. Full - Display a partial listing if 0, full listing otherwise.
  613. Return Value:
  614. None
  615. --*/
  616. {
  617. _objType _obj;
  618. ULONG result;
  619. unsigned int index;
  620. BOOL bActive;
  621. if ( !ReadMemory( _objAddr,
  622. &_obj,
  623. sizeof( _obj ),
  624. &result ))
  625. {
  626. dprintf("%08lx: Could not read %s structure.\n", _objAddr, _objTypeName );
  627. return;
  628. }
  629. #if DBG
  630. CHECK_SIGNATURE( ao_sig, ao_signature );
  631. #endif
  632. if ( Verbosity == VERBOSITY_ONE_LINER )
  633. {
  634. dprintf( "NOT IMPLEMENTED" );
  635. return;
  636. }
  637. dprintf( "%s @ %08lx\n", _objTypeName, _objAddr );
  638. PrintStartStruct();
  639. PrintPtr( ao_next );
  640. PrintLock( ao_lock );
  641. PrintPtr( ao_request );
  642. PrintLLTcp( ao_sendq );
  643. PrintLLTcp( ao_pendq );
  644. PrintLLTcp( ao_rcvq );
  645. PrintPtr( ao_opt.ioi_options );
  646. PrintIPAddress( ao_opt.ioi_addr );
  647. PrintUChar( ao_opt.ioi_optlength );
  648. PrintUChar( ao_opt.ioi_ttl );
  649. PrintUChar( ao_opt.ioi_tos );
  650. PrintUChar( ao_opt.ioi_flags );
  651. PrintUChar( ao_opt.ioi_hdrincl );
  652. PrintULong( ao_opt.ioi_GPCHandle );
  653. PrintULong( ao_opt.ioi_uni );
  654. PrintULong( ao_opt.ioi_TcpChksum );
  655. PrintULong( ao_opt.ioi_UdpChksum );
  656. PrintIPAddress( ao_addr );
  657. PrintHTONUShort( ao_port );
  658. PrintFlags( ao_flags, FlagsAO );
  659. PrintXEnum( ao_prot, Prot );
  660. PrintULong( ao_listencnt );
  661. PrintUShort( ao_usecnt );
  662. PrintUShort ( ao_mcast_loop );
  663. PrintUShort( ao_rcvall );
  664. PrintUShort( ao_rcvall_mcast );
  665. PrintPtr( ao_mcastopt.ioi_options );
  666. PrintIPAddress( ao_mcastopt.ioi_addr );
  667. PrintUChar( ao_mcastopt.ioi_optlength );
  668. PrintUChar( ao_mcastopt.ioi_ttl );
  669. PrintUChar( ao_mcastopt.ioi_tos );
  670. PrintUChar( ao_mcastopt.ioi_flags );
  671. PrintIPAddress( ao_mcastaddr );
  672. PrintLLTcp( ao_activeq );
  673. PrintLLTcp( ao_idleq );
  674. PrintLLTcp( ao_listenq );
  675. PrintCTEEvent( ao_event );
  676. PrintSymbolPtr( ao_connect );
  677. PrintPtr( ao_conncontext );
  678. PrintSymbolPtr( ao_disconnect );
  679. PrintPtr( ao_disconncontext );
  680. PrintSymbolPtr( ao_error );
  681. PrintPtr( ao_errcontext );
  682. PrintSymbolPtr( ao_rcv );
  683. PrintPtr( ao_rcvcontext );
  684. PrintSymbolPtr( ao_rcvdg );
  685. PrintPtr( ao_rcvdgcontext );
  686. PrintSymbolPtr( ao_exprcv );
  687. PrintPtr( ao_exprcvcontext );
  688. PrintPtr( ao_mcastlist );
  689. PrintSymbolPtr( ao_dgsend );
  690. PrintUShort( ao_maxdgsize );
  691. PrintSymbolPtr( ao_errorex ); // Error event routine.
  692. PrintPtr( ao_errorexcontext ); // Error event context.
  693. // PrintULong( ConnLimitReached ); //set when there are no connections left
  694. PrintSymbolPtr( ao_chainedrcv ); // Chained Receive event handler
  695. PrintPtr( ao_chainedrcvcontext ); // Chained Receive context.
  696. PrintAddr( ao_udpconn );
  697. PrintULong( ao_udpconn.UserDataLength );
  698. PrintPtr( ao_udpconn.UserData );
  699. PrintULong( ao_udpconn.OptionsLength );
  700. PrintPtr( ao_udpconn.Options );
  701. PrintULong( ao_udpconn.RemoteAddressLength );
  702. PrintPtr (ao_udpconn.RemoteAddress );
  703. PrintPtr ( ao_RemoteAddress );
  704. PrintPtr ( ao_Options );
  705. PrintPtr ( ao_rce );
  706. PrintULong( ao_GPCHandle );
  707. PrintULong( ao_GPCCachedIF );
  708. PrintULong( ao_GPCCachedLink );
  709. PrintPtr ( ao_GPCCachedRTE );
  710. PrintIPAddress( ao_rcesrc );
  711. PrintIPAddress( ao_destaddr );
  712. PrintHTONUShort( ao_destport );
  713. PrintULong( ao_promis_ifindex );
  714. PrintUChar( ao_absorb_rtralert );
  715. PrintULong ( ao_bindindex );
  716. PrintEndStruct();
  717. }
  718. #ifdef _obj
  719. # undef _obj
  720. # undef _objAddr
  721. # undef _objType
  722. # undef _objTypeName
  723. #endif
  724. #define _obj TcpConnBlock
  725. #define _objAddr TcpConnBlockToDump
  726. #define _objType TCPConnBlock
  727. #define _objTypeName "TCPConnBlock"
  728. VOID
  729. DumpTcpConnBlock
  730. (
  731. ULONG _objAddr,
  732. VERBOSITY Verbosity
  733. )
  734. {
  735. _objType _obj;
  736. ULONG result;
  737. unsigned int index;
  738. BOOL bActive;
  739. unsigned int count = 0;
  740. if ( !ReadMemory( _objAddr,
  741. &_obj,
  742. sizeof( _obj ),
  743. &result ))
  744. {
  745. dprintf("%08lx: Could not read %s structure.\n", _objAddr, _objTypeName );
  746. return;
  747. }
  748. dprintf( "%s @ %08lx\n", _objTypeName, _objAddr );
  749. PrintStartStruct();
  750. PrintULong( cb_freecons );
  751. PrintULong( cb_nextfree );
  752. PrintULong( cb_blockid );
  753. PrintULong( cb_conninst );
  754. PrintAddr( cb_conn );
  755. PrintEndStruct();
  756. for (index=0; index<MAX_CONN_PER_BLOCK; index++) {
  757. if ( _obj.cb_conn[index] != NULL ) {
  758. dprintf(" TCPConn @ %08lx\n", _obj.cb_conn[index] );
  759. if (Verbosity == VERBOSITY_FULL) {
  760. DumpTcpConn( (ULONG)(_obj.cb_conn[index]), VERBOSITY_NORMAL );
  761. }
  762. count++;
  763. }
  764. }
  765. dprintf("\n %d Active TCPConn entries in this block.\n", count);
  766. }
  767. VOID
  768. DumpTcpConnTable
  769. (
  770. VERBOSITY Verbosity
  771. )
  772. {
  773. TCPConnBlock **ConnTableBlock, **PreservedPtr;
  774. ULONG result;
  775. unsigned int index;
  776. unsigned int count = 0;
  777. ULONG TabAddr;
  778. ULONG Tablen;
  779. TabAddr = GetUlongValue( "tcpip!ConnTable" );
  780. Tablen = GetUlongValue( "tcpip!MaxConnBlocks" );
  781. dprintf("Dumping ConnTable @ %08lx - ConnTableSize = %08lx\n",
  782. TabAddr, Tablen );
  783. ConnTableBlock = malloc(sizeof( TCPConn * ) * Tablen);
  784. PreservedPtr = ConnTableBlock;
  785. if (ConnTableBlock == NULL) {
  786. dprintf("malloc failed in DumpTcpConnTable.\n");
  787. return;
  788. }
  789. if ( !ReadMemory( TabAddr,
  790. &ConnTableBlock[0],
  791. (sizeof( TCPConnBlock *) * Tablen),
  792. &result ))
  793. {
  794. dprintf("%08lx: Could not read %s structure.\n", TabAddr, "ConnTable" );
  795. free(ConnTableBlock);
  796. return;
  797. }
  798. for (index=0; index<Tablen && !CheckControlC(); index++) {
  799. if ( *ConnTableBlock != NULL ) {
  800. dprintf(" TCPConnBlock @ %08lx\n", *ConnTableBlock );
  801. DumpTcpConnBlock( (ULONG)*ConnTableBlock, VERBOSITY_NORMAL );
  802. count++;
  803. }
  804. ConnTableBlock++;
  805. }
  806. dprintf("\n %d Active TCPConnBlock entries.\n", count);
  807. //free(ConnTable);
  808. free(PreservedPtr);
  809. }
  810. typedef struct ConnStats {
  811. ULONG associated;
  812. ULONG connected;
  813. } ConnStats;
  814. #ifdef _obj
  815. # undef _obj
  816. # undef _objAddr
  817. # undef _objType
  818. # undef _objTypeName
  819. #endif
  820. #define _obj TcpConn
  821. #define _objAddr TcpConnToDump
  822. #define _objType TCPConn
  823. #define _objTypeName "TCPConn"
  824. ULONG
  825. ReadConnInfo
  826. (
  827. ULONG _objAddr
  828. )
  829. {
  830. _objType _obj;
  831. ULONG result;
  832. unsigned int index;
  833. BOOL bActive;
  834. ULONG num=1;
  835. ULONG start=_objAddr;
  836. while (1) {
  837. if ( !ReadMemory( _objAddr,
  838. &_obj,
  839. sizeof( _obj ),
  840. &result ))
  841. {
  842. dprintf("%08lx: Could not read %s structure.\n", _objAddr, _objTypeName );
  843. return(num);
  844. }
  845. _objAddr = (ULONG)_obj.tc_q.q_next;
  846. if (_objAddr == start) {
  847. break;
  848. }
  849. num++;
  850. }
  851. return(num);
  852. }
  853. VOID
  854. TcpConnStats
  855. (
  856. ULONG _objAddr,
  857. ConnStats *CS
  858. )
  859. /*++
  860. Routine Description:
  861. Dumps the fields of the specified DEVICE_CONTEXT structure
  862. Arguments:
  863. DeviceToDump - The device context object to display
  864. Full - Display a partial listing if 0, full listing otherwise.
  865. Return Value:
  866. None
  867. --*/
  868. {
  869. _objType _obj;
  870. ULONG result;
  871. unsigned int index;
  872. BOOL bActive;
  873. if ( !ReadMemory( _objAddr,
  874. &_obj,
  875. sizeof( _obj ),
  876. &result ))
  877. {
  878. dprintf("%08lx: Could not read %s structure.\n", _objAddr, _objTypeName );
  879. return;
  880. }
  881. #if DBG
  882. CHECK_SIGNATURE( tc_sig, tc_signature );
  883. #endif
  884. if (_obj.tc_tcb) {
  885. CS->connected++;
  886. }
  887. if (_obj.tc_ao) {
  888. CS->associated++;
  889. }
  890. }
  891. #ifdef _obj
  892. # undef _obj
  893. # undef _objAddr
  894. # undef _objType
  895. # undef _objTypeName
  896. #endif
  897. #define _obj TcpConnBlock
  898. #define _objAddr TcpConnBlockToDump
  899. #define _objType TCPConnBlock
  900. #define _objTypeName "TCPConnBlock"
  901. VOID
  902. TcpConnTableStats (
  903. VERBOSITY Verbosity
  904. )
  905. {
  906. TCPConn **ConnTableBlock, **PreservedPtr;
  907. ULONG result;
  908. unsigned int index;
  909. unsigned int count = 0;
  910. ULONG TabAddr;
  911. ULONG Tablen;
  912. ConnStats CS = { 0, 0 };
  913. TabAddr = GetUlongValue( "tcpip!ConnTable" );
  914. Tablen = GetUlongValue( "tcpip!MaxConnBlocks" );
  915. dprintf("Statistics for ConnTable @ %08lx - ConnTableSize = %08lx\n",
  916. TabAddr, Tablen );
  917. ConnTableBlock = malloc(sizeof( TCPConn * ) * Tablen);
  918. PreservedPtr = ConnTableBlock;
  919. if (ConnTableBlock == NULL) {
  920. dprintf("malloc failed in DumpTcpConnTable.\n");
  921. return;
  922. }
  923. if ( !ReadMemory( TabAddr,
  924. &ConnTableBlock[0],
  925. (sizeof( TCPConnBlock *) * Tablen),
  926. &result ))
  927. {
  928. dprintf("%08lx: Could not read %s structure.\n", TabAddr, "ConnTable" );
  929. free(PreservedPtr);
  930. return;
  931. }
  932. for (index=0; index<Tablen && !CheckControlC(); index++) {
  933. if ( *ConnTableBlock != NULL ) {
  934. {
  935. ULONG _objAddr;
  936. ULONG result;
  937. unsigned int index;
  938. _objType _obj;
  939. _objAddr = (ULONG) *ConnTableBlock;
  940. if ( !ReadMemory( _objAddr,
  941. &_obj,
  942. sizeof( _obj ),
  943. &result ))
  944. {
  945. dprintf("%08lx: Could not read %s structure.\n", _objAddr, _objTypeName );
  946. free(PreservedPtr);
  947. return;
  948. }
  949. for (index=0; index<MAX_CONN_PER_BLOCK; index++) {
  950. if ( _obj.cb_conn[index] != NULL ) {
  951. count++;
  952. TcpConnStats( (ULONG)(_obj.cb_conn[index]), &CS );
  953. }
  954. }
  955. }
  956. }
  957. ConnTableBlock++;
  958. }
  959. dprintf("\n %d Active TCPConn entries.\n", count);
  960. dprintf("\n %d TCPConn entries are associated with AOs.\n", CS.associated);
  961. dprintf("\n %d TCPConn entries are connected.\n", CS.connected);
  962. free(PreservedPtr);
  963. }
  964. VOID Tcptcbtable(
  965. VERBOSITY Verbosity
  966. )
  967. {
  968. UINT i,result;
  969. TCB *CurrentTcb, *NextTcb;
  970. TCB **TCBTable;
  971. USHORT *TcbDepths;
  972. ULONG_PTR TableAddr;
  973. ULONG TableSize;
  974. ULONG TotalTcbs = 0;
  975. ULONG AverageDepth;
  976. ULONG Variance;
  977. ULONG Depth;
  978. ULONG MinDepth = ~0;
  979. ULONG MaxDepth = 0;
  980. ULONG NumberWithZeroDepth = 0;
  981. TableAddr = GetUlongValue( "tcpip!TcbTable" );
  982. TableSize = GetUlongValue( "tcpip!MaxHashTableSize" );
  983. dprintf("Dumping TcbTable @ %08lx - TableSize = 0x%x (%u)\n",
  984. TableAddr, TableSize, TableSize );
  985. TCBTable = malloc(TableSize * sizeof(TCB *));
  986. if (!TCBTable) {
  987. dprintf("malloc failed in DumpTcbTable.\n");
  988. return;
  989. }
  990. // Array of depths we need in order to go back and calculate the
  991. // variance and standard deviation.
  992. //
  993. TcbDepths = malloc(TableSize * sizeof(USHORT));
  994. if (!TcbDepths) {
  995. free (TCBTable);
  996. dprintf("malloc failed in DumpTcbTable.\n");
  997. return;
  998. }
  999. if ( !ReadMemory(TableAddr,
  1000. TCBTable,
  1001. (sizeof(TCB *) * TableSize),
  1002. &result )) {
  1003. free (TcbDepths);
  1004. free (TCBTable);
  1005. dprintf("%08lx: Could not read %s structure.\n", TCBTable, "Tcb" );
  1006. return;
  1007. }
  1008. for (i = 0; i < TableSize && !CheckControlC(); i++) {
  1009. CurrentTcb = TCBTable[i];
  1010. if (!CurrentTcb)
  1011. {
  1012. NumberWithZeroDepth++;
  1013. }
  1014. Depth = 0;
  1015. while (CurrentTcb != NULL && !CheckControlC()) {
  1016. TotalTcbs++;
  1017. Depth++;
  1018. if ( !ReadMemory((ULONG)CurrentTcb + FIELD_OFFSET(TCB, tcb_next),
  1019. &NextTcb,
  1020. sizeof(TCB*), &result )) {
  1021. dprintf("%08lx: Could not read %s structure.\n", TCBTable, "TcbObj" );
  1022. free (TcbDepths);
  1023. free (TCBTable);
  1024. return;
  1025. }
  1026. if (VERBOSITY_FULL == Verbosity) {
  1027. TCB Tcb;
  1028. if ( !ReadMemory((ULONG)CurrentTcb,
  1029. &Tcb,
  1030. sizeof(TCB),
  1031. &result )) {
  1032. dprintf("%08lx: Could not read %s structure.\n", TCBTable, "TcbObj" );
  1033. free (TcbDepths);
  1034. free (TCBTable);
  1035. return;
  1036. }
  1037. dprintf("[%u] tcb %x :: SA: ", i, CurrentTcb);
  1038. dprint_IP_address( (IPAddr) Tcb.tcb_saddr);
  1039. dprintf(" DA: ");
  1040. dprint_IP_address( (IPAddr) Tcb.tcb_daddr);
  1041. dprintf(" SPort: %u Dport: %u ", htons(Tcb.tcb_sport), htons(Tcb.tcb_dport));
  1042. dprint_enum_name( (ULONG) Tcb.tcb_state, StateTcb );
  1043. dprintf("\n");
  1044. }
  1045. CurrentTcb = NextTcb;
  1046. }
  1047. if (Depth)
  1048. {
  1049. if (Depth > MaxDepth)
  1050. {
  1051. MaxDepth = Depth;
  1052. }
  1053. if (Depth < MinDepth)
  1054. {
  1055. MinDepth = Depth;
  1056. }
  1057. }
  1058. TcbDepths[i] = (USHORT)Depth;
  1059. }
  1060. AverageDepth = TotalTcbs / TableSize;
  1061. Variance = 0;
  1062. for (i = 0; i < TableSize; i++) {
  1063. SHORT Diff = (SHORT)(TcbDepths[i] - (USHORT)AverageDepth);
  1064. Variance += (Diff * Diff);
  1065. }
  1066. Variance /= (TableSize-1);
  1067. dprintf(
  1068. "\n"
  1069. "%10u total TCBs\n"
  1070. "%10u total hash buckets\n"
  1071. "%10u should ideally be in each bucket\n"
  1072. "%10u Minimum (non-zero) depth\n"
  1073. "%10u Maximum depth\n"
  1074. "%10u Variance (Standard Deviation = %0.1f)\n"
  1075. "%10u on average in the non-empty buckets\n"
  1076. "%10u empty hash buckets (%u%% of the hash table is unused)\n",
  1077. TotalTcbs,
  1078. TableSize,
  1079. AverageDepth,
  1080. MinDepth,
  1081. MaxDepth,
  1082. Variance, sqrt(Variance),
  1083. TotalTcbs / (TableSize - NumberWithZeroDepth),
  1084. NumberWithZeroDepth, (NumberWithZeroDepth * 100) / TableSize
  1085. );
  1086. free (TcbDepths);
  1087. free (TCBTable);
  1088. }
  1089. VOID syntcbtable(
  1090. VERBOSITY Verbosity
  1091. )
  1092. {
  1093. UINT i,result;
  1094. Queue *TCBTable;
  1095. Queue *Scan;
  1096. Queue NextItem;
  1097. SYNTCB *CurrentTcb, *NextTcb;
  1098. USHORT *TcbDepths;
  1099. ULONG_PTR TableAddr;
  1100. ULONG TableSize;
  1101. ULONG TotalTcbs = 0;
  1102. ULONG AverageDepth;
  1103. ULONG Variance;
  1104. ULONG Depth;
  1105. ULONG MinDepth = ~0;
  1106. ULONG MaxDepth = 0;
  1107. ULONG NumberWithZeroDepth = 0;
  1108. ULONG TableBuckets;
  1109. TableAddr = GetUlongValue( "tcpip!SynTcbTable" );
  1110. TableBuckets = GetUlongValue("tcpip!MaxHashTableSize");
  1111. TableSize = TableBuckets * sizeof(Queue);
  1112. dprintf("Dumping synTcbTable @ %08lx - TableSize = 0x%x (%u)\n",
  1113. TableAddr, TableSize, TableSize );
  1114. TCBTable = malloc(TableSize);
  1115. if (!TCBTable) {
  1116. dprintf("malloc failed in DumpsynTcbTable.\n");
  1117. return;
  1118. }
  1119. // Array of depths we need in order to go back and calculate the
  1120. // variance and standard deviation.
  1121. //
  1122. TcbDepths = malloc(TableSize * sizeof(USHORT));
  1123. if (!TcbDepths) {
  1124. free (TCBTable);
  1125. dprintf("malloc failed in DumpTcbTable.\n");
  1126. return;
  1127. }
  1128. if ( !ReadMemory(TableAddr,
  1129. TCBTable,
  1130. TableSize,
  1131. &result )) {
  1132. free (TcbDepths);
  1133. free (TCBTable);
  1134. dprintf("%08lx: Could not read %s structure.\n", TCBTable, "Tcb" );
  1135. return;
  1136. }
  1137. for (i = 0; i < TableSize && !CheckControlC(); i++) {
  1138. dprintf("\r...%d%%", (i * 100) / TableBuckets);
  1139. if (TCBTable[i].q_next == (Queue*)(TableAddr + (i * sizeof(Queue))))
  1140. {
  1141. NumberWithZeroDepth++;
  1142. }
  1143. Depth = 0;
  1144. for (Scan = TCBTable[i].q_next;
  1145. Scan != (Queue*)(TableAddr + (i * sizeof(Queue)));
  1146. Scan = NextItem.q_next) {
  1147. TotalTcbs++;
  1148. Depth++;
  1149. if (!ReadMemory((ULONG_PTR)Scan, &NextItem, sizeof(Queue), &result)) {
  1150. dprintf("%08lx: %d Could not read %s structure.\n", TCBTable, i,"scansyntcb" );
  1151. free (TcbDepths);
  1152. free (TCBTable);
  1153. return;
  1154. }
  1155. if (VERBOSITY_FULL == Verbosity) {
  1156. SYNTCB Tcb;
  1157. if (!ReadMemory((ULONG_PTR)Scan - FIELD_OFFSET(SYNTCB, syntcb_link),
  1158. &Tcb,
  1159. sizeof(SYNTCB),
  1160. &result )) {
  1161. dprintf("%08lx: Could not read %s structure.\n", TCBTable, "TcbObj" );
  1162. free (TcbDepths);
  1163. free (TCBTable);
  1164. return;
  1165. }
  1166. dprintf("[%u] tcb %x :: SA: ", i, Tcb);
  1167. //dprint_IP_address( (IPAddr) Tcb.tcb_saddr);
  1168. dprintf(" DA: ");
  1169. dprint_IP_address( (IPAddr) Tcb.syntcb_daddr);
  1170. dprintf(" SPort: %u Dport: %u ", htons(Tcb.syntcb_sport), htons(Tcb.syntcb_dport));
  1171. dprint_enum_name( (ULONG) Tcb.syntcb_state, StateTcb );
  1172. dprintf("\n");
  1173. }
  1174. }
  1175. if (Depth)
  1176. {
  1177. if (Depth > MaxDepth)
  1178. {
  1179. MaxDepth = Depth;
  1180. }
  1181. if (Depth < MinDepth)
  1182. {
  1183. MinDepth = Depth;
  1184. }
  1185. }
  1186. TcbDepths[i] = (USHORT)Depth;
  1187. }
  1188. AverageDepth = TotalTcbs / TableSize;
  1189. Variance = 0;
  1190. for (i = 0; i < TableSize; i++) {
  1191. SHORT Diff = (SHORT)(TcbDepths[i] - (USHORT)AverageDepth);
  1192. Variance += (Diff * Diff);
  1193. }
  1194. Variance /= (TableSize-1);
  1195. dprintf(
  1196. "\n"
  1197. "%10u total TCBs\n"
  1198. "%10u total hash buckets\n"
  1199. "%10u should ideally be in each bucket\n"
  1200. "%10u Minimum (non-zero) depth\n"
  1201. "%10u Maximum depth\n"
  1202. "%10u Variance (Standard Deviation = %0.1f)\n"
  1203. "%10u on average in the non-empty buckets\n"
  1204. "%10u empty hash buckets (%u%% of the hash table is unused)\n",
  1205. TotalTcbs,
  1206. TableSize,
  1207. AverageDepth,
  1208. MinDepth,
  1209. MaxDepth,
  1210. Variance, sqrt(Variance),
  1211. TotalTcbs / (TableSize - NumberWithZeroDepth),
  1212. NumberWithZeroDepth, (NumberWithZeroDepth * 100) / TableSize
  1213. );
  1214. free (TcbDepths);
  1215. free (TCBTable);
  1216. }
  1217. VOID Tcptwtcbtable(
  1218. VERBOSITY Verbosity
  1219. )
  1220. {
  1221. UINT i,result;
  1222. Queue *Table;
  1223. Queue *Scan;
  1224. Queue NextItem;
  1225. USHORT *Depths;
  1226. ULONG_PTR TableAddr;
  1227. ULONG TableBuckets;
  1228. ULONG TableSize;
  1229. ULONG TotalItems = 0;
  1230. ULONG AverageDepth;
  1231. ULONG Variance;
  1232. ULONG Depth;
  1233. ULONG MinDepth = ~0;
  1234. ULONG MaxDepth = 0;
  1235. ULONG NumberWithZeroDepth = 0;
  1236. TableAddr = GetUlongValue("tcpip!TWTCBTable");
  1237. TableBuckets = GetUlongValue("tcpip!MaxHashTableSize");
  1238. TableSize = TableBuckets * sizeof(Queue);
  1239. dprintf("Dumping TWTCBTable @ %08x - TableBuckets = 0x%x (%u)\n",
  1240. TableAddr, TableBuckets, TableBuckets );
  1241. Table = malloc(TableSize);
  1242. if (!Table) {
  1243. dprintf("malloc failed in DumpTcbTable.\n");
  1244. return;
  1245. }
  1246. // Array of depths we need in order to go back and calculate the
  1247. // variance and standard deviation.
  1248. //
  1249. Depths = malloc(TableBuckets * sizeof(USHORT));
  1250. if (!Depths) {
  1251. free (Table);
  1252. dprintf("malloc failed in DumpTcbTable.\n");
  1253. return;
  1254. }
  1255. if (!ReadMemory(TableAddr, Table, TableSize, &result)) {
  1256. free (Depths);
  1257. free (Table);
  1258. dprintf("%08lx: Could not read TWTCBTable structure.\n", Table);
  1259. return;
  1260. }
  1261. for (i = 0; i < TableBuckets && !CheckControlC(); i++) {
  1262. dprintf("\r...%d%%", (i * 100) / TableBuckets);
  1263. if (Table[i].q_next == (Queue*)(TableAddr + (i * sizeof(Queue))))
  1264. {
  1265. NumberWithZeroDepth++;
  1266. }
  1267. Depth = 0;
  1268. for (Scan = Table[i].q_next;
  1269. Scan != (Queue*)(TableAddr + (i * sizeof(Queue)));
  1270. Scan = NextItem.q_next) {
  1271. TotalItems++;
  1272. Depth++;
  1273. if (!ReadMemory((ULONG_PTR)Scan, &NextItem, sizeof(Queue), &result)) {
  1274. dprintf("%08lx: Could not read Queue structure.\n", Table);
  1275. free (Depths);
  1276. free (Table);
  1277. return;
  1278. }
  1279. if (VERBOSITY_FULL == Verbosity) {
  1280. TWTCB Twtcb;
  1281. if (!ReadMemory((ULONG_PTR)Scan - FIELD_OFFSET(TWTCB, twtcb_link),
  1282. &Twtcb,
  1283. sizeof(TWTCB),
  1284. &result )) {
  1285. dprintf("%08lx: Could not read Twtcb structure.\n", Table);
  1286. free (Depths);
  1287. free (Table);
  1288. return;
  1289. }
  1290. dprintf("[%u] twtcb %x :: SA: ", i, (ULONG_PTR)Scan - FIELD_OFFSET(TWTCB, twtcb_link));
  1291. dprint_IP_address( (IPAddr) Twtcb.twtcb_saddr);
  1292. dprintf(" DA: ");
  1293. dprint_IP_address( (IPAddr) Twtcb.twtcb_daddr);
  1294. dprintf(" SPort: %u Dport: %u\n", htons(Twtcb.twtcb_sport), htons(Twtcb.twtcb_dport));
  1295. }
  1296. }
  1297. if (Depth)
  1298. {
  1299. if (Depth > MaxDepth)
  1300. {
  1301. MaxDepth = Depth;
  1302. }
  1303. if (Depth < MinDepth)
  1304. {
  1305. MinDepth = Depth;
  1306. }
  1307. }
  1308. Depths[i] = (USHORT)Depth;
  1309. }
  1310. dprintf("\r...100%%\n");
  1311. AverageDepth = TotalItems / TableBuckets;
  1312. Variance = 0;
  1313. for (i = 0; i < TableBuckets; i++) {
  1314. SHORT Diff = (SHORT)(Depths[i] - (USHORT)AverageDepth);
  1315. Variance += (Diff * Diff);
  1316. }
  1317. Variance /= (TableBuckets-1);
  1318. dprintf(
  1319. "\n"
  1320. "%10u total TWTCBs\n"
  1321. "%10u total hash buckets\n"
  1322. "%10u should ideally be in each bucket\n"
  1323. "%10u Minimum (non-zero) depth\n"
  1324. "%10u Maximum depth\n"
  1325. "%10u Variance (Standard Deviation = %0.1f)\n"
  1326. "%10u on average in the non-empty buckets\n"
  1327. "%10u empty hash buckets (%u%% of the hash table is unused)\n",
  1328. TotalItems,
  1329. TableBuckets,
  1330. AverageDepth,
  1331. MinDepth,
  1332. MaxDepth,
  1333. Variance, sqrt(Variance),
  1334. TotalItems / (TableBuckets - NumberWithZeroDepth),
  1335. NumberWithZeroDepth, (NumberWithZeroDepth * 100) / TableBuckets
  1336. );
  1337. free (Depths);
  1338. free (Table);
  1339. }
  1340. VOID SearchTCB(
  1341. ULONG TcbAddr,
  1342. VERBOSITY Verbosity
  1343. )
  1344. {
  1345. unsigned int i,j=0,result; // Index variable.
  1346. TCB *CurrentTcb; // Current AddrObj being examined.
  1347. TCB Tcb; // Current AddrObj being examined.
  1348. TCB **TCBTable, **PreservedPtr;
  1349. ULONG TableAddr;
  1350. ULONG TableSize;
  1351. int found = 0;
  1352. TCB *PrevTcb;
  1353. TableAddr = GetUlongValue( "tcpip!TcbTable" );
  1354. TableSize = GetUlongValue( "tcpip!MaxHashTableSize" );
  1355. dprintf("Dumping TCbTable @ %08lx - TableSize = %08lx\n",
  1356. TableAddr, TableSize );
  1357. TCBTable = malloc(sizeof( TCB * ) * TableSize);
  1358. PreservedPtr = TCBTable;
  1359. if (TCBTable == NULL) {
  1360. dprintf("malloc failed in DumpTcbTable.\n");
  1361. return;
  1362. }
  1363. dprintf("Searching for Tcb @ %08lx \n", TcbAddr);
  1364. if ( !ReadMemory(TableAddr,
  1365. &TCBTable[0],
  1366. (sizeof( TCB *) * TableSize),
  1367. &result ))
  1368. {
  1369. dprintf("%08lx: Could not read %s structure.\n", TCBTable, "Tcb" );
  1370. return;
  1371. }
  1372. for (i = 0; i < TableSize && !CheckControlC(); i++) {
  1373. CurrentTcb = (TCB *)TCBTable[i];
  1374. j = 0;
  1375. PrevTcb = NULL;
  1376. dprintf("Searching in bucket i %d \n", i+1);
  1377. while (CurrentTcb != NULL && !CheckControlC()) {
  1378. j++;
  1379. if ( !ReadMemory((ULONG)CurrentTcb,
  1380. &Tcb,
  1381. sizeof(TCB),
  1382. &result ))
  1383. {
  1384. dprintf("%08lx: Could not read %s structure.\n", TCBTable, "TcbObj" );
  1385. return;
  1386. }
  1387. if (TcbAddr == (ULONG) CurrentTcb) {
  1388. found = 1;
  1389. dprintf("found tcb %x i %d j %d Prev %x\n", CurrentTcb, i+1, j, PrevTcb);
  1390. return;
  1391. }
  1392. dprintf("still searching j %d Prev %x\n", j, PrevTcb);
  1393. PrevTcb = CurrentTcb;
  1394. CurrentTcb = Tcb.tcb_next;
  1395. }
  1396. dprintf("Search completed in bucket i %d \n", i+1);
  1397. dprintf("************************ \n", i);
  1398. }
  1399. if (found == 0)
  1400. dprintf("\n Not found TCB entries.\n");
  1401. free(PreservedPtr);
  1402. }
  1403. #define EMPTY ((q).q_next == (q))
  1404. VOID
  1405. TcpAOTableStats(
  1406. VERBOSITY Verbosity
  1407. )
  1408. {
  1409. UINT i,result;
  1410. ULONG_PTR TdiErrorHandler;
  1411. ULONG valid=0,busy=0,emptylisten=0,emptyactive=0,emptyidle=0;
  1412. ULONG pendingque=0,pendingdel=0,netbtaos=0,tcpaos=0;
  1413. ULONG numidle, numlisten, numactive;
  1414. AddrObj AO;
  1415. USHORT *Depths;
  1416. ULONG_PTR TableAddr;
  1417. ULONG_PTR AOAddress;
  1418. ULONG TableBuckets;
  1419. ULONG TableSize;
  1420. ULONG TotalItems = 0;
  1421. ULONG AverageDepth;
  1422. ULONG Variance;
  1423. ULONG Depth;
  1424. ULONG MinDepth = ~0;
  1425. ULONG MaxDepth = 0;
  1426. ULONG NumberWithZeroDepth = 0;
  1427. TdiErrorHandler = GetExpression("netbt!TdiErrorHandler");
  1428. TableAddr = GetUlongValue("tcpip!AddrObjTable");
  1429. TableBuckets = GetUlongValue("tcpip!AO_TABLE_SIZE");
  1430. TableSize = TableBuckets * sizeof(AddrObj*);
  1431. dprintf("Statistics for AddrObjTable @ %08x - TableBuckets = 0x%x (%u)\n",
  1432. TableAddr, TableBuckets, TableBuckets );
  1433. // Array of depths we need in order to go back and calculate the
  1434. // variance and standard deviation.
  1435. //
  1436. Depths = malloc(TableBuckets * sizeof(USHORT));
  1437. if (!Depths) {
  1438. dprintf("malloc failed in TcpAOTableStats.\n");
  1439. return;
  1440. }
  1441. for (i = 0; i < TableBuckets && !CheckControlC(); i++) {
  1442. dprintf("\r...%d%%", (i * 100) / TableSize);
  1443. if (!ReadMemory(TableAddr + (i * 4), &AOAddress, sizeof(AddrObj*), &result)) {
  1444. dprintf("%08lx: Could not read AddrObj address.\n", TableAddr + (i * 4));
  1445. free (Depths);
  1446. return;
  1447. }
  1448. if (!AOAddress) {
  1449. NumberWithZeroDepth++;
  1450. }
  1451. Depth = 0;
  1452. while (AOAddress && !CheckControlC()) {
  1453. TotalItems++;
  1454. Depth++;
  1455. if (!ReadMemory(AOAddress, &AO, sizeof(AO), &result)) {
  1456. dprintf("%08lx: Could not read AddrObj structure.\n", AOAddress);
  1457. free (Depths);
  1458. return;
  1459. }
  1460. if (AO.ao_flags & AO_VALID_FLAG) {
  1461. valid++;
  1462. if (AO.ao_flags & AO_BUSY_FLAG) {
  1463. busy++;
  1464. }
  1465. if (AO.ao_flags & AO_QUEUED_FLAG) {
  1466. pendingque++;
  1467. }
  1468. if (AO.ao_flags & AO_DELETE_FLAG) {
  1469. pendingdel++;
  1470. }
  1471. if ((ULONG_PTR)AO.ao_error == TdiErrorHandler) {
  1472. netbtaos++;
  1473. }
  1474. if (AO.ao_prot == 6) {
  1475. tcpaos++;
  1476. }
  1477. //numidle = numactive = numlisten = 0;
  1478. if ((uint)AO.ao_activeq.q_next == (AOAddress + FIELD_OFFSET(AddrObj, ao_activeq.q_next))) {
  1479. emptyactive++;
  1480. } else {
  1481. //numactive = ReadConnInfo((ULONG )AO.ao_activeq.q_next);
  1482. }
  1483. if ((uint)AO.ao_idleq.q_next == (AOAddress + FIELD_OFFSET(AddrObj, ao_idleq.q_next))) {
  1484. emptyidle++;
  1485. } else {
  1486. //numidle = ReadConnInfo((ULONG )AO.ao_idleq.q_next);
  1487. }
  1488. if ((uint)AO.ao_listenq.q_next == (AOAddress + FIELD_OFFSET(AddrObj, ao_listenq.q_next))) {
  1489. emptylisten++;
  1490. } else {
  1491. //numlisten = ReadConnInfo((ULONG )AO.ao_listenq.q_next);
  1492. }
  1493. //dprintf("%x Connidle %d Conactive %d Connlisten %d loop %d\n",
  1494. // AOAddress, numidle, numactive, numlisten,
  1495. // (ushort)AO.ao_mcast_loop );
  1496. } else {
  1497. dprintf(" %x Invalid\n", AOAddress );
  1498. }
  1499. AOAddress = (ULONG_PTR)AO.ao_next;
  1500. }
  1501. if (Depth)
  1502. {
  1503. if (Depth > MaxDepth)
  1504. {
  1505. MaxDepth = Depth;
  1506. }
  1507. if (Depth < MinDepth)
  1508. {
  1509. MinDepth = Depth;
  1510. }
  1511. }
  1512. Depths[i] = (USHORT)Depth;
  1513. }
  1514. dprintf("\r...100%%\n");
  1515. AverageDepth = TotalItems / TableBuckets;
  1516. Variance = 0;
  1517. for (i = 0; i < TableBuckets; i++) {
  1518. SHORT Diff = (SHORT)(Depths[i] - (USHORT)AverageDepth);
  1519. Variance += (Diff * Diff);
  1520. }
  1521. Variance /= (TableBuckets-1);
  1522. dprintf(
  1523. "\n"
  1524. "%10u total Address objects\n"
  1525. "%10u total hash buckets\n"
  1526. "%10u should ideally be in each bucket\n"
  1527. "%10u Minimum (non-zero) depth\n"
  1528. "%10u Maximum depth\n"
  1529. "%10u Variance (Standard Deviation = %0.1f)\n"
  1530. "%10u on average in the non-empty buckets\n"
  1531. "%10u empty hash buckets (%u%% of the hash table is unused)\n",
  1532. TotalItems,
  1533. TableBuckets,
  1534. AverageDepth,
  1535. MinDepth,
  1536. MaxDepth,
  1537. Variance, sqrt(Variance),
  1538. TotalItems / (TableBuckets - NumberWithZeroDepth),
  1539. NumberWithZeroDepth, (NumberWithZeroDepth * 100) / TableBuckets
  1540. );
  1541. free (Depths);
  1542. dprintf("%10u are valid\n", valid);
  1543. dprintf("%10u are busy\n", busy);
  1544. dprintf("%10u with pending queue on\n", pendingque);
  1545. dprintf("%10u with pending delete on\n", pendingdel);
  1546. dprintf("%10u with empty active queue\n", emptyactive);
  1547. dprintf("%10u with empty idle queues\n", emptyidle);
  1548. dprintf("%10u with empty listen queues\n", emptylisten);
  1549. dprintf("%10u NETBT AO's\n", netbtaos);
  1550. dprintf("%10u TCP AO's\n\n", tcpaos);
  1551. }
  1552. VOID
  1553. TcpTwqStats(
  1554. VERBOSITY Verbosity
  1555. )
  1556. {
  1557. int i,j=0,result,sum; // Index variable.
  1558. ULONG_PTR TableAddr, TablePtr;
  1559. ULONG Tcbnext, Tcb;
  1560. TWTCB Tcbstr ;
  1561. ULONG Offset;
  1562. TablePtr = GetExpression( "tcpip!TWQueue" );
  1563. if (!TablePtr) {
  1564. dprintf("Error in tcpip!TWQueue: Please try reload\n");
  1565. return;
  1566. }
  1567. if ( !ReadMemory(TablePtr,
  1568. &TableAddr,
  1569. 4,
  1570. &result ))
  1571. {
  1572. dprintf(" Could not read twqueu \n" );
  1573. return;
  1574. }
  1575. dprintf("Statistics for Twqueue @ %08lx\n",
  1576. TableAddr );
  1577. if ( !ReadMemory(TableAddr,
  1578. &Tcbnext,
  1579. 4,
  1580. &result ))
  1581. {
  1582. dprintf(" Could not read twqueu \n" );
  1583. return;
  1584. }
  1585. sum=i=0;
  1586. // Tcb = Tcbnext - 0x118;
  1587. Tcb = Tcbnext - FIELD_OFFSET(TWTCB, twtcb_TWQueue);
  1588. dprintf(" First tcb::: Tcb %x\n", Tcb );
  1589. while ((Tcbnext != TableAddr) && !CheckControlC()) {
  1590. // Tcb = Tcbnext - 0x118;
  1591. Tcb = Tcbnext - FIELD_OFFSET(TWTCB, twtcb_TWQueue);
  1592. if ( !ReadMemory(Tcb,
  1593. &Tcbstr,
  1594. sizeof(TWTCB),
  1595. &result ))
  1596. {
  1597. dprintf(" Could not read tcb %x \n", Tcb );
  1598. return;
  1599. }
  1600. if (Tcbstr.twtcb_rexmittimer > 0x20) {
  1601. dprintf(" Tcb %x:: delta %u: rexmittimer %u\n ",Tcb,Tcbstr.twtcb_delta,Tcbstr.twtcb_rexmittimer);
  1602. }
  1603. sum += Tcbstr.twtcb_rexmittimer;
  1604. Tcbnext = (ULONG)Tcbstr.twtcb_TWQueue.q_next;
  1605. i++;
  1606. }
  1607. dprintf(" Total %d sum of rexmittimer %d\n ",i, sum);
  1608. }
  1609. #ifdef _obj
  1610. # undef _obj
  1611. # undef _objAddr
  1612. # undef _objType
  1613. # undef _objTypeName
  1614. #endif
  1615. #define _obj TcpConnBlock
  1616. #define _objAddr TcpConnBlockToDump
  1617. #define _objType TCPConnBlock
  1618. #define _objTypeName "TCPConnBlock"
  1619. VOID
  1620. DumpConnection(
  1621. ULONG ConnID
  1622. )
  1623. {
  1624. ULONG ConnIndex = CONN_INDEX(ConnID);
  1625. ULONG ConnBlockId = CONN_BLOCKID(ConnID);
  1626. UCHAR inst = CONN_INST(ConnID);
  1627. ULONG TableAddr;
  1628. ULONG ConnBlockAddr;
  1629. ULONG ConnTableSize;
  1630. ULONG MatchingConn;
  1631. ULONG result;
  1632. ULONG MaxAllocatedConnBlocks;
  1633. TableAddr = GetUlongValue( "tcpip!ConnTable" );
  1634. MaxAllocatedConnBlocks = GetUlongValue( "tcpip!MaxAllocatedConnBlocks" );
  1635. if ((ConnIndex < MAX_CONN_PER_BLOCK) &&
  1636. (ConnBlockId < MaxAllocatedConnBlocks) ){
  1637. // get the ConnBlockId
  1638. TableAddr += (ConnBlockId * sizeof(ULONG));
  1639. if ( !ReadMemory( TableAddr,
  1640. &ConnBlockAddr,
  1641. sizeof( ULONG ),
  1642. &result ))
  1643. {
  1644. dprintf("%08lx: Could not read %s structure.\n", TableAddr, "ConnTableBlock" );
  1645. return;
  1646. }
  1647. if (ConnBlockAddr) {
  1648. _objType _obj;
  1649. ULONG _objAddr;
  1650. _objAddr = ConnBlockAddr;
  1651. if ( !ReadMemory( _objAddr,
  1652. &_obj,
  1653. sizeof( _obj ),
  1654. &result ))
  1655. {
  1656. dprintf("%08lx: Could not read %s structure.\n", _objAddr, _objTypeName );
  1657. return;
  1658. }
  1659. MatchingConn = (ULONG)_obj.cb_conn[ConnIndex];
  1660. if (MatchingConn) {
  1661. DumpTcpConn( MatchingConn, VERBOSITY_FULL );
  1662. } else {
  1663. dprintf( "NULL Conn!!\n");
  1664. }
  1665. } else {
  1666. dprintf( "NULL ConnBlock!!\n");
  1667. }
  1668. } else {
  1669. dprintf( "Invalid ConnIndex!!\n");
  1670. }
  1671. }
  1672. #ifdef _obj
  1673. # undef _obj
  1674. # undef _objAddr
  1675. # undef _objType
  1676. # undef _objTypeName
  1677. #endif
  1678. #define _obj TcpContext
  1679. #define _objAddr TcpContextToDump
  1680. #define _objType TCP_CONTEXT
  1681. #define _objTypeName "Tcp Context"
  1682. VOID
  1683. DumpTcpContext(
  1684. ULONG _objAddr,
  1685. ULONG Type
  1686. )
  1687. {
  1688. _objType _obj;
  1689. ULONG result;
  1690. unsigned int index;
  1691. BOOL bActive;
  1692. if ( !ReadMemory( _objAddr,
  1693. &_obj,
  1694. sizeof( _obj ),
  1695. &result ))
  1696. {
  1697. dprintf("%08lx: Could not read %s structure.\n", _objAddr, _objTypeName );
  1698. return;
  1699. }
  1700. dprintf( "%s @ %08lx\n", _objTypeName, _objAddr );
  1701. PrintStartStruct();
  1702. switch ( Type) {
  1703. case TDI_TRANSPORT_ADDRESS_FILE:
  1704. PrintPtr( Handle.AddressHandle );
  1705. break;
  1706. case TDI_CONNECTION_FILE:
  1707. PrintPtr( Handle.ConnectionContext );
  1708. break;
  1709. case TDI_CONTROL_CHANNEL_FILE:
  1710. PrintPtr( Handle.ControlChannel );
  1711. break;
  1712. default:
  1713. dprintf(" INVALID FsContext2 - Unknown Type \n");
  1714. break;
  1715. }
  1716. PrintULong( ReferenceCount );
  1717. PrintBool( CancelIrps );
  1718. PrintKEvent( CleanupEvent );
  1719. PrintEndStruct();
  1720. switch ( Type) {
  1721. case TDI_TRANSPORT_ADDRESS_FILE:
  1722. break;
  1723. case TDI_CONNECTION_FILE:
  1724. DumpConnection( (ULONG)_obj.Handle.ConnectionContext );
  1725. break;
  1726. case TDI_CONTROL_CHANNEL_FILE:
  1727. break;
  1728. default:
  1729. break;
  1730. }
  1731. }
  1732. #ifdef _obj
  1733. # undef _obj
  1734. # undef _objAddr
  1735. # undef _objType
  1736. # undef _objTypeName
  1737. #endif
  1738. #define _obj FileObj
  1739. #define _objAddr FileObjToDump
  1740. #define _objType FILE_OBJECT
  1741. #define _objTypeName "File Object"
  1742. VOID
  1743. DumpTcpIrp(
  1744. ULONG _objAddr
  1745. )
  1746. {
  1747. _objType _obj;
  1748. ULONG result;
  1749. unsigned int index;
  1750. BOOL bActive;
  1751. if ( !ReadMemory( _objAddr,
  1752. &_obj,
  1753. sizeof( _obj ),
  1754. &result ))
  1755. {
  1756. dprintf("%08lx: Could not read %s structure.\n", _objAddr, _objTypeName );
  1757. return;
  1758. }
  1759. dprintf(" %s @ %08lx\n", _objTypeName, _objAddr );
  1760. PrintPtr( FsContext );
  1761. PrintXEnum( FsContext2, FsContext2 );
  1762. DumpTcpContext( (ULONG)_obj.FsContext, (ULONG)_obj.FsContext2 );
  1763. }
  1764. VOID
  1765. DumpIrp(
  1766. PVOID IrpToDump,
  1767. BOOLEAN FullOutput
  1768. )
  1769. /*++
  1770. Routine Description:
  1771. This routine dumps an Irp. It does not check to see that the address
  1772. supplied actually locates an Irp. This is done to allow for dumping
  1773. Irps post mortem, or after they have been freed or completed.
  1774. Arguments:
  1775. IrpToDump - the address of the irp.
  1776. Return Value:
  1777. None
  1778. --*/
  1779. {
  1780. IO_STACK_LOCATION irpStack;
  1781. PCHAR buffer;
  1782. ULONG irpStackAddress;
  1783. ULONG result;
  1784. IRP irp;
  1785. CCHAR irpStackIndex;
  1786. BOOLEAN TcpIrp = FALSE;
  1787. if ( !ReadMemory( (DWORD) IrpToDump,
  1788. &irp,
  1789. sizeof(irp),
  1790. &result) ) {
  1791. dprintf("%08lx: Could not read Irp\n", IrpToDump);
  1792. return;
  1793. }
  1794. if (irp.Type != IO_TYPE_IRP) {
  1795. dprintf("IRP signature does not match, probably not an IRP\n");
  1796. return;
  1797. }
  1798. dprintf("Irp is Active with %d stacks %d is current\n",
  1799. irp.StackCount,
  1800. irp.CurrentLocation);
  1801. if ((irp.MdlAddress != NULL) && (irp.Type == IO_TYPE_IRP)) {
  1802. dprintf(" Mdl = %08lx ", irp.MdlAddress);
  1803. } else {
  1804. dprintf(" No Mdl ");
  1805. }
  1806. if (irp.AssociatedIrp.MasterIrp != NULL) {
  1807. dprintf("%s = %08lx ",
  1808. (irp.Flags & IRP_ASSOCIATED_IRP) ? "Associated Irp" :
  1809. (irp.Flags & IRP_DEALLOCATE_BUFFER) ? "System buffer" :
  1810. "Irp count",
  1811. irp.AssociatedIrp.MasterIrp);
  1812. }
  1813. dprintf("Thread %08lx: ", irp.Tail.Overlay.Thread);
  1814. if (irp.StackCount > 15) {
  1815. dprintf("Too many Irp stacks to be believed (>15)!!\n");
  1816. return;
  1817. } else {
  1818. if (irp.CurrentLocation > irp.StackCount) {
  1819. dprintf("Irp is completed. ");
  1820. } else {
  1821. dprintf("Irp stack trace. ");
  1822. }
  1823. }
  1824. if (irp.PendingReturned) {
  1825. dprintf("Pending has been returned\n");
  1826. } else {
  1827. dprintf("\n");
  1828. }
  1829. if (FullOutput)
  1830. {
  1831. dprintf("Flags = %08lx\n", irp.Flags);
  1832. dprintf("ThreadListEntry.Flink = %08lx\n", irp.ThreadListEntry.Flink);
  1833. dprintf("ThreadListEntry.Blink = %08lx\n", irp.ThreadListEntry.Blink);
  1834. dprintf("IoStatus.Status = %08lx\n", irp.IoStatus.Status);
  1835. dprintf("IoStatus.Information = %08lx\n", irp.IoStatus.Information);
  1836. dprintf("RequestorMode = %08lx\n", irp.RequestorMode);
  1837. dprintf("Cancel = %02lx\n", irp.Cancel);
  1838. dprintf("CancelIrql = %lx\n", irp.CancelIrql);
  1839. dprintf("ApcEnvironment = %02lx\n", irp.ApcEnvironment);
  1840. dprintf("UserIosb = %08lx\n", irp.UserIosb);
  1841. dprintf("UserEvent = %08lx\n", irp.UserEvent);
  1842. dprintf("Overlay.AsynchronousParameters.UserApcRoutine = %08lx\n", irp.Overlay.AsynchronousParameters.UserApcRoutine);
  1843. dprintf("Overlay.AsynchronousParameters.UserApcContext = %08lx\n", irp.Overlay.AsynchronousParameters.UserApcContext);
  1844. dprintf(
  1845. "Overlay.AllocationSize = %08lx - %08lx\n",
  1846. irp.Overlay.AllocationSize.HighPart,
  1847. irp.Overlay.AllocationSize.LowPart);
  1848. dprintf("CancelRoutine = %08lx\n", irp.CancelRoutine);
  1849. dprintf("UserBuffer = %08lx\n", irp.UserBuffer);
  1850. dprintf("&Tail.Overlay.DeviceQueueEntry = %08lx\n", &irp.Tail.Overlay.DeviceQueueEntry);
  1851. dprintf("Tail.Overlay.Thread = %08lx\n", irp.Tail.Overlay.Thread);
  1852. dprintf("Tail.Overlay.AuxiliaryBuffer = %08lx\n", irp.Tail.Overlay.AuxiliaryBuffer);
  1853. dprintf("Tail.Overlay.ListEntry.Flink = %08lx\n", irp.Tail.Overlay.ListEntry.Flink);
  1854. dprintf("Tail.Overlay.ListEntry.Blink = %08lx\n", irp.Tail.Overlay.ListEntry.Blink);
  1855. dprintf("Tail.Overlay.CurrentStackLocation = %08lx\n", irp.Tail.Overlay.CurrentStackLocation);
  1856. dprintf("Tail.Overlay.OriginalFileObject = %08lx\n", irp.Tail.Overlay.OriginalFileObject);
  1857. dprintf("Tail.Apc = %08lx\n", irp.Tail.Apc);
  1858. dprintf("Tail.CompletionKey = %08lx\n", irp.Tail.CompletionKey);
  1859. }
  1860. irpStackAddress = (ULONG)IrpToDump + sizeof(irp);
  1861. buffer = LocalAlloc(LPTR, 256);
  1862. if (buffer == NULL) {
  1863. dprintf("Can't allocate 256 bytes\n");
  1864. return;
  1865. }
  1866. dprintf(" cmd flg cl Device File Completion-Context\n");
  1867. for (irpStackIndex = 1; irpStackIndex <= irp.StackCount; irpStackIndex++) {
  1868. if ( !ReadMemory( (DWORD) irpStackAddress,
  1869. &irpStack,
  1870. sizeof(irpStack),
  1871. &result) ) {
  1872. dprintf("%08lx: Could not read IrpStack\n", irpStackAddress);
  1873. goto exit;
  1874. }
  1875. dprintf("%c%3x %2x %2x %08lx %08lx %08lx-%08lx %s %s %s %s\n",
  1876. irpStackIndex == irp.CurrentLocation ? '>' : ' ',
  1877. irpStack.MajorFunction,
  1878. irpStack.Flags,
  1879. irpStack.Control,
  1880. irpStack.DeviceObject,
  1881. irpStack.FileObject,
  1882. irpStack.CompletionRoutine,
  1883. irpStack.Context,
  1884. (irpStack.Control & SL_INVOKE_ON_SUCCESS) ? "Success" : "",
  1885. (irpStack.Control & SL_INVOKE_ON_ERROR) ? "Error" : "",
  1886. (irpStack.Control & SL_INVOKE_ON_CANCEL) ? "Cancel" : "",
  1887. (irpStack.Control & SL_PENDING_RETURNED) ? "pending" : "");
  1888. if (irpStack.DeviceObject != NULL) {
  1889. if ((ULONG)irpStack.DeviceObject != GetUlongValue( "tcpip!TCPDeviceObject" )) {
  1890. dprintf("THIS IS NOT A TCP Irp!!!!\n");
  1891. TcpIrp = FALSE;
  1892. } else {
  1893. dprintf("\t \\Driver\\Tcpip");
  1894. TcpIrp = TRUE;
  1895. }
  1896. }
  1897. if (irpStack.CompletionRoutine != NULL) {
  1898. GetSymbol(irpStack.CompletionRoutine, buffer, &result);
  1899. dprintf("\t%s\n", buffer);
  1900. } else {
  1901. dprintf("\n");
  1902. }
  1903. dprintf("\t\t\tArgs: %08lx %08lx %08lx %08lx\n",
  1904. irpStack.Parameters.Others.Argument1,
  1905. irpStack.Parameters.Others.Argument2,
  1906. irpStack.Parameters.Others.Argument3,
  1907. irpStack.Parameters.Others.Argument4);
  1908. irpStackAddress += sizeof(irpStack);
  1909. if (CheckControlC()) {
  1910. goto exit;
  1911. }
  1912. if (TcpIrp) {
  1913. if ( irpStack.FileObject != NULL ) {
  1914. DumpTcpIrp( (ULONG)irpStack.FileObject );
  1915. } else {
  1916. dprintf("FILEOBJECT Ptr is NULL!!!!\n");
  1917. }
  1918. }
  1919. }
  1920. exit:
  1921. LocalFree(buffer);
  1922. }