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.

1441 lines
50 KiB

  1. /*++
  2. Copyright (c) 1997-2001 Microsoft Corporation
  3. Module Name:
  4. macros.h
  5. Abstract:
  6. Contains all the macros.
  7. Author:
  8. Sanjay Anand (SanjayAn) 2-January-1997
  9. ChunYe
  10. Environment:
  11. Kernel mode
  12. Revision History:
  13. --*/
  14. #ifndef _MACROS_H
  15. #define _MACROS_H
  16. #define REGISTER register
  17. #define EXTENDED_MULTIPLY RtlExtendedIntegerMultiply
  18. #ifndef MAX
  19. #define MAX(x,y) ((x) < (y)) ? (y) : (x)
  20. #endif
  21. #ifndef MIN
  22. #define MIN(x,y) ((x) < (y)) ? (x) : (y)
  23. #endif
  24. #define MAX_IP_DATA_LENGTH ((USHORT)0xfffff)
  25. #define MAX_AH_OUTPUT_LEN MAX(MD5DIGESTLEN, A_SHA_DIGEST_LEN)
  26. //
  27. // This macro adds a ULONG to a LARGE_INTEGER.
  28. //
  29. #define ADD_TO_LARGE_INTEGER(_LargeInteger,_Ulong) \
  30. ExInterlockedAddLargeStatistic((PLARGE_INTEGER)(_LargeInteger),(ULONG)(_Ulong))
  31. #define IPSecEqualMemory(_p1, _p2, _len) RtlEqualMemory(_p1, _p2, _len)
  32. #define IPSecMoveMemory(_p1, _p2, _len) RtlMoveMemory(_p1, _p2, _len)
  33. #define IPSecZeroMemory(_p1, _len) RtlZeroMemory(_p1, _len)
  34. //
  35. // Truncates _src to _numbytes and copies into _dest
  36. // then zeroes out the rest in _dest
  37. //
  38. #define TRUNCATE(_dest, _src, _numbytes, _destlen) { \
  39. IPSecZeroMemory ( _dest+_numbytes, _destlen - _numbytes); \
  40. }
  41. //
  42. // Some macros
  43. //
  44. #ifdef NET_SHORT
  45. #undef NET_SHORT
  46. #endif
  47. __inline
  48. USHORT
  49. FASTCALL
  50. NET_SHORT(USHORT x)
  51. {
  52. #if (defined(_M_IX86) && (_MSC_FULL_VER > 13009037)) || ((defined(_M_AMD64) || defined(_M_IA64)) && (_MSC_FULL_VER > 13009175))
  53. return _byteswap_ushort(x);
  54. #else
  55. ASSERT(x <= 0xffff);
  56. return (x << 8) | (x >> 8);
  57. #endif
  58. }
  59. #define NET_TO_HOST_SHORT(Val) NET_SHORT(Val)
  60. #define HOST_TO_NET_SHORT(Val) NET_SHORT(Val)
  61. #ifdef NET_LONG
  62. #undef NET_LONG
  63. #endif
  64. __inline
  65. ULONG
  66. FASTCALL
  67. NET_LONG(ULONG x)
  68. {
  69. #if (defined(_M_IX86) && (_MSC_FULL_VER > 13009037)) || ((defined(_M_AMD64) || defined(_M_IA64)) && (_MSC_FULL_VER > 13009175))
  70. return _byteswap_ulong(x);
  71. #else
  72. REGISTER ULONG BytesSwapped;
  73. BytesSwapped = ((x & 0x00ff00ff) << 8) | ((x & 0xff00ff00) >> 8);
  74. return (BytesSwapped << 16) | (BytesSwapped >> 16);
  75. #endif
  76. }
  77. #define NET_TO_HOST_LONG(Val) NET_LONG(Val)
  78. #define HOST_TO_NET_LONG(Val) NET_LONG(Val)
  79. #define IPSEC_100NS_FACTOR 10000000
  80. #define IPSEC_CONVERT_SECS_TO_100NS(_li, _delta) { \
  81. (_li).LowPart = _delta; \
  82. (_li) = EXTENDED_MULTIPLY(_li, IPSEC_100NS_FACTOR); \
  83. }
  84. #define IS_CLASSD(i) (((long)(i) & 0xf0000000) == 0xe0000000)
  85. //
  86. // Check SA against Lifetime information - we try to anticipate in advance if the
  87. // SA is going to expire and start off a re-key so that when it actually does expire,
  88. // we have the new SA setup.
  89. //
  90. //
  91. // IPSEC_EXPIRE_TIME_PAD is the time before expiration when we start re-keying
  92. //
  93. #define IPSEC_EXPIRE_TIME_PAD_I (75 * IPSEC_100NS_FACTOR)
  94. #define IPSEC_EXPIRE_TIME_PAD_R (40 * IPSEC_100NS_FACTOR)
  95. #define IPSEC_EXPIRE_TIME_PAD_OAKLEY (1 * IPSEC_100NS_FACTOR)
  96. //
  97. // IPSEC_INBOUND_KEEPALIVE_TIME is the time an expired inboundSA will be kept
  98. // alive in the driver
  99. //
  100. #define IPSEC_INBOUND_KEEPALIVE_TIME (60)
  101. //
  102. // IPSEC_MAX_EXPIRE_TIME is the maximum phase-2 lifetime allowed in driver
  103. //
  104. #define IPSEC_MAX_EXPIRE_TIME (48 * 3600 - 1)
  105. //
  106. // IPSEC_MIN_EXPIRE_TIME is the minimum phase-2 lifetime allowed in driver
  107. //
  108. #define IPSEC_MIN_EXPIRE_TIME (60)
  109. #define IPSEC_EXPIRE_THRESHOLD_I (50)
  110. #define IPSEC_EXPIRE_THRESHOLD_R (75)
  111. //
  112. // skew the initiator and responder with Pads
  113. //
  114. #define IPSEC_DEFAULT_SA_IDLE_TIME_PAD_I 0
  115. #define IPSEC_DEFAULT_SA_IDLE_TIME_PAD_R 30
  116. #define IPSEC_NLBS_IDLE_TIME 60
  117. //
  118. // The # of packets before which we start reneg. because of replay rollover
  119. // 1M bytes / 1500 packets
  120. //
  121. #define IPSEC_EXPIRE_REPLAY_MASK (0x80000000)
  122. #define MAX_ULONG ((ULONG) -1)
  123. #define MAX_LONG (0x7fffffff)
  124. //
  125. // Some constants used for POST_EXPIRE_NOTIFY
  126. //
  127. #define IPSEC_INVALID_SPI 0
  128. #define IPSEC_INVALID_ADDR (-1)
  129. //
  130. // Check the lifetime (kbytes and seconds) and replay rollover.
  131. // FALSE => expired
  132. //
  133. #define IPSEC_CHECK_PADDED_LIFETIME(__pSA, _status, _index) { \
  134. LARGE_INTEGER __curtime; \
  135. (_status) = TRUE; \
  136. if (((__pSA)->sa_ReplaySendSeq[0] & \
  137. IPSEC_EXPIRE_REPLAY_MASK) && \
  138. ((__pSA)->sa_Flags & FLAGS_SA_OUTBOUND)) { \
  139. _status = FALSE; \
  140. } else { \
  141. KeQuerySystemTime(&__curtime); \
  142. if (((__pSA)->sa_KeyExpirationTimeWithPad.QuadPart > 0i64) && \
  143. ((__pSA)->sa_KeyExpirationTimeWithPad.QuadPart < __curtime.QuadPart)) {\
  144. _status = FALSE; \
  145. } else if (((__pSA)->sa_KeyExpirationBytesWithPad.QuadPart > 0i64) && \
  146. ((__pSA)->sa_KeyExpirationBytesWithPad.QuadPart < (__pSA)->sa_TotalBytesTransformed.QuadPart)) { \
  147. _status = FALSE; \
  148. } \
  149. } \
  150. }
  151. #define IPSEC_CHECK_LIFETIME(__pSA, _status, _index) { \
  152. LARGE_INTEGER __curtime; \
  153. (_status) = TRUE; \
  154. if ((__pSA)->sa_ReplaySendSeq[_index] == MAX_ULONG) { \
  155. _status = FALSE; \
  156. } else { \
  157. KeQuerySystemTime(&__curtime); \
  158. if (((__pSA)->sa_KeyExpirationTime.QuadPart > 0i64) && \
  159. ((__pSA)->sa_KeyExpirationTime.QuadPart < __curtime.QuadPart)) { \
  160. _status = FALSE; \
  161. } else if (((__pSA)->sa_KeyExpirationBytes.QuadPart > 0i64) && \
  162. ((__pSA)->sa_KeyExpirationBytes.QuadPart < (__pSA)->sa_TotalBytesTransformed.QuadPart)) { \
  163. _status = FALSE; \
  164. } \
  165. } \
  166. }
  167. #define IPSEC_SA_EXPIRED(__pSA, __fexpired) { \
  168. LARGE_INTEGER __curtime; \
  169. KeQuerySystemTime(&__curtime); \
  170. (__fexpired) = FALSE; \
  171. __curtime.QuadPart -= pSA->sa_LastUsedTime.QuadPart;\
  172. if (__pSA->sa_IdleTime.QuadPart < __curtime.QuadPart) { \
  173. __fexpired = TRUE; \
  174. } \
  175. }
  176. //
  177. // Max tolerated collisions when trying to allocate SPIs.
  178. //
  179. #define MAX_SPI_RETRIES 50
  180. #define IPSEC_SPI_TO_ENTRY(_spi, _entry, _dst) { \
  181. KIRQL kIrql; \
  182. AcquireReadLock(&g_ipsec.SPIListLock, &kIrql); \
  183. *(_entry) = IPSecLookupSABySPIWithLock(_spi, _dst); \
  184. if (*(_entry)) { \
  185. IPSecRefSA((*(_entry))); \
  186. } \
  187. ReleaseReadLock(&g_ipsec.SPIListLock, kIrql); \
  188. }
  189. //
  190. // Generic memory allocators
  191. //
  192. #define IPSecAllocatePktInfo(__tag) \
  193. IPSecAllocateMemory(sizeof(NDIS_IPSEC_PACKET_INFO), __tag)
  194. #define IPSecFreePktInfo(__p) \
  195. IPSecFreeMemory(__p)
  196. #define IPSecAllocatePktExt(__tag) \
  197. IPSecAllocateMemory(sizeof(NDIS_IPSEC_PACKET_INFO), __tag)
  198. #define IPSecFreePktExt(__p) \
  199. IPSecFreeMemory(__p)
  200. #define IPSecAllocateBuffer(_ntstatus, _ppBuf, _ppData, _size, _tag) { \
  201. PIPSEC_LA_BUFFER __labuf; \
  202. *(_ntstatus) = STATUS_SUCCESS; \
  203. __labuf = IPSecGetBuffer(_size, _tag); \
  204. if (__labuf) { \
  205. if (ARGUMENT_PRESENT(_ppData)) { \
  206. *(PVOID *)(_ppData) = __labuf->Buffer; \
  207. } \
  208. *(_ppBuf) = __labuf->Mdl; \
  209. NdisAdjustBufferLength(__labuf->Mdl, _size); \
  210. NDIS_BUFFER_LINKAGE(__labuf->Mdl) = NULL; \
  211. } else { \
  212. *(_ntstatus) = STATUS_INSUFFICIENT_RESOURCES; \
  213. } \
  214. }
  215. #define IPSecFreeBuffer(_ntstatus, _pBuf) { \
  216. PIPSEC_LA_BUFFER __buffer; \
  217. *(_ntstatus) = STATUS_SUCCESS; \
  218. __buffer = CONTAINING_RECORD((_pBuf), IPSEC_LA_BUFFER, Data); \
  219. IPSecReturnBuffer(__buffer); \
  220. }
  221. #define IPSecAllocateSendCompleteCtx(__tag) \
  222. ExAllocateFromNPagedLookasideList(&g_ipsec.IPSecLookasideLists->SendCompleteCtxList)
  223. #define IPSecFreeSendCompleteCtx(_buffer) \
  224. ExFreeToNPagedLookasideList(&g_ipsec.IPSecLookasideLists->SendCompleteCtxList, _buffer); \
  225. IPSEC_DECREMENT(g_ipsec.NumSends);
  226. #define IPSEC_GET_TOTAL_LEN(_pbuf, _plen) { \
  227. PNDIS_BUFFER _ptemp = (PNDIS_BUFFER)(_pbuf); \
  228. *(_plen) = 0; \
  229. while (_ptemp) { \
  230. *(_plen) += _ptemp->ByteCount; \
  231. _ptemp = NDIS_BUFFER_LINKAGE(_ptemp); \
  232. } \
  233. }
  234. #define IPSEC_GET_TOTAL_LEN_RCV_BUF(_pbuf, _plen) { \
  235. IPRcvBuf *_ptemp = (_pbuf); \
  236. *(_plen) = 0; \
  237. while (_ptemp) { \
  238. *(_plen) += _ptemp->ipr_size; \
  239. _ptemp = IPSEC_BUFFER_LINKAGE(_ptemp); \
  240. } \
  241. }
  242. //
  243. // Copy len bytes from RcvBuf chain to mdl (only one MDL)
  244. //
  245. #define IPSEC_COPY_FROM_RCVBUF(_pMdl, _pRcvBuf, _len, _offset) { \
  246. IPRcvBuf *__pBuf=(_pRcvBuf); \
  247. PMDL __pMdl=(_pMdl); \
  248. ULONG __srclen; \
  249. ULONG __destlen; \
  250. ULONG __totallen=0; \
  251. PUCHAR __pSrc; \
  252. PUCHAR __pDest; \
  253. ULONG __curroffset = (_offset); \
  254. IPSecQueryNdisBuf(__pMdl, &__pDest, &__destlen); \
  255. while (__pBuf) { \
  256. IPSecQueryRcvBuf(__pBuf, &__pSrc, &__srclen); \
  257. if (__srclen > __curroffset) { \
  258. RtlCopyMemory(__pDest, __pSrc+__curroffset, __srclen-__curroffset); \
  259. __pDest += (__srclen - __curroffset); \
  260. __totallen += (__srclen - __curroffset); \
  261. } \
  262. __curroffset = 0; \
  263. __pBuf = IPSEC_BUFFER_LINKAGE(__pBuf); \
  264. } \
  265. ASSERT(__totallen == __destlen); \
  266. }
  267. //
  268. // Copy len bytes from Ndis Buffer chain to mdl (only one MDL)
  269. //
  270. #define IPSEC_COPY_FROM_NDISBUF(_pMdl, _pRcvBuf, _len, _offset) { \
  271. NDIS_BUFFER *__pBuf=(_pRcvBuf); \
  272. PMDL __pMdl=(_pMdl); \
  273. ULONG __srclen; \
  274. ULONG __destlen; \
  275. ULONG __totallen=0; \
  276. PUCHAR __pSrc; \
  277. PUCHAR __pDest; \
  278. ULONG __curroffset = (_offset); \
  279. IPSecQueryNdisBuf(__pMdl, &__pDest, &__destlen); \
  280. while (__pBuf) { \
  281. IPSecQueryNdisBuf(__pBuf, &__pSrc, &__srclen); \
  282. if (__srclen > __curroffset) { \
  283. RtlCopyMemory(__pDest, __pSrc+__curroffset, __srclen-__curroffset); \
  284. __pDest += (__srclen - __curroffset); \
  285. __totallen += (__srclen - __curroffset); \
  286. } \
  287. __curroffset = 0; \
  288. __pBuf = NDIS_BUFFER_LINKAGE(__pBuf); \
  289. } \
  290. ASSERT(__totallen == __destlen); \
  291. }
  292. #define IPSecAllocateMemory(_size, _tag) \
  293. ExAllocatePoolWithTag (NonPagedPool, _size, _tag)
  294. #define IPSecAllocateMemoryLowPriority(_size, _tag) \
  295. ExAllocatePoolWithTagPriority (NonPagedPool, _size, _tag, LowPoolPriority)
  296. #define IPSecFreeMemory(_addr) ExFreePool (_addr)
  297. #define IPSecQueryNdisBuf(_Buffer, _VirtualAddress, _Length) \
  298. { \
  299. PNDIS_BUFFER __Mdl = (PNDIS_BUFFER) (_Buffer); \
  300. if (ARGUMENT_PRESENT(_VirtualAddress)) { \
  301. *(PVOID *)(_VirtualAddress) = (__Mdl)->MappedSystemVa; \
  302. } \
  303. *(_Length) = (__Mdl)->ByteCount; \
  304. }
  305. #define IPSecQueryRcvBuf(_Buffer, _VirtualAddress, _Length) \
  306. { \
  307. IPRcvBuf *__buf = (IPRcvBuf *) (_Buffer); \
  308. if (ARGUMENT_PRESENT(_VirtualAddress)) { \
  309. *(PVOID *)(_VirtualAddress) = (__buf)->ipr_buffer; \
  310. } \
  311. *(_Length) = (__buf)->ipr_size; \
  312. }
  313. #define IPSEC_ADJUST_BUFFER_LEN(_pBuf, _len) \
  314. ((IPRcvBuf *)(_pBuf))->ipr_size = (_len)
  315. #define IPSEC_ADJUST_BUFFER(_pBuf, _offset) \
  316. ((IPRcvBuf *)(_pBuf))->ipr_buffer += (_offset)
  317. #define IPSEC_ADJUST_BUFFER_NEG(_pBuf, _offset) \
  318. ((IPRcvBuf *)(_pBuf))->ipr_buffer -= (_offset)
  319. #define IPSEC_ADJUST_BUFFER_RCVOFFSET(_pBuf, _offset) \
  320. ((IPRcvBuf *)(_pBuf))->ipr_RcvOffset += (_offset)
  321. #define IPSEC_BUFFER_LINKAGE(_pBuf) \
  322. ((IPRcvBuf *)(_pBuf))->ipr_next
  323. #define IPSEC_BUFFER_LEN(_pBuf) \
  324. ((IPRcvBuf *)(_pBuf))->ipr_size
  325. #define IPSEC_BUFFER_OWNER(_pBuf) \
  326. (((IPRcvBuf *)(_pBuf))->ipr_owner)
  327. #define IPSEC_SET_OFFSET_IN_BUFFER(_pBuf, _offset) { \
  328. PUCHAR _p; \
  329. LONG _len; \
  330. IPSecQueryRcvBuf((_pBuf), &(_p), &(_len)); \
  331. if ((_offset) > 0 && (_offset) < (_len)) { \
  332. if (IPSEC_BUFFER_OWNER(_pBuf) == IPR_OWNER_FIREWALL) { \
  333. IPSecMoveMemory((_p), (_p) + (_offset), (_len) - (_offset));\
  334. } else { \
  335. IPSEC_ADJUST_BUFFER((_pBuf), (_offset)); \
  336. IPSEC_ADJUST_BUFFER_RCVOFFSET((_pBuf), (_offset)); \
  337. } \
  338. IPSEC_ADJUST_BUFFER_LEN((_pBuf), (_len) - (_offset)); \
  339. } else { \
  340. ASSERT(FALSE); \
  341. return STATUS_INVALID_PARAMETER; \
  342. } \
  343. }
  344. #define IPSEC_ADD_VALUE(_val, _inc) InterlockedExchangeAdd((PULONG)&(_val), _inc)
  345. #define IPSEC_INCREMENT(_val) InterlockedIncrement(&(_val))
  346. #define IPSEC_DECREMENT(_val) InterlockedDecrement(&(_val))
  347. #define IPSEC_GET_VALUE(_val) InterlockedExchangeAdd((PULONG)&(_val), 0)
  348. #define IPSEC_SET_VALUE(_target, _val) \
  349. InterlockedExchange((PULONG)&(_target), _val)
  350. #define IPSEC_DRIVER_IS_EMPTY() (g_ipsec.NumPolicies == 0)
  351. #define IPSEC_DRIVER_IS_INACTIVE() (g_ipsec.DriverUnloading || !g_ipsec.InitTcpip)
  352. #define IPSEC_DRIVER_UNLOADING() (g_ipsec.DriverUnloading)
  353. #define IPSEC_DRIVER_BOUND() (g_ipsec.BoundToIP)
  354. #define IPSEC_DRIVER_SEND_BOUND() (g_ipsec.SendBoundToIP)
  355. #define IPSEC_DRIVER_INIT_CRYPTO() (g_ipsec.InitCrypto)
  356. #define IPSEC_DRIVER_INIT_RNG() (g_ipsec.InitRNG)
  357. #define IPSEC_DRIVER_INIT_TCPIP() (g_ipsec.InitTcpip)
  358. #if FIPS
  359. #define IPSEC_DRIVER_INIT_FIPS() (g_ipsec.InitFips)
  360. #endif
  361. #if GPC
  362. #define IPSEC_DRIVER_INIT_GPC() (g_ipsec.InitGpc)
  363. #endif
  364. #if DBG
  365. #define IPSecRemoveEntryList(_x) \
  366. { \
  367. RemoveEntryList(_x); \
  368. (_x)->Flink = (_x)->Blink = (PLIST_ENTRY)__LINE__; \
  369. }
  370. #else
  371. #define IPSecRemoveEntryList(_x) RemoveEntryList(_x)
  372. #endif
  373. //
  374. // macros for filter list management
  375. //
  376. #define IS_TRANSPORT_FILTER(f) (!(f)->TunnelFilter)
  377. #define IS_TUNNEL_FILTER(f) ((f)->TunnelFilter)
  378. #define IS_INBOUND_FILTER(f) ((f)->Flags & FILTER_FLAGS_INBOUND)
  379. #define IS_OUTBOUND_FILTER(f) ((f)->Flags & FILTER_FLAGS_OUTBOUND)
  380. #define IS_EXEMPT_FILTER(f) (((f)->Flags & FILTER_FLAGS_DROP) || ((f)->Flags & FILTER_FLAGS_PASS_THRU))
  381. #define IS_MULTICAST_FILTER(f) (IS_CLASSD(NET_LONG((f)->SRC_ADDR)) || \
  382. IS_CLASSD(NET_LONG((f)->DEST_ADDR)))
  383. __inline
  384. PLIST_ENTRY
  385. IPSecResolveFilterList(
  386. IN BOOLEAN fTunnel,
  387. IN BOOLEAN fOutbound
  388. )
  389. {
  390. PLIST_ENTRY pEntry;
  391. if (fTunnel) {
  392. if (fOutbound) {
  393. pEntry = &g_ipsec.FilterList[OUTBOUND_TUNNEL_FILTER];
  394. } else {
  395. pEntry = &g_ipsec.FilterList[INBOUND_TUNNEL_FILTER];
  396. }
  397. } else {
  398. if (fOutbound) {
  399. pEntry = &g_ipsec.FilterList[OUTBOUND_TRANSPORT_FILTER];
  400. } else {
  401. pEntry = &g_ipsec.FilterList[INBOUND_TRANSPORT_FILTER];
  402. }
  403. }
  404. return pEntry;
  405. }
  406. //
  407. // Filter/SA Cache Table
  408. //
  409. #define CacheMatch(uliAddr, uliPort, pInCache) \
  410. ((uliAddr).QuadPart == pInCache->uliSrcDstAddr.QuadPart) && \
  411. ((uliPort).QuadPart == pInCache->uliProtoSrcDstPort.QuadPart)
  412. #define IS_VALID_CACHE_ENTRY(_entry) ((_entry)->pFilter != NULL)
  413. #define INVALIDATE_CACHE_ENTRY(_entry) \
  414. { \
  415. ((PFILTER_CACHE)(_entry))->pSAEntry = NULL; \
  416. ((PFILTER_CACHE)(_entry))->pNextSAEntry = NULL; \
  417. } \
  418. __inline
  419. ULONG
  420. FASTCALL
  421. CalcCacheIndex(
  422. IN IPAddr SrcAddr,
  423. IN IPAddr DestAddr,
  424. IN UCHAR Protocol,
  425. IN USHORT SrcPort,
  426. IN USHORT DestPort,
  427. IN BOOLEAN fOutbound
  428. )
  429. {
  430. REGISTER ULONG dwIndex;
  431. REGISTER ULONG Address;
  432. REGISTER USHORT Port;
  433. Address = SrcAddr ^ DestAddr;
  434. Port = SrcPort ^ DestPort;
  435. dwIndex = NET_TO_HOST_LONG(Address);
  436. dwIndex += Protocol;
  437. dwIndex += NET_TO_HOST_SHORT(Port);
  438. dwIndex %= g_ipsec.CacheHalfSize;
  439. if (fOutbound) {
  440. dwIndex += g_ipsec.CacheHalfSize;
  441. }
  442. return dwIndex;
  443. }
  444. __inline
  445. VOID
  446. CacheUpdate(
  447. IN ULARGE_INTEGER uliAddr,
  448. IN ULARGE_INTEGER uliPort,
  449. IN PVOID _pCtxt1,
  450. IN PVOID _pCtxt2,
  451. IN ULONG dwId,
  452. IN BOOLEAN fFilter
  453. )
  454. {
  455. PFILTER_CACHE __pCache;
  456. PFILTER_CACHE __pTempCache;
  457. PFILTER __pFilter;
  458. PSA_TABLE_ENTRY __pSA;
  459. PSA_TABLE_ENTRY __pNextSA;
  460. __pCache = g_ipsec.ppCache[(dwId)];
  461. if (IS_VALID_CACHE_ENTRY(__pCache)) {
  462. if (__pCache->FilterEntry) {
  463. __pCache->pFilter->FilterCache = NULL;
  464. } else {
  465. __pCache->pSAEntry->sa_FilterCache = NULL;
  466. if (__pCache->pNextSAEntry) {
  467. __pCache->pNextSAEntry->sa_FilterCache = NULL;
  468. __pCache->pNextSAEntry = NULL;
  469. }
  470. }
  471. }
  472. if (fFilter) {
  473. __pFilter = (PFILTER)(_pCtxt1);
  474. if (__pFilter->FilterCache) {
  475. INVALIDATE_CACHE_ENTRY(__pFilter->FilterCache);
  476. __pFilter->FilterCache = NULL;
  477. }
  478. __pCache->uliSrcDstAddr = (uliAddr);
  479. __pCache->uliProtoSrcDstPort = (uliPort);
  480. __pCache->FilterEntry = TRUE;
  481. __pCache->pFilter = __pFilter;
  482. __pFilter->FilterCache = __pCache;
  483. } else {
  484. __pSA = (PSA_TABLE_ENTRY)(_pCtxt1);
  485. __pNextSA = (PSA_TABLE_ENTRY)(_pCtxt2);
  486. if (__pSA->sa_FilterCache) {
  487. __pTempCache = __pSA->sa_FilterCache;
  488. __pTempCache->pSAEntry->sa_FilterCache = NULL;
  489. if (__pTempCache->pNextSAEntry) {
  490. __pTempCache->pNextSAEntry->sa_FilterCache = NULL;
  491. }
  492. INVALIDATE_CACHE_ENTRY(__pTempCache);
  493. }
  494. if (__pNextSA && __pNextSA->sa_FilterCache) {
  495. __pTempCache = __pNextSA->sa_FilterCache;
  496. __pTempCache->pSAEntry->sa_FilterCache = NULL;
  497. if (__pTempCache->pNextSAEntry) {
  498. __pTempCache->pNextSAEntry->sa_FilterCache = NULL;
  499. }
  500. INVALIDATE_CACHE_ENTRY(__pTempCache);
  501. }
  502. __pCache->uliSrcDstAddr = (uliAddr);
  503. __pCache->uliProtoSrcDstPort = (uliPort);
  504. __pCache->FilterEntry = FALSE;
  505. __pCache->pSAEntry = __pSA;
  506. __pSA->sa_FilterCache = __pCache;
  507. if (__pNextSA) {
  508. __pCache->pNextSAEntry = __pNextSA;
  509. __pNextSA->sa_FilterCache = __pCache;
  510. }
  511. }
  512. }
  513. __inline
  514. VOID
  515. IPSecInvalidateSACacheEntry(
  516. IN PSA_TABLE_ENTRY pSA
  517. )
  518. {
  519. PFILTER_CACHE pCache;
  520. pCache = pSA->sa_FilterCache;
  521. if (pCache) {
  522. ASSERT(IS_VALID_CACHE_ENTRY(pCache));
  523. ASSERT(pSA == pCache->pSAEntry || pSA == pCache->pNextSAEntry);
  524. pCache->pSAEntry->sa_FilterCache = NULL;
  525. if (pCache->pNextSAEntry) {
  526. pCache->pNextSAEntry->sa_FilterCache = NULL;
  527. }
  528. INVALIDATE_CACHE_ENTRY(pCache);
  529. }
  530. }
  531. __inline
  532. VOID
  533. IPSecInvalidateFilterCacheEntry(
  534. IN PFILTER pFilter
  535. )
  536. {
  537. PFILTER_CACHE pCache;
  538. pCache = pFilter->FilterCache;
  539. if (pCache) {
  540. ASSERT(IS_VALID_CACHE_ENTRY(pCache));
  541. ASSERT(IS_EXEMPT_FILTER(pFilter));
  542. pFilter->FilterCache = NULL;
  543. INVALIDATE_CACHE_ENTRY(pCache);
  544. }
  545. }
  546. __inline
  547. VOID
  548. IPSecStartSATimer(
  549. IN PSA_TABLE_ENTRY pSA,
  550. IN IPSEC_TIMEOUT_HANDLER TimeoutHandler,
  551. IN ULONG SecondsToGo
  552. )
  553. {
  554. if (pSA->sa_Flags & FLAGS_SA_TIMER_STARTED) {
  555. if (IPSecStopTimer(&pSA->sa_Timer)) {
  556. IPSecStartTimer(&pSA->sa_Timer,
  557. TimeoutHandler,
  558. SecondsToGo,
  559. (PVOID)pSA);
  560. }
  561. } else {
  562. pSA->sa_Flags |= FLAGS_SA_TIMER_STARTED;
  563. IPSecStartTimer(&pSA->sa_Timer,
  564. TimeoutHandler,
  565. SecondsToGo,
  566. (PVOID)pSA);
  567. }
  568. }
  569. __inline
  570. VOID
  571. IPSecStopSATimer(
  572. IN PSA_TABLE_ENTRY pSA
  573. )
  574. {
  575. if (pSA->sa_Flags & FLAGS_SA_TIMER_STARTED) {
  576. pSA->sa_Flags &= ~FLAGS_SA_TIMER_STARTED;
  577. IPSecStopTimer(&pSA->sa_Timer);
  578. }
  579. }
  580. __inline
  581. VOID
  582. IPSecStopTimerDerefSA(
  583. IN PSA_TABLE_ENTRY pSA
  584. )
  585. {
  586. if (pSA->sa_Flags & FLAGS_SA_TIMER_STARTED) {
  587. if (IPSecStopTimer(&pSA->sa_Timer)) {
  588. pSA->sa_Flags &= ~FLAGS_SA_TIMER_STARTED;
  589. IPSecDerefSA(pSA);
  590. }
  591. } else {
  592. IPSecDerefSA(pSA);
  593. }
  594. }
  595. __inline
  596. VOID
  597. IPSecDerefSANextSA(
  598. IN PSA_TABLE_ENTRY pSA,
  599. IN PSA_TABLE_ENTRY pNextSA
  600. )
  601. {
  602. if (pNextSA) {
  603. IPSecDerefSA(pNextSA);
  604. }
  605. IPSecDerefSA(pSA);
  606. }
  607. __inline
  608. VOID
  609. IPSecRemoveSPIEntry(
  610. IN PSA_TABLE_ENTRY pSA
  611. )
  612. {
  613. if (pSA->sa_Flags & FLAGS_SA_ON_SPI_HASH) {
  614. IPSecRemoveEntryList(&pSA->sa_SPILinkage);
  615. pSA->sa_Flags &= ~FLAGS_SA_ON_SPI_HASH;
  616. }
  617. }
  618. //
  619. // Packs the src/dest IP addrs in a large integer
  620. //
  621. #define IPSEC_BUILD_SRC_DEST_ADDR(_li, _src, _dest) { \
  622. (_li).LowPart = _src; \
  623. (_li).HighPart = _dest; \
  624. }
  625. #define IPSEC_BUILD_SRC_DEST_MASK IPSEC_BUILD_SRC_DEST_ADDR
  626. //
  627. // Packs the Proto and Src/Dest ports into a large int
  628. //
  629. //
  630. // Ports make sense only for TCP and UDP
  631. //
  632. //
  633. // TCP/UDP header
  634. // 0 15 16 31
  635. // |----|----|----|----|----|----|----|----|
  636. // | Source Port | Dst Port |
  637. //
  638. #define IPSEC_BUILD_PROTO_PORT_LI(_li, _proto, _sport, _dport) { \
  639. (_li).LowPart = \
  640. MAKELONG(MAKEWORD((_proto),0x00),0x0000); \
  641. switch((_li).LowPart) { \
  642. case 6: \
  643. case 17: { \
  644. (_li).HighPart = MAKELONG((_sport),(_dport)); \
  645. break; \
  646. } \
  647. default: { \
  648. (_li).HighPart = 0x00000000; \
  649. break; \
  650. } \
  651. } \
  652. }
  653. #define IPSecRefFilter(__pfilter) IPSEC_INCREMENT((__pfilter)->Reference)
  654. #define IPSecFreeFilter(__pfilter) IPSecFreeMemory(__pfilter)
  655. #define IPSecDerefFilter(__pfilter) \
  656. { \
  657. if (IPSEC_DECREMENT((__pfilter)->Reference) == 0) { \
  658. IPSecFreeFilter(__pfilter); \
  659. } \
  660. }
  661. #define IPSecAllocateKeyBuffer(_size) IPSecAllocateMemory(_size, IPSEC_TAG_KEY)
  662. #define IPSecFreeKeyBuffer(_key) IPSecFreeMemory(_key)
  663. #define IPSecAllocateLogBuffer(_size) IPSecAllocateMemory(_size, IPSEC_TAG_LOG)
  664. #define IPSecFreeLogBuffer(_key) IPSecFreeMemory(_key)
  665. #define IPSecFreeSA(_sa) { \
  666. LONG _i; \
  667. for (_i=0; _i<(_sa)->sa_NumOps; _i++) { \
  668. if ((_sa)->INT_KEY(_i)) { \
  669. IPSecFreeKeyBuffer((_sa)->INT_KEY(_i)); \
  670. } \
  671. if ((_sa)->CONF_KEY(_i)) { \
  672. IPSecFreeKeyBuffer((_sa)->CONF_KEY(_i));\
  673. } \
  674. } \
  675. IPSecFreeMemory(_sa); \
  676. }
  677. #define IPSecGetAcquireContext() IPSecAllocateMemory(sizeof(IPSEC_ACQUIRE_CONTEXT), IPSEC_TAG_ACQUIRE_CTX)
  678. #define IPSecFreeAcquireContext(_ctx) IPSecFreeMemory(_ctx)
  679. #define IPSecGetNotifyExpire() IPSecAllocateMemory(sizeof(IPSEC_NOTIFY_EXPIRE), IPSEC_TAG_ACQUIRE_CTX)
  680. //
  681. // Hashes <SPI, Dest>
  682. //
  683. #define IPSEC_HASH_SPI(_dest, _spi, _phash) { \
  684. DWORD dwIndex; \
  685. dwIndex = NET_TO_HOST_LONG(_dest) + (_spi); \
  686. dwIndex %= g_ipsec.SAHashSize; \
  687. pHash = &g_ipsec.pSADb[dwIndex]; \
  688. IPSEC_DEBUG_KD_ONLY( \
  689. DBF_EXTRADIAGNOSTIC, ("SPI: Index: %lx for S: %lx, D: %lx, pHash: %lx", \
  690. dwIndex, \
  691. (_spi), \
  692. (_dest), \
  693. pHash)); \
  694. }
  695. //
  696. // Hashes <Src, Dest>
  697. //
  698. #define IPSEC_HASH_ADDR(_src, _dest,_phash) { \
  699. DWORD dwIndex; \
  700. dwIndex = (_src)+(_dest); \
  701. dwIndex %= g_ipsec.SpFilterHashSize; \
  702. pHash = &g_ipsec.pSpFilter[dwIndex]; \
  703. IPSEC_DEBUG_KD_ONLY( \
  704. DBF_EXTRADIAGNOSTIC, ("ADDR: Index: %lx for S: %lx, D: %lx, pHash: %lx", \
  705. dwIndex, \
  706. (_src), \
  707. (_dest), \
  708. pHash)); \
  709. }
  710. #define SRC_ADDR uliSrcDstAddr.LowPart
  711. #define DEST_ADDR uliSrcDstAddr.HighPart
  712. #define SRC_MASK uliSrcDstMask.LowPart
  713. #define DEST_MASK uliSrcDstMask.HighPart
  714. #define PROTO uliProtoSrcDstPort.LowPart
  715. #define SRC_PORT LOWORD(uliProtoSrcDstPort.HighPart)
  716. #define DEST_PORT HIWORD(uliProtoSrcDstPort.HighPart)
  717. #define FI_SRC_PORT(_filter) LOWORD((_filter)->uliProtoSrcDstPort.HighPart)
  718. #define FI_DEST_PORT(_filter) HIWORD((_filter)->uliProtoSrcDstPort.HighPart)
  719. #define SA_SRC_ADDR sa_uliSrcDstAddr.LowPart
  720. #define SA_DEST_ADDR sa_uliSrcDstAddr.HighPart
  721. #define SA_SRC_MASK sa_uliSrcDstMask.LowPart
  722. #define SA_DEST_MASK sa_uliSrcDstMask.HighPart
  723. #define SA_PROTO sa_uliProtoSrcDstPort.LowPart
  724. #define SA_SRC_PORT(_psa) LOWORD((_psa)->sa_uliProtoSrcDstPort.HighPart)
  725. #define SA_DEST_PORT(_psa) HIWORD((_psa)->sa_uliProtoSrcDstPort.HighPart)
  726. #define FILTER_PROTO(ProtoId) MAKELONG(MAKEWORD((ProtoId),0x00),0x00000)
  727. #define FILTER_PROTO_ANY FILTER_PROTO(0x00)
  728. #define FILTER_PROTO_ICMP FILTER_PROTO(0x01)
  729. #define FILTER_PROTO_TCP FILTER_PROTO(0x06)
  730. #define FILTER_PROTO_UDP FILTER_PROTO(0x11)
  731. #define FILTER_TCPUDP_PORT_ANY (WORD)0x0000
  732. #define FILTER_ICMP_TYPE_ANY (BYTE)0xff
  733. #define FILTER_ICMP_CODE_ANY (BYTE)0xff
  734. #define FILTER_MASK_ALL (DWORD)0xffffffff
  735. #define FILTER_MASK_NONE (DWORD)0x00000000
  736. //
  737. // macros to parse the ALGORITHM structure
  738. //
  739. #define INT_ALGO(_i) sa_Algorithm[_i].integrityAlgo.algoIdentifier
  740. #define INT_KEY(_i) sa_Algorithm[_i].integrityAlgo.algoKey
  741. #define INT_KEYLEN(_i) sa_Algorithm[_i].integrityAlgo.algoKeylen
  742. #define INT_ROUNDS(_i) sa_Algorithm[_i].integrityAlgo.algoRounds
  743. #define CONF_ALGO(_i) sa_Algorithm[_i].confAlgo.algoIdentifier
  744. #define CONF_KEY(_i) sa_Algorithm[_i].confAlgo.algoKey
  745. #define CONF_KEYLEN(_i) sa_Algorithm[_i].confAlgo.algoKeylen
  746. #define CONF_ROUNDS(_i) sa_Algorithm[_i].confAlgo.algoRounds
  747. #define COMP_ALGO(_i) sa_Algorithm[_i].compAlgo.algoIdentifier
  748. #define EXT_INT_ALGO IntegrityAlgo.algoIdentifier
  749. #define EXT_INT_KEY IntegrityAlgo.algoKey
  750. #define EXT_INT_KEYLEN IntegrityAlgo.algoKeylen
  751. #define EXT_INT_ROUNDS IntegrityAlgo.algoRounds
  752. #define EXT_CONF_ALGO ConfAlgo.algoIdentifier
  753. #define EXT_CONF_KEY ConfAlgo.algoKey
  754. #define EXT_CONF_KEYLEN ConfAlgo.algoKeylen
  755. #define EXT_CONF_ROUNDS ConfAlgo.algoRounds
  756. #define EXT_INT_ALGO_EX(_i) AlgoInfo[_i].IntegrityAlgo.algoIdentifier
  757. #define EXT_INT_KEYLEN_EX(_i) AlgoInfo[_i].IntegrityAlgo.algoKeylen
  758. #define EXT_INT_ROUNDS_EX(_i) AlgoInfo[_i].IntegrityAlgo.algoRounds
  759. #define EXT_CONF_ALGO_EX(_i) AlgoInfo[_i].ConfAlgo.algoIdentifier
  760. #define EXT_CONF_KEYLEN_EX(_i) AlgoInfo[_i].ConfAlgo.algoKeylen
  761. #define EXT_CONF_ROUNDS_EX(_i) AlgoInfo[_i].ConfAlgo.algoRounds
  762. #define IS_AH_SA(_psa) ((_psa)->sa_Operation[0] == Auth || \
  763. (_psa)->sa_Operation[1] == Auth || \
  764. (_psa)->sa_Operation[2] == Auth)
  765. #define IS_ESP_SA(_psa) ((_psa)->sa_Operation[0] == Encrypt || \
  766. (_psa)->sa_Operation[1] == Encrypt || \
  767. (_psa)->sa_Operation[2] == Encrypt)
  768. //
  769. // Increment/decrement statistics
  770. //
  771. #define IPSEC_INC_STATISTIC(_stat) \
  772. (g_ipsec.Statistics.##_stat)++;
  773. #define IPSEC_DEC_STATISTIC(_stat) \
  774. (g_ipsec.Statistics.##_stat)--;
  775. #define IPSEC_INC_TUNNELS(_pSA) { \
  776. if ((_pSA)->sa_Flags & FLAGS_SA_TUNNEL) \
  777. g_ipsec.Statistics.dwNumActiveTunnels++; \
  778. }
  779. #define IPSEC_DEC_TUNNELS(_pSA) { \
  780. if ((_pSA)->sa_Flags & FLAGS_SA_TUNNEL) \
  781. g_ipsec.Statistics.dwNumActiveTunnels--; \
  782. }
  783. //
  784. // Function to read a dword from registry and init the variable passed in.
  785. //
  786. __inline
  787. void IPSecRegReadDword(
  788. HANDLE hRegKey,
  789. PWCHAR param,
  790. PULONG var,
  791. ULONG def,
  792. ULONG max,
  793. ULONG min
  794. )
  795. {
  796. NTSTATUS status;
  797. status = GetRegDWORDValue(hRegKey,
  798. param,
  799. var);
  800. if (!NT_SUCCESS(status)) {
  801. *(var) = def;
  802. } else if (*(var) > max) {
  803. *(var) = max;
  804. } else if (*(var) <= min) {
  805. *(var) = min;
  806. }
  807. }
  808. //
  809. // Extended function with different default values for
  810. // different kind of registry errors.
  811. //
  812. __inline
  813. void IPSecRegReadDwordEx(
  814. HANDLE hRegKey,
  815. PWCHAR param,
  816. PULONG var,
  817. ULONG max,
  818. ULONG min,
  819. ULONG NoExist,
  820. ULONG ReadError,
  821. ULONG OutOfRange
  822. )
  823. {
  824. NTSTATUS status;
  825. status = GetRegDWORDValue(hRegKey,
  826. param,
  827. var);
  828. if (!NT_SUCCESS(status)){
  829. if (STATUS_OBJECT_NAME_NOT_FOUND == status){
  830. (*var) = NoExist;
  831. }
  832. else{
  833. (*var) = ReadError;
  834. }
  835. }
  836. else if (((*var)>max) || ((*var)<min)){
  837. (*var) = OutOfRange;
  838. }
  839. }
  840. //
  841. // Macro for computing incremental checksum (RFC 1624)
  842. //
  843. #define UpdateIPLength(_piph, _length) \
  844. { \
  845. ULONG _sum; \
  846. USHORT _old; \
  847. \
  848. _old = NET_SHORT((_piph)->iph_length); \
  849. (_piph)->iph_length = (_length); \
  850. _sum = (~NET_SHORT((_piph)->iph_xsum) & 0xffff) + \
  851. (~_old & 0xffff) + \
  852. NET_SHORT((_piph)->iph_length); \
  853. _sum = (_sum & 0xffff) + (_sum >> 16); \
  854. _sum += (_sum >> 16); \
  855. (_piph)->iph_xsum = NET_SHORT((USHORT)(~_sum & 0xffff)); \
  856. }
  857. #define UpdateIPProtocol(_piph, _proto) \
  858. { \
  859. ULONG _sum; \
  860. USHORT _old; \
  861. \
  862. _old = NET_SHORT(*(USHORT *)&(_piph)->iph_ttl); \
  863. (_piph)->iph_protocol = (_proto); \
  864. _sum = (~NET_SHORT((_piph)->iph_xsum) & 0xffff) + \
  865. (~_old & 0xffff) + \
  866. NET_SHORT(*(USHORT *)&(_piph)->iph_ttl); \
  867. _sum = (_sum & 0xffff) + (_sum >> 16); \
  868. _sum += (_sum >> 16); \
  869. (_piph)->iph_xsum = NET_SHORT((USHORT)(~_sum & 0xffff)); \
  870. }
  871. #define IPSecPrint4Long(_key) \
  872. DbgPrint("Key: %lx-%lx-%lx-%lx", \
  873. *(ULONG *)&(_key)[0], \
  874. *(ULONG *)&(_key)[4], \
  875. *(ULONG *)&(_key)[8], \
  876. *(ULONG *)&(_key)[12]);
  877. #define IPSEC_DELAY_INTERVAL ((LONGLONG)(-1 * 1000 * 1000)) // 1/10 sec.
  878. #define IPSEC_DELAY_EXECUTION() \
  879. { \
  880. IPSecDelayInterval.QuadPart = IPSEC_DELAY_INTERVAL; \
  881. KeDelayExecutionThread(UserMode, FALSE, &IPSecDelayInterval); \
  882. }
  883. #define IS_DRIVER_BLOCK() (g_ipsec.OperationMode == IPSEC_BLOCK_MODE)
  884. #define IS_DRIVER_BYPASS() (g_ipsec.OperationMode == IPSEC_BYPASS_MODE)
  885. #define IS_DRIVER_SECURE() (g_ipsec.OperationMode == IPSEC_SECURE_MODE)
  886. #define IS_DRIVER_BOOTSTATEFUL() (g_ipsec.OperationMode == IPSEC_BOOTTIME_STATEFUL_MODE)
  887. #define IS_DRIVER_FORWARD_BYPASS() (g_ipsec.DefaultForwardingBehavior == IPSEC_FORWARD_BYPASS)
  888. #define IS_DRIVER_FORWARD_BLOCK()(g_ipsec.DefaultForwardingBehavior == IPSEC_FORWARD_BLOCK)
  889. #define IS_DRIVER_DIAGNOSTIC() (g_ipsec.DiagnosticMode)
  890. #define LOG_EVENT NdisWriteEventLogEntry
  891. #define IPSEC_NULL_GUIDS "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  892. #define IPSEC_EQUAL_GUIDS(_A, _B) \
  893. ((*(UNALIGNED ULONG *)((PUCHAR)(_A)) == *(UNALIGNED ULONG *)((PUCHAR)(_B))) && \
  894. (*(UNALIGNED ULONG *)(((PUCHAR)(_A))+4) == *(UNALIGNED ULONG *)(((PUCHAR)(_B))+4)) && \
  895. (*(UNALIGNED ULONG *)(((PUCHAR)(_A))+8) == *(UNALIGNED ULONG *)(((PUCHAR)(_B))+8)) && \
  896. (*(UNALIGNED ULONG *)(((PUCHAR)(_A))+12) == *(UNALIGNED ULONG *)(((PUCHAR)(_B))+12)))
  897. //
  898. // Get the next non-zero length NDIS buffer.
  899. //
  900. __inline
  901. PNDIS_BUFFER
  902. FASTCALL
  903. IPSEC_NEXT_BUFFER(
  904. IN PNDIS_BUFFER pBuffer
  905. )
  906. {
  907. PVOID *pDummy = NULL;
  908. ULONG Length = 0;
  909. if (!pBuffer) {
  910. ASSERT(FALSE);
  911. return NULL;
  912. }
  913. pBuffer = NDIS_BUFFER_LINKAGE(pBuffer);
  914. while (pBuffer) {
  915. IPSecQueryNdisBuf(pBuffer, &pDummy, &Length);
  916. if (Length == 0) {
  917. pBuffer = NDIS_BUFFER_LINKAGE(pBuffer);
  918. continue;
  919. } else {
  920. return pBuffer;
  921. }
  922. }
  923. return NULL;
  924. }
  925. #define SA_CHAIN_WIDTH 4
  926. //
  927. // Count number of 1's in the IP mask
  928. //
  929. __inline
  930. LONG
  931. CountNumberOfOnes(
  932. IN IPMask IpMask
  933. )
  934. {
  935. INT i;
  936. LONG NumberOfOnes = 0;
  937. IPMask Mask = IpMask;
  938. for (i = 0; i < sizeof(IPMask) * 8; i++) {
  939. if ((Mask & 0x1) == 0x1) {
  940. NumberOfOnes++;
  941. }
  942. Mask = Mask >> 1;
  943. }
  944. return NumberOfOnes;
  945. }
  946. __inline
  947. PLIST_ENTRY
  948. FASTCALL
  949. IPSecResolveSAChain(
  950. IN PFILTER pFilter,
  951. IN IPAddr IpAddr
  952. )
  953. {
  954. PLIST_ENTRY pEntry;
  955. ULONG Index;
  956. if (IS_TUNNEL_FILTER(pFilter)) {
  957. pEntry = &pFilter->SAChain[0];
  958. } else {
  959. Index = NET_TO_HOST_LONG(IpAddr) % pFilter->SAChainSize;
  960. pEntry = &pFilter->SAChain[Index];
  961. }
  962. return pEntry;
  963. }
  964. // This function should only be called
  965. // when holding SABDlock
  966. __inline
  967. PIPSEC_STATEFUL_ENTRY
  968. IPSecAllocateFromHashPool(
  969. VOID
  970. )
  971. {
  972. PIPSEC_STATEFUL_ENTRY pMem;
  973. int index;
  974. BOOL fReuse=FALSE;
  975. //Get index of buffer to use
  976. //
  977. index =
  978. g_ipsec.BootBufferPool->ulCurrentPosition;
  979. //Update index
  980. //
  981. if (TOTAL_STATEFUL_ENTRY_COUNT ==
  982. (++g_ipsec.BootBufferPool->ulCurrentPosition)){
  983. g_ipsec.BootBufferPool->ulCurrentPosition = 0;
  984. }
  985. //if used up all locations then recycle
  986. //
  987. if (g_ipsec.BootBufferPool->ulEntriesUsed < TOTAL_STATEFUL_ENTRY_COUNT){
  988. g_ipsec.BootBufferPool->ulEntriesUsed++;
  989. }
  990. else
  991. {
  992. //Reuse this connection. Remove it from it's location in the Hash Table
  993. //This can result in dropped packets
  994. //
  995. IPSecRemoveEntryList(&(g_ipsec.BootBufferPool->PoolEntry[index].CollisionLinkage));
  996. }
  997. //Return the buffer selected at location index
  998. //
  999. return (&(g_ipsec.BootBufferPool->PoolEntry[index]));
  1000. }
  1001. #if GPC
  1002. #define IPSEC_GPC_MASK_ALL (0xff)
  1003. #define IPSEC_GPC_MASK_NONE (0x0)
  1004. #define GPC_REGISTER_CLIENT g_ipsec.GpcEntries.GpcRegisterClientHandler
  1005. #define GPC_DEREGISTER_CLIENT g_ipsec.GpcEntries.GpcDeregisterClientHandler
  1006. #define GPC_ADD_CFINFO g_ipsec.GpcEntries.GpcAddCfInfoHandler
  1007. #define GPC_REMOVE_CFINFO g_ipsec.GpcEntries.GpcRemoveCfInfoHandler
  1008. #define GPC_ADD_PATTERN g_ipsec.GpcEntries.GpcAddPatternHandler
  1009. #define GPC_REMOVE_PATTERN g_ipsec.GpcEntries.GpcRemovePatternHandler
  1010. #define GPC_CLASSIFY_PATTERN g_ipsec.GpcEntries.GpcClassifyPatternHandler
  1011. #define GPC_GET_CLIENT_CONTEXT g_ipsec.GpcEntries.GpcGetCfInfoClientContextHandler
  1012. #define IPSEC_GPC_ACTIVE (0x12345678)
  1013. #define IPSEC_NUM_GPC_FILTERS() (g_ipsec.NumMaskedFilters)
  1014. #define IS_GPC_ACTIVE() (g_ipsec.GpcActive == IPSEC_GPC_ACTIVE)
  1015. #define IPSEC_SET_GPC_ACTIVE() \
  1016. { \
  1017. g_ipsec.GpcActive = IPSEC_GPC_ACTIVE; \
  1018. }
  1019. #define IPSEC_UNSET_GPC_ACTIVE() \
  1020. { \
  1021. g_ipsec.GpcActive = 0; \
  1022. }
  1023. __inline
  1024. INT
  1025. FASTCALL
  1026. IPSecResolveGpcCf(
  1027. IN BOOLEAN fOutbound
  1028. )
  1029. {
  1030. return fOutbound? GPC_CF_IPSEC_OUT: GPC_CF_IPSEC_IN;
  1031. }
  1032. __inline
  1033. PLIST_ENTRY
  1034. FASTCALL
  1035. IPSecResolveGpcFilterList(
  1036. IN BOOLEAN fTunnel,
  1037. IN BOOLEAN fOutbound
  1038. )
  1039. {
  1040. PLIST_ENTRY pEntry;
  1041. if (fTunnel) {
  1042. if (fOutbound) {
  1043. pEntry = &g_ipsec.GpcFilterList[OUTBOUND_TUNNEL_FILTER];
  1044. } else {
  1045. pEntry = &g_ipsec.GpcFilterList[INBOUND_TUNNEL_FILTER];
  1046. }
  1047. } else {
  1048. if (fOutbound) {
  1049. pEntry = &g_ipsec.GpcFilterList[OUTBOUND_TRANSPORT_FILTER];
  1050. } else {
  1051. pEntry = &g_ipsec.GpcFilterList[INBOUND_TRANSPORT_FILTER];
  1052. }
  1053. }
  1054. return pEntry;
  1055. }
  1056. __inline
  1057. VOID
  1058. IPSEC_CLASSIFY_PACKET(
  1059. IN INT GpcCf,
  1060. IN ULARGE_INTEGER uliSrcDstAddr,
  1061. IN ULARGE_INTEGER uliProtoSrcDstPort,
  1062. OUT PFILTER *ppFilter,
  1063. OUT PCLASSIFICATION_HANDLE pGpcHandle
  1064. )
  1065. {
  1066. GPC_IP_PATTERN Pattern;
  1067. *ppFilter = NULL;
  1068. *pGpcHandle = 0;
  1069. Pattern.SrcAddr = SRC_ADDR;
  1070. Pattern.DstAddr = DEST_ADDR;
  1071. Pattern.ProtocolId = (UCHAR)PROTO;
  1072. if (PROTO == PROTOCOL_TCP || PROTO == PROTOCOL_UDP) {
  1073. Pattern.gpcSrcPort = SRC_PORT;
  1074. Pattern.gpcDstPort = DEST_PORT;
  1075. } else {
  1076. Pattern.gpcSrcPort = 0;
  1077. Pattern.gpcDstPort = 0;
  1078. }
  1079. Pattern.InterfaceId.InterfaceId = 0;
  1080. Pattern.InterfaceId.LinkId = 0;
  1081. GPC_CLASSIFY_PATTERN( g_ipsec.GpcClients[GpcCf],
  1082. GPC_PROTOCOL_TEMPLATE_IP,
  1083. &Pattern,
  1084. ppFilter,
  1085. pGpcHandle,
  1086. 0,
  1087. NULL,
  1088. TRUE);
  1089. }
  1090. #define IS_GPC_FILTER(f) (g_ipsec.InitGpc && \
  1091. f->SRC_MASK == FILTER_MASK_ALL && \
  1092. f->DEST_MASK == FILTER_MASK_ALL)
  1093. #endif
  1094. #if FIPS
  1095. #define IPSEC_DES_ALGO FIPS_CBC_DES
  1096. #define IPSEC_3DES_ALGO FIPS_CBC_3DES
  1097. #define IPSEC_SHA_INIT g_ipsec.FipsFunctionTable.FipsSHAInit
  1098. #define IPSEC_SHA_UPDATE g_ipsec.FipsFunctionTable.FipsSHAUpdate
  1099. #define IPSEC_SHA_FINAL g_ipsec.FipsFunctionTable.FipsSHAFinal
  1100. #define IPSEC_DES_KEY g_ipsec.FipsFunctionTable.FipsDesKey
  1101. #define IPSEC_3DES_KEY g_ipsec.FipsFunctionTable.Fips3Des3Key
  1102. #define IPSEC_CBC g_ipsec.FipsFunctionTable.FipsCBC
  1103. #define IPSEC_GEN_RANDOM g_ipsec.FipsFunctionTable.FIPSGenRandom
  1104. #define IPSEC_HMAC_SHA_INIT g_ipsec.FipsFunctionTable.FipsHmacSHAInit
  1105. #define IPSEC_HMAC_SHA_UPDATE g_ipsec.FipsFunctionTable.FipsHmacSHAUpdate
  1106. #define IPSEC_HMAC_SHA_FINAL g_ipsec.FipsFunctionTable.FipsHmacSHAFinal
  1107. #define IPSEC_HMAC_MD5_INIT g_ipsec.FipsFunctionTable.HmacMD5Init
  1108. #define IPSEC_HMAC_MD5_UPDATE g_ipsec.FipsFunctionTable.HmacMD5Update
  1109. #define IPSEC_HMAC_MD5_FINAL g_ipsec.FipsFunctionTable.HmacMD5Final
  1110. #else
  1111. #define IPSEC_DES_ALGO des
  1112. #define IPSEC_3DES_ALGO tripledes
  1113. #define IPSEC_SHA_INIT A_SHAInit
  1114. #define IPSEC_SHA_UPDATE A_SHAUpdate
  1115. #define IPSEC_SHA_FINAL A_SHAFinal
  1116. #define IPSEC_DES_KEY deskey
  1117. #define IPSEC_3DES_KEY tripledes3key
  1118. #define IPSEC_CBC(_EncryptionAlgo, _pOut, _pIn, _pKeyTable, _Operation, _pFeedback) \
  1119. CBC(_EncryptionAlgo, \
  1120. DES_BLOCKLEN, \
  1121. _pOut, \
  1122. _pIn, \
  1123. _pKeyTable, \
  1124. _Operation, \
  1125. _pFeedback)
  1126. #define IPSEC_GEN_RANDOM(_pBuf, _KeySize) NewGenRandom(NULL, NULL, _pBuf, _KeySize)
  1127. #endif
  1128. #define IPSEC_MD5_INIT MD5Init
  1129. #define IPSEC_MD5_UPDATE MD5Update
  1130. #define IPSEC_MD5_FINAL MD5Final
  1131. #define IPSEC_RC4_KEY rc4_key
  1132. #define IPSEC_RC4 rc4
  1133. #define IS_CLASS_D_ADDR(x) (((x) & 0x000000f0) == 0x000000e0)
  1134. #define TCPIP_FREE_BUFF g_ipsec.TcpipFreeBuff
  1135. #define TCPIP_ALLOC_BUFF g_ipsec.TcpipAllocBuff
  1136. #define TCPIP_GET_ADDRTYPE g_ipsec.TcpipGetAddrType
  1137. #define TCPIP_GET_INFO g_ipsec.TcpipGetInfo
  1138. #define TCPIP_NDIS_REQUEST g_ipsec.TcpipNdisRequest
  1139. #define TCPIP_REGISTER_PROTOCOL g_ipsec.TcpipRegisterProtocol
  1140. #define TCPIP_SET_IPSEC_STATUS g_ipsec.TcpipSetIPSecStatus
  1141. #define TCPIP_IP_TRANSMIT g_ipsec.TcpipIPTransmit
  1142. #define TCPIP_SET_IPSEC g_ipsec.TcpipSetIPSecPtr
  1143. #define TCPIP_UNSET_IPSEC g_ipsec.TcpipUnSetIPSecPtr
  1144. #define TCPIP_UNSET_IPSEC_SEND g_ipsec.TcpipUnSetIPSecSendPtr
  1145. #define TCPIP_TCP_XSUM g_ipsec.TcpipTCPXsum
  1146. #define TCPIP_GEN_IPID g_ipsec.TcpipGenIpId
  1147. #define TCPIP_DEREGISTER_PROTOCOL g_ipsec.TcpipDeRegisterProtocol
  1148. #define TCPIP_GET_PINFO g_ipsec.TcpipGetPInfo
  1149. #define TCPIP_SEND_ICMP_ERR g_ipsec.TcpipSendICMPErr
  1150. #ifdef xsum
  1151. #undef xsum
  1152. #define xsum(Buffer, Length) ((USHORT)TCPIP_TCP_XSUM(0, (PUCHAR)(Buffer), (Length)))
  1153. #endif
  1154. #define SAFETY_LEN (TRUNCATED_HASH_LEN+MAX_PAD_LEN)
  1155. //
  1156. // Compares the src/dest ports out of a word with the number input
  1157. //
  1158. #define IPSEC_COMPARE_SD_PORT(_pport, _port) \
  1159. ( ((_pport)[0] == (_port)) || \
  1160. ((_pport)[1] == (_port)))
  1161. #define IPSEC_COMPARE_D_PORT(_pport, _port) ((_pport)[1] == (_port))
  1162. //
  1163. // Bypass traffic logic for IKE, Kerberos and RSVP
  1164. //
  1165. #define IPSEC_KERBEROS_TRAFFIC() \
  1166. ((pIPHeader->iph_protocol == PROTOCOL_UDP || \
  1167. pIPHeader->iph_protocol == PROTOCOL_TCP) && \
  1168. IPSEC_COMPARE_SD_PORT(pwPort, IPSEC_KERBEROS_PORT))
  1169. #define IPSEC_ISAKMP_TRAFFIC() \
  1170. (pIPHeader->iph_protocol == PROTOCOL_UDP && \
  1171. IPSEC_COMPARE_D_PORT(pwPort, IPSEC_ISAKMP_PORT)) \
  1172. #define IPSEC_ISAKMP_TRAFFIC2() \
  1173. (pIPHeader->iph_protocol == PROTOCOL_UDP && \
  1174. IPSEC_COMPARE_D_PORT(pwPort, IPSEC_ISAKMP_PORT2)) \
  1175. #define IPSEC_RSVP_TRAFFIC() \
  1176. (pIPHeader->iph_protocol == PROTOCOL_RSVP)
  1177. #define IPSEC_NO_UNICAST_EXEMPT 0x00000001
  1178. #define IPSEC_NO_MANDBCAST_EXEMPT 0x00000002
  1179. #define IPSEC_NO_DEFAULT_EXEMPT() (g_ipsec.NoDefaultExempt & IPSEC_NO_UNICAST_EXEMPT)
  1180. #define IPSEC_HANDLE_MANDBCAST() (g_ipsec.NoDefaultExempt & IPSEC_NO_MANDBCAST_EXEMPT)
  1181. #define IPSEC_MANDBCAST_PROCESS() (IPSEC_GET_VALUE(g_ipsec.NumMulticastFilters) || \
  1182. IPSEC_HANDLE_MANDBCAST())
  1183. #define IPSEC_BYPASS_TRAFFIC() \
  1184. (IPSEC_ISAKMP_TRAFFIC() || IPSEC_ISAKMP_TRAFFIC2() || \
  1185. (!IPSEC_NO_DEFAULT_EXEMPT() && \
  1186. (IPSEC_KERBEROS_TRAFFIC() || \
  1187. IPSEC_RSVP_TRAFFIC())))
  1188. //
  1189. // Forwarding path is either reinject a detunneled forward packet or route
  1190. //
  1191. #define IPSEC_FORWARD_PATH() (fFWPacket || (fOutbound && TCPIP_GET_ADDRTYPE(pIPHeader->iph_src) != DEST_LOCAL))
  1192. #define EQUAL_NATENCAP(_pNatContext,_pSA) ((_pNatContext == NULL) || (_pNatContext && (_pSA->sa_EncapContext.wSrcEncapPort == _pNatContext->wSrcEncapPort && _pSA->sa_EncapContext.wDesEncapPort == _pNatContext->wDesEncapPort)))
  1193. /*++
  1194. Routine Description:
  1195. Fills in the DELETE_SA hw request from pSA
  1196. Arguments:
  1197. pSA - the SA
  1198. Buf - buffer to set info
  1199. Len - length
  1200. Return Value:
  1201. status of the operation
  1202. --*/
  1203. #define IPSecFillHwDelSA(_pSA, _Buf, _Len) \
  1204. ((POFFLOAD_IPSEC_DELETE_SA)(_Buf))->OffloadHandle = (_pSA)->sa_OffloadHandle;
  1205. #endif _MACROS_H