Esempio n. 1
0
/*
 * 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;
}
Esempio n. 2
0
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);
        }
    }
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
        }
    }
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
        }
    }
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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();
}