Move the function to xshared.c for common use between legacy and xtables
sources. While being at it, silence a covscan warning triggered by that
function as it couldn't verify input buffers won't exceed IFNAMSIZ.
Therefore use snprintf() when writing to the local buffer.

Signed-off-by: Phil Sutter <p...@nwl.cc>
---
 iptables/ip6tables.c  | 31 ++-----------------------------
 iptables/iptables.c   | 30 +-----------------------------
 iptables/nft-shared.c | 39 ---------------------------------------
 iptables/nft-shared.h |  2 --
 iptables/xshared.c    | 25 +++++++++++++++++++++++++
 iptables/xshared.h    |  3 +++
 6 files changed, 31 insertions(+), 99 deletions(-)

diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c
index f5f73fe319595..f447bc7474c25 100644
--- a/iptables/ip6tables.c
+++ b/iptables/ip6tables.c
@@ -587,35 +587,8 @@ print_firewall(const struct ip6t_entry *fw,
                fputc(' ', stdout);
        }
 
-       if (format & FMT_VIA) {
-               char iface[IFNAMSIZ+2];
-
-               if (fw->ipv6.invflags & IP6T_INV_VIA_IN) {
-                       iface[0] = '!';
-                       iface[1] = '\0';
-               }
-               else iface[0] = '\0';
-
-               if (fw->ipv6.iniface[0] != '\0') {
-                       strcat(iface, fw->ipv6.iniface);
-               }
-               else if (format & FMT_NUMERIC) strcat(iface, "*");
-               else strcat(iface, "any");
-               printf(FMT(" %-6s ","in %s "), iface);
-
-               if (fw->ipv6.invflags & IP6T_INV_VIA_OUT) {
-                       iface[0] = '!';
-                       iface[1] = '\0';
-               }
-               else iface[0] = '\0';
-
-               if (fw->ipv6.outiface[0] != '\0') {
-                       strcat(iface, fw->ipv6.outiface);
-               }
-               else if (format & FMT_NUMERIC) strcat(iface, "*");
-               else strcat(iface, "any");
-               printf(FMT("%-6s ","out %s "), iface);
-       }
+       print_ifaces(fw->ipv6.iniface, fw->ipv6.outiface,
+                    fw->ipv6.invflags, format);
 
        print_ipv6_addresses(fw, format);
 
diff --git a/iptables/iptables.c b/iptables/iptables.c
index 31cb97b2ee7fa..144550fcc92ad 100644
--- a/iptables/iptables.c
+++ b/iptables/iptables.c
@@ -573,35 +573,7 @@ print_firewall(const struct ipt_entry *fw,
                fputc(' ', stdout);
        }
 
-       if (format & FMT_VIA) {
-               char iface[IFNAMSIZ+2];
-
-               if (fw->ip.invflags & IPT_INV_VIA_IN) {
-                       iface[0] = '!';
-                       iface[1] = '\0';
-               }
-               else iface[0] = '\0';
-
-               if (fw->ip.iniface[0] != '\0') {
-                       strcat(iface, fw->ip.iniface);
-               }
-               else if (format & FMT_NUMERIC) strcat(iface, "*");
-               else strcat(iface, "any");
-               printf(FMT(" %-6s ","in %s "), iface);
-
-               if (fw->ip.invflags & IPT_INV_VIA_OUT) {
-                       iface[0] = '!';
-                       iface[1] = '\0';
-               }
-               else iface[0] = '\0';
-
-               if (fw->ip.outiface[0] != '\0') {
-                       strcat(iface, fw->ip.outiface);
-               }
-               else if (format & FMT_NUMERIC) strcat(iface, "*");
-               else strcat(iface, "any");
-               printf(FMT("%-6s ","out %s "), iface);
-       }
+       print_ifaces(fw->ip.iniface, fw->ip.outiface, fw->ip.invflags, format);
 
        print_ipv4_addresses(fw, format);
 
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
index a38ffd3aa1145..fdd4522ce24f4 100644
--- a/iptables/nft-shared.c
+++ b/iptables/nft-shared.c
@@ -755,45 +755,6 @@ void print_rule_details(const struct 
iptables_command_state *cs,
        }
 }
 
