diff --git a/Makefile.dep b/Makefile.dep index d7b244c58a9216d16ec691e18d11af836b9d601e..4d7f2b4d0107059c5159f5627e2de53d41d1d49f 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -193,20 +193,6 @@ ifneq (,$(filter gnrc_ipv6_router_default,$(USEMODULE))) USEMODULE += gnrc_icmpv6 endif -ifneq (,$(filter gnrc_ndp_router,$(USEMODULE))) - USEMODULE += gnrc_ndp_node - USEMODULE += random - USEMODULE += xtimer -endif - -ifneq (,$(filter gnrc_ndp_node,$(USEMODULE))) - USEMODULE += gnrc_ndp_internal -endif - -ifneq (,$(filter gnrc_ndp_%,$(USEMODULE))) - USEMODULE += gnrc_ndp -endif - ifneq (,$(filter gnrc_ndp2,$(USEMODULE))) USEMODULE += gnrc_icmpv6 USEMODULE += gnrc_netif2 @@ -273,10 +259,6 @@ ifneq (,$(filter ipv6_hdr,$(USEMODULE))) USEMODULE += ipv6_addr endif -ifneq (,$(filter gnrc_ipv6_nc,$(USEMODULE))) - USEMODULE += ipv6_addr -endif - ifneq (,$(filter gnrc_ipv6_nib_6lbr,$(USEMODULE))) USEMODULE += gnrc_ipv6_nib_6lr endif diff --git a/examples/gnrc_minimal/Makefile b/examples/gnrc_minimal/Makefile index 69a5b7c396bdf0aaa0db211f4f6b5c6c19089f86..09200a6ec65094f0080a8b17c05f11e2eb76e2fc 100644 --- a/examples/gnrc_minimal/Makefile +++ b/examples/gnrc_minimal/Makefile @@ -20,7 +20,6 @@ USEMODULE += gnrc_netdev_default USEMODULE += auto_init_gnrc_netif # Specify the minimum networking modules for IPv6 USEMODULE += gnrc_ipv6 -USEMODULE += gnrc_ndp # Additional networking modules that can be dropped if not needed USEMODULE += gnrc_icmpv6_echo # Use minimal standard PRNG diff --git a/sys/include/net/gnrc.h b/sys/include/net/gnrc.h index 313bdbb7bfef9c0b36a79f7ce2baba531831b76b..75bb0e67ba2cc952ff988f3efd7b48b6ce1238a1 100644 --- a/sys/include/net/gnrc.h +++ b/sys/include/net/gnrc.h @@ -241,11 +241,10 @@ * USEMODULE += gnrc_ipv6_router * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * respectively. Those modules provide the bare minimum of IPv6 - * functionalities (no @ref net_gnrc_icmpv6, no @ref net_gnrc_ndp). Because - * of that, the @ref net_gnrc_ipv6_nc needs to be configured manually. If an - * IEEE 802.15.4 device is present @ref net_gnrc_sixlowpan will be included - * automatically, but no fragmentation or header compression support will be - * provided. + * functionalities (no @ref net_gnrc_icmpv6). Because of that, the + * @ref net_gnrc_ipv6_nib needs to be configured manually. If an IEEE 802.15.4 + * device is present @ref net_gnrc_sixlowpan will be included automatically, + * but no fragmentation or header compression support will be provided. * * - For @ref net_gnrc_icmpv6_echo "ICMPv6 echo request/reply (ping)" * functionality: diff --git a/sys/include/net/gnrc/ipv6/nc.h b/sys/include/net/gnrc/ipv6/nc.h deleted file mode 100644 index 9672c9037347da777fc1e147e2d40680f1864c2b..0000000000000000000000000000000000000000 --- a/sys/include/net/gnrc/ipv6/nc.h +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> - * - * This file is subject to the terms and conditions of the GNU Lesser General - * Public License v2.1. See the file LICENSE in the top level directory for - * more details. - */ - -/** - * @defgroup net_gnrc_ipv6_nc IPv6 neighbor cache - * @ingroup net_gnrc_ipv6 - * @brief Translates IPv6 addresses to link layer addresses. - * @{ - * - * @file - * @brief Neighbor cache definitions. - * - * @author Martine Lenders <mlenders@inf.fu-berlin.de> - */ - -#ifndef NET_GNRC_IPV6_NC_H -#define NET_GNRC_IPV6_NC_H - -#include <assert.h> -#include <stdbool.h> -#include <stdint.h> -#include <string.h> - -#include "kernel_types.h" -#include "net/eui64.h" -#include "net/ipv6/addr.h" -#include "net/gnrc/pktqueue.h" -#include "xtimer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef GNRC_IPV6_NC_SIZE -/** - * @brief The size of the neighbor cache - */ -#define GNRC_IPV6_NC_SIZE (GNRC_NETIF_NUMOF * 8) -#endif - -#ifndef GNRC_IPV6_NC_L2_ADDR_MAX -/** - * @brief The maximum size of a link layer address - */ -#define GNRC_IPV6_NC_L2_ADDR_MAX (8) -#endif - -/** - * @{ - * @name Flag definitions for gnrc_ipv6_nc_t - */ -/** - * @{ - * @brief States of a neighbor cache entry. - * - * @see <a href="http://tools.ietf.org/html/rfc4861#section-7.3.2"> - * RFC 4861, section 7.3.2 - * </a> - */ -#define GNRC_IPV6_NC_STATE_MASK (0x07) /**< Mask for neighbor cache state */ -#define GNRC_IPV6_NC_STATE_POS (0) /**< Shift of neighbor cache state */ - -#define GNRC_IPV6_NC_STATE_UNMANAGED (0x00) /**< The entry is not manage by NDP */ - -/** - * @brief The entry is unreachable - * - * @see <a href="http://tools.ietf.org/html/rfc7048#section-3"> - * RFC 7048, section 3 - * </a> - */ -#define GNRC_IPV6_NC_STATE_UNREACHABLE (0x01) -#define GNRC_IPV6_NC_STATE_INCOMPLETE (0x02) /**< Address resolution is performed */ -#define GNRC_IPV6_NC_STATE_STALE (0x03) /**< The entry is stale */ -#define GNRC_IPV6_NC_STATE_DELAY (0x04) /**< The entry was stale but packet was sent out */ -#define GNRC_IPV6_NC_STATE_PROBE (0x05) /**< Periodic reachabality confirmation */ -#define GNRC_IPV6_NC_STATE_REACHABLE (0x07) /**< The entry is reachable */ -/** - * @} - */ - -#define GNRC_IPV6_NC_IS_ROUTER (0x08) /**< The neighbor is a router */ - -#define GNRC_IPV6_NC_TYPE_MASK (0x30) /**< Mask for neighbor cache state */ - -/** - * @{ - * @brief States of a neighbor cache entry. - * - * @see <a href="http://tools.ietf.org/html/rfc6775#section-3.5"> - * RFC 6775, section 3.5 - * </a> - */ -/** - * @brief The entry has no type - * - * @details The node sents multicast Neighbor Solicitations for hosts. - */ -#define GNRC_IPV6_NC_TYPE_NONE (0x00) -#define GNRC_IPV6_NC_TYPE_GC (0x10) /**< The entry is marked for removal */ -#define GNRC_IPV6_NC_TYPE_TENTATIVE (0x20) /**< The entry is temporary */ -#define GNRC_IPV6_NC_TYPE_REGISTERED (0x30) /**< The entry is registered */ -/** - * @} - */ -/** - * @} - */ - -/** - * @brief Neighbor cache entry as defined in - * <a href="http://tools.ietf.org/html/rfc4861#section-5.1"> - * RFC 4861, section 5.1 - * </a>. - */ -typedef struct { -#ifdef MODULE_GNRC_NDP_NODE - gnrc_pktqueue_t *pkts; /**< Packets waiting for address resolution */ -#endif - ipv6_addr_t ipv6_addr; /**< IPv6 address of the neighbor */ - uint8_t l2_addr[GNRC_IPV6_NC_L2_ADDR_MAX]; /**< Link layer address of the neighbor */ - uint8_t l2_addr_len; /**< Length of gnrc_ipv6_nc_t::l2_addr */ - uint8_t flags; /**< Flags as defined above */ - kernel_pid_t iface; /**< PID to the interface where the neighbor is */ - xtimer_t rtr_timeout; /**< timeout timer for router flag */ - msg_t rtr_timeout_msg; /**< msg_t for gnrc_ipv6_nc_t::rtr_timeout */ - - /** - * @brief (Re)Transmission timer for neighbor solicitations of this entry and - * timeout for states. - */ - xtimer_t nbr_sol_timer; - msg_t nbr_sol_msg; /**< msg_t for gnrc_ipv6_nc_t::nbr_sol_timer */ - - /** - * @brief Delay timer for neighbor advertisements of this entry. - * - * @note Only needed for delayed anycast neighbor advertisements - * - * @see <a href="https://tools.ietf.org/html/rfc4861#section-7.2.7"> - * RFC 4861, section 7.2.7 - * </a> - */ - xtimer_t nbr_adv_timer; - msg_t nbr_adv_msg; /**< msg_t for gnrc_ipv6_nc_t::nbr_adv_timer */ - -#if defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER) - xtimer_t rtr_adv_timer; /**< Timer for periodic router advertisements */ - msg_t rtr_adv_msg; /**< msg_t for gnrc_ipv6_nc_t::rtr_adv_timer */ -#endif - -#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER - xtimer_t type_timeout; /**< Timer for type transmissions */ - msg_t type_timeout_msg; /**< msg_t for gnrc_ipv6_nc_t::type_timeout */ - eui64_t eui64; /**< the unique EUI-64 of the neighbor (might be - * different from L2 address, if l2_addr_len == 2) */ -#endif - - uint8_t probes_remaining; /**< remaining number of unanswered probes */ - /** - * @} - */ -} gnrc_ipv6_nc_t; - -/** - * @brief Initializes neighbor cache - */ -void gnrc_ipv6_nc_init(void); - -/** - * @brief Adds a neighbor to the neighbor cache - * - * @param[in] iface PID to the interface where the neighbor is. - * @param[in] ipv6_addr IPv6 address of the neighbor. Must not be NULL. - * @param[in] l2_addr Link layer address of the neighbor. NULL if unknown. - * @param[in] l2_addr_len Length of @p l2_addr, must be lesser than or equal - * to GNRC_IPV6_L2_ADDR_MAX. 0 if unknown. - * @param[in] flags Flags for the entry - * - * @return Pointer to new neighbor cache entry on success - * @return NULL, on failure - */ -gnrc_ipv6_nc_t *gnrc_ipv6_nc_add(kernel_pid_t iface, const ipv6_addr_t *ipv6_addr, - const void *l2_addr, size_t l2_addr_len, uint8_t flags); - -/** - * @brief Removes a neighbor from the neighbor cache - * - * @param[in] iface PID to the interface where the neighbor is. If it - * is KERNEL_PID_UNDEF it will be removed for all - * interfaces. - * @param[in] ipv6_addr IPv6 address of the neighbor - */ -void gnrc_ipv6_nc_remove(kernel_pid_t iface, const ipv6_addr_t *ipv6_addr); - -/** - * @brief Searches for any neighbor cache entry fitting the @p ipv6_addr. - * - * @param[in] iface PID to the interface where the neighbor is. If it - * is KERNEL_PID_UNDEF it will be searched on all - * interfaces. - * @param[in] ipv6_addr An IPv6 address - * - * @return The neighbor cache entry, if one is found. - * @return NULL, if none is found. - */ -gnrc_ipv6_nc_t *gnrc_ipv6_nc_get(kernel_pid_t iface, const ipv6_addr_t *ipv6_addr); - -/** - * @brief Gets next entry in neighbor cache after @p prev. - * - * @param[in] prev Previous entry. NULL to start iteration. - * - * @return The next entry in neighbor cache. - */ -gnrc_ipv6_nc_t *gnrc_ipv6_nc_get_next(gnrc_ipv6_nc_t *prev); - -/** - * @brief Gets next reachable router entry in neighbor cache after @p prev. - * - * @param[in] prev Previous router entry. NULL to start iteration. - * - * @return The next reachable router entry in neighbor cache. - */ -gnrc_ipv6_nc_t *gnrc_ipv6_nc_get_next_router(gnrc_ipv6_nc_t *prev); - -/** - * @brief Returns the state of a neighbor cache entry. - * - * @param[in] entry A neighbor cache entry - * - * @return The state of the neighbor cache entry as defined by its flags. - */ -static inline uint8_t gnrc_ipv6_nc_get_state(const gnrc_ipv6_nc_t *entry) -{ - return (entry->flags & GNRC_IPV6_NC_STATE_MASK); -} - -/** - * @brief Returns the type of a neighbor cache entry. - * - * @param[in] entry A neighbor cache entry - * - * @return The type of the neighbor cache entry as defined by its flags. - */ -static inline uint8_t gnrc_ipv6_nc_get_type(const gnrc_ipv6_nc_t *entry) -{ - return (entry->flags & GNRC_IPV6_NC_TYPE_MASK); -} - -/** - * @brief Checks if an entry is reachable (do not confuse with - * @ref GNRC_IPV6_NC_STATE_REACHABLE). - * - * @param[in] entry A neighbor cache entry - * - * @return true, if you can send packets to @p entry - * @return false, if you can't send packets to @p entry - */ -static inline bool gnrc_ipv6_nc_is_reachable(const gnrc_ipv6_nc_t *entry) -{ - switch (gnrc_ipv6_nc_get_state(entry)) { - case GNRC_IPV6_NC_STATE_UNREACHABLE: - case GNRC_IPV6_NC_STATE_INCOMPLETE: - return false; - - default: - return true; - } -} - -/** - * @brief Marks an entry as still reachable, if one with a fitting @p ipv6_addr - * can be found. - * - * @details This function can be used by upper layer protocols for neighbor - * discovery optimization to confirm that there was a reachability - * confirmation (e. g. an ACK in TCP) from the neighbor. - * - * @see <a href="http://tools.ietf.org/html/rfc4861#section-7.3.1"> - * RFC 4861, section 7.3.1 - * </a> - * - * @param[in] ipv6_addr An IPv6 address - * - * @return The neighbor cache entry, if one is found. - * @return NULL, if none is found. - */ -gnrc_ipv6_nc_t *gnrc_ipv6_nc_still_reachable(const ipv6_addr_t *ipv6_addr); - -/** - * @brief Gets link-layer address from neighbor cache entry if neighbor is reachable. - * - * @pre (l2_addr != NULL) && (l2_addr_len != NULL) - * - * @param[out] l2_addr The link layer address of @p entry. Must not be NULL. - * @param[out] l2_addr_len Length of @p l2_addr. Must not be NULL. - * @param[in] entry A neighbor cache entry - * - * @return PID to the interface where the neighbor is. - * @return KERNEL_PID_UNDEF, if @p entry == NULL or the neighbor is not reachable. - */ -kernel_pid_t gnrc_ipv6_nc_get_l2_addr(uint8_t *l2_addr, uint8_t *l2_addr_len, - const gnrc_ipv6_nc_t *entry); - -#ifdef __cplusplus -} -#endif - -#endif /* NET_GNRC_IPV6_NC_H */ -/** - * @} - */ diff --git a/sys/include/net/gnrc/ndp.h b/sys/include/net/gnrc/ndp.h deleted file mode 100644 index 33974376272ceedd876dcbe7214a94d5f9e7e09d..0000000000000000000000000000000000000000 --- a/sys/include/net/gnrc/ndp.h +++ /dev/null @@ -1,548 +0,0 @@ -/* - * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> - * - * This file is subject to the terms and conditions of the GNU Lesser General - * Public License v2.1. See the file LICENSE in the top level directory for - * more details. - */ - -/** - * @defgroup net_gnrc_ndp IPv6 Neighbor discovery - * @ingroup net_gnrc_icmpv6 - * @brief GNRC's IPv6 Neighbor Discovery implementation - * @{ - * - * @file - * @brief Definitions for GNRC's IPv6 Neighbor Discovery - * - * @author Martine Lenders <mlenders@inf.fu-berlin.de> - */ - -#ifndef NET_GNRC_NDP_H -#define NET_GNRC_NDP_H - -#include <inttypes.h> -#include <stdlib.h> - -#include "byteorder.h" -#include "net/ndp.h" -#include "net/gnrc/pkt.h" -#include "net/gnrc/icmpv6.h" -#include "net/ipv6/addr.h" -#include "net/gnrc/ipv6/nc.h" - -#include "net/gnrc/ndp/host.h" -#include "net/gnrc/ndp/internal.h" -#include "net/gnrc/ndp/router.h" -#include "net/gnrc/ndp/node.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** Message type for router timeouts */ -#define GNRC_NDP_MSG_RTR_TIMEOUT (0x0210) -/** Message type for address timeouts */ -#define GNRC_NDP_MSG_ADDR_TIMEOUT (0x0211) -/** Message type for multicast neighbor solicitation retransmissions */ -#define GNRC_NDP_MSG_NBR_SOL_RETRANS (0x0212) -/** Message type for periodic router advertisements */ -#define GNRC_NDP_MSG_RTR_ADV_RETRANS (0x0213) -/** Message type for delayed router advertisements */ -#define GNRC_NDP_MSG_RTR_ADV_DELAY (0x0214) -/** Message type for delayed router advertisements in a 6LoWPAN - * 6LoWPAN needs a special handling, because router advertisements are only - * sent after a short randomized delay, but not periodically. */ -#define GNRC_NDP_MSG_RTR_ADV_SIXLOWPAN_DELAY (0x0215) -/** Message type for periodic router solicitations */ -#define GNRC_NDP_MSG_RTR_SOL_RETRANS (0x0216) -/** Message type for neighbor cache state timeouts */ -#define GNRC_NDP_MSG_NC_STATE_TIMEOUT (0x0217) - -/** - * @name Host constants - * @{ - * @see <a href="https://tools.ietf.org/html/rfc4861#section-10"> - * RFC 4861, section 10 - * </a> - */ -/** - * @brief Upper bound for randomised delay in seconds for initial - * router solicitation transmissions - */ -#define GNRC_NDP_MAX_RTR_SOL_DELAY (1U) - -/** - * @brief Interval in seconds between initial router solicitation - * transmissions - */ -#define GNRC_NDP_MAX_RTR_SOL_INT (4U) - -/** - * @brief Maximum number of initial router solicitation transmissions - */ -#define GNRC_NDP_MAX_RTR_SOL_NUMOF (3U) -/** @} */ - -/** - * @name Node constants - * @{ - * @see <a href="https://tools.ietf.org/html/rfc4861#section-10"> - * RFC 4861, section 10 - * </a> - */ -/** - * @brief Maximum number of unanswered multicast neighbor solicitations - * before address resolution is considered failed. - */ -#define GNRC_NDP_MAX_MC_NBR_SOL_NUMOF (3U) - -/** - * @brief Maximum number of unanswered unicast neighbor solicitations before - * an address is considered unreachable. - */ -#define GNRC_NDP_MAX_UC_NBR_SOL_NUMOF (3U) - -/** - * @brief Upper bound of randomized delay in seconds for a solicited - * neighbor advertisement transmission for an anycast target. - */ -#define GNRC_NDP_MAX_AC_TGT_DELAY (1U) - -/** - * @brief Maximum number of unsolicited neighbor advertisements before on - * link-layer address change. - */ -#define GNRC_NDP_MAX_NBR_ADV_NUMOF (3U) - -/** - * @brief Base value in mircoseconds for computing randomised - * reachable time. - */ -#define GNRC_NDP_REACH_TIME (30U * US_PER_SEC) - -/** - * @brief Time in mircoseconds between retransmissions of neighbor - * solicitations to a neighbor. - */ -#define GNRC_NDP_RETRANS_TIMER (1U * US_PER_SEC) - -/** - * @brief Delay in seconds for neighbor cache entry between entering - * DELAY state and entering PROBE state if no reachability - * confirmation has been received. - */ -#define GNRC_NDP_FIRST_PROBE_DELAY (5U) - -/** - * @brief Lower bound for randomised reachable time calculation. - */ -#define GNRC_NDP_MIN_RAND (5U) - -/** - * @brief Upper bound for randomised reachable time calculation. - */ -#define GNRC_NDP_MAX_RAND (15U) -/** @} */ - -/** - * @name Router constants - * @{ - * @see <a href="https://tools.ietf.org/html/rfc4861#section-10"> - * RFC 4861, section 10 - * </a> - */ -/** - * @brief Initial router advertisement interval in seconds - */ -#define GNRC_NDP_MAX_INIT_RTR_ADV_INT (16U) - -/** - * @brief Maximum number of initial router advertisement transmissions - */ -#define GNRC_NDP_MAX_INIT_RTR_ADV_NUMOF (3U) - -/** - * @brief Maximum number of final router advertisement transmissions - */ -#define GNRC_NDP_MAX_FIN_RTR_ADV_NUMOF (3U) - -/** - * @brief Minimum delay in seconds between router advertisement - * transmissions - */ -#define GNRC_NDP_MIN_RTR_ADV_DELAY (3U) - -/** - * @brief Upper bound for randomised delay in microseconds between router - * solicitation reception and responding router advertisement - * transmission. - */ -#define GNRC_NDP_MAX_RTR_ADV_DELAY (500U * US_PER_MS) -/** @} */ - -/** - * @brief Handles received neighbor solicitations. - * - * @param[in] iface The receiving interface. - * @param[in] pkt The received packet. - * @param[in] ipv6 The IPv6 header in @p pkt. - * @param[in] nbr_sol The neighbor solicitation in @p pkt. - * @param[in] icmpv6_size The overall size of the neighbor solicitation. - */ -void gnrc_ndp_nbr_sol_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt, - ipv6_hdr_t *ipv6, ndp_nbr_sol_t *nbr_sol, - size_t icmpv6_size); - -/** - * @brief Handles received neighbor advertisements. - * - * @param[in] iface The receiving interface. - * @param[in] pkt The received packet. - * @param[in] ipv6 The IPv6 header in @p pkt. - * @param[in] nbr_adv The neighbor advertisement in @p pkt. - * @param[in] icmpv6_size The overall size of the neighbor advertisement. - */ -void gnrc_ndp_nbr_adv_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt, - ipv6_hdr_t *ipv6, ndp_nbr_adv_t *nbr_adv, - size_t icmpv6_size); - -#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER)) -/** - * @brief Handles received router solicitations. - * - * @param[in] iface The receiving interface. - * @param[in] pkt The received packet. - * @param[in] ipv6 The IPv6 header in @p pkt. - * @param[in] rtr_sol The router solicitation in @p pkt. - * @param[in] icmpv6_size The overall size of the router solicitation. - */ -void gnrc_ndp_rtr_sol_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt, - ipv6_hdr_t *ipv6, ndp_rtr_sol_t *rtr_sol, - size_t icmpv6_size); -#else -/** - * @brief A host *must* silently discard all received router solicitations. - * @see <a href="https://tools.ietf.org/html/rfc4861#section-6.2.6"> - * RFC 4861, section 6.2.6 - * </a> - * - * This macro is primarily an optimization to not go into the function defined - * above. - */ -#define gnrc_ndp_rtr_sol_handle(iface, pkt, ipv6, rtr_sol, size) -#endif - -/** - * @brief Handles received router advertisements - * - * @todo As router check consistency as described in RFC 4861, section 6.2.3 - * - * @param[in] iface The receiving interface. - * @param[in] pkt The received packet. - * @param[in] ipv6 The IPv6 header in @p pkt. - * @param[in] rtr_adv The router advertisement in @p pkt. - * @param[in] icmpv6_size The overall size of the router advertisement. - */ -void gnrc_ndp_rtr_adv_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt, - ipv6_hdr_t *ipv6, ndp_rtr_adv_t *rtr_adv, - size_t icmpv6_size); - -/** - * @brief Retransmits a multicast neighbor solicitation for an incomplete or - * probing neighbor cache entry @p nc_entry, - * if nc_entry::probes_remaining > 0. - * - * @details If nc_entry::probes_remaining > 0 it will be decremented. If it - * reaches 0 it the entry @p nc_entry will be removed from the - * neighbor cache. - * - * @param[in] nc_entry A neighbor cache entry. Will be ignored if its state - * is not @ref GNRC_IPV6_NC_STATE_INCOMPLETE or - * @ref GNRC_IPV6_NC_STATE_PROBE. - */ -void gnrc_ndp_retrans_nbr_sol(gnrc_ipv6_nc_t *nc_entry); - -/** - * @brief Event handler for a neighbor cache state timeout. - * - * @param[in] nc_entry A neighbor cache entry. - */ -void gnrc_ndp_state_timeout(gnrc_ipv6_nc_t *nc_entry); - -/** - * @brief Get link-layer address and interface for next hop to destination - * IPv6 address. - * - * @param[out] l2addr The link-layer for the next hop to @p dst. - * @param[out] l2addr_len Length of @p l2addr. - * @param[in] iface The interface to search the next hop on. - * May be @ref KERNEL_PID_UNDEF if not specified. - * @param[in] dst An IPv6 address to search the next hop for. - * @param[in] pkt Packet to send to @p dst. Leave NULL if you - * just want to get the addresses. - * - * @return The PID of the interface, on success. - * @return -EHOSTUNREACH, if @p dst is not reachable. - * @return -ENOBUFS, if @p l2addr_len was smaller than the resulting @p l2addr - * would be long. - */ -kernel_pid_t gnrc_ndp_next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len, - kernel_pid_t iface, ipv6_addr_t *dst, - gnrc_pktsnip_t *pkt); - -/** - * @brief Builds a neighbor solicitation message for sending. - * - * @see <a href="https://tools.ietf.org/html/rfc4861#section-4.3"> - * RFC 4861, section 4.3 - * </a> - * - * @param[in] tgt The target address. - * @param[in] options Options to append to the router solicitation. - * - * @return The resulting ICMPv6 packet on success. - * @return NULL, on failure. - */ -gnrc_pktsnip_t *gnrc_ndp_nbr_sol_build(ipv6_addr_t *tgt, gnrc_pktsnip_t *options); - -/** - * @brief Builds a neighbor advertisement message for sending. - * - * @see <a href="https://tools.ietf.org/html/rfc4861#section-4.4"> - * RFC 4861, section 4.4 - * </a> - * - * @param[in] flags Neighbor advertisement flags: - * @ref NDP_NBR_ADV_FLAGS_R == 1 indicates, that the - * sender is a router, - * @ref NDP_NBR_ADV_FLAGS_S == 1 indicates that the - * advertisement was sent in response to a neighbor - * solicitation, - * @ref NDP_NBR_ADV_FLAGS_O == 1 indicates that the - * advertisement should override an existing cache entry - * and update the cached link-layer address. - * @param[in] tgt For solicited advertisements, the Target Address field - * in the neighbor solicitaton. - * For and unsolicited advertisement, the address whose - * link-layer address has changed. - * MUST NOT be multicast. - * @param[in] options Options to append to the neighbor advertisement. - * - * @return The resulting ICMPv6 packet on success. - * @return NULL, on failure. - */ -gnrc_pktsnip_t *gnrc_ndp_nbr_adv_build(uint8_t flags, ipv6_addr_t *tgt, - gnrc_pktsnip_t *options); - -/** - * @brief Builds a router solicitation message for sending. - * - * @see <a href="https://tools.ietf.org/html/rfc4861#section-4.1"> - * RFC 4861, section 4.1 - * </a> - * - * @param[in] options Options to append to the router solicitation. - * - * @return The resulting ICMPv6 packet on success. - * @return NULL, on failure. - */ -gnrc_pktsnip_t *gnrc_ndp_rtr_sol_build(gnrc_pktsnip_t *options); - -/** - * @brief Builds a router solicitation message for sending. - * - * @see <a href="https://tools.ietf.org/html/rfc4861#section-4.1"> - * RFC 4861, section 4.1 - * </a> - * - * @param[in] options Options to append to the router solicitation. - * - * @return The resulting ICMPv6 packet on success. - * @return NULL, on failure. - */ -gnrc_pktsnip_t *gnrc_ndp_rtr_sol_build(gnrc_pktsnip_t *options); - -#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER)) -/** - * @brief Builds a router advertisement message for sending. - * - * @see <a href="https://tools.ietf.org/html/rfc4861#section-4.2"> - * RFC 4861, section 4.2 - * </a> - * - * @note The source address for the packet MUST be the link-local address - * of the interface. - * - * @param[in] cur_hl Default hop limit for outgoing IP packets, 0 if - * unspecified by this router. - * @param[in] flags Flags as defined above. - * @ref NDP_RTR_ADV_FLAGS_M == 1 indicates, that the - * addresses are managed by DHCPv6, - * @ref NDP_RTR_ADV_FLAGS_O == 1 indicates that other - * configuration information is available via DHCPv6. - * @param[in] ltime Lifetime of the default router in seconds. - * @param[in] reach_time Time in milliseconds a node should assume a neighbor - * reachable. 0 means unspecified by the router. - * @param[in] retrans_timer Time in milliseconds between retransmitted - * neighbor solicitations. 0 means unspecified by - * the router. - * @param[in] options Options to append to the router advertisement. - * - * @return The resulting ICMPv6 packet on success. - * @return NULL, on failure. - */ -gnrc_pktsnip_t *gnrc_ndp_rtr_adv_build(uint8_t cur_hl, uint8_t flags, uint16_t ltime, - uint32_t reach_time, uint32_t retrans_timer, - gnrc_pktsnip_t *options); -#else -/** - * @brief A host *must not* send router advertisements at any time (so why build them?) - * @see <a href="https://tools.ietf.org/html/rfc4861#section-6.3.4"> - * RFC 4861, section 6.3.4 - * </a> - * - * This macro is primarily an optimization to not go into the function defined - * above. - */ -#define gnrc_ndp_rtr_adv_build(cur_hl, flags, ltime, reach_time, retrans_timer, options) (NULL) -#endif - -/** - * @brief Builds a generic NDP option. - * - * @param[in] type Type of the option. - * @param[in] size Size in byte of the option (will be rounded up to the next - * multiple of 8). - * @param[in] next More options in the packet. NULL, if there are none. - * - * @return The packet snip list of options, on success - * @return NULL, if packet buffer is full - */ -gnrc_pktsnip_t *gnrc_ndp_opt_build(uint8_t type, size_t size, gnrc_pktsnip_t *next); - -/** - * @brief Builds the source link-layer address option. - * - * @see <a href="https://tools.ietf.org/html/rfc4861#section-4.6.1"> - * RFC 4861, section 4.6.1 - * </a> - * - * @note Must only be used with neighbor solicitations, router solicitations, - * and router advertisements. This is not checked however, since - * hosts should silently ignore it in other NDP messages. - * - * @param[in] l2addr A link-layer address of variable length. - * @param[in] l2addr_len Length of @p l2addr. - * @param[in] next More options in the packet. NULL, if there are none. - * - * @return The packet snip list of options, on success - * @return NULL, if packet buffer is full - */ -gnrc_pktsnip_t *gnrc_ndp_opt_sl2a_build(const uint8_t *l2addr, uint8_t l2addr_len, - gnrc_pktsnip_t *next); - -/** - * @brief Builds the target link-layer address option. - * - * @see <a href="https://tools.ietf.org/html/rfc4861#section-4.6.1"> - * RFC 4861, section 4.6.1 - * </a> - * - * @note Must only be used with neighbor advertisemnents and redirect packets. - * This is not checked however, since hosts should silently ignore it - * in other NDP messages. - * - * @param[in] l2addr A link-layer address of variable length. - * @param[in] l2addr_len Length of @p l2addr. - * @param[in] next More options in the packet. NULL, if there are none. - * - * @return The pkt snip list of options, on success - * @return NULL, if packet buffer is full - */ -gnrc_pktsnip_t *gnrc_ndp_opt_tl2a_build(const uint8_t *l2addr, uint8_t l2addr_len, - gnrc_pktsnip_t *next); - -#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER)) -/** - * @brief Builds the prefix information option. - * - * @see <a href="https://tools.ietf.org/html/rfc4861#section-4.6.2"> - * RFC 4861, section 4.6.2 - * </a> - * - * @note Must only be used with router advertisemnents. This is not checked - * however, since nodes should silently ignore it in other NDP messages. - * - * @param[in] prefix_len The length of @p prefix in bits. Must be between - * 0 and 128. - * @param[in] flags Flags as defined above. - * @ref NDP_OPT_PI_FLAGS_L == 1 indicates, that - * @p prefix can be used for on-link determination, - * @ref NDP_OPT_PI_FLAGS_A == 1 indicates, that - * @p prefix can be used for stateless address - * configuration. - * @param[in] valid_ltime Length of time in seconds that @p prefix is valid. - * UINT32_MAX represents infinity. - * @param[in] pref_ltime Length of time in seconds that addresses using - * @p prefix remain prefered. UINT32_MAX represents - * infinity. - * @param[in] prefix An IPv6 address or a prefix of an IPv6 address. - * @param[in] next More options in the packet. NULL, if there are none. - * - * @return The packet snip list of options, on success - * @return NULL, if packet buffer is full - */ -gnrc_pktsnip_t *gnrc_ndp_opt_pi_build(uint8_t prefix_len, uint8_t flags, - uint32_t valid_ltime, uint32_t pref_ltime, - ipv6_addr_t *prefix, gnrc_pktsnip_t *next); - -/** - * @brief Builds the MTU option. - * - * @see <a href="https://tools.ietf.org/html/rfc4861#section-4.6.4"> - * RFC 4861, section 4.6.4 - * </a> - * - * @note Must only be used with router advertisemnents. This is not checked - * however, since nodes should silently ignore it in other NDP messages. - * - * @param[in] mtu The recommended MTU for the link. - * @param[in] next More options in the packet. NULL, if there are none. - * - * @return The packet snip list of options, on success - * @return NULL, if packet buffer is full - */ -gnrc_pktsnip_t *gnrc_ndp_opt_mtu_build(uint32_t mtu, gnrc_pktsnip_t *next); -#else -/** - * @brief A host *must not* send router advertisements at any time (so why build their options?) - * @see <a href="https://tools.ietf.org/html/rfc4861#section-6.3.4"> - * RFC 4861, section 6.3.4 - * </a> - * - * This macro is primarily an optimization to not go into the function defined - * above. - */ -#define gnrc_ndp_opt_pi_build(prefix_len, flags, valid_ltime, pref_ltime, prefix, next) (NULL) - -/** - * @brief A host *must not* send router advertisements at any time (so why build their options?) - * @see <a href="https://tools.ietf.org/html/rfc4861#section-6.3.4"> - * RFC 4861, section 6.3.4 - * </a> - * - * This macro is primarily an optimization to not go into the function defined - * above. - */ -#define gnrc_ndp_opt_mtu_build(mtu, next) (NULL) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* NET_GNRC_NDP_H */ -/** - * @} - */ diff --git a/sys/include/net/gnrc/ndp/host.h b/sys/include/net/gnrc/ndp/host.h deleted file mode 100644 index c67090a3d3260e86fc0621b5bdbf78e2e15198ec..0000000000000000000000000000000000000000 --- a/sys/include/net/gnrc/ndp/host.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @defgroup net_gnrc_ndp_host Host-specific part of router discovery. - * @ingroup net_gnrc_ndp - * @brief Host-specific part for the router discovery in IPv6 - * neighbor discovery. - * @{ - * - * @file - * @brief Host-specific router discovery definitions - * - * @author Martine Lenders <mlenders@inf.fu-berlin.de> - */ -#ifndef NET_GNRC_NDP_HOST_H -#define NET_GNRC_NDP_HOST_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* NET_GNRC_NDP_HOST_H */ -/** @} */ diff --git a/sys/include/net/gnrc/ndp/internal.h b/sys/include/net/gnrc/ndp/internal.h deleted file mode 100644 index 13fd68e357487e78177583a64e3c32851d2dd4f9..0000000000000000000000000000000000000000 --- a/sys/include/net/gnrc/ndp/internal.h +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @defgroup net_gnrc_ndp_internal Internal functions for neighbor discovery. - * @ingroup net_gnrc_ndp - * @brief Internal functions for neighbor discovery. - * @internal - * @note Only for use with a neighbor discovery implementations. - * @{ - * - * @file - * @brief Internal neighbor discovery functions for neighbor discovery. - * - * @author Martine Lenders <mlenders@inf.fu-berlin.de> - */ -#ifndef NET_GNRC_NDP_INTERNAL_H -#define NET_GNRC_NDP_INTERNAL_H - -#include "kernel_types.h" -#include "net/gnrc/ipv6/nc.h" -#include "net/ipv6/addr.h" -#include "net/ipv6/hdr.h" -#include "net/ndp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Get best match from default router list. - * - * @internal - * - * @see <a href="https://tools.ietf.org/html/rfc4861#section-6.3.6"> - * RFC 4861, section 6.3.6 - * </a> - * - * @return Address to a default router. - * @return NULL, if the default router list is empty. - */ -ipv6_addr_t *gnrc_ndp_internal_default_router(void); - -/** - * @brief Sets state of a neighbor cache entry and triggers required actions. - * - * @internal - * - * @param[in] nc_entry A neighbor cache entry. - * @param[in] state The new state for the neighbor cache entry. - */ -void gnrc_ndp_internal_set_state(gnrc_ipv6_nc_t *nc_entry, uint8_t state); - -/** - * @brief Send precompiled neighbor solicitation. - * - * @internal - * - * @param[in] iface Interface to send over. May not be KERNEL_PID_UNDEF. - * @param[in] src Source address for the neighbor solicitation. Will be chosen from the - * interface according to @p dst, if NULL. - * @param[in] tgt Target address for the neighbor solicitation. May not be - * NULL. - * @param[in] dst Destination address for neighbor solicitation. May not be - * NULL. - */ -void gnrc_ndp_internal_send_nbr_sol(kernel_pid_t iface, ipv6_addr_t *src, ipv6_addr_t *tgt, - ipv6_addr_t *dst); - -/** - * @brief Send precompiled neighbor advertisement. - * - * @internal - * - * @param[in] iface Interface to send over. May not be KERNEL_PID_UNDEF. - * @param[in] tgt Target address for the neighbor solicitation. May - * not be NULL. - * @param[in] dst Destination address for neighbor solicitation. May - * not be NULL. - * @param[in] supply_tl2a Add target link-layer address option to neighbor - * advertisement if link-layer has addresses. - * @param[in] ext_opts External options for the neighbor advertisement. Leave NULL for none. - * **Warning:** these are not tested if they are suitable for a - * neighbor advertisement so be sure to check that. - * **Will be released** in an error case. - */ -void gnrc_ndp_internal_send_nbr_adv(kernel_pid_t iface, ipv6_addr_t *tgt, ipv6_addr_t *dst, - bool supply_tl2a, gnrc_pktsnip_t *ext_opts); - -/** - * @brief Send precompiled router solicitation to @p dst. - * - * @internal - * - * @param[in] iface Interface to send over. May not be KERNEL_PID_UNDEF. - * @param[in] dst Destination for the router solicitation. ff02::2 if NULL. - */ -void gnrc_ndp_internal_send_rtr_sol(kernel_pid_t iface, ipv6_addr_t *dst); - -#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER)) -/** - * @brief Handles received router solicitations. - * - * @param[in] iface Interface to send over. May not be KERNEL_PID_UNDEF. - * @param[in] src Source address for the router advertisement. May be NULL to be determined - * by source address selection (:: if no @p iface has no address). - * @param[in] dst Destination address for router advertisement. - * @ref IPV6_ADDR_ALL_NODES_LINK_LOCAL if NULL. - * @param[in] fin This is part of the router's final batch of router advertisements - * before ceising to be a router (set's router lifetime field to 0). - */ -void gnrc_ndp_internal_send_rtr_adv(kernel_pid_t iface, ipv6_addr_t *src, - ipv6_addr_t *dst, bool fin); -#else -/** - * @brief A host *must not* send router advertisements at any time. - * - * This macro is primarily an optimization to not go into the function defined - * above. - */ -#define gnrc_ndp_internal_send_rtr_adv(iface, src, dst, fin) -#endif - -/** - * @brief Handles a SL2A option. - * - * @param[in] pkt Packet the option was received in. - * @param[in] ipv6 IPv6 header of @p pkt - * @param[in] icmpv6_type ICMPv6 type of the message carrying the option. - * @param[in] tl2a_opt The TL2A option. - * @param[out] l2addr The L2 address carried in the SL2A option. - * - * @return length of the L2 address, on success. - * @return -EINVAL, if SL2A was not valid. - * @return -ENOTSUP, if node should silently ignore the option. - */ -int gnrc_ndp_internal_sl2a_opt_handle(gnrc_pktsnip_t *pkt, ipv6_hdr_t *ipv6, uint8_t icmpv6_type, - ndp_opt_t *sl2a_opt, uint8_t *l2addr); - -/** - * @brief Handles a TL2A option. - * - * @param[in] pkt Packet the option was received in. - * @param[in] ipv6 IPv6 header of @p pkt - * @param[in] icmpv6_type ICMPv6 type of the message carrying the option. - * @param[in] tl2a_opt The TL2A option. - * @param[out] l2addr The L2 address carried in the TL2A option. - * - * @return length of the L2 address, on success. - * @return -EINVAL, if TL2A was not valid. - * @return -ENOTSUP, if node should silently ignore the option. - */ -int gnrc_ndp_internal_tl2a_opt_handle(gnrc_pktsnip_t *pkt, ipv6_hdr_t *ipv6, - uint8_t icmpv6_type, ndp_opt_t *tl2a_opt, - uint8_t *l2addr); - -/** - * @brief Handles a MTU option. - * - * @internal - * - * @param[in] iface Interface the MTU option was received on. - * @param[in] icmpv6_type ICMPv6 type of the message carrying the option. - * @param[in] mtu_opt A MTU option. - * - * @return true, on success (or if the node should silently ignore the option). - * @return false, if MTU option was not valid. - */ -bool gnrc_ndp_internal_mtu_opt_handle(kernel_pid_t iface, uint8_t icmpv6_type, - ndp_opt_mtu_t *mtu_opt); - -/** - * @brief Handles a PI option. - * - * @internal - * - * @param[in] iface Interface the PI option was received on. - * @param[in] icmpv6_type ICMPv6 type of the message carrying the option. - * @param[in] pi_opt A PI option. - * - * @return true, on success (or if the node should silently ignore the option). - * @return false, if PIO was not valid. - */ -bool gnrc_ndp_internal_pi_opt_handle(kernel_pid_t iface, uint8_t icmpv6_type, - ndp_opt_pi_t *pi_opt); - -/** - * @brief Resets the gnrc_ipv6_nc_t::nbr_sol_timer. - * - * @internal - * - * @param[in] nc_entry A neighbor cache entry. - * @param[in] delay The delay when the timer should fire. - * @param[in] type The msg_t::type for the timer. - * @param[in] pid The pid of the receiver thread of the msg_t - */ -static inline void gnrc_ndp_internal_reset_nbr_sol_timer(gnrc_ipv6_nc_t *nc_entry, uint32_t delay, - uint16_t type, kernel_pid_t pid) -{ - xtimer_remove(&nc_entry->nbr_sol_timer); - nc_entry->nbr_sol_msg.type = type; - xtimer_set_msg(&nc_entry->nbr_sol_timer, delay, &nc_entry->nbr_sol_msg, pid); -} - -#ifdef __cplusplus -} -#endif - -#endif /* NET_GNRC_NDP_INTERNAL_H */ -/** @} */ diff --git a/sys/include/net/gnrc/ndp/node.h b/sys/include/net/gnrc/ndp/node.h deleted file mode 100644 index 61ef12e14f0f99f7a48f5f996ebca423fe3a35e1..0000000000000000000000000000000000000000 --- a/sys/include/net/gnrc/ndp/node.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @defgroup net_gnrc_ndp_node Neighbor discovery for pure IPv6 nodes - * @ingroup net_gnrc_ndp - * @brief Used for pure IPv6 nodes (without 6LoWPAN). - * @{ - * - * @file - * @brief IPv6-node neighbor discovery definitions - * - * @author Martine Lenders <mlenders@inf.fu-berlin.de> - */ -#ifndef NET_GNRC_NDP_NODE_H -#define NET_GNRC_NDP_NODE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Get link-layer address and interface for next hop to destination - * IPv6 address. - * - * @param[out] l2addr The link-layer for the next hop to @p dst. - * @param[out] l2addr_len Length of @p l2addr. - * @param[in] iface The interface to search the next hop on. - * May be @ref KERNEL_PID_UNDEF if not specified. - * @param[in] dst An IPv6 address to search the next hop for. - * @param[in] pkt Packet to send to @p dst. Leave NULL if you - * just want to get the addresses. - * - * @return The PID of the interface, on success. - * @return -EHOSTUNREACH, if @p dst is not reachable. - * @return -ENOBUFS, if @p l2addr_len was smaller than the resulting @p l2addr - * would be long. - */ -kernel_pid_t gnrc_ndp_node_next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len, - kernel_pid_t iface, ipv6_addr_t *dst, - gnrc_pktsnip_t *pkt); - -#ifdef __cplusplus -} -#endif - -#endif /* NET_GNRC_NDP_NODE_H */ -/** @} */ diff --git a/sys/include/net/gnrc/ndp/router.h b/sys/include/net/gnrc/ndp/router.h deleted file mode 100644 index 86a2a73921c431794c9f65ce9648e52f4dd0f34c..0000000000000000000000000000000000000000 --- a/sys/include/net/gnrc/ndp/router.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @defgroup net_gnrc_ndp_router Router-specific part of router discovery. - * @ingroup net_gnrc_ndp - * @brief Router-specific part for the router discovery in IPv6 - * neighbor discovery. - * @{ - * - * @file - * @brief Router-specific router discovery definitions - * - * @author Martine Lenders <mlenders@inf.fu-berlin.de> - */ -#ifndef NET_GNRC_NDP_ROUTER_H -#define NET_GNRC_NDP_ROUTER_H - -#include <stdbool.h> - -#include "kernel_types.h" -#include "net/ipv6/hdr.h" -#include "net/ndp.h" -#include "net/gnrc/ipv6/nc.h" -#include "timex.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Send an solicited router advertisement to IPv6 address of - * @p neighbor. - * - * @param[in] neighbor A neighbor cache entry. - */ -void gnrc_ndp_router_send_rtr_adv(gnrc_ipv6_nc_t *neighbor); - -#ifdef __cplusplus -} -#endif - -#endif /* NET_GNRC_NDP_ROUTER_H */ -/** @} */ diff --git a/sys/include/net/gnrc/sixlowpan/nd/router.h b/sys/include/net/gnrc/sixlowpan/nd/router.h deleted file mode 100644 index 3c11d6acce81b1dd46e31b47bcf8389b7c369fad..0000000000000000000000000000000000000000 --- a/sys/include/net/gnrc/sixlowpan/nd/router.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @defgroup net_gnrc_sixlowpan_nd_router Router-part of 6LoWPAN-ND - * @ingroup net_gnrc_sixlowpan_nd - * @brief Router-part of 6LoWPAN-ND - * @{ - * - * @file - * @brief Router-definitions for 6LoWPAN-ND. - * - * @author Martine Lenders <mlenders@inf.fu-berlin.de> - */ -#ifndef NET_GNRC_SIXLOWPAN_ND_ROUTER_H -#define NET_GNRC_SIXLOWPAN_ND_ROUTER_H - -#include <stdbool.h> - -#include "bitfield.h" -#include "net/gnrc/sixlowpan/ctx.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Number of registerable border routers - * - * @note More than one border routers require some way of synchronization - * of the context information (see - * [RFC 6775, section 8.1](https://tools.ietf.org/html/rfc6775#section-8.1)) - */ -#ifndef GNRC_SIXLOWPAN_ND_ROUTER_ABR_NUMOF -#define GNRC_SIXLOWPAN_ND_ROUTER_ABR_NUMOF (1) -#endif - -/** - * @brief The number of non-link-local prefixes associated with border routers - * at maximum. - */ -#ifndef GNRC_SIXLOWPAN_ND_ROUTER_ABR_PRF_NUMOF -/* One prefix per interface */ -#define GNRC_SIXLOWPAN_ND_ROUTER_ABR_PRF_NUMOF \ - (GNRC_SIXLOWPAN_ND_ROUTER_ABR_NUMOF * GNRC_NETIF_NUMOF) -#endif - -/** - * @brief Representation for prefixes coming from a router - */ -typedef struct gnrc_sixlowpan_nd_router_prf { - struct gnrc_sixlowpan_nd_router_prf *next; /**< next prefix */ -} gnrc_sixlowpan_nd_router_prf_t; - -/** - * @brief Abstract representation of a border router on all (border) routers. - */ -typedef struct { - ipv6_addr_t addr; /**< the IPv6 address of the border router (BR) */ - uint32_t version; /**< version of the information dissiminated by the - * BR */ - uint16_t ltime; /**< the time in minutes until deletion */ -#ifdef MODULE_GNRC_SIXLOWPAN_CTX - BITFIELD(ctxs, GNRC_SIXLOWPAN_CTX_SIZE);/**< contexts associated with BR */ -#endif - gnrc_sixlowpan_nd_router_prf_t *prfs; /**< prefixes associated with BR */ - xtimer_t ltimer; /**< timer for deletion */ - msg_t ltimer_msg; /**< msg_t for gnrc_sixlowpan_nd_router_abr_t::ltimer */ -} gnrc_sixlowpan_nd_router_abr_t; - -/** - * @brief Removes tentetative neighbor cache entries or sets registered ones to - * garbage-collectible. - * - * @param[in] nc_entry A neighbor cache entry. - */ -static inline void gnrc_sixlowpan_nd_router_gc_nc(gnrc_ipv6_nc_t *nc_entry) -{ - switch (gnrc_ipv6_nc_get_type(nc_entry)) { - case GNRC_IPV6_NC_TYPE_TENTATIVE: - case GNRC_IPV6_NC_TYPE_REGISTERED: - gnrc_ipv6_nc_remove(nc_entry->iface, &nc_entry->ipv6_addr); - break; - default: - break; - } - -} - -/** - * @brief Set @p netif to router mode. - * - * @details This sets/unsets the GNRC_IPV6_NETIF_FLAGS_ROUTER and initializes or ceases router - * behavior for 6LoWPAN neighbor discovery. - * - * @param[in] netif An IPv6 interface. Must not be NULL. - * @param[in] enable Status for the GNRC_IPV6_NETIF_FLAGS_ROUTER flag. - */ -static inline void gnrc_sixlowpan_nd_router_set_router(gnrc_ipv6_netif_t *netif, bool enable) -{ - if (enable) { - netif->flags |= GNRC_IPV6_NETIF_FLAGS_ROUTER; - } - else { - netif->flags &= ~GNRC_IPV6_NETIF_FLAGS_ROUTER; - } -} - -/** - * @brief Set/Unset GNRC_IPV6_NETIF_FLAGS_RTR_ADV flag for @p netif. - * - * @details GNRC_IPV6_NETIF_FLAGS_RTR_ADV and initializes or ceases - * periodic router advertising behavior for neighbor discovery. - * - * @param[in] netif An IPv6 interface. Must not be NULL. - * @param[in] enable Status for the GNRC_IPV6_NETIF_FLAGS_RTR_ADV flag. - */ -void gnrc_sixlowpan_nd_router_set_rtr_adv(gnrc_ipv6_netif_t *netif, bool enable); - -/** - * @brief Get's the border router for this router. - * - * @return The border router, if one is specified. - * @return NULL, otherwise. - */ -gnrc_sixlowpan_nd_router_abr_t *gnrc_sixlowpan_nd_router_abr_get(void); - -/** - * @brief Checks if the version data @p abr_opt is older than the version of the currently - * registered border router. - * - * @param[in] abr_opt An authoritative border router option containing potentially new - * information on the currently registered border router. - * - * @return true, if the information in @p abr_opt is newer. - * @return false, if the information in @p abr_opt is older. - */ -bool gnrc_sixlowpan_nd_router_abr_older(sixlowpan_nd_opt_abr_t *abr_opt); - -/** - * @brief Removes the border router and all the prefixes and contexts it disseminated through - * the network for this node. - * - * @param[in] abr The border router. - */ -void gnrc_sixlowpan_nd_router_abr_remove(gnrc_sixlowpan_nd_router_abr_t *abr); - -#ifdef MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER -/** - * @brief Makes this node a new border router. - * - * @pre addr != NULL - * - * @param[in] addr The local address to use in the ABROs - * @param[in] ltime The lifetime to advertise in the ABROs. 0 assumes a default value of - * @ref GNRC_SIXLOWPAN_ND_BORDER_ROUTER_DEFAULT_LTIME - * - * @return The new border router object. - * @return NULL, on error. - */ -gnrc_sixlowpan_nd_router_abr_t *gnrc_sixlowpan_nd_router_abr_create(ipv6_addr_t *addr, - unsigned int ltime); - -/** - * @brief Adds a prefix for this border router to manage. - * - * @pre iface != NULL && prefix != NULL - * - * @param[in] abr The local border router. - * @param[in] iface The IPv6 interface the prefix was added to. - * @param[in] prefix The prefix. - * - * @return 0, on success - * @return -ENOMEM, if no space for the new prefix is available. - * @return -ENOENT, if @p abr is not registered. - */ -int gnrc_sixlowpan_nd_router_abr_add_prf(gnrc_sixlowpan_nd_router_abr_t* abr, - gnrc_ipv6_netif_t *iface, gnrc_ipv6_netif_addr_t *prefix); - -/** - * @brief Removes a prefix from this border router. - * - * @param[in] abr The local border router. - * @param[in] iface The IPv6 interface the prefix was added to. - * @param[in] prefix The prefix. - */ -void gnrc_sixlowpan_nd_router_abr_rem_prf(gnrc_sixlowpan_nd_router_abr_t *abr, - gnrc_ipv6_netif_t *iface, gnrc_ipv6_netif_addr_t *prefix); - -/** - * @brief Adds a context for this border router to manage. - * - * @param[in] abr The local border router - * @param[in] cid The context to be add. - * - * @return 0, on success - * @return -EINVAL, if @p ctx is greater than 15. - * @return -ENOENT, if @p abr is not registered. - */ -int gnrc_sixlowpan_nd_router_abr_add_ctx(gnrc_sixlowpan_nd_router_abr_t *abr, uint8_t cid); - -/** - * @brief Removes a context from this border router. - * - * @param[in] abr The local border router. - * @param[in] cid The context to be remove. - */ -void gnrc_sixlowpan_nd_router_abr_rem_ctx(gnrc_sixlowpan_nd_router_abr_t *abr, uint8_t cid); -#else -#define gnrc_sixlowpan_nd_router_abr_create(addr, ltime) (NULL) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* NET_GNRC_SIXLOWPAN_ND_ROUTER_H */ -/** @} */ diff --git a/sys/net/gnrc/Makefile b/sys/net/gnrc/Makefile index a26ecff645f3680683e590391cff538cc7b263d4..61d132a635fdeb6239bc74d797b5e1ce338e748e 100644 --- a/sys/net/gnrc/Makefile +++ b/sys/net/gnrc/Makefile @@ -16,9 +16,6 @@ endif ifneq (,$(filter gnrc_ipv6_hdr,$(USEMODULE))) DIRS += network_layer/ipv6/hdr endif -ifneq (,$(filter gnrc_ipv6_nc,$(USEMODULE))) - DIRS += network_layer/ipv6/nc -endif ifneq (,$(filter gnrc_ipv6_nib,$(USEMODULE))) DIRS += network_layer/ipv6/nib endif @@ -28,21 +25,6 @@ endif ifneq (,$(filter gnrc_ipv6_blacklist,$(USEMODULE))) DIRS += network_layer/ipv6/blacklist endif -ifneq (,$(filter gnrc_ndp,$(USEMODULE))) - DIRS += network_layer/ndp -endif -ifneq (,$(filter gnrc_ndp_internal,$(USEMODULE))) - DIRS += network_layer/ndp/internal -endif -ifneq (,$(filter gnrc_ndp_host,$(USEMODULE))) - DIRS += network_layer/ndp/host -endif -ifneq (,$(filter gnrc_ndp_node,$(USEMODULE))) - DIRS += network_layer/ndp/node -endif -ifneq (,$(filter gnrc_ndp_router,$(USEMODULE))) - DIRS += network_layer/ndp/router -endif ifneq (,$(filter gnrc_ndp2,$(USEMODULE))) DIRS += network_layer/ndp2 endif @@ -106,9 +88,6 @@ endif ifneq (,$(filter gnrc_sixlowpan_nd,$(USEMODULE))) DIRS += network_layer/sixlowpan/nd endif -ifneq (,$(filter gnrc_sixlowpan_nd_router,$(USEMODULE))) - DIRS += network_layer/sixlowpan/nd/router -endif ifneq (,$(filter gnrc_sock,$(USEMODULE))) DIRS += sock endif diff --git a/sys/net/gnrc/network_layer/icmpv6/gnrc_icmpv6.c b/sys/net/gnrc/network_layer/icmpv6/gnrc_icmpv6.c index 9184a29b88149a2f2a9ba125cdec4e34c5dbf94a..b7ab3a3ae5477eba974f8f0c25469d1f86b72a5e 100644 --- a/sys/net/gnrc/network_layer/icmpv6/gnrc_icmpv6.c +++ b/sys/net/gnrc/network_layer/icmpv6/gnrc_icmpv6.c @@ -73,8 +73,7 @@ void gnrc_icmpv6_demux(kernel_pid_t iface, gnrc_pktsnip_t *pkt) return; } - /* Note: size will be checked again in gnrc_icmpv6_echo_req_handle, - gnrc_ndp_rtr_sol_handle, and others */ + /* Note: size will be checked again in packet handlers */ hdr = (icmpv6_hdr_t *)icmpv6->data; diff --git a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c index 664eb2682c0dac705ce7ece56c7e05d1cfa34aee..c612768753c7eec59e7821d8bf85dede2ba10742 100644 --- a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c +++ b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c @@ -21,10 +21,8 @@ #include "kernel_types.h" #include "net/gnrc.h" #include "net/gnrc/icmpv6.h" -#include "net/gnrc/ndp.h" #include "net/gnrc/sixlowpan/ctx.h" #include "net/gnrc/sixlowpan/nd.h" -#include "net/gnrc/sixlowpan/nd/router.h" #include "net/protnum.h" #include "thread.h" #include "utlist.h" diff --git a/sys/net/gnrc/network_layer/ipv6/nc/Makefile b/sys/net/gnrc/network_layer/ipv6/nc/Makefile deleted file mode 100644 index d0c37ac776a08334721646aa0814e98e063e0829..0000000000000000000000000000000000000000 --- a/sys/net/gnrc/network_layer/ipv6/nc/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -MODULE = gnrc_ipv6_nc - -include $(RIOTBASE)/Makefile.base diff --git a/sys/net/gnrc/network_layer/ipv6/nc/gnrc_ipv6_nc.c b/sys/net/gnrc/network_layer/ipv6/nc/gnrc_ipv6_nc.c deleted file mode 100644 index 417a442b160663ab362e5a425d637ec26396e3b3..0000000000000000000000000000000000000000 --- a/sys/net/gnrc/network_layer/ipv6/nc/gnrc_ipv6_nc.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @{ - * - * @file - */ - -#include <errno.h> -#include <string.h> - -#include "net/gnrc/ipv6.h" -#include "net/ipv6/addr.h" -#include "net/gnrc/ipv6/nc.h" -#include "net/gnrc/ipv6/netif.h" -#include "net/gnrc/ndp.h" -#include "net/gnrc/pktbuf.h" -#include "net/gnrc/sixlowpan/nd.h" -#include "thread.h" -#include "xtimer.h" - -#define ENABLE_DEBUG (0) -#include "debug.h" - -#if ENABLE_DEBUG -/* For PRIu8 etc. */ -#include <inttypes.h> - -static char addr_str[IPV6_ADDR_MAX_STR_LEN]; -#endif - -static gnrc_ipv6_nc_t ncache[GNRC_IPV6_NC_SIZE]; - -static void _nc_remove(kernel_pid_t iface, gnrc_ipv6_nc_t *entry) -{ - (void) iface; - if (entry == NULL) { - return; - } - - DEBUG("ipv6_nc: Remove %s for interface %" PRIkernel_pid "\n", - ipv6_addr_to_str(addr_str, &(entry->ipv6_addr), sizeof(addr_str)), - iface); - -#ifdef MODULE_GNRC_NDP_NODE - while (entry->pkts != NULL) { - gnrc_pktbuf_release(entry->pkts->pkt); - entry->pkts->pkt = NULL; - gnrc_pktqueue_remove_head(&entry->pkts); - } -#endif -#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER - xtimer_remove(&entry->type_timeout); - - gnrc_ipv6_netif_t *if_entry = gnrc_ipv6_netif_get(iface); - - if ((if_entry != NULL) && (if_entry->rtr_adv_msg.content.ptr == entry)) { - /* cancel timer set by gnrc_ndp_rtr_sol_handle */ - xtimer_remove(&if_entry->rtr_adv_timer); - } -#endif -#if defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER) - xtimer_remove(&entry->rtr_adv_timer); -#endif - - xtimer_remove(&entry->rtr_timeout); - xtimer_remove(&entry->nbr_sol_timer); - xtimer_remove(&entry->nbr_adv_timer); - - ipv6_addr_set_unspecified(&(entry->ipv6_addr)); - entry->iface = KERNEL_PID_UNDEF; - entry->flags = 0; -} - -void gnrc_ipv6_nc_init(void) -{ - gnrc_ipv6_nc_t *entry; - - for (entry = ncache; entry < (ncache + GNRC_IPV6_NC_SIZE); entry++) { - _nc_remove(entry->iface, entry); - } - memset(ncache, 0, sizeof(ncache)); -} - -gnrc_ipv6_nc_t *_find_free_entry(void) -{ - for (int i = 0; i < GNRC_IPV6_NC_SIZE; i++) { - if (ipv6_addr_is_unspecified(&(ncache[i].ipv6_addr))) { - return ncache + i; - } - } - - return NULL; -} - -gnrc_ipv6_nc_t *gnrc_ipv6_nc_add(kernel_pid_t iface, const ipv6_addr_t *ipv6_addr, - const void *l2_addr, size_t l2_addr_len, uint8_t flags) -{ - gnrc_ipv6_nc_t *free_entry = NULL; - - if (ipv6_addr == NULL) { - DEBUG("ipv6_nc: address was NULL\n"); - return NULL; - } - - if ((l2_addr_len > GNRC_IPV6_NC_L2_ADDR_MAX) || ipv6_addr_is_unspecified(ipv6_addr)) { - DEBUG("ipv6_nc: invalid parameters\n"); - return NULL; - } - - for (int i = 0; i < GNRC_IPV6_NC_SIZE; i++) { - if (ipv6_addr_equal(&(ncache[i].ipv6_addr), ipv6_addr)) { - DEBUG("ipv6_nc: Address %s already registered.\n", - ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str))); - - if ((l2_addr != NULL) && (l2_addr_len > 0)) { - DEBUG("ipv6_nc: Update to L2 address %s", - gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), - l2_addr, l2_addr_len)); - - memcpy(&(ncache[i].l2_addr), l2_addr, l2_addr_len); - ncache[i].l2_addr_len = l2_addr_len; - ncache[i].flags = flags; - DEBUG(" with flags = 0x%0x\n", flags); - - } - return &ncache[i]; - } - - if (ipv6_addr_is_unspecified(&(ncache[i].ipv6_addr)) && !free_entry) { - /* found the first free entry */ - free_entry = &ncache[i]; - } - } - - if (!free_entry) { - /* reached end of NC without finding updateable or free entry */ - DEBUG("ipv6_nc: neighbor cache full.\n"); - return NULL; - } - - /* Otherwise, fill free entry with your fresh information */ - free_entry->iface = iface; - -#ifdef MODULE_GNRC_NDP_NODE - free_entry->pkts = NULL; -#endif - memcpy(&(free_entry->ipv6_addr), ipv6_addr, sizeof(ipv6_addr_t)); - DEBUG("ipv6_nc: Register %s for interface %" PRIkernel_pid, - ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str)), - iface); - - if ((l2_addr != NULL) && (l2_addr_len > 0)) { - DEBUG(" to L2 address %s", - gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), - l2_addr, l2_addr_len)); - memcpy(&(free_entry->l2_addr), l2_addr, l2_addr_len); - free_entry->l2_addr_len = l2_addr_len; - } - - free_entry->flags = flags; - - DEBUG(" with flags = 0x%0x\n", flags); - - if (gnrc_ipv6_nc_get_state(free_entry) == GNRC_IPV6_NC_STATE_INCOMPLETE) { - DEBUG("ipv6_nc: Set remaining probes to %" PRIu8 "\n", (uint8_t) GNRC_NDP_MAX_MC_NBR_SOL_NUMOF); - free_entry->probes_remaining = GNRC_NDP_MAX_MC_NBR_SOL_NUMOF; - } - -#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER - free_entry->type_timeout_msg.type = GNRC_SIXLOWPAN_ND_MSG_AR_TIMEOUT; - free_entry->type_timeout_msg.content.ptr = free_entry; -#endif - - free_entry->rtr_timeout_msg.type = GNRC_NDP_MSG_RTR_TIMEOUT; - free_entry->rtr_timeout_msg.content.ptr = free_entry; - -#if defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER) - free_entry->rtr_adv_msg.type = GNRC_NDP_MSG_RTR_ADV_DELAY; - free_entry->rtr_adv_msg.content.ptr = free_entry; -#endif - - free_entry->nbr_sol_msg.content.ptr = free_entry; - - return free_entry; -} - -void gnrc_ipv6_nc_remove(kernel_pid_t iface, const ipv6_addr_t *ipv6_addr) -{ - gnrc_ipv6_nc_t *entry = gnrc_ipv6_nc_get(iface, ipv6_addr); - _nc_remove(iface, entry); -} - -gnrc_ipv6_nc_t *gnrc_ipv6_nc_get(kernel_pid_t iface, const ipv6_addr_t *ipv6_addr) -{ - if ((ipv6_addr == NULL) || (ipv6_addr_is_unspecified(ipv6_addr))) { - DEBUG("ipv6_nc: address was NULL or ::\n"); - return NULL; - } - - for (int i = 0; i < GNRC_IPV6_NC_SIZE; i++) { - if (((ncache[i].iface == KERNEL_PID_UNDEF) || (iface == KERNEL_PID_UNDEF) || - (iface == ncache[i].iface)) && - ipv6_addr_equal(&(ncache[i].ipv6_addr), ipv6_addr)) { - DEBUG("ipv6_nc: Found entry for %s on interface %" PRIkernel_pid - " (0 = all interfaces) [%p]\n", - ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str)), - iface, (void *)(ncache + i)); - - return ncache + i; - } - } - - return NULL; -} - -gnrc_ipv6_nc_t *gnrc_ipv6_nc_get_next(gnrc_ipv6_nc_t *prev) -{ - if (prev == NULL) { - prev = ncache; - } - else { - prev++; /* get next entry */ - } - - while (prev < (ncache + GNRC_IPV6_NC_SIZE)) { /* while not reached end */ - if (!ipv6_addr_is_unspecified(&(prev->ipv6_addr))) { - return prev; - } - - prev++; - } - - return NULL; -} - -gnrc_ipv6_nc_t *gnrc_ipv6_nc_get_next_router(gnrc_ipv6_nc_t *prev) -{ - for (gnrc_ipv6_nc_t *router = gnrc_ipv6_nc_get_next(prev); router != NULL; - router = gnrc_ipv6_nc_get_next(router)) { - if (router->flags & GNRC_IPV6_NC_IS_ROUTER) { - return router; - } - } - - return NULL; -} - -gnrc_ipv6_nc_t *gnrc_ipv6_nc_still_reachable(const ipv6_addr_t *ipv6_addr) -{ - gnrc_ipv6_nc_t *entry = gnrc_ipv6_nc_get(KERNEL_PID_UNDEF, ipv6_addr); - - if (entry == NULL) { - DEBUG("ipv6_nc: No entry found for %s\n", - ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str))); - return NULL; - } - - if ((gnrc_ipv6_nc_get_state(entry) != GNRC_IPV6_NC_STATE_INCOMPLETE) && - (gnrc_ipv6_nc_get_state(entry) != GNRC_IPV6_NC_STATE_UNMANAGED)) { -#if defined(MODULE_GNRC_IPV6_NETIF) && defined(MODULE_XTIMER) && defined(MODULE_GNRC_IPV6) - gnrc_ipv6_netif_t *iface = gnrc_ipv6_netif_get(entry->iface); - - gnrc_ndp_internal_reset_nbr_sol_timer(entry, iface->reach_time, - GNRC_NDP_MSG_NC_STATE_TIMEOUT, gnrc_ipv6_pid); -#endif - - DEBUG("ipv6_nc: Marking entry %s as reachable\n", - ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str))); - entry->flags &= ~(GNRC_IPV6_NC_STATE_MASK >> GNRC_IPV6_NC_STATE_POS); - entry->flags |= (GNRC_IPV6_NC_STATE_REACHABLE >> GNRC_IPV6_NC_STATE_POS); - } - - return entry; -} - -kernel_pid_t gnrc_ipv6_nc_get_l2_addr(uint8_t *l2_addr, uint8_t *l2_addr_len, - const gnrc_ipv6_nc_t *entry) -{ - assert((l2_addr != NULL) && (l2_addr_len != NULL)); - if ((entry == NULL) || !gnrc_ipv6_nc_is_reachable(entry)) { - return KERNEL_PID_UNDEF; - } - *l2_addr_len = entry->l2_addr_len; - memcpy(l2_addr, entry->l2_addr, entry->l2_addr_len); - return entry->iface; -} - -/** @} */ diff --git a/sys/net/gnrc/network_layer/ndp/Makefile b/sys/net/gnrc/network_layer/ndp/Makefile deleted file mode 100644 index c4c1861f0b63827bf91b7bebe0b6f0ada7acfeaa..0000000000000000000000000000000000000000 --- a/sys/net/gnrc/network_layer/ndp/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -MODULE = gnrc_ndp - -include $(RIOTBASE)/Makefile.base diff --git a/sys/net/gnrc/network_layer/ndp/gnrc_ndp.c b/sys/net/gnrc/network_layer/ndp/gnrc_ndp.c deleted file mode 100644 index dd1845375e6777af4318eb65cf7d4da8494a92c9..0000000000000000000000000000000000000000 --- a/sys/net/gnrc/network_layer/ndp/gnrc_ndp.c +++ /dev/null @@ -1,900 +0,0 @@ -/* - * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> - * - * This file is subject to the terms and conditions of the GNU Lesser General - * Public License v2.1. See the file LICENSE in the top level directory for - * more details. - */ - -/** - * @ingroup net_gnrc_ndp - * @{ - * - * @file - * - * @author Martine Lenders <mlenders@inf.fu-berlin.de> - */ - -#include <errno.h> -#include <string.h> - -#include "byteorder.h" -#include "net/fib.h" -#include "net/ieee802154.h" -#include "net/ipv6/ext/rh.h" -#include "net/gnrc/icmpv6.h" -#include "net/gnrc/ipv6.h" -#include "net/gnrc/sixlowpan/nd.h" -#include "net/gnrc.h" -#include "net/sixlowpan/nd.h" -#include "random.h" -#include "utlist.h" -#include "thread.h" -#include "xtimer.h" - -#include "net/gnrc/ndp/internal.h" - -#include "net/gnrc/ndp.h" - -#define ENABLE_DEBUG (0) -#include "debug.h" - -#if ENABLE_DEBUG -/* For PRIu8 etc. */ -#include <inttypes.h> - -static char addr_str[IPV6_ADDR_MAX_STR_LEN]; -#endif - -/* sets an entry to stale if its l2addr differs from the given one or creates it stale if it - * does not exist */ -static void _stale_nc(kernel_pid_t iface, ipv6_addr_t *ipaddr, uint8_t *l2addr, - int l2addr_len) -{ - if (l2addr_len != -ENOTSUP) { - gnrc_ipv6_nc_t *nc_entry = gnrc_ipv6_nc_get(iface, ipaddr); - if (nc_entry == NULL) { - gnrc_ipv6_nc_add(iface, ipaddr, l2addr, (uint16_t)l2addr_len, - GNRC_IPV6_NC_STATE_STALE); - } -#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER - /* unreachable set in gnrc_ndp_retrans_nbr_sol() will just be staled */ - else if (gnrc_ipv6_nc_get_state(nc_entry) == GNRC_IPV6_NC_STATE_UNREACHABLE) { - gnrc_ndp_internal_set_state(nc_entry, GNRC_IPV6_NC_STATE_STALE); - } -#endif - else if (((uint16_t)l2addr_len != nc_entry->l2_addr_len) || - (memcmp(l2addr, nc_entry->l2_addr, l2addr_len) != 0)) { - /* if entry exists but l2 address differs: set */ - nc_entry->l2_addr_len = (uint16_t)l2addr_len; - memcpy(nc_entry->l2_addr, l2addr, l2addr_len); - gnrc_ndp_internal_set_state(nc_entry, GNRC_IPV6_NC_STATE_STALE); - } - } -} - -void gnrc_ndp_nbr_sol_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt, - ipv6_hdr_t *ipv6, ndp_nbr_sol_t *nbr_sol, - size_t icmpv6_size) -{ - uint16_t opt_offset = 0; - uint8_t l2src[GNRC_IPV6_NC_L2_ADDR_MAX]; - uint8_t *buf = ((uint8_t *)nbr_sol) + sizeof(ndp_nbr_sol_t); - ipv6_addr_t *tgt, nbr_adv_dst; - gnrc_pktsnip_t *nbr_adv_opts = NULL; -#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER - ndp_opt_t *sl2a_opt = NULL; - sixlowpan_nd_opt_ar_t *ar_opt = NULL; -#endif - int sicmpv6_size = (int)icmpv6_size, l2src_len = 0; - DEBUG("ndp: received neighbor solicitation (src: %s, ", - ipv6_addr_to_str(addr_str, &ipv6->src, sizeof(addr_str))); - DEBUG("dst: %s, ", - ipv6_addr_to_str(addr_str, &ipv6->dst, sizeof(addr_str))); - DEBUG("tgt: %s)\n", - ipv6_addr_to_str(addr_str, &nbr_sol->tgt, sizeof(addr_str))); - /* check validity */ - if ((ipv6->hl != 255) || (nbr_sol->code != 0) || - (icmpv6_size < sizeof(ndp_nbr_sol_t)) || - ipv6_addr_is_multicast(&nbr_sol->tgt) || - (ipv6_addr_is_unspecified(&ipv6->src) && - ipv6_addr_is_solicited_node(&ipv6->dst))) { - DEBUG("ndp: neighbor solicitation was invalid.\n"); - /* icmpv6 releases */ - return; - } - if ((tgt = gnrc_ipv6_netif_find_addr(iface, &nbr_sol->tgt)) == NULL) { - DEBUG("ndp: Target address is not to interface %" PRIkernel_pid "\n", - iface); - /* icmpv6 releases */ - return; - } - sicmpv6_size -= sizeof(ndp_nbr_sol_t); - while (sicmpv6_size > 0) { - ndp_opt_t *opt = (ndp_opt_t *)(buf + opt_offset); - switch (opt->type) { - case NDP_OPT_SL2A: - if ((l2src_len = gnrc_ndp_internal_sl2a_opt_handle(pkt, ipv6, nbr_sol->type, opt, - l2src)) < 0) { - /* -ENOTSUP can not happen, since the function only returns this for invalid - * message types containing the SL2A. Neighbor solicitations are not an - * invalid message type for SL2A. According to that, we don't need to watch - * out for that here, but regardless, the source link-layer address option - * is invalid. */ - return; - } -#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER - sl2a_opt = opt; - break; - case NDP_OPT_AR: - /* actually handling at the end of the function (see below) */ - ar_opt = (sixlowpan_nd_opt_ar_t *)opt; -#endif - break; - default: - /* silently discard all other options */ - break; - } - opt_offset += (opt->len * 8); - sicmpv6_size -= (opt->len * 8); - -#if ENABLE_DEBUG - if (sicmpv6_size < 0) { - DEBUG("ndp: Option parsing out of sync.\n"); - } -#endif - } -#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER - gnrc_ipv6_netif_t *ipv6_iface = gnrc_ipv6_netif_get(iface); - assert(ipv6_iface != NULL); - if ((sl2a_opt != NULL) && (ar_opt != NULL) && - (ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) && - (ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER)) { - uint8_t status = gnrc_sixlowpan_nd_opt_ar_handle(iface, ipv6, - nbr_sol->type, - &ipv6->src, ar_opt, - l2src, l2src_len); - /* check for multihop DAD return */ - nbr_adv_opts = gnrc_sixlowpan_nd_opt_ar_build(status, GNRC_SIXLOWPAN_ND_AR_LTIME, - &ar_opt->eui64, NULL); - if (status == 0) { - memcpy(&nbr_adv_dst, &ipv6->src, sizeof(ipv6_addr_t)); - } - else { - /* see https://tools.ietf.org/html/rfc6775#section-6.5.2 */ - eui64_t iid; - ieee802154_get_iid(&iid, ar_opt->eui64.uint8, sizeof(eui64_t)); - ipv6_addr_set_aiid(&nbr_adv_dst, iid.uint8); - ipv6_addr_set_link_local_prefix(&nbr_adv_dst); - } - } - else { /* gnrc_sixlowpan_nd_opt_ar_handle updates neighbor cache */ - _stale_nc(iface, &ipv6->src, l2src, l2src_len); - memcpy(&nbr_adv_dst, &ipv6->src, sizeof(ipv6_addr_t)); - } -#else - _stale_nc(iface, &ipv6->src, l2src, l2src_len); - memcpy(&nbr_adv_dst, &ipv6->src, sizeof(ipv6_addr_t)); -#endif - gnrc_ndp_internal_send_nbr_adv(iface, tgt, &nbr_adv_dst, ipv6_addr_is_multicast(&ipv6->dst), - nbr_adv_opts); -} - -static inline bool _pkt_has_l2addr(gnrc_netif_hdr_t *netif_hdr) -{ - return (netif_hdr != NULL) && (netif_hdr->src_l2addr_len != 0) && - (netif_hdr->dst_l2addr_len != 0); -} - -void gnrc_ndp_nbr_adv_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt, - ipv6_hdr_t *ipv6, ndp_nbr_adv_t *nbr_adv, - size_t icmpv6_size) -{ - uint16_t opt_offset = 0; - uint8_t *buf = ((uint8_t *)nbr_adv) + sizeof(ndp_nbr_adv_t); - int l2tgt_len = 0; - uint8_t l2tgt[GNRC_IPV6_NC_L2_ADDR_MAX]; - int sicmpv6_size = (int)icmpv6_size; - gnrc_ipv6_nc_t *nc_entry = gnrc_ipv6_nc_get(iface, &nbr_adv->tgt); - gnrc_pktsnip_t *netif; - gnrc_netif_hdr_t *netif_hdr = NULL; - - DEBUG("ndp: received neighbor advertisement (src: %s, ", - ipv6_addr_to_str(addr_str, &ipv6->src, sizeof(addr_str))); - DEBUG("dst: %s, ", - ipv6_addr_to_str(addr_str, &ipv6->dst, sizeof(addr_str))); - DEBUG("tgt: %s)\n", - ipv6_addr_to_str(addr_str, &nbr_adv->tgt, sizeof(addr_str))); - - /* check validity */ - if ((ipv6->hl != 255) || (nbr_adv->code != 0) || - (icmpv6_size < sizeof(ndp_nbr_adv_t)) || - ipv6_addr_is_multicast(&nbr_adv->tgt)) { - DEBUG("ndp: neighbor advertisement was invalid.\n"); - /* icmpv6 releases */ - return; - } - - if (nc_entry == NULL) { - /* see https://tools.ietf.org/html/rfc4861#section-7.2.5 */ - DEBUG("ndp: no neighbor cache entry found for advertisement's target\n"); - /* icmpv6 releases */ - return; - } - - sicmpv6_size -= sizeof(ndp_nbr_adv_t); - - while (sicmpv6_size > 0) { - ndp_opt_t *opt = (ndp_opt_t *)(buf + opt_offset); - - switch (opt->type) { - case NDP_OPT_TL2A: - if ((l2tgt_len = gnrc_ndp_internal_tl2a_opt_handle(pkt, ipv6, nbr_adv->type, opt, l2tgt)) < 0) { - /* invalid target link-layer address option */ - return; - } - break; -#ifdef MODULE_GNRC_SIXLOWPAN_ND - case NDP_OPT_AR: - /* address registration option is always ignored when invalid */ - gnrc_sixlowpan_nd_opt_ar_handle(iface, ipv6, nbr_adv->type, - &nbr_adv->tgt, - (sixlowpan_nd_opt_ar_t *)opt, - NULL, 0); - break; -#endif - default: - /* silently discard all other options */ - break; - } - - opt_offset += (opt->len * 8); - sicmpv6_size -= (opt->len * 8); - -#if ENABLE_DEBUG - if (sicmpv6_size < 0) { - DEBUG("ndp: Option parsing out of sync.\n"); - } -#endif - } - - netif = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_NETIF); - - if (netif != NULL) { - netif_hdr = netif->data; - } - - if (l2tgt_len != -ENOTSUP) { -#ifdef MODULE_GNRC_SIXLOWPAN_ND - /* check if entry wasn't removed by ARO, ideally there should not be any TL2A in here */ - nc_entry = gnrc_ipv6_nc_get(iface, &nbr_adv->tgt); - if (nc_entry == NULL) { - return; - } -#endif - if (gnrc_ipv6_nc_get_state(nc_entry) == GNRC_IPV6_NC_STATE_INCOMPLETE) { - if (_pkt_has_l2addr(netif_hdr) && (l2tgt_len == 0)) { - /* link-layer has addresses, but no TLLAO supplied: discard silently - * (see https://tools.ietf.org/html/rfc4861#section-7.2.5) */ - return; - } - - nc_entry->iface = iface; - nc_entry->l2_addr_len = l2tgt_len; - memcpy(nc_entry->l2_addr, l2tgt, l2tgt_len); - - if (nbr_adv->flags & NDP_NBR_ADV_FLAGS_S) { - gnrc_ndp_internal_set_state(nc_entry, GNRC_IPV6_NC_STATE_REACHABLE); - } - else { - gnrc_ndp_internal_set_state(nc_entry, GNRC_IPV6_NC_STATE_STALE); - } - - if (nbr_adv->flags & NDP_NBR_ADV_FLAGS_R) { - nc_entry->flags |= GNRC_IPV6_NC_IS_ROUTER; - } - else { - nc_entry->flags &= ~GNRC_IPV6_NC_IS_ROUTER; - /* TODO: update state of neighbor as router in FIB? */ - } -#ifdef MODULE_GNRC_NDP_NODE - gnrc_pktqueue_t *queued_pkt; - while ((queued_pkt = gnrc_pktqueue_remove_head(&nc_entry->pkts)) != NULL) { - if (gnrc_netapi_send(gnrc_ipv6_pid, queued_pkt->pkt) < 1) { - DEBUG("ndp: unable to send queued packet\n"); - gnrc_pktbuf_release(queued_pkt->pkt); - } - queued_pkt->pkt = NULL; - } -#endif - } - else { - /* first or-term: no link-layer, but nc_entry has l2addr, - * second or-term: different l2addr cached */ - bool l2tgt_changed = false; - - if ((!_pkt_has_l2addr(netif_hdr)) && (l2tgt_len == 0)) { - /* there was previously a L2 address registered */ - l2tgt_changed = (nc_entry->l2_addr_len != 0); - } - /* link-layer has addresses and TLLAO with different address */ - else if (_pkt_has_l2addr(netif_hdr) && (l2tgt_len != 0)) { - l2tgt_changed = (!(l2tgt_len == nc_entry->l2_addr_len)) && - (memcmp(nc_entry->l2_addr, l2tgt, l2tgt_len) == 0); - } - - if ((nbr_adv->flags & NDP_NBR_ADV_FLAGS_O) || !l2tgt_changed || - (l2tgt_len == 0)) { - if (l2tgt_len != 0) { - nc_entry->iface = iface; - nc_entry->l2_addr_len = l2tgt_len; - memcpy(nc_entry->l2_addr, l2tgt, l2tgt_len); - } - - if (nbr_adv->flags & NDP_NBR_ADV_FLAGS_S) { - gnrc_ndp_internal_set_state(nc_entry, GNRC_IPV6_NC_STATE_REACHABLE); - } - else if (l2tgt_changed) { - gnrc_ndp_internal_set_state(nc_entry, GNRC_IPV6_NC_STATE_STALE); - } - - if (nbr_adv->flags & NDP_NBR_ADV_FLAGS_R) { - nc_entry->flags |= GNRC_IPV6_NC_IS_ROUTER; - } - else { - nc_entry->flags &= ~GNRC_IPV6_NC_IS_ROUTER; - /* TODO: update state of neighbor as router in FIB? */ - } - } - else if (l2tgt_changed && - gnrc_ipv6_nc_get_state(nc_entry) == GNRC_IPV6_NC_STATE_REACHABLE) { - gnrc_ndp_internal_set_state(nc_entry, GNRC_IPV6_NC_STATE_STALE); - } - } - } - - return; -} - -#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER)) -void gnrc_ndp_rtr_sol_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt, - ipv6_hdr_t *ipv6, ndp_rtr_sol_t *rtr_sol, - size_t icmpv6_size) -{ - gnrc_ipv6_netif_t *if_entry = gnrc_ipv6_netif_get(iface); - - if (if_entry->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER) { - gnrc_ipv6_nc_t *nc_entry; - int sicmpv6_size = (int)icmpv6_size, l2src_len = 0; - uint8_t l2src[GNRC_IPV6_NC_L2_ADDR_MAX]; - uint16_t opt_offset = 0; - uint8_t *buf = (uint8_t *)(rtr_sol + 1); - /* check validity */ - if ((ipv6->hl != 255) || (rtr_sol->code != 0) || - (icmpv6_size < sizeof(ndp_rtr_sol_t))) { - DEBUG("ndp: router solicitation was invalid\n"); - return; - } - sicmpv6_size -= sizeof(ndp_rtr_sol_t); - while (sicmpv6_size > 0) { - ndp_opt_t *opt = (ndp_opt_t *)(buf + opt_offset); - - switch (opt->type) { - case NDP_OPT_SL2A: - l2src_len = gnrc_ndp_internal_sl2a_opt_handle(pkt, ipv6, - rtr_sol->type, - opt, l2src); - if (l2src_len < 0) { - /* -ENOTSUP can not happen */ - /* invalid source link-layer address option */ - return; - } - _stale_nc(iface, &ipv6->src, l2src, l2src_len); - break; - - default: - /* silently discard all other options */ - break; - } - - opt_offset += (opt->len * 8); - sicmpv6_size -= (opt->len * 8); - -#if ENABLE_DEBUG - if (sicmpv6_size < 0) { - DEBUG("ndp: Option parsing out of sync.\n"); - } -#endif - } - - /* send delayed */ - if (if_entry->flags & GNRC_IPV6_NETIF_FLAGS_RTR_ADV) { - uint32_t delay; - uint32_t ms = GNRC_NDP_MAX_RTR_ADV_DELAY; -#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER - if (if_entry->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) { - ms = GNRC_SIXLOWPAN_ND_MAX_RTR_ADV_DELAY; - } -#endif - delay = random_uint32_range(0, ms); - xtimer_remove(&if_entry->rtr_adv_timer); -#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER - /* in case of a 6LBR we have to check if the interface is actually - * the 6lo interface */ - if (if_entry->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) { - gnrc_ipv6_nc_t *nc_entry = gnrc_ipv6_nc_get(iface, &ipv6->src); - if (nc_entry != NULL) { - if_entry->rtr_adv_msg.type = GNRC_NDP_MSG_RTR_ADV_SIXLOWPAN_DELAY; - if_entry->rtr_adv_msg.content.ptr = nc_entry; - xtimer_set_msg(&if_entry->rtr_adv_timer, delay, &if_entry->rtr_adv_msg, - gnrc_ipv6_pid); - } - } -#elif defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER) - if (ipv6_addr_is_unspecified(&ipv6->src)) { - /* either multicast, if source unspecified */ - if_entry->rtr_adv_msg.type = GNRC_NDP_MSG_RTR_ADV_RETRANS; - if_entry->rtr_adv_msg.content.ptr = if_entry; - xtimer_set_msg(&if_entry->rtr_adv_timer, delay, &if_entry->rtr_adv_msg, - gnrc_ipv6_pid); - } - else { - /* or unicast, if source is known */ - /* XXX: can't just use GNRC_NETAPI_MSG_TYPE_SND, since the next retransmission - * must also be set. */ - nc_entry = gnrc_ipv6_nc_get(iface, &ipv6->src); - if (nc_entry) { - xtimer_set_msg(&nc_entry->rtr_adv_timer, delay, &nc_entry->rtr_adv_msg, - gnrc_ipv6_pid); - } - } -#endif - } - nc_entry = gnrc_ipv6_nc_get(iface, &ipv6->src); - if (nc_entry != NULL) { - /* unset isRouter flag - * (https://tools.ietf.org/html/rfc4861#section-6.2.6) */ - nc_entry->flags &= ~GNRC_IPV6_NC_IS_ROUTER; - } - } - /* otherwise ignore silently */ -} -#endif - -static inline void _set_reach_time(gnrc_ipv6_netif_t *if_entry, uint32_t mean) -{ - uint32_t reach_time = random_uint32_range(GNRC_NDP_MIN_RAND, GNRC_NDP_MAX_RAND); - - if_entry->reach_time_base = mean; - /* to avoid floating point number computation and have higher value entropy, the - * boundaries for the random value are multiplied by 10 and we need to account for that */ - reach_time = (reach_time * if_entry->reach_time_base) / 10; - if_entry->reach_time = reach_time; -} - -void gnrc_ndp_rtr_adv_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt, ipv6_hdr_t *ipv6, - ndp_rtr_adv_t *rtr_adv, size_t icmpv6_size) -{ - uint8_t *buf = (uint8_t *)(rtr_adv + 1); - gnrc_ipv6_nc_t *nc_entry = NULL; - gnrc_ipv6_netif_t *if_entry = gnrc_ipv6_netif_get(iface); - uint8_t l2src[GNRC_IPV6_NC_L2_ADDR_MAX]; -#ifdef MODULE_GNRC_SIXLOWPAN_ND - uint32_t next_rtr_sol = 0; -#endif - int sicmpv6_size = (int)icmpv6_size, l2src_len = 0; - uint16_t opt_offset = 0; - - if (!ipv6_addr_is_link_local(&ipv6->src) || - ipv6_addr_is_multicast(&ipv6->src) || - (ipv6->hl != 255) || (rtr_adv->code != 0) || - (icmpv6_size < sizeof(ndp_rtr_adv_t))) { - DEBUG("ndp: router advertisement was invalid\n"); - /* icmpv6 releases */ - return; - } - /* get source from default router list */ - nc_entry = gnrc_ipv6_nc_get(iface, &ipv6->src); - if (nc_entry == NULL) { /* not in default router list */ - /* create default router list entry */ - nc_entry = gnrc_ipv6_nc_add(iface, &ipv6->src, NULL, 0, - GNRC_IPV6_NC_STATE_STALE | GNRC_IPV6_NC_IS_ROUTER); - if (nc_entry == NULL) { - DEBUG("ndp: error on default router list entry creation\n"); - return; - } - } - else if ((nc_entry->flags & GNRC_IPV6_NC_IS_ROUTER) && (byteorder_ntohs(rtr_adv->ltime) == 0)) { - nc_entry->flags &= ~GNRC_IPV6_NC_IS_ROUTER; - } - else { - nc_entry->flags |= GNRC_IPV6_NC_IS_ROUTER; - } - /* set router life timer */ - if (rtr_adv->ltime.u16 != 0) { - uint16_t ltime = byteorder_ntohs(rtr_adv->ltime); -#ifdef MODULE_GNRC_SIXLOWPAN_ND - next_rtr_sol = ltime; -#endif - xtimer_set_msg(&nc_entry->rtr_timeout, (ltime * US_PER_SEC), - &nc_entry->rtr_timeout_msg, thread_getpid()); - } - /* set current hop limit from message if available */ - if (rtr_adv->cur_hl != 0) { - if_entry->cur_hl = rtr_adv->cur_hl; - } - /* set flags from message */ - if_entry->flags &= ~GNRC_IPV6_NETIF_FLAGS_RTR_ADV_MASK; - if_entry->flags |= (rtr_adv->flags << GNRC_IPV6_NETIF_FLAGS_RTR_ADV_POS) & - GNRC_IPV6_NETIF_FLAGS_RTR_ADV_MASK; - /* set reachable time from message if it is not the same as the random base - * value */ - if ((rtr_adv->reach_time.u32 != 0) && - (if_entry->reach_time_base != byteorder_ntohl(rtr_adv->reach_time))) { - _set_reach_time(if_entry, byteorder_ntohl(rtr_adv->reach_time)); - } - /* set retransmission timer from message */ - if (rtr_adv->retrans_timer.u32 != 0) { - if_entry->retrans_timer = byteorder_ntohl(rtr_adv->retrans_timer); - } - mutex_unlock(&if_entry->mutex); - sicmpv6_size -= sizeof(ndp_rtr_adv_t); - /* parse options */ - while (sicmpv6_size > 0) { - ndp_opt_t *opt = (ndp_opt_t *)(buf + opt_offset); - switch (opt->type) { - case NDP_OPT_SL2A: - if ((l2src_len = gnrc_ndp_internal_sl2a_opt_handle(pkt, ipv6, rtr_adv->type, opt, - l2src)) < 0) { - /* -ENOTSUP can not happen */ - /* invalid source link-layer address option */ - return; - } - break; - case NDP_OPT_MTU: - if (!gnrc_ndp_internal_mtu_opt_handle(iface, rtr_adv->type, (ndp_opt_mtu_t *)opt)) { - /* invalid MTU option */ - return; - } - break; - case NDP_OPT_PI: - if (!gnrc_ndp_internal_pi_opt_handle(iface, rtr_adv->type, (ndp_opt_pi_t *)opt)) { - /* invalid prefix information option */ - return; - } -#ifdef MODULE_GNRC_SIXLOWPAN_ND - uint32_t valid_ltime = byteorder_ntohl(((ndp_opt_pi_t *)opt)->valid_ltime); - if ((valid_ltime != 0) && (valid_ltime < next_rtr_sol)) { - next_rtr_sol = valid_ltime; - } -#endif - break; -#ifdef MODULE_GNRC_SIXLOWPAN_ND - case NDP_OPT_6CTX: - if (!gnrc_sixlowpan_nd_opt_6ctx_handle(rtr_adv->type, - (sixlowpan_nd_opt_6ctx_t *)opt)) { - /* invalid 6LoWPAN context option */ - return; - } - uint16_t ltime = byteorder_ntohs(((sixlowpan_nd_opt_6ctx_t *)opt)->ltime); - if ((ltime != 0) && (ltime < (next_rtr_sol / 60))) { - next_rtr_sol = ltime * 60; - } - - break; -#endif -#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER - case NDP_OPT_ABR: - gnrc_sixlowpan_nd_opt_abr_handle(iface, rtr_adv, icmpv6_size, - (sixlowpan_nd_opt_abr_t *)opt); - break; -#endif - } - - opt_offset += (opt->len * 8); - sicmpv6_size -= (opt->len * 8); - -#if ENABLE_DEBUG - if (sicmpv6_size < 0) { - DEBUG("ndp: Option parsing out of sync.\n"); - } -#endif - } -#if ENABLE_DEBUG && defined(MODULE_GNRC_SIXLOWPAN_ND) - if ((if_entry->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) && (l2src_len <= 0)) { - DEBUG("ndp: Router advertisement did not contain any source address information\n"); - } -#endif - _stale_nc(iface, &ipv6->src, l2src, l2src_len); - /* stop multicast router solicitation retransmission timer */ - xtimer_remove(&if_entry->rtr_sol_timer); -#ifdef MODULE_GNRC_SIXLOWPAN_ND - if (if_entry->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) { - /* 3/4 of the time should be "well before" enough the respective timeout - * not to run out; see https://tools.ietf.org/html/rfc6775#section-5.4.3 */ - next_rtr_sol *= 3; - next_rtr_sol = (next_rtr_sol > 4) ? (next_rtr_sol >> 2) : 1; - /* according to https://tools.ietf.org/html/rfc6775#section-5.3: - * "In all cases, the RS retransmissions are terminated when an RA is - * received." - * Hence, reset router solicitation counter and reset timer. */ - if_entry->rtr_sol_count = 0; - gnrc_sixlowpan_nd_rtr_sol_reschedule(nc_entry, next_rtr_sol); - gnrc_ndp_internal_send_nbr_sol(nc_entry->iface, NULL, &nc_entry->ipv6_addr, - &nc_entry->ipv6_addr); - if (if_entry->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER) { - gnrc_ipv6_netif_set_rtr_adv(if_entry, true); - } - } -#endif -} - -void gnrc_ndp_retrans_nbr_sol(gnrc_ipv6_nc_t *nc_entry) -{ - if ((gnrc_ipv6_nc_get_state(nc_entry) == GNRC_IPV6_NC_STATE_INCOMPLETE) || - (gnrc_ipv6_nc_get_state(nc_entry) == GNRC_IPV6_NC_STATE_PROBE)) { - if (nc_entry->probes_remaining > 1) { - ipv6_addr_t dst; - - DEBUG("ndp: Retransmit neighbor solicitation for %s\n", - ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str))); - - /* retransmit neighbor solicatation */ - if (gnrc_ipv6_nc_get_state(nc_entry) == GNRC_IPV6_NC_STATE_INCOMPLETE) { - ipv6_addr_set_solicited_nodes(&dst, &nc_entry->ipv6_addr); - } - else { - dst.u64[0] = nc_entry->ipv6_addr.u64[0]; - dst.u64[1] = nc_entry->ipv6_addr.u64[1]; - } - - nc_entry->probes_remaining--; - - if (nc_entry->iface == KERNEL_PID_UNDEF) { - kernel_pid_t ifs[GNRC_NETIF_NUMOF]; - size_t ifnum = gnrc_netif_get(ifs); - - for (size_t i = 0; i < ifnum; i++) { - gnrc_ndp_internal_send_nbr_sol(ifs[i], NULL, &nc_entry->ipv6_addr, &dst); - } - - gnrc_ndp_internal_reset_nbr_sol_timer(nc_entry, GNRC_NDP_RETRANS_TIMER, - GNRC_NDP_MSG_NBR_SOL_RETRANS, gnrc_ipv6_pid); - } - else { - gnrc_ipv6_netif_t *ipv6_iface = gnrc_ipv6_netif_get(nc_entry->iface); - - gnrc_ndp_internal_send_nbr_sol(nc_entry->iface, NULL, &nc_entry->ipv6_addr, &dst); - - mutex_lock(&ipv6_iface->mutex); - gnrc_ndp_internal_reset_nbr_sol_timer(nc_entry, ipv6_iface->retrans_timer, - GNRC_NDP_MSG_NBR_SOL_RETRANS, gnrc_ipv6_pid); - mutex_unlock(&ipv6_iface->mutex); - } - } - /* cppcheck-suppress knownConditionTrueFalse - * cppcheck bug: probes_remaining is initialized to a value > 1 */ - else if (nc_entry->probes_remaining <= 1) { - - /* For a 6LoWPAN router entries may be set to UNREACHABLE instead - * of removing them, since RFC6775, section 6 - * (https://tools.ietf.org/html/rfc6775#section-6) says: "if NUD on - * the router determines that the host is UNREACHABLE (based on the - * logic in [RFC4861]), the NCE SHOULD NOT be deleted but rather - * retained until the Registration Lifetime expires." However, this - * "SHOULD NOT" is not implemented to circumvent NCEs going into - * UNREACHABLE forever and in order to save some memory in the - * neighbor cache. */ - - DEBUG("ndp: Remove nc entry %s for interface %" PRIkernel_pid "\n", - ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str)), - nc_entry->iface); - - gnrc_ipv6_nc_remove(nc_entry->iface, &nc_entry->ipv6_addr); - } - } -} - -void gnrc_ndp_state_timeout(gnrc_ipv6_nc_t *nc_entry) -{ - switch (gnrc_ipv6_nc_get_state(nc_entry)) { - case GNRC_IPV6_NC_STATE_REACHABLE: - gnrc_ndp_internal_set_state(nc_entry, GNRC_IPV6_NC_STATE_STALE); - break; - - case GNRC_IPV6_NC_STATE_DELAY: - gnrc_ndp_internal_set_state(nc_entry, GNRC_IPV6_NC_STATE_PROBE); - break; - - default: - break; - } -} - -void gnrc_ndp_netif_add(gnrc_ipv6_netif_t *iface) -{ - /* set default values */ - mutex_lock(&iface->mutex); - _set_reach_time(iface, GNRC_NDP_REACH_TIME); - iface->retrans_timer = GNRC_NDP_RETRANS_TIMER; - mutex_unlock(&iface->mutex); -} - -void gnrc_ndp_netif_remove(gnrc_ipv6_netif_t *iface) -{ - /* TODO */ - (void) iface; -} - -gnrc_pktsnip_t *gnrc_ndp_nbr_sol_build(ipv6_addr_t *tgt, gnrc_pktsnip_t *options) -{ - gnrc_pktsnip_t *pkt; - - DEBUG("ndp: building neighbor solicitation message\n"); - - if (ipv6_addr_is_multicast(tgt)) { - DEBUG("ndp: tgt must not be multicast\n"); - return NULL; - } - - pkt = gnrc_icmpv6_build(options, ICMPV6_NBR_SOL, 0, sizeof(ndp_nbr_sol_t)); - - if (pkt != NULL) { - ndp_nbr_sol_t *nbr_sol = pkt->data; - nbr_sol->resv.u32 = 0; - nbr_sol->tgt.u64[0].u64 = tgt->u64[0].u64; - nbr_sol->tgt.u64[1].u64 = tgt->u64[1].u64; - } - - return pkt; -} - -gnrc_pktsnip_t *gnrc_ndp_nbr_adv_build(uint8_t flags, ipv6_addr_t *tgt, - gnrc_pktsnip_t *options) -{ - gnrc_pktsnip_t *pkt; - - DEBUG("ndp: building neighbor advertisement message\n"); - - if (ipv6_addr_is_multicast(tgt)) { - DEBUG("ndp: tgt must not be multicast\n"); - return NULL; - } - - pkt = gnrc_icmpv6_build(options, ICMPV6_NBR_ADV, 0, sizeof(ndp_nbr_adv_t)); - - if (pkt != NULL) { - ndp_nbr_adv_t *nbr_adv = pkt->data; - nbr_adv->flags = (flags & NDP_NBR_ADV_FLAGS_MASK); - nbr_adv->resv[0] = nbr_adv->resv[1] = nbr_adv->resv[2] = 0; - nbr_adv->tgt.u64[0].u64 = tgt->u64[0].u64; - nbr_adv->tgt.u64[1].u64 = tgt->u64[1].u64; - } - - return pkt; -} - -gnrc_pktsnip_t *gnrc_ndp_rtr_sol_build(gnrc_pktsnip_t *options) -{ - gnrc_pktsnip_t *pkt; - DEBUG("ndp: building router solicitation message\n"); - pkt = gnrc_icmpv6_build(options, ICMPV6_RTR_SOL, 0, sizeof(ndp_rtr_sol_t)); - if (pkt != NULL) { - ndp_rtr_sol_t *rtr_sol = pkt->data; - rtr_sol->resv.u32 = 0; - } - return pkt; -} - -static inline size_t _ceil8(uint8_t length) -{ - /* NDP options use units of 8 byte for there length field, so round up */ - return (length + 7U) & 0xf8U; -} - -gnrc_pktsnip_t *gnrc_ndp_opt_build(uint8_t type, size_t size, gnrc_pktsnip_t *next) -{ - ndp_opt_t *opt; - gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(next, NULL, _ceil8(size), GNRC_NETTYPE_UNDEF); - - if (pkt == NULL) { - DEBUG("ndp: no space left in packet buffer\n"); - return NULL; - } - - opt = pkt->data; - - opt->type = type; - opt->len = (uint8_t)(pkt->size / 8); - - return pkt; -} - -static inline gnrc_pktsnip_t *_opt_l2a_build(uint8_t type, const uint8_t *l2addr, - uint8_t l2addr_len, gnrc_pktsnip_t *next) -{ - gnrc_pktsnip_t *pkt = gnrc_ndp_opt_build(type, sizeof(ndp_opt_t) + l2addr_len, next); - - if (pkt != NULL) { - ndp_opt_t *l2a_opt = pkt->data; - - memset(l2a_opt + 1, 0, pkt->size - sizeof(ndp_opt_t)); - memcpy(l2a_opt + 1, l2addr, l2addr_len); - } - - return pkt; -} - -gnrc_pktsnip_t *gnrc_ndp_opt_sl2a_build(const uint8_t *l2addr, uint8_t l2addr_len, - gnrc_pktsnip_t *next) -{ - DEBUG("ndp: building source link-layer address option (l2addr: %s)\n", - gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), l2addr, l2addr_len)); - - return _opt_l2a_build(NDP_OPT_SL2A, l2addr, l2addr_len, next); -} - -gnrc_pktsnip_t *gnrc_ndp_opt_tl2a_build(const uint8_t *l2addr, uint8_t l2addr_len, - gnrc_pktsnip_t *next) -{ - DEBUG("ndp: building target link-layer address option (l2addr: %s)\n", - gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), l2addr, l2addr_len)); - - return _opt_l2a_build(NDP_OPT_TL2A, l2addr, l2addr_len, next); -} - -#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER)) -gnrc_pktsnip_t *gnrc_ndp_rtr_adv_build(uint8_t cur_hl, uint8_t flags, - uint16_t ltime, uint32_t reach_time, - uint32_t retrans_timer, gnrc_pktsnip_t *options) -{ - gnrc_pktsnip_t *pkt; - DEBUG("ndp rtr: building router advertisement message\n"); - pkt = gnrc_icmpv6_build(options, ICMPV6_RTR_ADV, 0, sizeof(ndp_rtr_adv_t)); - if (pkt != NULL) { - ndp_rtr_adv_t *rtr_adv = pkt->data; - rtr_adv->cur_hl = cur_hl; - rtr_adv->flags = (flags & NDP_RTR_ADV_FLAGS_MASK); - rtr_adv->ltime = byteorder_htons(ltime); - rtr_adv->reach_time = byteorder_htonl(reach_time); - rtr_adv->retrans_timer = byteorder_htonl(retrans_timer); - } - return pkt; -} - -gnrc_pktsnip_t *gnrc_ndp_opt_pi_build(uint8_t prefix_len, uint8_t flags, - uint32_t valid_ltime, uint32_t pref_ltime, - ipv6_addr_t *prefix, gnrc_pktsnip_t *next) -{ - gnrc_pktsnip_t *pkt = gnrc_ndp_opt_build(NDP_OPT_PI, sizeof(ndp_opt_pi_t), - next); - if (pkt != NULL) { - ndp_opt_pi_t *pi_opt = pkt->data; - pi_opt->prefix_len = prefix_len; - pi_opt->flags = (flags & NDP_OPT_PI_FLAGS_MASK); - pi_opt->valid_ltime = byteorder_htonl(valid_ltime); - pi_opt->pref_ltime = byteorder_htonl(pref_ltime); - pi_opt->resv.u32 = 0; - /* Bits beyond prefix_len MUST be 0 */ - ipv6_addr_set_unspecified(&pi_opt->prefix); - ipv6_addr_init_prefix(&pi_opt->prefix, prefix, prefix_len); - } - return pkt; -} - -gnrc_pktsnip_t *gnrc_ndp_opt_mtu_build(uint32_t mtu, gnrc_pktsnip_t *next) -{ - gnrc_pktsnip_t *pkt = gnrc_ndp_opt_build(NDP_OPT_MTU, sizeof(ndp_opt_mtu_t), - next); - if (pkt != NULL) { - ndp_opt_mtu_t *mtu_opt = pkt->data; - mtu_opt->resv.u16 = 0; - mtu_opt->mtu = byteorder_htonl(mtu); - } - return pkt; -} -#endif - -/** - * @} - */ diff --git a/sys/net/gnrc/network_layer/ndp/host/Makefile b/sys/net/gnrc/network_layer/ndp/host/Makefile deleted file mode 100644 index c3b51fb8dab8ddd6a05215dc421561ee4dd3d572..0000000000000000000000000000000000000000 --- a/sys/net/gnrc/network_layer/ndp/host/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -MODULE = gnrc_ndp_host - -include $(RIOTBASE)/Makefile.base diff --git a/sys/net/gnrc/network_layer/ndp/host/gnrc_ndp_host.c b/sys/net/gnrc/network_layer/ndp/host/gnrc_ndp_host.c deleted file mode 100644 index 433e0f58a91844cafb120e37a7f6456998e2526d..0000000000000000000000000000000000000000 --- a/sys/net/gnrc/network_layer/ndp/host/gnrc_ndp_host.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @{ - * - * @file - */ - -#include <inttypes.h> -#include "random.h" -#include "net/gnrc/ipv6.h" -#include "net/gnrc/ndp.h" -#include "net/gnrc/ndp/internal.h" -#include "xtimer.h" - -#include "net/gnrc/ndp/host.h" - -#define ENABLE_DEBUG (0) -#include "debug.h" - -static inline void _reschedule_rtr_sol(gnrc_ipv6_netif_t *iface, uint32_t delay) -{ - xtimer_remove(&iface->rtr_sol_timer); - iface->rtr_sol_msg.type = GNRC_NDP_MSG_RTR_SOL_RETRANS; - iface->rtr_sol_msg.content.ptr = iface; - xtimer_set_msg(&iface->rtr_sol_timer, delay, &iface->rtr_sol_msg, gnrc_ipv6_pid); -} - -void gnrc_ndp_host_init(gnrc_ipv6_netif_t *iface) -{ - uint32_t interval = random_uint32_range(0, GNRC_NDP_MAX_RTR_SOL_DELAY * US_PER_SEC); - mutex_lock(&iface->mutex); - iface->rtr_sol_count = GNRC_NDP_MAX_RTR_SOL_NUMOF; - DEBUG("ndp host: delayed initial router solicitation by %" PRIu32 " usec.\n", interval); - _reschedule_rtr_sol(iface, interval); - mutex_unlock(&iface->mutex); -} - -void gnrc_ndp_host_retrans_rtr_sol(gnrc_ipv6_netif_t *iface) -{ - mutex_lock(&iface->mutex); - if (iface->rtr_sol_count > 1) { /* regard off-by-one error */ - DEBUG("ndp hst: retransmit rtr sol in %d sec\n", GNRC_NDP_MAX_RTR_SOL_INT); - iface->rtr_sol_count--; - _reschedule_rtr_sol(iface, GNRC_NDP_MAX_RTR_SOL_INT * US_PER_SEC); - } - mutex_unlock(&iface->mutex); - gnrc_ndp_internal_send_rtr_sol(iface->pid, NULL); -} - -/** @} */ diff --git a/sys/net/gnrc/network_layer/ndp/internal/Makefile b/sys/net/gnrc/network_layer/ndp/internal/Makefile deleted file mode 100644 index 54bdd221c2a49bc03c1b9c5a38ebca7a4160744f..0000000000000000000000000000000000000000 --- a/sys/net/gnrc/network_layer/ndp/internal/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -MODULE = gnrc_ndp_internal - -include $(RIOTBASE)/Makefile.base diff --git a/sys/net/gnrc/network_layer/ndp/internal/gnrc_ndp_internal.c b/sys/net/gnrc/network_layer/ndp/internal/gnrc_ndp_internal.c deleted file mode 100644 index f46c39ca38866d074331d24ccc7c4f4fa7b3cff3..0000000000000000000000000000000000000000 --- a/sys/net/gnrc/network_layer/ndp/internal/gnrc_ndp_internal.c +++ /dev/null @@ -1,860 +0,0 @@ -/* - * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @{ - * - * @file - */ - -#include <stdlib.h> - -#include "net/eui64.h" -#include "net/gnrc/ipv6.h" -#include "net/gnrc/ndp.h" -#include "net/gnrc/sixlowpan/ctx.h" -#include "net/gnrc/sixlowpan/nd.h" -#include "random.h" -#include "xtimer.h" - -#include "net/gnrc/ndp/internal.h" - -#define ENABLE_DEBUG (0) -#include "debug.h" - -#if ENABLE_DEBUG -static char addr_str[IPV6_ADDR_MAX_STR_LEN]; -#endif - -static gnrc_ipv6_nc_t *_last_router = NULL; /* last router chosen as default - * router. Only used if reachability - * is suspect (i. e. incomplete or - * not at all) */ -static gnrc_pktsnip_t *_build_headers(kernel_pid_t iface, gnrc_pktsnip_t *payload, - ipv6_addr_t *dst, ipv6_addr_t *src); -static size_t _get_l2src(kernel_pid_t iface, uint8_t *l2src, size_t l2src_maxlen); - -/** - * @brief Sends @ref GNRC_NETAPI_MSG_TYPE_SND delayed. - * - * @param[in] t Timer for the delay. - * @param[in] msg Msg for the timer. - * @param[in] interval Delay interval. - * @param[in] pkt Packet to send delayed. - */ -static inline void _send_delayed(xtimer_t *t, msg_t *msg, uint32_t interval, gnrc_pktsnip_t *pkt) -{ - xtimer_remove(t); - msg->type = GNRC_NETAPI_MSG_TYPE_SND; - msg->content.ptr = pkt; - xtimer_set_msg(t, interval, msg, gnrc_ipv6_pid); -} - - -ipv6_addr_t *gnrc_ndp_internal_default_router(void) -{ - gnrc_ipv6_nc_t *router = gnrc_ipv6_nc_get_next_router(NULL); - - /* first look if there is any reachable router */ - while (router != NULL) { - if ((gnrc_ipv6_nc_get_state(router) != GNRC_IPV6_NC_STATE_INCOMPLETE) && - (gnrc_ipv6_nc_get_state(router) != GNRC_IPV6_NC_STATE_UNREACHABLE)) { - _last_router = NULL; - - return &router->ipv6_addr; - } - - router = gnrc_ipv6_nc_get_next_router(router); - } - - /* else take the first one, but keep round-robin in further selections */ - router = gnrc_ipv6_nc_get_next_router(_last_router); - - if (router == NULL) { /* end of router list or there is none => wrap around */ - router = gnrc_ipv6_nc_get_next_router(router); - - if (router == NULL) { /* still nothing found => no router in list */ - return NULL; - } - } - - _last_router = router; - - return &router->ipv6_addr; -} - -void gnrc_ndp_internal_set_state(gnrc_ipv6_nc_t *nc_entry, uint8_t state) -{ - gnrc_ipv6_netif_t *ipv6_iface; - uint32_t t = GNRC_NDP_FIRST_PROBE_DELAY * US_PER_SEC; - - nc_entry->flags &= ~GNRC_IPV6_NC_STATE_MASK; - nc_entry->flags |= state; - - DEBUG("ndp internal: set %s state to ", - ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str))); - - switch (state) { - case GNRC_IPV6_NC_STATE_REACHABLE: - ipv6_iface = gnrc_ipv6_netif_get(nc_entry->iface); - DEBUG("REACHABLE (reachable time = %" PRIu32 " us)\n", ipv6_iface->reach_time); - t = ipv6_iface->reach_time; - - /* Falls through. */ - /* this is intentional to set the desired timeout t */ - case GNRC_IPV6_NC_STATE_DELAY: -#if ENABLE_DEBUG - if (state == GNRC_IPV6_NC_STATE_DELAY) { - DEBUG("DELAY (probe with unicast NS in %u seconds)\n", - GNRC_NDP_FIRST_PROBE_DELAY); - } -#endif - gnrc_ndp_internal_reset_nbr_sol_timer(nc_entry, t, GNRC_NDP_MSG_NC_STATE_TIMEOUT, - gnrc_ipv6_pid); - break; - - case GNRC_IPV6_NC_STATE_PROBE: - ipv6_iface = gnrc_ipv6_netif_get(nc_entry->iface); - - nc_entry->probes_remaining = GNRC_NDP_MAX_UC_NBR_SOL_NUMOF; - DEBUG("PROBE (probe with %" PRIu8 " unicast NS every %" PRIu32 " us)\n", - nc_entry->probes_remaining, ipv6_iface->retrans_timer); - - gnrc_ndp_internal_send_nbr_sol(nc_entry->iface, NULL, &nc_entry->ipv6_addr, - &nc_entry->ipv6_addr); - - mutex_lock(&ipv6_iface->mutex); - gnrc_ndp_internal_reset_nbr_sol_timer(nc_entry, ipv6_iface->retrans_timer, - GNRC_NDP_MSG_NBR_SOL_RETRANS, gnrc_ipv6_pid); - mutex_unlock(&ipv6_iface->mutex); - break; - -#ifdef ENABLE_DEBUG - case GNRC_IPV6_NC_STATE_STALE: - DEBUG("STALE (go into DELAY on next packet)\n"); - break; -#endif - - default: - DEBUG("errorneous or unknown\n"); - break; - } -} - -void gnrc_ndp_internal_send_nbr_adv(kernel_pid_t iface, ipv6_addr_t *tgt, ipv6_addr_t *dst, - bool supply_tl2a, gnrc_pktsnip_t *ext_opts) -{ - gnrc_pktsnip_t *hdr, *pkt = ext_opts; - uint8_t adv_flags = 0; - - DEBUG("ndp internal: send neighbor advertisement (iface: %" PRIkernel_pid ", tgt: %s, ", - iface, ipv6_addr_to_str(addr_str, tgt, sizeof(addr_str))); - DEBUG("dst: %s, supply_tl2a: %d)\n", - ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)), supply_tl2a); - - if ((gnrc_ipv6_netif_get(iface)->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER) && - (gnrc_ipv6_netif_get(iface)->flags & GNRC_IPV6_NETIF_FLAGS_RTR_ADV)) { - adv_flags |= NDP_NBR_ADV_FLAGS_R; - } - - if (ipv6_addr_is_unspecified(dst)) { - ipv6_addr_set_all_nodes_multicast(dst, IPV6_ADDR_MCAST_SCP_LINK_LOCAL); - } - else { - adv_flags |= NDP_NBR_ADV_FLAGS_S; - } - - if (supply_tl2a) { - uint8_t l2src[8]; - size_t l2src_len; - /* we previously checked if we are the target, so we can take our L2src */ - l2src_len = _get_l2src(iface, l2src, sizeof(l2src)); - - if (l2src_len > 0) { - /* add target address link-layer address option */ - pkt = gnrc_ndp_opt_tl2a_build(l2src, l2src_len, pkt); - - if (pkt == NULL) { - DEBUG("ndp internal: error allocating Target Link-layer address option.\n"); - gnrc_pktbuf_release(ext_opts); - return; - } - } - } - - /* TODO: also check if the node provides proxy servies for tgt */ - if ((pkt != NULL) && !gnrc_ipv6_netif_addr_is_non_unicast(tgt)) { - /* TL2A is not supplied and tgt is not anycast */ - adv_flags |= NDP_NBR_ADV_FLAGS_O; - } - - hdr = gnrc_ndp_nbr_adv_build(adv_flags, tgt, pkt); - - if (hdr == NULL) { - DEBUG("ndp internal: error allocating Neighbor advertisement.\n"); - gnrc_pktbuf_release(pkt); - return; - } - pkt = hdr; - hdr = _build_headers(iface, pkt, dst, NULL); - if (hdr == NULL) { - DEBUG("ndp internal: error adding lower-layer headers.\n"); - gnrc_pktbuf_release(pkt); - return; - } - if (gnrc_ipv6_netif_addr_is_non_unicast(tgt)) { - /* avoid collision for anycast addresses - * (see https://tools.ietf.org/html/rfc4861#section-7.2.7) */ - uint32_t delay = random_uint32_range(0, GNRC_NDP_MAX_AC_TGT_DELAY * US_PER_SEC); - gnrc_ipv6_nc_t *nc_entry = gnrc_ipv6_nc_get(iface, dst); - DEBUG("ndp internal: delay neighbor advertisement for %" PRIu32 " sec.", - (delay / US_PER_SEC)); - - /* nc_entry must be set so no need to check it */ - assert(nc_entry); - - _send_delayed(&nc_entry->nbr_adv_timer, &nc_entry->nbr_adv_msg, delay, hdr); - } - else if (gnrc_netapi_send(gnrc_ipv6_pid, hdr) < 1) { - DEBUG("ndp internal: unable to send neighbor advertisement\n"); - gnrc_pktbuf_release(hdr); - } -} - -void gnrc_ndp_internal_send_nbr_sol(kernel_pid_t iface, ipv6_addr_t *src, ipv6_addr_t *tgt, - ipv6_addr_t *dst) -{ -#ifdef MODULE_GNRC_SIXLOWPAN_ND - gnrc_ipv6_netif_t *ipv6_iface = gnrc_ipv6_netif_get(iface); - assert(ipv6_iface != NULL); -#endif - gnrc_pktsnip_t *hdr, *pkt = NULL; - /* cppcheck-suppress variableScope - * (reason: they are needed in the MODULE_GNRC_SIXLOWPAN_ND branch) */ - uint8_t l2src[8]; - /* cppcheck-suppress variableScope - * (reason: they are needed in the MODULE_GNRC_SIXLOWPAN_ND branch) */ - size_t l2src_len = 0; - - DEBUG("ndp internal: send neighbor solicitation (iface: %" PRIkernel_pid ", src: %s, ", - iface, ipv6_addr_to_str(addr_str, src ? src : &ipv6_addr_unspecified, sizeof(addr_str))); - DEBUG(" tgt: %s, ", ipv6_addr_to_str(addr_str, tgt, sizeof(addr_str))); - DEBUG("dst: %s)\n", ipv6_addr_to_str(addr_str, dst, sizeof(addr_str))); - - /* check if there is a fitting source address to target */ - if (src == NULL) { - src = gnrc_ipv6_netif_find_best_src_addr(iface, tgt, false); - } - if (src != NULL) { - l2src_len = _get_l2src(iface, l2src, sizeof(l2src)); - - if (l2src_len > 0) { - /* add source address link-layer address option */ - pkt = gnrc_ndp_opt_sl2a_build(l2src, l2src_len, NULL); - - if (pkt == NULL) { - DEBUG("ndp internal: error allocating Source Link-layer address option.\n"); - gnrc_pktbuf_release(pkt); - return; - } - } - } - -#ifdef MODULE_GNRC_SIXLOWPAN_ND - if (ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) { - if (l2src_len != sizeof(eui64_t)) { - l2src_len = (uint16_t)gnrc_netapi_get(iface, NETOPT_ADDRESS_LONG, 0, l2src, - sizeof(l2src)); - if (l2src_len != sizeof(eui64_t)) { - DEBUG("ndp internal: can't get EUI-64 of the interface\n"); - gnrc_pktbuf_release(pkt); - return; - } - } - hdr = gnrc_sixlowpan_nd_opt_ar_build(0, GNRC_SIXLOWPAN_ND_AR_LTIME, (eui64_t *)l2src, pkt); - if (hdr == NULL) { - DEBUG("ndp internal: error allocatin Address Registration option.\n"); - gnrc_pktbuf_release(pkt); - return; - } - pkt = hdr; - } -#endif - - hdr = gnrc_ndp_nbr_sol_build(tgt, pkt); - - if (hdr == NULL) { - DEBUG("ndp internal: error allocating Neighbor solicitation.\n"); - gnrc_pktbuf_release(pkt); - return; - } - pkt = hdr; - hdr = _build_headers(iface, pkt, dst, src); - if (hdr == NULL) { - DEBUG("ndp internal: error adding lower-layer headers.\n"); - gnrc_pktbuf_release(pkt); - return; - } - else if (gnrc_netapi_send(gnrc_ipv6_pid, hdr) < 1) { - DEBUG("ndp internal: unable to send neighbor solicitation\n"); - gnrc_pktbuf_release(hdr); - } -} - -void gnrc_ndp_internal_send_rtr_sol(kernel_pid_t iface, ipv6_addr_t *dst) -{ - gnrc_pktsnip_t *hdr, *pkt = NULL; - ipv6_addr_t *src = NULL; - DEBUG("ndp internal: send router solicitation (iface: %" PRIkernel_pid ", dst: ff02::2)\n", - iface); - if (dst == NULL) { - /* isn't changed afterwards so discarding const should be alright */ - dst = (ipv6_addr_t *)&ipv6_addr_all_routers_link_local; - } - /* check if there is a fitting source address to target */ - if ((src = gnrc_ipv6_netif_find_best_src_addr(iface, dst, false)) != NULL) { - uint8_t l2src[8]; - size_t l2src_len; - l2src_len = _get_l2src(iface, l2src, sizeof(l2src)); - if (l2src_len > 0) { - /* add source address link-layer address option */ - pkt = gnrc_ndp_opt_sl2a_build(l2src, l2src_len, NULL); - - if (pkt == NULL) { - DEBUG("ndp internal: error allocating Source Link-layer address option.\n"); - gnrc_pktbuf_release(pkt); - return; - } - } - } - hdr = gnrc_ndp_rtr_sol_build(pkt); - if (hdr == NULL) { - DEBUG("ndp internal: error allocating router solicitation.\n"); - gnrc_pktbuf_release(pkt); - return; - } - pkt = hdr; - hdr = _build_headers(iface, pkt, dst, src); - if (hdr == NULL) { - DEBUG("ndp internal: error adding lower-layer headers.\n"); - gnrc_pktbuf_release(pkt); - return; - } - else if (gnrc_netapi_send(gnrc_ipv6_pid, hdr) < 1) { - DEBUG("ndp internal: unable to send router solicitation\n"); - gnrc_pktbuf_release(hdr); - } -} - -#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER)) -static bool _pio_from_iface_addr(gnrc_pktsnip_t **res, gnrc_ipv6_netif_t *iface, - gnrc_ipv6_netif_addr_t *addr, gnrc_pktsnip_t *next) -{ - assert(((uint8_t) addr->prefix_len) <= 128U); - - if (!ipv6_addr_is_unspecified(&addr->addr) && - !ipv6_addr_is_link_local(&addr->addr) && - !gnrc_ipv6_netif_addr_is_non_unicast(&addr->addr)) { - uint8_t flags = 0; - DEBUG(" - PIO for %s/%" PRIu8 "\n", ipv6_addr_to_str(addr_str, &addr->addr, - sizeof(addr_str)), - addr->prefix_len); - -#ifdef MODULE_GNRC_SIXLOWPAN_ND - if (!(iface->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN)) { - flags = GNRC_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK; - } -#else - (void) iface; -#endif - - *res = gnrc_ndp_opt_pi_build(addr->prefix_len, addr->flags | flags, addr->valid, - addr->preferred, &addr->addr, next); - return true; - } - return false; -} - -static inline bool _check_prefixes(gnrc_ipv6_netif_addr_t *a, gnrc_ipv6_netif_addr_t *b) -{ - if ((a->prefix_len == b->prefix_len) && - (ipv6_addr_match_prefix(&a->addr, &b->addr) >= a->prefix_len)) { - return true; - } - - return false; -} - -static bool _add_pios(gnrc_pktsnip_t **res, gnrc_ipv6_netif_t *ipv6_iface, gnrc_pktsnip_t *pkt) -{ - for (int i = 0; i < GNRC_IPV6_NETIF_ADDR_NUMOF; i++) { - /* skip if prefix has been processed already */ - bool processed_before = false; - - for (int j = 0; j < i; j++) { - if ((processed_before = - _check_prefixes(&ipv6_iface->addrs[i], &ipv6_iface->addrs[j]))) { - break; - } - } - - if (processed_before) { - continue; - } - - if (_pio_from_iface_addr(res, ipv6_iface, &ipv6_iface->addrs[i], pkt)) { - if (*res != NULL) { - pkt = *res; - } - else { - DEBUG("ndp rtr: error allocating PIO\n"); - gnrc_pktbuf_release(pkt); - return false; - } - } - } - return true; -} - -void gnrc_ndp_internal_send_rtr_adv(kernel_pid_t iface, ipv6_addr_t *src, ipv6_addr_t *dst, - bool fin) -{ - gnrc_pktsnip_t *hdr = NULL, *pkt = NULL; - gnrc_ipv6_netif_t *ipv6_iface = gnrc_ipv6_netif_get(iface); - uint32_t reach_time = 0, retrans_timer = 0; - uint16_t adv_ltime = 0; - uint8_t cur_hl = 0; - - if (dst == NULL) { - /* isn't changed afterwards so discarding const should be fine */ - dst = (ipv6_addr_t *)&ipv6_addr_all_nodes_link_local; - } - DEBUG("ndp internal: send router advertisement (iface: %" PRIkernel_pid ", dst: %s%s\n", - iface, ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)), fin ? ", final" : ""); - mutex_lock(&ipv6_iface->mutex); -#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER - if (!(ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN)) { -#endif - if (!_add_pios(&hdr, ipv6_iface, pkt)) { - /* pkt already released in _add_pios */ - mutex_unlock(&ipv6_iface->mutex); - return; - } - pkt = hdr; -#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER - } - else { - gnrc_sixlowpan_nd_router_abr_t *abr = gnrc_sixlowpan_nd_router_abr_get(); - if (abr != NULL) { - gnrc_sixlowpan_nd_router_prf_t *prf = abr->prfs; - /* add prefixes from border router */ - while (prf) { - bool processed_before = false; - /* skip if prefix does not belong to iface */ - if (prf->iface != ipv6_iface) { - prf = prf->next; - continue; - } - /* skip if prefix has been processed already */ - for (gnrc_sixlowpan_nd_router_prf_t *tmp = abr->prfs; tmp != prf; tmp = tmp->next) { - if ((processed_before = - _check_prefixes(prf->prefix, tmp->prefix))) { - break; - } - } - - if (processed_before) { - prf = prf->next; - continue; - } - - if (_pio_from_iface_addr(&hdr, ipv6_iface, prf->prefix, pkt)) { - if (hdr != NULL) { - pkt = hdr; - } - else { - DEBUG("ndp rtr: error allocating PIO\n"); - gnrc_pktbuf_release(pkt); - mutex_unlock(&ipv6_iface->mutex); - return; - } - } - prf = prf->next; - } - for (unsigned int i = 0; i < GNRC_SIXLOWPAN_CTX_SIZE; i++) { - gnrc_sixlowpan_ctx_t *ctx; - if (!bf_isset(abr->ctxs, i)) { - continue; - } - ctx = gnrc_sixlowpan_ctx_lookup_id(i); - hdr = gnrc_sixlowpan_nd_opt_6ctx_build(ctx->prefix_len, ctx->flags_id, ctx->ltime, - &ctx->prefix, pkt); - if (hdr == NULL) { - DEBUG("ndp rtr: error allocating 6CO\n"); - mutex_unlock(&ipv6_iface->mutex); - gnrc_pktbuf_release(pkt); - return; - } - pkt = hdr; - } - hdr = gnrc_sixlowpan_nd_opt_abr_build(abr->version, abr->ltime, &abr->addr, pkt); - if (hdr == NULL) { - DEBUG("ndp internal: error allocating ABRO.\n"); - mutex_unlock(&ipv6_iface->mutex); - gnrc_pktbuf_release(pkt); - return; - } - pkt = hdr; - } - } -#endif /* MODULE_GNRC_SIXLOWPAN_ND_ROUTER */ - if (ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_ADV_MTU) { - if ((hdr = gnrc_ndp_opt_mtu_build(ipv6_iface->mtu, pkt)) == NULL) { - DEBUG("ndp rtr: no space left in packet buffer\n"); - mutex_unlock(&ipv6_iface->mutex); - gnrc_pktbuf_release(pkt); - return; - } - pkt = hdr; - } - if (src == NULL) { - mutex_unlock(&ipv6_iface->mutex); - /* get address from source selection algorithm. - * Only link local addresses may be used (RFC 4861 section 4.1) */ - src = gnrc_ipv6_netif_find_best_src_addr(iface, dst, true); - mutex_lock(&ipv6_iface->mutex); - } - /* add SL2A for source address */ - if (src != NULL) { - DEBUG(" - SL2A\n"); - uint8_t l2src[8]; - size_t l2src_len; - /* optimization note: MAY also be omitted to facilitate in-bound load balancing over - * replicated interfaces. - * source: https://tools.ietf.org/html/rfc4861#section-6.2.3 */ - l2src_len = _get_l2src(iface, l2src, sizeof(l2src)); - if (l2src_len > 0) { - /* add source address link-layer address option */ - hdr = gnrc_ndp_opt_sl2a_build(l2src, l2src_len, pkt); - - if (hdr == NULL) { - DEBUG("ndp internal: error allocating Source Link-layer address option.\n"); - mutex_unlock(&ipv6_iface->mutex); - gnrc_pktbuf_release(pkt); - return; - } - pkt = hdr; - } - } - if (ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_ADV_CUR_HL) { - cur_hl = ipv6_iface->cur_hl; - } - if (ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_ADV_REACH_TIME) { - - if (ipv6_iface->reach_time > (3600 * US_PER_SEC)) { /* reach_time > 1 hour */ - reach_time = (3600 * MS_PER_SEC); - } - else { - reach_time = ipv6_iface->reach_time / US_PER_MS; - } - } - if (ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_ADV_RETRANS_TIMER) { - retrans_timer = ipv6_iface->retrans_timer / US_PER_MS; - } - if (!fin) { - adv_ltime = ipv6_iface->adv_ltime; - } - mutex_unlock(&ipv6_iface->mutex); - hdr = gnrc_ndp_rtr_adv_build(cur_hl, - (ipv6_iface->flags & (GNRC_IPV6_NETIF_FLAGS_OTHER_CONF | - GNRC_IPV6_NETIF_FLAGS_MANAGED)) >> 8, - adv_ltime, reach_time, retrans_timer, pkt); - if (hdr == NULL) { - DEBUG("ndp internal: error allocating router advertisement.\n"); - gnrc_pktbuf_release(pkt); - return; - } - pkt = hdr; - hdr = _build_headers(iface, pkt, dst, src); - if (hdr == NULL) { - DEBUG("ndp internal: error adding lower-layer headers.\n"); - gnrc_pktbuf_release(pkt); - return; - } - else if (gnrc_netapi_send(gnrc_ipv6_pid, hdr) < 1) { - DEBUG("ndp internal: unable to send router advertisement\n"); - gnrc_pktbuf_release(hdr); - } -} -#endif - -int gnrc_ndp_internal_sl2a_opt_handle(gnrc_pktsnip_t *pkt, ipv6_hdr_t *ipv6, uint8_t icmpv6_type, - ndp_opt_t *sl2a_opt, uint8_t *l2src) -{ - int sl2a_len = 0; - uint8_t *sl2a = (uint8_t *)(sl2a_opt + 1); - - if ((sl2a_opt->len == 0) || ipv6_addr_is_unspecified(&ipv6->src)) { - DEBUG("ndp: invalid source link-layer address option received\n"); - return -EINVAL; - } - - while (pkt) { - if (pkt->type == GNRC_NETTYPE_NETIF) { - gnrc_netif_hdr_t *hdr = pkt->data; - sl2a_len = hdr->src_l2addr_len; - break; - } - pkt = pkt->next; - } - -#ifdef MODULE_GNRC_SIXLOWPAN_ND - if ((sl2a_len == 2) || (sl2a_len == 8)) { - /* The link-layer seems to be IEEE 802.15.4. - * Determining address length from the option length: - * https://tools.ietf.org/html/rfc4944#section-8 */ - if (sl2a_opt->len == 1) { - sl2a_len = 2; - } - else if (sl2a_opt->len == 2) { - sl2a_len = 8; - } - else { - DEBUG("ndp: invalid source link-layer address option received\n"); - return -EINVAL; - } - } -#endif - - DEBUG("ndp: received SL2A (link-layer address: %s)\n", - gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), sl2a, sl2a_len)); - - switch (icmpv6_type) { - case ICMPV6_RTR_SOL: - case ICMPV6_RTR_ADV: - case ICMPV6_NBR_SOL: - if (sl2a_len == 0) { /* in case there was no source address in l2 */ - sl2a_len = (sl2a_opt->len * 8) - sizeof(ndp_opt_t); - - /* ignore all zeroes at the end for length */ - for (; sl2a[sl2a_len - 1] == 0x00; sl2a_len--); - } - - memcpy(l2src, sl2a, sl2a_len); - return sl2a_len; - - default: /* wrong encapsulating message: silently discard */ - DEBUG("ndp: silently discard sl2a_opt for ICMPv6 message type %" - PRIu8 "\n", icmpv6_type); - return -ENOTSUP; - } -} - -int gnrc_ndp_internal_tl2a_opt_handle(gnrc_pktsnip_t *pkt, ipv6_hdr_t *ipv6, - uint8_t icmpv6_type, ndp_opt_t *tl2a_opt, - uint8_t *l2addr) -{ - uint8_t tl2a_len = 0; - uint8_t *tl2a = (uint8_t *)(tl2a_opt + 1); - - if ((tl2a_opt->len == 0) || ipv6_addr_is_unspecified(&ipv6->src)) { - DEBUG("ndp: invalid target link-layer address option received\n"); - return -EINVAL; - } - - switch (icmpv6_type) { - case ICMPV6_NBR_ADV: - while (pkt) { - if (pkt->type == GNRC_NETTYPE_NETIF) { - gnrc_netif_hdr_t *hdr = pkt->data; - tl2a_len = hdr->src_l2addr_len; - break; - } - pkt = pkt->next; - } -#ifdef MODULE_GNRC_SIXLOWPAN_ND - if ((tl2a_len == 2) || (tl2a_len == 8)) { - /* The link-layer seems to be IEEE 802.15.4. - * Determining address length from the option length: - * https://tools.ietf.org/html/rfc4944#section-8 */ - if (tl2a_opt->len == 1) { - tl2a_len = 2; - } - else if (tl2a_opt->len == 2) { - tl2a_len = 8; - } - else { - DEBUG("ndp: invalid target link-layer address option received\n"); - return -EINVAL; - } - } -#endif - - if (tl2a_len == 0) { /* in case there was no source address in l2 */ - tl2a_len = (tl2a_opt->len / 8) - sizeof(ndp_opt_t); - - /* ignore all zeroes at the end for length */ - for (; tl2a[tl2a_len - 1] == 0x00; tl2a_len--); - } - - DEBUG("ndp: received TL2A (link-layer address: %s)\n", - gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), tl2a, tl2a_len)); - - memcpy(l2addr, tl2a, tl2a_len); - - return (int)tl2a_len; - - default: /* wrong encapsulating message: silently discard */ - DEBUG("ndp: silently discard tl2a_opt for ICMPv6 message type %" - PRIu8 "\n", icmpv6_type); - return 0; - } -} - -bool gnrc_ndp_internal_mtu_opt_handle(kernel_pid_t iface, uint8_t icmpv6_type, - ndp_opt_mtu_t *mtu_opt) -{ - gnrc_ipv6_netif_t *if_entry = gnrc_ipv6_netif_get(iface); - - if ((mtu_opt->len != NDP_OPT_MTU_LEN)) { - DEBUG("ndp: invalid MTU option received\n"); - return false; - } - if (icmpv6_type != ICMPV6_RTR_ADV) { - /* else discard silently */ - return true; - } - mutex_lock(&if_entry->mutex); - if_entry->mtu = byteorder_ntohl(mtu_opt->mtu); - mutex_unlock(&if_entry->mutex); - return true; -} - -bool gnrc_ndp_internal_pi_opt_handle(kernel_pid_t iface, uint8_t icmpv6_type, - ndp_opt_pi_t *pi_opt) -{ - ipv6_addr_t *prefix; - gnrc_ipv6_netif_addr_t *netif_addr; - - if ((pi_opt->len != NDP_OPT_PI_LEN)) { - DEBUG("ndp: invalid PI option received\n"); - return false; - } - if (icmpv6_type != ICMPV6_RTR_ADV || ipv6_addr_is_link_local(&pi_opt->prefix)) { - /* else discard silently */ - return true; - } -#ifdef MODULE_GNRC_SIXLOWPAN_ND - if ((gnrc_ipv6_netif_get(iface)->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) && - (pi_opt->flags & NDP_OPT_PI_FLAGS_L)) { - /* ignore: see https://tools.ietf.org/html/rfc6775#section-5.4 */ - return true; - } -#endif - prefix = gnrc_ipv6_netif_find_addr(iface, &pi_opt->prefix); - if (((prefix == NULL) || - (gnrc_ipv6_netif_addr_get(prefix)->prefix_len != pi_opt->prefix_len)) && - (pi_opt->valid_ltime.u32 != 0)) { - ipv6_addr_t pref_addr = IPV6_ADDR_UNSPECIFIED; - - if (pi_opt->flags & NDP_OPT_PI_FLAGS_A) { - if ((gnrc_netapi_get(iface, NETOPT_IPV6_IID, 0, &pref_addr.u64[1], - sizeof(eui64_t)) < 0)) { - DEBUG("ndp: could not get IID from interface %d\n", iface); - return false; - } - } - - ipv6_addr_init_prefix(&pref_addr, &pi_opt->prefix, pi_opt->prefix_len); - prefix = gnrc_ipv6_netif_add_addr(iface, &pref_addr, - pi_opt->prefix_len, - pi_opt->flags & NDP_OPT_PI_FLAGS_MASK); - if (prefix == NULL) { - DEBUG("ndp: could not add prefix to interface %d\n", iface); - return false; - } -#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER - gnrc_sixlowpan_nd_router_set_rtr_adv(gnrc_ipv6_netif_get(iface), true); -#endif - } - netif_addr = gnrc_ipv6_netif_addr_get(prefix); - if (pi_opt->valid_ltime.u32 == 0) { - if (prefix != NULL) { - gnrc_ipv6_netif_remove_addr(iface, &netif_addr->addr); - } - - return true; - } - netif_addr->valid = byteorder_ntohl(pi_opt->valid_ltime); - netif_addr->preferred = byteorder_ntohl(pi_opt->pref_ltime); - if (netif_addr->valid != UINT32_MAX) { - xtimer_set_msg(&netif_addr->valid_timeout, - (byteorder_ntohl(pi_opt->valid_ltime) * US_PER_SEC), - &netif_addr->valid_timeout_msg, thread_getpid()); - } - /* TODO: preferred lifetime for address auto configuration */ - /* on-link flag MUST stay set if it was */ - netif_addr->flags &= NDP_OPT_PI_FLAGS_L; - netif_addr->flags |= (pi_opt->flags & NDP_OPT_PI_FLAGS_MASK); - return true; -} - -static size_t _get_l2src(kernel_pid_t iface, uint8_t *l2src, size_t l2src_maxlen) -{ - bool try_long = false; - int res; - uint16_t l2src_len; - /* maximum address length that fits into a minimum length (8) S/TL2A option */ - const uint16_t max_short_len = 6; - - /* try getting source address */ - if ((gnrc_netapi_get(iface, NETOPT_SRC_LEN, 0, &l2src_len, - sizeof(l2src_len)) >= 0) && - (l2src_len > max_short_len)) { - try_long = true; - } - - if (try_long && ((res = gnrc_netapi_get(iface, NETOPT_ADDRESS_LONG, 0, - l2src, l2src_maxlen)) > max_short_len)) { - l2src_len = (uint16_t)res; - } - else if ((res = gnrc_netapi_get(iface, NETOPT_ADDRESS, 0, l2src, - l2src_maxlen)) >= 0) { - l2src_len = (uint16_t)res; - } - else { - DEBUG("ndp internal: no link-layer address found.\n"); - l2src_len = 0; - } - - return l2src_len; -} - -static gnrc_pktsnip_t *_build_headers(kernel_pid_t iface, gnrc_pktsnip_t *payload, - ipv6_addr_t *dst, ipv6_addr_t *src) -{ - gnrc_pktsnip_t *l2hdr; - gnrc_pktsnip_t *iphdr = gnrc_ipv6_hdr_build(payload, src, dst); - if (iphdr == NULL) { - DEBUG("ndp internal: error allocating IPv6 header.\n"); - return NULL; - } - ((ipv6_hdr_t *)iphdr->data)->hl = 255; - /* add netif header for send interface specification */ - l2hdr = gnrc_netif_hdr_build(NULL, 0, NULL, 0); - if (l2hdr == NULL) { - DEBUG("ndp internal: error allocating netif header.\n"); - gnrc_pktbuf_remove_snip(iphdr, iphdr); - return NULL; - } - ((gnrc_netif_hdr_t *)l2hdr->data)->if_pid = iface; - LL_PREPEND(iphdr, l2hdr); - return l2hdr; -} - -/** @} */ diff --git a/sys/net/gnrc/network_layer/ndp/node/Makefile b/sys/net/gnrc/network_layer/ndp/node/Makefile deleted file mode 100644 index 127a91910935d743e56ffe82d31b22f07d2ea6aa..0000000000000000000000000000000000000000 --- a/sys/net/gnrc/network_layer/ndp/node/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -MODULE = gnrc_ndp_node - -include $(RIOTBASE)/Makefile.base diff --git a/sys/net/gnrc/network_layer/ndp/node/gnrc_ndp_node.c b/sys/net/gnrc/network_layer/ndp/node/gnrc_ndp_node.c deleted file mode 100644 index 402d344d209231df370218cbba6be2ac663e4d92..0000000000000000000000000000000000000000 --- a/sys/net/gnrc/network_layer/ndp/node/gnrc_ndp_node.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @{ - * - * @file - */ - -#include <stdint.h> -#include <stdlib.h> - -#include "kernel_types.h" -#include "net/fib.h" -#include "net/gnrc/ipv6.h" -#include "net/gnrc/ndp.h" -#include "net/gnrc/pkt.h" -#include "net/gnrc/pktqueue.h" - -#include "net/gnrc/ndp/internal.h" - -#include "net/gnrc/ndp/node.h" - -#define ENABLE_DEBUG (0) -#include "debug.h" - -#if ENABLE_DEBUG -static char addr_str[IPV6_ADDR_MAX_STR_LEN]; -#endif - -static gnrc_pktqueue_t _pkt_nodes[GNRC_IPV6_NC_SIZE * 2]; - -/** - * @brief Allocates a node for the packet queue. - * - * @param[in] pkt Packet to add to the packet queue. - * - * @return A packet queue node. - */ -static gnrc_pktqueue_t *_alloc_pkt_node(gnrc_pktsnip_t *pkt) -{ - for (size_t i = 0; i < sizeof(_pkt_nodes) / sizeof(gnrc_pktqueue_t); i++) { - if ((_pkt_nodes[i].pkt == NULL) && (_pkt_nodes[i].next == NULL)) { - _pkt_nodes[i].pkt = pkt; - - return &(_pkt_nodes[i]); - } - } - - return NULL; -} - -kernel_pid_t gnrc_ndp_node_next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len, - kernel_pid_t iface, ipv6_addr_t *dst, - gnrc_pktsnip_t *pkt) -{ - gnrc_ipv6_nc_t *nc_entry; - ipv6_addr_t *next_hop_ip = NULL, *prefix = NULL; - bool dst_link_local = ipv6_addr_is_link_local(dst); - -#ifdef MODULE_FIB - ipv6_addr_t next_hop_actual; /* FIB copies address into this variable */ - /* don't look-up link local addresses in FIB */ - if (!dst_link_local) { - size_t next_hop_size = sizeof(ipv6_addr_t); - uint32_t next_hop_flags = 0; - - if ((next_hop_ip == NULL) && - (fib_get_next_hop(&gnrc_ipv6_fib_table, &iface, next_hop_actual.u8, - &next_hop_size, &next_hop_flags, (uint8_t *)dst, - sizeof(ipv6_addr_t), 0) >= 0) && - (next_hop_size == sizeof(ipv6_addr_t))) { - next_hop_ip = &next_hop_actual; - } - } -#endif - - /* cppcheck-suppress knownConditionTrueFalse - * cppcheck bug: next_hop_ip might be initialized if a FIB is available */ - if (next_hop_ip == NULL) { /* no route to host */ - if (!dst_link_local) { - if (iface == KERNEL_PID_UNDEF) { - /* gnrc_ipv6_netif_t doubles as prefix list */ - iface = gnrc_ipv6_netif_find_by_prefix(&prefix, dst); - } - else { - /* gnrc_ipv6_netif_t doubles as prefix list */ - prefix = gnrc_ipv6_netif_match_prefix(iface, dst); - } - } - - if (dst_link_local || ((prefix != NULL) && - (gnrc_ipv6_netif_addr_get(prefix)->flags & /* prefix is on-link */ - GNRC_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK))) { - next_hop_ip = dst; - } - } - - /* dst has not an on-link prefix */ - if (next_hop_ip == NULL) { - next_hop_ip = gnrc_ndp_internal_default_router(); - } - - if (next_hop_ip == NULL) { - next_hop_ip = dst; /* Just look if it's in the neighbor cache - * (aka on-link but not registered in prefix list as such) */ - } - - /* start address resolution */ - nc_entry = gnrc_ipv6_nc_get(iface, next_hop_ip); - - if ((nc_entry != NULL) && gnrc_ipv6_nc_is_reachable(nc_entry)) { - DEBUG("ndp node: found reachable neighbor (%s => ", - ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str))); - DEBUG("%s)\n", - gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), - nc_entry->l2_addr, nc_entry->l2_addr_len)); - - if (gnrc_ipv6_nc_get_state(nc_entry) == GNRC_IPV6_NC_STATE_STALE) { - gnrc_ndp_internal_set_state(nc_entry, GNRC_IPV6_NC_STATE_DELAY); - } - return gnrc_ipv6_nc_get_l2_addr(l2addr, l2addr_len, nc_entry); - } - else if (nc_entry == NULL) { - gnrc_pktqueue_t *pkt_node; - ipv6_addr_t dst_sol; - - nc_entry = gnrc_ipv6_nc_add(iface, next_hop_ip, NULL, 0, - GNRC_IPV6_NC_STATE_INCOMPLETE << GNRC_IPV6_NC_STATE_POS); - - if (nc_entry == NULL) { - DEBUG("ndp node: could not create neighbor cache entry\n"); - return KERNEL_PID_UNDEF; - } - - pkt_node = _alloc_pkt_node(pkt); - - if (pkt_node == NULL) { - DEBUG("ndp node: could not add packet to packet queue\n"); - } - else { - /* prevent packet from being released by IPv6 */ - gnrc_pktbuf_hold(pkt_node->pkt, 1); - gnrc_pktqueue_add(&nc_entry->pkts, pkt_node); - } - - /* address resolution */ - ipv6_addr_set_solicited_nodes(&dst_sol, next_hop_ip); - - if (iface == KERNEL_PID_UNDEF) { - kernel_pid_t ifs[GNRC_NETIF_NUMOF]; - size_t ifnum = gnrc_netif_get(ifs); - - for (size_t i = 0; i < ifnum; i++) { - gnrc_ndp_internal_send_nbr_sol(ifs[i], NULL, next_hop_ip, &dst_sol); - } - - gnrc_ndp_internal_reset_nbr_sol_timer(nc_entry, GNRC_NDP_RETRANS_TIMER, - GNRC_NDP_MSG_NBR_SOL_RETRANS, gnrc_ipv6_pid); - } - else { - gnrc_ipv6_netif_t *ipv6_iface = gnrc_ipv6_netif_get(iface); - - gnrc_ndp_internal_send_nbr_sol(iface, NULL, next_hop_ip, &dst_sol); - - mutex_lock(&ipv6_iface->mutex); - gnrc_ndp_internal_reset_nbr_sol_timer(nc_entry, ipv6_iface->retrans_timer, - GNRC_NDP_MSG_NBR_SOL_RETRANS, gnrc_ipv6_pid); - mutex_unlock(&ipv6_iface->mutex); - } - } - - return KERNEL_PID_UNDEF; -} - - -/** @} */ diff --git a/sys/net/gnrc/network_layer/ndp/router/Makefile b/sys/net/gnrc/network_layer/ndp/router/Makefile deleted file mode 100644 index 541dc343692c18477294358051880d8477ec554d..0000000000000000000000000000000000000000 --- a/sys/net/gnrc/network_layer/ndp/router/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -MODULE = gnrc_ndp_router - -include $(RIOTBASE)/Makefile.base diff --git a/sys/net/gnrc/network_layer/ndp/router/gnrc_ndp_router.c b/sys/net/gnrc/network_layer/ndp/router/gnrc_ndp_router.c deleted file mode 100644 index 07fd1109742eb1fadee752ced22c2ed256f51d88..0000000000000000000000000000000000000000 --- a/sys/net/gnrc/network_layer/ndp/router/gnrc_ndp_router.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @{ - * - * @file - */ - -#include "net/gnrc/ipv6.h" -#include "net/gnrc/ndp.h" -#include "net/gnrc/ndp/internal.h" -#include "random.h" -#include "xtimer.h" - -#include "net/gnrc/ndp/router.h" - -#define ENABLE_DEBUG (0) -#include "debug.h" - -static void _send_rtr_adv(gnrc_ipv6_netif_t *iface, ipv6_addr_t *dst); - -void gnrc_ndp_router_set_router(gnrc_ipv6_netif_t *iface, bool enable) -{ - if (enable && !(iface->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER)) { - gnrc_ipv6_netif_add_addr(iface->pid, &ipv6_addr_all_routers_link_local, - 128, GNRC_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST); - mutex_lock(&iface->mutex); - iface->flags |= GNRC_IPV6_NETIF_FLAGS_ROUTER; - iface->max_adv_int = GNRC_IPV6_NETIF_DEFAULT_MAX_ADV_INT; - iface->min_adv_int = GNRC_IPV6_NETIF_DEFAULT_MIN_ADV_INT; - iface->adv_ltime = GNRC_IPV6_NETIF_DEFAULT_ROUTER_LTIME; - mutex_unlock(&iface->mutex); - gnrc_ndp_router_set_rtr_adv(iface, enable); - } - else if (!enable && (iface->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER)) { - gnrc_ipv6_netif_remove_addr(iface->pid, (ipv6_addr_t *)&ipv6_addr_all_routers_link_local); - gnrc_ndp_router_set_rtr_adv(iface, enable); - } -} - -void gnrc_ndp_router_set_rtr_adv(gnrc_ipv6_netif_t *iface, bool enable) -{ - if (enable && !(iface->flags & GNRC_IPV6_NETIF_FLAGS_RTR_ADV)) { - mutex_lock(&iface->mutex); - iface->flags |= GNRC_IPV6_NETIF_FLAGS_RTR_ADV; - iface->rtr_adv_count = GNRC_NDP_MAX_INIT_RTR_ADV_NUMOF; - mutex_unlock(&iface->mutex); - _send_rtr_adv(iface, NULL); - } - else if (!enable && (iface->flags & GNRC_IPV6_NETIF_FLAGS_RTR_ADV)) { - mutex_lock(&iface->mutex); - iface->rtr_adv_count = GNRC_NDP_MAX_FIN_RTR_ADV_NUMOF; - iface->flags &= ~GNRC_IPV6_NETIF_FLAGS_RTR_ADV; - iface->adv_ltime = 0; -#ifdef MODULE_GNRC_NDP_HOST - iface->rtr_sol_count = GNRC_NDP_MAX_RTR_SOL_NUMOF; -#endif - mutex_unlock(&iface->mutex); - _send_rtr_adv(iface, NULL); -#ifdef MODULE_GNRC_NDP_HOST - gnrc_ndp_host_retrans_rtr_sol(iface); -#endif - } -} - -void gnrc_ndp_router_retrans_rtr_adv(gnrc_ipv6_netif_t *iface) -{ - _send_rtr_adv(iface, NULL); -} - -void gnrc_ndp_router_send_rtr_adv(gnrc_ipv6_nc_t *neighbor) -{ - gnrc_ipv6_netif_t *iface = gnrc_ipv6_netif_get(neighbor->iface); - /* TODO: send one router advertisement per ABR: https://tools.ietf.org/html/rfc6775#section-6.3 */ - _send_rtr_adv(iface, &neighbor->ipv6_addr); -} - -static void _send_rtr_adv(gnrc_ipv6_netif_t *iface, ipv6_addr_t *dst) -{ - bool fin; - uint32_t interval; - - mutex_lock(&iface->mutex); - fin = (iface->adv_ltime == 0); - assert((iface->min_adv_int != 0) && (iface->max_adv_int != 0)); - interval = random_uint32_range(iface->min_adv_int, iface->max_adv_int); - if (!fin && !((iface->flags | GNRC_IPV6_NETIF_FLAGS_ROUTER) && - (iface->flags | GNRC_IPV6_NETIF_FLAGS_RTR_ADV))) { - DEBUG("ndp rtr: interface %" PRIkernel_pid " is not an advertising interface\n", - iface->pid); - return; - } - if (iface->rtr_adv_count > 1) { /* regard for off-by-one error */ - iface->rtr_adv_count--; - if (!fin && (interval > GNRC_NDP_MAX_INIT_RTR_ADV_INT)) { - interval = GNRC_NDP_MAX_INIT_RTR_ADV_INT; - } - } - if (!fin || (iface->rtr_adv_count > 1)) { /* regard for off-by-one-error */ - /* reset timer for next router advertisement */ - xtimer_remove(&iface->rtr_adv_timer); - iface->rtr_adv_msg.type = GNRC_NDP_MSG_RTR_ADV_RETRANS; - iface->rtr_adv_msg.content.ptr = iface; - xtimer_set_msg(&iface->rtr_adv_timer, interval * US_PER_SEC, &iface->rtr_adv_msg, - gnrc_ipv6_pid); - } - mutex_unlock(&iface->mutex); - for (int i = 0; i < GNRC_IPV6_NETIF_ADDR_NUMOF; i++) { - ipv6_addr_t *src = &iface->addrs[i].addr; - - if (!ipv6_addr_is_unspecified(src) && ipv6_addr_is_link_local(src) && - !gnrc_ipv6_netif_addr_is_non_unicast(src)) { - /* send one for every link local address (ideally there is only one) */ - gnrc_ndp_internal_send_rtr_adv(iface->pid, src, dst, fin); - } - } -} - -/** @} */ diff --git a/sys/shell/commands/Makefile b/sys/shell/commands/Makefile index 09d4280498f8d4b139d4407dcdd59354fba8dfaa..2c8da3187382eee948975c16f07b1df6aa3194d9 100644 --- a/sys/shell/commands/Makefile +++ b/sys/shell/commands/Makefile @@ -29,9 +29,6 @@ endif ifneq (,$(filter fib,$(USEMODULE))) SRC += sc_fib.c endif -ifneq (,$(filter gnrc_ipv6_nc,$(USEMODULE))) - SRC += sc_ipv6_nc.c -endif ifneq (,$(filter gnrc_ipv6_nib,$(USEMODULE))) SRC += sc_gnrc_ipv6_nib.c endif diff --git a/sys/shell/commands/sc_gnrc_6ctx.c b/sys/shell/commands/sc_gnrc_6ctx.c index 32232e2188b4d33ea8717bb88cb6a3efd9548a25..ab457e444c4af0b1c6feee8ce5226debe9ccbd9b 100644 --- a/sys/shell/commands/sc_gnrc_6ctx.c +++ b/sys/shell/commands/sc_gnrc_6ctx.c @@ -20,7 +20,6 @@ #include <string.h> #include "net/ipv6/addr.h" -#include "net/gnrc/ndp/internal.h" #include "net/gnrc/sixlowpan/ctx.h" #include "net/gnrc/sixlowpan/nd.h" #include "timex.h" diff --git a/sys/shell/commands/sc_icmpv6_echo.c b/sys/shell/commands/sc_icmpv6_echo.c index 2d6710946ca49420c931fa51634410611dfd5bb0..5ac65923b4abcdef3cad064de45bf46e58f82b35 100644 --- a/sys/shell/commands/sc_icmpv6_echo.c +++ b/sys/shell/commands/sc_icmpv6_echo.c @@ -24,7 +24,9 @@ #include "byteorder.h" #include "net/gnrc/icmpv6.h" #include "net/ipv6/addr.h" -#include "net/gnrc/ipv6/nc.h" +#ifdef MODULE_GNRC_IPV6_NIB +#include "net/gnrc/ipv6/nib/nc.h" +#endif #include "net/gnrc/ipv6/hdr.h" #include "net/gnrc/netif2.h" #include "net/gnrc.h" @@ -109,8 +111,8 @@ int _handle_reply(gnrc_pktsnip_t *pkt, uint32_t time) ipv6_addr_to_str(ipv6_str, &(ipv6_hdr->src), sizeof(ipv6_str)), byteorder_ntohs(icmpv6_hdr->id), seq, (unsigned)ipv6_hdr->hl, time / US_PER_MS, time % US_PER_MS); -#ifdef MODULE_GNRC_IPV6_NC - gnrc_ipv6_nc_still_reachable(&ipv6_hdr->src); +#ifdef MODULE_GNRC_IPV6_NIB + gnrc_ipv6_nib_nc_mark_reachable(&ipv6_hdr->src); #endif } else { diff --git a/sys/shell/commands/sc_ipv6_nc.c b/sys/shell/commands/sc_ipv6_nc.c deleted file mode 100644 index 88f16e768f70ab304e1d5127a1c12ed5c8bad5a8..0000000000000000000000000000000000000000 --- a/sys/shell/commands/sc_ipv6_nc.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de> - * - * This file is subject to the terms and conditions of the GNU Lesser General - * Public License v2.1. See the file LICENSE in the top level directory for - * more details. - */ - -/** - * @ingroup sys_shell_commands.h - * @{ - * - * @file - * - * @author Martine Lenders <mlenders@inf.fu-berlin.de> - */ - -#include <stdio.h> -#include <string.h> - -#include "kernel_types.h" -#include "net/ipv6/addr.h" -#include "net/gnrc/ipv6/nc.h" -#include "thread.h" - -/* maximum length of L2 address */ -#define MAX_L2_ADDR_LEN (8U) - -static void _print_nc_state(gnrc_ipv6_nc_t *entry) -{ - switch (entry->flags & GNRC_IPV6_NC_STATE_MASK) { - case GNRC_IPV6_NC_STATE_UNMANAGED: - printf("UNMANAGED "); - break; - - case GNRC_IPV6_NC_STATE_UNREACHABLE: - printf("UNREACHABLE "); - break; - - case GNRC_IPV6_NC_STATE_INCOMPLETE: - printf("INCOMPLETE "); - break; - - case GNRC_IPV6_NC_STATE_STALE: - printf("STALE "); - break; - - case GNRC_IPV6_NC_STATE_DELAY: - printf("DELAY "); - break; - - case GNRC_IPV6_NC_STATE_PROBE: - printf("PROBE "); - break; - - case GNRC_IPV6_NC_STATE_REACHABLE: - printf("REACHABLE "); - break; - - default: - printf("UNKNOWN "); - break; - } -} - -static void _print_nc_type(gnrc_ipv6_nc_t *entry) -{ - switch (entry->flags & GNRC_IPV6_NC_TYPE_MASK) { - case GNRC_IPV6_NC_TYPE_GC: - printf("GC"); - break; - - case GNRC_IPV6_NC_TYPE_TENTATIVE: - printf("TENT"); - break; - - case GNRC_IPV6_NC_TYPE_REGISTERED: - printf("REG"); - break; - - default: - printf("-"); - break; - } -} - -static bool _is_iface(kernel_pid_t iface) -{ - return (thread_get(iface) != NULL); -} - -static int _ipv6_nc_list(void) -{ - char ipv6_str[IPV6_ADDR_MAX_STR_LEN]; - char l2addr_str[3 * MAX_L2_ADDR_LEN]; - - puts("IPv6 address if L2 address state type"); - puts("------------------------------------------------------------------------------"); - - for (gnrc_ipv6_nc_t *entry = gnrc_ipv6_nc_get_next(NULL); - entry != NULL; - entry = gnrc_ipv6_nc_get_next(entry)) { - printf("%-30s %2" PRIkernel_pid " %-24s ", - ipv6_addr_to_str(ipv6_str, &entry->ipv6_addr, sizeof(ipv6_str)), - entry->iface, - gnrc_netif_addr_to_str(l2addr_str, sizeof(l2addr_str), - entry->l2_addr, entry->l2_addr_len)); - _print_nc_state(entry); - _print_nc_type(entry); - puts(""); - } - - return 0; -} - -static inline kernel_pid_t _get_iface(void) -{ - kernel_pid_t ifs[GNRC_NETIF_NUMOF]; - size_t ifnum = gnrc_netif_get(ifs); - return (ifnum > 1) ? KERNEL_PID_UNDEF : ifs[0]; -} - -static int _ipv6_nc_add(int argc, char **argv) -{ - char *ipv6_addr_str; - char *l2_addr_str = NULL; - kernel_pid_t iface = KERNEL_PID_UNDEF; - ipv6_addr_t ipv6_addr; - uint8_t l2_addr[MAX_L2_ADDR_LEN]; - size_t l2_addr_len = 0; - - switch (argc) { - case 1: - iface = _get_iface(); - ipv6_addr_str = argv[0]; /* store for output */ - l2_addr_len = 0; - break; - case 2: - ipv6_addr_str = argv[0]; /* store for output */ - if (ipv6_addr_from_str(&ipv6_addr, ipv6_addr_str) == NULL) { - iface = atoi(argv[0]); - ipv6_addr_str = argv[1]; - l2_addr_len = 0; - } - else { - iface = _get_iface(); - l2_addr_str = argv[1]; - } - break; - default: - iface = atoi(argv[0]); - ipv6_addr_str = argv[1]; - l2_addr_str = argv[2]; - break; - } - - if (!_is_iface(iface)) { - puts("error: invalid interface given."); - return 1; - } - - if (ipv6_addr_from_str(&ipv6_addr, ipv6_addr_str) == NULL) { - puts("error: unable to parse IPv6 address."); - return 1; - } - - if ((l2_addr_str != NULL) && (l2_addr_len = gnrc_netif_addr_from_str(l2_addr, sizeof(l2_addr), - l2_addr_str)) == 0) { - puts("error: unable to parse link-layer address."); - return 1; - } - - if (gnrc_ipv6_nc_add(iface, &ipv6_addr, l2_addr, l2_addr_len, 0) == NULL) { - puts("error: unable to add address to neighbor cache."); - return 1; - } - - printf("success: added IPv6 address %s to neighbor cache\n", ipv6_addr_str); - return 0; -} - -static int _ipv6_nc_del(char *ipv6_addr_str) -{ - ipv6_addr_t ipv6_addr; - - if (ipv6_addr_from_str(&ipv6_addr, ipv6_addr_str) == NULL) { - puts("error: unable to parse IPv6 address."); - return 1; - } - - gnrc_ipv6_nc_remove(KERNEL_PID_UNDEF, &ipv6_addr); - printf("success: removed %s from neighbor cache\n", ipv6_addr_str); - - return 0; -} - -static int _ipv6_nc_reset(void) -{ - gnrc_ipv6_nc_t *tmp = NULL; - - for (gnrc_ipv6_nc_t *entry = gnrc_ipv6_nc_get_next(NULL); - entry != NULL; - tmp = entry, entry = gnrc_ipv6_nc_get_next(entry)) { - if (tmp) { - gnrc_ipv6_nc_remove(tmp->iface, &tmp->ipv6_addr); - } - } - - /* remove last entry */ - if (tmp) { - gnrc_ipv6_nc_remove(tmp->iface, &tmp->ipv6_addr); - } - - printf("success: reset neighbor cache\n"); - - return 0; -} - -int _ipv6_nc_manage(int argc, char **argv) -{ - if ((argc == 1) || (strcmp("list", argv[1]) == 0)) { - return _ipv6_nc_list(); - } - - if (argc > 1) { - if ((argc > 2) && (strcmp("add", argv[1]) == 0)) { - return _ipv6_nc_add(argc - 2, &argv[2]); - } - if ((argc > 2) && (strcmp("del", argv[1]) == 0)) { - return _ipv6_nc_del(argv[2]); - } - if (strcmp("reset", argv[1]) == 0) { - return _ipv6_nc_reset(); - } - } - - printf("usage: %s [list]\n" - " or: %s add [<iface pid>] <ipv6_addr> <l2_addr>\n" - " * <iface pid> is optional if only one interface exists.\n" - " or: %s del <ipv6_addr>\n" - " or: %s reset\n", argv[0], argv[0], argv[0], argv[0]); - return 1; -} - -int _ipv6_nc_routers(int argc, char **argv) -{ - kernel_pid_t iface = KERNEL_PID_UNDEF; - char ipv6_str[IPV6_ADDR_MAX_STR_LEN]; - - if (argc > 1) { - iface = atoi(argv[1]); - - if (!_is_iface(iface)) { - printf("usage: %s [<iface pid>]\n", argv[0]); - return 1; - } - } - - puts("if Router state type"); - puts("---------------------------------------------------"); - - for (gnrc_ipv6_nc_t *entry = gnrc_ipv6_nc_get_next_router(NULL); - entry != NULL; - entry = gnrc_ipv6_nc_get_next_router(entry)) { - if ((iface != KERNEL_PID_UNDEF) && (iface != entry->iface)) { - continue; - } - - printf("%2" PRIkernel_pid " %-30s ", entry->iface, - ipv6_addr_to_str(ipv6_str, &entry->ipv6_addr, sizeof(ipv6_str))); - _print_nc_state(entry); - _print_nc_type(entry); - puts(""); - } - - return 0; -} - -/** - * @} - */ diff --git a/sys/shell/commands/shell_commands.c b/sys/shell/commands/shell_commands.c index fc7fc22796852b9dfe1306aa8dae4c70b4fa15db..e61b9e2552dd814299fa4bb7b8482d4fa39a17d5 100644 --- a/sys/shell/commands/shell_commands.c +++ b/sys/shell/commands/shell_commands.c @@ -200,10 +200,6 @@ const shell_command_t _shell_command_list[] = { #ifdef MODULE_FIB {"fibroute", "Manipulate the FIB (info: 'fibroute [add|del]')", _fib_route_handler}, #endif -#ifdef MODULE_GNRC_IPV6_NC - {"ncache", "manage neighbor cache by hand", _ipv6_nc_manage }, - {"routers", "IPv6 default router list", _ipv6_nc_routers }, -#endif #ifdef MODULE_GNRC_IPV6_WHITELIST {"whitelist", "whitelists an address for receival ('whitelist [add|del|help]')", _whitelist }, #endif