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