0

我正在尝试使用 libpcap 查看进出我的环回网络适配器的 http 流量。我刚从网络编程开始,对这个库完全陌生。感谢我之前收到的答案,我成功地检测到了我机器的“lo0”适配器(Mac OSx)上的链路层类型。

//lookup link-layer header type
link_layer_type = pcap_datalink(handle);
if(link_layer_type == DLT_NULL){
    printf("DLT_NULL"); // this true in the case of "lo0"
}

Programming with Pcap指南假设每个数据包都包含一个以太网标头。因此用于查找数据包有效负载的逻辑如下:

 ethernet = (struct sniff_ethernet*)(packet);
    ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);
    size_ip = IP_HL(ip)*4;
    if (size_ip < 20) {
        printf("   * Invalid IP header length: %u bytes\n", size_ip);
        return;
    }
    tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip);
    size_tcp = TH_OFF(tcp)*4;
    if (size_tcp < 20) {
        printf("   * Invalid TCP header length: %u bytes\n", size_tcp);
        return;
    }
}

payload = (u_char *)(packet + SIZE_ETHERNET + size_ip + size_tcp);

当检查源自不存在以太网标头的环回接口的数据包内容时,此逻辑将不起作用。Link-Layer Header Types 文档指出,“DTL_NULL”的Link-Layer 类型包含一个 4 字节的标头,其中包含一个 PF_ 值,其中包含网络层协议(我猜在我的情况下是 IPv4)。

鉴于上述信息..如何正确定位数据包的有效负载位置?

任何指导或信息将不胜感激。谢谢!

4

1 回答 1

0

鉴于上述信息..如何正确定位数据包的有效负载位置?

对于DLT_NULL,您的程序应将数据包数据的前 4 个字节提取为 32 位数字。如果您正在进行实时捕获,您可以按主机的字节顺序提取它,并将其与您的操作系统的值进行比较AF_INETAF_INET6如果它有AF_INET6定义;如今,大多数当前的操作系统版本应该支持 IPv6);如果您正在读取捕获文件,则如果pcap_is_swapped()返回非零值,则需要对值进行字节交换(您也可以将其用于实时捕获;对于实时捕获,它始终返回零),并且您需要与几个不同的“IPv6”值(24、28 和 30)进行比较,每个值都表示某些特定操作系统上的“IPv6”(幸运的AF_INET是,在所有支持的操作系统上都是 2 DLT_NULL,因为它们都从 4.2BSD 中获取了该值) .

如果该值是 IPv4 值(2,如上所述),那么在这 4 个字节之后,您将获得数据包的 IPv4 标头。如果它是 IPv6 值之一,那么在这 4 个字节之后,您就有了数据包的IPv6标头。如果不是这些值中的任何一个,那就是其他协议。

于 2013-08-05T18:58:18.163 回答