libxt_DSCP.c revision 72c359784a03b1ea46a9964e5c1f8636a52507dd
1/* Shared library add-on to iptables for DSCP
2 *
3 * (C) 2000- 2002 by Matthew G. Marsh <mgm@paktronix.com>,
4 * 		     Harald Welte <laforge@gnumonks.org>
5 *
6 * This program is distributed under the terms of GNU GPL v2, 1991
7 *
8 * libipt_DSCP.c borrowed heavily from libipt_TOS.c
9 *
10 * --set-class added by Iain Barnes
11 */
12#include <stdio.h>
13#include <string.h>
14#include <xtables.h>
15#include <linux/netfilter/xt_DSCP.h>
16
17/* This is evil, but it's my code - HW*/
18#include "dscp_helper.c"
19
20enum {
21	O_SET_DSCP = 0,
22	O_SET_DSCP_CLASS,
23	F_SET_DSCP       = 1 << O_SET_DSCP,
24	F_SET_DSCP_CLASS = 1 << O_SET_DSCP_CLASS,
25};
26
27static void DSCP_help(void)
28{
29	printf(
30"DSCP target options\n"
31"  --set-dscp value		Set DSCP field in packet header to value\n"
32"  		                This value can be in decimal (ex: 32)\n"
33"               		or in hex (ex: 0x20)\n"
34"  --set-dscp-class class	Set the DSCP field in packet header to the\n"
35"				value represented by the DiffServ class value.\n"
36"				This class may be EF,BE or any of the CSxx\n"
37"				or AFxx classes.\n"
38"\n"
39"				These two options are mutually exclusive !\n"
40);
41}
42
43static const struct xt_option_entry DSCP_opts[] = {
44	{.name = "set-dscp", .id = O_SET_DSCP, .excl = F_SET_DSCP_CLASS,
45	 .type = XTTYPE_UINT8, .min = 0, .max = XT_DSCP_MAX,
46	 .flags = XTOPT_PUT,
47	 XTOPT_POINTER(struct xt_DSCP_info, dscp)},
48	{.name = "set-dscp-class", .id = O_SET_DSCP_CLASS, .excl = F_SET_DSCP,
49	 .type = XTTYPE_STRING},
50	XTOPT_TABLEEND,
51};
52
53static 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_SET_DSCP_CLASS:
60		dinfo->dscp = class_to_dscp(cb->arg);
61		break;
62	}
63}
64
65static void DSCP_check(struct xt_fcheck_call *cb)
66{
67	if (cb->xflags == 0)
68		xtables_error(PARAMETER_PROBLEM,
69		           "DSCP target: Parameter --set-dscp is required");
70}
71
72static void
73print_dscp(uint8_t dscp, int numeric)
74{
75	printf(" 0x%02x", dscp);
76}
77
78static void DSCP_print(const void *ip, const struct xt_entry_target *target,
79                       int numeric)
80{
81	const struct xt_DSCP_info *dinfo =
82		(const struct xt_DSCP_info *)target->data;
83	printf(" DSCP set");
84	print_dscp(dinfo->dscp, numeric);
85}
86
87static void DSCP_save(const void *ip, const struct xt_entry_target *target)
88{
89	const struct xt_DSCP_info *dinfo =
90		(const struct xt_DSCP_info *)target->data;
91
92	printf(" --set-dscp 0x%02x", dinfo->dscp);
93}
94
95static struct xtables_target dscp_target = {
96	.family		= NFPROTO_UNSPEC,
97	.name		= "DSCP",
98	.version	= XTABLES_VERSION,
99	.size		= XT_ALIGN(sizeof(struct xt_DSCP_info)),
100	.userspacesize	= XT_ALIGN(sizeof(struct xt_DSCP_info)),
101	.help		= DSCP_help,
102	.print		= DSCP_print,
103	.save		= DSCP_save,
104	.x6_parse	= DSCP_parse,
105	.x6_fcheck	= DSCP_check,
106	.x6_options	= DSCP_opts,
107};
108
109void _init(void)
110{
111	xtables_register_target(&dscp_target);
112}
113