netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Phil Sutter <phil@nwl.cc>
To: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: netfilter-devel@vger.kernel.org
Subject: [iptables PATCH 9/9] extensions: DNAT: Support service names in all spots
Date: Wed, 30 Mar 2022 17:58:51 +0200	[thread overview]
Message-ID: <20220330155851.13249-10-phil@nwl.cc> (raw)
In-Reply-To: <20220330155851.13249-1-phil@nwl.cc>

When parsing (parts of) a port spec, if it doesn't start with a digit,
try to find the largest substring getservbyname() accepts.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 extensions/libipt_DNAT.t    |  4 +++
 extensions/libxt_DNAT.c     | 70 +++++++++++++++++++++++++++----------
 extensions/libxt_REDIRECT.t |  2 ++
 3 files changed, 58 insertions(+), 18 deletions(-)

diff --git a/extensions/libipt_DNAT.t b/extensions/libipt_DNAT.t
index eb187bc91053b..c744dff3ec902 100644
--- a/extensions/libipt_DNAT.t
+++ b/extensions/libipt_DNAT.t
@@ -15,4 +15,8 @@
 -p tcp -j DNAT --to-destination 1.1.1.1:1000-2000/65536;;FAIL
 -p tcp -j DNAT --to-destination 1.1.1.1:ssh;-p tcp -j DNAT --to-destination 1.1.1.1:22;OK
 -p tcp -j DNAT --to-destination 1.1.1.1:ftp-data;-p tcp -j DNAT --to-destination 1.1.1.1:20;OK
+-p tcp -j DNAT --to-destination 1.1.1.1:ftp-data-ssh;-p tcp -j DNAT --to-destination 1.1.1.1:20-22;OK
+-p tcp -j DNAT --to-destination 1.1.1.1:echo-ftp-data;-p tcp -j DNAT --to-destination 1.1.1.1:7-20;OK
+-p tcp -j DNAT --to-destination 1.1.1.1:ftp-data-ssh/echo;-p tcp -j DNAT --to-destination 1.1.1.1:20-22/7;OK
+-p tcp -j DNAT --to-destination 1.1.1.1:echo-ftp-data/ssh;-p tcp -j DNAT --to-destination 1.1.1.1:7-20/22;OK
 -j DNAT;;FAIL
diff --git a/extensions/libxt_DNAT.c b/extensions/libxt_DNAT.c
index 754e244e0dbe6..70d2823568c7d 100644
--- a/extensions/libxt_DNAT.c
+++ b/extensions/libxt_DNAT.c
@@ -77,6 +77,49 @@ static const struct xt_option_entry REDIRECT_opts[] = {
 	XTOPT_TABLEEND,
 };
 
+static char *strrchrs(const char *s, const char *chrs)
+{
+	int i;
+
+	for (i = strlen(s) - 1; i >= 0; i--) {
+		if (strchr(chrs, s[i]))
+			return (char *)s + i;
+	}
+	return NULL;
+}
+
+static bool parse_port(const char *orig_s, char **end, unsigned int *value,
+		       unsigned int min, unsigned int max)
+{
+	char *s, *pos;
+	int port;
+
+	if (xtables_strtoui(orig_s, end, value, min, max))
+		return true;
+
+	s = xtables_strdup(orig_s);
+	port = xtables_service_to_port(s, NULL);
+	if (port >= min && port <= max)
+		goto found;
+
+	pos = strrchrs(s, "-:/");
+	while (pos) {
+		*pos = '\0';
+		port = xtables_service_to_port(s, NULL);
+		if (port >= min && port <= max)
+			goto found;
+
+		pos = strrchrs(s, "-:/");
+	}
+	free(s);
+	return false;
+found:
+	*end = (char *)orig_s + strlen(s);
+	*value = port;
+	free(s);
+	return true;
+}
+
 /* Parses ports */
 static void
 parse_ports(const char *arg, bool portok, struct nf_nat_range2 *range)
@@ -90,12 +133,9 @@ parse_ports(const char *arg, bool portok, struct nf_nat_range2 *range)
 
 	range->flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
 
-	if (!xtables_strtoui(arg, &end, &port, 1, UINT16_MAX)) {
-		port = xtables_service_to_port(arg, NULL);
-		if (port == (unsigned)-1)
-			xtables_error(PARAMETER_PROBLEM,
-				      "Port `%s' not valid", arg);
-	}
+	if (!parse_port(arg, &end, &port, 1, UINT16_MAX))
+		xtables_error(PARAMETER_PROBLEM,
+			      "Port `%s' not valid", arg);
 
 	switch (*end) {
 	case '\0':
@@ -114,12 +154,9 @@ parse_ports(const char *arg, bool portok, struct nf_nat_range2 *range)
 			      "Garbage after port value: `%s'", end);
 	}
 
