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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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, int numeric)
     93 {
     94 	const struct xt_connmark_mtinfo1 *info = (const void *)match->data;
     95 
     96 	printf(" connmark match ");
     97 	if (info->invert)
     98 		printf("!");
     99 	print_mark(info->mark, info->mask);
    100 }
    101 
    102 static void connmark_save(const void *ip, const struct xt_entry_match *match)
    103 {
    104 	const struct xt_connmark_info *info = (const void *)match->data;
    105 
    106 	if (info->invert)
    107 		printf(" !");
    108 
    109 	printf(" --mark");
    110 	print_mark(info->mark, info->mask);
    111 }
    112 
    113 static void
    114 connmark_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)
    119 		printf(" !");
    120 
    121 	printf(" --mark");
    122 	print_mark(info->mark, info->mask);
    123 }
    124 
    125 static 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,
    134 		.print         = connmark_print,
    135 		.save          = connmark_save,
    136 		.x6_parse      = connmark_parse,
    137 		.x6_options    = connmark_mt_opts,
    138 	},
    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,
    147 		.print         = connmark_mt_print,
    148 		.save          = connmark_mt_save,
    149 		.x6_parse      = connmark_mt_parse,
    150 		.x6_options    = connmark_mt_opts,
    151 	},
    152 };
    153 
    154 void _init(void)
    155 {
    156 	xtables_register_matches(connmark_mt_reg, ARRAY_SIZE(connmark_mt_reg));
    157 }
    158