160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak/*
260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak * IPv6 Hop Limit matching module
360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak * Maciej Soltysiak <solt@dns.toxicfilms.tv>
460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak * Based on HW's ttl match
560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak * This program is released under the terms of GNU GPL
646525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette * Cleanups by Stephane Ouellette <ouellettes@videotron.ca>
760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak */
860358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak#include <stdio.h>
95d9678ad3eabc34ac40dfe055d7f6a8e44445a5aJan Engelhardt#include <xtables.h>
1060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak#include <linux/netfilter_ipv6/ip6t_hl.h>
1160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
12dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardtenum {
13dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	O_HL_EQ = 0,
14dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	O_HL_LT,
15dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	O_HL_GT,
16dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	F_HL_EQ = 1 << O_HL_EQ,
17dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	F_HL_LT = 1 << O_HL_LT,
18dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	F_HL_GT = 1 << O_HL_GT,
19dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	F_ANY  = F_HL_EQ | F_HL_LT | F_HL_GT,
20dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt};
21dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt
22997045f536026c0d643bf884da5ff5de2605197fJan Engelhardtstatic void hl_help(void)
2360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak{
2460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak	printf(
258b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"hl match options:\n"
26967279231a9ecfa99f26694a954afc535c63db1dJan Engelhardt"[!] --hl-eq value	Match hop limit value\n"
2760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak"  --hl-lt value	Match HL < value\n"
288b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"  --hl-gt value	Match HL > value\n");
2960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak}
3060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
31dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardtstatic void hl_parse(struct xt_option_call *cb)
3260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak{
33dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	struct ip6t_hl_info *info = cb->data;
34dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt
35dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	xtables_option_parse(cb);
36dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	switch (cb->entry->id) {
37dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	case O_HL_EQ:
38dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt		info->mode = cb->invert ? IP6T_HL_NE : IP6T_HL_EQ;
39dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt		break;
40dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	case O_HL_LT:
41dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt		info->mode = IP6T_HL_LT;
42dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt		break;
43dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	case O_HL_GT:
44dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt		info->mode = IP6T_HL_GT;
45dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt		break;
4660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak	}
4760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak}
4860358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
49dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardtstatic void hl_check(struct xt_fcheck_call *cb)
5060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak{
51dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	if (!(cb->xflags & F_ANY))
521829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM,
5360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak			"HL match: You must specify one of "
5446525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette			"`--hl-eq', `--hl-lt', `--hl-gt'");
5560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak}
5660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
57997045f536026c0d643bf884da5ff5de2605197fJan Engelhardtstatic void hl_print(const void *ip, const struct xt_entry_match *match,
58997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt                     int numeric)
5960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak{
6069f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardt	static const char *const op[] = {
6146525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette		[IP6T_HL_EQ] = "==",
6246525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette		[IP6T_HL_NE] = "!=",
6346525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette		[IP6T_HL_LT] = "<",
6446525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette		[IP6T_HL_GT] = ">" };
6546525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette
6660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak	const struct ip6t_hl_info *info =
6760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak		(struct ip6t_hl_info *) match->data;
6860358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
6973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" HL match HL %s %u", op[info->mode], info->hop_limit);
7060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak}
7160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
72997045f536026c0d643bf884da5ff5de2605197fJan Engelhardtstatic void hl_save(const void *ip, const struct xt_entry_match *match)
7360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak{
74cea9f71f5618250a38acb21c31fbbf93a752f7d4Jan Engelhardt	static const char *const op[] = {
75cea9f71f5618250a38acb21c31fbbf93a752f7d4Jan Engelhardt		[IP6T_HL_EQ] = "--hl-eq",
76cea9f71f5618250a38acb21c31fbbf93a752f7d4Jan Engelhardt		[IP6T_HL_NE] = "! --hl-eq",
77cea9f71f5618250a38acb21c31fbbf93a752f7d4Jan Engelhardt		[IP6T_HL_LT] = "--hl-lt",
78cea9f71f5618250a38acb21c31fbbf93a752f7d4Jan Engelhardt		[IP6T_HL_GT] = "--hl-gt" };
7946525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette
8060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak	const struct ip6t_hl_info *info =
8160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak		(struct ip6t_hl_info *) match->data;
8260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
8373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" %s %u", op[info->mode], info->hop_limit);
8460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak}
8560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
867a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayusostatic const char *const op[] = {
877a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayuso	[IP6T_HL_EQ] = "",
887a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayuso	[IP6T_HL_NE] = "!= ",
897a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayuso	[IP6T_HL_LT] = "lt ",
907a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayuso	[IP6T_HL_GT] = "gt "
917a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayuso};
920198008d1de13037c2e809c598d51771b166cc46Shivani Bhardwaj
937a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayusostatic int hl_xlate(struct xt_xlate *xl,
947a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayuso		    const struct xt_xlate_mt_params *params)
957a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayuso{
960198008d1de13037c2e809c598d51771b166cc46Shivani Bhardwaj	const struct ip6t_hl_info *info =
977a0992da44cfb6cab0ccd1beadcf326df8773552Pablo Neira Ayuso		(struct ip6t_hl_info *) params->match->data;
980198008d1de13037c2e809c598d51771b166cc46Shivani Bhardwaj
99f035be35c749d5c5cbb7ffdbcd1c548b91bd3033Pablo M. Bermudo Garay	xt_xlate_add(xl, "ip6 hoplimit %s%u", op[info->mode], info->hop_limit);
1000198008d1de13037c2e809c598d51771b166cc46Shivani Bhardwaj
1010198008d1de13037c2e809c598d51771b166cc46Shivani Bhardwaj	return 1;
1020198008d1de13037c2e809c598d51771b166cc46Shivani Bhardwaj}
1030198008d1de13037c2e809c598d51771b166cc46Shivani Bhardwaj
104dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt#define s struct ip6t_hl_info
105dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardtstatic const struct xt_option_entry hl_opts[] = {
106dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	{.name = "hl-lt", .id = O_HL_LT, .excl = F_ANY, .type = XTTYPE_UINT8,
107dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	 .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit)},
108dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	{.name = "hl-gt", .id = O_HL_GT, .excl = F_ANY, .type = XTTYPE_UINT8,
109dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	 .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit)},
110dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	{.name = "hl-eq", .id = O_HL_EQ, .excl = F_ANY, .type = XTTYPE_UINT8,
111dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	 .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hop_limit)},
112dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	{.name = "hl", .id = O_HL_EQ, .excl = F_ANY, .type = XTTYPE_UINT8,
113dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	 .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit)},
114dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	XTOPT_TABLEEND,
11560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak};
116dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt#undef s
11760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
1188b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardtstatic struct xtables_match hl_mt6_reg = {
11946525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette	.name          = "hl",
1208b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.version       = XTABLES_VERSION,
12103d99486d8283552705b58dc55b6085dffc38792Jan Engelhardt	.family        = NFPROTO_IPV6,
1228b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.size          = XT_ALIGN(sizeof(struct ip6t_hl_info)),
1238b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.userspacesize = XT_ALIGN(sizeof(struct ip6t_hl_info)),
124997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt	.help          = hl_help,
125997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt	.print         = hl_print,
126997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt	.save          = hl_save,
127dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	.x6_parse      = hl_parse,
128dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	.x6_fcheck     = hl_check,
129dba0839a103fe0384b41a8f08a3b3a5f9eba732bJan Engelhardt	.x6_options    = hl_opts,
1300198008d1de13037c2e809c598d51771b166cc46Shivani Bhardwaj	.xlate	       = hl_xlate,
13160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak};
13260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
13360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
13460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiakvoid _init(void)
13560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak{
1368b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	xtables_register_match(&hl_mt6_reg);
13760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak}
138