Statistics
| Branch: | Revision:

root / slirp / arp_table.c @ 0ef654e3

History | View | Annotate | Download (3.4 kB)

1 1a0ca1e1 Fabien Chouteau
/*
2 1a0ca1e1 Fabien Chouteau
 * ARP table
3 1a0ca1e1 Fabien Chouteau
 *
4 1a0ca1e1 Fabien Chouteau
 * Copyright (c) 2011 AdaCore
5 1a0ca1e1 Fabien Chouteau
 *
6 1a0ca1e1 Fabien Chouteau
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 1a0ca1e1 Fabien Chouteau
 * of this software and associated documentation files (the "Software"), to deal
8 1a0ca1e1 Fabien Chouteau
 * in the Software without restriction, including without limitation the rights
9 1a0ca1e1 Fabien Chouteau
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 1a0ca1e1 Fabien Chouteau
 * copies of the Software, and to permit persons to whom the Software is
11 1a0ca1e1 Fabien Chouteau
 * furnished to do so, subject to the following conditions:
12 1a0ca1e1 Fabien Chouteau
 *
13 1a0ca1e1 Fabien Chouteau
 * The above copyright notice and this permission notice shall be included in
14 1a0ca1e1 Fabien Chouteau
 * all copies or substantial portions of the Software.
15 1a0ca1e1 Fabien Chouteau
 *
16 1a0ca1e1 Fabien Chouteau
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 1a0ca1e1 Fabien Chouteau
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 1a0ca1e1 Fabien Chouteau
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 1a0ca1e1 Fabien Chouteau
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 1a0ca1e1 Fabien Chouteau
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 1a0ca1e1 Fabien Chouteau
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 1a0ca1e1 Fabien Chouteau
 * THE SOFTWARE.
23 1a0ca1e1 Fabien Chouteau
 */
24 1a0ca1e1 Fabien Chouteau
25 1a0ca1e1 Fabien Chouteau
#include "slirp.h"
26 1a0ca1e1 Fabien Chouteau
27 5a371a2e Jan Kiszka
void arp_table_add(Slirp *slirp, uint32_t ip_addr, uint8_t ethaddr[ETH_ALEN])
28 1a0ca1e1 Fabien Chouteau
{
29 5a371a2e Jan Kiszka
    const uint32_t broadcast_addr =
30 1a0ca1e1 Fabien Chouteau
        ~slirp->vnetwork_mask.s_addr | slirp->vnetwork_addr.s_addr;
31 1a0ca1e1 Fabien Chouteau
    ArpTable *arptbl = &slirp->arp_table;
32 1a0ca1e1 Fabien Chouteau
    int i;
33 1a0ca1e1 Fabien Chouteau
34 1a0ca1e1 Fabien Chouteau
    DEBUG_CALL("arp_table_add");
35 1a0ca1e1 Fabien Chouteau
    DEBUG_ARG("ip = 0x%x", ip_addr);
36 1a0ca1e1 Fabien Chouteau
    DEBUG_ARGS((dfd, " hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
37 1a0ca1e1 Fabien Chouteau
                ethaddr[0], ethaddr[1], ethaddr[2],
38 1a0ca1e1 Fabien Chouteau
                ethaddr[3], ethaddr[4], ethaddr[5]));
39 1a0ca1e1 Fabien Chouteau
40 1a0ca1e1 Fabien Chouteau
    /* Check 0.0.0.0/8 invalid source-only addresses */
41 1a0ca1e1 Fabien Chouteau
    assert((ip_addr & htonl(~(0xf << 28))) != 0);
42 1a0ca1e1 Fabien Chouteau
43 1a0ca1e1 Fabien Chouteau
    if (ip_addr == 0xffffffff || ip_addr == broadcast_addr) {
44 1a0ca1e1 Fabien Chouteau
        /* Do not register broadcast addresses */
45 1a0ca1e1 Fabien Chouteau
        return;
46 1a0ca1e1 Fabien Chouteau
    }
47 1a0ca1e1 Fabien Chouteau
48 1a0ca1e1 Fabien Chouteau
    /* Search for an entry */
49 1a0ca1e1 Fabien Chouteau
    for (i = 0; i < ARP_TABLE_SIZE; i++) {
50 1a0ca1e1 Fabien Chouteau
        if (arptbl->table[i].ar_sip == ip_addr) {
51 1a0ca1e1 Fabien Chouteau
            /* Update the entry */
52 1a0ca1e1 Fabien Chouteau
            memcpy(arptbl->table[i].ar_sha, ethaddr, ETH_ALEN);
53 1a0ca1e1 Fabien Chouteau
            return;
54 1a0ca1e1 Fabien Chouteau
        }
55 1a0ca1e1 Fabien Chouteau
    }
56 1a0ca1e1 Fabien Chouteau
57 1a0ca1e1 Fabien Chouteau
    /* No entry found, create a new one */
58 1a0ca1e1 Fabien Chouteau
    arptbl->table[arptbl->next_victim].ar_sip = ip_addr;
59 1a0ca1e1 Fabien Chouteau
    memcpy(arptbl->table[arptbl->next_victim].ar_sha,  ethaddr, ETH_ALEN);
60 1a0ca1e1 Fabien Chouteau
    arptbl->next_victim = (arptbl->next_victim + 1) % ARP_TABLE_SIZE;
61 1a0ca1e1 Fabien Chouteau
}
62 1a0ca1e1 Fabien Chouteau
63 5a371a2e Jan Kiszka
bool arp_table_search(Slirp *slirp, uint32_t ip_addr,
64 1a0ca1e1 Fabien Chouteau
                      uint8_t out_ethaddr[ETH_ALEN])
