libipt_TTL.c revision 32b8e61e4e5bd405d9ad07bf9468498dfbb19f9e
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 <stdbool.h>
9#include <stdio.h>
10#include <string.h>
11#include <stdlib.h>
12#include <getopt.h>
13#include <xtables.h>
14
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 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}
27
28static int TTL_parse(int c, char **argv, int invert, unsigned int *flags,
29                     const void *entry, struct xt_entry_target **target)
30{
31	struct ipt_TTL_info *info = (struct ipt_TTL_info *) (*target)->data;
32	unsigned int value;
33
34	if (*flags & IPT_TTL_USED) {
35		xtables_error(PARAMETER_PROBLEM,
36				"Can't specify TTL option twice");
37	}
38
39	if (!optarg)
40		xtables_error(PARAMETER_PROBLEM,
41				"TTL: You must specify a value");
42
43	if (xtables_check_inverse(optarg, &invert, NULL, 0, argv))
44		xtables_error(PARAMETER_PROBLEM,
45				"TTL: unexpected `!'");
46
47	if (!xtables_strtoui(optarg, NULL, &value, 0, UINT8_MAX))
48		xtables_error(PARAMETER_PROBLEM,
49		           "TTL: Expected value between 0 and 255");
50
51	switch (c) {
52
53		case '1':
54			info->mode = IPT_TTL_SET;
55			break;
56
57		case '2':
58			if (value == 0) {
59				xtables_error(PARAMETER_PROBLEM,
60					"TTL: decreasing by 0?");
61			}
62
63			info->mode = IPT_TTL_DEC;
64			break;
65
66		case '3':
67			if (value == 0) {
68				xtables_error(PARAMETER_PROBLEM,
69					"TTL: increasing by 0?");
70			}
71
72			info->mode = IPT_TTL_INC;
73			break;
74
75		default:
76			return 0;
77
78	}
79
80	info->ttl = value;
81	*flags |= IPT_TTL_USED;
82
83	return 1;
84}
85
86static void TTL_check(unsigned int flags)
87{
88	if (!(flags & IPT_TTL_USED))
89		xtables_error(PARAMETER_PROBLEM,
90				"TTL: You must specify an action");
91}
92
93static void TTL_save(const void *ip, const struct xt_entry_target *target)
94{
95	const struct ipt_TTL_info *info =
96		(struct ipt_TTL_info *) target->data;
97
98	switch (info->mode) {
99		case IPT_TTL_SET:
100			printf("--ttl-set ");
101			break;
102		case IPT_TTL_DEC:
103			printf("--ttl-dec ");
104			break;
105
106		case IPT_TTL_INC:
107			printf("--ttl-inc ");
108			break;
109	}
110	printf("%u ", info->ttl);
111}
112
113static void TTL_print(const void *ip, const struct xt_entry_target *target,
114                      int numeric)
115{
116	const struct ipt_TTL_info *info =
117		(struct ipt_TTL_info *) target->data;
118
119	printf("TTL ");
120	switch (info->mode) {
121		case IPT_TTL_SET:
122			printf("set to ");
123			break;
124		case IPT_TTL_DEC:
125			printf("decrement by ");
126			break;
127		case IPT_TTL_INC:
128			printf("increment by ");
129			break;
130	}
131	printf("%u ", info->ttl);
132}
133
134static const struct option TTL_opts[] = {
135	{.name = "ttl-set", .has_arg = true, .val = '1'},
136	{.name = "ttl-dec", .has_arg = true, .val = '2'},
137	{.name = "ttl-inc", .has_arg = true, .val = '3'},
138	XT_GETOPT_TABLEEND,
139};
140
141static struct xtables_target ttl_tg_reg = {
142	.name		= "TTL",
143	.version	= XTABLES_VERSION,
144	.family		= NFPROTO_IPV4,
145	.size		= XT_ALIGN(sizeof(struct ipt_TTL_info)),
146	.userspacesize	= XT_ALIGN(sizeof(struct ipt_TTL_info)),
147	.help		= TTL_help,
148	.parse		= TTL_parse,
149	.final_check	= TTL_check,
150	.print		= TTL_print,
151	.save		= TTL_save,
152	.extra_opts	= TTL_opts,
153};
154
155void _init(void)
156{
157	xtables_register_target(&ttl_tg_reg);
158}
159