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.

1169 lines
28 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. tcp.c
  5. Abstract:
  6. TCP kernel debugger extensions.
  7. Author:
  8. Scott Holden (sholden) 24-Apr-1999
  9. Revision History:
  10. --*/
  11. #include "tcpipxp.h"
  12. #include "tcpipkd.h"
  13. // Simple to declare if just dumping a specific address/object type.
  14. TCPIP_DBGEXT(TCB, tcb);
  15. TCPIP_DBGEXT(TWTCB, twtcb);
  16. TCPIP_DBGEXT(AddrObj, ao);
  17. TCPIP_DBGEXT(TCPRcvReq, trr);
  18. TCPIP_DBGEXT(TCPSendReq, tsr);
  19. TCPIP_DBGEXT(SendCmpltContext, scc);
  20. TCPIP_DBGEXT(TCPRAHdr, trh);
  21. TCPIP_DBGEXT(DGSendReq, dsr);
  22. TCPIP_DBGEXT(DGRcvReq, drr);
  23. TCPIP_DBGEXT(TCPConn, tc);
  24. TCPIP_DBGEXT(TCPConnBlock, cb);
  25. TCPIP_DBGEXT(TCPHeader, tcph);
  26. TCPIP_DBGEXT(UDPHeader, udph);
  27. TCPIP_DBGEXT(TCP_CONTEXT, tcpctxt);
  28. TCPIP_DBGEXT(FILE_OBJECT, tcpfo);
  29. TCPIP_DBGEXT_LIST(MDL, mdlc, Next);
  30. //
  31. // Dump TCP global parameters.
  32. //
  33. DECLARE_API(gtcp)
  34. {
  35. dprintf(ENDL);
  36. //
  37. // tcpconn.c
  38. //
  39. TCPIPDump_uint(MaxConnBlocks);
  40. TCPIPDumpCfg_uint(ConnPerBlock, MAX_CONN_PER_BLOCK);
  41. TCPIPDumpCfg_uint(MaxFreeConns, MAX_CONN_PER_BLOCK);
  42. TCPIPDump_uint(ConnsAllocated);
  43. TCPIPDump_uint(ConnsOnFreeList);
  44. TCPIPDump_uint(NextConnBlock);
  45. TCPIPDump_uint(MaxAllocatedConnBlocks);
  46. dprintf(ENDL);
  47. TCPIPDump_DWORD(g_CurIsn);
  48. TCPIPDumpCfg_DWORD(g_cRandIsnStore, 256);
  49. TCPIPDumpCfg_DWORD(g_maskRandIsnStore, 255);
  50. dprintf(ENDL);
  51. TCPIPDump_uint(NumConnReq);
  52. TCPIPDumpCfg_uint(MaxConnReq, 0xffffffff);
  53. TCPIPDump_uint(ConnTableSize);
  54. dprintf(ENDL);
  55. //
  56. // tcpdeliv.c
  57. //
  58. TCPIPDump_uint(NumTCPRcvReq);
  59. TCPIPDumpCfg_uint(MaxRcvReq, 0xffffffff);
  60. dprintf(ENDL);
  61. //
  62. // tcprcv.c
  63. //
  64. TCPIPDumpCfg_uint(MaxRcvWin, 0xffff);
  65. TCPIPDump_uint(MaxDupAcks);
  66. dprintf(ENDL);
  67. //
  68. // tcpsend.c
  69. //
  70. TCPIPDumpCfg_uint(MaxSendSegments, 64);
  71. TCPIPDump_uint(TCPSendHwchksum);
  72. TCPIPDump_uint(TCPCurrentSendFree);
  73. TCPIPDump_uint(NumTCPSendReq);
  74. TCPIPDumpCfg_uint(MaxSendReq , 0xffffffff);
  75. dprintf(ENDL);
  76. //
  77. // tcb.c
  78. //
  79. TCPIPDump_uint(TCBsOnFreeList);
  80. TCPIPDump_uint(TCPTime);
  81. TCPIPDump_uint(TCBWalkCount);
  82. TCPIPDump_uint(CurrentTCBs);
  83. TCPIPDump_uint(CurrentTWTCBs);
  84. TCPIPDumpCfg_uint(MaxTCBs, 0xffffffff);
  85. TCPIPDumpCfg_uint(MaxTWTCBs, 0xffffffff);
  86. TCPIPDumpCfg_uint(MaxFreeTcbs, 1000);
  87. TCPIPDumpCfg_uint(MaxFreeTWTcbs, 1000);
  88. TCPIPDumpCfg_uint(MaxHashTableSize, 512);
  89. TCPIPDump_uint(DeadmanTicks);
  90. TCPIPDump_uint(NumTcbTablePartitions);
  91. TCPIPDump_uint(PerPartitionSize);
  92. TCPIPDump_uint(LogPerPartitionSize);
  93. TCPIPDump_BOOLEAN(fTCBTimerStopping);
  94. dprintf(ENDL);
  95. //
  96. // addr.c
  97. //
  98. TCPIPDump_ushort(NextUserPort);
  99. TCPIPDumpCfg_ULONG(DisableUserTOSSetting, TRUE);
  100. TCPIPDumpCfg_ULONG(DefaultTOSValue, 0);
  101. dprintf(ENDL);
  102. //
  103. // dgram.c
  104. //
  105. TCPIPDump_ULONG(DGCurrentSendFree);
  106. TCPIPDumpCfg_ULONG(DGMaxSendFree, 0x4000);
  107. TCPIPDump_uint(NumSendReq);
  108. TCPIPDump_uint(DGHeaderSize);
  109. dprintf(ENDL);
  110. //
  111. // init.c
  112. //
  113. TCPIPDumpCfg_uint(DeadGWDetect, TRUE);
  114. TCPIPDumpCfg_uint(PMTUDiscovery, TRUE);
  115. TCPIPDumpCfg_uint(PMTUBHDetect, FALSE);
  116. TCPIPDumpCfg_uint(KeepAliveTime, 72000 /*DEFAULT_KEEPALIVE_TIME*/);
  117. TCPIPDumpCfg_uint(KAInterval, 10 /*DEFAULT_KEEPALIVE_INTERVAL*/);
  118. TCPIPDumpCfg_uint(DefaultRcvWin, 0);
  119. dprintf(ENDL);
  120. TCPIPDumpCfg_uint(MaxConnections, DEFAULT_MAX_CONNECTIONS);
  121. TCPIPDumpCfg_uint(MaxConnectRexmitCount, MAX_CONNECT_REXMIT_CNT);
  122. TCPIPDumpCfg_uint(MaxConnectResponseRexmitCount, MAX_CONNECT_RESPONSE_REXMIT_CNT);
  123. TCPIPDump_uint(MaxConnectResponseRexmitCountTmp);
  124. TCPIPDumpCfg_uint(MaxDataRexmitCount, MAX_REXMIT_CNT);
  125. dprintf(ENDL);
  126. //
  127. // ntinit.c
  128. //
  129. TCPIPDump_uint(TCPHalfOpen);
  130. TCPIPDump_uint(TCPHalfOpenRetried);
  131. TCPIPDump_uint(TCPMaxHalfOpen);
  132. TCPIPDump_uint(TCPMaxHalfOpenRetried);
  133. TCPIPDump_uint(TCPMaxHalfOpenRetriedLW);
  134. dprintf(ENDL);
  135. TCPIPDump_uint(TCPPortsExhausted);
  136. TCPIPDump_uint(TCPMaxPortsExhausted);
  137. TCPIPDump_uint(TCPMaxPortsExhaustedLW);
  138. dprintf(ENDL);
  139. TCPIPDumpCfg_BOOLEAN(SynAttackProtect, FALSE);
  140. TCPIPDumpCfg_uint(BSDUrgent, TRUE);
  141. TCPIPDumpCfg_uint(FinWait2TO, FIN_WAIT2_TO * 10);
  142. TCPIPDumpCfg_uint(NTWMaxConnectCount, NTW_MAX_CONNECT_COUNT);
  143. TCPIPDumpCfg_uint(NTWMaxConnectTime, NTW_MAX_CONNECT_TIME * 2);
  144. TCPIPDumpCfg_uint(MaxUserPort, MAX_USER_PORT);
  145. TCPIPDumpCfg_uint(SecurityFilteringEnabled, FALSE);
  146. dprintf(ENDL);
  147. return;
  148. }
  149. //
  150. // Searches TCBs in the TCB table and dumps.
  151. //
  152. DECLARE_API(srchtcbtable)
  153. {
  154. TCB **TcbTable = NULL;
  155. ULONG TcbTableAddr = 0;
  156. ULONG TcbTableSize = 0;
  157. BOOL fStatus;
  158. ULONG i;
  159. PTCPIP_SRCH pSrch = NULL;
  160. pSrch = ParseSrch(
  161. args,
  162. TCPIP_SRCH_ALL,
  163. TCPIP_SRCH_ALL | TCPIP_SRCH_IPADDR | TCPIP_SRCH_PORT | TCPIP_SRCH_STATS);
  164. if (pSrch == NULL)
  165. {
  166. dprintf("srchtcbtable: Invalid parameter" ENDL);
  167. goto done;
  168. }
  169. //
  170. // Now retrieve the table and dump.
  171. //
  172. TcbTableAddr = GetUlongValue("tcpip!TcbTable");
  173. TcbTableSize = GetUlongValue("tcpip!MaxHashTableSize");
  174. // Allocate and read table into memory.
  175. TcbTable = LocalAlloc(LPTR, sizeof(TCB *) * TcbTableSize);
  176. if (TcbTable == NULL)
  177. {
  178. dprintf("Failed to allocate table" ENDL);
  179. goto done;
  180. }
  181. fStatus = GetData(
  182. TcbTable,
  183. sizeof(TCB *) * TcbTableSize,
  184. TcbTableAddr,
  185. "TcbTable");
  186. if (fStatus == FALSE)
  187. {
  188. dprintf("Failed to read table at %x" ENDL, TcbTableAddr);
  189. goto done;
  190. }
  191. dprintf("TcbTable %x, size = %d" ENDL, TcbTableAddr, TcbTableSize);
  192. for (i = 0; i < TcbTableSize; i++)
  193. {
  194. TCB Tcb;
  195. BOOL fPrint;
  196. TCB * pTcb;
  197. pTcb = TcbTable[i];
  198. while (pTcb != NULL)
  199. {
  200. fStatus = GetData(&Tcb, sizeof(TCB), (ULONG_PTR)pTcb, "TCB");
  201. if (fStatus == FALSE)
  202. {
  203. dprintf("Failed to get TCB %x" ENDL, pTcb);
  204. goto done;
  205. }
  206. fPrint = FALSE;
  207. switch (pSrch->ulOp)
  208. {
  209. case TCPIP_SRCH_PORT:
  210. if (Tcb.tcb_sport == htons(pSrch->port) ||
  211. Tcb.tcb_dport == htons(pSrch->port))
  212. {
  213. fPrint = TRUE;
  214. }
  215. break;
  216. case TCPIP_SRCH_IPADDR:
  217. if (Tcb.tcb_saddr == pSrch->ipaddr ||
  218. Tcb.tcb_daddr == pSrch->ipaddr)
  219. {
  220. fPrint = TRUE;
  221. }
  222. break;
  223. case TCPIP_SRCH_STATS:
  224. fPrint = FALSE;
  225. break;
  226. case TCPIP_SRCH_ALL:
  227. fPrint = TRUE;
  228. break;
  229. }
  230. if (fPrint == TRUE)
  231. {
  232. dprintf("[%4d] ", i); // Print which table entry it is in.
  233. fStatus = DumpTCB(&Tcb, (ULONG_PTR) pTcb, g_Verbosity);
  234. if (fStatus == FALSE)
  235. {
  236. dprintf("Failed to dump TCB %x" ENDL, pTcb);
  237. }
  238. }
  239. pTcb = Tcb.tcb_next;
  240. if (CheckControlC())
  241. {
  242. goto done;
  243. }
  244. }
  245. }
  246. done:
  247. if (pSrch)
  248. {
  249. LocalFree(pSrch);
  250. }
  251. if (TcbTable)
  252. {
  253. LocalFree(TcbTable);
  254. }
  255. return;
  256. }
  257. //
  258. // Searches time-wait TCB table.
  259. //
  260. DECLARE_API(srchtwtcbtable)
  261. {
  262. // Don't fix until I know that change has stopped.
  263. #if 0
  264. TWTCB **TwtcbTable = NULL;
  265. ULONG TwtcbTableAddr = 0;
  266. ULONG TwtcbTableSize = 0;
  267. BOOL fStatus;
  268. ULONG i;
  269. PTCPIP_SRCH pSrch = NULL;
  270. pSrch = ParseSrch(
  271. args,
  272. TCPIP_SRCH_ALL,
  273. TCPIP_SRCH_ALL | TCPIP_SRCH_IPADDR | TCPIP_SRCH_PORT | TCPIP_SRCH_STATS);
  274. if (pSrch == NULL)
  275. {
  276. dprintf("srchtwtcbtable: Invalid parameter" ENDL);
  277. goto done;
  278. }
  279. //
  280. // Now retrieve the table and dump.
  281. //
  282. TwtcbTableAddr = GetUlongValue("tcpip!TwtcbTable");
  283. TwtcbTableSize = GetUlongValue("tcpip!MaxHashTableSize");
  284. // Allocate and read table into memory.
  285. TwtcbTable = LocalAlloc(LPTR, sizeof(TWTCB *) * TwtcbTableSize);
  286. if (TwtcbTable == NULL)
  287. {
  288. dprintf("Failed to allocate table" ENDL);
  289. goto done;
  290. }
  291. fStatus = GetData(
  292. TwtcbTable,
  293. sizeof(TWTCB *) * TwtcbTableSize,
  294. TwtcbTableAddr,
  295. "TwtcbTable");
  296. if (fStatus == FALSE)
  297. {
  298. dprintf("Failed to read table at %x" ENDL, TwtcbTableAddr);
  299. goto done;
  300. }
  301. dprintf("TwtcbTable %x, size = %d" ENDL, TwtcbTableAddr, TwtcbTableSize);
  302. for (i = 0; i < TwtcbTableSize; i++)
  303. {
  304. TWTCB Twtcb;
  305. BOOL fPrint;
  306. TWTCB * pTwtcb;
  307. pTwtcb = TwtcbTable[i];
  308. while (pTwtcb != NULL)
  309. {
  310. fStatus = GetData(&Twtcb, sizeof(TWTCB), (ULONG_PTR)pTwtcb, "TWTCB");
  311. if (fStatus == FALSE)
  312. {
  313. dprintf("Failed to get TWTCB %x" ENDL, pTwtcb);
  314. goto done;
  315. }
  316. fPrint = FALSE;
  317. switch (pSrch->ulOp)
  318. {
  319. case TCPIP_SRCH_PORT:
  320. if (Twtcb.twtcb_sport == htons(pSrch->port) ||
  321. Twtcb.twtcb_dport == htons(pSrch->port))
  322. {
  323. fPrint = TRUE;
  324. }
  325. break;
  326. case TCPIP_SRCH_IPADDR:
  327. if (Twtcb.twtcb_saddr == pSrch->ipaddr ||
  328. Twtcb.twtcb_daddr == pSrch->ipaddr)
  329. {
  330. fPrint = TRUE;
  331. }
  332. break;
  333. case TCPIP_SRCH_STATS:
  334. fPrint = FALSE;
  335. break;
  336. case TCPIP_SRCH_ALL:
  337. fPrint = TRUE;
  338. break;
  339. }
  340. if (fPrint == TRUE)
  341. {
  342. dprintf("[%4d] ", i); // Print which table entry it is in.
  343. fStatus = DumpTWTCB(&Twtcb, (ULONG_PTR) pTwtcb, g_Verbosity);
  344. if (fStatus == FALSE)
  345. {
  346. dprintf("Failed to dump TWTCB %x" ENDL, pTwtcb);
  347. }
  348. }
  349. pTwtcb = Twtcb.twtcb_next;
  350. if (CheckControlC())
  351. {
  352. goto done;
  353. }
  354. }
  355. }
  356. done:
  357. if (pSrch)
  358. {
  359. LocalFree(pSrch);
  360. }
  361. if (TwtcbTable)
  362. {
  363. LocalFree(TwtcbTable);
  364. }
  365. return;
  366. #endif
  367. }
  368. //
  369. // Searches time-wait TCB queue.
  370. //
  371. DECLARE_API(srchtwtcbq)
  372. {
  373. #if 0
  374. Queue *TwtcbQ = NULL;
  375. ULONG TwtcbQAddr = 0;
  376. ULONG TwtcbQSize = 0;
  377. BOOL fStatus;
  378. ULONG i;
  379. PTCPIP_SRCH pSrch = NULL;
  380. pSrch = ParseSrch(
  381. args,
  382. TCPIP_SRCH_ALL,
  383. TCPIP_SRCH_ALL | TCPIP_SRCH_IPADDR | TCPIP_SRCH_PORT | TCPIP_SRCH_STATS);
  384. if (pSrch == NULL)
  385. {
  386. dprintf("srchtwtcbq: Invalid parameter" ENDL);
  387. goto done;
  388. }
  389. //
  390. // Now retrieve the table and dump.
  391. //
  392. TwtcbQAddr = GetUlongValue("tcpip!TWQueue");
  393. TwtcbQSize = GetUlongValue("tcpip!NumTcbTablePartitions");
  394. // Allocate and read table into memory.
  395. TwtcbQ = LocalAlloc(LPTR, sizeof(Queue) * TwtcbQSize);
  396. if (TwtcbQ == NULL)
  397. {
  398. dprintf("Failed to allocate table" ENDL);
  399. goto done;
  400. }
  401. fStatus = GetData(
  402. TwtcbQ,
  403. sizeof(Queue) * TwtcbQSize,
  404. TwtcbQAddr,
  405. "TWQueue");
  406. if (fStatus == FALSE)
  407. {
  408. dprintf("Failed to read table at %x" ENDL, TwtcbQAddr);
  409. goto done;
  410. }
  411. dprintf("TwtcbQ %x, size = %d" ENDL, TwtcbQAddr, TwtcbQSize);
  412. for (i = 0; i < TwtcbQSize; i++)
  413. {
  414. TWTCB Twtcb;
  415. BOOL fPrint;
  416. TWTCB * pTwtcb;
  417. Queue * pQ;
  418. pQ = TwtcbQ[i].q_next;
  419. while (pQ != (Queue *)((PBYTE)TwtcbQAddr + sizeof(Queue) * i))
  420. {
  421. pTwtcb = STRUCT_OF(TWTCB, pQ, twtcb_TWQueue);
  422. fStatus = GetData(&Twtcb, sizeof(TWTCB), (ULONG_PTR)pTwtcb, "TWTCB");
  423. if (fStatus == FALSE)
  424. {
  425. dprintf("Failed to get TWTCB %x" ENDL, pTwtcb);
  426. goto done;
  427. }
  428. fPrint = FALSE;
  429. switch (pSrch->ulOp)
  430. {
  431. case TCPIP_SRCH_PORT:
  432. if (Twtcb.twtcb_sport == htons(pSrch->port) ||
  433. Twtcb.twtcb_dport == htons(pSrch->port))
  434. {
  435. fPrint = TRUE;
  436. }
  437. break;
  438. case TCPIP_SRCH_IPADDR:
  439. if (Twtcb.twtcb_saddr == pSrch->ipaddr ||
  440. Twtcb.twtcb_daddr == pSrch->ipaddr)
  441. {
  442. fPrint = TRUE;
  443. }
  444. break;
  445. case TCPIP_SRCH_STATS:
  446. fPrint = FALSE;
  447. break;
  448. case TCPIP_SRCH_ALL:
  449. fPrint = TRUE;
  450. break;
  451. }
  452. if (fPrint == TRUE)
  453. {
  454. dprintf("[%4d] ", i); // Print which queue it is in.
  455. fStatus = DumpTWTCB(&Twtcb, (ULONG_PTR) pTwtcb, g_Verbosity);
  456. if (fStatus == FALSE)
  457. {
  458. dprintf("Failed to dump TWTCB %x" ENDL, pTwtcb);
  459. }
  460. }
  461. pTwtcb = Twtcb.twtcb_next;
  462. if (CheckControlC())
  463. {
  464. goto done;
  465. }
  466. pQ = Twtcb.twtcb_TWQueue.q_next;
  467. }
  468. }
  469. done:
  470. if (pSrch)
  471. {
  472. LocalFree(pSrch);
  473. }
  474. if (TwtcbQ)
  475. {
  476. LocalFree(TwtcbQ);
  477. }
  478. return;
  479. #endif
  480. }
  481. //
  482. // Searches AddrObj table.
  483. //
  484. DECLARE_API(srchaotable)
  485. {
  486. ULONG_PTR AoTableAddr;
  487. DWORD AoTableSize;
  488. AddrObj *AoTable[AO_TABLE_SIZE];
  489. BOOL fStatus;
  490. DWORD i;
  491. ULONG cAos = 0;
  492. ULONG cValidAos = 0;
  493. ULONG cBusyAos = 0;
  494. ULONG cQueueAos = 0;
  495. ULONG cDeleteAos = 0;
  496. ULONG cNetbtAos = 0;
  497. ULONG cTcpAos = 0;
  498. PTCPIP_SRCH pSrch = NULL;
  499. pSrch = ParseSrch(
  500. args,
  501. TCPIP_SRCH_ALL,
  502. TCPIP_SRCH_ALL | TCPIP_SRCH_IPADDR | TCPIP_SRCH_PORT |
  503. TCPIP_SRCH_STATS | TCPIP_SRCH_PROT);
  504. if (pSrch == NULL)
  505. {
  506. dprintf("srchaotable: Invalid parameter" ENDL);
  507. goto done;
  508. }
  509. AoTableAddr = GetExpression("tcpip!AddrObjTable");
  510. AoTableSize = AO_TABLE_SIZE;
  511. fStatus = GetData(
  512. AoTable,
  513. sizeof(AddrObj *) * AO_TABLE_SIZE,
  514. AoTableAddr,
  515. "AoTable");
  516. if (fStatus == FALSE)
  517. {
  518. dprintf("Failed to read table at %x" ENDL, AoTableAddr);
  519. goto done;
  520. }
  521. dprintf("AoTable %x, size %d" ENDL, AoTableAddr, AoTableSize);
  522. for (i = 0; i < AoTableSize; i++)
  523. {
  524. AddrObj Ao;
  525. BOOL fPrint;
  526. AddrObj *pAo;
  527. pAo = AoTable[i];
  528. while (pAo != NULL)
  529. {
  530. fStatus = GetData(
  531. &Ao,
  532. sizeof(AddrObj),
  533. (ULONG_PTR)pAo,
  534. "AddrObj");
  535. if (fStatus == FALSE)
  536. {
  537. dprintf("Failed to get AddrObj %x" ENDL, pAo);
  538. goto done;
  539. }
  540. fPrint = FALSE; // Default.
  541. switch (pSrch->ulOp)
  542. {
  543. case TCPIP_SRCH_PORT:
  544. if (Ao.ao_port == htons(pSrch->port))
  545. {
  546. fPrint = TRUE;
  547. }
  548. break;
  549. case TCPIP_SRCH_PROT:
  550. if (Ao.ao_prot == pSrch->prot)
  551. {
  552. fPrint = TRUE;
  553. }
  554. break;
  555. case TCPIP_SRCH_IPADDR:
  556. if (Ao.ao_addr == pSrch->ipaddr)
  557. {
  558. fPrint = TRUE;
  559. }
  560. break;
  561. case TCPIP_SRCH_STATS:
  562. fPrint = FALSE;
  563. break;
  564. case TCPIP_SRCH_ALL:
  565. fPrint = TRUE;
  566. break;
  567. }
  568. if (fPrint == TRUE)
  569. {
  570. dprintf("[%4d] ", i); // Print which entry.
  571. fStatus = DumpAddrObj(&Ao, (ULONG_PTR)pAo, g_Verbosity);
  572. if (fStatus == FALSE)
  573. {
  574. dprintf("Failed to dump AO %x" ENDL, pAo);
  575. }
  576. }
  577. // Collect stats.
  578. cAos++;
  579. if (Ao.ao_flags & AO_VALID_FLAG)
  580. {
  581. cValidAos++;
  582. if (Ao.ao_flags & AO_BUSY_FLAG)
  583. cBusyAos++;
  584. if (Ao.ao_flags & AO_QUEUED_FLAG)
  585. cQueueAos++;
  586. if (Ao.ao_flags & AO_DELETE_FLAG)
  587. cDeleteAos++;
  588. if ((ULONG_PTR)Ao.ao_error == GetExpression("netbt!TdiErrorHandler"))
  589. cNetbtAos++;
  590. if (Ao.ao_prot == PROTOCOL_TCP)
  591. cTcpAos++;
  592. }
  593. pAo = Ao.ao_next;
  594. if (CheckControlC())
  595. {
  596. goto done;
  597. }
  598. }
  599. }
  600. dprintf("AO Entries: %d::" ENDL, cAos);
  601. dprintf(TAB "Valid AOs: %d" ENDL, cValidAos);
  602. dprintf(TAB "Busy AOs: %d" ENDL, cBusyAos);
  603. dprintf(TAB "AOs with pending queue: %d" ENDL, cQueueAos);
  604. dprintf(TAB "AOs with pending delete: %d" ENDL, cDeleteAos);
  605. dprintf(TAB "Netbt AOs: %d" ENDL, cNetbtAos);
  606. dprintf(TAB "TCP AOs: %d" ENDL, cTcpAos);
  607. done:
  608. if (pSrch)
  609. {
  610. LocalFree(pSrch);
  611. }
  612. return;
  613. }
  614. //
  615. // Dumps the TCPConns associated with the TCPConnBlock.
  616. //
  617. BOOL
  618. SrchConnBlock(
  619. ULONG_PTR CbAddr,
  620. ULONG op,
  621. VERB verb
  622. )
  623. {
  624. TCPConnBlock cb;
  625. TCPConnBlock *pCb = &cb;
  626. BOOL fStatus;
  627. ULONG i;
  628. fStatus = GetData(
  629. pCb,
  630. sizeof(TCPConnBlock),
  631. CbAddr,
  632. "TCPConnBlock");
  633. if (fStatus == FALSE)
  634. {
  635. dprintf("Failed to read TCPConnBlock @ %x" ENDL, CbAddr);
  636. goto done;
  637. }
  638. fStatus = DumpTCPConnBlock(
  639. pCb,
  640. CbAddr,
  641. VERB_MED);
  642. for (i = 0; i < MAX_CONN_PER_BLOCK; i++)
  643. {
  644. if (CheckControlC())
  645. {
  646. goto done;
  647. }
  648. if (pCb->cb_conn[i] != NULL)
  649. {
  650. TCPConn tc;
  651. fStatus = GetData(
  652. &tc,
  653. sizeof(TCPConn),
  654. (ULONG_PTR) pCb->cb_conn[i],
  655. "TCPConn");
  656. if (fStatus == FALSE)
  657. {
  658. dprintf("Failed to read TCPConn @ %x" ENDL, pCb->cb_conn[i]);
  659. goto done;
  660. }
  661. fStatus = DumpTCPConn(&tc, (ULONG_PTR) pCb->cb_conn[i], verb);
  662. if (fStatus == FALSE)
  663. {
  664. dprintf("Failed to dump TCPConn @ %x" ENDL, pCb->cb_conn[i]);
  665. }
  666. }
  667. }
  668. done:
  669. return (TRUE);
  670. }
  671. //
  672. // Dumps the TCPConn's in the conn table.
  673. //
  674. DECLARE_API(conntable)
  675. {
  676. TCPConnBlock **CbTable = NULL;
  677. ULONG CbTableAddr = 0;
  678. ULONG CbTableSize = 0;
  679. BOOL fStatus;
  680. ULONG i;
  681. //
  682. // Now retrieve the table and dump.
  683. //
  684. CbTableAddr = GetUlongValue("tcpip!ConnTable");
  685. CbTableSize = GetUlongValue("tcpip!ConnTableSize");
  686. CbTableSize = CbTableSize/MAX_CONN_PER_BLOCK;
  687. // Allocate and read table into memory.
  688. CbTable = LocalAlloc(LPTR, sizeof(TWTCB *) * CbTableSize);
  689. if (CbTable == NULL)
  690. {
  691. dprintf("Failed to allocate table" ENDL);
  692. goto done;
  693. }
  694. fStatus = GetData(
  695. CbTable,
  696. sizeof(TCPConnBlock *) * CbTableSize,
  697. CbTableAddr,
  698. "ConnTable");
  699. if (fStatus == FALSE)
  700. {
  701. dprintf("Failed to read table at %x" ENDL, CbTableAddr);
  702. goto done;
  703. }
  704. dprintf("ConnTable %x, size = %d" ENDL, CbTableAddr, CbTableSize);
  705. for (i = 0; i < CbTableSize; i++)
  706. {
  707. if (CheckControlC())
  708. {
  709. goto done;
  710. }
  711. if (CbTable[i] != NULL)
  712. {
  713. dprintf("[%4d] ", i);
  714. fStatus = SrchConnBlock(
  715. (ULONG_PTR) CbTable[i],
  716. TCPIP_SRCH_ALL | TCPIP_SRCH_STATS,
  717. g_Verbosity);
  718. if (fStatus == FALSE)
  719. {
  720. dprintf("Failed to dump ConnBlock @ %x" ENDL, CbTable[i]);
  721. }
  722. }
  723. }
  724. done:
  725. if (CbTable)
  726. {
  727. LocalFree(CbTable);
  728. }
  729. return;
  730. }
  731. //
  732. // Dumps a TCP IRP.
  733. //
  734. DECLARE_API(tcpirp)
  735. {
  736. ULONG_PTR IrpAddr;
  737. ULONG_PTR IrpspAddr;
  738. IRP irp;
  739. IO_STACK_LOCATION irpsp;
  740. LONG iIrpsp;
  741. BOOL fTcpIrp = TRUE;
  742. BOOL fStatus;
  743. if (!*args)
  744. {
  745. dprintf("Usage: !irp <address>" ENDL);
  746. return;
  747. }
  748. IrpAddr = GetExpression(args);
  749. fStatus = GetData(&irp, sizeof(IRP), IrpAddr, "IRP");
  750. if (fStatus == FALSE)
  751. {
  752. dprintf("Failed to get IRP %x" ENDL, IrpAddr);
  753. return;
  754. }
  755. if (irp.Type != IO_TYPE_IRP)
  756. {
  757. dprintf("IRP sig does not match. Likely not a n IRP" ENDL);
  758. return;
  759. }
  760. dprintf("IRP is active with %d stacks, %d is current" ENDL,
  761. irp.StackCount,
  762. irp.CurrentLocation);
  763. if ((irp.MdlAddress != NULL) && (irp.Type == IO_TYPE_IRP))
  764. {
  765. dprintf(" Mdl = %08lx ", irp.MdlAddress);
  766. }
  767. else
  768. {
  769. dprintf(" No Mdl ");
  770. }
  771. if (irp.AssociatedIrp.MasterIrp != NULL)
  772. {
  773. dprintf("%s = %08lx ",
  774. (irp.Flags & IRP_ASSOCIATED_IRP) ? "Associated Irp" :
  775. (irp.Flags & IRP_DEALLOCATE_BUFFER) ? "System buffer" :
  776. "Irp count",
  777. irp.AssociatedIrp.MasterIrp);
  778. }
  779. dprintf("Thread %08lx: ", irp.Tail.Overlay.Thread);
  780. if (irp.StackCount > 15)
  781. {
  782. dprintf("Too many Irp stacks to be believed (>15)!!" ENDL);
  783. return;
  784. }
  785. else
  786. {
  787. if (irp.CurrentLocation > irp.StackCount)
  788. {
  789. dprintf("Irp is completed. ");
  790. }
  791. else
  792. {
  793. dprintf("Irp stack trace. ");
  794. }
  795. }
  796. if (irp.PendingReturned)
  797. {
  798. dprintf("Pending has been returned" ENDL);
  799. }
  800. else
  801. {
  802. dprintf("" ENDL);
  803. }
  804. if (g_Verbosity == VERB_MAX)
  805. {
  806. dprintf("Flags = %08lx" ENDL, irp.Flags);
  807. dprintf("ThreadListEntry.Flink = %08lx" ENDL, irp.ThreadListEntry.Flink);
  808. dprintf("ThreadListEntry.Blink = %08lx" ENDL, irp.ThreadListEntry.Blink);
  809. dprintf("IoStatus.Status = %08lx" ENDL, irp.IoStatus.Status);
  810. dprintf("IoStatus.Information = %08lx" ENDL, irp.IoStatus.Information);
  811. dprintf("RequestorMode = %08lx" ENDL, irp.RequestorMode);
  812. dprintf("Cancel = %02lx" ENDL, irp.Cancel);
  813. dprintf("CancelIrql = %lx" ENDL, irp.CancelIrql);
  814. dprintf("ApcEnvironment = %02lx" ENDL, irp.ApcEnvironment);
  815. dprintf("UserIosb = %08lx" ENDL, irp.UserIosb);
  816. dprintf("UserEvent = %08lx" ENDL, irp.UserEvent);
  817. dprintf("Overlay.AsynchronousParameters.UserApcRoutine = %08lx" ENDL, irp.Overlay.AsynchronousParameters.UserApcRoutine);
  818. dprintf("Overlay.AsynchronousParameters.UserApcContext = %08lx" ENDL, irp.Overlay.AsynchronousParameters.UserApcContext);
  819. dprintf("Overlay.AllocationSize = %08lx - %08lx" ENDL,
  820. irp.Overlay.AllocationSize.HighPart,
  821. irp.Overlay.AllocationSize.LowPart);
  822. dprintf("CancelRoutine = %08lx" ENDL, irp.CancelRoutine);
  823. dprintf("UserBuffer = %08lx" ENDL, irp.UserBuffer);
  824. dprintf("&Tail.Overlay.DeviceQueueEntry = %08lx" ENDL, &irp.Tail.Overlay.DeviceQueueEntry);
  825. dprintf("Tail.Overlay.Thread = %08lx" ENDL, irp.Tail.Overlay.Thread);
  826. dprintf("Tail.Overlay.AuxiliaryBuffer = %08lx" ENDL, irp.Tail.Overlay.AuxiliaryBuffer);
  827. dprintf("Tail.Overlay.ListEntry.Flink = %08lx" ENDL, irp.Tail.Overlay.ListEntry.Flink);
  828. dprintf("Tail.Overlay.ListEntry.Blink = %08lx" ENDL, irp.Tail.Overlay.ListEntry.Blink);
  829. dprintf("Tail.Overlay.CurrentStackLocation = %08lx" ENDL, irp.Tail.Overlay.CurrentStackLocation);
  830. dprintf("Tail.Overlay.OriginalFileObject = %08lx" ENDL, irp.Tail.Overlay.OriginalFileObject);
  831. dprintf("Tail.Apc = %08lx" ENDL, irp.Tail.Apc);
  832. dprintf("Tail.CompletionKey = %08lx" ENDL, irp.Tail.CompletionKey);
  833. }
  834. IrpspAddr = IrpAddr + sizeof(IRP);
  835. for (iIrpsp = 0; iIrpsp < irp.StackCount; iIrpsp++)
  836. {
  837. fStatus = GetData(
  838. &irpsp,
  839. sizeof(IO_STACK_LOCATION),
  840. IrpspAddr,
  841. "IO_STACK_LOCATION");
  842. if (fStatus == FALSE)
  843. {
  844. dprintf("Failed to read IRP stack @ %x" ENDL, IrpspAddr);
  845. break;
  846. }
  847. dprintf("%c%3x %2x %2x %08lx %08lx %08lx-%08lx %s %s %s %s" ENDL,
  848. iIrpsp == irp.CurrentLocation ? '>' : ' ',
  849. irpsp.MajorFunction,
  850. irpsp.Flags,
  851. irpsp.Control,
  852. irpsp.DeviceObject,
  853. irpsp.FileObject,
  854. irpsp.CompletionRoutine,
  855. irpsp.Context,
  856. (irpsp.Control & SL_INVOKE_ON_SUCCESS) ? "Success" : "",
  857. (irpsp.Control & SL_INVOKE_ON_ERROR) ? "Error" : "",
  858. (irpsp.Control & SL_INVOKE_ON_CANCEL) ? "Cancel" : "",
  859. (irpsp.Control & SL_PENDING_RETURNED) ? "pending" : "");
  860. if (irpsp.DeviceObject != NULL)
  861. {
  862. ULONG_PTR TcpDevObj;
  863. TcpDevObj = GetUlongValue("tcpip!TCPDeviceObject");
  864. dprintf("tcpdevobj %x" ENDL, TcpDevObj);
  865. if ((ULONG)irpsp.DeviceObject != TcpDevObj)
  866. {
  867. dprintf("THIS IS NOT A TCP Irp!!!!" ENDL);
  868. fTcpIrp = FALSE;
  869. }
  870. else
  871. {
  872. dprintf(TAB TAB "\\Driver\\Tcpip");
  873. fTcpIrp = TRUE;
  874. }
  875. }
  876. DumpPtrSymbol(irpsp.CompletionRoutine);
  877. dprintf(TAB TAB TAB "Args: %08lx %08lx %08lx %08lx" ENDL,
  878. irpsp.Parameters.Others.Argument1,
  879. irpsp.Parameters.Others.Argument2,
  880. irpsp.Parameters.Others.Argument3,
  881. irpsp.Parameters.Others.Argument4);
  882. if (fTcpIrp == TRUE)
  883. {
  884. if (irpsp.FileObject != NULL)
  885. {
  886. FILE_OBJECT fo;
  887. fStatus = GetData(
  888. &fo,
  889. sizeof(FILE_OBJECT),
  890. (ULONG_PTR)irpsp.FileObject,
  891. "FILE_OBJECT");
  892. if (fStatus == FALSE)
  893. {
  894. dprintf("Failed to read FILE_OBJECT @ %x" ENDL,
  895. irpsp.FileObject);
  896. }
  897. else
  898. {
  899. DumpFILE_OBJECT(&fo, (ULONG_PTR)irpsp.FileObject, g_Verbosity);
  900. if (fo.FsContext)
  901. {
  902. TCP_CONTEXT tc;
  903. fStatus = GetData(
  904. &tc,
  905. sizeof(TCP_CONTEXT),
  906. (ULONG_PTR) fo.FsContext,
  907. "TCP_CONTEXT");
  908. if (fStatus == FALSE)
  909. {
  910. dprintf("Failed to read TCP_CONTEXT @ %x" ENDL,
  911. fo.FsContext);
  912. }
  913. else
  914. {
  915. DumpTCP_CONTEXT_typed(
  916. &tc,
  917. (ULONG_PTR) fo.FsContext,
  918. g_Verbosity,
  919. (ULONG_PTR) fo.FsContext2);
  920. }
  921. }
  922. }
  923. }
  924. }
  925. if (CheckControlC())
  926. {
  927. break;
  928. }
  929. IrpspAddr += sizeof(irpsp);
  930. }
  931. return;
  932. }