blob: cef587650278e70aea7ab629190c9718e982a0b6 [file] [log] [blame]
Jan Engelhardt36f2ead2008-01-20 13:25:08 +00001/*
2 * Shared library add-on to iptables to add TOS target support
3 *
4 * Copyright © CC Computer Consultants GmbH, 2007
Jan Engelhardt61cc52b2011-04-29 01:25:14 +02005 * Contact: Jan Engelhardt <jengelh@medozas.de>
Jan Engelhardt36f2ead2008-01-20 13:25:08 +00006 */
7#include <getopt.h>
Jan Engelhardt32b8e612010-07-23 21:16:14 +02008#include <stdbool.h>
Jan Engelhardt36f2ead2008-01-20 13:25:08 +00009#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
Jirí Moravec56156cd2008-10-22 08:57:38 +020012#include <netinet/in.h>
Jan Engelhardt36f2ead2008-01-20 13:25:08 +000013
14#include <xtables.h>
15#include <linux/netfilter/xt_DSCP.h>
Jan Engelhardt36f2ead2008-01-20 13:25:08 +000016#include "tos_values.c"
17
Jan Engelhardt350661a2010-01-31 22:42:52 +010018struct ipt_tos_target_info {
Jan Engelhardt7ac40522011-01-07 12:34:04 +010019 uint8_t tos;
Jan Engelhardt350661a2010-01-31 22:42:52 +010020};
21
Jan Engelhardt36f2ead2008-01-20 13:25:08 +000022enum {
Jan Engelhardt61cc52b2011-04-29 01:25:14 +020023 O_SET_TOS = 0,
24 O_AND_TOS,
25 O_OR_TOS,
26 O_XOR_TOS,
27 F_SET_TOS = 1 << O_SET_TOS,
28 F_AND_TOS = 1 << O_AND_TOS,
29 F_OR_TOS = 1 << O_OR_TOS,
30 F_XOR_TOS = 1 << O_XOR_TOS,
31 F_ANY = F_SET_TOS | F_AND_TOS | F_OR_TOS | F_XOR_TOS,
Jan Engelhardt36f2ead2008-01-20 13:25:08 +000032};
33
Jan Engelhardt61cc52b2011-04-29 01:25:14 +020034static const struct xt_option_entry tos_tg_opts_v0[] = {
35 {.name = "set-tos", .id = O_SET_TOS, .type = XTTYPE_TOSMASK,
36 .excl = F_ANY, .max = 0xFF},
37 XTOPT_TABLEEND,
Jan Engelhardt36f2ead2008-01-20 13:25:08 +000038};
39
Jan Engelhardt61cc52b2011-04-29 01:25:14 +020040static const struct xt_option_entry tos_tg_opts[] = {
41 {.name = "set-tos", .id = O_SET_TOS, .type = XTTYPE_TOSMASK,
42 .excl = F_ANY, .max = 0x3F},
43 {.name = "and-tos", .id = O_AND_TOS, .type = XTTYPE_UINT8,
44 .excl = F_ANY},
45 {.name = "or-tos", .id = O_OR_TOS, .type = XTTYPE_UINT8,
46 .excl = F_ANY},
47 {.name = "xor-tos", .id = O_XOR_TOS, .type = XTTYPE_UINT8,
48 .excl = F_ANY},
49 XTOPT_TABLEEND,
Jan Engelhardt36f2ead2008-01-20 13:25:08 +000050};
51
52static void tos_tg_help_v0(void)
53{
54 const struct tos_symbol_info *symbol;
55
56 printf(
57"TOS target options:\n"
58" --set-tos value Set Type of Service/Priority field to value\n"
59" --set-tos symbol Set TOS field (IPv4 only) by symbol\n"
60" Accepted symbolic names for value are:\n");
61
62 for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol)
63 printf(" (0x%02x) %2u %s\n",
64 symbol->value, symbol->value, symbol->name);
65
66 printf("\n");
67}
68
69static void tos_tg_help(void)
70{
71 const struct tos_symbol_info *symbol;
72
73 printf(
74"TOS target v%s options:\n"
75" --set-tos value[/mask] Set Type of Service/Priority field to value\n"
76" (Zero out bits in mask and XOR value into TOS)\n"
77" --set-tos symbol Set TOS field (IPv4 only) by symbol\n"
78" (this zeroes the 4-bit Precedence part!)\n"
79" Accepted symbolic names for value are:\n",
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020080XTABLES_VERSION);
Jan Engelhardt36f2ead2008-01-20 13:25:08 +000081
82 for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol)
83 printf(" (0x%02x) %2u %s\n",
84 symbol->value, symbol->value, symbol->name);
85
86 printf(
87"\n"
88" --and-tos bits Binary AND the TOS value with bits\n"
89" --or-tos bits Binary OR the TOS value with bits\n"
90" --xor-tos bits Binary XOR the TOS value with bits\n"
91);
92}
93
Jan Engelhardt61cc52b2011-04-29 01:25:14 +020094static void tos_tg_parse_v0(struct xt_option_call *cb)
Jan Engelhardt36f2ead2008-01-20 13:25:08 +000095{
Jan Engelhardt61cc52b2011-04-29 01:25:14 +020096 struct ipt_tos_target_info *info = cb->data;
Jan Engelhardt36f2ead2008-01-20 13:25:08 +000097
Jan Engelhardt61cc52b2011-04-29 01:25:14 +020098 xtables_option_parse(cb);
99 if (cb->val.tos_mask != 0xFF)
100 xtables_error(PARAMETER_PROBLEM, "tos match: Your kernel "
101 "is too old to support anything besides "
102 "/0xFF as a mask.");
103 info->tos = cb->val.tos_value;
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000104}
105
Jan Engelhardt61cc52b2011-04-29 01:25:14 +0200106static void tos_tg_parse(struct xt_option_call *cb)
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000107{
Jan Engelhardt61cc52b2011-04-29 01:25:14 +0200108 struct xt_tos_target_info *info = cb->data;
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000109
Jan Engelhardt61cc52b2011-04-29 01:25:14 +0200110 xtables_option_parse(cb);
111 switch (cb->entry->id) {
112 case O_SET_TOS:
113 info->tos_value = cb->val.tos_value;
114 info->tos_mask = cb->val.tos_mask;
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000115 break;
Jan Engelhardt61cc52b2011-04-29 01:25:14 +0200116 case O_AND_TOS:
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000117 info->tos_value = 0;
Jan Engelhardt61cc52b2011-04-29 01:25:14 +0200118 info->tos_mask = ~cb->val.u8;
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000119 break;
Jan Engelhardt61cc52b2011-04-29 01:25:14 +0200120 case O_OR_TOS:
121 info->tos_value = cb->val.u8;
122 info->tos_mask = cb->val.u8;
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000123 break;
Jan Engelhardt61cc52b2011-04-29 01:25:14 +0200124 case O_XOR_TOS:
125 info->tos_value = cb->val.u8;
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000126 info->tos_mask = 0;
127 break;
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000128 }
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000129}
130
Jan Engelhardt61cc52b2011-04-29 01:25:14 +0200131static void tos_tg_check(struct xt_fcheck_call *cb)
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000132{
Jan Engelhardt61cc52b2011-04-29 01:25:14 +0200133 if (!(cb->xflags & F_ANY))
Jan Engelhardt1829ed42009-02-21 03:29:44 +0100134 xtables_error(PARAMETER_PROBLEM,
Jan Engelhardt61cc52b2011-04-29 01:25:14 +0200135 "TOS: An action is required");
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000136}
137
138static void tos_tg_print_v0(const void *ip,
139 const struct xt_entry_target *target, int numeric)
140{
141 const struct ipt_tos_target_info *info = (const void *)target->data;
142
Jan Engelhardt73866352010-12-18 02:04:59 +0100143 printf(" TOS set ");
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000144 if (numeric || !tos_try_print_symbolic("", info->tos, 0xFF))
Jan Engelhardt73866352010-12-18 02:04:59 +0100145 printf("0x%02x", info->tos);
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000146}
147
148static void tos_tg_print(const void *ip, const struct xt_entry_target *target,
149 int numeric)
150{
151 const struct xt_tos_target_info *info = (const void *)target->data;
152
153 if (numeric)
Jan Engelhardt73866352010-12-18 02:04:59 +0100154 printf(" TOS set 0x%02x/0x%02x",
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000155 info->tos_value, info->tos_mask);
Jan Engelhardt73866352010-12-18 02:04:59 +0100156 else if (tos_try_print_symbolic(" TOS set",
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000157 info->tos_value, info->tos_mask))
158 /* already printed by call */
159 return;
160 else if (info->tos_value == 0)
Jan Engelhardt73866352010-12-18 02:04:59 +0100161 printf(" TOS and 0x%02x",
Jan Engelhardt7ac40522011-01-07 12:34:04 +0100162 (unsigned int)(uint8_t)~info->tos_mask);
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000163 else if (info->tos_value == info->tos_mask)
Jan Engelhardt73866352010-12-18 02:04:59 +0100164 printf(" TOS or 0x%02x", info->tos_value);
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000165 else if (info->tos_mask == 0)
Jan Engelhardt73866352010-12-18 02:04:59 +0100166 printf(" TOS xor 0x%02x", info->tos_value);
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000167 else
Jan Engelhardt73866352010-12-18 02:04:59 +0100168 printf(" TOS set 0x%02x/0x%02x",
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000169 info->tos_value, info->tos_mask);
170}
171
172static void tos_tg_save_v0(const void *ip, const struct xt_entry_target *target)
173{
174 const struct ipt_tos_target_info *info = (const void *)target->data;
175
Jan Engelhardt73866352010-12-18 02:04:59 +0100176 printf(" --set-tos 0x%02x", info->tos);
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000177}
178
179static void tos_tg_save(const void *ip, const struct xt_entry_target *target)
180{
181 const struct xt_tos_target_info *info = (const void *)target->data;
182
Jan Engelhardt73866352010-12-18 02:04:59 +0100183 printf(" --set-tos 0x%02x/0x%02x", info->tos_value, info->tos_mask);
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000184}
185
Jan Engelhardtf2a77522009-06-25 20:12:12 +0200186static struct xtables_target tos_tg_reg[] = {
187 {
188 .version = XTABLES_VERSION,
189 .name = "TOS",
190 .revision = 0,
191 .family = NFPROTO_IPV4,
192 .size = XT_ALIGN(sizeof(struct xt_tos_target_info)),
193 .userspacesize = XT_ALIGN(sizeof(struct xt_tos_target_info)),
194 .help = tos_tg_help_v0,
Jan Engelhardtf2a77522009-06-25 20:12:12 +0200195 .print = tos_tg_print_v0,
196 .save = tos_tg_save_v0,
Jan Engelhardt61cc52b2011-04-29 01:25:14 +0200197 .x6_parse = tos_tg_parse_v0,
198 .x6_fcheck = tos_tg_check,
199 .x6_options = tos_tg_opts_v0,
Jan Engelhardtf2a77522009-06-25 20:12:12 +0200200 },
201 {
202 .version = XTABLES_VERSION,
203 .name = "TOS",
204 .revision = 1,
205 .family = NFPROTO_UNSPEC,
206 .size = XT_ALIGN(sizeof(struct xt_tos_target_info)),
207 .userspacesize = XT_ALIGN(sizeof(struct xt_tos_target_info)),
208 .help = tos_tg_help,
Jan Engelhardtf2a77522009-06-25 20:12:12 +0200209 .print = tos_tg_print,
210 .save = tos_tg_save,
Jan Engelhardt61cc52b2011-04-29 01:25:14 +0200211 .x6_parse = tos_tg_parse,
212 .x6_fcheck = tos_tg_check,
213 .x6_options = tos_tg_opts,
Jan Engelhardtf2a77522009-06-25 20:12:12 +0200214 },
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000215};
216
217void _init(void)
218{
Jan Engelhardtf2a77522009-06-25 20:12:12 +0200219 xtables_register_targets(tos_tg_reg, ARRAY_SIZE(tos_tg_reg));
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000220}