iptables-1.2.9-2.3.1.src.rpm
[iptables.git] / extensions / libipt_tos.c
1 /* 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. */
12 static
13 struct 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. */
26 static void
27 help(void)
28 {
29         unsigned int i;
30
31         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",
35 IPTABLES_VERSION);
36
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
45 static struct option opts[] = {
46         { "tos", 1, 0, '1' },
47         {0}
48 };
49
50 /* Initialize the match. */
51 static void
52 init(struct ipt_entry_match *m, unsigned int *nfcache)
53 {
54         *nfcache |= NFC_IP_TOS;
55 }
56
57 static void
58 parse_tos(const unsigned char *s, struct ipt_tos_info *info)
59 {
60         unsigned int i;
61         unsigned int tos;
62
63         if (string_to_number(s, 0, 255, &tos) != -1) {
64                 if (tos == IPTOS_LOWDELAY
65                     || tos == IPTOS_THROUGHPUT
66                     || tos == IPTOS_RELIABILITY
67                     || tos == IPTOS_MINCOST
68                     || tos == IPTOS_NORMALSVC) {
69                         info->tos = (u_int8_t )tos;
70                         return;
71                 }
72         } else {
73                 for (i = 0; i<sizeof(TOS_values)/sizeof(struct TOS_value); i++)
74                         if (strcasecmp(s,TOS_values[i].name) == 0) {
75                                 info->tos = TOS_values[i].TOS;
76                                 return;
77                         }
78         }
79         exit_error(PARAMETER_PROBLEM, "Bad TOS value `%s'", s);
80 }
81
82 /* Function which parses command options; returns true if it
83    ate an option */
84 static int
85 parse(int c, char **argv, int invert, unsigned int *flags,
86       const struct ipt_entry *entry,
87       unsigned int *nfcache,
88       struct ipt_entry_match **match)
89 {
90         struct ipt_tos_info *tosinfo = (struct ipt_tos_info *)(*match)->data;
91
92         switch (c) {
93         case '1':
94                 check_inverse(optarg, &invert, &optind, 0);
95                 parse_tos(argv[optind-1], tosinfo);
96                 if (invert)
97                         tosinfo->invert = 1;
98                 *flags = 1;
99                 break;
100
101         default:
102                 return 0;
103         }
104         return 1;
105 }
106
107 static void
108 print_tos(u_int8_t tos, int numeric)
109 {
110         unsigned int i;
111
112         if (!numeric) {
113                 for (i = 0; i<sizeof(TOS_values)/sizeof(struct TOS_value); i++)
114                         if (TOS_values[i].TOS == tos) {
115                                 printf("%s ", TOS_values[i].name);
116                                 return;
117                         }
118         }
119         printf("0x%02x ", tos);
120 }
121
122 /* Final check; must have specified --tos. */
123 static void
124 final_check(unsigned int flags)
125 {
126         if (!flags)
127                 exit_error(PARAMETER_PROBLEM,
128                            "TOS match: You must specify `--tos'");
129 }
130
131 /* Prints out the matchinfo. */
132 static void
133 print(const struct ipt_ip *ip,
134       const struct ipt_entry_match *match,
135       int numeric)
136 {
137         const struct ipt_tos_info *info = (const struct ipt_tos_info *)match->data;
138     
139         printf("TOS match ");
140         if (info->invert)
141                 printf("!");
142         print_tos(info->tos, numeric);
143 }
144
145 /* Saves the union ipt_matchinfo in parsable form to stdout. */
146 static void
147 save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
148 {
149         const struct ipt_tos_info *info = (const struct ipt_tos_info *)match->data;
150     
151         if (info->invert)
152                 printf("! ");
153         printf("--tos ");
154         print_tos(info->tos, 0);
155 }
156
157 static
158 struct iptables_match tos
159 = { NULL,
160     "tos",
161     IPTABLES_VERSION,
162     IPT_ALIGN(sizeof(struct ipt_tos_info)),
163     IPT_ALIGN(sizeof(struct ipt_tos_info)),
164     &help,
165     &init,
166     &parse,
167     &final_check,
168     &print,
169     &save,
170     opts
171 };
172
173 void _init(void)
174 {
175         register_match(&tos);
176 }