diff options
Diffstat (limited to 'lib/zclient.c')
| -rw-r--r-- | lib/zclient.c | 121 |
1 files changed, 85 insertions, 36 deletions
diff --git a/lib/zclient.c b/lib/zclient.c index 8ada2cf978..ce4886efdc 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -297,11 +297,12 @@ int zclient_read_header(struct stream *s, int sock, u_int16_t *size, if (stream_read(s, sock, ZEBRA_HEADER_SIZE) != ZEBRA_HEADER_SIZE) return -1; - *size = stream_getw(s) - ZEBRA_HEADER_SIZE; - *marker = stream_getc(s); - *version = stream_getc(s); - *vrf_id = stream_getw(s); - *cmd = stream_getw(s); + STREAM_GETW(s, *size); + *size -= ZEBRA_HEADER_SIZE; + STREAM_GETC(s, *marker); + STREAM_GETC(s, *version); + STREAM_GETW(s, *vrf_id); + STREAM_GETW(s, *cmd); if (*version != ZSERV_VERSION || *marker != ZEBRA_HEADER_MARKER) { zlog_err( @@ -313,6 +314,7 @@ int zclient_read_header(struct stream *s, int sock, u_int16_t *size, if (*size && stream_read(s, sock, *size) != *size) return -1; +stream_failure: return 0; } @@ -956,6 +958,10 @@ int zapi_route_encode(u_char cmd, struct stream *s, struct zapi_route *api) 16); stream_putl(s, api_nh->ifindex); break; + default: + zlog_warn("%s: Specified Nexthop type %d does not exist", + __PRETTY_FUNCTION__, api_nh->type); + return -1; } /* MPLS labels for BGP-LU or Segment Routing */ @@ -1005,37 +1011,66 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) memset(api, 0, sizeof(*api)); /* Type, flags, message. */ - api->type = stream_getc(s); - api->instance = stream_getw(s); - api->flags = stream_getl(s); - api->message = stream_getc(s); - api->safi = stream_getw(s); + STREAM_GETC(s, api->type); + if (api->type > ZEBRA_ROUTE_MAX) { + zlog_warn("%s: Specified route type: %d is not a legal value\n", + __PRETTY_FUNCTION__, api->type); + return -1; + } + + STREAM_GETW(s, api->instance); + STREAM_GETL(s, api->flags); + STREAM_GETC(s, api->message); + STREAM_GETW(s, api->safi); /* Prefix. */ - api->prefix.family = stream_getc(s); + STREAM_GETC(s, api->prefix.family); + STREAM_GETC(s, api->prefix.prefixlen); switch (api->prefix.family) { case AF_INET: - api->prefix.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc(s)); + if (api->prefix.prefixlen > IPV4_MAX_PREFIXLEN) { + zlog_warn("%s: V4 prefixlen is %d which should not be more than 32", + __PRETTY_FUNCTION__, api->prefix.prefixlen); + return -1; + } break; case AF_INET6: - api->prefix.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc(s)); + if (api->prefix.prefixlen > IPV6_MAX_PREFIXLEN) { + zlog_warn("%s: v6 prefixlen is %d which should not be more than 128", + __PRETTY_FUNCTION__, api->prefix.prefixlen); + return -1; + } break; + default: + zlog_warn("%s: Specified family %d is not v4 or v6", + __PRETTY_FUNCTION__, api->prefix.family); + return -1; } - stream_get(&api->prefix.u.prefix, s, PSIZE(api->prefix.prefixlen)); + STREAM_GET(&api->prefix.u.prefix, s, PSIZE(api->prefix.prefixlen)); + if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) { api->src_prefix.family = AF_INET6; - api->src_prefix.prefixlen = stream_getc(s); - stream_get(&api->src_prefix.prefix, s, + STREAM_GETC(s, api->src_prefix.prefixlen); + if (api->src_prefix.prefixlen > IPV6_MAX_PREFIXLEN) { + zlog_warn("%s: SRC Prefix prefixlen received: %d is too large", + __PRETTY_FUNCTION__, + api->src_prefix.prefixlen); + return -1; + } + STREAM_GET(&api->src_prefix.prefix, s, PSIZE(api->src_prefix.prefixlen)); if (api->prefix.family != AF_INET6 - || api->src_prefix.prefixlen == 0) - UNSET_FLAG(api->message, ZAPI_MESSAGE_SRCPFX); + || api->src_prefix.prefixlen == 0) { + zlog_warn("%s: SRC prefix specified in some manner that makes no sense", + __PRETTY_FUNCTION__); + return -1; + } } /* Nexthops. */ if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) { - api->nexthop_num = stream_getw(s); + STREAM_GETW(s, api->nexthop_num); if (api->nexthop_num > MULTIPATH_NUM) { zlog_warn("%s: invalid number of nexthops (%u)", __func__, api->nexthop_num); @@ -1045,33 +1080,40 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) for (i = 0; i < api->nexthop_num; i++) { api_nh = &api->nexthops[i]; - api_nh->type = stream_getc(s); + STREAM_GETC(s, api_nh->type); switch (api_nh->type) { case NEXTHOP_TYPE_BLACKHOLE: - api_nh->bh_type = stream_getc(s); + STREAM_GETC(s, api_nh->bh_type); break; case NEXTHOP_TYPE_IPV4: - api_nh->gate.ipv4.s_addr = stream_get_ipv4(s); + STREAM_GET(&api_nh->gate.ipv4.s_addr, s, + IPV4_MAX_BYTELEN); break; case NEXTHOP_TYPE_IPV4_IFINDEX: - api_nh->gate.ipv4.s_addr = stream_get_ipv4(s); - api_nh->ifindex = stream_getl(s); + STREAM_GET(&api_nh->gate.ipv4.s_addr, s, + IPV4_MAX_BYTELEN); + STREAM_GETL(s, api_nh->ifindex); break; case NEXTHOP_TYPE_IFINDEX: - api_nh->ifindex = stream_getl(s); + STREAM_GETL(s, api_nh->ifindex); break; case NEXTHOP_TYPE_IPV6: - stream_get(&api_nh->gate.ipv6, s, 16); + STREAM_GET(&api_nh->gate.ipv6, s, 16); break; case NEXTHOP_TYPE_IPV6_IFINDEX: - stream_get(&api_nh->gate.ipv6, s, 16); - api_nh->ifindex = stream_getl(s); + STREAM_GET(&api_nh->gate.ipv6, s, 16); + STREAM_GETL(s, api_nh->ifindex); break; + default: + zlog_warn("%s: Specified nexthop type %d does not exist", + __PRETTY_FUNCTION__, + api_nh->type); + return -1; } /* MPLS labels for BGP-LU or Segment Routing */ if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)) { - api_nh->label_num = stream_getc(s); + STREAM_GETC(s, api_nh->label_num); if (api_nh->label_num > MPLS_MAX_LABELS) { zlog_warn( @@ -1081,7 +1123,7 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) return -1; } - stream_get(&api_nh->labels[0], s, + STREAM_GET(&api_nh->labels[0], s, api_nh->label_num * sizeof(mpls_label_t)); } @@ -1090,14 +1132,15 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) /* Attributes. */ if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE)) - api->distance = stream_getc(s); + STREAM_GETC(s, api->distance); if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC)) - api->metric = stream_getl(s); + STREAM_GETL(s, api->metric); if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG)) - api->tag = stream_getl(s); + STREAM_GETL(s, api->tag); if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU)) - api->mtu = stream_getl(s); + STREAM_GETL(s, api->mtu); +stream_failure: return 0; } @@ -1136,17 +1179,23 @@ static void zclient_stream_get_prefix(struct stream *s, struct prefix *p) return; stream_get(&p->u.prefix, s, plen); - c = stream_getc(s); + STREAM_GETC(s, c); p->prefixlen = MIN(plen * 8, c); + +stream_failure: + return; } /* Router-id update from zebra daemon. */ void zebra_router_id_update_read(struct stream *s, struct prefix *rid) { /* Fetch interface address. */ - rid->family = stream_getc(s); + STREAM_GETC(s, rid->family); zclient_stream_get_prefix(s, rid); + +stream_failure: + return; } /* Interface addition from zebra daemon. */ |
