libipt_TTL.c revision 1d5b63d12984d12c8d87242179855e17657be16d
1/* Shared library add-on to iptables for the TTL target
2 * (C) 2000 by Harald Welte <laforge@gnumonks.org>
3 *
4 * $Id$
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 TTL_help(void)
20{
21	printf(
22"TTL target v%s options\n"
23"  --ttl-set value		Set TTL to <value 0-255>\n"
24"  --ttl-dec value		Decrement TTL by <value 1-255>\n"
25"  --ttl-inc value		Increment TTL by <value 1-255>\n"
26, IPTABLES_VERSION);
27}
28
29static int TTL_parse(int c, char **argv, int invert, unsigned int *flags,
30                     const void *entry, struct xt_entry_target **target)
31{
32	struct ipt_TTL_info *info = (struct ipt_TTL_info *) (*target)->data;
33	unsigned int value;
34
35	if (*flags & IPT_TTL_USED) {
36		exit_error(PARAMETER_PROBLEM,
37				"Can't specify TTL option twice");
38	}
39
40	if (!optarg)
41		exit_error(PARAMETER_PROBLEM,
42				"TTL: You must specify a value");
43
44	if (check_inverse(optarg, &invert, NULL, 0))
45		exit_error(PARAMETER_PROBLEM,
46				"TTL: unexpected `!'");
47
48	if (string_to_number(optarg, 0, 255, &value) == -1)
49		exit_error(PARAMETER_PROBLEM,
50		           "TTL: Expected value between 0 and 255");
51
52	switch (c) {
53
54		case '1':
55			info->mode = IPT_TTL_SET;
56			break;
57
58		case '2':
59			if (value == 0) {
60				exit_error(PARAMETER_PROBLEM,
61					"TTL: decreasing by 0?");
62			}
63
64			info->mode = IPT_TTL_DEC;
65			break;
66
67		case '3':
68			if (value == 0) {
69				exit_error(PARAMETER_PROBLEM,
70					"TTL: increasing by 0?");
71			}
72
73			info->mode = IPT_TTL_INC;
74			break;
75
76		default:
77			return 0;
78
79	}
80
81	info->ttl = value;
82	*flags |= IPT_TTL_USED;
83
84	return 1;
85}
86
87static void TTL_check(unsigned int flags)
88{
89	if (!(flags & IPT_TTL_USED))
90		exit_error(PARAMETER_PROBLEM,
91				"TTL: You must specify an action");
92}
93
94static void TTL_save(const void *ip, const struct xt_entry_target *target)
95{
96	const struct ipt_TTL_info *info =
97		(struct ipt_TTL_info *) target->data;
98
99	switch (info->mode) {
100		case IPT_TTL_SET:
101			printf("--ttl-set ");
102			break;
103		case IPT_TTL_DEC:
104			printf("--ttl-dec ");
105			break;
106
107		case IPT_TTL_INC:
108			printf("--ttl-inc ");
109			break;
110	}
111	printf("%u ", info->ttl);
112}
113
114static void TTL_print(const void *ip, const struct xt_entry_target *target,
115                      int numeric)
116{
117	const struct ipt_TTL_info *info =
118		(struct ipt_TTL_info *) target->data;
119
120	printf("TTL ");
121	switch (info->mode) {
122		case IPT_TTL_SET:
123			printf("set to ");
124			break;
125		case IPT_TTL_DEC:
126			printf("decrement by ");
127			break;
128		case IPT_TTL_INC:
129			printf("increment by ");
130			break;
131	}
132	printf("%u ", info->ttl);
133}
134
135static const struct option TTL_opts[] = {
136	{ "ttl-set", 1, NULL, '1' },
137	{ "ttl-dec", 1, NULL, '2' },
138	{ "ttl-inc", 1, NULL, '3' },
139	{ }
140};
141
142static struct iptables_target ttl_target = {
143	.next		= NULL,
144	.name		= "TTL",
145	.version	= IPTABLES_VERSION,
146	.size		= IPT_ALIGN(sizeof(struct ipt_TTL_info)),
147	.userspacesize	= IPT_ALIGN(sizeof(struct ipt_TTL_info)),
148	.help		= TTL_help,
149	.parse		= TTL_parse,
150	.final_check	= TTL_check,
151	.print		= TTL_print,
152	.save		= TTL_save,
153	.extra_opts	= TTL_opts,
154};
155
156void _init(void)
157{
158	register_target(&ttl_target);
159}
160