URL过滤器(1)

5126阅读 0评论2011-11-08 lthyxy
分类:LINUX

  1. /*

  2. 其中 * 表示0或者多个小写字母,? 代表1个字母。
  3. 原理就是:挂一个钩子函数去 NF_INET_LOCAL_OUT
  4. 然后分析数据包,如果是TCP/IP包,而且端口是80,而且是80端口(也就是http协议)
  5. 如果是GET方法就把里面的URL提取出来,看是否跟要过滤的匹配.
  6. 要过滤则直接丢弃这个包.
  7. 进一步工作:
  8.   用bitmap过滤.
  9.   如果匹配不是丢弃这个包而是发回一个RST包.
  10. */

  11. #include <linux/module.h>
  12. #include <linux/moduleparam.h>
  13. #include <linux/kernel.h>
  14. #include <linux/skbuff.h>
  15. #include <linux/ip.h>
  16. #include <linux/tcp.h>
  17. #include <net/tcp.h>
  18. #include <net/udp.h>
  19. #include <linux/netfilter.h>
  20. #include <linux/netfilter_ipv4.h>
  21. #include <net/sock.h>
  22. #include <net/netfilter/nf_nat.h>
  23. #include <net/netfilter/nf_nat_helper.h>
  24. #include <net/netfilter/nf_nat_rule.h>
  25. #include <net/netfilter/nf_conntrack.h>
  26. #include <net/netfilter/nf_conntrack_helper.h>
  27. #include <net/netfilter/nf_conntrack_expect.h>

  28. MODULE_LICENSE("GPL");
  29. MODULE_AUTHOR("liutengfei ");
  30. MODULE_DESCRIPTION("URLFilter");
  31. MODULE_VERSION("1.0");
  32. bool f[51][51];
  33. char now[50];

  34. bool url_filter(char *ok)
  35. {
  36.   int ii,i,j,k,lp,ls;
  37.   char *p,*s;//p是带*,?
  38.   char a[3][50] = {
  39.                   "",
  40.                   "*baidu*",
  41.                   "ww?.google.cn"
  42.                   /*
  43.                    这里放入你想过滤的东西
  44.                   */
  45.                  };
  46.   for (ii = 0;; ++ii){
  47.     if (ok[ii] == 'H' && ok[ii+1] == 'o' && ok[ii+2] == 's'
  48.         && ok[ii+3] == 't' && ok[ii+4] == ':'){
  49.        k = 0;
  50.        ii += 6;
  51.        
  52.        while(ok[ii] != '\r' && ok[ii+1] != '\n')
  53.          now[k++] = ok[ii++];
  54.        now[k] = '\0';
  55.        ls = strlen(now);
  56.        for (k = 0; k < 3; ++k){//全部都尝试一次
  57.           
  58.          memset(f,false,sizeof(f));
  59.          f[0][0] = true;
  60.          lp = strlen(a[k]);
  61.          p = a[k];
  62.          s = now;
  63.          
  64.         for (i = 1 ; i <= lp ; i++){
  65.           for (j = 0 ;j <= ls ; j++){
  66.                 if (p[i-1] == '*')
  67.                     f[i][j] = j? (f[i-1][j] | f[i][j-1]) : f[i-1][j];
  68.                 else if (j){
  69.                             if (p[i-1] == '?') f[i][j] = f[i-1][j-1];
  70.                             else f[i][j] = f[i-1][j-1] & (p[i-1] == s[j-1]);
  71.                 }
  72.           }
  73.         }
  74.         
  75.         if (f[lp][ls])
  76.             return true;
  77.        }
  78.        
  79.      return false;
  80.     }
  81.   }
  82.   
  83.   return false;
  84. }

  85. unsigned int check_link_address(unsigned int hooknum, struct sk_buff *skb,
  86.         const struct net_device *in, const struct net_device *out, int(*okfn)(
  87.                 struct sk_buff *))
  88. {
  89.     char * payload = NULL;
  90.     const struct iphdr *iph = NULL;
  91.     struct tcphdr *tcph = NULL;
  92.     __be16 dport;
  93.     int len;
  94.     
  95.     iph = ip_hdr(skb);
  96.     
  97.     if (iph->protocol == IPPROTO_TCP) {
  98.       
  99.         tcph = tcp_hdr(skb);
  100.         dport = tcph->dest;
  101.         len = tcph->doff*4 + iph->ihl*4;
  102.         
  103.         if (likely(ntohs(dport) != 80))
  104.             return NF_ACCEPT;
  105.             
  106.         if (0 != skb_linearize(skb))
  107.             return NF_ACCEPT;
  108.             
  109.         payload = (void *) skb->data + len;//+len后直接到GET
  110.         if (0 == strncmp(payload, "GET", 3)) {
  111.             if (url_filter(payload)){
  112.                 return NF_DROP;
  113.             }
  114.         }
  115.    }
  116.    
  117.   return NF_ACCEPT;
  118. }

  119. static struct nf_hook_ops http_hooks =
  120. {
  121.         .pf = NFPROTO_IPV4,
  122.         .priority = NF_IP_PRI_MANGLE,
  123.         .hooknum = NF_INET_LOCAL_OUT,
  124.         .hook = check_link_address,
  125.         .owner = THIS_MODULE,
  126. };

  127. static int __init url_init(void)
  128. {
  129.     nf_register_hook(&http_hooks);
  130.     return 0;
  131. }

  132. static void __exit url_cleanup(void)
  133. {
  134.     nf_unregister_hook(&http_hooks);
  135. }

  136. module_init(url_init);
  137. module_exit(url_cleanup);
上一篇:struct sk_buff在内核2.6.24版本以后的扩展变化
下一篇:hbase框架介绍