s = format (s, "%s(%d): ", h->name, t->t);
- for (i = 0; i < (t->l - sizeof (*t)); i++)
- vec_add1 (s, t->v[i]);
+ if (t->l >= 4)
+ {
+ for (i = 0; i < (t->l - sizeof (*t)); i++)
+ vec_add1 (s, t->v[i]);
+ }
vec_add1 (s, '\n');
return s;
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;
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);
+
+ /* tlv length includes t, l and v */
+
+ if (tlv->l < 4)
+ return CDP_ERROR_BAD_TLV;
+
+ 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 (e)
return e;
}
- /* tlv length includes (t, l) */
- cur += tlv->l;
}
+ // did not process all tlvs or none tlv processed
+ if ((cur - 1) != end)
+ return CDP_ERROR_BAD_TLV;
+
return CDP_ERROR_NONE;
}
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,
static clib_error_t *
cdp_input_init (vlib_main_t * vm)
{
- clib_error_t *error;
cdp_main_t *cm = &cdp_main;
- void vnet_cdp_node_reference (void);
-
- vnet_cdp_node_reference ();
-
- if ((error = vlib_call_init_function (vm, cdp_periodic_init)))
- return error;
cm->vlib_main = vm;
cm->vnet_main = vnet_get_main ();
return 0;
}
-VLIB_INIT_FUNCTION (cdp_input_init);
+/* *INDENT-OFF* */
+VLIB_INIT_FUNCTION (cdp_input_init) =
+{
+ .runs_after = VLIB_INITS("cdp_periodic_init"),
+};
+/* *INDENT-ON* */
static u8 *
vnet_hw_interface_t *hw;
s = format (s,
- "%=25s %=15s %=25s %=10s\n",
+ "%=25s %=25s %=25s %=10s\n",
"Our Port", "Peer System", "Peer Port", "Last Heard");
/* *INDENT-OFF* */
hw = vnet_get_sup_hw_interface (vnm, n->sw_if_index);
if (n->disabled == 0)
- s = format (s, "%=25s %=15s %=25s %=10.1f\n",
+ s = format (s, "%=25v %=25s %=25s %=10.1f\n",
hw->name, n->device_name, n->port_id,
n->last_heard);
}));