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 28struct xt_connmark_info { 29 unsigned long mark, mask; 30 uint8_t invert; 31}; 32 33enum { 34 O_MARK = 0, 35}; 36 37static 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 44static 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 50static 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 61static 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 72static 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 80static void 81connmark_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 91static void 92connmark_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 103static 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 114static void 115connmark_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 126static 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 137static 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 152static int 153connmark_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 169static 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 200void _init(void) 201{ 202 xtables_register_matches(connmark_mt_reg, ARRAY_SIZE(connmark_mt_reg)); 203} 204