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.

1245 lines
33 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. tcpipkd.c
  5. Abstract:
  6. Contains Win9x TCP/IP KD extensions.
  7. Author:
  8. Scott Holden (sholden) 24-Apr-1999
  9. Revision History:
  10. --*/
  11. #include "tcpipxp.h"
  12. #include "tcpipkd.h"
  13. #if TCPIPKD
  14. //
  15. // Globals.
  16. //
  17. // Default global verbosity level of dumping structures.
  18. VERB g_Verbosity = VERB_MIN;
  19. //
  20. // Basic structure dumping functions.
  21. //
  22. TCPIP_DBGEXT(TCB, tcb);
  23. TCPIP_DBGEXT(TWTCB, twtcb);
  24. TCPIP_DBGEXT(AddrObj, ao);
  25. TCPIP_DBGEXT(TCPRcvReq, trr);
  26. TCPIP_DBGEXT(TCPSendReq, tsr);
  27. TCPIP_DBGEXT(SendCmpltContext, scc);
  28. TCPIP_DBGEXT(TCPRAHdr, trh);
  29. TCPIP_DBGEXT(DGSendReq, dsr);
  30. TCPIP_DBGEXT(DGRcvReq, drr);
  31. TCPIP_DBGEXT(TCPConn, tc);
  32. TCPIP_DBGEXT(TCPConnBlock, cb);
  33. TCPIP_DBGEXT(TCPHeader, tcph);
  34. TCPIP_DBGEXT(UDPHeader, udph);
  35. TCPIP_DBGEXT(TCP_CONTEXT, tcpctxt);
  36. TCPIP_DBGEXT(FILE_OBJECT, tcpfo);
  37. TCPIP_DBGEXT_LIST(MDL, mdlc, Next);
  38. TCPIP_DBGEXT(NetTableEntry, nte);
  39. TCPIP_DBGEXT(IPInfo, ipi);
  40. TCPIP_DBGEXT(PacketContext, pc);
  41. TCPIP_DBGEXT(ARPInterface, ai);
  42. TCPIP_DBGEXT(RouteCacheEntry, rce);
  43. TCPIP_DBGEXT(IPHeader, iph);
  44. TCPIP_DBGEXT(ICMPHeader, icmph);
  45. TCPIP_DBGEXT(ARPHeader, arph);
  46. TCPIP_DBGEXT(ARPIPAddr, aia);
  47. TCPIP_DBGEXT(ARPTableEntry, ate);
  48. TCPIP_DBGEXT(RouteTableEntry, rte);
  49. TCPIP_DBGEXT(LinkEntry, link);
  50. TCPIP_DBGEXT(Interface, interface);
  51. TCPIP_DBGEXT(IPOptInfo, ioi);
  52. TCPIP_DBGEXT(LLIPBindInfo, lip);
  53. TCPIP_DBGEXT(NPAGED_LOOKASIDE_LIST, ppl);
  54. TCPIP_DBGEXT(NDIS_PACKET, np);
  55. //
  56. // NDIS_BUFFERs specific to MILLEN. On other platforms, its just an MDL.
  57. //
  58. typedef struct _XNDIS_BUFFER {
  59. struct _NDIS_BUFFER *Next;
  60. PVOID VirtualAddress;
  61. PVOID Pool;
  62. UINT Length;
  63. UINT Signature;
  64. } XNDIS_BUFFER, *PXNDIS_BUFFER;
  65. BOOL
  66. DumpXNDIS_BUFFER(
  67. PXNDIS_BUFFER pBuffer,
  68. ULONG_PTR BufferAddr,
  69. VERB verb
  70. )
  71. {
  72. Print_ptr(pBuffer, Next);
  73. Print_ptr(pBuffer, VirtualAddress);
  74. Print_uint(pBuffer, Length);
  75. Print_ptr(pBuffer, Pool);
  76. Print_sig(pBuffer, Signature);
  77. return (TRUE);
  78. }
  79. TCPIP_DBGEXT(XNDIS_BUFFER, nb);
  80. TCPIP_DBGEXT_LIST(XNDIS_BUFFER, nbc, Next);
  81. // END special NDIS_BUFFER treatment.
  82. extern Interface *IFList;
  83. extern uint NumIF;
  84. VOID Tcpipkd_iflist(
  85. PVOID args[]
  86. )
  87. {
  88. Interface *pIf;
  89. BOOL fStatus;
  90. pIf = IFList;
  91. dprintf("IfList %x, size %d" ENDL, IFList, NumIF);
  92. while (pIf) {
  93. fStatus = DumpInterface(pIf, (ULONG_PTR) pIf, g_Verbosity);
  94. if (fStatus == FALSE) {
  95. dprintf("Failed to dump Interface @ %x" ENDL, pIf);
  96. break;
  97. }
  98. pIf = pIf->if_next;
  99. }
  100. }
  101. extern LIST_ENTRY ArpInterfaceList;
  102. VOID
  103. Tcpipkd_ailist(
  104. PVOID args[]
  105. )
  106. {
  107. ARPInterface *pAi;
  108. BOOL fStatus;
  109. pAi = (ARPInterface *) ArpInterfaceList.Flink;
  110. dprintf("ArpInterfaceList %x:" ENDL, &ArpInterfaceList);
  111. while ((PLIST_ENTRY) pAi != &ArpInterfaceList) {
  112. fStatus = DumpARPInterface(pAi, (ULONG_PTR) pAi, g_Verbosity);
  113. if (fStatus == FALSE)
  114. {
  115. dprintf("Failed to dump ARPInterface @ %x" ENDL, pAi);
  116. break;
  117. }
  118. pAi = (ARPInterface *) pAi->ai_linkage.Flink;
  119. }
  120. }
  121. extern NetTableEntry **NewNetTableList;
  122. extern uint NET_TABLE_SIZE;
  123. VOID
  124. Tcpipkd_srchntelist(
  125. PVOID args[]
  126. )
  127. {
  128. uint i;
  129. NetTableEntry *pNte;
  130. TCPIP_SRCH Srch;
  131. PTCPIP_SRCH pSrch = &Srch;
  132. BOOLEAN fPrint;
  133. ULONG cTotalNtes = 0;
  134. NTSTATUS NtStatus;
  135. BOOL fStatus;
  136. NtStatus = ParseSrch(
  137. (PCHAR *) args,
  138. TCPIP_SRCH_ALL,
  139. TCPIP_SRCH_ALL | TCPIP_SRCH_IPADDR | TCPIP_SRCH_CONTEXT,
  140. pSrch);
  141. if (NtStatus != STATUS_SUCCESS) {
  142. dprintf("invalid paramter\n");
  143. goto done;
  144. }
  145. dprintf("NteList %x, size %d" ENDL, NewNetTableList, NET_TABLE_SIZE);
  146. for (i = 0; i < NET_TABLE_SIZE; i++) {
  147. pNte = NewNetTableList[i];
  148. while (pNte != NULL) {
  149. cTotalNtes++;
  150. fPrint = FALSE;
  151. switch (pSrch->ulOp)
  152. {
  153. case TCPIP_SRCH_CONTEXT:
  154. if (pNte->nte_context == (ushort)pSrch->context)
  155. {
  156. fPrint = TRUE;
  157. }
  158. break;
  159. case TCPIP_SRCH_IPADDR:
  160. if (pNte->nte_addr == pSrch->ipaddr)
  161. {
  162. fPrint = TRUE;
  163. }
  164. break;
  165. case TCPIP_SRCH_ALL:
  166. fPrint = TRUE;
  167. break;
  168. }
  169. if (fPrint == TRUE)
  170. {
  171. dprintf("[%4d] ", i);
  172. fStatus = DumpNetTableEntry(pNte, (ULONG_PTR) pNte, g_Verbosity);
  173. if (fStatus == FALSE)
  174. {
  175. dprintf("Failed to dump NTE %x" ENDL, pNte);
  176. }
  177. }
  178. pNte = pNte->nte_next;
  179. }
  180. }
  181. dprintf("Total NTEs = %d" ENDL, cTotalNtes);
  182. done:
  183. return;
  184. }
  185. VOID
  186. Tcpipkd_arptable(
  187. PVOID args[]
  188. )
  189. {
  190. ARPTable *ArpTable;
  191. ARPTableEntry *pAte;
  192. BOOL fStatus;
  193. ULONG cActiveAtes = 0;
  194. ULONG i;
  195. ULONG_PTR Addr;
  196. VERB verb = g_Verbosity;
  197. if (*args == NULL) {
  198. dprintf("!arptable <ptr>" ENDL);
  199. goto done;
  200. }
  201. ParseAddrArg(args, &Addr, &verb);
  202. ArpTable = (ARPTable *)Addr;
  203. dprintf("ARPTable %x:" ENDL, ArpTable);
  204. for (i = 0; i < ARP_TABLE_SIZE; i++) {
  205. pAte = (*ArpTable)[i];
  206. while (pAte) {
  207. cActiveAtes++;
  208. fStatus = DumpARPTableEntry(pAte, (ULONG_PTR) pAte, verb);
  209. if (fStatus == FALSE) {
  210. dprintf("Failed to dump ARPTableEntry @ %x" ENDL, pAte);
  211. goto done;
  212. }
  213. pAte = pAte->ate_next;
  214. }
  215. }
  216. dprintf("Active ARPTable entries = %d" ENDL, cActiveAtes);
  217. done:
  218. return;
  219. }
  220. VOID
  221. Tcpipkd_arptables(
  222. PVOID args[]
  223. )
  224. {
  225. ARPInterface *pAi;
  226. ARPTableEntry *pAte;
  227. ULONG i;
  228. BOOL fStatus;
  229. ULONG cActiveAtes = 0;
  230. pAi = (ARPInterface *) ArpInterfaceList.Flink;
  231. while ((PLIST_ENTRY) pAi != &ArpInterfaceList) {
  232. if (pAi->ai_ARPTbl) {
  233. dprintf("AI %x: ArpTable %x:" ENDL, pAi, pAi->ai_ARPTbl);
  234. for (i = 0; i < ARP_TABLE_SIZE; i++) {
  235. pAte = (*pAi->ai_ARPTbl)[i];
  236. while (pAte) {
  237. cActiveAtes++;
  238. fStatus = DumpARPTableEntry(pAte, (ULONG_PTR) pAte, g_Verbosity);
  239. if (fStatus == FALSE) {
  240. dprintf("Failed to dump ARPTableEntry @ %x" ENDL, pAte);
  241. goto done;
  242. }
  243. pAte = pAte->ate_next;
  244. }
  245. }
  246. }
  247. pAi = (ARPInterface *) pAi->ai_linkage.Flink;
  248. }
  249. dprintf("Active ARPTable entries = %d" ENDL, cActiveAtes);
  250. done:
  251. return;
  252. }
  253. VOID
  254. Tcpipkd_srchlink(
  255. PVOID args[]
  256. )
  257. {
  258. dprintf("srchlink NOT supported\n");
  259. return;
  260. }
  261. extern VOID
  262. Tcpipkd_rtes(
  263. PVOID args[]
  264. );
  265. extern VOID
  266. Tcpipkd_rtetable(
  267. PVOID args[]
  268. );
  269. extern TCB **TCBTable;
  270. VOID
  271. Tcpipkd_srchtcbtable(
  272. PVOID args[]
  273. )
  274. {
  275. TCPIP_SRCH Srch;
  276. PTCPIP_SRCH pSrch = &Srch;
  277. NTSTATUS NtStatus;
  278. TCB *pTcb;
  279. ULONG i;
  280. BOOLEAN fPrint;
  281. BOOL fStatus;
  282. NtStatus = ParseSrch(
  283. (PCHAR *) args,
  284. TCPIP_SRCH_ALL,
  285. TCPIP_SRCH_ALL | TCPIP_SRCH_IPADDR | TCPIP_SRCH_PORT | TCPIP_SRCH_STATS,
  286. pSrch);
  287. if (!NT_SUCCESS(NtStatus))
  288. {
  289. dprintf("srchtcbtable: Invalid parameter" ENDL);
  290. goto done;
  291. }
  292. for (i = 0; i < MaxHashTableSize; i++) {
  293. pTcb = TCBTable[i];
  294. while (pTcb) {
  295. fPrint = FALSE;
  296. switch (pSrch->ulOp)
  297. {
  298. case TCPIP_SRCH_PORT:
  299. if (pTcb->tcb_sport == htons(pSrch->port) ||
  300. pTcb->tcb_dport == htons(pSrch->port))
  301. {
  302. fPrint = TRUE;
  303. }
  304. break;
  305. case TCPIP_SRCH_IPADDR:
  306. if (pTcb->tcb_saddr == pSrch->ipaddr ||
  307. pTcb->tcb_daddr == pSrch->ipaddr)
  308. {
  309. fPrint = TRUE;
  310. }
  311. break;
  312. case TCPIP_SRCH_STATS:
  313. fPrint = FALSE;
  314. break;
  315. case TCPIP_SRCH_ALL:
  316. fPrint = TRUE;
  317. break;
  318. }
  319. if (fPrint == TRUE)
  320. {
  321. dprintf("[%4d] ", i); // Print which table entry it is in.
  322. fStatus = DumpTCB(pTcb, (ULONG_PTR) pTcb, g_Verbosity);
  323. if (fStatus == FALSE)
  324. {
  325. dprintf("Failed to dump TCB %x" ENDL, pTcb);
  326. }
  327. }
  328. pTcb = pTcb->tcb_next;
  329. }
  330. }
  331. done:
  332. return;
  333. }
  334. #if 0
  335. extern TWTCB **TWTCBTable;
  336. VOID
  337. Tcpipkd_srchtwtcbtable(
  338. PVOID args[]
  339. )
  340. {
  341. TCPIP_SRCH Srch;
  342. PTCPIP_SRCH pSrch = &Srch;
  343. NTSTATUS NtStatus;
  344. TWTCB *pTwtcb;
  345. ULONG i;
  346. BOOLEAN fPrint;
  347. BOOL fStatus;
  348. NtStatus = ParseSrch(
  349. (PCHAR *) args,
  350. TCPIP_SRCH_ALL,
  351. TCPIP_SRCH_ALL | TCPIP_SRCH_IPADDR | TCPIP_SRCH_PORT | TCPIP_SRCH_STATS,
  352. pSrch);
  353. if (!NT_SUCCESS(NtStatus))
  354. {
  355. dprintf("srchtwtcbtable: Invalid parameter" ENDL);
  356. goto done;
  357. }
  358. for (i = 0; i < MaxHashTableSize; i++) {
  359. pTwtcb = TWTCBTable[i];
  360. while (pTwtcb) {
  361. fPrint = FALSE;
  362. switch (pSrch->ulOp)
  363. {
  364. case TCPIP_SRCH_PORT:
  365. if (pTwtcb->twtcb_sport == htons(pSrch->port) ||
  366. pTwtcb->twtcb_dport == htons(pSrch->port))
  367. {
  368. fPrint = TRUE;
  369. }
  370. break;
  371. case TCPIP_SRCH_IPADDR:
  372. if (pTwtcb->twtcb_saddr == pSrch->ipaddr ||
  373. pTwtcb->twtcb_daddr == pSrch->ipaddr)
  374. {
  375. fPrint = TRUE;
  376. }
  377. break;
  378. case TCPIP_SRCH_STATS:
  379. fPrint = FALSE;
  380. break;
  381. case TCPIP_SRCH_ALL:
  382. fPrint = TRUE;
  383. break;
  384. }
  385. if (fPrint == TRUE)
  386. {
  387. dprintf("[%4d] ", i); // Print which table entry it is in.
  388. fStatus = DumpTWTCB(pTwtcb, (ULONG_PTR) pTwtcb, g_Verbosity);
  389. if (fStatus == FALSE)
  390. {
  391. dprintf("Failed to dump TCB %x" ENDL, pTwtcb);
  392. }
  393. }
  394. pTwtcb = pTwtcb->twtcb_next;
  395. }
  396. }
  397. done:
  398. return;
  399. }
  400. #endif
  401. VOID
  402. Tcpipkd_srchtwtcbtable(
  403. PVOID args[]
  404. )
  405. {
  406. dprintf("srchtwtcbtable NOT supported\n");
  407. return;
  408. }
  409. VOID
  410. Tcpipkd_srchtwtcbq(
  411. PVOID args[]
  412. )
  413. {
  414. dprintf("srchtwtcbq NOT supported\n");
  415. return;
  416. }
  417. extern AddrObj *AddrObjTable[];
  418. VOID
  419. Tcpipkd_srchaotable(
  420. PVOID args[]
  421. )
  422. {
  423. ULONG cAos = 0;
  424. ULONG cValidAos = 0;
  425. ULONG cBusyAos = 0;
  426. ULONG cQueueAos = 0;
  427. ULONG cDeleteAos = 0;
  428. ULONG cNetbtAos = 0;
  429. ULONG cTcpAos = 0;
  430. TCPIP_SRCH Srch;
  431. PTCPIP_SRCH pSrch = &Srch;
  432. ULONG i;
  433. AddrObj *pAo;
  434. BOOL fStatus;
  435. BOOLEAN fPrint;
  436. NTSTATUS NtStatus;
  437. NtStatus = ParseSrch(
  438. (PCHAR *) args,
  439. TCPIP_SRCH_ALL,
  440. TCPIP_SRCH_ALL | TCPIP_SRCH_IPADDR | TCPIP_SRCH_PORT |
  441. TCPIP_SRCH_STATS | TCPIP_SRCH_PROT,
  442. pSrch);
  443. if (!NT_SUCCESS(NtStatus))
  444. {
  445. dprintf("srchaotable: Invalid parameter" ENDL);
  446. goto done;
  447. }
  448. for (i = 0; i < AO_TABLE_SIZE; i++) {
  449. pAo = AddrObjTable[i];
  450. while (pAo != NULL) {
  451. fPrint = FALSE; // Default.
  452. switch (pSrch->ulOp)
  453. {
  454. case TCPIP_SRCH_PORT:
  455. if (pAo->ao_port == htons(pSrch->port))
  456. {
  457. fPrint = TRUE;
  458. }
  459. break;
  460. case TCPIP_SRCH_PROT:
  461. if (pAo->ao_prot == pSrch->prot)
  462. {
  463. fPrint = TRUE;
  464. }
  465. break;
  466. case TCPIP_SRCH_IPADDR:
  467. if (pAo->ao_addr == pSrch->ipaddr)
  468. {
  469. fPrint = TRUE;
  470. }
  471. break;
  472. case TCPIP_SRCH_STATS:
  473. fPrint = FALSE;
  474. break;
  475. case TCPIP_SRCH_ALL:
  476. fPrint = TRUE;
  477. break;
  478. }
  479. if (fPrint == TRUE)
  480. {
  481. dprintf("[%4d] ", i); // Print which entry.
  482. fStatus = DumpAddrObj(pAo, (ULONG_PTR)pAo, g_Verbosity);
  483. if (fStatus == FALSE)
  484. {
  485. dprintf("Failed to dump AO %x" ENDL, pAo);
  486. }
  487. }
  488. // Collect stats.
  489. cAos++;
  490. if (pAo->ao_flags & AO_VALID_FLAG)
  491. {
  492. cValidAos++;
  493. if (pAo->ao_flags & AO_BUSY_FLAG)
  494. cBusyAos++;
  495. if (pAo->ao_flags & AO_QUEUED_FLAG)
  496. cQueueAos++;
  497. if (pAo->ao_flags & AO_DELETE_FLAG)
  498. cDeleteAos++;
  499. // if ((ULONG_PTR)pAo->ao_error == GetExpression("netbt!TdiErrorHandler"))
  500. // cNetbtAos++;
  501. if (pAo->ao_prot == PROTOCOL_TCP)
  502. cTcpAos++;
  503. }
  504. pAo = pAo->ao_next;
  505. }
  506. }
  507. dprintf("AO Entries: %d::" ENDL, cAos);
  508. dprintf(TAB "Valid AOs: %d" ENDL, cValidAos);
  509. dprintf(TAB "Busy AOs: %d" ENDL, cBusyAos);
  510. dprintf(TAB "AOs with pending queue: %d" ENDL, cQueueAos);
  511. dprintf(TAB "AOs with pending delete: %d" ENDL, cDeleteAos);
  512. // dprintf(TAB "Netbt AOs: %d" ENDL, cNetbtAos);
  513. dprintf(TAB "TCP AOs: %d" ENDL, cTcpAos);
  514. done:
  515. return;
  516. }
  517. //
  518. // Dumps the TCPConns associated with the TCPConnBlock.
  519. //
  520. BOOL
  521. SrchConnBlock(
  522. ULONG_PTR CbAddr,
  523. ULONG op,
  524. VERB verb
  525. )
  526. {
  527. TCPConnBlock *pCb;
  528. BOOL fStatus;
  529. ULONG i;
  530. pCb = (TCPConnBlock *)CbAddr;
  531. fStatus = DumpTCPConnBlock(
  532. pCb,
  533. CbAddr,
  534. VERB_MED);
  535. for (i = 0; i < MAX_CONN_PER_BLOCK; i++)
  536. {
  537. if ((pCb->cb_conn)[i] != NULL)
  538. {
  539. fStatus = DumpTCPConn((pCb->cb_conn)[i], (ULONG_PTR) (pCb->cb_conn)[i], verb);
  540. if (fStatus == FALSE)
  541. {
  542. dprintf("Failed to dump TCPConn @ %x" ENDL, (pCb->cb_conn)[i]);
  543. }
  544. }
  545. }
  546. return (TRUE);
  547. }
  548. extern uint ConnTableSize;
  549. extern TCPConnBlock **ConnTable;
  550. extern uint MaxAllocatedConnBlocks;
  551. VOID
  552. Tcpipkd_conntable(
  553. PVOID args[]
  554. )
  555. {
  556. ULONG i;
  557. BOOL fStatus;
  558. for (i = 0; i < MaxAllocatedConnBlocks; i++) {
  559. if (ConnTable[i] != NULL) {
  560. dprintf("[%4d] ", i);
  561. fStatus = SrchConnBlock(
  562. (ULONG_PTR) ConnTable[i],
  563. TCPIP_SRCH_ALL | TCPIP_SRCH_STATS,
  564. g_Verbosity);
  565. if (fStatus == FALSE)
  566. {
  567. dprintf("Failed to dump ConnBlock @ %x" ENDL, ConnTable[i]);
  568. }
  569. }
  570. }
  571. return;
  572. }
  573. VOID
  574. Tcpipkd_irp(
  575. PVOID args[]
  576. )
  577. {
  578. ULONG_PTR Addr;
  579. VERB verb = g_Verbosity;
  580. PIRP pIrp;
  581. PIO_STACK_LOCATION pIrpSp;
  582. CCHAR irpStackIndex;
  583. ParseAddrArg(args, &Addr, &verb);
  584. pIrp = (PIRP) Addr;
  585. pIrpSp = (PIO_STACK_LOCATION) ((PUCHAR) pIrp + sizeof(IRP));
  586. if (pIrp->Type != IO_TYPE_IRP) {
  587. dprintf("IRP signature does not match, probably not an IRP\n");
  588. return;
  589. }
  590. dprintf("Irp is active with %d stacks %d is current (= %#08lx)\n",
  591. pIrp->StackCount,
  592. pIrp->CurrentLocation,
  593. pIrp->Tail.Overlay.CurrentStackLocation);
  594. if ((pIrp->MdlAddress != NULL) && (pIrp->Type == IO_TYPE_IRP)) {
  595. dprintf(" Mdl = %08lx ", pIrp->MdlAddress);
  596. } else {
  597. dprintf(" No Mdl ");
  598. }
  599. if (pIrp->AssociatedIrp.MasterIrp != NULL) {
  600. dprintf("%s = %08lx ",
  601. (pIrp->Flags & IRP_ASSOCIATED_IRP) ? "Associated Irp" :
  602. (pIrp->Flags & IRP_DEALLOCATE_BUFFER) ? "System buffer" :
  603. "Irp count",
  604. pIrp->AssociatedIrp.MasterIrp);
  605. }
  606. dprintf("Thread %08lx: ", pIrp->Tail.Overlay.Thread);
  607. if (pIrp->StackCount > 30) {
  608. dprintf("Too many Irp stacks to be believed (>30)!!\n");
  609. return;
  610. } else {
  611. if (pIrp->CurrentLocation > pIrp->StackCount) {
  612. dprintf("Irp is completed. ");
  613. } else {
  614. dprintf("Irp stack trace. ");
  615. }
  616. }
  617. if (pIrp->PendingReturned) {
  618. dprintf("Pending has been returned\n");
  619. } else {
  620. dprintf("\n");
  621. }
  622. if (g_Verbosity > 0)
  623. {
  624. dprintf("Flags = %08lx\n", pIrp->Flags);
  625. dprintf("ThreadListEntry.Flink = %08lx\n", pIrp->ThreadListEntry.Flink);
  626. dprintf("ThreadListEntry.Blink = %08lx\n", pIrp->ThreadListEntry.Blink);
  627. dprintf("IoStatus.Status = %08lx\n", pIrp->IoStatus.Status);
  628. dprintf("IoStatus.Information = %08lx\n", pIrp->IoStatus.Information);
  629. dprintf("RequestorMode = %08lx\n", pIrp->RequestorMode);
  630. dprintf("Cancel = %02lx\n", pIrp->Cancel);
  631. dprintf("CancelIrql = %lx\n", pIrp->CancelIrql);
  632. dprintf("ApcEnvironment = %02lx\n", pIrp->ApcEnvironment);
  633. dprintf("UserIosb = %08lx\n", pIrp->UserIosb);
  634. dprintf("UserEvent = %08lx\n", pIrp->UserEvent);
  635. dprintf("Overlay.AsynchronousParameters.UserApcRoutine = %08lx\n", pIrp->Overlay.AsynchronousParameters.UserApcRoutine);
  636. dprintf("Overlay.AsynchronousParameters.UserApcContext = %08lx\n", pIrp->Overlay.AsynchronousParameters.UserApcContext);
  637. dprintf("Overlay.AllocationSize = %08lx - %08lx\n",
  638. pIrp->Overlay.AllocationSize.HighPart,
  639. pIrp->Overlay.AllocationSize.LowPart);
  640. dprintf("CancelRoutine = %08lx\n", pIrp->CancelRoutine);
  641. dprintf("UserBuffer = %08lx\n", pIrp->UserBuffer);
  642. dprintf("&Tail.Overlay.DeviceQueueEntry = %08lx\n", &pIrp->Tail.Overlay.DeviceQueueEntry);
  643. dprintf("Tail.Overlay.Thread = %08lx\n", pIrp->Tail.Overlay.Thread);
  644. dprintf("Tail.Overlay.AuxiliaryBuffer = %08lx\n", pIrp->Tail.Overlay.AuxiliaryBuffer);
  645. dprintf("Tail.Overlay.ListEntry.Flink = %08lx\n", pIrp->Tail.Overlay.ListEntry.Flink);
  646. dprintf("Tail.Overlay.ListEntry.Blink = %08lx\n", pIrp->Tail.Overlay.ListEntry.Blink);
  647. dprintf("Tail.Overlay.CurrentStackLocation = %08lx\n", pIrp->Tail.Overlay.CurrentStackLocation);
  648. dprintf("Tail.Overlay.OriginalFileObject = %08lx\n", pIrp->Tail.Overlay.OriginalFileObject);
  649. dprintf("Tail.Apc = %08lx\n", pIrp->Tail.Apc);
  650. dprintf("Tail.CompletionKey = %08lx\n", pIrp->Tail.CompletionKey);
  651. }
  652. dprintf(" cmd flg cl Device File Completion-Context\n");
  653. for (irpStackIndex = 1; irpStackIndex <= pIrp->StackCount; irpStackIndex++) {
  654. dprintf("%c[%3x,%2x] %2x %2x %08lx %08lx %08lx-%08lx %s %s %s %s\n",
  655. irpStackIndex == pIrp->CurrentLocation ? '>' : ' ',
  656. pIrpSp->MajorFunction,
  657. pIrpSp->MinorFunction,
  658. pIrpSp->Flags,
  659. pIrpSp->Control,
  660. pIrpSp->DeviceObject,
  661. pIrpSp->FileObject,
  662. pIrpSp->CompletionRoutine,
  663. pIrpSp->Context,
  664. (pIrpSp->Control & SL_INVOKE_ON_SUCCESS) ? "Success" : "",
  665. (pIrpSp->Control & SL_INVOKE_ON_ERROR) ? "Error" : "",
  666. (pIrpSp->Control & SL_INVOKE_ON_CANCEL) ? "Cancel" : "",
  667. (pIrpSp->Control & SL_PENDING_RETURNED) ? "pending" : "");
  668. if (pIrpSp->DeviceObject != NULL) {
  669. dprintf(TAB " %08lx", pIrpSp->DeviceObject);
  670. }
  671. if (pIrpSp->CompletionRoutine != NULL) {
  672. dprintf(TAB "%pS + %pX" ENDL, pIrpSp->CompletionRoutine,
  673. pIrpSp->CompletionRoutine);
  674. } else {
  675. dprintf("\n");
  676. }
  677. dprintf("\t\t\tArgs: %08lx %08lx %08lx %08lx\n",
  678. pIrpSp->Parameters.Others.Argument1,
  679. pIrpSp->Parameters.Others.Argument2,
  680. pIrpSp->Parameters.Others.Argument3,
  681. pIrpSp->Parameters.Others.Argument4);
  682. pIrpSp++;
  683. }
  684. return;
  685. }
  686. VOID
  687. Tcpipkd_ipaddr(
  688. PVOID args[]
  689. )
  690. {
  691. ULONG ipaddress;
  692. if (args == NULL || *args == NULL)
  693. {
  694. dprintf("Usage: ipaddr <ip address>" ENDL);
  695. return;
  696. }
  697. ipaddress = mystrtoul(args[0], NULL, 16);
  698. dprintf("IP Address: ");
  699. DumpIPAddr(ipaddress);
  700. dprintf(ENDL);
  701. return;
  702. }
  703. VOID
  704. Tcpipkd_macaddr(
  705. PVOID args[]
  706. )
  707. {
  708. ULONG_PTR MacAddr;
  709. BOOL fStatus;
  710. VERB verb;
  711. UCHAR Mac[ARP_802_ADDR_LENGTH] = {0};
  712. if (args == 0 || !*args)
  713. {
  714. dprintf("Usage: macaddr <ptr>" ENDL);
  715. return;
  716. }
  717. ParseAddrArg(args, &MacAddr, &verb);
  718. memcpy(Mac, (PCHAR)MacAddr, 6);
  719. dprintf("MAC Address: %2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x" ENDL,
  720. Mac[0], Mac[1], Mac[2], Mac[3], Mac[4], Mac[5], Mac[6]);
  721. return;
  722. }
  723. extern HANDLE TcpIprDataPoolSmall;
  724. extern HANDLE TcpIprDataPoolMedium;
  725. extern HANDLE TcpIprDataPoolLarge;
  726. extern HANDLE TcpRequestPool;
  727. extern HANDLE TcbPool;
  728. extern HANDLE TcpConnPool;
  729. typedef struct _PPL_POOL_INFO {
  730. HANDLE Pool;
  731. PCHAR Name;
  732. } PPL_POOL_INFO;
  733. VOID
  734. Tcpipkd_ppls(
  735. PVOID args[]
  736. )
  737. {
  738. PPL_POOL_INFO PoolInfo[] = {
  739. { TcpIprDataPoolSmall, "Small IPR Pool" },
  740. { TcpIprDataPoolMedium, "Medium IPR Pool" },
  741. { TcpIprDataPoolLarge, "Large IPR Pool" },
  742. { TcpRequestPool, "TcpRequestPool (DGSendReq, TCPConnReq, TCPSendReq, TCPRcvReq, TWTCB)" },
  743. { TcbPool, "TCB Pool" },
  744. { TcpConnPool, "TCPConn Pool" },
  745. { NULL, NULL }
  746. };
  747. ULONG cPoolInfo = sizeof(PoolInfo)/sizeof(PPL_POOL_INFO);
  748. ULONG i;
  749. VERB Verb = VERB_MAX;
  750. for (i = 0; PoolInfo[i].Pool != NULL; i++) {
  751. dprintf(ENDL "%s" ENDL, PoolInfo[i].Name);
  752. DumpNPAGED_LOOKASIDE_LIST(
  753. (PNPAGED_LOOKASIDE_LIST) PoolInfo[i].Pool,
  754. (ULONG_PTR) PoolInfo[i].Pool,
  755. Verb);
  756. }
  757. return;
  758. }
  759. VOID
  760. TcpipKdHelp()
  761. {
  762. dprintf("TCP/IP debugger extension commands:" ENDL ENDL);
  763. dprintf(TAB "tcpv - Global setting of verbosity of searches." ENDL);
  764. dprintf(TAB " 0 - One liner" ENDL);
  765. dprintf(TAB " 1 - Medium" ENDL);
  766. dprintf(TAB " 2 - Full structure dump." ENDL);
  767. dprintf(TAB " some dumps have global verbosity override, indicated as [v] below." ENDL);
  768. dprintf(ENDL);
  769. dprintf("Simple structure dumping" ENDL);
  770. dprintf(TAB "ipaddr <ulong> - Dumps ipaddr in <a.b.c.d> format." ENDL);
  771. dprintf(TAB "macaddr <ptr> - Dumps 802.3 address in x-x-x-x-x-x" ENDL);
  772. dprintf(TAB "ao <ptr> [v] - Dumps an AddrObj" ENDL);
  773. dprintf(TAB "tcb <ptr> [v] - Dumps a TCB" ENDL);
  774. dprintf(TAB "twtcb <ptr> [v] - Dumps a TWTCB" ENDL);
  775. dprintf(TAB "tcpctxt <ptr> [v] - Dumps a TCP_CONTEXT" ENDL);
  776. dprintf(TAB "tcpfo <ptr> [v] - Dumps a FILE_OBJECT" ENDL);
  777. dprintf(TAB "tc <ptr> [v] - Dumps a TCPConn" ENDL);
  778. dprintf(TAB "trr <ptr> [v] - Dumps a TCPRcvReq" ENDL);
  779. dprintf(TAB "tsr <ptr> [v] - Dumps a TCPRSendReq" ENDL);
  780. dprintf(TAB "scc <ptr> [v] - Dumps a SendCmpltContext" ENDL);
  781. dprintf(TAB "trh <ptr> [v] - Dumps a TCPRAHdr" ENDL);
  782. dprintf(TAB "dsr <ptr> [v] - Dumps a DGSendReq" ENDL);
  783. dprintf(TAB "drr <ptr> [v] - Dumps a DGRcvReq" ENDL);
  784. dprintf(TAB "udph <ptr> [v] - Dumps an UDPHeader" ENDL);
  785. dprintf(TAB "tcph <ptr> [v] - Dumps an TCPHeader" ENDL);
  786. dprintf(TAB "iph <ptr> [v] - Dumps an IPHeader" ENDL);
  787. dprintf(TAB "icmph <ptr> [v] - Dumps an ICMPHeader" ENDL);
  788. dprintf(TAB "arph <ptr> [v] - Dumps an ARPHeader" ENDL);
  789. dprintf(TAB "ipi <ptr> [v] - Dumps an IPInfo" ENDL);
  790. dprintf(TAB "rce <ptr> [v] - Dumps a RouteCacheEntry" ENDL);
  791. dprintf(TAB "nte <ptr> [v] - Dumps a NetTableEntry" ENDL);
  792. dprintf(TAB "ate <ptr> [v] - Dumps an ARPTableEntry" ENDL);
  793. dprintf(TAB "aia <ptr> [v] - Dumps an ARPIPAddr" ENDL);
  794. dprintf(TAB "rte <ptr> [v] - Dumps a RouteTableEntry" ENDL);
  795. dprintf(TAB "ioi <ptr> [v] - Dumps an IPOptInfo" ENDL);
  796. dprintf(TAB "cb <ptr> [v] - Dumps a TCPConnBlock" ENDL);
  797. dprintf(TAB "pc <ptr> [v] - Dumps a PacketContext" ENDL);
  798. dprintf(TAB "ai <ptr> [v] - Dumps an ARPInterface" ENDL);
  799. dprintf(TAB "interface <ptr> [v] - Dumps an Interface" ENDL);
  800. dprintf(TAB "lip <ptr> [v] - Dumps a LLIPBindInfo" ENDL);
  801. dprintf(TAB "link <ptr> [v] - Dumps a LinkEntry" ENDL);
  802. dprintf(TAB "ppl <handle> - Dumps a Per-processor Lookaside list" ENDL);
  803. dprintf(TAB "np <ptr> - Dumps an NDIS_PACKET" ENDL);
  804. dprintf(ENDL);
  805. dprintf("General structures" ENDL);
  806. dprintf(TAB "irp <ptr> [v] - Dumps an IRP" ENDL);
  807. dprintf(ENDL);
  808. dprintf("Dump and search lists and tables" ENDL);
  809. dprintf(TAB "mdlc <ptr> [v] - Dumps the given MDL chain" ENDL);
  810. dprintf(TAB "arptable <ptr> [v] - Dumps the given ARPTable" ENDL);
  811. dprintf(TAB "arptables - Dumps the all ARPTables" ENDL);
  812. dprintf(TAB "conntable - Dumps the ConnTable" ENDL);
  813. dprintf(TAB "ailist - Dumps the ARPInterface list" ENDL);
  814. dprintf(TAB "iflist - Dumps the Interface list" ENDL);
  815. dprintf(TAB "rtetable - Dumps the RouteTable" ENDL);
  816. dprintf(TAB "rtes - Dumps the RouteTable in route print format" ENDL);
  817. dprintf(TAB "srchtcbtable - Searches TCB table and dumps found TCBs." ENDL);
  818. dprintf(TAB " port <n> - Searches <n> against source and dest port on TCB" ENDL);
  819. dprintf(TAB " ipaddr <a.b.c.d> - Searches <a.b.c.d> against source and dest ipaddr on TCB" ENDL);
  820. dprintf(TAB " all - Dumps all TCBs in the TCB table" ENDL);
  821. dprintf(TAB "srchtwtcbtable - Searches TimeWait TCB table and dumps found TWTCBs." ENDL);
  822. dprintf(TAB " port <n> - Searches <n> against source and dest port on TCB" ENDL);
  823. dprintf(TAB " ipaddr <a.b.c.d> - Searches <a.b.c.d> against source and dest ipaddr on TCB" ENDL);
  824. dprintf(TAB " all - Dumps all TCBs in the TCB table" ENDL);
  825. dprintf(TAB "srchtwtcbq - Searches TimeWait TCB Queue and dumps found TWTCBs." ENDL);
  826. dprintf(TAB " port <n> - Searches <n> against source and dest port on TCB" ENDL);
  827. dprintf(TAB " ipaddr <a.b.c.d> - Searches <a.b.c.d> against source and dest ipaddr on TCB" ENDL);
  828. dprintf(TAB " all - Dumps all TCBs in the TCB table" ENDL);
  829. dprintf(TAB "srchaotable - Searches AO tables and dumps found AOs" ENDL);
  830. dprintf(TAB " port <n> - Searches <n> against source and dest port on TCB" ENDL);
  831. dprintf(TAB " ipaddr <a.b.c.d> - Searches <a.b.c.d> against source and dest ipaddr on TCB" ENDL);
  832. dprintf(TAB " prot <udp|tcp|raw> - Searches AO table for specific protocol" ENDL);
  833. dprintf(TAB " stats - Only dumps stats for AOs in the table" ENDL);
  834. dprintf(TAB " all - Dumps all AOs in the AO table" ENDL);
  835. dprintf(TAB "srchntelist - Dumps NTE list and dumps found NTEs" ENDL);
  836. dprintf(TAB " ipaddr <a.b.c.d> - Searches <a.b.c.d> against NTEs" ENDL);
  837. dprintf(TAB " context <context> - Dumps all NTEs with context" ENDL);
  838. dprintf(TAB " all - Dumps all NTEs in the NTE list" ENDL);
  839. dprintf(TAB "srchlink <ptr> - Dumps a LinkEntry list starting at <ptr>" ENDL);
  840. dprintf(TAB " ipaddr <a.b.c.d> - Searches <a.b.c.d> against LinkEntry's NextHop addr" ENDL);
  841. dprintf(TAB " all - Dumps all LinkEntry's in given list" ENDL);
  842. dprintf(TAB "ppls - Dumps PPLs in the stack" ENDL);
  843. dprintf(ENDL);
  844. dprintf("Dump global variables and paramters" ENDL);
  845. dprintf(TAB "gtcp - All TCP globals" ENDL);
  846. dprintf(TAB "gip - All IP globals" ENDL);
  847. dprintf("" ENDL);
  848. dprintf( "Compiled on " __DATE__ " at " __TIME__ "" ENDL );
  849. return;
  850. }
  851. VOID __cdecl
  852. dprintf(
  853. PUCHAR pszFmt,
  854. ...
  855. )
  856. {
  857. __asm mov esi, [pszFmt]
  858. __asm lea edi, [pszFmt + 4]
  859. __asm mov eax, 0x73
  860. __asm int 41h
  861. }
  862. #pragma warning(disable:4035) // Don't warn about no return value
  863. CHAR __cdecl
  864. DebugGetCommandChar(
  865. )
  866. {
  867. __asm mov ax, 0x77 // get command char
  868. __asm mov bl, 1 // get char
  869. __asm int 41h
  870. __asm or ah, ah
  871. __asm jnz morechars
  872. __asm mov al, ah
  873. morechars:
  874. __asm movzx eax, al
  875. // return value in (al) of eax
  876. }
  877. CHAR __cdecl
  878. DebugPeekCommandChar(
  879. )
  880. {
  881. __asm mov ax, 0x77 // get command char
  882. __asm mov bl, 0 // peek char, inc whitespace
  883. __asm int 41h
  884. __asm or ah, ah
  885. __asm jnz morechars
  886. __asm mov al, ah
  887. morechars:
  888. __asm movzx eax, al
  889. // return value in (al) of eax
  890. }
  891. #pragma warning(default:4035)
  892. #define MAX_COMMAND_LEN 128
  893. #define MAX_COMMAND_ARGS 20
  894. #define ELSE_IF_CMD(_cmd) \
  895. else if (mystricmp(argv[0], #_cmd) == 0) \
  896. Tcpipkd_##_cmd(&argv[1]);
  897. VOID
  898. GetVxdCommandLine(
  899. PCHAR pBuffer,
  900. ULONG cbBuffer
  901. )
  902. {
  903. CHAR c;
  904. while (1) {
  905. //
  906. // Since we can't get white-space, we peek for white-space. If there is
  907. // white-space, insert into our buffer.
  908. //
  909. c = DebugPeekCommandChar();
  910. if (isspace(c)) {
  911. *pBuffer++ = c;
  912. if (--cbBuffer == 0) {
  913. break;
  914. }
  915. }
  916. //
  917. // Now get the real char, this skips white-space.
  918. //
  919. c = DebugGetCommandChar();
  920. *pBuffer++ = c;
  921. // Break if we are at the end of input stream or buffer.
  922. if (c == 0 || --cbBuffer == 0) {
  923. break;
  924. }
  925. }
  926. return;
  927. }
  928. VOID __cdecl
  929. DebugCommand()
  930. {
  931. CHAR c;
  932. UINT i = 0;
  933. UINT argc = 0;
  934. PCHAR argv[MAX_COMMAND_ARGS];
  935. CHAR CommandBuffer[MAX_COMMAND_LEN + 1];
  936. PCHAR pc;
  937. memset(argv, 0, sizeof(argv));
  938. GetVxdCommandLine(CommandBuffer, MAX_COMMAND_LEN);
  939. // Create argv/argc...
  940. argc = CreateArgvArgc(NULL, argv, CommandBuffer);
  941. if (strcmp(argv[0], "?") == 0)
  942. TcpipKdHelp();
  943. ELSE_IF_CMD(ppls)
  944. ELSE_IF_CMD(ppl)
  945. ELSE_IF_CMD(np)
  946. ELSE_IF_CMD(nb)
  947. ELSE_IF_CMD(nbc)
  948. ELSE_IF_CMD(ao)
  949. ELSE_IF_CMD(tcb)
  950. ELSE_IF_CMD(twtcb)
  951. ELSE_IF_CMD(trr)
  952. ELSE_IF_CMD(tsr)
  953. ELSE_IF_CMD(scc)
  954. ELSE_IF_CMD(trh)
  955. ELSE_IF_CMD(dsr)
  956. ELSE_IF_CMD(drr)
  957. ELSE_IF_CMD(tc)
  958. ELSE_IF_CMD(cb)
  959. ELSE_IF_CMD(tcph)
  960. ELSE_IF_CMD(udph)
  961. ELSE_IF_CMD(tcpctxt)
  962. ELSE_IF_CMD(tcpfo)
  963. ELSE_IF_CMD(mdlc)
  964. ELSE_IF_CMD(nte)
  965. ELSE_IF_CMD(ipi)
  966. ELSE_IF_CMD(pc)
  967. ELSE_IF_CMD(ai)
  968. ELSE_IF_CMD(rce)
  969. ELSE_IF_CMD(iph)
  970. ELSE_IF_CMD(icmph)
  971. ELSE_IF_CMD(arph)
  972. ELSE_IF_CMD(aia)
  973. ELSE_IF_CMD(ate)
  974. ELSE_IF_CMD(rte)
  975. ELSE_IF_CMD(link)
  976. ELSE_IF_CMD(interface)
  977. ELSE_IF_CMD(ioi)
  978. ELSE_IF_CMD(lip)
  979. ELSE_IF_CMD(iflist)
  980. ELSE_IF_CMD(ailist)
  981. ELSE_IF_CMD(srchntelist)
  982. ELSE_IF_CMD(srchtcbtable)
  983. ELSE_IF_CMD(srchtwtcbtable)
  984. ELSE_IF_CMD(srchtwtcbq)
  985. ELSE_IF_CMD(srchaotable)
  986. ELSE_IF_CMD(srchlink)
  987. ELSE_IF_CMD(rtes)
  988. ELSE_IF_CMD(rtetable)
  989. ELSE_IF_CMD(conntable)
  990. ELSE_IF_CMD(arptable)
  991. ELSE_IF_CMD(arptables)
  992. ELSE_IF_CMD(gip)
  993. ELSE_IF_CMD(gtcp)
  994. ELSE_IF_CMD(irp)
  995. ELSE_IF_CMD(ipaddr)
  996. ELSE_IF_CMD(macaddr)
  997. else
  998. dprintf(".T? for help on TCP/IP debugger extensions\n");
  999. return;
  1000. }
  1001. VOID __cdecl
  1002. DebugDotCommand()
  1003. {
  1004. DebugCommand();
  1005. __asm xor eax, eax
  1006. __asm pop edi
  1007. __asm pop esi
  1008. __asm pop ebx
  1009. // __asm pop ebp
  1010. __asm retf
  1011. }
  1012. VOID
  1013. InitializeWDebDebug()
  1014. {
  1015. char *pszHelp = ".T? - TCP/IP Debugger Extension Help\n";
  1016. InitTcpipx();
  1017. __asm {
  1018. _emit 0xcd
  1019. _emit 0x20
  1020. _emit 0xc1
  1021. _emit 0x00
  1022. _emit 0x01
  1023. _emit 0x00
  1024. jz exitlab
  1025. mov bl, 'T'
  1026. mov esi, offset DebugDotCommand
  1027. mov edi, pszHelp
  1028. mov eax, 0x70 // DS_RegisterDotCommand
  1029. int 41h
  1030. exitlab:
  1031. }
  1032. }
  1033. #endif // TCPIPKD