1487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte/* Shared library add-on to iptables for DSCP
2487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte *
3487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte * (C) 2002 by Harald Welte <laforge@gnumonks.org>
4487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte *
5487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte * This program is distributed under the terms of GNU GPL v2, 1991
6487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte *
7487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte * libipt_dscp.c borrowed heavily from libipt_tos.c
8487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte *
90ddae8f8ade1084c38a1408d61b6a16725912283Iain Barnes * --class support added by Iain Barnes
100ddae8f8ade1084c38a1408d61b6a16725912283Iain Barnes *
11487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte * For a list of DSCP codepoints see
12487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte * http://www.iana.org/assignments/dscp-registry
13487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte *
14487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte */
15487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte#include <stdio.h>
16487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte#include <string.h>
1718e060822be3ad17368dbe3d7289dd21efd341a5Yasuyuki KOZAKAI#include <xtables.h>
1818e060822be3ad17368dbe3d7289dd21efd341a5Yasuyuki KOZAKAI#include <linux/netfilter/xt_dscp.h>
19487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte
200ddae8f8ade1084c38a1408d61b6a16725912283Iain Barnes/* This is evil, but it's my code - HW*/
21f82070f9871d281c2802c1624dcf222886b5fb50Jan Engelhardt#include "dscp_helper.c"
220ddae8f8ade1084c38a1408d61b6a16725912283Iain Barnes
2372c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardtenum {
2472c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt	O_DSCP = 0,
2572c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt	O_DSCP_CLASS,
2672c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt	F_DSCP       = 1 << O_DSCP,
2772c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt	F_DSCP_CLASS = 1 << O_DSCP_CLASS,
2872c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt};
2972c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt
30181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void dscp_help(void)
31487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte{
32487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte	printf(
338b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"dscp match options\n"
34487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte"[!] --dscp value		Match DSCP codepoint with numerical value\n"
35487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte"  		                This value can be in decimal (ex: 32)\n"
360ddae8f8ade1084c38a1408d61b6a16725912283Iain Barnes"               		or in hex (ex: 0x20)\n"
37a49ded0aced6e22e4fcc7a6463e0366e05550b37Harald Welte"[!] --dscp-class name		Match the DiffServ class. This value may\n"
380ddae8f8ade1084c38a1408d61b6a16725912283Iain Barnes"				be any of the BE,EF, AFxx or CSx classes\n"
390ddae8f8ade1084c38a1408d61b6a16725912283Iain Barnes"\n"
408b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"				These two options are mutually exclusive !\n");
41487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte}
42487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte
4372c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardtstatic const struct xt_option_entry dscp_opts[] = {
4472c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt	{.name = "dscp", .id = O_DSCP, .excl = F_DSCP_CLASS,
4572c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt	 .type = XTTYPE_UINT8, .min = 0, .max = XT_DSCP_MAX,
4683c342b36a7048ab86827e09a4916064837293d3Jan Engelhardt	 .flags = XTOPT_INVERT | XTOPT_PUT,
4783c342b36a7048ab86827e09a4916064837293d3Jan Engelhardt	 XTOPT_POINTER(struct xt_dscp_info, dscp)},
4872c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt	{.name = "dscp-class", .id = O_DSCP_CLASS, .excl = F_DSCP,
4983c342b36a7048ab86827e09a4916064837293d3Jan Engelhardt	 .type = XTTYPE_STRING, .flags = XTOPT_INVERT},
5072c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt	XTOPT_TABLEEND,
51487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte};
52487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte
5372c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardtstatic void dscp_parse(struct xt_option_call *cb)
54487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte{
5572c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt	struct xt_dscp_info *dinfo = cb->data;
56487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte
5772c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt	xtables_option_parse(cb);
5872c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt	switch (cb->entry->id) {
5972c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt	case O_DSCP:
6072c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt		if (cb->invert)
61487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte			dinfo->invert = 1;
62487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte		break;
6372c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt	case O_DSCP_CLASS:
6472c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt		dinfo->dscp = class_to_dscp(cb->arg);
6572c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt		if (cb->invert)
660ddae8f8ade1084c38a1408d61b6a16725912283Iain Barnes			dinfo->invert = 1;
670ddae8f8ade1084c38a1408d61b6a16725912283Iain Barnes		break;
68487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte	}
69487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte}
70487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte
7172c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardtstatic void dscp_check(struct xt_fcheck_call *cb)
72487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte{
7372c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt	if (cb->xflags == 0)
741829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM,
75487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte		           "DSCP match: Parameter --dscp is required");
76487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte}
77487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte
78487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Weltestatic void
79181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtdscp_print(const void *ip, const struct xt_entry_match *match, int numeric)
80487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte{
8118e060822be3ad17368dbe3d7289dd21efd341a5Yasuyuki KOZAKAI	const struct xt_dscp_info *dinfo =
8218e060822be3ad17368dbe3d7289dd21efd341a5Yasuyuki KOZAKAI		(const struct xt_dscp_info *)match->data;
8373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" DSCP match %s0x%02x", dinfo->invert ? "!" : "", dinfo->dscp);
84487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte}
85487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte
86181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void dscp_save(const void *ip, const struct xt_entry_match *match)
87487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte{
8818e060822be3ad17368dbe3d7289dd21efd341a5Yasuyuki KOZAKAI	const struct xt_dscp_info *dinfo =
8918e060822be3ad17368dbe3d7289dd21efd341a5Yasuyuki KOZAKAI		(const struct xt_dscp_info *)match->data;
90487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte
9173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf("%s --dscp 0x%02x", dinfo->invert ? " !" : "", dinfo->dscp);
92487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte}
93487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte
94181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic struct xtables_match dscp_match = {
95c5e85736c207f211d82d2878a5781f512327dfceJan Engelhardt	.family		= NFPROTO_UNSPEC,
9618e060822be3ad17368dbe3d7289dd21efd341a5Yasuyuki KOZAKAI	.name 		= "dscp",
978b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.version 	= XTABLES_VERSION,
9818e060822be3ad17368dbe3d7289dd21efd341a5Yasuyuki KOZAKAI	.size 		= XT_ALIGN(sizeof(struct xt_dscp_info)),
9918e060822be3ad17368dbe3d7289dd21efd341a5Yasuyuki KOZAKAI	.userspacesize	= XT_ALIGN(sizeof(struct xt_dscp_info)),
100181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.help		= dscp_help,
101181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.print		= dscp_print,
102181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.save		= dscp_save,
10372c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt	.x6_parse	= dscp_parse,
10472c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt	.x6_fcheck	= dscp_check,
10572c359784a03b1ea46a9964e5c1f8636a52507ddJan Engelhardt	.x6_options	= dscp_opts,
106487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte};
107487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte
108487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Weltevoid _init(void)
109487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte{
110181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	xtables_register_match(&dscp_match);
111487d1d39b6457a4a3aeb2b9dac3b1925a003a3e1Harald Welte}
112