概述

在协议栈的三层IPv4(IPv6还没看,不清楚)数据包的处理过程中,可能经过Netfilter的五个钩子点,分别为NF_INET_PRE_ROUTING、NF_INET_LOCAL_IN、NF_INET_FORWARD、NF_INET_LOCAL_OUT、NF_INET_POST_ROUTING,在每个点都可以设置一些规则,来对数据包进行匹配检查处理,这些规则的配置、布局和匹配流程,后续文章会详细介绍,本篇主要介绍这五个钩子点以及所处的上下文调用关系;

五个钩子点的位置如下图所示;

代码分析
NF_INET_PRE_ROUTING

当二层收包结束后,会根据注册的协议和回调函数分发数据包,其中ipv4的数据包会分发到ip_rcv函数进行三层协议栈处理,该函数对数据包的合法性进行检查,并且设置一些必要字段之后,经过PRE_ROUTING钩子点;

 int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
{
/* IP数据报的合法性检查和一些必要字段设置,此处省略 */ /* 经过PRE_ROUTING钩子点 */
return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING,
net, NULL, skb, dev, NULL,
ip_rcv_finish); }
NF_INET_LOCAL_IN

上面的ip_rcv函数在经过了PRE_ROUTING钩子点之后,会调用ip_rcv_finish函数,该函数的主要功能是查路由,决定数据包是输入到本地还是转发,并调用dst_input函数;当数据包输入本地时,dst_input函数实际调用了ip_local_deliver函数,函数首先对分片进行检查,如果是分片则需要进行重组,然后经过NF_INET_LOCAL_IN钩子点,之后调用ip_local_deliver_finish继续进行输入本地的其他工作;

 int ip_local_deliver(struct sk_buff *skb)
{
struct net *net = dev_net(skb->dev); /* 分片重组 */
if (ip_is_fragment(ip_hdr(skb))) {
if (ip_defrag(net, skb, IP_DEFRAG_LOCAL_DELIVER))
return ;
} /* 经过LOCAL_IN钩子点 */
return NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_IN,
net, NULL, skb, skb->dev, NULL,
ip_local_deliver_finish);
}
NF_INET_FORWARD

上面的ip_rcv函数在经过了PRE_ROUTING钩子点之后,会调用ip_rcv_finish函数,该函数的主要功能是查路由,决定数据包是输入到本地还是转发,并调用dst_input函数;当数据包输入本地时,dst_input函数实际调用了ip_forward函数,函数数据包进行合法性检查,然后经过NF_INET_FORWARD钩子点,之后调用ip_forward_finish继续进行转发的其他工作,ip_forward_finish在输出数据包的时候,实际上又调用dst_output,实际上就是ip_output函数;

 static int ip_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
{
/* 合法性检查等,此处省略 */ /* 经过FORWARD钩子点 */
return NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD,
net, NULL, skb, skb->dev, rt->dst.dev,
ip_forward_finish); }
NF_INET_LOCAL_OUT

从本机发出的数据包,在查询路由成功之后,会调用__ip_local_out函数,函数首先进行必要字段设置和校验和计算,然后经过NF_INET_LOCAL_OUT钩子点,之后会调用dst_output继续完成数据包输出的其他工作,ipv4的路由输出函数实际上就是ip_output函数;

 int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct iphdr *iph = ip_hdr(skb); /* 设置总长度 */
iph->tot_len = htons(skb->len);
/* 计算校验和 */
ip_send_check(iph); /* if egress device is enslaved to an L3 master device pass the
* skb to its handler for processing
*/
skb = l3mdev_ip_out(sk, skb);
if (unlikely(!skb))
return ; /* 设置ip协议 */
skb->protocol = htons(ETH_P_IP); /* 经过NF的LOCAL_OUT钩子点 */
return nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT,
net, sk, skb, NULL, skb_dst(skb)->dev,
dst_output);
}
NF_INET_POST_ROUTING

转发的数据包或者是本地输出的数据包,最后都会经过ip_output进行输出,函数设置设备和协议之后,经过NF_INET_POST_ROUTING钩子点,之后调用ip_finish_output进行后续输出操作,其中包括了分片等;

 int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct net_device *dev = skb_dst(skb)->dev; IP_UPD_PO_STATS(net, IPSTATS_MIB_OUT, skb->len); /* 设置输出设备和协议 */
skb->dev = dev;
skb->protocol = htons(ETH_P_IP); /* 经过NF的POST_ROUTING钩子点 */
return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING,
net, sk, skb, NULL, dev,
ip_finish_output,
!(IPCB(skb)->flags & IPSKB_REROUTED));
}

