ethHeader = (PEthHeader) (PUCHAR)MmGetSystemAddressForMdlSafe(NET_BUFFER_CURRENT_MDL()) + NET_BUFFER_CURRENT_MDL_OFFSET()那么如果你Advance(释放used data space)Ethernet_header_size的空间,那么你很容易得到你IP_Header:
iPHeader = (IPHeader)(PUCHAR)MmGetSystemAddressForMdlSafe(NET_BUFFER_CURRENT_MDL()) + NET_BUFFER_CURRENT_MDL_OFFSET()注意的是,Advance,Retreat操作改变了NET_BUFFER_CURRENT_MDL()的返回值甚至需要的时候改变NET_BUFFER_CURRENT_MDL_OFFSET()的返回值。如图~
----------------------------------------------------------------------------------------------------------------------------------
An NBL contains a list of NET_BUFFERs (NB); each NB describes an IP packet.
On recv path, one NBL only contains one NB. So nbl->FirstNetBuffer is the packet.
Each NB contains a chain of MDLs with the CurrentMdl referring to the MDL where the beginning of the packet resides. So nb->CurrentMdl contains the IP header.
The MappedSystemVa field inside the MDL points to the system virtual memory. Advance this pointer by the amount of nb->DataOffset you will be looking at the beginning of the IP header.
Yes the NBL referred to the clone on which you had invoked FwpsConstructXxx api function.
Here would be an example you can try with the code you posted --
NET_BUFFER* netBuffer = NET_BUFFER_LIST_FIRST_NB(clonedNetBufferList); ULONG netBufferOffset = netBuffer->DataOffset; MDL* currentMdl = netBuffer->CurrentMdl; UCHAR* packet = currentMdl->MappedSystemVa + netBufferOffset; // beginning of the IP header
netBuffer->DataLength is the length of your packet (starting from the "packet" variable).
It is possible that one packet consists of multiple MDLs, in which case CurrentMdl->Next is not NULL. If that's the case the ByteCount field of the MDL will be smaller than netBuffer->DataLength and you will need to traverse to the next MDL for more data.
-->http://social.msdn.microsoft.com/forums/en-US/wfp/thread/3ccb32da-c240-477b-bd28-ea584784bd48/
附上:MDL struct:
typedef struct _MDL { PMDL Next; SHORT Size; SHORT MdlFlags; PEPROCESS Process; PVOID MappedSystemVa; PVOID StartVa; ULONG ByteCount; ULONG ByteOffset; } MDL, *PMDL;