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
5 This patch also adds userspace support for the --transparent mode
6 of matching, which the kernel already supports, but the iptables userspace
9 Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>
10 Signed-off-by: KOVACS Krisztian <hidden@balabit.hu>
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
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
24 * Shared library add-on to iptables to add early socket matching support.
26 - * Copyright (C) 2007 BalaBit IT Ltd.
27 + * Copyright (C) 2007, 2009 BalaBit IT Ltd.
32 +#include <linux/netfilter/xt_socket.h>
34 -static struct xtables_match socket_mt_reg = {
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)
42 + printf("socket match has no options.\n\n");
45 +static void socket_mt_help_v1(void)
47 + printf("socket match options:\n"
48 +"--transparent Matches only if the socket's transparent option is set\n");
51 +static const struct option socket_opts_v1[] = {
52 + { "transparent", 0, NULL, '1' },
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)
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)
67 + struct xt_socket_mtinfo1 *info = (void *) (*match)->data;
72 + xtables_error(PARAMETER_PROBLEM,
73 + "Can't specify multiple --transparent");
74 + info->flags |= XT_SOCKET_TRANSPARENT;
83 +static void socket_mt_check(unsigned int flags)
87 +static void socket_mt_print_v1(const void *ip,
88 + const struct xt_entry_match *match,
91 + const struct xt_socket_mtinfo1 *info = (const void *)match->data;
93 + if (info->flags & XT_SOCKET_TRANSPARENT)
94 + printf("transparent ");
97 +static void socket_mt_save_v1(const void *ip,
98 + const struct xt_entry_match *match)
100 + const struct xt_socket_mtinfo1 *info = (const void *)match->data;
102 + if (info->flags & XT_SOCKET_TRANSPARENT)
103 + printf("--transparent ");
106 +static struct xtables_match socket_matches[] = {
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,
118 + .version = XTABLES_VERSION,
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,
134 - xtables_register_match(&socket_mt_reg);
135 + xtables_register_matches(socket_matches, ARRAY_SIZE(socket_matches));
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
142 This matches if an open socket can be found by doing a socket lookup on the
144 +packet which doesn\'t listen on the \'any\' IP address (0.0.0.0).
146 +.BI "\-\-transparent"
147 +Enables additional check, that the actual socket's transparent socket option
149 diff --git a/include/linux/netfilter/xt_socket.h b/include/linux/netfilter/xt_socket.h
151 index 0000000..6f475b8
153 +++ b/include/linux/netfilter/xt_socket.h
155 +#ifndef _XT_SOCKET_H
156 +#define _XT_SOCKET_H
159 + XT_SOCKET_TRANSPARENT = 1 << 0,
162 +struct xt_socket_mtinfo1 {
166 +#endif /* _XT_SOCKET_H */
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
173 Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>
174 Signed-off-by: KOVACS Krisztian <hidden@balabit.hu>
176 extensions/libxt_TPROXY.c | 213 +++++++++++++++++++++++++++++------
177 include/linux/netfilter/xt_TPROXY.h | 7 +
178 2 files changed, 183 insertions(+), 37 deletions(-)
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
186 * Shared library add-on to iptables to add TPROXY target support.
188 - * Copyright (C) 2002-2008 BalaBit IT Ltd.
189 + * Copyright (C) 2002-2009 BalaBit IT Ltd.
194 #include <linux/netfilter/xt_TPROXY.h>
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'},
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");
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)
211 - unsigned int lport;
212 + unsigned int value;
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);
219 xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--on-port", s);
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)
225 - struct in_addr *laddr;
226 + struct in_addr *ina;
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);
232 - info->laddr = laddr->s_addr;
233 + *laddr = ina->s_addr;
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)
240 + if (family == NFPROTO_IPV6) {
241 + struct in6_addr *addr6;
243 + if ((addr6 = xtables_numeric_to_ip6addr(s))) {
244 + laddr->in6 = *addr6;
246 + xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--on-ip", s);
249 + struct in_addr *addr;
251 + if ((addr = xtables_numeric_to_ipaddr(s))) {
254 + xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--on-ip", s);
260 +static void parse_tproxy_mark(char *s, unsigned int *value, unsigned int *mask)
262 - unsigned int value, mask = UINT32_MAX;
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);
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);
274 xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s);
276 - info->mark_mask = mask;
277 - info->mark_value = value;
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)
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,
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;
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;
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;
308 @@ -102,6 +122,47 @@ static int tproxy_tg_parse(int c, char **argv, int invert, unsigned int *flags,
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)
315 + struct xt_tproxy_target_info_v1 *tproxyinfo = (void *)(*target)->data;
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;
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;
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;
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)
344 + return tproxy_tg_parse_v1(NFPROTO_IPV4, c, argv, invert, flags, entry, target);
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)
350 + return tproxy_tg_parse_v1(NFPROTO_IPV6, c, argv, invert, flags, entry, target);
353 static void tproxy_tg_check(unsigned int flags)
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");
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,
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);
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,
373 + const struct xt_tproxy_target_info_v1 *info = (const void *)target->data;
374 + printf("TPROXY redirect %s:%u mark 0x%x/0x%x",
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);
382 +static void tproxy_tg_print4_v1(const void *ip, const struct xt_entry_target *target,
385 + return tproxy_tg_print_v1(NFPROTO_IPV4, ip, target, numeric);
388 +static void tproxy_tg_print6_v1(const void *ip, const struct xt_entry_target *target,
391 + return tproxy_tg_print_v1(NFPROTO_IPV6, ip, target, numeric);
394 +static void tproxy_tg_save_v0(const void *ip, const struct xt_entry_target *target)
396 const struct xt_tproxy_target_info *info = (const void *)target->data;
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);
402 -static struct xtables_target tproxy_tg_reg = {
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)
416 + const struct xt_tproxy_target_info_v1 *info = (const void *)target->data;
418 + printf("--on-port %u ", ntohs(info->lport));
419 + printf("--on-ip %s ",
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);
427 +static void tproxy_tg_save4_v1(const void *ip, const struct xt_entry_target *target)
429 + return tproxy_tg_save_v1(NFPROTO_IPV4, ip, target);
432 +static void tproxy_tg_save6_v1(const void *ip, const struct xt_entry_target *target)
434 + return tproxy_tg_save_v1(NFPROTO_IPV6, ip, target);
438 +static struct xtables_target tproxy_tg_reg[] = {
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,
454 + .family = NFPROTO_IPV4,
455 + .version = XTABLES_VERSION,
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,
468 + .family = NFPROTO_IPV6,
469 + .version = XTABLES_VERSION,
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,
484 - xtables_register_target(&tproxy_tg_reg);
485 + xtables_register_targets(tproxy_tg_reg, ARRAY_SIZE(tproxy_tg_reg));
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 {
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;
502 #endif /* _XT_TPROXY_H_target */