Sapan says vnet_tun is obsolete.
[iptables.git] / extensions / libxt_connmark.c
1 /* Shared library add-on to iptables to add connmark matching support.
2  *
3  * (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
4  * by Henrik Nordstrom <hno@marasystems.com>
5  *
6  * Version 1.1
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22 #include <stdio.h>
23 #include <netdb.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <getopt.h>
27
28 #include <xtables.h>
29 #include <linux/netfilter/xt_connmark.h>
30
31 enum {
32         F_MARK = 1 << 0,
33 };
34
35 static void connmark_mt_help(void)
36 {
37         printf(
38 "connmark match options:\n"
39 "[!] --mark value[/mask]    Match ctmark value with optional mask\n");
40 }
41
42 static const struct option connmark_mt_opts[] = {
43         {.name = "mark", .has_arg = true, .val = '1'},
44         { .name = NULL }
45 };
46
47 static int
48 connmark_mt_parse(int c, char **argv, int invert, unsigned int *flags,
49                   const void *entry, struct xt_entry_match **match)
50 {
51         struct xt_connmark_mtinfo1 *info = (void *)(*match)->data;
52         unsigned int mark, mask = ~0U;
53         char *end;
54
55         switch (c) {
56         case '1': /* --mark */
57                 param_act(P_ONLY_ONCE, "connmark", "--mark", *flags & F_MARK);
58                 if (!strtonum(optarg, &end, &mark, 0, ~0U))
59                         param_act(P_BAD_VALUE, "connmark", "--mark", optarg);
60                 if (*end == '/')
61                         if (!strtonum(end + 1, &end, &mask, 0, ~0U))
62                                 param_act(P_BAD_VALUE, "connmark", "--mark", optarg);
63                 if (*end != '\0')
64                         param_act(P_BAD_VALUE, "connmark", "--mark", optarg);
65
66                 if (invert)
67                         info->invert = true;
68                 info->mark = mark;
69                 info->mask = mask;
70                 *flags    |= F_MARK;
71                 return true;
72         }
73         return false;
74 }
75
76 /* Function which parses command options; returns true if it
77    ate an option */
78 static int
79 connmark_parse(int c, char **argv, int invert, unsigned int *flags,
80                const void *entry, struct xt_entry_match **match)
81 {
82         struct xt_connmark_info *markinfo = (struct xt_connmark_info *)(*match)->data;
83
84         switch (c) {
85                 char *end;
86         case '1':
87                 check_inverse(optarg, &invert, &optind, 0);
88
89                 markinfo->mark = strtoul(optarg, &end, 0);
90                 markinfo->mask = 0xffffffffUL;
91                 
92                 if (*end == '/')
93                         markinfo->mask = strtoul(end+1, &end, 0);
94
95                 if (*end != '\0' || end == optarg)
96                         exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
97                 if (invert)
98                         markinfo->invert = 1;
99                 *flags = 1;
100                 break;
101
102         default:
103                 return 0;
104         }
105         return 1;
106 }
107
108 static void print_mark(unsigned int mark, unsigned int mask)
109 {
110         if (mask != 0xffffffffU)
111                 printf("0x%x/0x%x ", mark, mask);
112         else
113                 printf("0x%x ", mark);
114 }
115
116 static void connmark_mt_check(unsigned int flags)
117 {
118         if (flags == 0)
119                 exit_error(PARAMETER_PROBLEM,
120                            "connmark: The --mark option is required");
121 }
122
123 /* Prints out the matchinfo. */
124 static void
125 connmark_print(const void *ip, const struct xt_entry_match *match, int numeric)
126 {
127         struct xt_connmark_info *info = (struct xt_connmark_info *)match->data;
128
129         printf("CONNMARK match ");
130         if (info->invert)
131                 printf("!");
132         print_mark(info->mark, info->mask);
133 }
134
135 static void
136 connmark_mt_print(const void *ip, const struct xt_entry_match *match, int numeric)
137 {
138         const struct xt_connmark_mtinfo1 *info = (const void *)match->data;
139
140         printf("connmark match ");
141         if (info->invert)
142                 printf("!");
143         print_mark(info->mark, info->mask);
144 }
145
146 /* Saves the matchinfo in parsable form to stdout. */
147 static void connmark_save(const void *ip, const struct xt_entry_match *match)
148 {
149         struct xt_connmark_info *info = (struct xt_connmark_info *)match->data;
150
151         if (info->invert)
152                 printf("! ");
153
154         printf("--mark ");
155         print_mark(info->mark, info->mask);
156 }
157
158 static void
159 connmark_mt_save(const void *ip, const struct xt_entry_match *match)
160 {
161         const struct xt_connmark_mtinfo1 *info = (const void *)match->data;
162
163         if (info->invert)
164                 printf("! ");
165
166         printf("--mark ");
167         print_mark(info->mark, info->mask);
168 }
169
170 static struct xtables_match connmark_mt_reg_v0 = {
171         .family         = AF_INET,
172         .name           = "connmark",
173         .revision       = 0,
174         .version        = XTABLES_VERSION,
175         .size           = XT_ALIGN(sizeof(struct xt_connmark_info)),
176         .userspacesize  = XT_ALIGN(sizeof(struct xt_connmark_info)),
177         .help           = connmark_mt_help,
178         .parse          = connmark_parse,
179         .final_check    = connmark_mt_check,
180         .print          = connmark_print,
181         .save           = connmark_save,
182         .extra_opts     = connmark_mt_opts,
183 };
184
185 static struct xtables_match connmark_mt6_reg_v0 = {
186         .family         = AF_INET6,
187         .name           = "connmark",
188         .revision       = 0,
189         .version        = XTABLES_VERSION,
190         .size           = XT_ALIGN(sizeof(struct xt_connmark_info)),
191         .userspacesize  = XT_ALIGN(sizeof(struct xt_connmark_info)),
192         .help           = connmark_mt_help,
193         .parse          = connmark_parse,
194         .final_check    = connmark_mt_check,
195         .print          = connmark_print,
196         .save           = connmark_save,
197         .extra_opts     = connmark_mt_opts,
198 };
199
200 static struct xtables_match connmark_mt_reg = {
201         .version        = XTABLES_VERSION,
202         .name           = "connmark",
203         .revision       = 1,
204         .family         = AF_INET,
205         .size           = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)),
206         .userspacesize  = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)),
207         .help           = connmark_mt_help,
208         .parse          = connmark_mt_parse,
209         .final_check    = connmark_mt_check,
210         .print          = connmark_mt_print,
211         .save           = connmark_mt_save,
212         .extra_opts     = connmark_mt_opts,
213 };
214
215 static struct xtables_match connmark_mt6_reg = {
216         .version        = XTABLES_VERSION,
217         .name           = "connmark",
218         .revision       = 1,
219         .family         = AF_INET6,
220         .size           = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)),
221         .userspacesize  = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)),
222         .help           = connmark_mt_help,
223         .parse          = connmark_mt_parse,
224         .final_check    = connmark_mt_check,
225         .print          = connmark_mt_print,
226         .save           = connmark_mt_save,
227         .extra_opts     = connmark_mt_opts,
228 };
229
230 void _init(void)
231 {
232         xtables_register_match(&connmark_mt_reg_v0);
233         xtables_register_match(&connmark_mt6_reg_v0);
234         xtables_register_match(&connmark_mt_reg);
235         xtables_register_match(&connmark_mt6_reg);
236 }