diff options
33 files changed, 952 insertions, 1050 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/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 <gozem@linux.nu> - * Patrick Schaaf <bof@bof.de> - * Martin Josefsson <gandalf@wlug.westbo.se> - * Copyright (C) 2003-2004 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> - * - * 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 <stdio.h> -#include <netdb.h> -#include <string.h> -#include <stdlib.h> -#include <getopt.h> -#include <ctype.h> - -#include <xtables.h> -#include <linux/netfilter_ipv4/ip_set.h> -#include <linux/netfilter_ipv4/ipt_set.h> -#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 <set> <flags> */ - parse_target(argv, invert, flags, - &myinfo->add_set, "add-set"); - break; - case '2': /* --del-set <set>[:<flags>] <flags> */ - 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.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 <gozem@linux.nu> - * Patrick Schaaf <bof@bof.de> - * Martin Josefsson <gandalf@wlug.westbo.se> - * Copyright (C) 2003-2004 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> - * - * 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 <stdio.h> -#include <netdb.h> -#include <string.h> -#include <stdlib.h> -#include <getopt.h> -#include <ctype.h> -#include <errno.h> - -#include <xtables.h> -#include <linux/netfilter_ipv4/ipt_set.h> -#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 <set> <flag>[,<flag> */ - 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 <unistd.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <errno.h> - -#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/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 <gozem@linux.nu> + * Patrick Schaaf <bof@bof.de> + * Martin Josefsson <gandalf@wlug.westbo.se> + * Copyright (C) 2003-2010 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> + * + * 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 <stdio.h> +#include <netdb.h> +#include <string.h> +#include <stdlib.h> +#include <getopt.h> +#include <ctype.h> + +#include <xtables.h> +#include <linux/netfilter/xt_set.h> +#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 <set> <flags> */ + parse_target_v0(argv, invert, flags, + &myinfo->add_set, "add-set"); + break; + case '2': /* --del-set <set>[:<flags>] <flags> */ + 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 <set> <flags> */ + parse_target(argv, invert, flags, + &myinfo->add_set, "add-set"); + break; + case '2': /* --del-set <set>[:<flags>] <flags> */ + 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/libipt_SET.man b/extensions/libxt_SET.man index ea80c2a1..ea80c2a1 100644 --- a/extensions/libipt_SET.man +++ b/extensions/libxt_SET.man 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)); } } 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)) { diff --git a/extensions/libxt_quota.c b/extensions/libxt_quota.c index 69d27460..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 @@ -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: 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 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 "); 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 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 <gozem@linux.nu> + * Patrick Schaaf <bof@bof.de> + * Martin Josefsson <gandalf@wlug.westbo.se> + * Copyright (C) 2003-2010 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> + * + * 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 <stdio.h> +#include <netdb.h> +#include <string.h> +#include <stdlib.h> +#include <getopt.h> +#include <ctype.h> +#include <errno.h> + +#include <xtables.h> +#include <linux/netfilter/xt_set.h> +#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 <set> <flag>[,<flag> */ + 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 <set> <flag>[,<flag> */ + 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 <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <errno.h> + +#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/libipt_set.man b/extensions/libxt_set.man index aca1bfce..aca1bfce 100644 --- a/extensions/libipt_set.man +++ b/extensions/libxt_set.man 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 <linux/kernel.h> #include <linux/types.h> #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 <linux/types.h> - -/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> - * by Henrik Nordstrom <hno@marasystems.com> - * - * 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 <linux/netfilter/xt_connmark.h> #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 <linux/types.h> - -struct xt_mark_tginfo2 { - __u32 mark, mask; -}; +#include <linux/netfilter/xt_mark.h> #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 <linux/types.h> +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/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 <gozem@linux.nu> - * Patrick Schaaf <bof@bof.de> - * Martin Josefsson <gandalf@wlug.westbo.se> - * Copyright (C) 2003-2004 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> - * - * 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 <linux/netfilter_ipv4/ip_set.h> - -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*/ 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, 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-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..6c5d124c 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)) @@ -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-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)) { @@ -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)) @@ -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); } @@ -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") @@ -545,10 +537,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 +733,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 +818,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); |