亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 3333 | 回復(fù): 8
打印 上一主題 下一主題

[網(wǎng)絡(luò)子系統(tǒng)] 請(qǐng)教一個(gè)問題,Netfilter過濾URL,遇到視頻類網(wǎng)站內(nèi)核崩潰 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2014-06-02 10:05 |只看該作者 |倒序?yàn)g覽
如題,用Netfilter寫了一段代碼來打印HOST和URI信息,編譯后可正常打印出URL,當(dāng)瀏覽器打開騰訊視頻等一些內(nèi)容的時(shí)候,內(nèi)核就崩潰了,麻煩各位大牛幫忙分析一下,謝謝!
  1. #ifndef __KERNEL__
  2. #define __KERNEL__
  3. #endif
  4. #ifndef MODULE
  5. #define MODULE
  6. #endif

  7. #include   <linux/module.h>
  8. #include   <linux/kernel.h>
  9. #include   <linux/skbuff.h>
  10. #include   <linux/in.h>
  11. #include   <linux/ip.h>
  12. #include   <linux/tcp.h>
  13. #include   <linux/icmp.h>
  14. #include   <linux/netdevice.h>
  15. #include   <linux/netfilter.h>
  16. #include   <linux/netfilter_ipv4.h>
  17. #include   <linux/if_arp.h>
  18. #include   <linux/if_ether.h>
  19. #include   <linux/if_packet.h>
  20. #include   <linux/mm.h>
  21. #include   <linux/fs.h>
  22. #include   <linux/uaccess.h>
  23. #include   <asm/uaccess.h>

  24. //#define    DEBUG

  25. MODULE_LICENSE("GPL");

  26. char* h_tmp ;           //HOST
  27. char* u_tmp ;           //URI


  28. static struct nf_hook_ops nfho;


  29. //獲取HOST
  30. void print_host(const unsigned char* start,unsigned int len)
  31. {
  32.         char* host_tmp ;
  33.         char* url_tmp ;
  34.         int i = 0;
  35.         int j = 0;
  36.         if (len > 4)
  37.         {
  38.            if (0 == strncmp(start, "GET", 3) || 0 == strncmp(start, "POST", 4))
  39.            {
  40.                 /*獲取HOST的值*/
  41.                    host_tmp = strstr(start,"Host:");
  42.                    if(memcmp(host_tmp,"Host:",5) == 0)
  43.                    {
  44.                            host_tmp = host_tmp + 6;               // 跳過HOST: 這6個(gè)字符
  45.                            while(*host_tmp!='\r')
  46.                            {
  47.                                    host_tmp++;
  48.                                    i++;
  49.                            }
  50.                                 host_tmp -= i;
  51.                                 h_tmp = kmalloc((i + 1)*sizeof(char),GFP_KERNEL);
  52.                                 memcpy(h_tmp,host_tmp,i);
  53.                                 *(h_tmp+i) ='\0';
  54.                                 printk(">>>Host:%s",h_tmp);
  55.                                 kfree(h_tmp);
  56.                    }
  57.                 /*獲取GET后面的參數(shù)*/
  58.                            url_tmp = strstr(start,"/");            /*從/開始獲取GET后面的URI部分*/
  59.                            while(*url_tmp!=' ')                                /*到空格的地方結(jié)束*/
  60.                                 {
  61.                                    url_tmp++;
  62.                                    j++;
  63.                                 }
  64.                            url_tmp -=j;
  65.                            u_tmp = kmalloc((j + 1)*sizeof(char),GFP_KERNEL);
  66.                            memcpy(u_tmp,url_tmp,j);
  67.                            *(u_tmp+j) ='\0';
  68.                            printk("%s\n",u_tmp);
  69.                            kfree(u_tmp);
  70.                    }
  71.          }
  72. }

  73. /* HOOK函數(shù) */
  74. unsigned int hook_func(unsigned int hooknum,
  75.                                            struct sk_buff *skb,
  76.                                            const struct net_device *in,
  77.                                            const struct net_device *out,
  78.                                            int (*okfn)(struct sk_buff *))
  79. {
  80.         char * payload = NULL;
  81.         struct sk_buff* sb = skb;                                                                                        //定義一個(gè)Linux網(wǎng)絡(luò)數(shù)據(jù)包緩存
  82.         struct iphdr *iph = ip_hdr(sb);                                                                        //定義一個(gè)ip報(bào)文的數(shù)據(jù)報(bào)頭

  83. /*讀取文件結(jié)束,過濾掉skb_buf為空以及iph為空的數(shù)據(jù)包*/
  84.         if(sb == NULL)
  85.           return NF_ACCEPT;
  86.         if(iph == NULL)
  87.           return NF_ACCEPT;

  88. /*判斷是否為TCP協(xié)議,不是TCP協(xié)議的數(shù)據(jù)包直接return NF_ACCEPT*/
  89.         if (iph && iph->protocol && (iph->protocol == IPPROTO_TCP)) {
  90.                 //struct tcphdr* tcph = (void *)iph + iph->ihl*4;                           //TCP報(bào)文的頭部
  91.                 struct tcphdr* tcph =(void *)iph +(iph->ihl<<2);
  92.                 unsigned int srcport = tcph->source;                                                 //源端口
  93.                 unsigned int dstport = tcph->dest;                                                   //目的端口
  94.                 unsigned int ack_seq_num = tcph->ack_seq;                                                   //ACK-SEQ的值
  95.                 unsigned int seq_num = tcph->seq;                                                              //SEQ的值
  96.                 unsigned int ip_saddr = ntohl(iph->saddr);                                                  //源IP
  97.                 unsigned int ip_daddr = ntohl(iph->daddr);                                                  //目的IP
  98.                 unsigned int len_tot = ntohs(iph->tot_len);                                                  //包總長度
  99.                 unsigned int len_tcp = len_tot - iph->ihl*4 - tcph->doff*4;         //TCP包的長度

  100. /*判斷tcph是否為空,為空直接返回NF_ACCEPT*******/
  101.             if(tcph == NULL)
  102.                return NF_ACCEPT;
  103. /*判斷目的端口是否為80************************/
  104.                 if (ntohs(dstport) == 80 )                                                                                   //篩選遠(yuǎn)端口或者目的
  105.                 {
  106.                         if (0 != skb_linearize(sb))
  107.                            return NF_ACCEPT;

  108. //                   payload = (char*)iph+(iph->ihl*4) + tcph->doff*4;
  109.                    payload = (void *)tcph + (tcph->doff<<2);
  110.                    print_host(payload,len_tcp);                                                                                     //DEBUG模式下打印HOST 和 URL

  111.                     if (0 == strncmp(payload, "GET", 3) || 0 == strncmp(payload, "POST", 4))
  112.                          {

  113.                                          printk("**************Request**************\n");
  114.                                          printk("In-Device :%s         Out-Device:%s\n",in->name,out->name);
  115.                                          printk("Src IP    :%d.%d.%d.%d \n", (ip_saddr & 0xff000000) >> 24,
  116.                                                                                                                   (ip_saddr & 0x00ff0000) >> 16,
  117.                                                                                                                   (ip_saddr & 0x0000ff00) >> 8,
  118.                                                                                                                   (ip_saddr & 0x000000ff));
  119.                                          printk("Dst IP    :%d.%d.%d.%d \n", (ip_daddr & 0xff000000) >> 24,
  120.                                                                                                                  (ip_daddr & 0x00ff0000) >> 16,
  121.                                                                                                                 (ip_daddr & 0x0000ff00) >> 8,
  122.                                                                                                                  (ip_daddr & 0x000000ff));
  123.                                          printk("ID        :%u\n",ntohs(iph->id));
  124.                                          printk("Src-Port  :%d         Dst-Port:%d\n", ntohs(srcport), ntohs(dstport));
  125.                                          printk("Seq       :0x%2x\n", ntohl(seq_num));
  126.                                          printk("Ack_Seq   :0x%2x\n", ntohl(ack_seq_num));
  127.                                          printk("Tcp len   :%u\n",len_tcp);
  128.                                          printk("Next ack  :%u\n",ntohl(seq_num + len_tcp ));
  129.                                          printk("*******************************\n");
  130.                                          return NF_ACCEPT;
  131.                          }
  132.                          return NF_ACCEPT;
  133.                 }
  134.         }

  135.         return NF_ACCEPT;
  136. }

  137. /* 加載模塊 */
  138. int init_module() {
  139.         nfho.hook = hook_func;                                     //鉤子函數(shù)指針
  140.         nfho.hooknum = NF_INET_POST_ROUTING;    //hook類型
  141.         nfho.pf = PF_INET;                                            //協(xié)議簇,對(duì)于ipv4而言,是PF_INET
  142.         nfho.priority = NF_IP_PRI_FIRST;              //優(yōu)先級(jí)
  143.         nf_register_hook(&nfho);

  144.         pr_info("Filter add into kernel!\r\n");
  145.         return 0;
  146. }
  147. /* 清除模塊 */
  148. void cleanup_module() {
  149.         nf_unregister_hook(&nfho);
  150.         pr_info("Filter removed from kernel!\r\n");
  151. }
