1*a71a9546SAutomerger Merge Worker /* Shared library add-on to iptables for DSCP 2*a71a9546SAutomerger Merge Worker * 3*a71a9546SAutomerger Merge Worker * (C) 2002 by Harald Welte <[email protected]> 4*a71a9546SAutomerger Merge Worker * 5*a71a9546SAutomerger Merge Worker * This program is distributed under the terms of GNU GPL v2, 1991 6*a71a9546SAutomerger Merge Worker * 7*a71a9546SAutomerger Merge Worker * libipt_dscp.c borrowed heavily from libipt_tos.c 8*a71a9546SAutomerger Merge Worker * 9*a71a9546SAutomerger Merge Worker * --class support added by Iain Barnes 10*a71a9546SAutomerger Merge Worker * 11*a71a9546SAutomerger Merge Worker * For a list of DSCP codepoints see 12*a71a9546SAutomerger Merge Worker * http://www.iana.org/assignments/dscp-registry 13*a71a9546SAutomerger Merge Worker * 14*a71a9546SAutomerger Merge Worker */ 15*a71a9546SAutomerger Merge Worker #include <stdio.h> 16*a71a9546SAutomerger Merge Worker #include <string.h> 17*a71a9546SAutomerger Merge Worker #include <xtables.h> 18*a71a9546SAutomerger Merge Worker #include <linux/netfilter/xt_dscp.h> 19*a71a9546SAutomerger Merge Worker 20*a71a9546SAutomerger Merge Worker /* This is evil, but it's my code - HW*/ 21*a71a9546SAutomerger Merge Worker #include "dscp_helper.c" 22*a71a9546SAutomerger Merge Worker 23*a71a9546SAutomerger Merge Worker enum { 24*a71a9546SAutomerger Merge Worker O_DSCP = 0, 25*a71a9546SAutomerger Merge Worker O_DSCP_CLASS, 26*a71a9546SAutomerger Merge Worker F_DSCP = 1 << O_DSCP, 27*a71a9546SAutomerger Merge Worker F_DSCP_CLASS = 1 << O_DSCP_CLASS, 28*a71a9546SAutomerger Merge Worker }; 29*a71a9546SAutomerger Merge Worker 30*a71a9546SAutomerger Merge Worker static void dscp_help(void) 31*a71a9546SAutomerger Merge Worker { 32*a71a9546SAutomerger Merge Worker printf( 33*a71a9546SAutomerger Merge Worker "dscp match options\n" 34*a71a9546SAutomerger Merge Worker "[!] --dscp value Match DSCP codepoint with numerical value\n" 35*a71a9546SAutomerger Merge Worker " This value can be in decimal (ex: 32)\n" 36*a71a9546SAutomerger Merge Worker " or in hex (ex: 0x20)\n" 37*a71a9546SAutomerger Merge Worker "[!] --dscp-class name Match the DiffServ class. This value may\n" 38*a71a9546SAutomerger Merge Worker " be any of the BE,EF, AFxx or CSx classes\n" 39*a71a9546SAutomerger Merge Worker "\n" 40*a71a9546SAutomerger Merge Worker " These two options are mutually exclusive !\n"); 41*a71a9546SAutomerger Merge Worker } 42*a71a9546SAutomerger Merge Worker 43*a71a9546SAutomerger Merge Worker static const struct xt_option_entry dscp_opts[] = { 44*a71a9546SAutomerger Merge Worker {.name = "dscp", .id = O_DSCP, .excl = F_DSCP_CLASS, 45*a71a9546SAutomerger Merge Worker .type = XTTYPE_UINT8, .min = 0, .max = XT_DSCP_MAX, 46*a71a9546SAutomerger Merge Worker .flags = XTOPT_INVERT | XTOPT_PUT, 47*a71a9546SAutomerger Merge Worker XTOPT_POINTER(struct xt_dscp_info, dscp)}, 48*a71a9546SAutomerger Merge Worker {.name = "dscp-class", .id = O_DSCP_CLASS, .excl = F_DSCP, 49*a71a9546SAutomerger Merge Worker .type = XTTYPE_STRING, .flags = XTOPT_INVERT}, 50*a71a9546SAutomerger Merge Worker XTOPT_TABLEEND, 51*a71a9546SAutomerger Merge Worker }; 52*a71a9546SAutomerger Merge Worker 53*a71a9546SAutomerger Merge Worker static void dscp_parse(struct xt_option_call *cb) 54*a71a9546SAutomerger Merge Worker { 55*a71a9546SAutomerger Merge Worker struct xt_dscp_info *dinfo = cb->data; 56*a71a9546SAutomerger Merge Worker 57*a71a9546SAutomerger Merge Worker xtables_option_parse(cb); 58*a71a9546SAutomerger Merge Worker switch (cb->entry->id) { 59*a71a9546SAutomerger Merge Worker case O_DSCP: 60*a71a9546SAutomerger Merge Worker if (cb->invert) 61*a71a9546SAutomerger Merge Worker dinfo->invert = 1; 62*a71a9546SAutomerger Merge Worker break; 63*a71a9546SAutomerger Merge Worker case O_DSCP_CLASS: 64*a71a9546SAutomerger Merge Worker dinfo->dscp = class_to_dscp(cb->arg); 65*a71a9546SAutomerger Merge Worker if (cb->invert) 66*a71a9546SAutomerger Merge Worker dinfo->invert = 1; 67*a71a9546SAutomerger Merge Worker break; 68*a71a9546SAutomerger Merge Worker } 69*a71a9546SAutomerger Merge Worker } 70*a71a9546SAutomerger Merge Worker 71*a71a9546SAutomerger Merge Worker static void dscp_check(struct xt_fcheck_call *cb) 72*a71a9546SAutomerger Merge Worker { 73*a71a9546SAutomerger Merge Worker if (cb->xflags == 0) 74*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, 75*a71a9546SAutomerger Merge Worker "DSCP match: Parameter --dscp is required"); 76*a71a9546SAutomerger Merge Worker } 77*a71a9546SAutomerger Merge Worker 78*a71a9546SAutomerger Merge Worker static void 79*a71a9546SAutomerger Merge Worker dscp_print(const void *ip, const struct xt_entry_match *match, int numeric) 80*a71a9546SAutomerger Merge Worker { 81*a71a9546SAutomerger Merge Worker const struct xt_dscp_info *dinfo = 82*a71a9546SAutomerger Merge Worker (const struct xt_dscp_info *)match->data; 83*a71a9546SAutomerger Merge Worker printf(" DSCP match %s0x%02x", dinfo->invert ? "!" : "", dinfo->dscp); 84*a71a9546SAutomerger Merge Worker } 85*a71a9546SAutomerger Merge Worker 86*a71a9546SAutomerger Merge Worker static void dscp_save(const void *ip, const struct xt_entry_match *match) 87*a71a9546SAutomerger Merge Worker { 88*a71a9546SAutomerger Merge Worker const struct xt_dscp_info *dinfo = 89*a71a9546SAutomerger Merge Worker (const struct xt_dscp_info *)match->data; 90*a71a9546SAutomerger Merge Worker 91*a71a9546SAutomerger Merge Worker printf("%s --dscp 0x%02x", dinfo->invert ? " !" : "", dinfo->dscp); 92*a71a9546SAutomerger Merge Worker } 93*a71a9546SAutomerger Merge Worker 94*a71a9546SAutomerger Merge Worker static int __dscp_xlate(struct xt_xlate *xl, 95*a71a9546SAutomerger Merge Worker const struct xt_xlate_mt_params *params) 96*a71a9546SAutomerger Merge Worker { 97*a71a9546SAutomerger Merge Worker const struct xt_dscp_info *dinfo = 98*a71a9546SAutomerger Merge Worker (const struct xt_dscp_info *)params->match->data; 99*a71a9546SAutomerger Merge Worker 100*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "dscp %s0x%02x", dinfo->invert ? "!= " : "", 101*a71a9546SAutomerger Merge Worker dinfo->dscp); 102*a71a9546SAutomerger Merge Worker 103*a71a9546SAutomerger Merge Worker return 1; 104*a71a9546SAutomerger Merge Worker } 105*a71a9546SAutomerger Merge Worker 106*a71a9546SAutomerger Merge Worker static int dscp_xlate(struct xt_xlate *xl, 107*a71a9546SAutomerger Merge Worker const struct xt_xlate_mt_params *params) 108*a71a9546SAutomerger Merge Worker { 109*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "ip "); 110*a71a9546SAutomerger Merge Worker 111*a71a9546SAutomerger Merge Worker return __dscp_xlate(xl, params); 112*a71a9546SAutomerger Merge Worker } 113*a71a9546SAutomerger Merge Worker 114*a71a9546SAutomerger Merge Worker static int dscp_xlate6(struct xt_xlate *xl, 115*a71a9546SAutomerger Merge Worker const struct xt_xlate_mt_params *params) 116*a71a9546SAutomerger Merge Worker { 117*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "ip6 "); 118*a71a9546SAutomerger Merge Worker 119*a71a9546SAutomerger Merge Worker return __dscp_xlate(xl, params); 120*a71a9546SAutomerger Merge Worker } 121*a71a9546SAutomerger Merge Worker 122*a71a9546SAutomerger Merge Worker static struct xtables_match dscp_mt_reg[] = { 123*a71a9546SAutomerger Merge Worker { 124*a71a9546SAutomerger Merge Worker .family = NFPROTO_IPV4, 125*a71a9546SAutomerger Merge Worker .name = "dscp", 126*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION, 127*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_dscp_info)), 128*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_dscp_info)), 129*a71a9546SAutomerger Merge Worker .help = dscp_help, 130*a71a9546SAutomerger Merge Worker .print = dscp_print, 131*a71a9546SAutomerger Merge Worker .save = dscp_save, 132*a71a9546SAutomerger Merge Worker .x6_parse = dscp_parse, 133*a71a9546SAutomerger Merge Worker .x6_fcheck = dscp_check, 134*a71a9546SAutomerger Merge Worker .x6_options = dscp_opts, 135*a71a9546SAutomerger Merge Worker .xlate = dscp_xlate, 136*a71a9546SAutomerger Merge Worker }, 137*a71a9546SAutomerger Merge Worker { 138*a71a9546SAutomerger Merge Worker .family = NFPROTO_IPV6, 139*a71a9546SAutomerger Merge Worker .name = "dscp", 140*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION, 141*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_dscp_info)), 142*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_dscp_info)), 143*a71a9546SAutomerger Merge Worker .help = dscp_help, 144*a71a9546SAutomerger Merge Worker .print = dscp_print, 145*a71a9546SAutomerger Merge Worker .save = dscp_save, 146*a71a9546SAutomerger Merge Worker .x6_parse = dscp_parse, 147*a71a9546SAutomerger Merge Worker .x6_fcheck = dscp_check, 148*a71a9546SAutomerger Merge Worker .x6_options = dscp_opts, 149*a71a9546SAutomerger Merge Worker .xlate = dscp_xlate6, 150*a71a9546SAutomerger Merge Worker }, 151*a71a9546SAutomerger Merge Worker }; 152*a71a9546SAutomerger Merge Worker 153*a71a9546SAutomerger Merge Worker void _init(void) 154*a71a9546SAutomerger Merge Worker { 155*a71a9546SAutomerger Merge Worker xtables_register_matches(dscp_mt_reg, ARRAY_SIZE(dscp_mt_reg)); 156*a71a9546SAutomerger Merge Worker } 157