1*a71a9546SAutomerger Merge Worker #include <stdint.h>
2*a71a9546SAutomerger Merge Worker #include <stdio.h>
3*a71a9546SAutomerger Merge Worker #include <string.h>
4*a71a9546SAutomerger Merge Worker #include <stdlib.h>
5*a71a9546SAutomerger Merge Worker #include <xtables.h>
6*a71a9546SAutomerger Merge Worker #include <linux/netfilter.h>
7*a71a9546SAutomerger Merge Worker #include <linux/netfilter/xt_iprange.h>
8*a71a9546SAutomerger Merge Worker
9*a71a9546SAutomerger Merge Worker struct ipt_iprange {
10*a71a9546SAutomerger Merge Worker /* Inclusive: network order. */
11*a71a9546SAutomerger Merge Worker __be32 min_ip, max_ip;
12*a71a9546SAutomerger Merge Worker };
13*a71a9546SAutomerger Merge Worker
14*a71a9546SAutomerger Merge Worker struct ipt_iprange_info {
15*a71a9546SAutomerger Merge Worker struct ipt_iprange src;
16*a71a9546SAutomerger Merge Worker struct ipt_iprange dst;
17*a71a9546SAutomerger Merge Worker
18*a71a9546SAutomerger Merge Worker /* Flags from above */
19*a71a9546SAutomerger Merge Worker uint8_t flags;
20*a71a9546SAutomerger Merge Worker };
21*a71a9546SAutomerger Merge Worker
22*a71a9546SAutomerger Merge Worker enum {
23*a71a9546SAutomerger Merge Worker O_SRC_RANGE = 0,
24*a71a9546SAutomerger Merge Worker O_DST_RANGE,
25*a71a9546SAutomerger Merge Worker };
26*a71a9546SAutomerger Merge Worker
iprange_mt_help(void)27*a71a9546SAutomerger Merge Worker static void iprange_mt_help(void)
28*a71a9546SAutomerger Merge Worker {
29*a71a9546SAutomerger Merge Worker printf(
30*a71a9546SAutomerger Merge Worker "iprange match options:\n"
31*a71a9546SAutomerger Merge Worker "[!] --src-range ip[-ip] Match source IP in the specified range\n"
32*a71a9546SAutomerger Merge Worker "[!] --dst-range ip[-ip] Match destination IP in the specified range\n");
33*a71a9546SAutomerger Merge Worker }
34*a71a9546SAutomerger Merge Worker
35*a71a9546SAutomerger Merge Worker static const struct xt_option_entry iprange_mt_opts[] = {
36*a71a9546SAutomerger Merge Worker {.name = "src-range", .id = O_SRC_RANGE, .type = XTTYPE_STRING,
37*a71a9546SAutomerger Merge Worker .flags = XTOPT_INVERT},
38*a71a9546SAutomerger Merge Worker {.name = "dst-range", .id = O_DST_RANGE, .type = XTTYPE_STRING,
39*a71a9546SAutomerger Merge Worker .flags = XTOPT_INVERT},
40*a71a9546SAutomerger Merge Worker XTOPT_TABLEEND,
41*a71a9546SAutomerger Merge Worker };
42*a71a9546SAutomerger Merge Worker
43*a71a9546SAutomerger Merge Worker static void
iprange_parse_spec(const char * from,const char * to,union nf_inet_addr * range,uint8_t family,const char * optname)44*a71a9546SAutomerger Merge Worker iprange_parse_spec(const char *from, const char *to, union nf_inet_addr *range,
45*a71a9546SAutomerger Merge Worker uint8_t family, const char *optname)
46*a71a9546SAutomerger Merge Worker {
47*a71a9546SAutomerger Merge Worker const char *spec[2] = {from, to};
48*a71a9546SAutomerger Merge Worker struct in6_addr *ia6;
49*a71a9546SAutomerger Merge Worker struct in_addr *ia4;
50*a71a9546SAutomerger Merge Worker unsigned int i;
51*a71a9546SAutomerger Merge Worker
52*a71a9546SAutomerger Merge Worker memset(range, 0, sizeof(union nf_inet_addr) * 2);
53*a71a9546SAutomerger Merge Worker
54*a71a9546SAutomerger Merge Worker if (family == NFPROTO_IPV6) {
55*a71a9546SAutomerger Merge Worker for (i = 0; i < ARRAY_SIZE(spec); ++i) {
56*a71a9546SAutomerger Merge Worker ia6 = xtables_numeric_to_ip6addr(spec[i]);
57*a71a9546SAutomerger Merge Worker if (ia6 == NULL)
58*a71a9546SAutomerger Merge Worker xtables_param_act(XTF_BAD_VALUE, "iprange",
59*a71a9546SAutomerger Merge Worker optname, spec[i]);
60*a71a9546SAutomerger Merge Worker range[i].in6 = *ia6;
61*a71a9546SAutomerger Merge Worker }
62*a71a9546SAutomerger Merge Worker } else {
63*a71a9546SAutomerger Merge Worker for (i = 0; i < ARRAY_SIZE(spec); ++i) {
64*a71a9546SAutomerger Merge Worker ia4 = xtables_numeric_to_ipaddr(spec[i]);
65*a71a9546SAutomerger Merge Worker if (ia4 == NULL)
66*a71a9546SAutomerger Merge Worker xtables_param_act(XTF_BAD_VALUE, "iprange",
67*a71a9546SAutomerger Merge Worker optname, spec[i]);
68*a71a9546SAutomerger Merge Worker range[i].in = *ia4;
69*a71a9546SAutomerger Merge Worker }
70*a71a9546SAutomerger Merge Worker }
71*a71a9546SAutomerger Merge Worker }
72*a71a9546SAutomerger Merge Worker
iprange_parse_range(const char * oarg,union nf_inet_addr * range,uint8_t family,const char * optname)73*a71a9546SAutomerger Merge Worker static void iprange_parse_range(const char *oarg, union nf_inet_addr *range,
74*a71a9546SAutomerger Merge Worker uint8_t family, const char *optname)
75*a71a9546SAutomerger Merge Worker {
76*a71a9546SAutomerger Merge Worker char *arg = xtables_strdup(oarg);
77*a71a9546SAutomerger Merge Worker char *dash;
78*a71a9546SAutomerger Merge Worker
79*a71a9546SAutomerger Merge Worker dash = strchr(arg, '-');
80*a71a9546SAutomerger Merge Worker if (dash == NULL) {
81*a71a9546SAutomerger Merge Worker iprange_parse_spec(arg, arg, range, family, optname);
82*a71a9546SAutomerger Merge Worker free(arg);
83*a71a9546SAutomerger Merge Worker return;
84*a71a9546SAutomerger Merge Worker }
85*a71a9546SAutomerger Merge Worker
86*a71a9546SAutomerger Merge Worker *dash = '\0';
87*a71a9546SAutomerger Merge Worker iprange_parse_spec(arg, dash + 1, range, family, optname);
88*a71a9546SAutomerger Merge Worker if (memcmp(&range[0], &range[1], sizeof(*range)) > 0)
89*a71a9546SAutomerger Merge Worker fprintf(stderr, "xt_iprange: range %s-%s is reversed and "
90*a71a9546SAutomerger Merge Worker "will never match\n", arg, dash + 1);
91*a71a9546SAutomerger Merge Worker free(arg);
92*a71a9546SAutomerger Merge Worker }
93*a71a9546SAutomerger Merge Worker
iprange_parse(struct xt_option_call * cb)94*a71a9546SAutomerger Merge Worker static void iprange_parse(struct xt_option_call *cb)
95*a71a9546SAutomerger Merge Worker {
96*a71a9546SAutomerger Merge Worker struct ipt_iprange_info *info = cb->data;
97*a71a9546SAutomerger Merge Worker union nf_inet_addr range[2];
98*a71a9546SAutomerger Merge Worker
99*a71a9546SAutomerger Merge Worker xtables_option_parse(cb);
100*a71a9546SAutomerger Merge Worker switch (cb->entry->id) {
101*a71a9546SAutomerger Merge Worker case O_SRC_RANGE:
102*a71a9546SAutomerger Merge Worker info->flags |= IPRANGE_SRC;
103*a71a9546SAutomerger Merge Worker if (cb->invert)
104*a71a9546SAutomerger Merge Worker info->flags |= IPRANGE_SRC_INV;
105*a71a9546SAutomerger Merge Worker iprange_parse_range(cb->arg, range,
106*a71a9546SAutomerger Merge Worker NFPROTO_IPV4, "--src-range");
107*a71a9546SAutomerger Merge Worker info->src.min_ip = range[0].ip;
108*a71a9546SAutomerger Merge Worker info->src.max_ip = range[1].ip;
109*a71a9546SAutomerger Merge Worker break;
110*a71a9546SAutomerger Merge Worker case O_DST_RANGE:
111*a71a9546SAutomerger Merge Worker info->flags |= IPRANGE_DST;
112*a71a9546SAutomerger Merge Worker if (cb->invert)
113*a71a9546SAutomerger Merge Worker info->flags |= IPRANGE_DST_INV;
114*a71a9546SAutomerger Merge Worker iprange_parse_range(cb->arg, range,
115*a71a9546SAutomerger Merge Worker NFPROTO_IPV4, "--dst-range");
116*a71a9546SAutomerger Merge Worker info->dst.min_ip = range[0].ip;
117*a71a9546SAutomerger Merge Worker info->dst.max_ip = range[1].ip;
118*a71a9546SAutomerger Merge Worker break;
119*a71a9546SAutomerger Merge Worker }
120*a71a9546SAutomerger Merge Worker }
121*a71a9546SAutomerger Merge Worker
iprange_mt_parse(struct xt_option_call * cb,uint8_t nfproto)122*a71a9546SAutomerger Merge Worker static void iprange_mt_parse(struct xt_option_call *cb, uint8_t nfproto)
123*a71a9546SAutomerger Merge Worker {
124*a71a9546SAutomerger Merge Worker struct xt_iprange_mtinfo *info = cb->data;
125*a71a9546SAutomerger Merge Worker
126*a71a9546SAutomerger Merge Worker xtables_option_parse(cb);
127*a71a9546SAutomerger Merge Worker switch (cb->entry->id) {
128*a71a9546SAutomerger Merge Worker case O_SRC_RANGE:
129*a71a9546SAutomerger Merge Worker iprange_parse_range(cb->arg, &info->src_min, nfproto,
130*a71a9546SAutomerger Merge Worker "--src-range");
131*a71a9546SAutomerger Merge Worker info->flags |= IPRANGE_SRC;
132*a71a9546SAutomerger Merge Worker if (cb->invert)
133*a71a9546SAutomerger Merge Worker info->flags |= IPRANGE_SRC_INV;
134*a71a9546SAutomerger Merge Worker break;
135*a71a9546SAutomerger Merge Worker case O_DST_RANGE:
136*a71a9546SAutomerger Merge Worker iprange_parse_range(cb->arg, &info->dst_min, nfproto,
137*a71a9546SAutomerger Merge Worker "--dst-range");
138*a71a9546SAutomerger Merge Worker info->flags |= IPRANGE_DST;
139*a71a9546SAutomerger Merge Worker if (cb->invert)
140*a71a9546SAutomerger Merge Worker info->flags |= IPRANGE_DST_INV;
141*a71a9546SAutomerger Merge Worker break;
142*a71a9546SAutomerger Merge Worker }
143*a71a9546SAutomerger Merge Worker }
144*a71a9546SAutomerger Merge Worker
iprange_mt4_parse(struct xt_option_call * cb)145*a71a9546SAutomerger Merge Worker static void iprange_mt4_parse(struct xt_option_call *cb)
146*a71a9546SAutomerger Merge Worker {
147*a71a9546SAutomerger Merge Worker iprange_mt_parse(cb, NFPROTO_IPV4);
148*a71a9546SAutomerger Merge Worker }
149*a71a9546SAutomerger Merge Worker
iprange_mt6_parse(struct xt_option_call * cb)150*a71a9546SAutomerger Merge Worker static void iprange_mt6_parse(struct xt_option_call *cb)
151*a71a9546SAutomerger Merge Worker {
152*a71a9546SAutomerger Merge Worker iprange_mt_parse(cb, NFPROTO_IPV6);
153*a71a9546SAutomerger Merge Worker }
154*a71a9546SAutomerger Merge Worker
iprange_mt_check(struct xt_fcheck_call * cb)155*a71a9546SAutomerger Merge Worker static void iprange_mt_check(struct xt_fcheck_call *cb)
156*a71a9546SAutomerger Merge Worker {
157*a71a9546SAutomerger Merge Worker if (cb->xflags == 0)
158*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM,
159*a71a9546SAutomerger Merge Worker "iprange match: You must specify `--src-range' or `--dst-range'");
160*a71a9546SAutomerger Merge Worker }
161*a71a9546SAutomerger Merge Worker
162*a71a9546SAutomerger Merge Worker static void
print_iprange(const struct ipt_iprange * range)163*a71a9546SAutomerger Merge Worker print_iprange(const struct ipt_iprange *range)
164*a71a9546SAutomerger Merge Worker {
165*a71a9546SAutomerger Merge Worker const unsigned char *byte_min, *byte_max;
166*a71a9546SAutomerger Merge Worker
167*a71a9546SAutomerger Merge Worker byte_min = (const unsigned char *)&range->min_ip;
168*a71a9546SAutomerger Merge Worker byte_max = (const unsigned char *)&range->max_ip;
169*a71a9546SAutomerger Merge Worker printf(" %u.%u.%u.%u-%u.%u.%u.%u",
170*a71a9546SAutomerger Merge Worker byte_min[0], byte_min[1], byte_min[2], byte_min[3],
171*a71a9546SAutomerger Merge Worker byte_max[0], byte_max[1], byte_max[2], byte_max[3]);
172*a71a9546SAutomerger Merge Worker }
173*a71a9546SAutomerger Merge Worker
iprange_print(const void * ip,const struct xt_entry_match * match,int numeric)174*a71a9546SAutomerger Merge Worker static void iprange_print(const void *ip, const struct xt_entry_match *match,
175*a71a9546SAutomerger Merge Worker int numeric)
176*a71a9546SAutomerger Merge Worker {
177*a71a9546SAutomerger Merge Worker const struct ipt_iprange_info *info = (const void *)match->data;
178*a71a9546SAutomerger Merge Worker
179*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_SRC) {
180*a71a9546SAutomerger Merge Worker printf(" source IP range");
181*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_SRC_INV)
182*a71a9546SAutomerger Merge Worker printf(" !");
183*a71a9546SAutomerger Merge Worker print_iprange(&info->src);
184*a71a9546SAutomerger Merge Worker }
185*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_DST) {
186*a71a9546SAutomerger Merge Worker printf(" destination IP range");
187*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_DST_INV)
188*a71a9546SAutomerger Merge Worker printf(" !");
189*a71a9546SAutomerger Merge Worker print_iprange(&info->dst);
190*a71a9546SAutomerger Merge Worker }
191*a71a9546SAutomerger Merge Worker }
192*a71a9546SAutomerger Merge Worker
193*a71a9546SAutomerger Merge Worker static void
iprange_mt4_print(const void * ip,const struct xt_entry_match * match,int numeric)194*a71a9546SAutomerger Merge Worker iprange_mt4_print(const void *ip, const struct xt_entry_match *match,
195*a71a9546SAutomerger Merge Worker int numeric)
196*a71a9546SAutomerger Merge Worker {
197*a71a9546SAutomerger Merge Worker const struct xt_iprange_mtinfo *info = (const void *)match->data;
198*a71a9546SAutomerger Merge Worker
199*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_SRC) {
200*a71a9546SAutomerger Merge Worker printf(" source IP range");
201*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_SRC_INV)
202*a71a9546SAutomerger Merge Worker printf(" !");
203*a71a9546SAutomerger Merge Worker /*
204*a71a9546SAutomerger Merge Worker * ipaddr_to_numeric() uses a static buffer, so cannot
205*a71a9546SAutomerger Merge Worker * combine the printf() calls.
206*a71a9546SAutomerger Merge Worker */
207*a71a9546SAutomerger Merge Worker printf(" %s", xtables_ipaddr_to_numeric(&info->src_min.in));
208*a71a9546SAutomerger Merge Worker printf("-%s", xtables_ipaddr_to_numeric(&info->src_max.in));
209*a71a9546SAutomerger Merge Worker }
210*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_DST) {
211*a71a9546SAutomerger Merge Worker printf(" destination IP range");
212*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_DST_INV)
213*a71a9546SAutomerger Merge Worker printf(" !");
214*a71a9546SAutomerger Merge Worker printf(" %s", xtables_ipaddr_to_numeric(&info->dst_min.in));
215*a71a9546SAutomerger Merge Worker printf("-%s", xtables_ipaddr_to_numeric(&info->dst_max.in));
216*a71a9546SAutomerger Merge Worker }
217*a71a9546SAutomerger Merge Worker }
218*a71a9546SAutomerger Merge Worker
219*a71a9546SAutomerger Merge Worker static void
iprange_mt6_print(const void * ip,const struct xt_entry_match * match,int numeric)220*a71a9546SAutomerger Merge Worker iprange_mt6_print(const void *ip, const struct xt_entry_match *match,
221*a71a9546SAutomerger Merge Worker int numeric)
222*a71a9546SAutomerger Merge Worker {
223*a71a9546SAutomerger Merge Worker const struct xt_iprange_mtinfo *info = (const void *)match->data;
224*a71a9546SAutomerger Merge Worker
225*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_SRC) {
226*a71a9546SAutomerger Merge Worker printf(" source IP range");
227*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_SRC_INV)
228*a71a9546SAutomerger Merge Worker printf(" !");
229*a71a9546SAutomerger Merge Worker /*
230*a71a9546SAutomerger Merge Worker * ipaddr_to_numeric() uses a static buffer, so cannot
231*a71a9546SAutomerger Merge Worker * combine the printf() calls.
232*a71a9546SAutomerger Merge Worker */
233*a71a9546SAutomerger Merge Worker printf(" %s", xtables_ip6addr_to_numeric(&info->src_min.in6));
234*a71a9546SAutomerger Merge Worker printf("-%s", xtables_ip6addr_to_numeric(&info->src_max.in6));
235*a71a9546SAutomerger Merge Worker }
236*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_DST) {
237*a71a9546SAutomerger Merge Worker printf(" destination IP range");
238*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_DST_INV)
239*a71a9546SAutomerger Merge Worker printf(" !");
240*a71a9546SAutomerger Merge Worker printf(" %s", xtables_ip6addr_to_numeric(&info->dst_min.in6));
241*a71a9546SAutomerger Merge Worker printf("-%s", xtables_ip6addr_to_numeric(&info->dst_max.in6));
242*a71a9546SAutomerger Merge Worker }
243*a71a9546SAutomerger Merge Worker }
244*a71a9546SAutomerger Merge Worker
iprange_save(const void * ip,const struct xt_entry_match * match)245*a71a9546SAutomerger Merge Worker static void iprange_save(const void *ip, const struct xt_entry_match *match)
246*a71a9546SAutomerger Merge Worker {
247*a71a9546SAutomerger Merge Worker const struct ipt_iprange_info *info = (const void *)match->data;
248*a71a9546SAutomerger Merge Worker
249*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_SRC) {
250*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_SRC_INV)
251*a71a9546SAutomerger Merge Worker printf(" !");
252*a71a9546SAutomerger Merge Worker printf(" --src-range");
253*a71a9546SAutomerger Merge Worker print_iprange(&info->src);
254*a71a9546SAutomerger Merge Worker }
255*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_DST) {
256*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_DST_INV)
257*a71a9546SAutomerger Merge Worker printf(" !");
258*a71a9546SAutomerger Merge Worker printf(" --dst-range");
259*a71a9546SAutomerger Merge Worker print_iprange(&info->dst);
260*a71a9546SAutomerger Merge Worker }
261*a71a9546SAutomerger Merge Worker }
262*a71a9546SAutomerger Merge Worker
iprange_mt4_save(const void * ip,const struct xt_entry_match * match)263*a71a9546SAutomerger Merge Worker static void iprange_mt4_save(const void *ip, const struct xt_entry_match *match)
264*a71a9546SAutomerger Merge Worker {
265*a71a9546SAutomerger Merge Worker const struct xt_iprange_mtinfo *info = (const void *)match->data;
266*a71a9546SAutomerger Merge Worker
267*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_SRC) {
268*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_SRC_INV)
269*a71a9546SAutomerger Merge Worker printf(" !");
270*a71a9546SAutomerger Merge Worker printf(" --src-range %s",
271*a71a9546SAutomerger Merge Worker xtables_ipaddr_to_numeric(&info->src_min.in));
272*a71a9546SAutomerger Merge Worker printf("-%s", xtables_ipaddr_to_numeric(&info->src_max.in));
273*a71a9546SAutomerger Merge Worker }
274*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_DST) {
275*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_DST_INV)
276*a71a9546SAutomerger Merge Worker printf(" !");
277*a71a9546SAutomerger Merge Worker printf(" --dst-range %s",
278*a71a9546SAutomerger Merge Worker xtables_ipaddr_to_numeric(&info->dst_min.in));
279*a71a9546SAutomerger Merge Worker printf("-%s", xtables_ipaddr_to_numeric(&info->dst_max.in));
280*a71a9546SAutomerger Merge Worker }
281*a71a9546SAutomerger Merge Worker }
282*a71a9546SAutomerger Merge Worker
iprange_mt6_save(const void * ip,const struct xt_entry_match * match)283*a71a9546SAutomerger Merge Worker static void iprange_mt6_save(const void *ip, const struct xt_entry_match *match)
284*a71a9546SAutomerger Merge Worker {
285*a71a9546SAutomerger Merge Worker const struct xt_iprange_mtinfo *info = (const void *)match->data;
286*a71a9546SAutomerger Merge Worker
287*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_SRC) {
288*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_SRC_INV)
289*a71a9546SAutomerger Merge Worker printf(" !");
290*a71a9546SAutomerger Merge Worker printf(" --src-range %s",
291*a71a9546SAutomerger Merge Worker xtables_ip6addr_to_numeric(&info->src_min.in6));
292*a71a9546SAutomerger Merge Worker printf("-%s", xtables_ip6addr_to_numeric(&info->src_max.in6));
293*a71a9546SAutomerger Merge Worker }
294*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_DST) {
295*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_DST_INV)
296*a71a9546SAutomerger Merge Worker printf(" !");
297*a71a9546SAutomerger Merge Worker printf(" --dst-range %s",
298*a71a9546SAutomerger Merge Worker xtables_ip6addr_to_numeric(&info->dst_min.in6));
299*a71a9546SAutomerger Merge Worker printf("-%s", xtables_ip6addr_to_numeric(&info->dst_max.in6));
300*a71a9546SAutomerger Merge Worker }
301*a71a9546SAutomerger Merge Worker }
302*a71a9546SAutomerger Merge Worker
303*a71a9546SAutomerger Merge Worker static void
print_iprange_xlate(const struct ipt_iprange * range,struct xt_xlate * xl)304*a71a9546SAutomerger Merge Worker print_iprange_xlate(const struct ipt_iprange *range,
305*a71a9546SAutomerger Merge Worker struct xt_xlate *xl)
306*a71a9546SAutomerger Merge Worker {
307*a71a9546SAutomerger Merge Worker const unsigned char *byte_min, *byte_max;
308*a71a9546SAutomerger Merge Worker
309*a71a9546SAutomerger Merge Worker byte_min = (const unsigned char *)&range->min_ip;
310*a71a9546SAutomerger Merge Worker byte_max = (const unsigned char *)&range->max_ip;
311*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, " %u.%u.%u.%u-%u.%u.%u.%u ",
312*a71a9546SAutomerger Merge Worker byte_min[0], byte_min[1], byte_min[2], byte_min[3],
313*a71a9546SAutomerger Merge Worker byte_max[0], byte_max[1], byte_max[2], byte_max[3]);
314*a71a9546SAutomerger Merge Worker }
315*a71a9546SAutomerger Merge Worker
iprange_xlate(struct xt_xlate * xl,const struct xt_xlate_mt_params * params)316*a71a9546SAutomerger Merge Worker static int iprange_xlate(struct xt_xlate *xl,
317*a71a9546SAutomerger Merge Worker const struct xt_xlate_mt_params *params)
318*a71a9546SAutomerger Merge Worker {
319*a71a9546SAutomerger Merge Worker const struct ipt_iprange_info *info = (const void *)params->match->data;
320*a71a9546SAutomerger Merge Worker
321*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_SRC) {
322*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "ip saddr%s",
323*a71a9546SAutomerger Merge Worker info->flags & IPRANGE_SRC_INV ? " !=" : "");
324*a71a9546SAutomerger Merge Worker print_iprange_xlate(&info->src, xl);
325*a71a9546SAutomerger Merge Worker }
326*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_DST) {
327*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "ip daddr%s",
328*a71a9546SAutomerger Merge Worker info->flags & IPRANGE_DST_INV ? " !=" : "");
329*a71a9546SAutomerger Merge Worker print_iprange_xlate(&info->dst, xl);
330*a71a9546SAutomerger Merge Worker }
331*a71a9546SAutomerger Merge Worker
332*a71a9546SAutomerger Merge Worker return 1;
333*a71a9546SAutomerger Merge Worker }
334*a71a9546SAutomerger Merge Worker
iprange_mt4_xlate(struct xt_xlate * xl,const struct xt_xlate_mt_params * params)335*a71a9546SAutomerger Merge Worker static int iprange_mt4_xlate(struct xt_xlate *xl,
336*a71a9546SAutomerger Merge Worker const struct xt_xlate_mt_params *params)
337*a71a9546SAutomerger Merge Worker {
338*a71a9546SAutomerger Merge Worker const struct xt_iprange_mtinfo *info =
339*a71a9546SAutomerger Merge Worker (const void *)params->match->data;
340*a71a9546SAutomerger Merge Worker
341*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_SRC) {
342*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "ip saddr%s %s",
343*a71a9546SAutomerger Merge Worker info->flags & IPRANGE_SRC_INV ? " !=" : "",
344*a71a9546SAutomerger Merge Worker xtables_ipaddr_to_numeric(&info->src_min.in));
345*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "-%s",
346*a71a9546SAutomerger Merge Worker xtables_ipaddr_to_numeric(&info->src_max.in));
347*a71a9546SAutomerger Merge Worker }
348*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_DST) {
349*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "ip daddr%s %s",
350*a71a9546SAutomerger Merge Worker info->flags & IPRANGE_DST_INV ? " !=" : "",
351*a71a9546SAutomerger Merge Worker xtables_ipaddr_to_numeric(&info->dst_min.in));
352*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "-%s",
353*a71a9546SAutomerger Merge Worker xtables_ipaddr_to_numeric(&info->dst_max.in));
354*a71a9546SAutomerger Merge Worker }
355*a71a9546SAutomerger Merge Worker
356*a71a9546SAutomerger Merge Worker return 1;
357*a71a9546SAutomerger Merge Worker }
358*a71a9546SAutomerger Merge Worker
iprange_mt6_xlate(struct xt_xlate * xl,const struct xt_xlate_mt_params * params)359*a71a9546SAutomerger Merge Worker static int iprange_mt6_xlate(struct xt_xlate *xl,
360*a71a9546SAutomerger Merge Worker const struct xt_xlate_mt_params *params)
361*a71a9546SAutomerger Merge Worker {
362*a71a9546SAutomerger Merge Worker const struct xt_iprange_mtinfo *info =
363*a71a9546SAutomerger Merge Worker (const void *)params->match->data;
364*a71a9546SAutomerger Merge Worker
365*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_SRC) {
366*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "ip6 saddr%s %s",
367*a71a9546SAutomerger Merge Worker info->flags & IPRANGE_SRC_INV ? " !=" : "",
368*a71a9546SAutomerger Merge Worker xtables_ip6addr_to_numeric(&info->src_min.in6));
369*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "-%s",
370*a71a9546SAutomerger Merge Worker xtables_ip6addr_to_numeric(&info->src_max.in6));
371*a71a9546SAutomerger Merge Worker }
372*a71a9546SAutomerger Merge Worker if (info->flags & IPRANGE_DST) {
373*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "ip6 daddr%s %s",
374*a71a9546SAutomerger Merge Worker info->flags & IPRANGE_DST_INV ? " !=" : "",
375*a71a9546SAutomerger Merge Worker xtables_ip6addr_to_numeric(&info->dst_min.in6));
376*a71a9546SAutomerger Merge Worker xt_xlate_add(xl, "-%s",
377*a71a9546SAutomerger Merge Worker xtables_ip6addr_to_numeric(&info->dst_max.in6));
378*a71a9546SAutomerger Merge Worker }
379*a71a9546SAutomerger Merge Worker
380*a71a9546SAutomerger Merge Worker return 1;
381*a71a9546SAutomerger Merge Worker }
382*a71a9546SAutomerger Merge Worker
383*a71a9546SAutomerger Merge Worker static struct xtables_match iprange_mt_reg[] = {
384*a71a9546SAutomerger Merge Worker {
385*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION,
386*a71a9546SAutomerger Merge Worker .name = "iprange",
387*a71a9546SAutomerger Merge Worker .revision = 0,
388*a71a9546SAutomerger Merge Worker .family = NFPROTO_IPV4,
389*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct ipt_iprange_info)),
390*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct ipt_iprange_info)),
391*a71a9546SAutomerger Merge Worker .help = iprange_mt_help,
392*a71a9546SAutomerger Merge Worker .x6_parse = iprange_parse,
393*a71a9546SAutomerger Merge Worker .x6_fcheck = iprange_mt_check,
394*a71a9546SAutomerger Merge Worker .print = iprange_print,
395*a71a9546SAutomerger Merge Worker .save = iprange_save,
396*a71a9546SAutomerger Merge Worker .x6_options = iprange_mt_opts,
397*a71a9546SAutomerger Merge Worker .xlate = iprange_xlate,
398*a71a9546SAutomerger Merge Worker },
399*a71a9546SAutomerger Merge Worker {
400*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION,
401*a71a9546SAutomerger Merge Worker .name = "iprange",
402*a71a9546SAutomerger Merge Worker .revision = 1,
403*a71a9546SAutomerger Merge Worker .family = NFPROTO_IPV4,
404*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_iprange_mtinfo)),
405*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_iprange_mtinfo)),
406*a71a9546SAutomerger Merge Worker .help = iprange_mt_help,
407*a71a9546SAutomerger Merge Worker .x6_parse = iprange_mt4_parse,
408*a71a9546SAutomerger Merge Worker .x6_fcheck = iprange_mt_check,
409*a71a9546SAutomerger Merge Worker .print = iprange_mt4_print,
410*a71a9546SAutomerger Merge Worker .save = iprange_mt4_save,
411*a71a9546SAutomerger Merge Worker .x6_options = iprange_mt_opts,
412*a71a9546SAutomerger Merge Worker .xlate = iprange_mt4_xlate,
413*a71a9546SAutomerger Merge Worker },
414*a71a9546SAutomerger Merge Worker {
415*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION,
416*a71a9546SAutomerger Merge Worker .name = "iprange",
417*a71a9546SAutomerger Merge Worker .revision = 1,
418*a71a9546SAutomerger Merge Worker .family = NFPROTO_IPV6,
419*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_iprange_mtinfo)),
420*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_iprange_mtinfo)),
421*a71a9546SAutomerger Merge Worker .help = iprange_mt_help,
422*a71a9546SAutomerger Merge Worker .x6_parse = iprange_mt6_parse,
423*a71a9546SAutomerger Merge Worker .x6_fcheck = iprange_mt_check,
424*a71a9546SAutomerger Merge Worker .print = iprange_mt6_print,
425*a71a9546SAutomerger Merge Worker .save = iprange_mt6_save,
426*a71a9546SAutomerger Merge Worker .x6_options = iprange_mt_opts,
427*a71a9546SAutomerger Merge Worker .xlate = iprange_mt6_xlate,
428*a71a9546SAutomerger Merge Worker },
429*a71a9546SAutomerger Merge Worker };
430*a71a9546SAutomerger Merge Worker
_init(void)431*a71a9546SAutomerger Merge Worker void _init(void)
432*a71a9546SAutomerger Merge Worker {
433*a71a9546SAutomerger Merge Worker xtables_register_matches(iprange_mt_reg, ARRAY_SIZE(iprange_mt_reg));
434*a71a9546SAutomerger Merge Worker }
435