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