【问题标题】:libpcap - packet ip header length is zero bytes with loopback tcp requestslibpcap - 数据包 ip 标头长度为零字节,带有环回 tcp 请求
【发布时间】:2013-06-12 08:17:01
【问题描述】:

我正在尝试使用 libpcap 查看 TCP 有效负载信息。为此,我需要定位有效载荷在内存中的位置。我正在使用这个Programming With Pcap 指南来确定请求有效负载的位置。当嗅探来自与服务(环回适配器)位于同一台机器上的客户端的数据包时,IP 标头长度为 0。我无法成功找到请求有效负载的位置。在收听环回适配器时这是可以预料的吗?我正在使用一个监听适配器“lo0”的 MacOSx 10.8 系统。

这是我正在尝试的:

    //this callback is called when a packet is found
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet){
    ethernet = (struct sniff_ethernet*)(packet);
    ip = (struct sniff_ip*)(packet + SIZE_ETHERNET); <-- the result is 0
    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);

}

结构嗅探IP:

#define SIZE_ETHERNET 14

 /* IP header */
struct sniff_ip {
    u_char ip_vhl;      /* version << 4 | header length >> 2 */
    u_char ip_tos;      /* type of service */
    u_short ip_len;     /* total length */
    u_short ip_id;      /* identification */
    u_short ip_off;     /* fragment offset field */
#define IP_RF 0x8000        /* reserved fragment flag */
#define IP_DF 0x4000        /* dont fragment flag */
#define IP_MF 0x2000        /* more fragments flag */
#define IP_OFFMASK 0x1fff   /* mask for fragmenting bits */
    u_char ip_ttl;      /* time to live */
    u_char ip_p;        /* protocol */
    u_short ip_sum;     /* checksum */
    struct in_addr ip_src,ip_dst; /* source and dest address */
};

【问题讨论】:

    标签: c tcp network-programming libpcap


    【解决方案1】:
    ethernet = (struct sniff_ethernet*)(packet);
    ip = (struct sniff_ip*)(packet + SIZE_ETHERNET); <-- the result is 0
    

    如果您在环回接口上进行捕获,则该代码是错误的。并非 OS X(或任何其他支持 libpcap/WinPcap 的操作系统)上的所有接口都提供以太网头;您需要调用pcap_datalink() 来查找捕获设备的链路层类型(或捕获文件,如果您正在使用pcap_open_offline() 读取捕获文件),并在此基础上解析数据包。

    完整列表请参见the list of pcap link-layer header types

    DLT_EN10MB 是以太网设备的链路层标头类型(“10MB”是历史的,指的是 3MB 与 10MB 以太网,它们有不同的标头;DLT_EN10MB 适用于 10 MB 和 100 MB 和 1 GB和 10 GB 和 40 GB 和 100 GB 和...以太网),以及一些提供虚假以太网标头的非以太网设备。

    大多数 BSD 和 OS X 上环回设备的链路层标头类型是 DLT_NULL;正如链路层标头类型页面所说,它有一个 4 字节的链路层标头,其中包含操作系统的 PF_ 协议值,可能是 IPv4 或 IPv6。

    【讨论】:

    • 很好的答案。非常感谢。
    猜你喜欢
    • 2013-05-07
    • 2016-01-27
    • 1970-01-01
    • 1970-01-01
    • 2010-10-28
    • 1970-01-01
    • 2018-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多