Chinaunix首页 | 论坛 | 博客
  • 博客访问: 386983
  • 博文数量: 109
  • 博客积分: 5045
  • 博客等级: 大校
  • 技术积分: 1199
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-08 14:47
文章分类

全部博文(109)

文章存档

2017年(1)

2012年(5)

2011年(10)

2010年(1)

2009年(13)

2008年(29)

2007年(6)

2006年(44)

我的朋友

分类:

2006-05-09 11:17:32

1 最近开发一网络项目,涉及到netfilter,现在要在自己的prerouting_hook中实现重定向功能,可以调用iptables的函数吗,最简单的实现方案是什么? 2 我们用iptable命令实现重定向: iptables -n nat PREROUTING -p tcp -s 192.168.1.2 --dport 80 -j REDIRECT --to-pot 80 如何在自己的hook中调用iptables函数实现此功能??那位大虾知道啊? 3 参照net/ipv4/netfilter/ipt_REDIRECT.c写了个NAT模块, 将发往本机88断口的包重定向到23断口,编译时出错, 代码和出错信息如下: // gcc -c -Wall -O2 -I/usr/src/linux/include ipnat.c #define __KERNEL__ #define MODULE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define DEBUGP(fmt, arg...) printk(fmt, ##arg) static u_int32_t fw_ip; static u_int16_t fw_port; static unsigned int ip_nat_test( unsigned int hooknum, struct sk_buff **skb, const struct net_device *in, const struct net_device *out, int(*okfn)(struct sk_buff*)) { struct ip_conntrack *ct; enum ip_conntrack_info ctinfo; struct ip_nat_multi_range newrange; struct tcphdr * tcp; if ( (*skb)->sk ) return NF_ACCEPT; ct = ip_conntrack_get ( *skb, &ctinfo); IP_NF_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); if( (*skb)->nh.iph->protocol != IPPROTO_TCP ) return NF_ACCEPT; tcp = ( struct tcphdr*)((char*)(*skb)->nh.iph + ((*skb)->nh.iph->ihl<<2)); if ( tcp->dest == __constant_htons(88)) { newrange = (struct ip_nat_multi_range) { 1,{ { IP_NAT_MANIP_DST|IP_NAT_RANGE_PROTO_SPECIFIED, fw_ip, fw_ip, { fw_port }, { fw_port }}} }; return ip_nat_setup_info (ct, &newrange,hooknum); } else return NF_ACCEPT; } static struct nf_hook_ops ip_in_ops = { { NULL, NULL }, ip_nat_test, PF_INET, NF_IP_PRE_ROUTING, NF_IP_PRI_NAT_DST + 1 }; static int __init init(void) { fw_ip = in_aton("172.18.10.31"); fw_port = __constant_htons(23); return nf_register_hook( &ip_in_ops ); } static void __exit fini(void) { DEBUGP( "ipnat test unregister\n"); nf_unregister_hook (&ip_in_ops); } module_init(init); module_exit(fini); 内核为2.4.7 gcc为2.96 , 出错信息如下: [root@ac31 ksrc]# gcc -c -Wall -O2 -I/usr/src/linux/include ipnat.c In file included from /usr/src/linux/include/linux/irq.h:57, from /usr/include/asm/hardirq.h:6, from /usr/src/linux/include/linux/interrupt.h:45, from /usr/include/asm/highmem.h:25, from /usr/src/linux/include/linux/highmem.h:11, from /usr/src/linux/include/linux/skbuff.h:27, from ipnat.c:7: /usr/include/asm/hw_irq.h:186: conflicting types for `prof_shift' /usr/src/linux/include/linux/sched.h:547: previous declaration of `prof_shift' /usr/include/asm/hw_irq.h: In function `x86_do_profile': /usr/include/asm/hw_irq.h:203: `prof_pid' undeclared (first use in this function) /usr/include/asm/hw_irq.h:203: (Each undeclared identifier is reported only once /usr/include/asm/hw_irq.h:203: for each function it appears in.) 哪位帮忙看看.thx. 4 搞定了. 在/usr/src/linux目录下: (kernel 2.4.7-10) make mrproper make munuconfig make dep;make clean 然后选上 High Memory Support. 不知道为什么要这个,我才128M内存。:( NAT功能OK。 5 这个模块编译没有问题 ,insmod 这个模块也没有问题。但是我测试了一下,好像他所说的NAT功能根本不起作用 6 感觉你的说法有点问题,所谓iptable,其实可以看作netfilter在用户空间的一个工具。用户通过配置iptable,可以向 netfilter映射一系列规则,netfilter在协议栈中埋下了5个hook点,这些hook点的钩子函数在被调用时会去匹配这些规则,然后把相 应的包做不同的处理。所以iptable规则的实现最后也依赖于hook函数的调用。你所提出的怎么调用iptable的函数我实在是没看明白是什么意 思。。。 7 写了个2.6下的,在FC3/2.6.12-1下测试过。 1) 这个模块工作在LOCAL_OUT上,注意Hook点的优先级在正常NAT的前面。 2) 只把所有本机的TCP连接redirect到某IP,端口不变。 2.4下的那个代码毛病很多,如 1) 没有锁WRITE_LOCK(&ip_nat_lock), 2) 没有判断是否已经对某连接设置过,等等。 修改后曾试图在一个RH9.0上测试,老crash, (也觉得有点奇怪,因为路数和2.6的一样,怀疑2.4的LOCAL_OUT处理不健全?) 编译和调试内核模块太费劲,因此没有继续尝试。 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define DEBUGP(fmt, arg...) printk(fmt, ##arg) static u_int32_t fw_ip; static u_int16_t fw_port; static unsigned int ip_nat_test( unsigned int hooknum, struct sk_buff **skb, const struct net_device *in, const struct net_device *out, int(*okfn)(struct sk_buff*)) { struct ip_conntrack *ct; enum ip_conntrack_info ctinfo; struct ip_nat_range newrange; unsigned int ret=NF_ACCEPT; ct = ip_conntrack_get ( *skb, &ctinfo); if(!ct) return NF_ACCEPT; if(ctinfo != IP_CT_NEW && ctinfo != IP_CT_RELATED) return NF_ACCEPT; if( (*skb)->nh.iph->protocol != IPPROTO_TCP ) return NF_ACCEPT; newrange = ((struct ip_nat_range) { IP_NAT_RANGE_MAP_IPS /*|IP_NAT_RANGE_PROTO_SPECIFIED*/, fw_ip, fw_ip, { fw_port}, { fw_port} }); if(!ip_nat_initialized(ct, HOOK2MANIP(hooknum))){ ret = ip_nat_setup_info (ct,&newrange,hooknum); } return ret; } static struct nf_hook_ops ip_in_ops = { .hook = ip_nat_test, .owner = THIS_MODULE, .pf = PF_INET, .hooknum = NF_IP_LOCAL_OUT, .priority = NF_IP_PRI_NAT_DST-1 }; static int __init init(void) { fw_ip = in_aton("192.168.1.1"); fw_port = __constant_htons(80); return nf_register_hook( &ip_in_ops ); } static void __exit fini(void) { DEBUGP( "ipnat test unregister\n"); nf_unregister_hook (&ip_in_ops); } module_init(init); module_exit(fini); MODULE_LICENSE("GPL"); -------------------- >| >| 8 顺便问一下:在该模块如果工作在NF_IP_PRE_ROUTING上,是不是只要把 .hooknum =NF_IP_LOCAL_OUT,改成 hooknum =NF_IP_PRE_ROUTING了?
阅读(2865) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~