Interpreting FWP_CONDITION_VALUE0 structure members

Hi All,

How can I interpret the members in the FWP_CONDITION_VALUE0 structure. When I check some MSDN samples, I see that the first four fields are mapped to protocol , ipaddress, port.
But I couldn’t find any msdn doc that explains each filed in the structure

typedef struct FWP_CONDITION_VALUE0_ {
  FWP_DATA_TYPE type;
  union {
    UINT8                 uint8;
    UINT16                uint16;
    UINT32                uint32;
    UINT64                *uint64;
    INT8                  int8;
    INT16                 int16;
    INT32                 int32;
    INT64                 *int64;
    float                 float32;
    double                *double64;
    FWP_BYTE_ARRAY16      *byteArray16;
    FWP_BYTE_BLOB         *byteBlob;
    SID                   *sid;
    FWP_BYTE_BLOB         *sd;
    FWP_TOKEN_INFORMATION *tokenInformation;
    FWP_BYTE_BLOB         *tokenAccessInformation;
    LPWSTR                unicodeString;
    FWP_BYTE_ARRAY6       *byteArray6;
    FWP_BITMAP_ARRAY64    *bitmapArray64;
    FWP_V4_ADDR_AND_MASK  *v4AddrMask;
    FWP_V6_ADDR_AND_MASK  *v6AddrMask;
    FWP_RANGE0            *rangeValue;
  };
} FWP_CONDITION_VALUE0;

https://docs.microsoft.com/en-us/windows/win32/api/fwptypes/ns-fwptypes-fwp_condition_value0

There really aren’t enough bad things to say about the WFP API…

These values passed as an array to your classify function and provide access to various bits of information available at the current filtering layer. Do NOT assume that the values are in a particular order, their locations in the array varies depending on your filtering layer.

For example, if you’re at FWPM_LAYER_ALE_AUTH_CONNECT_V4 then you get the local IP address by indexing with FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_LOCAL_ADDRESS:

inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_LOCAL_ADDRESS]

The type will be FWP_UINT32, so you use the uint32 member of the union to get the value:

inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_LOCAL_ADDRESS].value.uint32

If you’re at FWPM_LAYER_ALE_AUTH_CONNECT_V6 then you need to use a different index to get the local IP:

inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V6_IP_LOCAL_ADDRESS]

The IPv6 address has a type of FWP_BYTE_ARRAY16_TYPE, so you use the byteArray16 member to get the value:

inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V6_IP_LOCAL_ADDRESS].value.byteArray16

These are of course just examples and you need different indexes for different layers (i.e. FWPS_FIELD_ALE_AUTH_LISTEN_V4_IP_LOCAL_ADDRESS, FWPS_FIELD_ALE_AUTH_RECV_ACCEPT_V4_IP_LOCAL_ADDRESS, etc.) And, yes, these values can be different so you can’t just cheat and use one for all layers…You can check the docs for which values are available at each layer. For example, here’s all the indexes for the Connect V4 layer:

https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/fwpsk/ne-fwpsk-fwps_fields_ale_auth_connect_v4_

As you might imagine this is REALLY error prone…I wish they had just provided APIs for extracting these things OR put them at the same index for every layer.

1 Like

Thanks Scott for the detailed answer.

I just want to make sure you recognize that this is not a structure with 22 different fields. That’s a UNION. There are only two fields there: the type, and another “thing”. You have to use the type to know whether you should use uint8 or uint16 or uint64 or float32.

1 Like

Thanks, Tim.

One more question. When I run driver verifier against my callout drivers, do I need to enable DV on any other drivers in the WFP framework?