libxt_tos.c revision 32b8e61e4e5bd405d9ad07bf9468498dfbb19f9e
1/* 2 * Shared library add-on to iptables to add tos match support 3 * 4 * Copyright © CC Computer Consultants GmbH, 2007 5 * Contact: Jan Engelhardt <jengelh@computergmbh.de> 6 */ 7#include <getopt.h> 8#include <netdb.h> 9#include <stdbool.h> 10#include <stdio.h> 11#include <stdlib.h> 12#include <string.h> 13 14#include <xtables.h> 15#include <linux/netfilter/xt_dscp.h> 16#include "tos_values.c" 17 18struct ipt_tos_info { 19 u_int8_t tos; 20 u_int8_t invert; 21}; 22 23enum { 24 FLAG_TOS = 1 << 0, 25}; 26 27static const struct option tos_mt_opts[] = { 28 {.name = "tos", .has_arg = true, .val = 't'}, 29 XT_GETOPT_TABLEEND, 30}; 31 32static void tos_mt_help(void) 33{ 34 const struct tos_symbol_info *symbol; 35 36 printf( 37"tos match options:\n" 38"[!] --tos value[/mask] Match Type of Service/Priority field value\n" 39"[!] --tos symbol Match TOS field (IPv4 only) by symbol\n" 40" Accepted symbolic names for value are:\n"); 41 42 for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol) 43 printf(" (0x%02x) %2u %s\n", 44 symbol->value, symbol->value, symbol->name); 45 46 printf("\n"); 47} 48 49static int tos_mt_parse_v0(int c, char **argv, int invert, unsigned int *flags, 50 const void *entry, struct xt_entry_match **match) 51{ 52 struct ipt_tos_info *info = (void *)(*match)->data; 53 struct tos_value_mask tvm; 54 55 switch (c) { 56 case 't': 57 xtables_param_act(XTF_ONLY_ONCE, "tos", "--tos", *flags & FLAG_TOS); 58 if (!tos_parse_symbolic(optarg, &tvm, 0xFF)) 59 xtables_param_act(XTF_BAD_VALUE, "tos", "--tos", optarg); 60 if (tvm.mask != 0xFF) 61 xtables_error(PARAMETER_PROBLEM, "tos: Your kernel is " 62 "too old to support anything besides /0xFF " 63 "as a mask."); 64 info->tos = tvm.value; 65 if (invert) 66 info->invert = true; 67 *flags |= FLAG_TOS; 68 return true; 69 } 70 return false; 71} 72 73static int tos_mt_parse(int c, char **argv, int invert, unsigned int *flags, 74 const void *entry, struct xt_entry_match **match) 75{ 76 struct xt_tos_match_info *info = (void *)(*match)->data; 77 struct tos_value_mask tvm = {.mask = 0xFF}; 78 79 switch (c) { 80 case 't': 81 xtables_param_act(XTF_ONLY_ONCE, "tos", "--tos", *flags & FLAG_TOS); 82 if (!tos_parse_symbolic(optarg, &tvm, 0x3F)) 83 xtables_param_act(XTF_BAD_VALUE, "tos", "--tos", optarg); 84 info->tos_value = tvm.value; 85 info->tos_mask = tvm.mask; 86 if (invert) 87 info->invert = true; 88 *flags |= FLAG_TOS; 89 return true; 90 } 91 return false; 92} 93 94static void tos_mt_check(unsigned int flags) 95{ 96 if (flags == 0) 97 xtables_error(PARAMETER_PROBLEM, 98 "tos: --tos parameter required"); 99} 100 101static void tos_mt_print_v0(const void *ip, const struct xt_entry_match *match, 102 int numeric) 103{ 104 const struct ipt_tos_info *info = (const void *)match->data; 105 106 printf("tos match "); 107 if (info->invert) 108 printf("!"); 109 if (numeric || !tos_try_print_symbolic("", info->tos, 0x3F)) 110 printf("0x%02x ", info->tos); 111} 112 113static void tos_mt_print(const void *ip, const struct xt_entry_match *match, 114 int numeric) 115{ 116 const struct xt_tos_match_info *info = (const void *)match->data; 117 118 printf("tos match "); 119 if (info->invert) 120 printf("!"); 121 if (numeric || 122 !tos_try_print_symbolic("", info->tos_value, info->tos_mask)) 123 printf("0x%02x/0x%02x ", info->tos_value, info->tos_mask); 124} 125 126static void tos_mt_save_v0(const void *ip, const struct xt_entry_match *match) 127{ 128 const struct ipt_tos_info *info = (const void *)match->data; 129 130 if (info->invert) 131 printf("! "); 132 printf("--tos 0x%02x ", info->tos); 133} 134 135static void tos_mt_save(const void *ip, const struct xt_entry_match *match) 136{ 137 const struct xt_tos_match_info *info = (const void *)match->data; 138 139 if (info->invert) 140 printf("! "); 141 printf("--tos 0x%02x/0x%02x ", info->tos_value, info->tos_mask); 142} 143 144static struct xtables_match tos_mt_reg[] = { 145 { 146 .version = XTABLES_VERSION, 147 .name = "tos", 148 .family = NFPROTO_IPV4, 149 .revision = 0, 150 .size = XT_ALIGN(sizeof(struct ipt_tos_info)), 151 .userspacesize = XT_ALIGN(sizeof(struct ipt_tos_info)), 152 .help = tos_mt_help, 153 .parse = tos_mt_parse_v0, 154 .final_check = tos_mt_check, 155 .print = tos_mt_print_v0, 156 .save = tos_mt_save_v0, 157 .extra_opts = tos_mt_opts, 158 }, 159 { 160 .version = XTABLES_VERSION, 161 .name = "tos", 162 .family = NFPROTO_UNSPEC, 163 .revision = 1, 164 .size = XT_ALIGN(sizeof(struct xt_tos_match_info)), 165 .userspacesize = XT_ALIGN(sizeof(struct xt_tos_match_info)), 166 .help = tos_mt_help, 167 .parse = tos_mt_parse, 168 .final_check = tos_mt_check, 169 .print = tos_mt_print, 170 .save = tos_mt_save, 171 .extra_opts = tos_mt_opts, 172 }, 173}; 174 175void _init(void) 176{ 177 xtables_register_matches(tos_mt_reg, ARRAY_SIZE(tos_mt_reg)); 178} 179