libxt_TOS.c revision 1829ed482efbc8b390cc760d012b3a4450494e1a
1/* 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> 11#include <netinet/in.h> 12 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 = '='}, 24 { .name = NULL } 25}; 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 = '^'}, 32 { .name = NULL } 33}; 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", 63XTABLES_VERSION); 64 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 '=': 85 xtables_param_act(XTF_ONLY_ONCE, "TOS", "--set-tos", *flags & FLAG_TOS); 86 xtables_param_act(XTF_NO_INVERT, "TOS", "--set-tos", invert); 87 if (!tos_parse_symbolic(optarg, &tvm, 0xFF)) 88 xtables_param_act(XTF_BAD_VALUE, "TOS", "--set-tos", optarg); 89 if (tvm.mask != 0xFF) 90 xtables_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 */ 110 xtables_param_act(XTF_ONLY_ONCE, "TOS", "--set-tos", *flags & FLAG_TOS); 111 xtables_param_act(XTF_NO_INVERT, "TOS", "--set-tos", invert); 112 if (!tos_parse_symbolic(optarg, &tvm, 0x3F)) 113 xtables_param_act(XTF_BAD_VALUE, "TOS", "--set-tos", optarg); 114 info->tos_value = tvm.value; 115 info->tos_mask = tvm.mask; 116 break; 117 118 case '&': /* --and-tos */ 119 xtables_param_act(XTF_ONLY_ONCE, "TOS", "--and-tos", *flags & FLAG_TOS); 120 xtables_param_act(XTF_NO_INVERT, "TOS", "--and-tos", invert); 121 if (!xtables_strtoui(optarg, NULL, &bits, 0, UINT8_MAX)) 122 xtables_param_act(XTF_BAD_VALUE, "TOS", "--and-tos", optarg); 123 info->tos_value = 0; 124 info->tos_mask = ~bits; 125 break; 126 127 case '|': /* --or-tos */ 128 xtables_param_act(XTF_ONLY_ONCE, "TOS", "--or-tos", *flags & FLAG_TOS); 129 xtables_param_act(XTF_NO_INVERT, "TOS", "--or-tos", invert); 130 if (!xtables_strtoui(optarg, NULL, &bits, 0, UINT8_MAX)) 131 xtables_param_act(XTF_BAD_VALUE, "TOS", "--or-tos", optarg); 132 info->tos_value = bits; 133 info->tos_mask = bits; 134 break; 135 136 case '^': /* --xor-tos */ 137 xtables_param_act(XTF_ONLY_ONCE, "TOS", "--xor-tos", *flags & FLAG_TOS); 138 xtables_param_act(XTF_NO_INVERT, "TOS", "--xor-tos", invert); 139 if (!xtables_strtoui(optarg, NULL, &bits, 0, UINT8_MAX)) 140 xtables_param_act(XTF_BAD_VALUE, "TOS", "--xor-tos", optarg); 141 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 xtables_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 = { 209 .version = XTABLES_VERSION, 210 .name = "TOS", 211 .revision = 0, 212 .family = NFPROTO_IPV4, 213 .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 = { 224 .version = XTABLES_VERSION, 225 .name = "TOS", 226 .revision = 1, 227 .family = NFPROTO_IPV4, 228 .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 = { 239 .version = XTABLES_VERSION, 240 .name = "TOS", 241 .family = NFPROTO_IPV6, 242 .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} 259