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) |