locked
Whay is Classify routine called in a loop with same packet? RRS feed

  • Question

  • I'm doing WFP filters at the transport layer. I'm catching the packet, cloning, doing out-of-band edit and then injecting. Everything is fine, except the classify keeps getting called in a loop with the same packet. I return block, clear the right bit and set the abandon bit.

    It  also does this if I return permit. It does this for inbound and outbound. It was also doing this before at the Stream level. I've also used different values when setting up the filter (terminating and unknown) and many combinations of the bit sets/resets. In a nutshell it doesn't seem to flush the packet, and the looping is blocking out the user mode code from processing.

    When I do NetSh, the filter looks fine, thoug I've noticed the weights are always changed by windows. I've tried to set max weights and min weights, but they are always something else in the effective weight. This layer does have 2 Microsoft callouts, one for IPSec and another, but no filters I can see.

    I've wondered whether I need some kind of special security setting when I open the Engine. Note, that it's a kernel driver which communicates with IRPs to user mode.

    I've tried to create my own sublayer, but no change. And again, the Sublayer weight gets changed by Windows.

    I've also tried adding  a Provider, but the filter add fails if I try and use it. When is a provider needed, as Doc here is sparse.

    And I've also wondered whether each time I'm creating a device it sometikeeps living, and I have 50 devices, though this seems unlikely to me, but I was wondering if there was a way to check it. Also, I'm adding as FILE_DEVICE_NETWORK, could it be I need a different type to block??

    I need help, why would Windows keep calling Classify with the same packet in a loop????? 

     Answer: The problem was that I was not using the right Device type when creating the IO device. I was using Network, when I changed to transport, things started to work properly

     



    Monday, November 14, 2011 4:42 PM

All replies

  • 1) Are you setting the FWPS_CLASSIFY_OUT_FLAG_ABSORB when blocking?  This will cause the stack to swallow the original NBL.  Additionally when you clone and re-inject the clone, your classifyFn must return FWP_ACTION_BLOCK and ideally set this flag.

       Note that multiple callouts are supported, and each one gets called for any layer provided the filters match (see filter arbitration).  You should also be using the FwpsQueryPacketInjectionState() API.  This will tell if no one has injected yet (FWPS_PACKET_NOT_INJECTED), you have already injected the NBL (FWPS_PACKET_INJECTED_BY_SELF), another callout has injected the NBL before you (FWPS_PACKET_INJECTED_BY_OTHER), or you injected the NBL, another callout(s) reinjected the NBL, and you are now seeing the NBL again (FWPS_PACKET_PREVIOUSLY_INJECTED_BY_SELF).  Ideally if the state is FWPS_PACKET_INJECTED_BY_SELF, you can safely return FWP_ACTION_PERMIT or FWP_ACTION_CONTINUE.  If the state is FWPS_PACKET_PREVIOUSLY_INJECTED_BY_SELF, then you need to make a decision whether you trust the other callouts and what they have done and allow the NBL by without further injection, or don't trust them and block the NBL.

    2)BFE takes all weights as suggestions and tries to accommodate accordingly.  If you specify a UINT64 as a weight, BFE will try to set the weight as that UINT64 to the best of its abilities (i.e. no other object of the same type is already assigned that weight).

    3) No special security setting is needed for FwpmEngineOpen (other than Administrator rights).  The following is the simplest call to FwpmEngineOpen():

    status = FwpmEngineOpen0(0,
                             RPC_C_AUTHN_WINNT,
                             0,
                             0,
                             &engineHandle);
    

    4) Sublayers are used to help with filter arbitration.  This will allow you to have a guarantee that your filters will be a part of the filtering decision in addition to those from other sublayers.  For example if a filter in FWPM_SUBLAYER_UNIVERSAL says to permit all packets from 1.0.0.1 TCP port 4000, and you have a filter that says BLOCK all in the same sublayer, the PERMIT will happen, as its more specific to the traffic when filter arbitration occurs. Now if you move the BLOCK all filter into your own sublayer, then FWPM_SUBLAYER_UNIVERSAL returns PERMIT after its arbitration, and your arbitrated sublayer returns BLOCK, the final decision will be BLOCK (as BLOCK overrides PERMIT).

    5) You should always have a FWPM_PROVIDER.  this helps identify all of the objects you create.  What failure are you getting?  You need to add the provider (FwpmProviderAdd()) before you can use it in any objects, and its lifetime must be at least the same as the object its being used in (i.e. you have to specify the provider is persistent if the object you use it in is persistent).

    Hope this helps,

     


    Dusty Harper [MSFT]
    Microsoft Corporation
    ------------------------------------------------------------
    This posting is provided "AS IS", with NO warranties and confers NO rights
    ------------------------------------------------------------
    Monday, November 14, 2011 6:11 PM
    Moderator
  • 1) I'm doing everything you mention in 1.

    2) I've  tried the UNINT 64 weights, but have gone for Max and Min, which someone else may be using, so I will consider values near these. Regardless, the windows seems to do as it pleases.

    3) good to know, I won't chase this.

    4) Yes, I had great hopes for the sublayer, but it made no real difference

    5) Good to know, as I've seen many examples without providers. I'll check the error code tonight. But, is the provider of any additional use?

    My current theory is that I'm using the wrong Device type with iocreatedevice. I'm using FILER_DEVICE_NETWORK, and I'm suspect that changing this to FILE_DEVICE_TRANSPORT might fix the problem, as I'm filtering at the TRANSPORT_INBOUND level. Any idea what the symptoms would be for creating a Device of one type, then filter at another layer, using the Device? I'll try this change this evening.

     

    Monday, November 14, 2011 7:23 PM
  • 1) when you are debugging this, are you paying attention to the injection state?  does it indicate any looping?  Is the injection succeeding (look in the completionFn for the injected NBL->status)?  Is it possible these are retransmissions?  How are you determining it's the same packet?  using a network sniffer, doe the packet ever leave the interface?

    2) again weights are essentially suggestions.  to define a specific weight, you must use an FWP_UINT64 (and this is a best effort as well).  setting the weight to FWP_EMPTY results in BFE doing whatever it pleases, and setting it to an FWP_UINT8 tells BFE to weight it accordingly within that range.

    5) Providers allow for identification, and you can also tag them with provider specific data.  If you are going to get a Windows Certification (previously Windows Logo) then having an identifying provider and associating it with all of your WFP objects is a requirement to pass the program.

    WFP is agnostic to the FILE_DEVICE_*.  In house we use FILE_DEVICE_NETWORK just fine.

    Hope this helps,

     

     


    Dusty Harper [MSFT]
    Microsoft Corporation
    ------------------------------------------------------------
    This posting is provided "AS IS", with NO warranties and confers NO rights
    ------------------------------------------------------------
    Tuesday, November 15, 2011 5:51 PM
    Moderator