Netfilter 之 五个钩子点的更多相关文章

  1. linux netfilter 五个钩子点

    参考http://www.linuxtcpipstack.com/685.html#NF_INET_PRE_ROUTING https://opengers.github.io/openstack/o ...

  2. {Django基础十之Form和ModelForm组件}一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 ModelForm

    Django基础十之Form和ModelForm组件 本节目录 一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 Model ...

  3. Netfilter 之 连接跟踪钩子函数分析

    ipv4_conntrack_defrag ipv4_conntrack_defrag对输入包进行检查,如果是分片包,则调用nf_ct_ipv4_gather_frags函数进行重组: static ...

  4. flask 之(五) --- 对象|钩子|拆分

    内置对象 request: 请求的所有信息 session   服务端会话技术的接口 config:    当前项目的配置信息,模板中可以直接使用 g:global 在单次请求过程中,实现全局数据共享 ...

  5. 对于数据包的截取,使用linux中的netfilter钩子函数

    http://blog.csdn.net/wswifth/article/details/5115358 在师哥的代码(packet.c)中使用的是Linux2.4内核中的一个子系统:netfilte ...

  6. Netfilter 之 钩子函数与钩子点关系图

    概述 通过钩子点和优先级的代码追溯,得到如下对应关系图,图中横坐标为钩子点,纵坐标为优先级,每个钩子点上的钩子函数按照优先级排布: 详细分析 5个钩子点如下所示,在这个五个钩子点上的钩子函数按照上面的 ...

  7. netfilter/iptables 简介

    netfilter 是 Linux 内置的一种防火墙机制,我们一般也称之为数据包过滤机制.iptables 则是一个命令行工具,用来配置 netfilter 防火墙.下图展示了一个带有防火墙的简单网络 ...

  8. flask请求钩子、HTTP响应、响应报文、重定向、手动返回错误码、修改MIME类型、jsonify()方法

    请求钩子: 当我们需要对请求进行预处理和后处理时,就可以用Flask提供的回调函数(钩子),他们可用来注册在请求处理的不同阶段执行的处理函数.这些请求钩子使用装饰器实现,通过程序实例app调用,以 b ...

  9. SVN配置钩子

    安装测试环境:109  CentOS4.6 安装: SVN1.32http://subversion.tigris.org/downloads/subversion-1.3.2.tar.gz安装:解压 ...

随机推荐

  1. 【ES6 】ES6 字符串扩展及新增方法

    模板字符串 传统写法 var str = 'There are <b>' + basket.count + '</b> ' + 'items in your basket, ' ...

  2. CSP-S2019题解

    格雷码 €€£:我不抄自己辣!JOJO! 这题比那个SCOI的炒鸡格雷码好多了,甚至告诉你构造方法,所以... void wk(uLL kk) { int j=0; for(uLL i=n-1;~i; ...

  3. Oracle创建索引;查询索引

    1.创建索引 create index 索引名 on 表名(列名); 2.删除索引 drop index 索引名; 3.创建组合索引 create index 索引名 on 表名(列名1,,列名2); ...

  4. DX使用随记--ImageComboBoxEdit

    1. 增加按钮: Combo_订单类型.Properties.Items.Clear()Select Case Combo_客户名称.EditValue Case "ABC" Co ...

  5. go语言入门(6)复合类型

    1,分类 2,指针 指针是一个代表着某个内存地址的值.这个内存地址往往是在内存中存储的另一个变量的值的起始位置. 1)基本操作 Go语言虽然保留了指针,但与其它编程语言不同的是: 默认值 nil,没有 ...

  6. 二、MySQL介绍

    目录 一.MySQL背景 二.MySQL的优点 三.MySQL安装 四.MySQL服务的启动和停止 五.MySQL登录和退出 六.MySQL常用命令 (一)常用命令 (二)语法规范 (三)SQL语言细 ...

  7. OpenCV_contrib里的Text(自然场景图像中的文本检测与识别)

    平台:win10 x64 +VS 2015专业版 +opencv-3.x.+CMake 待解决!!!Issue说明:最近做一些字符识别的事情,想试一下opencv_contrib里的Text(自然场景 ...

  8. NORDIC 错误文件

    ble_err.h sdk_errors.h nrf_error.h app_error.h

  9. linux常用的操作命令

    ---恢复内容开始--- 最近换了工作之后,需要管理linux服务器的日常运行和维护,自然linux命令是少不了的,切换目录,vim操作等的简单的操作就不说了,有些时候还需要查看日志和监控服务器启动进 ...

  10. 【Java 基础项目 - - Bank项目4】 对象构造/跨package调用

    UML设计: 文件组织: (注: 在bank4中,直接调用bank3的内容, 不再重复编写代码即可!) 代码编写Bank.java: package Banking_4; import Banking ...