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