X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fcdp%2Fcdp_input.c;h=dd3619cb8acd5a8120a738ce6810dac231e5bfbe;hb=refs%2Fchanges%2F53%2F15653%2F2;hp=fa993b84def98b79c417dd44ae255cbde921eb4b;hpb=aaacfbc5b15b0653489ad2e80db48151a4375ece;p=vpp.git diff --git a/src/plugins/cdp/cdp_input.c b/src/plugins/cdp/cdp_input.c index fa993b84def..dd3619cb8ac 100644 --- a/src/plugins/cdp/cdp_input.c +++ b/src/plugins/cdp/cdp_input.c @@ -250,7 +250,7 @@ process_cdp_hdr (cdp_main_t * cm, cdp_neighbor_t * n, cdp_hdr_t * h) static int cdp_packet_scan (cdp_main_t * cm, cdp_neighbor_t * n) { - u8 *cur = n->last_rx_pkt; + u8 *end, *cur = n->last_rx_pkt; cdp_hdr_t *h; cdp_tlv_t *tlv; cdp_error_t e = CDP_ERROR_NONE; @@ -269,24 +269,42 @@ cdp_packet_scan (cdp_main_t * cm, cdp_neighbor_t * n) if (e) return e; + // there are no tlvs + if (vec_len (n->last_rx_pkt) <= 0) + return CDP_ERROR_BAD_TLV; + cur = (u8 *) (h + 1); + end = n->last_rx_pkt + vec_len (n->last_rx_pkt) - 1; - while (cur < n->last_rx_pkt + vec_len (n->last_rx_pkt) - 1) + // look ahead 4 bytes (u16 tlv->t + u16 tlv->l) + while (cur + 3 <= end) { tlv = (cdp_tlv_t *) cur; tlv->t = ntohs (tlv->t); tlv->l = ntohs (tlv->l); - if (tlv->t >= ARRAY_LEN (tlv_handlers)) - return CDP_ERROR_BAD_TLV; - handler = &tlv_handlers[tlv->t]; - fp = handler->process; - e = (*fp) (cm, n, tlv); - if (e) - return e; - /* tlv length includes (t, l) */ + + /* tlv length includes t, l and v */ cur += tlv->l; + if ((cur - 1) > end) + return CDP_ERROR_BAD_TLV; + /* + * Only process known TLVs. In practice, certain + * devices send tlv->t = 0xFF, perhaps as an EOF of sorts. + */ + if (tlv->t < ARRAY_LEN (tlv_handlers)) + { + handler = &tlv_handlers[tlv->t]; + fp = handler->process; + e = (*fp) (cm, n, tlv); + if (e) + return e; + } } + // did not process all tlvs or none tlv processed + if ((cur - 1) != end) + return CDP_ERROR_BAD_TLV; + return CDP_ERROR_NONE; } @@ -310,7 +328,7 @@ cdp_input (vlib_main_t * vm, vlib_buffer_t * b0, u32 bi0) if (p == 0) { pool_get (cm->neighbors, n); - memset (n, 0, sizeof (*n)); + clib_memset (n, 0, sizeof (*n)); n->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; n->packet_template_index = (u8) ~ 0; hash_set (cm->neighbor_by_sw_if_index, n->sw_if_index,