diff --git a/sys/Makefile b/sys/Makefile index e8fddc781..41a79356a 100644 --- a/sys/Makefile +++ b/sys/Makefile @@ -40,9 +40,6 @@ endif ifneq (,$(filter routing,$(USEMODULE))) DIRS += net/routing endif -ifneq (,$(filter aodvv2,$(USEMODULE))) - DIRS += net/routing/aodvv2 -endif ifneq (,$(filter ieee802154,$(USEMODULE))) DIRS += net/link_layer/ieee802154 endif diff --git a/sys/net/include/aodvv2/aodvv2.h b/sys/net/include/aodvv2/aodvv2.h deleted file mode 100644 index 008db2d97..000000000 --- a/sys/net/include/aodvv2/aodvv2.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * Copyright (C) 2014 Lotte Steenbrink - * - * 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 aodvv2 AODVv2 - * @brief The Ad-hoc On-demand Distance Vector routing protocol, version 2 - * @ingroup net - * @{ - * - * @file - * @brief Interface for the AODVv2 routing protocol - * - * @author Lotte Steenbrink - */ - -#ifndef AODVV2_H_ -#define AODVV2_H_ - -#include "common/netaddr.h" -#include "rfc5444/rfc5444_print.h" - -#include "aodvv2/types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Initialize the AODVv2 routing protocol. - */ -void aodv_init(void); - -/** - * @brief Set the metric type. If metric_type does not match any known metric - * types, no changes will be made. - * - * @param[in] metric_type type of new metric - */ -void aodv_set_metric_type(aodvv2_metric_t metric_type); - -#ifdef __cplusplus -} -#endif - -#endif /* AODVV2_H_ */ -/** @} */ diff --git a/sys/net/include/aodvv2/types.h b/sys/net/include/aodvv2/types.h deleted file mode 100644 index 311530ea2..000000000 --- a/sys/net/include/aodvv2/types.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * Copyright (C) 2014 Lotte Steenbrink - * - * 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 aodvv2 - * @{ - * - * @file - * @brief data types for the aodvv2 routing protocol - * - * @author Lotte Steenbrink - */ - -#ifndef AODVV2_TYPES_H -#define AODVV2_TYPES_H - -#include "common/netaddr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief AODVv2 metric types. Extend to include alternate metrics. - */ -typedef enum { - HOP_COUNT = 3, /**< see RFC6551*/ -} aodvv2_metric_t; - -typedef uint16_t aodvv2_seqnum_t; - -#define AODVV2_DEFAULT_METRIC_TYPE HOP_COUNT - -/** - * @brief AODVv2 message types - */ -enum rfc5444_msg_type -{ - RFC5444_MSGTYPE_RREQ = 10, - RFC5444_MSGTYPE_RREP = 11, - RFC5444_MSGTYPE_RERR = 12, -}; - -/** - * @brief AODVv2 TLV types - */ -enum rfc5444_tlv_type -{ - RFC5444_MSGTLV_ORIGSEQNUM, - RFC5444_MSGTLV_TARGSEQNUM, - RFC5444_MSGTLV_UNREACHABLE_NODE_SEQNUM, - RFC5444_MSGTLV_METRIC, -}; - -/** - * @brief Data about an OrigNode or TargNode, typically embedded in an - * aodvv2_packet_data struct. - */ -struct node_data -{ - struct netaddr addr; /**< IP address of the node */ - uint8_t metric; /**< Metric value */ - aodvv2_seqnum_t seqnum; /**< Sequence Number */ -}; - -/** - * @brief all data contained in a RREQ or RREP. - */ -struct aodvv2_packet_data -{ - uint8_t hoplimit; /**< Hop limit */ - struct netaddr sender; /**< IP address of the neighboring router - * which sent the RREQ/RREP*/ - aodvv2_metric_t metricType; /**< Metric type */ - struct node_data origNode; /**< Data about the originating node */ - struct node_data targNode; /**< Data about the originating node */ - timex_t timestamp; /**< point at which the packet was (roughly) - * received. Note that this timestamp - * will be set after the packet has been - * successfully parsed. */ -}; - -/** - * @brief Data about an unreachable node to be embedded in a RERR. - */ -struct unreachable_node -{ - struct netaddr addr; /**< IP address */ - aodvv2_seqnum_t seqnum; /**< Sequence Number */ -}; - -#ifdef __cplusplus -} -#endif - -#endif /* AODVV2_TYPES_H */ diff --git a/sys/net/routing/aodvv2/Makefile b/sys/net/routing/aodvv2/Makefile deleted file mode 100644 index 48422e909..000000000 --- a/sys/net/routing/aodvv2/Makefile +++ /dev/null @@ -1 +0,0 @@ -include $(RIOTBASE)/Makefile.base diff --git a/sys/net/routing/aodvv2/aodv.c b/sys/net/routing/aodvv2/aodv.c deleted file mode 100644 index d5e8c4c34..000000000 --- a/sys/net/routing/aodvv2/aodv.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * Copyright (C) 2014 Lotte Steenbrink - * - * 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 aodvv2 - * @{ - * - * @file - * @brief aodvv2 routing protocol - * - * @author Lotte Steenbrink - */ - -#include "aodv.h" -#include "aodvv2/aodvv2.h" -#include "aodv_debug.h" -#include "ng_fib.h" - -#define ENABLE_DEBUG (0) -#include "debug.h" - -#define UDP_BUFFER_SIZE (128) /** with respect to IEEE 802.15.4's MTU */ -#define RCV_MSG_Q_SIZE (32) /* TODO: check if smaller values work, too */ - -static void _init_addresses(void); -static void _init_sock_snd(void); -static void *_aodv_receiver_thread(void *arg); -static void *_aodv_sender_thread(void *arg); -static void *fib_signal_handler_thread(void *arg); - -static void _deep_free_msg_container(struct msg_container *msg_container); -static void _write_packet(struct rfc5444_writer *wr __attribute__ ((unused)), - struct rfc5444_writer_target *iface __attribute__((unused)), - void *buffer, size_t length); -static void print_json_pkt_sent(struct writer_target *wt); - -#if AODV_DEBUG -char addr_str[IPV6_MAX_ADDR_STR_LEN]; -static struct netaddr_str nbuf; -#endif -#if TEST_SETUP -static struct netaddr_str nbuf_origaddr, nbuf_targaddr, nbuf_nexthop; -#endif - -static char aodv_rcv_stack_buf[THREAD_STACKSIZE_MAIN]; -static char aodv_snd_stack_buf[THREAD_STACKSIZE_MAIN]; -static char aodv_fib_stack_buf[THREAD_STACKSIZE_MAIN]; - -static aodvv2_metric_t _metric_type; -static int sender_thread; -static int _sock_snd; -static struct autobuf _hexbuf; -static sockaddr6_t sa_wp; -static ipv6_addr_t _v6_addr_local, _v6_addr_mcast, _v6_addr_loopback; -static struct netaddr na_local; /* the same as _v6_addr_local, but to save us - * constant calls to ipv6_addr_t_to_netaddr()... */ -static struct writer_target *wt; -static mutex_t rreq_mutex; -static mutex_t rrep_mutex; -static mutex_t rerr_mutex; - -struct netaddr na_mcast; -kernel_pid_t aodvv2_if_id; -ipv6_addr_t aodvv2_prefix; -int aodvv2_prefix_len; - -void aodv_init(void) -{ - AODV_DEBUG("%s()\n", __func__); - - /* init this thread's IPC msg queue (TODO: do I need to do this?) */ - msg_t msgq[RCV_MSG_Q_SIZE]; - msg_init_queue(msgq, sizeof msgq); - - /* TODO: set & handle prefix and prefix_len properly (consider AODVV2_RIOT_PREFIXLEN!) */ - aodvv2_prefix_len = 0; - /* TODO: set if_id properly (as param of aodv_init) */ - aodvv2_if_id = 0; - net_if_set_src_address_mode(aodvv2_if_id, NET_IF_TRANS_ADDR_M_SHORT); - - mutex_init(&rreq_mutex); - mutex_init(&rrep_mutex); - mutex_init(&rerr_mutex); - - aodv_set_metric_type(AODVV2_DEFAULT_METRIC_TYPE); - _init_addresses(); - _init_sock_snd(); - - /* init ALL the things! \o, */ - seqnum_init(); - routingtable_init(); - clienttable_init(); - - /* every node is its own client. */ - clienttable_add_client(&na_local); - rreqtable_init(); - - /* init reader and writer */ - aodv_packet_reader_init(); - aodv_packet_writer_init(_write_packet); - - /* start listening & enable sending */ - thread_create(aodv_rcv_stack_buf, sizeof(aodv_rcv_stack_buf), THREAD_PRIORITY_MAIN, - CREATE_STACKTEST, _aodv_receiver_thread, NULL, "_aodv_receiver_thread"); - AODV_DEBUG("listening on port %d\n", HTONS(MANET_PORT)); - sender_thread = thread_create(aodv_snd_stack_buf, sizeof(aodv_snd_stack_buf), - THREAD_PRIORITY_MAIN, CREATE_STACKTEST, _aodv_sender_thread, - NULL, "_aodv_sender_thread"); - thread_create(aodv_fib_stack_buf, sizeof(aodv_fib_stack_buf), - THREAD_PRIORITY_MAIN, CREATE_STACKTEST, fib_signal_handler_thread, - NULL, "fib_signal_handler_thread"); -} - -void aodv_set_metric_type(aodvv2_metric_t metric_type) -{ - if (metric_type != AODVV2_DEFAULT_METRIC_TYPE) { - return; - } - _metric_type = metric_type; -} -/* - * @brief handles callbacks from the FIB when it needs a route - */ -void *fib_signal_handler_thread(void *arg) -{ - (void) arg; - ipv6_addr_t dest; - struct netaddr na_dest; - - fib_register_rp((uint8_t*) &aodvv2_prefix, aodvv2_prefix_len); - - while (true) { - msg_t msg; - msg_receive(&msg); - - if (msg.type == FIB_MSG_RP_SIGNAL) { - rp_address_msg_t* rp_msg = (rp_address_msg_t*)msg.content.ptr; - if (rp_msg->address_size == sizeof(ipv6_addr_t)) { - /* We currently only support IPv6*/ - memcpy(&dest, rp_msg->address, rp_msg->address_size); - /* Reply to the FIB so that it can stop blocking */ - msg_reply(&msg, &msg); - - /* perform/initiate a rreq for dst here*/ - ipv6_addr_t_to_netaddr(&dest, &na_dest); - - aodvv2_seqnum_t seqnum = seqnum_get(); - seqnum_inc(); - - /* Build new RREQ */ - struct aodvv2_packet_data rreq_data = (struct aodvv2_packet_data) { - .hoplimit = AODVV2_MAX_HOPCOUNT, - .metricType = _metric_type, - .origNode = (struct node_data) { - .addr = na_local, - .metric = 0, - .seqnum = seqnum, - }, - .targNode = (struct node_data) { - .addr = na_dest, - }, - .timestamp = (timex_t) {0,0} /* this timestamp is never used, it exists - * merely to make the compiler shut up */ - }; - - AODV_DEBUG("\tstarting route discovery towards %s... \n", - ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, &dest)); - aodv_send_rreq(&rreq_data); - } - else { - /* Reply to the FIB so that it can stop blocking */ - msg_reply(&msg, &msg); - } - } - } - return NULL; -} - -void aodv_send_rreq(struct aodvv2_packet_data *packet_data) -{ - /* Make sure only one thread is dispatching a RREQ at a time */ - mutex_lock(&rreq_mutex); - - struct aodvv2_packet_data *pd = malloc(sizeof(struct aodvv2_packet_data)); - memcpy(pd, packet_data, sizeof(struct aodvv2_packet_data)); - - struct rreq_rrep_data *rd = malloc(sizeof(struct rreq_rrep_data)); - *rd = (struct rreq_rrep_data) { - .next_hop = &na_mcast, - .packet_data = pd, - }; - - struct msg_container *mc = malloc(sizeof(struct msg_container)); - *mc = (struct msg_container) { - .type = RFC5444_MSGTYPE_RREQ, - .data = rd - }; - - msg_t msg; - msg.content.ptr = (char *) mc; - - msg_try_send(&msg, sender_thread); - mutex_unlock(&rreq_mutex); -} - -void aodv_send_rrep(struct aodvv2_packet_data *packet_data, struct netaddr *next_hop) -{ - /* Make sure only one thread is dispatching a RREP at a time */ - mutex_lock(&rrep_mutex); - - struct aodvv2_packet_data *pd = malloc(sizeof(struct aodvv2_packet_data)); - memcpy(pd, packet_data, sizeof(struct aodvv2_packet_data)); - - struct netaddr *nh = malloc(sizeof(struct netaddr)); - memcpy(nh, next_hop, sizeof(struct netaddr)); - - struct rreq_rrep_data *rd = malloc(sizeof(struct rreq_rrep_data)); - *rd = (struct rreq_rrep_data) { - .next_hop = nh, - .packet_data = pd, - }; - - struct msg_container *mc = malloc(sizeof(struct msg_container)); - *mc = (struct msg_container) { - .type = RFC5444_MSGTYPE_RREP, - .data = rd - }; - - msg_t msg; - msg.content.ptr = (char *) mc; - - msg_try_send(&msg, sender_thread); - mutex_unlock(&rrep_mutex); -} - -void aodv_send_rerr(struct unreachable_node unreachable_nodes[], size_t len, struct netaddr *next_hop) -{ - /* Make sure only one thread is dispatching a RERR at a time */ - mutex_lock(&rerr_mutex); - - struct rerr_data *rerrd = malloc(sizeof(struct rerr_data)); - *rerrd = (struct rerr_data) { - .unreachable_nodes = unreachable_nodes, - .len = len, - .hoplimit = AODVV2_MAX_HOPCOUNT, - .next_hop = next_hop - }; - - struct msg_container *mc2 = malloc(sizeof(struct msg_container)); - *mc2 = (struct msg_container) { - .type = RFC5444_MSGTYPE_RERR, - .data = rerrd - }; - - msg_t msg2; - msg2.content.ptr = (char *) mc2; - - msg_try_send(&msg2, sender_thread); - mutex_unlock(&rerr_mutex); -} - -/* - * init the multicast address all RREQ and RERRS are sent to - * and the local address (source address) of this node - */ -static void _init_addresses(void) -{ - /* init multicast address: set to to a link-local all nodes multicast address */ - ipv6_addr_set_all_nodes_addr(&_v6_addr_mcast); - AODV_DEBUG("my multicast address is: %s\n", - ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, &_v6_addr_mcast)); - - /* get best IP for sending */ - ipv6_net_if_get_best_src_addr(&_v6_addr_local, &_v6_addr_mcast); - AODV_DEBUG("my src address is: %s\n", - ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, &_v6_addr_local)); - - /* store src & multicast address as netaddr as well for easy interaction - * with oonf based stuff */ - ipv6_addr_t_to_netaddr(&_v6_addr_local, &na_local); - ipv6_addr_t_to_netaddr(&_v6_addr_mcast, &na_mcast); - ipv6_addr_set_loopback_addr(&_v6_addr_loopback); - - /* init sockaddr that write_packet will use to send data */ - sa_wp.sin6_family = AF_INET6; - sa_wp.sin6_port = HTONS(MANET_PORT); -} - -/* init socket communication for sender */ -static void _init_sock_snd(void) -{ - _sock_snd = socket_base_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); - - if (-1 == _sock_snd) { - AODV_DEBUG("Error Creating Socket!\n"); - } -} - -/* Build RREQs, RREPs and RERRs from the information contained in the thread's - * message queue and send them */ -static void *_aodv_sender_thread(void *arg) -{ - (void) arg; - - msg_t msgq[RCV_MSG_Q_SIZE]; - msg_init_queue(msgq, RCV_MSG_Q_SIZE); - - while (true) { - msg_t msg; - msg_receive(&msg); - struct msg_container *mc = (struct msg_container *) msg.content.ptr; - - if (mc->type == RFC5444_MSGTYPE_RREQ) { - struct rreq_rrep_data *rreq_data = (struct rreq_rrep_data *) mc->data; - aodv_packet_writer_send_rreq(rreq_data->packet_data, rreq_data->next_hop); - } - else if (mc->type == RFC5444_MSGTYPE_RREP) { - struct rreq_rrep_data *rrep_data = (struct rreq_rrep_data *) mc->data; - aodv_packet_writer_send_rrep(rrep_data->packet_data, rrep_data->next_hop); - } - else if (mc->type == RFC5444_MSGTYPE_RERR) { - struct rerr_data *rerr_data = (struct rerr_data *) mc->data; - aodv_packet_writer_send_rerr(rerr_data->unreachable_nodes, rerr_data->len, - rerr_data->hoplimit, rerr_data->next_hop); - } - else { - AODV_DEBUG("ERROR: Couldn't identify Message\n"); - } - _deep_free_msg_container(mc); - } - - return NULL; -} - -/* receive RREQs, RREPs and RERRs and handle them */ -static void *_aodv_receiver_thread(void *arg) -{ - (void) arg; - - uint32_t fromlen; - char buf_rcv[UDP_BUFFER_SIZE]; - msg_t msg_q[RCV_MSG_Q_SIZE]; - - msg_init_queue(msg_q, RCV_MSG_Q_SIZE); - - sockaddr6_t sa_rcv = { .sin6_family = AF_INET6, - .sin6_port = HTONS(MANET_PORT) - }; - - int sock_rcv = socket_base_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); - - if (-1 == socket_base_bind(sock_rcv, &sa_rcv, sizeof(sa_rcv))) { - AODV_DEBUG("Error: bind to receive socket failed!\n"); - socket_base_close(sock_rcv); - return NULL; - } - - while (true) { - int32_t rcv_size = socket_base_recvfrom(sock_rcv, (void *)buf_rcv, UDP_BUFFER_SIZE, 0, - &sa_rcv, &fromlen); - - if (rcv_size < 0) { - AODV_DEBUG("ERROR receiving data!\n"); - } - - struct netaddr _sender; - ipv6_addr_t_to_netaddr(&sa_rcv.sin6_addr, &_sender); - - /* We sometimes get passed our own packets. Drop them. */ - if (netaddr_cmp(&_sender, &na_local) == 0) { - AODV_DEBUG("received our own packet, dropping it.\n"); - } - else { - aodv_packet_reader_handle_packet((void *) buf_rcv, rcv_size, &_sender); - } - } - - socket_base_close(sock_rcv); - - return NULL; -} - -/** - * Handle the output of the RFC5444 packet creation process. This callback is - * called by every writer_send_* function. - */ -static void _write_packet(struct rfc5444_writer *wr __attribute__ ((unused)), - struct rfc5444_writer_target *iface __attribute__((unused)), - void *buffer, size_t length) -{ - AODV_DEBUG("%s()\n", __func__); - /* generate hexdump and human readable representation of packet - * and print to console */ - abuf_hexdump(&_hexbuf, "\t", buffer, length); - rfc5444_print_direct(&_hexbuf, buffer, length); - /* DEBUG("%s", abuf_getptr(&_hexbuf)); */ - abuf_clear(&_hexbuf); - - /* fetch the address the packet is supposed to be sent to (i.e. to a - * specific node or the multicast address) from the writer_target struct - * iface* is stored in. This is a bit hacky, but it does the trick. */ - wt = container_of(iface, struct writer_target, interface); - print_json_pkt_sent(wt); - netaddr_to_ipv6_addr_t(&wt->target_addr, &sa_wp.sin6_addr); - - /* When originating a RREQ, add it to our RREQ table/update its predecessor */ - if (wt->type == RFC5444_MSGTYPE_RREQ - && netaddr_cmp(&wt->packet_data.origNode.addr, &na_local) == 0) { - AODV_DEBUG("originating RREQ with SeqNum %d towards %s via %s; updating RREQ table...\n", - wt->packet_data.origNode.seqnum, - netaddr_to_string(&nbuf, &wt->packet_data.targNode.addr), - ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, &sa_wp.sin6_addr)); - rreqtable_is_redundant(&wt->packet_data); - } - - int bytes_sent = socket_base_sendto(_sock_snd, buffer, length, - 0, &sa_wp, sizeof sa_wp); - - (void) bytes_sent; - AODV_DEBUG("%d bytes sent.\n", bytes_sent); -} - -/* Print the json representation of a sent packet to stdout for debugging */ -static void print_json_pkt_sent(struct writer_target *wt) -{ -#if TEST_SETUP - // note: what if the content at wt has changed until this is printed? memcpy the entire thing? - int msg_type = wt->type; - if (msg_type == RFC5444_MSGTYPE_RREQ) { - printf("{\"log_type\": \"sent_rreq\", \"log_data\": {" - "\"orig_addr\": \"%s\", \"targ_addr\": \"%s\", \"orig_seqnum\": %d, \"metric\": %d}}\n", - netaddr_to_string(&nbuf_origaddr, &wt->packet_data.origNode.addr), - netaddr_to_string(&nbuf_targaddr, &wt->packet_data.targNode.addr), - wt->packet_data.origNode.seqnum, wt->packet_data.origNode.metric); - } - if (msg_type == RFC5444_MSGTYPE_RREP) { - printf("{\"log_type\": \"sent_rrep\", \"log_data\": {" - "\"next_hop\": \"%s\",\"orig_addr\": \"%s\", \"orig_seqnum\": %d," - " \"targ_addr\": \"%s\"}}\n", - netaddr_to_string(&nbuf_nexthop, &wt->target_addr), - netaddr_to_string(&nbuf_origaddr, &wt->packet_data.origNode.addr), - wt->packet_data.origNode.seqnum, - netaddr_to_string(&nbuf_targaddr, &wt->packet_data.targNode.addr)); - } - if (msg_type == RFC5444_MSGTYPE_RERR) { - /* TODO */ - } -#else - (void) wt; /* silence compiler */ -#endif -} - -/* free the matryoshka doll of cobbled-together structs that the sender_thread receives */ -static void _deep_free_msg_container(struct msg_container *mc) -{ - int type = mc->type; - if ((type == RFC5444_MSGTYPE_RREQ) || (type == RFC5444_MSGTYPE_RREP)) { - struct rreq_rrep_data *rreq_rrep_data = (struct rreq_rrep_data *) mc->data; - free(rreq_rrep_data->packet_data); - if (netaddr_cmp(rreq_rrep_data->next_hop, &na_mcast) != 0) { - free(rreq_rrep_data->next_hop); - } - } - else if (type == RFC5444_MSGTYPE_RERR) { - struct rerr_data *rerr_data = (struct rerr_data *) mc->data; - if (netaddr_cmp(rerr_data->next_hop, &na_mcast) != 0) { - free(rerr_data->next_hop); - } - } - free(mc->data); - free(mc); -} diff --git a/sys/net/routing/aodvv2/aodv.h b/sys/net/routing/aodvv2/aodv.h deleted file mode 100644 index dd14143d4..000000000 --- a/sys/net/routing/aodvv2/aodv.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * Copyright (C) 2014 Lotte Steenbrink - * - * 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 aodvv2 - * @{ - * - * @file - * @brief aodvv2 routing protocol - * - * @author Lotte Steenbrink - */ - -#ifndef AODV_H_ -#define AODV_H_ - -#include -#include "sixlowpan.h" -#include "kernel.h" -#include "udp.h" -#include "socket_base/socket.h" -#include "net_help.h" -#include "net_if.h" - -#include "aodvv2/types.h" -#include "constants.h" -#include "seqnum.h" -#include "routingtable.h" -#include "utils.h" -#include "reader.h" -#include "writer.h" -#include "thread.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief This struct contains data which needs to be put into a RREQ or RREP. - * It is used to transport this data in a message to the sender_thread. - * @note Please note that it is for internal use only. To send a RREQ or RREP, - * please use the aodv_send_rreq() and aodv_send_rrep() functions. - */ -struct rreq_rrep_data -{ - struct aodvv2_packet_data *packet_data; /**< Data for the RREQ or RREP */ - struct netaddr *next_hop; /**< Next hop to which the RREQ - * or RREP should be sent */ -}; - -/** - * @brief This struct contains data which needs to be put into a RERR. - * It is used to transport this data in a message to the sender_thread. - * @note Please note that it is for internal use only. To send a RERR, - * please use the aodv_send_rerr() function. - */ -struct rerr_data -{ - struct unreachable_node *unreachable_nodes; /**< All unreachable nodes. Beware, - * this is the start of an array */ - size_t len; /**< Length of the unreachable_nodes array */ - int hoplimit; /**< hoplimit for the RERR */ - struct netaddr *next_hop; /**< Next hop to which the RERR - * should be sent */ -}; - - -/** - * @brief This struct holds the data for a RREQ, RREP or RERR (contained - * in a rreq_rrep_data or rerr_data struct) and the next hop the RREQ, RREP - * or RERR should be sent to. It used for message communication with - * the sender_thread. - * @note Please note that it is for internal use only. To send a RERR, - * please use the aodv_send_rerr() function. - */ -struct msg_container -{ - int type; /**< Message type (i.e. one of - * rfc5444_msg_type) */ - void *data; /**< Pointer to the message data - * (i.e. rreq_rrep_data or rerr_data) */ -}; - -/** - * @brief When set as ipv6_iface_routing_provider, this function is called by - * ipv6_sendto() to determine the next hop towards dest. This function - * is non-blocking. - * - * @param[in] dest destination of the packet - * @return Address of the next hop towards dest if there is any, - * NULL if there is none (yet) - */ -ipv6_addr_t *aodv_get_next_hop(ipv6_addr_t *dest); - -/** - * @brief Dispatch a RREQ - * - * @param[in] packet_data Payload of the RREQ - */ -void aodv_send_rreq(struct aodvv2_packet_data *packet_data); - -/** - * @brief Dispatch a RREP - * - * @param[in] packet_data Payload of the RREP - * @param[in] next_hop Address of the next hop the RREP should be sent to - */ -void aodv_send_rrep(struct aodvv2_packet_data *packet_data, struct netaddr *next_hop); - -/** - * @brief Dispatch a RERR - * - * @param[in] unreachable_nodes All nodes that are marked as unreachable - * by this RERR - * @param[in] len Number of unreachable nodes - * @param[in] next_hop Address of the next hop the RERR should be sent to - */ -void aodv_send_rerr(struct unreachable_node unreachable_nodes[], size_t len, - struct netaddr *next_hop); - -#ifdef __cplusplus -} -#endif - -#endif /* AODV_H_ */ diff --git a/sys/net/routing/aodvv2/aodv_debug.h b/sys/net/routing/aodvv2/aodv_debug.h deleted file mode 100644 index f4612a4a5..000000000 --- a/sys/net/routing/aodvv2/aodv_debug.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * - * 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 aodvv2 - * @{ - * - * @brief Debug-header for aodvv2 debug messages - * - * - * @author Lotte Steenbrink - */ - -#ifndef AODV_DEBUG_H_ -#define AODV_DEBUG_H_ - -#include -#include "sched.h" - -#ifdef __cplusplus - extern "C" { -#endif - -#if ENABLE_DEBUG -#define ENABLE_AODV_DEBUG (1) -#endif - -/** - * @brief Print aodvv2 specific debug information to std-out with [aodvv2] prefix - * - */ -#if ENABLE_AODV_DEBUG -#include "tcb.h" -#define AODV_DEBUG(...) \ - do { \ - printf("[aodvv2] "); \ - printf(__VA_ARGS__); \ - } while (0) -#else -#define AODV_DEBUG(...) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* AODVV2_DEBUG_H_*/ -/** @} */ diff --git a/sys/net/routing/aodvv2/constants.h b/sys/net/routing/aodvv2/constants.h deleted file mode 100644 index 344b6c043..000000000 --- a/sys/net/routing/aodvv2/constants.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * Copyright (C) 2014 Lotte Steenbrink - * - * 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 aodvv2 - * @{ - * - * @file - * @brief constants for the aodvv2 routing protocol - * - * @author Lotte Steenbrink - */ - -#ifndef AODVV2_CONSTANTS_H_ -#define AODVV2_CONSTANTS_H_ - -#include "aodvv2/types.h" - -#include "common/netaddr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define MANET_PORT 269 /** RFC5498 */ - -enum aodvv2_constants { - AODVV2_MAX_HOPCOUNT = 250, /**< see AODVv2 draft, section 14.2.*/ - AODVV2_MAX_ROUTING_ENTRIES = 255, /**< maximum number of entries - * in the routing table */ - AODVV2_ACTIVE_INTERVAL = 5, /**< seconds */ - AODVV2_MAX_IDLETIME = 250, /**< seconds */ - AODVV2_MAX_SEQNUM_LIFETIME = 300, /**< seconds */ - AODVV2_MAX_UNREACHABLE_NODES = 15, /**< TODO: choose value (wisely) */ -}; - -/** - * @brief TLV type array indices - */ -enum tlv_index -{ - TLV_ORIGSEQNUM, - TLV_TARGSEQNUM, - TLV_UNREACHABLE_NODE_SEQNUM, - TLV_METRIC, -}; - -/* my multicast address */ -extern struct netaddr na_mcast; - -/* the interface this protocol operates on */ -extern kernel_pid_t aodvv2_if_id; - -#ifdef __cplusplus -} -#endif - -#endif /* AODVV2_CONSTANTS_H_ */ diff --git a/sys/net/routing/aodvv2/reader.c b/sys/net/routing/aodvv2/reader.c deleted file mode 100644 index c8ba0e386..000000000 --- a/sys/net/routing/aodvv2/reader.c +++ /dev/null @@ -1,792 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * Copyright (C) 2014 Lotte Steenbrink - * - * 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 aodvv2 - * @{ - * - * @file - * @brief reading and handling of RFC5444 aodvv2 messages - * - * @author Lotte Steenbrink - */ - -#ifdef RIOT -#include "net_help.h" -#endif - -#include "reader.h" -#include "aodv_debug.h" -#include "ng_fib.h" - -#define ENABLE_DEBUG (0) -#include "debug.h" - -#if ENABLE_DEBUG -/* For PRIu16 etc. */ -#include -#endif - -static enum rfc5444_result _cb_rreq_blocktlv_addresstlvs_okay( - struct rfc5444_reader_tlvblock_context *cont); -static enum rfc5444_result _cb_rreq_blocktlv_messagetlvs_okay( - struct rfc5444_reader_tlvblock_context *cont); -static enum rfc5444_result _cb_rreq_end_callback( - struct rfc5444_reader_tlvblock_context *cont, bool dropped); - -static enum rfc5444_result _cb_rrep_blocktlv_addresstlvs_okay( - struct rfc5444_reader_tlvblock_context *cont); -static enum rfc5444_result _cb_rrep_blocktlv_messagetlvs_okay( - struct rfc5444_reader_tlvblock_context *cont); -static enum rfc5444_result _cb_rrep_end_callback( - struct rfc5444_reader_tlvblock_context *cont, bool dropped); - -static enum rfc5444_result _cb_rerr_blocktlv_addresstlvs_okay( - struct rfc5444_reader_tlvblock_context *cont); -static enum rfc5444_result _cb_rerr_blocktlv_messagetlvs_okay( - struct rfc5444_reader_tlvblock_context *cont); -static enum rfc5444_result _cb_rerr_end_callback( - struct rfc5444_reader_tlvblock_context *cont, bool dropped); - -/* helper functions */ -static void print_json_received_rreq(void); -static void print_json_received_rrep(void); -static uint8_t _get_link_cost(aodvv2_metric_t metricType); -static uint8_t _get_max_metric(aodvv2_metric_t metricType); -static uint8_t _get_route_cost(aodvv2_metric_t metricType, uint8_t metric); - -/* This is where we store data gathered from packets */ -static struct aodvv2_packet_data packet_data; -static struct unreachable_node unreachable_nodes[AODVV2_MAX_UNREACHABLE_NODES]; -static int num_unreachable_nodes; -static int aodvv2_validity_t = (AODVV2_ACTIVE_INTERVAL + AODVV2_MAX_IDLETIME) * 1000; /* milliseconds */ - -static struct rfc5444_reader reader; -#if AODV_DEBUG -static struct netaddr_str nbuf; -#endif - -/* - * Message consumer, will be called once for every message of - * type RFC5444_MSGTYPE_RREQ that contains all the mandatory message TLVs - */ -static struct rfc5444_reader_tlvblock_consumer _rreq_consumer = -{ - .msg_id = RFC5444_MSGTYPE_RREQ, - .block_callback = _cb_rreq_blocktlv_messagetlvs_okay, - .end_callback = _cb_rreq_end_callback, -}; - -/* - * Address consumer. Will be called once for every address in a message of - * type RFC5444_MSGTYPE_RREQ. - */ -static struct rfc5444_reader_tlvblock_consumer _rreq_address_consumer = -{ - .msg_id = RFC5444_MSGTYPE_RREQ, - .addrblock_consumer = true, - .block_callback = _cb_rreq_blocktlv_addresstlvs_okay, -}; - -/* - * Message consumer, will be called once for every message of - * type RFC5444_MSGTYPE_RREP that contains all the mandatory message TLVs - */ -static struct rfc5444_reader_tlvblock_consumer _rrep_consumer = -{ - .msg_id = RFC5444_MSGTYPE_RREP, - .block_callback = _cb_rrep_blocktlv_messagetlvs_okay, - .end_callback = _cb_rrep_end_callback, -}; - -/* - * Address consumer. Will be called once for every address in a message of - * type RFC5444_MSGTYPE_RREP. - */ -static struct rfc5444_reader_tlvblock_consumer _rrep_address_consumer = -{ - .msg_id = RFC5444_MSGTYPE_RREP, - .addrblock_consumer = true, - .block_callback = _cb_rrep_blocktlv_addresstlvs_okay, -}; - -/* - * Message consumer, will be called once for every message of - * type RFC5444_MSGTYPE_RERR that contains all the mandatory message TLVs - */ -static struct rfc5444_reader_tlvblock_consumer _rerr_consumer = -{ - .msg_id = RFC5444_MSGTYPE_RERR, - .block_callback = _cb_rerr_blocktlv_messagetlvs_okay, - .end_callback = _cb_rerr_end_callback, -}; - -/* - * Address consumer. Will be called once for every address in a message of - * type RFC5444_MSGTYPE_RERR. - */ -static struct rfc5444_reader_tlvblock_consumer _rerr_address_consumer = -{ - .msg_id = RFC5444_MSGTYPE_RERR, - .addrblock_consumer = true, - .block_callback = _cb_rerr_blocktlv_addresstlvs_okay, -}; - - -/* - * Address consumer entries definition - * TLV types RFC5444_MSGTLV__SEQNUM and RFC5444_MSGTLV_METRIC - */ -static struct rfc5444_reader_tlvblock_consumer_entry _rreq_rrep_address_consumer_entries[] = -{ - [RFC5444_MSGTLV_ORIGSEQNUM] = { .type = RFC5444_MSGTLV_ORIGSEQNUM}, - [RFC5444_MSGTLV_TARGSEQNUM] = { .type = RFC5444_MSGTLV_TARGSEQNUM}, - [RFC5444_MSGTLV_METRIC] = { .type = RFC5444_MSGTLV_METRIC } -}; - -/* - * Address consumer entries definition - * TLV types RFC5444_MSGTLV__SEQNUM and RFC5444_MSGTLV_METRIC - */ -static struct rfc5444_reader_tlvblock_consumer_entry _rerr_address_consumer_entries[] = -{ - [RFC5444_MSGTLV_UNREACHABLE_NODE_SEQNUM] = { - .type = RFC5444_MSGTLV_UNREACHABLE_NODE_SEQNUM - }, -}; - -/** - * This block callback is called for every address - * - * @param cont - * @return - */ -static enum rfc5444_result _cb_rreq_blocktlv_messagetlvs_okay(struct rfc5444_reader_tlvblock_context *cont) -{ - if (!cont->has_hoplimit) { - AODV_DEBUG("\tERROR: missing hop limit\n"); - return RFC5444_DROP_PACKET; - } - - packet_data.hoplimit = cont->hoplimit; - if (packet_data.hoplimit == 0) { - AODV_DEBUG("\tERROR: Hoplimit is 0.\n"); - return RFC5444_DROP_PACKET; - } - packet_data.hoplimit--; - - return RFC5444_OKAY; -} - -/** - * This block callback is called for every address of a RREQ Message. - * - * @param cont - * @return - */ -static enum rfc5444_result _cb_rreq_blocktlv_addresstlvs_okay(struct rfc5444_reader_tlvblock_context *cont) -{ -#if AODV_DEBUG - struct netaddr_str nbuf; -#endif - struct rfc5444_reader_tlvblock_entry *tlv; - bool is_origNode_addr = false; - bool is_targNode_addr = false; - - /* handle OrigNode SeqNum TLV */ - tlv = _rreq_rrep_address_consumer_entries[RFC5444_MSGTLV_ORIGSEQNUM].tlv; - if (tlv) { - is_origNode_addr = true; - packet_data.origNode.addr = cont->addr; - packet_data.origNode.seqnum = *tlv->single_value; - } - - /* handle TargNode SeqNum TLV */ - tlv = _rreq_rrep_address_consumer_entries[RFC5444_MSGTLV_TARGSEQNUM].tlv; - if (tlv) { - is_targNode_addr = true; - packet_data.targNode.addr = cont->addr; - packet_data.targNode.seqnum = *tlv->single_value; - } - if (!tlv && !is_origNode_addr) { - /* assume that tlv missing => targNode Address */ - is_targNode_addr = true; - packet_data.targNode.addr = cont->addr; - } - if (!is_origNode_addr && !is_targNode_addr) { - AODV_DEBUG("\tERROR: mandatory RFC5444_MSGTLV_ORIGSEQNUM TLV missing.\n"); - return RFC5444_DROP_PACKET; - } - - /* handle Metric TLV */ - /* cppcheck: suppress false positive on non-trivially initialized arrays. - * this is a known bug: http://trac.cppcheck.net/ticket/5497 */ - /* cppcheck-suppress arrayIndexOutOfBounds */ - tlv = _rreq_rrep_address_consumer_entries[RFC5444_MSGTLV_METRIC].tlv; - if (!tlv && is_origNode_addr) { - AODV_DEBUG("\tERROR: Missing or unknown metric TLV.\n"); - return RFC5444_DROP_PACKET; - } - if (tlv) { - if (!is_origNode_addr) { - AODV_DEBUG("\tERROR: Metric TLV belongs to wrong address.\n"); - return RFC5444_DROP_PACKET; - } - packet_data.metricType = tlv->type_ext; - packet_data.origNode.metric = *tlv->single_value; - } - - return RFC5444_OKAY; -} - -/** - * This callback is called every time the _rreq_consumer finishes reading a - * packet. - * @param cont - * @param dropped indicates whether the packet has been dropped previously by - * another callback - */ -static enum rfc5444_result _cb_rreq_end_callback( - struct rfc5444_reader_tlvblock_context *cont, bool dropped) -{ - (void) cont; - - struct aodvv2_routing_entry_t *rt_entry; - timex_t now; - - /* We've received a valid RREQ, log this. */ - print_json_received_rreq(); - - /* Check if packet contains the required information */ - if (dropped) { - AODV_DEBUG("\t Dropping packet.\n"); - return RFC5444_DROP_PACKET; - } - if ((packet_data.origNode.addr._type == AF_UNSPEC) || !packet_data.origNode.seqnum) { - AODV_DEBUG("\tERROR: missing OrigNode Address or SeqNum. Dropping packet.\n"); - return RFC5444_DROP_PACKET; - } - if (packet_data.targNode.addr._type == AF_UNSPEC) { - AODV_DEBUG("\tERROR: missing TargNode Address. Dropping packet.\n"); - return RFC5444_DROP_PACKET; - } - if (packet_data.hoplimit == 0) { - AODV_DEBUG("\tERROR: Hoplimit is 0. Dropping packet.\n"); - return RFC5444_DROP_PACKET; - } - if ((_get_max_metric(packet_data.metricType) - _get_link_cost(packet_data.metricType)) - <= packet_data.origNode.metric) { - AODV_DEBUG("\tMetric Limit reached. Dropping packet.\n"); - return RFC5444_DROP_PACKET; - } - - /* - The incoming RREQ MUST be checked against previously received - information from the RREQ Table Section 7.6. If the information - in the incoming RteMsg is redundant, then then no further action - is taken. - */ - if (rreqtable_is_redundant(&packet_data)) { - AODV_DEBUG("\tPacket is redundant. Dropping Packet. %i\n", RFC5444_DROP_PACKET); - return RFC5444_DROP_PACKET; - } - - /* Update the cost of the route, since the packet has successfully traversed - * one more hop. */ - packet_data.origNode.metric = _get_route_cost(packet_data.metricType, - packet_data.origNode.metric); - vtimer_now(&now); - packet_data.timestamp = now; - - /* for every relevant - * address (RteMsg.Addr) in the RteMsg, HandlingRtr searches its route - * table to see if there is a route table entry with the same MetricType - * of the RteMsg, matching RteMsg.Addr. - */ - - rt_entry = routingtable_get_entry(&packet_data.origNode.addr, packet_data.metricType); - - if (!rt_entry || (rt_entry->metricType != packet_data.metricType)) { - /* CAUTION SUPER HACKY FIX FIXME ASAP - problem: sometimes we get broadcasted RREQs from 2 hop neighbors and then - AODVv2 gets super confused when they're not in the routing table and starts a - Route discovery to find them and all hell breaks loose. let's see if we can fix - this (horribly). - - (another fix would be to stop bouncing the RREP back to the sender and asking - the routing table for the next hop (or just send towards TargNode and let the - network stack figure out the rest?)) - TODO evaluate that - */ - - ipv6_addr_t sender_tmp; - netaddr_to_ipv6_addr_t(&packet_data.sender, &sender_tmp); - ndp_neighbor_cache_t *ndp_nc_entry = ndp_neighbor_cache_search(&sender_tmp); - - if (ndp_nc_entry == NULL) { - AODV_DEBUG("No bidirectional link to sender. Dropping packet.\n"); - return RFC5444_DROP_PACKET; - } - /* HACKY FIX ENDS HERE */ - - struct aodvv2_routing_entry_t *tmp_rt_entry = (struct aodvv2_routing_entry_t *) - malloc(sizeof(struct aodvv2_routing_entry_t)); - memset(tmp_rt_entry, 0, sizeof(*tmp_rt_entry)); - - routingtable_fill_routing_entry_t_rreq(&packet_data, tmp_rt_entry); - routingtable_add_entry(tmp_rt_entry); - - /* add entry to FIB */ - fib_add_entry(aodvv2_if_id, tmp_rt_entry->addr._addr, sizeof(ipv6_addr_t), 0, - tmp_rt_entry->nextHopAddr._addr, sizeof(ipv6_addr_t), 0, aodvv2_validity_t); - - free(tmp_rt_entry); - } - else { - if (!routingtable_offers_improvement(rt_entry, &packet_data.origNode)) { - AODV_DEBUG("\tPacket offers no improvement over known route. Dropping Packet.\n"); - return RFC5444_DROP_PACKET; - } - /* The incoming routing information is better than existing routing - * table information and SHOULD be used to improve the route table. */ - AODV_DEBUG("\tUpdating Routing Table entry...\n"); - routingtable_fill_routing_entry_t_rreq(&packet_data, rt_entry); - - /* update the FIB */ - fib_update_entry(rt_entry->addr._addr, sizeof(ipv6_addr_t), rt_entry->nextHopAddr._addr, - sizeof(ipv6_addr_t), 0, aodvv2_validity_t); - } - - /* - * If TargNode is a client of the router receiving the RREQ, then the - * router generates a RREP message as specified in Section 7.4, and - * subsequently processing for the RREQ is complete. Otherwise, - * processing continues as follows. - */ - if (clienttable_is_client(&packet_data.targNode.addr)) { - AODV_DEBUG("TargNode is in client list, sending RREP\n"); - - /* make sure to start with a clean metric value */ - packet_data.targNode.metric = 0; - aodv_send_rrep(&packet_data, &packet_data.sender); - } - else { - AODV_DEBUG("I am not TargNode, forwarding RREQ\n"); - aodv_send_rreq(&packet_data); - } - return RFC5444_OKAY; -} - -/** - * This block callback is called for every address - * - * @param cont - * @return - */ -static enum rfc5444_result _cb_rrep_blocktlv_messagetlvs_okay(struct rfc5444_reader_tlvblock_context *cont) -{ - if (!cont->has_hoplimit) { - AODV_DEBUG("\tERROR: missing hop limit\n"); - return RFC5444_DROP_PACKET; - } - - packet_data.hoplimit = cont->hoplimit; - if (packet_data.hoplimit == 0) { - AODV_DEBUG("\tERROR: Hoplimit is 0.\n"); - return RFC5444_DROP_PACKET; - } - - packet_data.hoplimit--; - - return RFC5444_OKAY; -} - -/** - * This block callback is called for every address of a RREP Message. - * - * @param cont - * @return - */ -static enum rfc5444_result _cb_rrep_blocktlv_addresstlvs_okay(struct rfc5444_reader_tlvblock_context *cont) -{ -#if AODV_DEBUG - /* cppcheck-suppress unusedVariable as nbuf is needed by AODV_DEBUG. */ - struct netaddr_str nbuf; -#endif - struct rfc5444_reader_tlvblock_entry *tlv; - bool is_targNode_addr = false; - - /* handle TargNode SeqNum TLV */ - tlv = _rreq_rrep_address_consumer_entries[RFC5444_MSGTLV_TARGSEQNUM].tlv; - if (tlv) { - is_targNode_addr = true; - packet_data.targNode.addr = cont->addr; - packet_data.targNode.seqnum = *tlv->single_value; - } - - /* handle OrigNode SeqNum TLV */ - tlv = _rreq_rrep_address_consumer_entries[RFC5444_MSGTLV_ORIGSEQNUM].tlv; - if (tlv) { - is_targNode_addr = false; - packet_data.origNode.addr = cont->addr; - packet_data.origNode.seqnum = *tlv->single_value; - } - if (!tlv && !is_targNode_addr) { - AODV_DEBUG("\tERROR: mandatory SeqNum TLV missing.\n"); - return RFC5444_DROP_PACKET; - } - - /* handle Metric TLV */ - /* cppcheck: suppress false positive on non-trivially initialized arrays. - * this is a known bug: http://trac.cppcheck.net/ticket/5497 */ - /* cppcheck-suppress arrayIndexOutOfBounds */ - tlv = _rreq_rrep_address_consumer_entries[RFC5444_MSGTLV_METRIC].tlv; - if (!tlv && is_targNode_addr) { - AODV_DEBUG("\tERROR: Missing or unknown metric TLV.\n"); - return RFC5444_DROP_PACKET; - } - if (tlv) { - if (!is_targNode_addr) { - AODV_DEBUG("\tERROR: metric TLV belongs to wrong address.\n"); - return RFC5444_DROP_PACKET; - } - packet_data.metricType = tlv->type_ext; - packet_data.targNode.metric = *tlv->single_value; - } - return RFC5444_OKAY; -} - -/** - * This callback is called every time the _rreq_consumer finishes reading a - * packet. - * @param cont - * @param dropped indicates wehther the packet has been dropped previously by - * another callback - */ -static enum rfc5444_result _cb_rrep_end_callback( - struct rfc5444_reader_tlvblock_context *cont, bool dropped) -{ - (void) cont; - - struct aodvv2_routing_entry_t *rt_entry; -#if AODV_DEBUG - struct netaddr_str nbuf; -#endif - timex_t now; - - /* We've received a valid RREP, log this. */ - print_json_received_rrep(); - - /* Check if packet contains the required information */ - if (dropped) { - AODV_DEBUG("\t Dropping packet.\n"); - return RFC5444_DROP_PACKET; - } - if ((packet_data.origNode.addr._type == AF_UNSPEC) - || !packet_data.origNode.seqnum) { - AODV_DEBUG("\tERROR: missing OrigNode Address or SeqNum. Dropping packet.\n"); - return RFC5444_DROP_PACKET; - } - if ((packet_data.targNode.addr._type == AF_UNSPEC) - || !packet_data.targNode.seqnum) { - AODV_DEBUG("\tERROR: missing TargNode Address or SeqNum. Dropping packet.\n"); - return RFC5444_DROP_PACKET; - } - if ((_get_max_metric(packet_data.metricType) - _get_link_cost(packet_data.metricType)) - <= packet_data.targNode.metric) { - AODV_DEBUG("\tMetric Limit reached. Dropping packet.\n"); - return RFC5444_DROP_PACKET; - } - - /* Update the cost of the route, since the packet has successfully traversed - * one more hop. */ - packet_data.targNode.metric = _get_route_cost(packet_data.metricType, - packet_data.targNode.metric); - vtimer_now(&now); - packet_data.timestamp = now; - - /* for every relevant address (RteMsg.Addr) in the RteMsg, HandlingRtr - searches its route table to see if there is a route table entry with the - same MetricType of the RteMsg, matching RteMsg.Addr. */ - - rt_entry = routingtable_get_entry(&packet_data.targNode.addr, packet_data.metricType); - - if (!rt_entry || (rt_entry->metricType != packet_data.metricType)) { - /* CAUTION SUPER HACKY FIX FIXME ASAP - problem: sometimes we get broadcasted RREQs from 2 hop neighbors and then - AODVv2 gets super confused when they're not in the routing table and starts a - Route discovery to find them and all hell breaks loose. let's see if we can fix - this (horribly). - - (another fix would be to stop bouncing the RREP back to the sender and asking - the routing table for the next hop (or just send towards TargNode and let the network stack figure out the rest?)) - TODO evaluate that - */ - - ipv6_addr_t sender_tmp; - netaddr_to_ipv6_addr_t(&packet_data.sender, &sender_tmp); - ndp_neighbor_cache_t *ndp_nc_entry = ndp_neighbor_cache_search(&sender_tmp); - - if (ndp_nc_entry == NULL) { - AODV_DEBUG("No bidirectional link to sender. Dropping packet.\n"); - return RFC5444_DROP_PACKET; - } - /* HACKY FIX ENDS HERE */ - - struct aodvv2_routing_entry_t *tmp_rt_entry = (struct aodvv2_routing_entry_t *) - malloc(sizeof(struct aodvv2_routing_entry_t)); - memset(tmp_rt_entry, 0, sizeof(*tmp_rt_entry)); - - routingtable_fill_routing_entry_t_rrep(&packet_data, tmp_rt_entry); - routingtable_add_entry(tmp_rt_entry); - - /* add entry to FIB */ - fib_add_entry(aodvv2_if_id, tmp_rt_entry->addr._addr, sizeof(ipv6_addr_t), 0, - tmp_rt_entry->nextHopAddr._addr, sizeof(ipv6_addr_t), 0, aodvv2_validity_t); - - free(tmp_rt_entry); - } - else { - if (!routingtable_offers_improvement(rt_entry, &packet_data.targNode)) { - AODV_DEBUG("\tPacket offers no improvement over known route. Dropping Packet.\n"); - return RFC5444_DROP_PACKET; - } - /* The incoming routing information is better than existing routing - * table information and SHOULD be used to improve the route table. */ - AODV_DEBUG("\tUpdating Routing Table entry...\n"); - routingtable_fill_routing_entry_t_rrep(&packet_data, rt_entry); - - /* update the FIB */ - fib_update_entry(rt_entry->addr._addr, sizeof(ipv6_addr_t), rt_entry->nextHopAddr._addr, - sizeof(ipv6_addr_t), 0, aodvv2_validity_t); - } - - /* If HandlingRtr is RREQ_Gen then the RREP satisfies RREQ_Gen's - earlier RREQ, and RREP processing is completed. Any packets - buffered for OrigNode should be transmitted. */ - if (clienttable_is_client(&packet_data.origNode.addr)) { - AODV_DEBUG("\t%s: This is my RREP. We are done here!\n", - netaddr_to_string(&nbuf, &packet_data.origNode.addr)); - } - - else { - /* If HandlingRtr is not RREQ_Gen then the outgoing RREP is sent to the - * Route.NextHopAddress for the RREP.AddrBlk[OrigNodeNdx]. */ - AODV_DEBUG("Not my RREP, passing it on to the next hop\n"); - aodv_send_rrep(&packet_data, - routingtable_get_next_hop(&packet_data.origNode.addr,packet_data.metricType)); - } - return RFC5444_OKAY; -} - -static enum rfc5444_result _cb_rerr_blocktlv_messagetlvs_okay(struct rfc5444_reader_tlvblock_context *cont) -{ - if (!cont->has_hoplimit) { - AODV_DEBUG("\tERROR: missing hop limit\n"); - return RFC5444_DROP_PACKET; - } - - packet_data.hoplimit = cont->hoplimit; - if (packet_data.hoplimit == 0) { - AODV_DEBUG("\tERROR: Hoplimit is 0.\n"); - return RFC5444_DROP_PACKET; - } - - packet_data.hoplimit--; - - /* prepare buffer for unreachable nodes */ - num_unreachable_nodes = 0; - for (unsigned i = 0; i < AODVV2_MAX_UNREACHABLE_NODES; i++) { - memset(&unreachable_nodes[i], 0, sizeof(unreachable_nodes[i])); - } - return RFC5444_OKAY; -} - -static enum rfc5444_result _cb_rerr_blocktlv_addresstlvs_okay(struct rfc5444_reader_tlvblock_context *cont) -{ -#if AODV_DEBUG - /* cppcheck-suppress unusedVariable as nbuf is needed by AODV_DEBUG. */ - struct netaddr_str nbuf; -#endif - struct aodvv2_routing_entry_t *unreachable_entry; - struct rfc5444_reader_tlvblock_entry *tlv; - - AODV_DEBUG("%s()\n", __func__); - AODV_DEBUG("\tmessage type: %d\n", cont->type); - AODV_DEBUG("\taddr: %s\n", netaddr_to_string(&nbuf, &cont->addr)); - - /* Out of buffer size for more unreachable nodes. We're screwed, basically. */ - if (num_unreachable_nodes == AODVV2_MAX_UNREACHABLE_NODES) { - return RFC5444_OKAY; - } - - /* gather packet data */ - packet_data.origNode.addr = cont->addr; - - /* handle this unreachable node's SeqNum TLV */ - /* cppcheck: suppress false positive on non-trivially initialized arrays. - * this is a known bug: http://trac.cppcheck.net/ticket/5497 */ - /* cppcheck-suppress arrayIndexOutOfBounds */ - tlv = _rerr_address_consumer_entries[RFC5444_MSGTLV_UNREACHABLE_NODE_SEQNUM].tlv; - if (tlv) { - AODV_DEBUG("\ttlv RFC5444_MSGTLV_UNREACHABLE_NODE_SEQNUM: %d\n", *tlv->single_value); - packet_data.origNode.seqnum = *tlv->single_value; - } - - /* Check if there is an entry for unreachable node in our routing table */ - unreachable_entry = routingtable_get_entry(&packet_data.origNode.addr, packet_data.metricType); - if (unreachable_entry) { - AODV_DEBUG("\t found possibly unreachable entry.\n"); - - /* check if route to unreachable node has to be marked as broken and RERR has to be forwarded */ - if (netaddr_cmp(&unreachable_entry->nextHopAddr, &packet_data.sender) == 0 - && (!tlv || seqnum_cmp(unreachable_entry->seqnum, packet_data.origNode.seqnum) == 0)) { - unreachable_entry->state = ROUTE_STATE_INVALID; - unreachable_nodes[num_unreachable_nodes].addr = packet_data.origNode.addr; - unreachable_nodes[num_unreachable_nodes].seqnum = packet_data.origNode.seqnum; - num_unreachable_nodes++; - } - - /* remove entry from FIB */ - fib_remove_entry(packet_data.origNode.addr._addr, sizeof(ipv6_addr_t)); - } - - return RFC5444_OKAY; -} - -static enum rfc5444_result _cb_rerr_end_callback(struct rfc5444_reader_tlvblock_context *cont, bool dropped) -{ - (void) cont; - - if (dropped) { - AODV_DEBUG("\tDropping packet.\n"); - return RFC5444_DROP_PACKET; - } - - if (num_unreachable_nodes == 0) { - AODV_DEBUG("\tNo unreachable nodes from my routing table. Dropping Packet.\n"); - return RFC5444_DROP_PACKET; - } - /* gather all unreachable nodes and put them into a RERR */ - aodv_send_rerr(unreachable_nodes, num_unreachable_nodes, &na_mcast); - return RFC5444_OKAY; -} - -void aodv_packet_reader_init(void) -{ - AODV_DEBUG("%s()\n", __func__); - - /* initialize reader */ - rfc5444_reader_init(&reader); - - /* register message consumers. We have no message TLVs, so we can leave the - * rfc5444_reader_tlvblock_consumer_entry empty */ - rfc5444_reader_add_message_consumer(&reader, &_rreq_consumer, - NULL, 0); - rfc5444_reader_add_message_consumer(&reader, &_rrep_consumer, - NULL, 0); - rfc5444_reader_add_message_consumer(&reader, &_rerr_consumer, - NULL, 0); - - /* register address consumer */ - rfc5444_reader_add_message_consumer(&reader, &_rreq_address_consumer, - _rreq_rrep_address_consumer_entries, - ARRAYSIZE(_rreq_rrep_address_consumer_entries)); - rfc5444_reader_add_message_consumer(&reader, &_rrep_address_consumer, - _rreq_rrep_address_consumer_entries, - ARRAYSIZE(_rreq_rrep_address_consumer_entries)); - rfc5444_reader_add_message_consumer(&reader, &_rerr_address_consumer, - _rerr_address_consumer_entries, - ARRAYSIZE(_rerr_address_consumer_entries)); -} - -void aodv_packet_reader_cleanup(void) -{ - rfc5444_reader_cleanup(&reader); -} - -int aodv_packet_reader_handle_packet(void *buffer, size_t length, struct netaddr *sender) -{ - memcpy(&packet_data.sender, sender, sizeof(*sender)); - - return rfc5444_reader_handle_packet(&reader, buffer, length); -} - -/*============= HELPER FUNCTIONS =============================================*/ - -static void print_json_received_rreq(void) -{ -#if TEST_SETUP - static struct netaddr_str nbuf_origaddr, nbuf_targaddr, nbuf_send; - - printf("{\"log_type\": \"received_rreq\", " - "\"log_data\":{ \"last_hop\": \"%s\", \"orig_addr\": \"%s\", " - "\"orig_seqnum\": %d, \"targ_addr\": \"%s\", \"metric\": %d}}\n", - netaddr_to_string(&nbuf_send, &packet_data.sender), - netaddr_to_string(&nbuf_origaddr, &packet_data.origNode.addr), - packet_data.origNode.seqnum, - netaddr_to_string(&nbuf_targaddr, &packet_data.targNode.addr), - packet_data.origNode.metric); -#endif -} - -static void print_json_received_rrep(void) -{ -#if TEST_SETUP - static struct netaddr_str nbuf_origaddr, nbuf_targaddr, nbuf_send; - - printf("{\"log_type\": \"received_rrep\", " - "\"log_data\":{ \"last_hop\": \"%s\", \"orig_addr\": \"%s\", " - "\"orig_seqnum\": %d, \"targ_addr\": \"%s\", \"targ_seqnum\":%d}}\n", - netaddr_to_string(&nbuf_send, &packet_data.sender), - netaddr_to_string(&nbuf_origaddr, &packet_data.origNode.addr), - packet_data.origNode.seqnum, - netaddr_to_string(&nbuf_targaddr, &packet_data.targNode.addr), - packet_data.targNode.seqnum); -#endif -} - -/* - * Cost(L): Get Cost of a Link regarding the specified metric. - * (currently only AODVV2_DEFAULT_METRIC_TYPE (HopCount) implemented) - * returns cost if metric is known, 0 otherwise - */ -static uint8_t _get_link_cost(aodvv2_metric_t metricType) -{ - if (metricType == AODVV2_DEFAULT_METRIC_TYPE) { - return 1; - } - return 0; -} - -/* - * MAX_METRIC[MetricType]: - * returns maximum value of the given metric if metric is known, 0 otherwise. - */ -static uint8_t _get_max_metric(aodvv2_metric_t metricType) -{ - if (metricType == AODVV2_DEFAULT_METRIC_TYPE) { - return AODVV2_MAX_HOPCOUNT; - } - return 0; -} - -/* - * Cost(R): Get Cost of a Route regarding the specified metric, based on the - * earlier metric value of the Route. - * (currently only AODVV2_DEFAULT_METRIC_TYPE (HopCount) implemented) - * returns cost if metric is known, 0 otherwise - */ -static uint8_t _get_route_cost(aodvv2_metric_t metricType, uint8_t metric) -{ - if (metricType == AODVV2_DEFAULT_METRIC_TYPE){ - return metric + _get_link_cost(AODVV2_DEFAULT_METRIC_TYPE); - } - return 0; -} diff --git a/sys/net/routing/aodvv2/reader.h b/sys/net/routing/aodvv2/reader.h deleted file mode 100644 index c47b5a06b..000000000 --- a/sys/net/routing/aodvv2/reader.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * Copyright (C) 2014 Lotte Steenbrink - * - * 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 aodvv2 - * @{ - * - * @file - * @brief reading and handling of RFC5444 aodvv2 messages - * - * @author Lotte Steenbrink - */ - -#ifndef AODVV2_READER_H_ -#define AODVV2_READER_H_ - -#include -#include - -#include "common/netaddr.h" -#include "rfc5444/rfc5444_reader.h" - -#include "utils.h" -#include "routingtable.h" -#include "constants.h" -#include "seqnum.h" -#include "aodv.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Initialize reader. - */ -void aodv_packet_reader_init(void); - -/** - * @brief Clean up after reader. Only needs to be called upon shutdown. - */ -void aodv_packet_reader_cleanup(void); - -/** - * @brief Read data buffer as RFC5444 packet and handle the data it contains - * - * @param[in] buffer Data to be read and handled - * @param[in] length Length of data - * @param[in] sender Address of the node from which the packet was received - */ -int aodv_packet_reader_handle_packet(void *buffer, size_t length, struct netaddr *sender); - -#ifdef __cplusplus -} -#endif - -#endif /* AODVV2_READER_H_ */ diff --git a/sys/net/routing/aodvv2/routingtable.c b/sys/net/routing/aodvv2/routingtable.c deleted file mode 100644 index bf574d2e6..000000000 --- a/sys/net/routing/aodvv2/routingtable.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * Copyright (C) 2014 Lotte Steenbrink - * - * 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 aodvv2 - * @{ - * - * @file - * @brief Cobbled-together routing table. - * - * @author Lotte Steenbrink - */ - -#include -#include - -#include "routingtable.h" -#include "aodv_debug.h" - -#define ENABLE_DEBUG (0) -#include "debug.h" - -/* helper functions */ -static void _reset_entry_if_stale(uint8_t i); -static void print_json_added_rt_entry(struct aodvv2_routing_entry_t *entry); - -static struct aodvv2_routing_entry_t routing_table[AODVV2_MAX_ROUTING_ENTRIES]; -static timex_t null_time, max_seqnum_lifetime, active_interval, max_idletime, validity_t; -timex_t now; -#if ENABLE_DEBUG -static struct netaddr_str nbuf; -#endif - -void routingtable_init(void) -{ - null_time = timex_set(0, 0); - max_seqnum_lifetime = timex_set(AODVV2_MAX_SEQNUM_LIFETIME, 0); - active_interval = timex_set(AODVV2_ACTIVE_INTERVAL, 0); - max_idletime = timex_set(AODVV2_MAX_IDLETIME, 0); - validity_t = timex_set(AODVV2_ACTIVE_INTERVAL + AODVV2_MAX_IDLETIME, 0); - - memset(&routing_table, 0, sizeof(routing_table)); - AODV_DEBUG("routing table initialized.\n"); -} - -struct netaddr *routingtable_get_next_hop(struct netaddr *dest, aodvv2_metric_t metricType) -{ - struct aodvv2_routing_entry_t *entry = routingtable_get_entry(dest, metricType); - if (!entry) { - return NULL; - } - return (&entry->nextHopAddr); -} - -void routingtable_add_entry(struct aodvv2_routing_entry_t *entry) -{ - print_json_added_rt_entry(entry); - - /* only add if we don't already know the address */ - if (routingtable_get_entry(&(entry->addr), entry->metricType)) { - return; - } - /*find free spot in RT and place rt_entry there */ - for (unsigned i = 0; i < AODVV2_MAX_ROUTING_ENTRIES; i++) { - if (routing_table[i].addr._type == AF_UNSPEC) { - memcpy(&routing_table[i], entry, sizeof(struct aodvv2_routing_entry_t)); - return; - } - } -} - -struct aodvv2_routing_entry_t *routingtable_get_entry(struct netaddr *addr, - aodvv2_metric_t metricType) -{ - for (unsigned i = 0; i < AODVV2_MAX_ROUTING_ENTRIES; i++) { - _reset_entry_if_stale(i); - - if (!netaddr_cmp(&routing_table[i].addr, addr) - && routing_table[i].metricType == metricType) { - DEBUG("[routing] found entry for %s :", netaddr_to_string(&nbuf, addr)); -#if ENABLE_DEBUG - print_routingtable_entry(&routing_table[i]); -#endif - return &routing_table[i]; - } - } - return NULL; -} - -void routingtable_delete_entry(struct netaddr *addr, aodvv2_metric_t metricType) -{ - for (unsigned i = 0; i < AODVV2_MAX_ROUTING_ENTRIES; i++) { - _reset_entry_if_stale(i); - - if (!netaddr_cmp(&routing_table[i].addr, addr) - && routing_table[i].metricType == metricType) { - memset(&routing_table[i], 0, sizeof(routing_table[i])); - return; - } - } -} - -void routingtable_break_and_get_all_hopping_over(struct netaddr *hop, - struct unreachable_node unreachable_nodes[], - size_t *len) -{ - *len = 0; /* to be sure */ - - for (unsigned i = 0; i < AODVV2_MAX_ROUTING_ENTRIES; i++) { - _reset_entry_if_stale(i); - - if (netaddr_cmp(&routing_table[i].nextHopAddr, hop) == 0) { - if (routing_table[i].state == ROUTE_STATE_ACTIVE && - *len < AODVV2_MAX_UNREACHABLE_NODES) { - /* when the max number of unreachable nodes is reached we're screwed. - * the above check is just damage control. */ - unreachable_nodes[*len].addr = routing_table[i].addr; - unreachable_nodes[*len].seqnum = routing_table[i].seqnum; - - (*len)++; - DEBUG("\t[routing] unreachable node found: %s\n", netaddr_to_string(&nbuf, &routing_table[i].nextHopAddr)); - } - routing_table[i].state = ROUTE_STATE_INVALID; - DEBUG("\t[routing] number of unreachable nodes: %i\n", *len); - } - } -} - -/* - * Check if entry at index i is stale as described in Section 6.3. - * and clear the struct it fills if it is - */ -static void _reset_entry_if_stale(uint8_t i) -{ - vtimer_now(&now); - timex_t lastUsed, expirationTime; - - if (timex_cmp(routing_table[i].expirationTime, null_time) == 0) { - return; - } - - int state = routing_table[i].state; - lastUsed = routing_table[i].lastUsed; - expirationTime = routing_table[i].expirationTime; - - /* an Active route is considered to remain Active as long as it is used at least once - * during every ACTIVE_INTERVAL. When a route is no longer Active, it becomes an Idle route. */ - - /* if the node is younger than the active interval, don't bother */ - if (timex_cmp(now, active_interval) < 0) { - return; - } - - if ((state == ROUTE_STATE_ACTIVE) && - (timex_cmp(timex_sub(now, active_interval), lastUsed) == 1)) { - DEBUG("\t[routing] route towards %s Idle\n", - netaddr_to_string(&nbuf, &routing_table[i].addr)); - routing_table[i].state = ROUTE_STATE_IDLE; - routing_table[i].lastUsed = now; /* mark the time entry was set to Idle */ - } - - /* After an Idle route remains Idle for MAX_IDLETIME, it becomes an Invalid route. */ - - /* if the node is younger than the expiration time, don't bother */ - if (timex_cmp(now, expirationTime) < 0) { - return; - } - - /* If Current_Time > Route.ExpirationTime, set Route.State := Invalid. */ - if ((state == ROUTE_STATE_IDLE) && - (timex_cmp(now, expirationTime) > 0)) { - DEBUG("\t[routing] route towards %s became Invalid\n", - netaddr_to_string(&nbuf, &routing_table[i].addr)); - routing_table[i].state = ROUTE_STATE_INVALID; - routing_table[i].lastUsed = now; /* mark the time entry was set to Invalid */ - } - - /* If (Current_Time - Route.LastUsed) > (ACTIVE_INTERVAL + MAX_IDLETIME), - * and if (Route.Timed == FALSE), set Route.State := Invalid. */ - if ((timex_cmp(timex_sub(now, lastUsed), timex_add(active_interval, max_idletime)) > 0) && - (state != ROUTE_STATE_TIMED)) { - routing_table[i].state = ROUTE_STATE_INVALID; - } - - /* After that time, old sequence number information is considered no longer - * valid and the Invalid route MUST BE expunged */ - if (timex_cmp(timex_sub(now, lastUsed), max_seqnum_lifetime) >= 0) { - DEBUG("\t[routing] Expunged routing table entry for %s at %i\n", - netaddr_to_string(&nbuf, &routing_table[i].addr), i); - memset(&routing_table[i], 0, sizeof(routing_table[i])); - } -} - -bool routingtable_offers_improvement(struct aodvv2_routing_entry_t *rt_entry, - struct node_data *node_data) -{ - /* (TODO only guaranteed for AODVV2_DEFAULT_METRIC_TYPE!)*/ - bool is_loop_free = node_data->metric <= rt_entry->metric; - int stale = seqnum_cmp(node_data->seqnum, rt_entry->seqnum); - - if ((stale == 1) /* New info is more recent and MUST be used */ - || ((stale == 0) && (node_data->metric < rt_entry->metric)) /* New info offers a better route and SHOULD be used */ - || ((stale == 0) && (node_data->metric >= rt_entry->metric) /* Route is not an improvement, */ - && (rt_entry->state == ROUTE_STATE_INVALID) /* but repairs an invalid route */ - && is_loop_free) /* and contains no loops */ - ) { - return true; - } - return false; -} - -void routingtable_fill_routing_entry_t_rreq(struct aodvv2_packet_data *packet_data, - struct aodvv2_routing_entry_t *rt_entry) -{ - rt_entry->addr = packet_data->origNode.addr; - rt_entry->seqnum = packet_data->origNode.seqnum; - rt_entry->nextHopAddr = packet_data->sender; - rt_entry->lastUsed = packet_data->timestamp; - rt_entry->expirationTime = timex_add(packet_data->timestamp, validity_t); - rt_entry->metricType = packet_data->metricType; - rt_entry->metric = packet_data->origNode.metric; - rt_entry->state = ROUTE_STATE_ACTIVE; -} - -void routingtable_fill_routing_entry_t_rrep(struct aodvv2_packet_data *packet_data, - struct aodvv2_routing_entry_t *rt_entry) -{ - rt_entry->addr = packet_data->targNode.addr; - rt_entry->seqnum = packet_data->targNode.seqnum; - rt_entry->nextHopAddr = packet_data->sender; - rt_entry->lastUsed = packet_data->timestamp; - rt_entry->expirationTime = timex_add(packet_data->timestamp, validity_t); - rt_entry->metricType = packet_data->metricType; - rt_entry->metric = packet_data->targNode.metric; - rt_entry->state = ROUTE_STATE_ACTIVE; -} - -#if TEST_SETUP -/* Write JSON representation of rt_entry to json_str */ -static void routingtable_entry_to_json(struct aodvv2_routing_entry_t *rt_entry, char* json_str) -{ - - struct netaddr_str nbuf_addr, nbuf_nexthop; - - sprintf(json_str,"{\"addr\": \"%s\", \"next_hop\": \"%s\", \"seqnum\": %d," - "\"metric\": %d, \"state\": %d}", - netaddr_to_string(&nbuf_addr, &rt_entry->addr), - netaddr_to_string(&nbuf_nexthop, &rt_entry->nextHopAddr), - rt_entry->seqnum, rt_entry->metric, rt_entry->state); -} -#endif - -static void print_json_added_rt_entry(struct aodvv2_routing_entry_t *entry) -{ -#if TEST_SETUP - char rt_entry_json [500]; - routingtable_entry_to_json(entry, rt_entry_json); - printf("{\"log_type\": \"added_rt_entry\", \"log_data\": %s}\n", rt_entry_json); -#else - (void) entry; /* silence compiler */ -#endif -} - -void print_routingtable(void) -{ - printf("===== BEGIN ROUTING TABLE ===================\n"); - for (int i = 0; i < AODVV2_MAX_ROUTING_ENTRIES; i++) { - /* route has been used before => non-empty entry */ - if (routing_table[i].lastUsed.seconds - || routing_table[i].lastUsed.microseconds) { - print_routingtable_entry(&routing_table[i]); - } - } - printf("===== END ROUTING TABLE =====================\n"); -} - -void print_routingtable_entry(struct aodvv2_routing_entry_t *rt_entry) -{ - struct netaddr_str nbuf; - - printf(".................................\n"); - printf("\t address: %s\n", netaddr_to_string(&nbuf, &(rt_entry->addr))); - printf("\t seqnum: %i\n", rt_entry->seqnum); - printf("\t nextHopAddress: %s\n", - netaddr_to_string(&nbuf, &(rt_entry->nextHopAddr))); - printf("\t lastUsed: %"PRIu32":%"PRIu32"\n", - rt_entry->lastUsed.seconds, rt_entry->lastUsed.microseconds); - printf("\t expirationTime: %"PRIu32":%"PRIu32"\n", - rt_entry->expirationTime.seconds, rt_entry->expirationTime.microseconds); - printf("\t metricType: %i\n", rt_entry->metricType); - printf("\t metric: %d\n", rt_entry->metric); - printf("\t state: %d\n", rt_entry->state); -} diff --git a/sys/net/routing/aodvv2/routingtable.h b/sys/net/routing/aodvv2/routingtable.h deleted file mode 100644 index c4bd9f5e2..000000000 --- a/sys/net/routing/aodvv2/routingtable.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * Copyright (C) 2014 Lotte Steenbrink - * - * 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 aodvv2 - * @{ - * - * @file - * @brief Cobbled-together routing table. - * - * @author Lotte Steenbrink - */ - -#ifndef AODVV2_ROUTINGTABLE_H_ -#define AODVV2_ROUTINGTABLE_H_ - -#include - -#include "common/netaddr.h" - -#include "aodvv2/types.h" -#include "constants.h" -#include "seqnum.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * A route table entry (i.e., a route) may be in one of the following states: - */ -enum aodvv2_routing_states -{ - ROUTE_STATE_ACTIVE, - ROUTE_STATE_IDLE, - ROUTE_STATE_INVALID, - ROUTE_STATE_TIMED -}; - -/** - * all fields of a routing table entry - */ -struct aodvv2_routing_entry_t -{ - struct netaddr addr; /**< IP address of this route's destination */ - aodvv2_seqnum_t seqnum; /**< The Sequence Number obtained from the - * last packet that updated the entry */ - struct netaddr nextHopAddr; /**< IP address of the the next hop towards - * the destination */ - timex_t lastUsed; /**< IP address of this route's destination */ - timex_t expirationTime; /**< Time at which this route expires */ - aodvv2_metric_t metricType; /**< Metric type of this route */ - uint8_t metric; /**< Metric value of this route*/ - uint8_t state; /**< State of this route - * (i.e. one of aodvv2_routing_states) */ -}; - -/** - * @brief Initialize routing table. - */ -void routingtable_init(void); - -/** - * @brief Get next hop towards dest. - * Returns NULL if dest is not in routing table. - * - * @param[in] dest Destination of the packet - * @param[in] metricType Metric Type of the desired route - * @return next hop towards dest if it exists, NULL otherwise - */ -struct netaddr *routingtable_get_next_hop(struct netaddr *dest, aodvv2_metric_t metricType); - -/** - * @brief Add new entry to routing table, if there is no other entry - * to the same destination. - * - * @param[in] entry The routing table entry to add - */ -void routingtable_add_entry(struct aodvv2_routing_entry_t *entry); - -/** - * @brief Retrieve pointer to a routing table entry. - * To edit, simply follow the pointer. - * Returns NULL if addr is not in routing table. - * - * @param[in] addr The address towards which the route should point - * @param[in] metricType Metric Type of the desired route - * @return Routing table entry if it exists, NULL otherwise - */ -struct aodvv2_routing_entry_t *routingtable_get_entry(struct netaddr *addr, aodvv2_metric_t metricType); - -/** - * @brief Delete routing table entry towards addr with metric type MetricType, - * if it exists. - * - * @param[in] addr The address towards which the route should point - * @param[in] metricType Metric Type of the desired route - */ -void routingtable_delete_entry(struct netaddr *addr, aodvv2_metric_t metricType); - -/** - * Find all routing table entries that use hop as their nextHopAddress, mark them - * as broken, write the active one into unreachable_nodes[] and increment len - * accordingly. (Sorry about the Name.) - * - * @param hop Address of the newly unreachable next hop - * @param unreachable_nodes[] array of newlu unreachable nodes to be filled. - * should be empty. - * @param len size_t* which will contain the length of - * unreachable_nodes[] after execution - */ -void routingtable_break_and_get_all_hopping_over(struct netaddr *hop, - struct unreachable_node unreachable_nodes[], - size_t *len); - -/** - * Check if the data of a RREQ or RREP offers improvement for an existing routing - * table entry. - * @param rt_entry the routing table entry to check - * @param node_data The data to check against. When handling a RREQ, - * the OrigNode's information (i.e. packet_data.origNode) - * must be passed. When handling a RREP, the - * TargNode's data (i.e. packet_data.targNode) must - * be passed. - */ -bool routingtable_offers_improvement(struct aodvv2_routing_entry_t *rt_entry, - struct node_data *node_data); - -/** - * Fills a routing table entry with the data of a RREQ. - * @param packet_data the RREQ's data - * @param rt_entry the routing table entry to fill - * @param link_cost the link cost for this RREQ - */ -void routingtable_fill_routing_entry_t_rreq(struct aodvv2_packet_data *packet_data, - struct aodvv2_routing_entry_t *rt_entry); - -/** - * Fills a routing table entry with the data of a RREP. - * @param packet_data the RREP's data - * @param rt_entry the routing table entry to fill - * @param link_cost the link cost for this RREP - */ -void routingtable_fill_routing_entry_t_rrep(struct aodvv2_packet_data *packet_data, - struct aodvv2_routing_entry_t *rt_entry); - -void print_routingtable(void); -void print_routingtable_entry(struct aodvv2_routing_entry_t *rt_entry); - -#ifdef __cplusplus -} -#endif - -#endif /* AODVV2_ROUTINGTABLE_H_*/ diff --git a/sys/net/routing/aodvv2/seqnum.c b/sys/net/routing/aodvv2/seqnum.c deleted file mode 100644 index 0cfec95f7..000000000 --- a/sys/net/routing/aodvv2/seqnum.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * Copyright (C) 2014 Lotte Steenbrink - * - * 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 aodvv2 - * @{ - * - * @file - * @brief aodvv2 sequence number - * - * @author Lotte Steenbrink - */ - - -#include "seqnum.h" - -#define ENABLE_DEBUG (0) -#include "debug.h" - -static aodvv2_seqnum_t seqnum; - -void seqnum_init(void) -{ - seqnum = 1; -} - -void seqnum_inc(void) -{ - if (seqnum == 65535) { - seqnum = 1; - } - else if (seqnum == 0) { - DEBUG("ERROR: SeqNum shouldn't be 0! \n"); /* TODO handle properly */ - } - else { - seqnum++; - } -} - -aodvv2_seqnum_t seqnum_get(void) -{ - return seqnum; -} diff --git a/sys/net/routing/aodvv2/seqnum.h b/sys/net/routing/aodvv2/seqnum.h deleted file mode 100644 index c47ee224e..000000000 --- a/sys/net/routing/aodvv2/seqnum.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * Copyright (C) 2014 Lotte Steenbrink - * - * 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 aodvv2 - * @{ - * - * @file - * @brief aodvv2 sequence number - * - * @author Lotte Steenbrink - */ - -#ifndef AODVV2_SEQNUM_H_ -#define AODVV2_SEQNUM_H_ - -#include - -#include "aodvv2/types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Initialize sequence number. - */ -void seqnum_init(void); - -/** - * @brief Get sequence number. - * - * @return sequence number - */ -aodvv2_seqnum_t seqnum_get(void); - -/** - * @brief Increment the sequence number by 1. - */ -void seqnum_inc(void); - -/** - * @brief Compare 2 sequence numbers. - * @param[in] s1 first sequence number - * @param[in] s2 second sequence number - * @return -1 when s1 is smaller, 0 if equal, 1 if s1 is bigger. - */ -static inline int seqnum_cmp(aodvv2_seqnum_t s1, aodvv2_seqnum_t s2) -{ - return s1 == s2 ? 0 : (s1 > s2 ? +1 : -1); -} - -#ifdef __cplusplus -} -#endif - -#endif /* AODVV2_SEQNUM_H_ */ diff --git a/sys/net/routing/aodvv2/utils.c b/sys/net/routing/aodvv2/utils.c deleted file mode 100644 index 62f4741b6..000000000 --- a/sys/net/routing/aodvv2/utils.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * Copyright (C) 2014 Lotte Steenbrink - * - * 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 aodvv2 - * @{ - * - * @file - * @brief client- and RREQ-table, ipv6 address representation converters - * - * @author Lotte Steenbrink - */ - -#include "utils.h" - -#include "aodv_debug.h" - -#define ENABLE_DEBUG (0) -#include "debug.h" - -/* Some aodvv2 utilities (mostly tables) */ -static mutex_t clientt_mutex; -static mutex_t rreqt_mutex; - -/* helper functions */ -static struct aodvv2_rreq_entry *_get_comparable_rreq(struct aodvv2_packet_data *packet_data); -static void _add_rreq(struct aodvv2_packet_data *packet_data); -static void _reset_entry_if_stale(uint8_t i); - -static struct netaddr client_table[AODVV2_MAX_CLIENTS]; -static struct aodvv2_rreq_entry rreq_table[AODVV2_RREQ_BUF]; - -#if ENABLE_DEBUG -static struct netaddr_str nbuf; -#endif -static timex_t null_time, now, _max_idletime; - - -void clienttable_init(void) -{ - mutex_lock(&clientt_mutex); - memset(&client_table, 0, sizeof(client_table)); - mutex_unlock(&clientt_mutex); - - AODV_DEBUG("client table initialized.\n"); -} - -void clienttable_add_client(struct netaddr *addr) -{ - if (clienttable_is_client(addr)){ - return; - } - - /*find free spot in client table and place client address there */ - mutex_lock(&clientt_mutex); - for (unsigned i = 0; i < AODVV2_MAX_CLIENTS; i++) { - if ((client_table[i]._type == AF_UNSPEC) && - (client_table[i]._prefix_len == 0)) { - client_table[i] = *addr; - AODV_DEBUG("clienttable: added client %s\n", - netaddr_to_string(&nbuf, addr)); - mutex_unlock(&clientt_mutex); - return; - } - } - AODV_DEBUG("Error: Client could not be added: Client table is full.\n"); - mutex_unlock(&clientt_mutex); -} - -bool clienttable_is_client(struct netaddr *addr) -{ - mutex_lock(&clientt_mutex); - for (unsigned i = 0; i < AODVV2_MAX_CLIENTS; i++) { - if (!netaddr_cmp(&client_table[i], addr)) { - mutex_unlock(&clientt_mutex); - return true; - } - } - mutex_unlock(&clientt_mutex); - return false; -} - -void clienttable_delete_client(struct netaddr *addr) -{ - if (!clienttable_is_client(addr)) { - return; - } - - mutex_lock(&clientt_mutex); - for (unsigned i = 0; i < AODVV2_MAX_CLIENTS; i++) { - if (!netaddr_cmp(&client_table[i], addr)) { - memset(&client_table[i], 0, sizeof(client_table[i])); - mutex_unlock(&clientt_mutex); - return; - } - } -} - -void rreqtable_init(void) -{ - mutex_lock(&rreqt_mutex); - null_time = timex_set(0, 0); - _max_idletime = timex_set(AODVV2_MAX_IDLETIME, 0); - - memset(&rreq_table, 0, sizeof(rreq_table)); - mutex_unlock(&rreqt_mutex); - AODV_DEBUG("RREQ table initialized.\n"); -} - -bool rreqtable_is_redundant(struct aodvv2_packet_data *packet_data) -{ - struct aodvv2_rreq_entry *comparable_rreq; - timex_t now; - bool result = false; - - mutex_lock(&rreqt_mutex); - comparable_rreq = _get_comparable_rreq(packet_data); - - /* if there is no comparable rreq stored, add one and return false */ - if (comparable_rreq == NULL) { - _add_rreq(packet_data); - } - else { - int seqnum_comparison = seqnum_cmp(packet_data->origNode.seqnum, comparable_rreq->seqnum); - - /* - * If two RREQs have the same - * metric type and OrigNode and Targnode addresses, the information from - * the one with the older Sequence Number is not needed in the table - */ - if (seqnum_comparison == -1) { - result = true; - } - - if (seqnum_comparison == 1) { - /* Update RREQ table entry with new seqnum and metric value */ - comparable_rreq->seqnum = packet_data->origNode.seqnum; - comparable_rreq->metric = packet_data->origNode.metric; - } - - /* - * in case they have the same Sequence Number, the one with the greater - * Metric value is not needed - */ - if (seqnum_comparison == 0) { - if (comparable_rreq->metric <= packet_data->origNode.metric) { - result = true; - } - /* Update RREQ table entry with new metric value */ - comparable_rreq->metric = packet_data->origNode.metric; - } - - /* Since we've changed RREQ info, update the timestamp */ - vtimer_now(&now); - comparable_rreq->timestamp = now; - } - - mutex_unlock(&rreqt_mutex); - return result; -} - -/* - * retrieve pointer to a comparable (according to Section 6.7.) - * RREQ table entry if it exists and NULL otherwise. - * Two AODVv2 RREQ messages are comparable if: - * - they have the same metric type - * - they have the same OrigNode and TargNode addresses - */ -static struct aodvv2_rreq_entry *_get_comparable_rreq(struct aodvv2_packet_data *packet_data) -{ - for (unsigned i = 0; i < AODVV2_RREQ_BUF; i++) { - _reset_entry_if_stale(i); - - if (!netaddr_cmp(&rreq_table[i].origNode, &packet_data->origNode.addr) - && !netaddr_cmp(&rreq_table[i].targNode, &packet_data->targNode.addr) - && rreq_table[i].metricType == packet_data->metricType) { - return &rreq_table[i]; - } - } - - return NULL; -} - - -static void _add_rreq(struct aodvv2_packet_data *packet_data) -{ - if (_get_comparable_rreq(packet_data)) { - return; - } - /*find empty rreq and fill it with packet_data */ - - for (unsigned i = 0; i < AODVV2_RREQ_BUF; i++) { - if (!rreq_table[i].timestamp.seconds && - !rreq_table[i].timestamp.microseconds) { - rreq_table[i].origNode = packet_data->origNode.addr; - rreq_table[i].targNode = packet_data->targNode.addr; - rreq_table[i].metricType = packet_data->metricType; - rreq_table[i].metric = packet_data->origNode.metric; - rreq_table[i].seqnum = packet_data->origNode.seqnum; - rreq_table[i].timestamp = packet_data->timestamp; - return; - } - } -} - -/* - * Check if entry at index i is stale and clear the struct it fills if it is - */ -static void _reset_entry_if_stale(uint8_t i) -{ - vtimer_now(&now); - - if (timex_cmp(rreq_table[i].timestamp, null_time) == 0) { - return; - } - timex_t expiration_time = timex_add(rreq_table[i].timestamp, _max_idletime); - if (timex_cmp(expiration_time, now) < 0) { - /* timestamp+expiration time is in the past: this entry is stale */ - DEBUG("\treset rreq table entry %s\n", - netaddr_to_string(&nbuf, &rreq_table[i].origNode)); - memset(&rreq_table[i], 0, sizeof(rreq_table[i])); - } -} - -void ipv6_addr_t_to_netaddr(ipv6_addr_t *src, struct netaddr *dst) -{ - dst->_type = AF_INET6; - dst->_prefix_len = AODVV2_RIOT_PREFIXLEN; - memcpy(dst->_addr, src, sizeof(dst->_addr)); -} - -void netaddr_to_ipv6_addr_t(struct netaddr *src, ipv6_addr_t *dst) -{ - memcpy(dst, src->_addr, sizeof(uint8_t) * NETADDR_MAX_LENGTH); -} diff --git a/sys/net/routing/aodvv2/utils.h b/sys/net/routing/aodvv2/utils.h deleted file mode 100644 index 2a23140e7..000000000 --- a/sys/net/routing/aodvv2/utils.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * Copyright (C) 2014 Lotte Steenbrink - * - * 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 aodvv2 - * @{ - * - * @file - * @brief client- and RREQ-table, ipv6 address representation converters - * - * @author Lotte Steenbrink - */ - -#ifndef AODVV2_UTILS_H_ -#define AODVV2_UTILS_H_ - -#include - -#include "ipv6.h" - -#include "common/netaddr.h" - -#include "aodvv2/types.h" -#include "constants.h" -#include "seqnum.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define AODVV2_MAX_CLIENTS 1 /** multiple clients are currently not supported. */ -#define AODVV2_RREQ_BUF 128 /** should be enough for now... */ -#define AODVV2_RREQ_WAIT_TIME 2 /** seconds */ -#define AODVV2_RIOT_PREFIXLEN 128 /** Prefix length of the IPv6 addresses - * used in the network served by AODVv2 () */ -/** - * @brief RREQ Table entry which stores all information about a RREQ that was received - * in order to avoid duplicates. - */ -struct aodvv2_rreq_entry -{ - struct netaddr origNode; /**< Node which originated the RREQ*/ - struct netaddr targNode; /**< Target (destination) of the RREQ */ - aodvv2_metric_t metricType; /**< Metric type of the RREQ */ - uint8_t metric; /**< Metric of the RREQ */ - aodvv2_seqnum_t seqnum; /**< Sequence number of the RREQ */ - timex_t timestamp; /**< Last time this entry was updated */ -}; - -/** - * Initialize table of clients that the router currently serves. - */ -void clienttable_init(void); - -/** - * Add client to the list of clients that the router currently serves. - * @param addr address of the client - * (Since the current version doesn't offer support for - * Client Networks, the prefixlen is currently ignored.) - */ -void clienttable_add_client(struct netaddr *addr); - -/** - * Find out if a client is in the list of clients that the router currently serves. - * @param addr address of the client in question - * (Since the current version doesn't offer support for - * Client Networks, the prefixlen is currently ignored.) - */ -bool clienttable_is_client(struct netaddr *addr); - -/** - * Delete a client from the list of clients that the router currently serves. - * @param addr address of the client to delete - * (Since the current version doesn't offer support for - * Client Networks, the prefixlen is currently ignored.) - */ -void clienttable_delete_client(struct netaddr *addr); - -/** - * Initialize RREQ table. - */ -void rreqtable_init(void); - -/** - * Check if a RREQ is redundant, i.e. was received from another node already. - * Behaves as described in Sections 5.7. and 7.6. - * @param packet_data data of the RREQ in question - * @return true if packet_data is redundant, false otherwise. - */ -bool rreqtable_is_redundant(struct aodvv2_packet_data *packet_data); - -/** - * Convert an IP stored as an ipv6_addr_t to a netaddr - * @param src ipv6_addr_t to convert - * @param dst (empty) netaddr to convert into - */ -void ipv6_addr_t_to_netaddr(ipv6_addr_t *src, struct netaddr *dst); - -/** - * Convert an IP stored as a netaddr to an ipv6_addr_t - * @param src (empty) netaddr to convert into - * @param dst ipv6_addr_t to convert - */ -void netaddr_to_ipv6_addr_t(struct netaddr *src, ipv6_addr_t *dst); - -#ifdef __cplusplus -} -#endif - -#endif /* AODVV2_UTILS_H_ */ diff --git a/sys/net/routing/aodvv2/writer.c b/sys/net/routing/aodvv2/writer.c deleted file mode 100644 index 275082425..000000000 --- a/sys/net/routing/aodvv2/writer.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * Copyright (C) 2014 Lotte Steenbrink - * - * 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 aodvv2 - * @{ - * - * @file - * @brief writer to create RFC5444 aodvv2 messages - * - * @author Lotte Steenbrink - */ - -#ifdef RIOT -#include "net_help.h" -#endif - -#include "writer.h" - -#include "aodv_debug.h" - -#define ENABLE_DEBUG (0) -#include "debug.h" - -static void _cb_addMessageHeader(struct rfc5444_writer *wr, - struct rfc5444_writer_message *message); - -static void _cb_rreq_addAddresses(struct rfc5444_writer *wr); -static void _cb_rrep_addAddresses(struct rfc5444_writer *wr); -static void _cb_rerr_addAddresses(struct rfc5444_writer *wr); - -struct rfc5444_writer writer; -static struct writer_target _target; - -static struct unreachable_node *_unreachable_nodes; -static size_t _num_unreachable_nodes; - -static uint8_t _msg_buffer[128]; -static uint8_t _msg_addrtlvs[1000]; -static uint8_t _packet_buffer[128]; - -static struct rfc5444_writer_message *_rreq_msg; -static struct rfc5444_writer_message *_rrep_msg; -static struct rfc5444_writer_message *_rerr_msg; - -/* - * message content provider that will add message TLVs, - * addresses and address block TLVs to all messages of type RREQ. - */ -static struct rfc5444_writer_content_provider _rreq_message_content_provider = -{ - .msg_type = RFC5444_MSGTYPE_RREQ, - .addAddresses = _cb_rreq_addAddresses, -}; - -/* declaration of all address TLVs added to the RREQ message */ -static struct rfc5444_writer_tlvtype _rreq_addrtlvs[] = -{ - [RFC5444_MSGTLV_ORIGSEQNUM] = { .type = RFC5444_MSGTLV_ORIGSEQNUM }, - [RFC5444_MSGTLV_METRIC] = { - .type = RFC5444_MSGTLV_METRIC, - .exttype = AODVV2_DEFAULT_METRIC_TYPE - }, -}; - -/* - * message content provider that will add message TLVs, - * addresses and address block TLVs to all messages of type RREQ. - */ -static struct rfc5444_writer_content_provider _rrep_message_content_provider = -{ - .msg_type = RFC5444_MSGTYPE_RREP, - .addAddresses = _cb_rrep_addAddresses, -}; - -/* declaration of all address TLVs added to the RREP message */ -static struct rfc5444_writer_tlvtype _rrep_addrtlvs[] = -{ - [RFC5444_MSGTLV_ORIGSEQNUM] = { .type = RFC5444_MSGTLV_ORIGSEQNUM}, - [RFC5444_MSGTLV_TARGSEQNUM] = { .type = RFC5444_MSGTLV_TARGSEQNUM}, - [RFC5444_MSGTLV_METRIC] = { - .type = RFC5444_MSGTLV_METRIC, - .exttype = AODVV2_DEFAULT_METRIC_TYPE - }, -}; - -/* - * message content provider that will add message TLVs, - * addresses and address block TLVs to all messages of type RREQ. - */ -static struct rfc5444_writer_content_provider _rerr_message_content_provider = -{ - .msg_type = RFC5444_MSGTYPE_RERR, - .addAddresses = _cb_rerr_addAddresses, -}; - -/* declaration of all address TLVs added to the RREP message */ -static struct rfc5444_writer_tlvtype _rerr_addrtlvs[] = -{ - [RFC5444_MSGTLV_UNREACHABLE_NODE_SEQNUM] = { .type = RFC5444_MSGTLV_UNREACHABLE_NODE_SEQNUM}, -}; - -/** - * Callback to define the message header for a RFC5444 RREQ message - * @param message - */ -static void -_cb_addMessageHeader(struct rfc5444_writer *wr, struct rfc5444_writer_message *message) -{ - AODV_DEBUG("%s()\n", __func__); - - /* no originator, no hopcount, has hoplimit, no seqno */ - rfc5444_writer_set_msg_header(wr, message, false, false, true, false); - rfc5444_writer_set_msg_hoplimit(wr, message, _target.packet_data.hoplimit); -} - -/** - * Callback to add addresses and address TLVs to a RFC5444 RREQ message - */ -static void -_cb_rreq_addAddresses(struct rfc5444_writer *wr) -{ - AODV_DEBUG("%s()\n", __func__); - - struct rfc5444_writer_address *origNode_addr; - - /* add origNode address (has no address tlv); is mandatory address */ - origNode_addr = rfc5444_writer_add_address(wr, _rreq_message_content_provider.creator, - &_target.packet_data.origNode.addr, true); - - /* add targNode address (has no address tlv); is mandatory address */ - rfc5444_writer_add_address(wr, _rreq_message_content_provider.creator, - &_target.packet_data.targNode.addr, true); - - /* add SeqNum TLV and metric TLV to origNode */ - /* TODO: allow_dup true or false? */ - rfc5444_writer_add_addrtlv(wr, origNode_addr, &_rreq_addrtlvs[RFC5444_MSGTLV_ORIGSEQNUM], - &_target.packet_data.origNode.seqnum, - sizeof(_target.packet_data.origNode.seqnum), false); - /* cppcheck: suppress false positive on non-trivially initialized arrays. - * this is a known bug: http://trac.cppcheck.net/ticket/5497 */ - /* cppcheck-suppress arrayIndexOutOfBounds */ - rfc5444_writer_add_addrtlv(wr, origNode_addr, &_rreq_addrtlvs[RFC5444_MSGTLV_METRIC], - &_target.packet_data.origNode.metric, - sizeof(_target.packet_data.origNode.metric), false); -} - -/** - * Callback to add addresses and address TLVs to a RFC5444 RREQ message - */ -static void -_cb_rrep_addAddresses(struct rfc5444_writer *wr) -{ - AODV_DEBUG("%s()\n", __func__); - - struct rfc5444_writer_address *origNode_addr, *targNode_addr; - - uint16_t origNode_seqnum = _target.packet_data.origNode.seqnum; - - uint16_t targNode_seqnum = seqnum_get(); - seqnum_inc(); - - uint8_t targNode_hopCt = _target.packet_data.targNode.metric; - - /* add origNode address (has no address tlv); is mandatory address */ - origNode_addr = rfc5444_writer_add_address(wr, _rrep_message_content_provider.creator, - &_target.packet_data.origNode.addr, true); - - /* add targNode address (has no address tlv); is mandatory address */ - targNode_addr = rfc5444_writer_add_address(wr, _rrep_message_content_provider.creator, - &_target.packet_data.targNode.addr, true); - - /* add OrigNode and TargNode SeqNum TLVs */ - /* TODO: allow_dup true or false? */ - rfc5444_writer_add_addrtlv(wr, origNode_addr, &_rrep_addrtlvs[RFC5444_MSGTLV_ORIGSEQNUM], - &origNode_seqnum, sizeof(origNode_seqnum), false); - rfc5444_writer_add_addrtlv(wr, targNode_addr, &_rrep_addrtlvs[RFC5444_MSGTLV_TARGSEQNUM], - &targNode_seqnum, sizeof(targNode_seqnum), false); - - /* Add Metric TLV to targNode Address */ - rfc5444_writer_add_addrtlv(wr, targNode_addr, &_rrep_addrtlvs[RFC5444_MSGTLV_METRIC], - &targNode_hopCt, sizeof(targNode_hopCt), false); -} - -/** - * Callback to add addresses and address TLVs to a RFC5444 RERR message - */ -static void -_cb_rerr_addAddresses(struct rfc5444_writer *wr) -{ - AODV_DEBUG("%s()\n", __func__); - - for (unsigned i = 0; i < _num_unreachable_nodes; i++) { - /* add unreachableNode addresses (has no address tlv); is mandatory address */ - struct rfc5444_writer_address *unreachableNode_addr = rfc5444_writer_add_address( - wr, _rerr_message_content_provider.creator, - &_unreachable_nodes[i].addr, true); - - /* add SeqNum TLV to unreachableNode */ - /* TODO: allow_dup true or false? */ - /* cppcheck: suppress false positive on non-trivially initialized arrays. - * this is a known bug: http://trac.cppcheck.net/ticket/5497 */ - /* cppcheck-suppress arrayIndexOutOfBounds */ - rfc5444_writer_add_addrtlv(wr, unreachableNode_addr, - &_rerr_addrtlvs[RFC5444_MSGTLV_UNREACHABLE_NODE_SEQNUM], - &_unreachable_nodes[i].seqnum, - sizeof(_unreachable_nodes[i].seqnum), false); - } -} - -void aodv_packet_writer_init(write_packet_func_ptr ptr) -{ - AODV_DEBUG("%s()\n", __func__); - - /* define interface for generating rfc5444 packets */ - _target.interface.packet_buffer = _packet_buffer; - _target.interface.packet_size = sizeof(_packet_buffer); - - /* set function to send binary packet content */ - _target.interface.sendPacket = ptr; - - /* define the rfc5444 writer */ - writer.msg_buffer = _msg_buffer; - writer.msg_size = sizeof(_msg_buffer); - writer.addrtlv_buffer = _msg_addrtlvs; - writer.addrtlv_size = sizeof(_msg_addrtlvs); - - /* initialize writer */ - rfc5444_writer_init(&writer); - - /* register a target (for sending messages to) in writer */ - rfc5444_writer_register_target(&writer, &_target.interface); - - /* register a message content providers for RREQ and RREP */ - rfc5444_writer_register_msgcontentprovider(&writer, &_rreq_message_content_provider, - _rreq_addrtlvs, ARRAYSIZE(_rreq_addrtlvs)); - rfc5444_writer_register_msgcontentprovider(&writer, &_rrep_message_content_provider, - _rrep_addrtlvs, ARRAYSIZE(_rrep_addrtlvs)); - rfc5444_writer_register_msgcontentprovider(&writer, &_rerr_message_content_provider, - _rerr_addrtlvs, ARRAYSIZE(_rerr_addrtlvs)); - - /* register rreq and rrep messages with 16 byte (ipv6) addresses. - * AddPacketHeader & addMessageHeader callbacks are triggered here. */ - _rreq_msg = rfc5444_writer_register_message(&writer, RFC5444_MSGTYPE_RREQ, - false, RFC5444_MAX_ADDRLEN); - _rrep_msg = rfc5444_writer_register_message(&writer, RFC5444_MSGTYPE_RREP, - false, RFC5444_MAX_ADDRLEN); - _rerr_msg = rfc5444_writer_register_message(&writer, RFC5444_MSGTYPE_RERR, - false, RFC5444_MAX_ADDRLEN); - - _rreq_msg->addMessageHeader = _cb_addMessageHeader; - _rrep_msg->addMessageHeader = _cb_addMessageHeader; - _rerr_msg->addMessageHeader = _cb_addMessageHeader; -} - -/** - * Send a RREQ. DO NOT use this function to dispatch packets from anything else - * than the sender_thread. To send RREQs, use aodv_send_rreq(). - * @param packet_data parameters of the RREQ - * @param next_hop Address the RREP is sent to - */ -void aodv_packet_writer_send_rreq(struct aodvv2_packet_data *packet_data, struct netaddr *next_hop) -{ - AODV_DEBUG("%s()\n", __func__); - - if ((packet_data == NULL) || (next_hop == NULL)) { - return; - } - - /* Make sure no other thread is using the writer right now */ - memcpy(&_target.packet_data, packet_data, sizeof(struct aodvv2_packet_data)); - _target.type = RFC5444_MSGTYPE_RREQ; - _target.packet_data.hoplimit = packet_data->hoplimit; - - /* set address to which the write_packet callback should send our RREQ */ - memcpy(&_target.target_addr, next_hop, sizeof (struct netaddr)); - - rfc5444_writer_create_message_alltarget(&writer, RFC5444_MSGTYPE_RREQ); - rfc5444_writer_flush(&writer, &_target.interface, false); -} - - -/** - * Send a RREP. DO NOT use this function to dispatch packets from anything else - * than the sender_thread. To send RREPs, use aodv_send_rrep(). - * @param packet_data parameters of the RREP - * @param next_hop Address the RREP is sent to - */ -void aodv_packet_writer_send_rrep(struct aodvv2_packet_data *packet_data, struct netaddr *next_hop) -{ - AODV_DEBUG("%s()\n", __func__); - - if ((packet_data == NULL) || (next_hop == NULL)) { - return; - } - - memcpy(&_target.packet_data, packet_data, sizeof(struct aodvv2_packet_data)); - _target.type = RFC5444_MSGTYPE_RREP; - _target.packet_data.hoplimit = AODVV2_MAX_HOPCOUNT; - - /* set address to which the write_packet callback should send our RREQ */ - memcpy(&_target.target_addr, next_hop, sizeof (struct netaddr)); - - rfc5444_writer_create_message_alltarget(&writer, RFC5444_MSGTYPE_RREP); - rfc5444_writer_flush(&writer, &_target.interface, false); -} - -/** - * Send a RERR. DO NOT use this function to dispatch packets from anything else - * than the sender_thread. To send RERRs, use aodv_send_rerr(). - * @param unreachable_nodes[] array containing all newly unreachable nodes. each - * in a struct unreachable_node - * @param len length of unreachable_nodes[] - * @param hoplimit the message's hop limit - * @param next_hop Address the RREP is sent to - */ -void aodv_packet_writer_send_rerr(struct unreachable_node unreachable_nodes[], size_t len, - int hoplimit, struct netaddr *next_hop) -{ - AODV_DEBUG("%s()\n", __func__); - - if ((unreachable_nodes == NULL) || (next_hop == NULL)) { - return; - } - - _target.packet_data.hoplimit = hoplimit; - _target.type = RFC5444_MSGTYPE_RERR; - _unreachable_nodes = unreachable_nodes; - _num_unreachable_nodes = len; - - /* set address to which the write_packet callback should send our RREQ */ - memcpy(&_target.target_addr, next_hop, sizeof (struct netaddr)); - - rfc5444_writer_create_message_alltarget(&writer, RFC5444_MSGTYPE_RERR); - rfc5444_writer_flush(&writer, &_target.interface, false); -} - -void aodv_packet_writer_cleanup(void) -{ - AODV_DEBUG("%s()\n", __func__); - rfc5444_writer_cleanup(&writer); -} diff --git a/sys/net/routing/aodvv2/writer.h b/sys/net/routing/aodvv2/writer.h deleted file mode 100644 index 24fa54386..000000000 --- a/sys/net/routing/aodvv2/writer.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * Copyright (C) 2014 Lotte Steenbrink - * - * 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 aodvv2 - * @{ - * - * @file - * @brief writer to create RFC5444 aodvv2 messages - * - * @author Lotte Steenbrink - */ - -#ifndef AODVV2_WRITER_H_ -#define AODVV2_WRITER_H_ - -#include "common/netaddr.h" -#include "rfc5444/rfc5444_writer.h" -#include "mutex.h" - -#include "constants.h" -#include "seqnum.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Wrapper for the rfc5444_writer_target that the _write_packet() callback receives. - * _write_packet() needs to know the type, payload and target address - * of the RFC5444 message to be sent as well, but the oonf api does not - * offer this feature. Having this wrapper enables the use of the - * container_of macro to fetch this information. - * It is hacky, but it does the trick. - */ -struct writer_target -{ - struct rfc5444_writer_target interface; /**< Interface for generating rfc5444 packets */ - struct netaddr target_addr; /**< Address to which the packet should be sent */ - struct aodvv2_packet_data packet_data; /**< Payload of the AODVv2 Message */ - int type; /**< Type of the AODVv2 Message (i.e. rfc5444_msg_type) */ -}; - -/** - * @brief oonf api voodo. Pointer to a callback function which is passed to - * writer_init() and called when the packet is ready to send. - */ -typedef void (*write_packet_func_ptr)( - struct rfc5444_writer *wr, struct rfc5444_writer_target *iface, - void *buffer, size_t length); - -/** - * @brief Initialize RFC5444 writer - * @param ptr pointer to "send_packet" callback - */ -void aodv_packet_writer_init(write_packet_func_ptr ptr); - -/** - * @brief Clean up after the RFC5444 writer - */ -void aodv_packet_writer_cleanup(void); - -/** - * @brief Send a RREQ. DO NOT use this function to dispatch packets from anything else - * than the sender_thread. To send RREQs, use aodv_send_rreq(). - * @param packet_data parameters of the RREQ - * @param next_hop Address the RREP is sent to - */ -void aodv_packet_writer_send_rreq(struct aodvv2_packet_data *packet_data, struct netaddr *next_hop); - -/** - * @brief Send a RREP. DO NOT use this function to dispatch packets from anything else - * than the sender_thread. To send RREPs, use aodv_send_rrep(). - * @param packet_data parameters of the RREP - * @param next_hop Address the RREP is sent to - */ -void aodv_packet_writer_send_rrep(struct aodvv2_packet_data *packet_data, struct netaddr *next_hop); - -/** - * @brief Send a RERR. DO NOT use this function to dispatch packets from anything else - * than the sender_thread. To send RERRs, use aodv_send_rerr(). - * @param unreachable_nodes[] array containing all newly unreachable nodes. each - * in a struct unreachable_node - * @param len length of unreachable_nodes[] - * @param hoplimit the message's hop limit - * @param next_hop Address the RREP is sent to - */ -void aodv_packet_writer_send_rerr(struct unreachable_node unreachable_nodes[], size_t len, - int hoplimit, struct netaddr *next_hop); - -#ifdef __cplusplus -} -#endif - -#endif /* AODVV2_WRITER_H_ */ diff --git a/tests/aodvv2/Makefile b/tests/aodvv2/Makefile deleted file mode 100644 index 81ef180a8..000000000 --- a/tests/aodvv2/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -# name of your application -APPLICATION = aodvv2_tests -include ../Makefile.tests_common - -# If no BOARD is found in the environment, use this default: -BOARD ?= native - -# This test has not been verified to work on any other boards-- proceed with caution. -BOARD_WHITELIST := native - -# This has to be the absolute path to the RIOT base directory: -RIOTBASE ?= $(CURDIR)/../.. - -# Comment this out to disable code in RIOT that does safety checking -# which is not needed in a production environment but helps in the -# development process: -CFLAGS += -DDEVELHELP -CFLAGS += -DRIOT -CFLAGS += -DFIB_DEVEL_HELPER - -# Change this to 0 show compiler invocation lines by default: -QUIET ?= 1 - -# Modules to include -USEMODULE += defaulttransceiver -USEMODULE += aodvv2 -USEMODULE += udp - -export INCLUDES += -I$(RIOTBASE)/sys/net/routing/aodvv2/ - -include $(RIOTBASE)/Makefile.include diff --git a/tests/aodvv2/aodv_fib_tests.c b/tests/aodvv2/aodv_fib_tests.c deleted file mode 100644 index c2c7bef25..000000000 --- a/tests/aodvv2/aodv_fib_tests.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (C) 2014 Hochschule für Angewandte Wissenschaften Hamburg (HAW) - * Copyright (C) 2015 Lotte Steenbrink - * - * 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 tests - * @{ - * - * @file - * @brief tests for the interaction between AODVv2 and the FIB - * - * @author Lotte Steenbrink - * - * @} - */ - -#include -#include - -#include "aodv_fib_tests.h" -#include "aodv_tests.h" - -#include "common/autobuf.h" -#include "rfc5444/rfc5444_writer.h" -#include "rfc5444/rfc5444_print.h" -#include "ng_fib.h" - -#include "reader.h" -#include "utils.h" - - -/* make sure packet is not rejected because "sender" is not in the neighbor cache */ -static void _aodv_test_add_to_nc(struct netaddr *sender_na){ - ipv6_addr_t sender; - - netaddr_to_ipv6_addr_t(sender_na, &sender); - /* TODO: isrouter = 1 correct? */ - ndp_neighbor_cache_add(aodvv2_iface_id, &sender, &sender.uint16[7], 2, 1, - NDP_NCE_STATUS_REACHABLE, NDP_NCE_TYPE_TENTATIVE, 0xffff); -} - -/* Handle RREQ with no anomalies */ -static void aodv_test_add_to_fib_regular_rreq(void) -{ - printf("\n============= Handling regular RREQ ================================\n"); - ipv6_addr_t next_hop; - kernel_pid_t iface_id; - size_t next_hop_size = sizeof(ipv6_addr_t); - uint32_t next_hop_flags = 0; - - _aodv_test_add_to_nc(aodv_test_plain_rreq.sender); - aodv_packet_reader_handle_packet((void *) aodv_test_plain_rreq.buffer, - aodv_test_plain_rreq.length, - aodv_test_plain_rreq.sender); - - printf("Checking FIB ...\n"); - - /* Check if route back to origaddr was created */ - int fib_success = fib_get_next_hop(&iface_id, &next_hop.uint8[0], &next_hop_size, - &next_hop_flags, aodvv2_test_origaddr._addr, - sizeof(ipv6_addr_t), 0); - assert(0 == fib_success); - - printf("Done.\n"); -} - -/* Handle RREQ with no anomalies */ -static void aodv_test_add_to_fib_regular_rrep(void) -{ - printf("\n============= Handling regular RREP ================================\n"); - ipv6_addr_t next_hop; - kernel_pid_t iface_id; - size_t next_hop_size = sizeof(ipv6_addr_t); - uint32_t next_hop_flags = 0; - timex_t now; - - _aodv_test_add_to_nc(aodv_test_plain_rrep.sender); - - /* Make sure route back is known TODO make this global too?!*/ - vtimer_now(&now); - struct aodvv2_routing_entry_t tmp_rt_entry = { - .addr = aodvv2_test_origaddr, - .seqnum = 1, - .nextHopAddr = aodvv2_test_sender_oa, - .lastUsed = now, - .expirationTime = timex_add(now, - timex_set(AODVV2_ACTIVE_INTERVAL + AODVV2_MAX_IDLETIME, 0)), - .metricType = AODVV2_DEFAULT_METRIC_TYPE, - .metric = 2, - .state = ROUTE_STATE_ACTIVE, - }; - routingtable_add_entry(&tmp_rt_entry); - - aodv_packet_reader_handle_packet((void *) aodv_test_plain_rrep.buffer, - aodv_test_plain_rrep.length, - aodv_test_plain_rrep.sender); - printf("Checking FIB ...\n"); - - /* Check if route back to origaddr was created */ - int fib_success = fib_get_next_hop(&iface_id, &next_hop.uint8[0], &next_hop_size, - &next_hop_flags, aodvv2_test_targaddr._addr, - sizeof(ipv6_addr_t), 0); - assert(0 == fib_success); - printf("Done.\n"); -} - -static void aodv_test_update_fib_regular_rreq(void) -{ - printf("\n============= Handling more recent RREQ ============================\n"); - timex_t lifetime, now; - - printf("Checking FIB ...\n"); - aodv_packet_reader_handle_packet((void *) aodv_test_more_recent_rreq.buffer, - aodv_test_more_recent_rreq.length, - aodv_test_more_recent_rreq.sender); - - assert(0 == fib_devel_get_lifetime(&lifetime, aodvv2_test_origaddr._addr, sizeof(ipv6_addr_t))); - - /* assuming some ms passed during these operations... */ - vtimer_now(&now); - timex_t cmp_lifetime = timex_add(now, timex_set(0, 900000)); - assert(1 == timex_cmp(lifetime, cmp_lifetime)); - - printf("Done. \n"); -} - -static void aodv_test_update_fib_regular_rrep(void) -{ - printf("\n============= Handling more recent RREP ============================\n"); - timex_t lifetime, now; - - printf("Checking FIB ...\n"); - aodv_packet_reader_handle_packet((void *) aodv_test_more_recent_rrep.buffer, - aodv_test_more_recent_rrep.length, - aodv_test_more_recent_rrep.sender); - - assert(0 == fib_devel_get_lifetime(&lifetime, aodvv2_test_targaddr._addr, sizeof(ipv6_addr_t))); - - /* assuming some ms passed during these operations... */ - vtimer_now(&now); - timex_t cmp_lifetime = timex_add(now, timex_set(0, 900000)); - assert(1 == timex_cmp(lifetime, cmp_lifetime)); - printf("Done.\n"); -} - -static void aodv_test_route_expired(void) -{ - printf("\n============= testing if route vanishes after expiring ===========\n"); - kernel_pid_t iface_id; - uint32_t next_hop_flags = 0; - size_t next_hop_size = sizeof(ipv6_addr_t); - ipv6_addr_t next_hop; - - printf("waiting until route expires... (about 4.5 minutes)\n"); - /* TODO: use MAXTIME */ - sleep(AODVV2_ACTIVE_INTERVAL + AODVV2_MAX_IDLETIME); - printf("Checking FIB ...\n"); - - /* Check if route back to origaddr was created */ - int fib_success = fib_get_next_hop(&iface_id, &next_hop.uint8[0], &next_hop_size, - &next_hop_flags, aodvv2_test_origaddr._addr, - sizeof(ipv6_addr_t), 0); - assert( 0 != fib_success); - - printf("Done.\n"); - -} - -void aodv_test_add_to_fib(void) -{ - /* overwrite the aodvv2 packet writer so that messages aren't actually swnt */ - aodv_packet_writer_init(aodv_test_drop_packet); - - printf("Starting tests...\n"); - aodv_test_add_to_fib_regular_rreq(); - sleep(5); - aodv_test_update_fib_regular_rreq(); - sleep(5); - aodv_test_add_to_fib_regular_rrep(); - sleep(5); - aodv_test_update_fib_regular_rrep(); - sleep(5); - aodv_test_route_expired(); - printf("All done!\n"); -} diff --git a/tests/aodvv2/aodv_fib_tests.h b/tests/aodvv2/aodv_fib_tests.h deleted file mode 100644 index 53811114c..000000000 --- a/tests/aodvv2/aodv_fib_tests.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2014 Hochschule für Angewandte Wissenschaften Hamburg (HAW) - * Copyright (C) 2015 Lotte Steenbrink - * - * 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 tests - * @{ - * - * @file - * @brief tests for the interaction between AODVv2 and the FIB - * - * @author Lotte Steenbrink - * - * @} - */ - -#ifndef AODV_FIB_TESTS_H_ -#define AODV_FIB_TESTS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -void aodv_test_add_to_fib(void); - -#ifdef __cplusplus -} -#endif - -#endif /* AODV_FIB_TESTS_H_ */ diff --git a/tests/aodvv2/aodv_tests.h b/tests/aodvv2/aodv_tests.h deleted file mode 100644 index 61c02aff0..000000000 --- a/tests/aodvv2/aodv_tests.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2014 Hochschule für Angewandte Wissenschaften Hamburg (HAW) - * Copyright (C) 2015 Lotte Steenbrink - * - * 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 tests - * @{ - * - * @file - * @brief constants and global variables for AODVv2 tests - * - * @author Lotte Steenbrink - * - * @} - */ - -#ifndef AODV_TESTS_H_ -#define AODV_TESTS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "udp.h" - -#include "rfc5444/rfc5444_writer.h" - -#define AODV_TEST_MSGBUF_MAX (500) - -typedef struct -{ - unsigned char buffer[AODV_TEST_MSGBUF_MAX]; - uint8_t length; - struct netaddr* sender; -} aodvv2_test_msg; - - -extern radio_address_t aodvv2_iface_id; - -extern aodvv2_test_msg aodv_test_plain_rreq; -extern aodvv2_test_msg aodv_test_more_recent_rreq; -extern aodvv2_test_msg aodv_test_plain_rrep; -extern aodvv2_test_msg aodv_test_more_recent_rrep; - -/* -Messages will always be sent/stored along the following path: -OrigAddr -> sender_oa -> TESTNODE -> sender_ta -> TargAddr -OrigAddr <- sender_oa <- TESTNODE <- sender_ta <- TargAddr */ -extern struct netaddr aodvv2_test_origaddr; -extern struct netaddr aodvv2_test_sender_oa; -extern struct netaddr aodvv2_test_sender_ta; -extern struct netaddr aodvv2_test_targaddr; - -/* callback for the rfc5444 packet writer. can be set with aodv_packet_writer_init() - * To enforce the dropping of all control packets (and reduce overhead) */ -void aodv_test_drop_packet(struct rfc5444_writer *wr __attribute__ ((unused)), - struct rfc5444_writer_target *iface __attribute__((unused)), - void *buffer, size_t length); - -#ifdef __cplusplus -} -#endif - -#endif /* AODV_FIB_TESTS_H_ */ diff --git a/tests/aodvv2/aodv_writer_tests.c b/tests/aodvv2/aodv_writer_tests.c deleted file mode 100644 index f8f96d04f..000000000 --- a/tests/aodvv2/aodv_writer_tests.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2014 Hochschule für Angewandte Wissenschaften Hamburg (HAW) - * Copyright (C) 2015 Lotte Steenbrink - * - * 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 tests - * @{ - * - * @file - * @brief tests for the AODVv2 writer - * - * @author Lotte Steenbrink - * - * @} - */ - -#include -#include -#include -#include - -#include "aodv_writer_tests.h" -#include "aodv_tests.h" - -#include "aodv.h" -#include "aodvv2/aodvv2.h" - -#include "common/autobuf.h" -#include "rfc5444/rfc5444_writer.h" -#include "rfc5444/rfc5444_print.h" -#include "writer.h" -#include "thread.h" - -aodvv2_test_msg aodv_test_plain_rreq; -aodvv2_test_msg aodv_test_more_recent_rreq; -aodvv2_test_msg aodv_test_plain_rrep; -aodvv2_test_msg aodv_test_more_recent_rrep; - -static aodvv2_test_msg* current_msg; /* Point to the buffer the current message should be written to. - * Yes, this is awful, but I fear the oonf_apis - * callback infrastructure leaves me no other choice... - * Sorry. :( */ - -/* All the test data */ -static timex_t now, validity_t; - -static struct aodvv2_packet_data plain_rreq_msg, plain_rrep_msg; - -static int aodv_test_writer_init_data(void) -{ - vtimer_now(&now); - validity_t = timex_set(AODVV2_ACTIVE_INTERVAL + AODVV2_MAX_IDLETIME, 0); - - plain_rreq_msg = (struct aodvv2_packet_data) { - .hoplimit = AODVV2_MAX_HOPCOUNT, - .sender = aodvv2_test_sender_oa, - .metricType = AODVV2_DEFAULT_METRIC_TYPE, - .origNode = { - .addr = aodvv2_test_origaddr, - .metric = 2, - .seqnum = 1, - }, - .targNode = { - .addr = aodvv2_test_targaddr, - .metric = 12, - .seqnum = 1, - }, - .timestamp = now, - }; - - vtimer_now(&now); - plain_rrep_msg = (struct aodvv2_packet_data) { - .hoplimit = AODVV2_MAX_HOPCOUNT, - .sender = aodvv2_test_sender_ta, - .metricType = AODVV2_DEFAULT_METRIC_TYPE, - .origNode = { - .addr = aodvv2_test_origaddr, - .metric = 4, - .seqnum = 1, - }, - .targNode = { - .addr = aodvv2_test_targaddr, - .metric = 2, - .seqnum = 2, - }, - .timestamp = now, - }; - - return 0; -} - -static void aodv_test_write_packet(struct rfc5444_writer *wr __attribute__ ((unused)), - struct rfc5444_writer_target *iface __attribute__((unused)), - void *buffer, size_t length) -{ - printf("Writing message to buffer\n"); - /* make sure buffer is clear */ - memcpy(current_msg->buffer, buffer, length); - current_msg->length = length; - printf("Done.\n"); -} - -static void aodv_test_writer_write_new_rreq(void) -{ - current_msg = &aodv_test_plain_rreq; - current_msg->sender = &aodvv2_test_sender_oa; - aodv_send_rreq(&plain_rreq_msg); -} - -static void aodv_test_writer_write_more_recent_rreq(void) -{ - plain_rreq_msg.origNode.seqnum += 1; - current_msg = &aodv_test_more_recent_rreq; - current_msg->sender = &aodvv2_test_sender_oa; - aodv_send_rreq(&plain_rreq_msg); -} - -static void aodv_test_writer_write_new_rrep(void) -{ - current_msg = &aodv_test_plain_rrep; - current_msg->sender = &aodvv2_test_sender_ta; - aodv_send_rrep(&plain_rrep_msg, &aodvv2_test_sender_ta); -} - -static void aodv_test_writer_write_more_recent_rrep(void) -{ - plain_rrep_msg.targNode.seqnum += 1; - current_msg = &aodv_test_more_recent_rrep; - current_msg->sender = &aodvv2_test_sender_ta; - aodv_send_rrep(&plain_rrep_msg, &aodvv2_test_sender_ta); -} - -/* Store packets in buffers that we can use them for testing */ -void write_packets_to_buf(void) -{ - printf("============= Preparing to write packets to buffers ==================\n"); - - /* Make sure the threads are up and running */ - sleep(2); - - if (0 != aodv_test_writer_init_data()){ - printf ("FAILED: unable to init data!\n"); - return; - } - /* overwrite the aodvv2 packet writer */ - aodv_packet_writer_init(aodv_test_write_packet); - - aodv_test_writer_write_new_rreq(); - - /* make sure sender_thread is done */ - sleep(2); - aodv_test_writer_write_more_recent_rreq(); - - /* make sure sender_thread is done */ - sleep(2); - aodv_test_writer_write_new_rrep(); - - /* make sure sender_thread is done */ - sleep(2); - aodv_test_writer_write_more_recent_rrep(); - - /* give current writer time to finish and init aodvv2 again cleanly - * to undo the change to the aodv_packet_writer callback */ - sleep(2); - aodv_init(); -} diff --git a/tests/aodvv2/aodv_writer_tests.h b/tests/aodvv2/aodv_writer_tests.h deleted file mode 100644 index 80d48876e..000000000 --- a/tests/aodvv2/aodv_writer_tests.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2014 Hochschule für Angewandte Wissenschaften Hamburg (HAW) - * Copyright (C) 2015 Lotte Steenbrink - * - * 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 tests - * @{ - * - * @file - * @brief tests for the AODVv2 writer - * - * @author Lotte Steenbrink - * - * @} - */ - -#ifndef AODV_WRITER_TESTS_H_ -#define AODV_WRITER_TESTS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -void write_packets_to_buf(void); - -#ifdef __cplusplus -} -#endif - -#endif /* AODV_WRITER_TESTS_H_ */ diff --git a/tests/aodvv2/main.c b/tests/aodvv2/main.c deleted file mode 100644 index 6ec86e6d1..000000000 --- a/tests/aodvv2/main.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2014 Hochschule für Angewandte Wissenschaften Hamburg (HAW) - * Copyright (C) 2015 Lotte Steenbrink - * Copyright (C) 2014 Martin Landsmann - * - * 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 tests - * @{ - * - * @file - * @brief tests for the interaction between AODVv2 and the FIB - * - * @author Lotte Steenbrink - * @author Martin Landsmann - * - * @} - */ - -#include -#include - -#include "udp.h" -#include "thread.h" - -#include "aodvv2/aodvv2.h" - -#include "aodv_writer_tests.h" -#include "aodv_fib_tests.h" -#include "aodv_tests.h" - -#define AODVV2_IFACE (0) /**< The used Trasmssion device */ - -/** The node IPv6 address */ -ipv6_addr_t myaddr; - -radio_address_t aodvv2_iface_id; -struct netaddr aodvv2_test_sender_oa, aodvv2_test_sender_ta, aodvv2_test_origaddr, aodvv2_test_targaddr; - -/** -* @brief prepares this node -* @return 0 on success -*/ -static int aodvv2_setup_node(void) -{ - /* setup the radio interface */ - if( net_if_set_src_address_mode(AODVV2_IFACE, NET_IF_TRANS_ADDR_M_SHORT) != 1 ) { - return -1; - } - - aodvv2_iface_id = net_if_get_hardware_address(AODVV2_IFACE); - if( aodvv2_iface_id == 0 ) { - return -1; - } - - /* choose addresses */ - ipv6_addr_init(&myaddr, 0x2015, 0x3, 0x18, 0x1111, 0x0, 0x0, 0x0, aodvv2_iface_id); - - /* and set it */ - if( ipv6_net_if_add_addr(AODVV2_IFACE, &myaddr, NDP_ADDR_STATE_PREFERRED, 0, 0, 0) != 1) { - return -1; - } - - return 0; -} - -/** -* @brief init data that needs to be globally known -*/ -static int aodvv2_init_testdata(void) -{ - if( netaddr_from_string(&aodvv2_test_origaddr, "::10") == -1 ) { - return -1; - } - - if( netaddr_from_string(&aodvv2_test_sender_oa, "::11") == -1 ) { - return -1; - } - - if( netaddr_from_string(&aodvv2_test_sender_ta, "::12") == -1 ) { - return -1; - } - - if( netaddr_from_string(&aodvv2_test_targaddr, "::13") == -1 ) { - return -1; - } - return 0; -} - -void aodv_test_drop_packet(struct rfc5444_writer *wr __attribute__ ((unused)), - struct rfc5444_writer_target *iface __attribute__((unused)), - void *buffer, size_t length) -{ - (void) buffer; - (void) length; -} - -int main(void) -{ - if( aodvv2_init_testdata() != 0 ) { - return -1; - } - - if( aodvv2_setup_node() != 0 ) { - return -1; - } - - aodv_init(); - - write_packets_to_buf(); - - sleep(5); - - /* TODO: - - use route and see if it updates the lifetime - */ - aodv_test_add_to_fib(); - - return 0; -}