Bugfix: need to explictly drop RPL packets by setting uip_len = 0, otherwise those packets are forwarded, with the wrong link layer address as a sender, causing the mesh to create false routes

This commit is contained in:
Adam Dunkels 2015-08-26 16:48:34 +02:00
parent 9cd84563cb
commit 2b549f3789
1 changed files with 19 additions and 15 deletions

View File

@ -256,7 +256,8 @@ dio_input(void)
PRINTF(", "); PRINTF(", ");
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
PRINTF("\n"); PRINTF("\n");
return;
goto discard;
} }
} else { } else {
PRINTF("RPL: Neighbor already in neighbor cache\n"); PRINTF("RPL: Neighbor already in neighbor cache\n");
@ -306,7 +307,7 @@ dio_input(void)
if(len + i > buffer_length) { if(len + i > buffer_length) {
PRINTF("RPL: Invalid DIO packet\n"); PRINTF("RPL: Invalid DIO packet\n");
RPL_STAT(rpl_stats.malformed_msgs++); RPL_STAT(rpl_stats.malformed_msgs++);
return; goto discard;
} }
PRINTF("RPL: DIO option %u, length: %u\n", subopt_type, len - 2); PRINTF("RPL: DIO option %u, length: %u\n", subopt_type, len - 2);
@ -316,7 +317,7 @@ dio_input(void)
if(len < 6) { if(len < 6) {
PRINTF("RPL: Invalid DAG MC, len = %d\n", len); PRINTF("RPL: Invalid DAG MC, len = %d\n", len);
RPL_STAT(rpl_stats.malformed_msgs++); RPL_STAT(rpl_stats.malformed_msgs++);
return; goto discard;
} }
dio.mc.type = buffer[i + 2]; dio.mc.type = buffer[i + 2];
dio.mc.flags = buffer[i + 3] << 1; dio.mc.flags = buffer[i + 3] << 1;
@ -342,14 +343,14 @@ dio_input(void)
dio.mc.obj.energy.energy_est = buffer[i + 7]; dio.mc.obj.energy.energy_est = buffer[i + 7];
} else { } else {
PRINTF("RPL: Unhandled DAG MC type: %u\n", (unsigned)dio.mc.type); PRINTF("RPL: Unhandled DAG MC type: %u\n", (unsigned)dio.mc.type);
return; goto discard;
} }
break; break;
case RPL_OPTION_ROUTE_INFO: case RPL_OPTION_ROUTE_INFO:
if(len < 9) { if(len < 9) {
PRINTF("RPL: Invalid destination prefix option, len = %d\n", len); PRINTF("RPL: Invalid destination prefix option, len = %d\n", len);
RPL_STAT(rpl_stats.malformed_msgs++); RPL_STAT(rpl_stats.malformed_msgs++);
return; goto discard;
} }
/* The flags field includes the preference value. */ /* The flags field includes the preference value. */
@ -365,7 +366,7 @@ dio_input(void)
} else { } else {
PRINTF("RPL: Invalid route info option, len = %d\n", len); PRINTF("RPL: Invalid route info option, len = %d\n", len);
RPL_STAT(rpl_stats.malformed_msgs++); RPL_STAT(rpl_stats.malformed_msgs++);
return; goto discard;
} }
break; break;
@ -373,7 +374,7 @@ dio_input(void)
if(len != 16) { if(len != 16) {
PRINTF("RPL: Invalid DAG configuration option, len = %d\n", len); PRINTF("RPL: Invalid DAG configuration option, len = %d\n", len);
RPL_STAT(rpl_stats.malformed_msgs++); RPL_STAT(rpl_stats.malformed_msgs++);
return; goto discard;
} }
/* Path control field not yet implemented - at i + 2 */ /* Path control field not yet implemented - at i + 2 */
@ -395,7 +396,7 @@ dio_input(void)
if(len != 32) { if(len != 32) {
PRINTF("RPL: Invalid DAG prefix info, len != 32\n"); PRINTF("RPL: Invalid DAG prefix info, len != 32\n");
RPL_STAT(rpl_stats.malformed_msgs++); RPL_STAT(rpl_stats.malformed_msgs++);
return; goto discard;
} }
dio.prefix_info.length = buffer[i + 2]; dio.prefix_info.length = buffer[i + 2];
dio.prefix_info.flags = buffer[i + 3]; dio.prefix_info.flags = buffer[i + 3];
@ -418,6 +419,7 @@ dio_input(void)
rpl_process_dio(&from, &dio); rpl_process_dio(&from, &dio);
discard:
uip_clear_buf(); uip_clear_buf();
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -622,7 +624,7 @@ dao_input(void)
if(instance == NULL) { if(instance == NULL) {
PRINTF("RPL: Ignoring a DAO for an unknown RPL instance(%u)\n", PRINTF("RPL: Ignoring a DAO for an unknown RPL instance(%u)\n",
instance_id); instance_id);
return; goto discard;
} }
lifetime = instance->default_lifetime; lifetime = instance->default_lifetime;
@ -637,7 +639,7 @@ dao_input(void)
if(flags & RPL_DAO_D_FLAG) { if(flags & RPL_DAO_D_FLAG) {
if(memcmp(&dag->dag_id, &buffer[pos], sizeof(dag->dag_id))) { if(memcmp(&dag->dag_id, &buffer[pos], sizeof(dag->dag_id))) {
PRINTF("RPL: Ignoring a DAO for a DAG different from ours\n"); PRINTF("RPL: Ignoring a DAO for a DAG different from ours\n");
return; goto discard;
} }
pos += 16; pos += 16;
} }
@ -658,7 +660,7 @@ dao_input(void)
DAG_RANK(parent->rank, instance), DAG_RANK(dag->rank, instance)); DAG_RANK(parent->rank, instance), DAG_RANK(dag->rank, instance));
parent->rank = INFINITE_RANK; parent->rank = INFINITE_RANK;
parent->flags |= RPL_PARENT_FLAG_UPDATED; parent->flags |= RPL_PARENT_FLAG_UPDATED;
return; goto discard;
} }
/* If we get the DAO from our parent, we also have a loop. */ /* If we get the DAO from our parent, we also have a loop. */
@ -666,7 +668,7 @@ dao_input(void)
PRINTF("RPL: Loop detected when receiving a unicast DAO from our parent\n"); PRINTF("RPL: Loop detected when receiving a unicast DAO from our parent\n");
parent->rank = INFINITE_RANK; parent->rank = INFINITE_RANK;
parent->flags |= RPL_PARENT_FLAG_UPDATED; parent->flags |= RPL_PARENT_FLAG_UPDATED;
return; goto discard;
} }
} }
@ -743,7 +745,7 @@ dao_input(void)
dao_ack_output(instance, &dao_sender_addr, sequence); dao_ack_output(instance, &dao_sender_addr, sequence);
} }
} }
return; goto discard;
} }
PRINTF("RPL: adding DAO route\n"); PRINTF("RPL: adding DAO route\n");
@ -765,7 +767,7 @@ dao_input(void)
PRINTF(", "); PRINTF(", ");
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
PRINTF("\n"); PRINTF("\n");
return; goto discard;
} }
} else { } else {
PRINTF("RPL: Neighbor already in neighbor cache\n"); PRINTF("RPL: Neighbor already in neighbor cache\n");
@ -777,7 +779,7 @@ dao_input(void)
if(rep == NULL) { if(rep == NULL) {
RPL_STAT(rpl_stats.mem_overflows++); RPL_STAT(rpl_stats.mem_overflows++);
PRINTF("RPL: Could not add a route after receiving a DAO\n"); PRINTF("RPL: Could not add a route after receiving a DAO\n");
return; goto discard;
} }
rep->state.lifetime = RPL_LIFETIME(instance, lifetime); rep->state.lifetime = RPL_LIFETIME(instance, lifetime);
@ -801,6 +803,8 @@ fwd_dao:
dao_ack_output(instance, &dao_sender_addr, sequence); dao_ack_output(instance, &dao_sender_addr, sequence);
} }
} }
discard:
uip_clear_buf(); uip_clear_buf();
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/