分类: LINUX
2011-07-28 23:09:19
原文地址:【论坛精华帖整理】iptables 版 DNS 匹配模块 作者:CU技术文章
#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"); |