diff --git a/inc/usersim/fwp_test.h b/inc/usersim/fwp_test.h index 64284cd..e4db2b3 100644 --- a/inc/usersim/fwp_test.h +++ b/inc/usersim/fwp_test.h @@ -34,6 +34,9 @@ usersim_fwp_classify_packet(_In_ const GUID* layer_guid, NET_IFINDEX if_index); USERSIM_API FWP_ACTION_TYPE usersim_fwp_bind_ipv4(_In_ fwp_classify_parameters_t* parameters); +USERSIM_API FWP_ACTION_TYPE +usersim_fwp_bind_ipv6(_In_ fwp_classify_parameters_t* parameters); + USERSIM_API FWP_ACTION_TYPE usersim_fwp_cgroup_inet4_recv_accept(_In_ fwp_classify_parameters_t* parameters); diff --git a/src/fwp_um.cpp b/src/fwp_um.cpp index 68b7761..11bde28 100644 --- a/src/fwp_um.cpp +++ b/src/fwp_um.cpp @@ -138,6 +138,10 @@ fwp_engine_t::test_bind_ipv4(_In_ fwp_classify_parameters_t* parameters) parameters->destination_ipv4_address; incoming_value[FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_IP_PROTOCOL].value.uint8 = parameters->protocol; incoming_value[FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_ALE_APP_ID].value.byteBlob = ¶meters->app_id; + incoming_value[FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_COMPARTMENT_ID].value.uint32 = parameters->compartment_id; + incoming_value[FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_IP_LOCAL_INTERFACE].value.uint64 = + const_cast(¶meters->interface_luid); + incoming_value[FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V4_ALE_USER_ID].value.byteBlob = ¶meters->user_id; return test_callout( FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V4, @@ -147,6 +151,29 @@ fwp_engine_t::test_bind_ipv4(_In_ fwp_classify_parameters_t* parameters) nullptr); } +// This is used to test the IPv6 bind hook. +FWP_ACTION_TYPE +fwp_engine_t::test_bind_ipv6(_In_ fwp_classify_parameters_t* parameters) +{ + FWPS_INCOMING_VALUE0 incoming_value[FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V6_MAX] = {}; + incoming_value[FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V6_IP_LOCAL_PORT].value.uint16 = parameters->destination_port; + incoming_value[FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V6_IP_LOCAL_ADDRESS].value.byteArray16 = + ¶meters->destination_ipv6_address; + incoming_value[FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V6_IP_PROTOCOL].value.uint8 = parameters->protocol; + incoming_value[FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V6_ALE_APP_ID].value.byteBlob = ¶meters->app_id; + incoming_value[FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V6_COMPARTMENT_ID].value.uint32 = parameters->compartment_id; + incoming_value[FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V6_IP_LOCAL_INTERFACE].value.uint64 = + const_cast(¶meters->interface_luid); + incoming_value[FWPS_FIELD_ALE_RESOURCE_ASSIGNMENT_V6_ALE_USER_ID].value.byteBlob = ¶meters->user_id; + + return test_callout( + FWPS_LAYER_ALE_RESOURCE_ASSIGNMENT_V6, + FWPM_LAYER_ALE_RESOURCE_ASSIGNMENT_V6, + _default_sublayer, + incoming_value, + nullptr); +} + _Requires_lock_not_held_(this->lock) FWP_ACTION_TYPE fwp_engine_t::test_callout( uint16_t layer_id, _In_ const GUID& layer_guid, @@ -167,12 +194,10 @@ _Requires_lock_not_held_(this->lock) FWP_ACTION_TYPE fwp_engine_t::test_callout( } fwps_filter.context = fwpm_filter->rawContext; - const GUID* callout_key = get_callout_key_from_layer_guid_under_lock(&layer_guid); - if (callout_key == nullptr) { - return FWP_ACTION_CALLOUT_UNKNOWN; - } - - callout = get_callout_from_key_under_lock(callout_key); + // Look up the callout via the filter's calloutKey rather than scanning by layer. + // This matches real WFP behavior where each filter is bound to a specific callout + // and correctly handles multiple callouts registered at the same WFP layer. + callout = get_callout_from_key_under_lock(&fwpm_filter->action.calloutKey); if (callout == nullptr) { return FWP_ACTION_CALLOUT_UNKNOWN; } @@ -1006,6 +1031,12 @@ usersim_fwp_bind_ipv4(_In_ fwp_classify_parameters_t* parameters) return fwp_engine_t::get()->test_bind_ipv4(parameters); } +FWP_ACTION_TYPE +usersim_fwp_bind_ipv6(_In_ fwp_classify_parameters_t* parameters) +{ + return fwp_engine_t::get()->test_bind_ipv6(parameters); +} + FWP_ACTION_TYPE usersim_fwp_cgroup_inet4_recv_accept(_In_ fwp_classify_parameters_t* parameters) { diff --git a/src/fwp_um.h b/src/fwp_um.h index 44c31d5..c7c903a 100644 --- a/src/fwp_um.h +++ b/src/fwp_um.h @@ -220,6 +220,9 @@ typedef class fwp_engine_t FWP_ACTION_TYPE test_bind_ipv4(_In_ fwp_classify_parameters_t* parameters); + FWP_ACTION_TYPE + test_bind_ipv6(_In_ fwp_classify_parameters_t* parameters); + FWP_ACTION_TYPE test_cgroup_inet4_recv_accept(_In_ fwp_classify_parameters_t* parameters);