169 lines
3.9 KiB
C
169 lines
3.9 KiB
C
#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");
|
||
|