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.

568 lines
17 KiB

  1. /*++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Module Name:
  4. natext.c
  5. Abstract:
  6. This file contains the generic routines and initialization code
  7. for the kernel debugger extensions dll.
  8. Author:
  9. AmritanR
  10. Environment:
  11. User Mode
  12. Revision History:
  13. Abolade Gbadegesin (aboladeg) Feb-13-1998 Completed.
  14. --*/
  15. //
  16. // globals
  17. //
  18. #include <nt.h>
  19. #include <ntrtl.h>
  20. #include <nturtl.h>
  21. #include <ntverp.h>
  22. #include <windef.h>
  23. #include <winbase.h>
  24. #include <ntosp.h>
  25. #include <stdio.h>
  26. #include <wdbgexts.h>
  27. #include <winsock.h>
  28. #include <cxport.h>
  29. #include <ndis.h>
  30. #include <ip.h> // for IPRcvBuf
  31. #include <ipfilter.h>
  32. #include <ipnat.h>
  33. #include "prot.h"
  34. #include "resource.h"
  35. #include "cache.h"
  36. #include "compref.h"
  37. #include "entry.h"
  38. #include "pool.h"
  39. #include "xlate.h"
  40. #include "director.h"
  41. #include "editor.h"
  42. #include "mapping.h"
  43. #undef SetContext
  44. #include "if.h"
  45. #include "dispatch.h"
  46. #include "timer.h"
  47. #include "icmp.h"
  48. #include "pptp.h"
  49. #include "ticket.h"
  50. #include "ftp.h"
  51. #include "raw.h"
  52. const CHAR c_szInterfaceCount[] = "ipnat!InterfaceCount";
  53. const CHAR c_szInterfaceList[] = "ipnat!InterfaceList";
  54. const CHAR c_szMappingCount[] = "ipnat!MappingCount";
  55. const CHAR c_szMappingList[] = "ipnat!MappingList";
  56. EXT_API_VERSION ApiVersion = { 5, 0, EXT_API_VERSION_NUMBER, 0 };
  57. BOOLEAN ChkTarget;
  58. WINDBG_EXTENSION_APIS ExtensionApis;
  59. USHORT SavedMajorVersion;
  60. USHORT SavedMinorVersion;
  61. BOOL
  62. RetrieveValue(
  63. ULONG_PTR Address,
  64. PVOID Value,
  65. ULONG Length
  66. ) {
  67. ULONG LengthRead;
  68. if (!ReadMemory(Address, Value, Length, &LengthRead)) {
  69. dprintf("ReadMemory: address %x length %d\n", Address, Length);
  70. return FALSE;
  71. } else if (LengthRead < Length) {
  72. dprintf(
  73. "ReadMemory: address %x length %d read %d\n",
  74. Address, Length, LengthRead
  75. );
  76. return FALSE;
  77. }
  78. return TRUE;
  79. }
  80. BOOL
  81. RetrieveExpression(
  82. LPCSTR Expression,
  83. ULONG_PTR* Address,
  84. PVOID Value,
  85. ULONG Length
  86. ) {
  87. if (!(*Address = GetExpression(Expression))) {
  88. dprintf("GetExpression: expression %s\n", Expression);
  89. return FALSE;
  90. }
  91. return RetrieveValue(*Address, Value, Length);
  92. }
  93. #define INET_NTOA(a) inet_ntoa(*(struct in_addr*)&(a))
  94. BOOL
  95. DllInit(
  96. HANDLE Module,
  97. ULONG Reason,
  98. ULONG Reserved
  99. )
  100. {
  101. if (Reason == DLL_PROCESS_ATTACH) {
  102. DisableThreadLibraryCalls(Module);
  103. }
  104. return TRUE;
  105. }
  106. VOID
  107. WinDbgExtensionDllInit(
  108. PWINDBG_EXTENSION_APIS lpExtensionApis,
  109. USHORT MajorVersion,
  110. USHORT MinorVersion
  111. )
  112. {
  113. ExtensionApis = *lpExtensionApis;
  114. SavedMajorVersion = MajorVersion;
  115. SavedMinorVersion = MinorVersion;
  116. ChkTarget = SavedMajorVersion == 0x0c ? TRUE : FALSE;
  117. return;
  118. }
  119. DECLARE_API( version )
  120. {
  121. #if DBG
  122. PCHAR DebuggerType = "Checked";
  123. #else
  124. PCHAR DebuggerType = "Free";
  125. #endif
  126. dprintf(
  127. "%s Extension dll for Build %d debugging %s kernel for Build %d\n",
  128. DebuggerType,
  129. VER_PRODUCTBUILD,
  130. SavedMajorVersion == 0x0c ? "Checked" : "Free",
  131. SavedMinorVersion
  132. );
  133. }
  134. VOID
  135. CheckVersion(
  136. VOID
  137. )
  138. {
  139. #if DBG
  140. if ((SavedMajorVersion != 0x0c) ||
  141. (SavedMinorVersion != VER_PRODUCTBUILD)) {
  142. dprintf(
  143. "\n*** Extension DLL(%d Checked) does not match target system(%d %s)\n",
  144. VER_PRODUCTBUILD,
  145. SavedMinorVersion,
  146. (SavedMajorVersion==0x0f) ? "Free" : "Checked"
  147. );
  148. }
  149. #else
  150. if ((SavedMajorVersion!=0x0f) || (SavedMinorVersion!=VER_PRODUCTBUILD)) {
  151. dprintf(
  152. "\n*** Extension DLL(%d Free) does not match target (%d %s)\n",
  153. VER_PRODUCTBUILD, SavedMinorVersion,
  154. (SavedMajorVersion==0x0f) ? "Free" : "Checked"
  155. );
  156. }
  157. #endif
  158. }
  159. LPEXT_API_VERSION
  160. ExtensionApiVersion(
  161. VOID
  162. )
  163. {
  164. return &ApiVersion;
  165. }
  166. //
  167. // Exported functions
  168. //
  169. DECLARE_API( help )
  170. /*++
  171. Routine Description:
  172. Command help for IPNAT debugger extensions.
  173. Arguments:
  174. None
  175. Return Value:
  176. None
  177. --*/
  178. {
  179. dprintf("\n\tIPNAT debugger extension commands:\n\n");
  180. dprintf("\tinterfacecount - Dump the interface count\n");
  181. dprintf("\tinterfacelist - Dump the interface list\n");
  182. dprintf("\tinterface <ptr> - Dump the interface at <ptr>\n");
  183. dprintf("\tmappingcount - Dump the mapping count\n");
  184. dprintf("\tmappinglist - Dump the mapping list\n");
  185. dprintf("\tmapping <ptr> - Dump the mapping at <ptr>\n");
  186. dprintf("\tusedaddress <ptr> - Dump the used-address at <ptr>\n");
  187. dprintf("\tticket <ptr> - Dump the ticket at <ptr>\n");
  188. dprintf("\n\tCompiled on " __DATE__ " at " __TIME__ "\n");
  189. }
  190. DECLARE_API( interfacecount )
  191. {
  192. ULONG InterfaceCount;
  193. ULONG_PTR InterfaceCountPtr;
  194. if (RetrieveExpression(
  195. c_szInterfaceCount,
  196. &InterfaceCountPtr,
  197. &InterfaceCount,
  198. sizeof(InterfaceCount)
  199. )) {
  200. dprintf("InterfaceCount @ %x : %d\n", InterfaceCountPtr, InterfaceCount);
  201. }
  202. }
  203. DECLARE_API( mappingcount )
  204. {
  205. ULONG MappingCount;
  206. ULONG_PTR MappingCountPtr;
  207. if (RetrieveExpression(
  208. c_szMappingCount,
  209. &MappingCountPtr,
  210. &MappingCount,
  211. sizeof(MappingCount)
  212. )) {
  213. dprintf("MappingCount @ %x = %d\n", MappingCountPtr, MappingCount);
  214. }
  215. }
  216. DECLARE_API( interfacelist )
  217. {
  218. LIST_ENTRY InterfaceList;
  219. ULONG_PTR InterfaceListPtr;
  220. NAT_INTERFACE Interfacep;
  221. ULONG_PTR InterfacePtr;
  222. PLIST_ENTRY Link;
  223. if (!RetrieveExpression(
  224. c_szInterfaceList,
  225. &InterfaceListPtr,
  226. &InterfaceList,
  227. sizeof(InterfaceList)
  228. )) {
  229. return;
  230. }
  231. dprintf("InterfaceList @ %x = {\n", InterfaceListPtr);
  232. for (Link = InterfaceList.Flink; Link != (PLIST_ENTRY)InterfaceListPtr;
  233. Link = Interfacep.Link.Flink) {
  234. InterfacePtr = (ULONG_PTR)CONTAINING_RECORD(Link, NAT_INTERFACE, Link);
  235. if (!RetrieveValue(InterfacePtr, &Interfacep, sizeof(Interfacep))) {
  236. break;
  237. }
  238. dprintf("\tInterface @ %x\n", InterfacePtr);
  239. dprintf("\tIndex: %d\n", Interfacep.Index);
  240. dprintf("\tFlags: %08x [ ", Interfacep.Flags);
  241. if (NAT_INTERFACE_DELETED(&Interfacep)) { dprintf("DELETED "); }
  242. dprintf("]\n");
  243. }
  244. dprintf("}\n");
  245. }
  246. DECLARE_API( interface )
  247. {
  248. NAT_ICMP_MAPPING IcmpMapping;
  249. ULONG_PTR IcmpMappingPtr;
  250. NAT_ICMP_MAPPING IpMapping;
  251. ULONG_PTR IpMappingPtr;
  252. NAT_INTERFACE Interfacep;
  253. ULONG_PTR InterfacePtr;
  254. PLIST_ENTRY Link;
  255. NAT_PPTP_MAPPING PptpMapping;
  256. ULONG_PTR PptpMappingPtr;
  257. NAT_TICKET Ticket;
  258. ULONG_PTR TicketPtr;
  259. NAT_USED_ADDRESS UsedAddress;
  260. ULONG_PTR UsedAddressPtr;
  261. if (!args[0]) { dprintf("natext!interface <ptr>\n"); return; }
  262. sscanf(args, "%x", &InterfacePtr);
  263. if (!RetrieveValue(InterfacePtr, &Interfacep, sizeof(Interfacep))) {
  264. return;
  265. }
  266. dprintf("Interface @ %x = {\n", InterfacePtr);
  267. dprintf("\tReferenceCount: %d\n", Interfacep.ReferenceCount);
  268. dprintf("\tIndex: %d\n", Interfacep.Index);
  269. dprintf("\tFileObject: %x\n", Interfacep.FileObject);
  270. dprintf("\tInfo: %x\n", Interfacep.Info);
  271. dprintf("\tFlags: %08x\n", Interfacep.Flags);
  272. dprintf("\tAddressRangeCount: %d\n", Interfacep.AddressRangeCount);
  273. dprintf("\tAddressRangeArray: %x\n", Interfacep.AddressRangeArray);
  274. dprintf("\tPortMappingCount: %d\n", Interfacep.PortMappingCount);
  275. dprintf("\tPortMappingArray: %x\n", Interfacep.PortMappingArray);
  276. dprintf("\tAddressMappingCount: %d\n", Interfacep.AddressMappingCount);
  277. dprintf("\tAddressMappingArray: %x\n", Interfacep.AddressMappingArray);
  278. dprintf("\tAddressCount: %d\n", Interfacep.AddressCount);
  279. dprintf("\tAddressArray: %x\n", Interfacep.AddressArray);
  280. dprintf("\tNoStaticMappingExists: %d\n", Interfacep.NoStaticMappingExists);
  281. dprintf("\tFreeMapCount: %d\n", Interfacep.FreeMapCount);
  282. dprintf("\tFreeMapArray: %x\n", Interfacep.FreeMapArray);
  283. dprintf("\tUsedAddressTree: %x\n", Interfacep.UsedAddressTree);
  284. dprintf("\tUsedAddressList @ %x { ",
  285. InterfacePtr + FIELD_OFFSET(NAT_INTERFACE, UsedAddressList));
  286. for (Link = Interfacep.UsedAddressList.Flink;
  287. (PVOID)Link !=
  288. (PVOID)(InterfacePtr + FIELD_OFFSET(NAT_INTERFACE, UsedAddressList));
  289. Link = UsedAddress.Link.Flink) {
  290. UsedAddressPtr =
  291. (ULONG_PTR)CONTAINING_RECORD(Link, NAT_USED_ADDRESS, Link);
  292. if (!RetrieveValue(UsedAddressPtr, &UsedAddress, sizeof(UsedAddress))) {
  293. break;
  294. }
  295. dprintf("%x ", UsedAddressPtr);
  296. }
  297. dprintf("}\n");
  298. dprintf("\tTicketList @ %x { ",
  299. InterfacePtr + FIELD_OFFSET(NAT_INTERFACE, TicketList));
  300. for (Link = Interfacep.TicketList.Flink;
  301. (PVOID)Link !=
  302. (PVOID)(InterfacePtr + FIELD_OFFSET(NAT_INTERFACE, TicketList));
  303. Link = Ticket.Link.Flink) {
  304. TicketPtr = (ULONG_PTR)CONTAINING_RECORD(Link, NAT_TICKET, Link);
  305. if (!RetrieveValue(TicketPtr, &Ticket, sizeof(Ticket))) { break; }
  306. dprintf("%x ", TicketPtr);
  307. }
  308. dprintf("}\n");
  309. dprintf("\tMappingList @ %x\n",
  310. InterfacePtr + FIELD_OFFSET(NAT_INTERFACE, MappingList));
  311. dprintf("}\n");
  312. }
  313. DECLARE_API( mappinglist )
  314. {
  315. LIST_ENTRY MappingList;
  316. ULONG_PTR MappingListPtr;
  317. NAT_DYNAMIC_MAPPING Mapping;
  318. ULONG_PTR MappingPtr;
  319. PLIST_ENTRY Link;
  320. if (!RetrieveExpression(
  321. c_szMappingList,
  322. &MappingListPtr,
  323. &MappingList,
  324. sizeof(MappingList)
  325. )) {
  326. return;
  327. }
  328. dprintf("MappingList @ %x = {\n", MappingListPtr);
  329. for (Link = MappingList.Flink; Link != (PLIST_ENTRY)MappingListPtr;
  330. Link = Mapping.Link.Flink) {
  331. MappingPtr =
  332. (ULONG_PTR)CONTAINING_RECORD(Link, NAT_DYNAMIC_MAPPING, Link);
  333. if (!RetrieveValue(MappingPtr, &Mapping, sizeof(Mapping))) { break; }
  334. dprintf("\tMapping @ %x\n", MappingPtr);
  335. dprintf(
  336. "\tDestinationKey: %016I64x <> %016I64x\n",
  337. Mapping.DestinationKey[NatForwardPath],
  338. Mapping.DestinationKey[NatReversePath]
  339. );
  340. dprintf(
  341. "\tSourceKey: %016I64x <> %016I64x\n",
  342. Mapping.SourceKey[NatForwardPath], Mapping.SourceKey[NatReversePath]
  343. );
  344. dprintf("\tFlags: %08x [ ", Mapping.Flags);
  345. if (NAT_MAPPING_DELETED(&Mapping)) { dprintf("DELETED "); }
  346. if (NAT_MAPPING_EXPIRED(&Mapping)) { dprintf("EXPIRED "); }
  347. if (NAT_MAPPING_INBOUND(&Mapping)) { dprintf("INBOUND "); }
  348. if (NAT_MAPPING_NO_TIMEOUT(&Mapping)) { dprintf("NO_TIMEOUT "); }
  349. if (NAT_MAPPING_UNIDIRECTIONAL(&Mapping)) { dprintf("UNIDIRECTIONAL "); }
  350. if (Mapping.Flags & NAT_MAPPING_FLAG_FWD_SYN) { dprintf("FWD_SYN "); }
  351. if (Mapping.Flags & NAT_MAPPING_FLAG_REV_SYN) { dprintf("REV_SYN "); }
  352. if (Mapping.Flags & NAT_MAPPING_FLAG_FWD_FIN) { dprintf("FWD_FIN "); }
  353. if (Mapping.Flags & NAT_MAPPING_FLAG_REV_FIN) { dprintf("REV_FIN "); }
  354. dprintf("]\n");
  355. }
  356. dprintf("}\n");
  357. }
  358. DECLARE_API( mapping )
  359. {
  360. CHAR ForwardDestination[32];
  361. CHAR ForwardSource[32];
  362. NAT_DYNAMIC_MAPPING Mapping;
  363. ULONG_PTR MappingPtr;
  364. CHAR ReverseDestination[32];
  365. CHAR ReverseSource[32];
  366. if (!args[0]) { dprintf("natext!mapping <ptr>\n"); return; }
  367. sscanf(args, "%x", &MappingPtr);
  368. if (!RetrieveValue(MappingPtr, &Mapping, sizeof(Mapping))) {
  369. return;
  370. }
  371. dprintf("Mapping @ %x = {\n", MappingPtr);
  372. wsprintf(
  373. ForwardDestination,
  374. "%s/%d",
  375. INET_NTOA(MAPPING_ADDRESS(Mapping.DestinationKey[NatForwardPath])),
  376. ntohs(MAPPING_PORT(Mapping.DestinationKey[NatForwardPath]))
  377. );
  378. wsprintf(
  379. ForwardSource,
  380. "%s/%d",
  381. INET_NTOA(MAPPING_ADDRESS(Mapping.SourceKey[NatForwardPath])),
  382. ntohs(MAPPING_PORT(Mapping.SourceKey[NatForwardPath]))
  383. );
  384. wsprintf(
  385. ReverseDestination,
  386. "%s/%d",
  387. INET_NTOA(MAPPING_ADDRESS(Mapping.DestinationKey[NatReversePath])),
  388. ntohs(MAPPING_PORT(Mapping.DestinationKey[NatReversePath]))
  389. );
  390. wsprintf(
  391. ReverseSource,
  392. "%s/%d",
  393. INET_NTOA(MAPPING_ADDRESS(Mapping.SourceKey[NatReversePath])),
  394. ntohs(MAPPING_PORT(Mapping.SourceKey[NatReversePath]))
  395. );
  396. dprintf("\tDestinationKey: %d %s <> %s\n",
  397. MAPPING_PROTOCOL(Mapping.DestinationKey[NatForwardPath]),
  398. ForwardDestination, ReverseDestination
  399. );
  400. dprintf("\tSourceKey: %d %s <> %s\n",
  401. MAPPING_PROTOCOL(Mapping.SourceKey[NatForwardPath]),
  402. ForwardSource, ReverseSource
  403. );
  404. dprintf("\tLastAccessTime: %I64d\n", Mapping.LastAccessTime);
  405. dprintf("\tReferenceCount: %d\n", Mapping.ReferenceCount);
  406. dprintf("\tAccessCount[]: %d <> %d\n",
  407. Mapping.AccessCount[0], Mapping.AccessCount[1]);
  408. dprintf("\tTranslateRoutine[]: %x <> %x\n",
  409. Mapping.TranslateRoutine[0], Mapping.TranslateRoutine[1]);
  410. dprintf("\tInterface: interface %x context %x\n",
  411. Mapping.Interfacep, Mapping.InterfaceContext);
  412. dprintf("\tEditor: editor %x context %x\n",
  413. Mapping.Editor, Mapping.EditorContext);
  414. dprintf("\tDirector: director %x context %x\n",
  415. Mapping.Director, Mapping.DirectorContext);
  416. dprintf("\tFlags: %08x [ ", Mapping.Flags);
  417. if (NAT_MAPPING_DELETED(&Mapping)) { dprintf("DELETED "); }
  418. if (NAT_MAPPING_EXPIRED(&Mapping)) { dprintf("EXPIRED "); }
  419. if (NAT_MAPPING_INBOUND(&Mapping)) { dprintf("INBOUND "); }
  420. if (NAT_MAPPING_NO_TIMEOUT(&Mapping)) { dprintf("NO_TIMEOUT "); }
  421. if (NAT_MAPPING_UNIDIRECTIONAL(&Mapping)) { dprintf("UNIDIRECTIONAL "); }
  422. if (Mapping.Flags & NAT_MAPPING_FLAG_FWD_SYN) { dprintf("FWD_SYN "); }
  423. if (Mapping.Flags & NAT_MAPPING_FLAG_REV_SYN) { dprintf("REV_SYN "); }
  424. if (Mapping.Flags & NAT_MAPPING_FLAG_FWD_FIN) { dprintf("FWD_FIN "); }
  425. if (Mapping.Flags & NAT_MAPPING_FLAG_REV_FIN) { dprintf("REV_FIN "); }
  426. dprintf("]\n");
  427. dprintf("}\n");
  428. return;
  429. }
  430. DECLARE_API( usedaddress )
  431. {
  432. ULONG_PTR UsedAddressPtr;
  433. NAT_USED_ADDRESS UsedAddress;
  434. if (!args[0]) { dprintf("natext!usedaddress <ptr>\n"); return; }
  435. sscanf(args, "%x", &UsedAddressPtr);
  436. if (!RetrieveValue(UsedAddressPtr, &UsedAddress, sizeof(UsedAddress))) {
  437. return;
  438. }
  439. dprintf("Used address @ %x = {\n", UsedAddressPtr);
  440. dprintf("\tPrivateAddress: %s\n",
  441. INET_NTOA(UsedAddress.PrivateAddress));
  442. dprintf("\tPublicAddress: %s\n",
  443. INET_NTOA(UsedAddress.PublicAddress));
  444. dprintf("\tSharedAddress: %x\n", UsedAddress.SharedAddress);
  445. dprintf("\tAddressMapping: %x\n", UsedAddress.AddressMapping);
  446. dprintf("\tFlags: %08x [ ", UsedAddress.Flags);
  447. if (NAT_POOL_DELETED(&UsedAddress)) { dprintf("DELETED "); }
  448. if (NAT_POOL_STATIC(&UsedAddress)) { dprintf("STATIC "); }
  449. if (NAT_POOL_BINDING(&UsedAddress)) { dprintf("BINDING "); }
  450. if (NAT_POOL_PLACEHOLDER(&UsedAddress)) { dprintf("PLACEHOLDER "); }
  451. dprintf("]\n");
  452. dprintf("\tReferenceCount: %d\n", UsedAddress.ReferenceCount);
  453. dprintf("\tStartPort: %d\n", ntohs(UsedAddress.StartPort));
  454. dprintf("\tEndPort: %d\n", ntohs(UsedAddress.EndPort));
  455. dprintf("}\n");
  456. }
  457. DECLARE_API( ticket )
  458. {
  459. ULONG_PTR TicketPtr;
  460. NAT_TICKET Ticket;
  461. if (!args[0]) { dprintf("natext!ticket <ptr>\n"); return; }
  462. sscanf(args, "%x", &TicketPtr);
  463. if (!RetrieveValue(TicketPtr, &Ticket, sizeof(Ticket))) { return; }
  464. dprintf("Ticket @ %x = {\n", TicketPtr);
  465. dprintf("\tKey: %d %s/%d\n", TICKET_PROTOCOL(Ticket.Key),
  466. INET_NTOA(TICKET_ADDRESS(Ticket.Key)), ntohs(TICKET_PORT(Ticket.Key))
  467. );
  468. dprintf("\tUsedAddress: %x\n", Ticket.UsedAddress);
  469. dprintf("\tPrivateAddress: %s\n", INET_NTOA(Ticket.PrivateAddress));
  470. if (NAT_TICKET_IS_RANGE(&Ticket)) {
  471. dprintf("\tRange: %d - %d\n",
  472. ntohs(TICKET_PORT(Ticket.Key)), Ticket.PrivateOrHostOrderEndPort);
  473. } else {
  474. dprintf("\tPrivatePort: %d\n",
  475. ntohs(Ticket.PrivateOrHostOrderEndPort));
  476. }
  477. dprintf("\tFlags: %08x [ ", Ticket.Flags);
  478. if (NAT_TICKET_PERSISTENT(&Ticket)) { dprintf("PERSISTENT "); }
  479. if (NAT_TICKET_PORT_MAPPING(&Ticket)) { dprintf("PORT_MAPPING "); }
  480. if (NAT_TICKET_IS_RANGE(&Ticket)) { dprintf("IS_RANGE "); }
  481. dprintf("]\n");
  482. dprintf("}\n");
  483. }