libxt_tos.c revision 32b8e61e4e5bd405d9ad07bf9468498dfbb19f9e
1/*
2 * Shared library add-on to iptables to add tos match support
3 *
4 * Copyright © CC Computer Consultants GmbH, 2007
5 * Contact: Jan Engelhardt <jengelh@computergmbh.de>
6 */
7#include <getopt.h>
8#include <netdb.h>
9#include <stdbool.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14#include <xtables.h>
15#include <linux/netfilter/xt_dscp.h>
16#include "tos_values.c"
17
18struct ipt_tos_info {
19	u_int8_t tos;
20	u_int8_t invert;
21};
22
23enum {
24	FLAG_TOS = 1 << 0,
25};
26
27static const struct option tos_mt_opts[] = {
28	{.name = "tos", .has_arg = true, .val = 't'},
29	XT_GETOPT_TABLEEND,
30};
31
32static void tos_mt_help(void)
33{
34	const struct tos_symbol_info *symbol;
35
36	printf(
37"tos match options:\n"
38"[!] --tos value[/mask]    Match Type of Service/Priority field value\n"
39"[!] --tos symbol          Match TOS field (IPv4 only) by symbol\n"
40"                          Accepted symbolic names for value are:\n");
41
42	for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol)
43		printf("                          (0x%02x) %2u %s\n",
44		       symbol->value, symbol->value, symbol->name);
45
46	printf("\n");
47}
48
49static int tos_mt_parse_v0(int c, char **argv, int invert, unsigned int *flags,
50                           const void *entry, struct xt_entry_match **match)
51{
52	struct ipt_tos_info *info = (void *)(*match)->data;
53	struct tos_value_mask tvm;
54
55	switch (c) {
56	case 't':
57		xtables_param_act(XTF_ONLY_ONCE, "tos", "--tos", *flags & FLAG_TOS);
58		if (!tos_parse_symbolic(optarg, &tvm, 0xFF))
59			xtables_param_act(XTF_BAD_VALUE, "tos", "--tos", optarg);
60		if (tvm.mask != 0xFF)
61			xtables_error(PARAMETER_PROBLEM, "tos: Your kernel is "
62			           "too old to support anything besides /0xFF "
63				   "as a mask.");
64		info->tos = tvm.value;
65		if (invert)
66			info->invert = true;
67		*flags |= FLAG_TOS;
68		return true;
69	}
70	return false;
71}
72
73static int tos_mt_parse(int c, char **argv, int invert, unsigned int *flags,
74                        const void *entry, struct xt_entry_match **match)
75{
76	struct xt_tos_match_info *info = (void *)(*match)->data;
77	struct tos_value_mask tvm = {.mask = 0xFF};
78
79	switch (c) {
80	case 't':
81		xtables_param_act(XTF_ONLY_ONCE, "tos", "--tos", *flags & FLAG_TOS);
82		if (!tos_parse_symbolic(optarg, &tvm, 0x3F))
83			xtables_param_act(XTF_BAD_VALUE, "tos", "--tos", optarg);
84		info->tos_value = tvm.value;
85		info->tos_mask  = tvm.mask;
86		if (invert)
87			info->invert = true;
88		*flags |= FLAG_TOS;
89		return true;
90	}
91	return false;
92}
93
94static void tos_mt_check(unsigned int flags)
95{
96	if (flags == 0)
97		xtables_error(PARAMETER_PROBLEM,
98		           "tos: --tos parameter required");
99}
100
101static void tos_mt_print_v0(const void *ip, const struct xt_entry_match *match,
102                            int numeric)
103{
104	const struct ipt_tos_info *info = (const void *)match->data;
105
106	printf("tos match ");
107	if (info->invert)
108		printf("!");
109	if (numeric || !tos_try_print_symbolic("", info->tos, 0x3F))
110		printf("0x%02x ", info->tos);
111}
112
113static void tos_mt_print(const void *ip, const struct xt_entry_match *match,
114                         int numeric)
115{
116	const struct xt_tos_match_info *info = (const void *)match->data;
117
118	printf("tos match ");
119	if (info->invert)
120		printf("!");
121	if (numeric ||
122	    !tos_try_print_symbolic("", info->tos_value, info->tos_mask))
123		printf("0x%02x/0x%02x ", info->tos_value, info->tos_mask);
124}
125
126static void tos_mt_save_v0(const void *ip, const struct xt_entry_match *match)
127{
128	const struct ipt_tos_info *info = (const void *)match->data;
129
130	if (info->invert)
131		printf("! ");
132	printf("--tos 0x%02x ", info->tos);
133}
134
135static void tos_mt_save(const void *ip, const struct xt_entry_match *match)
136{
137	const struct xt_tos_match_info *info = (const void *)match->data;
138
139	if (info->invert)
140		printf("! ");
141	printf("--tos 0x%02x/0x%02x ", info->tos_value, info->tos_mask);
142}
143
144static struct xtables_match tos_mt_reg[] = {
145	{
146		.version       = XTABLES_VERSION,
147		.name          = "tos",
148		.family        = NFPROTO_IPV4,
149		.revision      = 0,
150		.size          = XT_ALIGN(sizeof(struct ipt_tos_info)),
151		.userspacesize = XT_ALIGN(sizeof(struct ipt_tos_info)),
152		.help          = tos_mt_help,
153		.parse         = tos_mt_parse_v0,
154		.final_check   = tos_mt_check,
155		.print         = tos_mt_print_v0,
156		.save          = tos_mt_save_v0,
157		.extra_opts    = tos_mt_opts,
158	},
159	{
160		.version       = XTABLES_VERSION,
161		.name          = "tos",
162		.family        = NFPROTO_UNSPEC,
163		.revision      = 1,
164		.size          = XT_ALIGN(sizeof(struct xt_tos_match_info)),
165		.userspacesize = XT_ALIGN(sizeof(struct xt_tos_match_info)),
166		.help          = tos_mt_help,
167		.parse         = tos_mt_parse,
168		.final_check   = tos_mt_check,
169		.print         = tos_mt_print,
170		.save          = tos_mt_save,
171		.extra_opts    = tos_mt_opts,
172	},
173};
174
175void _init(void)
176{
177	xtables_register_matches(tos_mt_reg, ARRAY_SIZE(tos_mt_reg));
178}
179