diff options
-rw-r--r-- | usr.sbin/bgpctl/bgpctl.c | 51 | ||||
-rw-r--r-- | usr.sbin/bgpctl/bgpctl.h | 6 | ||||
-rw-r--r-- | usr.sbin/bgpctl/output.c | 24 | ||||
-rw-r--r-- | usr.sbin/bgpctl/output_json.c | 28 |
4 files changed, 49 insertions, 60 deletions
diff --git a/usr.sbin/bgpctl/bgpctl.c b/usr.sbin/bgpctl/bgpctl.c index 90e262cbd75..014b3000a55 100644 --- a/usr.sbin/bgpctl/bgpctl.c +++ b/usr.sbin/bgpctl/bgpctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpctl.c,v 1.301 2024/01/23 16:16:15 claudio Exp $ */ +/* $OpenBSD: bgpctl.c,v 1.302 2024/01/25 09:54:21 claudio Exp $ */ /* * Copyright (c) 2003 Henning Brauer <henning@openbsd.org> @@ -470,6 +470,7 @@ show(struct imsg *imsg, struct parse_result *res) struct flowspec f; struct ctl_show_rib rib; struct rde_memstats stats; + struct ibuf ibuf; u_char *asdata; u_int rescode, ilen; size_t aslen; @@ -539,14 +540,11 @@ show(struct imsg *imsg, struct parse_result *res) output->rib(&rib, asdata, aslen, res); break; case IMSG_CTL_SHOW_RIB_COMMUNITIES: - ilen = imsg->hdr.len - IMSG_HEADER_SIZE; - if (ilen % sizeof(struct community)) { - warnx("bad IMSG_CTL_SHOW_RIB_COMMUNITIES received"); - break; - } if (output->communities == NULL) break; - output->communities(imsg->data, ilen, res); + if (imsg_get_ibuf(imsg, &ibuf) == -1) + err(1, "imsg_get_ibuf"); + output->communities(&ibuf, res); break; case IMSG_CTL_SHOW_RIB_ATTR: ilen = imsg->hdr.len - IMSG_HEADER_SIZE; @@ -1044,53 +1042,47 @@ fmt_large_community(uint32_t d1, uint32_t d2, uint32_t d3) } const char * -fmt_ext_community(uint8_t *data) +fmt_ext_community(uint64_t ext) { static char buf[32]; - uint64_t ext; struct in_addr ip; uint32_t as4, u32; uint16_t as2, u16; uint8_t type, subtype; - type = data[0]; - subtype = data[1]; + type = ext >> 56; + subtype = ext >> 48; switch (type) { case EXT_COMMUNITY_TRANS_TWO_AS: case EXT_COMMUNITY_GEN_TWO_AS: - memcpy(&as2, data + 2, sizeof(as2)); - memcpy(&u32, data + 4, sizeof(u32)); + as2 = ext >> 32; + u32 = ext; snprintf(buf, sizeof(buf), "%s %s:%u", - log_ext_subtype(type, subtype), - log_as(ntohs(as2)), ntohl(u32)); + log_ext_subtype(type, subtype), log_as(as2), u32); return buf; case EXT_COMMUNITY_TRANS_IPV4: case EXT_COMMUNITY_GEN_IPV4: - memcpy(&ip, data + 2, sizeof(ip)); - memcpy(&u16, data + 6, sizeof(u16)); + ip.s_addr = htonl(ext >> 16); + u16 = ext; snprintf(buf, sizeof(buf), "%s %s:%hu", - log_ext_subtype(type, subtype), - inet_ntoa(ip), ntohs(u16)); + log_ext_subtype(type, subtype), inet_ntoa(ip), u16); return buf; case EXT_COMMUNITY_TRANS_FOUR_AS: case EXT_COMMUNITY_GEN_FOUR_AS: - memcpy(&as4, data + 2, sizeof(as4)); - memcpy(&u16, data + 6, sizeof(u16)); + as4 = ext >> 16; + u16 = ext; snprintf(buf, sizeof(buf), "%s %s:%hu", - log_ext_subtype(type, subtype), - log_as(ntohl(as4)), ntohs(u16)); + log_ext_subtype(type, subtype), log_as(as4), u16); return buf; case EXT_COMMUNITY_TRANS_OPAQUE: case EXT_COMMUNITY_TRANS_EVPN: - memcpy(&ext, data, sizeof(ext)); - ext = be64toh(ext) & 0xffffffffffffLL; + ext &= 0xffffffffffffULL; snprintf(buf, sizeof(buf), "%s 0x%llx", log_ext_subtype(type, subtype), (unsigned long long)ext); return buf; case EXT_COMMUNITY_NON_TRANS_OPAQUE: - memcpy(&ext, data, sizeof(ext)); - ext = be64toh(ext) & 0xffffffffffffLL; + ext &= 0xffffffffffffULL; if (subtype == EXT_COMMUNITY_SUBTYPE_OVS) { switch (ext) { case EXT_COMMUNITY_OVS_VALID: @@ -1119,10 +1111,7 @@ fmt_ext_community(uint8_t *data) } break; default: - memcpy(&ext, data, sizeof(ext)); - snprintf(buf, sizeof(buf), "%s 0x%llx", - log_ext_subtype(type, subtype), - (unsigned long long)be64toh(ext)); + snprintf(buf, sizeof(buf), "0x%llx", (unsigned long long)ext); return buf; } } diff --git a/usr.sbin/bgpctl/bgpctl.h b/usr.sbin/bgpctl/bgpctl.h index cd15723e156..db9e206c17e 100644 --- a/usr.sbin/bgpctl/bgpctl.h +++ b/usr.sbin/bgpctl/bgpctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpctl.h,v 1.21 2023/04/20 14:01:50 claudio Exp $ */ +/* $OpenBSD: bgpctl.h,v 1.22 2024/01/25 09:54:21 claudio Exp $ */ /* * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org> @@ -28,7 +28,7 @@ struct output { void (*nexthop)(struct ctl_show_nexthop *); void (*interface)(struct ctl_show_interface *); void (*attr)(u_char *, size_t, int, int); - void (*communities)(u_char *, size_t, struct parse_result *); + void (*communities)(struct ibuf *, struct parse_result *); void (*rib)(struct ctl_show_rib *, u_char *, size_t, struct parse_result *); void (*rib_mem)(struct rde_memstats *); @@ -57,7 +57,7 @@ const char *fmt_errstr(uint8_t, uint8_t); const char *fmt_attr(uint8_t, int); const char *fmt_community(uint16_t, uint16_t); const char *fmt_large_community(uint32_t, uint32_t, uint32_t); -const char *fmt_ext_community(uint8_t *); +const char *fmt_ext_community(uint64_t); const char *fmt_set_type(struct ctl_show_set *); #define MPLS_LABEL_OFFSET 12 diff --git a/usr.sbin/bgpctl/output.c b/usr.sbin/bgpctl/output.c index 3eddeaff834..3a5e59cf4ee 100644 --- a/usr.sbin/bgpctl/output.c +++ b/usr.sbin/bgpctl/output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: output.c,v 1.47 2024/01/23 16:16:15 claudio Exp $ */ +/* $OpenBSD: output.c,v 1.48 2024/01/25 09:54:21 claudio Exp $ */ /* * Copyright (c) 2003 Henning Brauer <henning@openbsd.org> @@ -646,18 +646,17 @@ show_interface(struct ctl_show_interface *iface) } static void -show_communities(u_char *data, size_t len, struct parse_result *res) +show_communities(struct ibuf *data, struct parse_result *res) { struct community c; - size_t i; uint64_t ext; uint8_t type = 0; - if (len % sizeof(c)) - return; - - for (i = 0; i < len; i += sizeof(c)) { - memcpy(&c, data + i, sizeof(c)); + while (ibuf_size(data) != 0) { + if (ibuf_get(data, &c, sizeof(c)) == -1) { + warn("communities"); + break; + } if (type != c.flags) { if (type != 0) @@ -690,9 +689,7 @@ show_communities(u_char *data, size_t len, struct parse_result *res) ext |= (uint64_t)c.data2 & 0xffff; break; } - ext = htobe64(ext); - - printf(" %s", fmt_ext_community((void *)&ext)); + printf(" %s", fmt_ext_community(ext)); break; } } @@ -751,6 +748,7 @@ show_large_community(u_char *data, uint16_t len) static void show_ext_community(u_char *data, uint16_t len) { + uint64_t ext; uint16_t i; if (len & 0x7) { @@ -759,7 +757,9 @@ show_ext_community(u_char *data, uint16_t len) } for (i = 0; i < len; i += 8) { - printf("%s", fmt_ext_community(data + i)); + memcpy(&ext, data + i, sizeof(ext)); + ext = be64toh(ext); + printf("%s", fmt_ext_community(ext)); if (i + 8 < len) printf(" "); diff --git a/usr.sbin/bgpctl/output_json.c b/usr.sbin/bgpctl/output_json.c index f04a41be86f..1ebd27b40da 100644 --- a/usr.sbin/bgpctl/output_json.c +++ b/usr.sbin/bgpctl/output_json.c @@ -1,4 +1,4 @@ -/* $OpenBSD: output_json.c,v 1.39 2024/01/23 16:16:15 claudio Exp $ */ +/* $OpenBSD: output_json.c,v 1.40 2024/01/25 09:54:21 claudio Exp $ */ /* * Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org> @@ -465,19 +465,17 @@ json_interface(struct ctl_show_interface *iface) } static void -json_communities(u_char *data, size_t len, struct parse_result *res) +json_communities(struct ibuf *data, struct parse_result *res) { struct community c; - size_t i; uint64_t ext; - if (len % sizeof(c)) { - warnx("communities: bad size"); - return; - } - for (i = 0; i < len; i += sizeof(c)) { - memcpy(&c, data + i, sizeof(c)); + while (ibuf_size(data) != 0) { + if (ibuf_get(data, &c, sizeof(c)) == -1) { + warn("communities"); + return; + } switch (c.flags) { case COMMUNITY_TYPE_BASIC: @@ -505,11 +503,9 @@ json_communities(u_char *data, size_t len, struct parse_result *res) ext |= (uint64_t)c.data2 & 0xffff; break; } - ext = htobe64(ext); json_do_array("extended_communities"); - json_do_string("community", - fmt_ext_community((void *)&ext)); + json_do_string("community", fmt_ext_community(ext)); break; } } @@ -569,6 +565,7 @@ json_do_large_community(u_char *data, uint16_t len) static void json_do_ext_community(u_char *data, uint16_t len) { + uint64_t ext; uint16_t i; if (len & 0x7) { @@ -578,8 +575,11 @@ json_do_ext_community(u_char *data, uint16_t len) json_do_array("extended_communities"); - for (i = 0; i < len; i += 8) - json_do_string("community", fmt_ext_community(data + i)); + for (i = 0; i < len; i += 8) { + memcpy(&ext, data + i, sizeof(ext)); + ext = be64toh(ext); + json_do_string("community", fmt_ext_community(ext)); + } json_do_end(); } |