merge with ns-3.5
authorPavel Boyko <boyko@iitp.ru>
Sun, 05 Jul 2009 11:42:32 +0400
changeset 5104 1be48cec7e63
parent 5103 e0fff8a36c03 (current diff)
parent 4665 daf9af206d08 (diff)
child 5105 7f4bd2584e9d
merge with ns-3.5
--- a/.hgtags	Fri Jul 03 12:59:49 2009 +0400
+++ b/.hgtags	Sun Jul 05 11:42:32 2009 +0400
@@ -35,3 +35,4 @@
 13a5b15fbe3429a6c3d00c1bccffa2c156a0603b ns-3.5-rc1
 8562a42accf6f715d312c037326ec7da48095e13 ns-3.5-rc2
 a600c11ff8d40a40e88c2d692acad6512dde70c8 ns-3.5-rc3
+c975274c9707b1f07d94cc51f205c351122131a5 ns-3.5
--- a/RELEASE_NOTES	Fri Jul 03 12:59:49 2009 +0400
+++ b/RELEASE_NOTES	Sun Jul 05 11:42:32 2009 +0400
@@ -4,9 +4,7 @@
 This file contains ns-3 release notes (most recent releases first).
 
 All of the ns-3 documentation is accessible from the ns-3 website: 
-http://www.nsnam.org
-including tutorials:
-http://www.nsnam.org/tutorials.html
+http://www.nsnam.org including tutorials: http://www.nsnam.org/tutorials.html
 
 Release 3.5
 ===========
@@ -64,8 +62,8 @@
 ---------------
 Our next release, which is expected to happen in 2 to 4 months from now, will
 feature the merging of some of our projects currently in development including
-fuller IPv6 support, and some smaller features such as a new Global ARP package 
-and possibly a new Testing and Validation suite.
+fuller IPv6 support, some smaller features such as a new Global ARP 
+package, and possibly a new Testing and Validation suite.
 
 Release 3.4
 ===========
--- a/doc/manual/attributes.texi	Fri Jul 03 12:59:49 2009 +0400
+++ b/doc/manual/attributes.texi	Sun Jul 05 11:42:32 2009 +0400
@@ -114,6 +114,7 @@
 
 The public header file node.h has a declaration that includes
 a static GetTypeId function call:
