以下模块相当于禁止ping某一个IP地址相当于命令:
iptables -A OUTPUT -p ICMP -d 220.181.111.147 -j DROP
代码:
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/string.h>
#include <linux/kmod.h>
#include <linux/vmalloc.h>
#include <linux/workqueue.h>
#include <linux/spinlock.h>
#include <linux/socket.h>
#include <linux/net.h>
#include <linux/in.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/icmp.h>
#include <net/sock.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("xsc");
static struct nf_hook_ops nfho;
static char *parg = "220.181.111.147";
module_param(parg,charp,S_IRUGO);
/// there is not a inet_addr in kernel. use in_aton .
/// or write one.
unsigned int inet_addr(char *str)
{
int a,b,c,d;
char arr[4];
sscanf(str,"%d.%d.%d.%d",&a,&b,&c,&d);
arr[0] = a; arr[1] = b; arr[2] = c; arr[3] = d;
return *(unsigned int*)arr;
}
unsigned int hook_func(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_copy(skb, 1);
struct iphdr *ip;
if (!sk)
return NF_ACCEPT;
ip = ip_hdr(sk);
switch (ip->protocol) {
case IPPROTO_ICMP:
if(ip->daddr == inet_addr(parg))
return NF_DROP;
else
return NF_ACCEPT;
default:
return NF_ACCEPT;
}
}
static int kexec_test_init(void)
{
printk("kexec test start ...\n");
nfho.hook = hook_func;
nfho.owner = NULL;
nfho.pf = PF_INET;
nfho.hooknum = NF_INET_LOCAL_OUT;
nfho.priority = NF_IP_PRI_FIRST;
nf_register_hook(&nfho);
return 0;
}
static void kexec_test_exit(void)
{
printk("kexec test exit ...\n");
nf_unregister_hook(&nfho);
}
module_init(kexec_test_init);
module_exit(kexec_test_exit);