Home | History | Annotate | Download | only in extensions
      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 (at) 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 
     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 
     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 
     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 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
     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
     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 
    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
    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 
    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 
    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
    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 
    200 void _init(void)
    201 {
    202 	xtables_register_matches(connmark_mt_reg, ARRAY_SIZE(connmark_mt_reg));
    203 }
    204