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.

477 lines
10 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. #include "routeext.h"
  4. //
  5. // Exported Functions
  6. //
  7. DECLARE_API( rtetable )
  8. /*++
  9. Routine Description:
  10. Print the route table @ tcpip!RouteTable
  11. Arguments:
  12. args - Detail of debug information
  13. [ SUMMARY is the default ]
  14. Return Value:
  15. None
  16. --*/
  17. {
  18. Trie trie;
  19. PVOID pTrie;
  20. ULONG proxyPtr;
  21. ULONG bytesRead;
  22. ULONG printFlags;
  23. // Get the detail of debug information needed
  24. printFlags = STRIE_INFO | FTRIE_INFO;
  25. if (*args)
  26. {
  27. sscanf(args, "%lu", &printFlags);
  28. }
  29. // Get the address corresponding to symbol
  30. proxyPtr = GetLocation("tcpip!RouteTable");
  31. // Get the pointer at this address
  32. if (!ReadMemory(proxyPtr, &pTrie, sizeof(PVOID), &bytesRead))
  33. {
  34. dprintf("%s @ %08x: Could not read pointer\n",
  35. "tcpip!RouteTable", proxyPtr);
  36. return;
  37. }
  38. proxyPtr = (ULONG) pTrie;
  39. // Read the trie wrapper structure
  40. if (ReadTrie(&trie, proxyPtr) == 0)
  41. {
  42. // KdPrint the trie wrapper structure
  43. KdPrintTrie(&trie, proxyPtr, printFlags);
  44. }
  45. }
  46. DECLARE_API( rtes )
  47. /*++
  48. Routine Description:
  49. Print the routes in the table @ tcpip!RouteTable
  50. Arguments:
  51. args - Detail of debug information
  52. [ SUMMARY is the default ]
  53. Return Value:
  54. None
  55. --*/
  56. {
  57. Trie trie;
  58. PVOID pTrie;
  59. ULONG proxyPtr;
  60. ULONG bytesRead;
  61. ULONG printFlags;
  62. // Get the detail of debug information needed
  63. printFlags = ROUTE_INFO;
  64. if (*args)
  65. {
  66. sscanf(args, "%lu", &printFlags);
  67. }
  68. // Get the address corresponding to symbol
  69. proxyPtr = GetLocation("tcpip!RouteTable");
  70. // Get the pointer at this address
  71. if (!ReadMemory(proxyPtr, &pTrie, sizeof(PVOID), &bytesRead))
  72. {
  73. dprintf("%s @ %08x: Could not read pointer\n",
  74. "tcpip!RouteTable", proxyPtr);
  75. return;
  76. }
  77. proxyPtr = (ULONG) pTrie;
  78. // Read the trie wrapper structure
  79. if (ReadTrie(&trie, proxyPtr) == 0)
  80. {
  81. // KdPrint the trie wrapper structure
  82. KdPrintTrie(&trie, proxyPtr, printFlags);
  83. }
  84. }
  85. //
  86. // Trie Print Routines
  87. //
  88. UINT
  89. ReadTrie(Trie *pTrie, ULONG proxyPtr)
  90. {
  91. ULONG bytesRead;
  92. // Read the trie wrapper structure
  93. if (!ReadMemory(proxyPtr, pTrie, sizeof(Trie), &bytesRead))
  94. {
  95. dprintf("%s @ %08x: Could not read structure\n",
  96. "Trie in RouteTable", proxyPtr);
  97. return -1;
  98. }
  99. return 0;
  100. }
  101. UINT
  102. KdPrintTrie(Trie *pTrie, ULONG proxyPtr, ULONG printFlags)
  103. {
  104. if (printFlags == ROUTE_INFO)
  105. {
  106. KdPrintSTrie(NULL, (ULONG) pTrie->sTrie, ROUTE_INFO);
  107. return 0;
  108. }
  109. if (pTrie->flags & TFLAG_FAST_TRIE_ENABLED)
  110. dprintf("Fast Trie Enabled\n");
  111. else
  112. dprintf("Slow Trie Only\n");
  113. if (printFlags & STRIE_INFO)
  114. {
  115. dprintf("STrie:\n");
  116. KdPrintSTrie(NULL, (ULONG) pTrie->sTrie, printFlags & STRIE_INFO);
  117. }
  118. if (printFlags & FTRIE_INFO)
  119. {
  120. if (pTrie->flags & TFLAG_FAST_TRIE_ENABLED)
  121. {
  122. dprintf("FTrie:\n");
  123. KdPrintFTrie(NULL, (ULONG) pTrie->fTrie, printFlags & FTRIE_INFO);
  124. }
  125. }
  126. return 0;
  127. }
  128. //
  129. // STrie Print Routines
  130. //
  131. UINT
  132. KdPrintSTrie(STrie *pSTrie, ULONG proxyPtr, ULONG printFlags)
  133. {
  134. STrie strie;
  135. ULONG bytesRead;
  136. if (proxyPtr == 0)
  137. return -1;
  138. if (pSTrie == NULL)
  139. {
  140. pSTrie = &strie;
  141. // Read the strie structure at this address
  142. if (!ReadMemory(proxyPtr, pSTrie, sizeof(STrie), &bytesRead))
  143. {
  144. dprintf("%s @ %08x: Could not read structure\n",
  145. "STrie in RouteTable", proxyPtr);
  146. return -1;
  147. }
  148. }
  149. if (printFlags == STRIE_INFO)
  150. {
  151. dprintf("\n\n/***Slow-Trie------------------------------------------------");
  152. dprintf("\n/***---------------------------------------------------------\n");
  153. dprintf("Available Memory: %10lu\n\n", pSTrie->availMemory);
  154. dprintf("Statistics:\n\n");
  155. dprintf("Total Number of Dests : %d\n", pSTrie->numDests);
  156. dprintf("Total Number of Routes: %d\n", pSTrie->numRoutes);
  157. dprintf("Total Number of Nodes : %d\n", pSTrie->numNodes);
  158. }
  159. if (pSTrie->trieRoot == NULL)
  160. {
  161. dprintf("\nEmpty STrie\n");
  162. }
  163. else
  164. {
  165. KdPrintSTrieNode(NULL, (ULONG) pSTrie->trieRoot, printFlags);
  166. }
  167. if (printFlags == STRIE_INFO)
  168. {
  169. dprintf("\n---------------------------------------------------------***/\n");
  170. dprintf("---------------------------------------------------------***/\n\n");
  171. }
  172. return 0;
  173. }
  174. UINT
  175. KdPrintSTrieNode(STrieNode *pSTrieNode, ULONG proxyPtr, ULONG printFlags)
  176. {
  177. ULONG bytesRead;
  178. STrieNode stNode;
  179. if (proxyPtr == 0)
  180. return -1;
  181. if (pSTrieNode == NULL)
  182. {
  183. pSTrieNode = &stNode;
  184. // Read the trie wrapper structure
  185. if (!ReadMemory(proxyPtr, pSTrieNode, sizeof(STrieNode), &bytesRead))
  186. {
  187. dprintf("%s @ %08x: Could not read structure\n",
  188. "STrieNode", proxyPtr);
  189. return -1;
  190. }
  191. }
  192. if (printFlags == STRIE_INFO)
  193. {
  194. dprintf("\n--------------------------------------------------------\n");
  195. dprintf("Child @ %08x", proxyPtr);
  196. dprintf("\n--------------------------------------------------------\n");
  197. dprintf("Key: Num of Bits : %8d, Value of Bits: %08x\n",
  198. pSTrieNode->numBits,
  199. pSTrieNode->keyBits);
  200. }
  201. KdPrintDest(NULL, (ULONG) pSTrieNode->dest, printFlags);
  202. if (printFlags == STRIE_INFO)
  203. {
  204. dprintf("Children: On the left %08x, On the right %08x\n",
  205. pSTrieNode->child[0],
  206. pSTrieNode->child[1]);
  207. dprintf("\n--------------------------------------------------------\n");
  208. dprintf("\n\n");
  209. }
  210. KdPrintSTrieNode(NULL, (ULONG) pSTrieNode->child[0], printFlags);
  211. KdPrintSTrieNode(NULL, (ULONG) pSTrieNode->child[1], printFlags);
  212. return 0;
  213. }
  214. //
  215. // FTrie Print Routines
  216. //
  217. UINT
  218. KdPrintFTrie(FTrie *pFTrie, ULONG proxyPtr, ULONG printFlags)
  219. {
  220. FTrieNode *pCurrNode;
  221. FTrie ftrie;
  222. ULONG bytesRead;
  223. UINT i;
  224. if (proxyPtr == 0)
  225. return -1;
  226. if (pFTrie == NULL)
  227. {
  228. pFTrie = &ftrie;
  229. // Read the ftrie structure at this address
  230. if (!ReadMemory(proxyPtr, pFTrie, sizeof(FTrie), &bytesRead))
  231. {
  232. dprintf("%s @ %08x: Could not read structure\n",
  233. "FTrie in RouteTable", proxyPtr);
  234. return -1;
  235. }
  236. }
  237. dprintf("\n\n/***Fast-Trie------------------------------------------------");
  238. dprintf("\n/***---------------------------------------------------------\n");
  239. dprintf("Available Memory: %10lu\n\n", pFTrie->availMemory);
  240. dprintf("\n---------------------------------------------------------***/\n");
  241. dprintf("---------------------------------------------------------***/\n\n");
  242. return 0;
  243. }
  244. UINT
  245. KdPrintFTrieNode(FTrieNode *pFTrieNode, ULONG proxyPtr, ULONG printFlags)
  246. {
  247. return 0;
  248. }
  249. //
  250. // Dest Routines
  251. //
  252. UINT
  253. KdPrintDest(Dest *pDest, ULONG proxyPtr, ULONG printFlags)
  254. {
  255. ULONG bytesRead;
  256. ULONG numBytes;
  257. UINT i;
  258. Dest dest;
  259. Route **pRoutes;
  260. if (proxyPtr == 0)
  261. return -1;
  262. if (pDest == NULL)
  263. {
  264. pDest = &dest;
  265. }
  266. // Read the first RTE - for (dest, mask)
  267. if (!ReadMemory(proxyPtr, pDest, sizeof(Dest), &bytesRead))
  268. {
  269. dprintf("%s @ %08x: Could not read structure\n",
  270. "Dest", proxyPtr);
  271. return -1;
  272. }
  273. if (pDest->numBestRoutes > 1)
  274. {
  275. dprintf("\nBest Routes: Max = %d, Num = %d\n",
  276. pDest->maxBestRoutes,
  277. pDest->numBestRoutes);
  278. // Read the cache of equal cost routes
  279. proxyPtr += FIELD_OFFSET(Dest, bestRoutes);
  280. numBytes = pDest->numBestRoutes * sizeof(Route *);
  281. pRoutes = (Route **) _alloca(numBytes);
  282. if (!ReadMemory(proxyPtr, pRoutes, numBytes, &bytesRead))
  283. {
  284. dprintf("%s @ %08x: Could not read structure\n",
  285. "Dest", proxyPtr);
  286. return -1;
  287. }
  288. for (i = 0; i < pDest->numBestRoutes; i++)
  289. {
  290. dprintf("Best Route %d: %08x\n", i, pRoutes[i]);
  291. }
  292. }
  293. // Get the first route on the destination
  294. KdPrintRoute(NULL, (ULONG) pDest->firstRoute, printFlags);
  295. if (pDest->numBestRoutes > 1)
  296. {
  297. dprintf("\n");
  298. }
  299. return 0;
  300. }
  301. //
  302. // Route Routines
  303. //
  304. UINT
  305. KdPrintRoute(Route *pRoute, ULONG proxyPtr, ULONG printFlags)
  306. {
  307. ULONG bytesRead;
  308. Route route;
  309. if (proxyPtr == 0)
  310. return -1;
  311. if (pRoute == NULL)
  312. {
  313. pRoute = &route;
  314. }
  315. // Read the first RTE - for (dest, mask)
  316. if (!ReadMemory(proxyPtr, pRoute, sizeof(Route), &bytesRead))
  317. {
  318. dprintf("%s @ %08x: Could not read structure\n",
  319. "Route", proxyPtr);
  320. return -1;
  321. }
  322. dprintf("(");
  323. KdPrintIPAddr(&DEST(pRoute));
  324. dprintf(" ");
  325. KdPrintIPAddr(&MASK(pRoute));
  326. dprintf(")");
  327. while (proxyPtr != 0)
  328. {
  329. dprintf(" -> %08x", proxyPtr);
  330. // Read the Route/RTE structure
  331. if (!ReadMemory(proxyPtr, pRoute, sizeof(Route), &bytesRead))
  332. {
  333. dprintf("%s @ %08x: Could not read structure\n",
  334. "Route", proxyPtr);
  335. return -1;
  336. }
  337. proxyPtr = (ULONG) NEXT(pRoute);
  338. }
  339. dprintf("\n");
  340. return 0;
  341. }
  342. //
  343. // Misc Helper Routines
  344. //
  345. ULONG
  346. GetLocation (char *String)
  347. {
  348. ULONG Location;
  349. Location = GetExpression( String );
  350. if (!Location)
  351. {
  352. dprintf("Unable to get %s\n", String);
  353. return 0;
  354. }
  355. return Location;
  356. }
  357. VOID
  358. KdPrintIPAddr (IN ULONG *addr)
  359. {
  360. UCHAR *addrBytes = (UCHAR *) addr;
  361. UINT i;
  362. if (addrBytes)
  363. {
  364. dprintf("%3d.", addrBytes[0]);
  365. dprintf("%3d.", addrBytes[1]);
  366. dprintf("%3d.", addrBytes[2]);
  367. dprintf("%3d ", addrBytes[3]);
  368. }
  369. else
  370. {
  371. dprintf("NULL Addr ");
  372. }
  373. }