/* * 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; }
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); } } }
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 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; } } }
static enum rfc5444_result _cb_rerr_blocktlv_addresstlvs_okay(struct rfc5444_reader_tlvblock_context *cont) { #if ENABLE_DEBUG /* cppcheck-suppress unusedVariable as nbuf is needed by VDEBUG. */ struct netaddr_str nbuf; #endif struct aodvv2_routing_entry_t *unreachable_entry; struct rfc5444_reader_tlvblock_entry *tlv; VDEBUG("%s()\n", __func__); VDEBUG("\tmessage type: %d\n", cont->type); VDEBUG("\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) { VDEBUG("\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) { VDEBUG("\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; }
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; } } }
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; }
static void test_netaddr_create_host(void) { struct netaddr netmask, host, result; struct netaddr_str buf1, buf2, buf3; char buffer1[17], buffer2[17]; size_t i; memset(buffer1, 255, sizeof(buffer1)); memset(buffer2, 0, sizeof(buffer2)); START_TEST(); for (i=0; i<ARRAYSIZE(_create_host_test); i++) { CHECK_TRUE(netaddr_from_string(&netmask, _create_host_test[i].netmask) == 0, "error in parsing netmask %"PRINTF_SIZE_T_SPECIFIER" %s", i, _create_host_test[i].netmask); CHECK_TRUE(netaddr_from_string(&result, _create_host_test[i].result) == 0, "error in parsing result %"PRINTF_SIZE_T_SPECIFIER" %s", i, _create_host_test[i].result); if (_create_host_test[i].buf_len >= 0) { CHECK_TRUE(netaddr_create_host_bin(&host, &netmask, buffer1, _create_host_test[i].buf_len) == 0, "error in creating host %"PRINTF_SIZE_T_SPECIFIER" %s with length %d", i, netaddr_to_string(&buf1, &netmask), _create_host_test[i].buf_len); } else { CHECK_TRUE(netaddr_create_host_bin(&host, &netmask, buffer2, -_create_host_test[i].buf_len) == 0, "error in creating host %"PRINTF_SIZE_T_SPECIFIER" %s with length %d", i, netaddr_to_string(&buf1, &netmask), _create_host_test[i].buf_len); } CHECK_TRUE(netaddr_cmp(&host, &result) == 0, "Error, host %"PRINTF_SIZE_T_SPECIFIER" %s != result %s (netmask %s, len=%d)", i, netaddr_to_string(&buf1, &host), netaddr_to_string(&buf2, &result), netaddr_to_string(&buf3, &netmask), _create_host_test[i].buf_len); } END_TEST(); }