summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2024-02-01 17:42:12 +0100
committerPhil Sutter <phil@nwl.cc>2024-02-02 18:26:14 +0100
commita86eb41ef2987a9f99cb2ef644fbe2a2096d58b2 (patch)
tree5a7f749ced799036f30e405e19fd5a5a5ff0f7c9
parent4195a89ab2e2bd690ba255e40a5c3d309f031796 (diff)
extensions: tcp/udp: Save/xlate inverted full ranges
Also translate a bare '-m tcp/udp' to 'meta l4proto' match. Fixes: 04f569ded54a7 ("extensions: libxt_udp: add translation to nft") Fixes: fb2593ebbf656 ("extensions: libxt_tcp: add translation to nft") Signed-off-by: Phil Sutter <phil@nwl.cc>
-rw-r--r--extensions/libxt_tcp.c48
-rw-r--r--extensions/libxt_tcp.t4
-rw-r--r--extensions/libxt_tcp.txlate4
-rw-r--r--extensions/libxt_udp.c43
-rw-r--r--extensions/libxt_udp.t4
-rw-r--r--extensions/libxt_udp.txlate4
6 files changed, 64 insertions, 43 deletions
diff --git a/extensions/libxt_tcp.c b/extensions/libxt_tcp.c
index f8257282..32bbd684 100644
--- a/extensions/libxt_tcp.c
+++ b/extensions/libxt_tcp.c
@@ -225,13 +225,18 @@ print_port(uint16_t port, int numeric)
printf("%s", service);
}
+static bool skip_ports_match(uint16_t min, uint16_t max, bool inv)
+{
+ return min == 0 && max == UINT16_MAX && !inv;
+}
+
static void
print_ports(const char *name, uint16_t min, uint16_t max,
int invert, int numeric)
{
const char *inv = invert ? "!" : "";
- if (min != 0 || max != 0xFFFF || invert) {
+ if (!skip_ports_match(min, max, invert)) {
printf(" %s", name);
if (min == max) {
printf(":%s", inv);
@@ -315,10 +320,11 @@ tcp_print(const void *ip, const struct xt_entry_match *match, int numeric)
static void tcp_save(const void *ip, const struct xt_entry_match *match)
{
const struct xt_tcp *tcpinfo = (struct xt_tcp *)match->data;
+ bool inv_srcpt = tcpinfo->invflags & XT_TCP_INV_SRCPT;
+ bool inv_dstpt = tcpinfo->invflags & XT_TCP_INV_DSTPT;
- if (tcpinfo->spts[0] != 0
- || tcpinfo->spts[1] != 0xFFFF) {
- if (tcpinfo->invflags & XT_TCP_INV_SRCPT)
+ if (!skip_ports_match(tcpinfo->spts[0], tcpinfo->spts[1], inv_srcpt)) {
+ if (inv_srcpt)
printf(" !");
if (tcpinfo->spts[0]
!= tcpinfo->spts[1])
@@ -330,9 +336,8 @@ static void tcp_save(const void *ip, const struct xt_entry_match *match)
tcpinfo->spts[0]);
}
- if (tcpinfo->dpts[0] != 0
- || tcpinfo->dpts[1] != 0xFFFF) {
- if (tcpinfo->invflags & XT_TCP_INV_DSTPT)
+ if (!skip_ports_match(tcpinfo->dpts[0], tcpinfo->dpts[1], inv_dstpt)) {
+ if (inv_dstpt)
printf(" !");
if (tcpinfo->dpts[0]
!= tcpinfo->dpts[1])
@@ -397,39 +402,42 @@ static int tcp_xlate(struct xt_xlate *xl,
{
const struct xt_tcp *tcpinfo =
(const struct xt_tcp *)params->match->data;
+ bool inv_srcpt = tcpinfo->invflags & XT_TCP_INV_SRCPT;
+ bool inv_dstpt = tcpinfo->invflags & XT_TCP_INV_DSTPT;
+ bool xlated = false;
- if (tcpinfo->spts[0] != 0 || tcpinfo->spts[1] != 0xffff) {
+ if (!skip_ports_match(tcpinfo->spts[0], tcpinfo->spts[1], inv_srcpt)) {
if (tcpinfo->spts[0] != tcpinfo->spts[1]) {
xt_xlate_add(xl, "tcp sport %s%u-%u",
- tcpinfo->invflags & XT_TCP_INV_SRCPT ?
- "!= " : "",
+ inv_srcpt ? "!= " : "",
tcpinfo->spts[0], tcpinfo->spts[1]);
} else {
xt_xlate_add(xl, "tcp sport %s%u",
- tcpinfo->invflags & XT_TCP_INV_SRCPT ?
- "!= " : "",
+ inv_srcpt ? "!= " : "",
tcpinfo->spts[0]);
}
+ xlated = true;
}
- if (tcpinfo->dpts[0] != 0 || tcpinfo->dpts[1] != 0xffff) {
+ if (!skip_ports_match(tcpinfo->dpts[0], tcpinfo->dpts[1], inv_dstpt)) {
if (tcpinfo->dpts[0] != tcpinfo->dpts[1]) {
xt_xlate_add(xl, "tcp dport %s%u-%u",
- tcpinfo->invflags & XT_TCP_INV_DSTPT ?
- "!= " : "",
+ inv_dstpt ? "!= " : "",
tcpinfo->dpts[0], tcpinfo->dpts[1]);
} else {
xt_xlate_add(xl, "tcp dport %s%u",
- tcpinfo->invflags & XT_TCP_INV_DSTPT ?
- "!= " : "",
+ inv_dstpt ? "!= " : "",
tcpinfo->dpts[0]);
}
+ xlated = true;
}
- if (tcpinfo->option)
+ if (tcpinfo->option) {
xt_xlate_add(xl, "tcp option %u %s", tcpinfo->option,
tcpinfo->invflags & XT_TCP_INV_OPTION ?
"missing" : "exists");
+ xlated = true;
+ }
if (tcpinfo->flg_mask || (tcpinfo->invflags & XT_TCP_INV_FLAGS)) {
xt_xlate_add(xl, "tcp flags %s",
@@ -437,8 +445,12 @@ static int tcp_xlate(struct xt_xlate *xl,
print_tcp_xlate(xl, tcpinfo->flg_cmp);
xt_xlate_add(xl, " / ");
print_tcp_xlate(xl, tcpinfo->flg_mask);
+ xlated = true;
}
+ if (!xlated)
+ xt_xlate_add(xl, "meta l4proto tcp");
+
return 1;
}
diff --git a/extensions/libxt_tcp.t b/extensions/libxt_tcp.t
index 911c5111..75d5b1ed 100644
--- a/extensions/libxt_tcp.t
+++ b/extensions/libxt_tcp.t
@@ -7,13 +7,13 @@
-p tcp -m tcp --sport 1024:65535;=;OK
-p tcp -m tcp --sport 1024:;-p tcp -m tcp --sport 1024:65535;OK
-p tcp -m tcp --sport :;-p tcp -m tcp;OK
--p tcp -m tcp ! --sport :;-p tcp -m tcp;OK
+-p tcp -m tcp ! --sport :;-p tcp -m tcp ! --sport 0:65535;OK
-p tcp -m tcp --sport :4;-p tcp -m tcp --sport 0:4;OK
-p tcp -m tcp --sport 4:;-p tcp -m tcp --sport 4:65535;OK
-p tcp -m tcp --sport 4:4;-p tcp -m tcp --sport 4;OK
-p tcp -m tcp --sport 4:3;;FAIL
-p tcp -m tcp --dport :;-p tcp -m tcp;OK
--p tcp -m tcp ! --dport :;-p tcp -m tcp;OK
+-p tcp -m tcp ! --dport :;-p tcp -m tcp ! --dport 0:65535;OK
-p tcp -m tcp --dport :4;-p tcp -m tcp --dport 0:4;OK
-p tcp -m tcp --dport 4:;-p tcp -m tcp --dport 4:65535;OK
-p tcp -m tcp --dport 4:4;-p tcp -m tcp --dport 4;OK
diff --git a/extensions/libxt_tcp.txlate b/extensions/libxt_tcp.txlate
index a7e921bf..b3ddcc15 100644
--- a/extensions/libxt_tcp.txlate
+++ b/extensions/libxt_tcp.txlate
@@ -32,7 +32,7 @@ iptables-translate -A INPUT -p tcp ! --tcp-option 23
nft 'add rule ip filter INPUT tcp option 23 missing counter'
iptables-translate -I OUTPUT -p tcp --sport 0:65535 -j ACCEPT
-nft 'insert rule ip filter OUTPUT counter accept'
+nft 'insert rule ip filter OUTPUT meta l4proto tcp counter accept'
iptables-translate -I OUTPUT -p tcp ! --sport 0:65535 -j ACCEPT
-nft 'insert rule ip filter OUTPUT counter accept'
+nft 'insert rule ip filter OUTPUT tcp sport != 0-65535 counter accept'
diff --git a/extensions/libxt_udp.c b/extensions/libxt_udp.c
index ba1c3eb7..748d4180 100644
--- a/extensions/libxt_udp.c
+++ b/extensions/libxt_udp.c
@@ -82,13 +82,18 @@ print_port(uint16_t port, int numeric)
printf("%s", service);
}
+static bool skip_ports_match(uint16_t min, uint16_t max, bool inv)
+{
+ return min == 0 && max == UINT16_MAX && !inv;
+}
+
static void
print_ports(const char *name, uint16_t min, uint16_t max,
int invert, int numeric)
{
const char *inv = invert ? "!" : "";
- if (min != 0 || max != 0xFFFF || invert) {
+ if (!skip_ports_match(min, max, invert)) {
printf(" %s", name);
if (min == max) {
printf(":%s", inv);
@@ -122,10 +127,11 @@ udp_print(const void *ip, const struct xt_entry_match *match, int numeric)
static void udp_save(const void *ip, const struct xt_entry_match *match)
{
const struct xt_udp *udpinfo = (struct xt_udp *)match->data;
+ bool inv_srcpt = udpinfo->invflags & XT_UDP_INV_SRCPT;
+ bool inv_dstpt = udpinfo->invflags & XT_UDP_INV_DSTPT;
- if (udpinfo->spts[0] != 0
- || udpinfo->spts[1] != 0xFFFF) {
- if (udpinfo->invflags & XT_UDP_INV_SRCPT)
+ if (!skip_ports_match(udpinfo->spts[0], udpinfo->spts[1], inv_srcpt)) {
+ if (inv_srcpt)
printf(" !");
if (udpinfo->spts[0]
!= udpinfo->spts[1])
@@ -137,9 +143,8 @@ static void udp_save(const void *ip, const struct xt_entry_match *match)
udpinfo->spts[0]);
}
- if (udpinfo->dpts[0] != 0
- || udpinfo->dpts[1] != 0xFFFF) {
- if (udpinfo->invflags & XT_UDP_INV_DSTPT)
+ if (!skip_ports_match(udpinfo->dpts[0], udpinfo->dpts[1], inv_dstpt)) {
+ if (inv_dstpt)
printf(" !");
if (udpinfo->dpts[0]
!= udpinfo->dpts[1])
@@ -156,35 +161,39 @@ 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;
+ bool inv_srcpt = udpinfo->invflags & XT_UDP_INV_SRCPT;
+ bool inv_dstpt = udpinfo->invflags & XT_UDP_INV_DSTPT;
+ bool xlated = false;
- if (udpinfo->spts[0] != 0 || udpinfo->spts[1] != 0xFFFF) {
+ if (!skip_ports_match(udpinfo->spts[0], udpinfo->spts[1], inv_srcpt)) {
if (udpinfo->spts[0] != udpinfo->spts[1]) {
xt_xlate_add(xl,"udp sport %s%u-%u",
- udpinfo->invflags & XT_UDP_INV_SRCPT ?
- "!= ": "",
+ inv_srcpt ? "!= ": "",
udpinfo->spts[0], udpinfo->spts[1]);
} else {
xt_xlate_add(xl, "udp sport %s%u",
- udpinfo->invflags & XT_UDP_INV_SRCPT ?
- "!= ": "",
+ inv_srcpt ? "!= ": "",
udpinfo->spts[0]);
}
+ xlated = true;
}
- if (udpinfo->dpts[0] != 0 || udpinfo->dpts[1] != 0xFFFF) {
+ if (!skip_ports_match(udpinfo->dpts[0], udpinfo->dpts[1], inv_dstpt)) {
if (udpinfo->dpts[0] != udpinfo->dpts[1]) {
xt_xlate_add(xl,"udp dport %s%u-%u",
- udpinfo->invflags & XT_UDP_INV_SRCPT ?
- "!= ": "",
+ inv_dstpt ? "!= ": "",
udpinfo->dpts[0], udpinfo->dpts[1]);
} else {
xt_xlate_add(xl,"udp dport %s%u",
- udpinfo->invflags & XT_UDP_INV_SRCPT ?
- "!= ": "",
+ inv_dstpt ? "!= ": "",
udpinfo->dpts[0]);
}
+ xlated = true;
}
+ if (!xlated)
+ xt_xlate_add(xl, "meta l4proto udp");
+
return 1;
}
diff --git a/extensions/libxt_udp.t b/extensions/libxt_udp.t
index 3c85b09f..6a2c9d07 100644
--- a/extensions/libxt_udp.t
+++ b/extensions/libxt_udp.t
@@ -7,13 +7,13 @@
-p udp -m udp --sport 1024:65535;=;OK
-p udp -m udp --sport 1024:;-p udp -m udp --sport 1024:65535;OK
-p udp -m udp --sport :;-p udp -m udp;OK
--p udp -m udp ! --sport :;-p udp -m udp;OK
+-p udp -m udp ! --sport :;-p udp -m udp ! --sport 0:65535;OK
-p udp -m udp --sport :4;-p udp -m udp --sport 0:4;OK
-p udp -m udp --sport 4:;-p udp -m udp --sport 4:65535;OK
-p udp -m udp --sport 4:4;-p udp -m udp --sport 4;OK
-p udp -m udp --sport 4:3;;FAIL
-p udp -m udp --dport :;-p udp -m udp;OK
--p udp -m udp ! --dport :;-p udp -m udp;OK
+-p udp -m udp ! --dport :;-p udp -m udp ! --dport 0:65535;OK
-p udp -m udp --dport :4;-p udp -m udp --dport 0:4;OK
-p udp -m udp --dport 4:;-p udp -m udp --dport 4:65535;OK
-p udp -m udp --dport 4:4;-p udp -m udp --dport 4;OK
diff --git a/extensions/libxt_udp.txlate b/extensions/libxt_udp.txlate
index 3aed7cd1..d6bbb96f 100644
--- a/extensions/libxt_udp.txlate
+++ b/extensions/libxt_udp.txlate
@@ -11,7 +11,7 @@ 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'
iptables-translate -I OUTPUT -p udp --sport 0:65535 -j ACCEPT
-nft 'insert rule ip filter OUTPUT counter accept'
+nft 'insert rule ip filter OUTPUT meta l4proto udp counter accept'
iptables-translate -I OUTPUT -p udp ! --sport 0:65535 -j ACCEPT
-nft 'insert rule ip filter OUTPUT counter accept'
+nft 'insert rule ip filter OUTPUT udp sport != 0-65535 counter accept'