blob: e16e93c4492af216d1ab9d50bbb5f88e9084049e [file] [log] [blame]
Harald Welte2e7377d2002-02-17 19:54:42 +00001/* 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 *
Iain Barnesdf5e13f2002-04-11 10:48:53 +000010 * --set-class added by Iain Barnes
Harald Welte2e7377d2002-02-17 19:54:42 +000011 */
12#include <stdio.h>
13#include <string.h>
Yasuyuki KOZAKAIa7bf6d02007-08-04 08:24:29 +000014#include <xtables.h>
Yasuyuki KOZAKAIa7bf6d02007-08-04 08:24:29 +000015#include <linux/netfilter/xt_DSCP.h>
Harald Welte2e7377d2002-02-17 19:54:42 +000016
Iain Barnes0ddae8f2002-06-21 17:35:55 +000017/* This is evil, but it's my code - HW*/
Jan Engelhardtf82070f2008-01-20 13:14:00 +000018#include "dscp_helper.c"
Iain Barnesdf5e13f2002-04-11 10:48:53 +000019
Jan Engelhardt72c35972011-03-01 20:28:24 +010020enum {
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
Jan Engelhardt932e6482007-10-04 16:27:30 +000027static void DSCP_help(void)
Harald Welte2e7377d2002-02-17 19:54:42 +000028{
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"
Harald Weltea49ded02002-08-07 09:55:37 +000034" --set-dscp-class class Set the DSCP field in packet header to the\n"
35" value represented by the DiffServ class value.\n"
Maciej Soltysiak920463d2004-03-04 00:14:03 +000036" This class may be EF,BE or any of the CSxx\n"
Iain Barnesdf5e13f2002-04-11 10:48:53 +000037" or AFxx classes.\n"
38"\n"
39" These two options are mutually exclusive !\n"
Harald Welte2e7377d2002-02-17 19:54:42 +000040);
41}
42
Jan Engelhardt72c35972011-03-01 20:28:24 +010043static 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,
Harald Welte2e7377d2002-02-17 19:54:42 +000051};
52
Jan Engelhardt72c35972011-03-01 20:28:24 +010053static void DSCP_parse(struct xt_option_call *cb)
Harald Welte2e7377d2002-02-17 19:54:42 +000054{
Jan Engelhardt72c35972011-03-01 20:28:24 +010055 struct xt_DSCP_info *dinfo = cb->data;
Harald Welte2e7377d2002-02-17 19:54:42 +000056
Jan Engelhardt72c35972011-03-01 20:28:24 +010057 xtables_option_parse(cb);
58 switch (cb->entry->id) {
59 case O_SET_DSCP_CLASS:
60 dinfo->dscp = class_to_dscp(cb->arg);
Iain Barnesdf5e13f2002-04-11 10:48:53 +000061 break;
Harald Welte2e7377d2002-02-17 19:54:42 +000062 }
Harald Welte2e7377d2002-02-17 19:54:42 +000063}
64
Jan Engelhardt72c35972011-03-01 20:28:24 +010065static void DSCP_check(struct xt_fcheck_call *cb)
Harald Welte2e7377d2002-02-17 19:54:42 +000066{
Jan Engelhardt72c35972011-03-01 20:28:24 +010067 if (cb->xflags == 0)
Jan Engelhardt1829ed42009-02-21 03:29:44 +010068 xtables_error(PARAMETER_PROBLEM,
Harald Welte2e7377d2002-02-17 19:54:42 +000069 "DSCP target: Parameter --set-dscp is required");
70}
71
72static void
Jan Engelhardt7ac40522011-01-07 12:34:04 +010073print_dscp(uint8_t dscp, int numeric)
Harald Welte2e7377d2002-02-17 19:54:42 +000074{
Jan Engelhardt73866352010-12-18 02:04:59 +010075 printf(" 0x%02x", dscp);
Harald Welte2e7377d2002-02-17 19:54:42 +000076}
77
Jan Engelhardt932e6482007-10-04 16:27:30 +000078static void DSCP_print(const void *ip, const struct xt_entry_target *target,
79 int numeric)
Harald Welte2e7377d2002-02-17 19:54:42 +000080{
Yasuyuki KOZAKAIa7bf6d02007-08-04 08:24:29 +000081 const struct xt_DSCP_info *dinfo =
82 (const struct xt_DSCP_info *)target->data;
Jan Engelhardt73866352010-12-18 02:04:59 +010083 printf(" DSCP set");
Harald Welteed18bad2002-02-17 21:28:51 +000084 print_dscp(dinfo->dscp, numeric);
Harald Welte2e7377d2002-02-17 19:54:42 +000085}
86
Jan Engelhardt932e6482007-10-04 16:27:30 +000087static void DSCP_save(const void *ip, const struct xt_entry_target *target)
Harald Welte2e7377d2002-02-17 19:54:42 +000088{
Yasuyuki KOZAKAIa7bf6d02007-08-04 08:24:29 +000089 const struct xt_DSCP_info *dinfo =
90 (const struct xt_DSCP_info *)target->data;
Harald Welte2e7377d2002-02-17 19:54:42 +000091
Jan Engelhardt73866352010-12-18 02:04:59 +010092 printf(" --set-dscp 0x%02x", dinfo->dscp);
Harald Welte2e7377d2002-02-17 19:54:42 +000093}
94
Jan Engelhardt932e6482007-10-04 16:27:30 +000095static struct xtables_target dscp_target = {
Jan Engelhardtc5e85732009-06-12 20:55:44 +020096 .family = NFPROTO_UNSPEC,
Yasuyuki KOZAKAIa7bf6d02007-08-04 08:24:29 +000097 .name = "DSCP",
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020098 .version = XTABLES_VERSION,
Yasuyuki KOZAKAIa7bf6d02007-08-04 08:24:29 +000099 .size = XT_ALIGN(sizeof(struct xt_DSCP_info)),
100 .userspacesize = XT_ALIGN(sizeof(struct xt_DSCP_info)),
Jan Engelhardt932e6482007-10-04 16:27:30 +0000101 .help = DSCP_help,
Jan Engelhardt932e6482007-10-04 16:27:30 +0000102 .print = DSCP_print,
103 .save = DSCP_save,
Jan Engelhardt72c35972011-03-01 20:28:24 +0100104 .x6_parse = DSCP_parse,
105 .x6_fcheck = DSCP_check,
106 .x6_options = DSCP_opts,
Harald Welte2e7377d2002-02-17 19:54:42 +0000107};
108
109void _init(void)
110{
Jan Engelhardt932e6482007-10-04 16:27:30 +0000111 xtables_register_target(&dscp_target);
Harald Welte2e7377d2002-02-17 19:54:42 +0000112}