mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-02 15:34:30 +00:00
lib: add %*pHX
+ %*pHS
hexdump in printfrr
(I'll get to `zlog_hexdump()` in a separate pass.) Signed-off-by: David Lamparter <equinox@diac24.net>
This commit is contained in:
parent
bb12115e0b
commit
a4cb97a6c1
@ -91,6 +91,8 @@ Extensions
|
||||
+-----------+--------------------------+----------------------------------------------+
|
||||
| ``%pFX`` | ``struct bgp_dest *`` | ``fe80::1234/64`` (available in BGP only) |
|
||||
+-----------+--------------------------+----------------------------------------------+
|
||||
| ``%.*pHX``| ``int len, void *ptr`` | ``12 34 56 78`` (hexdump) |
|
||||
+-----------+--------------------------+----------------------------------------------+
|
||||
|
||||
Printf features like field lengths can be used normally with these extensions,
|
||||
e.g. ``%-15pI4`` works correctly.
|
||||
|
@ -227,7 +227,11 @@ void printfrr_ext_reg(const struct printfrr_ext *);
|
||||
} \
|
||||
/* end */
|
||||
|
||||
/* fbuf helper functions */
|
||||
/* fbuf helper functions - note all 3 of these return the length that would
|
||||
* be written regardless of how much space was available in the buffer, as
|
||||
* needed for implementing printfrr extensions. (They also accept NULL buf
|
||||
* for that.)
|
||||
*/
|
||||
|
||||
static inline ssize_t bputs(struct fbuf *buf, const char *str)
|
||||
{
|
||||
@ -251,6 +255,17 @@ static inline ssize_t bputch(struct fbuf *buf, char ch)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline ssize_t bputhex(struct fbuf *buf, uint8_t val)
|
||||
{
|
||||
static const char hexch[] = "0123456789abcdef";
|
||||
|
||||
if (buf && buf->pos < buf->buf + buf->len)
|
||||
*buf->pos++ = hexch[(val >> 4) & 0xf];
|
||||
if (buf && buf->pos < buf->buf + buf->len)
|
||||
*buf->pos++ = hexch[val & 0xf];
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* %pVA extension, equivalent to Linux kernel %pV */
|
||||
|
||||
struct va_format {
|
||||
@ -261,6 +276,13 @@ struct va_format {
|
||||
#ifdef _FRR_ATTRIBUTE_PRINTFRR
|
||||
#pragma FRR printfrr_ext "%pFB" (struct fbuf *)
|
||||
#pragma FRR printfrr_ext "%pVA" (struct va_format *)
|
||||
|
||||
#pragma FRR printfrr_ext "%pHX" (signed char *)
|
||||
#pragma FRR printfrr_ext "%pHX" (unsigned char *)
|
||||
#pragma FRR printfrr_ext "%pHX" (void *)
|
||||
#pragma FRR printfrr_ext "%pHS" (signed char *)
|
||||
#pragma FRR printfrr_ext "%pHS" (unsigned char *)
|
||||
#pragma FRR printfrr_ext "%pHS" (void *)
|
||||
#endif
|
||||
|
||||
/* when using non-ISO-C compatible extension specifiers... */
|
||||
|
75
lib/strformat.c
Normal file
75
lib/strformat.c
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2019 David Lamparter, for NetDEF, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "printfrr.h"
|
||||
|
||||
printfrr_ext_autoreg_p("HX", printfrr_hexdump)
|
||||
static ssize_t printfrr_hexdump(struct fbuf *buf, struct printfrr_eargs *ea,
|
||||
const void *ptr)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
ssize_t input_len = printfrr_ext_len(ea);
|
||||
char sep = ' ';
|
||||
const uint8_t *pos, *end;
|
||||
|
||||
if (ea->fmt[0] == 'c') {
|
||||
ea->fmt++;
|
||||
sep = ':';
|
||||
} else if (ea->fmt[0] == 'n') {
|
||||
ea->fmt++;
|
||||
sep = '\0';
|
||||
}
|
||||
|
||||
if (input_len < 0)
|
||||
return 0;
|
||||
|
||||
for (pos = ptr, end = pos + input_len; pos < end; pos++) {
|
||||
if (sep && pos != ptr)
|
||||
ret += bputch(buf, sep);
|
||||
ret += bputhex(buf, *pos);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* string analog for hexdumps / the "this." in ("74 68 69 73 0a |this.|") */
|
||||
|
||||
printfrr_ext_autoreg_p("HS", printfrr_hexdstr)
|
||||
static ssize_t printfrr_hexdstr(struct fbuf *buf, struct printfrr_eargs *ea,
|
||||
const void *ptr)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
ssize_t input_len = printfrr_ext_len(ea);
|
||||
const uint8_t *pos, *end;
|
||||
|
||||
if (input_len < 0)
|
||||
return 0;
|
||||
|
||||
for (pos = ptr, end = pos + input_len; pos < end; pos++) {
|
||||
if (*pos >= 0x20 && *pos < 0x7f)
|
||||
ret += bputch(buf, *pos);
|
||||
else
|
||||
ret += bputch(buf, '.');
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
@ -90,6 +90,7 @@ lib_libfrr_la_SOURCES = \
|
||||
lib/spf_backoff.c \
|
||||
lib/srcdest_table.c \
|
||||
lib/stream.c \
|
||||
lib/strformat.c \
|
||||
lib/strlcat.c \
|
||||
lib/strlcpy.c \
|
||||
lib/systemd.c \
|
||||
|
@ -216,5 +216,15 @@ int main(int argc, char **argv)
|
||||
sg.src.s_addr = INADDR_ANY;
|
||||
printchk("(*,224.1.2.3)", "%pSG4", &sg);
|
||||
|
||||
uint8_t randhex[] = { 0x12, 0x34, 0x00, 0xca, 0xfe, 0x00, 0xaa, 0x55 };
|
||||
|
||||
printchk("12 34 00 ca fe 00 aa 55", "%.8pHX", randhex);
|
||||
printchk("12 34 00 ca fe 00 aa 55", "%.*pHX",
|
||||
(int)sizeof(randhex), randhex);
|
||||
printchk("12 34 00 ca", "%.4pHX", randhex);
|
||||
|
||||
printchk("12:34:00:ca:fe:00:aa:55", "%.8pHXc", randhex);
|
||||
printchk("123400cafe00aa55", "%.8pHXn", randhex);
|
||||
|
||||
return !!errors;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user