关于Netfilter中连接跟踪机制的方向问题 Original or Relay
时间:2010-10-26
来源:互联网
内核版本2.6.30
由于之前一直在2.4版本的内核,现在刚刚改用2.6.30,其内核一些数据结构和实现机制都发送了改变,因此变写了几个小程序去验证性的跑一下,结果却发现了这个另我费解的问题。。。
本意是在测试最新版本内核中连接跟踪模块的使用情况,在新版本内核中通过struct nf_conn代替之前的ip_conntrack结构,但其中主要的一个数据结构
struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX]并没有太大改变。
好了,问题来了,按照道理说这个连接数组中 IP_CT_DIR_ORIGINAL代表的应该是原始方向的数据包,其源地址应该与ip头部中的源地址是相同的,而IP_CT_DIR_REPLY代表回复方向的数据包,其目的地址才应该为本机地址。(这是我之前的理解)
但是在我写的一个小测试用例中,得到的结果恰恰相反,ORIGINAL方向的连接的目的地址才是ip头部中的源地址,RELAY方向连接的源地址才是ip头部中的目的地址,很是困惑,想不明白,难道说是我之前对于连接跟踪方向一直理解错了吗?。。。
现在贴一下我的代码以及测试结果,有些长,各位看官不要嫌麻烦,因此这个问题真的很困扰我,急求给为牛人解惑,小弟不胜感激。。。。
复制代码
然后使运行结果;
复制代码
从这个结果来看,ip首部的源地址和目的地址对应的是relay方向的连接包,通过tcp头部的端口号也证明了这一点。。。
而且我刚刚看了下ipv4_pkt_to_tuple,它所做的工作的确是从ip首部自动的源地址开始,读取两个32字节的变量,分别赋给tuple中的源地址和目的地址,按照道理说应该不会出错啊,可是我怎么得出了这么个结果。。。
这个真的很困惑,本人也是刚开始学Netfilter不久,还请各位高手帮忙解答。。。
由于之前一直在2.4版本的内核,现在刚刚改用2.6.30,其内核一些数据结构和实现机制都发送了改变,因此变写了几个小程序去验证性的跑一下,结果却发现了这个另我费解的问题。。。
本意是在测试最新版本内核中连接跟踪模块的使用情况,在新版本内核中通过struct nf_conn代替之前的ip_conntrack结构,但其中主要的一个数据结构
struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX]并没有太大改变。
好了,问题来了,按照道理说这个连接数组中 IP_CT_DIR_ORIGINAL代表的应该是原始方向的数据包,其源地址应该与ip头部中的源地址是相同的,而IP_CT_DIR_REPLY代表回复方向的数据包,其目的地址才应该为本机地址。(这是我之前的理解)
但是在我写的一个小测试用例中,得到的结果恰恰相反,ORIGINAL方向的连接的目的地址才是ip头部中的源地址,RELAY方向连接的源地址才是ip头部中的目的地址,很是困惑,想不明白,难道说是我之前对于连接跟踪方向一直理解错了吗?。。。
现在贴一下我的代码以及测试结果,有些长,各位看官不要嫌麻烦,因此这个问题真的很困扰我,急求给为牛人解惑,小弟不胜感激。。。。
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/kernel.h>
-
- #include <linux/types.h>
- #include <linux/errno.h>
- #include <linux/sched.h>
- #include <linux/slab.h>
- #include <linux/fs.h>
- #include <linux/poll.h>
- #include <linux/spinlock.h>
- #include <linux/ioctl.h>
- #include <linux/proc_fs.h>
- #include <linux/list.h>
- #include <linux/param.h>
- #include <asm/uaccess.h>
- #include <asm/atomic.h>
-
-
- #include <linux/skbuff.h>
- #include <linux/in.h>
- #include <linux/ip.h>
- #include <linux/tcp.h>
- #include <linux/udp.h>
- #include <linux/icmp.h>
- #include <linux/netdevice.h>
- #include <linux/netfilter.h>
- #include <linux/netfilter_ipv4.h>
- #include <linux/netfilter/nf_conntrack_tuple_common.h>
- #include <net/netfilter/nf_conntrack.h>
-
- #include <linux/byteorder/generic.h>
- #include <linux/if_arp.h>
- #include <linux/if_ether.h>
- #include <linux/if_packet.h>
- #include <linux/delay.h>
-
- #define HASH_SIZE 1024
-
- static unsigned int
- conn_hook(unsigned int hook,
- struct sk_buff *skb,
- const struct net_device *indev,
- const struct net_device *outdev,
- int (*okfn)(struct sk_buff *))
- {
- struct nf_conn *conn;
- struct nf_conntrack_tuple_hash tuple_list;
- struct nf_conntrack_tuple orig_tuple;
- struct nf_conntrack_tuple relay_tuple;
- struct iphdr *iph;
- struct tcphdr *tcph;
- u32 ip_saddr;
- u32 ip_daddr;
-
- if(!skb)
- {
- return NF_ACCEPT;
- }
- printk("Hook functions\n");
- //获取连接跟踪数据结构
- conn = (struct nf_conn *)(skb->nfct);
- if(!conn)
- {
- printk("no nf_conntrack \n");
- return NF_ACCEPT;
- }
-
- #if 1
- iph = ip_hdr(skb);
- tcph = tcp_hdr(skb);
- printk("ipv4 src addr: %d.%d.%d.%d,dst addr:%d.%d.%d.%d\n", NIPQUAD(iph->saddr),NIPQUAD(iph->daddr));
- printk("ipv4 tcp src port %d, dst port %d\n",tcph->source,tcph->dest);
- tuple_list = conn->tuplehash[IP_CT_DIR_REPLY];
- orig_tuple = conn->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
- relay_tuple = conn->tuplehash[IP_CT_DIR_REPLY].tuple;
- ip_saddr = orig_tuple.src.u3.ip;
- ip_daddr = orig_tuple.dst.u3.ip;
- printk("ipv4 original src addr: %d.%d.%d.%d,dst src addr: %d.%d.%d.%d\n", NIPQUAD(ip_saddr),NIPQUAD(ip_daddr));
- printk("src original port: %d,dst prot: %d\n",orig_tuple.src.u.tcp.port,orig_tuple.dst.u.tcp.port);
- ip_saddr = relay_tuple.src.u3.ip;
- ip_daddr = relay_tuple.dst.u3.ip;
- printk("ipv4 relay src addr: %d.%d.%d.%d,dst src addr: %d.%d.%d.%d\n", NIPQUAD(ip_saddr),NIPQUAD(ip_daddr));
- printk("src relay port: %d,dst prot: %d\n",relay_tuple.src.u.tcp.port,relay_tuple.dst.u.tcp.port);
- #endif
-
- return NF_ACCEPT;
- }
-
- static struct nf_hook_ops conn_hook_ops = {
- .hook = conn_hook,
- .pf = PF_INET,
- .hooknum = NF_INET_POST_ROUTING,
- .priority = NF_IP_PRI_LAST-1,
- };
-
- static int conn_init(void)
- {
- int ret = 0;
- //注册钩子
- ret = nf_register_hook(&conn_hook_ops);
- if (ret < 0)
- {
- printk("register isatap hook ops error!\n");
- return -ENOMEM;
- }
- return 0;
- }
-
- static void conn_exit(void)
- {
- nf_unregister_hook(&conn_hook_ops);
- printk("Unregister conntrack hook ok\n");
- return;
- }
-
- module_init(conn_init);
- module_exit(conn_exit);
-
- MODULE_LICENSE("GPL");
- Hook functions
- ipv4 src addr: 192.168.1.4,dst addr:192.168.1.221
- ipv4 tcp src port 5632, dst port 2824
- ipv4 original src addr: 192.168.1.221,dst src addr: 192.168.1.4
- src original port: 2824,dst prot: 5632
- ipv4 relay src addr: 192.168.1.4,dst src addr: 192.168.1.221
- src relay port: 5632,dst prot: 2824
- Hook functions
- ipv4 src addr: 192.168.1.4,dst addr:192.168.1.221
- ipv4 tcp src port 5632, dst port 2824
- ipv4 original src addr: 192.168.1.221,dst src addr: 192.168.1.4
- src original port: 2824,dst prot: 5632
- ipv4 relay src addr: 192.168.1.4,dst src addr: 192.168.1.221
- src relay port: 5632,dst prot: 2824
- Hook functions
- ipv4 src addr: 192.168.1.4,dst addr:192.168.1.221
- ipv4 tcp src port 5632, dst port 2824
- ipv4 original src addr: 192.168.1.221,dst src addr: 192.168.1.4
- src original port: 2824,dst prot: 5632
- ipv4 relay src addr: 192.168.1.4,dst src addr: 192.168.1.221
- src relay port: 5632,dst prot: 2824
- Hook functions
- ipv4 src addr: 192.168.1.4,dst addr:192.168.1.221
- ipv4 tcp src port 5632, dst port 10760
- ipv4 original src addr: 192.168.1.221,dst src addr: 192.168.1.4
- src original port: 10760,dst prot: 5632
- ipv4 relay src addr: 192.168.1.4,dst src addr: 192.168.1.221
- src relay port: 5632,dst prot: 10760
而且我刚刚看了下ipv4_pkt_to_tuple,它所做的工作的确是从ip首部自动的源地址开始,读取两个32字节的变量,分别赋给tuple中的源地址和目的地址,按照道理说应该不会出错啊,可是我怎么得出了这么个结果。。。
这个真的很困惑,本人也是刚开始学Netfilter不久,还请各位高手帮忙解答。。。
作者: luoyan_xy 发布时间: 2010-10-26
貌似我忘记考虑端口的网络字节序的问题了。。。。
各位请直接跳过这个问题
各位请直接跳过这个问题

作者: luoyan_xy 发布时间: 2010-10-26
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28