- 论坛徽章:
- 0
|
只贴核心代码了,完整内容见附件
使用方法:
- iptables -A FORWARD -m domain --name "www.chinaunix.net" -j DROP
- iptables -A FORWARD -m domain --name "www.163.com" -j DROP
复制代码
ipt_domain.c
#if defined(MODVERSIONS)
#include <linux/modversions.h>
#endif
#include <linux/module.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
# include <linux/netfilter/x_tables.h>
# define ipt_register_match xt_register_match
# define ipt_unregister_match xt_unregister_match
# define ipt_match xt_match
#else
# include <linux/netfilter_ipv4/ip_tables.h>
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) */
#include <linux/types.h>
#include <linux/skbuff.h>
#include "ipt_domain.h"
#include <net/udp.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
static bool
#else
static int
#endif
match(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
const struct xt_match *mymatch,
const void *matchinfo,
int offset,
unsigned int myprotoff,
#else
const void *matchinfo,
int offset,
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
const void *hdr,
u_int16_t datalen,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
bool *hotdrop)
#else
int *hotdrop)
#endif
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
struct iphdr *ip = ip_hdr(skb);
#else
struct iphdr *ip = skb->nh.iph;
#endif
struct udphdr *udph;
const struct ipt_domain_info *info = matchinfo;
if (offset || ip->protocol != IPPROTO_UDP)
return 0;
udph = (char *)ip + ip->ihl*4;
return ( (ntohs(udph->source) == 53 || ntohs(udph->dest) == 53)
&& (udph->len >= (8 + 12 + info->len + 5))
&& !strcmp(info->name,
(char *)((void *)udph + ntohs(udph->len) - info->len - 5))
);
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
static bool
#else
static int
#endif
checkentry(const char *tablename,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
const void *ip,
const struct xt_match *mymatch,
#else
const struct ipt_ip *ip,
#endif
void *matchinfo,
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18)
unsigned int matchsize,
#endif
unsigned int hook_mask)
{
// if (matchsize != IPT_ALIGN(sizeof(struct ipt_domain_info)))
// return 0;
return 1;
}
static struct ipt_match domain_match = {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
{ NULL, NULL },
"domain",
&match,
&checkentry,
NULL,
THIS_MODULE
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
.name = "domain",
.match = &match,
.checkentry = &checkentry,
.me = THIS_MODULE,
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) */
.name = "domain",
.match = &match,
.family = AF_INET,
.matchsize = XT_ALIGN(sizeof(struct ipt_domain_info)),
.checkentry = &checkentry,
.me = THIS_MODULE,
#endif
};
static int __init init(void)
{
return ipt_register_match(&domain_match);
}
static void __exit fini(void)
{
ipt_unregister_match(&domain_match);
}
module_init(init);
module_exit(fini);
MODULE_AUTHOR("Platinum, bbs.chinaunix.net");
MODULE_DESCRIPTION("A module to match DOMAIN. VERSION: 0.0.3");
MODULE_LICENSE("GPL"); |
[ 本帖最后由 platinum 于 2009-12-18 18:49 编辑 ] |
评分
-
查看全部评分
|