+
 @verbatim
 class Node : public Object
 {
@@ -123,21 +124,72 @@
 @end verbatim
 
 This is defined in the node.cc file as follows:
+
 @verbatim
 TypeId 
 Node::GetTypeId (void)
 {
   static TypeId tid = TypeId ("ns3::Node")
     .SetParent<Object> ()
+    .AddConstructor<Node> ()
+    .AddAttribute ("DeviceList", "The list of devices associated to this Node.",
+                   ObjectVectorValue (),
+                   MakeObjectVectorAccessor (&Node::m_devices),
+                   MakeObjectVectorChecker<NetDevice> ())
+    .AddAttribute ("ApplicationList", "The list of applications associated to this Node.",
+                   ObjectVectorValue (),
+                   MakeObjectVectorAccessor (&Node::m_applications),
+                   MakeObjectVectorChecker<Application> ())
+    .AddAttribute ("Id", "The id (unique integer) of this Node.",
+                   TypeId::ATTR_GET, // allow only getting it.
+                   UintegerValue (0),
+                   MakeUintegerAccessor (&Node::m_id),
+                   MakeUintegerChecker<uint32_t> ())
     ;
   return tid;
 }
 @end verbatim
-Finally, when users want to create Nodes, they call:
+
+Look at the TypeId of an ns-3 @code{Object} class as an extended form of run 
+time type information (RTTI).  The C++ language includes simple kind of RTTI
+in order to support @code{dynamic_cast} and @code{typeid} operators.
+
+The ``@code{.SetParent<Object> ()}'' call in the declaration above is used in 
+conjunction with our object aggregation mechanisms to allow safe up- and
+down-casing in inheritance trees during @code{GetObject}.
+
+The ``@code{.AddConstructor<Node> ()}'' call is used in conjunction with our
+abstract object factory mechanisms to allow us to construct C++ objects without
+forcing a user to know the concrete class of the object she is building.
+
+The three calls to ``@code{.AddAttribute}'' associate a given string with a 
+strongly typed value in the class.  Notice that you must provide a help string
+which may be displayed, for example, via command line processors.  Each 
+@code{Attribute} is associated with mechanisms for accessing the underlying
+member variable in the object (for example, @code{MakeUintegerAccessor} tells
+the generic @code{Attribute} code how to get to the node ID above).  There are
+also ``Checker'' methods which are used to validate values.
+
+When users want to create Nodes, they will usually call some form of 
+@code{CreateObject},
+
 @verbatim
   Ptr<Node> n = CreateObject<Node> ();
 @end verbatim
 
+or more abstractly, using an object factory, you can create a @code{Node} object
+without even knowing the concrete C++ type
+
+@verbatim
+  ObjectFactory factory;
+  const std::string typeId = "ns3::Node'';
+  factory.SetTypeId(typeId);
+  Ptr<Object> node = factory.Create <Object> ();
+@end verbatim
+
+Both of these methods result in fully initialized attributes being available 
+in the resulting @code{Object} instances.
+
 We next discuss how attributes (values associated with member variables
 or functions of the class) are plumbed into the above TypeId.
 
@@ -206,6 +258,7 @@
 
 In the ns-3 attribute system, these value definitions and accessor
 functions are moved into the TypeId class; e.g.:  
+
 @verbatim
 NS_OBJECT_ENSURE_REGISTERED (DropTailQueue);
 
@@ -358,11 +411,11 @@
 
 @subsubsection Namespace-based access
 
-An alternative way to get at the attribute is to use the configuration
-namespace.  Here, this attribute resides on a known path in this
-namespace; this approach is useful if one doesn't have access to
-the underlying pointers and would like to configure a specific
-attribute with a single statement.  
+An alternative way to get at the attribute is to use the configuration namespace.
+Here, this attribute resides on a known path in this namespace; this approach
+is useful if one doesn't have access to the underlying pointers and would like
+to configure a specific attribute with a single statement.  
+
 @verbatim
   Config::Set ("/NodeList/0/DeviceList/0/TxQueue/MaxPackets", UintegerValue (25));
   txQueue->GetAttribute ("MaxPackets", limit); 
@@ -370,9 +423,8 @@
     limit.Get () << " packets");
 @end verbatim
 
-We could have also used wildcards to set this value for all nodes
-and all net devices (which in this simple example has the same
-effect as the previous Set())
+We could have also used wildcards to set this value for all nodes and all net 
+devices (which in this simple example has the same effect as the previous Set())
 @verbatim
   Config::Set ("/NodeList/*/DeviceList/*/TxQueue/MaxPackets", UintegerValue (15));
   txQueue->GetAttribute ("MaxPackets", limit); 
@@ -380,6 +432,22 @@
     limit.Get () << " packets");
 @end verbatim
 
+@subsubsection Object Name Service-based access
+
+Another way to get at the attribute is to use the object name service facility.
+Here, this attribute is found using a name string.  This approach is useful if 
+one doesn't have access to the underlying pointers and it is difficult to 
+determine the required concrete configuration namespaced path.
+
+@verbatim
+  Names::Add ("server", serverNode);
+  Names::Add ("server/eth0", serverDevice);
+
+  ...
+
+  Config::Set ("/Names/server/eth0/TxQueue/MaxPackets", UintegerValue (25));
+@end verbatim
+
 @subsection Setting through constructors helper classes
 
 Arbitrary combinations of attributes can be set and fetched from
@@ -438,13 +506,13 @@
 Suppose that someone working with Tcp wanted to get or set the 
 value of that variable using the metadata system.  If it were not
 already provided by ns-3, the user could declare the following addition 
-in the metadata system (to the TypeId declaration for TcpSocket):
+in the runtime metadata system (to the TypeId declaration for TcpSocket):
 @verbatim
