qemu/slirp/ndp_table.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2013
   3 * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
   4 */
   5
   6#include "qemu/osdep.h"
   7#include "qemu-common.h"
   8#include "slirp.h"
   9
  10void ndp_table_add(Slirp *slirp, struct in6_addr ip_addr,
  11                    uint8_t ethaddr[ETH_ALEN])
  12{
  13    NdpTable *ndp_table = &slirp->ndp_table;
  14    int i;
  15
  16    DEBUG_CALL("ndp_table_add");
  17#if !defined(_WIN32) || (_WIN32_WINNT >= 0x0600)
  18    char addrstr[INET6_ADDRSTRLEN];
  19    inet_ntop(AF_INET6, &(ip_addr), addrstr, INET6_ADDRSTRLEN);
  20    DEBUG_ARG("ip = %s", addrstr);
  21#endif
  22    DEBUG_ARGS((dfd, " hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
  23                ethaddr[0], ethaddr[1], ethaddr[2],
  24                ethaddr[3], ethaddr[4], ethaddr[5]));
  25
  26    if (IN6_IS_ADDR_MULTICAST(&ip_addr) || in6_zero(&ip_addr)) {
  27        /* Do not register multicast or unspecified addresses */
  28        DEBUG_CALL(" abort: do not register multicast or unspecified address");
  29        return;
  30    }
  31
  32    /* Search for an entry */
  33    for (i = 0; i < NDP_TABLE_SIZE; i++) {
  34        if (in6_equal(&ndp_table->table[i].ip_addr, &ip_addr)) {
  35            DEBUG_CALL(" already in table: update the entry");
  36            /* Update the entry */
  37            memcpy(ndp_table->table[i].eth_addr, ethaddr, ETH_ALEN);
  38            return;
  39        }
  40    }
  41
  42    /* No entry found, create a new one */
  43    DEBUG_CALL(" create new entry");
  44    ndp_table->table[ndp_table->next_victim].ip_addr = ip_addr;
  45    memcpy(ndp_table->table[ndp_table->next_victim].eth_addr,
  46            ethaddr, ETH_ALEN);
  47    ndp_table->next_victim = (ndp_table->next_victim + 1) % NDP_TABLE_SIZE;
  48}
  49
  50bool ndp_table_search(Slirp *slirp, struct in6_addr ip_addr,
  51                      uint8_t out_ethaddr[ETH_ALEN])
  52{
  53    NdpTable *ndp_table = &slirp->ndp_table;
  54    int i;
  55
  56    DEBUG_CALL("ndp_table_search");
  57#if !defined(_WIN32) || (_WIN32_WINNT >= 0x0600)
  58    char addrstr[INET6_ADDRSTRLEN];
  59    inet_ntop(AF_INET6, &(ip_addr), addrstr, INET6_ADDRSTRLEN);
  60    DEBUG_ARG("ip = %s", addrstr);
  61#endif
  62
  63    assert(!in6_zero(&ip_addr));
  64
  65    /* Multicast address: fec0::abcd:efgh/8 -> 33:33:ab:cd:ef:gh */
  66    if (IN6_IS_ADDR_MULTICAST(&ip_addr)) {
  67        out_ethaddr[0] = 0x33; out_ethaddr[1] = 0x33;
  68        out_ethaddr[2] = ip_addr.s6_addr[12];
  69        out_ethaddr[3] = ip_addr.s6_addr[13];
  70        out_ethaddr[4] = ip_addr.s6_addr[14];
  71        out_ethaddr[5] = ip_addr.s6_addr[15];
  72        DEBUG_ARGS((dfd, " multicast addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
  73                    out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
  74                    out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]));
  75        return 1;
  76    }
  77
  78    for (i = 0; i < NDP_TABLE_SIZE; i++) {
  79        if (in6_equal(&ndp_table->table[i].ip_addr, &ip_addr)) {
  80            memcpy(out_ethaddr, ndp_table->table[i].eth_addr,  ETH_ALEN);
  81            DEBUG_ARGS((dfd, " found hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
  82                        out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
  83                        out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]));
  84            return 1;
  85        }
  86    }
  87
  88    DEBUG_CALL(" ip not found in table");
  89    return 0;
  90}
  91