libpcap的 - 数据包的IP报头长度为零字节环回TCP请求 [英] libpcap - packet ip header length is zero bytes with loopback tcp requests

查看:447
本文介绍了libpcap的 - 数据包的IP报头长度为零字节环回TCP请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用查看libpcap的TCP负载信息。要做到这一点,我需要找到有效载荷的在内存中的位置。我用这编程PCAP 引导弄清楚请求负载的位置。当嗅探驻留在同一台计算机上作为服务(环回适配器)的IP报头长度为0客户端发起的包,我不能顺利找到请求负载的位置。难道这聆听环回适配器时预期?我正在一个的MacOSX 10.8系统上听适配器lo0的

下面是我想:

  //当一个数据包时发现这个回调被调用
无效got_packet(u_char * ARGS,常量结构pcap_pkthdr *头,常量u_char *包){
    以太网=(结构sniff_ethernet *)(包);
    IP =(结构sniff_ip *)(包+ SIZE_ETHERNET); < - 结果是0
    size_ip = IP_HL(IP)* 4;
    如果(size_ip&下; 20){
        的printf(*无效的IP报头长度:%u字节\\ n,size_ip);
        返回;
    }
    TCP =(结构sniff_tcp *)(+包+ SIZE_ETHERNET size_ip);
    size_tcp = TH_OFF(TCP)* 4;
    如果(size_tcp&下; 20){
        的printf(*无效的TCP报头长度:%u字节\\ n,size_tcp);
        返回;
    }
    有效载荷=(u_char *)(分组+ SIZE_ETHERNET + size_ip + size_tcp);}

结构sniff_ip:

 的#define SIZE_ETHERNET 14 / * IP报头* /
结构sniff_ip {
    u_char ip_vhl; / *版本<< 4 |报头长度GT;> 2 * /
    u_char IP_TOS; / *服务类型* /
    u_short ip_len; /* 总长度 */
    u_short ip_id; / * *识别/
    u_short ip_off; / *片段偏移字段* /
#定义IP_RF为0x8000 / *保留片段标志* /
#定义IP_DF 0x4000的/ *不片段标志* /
#定义IP_MF为0x2000 / *多个片段标志* /
#定义IP_OFF​​MASK 0x1FFF的/ *为分段位掩码* /
    u_char IP_TTL; / *生存时间* /
    u_char ip_p; /* 协议 */
    u_short ip_sum; / * *校验/
    struct in_addr,这个ip_src,ip_dst; / *源和目标地址* /
};


解决方案

 以太网=(结构sniff_ethernet *)(数据包);
IP =(结构sniff_ip *)(包+ SIZE_ETHERNET); < - 结果是0

如果你在loopback接口上捕获,即code是错误的。在OS X(或支持libpcap的/ WinPcap的任何其他操作系统)提供以太网头并非所有的接口;您需要调用 pcap_datalink()查找捕获设备的链路层类型(或捕获文件,如果你正在读一个捕获文件 pcap_open_offline()),并根据该,解析所述分组的链路层报头。

请参阅 PCAP链路层头类型的列表的完整列表。

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值。

I am trying to view TCP payload information using libpcap. To do this I need to locate the payload's position in memory. I am using this Programming With Pcap guide to figure out the location of the request payload. When sniffing packets originating from a client that resides on the same machine as the service (loopback adapter) the IP Header length is 0. I cannot successfully find the location of the request payload. Is this to be expected when listening to loopback adapter? I am working on a MacOSx 10.8 system listening to adapter 'lo0'.

Here is what I am trying:

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

}

struct sniff_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 */
};

解决方案

ethernet = (struct sniff_ethernet*)(packet);
ip = (struct sniff_ip*)(packet + SIZE_ETHERNET); <-- the result is 0

If you're capturing on the loopback interface, that code is wrong. Not all interfaces on OS X (or any other OS that supports libpcap/WinPcap) provide Ethernet headers; you need to call pcap_datalink() to find the link-layer type of the capture device (or capture file, if you're reading a capture file with pcap_open_offline()) and, based on that, parse the link-layer headers of the packet.

See the list of pcap link-layer header types for a complete list.

DLT_EN10MB is the link-layer header type for Ethernet devices ("10MB" is historical, and refers to 3MB vs. 10MB Ethernet, which had different headers; DLT_EN10MB applies to 10 MB and 100 MB and 1 GB and 10 GB and 40 GB and 100 GB and... Ethernet), as well as some non-Ethernet devices that provide fake Ethernet headers.

The link-layer header type for the loopback device on most BSDs and on OS X is DLT_NULL; as the link-layer header types page says, it has a 4-byte link-layer header containing the OS's PF_ value for the protocol, which will probably be IPv4 or IPv6.

这篇关于libpcap的 - 数据包的IP报头长度为零字节环回TCP请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