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.

589 lines
14 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. ipinip\ipinip.h
  5. Abstract:
  6. Main header file for the IP in IP encapsulation driver
  7. Revision History:
  8. --*/
  9. #ifndef __IPINIP_IPINIP_H__
  10. #define __IPINIP_IPINIP_H___
  11. //
  12. // The protocol ID for IP in IP
  13. //
  14. #define PROTO_IPINIP 4
  15. #define PROTO_ICMP 1
  16. //
  17. // The IP version that we work with
  18. //
  19. #define IP_VERSION_4 0x04
  20. //
  21. // Macro for figuring out the length of an IP header
  22. //
  23. #define LengthOfIPHeader(X) (ULONG)((((X)->byVerLen) & 0x0F)<<2);
  24. //
  25. // The length of the smallest valid IP Header is 20 bytes
  26. // and the largest is 60
  27. //
  28. #define MIN_IP_HEADER_LENGTH 20
  29. #define MAX_IP_HEADER_LENGTH 60
  30. #define ICMP_HEADER_LENGTH 8
  31. //
  32. // Since we are IPv4 and 20 bytes of header, the version+length field is 45
  33. //
  34. #define IP_VERSION_LEN 0x45
  35. //
  36. // Macro to decide whether the address is unicast
  37. //
  38. #define IsUnicastAddr(X) ((DWORD)((X) & 0x000000F0) < (DWORD)(0x000000E0))
  39. #define IsClassDAddr(X) (((X) & 0x000000F0) == 0x000000E0)
  40. #define IsClassEAddr(X) (((X) & 0x000000F8) == 0x000000F0)
  41. //
  42. // Symbolic link into DOS space
  43. //
  44. #define WIN32_IPINIP_SYMBOLIC_LINK L"\\DosDevices\\IPINIP"
  45. //
  46. // ARP name (for IP). Also goes into LLInterface
  47. //
  48. #define IPINIP_ARP_NAME L"IPINIP"
  49. #define TCPIP_IF_PREFIX L"\\Device\\"
  50. //
  51. // All IOCTLs are handled by functions with the prototype below. This allows
  52. // us to build a table of pointers and call out to them instead of doing
  53. // a switch
  54. //
  55. typedef
  56. NTSTATUS
  57. (*PFN_IOCTL_HNDLR)(
  58. PIRP pIrp,
  59. ULONG ulInLength,
  60. ULONG ulOutLength
  61. );
  62. //
  63. // We look like an 802.x ARP interface
  64. //
  65. #define ARP_802_ADDR_LENGTH 6
  66. //
  67. // Macro for building a 802.3 hw address given an index.
  68. // We do this since our adapters do not have a real net card associated with
  69. // them
  70. //
  71. #define HW_NAME_SEED "\0SExx\0"
  72. #define BuildHardwareAddrFromIndex(addr,index) { \
  73. RtlCopyMemory(addr, HW_NAME_SEED, 6); \
  74. addr[3] = (uchar) index >> 8; \
  75. addr[4] = (uchar) index; \
  76. }
  77. //
  78. // The description string for our interfaces (try and make length + 1 a
  79. // multiple of 4)
  80. //
  81. #define VENDOR_DESCRIPTION_STRING "IP in IP (Tunnel) Interface"
  82. //
  83. // The default speed and MTU. We change the MTU when we get a better estimate
  84. // but the speed remains the same
  85. //
  86. #define DEFAULT_MTU (1500 - 60)
  87. #define DEFAULT_SPEED (100000000)
  88. //
  89. // The number of seconds after which an attempt is made to change the state
  90. // of an interface
  91. //
  92. #define UP_TO_DOWN_CHANGE_PERIOD (5 * 60)
  93. #define DOWN_TO_UP_CHANGE_PERIOD (1 * 60)
  94. //
  95. // Timer period
  96. //
  97. #define TIMER_IN_MILLISECS (1 * 60 * 1000)
  98. #define SYS_UNITS_IN_ONE_MILLISEC (1000 * 10)
  99. #define MILLISECS_TO_TICKS(ms) \
  100. ((ULONGLONG)(ms) * SYS_UNITS_IN_ONE_MILLISEC / KeQueryTimeIncrement())
  101. #define SECS_TO_TICKS(s) \
  102. ((ULONGLONG)MILLISECS_TO_TICKS((s) * 1000))
  103. //
  104. // #defines to make it easier to get to the Remote and Local
  105. // addresses of a tunnel
  106. //
  107. #define REMADDR uliTunnelId.LowPart
  108. #define LOCALADDR uliTunnelId.HighPart
  109. //
  110. // A tunnel is considered mapped when both endpoints have been specified
  111. // Instead of keeping a separate field for the tunnel state, we reuse the
  112. // dwAdminState field
  113. //
  114. #define TS_ADDRESS_PRESENT (0x01000000)
  115. #define TS_ADDRESS_REACHABLE (0x02000000)
  116. #define TS_DELETING (0x04000000)
  117. #define TS_MAPPED (0x08000000)
  118. #define TS_DEST_UNREACH (0x10000000)
  119. #define TS_TTL_TOO_LOW (0x20000000)
  120. #define ERROR_BITS (TS_DEST_UNREACH|TS_TTL_TOO_LOW)
  121. #define MarkTunnelMapped(p) (p)->dwAdminState |= TS_MAPPED;
  122. #define MarkTunnelUnmapped(p) (p)->dwAdminState &= ~TS_MAPPED;
  123. #define IsTunnelMapped(p) ((p)->dwAdminState & TS_MAPPED)
  124. #define ClearErrorBits(p) ((p)->dwAdminState &= ~(ERROR_BITS))
  125. #define GetAdminState(p) ((p)->dwAdminState & 0x0000FFFF)
  126. typedef struct _TUNNEL
  127. {
  128. //
  129. // Link in the list of tunnels
  130. //
  131. LIST_ENTRY leTunnelLink;
  132. //
  133. // Address of the remote end and the local end are
  134. // kept in a ULARGE_INTEGER. This makes it easier for comparisons
  135. // uliTunnelId.LowPart = RemoteAddress
  136. // uliTunnelId.HighPart = LocalAddress
  137. // For comparisons use uliTunnelId.QuadPart
  138. //
  139. ULARGE_INTEGER uliTunnelId;
  140. //
  141. // The interface index given to us by IP stack
  142. //
  143. DWORD dwIfIndex;
  144. //
  145. // TDI magic stuff. Entity Ids
  146. //
  147. DWORD dwATInstance;
  148. DWORD dwIfInstance;
  149. //
  150. // IP's context for this interface
  151. //
  152. PVOID pvIpContext;
  153. //
  154. // The name of the binding/adapter
  155. //
  156. UNICODE_STRING usBindName;
  157. #if DBG
  158. //
  159. // In debug builds we have the name is ANSI so that we can print it
  160. //
  161. ANSI_STRING asDebugBindName;
  162. #endif
  163. //
  164. // The lock and reference count used to mantain consistency for the
  165. // data structure. We keep one refcount for every stored reference to
  166. // the TUNNEL. Thus, when the TUNNEL is created and an interface is
  167. // added to IP, the ref count is set to 2. Since IP does not return
  168. // from IPDeleteInterface() till it is done using the interface, this
  169. // means we do not need to reference the tunnel when executing code that
  170. // is called by IP (e.g IpIpSend())
  171. //
  172. RT_LOCK rlLock;
  173. LONG lRefCount;
  174. //
  175. // The (fake) hardware address
  176. //
  177. BYTE rgbyHardwareAddr[ARP_802_ADDR_LENGTH];
  178. //
  179. // The TTL associated with the tunnel. Defaults to DEFAULT_TTL
  180. //
  181. BYTE byTtl;
  182. //
  183. // Flags determiniting the state of the tunnel
  184. //
  185. BYTE byTunnelState;
  186. //
  187. // The MTU for this tunnel. This is learnt dynamically, though it starts
  188. // at DEFAULT_MTU
  189. //
  190. ULONG ulMtu;
  191. //
  192. // The link on the address list
  193. //
  194. LIST_ENTRY leAddressLink;
  195. //
  196. // The admin and operational states.
  197. //
  198. DWORD dwAdminState;
  199. DWORD dwOperState;
  200. //
  201. // The KeQueryTickCount() value the last time the dwOperState was
  202. // changed
  203. //
  204. ULONGLONG ullLastChange;
  205. //
  206. // Last time the state changed. We dont do anything with this right now
  207. //
  208. DWORD dwLastChange;
  209. //
  210. // Sundry MIB-II statistics for the interface
  211. //
  212. ULONG ulInOctets;
  213. ULONG ulInUniPkts;
  214. ULONG ulInNonUniPkts;
  215. ULONG ulInDiscards;
  216. ULONG ulInErrors;
  217. ULONG ulInUnknownProto;
  218. ULONG ulOutOctets;
  219. ULONG ulOutUniPkts;
  220. ULONG ulOutNonUniPkts;
  221. ULONG ulOutDiscards;
  222. ULONG ulOutErrors;
  223. ULONG ulOutQLen;
  224. //
  225. // Constant structures needed to do a send. Instead of filling these
  226. // up every time, we reuse these
  227. //
  228. TA_IP_ADDRESS tiaIpAddr;
  229. TDI_CONNECTION_INFORMATION tciConnInfo;
  230. //
  231. // Each tunnel has a packet pool, a buffer pool for headers and a
  232. // buffer pool for data
  233. //
  234. PACKET_POOL PacketPool;
  235. BUFFER_POOL HdrBufferPool;
  236. LIST_ENTRY lePacketQueueHead;
  237. BOOLEAN bWorkItemQueued;
  238. }TUNNEL, *PTUNNEL;
  239. typedef struct _ADDRESS_BLOCK
  240. {
  241. //
  242. // Link on the list of address blocks
  243. //
  244. LIST_ENTRY leAddressLink;
  245. //
  246. // Listhead for the tunnels that use this as their local address
  247. //
  248. LIST_ENTRY leTunnelList;
  249. //
  250. // The IP Address
  251. //
  252. DWORD dwAddress;
  253. //
  254. // Set to true if the address is actually in the system
  255. //
  256. BOOLEAN bAddressPresent;
  257. }ADDRESS_BLOCK, *PADDRESS_BLOCK;
  258. //
  259. // The size of a data buffer in the buffer pool
  260. //
  261. #define DATA_BUFFER_SIZE (128)
  262. //
  263. // The size of the header buffer in the buffer pool. We dont have any
  264. // options so we go with the basic IP header
  265. //
  266. #define HEADER_BUFFER_SIZE MIN_IP_HEADER_LENGTH
  267. //++
  268. //
  269. // PIP_HEADER
  270. // GetIpHeader(
  271. // PTUNNEL pTunnel
  272. // )
  273. //
  274. // Gets an IP Header from the HdrBufferPool
  275. //
  276. //--
  277. #define GetIpHeader(X) (PIP_HEADER)GetBufferFromPool(&((X)->HdrBufferPool))
  278. //++
  279. //
  280. // VOID
  281. // FreeHeader(
  282. // PTUNNEL pTunnel,
  283. // PIP_HEADER pHeader
  284. // )
  285. //
  286. // Frees an IP Header buffer to the HdrBufferPool
  287. //
  288. //--
  289. #define FreeIpHeader(T,H) FreeBufferToPool(&((T)->HdrBufferPool),(H))
  290. //
  291. // The size of our protocol reserved area
  292. //
  293. #define PACKET_RSVD_LENGTH 8
  294. //
  295. // The ref count for a TUNNEL is set to 2, once because a pointer is saved in
  296. // the group list and once because the function that creates the TUNNEL will
  297. // deref it once
  298. //
  299. #if 0
  300. #define InitRefCount(pTunnel) \
  301. { \
  302. DbgPrint("\n<>Init refcount to 2 for %x (%s, %d)\n\n", \
  303. pTunnel, __FILE__, __LINE__); \
  304. (pTunnel)->lRefCount = 2; \
  305. }
  306. #else
  307. #define InitRefCount(pTunnel) \
  308. (pTunnel)->lRefCount = 2
  309. #endif
  310. #if 0
  311. #define ReferenceTunnel(pTunnel) \
  312. { \
  313. DbgPrint("\n++Ref %x to %d (%s, %d)\n\n", \
  314. pTunnel, \
  315. InterlockedIncrement(&((pTunnel)->lRefCount)), \
  316. __FILE__, __LINE__); \
  317. }
  318. #else
  319. #define ReferenceTunnel(pTunnel) \
  320. InterlockedIncrement(&((pTunnel)->lRefCount))
  321. #endif
  322. #if 0
  323. #define DereferenceTunnel(pTunnel) \
  324. { \
  325. LONG __lTemp; \
  326. __lTemp = InterlockedDecrement(&((pTunnel)->lRefCount));\
  327. DbgPrint("\n--Deref %x to %d (%s, %d)\n\n", \
  328. pTunnel,__lTemp,__FILE__, __LINE__); \
  329. if(__lTemp == 0) \
  330. { \
  331. DeleteTunnel((pTunnel)); \
  332. } \
  333. }
  334. #else
  335. #define DereferenceTunnel(pTunnel) \
  336. { \
  337. if(InterlockedDecrement(&((pTunnel)->lRefCount)) == 0) \
  338. { \
  339. DeleteTunnel((pTunnel)); \
  340. } \
  341. }
  342. #endif
  343. //
  344. // The state of the driver.
  345. //
  346. #define DRIVER_STOPPED 0
  347. #define DRIVER_STARTING 1
  348. #define DRIVER_STARTED 2
  349. //
  350. // Timeout value for start is 10 seconds.
  351. // So in 100ns it becomes
  352. //
  353. #define START_TIMEOUT (LONGLONG)(10 * 1000 * 1000 * 10)
  354. #define CompareUnicodeStrings(S1,S2) \
  355. (((S1)->Length == (S2)->Length) && \
  356. (RtlCompareMemory((S1)->Buffer, \
  357. (S2)->Buffer, \
  358. (S2)->Length) == (S2)->Length))
  359. //
  360. // #defines to keep track of number of threads of execution in our code
  361. // This is needed for us to stop cleanly
  362. //
  363. //
  364. // EnterDriver returns if the driver is stopping
  365. //
  366. #define EnterDriver() \
  367. { \
  368. RtAcquireSpinLockAtDpcLevel(&g_rlStateLock); \
  369. if(g_dwDriverState is DRIVER_STOPPED) \
  370. { \
  371. RtReleaseSpinLockFromDpcLevel(&g_rlStateLock); \
  372. return; \
  373. } \
  374. g_ulNumThreads++; \
  375. RtReleaseSpinLockFromDpcLevel(&g_rlStateLock); \
  376. }
  377. #define ExitDriver() \
  378. { \
  379. RtAcquireSpinLockAtDpcLevel(&g_rlStateLock); \
  380. g_ulNumThreads--; \
  381. if((g_dwDriverState is DRIVER_STOPPED) and \
  382. (g_dwNumThreads is 0)) \
  383. { \
  384. KeSetEvent(&g_keStateEvent, \
  385. 0, \
  386. FALSE); \
  387. } \
  388. RtReleaseSpinLockFromDpcLevel(&g_rlStateLock); \
  389. }
  390. //
  391. // Nifty macro for printing IP Addresses
  392. //
  393. #define PRINT_IPADDR(x) \
  394. ((x)&0x000000FF),(((x)&0x0000FF00)>>8),(((x)&0x00FF0000)>>16),(((x)&0xFF000000)>>24)
  395. //
  396. // IPv4 header
  397. //
  398. #include <packon.h>
  399. #if !defined(DONT_INCLUDE_IP_HEADER)
  400. #define IP_DF_FLAG (0x0040)
  401. //
  402. // 0.0.0.0 is an invalid address
  403. //
  404. #define INVALID_IP_ADDRESS (0x00000000)
  405. typedef struct _IP_HEADER
  406. {
  407. BYTE byVerLen; // Version and length.
  408. BYTE byTos; // Type of service.
  409. WORD wLength; // Total length of datagram.
  410. WORD wId; // Identification.
  411. WORD wFlagOff; // Flags and fragment offset.
  412. BYTE byTtl; // Time to live.
  413. BYTE byProtocol; // Protocol.
  414. WORD wXSum; // Header checksum.
  415. DWORD dwSrc; // Source address.
  416. DWORD dwDest; // Destination address.
  417. }IP_HEADER, *PIP_HEADER;
  418. #endif
  419. #include <packoff.h>
  420. //
  421. // Define alignment macros to align structure sizes and pointers up and down.
  422. //
  423. #define ALIGN_DOWN(length, type) \
  424. ((ULONG)(length) & ~(sizeof(type) - 1))
  425. #define ALIGN_UP(length, type) \
  426. (ALIGN_DOWN(((ULONG)(length) + sizeof(type) - 1), type))
  427. #define ALIGN_DOWN_POINTER(address, type) \
  428. ((PVOID)((ULONG_PTR)(address) & ~((ULONG_PTR)sizeof(type) - 1)))
  429. #define ALIGN_UP_POINTER(address, type) \
  430. (ALIGN_DOWN_POINTER(((ULONG_PTR)(address) + sizeof(type) - 1), type))
  431. #endif // __IPINIP_IPINIP_H__