blob: ba4c5652784ff7b3485da72516dbf83984f56532 [file] [log] [blame]
Marc Bouchere6869a82000-03-20 06:03:29 +00001/* Shared library add-on to iptables to add TOS target support. */
2#include <stdio.h>
3#include <string.h>
4#include <stdlib.h>
5#include <getopt.h>
6
7#include <iptables.h>
8#include <linux/netfilter_ipv4/ip_tables.h>
9#include <linux/netfilter_ipv4/ipt_TOS.h>
10
11struct tosinfo {
Yasuyuki KOZAKAI193df8e2007-07-24 05:57:28 +000012 struct xt_entry_target t;
Marc Bouchere6869a82000-03-20 06:03:29 +000013 struct ipt_tos_target_info tos;
14};
15
16/* TOS names and values. */
Jan Engelhardt661f1122007-07-30 14:46:51 +000017static const
Marc Bouchere6869a82000-03-20 06:03:29 +000018struct TOS_value
19{
20 unsigned char TOS;
21 const char *name;
22} TOS_values[] = {
23 { IPTOS_LOWDELAY, "Minimize-Delay" },
24 { IPTOS_THROUGHPUT, "Maximize-Throughput" },
25 { IPTOS_RELIABILITY, "Maximize-Reliability" },
26 { IPTOS_MINCOST, "Minimize-Cost" },
27 { IPTOS_NORMALSVC, "Normal-Service" },
28};
29
30/* Function which prints out usage message. */
31static void
32help(void)
33{
34 unsigned int i;
Rusty Russell7e53bf92000-03-20 07:03:28 +000035
Marc Bouchere6869a82000-03-20 06:03:29 +000036 printf(
37"TOS target v%s options:\n"
38" --set-tos value Set Type of Service field to one of the\n"
39" following numeric or descriptive values:\n",
Harald Welte80fe35d2002-05-29 13:08:15 +000040IPTABLES_VERSION);
Marc Bouchere6869a82000-03-20 06:03:29 +000041
42 for (i = 0; i < sizeof(TOS_values)/sizeof(struct TOS_value);i++)
43 printf(" %s %u (0x%02x)\n",
44 TOS_values[i].name,
45 TOS_values[i].TOS,
46 TOS_values[i].TOS);
47 fputc('\n', stdout);
48}
49
Jan Engelhardt661f1122007-07-30 14:46:51 +000050static const struct option opts[] = {
Marc Bouchere6869a82000-03-20 06:03:29 +000051 { "set-tos", 1, 0, '1' },
52 { 0 }
53};
54
55/* Initialize the target. */
56static void
Peter Rileyea146a92007-09-02 13:09:07 +000057init(struct xt_entry_target *t)
Marc Bouchere6869a82000-03-20 06:03:29 +000058{
59}
60
61static void
Harald Welteefa8fc22005-07-19 22:03:49 +000062parse_tos(const char *s, struct ipt_tos_target_info *info)
Marc Bouchere6869a82000-03-20 06:03:29 +000063{
Harald Welteb4719762001-07-23 02:14:22 +000064 unsigned int i, tos;
Marc Bouchere6869a82000-03-20 06:03:29 +000065
Marc Boucher459357f2001-09-08 02:16:51 +000066 if (string_to_number(s, 0, 255, &tos) != -1) {
Marc Bouchere6869a82000-03-20 06:03:29 +000067 if (tos == IPTOS_LOWDELAY
68 || tos == IPTOS_THROUGHPUT
69 || tos == IPTOS_RELIABILITY
70 || tos == IPTOS_MINCOST
71 || tos == IPTOS_NORMALSVC) {
72 info->tos = (u_int8_t )tos;
73 return;
74 }
75 } else {
76 for (i = 0; i<sizeof(TOS_values)/sizeof(struct TOS_value); i++)
77 if (strcasecmp(s,TOS_values[i].name) == 0) {
78 info->tos = TOS_values[i].TOS;
79 return;
80 }
81 }
82 exit_error(PARAMETER_PROBLEM, "Bad TOS value `%s'", s);
83}
84
85/* Function which parses command options; returns true if it
86 ate an option */
87static int
88parse(int c, char **argv, int invert, unsigned int *flags,
Yasuyuki KOZAKAIc0a9ab92007-07-24 06:02:05 +000089 const void *entry,
Yasuyuki KOZAKAI193df8e2007-07-24 05:57:28 +000090 struct xt_entry_target **target)
Marc Bouchere6869a82000-03-20 06:03:29 +000091{
92 struct ipt_tos_target_info *tosinfo
93 = (struct ipt_tos_target_info *)(*target)->data;
94
95 switch (c) {
96 case '1':
97 if (*flags)
98 exit_error(PARAMETER_PROBLEM,
99 "TOS target: Cant specify --set-tos twice");
100 parse_tos(optarg, tosinfo);
101 *flags = 1;
102 break;
Rusty Russell7e53bf92000-03-20 07:03:28 +0000103
Marc Bouchere6869a82000-03-20 06:03:29 +0000104 default:
105 return 0;
106 }
107
108 return 1;
109}
110
111static void
112final_check(unsigned int flags)
113{
114 if (!flags)
115 exit_error(PARAMETER_PROBLEM,
116 "TOS target: Parameter --set-tos is required");
117}
118
119static void
120print_tos(u_int8_t tos, int numeric)
121{
122 unsigned int i;
Rusty Russell7e53bf92000-03-20 07:03:28 +0000123
Marc Bouchere6869a82000-03-20 06:03:29 +0000124 if (!numeric) {
125 for (i = 0; i<sizeof(TOS_values)/sizeof(struct TOS_value); i++)
126 if (TOS_values[i].TOS == tos) {
127 printf("%s ", TOS_values[i].name);
128 return;
129 }
130 }
131 printf("0x%02x ", tos);
132}
133
134/* Prints out the targinfo. */
135static void
Yasuyuki KOZAKAIc0a9ab92007-07-24 06:02:05 +0000136print(const void *ip,
Yasuyuki KOZAKAI193df8e2007-07-24 05:57:28 +0000137 const struct xt_entry_target *target,
Marc Bouchere6869a82000-03-20 06:03:29 +0000138 int numeric)
139{
140 const struct ipt_tos_target_info *tosinfo =
141 (const struct ipt_tos_target_info *)target->data;
142 printf("TOS set ");
Rusty Russell7e53bf92000-03-20 07:03:28 +0000143 print_tos(tosinfo->tos, numeric);
Marc Bouchere6869a82000-03-20 06:03:29 +0000144}
145
146/* Saves the union ipt_targinfo in parsable form to stdout. */
147static void
Yasuyuki KOZAKAIc0a9ab92007-07-24 06:02:05 +0000148save(const void *ip, const struct xt_entry_target *target)
Marc Bouchere6869a82000-03-20 06:03:29 +0000149{
150 const struct ipt_tos_target_info *tosinfo =
151 (const struct ipt_tos_target_info *)target->data;
Rusty Russell7e53bf92000-03-20 07:03:28 +0000152
153 printf("--set-tos 0x%02x ", tosinfo->tos);
Marc Bouchere6869a82000-03-20 06:03:29 +0000154}
155
Pablo Neira8caee8b2004-12-28 13:11:59 +0000156static struct iptables_target tos = {
Pablo Neira8caee8b2004-12-28 13:11:59 +0000157 .name = "TOS",
158 .version = IPTABLES_VERSION,
159 .size = IPT_ALIGN(sizeof(struct ipt_tos_target_info)),
160 .userspacesize = IPT_ALIGN(sizeof(struct ipt_tos_target_info)),
161 .help = &help,
162 .init = &init,
163 .parse = &parse,
164 .final_check = &final_check,
165 .print = &print,
166 .save = &save,
167 .extra_opts = opts
Marc Bouchere6869a82000-03-20 06:03:29 +0000168};
169
170void _init(void)
171{
172 register_target(&tos);
173}