-    .AddParameter ("Congestion window", 
+    .AddAttribute ("Congestion window", 
                    "Tcp congestion window (bytes)",
-                   Uinteger (1),
+                   UintegerValue (1),
                    MakeUintegerAccessor (&TcpSocket::m_cWnd),
-                   MakeUintegerChecker<uint16_t> ());
+                   MakeUintegerChecker<uint16_t> ())
 
 @end verbatim
 
@@ -511,21 +579,26 @@
 of writing 
 the conversions to/from strings and attribute values.  Most of this can be
 copy/pasted with macro-ized code.  For instance, consider class
-Rectangle in the @code{src/mobility/} directory:
+delcaration for Rectangle in the @code{src/mobility/} directory:
 
-One line is added to the class declaration:
 @verbatim
 /**
  * \brief a 2d rectangle
  */
 class Rectangle
 {
-...
+  ...
 
+  double xMin;
+  double xMax;
+  double yMin;
+  double yMax;
 };
 @end verbatim
  
-One macro call and two operators, are added below the class declaration:
+One macro call and two operators, must be added below the class declaration
+in order to turn a Rectangle into a value usable by the @code{Attribute}
+system:
 
 @verbatim
 std::ostream &operator << (std::ostream &os, const Rectangle &rectangle);
@@ -534,7 +607,7 @@
 ATTRIBUTE_HELPER_HEADER (Rectangle);
 @end verbatim
 
-In the class definition, the code looks like this:
+In the class definition (@code{.cc} file), the code looks like this:
 
 @verbatim
 ATTRIBUTE_HELPER_CPP (Rectangle);
@@ -568,9 +641,9 @@
 @node ConfigStore
 @section ConfigStore
 
-@strong{Feedback requested:}  This is an experimental feature of ns-3.
-It is not in the main tree.  If you like this feature and would like
-to provide feedback on it, please email us.
+@strong{Feedback requested:}  This is an experimental feature of ns-3.  It is 
+found in @code{src/contrib} and not in the main tree.  If you like this feature
+and would like to provide feedback on it, please email us.
 
 Values for ns-3 attributes can be stored in an ascii text file and
 loaded into a future simulation.  This feature is known as the
--- a/examples/virtual-net-device.cc	Fri Jul 03 12:59:49 2009 +0400
+++ b/examples/virtual-net-device.cc	Sun Jul 05 11:42:32 2009 +0400
@@ -78,23 +78,33 @@
   
   
   bool
