]> git.pld-linux.org Git - packages/iptables.git/blob - iptables-TPROXY-IPv6.patch
1f382e73a437ed7915acbae68091093d547611e1
[packages/iptables.git] / iptables-TPROXY-IPv6.patch
1 Date:   Thu, 21 Oct 2010 17:19:22 +0200
2 From:   KOVACS Krisztian <hidden@balabit.hu>
3 Subject: [PATCH 1/2] tproxy: add IPv6 support for socket match
4
5 This patch also adds userspace support for the --transparent mode
6 of matching, which the kernel already supports, but the iptables userspace
7 doesn't.
8
9 Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>
10 Signed-off-by: KOVACS Krisztian <hidden@balabit.hu>
11 ---
12  extensions/libxt_socket.c           |  103 ++++++++++++++++++++++++++++++++---
13  extensions/libxt_socket.man         |    6 ++
14  include/linux/netfilter/xt_socket.h |   12 ++++
15  3 files changed, 112 insertions(+), 9 deletions(-)
16  create mode 100644 include/linux/netfilter/xt_socket.h
17
18 diff --git a/extensions/libxt_socket.c b/extensions/libxt_socket.c
19 index 1490473..5705466 100644
20 --- a/extensions/libxt_socket.c
21 +++ b/extensions/libxt_socket.c
22 @@ -1,19 +1,106 @@
23  /*
24   * Shared library add-on to iptables to add early socket matching support.
25   *
26 - * Copyright (C) 2007 BalaBit IT Ltd.
27 + * Copyright (C) 2007, 2009 BalaBit IT Ltd.
28   */
29 +#include <stdio.h>
30 +#include <getopt.h>
31  #include <xtables.h>
32 +#include <linux/netfilter/xt_socket.h>
33  
34 -static struct xtables_match socket_mt_reg = {
35 -       .name          = "socket",
36 -       .version       = XTABLES_VERSION,
37 -       .family        = NFPROTO_IPV4,
38 -       .size          = XT_ALIGN(0),
39 -       .userspacesize = XT_ALIGN(0),
40 +static void socket_mt_help_v0(void)
41 +{
42 +       printf("socket match has no options.\n\n");
43 +}
44 +
45 +static void socket_mt_help_v1(void)
46 +{
47 +       printf("socket match options:\n"
48 +"--transparent     Matches only if the socket's transparent option is set\n");
49 +}
50 +
51 +static const struct option socket_opts_v1[] = {
52 +       { "transparent", 0, NULL, '1' },
53 +       { }
54 +};
55 +
56 +static int socket_mt_parse_v0(int c, char **argv, int invert,
57 +                             unsigned int *flags, const void *entry,
58 +                             struct xt_entry_match **match)
59 +{
60 +       return 0;
61 +}
62 +
63 +static int socket_mt_parse_v1(int c, char **argv, int invert,
64 +                             unsigned int *flags, const void *entry,
65 +                             struct xt_entry_match **match)
66 +{
67 +       struct xt_socket_mtinfo1 *info = (void *) (*match)->data;
68 +
69 +       switch (c) {
70 +       case '1':
71 +               if (*flags)
72 +                       xtables_error(PARAMETER_PROBLEM,
73 +                                     "Can't specify multiple --transparent");
74 +               info->flags |= XT_SOCKET_TRANSPARENT;
75 +               *flags = 1;
76 +               break;
77 +       default:
78 +               return 0;
79 +       }
80 +       return 1;
81 +}
82 +
83 +static void socket_mt_check(unsigned int flags)
84 +{
85 +}
86 +
87 +static void socket_mt_print_v1(const void *ip,
88 +                              const struct xt_entry_match *match,
89 +                              int numeric)
90 +{
91 +       const struct xt_socket_mtinfo1 *info = (const void *)match->data;
92 +       printf("socket ");
93 +       if (info->flags & XT_SOCKET_TRANSPARENT)
94 +               printf("transparent ");
95 +}
96 +
97 +static void socket_mt_save_v1(const void *ip,
98 +                             const struct xt_entry_match *match)
99 +{
100 +       const struct xt_socket_mtinfo1 *info = (const void *)match->data;
101 +
102 +       if (info->flags & XT_SOCKET_TRANSPARENT)
103 +               printf("--transparent ");
104 +}
105 +
106 +static struct xtables_match socket_matches[] = {
107 +       {
108 +               .name           = "socket",
109 +               .revision       = 0,
110 +               .version        = XTABLES_VERSION,
111 +               .family         = NFPROTO_IPV4,
112 +               .parse          = socket_mt_parse_v0,
113 +               .final_check    = socket_mt_check,
114 +               .help           = socket_mt_help_v0,
115 +       },
116 +       {
117 +               .name           = "socket",
118 +               .version        = XTABLES_VERSION,
119 +               .revision       = 1,
120 +               .family         = NFPROTO_UNSPEC,
121 +               .size           = XT_ALIGN(sizeof(struct xt_socket_mtinfo1)),
122 +               .userspacesize  = XT_ALIGN(sizeof(struct xt_socket_mtinfo1)),
123 +               .parse          = socket_mt_parse_v1,
124 +               .print          = socket_mt_print_v1,
125 +               .save           = socket_mt_save_v1,
126 +               .final_check    = socket_mt_check,
127 +               .help           = socket_mt_help_v1,
128 +               .extra_opts     = socket_opts_v1,
129 +       }
130  };
131  
132  void _init(void)
133  {
134 -       xtables_register_match(&socket_mt_reg);
135 +       xtables_register_matches(socket_matches, ARRAY_SIZE(socket_matches));
136  }
137 diff --git a/extensions/libxt_socket.man b/extensions/libxt_socket.man
138 index 50c8854..edc9d75 100644
139 --- a/extensions/libxt_socket.man
140 +++ b/extensions/libxt_socket.man
141 @@ -1,2 +1,6 @@
142  This matches if an open socket can be found by doing a socket lookup on the
143 -packet.
144 +packet which doesn\'t listen on the \'any\' IP address (0.0.0.0).
145 +.TP
146 +.BI "\-\-transparent"
147 +Enables additional check, that the actual socket's transparent socket option
148 +has to be set.
149 diff --git a/include/linux/netfilter/xt_socket.h b/include/linux/netfilter/xt_socket.h
150 new file mode 100644
151 index 0000000..6f475b8
152 --- /dev/null
153 +++ b/include/linux/netfilter/xt_socket.h
154 @@ -0,0 +1,12 @@
155 +#ifndef _XT_SOCKET_H
156 +#define _XT_SOCKET_H
157 +
158 +enum {
159 +       XT_SOCKET_TRANSPARENT = 1 << 0,
160 +};
161 +
162 +struct xt_socket_mtinfo1 {
163 +       __u8 flags;
164 +};
165 +
166 +#endif /* _XT_SOCKET_H */
167
168
169 Date:   Thu, 21 Oct 2010 17:19:22 +0200
170 From:   KOVACS Krisztian <hidden@balabit.hu>
171 Subject: [PATCH 2/2] tproxy: add IPv6 support to the TPROXY target
172
173 Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>
174 Signed-off-by: KOVACS Krisztian <hidden@balabit.hu>
175 ---
176  extensions/libxt_TPROXY.c           |  213 +++++++++++++++++++++++++++++------
177  include/linux/netfilter/xt_TPROXY.h |    7 +
178  2 files changed, 183 insertions(+), 37 deletions(-)
179
180 diff --git a/extensions/libxt_TPROXY.c b/extensions/libxt_TPROXY.c
181 index cd0b50a..74d122c 100644
182 --- a/extensions/libxt_TPROXY.c
183 +++ b/extensions/libxt_TPROXY.c
184 @@ -1,7 +1,7 @@
185  /*
186   * Shared library add-on to iptables to add TPROXY target support.
187   *
188 - * Copyright (C) 2002-2008 BalaBit IT Ltd.
189 + * Copyright (C) 2002-2009 BalaBit IT Ltd.
190   */
191  #include <getopt.h>
192  #include <stdbool.h>
193 @@ -15,8 +15,8 @@
194  #include <linux/netfilter/xt_TPROXY.h>
195  
196  static const struct option tproxy_tg_opts[] = {
197 -       {.name = "on-port",     .has_arg = true, .val = '1'},
198 -       {.name = "on-ip",       .has_arg = true, .val = '2'},
199 +       {.name = "on-port",     .has_arg = true, .val = '1'},
200 +       {.name = "on-ip",       .has_arg = true, .val = '2'},
201         {.name = "tproxy-mark", .has_arg = true, .val = '3'},
202         XT_GETOPT_TABLEEND,
203  };
204 @@ -36,44 +36,64 @@ static void tproxy_tg_help(void)
205  "  --tproxy-mark value[/mask]      Mark packets with the given value/mask\n\n");
206  }
207  
208 -static void parse_tproxy_lport(const char *s, struct xt_tproxy_target_info *info)
209 +static void parse_tproxy_lport(const char *s, unsigned short *lport)
210  {
211 -       unsigned int lport;
212 +       unsigned int value;
213  
214 -       if (xtables_strtoui(s, NULL, &lport, 0, UINT16_MAX))
215 -               info->lport = htons(lport);
216 +       if (xtables_strtoui(s, NULL, &value, 0, UINT16_MAX))
217 +               *lport = htons(value);
218         else
219                 xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--on-port", s);
220  }
221  
222 -static void parse_tproxy_laddr(const char *s, struct xt_tproxy_target_info *info)
223 +static void parse_tproxy_laddr_v0(const char *s, __be32 *laddr)
224  {
225 -       struct in_addr *laddr;
226 +       struct in_addr *ina;
227  
228 -       if ((laddr = xtables_numeric_to_ipaddr(s)) == NULL)
229 +       if ((ina = xtables_numeric_to_ipaddr(s)) == NULL)
230                 xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--on-ip", s);
231  
232 -       info->laddr = laddr->s_addr;
233 +       *laddr = ina->s_addr;
234  }
235  
236 -static void parse_tproxy_mark(char *s, struct xt_tproxy_target_info *info)
237 +static void parse_tproxy_laddr(const char *s, int family, union nf_inet_addr *laddr)
238 +{
239 +
240 +       if (family == NFPROTO_IPV6) {
241 +               struct in6_addr *addr6;
242 +
243 +               if ((addr6 = xtables_numeric_to_ip6addr(s))) {
244 +                       laddr->in6 = *addr6;
245 +               } else {
246 +                       xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--on-ip", s);
247 +               }
248 +       } else {
249 +               struct in_addr *addr;
250 +
251 +               if ((addr = xtables_numeric_to_ipaddr(s))) {
252 +                       laddr->in = *addr;
253 +               } else {
254 +                       xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--on-ip", s);
255 +               }
256 +
257 +       }
258 +}
259 +
260 +static void parse_tproxy_mark(char *s, unsigned int *value, unsigned int *mask)
261  {
262 -       unsigned int value, mask = UINT32_MAX;
263         char *end;
264  
265 -       if (!xtables_strtoui(s, &end, &value, 0, UINT32_MAX))
266 +       *mask = UINT32_MAX;
267 +       if (!xtables_strtoui(s, &end, value, 0, UINT32_MAX))
268                 xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s);
269         if (*end == '/')
270 -               if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX))
271 +               if (!xtables_strtoui(end + 1, &end, mask, 0, UINT32_MAX))
272                         xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s);
273         if (*end != '\0')
274                 xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s);
275 -
276 -       info->mark_mask = mask;
277 -       info->mark_value = value;
278  }
279  
280 -static int tproxy_tg_parse(int c, char **argv, int invert, unsigned int *flags,
281 +static int tproxy_tg_parse_v0(int c, char **argv, int invert, unsigned int *flags,
282                         const void *entry, struct xt_entry_target **target)
283  {
284         struct xt_tproxy_target_info *tproxyinfo = (void *)(*target)->data;
285 @@ -82,19 +102,19 @@ static int tproxy_tg_parse(int c, char **argv, int invert, unsigned int *flags,
286         case '1':
287                 xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--on-port", *flags & PARAM_ONPORT);
288                 xtables_param_act(XTF_NO_INVERT, "TPROXY", "--on-port", invert);
289 -               parse_tproxy_lport(optarg, tproxyinfo);
290 +               parse_tproxy_lport(optarg, &tproxyinfo->lport);
291                 *flags |= PARAM_ONPORT;
292                 return 1;
293         case '2':
294                 xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--on-ip", *flags & PARAM_ONIP);
295                 xtables_param_act(XTF_NO_INVERT, "TPROXY", "--on-ip", invert);
296 -               parse_tproxy_laddr(optarg, tproxyinfo);
297 +               parse_tproxy_laddr_v0(optarg, &tproxyinfo->laddr);
298                 *flags |= PARAM_ONIP;
299                 return 1;
300         case '3':
301                 xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--tproxy-mark", *flags & PARAM_MARK);
302                 xtables_param_act(XTF_NO_INVERT, "TPROXY", "--tproxy-mark", invert);
303 -               parse_tproxy_mark(optarg, tproxyinfo);
304 +               parse_tproxy_mark(optarg, &tproxyinfo->mark_value, &tproxyinfo->mark_mask);
305                 *flags |= PARAM_MARK;
306                 return 1;
307         }
308 @@ -102,6 +122,47 @@ static int tproxy_tg_parse(int c, char **argv, int invert, unsigned int *flags,
309         return 0;
310  }
311  
312 +static int tproxy_tg_parse_v1(int family, int c, char **argv, int invert, unsigned int *flags,
313 +                       const void *entry, struct xt_entry_target **target)
314 +{
315 +       struct xt_tproxy_target_info_v1 *tproxyinfo = (void *)(*target)->data;
316 +
317 +       switch (c) {
318 +       case '1':
319 +               xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--on-port", *flags & PARAM_ONPORT);
320 +               xtables_param_act(XTF_NO_INVERT, "TPROXY", "--on-port", invert);
321 +               parse_tproxy_lport(optarg, &tproxyinfo->lport);
322 +               *flags |= PARAM_ONPORT;
323 +               return 1;
324 +       case '2':
325 +               xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--on-ip", *flags & PARAM_ONIP);
326 +               xtables_param_act(XTF_NO_INVERT, "TPROXY", "--on-ip", invert);
327 +               parse_tproxy_laddr(optarg, family, &tproxyinfo->laddr);
328 +               *flags |= PARAM_ONIP;
329 +               return 1;
330 +       case '3':
331 +               xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--tproxy-mark", *flags & PARAM_MARK);
332 +               xtables_param_act(XTF_NO_INVERT, "TPROXY", "--tproxy-mark", invert);
333 +               parse_tproxy_mark(optarg, &tproxyinfo->mark_value, &tproxyinfo->mark_mask);
334 +               *flags |= PARAM_MARK;
335 +               return 1;
336 +       }
337 +
338 +       return 0;
339 +}
340 +
341 +static int tproxy_tg_parse4_v1(int c, char **argv, int invert, unsigned int *flags,
342 +                       const void *entry, struct xt_entry_target **target)
343 +{
344 +       return tproxy_tg_parse_v1(NFPROTO_IPV4, c, argv, invert, flags, entry, target);
345 +}
346 +
347 +static int tproxy_tg_parse6_v1(int c, char **argv, int invert, unsigned int *flags,
348 +                       const void *entry, struct xt_entry_target **target)
349 +{
350 +       return tproxy_tg_parse_v1(NFPROTO_IPV6, c, argv, invert, flags, entry, target);
351 +}
352 +
353  static void tproxy_tg_check(unsigned int flags)
354  {
355         if (!(flags & PARAM_ONPORT))
356 @@ -109,7 +170,7 @@ static void tproxy_tg_check(unsigned int flags)
357                            "TPROXY target: Parameter --on-port is required");
358  }
359  
360 -static void tproxy_tg_print(const void *ip, const struct xt_entry_target *target,
361 +static void tproxy_tg_print_v0(const void *ip, const struct xt_entry_target *target,
362                          int numeric)
363  {
364         const struct xt_tproxy_target_info *info = (const void *)target->data;
365 @@ -119,7 +180,31 @@ static void tproxy_tg_print(const void *ip, const struct xt_entry_target *target
366                (unsigned int)info->mark_mask);
367  }
368  
369 -static void tproxy_tg_save(const void *ip, const struct xt_entry_target *target)
370 +static void tproxy_tg_print_v1(int family, const void *ip, const struct xt_entry_target *target,
371 +                        int numeric)
372 +{
373 +       const struct xt_tproxy_target_info_v1 *info = (const void *)target->data;
374 +       printf("TPROXY redirect %s:%u mark 0x%x/0x%x",
375 +              family == AF_INET
376 +              ? xtables_ipaddr_to_numeric(&info->laddr.in)
377 +              : xtables_ip6addr_to_numeric(&info->laddr.in6),
378 +              ntohs(info->lport), (unsigned int)info->mark_value,
379 +              (unsigned int)info->mark_mask);
380 +}
381 +
382 +static void tproxy_tg_print4_v1(const void *ip, const struct xt_entry_target *target,
383 +                              int numeric)
384 +{
385 +       return tproxy_tg_print_v1(NFPROTO_IPV4, ip, target, numeric);
386 +}
387 +
388 +static void tproxy_tg_print6_v1(const void *ip, const struct xt_entry_target *target,
389 +                              int numeric)
390 +{
391 +       return tproxy_tg_print_v1(NFPROTO_IPV6, ip, target, numeric);
392 +}
393 +
394 +static void tproxy_tg_save_v0(const void *ip, const struct xt_entry_target *target)
395  {
396         const struct xt_tproxy_target_info *info = (const void *)target->data;
397  
398 @@ -130,21 +215,75 @@ static void tproxy_tg_save(const void *ip, const struct xt_entry_target *target)
399                (unsigned int)info->mark_value, (unsigned int)info->mark_mask);
400  }
401  
402 -static struct xtables_target tproxy_tg_reg = {
403 -       .name          = "TPROXY",
404 -       .family        = NFPROTO_IPV4,
405 -       .version       = XTABLES_VERSION,
406 -       .size          = XT_ALIGN(sizeof(struct xt_tproxy_target_info)),
407 -       .userspacesize = XT_ALIGN(sizeof(struct xt_tproxy_target_info)),
408 -       .help          = tproxy_tg_help,
409 -       .parse         = tproxy_tg_parse,
410 -       .final_check   = tproxy_tg_check,
411 -       .print         = tproxy_tg_print,
412 -       .save          = tproxy_tg_save,
413 -       .extra_opts    = tproxy_tg_opts,
414 +static void tproxy_tg_save_v1(int family, const void *ip, const struct xt_entry_target *target)
415 +{
416 +       const struct xt_tproxy_target_info_v1 *info = (const void *)target->data;
417 +
418 +       printf("--on-port %u ", ntohs(info->lport));
419 +       printf("--on-ip %s ",
420 +              family == AF_INET
421 +              ? xtables_ipaddr_to_numeric(&info->laddr.in)
422 +              : xtables_ip6addr_to_numeric(&info->laddr.in6));
423 +       printf("--tproxy-mark 0x%x/0x%x ",
424 +              (unsigned int)info->mark_value, (unsigned int)info->mark_mask);
425 +}
426 +
427 +static void tproxy_tg_save4_v1(const void *ip, const struct xt_entry_target *target)
428 +{
429 +       return tproxy_tg_save_v1(NFPROTO_IPV4, ip, target);
430 +}
431 +
432 +static void tproxy_tg_save6_v1(const void *ip, const struct xt_entry_target *target)
433 +{
434 +       return tproxy_tg_save_v1(NFPROTO_IPV6, ip, target);
435 +}
436 +
437 +
438 +static struct xtables_target tproxy_tg_reg[] = {
439 +       {
440 +               .name          = "TPROXY",
441 +               .family        = NFPROTO_IPV4,
442 +               .version       = XTABLES_VERSION,
443 +               .size          = XT_ALIGN(sizeof(struct xt_tproxy_target_info)),
444 +               .userspacesize = XT_ALIGN(sizeof(struct xt_tproxy_target_info)),
445 +               .help          = tproxy_tg_help,
446 +               .parse         = tproxy_tg_parse_v0,
447 +               .final_check   = tproxy_tg_check,
448 +               .print         = tproxy_tg_print_v0,
449 +               .save          = tproxy_tg_save_v0,
450 +               .extra_opts    = tproxy_tg_opts,
451 +       },
452 +       {
453 +               .name          = "TPROXY",
454 +               .family        = NFPROTO_IPV4,
455 +               .version       = XTABLES_VERSION,
456 +               .revision      = 1,
457 +               .size          = XT_ALIGN(sizeof(struct xt_tproxy_target_info_v1)),
458 +               .userspacesize = XT_ALIGN(sizeof(struct xt_tproxy_target_info_v1)),
459 +               .help          = tproxy_tg_help,
460 +               .parse         = tproxy_tg_parse4_v1,
461 +               .final_check   = tproxy_tg_check,
462 +               .print         = tproxy_tg_print4_v1,
463 +               .save          = tproxy_tg_save4_v1,
464 +               .extra_opts    = tproxy_tg_opts,
465 +       },
466 +       {
467 +               .name          = "TPROXY",
468 +               .family        = NFPROTO_IPV6,
469 +               .version       = XTABLES_VERSION,
470 +               .revision      = 1,
471 +               .size          = XT_ALIGN(sizeof(struct xt_tproxy_target_info_v1)),
472 +               .userspacesize = XT_ALIGN(sizeof(struct xt_tproxy_target_info_v1)),
473 +               .help          = tproxy_tg_help,
474 +               .parse         = tproxy_tg_parse6_v1,
475 +               .final_check   = tproxy_tg_check,
476 +               .print         = tproxy_tg_print6_v1,
477 +               .save          = tproxy_tg_save6_v1,
478 +               .extra_opts    = tproxy_tg_opts,
479 +       },
480  };
481  
482  void _init(void)
483  {
484 -       xtables_register_target(&tproxy_tg_reg);
485 +       xtables_register_targets(tproxy_tg_reg, ARRAY_SIZE(tproxy_tg_reg));
486  }
487 diff --git a/include/linux/netfilter/xt_TPROXY.h b/include/linux/netfilter/xt_TPROXY.h
488 index 152e8f9..28ff0e8 100644
489 --- a/include/linux/netfilter/xt_TPROXY.h
490 +++ b/include/linux/netfilter/xt_TPROXY.h
491 @@ -11,4 +11,11 @@ struct xt_tproxy_target_info {
492         __be16 lport;
493  };
494  
495 +struct xt_tproxy_target_info_v1 {
496 +       u_int32_t mark_mask;
497 +       u_int32_t mark_value;
498 +       union nf_inet_addr laddr;
499 +       __be16 lport;
500 +};
501 +
502  #endif /* _XT_TPROXY_H_target */
503
504
505
This page took 0.079949 seconds and 2 git commands to generate.