10720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt/*
20720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt * Shared library add-on to iptables to add tos match support
30720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt *
40720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt * Copyright © CC Computer Consultants GmbH, 2007
50720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt * Contact: Jan Engelhardt <jengelh@computergmbh.de>
60720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt */
70720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt#include <getopt.h>
80720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt#include <netdb.h>
90720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt#include <stdbool.h>
100720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt#include <stdio.h>
110720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt#include <stdlib.h>
120720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt#include <string.h>
130720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt
140720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt#include <xtables.h>
150720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt#include <linux/netfilter/xt_dscp.h>
160720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt#include "tos_values.c"
170720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt
18350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardtstruct ipt_tos_info {
197ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardt	uint8_t tos;
207ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardt	uint8_t invert;
21350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt};
22350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt
230720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardtenum {
24d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt	O_TOS = 1 << 0,
250720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt};
260720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt
27d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardtstatic const struct xt_option_entry tos_mt_opts_v0[] = {
28d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt	{.name = "tos", .id = O_TOS, .type = XTTYPE_TOSMASK,
2906312dab6c530a214a4e7bad1b2329381430bddcJan Engelhardt	 .flags = XTOPT_INVERT | XTOPT_MAND, .max = 0xFF},
30d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt	XTOPT_TABLEEND,
31d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt};
32d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt
33d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardtstatic const struct xt_option_entry tos_mt_opts[] = {
34d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt	{.name = "tos", .id = O_TOS, .type = XTTYPE_TOSMASK,
3506312dab6c530a214a4e7bad1b2329381430bddcJan Engelhardt	 .flags = XTOPT_INVERT | XTOPT_MAND, .max = 0x3F},
36d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt	XTOPT_TABLEEND,
370720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt};
380720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt
390720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardtstatic void tos_mt_help(void)
400720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt{
410720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt	const struct tos_symbol_info *symbol;
420720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt
430720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt	printf(
440720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt"tos match options:\n"
450720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt"[!] --tos value[/mask]    Match Type of Service/Priority field value\n"
460720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt"[!] --tos symbol          Match TOS field (IPv4 only) by symbol\n"
470720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt"                          Accepted symbolic names for value are:\n");
480720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt
490720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt	for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol)
500720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt		printf("                          (0x%02x) %2u %s\n",
510720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt		       symbol->value, symbol->value, symbol->name);
520720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt
530720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt	printf("\n");
540720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt}
550720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt
56d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardtstatic void tos_mt_parse_v0(struct xt_option_call *cb)
570720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt{
58d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt	struct ipt_tos_info *info = cb->data;
59d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt
60d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt	xtables_option_parse(cb);
61d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt	if (cb->val.tos_mask != 0xFF)
62d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt		xtables_error(PARAMETER_PROBLEM, "tos: Your kernel is "
63d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt		           "too old to support anything besides /0xFF "
64d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt			   "as a mask.");
65d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt	info->tos = cb->val.tos_value;
66d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt	if (cb->invert)
67d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt		info->invert = true;
680720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt}
690720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt
70d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardtstatic void tos_mt_parse(struct xt_option_call *cb)
710720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt{
72d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt	struct xt_tos_match_info *info = cb->data;
730720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt
74d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt	xtables_option_parse(cb);
75d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt	info->tos_value = cb->val.tos_value;
76d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt	info->tos_mask  = cb->val.tos_mask;
77d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt	if (cb->invert)
78d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt		info->invert = true;
790720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt}
800720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt
810720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardtstatic void tos_mt_print_v0(const void *ip, const struct xt_entry_match *match,
820720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt                            int numeric)
830720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt{
840720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt	const struct ipt_tos_info *info = (const void *)match->data;
850720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt
8673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" tos match ");
870720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt	if (info->invert)
880720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt		printf("!");
890720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt	if (numeric || !tos_try_print_symbolic("", info->tos, 0x3F))
9073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf("0x%02x", info->tos);
910720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt}
920720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt
930720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardtstatic void tos_mt_print(const void *ip, const struct xt_entry_match *match,
940720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt                         int numeric)
950720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt{
960720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt	const struct xt_tos_match_info *info = (const void *)match->data;
970720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt
9873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" tos match");
990720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt	if (info->invert)
1000720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt		printf("!");
1010720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt	if (numeric ||
1020720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt	    !tos_try_print_symbolic("", info->tos_value, info->tos_mask))
10373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf("0x%02x/0x%02x", info->tos_value, info->tos_mask);
1040720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt}
1050720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt
1060720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardtstatic void tos_mt_save_v0(const void *ip, const struct xt_entry_match *match)
1070720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt{
1080720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt	const struct ipt_tos_info *info = (const void *)match->data;
1090720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt
1100720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt	if (info->invert)
11173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" !");
11273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" --tos 0x%02x", info->tos);
1130720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt}
1140720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt
1150720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardtstatic void tos_mt_save(const void *ip, const struct xt_entry_match *match)
1160720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt{
1170720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt	const struct xt_tos_match_info *info = (const void *)match->data;
1180720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt
1190720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt	if (info->invert)
12073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" !");
12173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" --tos 0x%02x/0x%02x", info->tos_value, info->tos_mask);
1220720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt}
1230720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt
124f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardtstatic struct xtables_match tos_mt_reg[] = {
125f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	{
126f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.version       = XTABLES_VERSION,
127f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.name          = "tos",
128f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.family        = NFPROTO_IPV4,
129f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.revision      = 0,
130f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.size          = XT_ALIGN(sizeof(struct ipt_tos_info)),
131f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.userspacesize = XT_ALIGN(sizeof(struct ipt_tos_info)),
132f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.help          = tos_mt_help,
133f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.print         = tos_mt_print_v0,
134f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.save          = tos_mt_save_v0,
135d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt		.x6_parse      = tos_mt_parse_v0,
136d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt		.x6_options    = tos_mt_opts_v0,
137f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	},
138f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	{
139f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.version       = XTABLES_VERSION,
140f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.name          = "tos",
141f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.family        = NFPROTO_UNSPEC,
142f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.revision      = 1,
143f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.size          = XT_ALIGN(sizeof(struct xt_tos_match_info)),
144f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.userspacesize = XT_ALIGN(sizeof(struct xt_tos_match_info)),
145f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.help          = tos_mt_help,
146f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.print         = tos_mt_print,
147f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.save          = tos_mt_save,
148d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt		.x6_parse      = tos_mt_parse,
149d8f591993eb610b41f3170a94a879edd24ad348aJan Engelhardt		.x6_options    = tos_mt_opts,
150f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	},
1510720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt};
1520720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt
1530720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardtvoid _init(void)
1540720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt{
155f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	xtables_register_matches(tos_mt_reg, ARRAY_SIZE(tos_mt_reg));
1560720c1226381f5c71748673c43c12499f1f254c7Jan Engelhardt}
157