blob: 7b1f7f831c88bbd570e47faff5650096f6b260b4 [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
5 * Contact: Jan Engelhardt <jengelh@computergmbh.de>
6 */
7#include <getopt.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
Jirí Moravec56156cd2008-10-22 08:57:38 +020011#include <netinet/in.h>
Jan Engelhardt36f2ead2008-01-20 13:25:08 +000012
13#include <xtables.h>
14#include <linux/netfilter/xt_DSCP.h>
15#include <linux/netfilter_ipv4/ipt_TOS.h>
16#include "tos_values.c"
17
18enum {
19 FLAG_TOS = 1 << 0,
20};
21
22static const struct option tos_tg_opts_v0[] = {
23 {.name = "set-tos", .has_arg = true, .val = '='},
Max Kellermann9ee386a2008-01-29 13:48:05 +000024 { .name = NULL }
Jan Engelhardt36f2ead2008-01-20 13:25:08 +000025};
26
27static const struct option tos_tg_opts[] = {
28 {.name = "set-tos", .has_arg = true, .val = '='},
29 {.name = "and-tos", .has_arg = true, .val = '&'},
30 {.name = "or-tos", .has_arg = true, .val = '|'},
31 {.name = "xor-tos", .has_arg = true, .val = '^'},
Max Kellermann9ee386a2008-01-29 13:48:05 +000032 { .name = NULL }
Jan Engelhardt36f2ead2008-01-20 13:25:08 +000033};
34
35static void tos_tg_help_v0(void)
36{
37 const struct tos_symbol_info *symbol;
38
39 printf(
40"TOS target options:\n"
41" --set-tos value Set Type of Service/Priority field to value\n"
42" --set-tos symbol Set TOS field (IPv4 only) by symbol\n"
43" Accepted symbolic names for value are:\n");
44
45 for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol)
46 printf(" (0x%02x) %2u %s\n",
47 symbol->value, symbol->value, symbol->name);
48
49 printf("\n");
50}
51
52static void tos_tg_help(void)
53{
54 const struct tos_symbol_info *symbol;
55
56 printf(
57"TOS target v%s options:\n"
58" --set-tos value[/mask] Set Type of Service/Priority field to value\n"
59" (Zero out bits in mask and XOR value into TOS)\n"
60" --set-tos symbol Set TOS field (IPv4 only) by symbol\n"
61" (this zeroes the 4-bit Precedence part!)\n"
62" Accepted symbolic names for value are:\n",
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020063XTABLES_VERSION);
Jan Engelhardt36f2ead2008-01-20 13:25:08 +000064
65 for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol)
66 printf(" (0x%02x) %2u %s\n",
67 symbol->value, symbol->value, symbol->name);
68
69 printf(
70"\n"
71" --and-tos bits Binary AND the TOS value with bits\n"
72" --or-tos bits Binary OR the TOS value with bits\n"
73" --xor-tos bits Binary XOR the TOS value with bits\n"
74);
75}
76
77static int tos_tg_parse_v0(int c, char **argv, int invert, unsigned int *flags,
78 const void *entry, struct xt_entry_target **target)
79{
80 struct ipt_tos_target_info *info = (void *)(*target)->data;
81 struct tos_value_mask tvm;
82
83 switch (c) {
84 case '=':
Jan Engelhardta41545c2009-01-27 21:27:19 +010085 xtables_param_act(XTF_ONLY_ONCE, "TOS", "--set-tos", *flags & FLAG_TOS);
86 xtables_param_act(XTF_NO_INVERT, "TOS", "--set-tos", invert);
Jan Engelhardt36f2ead2008-01-20 13:25:08 +000087 if (!tos_parse_symbolic(optarg, &tvm, 0xFF))
Jan Engelhardta41545c2009-01-27 21:27:19 +010088 xtables_param_act(XTF_BAD_VALUE, "TOS", "--set-tos", optarg);
Jan Engelhardt36f2ead2008-01-20 13:25:08 +000089 if (tvm.mask != 0xFF)
90 exit_error(PARAMETER_PROBLEM, "tos match: Your kernel "
91 "is too old to support anything besides "
92 "/0xFF as a mask.");
93 info->tos = tvm.value;
94 *flags |= FLAG_TOS;
95 return true;
96 }
97
98 return false;
99}
100
101static int tos_tg_parse(int c, char **argv, int invert, unsigned int *flags,
102 const void *entry, struct xt_entry_target **target)
103{
104 struct xt_tos_target_info *info = (void *)(*target)->data;
105 struct tos_value_mask tvm;
106 unsigned int bits;
107
108 switch (c) {
109 case '=': /* --set-tos */
Jan Engelhardta41545c2009-01-27 21:27:19 +0100110 xtables_param_act(XTF_ONLY_ONCE, "TOS", "--set-tos", *flags & FLAG_TOS);
111 xtables_param_act(XTF_NO_INVERT, "TOS", "--set-tos", invert);
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000112 if (!tos_parse_symbolic(optarg, &tvm, 0x3F))
Jan Engelhardta41545c2009-01-27 21:27:19 +0100113 xtables_param_act(XTF_BAD_VALUE, "TOS", "--set-tos", optarg);
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000114 info->tos_value = tvm.value;
115 info->tos_mask = tvm.mask;
116 break;
117
118 case '&': /* --and-tos */
Jan Engelhardta41545c2009-01-27 21:27:19 +0100119 xtables_param_act(XTF_ONLY_ONCE, "TOS", "--and-tos", *flags & FLAG_TOS);
120 xtables_param_act(XTF_NO_INVERT, "TOS", "--and-tos", invert);
Jan Engelhardt5f2922c2009-01-27 18:43:01 +0100121 if (!xtables_strtoui(optarg, NULL, &bits, 0, UINT8_MAX))
Jan Engelhardta41545c2009-01-27 21:27:19 +0100122 xtables_param_act(XTF_BAD_VALUE, "TOS", "--and-tos", optarg);
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000123 info->tos_value = 0;
124 info->tos_mask = ~bits;
125 break;
126
127 case '|': /* --or-tos */
Jan Engelhardta41545c2009-01-27 21:27:19 +0100128 xtables_param_act(XTF_ONLY_ONCE, "TOS", "--or-tos", *flags & FLAG_TOS);
129 xtables_param_act(XTF_NO_INVERT, "TOS", "--or-tos", invert);
Jan Engelhardt5f2922c2009-01-27 18:43:01 +0100130 if (!xtables_strtoui(optarg, NULL, &bits, 0, UINT8_MAX))
Jan Engelhardta41545c2009-01-27 21:27:19 +0100131 xtables_param_act(XTF_BAD_VALUE, "TOS", "--or-tos", optarg);
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000132 info->tos_value = bits;
133 info->tos_mask = bits;
134 break;
135
136 case '^': /* --xor-tos */
Jan Engelhardta41545c2009-01-27 21:27:19 +0100137 xtables_param_act(XTF_ONLY_ONCE, "TOS", "--xor-tos", *flags & FLAG_TOS);
138 xtables_param_act(XTF_NO_INVERT, "TOS", "--xor-tos", invert);
Jan Engelhardt5f2922c2009-01-27 18:43:01 +0100139 if (!xtables_strtoui(optarg, NULL, &bits, 0, UINT8_MAX))
Jan Engelhardta41545c2009-01-27 21:27:19 +0100140 xtables_param_act(XTF_BAD_VALUE, "TOS", "--xor-tos", optarg);
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000141 info->tos_value = bits;
142 info->tos_mask = 0;
143 break;
144
145 default:
146 return false;
147 }
148
149 *flags |= FLAG_TOS;
150 return true;
151}
152
153static void tos_tg_check(unsigned int flags)
154{
155 if (flags == 0)
156 exit_error(PARAMETER_PROBLEM,
157 "TOS: The --set-tos parameter is required");
158}
159
160static void tos_tg_print_v0(const void *ip,
161 const struct xt_entry_target *target, int numeric)
162{
163 const struct ipt_tos_target_info *info = (const void *)target->data;
164
165 printf("TOS set ");
166 if (numeric || !tos_try_print_symbolic("", info->tos, 0xFF))
167 printf("0x%02x ", info->tos);
168}
169
170static void tos_tg_print(const void *ip, const struct xt_entry_target *target,
171 int numeric)
172{
173 const struct xt_tos_target_info *info = (const void *)target->data;
174
175 if (numeric)
176 printf("TOS set 0x%02x/0x%02x ",
177 info->tos_value, info->tos_mask);
178 else if (tos_try_print_symbolic("TOS set ",
179 info->tos_value, info->tos_mask))
180 /* already printed by call */
181 return;
182 else if (info->tos_value == 0)
183 printf("TOS and 0x%02x ",
184 (unsigned int)(u_int8_t)~info->tos_mask);
185 else if (info->tos_value == info->tos_mask)
186 printf("TOS or 0x%02x ", info->tos_value);
187 else if (info->tos_mask == 0)
188 printf("TOS xor 0x%02x ", info->tos_value);
189 else
190 printf("TOS set 0x%02x/0x%02x ",
191 info->tos_value, info->tos_mask);
192}
193
194static void tos_tg_save_v0(const void *ip, const struct xt_entry_target *target)
195{
196 const struct ipt_tos_target_info *info = (const void *)target->data;
197
198 printf("--set-tos 0x%02x ", info->tos);
199}
200
201static void tos_tg_save(const void *ip, const struct xt_entry_target *target)
202{
203 const struct xt_tos_target_info *info = (const void *)target->data;
204
205 printf("--set-tos 0x%02x/0x%02x ", info->tos_value, info->tos_mask);
206}
207
208static struct xtables_target tos_tg_reg_v0 = {
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200209 .version = XTABLES_VERSION,
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000210 .name = "TOS",
211 .revision = 0,
Jan Engelhardt03d99482008-11-18 12:27:54 +0100212 .family = NFPROTO_IPV4,
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000213 .size = XT_ALIGN(sizeof(struct xt_tos_target_info)),
214 .userspacesize = XT_ALIGN(sizeof(struct xt_tos_target_info)),
215 .help = tos_tg_help_v0,
216 .parse = tos_tg_parse_v0,
217 .final_check = tos_tg_check,
218 .print = tos_tg_print_v0,
219 .save = tos_tg_save_v0,
220 .extra_opts = tos_tg_opts_v0,
221};
222
223static struct xtables_target tos_tg_reg = {
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200224 .version = XTABLES_VERSION,
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000225 .name = "TOS",
226 .revision = 1,
Jan Engelhardt03d99482008-11-18 12:27:54 +0100227 .family = NFPROTO_IPV4,
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000228 .size = XT_ALIGN(sizeof(struct xt_tos_target_info)),
229 .userspacesize = XT_ALIGN(sizeof(struct xt_tos_target_info)),
230 .help = tos_tg_help,
231 .parse = tos_tg_parse,
232 .final_check = tos_tg_check,
233 .print = tos_tg_print,
234 .save = tos_tg_save,
235 .extra_opts = tos_tg_opts,
236};
237
238static struct xtables_target tos_tg6_reg = {
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200239 .version = XTABLES_VERSION,
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000240 .name = "TOS",
Jan Engelhardt03d99482008-11-18 12:27:54 +0100241 .family = NFPROTO_IPV6,
Jan Engelhardt36f2ead2008-01-20 13:25:08 +0000242 .revision = 1,
243 .size = XT_ALIGN(sizeof(struct xt_tos_target_info)),
244 .userspacesize = XT_ALIGN(sizeof(struct xt_tos_target_info)),
245 .help = tos_tg_help,
246 .parse = tos_tg_parse,
247 .final_check = tos_tg_check,
248 .print = tos_tg_print,
249 .save = tos_tg_save,
250 .extra_opts = tos_tg_opts,
251};
252
253void _init(void)
254{
255 xtables_register_target(&tos_tg_reg_v0);
256 xtables_register_target(&tos_tg_reg);
257 xtables_register_target(&tos_tg6_reg);
258}