1 /* ebt_mark
2  *
3  * Authors:
4  * Bart De Schuymer <bdschuym@pandora.be>
5  *
6  * July, 2002, September 2006
7  *
8  * Adapted by Arturo Borrero Gonzalez <arturo@debian.org>
9  * to use libxtables for ebtables-compat in 2015.
10  */
11 
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <getopt.h>
16 #include <xtables.h>
17 #include <linux/netfilter_bridge/ebt_mark_t.h>
18 #include "iptables/nft.h"
19 #include "iptables/nft-bridge.h"
20 
21 static int mark_supplied;
22 
23 #define MARK_TARGET  '1'
24 #define MARK_SETMARK '2'
25 #define MARK_ORMARK  '3'
26 #define MARK_ANDMARK '4'
27 #define MARK_XORMARK '5'
28 static struct option brmark_opts[] = {
29 	{ .name = "mark-target",.has_arg = true,	.val = MARK_TARGET },
30 	/* an oldtime messup, we should have always used the scheme
31 	 * <extension-name>-<option> */
32 	{ .name = "set-mark",	.has_arg = true,	.val = MARK_SETMARK },
33 	{ .name = "mark-set",	.has_arg = true,	.val = MARK_SETMARK },
34 	{ .name = "mark-or",	.has_arg = true,	.val = MARK_ORMARK },
35 	{ .name = "mark-and",	.has_arg = true,	.val = MARK_ANDMARK },
36 	{ .name = "mark-xor",	.has_arg = true,	.val = MARK_XORMARK },
37 	XT_GETOPT_TABLEEND,
38 };
39 
brmark_print_help(void)40 static void brmark_print_help(void)
41 {
42 	printf(
43 	"mark target options:\n"
44 	" --mark-set value     : Set nfmark value\n"
45 	" --mark-or  value     : Or nfmark with value (nfmark |= value)\n"
46 	" --mark-and value     : And nfmark with value (nfmark &= value)\n"
47 	" --mark-xor value     : Xor nfmark with value (nfmark ^= value)\n"
48 	" --mark-target target : ACCEPT, DROP, RETURN or CONTINUE\n");
49 }
50 
brmark_init(struct xt_entry_target * target)51 static void brmark_init(struct xt_entry_target *target)
52 {
53 	struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)target->data;
54 
55 	info->target = EBT_ACCEPT;
56 	info->mark = 0;
57 	mark_supplied = 0;
58 }
59 
60 #define OPT_MARK_TARGET   0x01
61 #define OPT_MARK_SETMARK  0x02
62 #define OPT_MARK_ORMARK   0x04
63 #define OPT_MARK_ANDMARK  0x08
64 #define OPT_MARK_XORMARK  0x10
65 
66 static int
brmark_parse(int c,char ** argv,int invert,unsigned int * flags,const void * entry,struct xt_entry_target ** target)67 brmark_parse(int c, char **argv, int invert, unsigned int *flags,
68 	     const void *entry, struct xt_entry_target **target)
69 {
70 	struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)
71 				       (*target)->data;
72 	char *end;
73 	uint32_t mask;
74 
75 	switch (c) {
76 	case MARK_TARGET:
77 		{ unsigned int tmp;
78 		EBT_CHECK_OPTION(flags, OPT_MARK_TARGET);
79 		if (ebt_fill_target(optarg, &tmp))
80 			xtables_error(PARAMETER_PROBLEM,
81 				      "Illegal --mark-target target");
82 		/* the 4 lsb are left to designate the target */
83 		info->target = (info->target & ~EBT_VERDICT_BITS) |
84 			       (tmp & EBT_VERDICT_BITS);
85 		}
86 		return 1;
87 	case MARK_SETMARK:
88 		EBT_CHECK_OPTION(flags, OPT_MARK_SETMARK);
89 		mask = (OPT_MARK_ORMARK|OPT_MARK_ANDMARK|OPT_MARK_XORMARK);
90 		if (*flags & mask)
91 			xtables_error(PARAMETER_PROBLEM,
92 				      "--mark-set cannot be used together with"
93 				      " specific --mark option");
94 		info->target = (info->target & EBT_VERDICT_BITS) |
95 			       MARK_SET_VALUE;
96 		break;
97 	case MARK_ORMARK:
98 		EBT_CHECK_OPTION(flags, OPT_MARK_ORMARK);
99 		mask = (OPT_MARK_SETMARK|OPT_MARK_ANDMARK|OPT_MARK_XORMARK);
100 		if (*flags & mask)
101 			xtables_error(PARAMETER_PROBLEM,
102 				      "--mark-or cannot be used together with"
103 				      " specific --mark option");
104 		info->target = (info->target & EBT_VERDICT_BITS) |
105 			       MARK_OR_VALUE;
106 		break;
107 	case MARK_ANDMARK:
108 		EBT_CHECK_OPTION(flags, OPT_MARK_ANDMARK);
109 		mask = (OPT_MARK_SETMARK|OPT_MARK_ORMARK|OPT_MARK_XORMARK);
110 		if (*flags & mask)
111 			xtables_error(PARAMETER_PROBLEM,
112 				      "--mark-and cannot be used together with"
113 				      " specific --mark option");
114 		info->target = (info->target & EBT_VERDICT_BITS) |
115 			       MARK_AND_VALUE;
116 		break;
117 	case MARK_XORMARK:
118 		EBT_CHECK_OPTION(flags, OPT_MARK_XORMARK);
119 		mask = (OPT_MARK_SETMARK|OPT_MARK_ANDMARK|OPT_MARK_ORMARK);
120 		if (*flags & mask)
121 			xtables_error(PARAMETER_PROBLEM,
122 				      "--mark-xor cannot be used together with"
123 				      " specific --mark option");
124 		info->target = (info->target & EBT_VERDICT_BITS) |
125 			       MARK_XOR_VALUE;
126 		break;
127 	default:
128 		return 0;
129 	}
130 	/* mutual code */
131 	info->mark = strtoul(optarg, &end, 0);
132 	if (*end != '\0' || end == optarg)
133 		xtables_error(PARAMETER_PROBLEM, "Bad MARK value '%s'",
134 			      optarg);
135 
136 	mark_supplied = 1;
137 	return 1;
138 }
139 
brmark_print(const void * ip,const struct xt_entry_target * target,int numeric)140 static void brmark_print(const void *ip, const struct xt_entry_target *target,
141 			 int numeric)
142 {
143 	struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)target->data;
144 	int tmp;
145 
146 	tmp = info->target & ~EBT_VERDICT_BITS;
147 	if (tmp == MARK_SET_VALUE)
148 		printf("--mark-set");
149 	else if (tmp == MARK_OR_VALUE)
150 		printf("--mark-or");
151 	else if (tmp == MARK_XOR_VALUE)
152 		printf("--mark-xor");
153 	else if (tmp == MARK_AND_VALUE)
154 		printf("--mark-and");
155 	else
156 		xtables_error(PARAMETER_PROBLEM, "Unknown mark action");
157 
158 	printf(" 0x%lx", info->mark);
159 	tmp = info->target | ~EBT_VERDICT_BITS;
160 	printf(" --mark-target %s", ebt_target_name(tmp));
161 }
162 
brmark_final_check(unsigned int flags)163 static void brmark_final_check(unsigned int flags)
164 {
165 	if (mark_supplied == 0)
166 		xtables_error(PARAMETER_PROBLEM, "No mark value supplied");
167 
168 	if (!flags)
169 		xtables_error(PARAMETER_PROBLEM,
170 			      "You must specify some option");
171 }
172 
173 static struct xtables_target brmark_target = {
174 	.name		= "mark",
175 	.revision	= 0,
176 	.version	= XTABLES_VERSION,
177 	.family		= NFPROTO_BRIDGE,
178 	.size		= XT_ALIGN(sizeof(struct ebt_mark_t_info)),
179 	.userspacesize	= XT_ALIGN(sizeof(struct ebt_mark_t_info)),
180 	.help		= brmark_print_help,
181 	.init		= brmark_init,
182 	.parse		= brmark_parse,
183 	.final_check	= brmark_final_check,
184 	.print		= brmark_print,
185 	.extra_opts	= brmark_opts,
186 };
187 
_init(void)188 void _init(void)
189 {
190 	xtables_register_target(&brmark_target);
191 }
192