1/* Shared library add-on to iptables to add TTL matching support
2 * (C) 2000 by Harald Welte <laforge@gnumonks.org>
3 *
4 * This program is released under the terms of GNU GPL */
5#include <stdio.h>
6#include <xtables.h>
7#include <linux/netfilter_ipv4/ipt_ttl.h>
8
9enum {
10	O_TTL_EQ = 0,
11	O_TTL_LT,
12	O_TTL_GT,
13	F_TTL_EQ = 1 << O_TTL_EQ,
14	F_TTL_LT = 1 << O_TTL_LT,
15	F_TTL_GT = 1 << O_TTL_GT,
16	F_ANY    = F_TTL_EQ | F_TTL_LT | F_TTL_GT,
17};
18
19static void ttl_help(void)
20{
21	printf(
22"ttl match options:\n"
23"[!] --ttl-eq value	Match time to live value\n"
24"  --ttl-lt value	Match TTL < value\n"
25"  --ttl-gt value	Match TTL > value\n");
26}
27
28static void ttl_parse(struct xt_option_call *cb)
29{
30	struct ipt_ttl_info *info = cb->data;
31
32	xtables_option_parse(cb);
33	switch (cb->entry->id) {
34	case O_TTL_EQ:
35		info->mode = cb->invert ? IPT_TTL_NE : IPT_TTL_EQ;
36		break;
37	case O_TTL_LT:
38		info->mode = IPT_TTL_LT;
39		break;
40	case O_TTL_GT:
41		info->mode = IPT_TTL_GT;
42		break;
43	}
44}
45
46static void ttl_check(struct xt_fcheck_call *cb)
47{
48	if (!(cb->xflags & F_ANY))
49		xtables_error(PARAMETER_PROBLEM,
50			"TTL match: You must specify one of "
51			"`--ttl-eq', `--ttl-lt', `--ttl-gt");
52}
53
54static void ttl_print(const void *ip, const struct xt_entry_match *match,
55                      int numeric)
56{
57	const struct ipt_ttl_info *info =
58		(struct ipt_ttl_info *) match->data;
59
60	printf(" TTL match ");
61	switch (info->mode) {
62		case IPT_TTL_EQ:
63			printf("TTL ==");
64			break;
65		case IPT_TTL_NE:
66			printf("TTL !=");
67			break;
68		case IPT_TTL_LT:
69			printf("TTL <");
70			break;
71		case IPT_TTL_GT:
72			printf("TTL >");
73			break;
74	}
75	printf(" %u", info->ttl);
76}
77
78static void ttl_save(const void *ip, const struct xt_entry_match *match)
79{
80	const struct ipt_ttl_info *info =
81		(struct ipt_ttl_info *) match->data;
82
83	switch (info->mode) {
84		case IPT_TTL_EQ:
85			printf(" --ttl-eq");
86			break;
87		case IPT_TTL_NE:
88			printf(" ! --ttl-eq");
89			break;
90		case IPT_TTL_LT:
91			printf(" --ttl-lt");
92			break;
93		case IPT_TTL_GT:
94			printf(" --ttl-gt");
95			break;
96		default:
97			/* error */
98			break;
99	}
100	printf(" %u", info->ttl);
101}
102
103#define s struct ipt_ttl_info
104static const struct xt_option_entry ttl_opts[] = {
105	{.name = "ttl-lt", .id = O_TTL_LT, .excl = F_ANY, .type = XTTYPE_UINT8,
106	 .flags = XTOPT_PUT, XTOPT_POINTER(s, ttl)},
107	{.name = "ttl-gt", .id = O_TTL_GT, .excl = F_ANY, .type = XTTYPE_UINT8,
108	 .flags = XTOPT_PUT, XTOPT_POINTER(s, ttl)},
109	{.name = "ttl-eq", .id = O_TTL_EQ, .excl = F_ANY, .type = XTTYPE_UINT8,
110	 .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, ttl)},
111	{.name = "ttl", .id = O_TTL_EQ, .excl = F_ANY, .type = XTTYPE_UINT8,
112	 .flags = XTOPT_PUT, XTOPT_POINTER(s, ttl)},
113	XTOPT_TABLEEND,
114};
115#undef s
116
117static struct xtables_match ttl_mt_reg = {
118	.name		= "ttl",
119	.version	= XTABLES_VERSION,
120	.family		= NFPROTO_IPV4,
121	.size		= XT_ALIGN(sizeof(struct ipt_ttl_info)),
122	.userspacesize	= XT_ALIGN(sizeof(struct ipt_ttl_info)),
123	.help		= ttl_help,
124	.print		= ttl_print,
125	.save		= ttl_save,
126	.x6_parse	= ttl_parse,
127	.x6_fcheck	= ttl_check,
128	.x6_options	= ttl_opts,
129};
130
131
132void _init(void)
133{
134	xtables_register_match(&ttl_mt_reg);
135}
136