Merge pull request #5300 from cgundogan/pr/gnrc_rpl/without_validation
gnrc_rpl: validation configurable on compile-time
This commit is contained in:
commit
4a70299d6a
@ -72,6 +72,12 @@
|
||||
* interface exists (`GNRC_NETIF_NUMOF > 1`)
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
|
||||
* CFLAGS += -DGNRC_RPL_DEFAULT_NETIF=6
|
||||
*
|
||||
* - By default, all incoming control messages get checked for validation.
|
||||
* This validation can be disabled in case the involved RPL implementations
|
||||
* are known to produce valid messages.
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
|
||||
* CFLAGS += -DGNRC_RPL_WITHOUT_VALIDATION
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* @{
|
||||
|
||||
@ -32,6 +32,31 @@ extern "C" {
|
||||
#include "xtimer.h"
|
||||
#include "trickle.h"
|
||||
|
||||
/**
|
||||
* @name Option lengths
|
||||
* @{
|
||||
*/
|
||||
#define GNRC_RPL_OPT_DODAG_CONF_LEN (14)
|
||||
#define GNRC_RPL_OPT_PREFIX_INFO_LEN (30)
|
||||
#define GNRC_RPL_OPT_TARGET_LEN (18)
|
||||
#define GNRC_RPL_OPT_TRANSIT_INFO_LEN (4)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name DAO flag macros
|
||||
* @{
|
||||
*/
|
||||
#define GNRC_RPL_DAO_D_BIT (1 << 6)
|
||||
#define GNRC_RPL_DAO_K_BIT (1 << 7)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name DAO-ACK flag macros
|
||||
* @{
|
||||
*/
|
||||
#define GNRC_RPL_DAO_ACK_D_BIT (1 << 7)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @anchor GNRC_RPL_REQ_DIO_OPTS
|
||||
* @name DIO Options for gnrc_rpl_dodag_t::dio_opts
|
||||
|
||||
@ -24,6 +24,9 @@
|
||||
#include "net/eui64.h"
|
||||
|
||||
#include "net/gnrc/rpl.h"
|
||||
#ifndef GNRC_RPL_WITHOUT_VALIDATION
|
||||
#include "gnrc_rpl_internal/validation.h"
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_GNRC_RPL_P2P
|
||||
#include "net/gnrc/rpl/p2p_structs.h"
|
||||
@ -40,18 +43,11 @@ static char addr_str[IPV6_ADDR_MAX_STR_LEN];
|
||||
|
||||
#define GNRC_RPL_GROUNDED_SHIFT (7)
|
||||
#define GNRC_RPL_MOP_SHIFT (3)
|
||||
#define GNRC_RPL_OPT_DODAG_CONF_LEN (14)
|
||||
#define GNRC_RPL_OPT_PREFIX_INFO_LEN (30)
|
||||
#define GNRC_RPL_OPT_TARGET_LEN (18)
|
||||
#define GNRC_RPL_OPT_TRANSIT_E_FLAG_SHIFT (7)
|
||||
#define GNRC_RPL_OPT_TRANSIT_E_FLAG (1 << GNRC_RPL_OPT_TRANSIT_E_FLAG_SHIFT)
|
||||
#define GNRC_RPL_OPT_TRANSIT_INFO_LEN (4)
|
||||
#define GNRC_RPL_SHIFTED_MOP_MASK (0x7)
|
||||
#define GNRC_RPL_PRF_MASK (0x7)
|
||||
#define GNRC_RPL_PREFIX_AUTO_ADDRESS_BIT (1 << 6)
|
||||
#define GNRC_RPL_DAO_D_BIT (1 << 6)
|
||||
#define GNRC_RPL_DAO_K_BIT (1 << 7)
|
||||
#define GNRC_RPL_DAO_ACK_D_BIT (1 << 7)
|
||||
|
||||
void gnrc_rpl_send(gnrc_pktsnip_t *pkt, kernel_pid_t iface, ipv6_addr_t *src, ipv6_addr_t *dst,
|
||||
ipv6_addr_t *dodag_id)
|
||||
@ -253,28 +249,20 @@ void gnrc_rpl_send_DIS(gnrc_rpl_instance_t *inst, ipv6_addr_t *destination)
|
||||
gnrc_rpl_send(pkt, KERNEL_PID_UNDEF, NULL, destination, (inst? &(inst->dodag.dodag_id) : NULL));
|
||||
}
|
||||
|
||||
static bool _gnrc_rpl_check_DIS_validity(gnrc_rpl_dis_t *dis, uint16_t len)
|
||||
{
|
||||
uint16_t expected_len = sizeof(*dis) + sizeof(icmpv6_hdr_t);
|
||||
|
||||
if (expected_len <= len) {
|
||||
return true;
|
||||
}
|
||||
|
||||
DEBUG("RPL: wrong DIS len: %d, expected: %d\n", len, expected_len);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void gnrc_rpl_recv_DIS(gnrc_rpl_dis_t *dis, kernel_pid_t iface, ipv6_addr_t *src,
|
||||
ipv6_addr_t *dst, uint16_t len)
|
||||
{
|
||||
/* TODO handle Solicited Information Option */
|
||||
(void)iface;
|
||||
|
||||
if (!_gnrc_rpl_check_DIS_validity(dis, len)) {
|
||||
#ifndef GNRC_RPL_WITHOUT_VALIDATION
|
||||
if (!gnrc_rpl_validation_DIS(dis, len)) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
(void) dis;
|
||||
(void) len;
|
||||
#endif
|
||||
|
||||
if (ipv6_addr_is_multicast(dst)) {
|
||||
for (uint8_t i = 0; i < GNRC_RPL_INSTANCES_NUMOF; ++i) {
|
||||
@ -301,92 +289,6 @@ void gnrc_rpl_recv_DIS(gnrc_rpl_dis_t *dis, kernel_pid_t iface, ipv6_addr_t *src
|
||||
}
|
||||
}
|
||||
|
||||
static bool _gnrc_rpl_check_options_validity(int msg_type, gnrc_rpl_instance_t *inst,
|
||||
gnrc_rpl_opt_t *opt, uint16_t len)
|
||||
{
|
||||
uint16_t expected_len = 0;
|
||||
|
||||
while(expected_len < len) {
|
||||
switch(opt->type) {
|
||||
case (GNRC_RPL_OPT_PAD1):
|
||||
expected_len += 1;
|
||||
opt = (gnrc_rpl_opt_t *) (((uint8_t *) opt) + 1);
|
||||
continue;
|
||||
|
||||
case (GNRC_RPL_OPT_DODAG_CONF):
|
||||
if (msg_type != GNRC_RPL_ICMPV6_CODE_DIO) {
|
||||
DEBUG("RPL: DODAG CONF DIO option not expected\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (opt->length != GNRC_RPL_OPT_DODAG_CONF_LEN) {
|
||||
DEBUG("RPL: wrong DIO option (DODAG CONF) len: %d, expected: %d\n",
|
||||
opt->length, GNRC_RPL_OPT_DODAG_CONF_LEN);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case (GNRC_RPL_OPT_PREFIX_INFO):
|
||||
if (msg_type != GNRC_RPL_ICMPV6_CODE_DIO) {
|
||||
DEBUG("RPL: PREFIX INFO DIO option not expected\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (opt->length != GNRC_RPL_OPT_PREFIX_INFO_LEN) {
|
||||
DEBUG("RPL: wrong DIO option (PREFIX INFO) len: %d, expected: %d\n",
|
||||
opt->length, GNRC_RPL_OPT_PREFIX_INFO_LEN);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case (GNRC_RPL_OPT_TARGET):
|
||||
if (msg_type != GNRC_RPL_ICMPV6_CODE_DAO) {
|
||||
DEBUG("RPL: RPL TARGET DAO option not expected\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (opt->length > GNRC_RPL_OPT_TARGET_LEN) {
|
||||
DEBUG("RPL: wrong DAO option (RPL TARGET) len: %d, expected (max): %d\n",
|
||||
opt->length, GNRC_RPL_OPT_TARGET_LEN);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case (GNRC_RPL_OPT_TRANSIT):
|
||||
if (msg_type != GNRC_RPL_ICMPV6_CODE_DAO) {
|
||||
DEBUG("RPL: RPL TRANSIT INFO DAO option not expected\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t parent_addr = 0;
|
||||
if (inst->mop == GNRC_RPL_MOP_NON_STORING_MODE) {
|
||||
parent_addr = sizeof(ipv6_addr_t);
|
||||
}
|
||||
|
||||
if (opt->length != (GNRC_RPL_OPT_TRANSIT_INFO_LEN + parent_addr)) {
|
||||
DEBUG("RPL: wrong DAO option (TRANSIT INFO) len: %d, expected: %d\n",
|
||||
opt->length, (GNRC_RPL_OPT_TRANSIT_INFO_LEN + parent_addr));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
expected_len += opt->length + sizeof(gnrc_rpl_opt_t);
|
||||
opt = (gnrc_rpl_opt_t *) (((uint8_t *) (opt + 1)) + opt->length);
|
||||
}
|
||||
|
||||
if (expected_len == len) {
|
||||
return true;
|
||||
}
|
||||
|
||||
DEBUG("RPL: wrong options len: %d, expected: %d\n", len, expected_len);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @todo allow target prefixes in target options to be of variable length */
|
||||
bool _parse_options(int msg_type, gnrc_rpl_instance_t *inst, gnrc_rpl_opt_t *opt, uint16_t len,
|
||||
ipv6_addr_t *src, uint32_t *included_opts)
|
||||
@ -398,9 +300,13 @@ bool _parse_options(int msg_type, gnrc_rpl_instance_t *inst, gnrc_rpl_opt_t *opt
|
||||
*included_opts = 0;
|
||||
ipv6_addr_t *me;
|
||||
|
||||
if (!_gnrc_rpl_check_options_validity(msg_type, inst, opt, len)) {
|
||||
#ifndef GNRC_RPL_WITHOUT_VALIDATION
|
||||
if (!gnrc_rpl_validation_options(msg_type, inst, opt, len)) {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
(void) msg_type;
|
||||
#endif
|
||||
|
||||
while(l < len) {
|
||||
switch(opt->type) {
|
||||
@ -531,27 +437,16 @@ bool _parse_options(int msg_type, gnrc_rpl_instance_t *inst, gnrc_rpl_opt_t *opt
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _gnrc_rpl_check_DIO_validity(gnrc_rpl_dio_t *dio, uint16_t len)
|
||||
{
|
||||
uint16_t expected_len = sizeof(*dio) + sizeof(icmpv6_hdr_t);
|
||||
|
||||
if (expected_len <= len) {
|
||||
return true;
|
||||
}
|
||||
|
||||
DEBUG("RPL: wrong DIO len: %d, expected: %d\n", len, expected_len);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void gnrc_rpl_recv_DIO(gnrc_rpl_dio_t *dio, kernel_pid_t iface, ipv6_addr_t *src, uint16_t len)
|
||||
{
|
||||
gnrc_rpl_instance_t *inst = NULL;
|
||||
gnrc_rpl_dodag_t *dodag = NULL;
|
||||
|
||||
if (!_gnrc_rpl_check_DIO_validity(dio, len)) {
|
||||
#ifndef GNRC_RPL_WITHOUT_VALIDATION
|
||||
if (!gnrc_rpl_validation_DIO(dio, len)) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
len -= (sizeof(gnrc_rpl_dio_t) + sizeof(icmpv6_hdr_t));
|
||||
|
||||
@ -977,23 +872,6 @@ void gnrc_rpl_send_DAO_ACK(gnrc_rpl_instance_t *inst, ipv6_addr_t *destination,
|
||||
gnrc_rpl_send(pkt, dodag->iface, NULL, destination, &dodag->dodag_id);
|
||||
}
|
||||
|
||||
static bool _gnrc_rpl_check_DAO_validity(gnrc_rpl_dao_t *dao, uint16_t len)
|
||||
{
|
||||
uint16_t expected_len = sizeof(*dao) + sizeof(icmpv6_hdr_t);
|
||||
|
||||
if ((dao->k_d_flags & GNRC_RPL_DAO_D_BIT)) {
|
||||
expected_len += sizeof(ipv6_addr_t);
|
||||
}
|
||||
|
||||
if (expected_len <= len) {
|
||||
return true;
|
||||
}
|
||||
|
||||
DEBUG("RPL: wrong DAO len: %d, expected: %d\n", len, expected_len);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void gnrc_rpl_recv_DAO(gnrc_rpl_dao_t *dao, kernel_pid_t iface, ipv6_addr_t *src, uint16_t len)
|
||||
{
|
||||
(void)iface;
|
||||
@ -1001,9 +879,11 @@ void gnrc_rpl_recv_DAO(gnrc_rpl_dao_t *dao, kernel_pid_t iface, ipv6_addr_t *src
|
||||
gnrc_rpl_instance_t *inst = NULL;
|
||||
gnrc_rpl_dodag_t *dodag = NULL;
|
||||
|
||||
if (!_gnrc_rpl_check_DAO_validity(dao, len)) {
|
||||
#ifndef GNRC_RPL_WITHOUT_VALIDATION
|
||||
if (!gnrc_rpl_validation_DAO(dao, len)) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
gnrc_rpl_opt_t *opts = (gnrc_rpl_opt_t *) (dao + 1);
|
||||
|
||||
@ -1052,23 +932,6 @@ void gnrc_rpl_recv_DAO(gnrc_rpl_dao_t *dao, kernel_pid_t iface, ipv6_addr_t *src
|
||||
gnrc_rpl_delay_dao(dodag);
|
||||
}
|
||||
|
||||
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, kernel_pid_t iface, uint16_t len)
|
||||
{
|
||||
(void)iface;
|
||||
@ -1076,9 +939,13 @@ void gnrc_rpl_recv_DAO_ACK(gnrc_rpl_dao_ack_t *dao_ack, kernel_pid_t iface, uint
|
||||
gnrc_rpl_instance_t *inst = NULL;
|
||||
gnrc_rpl_dodag_t *dodag = NULL;
|
||||
|
||||
if (!_gnrc_rpl_check_DAO_ACK_validity(dao_ack, len)) {
|
||||
#ifndef GNRC_RPL_WITHOUT_VALIDATION
|
||||
if (!gnrc_rpl_validation_DAO_ACK(dao_ack, len)) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
(void) len;
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
147
sys/net/gnrc/routing/rpl/gnrc_rpl_internal/validation.h
Normal file
147
sys/net/gnrc/routing/rpl/gnrc_rpl_internal/validation.h
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Cenk Gündoğan <mail@cgundogan.de>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup net_gnrc_rpl
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief RPL control message validation functions
|
||||
*
|
||||
* @author Cenk Gündoğan <mail@cgundogan.de>
|
||||
*/
|
||||
|
||||
#ifndef GNRC_RPL_VALIDATION_H_
|
||||
#define GNRC_RPL_VALIDATION_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "net/gnrc/rpl/structs.h"
|
||||
#include "net/gnrc/icmpv6.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
/**
|
||||
* @brief Checks validity of DIS control messages
|
||||
*
|
||||
* @param[in] dis The DIS control message
|
||||
* @param[in] len Length of the DIS control message
|
||||
*
|
||||
* @return true, if @p dis is valid
|
||||
* @return false, otherwise
|
||||
*/
|
||||
static inline bool gnrc_rpl_validation_DIS(gnrc_rpl_dis_t *dis, uint16_t len)
|
||||
{
|
||||
uint16_t expected_len = sizeof(*dis) + sizeof(icmpv6_hdr_t);
|
||||
|
||||
if (expected_len <= len) {
|
||||
return true;
|
||||
}
|
||||
|
||||
DEBUG("RPL: wrong DIS len: %d, expected: %d\n", len, expected_len);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks validity of control message options
|
||||
*
|
||||
* @param[in] msg_type Type of the control message
|
||||
* @param[in] inst The RPL instance
|
||||
* @param[in] opt Options of the control message
|
||||
* @param[in] len Length of the options
|
||||
*
|
||||
* @return true, if @p opt is valid
|
||||
* @return false, otherwise
|
||||
*/
|
||||
bool gnrc_rpl_validation_options(int msg_type, gnrc_rpl_instance_t *inst,
|
||||
gnrc_rpl_opt_t *opt, uint16_t len);
|
||||
|
||||
/**
|
||||
* @brief Checks validity of DIO control messages
|
||||
*
|
||||
* @param[in] dio The DIO control message
|
||||
* @param[in] len Length of the DIO control message
|
||||
*
|
||||
* @return true, if @p dio is valid
|
||||
* @return false, otherwise
|
||||
*/
|
||||
static inline bool gnrc_rpl_validation_DIO(gnrc_rpl_dio_t *dio, uint16_t len)
|
||||
{
|
||||
uint16_t expected_len = sizeof(*dio) + sizeof(icmpv6_hdr_t);
|
||||
|
||||
if (expected_len <= len) {
|
||||
return true;
|
||||
}
|
||||
|
||||
DEBUG("RPL: wrong DIO len: %d, expected: %d\n", len, expected_len);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks validity of DAO control messages
|
||||
*
|
||||
* @param[in] dao The DAO control message
|
||||
* @param[in] len Length of the DAO control message
|
||||
*
|
||||
* @return true, if @p dao is valid
|
||||
* @return false, otherwise
|
||||
*/
|
||||
static inline bool gnrc_rpl_validation_DAO(gnrc_rpl_dao_t *dao, uint16_t len)
|
||||
{
|
||||
uint16_t expected_len = sizeof(*dao) + sizeof(icmpv6_hdr_t);
|
||||
|
||||
if ((dao->k_d_flags & GNRC_RPL_DAO_D_BIT)) {
|
||||
expected_len += sizeof(ipv6_addr_t);
|
||||
}
|
||||
|
||||
if (expected_len <= len) {
|
||||
return true;
|
||||
}
|
||||
|
||||
DEBUG("RPL: wrong DAO len: %d, expected: %d\n", len, expected_len);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks validity of DAO-ACK control messages
|
||||
*
|
||||
* @param[in] dao_ack The DAO-ACK control message
|
||||
* @param[in] len Length of the DAO-ACK control message
|
||||
*
|
||||
* @return true, if @p dao_ack is valid
|
||||
* @return false, otherwise
|
||||
*/
|
||||
static inline bool gnrc_rpl_validation_DAO_ACK(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;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GNRC_RPL_VALIDATION_H_ */
|
||||
/** @} */
|
||||
118
sys/net/gnrc/routing/rpl/gnrc_rpl_validation.c
Normal file
118
sys/net/gnrc/routing/rpl/gnrc_rpl_validation.c
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Cenk Gündoğan <mail@cgundogan.de>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License v2.1. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
*
|
||||
* @author Cenk Gündoğan <mail@cgundogan.de>
|
||||
*/
|
||||
|
||||
#include "net/gnrc/icmpv6.h"
|
||||
#include "net/gnrc/ipv6.h"
|
||||
|
||||
#include "net/gnrc/rpl.h"
|
||||
#include "gnrc_rpl_internal/validation.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
static char addr_str[IPV6_ADDR_MAX_STR_LEN];
|
||||
#endif
|
||||
|
||||
bool gnrc_rpl_validation_options(int msg_type, gnrc_rpl_instance_t *inst,
|
||||
gnrc_rpl_opt_t *opt, uint16_t len)
|
||||
{
|
||||
uint16_t expected_len = 0;
|
||||
|
||||
while(expected_len < len) {
|
||||
switch(opt->type) {
|
||||
case (GNRC_RPL_OPT_PAD1):
|
||||
expected_len += 1;
|
||||
opt = (gnrc_rpl_opt_t *) (((uint8_t *) opt) + 1);
|
||||
continue;
|
||||
|
||||
case (GNRC_RPL_OPT_DODAG_CONF):
|
||||
if (msg_type != GNRC_RPL_ICMPV6_CODE_DIO) {
|
||||
DEBUG("RPL: DODAG CONF DIO option not expected\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (opt->length != GNRC_RPL_OPT_DODAG_CONF_LEN) {
|
||||
DEBUG("RPL: wrong DIO option (DODAG CONF) len: %d, expected: %d\n",
|
||||
opt->length, GNRC_RPL_OPT_DODAG_CONF_LEN);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case (GNRC_RPL_OPT_PREFIX_INFO):
|
||||
if (msg_type != GNRC_RPL_ICMPV6_CODE_DIO) {
|
||||
DEBUG("RPL: PREFIX INFO DIO option not expected\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (opt->length != GNRC_RPL_OPT_PREFIX_INFO_LEN) {
|
||||
DEBUG("RPL: wrong DIO option (PREFIX INFO) len: %d, expected: %d\n",
|
||||
opt->length, GNRC_RPL_OPT_PREFIX_INFO_LEN);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case (GNRC_RPL_OPT_TARGET):
|
||||
if (msg_type != GNRC_RPL_ICMPV6_CODE_DAO) {
|
||||
DEBUG("RPL: RPL TARGET DAO option not expected\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (opt->length > GNRC_RPL_OPT_TARGET_LEN) {
|
||||
DEBUG("RPL: wrong DAO option (RPL TARGET) len: %d, expected (max): %d\n",
|
||||
opt->length, GNRC_RPL_OPT_TARGET_LEN);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case (GNRC_RPL_OPT_TRANSIT):
|
||||
if (msg_type != GNRC_RPL_ICMPV6_CODE_DAO) {
|
||||
DEBUG("RPL: RPL TRANSIT INFO DAO option not expected\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t parent_addr = 0;
|
||||
if (inst->mop == GNRC_RPL_MOP_NON_STORING_MODE) {
|
||||
parent_addr = sizeof(ipv6_addr_t);
|
||||
}
|
||||
|
||||
if (opt->length != (GNRC_RPL_OPT_TRANSIT_INFO_LEN + parent_addr)) {
|
||||
DEBUG("RPL: wrong DAO option (TRANSIT INFO) len: %d, expected: %d\n",
|
||||
opt->length, (GNRC_RPL_OPT_TRANSIT_INFO_LEN + parent_addr));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
expected_len += opt->length + sizeof(gnrc_rpl_opt_t);
|
||||
opt = (gnrc_rpl_opt_t *) (((uint8_t *) (opt + 1)) + opt->length);
|
||||
}
|
||||
|
||||
if (expected_len == len) {
|
||||
return true;
|
||||
}
|
||||
|
||||
DEBUG("RPL: wrong options len: %d, expected: %d\n", len, expected_len);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
Loading…
x
Reference in New Issue
Block a user