Control: tags -1 - moreinfo On 3 February 2017 at 20:13, Niels Thykier <ni...@thykier.net> wrote: > > Without any additional information, it is hard for us to review this > request. The easiest for us is if you attach a source debdiff between > testing and unstable plus the change log to the request. >
I'm afraid the resulting debdiff resulted in something bigger than I expected at first. Anyway, find it attached. The cmd used to generate the debdiff was: % debdiff iptables_1.6.0+snapshot20161117-5.dsc iptables_1.6.1-1.dsc | filterdiff -i *.c -i *.patch -i *changelog -i *control > debdiff.diff The package has not been uploaded to unstable.
diff -Nru iptables-1.6.0+snapshot20161117/debian/changelog iptables-1.6.1/debian/changelog --- iptables-1.6.0+snapshot20161117/debian/changelog 2017-01-23 09:13:07.000000000 +0100 +++ iptables-1.6.1/debian/changelog 2017-02-10 08:54:30.000000000 +0100 @@ -1,3 +1,13 @@ +iptables (1.6.1-1) unstable; urgency=medium + + * [475b9a9] d/: add basic autopkgtests + * [f1f129d] New upstream version 1.6.1 + * [3464592] d/patches/: refresh 0103-lintian_allows_to.patch + * [def0a30] d/patches/: refresh 0104-lintian_hyphens.patch + * [3abd57d] d/patches/: refresh 0301-install_iptables_apply.patch + + -- Arturo Borrero Gonzalez <art...@debian.org> Fri, 10 Feb 2017 08:54:30 +0100 + iptables (1.6.0+snapshot20161117-5) unstable; urgency=medium [ Samuel Henrique ] diff -Nru iptables-1.6.0+snapshot20161117/debian/patches/0103-lintian_allows_to.patch iptables-1.6.1/debian/patches/0103-lintian_allows_to.patch --- iptables-1.6.0+snapshot20161117/debian/patches/0103-lintian_allows_to.patch 2016-11-22 14:58:50.000000000 +0100 +++ iptables-1.6.1/debian/patches/0103-lintian_allows_to.patch 2017-02-10 08:51:12.000000000 +0100 @@ -62,7 +62,7 @@ " 1 log only first one.\n" --- a/iptables/iptables.8.in +++ b/iptables/iptables.8.in -@@ -244,13 +244,13 @@ +@@ -245,13 +245,13 @@ This option has no effect in iptables and iptables-restore. If a rule using the \fB\-4\fP option is inserted with (and only with) ip6tables-restore, it will be silently ignored. Any other uses will throw an diff -Nru iptables-1.6.0+snapshot20161117/debian/patches/0104-lintian_hyphens.patch iptables-1.6.1/debian/patches/0104-lintian_hyphens.patch --- iptables-1.6.0+snapshot20161117/debian/patches/0104-lintian_hyphens.patch 2016-11-22 14:58:50.000000000 +0100 +++ iptables-1.6.1/debian/patches/0104-lintian_hyphens.patch 2017-02-10 08:51:37.000000000 +0100 @@ -52,9 +52,9 @@ mnemonics. --- a/extensions/libxt_bpf.man +++ b/extensions/libxt_bpf.man -@@ -4,7 +4,7 @@ +@@ -17,7 +17,7 @@ \fB\-\-bytecode\fP \fIcode\fP - Pass the BPF byte code format (described in the example below). + Pass the BPF byte code format as generated by the \fBnfbpf_compile\fP utility. .PP -The code format is similar to the output of the tcpdump -ddd command: one line +The code format is similar to the output of the tcpdump \-ddd command: one line diff -Nru iptables-1.6.0+snapshot20161117/debian/patches/0301-install_iptables_apply.patch iptables-1.6.1/debian/patches/0301-install_iptables_apply.patch --- iptables-1.6.0+snapshot20161117/debian/patches/0301-install_iptables_apply.patch 2016-11-22 14:58:50.000000000 +0100 +++ iptables-1.6.1/debian/patches/0301-install_iptables_apply.patch 2017-02-10 08:52:14.000000000 +0100 @@ -12,7 +12,7 @@ --- a/iptables/Makefile.am +++ b/iptables/Makefile.am -@@ -54,7 +54,10 @@ +@@ -58,7 +58,10 @@ endif man_MANS = iptables.8 iptables-restore.8 iptables-save.8 \ iptables-xml.1 ip6tables.8 ip6tables-restore.8 \ @@ -24,7 +24,7 @@ CLEANFILES = iptables.8 \ xtables-config-parser.c xtables-config-syntax.c -@@ -86,3 +89,4 @@ +@@ -92,3 +95,4 @@ for i in ${v4_sbin_links}; do ${LN_S} -f xtables-multi "${DESTDIR}${sbindir}/$$i"; done; for i in ${v6_sbin_links}; do ${LN_S} -f xtables-multi "${DESTDIR}${sbindir}/$$i"; done; for i in ${x_sbin_links}; do ${LN_S} -f xtables-compat-multi "${DESTDIR}${sbindir}/$$i"; done; diff -Nru iptables-1.6.0+snapshot20161117/debian/tests/control iptables-1.6.1/debian/tests/control --- iptables-1.6.0+snapshot20161117/debian/tests/control 1970-01-01 01:00:00.000000000 +0100 +++ iptables-1.6.1/debian/tests/control 2017-02-10 08:45:29.000000000 +0100 @@ -0,0 +1,72 @@ +Test-Command: iptables -h +Depends: @ +Restrictions: needs-root, isolation-container + +Test-Command: ip6tables -h +Depends: @ +Restrictions: needs-root, isolation-container + +Test-Command: iptables-save +Depends: @ +Restrictions: needs-root, isolation-container + +Test-Command: ip6tables-save +Depends: @ +Restrictions: needs-root, isolation-container + +Test-Command: iptables-restore -h +Depends: @ +Restrictions: needs-root, isolation-container + +Test-Command: ip6tables-restore -h +Depends: @ +Restrictions: needs-root, isolation-container + +Test-Command: iptables-compat -h +Depends: @ +Restrictions: needs-root, isolation-container + +Test-Command: ip6tables-compat -h +Depends: @ +Restrictions: needs-root, isolation-container + +Test-Command: iptables-compat-save +Depends: @ +Restrictions: needs-root, isolation-container + +Test-Command: ip6tables-compat-save +Depends: @ +Restrictions: needs-root, isolation-container + +Test-Command: iptables-compat-restore -h +Depends: @ +Restrictions: needs-root, isolation-container + +Test-Command: ip6tables-compat-restore -h +Depends: @ +Restrictions: needs-root, isolation-container + +Test-Command: arptables-compat -h +Depends: @ +Restrictions: needs-root, isolation-container + +Test-Command: ebtables-compat -h +Depends: @ +Restrictions: needs-root, isolation-container + +Test-Command: iptables-translate -h +Depends: @ +Restrictions: needs-root, isolation-container + +Test-Command: iptables-restore-translate -h +Depends: @ +Restrictions: needs-root, isolation-container + +Test-Command: ip6tables-translate -h +Depends: @ +Restrictions: needs-root, isolation-container + +Test-Command: ip6tables-restore-translate -h +Depends: @ +Restrictions: needs-root, isolation-container + diff -Nru iptables-1.6.0+snapshot20161117/extensions/libip6t_ah.c iptables-1.6.1/extensions/libip6t_ah.c --- iptables-1.6.0+snapshot20161117/extensions/libip6t_ah.c 2016-11-17 06:25:02.000000000 +0100 +++ iptables-1.6.1/extensions/libip6t_ah.c 2017-01-26 17:11:58.000000000 +0100 @@ -152,8 +152,13 @@ space = " "; } - if (ahinfo->hdrres != 0) + if (ahinfo->hdrres != 0) { xt_xlate_add(xl, "%sah reserved %u", space, ahinfo->hdrres); + space = " "; + } + + if (!space[0]) /* plain '-m ah' */ + xt_xlate_add(xl, "meta l4proto ah"); return 1; } diff -Nru iptables-1.6.0+snapshot20161117/extensions/libip6t_LOG.c iptables-1.6.1/extensions/libip6t_LOG.c --- iptables-1.6.0+snapshot20161117/extensions/libip6t_LOG.c 2016-11-17 06:25:02.000000000 +0100 +++ iptables-1.6.1/extensions/libip6t_LOG.c 2017-01-26 17:11:58.000000000 +0100 @@ -189,22 +189,44 @@ (const struct ip6t_log_info *)params->target->data; unsigned int i = 0; - xt_xlate_add(xl, "log "); + xt_xlate_add(xl, "log"); if (strcmp(loginfo->prefix, "") != 0) { if (params->escape_quotes) - xt_xlate_add(xl, "prefix \\\"%s\\\" ", loginfo->prefix); + xt_xlate_add(xl, " prefix \\\"%s\\\"", loginfo->prefix); else - xt_xlate_add(xl, "prefix \"%s\" ", loginfo->prefix); + xt_xlate_add(xl, " prefix \"%s\"", loginfo->prefix); } for (i = 0; i < ARRAY_SIZE(ip6t_log_xlate_names); ++i) if (loginfo->level == ip6t_log_xlate_names[i].level && loginfo->level != LOG_DEFAULT_LEVEL) { - xt_xlate_add(xl, "level %s", + xt_xlate_add(xl, " level %s", ip6t_log_xlate_names[i].name); break; } + if ((loginfo->logflags & IP6T_LOG_MASK) == IP6T_LOG_MASK) { + xt_xlate_add(xl, " flags all"); + } else { + if (loginfo->logflags & (IP6T_LOG_TCPSEQ | IP6T_LOG_TCPOPT)) { + const char *delim = " "; + + xt_xlate_add(xl, " flags tcp"); + if (loginfo->logflags & IP6T_LOG_TCPSEQ) { + xt_xlate_add(xl, " sequence"); + delim = ","; + } + if (loginfo->logflags & IP6T_LOG_TCPOPT) + xt_xlate_add(xl, "%soptions", delim); + } + if (loginfo->logflags & IP6T_LOG_IPOPT) + xt_xlate_add(xl, " flags ip options"); + if (loginfo->logflags & IP6T_LOG_UID) + xt_xlate_add(xl, " flags skuid"); + if (loginfo->logflags & IP6T_LOG_MACDECODE) + xt_xlate_add(xl, " flags ether"); + } + return 1; } static struct xtables_target log_tg6_reg = { diff -Nru iptables-1.6.0+snapshot20161117/extensions/libipt_LOG.c iptables-1.6.1/extensions/libipt_LOG.c --- iptables-1.6.0+snapshot20161117/extensions/libipt_LOG.c 2016-11-17 06:25:02.000000000 +0100 +++ iptables-1.6.1/extensions/libipt_LOG.c 2017-01-26 17:11:58.000000000 +0100 @@ -189,22 +189,44 @@ (const struct ipt_log_info *)params->target->data; unsigned int i = 0; - xt_xlate_add(xl, "log "); + xt_xlate_add(xl, "log"); if (strcmp(loginfo->prefix, "") != 0) { if (params->escape_quotes) - xt_xlate_add(xl, "prefix \\\"%s\\\" ", loginfo->prefix); + xt_xlate_add(xl, " prefix \\\"%s\\\"", loginfo->prefix); else - xt_xlate_add(xl, "prefix \"%s\" ", loginfo->prefix); + xt_xlate_add(xl, " prefix \"%s\"", loginfo->prefix); } for (i = 0; i < ARRAY_SIZE(ipt_log_xlate_names); ++i) if (loginfo->level != LOG_DEFAULT_LEVEL && loginfo->level == ipt_log_xlate_names[i].level) { - xt_xlate_add(xl, "level %s ", + xt_xlate_add(xl, " level %s", ipt_log_xlate_names[i].name); break; } + if ((loginfo->logflags & IPT_LOG_MASK) == IPT_LOG_MASK) { + xt_xlate_add(xl, " flags all"); + } else { + if (loginfo->logflags & (IPT_LOG_TCPSEQ | IPT_LOG_TCPOPT)) { + const char *delim = " "; + + xt_xlate_add(xl, " flags tcp"); + if (loginfo->logflags & IPT_LOG_TCPSEQ) { + xt_xlate_add(xl, " sequence"); + delim = ","; + } + if (loginfo->logflags & IPT_LOG_TCPOPT) + xt_xlate_add(xl, "%soptions", delim); + } + if (loginfo->logflags & IPT_LOG_IPOPT) + xt_xlate_add(xl, " flags ip options"); + if (loginfo->logflags & IPT_LOG_UID) + xt_xlate_add(xl, " flags skuid"); + if (loginfo->logflags & IPT_LOG_MACDECODE) + xt_xlate_add(xl, " flags ether"); + } + return 1; } static struct xtables_target log_tg_reg = { diff -Nru iptables-1.6.0+snapshot20161117/extensions/libxt_bpf.c iptables-1.6.1/extensions/libxt_bpf.c --- iptables-1.6.0+snapshot20161117/extensions/libxt_bpf.c 2016-11-17 06:25:02.000000000 +0100 +++ iptables-1.6.1/extensions/libxt_bpf.c 2017-01-26 17:11:58.000000000 +0100 @@ -16,11 +16,17 @@ #include <sys/types.h> #include <unistd.h> #include <xtables.h> +#include "config.h" + +#ifdef HAVE_LINUX_BPF_H +#include <linux/bpf.h> +#endif #define BCODE_FILE_MAX_LEN_B 1024 enum { O_BCODE_STDIN = 0, + O_OBJ_PINNED = 1, }; static void bpf_help(void) @@ -28,7 +34,16 @@ printf( "bpf match options:\n" "--bytecode <program> : a bpf program as generated by\n" -" `nfbpf_compiler RAW <filter>`\n"); +" $(nfbpf_compile RAW '<filter>')\n"); +} + +static void bpf_help_v1(void) +{ + printf( +"bpf match options:\n" +"--bytecode <program> : a bpf program as generated by\n" +" $(nfbpf_compile RAW '<filter>')\n" +"--object-pinned <bpf object> : a path to a pinned BPF object in bpf fs\n"); } static const struct xt_option_entry bpf_opts[] = { @@ -36,23 +51,47 @@ XTOPT_TABLEEND, }; -static void bpf_parse_string(struct xt_option_call *cb, const char *bpf_program, - const char separator) +static const struct xt_option_entry bpf_opts_v1[] = { + {.name = "bytecode", .id = O_BCODE_STDIN, .type = XTTYPE_STRING}, + {.name = "object-pinned" , .id = O_OBJ_PINNED, .type = XTTYPE_STRING, + .flags = XTOPT_PUT, XTOPT_POINTER(struct xt_bpf_info_v1, path)}, + XTOPT_TABLEEND, +}; + +static int bpf_obj_get(const char *filepath) { - struct xt_bpf_info *bi = (void *) cb->data; +#if defined HAVE_LINUX_BPF_H && defined __NR_bpf + union bpf_attr attr; + + memset(&attr, 0, sizeof(attr)); + attr.pathname = (__u64) filepath; + + return syscall(__NR_bpf, BPF_OBJ_GET, &attr, sizeof(attr)); +#else + xtables_error(OTHER_PROBLEM, + "No bpf header, kernel headers too old?\n"); + return -EINVAL; +#endif +} + +static void bpf_parse_string(struct sock_filter *pc, __u16 *lenp, __u16 len_max, + const char *bpf_program) +{ + const char separator = ','; const char *token; char sp; int i; + __u16 len; /* parse head: length. */ - if (sscanf(bpf_program, "%hu%c", &bi->bpf_program_num_elem, &sp) != 2 || + if (sscanf(bpf_program, "%hu%c", &len, &sp) != 2 || sp != separator) xtables_error(PARAMETER_PROBLEM, "bpf: error parsing program length"); - if (!bi->bpf_program_num_elem) + if (!len) xtables_error(PARAMETER_PROBLEM, "bpf: illegal zero length program"); - if (bi->bpf_program_num_elem > XT_BPF_MAX_NUM_INSTR) + if (len > len_max) xtables_error(PARAMETER_PROBLEM, "bpf: number of instructions exceeds maximum"); @@ -60,62 +99,108 @@ i = 0; token = bpf_program; while ((token = strchr(token, separator)) && (++token)[0]) { - if (i >= bi->bpf_program_num_elem) + if (i >= len) xtables_error(PARAMETER_PROBLEM, "bpf: real program length exceeds" " the encoded length parameter"); if (sscanf(token, "%hu %hhu %hhu %u,", - &bi->bpf_program[i].code, - &bi->bpf_program[i].jt, - &bi->bpf_program[i].jf, - &bi->bpf_program[i].k) != 4) + &pc->code, &pc->jt, &pc->jf, &pc->k) != 4) xtables_error(PARAMETER_PROBLEM, "bpf: error at instr %d", i); i++; + pc++; } - if (i != bi->bpf_program_num_elem) + if (i != len) xtables_error(PARAMETER_PROBLEM, "bpf: parsed program length is less than the" " encoded length parameter"); + + *lenp = len; +} + +static void bpf_parse_obj_pinned(struct xt_bpf_info_v1 *bi, + const char *filepath) +{ + bi->fd = bpf_obj_get(filepath); + if (bi->fd < 0) + xtables_error(PARAMETER_PROBLEM, + "bpf: failed to get bpf object"); + + /* Cannot close bi->fd explicitly. Rely on exit */ + if (fcntl(bi->fd, F_SETFD, FD_CLOEXEC) == -1) { + xtables_error(OTHER_PROBLEM, + "Could not set close on exec: %s\n", + strerror(errno)); + } } static void bpf_parse(struct xt_option_call *cb) { + struct xt_bpf_info *bi = (void *) cb->data; + xtables_option_parse(cb); switch (cb->entry->id) { case O_BCODE_STDIN: - bpf_parse_string(cb, cb->arg, ','); + bpf_parse_string(bi->bpf_program, &bi->bpf_program_num_elem, + ARRAY_SIZE(bi->bpf_program), cb->arg); break; default: xtables_error(PARAMETER_PROBLEM, "bpf: unknown option"); } } -static void bpf_print_code(const void *ip, const struct xt_entry_match *match) +static void bpf_parse_v1(struct xt_option_call *cb) { - const struct xt_bpf_info *info = (void *) match->data; - int i; + struct xt_bpf_info_v1 *bi = (void *) cb->data; - for (i = 0; i < info->bpf_program_num_elem-1; i++) - printf("%hu %hhu %hhu %u,", info->bpf_program[i].code, - info->bpf_program[i].jt, - info->bpf_program[i].jf, - info->bpf_program[i].k); - - printf("%hu %hhu %hhu %u", info->bpf_program[i].code, - info->bpf_program[i].jt, - info->bpf_program[i].jf, - info->bpf_program[i].k); + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_BCODE_STDIN: + bpf_parse_string(bi->bpf_program, &bi->bpf_program_num_elem, + ARRAY_SIZE(bi->bpf_program), cb->arg); + bi->mode = XT_BPF_MODE_BYTECODE; + break; + case O_OBJ_PINNED: + bpf_parse_obj_pinned(bi, cb->arg); + bi->mode = XT_BPF_MODE_FD_PINNED; + break; + default: + xtables_error(PARAMETER_PROBLEM, "bpf: unknown option"); + } +} + +static void bpf_print_code(const struct sock_filter *pc, __u16 len, char tail) +{ + for (; len; len--, pc++) + printf("%hu %hhu %hhu %u%c", + pc->code, pc->jt, pc->jf, pc->k, + len > 1 ? ',' : tail); +} + +static void bpf_save_code(const struct sock_filter *pc, __u16 len) +{ + printf(" --bytecode \"%hu,", len); + bpf_print_code(pc, len, '\"'); } static void bpf_save(const void *ip, const struct xt_entry_match *match) { const struct xt_bpf_info *info = (void *) match->data; - printf(" --bytecode \"%hu,", info->bpf_program_num_elem); - bpf_print_code(ip, match); - printf("\""); + bpf_save_code(info->bpf_program, info->bpf_program_num_elem); +} + +static void bpf_save_v1(const void *ip, const struct xt_entry_match *match) +{ + const struct xt_bpf_info_v1 *info = (void *) match->data; + + if (info->mode == XT_BPF_MODE_BYTECODE) + bpf_save_code(info->bpf_program, info->bpf_program_num_elem); + else if (info->mode == XT_BPF_MODE_FD_PINNED) + printf(" --object-pinned %s", info->path); + else + xtables_error(OTHER_PROBLEM, "unknown bpf mode"); } static void bpf_fcheck(struct xt_fcheck_call *cb) @@ -125,28 +210,73 @@ "bpf: missing --bytecode parameter"); } +static void bpf_fcheck_v1(struct xt_fcheck_call *cb) +{ + const unsigned int bit_bcode = 1 << O_BCODE_STDIN; + const unsigned int bit_pinned = 1 << O_OBJ_PINNED; + unsigned int flags; + + flags = cb->xflags & (bit_bcode | bit_pinned); + if (flags != bit_bcode && flags != bit_pinned) + xtables_error(PARAMETER_PROBLEM, + "bpf: one of --bytecode or --pinned is required"); +} + static void bpf_print(const void *ip, const struct xt_entry_match *match, int numeric) { + const struct xt_bpf_info *info = (void *) match->data; + + printf("match bpf "); + bpf_print_code(info->bpf_program, info->bpf_program_num_elem, '\0'); +} + +static void bpf_print_v1(const void *ip, const struct xt_entry_match *match, + int numeric) +{ + const struct xt_bpf_info_v1 *info = (void *) match->data; + printf("match bpf "); - return bpf_print_code(ip, match); + if (info->mode == XT_BPF_MODE_BYTECODE) + bpf_print_code(info->bpf_program, info->bpf_program_num_elem, '\0'); + else if (info->mode == XT_BPF_MODE_FD_PINNED) + printf("pinned %s", info->path); + else + printf("unknown"); } -static struct xtables_match bpf_match = { - .family = NFPROTO_UNSPEC, - .name = "bpf", - .version = XTABLES_VERSION, - .size = XT_ALIGN(sizeof(struct xt_bpf_info)), - .userspacesize = XT_ALIGN(offsetof(struct xt_bpf_info, filter)), - .help = bpf_help, - .print = bpf_print, - .save = bpf_save, - .x6_parse = bpf_parse, - .x6_fcheck = bpf_fcheck, - .x6_options = bpf_opts, +static struct xtables_match bpf_matches[] = { + { + .family = NFPROTO_UNSPEC, + .name = "bpf", + .version = XTABLES_VERSION, + .revision = 0, + .size = XT_ALIGN(sizeof(struct xt_bpf_info)), + .userspacesize = XT_ALIGN(offsetof(struct xt_bpf_info, filter)), + .help = bpf_help, + .print = bpf_print, + .save = bpf_save, + .x6_parse = bpf_parse, + .x6_fcheck = bpf_fcheck, + .x6_options = bpf_opts, + }, + { + .family = NFPROTO_UNSPEC, + .name = "bpf", + .version = XTABLES_VERSION, + .revision = 1, + .size = XT_ALIGN(sizeof(struct xt_bpf_info_v1)), + .userspacesize = XT_ALIGN(offsetof(struct xt_bpf_info_v1, filter)), + .help = bpf_help_v1, + .print = bpf_print_v1, + .save = bpf_save_v1, + .x6_parse = bpf_parse_v1, + .x6_fcheck = bpf_fcheck_v1, + .x6_options = bpf_opts_v1, + }, }; void _init(void) { - xtables_register_match(&bpf_match); + xtables_register_matches(bpf_matches, ARRAY_SIZE(bpf_matches)); } diff -Nru iptables-1.6.0+snapshot20161117/extensions/libxt_connbytes.c iptables-1.6.1/extensions/libxt_connbytes.c --- iptables-1.6.0+snapshot20161117/extensions/libxt_connbytes.c 2016-11-17 06:25:02.000000000 +0100 +++ iptables-1.6.1/extensions/libxt_connbytes.c 2017-01-26 17:11:58.000000000 +0100 @@ -156,6 +156,61 @@ print_direction(sinfo); } + +static int connbytes_xlate(struct xt_xlate *xl, + const struct xt_xlate_mt_params *params) +{ + const struct xt_connbytes_info *info = (void *)params->match->data; + unsigned long long from, to; + bool invert = false; + + xt_xlate_add(xl, "ct "); + + switch (info->direction) { + case XT_CONNBYTES_DIR_ORIGINAL: + xt_xlate_add(xl, "original "); + break; + case XT_CONNBYTES_DIR_REPLY: + xt_xlate_add(xl, "reply "); + break; + case XT_CONNBYTES_DIR_BOTH: + break; + default: + return 0; + } + + switch (info->what) { + case XT_CONNBYTES_PKTS: + xt_xlate_add(xl, "packets "); + break; + case XT_CONNBYTES_BYTES: + xt_xlate_add(xl, "bytes "); + break; + case XT_CONNBYTES_AVGPKT: + xt_xlate_add(xl, "avgpkt "); + break; + default: + return 0; + } + + if (info->count.from > info->count.to) { + invert = true; + from = info->count.to; + to = info->count.from; + } else { + to = info->count.to; + from = info->count.from; + } + + if (from == to) + xt_xlate_add(xl, "%llu", from); + else if (to == UINT64_MAX) + xt_xlate_add(xl, "%s %llu", invert ? "lt" : "ge", from); + else + xt_xlate_add(xl, "%s%llu-%llu", invert ? "!= " : "", from, to); + return 1; +} + static struct xtables_match connbytes_match = { .family = NFPROTO_UNSPEC, .name = "connbytes", @@ -167,6 +222,7 @@ .save = connbytes_save, .x6_parse = connbytes_parse, .x6_options = connbytes_opts, + .xlate = connbytes_xlate, }; void _init(void) diff -Nru iptables-1.6.0+snapshot20161117/extensions/libxt_multiport.c iptables-1.6.1/extensions/libxt_multiport.c --- iptables-1.6.0+snapshot20161117/extensions/libxt_multiport.c 2016-11-17 06:25:02.000000000 +0100 +++ iptables-1.6.1/extensions/libxt_multiport.c 2017-01-26 17:11:58.000000000 +0100 @@ -108,7 +108,6 @@ { char *buffer, *cp, *next, *range; unsigned int i; - uint16_t m; buffer = strdup(portstring); if (!buffer) xtables_error(OTHER_PROBLEM, "strdup failed"); @@ -133,7 +132,6 @@ if (multiinfo->ports[i-1] >= multiinfo->ports[i]) xtables_error(PARAMETER_PROBLEM, "invalid portrange specified"); - m <<= 1; } } multiinfo->count = i; diff -Nru iptables-1.6.0+snapshot20161117/extensions/libxt_rpfilter.c iptables-1.6.1/extensions/libxt_rpfilter.c --- iptables-1.6.0+snapshot20161117/extensions/libxt_rpfilter.c 2016-11-17 06:25:02.000000000 +0100 +++ iptables-1.6.1/extensions/libxt_rpfilter.c 2017-01-26 17:11:58.000000000 +0100 @@ -77,6 +77,31 @@ return rpfilter_print_prefix(ip, match->data, "--"); } +static int rpfilter_xlate(struct xt_xlate *xl, + const struct xt_xlate_mt_params *params) +{ + const struct xt_rpfilter_info *info = (void *)params->match->data; + bool invert = info->flags & XT_RPFILTER_INVERT; + + if (info->flags & XT_RPFILTER_ACCEPT_LOCAL) { + if (invert) + xt_xlate_add(xl, "fib saddr type != local "); + else + return 0; + } + + xt_xlate_add(xl, "fib saddr "); + + if (info->flags & XT_RPFILTER_VALID_MARK) + xt_xlate_add(xl, ". mark "); + if (!(info->flags & XT_RPFILTER_LOOSE)) + xt_xlate_add(xl, ". iif "); + + xt_xlate_add(xl, "oif %s0", invert ? "" : "!= "); + + return 1; +} + static struct xtables_match rpfilter_match = { .family = NFPROTO_UNSPEC, .name = "rpfilter", @@ -88,6 +113,7 @@ .save = rpfilter_save, .x6_parse = rpfilter_parse, .x6_options = rpfilter_opts, + .xlate = rpfilter_xlate, }; void _init(void) diff -Nru iptables-1.6.0+snapshot20161117/extensions/libxt_tcp.c iptables-1.6.1/extensions/libxt_tcp.c --- iptables-1.6.0+snapshot20161117/extensions/libxt_tcp.c 2016-11-17 06:25:02.000000000 +0100 +++ iptables-1.6.1/extensions/libxt_tcp.c 2017-01-26 17:11:58.000000000 +0100 @@ -435,9 +435,9 @@ return 0; if (tcpinfo->flg_mask || (tcpinfo->invflags & XT_TCP_INV_FLAGS)) { - xt_xlate_add(xl, "%stcp flags & ", space); + xt_xlate_add(xl, "%stcp flags & (", space); print_tcp_xlate(xl, tcpinfo->flg_mask); - xt_xlate_add(xl, " %s ", + xt_xlate_add(xl, ") %s ", tcpinfo->invflags & XT_TCP_INV_FLAGS ? "!=": "=="); print_tcp_xlate(xl, tcpinfo->flg_cmp); } diff -Nru iptables-1.6.0+snapshot20161117/iptables/ip6tables.c iptables-1.6.1/iptables/ip6tables.c --- iptables-1.6.0+snapshot20161117/iptables/ip6tables.c 2016-11-17 06:25:02.000000000 +0100 +++ iptables-1.6.1/iptables/ip6tables.c 2017-01-26 17:11:58.000000000 +0100 @@ -76,6 +76,8 @@ static const char optflags[] = { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '0', 'c'}; +static const char unsupported_rev[] = " [unsupported revision]"; + static struct option original_opts[] = { {.name = "append", .has_arg = 1, .val = 'A'}, {.name = "delete", .has_arg = 1, .val = 'D'}, @@ -520,8 +522,10 @@ xtables_find_match(m->u.user.name, XTF_TRY_LOAD, NULL); if (match) { - if (match->print) + if (match->print && m->u.user.revision == match->revision) match->print(ip, m, numeric); + else if (match->print) + printf("%s%s ", match->name, unsupported_rev); else printf("%s ", match->name); } else { @@ -647,9 +651,11 @@ IP6T_MATCH_ITERATE(fw, print_match, &fw->ipv6, format & FMT_NUMERIC); if (target) { - if (target->print) + if (target->print && t->u.user.revision == target->revision) /* Print the target information. */ target->print(&fw->ipv6, t, format & FMT_NUMERIC); + else if (target->print) + printf(" %s%s", target->name, unsupported_rev); } else if (t->u.target_size != sizeof(*t)) printf("[%u bytes of unknown target data] ", (unsigned int)(t->u.target_size - sizeof(*t))); @@ -1037,8 +1043,10 @@ match->alias ? match->alias(e) : e->u.user.name); /* some matches don't provide a save function */ - if (match->save) + if (match->save && e->u.user.revision == match->revision) match->save(ip, e); + else if (match->save) + printf(unsupported_rev); } else { if (e->u.match_size) { fprintf(stderr, @@ -1138,8 +1146,10 @@ } printf(" -j %s", target->alias ? target->alias(t) : target_name); - if (target->save) + if (target->save && t->u.user.revision == target->revision) target->save(&e->ipv6, t); + else if (target->save) + printf(unsupported_rev); else { /* If the target size is greater than xt_entry_target * there is something to be saved, we just don't know diff -Nru iptables-1.6.0+snapshot20161117/iptables/ip6tables-save.c iptables-1.6.1/iptables/ip6tables-save.c --- iptables-1.6.0+snapshot20161117/iptables/ip6tables-save.c 2016-11-17 06:25:02.000000000 +0100 +++ iptables-1.6.1/iptables/ip6tables-save.c 2017-01-26 17:11:58.000000000 +0100 @@ -35,10 +35,16 @@ int ret = 1; FILE *procfile = NULL; char tablename[XT_TABLE_MAXNAMELEN+1]; + static const char filename[] = "/proc/net/ip6_tables_names"; - procfile = fopen("/proc/net/ip6_tables_names", "re"); - if (!procfile) - return ret; + procfile = fopen(filename, "re"); + if (!procfile) { + if (errno == ENOENT) + return ret; + fprintf(stderr, "Failed to list table names in %s: %s\n", + filename, strerror(errno)); + exit(1); + } while (fgets(tablename, sizeof(tablename), procfile)) { if (tablename[strlen(tablename) - 1] != '\n') diff -Nru iptables-1.6.0+snapshot20161117/iptables/iptables.c iptables-1.6.1/iptables/iptables.c --- iptables-1.6.0+snapshot20161117/iptables/iptables.c 2016-11-17 06:25:02.000000000 +0100 +++ iptables-1.6.1/iptables/iptables.c 2017-01-26 17:11:58.000000000 +0100 @@ -73,6 +73,8 @@ static const char optflags[] = { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '0', 'c', 'f'}; +static const char unsupported_rev[] = " [unsupported revision]"; + static struct option original_opts[] = { {.name = "append", .has_arg = 1, .val = 'A'}, {.name = "delete", .has_arg = 1, .val = 'D'}, @@ -504,8 +506,10 @@ xtables_find_match(m->u.user.name, XTF_TRY_LOAD, NULL); if (match) { - if (match->print) + if (match->print && m->u.user.revision == match->revision) match->print(ip, m, numeric); + else if (match->print) + printf("%s%s ", match->name, unsupported_rev); else printf("%s ", match->name); } else { @@ -631,9 +635,11 @@ IPT_MATCH_ITERATE(fw, print_match, &fw->ip, format & FMT_NUMERIC); if (target) { - if (target->print) + if (target->print && t->u.user.revision == target->revision) /* Print the target information. */ target->print(&fw->ip, t, format & FMT_NUMERIC); + else if (target->print) + printf(" %s%s", target->name, unsupported_rev); } else if (t->u.target_size != sizeof(*t)) printf("[%u bytes of unknown target data] ", (unsigned int)(t->u.target_size - sizeof(*t))); @@ -1027,8 +1033,10 @@ match->alias ? match->alias(e) : e->u.user.name); /* some matches don't provide a save function */ - if (match->save) + if (match->save && e->u.user.revision == match->revision) match->save(ip, e); + else if (match->save) + printf(unsupported_rev); } else { if (e->u.match_size) { fprintf(stderr, @@ -1128,8 +1136,10 @@ } printf(" -j %s", target->alias ? target->alias(t) : target_name); - if (target->save) + if (target->save && t->u.user.revision == target->revision) target->save(&e->ip, t); + else if (target->save) + printf(unsupported_rev); else { /* If the target size is greater than xt_entry_target * there is something to be saved, we just don't know diff -Nru iptables-1.6.0+snapshot20161117/iptables/iptables-save.c iptables-1.6.1/iptables/iptables-save.c --- iptables-1.6.0+snapshot20161117/iptables/iptables-save.c 2016-11-17 06:25:02.000000000 +0100 +++ iptables-1.6.1/iptables/iptables-save.c 2017-01-26 17:11:58.000000000 +0100 @@ -33,10 +33,16 @@ int ret = 1; FILE *procfile = NULL; char tablename[XT_TABLE_MAXNAMELEN+1]; + static const char filename[] = "/proc/net/ip_tables_names"; - procfile = fopen("/proc/net/ip_tables_names", "re"); - if (!procfile) - return ret; + procfile = fopen(filename, "re"); + if (!procfile) { + if (errno == ENOENT) + return ret; + fprintf(stderr, "Failed to list table names in %s: %s\n", + filename, strerror(errno)); + exit(1); + } while (fgets(tablename, sizeof(tablename), procfile)) { if (tablename[strlen(tablename) - 1] != '\n') diff -Nru iptables-1.6.0+snapshot20161117/iptables/nft-ipv4.c iptables-1.6.1/iptables/nft-ipv4.c --- iptables-1.6.0+snapshot20161117/iptables/nft-ipv4.c 2016-11-17 06:25:02.000000000 +0100 +++ iptables-1.6.1/iptables/nft-ipv4.c 2017-01-26 17:11:58.000000000 +0100 @@ -471,14 +471,16 @@ } if (cs->fw.ip.src.s_addr != 0) { - xt_xlate_add(xl, "ip saddr %s%s ", + xt_xlate_add(xl, "ip saddr %s%s%s ", cs->fw.ip.invflags & IPT_INV_SRCIP ? "!= " : "", - inet_ntoa(cs->fw.ip.src)); + inet_ntoa(cs->fw.ip.src), + xtables_ipmask_to_numeric(&cs->fw.ip.smsk)); } if (cs->fw.ip.dst.s_addr != 0) { - xt_xlate_add(xl, "ip daddr %s%s ", + xt_xlate_add(xl, "ip daddr %s%s%s ", cs->fw.ip.invflags & IPT_INV_DSTIP ? "!= " : "", - inet_ntoa(cs->fw.ip.dst)); + inet_ntoa(cs->fw.ip.dst), + xtables_ipmask_to_numeric(&cs->fw.ip.dmsk)); } ret = xlate_matches(cs, xl); @@ -487,12 +489,11 @@ /* Always add counters per rule, as in iptables */ xt_xlate_add(xl, "counter "); + ret = xlate_action(cs, !!(cs->fw.ip.flags & IPT_F_GOTO), xl); comment = xt_xlate_get_comment(xl); if (comment) - xt_xlate_add(xl, "comment %s", comment); - - ret = xlate_action(cs, !!(cs->fw.ip.flags & IPT_F_GOTO), xl); + xt_xlate_add(xl, " comment %s", comment); return ret; } diff -Nru iptables-1.6.0+snapshot20161117/iptables/nft-ipv6.c iptables-1.6.1/iptables/nft-ipv6.c --- iptables-1.6.0+snapshot20161117/iptables/nft-ipv6.c 2016-11-17 06:25:02.000000000 +0100 +++ iptables-1.6.1/iptables/nft-ipv6.c 2017-01-26 17:11:58.000000000 +0100 @@ -387,6 +387,7 @@ } static void xlate_ipv6_addr(const char *selector, const struct in6_addr *addr, + const struct in6_addr *mask, int invert, struct xt_xlate *xl) { char addr_str[INET6_ADDRSTRLEN]; @@ -395,7 +396,8 @@ return; inet_ntop(AF_INET6, addr, addr_str, INET6_ADDRSTRLEN); - xt_xlate_add(xl, "%s %s%s ", selector, invert ? "!= " : "", addr_str); + xt_xlate_add(xl, "%s %s%s%s ", selector, invert ? "!= " : "", addr_str, + xtables_ip6mask_to_numeric(mask)); } static int nft_ipv6_xlate(const void *data, struct xt_xlate *xl) @@ -425,9 +427,9 @@ } } - xlate_ipv6_addr("ip6 saddr", &cs->fw6.ipv6.src, + xlate_ipv6_addr("ip6 saddr", &cs->fw6.ipv6.src, &cs->fw6.ipv6.smsk, cs->fw6.ipv6.invflags & IP6T_INV_SRCIP, xl); - xlate_ipv6_addr("ip6 daddr", &cs->fw6.ipv6.dst, + xlate_ipv6_addr("ip6 daddr", &cs->fw6.ipv6.dst, &cs->fw6.ipv6.dmsk, cs->fw6.ipv6.invflags & IP6T_INV_DSTIP, xl); ret = xlate_matches(cs, xl); @@ -436,12 +438,11 @@ /* Always add counters per rule, as in iptables */ xt_xlate_add(xl, "counter "); + ret = xlate_action(cs, !!(cs->fw6.ipv6.flags & IP6T_F_GOTO), xl); comment = xt_xlate_get_comment(xl); if (comment) - xt_xlate_add(xl, "comment %s", comment); - - ret = xlate_action(cs, !!(cs->fw6.ipv6.flags & IP6T_F_GOTO), xl); + xt_xlate_add(xl, " comment %s", comment); return ret; } diff -Nru iptables-1.6.0+snapshot20161117/iptables/xtables-translate.c iptables-1.6.1/iptables/xtables-translate.c --- iptables-1.6.0+snapshot20161117/iptables/xtables-translate.c 2016-11-17 06:25:02.000000000 +0100 +++ iptables-1.6.1/iptables/xtables-translate.c 2017-01-26 17:11:58.000000000 +0100 @@ -352,18 +352,30 @@ const char *chain, const char *policy, const struct xt_counters *counters) { - printf("add chain %s %s %s ", family2str[h->family], table, chain); + const char *type = "filter"; + + if (strcmp(table, "nat") == 0) + type = "nat"; + + printf("add chain %s %s %s { type %s ", + family2str[h->family], table, chain, type); if (strcmp(chain, "PREROUTING") == 0) - printf("{ type filter hook prerouting priority 0; }\n"); + printf("hook prerouting priority 0; "); else if (strcmp(chain, "INPUT") == 0) - printf("{ type filter hook input priority 0; }\n"); + printf("hook input priority 0; "); else if (strcmp(chain, "FORWARD") == 0) - printf("{ type filter hook forward priority 0; }\n"); + printf("hook forward priority 0; "); else if (strcmp(chain, "OUTPUT") == 0) - printf("{ type filter hook output priority 0; }\n"); + printf("hook output priority 0; "); else if (strcmp(chain, "POSTROUTING") == 0) - printf("{ type filter hook postrouting priority 0; }\n"); + printf("hook postrouting priority 0; "); + + if (strcmp(policy, "ACCEPT") == 0) + printf("policy accept; "); + else if (strcmp(policy, "DROP") == 0) + printf("policy drop; "); + printf("}\n"); return 1; } diff -Nru iptables-1.6.0+snapshot20161117/libxtables/xtables.c iptables-1.6.1/libxtables/xtables.c --- iptables-1.6.0+snapshot20161117/libxtables/xtables.c 2016-11-17 06:25:02.000000000 +0100 +++ iptables-1.6.1/libxtables/xtables.c 2017-01-26 17:11:58.000000000 +0100 @@ -1210,13 +1210,20 @@ static const char *ipaddr_to_host(const struct in_addr *addr) { - struct hostent *host; + static char hostname[NI_MAXHOST]; + struct sockaddr_in saddr = { + .sin_family = AF_INET, + .sin_addr = *addr, + }; + int err; + - host = gethostbyaddr(addr, sizeof(struct in_addr), AF_INET); - if (host == NULL) + err = getnameinfo((const void *)&saddr, sizeof(struct sockaddr_in), + hostname, sizeof(hostname) - 1, NULL, 0, 0); + if (err != 0) return NULL; - return host->h_name; + return hostname; } static const char *ipaddr_to_network(const struct in_addr *addr) @@ -1366,17 +1373,10 @@ *naddr = 0; if ((err = getaddrinfo(name, NULL, &hints, &res)) != 0) { -#ifdef DEBUG - fprintf(stderr,"Name2IP: %s\n",gai_strerror(err)); -#endif return NULL; } else { for (p = res; p != NULL; p = p->ai_next) ++*naddr; -#ifdef DEBUG - fprintf(stderr, "resolved: len=%d %s ", res->ai_addrlen, - xtables_ipaddr_to_numeric(&((struct sockaddr_in *)res->ai_addr)->sin_addr)); -#endif addr = xtables_calloc(*naddr, sizeof(struct in_addr)); for (i = 0, p = res; p != NULL; p = p->ai_next) memcpy(&addr[i++], @@ -1577,17 +1577,10 @@ saddr.sin6_family = AF_INET6; err = getnameinfo((const void *)&saddr, sizeof(struct sockaddr_in6), - hostname, sizeof(hostname) - 1, NULL, 0, 0); - if (err != 0) { -#ifdef DEBUG - fprintf(stderr,"IP2Name: %s\n",gai_strerror(err)); -#endif + hostname, sizeof(hostname) - 1, NULL, 0, 0); + if (err != 0) return NULL; - } -#ifdef DEBUG - fprintf (stderr, "\naddr2host: %s\n", hostname); -#endif return hostname; } @@ -1650,9 +1643,7 @@ if ((err = inet_pton(AF_INET6, num, &ap)) == 1) return ≈ -#ifdef DEBUG - fprintf(stderr, "\nnumeric2addr: %d\n", err); -#endif + return NULL; } @@ -1672,18 +1663,11 @@ *naddr = 0; if ((err = getaddrinfo(name, NULL, &hints, &res)) != 0) { -#ifdef DEBUG - fprintf(stderr,"Name2IP: %s\n",gai_strerror(err)); -#endif return NULL; } else { /* Find length of address chain */ for (p = res; p != NULL; p = p->ai_next) ++*naddr; -#ifdef DEBUG - fprintf(stderr, "resolved: len=%d %s ", res->ai_addrlen, - xtables_ip6addr_to_numeric(&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr)); -#endif /* Copy each element of the address chain */ addr = xtables_calloc(*naddr, sizeof(struct in6_addr)); for (i = 0, p = res; p != NULL; p = p->ai_next)