libipt_TTL.c revision 4008138e2b5248940265b160fae001d8954fae21
1/* Shared library add-on to iptables for the TTL target
2 * (C) 2000 by Harald Welte <laforge@gnumonks.org>
3 *
4 * $Id: libipt_TTL.c 3507 2004-12-28 13:11:59Z /C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=rusty/emailAddress=rusty@netfilter.org $
5 *
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"
27"  --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"
30, IPTABLES_VERSION);
31}
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;
38	unsigned int value;
39
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
49	if (check_inverse(optarg, &invert, NULL, 0))
50		exit_error(PARAMETER_PROBLEM,
51				"TTL: unexpected `!'");
52
53	if (string_to_number(optarg, 0, 255, &value) == -1)
54		exit_error(PARAMETER_PROBLEM,
55		           "TTL: Expected value between 0 and 255");
56
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
148static 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
161};
162
163void ipt_TTL_init(void)
164{
165	register_target(&TTL);
166}
167