kernel module 禁止ping

本文介绍了一个用于禁止ping特定IP地址的Linux内核模块实现。该模块通过iptables规则拦截并丢弃发往指定IP的ICMP数据包,展示了如何在内核级别进行网络过滤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以下模块相当于禁止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);


huaxi@ubuntu:~/c_projects/kernel_module$ make clean make -C /lib/modules/4.15.0-142-generic/build M=/home/huaxi/c_projects/kernel_module clean make[1]: Entering directory '/usr/src/linux-headers-4.15.0-142-generic' CLEAN /home/huaxi/c_projects/kernel_module/.tmp_versions make[1]: Leaving directory '/usr/src/linux-headers-4.15.0-142-generic' huaxi@ubuntu:~/c_projects/kernel_module$ make make -C /lib/modules/4.15.0-142-generic/build M=/home/huaxi/c_projects/kernel_module modules make[1]: Entering directory '/usr/src/linux-headers-4.15.0-142-generic' CC [M] /home/huaxi/c_projects/kernel_module/ping_stat.o /home/huaxi/c_projects/kernel_module/ping_stat.c:138:21: error: variable ‘ping_fops’ has initializer but incomplete type static const struct proc_ops ping_fops = { ^ /home/huaxi/c_projects/kernel_module/ping_stat.c:139:5: error: unknown field ‘proc_open’ specified in initializer .proc_open = ping_proc_open, ^ /home/huaxi/c_projects/kernel_module/ping_stat.c:139:21: warning: excess elements in struct initializer .proc_open = ping_proc_open, ^ /home/huaxi/c_projects/kernel_module/ping_stat.c:139:21: note: (near initialization for ‘ping_fops’) /home/huaxi/c_projects/kernel_module/ping_stat.c:140:5: error: unknown field ‘proc_read’ specified in initializer .proc_read = seq_read, ^ /home/huaxi/c_projects/kernel_module/ping_stat.c:140:21: warning: excess elements in struct initializer .proc_read = seq_read, ^ /home/huaxi/c_projects/kernel_module/ping_stat.c:140:21: note: (near initialization for ‘ping_fops’) /home/huaxi/c_projects/kernel_module/ping_stat.c:141:5: error: unknown field ‘proc_lseek’ specified in initializer .proc_lseek = seq_lseek, ^ /home/huaxi/c_projects/kernel_module/ping_stat.c:141:21: warning: excess elements in struct initializer .proc_lseek = seq_lseek, ^ /home/huaxi/c_projects/kernel_module/ping_stat.c:141:21: note: (near initialization for ‘ping_fops’) /home/huaxi/c_projects/kernel_module/ping_stat.c:142:5: error: unknown field ‘proc_release’ specified in initializer .proc_release = single_release, ^ /home/huaxi/c_projects/kernel_module/ping_stat.c:142:21: warning: excess elements in struct initializer .proc_release = single_release, ^ /home/huaxi/c_projects/kernel_module/ping_stat.c:142:21: note: (near initialization for ‘ping_fops’) /home/huaxi/c_projects/kernel_module/ping_stat.c: In function ‘ping_stat_init’: /home/huaxi/c_projects/kernel_module/ping_stat.c:152:56: error: passing argument 4 of ‘proc_create’ from incompatible pointer type [-Werror=incompatible-pointer-types] proc_entry = proc_create("ping_stats", 0444, NULL, &ping_fops); ^ In file included from /home/huaxi/c_projects/kernel_module/ping_stat.c:3:0: ./include/linux/proc_fs.h:32:24: note: expected ‘const struct file_operations *’ but argument is of type ‘const struct proc_ops *’ struct proc_dir_entry *proc_create(const char *name, umode_t mode, struct proc_dir_entry *parent, const struct file_operations *proc_fops); ^ cc1: some warnings being treated as errors scripts/Makefile.build:337: recipe for target '/home/huaxi/c_projects/kernel_module/ping_stat.o' failed make[2]: *** [/home/huaxi/c_projects/kernel_module/ping_stat.o] Error 1 Makefile:1584: recipe for target '_module_/home/huaxi/c_projects/kernel_module' failed make[1]: *** [_module_/home/huaxi/c_projects/kernel_module] Error 2 make[1]: Leaving directory '/usr/src/linux-headers-4.15.0-142-generic' Makefile:8: recipe for target 'all' failed make: *** [all] Error
最新发布
08-19
huaxi@ubuntu:~/c_projects/kernel_module$ make make -C /lib/modules/4.15.0-142-generic/build M=/home/huaxi/c_projects/kernel_module modules make[1]: Entering directory '/usr/src/linux-headers-4.15.0-142-generic' CC [M] /home/huaxi/c_projects/kernel_module/ping_stat.o /home/huaxi/c_projects/kernel_module/ping_stat.c: In function ‘hook_func’: /home/huaxi/c_projects/kernel_module/ping_stat.c:66:5: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] struct ping_stat *entry = kmalloc(sizeof(*entry), GFP_ATOMIC); ^ /home/huaxi/c_projects/kernel_module/ping_stat.c: At top level: /home/huaxi/c_projects/kernel_module/ping_stat.c:89:17: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types] .hook = hook_func, ^ /home/huaxi/c_projects/kernel_module/ping_stat.c:89:17: note: (near initialization for ‘nf_ops.hook’) /home/huaxi/c_projects/kernel_module/ping_stat.c: In function ‘seq_show’: /home/huaxi/c_projects/kernel_module/ping_stat.c:115:19: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 4 has type ‘unsigned int’ [-Wformat=] seq_printf(s, "%-15pI4 %-20lu %u\n", ^ /home/huaxi/c_projects/kernel_module/ping_stat.c: In function ‘ping_stat_init’: /home/huaxi/c_projects/kernel_module/ping_stat.c:152:5: error: implicit declaration of function ‘nf_register_hook’ [-Werror=implicit-function-declaration] nf_register_hook(&nf_ops); ^ /home/huaxi/c_projects/kernel_module/ping_stat.c: In function ‘ping_stat_exit’: /home/huaxi/c_projects/kernel_module/ping_stat.c:164:5: error: implicit declaration of function ‘nf_unregister_hook’ [-Werror=implicit-function-declaration] nf_unregister_hook(&nf_ops); ^ cc1: some warnings being treated as errors scripts/Makefile.build:337: recipe for target '/home/huaxi/c_projects/kernel_module/ping_stat.o' failed make[2]: *** [/home/huaxi/c_projects/kernel_module/ping_stat.o] Error 1 Makefile:1584: recipe for target '_module_/home/huaxi/c_projects/kernel_module' failed make[1]: *** [_module_/home/huaxi/c_projects/kernel_module] Error 2 make[1]: Leaving directory '/usr/src/linux-headers-4.15.0-142-generic' Makefile:4: recipe for target 'all' failed make: *** [all] Error 2 huaxi@ubuntu:~/c_projects/kernel_module$
08-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值