- 论坛徽章:
- 0
|
只是获取的步骤,基本上看看DNS协议的人都会写。如果要做URL过滤的话,拿到URL后可以自己
添加匹配过程,最终DROP或者ACCEPT就行,献丑了。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define STR_IP(str, n) sprintf((str), "%u.%u.%u.%u", (n) & 0xff, ((n)>> 8) & 0xff, ((n)>>16) & 0xff, ((n)>>24) & 0xff)
#define DNS_PORT 53
#define UDP_HEAD_LEN 8
#define DNS_HEAD_LEN 12
static int get_name(const char* addr, char* szBuff, int len);
static unsigned int cme_hook(unsigned int hook,
struct sk_buff **pskb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct sk_buff * skb = *pskb;
char szurl[1024] = {0};
struct udphdr *uhead;
unsigned char* udp_data = 0;
u_int16_t src_port, dst_port;
u_int16_t udp_len = 0;
u_int8_t flag;
char src[20] = {0},dst[20]={0};
if(!skb)return NF_ACCEPT;
if (skb->protocol != htons(ETH_P_IP))
return NF_ACCEPT;
if(skb->nh.iph->protocol != IPPROTO_UDP)
return NF_ACCEPT;
STR_IP(src, skb->nh.iph->saddr );
STR_IP(dst, skb->nh.iph->daddr);
uhead = (struct udphdr *)(skb->data + (skb->nh.iph->ihl * 4));
src_port = ntohs(uhead->source);
dst_port = ntohs(uhead->dest);
udp_len = ntohs(uhead->len) - UDP_HEAD_LEN;
if(udp_len %s:%u, len = %u, type:%s\n",
src, src_port, dst, dst_port, udp_len, flag ? "response" : "query");
return NF_ACCEPT;
}
static struct nf_hook_ops ops =
{
.hook = cme_hook,
.owner = THIS_MODULE,
.pf = PF_INET,
.hooknum = NF_IP_POST_ROUTING,
.priority = NF_IP_PRI_FIRST,
};
int init(void)
{
nf_register_hook(&ops);
printk("cme hook registering.......\n");
return 0;
}
void finish(void)
{
nf_unregister_hook(&ops);
printk("removing cme hook.......\n");
}
module_init(init)
module_exit(finish)
MODULE_LICENSE("GPL");
MODULE_VERSION("1.0");
int get_name(const char* addr, char* szBuff, int len)
{
const char * p = addr;
int pos = 0;
// "03 w w w 03 1 2 6 03 c o m" means "www.126.com"
while(p && (*p > 0))
{
if(*p > len)
{
printk("error url len:%d\n", *p);
break;
}
strncpy(szBuff + pos, p + 1, *p);
pos += *p;
szBuff[pos] = '.';
pos++;
len -= (*p + 1);
p += (*p + 1);
}
if(pos > 0)
szBuff[pos - 1] = '\0';
return pos;
}
编译脚本:
MODULE_NAME:=dns_filter
obj-m:=$(MODULE_NAME).o
$(MODULE_NAME)-objs := dns_hook.o
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -fr *.ko *.o *.cmd $(MODULE_NAME).mod.c
cu段兄的帖子:
http://linux.chinaunix.net/bbs/thread-1149646-1-1.html
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/76292/showart_2125123.html |
|