现在的位置: 首页 > 综合 > 正文

Linux内核:从skb获取udp头,udp_hdr()获取到是错误的udp头

2018年10月02日 ⁄ 综合 ⁄ 共 1163字 ⁄ 字号 评论关闭

一、skb中获取ip头、udp头

内核代码HOOK函数中:

        从skb获取ip头,使用内核API ip_hdr():

#include <linux/ip.h>

struct iphdr *iph;
iph = ip_hdr(skb);

        从skb获取udp头,使用内核API udp_hdr():

#include <linux/udp.h>

struct udphdr *udph;
udph = udp_hdr(skb);

二、udp_hdr()获取到是错误的udp头

2.1 现象

        上述获取的iph是正确的ip头,获取的udph是错误的udp头。

2.2 原因

        因为此时sk_buff的transport_header并没有指向正确的udp头,而是和network_header一同指向了ip头。

三、正确的获取udp头

3.1 通过ip头计算udp头

struct udphdr *udph;
udph = (struct udphdr *) ((u8 *) iph + (iph->ihl << 2));

3.2 先设置transport_header指向正确的udp头,再用udp_hdr()获取

struct udphdr *udph;
skb_set_transport_header(skb, sizeof(struct iphdr));  //iph->ihl << 2
udph = udp_hdr(skb);

四、实例代码

4.1 代码

unsigned int hook_mark1(unsigned int hooknum, struct sk_buff *skb,
                        const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *))
{
    struct iphdr *iph;
    struct udphdr *udph1;
    struct udphdr *udph2;

    iph = ip_hdr(skb);
    if (iph->protocol == 17)
    {
        iph = ip_hdr(skb);
        udph1 = udp_hdr(skb);
        udph2 = (struct udphdr *) ((u8 *) iph + (iph->ihl << 2));
        printk("001 iph:%p, udph1:%p, udph2:%p\n", iph, udph1, udph2);

        skb_set_transport_header(skb, sizeof(struct iphdr)); 

        iph = ip_hdr(skb);
        udph1 = udp_hdr(skb);
        udph2 = (struct udphdr *) ((u8 *) iph + (iph->ihl << 2));
        printk("002 iph:%p, udph1:%p, udph2:%p\n", iph, udph1, udph2);
    }
    return NF_ACCEPT;
}

4.2 输出结果

抱歉!评论已关闭.