Hi, thanks for your reply. >>+static const struct option socket_opts_v1[] = { >>+ { "transparent", 0, NULL, '1' }, >>+ { } >>+}; > > Try to use the C99 version. Not sure what C99 shall mean in this context, > { .name = NULL } ? > ' does not need to be escaped, to my knowledge. I adopted the syntax from the original manpage, which escapes ', shall I remove it altogether? >>+struct xt_socket_mtinfo1 { >>+ __u8 flags; >>+}; > > I'm sure Eric Dumazet will remind us that u32 is a better idea. Adopted, as the kernel already uses __u8 for the socket match flags http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=include/linux/netfilter/xt_socket.h;h=6f475b8ff34be81caa612bf1a947d3ad627290ab;hb=962400e8fd29981a7b166e463dd143b6ac6a3e76#l8 shall I change it to u32? Attached is current version for iptables, I remembered being able to invert a match would be great, therefore I added the invertible implicit --exists option. So now, this patch covers all changes, adding the options [!] --exists --transparent --wildcard to the socket match. Markus
diff --git a/extensions/libxt_socket.c b/extensions/libxt_socket.c index 1490473..03a4f8f 100644 --- a/extensions/libxt_socket.c +++ b/extensions/libxt_socket.c @@ -3,17 +3,106 @@ * * Copyright (C) 2007 BalaBit IT Ltd. */ +#include <stdio.h> +#include <getopt.h> #include <xtables.h> +#include <linux/netfilter/xt_socket.h> -static struct xtables_match socket_mt_reg = { - .name = "socket", - .version = XTABLES_VERSION, - .family = NFPROTO_IPV4, - .size = XT_ALIGN(0), - .userspacesize = XT_ALIGN(0), +static void socket_mt_help_v1(void) +{ + printf("socket match options:\n" +"--transparent Matches only if the socket's transparent option is set\n" +"--wildcard Match wildcard socket's too\n" +"[!] --exists Match if socket exists (optional), allows inversion\n" + ); +} + +static const struct option socket_opts_v1[] = { + { "transparent", 0, NULL, '1' }, + { "wildcard", 0, NULL, '2' }, + { "exists", 0, NULL, '3' }, + { .name = NULL } +}; + +static int socket_mt_parse_v1(int c, char **argv, int invert, + unsigned int *flags, const void *entry, + struct xt_entry_match **match) +{ + struct xt_socket_mtinfo1 *info = (void *) (*match)->data; + + switch (c) { + case '1': + xtables_param_act(XTF_ONLY_ONCE, "socket", "--transparent", *flags & XT_SOCKET_TRANSPARENT); + info->flags |= XT_SOCKET_TRANSPARENT; + *flags |= XT_SOCKET_TRANSPARENT; + break; + case '2': + xtables_param_act(XTF_ONLY_ONCE, "socket", "--wildcard", *flags & XT_SOCKET_WILDCARD); + info->flags |= XT_SOCKET_WILDCARD; + *flags |= XT_SOCKET_WILDCARD; + break; + case '3': + xtables_param_act(XTF_ONLY_ONCE, "socket", "--exists", *flags & XT_SOCKET_INVERT); + if (invert) + info->flags |= XT_SOCKET_INVERT; + *flags |= XT_SOCKET_INVERT; + break; + default: + return 0; + } + return 1; +} + +static void socket_mt_print_v1(const void *ip, + const struct xt_entry_match *match, + int numeric) +{ + const struct xt_socket_mtinfo1 *info = (const void *)match->data; + printf("socket "); + if (info->flags & XT_SOCKET_TRANSPARENT) + printf("transparent "); + if (info->flags & XT_SOCKET_WILDCARD) + printf("wildcard "); + printf("%sexists ", (info->flags & XT_SOCKET_INVERT) ? "! " : ""); +} + +static void socket_mt_save_v1(const void *ip, + const struct xt_entry_match *match) +{ + const struct xt_socket_mtinfo1 *info = (const void *)match->data; + + if (info->flags & XT_SOCKET_TRANSPARENT) + printf("--transparent "); + + if (info->flags & XT_SOCKET_WILDCARD) + printf("--wildcard "); + + printf("%s--exists ", info->flags & XT_SOCKET_INVERT ? "! " : ""); +} + +static struct xtables_match socket_mt_reg[] = { + { + .name = "socket", + .revision = 0, + .version = XTABLES_VERSION, + .family = NFPROTO_UNSPEC, + }, + { + .name = "socket", + .version = XTABLES_VERSION, + .revision = 1, + .family = NFPROTO_UNSPEC, + .size = XT_ALIGN(sizeof(struct xt_socket_mtinfo1)), + .userspacesize = XT_ALIGN(sizeof(struct xt_socket_mtinfo1)), + .parse = socket_mt_parse_v1, + .print = socket_mt_print_v1, + .save = socket_mt_save_v1, + .help = socket_mt_help_v1, + .extra_opts = socket_opts_v1, + } }; void _init(void) { - xtables_register_match(&socket_mt_reg); + xtables_register_matches(socket_mt_reg, ARRAY_SIZE(socket_mt_reg)); } diff --git a/extensions/libxt_socket.man b/extensions/libxt_socket.man index 50c8854..4acd380 100644 --- a/extensions/libxt_socket.man +++ b/extensions/libxt_socket.man @@ -1,2 +1,12 @@ This matches if an open socket can be found by doing a socket lookup on the -packet. +packet which doesn\'t listen on the \'any\' IP address (0.0.0.0). +.TP +.BI "\-\-transparent" +Enables additional check, that the actual socket's transparent socket option +has to be set. +.BI "\-\-wildcard" +Matches sockets listening on the \'any\' IP address (0.0.0.0) too. +.BI "[!] \-\-exists" +Optional, allows inversion of the match. + + diff --git a/include/linux/netfilter/xt_socket.h b/include/linux/netfilter/xt_socket.h new file mode 100644 index 0000000..6f492ed --- /dev/null +++ b/include/linux/netfilter/xt_socket.h @@ -0,0 +1,14 @@ +#ifndef _XT_SOCKET_H_match +#define _XT_SOCKET_H_match + +enum { + XT_SOCKET_TRANSPARENT = 1 << 0, + XT_SOCKET_WILDCARD = 1 << 1, + XT_SOCKET_INVERT = 1 << 2, +}; + +struct xt_socket_mtinfo1 { + __u8 flags; +}; + +#endif /* _XT_SOCKET_H_match */