blob: 12fa4cb4c2c5fed30fa8e86ea025aedf50f12d42 [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 *
10 */
11#include <stdio.h>
12#include <string.h>
13#include <stdlib.h>
14#include <getopt.h>
15
16#include <iptables.h>
17#include <linux/netfilter_ipv4/ip_tables.h>
18#include <linux/netfilter_ipv4/ipt_DSCP.h>
19
Harald Welte2e7377d2002-02-17 19:54:42 +000020static void init(struct ipt_entry_target *t, unsigned int *nfcache)
21{
22}
23
24static void help(void)
25{
26 printf(
27"DSCP target options\n"
28" --set-dscp value Set DSCP field in packet header to value\n"
29" This value can be in decimal (ex: 32)\n"
30" or in hex (ex: 0x20)\n"
31);
32}
33
34static struct option opts[] = {
35 { "set-dscp", 1, 0, 'F' },
36 { 0 }
37};
38
39static void
Harald Welteed18bad2002-02-17 21:28:51 +000040parse_dscp(const unsigned char *s, struct ipt_DSCP_info *dinfo)
Harald Welte2e7377d2002-02-17 19:54:42 +000041{
42 unsigned int dscp;
43
44 if (string_to_number(s, 0, 255, &dscp) == -1)
45 exit_error(PARAMETER_PROBLEM,
46 "Invalid dscp `%s'\n", s);
47
Harald Welteed18bad2002-02-17 21:28:51 +000048 if (dscp > IPT_DSCP_MAX)
Harald Welte2e7377d2002-02-17 19:54:42 +000049 exit_error(PARAMETER_PROBLEM,
50 "DSCP `%d` out of range\n", dscp);
51
Harald Welteed18bad2002-02-17 21:28:51 +000052 dinfo->dscp = (u_int8_t )dscp;
Harald Welte2e7377d2002-02-17 19:54:42 +000053 return;
54}
55
56static int
57parse(int c, char **argv, int invert, unsigned int *flags,
58 const struct ipt_entry *entry,
59 struct ipt_entry_target **target)
60{
Harald Welteed18bad2002-02-17 21:28:51 +000061 struct ipt_DSCP_info *dinfo
Harald Welte2e7377d2002-02-17 19:54:42 +000062 = (struct ipt_DSCP_info *)(*target)->data;
63
64 switch (c) {
65 case 'F':
66 if (*flags)
67 exit_error(PARAMETER_PROBLEM,
68 "DSCP target: Only use --set-dscp ONCE!");
Harald Welteed18bad2002-02-17 21:28:51 +000069 parse_dscp(optarg, dinfo);
Harald Welte2e7377d2002-02-17 19:54:42 +000070 *flags = 1;
71 break;
72
73 default:
74 return 0;
75 }
76
77 return 1;
78}
79
80static void
81final_check(unsigned int flags)
82{
83 if (!flags)
84 exit_error(PARAMETER_PROBLEM,
85 "DSCP target: Parameter --set-dscp is required");
86}
87
88static void
Harald Welteed18bad2002-02-17 21:28:51 +000089print_dscp(u_int8_t dscp, int numeric)
Harald Welte2e7377d2002-02-17 19:54:42 +000090{
91 printf("0x%02x ", dscp);
92}
93
94/* Prints out the targinfo. */
95static void
96print(const struct ipt_ip *ip,
97 const struct ipt_entry_target *target,
98 int numeric)
99{
Harald Welteed18bad2002-02-17 21:28:51 +0000100 const struct ipt_DSCP_info *dinfo =
Harald Welte2e7377d2002-02-17 19:54:42 +0000101 (const struct ipt_DSCP_info *)target->data;
102 printf("DSCP set ");
Harald Welteed18bad2002-02-17 21:28:51 +0000103 print_dscp(dinfo->dscp, numeric);
Harald Welte2e7377d2002-02-17 19:54:42 +0000104}
105
106/* Saves the union ipt_targinfo in parsable form to stdout. */
107static void
108save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
109{
Harald Welteed18bad2002-02-17 21:28:51 +0000110 const struct ipt_DSCP_info *dinfo =
Harald Welte2e7377d2002-02-17 19:54:42 +0000111 (const struct ipt_DSCP_info *)target->data;
112
Harald Welteed18bad2002-02-17 21:28:51 +0000113 printf("--set-dscp 0x%02x ", dinfo->dscp);
Harald Welte2e7377d2002-02-17 19:54:42 +0000114}
115
116static
117struct iptables_target dscp
118= { NULL,
119 "DSCP",
120 NETFILTER_VERSION,
121 IPT_ALIGN(sizeof(struct ipt_DSCP_info)),
122 IPT_ALIGN(sizeof(struct ipt_DSCP_info)),
123 &help,
124 &init,
125 &parse,
126 &final_check,
127 &print,
128 &save,
129 opts
130};
131
132void _init(void)
133{
134 register_target(&dscp);
135}