secgateway/Platform/user/kernel_hook/lkh_hook_fwd.c

149 lines
3.6 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/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 <linux/list.h>
#include <linux/netdevice.h>
#include "lkh_hook.h"
#define LKH_VERDICT_MASK 0x000000ff
#define LKH_VERDICT_QBITS 16
static inline int LKH_DROP_GETERR(int verdict)
{
return -(verdict >> LKH_VERDICT_QBITS);
}
static inline int lkh_hook_entry_hookfn(const struct lkh_hook_entry *entry, struct sk_buff *skb, struct lkh_hook_state *state)
{
return entry->hook(entry->priv, skb, state);
}
static inline void lkh_hook_state_init(struct lkh_hook_state *p,
unsigned int hook,
u_int8_t pf,
struct net_device *indev,
struct net_device *outdev,
struct sock *sk,
struct net *net)
{
p->hook_stage = hook;
p->pf = pf;
p->in = indev;
p->out = outdev;
p->sk = sk;
p->net = net;
}
int lkh_hook_slow(struct sk_buff *skb, struct lkh_hook_state *state,
const struct lkh_hook_entries *e, unsigned int s)
{
unsigned int verdict;
int ret;
for (; s < e->num_hook_entries; s++)
{
verdict = lkh_hook_entry_hookfn(&e->hooks[s], skb, state);
switch (verdict & LKH_VERDICT_MASK)
{
case LKH_ACCEPT:
break;
case LKH_DROP:
kfree_skb(skb);
ret = LKH_DROP_GETERR(verdict);
if (ret == 0)
{
ret = -EPERM;
}
return ret;
default:
return 0;
}
}
return 1;
}
/*********************************************************************************
* Description  
* 转发流程调用钩子函数的处理报文的入口函数
* Input:  
* pf - 优先级
* hook_stage - 钩子函数调用阶段
* sk - socket
* skb - 报文描述符
* indev - 入设备信息
* outdev - 出设备信息
* Output:
* 
* Return:
* 无
* Others:
* 入口参数的定义和使用方法同netfilter一样
**********************************************************************************/
int lkh_hook(u_int8_t pf,
unsigned int hook_stage,
struct net *net,
struct sock *sk,
struct sk_buff *skb,
struct net_device *indev,
struct net_device *outdev)
{
struct lkh_hook_entries * hook_entrise;
int ret = 1;
bool find_flag = false;
struct lkh_hook * hook_head;
/* 查找对应网络空间的hook结构 */
list_for_each_entry(hook_head, &g_lkh_hook_handle.list, list)
{
if (hook_head->net_ptr == net)
{
find_flag = true;
break;
}
}
if (!find_flag)
{
return ret;
}
rcu_read_lock();
switch (pf)
{
case LKH_PROTO_IPV4:
hook_entrise = rcu_dereference(hook_head->hooks_ipv4[hook_stage]);
break;
case LKH_PROTO_IPV6:
hook_entrise = rcu_dereference(hook_head->hooks_ipv6[hook_stage]);
break;
default:
break;
}
if (hook_entrise != NULL)
{
struct lkh_hook_state state;
lkh_hook_state_init(&state, hook_stage, pf, indev, outdev, sk, net);
ret = lkh_hook_slow(skb, &state, hook_entrise, 0);
}
rcu_read_unlock();
return ret;
}
EXPORT_SYMBOL(lkh_hook);