libxt_connmark.c revision f2a77520693f0a6dd1df1f87be4b81913961c1f5
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 = UINT32_MAX; 53 char *end; 54 55 switch (c) { 56 case '1': /* --mark */ 57 xtables_param_act(XTF_ONLY_ONCE, "connmark", "--mark", *flags & F_MARK); 58 if (!xtables_strtoui(optarg, &end, &mark, 0, UINT32_MAX)) 59 xtables_param_act(XTF_BAD_VALUE, "connmark", "--mark", optarg); 60 if (*end == '/') 61 if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX)) 62 xtables_param_act(XTF_BAD_VALUE, "connmark", "--mark", optarg); 63 if (*end != '\0') 64 xtables_param_act(XTF_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 xtables_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 xtables_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 xtables_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 const struct xt_connmark_info *info = (const void *)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 const struct xt_connmark_info *info = (const void *)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[] = { 167 { 168 .family = NFPROTO_UNSPEC, 169 .name = "connmark", 170 .revision = 0, 171 .version = XTABLES_VERSION, 172 .size = XT_ALIGN(sizeof(struct xt_connmark_info)), 173 .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_info)), 174 .help = connmark_mt_help, 175 .parse = connmark_parse, 176 .final_check = connmark_mt_check, 177 .print = connmark_print, 178 .save = connmark_save, 179 .extra_opts = connmark_mt_opts, 180 }, 181 { 182 .version = XTABLES_VERSION, 183 .name = "connmark", 184 .revision = 1, 185 .family = NFPROTO_UNSPEC, 186 .size = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)), 187 .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)), 188 .help = connmark_mt_help, 189 .parse = connmark_mt_parse, 190 .final_check = connmark_mt_check, 191 .print = connmark_mt_print, 192 .save = connmark_mt_save, 193 .extra_opts = connmark_mt_opts, 194 }, 195}; 196 197void _init(void) 198{ 199 xtables_register_matches(connmark_mt_reg, ARRAY_SIZE(connmark_mt_reg)); 200} 201