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