- 論壇徽章:
- 0
|
內(nèi)核版本2.6.30
由于之前一直在2.4版本的內(nèi)核,現(xiàn)在剛剛改用2.6.30,其內(nèi)核一些數(shù)據(jù)結構和實現(xiàn)機制都發(fā)送了改變,因此變寫了幾個小程序去驗證性的跑一下,結果卻發(fā)現(xiàn)了這個另我費解的問題。。。
本意是在測試最新版本內(nèi)核中連接跟蹤模塊的使用情況,在新版本內(nèi)核中通過struct nf_conn代替之前的ip_conntrack結構,但其中主要的一個數(shù)據(jù)結構
struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX]并沒有太大改變。
好了,問題來了,按照道理說這個連接數(shù)組中 IP_CT_DIR_ORIGINAL代表的應該是原始方向的數(shù)據(jù)包,其源地址應該與ip頭部中的源地址是相同的,而IP_CT_DIR_REPLY代表回復方向的數(shù)據(jù)包,其目的地址才應該為本機地址。(這是我之前的理解)
但是在我寫的一個小測試用例中,得到的結果恰恰相反,ORIGINAL方向的連接的目的地址才是ip頭部中的源地址,RELAY方向連接的源地址才是ip頭部中的目的地址,很是困惑,想不明白,難道說是我之前對于連接跟蹤方向一直理解錯了嗎?。。。
現(xiàn)在貼一下我的代碼以及測試結果,有些長,各位看官不要嫌麻煩,因此這個問題真的很困擾我,急求給為牛人解惑,小弟不勝感激。。。。- #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");
- //獲取連接跟蹤數(shù)據(jù)結構
- 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
復制代碼 從這個結果來看,ip首部的源地址和目的地址對應的是relay方向的連接包,通過tcp頭部的端口號也證明了這一點。。。
而且我剛剛看了下ipv4_pkt_to_tuple,它所做的工作的確是從ip首部自動的源地址開始,讀取兩個32字節(jié)的變量,分別賦給tuple中的源地址和目的地址,按照道理說應該不會出錯啊,可是我怎么得出了這么個結果。。。
這個真的很困惑,本人也是剛開始學Netfilter不久,還請各位高手幫忙解答。。。 |
|