-  N0N1VirtualSend (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
+  N0VirtualSend (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
   {
-    m_n3Socket->SendTo (packet, 0, InetSocketAddress (m_n3Address, 667));
+    NS_LOG_DEBUG ("Send to " << m_n3Address << ": " << *packet);
+    m_n0Socket->SendTo (packet, 0, InetSocketAddress (m_n3Address, 667));
+    return true;
+  }
+
+  bool
+  N1VirtualSend (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
+  {
+    NS_LOG_DEBUG ("Send to " << m_n3Address << ": " << *packet);
+    m_n1Socket->SendTo (packet, 0, InetSocketAddress (m_n3Address, 667));
     return true;
   }
 
   bool
   N3VirtualSend (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
   {
-    
     if (m_rng.GetValue () < 0.25)
       {
-        m_n0Socket->SendTo (packet, 0, InetSocketAddress (m_n0Address, 667));
+        NS_LOG_DEBUG ("Send to " << m_n0Address << ": " << *packet);
+        m_n3Socket->SendTo (packet, 0, InetSocketAddress (m_n0Address, 667));
       }
     else 
       {
-        m_n1Socket->SendTo (packet, 0, InetSocketAddress (m_n1Address, 667));
+        NS_LOG_DEBUG ("Send to " << m_n1Address << ": " << *packet);
+        m_n3Socket->SendTo (packet, 0, InetSocketAddress (m_n1Address, 667));
       }
     return true;
   }
@@ -102,6 +112,7 @@
   void N3SocketRecv (Ptr<Socket> socket)
   {
     Ptr<Packet> packet = socket->Recv (65535, 0);
+    NS_LOG_DEBUG ("N3SocketRecv: " << *packet);
     SocketAddressTag socketAddressTag;
     packet->RemovePacketTag (socketAddressTag);
     m_n3Tap->Receive (packet, 0x0800, m_n3Tap->GetAddress (), m_n3Tap->GetAddress (), NetDevice::PACKET_HOST);
@@ -110,6 +121,7 @@
   void N0SocketRecv (Ptr<Socket> socket)
   {
     Ptr<Packet> packet = socket->Recv (65535, 0);
+    NS_LOG_DEBUG ("N0SocketRecv: " << *packet);
     SocketAddressTag socketAddressTag;
     packet->RemovePacketTag (socketAddressTag);
     m_n0Tap->Receive (packet, 0x0800, m_n0Tap->GetAddress (), m_n0Tap->GetAddress (), NetDevice::PACKET_HOST);
@@ -118,6 +130,7 @@
   void N1SocketRecv (Ptr<Socket> socket)
   {
     Ptr<Packet> packet = socket->Recv (65535, 0);
+    NS_LOG_DEBUG ("N1SocketRecv: " << *packet);
     SocketAddressTag socketAddressTag;
     packet->RemovePacketTag (socketAddressTag);
     m_n1Tap->Receive (packet, 0x0800, m_n1Tap->GetAddress (), m_n1Tap->GetAddress (), NetDevice::PACKET_HOST);
@@ -144,7 +157,7 @@
     // n0 tap device
     m_n0Tap = CreateObject<VirtualNetDevice> ();
     m_n0Tap->SetAddress (Mac48Address ("11:00:01:02:03:01"));
-    m_n0Tap->SetSendCallback (MakeCallback (&Tunnel::N0N1VirtualSend, this));
+    m_n0Tap->SetSendCallback (MakeCallback (&Tunnel::N0VirtualSend, this));
     n0->AddDevice (m_n0Tap);
     Ptr<Ipv4> ipv4 = n0->GetObject<Ipv4> ();
     uint32_t i = ipv4->AddInterface (m_n0Tap);
@@ -154,7 +167,7 @@
     // n1 tap device
     m_n1Tap = CreateObject<VirtualNetDevice> ();
     m_n1Tap->SetAddress (Mac48Address ("11:00:01:02:03:02"));
-    m_n1Tap->SetSendCallback (MakeCallback (&Tunnel::N0N1VirtualSend, this));
+    m_n1Tap->SetSendCallback (MakeCallback (&Tunnel::N1VirtualSend, this));
     n1->AddDevice (m_n1Tap);
     ipv4 = n1->GetObject<Ipv4> ();
     i = ipv4->AddInterface (m_n1Tap);
@@ -186,6 +199,8 @@
 #if 0 
   LogComponentEnable ("VirtualNetDeviceExample", LOG_LEVEL_INFO);
 #endif
+  Packet::EnablePrinting ();
+  
 
   // Set up some default values for the simulation.  Use the 
   Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (210));
@@ -260,11 +275,11 @@
     Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
   apps = sink.Install (c.Get (3));
   apps.Start (Seconds (1.0));
-  apps.Stop (Seconds (10.0));
+  //apps.Stop (Seconds (10.0));
 
   // Create a similar flow from n3 to n1, starting at time 1.1 seconds
   onoff.SetAttribute ("Remote", 
-                      AddressValue (InetSocketAddress (Ipv4Address ("11.0.0.2"), port)));
+                      AddressValue (InetSocketAddress (Ipv4Address ("11.0.0.1"), port)));
   apps = onoff.Install (c.Get (3));
   apps.Start (Seconds (1.1));
   apps.Stop (Seconds (10.0));
@@ -272,7 +287,7 @@
   // Create a packet sink to receive these packets
   apps = sink.Install (c.Get (1));
   apps.Start (Seconds (1.1));
-  apps.Stop (Seconds (10.0));
+  //apps.Stop (Seconds (10.0));
 
   std::ofstream ascii;
   ascii.open ("virtual-net-device.tr");
--- a/src/core/global-value.cc	Fri Jul 03 12:59:49 2009 +0400
+++ b/src/core/global-value.cc	Sun Jul 05 11:42:32 2009 +0400
@@ -174,6 +174,30 @@
 {
   return GetVector ()->end ();
 }
+
+bool
+GlobalValue::GetValueByNameFailSafe (std::string name, AttributeValue &value)
+{
+  for (GlobalValue::Iterator gvit = GlobalValue::Begin (); gvit != GlobalValue::End (); ++gvit)
+    {
+      if ((*gvit)->GetName () == name)
+         {
+           (*gvit)->GetValue (value);  
+           return true;
+         }
+    } 
+  return false; // not found
+}
+
+void
+GlobalValue::GetValueByName (std::string name, AttributeValue &value)
+{
+  if (! GetValueByNameFailSafe (name, value))
+    {
+      NS_FATAL_ERROR ("Could not find GlobalValue named \"" << name << "\"");
+    }
+}
+
 GlobalValue::Vector *
 GlobalValue::GetVector (void)
 {
--- a/src/core/global-value.h	Fri Jul 03 12:59:49 2009 +0400
+++ b/src/core/global-value.h	Sun Jul 05 11:42:32 2009 +0400
@@ -114,6 +114,30 @@
    * \returns an iterator which represents a pointer to the last GlobalValue registered.
    */
   static Iterator End (void);
+
+
+  /** 
+   * finds the GlobalValue with the given name and returns its value
+   * 
+   * @param name the name of the GlobalValue to be found
+   * @param value where to store the value of the found GlobalValue
+   * 
+   * @return true if the GlobalValue was found, false otherwise
+   */
+  static bool GetValueByNameFailSafe (std::string name, AttributeValue &value);
+
+  /** 
+   * finds the GlobalValue with the given name and returns its
+   * value. This method cannot fail, i.e., it will trigger a
+   * NS_FATAL_ERROR if the requested GlobalValue is not found.
+   * 
+   * @param name the name of the GlobalValue to be found
+   * @param value where to store the value of the found GlobalValue
+   * 
+   */
+  static void GetValueByName (std::string name, AttributeValue &value);
+  
+
 private:
   friend class GlobalValueTests;
   static Vector *GetVector (void);
--- a/src/helper/bridge-helper.h	Fri Jul 03 12:59:49 2009 +0400
+++ b/src/helper/bridge-helper.h	Sun Jul 05 11:42:32 2009 +0400
@@ -1,3 +1,23 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Gustavo Carneiro <gjc@inescporto.pt>
+ */
 #ifndef BRIDGE_HELPER_H
 #define BRIDGE_HELPER_H
 
@@ -10,12 +30,42 @@
 class Node;
 class AttributeValue;
 
+/**
+ * \brief Add capability to bridge multiple LAN segments (IEEE 802.1D bridging)
+ */
 class BridgeHelper
 {
 public:
   BridgeHelper ();
+  /**
+   * \param n1 the name of the attribute to set
+   * \param v1 the value of the attribute to set
+   *
+   * Set an attribute on each ns3::BridgeNetDevice created by
+   * BridgeHelper::Install
+   */
   void SetDeviceAttribute (std::string n1, const AttributeValue &v1);
+  /**
+   * This method creates an ns3::BridgeNetDevice with the attributes
+   * configured by BridgeHelper::SetDeviceAttribute, adds the device
+   * to the node, and attaches the given NetDevices as ports of the
+   * bridge.
+   *
+   * \param node The node to install the device in
+   * \param c Container of NetDevices to add as bridge ports
+   * \returns A containter holding the added net device.
+   */
   NetDeviceContainer Install (Ptr<Node> node, NetDeviceContainer c);
+  /**
+   * This method creates an ns3::BridgeNetDevice with the attributes
+   * configured by BridgeHelper::SetDeviceAttribute, adds the device
+   * to the node, and attaches the given NetDevices as ports of the
+   * bridge.
+   *
+   * \param nodeName The name of the node to install the device in
+   * \param c Container of NetDevices to add as bridge ports
+   * \returns A containter holding the added net device.
+   */
   NetDeviceContainer Install (std::string nodeName, NetDeviceContainer c);
 private:
   ObjectFactory m_deviceFactory;
--- a/src/helper/ipv4-list-routing-helper.h	Fri Jul 03 12:59:49 2009 +0400
+++ b/src/helper/ipv4-list-routing-helper.h	Sun Jul 05 11:42:32 2009 +0400
@@ -28,6 +28,9 @@
 
 /**
  * \brief Helper class that adds ns3::Ipv4ListRouting objects
+ *
+ * This class is expected to be used in conjunction with 
+ * ns3::InternetStackHelper::SetRoutingHelper
  */
 class Ipv4ListRoutingHelper : public Ipv4RoutingHelper
 {
--- a/src/helper/ipv4-routing-helper.h	Fri Jul 03 12:59:49 2009 +0400
+++ b/src/helper/ipv4-routing-helper.h	Sun Jul 05 11:42:32 2009 +0400
@@ -33,7 +33,7 @@
  * For each new routing protocol created as a subclass of 
  * ns3::Ipv4RoutingProtocol, you need to create a subclass of 
  * ns3::Ipv4RoutingHelper which can be used by 
- * ns3::InternetStackHelper::SetRoutingProtocol and 
+ * ns3::InternetStackHelper::SetRoutingHelper and 
  * ns3::InternetStackHelper::Install.
  */
 class Ipv4RoutingHelper
--- a/src/helper/ipv4-static-routing-helper.h	Fri Jul 03 12:59:49 2009 +0400
+++ b/src/helper/ipv4-static-routing-helper.h	Sun Jul 05 11:42:32 2009 +0400
@@ -33,6 +33,9 @@
 
 /**
  * \brief Helper class that adds ns3::Ipv4StaticRouting objects
+ *
+ * This class is expected to be used in conjunction with 
+ * ns3::InternetStackHelper::SetRoutingHelper
  */
 class Ipv4StaticRoutingHelper : public Ipv4RoutingHelper
 {
--- a/src/helper/nqos-wifi-mac-helper.h	Fri Jul 03 12:59:49 2009 +0400
+++ b/src/helper/nqos-wifi-mac-helper.h	Sun Jul 05 11:42:32 2009 +0400
@@ -24,6 +24,10 @@
 
 namespace ns3 {
 
+/**
+ * \brief create non-qos MAC layers for a ns3::WifiNetDevice. 
+ * This class can create MACs of type ns3::NqapWifiMac, ns3::NqstaWifiMac, and, ns3::AdhocWifiMac
+ */
 class NqosWifiMacHelper : public WifiMacHelper
 {
 public:
--- a/src/helper/olsr-helper.h	Fri Jul 03 12:59:49 2009 +0400
+++ b/src/helper/olsr-helper.h	Sun Jul 05 11:42:32 2009 +0400
@@ -29,6 +29,9 @@
 
 /**
  * \brief Helper class that adds OLSR routing to nodes.
+ *
+ * This class is expected to be used in conjunction with 
+ * ns3::InternetStackHelper::SetRoutingHelper
  */
 class OlsrHelper : public Ipv4RoutingHelper
 {
--- a/src/helper/qos-wifi-mac-helper.h	Fri Jul 03 12:59:49 2009 +0400
+++ b/src/helper/qos-wifi-mac-helper.h	Sun Jul 05 11:42:32 2009 +0400
@@ -27,6 +27,10 @@
 
 namespace ns3 {
 
+/**
+ * \brief create qos MAC layers for a ns3::WifiNetDevice. 
+ * This class can create MACs of type ns3::QapWifiMac, ns3::QstaWifiMac, and, ns3::QadhocWifiMac
+ */
 class QosWifiMacHelper : public WifiMacHelper
 {
 public:
--- a/src/internet-stack/ipv4-interface.cc	Fri Jul 03 12:59:49 2009 +0400
+++ b/src/internet-stack/ipv4-interface.cc	Sun Jul 05 11:42:32 2009 +0400
@@ -178,7 +178,7 @@
 void
 Ipv4Interface::Send (Ptr<Packet> p, Ipv4Address dest)
 {
-  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_FUNCTION (dest << *p);
   if (!IsUp()) 
     {
       return;