libxt_CONNMARK.c revision f36f4a8844132cbaacf3bbd5ec0254c17fcc97ae
1/* Shared library add-on to iptables to add CONNMARK target 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 <string.h> 24#include <stdlib.h> 25#include <getopt.h> 26 27#include <xtables.h> 28#include <linux/netfilter/x_tables.h> 29#include <linux/netfilter/xt_CONNMARK.h> 30 31#if 0 32struct markinfo { 33 struct xt_entry_target t; 34 struct ipt_connmark_target_info mark; 35}; 36#endif 37 38/* Function which prints out usage message. */ 39static void 40help(void) 41{ 42 printf( 43"CONNMARK target v%s options:\n" 44" --set-mark value[/mask] Set conntrack mark value\n" 45" --save-mark [--mask mask] Save the packet nfmark in the connection\n" 46" --restore-mark [--mask mask] Restore saved nfmark value\n" 47"\n", 48IPTABLES_VERSION); 49} 50 51static const struct option opts[] = { 52 { "set-mark", 1, 0, '1' }, 53 { "save-mark", 0, 0, '2' }, 54 { "restore-mark", 0, 0, '3' }, 55 { "mask", 1, 0, '4' }, 56 { 0 } 57}; 58 59/* Initialize the target. */ 60static void 61init(struct xt_entry_target *t, unsigned int *nfcache) 62{ 63} 64 65/* Function which parses command options; returns true if it 66 ate an option */ 67static int 68parse(int c, char **argv, int invert, unsigned int *flags, 69 const void *entry, 70 struct xt_entry_target **target) 71{ 72 struct xt_connmark_target_info *markinfo 73 = (struct xt_connmark_target_info *)(*target)->data; 74 75 markinfo->mask = 0xffffffffUL; 76 77 switch (c) { 78 char *end; 79 case '1': 80 markinfo->mode = XT_CONNMARK_SET; 81 82 markinfo->mark = strtoul(optarg, &end, 0); 83 if (*end == '/' && end[1] != '\0') 84 markinfo->mask = strtoul(end+1, &end, 0); 85 86 if (*end != '\0' || end == optarg) 87 exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg); 88 if (*flags) 89 exit_error(PARAMETER_PROBLEM, 90 "CONNMARK target: Can't specify --set-mark twice"); 91 *flags = 1; 92 break; 93 case '2': 94 markinfo->mode = XT_CONNMARK_SAVE; 95 if (*flags) 96 exit_error(PARAMETER_PROBLEM, 97 "CONNMARK target: Can't specify --save-mark twice"); 98 *flags = 1; 99 break; 100 case '3': 101 markinfo->mode = XT_CONNMARK_RESTORE; 102 if (*flags) 103 exit_error(PARAMETER_PROBLEM, 104 "CONNMARK target: Can't specify --restore-mark twice"); 105 *flags = 1; 106 break; 107 case '4': 108 if (!*flags) 109 exit_error(PARAMETER_PROBLEM, 110 "CONNMARK target: Can't specify --mask without a operation"); 111 markinfo->mask = strtoul(optarg, &end, 0); 112 113 if (*end != '\0' || end == optarg) 114 exit_error(PARAMETER_PROBLEM, "Bad MASK value `%s'", optarg); 115 break; 116 default: 117 return 0; 118 } 119 120 return 1; 121} 122 123static void 124final_check(unsigned int flags) 125{ 126 if (!flags) 127 exit_error(PARAMETER_PROBLEM, 128 "CONNMARK target: No operation specified"); 129} 130 131static void 132print_mark(unsigned long mark) 133{ 134 printf("0x%lx", mark); 135} 136 137static void 138print_mask(const char *text, unsigned long mask) 139{ 140 if (mask != 0xffffffffUL) 141 printf("%s0x%lx", text, mask); 142} 143 144 145/* Prints out the target info. */ 146static void 147print(const void *ip, 148 const struct xt_entry_target *target, 149 int numeric) 150{ 151 const struct xt_connmark_target_info *markinfo = 152 (const struct xt_connmark_target_info *)target->data; 153 switch (markinfo->mode) { 154 case XT_CONNMARK_SET: 155 printf("CONNMARK set "); 156 print_mark(markinfo->mark); 157 print_mask("/", markinfo->mask); 158 printf(" "); 159 break; 160 case XT_CONNMARK_SAVE: 161 printf("CONNMARK save "); 162 print_mask("mask ", markinfo->mask); 163 printf(" "); 164 break; 165 case XT_CONNMARK_RESTORE: 166 printf("CONNMARK restore "); 167 print_mask("mask ", markinfo->mask); 168 break; 169 default: 170 printf("ERROR: UNKNOWN CONNMARK MODE "); 171 break; 172 } 173} 174 175/* Saves the target into in parsable form to stdout. */ 176static void 177save(const void *ip, const struct xt_entry_target *target) 178{ 179 const struct xt_connmark_target_info *markinfo = 180 (const struct xt_connmark_target_info *)target->data; 181 182 switch (markinfo->mode) { 183 case XT_CONNMARK_SET: 184 printf("--set-mark "); 185 print_mark(markinfo->mark); 186 print_mask("/", markinfo->mask); 187 printf(" "); 188 break; 189 case XT_CONNMARK_SAVE: 190 printf("--save-mark "); 191 print_mask("--mask ", markinfo->mask); 192 break; 193 case XT_CONNMARK_RESTORE: 194 printf("--restore-mark "); 195 print_mask("--mask ", markinfo->mask); 196 break; 197 default: 198 printf("ERROR: UNKNOWN CONNMARK MODE "); 199 break; 200 } 201} 202 203static struct xtables_target connmark_target = { 204 .family = AF_INET, 205 .name = "CONNMARK", 206 .version = IPTABLES_VERSION, 207 .size = XT_ALIGN(sizeof(struct xt_connmark_target_info)), 208 .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_target_info)), 209 .help = &help, 210 .init = &init, 211 .parse = &parse, 212 .final_check = &final_check, 213 .print = &print, 214 .save = &save, 215 .extra_opts = opts, 216}; 217 218static struct xtables_target connmark_target6 = { 219 .family = AF_INET6, 220 .name = "CONNMARK", 221 .version = IPTABLES_VERSION, 222 .size = XT_ALIGN(sizeof(struct xt_connmark_target_info)), 223 .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_target_info)), 224 .help = &help, 225 .init = &init, 226 .parse = &parse, 227 .final_check = &final_check, 228 .print = &print, 229 .save = &save, 230 .extra_opts = opts, 231}; 232 233void _init(void) 234{ 235 xtables_register_target(&connmark_target); 236 xtables_register_target(&connmark_target6); 237} 238