Netfilter 之 钩子函数调用
本篇主要从三层协议栈调用函数NF_HOOK说起,不断深入,分析某个钩子点中所有钩子函数的调用流程,但是本文不包含规则介绍和核心的规则匹配流程,后续文章将继续分析;
NF_HOOK函数先调用了nf_hook继续执行调用钩子函数处理,处理之后,如果接受,则调用输入的回调函数okfn,继续数据包的下一步处理;
static inline int
NF_HOOK(uint8_t pf, unsigned int hook, struct net *net, struct sock *sk, struct sk_buff *skb,
struct net_device *in, struct net_device *out,
int (*okfn)(struct net *, struct sock *, struct sk_buff *))
{
/* 先执行钩子函数 */
int ret = nf_hook(pf, hook, net, sk, skb, in, out, okfn); /* 返回成功,则继续执行成功回调 */
if (ret == )
ret = okfn(net, sk, skb);
return ret;
}
NF_HOOK_COND增加了一个输入掉价cond,当不满足条件的时候,直接调用okfn,满足条件的时候,才会继续调用nf_hook进行后续的钩子函数调用流程,如果nf_hook返回1,则调用okfn;
static inline int
NF_HOOK_COND(uint8_t pf, unsigned int hook, struct net *net, struct sock *sk,
struct sk_buff *skb, struct net_device *in, struct net_device *out,
int (*okfn)(struct net *, struct sock *, struct sk_buff *),
bool cond)
{
int ret; if (!cond ||
((ret = nf_hook(pf, hook, net, sk, skb, in, out, okfn)) == ))
ret = okfn(net, sk, skb);
return ret;
}
nf_hook函数首先找到钩子点函数入口,如果有钩子函数,则进一步初始化nf_hook_state结构,然后调用nf_hook_slow进入钩子函数调用流程;
static inline int nf_hook(u_int8_t pf, unsigned int hook, struct net *net,
struct sock *sk, struct sk_buff *skb,
struct net_device *indev, struct net_device *outdev,
int (*okfn)(struct net *, struct sock *, struct sk_buff *))
{
struct nf_hook_entry *hook_head;
int ret = ; #ifdef HAVE_JUMP_LABEL
if (__builtin_constant_p(pf) &&
__builtin_constant_p(hook) &&
!static_key_false(&nf_hooks_needed[pf][hook]))
return ;
#endif rcu_read_lock();
/* 找到钩子点 */
hook_head = rcu_dereference(net->nf.hooks[pf][hook]);
if (hook_head) {
struct nf_hook_state state; /* 初始化nf_hook_state结构 */
nf_hook_state_init(&state, hook, pf, indev, outdev,
sk, net, okfn); /* 执行钩子函数 */
ret = nf_hook_slow(skb, &state, hook_head);
}
rcu_read_unlock(); return ret;
}
在分析nf_hook_slow之前,我们先看下该函数中涉及到的钩子函数执行结果的返回值字段的含义;
/* Responses from hook functions. */
#define NF_DROP 0 /* 丢包,不再传输 */
#define NF_ACCEPT 1 /* 接受数据包,继续正常传输 */
#define NF_STOLEN 2 /* 数据包已经被接管,回调函数处理该包,NF不再处理 */
#define NF_QUEUE 3 /* 将数据包交给用户空间的进程处理 */
#define NF_REPEAT 4 /* 再次调用钩子函数 */
#define NF_STOP 5 /* Deprecated, for userspace nf_queue compatibility. */
#define NF_MAX_VERDICT NF_STOP
nf_hook_slow会遍历当前钩子点上的钩子函数,通过函数nf_hook_entry_hookfn调用钩子函数,并根据返回值判断如何进行下一步处理;
int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state,
struct nf_hook_entry *entry)
{
unsigned int verdict;
int ret; do {
/* 调用钩子函数 */
verdict = nf_hook_entry_hookfn(entry, skb, state);
switch (verdict & NF_VERDICT_MASK) {
case NF_ACCEPT:
/* 获取下一个钩子函数 */
entry = rcu_dereference(entry->next);
break;
case NF_DROP:
/* 丢包 */
kfree_skb(skb);
ret = NF_DROP_GETERR(verdict);
if (ret == )
ret = -EPERM;
return ret;
case NF_QUEUE:
/* 通过netfilter_queue交给应用层nf_queue处理 */
ret = nf_queue(skb, state, &entry, verdict);
if (ret == && entry)
continue;
return ret;
default:
/* Implicit handling for NF_STOLEN, as well as any other
* non conventional verdicts.
*/
return ;
} /* 继续执行下一个钩子函数 */
} while (entry); return ;
}
nf_hook_entry_hookfn函数调用当前钩子函数结构entry中的钩子函数hook,返回执行结果;
static inline int
nf_hook_entry_hookfn(const struct nf_hook_entry *entry, struct sk_buff *skb,
struct nf_hook_state *state)
{
return entry->hook(entry->priv, skb, state);
}
我们暂且看一下filter表的钩子函数,可见,其核心流程为ipt_do_table,也就是进入filter表的规则匹配流程,ipt_do_table函数后续文章我们单独分析;
static unsigned int
iptable_filter_hook(void *priv, struct sk_buff *skb,
const struct nf_hook_state *state)
{
/* LOCAL_OUT && (数据长度不足ip头 || 实际ip头部长度不足最小ip头),在使用raw socket */
if (state->hook == NF_INET_LOCAL_OUT &&
(skb->len < sizeof(struct iphdr) ||
ip_hdrlen(skb) < sizeof(struct iphdr)))
/* root is playing with raw sockets. */
return NF_ACCEPT; /* 核心规则匹配流程 */
return ipt_do_table(skb, state, state->net->ipv4.iptable_filter);
}
Netfilter 之 钩子函数调用的更多相关文章
- netfilter的钩子——数据包在内核态得捕获、修改和转发
转发:http://blog.csdn.net/stonesharp/article/details/27091391 数据包在内核态得捕获.修改和转发(基于 netfilter) 忙活了好几天 ...
- Linux Netfilter注册钩子点
注册钩子点首先要包含响应的头文件,因为这应该已经属于对kernel的编程了. #include <linux/module.h> #include <linux/kernel.h&g ...
- Netfilter 之 钩子函数与钩子点关系图
概述 通过钩子点和优先级的代码追溯,得到如下对应关系图,图中横坐标为钩子点,纵坐标为优先级,每个钩子点上的钩子函数按照优先级排布: 详细分析 5个钩子点如下所示,在这个五个钩子点上的钩子函数按照上面的 ...
- Netfilter 之 钩子函数注册
通过注册流程代码的分析,能够明确钩子函数的注册流程,理解存储钩子函数的数据结构,如下图(点击图片可查看原图): 废话不多说,开始分析: nf_hook_ops是注册的钩子函数的核心结构,字段含义如下所 ...
- Netfilter的使用和实现
本文主要内容:Netfilter的原理和实现浅析,以及示例模块. 内核版本:2.6.37 Author:zhangskd @ csdn blog 概述 Netfilter为多种网络协议(IPv4.IP ...
- Linux内核project导论——网络:Netfilter概览
简单介绍 最早的内核包过滤机制是ipfwadm.后来是ipchains.再后来就是iptables/netfilter了. 再往后,也就是如今是nftables. 只是nftables与iptable ...
- Netfilter/iptables防火墙
http://os.51cto.com/art/201107/273443.htm [51CTO独家特稿]Linux系统管理员们都接触过Netfilter/iptables,这是Linux系统自带的免 ...
- c#调用钩子
1 概述 在c++中有钩子程序,但是在C#还没有对其进行封装,所以需要自己根据实际情况调用钩子.钩子在我的理解下是,通过初始化钩子与系统中消息映射建立某种关系,当点击鼠标或者键盘,就会通过钩子中的回调 ...
- Pytest权威教程19-编写钩子(Hooks)方法函数
目录 编写钩子(Hooks)函数 钩子函数验证和执行 firstresult: 遇到第一个有效(非None)结果返回 hookwrapper:在其他钩子函数周围执行 钩子(Hooks)函数排序/调用示 ...
随机推荐
- SSM框架警告/错误集合
警告: 1.使用Eclipse的Spring Elements组件的时候发现会提示有警告:Expect at least one bean match() 解决办法:项目可以正常运行,未有报错,在其他 ...
- EasyUI中的重要的控件和属性
data-options: precision:2 保留2为小数 validType:
- 在vue中引用echarts导致Cannot read property getAttribute of null ?
报错信息如下: 之前一直用echarts没有出现过这个问题,所以当这个问题出现时我就开始了各种查,试了几种方法依旧报错,比如: 1.在mounted() {},写成如下形式:(依旧报错) this.$ ...
- DX使用随记--TabControl
1. 关闭TabControl选项卡: Private Sub TabControl_Main_CloseButtonClick(sender As Object, e As EventArgs) H ...
- You are using the runtime-only build of Vue where the template compiler is not available.
使用vue-cli搭建的项目,启动报错 You are using the runtime-only build of Vue where the template compiler is not a ...
- MySQL存储引擎MyISAM和InnoDB,索引结构优缺点
MySQL存储引擎MyISAM和InnoDB底层索引结构 深入理解MySQL索引底层数据结构与算法 (各种索引结构优缺点) Myisam和Innodb索引实现的不同(存储结构) 存储引擎作用于什么对象 ...
- 【Distributed】互联网安全架构
一.常见Web安全漏洞 1.1 XSS攻击 什么是XSS攻击手段 如何防御XSS攻击 1.2 SQL注入攻击 什么是SQL注入 SQL注入防攻击手段 MyBatis #与$区别 1.3 Http请求防 ...
- Linux磁盘及文件系统管理3
文件系统管理工具: 创建文件系统的工具 mkfs mkfs.ext2,mkfs.ext3,mkfs.ext4,mkfs.xfs,mkfs.vfat,... 检测及修复文件系统的工具 fsck fsck ...
- Linux如何判断自己的服务器是否被入侵
如何判断自己的服务器是否被入侵了呢?仅仅靠两只手是不够的,但两只手也能起到一些作用,我们先来看看UNIX系统上一些入侵检测方法,以LINUX和solaris为例. 1.检查系统密码文件 首先从明显的入 ...
- 下划线文字,鼠标hover小样式
CSS样式 //不只是a标签,其他有下划线的字体也可以 a:hover{ color: #ff3100; //这里的颜色是指字体颜色不是波浪下划线效果的svg图颜色 text-decorati ...