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