1*a71a9546SAutomerger Merge Worker /* Shared library add-on to iptables to add connmark matching support. 2*a71a9546SAutomerger Merge Worker * 3*a71a9546SAutomerger Merge Worker * (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> 4*a71a9546SAutomerger Merge Worker * by Henrik Nordstrom <[email protected]> 5*a71a9546SAutomerger Merge Worker * 6*a71a9546SAutomerger Merge Worker * Version 1.1 7*a71a9546SAutomerger Merge Worker * 8*a71a9546SAutomerger Merge Worker * This program is free software; you can redistribute it and/or modify 9*a71a9546SAutomerger Merge Worker * it under the terms of the GNU General Public License as published by 10*a71a9546SAutomerger Merge Worker * the Free Software Foundation; either version 2 of the License, or 11*a71a9546SAutomerger Merge Worker * (at your option) any later version. 12*a71a9546SAutomerger Merge Worker * 13*a71a9546SAutomerger Merge Worker * This program is distributed in the hope that it will be useful, 14*a71a9546SAutomerger Merge Worker * but WITHOUT ANY WARRANTY; without even the implied warranty of 15*a71a9546SAutomerger Merge Worker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*a71a9546SAutomerger Merge Worker * GNU General Public License for more details. 17*a71a9546SAutomerger Merge Worker * 18*a71a9546SAutomerger Merge Worker * You should have received a copy of the GNU General Public License 19*a71a9546SAutomerger Merge Worker * along with this program; if not, write to the Free Software 20*a71a9546SAutomerger Merge Worker * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 21*a71a9546SAutomerger Merge Worker */ 22*a71a9546SAutomerger Merge Worker #include <stdbool.h> 23*a71a9546SAutomerger Merge Worker #include <stdint.h> 24*a71a9546SAutomerger Merge Worker #include <stdio.h> 25*a71a9546SAutomerger Merge Worker #include <xtables.h> 26*a71a9546SAutomerger Merge Worker #include <linux/netfilter/xt_connmark.h> 27*a71a9546SAutomerger Merge Worker 28*a71a9546SAutomerger Merge Worker struct xt_connmark_info { 29*a71a9546SAutomerger Merge Worker unsigned long mark, mask; 30*a71a9546SAutomerger Merge Worker uint8_t invert; 31*a71a9546SAutomerger Merge Worker }; 32*a71a9546SAutomerger Merge Worker 33*a71a9546SAutomerger Merge Worker enum { 34*a71a9546SAutomerger Merge Worker O_MARK = 0, 35*a71a9546SAutomerger Merge Worker }; 36*a71a9546SAutomerger Merge Worker 37*a71a9546SAutomerger Merge Worker static void connmark_mt_help(void) 38*a71a9546SAutomerger Merge Worker { 39*a71a9546SAutomerger Merge Worker printf( 40*a71a9546SAutomerger Merge Worker "connmark match options:\n" 41*a71a9546SAutomerger Merge Worker "[!] --mark value[/mask] Match ctmark value with optional mask\n"); 42*a71a9546SAutomerger Merge Worker } 43*a71a9546SAutomerger Merge Worker 44*a71a9546SAutomerger Merge Worker static const struct xt_option_entry connmark_mt_opts[] = { 45*a71a9546SAutomerger Merge Worker {.name = "mark", .id = O_MARK, .type = XTTYPE_MARKMASK32, 46*a71a9546SAutomerger Merge Worker .flags = XTOPT_MAND | XTOPT_INVERT}, 47*a71a9546SAutomerger Merge Worker XTOPT_TABLEEND, 48*a71a9546SAutomerger Merge Worker }; 49*a71a9546SAutomerger Merge Worker 50*a71a9546SAutomerger Merge Worker static void connmark_mt_parse(struct xt_option_call *cb) 51*a71a9546SAutomerger Merge Worker { 52*a71a9546SAutomerger Merge Worker struct xt_connmark_mtinfo1 *info = cb->data; 53*a71a9546SAutomerger Merge Worker 54*a71a9546SAutomerger Merge Worker xtables_option_parse(cb); 55*a71a9546SAutomerger Merge Worker if (cb->invert) 56*a71a9546SAutomerger Merge Worker info->invert = true; 57*a71a9546SAutomerger Merge Worker info->mark = cb->val.mark; 58*a71a9546SAutomerger Merge Worker info->mask = cb->val.mask; 59*a71a9546SAutomerger Merge Worker } 60*a71a9546SAutomerger Merge Worker 61*a71a9546SAutomerger Merge Worker static void connmark_parse(struct xt_option_call *cb) 62*a71a9546SAutomerger Merge Worker { 63*a71a9546SAutomerger Merge Worker struct xt_connmark_info *markinfo = cb->data; 64*a71a9546SAutomerger Merge Worker 65*a71a9546SAutomerger Merge Worker xtables_option_parse(cb); 66*a71a9546SAutomerger Merge Worker markinfo->mark = cb->val.mark; 67*a71a9546SAutomerger Merge Worker markinfo->mask = cb->val.mask; 68*a71a9546SAutomerger Merge Worker if (cb->invert) 69*a71a9546SAutomerger Merge Worker markinfo->invert = 1; 70*a71a9546SAutomerger Merge Worker } 71*a71a9546SAutomerger Merge Worker 72*a71a9546SAutomerger Merge Worker static void 73*a71a9546SAutomerger Merge Worker connmark_print(const void *ip, const struct xt_entry_match *match, int numeric) 74*a71a9546SAutomerger Merge Worker { 75*a71a9546SAutomerger Merge Worker const struct xt_connmark_info *info = (const void *)match->data; 76*a71a9546SAutomerger Merge Worker 77*a71a9546SAutomerger Merge Worker printf(" CONNMARK match "); 78*a71a9546SAutomerger Merge Worker if (info->invert) 79*a71a9546SAutomerger Merge Worker printf("!"); 80*a71a9546SAutomerger Merge Worker 81*a71a9546SAutomerger Merge Worker xtables_print_mark_mask(info->mark, info->mask); 82*a71a9546SAutomerger Merge Worker } 83*a71a9546SAutomerger Merge Worker 84*a71a9546SAutomerger Merge Worker static void 85*a71a9546SAutomerger Merge Worker connmark_mt_print(const void *ip, const struct xt_entry_match *match, 86*a71a9546SAutomerger Merge Worker int numeric) 87*a71a9546SAutomerger Merge Worker { 88*a71a9546SAutomerger Merge Worker const struct xt_connmark_mtinfo1 *info = (const void *)match->data; 89*a71a9546SAutomerger Merge Worker 90*a71a9546SAutomerger Merge Worker printf(" connmark match "); 91*a71a9546SAutomerger Merge Worker if (info->invert) 92*a71a9546SAutomerger Merge Worker printf("!"); 93*a71a9546SAutomerger Merge Worker 94*a71a9546SAutomerger Merge Worker xtables_print_mark_mask(info->mark, info->mask); 95*a71a9546SAutomerger Merge Worker } 96*a71a9546SAutomerger Merge Worker 97*a71a9546SAutomerger Merge Worker static void connmark_save(const void *ip, const struct xt_entry_match *match) 98*a71a9546SAutomerger Merge Worker { 99*a71a9546SAutomerger Merge Worker const struct xt_connmark_info *info = (const void *)match->data; 100*a71a9546SAutomerger Merge Worker 101*a71a9546SAutomerger Merge Worker if (info->invert) 102*a71a9546SAutomerger Merge Worker printf(" !"); 103*a71a9546SAutomerger Merge Worker 104*a71a9546SAutomerger Merge Worker printf(" --mark"); 105*a71a9546SAutomerger Merge Worker xtables_print_mark_mask(info->mark, info->mask); 106*a71a9546SAutomerger Merge Worker } 107*a71a9546SAutomerger Merge Worker 108*a71a9546SAutomerger Merge Worker static void 109*a71a9546SAutomerger Merge Worker connmark_mt_save(const void *ip, const struct xt_entry_match *match) 110*a71a9546SAutomerger Merge Worker { 111*a71a9546SAutomerger Merge Worker const struct xt_connmark_mtinfo1 *info = (const void *)match->data; 112*a71a9546SAutomerger Merge Worker 113*a71a9546SAutomerger Merge Worker if (info->invert) 114*a71a9546SAutomerger Merge Worker printf(" !"); 115*a71a9546SAutomerger Merge Worker 116*a71a9546SAutomerger Merge Worker printf(" --mark"); 117*a71a9546SAutomerger Merge Worker xtables_print_mark_mask(info->mark, info->mask); 118*a71a9546SAutomerger Merge Worker } 119*a71a9546SAutomerger Merge Worker 120*a71a9546SAutomerger Merge Worker static void print_mark_xlate(unsigned int mark, unsigned int mask, 121*a71a9546SAutomerger Merge Worker struct xt_xlate *xl, uint32_t op) 122*a71a9546SAutomerger Merge Worker { 123*a71a9546SAutomerger Merge Worker if (mask != 0xffffffffU) 124*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, " and 0x%x %s 0x%x", mask, 125*a71a9546SAutomerger Merge Worker op == XT_OP_EQ ? "==" : "!=", mark); 126*a71a9546SAutomerger Merge Worker else 127*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, " %s0x%x", 128*a71a9546SAutomerger Merge Worker op == XT_OP_EQ ? "" : "!= ", mark); 129*a71a9546SAutomerger Merge Worker } 130*a71a9546SAutomerger Merge Worker 131*a71a9546SAutomerger Merge Worker static int connmark_xlate(struct xt_xlate *xl, 132*a71a9546SAutomerger Merge Worker const struct xt_xlate_mt_params *params) 133*a71a9546SAutomerger Merge Worker { 134*a71a9546SAutomerger Merge Worker const struct xt_connmark_info *info = (const void *)params->match->data; 135*a71a9546SAutomerger Merge Worker enum xt_op op = XT_OP_EQ; 136*a71a9546SAutomerger Merge Worker 137*a71a9546SAutomerger Merge Worker if (info->invert) 138*a71a9546SAutomerger Merge Worker op = XT_OP_NEQ; 139*a71a9546SAutomerger Merge Worker 140*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "ct mark"); 141*a71a9546SAutomerger Merge Worker print_mark_xlate(info->mark, info->mask, xl, op); 142*a71a9546SAutomerger Merge Worker 143*a71a9546SAutomerger Merge Worker return 1; 144*a71a9546SAutomerger Merge Worker } 145*a71a9546SAutomerger Merge Worker 146*a71a9546SAutomerger Merge Worker static int 147*a71a9546SAutomerger Merge Worker connmark_mt_xlate(struct xt_xlate *xl, 148*a71a9546SAutomerger Merge Worker const struct xt_xlate_mt_params *params) 149*a71a9546SAutomerger Merge Worker { 150*a71a9546SAutomerger Merge Worker const struct xt_connmark_mtinfo1 *info = 151*a71a9546SAutomerger Merge Worker (const void *)params->match->data; 152*a71a9546SAutomerger Merge Worker enum xt_op op = XT_OP_EQ; 153*a71a9546SAutomerger Merge Worker 154*a71a9546SAutomerger Merge Worker if (info->invert) 155*a71a9546SAutomerger Merge Worker op = XT_OP_NEQ; 156*a71a9546SAutomerger Merge Worker 157*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "ct mark"); 158*a71a9546SAutomerger Merge Worker print_mark_xlate(info->mark, info->mask, xl, op); 159*a71a9546SAutomerger Merge Worker 160*a71a9546SAutomerger Merge Worker return 1; 161*a71a9546SAutomerger Merge Worker } 162*a71a9546SAutomerger Merge Worker 163*a71a9546SAutomerger Merge Worker static struct xtables_match connmark_mt_reg[] = { 164*a71a9546SAutomerger Merge Worker { 165*a71a9546SAutomerger Merge Worker .family = NFPROTO_UNSPEC, 166*a71a9546SAutomerger Merge Worker .name = "connmark", 167*a71a9546SAutomerger Merge Worker .revision = 0, 168*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION, 169*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_connmark_info)), 170*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_info)), 171*a71a9546SAutomerger Merge Worker .help = connmark_mt_help, 172*a71a9546SAutomerger Merge Worker .print = connmark_print, 173*a71a9546SAutomerger Merge Worker .save = connmark_save, 174*a71a9546SAutomerger Merge Worker .x6_parse = connmark_parse, 175*a71a9546SAutomerger Merge Worker .x6_options = connmark_mt_opts, 176*a71a9546SAutomerger Merge Worker .xlate = connmark_xlate, 177*a71a9546SAutomerger Merge Worker }, 178*a71a9546SAutomerger Merge Worker { 179*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION, 180*a71a9546SAutomerger Merge Worker .name = "connmark", 181*a71a9546SAutomerger Merge Worker .revision = 1, 182*a71a9546SAutomerger Merge Worker .family = NFPROTO_UNSPEC, 183*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)), 184*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)), 185*a71a9546SAutomerger Merge Worker .help = connmark_mt_help, 186*a71a9546SAutomerger Merge Worker .print = connmark_mt_print, 187*a71a9546SAutomerger Merge Worker .save = connmark_mt_save, 188*a71a9546SAutomerger Merge Worker .x6_parse = connmark_mt_parse, 189*a71a9546SAutomerger Merge Worker .x6_options = connmark_mt_opts, 190*a71a9546SAutomerger Merge Worker .xlate = connmark_mt_xlate, 191*a71a9546SAutomerger Merge Worker }, 192*a71a9546SAutomerger Merge Worker }; 193*a71a9546SAutomerger Merge Worker 194*a71a9546SAutomerger Merge Worker void _init(void) 195*a71a9546SAutomerger Merge Worker { 196*a71a9546SAutomerger Merge Worker xtables_register_matches(connmark_mt_reg, ARRAY_SIZE(connmark_mt_reg)); 197*a71a9546SAutomerger Merge Worker } 198