libipt_TTL.c revision 3efb6ead2e51fe1eca55bcb2b06afb4dc4b8cb7c
1/* Shared library add-on to iptables for the TTL target
2 * (C) 2000 by Harald Welte <laforge@gnumonks.org>
3 *
4 * libipt_TTL.c,v 1.3 2000/11/13 11:16:08 laforge Exp
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>\n"
28"  --ttl-dec value		Decrement TTL by <value>\n"
29"  --ttl-inc value		Increment TTL by <value>\n"
30, NETFILTER_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	u_int8_t 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))
50		exit_error(PARAMETER_PROBLEM,
51				"TTL: unexpected `!'");
52
53	value = atoi(optarg);
54
55	switch (c) {
56
57		case '1':
58			info->mode = IPT_TTL_SET;
59			break;
60
61		case '2':
62			if (value == 0) {
63				exit_error(PARAMETER_PROBLEM,
64					"TTL: decreasing by 0?");
65			}
66
67			info->mode = IPT_TTL_DEC;
68			break;
69
70		case '3':
71			if (value == 0) {
72				exit_error(PARAMETER_PROBLEM,
73					"TTL: increasing by 0?");
74			}
75
76			info->mode = IPT_TTL_INC;
77			break;
78
79		default:
80			return 0;
81
82	}
83
84	info->ttl = value;
85	*flags |= IPT_TTL_USED;
86
87	return 1;
88}
89
90static void final_check(unsigned int flags)
91{
92	if (!(flags & IPT_TTL_USED))
93		exit_error(PARAMETER_PROBLEM,
94				"TTL: You must specify an action");
95}
96
97static void save(const struct ipt_ip *ip,
98		const struct ipt_entry_target *target)
99{
100	const struct ipt_TTL_info *info =
101		(struct ipt_TTL_info *) target->data;
102
103	switch (info->mode) {
104		case IPT_TTL_SET:
105			printf("--ttl-set ");
106			break;
107		case IPT_TTL_DEC:
108			printf("--ttl-dec ");
109			break;
110
111		case IPT_TTL_INC:
112			printf("--ttl-inc ");
113			break;
114	}
115	printf("%u ", info->ttl);
116}
117
118static void print(const struct ipt_ip *ip,
119		const struct ipt_entry_target *target, int numeric)
120{
121	const struct ipt_TTL_info *info =
122		(struct ipt_TTL_info *) target->data;
123
124	printf("TTL ");
125	switch (info->mode) {
126		case IPT_TTL_SET:
127			printf("set to ");
128			break;
129		case IPT_TTL_DEC:
130			printf("decrement by ");
131			break;
132		case IPT_TTL_INC:
133			printf("increment by ");
134			break;
135	}
136	printf("%u ", info->ttl);
137}
138
139static struct option opts[] = {
140	{ "ttl-set", 1, 0, '1' },
141	{ "ttl-dec", 1, 0, '2' },
142	{ "ttl-inc", 1, 0, '3' },
143	{ 0 }
144};
145
146static
147struct iptables_target TTL = { NULL,
148	"TTL",
149	NETFILTER_VERSION,
150	IPT_ALIGN(sizeof(struct ipt_TTL_info)),
151	IPT_ALIGN(sizeof(struct ipt_TTL_info)),
152	&help,
153	&init,
154	&parse,
155	&final_check,
156	&print,
157	&save,
158	opts
159};
160
161void _init(void)
162{
163	register_target(&TTL);
164}
165