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