]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
add print_hexstring helper main
authorStephen Hemminger <stephen@networkplumber.org>
Thu, 23 Jul 2026 18:38:59 +0000 (18:38 +0000)
committerStephen Hemminger <stephen@networkplumber.org>
Mon, 27 Jul 2026 18:10:27 +0000 (11:10 -0700)
hexstring_n2a() writes into a caller-supplied buffer and silently
truncates when it is too small: the loop stops once fewer than three
bytes remain and returns the partial string. Callers using a fixed
SPRINT_BUF therefore drop trailing bytes for keys wider than 31 bytes.

Add a new function print_hexstring() that formats and prints a binary
attribute in one call.

Convert the callers that dump a binary attribute straight to output
over to print_hexstring().

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Reported-by: Gris Ge <cnfourt@gmail.com>
include/json_print.h
ip/ipaddress.c
ip/ipmacsec.c
lib/bpf_legacy.c
lib/json_print.c
tc/f_bpf.c
tc/m_action.c
tc/m_bpf.c

index c0d6315f1fa7b44b219074559f08fb8bdb4070dc..6a4581891fdc9c8d14d8d607935e5cb4ae27de7c 100644 (file)
@@ -84,6 +84,9 @@ _PRINT_FUNC(float, double)
 _PRINT_FUNC(tv, const struct timeval *)
 #undef _PRINT_FUNC
 
+void print_hexstring(const char *key, const char *fmt,
+                    const __u8 *data, unsigned int len);
+
 #define _PRINT_NAME_VALUE_FUNC(type_name, type, format_char)             \
        void print_##type_name##_name_value(const char *name, type value) \
 