-void print_ifaces(const char *iniface, const char *outiface, uint8_t invflags,
-                 unsigned int format)
-{
-       char iface[IFNAMSIZ+2];
-
-       if (!(format & FMT_VIA))
-               return;
-
-       if (invflags & IPT_INV_VIA_IN) {
-               iface[0] = '!';
-               iface[1] = '\0';
-       } else
-               iface[0] = '\0';
-
-       if (iniface[0] != '\0')
-               strcat(iface, iniface);
-       else if (format & FMT_NUMERIC)
-               strcat(iface, "*");
-       else
-               strcat(iface, "any");
-
-       printf(FMT(" %-6s ","in %s "), iface);
-
-       if (invflags & IPT_INV_VIA_OUT) {
-               iface[0] = '!';
-               iface[1] = '\0';
-       } else
-               iface[0] = '\0';
-
-       if (outiface[0] != '\0')
-               strcat(iface, outiface);
-       else if (format & FMT_NUMERIC)
-               strcat(iface, "*");
-       else
-               strcat(iface, "any");
-
-       printf(FMT("%-6s ","out %s "), iface);
-}
-
 static void
 print_iface(char letter, const char *iface, const unsigned char *mask, int inv)
 {
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
index 59e1062a725bf..1281f080bc31d 100644
--- a/iptables/nft-shared.h
+++ b/iptables/nft-shared.h
@@ -155,8 +155,6 @@ void print_rule_details(const struct iptables_command_state 
*cs,
                        const char *targname, uint8_t flags,
                        uint8_t invflags, uint8_t proto,
                        unsigned int num, unsigned int format);
-void print_ifaces(const char *iniface, const char *outiface, uint8_t invflags,
-                 unsigned int format);
 void print_matches_and_target(struct iptables_command_state *cs,
                              unsigned int format);
 void save_rule_details(const struct iptables_command_state *cs,
diff --git a/iptables/xshared.c b/iptables/xshared.c
index d30e723254570..a10e425c383a2 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -568,3 +568,28 @@ void print_ipv6_addresses(const struct ip6t_entry *fw6, 
unsigned int format)
               ipv6_addr_to_string(&fw6->ipv6.dst,
                                   &fw6->ipv6.dmsk, format));
 }
+
+/* Luckily, IPT_INV_VIA_IN and IPT_INV_VIA_OUT
+ * have the same values as IP6T_INV_VIA_IN and IP6T_INV_VIA_OUT
+ * so this function serves for both iptables and ip6tables */
+void print_ifaces(const char *iniface, const char *outiface, uint8_t invflags,
+                 unsigned int format)
+{
+       const char *anyname = format & FMT_NUMERIC ? "*" : "any";
+       char iface[IFNAMSIZ + 2];
+
+       if (!(format & FMT_VIA))
+               return;
+
+       snprintf(iface, IFNAMSIZ + 2, "%s%s",
+                invflags & IPT_INV_VIA_IN ? "!" : "",
+                iniface[0] != '\0' ? iniface : anyname);
+
+       printf(FMT(" %-6s ", "in %s "), iface);
+
+       snprintf(iface, IFNAMSIZ + 2, "%s%s",
+                invflags & IPT_INV_VIA_OUT ? "!" : "",
+                outiface[0] != '\0' ? outiface : anyname);
+
+       printf(FMT("%-6s ", "out %s "), iface);
+}
diff --git a/iptables/xshared.h b/iptables/xshared.h
index cb6f761d8afa1..ee0183c8f8e25 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -171,4 +171,7 @@ void add_param_to_argv(char *parsestart, int line);
 void print_ipv4_addresses(const struct ipt_entry *fw, unsigned int format);
 void print_ipv6_addresses(const struct ip6t_entry *fw6, unsigned int format);
 
+void print_ifaces(const char *iniface, const char *outiface, uint8_t invflags,
+                 unsigned int format);
+
 #endif /* IPTABLES_XSHARED_H */
-- 
2.18.0

Reply via email to