- /*
-
-
其中 * 表示0或者多个小写字母,? 代表1个字母。
-
原理就是:挂一个钩子函数去 NF_INET_LOCAL_OUT
-
然后分析数据包,如果是TCP/IP包,而且端口是80,而且是80端口(也就是http协议)
-
如果是GET方法就把里面的URL提取出来,看是否跟要过滤的匹配.
-
要过滤则直接丢弃这个包.
-
进一步工作:
-
用bitmap过滤.
-
如果匹配不是丢弃这个包而是发回一个RST包.
-
*/
-
-
#include <linux/module.h>
-
#include <linux/moduleparam.h>
-
#include <linux/kernel.h>
-
#include <linux/skbuff.h>
-
#include <linux/ip.h>
-
#include <linux/tcp.h>
-
#include <net/tcp.h>
-
#include <net/udp.h>
-
#include <linux/netfilter.h>
-
#include <linux/netfilter_ipv4.h>
-
#include <net/sock.h>
-
#include <net/netfilter/nf_nat.h>
-
#include <net/netfilter/nf_nat_helper.h>
-
#include <net/netfilter/nf_nat_rule.h>
-
#include <net/netfilter/nf_conntrack.h>
-
#include <net/netfilter/nf_conntrack_helper.h>
-
#include <net/netfilter/nf_conntrack_expect.h>
-
-
MODULE_LICENSE("GPL");
-
MODULE_AUTHOR("liutengfei
" ); -
MODULE_DESCRIPTION("URLFilter");
-
MODULE_VERSION("1.0");
-
bool f[51][51];
-
char now[50];
-
-
bool url_filter(char *ok)
-
{
-
int ii,i,j,k,lp,ls;
-
char *p,*s;//p是带*,?的
-
char a[3][50] = {
-
"",
-
"*baidu*",
-
"ww?.google.cn"
-
/*
-
这里放入你想过滤的东西
-
*/
-
};
-
for (ii = 0;; ++ii){
-
if (ok[ii] == 'H' && ok[ii+1] == 'o' && ok[ii+2] == 's'
-
&& ok[ii+3] == 't' && ok[ii+4] == ':'){
-
k = 0;
-
ii += 6;
-
-
while(ok[ii] != '\r' && ok[ii+1] != '\n')
-
now[k++] = ok[ii++];
-
now[k] = '\0';
-
ls = strlen(now);
-
for (k = 0; k < 3; ++k){//全部都尝试一次
-
-
memset(f,false,sizeof(f));
-
f[0][0] = true;
-
lp = strlen(a[k]);
-
p = a[k];
-
s = now;
-
-
for (i = 1 ; i <= lp ; i++){
-
for (j = 0 ;j <= ls ; j++){
-
if (p[i-1] == '*')
-
f[i][j] = j? (f[i-1][j] | f[i][j-1]) : f[i-1][j];
-
else if (j){
-
if (p[i-1] == '?') f[i][j] = f[i-1][j-1];
-
else f[i][j] = f[i-1][j-1] & (p[i-1] == s[j-1]);
-
}
-
}
-
}
-
-
if (f[lp][ls])
-
return true;
-
}
-
-
return false;
-
}
-
}
-
-
return false;
-
}
-
-
unsigned int check_link_address(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;
-
const struct iphdr *iph = NULL;
-
struct tcphdr *tcph = NULL;
-
__be16 dport;
-
int len;
-
-
iph = ip_hdr(skb);
-
-
if (iph->protocol == IPPROTO_TCP) {
-
-
tcph = tcp_hdr(skb);
-
dport = tcph->dest;
-
len = tcph->doff*4 + iph->ihl*4;
-
-
if (likely(ntohs(dport) != 80))
-
return NF_ACCEPT;
-
-
if (0 != skb_linearize(skb))
-
return NF_ACCEPT;
-
-
payload = (void *) skb->data + len;//+len后直接到GET
-
if (0 == strncmp(payload, "GET", 3)) {
-
if (url_filter(payload)){
-
return NF_DROP;
-
}
-
}
-
}
-
-
return NF_ACCEPT;
-
}
-
-
static struct nf_hook_ops http_hooks =
-
{
-
.pf = NFPROTO_IPV4,
-
.priority = NF_IP_PRI_MANGLE,
-
.hooknum = NF_INET_LOCAL_OUT,
-
.hook = check_link_address,
-
.owner = THIS_MODULE,
-
};
-
-
static int __init url_init(void)
-
{
-
nf_register_hook(&http_hooks);
-
return 0;
-
}
-
-
static void __exit url_cleanup(void)
-
{
-
nf_unregister_hook(&http_hooks);
-
}
-
-
module_init(url_init);
- module_exit(url_cleanup);