summaryrefslogtreecommitdiffstats
path: root/lib/sockunion.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sockunion.c')
-rw-r--r--lib/sockunion.c144
1 files changed, 106 insertions, 38 deletions
diff --git a/lib/sockunion.c b/lib/sockunion.c
index d65235b41..e6340a174 100644
--- a/lib/sockunion.c
+++ b/lib/sockunion.c
@@ -664,54 +664,76 @@ void sockunion_init(union sockunion *su)
}
printfrr_ext_autoreg_p("SU", printfrr_psu)
-static ssize_t printfrr_psu(char *buf, size_t bsz, const char *fmt,
- int prec, const void *ptr)
+static ssize_t printfrr_psu(struct fbuf *buf, struct printfrr_eargs *ea,
+ const void *ptr)
{
const union sockunion *su = ptr;
- struct fbuf fb = { .buf = buf, .pos = buf, .len = bsz - 1 };
- bool include_port = false;
+ bool include_port = false, include_scope = false;
bool endflags = false;
- ssize_t consumed = 2;
-
- if (su) {
- while (!endflags) {
- switch (fmt[consumed++]) {
- case 'p':
- include_port = true;
- break;
- default:
- consumed--;
- endflags = true;
- break;
- }
- };
-
- switch (sockunion_family(su)) {
- case AF_UNSPEC:
- bprintfrr(&fb, "(unspec)");
- break;
- case AF_INET:
- inet_ntop(AF_INET, &su->sin.sin_addr, buf, bsz);
- fb.pos += strlen(fb.buf);
- if (include_port)
- bprintfrr(&fb, ":%d", su->sin.sin_port);
+ ssize_t ret = 0;
+ char cbuf[INET6_ADDRSTRLEN];
+
+ if (!su)
+ return bputs(buf, "(null)");
+
+ while (!endflags) {
+ switch (*ea->fmt) {
+ case 'p':
+ ea->fmt++;
+ include_port = true;
break;
- case AF_INET6:
- inet_ntop(AF_INET6, &su->sin6.sin6_addr, buf, bsz);
- fb.pos += strlen(fb.buf);
- if (include_port)
- bprintfrr(&fb, ":%d", su->sin6.sin6_port);
+ case 's':
+ ea->fmt++;
+ include_scope = true;
break;
default:
- bprintfrr(&fb, "(af %d)", sockunion_family(su));
+ endflags = true;
+ break;
}
+ }
- fb.pos[0] = '\0';
- } else {
- strlcpy(buf, "NULL", bsz);
+ switch (sockunion_family(su)) {
+ case AF_UNSPEC:
+ ret += bputs(buf, "(unspec)");
+ break;
+ case AF_INET:
+ inet_ntop(AF_INET, &su->sin.sin_addr, cbuf, sizeof(cbuf));
+ ret += bputs(buf, cbuf);
+ if (include_port)
+ ret += bprintfrr(buf, ":%d", ntohs(su->sin.sin_port));
+ break;
+ case AF_INET6:
+ if (include_port)
+ ret += bputch(buf, '[');
+ inet_ntop(AF_INET6, &su->sin6.sin6_addr, cbuf, sizeof(cbuf));
+ ret += bputs(buf, cbuf);
+ if (include_scope && su->sin6.sin6_scope_id)
+ ret += bprintfrr(buf, "%%%u",
+ (unsigned int)su->sin6.sin6_scope_id);
+ if (include_port)
+ ret += bprintfrr(buf, "]:%d",
+ ntohs(su->sin6.sin6_port));
+ break;
+ case AF_UNIX: {
+ int len;
+#ifdef __linux__
+ if (su->sun.sun_path[0] == '\0' && su->sun.sun_path[1]) {
+ len = strnlen(su->sun.sun_path + 1,
+ sizeof(su->sun.sun_path) - 1);
+ ret += bprintfrr(buf, "@%*pSE", len,
+ su->sun.sun_path + 1);
+ break;
+ }
+#endif
+ len = strnlen(su->sun.sun_path, sizeof(su->sun.sun_path));
+ ret += bprintfrr(buf, "%*pSE", len, su->sun.sun_path);
+ break;
+ }
+ default:
+ ret += bprintfrr(buf, "(af %d)", sockunion_family(su));
}
- return consumed;
+ return ret;
}
int sockunion_is_null(const union sockunion *su)
@@ -730,3 +752,49 @@ int sockunion_is_null(const union sockunion *su)
return 0;
}
}
+
+printfrr_ext_autoreg_i("PF", printfrr_pf)
+static ssize_t printfrr_pf(struct fbuf *buf, struct printfrr_eargs *ea,
+ uintmax_t val)
+{
+ switch (val) {
+ case AF_INET:
+ return bputs(buf, "AF_INET");
+ case AF_INET6:
+ return bputs(buf, "AF_INET6");
+ case AF_UNIX:
+ return bputs(buf, "AF_UNIX");
+#ifdef AF_PACKET
+ case AF_PACKET:
+ return bputs(buf, "AF_PACKET");
+#endif
+#ifdef AF_NETLINK
+ case AF_NETLINK:
+ return bputs(buf, "AF_NETLINK");
+#endif
+ }
+ return bprintfrr(buf, "AF_(%ju)", val);
+}
+
+printfrr_ext_autoreg_i("SO", printfrr_so)
+static ssize_t printfrr_so(struct fbuf *buf, struct printfrr_eargs *ea,
+ uintmax_t val)
+{
+ switch (val) {
+ case SOCK_STREAM:
+ return bputs(buf, "SOCK_STREAM");
+ case SOCK_DGRAM:
+ return bputs(buf, "SOCK_DGRAM");
+ case SOCK_SEQPACKET:
+ return bputs(buf, "SOCK_SEQPACKET");
+#ifdef SOCK_RAW
+ case SOCK_RAW:
+ return bputs(buf, "SOCK_RAW");
+#endif
+#ifdef SOCK_PACKET
+ case SOCK_PACKET:
+ return bputs(buf, "SOCK_PACKET");
+#endif
+ }
+ return bprintfrr(buf, "SOCK_(%ju)", val);
+}