Пример #1
0
void init(char *str)
{
    transceiver_command_t tcmd;
    msg_t m;
    uint8_t chan = RADIO_CHANNEL;

    char command;

    int res = sscanf(str, "init %c", &command);

    if (res < 1) {
        printf("Usage: init (r|n)\n");
        printf("\tr\tinitialize as root\n");
        printf("\tn\tinitialize as node router\n");
    }

    uint8_t state;

    if ((command == 'n') || (command == 'r')) {
        printf("INFO: Initialize as %s on address %d\n", ((command == 'n') ? "node" : "root"), id);
        if (!id || (id > 255)) {
            printf("ERROR: address not a valid 8 bit integer\n");
            return;
        }

        state = rpl_init(TRANSCEIVER, id);

        if (state != SIXLOWERROR_SUCCESS) {
            printf("Error initializing RPL\n");
        }
        else {
            puts("6LoWPAN and RPL initialized.");
        }

        if (command == 'r') {
            rpl_init_root();
            is_root = 1;
        }
        else {
            ipv6_iface_set_routing_provider(rpl_get_next_hop);
        }
        int monitor_pid = thread_create(monitor_stack_buffer, MONITOR_STACK_SIZE, PRIORITY_MAIN-2, CREATE_STACKTEST, monitor, "monitor");
        transceiver_register(TRANSCEIVER, monitor_pid);
        ipv6_register_packet_handler(monitor_pid);
        //sixlowpan_lowpan_register(monitor_pid);
    }
    else {
        printf("ERROR: Unknown command '%c'\n", command);
        return;
    }

    /* TODO: check if this works as intended */
    ipv6_addr_t prefix, tmp;
    ipv6_addr_init(&std_addr, 0xABCD, 0xEF12, 0, 0, 0x1034, 0x00FF, 0xFE00, id);
    ipv6_addr_init_prefix(&prefix, &std_addr, 64);
    plist_add(&prefix, 64, NDP_OPT_PI_VLIFETIME_INFINITE, 0, 1, ICMPV6_NDP_OPT_PI_FLAG_AUTONOM);
    ipv6_init_iface_as_router();
    /* add global address */
    ipv6_addr_set_by_eui64(&tmp, &std_addr);
    ipv6_iface_add_addr(&tmp, IPV6_ADDR_TYPE_GLOBAL, NDP_ADDR_STATE_PREFERRED, 0, 0);
            
    /* set channel to 10 */
    tcmd.transceivers = TRANSCEIVER;
    tcmd.data = &chan;
    m.type = SET_CHANNEL;
    m.content.ptr = (void *) &tcmd;

    msg_send_receive(&m, &m, transceiver_pid);
    printf("Channel set to %u\n", RADIO_CHANNEL);

    destiny_init_transport_layer();
    puts("Destiny initialized");
    /* start transceiver watchdog */
}
Пример #2
0
void recv_rtr_adv(void)
{
    int8_t trigger_ns = -1;
    int8_t abro_found = 0;
    int16_t abro_version = 0;    /* later replaced, just to supress warnings */
    ipv6_addr_t abro_addr;

    ipv6_buf = get_ipv6_buf();
    opt_hdr_len = RTR_ADV_LEN;
    rtr_adv_buf = get_rtr_adv_buf(ipv6_ext_hdr_len);
    ipv6_addr_t newaddr;
    recvd_cids_len = 0;

    /* update interface reachable time and retrans timer */
    if (rtr_adv_buf->reachable_time != 0) {
        iface.adv_reachable_time = HTONL(rtr_adv_buf->reachable_time);
    }

    if (rtr_adv_buf->retrans_timer != 0) {
        iface.adv_retrans_timer = HTONL(rtr_adv_buf->retrans_timer);
    }

    def_rtr_entry = def_rtr_lst_search(&ipv6_buf->srcaddr);

    if (rtr_adv_buf->router_lifetime != 0) {
        if (def_rtr_entry != NULL) {
            set_remaining_time(&(def_rtr_entry->inval_time), HTONL(rtr_adv_buf->router_lifetime));
        }
        else {
            def_rtr_lst_add(&(ipv6_buf->srcaddr), HTONL(rtr_adv_buf->router_lifetime));
            trigger_ns = 1;
        }
    }
    else {
        /* remove router from default router list */
        if (def_rtr_entry != NULL) {
            def_rtr_lst_rem(def_rtr_entry);
        }
    }

    mutex_lock(&lowpan_context_mutex);

    /* read options */
    while (packet_length > IPV6HDR_ICMPV6HDR_LEN + opt_hdr_len) {
        opt_buf = get_opt_buf(ipv6_ext_hdr_len, opt_hdr_len);

        switch(opt_buf->type) {
            case (OPT_SLLAO_TYPE): {
                break;
            }

            case (OPT_MTU_TYPE): {
                break;
            }

            /* rfc 4862 section 5.5.3 */
            case (OPT_PI_TYPE): {
                opt_pi_buf = get_opt_pi_buf(ipv6_ext_hdr_len, opt_hdr_len);

                /* crazy condition, read 5.5.3a-b-c for further information */
                if (ipv6_prefix_ll_match(&opt_pi_buf->addr) ||
                   (HTONL(opt_pi_buf->pref_ltime) >
                    HTONL(opt_pi_buf->val_ltime))) {
                    break;
                }
                else {
                    /* check if on-link flag is set */
                    if (opt_pi_buf->l_a_reserved1 & OPT_PI_FLAG_L) {
                        /* TODO: do on-link pi handling */
                    }

                    if (opt_pi_buf->l_a_reserved1 & OPT_PI_FLAG_A) {
                        addr_list_ptr = ipv6_iface_addr_prefix_eq(&opt_pi_buf->addr);

                        if (addr_list_ptr == NULL) {
                            /* 5.5.3d */
                            if (opt_pi_buf->val_ltime != 0) {
                                /* iid will also be added here */
                                ipv6_init_addr_prefix(&newaddr, &opt_pi_buf->addr);
                                /* add into address list
                                * TODO: duplicate address detection is not
                                *       implementet yet, so all new addresse will
                                *       be added with state PREFFERED */
                                ipv6_iface_add_addr(&newaddr,
                                                    ADDR_STATE_PREFERRED,
                                                    opt_pi_buf->val_ltime,
                                                    opt_pi_buf->pref_ltime,
                                                    ADDR_CONFIGURED_AUTO);
                                printf("INFO: added address to interface\n");
                                trigger_ns = 1;
                            }
                        }
                        else {
                            /* 5.5.3e */
                            set_remaining_time(&(addr_list_ptr->pref_ltime), opt_pi_buf->pref_ltime);

                            /* 7200 = 2hours in seconds */
                            if (HTONL(opt_pi_buf->val_ltime) > 7200 ||
                               HTONL(opt_pi_buf->val_ltime) >
                               get_remaining_time(&(addr_list_ptr->val_ltime))) {
                                set_remaining_time(&(addr_list_ptr->val_ltime), HTONL(opt_pi_buf->val_ltime));
                            }
                            else {
                                /* reset valid lifetime to 2 hours */
                                set_remaining_time(&(addr_list_ptr->val_ltime), 7200);
                            }
                        }
                    }
                }

                /* TODO: save found prefixes */
                break;
            }

            case (OPT_6CO_TYPE): {
                uint8_t comp;
                uint8_t num;

                opt_6co_hdr_buf = get_opt_6co_hdr_buf(ipv6_ext_hdr_len, opt_hdr_len);

                get_opt_6co_flags(&comp, &num, opt_6co_hdr_buf->c_flags);

                ipv6_addr_t prefix;
                memset(&prefix, 0, 16);

                opt_6co_prefix_buf = get_opt_6co_prefix_buf(ipv6_ext_hdr_len, opt_hdr_len + OPT_6CO_HDR_LEN);

                memcpy(&prefix, opt_6co_prefix_buf, opt_6co_hdr_buf->c_length);

                lowpan_context_update(
                    num,
                    &prefix,
                    opt_6co_hdr_buf->c_length,
                    comp,
                    HTONS(opt_6co_hdr_buf->val_ltime)
                );
                recvd_cids[recvd_cids_len] = num;
                recvd_cids_len = (recvd_cids_len + 1) % LOWPAN_CONTEXT_MAX;
                break;
            }

            case (OPT_ABRO_TYPE): {
                opt_abro_buf = get_opt_abro_buf(ipv6_ext_hdr_len, opt_hdr_len);
                abro_found = 1;
                abro_version = HTONS(opt_abro_buf->version);
                memcpy(&(abro_addr), &(opt_abro_buf->addr), sizeof(ipv6_addr_t));
                break;
            }

            default:
                break;
        }

        /* multiplied with 8 because options length is in units of 8 bytes */
        opt_hdr_len += (opt_buf->length * 8);
    }

    if (abro_found) {
        int i;

        for (i = 0; i < recvd_cids_len; i++) {
            abr_add_context(abro_version, &abro_addr, recvd_cids[i]);
        }
    }

    mutex_unlock(&lowpan_context_mutex, 0);

    if (trigger_ns >= 0) {
        /* send ns - draft-ietf-6lowpan-nd-15#section-5.5.1
         *
         * section-10.2.4
         * "Next the 6LN registers that address with one or more of its
         * default routers by sending a unicast NS message with an ARO
         * containing its tentative global IPv6 address to register
         *
         * if new address was configured, set src to newaddr(gp16) */
        init_nbr_sol(&newaddr, &(ipv6_buf->srcaddr), &(ipv6_buf->srcaddr), OPT_SLLAO, OPT_ARO);
#if ENABLE_DEBUG
        printf("INFO: send neighbor solicitation to: ");
        ipv6_print_addr(&(ipv6_buf->destaddr));
#endif
        lowpan_init((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]), (uint8_t *)ipv6_buf);
    }
}