1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

gnrc_icmpv6_error: consider originator's destination address correctly

While 485dbd1fda (from #12175) was right
in assuming that the for most ICMPv6 error messages the originating
packet's destination address must not be a multicast, this is not the
case for _all_ ICMPv6 error messages (see [RFC 4443], section 2.4(e.3)).
Additionally, 485dbd1fda removed the
check for the source address ([RFC 4443], section 2.4(e.6)), which this
PR re-adds.

[RFC 4443]: https://tools.ietf.org/html/rfc4443#section-2.4
This commit is contained in:
Martine Lenders 2019-10-14 11:22:43 +02:00
parent 9bc600a2e5
commit c32f1076f6

View File

@ -234,7 +234,8 @@ 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)
static gnrc_pktsnip_t *_check_ipv6_hdr(const gnrc_pktsnip_t *orig_pkt,
uint8_t type, uint8_t code)
{
/* discarding const qualifier is safe here */
gnrc_pktsnip_t *ipv6 = gnrc_pktsnip_search_type((gnrc_pktsnip_t *)orig_pkt,
@ -242,16 +243,27 @@ static gnrc_pktsnip_t *_check_ipv6_hdr(const gnrc_pktsnip_t *orig_pkt)
assert(ipv6 != NULL);
const ipv6_hdr_t *ipv6_hdr = ipv6->data;
/* see https://tools.ietf.org/html/rfc4443#section-2.4 (e.6) */
if (ipv6_addr_is_unspecified(&ipv6_hdr->src) ||
ipv6_addr_is_multicast(&ipv6_hdr->dst)) {
ipv6_addr_is_multicast(&ipv6_hdr->src)) {
ipv6 = NULL;
}
/* ipv6_hdr->dst may only be multicast for Packet Too Big Messages
* and Parameter Problem Messages with code 2, see
* https://tools.ietf.org/html/rfc4443#section-2.4 (e.3) */
else if (ipv6_addr_is_multicast(&ipv6_hdr->dst)) {
if ((type != ICMPV6_PKT_TOO_BIG) &&
((type != ICMPV6_PARAM_PROB) ||
(code != ICMPV6_ERROR_PARAM_PROB_OPT))) {
ipv6 = NULL;
}
}
return ipv6;
}
void gnrc_icmpv6_error_dst_unr_send(uint8_t code, const gnrc_pktsnip_t *orig_pkt)
{
gnrc_pktsnip_t *ipv6 = _check_ipv6_hdr(orig_pkt);
gnrc_pktsnip_t *ipv6 = _check_ipv6_hdr(orig_pkt, ICMPV6_DST_UNR, code);
if (ipv6 != NULL) {
gnrc_pktsnip_t *pkt = _dst_unr_build(code, orig_pkt);
@ -264,7 +276,7 @@ void gnrc_icmpv6_error_dst_unr_send(uint8_t code, const gnrc_pktsnip_t *orig_pkt
void gnrc_icmpv6_error_pkt_too_big_send(uint32_t mtu,
const gnrc_pktsnip_t *orig_pkt)
{
gnrc_pktsnip_t *ipv6 = _check_ipv6_hdr(orig_pkt);
gnrc_pktsnip_t *ipv6 = _check_ipv6_hdr(orig_pkt, ICMPV6_PKT_TOO_BIG, 0);
if (ipv6 != NULL) {
gnrc_pktsnip_t *pkt = _pkt_too_big_build(mtu, orig_pkt);
@ -277,7 +289,7 @@ void gnrc_icmpv6_error_pkt_too_big_send(uint32_t mtu,
void gnrc_icmpv6_error_time_exc_send(uint8_t code,
const gnrc_pktsnip_t *orig_pkt)
{
gnrc_pktsnip_t *ipv6 = _check_ipv6_hdr(orig_pkt);
gnrc_pktsnip_t *ipv6 = _check_ipv6_hdr(orig_pkt, ICMPV6_TIME_EXC, code);
if (ipv6 != NULL) {
gnrc_pktsnip_t *pkt = _time_exc_build(code, orig_pkt);
@ -290,7 +302,7 @@ void gnrc_icmpv6_error_time_exc_send(uint8_t code,
void gnrc_icmpv6_error_param_prob_send(uint8_t code, void *ptr,
const gnrc_pktsnip_t *orig_pkt)
{
gnrc_pktsnip_t *ipv6 = _check_ipv6_hdr(orig_pkt);
gnrc_pktsnip_t *ipv6 = _check_ipv6_hdr(orig_pkt, ICMPV6_PARAM_PROB, code);
if (ipv6 != NULL) {
gnrc_pktsnip_t *pkt = _param_prob_build(code, ptr, orig_pkt);