1469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte/* Shared library add-on to iptables to add connmark matching support.
2469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte *
3469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
4469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * by Henrik Nordstrom <hno@marasystems.com>
5469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte *
6469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * Version 1.1
7469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte *
8469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * This program is free software; you can redistribute it and/or modify
9469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * it under the terms of the GNU General Public License as published by
10469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * the Free Software Foundation; either version 2 of the License, or
11469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * (at your option) any later version.
12469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte *
13469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * This program is distributed in the hope that it will be useful,
14469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * but WITHOUT ANY WARRANTY; without even the implied warranty of
15469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * GNU General Public License for more details.
17469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte *
18469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * You should have received a copy of the GNU General Public License
19469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * along with this program; if not, write to the Free Software
20469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte */
2232b8e61e4e5bd405d9ad07bf9468498dfbb19f9eJan Engelhardt#include <stdbool.h>
237299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt#include <stdint.h>
24469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte#include <stdio.h>
25c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI#include <xtables.h>
26c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI#include <linux/netfilter/xt_connmark.h>
27469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte
28350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardtstruct xt_connmark_info {
29350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt	unsigned long mark, mask;
307ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardt	uint8_t invert;
31350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt};
32350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt
33a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardtenum {
347299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	O_MARK = 0,
35a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt};
36a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt
37a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardtstatic void connmark_mt_help(void)
38469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte{
39469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte	printf(
40a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt"connmark match options:\n"
418b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"[!] --mark value[/mask]    Match ctmark value with optional mask\n");
42469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte}
43469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte
447299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardtstatic const struct xt_option_entry connmark_mt_opts[] = {
457299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	{.name = "mark", .id = O_MARK, .type = XTTYPE_MARKMASK32,
467299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	 .flags = XTOPT_MAND | XTOPT_INVERT},
477299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	XTOPT_TABLEEND,
48469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte};
49469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte
507299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardtstatic void connmark_mt_parse(struct xt_option_call *cb)
51a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt{
527299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	struct xt_connmark_mtinfo1 *info = cb->data;
537299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt
547299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	xtables_option_parse(cb);
557299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	if (cb->invert)
567299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		info->invert = true;
577299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	info->mark = cb->val.mark;
587299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	info->mask = cb->val.mask;
59a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt}
60a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt
617299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardtstatic void connmark_parse(struct xt_option_call *cb)
62469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte{
637299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	struct xt_connmark_info *markinfo = cb->data;
647299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt
657299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	xtables_option_parse(cb);
667299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	markinfo->mark = cb->val.mark;
677299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	markinfo->mask = cb->val.mask;
687299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	if (cb->invert)
697299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		markinfo->invert = 1;
70469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte}
71469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte
72a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardtstatic void print_mark(unsigned int mark, unsigned int mask)
73469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte{
74a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt	if (mask != 0xffffffffU)
7573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" 0x%x/0x%x", mark, mask);
76469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte	else
7773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" 0x%x", mark);
78469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte}
79469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte
80469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Weltestatic void
81181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtconnmark_print(const void *ip, const struct xt_entry_match *match, int numeric)
82469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte{
8369f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardt	const struct xt_connmark_info *info = (const void *)match->data;
84469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte
8573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" CONNMARK match ");
86469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte	if (info->invert)
87469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte		printf("!");
88a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt	print_mark(info->mark, info->mask);
89a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt}
90a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt
91a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardtstatic void
92a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardtconnmark_mt_print(const void *ip, const struct xt_entry_match *match, int numeric)
93a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt{
94a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt	const struct xt_connmark_mtinfo1 *info = (const void *)match->data;
95a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt
9673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" connmark match ");
97a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt	if (info->invert)
98a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt		printf("!");
99a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt	print_mark(info->mark, info->mask);
100469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte}
101469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte
102181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void connmark_save(const void *ip, const struct xt_entry_match *match)
103469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte{
10469f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardt	const struct xt_connmark_info *info = (const void *)match->data;
105469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte
106469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte	if (info->invert)
10773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" !");
108469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte
10973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" --mark");
110a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt	print_mark(info->mark, info->mask);
111a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt}
112a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt
113a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardtstatic void
114a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardtconnmark_mt_save(const void *ip, const struct xt_entry_match *match)
115a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt{
116a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt	const struct xt_connmark_mtinfo1 *info = (const void *)match->data;
117a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt
118a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt	if (info->invert)
11973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" !");
120a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt
12173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" --mark");
122a7b0707bd83bac30a92871872dab79ec8cebebbbJan Engelhardt	print_mark(info->mark, info->mask);
123469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte}
124469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte
125f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardtstatic struct xtables_match connmark_mt_reg[] = {
126f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	{
127f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.family        = NFPROTO_UNSPEC,
128f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.name          = "connmark",
129f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.revision      = 0,
130f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.version       = XTABLES_VERSION,
131f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.size          = XT_ALIGN(sizeof(struct xt_connmark_info)),
132f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.userspacesize = XT_ALIGN(sizeof(struct xt_connmark_info)),
133f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.help          = connmark_mt_help,
134f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.print         = connmark_print,
135f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.save          = connmark_save,
1367299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		.x6_parse      = connmark_parse,
1377299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		.x6_options    = connmark_mt_opts,
138f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	},
139f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	{
140f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.version       = XTABLES_VERSION,
141f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.name          = "connmark",
142f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.revision      = 1,
143f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.family        = NFPROTO_UNSPEC,
144f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.size          = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)),
145f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.userspacesize = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)),
146f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.help          = connmark_mt_help,
147f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.print         = connmark_mt_print,
148f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.save          = connmark_mt_save,
1497299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		.x6_parse      = connmark_mt_parse,
1507299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		.x6_options    = connmark_mt_opts,
151f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	},
152469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte};
153469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte
154469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Weltevoid _init(void)
155469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte{
156f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	xtables_register_matches(connmark_mt_reg, ARRAY_SIZE(connmark_mt_reg));
157469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte}
158