1*a71a9546SAutomerger Merge Worker /*
2*a71a9546SAutomerger Merge Worker * (C) 2012 by Hans Schillstrom <[email protected]>
3*a71a9546SAutomerger Merge Worker * (C) 2012 by Pablo Neira Ayuso <[email protected]>
4*a71a9546SAutomerger Merge Worker *
5*a71a9546SAutomerger Merge Worker * This program is free software; you can redistribute it and/or modify
6*a71a9546SAutomerger Merge Worker * it under the terms of the GNU General Public License version 2 as
7*a71a9546SAutomerger Merge Worker * published by the Free Software Foundation.
8*a71a9546SAutomerger Merge Worker *
9*a71a9546SAutomerger Merge Worker * Description: shared library add-on to iptables to add HMARK target support
10*a71a9546SAutomerger Merge Worker *
11*a71a9546SAutomerger Merge Worker * Initial development by Hans Schillstrom. Pablo's improvements to this piece
12*a71a9546SAutomerger Merge Worker * of software has been sponsored by Sophos Astaro <http://www.sophos.com>.
13*a71a9546SAutomerger Merge Worker */
14*a71a9546SAutomerger Merge Worker
15*a71a9546SAutomerger Merge Worker #include <stdbool.h>
16*a71a9546SAutomerger Merge Worker #include <stdio.h>
17*a71a9546SAutomerger Merge Worker #include <string.h>
18*a71a9546SAutomerger Merge Worker
19*a71a9546SAutomerger Merge Worker #include "xtables.h"
20*a71a9546SAutomerger Merge Worker #include <linux/netfilter/xt_HMARK.h>
21*a71a9546SAutomerger Merge Worker
HMARK_help(void)22*a71a9546SAutomerger Merge Worker static void HMARK_help(void)
23*a71a9546SAutomerger Merge Worker {
24*a71a9546SAutomerger Merge Worker printf(
25*a71a9546SAutomerger Merge Worker "HMARK target options, i.e. modify hash calculation by:\n"
26*a71a9546SAutomerger Merge Worker " --hmark-tuple [src|dst|sport|dport|spi|proto|ct][,...]\n"
27*a71a9546SAutomerger Merge Worker " --hmark-mod value nfmark modulus value\n"
28*a71a9546SAutomerger Merge Worker " --hmark-offset value Last action add value to nfmark\n\n"
29*a71a9546SAutomerger Merge Worker " --hmark-rnd Random see for hashing\n"
30*a71a9546SAutomerger Merge Worker " Alternatively, fine tuning of what will be included in hash calculation\n"
31*a71a9546SAutomerger Merge Worker " --hmark-src-prefix length Source address mask CIDR prefix\n"
32*a71a9546SAutomerger Merge Worker " --hmark-dst-prefix length Dest address mask CIDR prefix\n"
33*a71a9546SAutomerger Merge Worker " --hmark-sport-mask value Mask src port with value\n"
34*a71a9546SAutomerger Merge Worker " --hmark-dport-mask value Mask dst port with value\n"
35*a71a9546SAutomerger Merge Worker " --hmark-spi-mask value For esp and ah AND spi with value\n"
36*a71a9546SAutomerger Merge Worker " --hmark-sport value OR src port with value\n"
37*a71a9546SAutomerger Merge Worker " --hmark-dport value OR dst port with value\n"
38*a71a9546SAutomerger Merge Worker " --hmark-spi value For esp and ah OR spi with value\n"
39*a71a9546SAutomerger Merge Worker " --hmark-proto-mask value Mask Protocol with value\n");
40*a71a9546SAutomerger Merge Worker }
41*a71a9546SAutomerger Merge Worker
42*a71a9546SAutomerger Merge Worker #define hi struct xt_hmark_info
43*a71a9546SAutomerger Merge Worker
44*a71a9546SAutomerger Merge Worker enum {
45*a71a9546SAutomerger Merge Worker O_HMARK_SADDR_MASK,
46*a71a9546SAutomerger Merge Worker O_HMARK_DADDR_MASK,
47*a71a9546SAutomerger Merge Worker O_HMARK_SPI,
48*a71a9546SAutomerger Merge Worker O_HMARK_SPI_MASK,
49*a71a9546SAutomerger Merge Worker O_HMARK_SPORT,
50*a71a9546SAutomerger Merge Worker O_HMARK_DPORT,
51*a71a9546SAutomerger Merge Worker O_HMARK_SPORT_MASK,
52*a71a9546SAutomerger Merge Worker O_HMARK_DPORT_MASK,
53*a71a9546SAutomerger Merge Worker O_HMARK_PROTO_MASK,
54*a71a9546SAutomerger Merge Worker O_HMARK_RND,
55*a71a9546SAutomerger Merge Worker O_HMARK_MODULUS,
56*a71a9546SAutomerger Merge Worker O_HMARK_OFFSET,
57*a71a9546SAutomerger Merge Worker O_HMARK_CT,
58*a71a9546SAutomerger Merge Worker O_HMARK_TYPE,
59*a71a9546SAutomerger Merge Worker };
60*a71a9546SAutomerger Merge Worker
61*a71a9546SAutomerger Merge Worker #define HMARK_OPT_PKT_MASK \
62*a71a9546SAutomerger Merge Worker ((1 << O_HMARK_SADDR_MASK) | \
63*a71a9546SAutomerger Merge Worker (1 << O_HMARK_DADDR_MASK) | \
64*a71a9546SAutomerger Merge Worker (1 << O_HMARK_SPI_MASK) | \
65*a71a9546SAutomerger Merge Worker (1 << O_HMARK_SPORT_MASK) | \
66*a71a9546SAutomerger Merge Worker (1 << O_HMARK_DPORT_MASK) | \
67*a71a9546SAutomerger Merge Worker (1 << O_HMARK_PROTO_MASK) | \
68*a71a9546SAutomerger Merge Worker (1 << O_HMARK_SPI_MASK) | \
69*a71a9546SAutomerger Merge Worker (1 << O_HMARK_SPORT) | \
70*a71a9546SAutomerger Merge Worker (1 << O_HMARK_DPORT) | \
71*a71a9546SAutomerger Merge Worker (1 << O_HMARK_SPI))
72*a71a9546SAutomerger Merge Worker
73*a71a9546SAutomerger Merge Worker static const struct xt_option_entry HMARK_opts[] = {
74*a71a9546SAutomerger Merge Worker { .name = "hmark-tuple",
75*a71a9546SAutomerger Merge Worker .type = XTTYPE_STRING,
76*a71a9546SAutomerger Merge Worker .id = O_HMARK_TYPE,
77*a71a9546SAutomerger Merge Worker },
78*a71a9546SAutomerger Merge Worker { .name = "hmark-src-prefix",
79*a71a9546SAutomerger Merge Worker .type = XTTYPE_PLENMASK,
80*a71a9546SAutomerger Merge Worker .id = O_HMARK_SADDR_MASK,
81*a71a9546SAutomerger Merge Worker .flags = XTOPT_PUT, XTOPT_POINTER(hi, src_mask)
82*a71a9546SAutomerger Merge Worker },
83*a71a9546SAutomerger Merge Worker { .name = "hmark-dst-prefix",
84*a71a9546SAutomerger Merge Worker .type = XTTYPE_PLENMASK,
85*a71a9546SAutomerger Merge Worker .id = O_HMARK_DADDR_MASK,
86*a71a9546SAutomerger Merge Worker .flags = XTOPT_PUT, XTOPT_POINTER(hi, dst_mask)
87*a71a9546SAutomerger Merge Worker },
88*a71a9546SAutomerger Merge Worker { .name = "hmark-sport-mask",
89*a71a9546SAutomerger Merge Worker .type = XTTYPE_UINT16,
90*a71a9546SAutomerger Merge Worker .id = O_HMARK_SPORT_MASK,
91*a71a9546SAutomerger Merge Worker .flags = XTOPT_PUT, XTOPT_POINTER(hi, port_mask.p16.src)
92*a71a9546SAutomerger Merge Worker },
93*a71a9546SAutomerger Merge Worker { .name = "hmark-dport-mask",
94*a71a9546SAutomerger Merge Worker .type = XTTYPE_UINT16,
95*a71a9546SAutomerger Merge Worker .id = O_HMARK_DPORT_MASK,
96*a71a9546SAutomerger Merge Worker .flags = XTOPT_PUT, XTOPT_POINTER(hi, port_mask.p16.dst)
97*a71a9546SAutomerger Merge Worker },
98*a71a9546SAutomerger Merge Worker { .name = "hmark-spi-mask",
99*a71a9546SAutomerger Merge Worker .type = XTTYPE_UINT32,
100*a71a9546SAutomerger Merge Worker .id = O_HMARK_SPI_MASK,
101*a71a9546SAutomerger Merge Worker .flags = XTOPT_PUT, XTOPT_POINTER(hi, port_mask.v32)
102*a71a9546SAutomerger Merge Worker },
103*a71a9546SAutomerger Merge Worker { .name = "hmark-sport",
104*a71a9546SAutomerger Merge Worker .type = XTTYPE_UINT16,
105*a71a9546SAutomerger Merge Worker .id = O_HMARK_SPORT,
106*a71a9546SAutomerger Merge Worker .flags = XTOPT_PUT, XTOPT_POINTER(hi, port_set.p16.src)
107*a71a9546SAutomerger Merge Worker },
108*a71a9546SAutomerger Merge Worker { .name = "hmark-dport",
109*a71a9546SAutomerger Merge Worker .type = XTTYPE_UINT16,
110*a71a9546SAutomerger Merge Worker .id = O_HMARK_DPORT,
111*a71a9546SAutomerger Merge Worker .flags = XTOPT_PUT, XTOPT_POINTER(hi, port_set.p16.dst)
112*a71a9546SAutomerger Merge Worker },
113*a71a9546SAutomerger Merge Worker { .name = "hmark-spi",
114*a71a9546SAutomerger Merge Worker .type = XTTYPE_UINT32,
115*a71a9546SAutomerger Merge Worker .id = O_HMARK_SPI,
116*a71a9546SAutomerger Merge Worker .flags = XTOPT_PUT, XTOPT_POINTER(hi, port_set.v32)
117*a71a9546SAutomerger Merge Worker },
118*a71a9546SAutomerger Merge Worker { .name = "hmark-proto-mask",
119*a71a9546SAutomerger Merge Worker .type = XTTYPE_UINT16,
120*a71a9546SAutomerger Merge Worker .id = O_HMARK_PROTO_MASK,
121*a71a9546SAutomerger Merge Worker .flags = XTOPT_PUT, XTOPT_POINTER(hi, proto_mask)
122*a71a9546SAutomerger Merge Worker },
123*a71a9546SAutomerger Merge Worker { .name = "hmark-rnd",
124*a71a9546SAutomerger Merge Worker .type = XTTYPE_UINT32,
125*a71a9546SAutomerger Merge Worker .id = O_HMARK_RND,
126*a71a9546SAutomerger Merge Worker .flags = XTOPT_PUT, XTOPT_POINTER(hi, hashrnd)
127*a71a9546SAutomerger Merge Worker },
128*a71a9546SAutomerger Merge Worker { .name = "hmark-mod",
129*a71a9546SAutomerger Merge Worker .type = XTTYPE_UINT32,
130*a71a9546SAutomerger Merge Worker .id = O_HMARK_MODULUS,
131*a71a9546SAutomerger Merge Worker .min = 1,
132*a71a9546SAutomerger Merge Worker .flags = XTOPT_PUT | XTOPT_MAND, XTOPT_POINTER(hi, hmodulus)
133*a71a9546SAutomerger Merge Worker },
134*a71a9546SAutomerger Merge Worker { .name = "hmark-offset",
135*a71a9546SAutomerger Merge Worker .type = XTTYPE_UINT32,
136*a71a9546SAutomerger Merge Worker .id = O_HMARK_OFFSET,
137*a71a9546SAutomerger Merge Worker .flags = XTOPT_PUT, XTOPT_POINTER(hi, hoffset)
138*a71a9546SAutomerger Merge Worker },
139*a71a9546SAutomerger Merge Worker XTOPT_TABLEEND,
140*a71a9546SAutomerger Merge Worker };
141*a71a9546SAutomerger Merge Worker
142*a71a9546SAutomerger Merge Worker static int
hmark_parse(const char * type,size_t len,struct xt_hmark_info * info,unsigned int * xflags)143*a71a9546SAutomerger Merge Worker hmark_parse(const char *type, size_t len, struct xt_hmark_info *info,
144*a71a9546SAutomerger Merge Worker unsigned int *xflags)
145*a71a9546SAutomerger Merge Worker {
146*a71a9546SAutomerger Merge Worker if (strncasecmp(type, "ct", len) == 0) {
147*a71a9546SAutomerger Merge Worker info->flags |= XT_HMARK_FLAG(XT_HMARK_CT);
148*a71a9546SAutomerger Merge Worker *xflags |= (1 << O_HMARK_CT);
149*a71a9546SAutomerger Merge Worker } else if (strncasecmp(type, "src", len) == 0) {
150*a71a9546SAutomerger Merge Worker memset(&info->src_mask, 0xff, sizeof(info->src_mask));
151*a71a9546SAutomerger Merge Worker info->flags |= XT_HMARK_FLAG(XT_HMARK_SADDR_MASK);
152*a71a9546SAutomerger Merge Worker *xflags |= (1 << O_HMARK_SADDR_MASK);
153*a71a9546SAutomerger Merge Worker } else if (strncasecmp(type, "dst", len) == 0) {
154*a71a9546SAutomerger Merge Worker memset(&info->dst_mask, 0xff, sizeof(info->dst_mask));
155*a71a9546SAutomerger Merge Worker info->flags |= XT_HMARK_FLAG(XT_HMARK_DADDR_MASK);
156*a71a9546SAutomerger Merge Worker *xflags |= (1 << O_HMARK_DADDR_MASK);
157*a71a9546SAutomerger Merge Worker } else if (strncasecmp(type, "sport", len) == 0) {
158*a71a9546SAutomerger Merge Worker memset(&info->port_mask.p16.src, 0xff,
159*a71a9546SAutomerger Merge Worker sizeof(info->port_mask.p16.src));
160*a71a9546SAutomerger Merge Worker info->flags |= XT_HMARK_FLAG(XT_HMARK_SPORT_MASK);
161*a71a9546SAutomerger Merge Worker *xflags |= (1 << O_HMARK_SPORT_MASK);
162*a71a9546SAutomerger Merge Worker } else if (strncasecmp(type, "dport", len) == 0) {
163*a71a9546SAutomerger Merge Worker memset(&info->port_mask.p16.dst, 0xff,
164*a71a9546SAutomerger Merge Worker sizeof(info->port_mask.p16.dst));
165*a71a9546SAutomerger Merge Worker info->flags |= XT_HMARK_FLAG(XT_HMARK_DPORT_MASK);
166*a71a9546SAutomerger Merge Worker *xflags |= (1 << O_HMARK_DPORT_MASK);
167*a71a9546SAutomerger Merge Worker } else if (strncasecmp(type, "proto", len) == 0) {
168*a71a9546SAutomerger Merge Worker memset(&info->proto_mask, 0xff, sizeof(info->proto_mask));
169*a71a9546SAutomerger Merge Worker info->flags |= XT_HMARK_FLAG(XT_HMARK_PROTO_MASK);
170*a71a9546SAutomerger Merge Worker *xflags |= (1 << O_HMARK_PROTO_MASK);
171*a71a9546SAutomerger Merge Worker } else if (strncasecmp(type, "spi", len) == 0) {
172*a71a9546SAutomerger Merge Worker memset(&info->port_mask.v32, 0xff, sizeof(info->port_mask.v32));
173*a71a9546SAutomerger Merge Worker info->flags |= XT_HMARK_FLAG(XT_HMARK_SPI_MASK);
174*a71a9546SAutomerger Merge Worker *xflags |= (1 << O_HMARK_SPI_MASK);
175*a71a9546SAutomerger Merge Worker } else
176*a71a9546SAutomerger Merge Worker return 0;
177*a71a9546SAutomerger Merge Worker
178*a71a9546SAutomerger Merge Worker return 1;
179*a71a9546SAutomerger Merge Worker }
180*a71a9546SAutomerger Merge Worker
181*a71a9546SAutomerger Merge Worker static void
hmark_parse_type(struct xt_option_call * cb)182*a71a9546SAutomerger Merge Worker hmark_parse_type(struct xt_option_call *cb)
183*a71a9546SAutomerger Merge Worker {
184*a71a9546SAutomerger Merge Worker const char *arg = cb->arg;
185*a71a9546SAutomerger Merge Worker struct xt_hmark_info *info = cb->data;
186*a71a9546SAutomerger Merge Worker const char *comma;
187*a71a9546SAutomerger Merge Worker
188*a71a9546SAutomerger Merge Worker while ((comma = strchr(arg, ',')) != NULL) {
189*a71a9546SAutomerger Merge Worker if (comma == arg ||
190*a71a9546SAutomerger Merge Worker !hmark_parse(arg, comma-arg, info, &cb->xflags))
191*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, "Bad type \"%s\"", arg);
192*a71a9546SAutomerger Merge Worker arg = comma+1;
193*a71a9546SAutomerger Merge Worker }
194*a71a9546SAutomerger Merge Worker if (!*arg)
195*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, "\"--hmark-tuple\" requires "
196*a71a9546SAutomerger Merge Worker "a list of types with no "
197*a71a9546SAutomerger Merge Worker "spaces, e.g. "
198*a71a9546SAutomerger Merge Worker "src,dst,sport,dport,proto");
199*a71a9546SAutomerger Merge Worker if (strlen(arg) == 0 ||
200*a71a9546SAutomerger Merge Worker !hmark_parse(arg, strlen(arg), info, &cb->xflags))
201*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, "Bad type \"%s\"", arg);
202*a71a9546SAutomerger Merge Worker }
203*a71a9546SAutomerger Merge Worker
HMARK_parse(struct xt_option_call * cb,int plen)204*a71a9546SAutomerger Merge Worker static void HMARK_parse(struct xt_option_call *cb, int plen)
205*a71a9546SAutomerger Merge Worker {
206*a71a9546SAutomerger Merge Worker struct xt_hmark_info *info = cb->data;
207*a71a9546SAutomerger Merge Worker
208*a71a9546SAutomerger Merge Worker xtables_option_parse(cb);
209*a71a9546SAutomerger Merge Worker
210*a71a9546SAutomerger Merge Worker switch (cb->entry->id) {
211*a71a9546SAutomerger Merge Worker case O_HMARK_TYPE:
212*a71a9546SAutomerger Merge Worker hmark_parse_type(cb);
213*a71a9546SAutomerger Merge Worker break;
214*a71a9546SAutomerger Merge Worker case O_HMARK_SADDR_MASK:
215*a71a9546SAutomerger Merge Worker info->flags |= XT_HMARK_FLAG(XT_HMARK_SADDR_MASK);
216*a71a9546SAutomerger Merge Worker break;
217*a71a9546SAutomerger Merge Worker case O_HMARK_DADDR_MASK:
218*a71a9546SAutomerger Merge Worker info->flags |= XT_HMARK_FLAG(XT_HMARK_DADDR_MASK);
219*a71a9546SAutomerger Merge Worker break;
220*a71a9546SAutomerger Merge Worker case O_HMARK_SPI:
221*a71a9546SAutomerger Merge Worker info->port_set.v32 = htonl(cb->val.u32);
222*a71a9546SAutomerger Merge Worker info->flags |= XT_HMARK_FLAG(XT_HMARK_SPI);
223*a71a9546SAutomerger Merge Worker break;
224*a71a9546SAutomerger Merge Worker case O_HMARK_SPORT:
225*a71a9546SAutomerger Merge Worker info->port_set.p16.src = htons(cb->val.u16);
226*a71a9546SAutomerger Merge Worker info->flags |= XT_HMARK_FLAG(XT_HMARK_SPORT);
227*a71a9546SAutomerger Merge Worker break;
228*a71a9546SAutomerger Merge Worker case O_HMARK_DPORT:
229*a71a9546SAutomerger Merge Worker info->port_set.p16.dst = htons(cb->val.u16);
230*a71a9546SAutomerger Merge Worker info->flags |= XT_HMARK_FLAG(XT_HMARK_DPORT);
231*a71a9546SAutomerger Merge Worker break;
232*a71a9546SAutomerger Merge Worker case O_HMARK_SPORT_MASK:
233*a71a9546SAutomerger Merge Worker info->port_mask.p16.src = htons(cb->val.u16);
234*a71a9546SAutomerger Merge Worker info->flags |= XT_HMARK_FLAG(XT_HMARK_SPORT_MASK);
235*a71a9546SAutomerger Merge Worker break;
236*a71a9546SAutomerger Merge Worker case O_HMARK_DPORT_MASK:
237*a71a9546SAutomerger Merge Worker info->port_mask.p16.dst = htons(cb->val.u16);
238*a71a9546SAutomerger Merge Worker info->flags |= XT_HMARK_FLAG(XT_HMARK_DPORT_MASK);
239*a71a9546SAutomerger Merge Worker break;
240*a71a9546SAutomerger Merge Worker case O_HMARK_SPI_MASK:
241*a71a9546SAutomerger Merge Worker info->port_mask.v32 = htonl(cb->val.u32);
242*a71a9546SAutomerger Merge Worker info->flags |= XT_HMARK_FLAG(XT_HMARK_SPI_MASK);
243*a71a9546SAutomerger Merge Worker break;
244*a71a9546SAutomerger Merge Worker case O_HMARK_PROTO_MASK:
245*a71a9546SAutomerger Merge Worker info->flags |= XT_HMARK_FLAG(XT_HMARK_PROTO_MASK);
246*a71a9546SAutomerger Merge Worker break;
247*a71a9546SAutomerger Merge Worker case O_HMARK_RND:
248*a71a9546SAutomerger Merge Worker info->flags |= XT_HMARK_FLAG(XT_HMARK_RND);
249*a71a9546SAutomerger Merge Worker break;
250*a71a9546SAutomerger Merge Worker case O_HMARK_MODULUS:
251*a71a9546SAutomerger Merge Worker info->flags |= XT_HMARK_FLAG(XT_HMARK_MODULUS);
252*a71a9546SAutomerger Merge Worker break;
253*a71a9546SAutomerger Merge Worker case O_HMARK_OFFSET:
254*a71a9546SAutomerger Merge Worker info->flags |= XT_HMARK_FLAG(XT_HMARK_OFFSET);
255*a71a9546SAutomerger Merge Worker break;
256*a71a9546SAutomerger Merge Worker case O_HMARK_CT:
257*a71a9546SAutomerger Merge Worker info->flags |= XT_HMARK_FLAG(XT_HMARK_CT);
258*a71a9546SAutomerger Merge Worker break;
259*a71a9546SAutomerger Merge Worker }
260*a71a9546SAutomerger Merge Worker cb->xflags |= (1 << cb->entry->id);
261*a71a9546SAutomerger Merge Worker }
262*a71a9546SAutomerger Merge Worker
HMARK_ip4_parse(struct xt_option_call * cb)263*a71a9546SAutomerger Merge Worker static void HMARK_ip4_parse(struct xt_option_call *cb)
264*a71a9546SAutomerger Merge Worker {
265*a71a9546SAutomerger Merge Worker HMARK_parse(cb, 32);
266*a71a9546SAutomerger Merge Worker }
HMARK_ip6_parse(struct xt_option_call * cb)267*a71a9546SAutomerger Merge Worker static void HMARK_ip6_parse(struct xt_option_call *cb)
268*a71a9546SAutomerger Merge Worker {
269*a71a9546SAutomerger Merge Worker HMARK_parse(cb, 128);
270*a71a9546SAutomerger Merge Worker }
271*a71a9546SAutomerger Merge Worker
HMARK_check(struct xt_fcheck_call * cb)272*a71a9546SAutomerger Merge Worker static void HMARK_check(struct xt_fcheck_call *cb)
273*a71a9546SAutomerger Merge Worker {
274*a71a9546SAutomerger Merge Worker if (!(cb->xflags & (1 << O_HMARK_MODULUS)))
275*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, "--hmark-mod is mandatory");
276*a71a9546SAutomerger Merge Worker if (!(cb->xflags & (1 << O_HMARK_RND)))
277*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, "--hmark-rnd is mandatory");
278*a71a9546SAutomerger Merge Worker if (cb->xflags & (1 << O_HMARK_SPI_MASK) &&
279*a71a9546SAutomerger Merge Worker (cb->xflags & ((1 << O_HMARK_SPORT_MASK) |
280*a71a9546SAutomerger Merge Worker (1 << O_HMARK_DPORT_MASK))))
281*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, "you cannot use "
282*a71a9546SAutomerger Merge Worker "--hmark-spi-mask and --hmark-?port-mask,"
283*a71a9546SAutomerger Merge Worker "at the same time");
284*a71a9546SAutomerger Merge Worker if (!((cb->xflags & HMARK_OPT_PKT_MASK) ||
285*a71a9546SAutomerger Merge Worker cb->xflags & (1 << O_HMARK_CT)))
286*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM, "you have to specify "
287*a71a9546SAutomerger Merge Worker "--hmark-tuple at least");
288*a71a9546SAutomerger Merge Worker }
289*a71a9546SAutomerger Merge Worker
HMARK_print(const struct xt_hmark_info * info)290*a71a9546SAutomerger Merge Worker static void HMARK_print(const struct xt_hmark_info *info)
291*a71a9546SAutomerger Merge Worker {
292*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPORT_MASK))
293*a71a9546SAutomerger Merge Worker printf("sport-mask 0x%x ", htons(info->port_mask.p16.src));
294*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_DPORT_MASK))
295*a71a9546SAutomerger Merge Worker printf("dport-mask 0x%x ", htons(info->port_mask.p16.dst));
296*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPI_MASK))
297*a71a9546SAutomerger Merge Worker printf("spi-mask 0x%x ", htonl(info->port_mask.v32));
298*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPORT))
299*a71a9546SAutomerger Merge Worker printf("sport 0x%x ", htons(info->port_set.p16.src));
300*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_DPORT))
301*a71a9546SAutomerger Merge Worker printf("dport 0x%x ", htons(info->port_set.p16.dst));
302*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPI))
303*a71a9546SAutomerger Merge Worker printf("spi 0x%x ", htonl(info->port_set.v32));
304*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_PROTO_MASK))
305*a71a9546SAutomerger Merge Worker printf("proto-mask 0x%x ", info->proto_mask);
306*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_RND))
307*a71a9546SAutomerger Merge Worker printf("rnd 0x%x ", info->hashrnd);
308*a71a9546SAutomerger Merge Worker }
309*a71a9546SAutomerger Merge Worker
HMARK_ip6_print(const void * ip,const struct xt_entry_target * target,int numeric)310*a71a9546SAutomerger Merge Worker static void HMARK_ip6_print(const void *ip,
311*a71a9546SAutomerger Merge Worker const struct xt_entry_target *target, int numeric)
312*a71a9546SAutomerger Merge Worker {
313*a71a9546SAutomerger Merge Worker const struct xt_hmark_info *info =
314*a71a9546SAutomerger Merge Worker (const struct xt_hmark_info *)target->data;
315*a71a9546SAutomerger Merge Worker
316*a71a9546SAutomerger Merge Worker printf(" HMARK ");
317*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_MODULUS))
318*a71a9546SAutomerger Merge Worker printf("mod %u ", info->hmodulus);
319*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_OFFSET))
320*a71a9546SAutomerger Merge Worker printf("+ 0x%x ", info->hoffset);
321*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_CT))
322*a71a9546SAutomerger Merge Worker printf("ct, ");
323*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_SADDR_MASK))
324*a71a9546SAutomerger Merge Worker printf("src-prefix %s ",
325*a71a9546SAutomerger Merge Worker xtables_ip6mask_to_numeric(&info->src_mask.in6) + 1);
326*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_DADDR_MASK))
327*a71a9546SAutomerger Merge Worker printf("dst-prefix %s ",
328*a71a9546SAutomerger Merge Worker xtables_ip6mask_to_numeric(&info->dst_mask.in6) + 1);
329*a71a9546SAutomerger Merge Worker HMARK_print(info);
330*a71a9546SAutomerger Merge Worker }
HMARK_ip4_print(const void * ip,const struct xt_entry_target * target,int numeric)331*a71a9546SAutomerger Merge Worker static void HMARK_ip4_print(const void *ip,
332*a71a9546SAutomerger Merge Worker const struct xt_entry_target *target, int numeric)
333*a71a9546SAutomerger Merge Worker {
334*a71a9546SAutomerger Merge Worker const struct xt_hmark_info *info =
335*a71a9546SAutomerger Merge Worker (const struct xt_hmark_info *)target->data;
336*a71a9546SAutomerger Merge Worker
337*a71a9546SAutomerger Merge Worker printf(" HMARK ");
338*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_MODULUS))
339*a71a9546SAutomerger Merge Worker printf("mod %u ", info->hmodulus);
340*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_OFFSET))
341*a71a9546SAutomerger Merge Worker printf("+ 0x%x ", info->hoffset);
342*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_CT))
343*a71a9546SAutomerger Merge Worker printf("ct, ");
344*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_SADDR_MASK))
345*a71a9546SAutomerger Merge Worker printf("src-prefix %u ",
346*a71a9546SAutomerger Merge Worker xtables_ipmask_to_cidr(&info->src_mask.in));
347*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_DADDR_MASK))
348*a71a9546SAutomerger Merge Worker printf("dst-prefix %u ",
349*a71a9546SAutomerger Merge Worker xtables_ipmask_to_cidr(&info->dst_mask.in));
350*a71a9546SAutomerger Merge Worker HMARK_print(info);
351*a71a9546SAutomerger Merge Worker }
352*a71a9546SAutomerger Merge Worker
HMARK_save(const struct xt_hmark_info * info)353*a71a9546SAutomerger Merge Worker static void HMARK_save(const struct xt_hmark_info *info)
354*a71a9546SAutomerger Merge Worker {
355*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPORT_MASK))
356*a71a9546SAutomerger Merge Worker printf(" --hmark-sport-mask 0x%04x",
357*a71a9546SAutomerger Merge Worker htons(info->port_mask.p16.src));
358*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_DPORT_MASK))
359*a71a9546SAutomerger Merge Worker printf(" --hmark-dport-mask 0x%04x",
360*a71a9546SAutomerger Merge Worker htons(info->port_mask.p16.dst));
361*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPI_MASK))
362*a71a9546SAutomerger Merge Worker printf(" --hmark-spi-mask 0x%08x",
363*a71a9546SAutomerger Merge Worker htonl(info->port_mask.v32));
364*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPORT))
365*a71a9546SAutomerger Merge Worker printf(" --hmark-sport 0x%04x",
366*a71a9546SAutomerger Merge Worker htons(info->port_set.p16.src));
367*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_DPORT))
368*a71a9546SAutomerger Merge Worker printf(" --hmark-dport 0x%04x",
369*a71a9546SAutomerger Merge Worker htons(info->port_set.p16.dst));
370*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPI))
371*a71a9546SAutomerger Merge Worker printf(" --hmark-spi 0x%08x", htonl(info->port_set.v32));
372*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_PROTO_MASK))
373*a71a9546SAutomerger Merge Worker printf(" --hmark-proto-mask 0x%02x", info->proto_mask);
374*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_RND))
375*a71a9546SAutomerger Merge Worker printf(" --hmark-rnd 0x%08x", info->hashrnd);
376*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_MODULUS))
377*a71a9546SAutomerger Merge Worker printf(" --hmark-mod %u", info->hmodulus);
378*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_OFFSET))
379*a71a9546SAutomerger Merge Worker printf(" --hmark-offset %u", info->hoffset);
380*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_CT))
381*a71a9546SAutomerger Merge Worker printf(" --hmark-tuple ct");
382*a71a9546SAutomerger Merge Worker }
383*a71a9546SAutomerger Merge Worker
HMARK_ip6_save(const void * ip,const struct xt_entry_target * target)384*a71a9546SAutomerger Merge Worker static void HMARK_ip6_save(const void *ip, const struct xt_entry_target *target)
385*a71a9546SAutomerger Merge Worker {
386*a71a9546SAutomerger Merge Worker const struct xt_hmark_info *info =
387*a71a9546SAutomerger Merge Worker (const struct xt_hmark_info *)target->data;
388*a71a9546SAutomerger Merge Worker int ret;
389*a71a9546SAutomerger Merge Worker
390*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_SADDR_MASK)) {
391*a71a9546SAutomerger Merge Worker ret = xtables_ip6mask_to_cidr(&info->src_mask.in6);
392*a71a9546SAutomerger Merge Worker printf(" --hmark-src-prefix %d", ret);
393*a71a9546SAutomerger Merge Worker }
394*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_DADDR_MASK)) {
395*a71a9546SAutomerger Merge Worker ret = xtables_ip6mask_to_cidr(&info->dst_mask.in6);
396*a71a9546SAutomerger Merge Worker printf(" --hmark-dst-prefix %d", ret);
397*a71a9546SAutomerger Merge Worker }
398*a71a9546SAutomerger Merge Worker HMARK_save(info);
399*a71a9546SAutomerger Merge Worker }
400*a71a9546SAutomerger Merge Worker
HMARK_ip4_save(const void * ip,const struct xt_entry_target * target)401*a71a9546SAutomerger Merge Worker static void HMARK_ip4_save(const void *ip, const struct xt_entry_target *target)
402*a71a9546SAutomerger Merge Worker {
403*a71a9546SAutomerger Merge Worker const struct xt_hmark_info *info =
404*a71a9546SAutomerger Merge Worker (const struct xt_hmark_info *)target->data;
405*a71a9546SAutomerger Merge Worker int ret;
406*a71a9546SAutomerger Merge Worker
407*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_SADDR_MASK)) {
408*a71a9546SAutomerger Merge Worker ret = xtables_ipmask_to_cidr(&info->src_mask.in);
409*a71a9546SAutomerger Merge Worker printf(" --hmark-src-prefix %d", ret);
410*a71a9546SAutomerger Merge Worker }
411*a71a9546SAutomerger Merge Worker if (info->flags & XT_HMARK_FLAG(XT_HMARK_DADDR_MASK)) {
412*a71a9546SAutomerger Merge Worker ret = xtables_ipmask_to_cidr(&info->dst_mask.in);
413*a71a9546SAutomerger Merge Worker printf(" --hmark-dst-prefix %d", ret);
414*a71a9546SAutomerger Merge Worker }
415*a71a9546SAutomerger Merge Worker HMARK_save(info);
416*a71a9546SAutomerger Merge Worker }
417*a71a9546SAutomerger Merge Worker
418*a71a9546SAutomerger Merge Worker static struct xtables_target mark_tg_reg[] = {
419*a71a9546SAutomerger Merge Worker {
420*a71a9546SAutomerger Merge Worker .family = NFPROTO_IPV4,
421*a71a9546SAutomerger Merge Worker .name = "HMARK",
422*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION,
423*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_hmark_info)),
424*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_hmark_info)),
425*a71a9546SAutomerger Merge Worker .help = HMARK_help,
426*a71a9546SAutomerger Merge Worker .print = HMARK_ip4_print,
427*a71a9546SAutomerger Merge Worker .save = HMARK_ip4_save,
428*a71a9546SAutomerger Merge Worker .x6_parse = HMARK_ip4_parse,
429*a71a9546SAutomerger Merge Worker .x6_fcheck = HMARK_check,
430*a71a9546SAutomerger Merge Worker .x6_options = HMARK_opts,
431*a71a9546SAutomerger Merge Worker },
432*a71a9546SAutomerger Merge Worker {
433*a71a9546SAutomerger Merge Worker .family = NFPROTO_IPV6,
434*a71a9546SAutomerger Merge Worker .name = "HMARK",
435*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION,
436*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_hmark_info)),
437*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_hmark_info)),
438*a71a9546SAutomerger Merge Worker .help = HMARK_help,
439*a71a9546SAutomerger Merge Worker .print = HMARK_ip6_print,
440*a71a9546SAutomerger Merge Worker .save = HMARK_ip6_save,
441*a71a9546SAutomerger Merge Worker .x6_parse = HMARK_ip6_parse,
442*a71a9546SAutomerger Merge Worker .x6_fcheck = HMARK_check,
443*a71a9546SAutomerger Merge Worker .x6_options = HMARK_opts,
444*a71a9546SAutomerger Merge Worker },
445*a71a9546SAutomerger Merge Worker };
446*a71a9546SAutomerger Merge Worker
_init(void)447*a71a9546SAutomerger Merge Worker void _init(void)
448*a71a9546SAutomerger Merge Worker {
449*a71a9546SAutomerger Merge Worker xtables_register_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg));
450*a71a9546SAutomerger Merge Worker }
451