void rpl_recv_DIS(void) { ipv6_buf = get_rpl_ipv6_buf(); rpl_dis_buf = get_rpl_dis_buf(); int len = DIS_BASE_LEN; rpl_dodag_t *dodag, *end; uint8_t options_missing = 1; while (len < (NTOHS(ipv6_buf->length) - ICMPV6_HDR_LEN)) { rpl_opt_buf = get_rpl_opt_buf(len); switch (rpl_opt_buf->type) { case (RPL_OPT_PAD1): { len += 1; break; } case (RPL_OPT_PADN): { len += rpl_opt_buf->length; break; } case (RPL_OPT_SOLICITED_INFO): { options_missing = 0; len += RPL_OPT_SOLICITED_INFO_LEN; /* extract and check */ if (rpl_opt_buf->length != RPL_OPT_SOLICITED_INFO_LEN) { /* error malformed */ return; } rpl_opt_solicited_buf = get_rpl_opt_solicited_buf(len); for (dodag = rpl_dodags, end = dodag + RPL_MAX_DODAGS; dodag < end; dodag++) { if (dodag->joined) { if (rpl_opt_solicited_buf->VID_Flags & RPL_DIS_I_MASK) { if (dodag->instance->id != rpl_opt_solicited_buf->rplinstanceid) { continue; } } if (rpl_opt_solicited_buf->VID_Flags & RPL_DIS_D_MASK) { if (!rpl_equal_id(&dodag->dodag_id, &rpl_opt_solicited_buf->dodagid)) { continue; } } if (rpl_opt_solicited_buf->VID_Flags & RPL_DIS_V_MASK) { if (dodag->version != rpl_opt_solicited_buf->version) { continue; } } rpl_send_DIO(dodag, &ipv6_buf->srcaddr); trickle_reset_timer(&dodag->trickle); } } break; } default: return; } } if (options_missing) { for (dodag = rpl_dodags, end = dodag + RPL_MAX_DODAGS; dodag < end; dodag++) { if (dodag->joined) { rpl_send_DIO(dodag, &ipv6_buf->srcaddr); trickle_reset_timer(&dodag->trickle); } } } }
void rpl_recv_DIS_mode(void) { rpl_dodag_t *my_dodag = rpl_get_my_dodag(); if (my_dodag == NULL) { return; } ipv6_buf = get_rpl_ipv6_buf(); rpl_dis_buf = get_rpl_dis_buf(); int len = DIS_BASE_LEN; while (len < (NTOHS(ipv6_buf->length) - ICMPV6_HDR_LEN)) { rpl_opt_buf = get_rpl_opt_buf(len); switch (rpl_opt_buf->type) { case (RPL_OPT_PAD1): { len += 1; break; } case (RPL_OPT_PADN): { len += rpl_opt_buf->length; break; } case (RPL_OPT_SOLICITED_INFO): { len += RPL_OPT_SOLICITED_INFO_LEN; /* extract and check */ if (rpl_opt_buf->length != RPL_OPT_SOLICITED_INFO_LEN) { /* error malformed */ return; } rpl_opt_solicited_buf = get_rpl_opt_solicited_buf(len); if (rpl_opt_solicited_buf->VID_Flags & RPL_DIS_I_MASK) { if (my_dodag->instance->id != rpl_opt_solicited_buf->rplinstanceid) { return; } } if (rpl_opt_solicited_buf->VID_Flags & RPL_DIS_D_MASK) { if (!rpl_equal_id(&my_dodag->dodag_id, &rpl_opt_solicited_buf->dodagid)) { return; } } if (rpl_opt_solicited_buf->VID_Flags & RPL_DIS_V_MASK) { if (my_dodag->version != rpl_opt_solicited_buf->version) { return; } } break; } default: return; } } rpl_send_DIO(&ipv6_buf->srcaddr); }