1

我正在尝试使用 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));
}
4

1 回答 1

0

libpcap/WinPcap捕获的数据包中数据的字节顺序是数据在网络上传输的字节顺序;libpcap/WinPcap 提供原始数据包数据(“伪标头”信息除外,例如 Radiotap 无线电标头,这些信息不会出现在网络上,并且按照生成它们的软件使用的任何字节顺序排列,例如在这种情况下为 little-endian无线电台)。

MAC 地址最好被认为是 6 字节序列,而不是 48 位数字,因此它们不存在字节顺序问题。目的地址在前,所以在pkt_data[0]through pkt_data[5];接下来是源地址,所以它在pkt_data[6]through中pkt_data[11]

注意

    /* Acquire source MAC address */
    for ( i = 6; i < 12; i++ )
        ethernet->srcAddress[i] = pkt_data[i];

是错误的 -srcAddress可能是一个 6 字节数组,所以它有srcAddress[0]through srcAddress[5],没有srcAddress[6]on。你可以用

    /* 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);

type/length 字段紧随其后,长度为两个字节,因此位于pkt_data[12]and中pkt_data[13]。根据IEEE 802.3 标准,“长度/类型字段首先以高位八位字节传输和接收。” “第一个”八位字节是pkt_data[12],所以它是“高位八位字节”,它应该是值的高 8 位;“第二个”八位字节是pkt_data[13]并且是值的低 8 位,所以

ethernet->type = (pkt_data[12]<<8) | pkt_data[13];
于 2012-10-11T17:31:25.833 回答