xref: /aosp_15_r20/external/iptables/extensions/libxt_DSCP.c (revision a71a954618bbadd4a345637e5edcf36eec826889)
1*a71a9546SAutomerger Merge Worker /* Shared library add-on to iptables for DSCP
2*a71a9546SAutomerger Merge Worker  *
3*a71a9546SAutomerger Merge Worker  * (C) 2000- 2002 by Matthew G. Marsh <[email protected]>,
4*a71a9546SAutomerger Merge Worker  * 		     Harald Welte <[email protected]>
5*a71a9546SAutomerger Merge Worker  *
6*a71a9546SAutomerger Merge Worker  * This program is distributed under the terms of GNU GPL v2, 1991
7*a71a9546SAutomerger Merge Worker  *
8*a71a9546SAutomerger Merge Worker  * libipt_DSCP.c borrowed heavily from libipt_TOS.c
9*a71a9546SAutomerger Merge Worker  *
10*a71a9546SAutomerger Merge Worker  * --set-class added by Iain Barnes
11*a71a9546SAutomerger Merge Worker  */
12*a71a9546SAutomerger Merge Worker #include <stdio.h>
13*a71a9546SAutomerger Merge Worker #include <string.h>
14*a71a9546SAutomerger Merge Worker #include <xtables.h>
15*a71a9546SAutomerger Merge Worker #include <linux/netfilter/xt_DSCP.h>
16*a71a9546SAutomerger Merge Worker 
17*a71a9546SAutomerger Merge Worker /* This is evil, but it's my code - HW*/
18*a71a9546SAutomerger Merge Worker #include "dscp_helper.c"
19*a71a9546SAutomerger Merge Worker 
20*a71a9546SAutomerger Merge Worker enum {
21*a71a9546SAutomerger Merge Worker 	O_SET_DSCP = 0,
22*a71a9546SAutomerger Merge Worker 	O_SET_DSCP_CLASS,
23*a71a9546SAutomerger Merge Worker 	F_SET_DSCP       = 1 << O_SET_DSCP,
24*a71a9546SAutomerger Merge Worker 	F_SET_DSCP_CLASS = 1 << O_SET_DSCP_CLASS,
25*a71a9546SAutomerger Merge Worker };
26*a71a9546SAutomerger Merge Worker 
DSCP_help(void)27*a71a9546SAutomerger Merge Worker static void DSCP_help(void)
28*a71a9546SAutomerger Merge Worker {
29*a71a9546SAutomerger Merge Worker 	printf(
30*a71a9546SAutomerger Merge Worker "DSCP target options\n"
31*a71a9546SAutomerger Merge Worker "  --set-dscp value		Set DSCP field in packet header to value\n"
32*a71a9546SAutomerger Merge Worker "  		                This value can be in decimal (ex: 32)\n"
33*a71a9546SAutomerger Merge Worker "               		or in hex (ex: 0x20)\n"
34*a71a9546SAutomerger Merge Worker "  --set-dscp-class class	Set the DSCP field in packet header to the\n"
35*a71a9546SAutomerger Merge Worker "				value represented by the DiffServ class value.\n"
36*a71a9546SAutomerger Merge Worker "				This class may be EF,BE or any of the CSxx\n"
37*a71a9546SAutomerger Merge Worker "				or AFxx classes.\n"
38*a71a9546SAutomerger Merge Worker "\n"
39*a71a9546SAutomerger Merge Worker "				These two options are mutually exclusive !\n"
40*a71a9546SAutomerger Merge Worker );
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 = "set-dscp", .id = O_SET_DSCP, .excl = F_SET_DSCP_CLASS,
45*a71a9546SAutomerger Merge Worker 	 .type = XTTYPE_UINT8, .min = 0, .max = XT_DSCP_MAX,
46*a71a9546SAutomerger Merge Worker 	 .flags = XTOPT_PUT,
47*a71a9546SAutomerger Merge Worker 	 XTOPT_POINTER(struct xt_DSCP_info, dscp)},
48*a71a9546SAutomerger Merge Worker 	{.name = "set-dscp-class", .id = O_SET_DSCP_CLASS, .excl = F_SET_DSCP,
49*a71a9546SAutomerger Merge Worker 	 .type = XTTYPE_STRING},
50*a71a9546SAutomerger Merge Worker 	XTOPT_TABLEEND,
51*a71a9546SAutomerger Merge Worker };
52*a71a9546SAutomerger Merge Worker 
DSCP_parse(struct xt_option_call * cb)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_SET_DSCP_CLASS:
60*a71a9546SAutomerger Merge Worker 		dinfo->dscp = class_to_dscp(cb->arg);
61*a71a9546SAutomerger Merge Worker 		break;
62*a71a9546SAutomerger Merge Worker 	}
63*a71a9546SAutomerger Merge Worker }
64*a71a9546SAutomerger Merge Worker 
DSCP_check(struct xt_fcheck_call * cb)65*a71a9546SAutomerger Merge Worker static void DSCP_check(struct xt_fcheck_call *cb)
66*a71a9546SAutomerger Merge Worker {
67*a71a9546SAutomerger Merge Worker 	if (cb->xflags == 0)
68*a71a9546SAutomerger Merge Worker 		xtables_error(PARAMETER_PROBLEM,
69*a71a9546SAutomerger Merge Worker 		           "DSCP target: Parameter --set-dscp is required");
70*a71a9546SAutomerger Merge Worker }
71*a71a9546SAutomerger Merge Worker 
72*a71a9546SAutomerger Merge Worker static void
print_dscp(uint8_t dscp,int numeric)73*a71a9546SAutomerger Merge Worker print_dscp(uint8_t dscp, int numeric)
74*a71a9546SAutomerger Merge Worker {
75*a71a9546SAutomerger Merge Worker 	printf(" 0x%02x", dscp);
76*a71a9546SAutomerger Merge Worker }
77*a71a9546SAutomerger Merge Worker 
DSCP_print(const void * ip,const struct xt_entry_target * target,int numeric)78*a71a9546SAutomerger Merge Worker static void DSCP_print(const void *ip, const struct xt_entry_target *target,
79*a71a9546SAutomerger Merge Worker                        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 *)target->data;
83*a71a9546SAutomerger Merge Worker 	printf(" DSCP set");
84*a71a9546SAutomerger Merge Worker 	print_dscp(dinfo->dscp, numeric);
85*a71a9546SAutomerger Merge Worker }
86*a71a9546SAutomerger Merge Worker 
DSCP_save(const void * ip,const struct xt_entry_target * target)87*a71a9546SAutomerger Merge Worker static void DSCP_save(const void *ip, const struct xt_entry_target *target)
88*a71a9546SAutomerger Merge Worker {
89*a71a9546SAutomerger Merge Worker 	const struct xt_DSCP_info *dinfo =
90*a71a9546SAutomerger Merge Worker 		(const struct xt_DSCP_info *)target->data;
91*a71a9546SAutomerger Merge Worker 
92*a71a9546SAutomerger Merge Worker 	printf(" --set-dscp 0x%02x", dinfo->dscp);
93*a71a9546SAutomerger Merge Worker }
94*a71a9546SAutomerger Merge Worker 
95*a71a9546SAutomerger Merge Worker 
DSCP_xlate(struct xt_xlate * xl,const struct xt_xlate_tg_params * params)96*a71a9546SAutomerger Merge Worker static int DSCP_xlate(struct xt_xlate *xl,
97*a71a9546SAutomerger Merge Worker 		      const struct xt_xlate_tg_params *params)
98*a71a9546SAutomerger Merge Worker {
99*a71a9546SAutomerger Merge Worker 	const struct xt_DSCP_info *dinfo =
100*a71a9546SAutomerger Merge Worker 		(struct xt_DSCP_info *)params->target->data;
101*a71a9546SAutomerger Merge Worker 
102*a71a9546SAutomerger Merge Worker 	xt_xlate_add(xl, "ip dscp set 0x%02x", dinfo->dscp);
103*a71a9546SAutomerger Merge Worker 	return 1;
104*a71a9546SAutomerger Merge Worker }
105*a71a9546SAutomerger Merge Worker 
DSCP_xlate6(struct xt_xlate * xl,const struct xt_xlate_tg_params * params)106*a71a9546SAutomerger Merge Worker static int DSCP_xlate6(struct xt_xlate *xl,
107*a71a9546SAutomerger Merge Worker 		       const struct xt_xlate_tg_params *params)
108*a71a9546SAutomerger Merge Worker {
109*a71a9546SAutomerger Merge Worker 	const struct xt_DSCP_info *dinfo =
110*a71a9546SAutomerger Merge Worker 		(struct xt_DSCP_info *)params->target->data;
111*a71a9546SAutomerger Merge Worker 
112*a71a9546SAutomerger Merge Worker 	xt_xlate_add(xl, "ip6 dscp set 0x%02x", dinfo->dscp);
113*a71a9546SAutomerger Merge Worker 	return 1;
114*a71a9546SAutomerger Merge Worker }
115*a71a9546SAutomerger Merge Worker 
116*a71a9546SAutomerger Merge Worker static struct xtables_target dscp_target[] = {
117*a71a9546SAutomerger Merge Worker 	{
118*a71a9546SAutomerger Merge Worker 		.family		= NFPROTO_IPV4,
119*a71a9546SAutomerger Merge Worker 		.name		= "DSCP",
120*a71a9546SAutomerger Merge Worker 		.version	= XTABLES_VERSION,
121*a71a9546SAutomerger Merge Worker 		.size		= XT_ALIGN(sizeof(struct xt_DSCP_info)),
122*a71a9546SAutomerger Merge Worker 		.userspacesize	= XT_ALIGN(sizeof(struct xt_DSCP_info)),
123*a71a9546SAutomerger Merge Worker 		.help		= DSCP_help,
124*a71a9546SAutomerger Merge Worker 		.print		= DSCP_print,
125*a71a9546SAutomerger Merge Worker 		.save		= DSCP_save,
126*a71a9546SAutomerger Merge Worker 		.x6_parse	= DSCP_parse,
127*a71a9546SAutomerger Merge Worker 		.x6_fcheck	= DSCP_check,
128*a71a9546SAutomerger Merge Worker 		.x6_options	= DSCP_opts,
129*a71a9546SAutomerger Merge Worker 		.xlate		= DSCP_xlate,
130*a71a9546SAutomerger Merge Worker 	},
131*a71a9546SAutomerger Merge Worker 	{
132*a71a9546SAutomerger Merge Worker 		.family		= NFPROTO_IPV6,
133*a71a9546SAutomerger Merge Worker 		.name		= "DSCP",
134*a71a9546SAutomerger Merge Worker 		.version	= XTABLES_VERSION,
135*a71a9546SAutomerger Merge Worker 		.size		= XT_ALIGN(sizeof(struct xt_DSCP_info)),
136*a71a9546SAutomerger Merge Worker 		.userspacesize	= XT_ALIGN(sizeof(struct xt_DSCP_info)),
137*a71a9546SAutomerger Merge Worker 		.help		= DSCP_help,
138*a71a9546SAutomerger Merge Worker 		.print		= DSCP_print,
139*a71a9546SAutomerger Merge Worker 		.save		= DSCP_save,
140*a71a9546SAutomerger Merge Worker 		.x6_parse	= DSCP_parse,
141*a71a9546SAutomerger Merge Worker 		.x6_fcheck	= DSCP_check,
142*a71a9546SAutomerger Merge Worker 		.x6_options	= DSCP_opts,
143*a71a9546SAutomerger Merge Worker 		.xlate		= DSCP_xlate6,
144*a71a9546SAutomerger Merge Worker 	},
145*a71a9546SAutomerger Merge Worker };
146*a71a9546SAutomerger Merge Worker 
_init(void)147*a71a9546SAutomerger Merge Worker void _init(void)
148*a71a9546SAutomerger Merge Worker {
149*a71a9546SAutomerger Merge Worker 	xtables_register_targets(dscp_target, ARRAY_SIZE(dscp_target));
150*a71a9546SAutomerger Merge Worker }
151