Fork for IVI and add .changes file
[profile/ivi/iptables.git] / extensions / libxt_tos.c
1 /*
2  * Shared library add-on to iptables to add tos match support
3  *
4  * Copyright © CC Computer Consultants GmbH, 2007
5  * Contact: Jan Engelhardt <jengelh@computergmbh.de>
6  */
7 #include <getopt.h>
8 #include <netdb.h>
9 #include <stdbool.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 #include <xtables.h>
15 #include <linux/netfilter/xt_dscp.h>
16 #include "tos_values.c"
17
18 struct ipt_tos_info {
19         u_int8_t tos;
20         u_int8_t invert;
21 };
22
23 enum {
24         FLAG_TOS = 1 << 0,
25 };
26
27 static const struct option tos_mt_opts[] = {
28         {.name = "tos", .has_arg = true, .val = 't'},
29         { .name = NULL }
30 };
31
32 static void tos_mt_help(void)
33 {
34         const struct tos_symbol_info *symbol;
35
36         printf(
37 "tos match options:\n"
38 "[!] --tos value[/mask]    Match Type of Service/Priority field value\n"
39 "[!] --tos symbol          Match TOS field (IPv4 only) by symbol\n"
40 "                          Accepted symbolic names for value are:\n");
41
42         for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol)
43                 printf("                          (0x%02x) %2u %s\n",
44                        symbol->value, symbol->value, symbol->name);
45
46         printf("\n");
47 }
48
49 static int tos_mt_parse_v0(int c, char **argv, int invert, unsigned int *flags,
50                            const void *entry, struct xt_entry_match **match)
51 {
52         struct ipt_tos_info *info = (void *)(*match)->data;
53         struct tos_value_mask tvm;
54
55         switch (c) {
56         case 't':
57                 xtables_param_act(XTF_ONLY_ONCE, "tos", "--tos", *flags & FLAG_TOS);
58                 if (!tos_parse_symbolic(optarg, &tvm, 0xFF))
59                         xtables_param_act(XTF_BAD_VALUE, "tos", "--tos", optarg);
60                 if (tvm.mask != 0xFF)
61                         xtables_error(PARAMETER_PROBLEM, "tos: Your kernel is "
62                                    "too old to support anything besides /0xFF "
63                                    "as a mask.");
64                 info->tos = tvm.value;
65                 if (invert)
66                         info->invert = true;
67                 *flags |= FLAG_TOS;
68                 return true;
69         }
70         return false;
71 }
72
73 static int tos_mt_parse(int c, char **argv, int invert, unsigned int *flags,
74                         const void *entry, struct xt_entry_match **match)
75 {
76         struct xt_tos_match_info *info = (void *)(*match)->data;
77         struct tos_value_mask tvm = {.mask = 0xFF};
78
79         switch (c) {
80         case 't':
81                 xtables_param_act(XTF_ONLY_ONCE, "tos", "--tos", *flags & FLAG_TOS);
82                 if (!tos_parse_symbolic(optarg, &tvm, 0x3F))
83                         xtables_param_act(XTF_BAD_VALUE, "tos", "--tos", optarg);
84                 info->tos_value = tvm.value;
85                 info->tos_mask  = tvm.mask;
86                 if (invert)
87                         info->invert = true;
88                 *flags |= FLAG_TOS;
89                 return true;
90         }
91         return false;
92 }
93
94 static void tos_mt_check(unsigned int flags)
95 {
96         if (flags == 0)
97                 xtables_error(PARAMETER_PROBLEM,
98                            "tos: --tos parameter required");
99 }
100
101 static void tos_mt_print_v0(const void *ip, const struct xt_entry_match *match,
102                             int numeric)
103 {
104         const struct ipt_tos_info *info = (const void *)match->data;
105
106         printf("tos match ");
107         if (info->invert)
108                 printf("!");
109         if (numeric || !tos_try_print_symbolic("", info->tos, 0x3F))
110                 printf("0x%02x ", info->tos);
111 }
112
113 static void tos_mt_print(const void *ip, const struct xt_entry_match *match,
114                          int numeric)
115 {
116         const struct xt_tos_match_info *info = (const void *)match->data;
117
118         printf("tos match ");
119         if (info->invert)
120                 printf("!");
121         if (numeric ||
122             !tos_try_print_symbolic("", info->tos_value, info->tos_mask))
123                 printf("0x%02x/0x%02x ", info->tos_value, info->tos_mask);
124 }
125
126 static void tos_mt_save_v0(const void *ip, const struct xt_entry_match *match)
127 {
128         const struct ipt_tos_info *info = (const void *)match->data;
129
130         if (info->invert)
131                 printf("! ");
132         printf("--tos 0x%02x ", info->tos);
133 }
134
135 static void tos_mt_save(const void *ip, const struct xt_entry_match *match)
136 {
137         const struct xt_tos_match_info *info = (const void *)match->data;
138
139         if (info->invert)
140                 printf("! ");
141         printf("--tos 0x%02x/0x%02x ", info->tos_value, info->tos_mask);
142 }
143
144 static struct xtables_match tos_mt_reg[] = {
145         {
146                 .version       = XTABLES_VERSION,
147                 .name          = "tos",
148                 .family        = NFPROTO_IPV4,
149                 .revision      = 0,
150                 .size          = XT_ALIGN(sizeof(struct ipt_tos_info)),
151                 .userspacesize = XT_ALIGN(sizeof(struct ipt_tos_info)),
152                 .help          = tos_mt_help,
153                 .parse         = tos_mt_parse_v0,
154                 .final_check   = tos_mt_check,
155                 .print         = tos_mt_print_v0,
156                 .save          = tos_mt_save_v0,
157                 .extra_opts    = tos_mt_opts,
158         },
159         {
160                 .version       = XTABLES_VERSION,
161                 .name          = "tos",
162                 .family        = NFPROTO_UNSPEC,
163                 .revision      = 1,
164                 .size          = XT_ALIGN(sizeof(struct xt_tos_match_info)),
165                 .userspacesize = XT_ALIGN(sizeof(struct xt_tos_match_info)),
166                 .help          = tos_mt_help,
167                 .parse         = tos_mt_parse,
168                 .final_check   = tos_mt_check,
169                 .print         = tos_mt_print,
170                 .save          = tos_mt_save,
171                 .extra_opts    = tos_mt_opts,
172         },
173 };
174
175 void _init(void)
176 {
177         xtables_register_matches(tos_mt_reg, ARRAY_SIZE(tos_mt_reg));
178 }