netfilter源码(net filter)
本文目录一览:
- 1、Linux 内核 net/bridge/netfilter源代码分析求助
- 2、跪求linux 防火墙 源程序,基于netfilter & iptables 用户可以动态设置过滤规则,跪谢~~~
- 3、怎么看netfilter.h头文件内容
- 4、修改netfilter数据包
- 5、2.6内核源码netfilter中NF_INET_PRE_ROUTING跟NF_IP_PRE_ROUTING啥关系?
Linux 内核 net/bridge/netfilter源代码分析求助
netfilter这种专业级问题,就别来知道了,我们研究这玩意 都刻意回避外传,一个劲往svn里合呢,你还上来问! 你看看有论坛啥的没,那些版主啦 有空的技术牛人能写博客,你搜搜去吧。
跪求linux 防火墙 源程序,基于netfilter & iptables 用户可以动态设置过滤规则,跪谢~~~
ConfigServer Security Firewall 这套软件就是免费开源的,可以装到linux系统上。
朝暮数据客服中心
怎么看netfilter.h头文件内容
首先,定义一个nf_hook_ops结构体,选定要挂取的钩子点
static struct nf_hook_ops nfho = {
.hook = my_hookfn,
.pf = PF_INET,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_FIRST,
.owner = THIS_MODULE,
};
第二步,写好my_hookfn这个hook函数,即要实现的功能(此处是将其接收包的源IP地址改成100.100.100.100.
unsigned int my_hookfn(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;
iph = ip_hdr(skb);
/* log the original src IP */
printk(KERN_INFO"src IP %pI4\n", iph-saddr);
/* modify the packet's src IP */
iph-saddr = in_aton("100.100.100.100");
return NF_ACCEPT;
}
注册函数会把nf_hook_ops放入nf_hooks相应的位置中。
int nf_register_hook(struct nf_hook_ops *reg)
{
struct nf_hook_ops *elem;
int err;
err = mutex_lock_interruptible(nf_hook_mutex);
if (err 0)
return err;
list_for_each_entry(elem, nf_hooks[reg-pf][reg-hooknum], list) {
if (reg-priority elem-priority)
break;
}
list_add_rcu(reg-list, elem-list.prev); /* 把netfilter实例添加到队列中 */
mutex_unlock(nf_hook_mutex);
return 0;
}
注销函数
void nf_unregister_hook(struct nf_hook_ops *reg)
{
mutex_lock(nf_hook_mutex);
list_del_rcu(reg-list); /* 把netfilter实例从队列中删除 */
mutex_unlock(nf_hook_mutex);
synchronize_net();
}
然后进行模块的注册与注销
static int __init http_init(void)
{
if (nf_register_hook(nfho)) {
printk(KERN_ERR"nf_register_hook() failed\n");
return -1;
}
return 0;
}
static void __exit http_exit(void)
{
nf_unregister_hook(nfho);
}
这是完整的源代码,并取名http.c
#include linux/netfilter.h
#include linux/init.h
#include linux/module.h
#include linux/netfilter_ipv4.h
#include linux/ip.h
#include linux/inet.h
/**
* Hook function to be called.
* We modify the packet's src IP.
*/
unsigned int my_hookfn(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;
iph = ip_hdr(skb);
/* log the original src IP */
printk(KERN_INFO"src IP %pI4\n", iph-saddr);
/* modify the packet's src IP */
iph-saddr = in_aton("100.100.100.100");
return NF_ACCEPT;
}
/* A netfilter instance to use */
static struct nf_hook_ops nfho = {
.hook = my_hookfn,
.pf = PF_INET,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_FIRST,
.owner = THIS_MODULE,
};
static int __init http_init(void)
{
if (nf_register_hook(nfho)) {
printk(KERN_ERR"nf_register_hook() failed\n");
return -1;
}
return 0;
}
static void __exit http_exit(void)
{
nf_unregister_hook(nfho);
}
module_init(http_init);
module_exit(http_exit);
MODULE_AUTHOR("flyking");
MODULE_LICENSE("GPL");
然后编写Makefile,此处是Makefile源码
ifneq ($(KERNELRELEASE),)
obj-m += http.o
else
PWD := $(shell pwd)
KVER := $(shell uname -r)
KDIR := /lib/modules/$(KVER)/build
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
all:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -rf *.o *.mod.c *.ko *.symvers *.order *.makers
endif
8
编写好了http.c和Makefile,将其用动态模块的方式挂载在Linux系统内核。进行编译make,即可生成所需要的http.ko文件
修改netfilter数据包
01.static unsigned int send(unsigned int hooknum, struct sk_buff * skb,
02. const struct net_device * in, const struct net_device * out,
03. int (*okfn)(struct sk_buff *))
04.{
05. struct iphdr* iph;
06. struct udphdr* udph;
07. struct tcphdr* tcph;
08. unsigned char *data = NULL;
09. int datalen;
10. int ret = 0;
11.
12. __u16 dst_port,src_port;
13. __be32 myip;
14.
15. if(skb)
16. {
17. iph = (struct iphdr *)skb_header_pointer(skb,0,0,NULL);
18. if(iph)
19. {
20. if(strcmp(dstIP,"")!=0strcmp(dstIP,"0.0.0.0")!=0)
21. {
22. myip = in_aton(dstIP);
23. if(iph-daddr == myip)
24. {
25. if(iph-protocol == IPPROTO_UDP)
26. {
27. udph = (struct udphdr *)skb_header_pointer(skb,IP_HDR_LEN,0,NULL);
28. data = (char *)skb_header_pointer(nskb,TOT_HDR_LEN,0,NULL);
29. datalen = ntohs(iph-tot_len)-TOT_HDR_LEN;
30. }
31. else if(iph-protocol == IPPROTO_TCP)
32. {
33. tcph = (struct tcphdr *)skb_header_pointer(skb,IP_HDR_LEN,0,NULL);
34. int offlen = IP_HDR_LEN + tcph-doff*4;
35. data = (char *)skb_header_pointer(skb,offlen,0,NULL);
36. datalen = ntohs (iph-tot_len)-offlen;
37. }
38.
39. int j;
40. for(j=0; jdatalen; j++)
41. {
42. data[j] += 1;
43. }
44. printk("encrypted\n");
45. iph-check = 0;
46. ip_send_check(iph);
47. }
48. }
49. }
50. }
51. return NF_ACCEPT;
52.}
01.static unsigned int send(unsigned int hooknum, struct sk_buff * skb,
02. const struct net_device * in, const struct net_device * out,
03. int (*okfn)(struct sk_buff *))
04.{
05. struct iphdr* iph;
06. struct udphdr* udph;
07. struct tcphdr* tcph;
08. unsigned char *data = NULL;
09. int datalen;
10. int ret = 0;
11.
12. __u16 dst_port,src_port;
13. __be32 myip;
14.
15. if(skb)
16. {
17. iph = (struct iphdr *)skb_header_pointer(skb,0,0,NULL);
18. if(iph)
19. {
20. if(strcmp(dstIP,"")!=0strcmp(dstIP,"0.0.0.0")!=0)
21. {
22. myip = in_aton(dstIP);
23. if(iph-daddr == myip)
24. {
25. if(iph-protocol == IPPROTO_UDP)
26. {
27. udph = (struct udphdr *)skb_header_pointer(skb,IP_HDR_LEN,0,NULL);
28. data = (char *)skb_header_ pointer(nskb,TOT_HDR_LEN,0,NULL);
29. datalen = ntohs(iph-tot_len)-TOT_HDR_LEN;
30. }
31. else if(iph-protocol == IPPROTO_TCP)
32. {
33. tcph = (struct tcphdr *)skb_header_pointer(skb,IP_HDR_LEN,0,NULL);
34. int offlen = IP_HDR_LEN + tcph-doff*4;
35. data = (char *)skb_header_pointer(skb,offlen,0,NULL);
36. datalen = ntohs (iph-tot_len)-offlen;
37. }
38.
39. int j;
40. for(j=0; jdatalen; j++)
41. {
42. data[j] += 1;
43. }
44. printk("encrypted\n");
45. iph-check = 0;
46. ip_send_check(iph);
47. }
48. }
49. }
50. }
51. return NF_ACCEPT;
52.}
2.6内核源码netfilter中NF_INET_PRE_ROUTING跟NF_IP_PRE_ROUTING啥关系?
认真看头文件,头文件上面有说明。
两者的值是一样的。
NF_IP_*和NF_IP6_*都不能用在新的内核,内核/内核模块要用NF_INET_*。
我记得没错的话,这种转变是从2.6.25的内核开始,当时还没有NF_INET_*,全部都用NF_IP系列的。
现在,NF_IP_*只是为了兼容用户程序而保留的,一般应该用NF_INET_*。
你可以理解成变量换了个名字。