how to extract IP address from NET_BUFFER

after google and searching and reading and studying a long day, still haven’t figured out what i did wrong, here is my code to get IP address:

pContiguousBuffer = (UCHAR*)NdisGetDataBuffer(pNB,
bytesNeeded,
pAllocatedBuffer,
1,
0);
RtlCopyMemory(&(pBuffer[bytesCopied]),
pContiguousBuffer ? pContiguousBuffer : pAllocatedBuffer,
bytesNeeded);

bytesCopied += bytesNeeded;

UINT8 p1 = (pContiguousBuffer ? pContiguousBuffer : pAllocatedBuffer)[12];
UINT8 p2 = (pContiguousBuffer ? pContiguousBuffer : pAllocatedBuffer)[13];
UINT8 p3 = (pContiguousBuffer ? pContiguousBuffer : pAllocatedBuffer)[14];
UINT8 p4 = (pContiguousBuffer ? pContiguousBuffer : pAllocatedBuffer)[15];
UINT8 p5 = (pContiguousBuffer ? pContiguousBuffer : pAllocatedBuffer)[16];
UINT8 p6 = (pContiguousBuffer ? pContiguousBuffer : pAllocatedBuffer)[17];
UINT8 p7 = (pContiguousBuffer ? pContiguousBuffer : pAllocatedBuffer)[18];
UINT8 p8 = (pContiguousBuffer ? pContiguousBuffer : pAllocatedBuffer)[19];

DoTraceMessage(DL_TRACE,
“packet header: %d srcIp: %d.%d.%d.%d desIp: %d.%d.%d.%d\n”,
bytesNeeded,
p1,p2,p3,p4,p5,p6,p7,p8);

the result is a bit strange from traceview.exe :

00037473 filter 0 0 0 37473 05\11\2017-03:09:26:202 packet header: 1514 srcIp: 8.0.69.0 desIp: 5.220.23.121

any help?

Read on the Ethernet and IP header format.

Also, your code is unnecessarily complicated and ugly. Think a moment how you can make it less ugly.

I was studying ndislwf sample from the wdk. So eager to know how to do and just code if the parsing logic is correct. Looks like the logic is not correct

hi Alex Grig,

according to https://en.wikipedia.org/wiki/IPv4 ,IPv4 Header Format indicates that Source IP Address is starting from 12 offset from the beginning.
isn’t it correct?

VOID KrnlHlprNBLCopyToBuffer(In_opt NET_BUFFER_LIST* pTemplateNBL)
{
if (pTemplateNBL)
{
for (NET_BUFFER* pNB = NET_BUFFER_LIST_FIRST_NB(pTemplateNBL); pNB; pNB = NET_BUFFER_NEXT_NB(pNB))
{
BYTE* pContiguousBuffer = 0;
BYTE* pAllocatedBuffer = 0;
UINT32 bytesNeeded = NET_BUFFER_DATA_LENGTH(pNB);
BYTE* ipHeader = 0;
if (bytesNeeded)
{
HLPR_NEW_ARRAY(pAllocatedBuffer,
BYTE,
bytesNeeded,
WFPSAMPLER_SYSLIB_TAG);
if (pAllocatedBuffer)
{
pContiguousBuffer = (BYTE*)NdisGetDataBuffer(pNB,
bytesNeeded,
pAllocatedBuffer,
1,
0);
ipHeader = pContiguousBuffer ? pContiguousBuffer : pAllocatedBuffer;

UINT8 p1 = ipHeader[30];
UINT8 p2 = ipHeader[31];
UINT8 p3 = ipHeader[32];
UINT8 p4 = ipHeader[33];
UINT8 p5 = ipHeader[34];
UINT8 p6 = ipHeader[35];
UINT8 p7 = ipHeader[36];
UINT8 p8 = ipHeader[37];

DoTraceMessage(DL_TRACE,
“packet header: %d srcIp: %d.%d.%d.%d desIp: %d.%d.%d.%d\n”,
bytesNeeded,
p1, p2, p3, p4, p5, p6, p7, p8);

HLPR_DELETE_ARRAY(pAllocatedBuffer,
WFPSAMPLER_SYSLIB_TAG);
}
}
}
}
}

finally change the offset to begin from 30, the source IP address begins to look right, but the starting from 34, it doesn’t sound right again, any more help

UINT8 p1 = ipHeader[26];
UINT8 p2 = ipHeader[27];
UINT8 p3 = ipHeader[28];
UINT8 p4 = ipHeader[29];
UINT8 p5 = ipHeader[30];
UINT8 p6 = ipHeader[31];
UINT8 p7 = ipHeader[32];
UINT8 p8 = ipHeader[33];

DoTraceMessage(DL_TRACE,
“packet header: %d srcIp: %d.%d.%d.%d desIp: %d.%d.%d.%d\n”,
bytesNeeded,
p1, p2, p3, p4, p5, p6, p7, p8);

finally make it correct now

You forgot that Ethernet header takes 14 bytes.

> according to https://en.wikipedia.org/wiki/IPv4 ,IPv4 Header Format indicates that Source

IP Address is starting from 12 offset from the beginning. isn’t it correct?

Don’t forget that at NDIS level you are dealing with the full network packets, i.e. in a form that they actually appear on the network. Therefore, any packet that you receive starts with a MAC header, and the IP one follows. Therefore, you have to check the MAC header first (just to be sure that you are actually dealing with IPv4 packet), and then you can already check the IP one. Simple,ugh…

Anton Bassov

thanks so much for you guys’ explanations, i appreciate all of you
:slight_smile:

Good example how to get to the header including consideration of VLAN, analysis of the protocols etc: https://github.com/virtio-win/kvm-guest-drivers-windows/blob/5f8eec9d2c1293f5a447a8025b80d30f50454879/NetKVM/Common/sw-offload.cpp#L1035

@Yan:
In windows, the drivers strip the VLAN tag block to the NBL OOB info.