libipt_ttl.c revision 9ee386a1b6d7704b259460152c959ab0e79e02aa
1/* Shared library add-on to iptables to add TTL matching support
2 * (C) 2000 by Harald Welte <laforge@gnumonks.org>
3 *
4 * $Id$
5 *
6 * This program is released under the terms of GNU GPL */
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.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
17static void ttl_help(void)
18{
19	printf(
20"TTL match v%s options:\n"
21"  --ttl-eq value	Match time to live value\n"
22"  --ttl-lt value	Match TTL < value\n"
23"  --ttl-gt value	Match TTL > value\n"
24, IPTABLES_VERSION);
25}
26
27static int ttl_parse(int c, char **argv, int invert, unsigned int *flags,
28                     const void *entry, struct xt_entry_match **match)
29{
30	struct ipt_ttl_info *info = (struct ipt_ttl_info *) (*match)->data;
31	unsigned int value;
32
33	check_inverse(optarg, &invert, &optind, 0);
34
35	switch (c) {
36		case '2':
37			if (string_to_number(optarg, 0, 255, &value) == -1)
38				exit_error(PARAMETER_PROBLEM,
39				           "ttl: Expected value between 0 and 255");
40
41			if (invert)
42				info->mode = IPT_TTL_NE;
43			else
44				info->mode = IPT_TTL_EQ;
45
46			/* is 0 allowed? */
47			info->ttl = value;
48			break;
49		case '3':
50			if (string_to_number(optarg, 0, 255, &value) == -1)
51				exit_error(PARAMETER_PROBLEM,
52				           "ttl: Expected value between 0 and 255");
53
54			if (invert)
55				exit_error(PARAMETER_PROBLEM,
56						"ttl: unexpected `!'");
57
58			info->mode = IPT_TTL_LT;
59			info->ttl = value;
60			break;
61		case '4':
62			if (string_to_number(optarg, 0, 255, &value) == -1)
63				exit_error(PARAMETER_PROBLEM,
64				           "ttl: Expected value between 0 and 255");
65
66			if (invert)
67				exit_error(PARAMETER_PROBLEM,
68						"ttl: unexpected `!'");
69
70			info->mode = IPT_TTL_GT;
71			info->ttl = value;
72			break;
73		default:
74			return 0;
75
76	}
77
78	if (*flags)
79		exit_error(PARAMETER_PROBLEM,
80				"Can't specify TTL option twice");
81	*flags = 1;
82
83	return 1;
84}
85
86static void ttl_check(unsigned int flags)
87{
88	if (!flags)
89		exit_error(PARAMETER_PROBLEM,
90			"TTL match: You must specify one of "
91			"`--ttl-eq', `--ttl-lt', `--ttl-gt");
92}
93
94static void ttl_print(const void *ip, const struct xt_entry_match *match,
95                      int numeric)
96{
97	const struct ipt_ttl_info *info =
98		(struct ipt_ttl_info *) match->data;
99
100	printf("TTL match ");
101	switch (info->mode) {
102		case IPT_TTL_EQ:
103			printf("TTL == ");
104			break;
105		case IPT_TTL_NE:
106			printf("TTL != ");
107			break;
108		case IPT_TTL_LT:
109			printf("TTL < ");
110			break;
111		case IPT_TTL_GT:
112			printf("TTL > ");
113			break;
114	}
115	printf("%u ", info->ttl);
116}
117
118static void ttl_save(const void *ip, const struct xt_entry_match *match)
119{
120	const struct ipt_ttl_info *info =
121		(struct ipt_ttl_info *) match->data;
122
123	switch (info->mode) {
124		case IPT_TTL_EQ:
125			printf("--ttl-eq ");
126			break;
127		case IPT_TTL_NE:
128			printf("! --ttl-eq ");
129			break;
130		case IPT_TTL_LT:
131			printf("--ttl-lt ");
132			break;
133		case IPT_TTL_GT:
134			printf("--ttl-gt ");
135			break;
136		default:
137			/* error */
138			break;
139	}
140	printf("%u ", info->ttl);
141}
142
143static const struct option ttl_opts[] = {
144	{ "ttl", 1, NULL, '2' },
145	{ "ttl-eq", 1, NULL, '2'},
146	{ "ttl-lt", 1, NULL, '3'},
147	{ "ttl-gt", 1, NULL, '4'},
148	{ .name = NULL }
149};
150
151static struct iptables_match ttl_match = {
152	.name		= "ttl",
153	.version	= IPTABLES_VERSION,
154	.size		= IPT_ALIGN(sizeof(struct ipt_ttl_info)),
155	.userspacesize	= IPT_ALIGN(sizeof(struct ipt_ttl_info)),
156	.help		= ttl_help,
157	.parse		= ttl_parse,
158	.final_check	= ttl_check,
159	.print		= ttl_print,
160	.save		= ttl_save,
161	.extra_opts	= ttl_opts,
162};
163
164
165void _init(void)
166{
167	register_match(&ttl_match);
168}
169