summaryrefslogtreecommitdiff
path: root/lib/log.c
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@diac24.net>2020-03-24 19:37:58 +0100
committerDavid Lamparter <equinox@diac24.net>2020-03-24 19:43:18 +0100
commit46171e257c01c10bb0acf194d2b8d1f7edc03449 (patch)
tree53c5b963826bd4790034bd18f595a0f7427fe4be /lib/log.c
parent63efca0e95c727318485fe6d37141f79b1401a88 (diff)
lib: rewrite zlog_hexdump()
The old version was creating a multi-line log message, which we can't properly handle right now. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'lib/log.c')
-rw-r--r--lib/log.c88
1 files changed, 38 insertions, 50 deletions
diff --git a/lib/log.c b/lib/log.c
index 2101e0225c..b3be5216aa 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -1228,59 +1228,47 @@ int proto_redistnum(int afi, const char *s)
return -1;
}
-void zlog_hexdump(const void *mem, unsigned int len)
+void zlog_hexdump(const void *mem, size_t len)
{
- unsigned long i = 0;
- unsigned int j = 0;
- unsigned int columns = 8;
- /*
- * 19 bytes for 0xADDRESS:
- * 24 bytes for data; 2 chars plus a space per data byte
- * 1 byte for space
- * 8 bytes for ASCII representation
- * 1 byte for a newline
- * =====================
- * 53 bytes per 8 bytes of data
- * 1 byte for null term
- */
- size_t bs = ((len / 8) + 1) * 53 + 1;
- char buf[bs];
- char *s = buf;
- const unsigned char *memch = mem;
-
- memset(buf, 0, sizeof(buf));
-
- for (i = 0; i < len + ((len % columns) ? (columns - len % columns) : 0);
- i++) {
- /* print offset */
- if (i % columns == 0)
- s += snprintf(s, bs - (s - buf),
- "0x%016lx: ", (unsigned long)memch + i);
-
- /* print hex data */
- if (i < len)
- s += snprintf(s, bs - (s - buf), "%02x ", memch[i]);
-
- /* end of block, just aligning for ASCII dump */
- else
- s += snprintf(s, bs - (s - buf), " ");
-
- /* print ASCII dump */
- if (i % columns == (columns - 1)) {
- for (j = i - (columns - 1); j <= i; j++) {
- /* end of block not really printing */
- if (j >= len)
- s += snprintf(s, bs - (s - buf), " ");
- else if (isprint(memch[j]))
- s += snprintf(s, bs - (s - buf), "%c",
- memch[j]);
- else /* other char */
- s += snprintf(s, bs - (s - buf), ".");
- }
- s += snprintf(s, bs - (s - buf), "\n");
+ char line[64];
+ const uint8_t *src = mem;
+ const uint8_t *end = src + len;
+
+ if (len == 0) {
+ zlog_debug("%016lx: (zero length / no data)", (long)src);
+ return;
+ }
+
+ while (src < end) {
+ struct fbuf fb = {
+ .buf = line,
+ .pos = line,
+ .len = sizeof(line),
+ };
+ const uint8_t *lineend = src + 8;
+ unsigned line_bytes = 0;
+
+ bprintfrr(&fb, "%016lx: ", (long)src);
+
+ while (src < lineend && src < end) {
+ bprintfrr(&fb, "%02x ", *src++);
+ line_bytes++;
+ }
+ if (line_bytes < 8)
+ bprintfrr(&fb, "%*s", (8 - line_bytes) * 3, "");
+
+ src -= line_bytes;
+ while (src < lineend && src < end && fb.pos < fb.buf + fb.len) {
+ uint8_t byte = *src++;
+
+ if (isprint(byte))
+ *fb.pos++ = byte;
+ else
+ *fb.pos++ = '.';
}
+
+ zlog_debug("%.*s", (int)(fb.pos - fb.buf), fb.buf);
}
- zlog_debug("\n%s", buf);
}
const char *zlog_sanitize(char *buf, size_t bufsz, const void *in, size_t inlen)