关于Netfilter NF_HOOK宏的outdev參数bug
1.首先指出。NF_HOOK系列宏的outdev參数的传递方式(直接传递一个net_device结构体指针)是不对的
正确的方式要么是不传递。要么是传递指针的地址,即地址的地址。
2.接下来指出,仅仅传递一个地址为何不对
由于在该HOOK点可能存在多个HOOK函数,每个函数都有可能改变skb的路由,即调用reroute,比方NAT,比方IP Mark等,这样兴许的HOOK函数看到的依旧是旧的outdev參数,而不是reroute之后的skb_dst(skb)->dev。
3.然后看一个实际出错样例
设置默认路由
0.0.0.0/0 via 192.168.1.1 eth0
设置策略路由
iptables -t mangle -A OUTPUT -d 1.1.1.1 -j MARK --set-mark 100
ip rule fwmark 100 table my
ip route add 0.0.0.0/0 via 192.168.2.1 dev eth1 table my
防止mark 100的数据包从eth0出去(这实际上仅仅是为了展现问题而加入的多余的一条规则)
iptables -A OUTPUT -d 1.1.1.1 -o eth0 -j DROP
效果是到达1.1.1.1的数据包被DROP掉了。是的,策略路由确实生效了,问题在于进入OUTPUT的filter HOOK函数的时候,outdev还是旧的outdev。由于OUTPUT处在路由之后。假设当中的mangle表改变了skb的mark,那么会reroute,不幸的是,reroute并无法改变OUTPUT点上NF_HOOK的outdev參数值!
4.怎么修正
办法非常多,依次介绍:
a.使用setsockopt打mark而不是iptables打mark,绕开OUTPUT和路由的暧昧关系;
b.改动NF_HOOK的dev參数为struct net_device **类型,然后在reroute中重路由成功后运行*out = (struct dst_entry*)skb_dst(skb)->dev;从而改变NF_HOOK中的outdev的值;
c.去掉NF_HOOK宏的outdev參数。须要时从skb_dst(skb)->dev中实时获取。
非常easy。在ipt_do_table的开头位置。即变量声明的完结处,加入以下的代码:
struct xt_target_param tgpar;
#if 1
struct dst_entry *dst_e = skb_dst(skb);
if (dst_e) {
out = dst_e->dev;
}
#endif
实时替换掉參数定义的out值。
d.使用非传值机制!
C语言是传值的啊!
使用连续的******能够为了寻址一个字节遍历整个内存。即整个内存仅仅存储一个字节的值,其他的都被填满为它的直接或者间接的地址,地址,地址...
5.彻底仿真世界
就像人一样,进入了一个房间,外面就没有这个人了,可惜编程语言不是这种。
关于Netfilter NF_HOOK宏的outdev參数bug的更多相关文章
- C语言利用va_list、va_start、va_end、va_arg宏定义可变參数的函数
在定义可变參数的函数之前,先来理解一下函数參数的传递原理: 1.函数參数是以栈这样的数据结构来存取的,在函数參数列表中,从右至左依次入栈. 2.參数的内存存放格式:參数的内存地址存放在内存的堆栈段中, ...
- C语言变长參数的认识以及宏实现
1.认识 变长參数是C语言的特殊參数形式.比如例如以下函数声明: int printf(const char *format, ....); 如此的声明表明,printf函数除了第一个參数类型为con ...
- OC可变參数的函数实现va_start、va_end、va_list的使用
一.简单介绍 我们常常在编程的时候看见类似这种代码,如图1.1 图1.1 或者是这种可变參数,如图1.2 图1.2 二.基本知识介绍 在学习怎样写这样的格式的函数前,先简介几个经常使用的宏: 下面摘自 ...
- C语言中的system函数參数具体解释
http://blog.csdn.net/pipisorry/article/details/33024727 函数名: system 功 能: 发出一个DOS命令 用 法: int sy ...
- RPM安装包-Spec文件參数具体解释与演示样例分析
spec文件是整个RPM包建立过程的中心,它的作用就如同编译程序时的Makefile文件. 1.Spec文件參数 spec文件包括建立一个RPM包必需的信息,包括哪些文件是包的一部分以及它们安装在哪个 ...
- C语言可变长參数实现原理
微博:http://weibo.com/u/2203007022 (1) C语言可变參数 我们能够从C语言的printf得出可变參数的作用.printf函数的原型例如 ...
- 【深夜福利】Caffe 添加自己定义 Layer 及其 ProtoBuffer 參数
在飞驰的列车上,无法入眠.外面阴雨绵绵,思绪被拉扯到天边. 翻看之前聊天,想起还欠一个读者一篇博客. 于是花了点时间整理一下之前学习 Caffe 时添加自己定义 Layer 及自己定义 ProtoBu ...
- Direcshow中视频捕捉和參数设置报告
Direcshow中视频捕捉和參数设置报告 1. 关于视频捕捉(About Video Capture in Dshow) 1视频捕捉Graph的构建 一个能够捕捉音频或者视频的graph图 ...
- linux kernel的cmdline參数解析原理分析
利用工作之便,今天研究了kernel下cmdline參数解析过程.记录在此.与大家共享.转载请注明出处.谢谢. Kernel 版本:3.4.55 Kernel启动时会解析cmdline,然后依据这些參 ...
随机推荐
- iScroll示例,下拉刷新,上拉刷新
iScroll示例,下拉刷新,上拉刷新 <!DOCTYPE html> <html> <head> <meta http-equiv="Conten ...
- 9款HTML5实现的超酷特效
之前我们推荐了8款HTML5实现的特效和应用,今天我们带来的这9款热门的HTML5特效同样会带给你全新的视角和体验. HTML5是HTML的升级版,HTML5有两大特点:首先,强化了 Web 网页的表 ...
- Toast.makeText 方法出错 java.lang.RuntimeException
接手以前同事留下的代码,今天突然出现了一个bug: java.lang.RuntimeException: Can't create handler inside thread that has no ...
- 【转】Linux下的多线程编程背景知识
1. 进程和线程 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的 Unix也支持线程的概念,但是在一个进程(pr ...
- Android 再按一次退出应用的代码
private long exitTime = 0; @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (key ...
- Java之JVM调优案例分析与实战(2) - 集群间同步导致的内存溢出
环境:一个基于B/S的MIS系统,硬件为两台2个CPU.8GB内存的HP小型机,服务器是WebLogic 9.2,每台机器启动了3个WebLogic实例,构成一个6个节点的亲合式集群. 说明:由于是亲 ...
- Autofac3 在MVC4中的运用原理
这是一种新的开发模式,注入开发模式,或者叫它IOC模式,说起IOC你可以这样去理解它,它为你的某个实现流出一个注入点,你生产的对象,可以根据你之前的配置进行组合. IOC全称是Inversion o ...
- unity模型任意无限切割插件
概述 3d模型的任意切割一直是游戏开发里的一个很大的问题,模型切割的关键点就只有生成横切面的新顶点以及切口纹理的缝合,理论上解决了这两点,就近乎可以做到以假乱真的程度了.本篇文章就这两点进行描述 详细 ...
- 数据库-IO系统性能之衡量性能的几个指标
转自http://storage.it168.com/a2011/0323/1169/000001169755_all.shtml 作为一个数据库管理员,关注系统的性能是日常最重要的工作之一,而在所关 ...
- IntelliJ Idea各种技巧设置笔记和错误解决
版本控制 GitHub GitHub提示找不到路径: 解决方法:去官方下载gitHub,然后在以下路径找到Git.exe并设置 C:\Users\你的用户\AppData\Local\GitHub\P ...