50 #include "net/rpl/rpl-private.h"
52 #define DEBUG DEBUG_NONE
59 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
60 #define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len])
61 #define UIP_HBHO_BUF ((struct uip_hbho_hdr *)&uip_buf[uip_l2_l3_hdr_len])
62 #define UIP_HBHO_NEXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len + RPL_HOP_BY_HOP_LEN])
63 #define UIP_EXT_HDR_OPT_BUF ((struct uip_ext_hdr_opt *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
64 #define UIP_EXT_HDR_OPT_PADN_BUF ((struct uip_ext_hdr_opt_padn *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
65 #define UIP_EXT_HDR_OPT_RPL_BUF ((struct uip_ext_hdr_opt_rpl *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
71 rpl_instance_t *instance;
74 uint8_t sender_closer;
77 if(UIP_HBHO_BUF->len != RPL_HOP_BY_HOP_LEN - 8) {
78 PRINTF(
"RPL: Hop-by-hop extension header has wrong size\n");
82 if(UIP_EXT_HDR_OPT_RPL_BUF->opt_type != UIP_EXT_HDR_OPT_RPL) {
83 PRINTF(
"RPL: Non RPL Hop-by-hop option\n");
87 if(UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
88 PRINTF(
"RPL: Bad header option! (wrong length)\n");
92 instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance);
93 if(instance ==
NULL) {
94 PRINTF(
"RPL: Unknown instance: %u\n",
95 UIP_EXT_HDR_OPT_RPL_BUF->instance);
99 if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_FWD_ERR) {
100 PRINTF(
"RPL: Forward error!\n");
105 route = uip_ds6_route_lookup(&
UIP_IP_BUF->destipaddr);
107 uip_ds6_route_rm(route);
113 PRINTF(
"RPL: initiate global repair\n");
114 rpl_repair_root(instance->instance_id);
119 UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_FWD_ERR;
123 if(!instance->current_dag->joined) {
124 PRINTF(
"RPL: No DAG in the instance\n");
129 if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN) {
133 sender_rank =
UIP_HTONS(UIP_EXT_HDR_OPT_RPL_BUF->senderrank);
134 sender_closer = sender_rank < instance->current_dag->rank;
136 PRINTF(
"RPL: Packet going %s, sender closer %d (%d < %d)\n", down == 1 ?
"down" :
"up",
139 instance->current_dag->rank
142 if((down && !sender_closer) || (!down && sender_closer)) {
143 PRINTF(
"RPL: Loop detected - senderrank: %d my-rank: %d sender_closer: %d\n",
144 sender_rank, instance->current_dag->rank,
146 if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_RANK_ERR) {
147 PRINTF(
"RPL: Rank error signalled in RPL option!\n");
149 rpl_reset_dio_timer(instance);
153 PRINTF(
"RPL: Single error tolerated\n");
154 UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_RANK_ERR;
158 PRINTF(
"RPL: Rank OK\n");
164 set_rpl_opt(
unsigned uip_ext_opt_offset)
168 memmove(UIP_HBHO_NEXT_BUF, UIP_EXT_BUF,
uip_len - UIP_IPH_LEN);
169 memset(UIP_HBHO_BUF, 0, RPL_HOP_BY_HOP_LEN);
172 UIP_HBHO_BUF->len = RPL_HOP_BY_HOP_LEN - 8;
173 UIP_EXT_HDR_OPT_RPL_BUF->opt_type = UIP_EXT_HDR_OPT_RPL;
174 UIP_EXT_HDR_OPT_RPL_BUF->opt_len = RPL_HDR_OPT_LEN;
175 UIP_EXT_HDR_OPT_RPL_BUF->flags = 0;
176 UIP_EXT_HDR_OPT_RPL_BUF->instance = 0;
177 UIP_EXT_HDR_OPT_RPL_BUF->senderrank = 0;
187 rpl_update_header_empty(
void)
189 rpl_instance_t *instance;
191 int last_uip_ext_len;
195 uip_ext_opt_offset = 2;
197 PRINTF(
"RPL: Verifying the presence of the RPL header option\n");
201 if(UIP_HBHO_BUF->len != RPL_HOP_BY_HOP_LEN - 8) {
202 PRINTF(
"RPL: Hop-by-hop extension header has wrong size\n");
206 if(UIP_EXT_HDR_OPT_RPL_BUF->opt_type != UIP_EXT_HDR_OPT_RPL) {
207 PRINTF(
"RPL: Non RPL Hop-by-hop option support not implemented\n");
211 if(UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
212 PRINTF(
"RPL: RPL Hop-by-hop option has wrong length\n");
216 instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance);
217 if(instance ==
NULL || !instance->used || !instance->current_dag->joined) {
218 PRINTF(
"RPL: Unable to add hop-by-hop extension header: incorrect instance\n");
223 PRINTF(
"RPL: No hop-by-hop option found, creating it\n");
225 PRINTF(
"RPL: Packet too long: impossible to add hop-by-hop option\n");
229 set_rpl_opt(uip_ext_opt_offset);
230 uip_ext_len = last_uip_ext_len + RPL_HOP_BY_HOP_LEN;
234 switch(UIP_EXT_HDR_OPT_BUF->type) {
235 case UIP_EXT_HDR_OPT_RPL:
236 PRINTF(
"RPL: Updating RPL option\n");
237 UIP_EXT_HDR_OPT_RPL_BUF->senderrank =
UIP_HTONS(instance->current_dag->rank);
243 if((UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN)) {
245 UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_FWD_ERR;
246 PRINTF(
"RPL forwarding error\n");
255 UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_DOWN;
256 PRINTF(
"RPL option going up\n");
259 UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_DOWN;
260 PRINTF(
"RPL option going down\n");
267 PRINTF(
"RPL: Multi Hop-by-hop options not implemented\n");
274 rpl_update_header_final(uip_ipaddr_t *addr)
276 rpl_parent_t *parent;
278 int last_uip_ext_len;
282 uip_ext_opt_offset = 2;
285 if(UIP_HBHO_BUF->len != RPL_HOP_BY_HOP_LEN - 8) {
286 PRINTF(
"RPL: Non RPL Hop-by-hop options support not implemented\n");
291 if(UIP_EXT_HDR_OPT_BUF->type == UIP_EXT_HDR_OPT_RPL) {
292 if(UIP_EXT_HDR_OPT_RPL_BUF->senderrank == 0) {
293 PRINTF(
"RPL: Updating RPL option\n");
294 if(default_instance ==
NULL || !default_instance->used || !default_instance->current_dag->joined) {
295 PRINTF(
"RPL: Unable to add hop-by-hop extension header: incorrect default instance\n");
298 parent = rpl_find_parent(default_instance->current_dag, addr);
299 if(parent ==
NULL || parent != parent->dag->preferred_parent) {
300 UIP_EXT_HDR_OPT_RPL_BUF->flags = RPL_HDR_OPT_DOWN;
302 UIP_EXT_HDR_OPT_RPL_BUF->instance = default_instance->instance_id;
303 UIP_EXT_HDR_OPT_RPL_BUF->senderrank =
UIP_HTONS(default_instance->current_dag->rank);
311 rpl_remove_header(
void)
317 PRINTF(
"RPL: Verifying the presence of the RPL header option\n");
320 PRINTF(
"RPL: Removing the RPL header option\n");
323 uip_len -= UIP_HBHO_BUF->len + 8;
328 memmove(UIP_EXT_BUF, UIP_HBHO_NEXT_BUF,
uip_len - UIP_IPH_LEN);
331 PRINTF(
"RPL: No hop-by-hop Option found\n");
336 rpl_invert_header(
void)
339 uint8_t last_uip_ext_len;
343 uip_ext_opt_offset = 2;
345 PRINTF(
"RPL: Verifying the presence of the RPL header option\n");
350 PRINTF(
"RPL: No hop-by-hop Option found\n");
355 switch (UIP_EXT_HDR_OPT_BUF->type) {
356 case UIP_EXT_HDR_OPT_RPL:
357 PRINTF(
"RPL: Updating RPL option (switching direction)\n");
358 UIP_EXT_HDR_OPT_RPL_BUF->flags &= RPL_HDR_OPT_DOWN;
359 UIP_EXT_HDR_OPT_RPL_BUF->flags ^= RPL_HDR_OPT_DOWN;
360 UIP_EXT_HDR_OPT_RPL_BUF->senderrank =
UIP_HTONS(rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance)->current_dag->rank);
362 return RPL_HOP_BY_HOP_LEN;
364 PRINTF(
"RPL: Multi Hop-by-hop options not implemented\n");
371 rpl_insert_header(
void)
374 rpl_update_header_empty();
uip_len
The length of the packet in the uip_buf buffer.
An entry in the routing table.
#define uip_is_addr_mcast(a)
is address a multicast address, see RFC 3513 a is of type uip_ipaddr_t*
Header file for the uIP TCP/IP stack.
Header for the Contiki/uIP interface.
Network interface and stateless autoconfiguration (RFC 4862)
#define NULL
The null pointer.
#define UIP_BUFSIZE
The size of the uIP packet buffer.
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
#define UIP_IP_BUF
Pointer to IP header.
uint8_t uip_ext_opt_offset
length of the header options read
uint8_t uip_ext_len
The length of the extension headers.
#define UIP_PROTO_HBHO
extension headers types
A set of debugging macros.