netfiler框架是在内核协议栈实现的基础上完成的,在报文从网口接收,路由等方法实现基础上使用NF_HOOK调用相应的钩子来进入netfiler框架的处理,如

ip_rcv之后会调用NF_HOOK(NF_IP_PRE_ROUTING)

NF_HOOK宏定义如下:

#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \
NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, INT_MIN) #define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh) \
({int __ret; \
if ((__ret=nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, thresh, 1)) == 1)\
__ret = (okfn)(skb); \
__ret;}) static inline int nf_hook_thresh(int pf, unsigned int hook,
struct sk_buff **pskb,
struct net_device *indev,
struct net_device *outdev,
int (*okfn)(struct sk_buff *), int thresh,
int cond)
{
if (!cond)
return 1;
#ifndef CONFIG_NETFILTER_DEBUG
if (list_empty(&nf_hooks[pf][hook]))
return 1;
#endif
return nf_hook_slow(pf, hook, pskb, indev, outdev, okfn, thresh);
}

重点介绍下nf_hook_slow方法。

nf_hook_slow针对调用NF_HOOK时的hook点,遍历所有的钩子函数并判断匹配(match)及完成相应处理(target)。

int nf_hook_slow(int pf, unsigned int hook, struct sk_buff **pskb,
struct net_device *indev,
struct net_device *outdev,
int (*okfn)(struct sk_buff *),
int hook_thresh)
{
struct list_head *elem;
unsigned int verdict;
int ret = 0; /* We may already have this, but read-locks nest anyway */
rcu_read_lock(); elem = &nf_hooks[pf][hook];
next_hook:
verdict = nf_iterate(&nf_hooks[pf][hook], pskb, hook, indev,
outdev, &elem, okfn, hook_thresh);
if (verdict == NF_ACCEPT || verdict == NF_STOP) {
ret = 1;
goto unlock;
} else if (verdict == NF_DROP) {
kfree_skb(*pskb);
ret = -EPERM;
} else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) {
NFDEBUG("nf_hook: Verdict = QUEUE.\n");
if (!nf_queue(*pskb, elem, pf, hook, indev, outdev, okfn,
verdict >> NF_VERDICT_BITS))
goto next_hook;
}
unlock:
rcu_read_unlock();
return ret;
}

选择hook对应的钩子函数时,使用了 nf_hooks(struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS])二维数组,其中行定义了协议簇类型,最大为NPROTO(33),列定义了不同的hook点,具体内容如下所示(参考netfilter_ipv4.h)。

#define NF_IP_PRE_ROUTING 0

/* If the packet is destined for this box. */

#define NF_IP_LOCAL_IN 1

/* If the packet is destined for another interface. */

#define NF_IP_FORWARD 2

/* Packets coming from a local process. */

#define NF_IP_LOCAL_OUT 3

/* Packets about to hit the wire. */

#define NF_IP_POST_ROUTING 4

下面针对每个HOOK点列举下协议栈中的调用

1. ip_rcv中调用NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,ip_rcv_finish)

网卡接收ip报文后经过pre_routing hook点处理。此hook点一般是用来做DNAT。

2. ip_local_deliver中调用NF_HOOK(PF_INET, NF_IP_LOCAL_IN, skb, skb->dev, NULL,ip_local_deliver_finish)

ip报文被本地网卡接收后,经过local_in hook点处理

3. ip_forward中调用NF_HOOK(PF_INET, NF_IP_FORWARD, skb, skb->dev, rt->u.dst.dev, ip_forward_finish)

路由查询后不是本地数据,需要做转发处理,经过forward hook点处理

4. ip_push_pending_frames中调用NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,dst_output)

此处理是将ip分片报文重组后送出去

5. ip_output中调用NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,ip_finish_output,!(IPCB(skb)->flags & IPSKB_REROUTED))

如果报文中没有设置IPSKB_REROUTED标志,则报文会过post_routing hook点处理。此hook点一般是用来做SNAT的。

NEXT: 后面会介绍netfilter框架如何注册hook钩子。

