libipt_ttl.c revision e37d45ce390c2f5a7f1e64742b9100ecef0def54
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Shared library add-on to iptables to add TTL matching support
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (C) 2000 by Harald Welte <laforge@gnumonks.org>
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This program is released under the terms of GNU GPL */
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <xtables.h>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <linux/netfilter_ipv4/ipt_ttl.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum {
107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch	O_TTL_EQ = 0,
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	O_TTL_LT,
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	O_TTL_GT,
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	F_TTL_EQ = 1 << O_TTL_EQ,
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	F_TTL_LT = 1 << O_TTL_LT,
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	F_TTL_GT = 1 << O_TTL_GT,
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	F_ANY    = F_TTL_EQ | F_TTL_LT | F_TTL_GT,
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void ttl_help(void)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf(
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"ttl match options:\n"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"  --ttl-eq value	Match time to live value\n"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"  --ttl-lt value	Match TTL < value\n"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"  --ttl-gt value	Match TTL > value\n");
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static void ttl_parse(struct xt_option_call *cb)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct ipt_ttl_info *info = cb->data;
317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch	xtables_option_parse(cb);
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	switch (cb->entry->id) {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case O_TTL_EQ:
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		info->mode = cb->invert ? IPT_TTL_NE : IPT_TTL_EQ;
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		break;
37b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)	case O_TTL_LT:
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		info->mode = IPT_TTL_LT;
3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)		break;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case O_TTL_GT:
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		info->mode = IPT_TTL_GT;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void ttl_check(struct xt_fcheck_call *cb)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	if (!(cb->xflags & F_ANY))
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		xtables_error(PARAMETER_PROBLEM,
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)			"TTL match: You must specify one of "
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)			"`--ttl-eq', `--ttl-lt', `--ttl-gt");
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void ttl_print(const void *ip, const struct xt_entry_match *match,
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      int numeric)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	const struct ipt_ttl_info *info =
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(struct ipt_ttl_info *) match->data;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf(" TTL match ");
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	switch (info->mode) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case IPT_TTL_EQ:
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf("TTL ==");
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case IPT_TTL_NE:
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf("TTL !=");
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case IPT_TTL_LT:
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf("TTL <");
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			break;
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		case IPT_TTL_GT:
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)			printf("TTL >");
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	printf(" %u", info->ttl);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void ttl_save(const void *ip, const struct xt_entry_match *match)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const struct ipt_ttl_info *info =
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(struct ipt_ttl_info *) match->data;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	switch (info->mode) {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case IPT_TTL_EQ:
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			printf(" --ttl-eq");
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		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