void Arp::arp_resolve(Packet_ptr pckt) { debug("<ARP RESOLVE> %s\n", pckt->next_hop().str().c_str()); const auto next_hop = pckt->next_hop(); await_resolution(std::move(pckt), next_hop); auto req = static_unique_ptr_cast<PacketArp>(inet_.create_packet(sizeof(header))); req->init(mac_, inet_.ip_addr()); req->set_dest_mac(Ethernet::BROADCAST_FRAME); req->set_dest_ip(next_hop); req->set_opcode(H_request); // Stat increment requests sent requests_tx_++; linklayer_out_(std::move(req)); }
void Arp::transmit(Packet_ptr pckt, IP4::addr next_hop) { Expects(pckt->size()); PRINT("<ARP -> physical> Transmitting %u bytes to %s\n", (uint32_t) pckt->size(), next_hop.str().c_str()); MAC::Addr dest_mac; if (next_hop == IP4::ADDR_BCAST) { dest_mac = MAC::BROADCAST; } else { #ifdef ARP_PASSTHROUGH extern MAC::Addr linux_tap_device; dest_mac = linux_tap_device; #else // If we don't have a cached IP, perform address resolution auto cache_entry = cache_.find(next_hop); if (UNLIKELY(cache_entry == cache_.end())) { PRINT("<ARP> No cache entry for IP %s. Resolving. \n", next_hop.to_string().c_str()); await_resolution(std::move(pckt), next_hop); return; } // Get MAC from cache dest_mac = cache_[next_hop].mac(); #endif PRINT("<ARP> Found cache entry for IP %s -> %s \n", next_hop.to_string().c_str(), dest_mac.to_string().c_str()); } // Move chain to linklayer linklayer_out_(std::move(pckt), dest_mac, Ethertype::IP4); }