復(fù)制代碼

論壇徽章:
36
IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯(lián)賽之廣東
日期:2016-04-16 19:59:32IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
2 [報(bào)告]
發(fā)表于 2014-06-02 22:52 |只看該作者
回復(fù) 1# smillers
其實(shí)如果內(nèi)核 oops 了,應(yīng)該有一些有用的新的。

簡單看了一下你解析 TCP 報(bào)文的問題,首先一個(gè)問題沒有考慮,就是分片包的問題。如果是 TCP 的分片報(bào)文,那么根本就沒有所謂的 tcp header 讓你解引用了。

此外,一個(gè)吹毛求疵的小問題:
        if(iph == NULL)
          return NF_ACCEPT;

/*判斷是否為TCP協(xié)議,不是TCP協(xié)議的數(shù)據(jù)包直接return NF_ACCEPT*/
        if (iph && iph->protocol && (iph->protocol == IPPROTO_TCP)) {

最后那個(gè)條件判斷,可以簡化了為

if (iph->protocol == IPPROTO_TCP)

你 iph 都判斷過了,沒必要多兩個(gè)冗余的條件。

   

論壇徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辭舊歲徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亞洲杯之卡塔爾
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08處女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技術(shù)圖書徽章
日期:2014-03-25 09:00:29
3 [報(bào)告]
發(fā)表于 2014-06-03 08:38 |只看該作者
具體可能還得通過kdump,或者串口抓點(diǎn)信息來看。
也可能是printk打印太頻繁導(dǎo)致?

論壇徽章:
0
4 [報(bào)告]
發(fā)表于 2014-06-03 10:42 |只看該作者
Godbach 發(fā)表于 2014-06-02 22:52
回復(fù) 1# smillers
其實(shí)如果內(nèi)核 oops 了,應(yīng)該有一些有用的新的。


版主說的這個(gè),可以線性化一下

論壇徽章:
0
5 [報(bào)告]
發(fā)表于 2014-06-05 19:12 |只看該作者
本帖最后由 huangbanban 于 2014-06-05 19:17 編輯

host_tmp = strstr(start,"Host:");
url_tmp = strstr(start,"/");
strstr函數(shù)的使用讓我有些不安,沒有限制查找的范圍,因?yàn)槭蔷W(wǎng)絡(luò)數(shù)據(jù)包
要是能夠?qū)崿F(xiàn)這樣一個(gè)函數(shù)再使用,也許更安心一些吧
strnstr(char* s1, char*s2, int pos)

論壇徽章:
0
6 [報(bào)告]
發(fā)表于 2014-06-09 10:18 |只看該作者
本帖最后由 smillers 于 2014-06-09 10:23 編輯

好像是strstr()函數(shù)的問題,重寫了一個(gè)函數(shù),解決了,現(xiàn)在已經(jīng)不崩潰了回復(fù) 5# huangbanban


   

論壇徽章:
0
7 [報(bào)告]
發(fā)表于 2014-06-09 10:23 |只看該作者
好像是strstr()函數(shù)的問題你,重寫了一個(gè),解決了,現(xiàn)在已經(jīng)不崩潰了回復(fù) 5# huangbanban


   

論壇徽章:
0
8 [報(bào)告]
發(fā)表于 2014-06-09 10:41 |只看該作者
恭喜恭喜,呵呵

論壇徽章:
0
9 [報(bào)告]
發(fā)表于 2015-03-25 09:25 |只看該作者
大哥,strstr是什么問題呀?
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP