netfilter filter表(二)

news2024/12/23 17:09:20

这次继续分析filter表,不同与之前的分析方式,这次通过将内核中的数据打印出来,对比结构关系图来分析。这是本次分析涉及的几个数据结构:

struct xt_table {

struct list_head list;

/* What hooks you will enter on */

unsigned int valid_hooks;

/* Man behind the curtain... */

struct xt_table_info *private;

/* Set this to THIS_MODULE if you are a module, otherwise NULL */

struct module *me;

u_int8_t af; /* address/protocol family */

int priority; /* hook order */

/* called when table is needed in the given netns */

int (*table_init)(struct net *net);

/* A unique name... */

const char name[XT_TABLE_MAXNAMELEN];

};

struct xt_table_info {

/* Size per table */

unsigned int size; 

/* Number of entries: FIXME. --RR */

unsigned int number; 

/* Initial number of entries. Needed for module usage count */

unsigned int initial_entries;

/* Entry points and underflows */

unsigned int hook_entry[NF_INET_NUMHOOKS]; // hook_entry[NF_INET_LOCAL_IN]

unsigned int underflow[NF_INET_NUMHOOKS];

/*

* Number of user chains. Since tables cannot have loops, at most

* @stacksize jumps (number of user chains) can possibly be made.

*/

unsigned int stacksize;

void ***jumpstack;

unsigned char entries[0] __aligned(8);

};

依然用《netfilter filter表》 中的方法,打印内核中的数据,这次hello_open的代码如下:

static int hello_open(struct inode* inode, struct file*filep)
{
	printk("hello_open\n");
	struct task_struct *tsk = current;
	struct net *net;
	struct xt_table *xt_filter;
	struct xt_table_info *filter_info;
	const void* table_base;
	int i = 0;
	int local_in_hook_entry;
	struct ipt_entry* ipt_entry;

	struct nsproxy *nsprx = tsk->nsproxy; //命名空间
	net = nsprx->net_ns;

	xt_filter = net->ipv4.iptable_filter;

	// 打印xt_table信息
	printk("xt_table: af - %d\n", xt_filter->af);
	printk("xt_table: name - %s\n", xt_filter->name);
	printk("xt_table: valid_hooks - %d\n", xt_filter->valid_hooks);
	printk("xt_table: priority - %d\n", xt_filter->priority);

	filter_info = xt_filter->private;
	if (NULL == filter_info)
	{
		printk("filter_info is null\n");
		return 0;
	}

	printk("filter_info: size - %d\n", filter_info->size);
	printk("filter_info: number - %d\n", filter_info->number); // 4?
	printk("filter_info: initial_entries - %d\n", filter_info->initial_entries);
	printk("filter_info: stacksize - %d\n", filter_info->stacksize);

	table_base = filter_info->entries;

	//local_in_hook_entry = filter_info->hook_entry[NF_INET_LOCAL_IN];
	// 打印hook_entry数组
	for (i = 0; i < NF_INET_NUMHOOKS; ++i)
	{
		printk("filter_info: hook_entry[%d] - %d\n", i, filter_info->hook_entry[i]);
	}

	for (i = 0; i < NF_INET_NUMHOOKS; ++i)
	{
		printk("filter_info: underflow[%d] - %d\n", i, filter_info->underflow[i]);
	}

	return 0;
}

根据打印的内核日志,整理了下面的图: 

涉及的两个枚举类型:

enum {

NFPROTO_UNSPEC = 0,

NFPROTO_INET = 1,

NFPROTO_IPV4 = 2,

NFPROTO_ARP = 3,

NFPROTO_NETDEV = 5,

NFPROTO_BRIDGE = 7,

NFPROTO_IPV6 = 10,

NFPROTO_DECNET = 12,

NFPROTO_NUMPROTO,

};

 

enum nf_inet_hooks {

NF_INET_PRE_ROUTING,

NF_INET_LOCAL_IN,

NF_INET_FORWARD,

NF_INET_LOCAL_OUT,

NF_INET_POST_ROUTING,

NF_INET_NUMHOOKS

};

 现在开始分析日志,其中以“#”开头或标蓝的为注释信息。

[ 3885.915747] hello_open

# 2对应的是NFPROTO_IPV4,将上面NFPROTO_IPV4的定义
[ 3885.915749] xt_table: af - 2
[ 3885.915749] xt_table: name - filter

#14实际是:

#define FILTER_VALID_HOOKS ((1 << NF_INET_LOCAL_IN) | \

(1 << NF_INET_FORWARD) | \

(1 << NF_INET_LOCAL_OUT))

[ 3885.915750] xt_table: valid_hooks - 14
[ 3885.915751] xt_table: priority - 0

#下面是xt_table_info信息

#xt_table_info后面,紧接着是4120大小的内存空间,存放ipt_standard和ipt_error
[ 3885.915751] filter_info: size - 4120

#一共25个ipt_standard/ipt_error对象
[ 3885.915752] filter_info: number - 25
[ 3885.915752] filter_info: initial_entries - 4
[ 3885.915753] filter_info: stacksize - 5
[ 3885.915753] filter_info: hook_entry[0] - -1
[ 3885.915754] filter_info: hook_entry[1] - 0
[ 3885.915754] filter_info: hook_entry[2] - 456
[ 3885.915755] filter_info: hook_entry[3] - 1720
[ 3885.915755] filter_info: hook_entry[4] - -1
[ 3885.915756] filter_info: underflow[0] - -1
[ 3885.915756] filter_info: underflow[1] - 304
[ 3885.915757] filter_info: underflow[2] - 1568
[ 3885.915757] filter_info: underflow[3] - 1720
[ 3885.915758] filter_info: underflow[4] - -1

 xt_table_info的hook_entry和underflow需要单独说一下。内核网络栈有5个钩子挂载点,hook_entry[0]和underflow[0]分别表示第一个挂载点在filter表中配置存放的起始位置和结束位置,以此类推。

filter_info: hook_entry[0] - -1

underflow[0] - -1

表示第一个挂载点,filter表不处理此挂载点的数据,那第一个挂载点是哪个呢?就是NF_INET_PRE_ROUTING,见enum nf_inet_hooks的定义。

hook_entry[1] - 0

underflow[1] - 304

同理,这个表示第2个挂载点(NF_INET_LOCAL_IN)在filter表中配置项的起始位置和结束位置。

可以参考前面的图,加深对上述的理解。

再看下本机filter表INPUT链的配置:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       tcp  --  1.2.3.5              0.0.0.0/0           
ACCEPT     all  --  1.2.3.4              0.0.0.0/0      

INPUT链有两条配置,每个配置对应一个ipt_standard对象,每个ipt_standard对象大小为152字节。因此INPUT链配置存放的起始位置是0,结束位置是304。

 

 underflow[1] - 304

hook_entry[2] - 456

304和456,中间有152字节的内存,存放的是ipt_error对象。见上图。

hook_entry和 underflow存放的是配置项与xt_table_info的entries距离。

(void*)xt_table_info.entries + xt_table_info. hook_entry[1],得到的是INPUT链第一条配置(ipt_standard)的位置。

(void*)xt_table_info.entries + xt_table_info. hook_entry[2],得到的是FORWARD链第一条配置(ipt_standard)的位置。

下一篇将分析ipt_standard。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/446916.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

4、SpringBoot接收和响应xml报文请求

背景 平时开发的接口&#xff0c;基本是使用 json 格式的请求报文。然而&#xff0c;有时候也避免不了有 xml 报文请求的场景&#xff0c;最近就遇到了这种情况&#xff0c;在此记录下。另外&#xff0c;工程中使用的是 controller-service……这种结构。 xml请求报文&#x…

链表(JS实现)

&#x1f4dd;个人主页&#xff1a;爱吃炫迈 &#x1f48c;系列专栏&#xff1a;数据结构与算法 &#x1f9d1;‍&#x1f4bb;座右铭&#xff1a;道阻且长&#xff0c;行则将至&#x1f497; 文章目录 链表链表的分类创建链表LinkedList类的骨架 实现链表的方法push尾部添加元…

chatgpt智能提效职场办公-ppt怎么蒙层

作者&#xff1a;虚坏叔叔 博客&#xff1a;https://xuhss.com 早餐店不会开到晚上&#xff0c;想吃的人早就来了&#xff01;&#x1f604; 在 PowerPoint 中添加蒙版图层&#xff0c;可以在幻灯片中创建一个半透明的矩形或形状&#xff0c;并在其上方添加或放置其他对象。 下…

FPGA终于可以愉快地写代码了!Vivado和Visual Studio Code黄金搭档

如果你是一位FPGA开发者&#xff0c;那么你一定会对VIvado这款软件非常熟悉。但是&#xff0c;对于vivado兼容的第三方编辑器软件&#xff0c;你知道Visual Studio Code吗&#xff1f;这是个非常不错的选择&#xff0c;Visual Studio Code搭配众多插件&#xff0c;能让你FPGA开…

【SpringBoot】一:SpringBoot的基础(下)

文章目录 1.外部化的配置1.1 配置文件基础1.1.1 配置文件格式1.1.2 application文件1.1.3 application.properties1.1.4 application.yml1.1.5 environment1.1.6 组织多文件1.1.7多环境配置 1.2 绑定Bean1.2.1 简单的属性绑定1.2.2 嵌套Bean1.2.3 扫描注解1.2.4 处理第三方库对…

【移动端网页布局】移动端网页布局基础概念 ② ( 视口 | 布局视口 | 视觉视口 | 理想视口 )

文章目录 一、视口1、布局视口 ( 网页大小 | 网页大小 > 设备大小 )2、视觉视口 ( 设备大小 | 网页大小 > 设备大小 )3、理想视口 ( 网页大小 设备大小 ) 一、视口 浏览器 显示 网页页面内容 的 屏幕区域 被称为 " 视口 " ; 视口分为以下几个大类 : 布局视口…

项目协同中的git

在远程代码仓库&#xff08;云效&#xff0c;gitee&#xff0c;github&#xff0c;Coding等&#xff09;新建一个代码库&#xff0c; 我使用的云效 新建一个develop分支&#xff0c;后续所有人的提交代码都合并到develop分支上面&#xff0c;一般develop分支是用来开发用的&…

尚融宝22-提交借款申请

目录 一、需求介绍 二、图片上传 &#xff08;一&#xff09;前端页面 &#xff08;二&#xff09;实现图片上传 三、数据字典展示 &#xff08;一&#xff09;后端 &#xff08;二&#xff09;前端 四、表单信息提交 &#xff08;一&#xff09;后端 1、VO对象&…

嵌入式工程师如何快速的阅读datasheet的方法

目录 ▎从项目角度来看datasheet ▎各取所需 ▎最后 Datasheet&#xff08;数据手册&#xff09;的快速阅读能力&#xff0c;是每个工程师都应该具备的基本素养。 无论是项目开始阶段的选型还是后续的软硬件设计&#xff0c;到后期的项目调试&#xff0c;经常有工程师对着英…

06-Node.js—模块化

目录 1、介绍1.1 什么是模块化与模块 ?1.2 什么是模块化项目 ?1.3 模块化好处 2、模块暴露数据2.1 模块初体验2.2 暴露数据2.2.1 module.exports value2.2.2 exports.name value 3、导入&#xff08;引入&#xff09;模块4、导入模块的基本流程5、CommonJS 规范参考 1、介绍…

使用RabbitMQ的手动接收模式:消息第二次入队Failed to declare queue

问题&#xff1a;在rabbitMQ测试使用手动接收模式时发生 Failed to declare queue错误 : Channel shutdown: channel error; protocol method: #method<channel.close>(reply-code406, reply-textPRECONDITION_FAILED - unknown delivery tag 1, class-id60, method-id80…

C++ 命名空间、域、缺省参数、函数重载、引用、auto、内联函数的知识点+完整思维导图+基本练习题+深入细节+通俗易懂建议收藏

绪论 从本章开始我们正式进入到C的内容&#xff0c;对此如果没有学习过C语言的建议先将C语言系统的学习一遍后再来&#xff08;已经更新完在专栏就能看到&#xff09;。 话不多说安全带系好&#xff0c;发车啦&#xff08;建议电脑观看&#xff09;。 附&#xff1a;红色&#…

Linux运维基础

一.vim编辑器 1.编辑器介绍 vi/vim是visual interface的简称,是Linux中最经典的文本编辑器&#xff0c;同图形化界面中的文本编辑器一样&#xff0c;vi是命令行下对文本文件进行编辑的绝佳选择&#xff0c;粗暴理解相当于windows下的记事本。 vim是vi的加强版本,兼容vi的所有…

java版UWB人员定位系统源码,提供位置实时显示、历史轨迹回放、电子围栏、行为分析、智能巡检等功能

运用UWB定位技术开发的人员定位系统源码 文末获取联系&#xff01; 本套系统运用UWB定位技术&#xff0c;开发的高精度人员定位系统&#xff0c;通过独特的射频处理&#xff0c;配合先进的位置算法&#xff0c;可以有效计算复杂环境下的人员与物品的活动信息。 提供位置实时显…

SLAM论文速递【SLAM—— DynaSLAM:动态场景中的跟踪、建图和修复—4.19(1)

论文信息 题目&#xff1a; DynaSLAM:Tracking,Mapping and Inpainting in Dynamic Scenes DynaSLAM:动态场景中的跟踪、映射和修复论文地址&#xff1a; https://arxiv.org/pdf/1806.05620.pdf发表期刊&#xff1a; IEEE Robotics and Automation Letters ( Volume: 3, Issu…

RPC一文精通

基础&#xff1a; http是基于应用层协议&#xff0c;对请求和响应进行规范包装,一次http请求就会进行一次tcp连接和断开连接&#xff0c;属于短链接 udp是异步响应&#xff0c;无需建立连接&#xff0c;就可以发送封装的IP数据包 tcp是基于传输层协议&#xff0c;并规范了三…

Python单向循环链表操作

目录 一、单向循环链表 单向循环链表图 二、单向循环链表的操作 1、判断链表是否为空 2&#xff0c;链表长度 3&#xff0c;遍历整个链表 4&#xff0c;在链表头部添加元素 5、链表尾部添加元素 6&#xff0c;在指定位置插入元素 7&#xff0c;修改指定位置的元素 8&a…

JavaSE 和 Java EE 分别是什么

Java 作为最流行的编程语言受到了许多人的喜爱&#xff0c;其在编程中的地位自不必多说。 对于许多才刚刚入门 Java 的朋友来讲&#xff0c;常常会产生这样的困惑&#xff0c;JavaEE是什么&#xff1f;JavaSE又是什么&#xff1f; Java SE Java SE 是 Java Platform, Standa…

Liunx下进程间通信

文章目录 前言1.进程间通信相关介绍2.管道1.匿名管道2.管道的原理3.通过代码来演示匿名管道4.命名管道5.命名管道的原理6.命名管道代码演示 3.System V共享内存1.共享内存原理2.相关系统接口的介绍与共享内存的代码演示3.共享内存的一些特性 4.system V消息队列与system V信号量…

依赖注入方式

Spring中有哪些注入方式? 我们先来思考 向一个类中传递数据的方式有几种? 普通方法(set方法)构造方法 依赖注入描述了在容器中建立bean与bean之间的依赖关系的过程&#xff0c;如果bean运行需要的是数字或 字符串呢? 引用类型简单类型(基本数据类型与String) Spring就…