• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define MARK_TARGET  '1'
22 #define MARK_SETMARK '2'
23 #define MARK_ORMARK  '3'
24 #define MARK_ANDMARK '4'
25 #define MARK_XORMARK '5'
26 static const struct option brmark_opts[] = {
27 	{ .name = "mark-target",.has_arg = true,	.val = MARK_TARGET },
28 	/* an oldtime messup, we should have always used the scheme
29 	 * <extension-name>-<option> */
30 	{ .name = "set-mark",	.has_arg = true,	.val = MARK_SETMARK },
31 	{ .name = "mark-set",	.has_arg = true,	.val = MARK_SETMARK },
32 	{ .name = "mark-or",	.has_arg = true,	.val = MARK_ORMARK },
33 	{ .name = "mark-and",	.has_arg = true,	.val = MARK_ANDMARK },
34 	{ .name = "mark-xor",	.has_arg = true,	.val = MARK_XORMARK },
35 	XT_GETOPT_TABLEEND,
36 };
37 
brmark_print_help(void)38 static void brmark_print_help(void)
39 {
40 	printf(
41 	"mark target options:\n"
42 	" --mark-set value     : Set nfmark value\n"
43 	" --mark-or  value     : Or nfmark with value (nfmark |= value)\n"
44 	" --mark-and value     : And nfmark with value (nfmark &= value)\n"
45 	" --mark-xor value     : Xor nfmark with value (nfmark ^= value)\n"
46 	" --mark-target target : ACCEPT, DROP, RETURN or CONTINUE\n");
47 }
48 
brmark_init(struct xt_entry_target * target)49 static void brmark_init(struct xt_entry_target *target)
50 {
51 	struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)target->data;
52 
53 	info->target = EBT_ACCEPT;
54 	info->mark = 0;
55 }
56 
57 #define OPT_MARK_TARGET   0x01
58 #define OPT_MARK_SETMARK  0x02
59 #define OPT_MARK_ORMARK   0x04
60 #define OPT_MARK_ANDMARK  0x08
61 #define OPT_MARK_XORMARK  0x10
62 
63 static int
brmark_parse(int c,char ** argv,int invert,unsigned int * flags,const void * entry,struct xt_entry_target ** target)64 brmark_parse(int c, char **argv, int invert, unsigned int *flags,
65 	     const void *entry, struct xt_entry_target **target)
66 {
67 	struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)
68 				       (*target)->data;
69 	char *end;
70 	uint32_t mask;
71 
72 	switch (c) {
73 	case MARK_TARGET:
74 		{ unsigned int tmp;
75 		EBT_CHECK_OPTION(flags, OPT_MARK_TARGET);
76 		if (ebt_fill_target(optarg, &tmp))
77 			xtables_error(PARAMETER_PROBLEM,
78 				      "Illegal --mark-target target");
79 		/* the 4 lsb are left to designate the target */
80 		info->target = (info->target & ~EBT_VERDICT_BITS) |
81 			       (tmp & EBT_VERDICT_BITS);
82 		}
83 		return 1;
84 	case MARK_SETMARK:
85 		EBT_CHECK_OPTION(flags, OPT_MARK_SETMARK);
86 		mask = (OPT_MARK_ORMARK|OPT_MARK_ANDMARK|OPT_MARK_XORMARK);
87 		if (*flags & mask)
88 			xtables_error(PARAMETER_PROBLEM,
89 				      "--mark-set cannot be used together with"
90 				      " specific --mark option");
91 		info->target = (info->target & EBT_VERDICT_BITS) |
92 			       MARK_SET_VALUE;
93 		break;
94 	case MARK_ORMARK:
95 		EBT_CHECK_OPTION(flags, OPT_MARK_ORMARK);
96 		mask = (OPT_MARK_SETMARK|OPT_MARK_ANDMARK|OPT_MARK_XORMARK);
97 		if (*flags & mask)
98 			xtables_error(PARAMETER_PROBLEM,
99 				      "--mark-or cannot be used together with"
100 				      " specific --mark option");
101 		info->target = (info->target & EBT_VERDICT_BITS) |
102 			       MARK_OR_VALUE;
103 		break;
104 	case MARK_ANDMARK:
105 		EBT_CHECK_OPTION(flags, OPT_MARK_ANDMARK);
106 		mask = (OPT_MARK_SETMARK|OPT_MARK_ORMARK|OPT_MARK_XORMARK);
107 		if (*flags & mask)
108 			xtables_error(PARAMETER_PROBLEM,
109 				      "--mark-and cannot be used together with"
110 				      " specific --mark option");
111 		info->target = (info->target & EBT_VERDICT_BITS) |
112 			       MARK_AND_VALUE;
113 		break;
114 	case MARK_XORMARK:
115 		EBT_CHECK_OPTION(flags, OPT_MARK_XORMARK);
116 		mask = (OPT_MARK_SETMARK|OPT_MARK_ANDMARK|OPT_MARK_ORMARK);
117 		if (*flags & mask)
118 			xtables_error(PARAMETER_PROBLEM,
119 				      "--mark-xor cannot be used together with"
120 				      " specific --mark option");
121 		info->target = (info->target & EBT_VERDICT_BITS) |
122 			       MARK_XOR_VALUE;
123 		break;
124 	default:
125 		return 0;
126 	}
127 	/* mutual code */
128 	info->mark = strtoul(optarg, &end, 0);
129 	if (*end != '\0' || end == optarg)
130 		xtables_error(PARAMETER_PROBLEM, "Bad MARK value '%s'",
131 			      optarg);
132 
133 	return 1;
134 }
135 
brmark_print(const void * ip,const struct xt_entry_target * target,int numeric)136 static void brmark_print(const void *ip, const struct xt_entry_target *target,
137 			 int numeric)
138 {
139 	struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)target->data;
140 	int tmp;
141 
142 	tmp = info->target & ~EBT_VERDICT_BITS;
143 	if (tmp == MARK_SET_VALUE)
144 		printf("--mark-set");
145 	else if (tmp == MARK_OR_VALUE)
146 		printf("--mark-or");
147 	else if (tmp == MARK_XOR_VALUE)
148 		printf("--mark-xor");
149 	else if (tmp == MARK_AND_VALUE)
150 		printf("--mark-and");
151 	else
152 		xtables_error(PARAMETER_PROBLEM, "Unknown mark action");
153 
154 	printf(" 0x%lx", info->mark);
155 	tmp = info->target | ~EBT_VERDICT_BITS;
156 	printf(" --mark-target %s", ebt_target_name(tmp));
157 }
158 
brmark_final_check(unsigned int flags)159 static void brmark_final_check(unsigned int flags)
160 {
161 	if (!flags)
162 		xtables_error(PARAMETER_PROBLEM,
163 			      "You must specify some option");
164 }
165 
brmark_verdict(int verdict)166 static const char* brmark_verdict(int verdict)
167 {
168 	switch (verdict) {
169 	case EBT_ACCEPT: return "accept";
170 	case EBT_DROP: return "drop";
171 	case EBT_CONTINUE: return "continue";
172 	case EBT_RETURN: return "return";
173 	}
174 
175 	return "";
176 }
177 
brmark_xlate(struct xt_xlate * xl,const struct xt_xlate_tg_params * params)178 static int brmark_xlate(struct xt_xlate *xl,
179 			const struct xt_xlate_tg_params *params)
180 {
181 	const struct ebt_mark_t_info *info = (const void*)params->target->data;
182 	int tmp;
183 
184 	tmp = info->target & ~EBT_VERDICT_BITS;
185 
186 	xt_xlate_add(xl, "meta mark set ");
187 
188 	switch (tmp) {
189 	case MARK_SET_VALUE:
190 		break;
191 	case MARK_OR_VALUE:
192 		xt_xlate_add(xl, "meta mark or ");
193 		break;
194 	case MARK_XOR_VALUE:
195 		xt_xlate_add(xl, "meta mark xor ");
196 		break;
197 	case MARK_AND_VALUE:
198 		xt_xlate_add(xl, "meta mark and ");
199 		break;
200 	default:
201 		return 0;
202 	}
203 
204 	tmp = info->target & EBT_VERDICT_BITS;
205 	xt_xlate_add(xl, "0x%lx %s ", info->mark, brmark_verdict(tmp));
206 	return 1;
207 }
208 
209 static struct xtables_target brmark_target = {
210 	.name		= "mark",
211 	.revision	= 0,
212 	.version	= XTABLES_VERSION,
213 	.family		= NFPROTO_BRIDGE,
214 	.size		= XT_ALIGN(sizeof(struct ebt_mark_t_info)),
215 	.userspacesize	= XT_ALIGN(sizeof(struct ebt_mark_t_info)),
216 	.help		= brmark_print_help,
217 	.init		= brmark_init,
218 	.parse		= brmark_parse,
219 	.final_check	= brmark_final_check,
220 	.print		= brmark_print,
221 	.xlate		= brmark_xlate,
222 	.extra_opts	= brmark_opts,
223 };
224 
_init(void)225 void _init(void)
226 {
227 	xtables_register_target(&brmark_target);
228 }
229