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.
 
 
 
 
 
 

1327 lines
46 KiB

/*++
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
//
// 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_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 ((__pTempCache = __pSA->sa_FilterCache)) {
__pTempCache->pSAEntry->sa_FilterCache = NULL;
if (__pTempCache->pNextSAEntry) {
__pTempCache->pNextSAEntry->sa_FilterCache = NULL;
}
INVALIDATE_CACHE_ENTRY(__pTempCache);
}
if (__pNextSA && (__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(ALL, ("SPI: Index: %lx for S: %lx, D: %lx, pHash: %lx\n", \
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(ALL, ("ADDR: Index: %lx for S: %lx, D: %lx, pHash: %lx\n", \
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--; \
}
//
// Macro to read a dword from registry and init the variable passed in.
//
#define IPSEC_REG_READ_DWORD(_hRegKey, _param, _var, _def, _max, _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; \
} \
}
//
// 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\n", \
*(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_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;
}
#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 DEFAULT_IPSEC_OPERATION_MODE IPSEC_BYPASS_MODE
#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
#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_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_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))
/*++
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