使用钩子函数修改 skb,在 skb 前添加 ip 头。加载完模块后系统崩掉。各位看看是什么原因?

2016-08-26 11:12:56 +08:00
 likethewind
#include <linux/ip.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/inet.h>

#define print_addr(addr) printk("            %u.%u.%u.%u    \n", \
  ((addr & 0xff000000) >> 24), ((addr & 0x00ff0000) >> 16), \
  ((addr & 0x0000ff00) >> 8),  (addr & 0x000000ff))

MODULE_LICENSE("Dual BSD/GPL");

static struct nf_hook_ops nfho;

//钩子函数,注意参数格式与开发环境源码树保持一致
unsigned int hook_func(const struct nf_hook_ops *ops, 
        struct sk_buff *skb,
        const struct net_device *in,
        const struct net_device *out,
        int (*okfn)(struct sk_buff *))
{
	struct iphdr *iph = (struct iphdr *)(skb->data);	

	
	if(iph->protocol == 1){
	struct iphdr *iph_mod = skb_push(skb,20);
	
	memcpy(iph_mod,iph,20);
	
	iph_mod->daddr = 1661970624;//192.168.15.99 
	iph_mod->saddr = 16843009;//1.1.1.1
	iph_mod->tot_len = htons(ntohs(iph->tot_len) + 20);

	skb_reset_network_header(skb);


	struct iphdr *iphm = (struct iphdr *)(skb->data);	
#if 1
	printk("----------------in-in--in-in-----------------\n");
	printk("  _ _ _ _ _ _ _ _IPv4 HDR _ _  _ _ _ _ _");
	printk("\n");
	printk("|version | iphdr_len | Tos | total len  |");
	printk("\n");
	printk("    %u        %u        %u       %u     ",iphm->version,iphm->ihl,iphm->tos,ntohs(iphm->tot_len));
	printk("\n");
	printk("|  identity      |      fragment offset |");
	printk("\n");
	printk("     %u                       %u        ",ntohs(iphm->id),iphm->frag_off);

	printk("\n");
	printk("|   ttl   |    protocol  |   check      |\n");
	printk("     %u           %u           %u          ",iphm->ttl,iphm->protocol,ntohs(iphm->check));

	printk("\n");
	printk("|              src_ip                   |\n");
	print_addr(htonl(iphm->saddr));
	printk("|              dst_ip                   |\n");
	print_addr(htonl(iphm->daddr));
	printk("|---------------------------------------|\n");
#endif	
	}

	return NF_ACCEPT;
}

static int __init hook_init(void)
{
    nfho.hook = hook_func;//关联对应处理函数
    nfho.hooknum = NF_INET_LOCAL_IN;//钩子函数挂载点
    nfho.pf = PF_INET;//ipv4 ,所以用这个
    nfho.priority = NF_IP_PRI_FIRST;//优先级,第一顺位,首先执行我们定义的函数

    nf_register_hook(&nfho);//注册

    return 0;
}
static void __exit hook_exit(void)
{
    nf_unregister_hook(&nfho);//注销
}

module_init(hook_init);
module_exit(hook_exit);



添加 ip 头的方法有问题么?每次 insmod 模块后,都会死机是什么原因?

1902 次点击
所在节点    问与答
4 条回复
ShadowStar
2016-08-26 11:46:12 +08:00
哪个版本的内核?
死机的 panic 信息是什么?
helloworld2010
2016-08-26 16:26:27 +08:00
dead lock?
likethewind
2016-08-29 16:23:01 +08:00
@ShadowStar 3.19.0-25-generic 内核。 死机时大写锁定键(Caps Lock)不停闪烁。
likethewind
2016-08-29 16:23:28 +08:00
@helloworld2010 貌似不是...........

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/301874

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX