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
next prev 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).