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