libxt_DSCP.c revision 932e648f38ac16b1ea14c1f66f23951388448c5a
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 24static void DSCP_help(void) 25{ 26 printf( 27"DSCP target options\n" 28" --set-dscp value Set DSCP field in packet header to value\n" 29" This value can be in decimal (ex: 32)\n" 30" or in hex (ex: 0x20)\n" 31" --set-dscp-class class Set the DSCP field in packet header to the\n" 32" value represented by the DiffServ class value.\n" 33" This class may be EF,BE or any of the CSxx\n" 34" or AFxx classes.\n" 35"\n" 36" These two options are mutually exclusive !\n" 37); 38} 39 40static const struct option DSCP_opts[] = { 41 { "set-dscp", 1, NULL, 'F' }, 42 { "set-dscp-class", 1, NULL, 'G' }, 43 { } 44}; 45 46static void 47parse_dscp(const char *s, struct xt_DSCP_info *dinfo) 48{ 49 unsigned int dscp; 50 51 if (string_to_number(s, 0, 255, &dscp) == -1) 52 exit_error(PARAMETER_PROBLEM, 53 "Invalid dscp `%s'\n", s); 54 55 if (dscp > XT_DSCP_MAX) 56 exit_error(PARAMETER_PROBLEM, 57 "DSCP `%d` out of range\n", dscp); 58 59 dinfo->dscp = (u_int8_t )dscp; 60 return; 61} 62 63 64static void 65parse_class(const char *s, struct xt_DSCP_info *dinfo) 66{ 67 unsigned int dscp = class_to_dscp(s); 68 69 /* Assign the value */ 70 dinfo->dscp = (u_int8_t)dscp; 71} 72 73 74static int DSCP_parse(int c, char **argv, int invert, unsigned int *flags, 75 const void *entry, struct xt_entry_target **target) 76{ 77 struct xt_DSCP_info *dinfo 78 = (struct xt_DSCP_info *)(*target)->data; 79 80 switch (c) { 81 case 'F': 82 if (*flags) 83 exit_error(PARAMETER_PROBLEM, 84 "DSCP target: Only use --set-dscp ONCE!"); 85 parse_dscp(optarg, dinfo); 86 *flags = 1; 87 break; 88 case 'G': 89 if (*flags) 90 exit_error(PARAMETER_PROBLEM, 91 "DSCP target: Only use --set-dscp-class ONCE!"); 92 parse_class(optarg, dinfo); 93 *flags = 1; 94 break; 95 96 default: 97 return 0; 98 } 99 100 return 1; 101} 102 103static void DSCP_check(unsigned int flags) 104{ 105 if (!flags) 106 exit_error(PARAMETER_PROBLEM, 107 "DSCP target: Parameter --set-dscp is required"); 108} 109 110static void 111print_dscp(u_int8_t dscp, int numeric) 112{ 113 printf("0x%02x ", dscp); 114} 115 116/* Prints out the targinfo. */ 117static void DSCP_print(const void *ip, const struct xt_entry_target *target, 118 int numeric) 119{ 120 const struct xt_DSCP_info *dinfo = 121 (const struct xt_DSCP_info *)target->data; 122 printf("DSCP set "); 123 print_dscp(dinfo->dscp, numeric); 124} 125 126/* Saves the union ipt_targinfo in parsable form to stdout. */ 127static void DSCP_save(const void *ip, const struct xt_entry_target *target) 128{ 129 const struct xt_DSCP_info *dinfo = 130 (const struct xt_DSCP_info *)target->data; 131 132 printf("--set-dscp 0x%02x ", dinfo->dscp); 133} 134 135static struct xtables_target dscp_target = { 136 .family = AF_INET, 137 .name = "DSCP", 138 .version = IPTABLES_VERSION, 139 .size = XT_ALIGN(sizeof(struct xt_DSCP_info)), 140 .userspacesize = XT_ALIGN(sizeof(struct xt_DSCP_info)), 141 .help = DSCP_help, 142 .parse = DSCP_parse, 143 .final_check = DSCP_check, 144 .print = DSCP_print, 145 .save = DSCP_save, 146 .extra_opts = DSCP_opts, 147}; 148 149static struct xtables_target dscp_target6 = { 150 .family = AF_INET6, 151 .name = "DSCP", 152 .version = IPTABLES_VERSION, 153 .size = XT_ALIGN(sizeof(struct xt_DSCP_info)), 154 .userspacesize = XT_ALIGN(sizeof(struct xt_DSCP_info)), 155 .help = DSCP_help, 156 .parse = DSCP_parse, 157 .final_check = DSCP_check, 158 .print = DSCP_print, 159 .save = DSCP_save, 160 .extra_opts = DSCP_opts, 161}; 162 163void _init(void) 164{ 165 xtables_register_target(&dscp_target); 166 xtables_register_target(&dscp_target6); 167} 168