- 論壇徽章:
- 0
|
如題,用Netfilter寫了一段代碼來打印HOST和URI信息,編譯后可正常打印出URL,當(dāng)瀏覽器打開騰訊視頻等一些內(nèi)容的時(shí)候,內(nèi)核就崩潰了,麻煩各位大牛幫忙分析一下,謝謝!
- #ifndef __KERNEL__
- #define __KERNEL__
- #endif
- #ifndef MODULE
- #define MODULE
- #endif
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/skbuff.h>
- #include <linux/in.h>
- #include <linux/ip.h>
- #include <linux/tcp.h>
- #include <linux/icmp.h>
- #include <linux/netdevice.h>
- #include <linux/netfilter.h>
- #include <linux/netfilter_ipv4.h>
- #include <linux/if_arp.h>
- #include <linux/if_ether.h>
- #include <linux/if_packet.h>
- #include <linux/mm.h>
- #include <linux/fs.h>
- #include <linux/uaccess.h>
- #include <asm/uaccess.h>
- //#define DEBUG
- MODULE_LICENSE("GPL");
- char* h_tmp ; //HOST
- char* u_tmp ; //URI
- static struct nf_hook_ops nfho;
- //獲取HOST
- void print_host(const unsigned char* start,unsigned int len)
- {
- char* host_tmp ;
- char* url_tmp ;
- int i = 0;
- int j = 0;
- if (len > 4)
- {
- if (0 == strncmp(start, "GET", 3) || 0 == strncmp(start, "POST", 4))
- {
- /*獲取HOST的值*/
- host_tmp = strstr(start,"Host:");
- if(memcmp(host_tmp,"Host:",5) == 0)
- {
- host_tmp = host_tmp + 6; // 跳過HOST: 這6個(gè)字符
- while(*host_tmp!='\r')
- {
- host_tmp++;
- i++;
- }
- host_tmp -= i;
- h_tmp = kmalloc((i + 1)*sizeof(char),GFP_KERNEL);
- memcpy(h_tmp,host_tmp,i);
- *(h_tmp+i) ='\0';
- printk(">>>Host:%s",h_tmp);
- kfree(h_tmp);
- }
- /*獲取GET后面的參數(shù)*/
- url_tmp = strstr(start,"/"); /*從/開始獲取GET后面的URI部分*/
- while(*url_tmp!=' ') /*到空格的地方結(jié)束*/
- {
- url_tmp++;
- j++;
- }
- url_tmp -=j;
- u_tmp = kmalloc((j + 1)*sizeof(char),GFP_KERNEL);
- memcpy(u_tmp,url_tmp,j);
- *(u_tmp+j) ='\0';
- printk("%s\n",u_tmp);
- kfree(u_tmp);
- }
- }
- }
- /* HOOK函數(shù) */
- unsigned int hook_func(unsigned int hooknum,
- struct sk_buff *skb,
- const struct net_device *in,
- const struct net_device *out,
- int (*okfn)(struct sk_buff *))
- {
- char * payload = NULL;
- struct sk_buff* sb = skb; //定義一個(gè)Linux網(wǎng)絡(luò)數(shù)據(jù)包緩存
- struct iphdr *iph = ip_hdr(sb); //定義一個(gè)ip報(bào)文的數(shù)據(jù)報(bào)頭
- /*讀取文件結(jié)束,過濾掉skb_buf為空以及iph為空的數(shù)據(jù)包*/
- if(sb == NULL)
- return NF_ACCEPT;
- if(iph == NULL)
- return NF_ACCEPT;
- /*判斷是否為TCP協(xié)議,不是TCP協(xié)議的數(shù)據(jù)包直接return NF_ACCEPT*/
- if (iph && iph->protocol && (iph->protocol == IPPROTO_TCP)) {
- //struct tcphdr* tcph = (void *)iph + iph->ihl*4; //TCP報(bào)文的頭部
- struct tcphdr* tcph =(void *)iph +(iph->ihl<<2);
- unsigned int srcport = tcph->source; //源端口
- unsigned int dstport = tcph->dest; //目的端口
- unsigned int ack_seq_num = tcph->ack_seq; //ACK-SEQ的值
- unsigned int seq_num = tcph->seq; //SEQ的值
- unsigned int ip_saddr = ntohl(iph->saddr); //源IP
- unsigned int ip_daddr = ntohl(iph->daddr); //目的IP
- unsigned int len_tot = ntohs(iph->tot_len); //包總長度
- unsigned int len_tcp = len_tot - iph->ihl*4 - tcph->doff*4; //TCP包的長度
- /*判斷tcph是否為空,為空直接返回NF_ACCEPT*******/
- if(tcph == NULL)
- return NF_ACCEPT;
- /*判斷目的端口是否為80************************/
- if (ntohs(dstport) == 80 ) //篩選遠(yuǎn)端口或者目的
- {
- if (0 != skb_linearize(sb))
- return NF_ACCEPT;
- // payload = (char*)iph+(iph->ihl*4) + tcph->doff*4;
- payload = (void *)tcph + (tcph->doff<<2);
- print_host(payload,len_tcp); //DEBUG模式下打印HOST 和 URL
- if (0 == strncmp(payload, "GET", 3) || 0 == strncmp(payload, "POST", 4))
- {
- printk("**************Request**************\n");
- printk("In-Device :%s Out-Device:%s\n",in->name,out->name);
- printk("Src IP :%d.%d.%d.%d \n", (ip_saddr & 0xff000000) >> 24,
- (ip_saddr & 0x00ff0000) >> 16,
- (ip_saddr & 0x0000ff00) >> 8,
- (ip_saddr & 0x000000ff));
- printk("Dst IP :%d.%d.%d.%d \n", (ip_daddr & 0xff000000) >> 24,
- (ip_daddr & 0x00ff0000) >> 16,
- (ip_daddr & 0x0000ff00) >> 8,
- (ip_daddr & 0x000000ff));
- printk("ID :%u\n",ntohs(iph->id));
- printk("Src-Port :%d Dst-Port:%d\n", ntohs(srcport), ntohs(dstport));
- printk("Seq :0x%2x\n", ntohl(seq_num));
- printk("Ack_Seq :0x%2x\n", ntohl(ack_seq_num));
- printk("Tcp len :%u\n",len_tcp);
- printk("Next ack :%u\n",ntohl(seq_num + len_tcp ));
- printk("*******************************\n");
- return NF_ACCEPT;
- }
- return NF_ACCEPT;
- }
- }
- return NF_ACCEPT;
- }
- /* 加載模塊 */
- int init_module() {
- nfho.hook = hook_func; //鉤子函數(shù)指針
- nfho.hooknum = NF_INET_POST_ROUTING; //hook類型
- nfho.pf = PF_INET; //協(xié)議簇,對(duì)于ipv4而言,是PF_INET
- nfho.priority = NF_IP_PRI_FIRST; //優(yōu)先級(jí)
- nf_register_hook(&nfho);
- pr_info("Filter add into kernel!\r\n");
- return 0;
- }
- /* 清除模塊 */
- void cleanup_module() {
- nf_unregister_hook(&nfho);
- pr_info("Filter removed from kernel!\r\n");
- }
復(fù)制代碼 |
|