diff --git a/sys/include/net/gnrc/ipv6/nc.h b/sys/include/net/gnrc/ipv6/nc.h index a99251e79..617d59625 100644 --- a/sys/include/net/gnrc/ipv6/nc.h +++ b/sys/include/net/gnrc/ipv6/nc.h @@ -21,8 +21,10 @@ #ifndef GNRC_IPV6_NC_H_ #define GNRC_IPV6_NC_H_ +#include #include #include +#include #include "kernel_types.h" #include "net/eui64.h" @@ -293,6 +295,21 @@ static inline bool gnrc_ipv6_nc_is_reachable(const gnrc_ipv6_nc_t *entry) */ 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 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 index 8357b9924..345081cc7 100644 --- a/sys/net/gnrc/network_layer/ipv6/nc/gnrc_ipv6_nc.c +++ b/sys/net/gnrc/network_layer/ipv6/nc/gnrc_ipv6_nc.c @@ -263,4 +263,16 @@ gnrc_ipv6_nc_t *gnrc_ipv6_nc_still_reachable(const ipv6_addr_t *ipv6_addr) 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; +} + /** @} */