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