libxt_connmark.c revision 181dead3f13befe02769ef479bcbb51801b7fc4e
1469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte/* Shared library add-on to iptables to add connmark matching support. 2469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * 3469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> 4469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * by Henrik Nordstrom <hno@marasystems.com> 5469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * 6469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * Version 1.1 7469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * 8469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * This program is free software; you can redistribute it and/or modify 9469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * it under the terms of the GNU General Public License as published by 10469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * the Free Software Foundation; either version 2 of the License, or 11469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * (at your option) any later version. 12469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * 13469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * This program is distributed in the hope that it will be useful, 14469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * but WITHOUT ANY WARRANTY; without even the implied warranty of 15469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * GNU General Public License for more details. 17469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * 18469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * You should have received a copy of the GNU General Public License 19469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * along with this program; if not, write to the Free Software 20469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte */ 22469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte#include <stdio.h> 23469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte#include <netdb.h> 24469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte#include <string.h> 25469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte#include <stdlib.h> 26469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte#include <getopt.h> 27469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 28c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI#include <xtables.h> 29c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI#include <linux/netfilter/xt_connmark.h> 30469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 31469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte/* Function which prints out usage message. */ 32181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void connmark_help(void) 33469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte{ 34469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte printf( 35469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte"CONNMARK match v%s options:\n" 36469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte"[!] --mark value[/mask] Match nfmark value with optional mask\n" 37469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte"\n", 38469d18f66896ef509cac5a2ade494ea38e0c86e2Harald WelteIPTABLES_VERSION); 39469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte} 40469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 41181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic const struct option connmark_opts[] = { 42500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy { "mark", 1, NULL, '1' }, 43500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy { } 44469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte}; 45469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 46469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte/* Function which parses command options; returns true if it 47469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte ate an option */ 48469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Weltestatic int 49181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtconnmark_parse(int c, char **argv, int invert, unsigned int *flags, 50181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt const void *entry, struct xt_entry_match **match) 51469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte{ 52c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI struct xt_connmark_info *markinfo = (struct xt_connmark_info *)(*match)->data; 53469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 54469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte switch (c) { 55469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte char *end; 56469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte case '1': 57469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte check_inverse(optarg, &invert, &optind, 0); 58469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 59469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte markinfo->mark = strtoul(optarg, &end, 0); 60469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte markinfo->mask = 0xffffffffUL; 61469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 62469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte if (*end == '/') 63469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte markinfo->mask = strtoul(end+1, &end, 0); 64469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 65469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte if (*end != '\0' || end == optarg) 66469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg); 67469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte if (invert) 68469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte markinfo->invert = 1; 69469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte *flags = 1; 70469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte break; 71469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 72469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte default: 73469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte return 0; 74469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte } 75469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte return 1; 76469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte} 77469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 78469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Weltestatic void 79469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welteprint_mark(unsigned long mark, unsigned long mask, int numeric) 80469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte{ 81469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte if(mask != 0xffffffffUL) 82469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte printf("0x%lx/0x%lx ", mark, mask); 83469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte else 84469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte printf("0x%lx ", mark); 85469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte} 86469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 87469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte/* Final check; must have specified --mark. */ 88181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void connmark_check(unsigned int flags) 89469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte{ 90469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte if (!flags) 91469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte exit_error(PARAMETER_PROBLEM, 92469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte "MARK match: You must specify `--mark'"); 93469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte} 94469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 95469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte/* Prints out the matchinfo. */ 96469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Weltestatic void 97181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtconnmark_print(const void *ip, const struct xt_entry_match *match, int numeric) 98469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte{ 99c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI struct xt_connmark_info *info = (struct xt_connmark_info *)match->data; 100469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 101469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte printf("CONNMARK match "); 102469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte if (info->invert) 103469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte printf("!"); 104469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte print_mark(info->mark, info->mask, numeric); 105469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte} 106469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 107469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte/* Saves the matchinfo in parsable form to stdout. */ 108181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void connmark_save(const void *ip, const struct xt_entry_match *match) 109469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte{ 110c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI struct xt_connmark_info *info = (struct xt_connmark_info *)match->data; 111469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 112469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte if (info->invert) 113469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte printf("! "); 114469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 115469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte printf("--mark "); 116469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte print_mark(info->mark, info->mask, 0); 117469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte} 118469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 119c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAIstatic struct xtables_match connmark_match = { 120c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI .family = AF_INET, 121c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI .name = "connmark", 122c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI .version = IPTABLES_VERSION, 123c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI .size = XT_ALIGN(sizeof(struct xt_connmark_info)), 124c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_info)), 125181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .help = connmark_help, 126181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .parse = connmark_parse, 127181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .final_check = connmark_check, 128181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .print = connmark_print, 129181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .save = connmark_save, 130181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .extra_opts = connmark_opts, 131c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI}; 132c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI 133c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAIstatic struct xtables_match connmark_match6 = { 134c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI .family = AF_INET6, 135c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI .name = "connmark", 136c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI .version = IPTABLES_VERSION, 137c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI .size = XT_ALIGN(sizeof(struct xt_connmark_info)), 138c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_info)), 139181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .help = connmark_help, 140181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .parse = connmark_parse, 141181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .final_check = connmark_check, 142181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .print = connmark_print, 143181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .save = connmark_save, 144181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt .extra_opts = connmark_opts, 145469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte}; 146469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte 147469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Weltevoid _init(void) 148469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte{ 149c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI xtables_register_match(&connmark_match); 150c57c155312a544482a6b8a3c0f7224b00cfaae20Yasuyuki KOZAKAI xtables_register_match(&connmark_match6); 151469d18f66896ef509cac5a2ade494ea38e0c86e2Harald Welte} 152