From db2da19ea434c4b89005480d39abaceaa1304eb2 Mon Sep 17 00:00:00 2001 From: Martine Lenders <m.lenders@fu-berlin.de> Date: Sun, 18 Feb 2018 17:41:10 +0100 Subject: [PATCH] gnrc_ipv6: send IPv6 error messages where appropriate --- sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c | 23 ++++++++++++++++--- .../network_layer/ipv6/nib/_nib-internal.c | 3 +++ sys/net/gnrc/network_layer/ipv6/nib/nib.c | 9 ++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c index 255095f639..b030e39959 100644 --- a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c +++ b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c @@ -321,7 +321,8 @@ static void _send_to_iface(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) ((gnrc_netif_hdr_t *)pkt->data)->if_pid = netif->pid; if (gnrc_pkt_len(pkt->next) > netif->ipv6.mtu) { DEBUG("ipv6: packet too big\n"); - gnrc_pktbuf_release(pkt); + gnrc_icmpv6_error_pkt_too_big_send(netif->ipv6.mtu, pkt); + gnrc_pktbuf_release_error(pkt, EMSGSIZE); return; } #ifdef MODULE_NETSTATS_IPV6 @@ -742,6 +743,7 @@ static void _receive(gnrc_pktsnip_t *pkt) #ifdef MODULE_GNRC_IPV6_WHITELIST if (!gnrc_ipv6_whitelisted(&((ipv6_hdr_t *)(pkt->data))->src)) { DEBUG("ipv6: Source address not whitelisted, dropping packet\n"); + gnrc_icmpv6_error_dst_unr_send(ICMPV6_ERROR_DST_UNR_PROHIB, pkt); gnrc_pktbuf_release(pkt); return; } @@ -749,6 +751,7 @@ static void _receive(gnrc_pktsnip_t *pkt) #ifdef MODULE_GNRC_IPV6_BLACKLIST if (gnrc_ipv6_blacklisted(&((ipv6_hdr_t *)(pkt->data))->src)) { DEBUG("ipv6: Source address blacklisted, dropping packet\n"); + gnrc_icmpv6_error_dst_unr_send(ICMPV6_ERROR_DST_UNR_PROHIB, pkt); gnrc_pktbuf_release(pkt); return; } @@ -779,6 +782,7 @@ static void _receive(gnrc_pktsnip_t *pkt) else if (!gnrc_ipv6_whitelisted(&((ipv6_hdr_t *)(ipv6->data))->src)) { /* if ipv6 header already marked*/ DEBUG("ipv6: Source address not whitelisted, dropping packet\n"); + gnrc_icmpv6_error_dst_unr_send(ICMPV6_ERROR_DST_UNR_PROHIB, pkt); gnrc_pktbuf_release(pkt); return; } @@ -787,6 +791,7 @@ static void _receive(gnrc_pktsnip_t *pkt) else if (gnrc_ipv6_blacklisted(&((ipv6_hdr_t *)(ipv6->data))->src)) { /* if ipv6 header already marked*/ DEBUG("ipv6: Source address blacklisted, dropping packet\n"); + gnrc_icmpv6_error_dst_unr_send(ICMPV6_ERROR_DST_UNR_PROHIB, pkt); gnrc_pktbuf_release(pkt); return; } @@ -812,7 +817,9 @@ static void _receive(gnrc_pktsnip_t *pkt) DEBUG("ipv6: invalid payload length: %d, actual: %d, dropping packet\n", (int) byteorder_ntohs(hdr->len), (int) (gnrc_pkt_len_upto(pkt, GNRC_NETTYPE_IPV6) - sizeof(ipv6_hdr_t))); - gnrc_pktbuf_release(pkt); + gnrc_icmpv6_error_param_prob_send(ICMPV6_ERROR_PARAM_PROB_HDR_FIELD, + &(hdr->len), pkt); + gnrc_pktbuf_release_error(pkt, EINVAL); return; } @@ -836,6 +843,15 @@ static void _receive(gnrc_pktsnip_t *pkt) if ((ipv6_addr_is_link_local(&(hdr->src))) || (ipv6_addr_is_link_local(&(hdr->dst)))) { DEBUG("ipv6: do not forward packets with link-local source or" " destination address\n"); +#ifdef MODULE_GNRC_ICMPV6_ERROR + if (ipv6_addr_is_link_local(&(hdr->src)) && + !ipv6_addr_is_link_local(&(hdr->dst))) { + gnrc_icmpv6_error_dst_unr_send(ICMPV6_ERROR_DST_UNR_SCOPE, pkt); + } + else if (!ipv6_addr_is_multicast(&(hdr->dst))) { + gnrc_icmpv6_error_dst_unr_send(ICMPV6_ERROR_DST_UNR_ADDR, pkt); + } +#endif gnrc_pktbuf_release(pkt); return; } @@ -868,7 +884,8 @@ static void _receive(gnrc_pktsnip_t *pkt) } else { DEBUG("ipv6: hop limit reached 0: drop packet\n"); - gnrc_pktbuf_release(pkt); + gnrc_icmpv6_error_time_exc_send(ICMPV6_ERROR_TIME_EXC_HL, pkt); + gnrc_pktbuf_release_error(pkt, ETIMEDOUT); return; } diff --git a/sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.c b/sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.c index 65d3a32c33..4c33f9d536 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.c +++ b/sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.c @@ -17,6 +17,7 @@ #include <stdbool.h> #include <string.h> +#include "net/gnrc/icmpv6/error.h" #include "net/gnrc/ipv6.h" #include "net/gnrc/ipv6/nib/conf.h" #include "net/gnrc/ipv6/nib/nc.h" @@ -265,6 +266,8 @@ void _nib_nc_remove(_nib_onl_entry_t *node) (ptr != NULL) && (tmp = (ptr->next), 1); ptr = tmp) { gnrc_pktqueue_t *entry = gnrc_pktqueue_remove(&node->pktqueue, ptr); + gnrc_icmpv6_error_dst_unr_send(ICMPV6_ERROR_DST_UNR_ADDR, + entry->pkt); gnrc_pktbuf_release_error(entry->pkt, EHOSTUNREACH); entry->pkt = NULL; } diff --git a/sys/net/gnrc/network_layer/ipv6/nib/nib.c b/sys/net/gnrc/network_layer/ipv6/nib/nib.c index 81eb765d4f..17bb9b91ae 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/nib.c +++ b/sys/net/gnrc/network_layer/ipv6/nib/nib.c @@ -18,6 +18,7 @@ #include "log.h" #include "net/ipv6/addr.h" +#include "net/gnrc/icmpv6/error.h" #include "net/gnrc/nettype.h" #include "net/gnrc/netif/internal.h" #include "net/gnrc/ipv6/nib.h" @@ -203,6 +204,8 @@ int gnrc_ipv6_nib_get_next_hop_l2addr(const ipv6_addr_t *dst, * we also shouldn't release), but if netif is not defined we * should release in any case. */ if (netif == NULL) { + gnrc_icmpv6_error_dst_unr_send(ICMPV6_ERROR_DST_UNR_ADDR, + pkt); gnrc_pktbuf_release_error(pkt, EHOSTUNREACH); } res = -EHOSTUNREACH; @@ -225,6 +228,8 @@ int gnrc_ipv6_nib_get_next_hop_l2addr(const ipv6_addr_t *dst, memcpy(&route.next_hop, dst, sizeof(route.next_hop)); } else { + gnrc_icmpv6_error_dst_unr_send(ICMPV6_ERROR_DST_UNR_NO_ROUTE, + pkt); res = -ENETUNREACH; gnrc_pktbuf_release_error(pkt, ENETUNREACH); break; @@ -1168,9 +1173,13 @@ static bool _resolve_addr(const ipv6_addr_t *dst, gnrc_netif_t *netif, } } else { + gnrc_icmpv6_error_dst_unr_send(ICMPV6_ERROR_DST_UNR_ADDR, + pkt); gnrc_pktbuf_release_error(pkt, EHOSTUNREACH); } #else /* GNRC_IPV6_NIB_CONF_QUEUE_PKT */ + gnrc_icmpv6_error_dst_unr_send(ICMPV6_ERROR_DST_UNR_ADDR, + pkt); gnrc_pktbuf_release_error(pkt, EHOSTUNREACH); #endif /* GNRC_IPV6_NIB_CONF_QUEUE_PKT */ } -- GitLab