libxt_DSCP.c revision 500f483fff529dcd88ec96b9d5054be6cd6363a0
1/* Shared library add-on to iptables for DSCP 2 * 3 * (C) 2000- 2002 by Matthew G. Marsh <mgm@paktronix.com>, 4 * Harald Welte <laforge@gnumonks.org> 5 * 6 * This program is distributed under the terms of GNU GPL v2, 1991 7 * 8 * libipt_DSCP.c borrowed heavily from libipt_TOS.c 9 * 10 * --set-class added by Iain Barnes 11 */ 12#include <stdio.h> 13#include <string.h> 14#include <stdlib.h> 15#include <getopt.h> 16 17#include <xtables.h> 18#include <linux/netfilter/x_tables.h> 19#include <linux/netfilter/xt_DSCP.h> 20 21/* This is evil, but it's my code - HW*/ 22#include "libipt_dscp_helper.c" 23 24 25static void init(struct xt_entry_target *t) 26{ 27} 28 29static void help(void) 30{ 31 printf( 32"DSCP target options\n" 33" --set-dscp value Set DSCP field in packet header to value\n" 34" This value can be in decimal (ex: 32)\n" 35" or in hex (ex: 0x20)\n" 36" --set-dscp-class class Set the DSCP field in packet header to the\n" 37" value represented by the DiffServ class value.\n" 38" This class may be EF,BE or any of the CSxx\n" 39" or AFxx classes.\n" 40"\n" 41" These two options are mutually exclusive !\n" 42); 43} 44 45static const struct option opts[] = { 46 { "set-dscp", 1, NULL, 'F' }, 47 { "set-dscp-class", 1, NULL, 'G' }, 48 { } 49}; 50 51static void 52parse_dscp(const char *s, struct xt_DSCP_info *dinfo) 53{ 54 unsigned int dscp; 55 56 if (string_to_number(s, 0, 255, &dscp) == -1) 57 exit_error(PARAMETER_PROBLEM, 58 "Invalid dscp `%s'\n", s); 59 60 if (dscp > XT_DSCP_MAX) 61 exit_error(PARAMETER_PROBLEM, 62 "DSCP `%d` out of range\n", dscp); 63 64 dinfo->dscp = (u_int8_t )dscp; 65 return; 66} 67 68 69static void 70parse_class(const char *s, struct xt_DSCP_info *dinfo) 71{ 72 unsigned int dscp = class_to_dscp(s); 73 74 /* Assign the value */ 75 dinfo->dscp = (u_int8_t)dscp; 76} 77 78 79static int 80parse(int c, char **argv, int invert, unsigned int *flags, 81 const void *entry, 82 struct xt_entry_target **target) 83{ 84 struct xt_DSCP_info *dinfo 85 = (struct xt_DSCP_info *)(*target)->data; 86 87 switch (c) { 88 case 'F': 89 if (*flags) 90 exit_error(PARAMETER_PROBLEM, 91 "DSCP target: Only use --set-dscp ONCE!"); 92 parse_dscp(optarg, dinfo); 93 *flags = 1; 94 break; 95 case 'G': 96 if (*flags) 97 exit_error(PARAMETER_PROBLEM, 98 "DSCP target: Only use --set-dscp-class ONCE!"); 99 parse_class(optarg, dinfo); 100 *flags = 1; 101 break; 102 103 default: 104 return 0; 105 } 106 107 return 1; 108} 109 110static void 111final_check(unsigned int flags) 112{ 113 if (!flags) 114 exit_error(PARAMETER_PROBLEM, 115 "DSCP target: Parameter --set-dscp is required"); 116} 117 118static void 119print_dscp(u_int8_t dscp, int numeric) 120{ 121 printf("0x%02x ", dscp); 122} 123 124/* Prints out the targinfo. */ 125static void 126print(const void *ip, 127 const struct xt_entry_target *target, 128 int numeric) 129{ 130 const struct xt_DSCP_info *dinfo = 131 (const struct xt_DSCP_info *)target->data; 132 printf("DSCP set "); 133 print_dscp(dinfo->dscp, numeric); 134} 135 136/* Saves the union ipt_targinfo in parsable form to stdout. */ 137static void 138save(const void *ip, const struct xt_entry_target *target) 139{ 140 const struct xt_DSCP_info *dinfo = 141 (const struct xt_DSCP_info *)target->data; 142 143 printf("--set-dscp 0x%02x ", dinfo->dscp); 144} 145 146static struct xtables_target dscp = { 147 .family = AF_INET, 148 .name = "DSCP", 149 .version = IPTABLES_VERSION, 150 .size = XT_ALIGN(sizeof(struct xt_DSCP_info)), 151 .userspacesize = XT_ALIGN(sizeof(struct xt_DSCP_info)), 152 .help = &help, 153 .init = &init, 154 .parse = &parse, 155 .final_check = &final_check, 156 .print = &print, 157 .save = &save, 158 .extra_opts = opts, 159}; 160 161static struct xtables_target dscp6 = { 162 .family = AF_INET6, 163 .name = "DSCP", 164 .version = IPTABLES_VERSION, 165 .size = XT_ALIGN(sizeof(struct xt_DSCP_info)), 166 .userspacesize = XT_ALIGN(sizeof(struct xt_DSCP_info)), 167 .help = &help, 168 .init = &init, 169 .parse = &parse, 170 .final_check = &final_check, 171 .print = &print, 172 .save = &save, 173 .extra_opts = opts, 174}; 175 176void _init(void) 177{ 178 xtables_register_target(&dscp); 179 xtables_register_target(&dscp6); 180} 181