blob: f8b5cb495bfda581f65d6788c9ad4005b90db80b [file] [log] [blame]
Marc Bouchere6869a82000-03-20 06:03:29 +00001/* Shared library add-on to iptables to add TOS matching support. */
2#include <stdio.h>
3#include <netdb.h>
4#include <string.h>
5#include <stdlib.h>
6#include <getopt.h>
7
8#include <iptables.h>
9#include <linux/netfilter_ipv4/ipt_tos.h>
10
11/* TOS names and values. */
Harald Welte3efb6ea2001-08-06 18:50:21 +000012static
Marc Bouchere6869a82000-03-20 06:03:29 +000013struct TOS_value
14{
15 unsigned char TOS;
16 const char *name;
17} TOS_values[] = {
18 { IPTOS_LOWDELAY, "Minimize-Delay" },
19 { IPTOS_THROUGHPUT, "Maximize-Throughput" },
20 { IPTOS_RELIABILITY, "Maximize-Reliability" },
21 { IPTOS_MINCOST, "Minimize-Cost" },
22 { IPTOS_NORMALSVC, "Normal-Service" },
23};
24
25/* Function which prints out usage message. */
26static void
27help(void)
28{
29 unsigned int i;
Rusty Russell7e53bf92000-03-20 07:03:28 +000030
Marc Bouchere6869a82000-03-20 06:03:29 +000031 printf(
32"TOS match v%s options:\n"
33"[!] --tos value Match Type of Service field from one of the\n"
34" following numeric or descriptive values:\n",
Harald Welte80fe35d2002-05-29 13:08:15 +000035IPTABLES_VERSION);
Marc Bouchere6869a82000-03-20 06:03:29 +000036
37 for (i = 0; i < sizeof(TOS_values)/sizeof(struct TOS_value);i++)
38 printf(" %s %u (0x%02x)\n",
39 TOS_values[i].name,
40 TOS_values[i].TOS,
41 TOS_values[i].TOS);
42 fputc('\n', stdout);
43}
44
45static struct option opts[] = {
46 { "tos", 1, 0, '1' },
47 {0}
48};
49
Marc Bouchere6869a82000-03-20 06:03:29 +000050static void
Harald Welteefa8fc22005-07-19 22:03:49 +000051parse_tos(const char *s, struct ipt_tos_info *info)
Marc Bouchere6869a82000-03-20 06:03:29 +000052{
53 unsigned int i;
Patrick McHardy2739cb82005-11-18 18:00:25 +000054 unsigned int tos;
Marc Bouchere6869a82000-03-20 06:03:29 +000055
Harald Welteb4719762001-07-23 02:14:22 +000056 if (string_to_number(s, 0, 255, &tos) != -1) {
Marc Bouchere6869a82000-03-20 06:03:29 +000057 if (tos == IPTOS_LOWDELAY
58 || tos == IPTOS_THROUGHPUT
59 || tos == IPTOS_RELIABILITY
60 || tos == IPTOS_MINCOST
61 || tos == IPTOS_NORMALSVC) {
62 info->tos = (u_int8_t )tos;
63 return;
64 }
65 } else {
66 for (i = 0; i<sizeof(TOS_values)/sizeof(struct TOS_value); i++)
67 if (strcasecmp(s,TOS_values[i].name) == 0) {
68 info->tos = TOS_values[i].TOS;
69 return;
70 }
71 }
72 exit_error(PARAMETER_PROBLEM, "Bad TOS value `%s'", s);
73}
74
75/* Function which parses command options; returns true if it
76 ate an option */
77static int
78parse(int c, char **argv, int invert, unsigned int *flags,
79 const struct ipt_entry *entry,
80 unsigned int *nfcache,
81 struct ipt_entry_match **match)
82{
83 struct ipt_tos_info *tosinfo = (struct ipt_tos_info *)(*match)->data;
84
85 switch (c) {
86 case '1':
Nicolas Bouliane0b46d1d2004-12-20 05:11:59 +000087 /* Ensure that `--tos' haven't been used yet. */
88 if (*flags == 1)
89 exit_error(PARAMETER_PROBLEM,
90 "tos match: only use --tos once!");
91
Harald Welteb77f1da2002-03-14 11:35:58 +000092 check_inverse(optarg, &invert, &optind, 0);
Marc Bouchere6869a82000-03-20 06:03:29 +000093 parse_tos(argv[optind-1], tosinfo);
94 if (invert)
95 tosinfo->invert = 1;
96 *flags = 1;
97 break;
98
99 default:
100 return 0;
101 }
102 return 1;
103}
104
105static void
Harald Welte96473592002-12-05 19:39:10 +0000106print_tos(u_int8_t tos, int numeric)
Marc Bouchere6869a82000-03-20 06:03:29 +0000107{
108 unsigned int i;
Rusty Russell7e53bf92000-03-20 07:03:28 +0000109
Marc Bouchere6869a82000-03-20 06:03:29 +0000110 if (!numeric) {
111 for (i = 0; i<sizeof(TOS_values)/sizeof(struct TOS_value); i++)
112 if (TOS_values[i].TOS == tos) {
113 printf("%s ", TOS_values[i].name);
114 return;
115 }
116 }
117 printf("0x%02x ", tos);
118}
119
120/* Final check; must have specified --tos. */
121static void
122final_check(unsigned int flags)
123{
124 if (!flags)
125 exit_error(PARAMETER_PROBLEM,
126 "TOS match: You must specify `--tos'");
127}
128
129/* Prints out the matchinfo. */
130static void
131print(const struct ipt_ip *ip,
132 const struct ipt_entry_match *match,
133 int numeric)
134{
Harald Welte96473592002-12-05 19:39:10 +0000135 const struct ipt_tos_info *info = (const struct ipt_tos_info *)match->data;
136
Marc Bouchere6869a82000-03-20 06:03:29 +0000137 printf("TOS match ");
Harald Welte96473592002-12-05 19:39:10 +0000138 if (info->invert)
139 printf("!");
140 print_tos(info->tos, numeric);
Marc Bouchere6869a82000-03-20 06:03:29 +0000141}
142
143/* Saves the union ipt_matchinfo in parsable form to stdout. */
144static void
145save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
146{
Harald Welte96473592002-12-05 19:39:10 +0000147 const struct ipt_tos_info *info = (const struct ipt_tos_info *)match->data;
148
149 if (info->invert)
150 printf("! ");
Marc Bouchere6869a82000-03-20 06:03:29 +0000151 printf("--tos ");
Harald Welte96473592002-12-05 19:39:10 +0000152 print_tos(info->tos, 0);
Marc Bouchere6869a82000-03-20 06:03:29 +0000153}
154
Pablo Neira8caee8b2004-12-28 13:11:59 +0000155static struct iptables_match tos = {
156 .next = NULL,
157 .name = "tos",
158 .version = IPTABLES_VERSION,
159 .size = IPT_ALIGN(sizeof(struct ipt_tos_info)),
160 .userspacesize = IPT_ALIGN(sizeof(struct ipt_tos_info)),
161 .help = &help,
Pablo Neira8caee8b2004-12-28 13:11:59 +0000162 .parse = &parse,
163 .final_check = &final_check,
164 .print = &print,
165 .save = &save,
166 .extra_opts = opts
Marc Bouchere6869a82000-03-20 06:03:29 +0000167};
168
169void _init(void)
170{
171 register_match(&tos);
172}