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

Posted 二虎

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux内核:从skb获取udp头,udp_hdr()获取到是错误的udp头(转)相关的知识,希望对你有一定的参考价值。

一、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 ", 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 ", iph, udph1, udph2);
}
return NF_ACCEPT;

————————————————
版权声明:本文为CSDN博主「kanguolaikanguolaik」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/guowenyan001/article/details/41284723

以上是关于Linux内核:从skb获取udp头,udp_hdr()获取到是错误的udp头(转)的主要内容,如果未能解决你的问题,请参考以下文章

Linux内核网络UDP数据包发送——IP协议层分析

Linux内核网络UDP数据包发送——IP协议层分析

linux内核网络收包过程—IP协议处理

Linux内核网络udp数据包发送——UDP协议层分析

Linux内核网络udp数据包发送——UDP协议层分析

从Linux 2.6.8内核的一个TSO/NAT bug引出的网络问题排查观点(附一个skb的优化点)