libip6t_hl.c revision 03d99486d8283552705b58dc55b6085dffc38792
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
960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak#include <stdio.h>
1060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak#include <stdlib.h>
1160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak#include <string.h>
1260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak#include <getopt.h>
1360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak#include <ip6tables.h>
1460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
1560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak#include <linux/netfilter_ipv6/ip6_tables.h>
1660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak#include <linux/netfilter_ipv6/ip6t_hl.h>
1760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
18997045f536026c0d643bf884da5ff5de2605197fJan Engelhardtstatic void hl_help(void)
1960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak{
2060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak	printf(
218b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"hl match options:\n"
22967279231a9ecfa99f26694a954afc535c63db1dJan Engelhardt"[!] --hl-eq value	Match hop limit value\n"
2360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak"  --hl-lt value	Match HL < value\n"
248b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"  --hl-gt value	Match HL > value\n");
2560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak}
2660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
27997045f536026c0d643bf884da5ff5de2605197fJan Engelhardtstatic int hl_parse(int c, char **argv, int invert, unsigned int *flags,
28997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt                    const void *entry, struct xt_entry_match **match)
2960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak{
3060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak	struct ip6t_hl_info *info = (struct ip6t_hl_info *) (*match)->data;
3160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak	u_int8_t value;
3260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
3360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak	check_inverse(optarg, &invert, &optind, 0);
3460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak	value = atoi(argv[optind-1]);
3560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
3660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak	if (*flags)
3760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak		exit_error(PARAMETER_PROBLEM,
3860358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak				"Can't specify HL option twice");
3960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
4060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak	if (!optarg)
4160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak		exit_error(PARAMETER_PROBLEM,
4260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak				"hl: You must specify a value");
4360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak	switch (c) {
4460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak		case '2':
4560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak			if (invert)
4660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak				info->mode = IP6T_HL_NE;
4760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak			else
4860358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak				info->mode = IP6T_HL_EQ;
4960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
5060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak			/* is 0 allowed? */
5160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak			info->hop_limit = value;
5260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak			*flags = 1;
5360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
5460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak			break;
5560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak		case '3':
5660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak			if (invert)
5760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak				exit_error(PARAMETER_PROBLEM,
5860358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak						"hl: unexpected `!'");
5960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
6060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak			info->mode = IP6T_HL_LT;
6160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak			info->hop_limit = value;
6260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak			*flags = 1;
6360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
6460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak			break;
6560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak		case '4':
6660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak			if (invert)
6760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak				exit_error(PARAMETER_PROBLEM,
6860358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak						"hl: unexpected `!'");
6960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
7060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak			info->mode = IP6T_HL_GT;
7160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak			info->hop_limit = value;
7260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak			*flags = 1;
7360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
7460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak			break;
7560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak		default:
7660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak			return 0;
7760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak	}
7860358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
7960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak	return 1;
8060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak}
8160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
82997045f536026c0d643bf884da5ff5de2605197fJan Engelhardtstatic void hl_check(unsigned int flags)
8360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak{
8460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak	if (!flags)
8560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak		exit_error(PARAMETER_PROBLEM,
8660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak			"HL match: You must specify one of "
8746525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette			"`--hl-eq', `--hl-lt', `--hl-gt'");
8860358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak}
8960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
90997045f536026c0d643bf884da5ff5de2605197fJan Engelhardtstatic void hl_print(const void *ip, const struct xt_entry_match *match,
91997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt                     int numeric)
9260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak{
9346525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette	static const char *op[] = {
9446525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette		[IP6T_HL_EQ] = "==",
9546525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette		[IP6T_HL_NE] = "!=",
9646525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette		[IP6T_HL_LT] = "<",
9746525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette		[IP6T_HL_GT] = ">" };
9846525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette
9960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak	const struct ip6t_hl_info *info =
10060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak		(struct ip6t_hl_info *) match->data;
10160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
10246525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette	printf("HL match HL %s %u ", op[info->mode], info->hop_limit);
10360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak}
10460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
105997045f536026c0d643bf884da5ff5de2605197fJan Engelhardtstatic void hl_save(const void *ip, const struct xt_entry_match *match)
10660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak{
10746525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette	static const char *op[] = {
10846525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette		[IP6T_HL_EQ] = "eq",
10946525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette		[IP6T_HL_NE] = "eq !",
11046525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette		[IP6T_HL_LT] = "lt",
11146525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette		[IP6T_HL_GT] = "gt" };
11246525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette
11360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak	const struct ip6t_hl_info *info =
11460358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak		(struct ip6t_hl_info *) match->data;
11560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
11646525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette	printf("--hl-%s %u ", op[info->mode], info->hop_limit);
11760358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak}
11860358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
119997045f536026c0d643bf884da5ff5de2605197fJan Engelhardtstatic const struct option hl_opts[] = {
120500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy	{ .name = "hl",    .has_arg = 1, .val = '2' },
121500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy	{ .name = "hl-eq", .has_arg = 1, .val = '2' },
122500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy	{ .name = "hl-lt", .has_arg = 1, .val = '3' },
123500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy	{ .name = "hl-gt", .has_arg = 1, .val = '4' },
1249ee386a1b6d7704b259460152c959ab0e79e02aaMax Kellermann	{ .name = NULL }
12560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak};
12660358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
1278b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardtstatic struct xtables_match hl_mt6_reg = {
12846525cd3880d2b1aad0b049122a67c9e626ec6d9Stephane Ouellette	.name          = "hl",
1298b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.version       = XTABLES_VERSION,
13003d99486d8283552705b58dc55b6085dffc38792Jan Engelhardt	.family        = NFPROTO_IPV6,
1318b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.size          = XT_ALIGN(sizeof(struct ip6t_hl_info)),
1328b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.userspacesize = XT_ALIGN(sizeof(struct ip6t_hl_info)),
133997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt	.help          = hl_help,
134997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt	.parse         = hl_parse,
135997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt	.final_check   = hl_check,
136997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt	.print         = hl_print,
137997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt	.save          = hl_save,
138997045f536026c0d643bf884da5ff5de2605197fJan Engelhardt	.extra_opts    = hl_opts,
13960358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak};
14060358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
14160358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak
14260358d73482620aeafc34f38df36e462875fd244Maciej Soltysiakvoid _init(void)
14360358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak{
1448b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	xtables_register_match(&hl_mt6_reg);
14560358d73482620aeafc34f38df36e462875fd244Maciej Soltysiak}
146