void rpl_recv_DAO(void) { #if RPL_DEFAULT_MOP == RPL_MOP_NON_STORING_MODE if (!i_am_root) { DEBUGF("[Error] something went wrong - got a DAO.\n"); return; } #endif ipv6_buf = get_rpl_ipv6_buf(); rpl_dao_buf = get_rpl_dao_buf(); DEBUG("instance %04X ", rpl_dao_buf->rpl_instanceid); DEBUG("sequence %04X\n", rpl_dao_buf->dao_sequence); rpl_dodag_t *my_dodag = rpl_get_joined_dodag(rpl_dao_buf->rpl_instanceid); if (my_dodag == NULL) { DEBUG("[Error] got DAO although not a DODAG\n"); return; } int len = DAO_BASE_LEN; uint8_t increment_seq = 0; 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 + RPL_OPT_LEN); break; } case (RPL_OPT_DAG_METRIC_CONTAINER): { len += (rpl_opt_buf->length + RPL_OPT_LEN); break; } case (RPL_OPT_TARGET): { rpl_opt_target_buf = get_rpl_opt_target_buf(len); if (rpl_opt_target_buf->prefix_length != RPL_DODAG_ID_LEN) { DEBUGF("prefixes are not supported yet\n"); break; } len += (rpl_opt_target_buf->length + RPL_OPT_LEN); rpl_opt_transit_buf = get_rpl_opt_transit_buf(len); if (rpl_opt_transit_buf->type != RPL_OPT_TRANSIT) { DEBUGF("[Error] - no transit information for target option type = %d\n", rpl_opt_transit_buf->type); break; } len += (rpl_opt_transit_buf->length + RPL_OPT_LEN); /* route lifetime seconds = (DAO lifetime) * (Unit Lifetime) */ #if (RPL_DEFAULT_MOP == RPL_MOP_NON_STORING_MODE) && (RPL_MAX_ROUTING_ENTRIES != 0) rpl_add_srh_entry(&rpl_opt_target_buf->target, &rpl_opt_transit_buf->parent, rpl_opt_transit_buf->path_lifetime * my_dodag->lifetime_unit); #elif (RPL_MAX_ROUTING_ENTRIES != 0) DEBUG("Adding routing information: Target: %s, Source: %s, Lifetime: %u\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, &rpl_opt_target_buf->target), ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, &ipv6_buf->srcaddr), (rpl_opt_transit_buf->path_lifetime * my_dodag->lifetime_unit)); rpl_add_routing_entry(&rpl_opt_target_buf->target, &ipv6_buf->srcaddr, rpl_opt_transit_buf->path_lifetime * my_dodag->lifetime_unit); #endif increment_seq = 1; break; } case (RPL_OPT_TRANSIT): { len += (rpl_opt_buf->length + RPL_OPT_LEN); break; } case (RPL_OPT_TARGET_DESC): { len += (rpl_opt_buf->length + RPL_OPT_LEN); break; } default: return; } } #if RPL_DEFAULT_MOP != RPL_MOP_NON_STORING_MODE rpl_send_DAO_ACK(my_dodag, &ipv6_buf->srcaddr); #endif if (increment_seq) { RPL_COUNTER_INCREMENT(my_dodag->dao_seq); rpl_delay_dao(my_dodag); } }
void rpl_recv_DAO_mode(void) { rpl_dodag_t *my_dodag = rpl_get_my_dodag(); if (my_dodag == NULL) { DEBUGF("[Error] got DAO although not a DODAG.\n"); return; } if (!i_am_root) { DEBUGF("[Error] something went wrong - got a DAO.\n"); return; } ipv6_buf = get_rpl_ipv6_buf(); rpl_dao_buf = get_rpl_dao_buf(); int len = DAO_BASE_LEN; uint8_t increment_seq = 0; 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_DAG_METRIC_CONTAINER): { len += rpl_opt_buf->length; break; } case (RPL_OPT_TARGET): { rpl_opt_target_buf = get_rpl_opt_target_buf(len); if (rpl_opt_target_buf->prefix_length != RPL_DODAG_ID_LEN) { DEBUGF("prefixes are not supported yet\n"); break; } len += rpl_opt_target_buf->length; rpl_opt_transit_buf = get_rpl_opt_transit_buf(len); if (rpl_opt_transit_buf->type != RPL_OPT_TRANSIT) { DEBUGF("[Error] - no transit information for target option type = %d\n", rpl_opt_transit_buf->type); break; } len += rpl_opt_transit_buf->length; /* route lifetime seconds = (DAO lifetime) * (Unit Lifetime) */ DEBUGF("Target: %s\n", ipv6_addr_to_str(addr_str_mode, IPV6_MAX_ADDR_STR_LEN, &rpl_opt_target_buf->target)); DEBUGF("Transit: %s\n", ipv6_addr_to_str(addr_str_mode, IPV6_MAX_ADDR_STR_LEN, &rpl_opt_transit_buf->parent)); #if RPL_DEFAULT_MOP == RPL_NON_STORING_MODE rpl_add_srh_entry(&rpl_opt_target_buf->target, &rpl_opt_transit_buf->parent, rpl_opt_transit_buf->path_lifetime * my_dodag->lifetime_unit); #endif increment_seq = 1; break; } case (RPL_OPT_TRANSIT): { len += rpl_opt_buf->length; break; } case (RPL_OPT_TARGET_DESC): { len += rpl_opt_buf->length; break; } default: return; } } if (increment_seq) { RPL_COUNTER_INCREMENT(my_dodag->dao_seq); delay_dao(); } }