zoukankan      html  css  js  c++  java
  • 关于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.彻底仿真世界

    一个实体仅仅能同一时候存在于一个位置!

    就像人一样,进入了一个房间,外面就没有这个人了,可惜编程语言不是这种。

  • 相关阅读:
    sql server 查询当前月份日期列表数据
    redis + cookies 实现持久登入
    JS浏览器兼容问题
    Multicast注册中心
    django模板高级进阶
    django高级视图和URL配置
    django表单操作之django.forms
    django站点管理
    django表单
    django数据库模型
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/6735724.html
Copyright © 2011-2022 走看看