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