1*a71a9546SAutomerger Merge Worker #include <getopt.h>
2*a71a9546SAutomerger Merge Worker #include <stdbool.h>
3*a71a9546SAutomerger Merge Worker #include <stdio.h>
4*a71a9546SAutomerger Merge Worker #include <xtables.h>
5*a71a9546SAutomerger Merge Worker #include <linux/netfilter/xt_MARK.h>
6*a71a9546SAutomerger Merge Worker
7*a71a9546SAutomerger Merge Worker /* Version 0 */
8*a71a9546SAutomerger Merge Worker struct xt_mark_target_info {
9*a71a9546SAutomerger Merge Worker unsigned long mark;
10*a71a9546SAutomerger Merge Worker };
11*a71a9546SAutomerger Merge Worker
12*a71a9546SAutomerger Merge Worker /* Version 1 */
13*a71a9546SAutomerger Merge Worker enum {
14*a71a9546SAutomerger Merge Worker XT_MARK_SET=0,
15*a71a9546SAutomerger Merge Worker XT_MARK_AND,
16*a71a9546SAutomerger Merge Worker XT_MARK_OR,
17*a71a9546SAutomerger Merge Worker };
18*a71a9546SAutomerger Merge Worker
19*a71a9546SAutomerger Merge Worker struct xt_mark_target_info_v1 {
20*a71a9546SAutomerger Merge Worker unsigned long mark;
21*a71a9546SAutomerger Merge Worker uint8_t mode;
22*a71a9546SAutomerger Merge Worker };
23*a71a9546SAutomerger Merge Worker
24*a71a9546SAutomerger Merge Worker enum {
25*a71a9546SAutomerger Merge Worker O_SET_MARK = 0,
26*a71a9546SAutomerger Merge Worker O_AND_MARK,
27*a71a9546SAutomerger Merge Worker O_OR_MARK,
28*a71a9546SAutomerger Merge Worker O_XOR_MARK,
29*a71a9546SAutomerger Merge Worker O_SET_XMARK,
30*a71a9546SAutomerger Merge Worker F_SET_MARK = 1 << O_SET_MARK,
31*a71a9546SAutomerger Merge Worker F_AND_MARK = 1 << O_AND_MARK,
32*a71a9546SAutomerger Merge Worker F_OR_MARK = 1 << O_OR_MARK,
33*a71a9546SAutomerger Merge Worker F_XOR_MARK = 1 << O_XOR_MARK,
34*a71a9546SAutomerger Merge Worker F_SET_XMARK = 1 << O_SET_XMARK,
35*a71a9546SAutomerger Merge Worker F_ANY = F_SET_MARK | F_AND_MARK | F_OR_MARK |
36*a71a9546SAutomerger Merge Worker F_XOR_MARK | F_SET_XMARK,
37*a71a9546SAutomerger Merge Worker };
38*a71a9546SAutomerger Merge Worker
MARK_help(void)39*a71a9546SAutomerger Merge Worker static void MARK_help(void)
40*a71a9546SAutomerger Merge Worker {
41*a71a9546SAutomerger Merge Worker printf(
42*a71a9546SAutomerger Merge Worker "MARK target options:\n"
43*a71a9546SAutomerger Merge Worker " --set-mark value Set nfmark value\n"
44*a71a9546SAutomerger Merge Worker " --and-mark value Binary AND the nfmark with value\n"
45*a71a9546SAutomerger Merge Worker " --or-mark value Binary OR the nfmark with value\n");
46*a71a9546SAutomerger Merge Worker }
47*a71a9546SAutomerger Merge Worker
48*a71a9546SAutomerger Merge Worker static const struct xt_option_entry MARK_opts[] = {
49*a71a9546SAutomerger Merge Worker {.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_UINT32,
50*a71a9546SAutomerger Merge Worker .excl = F_ANY},
51*a71a9546SAutomerger Merge Worker {.name = "and-mark", .id = O_AND_MARK, .type = XTTYPE_UINT32,
52*a71a9546SAutomerger Merge Worker .excl = F_ANY},
53*a71a9546SAutomerger Merge Worker {.name = "or-mark", .id = O_OR_MARK, .type = XTTYPE_UINT32,
54*a71a9546SAutomerger Merge Worker .excl = F_ANY},
55*a71a9546SAutomerger Merge Worker XTOPT_TABLEEND,
56*a71a9546SAutomerger Merge Worker };
57*a71a9546SAutomerger Merge Worker
58*a71a9546SAutomerger Merge Worker static const struct xt_option_entry mark_tg_opts[] = {
59*a71a9546SAutomerger Merge Worker {.name = "set-xmark", .id = O_SET_XMARK, .type = XTTYPE_MARKMASK32,
60*a71a9546SAutomerger Merge Worker .excl = F_ANY},
61*a71a9546SAutomerger Merge Worker {.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_MARKMASK32,
62*a71a9546SAutomerger Merge Worker .excl = F_ANY},
63*a71a9546SAutomerger Merge Worker {.name = "and-mark", .id = O_AND_MARK, .type = XTTYPE_UINT32,
64*a71a9546SAutomerger Merge Worker .excl = F_ANY},
65*a71a9546SAutomerger Merge Worker {.name = "or-mark", .id = O_OR_MARK, .type = XTTYPE_UINT32,
66*a71a9546SAutomerger Merge Worker .excl = F_ANY},
67*a71a9546SAutomerger Merge Worker {.name = "xor-mark", .id = O_XOR_MARK, .type = XTTYPE_UINT32,
68*a71a9546SAutomerger Merge Worker .excl = F_ANY},
69*a71a9546SAutomerger Merge Worker XTOPT_TABLEEND,
70*a71a9546SAutomerger Merge Worker };
71*a71a9546SAutomerger Merge Worker
mark_tg_help(void)72*a71a9546SAutomerger Merge Worker static void mark_tg_help(void)
73*a71a9546SAutomerger Merge Worker {
74*a71a9546SAutomerger Merge Worker printf(
75*a71a9546SAutomerger Merge Worker "MARK target options:\n"
76*a71a9546SAutomerger Merge Worker " --set-xmark value[/mask] Clear bits in mask and XOR value into nfmark\n"
77*a71a9546SAutomerger Merge Worker " --set-mark value[/mask] Clear bits in mask and OR value into nfmark\n"
78*a71a9546SAutomerger Merge Worker " --and-mark bits Binary AND the nfmark with bits\n"
79*a71a9546SAutomerger Merge Worker " --or-mark bits Binary OR the nfmark with bits\n"
80*a71a9546SAutomerger Merge Worker " --xor-mark bits Binary XOR the nfmark with bits\n");
81*a71a9546SAutomerger Merge Worker }
82*a71a9546SAutomerger Merge Worker
MARK_parse_v0(struct xt_option_call * cb)83*a71a9546SAutomerger Merge Worker static void MARK_parse_v0(struct xt_option_call *cb)
84*a71a9546SAutomerger Merge Worker {
85*a71a9546SAutomerger Merge Worker struct xt_mark_target_info *markinfo = cb->data;
86*a71a9546SAutomerger Merge Worker
87*a71a9546SAutomerger Merge Worker xtables_option_parse(cb);
88*a71a9546SAutomerger Merge Worker switch (cb->entry->id) {
89*a71a9546SAutomerger Merge Worker case O_SET_MARK:
90*a71a9546SAutomerger Merge Worker markinfo->mark = cb->val.mark;
91*a71a9546SAutomerger Merge Worker break;
92*a71a9546SAutomerger Merge Worker default:
93*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM,
94*a71a9546SAutomerger Merge Worker "MARK target: kernel too old for --%s",
95*a71a9546SAutomerger Merge Worker cb->entry->name);
96*a71a9546SAutomerger Merge Worker }
97*a71a9546SAutomerger Merge Worker }
98*a71a9546SAutomerger Merge Worker
MARK_check(struct xt_fcheck_call * cb)99*a71a9546SAutomerger Merge Worker static void MARK_check(struct xt_fcheck_call *cb)
100*a71a9546SAutomerger Merge Worker {
101*a71a9546SAutomerger Merge Worker if (cb->xflags == 0)
102*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM,
103*a71a9546SAutomerger Merge Worker "MARK target: Parameter --set/and/or-mark"
104*a71a9546SAutomerger Merge Worker " is required");
105*a71a9546SAutomerger Merge Worker }
106*a71a9546SAutomerger Merge Worker
MARK_parse_v1(struct xt_option_call * cb)107*a71a9546SAutomerger Merge Worker static void MARK_parse_v1(struct xt_option_call *cb)
108*a71a9546SAutomerger Merge Worker {
109*a71a9546SAutomerger Merge Worker struct xt_mark_target_info_v1 *markinfo = cb->data;
110*a71a9546SAutomerger Merge Worker
111*a71a9546SAutomerger Merge Worker xtables_option_parse(cb);
112*a71a9546SAutomerger Merge Worker switch (cb->entry->id) {
113*a71a9546SAutomerger Merge Worker case O_SET_MARK:
114*a71a9546SAutomerger Merge Worker markinfo->mode = XT_MARK_SET;
115*a71a9546SAutomerger Merge Worker break;
116*a71a9546SAutomerger Merge Worker case O_AND_MARK:
117*a71a9546SAutomerger Merge Worker markinfo->mode = XT_MARK_AND;
118*a71a9546SAutomerger Merge Worker break;
119*a71a9546SAutomerger Merge Worker case O_OR_MARK:
120*a71a9546SAutomerger Merge Worker markinfo->mode = XT_MARK_OR;
121*a71a9546SAutomerger Merge Worker break;
122*a71a9546SAutomerger Merge Worker }
123*a71a9546SAutomerger Merge Worker markinfo->mark = cb->val.u32;
124*a71a9546SAutomerger Merge Worker }
125*a71a9546SAutomerger Merge Worker
mark_tg_parse(struct xt_option_call * cb)126*a71a9546SAutomerger Merge Worker static void mark_tg_parse(struct xt_option_call *cb)
127*a71a9546SAutomerger Merge Worker {
128*a71a9546SAutomerger Merge Worker struct xt_mark_tginfo2 *info = cb->data;
129*a71a9546SAutomerger Merge Worker
130*a71a9546SAutomerger Merge Worker xtables_option_parse(cb);
131*a71a9546SAutomerger Merge Worker switch (cb->entry->id) {
132*a71a9546SAutomerger Merge Worker case O_SET_XMARK:
133*a71a9546SAutomerger Merge Worker info->mark = cb->val.mark;
134*a71a9546SAutomerger Merge Worker info->mask = cb->val.mask;
135*a71a9546SAutomerger Merge Worker break;
136*a71a9546SAutomerger Merge Worker case O_SET_MARK:
137*a71a9546SAutomerger Merge Worker info->mark = cb->val.mark;
138*a71a9546SAutomerger Merge Worker info->mask = cb->val.mark | cb->val.mask;
139*a71a9546SAutomerger Merge Worker break;
140*a71a9546SAutomerger Merge Worker case O_AND_MARK:
141*a71a9546SAutomerger Merge Worker info->mark = 0;
142*a71a9546SAutomerger Merge Worker info->mask = ~cb->val.u32;
143*a71a9546SAutomerger Merge Worker break;
144*a71a9546SAutomerger Merge Worker case O_OR_MARK:
145*a71a9546SAutomerger Merge Worker info->mark = info->mask = cb->val.u32;
146*a71a9546SAutomerger Merge Worker break;
147*a71a9546SAutomerger Merge Worker case O_XOR_MARK:
148*a71a9546SAutomerger Merge Worker info->mark = cb->val.u32;
149*a71a9546SAutomerger Merge Worker info->mask = 0;
150*a71a9546SAutomerger Merge Worker break;
151*a71a9546SAutomerger Merge Worker }
152*a71a9546SAutomerger Merge Worker }
153*a71a9546SAutomerger Merge Worker
mark_tg_check(struct xt_fcheck_call * cb)154*a71a9546SAutomerger Merge Worker static void mark_tg_check(struct xt_fcheck_call *cb)
155*a71a9546SAutomerger Merge Worker {
156*a71a9546SAutomerger Merge Worker if (cb->xflags == 0)
157*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, "MARK: One of the --set-xmark, "
158*a71a9546SAutomerger Merge Worker "--{and,or,xor,set}-mark options is required");
159*a71a9546SAutomerger Merge Worker }
160*a71a9546SAutomerger Merge Worker
161*a71a9546SAutomerger Merge Worker static void
print_mark(unsigned long mark)162*a71a9546SAutomerger Merge Worker print_mark(unsigned long mark)
163*a71a9546SAutomerger Merge Worker {
164*a71a9546SAutomerger Merge Worker printf(" 0x%lx", mark);
165*a71a9546SAutomerger Merge Worker }
166*a71a9546SAutomerger Merge Worker
MARK_print_v0(const void * ip,const struct xt_entry_target * target,int numeric)167*a71a9546SAutomerger Merge Worker static void MARK_print_v0(const void *ip,
168*a71a9546SAutomerger Merge Worker const struct xt_entry_target *target, int numeric)
169*a71a9546SAutomerger Merge Worker {
170*a71a9546SAutomerger Merge Worker const struct xt_mark_target_info *markinfo =
171*a71a9546SAutomerger Merge Worker (const struct xt_mark_target_info *)target->data;
172*a71a9546SAutomerger Merge Worker printf(" MARK set");
173*a71a9546SAutomerger Merge Worker print_mark(markinfo->mark);
174*a71a9546SAutomerger Merge Worker }
175*a71a9546SAutomerger Merge Worker
MARK_save_v0(const void * ip,const struct xt_entry_target * target)176*a71a9546SAutomerger Merge Worker static void MARK_save_v0(const void *ip, const struct xt_entry_target *target)
177*a71a9546SAutomerger Merge Worker {
178*a71a9546SAutomerger Merge Worker const struct xt_mark_target_info *markinfo =
179*a71a9546SAutomerger Merge Worker (const struct xt_mark_target_info *)target->data;
180*a71a9546SAutomerger Merge Worker
181*a71a9546SAutomerger Merge Worker printf(" --set-mark");
182*a71a9546SAutomerger Merge Worker print_mark(markinfo->mark);
183*a71a9546SAutomerger Merge Worker }
184*a71a9546SAutomerger Merge Worker
MARK_print_v1(const void * ip,const struct xt_entry_target * target,int numeric)185*a71a9546SAutomerger Merge Worker static void MARK_print_v1(const void *ip, const struct xt_entry_target *target,
186*a71a9546SAutomerger Merge Worker int numeric)
187*a71a9546SAutomerger Merge Worker {
188*a71a9546SAutomerger Merge Worker const struct xt_mark_target_info_v1 *markinfo =
189*a71a9546SAutomerger Merge Worker (const struct xt_mark_target_info_v1 *)target->data;
190*a71a9546SAutomerger Merge Worker
191*a71a9546SAutomerger Merge Worker switch (markinfo->mode) {
192*a71a9546SAutomerger Merge Worker case XT_MARK_SET:
193*a71a9546SAutomerger Merge Worker printf(" MARK set");
194*a71a9546SAutomerger Merge Worker break;
195*a71a9546SAutomerger Merge Worker case XT_MARK_AND:
196*a71a9546SAutomerger Merge Worker printf(" MARK and");
197*a71a9546SAutomerger Merge Worker break;
198*a71a9546SAutomerger Merge Worker case XT_MARK_OR:
199*a71a9546SAutomerger Merge Worker printf(" MARK or");
200*a71a9546SAutomerger Merge Worker break;
201*a71a9546SAutomerger Merge Worker }
202*a71a9546SAutomerger Merge Worker print_mark(markinfo->mark);
203*a71a9546SAutomerger Merge Worker }
204*a71a9546SAutomerger Merge Worker
mark_tg_print(const void * ip,const struct xt_entry_target * target,int numeric)205*a71a9546SAutomerger Merge Worker static void mark_tg_print(const void *ip, const struct xt_entry_target *target,
206*a71a9546SAutomerger Merge Worker int numeric)
207*a71a9546SAutomerger Merge Worker {
208*a71a9546SAutomerger Merge Worker const struct xt_mark_tginfo2 *info = (const void *)target->data;
209*a71a9546SAutomerger Merge Worker
210*a71a9546SAutomerger Merge Worker if (info->mark == 0)
211*a71a9546SAutomerger Merge Worker printf(" MARK and 0x%x", (unsigned int)(uint32_t)~info->mask);
212*a71a9546SAutomerger Merge Worker else if (info->mark == info->mask)
213*a71a9546SAutomerger Merge Worker printf(" MARK or 0x%x", info->mark);
214*a71a9546SAutomerger Merge Worker else if (info->mask == 0)
215*a71a9546SAutomerger Merge Worker printf(" MARK xor 0x%x", info->mark);
216*a71a9546SAutomerger Merge Worker else if (info->mask == 0xffffffffU)
217*a71a9546SAutomerger Merge Worker printf(" MARK set 0x%x", info->mark);
218*a71a9546SAutomerger Merge Worker else
219*a71a9546SAutomerger Merge Worker printf(" MARK xset 0x%x/0x%x", info->mark, info->mask);
220*a71a9546SAutomerger Merge Worker }
221*a71a9546SAutomerger Merge Worker
MARK_save_v1(const void * ip,const struct xt_entry_target * target)222*a71a9546SAutomerger Merge Worker static void MARK_save_v1(const void *ip, const struct xt_entry_target *target)
223*a71a9546SAutomerger Merge Worker {
224*a71a9546SAutomerger Merge Worker const struct xt_mark_target_info_v1 *markinfo =
225*a71a9546SAutomerger Merge Worker (const struct xt_mark_target_info_v1 *)target->data;
226*a71a9546SAutomerger Merge Worker
227*a71a9546SAutomerger Merge Worker switch (markinfo->mode) {
228*a71a9546SAutomerger Merge Worker case XT_MARK_SET:
229*a71a9546SAutomerger Merge Worker printf(" --set-mark");
230*a71a9546SAutomerger Merge Worker break;
231*a71a9546SAutomerger Merge Worker case XT_MARK_AND:
232*a71a9546SAutomerger Merge Worker printf(" --and-mark");
233*a71a9546SAutomerger Merge Worker break;
234*a71a9546SAutomerger Merge Worker case XT_MARK_OR:
235*a71a9546SAutomerger Merge Worker printf(" --or-mark");
236*a71a9546SAutomerger Merge Worker break;
237*a71a9546SAutomerger Merge Worker }
238*a71a9546SAutomerger Merge Worker print_mark(markinfo->mark);
239*a71a9546SAutomerger Merge Worker }
240*a71a9546SAutomerger Merge Worker
mark_tg_save(const void * ip,const struct xt_entry_target * target)241*a71a9546SAutomerger Merge Worker static void mark_tg_save(const void *ip, const struct xt_entry_target *target)
242*a71a9546SAutomerger Merge Worker {
243*a71a9546SAutomerger Merge Worker const struct xt_mark_tginfo2 *info = (const void *)target->data;
244*a71a9546SAutomerger Merge Worker
245*a71a9546SAutomerger Merge Worker printf(" --set-xmark 0x%x/0x%x", info->mark, info->mask);
246*a71a9546SAutomerger Merge Worker }
247*a71a9546SAutomerger Merge Worker
mark_tg_arp_save(const void * ip,const struct xt_entry_target * target)248*a71a9546SAutomerger Merge Worker static void mark_tg_arp_save(const void *ip, const struct xt_entry_target *target)
249*a71a9546SAutomerger Merge Worker {
250*a71a9546SAutomerger Merge Worker const struct xt_mark_tginfo2 *info = (const void *)target->data;
251*a71a9546SAutomerger Merge Worker
252*a71a9546SAutomerger Merge Worker if (info->mark == 0)
253*a71a9546SAutomerger Merge Worker printf(" --and-mark %x", (unsigned int)(uint32_t)~info->mask);
254*a71a9546SAutomerger Merge Worker else if (info->mark == info->mask)
255*a71a9546SAutomerger Merge Worker printf(" --or-mark %x", info->mark);
256*a71a9546SAutomerger Merge Worker else
257*a71a9546SAutomerger Merge Worker printf(" --set-mark %x", info->mark);
258*a71a9546SAutomerger Merge Worker }
259*a71a9546SAutomerger Merge Worker
mark_tg_arp_print(const void * ip,const struct xt_entry_target * target,int numeric)260*a71a9546SAutomerger Merge Worker static void mark_tg_arp_print(const void *ip,
261*a71a9546SAutomerger Merge Worker const struct xt_entry_target *target, int numeric)
262*a71a9546SAutomerger Merge Worker {
263*a71a9546SAutomerger Merge Worker mark_tg_arp_save(ip, target);
264*a71a9546SAutomerger Merge Worker }
265*a71a9546SAutomerger Merge Worker
266*a71a9546SAutomerger Merge Worker #define MARK_OPT 1
267*a71a9546SAutomerger Merge Worker #define AND_MARK_OPT 2
268*a71a9546SAutomerger Merge Worker #define OR_MARK_OPT 3
269*a71a9546SAutomerger Merge Worker
270*a71a9546SAutomerger Merge Worker static struct option mark_tg_arp_opts[] = {
271*a71a9546SAutomerger Merge Worker { .name = "set-mark", .has_arg = required_argument, .flag = 0, .val = MARK_OPT },
272*a71a9546SAutomerger Merge Worker { .name = "and-mark", .has_arg = required_argument, .flag = 0, .val = AND_MARK_OPT },
273*a71a9546SAutomerger Merge Worker { .name = "or-mark", .has_arg = required_argument, .flag = 0, .val = OR_MARK_OPT },
274*a71a9546SAutomerger Merge Worker { .name = NULL}
275*a71a9546SAutomerger Merge Worker };
276*a71a9546SAutomerger Merge Worker
277*a71a9546SAutomerger Merge Worker static int
mark_tg_arp_parse(int c,char ** argv,int invert,unsigned int * flags,const void * entry,struct xt_entry_target ** target)278*a71a9546SAutomerger Merge Worker mark_tg_arp_parse(int c, char **argv, int invert, unsigned int *flags,
279*a71a9546SAutomerger Merge Worker const void *entry, struct xt_entry_target **target)
280*a71a9546SAutomerger Merge Worker {
281*a71a9546SAutomerger Merge Worker struct xt_mark_tginfo2 *info =
282*a71a9546SAutomerger Merge Worker (struct xt_mark_tginfo2 *)(*target)->data;
283*a71a9546SAutomerger Merge Worker int i;
284*a71a9546SAutomerger Merge Worker
285*a71a9546SAutomerger Merge Worker switch (c) {
286*a71a9546SAutomerger Merge Worker case MARK_OPT:
287*a71a9546SAutomerger Merge Worker if (sscanf(argv[optind-1], "%x", &i) != 1) {
288*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM,
289*a71a9546SAutomerger Merge Worker "Bad mark value `%s'", optarg);
290*a71a9546SAutomerger Merge Worker return 0;
291*a71a9546SAutomerger Merge Worker }
292*a71a9546SAutomerger Merge Worker info->mark = i;
293*a71a9546SAutomerger Merge Worker if (*flags)
294*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM,
295*a71a9546SAutomerger Merge Worker "MARK: Can't specify --set-mark twice");
296*a71a9546SAutomerger Merge Worker *flags = 1;
297*a71a9546SAutomerger Merge Worker break;
298*a71a9546SAutomerger Merge Worker case AND_MARK_OPT:
299*a71a9546SAutomerger Merge Worker if (sscanf(argv[optind-1], "%x", &i) != 1) {
300*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM,
301*a71a9546SAutomerger Merge Worker "Bad mark value `%s'", optarg);
302*a71a9546SAutomerger Merge Worker return 0;
303*a71a9546SAutomerger Merge Worker }
304*a71a9546SAutomerger Merge Worker info->mark = 0;
305*a71a9546SAutomerger Merge Worker info->mask = ~i;
306*a71a9546SAutomerger Merge Worker if (*flags)
307*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM,
308*a71a9546SAutomerger Merge Worker "MARK: Can't specify --and-mark twice");
309*a71a9546SAutomerger Merge Worker *flags = 1;
310*a71a9546SAutomerger Merge Worker break;
311*a71a9546SAutomerger Merge Worker case OR_MARK_OPT:
312*a71a9546SAutomerger Merge Worker if (sscanf(argv[optind-1], "%x", &i) != 1) {
313*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM,
314*a71a9546SAutomerger Merge Worker "Bad mark value `%s'", optarg);
315*a71a9546SAutomerger Merge Worker return 0;
316*a71a9546SAutomerger Merge Worker }
317*a71a9546SAutomerger Merge Worker info->mark = info->mask = i;
318*a71a9546SAutomerger Merge Worker if (*flags)
319*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM,
320*a71a9546SAutomerger Merge Worker "MARK: Can't specify --or-mark twice");
321*a71a9546SAutomerger Merge Worker *flags = 1;
322*a71a9546SAutomerger Merge Worker break;
323*a71a9546SAutomerger Merge Worker default:
324*a71a9546SAutomerger Merge Worker return 0;
325*a71a9546SAutomerger Merge Worker }
326*a71a9546SAutomerger Merge Worker return 1;
327*a71a9546SAutomerger Merge Worker }
328*a71a9546SAutomerger Merge Worker
mark_tg_xlate(struct xt_xlate * xl,const struct xt_xlate_tg_params * params)329*a71a9546SAutomerger Merge Worker static int mark_tg_xlate(struct xt_xlate *xl,
330*a71a9546SAutomerger Merge Worker const struct xt_xlate_tg_params *params)
331*a71a9546SAutomerger Merge Worker {
332*a71a9546SAutomerger Merge Worker const struct xt_mark_tginfo2 *info = (const void *)params->target->data;
333*a71a9546SAutomerger Merge Worker
334*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "meta mark set ");
335*a71a9546SAutomerger Merge Worker
336*a71a9546SAutomerger Merge Worker if (info->mask == 0xffffffffU)
337*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "0x%x ", info->mark);
338*a71a9546SAutomerger Merge Worker else if (info->mark == 0)
339*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "mark and 0x%x ", ~info->mask);
340*a71a9546SAutomerger Merge Worker else if (info->mark == info->mask)
341*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "mark or 0x%x ", info->mark);
342*a71a9546SAutomerger Merge Worker else if (info->mask == 0)
343*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "mark xor 0x%x ", info->mark);
344*a71a9546SAutomerger Merge Worker else
345*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "mark and 0x%x xor 0x%x ", ~info->mask,
346*a71a9546SAutomerger Merge Worker info->mark);
347*a71a9546SAutomerger Merge Worker
348*a71a9546SAutomerger Merge Worker return 1;
349*a71a9546SAutomerger Merge Worker }
350*a71a9546SAutomerger Merge Worker
MARK_xlate(struct xt_xlate * xl,const struct xt_xlate_tg_params * params)351*a71a9546SAutomerger Merge Worker static int MARK_xlate(struct xt_xlate *xl,
352*a71a9546SAutomerger Merge Worker const struct xt_xlate_tg_params *params)
353*a71a9546SAutomerger Merge Worker {
354*a71a9546SAutomerger Merge Worker const struct xt_mark_target_info_v1 *markinfo =
355*a71a9546SAutomerger Merge Worker (const struct xt_mark_target_info_v1 *)params->target->data;
356*a71a9546SAutomerger Merge Worker
357*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "meta mark set ");
358*a71a9546SAutomerger Merge Worker
359*a71a9546SAutomerger Merge Worker switch(markinfo->mode) {
360*a71a9546SAutomerger Merge Worker case XT_MARK_SET:
361*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "0x%x ", (uint32_t)markinfo->mark);
362*a71a9546SAutomerger Merge Worker break;
363*a71a9546SAutomerger Merge Worker case XT_MARK_AND:
364*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "mark and 0x%x ", (uint32_t)markinfo->mark);
365*a71a9546SAutomerger Merge Worker break;
366*a71a9546SAutomerger Merge Worker case XT_MARK_OR:
367*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "mark or 0x%x ", (uint32_t)markinfo->mark);
368*a71a9546SAutomerger Merge Worker break;
369*a71a9546SAutomerger Merge Worker default:
370*a71a9546SAutomerger Merge Worker return 0;
371*a71a9546SAutomerger Merge Worker }
372*a71a9546SAutomerger Merge Worker
373*a71a9546SAutomerger Merge Worker return 1;
374*a71a9546SAutomerger Merge Worker }
375*a71a9546SAutomerger Merge Worker
376*a71a9546SAutomerger Merge Worker static struct xtables_target mark_tg_reg[] = {
377*a71a9546SAutomerger Merge Worker {
378*a71a9546SAutomerger Merge Worker .family = NFPROTO_UNSPEC,
379*a71a9546SAutomerger Merge Worker .name = "MARK",
380*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION,
381*a71a9546SAutomerger Merge Worker .revision = 0,
382*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_mark_target_info)),
383*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_mark_target_info)),
384*a71a9546SAutomerger Merge Worker .help = MARK_help,
385*a71a9546SAutomerger Merge Worker .print = MARK_print_v0,
386*a71a9546SAutomerger Merge Worker .save = MARK_save_v0,
387*a71a9546SAutomerger Merge Worker .x6_parse = MARK_parse_v0,
388*a71a9546SAutomerger Merge Worker .x6_fcheck = MARK_check,
389*a71a9546SAutomerger Merge Worker .x6_options = MARK_opts,
390*a71a9546SAutomerger Merge Worker },
391*a71a9546SAutomerger Merge Worker {
392*a71a9546SAutomerger Merge Worker .family = NFPROTO_IPV4,
393*a71a9546SAutomerger Merge Worker .name = "MARK",
394*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION,
395*a71a9546SAutomerger Merge Worker .revision = 1,
396*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_mark_target_info_v1)),
397*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_mark_target_info_v1)),
398*a71a9546SAutomerger Merge Worker .help = MARK_help,
399*a71a9546SAutomerger Merge Worker .print = MARK_print_v1,
400*a71a9546SAutomerger Merge Worker .save = MARK_save_v1,
401*a71a9546SAutomerger Merge Worker .x6_parse = MARK_parse_v1,
402*a71a9546SAutomerger Merge Worker .x6_fcheck = MARK_check,
403*a71a9546SAutomerger Merge Worker .x6_options = MARK_opts,
404*a71a9546SAutomerger Merge Worker .xlate = MARK_xlate,
405*a71a9546SAutomerger Merge Worker },
406*a71a9546SAutomerger Merge Worker {
407*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION,
408*a71a9546SAutomerger Merge Worker .name = "MARK",
409*a71a9546SAutomerger Merge Worker .revision = 2,
410*a71a9546SAutomerger Merge Worker .family = NFPROTO_UNSPEC,
411*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_mark_tginfo2)),
412*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_mark_tginfo2)),
413*a71a9546SAutomerger Merge Worker .help = mark_tg_help,
414*a71a9546SAutomerger Merge Worker .print = mark_tg_print,
415*a71a9546SAutomerger Merge Worker .save = mark_tg_save,
416*a71a9546SAutomerger Merge Worker .x6_parse = mark_tg_parse,
417*a71a9546SAutomerger Merge Worker .x6_fcheck = mark_tg_check,
418*a71a9546SAutomerger Merge Worker .x6_options = mark_tg_opts,
419*a71a9546SAutomerger Merge Worker .xlate = mark_tg_xlate,
420*a71a9546SAutomerger Merge Worker },
421*a71a9546SAutomerger Merge Worker {
422*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION,
423*a71a9546SAutomerger Merge Worker .name = "MARK",
424*a71a9546SAutomerger Merge Worker .revision = 2,
425*a71a9546SAutomerger Merge Worker .family = NFPROTO_ARP,
426*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_mark_tginfo2)),
427*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_mark_tginfo2)),
428*a71a9546SAutomerger Merge Worker .help = mark_tg_help,
429*a71a9546SAutomerger Merge Worker .print = mark_tg_arp_print,
430*a71a9546SAutomerger Merge Worker .save = mark_tg_arp_save,
431*a71a9546SAutomerger Merge Worker .parse = mark_tg_arp_parse,
432*a71a9546SAutomerger Merge Worker .extra_opts = mark_tg_arp_opts,
433*a71a9546SAutomerger Merge Worker },
434*a71a9546SAutomerger Merge Worker };
435*a71a9546SAutomerger Merge Worker
_init(void)436*a71a9546SAutomerger Merge Worker void _init(void)
437*a71a9546SAutomerger Merge Worker {
438*a71a9546SAutomerger Merge Worker xtables_register_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg));
439*a71a9546SAutomerger Merge Worker }
440