root/net/netfilter/xt_HL.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ttl_tg
  2. hl_tg6
  3. ttl_tg_check
  4. hl_tg6_check
  5. hl_tg_init
  6. hl_tg_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * TTL modification target for IP tables
   4  * (C) 2000,2005 by Harald Welte <laforge@netfilter.org>
   5  *
   6  * Hop Limit modification target for ip6tables
   7  * Maciej Soltysiak <solt@dns.toxicfilms.tv>
   8  */
   9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  10 #include <linux/module.h>
  11 #include <linux/skbuff.h>
  12 #include <linux/ip.h>
  13 #include <linux/ipv6.h>
  14 #include <net/checksum.h>
  15 
  16 #include <linux/netfilter/x_tables.h>
  17 #include <linux/netfilter_ipv4/ipt_TTL.h>
  18 #include <linux/netfilter_ipv6/ip6t_HL.h>
  19 
  20 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
  21 MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
  22 MODULE_DESCRIPTION("Xtables: Hoplimit/TTL Limit field modification target");
  23 MODULE_LICENSE("GPL");
  24 
  25 static unsigned int
  26 ttl_tg(struct sk_buff *skb, const struct xt_action_param *par)
  27 {
  28         struct iphdr *iph;
  29         const struct ipt_TTL_info *info = par->targinfo;
  30         int new_ttl;
  31 
  32         if (skb_ensure_writable(skb, sizeof(*iph)))
  33                 return NF_DROP;
  34 
  35         iph = ip_hdr(skb);
  36 
  37         switch (info->mode) {
  38         case IPT_TTL_SET:
  39                 new_ttl = info->ttl;
  40                 break;
  41         case IPT_TTL_INC:
  42                 new_ttl = iph->ttl + info->ttl;
  43                 if (new_ttl > 255)
  44                         new_ttl = 255;
  45                 break;
  46         case IPT_TTL_DEC:
  47                 new_ttl = iph->ttl - info->ttl;
  48                 if (new_ttl < 0)
  49                         new_ttl = 0;
  50                 break;
  51         default:
  52                 new_ttl = iph->ttl;
  53                 break;
  54         }
  55 
  56         if (new_ttl != iph->ttl) {
  57                 csum_replace2(&iph->check, htons(iph->ttl << 8),
  58                                            htons(new_ttl << 8));
  59                 iph->ttl = new_ttl;
  60         }
  61 
  62         return XT_CONTINUE;
  63 }
  64 
  65 static unsigned int
  66 hl_tg6(struct sk_buff *skb, const struct xt_action_param *par)
  67 {
  68         struct ipv6hdr *ip6h;
  69         const struct ip6t_HL_info *info = par->targinfo;
  70         int new_hl;
  71 
  72         if (skb_ensure_writable(skb, sizeof(*ip6h)))
  73                 return NF_DROP;
  74 
  75         ip6h = ipv6_hdr(skb);
  76 
  77         switch (info->mode) {
  78         case IP6T_HL_SET:
  79                 new_hl = info->hop_limit;
  80                 break;
  81         case IP6T_HL_INC:
  82                 new_hl = ip6h->hop_limit + info->hop_limit;
  83                 if (new_hl > 255)
  84                         new_hl = 255;
  85                 break;
  86         case IP6T_HL_DEC:
  87                 new_hl = ip6h->hop_limit - info->hop_limit;
  88                 if (new_hl < 0)
  89                         new_hl = 0;
  90                 break;
  91         default:
  92                 new_hl = ip6h->hop_limit;
  93                 break;
  94         }
  95 
  96         ip6h->hop_limit = new_hl;
  97 
  98         return XT_CONTINUE;
  99 }
 100 
 101 static int ttl_tg_check(const struct xt_tgchk_param *par)
 102 {
 103         const struct ipt_TTL_info *info = par->targinfo;
 104 
 105         if (info->mode > IPT_TTL_MAXMODE)
 106                 return -EINVAL;
 107         if (info->mode != IPT_TTL_SET && info->ttl == 0)
 108                 return -EINVAL;
 109         return 0;
 110 }
 111 
 112 static int hl_tg6_check(const struct xt_tgchk_param *par)
 113 {
 114         const struct ip6t_HL_info *info = par->targinfo;
 115 
 116         if (info->mode > IP6T_HL_MAXMODE)
 117                 return -EINVAL;
 118         if (info->mode != IP6T_HL_SET && info->hop_limit == 0)
 119                 return -EINVAL;
 120         return 0;
 121 }
 122 
 123 static struct xt_target hl_tg_reg[] __read_mostly = {
 124         {
 125                 .name       = "TTL",
 126                 .revision   = 0,
 127                 .family     = NFPROTO_IPV4,
 128                 .target     = ttl_tg,
 129                 .targetsize = sizeof(struct ipt_TTL_info),
 130                 .table      = "mangle",
 131                 .checkentry = ttl_tg_check,
 132                 .me         = THIS_MODULE,
 133         },
 134         {
 135                 .name       = "HL",
 136                 .revision   = 0,
 137                 .family     = NFPROTO_IPV6,
 138                 .target     = hl_tg6,
 139                 .targetsize = sizeof(struct ip6t_HL_info),
 140                 .table      = "mangle",
 141                 .checkentry = hl_tg6_check,
 142                 .me         = THIS_MODULE,
 143         },
 144 };
 145 
 146 static int __init hl_tg_init(void)
 147 {
 148         return xt_register_targets(hl_tg_reg, ARRAY_SIZE(hl_tg_reg));
 149 }
 150 
 151 static void __exit hl_tg_exit(void)
 152 {
 153         xt_unregister_targets(hl_tg_reg, ARRAY_SIZE(hl_tg_reg));
 154 }
 155 
 156 module_init(hl_tg_init);
 157 module_exit(hl_tg_exit);
 158 MODULE_ALIAS("ipt_TTL");
 159 MODULE_ALIAS("ip6t_HL");

/* [<][>][^][v][top][bottom][index][help] */