如何确定原始数据包中IP头和TCP头的起始字节

Posted

技术标签:

【中文标题】如何确定原始数据包中IP头和TCP头的起始字节【英文标题】:how to determine the starting byte of IP Header and TCP header in a raw packet 【发布时间】:2013-03-04 01:12:45 【问题描述】:

我想用libpcap抓包 但由于以太网标头或 802.11 标头的长度可能会有所不同 IP头的长度也可能不同, 如何确定 IP 标头和 TCP 标头的起始字节(指针) 另外,如何区分一个数据包是纯IP数据包、TCP数据包还是UDP数据包? 是否有任何 API 或方法可以做到这一点? 谢谢!

【问题讨论】:

以太网头的长度不能变化!在偏移量 14 处,您将找到 IP 数据包,然后从那里您可以找到 IP 标头的长度并将其添加到 14 以获得 TCP 标头的偏移量。 那么 802.11 标头呢? 我从来没有在数据包捕获中看到过其中的一个,我也不是很熟悉它,但它似乎有一个固定的大小(30 字节 + 4 字节的预告片),所以,也不是问题。 当我收到一个数据包时,我必须判断第二层包头的大小,因为它可能是以太网包头或802.11包头。 但是在单个捕获文件中,数据包都是相同类型的,the header tells you which one it is! 【参考方案1】:

当您使用 libpcap 时,您可以通过直接查看 pcap 文件头(对于离线捕获)pcap_file_header.linktype 或(对于实时和离线捕获)调用 @ 来确定链接层头的大小987654322@。大多数情况下,这将是LINKTYPE_ETHERNET。为确保数据包是 IPv4,您可以转换为以太网标头并检查以确保以太网类型为 ETHERTYPE_IP(确保将其包装在 ntohs() 内。我通常将 bpf 过滤器应用于我的 pcap 实例化,所以我从不担心但是,要检查更高层协议并假设您使用的是pcap_dispatch(),您可以按照以下方式编写回调:(libnet 库对于其广泛的可移植数据包结构仍然有用):

#include <libnet.h>
#include <pcap.h>

void
process_packet(u_char *user, const struct pcap_pkthdr *header, const u_char *packet)

    struct libnet_ipv4_hdr *ip;
    struct libnet_udp_hdr  *tcp;
    uint16_t ip_hl, udp_hl, header_cruft;

    ip     = (struct libnet_ipv4_hdr *)(packet + LIBNET_ETH_H);
    ip_hl  = ip->ip_hl << 2;

    switch (ip->ip_p)
    
        case IPPROTO_UDP:
            udp    = (struct libnet_udp_hdr *)(packet + LIBNET_ETH_H + ip_hl);
            udp_hl = tcp->th_off << 2;
            header_cruft = LIBNET_ETH_H + ip_hl + tcp_hl;
            break;
        case IPPROTO_TCP:
            /** you get the idea */
            break;
        default:
            break;
    

【讨论】:

如果您使用 libpcap/WinPcap 读取离线捕获,pcap_datalink() 将返回文件的链接层标头类型,因此您可以使用相同的代码进行实时捕获和读取捕获文件. 还要注意pcap_datalink()返回DLT_值,而不是LINKTYPE_值;在 99 44/100% 的情况下,它们具有相同的数值,但在某些情况下,它们没有(某些操作系统对特定的 DLT_ 定义使用不同的数值,但这在捕获文件中不起作用,所有操作系统的解释都必须相同)。

以上是关于如何确定原始数据包中IP头和TCP头的起始字节的主要内容,如果未能解决你的问题,请参考以下文章

TCP段头的最小长度是多少?

linux内核中ip,tcp等头的定义(转)

为啥TCP段最大是65535字节,怎么计算的

Wireshark抓包工具--TCP数据包seq ack等解读

九度oj 题目1475:IP数据包解析

DDOS攻击分类