From b96e6b508ab22c027f0ed99adbc60f92f893caee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cenk=20G=C3=BCndo=C4=9Fan?= Date: Wed, 19 Aug 2015 19:29:17 +0200 Subject: [PATCH] rpl: dao-ack validity check --- sys/include/net/gnrc/rpl.h | 3 ++- sys/net/gnrc/routing/rpl/gnrc_rpl.c | 3 ++- .../routing/rpl/gnrc_rpl_control_messages.c | 24 ++++++++++++++++++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/sys/include/net/gnrc/rpl.h b/sys/include/net/gnrc/rpl.h index 150230cc7f..1c77f384cd 100644 --- a/sys/include/net/gnrc/rpl.h +++ b/sys/include/net/gnrc/rpl.h @@ -419,8 +419,9 @@ void gnrc_rpl_recv_DAO(gnrc_rpl_dao_t *dao, ipv6_addr_t *src, uint16_t len); * @brief Parse a DAO-ACK. * * @param[in] dao_ack Pointer to the DAO-ACK message. + * @param[in] len Length of the IPv6 packet. */ -void gnrc_rpl_recv_DAO_ACK(gnrc_rpl_dao_ack_t *dao_ack); +void gnrc_rpl_recv_DAO_ACK(gnrc_rpl_dao_ack_t *dao_ack, uint16_t len); /** * @brief Delay the DAO sending interval diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl.c b/sys/net/gnrc/routing/rpl/gnrc_rpl.c index 50956015e9..b0e979da8c 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl.c @@ -133,7 +133,8 @@ static void _receive(gnrc_pktsnip_t *icmpv6) break; case GNRC_RPL_ICMPV6_CODE_DAO_ACK: DEBUG("RPL: DAO-ACK received\n"); - gnrc_rpl_recv_DAO_ACK((gnrc_rpl_dao_ack_t *)(icmpv6_hdr + 1)); + gnrc_rpl_recv_DAO_ACK((gnrc_rpl_dao_ack_t *)(icmpv6_hdr + 1), + byteorder_ntohs(ipv6_hdr->len)); break; default: DEBUG("RPL: Unknown ICMPV6 code received\n"); diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c index 7d73e2c784..e00e8f2b66 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c @@ -707,10 +707,32 @@ void gnrc_rpl_recv_DAO(gnrc_rpl_dao_t *dao, ipv6_addr_t *src, uint16_t len) gnrc_rpl_delay_dao(dodag); } -void gnrc_rpl_recv_DAO_ACK(gnrc_rpl_dao_ack_t *dao_ack) +static bool _gnrc_rpl_check_DAO_ACK_validity(gnrc_rpl_dao_ack_t *dao_ack, uint16_t len) +{ + uint16_t expected_len = sizeof(*dao_ack) + sizeof(icmpv6_hdr_t); + + if ((dao_ack->d_reserved & GNRC_RPL_DAO_ACK_D_BIT)) { + expected_len += sizeof(ipv6_addr_t); + } + + if (expected_len == len) { + return true; + } + + DEBUG("RPL: wrong DAO-ACK len: %d, expected: %d\n", len, expected_len); + + return false; +} + +void gnrc_rpl_recv_DAO_ACK(gnrc_rpl_dao_ack_t *dao_ack, uint16_t len) { gnrc_rpl_instance_t *inst = NULL; gnrc_rpl_dodag_t *dodag = NULL; + + if (!_gnrc_rpl_check_DAO_ACK_validity(dao_ack, len)) { + return; + } + if ((inst = gnrc_rpl_instance_get(dao_ack->instance_id)) == NULL) { DEBUG("RPL: DAO-ACK with unknown instance id (%d) received\n", dao_ack->instance_id); return;