Path: blob/a-new-beginning/SharedDependencies/Sources/libslirp/arp_table.c
2 views
/* SPDX-License-Identifier: MIT */1/*2* ARP table3*4* Copyright (c) 2011 AdaCore5*6* Permission is hereby granted, free of charge, to any person obtaining a copy7* of this software and associated documentation files (the "Software"), to deal8* in the Software without restriction, including without limitation the rights9* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell10* copies of the Software, and to permit persons to whom the Software is11* furnished to do so, subject to the following conditions:12*13* The above copyright notice and this permission notice shall be included in14* all copies or substantial portions of the Software.15*16* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR17* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,18* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL19* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER20* 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 IN22* THE SOFTWARE.23*/2425#include "slirp.h"2627#include <string.h>2829void arp_table_add(Slirp *slirp, uint32_t ip_addr,30const uint8_t ethaddr[ETH_ALEN])31{32const uint32_t broadcast_addr =33~slirp->vnetwork_mask.s_addr | slirp->vnetwork_addr.s_addr;34ArpTable *arptbl = &slirp->arp_table;35int i;36char ethaddr_str[ETH_ADDRSTRLEN];37char addr[INET_ADDRSTRLEN];3839DEBUG_CALL("arp_table_add");40DEBUG_ARG("ip = %s", inet_ntop(AF_INET, &(struct in_addr){ .s_addr = ip_addr },41addr, sizeof(addr)));42DEBUG_ARG("hw addr = %s", slirp_ether_ntoa(ethaddr, ethaddr_str,43sizeof(ethaddr_str)));4445if (ip_addr == 0 || ip_addr == 0xffffffff || ip_addr == broadcast_addr) {46/* Do not register broadcast addresses */47return;48}4950/* Search for an entry */51for (i = 0; i < ARP_TABLE_SIZE; i++) {52if (arptbl->table[i].ar_sip == ip_addr) {53/* Update the entry */54memcpy(arptbl->table[i].ar_sha, ethaddr, ETH_ALEN);55return;56}57}5859/* No entry found, create a new one */60arptbl->table[arptbl->next_victim].ar_sip = ip_addr;61memcpy(arptbl->table[arptbl->next_victim].ar_sha, ethaddr, ETH_ALEN);62arptbl->next_victim = (arptbl->next_victim + 1) % ARP_TABLE_SIZE;63}6465bool arp_table_search(Slirp *slirp, uint32_t ip_addr,66uint8_t out_ethaddr[ETH_ALEN])67{68const uint32_t broadcast_addr =69~slirp->vnetwork_mask.s_addr | slirp->vnetwork_addr.s_addr;70ArpTable *arptbl = &slirp->arp_table;71int i;72char ethaddr_str[ETH_ADDRSTRLEN];73char addr[INET_ADDRSTRLEN];7475DEBUG_CALL("arp_table_search");76DEBUG_ARG("ip = %s", inet_ntop(AF_INET, &(struct in_addr){ .s_addr = ip_addr },77addr, sizeof(addr)));7879/* If broadcast address */80if (ip_addr == 0 || ip_addr == 0xffffffff || ip_addr == broadcast_addr) {81/* return Ethernet broadcast address */82memset(out_ethaddr, 0xff, ETH_ALEN);83return 1;84}8586for (i = 0; i < ARP_TABLE_SIZE; i++) {87if (arptbl->table[i].ar_sip == ip_addr) {88memcpy(out_ethaddr, arptbl->table[i].ar_sha, ETH_ALEN);89DEBUG_ARG("found hw addr = %s",90slirp_ether_ntoa(out_ethaddr, ethaddr_str,91sizeof(ethaddr_str)));92return 1;93}94}9596return 0;97}9899100