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