locked
How to modify/insert data at transport layer (TCP). RRS feed

  • Question

  • If I intercept inbound data at the transport layer (TCP), before it gets to it's application, then change the data, what do I need to update before sending the data to the Application?

    In particular:

    - Do I need to update the sequence number in the TCP Header, since the payload is now of a different size?

    - Do I need to recalculate the TCP checksum, since the payload data is now different, or will FwpsConstructIpHeaderForTransportPacket0 or FwpsInjectTransportReceiveAsync0 do this?

    - Since I've changed the payload, do I need to change the packet size in the IP header? Or is there a way that FwpsConstructIpHeaderForTransportPacket0 will do this, for example  if I changed the NetBuffer MDL size, or some other way?

    I've tried doing a NBL clone and changing the data, and I've tried allocating an NBL from scratch and completely building both the TCP and IP header from the Inbound packet with adjustments for the modified payload. So far I've not been able to get either to be accepted by the Application.

    Thanks for the help.

    Sunday, January 29, 2012 5:07 PM

All replies

  • You should be doing this at FWPM_LAYER_STREAM_V{4 / 6}.  Doing so will let you operate solely on the data, and no need in mucking with the ACK / SEQ / checksum in the TCP Header.

    To answer your question though, yes you'd need to update the transport header and recalculate the ACK / SEQ / and checksum.  In addition you'll need to hold up every packet for the same connection so you can tweak their ACK / SEQ / Checksum info.  This is the major reason why doing this at stream is much easier and more efficient.

    Neither FwpsConstructIpHeaderForTransportPackets nor FwpsInjectTransportReceiveAsync0 will update the transport checksum.

     

    Hope this helps,


    Dusty Harper [MSFT]
    Microsoft Corporation
    ------------------------------------------------------------
    This posting is provided "AS IS", with NO warranties and confers NO rights
    ------------------------------------------------------------
    Monday, January 30, 2012 4:07 AM
    Moderator
  • Dusty,

     

    Are you sure on the TCP header checksum.

    Before calling FwpsConstructIpHeaderForTransportPackets, I set both the IP header checksum and the TCP Header checksum fields to 0's. Then after calling it they both have values?

    I've  already written a routine to do the TCP checksum myself, but it looks like I will have to zero out what FwpsConstructIpHeaderForTransportPackets does, before applying it. So I was wondering about it's updating of this TCP Header field.

    Also, does it matter where the netbuffer offset is set before calling FwpsInjectTransportReceiveAsync0. As Inbound is generally at the payload, but construct seems to leave it at the IP header.

    If I use the streaming as you mention, would that also deal with Acks to the  server for the original packets?

     

     

     

    Monday, January 30, 2012 3:19 PM
  • I was incorrect in regard to FwpsConstructIpHeaderForTransportPacket.  This function will recalculate the IP and Transport checksums.  The same holds true for FwpsInjectTransportSendAsync.  FwpsInjectTransportReceiveAsync does not do this.

    The NBL offset is important when doing the injection.  You need the offset to be in the originating position of the classify (Inbound Transport @ the data, and Outbound Transport at the transport header).

    Again the recommended way to do data manipulation for TCP is to use STREAM.  This layer is before any headers are created and before the TCP state machine for Outbound, and after the headers are stripped and after the TCP state machine for inbound.  Essentially what this means is you don't have to worry about any of the headers and whether your ACK and SEQ counts are correct.

    Hope this helps,


    Dusty Harper [MSFT]
    Microsoft Corporation
    ------------------------------------------------------------
    This posting is provided "AS IS", with NO warranties and confers NO rights
    ------------------------------------------------------------
    Monday, January 30, 2012 4:16 PM
    Moderator
  • Hi Dusty, 

    I think you are right about going to the streaming layer, but another question.

    If I use the streaming layer, can I recognize each individual TCP connection, and will I be able to associate  the Outgoing and Incoming filtered content with each connection, how would this be done?

    I really appreciate your help!

     

    Tuesday, January 31, 2012 2:57 PM
  • Not solely from the STREAM layer.  You can have another filter / callout at FWPM_LAYER_ALE_FLOW_ESTABLISHED_V{4 / 6}.  This callout would get invoked once the TCP handshake has successfully finished (or on the first non-TCP packet).  In the callout you can call FwpsFlowAssociateContext to associate whatever context you want with an individual flow.

    Additionally each flow has its own unique flowId.

     

    Hope This helps


    Dusty Harper [MSFT]
    Microsoft Corporation
    ------------------------------------------------------------
    This posting is provided "AS IS", with NO warranties and confers NO rights
    ------------------------------------------------------------
    Tuesday, January 31, 2012 4:37 PM
    Moderator