前天还为一下的代码耿耿于怀,因为不明白为什么地址+偏移量,然后再来或、与运算。
if(pEthHeader->EthType == TESTPROV_ETH_TYPE_802_1Q) { if(NET_BUFFER_LIST_INFO(pNetBufferList, Ieee8021QNetBufferListInfo) == 0)// no tag info present in OOB { // Count of unstripped packets pFilter->RecdUnStrippedPackets++; } else { //should only reach here if vlanid > 0 VLanId = ((*(PUSHORT)((PUCHAR)pEthHeader + 14)) & 0x0FFF); if(VLanId == 0) pFilter->RecdUnStrippedPackets++; } pEthHeader->EthType = (USHORT)*((PUCHAR)pEthHeader + 16); bytesParsed = ETH_HEADER_SIZE + ETH_802_1Q_TAG_SIZE; } else bytesParsed = ETH_HEADER_SIZE;
pEthHeader是一个缓冲区的,指向Ethernet Header,这是它的定义:
typedef struct _TESTPROV_ETH_HEADER { UCHAR DstAddr[TESTPROV_MAC_ADDR_LEN]; UCHAR SrcAddr[TESTPROV_MAC_ADDR_LEN]; USHORT EthType; } TESTPROV_ETH_HEADER;
这里有一个EthType指明某种协议类型。可以参考:EtherType
这里代码考虑了两种情况,分别是包头中是否包含了IEEE 802.1Q的信息。数据结构如图:
可以看到IEEE 802.1Q Header是4个Byte的。位置在Ethernet Type之前。根据EtherType的值:
0x8100 VLAN-tagged frame (IEEE 802.1Q)
如果包含了IEEE 802.1Q Header,这个type值就定于0x0081(代码中是这样的,跟前面定义倒叙了??)
所以要拿到Vid:VLAN Identifier (VID) : a 12-bit field specifying the VLAN to which the frame belongs. 所以对于 802.1Q Header中的后两个Byte中的后面前4个bit为:(PCP和CFI)。 所以要拿到vlanID,自然packetBuffer+14bytes,然后再从后面两个bytes中取出后12-bit.
VLanId = ((*(PUSHORT)((PUCHAR)pEthHeader + 14)) & 0x0FFF);
这样的话,要拿到VlanID自然要petherhead+12+4了,才能得到了。这样就全部解释清楚了.
--------------------------------现在看看如何拿到AddressFamily----------------------------------
我一直对前面的pEtherhead->EthType的获得方式没有弄清。现在看看这段代码:
// // Start parsing the data // parserState = ParsingIPHeaders; switch (parserState) { case ParsingIPHeaders: // Determine the address family (IPv4 / IPv6) if (bytesCopied < bytesParsed + IP_ADDRESS_FAMILY_LEN) { goto Exit; } AddressFamily = IP_ADDRESS_FAMILY(packetBuffer + bytesParsed); if (IP_ADDRESS_FAMILY_IP4 == AddressFamily){..}
跳过前面的bytesParsed = ETH_HEADER_SIZE;的Ethernet Header,就到了IP Header了。
000000: 00 A0 CC 63 08 1B 00 40 : 95 49 03 5F 08 00 45 00 [email protected]._..E.
000010: 00 3C 82 47 00 00 20 01 : 94 C9 C0 A8 01 20 C0 A8 .<.G.. ...... ..
000020: 01 40 08 00 48 5C 01 00 : 04 00 61 62 63 64 65 66 [email protected]\....abcdef
000030: 67 68 69 6A 6B 6C 6D 6E : 6F 70 71 72 73 74 75 76 ghijklmnopqrstuv
000040: 77 61 62 63 64 65 66 67 : 68 69 wabcdefghi......
packetBuffer 指向的是上面的45的位置。至于数据格式参考 Sample Ping Packet Decode 。
其中高位表示IP version, 低位表示IP header 长度=5个32bits的word.其中((PUCHAR)(buffer))=45.
然后右移4为,对于16进制来说就是4为就是除以16,就剩下一个位,ox45就只剩下 ox4,转换为10进制=4.
可以参考论坛 http://topic.csdn.net/u/20091128/18/2b41c174-e24c-4b0d-8b30-55ff6131db01.html?34775 以及 http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/9234a3cb-eca5-440c-839e-7d45e54fd38b
参考: IEEE802.1q: http://en.wikipedia.org/wiki/IEEE_802.1Q
Ethernet header : http://en.wikipedia.org/wiki/EtherType
IPv4 Header: http://www.networksorcery.com/enp/protocol/ip.htm
IPv6 header :http://www.networksorcery.com/enp/protocol/ipv6.htm
Mobility Header: http://www.networksorcery.com/enp/protocol/mobilityheader.htm