Home | History | Annotate | Download | only in extensions
      1 /* Shared library add-on to iptables for DSCP
      2  *
      3  * (C) 2002 by Harald Welte <laforge (at) gnumonks.org>
      4  *
      5  * This program is distributed under the terms of GNU GPL v2, 1991
      6  *
      7  * libipt_dscp.c borrowed heavily from libipt_tos.c
      8  *
      9  * --class support added by Iain Barnes
     10  *
     11  * For a list of DSCP codepoints see
     12  * http://www.iana.org/assignments/dscp-registry
     13  *
     14  */
     15 #include <stdio.h>
     16 #include <string.h>
     17 #include <xtables.h>
     18 #include <linux/netfilter/xt_dscp.h>
     19 
     20 /* This is evil, but it's my code - HW*/
     21 #include "dscp_helper.c"
     22 
     23 enum {
     24 	O_DSCP = 0,
     25 	O_DSCP_CLASS,
     26 	F_DSCP       = 1 << O_DSCP,
     27 	F_DSCP_CLASS = 1 << O_DSCP_CLASS,
     28 };
     29 
     30 static void dscp_help(void)
     31 {
     32 	printf(
     33 "dscp match options\n"
     34 "[!] --dscp value		Match DSCP codepoint with numerical value\n"
     35 "  		                This value can be in decimal (ex: 32)\n"
     36 "               		or in hex (ex: 0x20)\n"
     37 "[!] --dscp-class name		Match the DiffServ class. This value may\n"
     38 "				be any of the BE,EF, AFxx or CSx classes\n"
     39 "\n"
     40 "				These two options are mutually exclusive !\n");
     41 }
     42 
     43 static const struct xt_option_entry dscp_opts[] = {
     44 	{.name = "dscp", .id = O_DSCP, .excl = F_DSCP_CLASS,
     45 	 .type = XTTYPE_UINT8, .min = 0, .max = XT_DSCP_MAX,
     46 	 .flags = XTOPT_PUT, XTOPT_POINTER(struct xt_dscp_info, dscp)},
     47 	{.name = "dscp-class", .id = O_DSCP_CLASS, .excl = F_DSCP,
     48 	 .type = XTTYPE_STRING},
     49 	XTOPT_TABLEEND,
     50 };
     51 
     52 static void dscp_parse(struct xt_option_call *cb)
     53 {
     54 	struct xt_dscp_info *dinfo = cb->data;
     55 
     56 	xtables_option_parse(cb);
     57 	switch (cb->entry->id) {
     58 	case O_DSCP:
     59 		if (cb->invert)
     60 			dinfo->invert = 1;
     61 		break;
     62 	case O_DSCP_CLASS:
     63 		dinfo->dscp = class_to_dscp(cb->arg);
     64 		if (cb->invert)
     65 			dinfo->invert = 1;
     66 		break;
     67 	}
     68 }
     69 
     70 static void dscp_check(struct xt_fcheck_call *cb)
     71 {
     72 	if (cb->xflags == 0)
     73 		xtables_error(PARAMETER_PROBLEM,
     74 		           "DSCP match: Parameter --dscp is required");
     75 }
     76 
     77 static void
     78 dscp_print(const void *ip, const struct xt_entry_match *match, int numeric)
     79 {
     80 	const struct xt_dscp_info *dinfo =
     81 		(const struct xt_dscp_info *)match->data;
     82 	printf(" DSCP match %s0x%02x", dinfo->invert ? "!" : "", dinfo->dscp);
     83 }
     84 
     85 static void dscp_save(const void *ip, const struct xt_entry_match *match)
     86 {
     87 	const struct xt_dscp_info *dinfo =
     88 		(const struct xt_dscp_info *)match->data;
     89 
     90 	printf("%s --dscp 0x%02x", dinfo->invert ? " !" : "", dinfo->dscp);
     91 }
     92 
     93 static struct xtables_match dscp_match = {
     94 	.family		= NFPROTO_UNSPEC,
     95 	.name 		= "dscp",
     96 	.version 	= XTABLES_VERSION,
     97 	.size 		= XT_ALIGN(sizeof(struct xt_dscp_info)),
     98 	.userspacesize	= XT_ALIGN(sizeof(struct xt_dscp_info)),
     99 	.help		= dscp_help,
    100 	.print		= dscp_print,
    101 	.save		= dscp_save,
    102 	.x6_parse	= dscp_parse,
    103 	.x6_fcheck	= dscp_check,
    104 	.x6_options	= dscp_opts,
    105 };
    106 
    107 void _init(void)
    108 {
    109 	xtables_register_match(&dscp_match);
    110 }
    111