title: Windows Filtering Platform - where's my packet payload?
body: <p>I've been modifying the 'inspect' WFP example (bundled with the WinDDK) with the aim of being able to parse the payload of all incoming TCP packets (from a specified IP address) for certain strings.  (I've already modified 'inspect' such that only TCP packets are caught by the filter)</p>
  
  <p>So far my modifications have been on the 'TLInspectTransportClassify'  classifyFn, as shown below.  My aim is to have access to the payload of each TCP packet that is caught.</p>
  
  <pre><code>FWPS_STREAM_CALLOUT_IO_PACKET* ioPacket = (FWPS_STREAM_CALLOUT_IO_PACKET*)layerData;
  FWPS_STREAM_DATA* streamData;
  SIZE_T streamLength;
  BYTE* stream = NULL;
  SIZE_T bytesCopied = 0;
  
  [...]
  
  if(ioPacket == NULL) {
     DbgPrint("ioPacket == NULL\n");
     return STATUS_INSUFFICIENT_RESOURCES;
  }
  streamData = ioPacket-&gt;streamData;
  
  if(!streamData) {     // why is this always NULL?  shouldn't our payload be here?
     DbgPrint("streamData == NULL: no data\n");   
     classifyOut-&gt;actionType = FWP_ACTION_PERMIT;
       classifyOut-&gt;rights &amp;= ~FWPS_RIGHT_ACTION_WRITE;
       goto Exit;
  }
  
  DbgPrint("tcp packet has some data\n");
  
  streamLength = streamData-&gt;dataLength;
  
  stream =  ExAllocatePoolWithTag(NonPagedPool,
                                 streamLength,
                                 'yftN');
  
  if (!stream)
    return STATUS_INSUFFICIENT_RESOURCES;
  
  RtlZeroMemory(stream,streamLength);
  FwpsCopyStreamDataToBuffer0(
    streamData,
    stream,
    streamLength,
    &amp;bytesCopied);
  
  // should now have our tcp payload in 'stream' buffer(?)
  
  DbgPrint("reached parsing code\n");
  
  [...]
  </code></pre>
  
  <p>From my understanding, after declaring ioPacket as above, ioPacket->streamData should contain the packet's payload.  However, ioPacket->streamData is ALWAYS NULL for me.  How do I get the packet's payload?  Am I doing something wrong.</p>
  
  <p>Thanks in advance.</p>