# HG changeset patch # User Sebastien Bindel # Date 1478363048 -3600 # Parent 06cd9fe6efb79ae2e781dcf0a6eb3ecc83be2e3c internet: (fixes #2483) ARP Request reception add an ARP table entry - RFC 826 diff --git a/src/internet/model/arp-l3-protocol.cc b/src/internet/model/arp-l3-protocol.cc --- a/src/internet/model/arp-l3-protocol.cc +++ b/src/internet/model/arp-l3-protocol.cc @@ -175,7 +175,7 @@ // // If we're connected to a real world network, then some of the fields sizes // in an ARP packet can vary in ways not seen in simulations. We need to be - // able to detect ARP packets with headers we don't recongnize and not process + // able to detect ARP packets with headers we don't recognize and not process // them instead of crashing. The ArpHeader will return 0 if it can't deal // with the received header. // @@ -198,25 +198,48 @@ NS_LOG_LOGIC (cache->GetInterface ()->GetAddress (i).GetLocal () << ", "); } - /** - * \internal - * Note: we do not update the ARP cache when we receive an ARP request - * from an unknown node. See \bugid{107} - */ bool found = false; for (uint32_t i = 0; i < cache->GetInterface ()->GetNAddresses (); i++) { if (arp.IsRequest () && arp.GetDestinationIpv4Address () == cache->GetInterface ()->GetAddress (i).GetLocal ()) { + ArpCache::Entry *entry = cache->Lookup (arp.GetSourceIpv4Address ()); + if (entry!=0) + { + if (entry->IsWaitReply ()) + { + NS_LOG_LOGIC ("node="<GetId ()<<", got request from " << + arp.GetSourceIpv4Address () << + " for waiting entry -- flush and later send reply"); + entry->MarkAlive (arp.GetSourceHardwareAddress ()); + } + else + { + // Ignore-- already have an entry + NS_LOG_LOGIC("node="<GetId () << ", got request from " << + arp.GetSourceIpv4Address () << " for non-waiting entry"); + entry->UpdateSeen (); + } + } + else + { + // No entry for this source, but add one now (RFC 826) + NS_LOG_LOGIC("node="<GetId ()<<", got request from " << + arp.GetSourceIpv4Address () << + " for non-existent entry-- adding "); + ArpCache::Entry *entry = cache->Add (arp.GetSourceIpv4Address ()); + entry->MarkAlive (arp.GetSourceHardwareAddress ()); + } + found = true; - NS_LOG_LOGIC ("node="<GetId () <<", got request from " << + NS_LOG_LOGIC ("node="<GetId () <<", got request from " << arp.GetSourceIpv4Address () << " -- send reply"); SendArpReply (cache, arp.GetDestinationIpv4Address (), arp.GetSourceIpv4Address (), arp.GetSourceHardwareAddress ()); break; - } - else if (arp.IsReply () && + } + else if (arp.IsReply () && arp.GetDestinationIpv4Address ().IsEqual (cache->GetInterface ()->GetAddress (i).GetLocal ()) && arp.GetDestinationHardwareAddress () == device->GetAddress ()) { @@ -228,8 +251,8 @@ if (entry->IsWaitReply ()) { NS_LOG_LOGIC ("node="<< m_node->GetId () << - ", got reply from " << arp.GetSourceIpv4Address () - << " for waiting entry -- flush"); + ", got reply from " << arp.GetSourceIpv4Address () << + " for waiting entry -- flush"); Address from_mac = arp.GetSourceHardwareAddress (); entry->MarkAlive (from_mac); ArpCache::Ipv4PayloadHeaderPair pending = entry->DequeuePending (); @@ -243,8 +266,8 @@ else { // ignore this reply which might well be an attempt - // at poisening my arp cache. - NS_LOG_LOGIC ("node="<GetId ()<<", got reply from " << + // at poisoning my arp cache. + NS_LOG_LOGIC ("node=" << m_node->GetId () << ", got reply from " << arp.GetSourceIpv4Address () << " for non-waiting entry -- drop"); m_dropTrace (packet); @@ -252,7 +275,7 @@ } else { - NS_LOG_LOGIC ("node="<GetId ()<<", got reply for unknown entry -- drop"); + NS_LOG_LOGIC ("node=" << m_node->GetId () << ", got reply for unknown entry -- drop"); m_dropTrace (packet); } break; @@ -260,7 +283,7 @@ } if (found == false) { - NS_LOG_LOGIC ("node="<GetId ()<<", got request from " << + NS_LOG_LOGIC ("node=" << m_node->GetId () << ", got request from " << arp.GetSourceIpv4Address () << " for unknown address " << arp.GetDestinationIpv4Address () << " -- drop"); }