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.

653 lines
21 KiB

  1. /*
  2. * File: nlbkd.c
  3. * Description: This file contains the implementation of the NLB KD
  4. * debugging extensions. Use '!load nlbkd.dll' to load
  5. * the extensions and '!nlbkd.help' to see the supported
  6. * extensions.
  7. * Author: Created by shouse, 1.4.01
  8. */
  9. #include "nlbkd.h"
  10. #include "utils.h"
  11. #include "print.h"
  12. WINDBG_EXTENSION_APIS ExtensionApis;
  13. EXT_API_VERSION ApiVersion = { 1, 0, EXT_API_VERSION_NUMBER64, 0 };
  14. #define NL 1
  15. #define NONL 0
  16. USHORT SavedMajorVersion;
  17. USHORT SavedMinorVersion;
  18. BOOL ChkTarget;
  19. /*
  20. * Function: WinDbgExtensionDllInit
  21. * Description: Initializes the KD extension DLL.
  22. * Author: Created by shouse, 1.4.01 - copied largely from ndiskd.dll
  23. */
  24. VOID WinDbgExtensionDllInit (PWINDBG_EXTENSION_APIS64 lpExtensionApis, USHORT MajorVersion, USHORT MinorVersion) {
  25. ExtensionApis = *lpExtensionApis;
  26. SavedMajorVersion = MajorVersion;
  27. SavedMinorVersion = MinorVersion;
  28. ChkTarget = (SavedMajorVersion == 0x0c) ? TRUE : FALSE;
  29. }
  30. /*
  31. * Function: CheckVersion
  32. * Description: Checks the extension DLL version against the target version.
  33. * Author: Created by shouse, 1.4.01 - copied largely from ndiskd.dll
  34. */
  35. VOID CheckVersion (VOID) {
  36. /* For now, do nothing. */
  37. return;
  38. #if DBG
  39. if ((SavedMajorVersion != 0x0c) || (SavedMinorVersion != VER_PRODUCTBUILD)) {
  40. dprintf("\r\n*** Extension DLL(%d Checked) does not match target system(%d %s)\r\n\r\n",
  41. VER_PRODUCTBUILD, SavedMinorVersion, (SavedMajorVersion==0x0f) ? "Free" : "Checked" );
  42. }
  43. #else
  44. if ((SavedMajorVersion != 0x0f) || (SavedMinorVersion != VER_PRODUCTBUILD)) {
  45. dprintf("\r\n*** Extension DLL(%d Free) does not match target system(%d %s)\r\n\r\n",
  46. VER_PRODUCTBUILD, SavedMinorVersion, (SavedMajorVersion==0x0f) ? "Free" : "Checked" );
  47. }
  48. #endif
  49. }
  50. /*
  51. * Function: ExtensionApiVersion
  52. * Description: Returns the API version information.
  53. * Author: Created by shouse, 1.4.01 - copied largely from ndiskd.dll
  54. */
  55. LPEXT_API_VERSION ExtensionApiVersion (VOID) {
  56. return &ApiVersion;
  57. }
  58. /*
  59. * Function: help
  60. * Description: Prints the usage of the NLB KD debugger extensions.
  61. * Author: Created by shouse, 1.4.01
  62. */
  63. DECLARE_API (help) {
  64. dprintf("Network Load Balancing debugger extensions:\n");
  65. dprintf(" version print nlbkd version\n");
  66. dprintf(" nlbadapters [Verbosity] show all NLB adapter blocks\n");
  67. dprintf(" nlbadapter <Adapter Block> [Verbosity] dump an NLB adapter block\n");
  68. dprintf(" nlbctxt <Context Block> [Verbosity] dump an NLB context block\n");
  69. dprintf(" nlbload <Load Block> [Verbosity] dump an NLB load block\n");
  70. dprintf(" nlbparams <Params Block> [Verbosity] dump an NLB parameters block\n");
  71. dprintf(" nlbresp <Packet> [Direction] dump the NLB private data for the specified packet\n");
  72. dprintf(" nlbconnq <Queue> [MaxEntries] dump the contents of a connection descriptor queue\n");
  73. dprintf(" nlbhash <Packet> determine whether or not NLB will accept this packet\n");
  74. dprintf(" nlbpkt <Packet> dump an NLB-specific packet whose type is determined\n");
  75. dprintf(" automagically (heartbeat, IGMP, or remote-control)\n");
  76. dprintf(" nlbmap <Load Block> <Client IP> <Client Port> <Server IP> <Server Port> [Protocol] [Packet Type]\n");
  77. dprintf(" query map function and retrieve any existing state for this tuple\n");
  78. dprintf(" nlbteams dump the linked list of NLB BDA teams\n");
  79. dprintf("\n");
  80. dprintf(" [Verbosity] is an optional integer from 0 to 2 that determines the level of detail displayed.\n");
  81. dprintf(" [Direction] is an optional integer that specifies the direction of the packet (RCV=0, SND=1).\n");
  82. dprintf(" [Protocol] is an optional protocol specification, which can be TCP or UDP.\n");
  83. dprintf(" [Packet Type] is an optional TCP packet type specification, which can be SYN, DATA, FIN or RST.\n");
  84. dprintf("\n");
  85. dprintf(" IP addresses can be in dotted notation or network byte order DWORDs.\n");
  86. }
  87. /*
  88. * Function: version
  89. * Description: Prints the NLB KD debugger extension version information.
  90. * Author: Created by shouse, 1.4.01 - copied largely from ndiskd.dll
  91. */
  92. DECLARE_API (version) {
  93. #if DBG
  94. PCSTR kind = "Checked";
  95. #else
  96. PCSTR kind = "Free";
  97. #endif
  98. dprintf("%s NLB Extension DLL for Build %d debugging %s kernel for Build %d\n", kind,
  99. VER_PRODUCTBUILD, SavedMajorVersion == 0x0c ? "Checked" : "Free", SavedMinorVersion);
  100. }
  101. /*
  102. * Function: nlbadapters
  103. * Description: Prints all NLB adapter strucutres in use. Verbosity is always LOW.
  104. * Author: Created by shouse, 1.5.01
  105. */
  106. DECLARE_API (nlbadapters) {
  107. ULONG dwVerbosity = VERBOSITY_LOW;
  108. CHAR szArgList[10][MAX_PATH];
  109. CHAR szArgBuffer[MAX_PATH];
  110. ULONG64 pNumAdapters;
  111. DWORD dwAdapterSize;
  112. ULONG dwNumAdapters;
  113. ULONG64 pAdapter;
  114. ULONG dwIndex;
  115. INT index = 0;
  116. CHAR * str;
  117. CHAR * p;
  118. if (args && (*args)) {
  119. /* Copy the argument list into a temporary buffer. */
  120. strcpy(szArgBuffer, args);
  121. /* Peel out all of the tokenized strings. */
  122. for (p = mystrtok(szArgBuffer, " \t," ); p && *p; p = mystrtok(NULL, " \t,"))
  123. strcpy(&szArgList[index++][0], p);
  124. /* If a verbosity was specified, get it. */
  125. if (index == 1) dwVerbosity = atoi(&szArgList[0][0]);
  126. /* If too many arguments were given, or the verbosity was out of range, complain. */
  127. if ((index > 1) || (dwVerbosity > VERBOSITY_HIGH)) {
  128. PrintUsage(USAGE_ADAPTERS);
  129. return;
  130. }
  131. }
  132. /* Get the address of the global variable containing the number of NLB adapters in use. */
  133. pNumAdapters = GetExpression(UNIV_ADAPTERS_COUNT);
  134. if (!pNumAdapters) {
  135. ErrorCheckSymbols(UNIV_ADAPTERS_COUNT);
  136. return;
  137. }
  138. /* Get the number of adapters from the address. */
  139. dwNumAdapters = GetUlongFromAddress(pNumAdapters);
  140. dprintf("Network Load Balancing is currently bound to %u adapter(s).\n", dwNumAdapters);
  141. /* Get the base address of the global array of NLB adapter structures. */
  142. pAdapter = GetExpression(UNIV_ADAPTERS);
  143. if (!pAdapter) {
  144. ErrorCheckSymbols(UNIV_ADAPTERS);
  145. return;
  146. }
  147. /* Find out the size of a MAIN_ADAPTER structure. */
  148. dwAdapterSize = GetTypeSize(MAIN_ADAPTER);
  149. /* Loop through all adapters in use and print some information about them. */
  150. for (dwIndex = 0; dwIndex < CVY_MAX_ADAPTERS; dwIndex++) {
  151. ULONG dwValue;
  152. /* Retrieve the used/unused state of the adapter. */
  153. GetFieldValue(pAdapter, MAIN_ADAPTER, MAIN_ADAPTER_FIELD_USED, dwValue);
  154. /* If the adapter is in use, or the user specified HIGH verbosity, print the adapter. */
  155. if (dwValue || (dwVerbosity == VERBOSITY_HIGH)) {
  156. /* Print the adapter index. */
  157. dprintf("\n[%u] ", dwIndex);
  158. /* Print the adapter contents. If verbosity is high, change it to
  159. medium - we don't want to recurse into context from here. */
  160. PrintAdapter(pAdapter, (dwVerbosity == VERBOSITY_HIGH) ? VERBOSITY_MEDIUM : dwVerbosity);
  161. }
  162. /* Advance the pointer to the next index in the array of structures. */
  163. pAdapter += dwAdapterSize;
  164. }
  165. }
  166. /*
  167. * Function: nlbadapter
  168. * Description: Prints NLB adapter information. Takes an adapter pointer and an
  169. * optional verbosity as arguments. Default verbosity is MEDIUM.
  170. * Author: Created by shouse, 1.5.01
  171. */
  172. DECLARE_API (nlbadapter) {
  173. ULONG dwVerbosity = VERBOSITY_LOW;
  174. CHAR szArgList[10][MAX_PATH];
  175. CHAR szArgBuffer[MAX_PATH];
  176. ULONG64 pAdapter;
  177. INT index = 0;
  178. CHAR * str;
  179. CHAR * p;
  180. /* Make sure at least one argument, the adapter pointer, is there. */
  181. if (!args || !(*args)) {
  182. PrintUsage(USAGE_ADAPTER);
  183. return;
  184. }
  185. /* Get the address of the NLB adapter block from the command line. */
  186. pAdapter = (ULONG64)GetExpression(args);
  187. /* Copy the argument list into a temporary buffer. */
  188. strcpy(szArgBuffer, args);
  189. /* Peel out all of the tokenized strings. */
  190. for (p = mystrtok(szArgBuffer, " \t," ); p && *p; p = mystrtok(NULL, " \t,"))
  191. strcpy(&szArgList[index++][0], p);
  192. /* If a verbosity was specified, get it. */
  193. if (index == 2) dwVerbosity = atoi(&szArgList[1][0]);
  194. /* If too many arguments were given, or the verbosity was out of range, complain. */
  195. if ((index > 2) || (dwVerbosity > VERBOSITY_HIGH)) {
  196. PrintUsage(USAGE_ADAPTER);
  197. return;
  198. }
  199. /* Print the adapter contents. */
  200. PrintAdapter(pAdapter, dwVerbosity);
  201. }
  202. /*
  203. * Function: nlbctxt
  204. * Description: Prints NLB context information. Takes a context pointer and an
  205. * optional verbosity as arguments. Default verbosity is LOW.
  206. * Author: Created by shouse, 1.21.01
  207. */
  208. DECLARE_API (nlbctxt) {
  209. ULONG dwVerbosity = VERBOSITY_LOW;
  210. CHAR szArgList[10][MAX_PATH];
  211. CHAR szArgBuffer[MAX_PATH];
  212. ULONG64 pContext;
  213. INT index = 0;
  214. CHAR * str;
  215. CHAR * p;
  216. /* Make sure at least one argument, the context pointer, is there. */
  217. if (!args || !(*args)) {
  218. PrintUsage(USAGE_CONTEXT);
  219. return;
  220. }
  221. /* Get the address of the NLB context block from the command line. */
  222. pContext = (ULONG64)GetExpression(args);
  223. /* Copy the argument list into a temporary buffer. */
  224. strcpy(szArgBuffer, args);
  225. /* Peel out all of the tokenized strings. */
  226. for (p = mystrtok(szArgBuffer, " \t," ); p && *p; p = mystrtok(NULL, " \t,"))
  227. strcpy(&szArgList[index++][0], p);
  228. /* If a verbosity was specified, get it. */
  229. if (index == 2) dwVerbosity = atoi(&szArgList[1][0]);
  230. /* If too many arguments were given, or the verbosity was out of range, complain. */
  231. if ((index > 2) || (dwVerbosity > VERBOSITY_HIGH)) {
  232. PrintUsage(USAGE_CONTEXT);
  233. return;
  234. }
  235. /* Print the context contents. */
  236. PrintContext(pContext, dwVerbosity);
  237. }
  238. /*
  239. * Function: nlbload
  240. * Description: Prints NLB load information. Takes a load pointer and an optional
  241. * verbosity as arguments. Default verbosity is LOW.
  242. * Author: Created by shouse, 2.1.01
  243. */
  244. DECLARE_API (nlbload) {
  245. ULONG dwVerbosity = VERBOSITY_LOW;
  246. CHAR szArgList[10][MAX_PATH];
  247. CHAR szArgBuffer[MAX_PATH];
  248. ULONG64 pLoad;
  249. INT index = 0;
  250. CHAR * str;
  251. CHAR * p;
  252. /* Make sure at least one argument, the load pointer, is there. */
  253. if (!args || !(*args)) {
  254. PrintUsage(USAGE_LOAD);
  255. return;
  256. }
  257. /* Get the address of the NLB load block from the command line. */
  258. pLoad = (ULONG64)GetExpression(args);
  259. /* Copy the argument list into a temporary buffer. */
  260. strcpy(szArgBuffer, args);
  261. /* Peel out all of the tokenized strings. */
  262. for (p = mystrtok(szArgBuffer, " \t," ); p && *p; p = mystrtok(NULL, " \t,"))
  263. strcpy(&szArgList[index++][0], p);
  264. /* If a verbosity was specified, get it. */
  265. if (index == 2) dwVerbosity = atoi(&szArgList[1][0]);
  266. /* If too many arguments were given, or the verbosity was out of range, complain. */
  267. if ((index > 2) || (dwVerbosity > VERBOSITY_HIGH)) {
  268. PrintUsage(USAGE_LOAD);
  269. return;
  270. }
  271. /* Print the load contents. */
  272. PrintLoad(pLoad, dwVerbosity);
  273. }
  274. /*
  275. * Function: nlbparams
  276. * Description: Prints NLB parameter information. Takes a parameter pointer and an
  277. * optional verbosity as arguments. Default verbosity is LOW.
  278. * Author: Created by shouse, 1.21.01
  279. */
  280. DECLARE_API (nlbparams) {
  281. ULONG dwVerbosity = VERBOSITY_LOW;
  282. CHAR szArgList[10][MAX_PATH];
  283. CHAR szArgBuffer[MAX_PATH];
  284. ULONG64 pParams;
  285. INT index = 0;
  286. CHAR * str;
  287. CHAR * p;
  288. /* Make sure at least one argument, the params pointer, is there. */
  289. if (!args || !(*args)) {
  290. PrintUsage(USAGE_PARAMS);
  291. return;
  292. }
  293. /* Get the address of the NLB params block from the command line. */
  294. pParams = (ULONG64)GetExpression(args);
  295. /* Copy the argument list into a temporary buffer. */
  296. strcpy(szArgBuffer, args);
  297. /* Peel out all of the tokenized strings. */
  298. for (p = mystrtok(szArgBuffer, " \t," ); p && *p; p = mystrtok(NULL, " \t,"))
  299. strcpy(&szArgList[index++][0], p);
  300. /* If a verbosity was specified, get it. */
  301. if (index == 2) dwVerbosity = atoi(&szArgList[1][0]);
  302. /* If too many arguments were given, or the verbosity was out of range, complain. */
  303. if ((index > 2) || (dwVerbosity > VERBOSITY_HIGH)) {
  304. PrintUsage(USAGE_PARAMS);
  305. return;
  306. }
  307. /* Print the parameter contents. */
  308. PrintParams(pParams, dwVerbosity);
  309. }
  310. /*
  311. * Function: nlbresp
  312. * Description: Prints out the NLB private packet data for a given packet. Takes a
  313. * packet pointer and an optional direction as arguments. If not specified,
  314. * the packet is presumed to be on the receive path.
  315. * Author: Created by shouse, 1.31.01
  316. */
  317. DECLARE_API (nlbresp) {
  318. ULONG dwDirection = DIRECTION_RECEIVE;
  319. CHAR szArgList[10][MAX_PATH];
  320. CHAR szArgBuffer[MAX_PATH];
  321. ULONG64 pPacket;
  322. INT index = 0;
  323. CHAR * str;
  324. CHAR * p;
  325. /* Make sure at least one argument, the packet pointer, is there. */
  326. if (!args || !(*args)) {
  327. PrintUsage(USAGE_RESP);
  328. return;
  329. }
  330. /* Get the address of the NDIS packet from the command line. */
  331. pPacket = (ULONG64)GetExpression(args);
  332. /* Copy the argument list into a temporary buffer. */
  333. strcpy(szArgBuffer, args);
  334. /* Peel out all of the tokenized strings. */
  335. for (p = mystrtok(szArgBuffer, " \t," ); p && *p; p = mystrtok(NULL, " \t,"))
  336. strcpy(&szArgList[index++][0], p);
  337. /* If a direction was specified, get it. */
  338. if (index == 2) dwDirection = atoi(&szArgList[1][0]);
  339. /* If too many arguments were given, or the direction was out of range, complain. */
  340. if ((index > 2) || (dwDirection > DIRECTION_SEND)) {
  341. PrintUsage(USAGE_RESP);
  342. return;
  343. }
  344. /* Print the NLB private data buffer contents. */
  345. PrintResp(pPacket, dwDirection);
  346. }
  347. /*
  348. * Function: nlbadapters
  349. * Description: Prints all NLB adapter strucutres in use. Verbosity is always LOW.
  350. * Author: Created by shouse, 1.5.01
  351. */
  352. DECLARE_API (nlbteams) {
  353. ULONG64 pTeam;
  354. ULONG64 pAddr;
  355. ULONG dwNumTeams = 0;
  356. ULONG dwValue;
  357. /* Get the base address of the global linked list of BDA teams. */
  358. pAddr = GetExpression(UNIV_BDA_TEAMS);
  359. if (!pAddr) {
  360. ErrorCheckSymbols(UNIV_BDA_TEAMS);
  361. return;
  362. }
  363. /* Get the pointer to the first team. */
  364. pTeam = GetPointerFromAddress(pAddr);
  365. dprintf("NLB bi-directional affinity teams:\n");
  366. /* Loop through all teams in the list and print them out. */
  367. while (pTeam) {
  368. /* Increment the number of teams found - only used if none are found. */
  369. dwNumTeams++;
  370. dprintf("\n");
  371. /* Print out the team. */
  372. PrintBDATeam(pTeam);
  373. /* Get the offset of the params pointer. */
  374. if (GetFieldOffset(BDA_TEAM, BDA_TEAM_FIELD_NEXT, &dwValue))
  375. dprintf("Can't get offset of %s in %s\n", BDA_TEAM_FIELD_NEXT, BDA_TEAM);
  376. else {
  377. pAddr = pTeam + dwValue;
  378. /* Retrieve the pointer. */
  379. pTeam = GetPointerFromAddress(pAddr);
  380. }
  381. }
  382. if (!dwNumTeams) dprintf("\nNone.\n");
  383. }
  384. /*
  385. * Function: nlbconnq
  386. * Description: This function prints out all connection descriptors in a given
  387. * queue of descriptors.
  388. * Author: Created by shouse, 4.15.01
  389. */
  390. DECLARE_API (nlbconnq) {
  391. ULONG dwMaxEntries = 0xffffffff;
  392. CHAR szArgList[10][MAX_PATH];
  393. CHAR szArgBuffer[MAX_PATH];
  394. ULONG64 pQueue;
  395. INT index = 0;
  396. CHAR * str;
  397. CHAR * p;
  398. /* Make sure at least one argument, the queue pointer, is there. */
  399. if (!args || !(*args)) {
  400. PrintUsage(USAGE_CONNQ);
  401. return;
  402. }
  403. /* Get the address of the queue from the command line. */
  404. pQueue = (ULONG64)GetExpression(args);
  405. /* Copy the argument list into a temporary buffer. */
  406. strcpy(szArgBuffer, args);
  407. /* Peel out all of the tokenized strings. */
  408. for (p = mystrtok(szArgBuffer, " \t," ); p && *p; p = mystrtok(NULL, " \t,"))
  409. strcpy(&szArgList[index++][0], p);
  410. /* If a maximum number of entries to print was specified, get it. */
  411. if (index == 2) dwMaxEntries = atoi(&szArgList[1][0]);
  412. /* If too many arguments were given,complain. */
  413. if (index > 2) {
  414. PrintUsage(USAGE_RESP);
  415. return;
  416. }
  417. /* Print the NLB private data buffer contents. */
  418. PrintQueue(pQueue, dwMaxEntries);
  419. }
  420. /*
  421. * Function: nlbmap
  422. * Description: This function will perform the NLB hashing algorithm to determine
  423. * whether a given packet - identified by a (Src IP, Src port, Dst IP,
  424. * Dst port) tuple would be handled by this host or another host.
  425. * Further, if the connection is a known TCP connection, the associated
  426. * descriptor and state information are displayed.
  427. * Author:
  428. */
  429. DECLARE_API (nlbmap) {
  430. CHAR szArgList[10][MAX_PATH];
  431. CHAR szArgBuffer[MAX_PATH];
  432. TCP_PACKET_TYPE ePktType = SYN;
  433. ULONG64 pLoad;
  434. ULONG dwClientIPAddress;
  435. ULONG dwClientPort;
  436. ULONG dwServerIPAddress;
  437. ULONG dwServerPort;
  438. BOOLEAN bIsTCP = TRUE;
  439. INT index = 0;
  440. CHAR * str;
  441. CHAR * p;
  442. /* Make sure that the load pointer is there. */
  443. if (!args || !(*args)) {
  444. PrintUsage(USAGE_MAP);
  445. return;
  446. }
  447. /* Get the address of the load module from the command line. */
  448. pLoad = (ULONG64)GetExpression(args);
  449. /* Copy the argument list into a temporary buffer. */
  450. strcpy(szArgBuffer, args);
  451. /* Peel out all of the tokenized strings. */
  452. for (p = mystrtok(szArgBuffer, " \t," ); p && *p; p = mystrtok(NULL, " \t,"))
  453. strcpy(&szArgList[index++][0], p);
  454. /* If too many arguments were given, complain. */
  455. if ((index > 7) || (index < 5)) {
  456. PrintUsage(USAGE_MAP);
  457. return;
  458. }
  459. /* If we find a '.' in the IP address, then we need to convert it using inet_addr.
  460. If there is no '.', then we assume its already a DWORD in network byte order. */
  461. if (strchr(szArgList[1], '.'))
  462. dwClientIPAddress = inet_addr(szArgList[1]);
  463. else
  464. dwClientIPAddress = atoi(&szArgList[1][0]);
  465. dwClientPort = atoi(&szArgList[2][0]);
  466. /* Make sure the port is between 0 and 65535. */
  467. if (dwClientPort > CVY_MAX_PORT) {
  468. dprintf("Invalid port: %s\n", dwClientPort);
  469. return;
  470. }
  471. /* If we find a '.' in the IP address, then we need to convert it using inet_addr.
  472. If there is no '.', then we assume its already a DWORD in network byte order. */
  473. if (strchr(szArgList[1], '.'))
  474. dwServerIPAddress = inet_addr(szArgList[3]);
  475. else
  476. dwServerIPAddress = atoi(&szArgList[3][0]);
  477. dwServerPort = atoi(&szArgList[4][0]);
  478. /* Make sure the port is between 0 and 65535. */
  479. if (dwServerPort > CVY_MAX_PORT) {
  480. dprintf("Invalid port: %s\n", dwServerPort);
  481. return;
  482. }
  483. /* If a sixth argument has been specified, it is the protocol, which should be either TCP or UDP. */
  484. if (index >= 6) {
  485. if (!_stricmp(szArgList[5], "TCP")) {
  486. bIsTCP = TRUE;
  487. } else if (!_stricmp(szArgList[5], "UDP")) {
  488. bIsTCP = FALSE;
  489. } else {
  490. dprintf("Invalid protocol: %s\n", szArgList[5]);
  491. return;
  492. }
  493. }
  494. /* If an seventh argument has been specified, it is TCP packet type, which should be SYN, DATA, FIN or RST. */
  495. if (index >= 7) {
  496. if (!bIsTCP) {
  497. dprintf("UDP connections do not have packet types\n");
  498. return;
  499. }
  500. if (!_stricmp(szArgList[6], "SYN")) {
  501. ePktType = SYN;
  502. } else if (!_stricmp(szArgList[6], "DATA")) {
  503. ePktType = DATA;
  504. } else if (!_stricmp(szArgList[6], "FIN")) {
  505. ePktType = FIN;
  506. } else if (!_stricmp(szArgList[6], "RST")) {
  507. ePktType = RST;
  508. } else {
  509. dprintf("Invalid TCP packet type: %s\n", szArgList[6]);
  510. return;
  511. }
  512. }
  513. /* Hash on this tuple and print the results. */
  514. PrintMap(pLoad, dwClientIPAddress, dwClientPort, dwServerIPAddress, dwServerPort, bIsTCP, ePktType);
  515. }
  516. /*
  517. * Function: nlbhash
  518. * Description:
  519. * Author: Created by shouse, 4.15.01
  520. */
  521. DECLARE_API (nlbhash) {
  522. dprintf("This extension has not yet been implemented.\n");
  523. }
  524. /*
  525. * Function: nlbpkt
  526. * Description: Prints out the contents of an NLB-specific packet. Takes a packet
  527. * pointer as an argument.
  528. * Author: Created by shouse, 2.1.01
  529. */
  530. DECLARE_API (nlbpkt) {
  531. dprintf("This extension should take a packet pointer and parse the packet to\n");
  532. dprintf(" determine whether it is an NLB heartbeat, remote control or IGMP join.\n");
  533. dprintf(" If the packet is one of those NLB-specific types, it will dump the\n");
  534. dprintf(" contents of the packet. Otherwise, it prints just basic packet info,\n");
  535. dprintf(" such as source and destination IP addresses and port numbers.\n");
  536. dprintf("\n");
  537. dprintf("This extension has not yet been implemented.\n");
  538. }