secgateway/Platform/user/kernel_hook/lkh_hook_init.c

169 lines
3.9 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/module.h>
#include <linux/if.h>
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
#include <linux/rcupdate.h>
#include <net/net_namespace.h>
#include "lkh_hook.h"
static void __net_init __lkh_net_init(struct lkh_hook_entries __rcu **e, int max)
{
int h;
for (h = 0; h < max; h++)
{
RCU_INIT_POINTER(e[h], NULL);
}
return;
}
/*********************************************************************************
* Description  
* 为指定的网络命名空间卸载对应的HOOK数据结构
* Input:  
* net - 网络命名空间指针
* Output:
* 
* Return:
* 无
* Others:
* 无
**********************************************************************************/
static void __net_exit lkh_net_exit(struct net *net)
{
struct list_head * temp_del;
struct list_head * temp_node;
struct lkh_hook * hook;
if (NULL == net)
{
return;
}
list_for_each_safe(temp_del, temp_node, &g_lkh_hook_handle.list)
{
hook = list_entry(temp_del, struct lkh_hook, list);
if (hook != NULL)
{
if (hook->net_ptr == net)
{
g_lkh_hook_handle.net_num--;
list_del(&hook->list);
/* 释放内存还需要释放hook_ptr内申请的内存之后补充 */
kvfree(hook);
}
}
}
return;
}
/*********************************************************************************
* Description  
* 为指定的网络命名空间初始化对应的HOOK数据结构
* Input:  
* net - 网络命名空间指针
* Output:
*  1 - 处理失败
* 0 - 处理成功
* Return:
* 无
* Others:
* 无
**********************************************************************************/
static int __net_init lkh_net_init(struct net *net)
{
struct lkh_hook * hook_ptr;
size_t alloc;
if (NULL == net)
{
return 1;
}
hook_ptr = kvzalloc(sizeof(struct lkh_hook), GFP_KERNEL);
if (NULL == hook_ptr)
{
return 1;
}
/* 记录net指针用来作为标识命名空间的关键字 */
hook_ptr->net_ptr = net;
list_add(&hook_ptr->list, &g_lkh_hook_handle.list);
g_lkh_hook_handle.net_num++;
alloc = sizeof(struct lkh_hook_entries __rcu *) * LKH_INET_NUMHOOKS;
hook_ptr->hooks_ipv4[0] = (struct lkh_hook_entries __rcu *)kvzalloc(alloc, GFP_KERNEL);
__lkh_net_init(hook_ptr->hooks_ipv4, ARRAY_SIZE(hook_ptr->hooks_ipv4));
hook_ptr->hooks_ipv6[0] = (struct lkh_hook_entries __rcu *)kvzalloc(alloc, GFP_KERNEL);
__lkh_net_init(hook_ptr->hooks_ipv6, ARRAY_SIZE(hook_ptr->hooks_ipv6));
return 0;
}
static struct pernet_operations lkh_net_ops = {
.init = lkh_net_init,
.exit = lkh_net_exit,
};
/*********************************************************************************
* Description  
* 内核钩子.KO insmod处理函数
* Input:  
* 无
* Output:
* 
* Return:
* 无
* Others:
* 无
**********************************************************************************/
static int lkh_init(void)
{
int ret;
INIT_LIST_HEAD(&g_lkh_hook_handle.list);
/* 网络空间模块注册函数 */
ret = register_pernet_subsys(&lkh_net_ops);
return ret;
}
/*********************************************************************************
* Description  
* 内核钩子.KO rmmod处理函数
* Input:  
* 无
* Output:
* 
* Return:
* 无
* Others:
* 无
**********************************************************************************/
static void lkh_exit(void)
{
/* 解除网络空间模块注册函数 */
unregister_pernet_subsys(&lkh_net_ops);
return;
}
module_init(lkh_init);
module_exit(lkh_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("meng");
MODULE_DESCRIPTION("LINUX HOOK");