|
|
/*++
Copyright (c) 1997-2001 Microsoft Corporation
Module Name:
macros.h
Abstract:
Contains all the macros.
Author:
Sanjay Anand (SanjayAn) 2-January-1997 ChunYe
Environment:
Kernel mode
Revision History:
--*/
#ifndef _MACROS_H
#define _MACROS_H
#define REGISTER register
#define EXTENDED_MULTIPLY RtlExtendedIntegerMultiply
#ifndef MAX
#define MAX(x,y) ((x) < (y)) ? (y) : (x)
#endif
#ifndef MIN
#define MIN(x,y) ((x) < (y)) ? (x) : (y)
#endif
#define MAX_IP_DATA_LENGTH ((USHORT)0xfffff)
#define MAX_AH_OUTPUT_LEN MAX(MD5DIGESTLEN, A_SHA_DIGEST_LEN)
//
// This macro adds a ULONG to a LARGE_INTEGER.
//
#define ADD_TO_LARGE_INTEGER(_LargeInteger,_Ulong) \
ExInterlockedAddLargeStatistic((PLARGE_INTEGER)(_LargeInteger),(ULONG)(_Ulong))
#define IPSecEqualMemory(_p1, _p2, _len) RtlEqualMemory(_p1, _p2, _len)
#define IPSecMoveMemory(_p1, _p2, _len) RtlMoveMemory(_p1, _p2, _len)
#define IPSecZeroMemory(_p1, _len) RtlZeroMemory(_p1, _len)
//
// Truncates _src to _numbytes and copies into _dest
// then zeroes out the rest in _dest
//
#define TRUNCATE(_dest, _src, _numbytes, _destlen) { \
IPSecZeroMemory ( _dest+_numbytes, _destlen - _numbytes); \ }
//
// Some macros
//
#ifdef NET_SHORT
#undef NET_SHORT
#endif
__inline USHORT FASTCALL NET_SHORT(USHORT x) { #if (defined(_M_IX86) && (_MSC_FULL_VER > 13009037)) || ((defined(_M_AMD64) || defined(_M_IA64)) && (_MSC_FULL_VER > 13009175))
return _byteswap_ushort(x); #else
ASSERT(x <= 0xffff);
return (x << 8) | (x >> 8); #endif
}
#define NET_TO_HOST_SHORT(Val) NET_SHORT(Val)
#define HOST_TO_NET_SHORT(Val) NET_SHORT(Val)
#ifdef NET_LONG
#undef NET_LONG
#endif
__inline ULONG FASTCALL NET_LONG(ULONG x) { #if (defined(_M_IX86) && (_MSC_FULL_VER > 13009037)) || ((defined(_M_AMD64) || defined(_M_IA64)) && (_MSC_FULL_VER > 13009175))
return _byteswap_ulong(x); #else
REGISTER ULONG BytesSwapped;
BytesSwapped = ((x & 0x00ff00ff) << 8) | ((x & 0xff00ff00) >> 8); return (BytesSwapped << 16) | (BytesSwapped >> 16); #endif
}
#define NET_TO_HOST_LONG(Val) NET_LONG(Val)
#define HOST_TO_NET_LONG(Val) NET_LONG(Val)
#define IPSEC_100NS_FACTOR 10000000
#define IPSEC_CONVERT_SECS_TO_100NS(_li, _delta) { \
(_li).LowPart = _delta; \ (_li) = EXTENDED_MULTIPLY(_li, IPSEC_100NS_FACTOR); \ }
#define IS_CLASSD(i) (((long)(i) & 0xf0000000) == 0xe0000000)
//
// Check SA against Lifetime information - we try to anticipate in advance if the
// SA is going to expire and start off a re-key so that when it actually does expire,
// we have the new SA setup.
//
//
// IPSEC_EXPIRE_TIME_PAD is the time before expiration when we start re-keying
//
#define IPSEC_EXPIRE_TIME_PAD_I (75 * IPSEC_100NS_FACTOR)
#define IPSEC_EXPIRE_TIME_PAD_R (40 * IPSEC_100NS_FACTOR)
#define IPSEC_EXPIRE_TIME_PAD_OAKLEY (1 * IPSEC_100NS_FACTOR)
//
// IPSEC_INBOUND_KEEPALIVE_TIME is the time an expired inboundSA will be kept
// alive in the driver
//
#define IPSEC_INBOUND_KEEPALIVE_TIME (60)
//
// IPSEC_MAX_EXPIRE_TIME is the maximum phase-2 lifetime allowed in driver
//
#define IPSEC_MAX_EXPIRE_TIME (48 * 3600 - 1)
//
// IPSEC_MIN_EXPIRE_TIME is the minimum phase-2 lifetime allowed in driver
//
#define IPSEC_MIN_EXPIRE_TIME (60)
#define IPSEC_EXPIRE_THRESHOLD_I (50)
#define IPSEC_EXPIRE_THRESHOLD_R (75)
//
// skew the initiator and responder with Pads
//
#define IPSEC_DEFAULT_SA_IDLE_TIME_PAD_I 0
#define IPSEC_DEFAULT_SA_IDLE_TIME_PAD_R 30
#define IPSEC_NLBS_IDLE_TIME 60
//
// The # of packets before which we start reneg. because of replay rollover
// 1M bytes / 1500 packets
//
#define IPSEC_EXPIRE_REPLAY_MASK (0x80000000)
#define MAX_ULONG ((ULONG) -1)
#define MAX_LONG (0x7fffffff)
//
// Some constants used for POST_EXPIRE_NOTIFY
//
#define IPSEC_INVALID_SPI 0
#define IPSEC_INVALID_ADDR (-1)
//
// Check the lifetime (kbytes and seconds) and replay rollover.
// FALSE => expired
//
#define IPSEC_CHECK_PADDED_LIFETIME(__pSA, _status, _index) { \
LARGE_INTEGER __curtime; \ (_status) = TRUE; \ if (((__pSA)->sa_ReplaySendSeq[0] & \ IPSEC_EXPIRE_REPLAY_MASK) && \ ((__pSA)->sa_Flags & FLAGS_SA_OUTBOUND)) { \ _status = FALSE; \ } else { \ KeQuerySystemTime(&__curtime); \ if (((__pSA)->sa_KeyExpirationTimeWithPad.QuadPart > 0i64) && \ ((__pSA)->sa_KeyExpirationTimeWithPad.QuadPart < __curtime.QuadPart)) {\ _status = FALSE; \ } else if (((__pSA)->sa_KeyExpirationBytesWithPad.QuadPart > 0i64) && \ ((__pSA)->sa_KeyExpirationBytesWithPad.QuadPart < (__pSA)->sa_TotalBytesTransformed.QuadPart)) { \ _status = FALSE; \ } \ } \ }
#define IPSEC_CHECK_LIFETIME(__pSA, _status, _index) { \
LARGE_INTEGER __curtime; \ (_status) = TRUE; \ if ((__pSA)->sa_ReplaySendSeq[_index] == MAX_ULONG) { \ _status = FALSE; \ } else { \ KeQuerySystemTime(&__curtime); \ if (((__pSA)->sa_KeyExpirationTime.QuadPart > 0i64) && \ ((__pSA)->sa_KeyExpirationTime.QuadPart < __curtime.QuadPart)) { \ _status = FALSE; \ } else if (((__pSA)->sa_KeyExpirationBytes.QuadPart > 0i64) && \ ((__pSA)->sa_KeyExpirationBytes.QuadPart < (__pSA)->sa_TotalBytesTransformed.QuadPart)) { \ _status = FALSE; \ } \ } \ }
#define IPSEC_SA_EXPIRED(__pSA, __fexpired) { \
LARGE_INTEGER __curtime; \ KeQuerySystemTime(&__curtime); \ (__fexpired) = FALSE; \ __curtime.QuadPart -= pSA->sa_LastUsedTime.QuadPart;\ if (__pSA->sa_IdleTime.QuadPart < __curtime.QuadPart) { \ __fexpired = TRUE; \ } \ }
//
// Max tolerated collisions when trying to allocate SPIs.
//
#define MAX_SPI_RETRIES 50
#define IPSEC_SPI_TO_ENTRY(_spi, _entry, _dst) { \
KIRQL kIrql; \ AcquireReadLock(&g_ipsec.SPIListLock, &kIrql); \ *(_entry) = IPSecLookupSABySPIWithLock(_spi, _dst); \ if (*(_entry)) { \ IPSecRefSA((*(_entry))); \ } \ ReleaseReadLock(&g_ipsec.SPIListLock, kIrql); \ }
//
// Generic memory allocators
//
#define IPSecAllocatePktInfo(__tag) \
IPSecAllocateMemory(sizeof(NDIS_IPSEC_PACKET_INFO), __tag)
#define IPSecFreePktInfo(__p) \
IPSecFreeMemory(__p)
#define IPSecAllocatePktExt(__tag) \
IPSecAllocateMemory(sizeof(NDIS_IPSEC_PACKET_INFO), __tag)
#define IPSecFreePktExt(__p) \
IPSecFreeMemory(__p)
#define IPSecAllocateBuffer(_ntstatus, _ppBuf, _ppData, _size, _tag) { \
PIPSEC_LA_BUFFER __labuf; \ *(_ntstatus) = STATUS_SUCCESS; \ __labuf = IPSecGetBuffer(_size, _tag); \ if (__labuf) { \ if (ARGUMENT_PRESENT(_ppData)) { \ *(PVOID *)(_ppData) = __labuf->Buffer; \ } \ *(_ppBuf) = __labuf->Mdl; \ NdisAdjustBufferLength(__labuf->Mdl, _size); \ NDIS_BUFFER_LINKAGE(__labuf->Mdl) = NULL; \ } else { \ *(_ntstatus) = STATUS_INSUFFICIENT_RESOURCES; \ } \ }
#define IPSecFreeBuffer(_ntstatus, _pBuf) { \
PIPSEC_LA_BUFFER __buffer; \ *(_ntstatus) = STATUS_SUCCESS; \ __buffer = CONTAINING_RECORD((_pBuf), IPSEC_LA_BUFFER, Data); \ IPSecReturnBuffer(__buffer); \ }
#define IPSecAllocateSendCompleteCtx(__tag) \
ExAllocateFromNPagedLookasideList(&g_ipsec.IPSecLookasideLists->SendCompleteCtxList)
#define IPSecFreeSendCompleteCtx(_buffer) \
ExFreeToNPagedLookasideList(&g_ipsec.IPSecLookasideLists->SendCompleteCtxList, _buffer); \ IPSEC_DECREMENT(g_ipsec.NumSends);
#define IPSEC_GET_TOTAL_LEN(_pbuf, _plen) { \
PNDIS_BUFFER _ptemp = (PNDIS_BUFFER)(_pbuf); \ *(_plen) = 0; \ while (_ptemp) { \ *(_plen) += _ptemp->ByteCount; \ _ptemp = NDIS_BUFFER_LINKAGE(_ptemp); \ } \ }
#define IPSEC_GET_TOTAL_LEN_RCV_BUF(_pbuf, _plen) { \
IPRcvBuf *_ptemp = (_pbuf); \ *(_plen) = 0; \ while (_ptemp) { \ *(_plen) += _ptemp->ipr_size; \ _ptemp = IPSEC_BUFFER_LINKAGE(_ptemp); \ } \ }
//
// Copy len bytes from RcvBuf chain to mdl (only one MDL)
//
#define IPSEC_COPY_FROM_RCVBUF(_pMdl, _pRcvBuf, _len, _offset) { \
IPRcvBuf *__pBuf=(_pRcvBuf); \ PMDL __pMdl=(_pMdl); \ ULONG __srclen; \ ULONG __destlen; \ ULONG __totallen=0; \ PUCHAR __pSrc; \ PUCHAR __pDest; \ ULONG __curroffset = (_offset); \ IPSecQueryNdisBuf(__pMdl, &__pDest, &__destlen); \ while (__pBuf) { \ IPSecQueryRcvBuf(__pBuf, &__pSrc, &__srclen); \ if (__srclen > __curroffset) { \ RtlCopyMemory(__pDest, __pSrc+__curroffset, __srclen-__curroffset); \ __pDest += (__srclen - __curroffset); \ __totallen += (__srclen - __curroffset); \ } \ __curroffset = 0; \ __pBuf = IPSEC_BUFFER_LINKAGE(__pBuf); \ } \ ASSERT(__totallen == __destlen); \ }
//
// Copy len bytes from Ndis Buffer chain to mdl (only one MDL)
//
#define IPSEC_COPY_FROM_NDISBUF(_pMdl, _pRcvBuf, _len, _offset) { \
NDIS_BUFFER *__pBuf=(_pRcvBuf); \ PMDL __pMdl=(_pMdl); \ ULONG __srclen; \ ULONG __destlen; \ ULONG __totallen=0; \ PUCHAR __pSrc; \ PUCHAR __pDest; \ ULONG __curroffset = (_offset); \ IPSecQueryNdisBuf(__pMdl, &__pDest, &__destlen); \ while (__pBuf) { \ IPSecQueryNdisBuf(__pBuf, &__pSrc, &__srclen); \ if (__srclen > __curroffset) { \ RtlCopyMemory(__pDest, __pSrc+__curroffset, __srclen-__curroffset); \ __pDest += (__srclen - __curroffset); \ __totallen += (__srclen - __curroffset); \ } \ __curroffset = 0; \ __pBuf = NDIS_BUFFER_LINKAGE(__pBuf); \ } \ ASSERT(__totallen == __destlen); \ }
#define IPSecAllocateMemory(_size, _tag) \
ExAllocatePoolWithTag (NonPagedPool, _size, _tag)
#define IPSecAllocateMemoryLowPriority(_size, _tag) \
ExAllocatePoolWithTagPriority (NonPagedPool, _size, _tag, LowPoolPriority)
#define IPSecFreeMemory(_addr) ExFreePool (_addr)
#define IPSecQueryNdisBuf(_Buffer, _VirtualAddress, _Length) \
{ \ PNDIS_BUFFER __Mdl = (PNDIS_BUFFER) (_Buffer); \ if (ARGUMENT_PRESENT(_VirtualAddress)) { \ *(PVOID *)(_VirtualAddress) = (__Mdl)->MappedSystemVa; \ } \ *(_Length) = (__Mdl)->ByteCount; \ }
#define IPSecQueryRcvBuf(_Buffer, _VirtualAddress, _Length) \
{ \ IPRcvBuf *__buf = (IPRcvBuf *) (_Buffer); \ if (ARGUMENT_PRESENT(_VirtualAddress)) { \ *(PVOID *)(_VirtualAddress) = (__buf)->ipr_buffer; \ } \ *(_Length) = (__buf)->ipr_size; \ }
#define IPSEC_ADJUST_BUFFER_LEN(_pBuf, _len) \
((IPRcvBuf *)(_pBuf))->ipr_size = (_len)
#define IPSEC_ADJUST_BUFFER(_pBuf, _offset) \
((IPRcvBuf *)(_pBuf))->ipr_buffer += (_offset)
#define IPSEC_ADJUST_BUFFER_NEG(_pBuf, _offset) \
((IPRcvBuf *)(_pBuf))->ipr_buffer -= (_offset)
#define IPSEC_ADJUST_BUFFER_RCVOFFSET(_pBuf, _offset) \
((IPRcvBuf *)(_pBuf))->ipr_RcvOffset += (_offset)
#define IPSEC_BUFFER_LINKAGE(_pBuf) \
((IPRcvBuf *)(_pBuf))->ipr_next
#define IPSEC_BUFFER_LEN(_pBuf) \
((IPRcvBuf *)(_pBuf))->ipr_size
#define IPSEC_BUFFER_OWNER(_pBuf) \
(((IPRcvBuf *)(_pBuf))->ipr_owner)
#define IPSEC_SET_OFFSET_IN_BUFFER(_pBuf, _offset) { \
PUCHAR _p; \ LONG _len; \ IPSecQueryRcvBuf((_pBuf), &(_p), &(_len)); \ if ((_offset) > 0 && (_offset) < (_len)) { \ if (IPSEC_BUFFER_OWNER(_pBuf) == IPR_OWNER_FIREWALL) { \ IPSecMoveMemory((_p), (_p) + (_offset), (_len) - (_offset));\ } else { \ IPSEC_ADJUST_BUFFER((_pBuf), (_offset)); \ IPSEC_ADJUST_BUFFER_RCVOFFSET((_pBuf), (_offset)); \ } \ IPSEC_ADJUST_BUFFER_LEN((_pBuf), (_len) - (_offset)); \ } else { \ ASSERT(FALSE); \ return STATUS_INVALID_PARAMETER; \ } \ }
#define IPSEC_ADD_VALUE(_val, _inc) InterlockedExchangeAdd((PULONG)&(_val), _inc)
#define IPSEC_INCREMENT(_val) InterlockedIncrement(&(_val))
#define IPSEC_DECREMENT(_val) InterlockedDecrement(&(_val))
#define IPSEC_GET_VALUE(_val) InterlockedExchangeAdd((PULONG)&(_val), 0)
#define IPSEC_SET_VALUE(_target, _val) \
InterlockedExchange((PULONG)&(_target), _val)
#define IPSEC_DRIVER_IS_EMPTY() (g_ipsec.NumPolicies == 0)
#define IPSEC_DRIVER_IS_INACTIVE() (g_ipsec.DriverUnloading || !g_ipsec.InitTcpip)
#define IPSEC_DRIVER_UNLOADING() (g_ipsec.DriverUnloading)
#define IPSEC_DRIVER_BOUND() (g_ipsec.BoundToIP)
#define IPSEC_DRIVER_SEND_BOUND() (g_ipsec.SendBoundToIP)
#define IPSEC_DRIVER_INIT_CRYPTO() (g_ipsec.InitCrypto)
#define IPSEC_DRIVER_INIT_RNG() (g_ipsec.InitRNG)
#define IPSEC_DRIVER_INIT_TCPIP() (g_ipsec.InitTcpip)
#if FIPS
#define IPSEC_DRIVER_INIT_FIPS() (g_ipsec.InitFips)
#endif
#if GPC
#define IPSEC_DRIVER_INIT_GPC() (g_ipsec.InitGpc)
#endif
#if DBG
#define IPSecRemoveEntryList(_x) \
{ \ RemoveEntryList(_x); \ (_x)->Flink = (_x)->Blink = (PLIST_ENTRY)__LINE__; \ } #else
#define IPSecRemoveEntryList(_x) RemoveEntryList(_x)
#endif
//
// macros for filter list management
//
#define IS_TRANSPORT_FILTER(f) (!(f)->TunnelFilter)
#define IS_TUNNEL_FILTER(f) ((f)->TunnelFilter)
#define IS_INBOUND_FILTER(f) ((f)->Flags & FILTER_FLAGS_INBOUND)
#define IS_OUTBOUND_FILTER(f) ((f)->Flags & FILTER_FLAGS_OUTBOUND)
#define IS_EXEMPT_FILTER(f) (((f)->Flags & FILTER_FLAGS_DROP) || ((f)->Flags & FILTER_FLAGS_PASS_THRU))
#define IS_MULTICAST_FILTER(f) (IS_CLASSD(NET_LONG((f)->SRC_ADDR)) || \
IS_CLASSD(NET_LONG((f)->DEST_ADDR)))
__inline PLIST_ENTRY IPSecResolveFilterList( IN BOOLEAN fTunnel, IN BOOLEAN fOutbound ) { PLIST_ENTRY pEntry;
if (fTunnel) { if (fOutbound) { pEntry = &g_ipsec.FilterList[OUTBOUND_TUNNEL_FILTER]; } else { pEntry = &g_ipsec.FilterList[INBOUND_TUNNEL_FILTER]; } } else { if (fOutbound) { pEntry = &g_ipsec.FilterList[OUTBOUND_TRANSPORT_FILTER]; } else { pEntry = &g_ipsec.FilterList[INBOUND_TRANSPORT_FILTER]; } }
return pEntry; }
//
// Filter/SA Cache Table
//
#define CacheMatch(uliAddr, uliPort, pInCache) \
((uliAddr).QuadPart == pInCache->uliSrcDstAddr.QuadPart) && \ ((uliPort).QuadPart == pInCache->uliProtoSrcDstPort.QuadPart)
#define IS_VALID_CACHE_ENTRY(_entry) ((_entry)->pFilter != NULL)
#define INVALIDATE_CACHE_ENTRY(_entry) \
{ \ ((PFILTER_CACHE)(_entry))->pSAEntry = NULL; \ ((PFILTER_CACHE)(_entry))->pNextSAEntry = NULL; \ } \
__inline ULONG FASTCALL CalcCacheIndex( IN IPAddr SrcAddr, IN IPAddr DestAddr, IN UCHAR Protocol, IN USHORT SrcPort, IN USHORT DestPort, IN BOOLEAN fOutbound ) { REGISTER ULONG dwIndex; REGISTER ULONG Address; REGISTER USHORT Port;
Address = SrcAddr ^ DestAddr; Port = SrcPort ^ DestPort;
dwIndex = NET_TO_HOST_LONG(Address); dwIndex += Protocol; dwIndex += NET_TO_HOST_SHORT(Port);
dwIndex %= g_ipsec.CacheHalfSize; if (fOutbound) { dwIndex += g_ipsec.CacheHalfSize; }
return dwIndex; }
__inline VOID CacheUpdate( IN ULARGE_INTEGER uliAddr, IN ULARGE_INTEGER uliPort, IN PVOID _pCtxt1, IN PVOID _pCtxt2, IN ULONG dwId, IN BOOLEAN fFilter ) { PFILTER_CACHE __pCache; PFILTER_CACHE __pTempCache; PFILTER __pFilter; PSA_TABLE_ENTRY __pSA; PSA_TABLE_ENTRY __pNextSA;
__pCache = g_ipsec.ppCache[(dwId)];
if (IS_VALID_CACHE_ENTRY(__pCache)) { if (__pCache->FilterEntry) { __pCache->pFilter->FilterCache = NULL; } else { __pCache->pSAEntry->sa_FilterCache = NULL; if (__pCache->pNextSAEntry) { __pCache->pNextSAEntry->sa_FilterCache = NULL; __pCache->pNextSAEntry = NULL; } } }
if (fFilter) { __pFilter = (PFILTER)(_pCtxt1);
if (__pFilter->FilterCache) { INVALIDATE_CACHE_ENTRY(__pFilter->FilterCache); __pFilter->FilterCache = NULL; }
__pCache->uliSrcDstAddr = (uliAddr); __pCache->uliProtoSrcDstPort = (uliPort); __pCache->FilterEntry = TRUE; __pCache->pFilter = __pFilter; __pFilter->FilterCache = __pCache; } else { __pSA = (PSA_TABLE_ENTRY)(_pCtxt1); __pNextSA = (PSA_TABLE_ENTRY)(_pCtxt2);
if (__pSA->sa_FilterCache) { __pTempCache = __pSA->sa_FilterCache; __pTempCache->pSAEntry->sa_FilterCache = NULL; if (__pTempCache->pNextSAEntry) { __pTempCache->pNextSAEntry->sa_FilterCache = NULL; } INVALIDATE_CACHE_ENTRY(__pTempCache); }
if (__pNextSA && __pNextSA->sa_FilterCache) { __pTempCache = __pNextSA->sa_FilterCache; __pTempCache->pSAEntry->sa_FilterCache = NULL; if (__pTempCache->pNextSAEntry) { __pTempCache->pNextSAEntry->sa_FilterCache = NULL; } INVALIDATE_CACHE_ENTRY(__pTempCache); }
__pCache->uliSrcDstAddr = (uliAddr); __pCache->uliProtoSrcDstPort = (uliPort); __pCache->FilterEntry = FALSE; __pCache->pSAEntry = __pSA; __pSA->sa_FilterCache = __pCache; if (__pNextSA) { __pCache->pNextSAEntry = __pNextSA; __pNextSA->sa_FilterCache = __pCache; } } }
__inline VOID IPSecInvalidateSACacheEntry( IN PSA_TABLE_ENTRY pSA ) { PFILTER_CACHE pCache;
pCache = pSA->sa_FilterCache;
if (pCache) { ASSERT(IS_VALID_CACHE_ENTRY(pCache)); ASSERT(pSA == pCache->pSAEntry || pSA == pCache->pNextSAEntry); pCache->pSAEntry->sa_FilterCache = NULL; if (pCache->pNextSAEntry) { pCache->pNextSAEntry->sa_FilterCache = NULL; } INVALIDATE_CACHE_ENTRY(pCache); } }
__inline VOID IPSecInvalidateFilterCacheEntry( IN PFILTER pFilter ) { PFILTER_CACHE pCache;
pCache = pFilter->FilterCache;
if (pCache) { ASSERT(IS_VALID_CACHE_ENTRY(pCache)); ASSERT(IS_EXEMPT_FILTER(pFilter)); pFilter->FilterCache = NULL; INVALIDATE_CACHE_ENTRY(pCache); } }
__inline VOID IPSecStartSATimer( IN PSA_TABLE_ENTRY pSA, IN IPSEC_TIMEOUT_HANDLER TimeoutHandler, IN ULONG SecondsToGo ) { if (pSA->sa_Flags & FLAGS_SA_TIMER_STARTED) { if (IPSecStopTimer(&pSA->sa_Timer)) { IPSecStartTimer(&pSA->sa_Timer, TimeoutHandler, SecondsToGo, (PVOID)pSA); } } else { pSA->sa_Flags |= FLAGS_SA_TIMER_STARTED; IPSecStartTimer(&pSA->sa_Timer, TimeoutHandler, SecondsToGo, (PVOID)pSA); } }
__inline VOID IPSecStopSATimer( IN PSA_TABLE_ENTRY pSA ) { if (pSA->sa_Flags & FLAGS_SA_TIMER_STARTED) { pSA->sa_Flags &= ~FLAGS_SA_TIMER_STARTED; IPSecStopTimer(&pSA->sa_Timer); } }
__inline VOID IPSecStopTimerDerefSA( IN PSA_TABLE_ENTRY pSA ) { if (pSA->sa_Flags & FLAGS_SA_TIMER_STARTED) { if (IPSecStopTimer(&pSA->sa_Timer)) { pSA->sa_Flags &= ~FLAGS_SA_TIMER_STARTED; IPSecDerefSA(pSA); } } else { IPSecDerefSA(pSA); } }
__inline VOID IPSecDerefSANextSA( IN PSA_TABLE_ENTRY pSA, IN PSA_TABLE_ENTRY pNextSA ) { if (pNextSA) { IPSecDerefSA(pNextSA); } IPSecDerefSA(pSA); }
__inline VOID IPSecRemoveSPIEntry( IN PSA_TABLE_ENTRY pSA ) { if (pSA->sa_Flags & FLAGS_SA_ON_SPI_HASH) { IPSecRemoveEntryList(&pSA->sa_SPILinkage); pSA->sa_Flags &= ~FLAGS_SA_ON_SPI_HASH; } }
//
// Packs the src/dest IP addrs in a large integer
//
#define IPSEC_BUILD_SRC_DEST_ADDR(_li, _src, _dest) { \
(_li).LowPart = _src; \ (_li).HighPart = _dest; \ }
#define IPSEC_BUILD_SRC_DEST_MASK IPSEC_BUILD_SRC_DEST_ADDR
//
// Packs the Proto and Src/Dest ports into a large int
//
//
// Ports make sense only for TCP and UDP
//
//
// TCP/UDP header
// 0 15 16 31
// |----|----|----|----|----|----|----|----|
// | Source Port | Dst Port |
//
#define IPSEC_BUILD_PROTO_PORT_LI(_li, _proto, _sport, _dport) { \
(_li).LowPart = \ MAKELONG(MAKEWORD((_proto),0x00),0x0000); \ switch((_li).LowPart) { \ case 6: \ case 17: { \ (_li).HighPart = MAKELONG((_sport),(_dport)); \ break; \ } \ default: { \ (_li).HighPart = 0x00000000; \ break; \ } \ } \ }
#define IPSecRefFilter(__pfilter) IPSEC_INCREMENT((__pfilter)->Reference)
#define IPSecFreeFilter(__pfilter) IPSecFreeMemory(__pfilter)
#define IPSecDerefFilter(__pfilter) \
{ \ if (IPSEC_DECREMENT((__pfilter)->Reference) == 0) { \ IPSecFreeFilter(__pfilter); \ } \ }
#define IPSecAllocateKeyBuffer(_size) IPSecAllocateMemory(_size, IPSEC_TAG_KEY)
#define IPSecFreeKeyBuffer(_key) IPSecFreeMemory(_key)
#define IPSecAllocateLogBuffer(_size) IPSecAllocateMemory(_size, IPSEC_TAG_LOG)
#define IPSecFreeLogBuffer(_key) IPSecFreeMemory(_key)
#define IPSecFreeSA(_sa) { \
LONG _i; \ for (_i=0; _i<(_sa)->sa_NumOps; _i++) { \ if ((_sa)->INT_KEY(_i)) { \ IPSecFreeKeyBuffer((_sa)->INT_KEY(_i)); \ } \ if ((_sa)->CONF_KEY(_i)) { \ IPSecFreeKeyBuffer((_sa)->CONF_KEY(_i));\ } \ } \ IPSecFreeMemory(_sa); \ }
#define IPSecGetAcquireContext() IPSecAllocateMemory(sizeof(IPSEC_ACQUIRE_CONTEXT), IPSEC_TAG_ACQUIRE_CTX)
#define IPSecFreeAcquireContext(_ctx) IPSecFreeMemory(_ctx)
#define IPSecGetNotifyExpire() IPSecAllocateMemory(sizeof(IPSEC_NOTIFY_EXPIRE), IPSEC_TAG_ACQUIRE_CTX)
//
// Hashes <SPI, Dest>
//
#define IPSEC_HASH_SPI(_dest, _spi, _phash) { \
DWORD dwIndex; \ dwIndex = NET_TO_HOST_LONG(_dest) + (_spi); \ dwIndex %= g_ipsec.SAHashSize; \ pHash = &g_ipsec.pSADb[dwIndex]; \ IPSEC_DEBUG_KD_ONLY( \ DBF_EXTRADIAGNOSTIC, ("SPI: Index: %lx for S: %lx, D: %lx, pHash: %lx", \ dwIndex, \ (_spi), \ (_dest), \ pHash)); \ }
//
// Hashes <Src, Dest>
//
#define IPSEC_HASH_ADDR(_src, _dest,_phash) { \
DWORD dwIndex; \ dwIndex = (_src)+(_dest); \ dwIndex %= g_ipsec.SpFilterHashSize; \ pHash = &g_ipsec.pSpFilter[dwIndex]; \ IPSEC_DEBUG_KD_ONLY( \ DBF_EXTRADIAGNOSTIC, ("ADDR: Index: %lx for S: %lx, D: %lx, pHash: %lx", \ dwIndex, \ (_src), \ (_dest), \ pHash)); \ }
#define SRC_ADDR uliSrcDstAddr.LowPart
#define DEST_ADDR uliSrcDstAddr.HighPart
#define SRC_MASK uliSrcDstMask.LowPart
#define DEST_MASK uliSrcDstMask.HighPart
#define PROTO uliProtoSrcDstPort.LowPart
#define SRC_PORT LOWORD(uliProtoSrcDstPort.HighPart)
#define DEST_PORT HIWORD(uliProtoSrcDstPort.HighPart)
#define FI_SRC_PORT(_filter) LOWORD((_filter)->uliProtoSrcDstPort.HighPart)
#define FI_DEST_PORT(_filter) HIWORD((_filter)->uliProtoSrcDstPort.HighPart)
#define SA_SRC_ADDR sa_uliSrcDstAddr.LowPart
#define SA_DEST_ADDR sa_uliSrcDstAddr.HighPart
#define SA_SRC_MASK sa_uliSrcDstMask.LowPart
#define SA_DEST_MASK sa_uliSrcDstMask.HighPart
#define SA_PROTO sa_uliProtoSrcDstPort.LowPart
#define SA_SRC_PORT(_psa) LOWORD((_psa)->sa_uliProtoSrcDstPort.HighPart)
#define SA_DEST_PORT(_psa) HIWORD((_psa)->sa_uliProtoSrcDstPort.HighPart)
#define FILTER_PROTO(ProtoId) MAKELONG(MAKEWORD((ProtoId),0x00),0x00000)
#define FILTER_PROTO_ANY FILTER_PROTO(0x00)
#define FILTER_PROTO_ICMP FILTER_PROTO(0x01)
#define FILTER_PROTO_TCP FILTER_PROTO(0x06)
#define FILTER_PROTO_UDP FILTER_PROTO(0x11)
#define FILTER_TCPUDP_PORT_ANY (WORD)0x0000
#define FILTER_ICMP_TYPE_ANY (BYTE)0xff
#define FILTER_ICMP_CODE_ANY (BYTE)0xff
#define FILTER_MASK_ALL (DWORD)0xffffffff
#define FILTER_MASK_NONE (DWORD)0x00000000
//
// macros to parse the ALGORITHM structure
//
#define INT_ALGO(_i) sa_Algorithm[_i].integrityAlgo.algoIdentifier
#define INT_KEY(_i) sa_Algorithm[_i].integrityAlgo.algoKey
#define INT_KEYLEN(_i) sa_Algorithm[_i].integrityAlgo.algoKeylen
#define INT_ROUNDS(_i) sa_Algorithm[_i].integrityAlgo.algoRounds
#define CONF_ALGO(_i) sa_Algorithm[_i].confAlgo.algoIdentifier
#define CONF_KEY(_i) sa_Algorithm[_i].confAlgo.algoKey
#define CONF_KEYLEN(_i) sa_Algorithm[_i].confAlgo.algoKeylen
#define CONF_ROUNDS(_i) sa_Algorithm[_i].confAlgo.algoRounds
#define COMP_ALGO(_i) sa_Algorithm[_i].compAlgo.algoIdentifier
#define EXT_INT_ALGO IntegrityAlgo.algoIdentifier
#define EXT_INT_KEY IntegrityAlgo.algoKey
#define EXT_INT_KEYLEN IntegrityAlgo.algoKeylen
#define EXT_INT_ROUNDS IntegrityAlgo.algoRounds
#define EXT_CONF_ALGO ConfAlgo.algoIdentifier
#define EXT_CONF_KEY ConfAlgo.algoKey
#define EXT_CONF_KEYLEN ConfAlgo.algoKeylen
#define EXT_CONF_ROUNDS ConfAlgo.algoRounds
#define EXT_INT_ALGO_EX(_i) AlgoInfo[_i].IntegrityAlgo.algoIdentifier
#define EXT_INT_KEYLEN_EX(_i) AlgoInfo[_i].IntegrityAlgo.algoKeylen
#define EXT_INT_ROUNDS_EX(_i) AlgoInfo[_i].IntegrityAlgo.algoRounds
#define EXT_CONF_ALGO_EX(_i) AlgoInfo[_i].ConfAlgo.algoIdentifier
#define EXT_CONF_KEYLEN_EX(_i) AlgoInfo[_i].ConfAlgo.algoKeylen
#define EXT_CONF_ROUNDS_EX(_i) AlgoInfo[_i].ConfAlgo.algoRounds
#define IS_AH_SA(_psa) ((_psa)->sa_Operation[0] == Auth || \
(_psa)->sa_Operation[1] == Auth || \ (_psa)->sa_Operation[2] == Auth) #define IS_ESP_SA(_psa) ((_psa)->sa_Operation[0] == Encrypt || \
(_psa)->sa_Operation[1] == Encrypt || \ (_psa)->sa_Operation[2] == Encrypt)
//
// Increment/decrement statistics
//
#define IPSEC_INC_STATISTIC(_stat) \
(g_ipsec.Statistics.##_stat)++;
#define IPSEC_DEC_STATISTIC(_stat) \
(g_ipsec.Statistics.##_stat)--;
#define IPSEC_INC_TUNNELS(_pSA) { \
if ((_pSA)->sa_Flags & FLAGS_SA_TUNNEL) \ g_ipsec.Statistics.dwNumActiveTunnels++; \ }
#define IPSEC_DEC_TUNNELS(_pSA) { \
if ((_pSA)->sa_Flags & FLAGS_SA_TUNNEL) \ g_ipsec.Statistics.dwNumActiveTunnels--; \ }
//
// Function to read a dword from registry and init the variable passed in.
//
__inline void IPSecRegReadDword( HANDLE hRegKey, PWCHAR param, PULONG var, ULONG def, ULONG max, ULONG min ) { NTSTATUS status; status = GetRegDWORDValue(hRegKey, param, var); if (!NT_SUCCESS(status)) { *(var) = def; } else if (*(var) > max) { *(var) = max; } else if (*(var) <= min) { *(var) = min; } }
//
// Extended function with different default values for
// different kind of registry errors.
//
__inline void IPSecRegReadDwordEx( HANDLE hRegKey, PWCHAR param, PULONG var, ULONG max, ULONG min, ULONG NoExist, ULONG ReadError, ULONG OutOfRange ) { NTSTATUS status; status = GetRegDWORDValue(hRegKey, param, var); if (!NT_SUCCESS(status)){
if (STATUS_OBJECT_NAME_NOT_FOUND == status){ (*var) = NoExist; } else{ (*var) = ReadError; } } else if (((*var)>max) || ((*var)<min)){ (*var) = OutOfRange; } }
//
// Macro for computing incremental checksum (RFC 1624)
//
#define UpdateIPLength(_piph, _length) \
{ \ ULONG _sum; \ USHORT _old; \ \ _old = NET_SHORT((_piph)->iph_length); \ (_piph)->iph_length = (_length); \ _sum = (~NET_SHORT((_piph)->iph_xsum) & 0xffff) + \ (~_old & 0xffff) + \ NET_SHORT((_piph)->iph_length); \ _sum = (_sum & 0xffff) + (_sum >> 16); \ _sum += (_sum >> 16); \ (_piph)->iph_xsum = NET_SHORT((USHORT)(~_sum & 0xffff)); \ }
#define UpdateIPProtocol(_piph, _proto) \
{ \ ULONG _sum; \ USHORT _old; \ \ _old = NET_SHORT(*(USHORT *)&(_piph)->iph_ttl); \ (_piph)->iph_protocol = (_proto); \ _sum = (~NET_SHORT((_piph)->iph_xsum) & 0xffff) + \ (~_old & 0xffff) + \ NET_SHORT(*(USHORT *)&(_piph)->iph_ttl); \ _sum = (_sum & 0xffff) + (_sum >> 16); \ _sum += (_sum >> 16); \ (_piph)->iph_xsum = NET_SHORT((USHORT)(~_sum & 0xffff)); \ }
#define IPSecPrint4Long(_key) \
DbgPrint("Key: %lx-%lx-%lx-%lx", \ *(ULONG *)&(_key)[0], \ *(ULONG *)&(_key)[4], \ *(ULONG *)&(_key)[8], \ *(ULONG *)&(_key)[12]);
#define IPSEC_DELAY_INTERVAL ((LONGLONG)(-1 * 1000 * 1000)) // 1/10 sec.
#define IPSEC_DELAY_EXECUTION() \
{ \ IPSecDelayInterval.QuadPart = IPSEC_DELAY_INTERVAL; \ KeDelayExecutionThread(UserMode, FALSE, &IPSecDelayInterval); \ }
#define IS_DRIVER_BLOCK() (g_ipsec.OperationMode == IPSEC_BLOCK_MODE)
#define IS_DRIVER_BYPASS() (g_ipsec.OperationMode == IPSEC_BYPASS_MODE)
#define IS_DRIVER_SECURE() (g_ipsec.OperationMode == IPSEC_SECURE_MODE)
#define IS_DRIVER_BOOTSTATEFUL() (g_ipsec.OperationMode == IPSEC_BOOTTIME_STATEFUL_MODE)
#define IS_DRIVER_FORWARD_BYPASS() (g_ipsec.DefaultForwardingBehavior == IPSEC_FORWARD_BYPASS)
#define IS_DRIVER_FORWARD_BLOCK()(g_ipsec.DefaultForwardingBehavior == IPSEC_FORWARD_BLOCK)
#define IS_DRIVER_DIAGNOSTIC() (g_ipsec.DiagnosticMode)
#define LOG_EVENT NdisWriteEventLogEntry
#define IPSEC_NULL_GUIDS "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define IPSEC_EQUAL_GUIDS(_A, _B) \
((*(UNALIGNED ULONG *)((PUCHAR)(_A)) == *(UNALIGNED ULONG *)((PUCHAR)(_B))) && \ (*(UNALIGNED ULONG *)(((PUCHAR)(_A))+4) == *(UNALIGNED ULONG *)(((PUCHAR)(_B))+4)) && \ (*(UNALIGNED ULONG *)(((PUCHAR)(_A))+8) == *(UNALIGNED ULONG *)(((PUCHAR)(_B))+8)) && \ (*(UNALIGNED ULONG *)(((PUCHAR)(_A))+12) == *(UNALIGNED ULONG *)(((PUCHAR)(_B))+12)))
//
// Get the next non-zero length NDIS buffer.
//
__inline PNDIS_BUFFER FASTCALL IPSEC_NEXT_BUFFER( IN PNDIS_BUFFER pBuffer ) { PVOID *pDummy = NULL; ULONG Length = 0;
if (!pBuffer) { ASSERT(FALSE); return NULL; }
pBuffer = NDIS_BUFFER_LINKAGE(pBuffer);
while (pBuffer) { IPSecQueryNdisBuf(pBuffer, &pDummy, &Length); if (Length == 0) { pBuffer = NDIS_BUFFER_LINKAGE(pBuffer); continue; } else { return pBuffer; } }
return NULL; }
#define SA_CHAIN_WIDTH 4
//
// Count number of 1's in the IP mask
//
__inline LONG CountNumberOfOnes( IN IPMask IpMask ) { INT i; LONG NumberOfOnes = 0; IPMask Mask = IpMask;
for (i = 0; i < sizeof(IPMask) * 8; i++) { if ((Mask & 0x1) == 0x1) { NumberOfOnes++; }
Mask = Mask >> 1; }
return NumberOfOnes; }
__inline PLIST_ENTRY FASTCALL IPSecResolveSAChain( IN PFILTER pFilter, IN IPAddr IpAddr ) { PLIST_ENTRY pEntry; ULONG Index;
if (IS_TUNNEL_FILTER(pFilter)) { pEntry = &pFilter->SAChain[0]; } else { Index = NET_TO_HOST_LONG(IpAddr) % pFilter->SAChainSize; pEntry = &pFilter->SAChain[Index]; }
return pEntry; }
// This function should only be called
// when holding SABDlock
__inline PIPSEC_STATEFUL_ENTRY IPSecAllocateFromHashPool( VOID ) { PIPSEC_STATEFUL_ENTRY pMem; int index; BOOL fReuse=FALSE; //Get index of buffer to use
//
index = g_ipsec.BootBufferPool->ulCurrentPosition; //Update index
//
if (TOTAL_STATEFUL_ENTRY_COUNT == (++g_ipsec.BootBufferPool->ulCurrentPosition)){ g_ipsec.BootBufferPool->ulCurrentPosition = 0; } //if used up all locations then recycle
//
if (g_ipsec.BootBufferPool->ulEntriesUsed < TOTAL_STATEFUL_ENTRY_COUNT){ g_ipsec.BootBufferPool->ulEntriesUsed++; } else { //Reuse this connection. Remove it from it's location in the Hash Table
//This can result in dropped packets
//
IPSecRemoveEntryList(&(g_ipsec.BootBufferPool->PoolEntry[index].CollisionLinkage)); } //Return the buffer selected at location index
//
return (&(g_ipsec.BootBufferPool->PoolEntry[index])); }
#if GPC
#define IPSEC_GPC_MASK_ALL (0xff)
#define IPSEC_GPC_MASK_NONE (0x0)
#define GPC_REGISTER_CLIENT g_ipsec.GpcEntries.GpcRegisterClientHandler
#define GPC_DEREGISTER_CLIENT g_ipsec.GpcEntries.GpcDeregisterClientHandler
#define GPC_ADD_CFINFO g_ipsec.GpcEntries.GpcAddCfInfoHandler
#define GPC_REMOVE_CFINFO g_ipsec.GpcEntries.GpcRemoveCfInfoHandler
#define GPC_ADD_PATTERN g_ipsec.GpcEntries.GpcAddPatternHandler
#define GPC_REMOVE_PATTERN g_ipsec.GpcEntries.GpcRemovePatternHandler
#define GPC_CLASSIFY_PATTERN g_ipsec.GpcEntries.GpcClassifyPatternHandler
#define GPC_GET_CLIENT_CONTEXT g_ipsec.GpcEntries.GpcGetCfInfoClientContextHandler
#define IPSEC_GPC_ACTIVE (0x12345678)
#define IPSEC_NUM_GPC_FILTERS() (g_ipsec.NumMaskedFilters)
#define IS_GPC_ACTIVE() (g_ipsec.GpcActive == IPSEC_GPC_ACTIVE)
#define IPSEC_SET_GPC_ACTIVE() \
{ \ g_ipsec.GpcActive = IPSEC_GPC_ACTIVE; \ }
#define IPSEC_UNSET_GPC_ACTIVE() \
{ \ g_ipsec.GpcActive = 0; \ }
__inline INT FASTCALL IPSecResolveGpcCf( IN BOOLEAN fOutbound ) { return fOutbound? GPC_CF_IPSEC_OUT: GPC_CF_IPSEC_IN; }
__inline PLIST_ENTRY FASTCALL IPSecResolveGpcFilterList( IN BOOLEAN fTunnel, IN BOOLEAN fOutbound ) { PLIST_ENTRY pEntry;
if (fTunnel) { if (fOutbound) { pEntry = &g_ipsec.GpcFilterList[OUTBOUND_TUNNEL_FILTER]; } else { pEntry = &g_ipsec.GpcFilterList[INBOUND_TUNNEL_FILTER]; } } else { if (fOutbound) { pEntry = &g_ipsec.GpcFilterList[OUTBOUND_TRANSPORT_FILTER]; } else { pEntry = &g_ipsec.GpcFilterList[INBOUND_TRANSPORT_FILTER]; } }
return pEntry; }
__inline VOID IPSEC_CLASSIFY_PACKET( IN INT GpcCf, IN ULARGE_INTEGER uliSrcDstAddr, IN ULARGE_INTEGER uliProtoSrcDstPort, OUT PFILTER *ppFilter, OUT PCLASSIFICATION_HANDLE pGpcHandle ) { GPC_IP_PATTERN Pattern;
*ppFilter = NULL; *pGpcHandle = 0;
Pattern.SrcAddr = SRC_ADDR; Pattern.DstAddr = DEST_ADDR; Pattern.ProtocolId = (UCHAR)PROTO; if (PROTO == PROTOCOL_TCP || PROTO == PROTOCOL_UDP) { Pattern.gpcSrcPort = SRC_PORT; Pattern.gpcDstPort = DEST_PORT; } else { Pattern.gpcSrcPort = 0; Pattern.gpcDstPort = 0; } Pattern.InterfaceId.InterfaceId = 0; Pattern.InterfaceId.LinkId = 0;
GPC_CLASSIFY_PATTERN( g_ipsec.GpcClients[GpcCf], GPC_PROTOCOL_TEMPLATE_IP, &Pattern, ppFilter, pGpcHandle, 0, NULL, TRUE); }
#define IS_GPC_FILTER(f) (g_ipsec.InitGpc && \
f->SRC_MASK == FILTER_MASK_ALL && \ f->DEST_MASK == FILTER_MASK_ALL) #endif
#if FIPS
#define IPSEC_DES_ALGO FIPS_CBC_DES
#define IPSEC_3DES_ALGO FIPS_CBC_3DES
#define IPSEC_SHA_INIT g_ipsec.FipsFunctionTable.FipsSHAInit
#define IPSEC_SHA_UPDATE g_ipsec.FipsFunctionTable.FipsSHAUpdate
#define IPSEC_SHA_FINAL g_ipsec.FipsFunctionTable.FipsSHAFinal
#define IPSEC_DES_KEY g_ipsec.FipsFunctionTable.FipsDesKey
#define IPSEC_3DES_KEY g_ipsec.FipsFunctionTable.Fips3Des3Key
#define IPSEC_CBC g_ipsec.FipsFunctionTable.FipsCBC
#define IPSEC_GEN_RANDOM g_ipsec.FipsFunctionTable.FIPSGenRandom
#define IPSEC_HMAC_SHA_INIT g_ipsec.FipsFunctionTable.FipsHmacSHAInit
#define IPSEC_HMAC_SHA_UPDATE g_ipsec.FipsFunctionTable.FipsHmacSHAUpdate
#define IPSEC_HMAC_SHA_FINAL g_ipsec.FipsFunctionTable.FipsHmacSHAFinal
#define IPSEC_HMAC_MD5_INIT g_ipsec.FipsFunctionTable.HmacMD5Init
#define IPSEC_HMAC_MD5_UPDATE g_ipsec.FipsFunctionTable.HmacMD5Update
#define IPSEC_HMAC_MD5_FINAL g_ipsec.FipsFunctionTable.HmacMD5Final
#else
#define IPSEC_DES_ALGO des
#define IPSEC_3DES_ALGO tripledes
#define IPSEC_SHA_INIT A_SHAInit
#define IPSEC_SHA_UPDATE A_SHAUpdate
#define IPSEC_SHA_FINAL A_SHAFinal
#define IPSEC_DES_KEY deskey
#define IPSEC_3DES_KEY tripledes3key
#define IPSEC_CBC(_EncryptionAlgo, _pOut, _pIn, _pKeyTable, _Operation, _pFeedback) \
CBC(_EncryptionAlgo, \ DES_BLOCKLEN, \ _pOut, \ _pIn, \ _pKeyTable, \ _Operation, \ _pFeedback) #define IPSEC_GEN_RANDOM(_pBuf, _KeySize) NewGenRandom(NULL, NULL, _pBuf, _KeySize)
#endif
#define IPSEC_MD5_INIT MD5Init
#define IPSEC_MD5_UPDATE MD5Update
#define IPSEC_MD5_FINAL MD5Final
#define IPSEC_RC4_KEY rc4_key
#define IPSEC_RC4 rc4
#define IS_CLASS_D_ADDR(x) (((x) & 0x000000f0) == 0x000000e0)
#define TCPIP_FREE_BUFF g_ipsec.TcpipFreeBuff
#define TCPIP_ALLOC_BUFF g_ipsec.TcpipAllocBuff
#define TCPIP_GET_ADDRTYPE g_ipsec.TcpipGetAddrType
#define TCPIP_GET_INFO g_ipsec.TcpipGetInfo
#define TCPIP_NDIS_REQUEST g_ipsec.TcpipNdisRequest
#define TCPIP_REGISTER_PROTOCOL g_ipsec.TcpipRegisterProtocol
#define TCPIP_SET_IPSEC_STATUS g_ipsec.TcpipSetIPSecStatus
#define TCPIP_IP_TRANSMIT g_ipsec.TcpipIPTransmit
#define TCPIP_SET_IPSEC g_ipsec.TcpipSetIPSecPtr
#define TCPIP_UNSET_IPSEC g_ipsec.TcpipUnSetIPSecPtr
#define TCPIP_UNSET_IPSEC_SEND g_ipsec.TcpipUnSetIPSecSendPtr
#define TCPIP_TCP_XSUM g_ipsec.TcpipTCPXsum
#define TCPIP_GEN_IPID g_ipsec.TcpipGenIpId
#define TCPIP_DEREGISTER_PROTOCOL g_ipsec.TcpipDeRegisterProtocol
#define TCPIP_GET_PINFO g_ipsec.TcpipGetPInfo
#define TCPIP_SEND_ICMP_ERR g_ipsec.TcpipSendICMPErr
#ifdef xsum
#undef xsum
#define xsum(Buffer, Length) ((USHORT)TCPIP_TCP_XSUM(0, (PUCHAR)(Buffer), (Length)))
#endif
#define SAFETY_LEN (TRUNCATED_HASH_LEN+MAX_PAD_LEN)
//
// Compares the src/dest ports out of a word with the number input
//
#define IPSEC_COMPARE_SD_PORT(_pport, _port) \
( ((_pport)[0] == (_port)) || \ ((_pport)[1] == (_port)))
#define IPSEC_COMPARE_D_PORT(_pport, _port) ((_pport)[1] == (_port))
//
// Bypass traffic logic for IKE, Kerberos and RSVP
//
#define IPSEC_KERBEROS_TRAFFIC() \
((pIPHeader->iph_protocol == PROTOCOL_UDP || \ pIPHeader->iph_protocol == PROTOCOL_TCP) && \ IPSEC_COMPARE_SD_PORT(pwPort, IPSEC_KERBEROS_PORT))
#define IPSEC_ISAKMP_TRAFFIC() \
(pIPHeader->iph_protocol == PROTOCOL_UDP && \ IPSEC_COMPARE_D_PORT(pwPort, IPSEC_ISAKMP_PORT)) \
#define IPSEC_ISAKMP_TRAFFIC2() \
(pIPHeader->iph_protocol == PROTOCOL_UDP && \ IPSEC_COMPARE_D_PORT(pwPort, IPSEC_ISAKMP_PORT2)) \
#define IPSEC_RSVP_TRAFFIC() \
(pIPHeader->iph_protocol == PROTOCOL_RSVP)
#define IPSEC_NO_UNICAST_EXEMPT 0x00000001
#define IPSEC_NO_MANDBCAST_EXEMPT 0x00000002
#define IPSEC_NO_DEFAULT_EXEMPT() (g_ipsec.NoDefaultExempt & IPSEC_NO_UNICAST_EXEMPT)
#define IPSEC_HANDLE_MANDBCAST() (g_ipsec.NoDefaultExempt & IPSEC_NO_MANDBCAST_EXEMPT)
#define IPSEC_MANDBCAST_PROCESS() (IPSEC_GET_VALUE(g_ipsec.NumMulticastFilters) || \
IPSEC_HANDLE_MANDBCAST())
#define IPSEC_BYPASS_TRAFFIC() \
(IPSEC_ISAKMP_TRAFFIC() || IPSEC_ISAKMP_TRAFFIC2() || \ (!IPSEC_NO_DEFAULT_EXEMPT() && \ (IPSEC_KERBEROS_TRAFFIC() || \ IPSEC_RSVP_TRAFFIC())))
//
// Forwarding path is either reinject a detunneled forward packet or route
//
#define IPSEC_FORWARD_PATH() (fFWPacket || (fOutbound && TCPIP_GET_ADDRTYPE(pIPHeader->iph_src) != DEST_LOCAL))
#define EQUAL_NATENCAP(_pNatContext,_pSA) ((_pNatContext == NULL) || (_pNatContext && (_pSA->sa_EncapContext.wSrcEncapPort == _pNatContext->wSrcEncapPort && _pSA->sa_EncapContext.wDesEncapPort == _pNatContext->wDesEncapPort)))
/*++
Routine Description:
Fills in the DELETE_SA hw request from pSA
Arguments:
pSA - the SA Buf - buffer to set info Len - length
Return Value:
status of the operation
--*/ #define IPSecFillHwDelSA(_pSA, _Buf, _Len) \
((POFFLOAD_IPSEC_DELETE_SA)(_Buf))->OffloadHandle = (_pSA)->sa_OffloadHandle;
#endif _MACROS_H
|