netfiler源代码分析之框架介绍的更多相关文章

  1. Appium Android Bootstrap源代码分析之简单介绍

    在上一个系列中我们分析了UiAutomator的核心源代码,对UiAutomator是怎么执行的原理有了根本的了解.今天我们会開始另外一个在安卓平台上基于UiAutomator的新起之秀--Appiu ...

  2. 【转载】linux环境下tcpdump源代码分析

    linux环境下tcpdump源代码分析 原文时间 2013-10-11 13:13:02  CSDN博客 原文链接  http://blog.csdn.net/han_dawei/article/d ...

  3. linux环境下tcpdump源代码分析

    Linux 环境下tcpdump 源代码分析 韩大卫@吉林师范大学 tcpdump.c 是tcpdump 工具的main.c, 本文旨对tcpdump的框架有简单了解,只展示linux平台使用的一部分 ...

  4. Android应用程序绑定服务(bindService)的过程源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6745181 Android应用程序组件Serv ...

  5. Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6633311 在上一篇文章中,我 们分析了And ...

  6. Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6642463 在前面几篇文章中,我们详细介绍了A ...

  7. Android应用程序框架层和系统运行库层日志系统源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6598703 在开发Android应用程序时,少 ...

  8. 【Android开源项目分析】android轻量级开源缓存框架——ASimpleCache(ACache)源代码分析

    转载请注明出处:http://blog.csdn.net/zhoubin1992/article/details/46379055 ASimpleCache框架源代码链接 https://github ...

  9. Android异步任务处理框架AsyncTask源代码分析

    [转载请注明出处:http://blog.csdn.net/feiduclear_up CSDN 废墟的树] 引言 在平时项目开发中难免会遇到异步耗时的任务(比方最常见的网络请求).遇到这样的问题.我 ...

随机推荐

  1. EL操作 web 对象的常用方法

    11个常见的web对象 pageScope :获得pageContext对象中存的数据 requestScope :获得request对象中存的数据 sessionScope :获得session对象 ...

  2. ffmpeg-20160822-bin.7z

    ESC 退出 0 进度条开关 1 屏幕原始大小 2 屏幕1/2大小 3 屏幕1/3大小 4 屏幕1/4大小 5 屏幕横向放大 20 像素 6 屏幕横向缩小 20 像素 S 下一帧 [ -2秒 ] +2 ...

  3. Oracle 过程中检查数据表存在与否

    在过程中,尤其是每天执行的任务,通常要检查查询的数据表存在不存在,如果不存在则等待一段时间在进行执行,以下代码实现了这个功能,如果表不存在,抛出异常,交给异常处理代码,确保数据完整性 使用方法:p_C ...

  4. 删除安装的 cocoapods 的缓存方法

    清除 Cocoapods 本地缓存 特殊情况下,由于网络或者别的原因,通过 cocoapods 下载的文件可能会有问题.这时候可以删除 Cocoapods 的缓存(~/Library/Caches/C ...

  5. 模拟搭建Web项目的真实运行环境(三)

    一.解决Redis出现的RDB权限问题 当你在安装redis的时候,如果是使用超级用户root安装, 开启redis服务的时候没有用超级用户去开启, 在用客户端登录redis,然后使用shutdown ...

  6. 【基础知识】UML基础

    http://www.ibm.com/developerworks/cn/rational/r-uml/

  7. windows 10 设置

    精简应用 邮件和日历: Get-AppxPackage *communi* | Remove-AppxPackage 新闻: Get-AppxPackage *bing* | Remove-AppxP ...

  8. JVM 1.6 GC

    JVM调优是一门艺术. JVM调优的重点是减少Major GC的次数,因为Major GC会暂停程序比较长的时间.如果Major GC的次数比较多,意味着应用程序的JVM内存参数需要调整. JVM内存 ...

  9. 图文介绍如何在Eclipse统计代码行数

    使用Eclipse可以方便的统计工程或文件的代码行数,方法如下: 1.点击要统计的项目或许文件夹,在菜单栏点击Search,然后点击File... 2.选中正则表达式(Regular expressi ...

  10. mysql多表联合查询

    转自:http://www.cnblogs.com/Toolo/p/3634563.html 多表连接,小分三种(笛卡尔积.内连接.外连接),多分五种 (笛卡尔积.内连接.左连接.右连接.全连接(my ...