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 <[email protected]>
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22 #include <stdbool.h>
23 #include <stdint.h>
24 #include <stdio.h>
25 #include <xtables.h>
26 #include <linux/netfilter/xt_connmark.h>
27
28 struct xt_connmark_info {
29 unsigned long mark, mask;
30 uint8_t invert;
31 };
32
33 enum {
34 O_MARK = 0,
35 };
36
connmark_mt_help(void)37 static void connmark_mt_help(void)
38 {
39 printf(
40 "connmark match options:\n"
41 "[!] --mark value[/mask] Match ctmark value with optional mask\n");
42 }
43
44 static const struct xt_option_entry connmark_mt_opts[] = {
45 {.name = "mark", .id = O_MARK, .type = XTTYPE_MARKMASK32,
46 .flags = XTOPT_MAND | XTOPT_INVERT},
47 XTOPT_TABLEEND,
48 };
49
connmark_mt_parse(struct xt_option_call * cb)50 static void connmark_mt_parse(struct xt_option_call *cb)
51 {
52 struct xt_connmark_mtinfo1 *info = cb->data;
53
54 xtables_option_parse(cb);
55 if (cb->invert)
56 info->invert = true;
57 info->mark = cb->val.mark;
58 info->mask = cb->val.mask;
59 }
60
connmark_parse(struct xt_option_call * cb)61 static void connmark_parse(struct xt_option_call *cb)
62 {
63 struct xt_connmark_info *markinfo = cb->data;
64
65 xtables_option_parse(cb);
66 markinfo->mark = cb->val.mark;
67 markinfo->mask = cb->val.mask;
68 if (cb->invert)
69 markinfo->invert = 1;
70 }
71
72 static void
connmark_print(const void * ip,const struct xt_entry_match * match,int numeric)73 connmark_print(const void *ip, const struct xt_entry_match *match, int numeric)
74 {
75 const struct xt_connmark_info *info = (const void *)match->data;
76
77 printf(" CONNMARK match ");
78 if (info->invert)
79 printf("!");
80
81 xtables_print_mark_mask(info->mark, info->mask);
82 }
83
84 static void
connmark_mt_print(const void * ip,const struct xt_entry_match * match,int numeric)85 connmark_mt_print(const void *ip, const struct xt_entry_match *match,
86 int numeric)
87 {
88 const struct xt_connmark_mtinfo1 *info = (const void *)match->data;
89
90 printf(" connmark match ");
91 if (info->invert)
92 printf("!");
93
94 xtables_print_mark_mask(info->mark, info->mask);
95 }
96
connmark_save(const void * ip,const struct xt_entry_match * match)97 static void connmark_save(const void *ip, const struct xt_entry_match *match)
98 {
99 const struct xt_connmark_info *info = (const void *)match->data;
100
101 if (info->invert)
102 printf(" !");
103
104 printf(" --mark");
105 xtables_print_mark_mask(info->mark, info->mask);
106 }
107
108 static void
connmark_mt_save(const void * ip,const struct xt_entry_match * match)109 connmark_mt_save(const void *ip, const struct xt_entry_match *match)
110 {
111 const struct xt_connmark_mtinfo1 *info = (const void *)match->data;
112
113 if (info->invert)
114 printf(" !");
115
116 printf(" --mark");
117 xtables_print_mark_mask(info->mark, info->mask);
118 }
119
print_mark_xlate(unsigned int mark,unsigned int mask,struct xt_xlate * xl,uint32_t op)120 static void print_mark_xlate(unsigned int mark, unsigned int mask,
121 struct xt_xlate *xl, uint32_t op)
122 {
123 if (mask != 0xffffffffU)
124 xt_xlate_add(xl, " and 0x%x %s 0x%x", mask,
125 op == XT_OP_EQ ? "==" : "!=", mark);
126 else
127 xt_xlate_add(xl, " %s0x%x",
128 op == XT_OP_EQ ? "" : "!= ", mark);
129 }
130
connmark_xlate(struct xt_xlate * xl,const struct xt_xlate_mt_params * params)131 static int connmark_xlate(struct xt_xlate *xl,
132 const struct xt_xlate_mt_params *params)
133 {
134 const struct xt_connmark_info *info = (const void *)params->match->data;
135 enum xt_op op = XT_OP_EQ;
136
137 if (info->invert)
138 op = XT_OP_NEQ;
139
140 xt_xlate_add(xl, "ct mark");
141 print_mark_xlate(info->mark, info->mask, xl, op);
142
143 return 1;
144 }
145
146 static int
connmark_mt_xlate(struct xt_xlate * xl,const struct xt_xlate_mt_params * params)147 connmark_mt_xlate(struct xt_xlate *xl,
148 const struct xt_xlate_mt_params *params)
149 {
150 const struct xt_connmark_mtinfo1 *info =
151 (const void *)params->match->data;
152 enum xt_op op = XT_OP_EQ;
153
154 if (info->invert)
155 op = XT_OP_NEQ;
156
157 xt_xlate_add(xl, "ct mark");
158 print_mark_xlate(info->mark, info->mask, xl, op);
159
160 return 1;
161 }
162
163 static struct xtables_match connmark_mt_reg[] = {
164 {
165 .family = NFPROTO_UNSPEC,
166 .name = "connmark",
167 .revision = 0,
168 .version = XTABLES_VERSION,
169 .size = XT_ALIGN(sizeof(struct xt_connmark_info)),
170 .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_info)),
171 .help = connmark_mt_help,
172 .print = connmark_print,
173 .save = connmark_save,
174 .x6_parse = connmark_parse,
175 .x6_options = connmark_mt_opts,
176 .xlate = connmark_xlate,
177 },
178 {
179 .version = XTABLES_VERSION,
180 .name = "connmark",
181 .revision = 1,
182 .family = NFPROTO_UNSPEC,
183 .size = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)),
184 .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)),
185 .help = connmark_mt_help,
186 .print = connmark_mt_print,
187 .save = connmark_mt_save,
188 .x6_parse = connmark_mt_parse,
189 .x6_options = connmark_mt_opts,
190 .xlate = connmark_mt_xlate,
191 },
192 };
193
_init(void)194 void _init(void)
195 {
196 xtables_register_matches(connmark_mt_reg, ARRAY_SIZE(connmark_mt_reg));
197 }
198