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.
294 lines
8.5 KiB
294 lines
8.5 KiB
/*++
|
|
|
|
Copyright (c) 1997-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
NsPacketRoutines.h
|
|
|
|
Abstract:
|
|
|
|
This file contains the code for the packet-routines used for
|
|
connection routines.
|
|
|
|
The inbound routines have the exact same logic as the outbound routines.
|
|
However, for reasons of efficiency the two are separate routines,
|
|
to avoid the cost of indexing on 'NsDirection' for every packet
|
|
processed.
|
|
|
|
To avoid duplicating the code, then, this header file consolidates the code
|
|
in one location. This file is included twice in NsPacket.c, and before each
|
|
inclusion, either 'NS_INBOUND' or 'NS_OUTBOUND' is defined.
|
|
|
|
This causes the compiler to generate the code for separate functions,
|
|
as desired, while avoiding the unpleasantness of code-duplication.
|
|
|
|
Each routine is invoked from 'NsProcess*Packet' at dispatch level
|
|
with no locks held and with a reference acquired for the connection
|
|
entry.
|
|
|
|
Author:
|
|
|
|
Jonathan Burstein (jonburs) 20-July-2001
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#ifdef NS_INBOUND
|
|
#define NS_POSITIVE NsInboundDirection
|
|
#define NS_NEGATIVE NsOutboundDirection
|
|
#define NS_TCP_ROUTINE NsInboundTcpPacketRoutine
|
|
#define NS_UDP_ROUTINE NsInboundUdpPacketRoutine
|
|
#define NS_TCP_TRANSLATE_PORT_ROUTINE NsInboundTcpTranslatePortPacketRoutine
|
|
#define NS_UDP_TRANSLATE_PORT_ROUTINE NsInboundUdpTranslatePortPacketRoutine
|
|
#define NS_PACKET_FIN NS_CONNECTION_FLAG_IB_FIN
|
|
#define NS_TRANSLATE_PORTS_TCP() \
|
|
pContext->pTcpHeader->SourcePort = \
|
|
CONNECTION_REMOTE_PORT(pConnection->ulPortKey[NsOutboundDirection])
|
|
#define NS_TRANSLATE_PORTS_UDP() \
|
|
pContext->pUdpHeader->SourcePort = \
|
|
CONNECTION_REMOTE_PORT(pConnection->ulPortKey[NsOutboundDirection])
|
|
#else
|
|
#define NS_POSITIVE NsOutboundDirection
|
|
#define NS_NEGATIVE NsInboundDirection
|
|
#define NS_TCP_ROUTINE NsOutboundTcpPacketRoutine
|
|
#define NS_UDP_ROUTINE NsOutboundUdpPacketRoutine
|
|
#define NS_TCP_TRANSLATE_PORT_ROUTINE NsOutboundTcpTranslatePortPacketRoutine
|
|
#define NS_UDP_TRANSLATE_PORT_ROUTINE NsOutboundUdpTranslatePortPacketRoutine
|
|
#define NS_PACKET_FIN NS_CONNECTION_FLAG_OB_FIN
|
|
#define NS_TRANSLATE_PORTS_TCP() \
|
|
pContext->pTcpHeader->DestinationPort = \
|
|
CONNECTION_REMOTE_PORT(pConnection->ulPortKey[NsInboundDirection])
|
|
#define NS_TRANSLATE_PORTS_UDP() \
|
|
pContext->pUdpHeader->DestinationPort = \
|
|
CONNECTION_REMOTE_PORT(pConnection->ulPortKey[NsInboundDirection])
|
|
#endif
|
|
|
|
NTSTATUS
|
|
FASTCALL
|
|
NS_TCP_ROUTINE(
|
|
PNS_CONNECTION_ENTRY pConnection,
|
|
PNS_PACKET_CONTEXT pContext
|
|
)
|
|
|
|
{
|
|
KeAcquireSpinLockAtDpcLevel(&pConnection->Lock);
|
|
|
|
//
|
|
// Update the connection state based on the flags in the packet:
|
|
//
|
|
// When a RST is seen, mark the connection for deletion
|
|
// When a FIN is seen, mark the connection appropriately
|
|
// When both FINs have been seen, mark the connection for deletion
|
|
//
|
|
|
|
if (TCP_FLAG(pContext->pTcpHeader, RST))
|
|
{
|
|
pConnection->ulFlags |= NS_CONNECTION_FLAG_EXPIRED;
|
|
}
|
|
else if (TCP_FLAG(pContext->pTcpHeader, FIN))
|
|
{
|
|
pConnection->ulFlags |= NS_PACKET_FIN;
|
|
if (NS_CONNECTION_FIN(pConnection))
|
|
{
|
|
pConnection->ulFlags |= NS_CONNECTION_FLAG_EXPIRED;
|
|
|
|
//
|
|
// Perform a final update of the timestamp for the connection.
|
|
// From this point on the timestamp is used to determine when
|
|
// this connection has left the time-wait state.
|
|
//
|
|
|
|
KeQueryTickCount((PLARGE_INTEGER)&pConnection->l64AccessOrExpiryTime);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Update the timestamp for the connection (if this connection is not in
|
|
// a timer-wait state -- i.e., both FINs have not been seen).
|
|
//
|
|
|
|
if (!NS_CONNECTION_FIN(pConnection))
|
|
{
|
|
KeQueryTickCount((PLARGE_INTEGER)&pConnection->l64AccessOrExpiryTime);
|
|
}
|
|
|
|
KeReleaseSpinLockFromDpcLevel(&pConnection->Lock);
|
|
|
|
//
|
|
// Periodically resplay the connection entry
|
|
//
|
|
|
|
NsTryToResplayConnectionEntry(pConnection, NS_POSITIVE);
|
|
|
|
return STATUS_SUCCESS;
|
|
} // NS_TCP_ROUTINE
|
|
|
|
NTSTATUS
|
|
FASTCALL
|
|
NS_UDP_ROUTINE(
|
|
PNS_CONNECTION_ENTRY pConnection,
|
|
PNS_PACKET_CONTEXT pContext
|
|
)
|
|
|
|
{
|
|
KeAcquireSpinLockAtDpcLevel(&pConnection->Lock);
|
|
|
|
//
|
|
// Update the timestamp for the connection
|
|
//
|
|
|
|
KeQueryTickCount((PLARGE_INTEGER)&pConnection->l64AccessOrExpiryTime);
|
|
|
|
KeReleaseSpinLockFromDpcLevel(&pConnection->Lock);
|
|
|
|
//
|
|
// Periodically resplay the connection entry
|
|
//
|
|
|
|
NsTryToResplayConnectionEntry(pConnection, NS_POSITIVE);
|
|
|
|
return STATUS_SUCCESS;
|
|
} // NS_UDP_ROUTINE
|
|
|
|
NTSTATUS
|
|
FASTCALL
|
|
NS_TCP_TRANSLATE_PORT_ROUTINE(
|
|
PNS_CONNECTION_ENTRY pConnection,
|
|
PNS_PACKET_CONTEXT pContext
|
|
)
|
|
|
|
{
|
|
ULONG ulChecksumDelta;
|
|
|
|
//
|
|
// Translate the port information in the packet
|
|
//
|
|
|
|
NS_TRANSLATE_PORTS_TCP();
|
|
|
|
//
|
|
// Update the protocol checksum
|
|
//
|
|
|
|
CHECKSUM_XFER(ulChecksumDelta, pContext->pTcpHeader->Checksum);
|
|
ulChecksumDelta += pConnection->ulProtocolChecksumDelta[NS_POSITIVE];
|
|
CHECKSUM_FOLD(ulChecksumDelta);
|
|
CHECKSUM_XFER(pContext->pTcpHeader->Checksum, ulChecksumDelta);
|
|
|
|
KeAcquireSpinLockAtDpcLevel(&pConnection->Lock);
|
|
|
|
//
|
|
// Update the connection state based on the flags in the packet:
|
|
//
|
|
// When a RST is seen, mark the connection for deletion
|
|
// When a FIN is seen, mark the connection appropriately
|
|
// When both FINs have been seen, mark the connection for deletion
|
|
//
|
|
|
|
if (TCP_FLAG(pContext->pTcpHeader, RST))
|
|
{
|
|
pConnection->ulFlags |= NS_CONNECTION_FLAG_EXPIRED;
|
|
}
|
|
else if (TCP_FLAG(pContext->pTcpHeader, FIN))
|
|
{
|
|
pConnection->ulFlags |= NS_PACKET_FIN;
|
|
if (NS_CONNECTION_FIN(pConnection))
|
|
{
|
|
pConnection->ulFlags |= NS_CONNECTION_FLAG_EXPIRED;
|
|
|
|
//
|
|
// Perform a final update of the timestamp for the connection.
|
|
// From this point on the timestamp is used to determine when
|
|
// this connection has left the time-wait state.
|
|
//
|
|
|
|
KeQueryTickCount((PLARGE_INTEGER)&pConnection->l64AccessOrExpiryTime);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Update the timestamp for the connection (if this connection is not in
|
|
// a timer-wait state -- i.e., both FINs have not been seen).
|
|
//
|
|
|
|
if (!NS_CONNECTION_FIN(pConnection))
|
|
{
|
|
KeQueryTickCount((PLARGE_INTEGER)&pConnection->l64AccessOrExpiryTime);
|
|
}
|
|
|
|
KeReleaseSpinLockFromDpcLevel(&pConnection->Lock);
|
|
|
|
//
|
|
// Periodically resplay the connection entry
|
|
//
|
|
|
|
NsTryToResplayConnectionEntry(pConnection, NS_POSITIVE);
|
|
|
|
return STATUS_SUCCESS;
|
|
} // NS_TCP_TRANSLATE_PORT_ROUTINE
|
|
|
|
NTSTATUS
|
|
FASTCALL
|
|
NS_UDP_TRANSLATE_PORT_ROUTINE(
|
|
PNS_CONNECTION_ENTRY pConnection,
|
|
PNS_PACKET_CONTEXT pContext
|
|
)
|
|
|
|
{
|
|
ULONG ulChecksumDelta;
|
|
|
|
//
|
|
// Translate the port information in the packet
|
|
//
|
|
|
|
NS_TRANSLATE_PORTS_UDP();
|
|
|
|
//
|
|
// Update the protocol checksum if the original packet contained
|
|
// a checksum (UDP checksum is optional)
|
|
//
|
|
|
|
if (0 != pContext->pUdpHeader->Checksum)
|
|
{
|
|
CHECKSUM_XFER(ulChecksumDelta, pContext->pUdpHeader->Checksum);
|
|
ulChecksumDelta += pConnection->ulProtocolChecksumDelta[NS_POSITIVE];
|
|
CHECKSUM_FOLD(ulChecksumDelta);
|
|
CHECKSUM_XFER(pContext->pUdpHeader->Checksum, ulChecksumDelta);
|
|
}
|
|
|
|
KeAcquireSpinLockAtDpcLevel(&pConnection->Lock);
|
|
|
|
//
|
|
// Update the timestamp for the connection
|
|
//
|
|
|
|
KeQueryTickCount((PLARGE_INTEGER)&pConnection->l64AccessOrExpiryTime);
|
|
|
|
KeReleaseSpinLockFromDpcLevel(&pConnection->Lock);
|
|
|
|
//
|
|
// Periodically resplay the connection entry
|
|
//
|
|
|
|
NsTryToResplayConnectionEntry(pConnection, NS_POSITIVE);
|
|
|
|
return STATUS_SUCCESS;
|
|
} // NS_UDP_TRANSLATE_PORT_ROUTINE
|
|
|
|
|
|
|
|
#undef NS_POSITIVE
|
|
#undef NS_NEGATIVE
|
|
#undef NS_TCP_ROUTINE
|
|
#undef NS_UDP_ROUTINE
|
|
#undef NS_TCP_TRANSLATE_PORT_ROUTINE
|
|
#undef NS_UDP_TRANSLATE_PORT_ROUTINE
|
|
#undef NS_PACKET_FIN
|
|
#undef NS_TRANSLATE_PORTS_TCP
|
|
#undef NS_TRANSLATE_PORTS_UDP
|