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