zoukankan      html  css  js  c++  java
  • Netfilter 之 iptable_mangle

    初始化

    iptable_mangle_table_init函数通过调用ipt_register_table完成mangle表注册和钩子函数注册的功能;该流程与iptable_filter的函数调用的函数一致,此处不再重复分析,详情请移步<iptable_filter分析>;

     1 static int __net_init iptable_mangle_table_init(struct net *net)
     2 {
     3     struct ipt_replace *repl;
     4     int ret;
     5 
     6     /* 已经初始化 */
     7     if (net->ipv4.iptable_mangle)
     8         return 0;
     9 
    10     /* 分配初始化用于下面注册的结构 */
    11     repl = ipt_alloc_initial_table(&packet_mangler);
    12     if (repl == NULL)
    13         return -ENOMEM;
    14     /* 注册表和钩子函数 */
    15     ret = ipt_register_table(net, &packet_mangler, repl, mangle_ops,
    16                  &net->ipv4.iptable_mangle);
    17     kfree(repl);
    18     return ret;
    19 }
    钩子函数

    从下面的钩子函数可以看到其分布于全部5个钩子点;

    1 #define MANGLE_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | 
    2                 (1 << NF_INET_LOCAL_IN) | 
    3                 (1 << NF_INET_FORWARD) | 
    4                 (1 << NF_INET_LOCAL_OUT) | 
    5                 (1 << NF_INET_POST_ROUTING))
    1 static const struct xt_table packet_mangler = {
    2     .name        = "mangle",
    3     .valid_hooks    = MANGLE_VALID_HOOKS,
    4     .me        = THIS_MODULE,
    5     .af        = NFPROTO_IPV4,
    6     .priority    = NF_IP_PRI_MANGLE,
    7     .table_init    = iptable_mangle_table_init,
    8 };

    iptable_mangle_hook为mangle钩子函数,如果当前是处于LOCAL_OUT钩子点,则需要调用ip_mangle_out函数,其他店则调用ipt_do_table进行规则匹配;ipt_do_table函数此处不再重复分析,详情请移步<iptable_filter分析>;

     1 static unsigned int
     2 iptable_mangle_hook(void *priv,
     3              struct sk_buff *skb,
     4              const struct nf_hook_state *state)
     5 {
     6     /* LOCAL_OUT钩子点,调用mangle_out */
     7     if (state->hook == NF_INET_LOCAL_OUT)
     8         return ipt_mangle_out(skb, state);
     9     /* 规则匹配 */
    10     return ipt_do_table(skb, state, state->net->ipv4.iptable_mangle);
    11 }

    ipt_mangle_out首先保存ip头部的一些信息,然后调用ipt_do_table进行规则匹配,规则之后检查ip头中的保存字段是否发生变化,如果发生变化,则需要重新查路由;

     1 static unsigned int
     2 ipt_mangle_out(struct sk_buff *skb, const struct nf_hook_state *state)
     3 {
     4     unsigned int ret;
     5     const struct iphdr *iph;
     6     u_int8_t tos;
     7     __be32 saddr, daddr;
     8     u_int32_t mark;
     9     int err;
    10 
    11     /* root is playing with raw sockets. */
    12     /* 原始套接字 */
    13     if (skb->len < sizeof(struct iphdr) ||
    14         ip_hdrlen(skb) < sizeof(struct iphdr))
    15         return NF_ACCEPT;
    16 
    17     /* Save things which could affect route */
    18     
    19     mark = skb->mark;
    20     iph = ip_hdr(skb);
    21     saddr = iph->saddr;
    22     daddr = iph->daddr;
    23     tos = iph->tos;
    24 
    25     /* 进行规则匹配 */
    26     ret = ipt_do_table(skb, state, state->net->ipv4.iptable_mangle);
    27     /* Reroute for ANY change. */
    28     /* 经过规则后 */
    29     if (ret != NF_DROP && ret != NF_STOLEN) {
    30         iph = ip_hdr(skb);
    31 
    32         /* 判断ip头中的字段是否有改变 */
    33         if (iph->saddr != saddr ||
    34             iph->daddr != daddr ||
    35             skb->mark != mark ||
    36             iph->tos != tos) {
    37             /* 重新查路由 */
    38             err = ip_route_me_harder(state->net, skb, RTN_UNSPEC);
    39             if (err < 0)
    40                 ret = NF_DROP_ERR(err);
    41         }
    42     }
    43 
    44     return ret;
    45 }
  • 相关阅读:
    mina简介
    idea编辑器jdk版本报错
    设计模式之-工厂模式
    设计模式之-外观模式
    ssm项目中bean注入失败,获取spring中指定bean之解决方案
    Jquery.Page.js 分页插件的使用
    发现某网站低级致命漏洞引发的对多用户系统安全性讨论
    C#微信公众号开发之网页授权oauth2.0获取用户基本信息(一)
    有关C#中使用if else和try catch的问题及效率问题
    C#伪静态实现的方法
  • 原文地址:https://www.cnblogs.com/wanpengcoder/p/11755756.html
Copyright © 2011-2022 走看看