我正在尝试使用WinPCap获取并解析以太网标签(目标地址,源地址,类型/长度字段)。
我主要是从WinPCap SDK复制/粘贴。我试图将WinPCap数据包数据(在pkt_data中)存储在名为ethernet的结构中,该结构包含目标地址[6字节],源地址[6字节],类型/长度字段(短整数)和数据包长度(整数)。
我认为pkt_data排在前6个字节作为目标地址,接下来的6个字节作为源地址,后面的两个作为类型/长度字段,但我不确定。
有人知道WinPCap在此示例中存储的标签的确切字节顺序吗?
/* If device is open, acquire attributes from packet */
if( ( res = pcap_next_ex( fp, &header, &pkt_data)) >= 0)
{
if(res != 0)
{
/* Acquire the length of the capture */
ethernet->length = header->caplen;
/* Acquire destination MAC address */
for (i = 0; i < 6; i++)
ethernet->destAddress[i] = pkt_data[i];
/* Acquire source MAC address */
for ( i = 6; i < 12; i++ )
ethernet->srcAddress[i] = pkt_data[i];
/* Acquire etherType type/length designation field */
ethernet->type = ( pkt_data[12] | pkt_data[13] );
/* Acquire the remaining data of the packet */
for ( i = 14; (i < header->caplen + 1); i++ )
ethernet->data[i - 14] = pkt_data[i];
}
/* Device error: cannot read from packet */
else if(res == -1)
printf("Error reading the packets: %s\n", pcap_geterr(fp));
}
答案 0 :(得分:0)
libpcap / WinPcap捕获的数据包中的数据字节顺序是数据在网络上传输的字节顺序; libpcap / WinPcap提供原始数据包数据(Raditaap无线电报头之类的“伪报头”信息除外,这些信息不会出现在线路上,并且以生成它们的软件的任何字节顺序使用,例如,在该情况下为little-endian Radiotap)。
MAC地址最好被认为是6字节序列,而不是48位数字,因此它们没有字节顺序问题。目的地地址首先出现,因此位于pkt_data[0]
到pkt_data[5]
;接下来是源地址,因此它位于pkt_data[6]
到pkt_data[11]
。
请注意
/* Acquire source MAC address */
for ( i = 6; i < 12; i++ )
ethernet->srcAddress[i] = pkt_data[i];
错误 - srcAddress
可能是一个6字节的数组,因此它有srcAddress[0]
到srcAddress[5]
,并且没有启用srcAddress[6]
。你可以用
/* Acquire source MAC address */
for ( i = 0; i < 6; i++ )
ethernet->srcAddress[i] = pkt_data[i + 6];
但使用memcpy()
复制数据可能最简单,而不是自己编写循环:
memcpy(ethernet->dstAddress, &pkt_data[0], 6);
memcpy(ethernet->srcAddress, &pkt_data[6], 6);
之后是类型/长度字段,长度为两个字节,因此它位于pkt_data[12]
和pkt_data[13]
中。根据{{3}},“首先使用高阶八位字节发送和接收长度/类型字段。” “第一个”八位字节是pkt_data[12]
,所以它是“高阶八位字节”,它应该是该值的高8位; “第二个”八位位组是pkt_data[13]
,并且是值的低位8位,所以
ethernet->type = (pkt_data[12]<<8) | pkt_data[13];