Beispiel #1
0
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);
            }
        }
    }
}
Beispiel #2
0
Datei: rpl.c Projekt: hper/RIOT
void recv_rpl_dis(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 < (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 + 2;
                break;
            }

            case (RPL_OPT_SOLICITED_INFO): {
                len += RPL_OPT_SOLICITED_INFO_LEN + 2;

                /* 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;
        }
    }

    send_DIO(&ipv6_buf->srcaddr);

}