svassilev

Hi,

I am implementing an OOB terminating callout which registers at FWPM_LAYER_DATAGRAM_DATA_V4/V6 (among other layers). As far as my understanding goes at this layer the callout's classifyFn gets the transport payload thru pLayerData parameter and it does not contain the transport header, which makes sense because for the outbound case the transposrt still has not gotten the data. Now I would like to hold on to the data (NET_BUFFER_LIST), perform inspection and at a later point inject the data back to the stream. In order to simplify the discussion lets assume only outbound UDP data.

Questions:

1.
Is it enough to just reference the buffer list and then dereference it when I am done with the injection - FwpsReferenceNetBufferList0/FwpsDereeferenceNetBufferList0 or should I make my own clone via FwpsAllocateCloneNetBufferList0 The reference seems like a faster operation with the downside that it may possibly starve the tcp/ip engine.

2.
Is classifyOut->actionType = FWP_ACTION_BLOCK; enough for setting the status Isnt this going to result in an error returned to the app that is trying to send the data

3.
In order to inject back the data it seems that the only option for outbound UDP is FwpsInjectTransportSendAsync0. Unfortunately to me this sounds like I'll have to create the UDP header myself - compute the checksum, etc. Is this the case Isn't there an API for non-TCP stream data that is similar to FwpsStreamInjectAsync0

Thanks!


Re: Windows Filtering Platform (WFP) OOB stream inspection for non-TCP data

Biao Wang [MSFT]

Hi,

Outbound packets indicated at DATAGRAM_DATA layers (i.e. those with FWPS_FIELD_DATAGRAM_DATA_V{4|6}_DIRECTION field set to FWP_DIRECTION_OUTBOUND) begin with the transport header (e.g. UDP header) while inbound packets' data offset are positioned at the beginning of transport data.

Data offset information for various WFP layers are documented here -- http://msdn2.microsoft.com/en-us/library/aa504926.aspx. Note that the inbound and oubound offsets are not always symmetrical.

1. Only NET_BUFFER_LIST clones can be injected back to the TCP/IP stack. In most cases the cloning process is fast because it does not involve deep-copy of packet data (http://msdn2.microsoft.com/en-us/library/ms795562.aspx). Only in rare circumstances would WFP deep copy packet data -- to ensure multiple callouts inspecting the same packet to have consistent views.

2. To Prevent error being propagated back to the sending app, you should block and "aborb" the packet by setting the FWPS_CLASSIFY_OUT_FLAG_ABSORB flag. For example --

classifyOut->actionType = FWP_ACTION_BLOCK;
classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB;

3. Since at Datagram-Data outbound a UDP packet begins with the UDP header, a clone of the packet will inherit the header so you don't need to re-create it. you will need to recalculate the checksum after modifying the clone, if necessary.

Hope this helps,

Biao.W.





Re: Windows Filtering Platform (WFP) OOB stream inspection for non-TCP data

svassilev

Thanks this really helps. 2 more questions:

1. If the callout decides not to inject back the cloned buf list , does it need to do anything besides calling FwpsFreeCloneNetBufferList0

2. This is more like a suggestion for improvement - it does not seem very logical that the data indicated at FWPM_LAYER_DATAGRAM_DATA_V4/6 has different format depending on the direction. After all there is a flow, which has an established flow-id - why can't the callouts inject the data to the flow At the very least it seems that this layer needs to be broken into two - since the processing is different based on the direction. But ... ideally I would like to be able to treat the data flows the same regardless whether they are TCP or non-TCP.




Re: Windows Filtering Platform (WFP) OOB stream inspection for non-TCP data

Biao Wang [MSFT]

1. Calling FwpsFreeCloneNetBufferList0 would be all you need. If you need to discard packets frequently, you may want to ony reference the packet from classifyFn and only make a clone before modification and/or re-injection. In that case discard a packet is just a simple de-reference operation. You can review the "Out-of-band Packet Modification from Inbound Datagram Data Layers" code snippet from http://msdn2.microsoft.com/en-us/library/aa938500.aspx.

2. Thanks for the feedbacks. Some of the inconsistencies in the current API set are due to the tradeoffs between performance and uniformity; some others are to keep the operation of the TCP/IP Stack simple with the presence of callout drivers modifying packets in mid-flight. That said, we are lookinig into ways to hide some of the complexities and to make common filtering tasks simpler.

Thanks,

Biao.W.