LINUX nf_register_hooks NF_HOOK以及模块实现以及模块的装载和卸载

最近一个项目需要检查TCP/IP包,于是就有了它

  1. HOOK代码编写
    下面展示一些 内联代码片
// 钩子回调函数 
unsigned int myHookCallBack(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
···············
}
struct nf_hook_ops g_stMyNfHook = 
{
    .hook = myHookCallBack,                 //回调函数
    .pf             = PF_INET,              //协议类型
    .hooknum        = NF_BR_LOCAL_OUT,    //hook注册点
    .priority       = NF_IP_PRI_FIRST,      //优先级
};
static void hello_NfHook_Init(void)
{   
	int iRet;
	printk(KERN_ALERT "hello ini success!\n");
    
	iRet = nf_register_hook(&g_stMyNfHook);	// 注册
    if (0 != iRet)
    {
        printk(KERN_WARNING "nf_register_hook failed\n");
        return;
    }
    return;
}
static void hello_NfHook_Fini(void)
{
	printk(KERN_ALERT "hello_NfHook_Fini\n");
    nf_unregister_hook(&g_stMyNfHook);   //卸载
    return;
}

module_init(hello_NfHook_Init);//注册
module_exit(hello_NfHook_Fini);//卸载
 
MODULE_LICENSE("GPL");//模块的license,有GPL、BSD等,即模块遵循的开源协议;
MODULE_AUTHOR("Stone");//模块作者
//MODULE_DESCRIPTION--模块描述
obj-m += test.o
#generate the path
CURRENT_PATH:=$(shell pwd)
#the current kernel version number
LINUX_KERNEL:=$(shell uname -r)
#the absolute path
LINUX_KERNEL_PATH:=/usr/src/kernels/linux-headers-$(LINUX_KERNEL)
#complie object
all:
	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
#clean
clean:
	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean

通过上面的命令就可以生产一个test.ko模块

  1. 模块的操作命令
    装载模块 insmod test.ko
    卸载模块 rmmod test.ko
    查看打印日志 dmesg(查看内核日志,因为prink是打印到内核的)
    列出系统所有内核模块 lsmod
  2. struct nf_hook_ops
struct nf_hook_ops {
	struct list_head 	list;
 
	/* User fills in from here down. */
	nf_hookfn		*hook;			//hook处理函数
	struct net_device	*dev;		
	void			*priv;
	u_int8_t		pf;			//协议类型
	unsigned int		hooknum;		//hook点
	/* Hooks are ordered in ascending priority. */
	int			priority;		//优先级
};

	struct nf_hook_ops g_stMyNfHook = 
{
    .hook = myHookCallBack,                 //回调函数
    .pf             = PF_INET,              //协议类型
    .hooknum        = NF_BR_LOCAL_OUT,    //hook注册点
    .priority       = NF_IP_PRI_FIRST,      //优先级
};

协议类型一般分为:

enum {
	NFPROTO_UNSPEC =  0,
	NFPROTO_INET   =  1,        
	NFPROTO_IPV4   =  2,		
	NFPROTO_ARP    =  3,
	NFPROTO_NETDEV =  5,
	NFPROTO_BRIDGE =  7,
	NFPROTO_IPV6   = 10,
	NFPROTO_DECNET = 12,
	NFPROTO_NUMPROTO,
};

hook注册点

/* Bridge Hooks */
/* After promisc drops, checksum checks. */------网卡混杂丢包和校验和检查之后(所有进入协议栈的数据包都会经过PRE_ROUTING)
#define NF_BR_PRE_ROUTING	0				
/* If the packet is destined for this box. */------经过路由判决,确定发往本机
#define NF_BR_LOCAL_IN		1
/* If the packet is destined for another interface. */--------经过路由判决,不是发往本机,需要从其他接口转发出去
#define NF_BR_FORWARD		2
/* Packets coming from a local process. */--------由本机外发出去的报文路径
#define NF_BR_LOCAL_OUT		3			
/* Packets about to hit the wire. */--------所有数据包离开本机前的路径
#define NF_BR_POST_ROUTING	4
 
/* Not really a hook, but used for the ebtables broute table */-------非hook点,用于其他目的
#define NF_BR_BROUTING		5
#define NF_BR_NUMHOOKS		6

priority 钩子优先级

	NF_IP_PRI_FIRST = INT_MIN,
	NF_IP_PRI_CONNTRACK_DEFRAG = -400,
	NF_IP_PRI_RAW = -300,
	NF_IP_PRI_SELINUX_FIRST = -225,
	NF_IP_PRI_CONNTRACK = -200,
	NF_IP_PRI_MANGLE = -150,
	NF_IP_PRI_NAT_DST = -100,
	NF_IP_PRI_FILTER = 0,
	NF_IP_PRI_SECURITY = 50,
	NF_IP_PRI_NAT_SRC = 100,
	NF_IP_PRI_SELINUX_LAST = 225,
	NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,
	NF_IP_PRI_LAST = INT_MAX,

回调函数的返回值

/* Responses from hook functions. */
 
#define NF_DROP 0       ----丢弃,释放sk_buff结构
 
#define NF_ACCEPT 1     ----继续正常传输数据报(按照5个钩子点正常传输)
 
#define NF_STOLEN 2    ----模块接管该数据报,告诉Netfilter“忘掉”该数据报。该回调函数将从此开始对数据包的处理,并且Netfilter应当放弃对该数据包做任何的处理。但是,这并不意味着该数据包的资源已经被释放。这个数据包以及它独自的sk_buff数据结构仍然有效,只是回调函数从Netfilter获取了该数据包的所有权。
 
#define NF_QUEUE 3       ----对该数据报进行排队(通常用于将数据报给用户空间的进程进行处理)
 
#define NF_REPEAT 4      ----再次调用该回调函数,应当谨慎使用这个值,以免造成死循环
 
#define NF_STOP 5      ----终止hook链处理,不会释放sk_buff数据

借鉴了网上很多文章,这里就不一一说了,谢谢大家,有不对的地方请指出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值