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