index 6017bc8370cb6abedd68e8a25c82de0725639cda..7e4cb77c405ba5135afc04cd158d798db527b576 100644 (file)
@@ -1263,22 +1263,15 @@ int print_linkinfo(struct nlmsghdr *n, void *arg)
                                     rta_getattr_str(tb[IFLA_PHYS_PORT_NAME]));
 
                if (tb[IFLA_PHYS_PORT_ID]) {
-                       print_string(PRINT_ANY,
-                                    "phys_port_id",
-                                    "portid %s ",
-                                    hexstring_n2a(
-                                            RTA_DATA(tb[IFLA_PHYS_PORT_ID]),
-                                            RTA_PAYLOAD(tb[IFLA_PHYS_PORT_ID]),
-                                            b1, sizeof(b1)));
+                       print_hexstring("phys_port_id", "portid %s ",
+                                       RTA_DATA(tb[IFLA_PHYS_PORT_ID]),
+                                       RTA_PAYLOAD(tb[IFLA_PHYS_PORT_ID]));
                }
 
                if (tb[IFLA_PHYS_SWITCH_ID]) {
-                       print_string(PRINT_ANY,
-                                    "phys_switch_id",
-                                    "switchid %s ",
-                                    hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_SWITCH_ID]),
-                                                  RTA_PAYLOAD(tb[IFLA_PHYS_SWITCH_ID]),
-                                                  b1, sizeof(b1)));
+                       print_hexstring("phys_switch_id", "switchid %s ",
+                                       RTA_DATA(tb[IFLA_PHYS_SWITCH_ID]),
+                                       RTA_PAYLOAD(tb[IFLA_PHYS_SWITCH_ID]));
                }
 
                if (tb[IFLA_PARENT_DEV_BUS_NAME]) {
index fc4c86314fabdd06eaabda02e66189e7aa2565df..1864ffd3cd9ff1094e77b9c229b78502be5e45ab 100644 (file)
@@ -661,11 +661,8 @@ static void print_flag(struct rtattr *attrs[], const char *desc,
 
 static void print_key(struct rtattr *key)
 {
-       SPRINT_BUF(keyid);
-
-       print_string(PRINT_ANY, "key", " key %s\n",
-                    hexstring_n2a(RTA_DATA(key), RTA_PAYLOAD(key),
-                                  keyid, sizeof(keyid)));
+       print_hexstring("key", " key %s\n",
+                       RTA_DATA(key), RTA_PAYLOAD(key));
 }
 
 #define CIPHER_NAME_GCM_AES_128 "GCM-AES-128"
index 50ca82c1a51a596bbca466507b80005fb4aac533..9d5fcf5f515d8e4ad0c2f3c063278cad957e1386 100644 (file)
@@ -176,7 +176,6 @@ int bpf_dump_prog_info(FILE *f, uint32_t id)
        struct bpf_prog_info info = {};
        uint32_t len = sizeof(info);
        int fd, ret, dump_ok = 0;
-       SPRINT_BUF(tmp);
 
        open_json_object("prog");
        print_uint(PRINT_ANY, "id", "id %u ", id);
@@ -190,9 +189,8 @@ int bpf_dump_prog_info(FILE *f, uint32_t id)
                int jited = !!info.jited_prog_len;
 
                print_string(PRINT_ANY, "name", "name %s ", info.name);
-               print_string(PRINT_ANY, "tag", "tag %s ",
-                            hexstring_n2a(info.tag, sizeof(info.tag),
-                                          tmp, sizeof(tmp)));
+               print_hexstring("tag", "tag %s ",
+                               info.tag, sizeof(info.tag));
                print_uint(PRINT_JSON, "jited", NULL, jited);
                if (jited && !is_json_context())
                        fprintf(f, "jited ");
index 810d496e99c7ccea6d00083fd8dc1492f29cadbc..f604f2652596565e3466d602976420372299ccc4 100644 (file)
@@ -179,6 +179,19 @@ int print_color_string(enum output_type type,
        return ret;
 }
 
+/* Print binary data as a hex string. The buffer is sized to the input,
+ * so keys of any length are printed in full rather than truncated.
+ */
+void print_hexstring(const char *key, const char *fmt,
+                    const __u8 *data, unsigned int len)
+{
+       int blen = 2 * len + 1;
+       char buf[blen];
+
+       print_string(PRINT_ANY, key, fmt,
+                    hexstring_n2a(data, len, buf, blen));
+}
+
 /*
  * value's type is bool. When using this function in FP context you can't pass
  * a value to it, you will need to use "is_json_context()" to have different
index 6dd75445c758f58eb3123e4416dc2f32afbe0856..50fe01cae0c856d05f814b2feb6f3f02a9aff316 100644 (file)
@@ -241,11 +241,9 @@ static int bpf_print_opt(const struct filter_util *qu, FILE *f,
        if (tb[TCA_BPF_ID])
                dump_ok = bpf_dump_prog_info(f, rta_getattr_u32(tb[TCA_BPF_ID]));
        if (!dump_ok && tb[TCA_BPF_TAG]) {
-               SPRINT_BUF(b);
-
-               print_string(PRINT_ANY, "tag", "tag %s ",
-                            hexstring_n2a(RTA_DATA(tb[TCA_BPF_TAG]),
-                            RTA_PAYLOAD(tb[TCA_BPF_TAG]), b, sizeof(b)));
+               print_hexstring("tag", "tag %s ",
+                               RTA_DATA(tb[TCA_BPF_TAG]),
+                               RTA_PAYLOAD(tb[TCA_BPF_TAG]));
        }
 
        if (tb[TCA_BPF_POLICE]) {
index 6f79fdae767e191a0db4885ba9390416530975c3..bbc8e6a689f51b5dad1c346bae8ca85bcdf0c5d6 100644 (file)
@@ -401,12 +401,9 @@ static int tc_print_one_action(FILE *f, struct rtattr *arg, bool bind)
                print_nl();
        }
        if (tb[TCA_ACT_COOKIE]) {
-               int strsz = RTA_PAYLOAD(tb[TCA_ACT_COOKIE]);
-               char b1[strsz * 2 + 1];
-
-               print_string(PRINT_ANY, "cookie", "\tcookie %s",
-                            hexstring_n2a(RTA_DATA(tb[TCA_ACT_COOKIE]),
-                                          strsz, b1, sizeof(b1)));
+               print_hexstring("cookie", "\tcookie %s",
+                               RTA_DATA(tb[TCA_ACT_COOKIE]),
+                               RTA_PAYLOAD(tb[TCA_ACT_COOKIE]));
                print_nl();
        }
        if (tb[TCA_ACT_FLAGS] || tb[TCA_ACT_IN_HW_COUNT]) {
index a5de7da1fc3ec628931f6f0d32eb9f871ed868e7..83b21b57b72f56622d62a8840ce038d2a3c52e5a 100644 (file)
@@ -183,12 +183,9 @@ static int bpf_print_opt(const struct action_util *au, FILE *f, struct rtattr *a
                d_ok = bpf_dump_prog_info(f,
                                          rta_getattr_u32(tb[TCA_ACT_BPF_ID]));
        if (!d_ok && tb[TCA_ACT_BPF_TAG]) {
-               SPRINT_BUF(b);
-
-               print_string(PRINT_ANY, "tag", "tag %s ",
-                            hexstring_n2a(RTA_DATA(tb[TCA_ACT_BPF_TAG]),
-                            RTA_PAYLOAD(tb[TCA_ACT_BPF_TAG]),
-                            b, sizeof(b)));
+               print_hexstring("tag", "tag %s ",
+                               RTA_DATA(tb[TCA_ACT_BPF_TAG]),
+                               RTA_PAYLOAD(tb[TCA_ACT_BPF_TAG]));
        }
 
        print_action_control("default-action ", parm->action, _SL_);