blob: ca83f295b0a07da188be496226e55903784f1c2e [file] [log] [blame]
Harald Welte703828f2000-10-04 15:27:07 +00001/* Shared library add-on to iptables for the TTL target
2 * (C) 2000 by Harald Welte <laforge@gnumonks.org>
3 *
Pablo Neira8caee8b2004-12-28 13:11:59 +00004 * $Id$
Harald Welte703828f2000-10-04 15:27:07 +00005 *
6 * This program is distributed under the terms of GNU GPL
7 */
8#include <stdio.h>
9#include <string.h>
10#include <stdlib.h>
11#include <getopt.h>
12#include <iptables.h>
13
14#include <linux/netfilter_ipv4/ip_tables.h>
15#include <linux/netfilter_ipv4/ipt_TTL.h>
16
17#define IPT_TTL_USED 1
18
19static void init(struct ipt_entry_target *t, unsigned int *nfcache)
20{
21}
22
23static void help(void)
24{
25 printf(
26"TTL target v%s options\n"
Nicolas Bouliane37fd00d2004-07-27 21:46:21 +000027" --ttl-set value Set TTL to <value 0-255>\n"
28" --ttl-dec value Decrement TTL by <value 1-255>\n"
29" --ttl-inc value Increment TTL by <value 1-255>\n"
Harald Welte80fe35d2002-05-29 13:08:15 +000030, IPTABLES_VERSION);
Harald Welte703828f2000-10-04 15:27:07 +000031}
32
33static int parse(int c, char **argv, int invert, unsigned int *flags,
34 const struct ipt_entry *entry,
35 struct ipt_entry_target **target)
36{
37 struct ipt_TTL_info *info = (struct ipt_TTL_info *) (*target)->data;
Nicolas Bouliane37fd00d2004-07-27 21:46:21 +000038 unsigned int value;
Harald Welte703828f2000-10-04 15:27:07 +000039
40 if (*flags & IPT_TTL_USED) {
41 exit_error(PARAMETER_PROBLEM,
42 "Can't specify TTL option twice");
43 }
44
45 if (!optarg)
46 exit_error(PARAMETER_PROBLEM,
47 "TTL: You must specify a value");
48
Harald Welteb77f1da2002-03-14 11:35:58 +000049 if (check_inverse(optarg, &invert, NULL, 0))
Harald Welte703828f2000-10-04 15:27:07 +000050 exit_error(PARAMETER_PROBLEM,
51 "TTL: unexpected `!'");
52
Nicolas Bouliane37fd00d2004-07-27 21:46:21 +000053 if (string_to_number(optarg, 0, 255, &value) == -1)
54 exit_error(PARAMETER_PROBLEM,
55 "TTL: Expected value between 0 and 255");
Harald Welte703828f2000-10-04 15:27:07 +000056
57 switch (c) {
58
59 case '1':
60 info->mode = IPT_TTL_SET;
61 break;
62
63 case '2':
64 if (value == 0) {
65 exit_error(PARAMETER_PROBLEM,
66 "TTL: decreasing by 0?");
67 }
68
69 info->mode = IPT_TTL_DEC;
70 break;
71
72 case '3':
73 if (value == 0) {
74 exit_error(PARAMETER_PROBLEM,
75 "TTL: increasing by 0?");
76 }
77
78 info->mode = IPT_TTL_INC;
79 break;
80
81 default:
82 return 0;
83
84 }
85
86 info->ttl = value;
87 *flags |= IPT_TTL_USED;
88
89 return 1;
90}
91
92static void final_check(unsigned int flags)
93{
94 if (!(flags & IPT_TTL_USED))
95 exit_error(PARAMETER_PROBLEM,
96 "TTL: You must specify an action");
97}
98
99static void save(const struct ipt_ip *ip,
100 const struct ipt_entry_target *target)
101{
102 const struct ipt_TTL_info *info =
103 (struct ipt_TTL_info *) target->data;
104
105 switch (info->mode) {
106 case IPT_TTL_SET:
107 printf("--ttl-set ");
108 break;
109 case IPT_TTL_DEC:
110 printf("--ttl-dec ");
111 break;
112
113 case IPT_TTL_INC:
114 printf("--ttl-inc ");
115 break;
116 }
117 printf("%u ", info->ttl);
118}
119
120static void print(const struct ipt_ip *ip,
121 const struct ipt_entry_target *target, int numeric)
122{
123 const struct ipt_TTL_info *info =
124 (struct ipt_TTL_info *) target->data;
125
126 printf("TTL ");
127 switch (info->mode) {
128 case IPT_TTL_SET:
129 printf("set to ");
130 break;
131 case IPT_TTL_DEC:
132 printf("decrement by ");
133 break;
134 case IPT_TTL_INC:
135 printf("increment by ");
136 break;
137 }
138 printf("%u ", info->ttl);
139}
140
141static struct option opts[] = {
142 { "ttl-set", 1, 0, '1' },
143 { "ttl-dec", 1, 0, '2' },
144 { "ttl-inc", 1, 0, '3' },
145 { 0 }
146};
147
Pablo Neira8caee8b2004-12-28 13:11:59 +0000148static struct iptables_target TTL = {
149 .next = NULL,
150 .name = "TTL",
151 .version = IPTABLES_VERSION,
152 .size = IPT_ALIGN(sizeof(struct ipt_TTL_info)),
153 .userspacesize = IPT_ALIGN(sizeof(struct ipt_TTL_info)),
154 .help = &help,
155 .init = &init,
156 .parse = &parse,
157 .final_check = &final_check,
158 .print = &print,
159 .save = &save,
160 .extra_opts = opts
Harald Welte703828f2000-10-04 15:27:07 +0000161};
162
163void _init(void)
164{
165 register_target(&TTL);
166}