一、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 输出结果