From 491c1660fced08e2d1a08c101c63af04250275d0 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 7 Jun 2010 10:59:03 +0200 Subject: includes: sync header files from Linux 2.6.35-rc1 Signed-off-by: Jan Engelhardt --- include/linux/kernel.h | 62 +++++++++++++++++++++++++++++++++++ include/linux/netfilter/x_tables.h | 30 ++++++++++++----- include/linux/netfilter/xt_CONNMARK.h | 22 +------------ include/linux/netfilter/xt_MARK.h | 6 +--- include/linux/netfilter/xt_TEE.h | 3 ++ include/linux/netfilter/xt_connmark.h | 11 +++++++ include/linux/netfilter/xt_mark.h | 4 +++ include/linux/netfilter/xt_recent.h | 7 ++++ include/linux/netfilter_ipv6.h | 1 + 9 files changed, 111 insertions(+), 35 deletions(-) create mode 100644 include/linux/kernel.h diff --git a/include/linux/kernel.h b/include/linux/kernel.h new file mode 100644 index 00000000..d1671a01 --- /dev/null +++ b/include/linux/kernel.h @@ -0,0 +1,62 @@ +#ifndef _LINUX_KERNEL_H +#define _LINUX_KERNEL_H + +/* + * 'kernel.h' contains some often-used function prototypes etc + */ +#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1) +#define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask)) + + + +#define SI_LOAD_SHIFT 16 +struct sysinfo { + long uptime; /* Seconds since boot */ + unsigned long loads[3]; /* 1, 5, and 15 minute load averages */ + unsigned long totalram; /* Total usable main memory size */ + unsigned long freeram; /* Available memory size */ + unsigned long sharedram; /* Amount of shared memory */ + unsigned long bufferram; /* Memory used by buffers */ + unsigned long totalswap; /* Total swap space size */ + unsigned long freeswap; /* swap space still available */ + unsigned short procs; /* Number of current processes */ + unsigned short pad; /* explicit padding for m68k */ + unsigned long totalhigh; /* Total high memory size */ + unsigned long freehigh; /* Available high memory size */ + unsigned int mem_unit; /* Memory unit size in bytes */ + char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */ +}; + +/* Force a compilation error if condition is true */ +#define BUILD_BUG_ON(condition) ((void)BUILD_BUG_ON_ZERO(condition)) + +/* Force a compilation error if condition is constant and true */ +#define MAYBE_BUILD_BUG_ON(cond) ((void)sizeof(char[1 - 2 * !!(cond)])) + +/* Force a compilation error if a constant expression is not a power of 2 */ +#define BUILD_BUG_ON_NOT_POWER_OF_2(n) \ + BUILD_BUG_ON((n) == 0 || (((n) & ((n) - 1)) != 0)) + +/* Force a compilation error if condition is true, but also produce a + result (of value 0 and type size_t), so the expression can be used + e.g. in a structure initializer (or where-ever else comma expressions + aren't permitted). */ +#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); })) +#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); })) + +/* Trap pasters of __FUNCTION__ at compile-time */ +#define __FUNCTION__ (__func__) + +/* This helps us to avoid #ifdef CONFIG_NUMA */ +#ifdef CONFIG_NUMA +#define NUMA_BUILD 1 +#else +#define NUMA_BUILD 0 +#endif + +/* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */ +#ifdef CONFIG_FTRACE_MCOUNT_RECORD +# define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD +#endif + +#endif diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index ccb56410..fa2d9578 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -1,9 +1,10 @@ #ifndef _X_TABLES_H #define _X_TABLES_H - +#include #include #define XT_FUNCTION_MAXNAMELEN 30 +#define XT_EXTENSION_MAXNAMELEN 29 #define XT_TABLE_MAXNAMELEN 32 struct xt_entry_match { @@ -12,8 +13,7 @@ struct xt_entry_match { __u16 match_size; /* Used by userspace */ - char name[XT_FUNCTION_MAXNAMELEN-1]; - + char name[XT_EXTENSION_MAXNAMELEN]; __u8 revision; } user; struct { @@ -36,8 +36,7 @@ struct xt_entry_target { __u16 target_size; /* Used by userspace */ - char name[XT_FUNCTION_MAXNAMELEN-1]; - + char name[XT_EXTENSION_MAXNAMELEN]; __u8 revision; } user; struct { @@ -70,8 +69,7 @@ struct xt_standard_target { /* The argument to IPT_SO_GET_REVISION_*. Returns highest revision * kernel supports, if >= revision. */ struct xt_get_revision { - char name[XT_FUNCTION_MAXNAMELEN-1]; - + char name[XT_EXTENSION_MAXNAMELEN]; __u8 revision; }; @@ -93,8 +91,7 @@ struct _xt_align { __u64 u64; }; -#define XT_ALIGN(s) (((s) + (__alignof__(struct _xt_align)-1)) \ - & ~(__alignof__(struct _xt_align)-1)) +#define XT_ALIGN(s) __ALIGN_KERNEL((s), __alignof__(struct _xt_align)) /* Standard return verdict, or do jump. */ #define XT_STANDARD_TARGET "" @@ -165,4 +162,19 @@ struct xt_counters_info { XT_ENTRY_ITERATE_CONTINUE(type, entries, size, 0, fn, args) +/* pos is normally a struct ipt_entry/ip6t_entry/etc. */ +#define xt_entry_foreach(pos, ehead, esize) \ + for ((pos) = (typeof(pos))(ehead); \ + (pos) < (typeof(pos))((char *)(ehead) + (esize)); \ + (pos) = (typeof(pos))((char *)(pos) + (pos)->next_offset)) + +/* can only be xt_entry_match, so no use of typeof here */ +#define xt_ematch_foreach(pos, entry) \ + for ((pos) = (struct xt_entry_match *)entry->elems; \ + (pos) < (struct xt_entry_match *)((char *)(entry) + \ + (entry)->target_offset); \ + (pos) = (struct xt_entry_match *)((char *)(pos) + \ + (pos)->u.match_size)) + + #endif /* _X_TABLES_H */ diff --git a/include/linux/netfilter/xt_CONNMARK.h b/include/linux/netfilter/xt_CONNMARK.h index 0a854586..2f2e48ec 100644 --- a/include/linux/netfilter/xt_CONNMARK.h +++ b/include/linux/netfilter/xt_CONNMARK.h @@ -1,26 +1,6 @@ #ifndef _XT_CONNMARK_H_target #define _XT_CONNMARK_H_target -#include - -/* Copyright (C) 2002,2004 MARA Systems AB - * by Henrik Nordstrom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -enum { - XT_CONNMARK_SET = 0, - XT_CONNMARK_SAVE, - XT_CONNMARK_RESTORE -}; - -struct xt_connmark_tginfo1 { - __u32 ctmark, ctmask, nfmask; - __u8 mode; -}; +#include #endif /*_XT_CONNMARK_H_target*/ diff --git a/include/linux/netfilter/xt_MARK.h b/include/linux/netfilter/xt_MARK.h index bc9561bd..41c456de 100644 --- a/include/linux/netfilter/xt_MARK.h +++ b/include/linux/netfilter/xt_MARK.h @@ -1,10 +1,6 @@ #ifndef _XT_MARK_H_target #define _XT_MARK_H_target -#include - -struct xt_mark_tginfo2 { - __u32 mark, mask; -}; +#include #endif /*_XT_MARK_H_target */ diff --git a/include/linux/netfilter/xt_TEE.h b/include/linux/netfilter/xt_TEE.h index 55d4a501..5c21d5c8 100644 --- a/include/linux/netfilter/xt_TEE.h +++ b/include/linux/netfilter/xt_TEE.h @@ -4,6 +4,9 @@ struct xt_tee_tginfo { union nf_inet_addr gw; char oif[16]; + + /* used internally by the kernel */ + struct xt_tee_priv *priv __attribute__((aligned(8))); }; #endif /* _XT_TEE_TARGET_H */ diff --git a/include/linux/netfilter/xt_connmark.h b/include/linux/netfilter/xt_connmark.h index 619e47cd..efc17a83 100644 --- a/include/linux/netfilter/xt_connmark.h +++ b/include/linux/netfilter/xt_connmark.h @@ -12,6 +12,17 @@ * (at your option) any later version. */ +enum { + XT_CONNMARK_SET = 0, + XT_CONNMARK_SAVE, + XT_CONNMARK_RESTORE +}; + +struct xt_connmark_tginfo1 { + __u32 ctmark, ctmask, nfmask; + __u8 mode; +}; + struct xt_connmark_mtinfo1 { __u32 mark, mask; __u8 invert; diff --git a/include/linux/netfilter/xt_mark.h b/include/linux/netfilter/xt_mark.h index 6607c8f3..ecadc40d 100644 --- a/include/linux/netfilter/xt_mark.h +++ b/include/linux/netfilter/xt_mark.h @@ -3,6 +3,10 @@ #include +struct xt_mark_tginfo2 { + __u32 mark, mask; +}; + struct xt_mark_mtinfo1 { __u32 mark, mask; __u8 invert; diff --git a/include/linux/netfilter/xt_recent.h b/include/linux/netfilter/xt_recent.h index d2c27660..83318e01 100644 --- a/include/linux/netfilter/xt_recent.h +++ b/include/linux/netfilter/xt_recent.h @@ -9,6 +9,7 @@ enum { XT_RECENT_UPDATE = 1 << 2, XT_RECENT_REMOVE = 1 << 3, XT_RECENT_TTL = 1 << 4, + XT_RECENT_REAP = 1 << 5, XT_RECENT_SOURCE = 0, XT_RECENT_DEST = 1, @@ -16,6 +17,12 @@ enum { XT_RECENT_NAME_LEN = 200, }; +/* Only allowed with --rcheck and --update */ +#define XT_RECENT_MODIFIERS (XT_RECENT_TTL|XT_RECENT_REAP) + +#define XT_RECENT_VALID_FLAGS (XT_RECENT_CHECK|XT_RECENT_SET|XT_RECENT_UPDATE|\ + XT_RECENT_REMOVE|XT_RECENT_TTL|XT_RECENT_REAP) + struct xt_recent_mtinfo { __u32 seconds; __u32 hit_count; diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h index 7430b392..f155b9d3 100644 --- a/include/linux/netfilter_ipv6.h +++ b/include/linux/netfilter_ipv6.h @@ -57,6 +57,7 @@ enum nf_ip6_hook_priorities { NF_IP6_PRI_FIRST = INT_MIN, NF_IP6_PRI_CONNTRACK_DEFRAG = -400, + NF_IP6_PRI_RAW = -300, NF_IP6_PRI_SELINUX_FIRST = -225, NF_IP6_PRI_CONNTRACK = -200, NF_IP6_PRI_MANGLE = -150, -- cgit v1.2.3 From 0cb675b8f18c4b074d4c69461638820708e98100 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 7 Jun 2010 11:50:25 +0200 Subject: xtables: another try at chain name length checking Since XT_EXTENSION_MAXNAMELEN is now available, make use of it and clear the confusion. Signed-off-by: Jan Engelhardt --- ip6tables-restore.c | 4 ++-- ip6tables.c | 4 ++-- iptables-restore.c | 4 ++-- iptables.c | 4 ++-- xtables.c | 10 ++++------ 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/ip6tables-restore.c b/ip6tables-restore.c index f0725d1e..008566c4 100644 --- a/ip6tables-restore.c +++ b/ip6tables-restore.c @@ -253,11 +253,11 @@ int main(int argc, char *argv[]) exit(1); } - if (strlen(chain) > XT_FUNCTION_MAXNAMELEN - 1) + if (strlen(chain) >= XT_EXTENSION_MAXNAMELEN) xtables_error(PARAMETER_PROBLEM, "Invalid chain name `%s' " "(%u chars max)", - chain, XT_FUNCTION_MAXNAMELEN - 1); + chain, XT_EXTENSION_MAXNAMELEN - 1); if (ip6tc_builtin(chain, handle) <= 0) { if (noflush && ip6tc_is_chain(chain, handle)) { diff --git a/ip6tables.c b/ip6tables.c index 4e73d34e..2fff21bf 100644 --- a/ip6tables.c +++ b/ip6tables.c @@ -456,10 +456,10 @@ parse_target(const char *targetname) xtables_error(PARAMETER_PROBLEM, "Invalid target name (too short)"); - if (strlen(targetname) > XT_FUNCTION_MAXNAMELEN - 1) + if (strlen(targetname) >= XT_EXTENSION_MAXNAMELEN) xtables_error(PARAMETER_PROBLEM, "Invalid target name `%s' (%u chars max)", - targetname, XT_FUNCTION_MAXNAMELEN - 1); + targetname, XT_EXTENSION_MAXNAMELEN - 1); for (ptr = targetname; *ptr; ptr++) if (isspace(*ptr)) diff --git a/iptables-restore.c b/iptables-restore.c index 4a74485c..8c6648e9 100644 --- a/iptables-restore.c +++ b/iptables-restore.c @@ -259,11 +259,11 @@ main(int argc, char *argv[]) exit(1); } - if (strlen(chain) > XT_FUNCTION_MAXNAMELEN - 1) + if (strlen(chain) >= XT_EXTENSION_MAXNAMELEN) xtables_error(PARAMETER_PROBLEM, "Invalid chain name `%s' " "(%u chars max)", - chain, XT_FUNCTION_MAXNAMELEN - 1); + chain, XT_EXTENSION_MAXNAMELEN - 1); if (iptc_builtin(chain, handle) <= 0) { if (noflush && iptc_is_chain(chain, handle)) { diff --git a/iptables.c b/iptables.c index 19c2af54..efe993e1 100644 --- a/iptables.c +++ b/iptables.c @@ -460,10 +460,10 @@ parse_target(const char *targetname) xtables_error(PARAMETER_PROBLEM, "Invalid target name (too short)"); - if (strlen(targetname) > XT_FUNCTION_MAXNAMELEN - 1) + if (strlen(targetname) >= XT_EXTENSION_MAXNAMELEN) xtables_error(PARAMETER_PROBLEM, "Invalid target name `%s' (%u chars max)", - targetname, XT_FUNCTION_MAXNAMELEN - 1); + targetname, XT_EXTENSION_MAXNAMELEN - 1); for (ptr = targetname; *ptr; ptr++) if (isspace(*ptr)) diff --git a/xtables.c b/xtables.c index 440b2e14..b4c4f6b3 100644 --- a/xtables.c +++ b/xtables.c @@ -545,10 +545,10 @@ xtables_find_match(const char *name, enum xtables_tryload tryload, struct xtables_match *ptr; const char *icmp6 = "icmp6"; - if (strlen(name) > XT_FUNCTION_MAXNAMELEN - 1) + if (strlen(name) >= XT_EXTENSION_MAXNAMELEN) xtables_error(PARAMETER_PROBLEM, "Invalid match name \"%s\" (%u chars max)", - name, XT_FUNCTION_MAXNAMELEN - 1); + name, XT_EXTENSION_MAXNAMELEN - 1); /* This is ugly as hell. Nonetheless, there is no way of changing * this without hurting backwards compatibility */ @@ -741,8 +741,7 @@ void xtables_register_match(struct xtables_match *me) exit(1); } - /* Revision field stole a char from name. */ - if (strlen(me->name) >= XT_FUNCTION_MAXNAMELEN-1) { + if (strlen(me->name) >= XT_EXTENSION_MAXNAMELEN) { fprintf(stderr, "%s: target `%s' has invalid name\n", xt_params->program_name, me->name); exit(1); @@ -827,8 +826,7 @@ void xtables_register_target(struct xtables_target *me) exit(1); } - /* Revision field stole a char from name. */ - if (strlen(me->name) >= XT_FUNCTION_MAXNAMELEN-1) { + if (strlen(me->name) >= XT_EXTENSION_MAXNAMELEN) { fprintf(stderr, "%s: target `%s' has invalid name\n", xt_params->program_name, me->name); exit(1); -- cgit v1.2.3 From 11c2dd54b69e06ae3f35dea130ecba3df3859243 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 7 Jun 2010 12:00:24 +0200 Subject: xtables: remove xtables_set_revision function Since iptables uses its own copies of the header files anyway where the revision field is exposed, there is no reach to access name[] beyond its size. Signed-off-by: Jan Engelhardt --- configure.ac | 2 +- include/xtables.h.in | 1 - ip6tables.c | 8 +++----- iptables.c | 11 ++++------- xtables.c | 8 -------- 5 files changed, 8 insertions(+), 22 deletions(-) diff --git a/configure.ac b/configure.ac index ba723bf3..dd74a895 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_INIT([iptables], [1.4.8]) # See libtool.info "Libtool's versioning system" -libxtables_vcurrent=4 +libxtables_vcurrent=5 libxtables_vage=0 AC_CONFIG_HEADERS([config.h]) diff --git a/include/xtables.h.in b/include/xtables.h.in index 788ad7de..2d7df322 100644 --- a/include/xtables.h.in +++ b/include/xtables.h.in @@ -216,7 +216,6 @@ extern void *xtables_realloc(void *, size_t); extern int xtables_insmod(const char *, const char *, bool); extern int xtables_load_ko(const char *, bool); extern int xtables_set_params(struct xtables_globals *xtp); -extern void xtables_set_revision(char *name, u_int8_t revision); extern void xtables_free_opts(int reset_offset); extern struct option *xtables_merge_options(struct option *oldopts, const struct option *newopts, unsigned int *option_offset); diff --git a/ip6tables.c b/ip6tables.c index 2fff21bf..6c5d124c 100644 --- a/ip6tables.c +++ b/ip6tables.c @@ -1558,8 +1558,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand target->t = xtables_calloc(1, size); target->t->u.target_size = size; strcpy(target->t->u.user.name, jumpto); - xtables_set_revision(target->t->u.user.name, - target->revision); + target->t->u.user.revision = target->revision; if (target->init != NULL) target->init(target->t); opts = xtables_merge_options(opts, @@ -1611,7 +1610,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand m->m = xtables_calloc(1, size); m->m->u.match_size = size; strcpy(m->m->u.user.name, m->name); - xtables_set_revision(m->m->u.user.name, m->revision); + m->m->u.user.revision = m->revision; if (m->init != NULL) m->init(m->m); if (m != m->next) @@ -1759,8 +1758,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand m->m = xtables_calloc(1, size); m->m->u.match_size = size; strcpy(m->m->u.user.name, m->name); - xtables_set_revision(m->m->u.user.name, - m->revision); + m->m->u.user.revision = m->revision; if (m->init != NULL) m->init(m->m); diff --git a/iptables.c b/iptables.c index efe993e1..19f6d4fe 100644 --- a/iptables.c +++ b/iptables.c @@ -1573,8 +1573,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle target->t = xtables_calloc(1, size); target->t->u.target_size = size; strcpy(target->t->u.user.name, jumpto); - xtables_set_revision(target->t->u.user.name, - target->revision); + target->t->u.user.revision = target->revision; if (target->init != NULL) target->init(target->t); opts = xtables_merge_options(opts, @@ -1632,7 +1631,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle m->m = xtables_calloc(1, size); m->m->u.match_size = size; strcpy(m->m->u.user.name, m->name); - xtables_set_revision(m->m->u.user.name, m->revision); + m->m->u.user.revision = m->revision; if (m->init != NULL) m->init(m->m); if (m != m->next) { @@ -1787,8 +1786,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle m->m = xtables_calloc(1, size); m->m->u.match_size = size; strcpy(m->m->u.user.name, m->name); - xtables_set_revision(m->m->u.user.name, - m->revision); + m->m->u.user.revision = m->revision; if (m->init != NULL) m->init(m->m); @@ -1947,8 +1945,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle target->t->u.target_size = size; strcpy(target->t->u.user.name, jumpto); if (!iptc_is_chain(jumpto, *handle)) - xtables_set_revision(target->t->u.user.name, - target->revision); + target->t->u.user.revision = target->revision; if (target->init != NULL) target->init(target->t); } diff --git a/xtables.c b/xtables.c index b4c4f6b3..ed082f3f 100644 --- a/xtables.c +++ b/xtables.c @@ -114,14 +114,6 @@ struct option *xtables_merge_options(struct option *oldopts, return merge; } -void xtables_set_revision(char *name, u_int8_t revision) -{ - /* Old kernel sources don't have ".revision" field, - * but we stole a byte from name. */ - name[XT_FUNCTION_MAXNAMELEN - 2] = '\0'; - name[XT_FUNCTION_MAXNAMELEN - 1] = revision; -} - /** * xtables_afinfo - protocol family dependent information * @kmod: kernel module basename (e.g. "ip_tables") -- cgit v1.2.3 From d40f1628c3717daebc437a398a285e371b5b6f7f Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Wed, 16 Jun 2010 12:45:33 +0200 Subject: libxt_set: new revision added libipt_set renamed to libxt_set and the support for the forthcoming ipset release added. I have tested backward (IPv4) and forward compatibility (IPv4/IPv6): ipset -N test iphash ipset -A test test-address iptables -N test-set iptables -A test-set -j LOG --log-prefix "match " iptables -A test-set -j DROP iptables -A OUTPUT -m set --match-set test dst -j test-set ping test-address --- extensions/libipt_SET.c | 164 ----------- extensions/libipt_SET.man | 18 -- extensions/libipt_set.c | 160 ----------- extensions/libipt_set.h | 119 -------- extensions/libipt_set.man | 23 -- extensions/libxt_SET.c | 286 +++++++++++++++++++ extensions/libxt_SET.man | 18 ++ extensions/libxt_set.c | 250 +++++++++++++++++ extensions/libxt_set.h | 147 ++++++++++ extensions/libxt_set.man | 23 ++ include/linux/netfilter/xt_set.h | 110 ++++++++ include/linux/netfilter_ipv4/ip_set.h | 498 --------------------------------- include/linux/netfilter_ipv4/ipt_set.h | 21 -- 13 files changed, 834 insertions(+), 1003 deletions(-) delete mode 100644 extensions/libipt_SET.c delete mode 100644 extensions/libipt_SET.man delete mode 100644 extensions/libipt_set.c delete mode 100644 extensions/libipt_set.h delete mode 100644 extensions/libipt_set.man create mode 100644 extensions/libxt_SET.c create mode 100644 extensions/libxt_SET.man create mode 100644 extensions/libxt_set.c create mode 100644 extensions/libxt_set.h create mode 100644 extensions/libxt_set.man create mode 100644 include/linux/netfilter/xt_set.h delete mode 100644 include/linux/netfilter_ipv4/ip_set.h delete mode 100644 include/linux/netfilter_ipv4/ipt_set.h diff --git a/extensions/libipt_SET.c b/extensions/libipt_SET.c deleted file mode 100644 index 18cf7d48..00000000 --- a/extensions/libipt_SET.c +++ /dev/null @@ -1,164 +0,0 @@ -/* Copyright (C) 2000-2002 Joakim Axelsson - * Patrick Schaaf - * Martin Josefsson - * Copyright (C) 2003-2004 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Shared library add-on to iptables to add IP set mangling target. */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "libipt_set.h" - -static void SET_help(void) -{ - printf("SET target options:\n" - " --add-set name flags\n" - " --del-set name flags\n" - " add/del src/dst IP/port from/to named sets,\n" - " where flags are the comma separated list of\n" - " 'src' and 'dst' specifications.\n"); -} - -static const struct option SET_opts[] = { - { .name = "add-set", .has_arg = true, .val = '1'}, - { .name = "del-set", .has_arg = true, .val = '2'}, - { .name = NULL } -}; - -static void SET_init(struct xt_entry_target *target) -{ - struct ipt_set_info_target *info = - (struct ipt_set_info_target *) target->data; - - memset(info, 0, sizeof(struct ipt_set_info_target)); - info->add_set.index = - info->del_set.index = IP_SET_INVALID_ID; - -} - -static void -parse_target(char **argv, int invert, unsigned int *flags, - struct ipt_set_info *info, const char *what) -{ - if (info->flags[0]) - xtables_error(PARAMETER_PROBLEM, - "--%s can be specified only once", what); - - if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) - xtables_error(PARAMETER_PROBLEM, - "Unexpected `!' after --%s", what); - - if (!argv[optind] - || argv[optind][0] == '-' || argv[optind][0] == '!') - xtables_error(PARAMETER_PROBLEM, - "--%s requires two args.", what); - - if (strlen(optarg) > IP_SET_MAXNAMELEN - 1) - xtables_error(PARAMETER_PROBLEM, - "setname `%s' too long, max %d characters.", - optarg, IP_SET_MAXNAMELEN - 1); - - get_set_byname(optarg, info); - parse_bindings(argv[optind], info); - optind++; - - *flags = 1; -} - -static int SET_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) -{ - struct ipt_set_info_target *myinfo = - (struct ipt_set_info_target *) (*target)->data; - - switch (c) { - case '1': /* --add-set */ - parse_target(argv, invert, flags, - &myinfo->add_set, "add-set"); - break; - case '2': /* --del-set [:] */ - parse_target(argv, invert, flags, - &myinfo->del_set, "del-set"); - break; - - default: - return 0; - } - return 1; -} - -static void SET_check(unsigned int flags) -{ - if (!flags) - xtables_error(PARAMETER_PROBLEM, - "You must specify either `--add-set' or `--del-set'"); -} - -static void -print_target(const char *prefix, const struct ipt_set_info *info) -{ - int i; - char setname[IP_SET_MAXNAMELEN]; - - if (info->index == IP_SET_INVALID_ID) - return; - get_set_byid(setname, info->index); - printf("%s %s", prefix, setname); - for (i = 0; i < IP_SET_MAX_BINDINGS; i++) { - if (!info->flags[i]) - break; - printf("%s%s", - i == 0 ? " " : ",", - info->flags[i] & IPSET_SRC ? "src" : "dst"); - } - printf(" "); -} - -static void SET_print(const void *ip, const struct xt_entry_target *target, - int numeric) -{ - const struct ipt_set_info_target *info = (const void *)target->data; - - print_target("add-set", &info->add_set); - print_target("del-set", &info->del_set); -} - -static void SET_save(const void *ip, const struct xt_entry_target *target) -{ - const struct ipt_set_info_target *info = (const void *)target->data; - - print_target("--add-set", &info->add_set); - print_target("--del-set", &info->del_set); -} - -static struct xtables_target set_tg_reg = { - .name = "SET", - .version = XTABLES_VERSION, - .family = NFPROTO_IPV4, - .size = XT_ALIGN(sizeof(struct ipt_set_info_target)), - .userspacesize = XT_ALIGN(sizeof(struct ipt_set_info_target)), - .help = SET_help, - .init = SET_init, - .parse = SET_parse, - .final_check = SET_check, - .print = SET_print, - .save = SET_save, - .extra_opts = SET_opts, -}; - -void _init(void) -{ - xtables_register_target(&set_tg_reg); -} diff --git a/extensions/libipt_SET.man b/extensions/libipt_SET.man deleted file mode 100644 index ea80c2a1..00000000 --- a/extensions/libipt_SET.man +++ /dev/null @@ -1,18 +0,0 @@ -This modules adds and/or deletes entries from IP sets which can be defined -by ipset(8). -.TP -\fB\-\-add\-set\fP \fIsetname\fP \fIflag\fP[\fB,\fP\fIflag\fP...] -add the address(es)/port(s) of the packet to the sets -.TP -\fB\-\-del\-set\fP \fIsetname\fP \fIflag\fP[\fB,\fP\fIflag\fP...] -delete the address(es)/port(s) of the packet from the sets -.IP -where flags are -.BR "src" -and/or -.BR "dst" -specifications and there can be no more than six of them. -.PP -Use of -j SET requires that ipset kernel support is provided. As standard -kernels do not ship this currently, the ipset or Xtables-addons package needs -to be installed. diff --git a/extensions/libipt_set.c b/extensions/libipt_set.c deleted file mode 100644 index 9f7a97c9..00000000 --- a/extensions/libipt_set.c +++ /dev/null @@ -1,160 +0,0 @@ -/* Copyright (C) 2000-2002 Joakim Axelsson - * Patrick Schaaf - * Martin Josefsson - * Copyright (C) 2003-2004 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Shared library add-on to iptables to add IP set matching. */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "libipt_set.h" - -static void set_help(void) -{ - printf("set match options:\n" - " [!] --match-set name flags\n" - " 'name' is the set name from to match,\n" - " 'flags' are the comma separated list of\n" - " 'src' and 'dst' specifications.\n"); -} - -static const struct option set_opts[] = { - { .name = "match-set", .has_arg = true, .val = '1'}, - { .name = "set", .has_arg = true, .val = '2'}, - { .name = NULL } -}; - -static void set_init(struct xt_entry_match *match) -{ - struct ipt_set_info_match *info = - (struct ipt_set_info_match *) match->data; - - - memset(info, 0, sizeof(struct ipt_set_info_match)); - -} - -static int set_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) -{ - struct ipt_set_info_match *myinfo = - (struct ipt_set_info_match *) (*match)->data; - struct ipt_set_info *info = &myinfo->match_set; - - switch (c) { - case '2': -#if 0 - fprintf(stderr, - "--set option deprecated, please use --match-set\n"); -#endif - case '1': /* --match-set [, */ - if (info->flags[0]) - xtables_error(PARAMETER_PROBLEM, - "--match-set can be specified only once"); - - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - if (invert) - info->flags[0] |= IPSET_MATCH_INV; - - if (!argv[optind] - || argv[optind][0] == '-' - || argv[optind][0] == '!') - xtables_error(PARAMETER_PROBLEM, - "--match-set requires two args."); - - if (strlen(optarg) > IP_SET_MAXNAMELEN - 1) - xtables_error(PARAMETER_PROBLEM, - "setname `%s' too long, max %d characters.", - optarg, IP_SET_MAXNAMELEN - 1); - - get_set_byname(optarg, info); - parse_bindings(argv[optind], info); - DEBUGP("parse: set index %u\n", info->index); - optind++; - - *flags = 1; - break; - - default: - return 0; - } - - return 1; -} - -static void set_check(unsigned int flags) -{ - if (!flags) - xtables_error(PARAMETER_PROBLEM, - "You must specify `--match-set' with proper arguments"); - DEBUGP("final check OK\n"); -} - -static void -print_match(const char *prefix, const struct ipt_set_info *info) -{ - int i; - char setname[IP_SET_MAXNAMELEN]; - - get_set_byid(setname, info->index); - printf("%s%s %s", - (info->flags[0] & IPSET_MATCH_INV) ? "! " : "", - prefix, - setname); - for (i = 0; i < IP_SET_MAX_BINDINGS; i++) { - if (!info->flags[i]) - break; - printf("%s%s", - i == 0 ? " " : ",", - info->flags[i] & IPSET_SRC ? "src" : "dst"); - } - printf(" "); -} - -/* Prints out the matchinfo. */ -static void set_print(const void *ip, const struct xt_entry_match *match, - int numeric) -{ - const struct ipt_set_info_match *info = (const void *)match->data; - - print_match("match-set", &info->match_set); -} - -static void set_save(const void *ip, const struct xt_entry_match *match) -{ - const struct ipt_set_info_match *info = (const void *)match->data; - - print_match("--match-set", &info->match_set); -} - -static struct xtables_match set_mt_reg = { - .name = "set", - .version = XTABLES_VERSION, - .family = NFPROTO_IPV4, - .size = XT_ALIGN(sizeof(struct ipt_set_info_match)), - .userspacesize = XT_ALIGN(sizeof(struct ipt_set_info_match)), - .help = set_help, - .init = set_init, - .parse = set_parse, - .final_check = set_check, - .print = set_print, - .save = set_save, - .extra_opts = set_opts, -}; - -void _init(void) -{ - xtables_register_match(&set_mt_reg); -} diff --git a/extensions/libipt_set.h b/extensions/libipt_set.h deleted file mode 100644 index 0e9b0b54..00000000 --- a/extensions/libipt_set.h +++ /dev/null @@ -1,119 +0,0 @@ -#ifndef _LIBIPT_SET_H -#define _LIBIPT_SET_H - -#include -#include -#include -#include - -#ifdef DEBUG -#define DEBUGP(x, args...) fprintf(stderr, x, ## args) -#else -#define DEBUGP(x, args...) -#endif - -static void -parse_bindings(const char *opt_arg, struct ipt_set_info *info) -{ - char *saved = strdup(opt_arg); - char *ptr, *tmp = saved; - int i = 0; - - while (i < (IP_SET_MAX_BINDINGS - 1) && tmp != NULL) { - ptr = strsep(&tmp, ","); - if (strncmp(ptr, "src", 3) == 0) - info->flags[i++] |= IPSET_SRC; - else if (strncmp(ptr, "dst", 3) == 0) - info->flags[i++] |= IPSET_DST; - else - xtables_error(PARAMETER_PROBLEM, - "You must spefify (the comma separated list of) 'src' or 'dst'."); - } - - if (tmp) - xtables_error(PARAMETER_PROBLEM, - "Can't follow bindings deeper than %i.", - IP_SET_MAX_BINDINGS - 1); - - free(saved); -} - -static int get_version(unsigned *version) -{ - int res, sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); - struct ip_set_req_version req_version; - socklen_t size = sizeof(req_version); - - if (sockfd < 0) - xtables_error(OTHER_PROBLEM, - "Can't open socket to ipset.\n"); - - req_version.op = IP_SET_OP_VERSION; - res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req_version, &size); - if (res != 0) - xtables_error(OTHER_PROBLEM, - "Kernel module ip_set is not loaded in.\n"); - - *version = req_version.version; - - return sockfd; -} - -static void get_set_byname(const char *setname, struct ipt_set_info *info) -{ - struct ip_set_req_get_set req; - socklen_t size = sizeof(struct ip_set_req_get_set); - int res, sockfd; - - sockfd = get_version(&req.version); - req.op = IP_SET_OP_GET_BYNAME; - strncpy(req.set.name, setname, IP_SET_MAXNAMELEN); - req.set.name[IP_SET_MAXNAMELEN - 1] = '\0'; - res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req, &size); - close(sockfd); - - if (res != 0) - xtables_error(OTHER_PROBLEM, - "Problem when communicating with ipset, errno=%d.\n", - errno); - if (size != sizeof(struct ip_set_req_get_set)) - xtables_error(OTHER_PROBLEM, - "Incorrect return size from kernel during ipset lookup, " - "(want %zu, got %zu)\n", - sizeof(struct ip_set_req_get_set), (size_t)size); - if (req.set.index == IP_SET_INVALID_ID) - xtables_error(PARAMETER_PROBLEM, - "Set %s doesn't exist.\n", setname); - - info->index = req.set.index; -} - -static void get_set_byid(char * setname, ip_set_id_t idx) -{ - struct ip_set_req_get_set req; - socklen_t size = sizeof(struct ip_set_req_get_set); - int res, sockfd; - - sockfd = get_version(&req.version); - req.op = IP_SET_OP_GET_BYINDEX; - req.set.index = idx; - res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req, &size); - close(sockfd); - - if (res != 0) - xtables_error(OTHER_PROBLEM, - "Problem when communicating with ipset, errno=%d.\n", - errno); - if (size != sizeof(struct ip_set_req_get_set)) - xtables_error(OTHER_PROBLEM, - "Incorrect return size from kernel during ipset lookup, " - "(want %zu, got %zu)\n", - sizeof(struct ip_set_req_get_set), (size_t)size); - if (req.set.name[0] == '\0') - xtables_error(PARAMETER_PROBLEM, - "Set id %i in kernel doesn't exist.\n", idx); - - strncpy(setname, req.set.name, IP_SET_MAXNAMELEN); -} - -#endif /*_LIBIPT_SET_H*/ diff --git a/extensions/libipt_set.man b/extensions/libipt_set.man deleted file mode 100644 index aca1bfce..00000000 --- a/extensions/libipt_set.man +++ /dev/null @@ -1,23 +0,0 @@ -This module matches IP sets which can be defined by ipset(8). -.TP -[\fB!\fP] \fB\-\-match\-set\fP \fIsetname\fP \fIflag\fP[\fB,\fP\fIflag\fP]... -where flags are the comma separated list of -.BR "src" -and/or -.BR "dst" -specifications and there can be no more than six of them. Hence the command -.IP - iptables \-A FORWARD \-m set \-\-match\-set test src,dst -.IP -will match packets, for which (if the set type is ipportmap) the source -address and destination port pair can be found in the specified set. If -the set type of the specified set is single dimension (for example ipmap), -then the command will match packets for which the source address can be -found in the specified set. -.PP -The option \fB\-\-match\-set\fR can be replaced by \fB\-\-set\fR if that does -not clash with an option of other extensions. -.PP -Use of -m set requires that ipset kernel support is provided. As standard -kernels do not ship this currently, the ipset or Xtables-addons package needs -to be installed. diff --git a/extensions/libxt_SET.c b/extensions/libxt_SET.c new file mode 100644 index 00000000..f6386a9e --- /dev/null +++ b/extensions/libxt_SET.c @@ -0,0 +1,286 @@ +/* Copyright (C) 2000-2002 Joakim Axelsson + * Patrick Schaaf + * Martin Josefsson + * Copyright (C) 2003-2010 Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* Shared library add-on to iptables to add IP set mangling target. */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include "libxt_set.h" + +static void +set_target_help(void) +{ + printf("SET target options:\n" + " --add-set name flags\n" + " --del-set name flags\n" + " add/del src/dst IP/port from/to named sets,\n" + " where flags are the comma separated list of\n" + " 'src' and 'dst' specifications.\n"); +} + +static const struct option set_target_opts[] = { + { .name = "add-set", .has_arg = true, .val = '1'}, + { .name = "del-set", .has_arg = true, .val = '2'}, + { .name = NULL } +}; + +static void +set_target_check(unsigned int flags) +{ + if (!flags) + xtables_error(PARAMETER_PROBLEM, + "You must specify either `--add-set' or `--del-set'"); +} + +static void +set_target_init_v0(struct xt_entry_target *target) +{ + struct xt_set_info_target_v0 *info = + (struct xt_set_info_target_v0 *) target->data; + + info->add_set.index = + info->del_set.index = IPSET_INVALID_ID; + +} + +static void +parse_target_v0(char **argv, int invert, unsigned int *flags, + struct xt_set_info_v0 *info, const char *what) +{ + if (info->u.flags[0]) + xtables_error(PARAMETER_PROBLEM, + "--%s can be specified only once", what); + + if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) + xtables_error(PARAMETER_PROBLEM, + "Unexpected `!' after --%s", what); + + if (!argv[optind] + || argv[optind][0] == '-' || argv[optind][0] == '!') + xtables_error(PARAMETER_PROBLEM, + "--%s requires two args.", what); + + if (strlen(optarg) > IPSET_MAXNAMELEN - 1) + xtables_error(PARAMETER_PROBLEM, + "setname `%s' too long, max %d characters.", + optarg, IPSET_MAXNAMELEN - 1); + + get_set_byname(optarg, (struct xt_set_info *)info); + parse_dirs_v0(argv[optind], info); + optind++; + + *flags = 1; +} + +static int +set_target_parse_v0(int c, char **argv, int invert, unsigned int *flags, + const void *entry, struct xt_entry_target **target) +{ + struct xt_set_info_target_v0 *myinfo = + (struct xt_set_info_target_v0 *) (*target)->data; + + switch (c) { + case '1': /* --add-set */ + parse_target_v0(argv, invert, flags, + &myinfo->add_set, "add-set"); + break; + case '2': /* --del-set [:] */ + parse_target_v0(argv, invert, flags, + &myinfo->del_set, "del-set"); + break; + + default: + return 0; + } + return 1; +} + +static void +print_target_v0(const char *prefix, const struct xt_set_info_v0 *info) +{ + int i; + char setname[IPSET_MAXNAMELEN]; + + if (info->index == IPSET_INVALID_ID) + return; + get_set_byid(setname, info->index); + printf("%s %s", prefix, setname); + for (i = 0; i < IPSET_DIM_MAX; i++) { + if (!info->u.flags[i]) + break; + printf("%s%s", + i == 0 ? " " : ",", + info->u.flags[i] & IPSET_SRC ? "src" : "dst"); + } + printf(" "); +} + +static void +set_target_print_v0(const void *ip, const struct xt_entry_target *target, + int numeric) +{ + const struct xt_set_info_target_v0 *info = (const void *)target->data; + + print_target_v0("add-set", &info->add_set); + print_target_v0("del-set", &info->del_set); +} + +static void +set_target_save_v0(const void *ip, const struct xt_entry_target *target) +{ + const struct xt_set_info_target_v0 *info = (const void *)target->data; + + print_target_v0("--add-set", &info->add_set); + print_target_v0("--del-set", &info->del_set); +} + +static void +set_target_init(struct xt_entry_target *target) +{ + struct xt_set_info_target *info = + (struct xt_set_info_target *) target->data; + + info->add_set.index = + info->del_set.index = IPSET_INVALID_ID; + +} + +static void +parse_target(char **argv, int invert, unsigned int *flags, + struct xt_set_info *info, const char *what) +{ + if (info->dim) + xtables_error(PARAMETER_PROBLEM, + "--%s can be specified only once", what); + + if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) + xtables_error(PARAMETER_PROBLEM, + "Unexpected `!' after --%s", what); + + if (!argv[optind] + || argv[optind][0] == '-' || argv[optind][0] == '!') + xtables_error(PARAMETER_PROBLEM, + "--%s requires two args.", what); + + if (strlen(optarg) > IPSET_MAXNAMELEN - 1) + xtables_error(PARAMETER_PROBLEM, + "setname `%s' too long, max %d characters.", + optarg, IPSET_MAXNAMELEN - 1); + + get_set_byname(optarg, info); + parse_dirs(argv[optind], info); + optind++; + + *flags = 1; +} + +static int +set_target_parse(int c, char **argv, int invert, unsigned int *flags, + const void *entry, struct xt_entry_target **target) +{ + struct xt_set_info_target *myinfo = + (struct xt_set_info_target *) (*target)->data; + + switch (c) { + case '1': /* --add-set */ + parse_target(argv, invert, flags, + &myinfo->add_set, "add-set"); + break; + case '2': /* --del-set [:] */ + parse_target(argv, invert, flags, + &myinfo->del_set, "del-set"); + break; + + default: + return 0; + } + return 1; +} + +static void +print_target(const char *prefix, const struct xt_set_info *info) +{ + int i; + char setname[IPSET_MAXNAMELEN]; + + if (info->index == IPSET_INVALID_ID) + return; + get_set_byid(setname, info->index); + printf("%s %s", prefix, setname); + for (i = 1; i <= IPSET_DIM_MAX; i++) { + printf("%s%s", + i == 1 ? " " : ",", + info->flags & (1 << i) ? "src" : "dst"); + } + printf(" "); +} + +static void +set_target_print(const void *ip, const struct xt_entry_target *target, + int numeric) +{ + const struct xt_set_info_target *info = (const void *)target->data; + + print_target("add-set", &info->add_set); + print_target("del-set", &info->del_set); +} + +static void +set_target_save(const void *ip, const struct xt_entry_target *target) +{ + const struct xt_set_info_target *info = (const void *)target->data; + + print_target("--add-set", &info->add_set); + print_target("--del-set", &info->del_set); +} + +static struct xtables_target set_tg_reg[] = { + { + .name = "SET", + .revision = 0, + .version = XTABLES_VERSION, + .family = NFPROTO_IPV4, + .size = XT_ALIGN(sizeof(struct xt_set_info_target_v0)), + .userspacesize = XT_ALIGN(sizeof(struct xt_set_info_target_v0)), + .help = set_target_help, + .init = set_target_init_v0, + .parse = set_target_parse_v0, + .final_check = set_target_check, + .print = set_target_print_v0, + .save = set_target_save_v0, + .extra_opts = set_target_opts, + }, + { + .name = "SET", + .revision = 1, + .version = XTABLES_VERSION, + .family = NFPROTO_UNSPEC, + .size = XT_ALIGN(sizeof(struct xt_set_info_target)), + .userspacesize = XT_ALIGN(sizeof(struct xt_set_info_target)), + .help = set_target_help, + .init = set_target_init, + .parse = set_target_parse, + .final_check = set_target_check, + .print = set_target_print, + .save = set_target_save, + .extra_opts = set_target_opts, + }, +}; + +void _init(void) +{ + xtables_register_targets(set_tg_reg, ARRAY_SIZE(set_tg_reg)); +} diff --git a/extensions/libxt_SET.man b/extensions/libxt_SET.man new file mode 100644 index 00000000..ea80c2a1 --- /dev/null +++ b/extensions/libxt_SET.man @@ -0,0 +1,18 @@ +This modules adds and/or deletes entries from IP sets which can be defined +by ipset(8). +.TP +\fB\-\-add\-set\fP \fIsetname\fP \fIflag\fP[\fB,\fP\fIflag\fP...] +add the address(es)/port(s) of the packet to the sets +.TP +\fB\-\-del\-set\fP \fIsetname\fP \fIflag\fP[\fB,\fP\fIflag\fP...] +delete the address(es)/port(s) of the packet from the sets +.IP +where flags are +.BR "src" +and/or +.BR "dst" +specifications and there can be no more than six of them. +.PP +Use of -j SET requires that ipset kernel support is provided. As standard +kernels do not ship this currently, the ipset or Xtables-addons package needs +to be installed. diff --git a/extensions/libxt_set.c b/extensions/libxt_set.c new file mode 100644 index 00000000..75fa3c27 --- /dev/null +++ b/extensions/libxt_set.c @@ -0,0 +1,250 @@ +/* Copyright (C) 2000-2002 Joakim Axelsson + * Patrick Schaaf + * Martin Josefsson + * Copyright (C) 2003-2010 Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* Shared library add-on to iptables to add IP set matching. */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "libxt_set.h" + +static void +set_help(void) +{ + printf("set match options:\n" + " [!] --match-set name flags\n" + " 'name' is the set name from to match,\n" + " 'flags' are the comma separated list of\n" + " 'src' and 'dst' specifications.\n"); +} + +static const struct option set_opts[] = { + { .name = "match-set", .has_arg = true, .val = '1'}, + { .name = "set", .has_arg = true, .val = '2'}, + { .name = NULL } +}; + +static void +set_check(unsigned int flags) +{ + if (!flags) + xtables_error(PARAMETER_PROBLEM, + "You must specify `--match-set' with proper arguments"); +} + +static int +set_parse_v0(int c, char **argv, int invert, unsigned int *flags, + const void *entry, struct xt_entry_match **match) +{ + struct xt_set_info_match_v0 *myinfo = + (struct xt_set_info_match_v0 *) (*match)->data; + struct xt_set_info_v0 *info = &myinfo->match_set; + + switch (c) { + case '2': + fprintf(stderr, + "--set option deprecated, please use --match-set\n"); + case '1': /* --match-set [, */ + if (info->u.flags[0]) + xtables_error(PARAMETER_PROBLEM, + "--match-set can be specified only once"); + + xtables_check_inverse(optarg, &invert, &optind, 0, argv); + if (invert) + info->u.flags[0] |= IPSET_MATCH_INV; + + if (!argv[optind] + || argv[optind][0] == '-' + || argv[optind][0] == '!') + xtables_error(PARAMETER_PROBLEM, + "--match-set requires two args."); + + if (strlen(optarg) > IPSET_MAXNAMELEN - 1) + xtables_error(PARAMETER_PROBLEM, + "setname `%s' too long, max %d characters.", + optarg, IPSET_MAXNAMELEN - 1); + + get_set_byname(optarg, (struct xt_set_info *)info); + parse_dirs_v0(argv[optind], info); + DEBUGP("parse: set index %u\n", info->index); + optind++; + + *flags = 1; + break; + + default: + return 0; + } + + return 1; +} + +static void +print_match_v0(const char *prefix, const struct xt_set_info_v0 *info) +{ + int i; + char setname[IPSET_MAXNAMELEN]; + + get_set_byid(setname, info->index); + printf("%s%s %s", + (info->u.flags[0] & IPSET_MATCH_INV) ? "! " : "", + prefix, + setname); + for (i = 0; i < IPSET_DIM_MAX; i++) { + if (!info->u.flags[i]) + break; + printf("%s%s", + i == 0 ? " " : ",", + info->u.flags[i] & IPSET_SRC ? "src" : "dst"); + } + printf(" "); +} + +/* Prints out the matchinfo. */ +static void +set_print_v0(const void *ip, const struct xt_entry_match *match, int numeric) +{ + const struct xt_set_info_match_v0 *info = (const void *)match->data; + + print_match_v0("match-set", &info->match_set); +} + +static void +set_save_v0(const void *ip, const struct xt_entry_match *match) +{ + const struct xt_set_info_match_v0 *info = (const void *)match->data; + + print_match_v0("--match-set", &info->match_set); +} + +static int +set_parse(int c, char **argv, int invert, unsigned int *flags, + const void *entry, struct xt_entry_match **match) +{ + struct xt_set_info_match *myinfo = + (struct xt_set_info_match *) (*match)->data; + struct xt_set_info *info = &myinfo->match_set; + + switch (c) { + case '2': + fprintf(stderr, + "--set option deprecated, please use --match-set\n"); + case '1': /* --match-set [, */ + if (info->dim) + xtables_error(PARAMETER_PROBLEM, + "--match-set can be specified only once"); + + xtables_check_inverse(optarg, &invert, &optind, 0, argv); + if (invert) + info->flags |= IPSET_INV_MATCH; + + if (!argv[optind] + || argv[optind][0] == '-' + || argv[optind][0] == '!') + xtables_error(PARAMETER_PROBLEM, + "--match-set requires two args."); + + if (strlen(optarg) > IPSET_MAXNAMELEN - 1) + xtables_error(PARAMETER_PROBLEM, + "setname `%s' too long, max %d characters.", + optarg, IPSET_MAXNAMELEN - 1); + + get_set_byname(optarg, info); + parse_dirs(argv[optind], info); + DEBUGP("parse: set index %u\n", info->index); + optind++; + + *flags = 1; + break; + + default: + return 0; + } + + return 1; +} + +static void +print_match(const char *prefix, const struct xt_set_info *info) +{ + int i; + char setname[IPSET_MAXNAMELEN]; + + get_set_byid(setname, info->index); + printf("%s%s %s", + (info->flags & IPSET_INV_MATCH) ? "! " : "", + prefix, + setname); + for (i = 1; i <= info->dim; i++) { + printf("%s%s", + i == 1 ? " " : ",", + info->flags & (1 << i) ? "src" : "dst"); + } + printf(" "); +} + +/* Prints out the matchinfo. */ +static void +set_print(const void *ip, const struct xt_entry_match *match, int numeric) +{ + const struct xt_set_info_match *info = (const void *)match->data; + + print_match("match-set", &info->match_set); +} + +static void +set_save(const void *ip, const struct xt_entry_match *match) +{ + const struct xt_set_info_match *info = (const void *)match->data; + + print_match("--match-set", &info->match_set); +} + +static struct xtables_match set_mt_reg[] = { + { + .name = "set", + .revision = 0, + .version = XTABLES_VERSION, + .family = NFPROTO_IPV4, + .size = XT_ALIGN(sizeof(struct xt_set_info_match_v0)), + .userspacesize = XT_ALIGN(sizeof(struct xt_set_info_match_v0)), + .help = set_help, + .parse = set_parse_v0, + .final_check = set_check, + .print = set_print_v0, + .save = set_save_v0, + .extra_opts = set_opts, + }, + { + .name = "set", + .revision = 1, + .version = XTABLES_VERSION, + .family = NFPROTO_UNSPEC, + .size = XT_ALIGN(sizeof(struct xt_set_info_match)), + .userspacesize = XT_ALIGN(sizeof(struct xt_set_info_match)), + .help = set_help, + .parse = set_parse, + .final_check = set_check, + .print = set_print, + .save = set_save, + .extra_opts = set_opts, + }, +}; + +void _init(void) +{ + xtables_register_matches(set_mt_reg, ARRAY_SIZE(set_mt_reg)); +} diff --git a/extensions/libxt_set.h b/extensions/libxt_set.h new file mode 100644 index 00000000..6b936911 --- /dev/null +++ b/extensions/libxt_set.h @@ -0,0 +1,147 @@ +#ifndef _LIBXT_SET_H +#define _LIBXT_SET_H + +#include +#include +#include +#include + +#ifdef DEBUG +#define DEBUGP(x, args...) fprintf(stderr, x , ## args) +#else +#define DEBUGP(x, args...) +#endif + +static int +get_version(unsigned *version) +{ + int res, sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); + struct ip_set_req_version req_version; + socklen_t size = sizeof(req_version); + + if (sockfd < 0) + xtables_error(OTHER_PROBLEM, + "Can't open socket to ipset.\n"); + + req_version.op = IP_SET_OP_VERSION; + res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req_version, &size); + if (res != 0) + xtables_error(OTHER_PROBLEM, + "Kernel module xt_set is not loaded in.\n"); + + *version = req_version.version; + + return sockfd; +} + +static void +get_set_byid(char *setname, ip_set_id_t idx) +{ + struct ip_set_req_get_set req; + socklen_t size = sizeof(struct ip_set_req_get_set); + int res, sockfd; + + sockfd = get_version(&req.version); + req.op = IP_SET_OP_GET_BYINDEX; + req.set.index = idx; + res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req, &size); + close(sockfd); + + if (res != 0) + xtables_error(OTHER_PROBLEM, + "Problem when communicating with ipset, errno=%d.\n", + errno); + if (size != sizeof(struct ip_set_req_get_set)) + xtables_error(OTHER_PROBLEM, + "Incorrect return size from kernel during ipset lookup, " + "(want %zu, got %zu)\n", + sizeof(struct ip_set_req_get_set), (size_t)size); + if (req.set.name[0] == '\0') + xtables_error(PARAMETER_PROBLEM, + "Set with index %i in kernel doesn't exist.\n", idx); + + strncpy(setname, req.set.name, IPSET_MAXNAMELEN); +} + +static void +get_set_byname(const char *setname, struct xt_set_info *info) +{ + struct ip_set_req_get_set req; + socklen_t size = sizeof(struct ip_set_req_get_set); + int res, sockfd; + + sockfd = get_version(&req.version); + req.op = IP_SET_OP_GET_BYNAME; + strncpy(req.set.name, setname, IPSET_MAXNAMELEN); + req.set.name[IPSET_MAXNAMELEN - 1] = '\0'; + res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req, &size); + close(sockfd); + + if (res != 0) + xtables_error(OTHER_PROBLEM, + "Problem when communicating with ipset, errno=%d.\n", + errno); + if (size != sizeof(struct ip_set_req_get_set)) + xtables_error(OTHER_PROBLEM, + "Incorrect return size from kernel during ipset lookup, " + "(want %zu, got %zu)\n", + sizeof(struct ip_set_req_get_set), (size_t)size); + if (req.set.index == IPSET_INVALID_ID) + xtables_error(PARAMETER_PROBLEM, + "Set %s doesn't exist.\n", setname); + + info->index = req.set.index; +} + +static void +parse_dirs_v0(const char *opt_arg, struct xt_set_info_v0 *info) +{ + char *saved = strdup(opt_arg); + char *ptr, *tmp = saved; + int i = 0; + + while (i < (IPSET_DIM_MAX - 1) && tmp != NULL) { + ptr = strsep(&tmp, ","); + if (strncmp(ptr, "src", 3) == 0) + info->u.flags[i++] |= IPSET_SRC; + else if (strncmp(ptr, "dst", 3) == 0) + info->u.flags[i++] |= IPSET_DST; + else + xtables_error(PARAMETER_PROBLEM, + "You must spefify (the comma separated list of) 'src' or 'dst'."); + } + + if (tmp) + xtables_error(PARAMETER_PROBLEM, + "Can't be more src/dst options than %i.", + IPSET_DIM_MAX - 1); + + free(saved); +} + +static void +parse_dirs(const char *opt_arg, struct xt_set_info *info) +{ + char *saved = strdup(opt_arg); + char *ptr, *tmp = saved; + int i = 0; + + while (i < (IPSET_DIM_MAX - 1) && tmp != NULL) { + info->dim++; + ptr = strsep(&tmp, ","); + if (strncmp(ptr, "src", 3) == 0) + info->flags |= (1 << info->dim); + else if (strncmp(ptr, "dst", 3) != 0) + xtables_error(PARAMETER_PROBLEM, + "You must spefify (the comma separated list of) 'src' or 'dst'."); + } + + if (tmp) + xtables_error(PARAMETER_PROBLEM, + "Can't be more src/dst options than %i.", + IPSET_DIM_MAX - 1); + + free(saved); +} + +#endif /*_LIBXT_SET_H*/ diff --git a/extensions/libxt_set.man b/extensions/libxt_set.man new file mode 100644 index 00000000..aca1bfce --- /dev/null +++ b/extensions/libxt_set.man @@ -0,0 +1,23 @@ +This module matches IP sets which can be defined by ipset(8). +.TP +[\fB!\fP] \fB\-\-match\-set\fP \fIsetname\fP \fIflag\fP[\fB,\fP\fIflag\fP]... +where flags are the comma separated list of +.BR "src" +and/or +.BR "dst" +specifications and there can be no more than six of them. Hence the command +.IP + iptables \-A FORWARD \-m set \-\-match\-set test src,dst +.IP +will match packets, for which (if the set type is ipportmap) the source +address and destination port pair can be found in the specified set. If +the set type of the specified set is single dimension (for example ipmap), +then the command will match packets for which the source address can be +found in the specified set. +.PP +The option \fB\-\-match\-set\fR can be replaced by \fB\-\-set\fR if that does +not clash with an option of other extensions. +.PP +Use of -m set requires that ipset kernel support is provided. As standard +kernels do not ship this currently, the ipset or Xtables-addons package needs +to be installed. diff --git a/include/linux/netfilter/xt_set.h b/include/linux/netfilter/xt_set.h new file mode 100644 index 00000000..3ad31378 --- /dev/null +++ b/include/linux/netfilter/xt_set.h @@ -0,0 +1,110 @@ +#ifndef _XT_SET_H +#define _XT_SET_H + +/* The protocol version */ +#define IPSET_PROTOCOL 5 + +/* The max length of strings including NUL: set and type identifiers */ +#define IPSET_MAXNAMELEN 32 + +/* Sets are identified by an index in kernel space. Tweak with ip_set_id_t + * and IPSET_INVALID_ID if you want to increase the max number of sets. + */ +typedef uint16_t ip_set_id_t; + +#define IPSET_INVALID_ID 65535 + +enum ip_set_dim { + IPSET_DIM_ZERO = 0, + IPSET_DIM_ONE, + IPSET_DIM_TWO, + IPSET_DIM_THREE, + /* Max dimension in elements. + * If changed, new revision of iptables match/target is required. + */ + IPSET_DIM_MAX = 6, +}; + +/* Option flags for kernel operations */ +enum ip_set_kopt { + IPSET_INV_MATCH = (1 << IPSET_DIM_ZERO), + IPSET_DIM_ONE_SRC = (1 << IPSET_DIM_ONE), + IPSET_DIM_TWO_SRC = (1 << IPSET_DIM_TWO), + IPSET_DIM_THREE_SRC = (1 << IPSET_DIM_THREE), +}; + +/* Interface to iptables/ip6tables */ + +#define SO_IP_SET 83 + +union ip_set_name_index { + char name[IPSET_MAXNAMELEN]; + ip_set_id_t index; +}; + +#define IP_SET_OP_GET_BYNAME 0x00000006 /* Get set index by name */ +struct ip_set_req_get_set { + unsigned op; + unsigned version; + union ip_set_name_index set; +}; + +#define IP_SET_OP_GET_BYINDEX 0x00000007 /* Get set name by index */ +/* Uses ip_set_req_get_set */ + +#define IP_SET_OP_VERSION 0x00000100 /* Ask kernel version */ +struct ip_set_req_version { + unsigned op; + unsigned version; +}; + +/* Revision 0 interface: backward compatible with netfilter/iptables */ + +/* + * Option flags for kernel operations (xt_set_info_v0) + */ +#define IPSET_SRC 0x01 /* Source match/add */ +#define IPSET_DST 0x02 /* Destination match/add */ +#define IPSET_MATCH_INV 0x04 /* Inverse matching */ + +struct xt_set_info_v0 { + ip_set_id_t index; + union { + u_int32_t flags[IPSET_DIM_MAX + 1]; + struct { + u_int32_t __flags[IPSET_DIM_MAX]; + u_int8_t dim; + u_int8_t flags; + } compat; + } u; +}; + +/* match and target infos */ +struct xt_set_info_match_v0 { + struct xt_set_info_v0 match_set; +}; + +struct xt_set_info_target_v0 { + struct xt_set_info_v0 add_set; + struct xt_set_info_v0 del_set; +}; + +/* Revision 1: current interface to netfilter/iptables */ + +struct xt_set_info { + ip_set_id_t index; + u_int8_t dim; + u_int8_t flags; +}; + +/* match and target infos */ +struct xt_set_info_match { + struct xt_set_info match_set; +}; + +struct xt_set_info_target { + struct xt_set_info add_set; + struct xt_set_info del_set; +}; + +#endif /*_XT_SET_H*/ diff --git a/include/linux/netfilter_ipv4/ip_set.h b/include/linux/netfilter_ipv4/ip_set.h deleted file mode 100644 index 92a746e9..00000000 --- a/include/linux/netfilter_ipv4/ip_set.h +++ /dev/null @@ -1,498 +0,0 @@ -#ifndef _IP_SET_H -#define _IP_SET_H - -/* Copyright (C) 2000-2002 Joakim Axelsson - * Patrick Schaaf - * Martin Josefsson - * Copyright (C) 2003-2004 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#if 0 -#define IP_SET_DEBUG -#endif - -/* - * A sockopt of such quality has hardly ever been seen before on the open - * market! This little beauty, hardly ever used: above 64, so it's - * traditionally used for firewalling, not touched (even once!) by the - * 2.0, 2.2 and 2.4 kernels! - * - * Comes with its own certificate of authenticity, valid anywhere in the - * Free world! - * - * Rusty, 19.4.2000 - */ -#define SO_IP_SET 83 - -/* - * Heavily modify by Joakim Axelsson 08.03.2002 - * - Made it more modulebased - * - * Additional heavy modifications by Jozsef Kadlecsik 22.02.2004 - * - bindings added - * - in order to "deal with" backward compatibility, renamed to ipset - */ - -/* - * Used so that the kernel module and ipset-binary can match their versions - */ -#define IP_SET_PROTOCOL_VERSION 2 - -#define IP_SET_MAXNAMELEN 32 /* set names and set typenames */ - -/* Lets work with our own typedef for representing an IP address. - * We hope to make the code more portable, possibly to IPv6... - * - * The representation works in HOST byte order, because most set types - * will perform arithmetic operations and compare operations. - * - * For now the type is an uint32_t. - * - * Make sure to ONLY use the functions when translating and parsing - * in order to keep the host byte order and make it more portable: - * parse_ip() - * parse_mask() - * parse_ipandmask() - * ip_tostring() - * (Joakim: where are they???) - */ - -typedef uint32_t ip_set_ip_t; - -/* Sets are identified by an id in kernel space. Tweak with ip_set_id_t - * and IP_SET_INVALID_ID if you want to increase the max number of sets. - */ -typedef uint16_t ip_set_id_t; - -#define IP_SET_INVALID_ID 65535 - -/* How deep we follow bindings */ -#define IP_SET_MAX_BINDINGS 6 - -/* - * Option flags for kernel operations (ipt_set_info) - */ -#define IPSET_SRC 0x01 /* Source match/add */ -#define IPSET_DST 0x02 /* Destination match/add */ -#define IPSET_MATCH_INV 0x04 /* Inverse matching */ - -/* - * Set features - */ -#define IPSET_TYPE_IP 0x01 /* IP address type of set */ -#define IPSET_TYPE_PORT 0x02 /* Port type of set */ -#define IPSET_DATA_SINGLE 0x04 /* Single data storage */ -#define IPSET_DATA_DOUBLE 0x08 /* Double data storage */ - -/* Reserved keywords */ -#define IPSET_TOKEN_DEFAULT ":default:" -#define IPSET_TOKEN_ALL ":all:" - -/* SO_IP_SET operation constants, and their request struct types. - * - * Operation ids: - * 0-99: commands with version checking - * 100-199: add/del/test/bind/unbind - * 200-299: list, save, restore - */ - -/* Single shot operations: - * version, create, destroy, flush, rename and swap - * - * Sets are identified by name. - */ - -#define IP_SET_REQ_STD \ - unsigned op; \ - unsigned version; \ - char name[IP_SET_MAXNAMELEN] - -#define IP_SET_OP_CREATE 0x00000001 /* Create a new (empty) set */ -struct ip_set_req_create { - IP_SET_REQ_STD; - char typename[IP_SET_MAXNAMELEN]; -}; - -#define IP_SET_OP_DESTROY 0x00000002 /* Remove a (empty) set */ -struct ip_set_req_std { - IP_SET_REQ_STD; -}; - -#define IP_SET_OP_FLUSH 0x00000003 /* Remove all IPs in a set */ -/* Uses ip_set_req_std */ - -#define IP_SET_OP_RENAME 0x00000004 /* Rename a set */ -/* Uses ip_set_req_create */ - -#define IP_SET_OP_SWAP 0x00000005 /* Swap two sets */ -/* Uses ip_set_req_create */ - -union ip_set_name_index { - char name[IP_SET_MAXNAMELEN]; - ip_set_id_t index; -}; - -#define IP_SET_OP_GET_BYNAME 0x00000006 /* Get set index by name */ -struct ip_set_req_get_set { - unsigned op; - unsigned version; - union ip_set_name_index set; -}; - -#define IP_SET_OP_GET_BYINDEX 0x00000007 /* Get set name by index */ -/* Uses ip_set_req_get_set */ - -#define IP_SET_OP_VERSION 0x00000100 /* Ask kernel version */ -struct ip_set_req_version { - unsigned op; - unsigned version; -}; - -/* Double shots operations: - * add, del, test, bind and unbind. - * - * First we query the kernel to get the index and type of the target set, - * then issue the command. Validity of IP is checked in kernel in order - * to minimalize sockopt operations. - */ - -/* Get minimal set data for add/del/test/bind/unbind IP */ -#define IP_SET_OP_ADT_GET 0x00000010 /* Get set and type */ -struct ip_set_req_adt_get { - unsigned op; - unsigned version; - union ip_set_name_index set; - char typename[IP_SET_MAXNAMELEN]; -}; - -#define IP_SET_REQ_BYINDEX \ - unsigned op; \ - ip_set_id_t index; - -struct ip_set_req_adt { - IP_SET_REQ_BYINDEX; -}; - -#define IP_SET_OP_ADD_IP 0x00000101 /* Add an IP to a set */ -/* Uses ip_set_req_adt, with type specific addage */ - -#define IP_SET_OP_DEL_IP 0x00000102 /* Remove an IP from a set */ -/* Uses ip_set_req_adt, with type specific addage */ - -#define IP_SET_OP_TEST_IP 0x00000103 /* Test an IP in a set */ -/* Uses ip_set_req_adt, with type specific addage */ - -#define IP_SET_OP_BIND_SET 0x00000104 /* Bind an IP to a set */ -/* Uses ip_set_req_bind, with type specific addage */ -struct ip_set_req_bind { - IP_SET_REQ_BYINDEX; - char binding[IP_SET_MAXNAMELEN]; -}; - -#define IP_SET_OP_UNBIND_SET 0x00000105 /* Unbind an IP from a set */ -/* Uses ip_set_req_bind, with type speficic addage - * index = 0 means unbinding for all sets */ - -#define IP_SET_OP_TEST_BIND_SET 0x00000106 /* Test binding an IP to a set */ -/* Uses ip_set_req_bind, with type specific addage */ - -/* Multiple shots operations: list, save, restore. - * - * - check kernel version and query the max number of sets - * - get the basic information on all sets - * and size required for the next step - * - get actual set data: header, data, bindings - */ - -/* Get max_sets and the index of a queried set - */ -#define IP_SET_OP_MAX_SETS 0x00000020 -struct ip_set_req_max_sets { - unsigned op; - unsigned version; - ip_set_id_t max_sets; /* max_sets */ - ip_set_id_t sets; /* real number of sets */ - union ip_set_name_index set; /* index of set if name used */ -}; - -/* Get the id and name of the sets plus size for next step */ -#define IP_SET_OP_LIST_SIZE 0x00000201 -#define IP_SET_OP_SAVE_SIZE 0x00000202 -struct ip_set_req_setnames { - unsigned op; - ip_set_id_t index; /* set to list/save */ - size_t size; /* size to get setdata/bindings */ - /* followed by sets number of struct ip_set_name_list */ -}; - -struct ip_set_name_list { - char name[IP_SET_MAXNAMELEN]; - char typename[IP_SET_MAXNAMELEN]; - ip_set_id_t index; - ip_set_id_t id; -}; - -/* The actual list operation */ -#define IP_SET_OP_LIST 0x00000203 -struct ip_set_req_list { - IP_SET_REQ_BYINDEX; - /* sets number of struct ip_set_list in reply */ -}; - -struct ip_set_list { - ip_set_id_t index; - ip_set_id_t binding; - u_int32_t ref; - size_t header_size; /* Set header data of header_size */ - size_t members_size; /* Set members data of members_size */ - size_t bindings_size; /* Set bindings data of bindings_size */ -}; - -struct ip_set_hash_list { - ip_set_ip_t ip; - ip_set_id_t binding; -}; - -/* The save operation */ -#define IP_SET_OP_SAVE 0x00000204 -/* Uses ip_set_req_list, in the reply replaced by - * sets number of struct ip_set_save plus a marker - * ip_set_save followed by ip_set_hash_save structures. - */ -struct ip_set_save { - ip_set_id_t index; - ip_set_id_t binding; - size_t header_size; /* Set header data of header_size */ - size_t members_size; /* Set members data of members_size */ -}; - -/* At restoring, ip == 0 means default binding for the given set: */ -struct ip_set_hash_save { - ip_set_ip_t ip; - ip_set_id_t id; - ip_set_id_t binding; -}; - -/* The restore operation */ -#define IP_SET_OP_RESTORE 0x00000205 -/* Uses ip_set_req_setnames followed by ip_set_restore structures - * plus a marker ip_set_restore, followed by ip_set_hash_save - * structures. - */ -struct ip_set_restore { - char name[IP_SET_MAXNAMELEN]; - char typename[IP_SET_MAXNAMELEN]; - ip_set_id_t index; - size_t header_size; /* Create data of header_size */ - size_t members_size; /* Set members data of members_size */ -}; - -static inline int bitmap_bytes(ip_set_ip_t a, ip_set_ip_t b) -{ - return 4 * ((((b - a + 8) / 8) + 3) / 4); -} - -#ifdef __KERNEL__ - -#define ip_set_printk(format, args...) \ - do { \ - printk("%s: %s: ", __FILE__, __FUNCTION__); \ - printk(format "\n" , ## args); \ - } while (0) - -#if defined(IP_SET_DEBUG) -#define DP(format, args...) \ - do { \ - printk("%s: %s (DBG): ", __FILE__, __FUNCTION__);\ - printk(format "\n" , ## args); \ - } while (0) -#define IP_SET_ASSERT(x) \ - do { \ - if (!(x)) \ - printk("IP_SET_ASSERT: %s:%i(%s)\n", \ - __FILE__, __LINE__, __FUNCTION__); \ - } while (0) -#else -#define DP(format, args...) -#define IP_SET_ASSERT(x) -#endif - -struct ip_set; - -/* - * The ip_set_type definition - one per set type, e.g. "ipmap". - * - * Each individual set has a pointer, set->type, going to one - * of these structures. Function pointers inside the structure implement - * the real behaviour of the sets. - * - * If not mentioned differently, the implementation behind the function - * pointers of a set_type, is expected to return 0 if ok, and a negative - * errno (e.g. -EINVAL) on error. - */ -struct ip_set_type { - struct list_head list; /* next in list of set types */ - - /* test for IP in set (kernel: iptables -m set src|dst) - * return 0 if not in set, 1 if in set. - */ - int (*testip_kernel) (struct ip_set *set, - const struct sk_buff * skb, - ip_set_ip_t *ip, - const u_int32_t *flags, - unsigned char index); - - /* test for IP in set (userspace: ipset -T set IP) - * return 0 if not in set, 1 if in set. - */ - int (*testip) (struct ip_set *set, - const void *data, size_t size, - ip_set_ip_t *ip); - - /* - * Size of the data structure passed by when - * adding/deletin/testing an entry. - */ - size_t reqsize; - - /* Add IP into set (userspace: ipset -A set IP) - * Return -EEXIST if the address is already in the set, - * and -ERANGE if the address lies outside the set bounds. - * If the address was not already in the set, 0 is returned. - */ - int (*addip) (struct ip_set *set, - const void *data, size_t size, - ip_set_ip_t *ip); - - /* Add IP into set (kernel: iptables ... -j SET set src|dst) - * Return -EEXIST if the address is already in the set, - * and -ERANGE if the address lies outside the set bounds. - * If the address was not already in the set, 0 is returned. - */ - int (*addip_kernel) (struct ip_set *set, - const struct sk_buff * skb, - ip_set_ip_t *ip, - const u_int32_t *flags, - unsigned char index); - - /* remove IP from set (userspace: ipset -D set --entry x) - * Return -EEXIST if the address is NOT in the set, - * and -ERANGE if the address lies outside the set bounds. - * If the address really was in the set, 0 is returned. - */ - int (*delip) (struct ip_set *set, - const void *data, size_t size, - ip_set_ip_t *ip); - - /* remove IP from set (kernel: iptables ... -j SET --entry x) - * Return -EEXIST if the address is NOT in the set, - * and -ERANGE if the address lies outside the set bounds. - * If the address really was in the set, 0 is returned. - */ - int (*delip_kernel) (struct ip_set *set, - const struct sk_buff * skb, - ip_set_ip_t *ip, - const u_int32_t *flags, - unsigned char index); - - /* new set creation - allocated type specific items - */ - int (*create) (struct ip_set *set, - const void *data, size_t size); - - /* retry the operation after successfully tweaking the set - */ - int (*retry) (struct ip_set *set); - - /* set destruction - free type specific items - * There is no return value. - * Can be called only when child sets are destroyed. - */ - void (*destroy) (struct ip_set *set); - - /* set flushing - reset all bits in the set, or something similar. - * There is no return value. - */ - void (*flush) (struct ip_set *set); - - /* Listing: size needed for header - */ - size_t header_size; - - /* Listing: Get the header - * - * Fill in the information in "data". - * This function is always run after list_header_size() under a - * writelock on the set. Therefor is the length of "data" always - * correct. - */ - void (*list_header) (const struct ip_set *set, - void *data); - - /* Listing: Get the size for the set members - */ - int (*list_members_size) (const struct ip_set *set); - - /* Listing: Get the set members - * - * Fill in the information in "data". - * This function is always run after list_member_size() under a - * writelock on the set. Therefor is the length of "data" always - * correct. - */ - void (*list_members) (const struct ip_set *set, - void *data); - - char typename[IP_SET_MAXNAMELEN]; - unsigned char features; - int protocol_version; - - /* Set this to THIS_MODULE if you are a module, otherwise NULL */ - struct module *me; -}; - -extern int ip_set_register_set_type(struct ip_set_type *set_type); -extern void ip_set_unregister_set_type(struct ip_set_type *set_type); - -/* A generic ipset */ -struct ip_set { - char name[IP_SET_MAXNAMELEN]; /* the name of the set */ - rwlock_t lock; /* lock for concurrency control */ - ip_set_id_t id; /* set id for swapping */ - ip_set_id_t binding; /* default binding for the set */ - atomic_t ref; /* in kernel and in hash references */ - struct ip_set_type *type; /* the set types */ - void *data; /* pooltype specific data */ -}; - -/* Structure to bind set elements to sets */ -struct ip_set_hash { - struct list_head list; /* list of clashing entries in hash */ - ip_set_ip_t ip; /* ip from set */ - ip_set_id_t id; /* set id */ - ip_set_id_t binding; /* set we bind the element to */ -}; - -/* register and unregister set references */ -extern ip_set_id_t ip_set_get_byname(const char name[IP_SET_MAXNAMELEN]); -extern ip_set_id_t ip_set_get_byindex(ip_set_id_t id); -extern void ip_set_put(ip_set_id_t id); - -/* API for iptables set match, and SET target */ -extern void ip_set_addip_kernel(ip_set_id_t id, - const struct sk_buff *skb, - const u_int32_t *flags); -extern void ip_set_delip_kernel(ip_set_id_t id, - const struct sk_buff *skb, - const u_int32_t *flags); -extern int ip_set_testip_kernel(ip_set_id_t id, - const struct sk_buff *skb, - const u_int32_t *flags); - -#endif /* __KERNEL__ */ - -#endif /*_IP_SET_H*/ diff --git a/include/linux/netfilter_ipv4/ipt_set.h b/include/linux/netfilter_ipv4/ipt_set.h deleted file mode 100644 index 2a18b93d..00000000 --- a/include/linux/netfilter_ipv4/ipt_set.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _IPT_SET_H -#define _IPT_SET_H - -#include - -struct ipt_set_info { - ip_set_id_t index; - u_int32_t flags[IP_SET_MAX_BINDINGS + 1]; -}; - -/* match info */ -struct ipt_set_info_match { - struct ipt_set_info match_set; -}; - -struct ipt_set_info_target { - struct ipt_set_info add_set; - struct ipt_set_info del_set; -}; - -#endif /*_IPT_SET_H*/ -- cgit v1.2.3 From dd2bbe0b614ad60fb2e267863471836aae424425 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Thu, 24 Jun 2010 21:13:47 +0200 Subject: libxt_hashlimit: always print burst value iptables -L lists the burst value, and so should iptables -S. I was certainly surprised to see it gone even when explicitly specifying --hashlimit-burst 5 on the command line. Signed-off-by: Jan Engelhardt --- extensions/libxt_hashlimit.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/extensions/libxt_hashlimit.c b/extensions/libxt_hashlimit.c index a8fe588f..7442dfcf 100644 --- a/extensions/libxt_hashlimit.c +++ b/extensions/libxt_hashlimit.c @@ -591,8 +591,7 @@ static void hashlimit_save(const void *ip, const struct xt_entry_match *match) const struct xt_hashlimit_info *r = (const void *)match->data; fputs("--hashlimit ", stdout); print_rate(r->cfg.avg); - if (r->cfg.burst != XT_HASHLIMIT_BURST) - printf("--hashlimit-burst %u ", r->cfg.burst); + printf("--hashlimit-burst %u ", r->cfg.burst); fputs("--hashlimit-mode ", stdout); print_mode(r->cfg.mode, ','); @@ -617,8 +616,7 @@ hashlimit_mt_save(const struct xt_hashlimit_mtinfo1 *info, unsigned int dmask) else fputs("--hashlimit-upto ", stdout); print_rate(info->cfg.avg); - if (info->cfg.burst != XT_HASHLIMIT_BURST) - printf("--hashlimit-burst %u ", info->cfg.burst); + printf("--hashlimit-burst %u ", info->cfg.burst); if (info->cfg.mode & (XT_HASHLIMIT_HASH_SIP | XT_HASHLIMIT_HASH_SPT | XT_HASHLIMIT_HASH_DIP | XT_HASHLIMIT_HASH_DPT)) { -- cgit v1.2.3 From 76f7a230e4182ab2b64a68c9d84437035d925f3b Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Thu, 24 Jun 2010 21:23:44 +0200 Subject: libxt_conntrack: do print netmask References: http://bugzilla.netfilter.org/show_bug.cgi?id=659 Signed-off-by: Jan Engelhardt --- extensions/libxt_conntrack.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/extensions/libxt_conntrack.c b/extensions/libxt_conntrack.c index e8225e6d..5557d3ea 100644 --- a/extensions/libxt_conntrack.c +++ b/extensions/libxt_conntrack.c @@ -842,9 +842,13 @@ conntrack_dump_addr(const union nf_inet_addr *addr, return; } if (numeric) - printf("%s ", xtables_ipaddr_to_numeric(&addr->in)); + printf("%s%s ", + xtables_ipaddr_to_numeric(&addr->in), + xtables_ipmask_to_numeric(&mask->in)); else - printf("%s ", xtables_ipaddr_to_anyname(&addr->in)); + printf("%s%s ", + xtables_ipaddr_to_anyname(&addr->in), + xtables_ipmask_to_numeric(&mask->in)); } else if (family == NFPROTO_IPV6) { if (!numeric && addr->ip6[0] == 0 && addr->ip6[1] == 0 && addr->ip6[2] == 0 && addr->ip6[3] == 0) { @@ -852,9 +856,13 @@ conntrack_dump_addr(const union nf_inet_addr *addr, return; } if (numeric) - printf("%s ", xtables_ip6addr_to_numeric(&addr->in6)); + printf("%s%s ", + xtables_ip6addr_to_numeric(&addr->in6), + xtables_ip6mask_to_numeric(&mask->in6)); else - printf("%s ", xtables_ip6addr_to_anyname(&addr->in6)); + printf("%s%s ", + xtables_ip6addr_to_anyname(&addr->in6), + xtables_ip6mask_to_numeric(&mask->in6)); } } -- cgit v1.2.3 From b1c768168ef1f79c4bdd02f6e681e6e1fbb8d533 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Fri, 2 Jul 2010 09:36:37 +0200 Subject: extensions: libxt_rateest: fix typo in the man page There were a few typos in some options in the rateest match section of the man page: --rateest1-bps should be --rateest-bps1 and so on. Signed-off-by: Luciano Coelho Signed-off-by: Patrick McHardy --- extensions/libxt_rateest.man | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/extensions/libxt_rateest.man b/extensions/libxt_rateest.man index 24c0673b..de064af3 100644 --- a/extensions/libxt_rateest.man +++ b/extensions/libxt_rateest.man @@ -11,14 +11,14 @@ Name of the second rate estimator (if difference is to be calculated). \fB\-\-rateest\-delta\fP Compare difference(s) to given rate(s) .TP -\fB\-\-rateest1\-bps\fP \fIvalue\fP +\fB\-\-rateest\-bps1\fP \fIvalue\fP .TP -\fB\-\-rateest2\-bps\fP \fIvalue\fP +\fB\-\-rateest\-bps2\fP \fIvalue\fP Compare bytes per second. .TP -\fB\-\-rateest1\-pps\fP \fIvalue\fP +\fB\-\-rateest\-pps1\fP \fIvalue\fP .TP -\fB\-\-rateest2\-pps\fP \fIvalue\fP +\fB\-\-rateest\-pps2\fP \fIvalue\fP Compare packets per second. .TP [\fB!\fP] \fB\-\-rateest\-lt\fP -- cgit v1.2.3 From e4540fcb86c2d7f4cdf51c49872847a03a11b433 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Fri, 2 Jul 2010 09:57:09 +0200 Subject: extensions: libxt_quota.c: Support option negation The xt_quota_info flags should be set properly for the --quota option negation support. Signed-off-by: Samuel Ortiz Signed-off-by: Patrick McHardy --- extensions/libxt_quota.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/extensions/libxt_quota.c b/extensions/libxt_quota.c index 69d27460..bdfc92a8 100644 --- a/extensions/libxt_quota.c +++ b/extensions/libxt_quota.c @@ -65,6 +65,10 @@ quota_parse(int c, char **argv, int invert, unsigned int *flags, if (!parse_quota(optarg, &info->quota)) xtables_error(PARAMETER_PROBLEM, "bad quota: '%s'", optarg); + + if (invert) + info->flags |= XT_QUOTA_INVERT; + break; default: -- cgit v1.2.3 From ce06c99ee107102a7168493b55970b53380ebbb6 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Fri, 2 Jul 2010 12:19:18 +0200 Subject: xt_quota: also document negation Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- extensions/libxt_quota.c | 2 +- extensions/libxt_quota.man | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/extensions/libxt_quota.c b/extensions/libxt_quota.c index bdfc92a8..ac7c686e 100644 --- a/extensions/libxt_quota.c +++ b/extensions/libxt_quota.c @@ -19,7 +19,7 @@ static const struct option quota_opts[] = { static void quota_help(void) { printf("quota match options:\n" - " --quota quota quota (bytes)\n"); + "[!] --quota quota quota (bytes)\n"); } static void diff --git a/extensions/libxt_quota.man b/extensions/libxt_quota.man index f8bf77b5..8d9e18b8 100644 --- a/extensions/libxt_quota.man +++ b/extensions/libxt_quota.man @@ -1,6 +1,5 @@ Implements network quotas by decrementing a byte counter with each packet. .TP -\fB\-\-quota\fP \fIbytes\fP +[\fB!\fP] \fB\-\-quota\fP \fIbytes\fP The quota in bytes. -.P -- cgit v1.2.3 From b4fa7222923bc10476b8753f358e871f461eb2db Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 15 Jul 2010 18:09:54 +0200 Subject: extensions: libxt_rateest: fix bps options for iptables-save The output generated by the libxt_rateest extension for bps matches was wrong and could not be restored properly. This patch fixes this problem by using the correct options in the right order when saving the table. Signed-off-by: Luciano Coelho Signed-off-by: Patrick McHardy --- extensions/libxt_rateest.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/extensions/libxt_rateest.c b/extensions/libxt_rateest.c index 62100f4b..ad0884e7 100644 --- a/extensions/libxt_rateest.c +++ b/extensions/libxt_rateest.c @@ -419,9 +419,11 @@ rateest_save(const void *ip, const struct xt_entry_match *match) } else { printf("--rateest %s ", info->name1); if (info->flags & XT_RATEEST_MATCH_BPS) { - printf("--rateest-bps "); - rateest_print_mode(info, "--rateest-"); + printf("--rateest-bps1 "); + rateest_print_rate(info->bps1, 0); + printf("--rateest-bps2 "); rateest_print_rate(info->bps2, 0); + rateest_print_mode(info, "--rateest-"); } if (info->flags & XT_RATEEST_MATCH_PPS) { printf("--rateest-pps "); -- cgit v1.2.3