1/*
2 * IPv6 Hop Limit Target module
3 * Maciej Soltysiak <solt@dns.toxicfilms.tv>
4 * Based on HW's ttl target
5 * This program is distributed under the terms of GNU GPL
6 */
7#include <stdio.h>
8#include <xtables.h>
9#include <linux/netfilter_ipv6/ip6t_HL.h>
10
11enum {
12	O_HL_SET = 0,
13	O_HL_INC,
14	O_HL_DEC,
15	F_HL_SET = 1 << O_HL_SET,
16	F_HL_INC = 1 << O_HL_INC,
17	F_HL_DEC = 1 << O_HL_DEC,
18	F_ANY    = F_HL_SET | F_HL_INC | F_HL_DEC,
19};
20
21#define s struct ip6t_HL_info
22static const struct xt_option_entry HL_opts[] = {
23	{.name = "hl-set", .type = XTTYPE_UINT8, .id = O_HL_SET,
24	 .excl = F_ANY, .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit)},
25	{.name = "hl-dec", .type = XTTYPE_UINT8, .id = O_HL_DEC,
26	 .excl = F_ANY, .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit),
27	 .min = 1},
28	{.name = "hl-inc", .type = XTTYPE_UINT8, .id = O_HL_INC,
29	 .excl = F_ANY, .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit),
30	 .min = 1},
31	XTOPT_TABLEEND,
32};
33#undef s
34
35static void HL_help(void)
36{
37	printf(
38"HL target options\n"
39"  --hl-set value		Set HL to <value 0-255>\n"
40"  --hl-dec value		Decrement HL by <value 1-255>\n"
41"  --hl-inc value		Increment HL by <value 1-255>\n");
42}
43
44static void HL_parse(struct xt_option_call *cb)
45{
46	struct ip6t_HL_info *info = cb->data;
47
48	xtables_option_parse(cb);
49	switch (cb->entry->id) {
50	case O_HL_SET:
51		info->mode = IP6T_HL_SET;
52		break;
53	case O_HL_INC:
54		info->mode = IP6T_HL_INC;
55		break;
56	case O_HL_DEC:
57		info->mode = IP6T_HL_DEC;
58		break;
59	}
60}
61
62static void HL_check(struct xt_fcheck_call *cb)
63{
64	if (!(cb->xflags & F_ANY))
65		xtables_error(PARAMETER_PROBLEM,
66				"HL: You must specify an action");
67}
68
69static void HL_save(const void *ip, const struct xt_entry_target *target)
70{
71	const struct ip6t_HL_info *info =
72		(struct ip6t_HL_info *) target->data;
73
74	switch (info->mode) {
75		case IP6T_HL_SET:
76			printf(" --hl-set");
77			break;
78		case IP6T_HL_DEC:
79			printf(" --hl-dec");
80			break;
81
82		case IP6T_HL_INC:
83			printf(" --hl-inc");
84			break;
85	}
86	printf(" %u", info->hop_limit);
87}
88
89static void HL_print(const void *ip, const struct xt_entry_target *target,
90                     int numeric)
91{
92	const struct ip6t_HL_info *info =
93		(struct ip6t_HL_info *) target->data;
94
95	printf(" HL ");
96	switch (info->mode) {
97		case IP6T_HL_SET:
98			printf("set to");
99			break;
100		case IP6T_HL_DEC:
101			printf("decrement by");
102			break;
103		case IP6T_HL_INC:
104			printf("increment by");
105			break;
106	}
107	printf(" %u", info->hop_limit);
108}
109
110static struct xtables_target hl_tg6_reg = {
111	.name 		= "HL",
112	.version	= XTABLES_VERSION,
113	.family		= NFPROTO_IPV6,
114	.size		= XT_ALIGN(sizeof(struct ip6t_HL_info)),
115	.userspacesize	= XT_ALIGN(sizeof(struct ip6t_HL_info)),
116	.help		= HL_help,
117	.print		= HL_print,
118	.save		= HL_save,
119	.x6_parse	= HL_parse,
120	.x6_fcheck	= HL_check,
121	.x6_options	= HL_opts,
122};
123
124void _init(void)
125{
126	xtables_register_target(&hl_tg6_reg);
127}
128