summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpctl/mrtparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/bgpctl/mrtparser.c')
-rw-r--r--usr.sbin/bgpctl/mrtparser.c173
1 files changed, 90 insertions, 83 deletions
diff --git a/usr.sbin/bgpctl/mrtparser.c b/usr.sbin/bgpctl/mrtparser.c
index 5b11098b182..4a930a5e5db 100644
--- a/usr.sbin/bgpctl/mrtparser.c
+++ b/usr.sbin/bgpctl/mrtparser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mrtparser.c,v 1.9 2018/07/20 12:49:49 claudio Exp $ */
+/* $OpenBSD: mrtparser.c,v 1.10 2019/02/25 11:51:58 claudio Exp $ */
/*
* Copyright (c) 2011 Claudio Jeker <claudio@openbsd.org>
*
@@ -38,7 +38,7 @@ int mrt_parse_dump(struct mrt_hdr *, void *, struct mrt_peer **,
struct mrt_rib **);
int mrt_parse_dump_mp(struct mrt_hdr *, void *, struct mrt_peer **,
struct mrt_rib **);
-int mrt_extract_attr(struct mrt_rib_entry *, u_char *, int, sa_family_t,
+int mrt_extract_attr(struct mrt_rib_entry *, u_char *, int, u_int8_t,
int);
void mrt_free_peers(struct mrt_peer *);
@@ -47,7 +47,7 @@ void mrt_free_bgp_state(struct mrt_bgp_state *);
void mrt_free_bgp_msg(struct mrt_bgp_msg *);
u_char *mrt_aspath_inflate(void *, u_int16_t, u_int16_t *);
-int mrt_extract_addr(void *, u_int, union mrt_addr *, sa_family_t);
+int mrt_extract_addr(void *, u_int, struct bgpd_addr *, u_int8_t);
struct mrt_bgp_state *mrt_parse_state(struct mrt_hdr *, void *);
struct mrt_bgp_msg *mrt_parse_msg(struct mrt_hdr *, void *);
@@ -172,7 +172,7 @@ mrt_parse(int fd, struct mrt_parser *p, int verbose)
break;
default:
if (verbose)
- printf("unhandled BGP4MP subtype %d\n",
+ printf("unhandled DUMP_V2 subtype %d\n",
ntohs(h.subtype));
break;
}
@@ -295,13 +295,13 @@ mrt_parse_v2_peer(struct mrt_hdr *hdr, void *msg)
if (type & MRT_DUMP_V2_PEER_BIT_I) {
if (mrt_extract_addr(b, len, &peers[i].addr,
- AF_INET6) == -1)
+ AID_INET6) == -1)
goto fail;
b += sizeof(struct in6_addr);
len -= sizeof(struct in6_addr);
} else {
if (mrt_extract_addr(b, len, &peers[i].addr,
- AF_INET) == -1)
+ AID_INET) == -1)
goto fail;
b += sizeof(struct in_addr);
len -= sizeof(struct in_addr);
@@ -360,9 +360,8 @@ mrt_parse_v2_rib(struct mrt_hdr *hdr, void *msg)
len -= 1;
if (len < MRT_PREFIX_LEN(plen))
goto fail;
- r->prefix.sin.sin_family = AF_INET;
- r->prefix.sin.sin_len = sizeof(struct sockaddr_in);
- memcpy(&r->prefix.sin.sin_addr, b, MRT_PREFIX_LEN(plen));
+ r->prefix.aid = AID_INET;
+ memcpy(&r->prefix.v4, b, MRT_PREFIX_LEN(plen));
b += MRT_PREFIX_LEN(plen);
len -= MRT_PREFIX_LEN(plen);
r->prefixlen = plen;
@@ -373,9 +372,8 @@ mrt_parse_v2_rib(struct mrt_hdr *hdr, void *msg)
len -= 1;
if (len < MRT_PREFIX_LEN(plen))
goto fail;
- r->prefix.sin6.sin6_family = AF_INET6;
- r->prefix.sin6.sin6_len = sizeof(struct sockaddr_in6);
- memcpy(&r->prefix.sin6.sin6_addr, b, MRT_PREFIX_LEN(plen));
+ r->prefix.aid = AID_INET6;
+ memcpy(&r->prefix.v6, b, MRT_PREFIX_LEN(plen));
b += MRT_PREFIX_LEN(plen);
len -= MRT_PREFIX_LEN(plen);
r->prefixlen = plen;
@@ -425,7 +423,7 @@ mrt_parse_v2_rib(struct mrt_hdr *hdr, void *msg)
if (len < alen)
goto fail;
if (mrt_extract_attr(&entries[i], b, alen,
- r->prefix.sa.sa_family, 1) == -1)
+ r->prefix.aid, 1) == -1)
goto fail;
b += alen;
len -= alen;
@@ -482,13 +480,13 @@ mrt_parse_dump(struct mrt_hdr *hdr, void *msg, struct mrt_peer **pp,
switch (ntohs(hdr->subtype)) {
case MRT_DUMP_AFI_IP:
- if (mrt_extract_addr(b, len, &r->prefix, AF_INET) == -1)
+ if (mrt_extract_addr(b, len, &r->prefix, AID_INET) == -1)
goto fail;
b += sizeof(struct in_addr);
len -= sizeof(struct in_addr);
break;
case MRT_DUMP_AFI_IPv6:
- if (mrt_extract_addr(b, len, &r->prefix, AF_INET6) == -1)
+ if (mrt_extract_addr(b, len, &r->prefix, AID_INET6) == -1)
goto fail;
b += sizeof(struct in6_addr);
len -= sizeof(struct in6_addr);
@@ -509,13 +507,13 @@ mrt_parse_dump(struct mrt_hdr *hdr, void *msg, struct mrt_peer **pp,
/* peer ip */
switch (ntohs(hdr->subtype)) {
case MRT_DUMP_AFI_IP:
- if (mrt_extract_addr(b, len, &p->peers->addr, AF_INET) == -1)
+ if (mrt_extract_addr(b, len, &p->peers->addr, AID_INET) == -1)
goto fail;
b += sizeof(struct in_addr);
len -= sizeof(struct in_addr);
break;
case MRT_DUMP_AFI_IPv6:
- if (mrt_extract_addr(b, len, &p->peers->addr, AF_INET6) == -1)
+ if (mrt_extract_addr(b, len, &p->peers->addr, AID_INET6) == -1)
goto fail;
b += sizeof(struct in6_addr);
len -= sizeof(struct in6_addr);
@@ -534,7 +532,7 @@ mrt_parse_dump(struct mrt_hdr *hdr, void *msg, struct mrt_peer **pp,
/* attr */
if (len < alen)
goto fail;
- if (mrt_extract_attr(re, b, alen, r->prefix.sa.sa_family, 0) == -1)
+ if (mrt_extract_attr(re, b, alen, r->prefix.aid, 0) == -1)
goto fail;
b += alen;
len -= alen;
@@ -555,8 +553,7 @@ mrt_parse_dump_mp(struct mrt_hdr *hdr, void *msg, struct mrt_peer **pp,
u_int8_t *b = msg;
u_int len = ntohl(hdr->length);
u_int16_t asnum, alen, afi;
- u_int8_t safi, nhlen;
- sa_family_t af;
+ u_int8_t safi, nhlen, aid;
/* just ignore the microsec field for _ET header for now */
if (ntohs(hdr->type) == MSG_PROTOCOL_BGP4MP_ET) {
@@ -612,7 +609,7 @@ mrt_parse_dump_mp(struct mrt_hdr *hdr, void *msg, struct mrt_peer **pp,
b += sizeof(struct in_addr);
len -= sizeof(struct in_addr);
/* dest IP */
- if (mrt_extract_addr(b, len, &p->peers->addr, AF_INET) == -1)
+ if (mrt_extract_addr(b, len, &p->peers->addr, AID_INET) == -1)
goto fail;
b += sizeof(struct in_addr);
len -= sizeof(struct in_addr);
@@ -624,7 +621,7 @@ mrt_parse_dump_mp(struct mrt_hdr *hdr, void *msg, struct mrt_peer **pp,
b += sizeof(struct in6_addr);
len -= sizeof(struct in6_addr);
/* dest IP */
- if (mrt_extract_addr(b, len, &p->peers->addr, AF_INET6) == -1)
+ if (mrt_extract_addr(b, len, &p->peers->addr, AID_INET6) == -1)
goto fail;
b += sizeof(struct in6_addr);
len -= sizeof(struct in6_addr);
@@ -655,18 +652,22 @@ mrt_parse_dump_mp(struct mrt_hdr *hdr, void *msg, struct mrt_peer **pp,
switch (afi) {
case MRT_DUMP_AFI_IP:
if (safi == 1 || safi == 2) {
- af = AF_INET;
+ aid = AID_INET;
break;
} else if (safi == 128) {
- af = AF_VPNv4;
+ aid = AID_VPN_IPv4;
break;
}
goto fail;
case MRT_DUMP_AFI_IPv6:
- if (safi != 1 && safi != 2)
- goto fail;
- af = AF_INET6;
- break;
+ if (safi == 1 || safi == 2) {
+ aid = AID_INET6;
+ break;
+ } else if (safi == 128) {
+ aid = AID_VPN_IPv6;
+ break;
+ }
+ goto fail;
default:
goto fail;
}
@@ -676,7 +677,7 @@ mrt_parse_dump_mp(struct mrt_hdr *hdr, void *msg, struct mrt_peer **pp,
len -= 1;
/* nexthop */
- if (mrt_extract_addr(b, len, &re->nexthop, af) == -1)
+ if (mrt_extract_addr(b, len, &re->nexthop, aid) == -1)
goto fail;
if (len < nhlen)
goto fail;
@@ -689,31 +690,32 @@ mrt_parse_dump_mp(struct mrt_hdr *hdr, void *msg, struct mrt_peer **pp,
len -= 1;
/* prefix */
- switch (af) {
- case AF_INET:
+ switch (aid) {
+ case AID_INET:
if (len < MRT_PREFIX_LEN(r->prefixlen))
goto fail;
- r->prefix.sin.sin_family = AF_INET;
- r->prefix.sin.sin_len = sizeof(struct sockaddr_in);
- memcpy(&r->prefix.sin.sin_addr, b,
- MRT_PREFIX_LEN(r->prefixlen));
+ r->prefix.aid = aid;
+ memcpy(&r->prefix.v4, b, MRT_PREFIX_LEN(r->prefixlen));
b += MRT_PREFIX_LEN(r->prefixlen);
len -= MRT_PREFIX_LEN(r->prefixlen);
break;
- case AF_INET6:
+ case AID_INET6:
if (len < MRT_PREFIX_LEN(r->prefixlen))
goto fail;
- r->prefix.sin6.sin6_family = AF_INET6;
- r->prefix.sin6.sin6_len = sizeof(struct sockaddr_in6);
- memcpy(&r->prefix.sin6.sin6_addr, b,
- MRT_PREFIX_LEN(r->prefixlen));
+ r->prefix.aid = aid;
+ memcpy(&r->prefix.v6, b, MRT_PREFIX_LEN(r->prefixlen));
b += MRT_PREFIX_LEN(r->prefixlen);
len -= MRT_PREFIX_LEN(r->prefixlen);
break;
- case AF_VPNv4:
+ case AID_VPN_IPv4:
if (len < MRT_PREFIX_LEN(r->prefixlen))
goto fail;
- errx(1, "AF_VPNv4 handling not yet implemented");
+ errx(1, "AID_VPN_IPv4 handling not yet implemented");
+ goto fail;
+ case AID_VPN_IPv6:
+ if (len < MRT_PREFIX_LEN(r->prefixlen))
+ goto fail;
+ errx(1, "AID_VPN_IPv6 handling not yet implemented");
goto fail;
}
@@ -725,7 +727,7 @@ mrt_parse_dump_mp(struct mrt_hdr *hdr, void *msg, struct mrt_peer **pp,
/* attr */
if (len < alen)
goto fail;
- if (mrt_extract_attr(re, b, alen, r->prefix.sa.sa_family, 0) == -1)
+ if (mrt_extract_attr(re, b, alen, r->prefix.aid, 0) == -1)
goto fail;
b += alen;
len -= alen;
@@ -737,7 +739,7 @@ fail:
}
int
-mrt_extract_attr(struct mrt_rib_entry *re, u_char *a, int alen, sa_family_t af,
+mrt_extract_attr(struct mrt_rib_entry *re, u_char *a, int alen, u_int8_t aid,
int as4)
{
struct mrt_attr *ap;
@@ -787,12 +789,11 @@ mrt_extract_attr(struct mrt_rib_entry *re, u_char *a, int alen, sa_family_t af,
case MRT_ATTR_NEXTHOP:
if (attr_len != 4)
return (-1);
- if (af != AF_INET)
+ if (aid != AID_INET)
break;
memcpy(&tmp, a, sizeof(tmp));
- re->nexthop.sin.sin_len = sizeof(struct sockaddr_in);
- re->nexthop.sin.sin_family = AF_INET;
- re->nexthop.sin.sin_addr.s_addr = tmp;
+ re->nexthop.aid = AID_INET;
+ re->nexthop.v4.s_addr = tmp;
break;
case MRT_ATTR_MED:
if (attr_len != 4)
@@ -823,26 +824,25 @@ mrt_extract_attr(struct mrt_rib_entry *re, u_char *a, int alen, sa_family_t af,
alen -= 3;
attr_len -= 3;
}
- switch (af) {
- case AF_INET6:
+ switch (aid) {
+ case AID_INET6:
if (attr_len < sizeof(struct in6_addr) + 1)
return (-1);
- re->nexthop.sin6.sin6_len =
- sizeof(struct sockaddr_in6);
- re->nexthop.sin6.sin6_family = AF_INET6;
- memcpy(&re->nexthop.sin6.sin6_addr, a + 1,
+ re->nexthop.aid = aid;
+ memcpy(&re->nexthop.v6, a + 1,
sizeof(struct in6_addr));
break;
- case AF_VPNv4:
+ case AID_VPN_IPv4:
if (attr_len < sizeof(u_int64_t) +
sizeof(struct in_addr))
return (-1);
- re->nexthop.svpn4.sv_len =
- sizeof(struct sockaddr_vpn4);
- re->nexthop.svpn4.sv_family = AF_VPNv4;
+ re->nexthop.aid = aid;
memcpy(&tmp, a + 1 + sizeof(u_int64_t),
sizeof(tmp));
- re->nexthop.svpn4.sv_addr.s_addr = tmp;
+ re->nexthop.vpn4.addr.s_addr = tmp;
+ break;
+ case AID_VPN_IPv6:
+ errx(1, "AID_VPN_IPv6 not yet implemented");
break;
}
break;
@@ -956,33 +956,40 @@ mrt_aspath_inflate(void *data, u_int16_t len, u_int16_t *newlen)
}
int
-mrt_extract_addr(void *msg, u_int len, union mrt_addr *addr, sa_family_t af)
+mrt_extract_addr(void *msg, u_int len, struct bgpd_addr *addr, u_int8_t aid)
{
u_int8_t *b = msg;
- switch (af) {
- case AF_INET:
+ memset(addr, 0, sizeof(*addr));
+ switch (aid) {
+ case AID_INET:
if (len < sizeof(struct in_addr))
return (-1);
- addr->sin.sin_family = AF_INET;
- addr->sin.sin_len = sizeof(struct sockaddr_in);
- memcpy(&addr->sin.sin_addr, b, sizeof(struct in_addr));
+ addr->aid = aid;
+ memcpy(&addr->v4, b, sizeof(struct in_addr));
return sizeof(struct in_addr);
- case AF_INET6:
+ case AID_INET6:
if (len < sizeof(struct in6_addr))
return (-1);
- addr->sin6.sin6_family = AF_INET6;
- addr->sin6.sin6_len = sizeof(struct sockaddr_in6);
- memcpy(&addr->sin6.sin6_addr, b, sizeof(struct in6_addr));
+ addr->aid = aid;
+ memcpy(&addr->v6, b, sizeof(struct in6_addr));
return sizeof(struct in6_addr);
- case AF_VPNv4:
+ case AID_VPN_IPv4:
if (len < sizeof(u_int64_t) + sizeof(struct in_addr))
return (-1);
- addr->svpn4.sv_len = sizeof(struct sockaddr_vpn4);
- addr->svpn4.sv_family = AF_VPNv4;
- memcpy(&addr->svpn4.sv_addr, b + sizeof(u_int64_t),
+ addr->aid = aid;
+ /* XXX labelstack and rd missing */
+ memcpy(&addr->vpn4.addr, b + sizeof(u_int64_t),
sizeof(struct in_addr));
return (sizeof(u_int64_t) + sizeof(struct in_addr));
+ case AID_VPN_IPv6:
+ if (len < sizeof(u_int64_t) + sizeof(struct in6_addr))
+ return (-1);
+ addr->aid = aid;
+ /* XXX labelstack and rd missing */
+ memcpy(&addr->vpn6.addr, b + sizeof(u_int64_t),
+ sizeof(struct in6_addr));
+ return (sizeof(u_int64_t) + sizeof(struct in6_addr));
default:
return (-1);
}
@@ -998,7 +1005,7 @@ mrt_parse_state(struct mrt_hdr *hdr, void *msg)
u_int32_t sas, das, usec;
u_int16_t tmp16, afi;
int r;
- sa_family_t af;
+ u_int8_t aid;
t.tv_sec = ntohl(hdr->timestamp);
t.tv_nsec = 0;
@@ -1063,10 +1070,10 @@ mrt_parse_state(struct mrt_hdr *hdr, void *msg)
/* src & dst addr */
switch (afi) {
case MRT_DUMP_AFI_IP:
- af = AF_INET;
+ aid = AID_INET;
break;
case MRT_DUMP_AFI_IPv6:
- af = AF_INET6;
+ aid = AID_INET6;
break;
default:
errx(1, "mrt_parse_state: bad afi");
@@ -1078,11 +1085,11 @@ mrt_parse_state(struct mrt_hdr *hdr, void *msg)
s->src_as = sas;
s->dst_as = das;
- if ((r = mrt_extract_addr(b, len, &s->src, af)) == -1)
+ if ((r = mrt_extract_addr(b, len, &s->src, aid)) == -1)
goto fail;
b += r;
len -= r;
- if ((r = mrt_extract_addr(b, len, &s->dst, af)) == -1)
+ if ((r = mrt_extract_addr(b, len, &s->dst, aid)) == -1)
goto fail;
b += r;
len -= r;
@@ -1114,7 +1121,7 @@ mrt_parse_msg(struct mrt_hdr *hdr, void *msg)
u_int32_t sas, das, usec;
u_int16_t tmp16, afi;
int r;
- sa_family_t af;
+ u_int8_t aid;
t.tv_sec = ntohl(hdr->timestamp);
t.tv_nsec = 0;
@@ -1179,10 +1186,10 @@ mrt_parse_msg(struct mrt_hdr *hdr, void *msg)
/* src & dst addr */
switch (afi) {
case MRT_DUMP_AFI_IP:
- af = AF_INET;
+ aid = AID_INET;
break;
case MRT_DUMP_AFI_IPv6:
- af = AF_INET6;
+ aid = AID_INET6;
break;
default:
errx(1, "mrt_parse_msg: bad afi");
@@ -1194,11 +1201,11 @@ mrt_parse_msg(struct mrt_hdr *hdr, void *msg)
m->src_as = sas;
m->dst_as = das;
- if ((r = mrt_extract_addr(b, len, &m->src, af)) == -1)
+ if ((r = mrt_extract_addr(b, len, &m->src, aid)) == -1)
goto fail;
b += r;
len -= r;
- if ((r = mrt_extract_addr(b, len, &m->dst, af)) == -1)
+ if ((r = mrt_extract_addr(b, len, &m->dst, aid)) == -1)
goto fail;
b += r;
len -= r;