티스토리 뷰
반응형
void
TLInspectTransportClassify(
_In_ const FWPS_INCOMING_VALUES* inFixedValues,
_In_ const FWPS_INCOMING_METADATA_VALUES* inMetaValues,
_Inout_opt_ void* layerData,
_In_opt_ const void* classifyContext,
_In_ const FWPS_FILTER* filter,
_In_ UINT64 flowContext,
_Inout_ FWPS_CLASSIFY_OUT* classifyOut
)
#else
void
TLInspectTransportClassify(
_In_ const FWPS_INCOMING_VALUES* inFixedValues,
_In_ const FWPS_INCOMING_METADATA_VALUES* inMetaValues,
_Inout_opt_ void* layerData,
_In_ const FWPS_FILTER* filter,
_In_ UINT64 flowContext,
_Inout_ FWPS_CLASSIFY_OUT* classifyOut
)
#endif
/* ++
This is the classifyFn function for the Transport (v4 and v6) callout.
packets (inbound or outbound) are ueued to the packet queue to be processed
by the worker thread.
-- */
{
KLOCK_QUEUE_HANDLE connListLockHandle;
KLOCK_QUEUE_HANDLE packetQueueLockHandle;
TL_INSPECT_PENDED_PACKET* pendedPacket = NULL;
FWP_DIRECTION packetDirection;
ADDRESS_FAMILY addressFamily;
FWPS_PACKET_INJECTION_STATE packetState;
BOOLEAN signalWorkerThread;
#if(NTDDI_VERSION >= NTDDI_WIN7)
UNREFERENCED_PARAMETER(classifyContext);
#endif /// (NTDDI_VERSION >= NTDDI_WIN7)
UNREFERENCED_PARAMETER(filter);
UNREFERENCED_PARAMETER(flowContext);
//
// We don't have the necessary right to alter the classify, exit.
//
if ((classifyOut->rights & FWPS_RIGHT_ACTION_WRITE) == 0)
{
goto Exit;
}
NT_ASSERT(layerData != NULL);
_Analysis_assume_(layerData != NULL);
//
// We don't re-inspect packets that we've inspected earlier.
//
packetState = FwpsQueryPacketInjectionState(
gInjectionHandle,
layerData,
NULL
);
if ((packetState == FWPS_PACKET_INJECTED_BY_SELF) ||
(packetState == FWPS_PACKET_PREVIOUSLY_INJECTED_BY_SELF))
{
classifyOut->actionType = FWP_ACTION_PERMIT;
if (filter->flags & FWPS_FILTER_FLAG_CLEAR_ACTION_RIGHT)
{
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
}
goto Exit;
}
addressFamily = GetAddressFamilyForLayer(inFixedValues->layerId);
packetDirection =
GetPacketDirectionForLayer(inFixedValues->layerId);
if (packetDirection == FWP_DIRECTION_INBOUND)
{
if (IsAleClassifyRequired(inFixedValues, inMetaValues))
{
//
// Inbound transport packets that are destined to ALE Recv-Accept
// layers, for initial authorization or reauth, should be inspected
// at the ALE layer. We permit it from Tranport here.
//
classifyOut->actionType = FWP_ACTION_PERMIT;
if (filter->flags & FWPS_FILTER_FLAG_CLEAR_ACTION_RIGHT)
{
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
}
goto Exit;
}
else
{
//
// To be compatible with Vista's IpSec implementation, we must not
// intercept not-yet-detunneled IpSec traffic.
//
FWPS_PACKET_LIST_INFORMATION packetInfo = {0};
FwpsGetPacketListSecurityInformation(
layerData,
FWPS_PACKET_LIST_INFORMATION_QUERY_IPSEC |
FWPS_PACKET_LIST_INFORMATION_QUERY_INBOUND,
&packetInfo
);
if (packetInfo.ipsecInformation.inbound.isTunnelMode &&
!packetInfo.ipsecInformation.inbound.isDeTunneled)
{
classifyOut->actionType = FWP_ACTION_PERMIT;
if (filter->flags & FWPS_FILTER_FLAG_CLEAR_ACTION_RIGHT)
{
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
}
goto Exit;
}
}
}
pendedPacket = AllocateAndInitializePendedPacket(
inFixedValues,
inMetaValues,
addressFamily,
layerData,
TL_INSPECT_DATA_PACKET,
packetDirection
);
if (pendedPacket == NULL)
{
classifyOut->actionType = FWP_ACTION_BLOCK;
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
goto Exit;
}
KeAcquireInStackQueuedSpinLock(
&gConnListLock,
&connListLockHandle
);
KeAcquireInStackQueuedSpinLock(
&gPacketQueueLock,
&packetQueueLockHandle
);
if (!gDriverUnloading)
{
signalWorkerThread = IsListEmpty(&gPacketQueue) &&
IsListEmpty(&gConnList);
InsertTailList(&gPacketQueue, &pendedPacket->listEntry);
pendedPacket = NULL; // ownership transferred
classifyOut->actionType = FWP_ACTION_BLOCK;
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB;
}
else
{
//
// Driver is being unloaded, permit any connect classify.
//
signalWorkerThread = FALSE;
classifyOut->actionType = FWP_ACTION_PERMIT;
if (filter->flags & FWPS_FILTER_FLAG_CLEAR_ACTION_RIGHT)
{
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
}
}
KeReleaseInStackQueuedSpinLock(&packetQueueLockHandle);
KeReleaseInStackQueuedSpinLock(&connListLockHandle);
if (signalWorkerThread)
{
KeSetEvent(
&gWorkerEvent,
0,
FALSE
);
}
Exit:
if (pendedPacket != NULL)
{
FreePendedPacket(pendedPacket);
}
return;
}반응형
'프로그래밍 > CC++' 카테고리의 다른 글
| C++ variant, 상속 없이 다형성 흉내 내기 (실무 후기) (0) | 2025.09.11 |
|---|---|
| C++ optional, '널 포인터'와 작별하는 가장 우아한 방법 (실무 후기) (0) | 2025.09.11 |
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- JavaScript
- react
- reactjs
- 프로그래밍
- 개발자
- 오리역
- 내집마련
- CSS
- AI
- 카카오톡
- SWiFT
- openai
- 생각
- Linux
- 부동산
- 재테크
- Spring
- golang
- 부동산분석
- MacOS
- Python
- Frontend
- go
- 주식투자
- ChatGPT
- 카톡업데이트
- Backend
- Java
- HTML
- ios
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
글 보관함