libip6t_HL.c revision 9ee386a1b6d7704b259460152c959ab0e79e02aa
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
8#include <stdio.h>
9#include <string.h>
10#include <stdlib.h>
11#include <getopt.h>
12#include <ip6tables.h>
13
14#include <linux/netfilter_ipv6/ip6_tables.h>
15#include <linux/netfilter_ipv6/ip6t_HL.h>
16
17#define IP6T_HL_USED	1
18
19static void HL_help(void)
20{
21	printf(
22"HL target v%s options\n"
23"  --hl-set value		Set HL to <value 0-255>\n"
24"  --hl-dec value		Decrement HL by <value 1-255>\n"
25"  --hl-inc value		Increment HL by <value 1-255>\n"
26, IPTABLES_VERSION);
27}
28
29static int HL_parse(int c, char **argv, int invert, unsigned int *flags,
30                    const void *entry, struct xt_entry_target **target)
31{
32	struct ip6t_HL_info *info = (struct ip6t_HL_info *) (*target)->data;
33	unsigned int value;
34
35	if (*flags & IP6T_HL_USED) {
36		exit_error(PARAMETER_PROBLEM,
37				"Can't specify HL option twice");
38	}
39
40	if (!optarg)
41		exit_error(PARAMETER_PROBLEM,
42				"HL: You must specify a value");
43
44	if (check_inverse(optarg, &invert, NULL, 0))
45		exit_error(PARAMETER_PROBLEM,
46				"HL: unexpected `!'");
47
48	if (string_to_number(optarg, 0, 255, &value) == -1)
49		exit_error(PARAMETER_PROBLEM,
50		           "HL: Expected value between 0 and 255");
51
52	switch (c) {
53
54		case '1':
55			info->mode = IP6T_HL_SET;
56			break;
57
58		case '2':
59			if (value == 0) {
60				exit_error(PARAMETER_PROBLEM,
61					"HL: decreasing by 0?");
62			}
63
64			info->mode = IP6T_HL_DEC;
65			break;
66
67		case '3':
68			if (value == 0) {
69				exit_error(PARAMETER_PROBLEM,
70					"HL: increasing by 0?");
71			}
72
73			info->mode = IP6T_HL_INC;
74			break;
75
76		default:
77			return 0;
78
79	}
80
81	info->hop_limit = value;
82	*flags |= IP6T_HL_USED;
83
84	return 1;
85}
86
87static void HL_check(unsigned int flags)
88{
89	if (!(flags & IP6T_HL_USED))
90		exit_error(PARAMETER_PROBLEM,
91				"HL: You must specify an action");
92}
93
94static void HL_save(const void *ip, const struct xt_entry_target *target)
95{
96	const struct ip6t_HL_info *info =
97		(struct ip6t_HL_info *) target->data;
98
99	switch (info->mode) {
100		case IP6T_HL_SET:
101			printf("--hl-set ");
102			break;
103		case IP6T_HL_DEC:
104			printf("--hl-dec ");
105			break;
106
107		case IP6T_HL_INC:
108			printf("--hl-inc ");
109			break;
110	}
111	printf("%u ", info->hop_limit);
112}
113
114static void HL_print(const void *ip, const struct xt_entry_target *target,
115                     int numeric)
116{
117	const struct ip6t_HL_info *info =
118		(struct ip6t_HL_info *) target->data;
119
120	printf("HL ");
121	switch (info->mode) {
122		case IP6T_HL_SET:
123			printf("set to ");
124			break;
125		case IP6T_HL_DEC:
126			printf("decrement by ");
127			break;
128		case IP6T_HL_INC:
129			printf("increment by ");
130			break;
131	}
132	printf("%u ", info->hop_limit);
133}
134
135static const struct option HL_opts[] = {
136	{ "hl-set", 1, NULL, '1' },
137	{ "hl-dec", 1, NULL, '2' },
138	{ "hl-inc", 1, NULL, '3' },
139	{ .name = NULL }
140};
141
142static struct ip6tables_target hl_target6 = {
143	.name 		= "HL",
144	.version	= IPTABLES_VERSION,
145	.size		= IP6T_ALIGN(sizeof(struct ip6t_HL_info)),
146	.userspacesize	= IP6T_ALIGN(sizeof(struct ip6t_HL_info)),
147	.help		= HL_help,
148	.parse		= HL_parse,
149	.final_check	= HL_check,
150	.print		= HL_print,
151	.save		= HL_save,
152	.extra_opts	= HL_opts,
153};
154
155void _init(void)
156{
157	register_target6(&hl_target6);
158}
159