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