# HG changeset patch # Parent 751e327b36324dcd12e274c97df54fbfbe5598ff # User Tommaso Pecorella # Date 1410765789 -7200 Bug 652 - no public API for IPv4 neighbor table diff --git a/src/internet/helper/ipv4-routing-helper.cc b/src/internet/helper/ipv4-routing-helper.cc --- a/src/internet/helper/ipv4-routing-helper.cc +++ b/src/internet/helper/ipv4-routing-helper.cc @@ -23,6 +23,10 @@ #include "ns3/simulator.h" #include "ns3/ipv4-routing-protocol.h" #include "ns3/ipv4-list-routing.h" +#include "ns3/ipv4-l3-protocol.h" +#include "ns3/ipv4-interface.h" +#include "ns3/arp-cache.h" +#include "ns3/names.h" #include "ipv4-routing-helper.h" namespace ns3 { @@ -82,4 +86,93 @@ Simulator::Schedule (printInterval, &Ipv4RoutingHelper::PrintEvery, this, printInterval, node, stream); } +void +Ipv4RoutingHelper::PrintNeighborCacheAllAt (Time printTime, Ptr stream) const +{ + for (uint32_t i = 0; i < NodeList::GetNNodes (); i++) + { + Ptr node = NodeList::GetNode (i); + Simulator::Schedule (printTime, &Ipv4RoutingHelper::PrintArpCache, this, node, stream); + } +} + +void +Ipv4RoutingHelper::PrintNeighborCacheAllEvery (Time printInterval, Ptr stream) const +{ + for (uint32_t i = 0; i < NodeList::GetNNodes (); i++) + { + Ptr node = NodeList::GetNode (i); + Simulator::Schedule (printInterval, &Ipv4RoutingHelper::PrintArpCacheEvery, this, printInterval, node, stream); + } +} + +void +Ipv4RoutingHelper::PrintNeighborCacheAt (Time printTime, Ptr node, Ptr stream) const +{ + Simulator::Schedule (printTime, &Ipv4RoutingHelper::PrintArpCache, this, node, stream); +} + +void +Ipv4RoutingHelper::PrintNeighborCacheEvery (Time printInterval,Ptr node, Ptr stream) const +{ + Simulator::Schedule (printInterval, &Ipv4RoutingHelper::PrintArpCacheEvery, this, printInterval, node, stream); +} + +void +Ipv4RoutingHelper::PrintArpCache (Ptr node, Ptr stream) const +{ + std::ostream* os = stream->GetStream (); + + *os << "ARP Cache of node "; + std::string found = Names::FindName (node); + if (Names::FindName (node) != "") + { + *os << found; + } + else + { + *os << static_cast (node->GetId ()); + } + *os << " at time " << Simulator::Now ().GetSeconds () << "\n"; + + Ptr ipv4 = node->GetObject (); + for (uint32_t i=0; iGetNInterfaces(); i++) + { + Ptr arpCache = ipv4->GetInterface (i)->GetArpCache (); + if (arpCache) + { + arpCache->PrintArpCache (stream); + } + } +} + +void +Ipv4RoutingHelper::PrintArpCacheEvery (Time printInterval, Ptr node, Ptr stream) const +{ + std::ostream* os = stream->GetStream (); + + *os << "ARP Cache of node "; + std::string found = Names::FindName (node); + if (Names::FindName (node) != "") + { + *os << found; + } + else + { + *os << static_cast (node->GetId ()); + } + *os << " at time " << Simulator::Now ().GetSeconds () << "\n"; + + Ptr ipv4 = node->GetObject (); + for (uint32_t i=0; iGetNInterfaces(); i++) + { + Ptr arpCache = ipv4->GetInterface (i)->GetArpCache (); + if (arpCache) + { + arpCache->PrintArpCache (stream); + } + } + Simulator::Schedule (printInterval, &Ipv4RoutingHelper::PrintArpCacheEvery, this, printInterval, node, stream); +} + } // namespace ns3 diff --git a/src/internet/helper/ipv4-routing-helper.h b/src/internet/helper/ipv4-routing-helper.h --- a/src/internet/helper/ipv4-routing-helper.h +++ b/src/internet/helper/ipv4-routing-helper.h @@ -110,6 +110,68 @@ void PrintRoutingTableEvery (Time printInterval, Ptr node, Ptr stream) const; /** + * \brief prints the neighbor cache of all nodes at a particular time. + * \param printTime the time at which the neighbor cache is supposed to be printed. + * \param stream The output stream object to use + * + * This method calls the PrintArpCache() method of the + * ArpCache associated with each Ipv4Interface stored in the Ipv4 object, for all nodes at the + * specified time. The output format is similar to: + * \verbatim + 10.1.1.2 dev 1 lladdr 00-06-00:00:00:00:00:02 REACHABLE + \endverbatim + * Note that the MAC address is printed as "type"-"size"-"actual address" + */ + void PrintNeighborCacheAllAt (Time printTime, Ptr stream) const; + + /** + * \brief prints the neighbor cache of all nodes at regular intervals specified by user. + * \param printInterval the time interval for which the neighbor cache is supposed to be printed. + * \param stream The output stream object to use + * + * This method calls the PrintArpCache() method of the + * ArpCache associated with each Ipv4Interface stored in the Ipv4 object, for all nodes at the + * specified time. The output format is similar to: + * \verbatim + 10.1.1.2 dev 1 lladdr 00-06-00:00:00:00:00:02 REACHABLE + \endverbatim + * Note that the MAC address is printed as "type"-"size"-"actual address" + */ + void PrintNeighborCacheAllEvery (Time printInterval, Ptr stream) const; + + /** + * \brief prints the neighbor cache of a node at a particular time. + * \param printTime the time at which the neighbor cache is supposed to be printed. + * \param node The node ptr for which we need the neighbor cache to be printed + * \param stream The output stream object to use + * + * This method calls the PrintArpCache() method of the + * ArpCache associated with each Ipv4Interface stored in the Ipv4 object, for all nodes at the + * specified time. The output format is similar to: + * \verbatim + 10.1.1.2 dev 1 lladdr 00-06-00:00:00:00:00:02 REACHABLE + \endverbatim + * Note that the MAC address is printed as "type"-"size"-"actual address" + */ + void PrintNeighborCacheAt (Time printTime, Ptr node, Ptr stream) const; + + /** + * \brief prints the neighbor cache of a node at regular intervals specified by user. + * \param printInterval the time interval for which the neighbor cache is supposed to be printed. + * \param node The node ptr for which we need the neighbor cache to be printed + * \param stream The output stream object to use + * + * This method calls the PrintArpCache() method of the + * ArpCache associated with each Ipv4Interface stored in the Ipv4 object, for all nodes at the + * specified time. The output format is similar to: + * \verbatim + 10.1.1.2 dev 1 lladdr 00-06-00:00:00:00:00:02 REACHABLE + \endverbatim + * Note that the MAC address is printed as "type"-"size"-"actual address" + */ + void PrintNeighborCacheEvery (Time printInterval, Ptr node, Ptr stream) const; + + /** * \brief Request a specified routing protocol <T> from Ipv4RoutingProtocol protocol * * If protocol is Ipv4ListRouting, then protocol will be searched in the list, @@ -130,7 +192,7 @@ * \param stream The output stream object to use * * This method calls the PrintRoutingTable() method of the - * Ipv6RoutingProtocol stored in the Ipv6 object; + * Ipv4RoutingProtocol stored in the Ipv4 object; * the output format is routing protocol-specific. */ void Print (Ptr node, Ptr stream) const; @@ -144,10 +206,45 @@ * \param stream The output stream object to use * * This method calls the PrintRoutingTable() method of the - * Ipv6RoutingProtocol stored in the Ipv6 object, for the selected node + * Ipv4RoutingProtocol stored in the Ipv4 object, for the selected node * at the specified interval; the output format is routing protocol-specific. */ void PrintEvery (Time printInterval, Ptr node, Ptr stream) const; + + /** + * \internal + * + * \brief prints the neighbor cache of a node. + * \param node The node ptr for which we need the neighbor cache to be printed + * \param stream The output stream object to use + * + * This method calls the PrintArpCache() method of the + * ArpCache associated with each Ipv4Interface stored in the Ipv4 object, for all nodes at the + * specified time. The output format is similar to: + * \verbatim + 10.1.1.2 dev 1 lladdr 00-06-00:00:00:00:00:02 REACHABLE + \endverbatim + * Note that the MAC address is printed as "type"-"size"-"actual address" + */ + void PrintArpCache (Ptr node, Ptr stream) const; + + /** + * \internal + * + * \brief prints the neighbor cache of a node at regular intervals specified by user. + * \param printInterval the time interval for which the neighbor cache is supposed to be printed. + * \param node The node ptr for which we need the neighbor cache to be printed + * \param stream The output stream object to use + * + * This method calls the PrintArpCache() method of the + * ArpCache associated with each Ipv4Interface stored in the Ipv4 object, for all nodes at the + * specified time. The output format is similar to: + * \verbatim + 10.1.1.2 dev 1 lladdr 00-06-00:00:00:00:00:02 REACHABLE + \endverbatim + * Note that the MAC address is printed as "type"-"size"-"actual address" + */ + void PrintArpCacheEvery (Time printInterval, Ptr node, Ptr stream) const; }; diff --git a/src/internet/helper/ipv6-routing-helper.cc b/src/internet/helper/ipv6-routing-helper.cc --- a/src/internet/helper/ipv6-routing-helper.cc +++ b/src/internet/helper/ipv6-routing-helper.cc @@ -23,6 +23,10 @@ #include "ns3/simulator.h" #include "ns3/ipv6-routing-protocol.h" #include "ns3/ipv6-list-routing.h" +#include "ns3/ipv6-l3-protocol.h" +#include "ns3/ipv6-interface.h" +#include "ns3/ndisc-cache.h" +#include "ns3/names.h" #include "ipv6-routing-helper.h" namespace ns3 { @@ -82,4 +86,93 @@ Simulator::Schedule (printInterval, &Ipv6RoutingHelper::PrintEvery, this, printInterval, node, stream); } +void +Ipv6RoutingHelper::PrintNeighborCacheAllAt (Time printTime, Ptr stream) const +{ + for (uint32_t i = 0; i < NodeList::GetNNodes (); i++) + { + Ptr node = NodeList::GetNode (i); + Simulator::Schedule (printTime, &Ipv6RoutingHelper::PrintNdiscCache, this, node, stream); + } +} + +void +Ipv6RoutingHelper::PrintNeighborCacheAllEvery (Time printInterval, Ptr stream) const +{ + for (uint32_t i = 0; i < NodeList::GetNNodes (); i++) + { + Ptr node = NodeList::GetNode (i); + Simulator::Schedule (printInterval, &Ipv6RoutingHelper::PrintNdiscCacheEvery, this, printInterval, node, stream); + } +} + +void +Ipv6RoutingHelper::PrintNeighborCacheAt (Time printTime, Ptr node, Ptr stream) const +{ + Simulator::Schedule (printTime, &Ipv6RoutingHelper::PrintNdiscCache, this, node, stream); +} + +void +Ipv6RoutingHelper::PrintNeighborCacheEvery (Time printInterval,Ptr node, Ptr stream) const +{ + Simulator::Schedule (printInterval, &Ipv6RoutingHelper::PrintNdiscCacheEvery, this, printInterval, node, stream); +} + +void +Ipv6RoutingHelper::PrintNdiscCache (Ptr node, Ptr stream) const +{ + std::ostream* os = stream->GetStream (); + + *os << "NDISC Cache of node "; + std::string found = Names::FindName (node); + if (Names::FindName (node) != "") + { + *os << found; + } + else + { + *os << static_cast (node->GetId ()); + } + *os << " at time " << Simulator::Now ().GetSeconds () << "\n"; + + Ptr ipv6 = node->GetObject (); + for (uint32_t i=0; iGetNInterfaces(); i++) + { + Ptr ndiscCache = ipv6->GetInterface (i)->GetNdiscCache (); + if (ndiscCache) + { + ndiscCache->PrintNdiscCache (stream); + } + } +} + +void +Ipv6RoutingHelper::PrintNdiscCacheEvery (Time printInterval, Ptr node, Ptr stream) const +{ + std::ostream* os = stream->GetStream (); + + *os << "NDISC Cache of node "; + std::string found = Names::FindName (node); + if (Names::FindName (node) != "") + { + *os << found; + } + else + { + *os << static_cast (node->GetId ()); + } + *os << " at time " << Simulator::Now ().GetSeconds () << "\n"; + + Ptr ipv6 = node->GetObject (); + for (uint32_t i=0; iGetNInterfaces(); i++) + { + Ptr ndiscCache = ipv6->GetInterface (i)->GetNdiscCache (); + if (ndiscCache) + { + ndiscCache->PrintNdiscCache (stream); + } + } + Simulator::Schedule (printInterval, &Ipv6RoutingHelper::PrintNdiscCacheEvery, this, printInterval, node, stream); +} + } // namespace ns3 diff --git a/src/internet/helper/ipv6-routing-helper.h b/src/internet/helper/ipv6-routing-helper.h --- a/src/internet/helper/ipv6-routing-helper.h +++ b/src/internet/helper/ipv6-routing-helper.h @@ -112,6 +112,68 @@ void PrintRoutingTableEvery (Time printInterval, Ptr node, Ptr stream) const; /** + * \brief prints the neighbor cache of all nodes at a particular time. + * \param printTime the time at which the neighbor cache is supposed to be printed. + * \param stream The output stream object to use + * + * This method calls the PrintNdiscCache() method of the + * NdiscCache associated with each Ipv6Interface stored in the Ipv6 object, for all nodes at the + * specified time. The output format is similar to: + * \verbatim + 2001:db8::f00d:beef:cafe dev 1 lladdr 00-06-00:00:00:00:00:02 REACHABLE + \endverbatim + * Note that the MAC address is printed as "type"-"size"-"actual address" + */ + void PrintNeighborCacheAllAt (Time printTime, Ptr stream) const; + + /** + * \brief prints the neighbor cache of all nodes at regular intervals specified by user. + * \param printInterval the time interval for which the neighbor cache is supposed to be printed. + * \param stream The output stream object to use + * + * This method calls the PrintNdiscCache() method of the + * NdiscCache associated with each Ipv6Interface stored in the Ipv6 object, for all nodes at the + * specified time. The output format is similar to: + * \verbatim + 2001:db8::f00d:beef:cafe dev 1 lladdr 00-06-00:00:00:00:00:02 REACHABLE + \endverbatim + * Note that the MAC address is printed as "type"-"size"-"actual address" + */ + void PrintNeighborCacheAllEvery (Time printInterval, Ptr stream) const; + + /** + * \brief prints the neighbor cache of a node at a particular time. + * \param printTime the time at which the neighbor cache is supposed to be printed. + * \param node The node ptr for which we need the neighbor cache to be printed + * \param stream The output stream object to use + * + * This method calls the PrintNdiscCache() method of the + * NdiscCache associated with each Ipv6Interface stored in the Ipv6 object, for all nodes at the + * specified time. The output format is similar to: + * \verbatim + 2001:db8::f00d:beef:cafe dev 1 lladdr 00-06-00:00:00:00:00:02 REACHABLE + \endverbatim + * Note that the MAC address is printed as "type"-"size"-"actual address" + */ + void PrintNeighborCacheAt (Time printTime, Ptr node, Ptr stream) const; + + /** + * \brief prints the neighbor cache of a node at regular intervals specified by user. + * \param printInterval the time interval for which the neighbor cache is supposed to be printed. + * \param node The node ptr for which we need the neighbor cache to be printed + * \param stream The output stream object to use + * + * This method calls the PrintNdiscCache() method of the + * NdiscCache associated with each Ipv6Interface stored in the Ipv6 object, for all nodes at the + * specified time. The output format is similar to: + * \verbatim + 2001:db8::f00d:beef:cafe dev 1 lladdr 00-06-00:00:00:00:00:02 REACHABLE + \endverbatim + * Note that the MAC address is printed as "type"-"size"-"actual address" + */ + void PrintNeighborCacheEvery (Time printInterval, Ptr node, Ptr stream) const; + + /** * \brief Request a specified routing protocol <T> from Ipv6RoutingProtocol protocol * * If protocol is Ipv6ListRouting, then protocol will be searched in the list, @@ -150,6 +212,41 @@ * at the specified interval; the output format is routing protocol-specific. */ void PrintEvery (Time printInterval, Ptr node, Ptr stream) const; + + /** + * \internal + * + * \brief prints the neighbor cache of a node. + * \param node The node ptr for which we need the neighbor cache to be printed + * \param stream The output stream object to use + * + * This method calls the PrintNdiscCache() method of the + * NdiscCache associated with each Ipv6Interface stored in the Ipv6 object, for all nodes at the + * specified time. The output format is similar to: + * \verbatim + 2001:db8::f00d:beef:cafe dev 1 lladdr 00-06-00:00:00:00:00:02 REACHABLE + \endverbatim + * Note that the MAC address is printed as "type"-"size"-"actual address" + */ + void PrintNdiscCache (Ptr node, Ptr stream) const; + + /** + * \internal + * + * \brief prints the neighbor cache of a node at regular intervals specified by user. + * \param printInterval the time interval for which the neighbor cache is supposed to be printed. + * \param node The node ptr for which we need the neighbor cache to be printed + * \param stream The output stream object to use + * + * This method calls the PrintNdiscCache() method of the + * NdiscCache associated with each Ipv6Interface stored in the Ipv6 object, for all nodes at the + * specified time. The output format is similar to: + * \verbatim + 2001:db8::f00d:beef:cafe dev 1 lladdr 00-06-00:00:00:00:00:02 REACHABLE + \endverbatim + * Note that the MAC address is printed as "type"-"size"-"actual address" + */ + void PrintNdiscCacheEvery (Time printInterval, Ptr node, Ptr stream) const; }; /** diff --git a/src/internet/model/arp-cache.cc b/src/internet/model/arp-cache.cc --- a/src/internet/model/arp-cache.cc +++ b/src/internet/model/arp-cache.cc @@ -24,6 +24,7 @@ #include "ns3/log.h" #include "ns3/node.h" #include "ns3/trace-source-accessor.h" +#include "ns3/names.h" #include "arp-cache.h" #include "arp-header.h" @@ -242,6 +243,42 @@ } } +void +ArpCache::PrintArpCache (Ptr stream) +{ + NS_LOG_FUNCTION (this << stream); + std::ostream* os = stream->GetStream (); + + for (CacheI i = m_arpCache.begin (); i != m_arpCache.end (); i++) + { + *os << i->first << " dev "; + std::string found = Names::FindName (m_device); + if (Names::FindName (m_device) != "") + { + *os << found; + } + else + { + *os << static_cast (m_device->GetIfIndex ()); + } + + *os << " lladdr " << i->second->GetMacAddress (); + + if (i->second->IsAlive ()) + { + *os << " REACHABLE\n"; + } + else if (i->second->IsWaitReply ()) + { + *os << " DELAY\n"; + } + else + { + *os << " STALE\n"; + } + } +} + ArpCache::Entry * ArpCache::Lookup (Ipv4Address to) { diff --git a/src/internet/model/arp-cache.h b/src/internet/model/arp-cache.h --- a/src/internet/model/arp-cache.h +++ b/src/internet/model/arp-cache.h @@ -33,6 +33,7 @@ #include "ns3/object.h" #include "ns3/traced-callback.h" #include "ns3/sgi-hashmap.h" +#include "ns3/output-stream-wrapper.h" namespace ns3 { @@ -76,8 +77,8 @@ /** * \brief Set the NetDevice and Ipv4Interface associated with the ArpCache * - * \param device The hardware NetDevice associated with this ARP chache - * \param interface the Ipv4Interface associated with this ARP chache + * \param device The hardware NetDevice associated with this ARP cache + * \param interface the Ipv4Interface associated with this ARP cache */ void SetDevice (Ptr device, Ptr interface); /** @@ -155,6 +156,13 @@ void Flush (void); /** + * \brief Print the ARP cache entries + * + * \param stream the ostream the ARP cache entries is printed to + */ + void PrintArpCache (Ptr stream); + + /** * \brief A record that that holds information about an ArpCache entry */ class Entry { diff --git a/src/internet/model/ipv4-interface.h b/src/internet/model/ipv4-interface.h --- a/src/internet/model/ipv4-interface.h +++ b/src/internet/model/ipv4-interface.h @@ -78,6 +78,7 @@ * \returns the underlying NetDevice. This method cannot return zero. */ Ptr GetDevice (void) const; + /** * \return ARP cache used by this interface */ diff --git a/src/internet/model/ipv6-interface.cc b/src/internet/model/ipv6-interface.cc --- a/src/internet/model/ipv6-interface.cc +++ b/src/internet/model/ipv6-interface.cc @@ -505,5 +505,11 @@ /* not found, maybe address has expired */ } +Ptr Ipv6Interface::GetNdiscCache () const +{ + NS_LOG_FUNCTION (this); + return m_ndCache; +} + } /* namespace ns3 */ diff --git a/src/internet/model/ipv6-interface.h b/src/internet/model/ipv6-interface.h --- a/src/internet/model/ipv6-interface.h +++ b/src/internet/model/ipv6-interface.h @@ -250,6 +250,12 @@ */ void SetNsDadUid (Ipv6Address address, uint32_t uid); + /** + * \return NDISC cache used by this interface + */ + Ptr GetNdiscCache () const; + + protected: /** * \brief Dispose this object. diff --git a/src/internet/model/ndisc-cache.cc b/src/internet/model/ndisc-cache.cc --- a/src/internet/model/ndisc-cache.cc +++ b/src/internet/model/ndisc-cache.cc @@ -21,6 +21,7 @@ #include "ns3/log.h" #include "ns3/uinteger.h" #include "ns3/node.h" +#include "ns3/names.h" #include "ipv6-l3-protocol.h" #include "icmpv6-l4-protocol.h" @@ -149,6 +150,49 @@ return m_unresQlen; } +void NdiscCache::PrintNdiscCache (Ptr stream) +{ + NS_LOG_FUNCTION (this << stream); + std::ostream* os = stream->GetStream (); + + for (CacheI i = m_ndCache.begin (); i != m_ndCache.end (); i++) + { + *os << i->first << " dev "; + std::string found = Names::FindName (m_device); + if (Names::FindName (m_device) != "") + { + *os << found; + } + else + { + *os << static_cast (m_device->GetIfIndex ()); + } + + *os << " lladdr " << i->second->GetMacAddress (); + + if (i->second->IsReachable ()) + { + *os << " REACHABLE\n"; + } + else if (i->second->IsDelay ()) + { + *os << " DELAY\n"; + } + else if (i->second->IsIncomplete ()) + { + *os << " INCOMPLETE\n"; + } + else if (i->second->IsProbe ()) + { + *os << " PROBE\n"; + } + else + { + *os << " STALE\n"; + } + } +} + NdiscCache::Entry::Entry (NdiscCache* nd) : m_ndCache (nd), m_waiting (), diff --git a/src/internet/model/ndisc-cache.h b/src/internet/model/ndisc-cache.h --- a/src/internet/model/ndisc-cache.h +++ b/src/internet/model/ndisc-cache.h @@ -22,7 +22,6 @@ #define NDISC_CACHE_H #include - #include #include "ns3/packet.h" @@ -32,6 +31,7 @@ #include "ns3/ptr.h" #include "ns3/timer.h" #include "ns3/sgi-hashmap.h" +#include "ns3/output-stream-wrapper.h" namespace ns3 { @@ -125,6 +125,13 @@ void SetDevice (Ptr device, Ptr interface); /** + * \brief Print the NDISC cache entries + * + * \param stream the ostream the NDISC cache entries is printed to + */ + void PrintNdiscCache (Ptr stream); + + /** * \class Entry * \brief A record that holds information about an NdiscCache entry. */