Chinaunix首页 | 论坛 | 博客
  • 博客访问: 11353
  • 博文数量: 2
  • 博客积分: 172
  • 博客等级: 入伍新兵
  • 技术积分: 20
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-08 10:25
文章分类
文章存档

2011年(2)

分类:

2011-07-28 17:15:41

本文由 platinum 在论坛所发,CU技术文章整理,供大家参考学习,转载请注明出处,谢谢。
只贴核心代码了,完整内容见附件

使用方法:
  1. iptables -A FORWARD -m domain --name "unix.net" -j DROP
  2. iptables -A FORWARD -m domain --name "" -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");
 
 
 
阅读(1225) | 评论(0) | 转发(0) |
0

上一篇:网络数据包收发流程(三): e1000网卡和DMA

下一篇:没有了

给主人留下些什么吧!~~