blob: 6f1d532360198e64429ffa6fb3fde55f9707490b [file] [log] [blame]
Harald Welte469d18f2006-01-26 14:43:52 +00001/* 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 */
Jan Engelhardt32b8e612010-07-23 21:16:14 +020022#include <stdbool.h>
Jan Engelhardt7299fa42011-03-06 15:54:58 +010023#include <stdint.h>
Harald Welte469d18f2006-01-26 14:43:52 +000024#include <stdio.h>
Yasuyuki KOZAKAIc57c1552007-08-04 08:09:04 +000025#include <xtables.h>
26#include <linux/netfilter/xt_connmark.h>
Harald Welte469d18f2006-01-26 14:43:52 +000027
Jan Engelhardt350661a2010-01-31 22:42:52 +010028struct xt_connmark_info {
29 unsigned long mark, mask;
Jan Engelhardt7ac40522011-01-07 12:34:04 +010030 uint8_t invert;
Jan Engelhardt350661a2010-01-31 22:42:52 +010031};
32
Jan Engelhardta7b07072008-01-20 13:32:01 +000033enum {
Jan Engelhardt7299fa42011-03-06 15:54:58 +010034 O_MARK = 0,
Jan Engelhardta7b07072008-01-20 13:32:01 +000035};
36
37static void connmark_mt_help(void)
Harald Welte469d18f2006-01-26 14:43:52 +000038{
39 printf(
Jan Engelhardta7b07072008-01-20 13:32:01 +000040"connmark match options:\n"
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +020041"[!] --mark value[/mask] Match ctmark value with optional mask\n");
Harald Welte469d18f2006-01-26 14:43:52 +000042}
43
Jan Engelhardt7299fa42011-03-06 15:54:58 +010044static 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,
Harald Welte469d18f2006-01-26 14:43:52 +000048};
49
Jan Engelhardt7299fa42011-03-06 15:54:58 +010050static void connmark_mt_parse(struct xt_option_call *cb)
Jan Engelhardta7b07072008-01-20 13:32:01 +000051{
Jan Engelhardt7299fa42011-03-06 15:54:58 +010052 struct xt_connmark_mtinfo1 *info = cb->data;
Jan Engelhardta7b07072008-01-20 13:32:01 +000053
Jan Engelhardt7299fa42011-03-06 15:54:58 +010054 xtables_option_parse(cb);
55 if (cb->invert)
56 info->invert = true;
57 info->mark = cb->val.mark;
58 info->mask = cb->val.mask;
Jan Engelhardta7b07072008-01-20 13:32:01 +000059}
60
Jan Engelhardt7299fa42011-03-06 15:54:58 +010061static void connmark_parse(struct xt_option_call *cb)
Harald Welte469d18f2006-01-26 14:43:52 +000062{
Jan Engelhardt7299fa42011-03-06 15:54:58 +010063 struct xt_connmark_info *markinfo = cb->data;
Harald Welte469d18f2006-01-26 14:43:52 +000064
Jan Engelhardt7299fa42011-03-06 15:54:58 +010065 xtables_option_parse(cb);
66 markinfo->mark = cb->val.mark;
67 markinfo->mask = cb->val.mask;
68 if (cb->invert)
69 markinfo->invert = 1;
Harald Welte469d18f2006-01-26 14:43:52 +000070}
71
Jan Engelhardta7b07072008-01-20 13:32:01 +000072static void print_mark(unsigned int mark, unsigned int mask)
Harald Welte469d18f2006-01-26 14:43:52 +000073{
Jan Engelhardta7b07072008-01-20 13:32:01 +000074 if (mask != 0xffffffffU)
Jan Engelhardt73866352010-12-18 02:04:59 +010075 printf(" 0x%x/0x%x", mark, mask);
Harald Welte469d18f2006-01-26 14:43:52 +000076 else
Jan Engelhardt73866352010-12-18 02:04:59 +010077 printf(" 0x%x", mark);
Harald Welte469d18f2006-01-26 14:43:52 +000078}
79
Harald Welte469d18f2006-01-26 14:43:52 +000080static void
Jan Engelhardt181dead2007-10-04 16:27:07 +000081connmark_print(const void *ip, const struct xt_entry_match *match, int numeric)
Harald Welte469d18f2006-01-26 14:43:52 +000082{
Jan Engelhardt69f564e2009-05-26 13:14:06 +020083 const struct xt_connmark_info *info = (const void *)match->data;
Harald Welte469d18f2006-01-26 14:43:52 +000084
Jan Engelhardt73866352010-12-18 02:04:59 +010085 printf(" CONNMARK match ");
Harald Welte469d18f2006-01-26 14:43:52 +000086 if (info->invert)
87 printf("!");
Jan Engelhardta7b07072008-01-20 13:32:01 +000088 print_mark(info->mark, info->mask);
89}
90
91static void
92connmark_mt_print(const void *ip, const struct xt_entry_match *match, int numeric)
93{
94 const struct xt_connmark_mtinfo1 *info = (const void *)match->data;
95
Jan Engelhardt73866352010-12-18 02:04:59 +010096 printf(" connmark match ");
Jan Engelhardta7b07072008-01-20 13:32:01 +000097 if (info->invert)
98 printf("!");
99 print_mark(info->mark, info->mask);
Harald Welte469d18f2006-01-26 14:43:52 +0000100}
101
Jan Engelhardt181dead2007-10-04 16:27:07 +0000102static void connmark_save(const void *ip, const struct xt_entry_match *match)
Harald Welte469d18f2006-01-26 14:43:52 +0000103{
Jan Engelhardt69f564e2009-05-26 13:14:06 +0200104 const struct xt_connmark_info *info = (const void *)match->data;
Harald Welte469d18f2006-01-26 14:43:52 +0000105
106 if (info->invert)
Jan Engelhardt73866352010-12-18 02:04:59 +0100107 printf(" !");
Harald Welte469d18f2006-01-26 14:43:52 +0000108
Jan Engelhardt73866352010-12-18 02:04:59 +0100109 printf(" --mark");
Jan Engelhardta7b07072008-01-20 13:32:01 +0000110 print_mark(info->mark, info->mask);
Harald Welte469d18f2006-01-26 14:43:52 +0000111}
112
Jan Engelhardta7b07072008-01-20 13:32:01 +0000113static void
114connmark_mt_save(const void *ip, const struct xt_entry_match *match)
115{
116 const struct xt_connmark_mtinfo1 *info = (const void *)match->data;
117
118 if (info->invert)
Jan Engelhardt73866352010-12-18 02:04:59 +0100119 printf(" !");
Jan Engelhardta7b07072008-01-20 13:32:01 +0000120
Jan Engelhardt73866352010-12-18 02:04:59 +0100121 printf(" --mark");
Jan Engelhardta7b07072008-01-20 13:32:01 +0000122 print_mark(info->mark, info->mask);
123}
124
Jan Engelhardtf2a77522009-06-25 20:12:12 +0200125static struct xtables_match connmark_mt_reg[] = {
126 {
127 .family = NFPROTO_UNSPEC,
128 .name = "connmark",
129 .revision = 0,
130 .version = XTABLES_VERSION,
131 .size = XT_ALIGN(sizeof(struct xt_connmark_info)),
132 .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_info)),
133 .help = connmark_mt_help,
Jan Engelhardtf2a77522009-06-25 20:12:12 +0200134 .print = connmark_print,
135 .save = connmark_save,
Jan Engelhardt7299fa42011-03-06 15:54:58 +0100136 .x6_parse = connmark_parse,
137 .x6_options = connmark_mt_opts,
Jan Engelhardtf2a77522009-06-25 20:12:12 +0200138 },
139 {
140 .version = XTABLES_VERSION,
141 .name = "connmark",
142 .revision = 1,
143 .family = NFPROTO_UNSPEC,
144 .size = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)),
145 .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)),
146 .help = connmark_mt_help,
Jan Engelhardtf2a77522009-06-25 20:12:12 +0200147 .print = connmark_mt_print,
148 .save = connmark_mt_save,
Jan Engelhardt7299fa42011-03-06 15:54:58 +0100149 .x6_parse = connmark_mt_parse,
150 .x6_options = connmark_mt_opts,
Jan Engelhardtf2a77522009-06-25 20:12:12 +0200151 },
Harald Welte469d18f2006-01-26 14:43:52 +0000152};
153
154void _init(void)
155{
Jan Engelhardtf2a77522009-06-25 20:12:12 +0200156 xtables_register_matches(connmark_mt_reg, ARRAY_SIZE(connmark_mt_reg));
Harald Welte469d18f2006-01-26 14:43:52 +0000157}