1a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom/* Shared library add-on to iptables to add CONNMARK target support.
2a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom *
3a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom * (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
4a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom * by Henrik Nordstrom <hno@marasystems.com>
5a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom *
6a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom * Version 1.1
7a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom *
8a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom * This program is free software; you can redistribute it and/or modify
9a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom * it under the terms of the GNU General Public License as published by
10a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom * the Free Software Foundation; either version 2 of the License, or
11a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom * (at your option) any later version.
12a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom *
13a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom * This program is distributed in the hope that it will be useful,
14a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom * but WITHOUT ANY WARRANTY; without even the implied warranty of
15a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom * GNU General Public License for more details.
17a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom *
18a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom * You should have received a copy of the GNU General Public License
19a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom * along with this program; if not, write to the Free Software
20a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom */
2232b8e61e4e5bd405d9ad07bf9468498dfbb19f9eJan Engelhardt#include <stdbool.h>
237299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt#include <stdint.h>
240e81d5db9ca61069e213236582deedb61dd38b45Harald Welte#include <stdio.h>
25f36f4a8844132cbaacf3bbd5ec0254c17fcc97aeYasuyuki KOZAKAI#include <xtables.h>
26f36f4a8844132cbaacf3bbd5ec0254c17fcc97aeYasuyuki KOZAKAI#include <linux/netfilter/xt_CONNMARK.h>
270e81d5db9ca61069e213236582deedb61dd38b45Harald Welte
28350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardtstruct xt_connmark_target_info {
29350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt	unsigned long mark;
30350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt	unsigned long mask;
317ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardt	uint8_t mode;
32350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt};
33350661a6eb089f3e54e67e022db9e16ea280499fJan Engelhardt
34ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardtenum {
357299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	O_SET_MARK = 0,
367299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	O_SAVE_MARK,
377299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	O_RESTORE_MARK,
387299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	O_AND_MARK,
397299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	O_OR_MARK,
407299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	O_XOR_MARK,
417299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	O_SET_XMARK,
427299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	O_CTMASK,
437299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	O_NFMASK,
447299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	O_MASK,
457299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	F_SET_MARK     = 1 << O_SET_MARK,
467299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	F_SAVE_MARK    = 1 << O_SAVE_MARK,
477299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	F_RESTORE_MARK = 1 << O_RESTORE_MARK,
487299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	F_AND_MARK     = 1 << O_AND_MARK,
497299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	F_OR_MARK      = 1 << O_OR_MARK,
507299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	F_XOR_MARK     = 1 << O_XOR_MARK,
517299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	F_SET_XMARK    = 1 << O_SET_XMARK,
527299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	F_CTMASK       = 1 << O_CTMASK,
537299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	F_NFMASK       = 1 << O_NFMASK,
547299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	F_MASK         = 1 << O_MASK,
557299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	F_OP_ANY       = F_SET_MARK | F_SAVE_MARK | F_RESTORE_MARK |
567299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	                 F_AND_MARK | F_OR_MARK | F_XOR_MARK | F_SET_XMARK,
570e81d5db9ca61069e213236582deedb61dd38b45Harald Welte};
580e81d5db9ca61069e213236582deedb61dd38b45Harald Welte
59932e648f38ac16b1ea14c1f66f23951388448c5aJan Engelhardtstatic void CONNMARK_help(void)
600e81d5db9ca61069e213236582deedb61dd38b45Harald Welte{
610e81d5db9ca61069e213236582deedb61dd38b45Harald Welte	printf(
628b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"CONNMARK target options:\n"
63a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom"  --set-mark value[/mask]       Set conntrack mark value\n"
64a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom"  --save-mark [--mask mask]     Save the packet nfmark in the connection\n"
658b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"  --restore-mark [--mask mask]  Restore saved nfmark value\n");
660e81d5db9ca61069e213236582deedb61dd38b45Harald Welte}
670e81d5db9ca61069e213236582deedb61dd38b45Harald Welte
687299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt#define s struct xt_connmark_target_info
697299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardtstatic const struct xt_option_entry CONNMARK_opts[] = {
707299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	{.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_MARKMASK32,
717299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	 .excl = F_OP_ANY},
727299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	{.name = "save-mark", .id = O_SAVE_MARK, .type = XTTYPE_NONE,
737299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	 .excl = F_OP_ANY},
747299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	{.name = "restore-mark", .id = O_RESTORE_MARK, .type = XTTYPE_NONE,
757299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	 .excl = F_OP_ANY},
767299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	{.name = "mask", .id = O_MASK, .type = XTTYPE_UINT32},
777299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	XTOPT_TABLEEND,
780e81d5db9ca61069e213236582deedb61dd38b45Harald Welte};
797299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt#undef s
807299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt
817299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt#define s struct xt_connmark_tginfo1
827299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardtstatic const struct xt_option_entry connmark_tg_opts[] = {
837299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	{.name = "set-xmark", .id = O_SET_XMARK, .type = XTTYPE_MARKMASK32,
847299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	 .excl = F_OP_ANY},
857299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	{.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_MARKMASK32,
867299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	 .excl = F_OP_ANY},
877299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	{.name = "and-mark", .id = O_AND_MARK, .type = XTTYPE_UINT32,
887299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	 .excl = F_OP_ANY},
897299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	{.name = "or-mark", .id = O_OR_MARK, .type = XTTYPE_UINT32,
907299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	 .excl = F_OP_ANY},
917299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	{.name = "xor-mark", .id = O_XOR_MARK, .type = XTTYPE_UINT32,
927299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	 .excl = F_OP_ANY},
937299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	{.name = "save-mark", .id = O_SAVE_MARK, .type = XTTYPE_NONE,
947299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	 .excl = F_OP_ANY},
957299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	{.name = "restore-mark", .id = O_RESTORE_MARK, .type = XTTYPE_NONE,
967299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	 .excl = F_OP_ANY},
977299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	{.name = "ctmask", .id = O_CTMASK, .type = XTTYPE_UINT32,
987299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	 .excl = F_MASK, .flags = XTOPT_PUT, XTOPT_POINTER(s, ctmask)},
997299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	{.name = "nfmask", .id = O_NFMASK, .type = XTTYPE_UINT32,
1007299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	 .excl = F_MASK, .flags = XTOPT_PUT, XTOPT_POINTER(s, nfmask)},
1017299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	{.name = "mask", .id = O_MASK, .type = XTTYPE_UINT32,
1027299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	 .excl = F_CTMASK | F_NFMASK},
1037299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	XTOPT_TABLEEND,
104ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt};
1057299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt#undef s
106ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt
107ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardtstatic void connmark_tg_help(void)
108ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt{
109ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	printf(
110ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt"CONNMARK target options:\n"
111ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt"  --set-xmark value[/ctmask]    Zero mask bits and XOR ctmark with value\n"
112ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt"  --save-mark [--ctmask mask] [--nfmask mask]\n"
113ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt"                                Copy ctmark to nfmark using masks\n"
114ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt"  --restore-mark [--ctmask mask] [--nfmask mask]\n"
115ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt"                                Copy nfmark to ctmark using masks\n"
116ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt"  --set-mark value[/mask]       Set conntrack mark value\n"
117ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt"  --save-mark [--mask mask]     Save the packet nfmark in the connection\n"
118ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt"  --restore-mark [--mask mask]  Restore saved nfmark value\n"
119ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt"  --and-mark value              Binary AND the ctmark with bits\n"
120ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt"  --or-mark value               Binary OR  the ctmark with bits\n"
121ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt"  --xor-mark value              Binary XOR the ctmark with bits\n"
122ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt);
123ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt}
124ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt
125ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardtstatic void connmark_tg_init(struct xt_entry_target *target)
126ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt{
127ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	struct xt_connmark_tginfo1 *info = (void *)target->data;
128ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt
129ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	/*
130ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	 * Need these defaults for --save-mark/--restore-mark if no
131ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	 * --ctmark or --nfmask is given.
132ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	 */
133a80975497968e69b23f56bf15d346c65bec381f2Jan Engelhardt	info->ctmask = UINT32_MAX;
134a80975497968e69b23f56bf15d346c65bec381f2Jan Engelhardt	info->nfmask = UINT32_MAX;
135ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt}
136ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt
1377299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardtstatic void CONNMARK_parse(struct xt_option_call *cb)
1380e81d5db9ca61069e213236582deedb61dd38b45Harald Welte{
1397299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	struct xt_connmark_target_info *markinfo = cb->data;
1400e81d5db9ca61069e213236582deedb61dd38b45Harald Welte
1417299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	xtables_option_parse(cb);
1427299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	switch (cb->entry->id) {
1437299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	case O_SET_MARK:
144f36f4a8844132cbaacf3bbd5ec0254c17fcc97aeYasuyuki KOZAKAI		markinfo->mode = XT_CONNMARK_SET;
1457299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		markinfo->mark = cb->val.mark;
1467299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		markinfo->mask = cb->val.mask;
1470e81d5db9ca61069e213236582deedb61dd38b45Harald Welte		break;
1487299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	case O_SAVE_MARK:
149f36f4a8844132cbaacf3bbd5ec0254c17fcc97aeYasuyuki KOZAKAI		markinfo->mode = XT_CONNMARK_SAVE;
1500e81d5db9ca61069e213236582deedb61dd38b45Harald Welte		break;
1517299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	case O_RESTORE_MARK:
152f36f4a8844132cbaacf3bbd5ec0254c17fcc97aeYasuyuki KOZAKAI		markinfo->mode = XT_CONNMARK_RESTORE;
1530e81d5db9ca61069e213236582deedb61dd38b45Harald Welte		break;
1547299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	case O_MASK:
1557299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		markinfo->mask = cb->val.u32;
156a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom		break;
1570e81d5db9ca61069e213236582deedb61dd38b45Harald Welte	}
1580e81d5db9ca61069e213236582deedb61dd38b45Harald Welte}
1590e81d5db9ca61069e213236582deedb61dd38b45Harald Welte
1607299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardtstatic void connmark_tg_parse(struct xt_option_call *cb)
161ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt{
1627299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	struct xt_connmark_tginfo1 *info = cb->data;
163ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt
1647299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	xtables_option_parse(cb);
1657299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	switch (cb->entry->id) {
1667299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	case O_SET_XMARK:
167ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		info->mode   = XT_CONNMARK_SET;
1687299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		info->ctmark = cb->val.mark;
1697299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		info->ctmask = cb->val.mask;
1707299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		break;
1717299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	case O_SET_MARK:
1727299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		info->mode   = XT_CONNMARK_SET;
1737299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		info->ctmark = cb->val.mark;
1747299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		info->ctmask = cb->val.mark | cb->val.mask;
1757299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		break;
1767299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	case O_AND_MARK:
177ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		info->mode   = XT_CONNMARK_SET;
178ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		info->ctmark = 0;
1797299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		info->ctmask = ~cb->val.u32;
1807299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		break;
1817299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	case O_OR_MARK:
182ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		info->mode   = XT_CONNMARK_SET;
1837299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		info->ctmark = cb->val.u32;
1847299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		info->ctmask = cb->val.u32;
1857299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		break;
1867299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	case O_XOR_MARK:
187ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		info->mode   = XT_CONNMARK_SET;
1887299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		info->ctmark = cb->val.u32;
189ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		info->ctmask = 0;
1907299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		break;
1917299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	case O_SAVE_MARK:
192ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		info->mode = XT_CONNMARK_SAVE;
1937299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		break;
1947299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	case O_RESTORE_MARK:
195ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		info->mode = XT_CONNMARK_RESTORE;
1967299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		break;
1977299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	case O_MASK:
1987299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		info->nfmask = info->ctmask = cb->val.u32;
1997299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		break;
200ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	}
201ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt}
202ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt
2037299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardtstatic void connmark_tg_check(struct xt_fcheck_call *cb)
2040e81d5db9ca61069e213236582deedb61dd38b45Harald Welte{
2057299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt	if (!(cb->xflags & F_OP_ANY))
2061829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM,
207a6ef99487b05ac5f358cb58d9448e28ac5f38b30Henrik Nordstrom		           "CONNMARK target: No operation specified");
2080e81d5db9ca61069e213236582deedb61dd38b45Harald Welte}
2090e81d5db9ca61069e213236582deedb61dd38b45Harald Welte
21002964b869a8616b41e4c2dc899ff23921aaaa4b0Martin Josefssonstatic void
21102964b869a8616b41e4c2dc899ff23921aaaa4b0Martin Josefssonprint_mark(unsigned long mark)
21202964b869a8616b41e4c2dc899ff23921aaaa4b0Martin Josefsson{
21302964b869a8616b41e4c2dc899ff23921aaaa4b0Martin Josefsson	printf("0x%lx", mark);
21402964b869a8616b41e4c2dc899ff23921aaaa4b0Martin Josefsson}
21502964b869a8616b41e4c2dc899ff23921aaaa4b0Martin Josefsson
21602964b869a8616b41e4c2dc899ff23921aaaa4b0Martin Josefssonstatic void
21702964b869a8616b41e4c2dc899ff23921aaaa4b0Martin Josefssonprint_mask(const char *text, unsigned long mask)
21802964b869a8616b41e4c2dc899ff23921aaaa4b0Martin Josefsson{
219361bac2f2c25ecabef125c6a8bb8dfc194bf73f1Deti Fliegl	if (mask != 0xffffffffUL)
220f3aa491a54847fbbaae0858d00e5e4c0986c1d7bTom Eastep		printf("%s0x%lx", text, mask);
22102964b869a8616b41e4c2dc899ff23921aaaa4b0Martin Josefsson}
22202964b869a8616b41e4c2dc899ff23921aaaa4b0Martin Josefsson
223932e648f38ac16b1ea14c1f66f23951388448c5aJan Engelhardtstatic void CONNMARK_print(const void *ip,
224932e648f38ac16b1ea14c1f66f23951388448c5aJan Engelhardt                           const struct xt_entry_target *target, int numeric)
2250e81d5db9ca61069e213236582deedb61dd38b45Harald Welte{
226f36f4a8844132cbaacf3bbd5ec0254c17fcc97aeYasuyuki KOZAKAI	const struct xt_connmark_target_info *markinfo =
227f36f4a8844132cbaacf3bbd5ec0254c17fcc97aeYasuyuki KOZAKAI		(const struct xt_connmark_target_info *)target->data;
2280e81d5db9ca61069e213236582deedb61dd38b45Harald Welte	switch (markinfo->mode) {
229f36f4a8844132cbaacf3bbd5ec0254c17fcc97aeYasuyuki KOZAKAI	case XT_CONNMARK_SET:
23073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	    printf(" CONNMARK set ");
23102964b869a8616b41e4c2dc899ff23921aaaa4b0Martin Josefsson	    print_mark(markinfo->mark);
23202964b869a8616b41e4c2dc899ff23921aaaa4b0Martin Josefsson	    print_mask("/", markinfo->mask);
2330e81d5db9ca61069e213236582deedb61dd38b45Harald Welte	    break;
234f36f4a8844132cbaacf3bbd5ec0254c17fcc97aeYasuyuki KOZAKAI	case XT_CONNMARK_SAVE:
23573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	    printf(" CONNMARK save ");
23602964b869a8616b41e4c2dc899ff23921aaaa4b0Martin Josefsson	    print_mask("mask ", markinfo->mask);
2370e81d5db9ca61069e213236582deedb61dd38b45Harald Welte	    break;
238f36f4a8844132cbaacf3bbd5ec0254c17fcc97aeYasuyuki KOZAKAI	case XT_CONNMARK_RESTORE:
23973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	    printf(" CONNMARK restore ");
24002964b869a8616b41e4c2dc899ff23921aaaa4b0Martin Josefsson	    print_mask("mask ", markinfo->mask);
2410e81d5db9ca61069e213236582deedb61dd38b45Harald Welte	    break;
2420e81d5db9ca61069e213236582deedb61dd38b45Harald Welte	default:
24373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	    printf(" ERROR: UNKNOWN CONNMARK MODE");
2440e81d5db9ca61069e213236582deedb61dd38b45Harald Welte	    break;
2450e81d5db9ca61069e213236582deedb61dd38b45Harald Welte	}
2460e81d5db9ca61069e213236582deedb61dd38b45Harald Welte}
2470e81d5db9ca61069e213236582deedb61dd38b45Harald Welte
248ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardtstatic void
249ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardtconnmark_tg_print(const void *ip, const struct xt_entry_target *target,
250ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt                  int numeric)
251ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt{
252ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	const struct xt_connmark_tginfo1 *info = (const void *)target->data;
253ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt
254ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	switch (info->mode) {
255ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	case XT_CONNMARK_SET:
256ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		if (info->ctmark == 0)
25773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" CONNMARK and 0x%x",
2587ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardt			       (unsigned int)(uint32_t)~info->ctmask);
259ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		else if (info->ctmark == info->ctmask)
26073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" CONNMARK or 0x%x", info->ctmark);
261ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		else if (info->ctmask == 0)
26273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" CONNMARK xor 0x%x", info->ctmark);
2635fdf032a02b671bc1a18cec0e803c17c64175ab1Jan Engelhardt		else if (info->ctmask == 0xFFFFFFFFU)
26473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" CONNMARK set 0x%x", info->ctmark);
265ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		else
26673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" CONNMARK xset 0x%x/0x%x",
267ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt			       info->ctmark, info->ctmask);
268ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		break;
269ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	case XT_CONNMARK_SAVE:
270a80975497968e69b23f56bf15d346c65bec381f2Jan Engelhardt		if (info->nfmask == UINT32_MAX && info->ctmask == UINT32_MAX)
27173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" CONNMARK save");
272ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		else if (info->nfmask == info->ctmask)
27373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" CONNMARK save mask 0x%x", info->nfmask);
274ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		else
27573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" CONNMARK save nfmask 0x%x ctmask ~0x%x",
276ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt			       info->nfmask, info->ctmask);
277ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		break;
278ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	case XT_CONNMARK_RESTORE:
279a80975497968e69b23f56bf15d346c65bec381f2Jan Engelhardt		if (info->ctmask == UINT32_MAX && info->nfmask == UINT32_MAX)
28073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" CONNMARK restore");
281ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		else if (info->ctmask == info->nfmask)
28273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" CONNMARK restore mask 0x%x", info->ctmask);
283ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		else
28473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf(" CONNMARK restore ctmask 0x%x nfmask ~0x%x",
285ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt			       info->ctmask, info->nfmask);
286ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		break;
287ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt
288ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	default:
28973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" ERROR: UNKNOWN CONNMARK MODE");
290ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		break;
291ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	}
292ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt}
293ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt
294932e648f38ac16b1ea14c1f66f23951388448c5aJan Engelhardtstatic void CONNMARK_save(const void *ip, const struct xt_entry_target *target)
2950e81d5db9ca61069e213236582deedb61dd38b45Harald Welte{
296f36f4a8844132cbaacf3bbd5ec0254c17fcc97aeYasuyuki KOZAKAI	const struct xt_connmark_target_info *markinfo =
297f36f4a8844132cbaacf3bbd5ec0254c17fcc97aeYasuyuki KOZAKAI		(const struct xt_connmark_target_info *)target->data;
2980e81d5db9ca61069e213236582deedb61dd38b45Harald Welte
2990e81d5db9ca61069e213236582deedb61dd38b45Harald Welte	switch (markinfo->mode) {
300f36f4a8844132cbaacf3bbd5ec0254c17fcc97aeYasuyuki KOZAKAI	case XT_CONNMARK_SET:
30173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	    printf(" --set-mark ");
30202964b869a8616b41e4c2dc899ff23921aaaa4b0Martin Josefsson	    print_mark(markinfo->mark);
30302964b869a8616b41e4c2dc899ff23921aaaa4b0Martin Josefsson	    print_mask("/", markinfo->mask);
3040e81d5db9ca61069e213236582deedb61dd38b45Harald Welte	    break;
305f36f4a8844132cbaacf3bbd5ec0254c17fcc97aeYasuyuki KOZAKAI	case XT_CONNMARK_SAVE:
30673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	    printf(" --save-mark ");
30702964b869a8616b41e4c2dc899ff23921aaaa4b0Martin Josefsson	    print_mask("--mask ", markinfo->mask);
3080e81d5db9ca61069e213236582deedb61dd38b45Harald Welte	    break;
309f36f4a8844132cbaacf3bbd5ec0254c17fcc97aeYasuyuki KOZAKAI	case XT_CONNMARK_RESTORE:
31073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	    printf(" --restore-mark ");
31102964b869a8616b41e4c2dc899ff23921aaaa4b0Martin Josefsson	    print_mask("--mask ", markinfo->mask);
3120e81d5db9ca61069e213236582deedb61dd38b45Harald Welte	    break;
3130e81d5db9ca61069e213236582deedb61dd38b45Harald Welte	default:
31473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	    printf(" ERROR: UNKNOWN CONNMARK MODE");
3150e81d5db9ca61069e213236582deedb61dd38b45Harald Welte	    break;
3160e81d5db9ca61069e213236582deedb61dd38b45Harald Welte	}
3170e81d5db9ca61069e213236582deedb61dd38b45Harald Welte}
3180e81d5db9ca61069e213236582deedb61dd38b45Harald Welte
3192c3ce6ad598cb479640f6f14c7c5e25488923062Peter Warasinstatic void CONNMARK_init(struct xt_entry_target *t)
3202c3ce6ad598cb479640f6f14c7c5e25488923062Peter Warasin{
3212c3ce6ad598cb479640f6f14c7c5e25488923062Peter Warasin	struct xt_connmark_target_info *markinfo
3222c3ce6ad598cb479640f6f14c7c5e25488923062Peter Warasin		= (struct xt_connmark_target_info *)t->data;
3232c3ce6ad598cb479640f6f14c7c5e25488923062Peter Warasin
3242c3ce6ad598cb479640f6f14c7c5e25488923062Peter Warasin	markinfo->mask = 0xffffffffUL;
3252c3ce6ad598cb479640f6f14c7c5e25488923062Peter Warasin}
3262c3ce6ad598cb479640f6f14c7c5e25488923062Peter Warasin
327ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardtstatic void
328ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardtconnmark_tg_save(const void *ip, const struct xt_entry_target *target)
329ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt{
330ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	const struct xt_connmark_tginfo1 *info = (const void *)target->data;
331ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt
332ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	switch (info->mode) {
333ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	case XT_CONNMARK_SET:
33473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" --set-xmark 0x%x/0x%x", info->ctmark, info->ctmask);
335ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		break;
336ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	case XT_CONNMARK_SAVE:
33773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" --save-mark --nfmask 0x%x --ctmask 0x%x",
338ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		       info->nfmask, info->ctmask);
339ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		break;
340ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	case XT_CONNMARK_RESTORE:
34173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" --restore-mark --nfmask 0x%x --ctmask 0x%x",
342ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		       info->nfmask, info->ctmask);
343ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		break;
344ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	default:
34573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" ERROR: UNKNOWN CONNMARK MODE");
346ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt		break;
347ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt	}
348ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt}
349ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt
350f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardtstatic struct xtables_target connmark_tg_reg[] = {
351f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	{
352f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.family        = NFPROTO_UNSPEC,
353f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.name          = "CONNMARK",
354f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.revision      = 0,
355f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.version       = XTABLES_VERSION,
356f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.size          = XT_ALIGN(sizeof(struct xt_connmark_target_info)),
357f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.userspacesize = XT_ALIGN(sizeof(struct xt_connmark_target_info)),
358f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.help          = CONNMARK_help,
359f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.init          = CONNMARK_init,
360f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.print         = CONNMARK_print,
361f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.save          = CONNMARK_save,
3627299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		.x6_parse      = CONNMARK_parse,
3637299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		.x6_fcheck     = connmark_tg_check,
3647299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		.x6_options    = CONNMARK_opts,
365f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	},
366f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	{
367f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.version       = XTABLES_VERSION,
368f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.name          = "CONNMARK",
369f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.revision      = 1,
370f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.family        = NFPROTO_UNSPEC,
371f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.size          = XT_ALIGN(sizeof(struct xt_connmark_tginfo1)),
372f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.userspacesize = XT_ALIGN(sizeof(struct xt_connmark_tginfo1)),
373f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.help          = connmark_tg_help,
374f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.init          = connmark_tg_init,
375f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.print         = connmark_tg_print,
376f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt		.save          = connmark_tg_save,
3777299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		.x6_parse      = connmark_tg_parse,
3787299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		.x6_fcheck     = connmark_tg_check,
3797299fa4b615d7f7ee12cde444266f6b31f667f9fJan Engelhardt		.x6_options    = connmark_tg_opts,
380f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	},
381ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt};
382ff068719055ae2327d94c79048381c09d3b744c4Jan Engelhardt
3830e81d5db9ca61069e213236582deedb61dd38b45Harald Weltevoid _init(void)
3840e81d5db9ca61069e213236582deedb61dd38b45Harald Welte{
385f2a77520693f0a6dd1df1f87be4b81913961c1f5Jan Engelhardt	xtables_register_targets(connmark_tg_reg, ARRAY_SIZE(connmark_tg_reg));
3860e81d5db9ca61069e213236582deedb61dd38b45Harald Welte}
387