diff --git a/os/net/app-layer/coap/coap.h b/os/net/app-layer/coap/coap.h index 9d88886af..616f67d5c 100644 --- a/os/net/app-layer/coap/coap.h +++ b/os/net/app-layer/coap/coap.h @@ -46,7 +46,7 @@ /* sanity check for configured values */ #define COAP_MAX_PACKET_SIZE (COAP_MAX_HEADER_SIZE + REST_MAX_CHUNK_SIZE) -#if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_IPH_LEN - UIP_UDPH_LEN) +#if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPH_LEN - UIP_UDPH_LEN) #error "UIP_CONF_BUFFER_SIZE too small for REST_MAX_CHUNK_SIZE" #endif diff --git a/os/net/ipv6/multicast/esmrf.c b/os/net/ipv6/multicast/esmrf.c index 2da8da400..adbea25e0 100644 --- a/os/net/ipv6/multicast/esmrf.c +++ b/os/net/ipv6/multicast/esmrf.c @@ -229,7 +229,7 @@ icmp_input() uip_process(UIP_UDP_SEND_CONN); - memcpy(&mcast_buf, uip_buf, uip_len); + memcpy(&mcast_buf, &uip_buf[UIP_LLH_LEN], uip_len); mcast_len = uip_len; /* pass the packet to our uip_process to check if it is allowed to * accept this packet or not */ @@ -239,7 +239,7 @@ icmp_input() uip_process(UIP_DATA); - memcpy(uip_buf, &mcast_buf, mcast_len); + memcpy(&uip_buf[UIP_LLH_LEN], &mcast_buf, mcast_len); uip_len = mcast_len; /* Return the IP of the original Multicast sender */ uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &src_ip); @@ -257,7 +257,7 @@ icmp_input() static void mcast_fwd(void *p) { - memcpy(uip_buf, &mcast_buf, mcast_len); + memcpy(&uip_buf[UIP_LLH_LEN], &mcast_buf, mcast_len); uip_len = mcast_len; UIP_IP_BUF->ttl--; tcpip_output(NULL); @@ -291,7 +291,7 @@ in() parent_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(parent_ipaddr); if(parent_lladdr == NULL) { - PRINTF("ESMRF: NO Parent exist \n"); + PRINTF("ESMRF: No Parent found\n"); UIP_MCAST6_STATS_ADD(mcast_dropped); return UIP_MCAST6_DROP; } @@ -309,6 +309,7 @@ in() if(UIP_IP_BUF->ttl <= 1) { UIP_MCAST6_STATS_ADD(mcast_dropped); + PRINTF("ESMRF: TTL too low\n"); return UIP_MCAST6_DROP; } @@ -350,12 +351,14 @@ in() fwd_delay = fwd_delay * (1 + ((random_rand() >> 11) % fwd_spread)); } - memcpy(&mcast_buf, uip_buf, uip_len); + memcpy(&mcast_buf, &uip_buf[UIP_LLH_LEN], uip_len); mcast_len = uip_len; ctimer_set(&mcast_periodic, fwd_delay, mcast_fwd, NULL); } PRINTF("ESMRF: %u bytes: fwd in %u [%u]\n", uip_len, fwd_delay, fwd_spread); + } else { + PRINTF("ESMRF: Group unknown, dropping\n"); } /* Done with this packet unless we are a member of the mcast group */ diff --git a/os/net/ipv6/multicast/roll-tm.c b/os/net/ipv6/multicast/roll-tm.c index edf86b22b..1d19512d6 100644 --- a/os/net/ipv6/multicast/roll-tm.c +++ b/os/net/ipv6/multicast/roll-tm.c @@ -1321,7 +1321,7 @@ static void out() { - if(uip_len + HBHO_TOTAL_LEN > UIP_BUFSIZE) { + if(uip_len + HBHO_TOTAL_LEN > UIP_BUFSIZE - UIP_LLH_LEN) { PRINTF("ROLL TM: Multicast Out can not add HBHO. Packet too long\n"); goto drop; } diff --git a/os/net/ipv6/multicast/smrf.c b/os/net/ipv6/multicast/smrf.c index 06167f75a..00043d60b 100644 --- a/os/net/ipv6/multicast/smrf.c +++ b/os/net/ipv6/multicast/smrf.c @@ -82,7 +82,7 @@ static uint8_t fwd_spread; static void mcast_fwd(void *p) { - memcpy(uip_buf, &mcast_buf, mcast_len); + memcpy(&uip_buf[UIP_LLH_LEN], &mcast_buf, mcast_len); uip_len = mcast_len; UIP_IP_BUF->ttl--; tcpip_output(NULL); @@ -106,6 +106,7 @@ in() */ d = rpl_get_any_dag(); if(!d) { + PRINTF("SMRF: No DODAG\n"); UIP_MCAST6_STATS_ADD(mcast_dropped); return UIP_MCAST6_DROP; } @@ -115,6 +116,7 @@ in() parent_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(parent_ipaddr); if(parent_lladdr == NULL) { + PRINTF("SMRF: No Parent found\n"); UIP_MCAST6_STATS_ADD(mcast_dropped); return UIP_MCAST6_DROP; } @@ -132,6 +134,7 @@ in() if(UIP_IP_BUF->ttl <= 1) { UIP_MCAST6_STATS_ADD(mcast_dropped); + PRINTF("SMRF: TTL too low\n"); return UIP_MCAST6_DROP; } @@ -173,12 +176,14 @@ in() fwd_delay = fwd_delay * (1 + ((random_rand() >> 11) % fwd_spread)); } - memcpy(&mcast_buf, uip_buf, uip_len); + memcpy(&mcast_buf, &uip_buf[UIP_LLH_LEN], uip_len); mcast_len = uip_len; ctimer_set(&mcast_periodic, fwd_delay, mcast_fwd, NULL); } PRINTF("SMRF: %u bytes: fwd in %u [%u]\n", uip_len, fwd_delay, fwd_spread); + } else { + PRINTF("SMRF: Group unknown, dropping\n"); } /* Done with this packet unless we are a member of the mcast group */ diff --git a/os/net/ipv6/sicslowpan.c b/os/net/ipv6/sicslowpan.c index 4509c3e08..060699e93 100644 --- a/os/net/ipv6/sicslowpan.c +++ b/os/net/ipv6/sicslowpan.c @@ -123,7 +123,7 @@ /* NOTE: In the multiple-reassembly context there is only room for the header / first fragment */ #define SICSLOWPAN_IP_BUF(buf) ((struct uip_ip_hdr *)buf) #define SICSLOWPAN_UDP_BUF(buf) ((struct uip_udp_hdr *)&buf[UIP_IPH_LEN]) -#define SICSLOWPAN_IPPAYLOAD_BUF(buf) (&buf[UIP_LLIPH_LEN]) +#define SICSLOWPAN_IPPAYLOAD_BUF(buf) (&buf[UIP_IPH_LEN]) #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) diff --git a/os/net/ipv6/tcpip.c b/os/net/ipv6/tcpip.c index d6207400b..e096ce44b 100644 --- a/os/net/ipv6/tcpip.c +++ b/os/net/ipv6/tcpip.c @@ -472,12 +472,7 @@ output_fallback(void) #ifdef UIP_FALLBACK_INTERFACE LOG_INFO("fallback: removing ext hdrs & setting proto %d %d\n", uip_ext_len, *((uint8_t *)UIP_IP_BUF + 40)); - if(uip_ext_len > 0) { - uint8_t proto = *((uint8_t *)UIP_IP_BUF + 40); - remove_ext_hdr(); - /* This should be copied from the ext header... */ - UIP_IP_BUF->proto = proto; - } + remove_ext_hdr(); /* Inform the other end that the destination is not reachable. If it's * not informed routes might get lost unexpectedly until there's a need * to send a new packet to the peer */ diff --git a/os/net/ipv6/uip6.c b/os/net/ipv6/uip6.c index 4ae366d2f..72384414a 100644 --- a/os/net/ipv6/uip6.c +++ b/os/net/ipv6/uip6.c @@ -523,6 +523,7 @@ uip_connect(const uip_ipaddr_t *ripaddr, uint16_t rport) void remove_ext_hdr(void) { + int last_uip_ext_len; /* Remove ext header before TCP/UDP processing. */ if(uip_ext_len > 0) { LOG_DBG("Cutting ext-header before processing (extlen: %d, uiplen: %d)\n", @@ -532,15 +533,17 @@ remove_ext_hdr(void) uip_clear_buf(); return; } - memmove(((uint8_t *)UIP_TCP_BUF), (uint8_t *)UIP_TCP_BUF + uip_ext_len, - uip_len - UIP_IPH_LEN - uip_ext_len); + last_uip_ext_len = uip_ext_len; + uip_ext_len = 0; + UIP_IP_BUF->proto = UIP_EXT_BUF->next; + memmove(((uint8_t *)UIP_TCP_BUF), (uint8_t *)UIP_TCP_BUF + last_uip_ext_len, + uip_len - UIP_IPH_LEN - last_uip_ext_len); - uip_len -= uip_ext_len; + uip_len -= last_uip_ext_len; /* Update the IP length. */ UIP_IP_BUF->len[0] = (uip_len - UIP_IPH_LEN) >> 8; UIP_IP_BUF->len[1] = (uip_len - UIP_IPH_LEN) & 0xff; - uip_ext_len = 0; } } /*---------------------------------------------------------------------------*/ @@ -1494,7 +1497,6 @@ uip_process(uint8_t flag) udp_input: remove_ext_hdr(); - UIP_IP_BUF->proto = UIP_PROTO_UDP; LOG_INFO("Receiving UDP packet\n"); @@ -1607,7 +1609,6 @@ uip_process(uint8_t flag) tcp_input: remove_ext_hdr(); - UIP_IP_BUF->proto = UIP_PROTO_TCP; UIP_STAT(++uip_stat.tcp.recv); LOG_INFO("Receiving TCP packet\n"); diff --git a/os/net/ipv6/uipbuf.c b/os/net/ipv6/uipbuf.c index c0f9da4e2..6ccbb99aa 100644 --- a/os/net/ipv6/uipbuf.c +++ b/os/net/ipv6/uipbuf.c @@ -128,6 +128,6 @@ uipbuf_clr_attr_flag(uint16_t flag) uint16_t uipbuf_is_attr_flag(uint16_t flag) { - return (uipbuf_attrs[UIPBUF_ATTR_FLAGS] & flag) > 0; + return (uipbuf_attrs[UIPBUF_ATTR_FLAGS] & flag) == flag; } /*---------------------------------------------------------------------------*/ diff --git a/os/net/ipv6/uipbuf.h b/os/net/ipv6/uipbuf.h index 16b201843..337ffe17f 100644 --- a/os/net/ipv6/uipbuf.h +++ b/os/net/ipv6/uipbuf.h @@ -35,33 +35,106 @@ #include "contiki.h" -/* Get the next header given the buffer - start indicates that this is - start of the IPv6 header - needs to be set to 0 when in an ext hdr */ - +/** + * \brief Get the next IPv6 header. + * \param buffer A pointer to the buffer holding the IPv6 packet + * \param size The size of the data in the buffer + * \param protocol A pointer to a variable where the protocol of the header will be stored + * \param start A flag that indicates if this is expected to be the IPv6 packet header or a later header (Extension header) + * \retval returns address of the starting position of the next header + * + * This function moves to the next header in a IPv6 packet. + */ uint8_t* uipbuf_get_next_header(uint8_t *buffer, uint16_t size, uint8_t *protocol, uint8_t start); -/* Get the final header given the buffer - that is assumed to be at start - of an IPv6 header */ + + +/** + * \brief Get the last IPv6 header. + * \param buffer A pointer to the buffer holding the IPv6 packet + * \param size The size of the data in the buffer + * \param protocol A pointer to a variable where the protocol of the header will be stored + * \retval returns address of the starting position of the next header + * + * This function moves to the last header of the IPv6 packet. + */ uint8_t* uipbuf_get_last_header(uint8_t *buffer, uint16_t size, uint8_t *protocol); -/* Attributes relating to the current packet in uipbuf */ + +/** + * \brief Get the value of the attribute + * \param type The attribute to get the value of + * \retval the value of the attribute + * + * This function gets the value of a specific uipbuf attribute. + */ uint16_t uipbuf_get_attr(uint8_t type); -void uipbuf_set_attr_flag(uint16_t flag); -void uipbuf_clr_attr_flag(uint16_t flag); -uint16_t uipbuf_is_attr_flag(uint16_t flag); + + +/** + * \brief Set the value of the attribute + * \param type The attribute to set the value of + * \param value The value to set + * \retval 0 - indicates failure of setting the value + * \retval 1 - indicates success of setting the value + * + * This function sets the value of a specific uipbuf attribute. + */ int uipbuf_set_attr(uint8_t type, uint16_t value); + +/** + * \brief Set bits in the uipbuf attribute flags. + * \param flag_bits The bits to set in the flag. + * + * This function sets the uipbuf attributes flag of specified bits. + */ +void uipbuf_set_attr_flag(uint16_t flag_bits); + +/** + * \brief Clear bits in the uipbuf attribute flags. + * \param flag_bits The bits to clear in the flag. + * + * This function clears the uipbuf attributes flag of specified bits. + */ +void uipbuf_clr_attr_flag(uint16_t flag_bits); + +/** + * \brief Check if bits in the uipbuf attribute flag are set. + * \param flag_bits The bits to check in the flag. + * + * This function checks if the specified bits are set in the + * uipbuf attributes flag. + */ +uint16_t uipbuf_is_attr_flag(uint16_t flag_bits); + + +/** + * \brief Clear all attributes. + * + * This function clear all attributes in the uipbuf attributes + * including all flags. + */ void uipbuf_clear_attr(void); -/* These flags will be used for being */ +/** + * \brief The bits defined for uipbuf attributes flag. + * + */ +/* Avoid using NHC compression on the packet (6LoWPAN) */ #define UIPBUF_ATTR_FLAGS_6LOWPAN_NO_NHC_COMPRESSION 0x01 +/* Avoid using prefix compression on the packet (6LoWPAN) */ #define UIPBUF_ATTR_FLAGS_6LOWPAN_NO_PREFIX_COMPRESSION 0x02 +/** + * \brief The attributes defined for uipbuf attributes function. + * + */ enum { - UIPBUF_ATTR_LLSEC_LEVEL, - UIPBUF_ATTR_LLSEC_KEY_ID, - UIPBUF_ATTR_INTERFACE_ID, - UIPBUF_ATTR_PHYSICAL_NETWORK_ID, - UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS, - UIPBUF_ATTR_FLAGS, + UIPBUF_ATTR_LLSEC_LEVEL, /**< Control link layer security level. */ + UIPBUF_ATTR_LLSEC_KEY_ID, /**< Control link layer security key ID. */ + UIPBUF_ATTR_INTERFACE_ID, /**< The interface to output packet on */ + UIPBUF_ATTR_PHYSICAL_NETWORK_ID, /**< Physical network ID (mapped to PAN ID)*/ + UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS, /**< MAX transmissions of the packet MAC */ + UIPBUF_ATTR_FLAGS, /**< Flags that can control lower layers. see above. */ UIPBUF_ATTR_MAX }; diff --git a/os/net/rpl-classic/rpl-dag.c b/os/net/rpl-classic/rpl-dag.c index e4f4191b1..aeed6194e 100644 --- a/os/net/rpl-classic/rpl-dag.c +++ b/os/net/rpl-classic/rpl-dag.c @@ -370,6 +370,7 @@ rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id) } if(dag == dag->instance->current_dag) { PRINTF("RPL: Dropping a joined DAG when setting this node as root"); + rpl_set_default_route(instance, NULL); dag->instance->current_dag = NULL; } else { PRINTF("RPL: Dropping a DAG when setting this node as root"); @@ -522,14 +523,16 @@ rpl_set_prefix(rpl_dag_t *dag, uip_ipaddr_t *prefix, unsigned len) dag->prefix_info.length = len; dag->prefix_info.flags = UIP_ND6_RA_FLAG_AUTONOMOUS; PRINTF("RPL: Prefix set - will announce this in DIOs\n"); - /* Autoconfigure an address if this node does not already have an address - with this prefix. Otherwise, update the prefix */ - if(last_len == 0) { - PRINTF("rpl_set_prefix - prefix NULL\n"); - check_prefix(NULL, &dag->prefix_info); - } else { - PRINTF("rpl_set_prefix - prefix NON-NULL\n"); - check_prefix(&last_prefix, &dag->prefix_info); + if(dag->rank != ROOT_RANK(dag->instance)) { + /* Autoconfigure an address if this node does not already have an address + with this prefix. Otherwise, update the prefix */ + if(last_len == 0) { + PRINTF("rpl_set_prefix - prefix NULL\n"); + check_prefix(NULL, &dag->prefix_info); + } else { + PRINTF("rpl_set_prefix - prefix NON-NULL\n"); + check_prefix(&last_prefix, &dag->prefix_info); + } } return 1; } @@ -665,6 +668,10 @@ rpl_free_dag(rpl_dag_t *dag) if(RPL_IS_STORING(dag->instance)) { rpl_remove_routes(dag); } + /* Stop the DAO retransmit timer */ +#if RPL_WITH_DAO_ACK + ctimer_stop(&dag->instance->dao_retransmit_timer); +#endif /* RPL_WITH_DAO_ACK */ /* Remove autoconfigured address */ if((dag->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS)) { @@ -757,22 +764,17 @@ rpl_select_dag(rpl_instance_t *instance, rpl_parent_t *p) old_rank = instance->current_dag->rank; last_parent = instance->current_dag->preferred_parent; - best_dag = instance->current_dag; - if(best_dag->rank != ROOT_RANK(instance)) { - if(rpl_select_parent(p->dag) != NULL) { - if(p->dag != best_dag) { - best_dag = instance->of->best_dag(best_dag, p->dag); - } - } else if(p->dag == best_dag) { - best_dag = NULL; - for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) { - if(dag->used && dag->preferred_parent != NULL && dag->preferred_parent->rank != RPL_INFINITE_RANK) { - if(best_dag == NULL) { - best_dag = dag; - } else { - best_dag = instance->of->best_dag(best_dag, dag); - } - } + if(instance->current_dag->rank != ROOT_RANK(instance)) { + rpl_select_parent(p->dag); + } + + best_dag = NULL; + for(dag = &instance->dag_table[0], end = dag + RPL_MAX_DAG_PER_INSTANCE; dag < end; ++dag) { + if(dag->used && dag->preferred_parent != NULL && dag->preferred_parent->rank != RPL_INFINITE_RANK) { + if(best_dag == NULL) { + best_dag = dag; + } else { + best_dag = instance->of->best_dag(best_dag, dag); } } } @@ -1323,6 +1325,9 @@ rpl_local_repair(rpl_instance_t *instance) /* no downward route anymore */ instance->has_downward_route = 0; +#if RPL_WITH_DAO_ACK + ctimer_stop(&instance->dao_retransmit_timer); +#endif /* RPL_WITH_DAO_ACK */ rpl_reset_dio_timer(instance); if(RPL_IS_STORING(instance)) { diff --git a/os/net/rpl-classic/rpl-ext-header.c b/os/net/rpl-classic/rpl-ext-header.c index 0c1f8076a..083d26741 100644 --- a/os/net/rpl-classic/rpl-ext-header.c +++ b/os/net/rpl-classic/rpl-ext-header.c @@ -408,7 +408,7 @@ insert_srh_header(void) path_len, cmpri, cmpre, ext_len, padding); /* Check if there is enough space to store the extension header */ - if(uip_len + ext_len > UIP_BUFSIZE) { + if(uip_len + ext_len > UIP_BUFSIZE - UIP_LLH_LEN) { PRINTF("RPL: Packet too long: impossible to add source routing header (%u bytes)\n", ext_len); return 0; } @@ -553,7 +553,7 @@ insert_hbh_header(const rpl_instance_t *instance) /* Insert hop-by-hop header */ PRINTF("RPL: Creating hop-by-hop option\n"); - if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE) { + if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE - UIP_LLH_LEN) { PRINTF("RPL: Packet too long: impossible to add hop-by-hop option\n"); uip_ext_len = last_uip_ext_len; return 0; @@ -592,9 +592,11 @@ rpl_ext_header_remove(void) { uint8_t temp_len; uint8_t rpl_ext_hdr_len; + int uip_ext_opt_offset; uint8_t *uip_next_hdr; uip_ext_len = 0; + uip_ext_opt_offset = 2; uip_next_hdr = &UIP_IP_BUF->proto; /* Look for hop-by-hop and routing headers */ @@ -602,17 +604,22 @@ rpl_ext_header_remove(void) switch(*uip_next_hdr) { case UIP_PROTO_HBHO: case UIP_PROTO_ROUTING: - /* Remove hop-by-hop and routing headers */ - *uip_next_hdr = UIP_EXT_BUF->next; - rpl_ext_hdr_len = (UIP_EXT_BUF->len * 8) + 8; - temp_len = UIP_IP_BUF->len[1]; - uip_len -= rpl_ext_hdr_len; - UIP_IP_BUF->len[1] -= rpl_ext_hdr_len; - if(UIP_IP_BUF->len[1] > temp_len) { - UIP_IP_BUF->len[0]--; + if((*uip_next_hdr != UIP_PROTO_HBHO || UIP_EXT_HDR_OPT_RPL_BUF->opt_type == UIP_EXT_HDR_OPT_RPL)) { + /* Remove hop-by-hop and routing headers */ + *uip_next_hdr = UIP_EXT_BUF->next; + rpl_ext_hdr_len = (UIP_EXT_BUF->len * 8) + 8; + temp_len = UIP_IP_BUF->len[1]; + uip_len -= rpl_ext_hdr_len; + UIP_IP_BUF->len[1] -= rpl_ext_hdr_len; + if(UIP_IP_BUF->len[1] > temp_len) { + UIP_IP_BUF->len[0]--; + } + PRINTF("RPL: Removing RPL extension header (type %u, len %u)\n", *uip_next_hdr, rpl_ext_hdr_len); + memmove(UIP_EXT_BUF, ((uint8_t *)UIP_EXT_BUF) + rpl_ext_hdr_len, uip_len - UIP_IPH_LEN); + } else { + uip_next_hdr = &UIP_EXT_BUF->next; + uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; } - PRINTF("RPL: Removing RPL extension header (type %u, len %u)\n", *uip_next_hdr, rpl_ext_hdr_len); - memmove(UIP_EXT_BUF, ((uint8_t *)UIP_EXT_BUF) + rpl_ext_hdr_len, uip_len - UIP_IPH_LEN); break; case UIP_PROTO_DESTO: /* @@ -626,6 +633,7 @@ rpl_ext_header_remove(void) /* Move to next header */ uip_next_hdr = &UIP_EXT_BUF->next; uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; + break; default: return; } diff --git a/os/net/rpl-classic/rpl-icmp6.c b/os/net/rpl-classic/rpl-icmp6.c index 6da3c2656..c5114fd14 100644 --- a/os/net/rpl-classic/rpl-icmp6.c +++ b/os/net/rpl-classic/rpl-icmp6.c @@ -1282,6 +1282,12 @@ dao_ack_input(void) parent = NULL; } + if(instance->current_dag->rank == ROOT_RANK(instance)) { + PRINTF("RPL: DODAG root received a DAO ACK, ignoring it\n"); + uip_clear_buf(); + return; + } + PRINTF("RPL: Received a DAO %s with sequence number %d (%d) and status %d from ", status < 128 ? "ACK" : "NACK", sequence, instance->my_dao_seqno, status); diff --git a/os/net/rpl-classic/rpl-ns.h b/os/net/rpl-classic/rpl-ns.h index f6ae4c2c6..dcc7e584a 100644 --- a/os/net/rpl-classic/rpl-ns.h +++ b/os/net/rpl-classic/rpl-ns.h @@ -56,6 +56,7 @@ typedef struct rpl_ns_node { struct rpl_ns_node *next; uint32_t lifetime; + rpl_dag_t *dag; /* Store only IPv6 link identifiers as all nodes in the DAG share the same prefix */ unsigned char link_identifier[8]; struct rpl_ns_node *parent; diff --git a/os/net/rpl-classic/rpl-private.h b/os/net/rpl-classic/rpl-private.h index f00734821..723154cdd 100644 --- a/os/net/rpl-classic/rpl-private.h +++ b/os/net/rpl-classic/rpl-private.h @@ -199,13 +199,6 @@ #define RPL_ROUTE_FROM_MULTICAST_DAO 2 #define RPL_ROUTE_FROM_DIO 3 -/* Multicast Route Lifetime as a multiple of the lifetime unit */ -#ifdef RPL_CONF_MCAST_LIFETIME -#define RPL_MCAST_LIFETIME RPL_CONF_MCAST_LIFETIME -#else -#define RPL_MCAST_LIFETIME 3 -#endif - /* DIS related */ #define RPL_DIS_SEND 1 diff --git a/os/net/rpl-classic/rpl-timers.c b/os/net/rpl-classic/rpl-timers.c index b89a1258d..7742a5fcc 100644 --- a/os/net/rpl-classic/rpl-timers.c +++ b/os/net/rpl-classic/rpl-timers.c @@ -283,7 +283,7 @@ handle_dao_timer(void *ptr) if(uip_ds6_if.maddr_list[i].isused && uip_is_addr_mcast_global(&uip_ds6_if.maddr_list[i].ipaddr)) { dao_output_target(instance->current_dag->preferred_parent, - &uip_ds6_if.maddr_list[i].ipaddr, RPL_MCAST_LIFETIME); + &uip_ds6_if.maddr_list[i].ipaddr, instance->default_lifetime); } } @@ -293,7 +293,7 @@ handle_dao_timer(void *ptr) /* Don't send if it's also our own address, done that already */ if(uip_ds6_maddr_lookup(&mcast_route->group) == NULL) { dao_output_target(instance->current_dag->preferred_parent, - &mcast_route->group, RPL_MCAST_LIFETIME); + &mcast_route->group, instance->default_lifetime); } mcast_route = list_item_next(mcast_route); } @@ -457,11 +457,29 @@ get_probing_target(rpl_dag_t *dag) return probing_target; } /*---------------------------------------------------------------------------*/ +static rpl_dag_t * +get_next_dag(rpl_instance_t *instance) +{ + rpl_dag_t *dag = NULL; + int new_dag = instance->last_dag; + do { + new_dag++; + if(new_dag >= RPL_MAX_DAG_PER_INSTANCE) { + new_dag = 0; + } + if(instance->dag_table[new_dag].used) { + dag = &instance->dag_table[new_dag]; + } + } while(new_dag != instance->last_dag && dag == NULL); + instance->last_dag = new_dag; + return dag; +} +/*---------------------------------------------------------------------------*/ static void handle_probing_timer(void *ptr) { rpl_instance_t *instance = (rpl_instance_t *)ptr; - rpl_parent_t *probing_target = RPL_PROBING_SELECT_FUNC(instance->current_dag); + rpl_parent_t *probing_target = RPL_PROBING_SELECT_FUNC(get_next_dag(instance)); uip_ipaddr_t *target_ipaddr = rpl_parent_get_ipaddr(probing_target); /* Perform probing */ diff --git a/os/net/rpl-classic/rpl.h b/os/net/rpl-classic/rpl.h index 185bcbef2..2fe9f1dbf 100644 --- a/os/net/rpl-classic/rpl.h +++ b/os/net/rpl-classic/rpl.h @@ -252,6 +252,7 @@ struct rpl_instance { #if RPL_WITH_PROBING struct ctimer probing_timer; rpl_parent_t *urgent_probing_target; + int last_dag; #endif /* RPL_WITH_PROBING */ struct ctimer dio_timer; struct ctimer dao_timer; diff --git a/os/net/rpl-lite/rpl-ext-header.c b/os/net/rpl-lite/rpl-ext-header.c index e71e6c1f6..6031d7eef 100644 --- a/os/net/rpl-lite/rpl-ext-header.c +++ b/os/net/rpl-lite/rpl-ext-header.c @@ -302,7 +302,7 @@ insert_srh_header(void) path_len, cmpri, cmpre, ext_len, padding); /* Check if there is enough space to store the extension header */ - if(uip_len + ext_len > UIP_BUFSIZE) { + if(uip_len + ext_len > UIP_BUFSIZE - UIP_LLH_LEN) { LOG_ERR("packet too long: impossible to add source routing header (%u bytes)\n", ext_len); return 0; } @@ -464,7 +464,7 @@ insert_hbh_header(void) /* Insert hop-by-hop header */ LOG_INFO("creating hop-by-hop option\n"); - if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE) { + if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE - UIP_LLH_LEN) { LOG_ERR("packet too long: impossible to add hop-by-hop option\n"); uip_ext_len = last_uip_ext_len; return 0; @@ -531,9 +531,11 @@ rpl_ext_header_remove(void) { uint8_t temp_len; uint8_t rpl_ext_hdr_len; + int uip_ext_opt_offset; uint8_t *uip_next_hdr; uip_ext_len = 0; + uip_ext_opt_offset = 2; uip_next_hdr = &UIP_IP_BUF->proto; /* Look for hop-by-hop and routing headers */ @@ -541,17 +543,22 @@ rpl_ext_header_remove(void) switch(*uip_next_hdr) { case UIP_PROTO_HBHO: case UIP_PROTO_ROUTING: - /* Remove hop-by-hop and routing headers */ - *uip_next_hdr = UIP_EXT_BUF->next; - rpl_ext_hdr_len = (UIP_EXT_BUF->len * 8) + 8; - temp_len = UIP_IP_BUF->len[1]; - uip_len -= rpl_ext_hdr_len; - UIP_IP_BUF->len[1] -= rpl_ext_hdr_len; - if(UIP_IP_BUF->len[1] > temp_len) { - UIP_IP_BUF->len[0]--; + if((*uip_next_hdr != UIP_PROTO_HBHO || UIP_EXT_HDR_OPT_RPL_BUF->opt_type == UIP_EXT_HDR_OPT_RPL)) { + /* Remove hop-by-hop and routing headers */ + *uip_next_hdr = UIP_EXT_BUF->next; + rpl_ext_hdr_len = (UIP_EXT_BUF->len * 8) + 8; + temp_len = UIP_IP_BUF->len[1]; + uip_len -= rpl_ext_hdr_len; + UIP_IP_BUF->len[1] -= rpl_ext_hdr_len; + if(UIP_IP_BUF->len[1] > temp_len) { + UIP_IP_BUF->len[0]--; + } + LOG_INFO("removing RPL extension header (type %u, len %u)\n", *uip_next_hdr, rpl_ext_hdr_len); + memmove(UIP_EXT_BUF, ((uint8_t *)UIP_EXT_BUF) + rpl_ext_hdr_len, uip_len - UIP_IPH_LEN); + } else { + uip_next_hdr = &UIP_EXT_BUF->next; + uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; } - LOG_INFO("removing RPL extension header (type %u, len %u)\n", *uip_next_hdr, rpl_ext_hdr_len); - memmove(UIP_EXT_BUF, ((uint8_t *)UIP_EXT_BUF) + rpl_ext_hdr_len, uip_len - UIP_IPH_LEN); break; case UIP_PROTO_DESTO: /* @@ -565,6 +572,7 @@ rpl_ext_header_remove(void) /* Move to next header */ uip_next_hdr = &UIP_EXT_BUF->next; uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; + break; default: return; } diff --git a/os/services/ip64/ip64-dhcpc.c b/os/services/ip64/ip64-dhcpc.c index 81d97490d..8e8e286f8 100644 --- a/os/services/ip64/ip64-dhcpc.c +++ b/os/services/ip64/ip64-dhcpc.c @@ -61,7 +61,7 @@ struct dhcp_msg { uint8_t options[312]; }; -#if (UIP_BUFSIZE - UIP_UDPIP_HLEN) < 548 +#if (UIP_BUFSIZE - UIP_LLH_LEN - UIP_UDPIP_HLEN) < 548 #error UIP_CONF_BUFFER_SIZE may be too small to accomodate DHCPv4 packets #error Increase UIP_CONF_BUFFER_SIZE in your project-conf.h, or contiki-conf.h #error A good size is 600 bytes