ppi包解析pcap

时间:2012-10-21 14:13:35

标签: parsing field packet pcap ppi

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

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);
}

公共字段的输出是正确的,它表示类型:2,len:20。但是其他值是错误的,就像它说的mac字段类型:64,len:0(mac + phy看起来相似) 。 这是小/大端的问题还是我的错误在哪里?我一直在关注wireshark实现,但他们使用函数tvb_get_letohs()作为偏移量,这是非常错综复杂的...... 希望有人可以提供帮助。

1 个答案:

答案 0 :(得分:1)

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

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

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

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