netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [iptables PATCH v2] extensions: dccp: Fix for DCCP type 'INVALID'
@ 2020-12-02 20:43 Phil Sutter
  0 siblings, 0 replies; only message in thread
From: Phil Sutter @ 2020-12-02 20:43 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

Support for matching on invalid DCCP type field values was pretty
broken: While RFC4340 declares any type value from 10 to 15 invalid, the
extension's type name 'INVALID' mapped to type value 10 only. Fix this
by introduction of INVALID_OTHER_TYPE_MASK which has the remaining
invalid type's bits set and apply it if bit 10 is set after parsing the
type list. When printing, stop searching type names after printing
'INVALID' - unless numeric output was requested. The latter prints all
actual type values. Since parsing types in numeric form is not
supported, changing the output should not break existing scripts.

When translating into nftables syntax, the code returned prematurely if
'INVALID' was among the list of types - thereby emitting invalid syntax.
Instead print a real match for invalid types by use of a range
expression.

While being at it, fix syntax of translator output: If only
'--dccp-types' was translated, the output contained an extra 'dccp'. On
the other hand, if '--sport' and '--dport' was present, a required
'dccp' between the translations of both was missing.

Fixes: e40b11d7ef827 ("add support for new 'dccp' protocol match")
Fixes: c94a998724143 ("extensions: libxt_dccp: Add translation to nft")
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
Changes since v1:
- Actually fix INVALID type match, thereby aligning behaviour of xtables
  match and nftables translation.
---
 extensions/libxt_dccp.c      | 57 ++++++++++++++++++++++--------------
 extensions/libxt_dccp.txlate | 12 ++++++--
 2 files changed, 44 insertions(+), 25 deletions(-)

diff --git a/extensions/libxt_dccp.c b/extensions/libxt_dccp.c
index 5e67c264db2a9..92edbafe03477 100644
--- a/extensions/libxt_dccp.c
+++ b/extensions/libxt_dccp.c
@@ -76,6 +76,9 @@ static const char *const dccp_pkt_types[] = {
 	[DCCP_PKT_INVALID]	= "INVALID",
 };
 
+/* Bits for type values 11-15 */
+#define INVALID_OTHER_TYPE_MASK		0xf800
+
 static uint16_t
 parse_dccp_types(const char *typestring)
 {
@@ -95,6 +98,9 @@ parse_dccp_types(const char *typestring)
 			xtables_error(PARAMETER_PROBLEM,
 				   "Unknown DCCP type `%s'", ptr);
 	}
+	if (typemask & (1 << DCCP_PKT_INVALID))
+		typemask |= INVALID_OTHER_TYPE_MASK;
+
 
 	free(buffer);
 	return typemask;
@@ -193,8 +199,11 @@ print_types(uint16_t types, int inverted, int numeric)
 
 		if (numeric)
 			printf("%u", i);
-		else
+		else {
+			if (i == DCCP_PKT_INVALID)
+				break;
 			printf("%s", dccp_pkt_types[i]);
+		}
 
 		types &= ~(1 << i);
 	}
@@ -288,6 +297,7 @@ static const char *const dccp_pkt_types_xlate[] = {
 	[DCCP_PKT_RESET]        = "reset",
 	[DCCP_PKT_SYNC]         = "sync",
 	[DCCP_PKT_SYNCACK]      = "syncack",
+	[DCCP_PKT_INVALID]	= "10-15",
 };
 
 static int dccp_type_xlate(const struct xt_dccp_info *einfo,
@@ -296,10 +306,10 @@ static int dccp_type_xlate(const struct xt_dccp_info *einfo,
 	bool have_type = false, set_need = false;
 	uint16_t types = einfo->typemask;
 
-	if (types & (1 << DCCP_PKT_INVALID))
-		return 0;
-
-	xt_xlate_add(xl, " dccp type%s ", einfo->invflags ? " !=" : "");
+	if (types & INVALID_OTHER_TYPE_MASK) {
+		types &= ~INVALID_OTHER_TYPE_MASK;
+		types |= 1 << DCCP_PKT_INVALID;
+	}
 
 	if ((types != 0) && !(types == (types & -types))) {
 		xt_xlate_add(xl, "{");
@@ -335,34 +345,37 @@ static int dccp_xlate(struct xt_xlate *xl,
 	char *space = "";
 	int ret = 1;
 
-	xt_xlate_add(xl, "dccp ");
-
 	if (einfo->flags & XT_DCCP_SRC_PORTS) {
+		xt_xlate_add(xl, "dccp sport%s %u",
+			     einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "",
+			     einfo->spts[0]);
+
 		if (einfo->spts[0] != einfo->spts[1])
-			xt_xlate_add(xl, "sport%s %u-%u",
-				     einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "",
-				     einfo->spts[0], einfo->spts[1]);
-		else
-			xt_xlate_add(xl, "sport%s %u",
-				     einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "",
-				     einfo->spts[0]);
+			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,
+			     einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "",
+			     einfo->dpts[0]);
+
 		if (einfo->dpts[0] != einfo->dpts[1])
-			xt_xlate_add(xl, "%sdport%s %u-%u", space,
-				     einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "",
-				     einfo->dpts[0], einfo->dpts[1]);
-		else
-			xt_xlate_add(xl, "%sdport%s %u", space,
-				     einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "",
-				     einfo->dpts[0]);
+			xt_xlate_add(xl, "-%u", einfo->dpts[1]);
+
+		space = " ";
 	}
 
-	if (einfo->flags & XT_DCCP_TYPE)
+	if (einfo->flags & XT_DCCP_TYPE && einfo->typemask) {
+		xt_xlate_add(xl, "%sdccp type%s ", space,
+			     einfo->invflags & XT_DCCP_TYPE ? " !=" : "");
 		ret = dccp_type_xlate(einfo, xl);
 
+		space = " ";
+	}
+
+	/* FIXME: no dccp option support in nftables yet */
 	if (einfo->flags & XT_DCCP_OPTION)
 		ret = 0;
 
diff --git a/extensions/libxt_dccp.txlate b/extensions/libxt_dccp.txlate
index b47dc65f5bc4f..ea853f6acf627 100644
--- a/extensions/libxt_dccp.txlate
+++ b/extensions/libxt_dccp.txlate
@@ -7,8 +7,14 @@ 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
 
-iptables-translate -A INPUT -p dccp -m dccp --dport 100 --dccp-types REQUEST,RESPONSE,DATA,ACK,DATAACK,CLOSEREQ,CLOSE,SYNC,SYNCACK
-nft add rule ip filter INPUT dccp dport 100 dccp type {request, response, data, ack, dataack, closereq, close, sync, syncack} counter
+iptables-translate -A INPUT -p dccp -m dccp --dccp-types CLOSE
+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
+
+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
 
 iptables-translate -A INPUT -p dccp -m dccp --sport 200 --dport 100
-nft add rule ip filter INPUT dccp sport 200 dport 100 counter
+nft add rule ip filter INPUT dccp sport 200 dccp dport 100 counter
-- 
2.28.0


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2020-12-02 20:44 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-02 20:43 [iptables PATCH v2] extensions: dccp: Fix for DCCP type 'INVALID' Phil Sutter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).