65 1a0ca1e1 Fabien Chouteau
{
66 5a371a2e Jan Kiszka
    const uint32_t broadcast_addr =
67 1a0ca1e1 Fabien Chouteau
        ~slirp->vnetwork_mask.s_addr | slirp->vnetwork_addr.s_addr;
68 1a0ca1e1 Fabien Chouteau
    ArpTable *arptbl = &slirp->arp_table;
69 1a0ca1e1 Fabien Chouteau
    int i;
70 1a0ca1e1 Fabien Chouteau
71 1a0ca1e1 Fabien Chouteau
    DEBUG_CALL("arp_table_search");
72 5a371a2e Jan Kiszka
    DEBUG_ARG("ip = 0x%x", ip_addr);
73 1a0ca1e1 Fabien Chouteau
74 1a0ca1e1 Fabien Chouteau
    /* Check 0.0.0.0/8 invalid source-only addresses */
75 5a371a2e Jan Kiszka
    assert((ip_addr & htonl(~(0xf << 28))) != 0);
76 1a0ca1e1 Fabien Chouteau
77 1a0ca1e1 Fabien Chouteau
    /* If broadcast address */
78 5a371a2e Jan Kiszka
    if (ip_addr == 0xffffffff || ip_addr == broadcast_addr) {
79 1a0ca1e1 Fabien Chouteau
        /* return Ethernet broadcast address */
80 1a0ca1e1 Fabien Chouteau
        memset(out_ethaddr, 0xff, ETH_ALEN);
81 1a0ca1e1 Fabien Chouteau
        return 1;
82 1a0ca1e1 Fabien Chouteau
    }
83 1a0ca1e1 Fabien Chouteau
84 1a0ca1e1 Fabien Chouteau
    for (i = 0; i < ARP_TABLE_SIZE; i++) {
85 5a371a2e Jan Kiszka
        if (arptbl->table[i].ar_sip == ip_addr) {
86 1a0ca1e1 Fabien Chouteau
            memcpy(out_ethaddr, arptbl->table[i].ar_sha,  ETH_ALEN);
87 1a0ca1e1 Fabien Chouteau
            DEBUG_ARGS((dfd, " found hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
88 1a0ca1e1 Fabien Chouteau
                        out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
89 1a0ca1e1 Fabien Chouteau
                        out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]));
90 1a0ca1e1 Fabien Chouteau
            return 1;
91 1a0ca1e1 Fabien Chouteau
        }
92 1a0ca1e1 Fabien Chouteau
    }
93 1a0ca1e1 Fabien Chouteau
94 1a0ca1e1 Fabien Chouteau
    return 0;
95 1a0ca1e1 Fabien Chouteau
}