From ba2bf31c202fc7e05c05e95fd43a10633a32c37d Mon Sep 17 00:00:00 2001 From: joxe Date: Thu, 3 Jun 2010 14:49:15 +0000 Subject: [PATCH] changed DAOs to be formatted according to the rpl-08 specification --- core/net/rpl/rpl-icmp6.c | 124 +++++++++++++++++++++++---------------- core/net/rpl/rpl.h | 9 ++- 2 files changed, 79 insertions(+), 54 deletions(-) diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 1423fa507..cd2e403dd 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -33,7 +33,7 @@ * * This file is part of the Contiki operating system. * - * $Id: rpl-icmp6.c,v 1.14 2010/06/02 11:59:51 joxe Exp $ + * $Id: rpl-icmp6.c,v 1.15 2010/06/03 14:49:15 joxe Exp $ */ /** * \file @@ -408,13 +408,20 @@ dao_input(void) uint16_t sequence; uint8_t instance_id; uint32_t lifetime; - uint8_t rank; uint8_t prefixlen; - uint32_t route_tag; + uint8_t flags; + uint8_t subopt_type; uip_ipaddr_t prefix; uip_ds6_route_t *rep; rpl_parent_t *n; + uint8_t buffer_length; int pos; + int len; + int i; + + lifetime = 0; + prefixlen = 0; + /* Destination Advertisement Object */ PRINTF("RPL: Received a DAO from "); @@ -422,45 +429,61 @@ dao_input(void) PRINTF("\n"); buffer = UIP_ICMP_PAYLOAD; + buffer_length = uip_len - uip_l2_l3_icmp_hdr_len; pos = 0; - sequence = (buffer[pos] << 8) | buffer[pos + 1]; - pos += 2; - - rank = (buffer[pos] << 8) | buffer[pos + 1]; - pos += 2; - - /* pos = 4 */ instance_id = buffer[pos++]; - - route_tag = buffer[pos++]; - prefixlen = buffer[pos++]; - /* ignore RRCount for now: rrcount = buffer[pos++]; */ + flags = buffer[pos++]; + /* reserved */ pos++; - /* pos = 8 */ - lifetime = get32(buffer, pos); - pos += 4; + sequence = buffer[pos++]; + /* is the DAGID present ? */ + if(flags & RPL_DAO_D_FLAG) { + /* currently the DAG ID is ignored since we only use global + RPL Instance IDs... */ + pos += 16; + } + + /* handle the target option */ dag = rpl_get_dag(instance_id); if(dag == NULL) { PRINTF("RPL: Ignoring a DAO for a different DAG instance (%u)\n", - instance_id); + instance_id); return; } - if(rank < dag->rank) { - PRINTF("RPL: Incoming DAO rank is %u, my rank is %u\n", - (unsigned)rank, (unsigned)dag->rank); - return; + /* Check if there are any DIO suboptions. */ + i = pos; + for(; i < buffer_length; i += len) { + subopt_type = buffer[i]; + if(subopt_type == RPL_DIO_SUBOPT_PAD1) { + len = 1; + } else { + /* Suboption with a two-byte header + payload */ + len = 2 + buffer[i + 1]; + } + + switch(subopt_type) { + case RPL_DIO_SUBOPT_TARGET: + prefixlen = buffer[i + 3]; + memset(&prefix, 0, sizeof(prefix)); + memcpy(&prefix, buffer + i + 4, prefixlen / CHAR_BIT); + break; + case RPL_DIO_SUBOPT_TRANSIT: + /* path sequence and control ignored */ + lifetime = get32(buffer, i + 4); + /* parent address also ignored */ + break; + } } - memset(&prefix, 0, sizeof(prefix)); - memcpy(&prefix, buffer + pos, prefixlen / CHAR_BIT); - - PRINTF("RPL: DAO rank: %u, lifetime: %lu, prefix length: %u", - (unsigned)rank, (unsigned long)lifetime, (unsigned)prefixlen); + PRINTF("RPL: DAO lifetime: %lu, prefix length: %u", + (unsigned long)lifetime, (unsigned)prefixlen); PRINTF("\n"); + + if(lifetime == ZERO_LIFETIME) { /* No-DAO received; invoke the route purging routine. */ rep = uip_ds6_route_lookup(&prefix); @@ -491,8 +514,7 @@ dao_input(void) PRINTF("RPL: Forwarding DAO to parent "); PRINT6ADDR(&n->addr); PRINTF("\n"); - uip_icmp6_send(&n->addr, ICMP6_RPL, RPL_CODE_DAO, - 14 + (prefixlen / CHAR_BIT)); + uip_icmp6_send(&n->addr, ICMP6_RPL, RPL_CODE_DAO, buffer_length); } } } @@ -509,11 +531,15 @@ dao_output(rpl_parent_t *n, uint32_t lifetime) int pos; /* Destination Advertisement Object */ + if(get_global_addr(&prefix) == 0) { + PRINTF("RPL: No global address set for this node - suppressing DAO\n"); + return; + } if(n == NULL) { dag = rpl_get_dag(RPL_ANY_INSTANCE); if(dag == NULL) { - PRINTF("RPL: Did not join a DAG before receiving DAO\n"); + PRINTF("RPL: Did not join a DAG before sending DAO\n"); return; } } else { @@ -524,35 +550,29 @@ dao_output(rpl_parent_t *n, uint32_t lifetime) ++sequence; pos = 0; - buffer[pos++] = sequence >> 8; + + buffer[pos++] = dag->instance_id; + buffer[pos++] = 0; /* no ack request, no DODAGID */ + buffer[pos++] = 0; /* reserved */ buffer[pos++] = sequence & 0xff; - buffer[pos++] = dag->rank >> 8; - buffer[pos++] = dag->rank & 0xff; - - /* pos = 4 */ - buffer[pos++] = dag->instance_id; - /* Route tag. Unspecified in draft-ietf-roll-rpl-06. */ - buffer[pos++] = 0; - + /* create target subopt */ prefixlen = sizeof(prefix) * CHAR_BIT; + buffer[pos++] = RPL_DIO_SUBOPT_TARGET; + buffer[pos++] = 2 + ((prefixlen + 7) / CHAR_BIT); + buffer[pos++] = 0; /* reserved */ buffer[pos++] = prefixlen; - /* Reverse route count. Not used because reverse routing is unscalable - beyond a few hops. */ - buffer[pos++] = 0; - /* pos = 8 */ - /* DAO Lifetime. */ + memcpy(buffer + pos, &prefix, (prefixlen + 7) / CHAR_BIT); + pos += ((prefixlen + 7) / CHAR_BIT); + + /* create a transit information subopt */ + buffer[pos++] = RPL_DIO_SUBOPT_TRANSIT; + buffer[pos++] = 6; + buffer[pos++] = 0; /* path seq - ignored */ + buffer[pos++] = 0; /* path control - ignored */ set32(buffer, pos, lifetime); pos += 4; - /* pos = 12 or 14 */ - if(get_global_addr(&prefix) == 0) { - PRINTF("RPL: No global address set for this node - suppressing DAO\n"); - return; - } - memcpy(buffer + pos, &prefix, prefixlen / CHAR_BIT); - pos += (prefixlen / CHAR_BIT); - if(n == NULL) { uip_create_linklocal_allnodes_mcast(&addr); } else { diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index 40f1f6440..b16bc31d6 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -30,7 +30,7 @@ * * Author: Joakim Eriksson, Nicolas Tsiftes * - * $Id: rpl.h,v 1.10 2010/06/02 16:55:00 joxe Exp $ + * $Id: rpl.h,v 1.11 2010/06/03 14:49:16 joxe Exp $ */ #ifndef RPL_H @@ -71,7 +71,7 @@ #define RPL_CODE_SEC_DAO 0x82 /* DAO message */ #define RPL_CODE_SEC_DAO_ACK 0x83 /* DAO ACK message */ -/* RPL DIO suboption types */ +/* RPL DIO/DAO suboption types */ #define RPL_DIO_SUBOPT_PAD1 0 /* Pad1 */ #define RPL_DIO_SUBOPT_PADN 1 /* PadN */ #define RPL_DIO_SUBOPT_DAG_MC 2 /* DAG metric container */ @@ -84,6 +84,9 @@ #define RPL_DIO_SUBOPT_OCP 9 /* 5 in the MC document... */ +#define RPL_DAO_K_FLAG 0x80 /* DAO ACK requested */ +#define RPL_DAO_D_FLAG 0x40 /* DODAG ID Present */ + /*---------------------------------------------------------------------------*/ /* Default values for RPL constants and variables. */ @@ -127,6 +130,8 @@ /* Expire DAOs from neighbors that do not respond in this time. (seconds) */ #define DAO_EXPIRATION_TIMEOUT 60 /*---------------------------------------------------------------------------*/ +#define RPL_INSTANCE_LOCAL_FLAG 0x80 +#define RPL_INSTANCE_D_FLAG 0x40 #define RPL_ROUTE_FROM_INTERNAL 0 #define RPL_ROUTE_FROM_UNICAST_DAO 1