Commit 5f2c3b910744f68e1a507f027398f404b3feb5fb

Authored by Harald Welte
Committed by David S. Miller
1 parent 29e4f8b3c3

[NETFILTER]: Add new iptables TTL target

This new iptables target allows manipulation of the TTL of an IPv4 packet.

Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 4 changed files with 155 additions and 0 deletions Side-by-side Diff

include/linux/netfilter_ipv4/ipt_TTL.h
  1 +/* TTL modification module for IP tables
  2 + * (C) 2000 by Harald Welte <laforge@netfilter.org> */
  3 +
  4 +#ifndef _IPT_TTL_H
  5 +#define _IPT_TTL_H
  6 +
  7 +enum {
  8 + IPT_TTL_SET = 0,
  9 + IPT_TTL_INC,
  10 + IPT_TTL_DEC
  11 +};
  12 +
  13 +#define IPT_TTL_MAXMODE IPT_TTL_DEC
  14 +
  15 +struct ipt_TTL_info {
  16 + u_int8_t mode;
  17 + u_int8_t ttl;
  18 +};
  19 +
  20 +
  21 +#endif
net/ipv4/netfilter/Kconfig
... ... @@ -664,6 +664,20 @@
664 664  
665 665 To compile it as a module, choose M here. If unsure, say N.
666 666  
  667 +config IP_NF_TARGET_TTL
  668 + tristate 'TTL target support'
  669 + depends on IP_NF_MANGLE
  670 + help
  671 + This option adds a `TTL' target, which enables the user to modify
  672 + the TTL value of the IP header.
  673 +
  674 + While it is safe to decrement/lower the TTL, this target also enables
  675 + functionality to increment and set the TTL value of the IP header to
  676 + arbitrary values. This is EXTREMELY DANGEROUS since you can easily
  677 + create immortal packets that loop forever on the network.
  678 +
  679 + To compile it as a module, choose M here. If unsure, say N.
  680 +
667 681 config IP_NF_TARGET_CONNMARK
668 682 tristate 'CONNMARK target support'
669 683 depends on IP_NF_CONNTRACK_MARK && IP_NF_MANGLE
net/ipv4/netfilter/Makefile
... ... @@ -85,6 +85,7 @@
85 85 obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
86 86 obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o
87 87 obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o
  88 +obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
88 89  
89 90 # generic ARP tables
90 91 obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o
net/ipv4/netfilter/ipt_TTL.c
  1 +/* TTL modification target for IP tables
  2 + * (C) 2000,2005 by Harald Welte <laforge@netfilter.org>
  3 + *
  4 + * This program is free software; you can redistribute it and/or modify
  5 + * it under the terms of the GNU General Public License version 2 as
  6 + * published by the Free Software Foundation.
  7 + *
  8 + */
  9 +
  10 +#include <linux/module.h>
  11 +#include <linux/skbuff.h>
  12 +#include <linux/ip.h>
  13 +#include <net/checksum.h>
  14 +
  15 +#include <linux/netfilter_ipv4/ip_tables.h>
  16 +#include <linux/netfilter_ipv4/ipt_TTL.h>
  17 +
  18 +MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
  19 +MODULE_DESCRIPTION("IP tables TTL modification module");
  20 +MODULE_LICENSE("GPL");
  21 +
  22 +static unsigned int
  23 +ipt_ttl_target(struct sk_buff **pskb, const struct net_device *in,
  24 + const struct net_device *out, unsigned int hooknum,
  25 + const void *targinfo, void *userinfo)
  26 +{
  27 + struct iphdr *iph;
  28 + const struct ipt_TTL_info *info = targinfo;
  29 + u_int16_t diffs[2];
  30 + int new_ttl;
  31 +
  32 + if (!skb_make_writable(pskb, (*pskb)->len))
  33 + return NF_DROP;
  34 +
  35 + iph = (*pskb)->nh.iph;
  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 + diffs[0] = htons(((unsigned)iph->ttl) << 8) ^ 0xFFFF;
  58 + iph->ttl = new_ttl;
  59 + diffs[1] = htons(((unsigned)iph->ttl) << 8);
  60 + iph->check = csum_fold(csum_partial((char *)diffs,
  61 + sizeof(diffs),
  62 + iph->check^0xFFFF));
  63 + }
  64 +
  65 + return IPT_CONTINUE;
  66 +}
  67 +
  68 +static int ipt_ttl_checkentry(const char *tablename,
  69 + const struct ipt_entry *e,
  70 + void *targinfo,
  71 + unsigned int targinfosize,
  72 + unsigned int hook_mask)
  73 +{
  74 + struct ipt_TTL_info *info = targinfo;
  75 +
  76 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_TTL_info))) {
  77 + printk(KERN_WARNING "ipt_TTL: targinfosize %u != %Zu\n",
  78 + targinfosize,
  79 + IPT_ALIGN(sizeof(struct ipt_TTL_info)));
  80 + return 0;
  81 + }
  82 +
  83 + if (strcmp(tablename, "mangle")) {
  84 + printk(KERN_WARNING "ipt_TTL: can only be called from "
  85 + "\"mangle\" table, not \"%s\"\n", tablename);
  86 + return 0;
  87 + }
  88 +
  89 + if (info->mode > IPT_TTL_MAXMODE) {
  90 + printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n",
  91 + info->mode);
  92 + return 0;
  93 + }
  94 +
  95 + if ((info->mode != IPT_TTL_SET) && (info->ttl == 0))
  96 + return 0;
  97 +
  98 + return 1;
  99 +}
  100 +
  101 +static struct ipt_target ipt_TTL = {
  102 + .name = "TTL",
  103 + .target = ipt_ttl_target,
  104 + .checkentry = ipt_ttl_checkentry,
  105 + .me = THIS_MODULE,
  106 +};
  107 +
  108 +static int __init init(void)
  109 +{
  110 + return ipt_register_target(&ipt_TTL);
  111 +}
  112 +
  113 +static void __exit fini(void)
  114 +{
  115 + ipt_unregister_target(&ipt_TTL);
  116 +}
  117 +
  118 +module_init(init);
  119 +module_exit(fini);