Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Shared library add-on to iptables to add TOS target support |
| 3 | * |
| 4 | * Copyright © CC Computer Consultants GmbH, 2007 |
Jan Engelhardt | 61cc52b | 2011-04-29 01:25:14 +0200 | [diff] [blame] | 5 | * Contact: Jan Engelhardt <jengelh@medozas.de> |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 6 | */ |
| 7 | #include <getopt.h> |
Jan Engelhardt | 32b8e61 | 2010-07-23 21:16:14 +0200 | [diff] [blame] | 8 | #include <stdbool.h> |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 9 | #include <stdio.h> |
| 10 | #include <stdlib.h> |
| 11 | #include <string.h> |
Jirí Moravec | 56156cd | 2008-10-22 08:57:38 +0200 | [diff] [blame] | 12 | #include <netinet/in.h> |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 13 | |
| 14 | #include <xtables.h> |
| 15 | #include <linux/netfilter/xt_DSCP.h> |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 16 | #include "tos_values.c" |
| 17 | |
Jan Engelhardt | 350661a | 2010-01-31 22:42:52 +0100 | [diff] [blame] | 18 | struct ipt_tos_target_info { |
Jan Engelhardt | 7ac4052 | 2011-01-07 12:34:04 +0100 | [diff] [blame] | 19 | uint8_t tos; |
Jan Engelhardt | 350661a | 2010-01-31 22:42:52 +0100 | [diff] [blame] | 20 | }; |
| 21 | |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 22 | enum { |
Jan Engelhardt | 61cc52b | 2011-04-29 01:25:14 +0200 | [diff] [blame] | 23 | 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 Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 32 | }; |
| 33 | |
Jan Engelhardt | 61cc52b | 2011-04-29 01:25:14 +0200 | [diff] [blame] | 34 | static 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 Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 38 | }; |
| 39 | |
Jan Engelhardt | 61cc52b | 2011-04-29 01:25:14 +0200 | [diff] [blame] | 40 | static 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 Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 50 | }; |
| 51 | |
| 52 | static 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 | |
| 69 | static 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 Engelhardt | 8b7c64d | 2008-04-15 11:48:25 +0200 | [diff] [blame] | 80 | XTABLES_VERSION); |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 81 | |
| 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 Engelhardt | 61cc52b | 2011-04-29 01:25:14 +0200 | [diff] [blame] | 94 | static void tos_tg_parse_v0(struct xt_option_call *cb) |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 95 | { |
Jan Engelhardt | 61cc52b | 2011-04-29 01:25:14 +0200 | [diff] [blame] | 96 | struct ipt_tos_target_info *info = cb->data; |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 97 | |
Jan Engelhardt | 61cc52b | 2011-04-29 01:25:14 +0200 | [diff] [blame] | 98 | 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 Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 104 | } |
| 105 | |
Jan Engelhardt | 61cc52b | 2011-04-29 01:25:14 +0200 | [diff] [blame] | 106 | static void tos_tg_parse(struct xt_option_call *cb) |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 107 | { |
Jan Engelhardt | 61cc52b | 2011-04-29 01:25:14 +0200 | [diff] [blame] | 108 | struct xt_tos_target_info *info = cb->data; |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 109 | |
Jan Engelhardt | 61cc52b | 2011-04-29 01:25:14 +0200 | [diff] [blame] | 110 | 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 Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 115 | break; |
Jan Engelhardt | 61cc52b | 2011-04-29 01:25:14 +0200 | [diff] [blame] | 116 | case O_AND_TOS: |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 117 | info->tos_value = 0; |
Jan Engelhardt | 61cc52b | 2011-04-29 01:25:14 +0200 | [diff] [blame] | 118 | info->tos_mask = ~cb->val.u8; |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 119 | break; |
Jan Engelhardt | 61cc52b | 2011-04-29 01:25:14 +0200 | [diff] [blame] | 120 | case O_OR_TOS: |
| 121 | info->tos_value = cb->val.u8; |
| 122 | info->tos_mask = cb->val.u8; |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 123 | break; |
Jan Engelhardt | 61cc52b | 2011-04-29 01:25:14 +0200 | [diff] [blame] | 124 | case O_XOR_TOS: |
| 125 | info->tos_value = cb->val.u8; |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 126 | info->tos_mask = 0; |
| 127 | break; |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 128 | } |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 129 | } |
| 130 | |
Jan Engelhardt | 61cc52b | 2011-04-29 01:25:14 +0200 | [diff] [blame] | 131 | static void tos_tg_check(struct xt_fcheck_call *cb) |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 132 | { |
Jan Engelhardt | 61cc52b | 2011-04-29 01:25:14 +0200 | [diff] [blame] | 133 | if (!(cb->xflags & F_ANY)) |
Jan Engelhardt | 1829ed4 | 2009-02-21 03:29:44 +0100 | [diff] [blame] | 134 | xtables_error(PARAMETER_PROBLEM, |
Jan Engelhardt | 61cc52b | 2011-04-29 01:25:14 +0200 | [diff] [blame] | 135 | "TOS: An action is required"); |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 136 | } |
| 137 | |
| 138 | static 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 Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 143 | printf(" TOS set "); |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 144 | if (numeric || !tos_try_print_symbolic("", info->tos, 0xFF)) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 145 | printf("0x%02x", info->tos); |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 146 | } |
| 147 | |
| 148 | static 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 Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 154 | printf(" TOS set 0x%02x/0x%02x", |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 155 | info->tos_value, info->tos_mask); |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 156 | else if (tos_try_print_symbolic(" TOS set", |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 157 | info->tos_value, info->tos_mask)) |
| 158 | /* already printed by call */ |
| 159 | return; |
| 160 | else if (info->tos_value == 0) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 161 | printf(" TOS and 0x%02x", |
Jan Engelhardt | 7ac4052 | 2011-01-07 12:34:04 +0100 | [diff] [blame] | 162 | (unsigned int)(uint8_t)~info->tos_mask); |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 163 | else if (info->tos_value == info->tos_mask) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 164 | printf(" TOS or 0x%02x", info->tos_value); |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 165 | else if (info->tos_mask == 0) |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 166 | printf(" TOS xor 0x%02x", info->tos_value); |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 167 | else |
Jan Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 168 | printf(" TOS set 0x%02x/0x%02x", |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 169 | info->tos_value, info->tos_mask); |
| 170 | } |
| 171 | |
| 172 | static 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 Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 176 | printf(" --set-tos 0x%02x", info->tos); |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 177 | } |
| 178 | |
| 179 | static 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 Engelhardt | 7386635 | 2010-12-18 02:04:59 +0100 | [diff] [blame] | 183 | printf(" --set-tos 0x%02x/0x%02x", info->tos_value, info->tos_mask); |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 184 | } |
| 185 | |
Jan Engelhardt | f2a7752 | 2009-06-25 20:12:12 +0200 | [diff] [blame] | 186 | static 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 Engelhardt | f2a7752 | 2009-06-25 20:12:12 +0200 | [diff] [blame] | 195 | .print = tos_tg_print_v0, |
| 196 | .save = tos_tg_save_v0, |
Jan Engelhardt | 61cc52b | 2011-04-29 01:25:14 +0200 | [diff] [blame] | 197 | .x6_parse = tos_tg_parse_v0, |
| 198 | .x6_fcheck = tos_tg_check, |
| 199 | .x6_options = tos_tg_opts_v0, |
Jan Engelhardt | f2a7752 | 2009-06-25 20:12:12 +0200 | [diff] [blame] | 200 | }, |
| 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 Engelhardt | f2a7752 | 2009-06-25 20:12:12 +0200 | [diff] [blame] | 209 | .print = tos_tg_print, |
| 210 | .save = tos_tg_save, |
Jan Engelhardt | 61cc52b | 2011-04-29 01:25:14 +0200 | [diff] [blame] | 211 | .x6_parse = tos_tg_parse, |
| 212 | .x6_fcheck = tos_tg_check, |
| 213 | .x6_options = tos_tg_opts, |
Jan Engelhardt | f2a7752 | 2009-06-25 20:12:12 +0200 | [diff] [blame] | 214 | }, |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 215 | }; |
| 216 | |
| 217 | void _init(void) |
| 218 | { |
Jan Engelhardt | f2a7752 | 2009-06-25 20:12:12 +0200 | [diff] [blame] | 219 | xtables_register_targets(tos_tg_reg, ARRAY_SIZE(tos_tg_reg)); |
Jan Engelhardt | 36f2ead | 2008-01-20 13:25:08 +0000 | [diff] [blame] | 220 | } |