Netfilter 之 iptable_mangle

initialization

iptable_mangle_table_init function by calling ipt_register_table complete mangle table registration and registration function hook function; the same functions and function calls the process iptable_filter, the analysis will not be repeated here, please venue <iptable_filter analysis>;

. 1  static  int __net_init iptable_mangle_table_init ( struct NET * NET)
 2  {
 . 3      struct ipt_replace * the repl;
 . 4      int RET;
 . 5  
. 6      / * initialized * / 
. 7      IF (NET -> ipv4.iptable_mangle)
 . 8          return  0 ;
 . 9  
10      / * allocate used to register the following structural initialization * / 
. 11      the repl = ipt_alloc_initial_table (& packet_mangler);
 12 is      IF (the repl == NULL)
 13 is          return -ENOMEM;
 14      / * registry and hook function * / 
15      RET = ipt_register_table (NET, & packet_mangler, the repl, mangle_ops,
 16                   & NET -> ipv4.iptable_mangle);
 . 17      kfree (the repl);
 18 is      return RET;
 . 19 }

 

Hook function

From the following hook function which can be seen in all five hooks distributed points;

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 to mangle hook function, if the current is in LOCAL_OUT hook point, you need to call ip_mangle_out function, other shop is called ipt_do_table match is performed; ipt_do_table function analysis is not repeated here, please venue <iptable_filter analysis>;

 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 first save some information about ip header, then call ipt_do_table match is performed, check the ip header after the rule change field is saved, if changes occur, you need to re-check the routing;

 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     = ipt_do_table RET (SKB, State, State-> NET -> ipv4.iptable_mangle);
 27      / * . Reroute for the ANY Change * / 
28      / * After the rule * / 
29      IF (!! && NF_DROP causes RET RET = = NF_STOLEN) {
 30          IPH = ip_hdr (SKB);
 31 is  
32          / * is determined whether ip header fields have changed * / 
33 is          iF ! (iph-> || the saddr the saddr =
 34 is              ! iph-> DADDR = DADDR ||
 35              skb-> Mark! = || Mark
 36              iph-> TOS! = TOS) {
 37 [              / * re-route search * / 
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 }

 

Guess you like

Origin www.cnblogs.com/wanpengcoder/p/11755756.html