blob: 69533d6b22c6e29e01f8e425fefc3b3c060eace0 [file] [log] [blame]
Harald Welte487d1d32002-03-14 12:22:06 +00001/* Shared library add-on to iptables for DSCP
2 *
3 * (C) 2002 by Harald Welte <laforge@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 *
Iain Barnes0ddae8f2002-06-21 17:35:55 +00009 * --class support added by Iain Barnes
10 *
Harald Welte487d1d32002-03-14 12:22:06 +000011 * 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>
Yasuyuki KOZAKAI18e06082007-07-24 07:17:23 +000017#include <xtables.h>
Yasuyuki KOZAKAI18e06082007-07-24 07:17:23 +000018#include <linux/netfilter/xt_dscp.h>
Harald Welte487d1d32002-03-14 12:22:06 +000019
Iain Barnes0ddae8f2002-06-21 17:35:55 +000020/* This is evil, but it's my code - HW*/
Jan Engelhardtf82070f2008-01-20 13:14:00 +000021#include "dscp_helper.c"
Iain Barnes0ddae8f2002-06-21 17:35:55 +000022
Jan Engelhardt72c35972011-03-01 20:28:24 +010023enum {
24 O_DSCP = 0,
25 O_DSCP_CLASS,
26 F_DSCP = 1 << O_DSCP,
27 F_DSCP_CLASS = 1 << O_DSCP_CLASS,
28};
29
Jan Engelhardt181dead2007-10-04 16:27:07 +000030static void dscp_help(void)
Harald Welte487d1d32002-03-14 12:22:06 +000031{
32 printf(
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020033"dscp match options\n"
Harald Welte487d1d32002-03-14 12:22:06 +000034"[!] --dscp value Match DSCP codepoint with numerical value\n"
35" This value can be in decimal (ex: 32)\n"
Iain Barnes0ddae8f2002-06-21 17:35:55 +000036" or in hex (ex: 0x20)\n"
Harald Weltea49ded02002-08-07 09:55:37 +000037"[!] --dscp-class name Match the DiffServ class. This value may\n"
Iain Barnes0ddae8f2002-06-21 17:35:55 +000038" be any of the BE,EF, AFxx or CSx classes\n"
39"\n"
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020040" These two options are mutually exclusive !\n");
Harald Welte487d1d32002-03-14 12:22:06 +000041}
42
Jan Engelhardt72c35972011-03-01 20:28:24 +010043static 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,
Harald Welte487d1d32002-03-14 12:22:06 +000050};
51
Jan Engelhardt72c35972011-03-01 20:28:24 +010052static void dscp_parse(struct xt_option_call *cb)
Harald Welte487d1d32002-03-14 12:22:06 +000053{
Jan Engelhardt72c35972011-03-01 20:28:24 +010054 struct xt_dscp_info *dinfo = cb->data;
Harald Welte487d1d32002-03-14 12:22:06 +000055
Jan Engelhardt72c35972011-03-01 20:28:24 +010056 xtables_option_parse(cb);
57 switch (cb->entry->id) {
58 case O_DSCP:
59 if (cb->invert)
Harald Welte487d1d32002-03-14 12:22:06 +000060 dinfo->invert = 1;
Harald Welte487d1d32002-03-14 12:22:06 +000061 break;
Jan Engelhardt72c35972011-03-01 20:28:24 +010062 case O_DSCP_CLASS:
63 dinfo->dscp = class_to_dscp(cb->arg);
64 if (cb->invert)
Iain Barnes0ddae8f2002-06-21 17:35:55 +000065 dinfo->invert = 1;
Iain Barnes0ddae8f2002-06-21 17:35:55 +000066 break;
Harald Welte487d1d32002-03-14 12:22:06 +000067 }
Harald Welte487d1d32002-03-14 12:22:06 +000068}
69
Jan Engelhardt72c35972011-03-01 20:28:24 +010070static void dscp_check(struct xt_fcheck_call *cb)
Harald Welte487d1d32002-03-14 12:22:06 +000071{
Jan Engelhardt72c35972011-03-01 20:28:24 +010072 if (cb->xflags == 0)
Jan Engelhardt1829ed42009-02-21 03:29:44 +010073 xtables_error(PARAMETER_PROBLEM,
Harald Welte487d1d32002-03-14 12:22:06 +000074 "DSCP match: Parameter --dscp is required");
75}
76
77static void
Jan Engelhardt181dead2007-10-04 16:27:07 +000078dscp_print(const void *ip, const struct xt_entry_match *match, int numeric)
Harald Welte487d1d32002-03-14 12:22:06 +000079{
Yasuyuki KOZAKAI18e06082007-07-24 07:17:23 +000080 const struct xt_dscp_info *dinfo =
81 (const struct xt_dscp_info *)match->data;
Jan Engelhardt73866352010-12-18 02:04:59 +010082 printf(" DSCP match %s0x%02x", dinfo->invert ? "!" : "", dinfo->dscp);
Harald Welte487d1d32002-03-14 12:22:06 +000083}
84
Jan Engelhardt181dead2007-10-04 16:27:07 +000085static void dscp_save(const void *ip, const struct xt_entry_match *match)
Harald Welte487d1d32002-03-14 12:22:06 +000086{
Yasuyuki KOZAKAI18e06082007-07-24 07:17:23 +000087 const struct xt_dscp_info *dinfo =
88 (const struct xt_dscp_info *)match->data;
Harald Welte487d1d32002-03-14 12:22:06 +000089
Jan Engelhardt73866352010-12-18 02:04:59 +010090 printf("%s --dscp 0x%02x", dinfo->invert ? " !" : "", dinfo->dscp);
Harald Welte487d1d32002-03-14 12:22:06 +000091}
92
Jan Engelhardt181dead2007-10-04 16:27:07 +000093static struct xtables_match dscp_match = {
Jan Engelhardtc5e85732009-06-12 20:55:44 +020094 .family = NFPROTO_UNSPEC,
Yasuyuki KOZAKAI18e06082007-07-24 07:17:23 +000095 .name = "dscp",
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020096 .version = XTABLES_VERSION,
Yasuyuki KOZAKAI18e06082007-07-24 07:17:23 +000097 .size = XT_ALIGN(sizeof(struct xt_dscp_info)),
98 .userspacesize = XT_ALIGN(sizeof(struct xt_dscp_info)),
Jan Engelhardt181dead2007-10-04 16:27:07 +000099 .help = dscp_help,
Jan Engelhardt181dead2007-10-04 16:27:07 +0000100 .print = dscp_print,
101 .save = dscp_save,
Jan Engelhardt72c35972011-03-01 20:28:24 +0100102 .x6_parse = dscp_parse,
103 .x6_fcheck = dscp_check,
104 .x6_options = dscp_opts,
Harald Welte487d1d32002-03-14 12:22:06 +0000105};
106
107void _init(void)
108{
Jan Engelhardt181dead2007-10-04 16:27:07 +0000109 xtables_register_match(&dscp_match);
Harald Welte487d1d32002-03-14 12:22:06 +0000110}