diff --git a/Makefile.pseudomodules b/Makefile.pseudomodules index 7e0f5189ef..e90712cf7d 100644 --- a/Makefile.pseudomodules +++ b/Makefile.pseudomodules @@ -39,6 +39,7 @@ PSEUDOMODULES += netif PSEUDOMODULES += netstats PSEUDOMODULES += netstats_l2 PSEUDOMODULES += netstats_ipv6 +PSEUDOMODULES += netstats_rpl PSEUDOMODULES += newlib PSEUDOMODULES += newlib_nano PSEUDOMODULES += pktqueue diff --git a/examples/gnrc_networking/Makefile b/examples/gnrc_networking/Makefile index 7412b8ff67..ab36f2eb55 100644 --- a/examples/gnrc_networking/Makefile +++ b/examples/gnrc_networking/Makefile @@ -32,6 +32,7 @@ USEMODULE += shell_commands USEMODULE += ps USEMODULE += netstats_l2 USEMODULE += netstats_ipv6 +USEMODULE += netstats_rpl # Set a custom 802.15.4 channel if needed DEFAULT_CHANNEL ?= 26 diff --git a/sys/include/net/gnrc/rpl.h b/sys/include/net/gnrc/rpl.h index bd92bc80cc..997e194fdc 100644 --- a/sys/include/net/gnrc/rpl.h +++ b/sys/include/net/gnrc/rpl.h @@ -111,6 +111,10 @@ #include "xtimer.h" #include "trickle.h" +#ifdef MODULE_NETSTATS_RPL +#include "net/rpl/rpl_netstats.h" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -447,6 +451,13 @@ extern kernel_pid_t gnrc_rpl_pid; */ extern const ipv6_addr_t ipv6_addr_all_rpl_nodes; +#ifdef MODULE_NETSTATS_RPL +/** + * @brief Statistics for RPL control messages + */ +extern netstats_rpl_t gnrc_rpl_netstats; +#endif + /** * @brief Initialization of the RPL thread. * @@ -525,9 +536,11 @@ void gnrc_rpl_recv_DIS(gnrc_rpl_dis_t *dis, kernel_pid_t iface, ipv6_addr_t *src * @param[in] dio Pointer to the DIO message. * @param[in] iface Interface PID of the incoming DIO. * @param[in] src Pointer to the source address of the IPv6 packet. + * @param[in] dst Pointer to the destination address of the IPv6 packet. * @param[in] len Length of the IPv6 packet. */ -void gnrc_rpl_recv_DIO(gnrc_rpl_dio_t *dio, kernel_pid_t iface, ipv6_addr_t *src, uint16_t len); +void gnrc_rpl_recv_DIO(gnrc_rpl_dio_t *dio, kernel_pid_t iface, ipv6_addr_t *src, ipv6_addr_t *dst, + uint16_t len); /** * @brief Parse a DAO. @@ -535,18 +548,23 @@ void gnrc_rpl_recv_DIO(gnrc_rpl_dio_t *dio, kernel_pid_t iface, ipv6_addr_t *src * @param[in] dao Pointer to the DAO message. * @param[in] iface Interface PID of the incoming DIO. * @param[in] src Pointer to the source address of the IPv6 packet. + * @param[in] dst Pointer to the destination address of the IPv6 packet. * @param[in] len Length of the IPv6 packet. */ -void gnrc_rpl_recv_DAO(gnrc_rpl_dao_t *dao, kernel_pid_t iface, ipv6_addr_t *src, uint16_t len); +void gnrc_rpl_recv_DAO(gnrc_rpl_dao_t *dao, kernel_pid_t iface, ipv6_addr_t *src, ipv6_addr_t *dst, + uint16_t len); /** * @brief Parse a DAO-ACK. * * @param[in] dao_ack Pointer to the DAO-ACK message. * @param[in] iface Interface PID of the incoming DIO. + * @param[in] src Pointer to the source address of the IPv6 packet. + * @param[in] dst Pointer to the destination address of the IPv6 packet. * @param[in] len Length of the IPv6 packet. */ -void gnrc_rpl_recv_DAO_ACK(gnrc_rpl_dao_ack_t *dao_ack, kernel_pid_t iface, uint16_t len); +void gnrc_rpl_recv_DAO_ACK(gnrc_rpl_dao_ack_t *dao_ack, kernel_pid_t iface, ipv6_addr_t *src, + ipv6_addr_t *dst, uint16_t len); /** * @brief Delay the DAO sending interval diff --git a/sys/include/net/netstats.h b/sys/include/net/netstats.h index 1bbb4ee32b..2e197eea04 100644 --- a/sys/include/net/netstats.h +++ b/sys/include/net/netstats.h @@ -33,6 +33,7 @@ extern "C" { */ #define NETSTATS_LAYER2 (0x01) #define NETSTATS_IPV6 (0x02) +#define NETSTATS_RPL (0x03) #define NETSTATS_ALL (0xFF) /** @} */ diff --git a/sys/include/net/rpl/rpl_netstats.h b/sys/include/net/rpl/rpl_netstats.h new file mode 100644 index 0000000000..aa670a5513 --- /dev/null +++ b/sys/include/net/rpl/rpl_netstats.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2016 HAW Hamburg + * + * 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. + */ + +/** + * @defgroup net_netstats_rpl Packet statistics for RPL + * @ingroup net_netstats + * @brief Packet statistics for RPL + * @{ + * + * @file + * @brief Definition of RPL related packet statistics + * + * @author Cenk Gündoğan + */ + +#include + +#ifndef NETSTATS_RPL_H +#define NETSTATS_RPL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief RPL statistics struct + */ +typedef struct { + /* DIO */ + uint32_t dio_rx_ucast_count; /**< unicast dio received in packets */ + uint32_t dio_rx_ucast_bytes; /**< unicast dio received in bytes */ + uint32_t dio_rx_mcast_count; /**< multicast dio received in packets */ + uint32_t dio_rx_mcast_bytes; /**< multicast dio received in bytes */ + uint32_t dio_tx_ucast_count; /**< unicast dio sent in packets */ + uint32_t dio_tx_ucast_bytes; /**< unicast dio sent in bytes */ + uint32_t dio_tx_mcast_count; /**< multicast dio sent in packets */ + uint32_t dio_tx_mcast_bytes; /**< multicast dio sent in bytes*/ + /* DIS */ + uint32_t dis_rx_ucast_count; /**< unicast dis received in packets */ + uint32_t dis_rx_ucast_bytes; /**< unicast dis received in bytes */ + uint32_t dis_rx_mcast_count; /**< multicast dis received in packets */ + uint32_t dis_rx_mcast_bytes; /**< multicast dis received in bytes */ + uint32_t dis_tx_ucast_count; /**< unicast dis sent in packets */ + uint32_t dis_tx_ucast_bytes; /**< unicast dis sent in bytes */ + uint32_t dis_tx_mcast_count; /**< multicast dis sent in packets */ + uint32_t dis_tx_mcast_bytes; /**< multicast dis sent in bytes*/ + /* DAO */ + uint32_t dao_rx_ucast_count; /**< unicast dao received in packets */ + uint32_t dao_rx_ucast_bytes; /**< unicast dao received in bytes */ + uint32_t dao_rx_mcast_count; /**< multicast dao received in packets */ + uint32_t dao_rx_mcast_bytes; /**< multicast dao received in bytes */ + uint32_t dao_tx_ucast_count; /**< unicast dao sent in packets */ + uint32_t dao_tx_ucast_bytes; /**< unicast dao sent in bytes */ + uint32_t dao_tx_mcast_count; /**< multicast dao sent in packets */ + uint32_t dao_tx_mcast_bytes; /**< multicast dao sent in bytes*/ + /* DAO-ACK */ + uint32_t dao_ack_rx_ucast_count; /**< unicast dao_ack received in packets */ + uint32_t dao_ack_rx_ucast_bytes; /**< unicast dao_ack received in bytes */ + uint32_t dao_ack_rx_mcast_count; /**< multicast dao_ack received in packets */ + uint32_t dao_ack_rx_mcast_bytes; /**< multicast dao_ack received in bytes */ + uint32_t dao_ack_tx_ucast_count; /**< unicast dao_ack sent in packets */ + uint32_t dao_ack_tx_ucast_bytes; /**< unicast dao_ack sent in bytes */ + uint32_t dao_ack_tx_mcast_count; /**< multicast dao_ack sent in packets */ + uint32_t dao_ack_tx_mcast_bytes; /**< multicast dao_ack sent in bytes*/ +} netstats_rpl_t; + +#ifdef __cplusplus +} +#endif + +#endif /* NETSTATS_RPL_H */ +/** @} */ diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl.c b/sys/net/gnrc/routing/rpl/gnrc_rpl.c index 7a8018afd8..df4e5ab89a 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl.c @@ -43,6 +43,10 @@ static uint8_t _instance_id; gnrc_rpl_instance_t gnrc_rpl_instances[GNRC_RPL_INSTANCES_NUMOF]; gnrc_rpl_parent_t gnrc_rpl_parents[GNRC_RPL_PARENTS_NUMOF]; +#ifdef MODULE_NETSTATS_RPL +netstats_rpl_t gnrc_rpl_netstats; +#endif + static void _update_lifetime(void); static void _dao_handle_send(gnrc_rpl_dodag_t *dodag); static void _receive(gnrc_pktsnip_t *pkt); @@ -70,6 +74,10 @@ kernel_pid_t gnrc_rpl_init(kernel_pid_t if_pid) gnrc_rpl_of_manager_init(); xtimer_set_msg(&_lt_timer, _lt_time, &_lt_msg, gnrc_rpl_pid); + +#ifdef MODULE_NETSTATS_RPL + memset(&gnrc_rpl_netstats, 0, sizeof(gnrc_rpl_netstats)); +#endif } /* register all_RPL_nodes multicast address */ @@ -149,17 +157,17 @@ static void _receive(gnrc_pktsnip_t *icmpv6) case GNRC_RPL_ICMPV6_CODE_DIO: DEBUG("RPL: DIO received\n"); gnrc_rpl_recv_DIO((gnrc_rpl_dio_t *)(icmpv6_hdr + 1), iface, &ipv6_hdr->src, - byteorder_ntohs(ipv6_hdr->len)); + &ipv6_hdr->dst, byteorder_ntohs(ipv6_hdr->len)); break; case GNRC_RPL_ICMPV6_CODE_DAO: DEBUG("RPL: DAO received\n"); gnrc_rpl_recv_DAO((gnrc_rpl_dao_t *)(icmpv6_hdr + 1), iface, &ipv6_hdr->src, - byteorder_ntohs(ipv6_hdr->len)); + &ipv6_hdr->dst, byteorder_ntohs(ipv6_hdr->len)); 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), iface, - byteorder_ntohs(ipv6_hdr->len)); + gnrc_rpl_recv_DAO_ACK((gnrc_rpl_dao_ack_t *)(icmpv6_hdr + 1), iface, &ipv6_hdr->src, + &ipv6_hdr->dst, byteorder_ntohs(ipv6_hdr->len)); break; #ifdef MODULE_GNRC_RPL_P2P case GNRC_RPL_P2P_ICMPV6_CODE_DRO: 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 8163dffe1e..4f012eb9cf 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c @@ -23,6 +23,10 @@ #include "net/gnrc.h" #include "net/eui64.h" +#ifdef MODULE_NETSTATS_RPL +#include "gnrc_rpl_internal/netstats.h" +#endif + #include "net/gnrc/rpl.h" #ifndef GNRC_RPL_WITHOUT_VALIDATION #include "gnrc_rpl_internal/validation.h" @@ -215,6 +219,11 @@ void gnrc_rpl_send_DIO(gnrc_rpl_instance_t *inst, ipv6_addr_t *destination) } pkt = tmp; +#ifdef MODULE_NETSTATS_RPL + gnrc_rpl_netstats_tx_DIO(&gnrc_rpl_netstats, gnrc_pkt_len(pkt), + (destination && !ipv6_addr_is_multicast(destination))); +#endif + gnrc_rpl_send(pkt, dodag->iface, NULL, destination, &dodag->dodag_id); } @@ -246,6 +255,11 @@ void gnrc_rpl_send_DIS(gnrc_rpl_instance_t *inst, ipv6_addr_t *destination) /* TODO add padding may be removed if packet size grows */ memcpy((dis + 1), padding, sizeof(padding)); +#ifdef MODULE_NETSTATS_RPL + gnrc_rpl_netstats_tx_DIS(&gnrc_rpl_netstats, gnrc_pkt_len(pkt), + (destination && !ipv6_addr_is_multicast(destination))); +#endif + gnrc_rpl_send(pkt, KERNEL_PID_UNDEF, NULL, destination, (inst? &(inst->dodag.dodag_id) : NULL)); } @@ -254,14 +268,17 @@ void gnrc_rpl_recv_DIS(gnrc_rpl_dis_t *dis, kernel_pid_t iface, ipv6_addr_t *src { /* TODO handle Solicited Information Option */ (void)iface; + (void)dis; + (void)len; + +#ifdef MODULE_NETSTATS_RPL + gnrc_rpl_netstats_rx_DIS(&gnrc_rpl_netstats, len, (dst && !ipv6_addr_is_multicast(dst))); +#endif #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)) { @@ -437,11 +454,17 @@ bool _parse_options(int msg_type, gnrc_rpl_instance_t *inst, gnrc_rpl_opt_t *opt return true; } -void gnrc_rpl_recv_DIO(gnrc_rpl_dio_t *dio, kernel_pid_t iface, ipv6_addr_t *src, uint16_t len) +void gnrc_rpl_recv_DIO(gnrc_rpl_dio_t *dio, kernel_pid_t iface, ipv6_addr_t *src, ipv6_addr_t *dst, + uint16_t len) { + (void) dst; gnrc_rpl_instance_t *inst = NULL; gnrc_rpl_dodag_t *dodag = NULL; +#ifdef MODULE_NETSTATS_RPL + gnrc_rpl_netstats_rx_DIO(&gnrc_rpl_netstats, len, (dst && !ipv6_addr_is_multicast(dst))); +#endif + #ifndef GNRC_RPL_WITHOUT_VALIDATION if (!gnrc_rpl_validation_DIO(dio, len)) { return; @@ -821,6 +844,11 @@ void gnrc_rpl_send_DAO(gnrc_rpl_instance_t *inst, ipv6_addr_t *destination, uint } pkt = tmp; +#ifdef MODULE_NETSTATS_RPL + gnrc_rpl_netstats_tx_DAO(&gnrc_rpl_netstats, gnrc_pkt_len(pkt), + (destination && !ipv6_addr_is_multicast(destination))); +#endif + gnrc_rpl_send(pkt, dodag->iface, NULL, destination, &dodag->dodag_id); GNRC_RPL_COUNTER_INCREMENT(dodag->dao_seq); @@ -868,12 +896,23 @@ void gnrc_rpl_send_DAO_ACK(gnrc_rpl_instance_t *inst, ipv6_addr_t *destination, dao_ack->dao_sequence = seq; dao_ack->status = 0; +#ifdef MODULE_NETSTATS_RPL + gnrc_rpl_netstats_tx_DAO_ACK(&gnrc_rpl_netstats, gnrc_pkt_len(pkt), + (destination && !ipv6_addr_is_multicast(destination))); +#endif + gnrc_rpl_send(pkt, dodag->iface, NULL, destination, &dodag->dodag_id); } -void gnrc_rpl_recv_DAO(gnrc_rpl_dao_t *dao, kernel_pid_t iface, ipv6_addr_t *src, uint16_t len) +void gnrc_rpl_recv_DAO(gnrc_rpl_dao_t *dao, kernel_pid_t iface, ipv6_addr_t *src, ipv6_addr_t *dst, + uint16_t len) { (void)iface; + (void)dst; + +#ifdef MODULE_NETSTATS_RPL + gnrc_rpl_netstats_rx_DAO(&gnrc_rpl_netstats, len, (dst && !ipv6_addr_is_multicast(dst))); +#endif gnrc_rpl_instance_t *inst = NULL; gnrc_rpl_dodag_t *dodag = NULL; @@ -931,19 +970,25 @@ void gnrc_rpl_recv_DAO(gnrc_rpl_dao_t *dao, kernel_pid_t iface, ipv6_addr_t *src gnrc_rpl_delay_dao(dodag); } -void gnrc_rpl_recv_DAO_ACK(gnrc_rpl_dao_ack_t *dao_ack, kernel_pid_t iface, uint16_t len) +void gnrc_rpl_recv_DAO_ACK(gnrc_rpl_dao_ack_t *dao_ack, kernel_pid_t iface, ipv6_addr_t *src, + ipv6_addr_t *dst, uint16_t len) { (void)iface; + (void)src; + (void)dst; + (void) len; gnrc_rpl_instance_t *inst = NULL; gnrc_rpl_dodag_t *dodag = NULL; +#ifdef MODULE_NETSTATS_RPL + gnrc_rpl_netstats_rx_DAO_ACK(&gnrc_rpl_netstats, len, (dst && !ipv6_addr_is_multicast(dst))); +#endif + #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) { diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_internal/netstats.h b/sys/net/gnrc/routing/rpl/gnrc_rpl_internal/netstats.h new file mode 100644 index 0000000000..2d9077dba6 --- /dev/null +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_internal/netstats.h @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2016 Cenk Gündoğan + * + * 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 statistics functions + * + * @author Cenk Gündoğan + */ + +#ifndef RPL_NETSTATS_H_ +#define RPL_NETSTATS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "net/rpl/rpl_netstats.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +#define GNRC_RPL_NETSTATS_MULTICAST (0) +#define GNRC_RPL_NETSTATS_UNICAST (1) + +/** + * @brief Increase statistics for received DIO + * + * @param[in] netstats Pointer to netstats_rpl_t + * @param[in] len Length in bytes of an ICMPv6 packet to add to statistics + * @param[in] cast GNRC_RPL_NETSTATS_MULTICAST or GNRC_RPL_NETSTATS_UNICAST + */ +static inline void gnrc_rpl_netstats_rx_DIO(netstats_rpl_t *netstats, size_t len, int cast) +{ + if (cast == GNRC_RPL_NETSTATS_MULTICAST) { + netstats->dio_rx_mcast_count++; + netstats->dio_rx_mcast_bytes += len; + } + else if (cast == GNRC_RPL_NETSTATS_UNICAST) { + netstats->dio_rx_ucast_count++; + netstats->dio_rx_ucast_bytes += len; + } +} + +/** + * @brief Increase statistics for sent DIO + * + * @param[in] netstats Pointer to netstats_rpl_t + * @param[in] len Length in bytes of an ICMPv6 packet to add to statistics + * @param[in] cast GNRC_RPL_NETSTATS_MULTICAST or GNRC_RPL_NETSTATS_UNICAST + */ +static inline void gnrc_rpl_netstats_tx_DIO(netstats_rpl_t *netstats, size_t len, int cast) +{ + if (cast == GNRC_RPL_NETSTATS_MULTICAST) { + netstats->dio_tx_mcast_count++; + netstats->dio_tx_mcast_bytes += len; + } + else if (cast == GNRC_RPL_NETSTATS_UNICAST) { + netstats->dio_tx_ucast_count++; + netstats->dio_tx_ucast_bytes += len; + } +} + +/** + * @brief Increase statistics for received DIS + * + * @param[in] netstats Pointer to netstats_rpl_t + * @param[in] len Length in bytes of an ICMPv6 packet to add to statistics + * @param[in] cast GNRC_RPL_NETSTATS_MULTICAST or GNRC_RPL_NETSTATS_UNICAST + */ +static inline void gnrc_rpl_netstats_rx_DIS(netstats_rpl_t *netstats, size_t len, int cast) +{ + if (cast == GNRC_RPL_NETSTATS_MULTICAST) { + netstats->dis_rx_mcast_count++; + netstats->dis_rx_mcast_bytes += len; + } + else if (cast == GNRC_RPL_NETSTATS_UNICAST) { + netstats->dis_rx_ucast_count++; + netstats->dis_rx_ucast_bytes += len; + } +} + +/** + * @brief Increase statistics for sent DIS + * + * @param[in] netstats Pointer to netstats_rpl_t + * @param[in] len Length in bytes of an ICMPv6 packet to add to statistics + * @param[in] cast GNRC_RPL_NETSTATS_MULTICAST or GNRC_RPL_NETSTATS_UNICAST + */ +static inline void gnrc_rpl_netstats_tx_DIS(netstats_rpl_t *netstats, size_t len, int cast) +{ + if (cast == GNRC_RPL_NETSTATS_MULTICAST) { + netstats->dis_tx_mcast_count++; + netstats->dis_tx_mcast_bytes += len; + } + else if (cast == GNRC_RPL_NETSTATS_UNICAST) { + netstats->dis_tx_ucast_count++; + netstats->dis_tx_ucast_bytes += len; + } +} + +/** + * @brief Increase statistics for received DAO + * + * @param[in] netstats Pointer to netstats_rpl_t + * @param[in] len Length in bytes of an ICMPv6 packet to add to statistics + * @param[in] cast GNRC_RPL_NETSTATS_MULTICAST or GNRC_RPL_NETSTATS_UNICAST + */ +static inline void gnrc_rpl_netstats_rx_DAO(netstats_rpl_t *netstats, size_t len, int cast) +{ + if (cast == GNRC_RPL_NETSTATS_MULTICAST) { + netstats->dao_rx_mcast_count++; + netstats->dao_rx_mcast_bytes += len; + } + else if (cast == GNRC_RPL_NETSTATS_UNICAST) { + netstats->dao_rx_ucast_count++; + netstats->dao_rx_ucast_bytes += len; + } +} + +/** + * @brief Increase statistics for sent DIO + * + * @param[in] netstats Pointer to netstats_rpl_t + * @param[in] len Length in bytes of an ICMPv6 packet to add to statistics + * @param[in] cast GNRC_RPL_NETSTATS_MULTICAST or GNRC_RPL_NETSTATS_UNICAST + */ +static inline void gnrc_rpl_netstats_tx_DAO(netstats_rpl_t *netstats, size_t len, int cast) +{ + if (cast == GNRC_RPL_NETSTATS_MULTICAST) { + netstats->dao_tx_mcast_count++; + netstats->dao_tx_mcast_bytes += len; + } + else if (cast == GNRC_RPL_NETSTATS_UNICAST) { + netstats->dao_tx_ucast_count++; + netstats->dao_tx_ucast_bytes += len; + } +} + +/** + * @brief Increase statistics for received DAO-ACK + * + * @param[in] netstats Pointer to netstats_rpl_t + * @param[in] len Length in bytes of an ICMPv6 packet to add to statistics + * @param[in] cast GNRC_RPL_NETSTATS_MULTICAST or GNRC_RPL_NETSTATS_UNICAST + */ +static inline void gnrc_rpl_netstats_rx_DAO_ACK(netstats_rpl_t *netstats, size_t len, int cast) +{ + if (cast == GNRC_RPL_NETSTATS_MULTICAST) { + netstats->dao_ack_rx_mcast_count++; + netstats->dao_ack_rx_mcast_bytes += len; + } + else if (cast == GNRC_RPL_NETSTATS_UNICAST) { + netstats->dao_ack_rx_ucast_count++; + netstats->dao_ack_rx_ucast_bytes += len; + } +} + +/** + * @brief Increase statistics for sent DAO-ACK + * + * @param[in] netstats Pointer to netstats_rpl_t + * @param[in] len Length in bytes of an ICMPv6 packet to add to statistics + * @param[in] cast GNRC_RPL_NETSTATS_MULTICAST or GNRC_RPL_NETSTATS_UNICAST + */ +static inline void gnrc_rpl_netstats_tx_DAO_ACK(netstats_rpl_t *netstats, size_t len, int cast) +{ + if (cast == GNRC_RPL_NETSTATS_MULTICAST) { + netstats->dao_ack_tx_mcast_count++; + netstats->dao_ack_tx_mcast_bytes += len; + } + else if (cast == GNRC_RPL_NETSTATS_UNICAST) { + netstats->dao_ack_tx_ucast_count++; + netstats->dao_ack_tx_ucast_bytes += len; + } +} + +#ifdef __cplusplus +} +#endif + +#endif /* RPL_NETSTATS_H_ */ +/** @} */ diff --git a/sys/shell/commands/sc_gnrc_rpl.c b/sys/shell/commands/sc_gnrc_rpl.c index eb3e339a2f..02459a0df4 100644 --- a/sys/shell/commands/sc_gnrc_rpl.c +++ b/sys/shell/commands/sc_gnrc_rpl.c @@ -182,6 +182,38 @@ int _gnrc_rpl_send_dis(void) return 0; } +#ifdef MODULE_NETSTATS_RPL +int _stats(void) +{ + puts( "Statistics (ucast) RX / TX RX / TX (mcast)"); + printf("DIO #packets: %10" PRIu32 " / %-10" PRIu32 " %10" PRIu32 " / %-10" PRIu32 "\n", + gnrc_rpl_netstats.dio_rx_ucast_count, gnrc_rpl_netstats.dio_tx_ucast_count, + gnrc_rpl_netstats.dio_rx_mcast_count, gnrc_rpl_netstats.dio_tx_mcast_count); + printf("DIO #bytes: %10" PRIu32 " / %-10" PRIu32 " %10" PRIu32 " / %-10" PRIu32 "\n", + gnrc_rpl_netstats.dio_rx_ucast_bytes, gnrc_rpl_netstats.dio_tx_ucast_bytes, + gnrc_rpl_netstats.dio_rx_mcast_bytes, gnrc_rpl_netstats.dio_tx_mcast_bytes); + printf("DIS #packets: %10" PRIu32 " / %-10" PRIu32 " %10" PRIu32 " / %-10" PRIu32 "\n", + gnrc_rpl_netstats.dis_rx_ucast_count, gnrc_rpl_netstats.dis_tx_ucast_count, + gnrc_rpl_netstats.dis_rx_mcast_count, gnrc_rpl_netstats.dis_tx_mcast_count); + printf("DIS #bytes: %10" PRIu32 " / %-10" PRIu32 " %10" PRIu32 " / %-10" PRIu32 "\n", + gnrc_rpl_netstats.dis_rx_ucast_bytes, gnrc_rpl_netstats.dis_tx_ucast_bytes, + gnrc_rpl_netstats.dis_rx_mcast_bytes, gnrc_rpl_netstats.dis_tx_mcast_bytes); + printf("DAO #packets: %10" PRIu32 " / %-10" PRIu32 " %10" PRIu32 " / %-10" PRIu32 "\n", + gnrc_rpl_netstats.dao_rx_ucast_count, gnrc_rpl_netstats.dao_tx_ucast_count, + gnrc_rpl_netstats.dao_rx_mcast_count, gnrc_rpl_netstats.dao_tx_mcast_count); + printf("DAO #bytes: %10" PRIu32 " / %-10" PRIu32 " %10" PRIu32 " / %-10" PRIu32 "\n", + gnrc_rpl_netstats.dao_rx_ucast_bytes, gnrc_rpl_netstats.dao_tx_ucast_bytes, + gnrc_rpl_netstats.dao_rx_mcast_bytes, gnrc_rpl_netstats.dao_tx_mcast_bytes); + printf("DAO-ACK #packets: %10" PRIu32 " / %-10" PRIu32 " %10" PRIu32 " / %-10" PRIu32 "\n", + gnrc_rpl_netstats.dao_ack_rx_ucast_count, gnrc_rpl_netstats.dao_ack_tx_ucast_count, + gnrc_rpl_netstats.dao_ack_rx_mcast_count, gnrc_rpl_netstats.dao_ack_tx_mcast_count); + printf("DAO-ACK #bytes: %10" PRIu32 " / %-10" PRIu32 " %10" PRIu32 " / %-10" PRIu32 "\n", + gnrc_rpl_netstats.dao_ack_rx_ucast_bytes, gnrc_rpl_netstats.dao_ack_tx_ucast_bytes, + gnrc_rpl_netstats.dao_ack_rx_mcast_bytes, gnrc_rpl_netstats.dao_ack_tx_mcast_bytes); + return 0; +} +#endif + int _gnrc_rpl_dodag_show(void) { printf("instance table:\t"); @@ -383,6 +415,11 @@ int _gnrc_rpl(int argc, char **argv) } } #endif +#ifdef MODULE_NETSTATS_RPL + else if (strcmp(argv[1], "stats") == 0) { + return _stats(); + } +#endif #ifdef MODULE_GNRC_RPL_P2P puts("* find \t\t\t- initiate a P2P-RPL route discovery");