• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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., 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 
print_mark(unsigned int mark,unsigned int mask)72 static void print_mark(unsigned int mark, unsigned int mask)
73 {
74 	if (mask != 0xffffffffU)
75 		printf(" 0x%x/0x%x", mark, mask);
76 	else
77 		printf(" 0x%x", mark);
78 }
79 
80 static void
connmark_print(const void * ip,const struct xt_entry_match * match,int numeric)81 connmark_print(const void *ip, const struct xt_entry_match *match, int numeric)
82 {
83 	const struct xt_connmark_info *info = (const void *)match->data;
84 
85 	printf(" CONNMARK match ");
86 	if (info->invert)
87 		printf("!");
88 	print_mark(info->mark, info->mask);
89 }
90 
91 static void
connmark_mt_print(const void * ip,const struct xt_entry_match * match,int numeric)92 connmark_mt_print(const void *ip, const struct xt_entry_match *match,
93 		  int numeric)
94 {
95 	const struct xt_connmark_mtinfo1 *info = (const void *)match->data;
96 
97 	printf(" connmark match ");
98 	if (info->invert)
99 		printf("!");
100 	print_mark(info->mark, info->mask);
101 }
102 
connmark_save(const void * ip,const struct xt_entry_match * match)103 static void connmark_save(const void *ip, const struct xt_entry_match *match)
104 {
105 	const struct xt_connmark_info *info = (const void *)match->data;
106 
107 	if (info->invert)
108 		printf(" !");
109 
110 	printf(" --mark");
111 	print_mark(info->mark, info->mask);
112 }
113 
114 static void
connmark_mt_save(const void * ip,const struct xt_entry_match * match)115 connmark_mt_save(const void *ip, const struct xt_entry_match *match)
116 {
117 	const struct xt_connmark_mtinfo1 *info = (const void *)match->data;
118 
119 	if (info->invert)
120 		printf(" !");
121 
122 	printf(" --mark");
123 	print_mark(info->mark, info->mask);
124 }
125 
print_mark_xlate(unsigned int mark,unsigned int mask,struct xt_xlate * xl,uint32_t op)126 static void print_mark_xlate(unsigned int mark, unsigned int mask,
127 			     struct xt_xlate *xl, uint32_t op)
128 {
129 	if (mask != 0xffffffffU)
130 		xt_xlate_add(xl, " and 0x%x %s 0x%x", mask,
131 			   op == XT_OP_EQ ? "==" : "!=", mark);
132 	else
133 		xt_xlate_add(xl, " %s0x%x",
134 			   op == XT_OP_EQ ? "" : "!= ", mark);
135 }
136 
connmark_xlate(struct xt_xlate * xl,const struct xt_xlate_mt_params * params)137 static int connmark_xlate(struct xt_xlate *xl,
138 			  const struct xt_xlate_mt_params *params)
139 {
140 	const struct xt_connmark_info *info = (const void *)params->match->data;
141 	enum xt_op op = XT_OP_EQ;
142 
143 	if (info->invert)
144 		op = XT_OP_NEQ;
145 
146 	xt_xlate_add(xl, "ct mark");
147 	print_mark_xlate(info->mark, info->mask, xl, op);
148 
149 	return 1;
150 }
151 
152 static int
connmark_mt_xlate(struct xt_xlate * xl,const struct xt_xlate_mt_params * params)153 connmark_mt_xlate(struct xt_xlate *xl,
154 		  const struct xt_xlate_mt_params *params)
155 {
156 	const struct xt_connmark_mtinfo1 *info =
157 		(const void *)params->match->data;
158 	enum xt_op op = XT_OP_EQ;
159 
160 	if (info->invert)
161 		op = XT_OP_NEQ;
162 
163 	xt_xlate_add(xl, "ct mark");
164 	print_mark_xlate(info->mark, info->mask, xl, op);
165 
166 	return 1;
167 }
168 
169 static struct xtables_match connmark_mt_reg[] = {
170 	{
171 		.family        = NFPROTO_UNSPEC,
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 		.print         = connmark_print,
179 		.save          = connmark_save,
180 		.x6_parse      = connmark_parse,
181 		.x6_options    = connmark_mt_opts,
182 		.xlate	       = connmark_xlate,
183 	},
184 	{
185 		.version       = XTABLES_VERSION,
186 		.name          = "connmark",
187 		.revision      = 1,
188 		.family        = NFPROTO_UNSPEC,
189 		.size          = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)),
190 		.userspacesize = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)),
191 		.help          = connmark_mt_help,
192 		.print         = connmark_mt_print,
193 		.save          = connmark_mt_save,
194 		.x6_parse      = connmark_mt_parse,
195 		.x6_options    = connmark_mt_opts,
196 		.xlate	       = connmark_mt_xlate,
197 	},
198 };
199 
_init(void)200 void _init(void)
201 {
202 	xtables_register_matches(connmark_mt_reg, ARRAY_SIZE(connmark_mt_reg));
203 }
204