diff --git a/Makefile.include b/Makefile.include index 631a927fd..19cd9d2a0 100644 --- a/Makefile.include +++ b/Makefile.include @@ -45,7 +45,7 @@ UPPERCASE = _ABCDEFGHIJKLMNOPQRSTUVWXYZ TARGET_UPPERCASE := ${shell echo $(TARGET) | sed 'y!$(LOWERCASE)!$(UPPERCASE)!'} CFLAGS += -DCONTIKI_TARGET_$(TARGET_UPPERCASE) -include $(CONTIKI)/core/net/routing/Makefile.routing +#include $(CONTIKI)/core/net/routing/Makefile.routing include $(CONTIKI)/core/net/rime/Makefile.rime include $(CONTIKI)/core/net/mac/Makefile.mac SYSTEM = process.c procinit.c autostart.c elfloader.c profile.c \ @@ -60,8 +60,8 @@ ifdef UIP_CONF_IPV6 CFLAGS += -DUIP_CONF_IPV6 UIP = uip6.c tcpip.c psock.c uip-udp-packet.c uip-split.c \ resolv.c tcpdump.c uiplib.c - NET += $(UIP) uip-icmp6.c uip-nd6.c uip-nd6-io.c uip-netif.c \ - sicslowpan.c neighbor-attr.c neighbor-info.c + NET += $(UIP) uip-icmp6.c uip-nd6.c \ + sicslowpan.c neighbor-attr.c neighbor-info.c uip-ds6.c else # UIP_CONF_IPV6 UIP = uip.c uiplib.c resolv.c tcpip.c psock.c hc.c uip-split.c uip-fw.c \ uip-fw-drv.c uip_arp.c tcpdump.c uip-neighbor.c uip-udp-packet.c \ diff --git a/core/net/sicslowpan.c b/core/net/sicslowpan.c index 62695ba49..5ad722183 100644 --- a/core/net/sicslowpan.c +++ b/core/net/sicslowpan.c @@ -32,7 +32,7 @@ * * This file is part of the Contiki operating system. * - * $Id: sicslowpan.c,v 1.27 2010/03/12 13:40:13 nvt-se Exp $ + * $Id: sicslowpan.c,v 1.28 2010/03/15 16:41:24 joxe Exp $ */ /** * \file @@ -62,7 +62,7 @@ #include "dev/watchdog.h" #include "net/tcpip.h" #include "net/uip.h" -#include "net/uip-netif.h" +#include "net/uip-ds6.h" #include "net/rime.h" #include "net/sicslowpan.h" #include "net/neighbor-info.h" @@ -753,8 +753,8 @@ uncompress_hdr_hc06(u16_t ip_len) { /* copy prefix from context */ memcpy(&SICSLOWPAN_IP_BUF->srcipaddr, context->prefix, 8); /* infer IID from L2 address */ - uip_netif_addr_autoconf_set(&SICSLOWPAN_IP_BUF->srcipaddr, - (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); + uip_ds6_set_addr_iid(&SICSLOWPAN_IP_BUF->srcipaddr, + (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); break; } /* end context based compression */ @@ -790,8 +790,8 @@ uncompress_hdr_hc06(u16_t ip_len) { /* copy 12 NULL bytes then 8 last bytes from L2 */ memset(&SICSLOWPAN_IP_BUF->srcipaddr.u8[2], 0, 6); /* infer IID from L2 address */ - uip_netif_addr_autoconf_set(&SICSLOWPAN_IP_BUF->srcipaddr, - (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); + uip_ds6_set_addr_iid(&SICSLOWPAN_IP_BUF->srcipaddr, + (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); break; } } @@ -866,8 +866,8 @@ uncompress_hdr_hc06(u16_t ip_len) { case SICSLOWPAN_IPHC_DAM_11: /* 0 bits */ /* unicast address */ memcpy(&SICSLOWPAN_IP_BUF->destipaddr, context->prefix, 8); - uip_netif_addr_autoconf_set(&SICSLOWPAN_IP_BUF->destipaddr, - (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); + uip_ds6_set_addr_iid(&SICSLOWPAN_IP_BUF->destipaddr, + (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); break; } } else { @@ -895,8 +895,8 @@ uncompress_hdr_hc06(u16_t ip_len) { SICSLOWPAN_IP_BUF->destipaddr.u8[0] = 0xfe; SICSLOWPAN_IP_BUF->destipaddr.u8[1] = 0x80; memset(&SICSLOWPAN_IP_BUF->destipaddr.u8[2], 0, 6); - uip_netif_addr_autoconf_set(&SICSLOWPAN_IP_BUF->destipaddr, - (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); + uip_ds6_set_addr_iid(&SICSLOWPAN_IP_BUF->destipaddr, + (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); break; } } @@ -1145,11 +1145,11 @@ uncompress_hdr_hc1(u16_t ip_len) { /* src and dest ip addresses */ uip_ip6addr(&SICSLOWPAN_IP_BUF->srcipaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0); - uip_netif_addr_autoconf_set(&SICSLOWPAN_IP_BUF->srcipaddr, - (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); + uip_sd6_set_addr_iid(&SICSLOWPAN_IP_BUF->srcipaddr, + (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); uip_ip6addr(&SICSLOWPAN_IP_BUF->destipaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0); - uip_netif_addr_autoconf_set(&SICSLOWPAN_IP_BUF->destipaddr, - (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); + uip_sd6_set_addr_iid(&SICSLOWPAN_IP_BUF->destipaddr, + (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); uncomp_hdr_len += UIP_IPH_LEN; diff --git a/core/net/tcpip.c b/core/net/tcpip.c index 21d6a9f54..23e20af89 100644 --- a/core/net/tcpip.c +++ b/core/net/tcpip.c @@ -29,7 +29,7 @@ * This file is part of the Contiki operating system. * * - * $Id: tcpip.c,v 1.24 2010/02/09 12:58:53 adamdunkels Exp $ + * $Id: tcpip.c,v 1.25 2010/03/15 16:41:24 joxe Exp $ */ /** * \file @@ -47,7 +47,7 @@ #if UIP_CONF_IPV6 #include "net/uip-nd6.h" -#include "net/uip-netif.h" +#include "net/uip-ds6.h" #endif #define DEBUG 0 @@ -469,28 +469,23 @@ eventhandler(process_event_t ev, process_data_t data) * check the different timers for neighbor discovery and * stateless autoconfiguration */ - if(data == &uip_nd6_timer_periodic && + /*if(data == &uip_nd6_timer_periodic && etimer_expired(&uip_nd6_timer_periodic)) { uip_nd6_periodic(); tcpip_ipv6_output(); - } - - if(data == &uip_netif_timer_dad && - etimer_expired(&uip_netif_timer_dad)){ - uip_netif_dad(); + }*/ +#if !UIP_CONF_ROUTER + if(data == &uip_ds6_timer_rs && + etimer_expired(&uip_ds6_timer_rs)){ + uip_ds6_send_rs(); tcpip_ipv6_output(); } - - if(data == &uip_netif_timer_rs && - etimer_expired(&uip_netif_timer_rs)){ - uip_netif_send_rs(); +#endif /* !UIP_CONF_ROUTER */ + if(data == &uip_ds6_timer_periodic && + etimer_expired(&uip_ds6_timer_periodic)){ + uip_ds6_periodic(); tcpip_ipv6_output(); } - - if(data == &uip_netif_timer_periodic && - etimer_expired(&uip_netif_timer_periodic)){ - uip_netif_periodic(); - } #endif /* UIP_CONF_IPV6 */ } break; @@ -547,8 +542,8 @@ tcpip_input(void) void tcpip_ipv6_output(void) { - struct uip_nd6_neighbor *nbc = NULL; - struct uip_nd6_defrouter *dr = NULL; + uip_ds6_nbr_t *nbr = NULL; + uip_ipaddr_t* nexthop; if(uip_len == 0) return; @@ -564,55 +559,33 @@ tcpip_ipv6_output(void) return; } if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) { - /*If destination is on link */ - nbc = NULL; - if(uip_nd6_is_addr_onlink(&UIP_IP_BUF->destipaddr)){ - nbc = uip_nd6_nbrcache_lookup(&UIP_IP_BUF->destipaddr); + /* Next hop determination */ + nbr = NULL; + if(uip_ds6_is_addr_onlink(&UIP_IP_BUF->destipaddr)){ + nexthop = &UIP_IP_BUF->destipaddr; } else { -#if UIP_CONF_ROUTER - /*destination is not on link*/ - uip_ipaddr_t ipaddr; - uip_ipaddr_t *next_hop; - - /* Try to find the next hop address in the local routing table. */ - next_hop = uip_router != NULL ? - uip_router->lookup(&UIP_IP_BUF->destipaddr, &ipaddr) : NULL; - if(next_hop != NULL) { - /* Look for the next hop of the route in the neighbor cache. - Add a cache entry if we can't find it. */ - nbc = uip_nd6_nbrcache_lookup(next_hop); - if(nbc == NULL) { - nbc = uip_nd6_nbrcache_add(next_hop, NULL, 1, NO_STATE); - } - } else { -#endif /* UIP_CONF_ROUTER */ - /* No route found, check if a default router exists and use it then. */ - dr = uip_nd6_choose_defrouter(); - if(dr != NULL){ - nbc = dr->nb; - } else { - /* shall we send a icmp error message destination unreachable ?*/ - UIP_LOG("tcpip_ipv6_output: Destination off-link but no router"); + uip_ds6_route_t* locrt; + locrt = uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr); + if(locrt == NULL) { + if((nexthop = uip_ds6_defrt_choose()) == NULL) { + PRINTF("tcpip_ipv6_output: Destination off-link but no route\n"); uip_len = 0; return; } -#if UIP_CONF_ROUTER - } -#endif /* UIP_CONF_ROUTER */ - } - /* there are two cases where the entry logically does not exist: - * 1 it really does not exist. 2 it is in the NO_STATE state */ - if (nbc == NULL || nbc->state == NO_STATE) { - if (nbc == NULL) { - /* create neighbor cache entry, original packet is replaced by NS*/ - nbc = uip_nd6_nbrcache_add(&UIP_IP_BUF->destipaddr, NULL, 0, INCOMPLETE); } else { - nbc->state = INCOMPLETE; + nexthop = &locrt->nexthop; } + } + /* end of next hop determination */ + if((nbr = uip_ds6_nbr_lookup(nexthop)) == NULL) { + if((nbr = uip_ds6_nbr_add(nexthop, NULL, 0, NBR_INCOMPLETE)) == NULL) { + uip_len = 0; + return; + } else { #if UIP_CONF_IPV6_QUEUE_PKT - /* copy outgoing pkt in the queuing buffer for later transmmit */ - memcpy(nbc->queue_buf, UIP_IP_BUF, uip_len); - nbc->queue_buf_len = uip_len; + /* copy outgoing pkt in the queuing buffer for later transmmit */ + memcpy(nbr->queue_buf, UIP_IP_BUF, uip_len); + nbr->queue_buf_len = uip_len; #endif /* RFC4861, 7.2.2: * "If the source address of the packet prompting the solicitation is the @@ -620,23 +593,23 @@ tcpip_ipv6_output(void) * address SHOULD be placed in the IP Source Address of the outgoing * solicitation. Otherwise, any one of the addresses assigned to the * interface should be used."*/ - if(uip_netif_is_addr_my_unicast(&UIP_IP_BUF->srcipaddr)){ - uip_nd6_io_ns_output(&UIP_IP_BUF->srcipaddr, NULL, &nbc->ipaddr); - } else { - uip_nd6_io_ns_output(NULL, NULL, &nbc->ipaddr); - } + if(uip_ds6_is_my_addr(&UIP_IP_BUF->srcipaddr)){ + uip_nd6_ns_output(&UIP_IP_BUF->srcipaddr, NULL, &nbr->ipaddr); + } else { + uip_nd6_ns_output(NULL, NULL, &nbr->ipaddr); + } - stimer_set(&(nbc->last_send), - uip_netif_physical_if.retrans_timer / 1000); - nbc->count_send = 1; + stimer_set(&(nbr->sendns), uip_ds6_if.retrans_timer / 1000); + nbr->nscount = 1; + } } else { - if (nbc->state == INCOMPLETE){ - PRINTF("tcpip_ipv6_output: neighbor cache entry incomplete\n"); + if (nbr->state == NBR_INCOMPLETE){ + PRINTF("tcpip_ipv6_output: nbr cache entry incomplete\n"); #if UIP_CONF_IPV6_QUEUE_PKT /* copy outgoing pkt in the queuing buffer for later transmmit and set - the destination neighbor to nbc */ - memcpy(nbc->queue_buf, UIP_IP_BUF, uip_len); - nbc->queue_buf_len = uip_len; + the destination nbr to nbr */ + memcpy(nbr->queue_buf, UIP_IP_BUF, uip_len); + nbr->queue_buf_len = uip_len; uip_len = 0; #endif /*UIP_CONF_IPV6_QUEUE_PKT*/ return; @@ -644,17 +617,18 @@ tcpip_ipv6_output(void) /* if running NUD (nbc->state == STALE, DELAY, or PROBE ) keep sending in parallel see rfc 4861 Node behavior in section 7.7.3*/ - if (nbc->state == STALE){ - nbc->state = DELAY; - stimer_set(&(nbc->reachable), + if (nbr->state == NBR_STALE){ + nbr->state = NBR_DELAY; + stimer_set(&(nbr->reachable), UIP_ND6_DELAY_FIRST_PROBE_TIME); - PRINTF("tcpip_ipv6_output: neighbor cache entry stale moving to delay\n"); + nbr->nscount = 0; + PRINTF("tcpip_ipv6_output: nbr cache entry stale moving to delay\n"); } - stimer_set(&(nbc->last_send), - uip_netif_physical_if.retrans_timer / 1000); + stimer_set(&(nbr->sendns), + uip_ds6_if.retrans_timer / 1000); - tcpip_output(&(nbc->lladdr)); + tcpip_output(&(nbr->lladdr)); #if UIP_CONF_IPV6_QUEUE_PKT @@ -663,11 +637,11 @@ tcpip_ipv6_output(void) * NA after sendiong a NS, you receive a NS with SLLAO: the entry moves *to STALE, and you must both send a NA and the queued packet */ - if(nbc->queue_buf_len != 0) { - uip_len = nbc->queue_buf_len; - memcpy(UIP_IP_BUF, nbc->queue_buf, uip_len); - nbc->queue_buf_len = 0; - tcpip_output(&(nbc->lladdr)); + if(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; + tcpip_output(&(nbr->lladdr)); } #endif /*UIP_CONF_IPV6_QUEUE_PKT*/ diff --git a/core/net/uip-ds6.c b/core/net/uip-ds6.c index 47001ebba..929d233d4 100755 --- a/core/net/uip-ds6.c +++ b/core/net/uip-ds6.c @@ -6,7 +6,7 @@ /** * \file * IPv6 data structures handling functions - * Comprises part of the Neighbor discovery (RFC 4861) + * Comprises part of the Neighbor discovery (RFC 4861) * and auto configuration (RFC 4862 )state machines * \author Mathilde Durvy * \author Julien Abeille @@ -60,6 +60,7 @@ struct etimer uip_ds6_timer_periodic; /** \brief Timer for maintenance of data structures */ + #if UIP_CONF_ROUTER struct stimer uip_ds6_timer_ra; /** \brief RA timer, to schedule RA sending */ static uint8_t racount; /** \brief number of RA already sent */ @@ -71,54 +72,66 @@ static uint8_t rscount; /** \brief numbe /** \name "DS6" Data structures */ /** @{ */ -uip_ds6_netif uip_ds6_if; /** \brief The single interface */ -uip_ds6_nbr uip_ds6_nbr_cache[UIP_DS6_NBR_NB]; /** \brief Neighor cache */ -uip_ds6_defrt uip_ds6_defrt_list[UIP_DS6_DEFRT_NB]; /** \brief Default rt list */ -uip_ds6_prefix uip_ds6_prefix_list[UIP_DS6_PREFIX_NB]; /** \brief Prefix list */ -uip_ds6_route uip_ds6_routing_table[UIP_DS6_ROUTE_NB]; /** \brief Routing table */ +uip_ds6_netif_t uip_ds6_if; /** \brief The single interface */ +uip_ds6_nbr_t uip_ds6_nbr_cache[UIP_DS6_NBR_NB]; /** \brief Neighor cache */ +uip_ds6_defrt_t uip_ds6_defrt_list[UIP_DS6_DEFRT_NB]; /** \brief Default rt list */ +uip_ds6_prefix_t uip_ds6_prefix_list[UIP_DS6_PREFIX_NB]; /** \brief Prefix list */ +uip_ds6_route_t uip_ds6_routing_table[UIP_DS6_ROUTE_NB]; /** \brief Routing table */ + /** @} */ /* "full" (as opposed to pointer) ip address used in this file, */ -static uip_ipaddr_t loc_fipaddr; +static uip_ipaddr_t loc_fipaddr; /* Pointers used in this file */ -static uip_ipaddr_t* locipaddr; -static uip_ds6_addr* locaddr; -static uip_ds6_maddr* locmaddr; -static uip_ds6_aaddr* locaaddr; -static uip_ds6_prefix* locprefix; -static uip_ds6_nbr* locnbr; -static uip_ds6_defrt* locdefrt; -static uip_ds6_route* locroute; +static uip_ipaddr_t *locipaddr; +static uip_ds6_addr_t *locaddr; +static uip_ds6_maddr_t *locmaddr; +static uip_ds6_aaddr_t *locaaddr; +static uip_ds6_prefix_t *locprefix; +static uip_ds6_nbr_t *locnbr; +static uip_ds6_defrt_t *locdefrt; +static uip_ds6_route_t *locroute; /*---------------------------------------------------------------------------*/ void -uip_ds6_init(void) { +uip_ds6_init(void) +{ PRINTF("Init of IPv6 data structures\n"); - PRINTF("%u neighbors\n%u default routers\n%u prefixes\n%u routes\n%u unicast addresses\n%u multicast addresses\n%u anycast addresses\n", UIP_DS6_NBR_NB, UIP_DS6_DEFRT_NB, UIP_DS6_PREFIX_NB, UIP_DS6_ROUTE_NB, UIP_DS6_ADDR_NB, UIP_DS6_MADDR_NB, UIP_DS6_AADDR_NB); - for(locnbr = uip_ds6_nbr_cache; locnbr < uip_ds6_nbr_cache + UIP_DS6_NBR_NB; locnbr++) { + PRINTF + ("%u neighbors\n%u default routers\n%u prefixes\n%u routes\n%u unicast addresses\n%u multicast addresses\n%u anycast addresses\n", + UIP_DS6_NBR_NB, UIP_DS6_DEFRT_NB, UIP_DS6_PREFIX_NB, UIP_DS6_ROUTE_NB, + UIP_DS6_ADDR_NB, UIP_DS6_MADDR_NB, UIP_DS6_AADDR_NB); + for(locnbr = uip_ds6_nbr_cache; locnbr < uip_ds6_nbr_cache + UIP_DS6_NBR_NB; + locnbr++) { locnbr->isused = 0; } - for(locdefrt = uip_ds6_defrt_list; locdefrt < uip_ds6_defrt_list + UIP_DS6_DEFRT_NB; locdefrt++) { + for(locdefrt = uip_ds6_defrt_list; + locdefrt < uip_ds6_defrt_list + UIP_DS6_DEFRT_NB; locdefrt++) { locdefrt->isused = 0; } - for(locprefix = uip_ds6_prefix_list; locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; locprefix++) { + for(locprefix = uip_ds6_prefix_list; + locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; locprefix++) { locprefix->isused = 0; } - for(locaddr = uip_ds6_if.addr_list; locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) { + for(locaddr = uip_ds6_if.addr_list; + locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) { locaddr->isused = 0; } - for(locmaddr = uip_ds6_if.maddr_list; locmaddr < uip_ds6_if.maddr_list + UIP_DS6_MADDR_NB; locmaddr++) { + for(locmaddr = uip_ds6_if.maddr_list; + locmaddr < uip_ds6_if.maddr_list + UIP_DS6_MADDR_NB; locmaddr++) { locmaddr->isused = 0; } - for(locaaddr = uip_ds6_if.aaddr_list; locaaddr < uip_ds6_if.aaddr_list + UIP_DS6_AADDR_NB; locaaddr++) { + for(locaaddr = uip_ds6_if.aaddr_list; + locaaddr < uip_ds6_if.aaddr_list + UIP_DS6_AADDR_NB; locaaddr++) { locaaddr->isused = 0; } - for(locroute = uip_ds6_routing_table; locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB; locroute++) { + for(locroute = uip_ds6_routing_table; + locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB; locroute++) { locroute->isused = 0; } - - /* Set interface parameters */ + + /* Set interface parameters */ uip_ds6_if.link_mtu = UIP_LINK_MTU; uip_ds6_if.cur_hop_limit = UIP_TTL; uip_ds6_if.base_reachable_time = UIP_ND6_REACHABLE_TIME; @@ -142,10 +155,12 @@ uip_ds6_init(void) { uip_create_linklocal_allrouters_mcast(&loc_fipaddr); uip_ds6_maddr_add(&loc_fipaddr); #if UIP_ND6_SEND_RA - stimer_set(&uip_ds6_timer_ra, 2); /* wait to have a link local IP address */ + stimer_set(&uip_ds6_timer_ra, 2); /* wait to have a link local IP address */ #endif /* UIP_ND6_SEND_RA */ #else /* UIP_CONF_ROUTER */ - etimer_set(&uip_ds6_timer_rs, random_rand()%(UIP_ND6_MAX_RTR_SOLICITATION_DELAY * CLOCK_SECOND)); + etimer_set(&uip_ds6_timer_rs, + random_rand() % (UIP_ND6_MAX_RTR_SOLICITATION_DELAY * + CLOCK_SECOND)); #endif /* UIP_CONF_ROUTER */ etimer_set(&uip_ds6_timer_periodic, UIP_DS6_PERIOD); @@ -155,85 +170,89 @@ uip_ds6_init(void) { /*---------------------------------------------------------------------------*/ void -uip_ds6_periodic(void) { +uip_ds6_periodic(void) +{ /* Periodic processing on unicast addresses */ - for(locaddr = uip_ds6_if.addr_list; locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) { - if(locaddr->isused) { + for(locaddr = uip_ds6_if.addr_list; + locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) { + if(locaddr->isused) { if((!locaddr->isinfinite) && (stimer_expired(&locaddr->vlifetime))) { uip_ds6_addr_rm(locaddr); - } else if ((locaddr->state == ADDR_TENTATIVE) && (locaddr->dadnscount <= uip_ds6_if.maxdadns) && (timer_expired(&locaddr->dadtimer))) { + } else if((locaddr->state == ADDR_TENTATIVE) + && (locaddr->dadnscount <= uip_ds6_if.maxdadns) + && (timer_expired(&locaddr->dadtimer))) { uip_ds6_dad(locaddr); } } } /* Periodic processing on default routers */ - for(locdefrt = uip_ds6_defrt_list; locdefrt < uip_ds6_defrt_list + UIP_DS6_DEFRT_NB; locdefrt++) { + for(locdefrt = uip_ds6_defrt_list; + locdefrt < uip_ds6_defrt_list + UIP_DS6_DEFRT_NB; locdefrt++) { if((locdefrt->isused) && (stimer_expired(&(locdefrt->lifetime)))) { - uip_ds6_defrt_rm(locdefrt); + uip_ds6_defrt_rm(locdefrt); } } #if !UIP_CONF_ROUTER /* Periodic processing on prefixes */ - for(locprefix = uip_ds6_prefix_list; locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; locprefix++) { - if((locprefix->isused) && - (!locprefix->isinfinite) && - (stimer_expired(&(locprefix->vlifetime)))) { + for(locprefix = uip_ds6_prefix_list; + locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; locprefix++) { + if((locprefix->isused) && (!locprefix->isinfinite) + && (stimer_expired(&(locprefix->vlifetime)))) { uip_ds6_prefix_rm(locprefix); } } #endif /* !UIP_CONF_ROUTER */ /* Periodic processing on neighbors */ - for(locnbr = uip_ds6_nbr_cache; locnbr < uip_ds6_nbr_cache + UIP_DS6_NBR_NB; locnbr++) { + for(locnbr = uip_ds6_nbr_cache; locnbr < uip_ds6_nbr_cache + UIP_DS6_NBR_NB; + locnbr++) { if(locnbr->isused) { switch (locnbr->state) { - case NBR_INCOMPLETE: - if(locnbr->nscount >= UIP_ND6_MAX_MULTICAST_SOLICIT) { - uip_ds6_nbr_rm(locnbr); + case NBR_INCOMPLETE: + if(locnbr->nscount >= UIP_ND6_MAX_MULTICAST_SOLICIT) { + uip_ds6_nbr_rm(locnbr); + } else if(stimer_expired(&(locnbr->sendns))) { + locnbr->nscount++; + PRINTF("NBR_INCOMPLETE: NS %u\n", locnbr->nscount); + uip_nd6_ns_output(NULL, NULL, &locnbr->ipaddr); + stimer_set(&(locnbr->sendns), uip_ds6_if.retrans_timer / 1000); + } + break; + case NBR_REACHABLE: + if(stimer_expired(&(locnbr->reachable))) { + PRINTF("REACHABLE: moving to STALE ("); + PRINT6ADDR(&locnbr->ipaddr); + PRINTF(")\n"); + locnbr->state = NBR_STALE; + } + break; + case NBR_DELAY: + if(stimer_expired(&(locnbr->reachable))) { + locnbr->state = NBR_PROBE; + locnbr->nscount = 1; + PRINTF("DELAY: moving to PROBE + NS %u\n", locnbr->nscount); + uip_nd6_ns_output(NULL, &locnbr->ipaddr, &locnbr->ipaddr); + stimer_set(&(locnbr->sendns), uip_ds6_if.retrans_timer / 1000); + } + break; + case NBR_PROBE: + if(locnbr->nscount >= UIP_ND6_MAX_UNICAST_SOLICIT) { + PRINTF("PROBE END \n"); + if((locdefrt = uip_ds6_defrt_lookup(&locnbr->ipaddr)) != NULL) { + uip_ds6_defrt_rm(locdefrt); } - else if(stimer_expired(&(locnbr->sendns))) { - locnbr->nscount++; - PRINTF("NBR_INCOMPLETE: NS %u\n",locnbr->nscount); - uip_nd6_ns_output(NULL, NULL, &locnbr->ipaddr); - stimer_set(&(locnbr->sendns), uip_ds6_if.retrans_timer / 1000); - } - break; - case NBR_REACHABLE: - if(stimer_expired(&(locnbr->reachable))) { - PRINTF("REACHABLE: moving to STALE ("); - PRINT6ADDR(&locnbr->ipaddr); - PRINTF(")\n"); - locnbr->state = NBR_STALE; - } - break; - case NBR_DELAY: - if(stimer_expired(&(locnbr->reachable))) { - locnbr->state = NBR_PROBE; - locnbr->nscount = 1; - PRINTF("DELAY: moving to PROBE + NS %u\n", locnbr->nscount); - uip_nd6_ns_output(NULL, &locnbr->ipaddr, &locnbr->ipaddr); - stimer_set(&(locnbr->sendns), - uip_ds6_if.retrans_timer / 1000); - } - break; - case NBR_PROBE: - if(locnbr->nscount >= UIP_ND6_MAX_UNICAST_SOLICIT) { - PRINTF("PROBE END \n"); - if((locdefrt = uip_ds6_defrt_lookup(&locnbr->ipaddr)) != NULL) { - uip_ds6_defrt_rm(locdefrt); - } - uip_ds6_nbr_rm(locnbr); - } else if(stimer_expired(&(locnbr->sendns))){ - locnbr->nscount++; - PRINTF("PROBE: NS %u\n",locnbr->nscount); - uip_nd6_ns_output(NULL, &locnbr->ipaddr, &locnbr->ipaddr); - stimer_set(&(locnbr->sendns), uip_ds6_if.retrans_timer / 1000); - } - break; - default: - break; + uip_ds6_nbr_rm(locnbr); + } else if(stimer_expired(&(locnbr->sendns))) { + locnbr->nscount++; + PRINTF("PROBE: NS %u\n", locnbr->nscount); + uip_nd6_ns_output(NULL, &locnbr->ipaddr, &locnbr->ipaddr); + stimer_set(&(locnbr->sendns), uip_ds6_if.retrans_timer / 1000); + } + break; + default: + break; } } } @@ -249,11 +268,19 @@ uip_ds6_periodic(void) { } /*---------------------------------------------------------------------------*/ -uint8_t uip_ds6_list_loop(uip_ds6_element* list, uint8_t size, uint16_t elementsize, uip_ipaddr_t* ipaddr, uint8_t ipaddrlen, uip_ds6_element** out_element) { - uip_ds6_element *element; +uint8_t +uip_ds6_list_loop(uip_ds6_element_t * list, uint8_t size, + uint16_t elementsize, uip_ipaddr_t * ipaddr, + uint8_t ipaddrlen, uip_ds6_element_t ** out_element) +{ + uip_ds6_element_t *element; + *out_element = NULL; - for(element = list; element < (uip_ds6_element*)((uint8_t*)list + (size * elementsize)); element = (uip_ds6_element*)((uint8_t*)element + elementsize)) { + for(element = list; + element < + (uip_ds6_element_t *) ((uint8_t *) list + (size * elementsize)); + element = (uip_ds6_element_t *) ((uint8_t *) element + elementsize)) { if(element->isused) { if(uip_ipaddr_prefixcmp(&(element->ipaddr), ipaddr, ipaddrlen)) { *out_element = element; @@ -272,12 +299,17 @@ uint8_t uip_ds6_list_loop(uip_ds6_element* list, uint8_t size, uint16_t elements } /*---------------------------------------------------------------------------*/ -uip_ds6_nbr* -uip_ds6_nbr_add(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr, uint8_t isrouter, uint8_t state) { - if(uip_ds6_list_loop((uip_ds6_element*)uip_ds6_nbr_cache, UIP_DS6_NBR_NB, sizeof(uip_ds6_nbr),ipaddr, 128, (uip_ds6_element**)&locnbr) == FREESPACE) { +uip_ds6_nbr_t * +uip_ds6_nbr_add(uip_ipaddr_t * ipaddr, uip_lladdr_t * lladdr, + uint8_t isrouter, uint8_t state) +{ + if(uip_ds6_list_loop + ((uip_ds6_element_t *) uip_ds6_nbr_cache, UIP_DS6_NBR_NB, + sizeof(uip_ds6_nbr_t), ipaddr, 128, + (uip_ds6_element_t **) & locnbr) == FREESPACE) { locnbr->isused = 1; uip_ipaddr_copy(&(locnbr->ipaddr), ipaddr); - if(lladdr != NULL){ + if(lladdr != NULL) { memcpy(&(locnbr->lladdr), lladdr, UIP_LLADDR_LEN); } else { memset(&(locnbr->lladdr), 0, UIP_LLADDR_LEN); @@ -285,8 +317,8 @@ uip_ds6_nbr_add(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr, uint8_t isrouter, ui locnbr->isrouter = isrouter; locnbr->state = state; /* timers are set separately, for now we put them in expired state */ - stimer_set(&(locnbr->reachable),0); - stimer_set(&(locnbr->sendns),0); + stimer_set(&(locnbr->reachable), 0); + stimer_set(&(locnbr->sendns), 0); locnbr->nscount = 0; PRINTF("Adding neighbor with ip addr"); PRINT6ADDR(ipaddr); @@ -300,30 +332,39 @@ uip_ds6_nbr_add(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr, uint8_t isrouter, ui /*---------------------------------------------------------------------------*/ void -uip_ds6_nbr_rm(uip_ds6_nbr* nbr) { - if(nbr != NULL) { +uip_ds6_nbr_rm(uip_ds6_nbr_t * nbr) +{ + if(nbr != NULL) { nbr->isused = 0; } return; } /*---------------------------------------------------------------------------*/ -uip_ds6_nbr* -uip_ds6_nbr_lookup(uip_ipaddr_t *ipaddr) { - if(uip_ds6_list_loop((uip_ds6_element*)uip_ds6_nbr_cache, UIP_DS6_NBR_NB, sizeof(uip_ds6_nbr) ,ipaddr, 128, (uip_ds6_element**)&locnbr) == FOUND) { +uip_ds6_nbr_t * +uip_ds6_nbr_lookup(uip_ipaddr_t * ipaddr) +{ + if(uip_ds6_list_loop + ((uip_ds6_element_t *) uip_ds6_nbr_cache, UIP_DS6_NBR_NB, + sizeof(uip_ds6_nbr_t), ipaddr, 128, + (uip_ds6_element_t **) & locnbr) == FOUND) { return locnbr; } return NULL; } /*---------------------------------------------------------------------------*/ -uip_ds6_defrt* -uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval) { - if(uip_ds6_list_loop((uip_ds6_element*)uip_ds6_defrt_list, UIP_DS6_DEFRT_NB, sizeof(uip_ds6_defrt),ipaddr, 128, (uip_ds6_element**)&locdefrt) == FREESPACE) { +uip_ds6_defrt_t * +uip_ds6_defrt_add(uip_ipaddr_t * ipaddr, unsigned long interval) +{ + if(uip_ds6_list_loop + ((uip_ds6_element_t *) uip_ds6_defrt_list, UIP_DS6_DEFRT_NB, + sizeof(uip_ds6_defrt_t), ipaddr, 128, + (uip_ds6_element_t **) & locdefrt) == FREESPACE) { locdefrt->isused = 1; uip_ipaddr_copy(&(locdefrt->ipaddr), ipaddr); stimer_set(&(locdefrt->lifetime), interval); - + PRINTF("Adding defrouter with ip addr"); PRINT6ADDR(&locdefrt->ipaddr); PRINTF("\n"); @@ -334,7 +375,8 @@ uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval) { /*---------------------------------------------------------------------------*/ void -uip_ds6_defrt_rm(uip_ds6_defrt* defrt) { +uip_ds6_defrt_rm(uip_ds6_defrt_t * defrt) +{ if(defrt != NULL) { defrt->isused = 0; } @@ -342,21 +384,27 @@ uip_ds6_defrt_rm(uip_ds6_defrt* defrt) { } /*---------------------------------------------------------------------------*/ -uip_ds6_defrt* -uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr) { - if(uip_ds6_list_loop((uip_ds6_element*)uip_ds6_defrt_list, UIP_DS6_DEFRT_NB, sizeof(uip_ds6_defrt),ipaddr, 128, (uip_ds6_element**)&locdefrt) == FOUND) { +uip_ds6_defrt_t * +uip_ds6_defrt_lookup(uip_ipaddr_t * ipaddr) +{ + if(uip_ds6_list_loop + ((uip_ds6_element_t *) uip_ds6_defrt_list, UIP_DS6_DEFRT_NB, + sizeof(uip_ds6_defrt_t), ipaddr, 128, + (uip_ds6_element_t **) & locdefrt) == FOUND) { return locdefrt; } return NULL; } /*---------------------------------------------------------------------------*/ -uip_ipaddr_t* -uip_ds6_defrt_choose() { - uip_ds6_nbr *bestnbr; +uip_ipaddr_t * +uip_ds6_defrt_choose() +{ + uip_ds6_nbr_t *bestnbr; locipaddr = NULL; - for(locdefrt = uip_ds6_defrt_list; locdefrt < uip_ds6_defrt_list + UIP_DS6_DEFRT_NB; locdefrt++) { + for(locdefrt = uip_ds6_defrt_list; + locdefrt < uip_ds6_defrt_list + UIP_DS6_DEFRT_NB; locdefrt++) { if(locdefrt->isused) { PRINTF("Defrt, IP address "); PRINT6ADDR(&locdefrt->ipaddr); @@ -373,16 +421,22 @@ uip_ds6_defrt_choose() { PRINT6ADDR(&locdefrt->ipaddr); PRINTF("\n"); } - } - } + } + } return locipaddr; } #if UIP_CONF_ROUTER /*---------------------------------------------------------------------------*/ -uip_ds6_prefix* -uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen, uint8_t advertise, uint8_t flags, unsigned long vtime, unsigned long ptime) { - if(uip_ds6_list_loop((uip_ds6_element*)uip_ds6_prefix_list, UIP_DS6_PREFIX_NB, sizeof(uip_ds6_prefix), ipaddr, ipaddrlen, (uip_ds6_element**)&locprefix) == FREESPACE) { +uip_ds6_prefix_t * +uip_ds6_prefix_add(uip_ipaddr_t * ipaddr, uint8_t ipaddrlen, + uint8_t advertise, uint8_t flags, unsigned long vtime, + unsigned long ptime) +{ + if(uip_ds6_list_loop + ((uip_ds6_element_t *) uip_ds6_prefix_list, UIP_DS6_PREFIX_NB, + sizeof(uip_ds6_prefix_t), ipaddr, ipaddrlen, + (uip_ds6_element_t **) & locprefix) == FREESPACE) { locprefix->isused = 1; uip_ipaddr_copy(&(locprefix->ipaddr), ipaddr); locprefix->length = ipaddrlen; @@ -392,7 +446,9 @@ uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen, uint8_t advertise, u locprefix->plifetime = ptime; PRINTF("Adding prefix "); PRINT6ADDR(&locprefix->ipaddr); - PRINTF("length %u, flags %x, Valid lifetime %lx, Preffered lifetime %lx\n", ipaddrlen, flags, vtime, ptime); + PRINTF + ("length %u, flags %x, Valid lifetime %lx, Preffered lifetime %lx\n", + ipaddrlen, flags, vtime, ptime); return locprefix; } else { PRINTF("No more space in Prefix list\n"); @@ -402,14 +458,19 @@ uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen, uint8_t advertise, u #else /* UIP_CONF_ROUTER */ -uip_ds6_prefix* -uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen, unsigned long interval){ - if(uip_ds6_list_loop((uip_ds6_element*)uip_ds6_prefix_list, UIP_DS6_PREFIX_NB, sizeof(uip_ds6_prefix), ipaddr, ipaddrlen, (uip_ds6_element**)&locprefix) == FREESPACE) { +uip_ds6_prefix_t * +uip_ds6_prefix_add(uip_ipaddr_t * ipaddr, uint8_t ipaddrlen, + unsigned long interval) +{ + if(uip_ds6_list_loop + ((uip_ds6_element_t *) uip_ds6_prefix_list, UIP_DS6_PREFIX_NB, + sizeof(uip_ds6_prefix_t), ipaddr, ipaddrlen, + (uip_ds6_element_t **) & locprefix) == FREESPACE) { locprefix->isused = 1; uip_ipaddr_copy(&(locprefix->ipaddr), ipaddr); locprefix->length = ipaddrlen; - if(interval != 0){ - stimer_set(&(locprefix->vlifetime),interval); + if(interval != 0) { + stimer_set(&(locprefix->vlifetime), interval); locprefix->isinfinite = 0; } else { locprefix->isinfinite = 1; @@ -425,7 +486,8 @@ uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen, unsigned long interv /*---------------------------------------------------------------------------*/ void -uip_ds6_prefix_rm( uip_ds6_prefix *prefix) { +uip_ds6_prefix_rm(uip_ds6_prefix_t * prefix) +{ if(prefix != NULL) { prefix->isused = 0; } @@ -433,29 +495,42 @@ uip_ds6_prefix_rm( uip_ds6_prefix *prefix) { } /*---------------------------------------------------------------------------*/ -uip_ds6_prefix* -uip_ds6_prefix_lookup(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen) { - if(uip_ds6_list_loop((uip_ds6_element*)uip_ds6_prefix_list, UIP_DS6_PREFIX_NB, sizeof(uip_ds6_prefix), ipaddr, ipaddrlen, (uip_ds6_element**)&locprefix) == FOUND) { +uip_ds6_prefix_t * +uip_ds6_prefix_lookup(uip_ipaddr_t * ipaddr, uint8_t ipaddrlen) +{ + if(uip_ds6_list_loop + ((uip_ds6_element_t *) uip_ds6_prefix_list, UIP_DS6_PREFIX_NB, + sizeof(uip_ds6_prefix_t), ipaddr, ipaddrlen, + (uip_ds6_element_t **) & locprefix) == FOUND) { return locprefix; } return NULL; } /*---------------------------------------------------------------------------*/ -uint8_t uip_ds6_is_addr_onlink(uip_ipaddr_t *ipaddr) { - for(locprefix = uip_ds6_prefix_list; locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; locprefix++) { - if((locprefix->isused) && - (uip_ipaddr_prefixcmp(&locprefix->ipaddr, ipaddr, locprefix->length)) ){ +uint8_t +uip_ds6_is_addr_onlink(uip_ipaddr_t * ipaddr) +{ + for(locprefix = uip_ds6_prefix_list; + locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; locprefix++) { + if((locprefix->isused) + && + (uip_ipaddr_prefixcmp(&locprefix->ipaddr, ipaddr, locprefix->length))) + { return 1; - } + } } return 0; } /*---------------------------------------------------------------------------*/ -uip_ds6_addr* -uip_ds6_addr_add(uip_ipaddr_t *ipaddr, unsigned long vlifetime, uint8_t type) { - if(uip_ds6_list_loop((uip_ds6_element*)uip_ds6_if.addr_list, UIP_DS6_ADDR_NB, sizeof(uip_ds6_addr),ipaddr, 128, (uip_ds6_element**)&locaddr) == FREESPACE) { +uip_ds6_addr_t * +uip_ds6_addr_add(uip_ipaddr_t * ipaddr, unsigned long vlifetime, uint8_t type) +{ + if(uip_ds6_list_loop + ((uip_ds6_element_t *) uip_ds6_if.addr_list, UIP_DS6_ADDR_NB, + sizeof(uip_ds6_addr_t), ipaddr, 128, + (uip_ds6_element_t **) & locaddr) == FREESPACE) { locaddr->isused = 1; uip_ipaddr_copy(&locaddr->ipaddr, ipaddr); locaddr->state = ADDR_TENTATIVE; @@ -466,19 +541,22 @@ uip_ds6_addr_add(uip_ipaddr_t *ipaddr, unsigned long vlifetime, uint8_t type) { locaddr->isinfinite = 0; stimer_set(&(locaddr->vlifetime), vlifetime); } - timer_set(&locaddr->dadtimer, random_rand()%(UIP_ND6_MAX_RTR_SOLICITATION_DELAY * CLOCK_SECOND)); + timer_set(&locaddr->dadtimer, + random_rand() % (UIP_ND6_MAX_RTR_SOLICITATION_DELAY * + CLOCK_SECOND)); locaddr->dadnscount = 0; uip_create_solicited_node(ipaddr, &loc_fipaddr); uip_ds6_maddr_add(&loc_fipaddr); return locaddr; } - return NULL; + return NULL; } /*---------------------------------------------------------------------------*/ -void -uip_ds6_addr_rm(uip_ds6_addr *addr) { - if(addr != NULL) { +void +uip_ds6_addr_rm(uip_ds6_addr_t * addr) +{ + if(addr != NULL) { uip_create_solicited_node(&addr->ipaddr, &loc_fipaddr); if((locmaddr = uip_ds6_maddr_lookup(&loc_fipaddr)) != NULL) { uip_ds6_maddr_rm(locmaddr); @@ -489,28 +567,37 @@ uip_ds6_addr_rm(uip_ds6_addr *addr) { } /*---------------------------------------------------------------------------*/ -uip_ds6_addr* -uip_ds6_addr_lookup(uip_ipaddr_t* ipaddr) { - if(uip_ds6_list_loop((uip_ds6_element*)uip_ds6_if.addr_list, UIP_DS6_ADDR_NB, sizeof(uip_ds6_addr),ipaddr, 128, (uip_ds6_element**)&locaddr) == FOUND) { +uip_ds6_addr_t * +uip_ds6_addr_lookup(uip_ipaddr_t * ipaddr) +{ + if(uip_ds6_list_loop + ((uip_ds6_element_t *) uip_ds6_if.addr_list, UIP_DS6_ADDR_NB, + sizeof(uip_ds6_addr_t), ipaddr, 128, + (uip_ds6_element_t **) & locaddr) == FOUND) { return locaddr; } return NULL; } /*---------------------------------------------------------------------------*/ -uip_ds6_maddr* -uip_ds6_maddr_add(uip_ipaddr_t *ipaddr) { - if(uip_ds6_list_loop((uip_ds6_element*)uip_ds6_if.maddr_list, UIP_DS6_MADDR_NB, sizeof(uip_ds6_maddr),ipaddr, 128, (uip_ds6_element**)&locmaddr) == FREESPACE) { +uip_ds6_maddr_t * +uip_ds6_maddr_add(uip_ipaddr_t * ipaddr) +{ + if(uip_ds6_list_loop + ((uip_ds6_element_t *) uip_ds6_if.maddr_list, UIP_DS6_MADDR_NB, + sizeof(uip_ds6_maddr_t), ipaddr, 128, + (uip_ds6_element_t **) & locmaddr) == FREESPACE) { locmaddr->isused = 1; uip_ipaddr_copy(&locmaddr->ipaddr, ipaddr); return locmaddr; } - return NULL; + return NULL; } /*---------------------------------------------------------------------------*/ -void -uip_ds6_maddr_rm(uip_ds6_maddr *maddr) { +void +uip_ds6_maddr_rm(uip_ds6_maddr_t * maddr) +{ if(maddr != NULL) { maddr->isused = 0; } @@ -518,9 +605,13 @@ uip_ds6_maddr_rm(uip_ds6_maddr *maddr) { } /*---------------------------------------------------------------------------*/ -uip_ds6_maddr* -uip_ds6_maddr_lookup(uip_ipaddr_t* ipaddr) { - if(uip_ds6_list_loop((uip_ds6_element*)uip_ds6_if.maddr_list, UIP_DS6_MADDR_NB, sizeof(uip_ds6_maddr),ipaddr, 128, (uip_ds6_element**)&locmaddr) == FOUND) { +uip_ds6_maddr_t * +uip_ds6_maddr_lookup(uip_ipaddr_t * ipaddr) +{ + if(uip_ds6_list_loop + ((uip_ds6_element_t *) uip_ds6_if.maddr_list, UIP_DS6_MADDR_NB, + sizeof(uip_ds6_maddr_t), ipaddr, 128, + (uip_ds6_element_t **) & locmaddr) == FOUND) { return locmaddr; } return NULL; @@ -528,19 +619,24 @@ uip_ds6_maddr_lookup(uip_ipaddr_t* ipaddr) { /*---------------------------------------------------------------------------*/ -uip_ds6_aaddr* -uip_ds6_aaddr_add(uip_ipaddr_t *ipaddr) { - if(uip_ds6_list_loop((uip_ds6_element*)uip_ds6_if.aaddr_list, UIP_DS6_AADDR_NB, sizeof(uip_ds6_aaddr),ipaddr, 128, (uip_ds6_element**)&locaaddr) == FREESPACE) { +uip_ds6_aaddr_t * +uip_ds6_aaddr_add(uip_ipaddr_t * ipaddr) +{ + if(uip_ds6_list_loop + ((uip_ds6_element_t *) uip_ds6_if.aaddr_list, UIP_DS6_AADDR_NB, + sizeof(uip_ds6_aaddr_t), ipaddr, 128, + (uip_ds6_element_t **) & locaaddr) == FREESPACE) { locaaddr->isused = 1; uip_ipaddr_copy(&locaaddr->ipaddr, ipaddr); return locaaddr; } - return NULL; + return NULL; } /*---------------------------------------------------------------------------*/ -void -uip_ds6_aaddr_rm(uip_ds6_aaddr *aaddr) { +void +uip_ds6_aaddr_rm(uip_ds6_aaddr_t * aaddr) +{ if(aaddr != NULL) { aaddr->isused = 0; } @@ -548,68 +644,103 @@ uip_ds6_aaddr_rm(uip_ds6_aaddr *aaddr) { } /*---------------------------------------------------------------------------*/ -uip_ds6_aaddr* -uip_ds6_aaddr_lookup(uip_ipaddr_t* ipaddr) { - if(uip_ds6_list_loop((uip_ds6_element*)uip_ds6_if.aaddr_list, UIP_DS6_AADDR_NB, sizeof(uip_ds6_aaddr),ipaddr, 128, (uip_ds6_element**)&locaaddr) == FOUND) { +uip_ds6_aaddr_t * +uip_ds6_aaddr_lookup(uip_ipaddr_t * ipaddr) +{ + if(uip_ds6_list_loop + ((uip_ds6_element_t *) uip_ds6_if.aaddr_list, UIP_DS6_AADDR_NB, + sizeof(uip_ds6_aaddr_t), ipaddr, 128, + (uip_ds6_element_t **) & locaaddr) == FOUND) { return locaaddr; } return NULL; } /*---------------------------------------------------------------------------*/ -uip_ipaddr_t* -uip_ds6_route_lookup(uip_ipaddr_t *destipaddr) { - locipaddr = NULL; +uip_ds6_route_t * +uip_ds6_route_lookup(uip_ipaddr_t * destipaddr) +{ + uip_ds6_route_t *locrt = NULL; uint8_t longestmatch = 0; - for(locroute = uip_ds6_routing_table; locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB; locroute++) { - if((locroute->isused) && - (locroute->length >= longestmatch) && - (uip_ipaddr_prefixcmp(destipaddr, &locroute->ipaddr, locroute->length))) { + PRINTF("DS6: Looking up route for"); + PRINT6ADDR(destipaddr); + PRINTF("\n"); + + for(locroute = uip_ds6_routing_table; + locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB; locroute++) { + if((locroute->isused) && (locroute->length >= longestmatch) + && + (uip_ipaddr_prefixcmp + (destipaddr, &locroute->ipaddr, locroute->length))) { longestmatch = locroute->length; - locipaddr = &locroute->ipaddr; + locrt = locroute; } } - - return locipaddr; + + if(locrt != NULL) { + PRINTF("DS6: Found route:"); + PRINT6ADDR(destipaddr); + PRINTF(" via "); + PRINT6ADDR(&locrt->nexthop); + PRINTF("\n"); + } else { + PRINTF("DS6: No route found ...\n"); + } + + return locrt; } /*---------------------------------------------------------------------------*/ -uip_ds6_route* -uip_ds6_route_add(uip_ipaddr_t *ipaddr, u8_t length, uip_ipaddr_t *nexthop, u8_t metric) { - - if(uip_ds6_list_loop((uip_ds6_element*)uip_ds6_routing_table, UIP_DS6_ROUTE_NB, sizeof(uip_ds6_route), ipaddr, length, (uip_ds6_element**)&locroute) == FREESPACE) { +uip_ds6_route_t * +uip_ds6_route_add(uip_ipaddr_t * ipaddr, u8_t length, uip_ipaddr_t * nexthop, + u8_t metric) +{ + + if(uip_ds6_list_loop + ((uip_ds6_element_t *) uip_ds6_routing_table, UIP_DS6_ROUTE_NB, + sizeof(uip_ds6_route_t), ipaddr, length, + (uip_ds6_element_t **) & locroute) == FREESPACE) { locroute->isused = 1; uip_ipaddr_copy(&(locroute->ipaddr), ipaddr); locroute->length = length; uip_ipaddr_copy(&(locroute->nexthop), nexthop); locroute->metric = metric; + + PRINTF("DS6: adding route:"); + PRINT6ADDR(ipaddr); + PRINTF(" via "); + PRINT6ADDR(nexthop); + PRINTF("\n"); + } - + return locroute; } /*---------------------------------------------------------------------------*/ void -uip_ds6_route_rm(uip_ds6_route* route) { +uip_ds6_route_rm(uip_ds6_route_t * route) +{ route->isused = 0; return; } /*---------------------------------------------------------------------------*/ void -uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst) -{ - uint8_t best = 0; /* number of bit in common with best match*/ +uip_ds6_select_src(uip_ipaddr_t * src, uip_ipaddr_t * dst) +{ + uint8_t best = 0; /* number of bit in common with best match */ uint8_t n = 0; - uip_ds6_addr *matchaddr = uip_ds6_if.addr_list; - + uip_ds6_addr_t *matchaddr = uip_ds6_if.addr_list; + if(!uip_is_addr_link_local(dst) && !uip_is_addr_mcast(dst)) { // find longest match - for(locaddr = uip_ds6_if.addr_list; locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) { - if((locaddr->isused) && (locaddr->state == ADDR_PREFERRED)){ + for(locaddr = uip_ds6_if.addr_list; + locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) { + if((locaddr->isused) && (locaddr->state == ADDR_PREFERRED)) { n = get_match_length(dst, &(locaddr->ipaddr)); - if(n >= best){ + if(n >= best) { best = n; matchaddr = locaddr; } @@ -617,8 +748,10 @@ uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst) } } else { // use link local - for(locaddr = uip_ds6_if.addr_list; locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) { - if((locaddr->isused) && (locaddr->state == ADDR_PREFERRED) && (uip_is_addr_link_local(&locaddr->ipaddr))) { + for(locaddr = uip_ds6_if.addr_list; + locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) { + if((locaddr->isused) && (locaddr->state == ADDR_PREFERRED) + && (uip_is_addr_link_local(&locaddr->ipaddr))) { matchaddr = locaddr; break; } @@ -630,7 +763,9 @@ uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst) } /*---------------------------------------------------------------------------*/ -void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr) { +void +uip_ds6_set_addr_iid(uip_ipaddr_t * ipaddr, uip_lladdr_t * lladdr) +{ /* We consider only links with IEEE EUI-64 identifier or * IEEE 48-bit MAC addresses */ #if (UIP_LLADDR_LEN == 8) @@ -640,36 +775,33 @@ void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr) { memcpy(ipaddr->u8 + 8, lladdr, 3); ipaddr->u8[11] = 0xff; ipaddr->u8[12] = 0xfe; - memcpy(ipaddr->u8 + 13, (uint8_t*)lladdr + 3, 3); + memcpy(ipaddr->u8 + 13, (uint8_t *) lladdr + 3, 3); ipaddr->u8[8] ^= 0x02; #else - PRINTF("CAN NOT BUIL INTERFACE IDENTIFIER"); - PRINTF("THE STACK IS GOING TO SHUT DOWN"); - PRINTF("THE HOST WILL BE UNREACHABLE"); - exit(-1); +#error uip-ds6.c cannot build interface address when UIP_LLADDR_LEN is not 6 or 8 #endif - return; } /*---------------------------------------------------------------------------*/ uint8_t -get_match_length(uip_ipaddr_t *src, uip_ipaddr_t *dst) { +get_match_length(uip_ipaddr_t * src, uip_ipaddr_t * dst) +{ uint8_t j, k, x_or; uint8_t len = 0; - for(j = 0; j < 16; j ++) { + + for(j = 0; j < 16; j++) { if(src->u8[j] == dst->u8[j]) { len += 8; } else { x_or = src->u8[j] ^ dst->u8[j]; - for(k = 0; k < 8; k ++) { - if((x_or & 0x80) == 0){ - len ++; + for(k = 0; k < 8; k++) { + if((x_or & 0x80) == 0) { + len++; x_or <<= 1; - } - else { + } else { break; } - } + } break; } } @@ -678,12 +810,14 @@ get_match_length(uip_ipaddr_t *src, uip_ipaddr_t *dst) { /*---------------------------------------------------------------------------*/ void -uip_ds6_dad(uip_ds6_addr* addr) { +uip_ds6_dad(uip_ds6_addr_t * addr) +{ /* send maxdadns NS for DAD */ if(addr->dadnscount < uip_ds6_if.maxdadns) { uip_nd6_ns_output(NULL, NULL, &addr->ipaddr); addr->dadnscount++; - timer_set(&addr->dadtimer, uip_ds6_if.retrans_timer / 1000 * CLOCK_SECOND); + timer_set(&addr->dadtimer, + uip_ds6_if.retrans_timer / 1000 * CLOCK_SECOND); return; } /* @@ -699,78 +833,89 @@ uip_ds6_dad(uip_ds6_addr* addr) { } /*---------------------------------------------------------------------------*/ -void -uip_ds6_dad_failed(uip_ds6_addr *addr) { +/* + * Calling code must handle when this returns 0 (e.g. link local + * address can not be used). + */ +int +uip_ds6_dad_failed(uip_ds6_addr_t * addr) +{ if(uip_is_addr_link_local(&addr->ipaddr)) { PRINTF("Contiki shutdown, DAD for link local address failed\n"); - exit(-1); + return 0; } uip_ds6_addr_rm(addr); - return; + return 1; } -#if UIP_CONF_ROUTER +#if UIP_CONF_ROUTER #if UIP_ND6_SEND_RA /*---------------------------------------------------------------------------*/ void -uip_ds6_send_ra_sollicited(void) { +uip_ds6_send_ra_sollicited(void) +{ /* We have a pb here: RA timer max possible value is 1800s, * hence we have to use stimers. However, when receiving a RS, we - * should delay the reply by a random value between 0 and 500ms timers. - * stimers are in seconds, hence we cannot do this. Therefore we just send - * the RA (setting the timer to 0 below). We keep the code logic for + * should delay the reply by a random value between 0 and 500ms timers. + * stimers are in seconds, hence we cannot do this. Therefore we just send + * the RA (setting the timer to 0 below). We keep the code logic for * the days contiki will support appropriate timers */ rand_time = 0; - PRINTF("Solicited RA, random time %u\n", rand_time); + PRINTF("Solicited RA, random time %u\n", rand_time); - if (stimer_remaining(&uip_ds6_timer_ra) > rand_time) { - if (stimer_elapsed(&uip_ds6_timer_ra) < UIP_ND6_MIN_DELAY_BETWEEN_RAS) { + if(stimer_remaining(&uip_ds6_timer_ra) > rand_time) { + if(stimer_elapsed(&uip_ds6_timer_ra) < UIP_ND6_MIN_DELAY_BETWEEN_RAS) { /* Ensure that the RAs are rate limited */ /* stimer_set(&uip_ds6_timer_ra, rand_time + UIP_ND6_MIN_DELAY_BETWEEN_RAS - - stimer_elapsed(&uip_ds6_timer_ra)); - */ } else { - stimer_set(&uip_ds6_timer_ra, rand_time); + stimer_elapsed(&uip_ds6_timer_ra)); + */ } else { + stimer_set(&uip_ds6_timer_ra, rand_time); } } } /*---------------------------------------------------------------------------*/ void -uip_ds6_send_ra_periodic(void) { - if(racount > 0){ - /* send previously scheduled RA*/ +uip_ds6_send_ra_periodic(void) +{ + if(racount > 0) { + /* send previously scheduled RA */ uip_nd6_ra_output(NULL); PRINTF("Sending periodic RA\n"); } rand_time = UIP_ND6_MIN_RA_INTERVAL + random_rand() % - (uint16_t)(UIP_ND6_MAX_RA_INTERVAL - UIP_ND6_MIN_RA_INTERVAL); + (uint16_t) (UIP_ND6_MAX_RA_INTERVAL - UIP_ND6_MIN_RA_INTERVAL); PRINTF("Random time 1 = %u\n", rand_time); - if(racount < UIP_ND6_MAX_INITIAL_RAS){ - if (rand_time > UIP_ND6_MAX_INITIAL_RA_INTERVAL){ + if(racount < UIP_ND6_MAX_INITIAL_RAS) { + if(rand_time > UIP_ND6_MAX_INITIAL_RA_INTERVAL) { rand_time = UIP_ND6_MAX_INITIAL_RA_INTERVAL; PRINTF("Random time 2 = %u\n", rand_time); } racount++; } PRINTF("Random time 3 = %u\n", rand_time); - stimer_set(&uip_ds6_timer_ra, rand_time); + stimer_set(&uip_ds6_timer_ra, rand_time); } #endif /* UIP_ND6_SEND_RA */ #else /* UIP_CONF_ROUTER */ /*---------------------------------------------------------------------------*/ void -uip_ds6_send_rs(void) { - if((uip_ds6_defrt_choose() == NULL) && (rscount < UIP_ND6_MAX_RTR_SOLICITATIONS)){ +uip_ds6_send_rs(void) +{ + if((uip_ds6_defrt_choose() == NULL) + && (rscount < UIP_ND6_MAX_RTR_SOLICITATIONS)) { PRINTF("Sending RS %u\n", rscount); uip_nd6_rs_output(); rscount++; - etimer_set(&uip_ds6_timer_rs, UIP_ND6_RTR_SOLICITATION_INTERVAL * CLOCK_SECOND); + etimer_set(&uip_ds6_timer_rs, + UIP_ND6_RTR_SOLICITATION_INTERVAL * CLOCK_SECOND); } else { - PRINTF("Router found ? (boolean): %u\n", (uip_ds6_defrt_choose() != NULL)); + PRINTF("Router found ? (boolean): %u\n", + (uip_ds6_defrt_choose() != NULL)); etimer_stop(&uip_ds6_timer_rs); } return; @@ -781,10 +926,12 @@ uip_ds6_send_rs(void) { uint32_t uip_ds6_compute_reachable_time(void) { - return (uint32_t)(UIP_ND6_MIN_RANDOM_FACTOR(uip_ds6_if.base_reachable_time)) + - ((uint16_t)(random_rand() << 8) + (uint16_t)random_rand()) % - (uint32_t)(UIP_ND6_MAX_RANDOM_FACTOR(uip_ds6_if.base_reachable_time) - - UIP_ND6_MIN_RANDOM_FACTOR(uip_ds6_if.base_reachable_time)); + return (uint32_t) (UIP_ND6_MIN_RANDOM_FACTOR + (uip_ds6_if.base_reachable_time)) + + ((uint16_t) (random_rand() << 8) + + (uint16_t) random_rand()) % + (uint32_t) (UIP_ND6_MAX_RANDOM_FACTOR(uip_ds6_if.base_reachable_time) - + UIP_ND6_MIN_RANDOM_FACTOR(uip_ds6_if.base_reachable_time)); } diff --git a/core/net/uip-ds6.h b/core/net/uip-ds6.h index 329bc2d54..8c912a95d 100755 --- a/core/net/uip-ds6.h +++ b/core/net/uip-ds6.h @@ -38,7 +38,7 @@ * * */ - + #ifndef __UIP_DS6_H__ #define __UIP_DS6_H__ @@ -47,7 +47,7 @@ /*--------------------------------------------------*/ /** Configuration. For all tables (Neighbor cache, Prefix List, Routing Table, - * Default Router List, Unicast address list, multicast address list, anycast address list), + * Default Router List, Unicast address list, multicast address list, anycast address list), * we define: * - the number of elements requested by the user in contiki configuration (name suffixed by _NBU) * - the number of elements assigned by the system (name suffixed by _NBS) @@ -56,59 +56,59 @@ /* Neighbor cache */ #define UIP_DS6_NBR_NBS 0 #ifndef UIP_CONF_DS6_NBR_NBU -#define UIP_DS6_NBR_NBU 4 -#else +#define UIP_DS6_NBR_NBU 4 +#else #define UIP_DS6_NBR_NBU UIP_CONF_DS6_NBR_NBU -#endif +#endif #define UIP_DS6_NBR_NB UIP_DS6_NBR_NBS + UIP_DS6_NBR_NBU /* Default router list */ #define UIP_DS6_DEFRT_NBS 0 #ifndef UIP_CONF_DS6_DEFRT_NBU #define UIP_DS6_DEFRT_NBU 2 -#else +#else #define UIP_DS6_DEFRT_NBU UIP_CONF_DS6_DEFRT_NBU -#endif +#endif #define UIP_DS6_DEFRT_NB UIP_DS6_DEFRT_NBS + UIP_DS6_DEFRT_NBU /* Prefix list */ -#define UIP_DS6_PREFIX_NBS 1 +#define UIP_DS6_PREFIX_NBS 1 #ifndef UIP_CONF_DS6_PREFIX_NBU #define UIP_DS6_PREFIX_NBU 2 -#else +#else #define UIP_DS6_PREFIX_NBU UIP_CONF_DS6_PREFIX_NBU -#endif +#endif #define UIP_DS6_PREFIX_NB UIP_DS6_PREFIX_NBS + UIP_DS6_PREFIX_NBU /* Routing table */ #define UIP_DS6_ROUTE_NBS 0 -#ifndef UIP_CONF_DS6_ROUTE_NBU +#ifndef UIP_CONF_DS6_ROUTE_NBU #define UIP_DS6_ROUTE_NBU 4 -#else +#else #define UIP_DS6_ROUTE_NBU UIP_CONF_DS6_ROUTE_NBU #endif -#define UIP_DS6_ROUTE_NB UIP_DS6_ROUTE_NBS + UIP_DS6_ROUTE_NBU +#define UIP_DS6_ROUTE_NB UIP_DS6_ROUTE_NBS + UIP_DS6_ROUTE_NBU /* Unicast address list*/ #define UIP_DS6_ADDR_NBS 1 #ifndef UIP_CONF_DS6_ADDR_NBU #define UIP_DS6_ADDR_NBU 2 -#else +#else #define UIP_DS6_ADDR_NBU UIP_CONF_DS6_ADDR_NBU -#endif +#endif #define UIP_DS6_ADDR_NB UIP_DS6_ADDR_NBS + UIP_DS6_ADDR_NBU /* Multicast address list */ #if UIP_CONF_ROUTER -#define UIP_DS6_MADDR_NBS 2 + UIP_DS6_ADDR_NB /* all routers + all nodes + one solicited per unicast */ +#define UIP_DS6_MADDR_NBS 2 + UIP_DS6_ADDR_NB /* all routers + all nodes + one solicited per unicast */ #else -#define UIP_DS6_MADDR_NBS 1 + UIP_DS6_ADDR_NB /* all nodes + one solicited per unicast */ +#define UIP_DS6_MADDR_NBS 1 + UIP_DS6_ADDR_NB /* all nodes + one solicited per unicast */ #endif #ifndef UIP_CONF_DS6_MADDR_NBU #define UIP_DS6_MADDR_NBU 0 -#else +#else #define UIP_DS6_MADDR_NBU UIP_CONF_DS6_MADDR_NBU -#endif +#endif #define UIP_DS6_MADDR_NB UIP_DS6_MADDR_NBS + UIP_DS6_MADDR_NBU /* Anycast address list */ @@ -136,7 +136,7 @@ /** \brief Possible states for the an address (RFC 4862) */ #define ADDR_TENTATIVE 0 #define ADDR_PREFERRED 1 -#define ADDR_DEPRECATED 2 +#define ADDR_DEPRECATED 2 /** \brief How the address was acquired: Autoconf, DHCP or manually */ #define ADDR_ANYTYPE 0 @@ -160,32 +160,32 @@ typedef struct uip_ds6_nbr { uint8_t isrouter; uint8_t state; struct stimer reachable; - struct stimer sendns; + struct stimer sendns; uint8_t nscount; #if UIP_CONF_IPV6_QUEUE_PKT uint8_t queue_buf[UIP_BUFSIZE - UIP_LLH_LEN]; uint8_t queue_buf_len; -#endif /*UIP_CONF_QUEUE_PKT*/ -} uip_ds6_nbr; +#endif /*UIP_CONF_QUEUE_PKT */ +} uip_ds6_nbr_t; /** \brief An entry in the default router list */ typedef struct uip_ds6_defrt { uint8_t isused; uip_ipaddr_t ipaddr; struct stimer lifetime; -} uip_ds6_defrt; +} uip_ds6_defrt_t; /** \brief A prefix list entry */ #if UIP_CONF_ROUTER typedef struct uip_ds6_prefix { - uint8_t isused; + uint8_t isused; uip_ipaddr_t ipaddr; uint8_t length; uint8_t advertise; u32_t vlifetime; u32_t plifetime; uint8_t l_a_reserved; /**< on-link and autonomous flags + 6 reserved bits */ -} uip_ds6_prefix ; +} uip_ds6_prefix_t; #else /* UIP_CONF_ROUTER */ typedef struct uip_ds6_prefix { uint8_t isused; @@ -193,8 +193,8 @@ typedef struct uip_ds6_prefix { uint8_t length; struct stimer vlifetime; uint8_t isinfinite; -} uip_ds6_prefix; -#endif /*UIP_CONF_ROUTER*/ +} uip_ds6_prefix_t; +#endif /*UIP_CONF_ROUTER */ /** * \brief Unicast address structure */ typedef struct uip_ds6_addr { @@ -206,19 +206,19 @@ typedef struct uip_ds6_addr { struct stimer vlifetime; struct timer dadtimer; uint8_t dadnscount; -} uip_ds6_addr; +} uip_ds6_addr_t; /** \brief Anycast address */ typedef struct uip_ds6_aaddr { uint8_t isused; uip_ipaddr_t ipaddr; -} uip_ds6_aaddr; +} uip_ds6_aaddr_t; /** \brief A multicast address */ typedef struct uip_ds6_maddr { uint8_t isused; uip_ipaddr_t ipaddr; -} uip_ds6_maddr; +} uip_ds6_maddr_t; /** \brief An entry in the routing table */ typedef struct uip_ds6_route { @@ -227,33 +227,34 @@ typedef struct uip_ds6_route { uint8_t length; uip_ipaddr_t nexthop; uint8_t metric; -} uip_ds6_route; +} uip_ds6_route_t; /** \brief Interface structure (contains all the interface variables) */ typedef struct uip_ds6_netif { uint32_t link_mtu; - uint8_t cur_hop_limit; + uint8_t cur_hop_limit; uint32_t base_reachable_time; /* in msec */ - uint32_t reachable_time; /* in msec */ - uint32_t retrans_timer; /* in msec */ + uint32_t reachable_time; /* in msec */ + uint32_t retrans_timer; /* in msec */ uint8_t maxdadns; - uip_ds6_addr addr_list[UIP_DS6_ADDR_NB]; - uip_ds6_aaddr aaddr_list[UIP_DS6_AADDR_NB]; - uip_ds6_maddr maddr_list[UIP_DS6_MADDR_NB]; -} uip_ds6_netif; + uip_ds6_addr_t addr_list[UIP_DS6_ADDR_NB]; + uip_ds6_aaddr_t aaddr_list[UIP_DS6_AADDR_NB]; + uip_ds6_maddr_t maddr_list[UIP_DS6_MADDR_NB]; +} uip_ds6_netif_t; /** \brief Generic type for a DS6, to use a common loop though all DS */ typedef struct uip_ds6_element { uint8_t isused; uip_ipaddr_t ipaddr; -} uip_ds6_element ; +} uip_ds6_element_t; /*---------------------------------------------------------------------------*/ -extern uip_ds6_netif uip_ds6_if; +extern uip_ds6_netif_t uip_ds6_if; extern struct etimer uip_ds6_timer_periodic; + #if UIP_CONF_ROUTER -extern uip_ds6_prefix uip_ds6_prefix_list[UIP_DS6_PREFIX_NB]; +extern uip_ds6_prefix_t uip_ds6_prefix_list[UIP_DS6_PREFIX_NB]; #else /* UIP_CONF_ROUTER */ extern struct etimer uip_ds6_timer_rs; #endif /* UIP_CONF_ROUTER */ @@ -266,80 +267,99 @@ void uip_ds6_init(void); /** \brief Periodic processing of data structures */ void uip_ds6_periodic(void); -/** \brief Generic loop routine on an abstract data structure, which generalizes +/** \brief Generic loop routine on an abstract data structure, which generalizes * all data structures used in DS6 */ -uint8_t uip_ds6_list_loop(uip_ds6_element* list, uint8_t size, uint16_t elementsize, uip_ipaddr_t* ipaddr, uint8_t ipaddrlen, uip_ds6_element** out_element); +uint8_t uip_ds6_list_loop(uip_ds6_element_t * list, uint8_t size, + uint16_t elementsize, uip_ipaddr_t * ipaddr, + uint8_t ipaddrlen, + uip_ds6_element_t ** out_element); /** \name Neighbor Cache basic routines */ /** @{ */ -uip_ds6_nbr* uip_ds6_nbr_add(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr, uint8_t isrouter, uint8_t state); -void uip_ds6_nbr_rm(uip_ds6_nbr* nbr); -uip_ds6_nbr* uip_ds6_nbr_lookup(uip_ipaddr_t *ipaddr); +uip_ds6_nbr_t *uip_ds6_nbr_add(uip_ipaddr_t * ipaddr, uip_lladdr_t * lladdr, + uint8_t isrouter, uint8_t state); +void uip_ds6_nbr_rm(uip_ds6_nbr_t * nbr); +uip_ds6_nbr_t *uip_ds6_nbr_lookup(uip_ipaddr_t * ipaddr); + /** @} */ /** \name Default router list basic routines */ /** @{ */ -uip_ds6_defrt* uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval); -void uip_ds6_defrt_rm(uip_ds6_defrt* defrt); -uip_ds6_defrt* uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr); -uip_ipaddr_t* uip_ds6_defrt_choose(void); +uip_ds6_defrt_t *uip_ds6_defrt_add(uip_ipaddr_t * ipaddr, + unsigned long interval); +void uip_ds6_defrt_rm(uip_ds6_defrt_t * defrt); +uip_ds6_defrt_t *uip_ds6_defrt_lookup(uip_ipaddr_t * ipaddr); +uip_ipaddr_t *uip_ds6_defrt_choose(void); + /** @} */ /** \name Prefix list basic routines */ /** @{ */ #if UIP_CONF_ROUTER -uip_ds6_prefix* uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t length, uint8_t advertise, uint8_t flags, unsigned long vtime, unsigned long ptime); +uip_ds6_prefix_t *uip_ds6_prefix_add(uip_ipaddr_t * ipaddr, uint8_t length, + uint8_t advertise, uint8_t flags, + unsigned long vtime, + unsigned long ptime); #else /* UIP_CONF_ROUTER */ -uip_ds6_prefix* uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t length, unsigned long interval); +uip_ds6_prefix_t *uip_ds6_prefix_add(uip_ipaddr_t * ipaddr, uint8_t length, + unsigned long interval); #endif /* UIP_CONF_ROUTER */ -void uip_ds6_prefix_rm(uip_ds6_prefix* prefix); -uip_ds6_prefix* uip_ds6_prefix_lookup(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen); -uint8_t uip_ds6_is_addr_onlink(uip_ipaddr_t *ipaddr); +void uip_ds6_prefix_rm(uip_ds6_prefix_t * prefix); +uip_ds6_prefix_t *uip_ds6_prefix_lookup(uip_ipaddr_t * ipaddr, + uint8_t ipaddrlen); +uint8_t uip_ds6_is_addr_onlink(uip_ipaddr_t * ipaddr); + /** @} */ /** \name Unicast address list basic routines */ /** @{ */ -uip_ds6_addr* uip_ds6_addr_add(uip_ipaddr_t *ipaddr, unsigned long vlifetime, uint8_t type); -void uip_ds6_addr_rm(uip_ds6_addr *addr); -uip_ds6_addr* uip_ds6_addr_lookup(uip_ipaddr_t* ipaddr); +uip_ds6_addr_t *uip_ds6_addr_add(uip_ipaddr_t * ipaddr, + unsigned long vlifetime, uint8_t type); +void uip_ds6_addr_rm(uip_ds6_addr_t * addr); +uip_ds6_addr_t *uip_ds6_addr_lookup(uip_ipaddr_t * ipaddr); + /** @} */ /** \name Multicast address list basic routines */ /** @{ */ -uip_ds6_maddr* uip_ds6_maddr_add(uip_ipaddr_t *ipaddr); -void uip_ds6_maddr_rm(uip_ds6_maddr *maddr); -uip_ds6_maddr* uip_ds6_maddr_lookup(uip_ipaddr_t* ipaddr); +uip_ds6_maddr_t *uip_ds6_maddr_add(uip_ipaddr_t * ipaddr); +void uip_ds6_maddr_rm(uip_ds6_maddr_t * maddr); +uip_ds6_maddr_t *uip_ds6_maddr_lookup(uip_ipaddr_t * ipaddr); + /** @} */ /** \name Anycast address list basic routines */ /** @{ */ -uip_ds6_aaddr* uip_ds6_aaddr_add(uip_ipaddr_t *ipaddr); -void uip_ds6_aaddr_rm(uip_ds6_aaddr *aaddr); -uip_ds6_aaddr* uip_ds6_aaddr_lookup(uip_ipaddr_t* ipaddr); +uip_ds6_aaddr_t *uip_ds6_aaddr_add(uip_ipaddr_t * ipaddr); +void uip_ds6_aaddr_rm(uip_ds6_aaddr_t * aaddr); +uip_ds6_aaddr_t *uip_ds6_aaddr_lookup(uip_ipaddr_t * ipaddr); + /** @} */ /** \name Routing Table basic routines */ /** @{ */ -uip_ipaddr_t* uip_ds6_route_lookup(uip_ipaddr_t *destipaddr); -uip_ds6_route* uip_ds6_route_add(uip_ipaddr_t *ipaddr, u8_t length, uip_ipaddr_t *next_hop, u8_t metric); -void uip_ds6_route_rm(uip_ds6_route* route); +uip_ds6_route_t *uip_ds6_route_lookup(uip_ipaddr_t * destipaddr); +uip_ds6_route_t *uip_ds6_route_add(uip_ipaddr_t * ipaddr, uint8_t length, + uip_ipaddr_t * next_hop, u8_t metric); +void uip_ds6_route_rm(uip_ds6_route_t * route); + /** @} */ /** \brief set the last 64 bits of an IP address based on the MAC address */ -void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr); +void uip_ds6_set_addr_iid(uip_ipaddr_t * ipaddr, uip_lladdr_t * lladdr); /** \brief Get the number of matching bits of two addresses */ -uint8_t get_match_length(uip_ipaddr_t *src, uip_ipaddr_t *dst); +uint8_t get_match_length(uip_ipaddr_t * src, uip_ipaddr_t * dst); /** \brief Perform Duplicate Address Selection on one address */ -void uip_ds6_dad(uip_ds6_addr* ifaddr); +void uip_ds6_dad(uip_ds6_addr_t * ifaddr); /** \brief Callback when DAD failed */ -void uip_ds6_dad_failed(uip_ds6_addr* ifaddr); +int uip_ds6_dad_failed(uip_ds6_addr_t * ifaddr); /** \brief Source address selection, see RFC 3484 */ -void uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst); +void uip_ds6_select_src(uip_ipaddr_t * src, uip_ipaddr_t * dst); #if UIP_CONF_ROUTER #if UIP_ND6_SEND_RA @@ -351,7 +371,7 @@ void uip_ds6_send_ra_periodic(void); #endif /* UIP_ND6_SEND_RA */ #else /* UIP_CONF_ROUTER */ /** \brief Send periodic RS to find router */ -void uip_ds6_send_rs(void); +void uip_ds6_send_rs(void); #endif /* UIP_CONF_ROUTER */ /** \brief Compute the reachable time based on base reachable time, see RFC 4861*/ @@ -366,4 +386,3 @@ uint32_t uip_ds6_compute_reachable_time(void); /** \brief compute random reachab /** @} */ #endif /* __UIP_DS6_H__ */ - diff --git a/core/net/uip-icmp6.c b/core/net/uip-icmp6.c index 7888f6f85..5c7184ccf 100644 --- a/core/net/uip-icmp6.c +++ b/core/net/uip-icmp6.c @@ -43,7 +43,7 @@ */ #include -#include "net/uip-netif.h" +#include "net/uip-ds6.h" #include "net/uip-icmp6.h" #define DEBUG 0 @@ -79,11 +79,11 @@ uip_icmp6_echo_request_input(void) PRINTF("\n"); /* IP header */ - UIP_IP_BUF->ttl = uip_netif_physical_if.cur_hop_limit; + UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit; if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)){ uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &UIP_IP_BUF->srcipaddr); - uip_netif_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); + uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); } else { uip_ipaddr_copy(&tmp_ipaddr, &UIP_IP_BUF->srcipaddr); uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); @@ -127,6 +127,13 @@ uip_icmp6_echo_request_input(void) void uip_icmp6_error_output(u8_t type, u8_t code, u32_t param) { uip_ext_len = 0; + + /* check if originating packet is not an ICMP error*/ + if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type < 128){ + uip_len = 0; + return; + } + /* remember data of original packet before shifting */ uip_ipaddr_copy(&tmp_ipaddr, &UIP_IP_BUF->destipaddr); @@ -142,7 +149,7 @@ uip_icmp6_error_output(u8_t type, u8_t code, u32_t param) { UIP_IP_BUF->tcflow = 0; UIP_IP_BUF->flow = 0; UIP_IP_BUF->proto = UIP_PROTO_ICMP6; - UIP_IP_BUF->ttl = uip_netif_physical_if.cur_hop_limit; + UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit; /* the source should not be unspecified nor multicast, the check for multicast is done in uip_process */ @@ -155,7 +162,7 @@ uip_icmp6_error_output(u8_t type, u8_t code, u32_t param) { if(uip_is_addr_mcast(&tmp_ipaddr)){ if(type == ICMP6_PARAM_PROB && code == ICMP6_PARAMPROB_OPTION){ - uip_netif_select_src(&UIP_IP_BUF->srcipaddr, &tmp_ipaddr); + uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &tmp_ipaddr); } else { uip_len = 0; return; @@ -163,7 +170,7 @@ uip_icmp6_error_output(u8_t type, u8_t code, u32_t param) { } else { #if UIP_CONF_ROUTER /* need to pick a source that corresponds to this node */ - uip_netif_select_src(&UIP_IP_BUF->srcipaddr, &tmp_ipaddr); + uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &tmp_ipaddr); #else uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &tmp_ipaddr); #endif diff --git a/core/net/uip-icmp6.h b/core/net/uip-icmp6.h index bd60a5fd2..e40a378b3 100644 --- a/core/net/uip-icmp6.h +++ b/core/net/uip-icmp6.h @@ -63,6 +63,8 @@ #define ICMP6_NS 135 /**< Neighbor Solicitation */ #define ICMP6_NA 136 /**< Neighbor advertisement */ #define ICMP6_REDIRECT 137 /**< Redirect */ + +#define ICMP6_RPL 155 /**< RPL */ /** @} */ @@ -122,6 +124,11 @@ uip_icmp6_error_output(u8_t type, u8_t code, u32_t param); /** @} */ +#if UIP_CONF_IPV6_RPL +void +uip_rpl_input(void); +#endif /* UIP_CONF_IPV6_RPL */ + #endif /*__ICMP6_H__*/ /** @} */ diff --git a/core/net/uip-nd6-io.c b/core/net/uip-nd6-io.c deleted file mode 100644 index 9fc688e83..000000000 --- a/core/net/uip-nd6-io.c +++ /dev/null @@ -1,917 +0,0 @@ -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * Neighbor discovery Input-Output (RFC 4861) - * \author Julien Abeille - * \author Mathilde Durvy - */ -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include -#include "net/uip-icmp6.h" -#include "net/uip-nd6.h" -#include "net/uip-netif.h" - - - -/*------------------------------------------------------------------*/ -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((u8_t *)addr)[0], ((u8_t *)addr)[1], ((u8_t *)addr)[2], ((u8_t *)addr)[3], ((u8_t *)addr)[4], ((u8_t *)addr)[5], ((u8_t *)addr)[6], ((u8_t *)addr)[7], ((u8_t *)addr)[8], ((u8_t *)addr)[9], ((u8_t *)addr)[10], ((u8_t *)addr)[11], ((u8_t *)addr)[12], ((u8_t *)addr)[13], ((u8_t *)addr)[14], ((u8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",lladdr->addr[0], lladdr->addr[1], lladdr->addr[2], lladdr->addr[3],lladdr->addr[4], lladdr->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(lladdr) -#endif - -#if UIP_LOGGING -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif /* UIP_LOGGING == 1 */ - - -/*------------------------------------------------------------------*/ -/** @{ */ -/** \name Pointers to the header structures. - * All pointers except UIP_IP_BUF depend on uip_ext_len, which at - * packet reception, is the total length of the extension headers. - * - * The pointer to ND6 options header also depends on nd6_opt_offset, - * which we set in each function. - * - * Care should be taken when manipulating these buffers about the - * value of these length variables - */ - -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -/**< Pointer to IP header */ -#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) -/**< Pointer to ICMP header*/ -/**@{ Pointers to messages just after icmp header */ -#define UIP_ND6_RS_BUF ((struct uip_nd6_rs *)&uip_buf[uip_l2_l3_icmp_hdr_len]) -#define UIP_ND6_RA_BUF ((struct uip_nd6_ra *)&uip_buf[uip_l2_l3_icmp_hdr_len]) -#define UIP_ND6_NS_BUF ((struct uip_nd6_ns *)&uip_buf[uip_l2_l3_icmp_hdr_len]) -#define UIP_ND6_NA_BUF ((struct uip_nd6_na *)&uip_buf[uip_l2_l3_icmp_hdr_len]) -#define UIP_ICMP6_ERROR_BUF ((struct uip_icmp6_error *)&uip_buf[uip_l2_l3_icmp_hdr_len]) -/** @} */ -/** Pointer to ND option */ -#define UIP_ND6_OPT_HDR_BUF ((struct uip_nd6_opt_hdr *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset]) -/** @} */ - -/** \brief Offset from the end of the icmpv6 header to the option in uip_buf*/ -static u8_t nd6_opt_offset; -/** \brief Pointer to llao option in uip_buf */ -static struct uip_nd6_opt_llao *nd6_opt_llao; -/** \brief Pointer to mtu option in uip_buf */ -static struct uip_nd6_opt_mtu *nd6_opt_mtu; -/** \brief Pointer to prefix information option in uip_buf */ -static struct uip_nd6_opt_prefix_info *nd6_opt_prefix_info[UIP_CONF_ND6_MAX_PREFIXES]; -/** \brief Pointer to a neighbor cache entry*/ -static struct uip_nd6_neighbor *neighbor; -/** \brief Pointer to a prefix list entry */ -static struct uip_nd6_prefix *prefix; -/** \brief Pointer to a router list entry */ -static struct uip_nd6_defrouter *router; -/** \brief Pointer to an interface address */ -static struct uip_netif_addr *ifaddr; -/** \brief Index used in loops */ -static u8_t i; - -/*------------------------------------------------------------------*/ -void -uip_nd6_io_ns_input(void) -{ - u8_t flags; - - PRINTF("Received NS from"); - PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF("to"); - PRINT6ADDR(&UIP_IP_BUF->destipaddr); - PRINTF("with target address"); - PRINT6ADDR((uip_ipaddr_t *)(&UIP_ND6_NS_BUF->tgtipaddr)); - 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_mcast(&UIP_ND6_NS_BUF->tgtipaddr)) || - (UIP_ICMP_BUF->icode != 0)) { - goto badpkt; - } -#endif /* UIP_CONF_IPV6_CHECKS */ - - /* Options reading: we handle only SLLAO for now */ - nd6_opt_llao = NULL; - nd6_opt_offset = UIP_ND6_NS_LEN; - while(uip_l3_icmp_hdr_len + nd6_opt_offset < uip_len) { -#if UIP_CONF_IPV6_CHECKS - if(UIP_ND6_OPT_HDR_BUF->len == 0) { - goto badpkt; - } -#endif /* UIP_CONF_IPV6_CHECKS */ - switch(UIP_ND6_OPT_HDR_BUF->type) { - case UIP_ND6_OPT_SLLAO: - nd6_opt_llao = (struct uip_nd6_opt_llao *)UIP_ND6_OPT_HDR_BUF; - break; - default: - UIP_LOG("ND option not supported in NS"); - break; - } - nd6_opt_offset += (UIP_ND6_OPT_HDR_BUF->len << 3); - } - - /* Options processing: only SLLAO */ - if(nd6_opt_llao != NULL) { -#if UIP_CONF_IPV6_CHECKS - /* There must be NO option in a DAD NS */ - if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) { - goto badpkt; - } else { -#endif /*UIP_CONF_IPV6_CHECKS*/ - neighbor = uip_nd6_nbrcache_lookup(&UIP_IP_BUF->srcipaddr); - if(neighbor == NULL) { - /* we need to add the neighbor*/ - uip_nd6_nbrcache_add(&UIP_IP_BUF->srcipaddr, - &nd6_opt_llao->addr, 0, STALE); - } else { - /* If LL address changed, set neighbor state to stale */ - if(memcmp(&nd6_opt_llao->addr, &neighbor->lladdr, UIP_LLADDR_LEN) != 0) { - memcpy(&neighbor->lladdr, &nd6_opt_llao->addr, UIP_LLADDR_LEN); - neighbor->state = STALE; - } else { - /* If neighbor state is INCOMPLETE, set to STALE */ - if(neighbor->state == INCOMPLETE) { - neighbor->state = STALE; - } - } - } -#if UIP_CONF_IPV6_CHECKS - } -#endif /*UIP_CONF_IPV6_CHECKS*/ - } - - /* - * Rest of NS processing: Depends on the purpose of the NS: NUD or DAD or - * Address Resolution - */ - /** \note we use ifaddr to remember the target address */ - ifaddr = uip_netif_addr_lookup(&UIP_ND6_NS_BUF->tgtipaddr, 128, 0); - if(ifaddr != NULL) { - if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)){ - /* DAD CASE */ -#if UIP_CONF_IPV6_CHECKS - /* Dst address must be solicited node mcast address */ - if(!uip_netif_is_addr_my_solicited(&UIP_IP_BUF->destipaddr)){ - goto badpkt; - } -#endif /* UIP_CONF_IPV6_CHECKS */ - /* - * If my address is not tentative, then send a NA to all nodes with - * TLLAO flags are: override = yes. - */ - if(ifaddr->state!=TENTATIVE) { - /* - * we need to send a NA, we set the src, dest, flags. tgt remains the - * same and the rest is done at "create_na" - */ - uip_create_linklocal_allnodes_mcast(&UIP_IP_BUF->destipaddr); - uip_netif_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); - flags = UIP_ND6_NA_FLAG_OVERRIDE; - goto create_na; - } else { - /** \todo if I sent a NS before him, I win */ - uip_netif_dad_failed(&UIP_ND6_NS_BUF->tgtipaddr); - goto discard; - } - } - - -#if UIP_CONF_IPV6_CHECKS - /* Duplicate check */ - if(uip_netif_is_addr_my_unicast(&UIP_IP_BUF->srcipaddr)) { - /** - * \NOTE do we do something here? we both are using the same address. - * If we are doing dad, we could cancel it, though we should receive a - * NA in response of DAD NS we sent, hence DAD will fail anyway. If we - * were not doing DAD, it means there is a duplicate in the network! - */ - goto badpkt; - } -#endif /*UIP_CONF_IPV6_CHECKS*/ - - /* Address resolution case */ - if(uip_netif_is_addr_my_solicited(&UIP_IP_BUF->destipaddr)){ - /* - * we need to send a NA, we set the src, dest, flags. The rest is - * set at the "create_na" label. - */ - uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &UIP_IP_BUF->srcipaddr); - uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &UIP_ND6_NS_BUF->tgtipaddr); - flags = UIP_ND6_NA_FLAG_SOLICITED | UIP_ND6_NA_FLAG_OVERRIDE; - goto create_na; - } - - /* - * NUD CASE. at this point the packet must be for us! we check this, - * and at the same time if target == dest - */ - if(uip_netif_addr_lookup(&UIP_IP_BUF->destipaddr, 128, 0) == ifaddr){ - /* - * we need to send a NA, we set the src, dest, flags. The rest is set - * at the "create_na" label. - */ - uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &UIP_IP_BUF->srcipaddr); - uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &UIP_ND6_NS_BUF->tgtipaddr); - flags = UIP_ND6_NA_FLAG_SOLICITED | UIP_ND6_NA_FLAG_OVERRIDE; - goto create_na; - } else { -#if UIP_CONF_IPV6_CHECKS - goto badpkt; -#endif /* UIP_CONF_IPV6_CHECKS */ - } - } else { - goto discard; - } - - - create_na: - /* - * Fill the part of the NA which is common to all NAs. If the NS contained - * extension headers, we must set the target address properly - */ - uip_ext_len = 0; - - /* IP header */ - UIP_IP_BUF->vtc = 0x60; - UIP_IP_BUF->tcflow = 0; - UIP_IP_BUF->flow = 0; - UIP_IP_BUF->len[0] = 0; /* length will not be more than 255 */ - UIP_IP_BUF->len[1] = UIP_ICMPH_LEN + UIP_ND6_NA_LEN + UIP_ND6_OPT_LLAO_LEN; - UIP_IP_BUF->proto = UIP_PROTO_ICMP6; - UIP_IP_BUF->ttl = UIP_ND6_HOP_LIMIT; - - /* ICMP header */ - UIP_ICMP_BUF->type = ICMP6_NA; - UIP_ICMP_BUF->icode = 0; - - /* NA static part */ - UIP_ND6_NA_BUF->flagsreserved = flags; - memcpy(&UIP_ND6_NA_BUF->tgtipaddr, &ifaddr->ipaddr, sizeof(uip_ipaddr_t)); - - /* NA option: TLLAO. note that length field is in unit of 8 bytes */ - uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NA_LEN + UIP_ND6_OPT_LLAO_LEN; - nd6_opt_llao = (struct uip_nd6_opt_llao *)&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_NA_LEN]; - nd6_opt_llao->type = UIP_ND6_OPT_TLLAO; - nd6_opt_llao->len = UIP_ND6_OPT_LLAO_LEN >> 3; - memcpy(&(nd6_opt_llao->addr), &uip_lladdr, UIP_LLADDR_LEN); - /* padding if needed */ - memset((void *)(&nd6_opt_llao->addr) + UIP_LLADDR_LEN, 0, UIP_ND6_OPT_LLAO_LEN - 2 - UIP_LLADDR_LEN); - - /*ICMP checksum*/ - UIP_ICMP_BUF->icmpchksum = 0; - UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); - - - UIP_STAT(++uip_stat.nd6.sent); - PRINTF("Sending NA to"); - PRINT6ADDR(&UIP_IP_BUF->destipaddr); - PRINTF("from"); - PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF("with target address"); - PRINT6ADDR(&UIP_ND6_NA_BUF->tgtipaddr); - PRINTF("\n"); - return; - -#if UIP_CONF_IPV6_CHECKS - badpkt: - UIP_STAT(++uip_stat.nd6.drop); - UIP_LOG("NS received is bad"); -#endif /* UIP_CONF_IPV6_CHECKS */ - - discard: - uip_len = 0; - return; -} -/*------------------------------------------------------------------*/ -void -uip_nd6_io_ns_output(uip_ipaddr_t *src, uip_ipaddr_t *dest, uip_ipaddr_t *tgt) -{ - /* IP header fields */ - uip_ext_len = 0; - UIP_IP_BUF->vtc = 0x60; - UIP_IP_BUF->tcflow = 0; - UIP_IP_BUF->flow = 0; - UIP_IP_BUF->proto = UIP_PROTO_ICMP6; - UIP_IP_BUF->ttl = UIP_ND6_HOP_LIMIT; - - /* - * The caller must put a valid tgt address. - * For dest, if the caller is doing DAD or Address resolution, he sets - * dest to NULL and we forge dest as the sollicited node mcast address - * for tgt. - * If the caller is sending the NS for NUD, dest is unicast and the caller - * specifies it in the arguments - */ - if(dest == NULL) { - uip_create_solicited_node(tgt, &UIP_IP_BUF->destipaddr); - } else { - uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, dest); - } - UIP_ICMP_BUF->type = ICMP6_NS; - UIP_ICMP_BUF->icode = 0; - UIP_ND6_NS_BUF->reserved = 0; - - /* Copy the tgt address */ - uip_ipaddr_copy((uip_ipaddr_t *)&UIP_ND6_NS_BUF->tgtipaddr, tgt); - - UIP_IP_BUF->len[0] = 0; /* length will not be more than 255 */ - /* - * check if we add a SLLAO option: for DAD, MUST NOT, for NUD, MAY - * (here yes), for Address resolution , MUST - * i.e. if and only if tgt is our address (in this case it is DAD), we do - * not add it - */ - if(!(uip_netif_is_addr_my_unicast(tgt))) { - if(src != NULL) { - uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, src); - } else { - uip_netif_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); - } - UIP_IP_BUF->len[1] = UIP_ICMPH_LEN + UIP_ND6_NS_LEN + UIP_ND6_OPT_LLAO_LEN; - - uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NS_LEN + UIP_ND6_OPT_LLAO_LEN; - nd6_opt_llao = (struct uip_nd6_opt_llao *)&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_NS_LEN]; - nd6_opt_llao->type = UIP_ND6_OPT_SLLAO; /* type of the option */ - /* - * length of the option: 2 bytes for type, length, plus the length of - * the L2 address. It must be in units of 8 bytes - */ - nd6_opt_llao->len = UIP_ND6_OPT_LLAO_LEN >> 3; - memcpy(&nd6_opt_llao->addr, &uip_lladdr, UIP_LLADDR_LEN); - /* padding if needed */ - memset((void *)(&nd6_opt_llao->addr) + UIP_LLADDR_LEN, 0, UIP_ND6_OPT_LLAO_LEN - 2 - UIP_LLADDR_LEN); - } - else { - uip_create_unspecified(&UIP_IP_BUF->srcipaddr); - UIP_IP_BUF->len[1] = UIP_ICMPH_LEN + UIP_ND6_NS_LEN; - uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NS_LEN; - } - - UIP_ICMP_BUF->icmpchksum = 0; - UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); - - UIP_STAT(++uip_stat.nd6.sent); - PRINTF("Sending NS to"); - PRINT6ADDR(&UIP_IP_BUF->destipaddr); - PRINTF("from"); - PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF("with target address"); - PRINT6ADDR(tgt); - PRINTF("\n"); - return; -} - - - -/*------------------------------------------------------------------*/ -void -uip_nd6_io_na_input(void) -{ - - /* - * booleans. the three last one are not 0 or 1 but 0 or 0x80, 0x40, 0x20 - * but it works. Be careful though, do not use tests such as is_router == 1 - */ - u8_t is_llchange = 0; - u8_t is_router = ((UIP_ND6_NA_BUF->flagsreserved & UIP_ND6_NA_FLAG_ROUTER)); - u8_t is_solicited = ((UIP_ND6_NA_BUF->flagsreserved & UIP_ND6_NA_FLAG_SOLICITED)); - u8_t is_override = ((UIP_ND6_NA_BUF->flagsreserved & UIP_ND6_NA_FLAG_OVERRIDE)); - - PRINTF("Received NA from"); - PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF("to"); - PRINT6ADDR(&UIP_IP_BUF->destipaddr); - PRINTF("with target address"); - PRINT6ADDR((uip_ipaddr_t *)(&UIP_ND6_NA_BUF->tgtipaddr)); - PRINTF("\n"); - UIP_STAT(++uip_stat.nd6.recv); - -#if UIP_CONF_IPV6_CHECKS - /* - * Check hop limit / icmp code - * target address must not be multicast - * if the NA is solicited, dest must not be multicast - */ - if((UIP_IP_BUF->ttl != UIP_ND6_HOP_LIMIT) || - (UIP_ICMP_BUF->icode != 0) || - (uip_is_addr_mcast(&UIP_ND6_NA_BUF->tgtipaddr)) || - (is_solicited && uip_is_addr_mcast(&UIP_IP_BUF->destipaddr))) { - goto badpkt; - } -#endif /*UIP_CONF_IPV6_CHECKS*/ - - /* Options reading: we can handle TLLAO, and must ignore othehrs */ - nd6_opt_offset = UIP_ND6_NA_LEN; - nd6_opt_llao = NULL; - while(uip_l3_icmp_hdr_len + nd6_opt_offset < uip_len) { -#if UIP_CONF_IPV6_CHECKS - if(UIP_ND6_OPT_HDR_BUF->len == 0) { - goto badpkt; - } -#endif /*UIP_CONF_IPV6_CHECKS*/ - switch(UIP_ND6_OPT_HDR_BUF->type) { - case UIP_ND6_OPT_TLLAO: - nd6_opt_llao = (struct uip_nd6_opt_llao *)UIP_ND6_OPT_HDR_BUF; - break; - default: - UIP_LOG("ND option not supported in NA"); - break; - } - nd6_opt_offset += (UIP_ND6_OPT_HDR_BUF->len << 3); - } - ifaddr = uip_netif_addr_lookup(&UIP_ND6_NA_BUF->tgtipaddr, 128, 0); - /* Message processing, including TLLAO if any */ - if(ifaddr != NULL) { - if(ifaddr->state == TENTATIVE) { - /*It means DAD failed*/ - uip_netif_dad_failed(&UIP_ND6_NA_BUF->tgtipaddr); - } - goto discard; - } else { - neighbor = uip_nd6_nbrcache_lookup(&UIP_ND6_NA_BUF->tgtipaddr); - /* if the neighbor entry does not exist, silently discard */ - if(neighbor == NULL) { - goto discard; - } - if(nd6_opt_llao != 0) { - is_llchange = memcmp((void *)&nd6_opt_llao->addr, (void *)(&neighbor->lladdr), UIP_LLADDR_LEN); - } - if(neighbor->state == INCOMPLETE){ - if(nd6_opt_llao == 0) { - goto discard; - } - memcpy(&neighbor->lladdr, &nd6_opt_llao->addr, UIP_LLADDR_LEN); - if(is_solicited) { - neighbor->state = REACHABLE; - /* reachable time is stored in ms*/ - stimer_set(&(neighbor->reachable), - uip_netif_physical_if.reachable_time / 1000); - - } else { - neighbor->state = STALE; - } - neighbor->isrouter = is_router; - } else { - if(!is_override && is_llchange) { - if(neighbor->state == REACHABLE) { - neighbor->state = STALE; - } - goto discard; - } else { - if(is_override - || (!is_override && nd6_opt_llao != 0 && !is_llchange) - || nd6_opt_llao == 0) { - - /* update LL address if any */ - if(nd6_opt_llao != 0) { - memcpy(&neighbor->lladdr, &nd6_opt_llao->addr, UIP_LLADDR_LEN); - } - - /* - * if the NA was solicited, change the state of the neighbor to - * reachabe. Otherwise and if the neighbor LL changed, set the - * state to STALE - */ - if(is_solicited) { - neighbor->state = REACHABLE; - /* reachable time is stored in ms*/ - stimer_set(&(neighbor->reachable), - uip_netif_physical_if.reachable_time / 1000); - - } else { - if(nd6_opt_llao != 0 && is_llchange) { - neighbor->state = STALE; - } - } - } - } - if(neighbor->isrouter && !is_router){ - /* the neighbor stopped being a router, we remove it from the list */ - router = uip_nd6_defrouter_lookup(neighbor); - if(router != NULL){ - uip_nd6_defrouter_rm(router); - } - } - neighbor->isrouter = is_router; - } - } - -#if UIP_CONF_IPV6_QUEUE_PKT - /* The neighbor is now reachable, check if we had buffered a pkt for it */ - if(neighbor->queue_buf_len != 0) { - uip_len = neighbor->queue_buf_len; - memcpy(UIP_IP_BUF, neighbor->queue_buf, uip_len); - neighbor->queue_buf_len = 0; - return; - } -#endif /*UIP_CONF_IPV6_QUEUE_PKT*/ - uip_len = 0; - return; - -#if UIP_CONF_IPV6_CHECKS - badpkt: - UIP_STAT(++uip_stat.nd6.drop); - UIP_LOG("NA received is bad"); -#endif /* UIP_CONF_IPV6_CHECKS */ - - discard: - uip_len = 0; - return; -} - - - -/*---------------------------------------------------------------------------*/ -void -uip_nd6_io_rs_output(void) { - UIP_IP_BUF->vtc = 0x60; - UIP_IP_BUF->tcflow = 0; - UIP_IP_BUF->flow = 0; - UIP_IP_BUF->proto = UIP_PROTO_ICMP6; - UIP_IP_BUF->ttl = UIP_ND6_HOP_LIMIT; - uip_create_linklocal_allrouters_mcast(&UIP_IP_BUF->destipaddr); - uip_netif_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); - UIP_ICMP_BUF->type = ICMP6_RS; - UIP_ICMP_BUF->icode = 0; - UIP_ND6_RS_BUF->reserved = 0; - - UIP_IP_BUF->len[0] = 0; /* length will not be more than 255 */ - - /* we add the SLLAO option only if src is not unspecified */ - if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) { - UIP_IP_BUF->len[1] = UIP_ICMPH_LEN + UIP_ND6_RS_LEN; - uip_len = uip_l3_icmp_hdr_len + UIP_ND6_RS_LEN; - } else { - uip_len = uip_l3_icmp_hdr_len + UIP_ND6_RS_LEN + UIP_ND6_OPT_LLAO_LEN; - UIP_IP_BUF->len[1] = UIP_ICMPH_LEN + UIP_ND6_RS_LEN + UIP_ND6_OPT_LLAO_LEN; - nd6_opt_llao = (struct uip_nd6_opt_llao *)&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_RS_LEN]; - nd6_opt_llao->type = UIP_ND6_OPT_SLLAO; /* type of the option */ - nd6_opt_llao->len = UIP_ND6_OPT_LLAO_LEN >> 3; - /* length of the option in units of 8 bytes */ - memcpy(&nd6_opt_llao->addr, &uip_lladdr, UIP_LLADDR_LEN); - /* padding if needed */ - memset((void *)(&nd6_opt_llao->addr) + UIP_LLADDR_LEN, 0, UIP_ND6_OPT_LLAO_LEN - 2 - UIP_LLADDR_LEN); - } - - - UIP_ICMP_BUF->icmpchksum = 0; - UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); - - UIP_STAT(++uip_stat.nd6.sent); - - PRINTF("Sendin RS to"); - PRINT6ADDR(&UIP_IP_BUF->destipaddr); - PRINTF("from"); - PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF("\n"); - - return; -} - - - -/*---------------------------------------------------------------------------*/ -void -uip_nd6_io_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 - /* a few validity checks */ - if((UIP_IP_BUF->ttl != UIP_ND6_HOP_LIMIT) || - (!uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr)) || - (UIP_ICMP_BUF->icode != 0)) { - goto badpkt; - } -#endif /*UIP_CONF_IPV6_CHECKS*/ - - /* - * process the fields of the constant part - * As per RFC 4861, for reachable time and retrans timer, a value of 0 means - * unspecified by this router. - * If router lifetime is 0, the router SHOULD NOT be placed in default - * router list - */ - if(UIP_ND6_RA_BUF->cur_ttl != 0) { - uip_netif_physical_if.cur_hop_limit = UIP_ND6_RA_BUF->cur_ttl; - PRINTF("uip_netif_physical_if.cur_hop_limit %u\n", uip_netif_physical_if.cur_hop_limit); - } - /* - * As per RFC4861 section 6.3.4, if reachable time field is non zero - * and defers from the current base reachable time for the interface, - * set base reachable time to the new value and recompute the reachable time - * as a random value distributed between 0.5 and 1.5 x Base reachable time - */ - if(UIP_ND6_RA_BUF->reachable_time != 0) { - if(uip_netif_physical_if.base_reachable_time != ntohl(UIP_ND6_RA_BUF->reachable_time)) { - uip_netif_physical_if.base_reachable_time = ntohl(UIP_ND6_RA_BUF->reachable_time); - uip_netif_physical_if.reachable_time = uip_netif_compute_reachable_time(); - } - } - if(UIP_ND6_RA_BUF->retrans_timer !=0) { - uip_netif_physical_if.retrans_timer = ntohl(UIP_ND6_RA_BUF->retrans_timer); - } - - /* - * Note: in our implementation, an entry in the default router list contains - * does not contain the IP address of the router. The entry has a pointer - * to the corresponding neighbor cache entry, where the IP address is stored - */ - /* Options reading: possible options are MTU, SLLAO, prefix */ - nd6_opt_llao = NULL; - nd6_opt_mtu = NULL; - for(i = 0; i < UIP_CONF_ND6_MAX_PREFIXES; i++) { - nd6_opt_prefix_info[i] = NULL; - } - 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) { - goto badpkt; - } - switch(UIP_ND6_OPT_HDR_BUF->type) { - case UIP_ND6_OPT_SLLAO: - nd6_opt_llao = (struct uip_nd6_opt_llao *)UIP_ND6_OPT_HDR_BUF; - break; - case UIP_ND6_OPT_MTU: - nd6_opt_mtu = (struct uip_nd6_opt_mtu *)UIP_ND6_OPT_HDR_BUF; - break; - case UIP_ND6_OPT_PREFIX_INFO: - i = 0; - while((i < UIP_CONF_ND6_MAX_PREFIXES) && (nd6_opt_prefix_info[i] != NULL)) { - i++; - } - if(i < UIP_CONF_ND6_MAX_PREFIXES) { - nd6_opt_prefix_info[i] = (struct uip_nd6_opt_prefix_info *)UIP_ND6_OPT_HDR_BUF; - } - break; - default: - UIP_LOG("ND option not supported in RA"); - break; - } - nd6_opt_offset += (UIP_ND6_OPT_HDR_BUF->len << 3); - } - - /* Process the MTU option if any */ - if(nd6_opt_mtu != NULL) { - /* just set the link MTU to the value specified. Note that this option */ - PRINTF("Processing MTU option in RA\n"); - uip_netif_physical_if.link_mtu = ntohl(nd6_opt_mtu->mtu); - } - - /* Prefix information options processing */ - i = 0; - while((i < UIP_CONF_ND6_MAX_PREFIXES - 1) && (nd6_opt_prefix_info[i] != NULL)) { - PRINTF("Processing PREFIX option in RA\n"); - - if((ntohl((nd6_opt_prefix_info[i])->validlt) >= - ntohl((nd6_opt_prefix_info[i])->preferredlt)) && - (!uip_is_addr_link_local(&nd6_opt_prefix_info[i]->prefix))) { - /* on-link flag related processing*/ - if(((nd6_opt_prefix_info[i])->flagsreserved1 & 0x80) == 0x80) { - prefix = uip_nd6_prefix_lookup(&(nd6_opt_prefix_info[i])->prefix); - if(prefix == NULL) { - if((nd6_opt_prefix_info[i])->validlt != 0){ - if((nd6_opt_prefix_info[i])->validlt != UIP_ND6_INFINITE_LIFETIME){ - prefix = uip_nd6_prefix_add(&(nd6_opt_prefix_info[i])->prefix, - (nd6_opt_prefix_info[i])->preflen, - ntohl((nd6_opt_prefix_info[i])->validlt)); - } else { - prefix = uip_nd6_prefix_add(&(nd6_opt_prefix_info[i])->prefix, - (nd6_opt_prefix_info[i])->preflen, - 0); - } - } - } else { - /* we update or remove an existing prefix */ - switch((nd6_opt_prefix_info[i])->validlt) { - case 0: - uip_nd6_prefix_rm(prefix); - break; - case UIP_ND6_INFINITE_LIFETIME: - prefix->is_infinite = 1; - break; - default: - PRINTF("Updating timer of prefix"); - PRINT6ADDR(prefix); - PRINTF("new value %lu\n", ntohl((nd6_opt_prefix_info[i])->validlt)); - stimer_set(&prefix->vlifetime, ntohl((nd6_opt_prefix_info[i])->validlt)); - /*in case the prefix lifetime was previously infinite */ - prefix->is_infinite = 0; - break; - } - } - } - /* End of on-link flag related processing */ - /* autonomous flag related processing*/ - if((((nd6_opt_prefix_info[i])->flagsreserved1 & 0x40) == 0x40) && - ((nd6_opt_prefix_info[i])->validlt != 0)){ - ifaddr = uip_netif_addr_lookup(&(nd6_opt_prefix_info[i])->prefix, - (nd6_opt_prefix_info[i])->preflen, - AUTOCONF); - if(ifaddr != NULL) { - if((nd6_opt_prefix_info[i])->validlt != UIP_ND6_INFINITE_LIFETIME) { - /* The processing below is defined in RFC4862 section 5.5.3 e */ - if((ntohl((nd6_opt_prefix_info[i])->validlt) > 2 * 60 * 60) || - (ntohl((nd6_opt_prefix_info[i])->validlt)> stimer_remaining(&ifaddr->vlifetime))) { - PRINTF("Updating timer of address"); - PRINT6ADDR(&ifaddr->ipaddr); - PRINTF("new value %lu\n", ntohl((nd6_opt_prefix_info[i])->validlt)); - stimer_set(&ifaddr->vlifetime, ntohl((nd6_opt_prefix_info[i])->validlt)); - } else { - stimer_set(&ifaddr->vlifetime, 2 * 60 * 60); - - PRINTF("Updating timer of address "); - PRINT6ADDR(&ifaddr->ipaddr); - PRINTF("new value %lu\n", (unsigned long)(2 * 60 * 60)); - } - /*in case the address lifetime was previously infinite */ - ifaddr->is_infinite = 0; - } else { - ifaddr->is_infinite = 1; - } - } else { - /* Autoconfigure an address*/ - if((nd6_opt_prefix_info[i])->validlt != UIP_ND6_INFINITE_LIFETIME) { - /* Add an address with FINITE lifetime */ - uip_netif_addr_add(&(nd6_opt_prefix_info[i])->prefix, - (nd6_opt_prefix_info[i])->preflen, - ntohl((nd6_opt_prefix_info[i])->validlt), - AUTOCONF); - } else { - /* Add an address with INFINITE lifetime */ - uip_netif_addr_add(&(nd6_opt_prefix_info[i])->prefix, - (nd6_opt_prefix_info[i])->preflen, - 0, - AUTOCONF); - } - } - } - /* End of autonomous flag related processing */ - } - i++; - } - /* End of Prefix Information Option processing*/ - - - /* SLLAO option processing */ - neighbor = uip_nd6_nbrcache_lookup(&UIP_IP_BUF->srcipaddr); - if(nd6_opt_llao != NULL) { - PRINTF("Processing SLLAO option in RA\n"); - if(neighbor == NULL) { - neighbor = uip_nd6_nbrcache_add(&UIP_IP_BUF->srcipaddr, - &nd6_opt_llao->addr, 1, STALE); - } else { - if(neighbor->state == INCOMPLETE) { - neighbor->state = STALE; - } - /* check if there was an address change. it applies to the case - * where if the router ND entry was in state NO_STATE */ - if(memcmp(&nd6_opt_llao->addr, &neighbor->lladdr, UIP_LLADDR_LEN) != 0) { - memcpy(&neighbor->lladdr, &nd6_opt_llao->addr, UIP_LLADDR_LEN); - neighbor->state = STALE; - } - /*in case the neighbor was not a router before */ - neighbor->isrouter = 1; - } - } - - - /* - * As per RFC4861, section 6.3.4, and considering that in our - * implementation, a router entry contains a pointer to an existing - * neighbor entry: - * if router lifetime != 0, if entry present in def router list - * (and therefore neighbor cache), update timer, and update neighbor entry - * if needed - * else add entry to both router list (and neighbor cache if absent) - * else delete entry in router list if it exists - */ - if(UIP_ND6_RA_BUF->router_lifetime != 0) { - /* Add router or update timer, we need a neighbor entry for this */ - if(neighbor == NULL) { - neighbor = uip_nd6_nbrcache_add(&UIP_IP_BUF->srcipaddr, NULL, 1, NO_STATE); - } else { - /* in case the neighbor was not a router before */ - neighbor->isrouter = 1; - } - if((router = uip_nd6_defrouter_lookup(neighbor)) == NULL) { - uip_nd6_defrouter_add(neighbor, (unsigned long)(ntohs(UIP_ND6_RA_BUF->router_lifetime))); - } else { - stimer_set(&(router->lifetime), (unsigned long)(ntohs(UIP_ND6_RA_BUF->router_lifetime))); - } - } else { - /* delete router entry*/ - if(neighbor != NULL) { - router = uip_nd6_defrouter_lookup(neighbor); - if(router != NULL) { - uip_nd6_defrouter_rm(router); - } - } - } - -#if UIP_CONF_IPV6_QUEUE_PKT - /* - * If the neighbor just became reachable (e.g. it was in INCOMPLETE state - * and we got a SLLAO), check if we had buffered a pkt for it - */ - if((neighbor != NULL) && (neighbor->queue_buf_len != 0)) { - uip_len = neighbor->queue_buf_len; - memcpy(UIP_IP_BUF, neighbor->queue_buf, uip_len); - neighbor->queue_buf_len = 0; - return; - } -#endif /*UIP_CONF_IPV6_QUEUE_PKT*/ - uip_len = 0; - return; - - badpkt: - UIP_STAT(++uip_stat.nd6.drop); - UIP_LOG("RA received is bad"); - uip_len = 0; - return; -} - - -/** @} */ diff --git a/core/net/uip-nd6.c b/core/net/uip-nd6.c index 001e93180..30ee2980b 100644 --- a/core/net/uip-nd6.c +++ b/core/net/uip-nd6.c @@ -68,12 +68,13 @@ * */ +#include +#include "net/uip-icmp6.h" #include "net/uip-nd6.h" -#include "net/uip-netif.h" +#include "net/uip-ds6.h" #include "lib/random.h" -#include - +/*------------------------------------------------------------------*/ #define DEBUG 0 #if DEBUG #include @@ -89,386 +90,849 @@ #if UIP_LOGGING #include void uip_log(char *msg); + #define UIP_LOG(m) uip_log(m) #else #define UIP_LOG(m) #endif /* UIP_LOGGING == 1 */ -/** Remove a neighbor cache entry */ -#define uip_nd6_nbrcache_rm(neighbor) do { \ - PRINTF("Removing neighbor with ip addr"); \ - PRINT6ADDR(&neighbor->ipaddr); \ - PRINTF("\n"); \ - neighbor->used = 0; \ - } while(0) - - -/** - * \brief Timer for maintenance of neighbor cache, prefix list, and default - * router lists +/*------------------------------------------------------------------*/ +/** @{ */ +/** \name Pointers to the header structures. + * All pointers except UIP_IP_BUF depend on uip_ext_len, which at + * packet reception, is the total length of the extension headers. + * + * The pointer to ND6 options header also depends on nd6_opt_offset, + * which we set in each function. + * + * Care should be taken when manipulating these buffers about the + * value of these length variables */ -struct etimer uip_nd6_timer_periodic; -/** \brief Neighor cache */ -static struct uip_nd6_neighbor uip_nd6_nbrcache_list[UIP_CONF_ND6_MAX_NEIGHBORS]; -/** \brief Default router list */ -static struct uip_nd6_defrouter uip_nd6_defrouter_list[UIP_CONF_ND6_MAX_DEFROUTERS]; -/** \brief Prefix list */ -static struct uip_nd6_prefix uip_nd6_prefix_list[UIP_CONF_ND6_MAX_PREFIXES]; -/** \name Temp variables*/ -/** @{*/ -static u8_t i; -static struct uip_nd6_prefix *prefix; -static struct uip_nd6_neighbor *neighbor; -static struct uip_nd6_defrouter *router; -/** @}*/ - - -void -uip_nd6_init(void) -{ - /* INITIALIZE NEIGHBOR DISCOVERY*/ - for(i = 0; i < UIP_CONF_ND6_MAX_NEIGHBORS; i ++) { - uip_nd6_nbrcache_list[i].used = 0; - } - for(i = 0; i < UIP_CONF_ND6_MAX_DEFROUTERS; i ++) { - uip_nd6_defrouter_list[i].used = 0; - } - for(i = 0; i < UIP_CONF_ND6_MAX_PREFIXES; i ++) { - uip_nd6_prefix_list[i].used = 0; - } - - /* create link local prefix */ - uip_ip6addr(&(uip_nd6_prefix_list[0].ipaddr), 0xfe80, 0, 0, 0, 0, 0, 0, 0); - uip_nd6_prefix_list[0].length = UIP_DEFAULT_PREFIX_LEN; - uip_nd6_prefix_list[0].used = 1; - uip_nd6_prefix_list[0].is_infinite = 1; - - /* we check the ND structures every 100ms */ - etimer_set(&uip_nd6_timer_periodic, 0.1 * CLOCK_SECOND); -} - -struct uip_nd6_neighbor * -uip_nd6_nbrcache_lookup(uip_ipaddr_t *ipaddr) -{ - neighbor = NULL; - - for(i = 0; i < UIP_CONF_ND6_MAX_NEIGHBORS; i ++) { - if(uip_nd6_nbrcache_list[i].used == 0) { - continue; - } - if(uip_ipaddr_cmp(&uip_nd6_nbrcache_list[i].ipaddr, ipaddr)) { - neighbor = &uip_nd6_nbrcache_list[i]; - break; - } - } - return neighbor; -} - -struct uip_nd6_neighbor * -uip_nd6_nbrcache_add(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr, - u8_t isrouter, uip_neighbor_state state) -{ - neighbor = NULL; - - for(i = 0; i < UIP_CONF_ND6_MAX_NEIGHBORS; ++i) { - if(uip_nd6_nbrcache_list[i].used == 0) { - break; - } - } - if(i == UIP_CONF_ND6_MAX_NEIGHBORS){ - i = (u8_t)(random_rand()%UIP_CONF_ND6_MAX_NEIGHBORS); - UIP_LOG("CACHE FULL"); - } - - neighbor = &(uip_nd6_nbrcache_list[i]); - uip_ipaddr_copy(&(neighbor->ipaddr), ipaddr); - if(lladdr != NULL){ - memcpy(&(neighbor->lladdr), lladdr, UIP_LLADDR_LEN); - } else { - memset(&(neighbor->lladdr), 0, UIP_LLADDR_LEN); - } - PRINTF("Adding neighbor with ip addr"); - PRINT6ADDR(ipaddr); - PRINTF("link addr"); - PRINTLLADDR((&(neighbor->lladdr))); - PRINTF("state %u\n", state); - - neighbor->isrouter = isrouter; - neighbor->state = state; - /* timers are set separately, for now we put them in expired state */ - stimer_set(&(neighbor->reachable),0); - stimer_set(&(neighbor->last_send),0); - neighbor->count_send = 0; - neighbor->used = 1; - return neighbor; -} - - -struct uip_nd6_defrouter * -uip_nd6_defrouter_lookup(struct uip_nd6_neighbor *neighbor) -{ - router = NULL; - - for(i = 0; i < UIP_CONF_ND6_MAX_DEFROUTERS; i ++) { - if(uip_nd6_defrouter_list[i].used == 0) { - continue; - } - if(uip_nd6_defrouter_list[i].nb == neighbor) { - router = &uip_nd6_defrouter_list[i]; - break; - } - } - return router; -} - -struct uip_nd6_defrouter * -uip_nd6_choose_defrouter(void) -{ - router = NULL; - - for(i = 0; i < UIP_CONF_ND6_MAX_DEFROUTERS; i ++) { - if(uip_nd6_defrouter_list[i].used == 0) { - continue; - } - if(uip_nd6_defrouter_list[i].nb == NULL){ - continue; - } - if(uip_nd6_defrouter_list[i].nb->state == INCOMPLETE || - uip_nd6_defrouter_list[i].nb->state == NO_STATE){ - if(router == NULL) - router = &(uip_nd6_defrouter_list[i]); - } else { - router = &(uip_nd6_defrouter_list[i]); - break; - } - } - return router; -} - -void -uip_nd6_defrouter_rm(struct uip_nd6_defrouter *router) -{ - PRINTF("Removing defrouter with ip addr"); - PRINT6ADDR(&((router->nb)->ipaddr)); - PRINTF("\n"); - router->used = 0; - if(((router->nb)->state) == NO_STATE){ - /* Also remove the corresponding neighbor cache entry */ - uip_nd6_nbrcache_rm(router->nb); - } -} - -struct uip_nd6_defrouter * -uip_nd6_defrouter_add(struct uip_nd6_neighbor *neighbor, unsigned long interval) -{ - router = NULL; - - for(i = 0; i < UIP_CONF_ND6_MAX_DEFROUTERS; ++i) { - if(uip_nd6_defrouter_list[i].used == 0) { - break; - } - } - if(i == UIP_CONF_ND6_MAX_DEFROUTERS){ - UIP_LOG("Defrouter list full"); - i = (u8_t)(random_rand()%UIP_CONF_ND6_MAX_DEFROUTERS); - } - - router = &(uip_nd6_defrouter_list[i]); - router->nb = neighbor; - - PRINTF("Adding defrouter with ip addr"); - PRINT6ADDR(&neighbor->ipaddr); - PRINTF("\n"); - - stimer_set(&(router->lifetime),interval); - uip_nd6_defrouter_list[i].used = 1; - - return router; -} - -u8_t -uip_nd6_is_addr_onlink(uip_ipaddr_t *ipaddr) -{ - - for(i = 0; i < UIP_CONF_ND6_MAX_PREFIXES; i ++) { - if(uip_nd6_prefix_list[i].used == 0){ - continue; - } - if(uip_ipaddr_prefixcmp(&uip_nd6_prefix_list[i].ipaddr, - ipaddr, uip_nd6_prefix_list[i].length)){ - return 1; - } - } - return 0; -} - -struct uip_nd6_prefix * -uip_nd6_prefix_lookup(uip_ipaddr_t *ipaddr) -{ - prefix = NULL; - - for (i = 0; i < UIP_CONF_ND6_MAX_PREFIXES; i ++) { - if (uip_nd6_prefix_list[i].used == 0){ - continue; - } - if (uip_ipaddr_cmp(&uip_nd6_prefix_list[i].ipaddr, ipaddr)) { - prefix = &uip_nd6_prefix_list[i]; - break; - } - } - return prefix; -} - -struct uip_nd6_prefix * -uip_nd6_prefix_add(uip_ipaddr_t *ipaddr, u8_t length, unsigned long interval){ - - prefix = NULL; - - /* - * we start at 1: we do not want to overwrite the link local - * prefix - */ - for(i = 1; i < UIP_CONF_ND6_MAX_PREFIXES; ++i) { - if(uip_nd6_prefix_list[i].used == 0) { - break; - } - } - if(i == UIP_CONF_ND6_MAX_PREFIXES){ - UIP_LOG("Prefix list full"); - /* - * we do not want it to pick the first entry, which - * is the link local prefix - */ - i = (u8_t)(random_rand()%(UIP_CONF_ND6_MAX_PREFIXES -1) + 1); - PRINTF("Prefix list full, picking index %x\n\n", i); - } - prefix = &(uip_nd6_prefix_list[i]); - uip_ipaddr_copy(&(prefix->ipaddr), ipaddr); - prefix->length = length; - - PRINTF("Adding prefix "); - PRINT6ADDR(&prefix->ipaddr); - PRINTF("length %u, vlifetime%lu\n", length, interval); - - if(interval != 0){ - stimer_set(&(prefix->vlifetime),interval); - prefix->is_infinite = 0; - } else { - prefix->is_infinite = 1; - } - - uip_nd6_prefix_list[i].used = 1; - return prefix; -} - - -void uip_nd6_prefix_rm(struct uip_nd6_prefix *prefix) { - PRINTF("Removing prefix "); - PRINT6ADDR(&prefix->ipaddr); - PRINTF("length %u\n", prefix->length); - prefix->used = 0; -} - - -void -uip_nd6_periodic(void) -{ - - etimer_reset(&uip_nd6_timer_periodic); - - /*PERIODIC PROCESSING FOR DEFAULT ROUTER LIST*/ - router = NULL; - for(i = 0; i < UIP_CONF_ND6_MAX_DEFROUTERS; i ++) { - if(uip_nd6_defrouter_list[i].used == 1) { - router = &(uip_nd6_defrouter_list[i]); - - if(stimer_expired(&(router->lifetime))) { - uip_nd6_defrouter_rm(router); - } - - - } - } - /*PERIODIC PROCESSING FOR NEIGHBOR CACHE*/ - neighbor = NULL; - for(i = 0; i < UIP_CONF_ND6_MAX_NEIGHBORS; i ++) { - if(uip_nd6_nbrcache_list[i].used == 1) { - neighbor = &(uip_nd6_nbrcache_list[i]); - switch (neighbor->state) { - case INCOMPLETE: - if(neighbor->count_send >= UIP_ND6_MAX_MULTICAST_SOLICIT) { - uip_nd6_nbrcache_list[i].used = 0; - } - else if(stimer_expired(&(neighbor->last_send))) { - PRINTF("INCOMPLETE: NS %u\n",neighbor->count_send+1); - uip_nd6_io_ns_output(NULL, NULL, &neighbor->ipaddr); - stimer_set(&(neighbor->last_send), - uip_netif_physical_if.retrans_timer / 1000); - neighbor->count_send++; - } - break; - case REACHABLE: - if(stimer_expired(&(neighbor->reachable))) { - PRINTF("REACHABLE: moving to STALE ("); - PRINT6ADDR(&neighbor->ipaddr); - PRINTF(")\n"); - - neighbor->state = STALE; - neighbor->count_send = 0; - } - break; - case DELAY: - if(stimer_expired(&(neighbor->reachable))) { - neighbor->state = PROBE; - neighbor->count_send = 0; - PRINTF("DELAY: moving to PROBE + NS %u\n", neighbor->count_send+1); - uip_nd6_io_ns_output(NULL, &neighbor->ipaddr, &neighbor->ipaddr); - stimer_set(&(neighbor->last_send), - uip_netif_physical_if.retrans_timer / 1000); - neighbor->count_send++; - } - break; - case PROBE: - if(neighbor->count_send >= UIP_ND6_MAX_UNICAST_SOLICIT) { - PRINTF("PROBE END \n"); - neighbor->count_send = 0; - /* remove any corresponding default router (if any)*/ - router = uip_nd6_defrouter_lookup(neighbor); - if(router != NULL) - uip_nd6_defrouter_rm(router); - /* remove neighbor cache entry */ - uip_nd6_nbrcache_rm(neighbor); - continue; - } - if(stimer_expired(&(neighbor->last_send))){ - PRINTF("PROBE: NS %u\n",neighbor->count_send+1); - uip_nd6_io_ns_output(NULL, &neighbor->ipaddr, &neighbor->ipaddr); - stimer_set(&(neighbor->last_send), - uip_netif_physical_if.retrans_timer / 1000); - neighbor->count_send++; - } - break; - default: - break; - } - } - } - /*PERIODIC PROCESSING FOR PREFIX LIST*/ - prefix = NULL; - /* - * we start with i=1 because the first prefix is the link-local prefix - * and therefore has INFINITE an lifetime - */ - for(i = 1; i < UIP_CONF_ND6_MAX_PREFIXES; i ++) { - if(uip_nd6_prefix_list[i].used == 1) { - prefix = &(uip_nd6_prefix_list[i]); - if((prefix->is_infinite == 0) && - (stimer_expired(&(prefix->vlifetime)))) { - /* remove prefix */ - uip_nd6_prefix_rm(prefix); - } - } - } -} +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) /**< Pointer to IP header */ +#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) /**< Pointer to ICMP header*/ +/**@{ Pointers to messages just after icmp header */ +#define UIP_ND6_RS_BUF ((uip_nd6_rs *)&uip_buf[uip_l2_l3_icmp_hdr_len]) +#define UIP_ND6_RA_BUF ((uip_nd6_ra *)&uip_buf[uip_l2_l3_icmp_hdr_len]) +#define UIP_ND6_NS_BUF ((uip_nd6_ns *)&uip_buf[uip_l2_l3_icmp_hdr_len]) +#define UIP_ND6_NA_BUF ((uip_nd6_na *)&uip_buf[uip_l2_l3_icmp_hdr_len]) /** @} */ +/** Pointer to ND option */ +#define UIP_ND6_OPT_HDR_BUF ((uip_nd6_opt_hdr *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset]) +#define UIP_ND6_OPT_LLAO ((uip_nd6_opt_llao *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset]) +#define UIP_ND6_OPT_PREFIX_BUF ((uip_nd6_opt_prefix_info *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset]) +#define UIP_ND6_OPT_MTU_BUF ((uip_nd6_opt_mtu *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset]) +/** @} */ + +static u8_t nd6_opt_offset; /** Offset from the end of the icmpv6 header to the option in uip_buf*/ +static uip_nd6_opt_llao *nd6_opt_llao; /** Pointer to llao option in uip_buf */ + +#if !UIP_CONF_ROUTER // TBD see if we move it to ra_input +static uip_nd6_opt_prefix_info *nd6_opt_prefix_info; /** Pointer to prefix information option in uip_buf */ +#endif +static uip_ds6_nbr_t *nbr; /** Pointer to a nbr cache entry*/ +static uip_ds6_prefix_t *prefix; /** Pointer to a prefix list entry */ +static uip_ds6_defrt_t *defrt; /** Pointer to a router list entry */ +static uip_ds6_addr_t *addr; /** Pointer to an interface address */ + +/*------------------------------------------------------------------*/ + + +void +uip_nd6_ns_input(void) +{ + PRINTF("Received NS from"); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF("to"); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF("with target address"); + PRINT6ADDR((uip_ipaddr_t *) (&UIP_ND6_NS_BUF->tgtipaddr)); + PRINTF("\n"); + UIP_STAT(++uip_stat.nd6.recv); + + u8_t flags; + +#if UIP_CONF_IPV6_CHECKS + if((UIP_IP_BUF->ttl != UIP_ND6_HOP_LIMIT) || + (uip_is_addr_mcast(&UIP_ND6_NS_BUF->tgtipaddr)) || + (UIP_ICMP_BUF->icode != 0)) { + PRINTF("NS received is bad\n"); + goto discard; + } +#endif /* UIP_CONF_IPV6_CHECKS */ + + /* Options processing */ + nd6_opt_llao = NULL; + nd6_opt_offset = UIP_ND6_NS_LEN; + while(uip_l3_icmp_hdr_len + nd6_opt_offset < uip_len) { +#if UIP_CONF_IPV6_CHECKS + if(UIP_ND6_OPT_HDR_BUF->len == 0) { + PRINTF("NS received is bad\n"); + goto discard; + } +#endif /* UIP_CONF_IPV6_CHECKS */ + switch (UIP_ND6_OPT_HDR_BUF->type) { + case UIP_ND6_OPT_SLLAO: + nd6_opt_llao = + (struct uip_nd6_opt_llao *)&uip_buf[uip_l2_l3_icmp_hdr_len + + nd6_opt_offset]; +#if UIP_CONF_IPV6_CHECKS + /* There must be NO option in a DAD NS */ + if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) { + PRINTF("NS received is bad\n"); + goto discard; + } else { +#endif /*UIP_CONF_IPV6_CHECKS */ + nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr); + if(nbr == NULL) { + uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, + &nd6_opt_llao->addr, 0, NBR_STALE); + } else { + if(memcmp(&nd6_opt_llao->addr, &nbr->lladdr, UIP_LLADDR_LEN) != 0) { + memcpy(&nbr->lladdr, &nd6_opt_llao->addr, UIP_LLADDR_LEN); + nbr->state = NBR_STALE; + } else { + if(nbr->state == NBR_INCOMPLETE) { + nbr->state = NBR_STALE; + } + } + } +#if UIP_CONF_IPV6_CHECKS + } +#endif /*UIP_CONF_IPV6_CHECKS */ + break; + default: + PRINTF("ND option not supported in NS"); + break; + } + nd6_opt_offset += (UIP_ND6_OPT_HDR_BUF->len << 3); + } + + addr = uip_ds6_addr_lookup(&UIP_ND6_NS_BUF->tgtipaddr); + if(addr != NULL) { + if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) { + /* DAD CASE */ +#if UIP_CONF_IPV6_CHECKS + if(!uip_is_addr_solicited_node(&UIP_IP_BUF->destipaddr)) { + PRINTF("NS received is bad\n"); + goto discard; + } +#endif /* UIP_CONF_IPV6_CHECKS */ + if(addr->state != ADDR_TENTATIVE) { + uip_create_linklocal_allnodes_mcast(&UIP_IP_BUF->destipaddr); + uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); + flags = UIP_ND6_NA_FLAG_OVERRIDE; + goto create_na; + } else { + /** \todo if I sent a NS before him, I win */ + uip_ds6_dad_failed(addr); + goto discard; + } + } +#if UIP_CONF_IPV6_CHECKS + if(uip_ds6_is_my_addr(&UIP_IP_BUF->srcipaddr)) { + /** + * \NOTE do we do something here? we both are using the same address. + * If we are doing dad, we could cancel it, though we should receive a + * NA in response of DAD NS we sent, hence DAD will fail anyway. If we + * were not doing DAD, it means there is a duplicate in the network! + */ + PRINTF("NS received is bad\n"); + goto discard; + } +#endif /*UIP_CONF_IPV6_CHECKS */ + + /* Address resolution case */ + if(uip_is_addr_solicited_node(&UIP_IP_BUF->destipaddr)) { + uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &UIP_IP_BUF->srcipaddr); + uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &UIP_ND6_NS_BUF->tgtipaddr); + flags = UIP_ND6_NA_FLAG_SOLICITED | UIP_ND6_NA_FLAG_OVERRIDE; + goto create_na; + } + + /* NUD CASE */ + if(uip_ds6_addr_lookup(&UIP_IP_BUF->destipaddr) == addr) { + uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &UIP_IP_BUF->srcipaddr); + uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &UIP_ND6_NS_BUF->tgtipaddr); + flags = UIP_ND6_NA_FLAG_SOLICITED | UIP_ND6_NA_FLAG_OVERRIDE; + goto create_na; + } else { +#if UIP_CONF_IPV6_CHECKS + PRINTF("NS received is bad\n"); + goto discard; +#endif /* UIP_CONF_IPV6_CHECKS */ + } + } else { + goto discard; + } + + +create_na: + uip_ext_len = 0; + UIP_IP_BUF->vtc = 0x60; + UIP_IP_BUF->tcflow = 0; + UIP_IP_BUF->flow = 0; + UIP_IP_BUF->len[0] = 0; /* length will not be more than 255 */ + UIP_IP_BUF->len[1] = UIP_ICMPH_LEN + UIP_ND6_NA_LEN + UIP_ND6_OPT_LLAO_LEN; + UIP_IP_BUF->proto = UIP_PROTO_ICMP6; + UIP_IP_BUF->ttl = UIP_ND6_HOP_LIMIT; + + UIP_ICMP_BUF->type = ICMP6_NA; + UIP_ICMP_BUF->icode = 0; + + UIP_ND6_NA_BUF->flagsreserved = flags; + memcpy(&UIP_ND6_NA_BUF->tgtipaddr, &addr->ipaddr, sizeof(uip_ipaddr_t)); + + nd6_opt_llao = + (struct uip_nd6_opt_llao *)&uip_buf[uip_l2_l3_icmp_hdr_len + + UIP_ND6_NA_LEN]; + nd6_opt_llao->type = UIP_ND6_OPT_TLLAO; + nd6_opt_llao->len = UIP_ND6_OPT_LLAO_LEN >> 3; + memcpy(&(nd6_opt_llao->addr), &uip_lladdr, UIP_LLADDR_LEN); + /* padding on some */ + memset((void *)(&nd6_opt_llao->addr) + UIP_LLADDR_LEN, 0, + UIP_ND6_OPT_LLAO_LEN - 2 - UIP_LLADDR_LEN); + + UIP_ICMP_BUF->icmpchksum = 0; + UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); + + uip_len = + UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NA_LEN + UIP_ND6_OPT_LLAO_LEN; + + UIP_STAT(++uip_stat.nd6.sent); + PRINTF("Sending NA to"); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF("from"); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF("with target address"); + PRINT6ADDR(&UIP_ND6_NA_BUF->tgtipaddr); + PRINTF("\n"); + return; + +discard: + uip_len = 0; + return; +} + + + +/*------------------------------------------------------------------*/ +void +uip_nd6_ns_output(uip_ipaddr_t * src, uip_ipaddr_t * dest, uip_ipaddr_t * tgt) +{ + uip_ext_len = 0; + UIP_IP_BUF->vtc = 0x60; + UIP_IP_BUF->tcflow = 0; + UIP_IP_BUF->flow = 0; + UIP_IP_BUF->proto = UIP_PROTO_ICMP6; + UIP_IP_BUF->ttl = UIP_ND6_HOP_LIMIT; + + if(dest == NULL) { + uip_create_solicited_node(tgt, &UIP_IP_BUF->destipaddr); + } else { + uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, dest); + } + UIP_ICMP_BUF->type = ICMP6_NS; + UIP_ICMP_BUF->icode = 0; + UIP_ND6_NS_BUF->reserved = 0; + uip_ipaddr_copy((uip_ipaddr_t *) & UIP_ND6_NS_BUF->tgtipaddr, tgt); + UIP_IP_BUF->len[0] = 0; /* length will not be more than 255 */ + /* + * check if we add a SLLAO option: for DAD, MUST NOT, for NUD, MAY + * (here yes), for Address resolution , MUST + */ + if(!(uip_ds6_is_my_addr(tgt))) { + if(src != NULL) { + uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, src); + } else { + uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); + } + UIP_IP_BUF->len[1] = + UIP_ICMPH_LEN + UIP_ND6_NS_LEN + UIP_ND6_OPT_LLAO_LEN; + nd6_opt_llao = + (struct uip_nd6_opt_llao *)&uip_buf[uip_l2_l3_icmp_hdr_len + + UIP_ND6_NS_LEN]; + nd6_opt_llao->type = UIP_ND6_OPT_SLLAO; /* type of the option */ + nd6_opt_llao->len = UIP_ND6_OPT_LLAO_LEN >> 3; + memcpy(&nd6_opt_llao->addr, &uip_lladdr, UIP_LLADDR_LEN); + /* padding on some */ + memset((void *)(&nd6_opt_llao->addr) + UIP_LLADDR_LEN, 0, + UIP_ND6_OPT_LLAO_LEN - 2 - UIP_LLADDR_LEN); + uip_len = + UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NS_LEN + UIP_ND6_OPT_LLAO_LEN; + } else { + uip_create_unspecified(&UIP_IP_BUF->srcipaddr); + UIP_IP_BUF->len[1] = UIP_ICMPH_LEN + UIP_ND6_NS_LEN; + uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NS_LEN; + } + + UIP_ICMP_BUF->icmpchksum = 0; + UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); + + UIP_STAT(++uip_stat.nd6.sent); + PRINTF("Sending NS to"); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF("from"); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF("with target address"); + PRINT6ADDR(tgt); + PRINTF("\n"); + return; +} + + + +/*------------------------------------------------------------------*/ +void +uip_nd6_na_input(void) +{ + PRINTF("Received NA from"); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF("to"); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF("with target address"); + PRINT6ADDR((uip_ipaddr_t *) (&UIP_ND6_NA_BUF->tgtipaddr)); + PRINTF("\n"); + UIP_STAT(++uip_stat.nd6.recv); + + /* + * booleans. the three last one are not 0 or 1 but 0 or 0x80, 0x40, 0x20 + * but it works. Be careful though, do not use tests such as is_router == 1 + */ + u8_t is_llchange = 0; + u8_t is_router = ((UIP_ND6_NA_BUF->flagsreserved & UIP_ND6_NA_FLAG_ROUTER)); + u8_t is_solicited = + ((UIP_ND6_NA_BUF->flagsreserved & UIP_ND6_NA_FLAG_SOLICITED)); + u8_t is_override = + ((UIP_ND6_NA_BUF->flagsreserved & UIP_ND6_NA_FLAG_OVERRIDE)); + +#if UIP_CONF_IPV6_CHECKS + if((UIP_IP_BUF->ttl != UIP_ND6_HOP_LIMIT) || + (UIP_ICMP_BUF->icode != 0) || + (uip_is_addr_mcast(&UIP_ND6_NA_BUF->tgtipaddr)) || + (is_solicited && uip_is_addr_mcast(&UIP_IP_BUF->destipaddr))) { + PRINTF("NA received is bad\n"); + goto discard; + } +#endif /*UIP_CONF_IPV6_CHECKS */ + + /* Options processing: we handle TLLAO, and must ignore others */ + nd6_opt_offset = UIP_ND6_NA_LEN; + nd6_opt_llao = NULL; + while(uip_l3_icmp_hdr_len + nd6_opt_offset < uip_len) { +#if UIP_CONF_IPV6_CHECKS + if(UIP_ND6_OPT_HDR_BUF->len == 0) { + PRINTF("NA received is bad\n"); + goto discard; + } +#endif /*UIP_CONF_IPV6_CHECKS */ + switch (UIP_ND6_OPT_HDR_BUF->type) { + case UIP_ND6_OPT_TLLAO: + nd6_opt_llao = (struct uip_nd6_opt_llao *)UIP_ND6_OPT_HDR_BUF; + break; + default: + PRINTF("ND option not supported in NA\n"); + break; + } + nd6_opt_offset += (UIP_ND6_OPT_HDR_BUF->len << 3); + } + addr = uip_ds6_addr_lookup(&UIP_ND6_NA_BUF->tgtipaddr); + /* Message processing, including TLLAO if any */ + if(addr != NULL) { + if(addr->state == ADDR_TENTATIVE) { + uip_ds6_dad_failed(addr); + } + PRINTF("NA received is bad\n"); + goto discard; + } else { + nbr = uip_ds6_nbr_lookup(&UIP_ND6_NA_BUF->tgtipaddr); + if(nbr == NULL) { + goto discard; + } + if(nd6_opt_llao != 0) { + is_llchange = + memcmp((void *)&nd6_opt_llao->addr, (void *)(&nbr->lladdr), + UIP_LLADDR_LEN); + } + if(nbr->state == NBR_INCOMPLETE) { + if(nd6_opt_llao == NULL) { + goto discard; + } + memcpy(&nbr->lladdr, &nd6_opt_llao->addr, UIP_LLADDR_LEN); + if(is_solicited) { + nbr->state = NBR_REACHABLE; + nbr->nscount = 0; + + /* reachable time is stored in ms */ + stimer_set(&(nbr->reachable), uip_ds6_if.reachable_time / 1000); + + } else { + nbr->state = NBR_STALE; + } + nbr->isrouter = is_router; + } else { + if(!is_override && is_llchange) { + if(nbr->state == NBR_REACHABLE) { + nbr->state = NBR_STALE; + } + goto discard; + } else { + if(is_override || (!is_override && nd6_opt_llao != 0 && !is_llchange) + || nd6_opt_llao == 0) { + if(nd6_opt_llao != 0) { + memcpy(&nbr->lladdr, &nd6_opt_llao->addr, UIP_LLADDR_LEN); + } + if(is_solicited) { + nbr->state = NBR_REACHABLE; + /* reachable time is stored in ms */ + stimer_set(&(nbr->reachable), uip_ds6_if.reachable_time / 1000); + } else { + if(nd6_opt_llao != 0 && is_llchange) { + nbr->state = NBR_STALE; + } + } + } + } + if(nbr->isrouter && !is_router) { + defrt = uip_ds6_defrt_lookup(&UIP_IP_BUF->srcipaddr); + if(defrt != NULL) { + uip_ds6_defrt_rm(defrt); + } + } + nbr->isrouter = is_router; + } + } +#if UIP_CONF_IPV6_QUEUE_PKT + /* The nbr is now reachable, check if we had buffered a pkt for it */ + if(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; + } +#endif /*UIP_CONF_IPV6_QUEUE_PKT */ + +discard: + uip_len = 0; + return; +} + + +#if UIP_CONF_ROUTER +#if UIP_ND6_SEND_RA +/*---------------------------------------------------------------------------*/ +void +uip_nd6_rs_input(void) +{ + + PRINTF("Received RS 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 + /* + * Check hop limit / icmp code + * target address must not be multicast + * if the NA is solicited, dest must not be multicast + */ + if((UIP_IP_BUF->ttl != UIP_ND6_HOP_LIMIT) || (UIP_ICMP_BUF->icode != 0)) { + PRINTF("RS received is bad\n"); + goto discard; + } +#endif /*UIP_CONF_IPV6_CHECKS */ + + /* Only valid option is Source Link-Layer Address option any thing + else is discarded */ + nd6_opt_offset = UIP_ND6_RS_LEN; + nd6_opt_llao = NULL; + + while(uip_l3_icmp_hdr_len + nd6_opt_offset < uip_len) { +#if UIP_CONF_IPV6_CHECKS + if(UIP_ND6_OPT_HDR_BUF->len == 0) { + PRINTF("RS received is bad\n"); + goto discard; + } +#endif /*UIP_CONF_IPV6_CHECKS */ + switch (UIP_ND6_OPT_HDR_BUF->type) { + case UIP_ND6_OPT_SLLAO: + nd6_opt_llao = (struct uip_nd6_opt_llao *)UIP_ND6_OPT_HDR_BUF; + break; + default: + PRINTF("ND option not supported in RS\n"); + break; + } + nd6_opt_offset += (UIP_ND6_OPT_HDR_BUF->len << 3); + } + /* Options processing: only SLLAO */ + if(nd6_opt_llao != NULL) { +#if UIP_CONF_IPV6_CHECKS + if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) { + PRINTF("RS received is bad\n"); + goto discard; + } else { +#endif /*UIP_CONF_IPV6_CHECKS */ + if((nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr)) == NULL) { + /* we need to add the neighbor */ + uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, + &nd6_opt_llao->addr, 0, NBR_STALE); + } else { + /* If LL address changed, set neighbor state to stale */ + if(memcmp(&nd6_opt_llao->addr, &nbr->lladdr, UIP_LLADDR_LEN) != 0) { + memcpy(&nbr->lladdr, &nd6_opt_llao->addr, UIP_LLADDR_LEN); + nbr->state = NBR_STALE; + } + nbr->isrouter = 0; + } +#if UIP_CONF_IPV6_CHECKS + } +#endif /*UIP_CONF_IPV6_CHECKS */ + } + + /* Schedule a sollicited RA */ + uip_ds6_send_ra_sollicited(); + +discard: + uip_len = 0; + return; +} + +/*---------------------------------------------------------------------------*/ +void +uip_nd6_ra_output(uip_ipaddr_t * dest) +{ + + UIP_IP_BUF->vtc = 0x60; + UIP_IP_BUF->tcflow = 0; + UIP_IP_BUF->flow = 0; + UIP_IP_BUF->proto = UIP_PROTO_ICMP6; + UIP_IP_BUF->ttl = UIP_ND6_HOP_LIMIT; + + if(dest == NULL) { + uip_create_linklocal_allnodes_mcast(&UIP_IP_BUF->destipaddr); + } else { + /* For sollicited RA */ + uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, dest); + } + uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); + + UIP_ICMP_BUF->type = ICMP6_RA; + UIP_ICMP_BUF->icode = 0; + + UIP_ND6_RA_BUF->cur_ttl = uip_ds6_if.cur_hop_limit; + + UIP_ND6_RA_BUF->flags_reserved = + (UIP_ND6_M_FLAG << 7) | (UIP_ND6_O_FLAG << 6); + + UIP_ND6_RA_BUF->router_lifetime = htons(UIP_ND6_ROUTER_LIFETIME); + //UIP_ND6_RA_BUF->reachable_time = htonl(uip_ds6_if.reachable_time); + //UIP_ND6_RA_BUF->retrans_timer = htonl(uip_ds6_if.retrans_timer); + UIP_ND6_RA_BUF->reachable_time = 0; + UIP_ND6_RA_BUF->retrans_timer = 0; + + uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_RA_LEN; + nd6_opt_offset = UIP_ND6_RA_LEN; + + + /* Prefix list */ + for(prefix = uip_ds6_prefix_list; + prefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; prefix++) { + if((prefix->isused) && (prefix->advertise)) { + UIP_ND6_OPT_PREFIX_BUF->type = UIP_ND6_OPT_PREFIX_INFO; + UIP_ND6_OPT_PREFIX_BUF->len = UIP_ND6_OPT_PREFIX_INFO_LEN / 8; + UIP_ND6_OPT_PREFIX_BUF->preflen = prefix->length; + UIP_ND6_OPT_PREFIX_BUF->flagsreserved1 = prefix->l_a_reserved; + UIP_ND6_OPT_PREFIX_BUF->validlt = htonl(prefix->vlifetime); + UIP_ND6_OPT_PREFIX_BUF->preferredlt = htonl(prefix->plifetime); + UIP_ND6_OPT_PREFIX_BUF->reserved2 = 0; + uip_ipaddr_copy(&(UIP_ND6_OPT_PREFIX_BUF->prefix), &(prefix->ipaddr)); + nd6_opt_offset += UIP_ND6_OPT_PREFIX_INFO_LEN; + uip_len += UIP_ND6_OPT_PREFIX_INFO_LEN; + } + } + + /* Source link-layer option */ + nd6_opt_llao = (struct uip_nd6_opt_llao *)UIP_ND6_OPT_HDR_BUF; + nd6_opt_llao->type = UIP_ND6_OPT_SLLAO; + nd6_opt_llao->len = UIP_ND6_OPT_LLAO_LEN >> 3; + memcpy(&(nd6_opt_llao->addr), &uip_lladdr, UIP_LLADDR_LEN); + /* padding if needed */ + memset((void *)(&nd6_opt_llao->addr) + UIP_LLADDR_LEN, 0, + UIP_ND6_OPT_LLAO_LEN - 2 - UIP_LLADDR_LEN); + + uip_len += UIP_ND6_OPT_LLAO_LEN; + nd6_opt_offset += UIP_ND6_OPT_LLAO_LEN; + + /* MTU */ + UIP_ND6_OPT_MTU_BUF->type = UIP_ND6_OPT_MTU; + UIP_ND6_OPT_MTU_BUF->len = UIP_ND6_OPT_MTU_LEN >> 3; + UIP_ND6_OPT_MTU_BUF->reserved = 0; + //UIP_ND6_OPT_MTU_BUF->mtu = htonl(uip_ds6_if.link_mtu); + UIP_ND6_OPT_MTU_BUF->mtu = htonl(1500); + + uip_len += UIP_ND6_OPT_MTU_LEN; + nd6_opt_offset += UIP_ND6_OPT_MTU_LEN; + UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); + UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); + + /*ICMP checksum */ + UIP_ICMP_BUF->icmpchksum = 0; + UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); + + UIP_STAT(++uip_stat.nd6.sent); + PRINTF("Sending RA to"); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF("from"); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF("\n"); + return; +} +#endif /* UIP_ND6_SEND_RA */ +#endif /* UIP_CONF_ROUTER */ + +#if !UIP_CONF_ROUTER +/*---------------------------------------------------------------------------*/ +void +uip_nd6_rs_output(void) +{ + UIP_IP_BUF->vtc = 0x60; + UIP_IP_BUF->tcflow = 0; + UIP_IP_BUF->flow = 0; + UIP_IP_BUF->proto = UIP_PROTO_ICMP6; + UIP_IP_BUF->ttl = UIP_ND6_HOP_LIMIT; + uip_create_linklocal_allrouters_mcast(&UIP_IP_BUF->destipaddr); + uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); + UIP_ICMP_BUF->type = ICMP6_RS; + UIP_ICMP_BUF->icode = 0; + UIP_IP_BUF->len[0] = 0; /* length will not be more than 255 */ + + if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) { + UIP_IP_BUF->len[1] = UIP_ICMPH_LEN + UIP_ND6_RS_LEN; + uip_len = uip_l3_icmp_hdr_len + UIP_ND6_RS_LEN; + } else { + uip_len = uip_l3_icmp_hdr_len + UIP_ND6_RS_LEN + UIP_ND6_OPT_LLAO_LEN; + UIP_IP_BUF->len[1] = + UIP_ICMPH_LEN + UIP_ND6_RS_LEN + UIP_ND6_OPT_LLAO_LEN; + nd6_opt_llao = + (struct uip_nd6_opt_llao *)&uip_buf[uip_l2_l3_icmp_hdr_len + + UIP_ND6_RS_LEN]; + nd6_opt_llao->type = UIP_ND6_OPT_SLLAO; /* type of the option */ + nd6_opt_llao->len = UIP_ND6_OPT_LLAO_LEN >> 3; + memcpy(&nd6_opt_llao->addr, &uip_lladdr, UIP_LLADDR_LEN); + /* padding on some link layers */ + memset((void *)(&nd6_opt_llao->addr) + UIP_LLADDR_LEN, 0, + UIP_ND6_OPT_LLAO_LEN - 2 - UIP_LLADDR_LEN); + } + + UIP_ICMP_BUF->icmpchksum = 0; + UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); + + UIP_STAT(++uip_stat.nd6.sent); + PRINTF("Sendin RS to"); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF("from"); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF("\n"); + return; +} + + +/*---------------------------------------------------------------------------*/ +void +uip_nd6_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 != + ntohl(UIP_ND6_RA_BUF->reachable_time)) { + uip_ds6_if.base_reachable_time = 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 = 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 = (uip_nd6_opt_llao *) 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, + &nd6_opt_llao->addr, 1, NBR_STALE); + } else { + if(nbr->state == NBR_INCOMPLETE) { + nbr->state = NBR_STALE; + } + if(memcmp(&nd6_opt_llao->addr, &nbr->lladdr, UIP_LLADDR_LEN) != 0) { + memcpy(&nbr->lladdr, &nd6_opt_llao->addr, 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 = + 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((ntohl(nd6_opt_prefix_info->validlt) >= + 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, + 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", ntohl(nd6_opt_prefix_info->validlt)); + stimer_set(&prefix->vlifetime, + 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((ntohl(nd6_opt_prefix_info->validlt) > 2 * 60 * 60) || + (ntohl(nd6_opt_prefix_info->validlt) > + stimer_remaining(&addr->vlifetime))) { + PRINTF("Updating timer of address"); + PRINT6ADDR(&addr->ipaddr); + PRINTF("new value %lu\n", + ntohl(nd6_opt_prefix_info->validlt)); + stimer_set(&addr->vlifetime, + 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(ntohl(nd6_opt_prefix_info->validlt) == + UIP_ND6_INFINITE_LIFETIME) { + uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); + } else { + uip_ds6_addr_add(&ipaddr, 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)(ntohs(UIP_ND6_RA_BUF->router_lifetime))); + } else { + stimer_set(&(defrt->lifetime), + (unsigned long)(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; + } +#endif /*UIP_CONF_IPV6_QUEUE_PKT */ + +discard: + uip_len = 0; + return; +} +#endif /* !UIP_CONF_ROUTER */ + + /** @} */ diff --git a/core/net/uip-nd6.h b/core/net/uip-nd6.h index 9caf36e68..c61b90e30 100644 --- a/core/net/uip-nd6.h +++ b/core/net/uip-nd6.h @@ -477,7 +477,7 @@ void * */ void -uip_nd6_io_ns_input(void); +uip_nd6_ns_input(void); /** * \brief Send a neighbor solicitation, send a Neighbor Advertisement @@ -500,7 +500,7 @@ uip_nd6_io_ns_input(void); * a SLLAO option, otherwise no. */ void -uip_nd6_io_ns_output(uip_ipaddr_t *src, uip_ipaddr_t *dest, uip_ipaddr_t *tgt); +uip_nd6_ns_output(uip_ipaddr_t *src, uip_ipaddr_t *dest, uip_ipaddr_t *tgt); /** * \brief Process a Neighbor Advertisement @@ -520,7 +520,7 @@ uip_nd6_io_ns_output(uip_ipaddr_t *src, uip_ipaddr_t *dest, uip_ipaddr_t *tgt); * */ void -uip_nd6_io_na_input(void); +uip_nd6_na_input(void); #if UIP_CONF_ROUTER #if UIP_ND6_SEND_RA @@ -550,7 +550,7 @@ void uip_nd6_ra_output(uip_ipaddr_t *dest); * possible option is SLLAO, MUST NOT be included if source = unspecified * SHOULD be included otherwise */ -void uip_nd6_io_rs_output(void); +void uip_nd6_rs_output(void); /** * @@ -563,7 +563,7 @@ void uip_nd6_io_rs_output(void); * - If prefix option: start autoconf, add prefix to prefix list */ void -uip_nd6_io_ra_input(void); +uip_nd6_ra_input(void); /** @} */ diff --git a/core/net/uip-netif.c b/core/net/uip-netif.c deleted file mode 100644 index 0684ba49a..000000000 --- a/core/net/uip-netif.c +++ /dev/null @@ -1,424 +0,0 @@ -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * Network interface and stateless autoconfiguration (RFC 4862) - * \author Mathilde Durvy - * \author Julien Abeille - * - */ - -/* - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * - */ - -#include "net/uip-nd6.h" -#include "net/uip-netif.h" -#include "lib/random.h" - -#include -#include - - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((u8_t *)addr)[0], ((u8_t *)addr)[1], ((u8_t *)addr)[2], ((u8_t *)addr)[3], ((u8_t *)addr)[4], ((u8_t *)addr)[5], ((u8_t *)addr)[6], ((u8_t *)addr)[7], ((u8_t *)addr)[8], ((u8_t *)addr)[9], ((u8_t *)addr)[10], ((u8_t *)addr)[11], ((u8_t *)addr)[12], ((u8_t *)addr)[13], ((u8_t *)addr)[14], ((u8_t *)addr)[15]) -#define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",lladdr->addr[0], lladdr->addr[1], lladdr->addr[2], lladdr->addr[3],lladdr->addr[4], lladdr->addr[5]) -#else -#define PRINTF(...) -#define PRINT6ADDR(addr) -#define PRINTLLADDR(lladdr) -#endif - -#if UIP_LOGGING -#include -void uip_log(char *msg); -#define UIP_LOG(m) uip_log(m) -#else -#define UIP_LOG(m) -#endif /* UIP_LOGGING == 1 */ - -/*---------------------------------------------------------------------------*/ -/** \brief The single physical interface */ -struct uip_netif uip_netif_physical_if; -/** \brief DAD timer */ -struct etimer uip_netif_timer_dad; -/** \brief The interface address on which dad is being performed */ -static struct uip_netif_addr *dad_ifaddr; -/** \brief Number of ns already sent for DAD*/ -static u8_t dad_ns; -/** \brief RS timer, to schedule RS sending */ -struct etimer uip_netif_timer_rs; -/** \brief number of rs already sent */ -static u8_t rs_count; -/** \brief index for loops */ -static u8_t i; -/** \brief timer to check the address states */ -struct etimer uip_netif_timer_periodic; - - -/** \brief remove an interface address, argument type is uip_netif_addr* */ -#define uip_netif_addr_rm(addr) do { \ - PRINTF("Removing address"); \ - PRINT6ADDR(&addr->ipaddr); \ - PRINTF("\n"); \ - addr->state = NOT_USED; \ - } while(0) -/*---------------------------------------------------------------------------*/ -void -uip_netif_init(void) -{ - /* INITIALIZE INTERFACE (default values for now) */ - uip_netif_physical_if.link_mtu = UIP_LINK_MTU; - uip_netif_physical_if.cur_hop_limit = UIP_TTL; - uip_netif_physical_if.base_reachable_time = UIP_ND6_REACHABLE_TIME; - uip_netif_physical_if.reachable_time = uip_netif_compute_reachable_time(); - uip_netif_physical_if.retrans_timer = UIP_ND6_RETRANS_TIMER; - uip_netif_physical_if.dup_addr_detect_transmit = 1; - - /* - * STATELESS AUTOCONFIGURATION of the link local address. We set it to - * infinite (this will become really true once DAD succeeds) - */ - uip_ip6addr(&(uip_netif_physical_if.addresses[0].ipaddr), - 0xfe80,0,0,0,0,0,0,0); - uip_netif_addr_autoconf_set(&(uip_netif_physical_if.addresses[0].ipaddr), &uip_lladdr); - uip_netif_physical_if.addresses[0].state = TENTATIVE; - uip_netif_physical_if.addresses[0].type = MANUAL; - uip_netif_physical_if.addresses[0].is_infinite = 1; - - /* set all other addresses to NOT_USED initialy */ - for(i = 1; i < UIP_CONF_NETIF_MAX_ADDRESSES; i ++) { - uip_netif_physical_if.addresses[i].state = NOT_USED; - } - - uip_ip6addr_u8(&(uip_netif_physical_if.solicited_node_mcastaddr), - 0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0xff, - uip_lladdr.addr[UIP_LLADDR_LEN - 3], - uip_lladdr.addr[UIP_LLADDR_LEN - 2], - uip_lladdr.addr[UIP_LLADDR_LEN - 1]); - /* Start DAD */ - uip_netif_sched_dad(&(uip_netif_physical_if.addresses[0])); - - /* Find router (send rs to all-routers multicast group)) */ - uip_netif_sched_send_rs(); - - /* Reset the timer */ - etimer_set(&uip_netif_timer_periodic, CLOCK_SECOND); -} -/*---------------------------------------------------------------------------*/ -void -uip_netif_periodic(void) -{ - for(i = 1; i < UIP_CONF_NETIF_MAX_ADDRESSES; i++) { - if((uip_netif_physical_if.addresses[i].state != NOT_USED) && - (uip_netif_physical_if.addresses[i].is_infinite != 1) && - (stimer_expired(&uip_netif_physical_if.addresses[i].vlifetime))) { - uip_netif_addr_rm((&uip_netif_physical_if.addresses[i])); - } - } - etimer_reset(&uip_netif_timer_periodic); - return; -} - -/*---------------------------------------------------------------------------*/ -u32_t -uip_netif_compute_reachable_time(void) -{ - return (u32_t)(UIP_ND6_MIN_RANDOM_FACTOR(uip_netif_physical_if.base_reachable_time)) + - ((u16_t)(random_rand() << 8) + (u16_t)random_rand()) % - (u32_t)(UIP_ND6_MAX_RANDOM_FACTOR(uip_netif_physical_if.base_reachable_time) - - UIP_ND6_MIN_RANDOM_FACTOR(uip_netif_physical_if.base_reachable_time)); -} -/*---------------------------------------------------------------------------*/ -u8_t -uip_netif_is_addr_my_solicited(uip_ipaddr_t *ipaddr) -{ - if(uip_ipaddr_cmp(ipaddr, &uip_netif_physical_if.solicited_node_mcastaddr)) { - return 1; - } - return 0; -} -/*---------------------------------------------------------------------------*/ -struct uip_netif_addr * -uip_netif_addr_lookup(uip_ipaddr_t *ipaddr, u8_t length, uip_netif_type type) -{ - for(i = 0; i < UIP_CONF_NETIF_MAX_ADDRESSES; i ++) { - if((uip_netif_physical_if.addresses[i].state != NOT_USED) && - (uip_netif_physical_if.addresses[i].type == type || type == 0) && - (uip_ipaddr_prefixcmp(&(uip_netif_physical_if.addresses[i].ipaddr), ipaddr, length))) { - return &uip_netif_physical_if.addresses[i]; - } - } - return NULL; -} -/*---------------------------------------------------------------------------*/ -void -uip_netif_addr_add(uip_ipaddr_t *ipaddr, u8_t length, unsigned long vlifetime, uip_netif_type type) { - - /* check prefix has the right length if we are doing autoconf */ - if((type == AUTOCONF) && (length != UIP_DEFAULT_PREFIX_LEN)) { - UIP_LOG("Error: UNSUPPORTED PREFIX LENGTH"); - return; - } - - /* check if addr does not already exist and find a free entry */ - for(i = 0; i < UIP_CONF_NETIF_MAX_ADDRESSES; ++i) { - if(uip_netif_physical_if.addresses[i].state == NOT_USED){ - /* - * Copying address - * If we are doing autoconf, ipaddr is a prefix, we copy the 128 bits - * of it, then overwrite the last 64 bits with the interface ID at - * next if statement. - * Otherwise ipaddr is an address, we just copy it - */ - uip_ipaddr_copy(&uip_netif_physical_if.addresses[i].ipaddr, ipaddr); - if(type == AUTOCONF) { - /* construct address from prefix and layer2 id */ - uip_netif_addr_autoconf_set(&uip_netif_physical_if.addresses[i].ipaddr, &uip_lladdr); - } - /* setting state, type */ - uip_netif_physical_if.addresses[i].state = TENTATIVE; - uip_netif_physical_if.addresses[i].type = type; - /* setting lifetime timer if lieftime is not infinite */ - if(vlifetime != 0) { - stimer_set(&(uip_netif_physical_if.addresses[i].vlifetime), vlifetime); - uip_netif_physical_if.addresses[i].is_infinite = 0; - } else { - uip_netif_physical_if.addresses[i].is_infinite = 1; - } - PRINTF("Created new address"); - PRINT6ADDR(&uip_netif_physical_if.addresses[i].ipaddr); - PRINTF("for interface\n"); - - /* schedule DAD */ - uip_netif_sched_dad(&uip_netif_physical_if.addresses[i]); - - return; - } - } - - /* If we did not find space, log */ - UIP_LOG("ADDRESS LIST FULL"); - return; -} -/*---------------------------------------------------------------------------*/ -void -uip_netif_addr_autoconf_set(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr) -{ - /* We consider only links with IEEE EUI-64 identifier or - IEEE 48-bit MAC addresses */ -#if (UIP_LLADDR_LEN == 8) - memcpy(ipaddr->u8 + 8, lladdr, UIP_LLADDR_LEN); - ipaddr->u8[8] ^= 0x02; -#elif (UIP_LLADDR_LEN == 6) - memcpy(ipaddr->u8 + 8, lladdr, 3); - ipaddr->u8[11] = 0xff; - ipaddr->u8[12] = 0xfe; - memcpy(ipaddr->u8 + 13, (u8_t*)lladdr + 3, 3); - ipaddr->u8[8] ^= 0x02; -#else -#error uip-netif.c cannot build interface address when UIP_LLADDR_LEN is not 6 or 8 -#endif -} -/*---------------------------------------------------------------------------*/ -u8_t -get_match_length(uip_ipaddr_t *src, uip_ipaddr_t *dst) -{ - u8_t j, k, x_or; - u8_t len = 0; - for(j = 0; j < 16; j ++) { - if(src->u8[j] == dst->u8[j]) { - len += 8; - } else { - x_or = src->u8[j] ^ dst->u8[j]; - for(k = 0; k < 8; k ++) { - if((x_or & 0x80) == 0){ - len ++; - x_or <<= 1; - } - else { - break; - } - } - break; - } - } - return len; -} -/*---------------------------------------------------------------------------*/ -void -uip_netif_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst) -{ - u8_t best = 0; /* number of bit in common with best match*/ - u8_t n = 0; - u8_t index = 0; - - if(!uip_is_addr_link_local(dst) && !uip_is_addr_mcast(dst)) { - for(i = 1; i < UIP_CONF_NETIF_MAX_ADDRESSES; ++i) { - if(uip_netif_physical_if.addresses[i].state == PREFERRED){ - n = get_match_length(dst, &(uip_netif_physical_if.addresses[i].ipaddr)); - if(n >= best){ - best = n; - index = i; - } - } - } - } - - uip_ipaddr_copy(src, &(uip_netif_physical_if.addresses[index].ipaddr)); - return; -} -/*---------------------------------------------------------------------------*/ -void -uip_netif_sched_dad(struct uip_netif_addr *ifaddr) -{ - if(ifaddr->state != TENTATIVE){ - UIP_LOG("DAD called with non tentative address"); - return; - } - /* - * check dad is not running - */ - if(dad_ifaddr != NULL){ - UIP_LOG("DAD already running"); - return; - } - /* - * Set the interface address that is going through DAD - */ - dad_ifaddr = ifaddr; - - PRINTF("Scheduling DAD for ipaddr:"); - PRINT6ADDR(&dad_ifaddr->ipaddr); - PRINTF("\n"); - - etimer_set(&uip_netif_timer_dad, random_rand()%(UIP_ND6_MAX_RTR_SOLICITATION_DELAY * CLOCK_SECOND)); -} -/*---------------------------------------------------------------------------*/ -void -uip_netif_dad(void) -{ - /* - * check if dad is running - */ - if(dad_ifaddr == NULL){ - PRINTF("uip_netif_dad: DAD not running\n"); - return; - } - /* - * send dup_addr_detect_transmit NS for DAD - */ - if(dad_ns < uip_netif_physical_if.dup_addr_detect_transmit) { - uip_nd6_io_ns_output(NULL, NULL, &dad_ifaddr->ipaddr); - dad_ns++; - etimer_set(&uip_netif_timer_dad, uip_netif_physical_if.retrans_timer / 1000 * CLOCK_SECOND); - return; - } - /* - * If we arrive here it means DAD succeeded, otherwise the dad process - * would have been interrupted in nd6_dad_ns/na_input - */ - PRINTF("DAD succeeded for ipaddr:"); - PRINT6ADDR(&(dad_ifaddr->ipaddr)); - PRINTF("\n"); - - etimer_stop(&uip_netif_timer_dad); - dad_ifaddr->state = PREFERRED; - dad_ifaddr = NULL; - dad_ns = 0; - /* - * check if we need to run DAD on another address - * This is necessary because if you receive a RA, - * you might want to run DAD for several addresses - * Considering that we have structures to do DAD - * for one address only, we start DAD for the subsequent - * addresses here - */ - PRINTF("END of DAD\n"); - for(i = 0; i < UIP_CONF_NETIF_MAX_ADDRESSES; i ++){ - if(uip_netif_physical_if.addresses[i].state != NOT_USED){ - PRINTF("address %u : ",i); - PRINT6ADDR(&(uip_netif_physical_if.addresses[i].ipaddr)); - PRINTF("\n"); - } - if(uip_netif_physical_if.addresses[i].state == TENTATIVE){ - uip_netif_sched_dad(&uip_netif_physical_if.addresses[i]); - return; - } - } -} -/*---------------------------------------------------------------------------*/ -void -uip_netif_dad_failed(uip_ipaddr_t *ipaddr) -{ - UIP_LOG("DAD FAILED"); - UIP_LOG("THE STACK IS GOING TO SHUT DOWN"); - UIP_LOG("THE HOST WILL BE UNREACHABLE"); - - if(uip_ipaddr_cmp(&dad_ifaddr->ipaddr, ipaddr)){ - etimer_stop(&uip_netif_timer_dad); - dad_ifaddr->state = NOT_USED; - dad_ifaddr = NULL; - dad_ns = 0; - } -} -/*---------------------------------------------------------------------------*/ -void -uip_netif_sched_send_rs(void) -{ - /* before a host sends an initial solicitation, it SHOULD delay the - transmission for a random amount of time between 0 and - UIP_ND6_MAX_RTR_SOLICITATION_DELAY. */ - if(rs_count == 0){ - etimer_set(&uip_netif_timer_rs, random_rand()%(UIP_ND6_MAX_RTR_SOLICITATION_DELAY * CLOCK_SECOND)); - PRINTF("Scheduling RS\n"); - } -} -/*---------------------------------------------------------------------------*/ -void -uip_netif_send_rs(void) -{ - if((uip_nd6_choose_defrouter() == NULL) && (rs_count < UIP_ND6_MAX_RTR_SOLICITATIONS)){ - PRINTF("Sending RS %u\n", rs_count); - uip_nd6_io_rs_output(); - rs_count++; - etimer_set(&uip_netif_timer_rs, UIP_ND6_RTR_SOLICITATION_INTERVAL * CLOCK_SECOND); - } else { - PRINTF("Router found ? (boolean): %u\n", (uip_nd6_choose_defrouter() != NULL)); - etimer_stop(&uip_netif_timer_rs); - rs_count = 0; - } -} - -/** @} */ diff --git a/core/net/uip-netif.h b/core/net/uip-netif.h deleted file mode 100644 index b5143d1a3..000000000 --- a/core/net/uip-netif.h +++ /dev/null @@ -1,207 +0,0 @@ -/** - * \addtogroup uip6 - * @{ - */ - -/** - * \file - * Network interface and stateless autoconfiguration (RFC 4862) - * \author Mathilde Durvy - * \author Julien Abeille - * - */ -/* - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * - */ - -#ifndef __UIP_NETIF_H__ -#define __UIP_NETIF_H__ - -#include "net/uip-nd6.h" - -#ifndef UIP_CONF_NETIF_MAX_ADDRESSES -#define UIP_CONF_NETIF_MAX_ADDRESSES 2 -#endif /*UIP_CONF_NETIF_MAX_ADDRESSES*/ - -/** - * \brief Possible states for the address of an interface (RFC 4862 autoconf + - * NOT_USED + INFINITE) - */ -typedef enum { - NOT_USED = -1, - TENTATIVE = 0, - PREFERRED = 1, - DEPRECATED = 2, /* not needed if we don't use pliffetime in prefix struct */ -} uip_netif_state; - -/** - * \brief How the address was acquired: Autoconf, DHCP or manually - * - */ -typedef enum { - AUTOCONF = 1, - DHCP = 2, - MANUAL = 3 -} uip_netif_type; - -/** - * \brief An address structure for an interface - * - * Contains an ip address assigned to the interface, and its state. - */ -struct uip_netif_addr { - uip_ipaddr_t ipaddr; - uip_netif_state state; - struct stimer vlifetime; - u8_t is_infinite; - uip_netif_type type; -}; - -/** \brief Interface structure (contains all the interface variables) */ -struct uip_netif { - u32_t link_mtu; - u8_t cur_hop_limit; - u32_t base_reachable_time; /* in msec */ - u32_t reachable_time; /* in msec */ - u32_t retrans_timer; /* in msec */ - u8_t dup_addr_detect_transmit; - /** Note: the link-local address is at position 0 */ - struct uip_netif_addr addresses[UIP_CONF_NETIF_MAX_ADDRESSES]; - uip_ipaddr_t solicited_node_mcastaddr; -}; - - -/*---------------------------------------------------------------------------*/ -extern struct uip_netif uip_netif_physical_if; -extern struct etimer uip_netif_timer_dad; -extern struct etimer uip_netif_timer_rs; -extern struct etimer uip_netif_timer_periodic; - -/*---------------------------------------------------------------------------*/ -/** \brief Initialize the network interfac and run stateless autoconf */ -void uip_netif_init(void); - - -/** - * \brief periodically check the state of the addresses. - */ -void uip_netif_periodic(void); - -/** - * \brief recompute random reachable timer - * \return the new value for timer - */ -u32_t uip_netif_compute_reachable_time(void); - -/** - * \brief Check if an unicast address is attached to my interface - * \param ipaddr an IP address to be checked - * \return 1 if address is attached to my interface (otherwise false) - */ -#define uip_netif_is_addr_my_unicast(a) (uip_netif_addr_lookup(a, 128, 0) != NULL) - -/** - * \brief Check if this is my solicited-node multicast address - * \param ipaddr an IP address to be checked - * \return 1 if the address is my solicited-node (otherwise false) - */ -u8_t uip_netif_is_addr_my_solicited(uip_ipaddr_t *ipaddr); - -/** - * \brief Autoconfigure and add an address corresponding to a specific prefix - * \param ipaddr the prefix if we are doing autoconf, the address for DHCP and manual - * \param length the prefix length if autoconf, 0 for DHCP and manual - * \param vlifetime valid lifetime of the address, 0 if the address has INFINITE lifetime, - * non 0 otherwise - * \param type AUTOCONF or MANUAL or DHCP - */ -void uip_netif_addr_add(uip_ipaddr_t *ipaddr, u8_t length, unsigned long vlifetime, uip_netif_type type); - -/** - * \brief Set the 8 last bytes of the IP address - * based on the L2 identifier using autoconf - * \param *ipaddr the IP address to be completed with layer 2 info - * \param *lladdr the L2 address - */ -void uip_netif_addr_autoconf_set(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr); - -/** - * \brief Lookup an address - * \param ipaddr the prefix if we are looking for an autoconf address, the address otherwise - * \param length the prefix length if we are looking for autoconf address, 128 otherwise - * \param type AUTOCONF or MANUAL or DHCP or 0 - * - * - * If we are looking for an AUTOCONFIGURED address, ipaddr is a prefix - * length is its length, type is AUTOCONF. - * Otherwise ipaddr is a full address, length must be 128, type is MANUAL - * or DHCP. - * Note: if we do not care about the type, type MUST be 0 - */ -struct uip_netif_addr * -uip_netif_addr_lookup(uip_ipaddr_t *ipaddr, u8_t length, uip_netif_type type); - -/** - * \brief Select the appropriate source address for a packet - * \param ipaddr the selected address (returned value) - * \param ipaddr the destination of the packet - */ -void uip_netif_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst); - -/** - * \brief Schedule DAD for a given address - * \param ifaddr the address for which schedule DAD - */ -void uip_netif_sched_dad(struct uip_netif_addr *ifaddr); - -/** - * \brief Perform DAD (i.e. Duplicate Address Detection) - */ -void uip_netif_dad(void); - -/** - * \brief DAD failed, should never happen! - * \param ipaddr the address for which DAD failed - */ -void uip_netif_dad_failed(uip_ipaddr_t *ipaddr); - -/** - * \brief Schedule the sending of RS - */ -void uip_netif_sched_send_rs(void); - -/** - * \brief Send up to MAX_RTR_SOLICITATION_DELAY RS separated by a delay of - * RTR_SOLICITATION_INTERVAL - */ -void uip_netif_send_rs(void); - -#endif - -/** @} */ - diff --git a/core/net/uip.h b/core/net/uip.h index 8ddb4b26b..492ee31e3 100644 --- a/core/net/uip.h +++ b/core/net/uip.h @@ -47,7 +47,7 @@ * * This file is part of the uIP TCP/IP stack. * - * $Id: uip.h,v 1.26 2010/03/12 16:19:19 joxe Exp $ + * $Id: uip.h,v 1.27 2010/03/15 16:41:24 joxe Exp $ * */ @@ -82,38 +82,39 @@ typedef uip_ip4addr_t uip_ipaddr_t; /*---------------------------------------------------------------------------*/ /** \brief 16 bit 802.15.4 address */ -struct uip_802154_shortaddr { +typedef struct uip_802154_shortaddr { u8_t addr[2]; -}; +} uip_802154_shortaddr; /** \brief 64 bit 802.15.4 address */ -struct uip_802154_longaddr { +typedef struct uip_802154_longaddr { u8_t addr[8]; -}; +} uip_802154_longaddr; /** \brief 802.11 address */ -struct uip_80211_addr { +typedef struct uip_80211_addr { u8_t addr[6]; -}; +} uip_80211_addr; /** \brief 802.3 address */ -struct uip_eth_addr { +typedef struct uip_eth_addr { u8_t addr[6]; -}; +} uip_eth_addr; + #if UIP_CONF_LL_802154 /** \brief 802.15.4 address */ -typedef struct uip_802154_longaddr uip_lladdr_t; +typedef uip_802154_longaddr uip_lladdr_t; #define UIP_802154_SHORTADDR_LEN 2 #define UIP_802154_LONGADDR_LEN 8 #define UIP_LLADDR_LEN UIP_802154_LONGADDR_LEN #else /*UIP_CONF_LL_802154*/ #if UIP_CONF_LL_80211 /** \brief 802.11 address */ -typedef struct uip_80211_addr uip_lladdr_t; +typedef uip_80211_addr uip_lladdr_t; #define UIP_LLADDR_LEN 6 #else /*UIP_CONF_LL_80211*/ /** \brief Ethernet address */ -typedef struct uip_eth_addr uip_lladdr_t; +typedef uip_eth_addr uip_lladdr_t; #define UIP_LLADDR_LEN 6 #endif /*UIP_CONF_LL_80211*/ #endif /*UIP_CONF_LL_802154*/ @@ -1716,22 +1717,22 @@ struct uip_ip_hdr { * used in IPSec and defined in RFC4302,4303,4305,4385 */ /* common header part */ -struct uip_ext_hdr { +typedef struct uip_ext_hdr { u8_t next; u8_t len; -}; +} uip_ext_hdr; /* Hop by Hop option header */ -struct uip_hbho_hdr { +typedef struct uip_hbho_hdr { u8_t next; u8_t len; -}; +} uip_hbho_hdr; /* destination option header */ -struct uip_desto_hdr { +typedef struct uip_desto_hdr { u8_t next; u8_t len; -}; +} uip_desto_hdr; /* We do not define structures for PAD1 and PADN options */ @@ -1743,35 +1744,35 @@ struct uip_desto_hdr { * RFC3775 (MIPv6) here we do not implement MIPv6, so we just need to * parse the 4 first bytes */ -struct uip_routing_hdr { +typedef struct uip_routing_hdr { u8_t next; u8_t len; u8_t routing_type; u8_t seg_left; -}; +} uip_routing_hdr; /* fragmentation header */ -struct uip_frag_hdr { +typedef struct uip_frag_hdr { u8_t next; u8_t res; u16_t offsetresmore; u32_t id; -}; +} uip_frag_hdr; /* * an option within the destination or hop by hop option headers * it contains type an length, which is true for all options but PAD1 */ -struct uip_ext_hdr_opt { +typedef struct uip_ext_hdr_opt { u8_t type; u8_t len; -}; +} uip_ext_hdr_opt; /* PADN option */ -struct uip_ext_hdr_opt_padn { +typedef struct uip_ext_hdr_opt_padn { u8_t opt_type; u8_t opt_len; -}; +} uip_ext_hdr_opt_padn; /* TCP header */ struct uip_tcp_hdr { @@ -1923,6 +1924,22 @@ CCIF extern uip_lladdr_t uip_lladdr; #ifdef UIP_CONF_IPV6 +/** Length of the link local prefix */ +#define UIP_LLPREF_LEN 10 + +/** + * \brief Is IPv6 address a the unspecified address + * a is of type uip_ipaddr_t + */ +#define uip_is_addr_loopback(a) \ + ((((a)->u16[0]) == 0) && \ + (((a)->u16[1]) == 0) && \ + (((a)->u16[2]) == 0) && \ + (((a)->u16[3]) == 0) && \ + (((a)->u16[4]) == 0) && \ + (((a)->u16[5]) == 0) && \ + (((a)->u16[6]) == 0) && \ + (((a)->u16[7]) == 1)) /** * \brief Is IPv6 address a the unspecified address * a is of type uip_ipaddr_t @@ -1982,15 +1999,16 @@ CCIF extern uip_lladdr_t uip_lladdr; * \brief is addr (a) a solicited node multicast address, see RFC3513 * a is of type uip_ipaddr_t* */ -#define uip_is_addr_solicited_node(a) \ - ((((a)->u8[0]) == 0xFF) && \ - (((a)->u8[1]) == 0x02) && \ - (((a)->u16[1]) == 0) && \ - (((a)->u16[2]) == 0) && \ - (((a)->u16[3]) == 0) && \ - (((a)->u16[4]) == 0) && \ - (((a)->u16[5]) == 1) && \ - (((a)->u8[12]) == 0xFF)) +#define uip_is_addr_solicited_node(a) \ + ((((a)->u8[0]) == 0xFF) && \ + (((a)->u8[1]) == 0x02) && \ + (((a)->u16[1]) == 0x00) && \ + (((a)->u16[2]) == 0x00) && \ + (((a)->u16[3]) == 0x00) && \ + (((a)->u16[4]) == 0x00) && \ + (((a)->u8[10]) == 0x00) && \ + (((a)->u8[11]) == 0x01) && \ + (((a)->u8[12]) == 0xFF)) /** * \briefput in b the solicited node address corresponding to address a diff --git a/core/net/uip6.c b/core/net/uip6.c index 0b55e1e53..94a6636f0 100644 --- a/core/net/uip6.c +++ b/core/net/uip6.c @@ -41,7 +41,7 @@ * * This file is part of the uIP TCP/IP stack. * - * $Id: uip6.c,v 1.14 2010/03/09 15:50:15 joxe Exp $ + * $Id: uip6.c,v 1.15 2010/03/15 16:41:24 joxe Exp $ * */ @@ -75,7 +75,7 @@ #include "net/uipopt.h" #include "net/uip-icmp6.h" #include "net/uip-nd6.h" -#include "net/uip-netif.h" +#include "net/uip-ds6.h" #include @@ -405,8 +405,7 @@ void uip_init(void) { - uip_netif_init(); - uip_nd6_init(); + uip_ds6_init(); #if UIP_TCP for(c = 0; c < UIP_LISTENPORTS; ++c) { @@ -428,19 +427,6 @@ uip_init(void) #endif /* UIP_UDP */ } -/*---------------------------------------------------------------------------*/ -#if UIP_CONF_ROUTER -void -uip_router_register(const struct uip_router *router) { - if(uip_router != NULL) { - uip_router->deactivate(); - } - uip_router = router; - if(uip_router != NULL) { - router->activate(); - } -} -#endif /*UIP_CONF_ROUTER*/ /*---------------------------------------------------------------------------*/ #if UIP_TCP && UIP_ACTIVE_OPEN struct uip_conn * @@ -550,7 +536,7 @@ uip_udp_new(const uip_ipaddr_t *ripaddr, u16_t rport) } else { uip_ipaddr_copy(&conn->ripaddr, ripaddr); } - conn->ttl = uip_netif_physical_if.cur_hop_limit; + conn->ttl = uip_ds6_if.cur_hop_limit; return conn; } @@ -1091,36 +1077,54 @@ uip_process(u8_t flag) } #if UIP_CONF_ROUTER - if(!uip_netif_is_addr_my_unicast(&UIP_IP_BUF->destipaddr) && - !uip_netif_is_addr_my_solicited(&UIP_IP_BUF->destipaddr)) { + /* TBD Some Parameter problem messages */ + if(!uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) && + !uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr)) { if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr) && - !uip_is_addr_link_local(&UIP_IP_BUF->destipaddr)) { + !uip_is_addr_link_local(&UIP_IP_BUF->destipaddr) && + !uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr) && + !uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr) && + !uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) { + + + /* Check MTU */ + if(uip_len > UIP_LINK_MTU) { + uip_icmp6_error_output(ICMP6_PACKET_TOO_BIG, 0, UIP_LINK_MTU); + UIP_STAT(++uip_stat.ip.drop); + goto send; + } + /* Check Hop Limit */ + if(UIP_IP_BUF->ttl <= 1) { + uip_icmp6_error_output(ICMP6_TIME_EXCEEDED, + ICMP6_TIME_EXCEED_TRANSIT, 0); + UIP_STAT(++uip_stat.ip.drop); + goto send; + } + UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1; PRINTF("Forwarding packet to "); PRINT6ADDR(&UIP_IP_BUF->destipaddr); PRINTF("\n"); - - if(UIP_IP_BUF->ttl <= 1) { - PRINTF("Dropping packet: hop limit reached\n"); - UIP_STAT(++uip_stat.ip.drop); - uip_icmp6_error_output(ICMP6_TIME_EXCEEDED, - ICMP6_TIME_EXCEED_TRANSIT, 0); - } else { - /* Decrement the TTL (time-to-live) value in the IP header */ - UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1; - UIP_STAT(++uip_stat.ip.forwarded); - } + UIP_STAT(++uip_stat.ip.forwarded); goto send; - } else if(!uip_is_addr_linklocal_allnodes_mcast(&UIP_IP_BUF->destipaddr) && - !uip_is_addr_linklocal_allrouters_mcast(&UIP_IP_BUF->destipaddr)) { - PRINTF("Dropping packet, not for me\n"); + } else { + if((uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr)) && + (!uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) && + (!uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) && + (!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) && + (!uip_ds6_is_addr_onlink((&UIP_IP_BUF->destipaddr)))) { + PRINTF("LL source address with off link destination, dropping\n"); + uip_icmp6_error_output(ICMP6_DST_UNREACH, + ICMP6_DST_UNREACH_NOTNEIGHBOR, 0); + goto send; + } + PRINTF("Dropping packet, not for me and link local or multicast\n"); UIP_STAT(++uip_stat.ip.drop); goto drop; } } -#else - if(!uip_netif_is_addr_my_unicast(&UIP_IP_BUF->destipaddr) && - !uip_netif_is_addr_my_solicited(&UIP_IP_BUF->destipaddr) && - !uip_is_addr_linklocal_allnodes_mcast(&UIP_IP_BUF->destipaddr)){ +#else /* UIP_CONF_ROUTER */ + if(!uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) && + !uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr)) { PRINTF("Dropping packet, not for me\n"); UIP_STAT(++uip_stat.ip.drop); goto drop; @@ -1292,7 +1296,7 @@ uip_process(u8_t flag) /* * Here we process incoming ICMPv6 packets * For echo request, we send echo reply - * For ND pkts, we call the appropriate function in uip-nd6-io.c + * For ND pkts, we call the appropriate function in uip-nd6.c * We do not treat Error messages for now * If no pkt is to be sent as an answer to the incoming one, we * "goto drop". Else we just break; then at the after the "switch" @@ -1304,18 +1308,32 @@ uip_process(u8_t flag) switch(UIP_ICMP_BUF->type) { case ICMP6_NS: - uip_nd6_io_ns_input(); + uip_nd6_ns_input(); break; case ICMP6_NA: - uip_nd6_io_na_input(); + uip_nd6_na_input(); break; case ICMP6_RS: - UIP_STAT(++uip_stat.icmp.drop); - uip_len = 0; - break; - case ICMP6_RA: - uip_nd6_io_ra_input(); - break; +#if UIP_CONF_ROUTER && UIP_ND6_SEND_RA + uip_nd6_rs_input(); +#else /* UIP_CONF_ROUTER && UIP_ND6_SEND_RA */ + UIP_STAT(++uip_stat.icmp.drop); + uip_len = 0; +#endif /* UIP_CONF_ROUTER && UIP_ND6_SEND_RA */ + break; + case ICMP6_RA: +#if UIP_CONF_ROUTER + UIP_STAT(++uip_stat.icmp.drop); + uip_len = 0; +#else /* UIP_CONF_ROUTER */ + uip_nd6_ra_input(); +#endif /* UIP_CONF_ROUTER */ + break; +#if UIP_CONF_IPV6_RPL + case ICMP6_RPL: + uip_rpl_input(); + break; +#endif /* UIP_CONF_IPV6_RPL */ case ICMP6_ECHO_REQUEST: uip_icmp6_echo_request_input(); break; @@ -1426,7 +1444,7 @@ uip_process(u8_t flag) UIP_TCP_BUF->destport = uip_udp_conn->rport; uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &uip_udp_conn->ripaddr); - uip_netif_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); + uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN]; @@ -1542,7 +1560,7 @@ uip_process(u8_t flag) /* Swap IP addresses. */ uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &UIP_IP_BUF->srcipaddr); - uip_netif_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); + uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); /* And send out the RST packet! */ goto tcp_send_noconn; @@ -2113,7 +2131,7 @@ uip_process(u8_t flag) uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &uip_connr->ripaddr); - uip_netif_select_src(&UIP_IP_BUF->srcipaddr,&UIP_IP_BUF->destipaddr); + uip_ds6_select_src(&UIP_IP_BUF->srcipaddr,&UIP_IP_BUF->destipaddr); PRINTF("Sending TCP packet to"); PRINT6ADDR(&UIP_IP_BUF->destipaddr); PRINTF("from"); @@ -2130,7 +2148,7 @@ uip_process(u8_t flag) } tcp_send_noconn: - UIP_IP_BUF->ttl = uip_netif_physical_if.cur_hop_limit; + UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit; UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); diff --git a/platform/sky/contiki-sky-main.c b/platform/sky/contiki-sky-main.c index cce22ee6c..906ea88ee 100644 --- a/platform/sky/contiki-sky-main.c +++ b/platform/sky/contiki-sky-main.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)$Id: contiki-sky-main.c,v 1.74 2010/03/01 14:46:57 nifi Exp $ + * @(#)$Id: contiki-sky-main.c,v 1.75 2010/03/15 16:43:04 joxe Exp $ */ #include @@ -40,7 +40,6 @@ #include "dev/cc2420.h" #include "dev/ds2411.h" #include "dev/leds.h" -#include "dev/light.h" #include "dev/serial-line.h" #include "dev/sht11.h" #include "dev/slip.h" @@ -53,7 +52,7 @@ #if WITH_UIP6 #include "net/sicslowpan.h" -#include "net/uip-netif.h" +#include "net/uip-ds6.h" #include "net/mac/sicslowmac.h" #endif /* WITH_UIP6 */ @@ -301,24 +300,28 @@ main(int argc, char **argv) printf("Tentative link-local IPv6 address "); { - int i; - for(i = 0; i < 7; ++i) { - printf("%02x%02x:", - uip_netif_physical_if.addresses[0].ipaddr.u8[i * 2], - uip_netif_physical_if.addresses[0].ipaddr.u8[i * 2 + 1]); + int i, a; + for(a = 0; a < UIP_DS6_ADDR_NB; a++) { + if (uip_ds6_if.addr_list[a].isused) { + for(i = 0; i < 7; ++i) { + printf("%02x%02x:", + uip_ds6_if.addr_list[a].ipaddr.u8[i * 2], + uip_ds6_if.addr_list[a].ipaddr.u8[i * 2 + 1]); + } + printf("%02x%02x\n", + uip_ds6_if.addr_list[a].ipaddr.u8[14], + uip_ds6_if.addr_list[a].ipaddr.u8[15]); + } } - printf("%02x%02x\n", - uip_netif_physical_if.addresses[0].ipaddr.u8[14], - uip_netif_physical_if.addresses[0].ipaddr.u8[15]); } if(1) { uip_ipaddr_t ipaddr; int i; uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); - uip_netif_addr_autoconf_set(&ipaddr, &uip_lladdr); - uip_netif_addr_add(&ipaddr, 16, 0, TENTATIVE); - printf("Tentative IPv6 address "); + uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); + uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE); + printf("Tentative global IPv6 address "); for(i = 0; i < 7; ++i) { printf("%02x%02x:", ipaddr.u8[i * 2], ipaddr.u8[i * 2 + 1]); @@ -329,7 +332,8 @@ main(int argc, char **argv) #if UIP_CONF_ROUTER - uip_router_register(&UIP_ROUTER_MODULE); + //uip_router_register(&UIP_ROUTER_MODULE); + UIP_ROUTER_MODULE.activate(); #endif /* UIP_CONF_ROUTER */ #else /* WITH_UIP6 */