Home | History | Annotate | Download | only in extensions
      1 /* Shared library add-on to iptables for DSCP
      2  *
      3  * (C) 2000- 2002 by Matthew G. Marsh <mgm (at) paktronix.com>,
      4  * 		     Harald Welte <laforge (at) 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 <xtables.h>
     15 #include <linux/netfilter/xt_DSCP.h>
     16 
     17 /* This is evil, but it's my code - HW*/
     18 #include "dscp_helper.c"
     19 
     20 enum {
     21 	O_SET_DSCP = 0,
     22 	O_SET_DSCP_CLASS,
     23 	F_SET_DSCP       = 1 << O_SET_DSCP,
     24 	F_SET_DSCP_CLASS = 1 << O_SET_DSCP_CLASS,
     25 };
     26 
     27 static void DSCP_help(void)
     28 {
     29 	printf(
     30 "DSCP target options\n"
     31 "  --set-dscp value		Set DSCP field in packet header to value\n"
     32 "  		                This value can be in decimal (ex: 32)\n"
     33 "               		or in hex (ex: 0x20)\n"
     34 "  --set-dscp-class class	Set the DSCP field in packet header to the\n"
     35 "				value represented by the DiffServ class value.\n"
     36 "				This class may be EF,BE or any of the CSxx\n"
     37 "				or AFxx classes.\n"
     38 "\n"
     39 "				These two options are mutually exclusive !\n"
     40 );
     41 }
     42 
     43 static const struct xt_option_entry DSCP_opts[] = {
     44 	{.name = "set-dscp", .id = O_SET_DSCP, .excl = F_SET_DSCP_CLASS,
     45 	 .type = XTTYPE_UINT8, .min = 0, .max = XT_DSCP_MAX,
     46 	 .flags = XTOPT_PUT,
     47 	 XTOPT_POINTER(struct xt_DSCP_info, dscp)},
     48 	{.name = "set-dscp-class", .id = O_SET_DSCP_CLASS, .excl = F_SET_DSCP,
     49 	 .type = XTTYPE_STRING},
     50 	XTOPT_TABLEEND,
     51 };
     52 
     53 static void DSCP_parse(struct xt_option_call *cb)
     54 {
     55 	struct xt_DSCP_info *dinfo = cb->data;
     56 
     57 	xtables_option_parse(cb);
     58 	switch (cb->entry->id) {
     59 	case O_SET_DSCP_CLASS:
     60 		dinfo->dscp = class_to_dscp(cb->arg);
     61 		break;
     62 	}
     63 }
     64 
     65 static void DSCP_check(struct xt_fcheck_call *cb)
     66 {
     67 	if (cb->xflags == 0)
     68 		xtables_error(PARAMETER_PROBLEM,
     69 		           "DSCP target: Parameter --set-dscp is required");
     70 }
     71 
     72 static void
     73 print_dscp(uint8_t dscp, int numeric)
     74 {
     75 	printf(" 0x%02x", dscp);
     76 }
     77 
     78 static void DSCP_print(const void *ip, const struct xt_entry_target *target,
     79                        int numeric)
     80 {
     81 	const struct xt_DSCP_info *dinfo =
     82 		(const struct xt_DSCP_info *)target->data;
     83 	printf(" DSCP set");
     84 	print_dscp(dinfo->dscp, numeric);
     85 }
     86 
     87 static void DSCP_save(const void *ip, const struct xt_entry_target *target)
     88 {
     89 	const struct xt_DSCP_info *dinfo =
     90 		(const struct xt_DSCP_info *)target->data;
     91 
     92 	printf(" --set-dscp 0x%02x", dinfo->dscp);
     93 }
     94 
     95 static struct xtables_target dscp_target = {
     96 	.family		= NFPROTO_UNSPEC,
     97 	.name		= "DSCP",
     98 	.version	= XTABLES_VERSION,
     99 	.size		= XT_ALIGN(sizeof(struct xt_DSCP_info)),
    100 	.userspacesize	= XT_ALIGN(sizeof(struct xt_DSCP_info)),
    101 	.help		= DSCP_help,
    102 	.print		= DSCP_print,
    103 	.save		= DSCP_save,
    104 	.x6_parse	= DSCP_parse,
    105 	.x6_fcheck	= DSCP_check,
    106 	.x6_options	= DSCP_opts,
    107 };
    108 
    109 void _init(void)
    110 {
    111 	xtables_register_target(&dscp_target);
    112 }
    113