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