1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-23 21:43:51 +01:00

Merge pull request #10421 from miri64/gnrc_icmpv6_error/bug/dont-send-to-unspec

gnrc_icmpv6_error / gnrc_ipv6: fixes for unspecified address
This commit is contained in:
Koen Zandberg 2018-11-17 16:06:03 +01:00 committed by GitHub
commit c755071483
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 20 deletions

View File

@ -37,7 +37,10 @@ extern "C" {
/**
* @brief Sends an ICMPv6 destination unreachable message for sending.
*
* @pre @p orig_pkt contains a packet snip of type @ref GNRC_NETTYPE_IPV6
* @pre @p orig_pkt contains a packet snip of type @ref GNRC_NETTYPE_IPV6
*
* @note Won't send if source address of @p orig_pkt is unspecified or
* multicast
*
* @param[in] code The [code for the message](@ref net_icmpv6_error_dst_unr_codes).
* @param[in] orig_pkt The invoking packet.
@ -47,7 +50,10 @@ void gnrc_icmpv6_error_dst_unr_send(uint8_t code, const gnrc_pktsnip_t *orig_pkt
/**
* @brief Sends an ICMPv6 packet too big message for sending.
*
* @pre @p orig_pkt contains a packet snip of type @ref GNRC_NETTYPE_IPV6
* @pre @p orig_pkt contains a packet snip of type @ref GNRC_NETTYPE_IPV6
*
* @note Won't send if source address of @p orig_pkt is unspecified or
* multicast
*
* @param[in] mtu The maximum transission unit of the next-hop link.
* @param[in] orig_pkt The invoking packet.
@ -58,7 +64,10 @@ void gnrc_icmpv6_error_pkt_too_big_send(uint32_t mtu,
/**
* @brief Sends an ICMPv6 time exceeded message for sending.
*
* @pre @p orig_pkt contains a packet snip of type @ref GNRC_NETTYPE_IPV6
* @pre @p orig_pkt contains a packet snip of type @ref GNRC_NETTYPE_IPV6
*
* @note Won't send if source address of @p orig_pkt is unspecified or
* multicast
*
* @param[in] code The [code for the message](@ref net_icmpv6_error_time_exc_codes).
* @param[in] orig_pkt The invoking packet.
@ -69,9 +78,11 @@ void gnrc_icmpv6_error_time_exc_send(uint8_t code,
/**
* @brief Sends an ICMPv6 parameter problem message for sending.
*
* @pre @p orig_pkt is in receive order.
* @pre @p orig_pkt contains a packet snip of type @ref GNRC_NETTYPE_IPV6
* @pre @p orig_pkt is in receive order.
* @pre @p orig_pkt contains a packet snip of type @ref GNRC_NETTYPE_IPV6
*
* @note Won't send if source address of @p orig_pkt is unspecified or
* multicast
*
* @param[in] code The [code for the message](@ref net_icmpv6_error_param_prob_codes).
* @param[in] ptr Pointer to the errorneous octet in @p orig_pkt.

View File

@ -192,16 +192,16 @@ static gnrc_pktsnip_t *_param_prob_build(uint8_t code, void *ptr,
return pkt;
}
static void _send(gnrc_pktsnip_t *pkt, const gnrc_pktsnip_t *orig_pkt)
static void _send(gnrc_pktsnip_t *pkt, const gnrc_pktsnip_t *orig_pkt,
gnrc_pktsnip_t *ipv6)
{
if (pkt != NULL) {
/* discarding const qualifier is safe here */
gnrc_pktsnip_t *ipv6 = gnrc_pktsnip_search_type((gnrc_pktsnip_t *)orig_pkt,
GNRC_NETTYPE_IPV6);
gnrc_pktsnip_t *netif = gnrc_pktsnip_search_type((gnrc_pktsnip_t *)orig_pkt,
GNRC_NETTYPE_NETIF);
assert(ipv6 != NULL);
ipv6_hdr_t *ipv6_hdr = ipv6->data;
/* overwrite ipv6 parameter pointer ... we don't need it after this */
ipv6 = gnrc_ipv6_hdr_build(pkt, NULL, &ipv6_hdr->src);
if (ipv6 == NULL) {
DEBUG("gnrc_icmpv6_error: No space in packet buffer left\n");
@ -237,39 +237,70 @@ static void _send(gnrc_pktsnip_t *pkt, const gnrc_pktsnip_t *orig_pkt)
}
}
static gnrc_pktsnip_t *_check_ipv6_hdr(const gnrc_pktsnip_t *orig_pkt)
{
/* discarding const qualifier is safe here */
gnrc_pktsnip_t *ipv6 = gnrc_pktsnip_search_type((gnrc_pktsnip_t *)orig_pkt,
GNRC_NETTYPE_IPV6);
assert(ipv6 != NULL);
const ipv6_hdr_t *ipv6_hdr = ipv6->data;
if (ipv6_addr_is_unspecified(&ipv6_hdr->src) ||
ipv6_addr_is_multicast(&ipv6_hdr->src)) {
ipv6 = NULL;
}
return ipv6;
}
void gnrc_icmpv6_error_dst_unr_send(uint8_t code, const gnrc_pktsnip_t *orig_pkt)
{
gnrc_pktsnip_t *pkt = _dst_unr_build(code, orig_pkt);
gnrc_pktsnip_t *ipv6 = _check_ipv6_hdr(orig_pkt);
DEBUG("gnrc_icmpv6_error: trying to send destination unreachable error\n");
_send(pkt, orig_pkt);
if (ipv6 != NULL) {
gnrc_pktsnip_t *pkt = _dst_unr_build(code, orig_pkt);
DEBUG("gnrc_icmpv6_error: trying to send destination unreachable error\n");
_send(pkt, orig_pkt, ipv6);
}
}
void gnrc_icmpv6_error_pkt_too_big_send(uint32_t mtu,
const gnrc_pktsnip_t *orig_pkt)
{
gnrc_pktsnip_t *pkt = _pkt_too_big_build(mtu, orig_pkt);
gnrc_pktsnip_t *ipv6 = _check_ipv6_hdr(orig_pkt);
DEBUG("gnrc_icmpv6_error: trying to send packet too big error\n");
_send(pkt, orig_pkt);
if (ipv6 != NULL) {
gnrc_pktsnip_t *pkt = _pkt_too_big_build(mtu, orig_pkt);
DEBUG("gnrc_icmpv6_error: trying to send packet too big error\n");
_send(pkt, orig_pkt, ipv6);
}
}
void gnrc_icmpv6_error_time_exc_send(uint8_t code,
const gnrc_pktsnip_t *orig_pkt)
{
gnrc_pktsnip_t *pkt = _time_exc_build(code, orig_pkt);
gnrc_pktsnip_t *ipv6 = _check_ipv6_hdr(orig_pkt);
DEBUG("gnrc_icmpv6_error: trying to send time exceeded error\n");
_send(pkt, orig_pkt);
if (ipv6 != NULL) {
gnrc_pktsnip_t *pkt = _time_exc_build(code, orig_pkt);
DEBUG("gnrc_icmpv6_error: trying to send time exceeded error\n");
_send(pkt, orig_pkt, ipv6);
}
}
void gnrc_icmpv6_error_param_prob_send(uint8_t code, void *ptr,
const gnrc_pktsnip_t *orig_pkt)
{
gnrc_pktsnip_t *pkt = _param_prob_build(code, ptr, orig_pkt);
gnrc_pktsnip_t *ipv6 = _check_ipv6_hdr(orig_pkt);
DEBUG("gnrc_icmpv6_error: trying to send parameter problem error\n");
_send(pkt, orig_pkt);
if (ipv6 != NULL) {
gnrc_pktsnip_t *pkt = _param_prob_build(code, ptr, orig_pkt);
DEBUG("gnrc_icmpv6_error: trying to send parameter problem error\n");
_send(pkt, orig_pkt, ipv6);
}
}
/** @} */

View File

@ -665,6 +665,12 @@ static void _send(gnrc_pktsnip_t *pkt, bool prep_hdr)
gnrc_pktbuf_release_error(pkt, EINVAL);
return;
}
if (ipv6_addr_is_unspecified(&((ipv6_hdr_t *)pkt->data)->dst)) {
DEBUG("ipv6: destination address is unspecified address (::), "
"dropping packet \n");
gnrc_pktbuf_release_error(pkt, EINVAL);
return;
}
tmp_pkt = gnrc_pktbuf_start_write(pkt);
if (tmp_pkt == NULL) {
DEBUG("ipv6: unable to get write access to IPv6 header, dropping packet\n");