1

我在解析 PPI 帧格式的数据包时遇到了一些麻烦。我需要 802.11+mac+phy 字段,在 common 字段之后似乎我的偏移量有误。这是我的代码:

void process_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{
int offset = 0;

const struct ppi_packetheader *ppi_header = (struct ppi_packetheader *)(packet + offset);
offset += 8;

const struct ppi_fieldheader *ppi_80211_common = (struct ppi_fieldheader *)(packet + offset);
printf("common type: %d | len: %d\n", ppi_80211_common->pfh_type, ppi_80211_common->pfh_datalen);
offset += 4 + 20;

const struct ppi_fieldheader *ppi_80211_mac = (struct ppi_fieldheader *)(packet + offset);
printf("mac type: %d | len: %d\n", ppi_80211_mac->pfh_type, ppi_80211_mac->pfh_datalen);
offset += 4 + 27;

const struct ppi_fieldheader *ppi_80211_mac_phy = (struct ppi_fieldheader *)(packet + offset);
printf("mac+phy type: %d | len: %d\n", ppi_80211_mac_phy->pfh_type, ppi_80211_mac_phy->pfh_datalen);
}

公共字段的输出是正确的,它显示 type: 2, len: 20。但其他值是错误的,就像 mac 字段 type: 64, len: 0 一样(mac+phy 看起来很相似)。是小/大端的问题还是我的错误在哪里?我一直在研究 Wireshark 的实现,但他们使用函数 tvb_get_letohs() 进行偏移,这非常复杂......希望有人能提供帮助。

4

1 回答 1

1

首先,您没有查看对齐位pph_flags- 如果已设置,则每个字段都在 4 字节边界上对齐,如果清楚,则字段不一定在 4 字节边界上对齐。但是,802.11-Common 字段的长度是 4 的倍数,字段标头的长度也是如此,因此,虽然您应该查看该位,但不会导致此特定问题。

而且,是的,“数据包头和字段头中的多字节整数必须存储为 little-endian。”,因此可能存在字节顺序问题。但是,这适用于pfh_typeand pfh_datalen,因此,如果您在大端机器上应该对这些值进行字节交换(这​​就是tvb_get_letohs()正在做的事情 - 它正在从进行边界检查的 Wireshark 缓冲区中获取一个 Little Endian , 短(16 位)值,并将其转换为主机字节顺序;无论该字段是否在“自然”字节边界上对齐,它也可以工作),您显然是在小端机器上运行(如果它是一台基于 x86 的 PC - 包括所有基于 Intel 的 Mac - 您在 little-endian 机器上运行),因为公共字段的输出是正确的,所以'

第三,然而,你没有看ppi_header->pph_len!无法保证PPI 标头中存在任何特定字段 - 对于每个字段,您必须通过查看您是否超过 PPI 标头的长度来检查它是否存在。

当我在 Mountain Lion 上的 Retina MBP 上使用 PPI 标头捕获时,标头长度为 32 个字节,唯一存在的字段是 802.11-Common 字段 - 802.11n MAC+PHY Extensions 字段存在(而且我们的网络是 802.11n 网络)。当您的代码认为它正在查看 802.11n MAC+PHY Extensions 字段时,它实际上可能正在查看 802.11 数据包中的 802.11 MAC 标头。

于 2012-10-22T09:20:56.037 回答