-/* $OpenBSD: bgpctl.c,v 1.303 2024/01/30 13:51:13 claudio Exp $ */
+/* $OpenBSD: bgpctl.c,v 1.304 2024/01/31 11:23:19 claudio Exp $ */
/*
* Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
struct ctl_show_rib rib;
struct rde_memstats stats;
struct ibuf ibuf;
- u_int rescode, ilen;
+ u_int rescode;
switch (imsg->hdr.type) {
case IMSG_CTL_SHOW_NEIGHBOR:
output->communities(&ibuf, res);
break;
case IMSG_CTL_SHOW_RIB_ATTR:
- ilen = imsg->hdr.len - IMSG_HEADER_SIZE;
- if (ilen < 3) {
- warnx("bad IMSG_CTL_SHOW_RIB_ATTR received");
- break;
- }
if (output->attr == NULL)
break;
- output->attr(imsg->data, ilen, res->flags, 0);
+ if (imsg_get_ibuf(imsg, &ibuf) == -1)
+ err(1, "imsg_get_ibuf");
+ output->attr(&ibuf, res->flags, 0);
break;
case IMSG_CTL_SHOW_RIB_MEM:
if (output->rib_mem == NULL)
ibuf_from_buffer(&ibuf, mre->aspath, mre->aspath_len);
output->rib(&ctl, &ibuf, &res);
if (req->flags & F_CTL_DETAIL) {
- for (j = 0; j < mre->nattrs; j++)
- output->attr(mre->attrs[j].attr,
- mre->attrs[j].attr_len, req->flags, 0);
+ for (j = 0; j < mre->nattrs; j++) {
+ ibuf_from_buffer(&ibuf, mre->attrs[j].attr,
+ mre->attrs[j].attr_len);
+ output->attr(&ibuf, req->flags, 0);
+ }
}
}
}
if (ibuf_skip(&abuf, ibuf_size(&attrbuf)) == -1)
goto trunc;
- output->attr(ibuf_data(&attrbuf), ibuf_size(&attrbuf),
- reqflags, addpath);
+ output->attr(&attrbuf, reqflags, addpath);
}
if (ibuf_size(b) > 0) {
-/* $OpenBSD: bgpctl.h,v 1.23 2024/01/30 13:51:13 claudio Exp $ */
+/* $OpenBSD: bgpctl.h,v 1.24 2024/01/31 11:23:20 claudio Exp $ */
/*
* Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
void (*flowspec)(struct flowspec *);
void (*nexthop)(struct ctl_show_nexthop *);
void (*interface)(struct ctl_show_interface *);
- void (*attr)(u_char *, size_t, int, int);
+ void (*attr)(struct ibuf *, int, int);
void (*communities)(struct ibuf *, struct parse_result *);
void (*rib)(struct ctl_show_rib *, struct ibuf *,
struct parse_result *);
-/* $OpenBSD: output.c,v 1.49 2024/01/30 13:51:13 claudio Exp $ */
+/* $OpenBSD: output.c,v 1.50 2024/01/31 11:23:20 claudio Exp $ */
/*
* Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
}
static void
-show_community(u_char *data, uint16_t len)
+show_community(struct ibuf *buf)
{
uint16_t a, v;
- uint16_t i;
- if (len & 0x3) {
- printf("bad length");
- return;
- }
-
- for (i = 0; i < len; i += 4) {
- memcpy(&a, data + i, sizeof(a));
- memcpy(&v, data + i + 2, sizeof(v));
- a = ntohs(a);
- v = ntohs(v);
+ while (ibuf_size(buf) > 0) {
+ if (ibuf_get_n16(buf, &a) == -1 ||
+ ibuf_get_n16(buf, &v) == -1) {
+ printf("bad length");
+ return;
+ }
printf("%s", fmt_community(a, v));
- if (i + 4 < len)
+ if (ibuf_size(buf) > 0)
printf(" ");
}
}
static void
-show_large_community(u_char *data, uint16_t len)
+show_large_community(struct ibuf *buf)
{
uint32_t a, l1, l2;
- uint16_t i;
- if (len % 12) {
- printf("bad length");
- return;
- }
-
- for (i = 0; i < len; i += 12) {
- memcpy(&a, data + i, sizeof(a));
- memcpy(&l1, data + i + 4, sizeof(l1));
- memcpy(&l2, data + i + 8, sizeof(l2));
- a = ntohl(a);
- l1 = ntohl(l1);
- l2 = ntohl(l2);
+ while (ibuf_size(buf) > 0) {
+ if (ibuf_get_n32(buf, &a) == -1 ||
+ ibuf_get_n32(buf, &l1) == -1 ||
+ ibuf_get_n32(buf, &l2) == -1) {
+ printf("bad length");
+ return;
+ }
printf("%s", fmt_large_community(a, l1, l2));
- if (i + 12 < len)
+ if (ibuf_size(buf) > 0)
printf(" ");
}
}
static void
-show_ext_community(u_char *data, uint16_t len)
+show_ext_community(struct ibuf *buf)
{
uint64_t ext;
- uint16_t i;
-
- if (len & 0x7) {
- printf("bad length");
- return;
- }
- for (i = 0; i < len; i += 8) {
- memcpy(&ext, data + i, sizeof(ext));
- ext = be64toh(ext);
+ while (ibuf_size(buf) > 0) {
+ if (ibuf_get_n64(buf, &ext) == -1) {
+ printf("bad length");
+ return;
+ }
printf("%s", fmt_ext_community(ext));
- if (i + 8 < len)
+ if (ibuf_size(buf) > 0)
printf(" ");
}
}
static void
-show_attr(u_char *data, size_t len, int reqflags, int addpath)
+show_attr(struct ibuf *buf, int reqflags, int addpath)
{
struct in_addr id;
struct bgpd_addr prefix;
- struct ibuf ibuf, *buf = &ibuf, asbuf, *path = NULL;
+ struct ibuf asbuf, *path = NULL;
char *aspath;
- uint32_t as, pathid;
- uint16_t alen, ioff, short_as, afi;
- uint8_t flags, type, safi, aid, prefixlen;
- int i, e2, e4;
+ size_t i, alen;
+ uint32_t as, pathid, val;
+ uint16_t short_as, afi;
+ uint8_t flags, type, safi, aid, prefixlen, origin, b;
+ int e2, e4;
- if (len < 3) {
- warnx("Too short BGP attribute");
- return;
- }
-
- flags = data[0];
- type = data[1];
+ if (ibuf_get_n8(buf, &flags) == -1 ||
+ ibuf_get_n8(buf, &type) == -1)
+ goto bad_len;
/* get the attribute length */
if (flags & ATTR_EXTLEN) {
- if (len < 4) {
- warnx("Too short BGP attribute");
- return;
- }
- memcpy(&alen, data+2, sizeof(uint16_t));
- alen = ntohs(alen);
- data += 4;
- len -= 4;
+ uint16_t attr_len;
+ if (ibuf_get_n16(buf, &attr_len) == -1)
+ goto bad_len;
+ alen = attr_len;
} else {
- alen = data[2];
- data += 3;
- len -= 3;
+ uint8_t attr_len;
+ if (ibuf_get_n8(buf, &attr_len) == -1)
+ goto bad_len;
+ alen = attr_len;
}
/* bad imsg len how can that happen!? */
- if (alen > len) {
- warnx("Bad BGP attribute length");
- return;
- }
+ if (alen > ibuf_size(buf))
+ goto bad_len;
printf(" %s: ", fmt_attr(type, flags));
switch (type) {
case ATTR_ORIGIN:
- if (alen == 1)
- printf("%s", fmt_origin(*data, 0));
- else
- printf("bad length");
+ if (alen != 1 || ibuf_get_n8(buf, &origin) == -1)
+ goto bad_len;
+ printf("%s", fmt_origin(origin, 0));
break;
case ATTR_ASPATH:
case ATTR_AS4_PATH:
- ibuf_from_buffer(buf, data, alen);
/* prefer 4-byte AS here */
e4 = aspath_verify(buf, 1, 0);
e2 = aspath_verify(buf, 0, 0);
ibuf_free(path);
break;
case ATTR_NEXTHOP:
- if (alen == 4) {
- memcpy(&id, data, sizeof(id));
- printf("%s", inet_ntoa(id));
- } else
- printf("bad length");
+ case ATTR_ORIGINATOR_ID:
+ if (alen != 4 || ibuf_get(buf, &id, sizeof(id)) == -1)
+ goto bad_len;
+ printf("%s", inet_ntoa(id));
break;
case ATTR_MED:
case ATTR_LOCALPREF:
- if (alen == 4) {
- uint32_t val;
- memcpy(&val, data, sizeof(val));
- val = ntohl(val);
- printf("%u", val);
- } else
- printf("bad length");
+ if (alen != 4 || ibuf_get_n32(buf, &val) == -1)
+ goto bad_len;
+ printf("%u", val);
break;
case ATTR_AGGREGATOR:
case ATTR_AS4_AGGREGATOR:
if (alen == 8) {
- memcpy(&as, data, sizeof(as));
- memcpy(&id, data + sizeof(as), sizeof(id));
- as = ntohl(as);
+ if (ibuf_get_n32(buf, &as) == -1 ||
+ ibuf_get(buf, &id, sizeof(id)) == -1)
+ goto bad_len;
} else if (alen == 6) {
- memcpy(&short_as, data, sizeof(short_as));
- memcpy(&id, data + sizeof(short_as), sizeof(id));
- as = ntohs(short_as);
+ if (ibuf_get_n16(buf, &short_as) == -1 ||
+ ibuf_get(buf, &id, sizeof(id)) == -1)
+ goto bad_len;
+ as = short_as;
} else {
- printf("bad length");
- break;
+ goto bad_len;
}
printf("%s [%s]", log_as(as), inet_ntoa(id));
break;
case ATTR_COMMUNITIES:
- show_community(data, alen);
- break;
- case ATTR_ORIGINATOR_ID:
- if (alen == 4) {
- memcpy(&id, data, sizeof(id));
- printf("%s", inet_ntoa(id));
- } else
- printf("bad length");
+ show_community(buf);
break;
case ATTR_CLUSTER_LIST:
- for (ioff = 0; ioff + sizeof(id) <= alen;
- ioff += sizeof(id)) {
- memcpy(&id, data + ioff, sizeof(id));
+ while (ibuf_size(buf) > 0) {
+ if (ibuf_get(buf, &id, sizeof(id)) == -1)
+ goto bad_len;
printf(" %s", inet_ntoa(id));
}
break;
case ATTR_MP_REACH_NLRI:
case ATTR_MP_UNREACH_NLRI:
- if (alen < 3) {
- bad_len:
- printf("bad length");
- break;
- }
- memcpy(&afi, data, 2);
- data += 2;
- alen -= 2;
- afi = ntohs(afi);
- safi = *data++;
- alen--;
+ if (ibuf_get_n16(buf, &afi) == -1 ||
+ ibuf_get_n8(buf, &safi) == -1)
+ goto bad_len;
if (afi2aid(afi, safi, &aid) == -1) {
printf("bad AFI/SAFI pair");
if (type == ATTR_MP_REACH_NLRI) {
struct bgpd_addr nexthop;
uint8_t nhlen;
- if (len == 0)
- goto bad_len;
- nhlen = *data++;
- alen--;
- if (nhlen > len)
+ if (ibuf_get_n8(buf, &nhlen) == -1)
goto bad_len;
memset(&nexthop, 0, sizeof(nexthop));
switch (aid) {
nexthop.aid = aid;
if (nhlen != 16 && nhlen != 32)
goto bad_len;
- memcpy(&nexthop.v6.s6_addr, data, 16);
+ if (ibuf_get(buf, &nexthop.v6,
+ sizeof(nexthop.v6)) == -1)
+ goto bad_len;
break;
case AID_VPN_IPv4:
if (nhlen != 12)
goto bad_len;
nexthop.aid = AID_INET;
- memcpy(&nexthop.v4, data + sizeof(uint64_t),
- sizeof(nexthop.v4));
+ if (ibuf_skip(buf, sizeof(uint64_t)) == -1 ||
+ ibuf_get(buf, &nexthop.v4,
+ sizeof(nexthop.v4)) == -1)
+ goto bad_len;
break;
case AID_VPN_IPv6:
if (nhlen != 24)
goto bad_len;
nexthop.aid = AID_INET6;
- memcpy(&nexthop.v6, data + sizeof(uint64_t),
- sizeof(nexthop.v6));
+ if (ibuf_skip(buf, sizeof(uint64_t)) == -1 ||
+ ibuf_get(buf, &nexthop.v6,
+ sizeof(nexthop.v6)) == -1)
+ goto bad_len;
break;
default:
printf("unhandled AID #%u", aid);
goto done;
}
/* ignore reserved (old SNPA) field as per RFC4760 */
- data += nhlen + 1;
- alen -= nhlen + 1;
+ if (ibuf_skip(buf, 1) == -1)
+ goto bad_len;
printf(" nexthop: %s", log_addr(&nexthop));
}
- ibuf_from_buffer(buf, data, alen);
-
while (ibuf_size(buf) > 0) {
if (addpath)
if (ibuf_get_n32(buf, &pathid) == -1)
}
break;
case ATTR_EXT_COMMUNITIES:
- show_ext_community(data, alen);
+ show_ext_community(buf);
break;
case ATTR_LARGE_COMMUNITIES:
- show_large_community(data, alen);
+ show_large_community(buf);
break;
case ATTR_OTC:
- if (alen == 4) {
- memcpy(&as, data, sizeof(as));
- as = ntohl(as);
- printf("%s", log_as(as));
- } else {
- printf("bad length");
- }
+ if (alen != 4 || ibuf_get_n32(buf, &as) == -1)
+ goto bad_len;
+ printf("%s", log_as(as));
break;
case ATTR_ATOMIC_AGGREGATE:
default:
- printf(" len %u", alen);
+ printf(" len %zu", alen);
if (alen) {
printf(":");
- for (i=0; i < alen; i++)
- printf(" %02x", *(data+i));
+ for (i = 0; i < alen; i++) {
+ if (ibuf_get_n8(buf, &b) == -1)
+ goto bad_len;
+ printf(" %02x", b);
+ }
}
break;
}
+
done:
printf("%c", EOL0(reqflags));
+ return;
+
+ bad_len:
+ printf("bad length%c", EOL0(reqflags));
}
static void
-/* $OpenBSD: output_json.c,v 1.41 2024/01/30 13:51:13 claudio Exp $ */
+/* $OpenBSD: output_json.c,v 1.42 2024/01/31 11:23:20 claudio Exp $ */
/*
* Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
}
static void
-json_do_community(u_char *data, uint16_t len)
+json_do_community(struct ibuf *buf)
{
- uint16_t a, v, i;
-
- if (len & 0x3) {
- json_do_string("error", "bad length");
- return;
- }
+ uint16_t a, v;
json_do_array("communities");
- for (i = 0; i < len; i += 4) {
- memcpy(&a, data + i, sizeof(a));
- memcpy(&v, data + i + 2, sizeof(v));
- a = ntohs(a);
- v = ntohs(v);
+ while (ibuf_size(buf) > 0) {
+ if (ibuf_get_n16(buf, &a) == -1 ||
+ ibuf_get_n16(buf, &v) == -1) {
+ json_do_string("error", "bad length");
+ return;
+ }
json_do_string("community", fmt_community(a, v));
}
}
static void
-json_do_large_community(u_char *data, uint16_t len)
+json_do_large_community(struct ibuf *buf)
{
uint32_t a, l1, l2;
- uint16_t i;
-
- if (len % 12) {
- json_do_string("error", "bad length");
- return;
- }
json_do_array("large_communities");
- for (i = 0; i < len; i += 12) {
- memcpy(&a, data + i, sizeof(a));
- memcpy(&l1, data + i + 4, sizeof(l1));
- memcpy(&l2, data + i + 8, sizeof(l2));
- a = ntohl(a);
- l1 = ntohl(l1);
- l2 = ntohl(l2);
-
- json_do_string("community",
- fmt_large_community(a, l1, l2));
+ while (ibuf_size(buf) > 0) {
+ if (ibuf_get_n32(buf, &a) == -1 ||
+ ibuf_get_n32(buf, &l1) == -1 ||
+ ibuf_get_n32(buf, &l2) == -1) {
+ json_do_string("error", "bad length");
+ return;
+ }
+ json_do_string("community", fmt_large_community(a, l1, l2));
}
json_do_end();
}
static void
-json_do_ext_community(u_char *data, uint16_t len)
+json_do_ext_community(struct ibuf *buf)
{
uint64_t ext;
- uint16_t i;
-
- if (len & 0x7) {
- json_do_string("error", "bad length");
- return;
- }
-
json_do_array("extended_communities");
- for (i = 0; i < len; i += 8) {
- memcpy(&ext, data + i, sizeof(ext));
- ext = be64toh(ext);
+ while (ibuf_size(buf) > 0) {
+ if (ibuf_get_n64(buf, &ext) == -1) {
+ json_do_string("error", "bad length");
+ return;
+ }
json_do_string("community", fmt_ext_community(ext));
}
}
static void
-json_attr(u_char *data, size_t len, int reqflags, int addpath)
+json_attr(struct ibuf *buf, int reqflags, int addpath)
{
struct bgpd_addr prefix;
struct in_addr id;
- struct ibuf ibuf, *buf = &ibuf, asbuf, *path = NULL;
+ struct ibuf asbuf, *path = NULL;
char *aspath;
- uint32_t as, pathid;
- uint16_t alen, afi, off, short_as;
- uint8_t flags, type, safi, aid, prefixlen;
+ uint32_t as, pathid, val;
+ uint16_t alen, afi, short_as;
+ uint8_t flags, type, safi, aid, prefixlen, origin;
int e4, e2;
- if (len < 3) {
- warnx("Too short BGP attribute");
- return;
- }
-
- flags = data[0];
- type = data[1];
- if (flags & ATTR_EXTLEN) {
- if (len < 4) {
- warnx("Too short BGP attribute");
- return;
- }
- memcpy(&alen, data+2, sizeof(uint16_t));
- alen = ntohs(alen);
- data += 4;
- len -= 4;
- } else {
- alen = data[2];
- data += 3;
- len -= 3;
- }
-
- /* bad imsg len how can that happen!? */
- if (alen > len) {
- warnx("Bad BGP attribute length");
- return;
- }
-
json_do_array("attributes");
-
json_do_object("attribute", 0);
+
+ if (ibuf_get_n8(buf, &flags) == -1 ||
+ ibuf_get_n8(buf, &type) == -1)
+ goto bad_len;
+
json_do_string("type", fmt_attr(type, -1));
- json_do_uint("length", alen);
json_do_object("flags", 1);
json_do_bool("partial", flags & ATTR_PARTIAL);
json_do_bool("transitive", flags & ATTR_TRANSITIVE);
json_do_bool("optional", flags & ATTR_OPTIONAL);
json_do_end();
+ if (flags & ATTR_EXTLEN) {
+ uint16_t attr_len;
+ if (ibuf_get_n16(buf, &attr_len) == -1)
+ goto bad_len;
+ alen = attr_len;
+ } else {
+ uint8_t attr_len;
+ if (ibuf_get_n8(buf, &attr_len) == -1)
+ goto bad_len;
+ alen = attr_len;
+ }
+
+ json_do_uint("length", alen);
+
+ /* bad imsg len how can that happen!? */
+ if (alen > ibuf_size(buf))
+ goto bad_len;
+
switch (type) {
case ATTR_ORIGIN:
- if (alen == 1)
- json_do_string("origin", fmt_origin(*data, 0));
- else
- json_do_string("error", "bad length");
+ if (alen != 1 || ibuf_get_n8(buf, &origin) == -1)
+ goto bad_len;
+ json_do_string("origin", fmt_origin(origin, 0));
break;
case ATTR_ASPATH:
case ATTR_AS4_PATH:
- ibuf_from_buffer(buf, data, alen);
/* prefer 4-byte AS here */
e4 = aspath_verify(buf, 1, 0);
e2 = aspath_verify(buf, 0, 0);
ibuf_free(path);
break;
case ATTR_NEXTHOP:
- if (alen == 4) {
- memcpy(&id, data, sizeof(id));
- json_do_string("nexthop", inet_ntoa(id));
- } else
- json_do_string("error", "bad length");
+ if (alen != 4 || ibuf_get(buf, &id, sizeof(id)) == -1)
+ goto bad_len;
+ json_do_string("nexthop", inet_ntoa(id));
break;
case ATTR_MED:
case ATTR_LOCALPREF:
- if (alen == 4) {
- uint32_t val;
- memcpy(&val, data, sizeof(val));
- json_do_uint("metric", ntohl(val));
- } else
- json_do_string("error", "bad length");
+ if (alen != 4 || ibuf_get_n32(buf, &val) == -1)
+ goto bad_len;
+ json_do_uint("metric", val);
break;
case ATTR_AGGREGATOR:
case ATTR_AS4_AGGREGATOR:
if (alen == 8) {
- memcpy(&as, data, sizeof(as));
- memcpy(&id, data + sizeof(as), sizeof(id));
- as = ntohl(as);
+ if (ibuf_get_n32(buf, &as) == -1 ||
+ ibuf_get(buf, &id, sizeof(id)) == -1)
+ goto bad_len;
} else if (alen == 6) {
- memcpy(&short_as, data, sizeof(short_as));
- memcpy(&id, data + sizeof(short_as), sizeof(id));
- as = ntohs(short_as);
+ if (ibuf_get_n16(buf, &short_as) == -1 ||
+ ibuf_get(buf, &id, sizeof(id)) == -1)
+ goto bad_len;
+ as = short_as;
} else {
- json_do_string("error", "bad AS-Path");
- break;
+ goto bad_len;
}
json_do_uint("AS", as);
json_do_string("router_id", inet_ntoa(id));
break;
case ATTR_COMMUNITIES:
- json_do_community(data, alen);
+ json_do_community(buf);
break;
case ATTR_ORIGINATOR_ID:
- if (alen == 4) {
- memcpy(&id, data, sizeof(id));
- json_do_string("originator", inet_ntoa(id));
- } else
- json_do_string("error", "bad length");
+ if (alen != 4 || ibuf_get(buf, &id, sizeof(id)) == -1)
+ goto bad_len;
+ json_do_string("originator", inet_ntoa(id));
break;
case ATTR_CLUSTER_LIST:
json_do_array("cluster_list");
- for (off = 0; off + sizeof(id) <= alen;
- off += sizeof(id)) {
- memcpy(&id, data + off, sizeof(id));
+ while (ibuf_size(buf) > 0) {
+ if (ibuf_get(buf, &id, sizeof(id)) == -1)
+ goto bad_len;
json_do_string("cluster_id", inet_ntoa(id));
}
json_do_end();
break;
case ATTR_MP_REACH_NLRI:
case ATTR_MP_UNREACH_NLRI:
- if (alen < 3) {
-bad_len:
- json_do_string("error", "bad length");
- break;
- }
- memcpy(&afi, data, 2);
- data += 2;
- alen -= 2;
- afi = ntohs(afi);
- safi = *data++;
- alen--;
+ if (ibuf_get_n16(buf, &afi) == -1 ||
+ ibuf_get_n8(buf, &safi) == -1)
+ goto bad_len;
if (afi2aid(afi, safi, &aid) == -1) {
json_do_printf("error", "bad AFI/SAFI pair: %d/%d",
if (type == ATTR_MP_REACH_NLRI) {
struct bgpd_addr nexthop;
uint8_t nhlen;
- if (len == 0)
- goto bad_len;
- nhlen = *data++;
- alen--;
- if (nhlen > len)
+ if (ibuf_get_n8(buf, &nhlen) == -1)
goto bad_len;
memset(&nexthop, 0, sizeof(nexthop));
switch (aid) {
nexthop.aid = aid;
if (nhlen != 16 && nhlen != 32)
goto bad_len;
- memcpy(&nexthop.v6.s6_addr, data, 16);
+ if (ibuf_get(buf, &nexthop.v6,
+ sizeof(nexthop.v6)) == -1)
+ goto bad_len;
break;
case AID_VPN_IPv4:
if (nhlen != 12)
goto bad_len;
nexthop.aid = AID_INET;
- memcpy(&nexthop.v4, data + sizeof(uint64_t),
- sizeof(nexthop.v4));
+ if (ibuf_skip(buf, sizeof(uint64_t)) == -1 ||
+ ibuf_get(buf, &nexthop.v4,
+ sizeof(nexthop.v4)) == -1)
+ goto bad_len;
break;
case AID_VPN_IPv6:
if (nhlen != 24)
goto bad_len;
nexthop.aid = AID_INET6;
- memcpy(&nexthop.v6, data + sizeof(uint64_t),
- sizeof(nexthop.v6));
+ if (ibuf_skip(buf, sizeof(uint64_t)) == -1 ||
+ ibuf_get(buf, &nexthop.v6,
+ sizeof(nexthop.v6)) == -1)
+ goto bad_len;
break;
default:
json_do_printf("error", "unhandled AID: %d",
return;
}
/* ignore reserved (old SNPA) field as per RFC4760 */
- data += nhlen + 1;
- alen -= nhlen + 1;
+ if (ibuf_skip(buf, 1) == -1)
+ goto bad_len;
json_do_string("nexthop", log_addr(&nexthop));
}
- ibuf_from_buffer(buf, data, alen);
-
json_do_array("NLRI");
while (ibuf_size(buf) > 0) {
json_do_object("prefix", 1);
json_do_end();
break;
case ATTR_EXT_COMMUNITIES:
- json_do_ext_community(data, alen);
+ json_do_ext_community(buf);
break;
case ATTR_LARGE_COMMUNITIES:
- json_do_large_community(data, alen);
+ json_do_large_community(buf);
break;
case ATTR_OTC:
- if (alen == 4) {
- memcpy(&as, data, sizeof(as));
- as = ntohl(as);
- json_do_uint("as", as);
- } else
- json_do_string("error", "bad length");
+ if (alen != 4 || ibuf_get_n32(buf, &as) == -1)
+ goto bad_len;
+ json_do_uint("as", as);
break;
case ATTR_ATOMIC_AGGREGATE:
default:
if (alen)
- json_do_hexdump("data", data, alen);
+ json_do_hexdump("data", ibuf_data(buf), ibuf_size(buf));
break;
}
+ return;
+
+ bad_len:
+ json_do_string("error", "bad length");
}
static void