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_INVERT | XTOPT_PUT, 47 XTOPT_POINTER(struct xt_dscp_info, dscp)}, 48 {.name = "dscp-class", .id = O_DSCP_CLASS, .excl = F_DSCP, 49 .type = XTTYPE_STRING, .flags = XTOPT_INVERT}, 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_DSCP: 60 if (cb->invert) 61 dinfo->invert = 1; 62 break; 63 case O_DSCP_CLASS: 64 dinfo->dscp = class_to_dscp(cb->arg); 65 if (cb->invert) 66 dinfo->invert = 1; 67 break; 68 } 69 } 70 71 static void dscp_check(struct xt_fcheck_call *cb) 72 { 73 if (cb->xflags == 0) 74 xtables_error(PARAMETER_PROBLEM, 75 "DSCP match: Parameter --dscp is required"); 76 } 77 78 static void 79 dscp_print(const void *ip, const struct xt_entry_match *match, int numeric) 80 { 81 const struct xt_dscp_info *dinfo = 82 (const struct xt_dscp_info *)match->data; 83 printf(" DSCP match %s0x%02x", dinfo->invert ? "!" : "", dinfo->dscp); 84 } 85 86 static void dscp_save(const void *ip, const struct xt_entry_match *match) 87 { 88 const struct xt_dscp_info *dinfo = 89 (const struct xt_dscp_info *)match->data; 90 91 printf("%s --dscp 0x%02x", dinfo->invert ? " !" : "", dinfo->dscp); 92 } 93 94 static int __dscp_xlate(struct xt_xlate *xl, 95 const struct xt_xlate_mt_params *params) 96 { 97 const struct xt_dscp_info *dinfo = 98 (const struct xt_dscp_info *)params->match->data; 99 100 xt_xlate_add(xl, "dscp %s0x%02x", dinfo->invert ? "!= " : "", 101 dinfo->dscp); 102 103 return 1; 104 } 105 106 static int dscp_xlate(struct xt_xlate *xl, 107 const struct xt_xlate_mt_params *params) 108 { 109 xt_xlate_add(xl, "ip "); 110 111 return __dscp_xlate(xl, params); 112 } 113 114 static int dscp_xlate6(struct xt_xlate *xl, 115 const struct xt_xlate_mt_params *params) 116 { 117 xt_xlate_add(xl, "ip6 "); 118 119 return __dscp_xlate(xl, params); 120 } 121 122 static struct xtables_match dscp_mt_reg[] = { 123 { 124 .family = NFPROTO_IPV4, 125 .name = "dscp", 126 .version = XTABLES_VERSION, 127 .size = XT_ALIGN(sizeof(struct xt_dscp_info)), 128 .userspacesize = XT_ALIGN(sizeof(struct xt_dscp_info)), 129 .help = dscp_help, 130 .print = dscp_print, 131 .save = dscp_save, 132 .x6_parse = dscp_parse, 133 .x6_fcheck = dscp_check, 134 .x6_options = dscp_opts, 135 .xlate = dscp_xlate, 136 }, 137 { 138 .family = NFPROTO_IPV6, 139 .name = "dscp", 140 .version = XTABLES_VERSION, 141 .size = XT_ALIGN(sizeof(struct xt_dscp_info)), 142 .userspacesize = XT_ALIGN(sizeof(struct xt_dscp_info)), 143 .help = dscp_help, 144 .print = dscp_print, 145 .save = dscp_save, 146 .x6_parse = dscp_parse, 147 .x6_fcheck = dscp_check, 148 .x6_options = dscp_opts, 149 .xlate = dscp_xlate6, 150 }, 151 }; 152 153 void _init(void) 154 { 155 xtables_register_matches(dscp_mt_reg, ARRAY_SIZE(dscp_mt_reg)); 156 } 157