netfilter例1:禁止訪問某ip地址

netfilter的功能很強大,可以提供類似防火牆那樣的訪問控制,可以更改報文結構,可以新增報文。

本模塊實現這樣一個功能,對禁止訪問指定的ip地址(包括ipv6的和ipv4的)。

 文件名:block_packet.c

/*
* this programe is working as plugin of netfilter 
* which block some special ipv6 and ipv4 packets
*/

#include <linux/netfilter.h>
#include <linux/netfilter_ipv6.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/inet.h>
#include <linux/ip.h>
#include <net/ipv6.h>


MODULE_LICENSE("GPL");
MODULE_AUTHOR("newand");
MODULE_DESCRIPTION("Block some specified ip address");

static long int ip4addr = 0;
module_param(ip4addr, long, S_IRUGO);

#define PRINT(fmt,args...) printk("debug, " fmt, ##args)

/* IP6 Hooks */
/* After promisc drops#include <asm/byteorder.h>
, checksum checks. */
#define NF_IP6_PRE_ROUTING  0
/* If the packet is destined for this box. */
#define NF_IP6_LOCAL_IN     1
/* If the packet is destined for another interface. */
#define NF_IP6_FORWARD      2
/* Packets coming from a local process. */
#define NF_IP6_LOCAL_OUT        3
/* Packets about to hit the wire. */
#define NF_IP6_POST_ROUTING 4

/*
* Hook deal with the the ipv6 packets, block specified address
*/
static unsigned int 
ip6_block(unsigned int hooknum,
				struct sk_buff *skb,
				const struct net_device *in,
				const struct net_device *out,
				int (*okfn)(struct sk_buff*))
{
    struct sk_buff *sk = skb;
	struct ipv6hdr *ip6_hdr = ipv6_hdr(skb);//header

    if(ip6_hdr->version == 6)
    {
        struct in6_addr destip = ip6_hdr->daddr;//destination ip
        //specify the ipv6 address that need block
        if(destip.s6_addr[0] == 0x20 && destip.s6_addr[1] == 0x01 && destip.s6_addr[2] == 0x0d && destip.s6_addr[3] == 0xa8 )
        {
            //if it match the condition then drop it
            return NF_DROP;      
        }
    }
    
    return NF_ACCEPT;      
}


/*
* Hook deal with the the ipv4 packets, block specified address
*/
static unsigned int 
ip4_block(unsigned int hooknum,
				struct sk_buff *skb,
				const struct net_device *in,
				const struct net_device *out,
				int (*okfn)(struct sk_buff*))
{
    struct sk_buff *sk = skb;
	struct iphdr *ip4_hdr = ip_hdr(skb);//header

    if(ip4_hdr->version == 4)
    {
		if(ip4_hdr->daddr == htonl(ip4addr))
        {
            return NF_DROP;      
        }
    }  

    return NF_ACCEPT;    
}

/*Initialize the hook*/
static struct nf_hook_ops nf_out_block =
{
	.hook = ip6_block,
	.hooknum = NF_IP6_POST_ROUTING,
	.pf = PF_INET6,
	.priority = NF_IP6_PRI_FIRST,
};
static struct nf_hook_ops nf_out_4block =
{
	.hook = ip4_block,
	.hooknum = NF_IP6_POST_ROUTING,////acturally here is NF_IP_POST_ROUTING which value is 4
	.pf = PF_INET,
	.priority = NF_IP_PRI_FIRST,
};

/*Initialize the module*/
static int __init ip6_block_init(void)
{
	nf_register_hook(&nf_out_block);
	nf_register_hook(&nf_out_4block);
	return 0; //success
}

/*Clear the module*/
static void __exit ip6_block_exit(void)
{
	nf_unregister_hook(&nf_out_block);
	nf_unregister_hook(&nf_out_4block);
}

module_init(ip6_block_init);
module_exit(ip6_block_exit);

 

makefile:

obj-m += block_packet.o        # 產生nf_change_header 模塊的目標文件
#obj-m += hellomod.o        # 產生hellomod 模塊的目標文件
CURRENT_PATH := $(shell pwd)   #模塊所在的當前路徑
LINUX_KERNEL := $(shell uname -r)    #Linux內核源代碼的當前版本
LINUX_KERNEL_PATH := /usr/src/linux-headers-$(LINUX_KERNEL) #Linux內核源代碼的絕對路徑
all:
	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules   #編譯模塊了
clean:
	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean    #清理


代碼參見:https://github.com/fts2012/netfilterIPv6Header

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章