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.

746 lines
18 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. wanarp2\ipinip.h
  5. Abstract:
  6. Main header file for the IP in IP encapsulation driver
  7. Revision History:
  8. --*/
  9. #ifndef __WANARP_WANARP_H__
  10. #define __WANARP_WANARP_H___
  11. //
  12. // Symbolic link into DOS space
  13. //
  14. #define WIN32_WANARP_SYMBOLIC_LINK L"\\DosDevices\\WanArp"
  15. //
  16. // ARP name (for IP). Also goes into LLInterface
  17. //
  18. #define WANARP_ARP_NAME WANARP_SERVICE_NAME_W
  19. //
  20. // Name for NDIS. NDIS requires us to have a TCPIP_ in front of the name
  21. //
  22. #define WANARP_NDIS_NAME L"TCPIP_WANARP"
  23. //
  24. // Need to prefix all our device names with this when we give name to
  25. // IP. We assume that the name we cat is of type \<Name>
  26. //
  27. #define TCPIP_IF_PREFIX L"\\DEVICE"
  28. //
  29. // The prefix for the registry key
  30. //
  31. #define TCPIP_REG_PREFIX L"\\Tcpip\\Parameters\\Interfaces\\"
  32. //
  33. // Length of a GUID
  34. //
  35. #define GUID_STR_LEN (38)
  36. //
  37. // We look like an 802.x ARP interface
  38. //
  39. #define ARP_802_ADDR_LENGTH 6
  40. //
  41. // Macro for building a 802.3 hw address given an index.
  42. // We do this since our adapters do not have a real net card associated with
  43. // them
  44. //
  45. #define HW_NAME_SEED "\0SExx\0"
  46. #define BuildHardwareAddrFromIndex(addr,index) { \
  47. RtlCopyMemory(addr, HW_NAME_SEED, 6); \
  48. addr[3] = (uchar) index >> 8; \
  49. addr[4] = (uchar) index; \
  50. }
  51. //
  52. // The default speed and MTU. We change the MTU when we get a better estimate
  53. // but the speed remains the same
  54. //
  55. #define WANARP_DEFAULT_MTU 1500
  56. #define WANARP_DEFAULT_SPEED 28000
  57. #define MEDIA_802_3 0 // index of media
  58. #define WANARP_LOOKAHEAD_SIZE 128 // A reasonable lookahead size
  59. #define MIN_ETYPE 0x600 // Minimum valid Ethertype
  60. #define ARP_ETYPE_IP 0x800 // Standard ETYPE
  61. //
  62. // Max number of packets a connection can have pending
  63. //
  64. #define WANARP_MAX_PENDING_PACKETS 32
  65. //
  66. // Initial size of packet pool
  67. //
  68. #define WAN_PACKET_POOL_COUNT 64
  69. //
  70. // Max outstanding packets:
  71. // Allow 64 connections to be maxed out pending, and 64 others to have
  72. // 2 packets outstanding
  73. //
  74. #define WAN_PACKET_POOL_OVERFLOW ((WANARP_MAX_PENDING_PACKETS * 64) + (2 * 64))
  75. #define CompareUnicodeStrings(S1,S2) \
  76. (((S1)->Length == (S2)->Length) && \
  77. (RtlCompareMemory((S1)->Buffer, \
  78. (S2)->Buffer, \
  79. (S2)->Length) == (S2)->Length))
  80. #define MIN(a,b) ((a) < (b)?a:b)
  81. //
  82. // Functions which are called at passive but acquire spinlocks
  83. //
  84. #define PASSIVE_ENTRY() PAGED_CODE()
  85. #define PASSIVE_EXIT() PAGED_CODE()
  86. //
  87. // Nifty macro for printing IP Addresses
  88. //
  89. #define PRINT_IPADDR(x) \
  90. ((x)&0x000000FF),(((x)&0x0000FF00)>>8),(((x)&0x00FF0000)>>16),(((x)&0xFF000000)>>24)
  91. //
  92. // 0.0.0.0 is an invalid address
  93. //
  94. #define INVALID_IP_ADDRESS 0x00000000
  95. #define IsUnicastAddr(X) ((DWORD)((X) & 0x000000F0) < (DWORD)(0x000000E0))
  96. #define IsClassDAddr(X) (((X) & 0x000000F0) == 0x000000E0)
  97. //
  98. // IPv4 header
  99. //
  100. #include <packon.h>
  101. typedef struct _IP_HEADER
  102. {
  103. BYTE byVerLen; // Version and length.
  104. BYTE byTos; // Type of service.
  105. WORD wLength; // Total length of datagram.
  106. WORD wId; // Identification.
  107. WORD wFlagOff; // Flags and fragment offset.
  108. BYTE byTtl; // Time to live.
  109. BYTE byProtocol; // Protocol.
  110. WORD wXSum; // Header checksum.
  111. DWORD dwSrc; // Source address.
  112. DWORD dwDest; // Destination address.
  113. }IP_HEADER, *PIP_HEADER;
  114. #define LengthOfIpHeader(X) (ULONG)((((X)->byVerLen) & 0x0F)<<2)
  115. typedef struct _ETH_HEADER
  116. {
  117. //
  118. // 6 byte destination address
  119. //
  120. BYTE rgbyDestAddr[ARP_802_ADDR_LENGTH];
  121. //
  122. // 6 byte source address
  123. //
  124. BYTE rgbySourceAddr[ARP_802_ADDR_LENGTH];
  125. //
  126. // 2 byte type
  127. //
  128. WORD wType;
  129. }ETH_HEADER, *PETH_HEADER;
  130. #include <packoff.h>
  131. #if DBG
  132. //
  133. // Reference history structure.
  134. //
  135. typedef struct _REF_HIST_ENTRY
  136. {
  137. //
  138. // time of reference operation
  139. //
  140. LARGE_INTEGER liChangeTime;
  141. //
  142. // Refcount after reference operation
  143. //
  144. LONG lRefCount;
  145. //
  146. // File where reference operation was invoked
  147. //
  148. DWORD dwFileSig;
  149. //
  150. // Line where reference operation was invoked
  151. //
  152. DWORD dwLine;
  153. } REF_HIST_ENTRY, *PREF_HIST_ENTRY;
  154. #define MAX_REF_HISTORY 16
  155. #endif
  156. #define CS_DISCONNECTING 0x00
  157. #define CS_CONNECTING 0x01
  158. #define CS_CONNECTED 0x02
  159. #if DBG
  160. #define CS_IP_DELETED_LINK 0xf0
  161. #endif
  162. //
  163. // The CONN_ENTRY structure defines a connection. There is only one
  164. // CONN_ENTRY for each dial out or router connection. However, on the
  165. // server adapter, we can have multiple CONN_ENYTRYs - one for each dial
  166. // in client. The fields of a CONN_ENTRY are all READ-ONLY except
  167. // for ulSpeed, ulMtu, pAdapter and byState.
  168. // REFCOUNTS: A CONN_ENTRY is refcounted once when the connection is
  169. // created (LinkUp) and then once for every send. It is deref'ed
  170. // on every SendComplete and then again on CloseLink.
  171. //
  172. typedef struct _CONN_ENTRY
  173. {
  174. //
  175. // Back pointer to owning adapter
  176. //
  177. struct _ADAPTER *pAdapter;
  178. //
  179. // Connection information
  180. //
  181. DWORD dwLocalAddr;
  182. DWORD dwLocalMask;
  183. DWORD dwRemoteAddr;
  184. //
  185. // IP's context for this link. Only used for DU_CALLIN connections
  186. //
  187. PVOID pvIpLinkContext;
  188. //
  189. // Pointer to the lock to use when locking this connection.
  190. // For clients, this is a pointer to rlLock, while for others
  191. // this points to the adapter's lock entry
  192. //
  193. PRT_LOCK prlLock;
  194. //
  195. // The lock for this entry. Only used for DU_CALLIN
  196. //
  197. RT_LOCK rlLock;
  198. //
  199. // Refcount
  200. //
  201. LONG lRefCount;
  202. //
  203. // The MTU and speed for this connection
  204. //
  205. ULONG ulMtu;
  206. ULONG ulSpeed;
  207. //
  208. // The usage (CALLIN, CALLOUT or ROUTER) for the connection
  209. //
  210. DIAL_USAGE duUsage;
  211. //
  212. // The slot index in the connection table
  213. //
  214. ULONG ulSlotIndex;
  215. //
  216. // Precanned header for this connection
  217. //
  218. ETH_HEADER ehHeader;
  219. //
  220. // Flag which determines whether to filter netbios packets or not
  221. //
  222. BOOLEAN bFilterNetBios;
  223. BYTE byState;
  224. #if DBG
  225. DWORD dwTotalRefOps;
  226. REF_HIST_ENTRY rheHistory[MAX_REF_HISTORY];
  227. #endif
  228. } CONN_ENTRY, *PCONN_ENTRY;
  229. #include "ref.h"
  230. #define InitConnEntryRefCount(p) InitStructureRefCount("ConnEntry", (p), 0)
  231. #if DBG
  232. #define ReferenceConnEntry(p) \
  233. { \
  234. REF_HIST_ENTRY __rheTemp; \
  235. InterlockedIncrement((PLONG)&((p)->dwTotalRefOps)); \
  236. KeQuerySystemTime(&(__rheTemp.liChangeTime)); \
  237. __rheTemp.lRefCount = ReferenceStructure("ConnEntry", (p)); \
  238. __rheTemp.dwFileSig = __FILE_SIG__; \
  239. __rheTemp.dwLine = __LINE__; \
  240. (p)->rheHistory[((p)->dwTotalRefOps) % MAX_REF_HISTORY] = \
  241. __rheTemp; \
  242. }
  243. #define DereferenceConnEntry(p) \
  244. { \
  245. REF_HIST_ENTRY __rheTemp; \
  246. InterlockedIncrement((PLONG)&((p)->dwTotalRefOps)); \
  247. KeQuerySystemTime(&(__rheTemp.liChangeTime)); \
  248. __rheTemp.dwFileSig = __FILE_SIG__; \
  249. __rheTemp.dwLine = __LINE__; \
  250. if((__rheTemp.lRefCount = \
  251. InterlockedDecrement(&((p)->lRefCount))) == 0) \
  252. { \
  253. (p)->rheHistory[((p)->dwTotalRefOps) % MAX_REF_HISTORY] =\
  254. __rheTemp; \
  255. WanpDeleteConnEntry((p)); \
  256. } \
  257. else \
  258. { \
  259. (p)->rheHistory[((p)->dwTotalRefOps) % MAX_REF_HISTORY] =\
  260. __rheTemp; \
  261. } \
  262. }
  263. #else
  264. #define ReferenceConnEntry(p) ReferenceStructure("ConnEntry", (p))
  265. #define DereferenceConnEntry(p) DereferenceStructure("ConnEntry", (p) ,WanpDeleteConnEntry)
  266. #endif
  267. #define AS_FREE 0x00
  268. #define AS_REMOVING 0x01
  269. #define AS_ADDING 0x02
  270. #define AS_ADDED 0x03
  271. #define AS_UNMAPPING 0x04
  272. #define AS_MAPPING 0x05
  273. #define AS_MAPPED 0x06
  274. //
  275. // There are two conditions where an adapter is in AS_MAPPED state yet has
  276. // no connection entry:
  277. // (i) A Server Adapter is mapped, but has a connection table
  278. // (ii) If a demand dial attempt finds an added adapter, it maps it but
  279. // doesnt create the CONN_ENTRY till LinkUp
  280. //
  281. //
  282. // REFCOUNTS: An ADAPTER is referenced once on creation since it lies on
  283. // a list and once when it added to IP. It is referenced when it
  284. // is mapped to an interface since the interface has a pointer to it.
  285. // It is also referenced once for each connection.
  286. // ADAPTERs are dereferenced when they are unmapped from an interface (at
  287. // linkdown or connection failure). They are deref'ed when a CONN_ENTRY
  288. // is finally cleaned out (not at linkdown - rather when the CONN_ENTRY's
  289. // ref goes to 0). They are deref'ed when they are removed from the
  290. // list to be deleted. We also deref them when we get a CloseAdapter from
  291. // IP
  292. //
  293. typedef struct _ADAPTER
  294. {
  295. //
  296. // Link in the list of adapters on this machine
  297. //
  298. LIST_ENTRY leAdapterLink;
  299. //
  300. // The connection entry for this adapter. Not used for the Server
  301. // Adapter since it has many connections on it
  302. //
  303. PCONN_ENTRY pConnEntry;
  304. //
  305. // Name of the binding
  306. //
  307. UNICODE_STRING usConfigKey;
  308. //
  309. // Name of the device
  310. //
  311. UNICODE_STRING usDeviceNameW;
  312. #if DBG
  313. //
  314. // Same thing, only in asciiz so that we can print it easily
  315. //
  316. ANSI_STRING asDeviceNameA;
  317. #endif
  318. //
  319. // Lock that protects the adapter
  320. //
  321. RT_LOCK rlLock;
  322. //
  323. // The reference count for the structure
  324. // Keep this and the lock together to make the cache happy
  325. //
  326. LONG lRefCount;
  327. //
  328. // The index given to us by IP
  329. //
  330. DWORD dwAdapterIndex;
  331. #if DBG
  332. DWORD dwRequestedIndex;
  333. #endif
  334. //
  335. // TDI entity magic
  336. //
  337. DWORD dwIfInstance;
  338. DWORD dwATInstance;
  339. //
  340. // The state of this adapter
  341. //
  342. BYTE byState;
  343. //
  344. // The Guid for the adapter
  345. //
  346. GUID Guid;
  347. //
  348. // IP's context for this adapter
  349. //
  350. PVOID pvIpContext;
  351. //
  352. // The interface that is adapter is mapped to
  353. //
  354. struct _UMODE_INTERFACE *pInterface;
  355. //
  356. // The pending packet queue length
  357. //
  358. ULONG ulQueueLen;
  359. //
  360. // Queue of pending packets
  361. //
  362. LIST_ENTRY lePendingPktList;
  363. //
  364. // Queue of header buffers for the pending packets
  365. //
  366. LIST_ENTRY lePendingHdrList;
  367. //
  368. // The next two members are used to synchronize state changes for
  369. // the adapter. There are two kinds of notifications needed. When a
  370. // thread is modifying the state using functions which are completed
  371. // asynchronously, it needs to wait for the completion routine to run
  372. // The completion routine uses the pkeChangeEvent to notify the original
  373. // thread.
  374. // Also while this change is in progress, other threads may be interested
  375. // in getting access to the data structure once the state has been
  376. // modified. They add WAN_EVENT_NODE to the EventList and the original
  377. // thread then goes about notifying each of the waiters
  378. //
  379. PKEVENT pkeChangeEvent;
  380. LIST_ENTRY leEventList;
  381. BYTE rgbyHardwareAddr[ARP_802_ADDR_LENGTH];
  382. }ADAPTER, *PADAPTER;
  383. #define InitAdapterRefCount(p) InitStructureRefCount("Adapter", (p), 1)
  384. #define ReferenceAdapter(p) ReferenceStructure("Adapter", (p))
  385. #define DereferenceAdapter(p) DereferenceStructure("Adapter", (p), WanpDeleteAdapter)
  386. typedef struct _UMODE_INTERFACE
  387. {
  388. //
  389. // Link on the list of interfaces
  390. //
  391. LIST_ENTRY leIfLink;
  392. //
  393. // Pointer to adapter when mapped
  394. //
  395. PADAPTER pAdapter;
  396. //
  397. // The (user mode) interface index
  398. //
  399. DWORD dwIfIndex;
  400. //
  401. // The reserved index for this interface
  402. //
  403. DWORD dwRsvdAdapterIndex;
  404. //
  405. // The lock for the interface
  406. //
  407. RT_LOCK rlLock;
  408. //
  409. // The reference count for the structure
  410. // Keep this and the lock together to make the cache happy
  411. //
  412. LONG lRefCount;
  413. //
  414. // The GUID for the interface. This is setup at add interface time
  415. // for router interfaces and at lineup for callouts
  416. //
  417. GUID Guid;
  418. //
  419. // The usage (CALLIN, CALLOUT or ROUTER)
  420. //
  421. DIAL_USAGE duUsage;
  422. //
  423. // Count of packets pending. Used to cap the max number of packets
  424. // copied when a connection is being brought up
  425. //
  426. ULONG ulPacketsPending;
  427. //
  428. // The admin and operational states.
  429. //
  430. DWORD dwAdminState;
  431. DWORD dwOperState;
  432. //
  433. // Last time the state changed. We dont do anything with this right now
  434. //
  435. DWORD dwLastChange;
  436. //
  437. // Sundry MIB-II statistics for the interface
  438. //
  439. ULONG ulInOctets;
  440. ULONG ulInUniPkts;
  441. ULONG ulInNonUniPkts;
  442. ULONG ulInDiscards;
  443. ULONG ulInErrors;
  444. ULONG ulInUnknownProto;
  445. ULONG ulOutOctets;
  446. ULONG ulOutUniPkts;
  447. ULONG ulOutNonUniPkts;
  448. ULONG ulOutDiscards;
  449. ULONG ulOutErrors;
  450. }UMODE_INTERFACE, *PUMODE_INTERFACE;
  451. #define InitInterfaceRefCount(p) InitStructureRefCount("Interface", (p), 1)
  452. #define ReferenceInterface(p) ReferenceStructure("Interface", (p))
  453. #define DereferenceInterface(p) DereferenceStructure("Interface", (p), WanpDeleteInterface)
  454. typedef struct _ADDRESS_CONTEXT
  455. {
  456. //
  457. // The next RCE in the chain
  458. //
  459. RouteCacheEntry *pNextRce;
  460. PCONN_ENTRY pOwningConn;
  461. }ADDRESS_CONTEXT, *PADDRESS_CONTEXT;
  462. //
  463. // Context for an asynchronous NdisRequest
  464. //
  465. typedef
  466. VOID
  467. (* PFNWANARP_REQUEST_COMPLETION_HANDLER)(
  468. NDIS_HANDLE nhHandle,
  469. struct _WANARP_NDIS_REQUEST_CONTEXT *pRequestContext,
  470. NDIS_STATUS nsStatus
  471. );
  472. #pragma warning(disable:4201)
  473. typedef struct _WANARP_NDIS_REQUEST_CONTEXT
  474. {
  475. //
  476. // The request sent to NDIS
  477. // Ndis returns a pointer to this in our completion routine; we
  478. // use CONTAINING_RECORD to get a pointer to the context structure
  479. //
  480. NDIS_REQUEST NdisRequest;
  481. //
  482. // The completion routine to call when NDIS is done processing the
  483. // request. If NULL, then we stop
  484. //
  485. PFNWANARP_REQUEST_COMPLETION_HANDLER pfnCompletionRoutine;
  486. union
  487. {
  488. BYTE rgbyProtocolId[ARP_802_ADDR_LENGTH];
  489. ULONG ulLookahead;
  490. ULONG ulPacketFilter;
  491. TRANSPORT_HEADER_OFFSET TransportHeaderOffset;
  492. };
  493. }WANARP_NDIS_REQUEST_CONTEXT, *PWANARP_NDIS_REQUEST_CONTEXT;
  494. #pragma warning(default:4201)
  495. //
  496. // Our resource (which doesnt allow recursive access)
  497. //
  498. typedef struct _WAN_RESOURCE
  499. {
  500. //
  501. // Number of people waiting on the resource ( + 1 if one is using
  502. // the resource)
  503. //
  504. LONG lWaitCount;
  505. KEVENT keEvent;
  506. }WAN_RESOURCE, *PWAN_RESOURCE;
  507. //
  508. // List of events
  509. //
  510. typedef struct _WAN_EVENT_NODE
  511. {
  512. LIST_ENTRY leEventLink;
  513. KEVENT keEvent;
  514. }WAN_EVENT_NODE, *PWAN_EVENT_NODE;
  515. //
  516. // Define alignment macros to align structure sizes and pointers up and down.
  517. //
  518. #define ALIGN_DOWN(length, type) \
  519. ((ULONG)(length) & ~(sizeof(type) - 1))
  520. #define ALIGN_UP(length, type) \
  521. (ALIGN_DOWN(((ULONG)(length) + sizeof(type) - 1), type))
  522. #define ALIGN_DOWN_POINTER(address, type) \
  523. ((PVOID)((ULONG_PTR)(address) & ~((ULONG_PTR)sizeof(type) - 1)))
  524. #define ALIGN_UP_POINTER(address, type) \
  525. (ALIGN_DOWN_POINTER(((ULONG_PTR)(address) + sizeof(type) - 1), type))
  526. #endif // __WANARP_WANARP_H__