首页 > 代码库 > 关于Netfilter NF_HOOK宏的outdev参数bug
关于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中实时获取;
很简单,在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.彻底仿真世界
一个实体只能同时存在于一个位置!就像人一样,进入了一个房间,外面就没有这个人了,可惜编程语言不是这样的。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。