首页 > 解决方案 > 用于获取 sk_buff 中可用数据包头的函数

问题描述

Linux 中有一些函数可以获取以太网头、IP 头和 UDP 头,比如这些

udp_hdr(skb)
ip_hdr
skb_push(skb, ETH_HLEN)

但是我找不到任何函数来获取有效负载,例如包含主体的数据包主体,因此我可以编写 HTTP 或其他协议数据。在 Linux Device Driver book 或搜索后找不到它。所以问题是如何在内核中用以太网、IP、UDP 标头和有效负载组成 UDP 数据包?

标签: clinuxnetworkinglinux-kerneludp

解决方案


任何用于获取有效载荷的函数,如数据包的主体

您可以根据下次要执行的操作以不同的方式访问有效负载。例如:

struct iphdr *iph = ip_hdr(skb);

if (iph->protocol == IPPROTO_UDP) {
    struct udphdr *udph = udp_hdr(skb);
    // E.g. check for UDP port
    struct myl7_header *l7h = (struct myl7_header *)(udph + sizeof(struct udphdr));
    // ...
}

或者,如果您想进一步重构封装或者不再需要它们,您可以拉取网络和传输标头(粗略示例,未进行所有可能的健全性检查):

struct iphdr *iph = ip_hdr(skb);

if (iph->protocol == IPPROTO_UDP) {
    struct udphdr *udph = udp_hdr(skb);
    struct myl7_header *l7h;
    // E.g. check for UDP port
    skb_pull(skb, sizeof(struct iphdr));
    skb_pull(skb, sizeof(struct udphdr));
    l7h = (struct myl7_header *)skb->data;
    // tansport protocol payload's length:
    // skb->len or skb_tail_pointer(skb) - skb->data
}

我真的不知道你的意思是什么payloadhtml,L7-protocol 它不是内核特定的东西,所以总的来说我们谈论的是传输协议的有效负载。

注意:ip_hdr()udp_hdr()函数意味着使用非分页(线性)skb。

相关:在 Linux 中处理 sk_buff 数据包的所有有效负载的正确方法是什么


推荐阅读