获取数据包 headers 的函数在 sk_buff 中可用

Functions for getting packet headers available in sk_buff

Linux中有获取以太网header、IPheader和UDPheader的函数

udp_hdr(skb)
ip_hdr
skb_push(skb, ETH_HLEN)

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

any function for getting payload like body of a packet

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

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

或者如果您想进一步重建封装或者不再需要它们(粗略的例子,没有进行所有可能的完整性检查),您可以拉动网络并传输 headers:

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 协议不是内核特定的东西,所以通常我们谈论的是传输协议的有效负载。

N.B.: ip_hdr(), udp_hdr() 函数暗示使用 non-paged (linear) skb.

相关:What's the correct way to process all the payload of a sk_buff packet in Linux