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 (at) 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 18 struct ipt_tos_info { 19 uint8_t tos; 20 uint8_t invert; 21 }; 22 23 enum { 24 O_TOS = 1 << 0, 25 }; 26 27 static const struct xt_option_entry tos_mt_opts_v0[] = { 28 {.name = "tos", .id = O_TOS, .type = XTTYPE_TOSMASK, 29 .flags = XTOPT_INVERT | XTOPT_MAND, .max = 0xFF}, 30 XTOPT_TABLEEND, 31 }; 32 33 static const struct xt_option_entry tos_mt_opts[] = { 34 {.name = "tos", .id = O_TOS, .type = XTTYPE_TOSMASK, 35 .flags = XTOPT_INVERT | XTOPT_MAND, .max = 0x3F}, 36 XTOPT_TABLEEND, 37 }; 38 39 static void tos_mt_help(void) 40 { 41 const struct tos_symbol_info *symbol; 42 43 printf( 44 "tos match options:\n" 45 "[!] --tos value[/mask] Match Type of Service/Priority field value\n" 46 "[!] --tos symbol Match TOS field (IPv4 only) by symbol\n" 47 " Accepted symbolic names for value are:\n"); 48 49 for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol) 50 printf(" (0x%02x) %2u %s\n", 51 symbol->value, symbol->value, symbol->name); 52 53 printf("\n"); 54 } 55 56 static void tos_mt_parse_v0(struct xt_option_call *cb) 57 { 58 struct ipt_tos_info *info = cb->data; 59 60 xtables_option_parse(cb); 61 if (cb->val.tos_mask != 0xFF) 62 xtables_error(PARAMETER_PROBLEM, "tos: Your kernel is " 63 "too old to support anything besides /0xFF " 64 "as a mask."); 65 info->tos = cb->val.tos_value; 66 if (cb->invert) 67 info->invert = true; 68 } 69 70 static void tos_mt_parse(struct xt_option_call *cb) 71 { 72 struct xt_tos_match_info *info = cb->data; 73 74 xtables_option_parse(cb); 75 info->tos_value = cb->val.tos_value; 76 info->tos_mask = cb->val.tos_mask; 77 if (cb->invert) 78 info->invert = true; 79 } 80 81 static void tos_mt_print_v0(const void *ip, const struct xt_entry_match *match, 82 int numeric) 83 { 84 const struct ipt_tos_info *info = (const void *)match->data; 85 86 printf(" tos match "); 87 if (info->invert) 88 printf("!"); 89 if (numeric || !tos_try_print_symbolic("", info->tos, 0x3F)) 90 printf("0x%02x", info->tos); 91 } 92 93 static void tos_mt_print(const void *ip, const struct xt_entry_match *match, 94 int numeric) 95 { 96 const struct xt_tos_match_info *info = (const void *)match->data; 97 98 printf(" tos match"); 99 if (info->invert) 100 printf("!"); 101 if (numeric || 102 !tos_try_print_symbolic("", info->tos_value, info->tos_mask)) 103 printf("0x%02x/0x%02x", info->tos_value, info->tos_mask); 104 } 105 106 static void tos_mt_save_v0(const void *ip, const struct xt_entry_match *match) 107 { 108 const struct ipt_tos_info *info = (const void *)match->data; 109 110 if (info->invert) 111 printf(" !"); 112 printf(" --tos 0x%02x", info->tos); 113 } 114 115 static void tos_mt_save(const void *ip, const struct xt_entry_match *match) 116 { 117 const struct xt_tos_match_info *info = (const void *)match->data; 118 119 if (info->invert) 120 printf(" !"); 121 printf(" --tos 0x%02x/0x%02x", info->tos_value, info->tos_mask); 122 } 123 124 static struct xtables_match tos_mt_reg[] = { 125 { 126 .version = XTABLES_VERSION, 127 .name = "tos", 128 .family = NFPROTO_IPV4, 129 .revision = 0, 130 .size = XT_ALIGN(sizeof(struct ipt_tos_info)), 131 .userspacesize = XT_ALIGN(sizeof(struct ipt_tos_info)), 132 .help = tos_mt_help, 133 .print = tos_mt_print_v0, 134 .save = tos_mt_save_v0, 135 .x6_parse = tos_mt_parse_v0, 136 .x6_options = tos_mt_opts_v0, 137 }, 138 { 139 .version = XTABLES_VERSION, 140 .name = "tos", 141 .family = NFPROTO_UNSPEC, 142 .revision = 1, 143 .size = XT_ALIGN(sizeof(struct xt_tos_match_info)), 144 .userspacesize = XT_ALIGN(sizeof(struct xt_tos_match_info)), 145 .help = tos_mt_help, 146 .print = tos_mt_print, 147 .save = tos_mt_save, 148 .x6_parse = tos_mt_parse, 149 .x6_options = tos_mt_opts, 150 }, 151 }; 152 153 void _init(void) 154 { 155 xtables_register_matches(tos_mt_reg, ARRAY_SIZE(tos_mt_reg)); 156 } 157