lib: add s option to pI4/pI6/pIA printfrr

Adding an `s` after these printfrr specifiers replaces 0.0.0.0 / :: in
the output with a star (`*`).  This is primarily intended for use with
multicast, e.g. to print `(*,G)`.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
David Lamparter 2022-01-05 16:23:23 +01:00
parent 176b254cb9
commit 2c5b4d80ef
3 changed files with 56 additions and 0 deletions

View File

@ -123,10 +123,14 @@ Networking data types
:frrfmtout:`1.2.3.4` :frrfmtout:`1.2.3.4`
``%pI4s``: :frrfmtout:`*` — print star instead of ``0.0.0.0`` (for multicast)
.. frrfmt:: %pI6 (struct in6_addr *) .. frrfmt:: %pI6 (struct in6_addr *)
:frrfmtout:`fe80::1234` :frrfmtout:`fe80::1234`
``%pI6s``: :frrfmtout:`*` — print star instead of ``::`` (for multicast)
.. frrfmt:: %pEA (struct ethaddr *) .. frrfmt:: %pEA (struct ethaddr *)
:frrfmtout:`01:23:45:67:89:ab` :frrfmtout:`01:23:45:67:89:ab`
@ -135,6 +139,8 @@ Networking data types
:frrfmtout:`1.2.3.4` / :frrfmtout:`fe80::1234` :frrfmtout:`1.2.3.4` / :frrfmtout:`fe80::1234`
``%pIAs``: — print star instead of zero address (for multicast)
.. frrfmt:: %pFX (struct prefix *) .. frrfmt:: %pFX (struct prefix *)
:frrfmtout:`1.2.3.0/24` / :frrfmtout:`fe80::1234/64` :frrfmtout:`1.2.3.0/24` / :frrfmtout:`fe80::1234/64`

View File

@ -1374,10 +1374,36 @@ static ssize_t printfrr_ia(struct fbuf *buf, struct printfrr_eargs *ea,
{ {
const struct ipaddr *ipa = ptr; const struct ipaddr *ipa = ptr;
char cbuf[INET6_ADDRSTRLEN]; char cbuf[INET6_ADDRSTRLEN];
bool use_star = false;
if (ea->fmt[0] == 's') {
use_star = true;
ea->fmt++;
}
if (!ipa) if (!ipa)
return bputs(buf, "(null)"); return bputs(buf, "(null)");
if (use_star) {
struct in_addr zero4 = {};
struct in6_addr zero6 = {};
switch (ipa->ipa_type) {
case IPADDR_V4:
if (!memcmp(&ipa->ip.addr, &zero4, sizeof(zero4)))
return bputch(buf, '*');
break;
case IPADDR_V6:
if (!memcmp(&ipa->ip.addr, &zero6, sizeof(zero6)))
return bputch(buf, '*');
break;
default:
break;
}
}
ipaddr2str(ipa, cbuf, sizeof(cbuf)); ipaddr2str(ipa, cbuf, sizeof(cbuf));
return bputs(buf, cbuf); return bputs(buf, cbuf);
} }
@ -1387,10 +1413,20 @@ static ssize_t printfrr_i4(struct fbuf *buf, struct printfrr_eargs *ea,
const void *ptr) const void *ptr)
{ {
char cbuf[INET_ADDRSTRLEN]; char cbuf[INET_ADDRSTRLEN];
bool use_star = false;
struct in_addr zero = {};
if (ea->fmt[0] == 's') {
use_star = true;
ea->fmt++;
}
if (!ptr) if (!ptr)
return bputs(buf, "(null)"); return bputs(buf, "(null)");
if (use_star && !memcmp(ptr, &zero, sizeof(zero)))
return bputch(buf, '*');
inet_ntop(AF_INET, ptr, cbuf, sizeof(cbuf)); inet_ntop(AF_INET, ptr, cbuf, sizeof(cbuf));
return bputs(buf, cbuf); return bputs(buf, cbuf);
} }
@ -1400,10 +1436,20 @@ static ssize_t printfrr_i6(struct fbuf *buf, struct printfrr_eargs *ea,
const void *ptr) const void *ptr)
{ {
char cbuf[INET6_ADDRSTRLEN]; char cbuf[INET6_ADDRSTRLEN];
bool use_star = false;
struct in6_addr zero = {};
if (ea->fmt[0] == 's') {
use_star = true;
ea->fmt++;
}
if (!ptr) if (!ptr)
return bputs(buf, "(null)"); return bputs(buf, "(null)");
if (use_star && !memcmp(ptr, &zero, sizeof(zero)))
return bputch(buf, '*');
inet_ntop(AF_INET6, ptr, cbuf, sizeof(cbuf)); inet_ntop(AF_INET6, ptr, cbuf, sizeof(cbuf));
return bputs(buf, cbuf); return bputs(buf, cbuf);
} }

View File

@ -186,6 +186,10 @@ int main(int argc, char **argv)
test_va("VA [192.168.1.2 1234] --", "%pI4 %u", &ip, 1234); test_va("VA [192.168.1.2 1234] --", "%pI4 %u", &ip, 1234);
inet_aton("0.0.0.0", &ip);
printchk("0.0.0.0", "%pI4", &ip);
printchk("*", "%pI4s", &ip);
snprintfrr(buf, sizeof(buf), "test%s", "#1"); snprintfrr(buf, sizeof(buf), "test%s", "#1");
csnprintfrr(buf, sizeof(buf), "test%s", "#2"); csnprintfrr(buf, sizeof(buf), "test%s", "#2");
assert(strcmp(buf, "test#1test#2") == 0); assert(strcmp(buf, "test#1test#2") == 0);