libxt_connmark.c revision ddac6c5bc636003d664d25c08ea3fe176565096c
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 */ 22#include <stdio.h> 23#include <netdb.h> 24#include <string.h> 25#include <stdlib.h> 26#include <getopt.h> 27 28#include <xtables.h> 29#include <linux/netfilter/xt_connmark.h> 30 31enum { 32 F_MARK = 1 << 0, 33}; 34 35static void connmark_mt_help(void) 36{ 37 printf( 38"connmark match options:\n" 39"[!] --mark value[/mask] Match ctmark value with optional mask\n"); 40} 41 42static const struct option connmark_mt_opts[] = { 43 {.name = "mark", .has_arg = true, .val = '1'}, 44 { .name = NULL } 45}; 46 47static int 48connmark_mt_parse(int c, char **argv, int invert, unsigned int *flags, 49 const void *entry, struct xt_entry_match **match) 50{ 51 struct xt_connmark_mtinfo1 *info = (void *)(*match)->data; 52 unsigned int mark, mask = ~0U; 53 char *end; 54 55 switch (c) { 56 case '1': /* --mark */ 57 param_act(P_ONLY_ONCE, "connmark", "--mark", *flags & F_MARK); 58 if (!strtonum(optarg, &end, &mark, 0, ~0U)) 59 param_act(P_BAD_VALUE, "connmark", "--mark", optarg); 60 if (*end == '/') 61 if (!strtonum(end + 1, &end, &mask, 0, ~0U)) 62 param_act(P_BAD_VALUE, "connmark", "--mark", optarg); 63 if (*end != '\0') 64 param_act(P_BAD_VALUE, "connmark", "--mark", optarg); 65 66 if (invert) 67 info->invert = true; 68 info->mark = mark; 69 info->mask = mask; 70 *flags |= F_MARK; 71 return true; 72 } 73 return false; 74} 75 76static int 77connmark_parse(int c, char **argv, int invert, unsigned int *flags, 78 const void *entry, struct xt_entry_match **match) 79{ 80 struct xt_connmark_info *markinfo = (struct xt_connmark_info *)(*match)->data; 81 82 switch (c) { 83 char *end; 84 case '1': 85 check_inverse(optarg, &invert, &optind, 0); 86 87 markinfo->mark = strtoul(optarg, &end, 0); 88 markinfo->mask = 0xffffffffUL; 89 90 if (*end == '/') 91 markinfo->mask = strtoul(end+1, &end, 0); 92 93 if (*end != '\0' || end == optarg) 94 exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg); 95 if (invert) 96 markinfo->invert = 1; 97 *flags = 1; 98 break; 99 100 default: 101 return 0; 102 } 103 return 1; 104} 105 106static void print_mark(unsigned int mark, unsigned int mask) 107{ 108 if (mask != 0xffffffffU) 109 printf("0x%x/0x%x ", mark, mask); 110 else 111 printf("0x%x ", mark); 112} 113 114static void connmark_mt_check(unsigned int flags) 115{ 116 if (flags == 0) 117 exit_error(PARAMETER_PROBLEM, 118 "connmark: The --mark option is required"); 119} 120 121static void 122connmark_print(const void *ip, const struct xt_entry_match *match, int numeric) 123{ 124 struct xt_connmark_info *info = (struct xt_connmark_info *)match->data; 125 126 printf("CONNMARK match "); 127 if (info->invert) 128 printf("!"); 129 print_mark(info->mark, info->mask); 130} 131 132static void 133connmark_mt_print(const void *ip, const struct xt_entry_match *match, int numeric) 134{ 135 const struct xt_connmark_mtinfo1 *info = (const void *)match->data; 136 137 printf("connmark match "); 138 if (info->invert) 139 printf("!"); 140 print_mark(info->mark, info->mask); 141} 142 143static void connmark_save(const void *ip, const struct xt_entry_match *match) 144{ 145 struct xt_connmark_info *info = (struct xt_connmark_info *)match->data; 146 147 if (info->invert) 148 printf("! "); 149 150 printf("--mark "); 151 print_mark(info->mark, info->mask); 152} 153 154static void 155connmark_mt_save(const void *ip, const struct xt_entry_match *match) 156{ 157 const struct xt_connmark_mtinfo1 *info = (const void *)match->data; 158 159 if (info->invert) 160 printf("! "); 161 162 printf("--mark "); 163 print_mark(info->mark, info->mask); 164} 165 166static struct xtables_match connmark_mt_reg_v0 = { 167 .family = AF_INET, 168 .name = "connmark", 169 .revision = 0, 170 .version = XTABLES_VERSION, 171 .size = XT_ALIGN(sizeof(struct xt_connmark_info)), 172 .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_info)), 173 .help = connmark_mt_help, 174 .parse = connmark_parse, 175 .final_check = connmark_mt_check, 176 .print = connmark_print, 177 .save = connmark_save, 178 .extra_opts = connmark_mt_opts, 179}; 180 181static struct xtables_match connmark_mt6_reg_v0 = { 182 .family = AF_INET6, 183 .name = "connmark", 184 .revision = 0, 185 .version = XTABLES_VERSION, 186 .size = XT_ALIGN(sizeof(struct xt_connmark_info)), 187 .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_info)), 188 .help = connmark_mt_help, 189 .parse = connmark_parse, 190 .final_check = connmark_mt_check, 191 .print = connmark_print, 192 .save = connmark_save, 193 .extra_opts = connmark_mt_opts, 194}; 195 196static struct xtables_match connmark_mt_reg = { 197 .version = XTABLES_VERSION, 198 .name = "connmark", 199 .revision = 1, 200 .family = AF_INET, 201 .size = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)), 202 .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)), 203 .help = connmark_mt_help, 204 .parse = connmark_mt_parse, 205 .final_check = connmark_mt_check, 206 .print = connmark_mt_print, 207 .save = connmark_mt_save, 208 .extra_opts = connmark_mt_opts, 209}; 210 211static struct xtables_match connmark_mt6_reg = { 212 .version = XTABLES_VERSION, 213 .name = "connmark", 214 .revision = 1, 215 .family = AF_INET6, 216 .size = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)), 217 .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)), 218 .help = connmark_mt_help, 219 .parse = connmark_mt_parse, 220 .final_check = connmark_mt_check, 221 .print = connmark_mt_print, 222 .save = connmark_mt_save, 223 .extra_opts = connmark_mt_opts, 224}; 225 226void _init(void) 227{ 228 xtables_register_match(&connmark_mt_reg_v0); 229 xtables_register_match(&connmark_mt6_reg_v0); 230 xtables_register_match(&connmark_mt_reg); 231 xtables_register_match(&connmark_mt6_reg); 232} 233