Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

834 lines
18 KiB

  1. /*++
  2. Copyright (c) 1995-1998 Microsoft Corporation
  3. Module Name:
  4. lkuptst.c
  5. Abstract:
  6. Contains routines for testing an implementation
  7. for the generalized best matching prefix lookup
  8. interface.
  9. Author:
  10. Chaitanya Kodeboyina (chaitk) 30-Jun-1998
  11. Revision History:
  12. --*/
  13. #include "lkuptst.h"
  14. //
  15. // Main
  16. //
  17. #if LOOKUP_TESTING
  18. __cdecl
  19. main (
  20. IN UINT argc,
  21. IN CHAR *argv[]
  22. )
  23. {
  24. CHAR RouteDatabase[MAX_FNAME_LEN];
  25. FILE *FilePtr;
  26. UINT NumRoutes;
  27. Route InputRoutes[MAXROUTES];
  28. UINT i;
  29. DWORD Status;
  30. // Initialize input arguments
  31. RouteDatabase[0] = '\0';
  32. for ( i = 1; i < argc - 1; i++ )
  33. {
  34. if ( ( argv[i][0] == '-' ) || ( argv[i][0] == '/' ) )
  35. {
  36. if (argv[i][2])
  37. {
  38. Usage();
  39. return -1;
  40. }
  41. switch (toupper(argv[i][1]))
  42. {
  43. case 'D':
  44. lstrcpyn(RouteDatabase, argv[++i],
  45. sizeof(RouteDatabase)/sizeof(RouteDatabase[0]));
  46. continue;
  47. default:
  48. Usage();
  49. return -1;
  50. }
  51. }
  52. else
  53. {
  54. Usage();
  55. return -1;
  56. }
  57. }
  58. if (RouteDatabase[0] == '\0')
  59. {
  60. Usage();
  61. return -1;
  62. }
  63. if ((FilePtr = fopen(RouteDatabase, "r")) == NULL)
  64. {
  65. Fatal("Failed open route database with status = %08x\n",
  66. ERROR_OPENING_DATABASE);
  67. return -1;
  68. }
  69. // Print("InputRoutes = %p\n", InputRoutes);
  70. NumRoutes = ReadRoutesFromFile(FilePtr, MAXROUTES, InputRoutes);
  71. // Print("InputRoutes = %p\n", InputRoutes);
  72. fclose(FilePtr);
  73. Status = WorkOnLookup(InputRoutes,
  74. NumRoutes);
  75. return 0;
  76. }
  77. #endif
  78. DWORD
  79. WorkOnLookup (
  80. IN Route *InputRoutes,
  81. IN UINT NumRoutes
  82. )
  83. {
  84. Route *OutputRoute;
  85. HANDLE Table;
  86. UINT Status;
  87. UINT i, j;
  88. PLOOKUP_LINKAGE linkage;
  89. #if PROF
  90. HANDLE Thread;
  91. UINT Priority;
  92. PROFVARS;
  93. Thread = GetCurrentThread();
  94. Priority = GetThreadPriority(Thread);
  95. SetThreadPriority(Thread, THREAD_PRIORITY_TIME_CRITICAL);
  96. #endif
  97. // Create and Initialize a new lookup table
  98. #if PROF
  99. INITPROF;
  100. STARTPROF;
  101. #endif
  102. Status = CreateTable(NUMBYTES, &Table);
  103. #if PROF
  104. STOPPROF;
  105. ADDPROF;
  106. PRINTPROF;
  107. Print("Time for an Initialize Table : %.3f ns\n\n", duration);
  108. #endif
  109. if (!SUCCESS(Status))
  110. {
  111. Fatal("Initialize Failed With Status: %08x\n", Status);
  112. }
  113. CheckTable(Table);
  114. // Compute the total time for inserting all routes
  115. #if PROF
  116. INITPROF;
  117. STARTPROF;
  118. #endif
  119. // Add each route one by one to the table
  120. for (i = 0; i < NumRoutes ; i++)
  121. {
  122. // Print("Inserting Route %6d\n", i + 1);
  123. Status = InsertIntoTable(Table,
  124. LEN(&InputRoutes[i]),
  125. (PUCHAR) &DEST(&InputRoutes[i]),
  126. NULL,
  127. &InputRoutes[i].backptr);
  128. // CheckTable(Table);
  129. if (!SUCCESS(Status))
  130. {
  131. Print("Inserting item %08x/%08x, but got an error",
  132. DEST(&InputRoutes[i]),
  133. MASK(&InputRoutes[i]));
  134. Fatal("Insert Failed With Status: %08x\n", Status);
  135. }
  136. }
  137. #if PROF
  138. STOPPROF;
  139. ADDPROF;
  140. #endif
  141. // Subtract from above the for - loop overhead
  142. #if PROF
  143. STARTPROF;
  144. #endif
  145. for (i = 0; i < NumRoutes ; i++) { ; }
  146. #if PROF
  147. STOPPROF;
  148. SUBPROF;
  149. Print("Avg Time for an Insert Table : %.3f ns for %d routes\n\n",
  150. duration/i, i);
  151. #endif
  152. CheckTable(Table);
  153. #ifdef _DBG_
  154. DumpTable(Table, VERBOSE);
  155. #endif
  156. #ifdef _DBG_
  157. EnumerateAllRoutes(Table);
  158. #endif
  159. #ifdef _DBG_
  160. ReadAddrAndGetRoute(Table);
  161. #endif
  162. // Compute the total time for searching all routes
  163. #if PROF
  164. INITPROF;
  165. STARTPROF;
  166. #endif
  167. for (i = 0; i < NumRoutes ; i++)
  168. {
  169. Status = SearchInTable(Table,
  170. LEN(&InputRoutes[i]),
  171. (PUCHAR) &DEST(&InputRoutes[i]),
  172. NULL,
  173. &linkage);
  174. if (!SUCCESS(Status))
  175. {
  176. Print("Searching for %08x/%08x, but got an error\n",
  177. DEST(&InputRoutes[i]),
  178. MASK(&InputRoutes[i]));
  179. Fatal("Search Failed With Status: %08x\n", Status);
  180. }
  181. OutputRoute = CONTAINING_RECORD(linkage, Route, backptr);
  182. if (OutputRoute != &InputRoutes[i])
  183. {
  184. if ((DEST(OutputRoute) != DEST(&InputRoutes[i])) ||
  185. (MASK(OutputRoute) != MASK(&InputRoutes[i])))
  186. {
  187. Print("Searching for %08x/%08x, but got %08x/%08x\n",
  188. DEST(&InputRoutes[i]),
  189. MASK(&InputRoutes[i]),
  190. DEST(OutputRoute),
  191. MASK(OutputRoute));
  192. }
  193. else
  194. {
  195. // Print("Possible Duplicate Insertion @S\n");
  196. }
  197. }
  198. }
  199. #if PROF
  200. STOPPROF;
  201. ADDPROF;
  202. #endif
  203. // Subtract from above the for - loop overhead
  204. #if PROF
  205. STARTPROF;
  206. #endif
  207. for (i = 0; i < NumRoutes ; i++) { ; }
  208. #if PROF
  209. STOPPROF;
  210. SUBPROF;
  211. Print("Avg Time for a Search Table : %.3f ns for %d routes\n\n",
  212. duration/i, i);
  213. #endif
  214. // Compute the total time for searching all prefixes
  215. #if PROF
  216. INITPROF;
  217. STARTPROF;
  218. #endif
  219. for (i = 0; i < NumRoutes ; i++)
  220. {
  221. Status = BestMatchInTable(Table,
  222. (PUCHAR) &DEST(&InputRoutes[i]),
  223. &linkage);
  224. OutputRoute = CONTAINING_RECORD(linkage, Route, backptr);
  225. if (!SUCCESS(Status))
  226. {
  227. Print("Searching for %08x, but got an error\n",
  228. DEST(&InputRoutes[i]));
  229. Fatal("Search Failed With Status: %08x\n", Status);
  230. }
  231. if (OutputRoute != &InputRoutes[i])
  232. {
  233. if (DEST(OutputRoute) != DEST(&InputRoutes[i]))
  234. {
  235. Print("Searching for %08x, but got %08x/%08x\n",
  236. DEST(&InputRoutes[i]),
  237. DEST(OutputRoute),
  238. MASK(OutputRoute));
  239. }
  240. else
  241. {
  242. // Print("Possible Duplicate Insertion @S\n");
  243. }
  244. }
  245. }
  246. #if PROF
  247. STOPPROF;
  248. ADDPROF;
  249. #endif
  250. // Subtract from above the for - loop overhead
  251. #if PROF
  252. STARTPROF;
  253. #endif
  254. for (i = 0; i < NumRoutes ; i++) { ; }
  255. #if PROF
  256. STOPPROF;
  257. SUBPROF;
  258. Print("Avg Time for Prefix in Table : %.3f ns for %d routes\n\n",
  259. duration/i, i);
  260. #endif
  261. // Compute the total time for deleting all routes
  262. #if PROF
  263. INITPROF;
  264. STARTPROF;
  265. #endif
  266. // Del each route one by one to the table
  267. for (i = 0; i < NumRoutes ; i++)
  268. {
  269. // Print("Deleting Route %6d\n", i + 1);
  270. j = NumRoutes - 1 - i;
  271. Status = DeleteFromTable(Table,
  272. LEN(&InputRoutes[j]),
  273. (PUCHAR) &DEST(&InputRoutes[j]),
  274. NULL,
  275. &linkage);
  276. OutputRoute = CONTAINING_RECORD(linkage, Route, backptr);
  277. // CheckTable(Table);
  278. if (!SUCCESS(Status))
  279. {
  280. /*
  281. Print("Deleting route %08x/%08x, but got an error\n",
  282. DEST(&InputRoutes[j]),
  283. MASK(&InputRoutes[j]));
  284. Error("Delete Failed With Status: %08x\n", Status);
  285. */
  286. }
  287. else
  288. if (OutputRoute != &InputRoutes[j])
  289. {
  290. if ((DEST(OutputRoute) != DEST(&InputRoutes[j])) ||
  291. (MASK(OutputRoute) != MASK(&InputRoutes[j])))
  292. {
  293. Print("Deleting route %08x/%08x, but got %08x/%08x\n",
  294. DEST(&InputRoutes[j]),
  295. MASK(&InputRoutes[j]),
  296. DEST(OutputRoute),
  297. MASK(OutputRoute));
  298. }
  299. else
  300. {
  301. // Print("Possible Duplicate Insertion @D\n");
  302. }
  303. }
  304. }
  305. #if PROF
  306. STOPPROF;
  307. ADDPROF;
  308. #endif
  309. // Subtract from above the for - loop overhead
  310. #if PROF
  311. STARTPROF;
  312. #endif
  313. for (i = 0; i < NumRoutes ; i++) { j = NumRoutes - 1 - i; }
  314. #if PROF
  315. STOPPROF;
  316. SUBPROF;
  317. Print("Avg Time for a Delete Table : %.3f ns for %d routes\n\n",
  318. duration/i, i);
  319. #endif
  320. CheckTable(Table);
  321. #ifdef _DBG_
  322. DumpTable(Table, VERBOSE);
  323. #endif
  324. #ifdef _DBG_
  325. EnumerateAllRoutes(Table);
  326. #endif
  327. #ifdef _DBG_
  328. ReadAddrAndGetRoute(Table);
  329. #endif
  330. // Destory the lookup table
  331. #if PROF
  332. INITPROF;
  333. STARTPROF;
  334. #endif
  335. Status = DestroyTable(Table);
  336. #if PROF
  337. STOPPROF;
  338. ADDPROF;
  339. PRINTPROF;
  340. Print("Time for a Destroy Table : %.3f ns\n\n", duration);
  341. #endif
  342. if (!SUCCESS(Status))
  343. {
  344. Fatal("Destroy Failed With Status: %08x\n", Status);
  345. }
  346. #if PROF
  347. SetThreadPriority(Thread, Priority);
  348. #endif
  349. return 0;
  350. }
  351. // Search Testing
  352. VOID
  353. ReadAddrAndGetRoute (
  354. IN PVOID Table
  355. )
  356. {
  357. LOOKUP_CONTEXT Context;
  358. FILE *FilePtr;
  359. Route *BestRoute;
  360. UINT Status;
  361. ULONG Addr;
  362. PLOOKUP_LINKAGE linkage;
  363. FilePtr = fopen("con", "r");
  364. do
  365. {
  366. Print("Enter the IP Addr to search for: ");
  367. ReadIPAddr(FilePtr, &Addr);
  368. Print("Searching route table for Addr = ");
  369. PrintIPAddr(&Addr);
  370. Print("\n");
  371. Status = SearchInTable(Table,
  372. ADDRSIZE,
  373. (PUCHAR) &Addr,
  374. &Context,
  375. &linkage);
  376. BestRoute = CONTAINING_RECORD(linkage, Route, backptr);
  377. if (!SUCCESS(Status))
  378. {
  379. Fatal("Search Failed With Status: %08x\n", Status);
  380. }
  381. Print("The BMP for this addr: \n");
  382. PrintRoute(BestRoute);
  383. }
  384. while (Addr != 0);
  385. fclose(FilePtr);
  386. }
  387. // Enumerate Testing
  388. VOID
  389. EnumerateAllRoutes (
  390. IN PVOID Table
  391. )
  392. {
  393. LOOKUP_CONTEXT Context;
  394. USHORT NumBits;
  395. UCHAR KeyBits[NUMBYTES];
  396. UINT Status;
  397. PLOOKUP_LINKAGE Linkage;
  398. UINT NumDests = 1;
  399. PVOID DestItems[1];
  400. Print("\n---------------- ENUMERATION BEGIN ---------------------\n");
  401. ZeroMemory(&Context, sizeof(LOOKUP_CONTEXT));
  402. ZeroMemory(&KeyBits, NUMBYTES);
  403. NumBits = 0;
  404. do
  405. {
  406. Status = EnumOverTable(Table,
  407. &NumBits,
  408. KeyBits,
  409. &Context,
  410. 0,
  411. NULL,
  412. &NumDests,
  413. &Linkage);
  414. DestItems[0] = CONTAINING_RECORD(Linkage, Route, backptr);
  415. if (SUCCESS(Status))
  416. {
  417. PrintRoute((Route *)DestItems[0]);
  418. }
  419. }
  420. while (SUCCESS(Status));
  421. // If it is just an EOF, print last route
  422. if (Status == ERROR_NO_MORE_ITEMS)
  423. {
  424. PrintRoute((Route *)DestItems[0]);
  425. }
  426. Print("---------------- ENUMERATION END ---------------------\n\n");
  427. }
  428. UINT ReadRoutesFromFile(
  429. IN FILE *FilePtr,
  430. IN UINT NumRoutes,
  431. OUT Route *RouteTable
  432. )
  433. {
  434. UINT i;
  435. for (i = 0; (!feof(FilePtr)) && (i < NumRoutes) ; )
  436. {
  437. // Print("RouteTable = %p\n", RouteTable);
  438. if (ReadRoute(FilePtr, &RouteTable[i]) != EOF)
  439. {
  440. if (RouteTable[i].len)
  441. {
  442. ;
  443. }
  444. else
  445. {
  446. ;
  447. }
  448. i++;
  449. }
  450. // Print("RouteTable = %p\n", RouteTable);
  451. }
  452. if (i >= NumRoutes)
  453. {
  454. Error("Number of routes in file exceeds the limit\n",
  455. ERROR_MAX_NUM_ROUTES);
  456. }
  457. Print("Total number of routes = %lu\n\n", i);
  458. return i;
  459. }
  460. INT
  461. ReadRoute (
  462. IN FILE *FilePtr,
  463. OUT Route *route
  464. )
  465. {
  466. UCHAR currLine[MAX_LINE_LEN];
  467. UCHAR *addrBytes;
  468. UCHAR *maskBytes;
  469. UINT byteRead;
  470. UINT byteTemp;
  471. INT numConv;
  472. UINT i;
  473. // Zero the input addr, mask, and len
  474. ClearMemory(route, sizeof(Route));
  475. // Input format: A1.A2..An/M1.M2..Mn!
  476. // Read destination IP address
  477. addrBytes = (UCHAR *) &DEST(route);
  478. // Read the address A1.A2..An
  479. for (i = 0; i < NUMBYTES; i++)
  480. {
  481. numConv = fscanf(FilePtr, "%d.", &byteRead);
  482. // Last Line in file
  483. if (numConv == EOF)
  484. {
  485. return EOF;
  486. }
  487. // End of Address
  488. if (numConv == 0)
  489. {
  490. break;
  491. }
  492. addrBytes[i] = (UCHAR) byteRead;
  493. }
  494. // Read the '/' seperator
  495. fscanf(FilePtr, "%c", &byteRead);
  496. // Read destination IP mask
  497. maskBytes = (UCHAR *) &MASK(route);
  498. // Read the mask M1.M2..Mn
  499. for (i = 0; i < NUMBYTES; i++)
  500. {
  501. numConv = fscanf(FilePtr, "%d.", &byteRead);
  502. // Incomplete line
  503. if (numConv == EOF)
  504. {
  505. return EOF;
  506. }
  507. // End of Mask
  508. if (numConv == 0)
  509. {
  510. break;
  511. }
  512. maskBytes[i] = (UCHAR) byteRead;
  513. // Assume route mask is contiguous
  514. byteTemp = byteRead;
  515. while (byteTemp)
  516. {
  517. byteTemp &= byteTemp - 1;
  518. LEN(route)++;
  519. }
  520. }
  521. // Read the ',' seperator
  522. fscanf(FilePtr, "%c", &byteRead);
  523. // Read next hop information
  524. addrBytes = (UCHAR *) &NHOP(route);
  525. // Read the next hop N1.N2..Nn
  526. for (i = 0; i < NUMBYTES; i++)
  527. {
  528. numConv = fscanf(FilePtr, "%d.", &byteRead);
  529. // Incomplete line
  530. if (numConv == EOF)
  531. {
  532. return EOF;
  533. }
  534. // End of Address
  535. if (numConv == 0)
  536. {
  537. break;
  538. }
  539. addrBytes[i] = (UCHAR) byteRead;
  540. }
  541. // Read the ',' seperator
  542. fscanf(FilePtr, "%c", &byteRead);
  543. // Read interface addr/index
  544. addrBytes = (UCHAR *) &IF(route);
  545. // Read the interface I1.I2..In
  546. for (i = 0; i < NUMBYTES; i++)
  547. {
  548. numConv = fscanf(FilePtr, "%d.", &byteRead);
  549. // Incomplete line
  550. if (numConv == EOF)
  551. {
  552. return EOF;
  553. }
  554. // End of Address
  555. if (numConv == 0)
  556. {
  557. break;
  558. }
  559. addrBytes[i] = (UCHAR) byteRead;
  560. }
  561. // Read the ',' seperator
  562. fscanf(FilePtr, "%c", &byteRead);
  563. // Read the route's metric
  564. fscanf(FilePtr, "%lu", &METRIC(route));
  565. // Read the rest of the line
  566. fscanf(FilePtr, "%s\n", currLine);
  567. #ifdef _DBG_
  568. PrintRoute(route);
  569. #endif
  570. return TRUE;
  571. }
  572. VOID
  573. PrintRoute (
  574. IN Route *route
  575. )
  576. {
  577. if (NULL_ROUTE(route))
  578. {
  579. Print("NULL route\n");
  580. }
  581. else
  582. {
  583. Print("Route: Len = %2d", LEN(route));
  584. Print(", Addr = ");
  585. PrintIPAddr(&DEST(route));
  586. Print(", NHop = ");
  587. PrintIPAddr(&NHOP(route));
  588. Print(", IF = %08x", PtrToInt(IF(route)));
  589. Print(", Metric = %3lu\n", METRIC(route));
  590. }
  591. }
  592. INT
  593. ReadIPAddr (
  594. IN FILE *FilePtr,
  595. OUT ULONG *addr
  596. )
  597. {
  598. UCHAR *addrBytes;
  599. UINT byteRead;
  600. INT numConv;
  601. UINT i;
  602. // Initialize the addr variable to 0
  603. *addr = 0;
  604. // Cast it for easy byte access
  605. addrBytes = (UCHAR *)addr;
  606. // Read the address A1.A2..An
  607. for (i = 0; i < NUMBYTES; i++)
  608. {
  609. numConv = fscanf(FilePtr, "%d.", &byteRead);
  610. // Last Line in file
  611. if (numConv == EOF)
  612. {
  613. return EOF;
  614. }
  615. // End of Address
  616. if (numConv == 0)
  617. {
  618. break;
  619. }
  620. addrBytes[i] = (UCHAR) byteRead;
  621. }
  622. return 0;
  623. }
  624. VOID
  625. PrintIPAddr (
  626. IN ULONG *addr
  627. )
  628. {
  629. UCHAR *addrBytes = (UCHAR *) addr;
  630. UINT i;
  631. if (addrBytes)
  632. {
  633. for (i = 0; i < NUMBYTES; i++)
  634. {
  635. Print("%3d.", addrBytes[i]);
  636. }
  637. Print(" ");
  638. }
  639. else
  640. {
  641. Print("NULL Addr ");
  642. }
  643. }
  644. VOID
  645. Usage (
  646. VOID
  647. )
  648. {
  649. Fatal("Failed Operation with status = %08x"
  650. "\n"
  651. "Tests and measures the IP route lookup mechanism \n"
  652. "\n"
  653. "Usage: \n"
  654. "\t lkuptst \t [ -d routing_database ] \n"
  655. "\n"
  656. "Options:\n"
  657. " -d routing_database \t Name of the route database\n"
  658. "\n",
  659. ERROR_WRONG_CMDUSAGE);
  660. }