libxt_TOS.c revision 350661a6eb089f3e54e67e022db9e16ea280499f
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 "tos_values.c" 16 17struct ipt_tos_target_info { 18 u_int8_t tos; 19}; 20 21enum { 22 FLAG_TOS = 1 << 0, 23}; 24 25static const struct option tos_tg_opts_v0[] = { 26 {.name = "set-tos", .has_arg = true, .val = '='}, 27 { .name = NULL } 28}; 29 30static const struct option tos_tg_opts[] = { 31 {.name = "set-tos", .has_arg = true, .val = '='}, 32 {.name = "and-tos", .has_arg = true, .val = '&'}, 33 {.name = "or-tos", .has_arg = true, .val = '|'}, 34 {.name = "xor-tos", .has_arg = true, .val = '^'}, 35 { .name = NULL } 36}; 37 38static void tos_tg_help_v0(void) 39{ 40 const struct tos_symbol_info *symbol; 41 42 printf( 43"TOS target options:\n" 44" --set-tos value Set Type of Service/Priority field to value\n" 45" --set-tos symbol Set TOS field (IPv4 only) by symbol\n" 46" Accepted symbolic names for value are:\n"); 47 48 for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol) 49 printf(" (0x%02x) %2u %s\n", 50 symbol->value, symbol->value, symbol->name); 51 52 printf("\n"); 53} 54 55static void tos_tg_help(void) 56{ 57 const struct tos_symbol_info *symbol; 58 59 printf( 60"TOS target v%s options:\n" 61" --set-tos value[/mask] Set Type of Service/Priority field to value\n" 62" (Zero out bits in mask and XOR value into TOS)\n" 63" --set-tos symbol Set TOS field (IPv4 only) by symbol\n" 64" (this zeroes the 4-bit Precedence part!)\n" 65" Accepted symbolic names for value are:\n", 66XTABLES_VERSION); 67 68 for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol) 69 printf(" (0x%02x) %2u %s\n", 70 symbol->value, symbol->value, symbol->name); 71 72 printf( 73"\n" 74" --and-tos bits Binary AND the TOS value with bits\n" 75" --or-tos bits Binary OR the TOS value with bits\n" 76" --xor-tos bits Binary XOR the TOS value with bits\n" 77); 78} 79 80static int tos_tg_parse_v0(int c, char **argv, int invert, unsigned int *flags, 81 const void *entry, struct xt_entry_target **target) 82{ 83 struct ipt_tos_target_info *info = (void *)(*target)->data; 84 struct tos_value_mask tvm; 85 86 switch (c) { 87 case '=': 88 xtables_param_act(XTF_ONLY_ONCE, "TOS", "--set-tos", *flags & FLAG_TOS); 89 xtables_param_act(XTF_NO_INVERT, "TOS", "--set-tos", invert); 90 if (!tos_parse_symbolic(optarg, &tvm, 0xFF)) 91 xtables_param_act(XTF_BAD_VALUE, "TOS", "--set-tos", optarg); 92 if (tvm.mask != 0xFF) 93 xtables_error(PARAMETER_PROBLEM, "tos match: Your kernel " 94 "is too old to support anything besides " 95 "/0xFF as a mask."); 96 info->tos = tvm.value; 97 *flags |= FLAG_TOS; 98 return true; 99 } 100 101 return false; 102} 103 104static int tos_tg_parse(int c, char **argv, int invert, unsigned int *flags, 105 const void *entry, struct xt_entry_target **target) 106{ 107 struct xt_tos_target_info *info = (void *)(*target)->data; 108 struct tos_value_mask tvm; 109 unsigned int bits; 110 111 switch (c) { 112 case '=': /* --set-tos */ 113 xtables_param_act(XTF_ONLY_ONCE, "TOS", "--set-tos", *flags & FLAG_TOS); 114 xtables_param_act(XTF_NO_INVERT, "TOS", "--set-tos", invert); 115 if (!tos_parse_symbolic(optarg, &tvm, 0x3F)) 116 xtables_param_act(XTF_BAD_VALUE, "TOS", "--set-tos", optarg); 117 info->tos_value = tvm.value; 118 info->tos_mask = tvm.mask; 119 break; 120 121 case '&': /* --and-tos */ 122 xtables_param_act(XTF_ONLY_ONCE, "TOS", "--and-tos", *flags & FLAG_TOS); 123 xtables_param_act(XTF_NO_INVERT, "TOS", "--and-tos", invert); 124 if (!xtables_strtoui(optarg, NULL, &bits, 0, UINT8_MAX)) 125 xtables_param_act(XTF_BAD_VALUE, "TOS", "--and-tos", optarg); 126 info->tos_value = 0; 127 info->tos_mask = ~bits; 128 break; 129 130 case '|': /* --or-tos */ 131 xtables_param_act(XTF_ONLY_ONCE, "TOS", "--or-tos", *flags & FLAG_TOS); 132 xtables_param_act(XTF_NO_INVERT, "TOS", "--or-tos", invert); 133 if (!xtables_strtoui(optarg, NULL, &bits, 0, UINT8_MAX)) 134 xtables_param_act(XTF_BAD_VALUE, "TOS", "--or-tos", optarg); 135 info->tos_value = bits; 136 info->tos_mask = bits; 137 break; 138 139 case '^': /* --xor-tos */ 140 xtables_param_act(XTF_ONLY_ONCE, "TOS", "--xor-tos", *flags & FLAG_TOS); 141 xtables_param_act(XTF_NO_INVERT, "TOS", "--xor-tos", invert); 142 if (!xtables_strtoui(optarg, NULL, &bits, 0, UINT8_MAX)) 143 xtables_param_act(XTF_BAD_VALUE, "TOS", "--xor-tos", optarg); 144 info->tos_value = bits; 145 info->tos_mask = 0; 146 break; 147 148 default: 149 return false; 150 } 151 152 *flags |= FLAG_TOS; 153 return true; 154} 155 156static void tos_tg_check(unsigned int flags) 157{ 158 if (flags == 0) 159 xtables_error(PARAMETER_PROBLEM, 160 "TOS: The --set-tos parameter is required"); 161} 162 163static void tos_tg_print_v0(const void *ip, 164 const struct xt_entry_target *target, int numeric) 165{ 166 const struct ipt_tos_target_info *info = (const void *)target->data; 167 168 printf("TOS set "); 169 if (numeric || !tos_try_print_symbolic("", info->tos, 0xFF)) 170 printf("0x%02x ", info->tos); 171} 172 173static void tos_tg_print(const void *ip, const struct xt_entry_target *target, 174 int numeric) 175{ 176 const struct xt_tos_target_info *info = (const void *)target->data; 177 178 if (numeric) 179 printf("TOS set 0x%02x/0x%02x ", 180 info->tos_value, info->tos_mask); 181 else if (tos_try_print_symbolic("TOS set ", 182 info->tos_value, info->tos_mask)) 183 /* already printed by call */ 184 return; 185 else if (info->tos_value == 0) 186 printf("TOS and 0x%02x ", 187 (unsigned int)(u_int8_t)~info->tos_mask); 188 else if (info->tos_value == info->tos_mask) 189 printf("TOS or 0x%02x ", info->tos_value); 190 else if (info->tos_mask == 0) 191 printf("TOS xor 0x%02x ", info->tos_value); 192 else 193 printf("TOS set 0x%02x/0x%02x ", 194 info->tos_value, info->tos_mask); 195} 196 197static void tos_tg_save_v0(const void *ip, const struct xt_entry_target *target) 198{ 199 const struct ipt_tos_target_info *info = (const void *)target->data; 200 201 printf("--set-tos 0x%02x ", info->tos); 202} 203 204static void tos_tg_save(const void *ip, const struct xt_entry_target *target) 205{ 206 const struct xt_tos_target_info *info = (const void *)target->data; 207 208 printf("--set-tos 0x%02x/0x%02x ", info->tos_value, info->tos_mask); 209} 210 211static struct xtables_target tos_tg_reg[] = { 212 { 213 .version = XTABLES_VERSION, 214 .name = "TOS", 215 .revision = 0, 216 .family = NFPROTO_IPV4, 217 .size = XT_ALIGN(sizeof(struct xt_tos_target_info)), 218 .userspacesize = XT_ALIGN(sizeof(struct xt_tos_target_info)), 219 .help = tos_tg_help_v0, 220 .parse = tos_tg_parse_v0, 221 .final_check = tos_tg_check, 222 .print = tos_tg_print_v0, 223 .save = tos_tg_save_v0, 224 .extra_opts = tos_tg_opts_v0, 225 }, 226 { 227 .version = XTABLES_VERSION, 228 .name = "TOS", 229 .revision = 1, 230 .family = NFPROTO_UNSPEC, 231 .size = XT_ALIGN(sizeof(struct xt_tos_target_info)), 232 .userspacesize = XT_ALIGN(sizeof(struct xt_tos_target_info)), 233 .help = tos_tg_help, 234 .parse = tos_tg_parse, 235 .final_check = tos_tg_check, 236 .print = tos_tg_print, 237 .save = tos_tg_save, 238 .extra_opts = tos_tg_opts, 239 }, 240}; 241 242void _init(void) 243{ 244 xtables_register_targets(tos_tg_reg, ARRAY_SIZE(tos_tg_reg)); 245} 246