libxt_DSCP.c revision c5e85736c207f211d82d2878a5781f512327dfce
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 "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 { .name = NULL } 44}; 45 46static void 47parse_dscp(const char *s, struct xt_DSCP_info *dinfo) 48{ 49 unsigned int dscp; 50 51 if (!xtables_strtoui(s, NULL, &dscp, 0, UINT8_MAX)) 52 xtables_error(PARAMETER_PROBLEM, 53 "Invalid dscp `%s'\n", s); 54 55 if (dscp > XT_DSCP_MAX) 56 xtables_error(PARAMETER_PROBLEM, 57 "DSCP `%d` out of range\n", dscp); 58 59 dinfo->dscp = dscp; 60} 61 62 63static void 64parse_class(const char *s, struct xt_DSCP_info *dinfo) 65{ 66 unsigned int dscp = class_to_dscp(s); 67 68 /* Assign the value */ 69 dinfo->dscp = dscp; 70} 71 72 73static int DSCP_parse(int c, char **argv, int invert, unsigned int *flags, 74 const void *entry, struct xt_entry_target **target) 75{ 76 struct xt_DSCP_info *dinfo 77 = (struct xt_DSCP_info *)(*target)->data; 78 79 switch (c) { 80 case 'F': 81 if (*flags) 82 xtables_error(PARAMETER_PROBLEM, 83 "DSCP target: Only use --set-dscp ONCE!"); 84 parse_dscp(optarg, dinfo); 85 *flags = 1; 86 break; 87 case 'G': 88 if (*flags) 89 xtables_error(PARAMETER_PROBLEM, 90 "DSCP target: Only use --set-dscp-class ONCE!"); 91 parse_class(optarg, dinfo); 92 *flags = 1; 93 break; 94 95 default: 96 return 0; 97 } 98 99 return 1; 100} 101 102static void DSCP_check(unsigned int flags) 103{ 104 if (!flags) 105 xtables_error(PARAMETER_PROBLEM, 106 "DSCP target: Parameter --set-dscp is required"); 107} 108 109static void 110print_dscp(u_int8_t dscp, int numeric) 111{ 112 printf("0x%02x ", dscp); 113} 114 115static void DSCP_print(const void *ip, const struct xt_entry_target *target, 116 int numeric) 117{ 118 const struct xt_DSCP_info *dinfo = 119 (const struct xt_DSCP_info *)target->data; 120 printf("DSCP set "); 121 print_dscp(dinfo->dscp, numeric); 122} 123 124static void DSCP_save(const void *ip, const struct xt_entry_target *target) 125{ 126 const struct xt_DSCP_info *dinfo = 127 (const struct xt_DSCP_info *)target->data; 128 129 printf("--set-dscp 0x%02x ", dinfo->dscp); 130} 131 132static struct xtables_target dscp_target = { 133 .family = NFPROTO_UNSPEC, 134 .name = "DSCP", 135 .version = XTABLES_VERSION, 136 .size = XT_ALIGN(sizeof(struct xt_DSCP_info)), 137 .userspacesize = XT_ALIGN(sizeof(struct xt_DSCP_info)), 138 .help = DSCP_help, 139 .parse = DSCP_parse, 140 .final_check = DSCP_check, 141 .print = DSCP_print, 142 .save = DSCP_save, 143 .extra_opts = DSCP_opts, 144}; 145 146void _init(void) 147{ 148 xtables_register_target(&dscp_target); 149} 150