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