1/* Shared library add-on to iptables to add TOS matching support. */ 2#include <stdio.h> 3#include <netdb.h> 4#include <string.h> 5#include <stdlib.h> 6#include <getopt.h> 7 8#include <iptables.h> 9#include <linux/netfilter_ipv4/ipt_tos.h> 10 11/* TOS names and values. */ 12static 13struct TOS_value 14{ 15 unsigned char TOS; 16 const char *name; 17} TOS_values[] = { 18 { IPTOS_LOWDELAY, "Minimize-Delay" }, 19 { IPTOS_THROUGHPUT, "Maximize-Throughput" }, 20 { IPTOS_RELIABILITY, "Maximize-Reliability" }, 21 { IPTOS_MINCOST, "Minimize-Cost" }, 22 { IPTOS_NORMALSVC, "Normal-Service" }, 23}; 24 25/* Function which prints out usage message. */ 26static void 27help(void) 28{ 29 unsigned int i; 30 31 printf( 32"TOS match v%s options:\n" 33"[!] --tos value Match Type of Service field from one of the\n" 34" following numeric or descriptive values:\n", 35IPTABLES_VERSION); 36 37 for (i = 0; i < sizeof(TOS_values)/sizeof(struct TOS_value);i++) 38 printf(" %s %u (0x%02x)\n", 39 TOS_values[i].name, 40 TOS_values[i].TOS, 41 TOS_values[i].TOS); 42 fputc('\n', stdout); 43} 44 45static struct option opts[] = { 46 { "tos", 1, 0, '1' }, 47 {0} 48}; 49 50static void 51parse_tos(const char *s, struct ipt_tos_info *info) 52{ 53 unsigned int i; 54 unsigned int tos; 55 56 if (string_to_number(s, 0, 255, &tos) != -1) { 57 if (tos == IPTOS_LOWDELAY 58 || tos == IPTOS_THROUGHPUT 59 || tos == IPTOS_RELIABILITY 60 || tos == IPTOS_MINCOST 61 || tos == IPTOS_NORMALSVC) { 62 info->tos = (u_int8_t )tos; 63 return; 64 } 65 } else { 66 for (i = 0; i<sizeof(TOS_values)/sizeof(struct TOS_value); i++) 67 if (strcasecmp(s,TOS_values[i].name) == 0) { 68 info->tos = TOS_values[i].TOS; 69 return; 70 } 71 } 72 exit_error(PARAMETER_PROBLEM, "Bad TOS value `%s'", s); 73} 74 75/* Function which parses command options; returns true if it 76 ate an option */ 77static int 78parse(int c, char **argv, int invert, unsigned int *flags, 79 const struct ipt_entry *entry, 80 unsigned int *nfcache, 81 struct ipt_entry_match **match) 82{ 83 struct ipt_tos_info *tosinfo = (struct ipt_tos_info *)(*match)->data; 84 85 switch (c) { 86 case '1': 87 /* Ensure that `--tos' haven't been used yet. */ 88 if (*flags == 1) 89 exit_error(PARAMETER_PROBLEM, 90 "tos match: only use --tos once!"); 91 92 check_inverse(optarg, &invert, &optind, 0); 93 parse_tos(argv[optind-1], tosinfo); 94 if (invert) 95 tosinfo->invert = 1; 96 *flags = 1; 97 break; 98 99 default: 100 return 0; 101 } 102 return 1; 103} 104 105static void 106print_tos(u_int8_t tos, int numeric) 107{ 108 unsigned int i; 109 110 if (!numeric) { 111 for (i = 0; i<sizeof(TOS_values)/sizeof(struct TOS_value); i++) 112 if (TOS_values[i].TOS == tos) { 113 printf("%s ", TOS_values[i].name); 114 return; 115 } 116 } 117 printf("0x%02x ", tos); 118} 119 120/* Final check; must have specified --tos. */ 121static void 122final_check(unsigned int flags) 123{ 124 if (!flags) 125 exit_error(PARAMETER_PROBLEM, 126 "TOS match: You must specify `--tos'"); 127} 128 129/* Prints out the matchinfo. */ 130static void 131print(const struct ipt_ip *ip, 132 const struct ipt_entry_match *match, 133 int numeric) 134{ 135 const struct ipt_tos_info *info = (const struct ipt_tos_info *)match->data; 136 137 printf("TOS match "); 138 if (info->invert) 139 printf("!"); 140 print_tos(info->tos, numeric); 141} 142 143/* Saves the union ipt_matchinfo in parsable form to stdout. */ 144static void 145save(const struct ipt_ip *ip, const struct ipt_entry_match *match) 146{ 147 const struct ipt_tos_info *info = (const struct ipt_tos_info *)match->data; 148 149 if (info->invert) 150 printf("! "); 151 printf("--tos "); 152 print_tos(info->tos, 0); 153} 154 155static struct iptables_match tos = { 156 .next = NULL, 157 .name = "tos", 158 .version = IPTABLES_VERSION, 159 .size = IPT_ALIGN(sizeof(struct ipt_tos_info)), 160 .userspacesize = IPT_ALIGN(sizeof(struct ipt_tos_info)), 161 .help = &help, 162 .parse = &parse, 163 .final_check = &final_check, 164 .print = &print, 165 .save = &save, 166 .extra_opts = opts 167}; 168 169void _init(void) 170{ 171 register_match(&tos); 172} 173