void uip_ds6_route_info_callback(uip_nd6_opt_route_info * rio, uip_ip6addr_t * next_hop) { PRINTF("RIO received\n"); //TODO Preferences ? uip_ds6_route_t *found; if((found = uip_ds6_route_lookup(&rio->prefix)) == NULL && rio->rlifetime != 0) { //New route PRINTF("New route received\n"); PRINTF("type=%d, flags=%d, length=%d, lifetime=%"PRIu32", Preflen=%d, prefix=", rio->type, rio->flagsreserved, rio->len, uip_ntohl(rio->rlifetime), rio->preflen); uip_ds6_route_t *new_route; if((new_route = uip_ds6_route_add(&rio->prefix, rio->preflen, next_hop)) == NULL) { PRINTF("error when adding route\n"); } else { PRINTF("Route added\n"); new_route->state.lifetime = uip_ntohl(rio->rlifetime); } } else { PRINTF("Route already exists\n"); if(rio->rlifetime == 0) { uip_ds6_route_rm(found); } else { found->state.lifetime = uip_ntohl(rio->rlifetime); } } }
/*---------------------------------------------------------------------------*/ static void handle_incoming_rerr(void) { struct uaodv_msg_rerr *rm = (struct uaodv_msg_rerr *)uip_appdata; struct uaodv_rt_entry *rt; print_debug("RERR %d.%d.%d.%d -> %d.%d.%d.%d" " unreach=%d.%d.%d.%d seq=%lu\n", uip_ipaddr_to_quad(&BUF->srcipaddr), uip_ipaddr_to_quad(&BUF->destipaddr), uip_ipaddr_to_quad((uip_ipaddr_t *)&rm->unreach[0]), uip_ntohl(rm->unreach[0].seqno)); if(uip_ipaddr_cmp(&rm->unreach[0].addr, &uip_hostaddr)) return; rt = uaodv_rt_lookup_any(&rm->unreach[0].addr); if(rt != NULL && uip_ipaddr_cmp(&rt->nexthop, uip_udp_sender())) { if((rm->flags & UAODV_RERR_UNKNOWN) || rm->unreach[0].seqno == 0 || SCMP32(rt->hseqno, uip_ntohl(rm->unreach[0].seqno)) <= 0) { rt->is_bad = 1; if(rm->flags & UAODV_RERR_UNKNOWN) { rm->flags &= ~UAODV_RERR_UNKNOWN; rm->unreach[0].seqno = uip_htonl(rt->hseqno); } print_debug("RERR rebroadcast\n"); uip_udp_packet_send(bcastconn, rm, sizeof(struct uaodv_msg_rerr)); } } }
/*---------------------------------------------------------------------------*/ struct uaodv_rt_entry * uaodv_rt_add(uip_ipaddr_t *dest, uip_ipaddr_t *nexthop, unsigned hop_count, const uint32_t *seqno) { struct uaodv_rt_entry *e; /* Avoid inserting duplicate entries. */ e = uaodv_rt_lookup_any(dest); if(e != NULL) { list_remove(route_table, e); } else { /* Allocate a new entry or reuse the oldest. */ e = memb_alloc(&route_mem); if(e == NULL) { e = list_chop(route_table); /* Remove oldest entry. */ } } uip_ipaddr_copy(&e->dest, dest); uip_ipaddr_copy(&e->nexthop, nexthop); e->hop_count = hop_count; e->hseqno = uip_ntohl(*seqno); e->is_bad = 0; /* New entry goes first. */ list_push(route_table, e); return e; }
/*---------------------------------------------------------------------------*/ static void tcpip_handler(void) { if(uip_newdata() && (uip_datalen()==48)) { CurrTime = uip_ntohl(((struct ntpformat *)uip_appdata)->seconds) - NTP_EPOCH; StartTime = clock_seconds(); } }
/*---------------------------------------------------------------------------*/ static void tcpip_handler(void) { if(uip_newdata()) { count++; PRINTF("In: [0x%08lx], TTL %u, total %u\n", uip_ntohl((unsigned long) *((uint32_t *)(uip_appdata))), UIP_IP_BUF->ttl, count); } return; }
void time_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { const uint8_t *payload = 0; size_t pay_len = REST.get_request_payload(request, &payload); if (payload && pay_len == 4) { uint32_t time; memcpy(&time, payload, 4); time = uip_ntohl(time); clock_set_seconds(time); REST.set_response_status(response, CHANGED_2_04); } else { REST.set_response_status(response, BAD_REQUEST_4_00); memcpy(buffer, "32 bit Unixzeit in Network-Byte-Order benötigt.", 48); REST.set_response_payload(response, buffer, 48); } }
/*---------------------------------------------------------------------------*/ static void multicast_send(void) { uint32_t id; id = uip_htonl(seq_id); memset(buf, 0, MAX_PAYLOAD_LEN); memcpy(buf, &id, sizeof(seq_id)); PRINTF("Send to: "); PRINT6ADDR(&mcast_conn->ripaddr); PRINTF(" Remote Port %u,", uip_ntohs(mcast_conn->rport)); PRINTF(" (msg=0x%08lx)", (unsigned long)uip_ntohl(*((uint32_t *)buf))); PRINTF(" %lu bytes\n", (unsigned long)sizeof(id)); seq_id++; uip_udp_packet_send(mcast_conn, buf, sizeof(id)); }
/*---------------------------------------------------------------------------*/ void ntp_adjust_time() { struct ntp_msg *pkt; // pointer to incomming packet /* timestamps for offset calculation */ // t1 == ts //#ifdef REMOTE_HOST // variables needed only for NTP unicast mode struct time_spec rects; // t2 struct time_spec xmtts; // t3 //#endif /* REMOTE_HOST */ struct time_spec dstts; // t4 /* timestamp for local clock adjustment */ struct time_spec adjts; if(uip_newdata()) { // get destination (t4) timestamp clock_get_time(&dstts); // check if received packet is complete if((uip_datalen() != NTP_MSGSIZE_NOAUTH) && (uip_datalen() != NTP_MSGSIZE)) { PRINTF("Received malformed NTP packet\n"); return; } pkt = uip_appdata; // check if the server is synchronised /*#if 0 { // change to 1 for strict check if(((pkt->status & LI_ALARM) == LI_ALARM) || (pkt->stratum > NTP_MAXSTRATUM) || (pkt->stratum == 0) || ((pkt->xmttime.int_partl) == (uint32_t) 0)) #else*/ if((pkt->stratum > NTP_MAXSTRATUM) || (pkt->xmttime.int_partl) == (uint32_t) 0) { //#endif PRINTF("Received NTP packet from unsynchronised server\n"); return; } /* Compute adjustment */ if((pkt->status & MODEMASK) == MODE_BROADCAST) { // in broadcast mode compute time from xmt and dst PRINTF("MODE_BROADCAST\n"); // local clock offset THETA = t3 - t4 adjts.sec = (uip_ntohl(pkt->xmttime.int_partl) - JAN_1970) - dstts.sec; adjts.nsec = fractionl_to_nsec(uip_htonl(pkt->xmttime.fractionl)) - dstts.nsec; } #ifdef BROADCAST_MODE // if only NTP broadcast mode supported else { // in broadcast only mode, no other calcualtion is possible PRINTF("Received NTP non-broadcast mode message\n"); return; } #else else { // in client-server mode calculate local clock offset if(ts.sec != (uip_ntohl(pkt->orgtime.int_partl) - JAN_1970)) { PRINTF("Orgtime mismatch between received NTP packet and timestamp sent by us\n"); return; } /* Compute local clock offset THETA = ((t2 - t1) + (t3 - t4)) / 2 * for seconds part */ rects.sec = uip_htonl(pkt->rectime.int_partl) - JAN_1970; xmtts.sec = uip_htonl(pkt->xmttime.int_partl) - JAN_1970; adjts.sec = ((rects.sec - ts.sec) + (xmtts.sec - dstts.sec)) / 2; PRINTF("ts = %ld, rects = %ld, dstts = %ld, xmtts = %ld \n", ts.sec, rects.sec, dstts.sec, xmtts.sec); /* Compute local clock offset for fraction part */ rects.nsec = fractionl_to_nsec(uip_htonl(pkt->rectime.fractionl)); xmtts.nsec = fractionl_to_nsec(uip_htonl(pkt->xmttime.fractionl)); /* Correct fraction parts if seconds are adjacent */ if(adjts.sec == 0) { if(ts.sec < rects.sec) // server received packet in other second ts.nsec -= 1000000000; if(xmtts.sec < dstts.sec) // our client received packet in other second dstts.nsec += 1000000000; } adjts.nsec = ((rects.nsec - ts.nsec) + (xmtts.nsec - dstts.nsec)) / 2; } /* Set our timestamp to zero to avoid processing the same packet more than once */ ts.sec = 0; #endif PRINTF("Local clock offset = %ld sec %ld nsec\n", adjts.sec, adjts.nsec); /* Set or adjust local clock */ if(ABS(adjts.sec) >= ADJUST_THRESHOLD) { PRINTF("Setting the time to xmttime from server\n"); clock_set_time(uip_ntohl(pkt->xmttime.int_partl) - JAN_1970,uip_ntohl(pkt->xmttime.fractionl)); } else { //with ADJUST_THRESHOLD = 0, following code would never be touch PRINTF("Adjusting the time for %ld and %ld\n", adjts.sec, adjts.nsec); clock_adjust_time(&adjts); } }
/*---------------------------------------------------------------------------*/ static void handle_incoming_rrep(void) { struct uaodv_msg_rrep *rm = (struct uaodv_msg_rrep *)uip_appdata; struct uaodv_rt_entry *rt; /* Useless HELLO message? */ if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr)) { #ifdef AODV_RESPOND_TO_HELLOS uint32_t net_seqno; #ifdef CC2420_RADIO int ret = cc2420_check_remote(uip_udp_sender()->u16[1]); if(ret == REMOTE_YES) { print_debug("HELLO drop is remote\n"); return; } else if (ret == REMOTE_NO) { /* Is neigbour, accept it. */ } else if(cc2420_last_rssi < RSSI_THRESHOLD) { print_debug("HELLO drop %d %d\n", cc2420_last_rssi, cc2420_last_correlation); return; } #endif /* Sometimes it helps to send a non-requested RREP in response! */ net_seqno = uip_htonl(my_hseqno); send_rrep(&uip_hostaddr, &BUF->srcipaddr, &BUF->srcipaddr, &net_seqno, 0); #endif return; } print_debug("RREP %d.%d.%d.%d -> %d.%d.%d.%d" " dest=%d.%d.%d.%d seq=%lu hops=%u orig=%d.%d.%d.%d\n", uip_ipaddr_to_quad(&BUF->srcipaddr), uip_ipaddr_to_quad(&BUF->destipaddr), uip_ipaddr_to_quad(&rm->dest_addr), uip_ntohl(rm->dest_seqno), rm->hop_count, uip_ipaddr_to_quad(&rm->orig_addr)); rt = uaodv_rt_lookup(&rm->dest_addr); /* New forward route? */ if(rt == NULL || (SCMP32(uip_ntohl(rm->dest_seqno), rt->hseqno) > 0)) { print_debug("Inserting3\n"); rt = uaodv_rt_add(&rm->dest_addr, uip_udp_sender(), rm->hop_count, &rm->dest_seqno); #ifdef CC2420_RADIO /* This link is ok since he is unicasting back to us! */ cc2420_recv_ok(uip_udp_sender()); print_debug("RREP recv ok %d %d\n", cc2420_last_rssi, cc2420_last_correlation); #endif } else { print_debug("Not inserting\n"); } /* Forward RREP towards originator? */ if(uip_ipaddr_cmp(&rm->orig_addr, &uip_hostaddr)) { print_debug("ROUTE FOUND\n"); if(rm->flags & UAODV_RREP_ACK) { struct uaodv_msg_rrep_ack *ack = (void *)uip_appdata; ack->type = UAODV_RREP_ACK_TYPE; ack->reserved = 0; sendto(uip_udp_sender(), ack, sizeof(*ack)); } } else { rt = uaodv_rt_lookup(&rm->orig_addr); if(rt == NULL) { print_debug("RREP received, but no route back to originator... :-( \n"); return; } if(rm->flags & UAODV_RREP_ACK) { print_debug("RREP with ACK request (ignored)!\n"); /* Don't want any RREP-ACKs in return! */ rm->flags &= ~UAODV_RREP_ACK; } rm->hop_count++; print_debug("Fwd RREP to %d.%d.%d.%d\n", uip_ipaddr_to_quad(&rt->nexthop)); sendto(&rt->nexthop, rm, sizeof(struct uaodv_msg_rrep)); } }
/*---------------------------------------------------------------------------*/ static void handle_incoming_rreq(void) { struct uaodv_msg_rreq *rm = (struct uaodv_msg_rreq *)uip_appdata; uip_ipaddr_t dest_addr, orig_addr; struct uaodv_rt_entry *rt, *fw = NULL; print_debug("RREQ %d.%d.%d.%d -> %d.%d.%d.%d ttl=%u" " orig=%d.%d.%d.%d seq=%lu hops=%u dest=%d.%d.%d.%d seq=%lu\n", uip_ipaddr_to_quad(&BUF->srcipaddr), uip_ipaddr_to_quad(&BUF->destipaddr), BUF->ttl, uip_ipaddr_to_quad(&rm->orig_addr), uip_ntohl(rm->orig_seqno), rm->hop_count, uip_ipaddr_to_quad(&rm->dest_addr), uip_ntohl(rm->dest_seqno)); if(uip_ipaddr_cmp(&rm->orig_addr, &uip_hostaddr)) { return; /* RREQ looped back! */ } #ifdef CC2420_RADIO { int ret = cc2420_check_remote(uip_udp_sender()->u16[1]); if(ret == REMOTE_YES) { print_debug("RREQ drop is remote\n"); return; } else if (ret == REMOTE_NO) { /* Is neigbour, accept it. */ } else if(cc2420_last_rssi < RSSI_THRESHOLD) { print_debug("RREQ drop %d %d\n", cc2420_last_rssi, cc2420_last_correlation); return; } } #endif #ifdef AODV_BAD_HOP_EXTENSION if(uip_len > (sizeof(*rm) + 2)) { struct uaodv_bad_hop_ext *ext = (void *)(uip_appdata + sizeof(*rm)); uint8_t *end = uip_appdata + uip_len; for(; (uint8_t *)ext < end; ext = (void *)((uint8_t *)ext + ext->length + 2)) { uint8_t *eend = (uint8_t *)ext + ext->length; if(eend > end) eend = end; if(ext->type == RREQ_BAD_HOP_EXT) { uip_ipaddr_t *a; for(a = ext->addrs; (uint8_t *)a < eend; a++) { if(uip_ipaddr_cmp(a, &uip_hostaddr)) { print_debug("BAD_HOP drop\n"); return; } } } } } #endif /* AODV_BAD_HOP_EXTENSION */ /* New reverse route? */ rt = uaodv_rt_lookup(&rm->orig_addr); if(rt == NULL || (SCMP32(uip_ntohl(rm->orig_seqno), rt->hseqno) > 0) /* New route. */ || (SCMP32(uip_ntohl(rm->orig_seqno), rt->hseqno) == 0 && rm->hop_count < rt->hop_count)) { /* Better route. */ print_debug("Inserting1\n"); rt = uaodv_rt_add(&rm->orig_addr, uip_udp_sender(), rm->hop_count, &rm->orig_seqno); } /* Check if it is for our address or a fresh route. */ if(uip_ipaddr_cmp(&rm->dest_addr, &uip_hostaddr) || rm->flags & UAODV_RREQ_DESTONLY) { fw = NULL; } else { fw = uaodv_rt_lookup(&rm->dest_addr); if(!(rm->flags & UAODV_RREQ_UNKSEQNO) && fw != NULL && SCMP32(fw->hseqno, uip_ntohl(rm->dest_seqno)) <= 0) { fw = NULL; } } if (fw != NULL) { uint32_t net_seqno; print_debug("RREQ for known route\n"); uip_ipaddr_copy(&dest_addr, &rm->dest_addr); uip_ipaddr_copy(&orig_addr, &rm->orig_addr); net_seqno = uip_htonl(fw->hseqno); send_rrep(&dest_addr, &rt->nexthop, &orig_addr, &net_seqno, fw->hop_count + 1); } else if(uip_ipaddr_cmp(&rm->dest_addr, &uip_hostaddr)) { uint32_t net_seqno; print_debug("RREQ for our address\n"); uip_ipaddr_copy(&dest_addr, &rm->dest_addr); uip_ipaddr_copy(&orig_addr, &rm->orig_addr); my_hseqno++; if(!(rm->flags & UAODV_RREQ_UNKSEQNO) && SCMP32(my_hseqno, uip_ntohl(rm->dest_seqno)) < 0) { print_debug("New my_hseqno %lu\n", my_hseqno); /* We have rebooted. */ my_hseqno = uip_ntohl(rm->dest_seqno) + 1; } net_seqno = uip_htonl(my_hseqno); send_rrep(&dest_addr, &rt->nexthop, &orig_addr, &net_seqno, 0); } else if(BUF->ttl > 1) { int len; /* Have we seen this RREQ before? */ if(fwc_lookup(&rm->orig_addr, &rm->rreq_id)) { print_debug("RREQ cached, not fwd\n"); return; } fwc_add(&rm->orig_addr, &rm->rreq_id); print_debug("RREQ fwd\n"); rm->hop_count++; bcastconn->ttl = BUF->ttl - 1; len = sizeof(struct uaodv_msg_rreq); len += add_rreq_extensions(rm + 1); uip_udp_packet_send(bcastconn, rm, len); } }
/* * Process a Router Advertisement * * - Possible actions when receiving a RA: add router to router list, * recalculate reachable time, update link hop limit, update retrans timer. * - If MTU option: update MTU. * - If SLLAO option: update entry in neighbor cache * - If prefix option: start autoconf, add prefix to prefix list */ void ra_input(void) { PRINTF("Received RA from"); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINTF("to"); PRINT6ADDR(&UIP_IP_BUF->destipaddr); PRINTF("\n"); UIP_STAT(++uip_stat.nd6.recv); #if UIP_CONF_IPV6_CHECKS if((UIP_IP_BUF->ttl != UIP_ND6_HOP_LIMIT) || (!uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr)) || (UIP_ICMP_BUF->icode != 0)) { PRINTF("RA received is bad"); goto discard; } #endif /*UIP_CONF_IPV6_CHECKS */ if(UIP_ND6_RA_BUF->cur_ttl != 0) { uip_ds6_if.cur_hop_limit = UIP_ND6_RA_BUF->cur_ttl; PRINTF("uip_ds6_if.cur_hop_limit %u\n", uip_ds6_if.cur_hop_limit); } if(UIP_ND6_RA_BUF->reachable_time != 0) { if(uip_ds6_if.base_reachable_time != uip_ntohl(UIP_ND6_RA_BUF->reachable_time)) { uip_ds6_if.base_reachable_time = uip_ntohl(UIP_ND6_RA_BUF->reachable_time); uip_ds6_if.reachable_time = uip_ds6_compute_reachable_time(); } } if(UIP_ND6_RA_BUF->retrans_timer != 0) { uip_ds6_if.retrans_timer = uip_ntohl(UIP_ND6_RA_BUF->retrans_timer); } /* Options processing */ nd6_opt_offset = UIP_ND6_RA_LEN; while(uip_l3_icmp_hdr_len + nd6_opt_offset < uip_len) { if(UIP_ND6_OPT_HDR_BUF->len == 0) { PRINTF("RA received is bad"); goto discard; } switch (UIP_ND6_OPT_HDR_BUF->type) { case UIP_ND6_OPT_SLLAO: PRINTF("Processing SLLAO option in RA\n"); nd6_opt_llao = (uint8_t *) UIP_ND6_OPT_HDR_BUF; nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr); if(nbr == NULL) { nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, (uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 1, NBR_STALE); } else { uip_lladdr_t *lladdr = uip_ds6_nbr_get_ll(nbr); if(nbr->state == NBR_INCOMPLETE) { nbr->state = NBR_STALE; } if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], lladdr, UIP_LLADDR_LEN) != 0) { memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN); nbr->state = NBR_STALE; } nbr->isrouter = 1; } break; case UIP_ND6_OPT_MTU: PRINTF("Processing MTU option in RA\n"); uip_ds6_if.link_mtu = uip_ntohl(((uip_nd6_opt_mtu *) UIP_ND6_OPT_HDR_BUF)->mtu); break; case UIP_ND6_OPT_PREFIX_INFO: PRINTF("Processing PREFIX option in RA\n"); nd6_opt_prefix_info = (uip_nd6_opt_prefix_info *) UIP_ND6_OPT_HDR_BUF; if((uip_ntohl(nd6_opt_prefix_info->validlt) >= uip_ntohl(nd6_opt_prefix_info->preferredlt)) && (!uip_is_addr_link_local(&nd6_opt_prefix_info->prefix))) { /* on-link flag related processing */ if(nd6_opt_prefix_info->flagsreserved1 & UIP_ND6_RA_FLAG_ONLINK) { prefix = uip_ds6_prefix_lookup(&nd6_opt_prefix_info->prefix, nd6_opt_prefix_info->preflen); if(prefix == NULL) { if(nd6_opt_prefix_info->validlt != 0) { if(nd6_opt_prefix_info->validlt != UIP_ND6_INFINITE_LIFETIME) { prefix = uip_ds6_prefix_add(&nd6_opt_prefix_info->prefix, nd6_opt_prefix_info->preflen, uip_ntohl(nd6_opt_prefix_info-> validlt)); } else { prefix = uip_ds6_prefix_add(&nd6_opt_prefix_info->prefix, nd6_opt_prefix_info->preflen, 0); } } } else { switch (nd6_opt_prefix_info->validlt) { case 0: uip_ds6_prefix_rm(prefix); break; case UIP_ND6_INFINITE_LIFETIME: prefix->isinfinite = 1; break; default: PRINTF("Updating timer of prefix"); PRINT6ADDR(&prefix->ipaddr); PRINTF("new value %lu\n", uip_ntohl(nd6_opt_prefix_info->validlt)); stimer_set(&prefix->vlifetime, uip_ntohl(nd6_opt_prefix_info->validlt)); prefix->isinfinite = 0; break; } } } /* End of on-link flag related processing */ /* autonomous flag related processing */ if((nd6_opt_prefix_info->flagsreserved1 & UIP_ND6_RA_FLAG_AUTONOMOUS) && (nd6_opt_prefix_info->validlt != 0) && (nd6_opt_prefix_info->preflen == UIP_DEFAULT_PREFIX_LEN)) { uip_ipaddr_copy(&ipaddr, &nd6_opt_prefix_info->prefix); uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); addr = uip_ds6_addr_lookup(&ipaddr); if((addr != NULL) && (addr->type == ADDR_AUTOCONF)) { if(nd6_opt_prefix_info->validlt != UIP_ND6_INFINITE_LIFETIME) { /* The processing below is defined in RFC4862 section 5.5.3 e */ if((uip_ntohl(nd6_opt_prefix_info->validlt) > 2 * 60 * 60) || (uip_ntohl(nd6_opt_prefix_info->validlt) > stimer_remaining(&addr->vlifetime))) { PRINTF("Updating timer of address"); PRINT6ADDR(&addr->ipaddr); PRINTF("new value %lu\n", uip_ntohl(nd6_opt_prefix_info->validlt)); stimer_set(&addr->vlifetime, uip_ntohl(nd6_opt_prefix_info->validlt)); } else { stimer_set(&addr->vlifetime, 2 * 60 * 60); PRINTF("Updating timer of address "); PRINT6ADDR(&addr->ipaddr); PRINTF("new value %lu\n", (unsigned long)(2 * 60 * 60)); } addr->isinfinite = 0; } else { addr->isinfinite = 1; } } else { if(uip_ntohl(nd6_opt_prefix_info->validlt) == UIP_ND6_INFINITE_LIFETIME) { uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); } else { uip_ds6_addr_add(&ipaddr, uip_ntohl(nd6_opt_prefix_info->validlt), ADDR_AUTOCONF); } } } /* End of autonomous flag related processing */ } break; default: PRINTF("ND option not supported in RA"); break; } nd6_opt_offset += (UIP_ND6_OPT_HDR_BUF->len << 3); } defrt = uip_ds6_defrt_lookup(&UIP_IP_BUF->srcipaddr); if(UIP_ND6_RA_BUF->router_lifetime != 0) { if(nbr != NULL) { nbr->isrouter = 1; } if(defrt == NULL) { uip_ds6_defrt_add(&UIP_IP_BUF->srcipaddr, (unsigned long)(uip_ntohs(UIP_ND6_RA_BUF->router_lifetime))); } else { stimer_set(&(defrt->lifetime), (unsigned long)(uip_ntohs(UIP_ND6_RA_BUF->router_lifetime))); } } else { if(defrt != NULL) { uip_ds6_defrt_rm(defrt); } } #if UIP_CONF_IPV6_QUEUE_PKT /* If the nbr just became reachable (e.g. it was in NBR_INCOMPLETE state * and we got a SLLAO), check if we had buffered a pkt for it */ /* if((nbr != NULL) && (nbr->queue_buf_len != 0)) { uip_len = nbr->queue_buf_len; memcpy(UIP_IP_BUF, nbr->queue_buf, uip_len); nbr->queue_buf_len = 0; return; }*/ if(nbr != NULL && uip_packetqueue_buflen(&nbr->packethandle) != 0) { uip_len = uip_packetqueue_buflen(&nbr->packethandle); memcpy(UIP_IP_BUF, uip_packetqueue_buf(&nbr->packethandle), uip_len); uip_packetqueue_free(&nbr->packethandle); return; } #endif /*UIP_CONF_IPV6_QUEUE_PKT */ discard: uip_len = 0; return; }