Sapan says vnet_tun is obsolete.
[iptables.git] / extensions / libxt_mark.c
1 /* Shared library add-on to iptables to add NFMARK matching support. */
2 #include <stdbool.h>
3 #include <stdio.h>
4 #include <netdb.h>
5 #include <string.h>
6 #include <stdlib.h>
7 #include <getopt.h>
8
9 #include <xtables.h>
10 #include <linux/netfilter/xt_mark.h>
11
12 enum {
13         F_MARK = 1 << 0,
14 };
15
16 static void mark_mt_help(void)
17 {
18         printf(
19 "mark match options:\n"
20 "[!] --mark value[/mask]    Match nfmark value with optional mask\n");
21 }
22
23 static const struct option mark_mt_opts[] = {
24         {.name = "mark", .has_arg = true, .val = '1'},
25         { .name = NULL }
26 };
27
28 static int mark_mt_parse(int c, char **argv, int invert, unsigned int *flags,
29                          const void *entry, struct xt_entry_match **match)
30 {
31         struct xt_mark_mtinfo1 *info = (void *)(*match)->data;
32         unsigned int mark, mask = ~0U;
33         char *end;
34
35         switch (c) {
36         case '1': /* --mark */
37                 param_act(P_ONLY_ONCE, "mark", "--mark", *flags & F_MARK);
38                 if (!strtonum(optarg, &end, &mark, 0, ~0U))
39                         param_act(P_BAD_VALUE, "mark", "--mark", optarg);
40                 if (*end == '/')
41                         if (!strtonum(end + 1, &end, &mask, 0, ~0U))
42                                 param_act(P_BAD_VALUE, "mark", "--mark", optarg);
43                 if (*end != '\0')
44                         param_act(P_BAD_VALUE, "mark", "--mark", optarg);
45
46                 if (invert)
47                         info->invert = true;
48                 info->mark = mark;
49                 info->mask = mask;
50                 *flags    |= F_MARK;
51                 return true;
52         }
53         return false;
54 }
55
56 /* Function which parses command options; returns true if it
57    ate an option */
58 static int
59 mark_parse(int c, char **argv, int invert, unsigned int *flags,
60            const void *entry, struct xt_entry_match **match)
61 {
62         struct xt_mark_info *markinfo = (struct xt_mark_info *)(*match)->data;
63
64         switch (c) {
65                 char *end;
66         case '1':
67                 check_inverse(optarg, &invert, &optind, 0);
68                 markinfo->mark = strtoul(optarg, &end, 0);
69                 if (*end == '/') {
70                         markinfo->mask = strtoul(end+1, &end, 0);
71                 } else
72                         markinfo->mask = 0xffffffff;
73                 if (*end != '\0' || end == optarg)
74                         exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
75                 if (invert)
76                         markinfo->invert = 1;
77                 *flags = 1;
78                 break;
79
80         default:
81                 return 0;
82         }
83         return 1;
84 }
85
86 static void print_mark(unsigned int mark, unsigned int mask)
87 {
88         if (mask != 0xffffffffU)
89                 printf("0x%x/0x%x ", mark, mask);
90         else
91                 printf("0x%x ", mark);
92 }
93
94 static void mark_mt_check(unsigned int flags)
95 {
96         if (flags == 0)
97                 exit_error(PARAMETER_PROBLEM,
98                            "mark match: The --mark option is required");
99 }
100
101 static void
102 mark_mt_print(const void *ip, const struct xt_entry_match *match, int numeric)
103 {
104         const struct xt_mark_mtinfo1 *info = (const void *)match->data;
105
106         printf("mark match ");
107         if (info->invert)
108                 printf("!");
109         print_mark(info->mark, info->mask);
110 }
111
112 /* Prints out the matchinfo. */
113 static void
114 mark_print(const void *ip, const struct xt_entry_match *match, int numeric)
115 {
116         struct xt_mark_info *info = (struct xt_mark_info *)match->data;
117
118         printf("MARK match ");
119
120         if (info->invert)
121                 printf("!");
122         
123         print_mark(info->mark, info->mask);
124 }
125
126 static void mark_mt_save(const void *ip, const struct xt_entry_match *match)
127 {
128         const struct xt_mark_mtinfo1 *info = (const void *)match->data;
129
130         if (info->invert)
131                 printf("!");
132
133         printf("--mark ");
134         print_mark(info->mark, info->mask);
135 }
136
137 /* Saves the union ipt_matchinfo in parsable form to stdout. */
138 static void
139 mark_save(const void *ip, const struct xt_entry_match *match)
140 {
141         struct xt_mark_info *info = (struct xt_mark_info *)match->data;
142
143         if (info->invert)
144                 printf("! ");
145         
146         printf("--mark ");
147         print_mark(info->mark, info->mask);
148 }
149
150 static struct xtables_match mark_match = {
151         .family         = AF_UNSPEC,
152         .name           = "mark",
153         .revision       = 0,
154         .version        = XTABLES_VERSION,
155         .size           = XT_ALIGN(sizeof(struct xt_mark_info)),
156         .userspacesize  = XT_ALIGN(sizeof(struct xt_mark_info)),
157         .help           = mark_mt_help,
158         .parse          = mark_parse,
159         .final_check    = mark_mt_check,
160         .print          = mark_print,
161         .save           = mark_save,
162         .extra_opts     = mark_mt_opts,
163 };
164
165 static struct xtables_match mark_mt_reg = {
166         .version        = XTABLES_VERSION,
167         .name           = "mark",
168         .revision       = 1,
169         .family         = AF_UNSPEC,
170         .size           = XT_ALIGN(sizeof(struct xt_mark_mtinfo1)),
171         .userspacesize  = XT_ALIGN(sizeof(struct xt_mark_mtinfo1)),
172         .help           = mark_mt_help,
173         .parse          = mark_mt_parse,
174         .final_check    = mark_mt_check,
175         .print          = mark_mt_print,
176         .save           = mark_mt_save,
177         .extra_opts     = mark_mt_opts,
178 };
179
180 void _init(void)
181 {
182         xtables_register_match(&mark_match);
183         xtables_register_match(&mark_mt_reg);
184 }