libipt_ttl.c revision 6656e1378f432ab8690e7d22128793a1ddc5166b
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 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 parse(int c, char **argv, int invert, unsigned int *flags,
28		const struct ipt_entry *entry, unsigned int *nfcache,
29		struct ipt_entry_match **match)
30{
31	struct ipt_ttl_info *info = (struct ipt_ttl_info *) (*match)->data;
32	unsigned int value;
33
34	check_inverse(optarg, &invert, &optind, 0);
35
36	switch (c) {
37		case '2':
38			if (string_to_number(optarg, 0, 255, &value) == -1)
39				exit_error(PARAMETER_PROBLEM,
40				           "ttl: Expected value between 0 and 255");
41
42			if (invert)
43				info->mode = IPT_TTL_NE;
44			else
45				info->mode = IPT_TTL_EQ;
46
47			/* is 0 allowed? */
48			info->ttl = value;
49			break;
50		case '3':
51			if (string_to_number(optarg, 0, 255, &value) == -1)
52				exit_error(PARAMETER_PROBLEM,
53				           "ttl: Expected value between 0 and 255");
54
55			if (invert)
56				exit_error(PARAMETER_PROBLEM,
57						"ttl: unexpected `!'");
58
59			info->mode = IPT_TTL_LT;
60			info->ttl = value;
61			break;
62		case '4':
63			if (string_to_number(optarg, 0, 255, &value) == -1)
64				exit_error(PARAMETER_PROBLEM,
65				           "ttl: Expected value between 0 and 255");
66
67			if (invert)
68				exit_error(PARAMETER_PROBLEM,
69						"ttl: unexpected `!'");
70
71			info->mode = IPT_TTL_GT;
72			info->ttl = value;
73			break;
74		default:
75			return 0;
76
77	}
78
79	if (*flags)
80		exit_error(PARAMETER_PROBLEM,
81				"Can't specify TTL option twice");
82	*flags = 1;
83
84	return 1;
85}
86
87static void final_check(unsigned int flags)
88{
89	if (!flags)
90		exit_error(PARAMETER_PROBLEM,
91			"TTL match: You must specify one of "
92			"`--ttl-eq', `--ttl-lt', `--ttl-gt");
93}
94
95static void print(const struct ipt_ip *ip,
96		const struct ipt_entry_match *match,
97		int numeric)
98{
99	const struct ipt_ttl_info *info =
100		(struct ipt_ttl_info *) match->data;
101
102	printf("TTL match ");
103	switch (info->mode) {
104		case IPT_TTL_EQ:
105			printf("TTL == ");
106			break;
107		case IPT_TTL_NE:
108			printf("TTL != ");
109			break;
110		case IPT_TTL_LT:
111			printf("TTL < ");
112			break;
113		case IPT_TTL_GT:
114			printf("TTL > ");
115			break;
116	}
117	printf("%u ", info->ttl);
118}
119
120static void save(const struct ipt_ip *ip,
121		const struct ipt_entry_match *match)
122{
123	const struct ipt_ttl_info *info =
124		(struct ipt_ttl_info *) match->data;
125
126	switch (info->mode) {
127		case IPT_TTL_EQ:
128			printf("--ttl-eq ");
129			break;
130		case IPT_TTL_NE:
131			printf("! --ttl-eq ");
132			break;
133		case IPT_TTL_LT:
134			printf("--ttl-lt ");
135			break;
136		case IPT_TTL_GT:
137			printf("--ttl-gt ");
138			break;
139		default:
140			/* error */
141			break;
142	}
143	printf("%u ", info->ttl);
144}
145
146static struct option opts[] = {
147	{ "ttl", 1, 0, '2' },
148	{ "ttl-eq", 1, 0, '2'},
149	{ "ttl-lt", 1, 0, '3'},
150	{ "ttl-gt", 1, 0, '4'},
151	{ 0 }
152};
153
154static struct iptables_match ttl = {
155	.next		= NULL,
156	.name		= "ttl",
157	.version	= IPTABLES_VERSION,
158	.size		= IPT_ALIGN(sizeof(struct ipt_ttl_info)),
159	.userspacesize	= IPT_ALIGN(sizeof(struct ipt_ttl_info)),
160	.help		= &help,
161	.parse		= &parse,
162	.final_check	= &final_check,
163	.print		= &print,
164	.save		= &save,
165	.extra_opts	= opts
166};
167
168
169void _init(void)
170{
171	register_match(&ttl);
172}
173