diff options
Diffstat (limited to 'extensions')
187 files changed, 1608 insertions, 3197 deletions
diff --git a/extensions/GNUmakefile.in b/extensions/GNUmakefile.in index 6dad4e02..e289adf0 100644 --- a/extensions/GNUmakefile.in +++ b/extensions/GNUmakefile.in @@ -24,7 +24,7 @@ kinclude_CPPFLAGS = @kinclude_CPPFLAGS@ AM_CFLAGS = ${regular_CFLAGS} AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_builddir}/include -I${top_builddir} -I${top_srcdir}/include -I${top_srcdir} ${kinclude_CPPFLAGS} ${CPPFLAGS} @libnetfilter_conntrack_CFLAGS@ @libnftnl_CFLAGS@ AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@ -AM_LDFLAGS = @noundef_LDFLAGS@ +AM_LDFLAGS = @noundef_LDFLAGS@ @regular_LDFLAGS@ ifeq (${V},) AM_LIBTOOL_SILENT = --silent @@ -42,7 +42,7 @@ endif pfx_build_mod := $(patsubst ${srcdir}/libxt_%.c,%,$(sort $(wildcard ${srcdir}/libxt_*.c))) @ENABLE_NFTABLES_TRUE@ pfb_build_mod := $(patsubst ${srcdir}/libebt_%.c,%,$(sort $(wildcard ${srcdir}/libebt_*.c))) @ENABLE_NFTABLES_TRUE@ pfa_build_mod := $(patsubst ${srcdir}/libarpt_%.c,%,$(sort $(wildcard ${srcdir}/libarpt_*.c))) -pfx_symlinks := NOTRACK state REDIRECT +pfx_symlinks := NOTRACK state REDIRECT MASQUERADE SNAT DNAT @ENABLE_IPV4_TRUE@ pf4_build_mod := $(patsubst ${srcdir}/libipt_%.c,%,$(sort $(wildcard ${srcdir}/libipt_*.c))) @ENABLE_IPV6_TRUE@ pf6_build_mod := $(patsubst ${srcdir}/libip6t_%.c,%,$(sort $(wildcard ${srcdir}/libip6t_*.c))) pfx_build_mod := $(filter-out @blacklist_modules@ @blacklist_x_modules@,${pfx_build_mod}) @@ -79,7 +79,7 @@ targets_install := .SECONDARY: -.PHONY: all install uninstall clean distclean FORCE +.PHONY: all install uninstall clean distclean FORCE dvi check installcheck all: ${targets} @@ -106,7 +106,8 @@ uninstall: } clean: - rm -f *.o *.oo *.so *.a {matches,targets}.man initext.c initext4.c initext6.c initextb.c initexta.c; + rm -f *.o *.oo *.so *.a matches.man targets.man + rm -f initext.c initext4.c initext6.c initextb.c initexta.c rm -f .*.d .*.dd; distclean: clean @@ -130,7 +131,13 @@ libxt_NOTRACK.so: libxt_CT.so ln -fs $< $@ libxt_state.so: libxt_conntrack.so ln -fs $< $@ -libxt_REDIRECT.so: libxt_DNAT.so +libxt_REDIRECT.so: libxt_NAT.so + ln -fs $< $@ +libxt_MASQUERADE.so: libxt_NAT.so + ln -fs $< $@ +libxt_SNAT.so: libxt_NAT.so + ln -fs $< $@ +libxt_DNAT.so: libxt_NAT.so ln -fs $< $@ # Need the LIBADDs in iptables/Makefile.am too for libxtables_la_LIBADD @@ -169,111 +176,33 @@ initexta_func := $(addprefix arpt_,${pfa_build_mod}) initext4_func := $(addprefix ipt_,${pf4_build_mod}) initext6_func := $(addprefix ip6t_,${pf6_build_mod}) -.initext.dd: FORCE - @echo "${initext_func}" >$@.tmp; \ - cmp -s $@ $@.tmp || mv $@.tmp $@; \ - rm -f $@.tmp; - -.initextb.dd: FORCE - @echo "${initextb_func}" >$@.tmp; \ - cmp -s $@ $@.tmp || mv $@.tmp $@; \ - rm -f $@.tmp; +initexts := ext exta extb ext4 ext6 +initext_depfiles = $(patsubst %,.init%.dd,${initexts}) +initext_sources = $(patsubst %,init%.c,${initexts}) -.initexta.dd: FORCE - @echo "${initexta_func}" >$@.tmp; \ +${initext_depfiles}: FORCE + @echo "$(value $(patsubst .%.dd,%,$@)_func)" >$@.tmp; \ cmp -s $@ $@.tmp || mv $@.tmp $@; \ rm -f $@.tmp; -.initext4.dd: FORCE - @echo "${initext4_func}" >$@.tmp; \ - cmp -s $@ $@.tmp || mv $@.tmp $@; \ - rm -f $@.tmp; - -.initext6.dd: FORCE - @echo "${initext6_func}" >$@.tmp; \ - cmp -s $@ $@.tmp || mv $@.tmp $@; \ - rm -f $@.tmp; - -initext.c: .initext.dd - ${AM_VERBOSE_GEN} - @( \ - echo "" >$@; \ - for i in ${initext_func}; do \ - echo "extern void lib$${i}_init(void);" >>$@; \ - done; \ - echo "void init_extensions(void);" >>$@; \ - echo "void init_extensions(void)" >>$@; \ - echo "{" >>$@; \ - for i in ${initext_func}; do \ - echo " ""lib$${i}_init();" >>$@; \ - done; \ - echo "}" >>$@; \ - ); - -initextb.c: .initextb.dd - ${AM_VERBOSE_GEN} - @( \ - echo "" >$@; \ - for i in ${initextb_func}; do \ - echo "extern void lib$${i}_init(void);" >>$@; \ - done; \ - echo "void init_extensionsb(void);" >>$@; \ - echo "void init_extensionsb(void)" >>$@; \ - echo "{" >>$@; \ - for i in ${initextb_func}; do \ - echo " ""lib$${i}_init();" >>$@; \ - done; \ - echo "}" >>$@; \ - ); - -initexta.c: .initexta.dd - ${AM_VERBOSE_GEN} - @( \ - echo "" >$@; \ - for i in ${initexta_func}; do \ - echo "extern void lib$${i}_init(void);" >>$@; \ - done; \ - echo "void init_extensionsa(void);" >>$@; \ - echo "void init_extensionsa(void)" >>$@; \ - echo "{" >>$@; \ - for i in ${initexta_func}; do \ - echo " ""lib$${i}_init();" >>$@; \ - done; \ - echo "}" >>$@; \ - ); - -initext4.c: .initext4.dd +${initext_sources}: %.c: .%.dd ${AM_VERBOSE_GEN} @( \ + initext_func="$(value $(basename $@)_func)"; \ + funcname="init_extensions$(patsubst initext%.c,%,$@)"; \ echo "" >$@; \ - for i in ${initext4_func}; do \ + for i in $${initext_func}; do \ echo "extern void lib$${i}_init(void);" >>$@; \ done; \ - echo "void init_extensions4(void);" >>$@; \ - echo "void init_extensions4(void)" >>$@; \ + echo "void $${funcname}(void);" >>$@; \ + echo "void $${funcname}(void)" >>$@; \ echo "{" >>$@; \ - for i in ${initext4_func}; do \ + for i in $${initext_func}; do \ echo " ""lib$${i}_init();" >>$@; \ done; \ echo "}" >>$@; \ ); -initext6.c: .initext6.dd - ${AM_VERBOSE_GEN} - @( \ - echo "" >$@; \ - for i in ${initext6_func}; do \ - echo "extern void lib$${i}_init(void);" >>$@; \ - done; \ - echo "void init_extensions6(void);" >>$@; \ - echo "void init_extensions6(void)" >>$@; \ - echo "{" >>$@; \ - for i in ${initext6_func}; do \ - echo " ""lib$${i}_init();" >>$@; \ - done; \ - echo "}" >>$@; \ - ); - # # Manual pages # @@ -302,8 +231,21 @@ man_run = \ fi; \ done >$@; -matches.man: .initext.dd .initextb.dd .initexta.dd .initext4.dd .initext6.dd $(wildcard ${srcdir}/lib*.man) +matches.man: ${initext_depfiles} $(wildcard ${srcdir}/lib*.man) $(call man_run,$(call ex_matches,${pfx_build_mod} ${pfb_build_mod} ${pfa_build_mod} ${pf4_build_mod} ${pf6_build_mod} ${pfx_symlinks})) -targets.man: .initext.dd .initextb.dd .initexta.dd .initext4.dd .initext6.dd $(wildcard ${srcdir}/lib*.man) +targets.man: ${initext_depfiles} $(wildcard ${srcdir}/lib*.man) $(call man_run,$(call ex_targets,${pfx_build_mod} ${pfb_build_mod} ${pfa_build_mod} ${pf4_build_mod} ${pf6_build_mod} ${pfx_symlinks})) + +dist_initext_src = $(addprefix $(srcdir)/,${initext_sources}) +dist_sources = $(filter-out ${dist_initext_src},$(wildcard $(srcdir)/*.[ch])) + +distdir: + mkdir -p $(distdir) + cp -p ${dist_sources} $(distdir)/ + cp -p $(wildcard ${srcdir}/lib*.man) $(distdir)/ + cp -p $(wildcard ${srcdir}/*.t ${srcdir}/*.txlate) $(distdir)/ + +dvi: +check: all +installcheck: diff --git a/extensions/dscp_helper.c b/extensions/dscp_helper.c index 75b1fece..1f20b2a5 100644 --- a/extensions/dscp_helper.c +++ b/extensions/dscp_helper.c @@ -58,7 +58,7 @@ class_to_dscp(const char *name) } xtables_error(PARAMETER_PROBLEM, - "Invalid DSCP value `%s'\n", name); + "Invalid DSCP value `%s'", name); } @@ -73,7 +73,7 @@ dscp_to_name(unsigned int dscp) return ds_classes[i].name; xtables_error(PARAMETER_PROBLEM, - "Invalid DSCP value `%d'\n", dscp); + "Invalid DSCP value `%d'", dscp); } #endif diff --git a/extensions/generic.txlate b/extensions/generic.txlate index 9ae9a5b5..c24ed156 100644 --- a/extensions/generic.txlate +++ b/extensions/generic.txlate @@ -1,84 +1,90 @@ iptables-translate -I OUTPUT -p udp -d 8.8.8.8 -j ACCEPT -nft insert rule ip filter OUTPUT ip protocol udp ip daddr 8.8.8.8 counter accept +nft 'insert rule ip filter OUTPUT ip protocol udp ip daddr 8.8.8.8 counter accept' iptables-translate -F -t nat nft flush table ip nat iptables-translate -I INPUT -i iifname -s 10.0.0.0/8 -nft insert rule ip filter INPUT iifname "iifname" ip saddr 10.0.0.0/8 counter +nft 'insert rule ip filter INPUT iifname "iifname" ip saddr 10.0.0.0/8 counter' iptables-translate -A INPUT -i iif+ ! -d 10.0.0.0/8 -nft add rule ip filter INPUT iifname "iif*" ip daddr != 10.0.0.0/8 counter +nft 'add rule ip filter INPUT iifname "iif*" ip daddr != 10.0.0.0/8 counter' iptables-translate -I INPUT -s 10.11.12.13/255.255.0.0 -nft insert rule ip filter INPUT ip saddr 10.11.0.0/16 counter +nft 'insert rule ip filter INPUT ip saddr 10.11.0.0/16 counter' iptables-translate -I INPUT -s 10.11.12.13/255.0.255.0 -nft insert rule ip filter INPUT ip saddr & 255.0.255.0 == 10.0.12.0 counter +nft 'insert rule ip filter INPUT ip saddr & 255.0.255.0 == 10.0.12.0 counter' iptables-translate -I INPUT -s 10.11.12.13/0.255.0.255 -nft insert rule ip filter INPUT ip saddr & 0.255.0.255 == 0.11.0.13 counter +nft 'insert rule ip filter INPUT ip saddr & 0.255.0.255 == 0.11.0.13 counter' iptables-translate -I INPUT ! -s 10.11.12.13/0.255.0.255 -nft insert rule ip filter INPUT ip saddr & 0.255.0.255 != 0.11.0.13 counter +nft 'insert rule ip filter INPUT ip saddr & 0.255.0.255 != 0.11.0.13 counter' iptables-translate -I INPUT -s 0.0.0.0/16 -nft insert rule ip filter INPUT ip saddr 0.0.0.0/16 counter +nft 'insert rule ip filter INPUT ip saddr 0.0.0.0/16 counter' iptables-translate -I INPUT -s 0.0.0.0/0 -nft insert rule ip filter INPUT counter +nft 'insert rule ip filter INPUT counter' iptables-translate -I INPUT ! -s 0.0.0.0/0 -nft insert rule ip filter INPUT ip saddr != 0.0.0.0/0 counter +nft 'insert rule ip filter INPUT ip saddr != 0.0.0.0/0 counter' ip6tables-translate -I INPUT -i iifname -s feed::/16 -nft insert rule ip6 filter INPUT iifname "iifname" ip6 saddr feed::/16 counter +nft 'insert rule ip6 filter INPUT iifname "iifname" ip6 saddr feed::/16 counter' ip6tables-translate -A INPUT -i iif+ ! -d feed::/16 -nft add rule ip6 filter INPUT iifname "iif*" ip6 daddr != feed::/16 counter +nft 'add rule ip6 filter INPUT iifname "iif*" ip6 daddr != feed::/16 counter' ip6tables-translate -I INPUT -s feed:babe::1/ffff:ff00:: -nft insert rule ip6 filter INPUT ip6 saddr feed:ba00::/24 counter +nft 'insert rule ip6 filter INPUT ip6 saddr feed:ba00::/24 counter' ip6tables-translate -I INPUT -s feed:babe:c0ff:ee00:c0be:1234:5678:90ab/ffff:0:ffff:0:ffff:0:ffff:0 -nft insert rule ip6 filter INPUT ip6 saddr & ffff:0:ffff:0:ffff:0:ffff:0 == feed:0:c0ff:0:c0be:0:5678:0 counter +nft 'insert rule ip6 filter INPUT ip6 saddr & ffff:0:ffff:0:ffff:0:ffff:0 == feed:0:c0ff:0:c0be:0:5678:0 counter' ip6tables-translate -I INPUT -s feed:babe:c0ff:ee00:c0be:1234:5678:90ab/0:ffff:0:ffff:0:ffff:0:ffff -nft insert rule ip6 filter INPUT ip6 saddr & 0:ffff:0:ffff:0:ffff:0:ffff == 0:babe:0:ee00:0:1234:0:90ab counter +nft 'insert rule ip6 filter INPUT ip6 saddr & 0:ffff:0:ffff:0:ffff:0:ffff == 0:babe:0:ee00:0:1234:0:90ab counter' ip6tables-translate -I INPUT ! -s feed:babe:c0ff:ee00:c0be:1234:5678:90ab/0:ffff:0:ffff:0:ffff:0:ffff -nft insert rule ip6 filter INPUT ip6 saddr & 0:ffff:0:ffff:0:ffff:0:ffff != 0:babe:0:ee00:0:1234:0:90ab counter +nft 'insert rule ip6 filter INPUT ip6 saddr & 0:ffff:0:ffff:0:ffff:0:ffff != 0:babe:0:ee00:0:1234:0:90ab counter' ip6tables-translate -I INPUT -s ::/16 -nft insert rule ip6 filter INPUT ip6 saddr ::/16 counter +nft 'insert rule ip6 filter INPUT ip6 saddr ::/16 counter' ip6tables-translate -I INPUT -s ::/0 -nft insert rule ip6 filter INPUT counter +nft 'insert rule ip6 filter INPUT counter' ip6tables-translate -I INPUT ! -s ::/0 -nft insert rule ip6 filter INPUT ip6 saddr != ::/0 counter +nft 'insert rule ip6 filter INPUT ip6 saddr != ::/0 counter' ebtables-translate -I INPUT -i iname --logical-in ilogname -s 0:0:0:0:0:0 -nft insert rule bridge filter INPUT iifname "iname" meta ibrname "ilogname" ether saddr 00:00:00:00:00:00 counter +nft 'insert rule bridge filter INPUT iifname "iname" meta ibrname "ilogname" ether saddr 00:00:00:00:00:00 counter' ebtables-translate -A FORWARD ! -i iname --logical-in ilogname -o out+ --logical-out lout+ -d 1:2:3:4:de:af -nft add rule bridge filter FORWARD iifname != "iname" meta ibrname "ilogname" oifname "out*" meta obrname "lout*" ether daddr 01:02:03:04:de:af counter +nft 'add rule bridge filter FORWARD iifname != "iname" meta ibrname "ilogname" oifname "out*" meta obrname "lout*" ether daddr 01:02:03:04:de:af counter' ebtables-translate -I INPUT -p ip -d 1:2:3:4:5:6/ff:ff:ff:ff:00:00 -nft insert rule bridge filter INPUT ether type 0x800 ether daddr 01:02:03:04:00:00 and ff:ff:ff:ff:00:00 == 01:02:03:04:00:00 counter +nft 'insert rule bridge filter INPUT ether type 0x800 ether daddr and ff:ff:ff:ff:00:00 == 01:02:03:04:00:00 counter' + +ebtables-translate -I INPUT -p Length +nft 'insert rule bridge filter INPUT ether type < 0x0600 counter' + +ebtables-translate -I INPUT -p ! Length +nft 'insert rule bridge filter INPUT ether type >= 0x0600 counter' # asterisk is not special in iptables and it is even a valid interface name -iptables-translate -A FORWARD -i '*' -o 'eth*foo' -nft add rule ip filter FORWARD iifname "\*" oifname "eth\*foo" counter +iptables-translate -A FORWARD -i * -o eth*foo +nft 'add rule ip filter FORWARD iifname "\*" oifname "eth*foo" counter' -# escape all asterisks but translate only the first plus character -iptables-translate -A FORWARD -i 'eth*foo*+' -o 'eth++' -nft add rule ip filter FORWARD iifname "eth\*foo\**" oifname "eth+*" counter +# escape only suffix asterisk and translate only the last plus character +iptables-translate -A FORWARD -i eth*foo*+ -o eth++ +nft 'add rule ip filter FORWARD iifname "eth*foo**" oifname "eth+*" counter' # skip for always matching interface names -iptables-translate -A FORWARD -i '+' -nft add rule ip filter FORWARD counter +iptables-translate -A FORWARD -i + +nft 'add rule ip filter FORWARD counter' # match against invalid interface name to simulate never matching rule -iptables-translate -A FORWARD ! -i '+' -nft add rule ip filter FORWARD iifname "INVAL/D" counter +iptables-translate -A FORWARD ! -i + +nft 'add rule ip filter FORWARD iifname "INVAL/D" counter' diff --git a/extensions/libarpt_standard.t b/extensions/libarpt_standard.t index e84a00b7..007fa2b8 100644 --- a/extensions/libarpt_standard.t +++ b/extensions/libarpt_standard.t @@ -12,3 +12,5 @@ -i lo --destination-mac 11:22:33:44:55:66;-i lo --dst-mac 11:22:33:44:55:66;OK --source-mac Unicast;--src-mac 00:00:00:00:00:00/01:00:00:00:00:00;OK ! --src-mac Multicast;! --src-mac 01:00:00:00:00:00/01:00:00:00:00:00;OK +--src-mac=01:02:03:04:05:06 --dst-mac=07:08:09:0A:0B:0C --h-length=6 --opcode=Request --h-type=Ethernet --proto-type=ipv4;--src-mac 01:02:03:04:05:06 --dst-mac 07:08:09:0a:0b:0c --opcode 1 --proto-type 0x800;OK +--src-mac ! 01:02:03:04:05:06 --dst-mac ! 07:08:09:0A:0B:0C --h-length ! 6 --opcode ! Request --h-type ! Ethernet --proto-type ! ipv4;! --src-mac 01:02:03:04:05:06 ! --dst-mac 07:08:09:0a:0b:0c ! --h-length 6 ! --opcode 1 ! --h-type 1 ! --proto-type 0x800;OK diff --git a/extensions/libebt_802_3.t b/extensions/libebt_802_3.t index ddfb2f0a..a138f35d 100644 --- a/extensions/libebt_802_3.t +++ b/extensions/libebt_802_3.t @@ -1,3 +1,5 @@ :INPUT,FORWARD,OUTPUT ---802_3-sap ! 0x0a -j CONTINUE;=;OK ---802_3-type 0x000a -j RETURN;=;OK +--802_3-sap ! 0x0a -j CONTINUE;=;FAIL +--802_3-type 0x000a -j RETURN;=;FAIL +-p Length --802_3-sap ! 0x0a -j CONTINUE;=;OK +-p Length --802_3-type 0x000a -j RETURN;=;OK diff --git a/extensions/libebt_among.c b/extensions/libebt_among.c index 7eb898f9..a80fb804 100644 --- a/extensions/libebt_among.c +++ b/extensions/libebt_among.c @@ -68,12 +68,12 @@ parse_nft_among_pair(char *buf, struct nft_among_pair *pair, bool have_ip) if (!inet_pton(AF_INET, sep + 1, &pair->in)) xtables_error(PARAMETER_PROBLEM, - "Invalid IP address '%s'\n", sep + 1); + "Invalid IP address '%s'", sep + 1); } ether = ether_aton(buf); if (!ether) xtables_error(PARAMETER_PROBLEM, - "Invalid MAC address '%s'\n", buf); + "Invalid MAC address '%s'", buf); memcpy(&pair->ether, ether, sizeof(*ether)); } @@ -119,7 +119,6 @@ static int bramong_parse(int c, char **argv, int invert, struct xt_entry_match **match) { struct nft_among_data *data = (struct nft_among_data *)(*match)->data; - struct xt_entry_match *new_match; bool have_ip, dst = false; size_t new_size, cnt; struct stat stats; @@ -152,10 +151,9 @@ static int bramong_parse(int c, char **argv, int invert, xtables_error(PARAMETER_PROBLEM, "File should only contain one line"); optarg[flen-1] = '\0'; - /* fall through */ + break; case AMONG_DST: - if (c == AMONG_DST) - dst = true; + dst = true; /* fall through */ case AMONG_SRC: break; @@ -171,18 +169,17 @@ static int bramong_parse(int c, char **argv, int invert, new_size *= sizeof(struct nft_among_pair); new_size += XT_ALIGN(sizeof(struct xt_entry_match)) + sizeof(struct nft_among_data); - new_match = xtables_calloc(1, new_size); - memcpy(new_match, *match, (*match)->u.match_size); - new_match->u.match_size = new_size; - data = (struct nft_among_data *)new_match->data; + if (new_size > (*match)->u.match_size) { + *match = xtables_realloc(*match, new_size); + (*match)->u.match_size = new_size; + data = (struct nft_among_data *)(*match)->data; + } + have_ip = nft_among_pairs_have_ip(optarg); poff = nft_among_prepare_data(data, dst, cnt, invert, have_ip); parse_nft_among_pairs(data->pairs + poff, optarg, cnt, have_ip); - free(*match); - *match = new_match; - if (c == AMONG_DST_F || c == AMONG_SRC_F) { munmap(argv, flen); close(fd); diff --git a/extensions/libebt_arp.c b/extensions/libebt_arp.c index d5035b95..63a953d4 100644 --- a/extensions/libebt_arp.c +++ b/extensions/libebt_arp.c @@ -87,91 +87,17 @@ static void brarp_print_help(void) #define OPT_MAC_D 0x40 #define OPT_GRAT 0x80 -static int undot_ip(char *ip, unsigned char *ip2) -{ - char *p, *q, *end; - long int onebyte; - int i; - char buf[20]; - - strncpy(buf, ip, sizeof(buf) - 1); - - p = buf; - for (i = 0; i < 3; i++) { - if ((q = strchr(p, '.')) == NULL) - return -1; - *q = '\0'; - onebyte = strtol(p, &end, 10); - if (*end != '\0' || onebyte > 255 || onebyte < 0) - return -1; - ip2[i] = (unsigned char)onebyte; - p = q + 1; - } - - onebyte = strtol(p, &end, 10); - if (*end != '\0' || onebyte > 255 || onebyte < 0) - return -1; - ip2[3] = (unsigned char)onebyte; - - return 0; -} - -static int ip_mask(char *mask, unsigned char *mask2) -{ - char *end; - long int bits; - uint32_t mask22; - - if (undot_ip(mask, mask2)) { - /* not the /a.b.c.e format, maybe the /x format */ - bits = strtol(mask, &end, 10); - if (*end != '\0' || bits > 32 || bits < 0) - return -1; - if (bits != 0) { - mask22 = htonl(0xFFFFFFFF << (32 - bits)); - memcpy(mask2, &mask22, 4); - } else { - mask22 = 0xFFFFFFFF; - memcpy(mask2, &mask22, 4); - } - } - return 0; -} - -static void ebt_parse_ip_address(char *address, uint32_t *addr, uint32_t *msk) -{ - char *p; - - /* first the mask */ - if ((p = strrchr(address, '/')) != NULL) { - *p = '\0'; - if (ip_mask(p + 1, (unsigned char *)msk)) { - xtables_error(PARAMETER_PROBLEM, - "Problem with the IP mask '%s'", p + 1); - return; - } - } else - *msk = 0xFFFFFFFF; - - if (undot_ip(address, (unsigned char *)addr)) { - xtables_error(PARAMETER_PROBLEM, - "Problem with the IP address '%s'", address); - return; - } - *addr = *addr & *msk; -} - static int brarp_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct ebt_arp_info *arpinfo = (struct ebt_arp_info *)(*match)->data; + struct in_addr *ipaddr, ipmask; long int i; char *end; - uint32_t *addr; - uint32_t *mask; unsigned char *maddr; unsigned char *mmask; + unsigned int ipnr; switch (c) { case ARP_OPCODE: @@ -231,24 +157,25 @@ brarp_parse(int c, char **argv, int invert, unsigned int *flags, case ARP_IP_S: case ARP_IP_D: + xtables_ipparse_any(optarg, &ipaddr, &ipmask, &ipnr); if (c == ARP_IP_S) { EBT_CHECK_OPTION(flags, OPT_IP_S); - addr = &arpinfo->saddr; - mask = &arpinfo->smsk; + arpinfo->saddr = ipaddr->s_addr; + arpinfo->smsk = ipmask.s_addr; arpinfo->bitmask |= EBT_ARP_SRC_IP; } else { EBT_CHECK_OPTION(flags, OPT_IP_D); - addr = &arpinfo->daddr; - mask = &arpinfo->dmsk; + arpinfo->daddr = ipaddr->s_addr; + arpinfo->dmsk = ipmask.s_addr; arpinfo->bitmask |= EBT_ARP_DST_IP; } + free(ipaddr); if (invert) { if (c == ARP_IP_S) arpinfo->invflags |= EBT_ARP_SRC_IP; else arpinfo->invflags |= EBT_ARP_DST_IP; } - ebt_parse_ip_address(optarg, addr, mask); break; case ARP_MAC_S: case ARP_MAC_D: diff --git a/extensions/libebt_arp.t b/extensions/libebt_arp.t index 14ff0f09..96fbce90 100644 --- a/extensions/libebt_arp.t +++ b/extensions/libebt_arp.t @@ -6,6 +6,9 @@ -p ARP ! --arp-ip-dst 1.2.3.4;-p ARP --arp-ip-dst ! 1.2.3.4 -j CONTINUE;OK -p ARP --arp-ip-src ! 0.0.0.0;=;OK -p ARP --arp-ip-dst ! 0.0.0.0/8;=;OK +-p ARP --arp-ip-src ! 1.2.3.4/32;-p ARP --arp-ip-src ! 1.2.3.4;OK +-p ARP --arp-ip-src ! 1.2.3.4/255.255.255.0;-p ARP --arp-ip-src ! 1.2.3.0/24;OK +-p ARP --arp-ip-src ! 1.2.3.4/255.0.255.255;-p ARP --arp-ip-src ! 1.0.3.4/255.0.255.255;OK -p ARP --arp-mac-src 00:de:ad:be:ef:00;=;OK -p ARP --arp-mac-dst de:ad:be:ef:00:00/ff:ff:ff:ff:00:00;=;OK -p ARP --arp-gratuitous;=;OK diff --git a/extensions/libebt_dnat.txlate b/extensions/libebt_dnat.txlate index 2652dd55..531a22aa 100644 --- a/extensions/libebt_dnat.txlate +++ b/extensions/libebt_dnat.txlate @@ -1,8 +1,8 @@ -ebtables-translate -t nat -A PREROUTING -i someport --to-dst de:ad:00:be:ee:ff -nft add rule bridge nat PREROUTING iifname "someport" ether daddr set de:ad:0:be:ee:ff accept counter +ebtables-translate -t nat -A PREROUTING -i someport -j dnat --to-dst de:ad:00:be:ee:ff +nft 'add rule bridge nat PREROUTING iifname "someport" counter ether daddr set de:ad:0:be:ee:ff accept' -ebtables-translate -t nat -A PREROUTING -i someport --to-dst de:ad:00:be:ee:ff --dnat-target ACCEPT -nft add rule bridge nat PREROUTING iifname "someport" ether daddr set de:ad:0:be:ee:ff accept counter +ebtables-translate -t nat -A PREROUTING -i someport -j dnat --to-dst de:ad:00:be:ee:ff --dnat-target ACCEPT +nft 'add rule bridge nat PREROUTING iifname "someport" counter ether daddr set de:ad:0:be:ee:ff accept' -ebtables-translate -t nat -A PREROUTING -i someport --to-dst de:ad:00:be:ee:ff --dnat-target CONTINUE -nft add rule bridge nat PREROUTING iifname "someport" ether daddr set de:ad:0:be:ee:ff continue counter +ebtables-translate -t nat -A PREROUTING -i someport -j dnat --to-dst de:ad:00:be:ee:ff --dnat-target CONTINUE +nft 'add rule bridge nat PREROUTING iifname "someport" counter ether daddr set de:ad:0:be:ee:ff continue' diff --git a/extensions/libebt_ip.c b/extensions/libebt_ip.c index 51649ffb..68f34bff 100644 --- a/extensions/libebt_ip.c +++ b/extensions/libebt_ip.c @@ -20,40 +20,10 @@ #include <netdb.h> #include <inttypes.h> #include <xtables.h> +#include <linux/netfilter_bridge/ebt_ip.h> #include "libxt_icmp.h" -#define EBT_IP_SOURCE 0x01 -#define EBT_IP_DEST 0x02 -#define EBT_IP_TOS 0x04 -#define EBT_IP_PROTO 0x08 -#define EBT_IP_SPORT 0x10 -#define EBT_IP_DPORT 0x20 -#define EBT_IP_ICMP 0x40 -#define EBT_IP_IGMP 0x80 -#define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO |\ - EBT_IP_SPORT | EBT_IP_DPORT | EBT_IP_ICMP | EBT_IP_IGMP) - -struct ebt_ip_info { - __be32 saddr; - __be32 daddr; - __be32 smsk; - __be32 dmsk; - __u8 tos; - __u8 protocol; - __u8 bitmask; - __u8 invflags; - union { - __u16 sport[2]; - __u8 icmp_type[2]; - __u8 igmp_type[2]; - }; - union { - __u16 dport[2]; - __u8 icmp_code[2]; - }; -}; - #define IP_SOURCE '1' #define IP_DEST '2' #define IP_EBT_TOS '3' /* include/bits/in.h seems to already define IP_TOS */ @@ -80,68 +50,6 @@ static const struct option brip_opts[] = { XT_GETOPT_TABLEEND, }; -static const struct xt_icmp_names icmp_codes[] = { - { "echo-reply", 0, 0, 0xFF }, - /* Alias */ { "pong", 0, 0, 0xFF }, - - { "destination-unreachable", 3, 0, 0xFF }, - { "network-unreachable", 3, 0, 0 }, - { "host-unreachable", 3, 1, 1 }, - { "protocol-unreachable", 3, 2, 2 }, - { "port-unreachable", 3, 3, 3 }, - { "fragmentation-needed", 3, 4, 4 }, - { "source-route-failed", 3, 5, 5 }, - { "network-unknown", 3, 6, 6 }, - { "host-unknown", 3, 7, 7 }, - { "network-prohibited", 3, 9, 9 }, - { "host-prohibited", 3, 10, 10 }, - { "TOS-network-unreachable", 3, 11, 11 }, - { "TOS-host-unreachable", 3, 12, 12 }, - { "communication-prohibited", 3, 13, 13 }, - { "host-precedence-violation", 3, 14, 14 }, - { "precedence-cutoff", 3, 15, 15 }, - - { "source-quench", 4, 0, 0xFF }, - - { "redirect", 5, 0, 0xFF }, - { "network-redirect", 5, 0, 0 }, - { "host-redirect", 5, 1, 1 }, - { "TOS-network-redirect", 5, 2, 2 }, - { "TOS-host-redirect", 5, 3, 3 }, - - { "echo-request", 8, 0, 0xFF }, - /* Alias */ { "ping", 8, 0, 0xFF }, - - { "router-advertisement", 9, 0, 0xFF }, - - { "router-solicitation", 10, 0, 0xFF }, - - { "time-exceeded", 11, 0, 0xFF }, - /* Alias */ { "ttl-exceeded", 11, 0, 0xFF }, - { "ttl-zero-during-transit", 11, 0, 0 }, - { "ttl-zero-during-reassembly", 11, 1, 1 }, - - { "parameter-problem", 12, 0, 0xFF }, - { "ip-header-bad", 12, 0, 0 }, - { "required-option-missing", 12, 1, 1 }, - - { "timestamp-request", 13, 0, 0xFF }, - - { "timestamp-reply", 14, 0, 0xFF }, - - { "address-mask-request", 17, 0, 0xFF }, - - { "address-mask-reply", 18, 0, 0xFF } -}; - -static const struct xt_icmp_names igmp_types[] = { - { "membership-query", 0x11 }, - { "membership-report-v1", 0x12 }, - { "membership-report-v2", 0x16 }, - { "leave-group", 0x17 }, - { "membership-report-v3", 0x22 }, -}; - static void brip_print_help(void) { printf( @@ -194,156 +102,6 @@ parse_port_range(const char *protocol, const char *portstring, uint16_t *ports) } /* original code from ebtables: useful_functions.c */ -static int undot_ip(char *ip, unsigned char *ip2) -{ - char *p, *q, *end; - long int onebyte; - int i; - char buf[20]; - - strncpy(buf, ip, sizeof(buf) - 1); - - p = buf; - for (i = 0; i < 3; i++) { - if ((q = strchr(p, '.')) == NULL) - return -1; - *q = '\0'; - onebyte = strtol(p, &end, 10); - if (*end != '\0' || onebyte > 255 || onebyte < 0) - return -1; - ip2[i] = (unsigned char)onebyte; - p = q + 1; - } - - onebyte = strtol(p, &end, 10); - if (*end != '\0' || onebyte > 255 || onebyte < 0) - return -1; - ip2[3] = (unsigned char)onebyte; - - return 0; -} - -static int ip_mask(char *mask, unsigned char *mask2) -{ - char *end; - long int bits; - uint32_t mask22; - - if (undot_ip(mask, mask2)) { - /* not the /a.b.c.e format, maybe the /x format */ - bits = strtol(mask, &end, 10); - if (*end != '\0' || bits > 32 || bits < 0) - return -1; - if (bits != 0) { - mask22 = htonl(0xFFFFFFFF << (32 - bits)); - memcpy(mask2, &mask22, 4); - } else { - mask22 = 0xFFFFFFFF; - memcpy(mask2, &mask22, 4); - } - } - return 0; -} - -static void ebt_parse_ip_address(char *address, uint32_t *addr, uint32_t *msk) -{ - char *p; - - /* first the mask */ - if ((p = strrchr(address, '/')) != NULL) { - *p = '\0'; - if (ip_mask(p + 1, (unsigned char *)msk)) { - xtables_error(PARAMETER_PROBLEM, - "Problem with the IP mask '%s'", p + 1); - return; - } - } else - *msk = 0xFFFFFFFF; - - if (undot_ip(address, (unsigned char *)addr)) { - xtables_error(PARAMETER_PROBLEM, - "Problem with the IP address '%s'", address); - return; - } - *addr = *addr & *msk; -} - -static char *parse_range(const char *str, unsigned int res[]) -{ - char *next; - - if (!xtables_strtoui(str, &next, &res[0], 0, 255)) - return NULL; - - res[1] = res[0]; - if (*next == ':') { - str = next + 1; - if (!xtables_strtoui(str, &next, &res[1], 0, 255)) - return NULL; - } - - return next; -} - -static int ebt_parse_icmp(const struct xt_icmp_names *codes, size_t n_codes, - const char *icmptype, uint8_t type[], uint8_t code[]) -{ - unsigned int match = n_codes; - unsigned int i, number[2]; - - for (i = 0; i < n_codes; i++) { - if (strncasecmp(codes[i].name, icmptype, strlen(icmptype))) - continue; - if (match != n_codes) - xtables_error(PARAMETER_PROBLEM, "Ambiguous ICMP type `%s':" - " `%s' or `%s'?", - icmptype, codes[match].name, - codes[i].name); - match = i; - } - - if (match < n_codes) { - type[0] = type[1] = codes[match].type; - if (code) { - code[0] = codes[match].code_min; - code[1] = codes[match].code_max; - } - } else { - char *next = parse_range(icmptype, number); - if (!next) { - xtables_error(PARAMETER_PROBLEM, "Unknown ICMP type `%s'", - icmptype); - return -1; - } - - type[0] = (uint8_t) number[0]; - type[1] = (uint8_t) number[1]; - switch (*next) { - case 0: - if (code) { - code[0] = 0; - code[1] = 255; - } - return 0; - case '/': - if (code) { - next = parse_range(next+1, number); - code[0] = (uint8_t) number[0]; - code[1] = (uint8_t) number[1]; - if (next == NULL) - return -1; - if (next && *next == 0) - return 0; - } - /* fallthrough */ - default: - xtables_error(PARAMETER_PROBLEM, "unknown character %c", *next); - return -1; - } - } - return 0; -} - static void print_icmp_code(uint8_t *code) { if (!code) @@ -385,18 +143,26 @@ brip_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { struct ebt_ip_info *info = (struct ebt_ip_info *)(*match)->data; + struct in_addr *ipaddr, ipmask; + unsigned int ipnr; switch (c) { case IP_SOURCE: if (invert) info->invflags |= EBT_IP_SOURCE; - ebt_parse_ip_address(optarg, &info->saddr, &info->smsk); + xtables_ipparse_any(optarg, &ipaddr, &ipmask, &ipnr); + info->saddr = ipaddr->s_addr; + info->smsk = ipmask.s_addr; + free(ipaddr); info->bitmask |= EBT_IP_SOURCE; break; case IP_DEST: if (invert) info->invflags |= EBT_IP_DEST; - ebt_parse_ip_address(optarg, &info->daddr, &info->dmsk); + xtables_ipparse_any(optarg, &ipaddr, &ipmask, &ipnr); + info->daddr = ipaddr->s_addr; + info->dmsk = ipmask.s_addr; + free(ipaddr); info->bitmask |= EBT_IP_DEST; break; case IP_SPORT: @@ -414,15 +180,13 @@ brip_parse(int c, char **argv, int invert, unsigned int *flags, case IP_EBT_ICMP: if (invert) info->invflags |= EBT_IP_ICMP; - ebt_parse_icmp(icmp_codes, ARRAY_SIZE(icmp_codes), optarg, - info->icmp_type, info->icmp_code); + ebt_parse_icmp(optarg, info->icmp_type, info->icmp_code); info->bitmask |= EBT_IP_ICMP; break; case IP_EBT_IGMP: if (invert) info->invflags |= EBT_IP_IGMP; - ebt_parse_icmp(igmp_types, ARRAY_SIZE(igmp_types), optarg, - info->igmp_type, NULL); + ebt_parse_igmp(optarg, info->igmp_type); info->bitmask |= EBT_IP_IGMP; break; case IP_EBT_TOS: { @@ -668,6 +432,24 @@ static void brip_xlate_nh(struct xt_xlate *xl, xtables_ipmask_to_numeric(maskp)); } +static bool may_skip_ether_type_dep(uint8_t flags) +{ + /* these convert to "ip (s|d)addr" matches */ + if (flags & (EBT_IP_SOURCE | EBT_IP_DEST)) + return true; + + /* icmp match triggers implicit ether type dependency in nft */ + if (flags & EBT_IP_ICMP) + return true; + + /* allow if "ip protocol" match is created by brip_xlate() */ + if (flags & EBT_IP_PROTO && + !(flags & (EBT_IP_SPORT | EBT_IP_DPORT | EBT_IP_ICMP))) + return true; + + return false; +} + static int brip_xlate(struct xt_xlate *xl, const struct xt_xlate_mt_params *params) { @@ -677,11 +459,14 @@ static int brip_xlate(struct xt_xlate *xl, brip_xlate_nh(xl, info, EBT_IP_SOURCE); brip_xlate_nh(xl, info, EBT_IP_DEST); + if (!may_skip_ether_type_dep(info->bitmask)) + xt_xlate_add(xl, "ether type ip "); + if (info->bitmask & EBT_IP_TOS) { - xt_xlate_add(xl, "ip dscp "); + xt_xlate_add(xl, "@nh,8,8 "); if (info->invflags & EBT_IP_TOS) xt_xlate_add(xl, "!= "); - xt_xlate_add(xl, "0x%02x ", info->tos & 0x3f); /* remove ECN bits */ + xt_xlate_add(xl, "0x%02x ", info->tos); } if (info->bitmask & EBT_IP_PROTO) { struct protoent *pe; diff --git a/extensions/libebt_ip.txlate b/extensions/libebt_ip.txlate index b5882c34..44ce9276 100644 --- a/extensions/libebt_ip.txlate +++ b/extensions/libebt_ip.txlate @@ -1,26 +1,26 @@ ebtables-translate -A FORWARD -p ip --ip-src ! 192.168.0.0/24 -j ACCEPT -nft add rule bridge filter FORWARD ip saddr != 192.168.0.0/24 counter accept +nft 'add rule bridge filter FORWARD ip saddr != 192.168.0.0/24 counter accept' ebtables-translate -I FORWARD -p ip --ip-dst 10.0.0.1 -nft insert rule bridge filter FORWARD ip daddr 10.0.0.1 counter +nft 'insert rule bridge filter FORWARD ip daddr 10.0.0.1 counter' -ebtables-translate -I OUTPUT 3 -p ip -o eth0 --ip-tos 0xff -nft insert rule bridge filter OUTPUT oifname "eth0" ip dscp 0x3f counter +ebtables-translate -I OUTPUT -p ip -o eth0 --ip-tos 0xff +nft 'insert rule bridge filter OUTPUT oifname "eth0" ether type ip @nh,8,8 0xff counter' ebtables-translate -A FORWARD -p ip --ip-proto tcp --ip-dport 22 -nft add rule bridge filter FORWARD tcp dport 22 counter +nft 'add rule bridge filter FORWARD ether type ip tcp dport 22 counter' ebtables-translate -A FORWARD -p ip --ip-proto udp --ip-sport 1024:65535 -nft add rule bridge filter FORWARD udp sport 1024-65535 counter +nft 'add rule bridge filter FORWARD ether type ip udp sport 1024-65535 counter' ebtables-translate -A FORWARD -p ip --ip-proto 253 -nft add rule bridge filter FORWARD ip protocol 253 counter +nft 'add rule bridge filter FORWARD ip protocol 253 counter' ebtables-translate -A FORWARD -p ip --ip-protocol icmp --ip-icmp-type "echo-request" -nft add rule bridge filter FORWARD icmp type 8 counter +nft 'add rule bridge filter FORWARD icmp type 8 counter' ebtables-translate -A FORWARD -p ip --ip-proto icmp --ip-icmp-type 1/1 -nft add rule bridge filter FORWARD icmp type 1 icmp code 1 counter +nft 'add rule bridge filter FORWARD icmp type 1 icmp code 1 counter' ebtables-translate -A FORWARD -p ip --ip-protocol icmp --ip-icmp-type ! 1:10 -nft add rule bridge filter FORWARD icmp type != 1-10 counter +nft 'add rule bridge filter FORWARD icmp type != 1-10 counter' diff --git a/extensions/libebt_ip6.c b/extensions/libebt_ip6.c index a686a285..18bb2720 100644 --- a/extensions/libebt_ip6.c +++ b/extensions/libebt_ip6.c @@ -49,44 +49,6 @@ static const struct option brip6_opts[] = { XT_GETOPT_TABLEEND, }; -static const struct xt_icmp_names icmpv6_codes[] = { - { "destination-unreachable", 1, 0, 0xFF }, - { "no-route", 1, 0, 0 }, - { "communication-prohibited", 1, 1, 1 }, - { "address-unreachable", 1, 3, 3 }, - { "port-unreachable", 1, 4, 4 }, - - { "packet-too-big", 2, 0, 0xFF }, - - { "time-exceeded", 3, 0, 0xFF }, - /* Alias */ { "ttl-exceeded", 3, 0, 0xFF }, - { "ttl-zero-during-transit", 3, 0, 0 }, - { "ttl-zero-during-reassembly", 3, 1, 1 }, - - { "parameter-problem", 4, 0, 0xFF }, - { "bad-header", 4, 0, 0 }, - { "unknown-header-type", 4, 1, 1 }, - { "unknown-option", 4, 2, 2 }, - - { "echo-request", 128, 0, 0xFF }, - /* Alias */ { "ping", 128, 0, 0xFF }, - - { "echo-reply", 129, 0, 0xFF }, - /* Alias */ { "pong", 129, 0, 0xFF }, - - { "router-solicitation", 133, 0, 0xFF }, - - { "router-advertisement", 134, 0, 0xFF }, - - { "neighbour-solicitation", 135, 0, 0xFF }, - /* Alias */ { "neighbor-solicitation", 135, 0, 0xFF }, - - { "neighbour-advertisement", 136, 0, 0xFF }, - /* Alias */ { "neighbor-advertisement", 136, 0, 0xFF }, - - { "redirect", 137, 0, 0xFF }, -}; - static void parse_port_range(const char *protocol, const char *portstring, uint16_t *ports) { @@ -110,76 +72,6 @@ parse_port_range(const char *protocol, const char *portstring, uint16_t *ports) free(buffer); } -static char *parse_range(const char *str, unsigned int res[]) -{ - char *next; - - if (!xtables_strtoui(str, &next, &res[0], 0, 255)) - return NULL; - - res[1] = res[0]; - if (*next == ':') { - str = next + 1; - if (!xtables_strtoui(str, &next, &res[1], 0, 255)) - return NULL; - } - - return next; -} - -static int -parse_icmpv6(const char *icmpv6type, uint8_t type[], uint8_t code[]) -{ - static const unsigned int limit = ARRAY_SIZE(icmpv6_codes); - unsigned int match = limit; - unsigned int i, number[2]; - - for (i = 0; i < limit; i++) { - if (strncasecmp(icmpv6_codes[i].name, icmpv6type, strlen(icmpv6type))) - continue; - if (match != limit) - xtables_error(PARAMETER_PROBLEM, "Ambiguous ICMPv6 type `%s':" - " `%s' or `%s'?", - icmpv6type, icmpv6_codes[match].name, - icmpv6_codes[i].name); - match = i; - } - - if (match < limit) { - type[0] = type[1] = icmpv6_codes[match].type; - code[0] = icmpv6_codes[match].code_min; - code[1] = icmpv6_codes[match].code_max; - } else { - char *next = parse_range(icmpv6type, number); - if (!next) { - xtables_error(PARAMETER_PROBLEM, "Unknown ICMPv6 type `%s'", - icmpv6type); - return -1; - } - type[0] = (uint8_t) number[0]; - type[1] = (uint8_t) number[1]; - switch (*next) { - case 0: - code[0] = 0; - code[1] = 255; - return 0; - case '/': - next = parse_range(next+1, number); - code[0] = (uint8_t) number[0]; - code[1] = (uint8_t) number[1]; - if (next == NULL) - return -1; - if (next && *next == 0) - return 0; - /* fallthrough */ - default: - xtables_error(PARAMETER_PROBLEM, "unknown character %c", *next); - return -1; - } - } - return 0; -} - static void print_port_range(uint16_t *ports) { if (ports[0] == ports[1]) @@ -304,8 +196,7 @@ brip6_parse(int c, char **argv, int invert, unsigned int *flags, case IP_ICMP6: if (invert) info->invflags |= EBT_IP6_ICMP6; - if (parse_icmpv6(optarg, info->icmpv6_type, info->icmpv6_code)) - return 0; + ebt_parse_icmpv6(optarg, info->icmpv6_type, info->icmpv6_code); info->bitmask |= EBT_IP6_ICMP6; break; case IP_TCLASS: diff --git a/extensions/libebt_ip6.txlate b/extensions/libebt_ip6.txlate index 0271734c..0debbe12 100644 --- a/extensions/libebt_ip6.txlate +++ b/extensions/libebt_ip6.txlate @@ -1,29 +1,29 @@ ebtables-translate -A FORWARD -p ip6 --ip6-src ! dead::beef/64 -j ACCEPT -nft add rule bridge filter FORWARD ip6 saddr != dead::/64 counter accept +nft 'add rule bridge filter FORWARD ip6 saddr != dead::/64 counter accept' ebtables-translate -A FORWARD -p ip6 ! --ip6-dst dead:beef::/64 -j ACCEPT -nft add rule bridge filter FORWARD ip6 daddr != dead:beef::/64 counter accept +nft 'add rule bridge filter FORWARD ip6 daddr != dead:beef::/64 counter accept' ebtables-translate -I FORWARD -p ip6 --ip6-dst f00:ba:: -nft insert rule bridge filter FORWARD ip6 daddr f00:ba:: counter +nft 'insert rule bridge filter FORWARD ip6 daddr f00:ba:: counter' ebtables-translate -I OUTPUT -o eth0 -p ip6 --ip6-tclass 0xff -nft insert rule bridge filter OUTPUT oifname "eth0" ip6 dscp 0x3f counter +nft 'insert rule bridge filter OUTPUT oifname "eth0" ip6 dscp 0x3f counter' ebtables-translate -A FORWARD -p ip6 --ip6-proto tcp --ip6-dport 22 -nft add rule bridge filter FORWARD ether type ip6 tcp dport 22 counter +nft 'add rule bridge filter FORWARD ether type ip6 tcp dport 22 counter' ebtables-translate -A FORWARD -p ip6 --ip6-proto udp --ip6-sport 1024:65535 -nft add rule bridge filter FORWARD ether type ip6 udp sport 1024-65535 counter +nft 'add rule bridge filter FORWARD ether type ip6 udp sport 1024-65535 counter' ebtables-translate -A FORWARD -p ip6 --ip6-proto 253 -nft add rule bridge filter FORWARD ether type ip6 meta l4proto 253 counter +nft 'add rule bridge filter FORWARD ether type ip6 meta l4proto 253 counter' ebtables-translate -A FORWARD -p ip6 --ip6-protocol icmpv6 --ip6-icmp-type "echo-request" -nft add rule bridge filter FORWARD icmpv6 type 128 counter +nft 'add rule bridge filter FORWARD icmpv6 type 128 counter' ebtables-translate -A FORWARD -p ip6 --ip6-protocol icmpv6 --ip6-icmp-type 1/1 -nft add rule bridge filter FORWARD icmpv6 type 1 icmpv6 code 1 counter +nft 'add rule bridge filter FORWARD icmpv6 type 1 icmpv6 code 1 counter' ebtables-translate -A FORWARD -p ip6 --ip6-protocol icmpv6 --ip6-icmp-type ! 1:10 -nft add rule bridge filter FORWARD icmpv6 type != 1-10 counter +nft 'add rule bridge filter FORWARD icmpv6 type != 1-10 counter' diff --git a/extensions/libebt_limit.txlate b/extensions/libebt_limit.txlate index b6af15d5..adcce3ed 100644 --- a/extensions/libebt_limit.txlate +++ b/extensions/libebt_limit.txlate @@ -1,8 +1,8 @@ ebtables-translate -A INPUT --limit 3/m --limit-burst 3 -nft add rule bridge filter INPUT limit rate 3/minute burst 3 packets counter +nft 'add rule bridge filter INPUT limit rate 3/minute burst 3 packets counter' ebtables-translate -A INPUT --limit 10/s --limit-burst 5 -nft add rule bridge filter INPUT limit rate 10/second burst 5 packets counter +nft 'add rule bridge filter INPUT limit rate 10/second burst 5 packets counter' ebtables-translate -A INPUT --limit 10/s --limit-burst 0 -nft add rule bridge filter INPUT limit rate 10/second counter +nft 'add rule bridge filter INPUT limit rate 10/second counter' diff --git a/extensions/libebt_log.c b/extensions/libebt_log.c index 8858cf0e..9f8d1589 100644 --- a/extensions/libebt_log.c +++ b/extensions/libebt_log.c @@ -161,9 +161,10 @@ static void brlog_print(const void *ip, const struct xt_entry_target *target, { struct ebt_log_info *loginfo = (struct ebt_log_info *)target->data; - printf("--log-level %s --log-prefix \"%s\"", - eight_priority[loginfo->loglevel].c_name, - loginfo->prefix); + printf("--log-level %s", eight_priority[loginfo->loglevel].c_name); + + if (loginfo->prefix[0]) + printf(" --log-prefix \"%s\"", loginfo->prefix); if (loginfo->bitmask & EBT_LOG_IP) printf(" --log-ip"); @@ -180,16 +181,14 @@ static int brlog_xlate(struct xt_xlate *xl, const struct ebt_log_info *loginfo = (const void *)params->target->data; xt_xlate_add(xl, "log"); - if (loginfo->prefix[0]) { - if (params->escape_quotes) - xt_xlate_add(xl, " prefix \\\"%s\\\"", loginfo->prefix); - else - xt_xlate_add(xl, " prefix \"%s\"", loginfo->prefix); - } + if (loginfo->prefix[0]) + xt_xlate_add(xl, " prefix \"%s\"", loginfo->prefix); if (loginfo->loglevel != LOG_DEFAULT_LEVEL) xt_xlate_add(xl, " level %s", eight_priority[loginfo->loglevel].c_name); + /* ebt_log always decodes MAC header, nft_log always decodes upper header - + * so set flags ether and ignore EBT_LOG_IP, EBT_LOG_ARP and EBT_LOG_IP6 */ xt_xlate_add(xl, " flags ether "); return 1; @@ -198,6 +197,7 @@ static int brlog_xlate(struct xt_xlate *xl, static struct xtables_target brlog_target = { .name = "log", .revision = 0, + .ext_flags = XTABLES_EXT_WATCHER, .version = XTABLES_VERSION, .family = NFPROTO_BRIDGE, .size = XT_ALIGN(sizeof(struct ebt_log_info)), diff --git a/extensions/libebt_log.t b/extensions/libebt_log.t index a0df6169..e6adbd3b 100644 --- a/extensions/libebt_log.t +++ b/extensions/libebt_log.t @@ -1,6 +1,6 @@ :INPUT,FORWARD,OUTPUT ---log;=;OK +--log;--log-level notice;OK --log-level crit;=;OK ---log-level 1;--log-level alert --log-prefix "";OK ---log-level emerg --log-ip --log-arp --log-ip6;--log-level emerg --log-prefix "" --log-ip --log-arp --log-ip6 -j CONTINUE;OK +--log-level 1;--log-level alert;OK +--log-level emerg --log-ip --log-arp --log-ip6;=;OK --log-level crit --log-ip --log-arp --log-ip6 --log-prefix foo;--log-level crit --log-prefix "foo" --log-ip --log-arp --log-ip6 -j CONTINUE;OK diff --git a/extensions/libebt_log.txlate b/extensions/libebt_log.txlate index 7ef8d5e1..9847e4c1 100644 --- a/extensions/libebt_log.txlate +++ b/extensions/libebt_log.txlate @@ -1,15 +1,15 @@ ebtables-translate -A INPUT --log -nft add rule bridge filter INPUT log level notice flags ether counter +nft 'add rule bridge filter INPUT log level notice flags ether counter' ebtables-translate -A INPUT --log-level 1 -nft add rule bridge filter INPUT log level alert flags ether counter +nft 'add rule bridge filter INPUT log level alert flags ether counter' ebtables-translate -A INPUT --log-level crit -nft add rule bridge filter INPUT log level crit flags ether counter +nft 'add rule bridge filter INPUT log level crit flags ether counter' ebtables-translate -A INPUT --log-level emerg --log-ip --log-arp --log-ip6 -nft add rule bridge filter INPUT log level emerg flags ether counter +nft 'add rule bridge filter INPUT log level emerg flags ether counter' ebtables-translate -A INPUT --log-level crit --log-ip --log-arp --log-ip6 --log-prefix foo -nft add rule bridge filter INPUT log prefix "foo" level crit flags ether counter +nft 'add rule bridge filter INPUT log prefix "foo" level crit flags ether counter' diff --git a/extensions/libebt_mark.c b/extensions/libebt_mark.c index 423c5c91..40e49618 100644 --- a/extensions/libebt_mark.c +++ b/extensions/libebt_mark.c @@ -201,7 +201,7 @@ static int brmark_xlate(struct xt_xlate *xl, return 0; } - tmp = info->target & EBT_VERDICT_BITS; + tmp = info->target | ~EBT_VERDICT_BITS; xt_xlate_add(xl, "0x%lx %s ", info->mark, brmark_verdict(tmp)); return 1; } diff --git a/extensions/libebt_mark.txlate b/extensions/libebt_mark.txlate new file mode 100644 index 00000000..4ace1a1f --- /dev/null +++ b/extensions/libebt_mark.txlate @@ -0,0 +1,11 @@ +ebtables-translate -A INPUT -j mark --mark-set 42 +nft 'add rule bridge filter INPUT counter meta mark set 0x2a accept' + +ebtables-translate -A INPUT -j mark --mark-or 42 --mark-target RETURN +nft 'add rule bridge filter INPUT counter meta mark set meta mark or 0x2a return' + +ebtables-translate -A INPUT -j mark --mark-and 42 --mark-target ACCEPT +nft 'add rule bridge filter INPUT counter meta mark set meta mark and 0x2a accept' + +ebtables-translate -A INPUT -j mark --mark-xor 42 --mark-target DROP +nft 'add rule bridge filter INPUT counter meta mark set meta mark xor 0x2a drop' diff --git a/extensions/libebt_mark.xlate b/extensions/libebt_mark.xlate deleted file mode 100644 index e0982a1e..00000000 --- a/extensions/libebt_mark.xlate +++ /dev/null @@ -1,11 +0,0 @@ -ebtables-translate -A INPUT --mark-set 42 -nft add rule bridge filter INPUT mark set 0x2a counter - -ebtables-translate -A INPUT --mark-or 42 --mark-target RETURN -nft add rule bridge filter INPUT mark set mark or 0x2a counter return - -ebtables-translate -A INPUT --mark-and 42 --mark-target ACCEPT -nft add rule bridge filter INPUT mark set mark and 0x2a counter accept - -ebtables-translate -A INPUT --mark-xor 42 --mark-target DROP -nft add rule bridge filter INPUT mark set mark xor 0x2a counter drop diff --git a/extensions/libebt_mark_m.txlate b/extensions/libebt_mark_m.txlate index 7b44425b..2981a564 100644 --- a/extensions/libebt_mark_m.txlate +++ b/extensions/libebt_mark_m.txlate @@ -1,14 +1,14 @@ ebtables-translate -A INPUT --mark 42 -nft add rule bridge filter INPUT meta mark 0x2a counter +nft 'add rule bridge filter INPUT meta mark 0x2a counter' ebtables-translate -A INPUT ! --mark 42 -nft add rule bridge filter INPUT meta mark != 0x2a counter +nft 'add rule bridge filter INPUT meta mark != 0x2a counter' ebtables-translate -A INPUT --mark ! 42 -nft add rule bridge filter INPUT meta mark != 0x2a counter +nft 'add rule bridge filter INPUT meta mark != 0x2a counter' ebtables-translate -A INPUT --mark ! 0x1/0xff -nft add rule bridge filter INPUT meta mark and 0xff != 0x1 counter +nft 'add rule bridge filter INPUT meta mark and 0xff != 0x1 counter' ebtables-translate -A INPUT --mark /0x02 -nft add rule bridge filter INPUT meta mark and 0x2 != 0 counter +nft 'add rule bridge filter INPUT meta mark and 0x2 != 0 counter' diff --git a/extensions/libebt_nflog.c b/extensions/libebt_nflog.c index 9801f358..762d6d5d 100644 --- a/extensions/libebt_nflog.c +++ b/extensions/libebt_nflog.c @@ -130,12 +130,8 @@ static int brnflog_xlate(struct xt_xlate *xl, const struct ebt_nflog_info *info = (void *)params->target->data; xt_xlate_add(xl, "log "); - if (info->prefix[0] != '\0') { - if (params->escape_quotes) - xt_xlate_add(xl, "prefix \\\"%s\\\" ", info->prefix); - else - xt_xlate_add(xl, "prefix \"%s\" ", info->prefix); - } + if (info->prefix[0] != '\0') + xt_xlate_add(xl, "prefix \"%s\" ", info->prefix); xt_xlate_add(xl, "group %u ", info->group); @@ -150,6 +146,7 @@ static int brnflog_xlate(struct xt_xlate *xl, static struct xtables_target brnflog_watcher = { .name = "nflog", .revision = 0, + .ext_flags = XTABLES_EXT_WATCHER, .version = XTABLES_VERSION, .family = NFPROTO_BRIDGE, .size = XT_ALIGN(sizeof(struct ebt_nflog_info)), diff --git a/extensions/libebt_nflog.t b/extensions/libebt_nflog.t index f867df30..e98d8f5f 100644 --- a/extensions/libebt_nflog.t +++ b/extensions/libebt_nflog.t @@ -1,5 +1,5 @@ :INPUT,FORWARD,OUTPUT ---nflog;=;OK +--nflog;--nflog-group 1;OK --nflog-group 42;=;OK --nflog-range 42;--nflog-group 1 --nflog-range 42 -j CONTINUE;OK --nflog-threshold 100 --nflog-prefix foo;--nflog-prefix "foo" --nflog-group 1 --nflog-threshold 100 -j CONTINUE;OK diff --git a/extensions/libebt_nflog.txlate b/extensions/libebt_nflog.txlate index bc3f5364..6f292fd2 100644 --- a/extensions/libebt_nflog.txlate +++ b/extensions/libebt_nflog.txlate @@ -1,11 +1,11 @@ ebtables-translate -A INPUT --nflog -nft add rule bridge filter INPUT log group 1 counter +nft 'add rule bridge filter INPUT log group 1 counter' ebtables-translate -A INPUT --nflog-group 42 -nft add rule bridge filter INPUT log group 42 counter +nft 'add rule bridge filter INPUT log group 42 counter' ebtables-translate -A INPUT --nflog-range 42 -nft add rule bridge filter INPUT log group 1 snaplen 42 counter +nft 'add rule bridge filter INPUT log group 1 snaplen 42 counter' ebtables-translate -A INPUT --nflog-threshold 100 --nflog-prefix foo -nft add rule bridge filter INPUT log prefix "foo" group 1 queue-threshold 100 counter +nft 'add rule bridge filter INPUT log prefix "foo" group 1 queue-threshold 100 counter' diff --git a/extensions/libebt_pkttype.txlate b/extensions/libebt_pkttype.txlate index 94d016d9..6a828a98 100644 --- a/extensions/libebt_pkttype.txlate +++ b/extensions/libebt_pkttype.txlate @@ -1,20 +1,20 @@ ebtables-translate -A INPUT --pkttype-type host -nft add rule bridge filter INPUT meta pkttype host counter +nft 'add rule bridge filter INPUT meta pkttype host counter' ebtables-translate -A INPUT ! --pkttype-type broadcast -nft add rule bridge filter INPUT meta pkttype != broadcast counter +nft 'add rule bridge filter INPUT meta pkttype != broadcast counter' ebtables-translate -A INPUT --pkttype-type ! multicast -nft add rule bridge filter INPUT meta pkttype != multicast counter +nft 'add rule bridge filter INPUT meta pkttype != multicast counter' ebtables-translate -A INPUT --pkttype-type otherhost -nft add rule bridge filter INPUT meta pkttype other counter +nft 'add rule bridge filter INPUT meta pkttype other counter' ebtables-translate -A INPUT --pkttype-type outgoing -nft add rule bridge filter INPUT meta pkttype 4 counter +nft 'add rule bridge filter INPUT meta pkttype 4 counter' ebtables-translate -A INPUT --pkttype-type loopback -nft add rule bridge filter INPUT meta pkttype 5 counter +nft 'add rule bridge filter INPUT meta pkttype 5 counter' ebtables-translate -A INPUT --pkttype-type fastroute -nft add rule bridge filter INPUT meta pkttype 6 counter +nft 'add rule bridge filter INPUT meta pkttype 6 counter' diff --git a/extensions/libebt_redirect.c b/extensions/libebt_redirect.c index 6e653997..7821935e 100644 --- a/extensions/libebt_redirect.c +++ b/extensions/libebt_redirect.c @@ -83,10 +83,10 @@ static int brredir_xlate(struct xt_xlate *xl, { const struct ebt_redirect_info *red = (const void*)params->target->data; - xt_xlate_add(xl, "meta set pkttype host"); - if (red->target != EBT_ACCEPT) + xt_xlate_add(xl, "meta pkttype set host"); + if (red->target != EBT_CONTINUE) xt_xlate_add(xl, " %s ", brredir_verdict(red->target)); - return 0; + return 1; } static struct xtables_target brredirect_target = { diff --git a/extensions/libebt_redirect.t b/extensions/libebt_redirect.t index 23858afa..58492b79 100644 --- a/extensions/libebt_redirect.t +++ b/extensions/libebt_redirect.t @@ -1,4 +1,4 @@ :PREROUTING *nat --j redirect;=;OK +-j redirect ;=;OK -j redirect --redirect-target RETURN;=;OK diff --git a/extensions/libebt_redirect.txlate b/extensions/libebt_redirect.txlate new file mode 100644 index 00000000..d073ec77 --- /dev/null +++ b/extensions/libebt_redirect.txlate @@ -0,0 +1,8 @@ +ebtables-translate -t nat -A PREROUTING -d de:ad:00:00:be:ef -j redirect +nft 'add rule bridge nat PREROUTING ether daddr de:ad:00:00:be:ef counter meta pkttype set host accept' + +ebtables-translate -t nat -A PREROUTING -d de:ad:00:00:be:ef -j redirect --redirect-target RETURN +nft 'add rule bridge nat PREROUTING ether daddr de:ad:00:00:be:ef counter meta pkttype set host return' + +ebtables-translate -t nat -A PREROUTING -d de:ad:00:00:be:ef -j redirect --redirect-target CONTINUE +nft 'add rule bridge nat PREROUTING ether daddr de:ad:00:00:be:ef counter meta pkttype set host' diff --git a/extensions/libebt_snat.txlate b/extensions/libebt_snat.txlate index 0d846024..37343d3a 100644 --- a/extensions/libebt_snat.txlate +++ b/extensions/libebt_snat.txlate @@ -1,5 +1,5 @@ -ebtables-translate -t nat -A POSTROUTING -s 0:0:0:0:0:0 -o someport+ --to-source de:ad:00:be:ee:ff -nft add rule bridge nat POSTROUTING oifname "someport*" ether saddr 00:00:00:00:00:00 ether saddr set de:ad:0:be:ee:ff accept counter +ebtables-translate -t nat -A POSTROUTING -s 0:0:0:0:0:0 -o someport+ -j snat --to-source de:ad:00:be:ee:ff +nft 'add rule bridge nat POSTROUTING oifname "someport*" ether saddr 00:00:00:00:00:00 counter ether saddr set de:ad:0:be:ee:ff accept' -ebtables-translate -t nat -A POSTROUTING -o someport --to-src de:ad:00:be:ee:ff --snat-target CONTINUE -nft add rule bridge nat POSTROUTING oifname "someport" ether saddr set de:ad:0:be:ee:ff continue counter +ebtables-translate -t nat -A POSTROUTING -o someport -j snat --to-src de:ad:00:be:ee:ff --snat-target CONTINUE +nft 'add rule bridge nat POSTROUTING oifname "someport" counter ether saddr set de:ad:0:be:ee:ff continue' diff --git a/extensions/libebt_standard.t b/extensions/libebt_standard.t index c6c31727..370a12f4 100644 --- a/extensions/libebt_standard.t +++ b/extensions/libebt_standard.t @@ -12,12 +12,21 @@ :INPUT -i foobar;=;OK -o foobar;=;FAIL +--logical-in br0;=;OK +--logical-out br1;=;FAIL +-i + -d 00:0f:ee:d0:ba:be;-d 00:0f:ee:d0:ba:be;OK +-i + -p ip;-p IPv4;OK +--logical-in + -d 00:0f:ee:d0:ba:be;-d 00:0f:ee:d0:ba:be;OK +--logical-in + -p ip;-p IPv4;OK :FORWARD -i foobar;=;OK -o foobar;=;OK +--logical-in br0 --logical-out br1;=;OK :OUTPUT -i foobar;=;FAIL -o foobar;=;OK +--logical-in br0;=;FAIL +--logical-out br1;=;OK :PREROUTING *nat -i foobar;=;OK diff --git a/extensions/libebt_stp.c b/extensions/libebt_stp.c index 3e9e2447..41059baa 100644 --- a/extensions/libebt_stp.c +++ b/extensions/libebt_stp.c @@ -146,9 +146,9 @@ out: static void print_range(unsigned int l, unsigned int u) { if (l == u) - printf("%u ", l); + printf("%u", l); else - printf("%u:%u ", l, u); + printf("%u:%u", l, u); } static int diff --git a/extensions/libebt_stp.t b/extensions/libebt_stp.t index 0c6b77b9..17d6c1c0 100644 --- a/extensions/libebt_stp.t +++ b/extensions/libebt_stp.t @@ -1,7 +1,7 @@ :INPUT,FORWARD,OUTPUT --stp-type 1;=;OK --stp-flags 0x1;--stp-flags topology-change -j CONTINUE;OK ---stp-root-prio 1 -j ACCEPT;=;OK +--stp-root-prio 1 -j ACCEPT;=;OK --stp-root-addr 0d:ea:d0:0b:ee:f0;=;OK --stp-root-cost 1;=;OK --stp-sender-prio 1;=;OK diff --git a/extensions/libebt_vlan.t b/extensions/libebt_vlan.t index 81c79585..3ec05599 100644 --- a/extensions/libebt_vlan.t +++ b/extensions/libebt_vlan.t @@ -4,8 +4,8 @@ -p 802_1Q --vlan-prio 1;=;OK -p 802_1Q --vlan-prio ! 1;=;OK -p 802_1Q --vlan-encap ip;-p 802_1Q --vlan-encap 0800 -j CONTINUE;OK --p 802_1Q --vlan-encap 0800 ;=;OK --p 802_1Q --vlan-encap ! 0800 ;=;OK +-p 802_1Q --vlan-encap 0800;=;OK +-p 802_1Q --vlan-encap ! 0800;=;OK -p 802_1Q --vlan-encap IPv6 ! --vlan-id 1;-p 802_1Q --vlan-id ! 1 --vlan-encap 86DD -j CONTINUE;OK -p 802_1Q --vlan-id ! 1 --vlan-encap 86DD;=;OK --vlan-encap ip;=;FAIL diff --git a/extensions/libebt_vlan.txlate b/extensions/libebt_vlan.txlate index 2ab62d53..5d21e3eb 100644 --- a/extensions/libebt_vlan.txlate +++ b/extensions/libebt_vlan.txlate @@ -1,11 +1,11 @@ ebtables-translate -A INPUT -p 802_1Q --vlan-id 42 -nft add rule bridge filter INPUT vlan id 42 counter +nft 'add rule bridge filter INPUT vlan id 42 counter' ebtables-translate -A INPUT -p 802_1Q --vlan-prio ! 1 -nft add rule bridge filter INPUT vlan pcp != 1 counter +nft 'add rule bridge filter INPUT vlan pcp != 1 counter' ebtables-translate -A INPUT -p 802_1Q --vlan-encap ip -nft add rule bridge filter INPUT vlan type 0x0800 counter +nft 'add rule bridge filter INPUT vlan type 0x0800 counter' ebtables-translate -A INPUT -p 802_1Q --vlan-encap ipv6 ! --vlan-id 1 -nft add rule bridge filter INPUT vlan id != 1 vlan type 0x86dd counter +nft 'add rule bridge filter INPUT vlan id != 1 vlan type 0x86dd counter' diff --git a/extensions/libip6t_LOG.c b/extensions/libip6t_LOG.c deleted file mode 100644 index 40adc69d..00000000 --- a/extensions/libip6t_LOG.c +++ /dev/null @@ -1,250 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <syslog.h> -#include <xtables.h> -#include <linux/netfilter_ipv6/ip6t_LOG.h> - -#ifndef IP6T_LOG_UID /* Old kernel */ -#define IP6T_LOG_UID 0x08 -#undef IP6T_LOG_MASK -#define IP6T_LOG_MASK 0x0f -#endif - -#define LOG_DEFAULT_LEVEL LOG_WARNING - -enum { - O_LOG_LEVEL = 0, - O_LOG_PREFIX, - O_LOG_TCPSEQ, - O_LOG_TCPOPTS, - O_LOG_IPOPTS, - O_LOG_UID, - O_LOG_MAC, -}; - -static void LOG_help(void) -{ - printf( -"LOG target options:\n" -" --log-level level Level of logging (numeric or see syslog.conf)\n" -" --log-prefix prefix Prefix log messages with this prefix.\n" -" --log-tcp-sequence Log TCP sequence numbers.\n" -" --log-tcp-options Log TCP options.\n" -" --log-ip-options Log IP options.\n" -" --log-uid Log UID owning the local socket.\n" -" --log-macdecode Decode MAC addresses and protocol.\n"); -} - -#define s struct ip6t_log_info -static const struct xt_option_entry LOG_opts[] = { - {.name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL, - .flags = XTOPT_PUT, XTOPT_POINTER(s, level)}, - {.name = "log-prefix", .id = O_LOG_PREFIX, .type = XTTYPE_STRING, - .flags = XTOPT_PUT, XTOPT_POINTER(s, prefix), .min = 1}, - {.name = "log-tcp-sequence", .id = O_LOG_TCPSEQ, .type = XTTYPE_NONE}, - {.name = "log-tcp-options", .id = O_LOG_TCPOPTS, .type = XTTYPE_NONE}, - {.name = "log-ip-options", .id = O_LOG_IPOPTS, .type = XTTYPE_NONE}, - {.name = "log-uid", .id = O_LOG_UID, .type = XTTYPE_NONE}, - {.name = "log-macdecode", .id = O_LOG_MAC, .type = XTTYPE_NONE}, - XTOPT_TABLEEND, -}; -#undef s - -static void LOG_init(struct xt_entry_target *t) -{ - struct ip6t_log_info *loginfo = (struct ip6t_log_info *)t->data; - - loginfo->level = LOG_DEFAULT_LEVEL; - -} - -struct ip6t_log_names { - const char *name; - unsigned int level; -}; - -struct ip6t_log_xlate { - const char *name; - unsigned int level; -}; - -static const struct ip6t_log_names ip6t_log_names[] -= { { .name = "alert", .level = LOG_ALERT }, - { .name = "crit", .level = LOG_CRIT }, - { .name = "debug", .level = LOG_DEBUG }, - { .name = "emerg", .level = LOG_EMERG }, - { .name = "error", .level = LOG_ERR }, /* DEPRECATED */ - { .name = "info", .level = LOG_INFO }, - { .name = "notice", .level = LOG_NOTICE }, - { .name = "panic", .level = LOG_EMERG }, /* DEPRECATED */ - { .name = "warning", .level = LOG_WARNING } -}; - -static void LOG_parse(struct xt_option_call *cb) -{ - struct ip6t_log_info *info = cb->data; - - xtables_option_parse(cb); - switch (cb->entry->id) { - case O_LOG_PREFIX: - if (strchr(cb->arg, '\n') != NULL) - xtables_error(PARAMETER_PROBLEM, - "Newlines not allowed in --log-prefix"); - break; - case O_LOG_TCPSEQ: - info->logflags |= IP6T_LOG_TCPSEQ; - break; - case O_LOG_TCPOPTS: - info->logflags |= IP6T_LOG_TCPOPT; - break; - case O_LOG_IPOPTS: - info->logflags |= IP6T_LOG_IPOPT; - break; - case O_LOG_UID: - info->logflags |= IP6T_LOG_UID; - break; - case O_LOG_MAC: - info->logflags |= IP6T_LOG_MACDECODE; - break; - } -} - -static void LOG_print(const void *ip, const struct xt_entry_target *target, - int numeric) -{ - const struct ip6t_log_info *loginfo - = (const struct ip6t_log_info *)target->data; - unsigned int i = 0; - - printf(" LOG"); - if (numeric) - printf(" flags %u level %u", - loginfo->logflags, loginfo->level); - else { - for (i = 0; i < ARRAY_SIZE(ip6t_log_names); ++i) - if (loginfo->level == ip6t_log_names[i].level) { - printf(" level %s", ip6t_log_names[i].name); - break; - } - if (i == ARRAY_SIZE(ip6t_log_names)) - printf(" UNKNOWN level %u", loginfo->level); - if (loginfo->logflags & IP6T_LOG_TCPSEQ) - printf(" tcp-sequence"); - if (loginfo->logflags & IP6T_LOG_TCPOPT) - printf(" tcp-options"); - if (loginfo->logflags & IP6T_LOG_IPOPT) - printf(" ip-options"); - if (loginfo->logflags & IP6T_LOG_UID) - printf(" uid"); - if (loginfo->logflags & IP6T_LOG_MACDECODE) - printf(" macdecode"); - if (loginfo->logflags & ~(IP6T_LOG_MASK)) - printf(" unknown-flags"); - } - - if (strcmp(loginfo->prefix, "") != 0) - printf(" prefix \"%s\"", loginfo->prefix); -} - -static void LOG_save(const void *ip, const struct xt_entry_target *target) -{ - const struct ip6t_log_info *loginfo - = (const struct ip6t_log_info *)target->data; - - if (strcmp(loginfo->prefix, "") != 0) { - printf(" --log-prefix"); - xtables_save_string(loginfo->prefix); - } - - if (loginfo->level != LOG_DEFAULT_LEVEL) - printf(" --log-level %d", loginfo->level); - - if (loginfo->logflags & IP6T_LOG_TCPSEQ) - printf(" --log-tcp-sequence"); - if (loginfo->logflags & IP6T_LOG_TCPOPT) - printf(" --log-tcp-options"); - if (loginfo->logflags & IP6T_LOG_IPOPT) - printf(" --log-ip-options"); - if (loginfo->logflags & IP6T_LOG_UID) - printf(" --log-uid"); - if (loginfo->logflags & IP6T_LOG_MACDECODE) - printf(" --log-macdecode"); -} - -static const struct ip6t_log_xlate ip6t_log_xlate_names[] = { - {"alert", LOG_ALERT }, - {"crit", LOG_CRIT }, - {"debug", LOG_DEBUG }, - {"emerg", LOG_EMERG }, - {"err", LOG_ERR }, - {"info", LOG_INFO }, - {"notice", LOG_NOTICE }, - {"warn", LOG_WARNING } -}; - -static int LOG_xlate(struct xt_xlate *xl, - const struct xt_xlate_tg_params *params) -{ - const struct ip6t_log_info *loginfo = - (const struct ip6t_log_info *)params->target->data; - unsigned int i = 0; - - xt_xlate_add(xl, "log"); - if (strcmp(loginfo->prefix, "") != 0) { - if (params->escape_quotes) - xt_xlate_add(xl, " prefix \\\"%s\\\"", loginfo->prefix); - else - 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", - 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 = { - .name = "LOG", - .version = XTABLES_VERSION, - .family = NFPROTO_IPV6, - .size = XT_ALIGN(sizeof(struct ip6t_log_info)), - .userspacesize = XT_ALIGN(sizeof(struct ip6t_log_info)), - .help = LOG_help, - .init = LOG_init, - .print = LOG_print, - .save = LOG_save, - .x6_parse = LOG_parse, - .x6_options = LOG_opts, - .xlate = LOG_xlate, -}; - -void _init(void) -{ - xtables_register_target(&log_tg6_reg); -} diff --git a/extensions/libip6t_LOG.txlate b/extensions/libip6t_LOG.txlate index 2820a82c..29ffce72 100644 --- a/extensions/libip6t_LOG.txlate +++ b/extensions/libip6t_LOG.txlate @@ -1,8 +1,8 @@ iptables-translate -I INPUT -j LOG -nft insert rule ip filter INPUT counter log +nft 'insert rule ip filter INPUT counter log' ip6tables-translate -A FORWARD -p tcp -j LOG --log-level debug -nft add rule ip6 filter FORWARD meta l4proto tcp counter log level debug +nft 'add rule ip6 filter FORWARD meta l4proto tcp counter log level debug' ip6tables-translate -A FORWARD -p tcp -j LOG --log-prefix "Checking log" -nft add rule ip6 filter FORWARD meta l4proto tcp counter log prefix \"Checking log\" +nft 'add rule ip6 filter FORWARD meta l4proto tcp counter log prefix "Checking log"' diff --git a/extensions/libip6t_MASQUERADE.c b/extensions/libip6t_MASQUERADE.c deleted file mode 100644 index f28f071b..00000000 --- a/extensions/libip6t_MASQUERADE.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2011 Patrick McHardy <kaber@trash.net> - * - * Based on Rusty Russell's IPv4 MASQUERADE target. Development of IPv6 NAT - * funded by Astaro. - */ - -#include <stdio.h> -#include <netdb.h> -#include <string.h> -#include <stdlib.h> -#include <getopt.h> -#include <xtables.h> -#include <limits.h> /* INT_MAX in ip_tables.h */ -#include <linux/netfilter_ipv6/ip6_tables.h> -#include <linux/netfilter/nf_nat.h> - -enum { - O_TO_PORTS = 0, - O_RANDOM, - O_RANDOM_FULLY, -}; - -static void MASQUERADE_help(void) -{ - printf( -"MASQUERADE target options:\n" -" --to-ports <port>[-<port>]\n" -" Port (range) to map to.\n" -" --random\n" -" Randomize source port.\n" -" --random-fully\n" -" Fully randomize source port.\n"); -} - -static const struct xt_option_entry MASQUERADE_opts[] = { - {.name = "to-ports", .id = O_TO_PORTS, .type = XTTYPE_STRING}, - {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE}, - {.name = "random-fully", .id = O_RANDOM_FULLY, .type = XTTYPE_NONE}, - XTOPT_TABLEEND, -}; - -/* Parses ports */ -static void -parse_ports(const char *arg, struct nf_nat_range *r) -{ - char *end; - unsigned int port, maxport; - - r->flags |= NF_NAT_RANGE_PROTO_SPECIFIED; - - if (!xtables_strtoui(arg, &end, &port, 0, UINT16_MAX)) - xtables_param_act(XTF_BAD_VALUE, "MASQUERADE", "--to-ports", arg); - - switch (*end) { - case '\0': - r->min_proto.tcp.port - = r->max_proto.tcp.port - = htons(port); - return; - case '-': - if (!xtables_strtoui(end + 1, NULL, &maxport, 0, UINT16_MAX)) - break; - - if (maxport < port) - break; - - r->min_proto.tcp.port = htons(port); - r->max_proto.tcp.port = htons(maxport); - return; - default: - break; - } - xtables_param_act(XTF_BAD_VALUE, "MASQUERADE", "--to-ports", arg); -} - -static void MASQUERADE_parse(struct xt_option_call *cb) -{ - const struct ip6t_entry *entry = cb->xt_entry; - struct nf_nat_range *r = cb->data; - int portok; - - if (entry->ipv6.proto == IPPROTO_TCP || - entry->ipv6.proto == IPPROTO_UDP || - entry->ipv6.proto == IPPROTO_SCTP || - entry->ipv6.proto == IPPROTO_DCCP || - entry->ipv6.proto == IPPROTO_ICMP) - portok = 1; - else - portok = 0; - - xtables_option_parse(cb); - switch (cb->entry->id) { - case O_TO_PORTS: - if (!portok) - xtables_error(PARAMETER_PROBLEM, - "Need TCP, UDP, SCTP or DCCP with port specification"); - parse_ports(cb->arg, r); - break; - case O_RANDOM: - r->flags |= NF_NAT_RANGE_PROTO_RANDOM; - break; - case O_RANDOM_FULLY: - r->flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY; - break; - } -} - -static void -MASQUERADE_print(const void *ip, const struct xt_entry_target *target, - int numeric) -{ - const struct nf_nat_range *r = (const void *)target->data; - - if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) { - printf(" masq ports: "); - printf("%hu", ntohs(r->min_proto.tcp.port)); - if (r->max_proto.tcp.port != r->min_proto.tcp.port) - printf("-%hu", ntohs(r->max_proto.tcp.port)); - } - - if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) - printf(" random"); - - if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) - printf(" random-fully"); -} - -static void -MASQUERADE_save(const void *ip, const struct xt_entry_target *target) -{ - const struct nf_nat_range *r = (const void *)target->data; - - if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) { - printf(" --to-ports %hu", ntohs(r->min_proto.tcp.port)); - if (r->max_proto.tcp.port != r->min_proto.tcp.port) - printf("-%hu", ntohs(r->max_proto.tcp.port)); - } - - if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) - printf(" --random"); - - if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) - printf(" --random-fully"); -} - -static int MASQUERADE_xlate(struct xt_xlate *xl, - const struct xt_xlate_tg_params *params) -{ - const struct nf_nat_range *r = (const void *)params->target->data; - - xt_xlate_add(xl, "masquerade"); - - if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) { - xt_xlate_add(xl, " to :%hu", ntohs(r->min_proto.tcp.port)); - if (r->max_proto.tcp.port != r->min_proto.tcp.port) - xt_xlate_add(xl, "-%hu", ntohs(r->max_proto.tcp.port)); - } - - xt_xlate_add(xl, " "); - if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) - xt_xlate_add(xl, "random "); - - xt_xlate_add(xl, " "); - if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) - xt_xlate_add(xl, "fully-random "); - - return 1; -} - -static struct xtables_target masquerade_tg_reg = { - .name = "MASQUERADE", - .version = XTABLES_VERSION, - .family = NFPROTO_IPV6, - .size = XT_ALIGN(sizeof(struct nf_nat_range)), - .userspacesize = XT_ALIGN(sizeof(struct nf_nat_range)), - .help = MASQUERADE_help, - .x6_parse = MASQUERADE_parse, - .print = MASQUERADE_print, - .save = MASQUERADE_save, - .x6_options = MASQUERADE_opts, - .xlate = MASQUERADE_xlate, -}; - -void _init(void) -{ - xtables_register_target(&masquerade_tg_reg); -} diff --git a/extensions/libip6t_MASQUERADE.txlate b/extensions/libip6t_MASQUERADE.txlate index 6c289c2b..3f003477 100644 --- a/extensions/libip6t_MASQUERADE.txlate +++ b/extensions/libip6t_MASQUERADE.txlate @@ -1,8 +1,17 @@ ip6tables-translate -t nat -A POSTROUTING -j MASQUERADE -nft add rule ip6 nat POSTROUTING counter masquerade +nft 'add rule ip6 nat POSTROUTING counter masquerade' ip6tables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --to-ports 10 -nft add rule ip6 nat POSTROUTING meta l4proto tcp counter masquerade to :10 +nft 'add rule ip6 nat POSTROUTING meta l4proto tcp counter masquerade to :10' ip6tables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --to-ports 10-20 --random -nft add rule ip6 nat POSTROUTING meta l4proto tcp counter masquerade to :10-20 random +nft 'add rule ip6 nat POSTROUTING meta l4proto tcp counter masquerade to :10-20 random' + +ip6tables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --random +nft 'add rule ip6 nat POSTROUTING meta l4proto tcp counter masquerade random' + +ip6tables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --random-fully +nft 'add rule ip6 nat POSTROUTING meta l4proto tcp counter masquerade fully-random' + +ip6tables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --random --random-fully +nft 'add rule ip6 nat POSTROUTING meta l4proto tcp counter masquerade random,fully-random' diff --git a/extensions/libip6t_NETMAP.t b/extensions/libip6t_NETMAP.t index 043562d2..79d47bf6 100644 --- a/extensions/libip6t_NETMAP.t +++ b/extensions/libip6t_NETMAP.t @@ -1,4 +1,4 @@ :PREROUTING,INPUT,OUTPUT,POSTROUTING *nat -j NETMAP --to dead::/64;=;OK --j NETMAP --to dead::beef;=;OK +-j NETMAP --to dead::beef;-j NETMAP --to dead::beef/128;OK diff --git a/extensions/libip6t_REJECT.t b/extensions/libip6t_REJECT.t index d2b337d7..8294f0bb 100644 --- a/extensions/libip6t_REJECT.t +++ b/extensions/libip6t_REJECT.t @@ -1,5 +1,5 @@ :INPUT,FORWARD,OUTPUT --j REJECT;=;OK +-j REJECT;-j REJECT --reject-with icmp6-port-unreachable;OK # manpage for IPv6 variant of REJECT does not show up for some reason? -j REJECT --reject-with icmp6-no-route;=;OK -j REJECT --reject-with icmp6-adm-prohibited;=;OK diff --git a/extensions/libip6t_REJECT.txlate b/extensions/libip6t_REJECT.txlate index cfa35ebf..184713d1 100644 --- a/extensions/libip6t_REJECT.txlate +++ b/extensions/libip6t_REJECT.txlate @@ -1,8 +1,8 @@ ip6tables-translate -A FORWARD -p TCP --dport 22 -j REJECT -nft add rule ip6 filter FORWARD tcp dport 22 counter reject +nft 'add rule ip6 filter FORWARD tcp dport 22 counter reject' ip6tables-translate -A FORWARD -p TCP --dport 22 -j REJECT --reject-with icmp6-reject-route -nft add rule ip6 filter FORWARD tcp dport 22 counter reject with icmpv6 type reject-route +nft 'add rule ip6 filter FORWARD tcp dport 22 counter reject with icmpv6 type reject-route' ip6tables-translate -A FORWARD -p TCP --dport 22 -j REJECT --reject-with tcp-reset -nft add rule ip6 filter FORWARD tcp dport 22 counter reject with tcp reset +nft 'add rule ip6 filter FORWARD tcp dport 22 counter reject with tcp reset' diff --git a/extensions/libip6t_SNAT.c b/extensions/libip6t_SNAT.c deleted file mode 100644 index 4fe272b2..00000000 --- a/extensions/libip6t_SNAT.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (c) 2011 Patrick McHardy <kaber@trash.net> - * - * Based on Rusty Russell's IPv4 SNAT target. Development of IPv6 NAT - * funded by Astaro. - */ - -#include <stdio.h> -#include <netdb.h> -#include <string.h> -#include <stdlib.h> -#include <xtables.h> -#include <iptables.h> -#include <limits.h> /* INT_MAX in ip_tables.h */ -#include <linux/netfilter_ipv6/ip6_tables.h> -#include <linux/netfilter/nf_nat.h> - -enum { - O_TO_SRC = 0, - O_RANDOM, - O_RANDOM_FULLY, - O_PERSISTENT, - F_TO_SRC = 1 << O_TO_SRC, - F_RANDOM = 1 << O_RANDOM, - F_RANDOM_FULLY = 1 << O_RANDOM_FULLY, -}; - -static void SNAT_help(void) -{ - printf( -"SNAT target options:\n" -" --to-source [<ipaddr>[-<ipaddr>]][:port[-port]]\n" -" Address to map source to.\n" -"[--random] [--random-fully] [--persistent]\n"); -} - -static const struct xt_option_entry SNAT_opts[] = { - {.name = "to-source", .id = O_TO_SRC, .type = XTTYPE_STRING, - .flags = XTOPT_MAND}, - {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE}, - {.name = "random-fully", .id = O_RANDOM_FULLY, .type = XTTYPE_NONE}, - {.name = "persistent", .id = O_PERSISTENT, .type = XTTYPE_NONE}, - XTOPT_TABLEEND, -}; - -/* Ranges expected in network order. */ -static void -parse_to(const char *orig_arg, int portok, struct nf_nat_range *range) -{ - char *arg, *start, *end = NULL, *colon = NULL, *dash, *error; - const struct in6_addr *ip; - - arg = xtables_strdup(orig_arg); - - start = strchr(arg, '['); - if (start == NULL) { - start = arg; - /* Lets assume one colon is port information. Otherwise its an IPv6 address */ - colon = strchr(arg, ':'); - if (colon && strchr(colon+1, ':')) - colon = NULL; - } - else { - start++; - end = strchr(start, ']'); - if (end == NULL) - xtables_error(PARAMETER_PROBLEM, - "Invalid address format"); - - *end = '\0'; - colon = strchr(end + 1, ':'); - } - - if (colon) { - int port; - - if (!portok) - xtables_error(PARAMETER_PROBLEM, - "Need TCP, UDP, SCTP or DCCP with port specification"); - - range->flags |= NF_NAT_RANGE_PROTO_SPECIFIED; - - port = atoi(colon+1); - if (port <= 0 || port > 65535) - xtables_error(PARAMETER_PROBLEM, - "Port `%s' not valid\n", colon+1); - - error = strchr(colon+1, ':'); - if (error) - xtables_error(PARAMETER_PROBLEM, - "Invalid port:port syntax - use dash\n"); - - dash = strchr(colon, '-'); - if (!dash) { - range->min_proto.tcp.port - = range->max_proto.tcp.port - = htons(port); - } else { - int maxport; - - maxport = atoi(dash + 1); - if (maxport <= 0 || maxport > 65535) - xtables_error(PARAMETER_PROBLEM, - "Port `%s' not valid\n", dash+1); - if (maxport < port) - /* People are stupid. */ - xtables_error(PARAMETER_PROBLEM, - "Port range `%s' funky\n", colon+1); - range->min_proto.tcp.port = htons(port); - range->max_proto.tcp.port = htons(maxport); - } - /* Starts with colon or [] colon? No IP info...*/ - if (colon == arg || colon == arg+2) { - free(arg); - return; - } - *colon = '\0'; - } - - range->flags |= NF_NAT_RANGE_MAP_IPS; - dash = strchr(start, '-'); - if (colon && dash && dash > colon) - dash = NULL; - - if (dash) - *dash = '\0'; - - ip = xtables_numeric_to_ip6addr(start); - if (!ip) - xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n", - start); - range->min_addr.in6 = *ip; - if (dash) { - ip = xtables_numeric_to_ip6addr(dash + 1); - if (!ip) - xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n", - dash+1); - range->max_addr.in6 = *ip; - } else - range->max_addr = range->min_addr; - - free(arg); - return; -} - -static void SNAT_parse(struct xt_option_call *cb) -{ - const struct ip6t_entry *entry = cb->xt_entry; - struct nf_nat_range *range = cb->data; - int portok; - - if (entry->ipv6.proto == IPPROTO_TCP || - entry->ipv6.proto == IPPROTO_UDP || - entry->ipv6.proto == IPPROTO_SCTP || - entry->ipv6.proto == IPPROTO_DCCP || - entry->ipv6.proto == IPPROTO_ICMP) - portok = 1; - else - portok = 0; - - xtables_option_parse(cb); - switch (cb->entry->id) { - case O_TO_SRC: - parse_to(cb->arg, portok, range); - break; - case O_PERSISTENT: - range->flags |= NF_NAT_RANGE_PERSISTENT; - break; - } -} - -static void SNAT_fcheck(struct xt_fcheck_call *cb) -{ - static const unsigned int f = F_TO_SRC | F_RANDOM; - static const unsigned int r = F_TO_SRC | F_RANDOM_FULLY; - struct nf_nat_range *range = cb->data; - - if ((cb->xflags & f) == f) - range->flags |= NF_NAT_RANGE_PROTO_RANDOM; - if ((cb->xflags & r) == r) - range->flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY; -} - -static void print_range(const struct nf_nat_range *range) -{ - if (range->flags & NF_NAT_RANGE_MAP_IPS) { - if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) - printf("["); - printf("%s", xtables_ip6addr_to_numeric(&range->min_addr.in6)); - if (memcmp(&range->min_addr, &range->max_addr, - sizeof(range->min_addr))) - printf("-%s", xtables_ip6addr_to_numeric(&range->max_addr.in6)); - if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) - printf("]"); - } - if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) { - printf(":"); - printf("%hu", ntohs(range->min_proto.tcp.port)); - if (range->max_proto.tcp.port != range->min_proto.tcp.port) - printf("-%hu", ntohs(range->max_proto.tcp.port)); - } -} - -static void SNAT_print(const void *ip, const struct xt_entry_target *target, - int numeric) -{ - const struct nf_nat_range *range = (const void *)target->data; - - printf(" to:"); - print_range(range); - if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) - printf(" random"); - if (range->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) - printf(" random-fully"); - if (range->flags & NF_NAT_RANGE_PERSISTENT) - printf(" persistent"); -} - -static void SNAT_save(const void *ip, const struct xt_entry_target *target) -{ - const struct nf_nat_range *range = (const void *)target->data; - - printf(" --to-source "); - print_range(range); - if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) - printf(" --random"); - if (range->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) - printf(" --random-fully"); - if (range->flags & NF_NAT_RANGE_PERSISTENT) - printf(" --persistent"); -} - -static void print_range_xlate(const struct nf_nat_range *range, - struct xt_xlate *xl) -{ - bool proto_specified = range->flags & NF_NAT_RANGE_PROTO_SPECIFIED; - - if (range->flags & NF_NAT_RANGE_MAP_IPS) { - xt_xlate_add(xl, "%s%s%s", - proto_specified ? "[" : "", - xtables_ip6addr_to_numeric(&range->min_addr.in6), - proto_specified ? "]" : ""); - - if (memcmp(&range->min_addr, &range->max_addr, - sizeof(range->min_addr))) { - xt_xlate_add(xl, "-%s%s%s", - proto_specified ? "[" : "", - xtables_ip6addr_to_numeric(&range->max_addr.in6), - proto_specified ? "]" : ""); - } - } - if (proto_specified) { - xt_xlate_add(xl, ":%hu", ntohs(range->min_proto.tcp.port)); - - if (range->max_proto.tcp.port != range->min_proto.tcp.port) - xt_xlate_add(xl, "-%hu", - ntohs(range->max_proto.tcp.port)); - } -} - -static int SNAT_xlate(struct xt_xlate *xl, - const struct xt_xlate_tg_params *params) -{ - const struct nf_nat_range *range = (const void *)params->target->data; - bool sep_need = false; - const char *sep = " "; - - xt_xlate_add(xl, "snat to "); - print_range_xlate(range, xl); - if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) { - xt_xlate_add(xl, " random"); - sep_need = true; - } - if (range->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) { - if (sep_need) - sep = ","; - xt_xlate_add(xl, "%sfully-random", sep); - sep_need = true; - } - if (range->flags & NF_NAT_RANGE_PERSISTENT) { - if (sep_need) - sep = ","; - xt_xlate_add(xl, "%spersistent", sep); - } - - return 1; -} - -static struct xtables_target snat_tg_reg = { - .name = "SNAT", - .version = XTABLES_VERSION, - .family = NFPROTO_IPV6, - .revision = 1, - .size = XT_ALIGN(sizeof(struct nf_nat_range)), - .userspacesize = XT_ALIGN(sizeof(struct nf_nat_range)), - .help = SNAT_help, - .x6_parse = SNAT_parse, - .x6_fcheck = SNAT_fcheck, - .print = SNAT_print, - .save = SNAT_save, - .x6_options = SNAT_opts, - .xlate = SNAT_xlate, -}; - -void _init(void) -{ - xtables_register_target(&snat_tg_reg); -} diff --git a/extensions/libip6t_SNAT.t b/extensions/libip6t_SNAT.t index d188a6bb..98aa7602 100644 --- a/extensions/libip6t_SNAT.t +++ b/extensions/libip6t_SNAT.t @@ -4,6 +4,12 @@ -j SNAT --to-source dead::beef-dead::fee7;=;OK -j SNAT --to-source [dead::beef]:1025-65535;;FAIL -j SNAT --to-source [dead::beef] --to-source [dead::fee7];;FAIL +-j SNAT --to-source dead::beef --random;=;OK +-j SNAT --to-source dead::beef --random-fully;=;OK +-j SNAT --to-source dead::beef --persistent;=;OK +-j SNAT --to-source dead::beef --random --persistent;=;OK +-j SNAT --to-source dead::beef --random --random-fully;=;OK +-j SNAT --to-source dead::beef --random --random-fully --persistent;=;OK -p tcp -j SNAT --to-source [dead::beef]:1025-65535;=;OK -p tcp -j SNAT --to-source [dead::beef-dead::fee7]:1025-65535;=;OK -p tcp -j SNAT --to-source [dead::beef-dead::fee7]:1025-65536;;FAIL diff --git a/extensions/libip6t_SNAT.txlate b/extensions/libip6t_SNAT.txlate index 44f2fcea..e5f6f735 100644 --- a/extensions/libip6t_SNAT.txlate +++ b/extensions/libip6t_SNAT.txlate @@ -1,11 +1,11 @@ ip6tables-translate -t nat -A postrouting -o eth0 -p tcp -j SNAT --to [fec0::1234]:80 -nft add rule ip6 nat postrouting oifname "eth0" meta l4proto tcp counter snat to [fec0::1234]:80 +nft 'add rule ip6 nat postrouting oifname "eth0" meta l4proto tcp counter snat to [fec0::1234]:80' ip6tables-translate -t nat -A postrouting -o eth0 -p tcp -j SNAT --to [fec0::1234]:1-20 -nft add rule ip6 nat postrouting oifname "eth0" meta l4proto tcp counter snat to [fec0::1234]:1-20 +nft 'add rule ip6 nat postrouting oifname "eth0" meta l4proto tcp counter snat to [fec0::1234]:1-20' ip6tables-translate -t nat -A postrouting -o eth0 -p tcp -j SNAT --to [fec0::1234]:123 --random -nft add rule ip6 nat postrouting oifname "eth0" meta l4proto tcp counter snat to [fec0::1234]:123 random +nft 'add rule ip6 nat postrouting oifname "eth0" meta l4proto tcp counter snat to [fec0::1234]:123 random' ip6tables-translate -t nat -A postrouting -o eth0 -p tcp -j SNAT --to [fec0::1234]:123 --random-fully --persistent -nft add rule ip6 nat postrouting oifname "eth0" meta l4proto tcp counter snat to [fec0::1234]:123 fully-random,persistent +nft 'add rule ip6 nat postrouting oifname "eth0" meta l4proto tcp counter snat to [fec0::1234]:123 fully-random,persistent' diff --git a/extensions/libip6t_ah.txlate b/extensions/libip6t_ah.txlate index c6b09a2e..cc33ac27 100644 --- a/extensions/libip6t_ah.txlate +++ b/extensions/libip6t_ah.txlate @@ -1,17 +1,17 @@ ip6tables-translate -A INPUT -m ah --ahspi 500 -j DROP -nft add rule ip6 filter INPUT ah spi 500 counter drop +nft 'add rule ip6 filter INPUT ah spi 500 counter drop' ip6tables-translate -A INPUT -m ah --ahspi 500:550 -j DROP -nft add rule ip6 filter INPUT ah spi 500-550 counter drop +nft 'add rule ip6 filter INPUT ah spi 500-550 counter drop' ip6tables-translate -A INPUT -m ah ! --ahlen 120 -nft add rule ip6 filter INPUT ah hdrlength != 120 counter +nft 'add rule ip6 filter INPUT ah hdrlength != 120 counter' ip6tables-translate -A INPUT -m ah --ahres -nft add rule ip6 filter INPUT ah reserved 1 counter +nft 'add rule ip6 filter INPUT ah reserved 1 counter' ip6tables-translate -A INPUT -m ah --ahspi 500 ! --ahlen 120 -j DROP -nft add rule ip6 filter INPUT ah spi 500 ah hdrlength != 120 counter drop +nft 'add rule ip6 filter INPUT ah spi 500 ah hdrlength != 120 counter drop' ip6tables-translate -A INPUT -m ah --ahspi 500 --ahlen 120 --ahres -j ACCEPT -nft add rule ip6 filter INPUT ah spi 500 ah hdrlength 120 ah reserved 1 counter accept +nft 'add rule ip6 filter INPUT ah spi 500 ah hdrlength 120 ah reserved 1 counter accept' diff --git a/extensions/libip6t_dst.c b/extensions/libip6t_dst.c index bf0e3e43..baa010f5 100644 --- a/extensions/libip6t_dst.c +++ b/extensions/libip6t_dst.c @@ -125,15 +125,15 @@ static void print_options(unsigned int optsnr, uint16_t *optsp) { unsigned int i; + char sep = ' '; - printf(" "); for(i = 0; i < optsnr; i++) { - printf("%d", (optsp[i] & 0xFF00) >> 8); + printf("%c%d", sep, (optsp[i] & 0xFF00) >> 8); if ((optsp[i] & 0x00FF) != 0x00FF) printf(":%d", (optsp[i] & 0x00FF)); - printf("%c", (i != optsnr - 1) ? ',' : ' '); + sep = ','; } } diff --git a/extensions/libip6t_frag.c b/extensions/libip6t_frag.c index 3842496e..49c787e7 100644 --- a/extensions/libip6t_frag.c +++ b/extensions/libip6t_frag.c @@ -178,7 +178,6 @@ static int frag_xlate(struct xt_xlate *xl, { const struct ip6t_frag *fraginfo = (struct ip6t_frag *)params->match->data; - char *space= ""; if (!(fraginfo->ids[0] == 0 && fraginfo->ids[1] == 0xFFFFFFFF)) { xt_xlate_add(xl, "frag id %s", @@ -190,24 +189,21 @@ static int frag_xlate(struct xt_xlate *xl, else xt_xlate_add(xl, "%u", fraginfo->ids[0]); - space = " "; } - if (fraginfo->flags & IP6T_FRAG_RES) { - xt_xlate_add(xl, "%sfrag reserved 1", space); - space = " "; - } - if (fraginfo->flags & IP6T_FRAG_FST) { - xt_xlate_add(xl, "%sfrag frag-off 0", space); - space = " "; - } - if (fraginfo->flags & IP6T_FRAG_MF) { - xt_xlate_add(xl, "%sfrag more-fragments 1", space); - space = " "; - } - if (fraginfo->flags & IP6T_FRAG_NMF) { - xt_xlate_add(xl, "%sfrag more-fragments 0", space); - } + /* ignore ineffective IP6T_FRAG_LEN bit */ + + if (fraginfo->flags & IP6T_FRAG_RES) + xt_xlate_add(xl, "frag reserved 1"); + + if (fraginfo->flags & IP6T_FRAG_FST) + xt_xlate_add(xl, "frag frag-off 0"); + + if (fraginfo->flags & IP6T_FRAG_MF) + xt_xlate_add(xl, "frag more-fragments 1"); + + if (fraginfo->flags & IP6T_FRAG_NMF) + xt_xlate_add(xl, "frag more-fragments 0"); return 1; } diff --git a/extensions/libip6t_frag.txlate b/extensions/libip6t_frag.txlate index e8bd9d4b..33fc0631 100644 --- a/extensions/libip6t_frag.txlate +++ b/extensions/libip6t_frag.txlate @@ -1,17 +1,17 @@ ip6tables-translate -t filter -A INPUT -m frag --fragid 100:200 -j ACCEPT -nft add rule ip6 filter INPUT frag id 100-200 counter accept +nft 'add rule ip6 filter INPUT frag id 100-200 counter accept' ip6tables-translate -t filter -A INPUT -m frag --fragid 100 --fragres --fragmore -j ACCEPT -nft add rule ip6 filter INPUT frag id 100 frag reserved 1 frag more-fragments 1 counter accept +nft 'add rule ip6 filter INPUT frag id 100 frag reserved 1 frag more-fragments 1 counter accept' ip6tables-translate -t filter -A INPUT -m frag ! --fragid 100:200 -j ACCEPT -nft add rule ip6 filter INPUT frag id != 100-200 counter accept +nft 'add rule ip6 filter INPUT frag id != 100-200 counter accept' ip6tables-translate -t filter -A INPUT -m frag --fragid 100:200 --fraglast -j ACCEPT -nft add rule ip6 filter INPUT frag id 100-200 frag more-fragments 0 counter accept +nft 'add rule ip6 filter INPUT frag id 100-200 frag more-fragments 0 counter accept' ip6tables-translate -t filter -A INPUT -m frag --fragid 100:200 --fragfirst -j ACCEPT -nft add rule ip6 filter INPUT frag id 100-200 frag frag-off 0 counter accept +nft 'add rule ip6 filter INPUT frag id 100-200 frag frag-off 0 counter accept' ip6tables-translate -t filter -A INPUT -m frag --fraglast -j ACCEPT -nft add rule ip6 filter INPUT frag more-fragments 0 counter accept +nft 'add rule ip6 filter INPUT frag more-fragments 0 counter accept' diff --git a/extensions/libip6t_hbh.txlate b/extensions/libip6t_hbh.txlate index 28101fd7..a753df0d 100644 --- a/extensions/libip6t_hbh.txlate +++ b/extensions/libip6t_hbh.txlate @@ -1,5 +1,5 @@ ip6tables-translate -t filter -A INPUT -m hbh --hbh-len 22 -nft add rule ip6 filter INPUT hbh hdrlength 22 counter +nft 'add rule ip6 filter INPUT hbh hdrlength 22 counter' ip6tables-translate -t filter -A INPUT -m hbh ! --hbh-len 22 -nft add rule ip6 filter INPUT hbh hdrlength != 22 counter +nft 'add rule ip6 filter INPUT hbh hdrlength != 22 counter' diff --git a/extensions/libip6t_hl.txlate b/extensions/libip6t_hl.txlate index 17563938..9ff0df9c 100644 --- a/extensions/libip6t_hl.txlate +++ b/extensions/libip6t_hl.txlate @@ -1,5 +1,5 @@ ip6tables-translate -t nat -A postrouting -m hl --hl-gt 3 -nft add rule ip6 nat postrouting ip6 hoplimit gt 3 counter +nft 'add rule ip6 nat postrouting ip6 hoplimit gt 3 counter' ip6tables-translate -t nat -A postrouting -m hl ! --hl-eq 3 -nft add rule ip6 nat postrouting ip6 hoplimit != 3 counter +nft 'add rule ip6 nat postrouting ip6 hoplimit != 3 counter' diff --git a/extensions/libip6t_icmp6.c b/extensions/libip6t_icmp6.c index cc7bfaeb..439291ea 100644 --- a/extensions/libip6t_icmp6.c +++ b/extensions/libip6t_icmp6.c @@ -12,48 +12,6 @@ enum { O_ICMPV6_TYPE = 0, }; -static const struct xt_icmp_names icmpv6_codes[] = { - { "destination-unreachable", 1, 0, 0xFF }, - { "no-route", 1, 0, 0 }, - { "communication-prohibited", 1, 1, 1 }, - { "beyond-scope", 1, 2, 2 }, - { "address-unreachable", 1, 3, 3 }, - { "port-unreachable", 1, 4, 4 }, - { "failed-policy", 1, 5, 5 }, - { "reject-route", 1, 6, 6 }, - - { "packet-too-big", 2, 0, 0xFF }, - - { "time-exceeded", 3, 0, 0xFF }, - /* Alias */ { "ttl-exceeded", 3, 0, 0xFF }, - { "ttl-zero-during-transit", 3, 0, 0 }, - { "ttl-zero-during-reassembly", 3, 1, 1 }, - - { "parameter-problem", 4, 0, 0xFF }, - { "bad-header", 4, 0, 0 }, - { "unknown-header-type", 4, 1, 1 }, - { "unknown-option", 4, 2, 2 }, - - { "echo-request", 128, 0, 0xFF }, - /* Alias */ { "ping", 128, 0, 0xFF }, - - { "echo-reply", 129, 0, 0xFF }, - /* Alias */ { "pong", 129, 0, 0xFF }, - - { "router-solicitation", 133, 0, 0xFF }, - - { "router-advertisement", 134, 0, 0xFF }, - - { "neighbour-solicitation", 135, 0, 0xFF }, - /* Alias */ { "neighbor-solicitation", 135, 0, 0xFF }, - - { "neighbour-advertisement", 136, 0, 0xFF }, - /* Alias */ { "neighbor-advertisement", 136, 0, 0xFF }, - - { "redirect", 137, 0, 0xFF }, - -}; - static void icmp6_help(void) { printf( @@ -70,59 +28,6 @@ static const struct xt_option_entry icmp6_opts[] = { XTOPT_TABLEEND, }; -static void -parse_icmpv6(const char *icmpv6type, uint8_t *type, uint8_t code[]) -{ - static const unsigned int limit = ARRAY_SIZE(icmpv6_codes); - unsigned int match = limit; - unsigned int i; - - for (i = 0; i < limit; i++) { - if (strncasecmp(icmpv6_codes[i].name, icmpv6type, strlen(icmpv6type)) - == 0) { - if (match != limit) - xtables_error(PARAMETER_PROBLEM, - "Ambiguous ICMPv6 type `%s':" - " `%s' or `%s'?", - icmpv6type, - icmpv6_codes[match].name, - icmpv6_codes[i].name); - match = i; - } - } - - if (match != limit) { - *type = icmpv6_codes[match].type; - code[0] = icmpv6_codes[match].code_min; - code[1] = icmpv6_codes[match].code_max; - } else { - char *slash; - char buffer[strlen(icmpv6type) + 1]; - unsigned int number; - - strcpy(buffer, icmpv6type); - slash = strchr(buffer, '/'); - - if (slash) - *slash = '\0'; - - if (!xtables_strtoui(buffer, NULL, &number, 0, UINT8_MAX)) - xtables_error(PARAMETER_PROBLEM, - "Invalid ICMPv6 type `%s'\n", buffer); - *type = number; - if (slash) { - if (!xtables_strtoui(slash+1, NULL, &number, 0, UINT8_MAX)) - xtables_error(PARAMETER_PROBLEM, - "Invalid ICMPv6 code `%s'\n", - slash+1); - code[0] = code[1] = number; - } else { - code[0] = 0; - code[1] = 0xFF; - } - } -} - static void icmp6_init(struct xt_entry_match *m) { struct ip6t_icmp *icmpv6info = (struct ip6t_icmp *)m->data; @@ -135,7 +40,7 @@ static void icmp6_parse(struct xt_option_call *cb) struct ip6t_icmp *icmpv6info = cb->data; xtables_option_parse(cb); - parse_icmpv6(cb->arg, &icmpv6info->type, icmpv6info->code); + ipt_parse_icmpv6(cb->arg, &icmpv6info->type, icmpv6info->code); if (cb->invert) icmpv6info->invflags |= IP6T_ICMP_INV; } diff --git a/extensions/libip6t_icmp6.t b/extensions/libip6t_icmp6.t index 028cfc16..b9a4dcd3 100644 --- a/extensions/libip6t_icmp6.t +++ b/extensions/libip6t_icmp6.t @@ -4,3 +4,7 @@ -p ipv6-icmp -m icmp6 --icmpv6-type 2;=;OK # cannot use option twice: -p ipv6-icmp -m icmp6 --icmpv6-type no-route --icmpv6-type packet-too-big;;FAIL +-p ipv6-icmp -m icmp6 --icmpv6-type mld-listener-query;-p ipv6-icmp -m icmp6 --icmpv6-type 130;OK +-p ipv6-icmp -m icmp6 --icmpv6-type mld-listener-report;-p ipv6-icmp -m icmp6 --icmpv6-type 131;OK +-p ipv6-icmp -m icmp6 --icmpv6-type mld-listener-done;-p ipv6-icmp -m icmp6 --icmpv6-type 132;OK +-p ipv6-icmp -m icmp6 --icmpv6-type mld-listener-reduction;-p ipv6-icmp -m icmp6 --icmpv6-type 132;OK diff --git a/extensions/libip6t_icmp6.txlate b/extensions/libip6t_icmp6.txlate index 15481ad6..324a48b9 100644 --- a/extensions/libip6t_icmp6.txlate +++ b/extensions/libip6t_icmp6.txlate @@ -1,8 +1,8 @@ ip6tables-translate -t filter -A INPUT -m icmp6 --icmpv6-type 1 -j LOG -nft add rule ip6 filter INPUT icmpv6 type destination-unreachable counter log +nft 'add rule ip6 filter INPUT icmpv6 type destination-unreachable counter log' ip6tables-translate -t filter -A INPUT -m icmp6 --icmpv6-type neighbour-advertisement -j LOG -nft add rule ip6 filter INPUT icmpv6 type nd-neighbor-advert counter log +nft 'add rule ip6 filter INPUT icmpv6 type nd-neighbor-advert counter log' ip6tables-translate -t filter -A INPUT -m icmp6 ! --icmpv6-type packet-too-big -j LOG -nft add rule ip6 filter INPUT icmpv6 type != packet-too-big counter log +nft 'add rule ip6 filter INPUT icmpv6 type != packet-too-big counter log' diff --git a/extensions/libip6t_mh.c b/extensions/libip6t_mh.c index 64675405..1410d324 100644 --- a/extensions/libip6t_mh.c +++ b/extensions/libip6t_mh.c @@ -97,7 +97,7 @@ static unsigned int name_to_type(const char *name) if (!xtables_strtoui(name, NULL, &number, 0, UINT8_MAX)) xtables_error(PARAMETER_PROBLEM, - "Invalid MH type `%s'\n", name); + "Invalid MH type `%s'", name); return number; } } diff --git a/extensions/libip6t_mh.txlate b/extensions/libip6t_mh.txlate index f5d638c0..4dfaf46a 100644 --- a/extensions/libip6t_mh.txlate +++ b/extensions/libip6t_mh.txlate @@ -1,5 +1,5 @@ ip6tables-translate -A INPUT -p mh --mh-type 1 -j ACCEPT -nft add rule ip6 filter INPUT meta l4proto mobility-header mh type 1 counter accept +nft 'add rule ip6 filter INPUT meta l4proto mobility-header mh type 1 counter accept' ip6tables-translate -A INPUT -p mh --mh-type 1:3 -j ACCEPT -nft add rule ip6 filter INPUT meta l4proto mobility-header mh type 1-3 counter accept +nft 'add rule ip6 filter INPUT meta l4proto mobility-header mh type 1-3 counter accept' diff --git a/extensions/libip6t_rt.c b/extensions/libip6t_rt.c index 9708b5a0..d5b0458b 100644 --- a/extensions/libip6t_rt.c +++ b/extensions/libip6t_rt.c @@ -248,17 +248,15 @@ static int rt_xlate(struct xt_xlate *xl, const struct xt_xlate_mt_params *params) { const struct ip6t_rt *rtinfo = (struct ip6t_rt *)params->match->data; - char *space = ""; if (rtinfo->flags & IP6T_RT_TYP) { xt_xlate_add(xl, "rt type%s %u", (rtinfo->invflags & IP6T_RT_INV_TYP) ? " !=" : "", rtinfo->rt_type); - space = " "; } if (!(rtinfo->segsleft[0] == 0 && rtinfo->segsleft[1] == 0xFFFFFFFF)) { - xt_xlate_add(xl, "%srt seg-left%s ", space, + xt_xlate_add(xl, "rt seg-left%s ", (rtinfo->invflags & IP6T_RT_INV_SGS) ? " !=" : ""); if (rtinfo->segsleft[0] != rtinfo->segsleft[1]) @@ -266,11 +264,10 @@ static int rt_xlate(struct xt_xlate *xl, rtinfo->segsleft[1]); else xt_xlate_add(xl, "%u", rtinfo->segsleft[0]); - space = " "; } if (rtinfo->flags & IP6T_RT_LEN) { - xt_xlate_add(xl, "%srt hdrlength%s %u", space, + xt_xlate_add(xl, "rt hdrlength%s %u", (rtinfo->invflags & IP6T_RT_INV_LEN) ? " !=" : "", rtinfo->hdrlen); } diff --git a/extensions/libip6t_rt.txlate b/extensions/libip6t_rt.txlate index 6464cf9e..3578bcba 100644 --- a/extensions/libip6t_rt.txlate +++ b/extensions/libip6t_rt.txlate @@ -1,14 +1,14 @@ ip6tables-translate -A INPUT -m rt --rt-type 0 -j DROP -nft add rule ip6 filter INPUT rt type 0 counter drop +nft 'add rule ip6 filter INPUT rt type 0 counter drop' ip6tables-translate -A INPUT -m rt ! --rt-len 22 -j DROP -nft add rule ip6 filter INPUT rt hdrlength != 22 counter drop +nft 'add rule ip6 filter INPUT rt hdrlength != 22 counter drop' ip6tables-translate -A INPUT -m rt --rt-segsleft 26 -j ACCEPT -nft add rule ip6 filter INPUT rt seg-left 26 counter accept +nft 'add rule ip6 filter INPUT rt seg-left 26 counter accept' ip6tables-translate -A INPUT -m rt --rt-type 0 --rt-len 22 -j DROP -nft add rule ip6 filter INPUT rt type 0 rt hdrlength 22 counter drop +nft 'add rule ip6 filter INPUT rt type 0 rt hdrlength 22 counter drop' ip6tables-translate -A INPUT -m rt --rt-type 0 --rt-len 22 ! --rt-segsleft 26 -j ACCEPT -nft add rule ip6 filter INPUT rt type 0 rt seg-left != 26 rt hdrlength 22 counter accept +nft 'add rule ip6 filter INPUT rt type 0 rt seg-left != 26 rt hdrlength 22 counter accept' diff --git a/extensions/libip6t_standard.t b/extensions/libip6t_standard.t index a528af10..0c559cc5 100644 --- a/extensions/libip6t_standard.t +++ b/extensions/libip6t_standard.t @@ -3,3 +3,6 @@ ! -d ::;! -d ::/128;OK ! -s ::;! -s ::/128;OK -s ::/64;=;OK +:INPUT +-i + -d c0::fe;-d c0::fe/128;OK +-i + -p tcp;-p tcp;OK diff --git a/extensions/libipt_CLUSTERIP.c b/extensions/libipt_CLUSTERIP.c index f4b638b2..b207cde3 100644 --- a/extensions/libipt_CLUSTERIP.c +++ b/extensions/libipt_CLUSTERIP.c @@ -87,12 +87,13 @@ static void CLUSTERIP_parse(struct xt_option_call *cb) else if (strcmp(cb->arg, "sourceip-sourceport-destport") == 0) cipinfo->hash_mode = CLUSTERIP_HASHMODE_SIP_SPT_DPT; else - xtables_error(PARAMETER_PROBLEM, "Unknown hashmode \"%s\"\n", - cb->arg); + xtables_error(PARAMETER_PROBLEM, + "Unknown hashmode \"%s\"", cb->arg); break; case O_CLUSTERMAC: if (!(cipinfo->clustermac[0] & 0x01)) - xtables_error(PARAMETER_PROBLEM, "MAC has to be a multicast ethernet address\n"); + xtables_error(PARAMETER_PROBLEM, + "MAC has to be a multicast ethernet address"); break; case O_LOCAL_NODE: cipinfo->num_local_nodes = 1; @@ -107,7 +108,8 @@ static void CLUSTERIP_check(struct xt_fcheck_call *cb) if ((cb->xflags & F_FULL) == F_FULL) return; - xtables_error(PARAMETER_PROBLEM, "CLUSTERIP target: Invalid parameter combination\n"); + xtables_error(PARAMETER_PROBLEM, + "CLUSTERIP target: Invalid parameter combination"); } static const char *hashmode2str(enum clusterip_hashmode mode) diff --git a/extensions/libipt_CLUSTERIP.t b/extensions/libipt_CLUSTERIP.t deleted file mode 100644 index 30b80167..00000000 --- a/extensions/libipt_CLUSTERIP.t +++ /dev/null @@ -1,4 +0,0 @@ -:INPUT --d 10.31.3.236/32 -i lo -j CLUSTERIP --new --hashmode sourceip --clustermac 01:AA:7B:47:F7:D7 --total-nodes 2 --local-node 0 --hash-init 1;=;FAIL --d 10.31.3.236/32 -i lo -j CLUSTERIP --new --hashmode sourceip --clustermac 01:AA:7B:47:F7:D7 --total-nodes 2 --local-node 1 --hash-init 1;=;OK;LEGACY --d 10.31.3.236/32 -i lo -j CLUSTERIP --new --hashmode sourceip --clustermac 01:AA:7B:47:F7:D7 --total-nodes 2 --local-node 2 --hash-init 1;=;OK;LEGACY diff --git a/extensions/libipt_LOG.c b/extensions/libipt_LOG.c deleted file mode 100644 index 36e2e73b..00000000 --- a/extensions/libipt_LOG.c +++ /dev/null @@ -1,250 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <syslog.h> -#include <xtables.h> -#include <linux/netfilter_ipv4/ipt_LOG.h> - -#define LOG_DEFAULT_LEVEL LOG_WARNING - -#ifndef IPT_LOG_UID /* Old kernel */ -#define IPT_LOG_UID 0x08 /* Log UID owning local socket */ -#undef IPT_LOG_MASK -#define IPT_LOG_MASK 0x0f -#endif - -enum { - O_LOG_LEVEL = 0, - O_LOG_PREFIX, - O_LOG_TCPSEQ, - O_LOG_TCPOPTS, - O_LOG_IPOPTS, - O_LOG_UID, - O_LOG_MAC, -}; - -static void LOG_help(void) -{ - printf( -"LOG target options:\n" -" --log-level level Level of logging (numeric or see syslog.conf)\n" -" --log-prefix prefix Prefix log messages with this prefix.\n\n" -" --log-tcp-sequence Log TCP sequence numbers.\n\n" -" --log-tcp-options Log TCP options.\n\n" -" --log-ip-options Log IP options.\n\n" -" --log-uid Log UID owning the local socket.\n\n" -" --log-macdecode Decode MAC addresses and protocol.\n\n"); -} - -#define s struct ipt_log_info -static const struct xt_option_entry LOG_opts[] = { - {.name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL, - .flags = XTOPT_PUT, XTOPT_POINTER(s, level)}, - {.name = "log-prefix", .id = O_LOG_PREFIX, .type = XTTYPE_STRING, - .flags = XTOPT_PUT, XTOPT_POINTER(s, prefix), .min = 1}, - {.name = "log-tcp-sequence", .id = O_LOG_TCPSEQ, .type = XTTYPE_NONE}, - {.name = "log-tcp-options", .id = O_LOG_TCPOPTS, .type = XTTYPE_NONE}, - {.name = "log-ip-options", .id = O_LOG_IPOPTS, .type = XTTYPE_NONE}, - {.name = "log-uid", .id = O_LOG_UID, .type = XTTYPE_NONE}, - {.name = "log-macdecode", .id = O_LOG_MAC, .type = XTTYPE_NONE}, - XTOPT_TABLEEND, -}; -#undef s - -static void LOG_init(struct xt_entry_target *t) -{ - struct ipt_log_info *loginfo = (struct ipt_log_info *)t->data; - - loginfo->level = LOG_DEFAULT_LEVEL; - -} - -struct ipt_log_names { - const char *name; - unsigned int level; -}; - -struct ipt_log_xlate { - const char *name; - unsigned int level; -}; - -static const struct ipt_log_names ipt_log_names[] -= { { .name = "alert", .level = LOG_ALERT }, - { .name = "crit", .level = LOG_CRIT }, - { .name = "debug", .level = LOG_DEBUG }, - { .name = "emerg", .level = LOG_EMERG }, - { .name = "error", .level = LOG_ERR }, /* DEPRECATED */ - { .name = "info", .level = LOG_INFO }, - { .name = "notice", .level = LOG_NOTICE }, - { .name = "panic", .level = LOG_EMERG }, /* DEPRECATED */ - { .name = "warning", .level = LOG_WARNING } -}; - -static void LOG_parse(struct xt_option_call *cb) -{ - struct ipt_log_info *info = cb->data; - - xtables_option_parse(cb); - switch (cb->entry->id) { - case O_LOG_PREFIX: - if (strchr(cb->arg, '\n') != NULL) - xtables_error(PARAMETER_PROBLEM, - "Newlines not allowed in --log-prefix"); - break; - case O_LOG_TCPSEQ: - info->logflags |= IPT_LOG_TCPSEQ; - break; - case O_LOG_TCPOPTS: - info->logflags |= IPT_LOG_TCPOPT; - break; - case O_LOG_IPOPTS: - info->logflags |= IPT_LOG_IPOPT; - break; - case O_LOG_UID: - info->logflags |= IPT_LOG_UID; - break; - case O_LOG_MAC: - info->logflags |= IPT_LOG_MACDECODE; - break; - } -} - -static void LOG_print(const void *ip, const struct xt_entry_target *target, - int numeric) -{ - const struct ipt_log_info *loginfo - = (const struct ipt_log_info *)target->data; - unsigned int i = 0; - - printf(" LOG"); - if (numeric) - printf(" flags %u level %u", - loginfo->logflags, loginfo->level); - else { - for (i = 0; i < ARRAY_SIZE(ipt_log_names); ++i) - if (loginfo->level == ipt_log_names[i].level) { - printf(" level %s", ipt_log_names[i].name); - break; - } - if (i == ARRAY_SIZE(ipt_log_names)) - printf(" UNKNOWN level %u", loginfo->level); - if (loginfo->logflags & IPT_LOG_TCPSEQ) - printf(" tcp-sequence"); - if (loginfo->logflags & IPT_LOG_TCPOPT) - printf(" tcp-options"); - if (loginfo->logflags & IPT_LOG_IPOPT) - printf(" ip-options"); - if (loginfo->logflags & IPT_LOG_UID) - printf(" uid"); - if (loginfo->logflags & IPT_LOG_MACDECODE) - printf(" macdecode"); - if (loginfo->logflags & ~(IPT_LOG_MASK)) - printf(" unknown-flags"); - } - - if (strcmp(loginfo->prefix, "") != 0) - printf(" prefix \"%s\"", loginfo->prefix); -} - -static void LOG_save(const void *ip, const struct xt_entry_target *target) -{ - const struct ipt_log_info *loginfo - = (const struct ipt_log_info *)target->data; - - if (strcmp(loginfo->prefix, "") != 0) { - printf(" --log-prefix"); - xtables_save_string(loginfo->prefix); - } - - if (loginfo->level != LOG_DEFAULT_LEVEL) - printf(" --log-level %d", loginfo->level); - - if (loginfo->logflags & IPT_LOG_TCPSEQ) - printf(" --log-tcp-sequence"); - if (loginfo->logflags & IPT_LOG_TCPOPT) - printf(" --log-tcp-options"); - if (loginfo->logflags & IPT_LOG_IPOPT) - printf(" --log-ip-options"); - if (loginfo->logflags & IPT_LOG_UID) - printf(" --log-uid"); - if (loginfo->logflags & IPT_LOG_MACDECODE) - printf(" --log-macdecode"); -} - -static const struct ipt_log_xlate ipt_log_xlate_names[] = { - {"alert", LOG_ALERT }, - {"crit", LOG_CRIT }, - {"debug", LOG_DEBUG }, - {"emerg", LOG_EMERG }, - {"err", LOG_ERR }, - {"info", LOG_INFO }, - {"notice", LOG_NOTICE }, - {"warn", LOG_WARNING } -}; - -static int LOG_xlate(struct xt_xlate *xl, - const struct xt_xlate_tg_params *params) -{ - const struct ipt_log_info *loginfo = - (const struct ipt_log_info *)params->target->data; - unsigned int i = 0; - - xt_xlate_add(xl, "log"); - if (strcmp(loginfo->prefix, "") != 0) { - if (params->escape_quotes) - xt_xlate_add(xl, " prefix \\\"%s\\\"", loginfo->prefix); - else - 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", - 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 = { - .name = "LOG", - .version = XTABLES_VERSION, - .family = NFPROTO_IPV4, - .size = XT_ALIGN(sizeof(struct ipt_log_info)), - .userspacesize = XT_ALIGN(sizeof(struct ipt_log_info)), - .help = LOG_help, - .init = LOG_init, - .print = LOG_print, - .save = LOG_save, - .x6_parse = LOG_parse, - .x6_options = LOG_opts, - .xlate = LOG_xlate, -}; - -void _init(void) -{ - xtables_register_target(&log_tg_reg); -} diff --git a/extensions/libipt_LOG.txlate b/extensions/libipt_LOG.txlate index 81f64fb2..13a2ef55 100644 --- a/extensions/libipt_LOG.txlate +++ b/extensions/libipt_LOG.txlate @@ -1,5 +1,5 @@ iptables-translate -A FORWARD -p tcp -j LOG --log-level error -nft add rule ip filter FORWARD ip protocol tcp counter log level err +nft 'add rule ip filter FORWARD ip protocol tcp counter log level err' iptables-translate -A FORWARD -p tcp -j LOG --log-prefix "Random prefix" -nft add rule ip filter FORWARD ip protocol tcp counter log prefix \"Random prefix\" +nft 'add rule ip filter FORWARD ip protocol tcp counter log prefix "Random prefix"' diff --git a/extensions/libipt_MASQUERADE.c b/extensions/libipt_MASQUERADE.c deleted file mode 100644 index 90bf6065..00000000 --- a/extensions/libipt_MASQUERADE.c +++ /dev/null @@ -1,190 +0,0 @@ -#include <stdio.h> -#include <netdb.h> -#include <string.h> -#include <stdlib.h> -#include <getopt.h> -#include <xtables.h> -#include <limits.h> /* INT_MAX in ip_tables.h */ -#include <linux/netfilter_ipv4/ip_tables.h> -#include <linux/netfilter/nf_nat.h> - -enum { - O_TO_PORTS = 0, - O_RANDOM, - O_RANDOM_FULLY, -}; - -static void MASQUERADE_help(void) -{ - printf( -"MASQUERADE target options:\n" -" --to-ports <port>[-<port>]\n" -" Port (range) to map to.\n" -" --random\n" -" Randomize source port.\n" -" --random-fully\n" -" Fully randomize source port.\n"); -} - -static const struct xt_option_entry MASQUERADE_opts[] = { - {.name = "to-ports", .id = O_TO_PORTS, .type = XTTYPE_STRING}, - {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE}, - {.name = "random-fully", .id = O_RANDOM_FULLY, .type = XTTYPE_NONE}, - XTOPT_TABLEEND, -}; - -static void MASQUERADE_init(struct xt_entry_target *t) -{ - struct nf_nat_ipv4_multi_range_compat *mr = (struct nf_nat_ipv4_multi_range_compat *)t->data; - - /* Actually, it's 0, but it's ignored at the moment. */ - mr->rangesize = 1; -} - -/* Parses ports */ -static void -parse_ports(const char *arg, struct nf_nat_ipv4_multi_range_compat *mr) -{ - char *end; - unsigned int port, maxport; - - mr->range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED; - - if (!xtables_strtoui(arg, &end, &port, 0, UINT16_MAX)) - xtables_param_act(XTF_BAD_VALUE, "MASQUERADE", "--to-ports", arg); - - switch (*end) { - case '\0': - mr->range[0].min.tcp.port - = mr->range[0].max.tcp.port - = htons(port); - return; - case '-': - if (!xtables_strtoui(end + 1, NULL, &maxport, 0, UINT16_MAX)) - break; - - if (maxport < port) - break; - - mr->range[0].min.tcp.port = htons(port); - mr->range[0].max.tcp.port = htons(maxport); - return; - default: - break; - } - xtables_param_act(XTF_BAD_VALUE, "MASQUERADE", "--to-ports", arg); -} - -static void MASQUERADE_parse(struct xt_option_call *cb) -{ - const struct ipt_entry *entry = cb->xt_entry; - int portok; - struct nf_nat_ipv4_multi_range_compat *mr = cb->data; - - if (entry->ip.proto == IPPROTO_TCP - || entry->ip.proto == IPPROTO_UDP - || entry->ip.proto == IPPROTO_SCTP - || entry->ip.proto == IPPROTO_DCCP - || entry->ip.proto == IPPROTO_ICMP) - portok = 1; - else - portok = 0; - - xtables_option_parse(cb); - switch (cb->entry->id) { - case O_TO_PORTS: - if (!portok) - xtables_error(PARAMETER_PROBLEM, - "Need TCP, UDP, SCTP or DCCP with port specification"); - parse_ports(cb->arg, mr); - break; - case O_RANDOM: - mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM; - break; - case O_RANDOM_FULLY: - mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY; - break; - } -} - -static void -MASQUERADE_print(const void *ip, const struct xt_entry_target *target, - int numeric) -{ - const struct nf_nat_ipv4_multi_range_compat *mr = (const void *)target->data; - const struct nf_nat_ipv4_range *r = &mr->range[0]; - - if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) { - printf(" masq ports: "); - printf("%hu", ntohs(r->min.tcp.port)); - if (r->max.tcp.port != r->min.tcp.port) - printf("-%hu", ntohs(r->max.tcp.port)); - } - - if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) - printf(" random"); - - if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) - printf(" random-fully"); -} - -static void -MASQUERADE_save(const void *ip, const struct xt_entry_target *target) -{ - const struct nf_nat_ipv4_multi_range_compat *mr = (const void *)target->data; - const struct nf_nat_ipv4_range *r = &mr->range[0]; - - if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) { - printf(" --to-ports %hu", ntohs(r->min.tcp.port)); - if (r->max.tcp.port != r->min.tcp.port) - printf("-%hu", ntohs(r->max.tcp.port)); - } - - if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) - printf(" --random"); - - if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) - printf(" --random-fully"); -} - -static int MASQUERADE_xlate(struct xt_xlate *xl, - const struct xt_xlate_tg_params *params) -{ - const struct nf_nat_ipv4_multi_range_compat *mr = - (const void *)params->target->data; - const struct nf_nat_ipv4_range *r = &mr->range[0]; - - xt_xlate_add(xl, "masquerade"); - - if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) { - xt_xlate_add(xl, " to :%hu", ntohs(r->min.tcp.port)); - if (r->max.tcp.port != r->min.tcp.port) - xt_xlate_add(xl, "-%hu", ntohs(r->max.tcp.port)); - } - - xt_xlate_add(xl, " "); - if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) - xt_xlate_add(xl, "random "); - - return 1; -} - -static struct xtables_target masquerade_tg_reg = { - .name = "MASQUERADE", - .version = XTABLES_VERSION, - .family = NFPROTO_IPV4, - .size = XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)), - .userspacesize = XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)), - .help = MASQUERADE_help, - .init = MASQUERADE_init, - .x6_parse = MASQUERADE_parse, - .print = MASQUERADE_print, - .save = MASQUERADE_save, - .x6_options = MASQUERADE_opts, - .xlate = MASQUERADE_xlate, -}; - -void _init(void) -{ - xtables_register_target(&masquerade_tg_reg); -} diff --git a/extensions/libipt_MASQUERADE.txlate b/extensions/libipt_MASQUERADE.txlate index 40b6958a..0293b05b 100644 --- a/extensions/libipt_MASQUERADE.txlate +++ b/extensions/libipt_MASQUERADE.txlate @@ -1,8 +1,17 @@ iptables-translate -t nat -A POSTROUTING -j MASQUERADE -nft add rule ip nat POSTROUTING counter masquerade +nft 'add rule ip nat POSTROUTING counter masquerade' iptables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --to-ports 10 -nft add rule ip nat POSTROUTING ip protocol tcp counter masquerade to :10 +nft 'add rule ip nat POSTROUTING ip protocol tcp counter masquerade to :10' iptables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --to-ports 10-20 --random -nft add rule ip nat POSTROUTING ip protocol tcp counter masquerade to :10-20 random +nft 'add rule ip nat POSTROUTING ip protocol tcp counter masquerade to :10-20 random' + +iptables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --random +nft 'add rule ip nat POSTROUTING ip protocol tcp counter masquerade random' + +iptables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --random-fully +nft 'add rule ip nat POSTROUTING ip protocol tcp counter masquerade fully-random' + +iptables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --random --random-fully +nft 'add rule ip nat POSTROUTING ip protocol tcp counter masquerade random,fully-random' diff --git a/extensions/libipt_NETMAP.t b/extensions/libipt_NETMAP.t index 31924b98..0de856f0 100644 --- a/extensions/libipt_NETMAP.t +++ b/extensions/libipt_NETMAP.t @@ -1,4 +1,4 @@ :PREROUTING,INPUT,OUTPUT,POSTROUTING *nat -j NETMAP --to 1.2.3.0/24;=;OK --j NETMAP --to 1.2.3.4;=;OK +-j NETMAP --to 1.2.3.4;-j NETMAP --to 1.2.3.4/32;OK diff --git a/extensions/libipt_REJECT.t b/extensions/libipt_REJECT.t index 5b26b107..3f69a729 100644 --- a/extensions/libipt_REJECT.t +++ b/extensions/libipt_REJECT.t @@ -1,5 +1,5 @@ :INPUT,FORWARD,OUTPUT --j REJECT;=;OK +-j REJECT;-j REJECT --reject-with icmp-port-unreachable;OK -j REJECT --reject-with icmp-net-unreachable;=;OK -j REJECT --reject-with icmp-host-unreachable;=;OK -j REJECT --reject-with icmp-port-unreachable;=;OK diff --git a/extensions/libipt_REJECT.txlate b/extensions/libipt_REJECT.txlate index a1bfb5f4..022166a6 100644 --- a/extensions/libipt_REJECT.txlate +++ b/extensions/libipt_REJECT.txlate @@ -1,8 +1,8 @@ iptables-translate -A FORWARD -p TCP --dport 22 -j REJECT -nft add rule ip filter FORWARD tcp dport 22 counter reject +nft 'add rule ip filter FORWARD tcp dport 22 counter reject' iptables-translate -A FORWARD -p TCP --dport 22 -j REJECT --reject-with icmp-net-unreachable -nft add rule ip filter FORWARD tcp dport 22 counter reject with icmp type net-unreachable +nft 'add rule ip filter FORWARD tcp dport 22 counter reject with icmp type net-unreachable' iptables-translate -A FORWARD -p TCP --dport 22 -j REJECT --reject-with tcp-reset -nft add rule ip filter FORWARD tcp dport 22 counter reject with tcp reset +nft 'add rule ip filter FORWARD tcp dport 22 counter reject with tcp reset' diff --git a/extensions/libipt_SNAT.c b/extensions/libipt_SNAT.c deleted file mode 100644 index 211a20bc..00000000 --- a/extensions/libipt_SNAT.c +++ /dev/null @@ -1,280 +0,0 @@ -#include <stdio.h> -#include <netdb.h> -#include <string.h> -#include <stdlib.h> -#include <xtables.h> -#include <iptables.h> -#include <limits.h> /* INT_MAX in ip_tables.h */ -#include <linux/netfilter_ipv4/ip_tables.h> -#include <linux/netfilter/nf_nat.h> - -enum { - O_TO_SRC = 0, - O_RANDOM, - O_RANDOM_FULLY, - O_PERSISTENT, - F_TO_SRC = 1 << O_TO_SRC, - F_RANDOM = 1 << O_RANDOM, - F_RANDOM_FULLY = 1 << O_RANDOM_FULLY, -}; - -static void SNAT_help(void) -{ - printf( -"SNAT target options:\n" -" --to-source [<ipaddr>[-<ipaddr>]][:port[-port]]\n" -" Address to map source to.\n" -"[--random] [--random-fully] [--persistent]\n"); -} - -static const struct xt_option_entry SNAT_opts[] = { - {.name = "to-source", .id = O_TO_SRC, .type = XTTYPE_STRING, - .flags = XTOPT_MAND}, - {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE}, - {.name = "random-fully", .id = O_RANDOM_FULLY, .type = XTTYPE_NONE}, - {.name = "persistent", .id = O_PERSISTENT, .type = XTTYPE_NONE}, - XTOPT_TABLEEND, -}; - -/* Ranges expected in network order. */ -static void -parse_to(const char *orig_arg, int portok, struct nf_nat_ipv4_range *range) -{ - char *arg, *colon, *dash, *error; - const struct in_addr *ip; - - arg = xtables_strdup(orig_arg); - colon = strchr(arg, ':'); - - if (colon) { - int port; - - if (!portok) - xtables_error(PARAMETER_PROBLEM, - "Need TCP, UDP, SCTP or DCCP with port specification"); - - range->flags |= NF_NAT_RANGE_PROTO_SPECIFIED; - - port = atoi(colon+1); - if (port <= 0 || port > 65535) - xtables_error(PARAMETER_PROBLEM, - "Port `%s' not valid\n", colon+1); - - error = strchr(colon+1, ':'); - if (error) - xtables_error(PARAMETER_PROBLEM, - "Invalid port:port syntax - use dash\n"); - - dash = strchr(colon, '-'); - if (!dash) { - range->min.tcp.port - = range->max.tcp.port - = htons(port); - } else { - int maxport; - - maxport = atoi(dash + 1); - if (maxport <= 0 || maxport > 65535) - xtables_error(PARAMETER_PROBLEM, - "Port `%s' not valid\n", dash+1); - if (maxport < port) - /* People are stupid. */ - xtables_error(PARAMETER_PROBLEM, - "Port range `%s' funky\n", colon+1); - range->min.tcp.port = htons(port); - range->max.tcp.port = htons(maxport); - } - /* Starts with a colon? No IP info...*/ - if (colon == arg) { - free(arg); - return; - } - *colon = '\0'; - } - - range->flags |= NF_NAT_RANGE_MAP_IPS; - dash = strchr(arg, '-'); - if (colon && dash && dash > colon) - dash = NULL; - - if (dash) - *dash = '\0'; - - ip = xtables_numeric_to_ipaddr(arg); - if (!ip) - xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n", - arg); - range->min_ip = ip->s_addr; - if (dash) { - ip = xtables_numeric_to_ipaddr(dash+1); - if (!ip) - xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n", - dash+1); - range->max_ip = ip->s_addr; - } else - range->max_ip = range->min_ip; - - free(arg); - return; -} - -static void SNAT_parse(struct xt_option_call *cb) -{ - struct nf_nat_ipv4_multi_range_compat *mr = cb->data; - const struct ipt_entry *entry = cb->xt_entry; - int portok; - - if (entry->ip.proto == IPPROTO_TCP - || entry->ip.proto == IPPROTO_UDP - || entry->ip.proto == IPPROTO_SCTP - || entry->ip.proto == IPPROTO_DCCP - || entry->ip.proto == IPPROTO_ICMP) - portok = 1; - else - portok = 0; - - xtables_option_parse(cb); - switch (cb->entry->id) { - case O_TO_SRC: - parse_to(cb->arg, portok, mr->range); - break; - case O_PERSISTENT: - mr->range->flags |= NF_NAT_RANGE_PERSISTENT; - break; - } -} - -static void SNAT_fcheck(struct xt_fcheck_call *cb) -{ - static const unsigned int f = F_TO_SRC | F_RANDOM; - static const unsigned int r = F_TO_SRC | F_RANDOM_FULLY; - struct nf_nat_ipv4_multi_range_compat *mr = cb->data; - - if ((cb->xflags & f) == f) - mr->range->flags |= NF_NAT_RANGE_PROTO_RANDOM; - if ((cb->xflags & r) == r) - mr->range->flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY; - - mr->rangesize = 1; -} - -static void print_range(const struct nf_nat_ipv4_range *r) -{ - if (r->flags & NF_NAT_RANGE_MAP_IPS) { - struct in_addr a; - - a.s_addr = r->min_ip; - printf("%s", xtables_ipaddr_to_numeric(&a)); - if (r->max_ip != r->min_ip) { - a.s_addr = r->max_ip; - printf("-%s", xtables_ipaddr_to_numeric(&a)); - } - } - if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) { - printf(":"); - printf("%hu", ntohs(r->min.tcp.port)); - if (r->max.tcp.port != r->min.tcp.port) - printf("-%hu", ntohs(r->max.tcp.port)); - } -} - -static void SNAT_print(const void *ip, const struct xt_entry_target *target, - int numeric) -{ - const struct nf_nat_ipv4_multi_range_compat *mr = - (const void *)target->data; - - printf(" to:"); - print_range(mr->range); - if (mr->range->flags & NF_NAT_RANGE_PROTO_RANDOM) - printf(" random"); - if (mr->range->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) - printf(" random-fully"); - if (mr->range->flags & NF_NAT_RANGE_PERSISTENT) - printf(" persistent"); -} - -static void SNAT_save(const void *ip, const struct xt_entry_target *target) -{ - const struct nf_nat_ipv4_multi_range_compat *mr = - (const void *)target->data; - - printf(" --to-source "); - print_range(mr->range); - if (mr->range->flags & NF_NAT_RANGE_PROTO_RANDOM) - printf(" --random"); - if (mr->range->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) - printf(" --random-fully"); - if (mr->range->flags & NF_NAT_RANGE_PERSISTENT) - printf(" --persistent"); -} - -static void print_range_xlate(const struct nf_nat_ipv4_range *r, - struct xt_xlate *xl) -{ - if (r->flags & NF_NAT_RANGE_MAP_IPS) { - struct in_addr a; - - a.s_addr = r->min_ip; - xt_xlate_add(xl, "%s", xtables_ipaddr_to_numeric(&a)); - if (r->max_ip != r->min_ip) { - a.s_addr = r->max_ip; - xt_xlate_add(xl, "-%s", xtables_ipaddr_to_numeric(&a)); - } - } - if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) { - xt_xlate_add(xl, ":"); - xt_xlate_add(xl, "%hu", ntohs(r->min.tcp.port)); - if (r->max.tcp.port != r->min.tcp.port) - xt_xlate_add(xl, "-%hu", ntohs(r->max.tcp.port)); - } -} - -static int SNAT_xlate(struct xt_xlate *xl, - const struct xt_xlate_tg_params *params) -{ - const struct nf_nat_ipv4_multi_range_compat *mr = - (const void *)params->target->data; - bool sep_need = false; - const char *sep = " "; - - xt_xlate_add(xl, "snat to "); - print_range_xlate(mr->range, xl); - if (mr->range->flags & NF_NAT_RANGE_PROTO_RANDOM) { - xt_xlate_add(xl, " random"); - sep_need = true; - } - if (mr->range->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) { - if (sep_need) - sep = ","; - xt_xlate_add(xl, "%sfully-random", sep); - sep_need = true; - } - if (mr->range->flags & NF_NAT_RANGE_PERSISTENT) { - if (sep_need) - sep = ","; - xt_xlate_add(xl, "%spersistent", sep); - } - - return 1; -} - -static struct xtables_target snat_tg_reg = { - .name = "SNAT", - .version = XTABLES_VERSION, - .family = NFPROTO_IPV4, - .size = XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)), - .userspacesize = XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)), - .help = SNAT_help, - .x6_parse = SNAT_parse, - .x6_fcheck = SNAT_fcheck, - .print = SNAT_print, - .save = SNAT_save, - .x6_options = SNAT_opts, - .xlate = SNAT_xlate, -}; - -void _init(void) -{ - xtables_register_target(&snat_tg_reg); -} diff --git a/extensions/libipt_SNAT.t b/extensions/libipt_SNAT.t index 186e1cb8..c31d6e7c 100644 --- a/extensions/libipt_SNAT.t +++ b/extensions/libipt_SNAT.t @@ -4,6 +4,12 @@ -j SNAT --to-source 1.1.1.1-1.1.1.10;=;OK -j SNAT --to-source 1.1.1.1:1025-65535;;FAIL -j SNAT --to-source 1.1.1.1 --to-source 2.2.2.2;;FAIL +-j SNAT --to-source 1.1.1.1 --random;=;OK +-j SNAT --to-source 1.1.1.1 --random-fully;=;OK +-j SNAT --to-source 1.1.1.1 --persistent;=;OK +-j SNAT --to-source 1.1.1.1 --random --persistent;=;OK +-j SNAT --to-source 1.1.1.1 --random --random-fully;=;OK +-j SNAT --to-source 1.1.1.1 --random --random-fully --persistent;=;OK -p tcp -j SNAT --to-source 1.1.1.1:1025-65535;=;OK -p tcp -j SNAT --to-source 1.1.1.1-1.1.1.10:1025-65535;=;OK -p tcp -j SNAT --to-source 1.1.1.1-1.1.1.10:1025-65536;;FAIL diff --git a/extensions/libipt_SNAT.txlate b/extensions/libipt_SNAT.txlate index 01592fad..83afef95 100644 --- a/extensions/libipt_SNAT.txlate +++ b/extensions/libipt_SNAT.txlate @@ -1,14 +1,14 @@ iptables-translate -t nat -A postrouting -o eth0 -j SNAT --to 1.2.3.4 -nft add rule ip nat postrouting oifname "eth0" counter snat to 1.2.3.4 +nft 'add rule ip nat postrouting oifname "eth0" counter snat to 1.2.3.4' iptables-translate -t nat -A postrouting -o eth0 -j SNAT --to 1.2.3.4-1.2.3.6 -nft add rule ip nat postrouting oifname "eth0" counter snat to 1.2.3.4-1.2.3.6 +nft 'add rule ip nat postrouting oifname "eth0" counter snat to 1.2.3.4-1.2.3.6' iptables-translate -t nat -A postrouting -p tcp -o eth0 -j SNAT --to 1.2.3.4:1-1023 -nft add rule ip nat postrouting oifname "eth0" ip protocol tcp counter snat to 1.2.3.4:1-1023 +nft 'add rule ip nat postrouting oifname "eth0" ip protocol tcp counter snat to 1.2.3.4:1-1023' iptables-translate -t nat -A postrouting -o eth0 -j SNAT --to 1.2.3.4 --random -nft add rule ip nat postrouting oifname "eth0" counter snat to 1.2.3.4 random +nft 'add rule ip nat postrouting oifname "eth0" counter snat to 1.2.3.4 random' iptables-translate -t nat -A postrouting -o eth0 -j SNAT --to 1.2.3.4 --random --persistent -nft add rule ip nat postrouting oifname "eth0" counter snat to 1.2.3.4 random,persistent +nft 'add rule ip nat postrouting oifname "eth0" counter snat to 1.2.3.4 random,persistent' diff --git a/extensions/libipt_ah.txlate b/extensions/libipt_ah.txlate index ea3ef3e9..897c82b5 100644 --- a/extensions/libipt_ah.txlate +++ b/extensions/libipt_ah.txlate @@ -1,8 +1,8 @@ iptables-translate -A INPUT -p 51 -m ah --ahspi 500 -j DROP -nft add rule ip filter INPUT ah spi 500 counter drop +nft 'add rule ip filter INPUT ah spi 500 counter drop' iptables-translate -A INPUT -p 51 -m ah --ahspi 500:600 -j DROP -nft add rule ip filter INPUT ah spi 500-600 counter drop +nft 'add rule ip filter INPUT ah spi 500-600 counter drop' iptables-translate -A INPUT -p 51 -m ah ! --ahspi 50 -j DROP -nft add rule ip filter INPUT ah spi != 50 counter drop +nft 'add rule ip filter INPUT ah spi != 50 counter drop' diff --git a/extensions/libipt_icmp.c b/extensions/libipt_icmp.c index e5e23661..171b3b39 100644 --- a/extensions/libipt_icmp.c +++ b/extensions/libipt_icmp.c @@ -19,61 +19,6 @@ enum { O_ICMP_TYPE = 0, }; -static const struct xt_icmp_names icmp_codes[] = { - { "any", 0xFF, 0, 0xFF }, - { "echo-reply", 0, 0, 0xFF }, - /* Alias */ { "pong", 0, 0, 0xFF }, - - { "destination-unreachable", 3, 0, 0xFF }, - { "network-unreachable", 3, 0, 0 }, - { "host-unreachable", 3, 1, 1 }, - { "protocol-unreachable", 3, 2, 2 }, - { "port-unreachable", 3, 3, 3 }, - { "fragmentation-needed", 3, 4, 4 }, - { "source-route-failed", 3, 5, 5 }, - { "network-unknown", 3, 6, 6 }, - { "host-unknown", 3, 7, 7 }, - { "network-prohibited", 3, 9, 9 }, - { "host-prohibited", 3, 10, 10 }, - { "TOS-network-unreachable", 3, 11, 11 }, - { "TOS-host-unreachable", 3, 12, 12 }, - { "communication-prohibited", 3, 13, 13 }, - { "host-precedence-violation", 3, 14, 14 }, - { "precedence-cutoff", 3, 15, 15 }, - - { "source-quench", 4, 0, 0xFF }, - - { "redirect", 5, 0, 0xFF }, - { "network-redirect", 5, 0, 0 }, - { "host-redirect", 5, 1, 1 }, - { "TOS-network-redirect", 5, 2, 2 }, - { "TOS-host-redirect", 5, 3, 3 }, - - { "echo-request", 8, 0, 0xFF }, - /* Alias */ { "ping", 8, 0, 0xFF }, - - { "router-advertisement", 9, 0, 0xFF }, - - { "router-solicitation", 10, 0, 0xFF }, - - { "time-exceeded", 11, 0, 0xFF }, - /* Alias */ { "ttl-exceeded", 11, 0, 0xFF }, - { "ttl-zero-during-transit", 11, 0, 0 }, - { "ttl-zero-during-reassembly", 11, 1, 1 }, - - { "parameter-problem", 12, 0, 0xFF }, - { "ip-header-bad", 12, 0, 0 }, - { "required-option-missing", 12, 1, 1 }, - - { "timestamp-request", 13, 0, 0xFF }, - - { "timestamp-reply", 14, 0, 0xFF }, - - { "address-mask-request", 17, 0, 0xFF }, - - { "address-mask-reply", 18, 0, 0xFF } -}; - static void icmp_help(void) { printf( @@ -90,59 +35,6 @@ static const struct xt_option_entry icmp_opts[] = { XTOPT_TABLEEND, }; -static void -parse_icmp(const char *icmptype, uint8_t *type, uint8_t code[]) -{ - static const unsigned int limit = ARRAY_SIZE(icmp_codes); - unsigned int match = limit; - unsigned int i; - - for (i = 0; i < limit; i++) { - if (strncasecmp(icmp_codes[i].name, icmptype, strlen(icmptype)) - == 0) { - if (match != limit) - xtables_error(PARAMETER_PROBLEM, - "Ambiguous ICMP type `%s':" - " `%s' or `%s'?", - icmptype, - icmp_codes[match].name, - icmp_codes[i].name); - match = i; - } - } - - if (match != limit) { - *type = icmp_codes[match].type; - code[0] = icmp_codes[match].code_min; - code[1] = icmp_codes[match].code_max; - } else { - char *slash; - char buffer[strlen(icmptype) + 1]; - unsigned int number; - - strcpy(buffer, icmptype); - slash = strchr(buffer, '/'); - - if (slash) - *slash = '\0'; - - if (!xtables_strtoui(buffer, NULL, &number, 0, UINT8_MAX)) - xtables_error(PARAMETER_PROBLEM, - "Invalid ICMP type `%s'\n", buffer); - *type = number; - if (slash) { - if (!xtables_strtoui(slash+1, NULL, &number, 0, UINT8_MAX)) - xtables_error(PARAMETER_PROBLEM, - "Invalid ICMP code `%s'\n", - slash+1); - code[0] = code[1] = number; - } else { - code[0] = 0; - code[1] = 0xFF; - } - } -} - static void icmp_init(struct xt_entry_match *m) { struct ipt_icmp *icmpinfo = (struct ipt_icmp *)m->data; @@ -156,7 +48,7 @@ static void icmp_parse(struct xt_option_call *cb) struct ipt_icmp *icmpinfo = cb->data; xtables_option_parse(cb); - parse_icmp(cb->arg, &icmpinfo->type, icmpinfo->code); + ipt_parse_icmp(cb->arg, &icmpinfo->type, icmpinfo->code); if (cb->invert) icmpinfo->invflags |= IPT_ICMP_INV; } @@ -216,7 +108,8 @@ static void icmp_save(const void *ip, const struct xt_entry_match *match) printf(" !"); /* special hack for 'any' case */ - if (icmp->type == 0xFF) { + if (icmp->type == 0xFF && + icmp->code[0] == 0 && icmp->code[1] == 0xFF) { printf(" --icmp-type any"); } else { printf(" --icmp-type %u", icmp->type); diff --git a/extensions/libipt_icmp.t b/extensions/libipt_icmp.t index f4ba65c2..4ea93621 100644 --- a/extensions/libipt_icmp.t +++ b/extensions/libipt_icmp.t @@ -1,11 +1,8 @@ :INPUT,FORWARD,OUTPUT -p icmp -m icmp --icmp-type any;=;OK -# output uses the number, better use the name? -# ERROR: cannot find: iptables -I INPUT -p icmp -m icmp --icmp-type echo-reply -# -p icmp -m icmp --icmp-type echo-reply;=;OK -# output uses the number, better use the name? -# ERROR: annot find: iptables -I INPUT -p icmp -m icmp --icmp-type destination-unreachable -# -p icmp -m icmp --icmp-type destination-unreachable;=;OK +# XXX: output uses the number, better use the name? +-p icmp -m icmp --icmp-type echo-reply;-p icmp -m icmp --icmp-type 0;OK +-p icmp -m icmp --icmp-type destination-unreachable;-p icmp -m icmp --icmp-type 3;OK # it does not acccept name/name, should we accept this? # ERROR: cannot load: iptables -A INPUT -p icmp -m icmp --icmp-type destination-unreachable/network-unreachable # -p icmp -m icmp --icmp-type destination-unreachable/network-unreachable;=;OK @@ -13,3 +10,5 @@ # we accept "iptables -I INPUT -p tcp -m tcp", why not this below? # ERROR: cannot load: iptables -A INPUT -p icmp -m icmp # -p icmp -m icmp;=;OK +-p icmp -m icmp --icmp-type 255/255;=;OK +-p icmp -m icmp --icmp-type 255/0:255;-p icmp -m icmp --icmp-type any;OK diff --git a/extensions/libipt_icmp.txlate b/extensions/libipt_icmp.txlate index a2aec8e2..e7208d8b 100644 --- a/extensions/libipt_icmp.txlate +++ b/extensions/libipt_icmp.txlate @@ -1,11 +1,11 @@ iptables-translate -t filter -A INPUT -m icmp --icmp-type echo-reply -j ACCEPT -nft add rule ip filter INPUT icmp type echo-reply counter accept +nft 'add rule ip filter INPUT icmp type echo-reply counter accept' iptables-translate -t filter -A INPUT -m icmp --icmp-type 3 -j ACCEPT -nft add rule ip filter INPUT icmp type destination-unreachable counter accept +nft 'add rule ip filter INPUT icmp type destination-unreachable counter accept' iptables-translate -t filter -A INPUT -m icmp ! --icmp-type 3 -j ACCEPT -nft add rule ip filter INPUT icmp type != destination-unreachable counter accept +nft 'add rule ip filter INPUT icmp type != destination-unreachable counter accept' iptables-translate -t filter -A INPUT -m icmp --icmp-type any -j ACCEPT -nft add rule ip filter INPUT ip protocol icmp counter accept +nft 'add rule ip filter INPUT ip protocol icmp counter accept' diff --git a/extensions/libipt_realm.txlate b/extensions/libipt_realm.txlate index 7d710294..6d134546 100644 --- a/extensions/libipt_realm.txlate +++ b/extensions/libipt_realm.txlate @@ -1,11 +1,11 @@ iptables-translate -A PREROUTING -m realm --realm 4 -nft add rule ip filter PREROUTING rtclassid 0x4 counter +nft 'add rule ip filter PREROUTING rtclassid 0x4 counter' iptables-translate -A PREROUTING -m realm --realm 5/5 -nft add rule ip filter PREROUTING rtclassid and 0x5 == 0x5 counter +nft 'add rule ip filter PREROUTING rtclassid and 0x5 == 0x5 counter' iptables-translate -A PREROUTING -m realm ! --realm 50 -nft add rule ip filter PREROUTING rtclassid != 0x32 counter +nft 'add rule ip filter PREROUTING rtclassid != 0x32 counter' iptables-translate -A INPUT -m realm --realm 1/0xf -nft add rule ip filter INPUT rtclassid and 0xf == 0x1 counter +nft 'add rule ip filter INPUT rtclassid and 0xf == 0x1 counter' diff --git a/extensions/libipt_ttl.c b/extensions/libipt_ttl.c index 6bdd2196..86ba554e 100644 --- a/extensions/libipt_ttl.c +++ b/extensions/libipt_ttl.c @@ -106,7 +106,7 @@ static int ttl_xlate(struct xt_xlate *xl, const struct ipt_ttl_info *info = (struct ipt_ttl_info *) params->match->data; - switch (info->mode) { + switch (info->mode) { case IPT_TTL_EQ: xt_xlate_add(xl, "ip ttl"); break; @@ -121,7 +121,7 @@ static int ttl_xlate(struct xt_xlate *xl, break; default: /* Should not happen. */ - break; + return 0; } xt_xlate_add(xl, " %u", info->ttl); diff --git a/extensions/libipt_ttl.txlate b/extensions/libipt_ttl.txlate index 3d5d6a70..6b90ff99 100644 --- a/extensions/libipt_ttl.txlate +++ b/extensions/libipt_ttl.txlate @@ -1,5 +1,5 @@ iptables-translate -A INPUT -m ttl --ttl-eq 3 -j ACCEPT -nft add rule ip filter INPUT ip ttl 3 counter accept +nft 'add rule ip filter INPUT ip ttl 3 counter accept' iptables-translate -A INPUT -m ttl --ttl-gt 5 -j ACCEPT -nft add rule ip filter INPUT ip ttl gt 5 counter accept +nft 'add rule ip filter INPUT ip ttl gt 5 counter accept' diff --git a/extensions/libxt_AUDIT.txlate b/extensions/libxt_AUDIT.txlate index abd11eae..c1650b9a 100644 --- a/extensions/libxt_AUDIT.txlate +++ b/extensions/libxt_AUDIT.txlate @@ -1,8 +1,8 @@ iptables-translate -t filter -A INPUT -j AUDIT --type accept -nft add rule ip filter INPUT counter log level audit +nft 'add rule ip filter INPUT counter log level audit' iptables-translate -t filter -A INPUT -j AUDIT --type drop -nft add rule ip filter INPUT counter log level audit +nft 'add rule ip filter INPUT counter log level audit' iptables-translate -t filter -A INPUT -j AUDIT --type reject -nft add rule ip filter INPUT counter log level audit +nft 'add rule ip filter INPUT counter log level audit' diff --git a/extensions/libxt_CLASSIFY.txlate b/extensions/libxt_CLASSIFY.txlate index 3b349237..3150c69e 100644 --- a/extensions/libxt_CLASSIFY.txlate +++ b/extensions/libxt_CLASSIFY.txlate @@ -1,8 +1,8 @@ iptables-translate -A OUTPUT -j CLASSIFY --set-class 0:0 -nft add rule ip filter OUTPUT counter meta priority set none +nft 'add rule ip filter OUTPUT counter meta priority set none' iptables-translate -A OUTPUT -j CLASSIFY --set-class ffff:ffff -nft add rule ip filter OUTPUT counter meta priority set root +nft 'add rule ip filter OUTPUT counter meta priority set root' iptables-translate -A OUTPUT -j CLASSIFY --set-class 1:234 -nft add rule ip filter OUTPUT counter meta priority set 1:234 +nft 'add rule ip filter OUTPUT counter meta priority set 1:234' diff --git a/extensions/libxt_CONNMARK.c b/extensions/libxt_CONNMARK.c index 21e10913..a6568c99 100644 --- a/extensions/libxt_CONNMARK.c +++ b/extensions/libxt_CONNMARK.c @@ -595,11 +595,11 @@ static int connmark_tg_xlate_v2(struct xt_xlate *xl, { const struct xt_connmark_tginfo2 *info = (const void *)params->target->data; - const char *shift_op = xt_connmark_shift_ops[info->shift_dir]; + const char *braces = info->shift_bits ? "( " : ""; switch (info->mode) { case XT_CONNMARK_SET: - xt_xlate_add(xl, "ct mark set "); + xt_xlate_add(xl, "ct mark set %s", braces); if (info->ctmask == 0xFFFFFFFFU) xt_xlate_add(xl, "0x%x ", info->ctmark); else if (info->ctmark == 0) @@ -615,26 +615,31 @@ static int connmark_tg_xlate_v2(struct xt_xlate *xl, info->ctmark, ~info->ctmask); break; case XT_CONNMARK_SAVE: - xt_xlate_add(xl, "ct mark set mark"); + xt_xlate_add(xl, "ct mark set %smark", braces); if (!(info->nfmask == UINT32_MAX && info->ctmask == UINT32_MAX)) { if (info->nfmask == info->ctmask) xt_xlate_add(xl, " and 0x%x", info->nfmask); + else + return 0; } break; case XT_CONNMARK_RESTORE: - xt_xlate_add(xl, "meta mark set ct mark"); + xt_xlate_add(xl, "meta mark set %sct mark", braces); if (!(info->nfmask == UINT32_MAX && info->ctmask == UINT32_MAX)) { if (info->nfmask == info->ctmask) xt_xlate_add(xl, " and 0x%x", info->nfmask); + else + return 0; } break; } if (info->mode <= XT_CONNMARK_RESTORE && info->shift_bits != 0) { - xt_xlate_add(xl, " %s %u", shift_op, info->shift_bits); + xt_xlate_add(xl, " ) %s %u", + info->shift_dir ? ">>" : "<<", info->shift_bits); } return 1; diff --git a/extensions/libxt_CONNMARK.t b/extensions/libxt_CONNMARK.t index 79a838fe..c9b2b4a5 100644 --- a/extensions/libxt_CONNMARK.t +++ b/extensions/libxt_CONNMARK.t @@ -1,7 +1,7 @@ :PREROUTING,FORWARD,OUTPUT,POSTROUTING *mangle --j CONNMARK --restore-mark;=;OK --j CONNMARK --save-mark;=;OK --j CONNMARK --save-mark --nfmask 0xfffffff --ctmask 0xffffffff;-j CONNMARK --save-mark;OK --j CONNMARK --restore-mark --nfmask 0xfffffff --ctmask 0xffffffff;-j CONNMARK --restore-mark;OK +-j CONNMARK --restore-mark;-j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff;OK +-j CONNMARK --save-mark;-j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff;OK +-j CONNMARK --save-mark --nfmask 0xfffffff --ctmask 0xffffffff;=;OK +-j CONNMARK --restore-mark --nfmask 0xfffffff --ctmask 0xffffffff;=;OK -j CONNMARK;;FAIL diff --git a/extensions/libxt_CONNMARK.txlate b/extensions/libxt_CONNMARK.txlate index ce40ae5e..5da4d6c7 100644 --- a/extensions/libxt_CONNMARK.txlate +++ b/extensions/libxt_CONNMARK.txlate @@ -1,20 +1,23 @@ iptables-translate -t mangle -A PREROUTING -j CONNMARK --set-mark 0 -nft add rule ip mangle PREROUTING counter ct mark set 0x0 +nft 'add rule ip mangle PREROUTING counter ct mark set 0x0' iptables-translate -t mangle -A PREROUTING -j CONNMARK --set-mark 0x16 -nft add rule ip mangle PREROUTING counter ct mark set 0x16 +nft 'add rule ip mangle PREROUTING counter ct mark set 0x16' iptables-translate -t mangle -A PREROUTING -j CONNMARK --set-xmark 0x16/0x12 -nft add rule ip mangle PREROUTING counter ct mark set ct mark xor 0x16 and 0xffffffed +nft 'add rule ip mangle PREROUTING counter ct mark set ct mark xor 0x16 and 0xffffffed' iptables-translate -t mangle -A PREROUTING -j CONNMARK --and-mark 0x16 -nft add rule ip mangle PREROUTING counter ct mark set ct mark and 0x16 +nft 'add rule ip mangle PREROUTING counter ct mark set ct mark and 0x16' iptables-translate -t mangle -A PREROUTING -j CONNMARK --or-mark 0x16 -nft add rule ip mangle PREROUTING counter ct mark set ct mark or 0x16 +nft 'add rule ip mangle PREROUTING counter ct mark set ct mark or 0x16' iptables-translate -t mangle -A PREROUTING -j CONNMARK --save-mark -nft add rule ip mangle PREROUTING counter ct mark set mark +nft 'add rule ip mangle PREROUTING counter ct mark set mark' iptables-translate -t mangle -A PREROUTING -j CONNMARK --restore-mark -nft add rule ip mangle PREROUTING counter meta mark set ct mark +nft 'add rule ip mangle PREROUTING counter meta mark set ct mark' + +iptables-translate -t mangle -A PREROUTING -j CONNMARK --set-mark 0x23/0x42 --right-shift-mark 5 +nft 'add rule ip mangle PREROUTING counter ct mark set ( ct mark xor 0x23 and 0xffffff9c ) >> 5' diff --git a/extensions/libxt_CONNSECMARK.c b/extensions/libxt_CONNSECMARK.c index 0b3cd79d..6da589d3 100644 --- a/extensions/libxt_CONNSECMARK.c +++ b/extensions/libxt_CONNSECMARK.c @@ -66,7 +66,8 @@ static void print_connsecmark(const struct xt_connsecmark_target_info *info) break; default: - xtables_error(OTHER_PROBLEM, PFX "invalid mode %hhu\n", info->mode); + xtables_error(OTHER_PROBLEM, + PFX "invalid mode %hhu", info->mode); } } diff --git a/extensions/libxt_CT.c b/extensions/libxt_CT.c index fbbbe266..18824665 100644 --- a/extensions/libxt_CT.c +++ b/extensions/libxt_CT.c @@ -117,7 +117,7 @@ static void ct_parse_zone_id(const char *opt, unsigned int opt_id, if (!xtables_strtoul(opt, NULL, &val, 0, UINT16_MAX)) xtables_error(PARAMETER_PROBLEM, - "Cannot parse %s as a zone ID\n", opt); + "Cannot parse %s as a zone ID", opt); *zone_id = (uint16_t)val; } diff --git a/extensions/libxt_DNAT.txlate b/extensions/libxt_DNAT.txlate index a6597656..e005245d 100644 --- a/extensions/libxt_DNAT.txlate +++ b/extensions/libxt_DNAT.txlate @@ -1,35 +1,35 @@ iptables-translate -t nat -A prerouting -p tcp -o eth0 -j DNAT --to-destination 1.2.3.4 -nft add rule ip nat prerouting oifname "eth0" ip protocol tcp counter dnat to 1.2.3.4 +nft 'add rule ip nat prerouting oifname "eth0" ip protocol tcp counter dnat to 1.2.3.4' iptables-translate -t nat -A prerouting -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.1.1-192.168.1.10 -nft add rule ip nat prerouting ip daddr 15.45.23.67 tcp dport 80 counter dnat to 192.168.1.1-192.168.1.10 +nft 'add rule ip nat prerouting ip daddr 15.45.23.67 tcp dport 80 counter dnat to 192.168.1.1-192.168.1.10' iptables-translate -t nat -A prerouting -p tcp -o eth0 -j DNAT --to-destination 1.2.3.4:1-1023 -nft add rule ip nat prerouting oifname "eth0" ip protocol tcp counter dnat to 1.2.3.4:1-1023 +nft 'add rule ip nat prerouting oifname "eth0" ip protocol tcp counter dnat to 1.2.3.4:1-1023' iptables-translate -t nat -A prerouting -p tcp -o eth0 -j DNAT --to-destination 1.2.3.4 --random -nft add rule ip nat prerouting oifname "eth0" ip protocol tcp counter dnat to 1.2.3.4 random +nft 'add rule ip nat prerouting oifname "eth0" ip protocol tcp counter dnat to 1.2.3.4 random' iptables-translate -t nat -A prerouting -p tcp -o eth0 -j DNAT --to-destination 1.2.3.4 --random --persistent -nft add rule ip nat prerouting oifname "eth0" ip protocol tcp counter dnat to 1.2.3.4 random,persistent +nft 'add rule ip nat prerouting oifname "eth0" ip protocol tcp counter dnat to 1.2.3.4 random,persistent' ip6tables-translate -t nat -A prerouting -p tcp --dport 8080 -j DNAT --to-destination fec0::1234 -nft add rule ip6 nat prerouting tcp dport 8080 counter dnat to fec0::1234 +nft 'add rule ip6 nat prerouting tcp dport 8080 counter dnat to fec0::1234' ip6tables-translate -t nat -A prerouting -p tcp --dport 8080 -j DNAT --to-destination fec0::1234-fec0::2000 -nft add rule ip6 nat prerouting tcp dport 8080 counter dnat to fec0::1234-fec0::2000 +nft 'add rule ip6 nat prerouting tcp dport 8080 counter dnat to fec0::1234-fec0::2000' ip6tables-translate -t nat -A prerouting -i eth1 -p tcp --dport 8080 -j DNAT --to-destination [fec0::1234]:80 -nft add rule ip6 nat prerouting iifname "eth1" tcp dport 8080 counter dnat to [fec0::1234]:80 +nft 'add rule ip6 nat prerouting iifname "eth1" tcp dport 8080 counter dnat to [fec0::1234]:80' ip6tables-translate -t nat -A prerouting -p tcp -j DNAT --to-destination [fec0::1234]:1-20 -nft add rule ip6 nat prerouting meta l4proto tcp counter dnat to [fec0::1234]:1-20 +nft 'add rule ip6 nat prerouting meta l4proto tcp counter dnat to [fec0::1234]:1-20' ip6tables-translate -t nat -A prerouting -p tcp -j DNAT --to-destination [fec0::1234-fec0::2000]:1-20 -nft add rule ip6 nat prerouting meta l4proto tcp counter dnat to [fec0::1234-fec0::2000]:1-20 +nft 'add rule ip6 nat prerouting meta l4proto tcp counter dnat to [fec0::1234-fec0::2000]:1-20' ip6tables-translate -t nat -A prerouting -p tcp -j DNAT --to-destination [fec0::1234]:80 --persistent -nft add rule ip6 nat prerouting meta l4proto tcp counter dnat to [fec0::1234]:80 persistent +nft 'add rule ip6 nat prerouting meta l4proto tcp counter dnat to [fec0::1234]:80 persistent' ip6tables-translate -t nat -A prerouting -p tcp -j DNAT --to-destination [fec0::1234]:80 --random --persistent -nft add rule ip6 nat prerouting meta l4proto tcp counter dnat to [fec0::1234]:80 random,persistent +nft 'add rule ip6 nat prerouting meta l4proto tcp counter dnat to [fec0::1234]:80 random,persistent' diff --git a/extensions/libxt_DSCP.t b/extensions/libxt_DSCP.t index fcc55986..762fcd31 100644 --- a/extensions/libxt_DSCP.t +++ b/extensions/libxt_DSCP.t @@ -1,6 +1,6 @@ :PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING *mangle --j DSCP --set-dscp 0;=;OK +-j DSCP --set-dscp 0x00;=;OK -j DSCP --set-dscp 0x3f;=;OK -j DSCP --set-dscp -1;;FAIL -j DSCP --set-dscp 0x40;;FAIL diff --git a/extensions/libxt_DSCP.txlate b/extensions/libxt_DSCP.txlate index 442742ef..f7801a83 100644 --- a/extensions/libxt_DSCP.txlate +++ b/extensions/libxt_DSCP.txlate @@ -1,5 +1,5 @@ iptables-translate -A OUTPUT -j DSCP --set-dscp 1 -nft add rule ip filter OUTPUT counter ip dscp set 0x01 +nft 'add rule ip filter OUTPUT counter ip dscp set 0x01' ip6tables-translate -A OUTPUT -j DSCP --set-dscp 6 -nft add rule ip6 filter OUTPUT counter ip6 dscp set 0x06 +nft 'add rule ip6 filter OUTPUT counter ip6 dscp set 0x06' diff --git a/extensions/libxt_IDLETIMER.t b/extensions/libxt_IDLETIMER.t index e8f306d2..3345d5be 100644 --- a/extensions/libxt_IDLETIMER.t +++ b/extensions/libxt_IDLETIMER.t @@ -2,4 +2,4 @@ -j IDLETIMER --timeout;;FAIL -j IDLETIMER --timeout 42;;FAIL -j IDLETIMER --timeout 42 --label foo;=;OK --j IDLETIMER --timeout 42 --label foo --alarm;;OK +-j IDLETIMER --timeout 42 --label bar --alarm;=;OK diff --git a/extensions/libxt_LOG.c b/extensions/libxt_LOG.c new file mode 100644 index 00000000..d930bb97 --- /dev/null +++ b/extensions/libxt_LOG.c @@ -0,0 +1,231 @@ +#include <stdio.h> +#include <string.h> +#ifndef __BIONIC__ +#define SYSLOG_NAMES +#include <syslog.h> +#else /* __BIONIC__ */ +#include <syslog.h> +/* 'prioritynames[]' should come from syslog.h, but bionic doesn't provide it... + * It is a lookup array from a string name to a non unique LOG_* value, + * but it can also be used in reverse (in which case first match wins), + * so the order matters. + * iptables 1.8.9 only uses it for the level -> name lookup. + */ +static const struct { + const char * const c_name; + const int c_val; +} prioritynames[] = { + { .c_name = "emerg", .c_val = LOG_EMERG, }, + { .c_name = "panic", .c_val = LOG_EMERG, }, + { .c_name = "alert", .c_val = LOG_ALERT, }, + { .c_name = "crit", .c_val = LOG_CRIT, }, + { .c_name = "err", .c_val = LOG_ERR, }, + { .c_name = "error", .c_val = LOG_ERR, }, + { .c_name = "warn", .c_val = LOG_WARNING, }, + { .c_name = "warning", .c_val = LOG_WARNING, }, + { .c_name = "notice", .c_val = LOG_NOTICE, }, + { .c_name = "info", .c_val = LOG_INFO, }, + { .c_name = "debug", .c_val = LOG_DEBUG, }, + { .c_name = NULL, .c_val = -1, }, +}; +#endif /* __BIONIC__ */ +#include <xtables.h> +#include <linux/netfilter/xt_LOG.h> + +#define LOG_DEFAULT_LEVEL LOG_WARNING + +enum { + /* make sure the values correspond with XT_LOG_* bit positions */ + O_LOG_TCPSEQ = 0, + O_LOG_TCPOPTS, + O_LOG_IPOPTS, + O_LOG_UID, + __O_LOG_NFLOG, + O_LOG_MAC, + O_LOG_LEVEL, + O_LOG_PREFIX, +}; + +static void LOG_help(void) +{ + printf( +"LOG target options:\n" +" --log-level level Level of logging (numeric or see syslog.conf)\n" +" --log-prefix prefix Prefix log messages with this prefix.\n" +" --log-tcp-sequence Log TCP sequence numbers.\n" +" --log-tcp-options Log TCP options.\n" +" --log-ip-options Log IP options.\n" +" --log-uid Log UID owning the local socket.\n" +" --log-macdecode Decode MAC addresses and protocol.\n"); +} + +#define s struct xt_log_info +static const struct xt_option_entry LOG_opts[] = { + {.name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL, + .flags = XTOPT_PUT, XTOPT_POINTER(s, level)}, + {.name = "log-prefix", .id = O_LOG_PREFIX, .type = XTTYPE_STRING, + .flags = XTOPT_PUT, XTOPT_POINTER(s, prefix), .min = 1}, + {.name = "log-tcp-sequence", .id = O_LOG_TCPSEQ, .type = XTTYPE_NONE}, + {.name = "log-tcp-options", .id = O_LOG_TCPOPTS, .type = XTTYPE_NONE}, + {.name = "log-ip-options", .id = O_LOG_IPOPTS, .type = XTTYPE_NONE}, + {.name = "log-uid", .id = O_LOG_UID, .type = XTTYPE_NONE}, + {.name = "log-macdecode", .id = O_LOG_MAC, .type = XTTYPE_NONE}, + XTOPT_TABLEEND, +}; +#undef s + +static void LOG_init(struct xt_entry_target *t) +{ + struct xt_log_info *loginfo = (void *)t->data; + + loginfo->level = LOG_DEFAULT_LEVEL; +} + +static void LOG_parse(struct xt_option_call *cb) +{ + struct xt_log_info *info = cb->data; + + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_LOG_PREFIX: + if (strchr(cb->arg, '\n') != NULL) + xtables_error(PARAMETER_PROBLEM, + "Newlines not allowed in --log-prefix"); + break; + case O_LOG_TCPSEQ: + case O_LOG_TCPOPTS: + case O_LOG_IPOPTS: + case O_LOG_UID: + case O_LOG_MAC: + info->logflags |= 1 << cb->entry->id; + break; + } +} + +static const char *priority2name(unsigned char level) +{ + int i; + + for (i = 0; prioritynames[i].c_name; ++i) { + if (level == prioritynames[i].c_val) + return prioritynames[i].c_name; + } + return NULL; +} + +static void LOG_print(const void *ip, const struct xt_entry_target *target, + int numeric) +{ + const struct xt_log_info *loginfo = (const void *)target->data; + + printf(" LOG"); + if (numeric) + printf(" flags %u level %u", + loginfo->logflags, loginfo->level); + else { + const char *pname = priority2name(loginfo->level); + + if (pname) + printf(" level %s", pname); + else + printf(" UNKNOWN level %u", loginfo->level); + if (loginfo->logflags & XT_LOG_TCPSEQ) + printf(" tcp-sequence"); + if (loginfo->logflags & XT_LOG_TCPOPT) + printf(" tcp-options"); + if (loginfo->logflags & XT_LOG_IPOPT) + printf(" ip-options"); + if (loginfo->logflags & XT_LOG_UID) + printf(" uid"); + if (loginfo->logflags & XT_LOG_MACDECODE) + printf(" macdecode"); + if (loginfo->logflags & ~(XT_LOG_MASK)) + printf(" unknown-flags"); + } + + if (strcmp(loginfo->prefix, "") != 0) + printf(" prefix \"%s\"", loginfo->prefix); +} + +static void LOG_save(const void *ip, const struct xt_entry_target *target) +{ + const struct xt_log_info *loginfo = (const void *)target->data; + + if (strcmp(loginfo->prefix, "") != 0) { + printf(" --log-prefix"); + xtables_save_string(loginfo->prefix); + } + + if (loginfo->level != LOG_DEFAULT_LEVEL) + printf(" --log-level %d", loginfo->level); + + if (loginfo->logflags & XT_LOG_TCPSEQ) + printf(" --log-tcp-sequence"); + if (loginfo->logflags & XT_LOG_TCPOPT) + printf(" --log-tcp-options"); + if (loginfo->logflags & XT_LOG_IPOPT) + printf(" --log-ip-options"); + if (loginfo->logflags & XT_LOG_UID) + printf(" --log-uid"); + if (loginfo->logflags & XT_LOG_MACDECODE) + printf(" --log-macdecode"); +} + +static int LOG_xlate(struct xt_xlate *xl, + const struct xt_xlate_tg_params *params) +{ + const struct xt_log_info *loginfo = (const void *)params->target->data; + const char *pname = priority2name(loginfo->level); + + xt_xlate_add(xl, "log"); + if (strcmp(loginfo->prefix, "") != 0) + xt_xlate_add(xl, " prefix \"%s\"", loginfo->prefix); + + if (loginfo->level != LOG_DEFAULT_LEVEL && pname) + xt_xlate_add(xl, " level %s", pname); + else if (!pname) + return 0; + + if ((loginfo->logflags & XT_LOG_MASK) == XT_LOG_MASK) { + xt_xlate_add(xl, " flags all"); + } else { + if (loginfo->logflags & (XT_LOG_TCPSEQ | XT_LOG_TCPOPT)) { + const char *delim = " "; + + xt_xlate_add(xl, " flags tcp"); + if (loginfo->logflags & XT_LOG_TCPSEQ) { + xt_xlate_add(xl, " sequence"); + delim = ","; + } + if (loginfo->logflags & XT_LOG_TCPOPT) + xt_xlate_add(xl, "%soptions", delim); + } + if (loginfo->logflags & XT_LOG_IPOPT) + xt_xlate_add(xl, " flags ip options"); + if (loginfo->logflags & XT_LOG_UID) + xt_xlate_add(xl, " flags skuid"); + if (loginfo->logflags & XT_LOG_MACDECODE) + xt_xlate_add(xl, " flags ether"); + } + + return 1; +} +static struct xtables_target log_tg_reg = { + .name = "LOG", + .version = XTABLES_VERSION, + .family = NFPROTO_UNSPEC, + .size = XT_ALIGN(sizeof(struct xt_log_info)), + .userspacesize = XT_ALIGN(sizeof(struct xt_log_info)), + .help = LOG_help, + .init = LOG_init, + .print = LOG_print, + .save = LOG_save, + .x6_parse = LOG_parse, + .x6_options = LOG_opts, + .xlate = LOG_xlate, +}; + +void _init(void) +{ + xtables_register_target(&log_tg_reg); +} diff --git a/extensions/libxt_MARK.c b/extensions/libxt_MARK.c index 1536563d..100f6a38 100644 --- a/extensions/libxt_MARK.c +++ b/extensions/libxt_MARK.c @@ -366,6 +366,8 @@ static int MARK_xlate(struct xt_xlate *xl, case XT_MARK_OR: xt_xlate_add(xl, "mark or 0x%x ", (uint32_t)markinfo->mark); break; + default: + return 0; } return 1; diff --git a/extensions/libxt_MARK.t b/extensions/libxt_MARK.t index 9d1aa7d7..ae026dbb 100644 --- a/extensions/libxt_MARK.t +++ b/extensions/libxt_MARK.t @@ -1,7 +1,7 @@ :INPUT,FORWARD,OUTPUT -j MARK --set-xmark 0xfeedcafe/0xfeedcafe;=;OK --j MARK --set-xmark 0;=;OK --j MARK --set-xmark 4294967295;-j MARK --set-xmark 0xffffffff;OK +-j MARK --set-xmark 0x0;-j MARK --set-xmark 0x0/0xffffffff;OK +-j MARK --set-xmark 4294967295;-j MARK --set-xmark 0xffffffff/0xffffffff;OK -j MARK --set-xmark 4294967296;;FAIL -j MARK --set-xmark -1;;FAIL -j MARK;;FAIL diff --git a/extensions/libxt_MARK.txlate b/extensions/libxt_MARK.txlate index d3250ab6..36ee7a3b 100644 --- a/extensions/libxt_MARK.txlate +++ b/extensions/libxt_MARK.txlate @@ -1,26 +1,26 @@ iptables-translate -t mangle -A OUTPUT -j MARK --set-mark 0 -nft add rule ip mangle OUTPUT counter meta mark set 0x0 +nft 'add rule ip mangle OUTPUT counter meta mark set 0x0' iptables-translate -t mangle -A OUTPUT -j MARK --set-mark 64 -nft add rule ip mangle OUTPUT counter meta mark set 0x40 +nft 'add rule ip mangle OUTPUT counter meta mark set 0x40' iptables-translate -t mangle -A OUTPUT -j MARK --set-xmark 0x40/0x32 -nft add rule ip mangle OUTPUT counter meta mark set mark and 0xffffffcd xor 0x40 +nft 'add rule ip mangle OUTPUT counter meta mark set mark and 0xffffffcd xor 0x40' iptables-translate -t mangle -A OUTPUT -j MARK --or-mark 64 -nft add rule ip mangle OUTPUT counter meta mark set mark or 0x40 +nft 'add rule ip mangle OUTPUT counter meta mark set mark or 0x40' iptables-translate -t mangle -A OUTPUT -j MARK --and-mark 64 -nft add rule ip mangle OUTPUT counter meta mark set mark and 0x40 +nft 'add rule ip mangle OUTPUT counter meta mark set mark and 0x40' iptables-translate -t mangle -A OUTPUT -j MARK --xor-mark 64 -nft add rule ip mangle OUTPUT counter meta mark set mark xor 0x40 +nft 'add rule ip mangle OUTPUT counter meta mark set mark xor 0x40' iptables-translate -t mangle -A PREROUTING -j MARK --set-mark 0x64 -nft add rule ip mangle PREROUTING counter meta mark set 0x64 +nft 'add rule ip mangle PREROUTING counter meta mark set 0x64' iptables-translate -t mangle -A PREROUTING -j MARK --and-mark 0x64 -nft add rule ip mangle PREROUTING counter meta mark set mark and 0x64 +nft 'add rule ip mangle PREROUTING counter meta mark set mark and 0x64' iptables-translate -t mangle -A PREROUTING -j MARK --or-mark 0x64 -nft add rule ip mangle PREROUTING counter meta mark set mark or 0x64 +nft 'add rule ip mangle PREROUTING counter meta mark set mark or 0x64' diff --git a/extensions/libxt_DNAT.c b/extensions/libxt_NAT.c index 5696d31f..2a634398 100644 --- a/extensions/libxt_DNAT.c +++ b/extensions/libxt_NAT.c @@ -25,17 +25,45 @@ .min_proto = TO_IPV4_MRC(ptr)->range[0].min, \ .max_proto = TO_IPV4_MRC(ptr)->range[0].max, \ }; +#define TO_NF_NAT_RANGE(ptr) ((const struct nf_nat_range *)(ptr)) +#define RANGE2_INIT_FROM_RANGE(ptr) { \ + .flags = TO_NF_NAT_RANGE(ptr)->flags, \ + .min_addr = TO_NF_NAT_RANGE(ptr)->min_addr, \ + .max_addr = TO_NF_NAT_RANGE(ptr)->max_addr, \ + .min_proto = TO_NF_NAT_RANGE(ptr)->min_proto, \ + .max_proto = TO_NF_NAT_RANGE(ptr)->max_proto, \ +}; enum { O_TO_DEST = 0, + O_TO_SRC, O_TO_PORTS, O_RANDOM, + O_RANDOM_FULLY, O_PERSISTENT, - F_TO_DEST = 1 << O_TO_DEST, - F_TO_PORTS = 1 << O_TO_PORTS, - F_RANDOM = 1 << O_RANDOM, }; +static void SNAT_help(void) +{ + printf( +"SNAT target options:\n" +" --to-source [<ipaddr>[-<ipaddr>]][:port[-port]]\n" +" Address to map source to.\n" +"[--random] [--random-fully] [--persistent]\n"); +} + +static void MASQUERADE_help(void) +{ + printf( +"MASQUERADE target options:\n" +" --to-ports <port>[-<port>]\n" +" Port (range) to map to.\n" +" --random\n" +" Randomize source port.\n" +" --random-fully\n" +" Fully randomize source port.\n"); +} + static void DNAT_help(void) { printf( @@ -63,6 +91,22 @@ static void REDIRECT_help(void) " [--random]\n"); } +static const struct xt_option_entry SNAT_opts[] = { + {.name = "to-source", .id = O_TO_SRC, .type = XTTYPE_STRING, + .flags = XTOPT_MAND}, + {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE}, + {.name = "random-fully", .id = O_RANDOM_FULLY, .type = XTTYPE_NONE}, + {.name = "persistent", .id = O_PERSISTENT, .type = XTTYPE_NONE}, + XTOPT_TABLEEND, +}; + +static const struct xt_option_entry MASQUERADE_opts[] = { + {.name = "to-ports", .id = O_TO_PORTS, .type = XTTYPE_STRING}, + {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE}, + {.name = "random-fully", .id = O_RANDOM_FULLY, .type = XTTYPE_NONE}, + XTOPT_TABLEEND, +}; + static const struct xt_option_entry DNAT_opts[] = { {.name = "to-destination", .id = O_TO_DEST, .type = XTTYPE_STRING, .flags = XTOPT_MAND}, @@ -197,7 +241,7 @@ parse_to(const char *orig_arg, bool portok, if (!inet_pton(family, start, &range->min_addr)) xtables_error(PARAMETER_PROBLEM, - "Bad IP address \"%s\"", arg); + "Bad IP address \"%s\"", start); if (dash) { if (!inet_pton(family, dash + 1, &range->max_addr)) xtables_error(PARAMETER_PROBLEM, @@ -209,8 +253,8 @@ parse_to(const char *orig_arg, bool portok, return; } -static void __DNAT_parse(struct xt_option_call *cb, __u16 proto, - struct nf_nat_range2 *range, int family) +static void __NAT_parse(struct xt_option_call *cb, __u16 proto, + struct nf_nat_range2 *range, int family) { bool portok = proto == IPPROTO_TCP || proto == IPPROTO_UDP || @@ -221,6 +265,7 @@ static void __DNAT_parse(struct xt_option_call *cb, __u16 proto, xtables_option_parse(cb); switch (cb->entry->id) { case O_TO_DEST: + case O_TO_SRC: parse_to(cb->arg, portok, range, family); break; case O_TO_PORTS: @@ -229,19 +274,26 @@ static void __DNAT_parse(struct xt_option_call *cb, __u16 proto, case O_PERSISTENT: range->flags |= NF_NAT_RANGE_PERSISTENT; break; + case O_RANDOM: + range->flags |= NF_NAT_RANGE_PROTO_RANDOM; + break; + case O_RANDOM_FULLY: + range->flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY; + break; } } -static void DNAT_parse(struct xt_option_call *cb) +static void NAT_parse(struct xt_option_call *cb) { struct nf_nat_ipv4_multi_range_compat *mr = (void *)cb->data; const struct ipt_entry *entry = cb->xt_entry; struct nf_nat_range2 range = {}; - __DNAT_parse(cb, entry->ip.proto, &range, AF_INET); + __NAT_parse(cb, entry->ip.proto, &range, AF_INET); switch (cb->entry->id) { case O_TO_DEST: + case O_TO_SRC: mr->range->min_ip = range.min_addr.ip; mr->range->max_ip = range.max_addr.ip; /* fall through */ @@ -250,19 +302,42 @@ static void DNAT_parse(struct xt_option_call *cb) mr->range->max = range.max_proto; /* fall through */ case O_PERSISTENT: + case O_RANDOM: + case O_RANDOM_FULLY: mr->range->flags |= range.flags; break; } } -static void __DNAT_fcheck(struct xt_fcheck_call *cb, unsigned int *flags) +static void NAT_parse6(struct xt_option_call *cb) +{ + struct nf_nat_range2 range = RANGE2_INIT_FROM_RANGE(cb->data); + struct nf_nat_range *range_v1 = (void *)cb->data; + const struct ip6t_entry *entry = cb->xt_entry; + + __NAT_parse(cb, entry->ipv6.proto, &range, AF_INET6); + memcpy(range_v1, &range, sizeof(*range_v1)); +} + +static void DNAT_parse_v2(struct xt_option_call *cb) { - static const unsigned int redir_f = F_TO_PORTS | F_RANDOM; - static const unsigned int dnat_f = F_TO_DEST | F_RANDOM; + const struct ipt_entry *entry = cb->xt_entry; - if ((cb->xflags & redir_f) == redir_f || - (cb->xflags & dnat_f) == dnat_f) - *flags |= NF_NAT_RANGE_PROTO_RANDOM; + __NAT_parse(cb, entry->ip.proto, cb->data, AF_INET); +} + +static void DNAT_parse6_v2(struct xt_option_call *cb) +{ + const struct ip6t_entry *entry = cb->xt_entry; + + __NAT_parse(cb, entry->ipv6.proto, cb->data, AF_INET6); +} + +static void SNAT_fcheck(struct xt_fcheck_call *cb) +{ + struct nf_nat_ipv4_multi_range_compat *mr = cb->data; + + mr->rangesize = 1; } static void DNAT_fcheck(struct xt_fcheck_call *cb) @@ -274,8 +349,15 @@ static void DNAT_fcheck(struct xt_fcheck_call *cb) if (mr->range[0].flags & NF_NAT_RANGE_PROTO_OFFSET) xtables_error(PARAMETER_PROBLEM, "Shifted portmap ranges not supported with this kernel"); +} - __DNAT_fcheck(cb, &mr->range[0].flags); +static void DNAT_fcheck6(struct xt_fcheck_call *cb) +{ + struct nf_nat_range *range = (void *)cb->data; + + if (range->flags & NF_NAT_RANGE_PROTO_OFFSET) + xtables_error(PARAMETER_PROBLEM, + "Shifted portmap ranges not supported with this kernel"); } static char *sprint_range(const struct nf_nat_range2 *r, int family) @@ -325,31 +407,15 @@ static void __NAT_print(const struct nf_nat_range2 *r, int family, } if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) printf(" %srandom", flag_pfx); + if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) + printf(" %srandom-fully", flag_pfx); if (r->flags & NF_NAT_RANGE_PERSISTENT) printf(" %spersistent", flag_pfx); } -#define __DNAT_print(r, family) __NAT_print(r, family, "to:", "", false) -#define __DNAT_save(r, family) __NAT_print(r, family, "--to-destination ", "--", false) -#define __REDIRECT_print(r) __NAT_print(r, AF_INET, "redir ports ", "", true) -#define __REDIRECT_save(r) __NAT_print(r, AF_INET, "--to-ports ", "--", true) - -static void DNAT_print(const void *ip, const struct xt_entry_target *target, - int numeric) -{ - struct nf_nat_range2 range = RANGE2_INIT_FROM_IPV4_MRC(target->data); - - __DNAT_print(&range, AF_INET); -} - -static void DNAT_save(const void *ip, const struct xt_entry_target *target) -{ - struct nf_nat_range2 range = RANGE2_INIT_FROM_IPV4_MRC(target->data); - - __DNAT_save(&range, AF_INET); -} static int -__DNAT_xlate(struct xt_xlate *xl, const struct nf_nat_range2 *r, int family) +__NAT_xlate(struct xt_xlate *xl, const struct nf_nat_range2 *r, + int family, const char *tgt) { char *range_str = sprint_range(r, family); const char *sep = " "; @@ -358,13 +424,17 @@ __DNAT_xlate(struct xt_xlate *xl, const struct nf_nat_range2 *r, int family) if (r->flags & NF_NAT_RANGE_PROTO_OFFSET) return 0; - xt_xlate_add(xl, "dnat"); + xt_xlate_add(xl, "%s", tgt); if (strlen(range_str)) xt_xlate_add(xl, " to %s", range_str); if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) { xt_xlate_add(xl, "%srandom", sep); sep = ","; } + if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) { + xt_xlate_add(xl, "%sfully-random", sep); + sep = ","; + } if (r->flags & NF_NAT_RANGE_PERSISTENT) { xt_xlate_add(xl, "%spersistent", sep); sep = ","; @@ -372,183 +442,74 @@ __DNAT_xlate(struct xt_xlate *xl, const struct nf_nat_range2 *r, int family) return 1; } -static int DNAT_xlate(struct xt_xlate *xl, - const struct xt_xlate_tg_params *params) -{ - struct nf_nat_range2 range = - RANGE2_INIT_FROM_IPV4_MRC(params->target->data); - - return __DNAT_xlate(xl, &range, AF_INET); +#define PSX_GEN(name, converter, family, \ + print_rangeopt, save_rangeopt, skip_colon, xlate) \ +static void name##_print(const void *ip, const struct xt_entry_target *target, \ + int numeric) \ +{ \ + struct nf_nat_range2 range = converter(target->data); \ + \ + __NAT_print(&range, family, print_rangeopt, "", skip_colon); \ +} \ +static void name##_save(const void *ip, const struct xt_entry_target *target) \ +{ \ + struct nf_nat_range2 range = converter(target->data); \ + \ + __NAT_print(&range, family, save_rangeopt, "--", skip_colon); \ +} \ +static int name##_xlate(struct xt_xlate *xl, \ + const struct xt_xlate_tg_params *params) \ +{ \ + struct nf_nat_range2 range = converter(params->target->data); \ + \ + return __NAT_xlate(xl, &range, family, xlate); \ } -static void DNAT_parse_v2(struct xt_option_call *cb) -{ - const struct ipt_entry *entry = cb->xt_entry; +PSX_GEN(DNAT, RANGE2_INIT_FROM_IPV4_MRC, \ + AF_INET, "to:", "--to-destination ", false, "dnat") - __DNAT_parse(cb, entry->ip.proto, cb->data, AF_INET); -} +PSX_GEN(DNATv2, *(struct nf_nat_range2 *), \ + AF_INET, "to:", "--to-destination ", false, "dnat") -static void DNAT_fcheck_v2(struct xt_fcheck_call *cb) -{ - __DNAT_fcheck(cb, &((struct nf_nat_range2 *)cb->data)->flags); -} +PSX_GEN(DNAT6, RANGE2_INIT_FROM_RANGE, \ + AF_INET6, "to:", "--to-destination ", false, "dnat") -static void DNAT_print_v2(const void *ip, const struct xt_entry_target *target, - int numeric) -{ - __DNAT_print((const void *)target->data, AF_INET); -} +PSX_GEN(DNAT6v2, *(struct nf_nat_range2 *), \ + AF_INET6, "to:", "--to-destination ", false, "dnat") -static void DNAT_save_v2(const void *ip, const struct xt_entry_target *target) -{ - __DNAT_save((const void *)target->data, AF_INET); -} +PSX_GEN(REDIRECT, RANGE2_INIT_FROM_IPV4_MRC, \ + AF_INET, "redir ports ", "--to-ports ", true, "redirect") -static int DNAT_xlate_v2(struct xt_xlate *xl, - const struct xt_xlate_tg_params *params) -{ - return __DNAT_xlate(xl, (const void *)params->target->data, AF_INET); -} - -static void DNAT_parse6(struct xt_option_call *cb) -{ - const struct ip6t_entry *entry = cb->xt_entry; - struct nf_nat_range *range_v1 = (void *)cb->data; - struct nf_nat_range2 range = {}; +PSX_GEN(REDIRECT6, RANGE2_INIT_FROM_RANGE, \ + AF_INET6, "redir ports ", "--to-ports ", true, "redirect") - memcpy(&range, range_v1, sizeof(*range_v1)); - __DNAT_parse(cb, entry->ipv6.proto, &range, AF_INET6); - memcpy(range_v1, &range, sizeof(*range_v1)); -} +PSX_GEN(SNAT, RANGE2_INIT_FROM_IPV4_MRC, \ + AF_INET, "to:", "--to-source ", false, "snat") -static void DNAT_fcheck6(struct xt_fcheck_call *cb) -{ - struct nf_nat_range *range = (void *)cb->data; +PSX_GEN(SNAT6, RANGE2_INIT_FROM_RANGE, \ + AF_INET6, "to:", "--to-source ", false, "snat") - if (range->flags & NF_NAT_RANGE_PROTO_OFFSET) - xtables_error(PARAMETER_PROBLEM, - "Shifted portmap ranges not supported with this kernel"); +PSX_GEN(MASQUERADE, RANGE2_INIT_FROM_IPV4_MRC, \ + AF_INET, "masq ports: ", "--to-ports ", true, "masquerade") - __DNAT_fcheck(cb, &range->flags); -} +PSX_GEN(MASQUERADE6, RANGE2_INIT_FROM_RANGE, \ + AF_INET6, "masq ports: ", "--to-ports ", true, "masquerade") -static void DNAT_print6(const void *ip, const struct xt_entry_target *target, - int numeric) -{ - struct nf_nat_range2 range = {}; - - memcpy(&range, (const void *)target->data, sizeof(struct nf_nat_range)); - __DNAT_print(&range, AF_INET6); -} - -static void DNAT_save6(const void *ip, const struct xt_entry_target *target) -{ - struct nf_nat_range2 range = {}; - - memcpy(&range, (const void *)target->data, sizeof(struct nf_nat_range)); - __DNAT_save(&range, AF_INET6); -} - -static int DNAT_xlate6(struct xt_xlate *xl, - const struct xt_xlate_tg_params *params) -{ - struct nf_nat_range2 range = {}; - - memcpy(&range, (const void *)params->target->data, - sizeof(struct nf_nat_range)); - return __DNAT_xlate(xl, &range, AF_INET6); -} - -static void DNAT_parse6_v2(struct xt_option_call *cb) -{ - const struct ip6t_entry *entry = cb->xt_entry; - - __DNAT_parse(cb, entry->ipv6.proto, cb->data, AF_INET6); -} - -static void DNAT_print6_v2(const void *ip, const struct xt_entry_target *target, - int numeric) -{ - __DNAT_print((const void *)target->data, AF_INET6); -} - -static void DNAT_save6_v2(const void *ip, const struct xt_entry_target *target) -{ - __DNAT_save((const void *)target->data, AF_INET6); -} - -static int DNAT_xlate6_v2(struct xt_xlate *xl, - const struct xt_xlate_tg_params *params) -{ - return __DNAT_xlate(xl, (const void *)params->target->data, AF_INET6); -} - -static int __REDIRECT_xlate(struct xt_xlate *xl, - const struct nf_nat_range2 *range) -{ - char *range_str = sprint_range(range, AF_INET); - - xt_xlate_add(xl, "redirect"); - if (strlen(range_str)) - xt_xlate_add(xl, " to %s", range_str); - if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) - xt_xlate_add(xl, " random"); - - return 1; -} - -static void REDIRECT_print(const void *ip, const struct xt_entry_target *target, - int numeric) -{ - struct nf_nat_range2 range = RANGE2_INIT_FROM_IPV4_MRC(target->data); - - __REDIRECT_print(&range); -} - -static void REDIRECT_save(const void *ip, const struct xt_entry_target *target) -{ - struct nf_nat_range2 range = RANGE2_INIT_FROM_IPV4_MRC(target->data); - - __REDIRECT_save(&range); -} - -static int REDIRECT_xlate(struct xt_xlate *xl, - const struct xt_xlate_tg_params *params) -{ - struct nf_nat_range2 range = - RANGE2_INIT_FROM_IPV4_MRC(params->target->data); - - return __REDIRECT_xlate(xl, &range); -} - -static void REDIRECT_print6(const void *ip, const struct xt_entry_target *target, - int numeric) -{ - struct nf_nat_range2 range = {}; - - memcpy(&range, (const void *)target->data, sizeof(struct nf_nat_range)); - __REDIRECT_print(&range); -} - -static void REDIRECT_save6(const void *ip, const struct xt_entry_target *target) -{ - struct nf_nat_range2 range = {}; - - memcpy(&range, (const void *)target->data, sizeof(struct nf_nat_range)); - __REDIRECT_save(&range); -} - -static int REDIRECT_xlate6(struct xt_xlate *xl, - const struct xt_xlate_tg_params *params) -{ - struct nf_nat_range2 range = {}; - - memcpy(&range, (const void *)params->target->data, - sizeof(struct nf_nat_range)); - return __REDIRECT_xlate(xl, &range); -} - -static struct xtables_target dnat_tg_reg[] = { +static struct xtables_target nat_tg_reg[] = { + { + .name = "SNAT", + .version = XTABLES_VERSION, + .family = NFPROTO_IPV4, + .size = XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)), + .userspacesize = XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)), + .help = SNAT_help, + .x6_parse = NAT_parse, + .x6_fcheck = SNAT_fcheck, + .print = SNAT_print, + .save = SNAT_save, + .x6_options = SNAT_opts, + .xlate = SNAT_xlate, + }, { .name = "DNAT", .version = XTABLES_VERSION, @@ -559,12 +520,39 @@ static struct xtables_target dnat_tg_reg[] = { .help = DNAT_help, .print = DNAT_print, .save = DNAT_save, - .x6_parse = DNAT_parse, + .x6_parse = NAT_parse, .x6_fcheck = DNAT_fcheck, .x6_options = DNAT_opts, .xlate = DNAT_xlate, }, { + .name = "MASQUERADE", + .version = XTABLES_VERSION, + .family = NFPROTO_IPV4, + .size = XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)), + .userspacesize = XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)), + .help = MASQUERADE_help, + .x6_parse = NAT_parse, + .x6_fcheck = SNAT_fcheck, + .print = MASQUERADE_print, + .save = MASQUERADE_save, + .x6_options = MASQUERADE_opts, + .xlate = MASQUERADE_xlate, + }, + { + .name = "MASQUERADE", + .version = XTABLES_VERSION, + .family = NFPROTO_IPV6, + .size = XT_ALIGN(sizeof(struct nf_nat_range)), + .userspacesize = XT_ALIGN(sizeof(struct nf_nat_range)), + .help = MASQUERADE_help, + .x6_parse = NAT_parse6, + .print = MASQUERADE6_print, + .save = MASQUERADE6_save, + .x6_options = MASQUERADE_opts, + .xlate = MASQUERADE6_xlate, + }, + { .name = "REDIRECT", .version = XTABLES_VERSION, .family = NFPROTO_IPV4, @@ -574,12 +562,26 @@ static struct xtables_target dnat_tg_reg[] = { .help = REDIRECT_help, .print = REDIRECT_print, .save = REDIRECT_save, - .x6_parse = DNAT_parse, + .x6_parse = NAT_parse, .x6_fcheck = DNAT_fcheck, .x6_options = REDIRECT_opts, .xlate = REDIRECT_xlate, }, { + .name = "SNAT", + .version = XTABLES_VERSION, + .family = NFPROTO_IPV6, + .revision = 1, + .size = XT_ALIGN(sizeof(struct nf_nat_range)), + .userspacesize = XT_ALIGN(sizeof(struct nf_nat_range)), + .help = SNAT_help, + .x6_parse = NAT_parse6, + .print = SNAT6_print, + .save = SNAT6_save, + .x6_options = SNAT_opts, + .xlate = SNAT6_xlate, + }, + { .name = "DNAT", .version = XTABLES_VERSION, .family = NFPROTO_IPV6, @@ -587,12 +589,12 @@ static struct xtables_target dnat_tg_reg[] = { .size = XT_ALIGN(sizeof(struct nf_nat_range)), .userspacesize = XT_ALIGN(sizeof(struct nf_nat_range)), .help = DNAT_help, - .print = DNAT_print6, - .save = DNAT_save6, - .x6_parse = DNAT_parse6, + .print = DNAT6_print, + .save = DNAT6_save, + .x6_parse = NAT_parse6, .x6_fcheck = DNAT_fcheck6, .x6_options = DNAT_opts, - .xlate = DNAT_xlate6, + .xlate = DNAT6_xlate, }, { .name = "REDIRECT", @@ -601,12 +603,12 @@ static struct xtables_target dnat_tg_reg[] = { .size = XT_ALIGN(sizeof(struct nf_nat_range)), .userspacesize = XT_ALIGN(sizeof(struct nf_nat_range)), .help = REDIRECT_help, - .print = REDIRECT_print6, - .save = REDIRECT_save6, - .x6_parse = DNAT_parse6, + .print = REDIRECT6_print, + .save = REDIRECT6_save, + .x6_parse = NAT_parse6, .x6_fcheck = DNAT_fcheck6, .x6_options = REDIRECT_opts, - .xlate = REDIRECT_xlate6, + .xlate = REDIRECT6_xlate, }, { .name = "DNAT", @@ -616,12 +618,11 @@ static struct xtables_target dnat_tg_reg[] = { .size = XT_ALIGN(sizeof(struct nf_nat_range2)), .userspacesize = XT_ALIGN(sizeof(struct nf_nat_range2)), .help = DNAT_help_v2, - .print = DNAT_print_v2, - .save = DNAT_save_v2, + .print = DNATv2_print, + .save = DNATv2_save, .x6_parse = DNAT_parse_v2, - .x6_fcheck = DNAT_fcheck_v2, .x6_options = DNAT_opts, - .xlate = DNAT_xlate_v2, + .xlate = DNATv2_xlate, }, { .name = "DNAT", @@ -631,16 +632,15 @@ static struct xtables_target dnat_tg_reg[] = { .size = XT_ALIGN(sizeof(struct nf_nat_range2)), .userspacesize = XT_ALIGN(sizeof(struct nf_nat_range2)), .help = DNAT_help_v2, - .print = DNAT_print6_v2, - .save = DNAT_save6_v2, + .print = DNAT6v2_print, + .save = DNAT6v2_save, .x6_parse = DNAT_parse6_v2, - .x6_fcheck = DNAT_fcheck_v2, .x6_options = DNAT_opts, - .xlate = DNAT_xlate6_v2, + .xlate = DNAT6v2_xlate, }, }; void _init(void) { - xtables_register_targets(dnat_tg_reg, ARRAY_SIZE(dnat_tg_reg)); + xtables_register_targets(nat_tg_reg, ARRAY_SIZE(nat_tg_reg)); } diff --git a/extensions/libxt_NFLOG.c b/extensions/libxt_NFLOG.c index 7a12e5ac..d12ef044 100644 --- a/extensions/libxt_NFLOG.c +++ b/extensions/libxt_NFLOG.c @@ -112,16 +112,12 @@ static void NFLOG_save(const void *ip, const struct xt_entry_target *target) } static void nflog_print_xlate(const struct xt_nflog_info *info, - struct xt_xlate *xl, bool escape_quotes) + struct xt_xlate *xl) { xt_xlate_add(xl, "log "); - if (info->prefix[0] != '\0') { - if (escape_quotes) - xt_xlate_add(xl, "prefix \\\"%s\\\" ", info->prefix); - else - xt_xlate_add(xl, "prefix \"%s\" ", info->prefix); + if (info->prefix[0] != '\0') + xt_xlate_add(xl, "prefix \"%s\" ", info->prefix); - } if (info->flags & XT_NFLOG_F_COPY_LEN) xt_xlate_add(xl, "snaplen %u ", info->len); if (info->threshold != XT_NFLOG_DEFAULT_THRESHOLD) @@ -135,7 +131,7 @@ static int NFLOG_xlate(struct xt_xlate *xl, const struct xt_nflog_info *info = (struct xt_nflog_info *)params->target->data; - nflog_print_xlate(info, xl, params->escape_quotes); + nflog_print_xlate(info, xl); return 1; } diff --git a/extensions/libxt_NFLOG.txlate b/extensions/libxt_NFLOG.txlate index a0872c9e..ebd81be3 100644 --- a/extensions/libxt_NFLOG.txlate +++ b/extensions/libxt_NFLOG.txlate @@ -1,14 +1,14 @@ iptables-translate -A FORWARD -j NFLOG --nflog-group 32 --nflog-prefix "Prefix 1.0" -nft add rule ip filter FORWARD counter log prefix \"Prefix 1.0\" group 32 +nft 'add rule ip filter FORWARD counter log prefix "Prefix 1.0" group 32' iptables-translate -A OUTPUT -j NFLOG --nflog-group 30 -nft add rule ip filter OUTPUT counter log group 30 +nft 'add rule ip filter OUTPUT counter log group 30' iptables-translate -I INPUT -j NFLOG --nflog-threshold 2 -nft insert rule ip filter INPUT counter log queue-threshold 2 group 0 +nft 'insert rule ip filter INPUT counter log queue-threshold 2 group 0' iptables-translate -I INPUT -j NFLOG --nflog-size 256 -nft insert rule ip filter INPUT counter log snaplen 256 group 0 +nft 'insert rule ip filter INPUT counter log snaplen 256 group 0' iptables-translate -I INPUT -j NFLOG --nflog-threshold 25 -nft insert rule ip filter INPUT counter log queue-threshold 25 group 0 +nft 'insert rule ip filter INPUT counter log queue-threshold 25 group 0' diff --git a/extensions/libxt_NFQUEUE.c b/extensions/libxt_NFQUEUE.c index fe519078..ca6cdaf4 100644 --- a/extensions/libxt_NFQUEUE.c +++ b/extensions/libxt_NFQUEUE.c @@ -64,7 +64,7 @@ static const struct xt_option_entry NFQUEUE_opts[] = { {.name = "queue-num", .id = O_QUEUE_NUM, .type = XTTYPE_UINT16, .flags = XTOPT_PUT, XTOPT_POINTER(s, queuenum), .excl = F_QUEUE_BALANCE}, - {.name = "queue-balance", .id = O_QUEUE_BALANCE, + {.name = "queue-balance", .id = O_QUEUE_BALANCE, .max = UINT16_MAX - 1, .type = XTTYPE_UINT16RC, .excl = F_QUEUE_NUM}, {.name = "queue-bypass", .id = O_QUEUE_BYPASS, .type = XTTYPE_NONE}, {.name = "queue-cpu-fanout", .id = O_QUEUE_CPU_FANOUT, diff --git a/extensions/libxt_NFQUEUE.man b/extensions/libxt_NFQUEUE.man index 1bfb7b84..950b0d24 100644 --- a/extensions/libxt_NFQUEUE.man +++ b/extensions/libxt_NFQUEUE.man @@ -18,6 +18,8 @@ This specifies a range of queues to use. Packets are then balanced across the gi This is useful for multicore systems: start multiple instances of the userspace program on queues x, x+1, .. x+n and use "\-\-queue\-balance \fIx\fP\fB:\fP\fIx+n\fP". Packets belonging to the same connection are put into the same nfqueue. +Due to implementation details, a lower range value of 0 limits the higher range +value to 65534, i.e. one can only balance between at most 65535 queues. .PP .TP \fB\-\-queue\-bypass\fP diff --git a/extensions/libxt_NFQUEUE.t b/extensions/libxt_NFQUEUE.t index b51b19fd..8fb2b760 100644 --- a/extensions/libxt_NFQUEUE.t +++ b/extensions/libxt_NFQUEUE.t @@ -1,12 +1,11 @@ :INPUT,FORWARD,OUTPUT --j NFQUEUE;=;OK +-j NFQUEUE;-j NFQUEUE --queue-num 0;OK -j NFQUEUE --queue-num 0;=;OK -j NFQUEUE --queue-num 65535;=;OK -j NFQUEUE --queue-num 65536;;FAIL -j NFQUEUE --queue-num -1;;FAIL -# it says "NFQUEUE: number of total queues is 0", overflow in NFQUEUE_parse_v1? -# ERROR: cannot load: iptables -A INPUT -j NFQUEUE --queue-balance 0:65535 -# -j NFQUEUE --queue-balance 0:65535;=;OK +-j NFQUEUE --queue-balance 0:65534;=;OK +-j NFQUEUE --queue-balance 0:65535;;FAIL -j NFQUEUE --queue-balance 0:65536;;FAIL -j NFQUEUE --queue-balance -1:65535;;FAIL -j NFQUEUE --queue-num 10 --queue-bypass;=;OK diff --git a/extensions/libxt_NFQUEUE.txlate b/extensions/libxt_NFQUEUE.txlate index 3d188a7a..3698dcbc 100644 --- a/extensions/libxt_NFQUEUE.txlate +++ b/extensions/libxt_NFQUEUE.txlate @@ -1,8 +1,8 @@ iptables-translate -t nat -A PREROUTING -p tcp --dport 80 -j NFQUEUE --queue-num 30 -nft add rule ip nat PREROUTING tcp dport 80 counter queue num 30 +nft 'add rule ip nat PREROUTING tcp dport 80 counter queue num 30' iptables-translate -A FORWARD -j NFQUEUE --queue-num 0 --queue-bypass -p TCP --sport 80 -nft add rule ip filter FORWARD tcp sport 80 counter queue num 0 bypass +nft 'add rule ip filter FORWARD tcp sport 80 counter queue num 0 bypass' iptables-translate -A FORWARD -j NFQUEUE --queue-bypass -p TCP --sport 80 --queue-balance 0:3 --queue-cpu-fanout -nft add rule ip filter FORWARD tcp sport 80 counter queue num 0-3 bypass,fanout +nft 'add rule ip filter FORWARD tcp sport 80 counter queue num 0-3 bypass,fanout' diff --git a/extensions/libxt_NOTRACK.txlate b/extensions/libxt_NOTRACK.txlate index 9d35619d..9490ee8f 100644 --- a/extensions/libxt_NOTRACK.txlate +++ b/extensions/libxt_NOTRACK.txlate @@ -1,2 +1,2 @@ iptables-translate -A PREROUTING -t raw -j NOTRACK -nft add rule ip raw PREROUTING counter notrack +nft 'add rule ip raw PREROUTING counter notrack' diff --git a/extensions/libxt_REDIRECT.t b/extensions/libxt_REDIRECT.t index f607dd0a..362efa84 100644 --- a/extensions/libxt_REDIRECT.t +++ b/extensions/libxt_REDIRECT.t @@ -14,3 +14,4 @@ -p tcp -j REDIRECT --to-ports ftp-ssh;;FAIL -p tcp -j REDIRECT --to-ports 10-ssh;;FAIL -j REDIRECT --to-ports 42;;FAIL +-j REDIRECT --random;=;OK diff --git a/extensions/libxt_REDIRECT.txlate b/extensions/libxt_REDIRECT.txlate index 2c536495..dc473340 100644 --- a/extensions/libxt_REDIRECT.txlate +++ b/extensions/libxt_REDIRECT.txlate @@ -1,26 +1,29 @@ iptables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT -nft add rule ip nat prerouting tcp dport 80 counter redirect +nft 'add rule ip nat prerouting tcp dport 80 counter redirect' iptables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT --to-ports 0 -nft add rule ip nat prerouting tcp dport 80 counter redirect to :0 +nft 'add rule ip nat prerouting tcp dport 80 counter redirect to :0' iptables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT --to-ports 8080 -nft add rule ip nat prerouting tcp dport 80 counter redirect to :8080 +nft 'add rule ip nat prerouting tcp dport 80 counter redirect to :8080' iptables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT --to-ports 0-65535 -nft add rule ip nat prerouting tcp dport 80 counter redirect to :0-65535 +nft 'add rule ip nat prerouting tcp dport 80 counter redirect to :0-65535' iptables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT --to-ports 10-22 -nft add rule ip nat prerouting tcp dport 80 counter redirect to :10-22 +nft 'add rule ip nat prerouting tcp dport 80 counter redirect to :10-22' iptables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT --to-ports 8080 --random -nft add rule ip nat prerouting tcp dport 80 counter redirect to :8080 random +nft 'add rule ip nat prerouting tcp dport 80 counter redirect to :8080 random' + +iptables-translate -t nat -A prerouting -j REDIRECT --random +nft 'add rule ip nat prerouting counter redirect random' ip6tables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT -nft add rule ip6 nat prerouting tcp dport 80 counter redirect +nft 'add rule ip6 nat prerouting tcp dport 80 counter redirect' ip6tables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT --to-ports 8080 -nft add rule ip6 nat prerouting tcp dport 80 counter redirect to :8080 +nft 'add rule ip6 nat prerouting tcp dport 80 counter redirect to :8080' ip6tables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT --to-ports 8080 --random -nft add rule ip6 nat prerouting tcp dport 80 counter redirect to :8080 random +nft 'add rule ip6 nat prerouting tcp dport 80 counter redirect to :8080 random' diff --git a/extensions/libxt_SECMARK.c b/extensions/libxt_SECMARK.c index 24249bd6..a4ee60f0 100644 --- a/extensions/libxt_SECMARK.c +++ b/extensions/libxt_SECMARK.c @@ -60,7 +60,7 @@ static void print_secmark(__u8 mode, const char *secctx) break; default: - xtables_error(OTHER_PROBLEM, PFX "invalid mode %hhu\n", mode); + xtables_error(OTHER_PROBLEM, PFX "invalid mode %hhu", mode); } } diff --git a/extensions/libxt_SYNPROXY.txlate b/extensions/libxt_SYNPROXY.txlate index b3de2b2a..b996c4b7 100644 --- a/extensions/libxt_SYNPROXY.txlate +++ b/extensions/libxt_SYNPROXY.txlate @@ -1,2 +1,2 @@ iptables-translate -t mangle -A INPUT -i iifname -p tcp -m tcp --dport 80 -m state --state INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460 -nft add rule ip mangle INPUT iifname "iifname" tcp dport 80 ct state invalid,untracked counter synproxy sack-perm timestamp wscale 7 mss 1460 +nft 'add rule ip mangle INPUT iifname "iifname" tcp dport 80 ct state invalid,untracked counter synproxy sack-perm timestamp wscale 7 mss 1460' diff --git a/extensions/libxt_TCPMSS.c b/extensions/libxt_TCPMSS.c index 0d9b200e..251a5532 100644 --- a/extensions/libxt_TCPMSS.c +++ b/extensions/libxt_TCPMSS.c @@ -131,6 +131,7 @@ static struct xtables_target tcpmss_tg_reg[] = { .x6_parse = TCPMSS_parse, .x6_fcheck = TCPMSS_check, .x6_options = TCPMSS6_opts, + .xlate = TCPMSS_xlate, }, }; diff --git a/extensions/libxt_TCPMSS.txlate b/extensions/libxt_TCPMSS.txlate index 3dbbad66..a059c602 100644 --- a/extensions/libxt_TCPMSS.txlate +++ b/extensions/libxt_TCPMSS.txlate @@ -1,5 +1,5 @@ iptables-translate -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu -nft add rule ip filter FORWARD tcp flags syn / syn,rst counter tcp option maxseg size set rt mtu +nft 'add rule ip filter FORWARD tcp flags syn / syn,rst counter tcp option maxseg size set rt mtu' iptables-translate -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 90 -nft add rule ip filter FORWARD tcp flags syn / syn,rst counter tcp option maxseg size set 90 +nft 'add rule ip filter FORWARD tcp flags syn / syn,rst counter tcp option maxseg size set 90' diff --git a/extensions/libxt_TCPOPTSTRIP.c b/extensions/libxt_TCPOPTSTRIP.c index 6ea34892..ff873f98 100644 --- a/extensions/libxt_TCPOPTSTRIP.c +++ b/extensions/libxt_TCPOPTSTRIP.c @@ -142,6 +142,13 @@ tcpoptstrip_print_list(const struct xt_tcpoptstrip_target_info *info, } } +static bool tcpoptstrip_empty(const struct xt_tcpoptstrip_target_info *info) +{ + static const struct xt_tcpoptstrip_target_info empty = {}; + + return memcmp(info, &empty, sizeof(empty)) == 0; +} + static void tcpoptstrip_tg_print(const void *ip, const struct xt_entry_target *target, int numeric) @@ -149,6 +156,9 @@ tcpoptstrip_tg_print(const void *ip, const struct xt_entry_target *target, const struct xt_tcpoptstrip_target_info *info = (const void *)target->data; + if (tcpoptstrip_empty(info)) + return; + printf(" TCPOPTSTRIP options "); tcpoptstrip_print_list(info, numeric); } @@ -159,6 +169,9 @@ tcpoptstrip_tg_save(const void *ip, const struct xt_entry_target *target) const struct xt_tcpoptstrip_target_info *info = (const void *)target->data; + if (tcpoptstrip_empty(info)) + return; + printf(" --strip-options "); tcpoptstrip_print_list(info, true); } diff --git a/extensions/libxt_TEE.txlate b/extensions/libxt_TEE.txlate index 9fcee254..fa1d5fe3 100644 --- a/extensions/libxt_TEE.txlate +++ b/extensions/libxt_TEE.txlate @@ -1,11 +1,11 @@ # iptables-translate -t mangle -A PREROUTING -j TEE --gateway 192.168.0.2 --oif eth0 -# nft add rule ip mangle PREROUTING counter dup to 192.168.0.2 device eth0 +# nft 'add rule ip mangle PREROUTING counter dup to 192.168.0.2 device eth0 # # iptables-translate -t mangle -A PREROUTING -j TEE --gateway 192.168.0.2 -# nft add rule ip mangle PREROUTING counter dup to 192.168.0.2 +# nft 'add rule ip mangle PREROUTING counter dup to 192.168.0.2 ip6tables-translate -t mangle -A PREROUTING -j TEE --gateway ab12:00a1:1112:acba:: -nft add rule ip6 mangle PREROUTING counter dup to ab12:a1:1112:acba:: +nft 'add rule ip6 mangle PREROUTING counter dup to ab12:a1:1112:acba::' ip6tables-translate -t mangle -A PREROUTING -j TEE --gateway ab12:00a1:1112:acba:: --oif eth0 -nft add rule ip6 mangle PREROUTING counter dup to ab12:a1:1112:acba:: device eth0 +nft 'add rule ip6 mangle PREROUTING counter dup to ab12:a1:1112:acba:: device eth0' diff --git a/extensions/libxt_TOS.c b/extensions/libxt_TOS.c index b66fa329..4fc849bd 100644 --- a/extensions/libxt_TOS.c +++ b/extensions/libxt_TOS.c @@ -183,28 +183,41 @@ static void tos_tg_save(const void *ip, const struct xt_entry_target *target) printf(" --set-tos 0x%02x/0x%02x", info->tos_value, info->tos_mask); } +static int __tos_xlate(struct xt_xlate *xl, const char *ip, + uint8_t tos, uint8_t tosmask) +{ + xt_xlate_add(xl, "%s dscp set ", ip); + if ((tosmask & 0x3f) == 0x3f) + xt_xlate_add(xl, "0x%02x", tos >> 2); + else if (!tos) + xt_xlate_add(xl, "%s dscp and 0x%02x", + ip, (uint8_t)~tosmask >> 2); + else if (tos == tosmask) + xt_xlate_add(xl, "%s dscp or 0x%02x", ip, tos >> 2); + else if (!tosmask) + xt_xlate_add(xl, "%s dscp xor 0x%02x", ip, tos >> 2); + else + xt_xlate_add(xl, "%s dscp and 0x%02x xor 0x%02x", + ip, (uint8_t)~tosmask >> 2, tos >> 2); + return 1; +} + static int tos_xlate(struct xt_xlate *xl, const struct xt_xlate_tg_params *params) { const struct ipt_tos_target_info *info = (struct ipt_tos_target_info *) params->target->data; - uint8_t dscp = info->tos >> 2; - - xt_xlate_add(xl, "ip dscp set 0x%02x", dscp); - return 1; + return __tos_xlate(xl, "ip", info->tos, UINT8_MAX); } static int tos_xlate6(struct xt_xlate *xl, const struct xt_xlate_tg_params *params) { - const struct ipt_tos_target_info *info = - (struct ipt_tos_target_info *) params->target->data; - uint8_t dscp = info->tos >> 2; + const struct xt_tos_target_info *info = + (struct xt_tos_target_info *)params->target->data; - xt_xlate_add(xl, "ip6 dscp set 0x%02x", dscp); - - return 1; + return __tos_xlate(xl, "ip6", info->tos_value, info->tos_mask); } static struct xtables_target tos_tg_reg[] = { diff --git a/extensions/libxt_TOS.t b/extensions/libxt_TOS.t index ae8531cc..9f8e33fd 100644 --- a/extensions/libxt_TOS.t +++ b/extensions/libxt_TOS.t @@ -1,15 +1,15 @@ :PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING *mangle --j TOS --set-tos 0x1f;=;OK +-j TOS --set-tos 0x1f;-j TOS --set-tos 0x1f/0xff;OK -j TOS --set-tos 0x1f/0x1f;=;OK # maximum TOS is 0x1f (5 bits) # ERROR: should fail: iptables -A PREROUTING -t mangle -j TOS --set-tos 0xff # -j TOS --set-tos 0xff;;FAIL --j TOS --set-tos Minimize-Delay;-j TOS --set-tos 0x10;OK --j TOS --set-tos Maximize-Throughput;-j TOS --set-tos 0x08;OK --j TOS --set-tos Maximize-Reliability;-j TOS --set-tos 0x04;OK --j TOS --set-tos Minimize-Cost;-j TOS --set-tos 0x02;OK --j TOS --set-tos Normal-Service;-j TOS --set-tos 0x00;OK +-j TOS --set-tos Minimize-Delay;-j TOS --set-tos 0x10/0x3f;OK +-j TOS --set-tos Maximize-Throughput;-j TOS --set-tos 0x08/0x3f;OK +-j TOS --set-tos Maximize-Reliability;-j TOS --set-tos 0x04/0x3f;OK +-j TOS --set-tos Minimize-Cost;-j TOS --set-tos 0x02/0x3f;OK +-j TOS --set-tos Normal-Service;-j TOS --set-tos 0x00/0x3f;OK -j TOS --and-tos 0x12;-j TOS --set-tos 0x00/0xed;OK -j TOS --or-tos 0x12;-j TOS --set-tos 0x12/0x12;OK -j TOS --xor-tos 0x12;-j TOS --set-tos 0x12/0x00;OK diff --git a/extensions/libxt_TOS.txlate b/extensions/libxt_TOS.txlate index 0952310e..37ef1d86 100644 --- a/extensions/libxt_TOS.txlate +++ b/extensions/libxt_TOS.txlate @@ -1,23 +1,26 @@ ip6tables-translate -A INPUT -j TOS --set-tos 0x1f -nft add rule ip6 filter INPUT counter ip6 dscp set 0x07 +nft 'add rule ip6 filter INPUT counter ip6 dscp set 0x07' ip6tables-translate -A INPUT -j TOS --set-tos 0xff -nft add rule ip6 filter INPUT counter ip6 dscp set 0x3f +nft 'add rule ip6 filter INPUT counter ip6 dscp set 0x3f' ip6tables-translate -A INPUT -j TOS --set-tos Minimize-Delay -nft add rule ip6 filter INPUT counter ip6 dscp set 0x04 +nft 'add rule ip6 filter INPUT counter ip6 dscp set 0x04' ip6tables-translate -A INPUT -j TOS --set-tos Minimize-Cost -nft add rule ip6 filter INPUT counter ip6 dscp set 0x00 +nft 'add rule ip6 filter INPUT counter ip6 dscp set 0x00' ip6tables-translate -A INPUT -j TOS --set-tos Normal-Service -nft add rule ip6 filter INPUT counter ip6 dscp set 0x00 +nft 'add rule ip6 filter INPUT counter ip6 dscp set 0x00' ip6tables-translate -A INPUT -j TOS --and-tos 0x12 -nft add rule ip6 filter INPUT counter ip6 dscp set 0x00 +nft 'add rule ip6 filter INPUT counter ip6 dscp set ip6 dscp and 0x04' ip6tables-translate -A INPUT -j TOS --or-tos 0x12 -nft add rule ip6 filter INPUT counter ip6 dscp set 0x04 +nft 'add rule ip6 filter INPUT counter ip6 dscp set ip6 dscp or 0x04' ip6tables-translate -A INPUT -j TOS --xor-tos 0x12 -nft add rule ip6 filter INPUT counter ip6 dscp set 0x04 +nft 'add rule ip6 filter INPUT counter ip6 dscp set ip6 dscp xor 0x04' + +ip6tables-translate -A INPUT -j TOS --set-tos 0x12/0x34 +nft 'add rule ip6 filter INPUT counter ip6 dscp set ip6 dscp and 0x32 xor 0x04' diff --git a/extensions/libxt_TRACE.txlate b/extensions/libxt_TRACE.txlate index 8e3d2a7a..a9d28fe0 100644 --- a/extensions/libxt_TRACE.txlate +++ b/extensions/libxt_TRACE.txlate @@ -1,2 +1,2 @@ iptables-translate -t raw -A PREROUTING -j TRACE -nft add rule ip raw PREROUTING counter nftrace set 1 +nft 'add rule ip raw PREROUTING counter nftrace set 1' diff --git a/extensions/libxt_addrtype.txlate b/extensions/libxt_addrtype.txlate index a719b2c9..70c0a345 100644 --- a/extensions/libxt_addrtype.txlate +++ b/extensions/libxt_addrtype.txlate @@ -1,11 +1,11 @@ iptables-translate -A INPUT -m addrtype --src-type LOCAL -nft add rule ip filter INPUT fib saddr type local counter +nft 'add rule ip filter INPUT fib saddr type local counter' iptables-translate -A INPUT -m addrtype --dst-type LOCAL -nft add rule ip filter INPUT fib daddr type local counter +nft 'add rule ip filter INPUT fib daddr type local counter' iptables-translate -A INPUT -m addrtype ! --dst-type ANYCAST,LOCAL -nft add rule ip filter INPUT fib daddr type != { local, anycast } counter +nft 'add rule ip filter INPUT fib daddr type != { local, anycast } counter' iptables-translate -A INPUT -m addrtype --limit-iface-in --dst-type ANYCAST,LOCAL -nft add rule ip filter INPUT fib daddr . iif type { local, anycast } counter +nft 'add rule ip filter INPUT fib daddr . iif type { local, anycast } counter' diff --git a/extensions/libxt_bpf.c b/extensions/libxt_bpf.c index eeae86e5..5e035837 100644 --- a/extensions/libxt_bpf.c +++ b/extensions/libxt_bpf.c @@ -83,8 +83,7 @@ static int bpf_obj_get_readonly(const char *filepath) attr.file_flags = 0; return syscall(__NR_bpf, BPF_OBJ_GET, &attr, sizeof(attr)); #else - xtables_error(OTHER_PROBLEM, - "No bpf header, kernel headers too old?\n"); + xtables_error(OTHER_PROBLEM, "No bpf header, kernel headers too old?"); return -EINVAL; #endif } diff --git a/extensions/libxt_cgroup.txlate b/extensions/libxt_cgroup.txlate index 75f2e6ae..6e3aab76 100644 --- a/extensions/libxt_cgroup.txlate +++ b/extensions/libxt_cgroup.txlate @@ -1,5 +1,5 @@ iptables-translate -t filter -A INPUT -m cgroup --cgroup 0 -j ACCEPT -nft add rule ip filter INPUT meta cgroup 0 counter accept +nft 'add rule ip filter INPUT meta cgroup 0 counter accept' iptables-translate -t filter -A INPUT -m cgroup ! --cgroup 0 -j ACCEPT -nft add rule ip filter INPUT meta cgroup != 0 counter accept +nft 'add rule ip filter INPUT meta cgroup != 0 counter accept' diff --git a/extensions/libxt_cluster.txlate b/extensions/libxt_cluster.txlate index 9dcf5707..4dc1c691 100644 --- a/extensions/libxt_cluster.txlate +++ b/extensions/libxt_cluster.txlate @@ -1,26 +1,26 @@ iptables-translate -A PREROUTING -t mangle -i eth1 -m cluster --cluster-total-nodes 2 --cluster-local-node 1 --cluster-hash-seed 0xdeadbeef -j MARK --set-mark 0xffff -nft add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 2 seed 0xdeadbeef eq 1 meta pkttype set host counter meta mark set 0xffff +nft 'add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 2 seed 0xdeadbeef eq 1 meta pkttype set host counter meta mark set 0xffff' iptables-translate -A PREROUTING -t mangle -i eth1 -m cluster --cluster-total-nodes 1 --cluster-local-node 1 --cluster-hash-seed 0xdeadbeef -j MARK --set-mark 0xffff -nft add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 1 seed 0xdeadbeef eq 1 meta pkttype set host counter meta mark set 0xffff +nft 'add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 1 seed 0xdeadbeef eq 1 meta pkttype set host counter meta mark set 0xffff' iptables-translate -A PREROUTING -t mangle -i eth1 -m cluster --cluster-total-nodes 2 --cluster-local-nodemask 1 --cluster-hash-seed 0xdeadbeef -j MARK --set-mark 0xffff -nft add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 2 seed 0xdeadbeef eq 1 meta pkttype set host counter meta mark set 0xffff +nft 'add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 2 seed 0xdeadbeef eq 1 meta pkttype set host counter meta mark set 0xffff' iptables-translate -A PREROUTING -t mangle -i eth1 -m cluster --cluster-total-nodes 1 --cluster-local-nodemask 1 --cluster-hash-seed 0xdeadbeef -j MARK --set-mark 0xffff -nft add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 1 seed 0xdeadbeef eq 1 meta pkttype set host counter meta mark set 0xffff +nft 'add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 1 seed 0xdeadbeef eq 1 meta pkttype set host counter meta mark set 0xffff' iptables-translate -A PREROUTING -t mangle -i eth1 -m cluster --cluster-total-nodes 32 --cluster-local-node 32 --cluster-hash-seed 0xdeadbeef -j MARK --set-mark 0xffff -nft add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 32 seed 0xdeadbeef eq 32 meta pkttype set host counter meta mark set 0xffff +nft 'add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 32 seed 0xdeadbeef eq 32 meta pkttype set host counter meta mark set 0xffff' iptables-translate -A PREROUTING -t mangle -i eth1 -m cluster --cluster-total-nodes 32 --cluster-local-nodemask 32 --cluster-hash-seed 0xdeadbeef -j MARK --set-mark 0xffff -nft add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 32 seed 0xdeadbeef eq 6 meta pkttype set host counter meta mark set 0xffff +nft 'add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 32 seed 0xdeadbeef eq 6 meta pkttype set host counter meta mark set 0xffff' iptables-translate -A PREROUTING -t mangle -i eth1 -m cluster --cluster-total-nodes 32 --cluster-local-nodemask 5 --cluster-hash-seed 0xdeadbeef -j MARK --set-mark 0xffff -nft add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 32 seed 0xdeadbeef { 0, 2 } meta pkttype set host counter meta mark set 0xffff +nft 'add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 32 seed 0xdeadbeef { 0, 2 } meta pkttype set host counter meta mark set 0xffff' iptables-translate -A PREROUTING -t mangle -i eth1 -m cluster --cluster-total-nodes 7 --cluster-local-nodemask 9 --cluster-hash-seed 0xdeadbeef -j MARK --set-mark 0xffff -nft add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 7 seed 0xdeadbeef { 0, 3 } meta pkttype set host counter meta mark set 0xffff +nft 'add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 7 seed 0xdeadbeef { 0, 3 } meta pkttype set host counter meta mark set 0xffff' iptables-translate -A PREROUTING -t mangle -i eth1 -m cluster --cluster-total-nodes 7 --cluster-local-node 5 --cluster-hash-seed 0xdeadbeef -j MARK --set-mark 0xffff -nft add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 7 seed 0xdeadbeef eq 5 meta pkttype set host counter meta mark set 0xffff +nft 'add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 7 seed 0xdeadbeef eq 5 meta pkttype set host counter meta mark set 0xffff' diff --git a/extensions/libxt_comment.c b/extensions/libxt_comment.c index 69795b6c..e9c539f6 100644 --- a/extensions/libxt_comment.c +++ b/extensions/libxt_comment.c @@ -55,12 +55,7 @@ static int comment_xlate(struct xt_xlate *xl, char comment[XT_MAX_COMMENT_LEN + sizeof("\\\"\\\"")]; commentinfo->comment[XT_MAX_COMMENT_LEN - 1] = '\0'; - if (params->escape_quotes) - snprintf(comment, sizeof(comment), "\\\"%s\\\"", - commentinfo->comment); - else - snprintf(comment, sizeof(comment), "\"%s\"", - commentinfo->comment); + snprintf(comment, sizeof(comment), "\"%s\"", commentinfo->comment); xt_xlate_add_comment(xl, comment); diff --git a/extensions/libxt_comment.txlate b/extensions/libxt_comment.txlate index c610b0e5..5d4ce59d 100644 --- a/extensions/libxt_comment.txlate +++ b/extensions/libxt_comment.txlate @@ -1,8 +1,8 @@ iptables-translate -A INPUT -s 192.168.0.0 -m comment --comment "A privatized IP block" -nft add rule ip filter INPUT ip saddr 192.168.0.0 counter comment \"A privatized IP block\" +nft 'add rule ip filter INPUT ip saddr 192.168.0.0 counter comment "A privatized IP block"' iptables-translate -A INPUT -p tcp -m tcp --sport http -s 192.168.0.0/16 -d 192.168.0.0/16 -j LONGNACCEPT -m comment --comment "foobar" -nft add rule ip filter INPUT ip saddr 192.168.0.0/16 ip daddr 192.168.0.0/16 tcp sport 80 counter jump LONGNACCEPT comment \"foobar\" +nft 'add rule ip filter INPUT ip saddr 192.168.0.0/16 ip daddr 192.168.0.0/16 tcp sport 80 counter jump LONGNACCEPT comment "foobar"' iptables-translate -A FORWARD -p tcp -m tcp --sport http -s 192.168.0.0/16 -d 192.168.0.0/16 -j DROP -m comment --comment singlecomment -nft add rule ip filter FORWARD ip saddr 192.168.0.0/16 ip daddr 192.168.0.0/16 tcp sport 80 counter drop comment \"singlecomment\" +nft 'add rule ip filter FORWARD ip saddr 192.168.0.0/16 ip daddr 192.168.0.0/16 tcp sport 80 counter drop comment "singlecomment"' diff --git a/extensions/libxt_connbytes.txlate b/extensions/libxt_connbytes.txlate index f78958d2..a6af1b87 100644 --- a/extensions/libxt_connbytes.txlate +++ b/extensions/libxt_connbytes.txlate @@ -1,14 +1,14 @@ iptables-translate -A OUTPUT -m connbytes --connbytes 200 --connbytes-dir original --connbytes-mode packets -nft add rule ip filter OUTPUT ct original packets ge 200 counter +nft 'add rule ip filter OUTPUT ct original packets ge 200 counter' iptables-translate -A OUTPUT -m connbytes ! --connbytes 200 --connbytes-dir reply --connbytes-mode packets -nft add rule ip filter OUTPUT ct reply packets lt 200 counter +nft 'add rule ip filter OUTPUT ct reply packets lt 200 counter' iptables-translate -A OUTPUT -m connbytes --connbytes 200:600 --connbytes-dir both --connbytes-mode bytes -nft add rule ip filter OUTPUT ct bytes 200-600 counter +nft 'add rule ip filter OUTPUT ct bytes 200-600 counter' iptables-translate -A OUTPUT -m connbytes ! --connbytes 200:600 --connbytes-dir both --connbytes-mode bytes -nft add rule ip filter OUTPUT ct bytes != 200-600 counter +nft 'add rule ip filter OUTPUT ct bytes != 200-600 counter' iptables-translate -A OUTPUT -m connbytes --connbytes 200:200 --connbytes-dir both --connbytes-mode avgpkt -nft add rule ip filter OUTPUT ct avgpkt 200 counter +nft 'add rule ip filter OUTPUT ct avgpkt 200 counter' diff --git a/extensions/libxt_connlabel.txlate b/extensions/libxt_connlabel.txlate index 12e4ac03..cba01d2d 100644 --- a/extensions/libxt_connlabel.txlate +++ b/extensions/libxt_connlabel.txlate @@ -1,5 +1,5 @@ iptables-translate -A INPUT -m connlabel --label 40 -nft add rule ip filter INPUT ct label 40 counter +nft 'add rule ip filter INPUT ct label 40 counter' iptables-translate -A INPUT -m connlabel ! --label 40 --set -nft add rule ip filter INPUT ct label set 40 ct label and 40 != 40 counter +nft 'add rule ip filter INPUT ct label set 40 ct label and 40 != 40 counter' diff --git a/extensions/libxt_connlimit.t b/extensions/libxt_connlimit.t index c7ea61e9..366cea74 100644 --- a/extensions/libxt_connlimit.t +++ b/extensions/libxt_connlimit.t @@ -1,11 +1,11 @@ :INPUT,FORWARD,OUTPUT --m connlimit --connlimit-upto 0;=;OK --m connlimit --connlimit-upto 4294967295;=;OK --m connlimit --connlimit-upto 4294967296;;FAIL +-m connlimit --connlimit-upto 0;-m connlimit --connlimit-upto 0 --connlimit-mask 32 --connlimit-saddr;OK +-m connlimit --connlimit-upto 4294967295 --connlimit-mask 32 --connlimit-saddr;=;OK +-m connlimit --connlimit-upto 4294967296 --connlimit-mask 32 --connlimit-saddr;;FAIL -m connlimit --connlimit-upto -1;;FAIL --m connlimit --connlimit-above 0;=;OK --m connlimit --connlimit-above 4294967295;=;OK --m connlimit --connlimit-above 4294967296;;FAIL +-m connlimit --connlimit-above 0;-m connlimit --connlimit-above 0 --connlimit-mask 32 --connlimit-saddr;OK +-m connlimit --connlimit-above 4294967295 --connlimit-mask 32 --connlimit-saddr;=;OK +-m connlimit --connlimit-above 4294967296 --connlimit-mask 32 --connlimit-saddr;;FAIL -m connlimit --connlimit-above -1;;FAIL -m connlimit --connlimit-upto 1 --conlimit-above 1;;FAIL -m connlimit --connlimit-above 10 --connlimit-saddr;-m connlimit --connlimit-above 10 --connlimit-mask 32 --connlimit-saddr;OK diff --git a/extensions/libxt_connlimit.txlate b/extensions/libxt_connlimit.txlate index 758868c4..3108a529 100644 --- a/extensions/libxt_connlimit.txlate +++ b/extensions/libxt_connlimit.txlate @@ -1,15 +1,15 @@ iptables-translate -A INPUT -m connlimit --connlimit-above 2 -nft add set ip filter connlimit0 { type ipv4_addr; flags dynamic; } -nft add rule ip filter INPUT add @connlimit0 { ip saddr ct count over 2 } counter +nft 'add set ip filter connlimit0 { type ipv4_addr; flags dynamic; }' +nft 'add rule ip filter INPUT add @connlimit0 { ip saddr ct count over 2 } counter' iptables-translate -A INPUT -m connlimit --connlimit-upto 2 -nft add set ip filter connlimit0 { type ipv4_addr; flags dynamic; } -nft add rule ip filter INPUT add @connlimit0 { ip saddr ct count 2 } counter +nft 'add set ip filter connlimit0 { type ipv4_addr; flags dynamic; }' +nft 'add rule ip filter INPUT add @connlimit0 { ip saddr ct count 2 } counter' iptables-translate -A INPUT -m connlimit --connlimit-upto 2 --connlimit-mask 24 -nft add set ip filter connlimit0 { type ipv4_addr; flags dynamic; } -nft add rule ip filter INPUT add @connlimit0 { ip saddr and 255.255.255.0 ct count 2 } counter +nft 'add set ip filter connlimit0 { type ipv4_addr; flags dynamic; }' +nft 'add rule ip filter INPUT add @connlimit0 { ip saddr and 255.255.255.0 ct count 2 } counter' iptables-translate -A INPUT -m connlimit --connlimit-upto 2 --connlimit-daddr -nft add set ip filter connlimit0 { type ipv4_addr; flags dynamic; } -nft add rule ip filter INPUT add @connlimit0 { ip daddr ct count 2 } counter +nft 'add set ip filter connlimit0 { type ipv4_addr; flags dynamic; }' +nft 'add rule ip filter INPUT add @connlimit0 { ip daddr ct count 2 } counter' diff --git a/extensions/libxt_connmark.t b/extensions/libxt_connmark.t index 4dd7d9af..353970a8 100644 --- a/extensions/libxt_connmark.t +++ b/extensions/libxt_connmark.t @@ -2,8 +2,8 @@ *mangle -m connmark --mark 0xffffffff;=;OK -m connmark --mark 0xffffffff/0xffffffff;-m connmark --mark 0xffffffff;OK --m connmark --mark 0xffffffff/0;=;OK --m connmark --mark 0/0xffffffff;-m connmark --mark 0;OK +-m connmark --mark 0xffffffff/0x0;=;OK +-m connmark --mark 0/0xffffffff;-m connmark --mark 0x0;OK -m connmark --mark -1;;FAIL -m connmark --mark 0xfffffffff;;FAIL -m connmark;;FAIL diff --git a/extensions/libxt_connmark.txlate b/extensions/libxt_connmark.txlate index 89423259..e7bfd721 100644 --- a/extensions/libxt_connmark.txlate +++ b/extensions/libxt_connmark.txlate @@ -1,14 +1,14 @@ iptables-translate -A INPUT -m connmark --mark 2 -j ACCEPT -nft add rule ip filter INPUT ct mark 0x2 counter accept +nft 'add rule ip filter INPUT ct mark 0x2 counter accept' iptables-translate -A INPUT -m connmark ! --mark 2 -j ACCEPT -nft add rule ip filter INPUT ct mark != 0x2 counter accept +nft 'add rule ip filter INPUT ct mark != 0x2 counter accept' iptables-translate -A INPUT -m connmark --mark 10/10 -j ACCEPT -nft add rule ip filter INPUT ct mark and 0xa == 0xa counter accept +nft 'add rule ip filter INPUT ct mark and 0xa == 0xa counter accept' iptables-translate -A INPUT -m connmark ! --mark 10/10 -j ACCEPT -nft add rule ip filter INPUT ct mark and 0xa != 0xa counter accept +nft 'add rule ip filter INPUT ct mark and 0xa != 0xa counter accept' iptables-translate -t mangle -A PREROUTING -p tcp --dport 40 -m connmark --mark 0x40 -nft add rule ip mangle PREROUTING tcp dport 40 ct mark 0x40 counter +nft 'add rule ip mangle PREROUTING tcp dport 40 ct mark 0x40 counter' diff --git a/extensions/libxt_conntrack.c b/extensions/libxt_conntrack.c index 64018ce1..ffbc7467 100644 --- a/extensions/libxt_conntrack.c +++ b/extensions/libxt_conntrack.c @@ -346,14 +346,13 @@ static void conntrack_parse(struct xt_option_call *cb) sinfo->invflags |= XT_CONNTRACK_STATE; break; case O_CTPROTO: + if (cb->val.protocol == 0) + xtables_error(PARAMETER_PROBLEM, cb->invert ? + "condition would always match protocol" : + "rule would never match protocol"); sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum = cb->val.protocol; if (cb->invert) sinfo->invflags |= XT_CONNTRACK_PROTO; - if (sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum == 0 - && (sinfo->invflags & XT_INV_PROTO)) - xtables_error(PARAMETER_PROBLEM, - "rule would never match protocol"); - sinfo->flags |= XT_CONNTRACK_PROTO; break; case O_CTORIGSRC: @@ -411,11 +410,11 @@ static void conntrack_mt_parse(struct xt_option_call *cb, uint8_t rev) info->invert_flags |= XT_CONNTRACK_STATE; break; case O_CTPROTO: + if (cb->val.protocol == 0) + xtables_error(PARAMETER_PROBLEM, cb->invert ? + "conntrack: condition would always match protocol" : + "conntrack: rule would never match protocol"); info->l4proto = cb->val.protocol; - if (info->l4proto == 0 && (info->invert_flags & XT_INV_PROTO)) - xtables_error(PARAMETER_PROBLEM, "conntrack: rule would " - "never match protocol"); - info->match_flags |= XT_CONNTRACK_PROTO; if (cb->invert) info->invert_flags |= XT_CONNTRACK_PROTO; @@ -778,7 +777,7 @@ matchinfo_print(const void *ip, const struct xt_entry_match *match, int numeric, static void conntrack_dump_ports(const char *prefix, const char *opt, - u_int16_t port_low, u_int16_t port_high) + uint16_t port_low, uint16_t port_high) { if (port_high == 0 || port_low == port_high) printf(" %s%s %u", prefix, opt, port_low); @@ -1186,7 +1185,6 @@ static int state_xlate(struct xt_xlate *xl, xt_xlate_add(xl, "ct state "); state_xlate_print(xl, sinfo->state_mask, sinfo->invert_flags & XT_CONNTRACK_STATE); - xt_xlate_add(xl, " "); return 1; } @@ -1289,9 +1287,6 @@ static int _conntrack3_mt_xlate(struct xt_xlate *xl, } if (sinfo->match_flags & XT_CONNTRACK_ORIGSRC) { - if (&sinfo->origsrc_addr == 0L) - return 0; - xt_xlate_add(xl, "%sct original saddr %s", space, sinfo->invert_flags & XT_CONNTRACK_ORIGSRC ? "!= " : ""); @@ -1301,9 +1296,6 @@ static int _conntrack3_mt_xlate(struct xt_xlate *xl, } if (sinfo->match_flags & XT_CONNTRACK_ORIGDST) { - if (&sinfo->origdst_addr == 0L) - return 0; - xt_xlate_add(xl, "%sct original daddr %s", space, sinfo->invert_flags & XT_CONNTRACK_ORIGDST ? "!= " : ""); @@ -1313,9 +1305,6 @@ static int _conntrack3_mt_xlate(struct xt_xlate *xl, } if (sinfo->match_flags & XT_CONNTRACK_REPLSRC) { - if (&sinfo->replsrc_addr == 0L) - return 0; - xt_xlate_add(xl, "%sct reply saddr %s", space, sinfo->invert_flags & XT_CONNTRACK_REPLSRC ? "!= " : ""); @@ -1325,9 +1314,6 @@ static int _conntrack3_mt_xlate(struct xt_xlate *xl, } if (sinfo->match_flags & XT_CONNTRACK_REPLDST) { - if (&sinfo->repldst_addr == 0L) - return 0; - xt_xlate_add(xl, "%sct reply daddr %s", space, sinfo->invert_flags & XT_CONNTRACK_REPLDST ? "!= " : ""); diff --git a/extensions/libxt_conntrack.t b/extensions/libxt_conntrack.t index db531475..2b3c5de9 100644 --- a/extensions/libxt_conntrack.t +++ b/extensions/libxt_conntrack.t @@ -25,3 +25,5 @@ -m conntrack --ctstatus EXPECTED;=;OK -m conntrack --ctstatus SEEN_REPLY;=;OK -m conntrack;;FAIL +-m conntrack --ctproto 0;;FAIL +-m conntrack ! --ctproto 0;;FAIL diff --git a/extensions/libxt_conntrack.txlate b/extensions/libxt_conntrack.txlate index 45fba984..0f44a957 100644 --- a/extensions/libxt_conntrack.txlate +++ b/extensions/libxt_conntrack.txlate @@ -1,60 +1,60 @@ iptables-translate -t filter -A INPUT -m conntrack --ctstate NEW,RELATED -j ACCEPT -nft add rule ip filter INPUT ct state new,related counter accept +nft 'add rule ip filter INPUT ct state new,related counter accept' ip6tables-translate -t filter -A INPUT -m conntrack ! --ctstate NEW,RELATED -j ACCEPT -nft add rule ip6 filter INPUT ct state ! new,related counter accept +nft 'add rule ip6 filter INPUT ct state ! new,related counter accept' ip6tables-translate -t filter -A INPUT -m conntrack ! --ctstate NEW -j ACCEPT -nft add rule ip6 filter INPUT ct state ! new counter accept +nft 'add rule ip6 filter INPUT ct state ! new counter accept' iptables-translate -t filter -A INPUT -m conntrack --ctproto UDP -j ACCEPT -nft add rule ip filter INPUT ct original protocol 17 counter accept +nft 'add rule ip filter INPUT ct original protocol 17 counter accept' iptables-translate -t filter -A INPUT -m conntrack ! --ctproto UDP -j ACCEPT -nft add rule ip filter INPUT ct original protocol != 17 counter accept +nft 'add rule ip filter INPUT ct original protocol != 17 counter accept' iptables-translate -t filter -A INPUT -m conntrack --ctorigsrc 10.100.2.131 -j ACCEPT -nft add rule ip filter INPUT ct original saddr 10.100.2.131 counter accept +nft 'add rule ip filter INPUT ct original saddr 10.100.2.131 counter accept' iptables-translate -t filter -A INPUT -m conntrack --ctorigsrc 10.100.0.0/255.255.0.0 -j ACCEPT -nft add rule ip filter INPUT ct original saddr 10.100.0.0/16 counter accept +nft 'add rule ip filter INPUT ct original saddr 10.100.0.0/16 counter accept' iptables-translate -t filter -A INPUT -m conntrack --ctorigdst 10.100.2.131 -j ACCEPT -nft add rule ip filter INPUT ct original daddr 10.100.2.131 counter accept +nft 'add rule ip filter INPUT ct original daddr 10.100.2.131 counter accept' iptables-translate -t filter -A INPUT -m conntrack --ctreplsrc 10.100.2.131 -j ACCEPT -nft add rule ip filter INPUT ct reply saddr 10.100.2.131 counter accept +nft 'add rule ip filter INPUT ct reply saddr 10.100.2.131 counter accept' iptables-translate -t filter -A INPUT -m conntrack --ctrepldst 10.100.2.131 -j ACCEPT -nft add rule ip filter INPUT ct reply daddr 10.100.2.131 counter accept +nft 'add rule ip filter INPUT ct reply daddr 10.100.2.131 counter accept' iptables-translate -t filter -A INPUT -m conntrack --ctproto tcp --ctorigsrcport 443:444 -j ACCEPT -nft add rule ip filter INPUT ct original protocol 6 ct original proto-src 443-444 counter accept +nft 'add rule ip filter INPUT ct original protocol 6 ct original proto-src 443-444 counter accept' iptables-translate -t filter -A INPUT -m conntrack --ctstatus EXPECTED -j ACCEPT -nft add rule ip filter INPUT ct status expected counter accept +nft 'add rule ip filter INPUT ct status expected counter accept' iptables-translate -t filter -A INPUT -m conntrack ! --ctstatus CONFIRMED -j ACCEPT -nft add rule ip filter INPUT ct status ! confirmed counter accept +nft 'add rule ip filter INPUT ct status ! confirmed counter accept' iptables-translate -t filter -A INPUT -m conntrack ! --ctstatus CONFIRMED,ASSURED -j ACCEPT -nft add rule ip filter INPUT ct status ! assured,confirmed counter accept +nft 'add rule ip filter INPUT ct status ! assured,confirmed counter accept' iptables-translate -t filter -A INPUT -m conntrack --ctstatus CONFIRMED,ASSURED -j ACCEPT -nft add rule ip filter INPUT ct status assured,confirmed counter accept +nft 'add rule ip filter INPUT ct status assured,confirmed counter accept' iptables-translate -t filter -A INPUT -m conntrack --ctexpire 3 -j ACCEPT -nft add rule ip filter INPUT ct expiration 3 counter accept +nft 'add rule ip filter INPUT ct expiration 3 counter accept' iptables-translate -t filter -A INPUT -m conntrack --ctdir ORIGINAL -j ACCEPT -nft add rule ip filter INPUT ct direction original counter accept +nft 'add rule ip filter INPUT ct direction original counter accept' iptables-translate -t filter -A INPUT -m conntrack --ctstate NEW --ctproto tcp --ctorigsrc 192.168.0.1 --ctorigdst 192.168.0.1 --ctreplsrc 192.168.0.1 --ctrepldst 192.168.0.1 --ctorigsrcport 12 --ctorigdstport 14 --ctreplsrcport 16 --ctrepldstport 18 --ctexpire 10 --ctstatus SEEN_REPLY --ctdir ORIGINAL -j ACCEPT -nft add rule ip filter INPUT ct direction original ct original protocol 6 ct state new ct status seen-reply ct expiration 10 ct original saddr 192.168.0.1 ct original daddr 192.168.0.1 ct reply saddr 192.168.0.1 ct reply daddr 192.168.0.1 ct original proto-src 12 ct original proto-dst 14 ct reply proto-src 16 ct reply proto-dst 18 counter accept +nft 'add rule ip filter INPUT ct direction original ct original protocol 6 ct state new ct status seen-reply ct expiration 10 ct original saddr 192.168.0.1 ct original daddr 192.168.0.1 ct reply saddr 192.168.0.1 ct reply daddr 192.168.0.1 ct original proto-src 12 ct original proto-dst 14 ct reply proto-src 16 ct reply proto-dst 18 counter accept' iptables-translate -t filter -A INPUT -m conntrack --ctstate SNAT -j ACCEPT -nft add rule ip filter INPUT ct status snat counter accept +nft 'add rule ip filter INPUT ct status snat counter accept' iptables-translate -t filter -A INPUT -m conntrack --ctstate DNAT -j ACCEPT -nft add rule ip filter INPUT ct status dnat counter accept +nft 'add rule ip filter INPUT ct status dnat counter accept' diff --git a/extensions/libxt_cpu.man b/extensions/libxt_cpu.man index d9ea5c2f..c89ef08a 100644 --- a/extensions/libxt_cpu.man +++ b/extensions/libxt_cpu.man @@ -7,9 +7,9 @@ multiqueue NICs to spread network traffic on different queues. Example: .PP iptables \-t nat \-A PREROUTING \-p tcp \-\-dport 80 \-m cpu \-\-cpu 0 -\-j REDIRECT \-\-to\-port 8080 +\-j REDIRECT \-\-to\-ports 8080 .PP iptables \-t nat \-A PREROUTING \-p tcp \-\-dport 80 \-m cpu \-\-cpu 1 -\-j REDIRECT \-\-to\-port 8081 +\-j REDIRECT \-\-to\-ports 8081 .PP Available since Linux 2.6.36. diff --git a/extensions/libxt_cpu.txlate b/extensions/libxt_cpu.txlate index c59b0e02..937c939e 100644 --- a/extensions/libxt_cpu.txlate +++ b/extensions/libxt_cpu.txlate @@ -1,5 +1,5 @@ iptables-translate -A INPUT -p tcp --dport 80 -m cpu --cpu 0 -j ACCEPT -nft add rule ip filter INPUT tcp dport 80 cpu 0 counter accept +nft 'add rule ip filter INPUT tcp dport 80 cpu 0 counter accept' iptables-translate -A INPUT -p tcp --dport 80 -m cpu ! --cpu 1 -j ACCEPT -nft add rule ip filter INPUT tcp dport 80 cpu != 1 counter accept +nft 'add rule ip filter INPUT tcp dport 80 cpu != 1 counter accept' diff --git a/extensions/libxt_dccp.c b/extensions/libxt_dccp.c index abd420fc..bfceced3 100644 --- a/extensions/libxt_dccp.c +++ b/extensions/libxt_dccp.c @@ -343,7 +343,6 @@ static int dccp_xlate(struct xt_xlate *xl, { const struct xt_dccp_info *einfo = (const struct xt_dccp_info *)params->match->data; - char *space = ""; int ret = 1; if (einfo->flags & XT_DCCP_SRC_PORTS) { @@ -353,27 +352,21 @@ static int dccp_xlate(struct xt_xlate *xl, if (einfo->spts[0] != einfo->spts[1]) xt_xlate_add(xl, "-%u", einfo->spts[1]); - - space = " "; } if (einfo->flags & XT_DCCP_DEST_PORTS) { - xt_xlate_add(xl, "%sdccp dport%s %u", space, + xt_xlate_add(xl, "dccp dport%s %u", einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "", einfo->dpts[0]); if (einfo->dpts[0] != einfo->dpts[1]) xt_xlate_add(xl, "-%u", einfo->dpts[1]); - - space = " "; } if (einfo->flags & XT_DCCP_TYPE && einfo->typemask) { - xt_xlate_add(xl, "%sdccp type%s ", space, + xt_xlate_add(xl, "dccp type%s ", einfo->invflags & XT_DCCP_TYPE ? " !=" : ""); ret = dccp_type_xlate(einfo, xl); - - space = " "; } /* FIXME: no dccp option support in nftables yet */ diff --git a/extensions/libxt_dccp.txlate b/extensions/libxt_dccp.txlate index ea853f6a..a4da1a79 100644 --- a/extensions/libxt_dccp.txlate +++ b/extensions/libxt_dccp.txlate @@ -1,20 +1,20 @@ iptables-translate -A INPUT -p dccp -m dccp --sport 100 -nft add rule ip filter INPUT dccp sport 100 counter +nft 'add rule ip filter INPUT dccp sport 100 counter' iptables-translate -A INPUT -p dccp -m dccp --dport 100:200 -nft add rule ip filter INPUT dccp dport 100-200 counter +nft 'add rule ip filter INPUT dccp dport 100-200 counter' iptables-translate -A INPUT -p dccp -m dccp ! --dport 100 -nft add rule ip filter INPUT dccp dport != 100 counter +nft 'add rule ip filter INPUT dccp dport != 100 counter' iptables-translate -A INPUT -p dccp -m dccp --dccp-types CLOSE -nft add rule ip filter INPUT dccp type close counter +nft 'add rule ip filter INPUT dccp type close counter' iptables-translate -A INPUT -p dccp -m dccp --dccp-types INVALID -nft add rule ip filter INPUT dccp type 10-15 counter +nft 'add rule ip filter INPUT dccp type 10-15 counter' iptables-translate -A INPUT -p dccp -m dccp --dport 100 --dccp-types REQUEST,RESPONSE,DATA,ACK,DATAACK,CLOSEREQ,CLOSE,SYNC,SYNCACK,INVALID -nft add rule ip filter INPUT dccp dport 100 dccp type {request, response, data, ack, dataack, closereq, close, sync, syncack, 10-15} counter +nft 'add rule ip filter INPUT dccp dport 100 dccp type { request, response, data, ack, dataack, closereq, close, sync, syncack, 10-15 } counter' iptables-translate -A INPUT -p dccp -m dccp --sport 200 --dport 100 -nft add rule ip filter INPUT dccp sport 200 dccp dport 100 counter +nft 'add rule ip filter INPUT dccp sport 200 dccp dport 100 counter' diff --git a/extensions/libxt_devgroup.c b/extensions/libxt_devgroup.c index a88211c5..f60526ff 100644 --- a/extensions/libxt_devgroup.c +++ b/extensions/libxt_devgroup.c @@ -129,7 +129,6 @@ static void devgroup_show_xlate(const struct xt_devgroup_info *info, struct xt_xlate *xl, int numeric) { enum xt_op op = XT_OP_EQ; - char *space = ""; if (info->flags & XT_DEVGROUP_MATCH_SRC) { if (info->flags & XT_DEVGROUP_INVERT_SRC) @@ -137,13 +136,12 @@ static void devgroup_show_xlate(const struct xt_devgroup_info *info, xt_xlate_add(xl, "iifgroup "); print_devgroup_xlate(info->src_group, op, info->src_mask, xl, numeric); - space = " "; } if (info->flags & XT_DEVGROUP_MATCH_DST) { if (info->flags & XT_DEVGROUP_INVERT_DST) op = XT_OP_NEQ; - xt_xlate_add(xl, "%soifgroup ", space); + xt_xlate_add(xl, "oifgroup "); print_devgroup_xlate(info->dst_group, op, info->dst_mask, xl, numeric); } diff --git a/extensions/libxt_devgroup.txlate b/extensions/libxt_devgroup.txlate index aeb597bd..dea47a99 100644 --- a/extensions/libxt_devgroup.txlate +++ b/extensions/libxt_devgroup.txlate @@ -1,17 +1,17 @@ iptables-translate -A FORWARD -m devgroup --src-group 0x2 -j ACCEPT -nft add rule ip filter FORWARD iifgroup 0x2 counter accept +nft 'add rule ip filter FORWARD iifgroup 0x2 counter accept' iptables-translate -A FORWARD -m devgroup --dst-group 0xc/0xc -j ACCEPT -nft add rule ip filter FORWARD oifgroup and 0xc == 0xc counter accept +nft 'add rule ip filter FORWARD oifgroup and 0xc == 0xc counter accept' iptables-translate -t mangle -A PREROUTING -p tcp --dport 46000 -m devgroup --src-group 23 -j ACCEPT -nft add rule ip mangle PREROUTING tcp dport 46000 iifgroup 0x17 counter accept +nft 'add rule ip mangle PREROUTING tcp dport 46000 iifgroup 0x17 counter accept' iptables-translate -A FORWARD -m devgroup ! --dst-group 0xc/0xc -j ACCEPT -nft add rule ip filter FORWARD oifgroup and 0xc != 0xc counter accept +nft 'add rule ip filter FORWARD oifgroup and 0xc != 0xc counter accept' iptables-translate -A FORWARD -m devgroup ! --src-group 0x2 -j ACCEPT -nft add rule ip filter FORWARD iifgroup != 0x2 counter accept +nft 'add rule ip filter FORWARD iifgroup != 0x2 counter accept' iptables-translate -A FORWARD -m devgroup ! --src-group 0x2 --dst-group 0xc/0xc -j ACCEPT -nft add rule ip filter FORWARD iifgroup != 0x2 oifgroup and 0xc != 0xc counter accept +nft 'add rule ip filter FORWARD iifgroup != 0x2 oifgroup and 0xc != 0xc counter accept' diff --git a/extensions/libxt_dscp.t b/extensions/libxt_dscp.t index 38d7f04e..e0101906 100644 --- a/extensions/libxt_dscp.t +++ b/extensions/libxt_dscp.t @@ -1,5 +1,5 @@ :INPUT,FORWARD,OUTPUT --m dscp --dscp 0;=;OK +-m dscp --dscp 0x00;=;OK -m dscp --dscp 0x3f;=;OK -m dscp --dscp -1;;FAIL -m dscp --dscp 0x40;;FAIL diff --git a/extensions/libxt_dscp.txlate b/extensions/libxt_dscp.txlate index 2cccc3b4..ca2ec724 100644 --- a/extensions/libxt_dscp.txlate +++ b/extensions/libxt_dscp.txlate @@ -1,5 +1,5 @@ iptables-translate -t filter -A INPUT -m dscp --dscp 0x32 -j ACCEPT -nft add rule ip filter INPUT ip dscp 0x32 counter accept +nft 'add rule ip filter INPUT ip dscp 0x32 counter accept' ip6tables-translate -t filter -A INPUT -m dscp ! --dscp 0x32 -j ACCEPT -nft add rule ip6 filter INPUT ip6 dscp != 0x32 counter accept +nft 'add rule ip6 filter INPUT ip6 dscp != 0x32 counter accept' diff --git a/extensions/libxt_ecn.c b/extensions/libxt_ecn.c index ad3c7a03..83a4acfa 100644 --- a/extensions/libxt_ecn.c +++ b/extensions/libxt_ecn.c @@ -156,6 +156,8 @@ static int ecn_xlate(struct xt_xlate *xl, case 3: xt_xlate_add(xl, "ce"); break; + default: + return 0; } } return 1; diff --git a/extensions/libxt_ecn.txlate b/extensions/libxt_ecn.txlate index f012f128..8488f8ce 100644 --- a/extensions/libxt_ecn.txlate +++ b/extensions/libxt_ecn.txlate @@ -1,29 +1,29 @@ iptables-translate -A INPUT -m ecn --ecn-ip-ect 0 -nft add rule ip filter INPUT ip ecn not-ect counter +nft 'add rule ip filter INPUT ip ecn not-ect counter' iptables-translate -A INPUT -m ecn --ecn-ip-ect 1 -nft add rule ip filter INPUT ip ecn ect1 counter +nft 'add rule ip filter INPUT ip ecn ect1 counter' iptables-translate -A INPUT -m ecn --ecn-ip-ect 2 -nft add rule ip filter INPUT ip ecn ect0 counter +nft 'add rule ip filter INPUT ip ecn ect0 counter' iptables-translate -A INPUT -m ecn --ecn-ip-ect 3 -nft add rule ip filter INPUT ip ecn ce counter +nft 'add rule ip filter INPUT ip ecn ce counter' iptables-translate -A INPUT -m ecn ! --ecn-ip-ect 0 -nft add rule ip filter INPUT ip ecn != not-ect counter +nft 'add rule ip filter INPUT ip ecn != not-ect counter' iptables-translate -A INPUT -m ecn ! --ecn-ip-ect 1 -nft add rule ip filter INPUT ip ecn != ect1 counter +nft 'add rule ip filter INPUT ip ecn != ect1 counter' iptables-translate -A INPUT -m ecn ! --ecn-ip-ect 2 -nft add rule ip filter INPUT ip ecn != ect0 counter +nft 'add rule ip filter INPUT ip ecn != ect0 counter' iptables-translate -A INPUT -m ecn ! --ecn-ip-ect 3 -nft add rule ip filter INPUT ip ecn != ce counter +nft 'add rule ip filter INPUT ip ecn != ce counter' iptables-translate -A INPUT -m ecn ! --ecn-tcp-ece -nft add rule ip filter INPUT tcp flags != ecn counter +nft 'add rule ip filter INPUT tcp flags != ecn counter' iptables-translate -A INPUT -m ecn --ecn-tcp-cwr -nft add rule ip filter INPUT tcp flags cwr counter +nft 'add rule ip filter INPUT tcp flags cwr counter' diff --git a/extensions/libxt_esp.txlate b/extensions/libxt_esp.txlate index 5e2f18fa..f6aba52f 100644 --- a/extensions/libxt_esp.txlate +++ b/extensions/libxt_esp.txlate @@ -1,11 +1,11 @@ iptables-translate -A FORWARD -p esp -j ACCEPT -nft add rule ip filter FORWARD ip protocol esp counter accept +nft 'add rule ip filter FORWARD ip protocol esp counter accept' iptables-translate -A INPUT --in-interface wan --protocol esp -j ACCEPT -nft add rule ip filter INPUT iifname "wan" ip protocol esp counter accept +nft 'add rule ip filter INPUT iifname "wan" ip protocol esp counter accept' iptables-translate -A INPUT -p 50 -m esp --espspi 500 -j DROP -nft add rule ip filter INPUT esp spi 500 counter drop +nft 'add rule ip filter INPUT esp spi 500 counter drop' iptables-translate -A INPUT -p 50 -m esp --espspi 500:600 -j DROP -nft add rule ip filter INPUT esp spi 500-600 counter drop +nft 'add rule ip filter INPUT esp spi 500-600 counter drop' diff --git a/extensions/libxt_hashlimit.c b/extensions/libxt_hashlimit.c index 3f3c4301..24e784ab 100644 --- a/extensions/libxt_hashlimit.c +++ b/extensions/libxt_hashlimit.c @@ -356,12 +356,12 @@ static bool parse_bytes(const char *rate, void *val, struct hashlimit_mt_udata * tmp = (uint64_t) r * factor; if (tmp > max) xtables_error(PARAMETER_PROBLEM, - "Rate value too large \"%"PRIu64"\" (max %"PRIu64")\n", - tmp, max); + "Rate value too large \"%"PRIu64"\" (max %"PRIu64")", + tmp, max); tmp = bytes_to_cost(tmp); if (tmp == 0) - xtables_error(PARAMETER_PROBLEM, "Rate too high \"%s\"\n", rate); + xtables_error(PARAMETER_PROBLEM, "Rate too high \"%s\"", rate); ud->mult = XT_HASHLIMIT_BYTE_EXPIRE; @@ -407,7 +407,7 @@ int parse_rate(const char *rate, void *val, struct hashlimit_mt_udata *ud, int r * The rate maps to infinity. (1/day is the minimum they can * specify, so we are ok at that end). */ - xtables_error(PARAMETER_PROBLEM, "Rate too fast \"%s\"\n", rate); + xtables_error(PARAMETER_PROBLEM, "Rate too fast \"%s\"", rate); if(revision == 1) *((uint32_t*)val) = tmp; @@ -1270,7 +1270,7 @@ static void hashlimit_print_subnet_xlate(struct xt_xlate *xl, } } - xt_xlate_add(xl, fmt, acm); + xt_xlate_add_nospc(xl, fmt, acm); if (nblocks > 0) xt_xlate_add(xl, "%c", sep); } diff --git a/extensions/libxt_hashlimit.txlate b/extensions/libxt_hashlimit.txlate index 6c8d07f1..306ee783 100644 --- a/extensions/libxt_hashlimit.txlate +++ b/extensions/libxt_hashlimit.txlate @@ -1,5 +1,5 @@ iptables-translate -A OUTPUT -m tcp -p tcp --dport 443 -m hashlimit --hashlimit-above 20kb/s --hashlimit-burst 1mb --hashlimit-mode dstip --hashlimit-name https --hashlimit-dstmask 24 -m state --state NEW -j DROP -nft add rule ip filter OUTPUT tcp dport 443 meter https { ip daddr and 255.255.255.0 timeout 60s limit rate over 20 kbytes/second burst 1 mbytes} ct state new counter drop +nft 'add rule ip filter OUTPUT tcp dport 443 meter https { ip daddr and 255.255.255.0 timeout 60s limit rate over 20 kbytes/second burst 1 mbytes } ct state new counter drop' iptables-translate -A OUTPUT -m tcp -p tcp --dport 443 -m hashlimit --hashlimit-upto 300 --hashlimit-burst 15 --hashlimit-mode srcip,dstip --hashlimit-name https --hashlimit-htable-expire 300000 -m state --state NEW -j DROP -nft add rule ip filter OUTPUT tcp dport 443 meter https { ip daddr . ip saddr timeout 300s limit rate 300/second burst 15 packets} ct state new counter drop +nft 'add rule ip filter OUTPUT tcp dport 443 meter https { ip daddr . ip saddr timeout 300s limit rate 300/second burst 15 packets } ct state new counter drop' diff --git a/extensions/libxt_helper.c b/extensions/libxt_helper.c index 2afbf996..0f72eec6 100644 --- a/extensions/libxt_helper.c +++ b/extensions/libxt_helper.c @@ -50,12 +50,8 @@ static int helper_xlate(struct xt_xlate *xl, { const struct xt_helper_info *info = (const void *)params->match->data; - if (params->escape_quotes) - xt_xlate_add(xl, "ct helper%s \\\"%s\\\"", - info->invert ? " !=" : "", info->name); - else - xt_xlate_add(xl, "ct helper%s \"%s\"", - info->invert ? " !=" : "", info->name); + xt_xlate_add(xl, "ct helper%s \"%s\"", + info->invert ? " !=" : "", info->name); return 1; } diff --git a/extensions/libxt_helper.txlate b/extensions/libxt_helper.txlate index 8259aba3..2d94f740 100644 --- a/extensions/libxt_helper.txlate +++ b/extensions/libxt_helper.txlate @@ -1,5 +1,5 @@ iptables-translate -A FORWARD -m helper --helper sip -nft add rule ip filter FORWARD ct helper \"sip\" counter +nft 'add rule ip filter FORWARD ct helper "sip" counter' iptables-translate -A FORWARD -m helper ! --helper ftp -nft add rule ip filter FORWARD ct helper != \"ftp\" counter +nft 'add rule ip filter FORWARD ct helper != "ftp" counter' diff --git a/extensions/libxt_icmp.h b/extensions/libxt_icmp.h index 5820206e..7a45b4bd 100644 --- a/extensions/libxt_icmp.h +++ b/extensions/libxt_icmp.h @@ -1,25 +1,256 @@ -struct xt_icmp_names { +static const struct xt_icmp_names { const char *name; uint8_t type; uint8_t code_min, code_max; +} icmp_codes[] = { + { "any", 0xFF, 0, 0xFF }, + { "echo-reply", 0, 0, 0xFF }, + /* Alias */ { "pong", 0, 0, 0xFF }, + + { "destination-unreachable", 3, 0, 0xFF }, + { "network-unreachable", 3, 0, 0 }, + { "host-unreachable", 3, 1, 1 }, + { "protocol-unreachable", 3, 2, 2 }, + { "port-unreachable", 3, 3, 3 }, + { "fragmentation-needed", 3, 4, 4 }, + { "source-route-failed", 3, 5, 5 }, + { "network-unknown", 3, 6, 6 }, + { "host-unknown", 3, 7, 7 }, + { "network-prohibited", 3, 9, 9 }, + { "host-prohibited", 3, 10, 10 }, + { "TOS-network-unreachable", 3, 11, 11 }, + { "TOS-host-unreachable", 3, 12, 12 }, + { "communication-prohibited", 3, 13, 13 }, + { "host-precedence-violation", 3, 14, 14 }, + { "precedence-cutoff", 3, 15, 15 }, + + { "source-quench", 4, 0, 0xFF }, + + { "redirect", 5, 0, 0xFF }, + { "network-redirect", 5, 0, 0 }, + { "host-redirect", 5, 1, 1 }, + { "TOS-network-redirect", 5, 2, 2 }, + { "TOS-host-redirect", 5, 3, 3 }, + + { "echo-request", 8, 0, 0xFF }, + /* Alias */ { "ping", 8, 0, 0xFF }, + + { "router-advertisement", 9, 0, 0xFF }, + + { "router-solicitation", 10, 0, 0xFF }, + + { "time-exceeded", 11, 0, 0xFF }, + /* Alias */ { "ttl-exceeded", 11, 0, 0xFF }, + { "ttl-zero-during-transit", 11, 0, 0 }, + { "ttl-zero-during-reassembly", 11, 1, 1 }, + + { "parameter-problem", 12, 0, 0xFF }, + { "ip-header-bad", 12, 0, 0 }, + { "required-option-missing", 12, 1, 1 }, + + { "timestamp-request", 13, 0, 0xFF }, + + { "timestamp-reply", 14, 0, 0xFF }, + + { "address-mask-request", 17, 0, 0xFF }, + + { "address-mask-reply", 18, 0, 0xFF } +}, icmpv6_codes[] = { + { "destination-unreachable", 1, 0, 0xFF }, + { "no-route", 1, 0, 0 }, + { "communication-prohibited", 1, 1, 1 }, + { "beyond-scope", 1, 2, 2 }, + { "address-unreachable", 1, 3, 3 }, + { "port-unreachable", 1, 4, 4 }, + { "failed-policy", 1, 5, 5 }, + { "reject-route", 1, 6, 6 }, + + { "packet-too-big", 2, 0, 0xFF }, + + { "time-exceeded", 3, 0, 0xFF }, + /* Alias */ { "ttl-exceeded", 3, 0, 0xFF }, + { "ttl-zero-during-transit", 3, 0, 0 }, + { "ttl-zero-during-reassembly", 3, 1, 1 }, + + { "parameter-problem", 4, 0, 0xFF }, + { "bad-header", 4, 0, 0 }, + { "unknown-header-type", 4, 1, 1 }, + { "unknown-option", 4, 2, 2 }, + + { "echo-request", 128, 0, 0xFF }, + /* Alias */ { "ping", 128, 0, 0xFF }, + + { "echo-reply", 129, 0, 0xFF }, + /* Alias */ { "pong", 129, 0, 0xFF }, + + { "mld-listener-query", 130, 0, 0xFF }, + + { "mld-listener-report", 131, 0, 0xFF }, + + { "mld-listener-done", 132, 0, 0xFF }, + /* Alias */ { "mld-listener-reduction", 132, 0, 0xFF }, + + { "router-solicitation", 133, 0, 0xFF }, + + { "router-advertisement", 134, 0, 0xFF }, + + { "neighbour-solicitation", 135, 0, 0xFF }, + /* Alias */ { "neighbor-solicitation", 135, 0, 0xFF }, + + { "neighbour-advertisement", 136, 0, 0xFF }, + /* Alias */ { "neighbor-advertisement", 136, 0, 0xFF }, + + { "redirect", 137, 0, 0xFF }, +}, igmp_types[] = { + { "membership-query", 0x11 }, + { "membership-report-v1", 0x12 }, + { "membership-report-v2", 0x16 }, + { "leave-group", 0x17 }, + { "membership-report-v3", 0x22 }, }; -static void xt_print_icmp_types(const struct xt_icmp_names *icmp_codes, +static inline char *parse_range(const char *str, unsigned int res[]) +{ + char *next; + + if (!xtables_strtoui(str, &next, &res[0], 0, 255)) + return NULL; + + res[1] = res[0]; + if (*next == ':') { + str = next + 1; + if (!xtables_strtoui(str, &next, &res[1], 0, 255)) + return NULL; + } + + return next; +} + +static void +__parse_icmp(const struct xt_icmp_names codes[], size_t n_codes, + const char *codes_name, const char *fmtstring, + uint8_t type[], uint8_t code[]) +{ + unsigned int match = n_codes; + unsigned int i, number[2]; + + for (i = 0; i < n_codes; i++) { + if (strncasecmp(codes[i].name, fmtstring, strlen(fmtstring))) + continue; + if (match != n_codes) + xtables_error(PARAMETER_PROBLEM, + "Ambiguous %s type `%s': `%s' or `%s'?", + codes_name, fmtstring, codes[match].name, + codes[i].name); + match = i; + } + + if (match < n_codes) { + type[0] = type[1] = codes[match].type; + if (code) { + code[0] = codes[match].code_min; + code[1] = codes[match].code_max; + } + } else { + char *next = parse_range(fmtstring, number); + if (!next) + xtables_error(PARAMETER_PROBLEM, "Unknown %s type `%s'", + codes_name, fmtstring); + type[0] = (uint8_t) number[0]; + type[1] = (uint8_t) number[1]; + switch (*next) { + case 0: + if (code) { + code[0] = 0; + code[1] = 255; + } + return; + case '/': + if (!code) + break; + + next = parse_range(next + 1, number); + if (!next) + xtables_error(PARAMETER_PROBLEM, + "Unknown %s code `%s'", + codes_name, fmtstring); + code[0] = (uint8_t) number[0]; + code[1] = (uint8_t) number[1]; + if (!*next) + break; + /* fallthrough */ + default: + xtables_error(PARAMETER_PROBLEM, + "unknown character %c", *next); + } + } +} + +static inline void +__ipt_parse_icmp(const struct xt_icmp_names *codes, size_t n_codes, + const char *codes_name, const char *fmtstr, + uint8_t *type, uint8_t code[]) +{ + uint8_t types[2]; + + __parse_icmp(codes, n_codes, codes_name, fmtstr, types, code); + if (types[1] != types[0]) + xtables_error(PARAMETER_PROBLEM, + "%s type range not supported", codes_name); + *type = types[0]; +} + +static inline void +ipt_parse_icmp(const char *str, uint8_t *type, uint8_t code[]) +{ + __ipt_parse_icmp(icmp_codes, ARRAY_SIZE(icmp_codes), + "ICMP", str, type, code); +} + +static inline void +ipt_parse_icmpv6(const char *str, uint8_t *type, uint8_t code[]) +{ + __ipt_parse_icmp(icmpv6_codes, ARRAY_SIZE(icmpv6_codes), + "ICMPv6", str, type, code); +} + +static inline void +ebt_parse_icmp(const char *str, uint8_t type[], uint8_t code[]) +{ + __parse_icmp(icmp_codes, ARRAY_SIZE(icmp_codes), + "ICMP", str, type, code); +} + +static inline void +ebt_parse_icmpv6(const char *str, uint8_t type[], uint8_t code[]) +{ + __parse_icmp(icmpv6_codes, ARRAY_SIZE(icmpv6_codes), + "ICMPv6", str, type, code); +} + +static inline void +ebt_parse_igmp(const char *str, uint8_t type[]) +{ + __parse_icmp(igmp_types, ARRAY_SIZE(igmp_types), + "IGMP", str, type, NULL); +} + +static void xt_print_icmp_types(const struct xt_icmp_names *_icmp_codes, unsigned int n_codes) { unsigned int i; for (i = 0; i < n_codes; ++i) { - if (i && icmp_codes[i].type == icmp_codes[i-1].type) { - if (icmp_codes[i].code_min == icmp_codes[i-1].code_min - && (icmp_codes[i].code_max - == icmp_codes[i-1].code_max)) - printf(" (%s)", icmp_codes[i].name); + if (i && _icmp_codes[i].type == _icmp_codes[i-1].type) { + if (_icmp_codes[i].code_min == _icmp_codes[i-1].code_min + && (_icmp_codes[i].code_max + == _icmp_codes[i-1].code_max)) + printf(" (%s)", _icmp_codes[i].name); else - printf("\n %s", icmp_codes[i].name); + printf("\n %s", _icmp_codes[i].name); } else - printf("\n%s", icmp_codes[i].name); + printf("\n%s", _icmp_codes[i].name); } printf("\n"); } diff --git a/extensions/libxt_ipcomp.c b/extensions/libxt_ipcomp.c index b5c43128..4171c4a1 100644 --- a/extensions/libxt_ipcomp.c +++ b/extensions/libxt_ipcomp.c @@ -101,6 +101,8 @@ static int comp_xlate(struct xt_xlate *xl, const struct xt_ipcomp *compinfo = (struct xt_ipcomp *)params->match->data; + /* ignore compinfo->hdrres like kernel's xt_ipcomp.c does */ + xt_xlate_add(xl, "comp cpi %s", compinfo->invflags & XT_IPCOMP_INV_SPI ? "!= " : ""); if (compinfo->spis[0] != compinfo->spis[1]) diff --git a/extensions/libxt_ipcomp.c.man b/extensions/libxt_ipcomp.c.man index f3b17d21..824f5b3d 100644 --- a/extensions/libxt_ipcomp.c.man +++ b/extensions/libxt_ipcomp.c.man @@ -2,6 +2,3 @@ This module matches the parameters in IPcomp header of IPsec packets. .TP [\fB!\fP] \fB\-\-ipcompspi\fP \fIspi\fP[\fB:\fP\fIspi\fP] Matches IPcomp header CPI value. -.TP -\fB\-\-compres\fP -Matches if the reserved field is filled with zero. diff --git a/extensions/libxt_ipcomp.txlate b/extensions/libxt_ipcomp.txlate index f9efe53c..877cccbb 100644 --- a/extensions/libxt_ipcomp.txlate +++ b/extensions/libxt_ipcomp.txlate @@ -1,5 +1,5 @@ iptables-translate -t filter -A INPUT -m ipcomp --ipcompspi 0x12 -j ACCEPT -nft add rule ip filter INPUT comp cpi 18 counter accept +nft 'add rule ip filter INPUT comp cpi 18 counter accept' iptables-translate -t filter -A INPUT -m ipcomp ! --ipcompspi 0x12 -j ACCEPT -nft add rule ip filter INPUT comp cpi != 18 counter accept +nft 'add rule ip filter INPUT comp cpi != 18 counter accept' diff --git a/extensions/libxt_iprange.c b/extensions/libxt_iprange.c index 04ce7b36..0df709d5 100644 --- a/extensions/libxt_iprange.c +++ b/extensions/libxt_iprange.c @@ -317,16 +317,14 @@ static int iprange_xlate(struct xt_xlate *xl, const struct xt_xlate_mt_params *params) { const struct ipt_iprange_info *info = (const void *)params->match->data; - char *space = ""; if (info->flags & IPRANGE_SRC) { xt_xlate_add(xl, "ip saddr%s", info->flags & IPRANGE_SRC_INV ? " !=" : ""); print_iprange_xlate(&info->src, xl); - space = " "; } if (info->flags & IPRANGE_DST) { - xt_xlate_add(xl, "%sip daddr%s", space, + xt_xlate_add(xl, "ip daddr%s", info->flags & IPRANGE_DST_INV ? " !=" : ""); print_iprange_xlate(&info->dst, xl); } @@ -339,7 +337,6 @@ static int iprange_mt4_xlate(struct xt_xlate *xl, { const struct xt_iprange_mtinfo *info = (const void *)params->match->data; - char *space = ""; if (info->flags & IPRANGE_SRC) { xt_xlate_add(xl, "ip saddr%s %s", @@ -347,10 +344,9 @@ static int iprange_mt4_xlate(struct xt_xlate *xl, xtables_ipaddr_to_numeric(&info->src_min.in)); xt_xlate_add(xl, "-%s", xtables_ipaddr_to_numeric(&info->src_max.in)); - space = " "; } if (info->flags & IPRANGE_DST) { - xt_xlate_add(xl, "%sip daddr%s %s", space, + xt_xlate_add(xl, "ip daddr%s %s", info->flags & IPRANGE_DST_INV ? " !=" : "", xtables_ipaddr_to_numeric(&info->dst_min.in)); xt_xlate_add(xl, "-%s", @@ -365,7 +361,6 @@ static int iprange_mt6_xlate(struct xt_xlate *xl, { const struct xt_iprange_mtinfo *info = (const void *)params->match->data; - char *space = ""; if (info->flags & IPRANGE_SRC) { xt_xlate_add(xl, "ip6 saddr%s %s", @@ -373,10 +368,9 @@ static int iprange_mt6_xlate(struct xt_xlate *xl, xtables_ip6addr_to_numeric(&info->src_min.in6)); xt_xlate_add(xl, "-%s", xtables_ip6addr_to_numeric(&info->src_max.in6)); - space = " "; } if (info->flags & IPRANGE_DST) { - xt_xlate_add(xl, "%sip6 daddr%s %s", space, + xt_xlate_add(xl, "ip6 daddr%s %s", info->flags & IPRANGE_DST_INV ? " !=" : "", xtables_ip6addr_to_numeric(&info->dst_min.in6)); xt_xlate_add(xl, "-%s", diff --git a/extensions/libxt_iprange.txlate b/extensions/libxt_iprange.txlate index 999f4b72..80369650 100644 --- a/extensions/libxt_iprange.txlate +++ b/extensions/libxt_iprange.txlate @@ -1,14 +1,14 @@ iptables-translate -A INPUT -m iprange --src-range 192.168.25.149-192.168.25.151 -j ACCEPT -nft add rule ip filter INPUT ip saddr 192.168.25.149-192.168.25.151 counter accept +nft 'add rule ip filter INPUT ip saddr 192.168.25.149-192.168.25.151 counter accept' iptables-translate -A INPUT -m iprange --dst-range 192.168.25.149-192.168.25.151 -j ACCEPT -nft add rule ip filter INPUT ip daddr 192.168.25.149-192.168.25.151 counter accept +nft 'add rule ip filter INPUT ip daddr 192.168.25.149-192.168.25.151 counter accept' iptables-translate -A INPUT -m iprange --dst-range 3.3.3.3-6.6.6.6 --src-range 4.4.4.4-7.7.7.7 -j ACCEPT -nft add rule ip filter INPUT ip saddr 4.4.4.4-7.7.7.7 ip daddr 3.3.3.3-6.6.6.6 counter accept +nft 'add rule ip filter INPUT ip saddr 4.4.4.4-7.7.7.7 ip daddr 3.3.3.3-6.6.6.6 counter accept' ip6tables-translate -A INPUT -m iprange ! --dst-range ::2d01-::2d03 -j ACCEPT -nft add rule ip6 filter INPUT ip6 daddr != ::2d01-::2d03 counter accept +nft 'add rule ip6 filter INPUT ip6 daddr != ::2d01-::2d03 counter accept' ip6tables-translate -A INPUT -m iprange ! --dst-range ::2d01-::2d03 --src-range ::2d01-::2d03 -j ACCEPT -nft add rule ip6 filter INPUT ip6 saddr ::2d01-::2d03 ip6 daddr != ::2d01-::2d03 counter accept +nft 'add rule ip6 filter INPUT ip6 saddr ::2d01-::2d03 ip6 daddr != ::2d01-::2d03 counter accept' diff --git a/extensions/libxt_length.t b/extensions/libxt_length.t index 0b6624ee..8b70fc31 100644 --- a/extensions/libxt_length.t +++ b/extensions/libxt_length.t @@ -2,7 +2,7 @@ -m length --length 1;=;OK -m length --length :2;-m length --length 0:2;OK -m length --length 0:3;=;OK --m length --length 4:;=;OK +-m length --length 4:;-m length --length 4:65535;OK -m length --length 0:65535;=;OK -m length ! --length 0:65535;=;OK -m length --length 0:65536;;FAIL diff --git a/extensions/libxt_length.txlate b/extensions/libxt_length.txlate index e777c265..38f835dc 100644 --- a/extensions/libxt_length.txlate +++ b/extensions/libxt_length.txlate @@ -1,11 +1,11 @@ iptables-translate -A INPUT -p icmp -m length --length 86:0xffff -j DROP -nft add rule ip filter INPUT ip protocol icmp meta length 86-65535 counter drop +nft 'add rule ip filter INPUT ip protocol icmp meta length 86-65535 counter drop' iptables-translate -A INPUT -p udp -m length --length :400 -nft add rule ip filter INPUT ip protocol udp meta length 0-400 counter +nft 'add rule ip filter INPUT ip protocol udp meta length 0-400 counter' iptables-translate -A INPUT -p udp -m length --length 40 -nft add rule ip filter INPUT ip protocol udp meta length 40 counter +nft 'add rule ip filter INPUT ip protocol udp meta length 40 counter' iptables-translate -A INPUT -p udp -m length ! --length 40 -nft add rule ip filter INPUT ip protocol udp meta length != 40 counter +nft 'add rule ip filter INPUT ip protocol udp meta length != 40 counter' diff --git a/extensions/libxt_limit.c b/extensions/libxt_limit.c index 1b324657..e6ec67f3 100644 --- a/extensions/libxt_limit.c +++ b/extensions/libxt_limit.c @@ -77,7 +77,7 @@ int parse_rate(const char *rate, uint32_t *val) * The rate maps to infinity. (1/day is the minimum they can * specify, so we are ok at that end). */ - xtables_error(PARAMETER_PROBLEM, "Rate too fast \"%s\"\n", rate); + xtables_error(PARAMETER_PROBLEM, "Rate too fast \"%s\"", rate); return 1; } @@ -93,7 +93,7 @@ static void limit_init(struct xt_entry_match *m) /* FIXME: handle overflow: if (r->avg*r->burst/r->burst != r->avg) xtables_error(PARAMETER_PROBLEM, - "Sorry: burst too large for that avg rate.\n"); + "Sorry: burst too large for that avg rate."); */ static void limit_parse(struct xt_option_call *cb) diff --git a/extensions/libxt_limit.txlate b/extensions/libxt_limit.txlate index df9ed2d5..fa8e1bc0 100644 --- a/extensions/libxt_limit.txlate +++ b/extensions/libxt_limit.txlate @@ -1,8 +1,8 @@ iptables-translate -A INPUT -m limit --limit 3/m --limit-burst 3 -nft add rule ip filter INPUT limit rate 3/minute burst 3 packets counter +nft 'add rule ip filter INPUT limit rate 3/minute burst 3 packets counter' iptables-translate -A INPUT -m limit --limit 10/s --limit-burst 5 -nft add rule ip filter INPUT limit rate 10/second burst 5 packets counter +nft 'add rule ip filter INPUT limit rate 10/second burst 5 packets counter' iptables-translate -A INPUT -m limit --limit 10/s --limit-burst 0 -nft add rule ip filter INPUT limit rate 10/second counter +nft 'add rule ip filter INPUT limit rate 10/second counter' diff --git a/extensions/libxt_mac.txlate b/extensions/libxt_mac.txlate index 08696f3d..16800179 100644 --- a/extensions/libxt_mac.txlate +++ b/extensions/libxt_mac.txlate @@ -1,5 +1,5 @@ iptables-translate -A INPUT -m mac --mac-source 0a:12:3e:4f:b2:c6 -j DROP -nft add rule ip filter INPUT ether saddr 0a:12:3e:4f:b2:c6 counter drop +nft 'add rule ip filter INPUT ether saddr 0a:12:3e:4f:b2:c6 counter drop' iptables-translate -A INPUT -p tcp --dport 80 -m mac --mac-source 0a:12:3e:4f:b2:c6 -j ACCEPT -nft add rule ip filter INPUT tcp dport 80 ether saddr 0a:12:3e:4f:b2:c6 counter accept +nft 'add rule ip filter INPUT tcp dport 80 ether saddr 0a:12:3e:4f:b2:c6 counter accept' diff --git a/extensions/libxt_mark.t b/extensions/libxt_mark.t index 7c005379..12c05865 100644 --- a/extensions/libxt_mark.t +++ b/extensions/libxt_mark.t @@ -1,7 +1,8 @@ :INPUT,FORWARD,OUTPUT -m mark --mark 0xfeedcafe/0xfeedcafe;=;OK --m mark --mark 0;=;OK +-m mark --mark 0x0;=;OK -m mark --mark 4294967295;-m mark --mark 0xffffffff;OK -m mark --mark 4294967296;;FAIL -m mark --mark -1;;FAIL -m mark;;FAIL +-s 1.2.0.0/15 -m mark --mark 0x0/0xff0;=;OK diff --git a/extensions/libxt_mark.txlate b/extensions/libxt_mark.txlate index 6bfb5243..6e097091 100644 --- a/extensions/libxt_mark.txlate +++ b/extensions/libxt_mark.txlate @@ -1,5 +1,5 @@ iptables-translate -I INPUT -p tcp -m mark ! --mark 0xa/0xa -nft insert rule ip filter INPUT ip protocol tcp mark and 0xa != 0xa counter +nft 'insert rule ip filter INPUT ip protocol tcp mark and 0xa != 0xa counter' iptables-translate -I INPUT -p tcp -m mark ! --mark 0x1 -nft insert rule ip filter INPUT ip protocol tcp mark != 0x1 counter +nft 'insert rule ip filter INPUT ip protocol tcp mark != 0x1 counter' diff --git a/extensions/libxt_multiport.c b/extensions/libxt_multiport.c index 6b0c8190..f3136d8a 100644 --- a/extensions/libxt_multiport.c +++ b/extensions/libxt_multiport.c @@ -497,7 +497,7 @@ static int __multiport_xlate(struct xt_xlate *xl, xt_xlate_add(xl, "{ "); for (i = 0; i < multiinfo->count; i++) - xt_xlate_add(xl, "%s%u", i ? "," : "", multiinfo->ports[i]); + xt_xlate_add(xl, "%s%u", i ? ", " : "", multiinfo->ports[i]); if (multiinfo->count > 1) xt_xlate_add(xl, "}"); @@ -560,7 +560,7 @@ static int __multiport_xlate_v1(struct xt_xlate *xl, xt_xlate_add(xl, "{ "); for (i = 0; i < multiinfo->count; i++) { - xt_xlate_add(xl, "%s%u", i ? "," : "", multiinfo->ports[i]); + xt_xlate_add(xl, "%s%u", i ? ", " : "", multiinfo->ports[i]); if (multiinfo->pflags[i]) xt_xlate_add(xl, "-%u", multiinfo->ports[++i]); } diff --git a/extensions/libxt_multiport.txlate b/extensions/libxt_multiport.txlate index bced1b84..aa5f006d 100644 --- a/extensions/libxt_multiport.txlate +++ b/extensions/libxt_multiport.txlate @@ -1,14 +1,14 @@ iptables-translate -t filter -A INPUT -p tcp -m multiport --dports 80,81 -j ACCEPT -nft add rule ip filter INPUT ip protocol tcp tcp dport { 80,81} counter accept +nft 'add rule ip filter INPUT ip protocol tcp tcp dport { 80, 81 } counter accept' iptables-translate -t filter -A INPUT -p tcp -m multiport --dports 80:88 -j ACCEPT -nft add rule ip filter INPUT ip protocol tcp tcp dport 80-88 counter accept +nft 'add rule ip filter INPUT ip protocol tcp tcp dport 80-88 counter accept' iptables-translate -t filter -A INPUT -p tcp -m multiport ! --dports 80:88 -j ACCEPT -nft add rule ip filter INPUT ip protocol tcp tcp dport != 80-88 counter accept +nft 'add rule ip filter INPUT ip protocol tcp tcp dport != 80-88 counter accept' iptables-translate -t filter -A INPUT -p tcp -m multiport --sports 50 -j ACCEPT -nft add rule ip filter INPUT ip protocol tcp tcp sport 50 counter accept +nft 'add rule ip filter INPUT ip protocol tcp tcp sport 50 counter accept' iptables-translate -t filter -I INPUT -p tcp -m multiport --ports 10 -nft insert rule ip filter INPUT ip protocol tcp tcp sport . tcp dport { 0-65535 . 10, 10 . 0-65535 } counter +nft 'insert rule ip filter INPUT ip protocol tcp tcp sport . tcp dport { 0-65535 . 10, 10 . 0-65535 } counter' diff --git a/extensions/libxt_nfacct.man b/extensions/libxt_nfacct.man index b755f977..a818fedd 100644 --- a/extensions/libxt_nfacct.man +++ b/extensions/libxt_nfacct.man @@ -26,5 +26,5 @@ nfacct get http\-traffic .PP You can obtain .B nfacct(8) -from http://www.netfilter.org or, alternatively, from the git.netfilter.org +from https://www.netfilter.org or, alternatively, from the git.netfilter.org repository. diff --git a/extensions/libxt_owner.txlate b/extensions/libxt_owner.txlate index 86fb0585..8fbd68eb 100644 --- a/extensions/libxt_owner.txlate +++ b/extensions/libxt_owner.txlate @@ -1,8 +1,8 @@ iptables-translate -t nat -A OUTPUT -p tcp --dport 80 -m owner --uid-owner root -j ACCEPT -nft add rule ip nat OUTPUT tcp dport 80 skuid 0 counter accept +nft 'add rule ip nat OUTPUT tcp dport 80 skuid 0 counter accept' iptables-translate -t nat -A OUTPUT -p tcp --dport 80 -m owner --gid-owner 0-10 -j ACCEPT -nft add rule ip nat OUTPUT tcp dport 80 skgid 0-10 counter accept +nft 'add rule ip nat OUTPUT tcp dport 80 skgid 0-10 counter accept' iptables-translate -t nat -A OUTPUT -p tcp --dport 80 -m owner ! --uid-owner 1000 -j ACCEPT -nft add rule ip nat OUTPUT tcp dport 80 skuid != 1000 counter accept +nft 'add rule ip nat OUTPUT tcp dport 80 skuid != 1000 counter accept' diff --git a/extensions/libxt_pkttype.c b/extensions/libxt_pkttype.c index bf6f5b96..a76310b0 100644 --- a/extensions/libxt_pkttype.c +++ b/extensions/libxt_pkttype.c @@ -30,8 +30,8 @@ static const struct pkttypes supported_types[] = { {"unicast", PACKET_HOST, 1, "to us"}, {"broadcast", PACKET_BROADCAST, 1, "to all"}, {"multicast", PACKET_MULTICAST, 1, "to group"}, -/* {"otherhost", PACKET_OTHERHOST, 1, "to someone else"}, +/* {"outgoing", PACKET_OUTGOING, 1, "outgoing of any type"}, */ /* aliases */ diff --git a/extensions/libxt_pkttype.txlate b/extensions/libxt_pkttype.txlate index 6506a380..c69f56f9 100644 --- a/extensions/libxt_pkttype.txlate +++ b/extensions/libxt_pkttype.txlate @@ -1,8 +1,8 @@ iptables-translate -A INPUT -m pkttype --pkt-type broadcast -j DROP -nft add rule ip filter INPUT pkttype broadcast counter drop +nft 'add rule ip filter INPUT pkttype broadcast counter drop' iptables-translate -A INPUT -m pkttype ! --pkt-type unicast -j DROP -nft add rule ip filter INPUT pkttype != unicast counter drop +nft 'add rule ip filter INPUT pkttype != unicast counter drop' iptables-translate -A INPUT -m pkttype --pkt-type multicast -j ACCEPT -nft add rule ip filter INPUT pkttype multicast counter accept +nft 'add rule ip filter INPUT pkttype multicast counter accept' diff --git a/extensions/libxt_policy.txlate b/extensions/libxt_policy.txlate index 66788a76..a960b395 100644 --- a/extensions/libxt_policy.txlate +++ b/extensions/libxt_policy.txlate @@ -1,5 +1,5 @@ iptables-translate -A INPUT -m policy --pol ipsec --dir in -nft add rule ip filter INPUT meta secpath exists counter +nft 'add rule ip filter INPUT meta secpath exists counter' iptables-translate -A INPUT -m policy --pol none --dir in -nft add rule ip filter INPUT meta secpath missing counter +nft 'add rule ip filter INPUT meta secpath missing counter' diff --git a/extensions/libxt_quota.txlate b/extensions/libxt_quota.txlate index 91142141..6edd925d 100644 --- a/extensions/libxt_quota.txlate +++ b/extensions/libxt_quota.txlate @@ -1,5 +1,5 @@ iptables-translate -A OUTPUT -m quota --quota 111 -nft add rule ip filter OUTPUT quota 111 bytes counter +nft 'add rule ip filter OUTPUT quota 111 bytes counter' iptables-translate -A OUTPUT -m quota ! --quota 111 -nft add rule ip filter OUTPUT quota over 111 bytes counter +nft 'add rule ip filter OUTPUT quota over 111 bytes counter' diff --git a/extensions/libxt_recent.t b/extensions/libxt_recent.t index 9a83918e..cf23aabc 100644 --- a/extensions/libxt_recent.t +++ b/extensions/libxt_recent.t @@ -1,8 +1,8 @@ :INPUT,FORWARD,OUTPUT --m recent --set;=;OK +-m recent --set;-m recent --set --name DEFAULT --mask 255.255.255.255 --rsource;OK -m recent --rcheck --hitcount 8 --name foo --mask 255.255.255.255 --rsource;=;OK -m recent --rcheck --hitcount 12 --name foo --mask 255.255.255.255 --rsource;=;OK --m recent --update --rttl;=;OK +-m recent --update --rttl;-m recent --update --rttl --name DEFAULT --mask 255.255.255.255 --rsource;OK -m recent --set --rttl;;FAIL -m recent --rcheck --hitcount 999 --name foo --mask 255.255.255.255 --rsource;;FAIL # nonsensical, but all should load successfully: diff --git a/extensions/libxt_rpfilter.txlate b/extensions/libxt_rpfilter.txlate index 8d7733ba..a551c419 100644 --- a/extensions/libxt_rpfilter.txlate +++ b/extensions/libxt_rpfilter.txlate @@ -1,8 +1,8 @@ iptables-translate -t mangle -A PREROUTING -m rpfilter -nft add rule ip mangle PREROUTING fib saddr . iif oif != 0 counter +nft 'add rule ip mangle PREROUTING fib saddr . iif oif != 0 counter' iptables-translate -t mangle -A PREROUTING -m rpfilter --validmark --loose -nft add rule ip mangle PREROUTING fib saddr . mark oif != 0 counter +nft 'add rule ip mangle PREROUTING fib saddr . mark oif != 0 counter' ip6tables-translate -t mangle -A PREROUTING -m rpfilter --validmark --invert -nft add rule ip6 mangle PREROUTING fib saddr . mark . iif oif 0 counter +nft 'add rule ip6 mangle PREROUTING fib saddr . mark . iif oif 0 counter' diff --git a/extensions/libxt_sctp.c b/extensions/libxt_sctp.c index a4c5415f..6e2b2745 100644 --- a/extensions/libxt_sctp.c +++ b/extensions/libxt_sctp.c @@ -50,7 +50,7 @@ static void sctp_help(void) " --dport ...\n" "[!] --chunk-types (all|any|none) (chunktype[:flags])+ match if all, any or none of\n" " chunktypes are present\n" -"chunktypes - DATA INIT INIT_ACK SACK HEARTBEAT HEARTBEAT_ACK ABORT SHUTDOWN SHUTDOWN_ACK ERROR COOKIE_ECHO COOKIE_ACK ECN_ECNE ECN_CWR SHUTDOWN_COMPLETE ASCONF ASCONF_ACK FORWARD_TSN ALL NONE\n"); +"chunktypes - DATA INIT INIT_ACK SACK HEARTBEAT HEARTBEAT_ACK ABORT SHUTDOWN SHUTDOWN_ACK ERROR COOKIE_ECHO COOKIE_ACK ECN_ECNE ECN_CWR SHUTDOWN_COMPLETE I_DATA RE_CONFIG PAD ASCONF ASCONF_ACK FORWARD_TSN I_FORWARD_TSN ALL NONE\n"); } static const struct option sctp_opts[] = { @@ -112,9 +112,13 @@ static const struct sctp_chunk_names sctp_chunk_names[] { .name = "ECN_ECNE", .chunk_type = 12, .valid_flags = "--------", .nftname = "ecne" }, { .name = "ECN_CWR", .chunk_type = 13, .valid_flags = "--------", .nftname = "cwr" }, { .name = "SHUTDOWN_COMPLETE", .chunk_type = 14, .valid_flags = "-------T", .nftname = "shutdown-complete" }, + { .name = "I_DATA", .chunk_type = 64, .valid_flags = "----IUBE", .nftname = "i-data"}, + { .name = "RE_CONFIG", .chunk_type = 130, .valid_flags = "--------", .nftname = "re-config"}, + { .name = "PAD", .chunk_type = 132, .valid_flags = "--------", .nftname = "pad"}, { .name = "ASCONF", .chunk_type = 193, .valid_flags = "--------", .nftname = "asconf" }, { .name = "ASCONF_ACK", .chunk_type = 128, .valid_flags = "--------", .nftname = "asconf-ack" }, { .name = "FORWARD_TSN", .chunk_type = 192, .valid_flags = "--------", .nftname = "forward-tsn" }, + { .name = "I_FORWARD_TSN", .chunk_type = 194, .valid_flags = "--------", .nftname = "i-forward-tsn" }, }; static void @@ -140,10 +144,8 @@ save_chunk_flag_info(struct xt_sctp_flag_info *flag_info, } if (*flag_count == XT_NUM_SCTP_FLAGS) { - xtables_error (PARAMETER_PROBLEM, - "Number of chunk types with flags exceeds currently allowed limit." - "Increasing this limit involves changing IPT_NUM_SCTP_FLAGS and" - "recompiling both the kernel space and user space modules\n"); + xtables_error(PARAMETER_PROBLEM, + "Number of chunk types with flags exceeds currently allowed limit. Increasing this limit involves changing IPT_NUM_SCTP_FLAGS and recompiling both the kernel space and user space modules"); } flag_info[*flag_count].chunktype = chunktype; @@ -215,7 +217,8 @@ parse_sctp_chunk(struct xt_sctp_info *einfo, isupper(chunk_flags[j])); } else { xtables_error(PARAMETER_PROBLEM, - "Invalid flags for chunk type %d\n", i); + "Invalid flags for chunk type %d", + i); } } } @@ -486,24 +489,24 @@ static void sctp_save(const void *ip, const struct xt_entry_match *match) } } -static const char *sctp_xlate_chunk(struct xt_xlate *xl, const char *space, - const struct xt_sctp_info *einfo, - const struct sctp_chunk_names *scn) +static void sctp_xlate_chunk(struct xt_xlate *xl, + const struct xt_sctp_info *einfo, + const struct sctp_chunk_names *scn) { bool inv = einfo->invflags & XT_SCTP_CHUNK_TYPES; const struct xt_sctp_flag_info *flag_info = NULL; int i; if (!scn->nftname) - return space; + return; if (!SCTP_CHUNKMAP_IS_SET(einfo->chunkmap, scn->chunk_type)) { if (einfo->chunk_match_type != SCTP_CHUNK_MATCH_ONLY) - return space; + return; - xt_xlate_add(xl, "%ssctp chunk %s %s", space, + xt_xlate_add(xl, "sctp chunk %s %s", scn->nftname, inv ? "exists" : "missing"); - return " "; + return; } for (i = 0; i < einfo->flag_count; i++) { @@ -514,16 +517,14 @@ static const char *sctp_xlate_chunk(struct xt_xlate *xl, const char *space, } if (!flag_info) { - xt_xlate_add(xl, "%ssctp chunk %s %s", space, + xt_xlate_add(xl, "sctp chunk %s %s", scn->nftname, inv ? "missing" : "exists"); - return " "; + return; } - xt_xlate_add(xl, "%ssctp chunk %s flags & 0x%x %s 0x%x", space, + xt_xlate_add(xl, "sctp chunk %s flags & 0x%x %s 0x%x", scn->nftname, flag_info->flag_mask, inv ? "!=" : "==", flag_info->flag); - - return " "; } static int sctp_xlate(struct xt_xlate *xl, @@ -531,7 +532,6 @@ static int sctp_xlate(struct xt_xlate *xl, { const struct xt_sctp_info *einfo = (const struct xt_sctp_info *)params->match->data; - const char *space = ""; if (!einfo->flags) return 0; @@ -545,19 +545,17 @@ static int sctp_xlate(struct xt_xlate *xl, xt_xlate_add(xl, "sctp sport%s %u", einfo->invflags & XT_SCTP_SRC_PORTS ? " !=" : "", einfo->spts[0]); - space = " "; } if (einfo->flags & XT_SCTP_DEST_PORTS) { if (einfo->dpts[0] != einfo->dpts[1]) - xt_xlate_add(xl, "%ssctp dport%s %u-%u", space, + xt_xlate_add(xl, "sctp dport%s %u-%u", einfo->invflags & XT_SCTP_DEST_PORTS ? " !=" : "", einfo->dpts[0], einfo->dpts[1]); else - xt_xlate_add(xl, "%ssctp dport%s %u", space, + xt_xlate_add(xl, "sctp dport%s %u", einfo->invflags & XT_SCTP_DEST_PORTS ? " !=" : "", einfo->dpts[0]); - space = " "; } if (einfo->flags & XT_SCTP_CHUNK_TYPES) { @@ -567,8 +565,7 @@ static int sctp_xlate(struct xt_xlate *xl, return 0; for (i = 0; i < ARRAY_SIZE(sctp_chunk_names); i++) - space = sctp_xlate_chunk(xl, space, einfo, - &sctp_chunk_names[i]); + sctp_xlate_chunk(xl, einfo, &sctp_chunk_names[i]); } return 1; diff --git a/extensions/libxt_sctp.man b/extensions/libxt_sctp.man index 3e5ffa09..06da04f8 100644 --- a/extensions/libxt_sctp.man +++ b/extensions/libxt_sctp.man @@ -19,12 +19,14 @@ Match if any of the given chunk types is present with given flags. only Match if only the given chunk types are present with given flags and none are missing. -Chunk types: DATA INIT INIT_ACK SACK HEARTBEAT HEARTBEAT_ACK ABORT SHUTDOWN SHUTDOWN_ACK ERROR COOKIE_ECHO COOKIE_ACK ECN_ECNE ECN_CWR SHUTDOWN_COMPLETE ASCONF ASCONF_ACK FORWARD_TSN +Chunk types: DATA INIT INIT_ACK SACK HEARTBEAT HEARTBEAT_ACK ABORT SHUTDOWN SHUTDOWN_ACK ERROR COOKIE_ECHO COOKIE_ACK ECN_ECNE ECN_CWR SHUTDOWN_COMPLETE I_DATA RE_CONFIG PAD ASCONF ASCONF_ACK FORWARD_TSN I_FORWARD_TSN chunk type available flags .br DATA I U B E i u b e .br +I_DATA I U B E i u b e +.br ABORT T t .br SHUTDOWN_COMPLETE T t diff --git a/extensions/libxt_sctp.t b/extensions/libxt_sctp.t index 4016e4fb..4d3b113d 100644 --- a/extensions/libxt_sctp.t +++ b/extensions/libxt_sctp.t @@ -27,3 +27,7 @@ -p sctp -m sctp --chunk-types all ASCONF_ACK;=;OK -p sctp -m sctp --chunk-types all FORWARD_TSN;=;OK -p sctp -m sctp --chunk-types all SHUTDOWN_COMPLETE;=;OK +-p sctp -m sctp --chunk-types all I_DATA;=;OK +-p sctp -m sctp --chunk-types all RE_CONFIG;=;OK +-p sctp -m sctp --chunk-types all PAD;=;OK +-p sctp -m sctp --chunk-types all I_FORWARD_TSN;=;OK diff --git a/extensions/libxt_sctp.txlate b/extensions/libxt_sctp.txlate index bb817525..0aa7371d 100644 --- a/extensions/libxt_sctp.txlate +++ b/extensions/libxt_sctp.txlate @@ -1,44 +1,44 @@ iptables-translate -A INPUT -p sctp --dport 80 -j DROP -nft add rule ip filter INPUT sctp dport 80 counter drop +nft 'add rule ip filter INPUT sctp dport 80 counter drop' iptables-translate -A INPUT -p sctp --sport 50 -j DROP -nft add rule ip filter INPUT sctp sport 50 counter drop +nft 'add rule ip filter INPUT sctp sport 50 counter drop' iptables-translate -A INPUT -p sctp ! --dport 80 -j DROP -nft add rule ip filter INPUT sctp dport != 80 counter drop +nft 'add rule ip filter INPUT sctp dport != 80 counter drop' iptables-translate -A INPUT -p sctp ! --sport 50 -j DROP -nft add rule ip filter INPUT sctp sport != 50 counter drop +nft 'add rule ip filter INPUT sctp sport != 50 counter drop' iptables-translate -A INPUT -p sctp --sport 80:100 -j ACCEPT -nft add rule ip filter INPUT sctp sport 80-100 counter accept +nft 'add rule ip filter INPUT sctp sport 80-100 counter accept' iptables-translate -A INPUT -p sctp --dport 50:56 -j ACCEPT -nft add rule ip filter INPUT sctp dport 50-56 counter accept +nft 'add rule ip filter INPUT sctp dport 50-56 counter accept' iptables-translate -A INPUT -p sctp ! --sport 80:100 -j ACCEPT -nft add rule ip filter INPUT sctp sport != 80-100 counter accept +nft 'add rule ip filter INPUT sctp sport != 80-100 counter accept' iptables-translate -A INPUT -p sctp ! --dport 50:56 -j ACCEPT -nft add rule ip filter INPUT sctp dport != 50-56 counter accept +nft 'add rule ip filter INPUT sctp dport != 50-56 counter accept' iptables-translate -A INPUT -p sctp --dport 80 --sport 50 -j ACCEPT -nft add rule ip filter INPUT sctp sport 50 sctp dport 80 counter accept +nft 'add rule ip filter INPUT sctp sport 50 sctp dport 80 counter accept' iptables-translate -A INPUT -p sctp --dport 80:100 --sport 50 -j ACCEPT -nft add rule ip filter INPUT sctp sport 50 sctp dport 80-100 counter accept +nft 'add rule ip filter INPUT sctp sport 50 sctp dport 80-100 counter accept' iptables-translate -A INPUT -p sctp --dport 80 --sport 50:55 -j ACCEPT -nft add rule ip filter INPUT sctp sport 50-55 sctp dport 80 counter accept +nft 'add rule ip filter INPUT sctp sport 50-55 sctp dport 80 counter accept' iptables-translate -A INPUT -p sctp ! --dport 80:100 --sport 50 -j ACCEPT -nft add rule ip filter INPUT sctp sport 50 sctp dport != 80-100 counter accept +nft 'add rule ip filter INPUT sctp sport 50 sctp dport != 80-100 counter accept' iptables-translate -A INPUT -p sctp --dport 80 ! --sport 50:55 -j ACCEPT -nft add rule ip filter INPUT sctp sport != 50-55 sctp dport 80 counter accept +nft 'add rule ip filter INPUT sctp sport != 50-55 sctp dport 80 counter accept' iptables-translate -A INPUT -p sctp --chunk-types all INIT,DATA:iUbE,SACK,ABORT:T -j ACCEPT -nft add rule ip filter INPUT sctp chunk data flags & 0xf == 0x5 sctp chunk init exists sctp chunk sack exists sctp chunk abort flags & 0x1 == 0x1 counter accept +nft 'add rule ip filter INPUT sctp chunk data flags & 0xf == 0x5 sctp chunk init exists sctp chunk sack exists sctp chunk abort flags & 0x1 == 0x1 counter accept' iptables-translate -A INPUT -p sctp --chunk-types only SHUTDOWN_COMPLETE -j ACCEPT -nft add rule ip filter INPUT sctp chunk data missing sctp chunk init missing sctp chunk init-ack missing sctp chunk sack missing sctp chunk heartbeat missing sctp chunk heartbeat-ack missing sctp chunk abort missing sctp chunk shutdown missing sctp chunk shutdown-ack missing sctp chunk error missing sctp chunk cookie-echo missing sctp chunk cookie-ack missing sctp chunk ecne missing sctp chunk cwr missing sctp chunk shutdown-complete exists sctp chunk asconf missing sctp chunk asconf-ack missing sctp chunk forward-tsn missing counter accept +nft 'add rule ip filter INPUT sctp chunk data missing sctp chunk init missing sctp chunk init-ack missing sctp chunk sack missing sctp chunk heartbeat missing sctp chunk heartbeat-ack missing sctp chunk abort missing sctp chunk shutdown missing sctp chunk shutdown-ack missing sctp chunk error missing sctp chunk cookie-echo missing sctp chunk cookie-ack missing sctp chunk ecne missing sctp chunk cwr missing sctp chunk shutdown-complete exists sctp chunk i-data missing sctp chunk re-config missing sctp chunk pad missing sctp chunk asconf missing sctp chunk asconf-ack missing sctp chunk forward-tsn missing sctp chunk i-forward-tsn missing counter accept' diff --git a/extensions/libxt_set.c b/extensions/libxt_set.c index 16921023..471bde8a 100644 --- a/extensions/libxt_set.c +++ b/extensions/libxt_set.c @@ -22,6 +22,12 @@ #include <linux/netfilter/xt_set.h> #include "libxt_set.h" +#ifdef DEBUG +#define DEBUGP(x, args...) fprintf(stderr, x, ## args) +#else +#define DEBUGP(x, args...) +#endif + /* Revision 0 */ static void @@ -328,8 +334,7 @@ parse_counter(const char *opt) if (!xtables_strtoul(opt, NULL, &value, 0, UINT64_MAX)) xtables_error(PARAMETER_PROBLEM, - "Cannot parse %s as a counter value\n", - opt); + "Cannot parse %s as a counter value", opt); return (uint64_t)value; } @@ -348,60 +353,54 @@ set_parse_v3(int c, char **argv, int invert, unsigned int *flags, case '0': if (info->bytes.op != IPSET_COUNTER_NONE) xtables_error(PARAMETER_PROBLEM, - "only one of the --bytes-[eq|lt|gt]" - " is allowed\n"); + "only one of the --bytes-[eq|lt|gt] is allowed"); if (invert) xtables_error(PARAMETER_PROBLEM, - "--bytes-gt option cannot be inverted\n"); + "--bytes-gt option cannot be inverted"); info->bytes.op = IPSET_COUNTER_GT; info->bytes.value = parse_counter(optarg); break; case '9': if (info->bytes.op != IPSET_COUNTER_NONE) xtables_error(PARAMETER_PROBLEM, - "only one of the --bytes-[eq|lt|gt]" - " is allowed\n"); + "only one of the --bytes-[eq|lt|gt] is allowed"); if (invert) xtables_error(PARAMETER_PROBLEM, - "--bytes-lt option cannot be inverted\n"); + "--bytes-lt option cannot be inverted"); info->bytes.op = IPSET_COUNTER_LT; info->bytes.value = parse_counter(optarg); break; case '8': if (info->bytes.op != IPSET_COUNTER_NONE) xtables_error(PARAMETER_PROBLEM, - "only one of the --bytes-[eq|lt|gt]" - " is allowed\n"); + "only one of the --bytes-[eq|lt|gt] is allowed"); info->bytes.op = invert ? IPSET_COUNTER_NE : IPSET_COUNTER_EQ; info->bytes.value = parse_counter(optarg); break; case '7': if (info->packets.op != IPSET_COUNTER_NONE) xtables_error(PARAMETER_PROBLEM, - "only one of the --packets-[eq|lt|gt]" - " is allowed\n"); + "only one of the --packets-[eq|lt|gt] is allowed"); if (invert) xtables_error(PARAMETER_PROBLEM, - "--packets-gt option cannot be inverted\n"); + "--packets-gt option cannot be inverted"); info->packets.op = IPSET_COUNTER_GT; info->packets.value = parse_counter(optarg); break; case '6': if (info->packets.op != IPSET_COUNTER_NONE) xtables_error(PARAMETER_PROBLEM, - "only one of the --packets-[eq|lt|gt]" - " is allowed\n"); + "only one of the --packets-[eq|lt|gt] is allowed"); if (invert) xtables_error(PARAMETER_PROBLEM, - "--packets-lt option cannot be inverted\n"); + "--packets-lt option cannot be inverted"); info->packets.op = IPSET_COUNTER_LT; info->packets.value = parse_counter(optarg); break; case '5': if (info->packets.op != IPSET_COUNTER_NONE) xtables_error(PARAMETER_PROBLEM, - "only one of the --packets-[eq|lt|gt]" - " is allowed\n"); + "only one of the --packets-[eq|lt|gt] is allowed"); info->packets.op = invert ? IPSET_COUNTER_NE : IPSET_COUNTER_EQ; info->packets.value = parse_counter(optarg); break; @@ -412,7 +411,7 @@ set_parse_v3(int c, char **argv, int invert, unsigned int *flags, case '3': if (invert) xtables_error(PARAMETER_PROBLEM, - "--return-nomatch flag cannot be inverted\n"); + "--return-nomatch flag cannot be inverted"); info->flags |= IPSET_FLAG_RETURN_NOMATCH; break; case '2': @@ -517,60 +516,54 @@ set_parse_v4(int c, char **argv, int invert, unsigned int *flags, case '0': if (info->bytes.op != IPSET_COUNTER_NONE) xtables_error(PARAMETER_PROBLEM, - "only one of the --bytes-[eq|lt|gt]" - " is allowed\n"); + "only one of the --bytes-[eq|lt|gt] is allowed"); if (invert) xtables_error(PARAMETER_PROBLEM, - "--bytes-gt option cannot be inverted\n"); + "--bytes-gt option cannot be inverted"); info->bytes.op = IPSET_COUNTER_GT; info->bytes.value = parse_counter(optarg); break; case '9': if (info->bytes.op != IPSET_COUNTER_NONE) xtables_error(PARAMETER_PROBLEM, - "only one of the --bytes-[eq|lt|gt]" - " is allowed\n"); + "only one of the --bytes-[eq|lt|gt] is allowed"); if (invert) xtables_error(PARAMETER_PROBLEM, - "--bytes-lt option cannot be inverted\n"); + "--bytes-lt option cannot be inverted"); info->bytes.op = IPSET_COUNTER_LT; info->bytes.value = parse_counter(optarg); break; case '8': if (info->bytes.op != IPSET_COUNTER_NONE) xtables_error(PARAMETER_PROBLEM, - "only one of the --bytes-[eq|lt|gt]" - " is allowed\n"); + "only one of the --bytes-[eq|lt|gt] is allowed"); info->bytes.op = invert ? IPSET_COUNTER_NE : IPSET_COUNTER_EQ; info->bytes.value = parse_counter(optarg); break; case '7': if (info->packets.op != IPSET_COUNTER_NONE) xtables_error(PARAMETER_PROBLEM, - "only one of the --packets-[eq|lt|gt]" - " is allowed\n"); + "only one of the --packets-[eq|lt|gt] is allowed"); if (invert) xtables_error(PARAMETER_PROBLEM, - "--packets-gt option cannot be inverted\n"); + "--packets-gt option cannot be inverted"); info->packets.op = IPSET_COUNTER_GT; info->packets.value = parse_counter(optarg); break; case '6': if (info->packets.op != IPSET_COUNTER_NONE) xtables_error(PARAMETER_PROBLEM, - "only one of the --packets-[eq|lt|gt]" - " is allowed\n"); + "only one of the --packets-[eq|lt|gt] is allowed"); if (invert) xtables_error(PARAMETER_PROBLEM, - "--packets-lt option cannot be inverted\n"); + "--packets-lt option cannot be inverted"); info->packets.op = IPSET_COUNTER_LT; info->packets.value = parse_counter(optarg); break; case '5': if (info->packets.op != IPSET_COUNTER_NONE) xtables_error(PARAMETER_PROBLEM, - "only one of the --packets-[eq|lt|gt]" - " is allowed\n"); + "only one of the --packets-[eq|lt|gt] is allowed"); info->packets.op = invert ? IPSET_COUNTER_NE : IPSET_COUNTER_EQ; info->packets.value = parse_counter(optarg); break; @@ -581,7 +574,7 @@ set_parse_v4(int c, char **argv, int invert, unsigned int *flags, case '3': if (invert) xtables_error(PARAMETER_PROBLEM, - "--return-nomatch flag cannot be inverted\n"); + "--return-nomatch flag cannot be inverted"); info->flags |= IPSET_FLAG_RETURN_NOMATCH; break; case '2': diff --git a/extensions/libxt_set.h b/extensions/libxt_set.h index ad895a75..685bfab9 100644 --- a/extensions/libxt_set.h +++ b/extensions/libxt_set.h @@ -6,12 +6,11 @@ #include <sys/types.h> #include <sys/socket.h> #include <errno.h> -#include "../iptables/xshared.h" static int get_version(unsigned *version) { - int res, sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); + int res, sockfd = socket(AF_INET, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW); struct ip_set_req_version req_version; socklen_t size = sizeof(req_version); @@ -19,12 +18,6 @@ get_version(unsigned *version) xtables_error(OTHER_PROBLEM, "Can't open socket to ipset.\n"); - if (fcntl(sockfd, F_SETFD, FD_CLOEXEC) == -1) { - xtables_error(OTHER_PROBLEM, - "Could not set close on exec: %s\n", - strerror(errno)); - } - req_version.op = IP_SET_OP_VERSION; res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req_version, &size); if (res != 0) diff --git a/extensions/libxt_standard.t b/extensions/libxt_standard.t index 56d6da2e..7c83cfa3 100644 --- a/extensions/libxt_standard.t +++ b/extensions/libxt_standard.t @@ -21,3 +21,8 @@ -s 10.11.12.13/255.128.0.0;-s 10.0.0.0/9;OK -s 10.11.12.13/255.0.255.0;-s 10.0.12.0/255.0.255.0;OK -s 10.11.12.13/255.0.12.0;-s 10.0.12.0/255.0.12.0;OK +:FORWARD +--protocol=tcp --source=1.2.3.4 --destination=5.6.7.8/32 --in-interface=eth0 --out-interface=eth1 --jump=ACCEPT;-s 1.2.3.4/32 -d 5.6.7.8/32 -i eth0 -o eth1 -p tcp -j ACCEPT;OK +-ptcp -s1.2.3.4 -d5.6.7.8/32 -ieth0 -oeth1 -jACCEPT;-s 1.2.3.4/32 -d 5.6.7.8/32 -i eth0 -o eth1 -p tcp -j ACCEPT;OK +-i + -d 1.2.3.4;-d 1.2.3.4/32;OK +-i + -p tcp;-p tcp;OK diff --git a/extensions/libxt_statistic.c b/extensions/libxt_statistic.c index 4f3341a3..37915adc 100644 --- a/extensions/libxt_statistic.c +++ b/extensions/libxt_statistic.c @@ -141,13 +141,19 @@ static int statistic_xlate(struct xt_xlate *xl, switch (info->mode) { case XT_STATISTIC_MODE_RANDOM: - return 0; + xt_xlate_add(xl, "meta random & %u %s %u", + INT_MAX, + info->flags & XT_STATISTIC_INVERT ? ">=" : "<", + info->u.random.probability); + break; case XT_STATISTIC_MODE_NTH: xt_xlate_add(xl, "numgen inc mod %u %s%u", info->u.nth.every + 1, info->flags & XT_STATISTIC_INVERT ? "!= " : "", info->u.nth.packet); break; + default: + return 0; } return 1; diff --git a/extensions/libxt_statistic.txlate b/extensions/libxt_statistic.txlate index 4c3dea43..627120c5 100644 --- a/extensions/libxt_statistic.txlate +++ b/extensions/libxt_statistic.txlate @@ -1,8 +1,8 @@ iptables-translate -A OUTPUT -m statistic --mode nth --every 10 --packet 1 -nft add rule ip filter OUTPUT numgen inc mod 10 1 counter +nft 'add rule ip filter OUTPUT numgen inc mod 10 1 counter' iptables-translate -A OUTPUT -m statistic --mode nth ! --every 10 --packet 5 -nft add rule ip filter OUTPUT numgen inc mod 10 != 5 counter +nft 'add rule ip filter OUTPUT numgen inc mod 10 != 5 counter' iptables-translate -A OUTPUT -m statistic --mode random --probability 0.1 -nft # -A OUTPUT -m statistic --mode random --probability 0.1 +nft 'add rule ip filter OUTPUT meta random & 2147483647 < 214748365 counter' diff --git a/extensions/libxt_string.c b/extensions/libxt_string.c index 739a8e7f..5d72a5cd 100644 --- a/extensions/libxt_string.c +++ b/extensions/libxt_string.c @@ -78,14 +78,13 @@ static void string_init(struct xt_entry_match *m) static void parse_string(const char *s, struct xt_string_info *info) -{ +{ /* xt_string does not need \0 at the end of the pattern */ - if (strlen(s) <= XT_STRING_MAX_PATTERN_SIZE) { - memcpy(info->pattern, s, XT_STRING_MAX_PATTERN_SIZE); - info->patlen = strnlen(s, XT_STRING_MAX_PATTERN_SIZE); - return; - } - xtables_error(PARAMETER_PROBLEM, "STRING too long \"%s\"", s); + if (strlen(s) > sizeof(info->pattern)) + xtables_error(PARAMETER_PROBLEM, "STRING too long \"%s\"", s); + + info->patlen = strnlen(s, sizeof(info->pattern)); + memcpy(info->pattern, s, info->patlen); } static void @@ -269,7 +268,7 @@ string_print(const void *ip, const struct xt_entry_match *match, int numeric) printf(" ALGO name %s", info->algo); if (info->from_offset != 0) printf(" FROM %u", info->from_offset); - if (info->to_offset != 0) + if (info->to_offset != UINT16_MAX) printf(" TO %u", info->to_offset); if (revision > 0 && info->u.v1.flags & XT_STRING_FLAG_IGNORECASE) printf(" ICASE"); @@ -293,7 +292,7 @@ static void string_save(const void *ip, const struct xt_entry_match *match) printf(" --algo %s", info->algo); if (info->from_offset != 0) printf(" --from %u", info->from_offset); - if (info->to_offset != 0) + if (info->to_offset != UINT16_MAX) printf(" --to %u", info->to_offset); if (revision > 0 && info->u.v1.flags & XT_STRING_FLAG_IGNORECASE) printf(" --icase"); diff --git a/extensions/libxt_string.man b/extensions/libxt_string.man index 5f1a993c..efdda492 100644 --- a/extensions/libxt_string.man +++ b/extensions/libxt_string.man @@ -7,9 +7,13 @@ Select the pattern matching strategy. (bm = Boyer-Moore, kmp = Knuth-Pratt-Morri Set the offset from which it starts looking for any matching. If not passed, default is 0. .TP \fB\-\-to\fP \fIoffset\fP -Set the offset up to which should be scanned. That is, byte \fIoffset\fP-1 -(counting from 0) is the last one that is scanned. +Set the offset up to which should be scanned. If the pattern does not start +within this offset, it is not considered a match. If not passed, default is the packet size. +A second function of this parameter is instructing the kernel how much data +from the packet should be provided. With non-linear skbuffs (e.g. due to +fragmentation), a pattern extending past this offset may not be found. Also see +the related note below about Boyer-Moore algorithm in these cases. .TP [\fB!\fP] \fB\-\-string\fP \fIpattern\fP Matches the given pattern. @@ -29,3 +33,18 @@ iptables \-A INPUT \-p tcp \-\-dport 80 \-m string \-\-algo bm \-\-string 'GET / # The hex string pattern can be used for non-printable characters, like |0D 0A| or |0D0A|. .br iptables \-p udp \-\-dport 53 \-m string \-\-algo bm \-\-from 40 \-\-to 57 \-\-hex\-string '|03|www|09|netfilter|03|org|00|' +.P +Note: Since Boyer-Moore (BM) performs searches for matches from right to left and +the kernel may store a packet in multiple discontiguous blocks, it's possible +that a match could be spread over multiple blocks, in which case this algorithm +won't find it. +.P +If you wish to ensure that such thing won't ever happen, use the +Knuth-Pratt-Morris (KMP) algorithm instead. In conclusion, choose the proper +string search algorithm depending on your use-case. +.P +For example, if you're using the module for filtering, NIDS or any similar +security-focused purpose, then choose KMP. On the other hand, if you really care +about performance \(em for example, you're classifying packets to apply Quality +of Service (QoS) policies \(em and you don't mind about missing possible matches +spread over multiple fragments, then choose BM. diff --git a/extensions/libxt_string.t b/extensions/libxt_string.t index d68f099d..2f4b30cb 100644 --- a/extensions/libxt_string.t +++ b/extensions/libxt_string.t @@ -1,18 +1,11 @@ :INPUT,FORWARD,OUTPUT -# ERROR: cannot find: iptables -I INPUT -m string --algo bm --string "test" -# -m string --algo bm --string "test";=;OK -# ERROR: cannot find: iptables -I INPUT -m string --algo kmp --string "test") -# -m string --algo kmp --string "test";=;OK -# ERROR: cannot find: iptables -I INPUT -m string --algo kmp ! --string "test" -# -m string --algo kmp ! --string "test";=;OK -# cannot find: iptables -I INPUT -m string --algo bm --string "xxxxxxxxxxx" ....] -# -m string --algo bm --string "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";=;OK -# ERROR: cannot load: iptables -A INPUT -m string --algo bm --string "xxxx" -# -m string --algo bm --string "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";=;OK -# ERROR: cannot load: iptables -A INPUT -m string --algo bm --hexstring "|0a0a0a0a|" -# -m string --algo bm --hexstring "|0a0a0a0a|";=;OK -# ERROR: cannot find: iptables -I INPUT -m string --algo bm --from 0 --to 65535 --string "test" -# -m string --algo bm --from 0 --to 65535 --string "test";=;OK +-m string --algo bm --string "test";-m string --string "test" --algo bm;OK +-m string --string "test" --algo kmp;=;OK +-m string ! --string "test" --algo kmp;=;OK +-m string --string "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" --algo bm;=;OK +-m string --string "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" --algo bm;;FAIL +-m string --hex-string "|0a0a0a0a|" --algo bm;=;OK +-m string --algo bm --from 0 --to 65535 --string "test";-m string --string "test" --algo bm;OK -m string --algo wrong;;FAIL -m string --algo bm;;FAIL -m string;;FAIL diff --git a/extensions/libxt_tcp.c b/extensions/libxt_tcp.c index 0b115cdd..f8257282 100644 --- a/extensions/libxt_tcp.c +++ b/extensions/libxt_tcp.c @@ -380,10 +380,9 @@ static void print_tcp_xlate(struct xt_xlate *xl, uint8_t flags) for (i = 0; (flags & tcp_flag_names_xlate[i].flag) == 0; i++); - if (have_flag) - xt_xlate_add(xl, ","); - - xt_xlate_add(xl, "%s", tcp_flag_names_xlate[i].name); + xt_xlate_add(xl, "%s%s", + have_flag ? "," : "", + tcp_flag_names_xlate[i].name); have_flag = 1; flags &= ~tcp_flag_names_xlate[i].flag; @@ -398,7 +397,6 @@ static int tcp_xlate(struct xt_xlate *xl, { const struct xt_tcp *tcpinfo = (const struct xt_tcp *)params->match->data; - char *space= ""; if (tcpinfo->spts[0] != 0 || tcpinfo->spts[1] != 0xffff) { if (tcpinfo->spts[0] != tcpinfo->spts[1]) { @@ -412,30 +410,29 @@ static int tcp_xlate(struct xt_xlate *xl, "!= " : "", tcpinfo->spts[0]); } - space = " "; } if (tcpinfo->dpts[0] != 0 || tcpinfo->dpts[1] != 0xffff) { if (tcpinfo->dpts[0] != tcpinfo->dpts[1]) { - xt_xlate_add(xl, "%stcp dport %s%u-%u", space, + xt_xlate_add(xl, "tcp dport %s%u-%u", tcpinfo->invflags & XT_TCP_INV_DSTPT ? "!= " : "", tcpinfo->dpts[0], tcpinfo->dpts[1]); } else { - xt_xlate_add(xl, "%stcp dport %s%u", space, + xt_xlate_add(xl, "tcp dport %s%u", tcpinfo->invflags & XT_TCP_INV_DSTPT ? "!= " : "", tcpinfo->dpts[0]); } - space = " "; } - /* XXX not yet implemented */ - if (tcpinfo->option || (tcpinfo->invflags & XT_TCP_INV_OPTION)) - return 0; + if (tcpinfo->option) + xt_xlate_add(xl, "tcp option %u %s", tcpinfo->option, + tcpinfo->invflags & XT_TCP_INV_OPTION ? + "missing" : "exists"); if (tcpinfo->flg_mask || (tcpinfo->invflags & XT_TCP_INV_FLAGS)) { - xt_xlate_add(xl, "%stcp flags %s", space, + xt_xlate_add(xl, "tcp flags %s", tcpinfo->invflags & XT_TCP_INV_FLAGS ? "!= ": ""); print_tcp_xlate(xl, tcpinfo->flg_cmp); xt_xlate_add(xl, " / "); diff --git a/extensions/libxt_tcp.t b/extensions/libxt_tcp.t index b0e8006e..7a3bbd08 100644 --- a/extensions/libxt_tcp.t +++ b/extensions/libxt_tcp.t @@ -22,5 +22,8 @@ -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG SYN;=;OK -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,PSH,ACK,URG SYN;=;OK -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG RST;=;OK +-m tcp --dport 1;;FAIL +-m tcp --dport 1 -p tcp;-p tcp -m tcp --dport 1;OK +-m tcp --dport 1 -p 6;-p tcp -m tcp --dport 1;OK # should we accept this below? -p tcp -m tcp;=;OK diff --git a/extensions/libxt_tcp.txlate b/extensions/libxt_tcp.txlate index 921d4af0..9802ddfe 100644 --- a/extensions/libxt_tcp.txlate +++ b/extensions/libxt_tcp.txlate @@ -1,26 +1,32 @@ iptables-translate -A INPUT -p tcp -i eth0 --sport 53 -j ACCEPT -nft add rule ip filter INPUT iifname "eth0" tcp sport 53 counter accept +nft 'add rule ip filter INPUT iifname "eth0" tcp sport 53 counter accept' iptables-translate -A OUTPUT -p tcp -o eth0 --dport 53:66 -j DROP -nft add rule ip filter OUTPUT oifname "eth0" tcp dport 53-66 counter drop +nft 'add rule ip filter OUTPUT oifname "eth0" tcp dport 53-66 counter drop' iptables-translate -I OUTPUT -p tcp -d 8.8.8.8 -j ACCEPT -nft insert rule ip filter OUTPUT ip protocol tcp ip daddr 8.8.8.8 counter accept +nft 'insert rule ip filter OUTPUT ip protocol tcp ip daddr 8.8.8.8 counter accept' iptables-translate -I OUTPUT -p tcp --dport 1020:1023 --sport 53 -j ACCEPT -nft insert rule ip filter OUTPUT tcp sport 53 tcp dport 1020-1023 counter accept +nft 'insert rule ip filter OUTPUT tcp sport 53 tcp dport 1020-1023 counter accept' iptables -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j DROP -nft add rule ip filter INPUT tcp flags fin / fin,ack counter drop +nft 'add rule ip filter INPUT tcp flags fin / fin,ack counter drop' iptables-translate -A INPUT -p tcp --syn -j ACCEPT -nft add rule ip filter INPUT tcp flags syn / fin,syn,rst,ack counter accept +nft 'add rule ip filter INPUT tcp flags syn / fin,syn,rst,ack counter accept' iptables-translate -A INPUT -p tcp --syn --dport 80 -j ACCEPT -nft add rule ip filter INPUT tcp dport 80 tcp flags syn / fin,syn,rst,ack counter accept +nft 'add rule ip filter INPUT tcp dport 80 tcp flags syn / fin,syn,rst,ack counter accept' iptables-translate -A INPUT -f -p tcp -nft add rule ip filter INPUT ip frag-off & 0x1fff != 0 ip protocol tcp counter +nft 'add rule ip filter INPUT ip frag-off & 0x1fff != 0 ip protocol tcp counter' iptables-translate -A INPUT ! -f -p tcp --dport 22 -nft add rule ip filter INPUT ip frag-off & 0x1fff 0 tcp dport 22 counter +nft 'add rule ip filter INPUT ip frag-off & 0x1fff 0 tcp dport 22 counter' + +iptables-translate -A INPUT -p tcp --tcp-option 23 +nft 'add rule ip filter INPUT tcp option 23 exists counter' + +iptables-translate -A INPUT -p tcp ! --tcp-option 23 +nft 'add rule ip filter INPUT tcp option 23 missing counter' diff --git a/extensions/libxt_tcpmss.txlate b/extensions/libxt_tcpmss.txlate index d3f1b27d..82475e67 100644 --- a/extensions/libxt_tcpmss.txlate +++ b/extensions/libxt_tcpmss.txlate @@ -1,11 +1,11 @@ iptables-translate -A INPUT -m tcpmss --mss 42 -nft add rule ip filter INPUT tcp option maxseg size 42 counter +nft 'add rule ip filter INPUT tcp option maxseg size 42 counter' iptables-translate -A INPUT -m tcpmss ! --mss 42 -nft add rule ip filter INPUT tcp option maxseg size != 42 counter +nft 'add rule ip filter INPUT tcp option maxseg size != 42 counter' iptables-translate -A INPUT -m tcpmss --mss 42:1024 -nft add rule ip filter INPUT tcp option maxseg size 42-1024 counter +nft 'add rule ip filter INPUT tcp option maxseg size 42-1024 counter' iptables-translate -A INPUT -m tcpmss ! --mss 1461:65535 -nft add rule ip filter INPUT tcp option maxseg size != 1461-65535 counter +nft 'add rule ip filter INPUT tcp option maxseg size != 1461-65535 counter' diff --git a/extensions/libxt_time.c b/extensions/libxt_time.c index d27d84ca..580861d3 100644 --- a/extensions/libxt_time.c +++ b/extensions/libxt_time.c @@ -466,9 +466,10 @@ static int time_xlate(struct xt_xlate *xl, const struct xt_time_info *info = (const struct xt_time_info *)params->match->data; unsigned int h, m, s, - i, sep, mask, count; + i, mask, count; time_t tt_start, tt_stop; struct tm *t_start, *t_stop; + const char *sep = ""; if (info->date_start != 0 || info->date_stop != INT_MAX) { @@ -498,7 +499,6 @@ static int time_xlate(struct xt_xlate *xl, if (info->monthdays_match != XT_TIME_ALL_MONTHDAYS) return 0; if (info->weekdays_match != XT_TIME_ALL_WEEKDAYS) { - sep = 0; mask = info->weekdays_match; count = time_count_weekdays(mask); @@ -507,12 +507,8 @@ static int time_xlate(struct xt_xlate *xl, xt_xlate_add(xl, "{"); for (i = 1; i <= 7; ++i) if (mask & (1 << i)) { - if (sep) - xt_xlate_add(xl, ",%u", i%7); - else { - xt_xlate_add(xl, "%u", i%7); - ++sep; - } + xt_xlate_add(xl, "%s%u", sep, i%7); + sep = ", "; } if (count > 1) xt_xlate_add(xl, "}"); diff --git a/extensions/libxt_time.txlate b/extensions/libxt_time.txlate index ff4a7b88..ed64b957 100644 --- a/extensions/libxt_time.txlate +++ b/extensions/libxt_time.txlate @@ -1,26 +1,26 @@ iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --weekdays Sa,Su -j REJECT -nft add rule ip filter INPUT icmp type echo-request meta day {6,0} counter reject +nft 'add rule ip filter INPUT icmp type echo-request meta day { 6, 0 } counter reject' iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --timestart 12:00 -j REJECT -nft add rule ip filter INPUT icmp type echo-request meta hour "12:00:00"-"23:59:59" counter reject +nft 'add rule ip filter INPUT icmp type echo-request meta hour "12:00:00"-"23:59:59" counter reject' iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --timestop 12:00 -j REJECT -nft add rule ip filter INPUT icmp type echo-request meta hour "00:00:00"-"12:00:00" counter reject +nft 'add rule ip filter INPUT icmp type echo-request meta hour "00:00:00"-"12:00:00" counter reject' iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --datestart 2021 -j REJECT -nft add rule ip filter INPUT icmp type echo-request meta time "2021-01-01 00:00:00"-"2038-01-19 03:14:07" counter reject +nft 'add rule ip filter INPUT icmp type echo-request meta time "2021-01-01 00:00:00"-"2038-01-19 03:14:07" counter reject' iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --datestop 2021 -j REJECT -nft add rule ip filter INPUT icmp type echo-request meta time "1970-01-01 00:00:00"-"2021-01-01 00:00:00" counter reject +nft 'add rule ip filter INPUT icmp type echo-request meta time "1970-01-01 00:00:00"-"2021-01-01 00:00:00" counter reject' iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --datestop 2021-01-29T00:00:00 -j REJECT -nft add rule ip filter INPUT icmp type echo-request meta time "1970-01-01 00:00:00"-"2021-01-29 00:00:00" counter reject +nft 'add rule ip filter INPUT icmp type echo-request meta time "1970-01-01 00:00:00"-"2021-01-29 00:00:00" counter reject' iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --datestart 2020-01-29T00:00:00 --timestart 12:00 -j REJECT -nft add rule ip filter INPUT icmp type echo-request meta time "2020-01-29 00:00:00"-"2038-01-19 03:14:07" meta hour "12:00:00"-"23:59:59" counter reject +nft 'add rule ip filter INPUT icmp type echo-request meta time "2020-01-29 00:00:00"-"2038-01-19 03:14:07" meta hour "12:00:00"-"23:59:59" counter reject' iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --datestart 2020-01-29T00:00:00 --timestart 12:00 --timestop 19:00 --weekdays Mon,Tue,Wed,Thu,Fri -j REJECT -nft add rule ip filter INPUT icmp type echo-request meta time "2020-01-29 00:00:00"-"2038-01-19 03:14:07" meta hour "12:00:00"-"19:00:00" meta day {1,2,3,4,5} counter reject +nft 'add rule ip filter INPUT icmp type echo-request meta time "2020-01-29 00:00:00"-"2038-01-19 03:14:07" meta hour "12:00:00"-"19:00:00" meta day { 1, 2, 3, 4, 5 } counter reject' iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --datestart 2020-01-29T00:00:00 --timestart 12:00 --timestop 19:00 ! --weekdays Mon,Tue,Wed,Thu,Fri -j REJECT -nft add rule ip filter INPUT icmp type echo-request meta time "2020-01-29 00:00:00"-"2038-01-19 03:14:07" meta hour "12:00:00"-"19:00:00" meta day {6,0} counter reject +nft 'add rule ip filter INPUT icmp type echo-request meta time "2020-01-29 00:00:00"-"2038-01-19 03:14:07" meta hour "12:00:00"-"19:00:00" meta day { 6, 0 } counter reject' diff --git a/extensions/libxt_tos.t b/extensions/libxt_tos.t index ccbe8009..6cceeeb4 100644 --- a/extensions/libxt_tos.t +++ b/extensions/libxt_tos.t @@ -4,10 +4,10 @@ -m tos --tos Maximize-Reliability;-m tos --tos 0x04/0x3f;OK -m tos --tos Minimize-Cost;-m tos --tos 0x02/0x3f;OK -m tos --tos Normal-Service;-m tos --tos 0x00/0x3f;OK --m tos --tos 0xff;=;OK --m tos ! --tos 0xff;=;OK --m tos --tos 0x00;=;OK --m tos --tos 0x0f;=;OK +-m tos --tos 0xff;-m tos --tos 0xff/0xff;OK +-m tos ! --tos 0xff;-m tos ! --tos 0xff/0xff;OK +-m tos --tos 0x00;-m tos --tos 0x00/0xff;OK +-m tos --tos 0x0f;-m tos --tos 0x0f/0xff;OK -m tos --tos 0x0f/0x0f;=;OK -m tos --tos wrong;;FAIL -m tos;;FAIL diff --git a/extensions/libxt_udp.c b/extensions/libxt_udp.c index 0c7a4bc2..ba1c3eb7 100644 --- a/extensions/libxt_udp.c +++ b/extensions/libxt_udp.c @@ -156,7 +156,6 @@ static int udp_xlate(struct xt_xlate *xl, const struct xt_xlate_mt_params *params) { const struct xt_udp *udpinfo = (struct xt_udp *)params->match->data; - char *space= ""; if (udpinfo->spts[0] != 0 || udpinfo->spts[1] != 0xFFFF) { if (udpinfo->spts[0] != udpinfo->spts[1]) { @@ -170,17 +169,16 @@ static int udp_xlate(struct xt_xlate *xl, "!= ": "", udpinfo->spts[0]); } - space = " "; } if (udpinfo->dpts[0] != 0 || udpinfo->dpts[1] != 0xFFFF) { if (udpinfo->dpts[0] != udpinfo->dpts[1]) { - xt_xlate_add(xl,"%sudp dport %s%u-%u", space, + xt_xlate_add(xl,"udp dport %s%u-%u", udpinfo->invflags & XT_UDP_INV_SRCPT ? "!= ": "", udpinfo->dpts[0], udpinfo->dpts[1]); } else { - xt_xlate_add(xl,"%sudp dport %s%u", space, + xt_xlate_add(xl,"udp dport %s%u", udpinfo->invflags & XT_UDP_INV_SRCPT ? "!= ": "", udpinfo->dpts[0]); diff --git a/extensions/libxt_udp.t b/extensions/libxt_udp.t index 1b4d3dd6..f5347701 100644 --- a/extensions/libxt_udp.t +++ b/extensions/libxt_udp.t @@ -18,5 +18,8 @@ # -p udp -m udp --sport 65536;;FAIL -p udp -m udp --sport -1;;FAIL -p udp -m udp --dport -1;;FAIL +-m udp --dport 1;;FAIL +-m udp --dport 1 -p udp;-p udp -m udp --dport 1;OK +-m udp --dport 1 -p 17;-p udp -m udp --dport 1;OK # should we accept this below? -p udp -m udp;=;OK diff --git a/extensions/libxt_udp.txlate b/extensions/libxt_udp.txlate index fbca5c12..28e7ca20 100644 --- a/extensions/libxt_udp.txlate +++ b/extensions/libxt_udp.txlate @@ -1,11 +1,11 @@ iptables-translate -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT -nft add rule ip filter INPUT iifname "eth0" udp sport 53 counter accept +nft 'add rule ip filter INPUT iifname "eth0" udp sport 53 counter accept' iptables-translate -A OUTPUT -p udp -o eth0 --dport 53:66 -j DROP -nft add rule ip filter OUTPUT oifname "eth0" udp dport 53-66 counter drop +nft 'add rule ip filter OUTPUT oifname "eth0" udp dport 53-66 counter drop' iptables-translate -I OUTPUT -p udp -d 8.8.8.8 -j ACCEPT -nft insert rule ip filter OUTPUT ip protocol udp ip daddr 8.8.8.8 counter accept +nft 'insert rule ip filter OUTPUT ip protocol udp ip daddr 8.8.8.8 counter accept' iptables-translate -I OUTPUT -p udp --dport 1020:1023 --sport 53 -j ACCEPT -nft insert rule ip filter OUTPUT udp sport 53 udp dport 1020-1023 counter accept +nft 'insert rule ip filter OUTPUT udp sport 53 udp dport 1020-1023 counter accept' |