-	if (!xtables_strtoui(arg, &end, &maxport, 1, UINT16_MAX)) {
-		maxport = xtables_service_to_port(arg, NULL);
-		if (maxport == (unsigned)-1)
-			xtables_error(PARAMETER_PROBLEM,
-				      "Port `%s' not valid", arg);
-	}
+	if (!parse_port(arg, &end, &maxport, 1, UINT16_MAX))
+		xtables_error(PARAMETER_PROBLEM,
+			      "Port `%s' not valid", arg);
 	if (maxport < port)
 		/* People are stupid. */
 		xtables_error(PARAMETER_PROBLEM,
@@ -139,12 +176,9 @@ parse_ports(const char *arg, bool portok, struct nf_nat_range2 *range)
 			      "Garbage after port range: `%s'", end);
 	}
 
-	if (!xtables_strtoui(arg, &end, &baseport, 1, UINT16_MAX)) {
-		baseport = xtables_service_to_port(arg, NULL);
-		if (baseport == (unsigned)-1)
-			xtables_error(PARAMETER_PROBLEM,
-				      "Port `%s' not valid", arg);
-	}
+	if (!parse_port(arg, &end, &baseport, 1, UINT16_MAX))
+		xtables_error(PARAMETER_PROBLEM,
+			      "Port `%s' not valid", arg);
 
 	range->flags |= NF_NAT_RANGE_PROTO_OFFSET;
 	range->base_proto.tcp.port = htons(baseport);
diff --git a/extensions/libxt_REDIRECT.t b/extensions/libxt_REDIRECT.t
index 3f0b8a6000445..a50ef257ec956 100644
--- a/extensions/libxt_REDIRECT.t
+++ b/extensions/libxt_REDIRECT.t
@@ -6,4 +6,6 @@
 -p tcp -j REDIRECT --to-ports 42-1234/567;;FAIL
 -p tcp -j REDIRECT --to-ports ssh;-p tcp -j REDIRECT --to-ports 22;OK
 -p tcp -j REDIRECT --to-ports ftp-data;-p tcp -j REDIRECT --to-ports 20;OK
+-p tcp -j REDIRECT --to-ports ftp-data-ssh;-p tcp -j REDIRECT --to-ports 20-22;OK
+-p tcp -j REDIRECT --to-ports echo-ftp-data;-p tcp -j REDIRECT --to-ports 7-20;OK
 -j REDIRECT --to-ports 42;;FAIL
-- 
2.34.1


  parent reply	other threads:[~2022-03-30 15:59 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-30 15:58 [iptables PATCH 0/9] extensions: Merge *_DNAT and *_REDIRECT Phil Sutter
2022-03-30 15:58 ` [iptables PATCH 1/9] man: DNAT: Describe shifted port range feature Phil Sutter
2022-03-30 15:58 ` [iptables PATCH 2/9] Revert "libipt_[SD]NAT: avoid false error about multiple destinations specified" Phil Sutter
2022-03-30 15:58 ` [iptables PATCH 3/9] extensions: ipt_DNAT: Merge v1 and v2 parsers Phil Sutter
2022-03-30 15:58 ` [iptables PATCH 4/9] extensions: ipt_DNAT: Merge v1/v2 print/save code Phil Sutter
2022-03-30 15:58 ` [iptables PATCH 5/9] extensions: ipt_DNAT: Combine xlate functions also Phil Sutter
2022-03-30 15:58 ` [iptables PATCH 6/9] extensions: DNAT: Rename from libipt to libxt Phil Sutter
2022-03-30 15:58 ` [iptables PATCH 7/9] extensions: Merge IPv4 and IPv6 DNAT targets Phil Sutter
2022-03-30 15:58 ` [iptables PATCH 8/9] extensions: Merge REDIRECT into DNAT Phil Sutter
2022-03-30 15:58 ` Phil Sutter [this message]
2022-03-30 18:38   ` [iptables PATCH 9/9] extensions: DNAT: Support service names in all spots Jan Engelhardt
2022-03-30 20:57     ` Phil Sutter
2022-03-31  0:19       ` Jan Engelhardt
2022-03-31 10:04         ` Phil Sutter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220330155851.13249-10-phil@nwl.cc \
    --to=phil@nwl.cc \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).