merge in packet.bundle
authorCraig Dowell <craigdo@ee.washington.edu>
Mon, 29 Oct 2007 12:48:01 -0700
changeset 1867 16deaedc0380
parent 1803 4078e5efdfc6 (current diff)
parent 1866 e7dbcc4df546 (diff)
child 1868 06027fd6a68c
merge in packet.bundle
src/applications/packet-sink/packet-sink.cc
src/applications/udp-echo/udp-echo-server.cc
src/common/packet.h
src/core/ptr.h
src/devices/csma/csma-channel.cc
src/devices/csma/csma-channel.h
src/devices/point-to-point/point-to-point-channel.cc
src/devices/point-to-point/point-to-point-channel.h
src/devices/point-to-point/point-to-point-net-device.h
src/internet-node/ipv4-interface.cc
src/internet-node/ipv4-interface.h
src/internet-node/ipv4-l3-protocol.cc
src/internet-node/ipv4-l3-protocol.h
src/internet-node/ipv4-static-routing.h
src/internet-node/udp-l4-protocol.h
src/internet-node/udp-socket.cc
src/node/ipv4.h
--- a/samples/main-packet-printer.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/samples/main-packet-printer.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -49,7 +49,7 @@
 {
   // We create a packet with 1000 bytes of zero payload
   // and add 3 headers to this packet.
-  Packet p (1000);
+  Ptr<Packet> p = Create<Packet> (1000);
   Ipv4Header ipv4;
   UdpHeader udp;
   ipv4.SetSource (Ipv4Address ("192.168.0.1"));
@@ -57,36 +57,36 @@
   udp.SetSource (1025);
   udp.SetDestination (80);
   udp.SetPayloadSize (1000);
-  p.AddHeader (udp);
-  p.AddHeader (ipv4);
+  p->AddHeader (udp);
+  p->AddHeader (ipv4);
 
-  std::cout << "full packet size=" << p.GetSize () << std::endl;
+  std::cout << "full packet size=" << p->GetSize () << std::endl;
   // Here, invoke the default Print routine, directed to std out
-  p.Print (std::cout);
+  p->Print (std::cout);
   std::cout << std::endl;
 
 
   // Now, we fragment our packet in 3 consecutive pieces.
-  Packet p1 = p.CreateFragment (0, 2);
-  Packet p2 = p.CreateFragment (2, 1000);
-  Packet p3 = p.CreateFragment (1002, 26);
+  Ptr<Packet> p1 = p->CreateFragment (0, 2);
+  Ptr<Packet> p2 = p->CreateFragment (2, 1000);
+  Ptr<Packet> p3 = p->CreateFragment (1002, 26);
 
   std::cout << "fragment1" << std::endl;
-  p1.Print (std::cout);
+  p1->Print (std::cout);
   std::cout << std::endl;
   std::cout << "fragment2" << std::endl;
-  p2.Print (std::cout);
+  p2->Print (std::cout);
   std::cout << std::endl;
   std::cout << "fragment3" << std::endl;
-  p3.Print (std::cout);
+  p3->Print (std::cout);
   std::cout << std::endl;
 
   // And, finally, we re-aggregate the 3 consecutive pieces.
-  Packet aggregate = p1;
-  aggregate.AddAtEnd (p2);
-  aggregate.AddAtEnd (p3);
+  Ptr<Packet> aggregate = p1->Copy ();
+  aggregate->AddAtEnd (p2);
+  aggregate->AddAtEnd (p3);
   std::cout << "aggregated" << std::endl;
-  aggregate.Print (std::cout);
+  aggregate->Print (std::cout);
   std::cout << std::endl;
 }
 
@@ -128,7 +128,7 @@
 
 
   // We create a packet with 1000 bytes of zero payload
-  Packet p (1000);
+  Ptr<Packet> p = Create<Packet> (1000);
   Ipv4Header ipv4;
   UdpHeader udp;
   ipv4.SetSource (Ipv4Address ("192.168.0.1"));
@@ -136,35 +136,35 @@
   udp.SetSource (1025);
   udp.SetDestination (80);
   udp.SetPayloadSize (1000);
-  p.AddHeader (udp);
-  p.AddHeader (ipv4);
+  p->AddHeader (udp);
+  p->AddHeader (ipv4);
 
-  std::cout << "full packet size=" << p.GetSize () << std::endl;
-  p.Print (std::cout, printer);
+  std::cout << "full packet size=" << p->GetSize () << std::endl;
+  p->Print (std::cout, printer);
   std::cout << std::endl;
 
 
   // fragment our packet in 3 pieces
-  Packet p1 = p.CreateFragment (0, 2);
-  Packet p2 = p.CreateFragment (2, 1000);
-  Packet p3 = p.CreateFragment (1002, 26);
+  Ptr<Packet> p1 = p->CreateFragment (0, 2);
+  Ptr<Packet> p2 = p->CreateFragment (2, 1000);
+  Ptr<Packet> p3 = p->CreateFragment (1002, 26);
   std::cout << "fragment1" << std::endl;
-  p1.Print (std::cout, printer);
+  p1->Print (std::cout, printer);
   std::cout << std::endl;
   std::cout << "fragment2" << std::endl;
-  p2.Print (std::cout, printer);
+  p2->Print (std::cout, printer);
   std::cout << std::endl;
   std::cout << "fragment3" << std::endl;
-  p3.Print (std::cout, printer);
+  p3->Print (std::cout, printer);
   std::cout << std::endl;
 
   // aggregate all 3 fragments of the original packet
   // to reconstruct a copy of the original packet.
-  Packet aggregate = p1;
-  aggregate.AddAtEnd (p2);
-  aggregate.AddAtEnd (p3);
+  Ptr<Packet> aggregate = p1->Copy ();
+  aggregate->AddAtEnd (p2);
+  aggregate->AddAtEnd (p3);
   std::cout << "aggregated" << std::endl;
-  aggregate.Print (std::cout, printer);
+  aggregate->Print (std::cout, printer);
   std::cout << std::endl;
 }
 
--- a/samples/main-packet-tag.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/samples/main-packet-tag.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -116,20 +116,20 @@
   tag.SetSimpleValue (0x56);
 
   // store the tag in a packet.
-  Packet p;
-  p.AddTag (tag);
+  Ptr<Packet> p = Create<Packet> ();
+  p->AddTag (tag);
 
   // create a copy of the packet
-  Packet aCopy = p;
+  Ptr<Packet> aCopy = p->Copy ();
 
   // read the tag from the packet copy
   MyTag tagCopy;
-  p.PeekTag (tagCopy);
+  p->PeekTag (tagCopy);
 
   // the copy and the original are the same !
   NS_ASSERT (tagCopy.GetSimpleValue () == tag.GetSimpleValue ());
 
-  aCopy.PrintTags (std::cout);
+  aCopy->PrintTags (std::cout);
   std::cout << std::endl;
 
   return 0;
--- a/samples/main-simple.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/samples/main-simple.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -14,7 +14,7 @@
 GenerateTraffic (Ptr<Socket> socket, uint32_t size)
 {
   std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, tx bytes=" << size << std::endl;
-  socket->Send (Packet (size));
+  socket->Send (Create<Packet> (size));
   if (size > 0)
     {
       Simulator::Schedule (Seconds (0.5), &GenerateTraffic, socket, size - 50);
@@ -26,9 +26,9 @@
 }
 
 static void
-SocketPrinter (Ptr<Socket> socket, const Packet &packet, const Address &from)
+SocketPrinter (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from)
 {
-  std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, rx bytes=" << packet.GetSize () << std::endl;
+  std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, rx bytes=" << packet->GetSize () << std::endl;
 }
 
 static void
--- a/src/applications/onoff/onoff-application.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/applications/onoff/onoff-application.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -240,7 +240,8 @@
   NS_LOG_FUNCTION;
 
   NS_ASSERT (m_sendEvent.IsExpired ());
-  m_socket->Send(Packet (m_pktSize));
+  Ptr<Packet> packet = Create<Packet> (m_pktSize);
+  m_socket->Send (packet);
   m_totBytes += m_pktSize;
   m_lastStartTime = Simulator::Now();
   m_residualBits = 0;
--- a/src/applications/packet-sink/packet-sink.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/applications/packet-sink/packet-sink.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -78,6 +78,7 @@
       m_socket = socketFactory->CreateSocket ();
       m_socket->Bind (m_local);
     }
+
   m_socket->SetRecvCallback (MakeCallback(&PacketSink::Receive, this));
 }
 
@@ -86,21 +87,20 @@
   if (!m_socket) 
     {
       m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket>, 
-        const Packet &, const Address &> ());
- 
+        Ptr<Packet>, const Address &> ());
     }
 }
 
 // This LOG output inspired by the application on Joseph Kopena's wiki
-void PacketSink::Receive(Ptr<Socket> socket, const Packet &packet,
+void PacketSink::Receive(Ptr<Socket> socket, Ptr<Packet> packet,
                        const Address &from) 
 {
   if (InetSocketAddress::IsMatchingType (from))
     {
       InetSocketAddress address = InetSocketAddress::ConvertFrom (from);
-      NS_LOG_INFO ("Received " << packet.GetSize() << " bytes from " << 
+      NS_LOG_INFO ("Received " << packet->GetSize() << " bytes from " << 
         address.GetIpv4() << " [" << address << "]---'" << 
-        packet.PeekData() << "'");
+        packet->PeekData() << "'");
       // TODO:  Add a tracing source here
     }
 }
--- a/src/applications/packet-sink/packet-sink.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/applications/packet-sink/packet-sink.h	Mon Oct 29 12:48:01 2007 -0700
@@ -73,7 +73,7 @@
                   const Address &local,
                   std::string iid);
 
-  virtual void Receive (Ptr<Socket> socket, const Packet& packet, const Address& from);
+  virtual void Receive (Ptr<Socket> socket, Ptr<Packet> packet, const Address& from);
 
   Ptr<Socket>     m_socket;       // Associated socket
   Address         m_local;        // Local address to bind to
--- a/src/applications/udp-echo/udp-echo-client.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/applications/udp-echo/udp-echo-client.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -101,8 +101,7 @@
       m_socket->Connect (m_peer);
     }
 
-  m_socket->SetRecvCallback((Callback<void, Ptr<Socket>, const Packet &,
-    const Address &>) MakeCallback(&UdpEchoClient::Receive, this));
+  m_socket->SetRecvCallback(MakeCallback(&UdpEchoClient::Receive, this));
 
   ScheduleTransmit (Seconds(0.));
 }
@@ -114,8 +113,8 @@
 
   if (!m_socket) 
     {
-      m_socket->SetRecvCallback((Callback<void, Ptr<Socket>, const Packet &,
-        const Address &>) NULL);
+      m_socket->SetRecvCallback(MakeNullCallback<void, Ptr<Socket>, Ptr<Packet>,
+                                const Address &> ());
     }
 
   Simulator::Cancel(m_sendEvent);
@@ -135,7 +134,7 @@
 
   NS_ASSERT (m_sendEvent.IsExpired ());
 
-  Packet p (m_size);
+  Ptr<Packet> p = Create<Packet> (m_size);
   m_socket->Send (p);
   ++m_sent;
 
@@ -150,7 +149,7 @@
 void
 UdpEchoClient::Receive(
   Ptr<Socket> socket, 
-  const Packet &packet,
+  Ptr<Packet> packet,
   const Address &from) 
 {
   NS_LOG_FUNCTION;
@@ -159,7 +158,7 @@
   if (InetSocketAddress::IsMatchingType (from))
     {
       InetSocketAddress address = InetSocketAddress::ConvertFrom (from);
-      NS_LOG_INFO ("Received " << packet.GetSize() << " bytes from " << 
+      NS_LOG_INFO ("Received " << packet->GetSize() << " bytes from " << 
         address.GetIpv4());
     }
 }
--- a/src/applications/udp-echo/udp-echo-client.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/applications/udp-echo/udp-echo-client.h	Mon Oct 29 12:48:01 2007 -0700
@@ -50,7 +50,7 @@
   void ScheduleTransmit (Time dt);
   void Send (void);
 
-  void Receive(Ptr<Socket> socket, const Packet &packet, const Address &from);
+  void Receive(Ptr<Socket> socket, Ptr<Packet> packet, const Address &from);
 
   Ptr<Node> m_node;
   Ipv4Address m_serverAddress;
--- a/src/applications/udp-echo/udp-echo-server.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/applications/udp-echo/udp-echo-server.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -94,15 +94,15 @@
 
   if (!m_socket) 
     {
-      m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket>, 
-        const Packet &, const Address &> ());
+      m_socket->SetRecvCallback(MakeNullCallback<void, Ptr<Socket>, 
+        Ptr<Packet>, const Address &> ());
     }
 }
 
 void
 UdpEchoServer::Receive(
   Ptr<Socket> socket, 
-  const Packet &packet,
+  Ptr<Packet> packet,
   const Address &from) 
 {
   NS_LOG_FUNCTION;
@@ -111,7 +111,7 @@
   if (InetSocketAddress::IsMatchingType (from))
     {
       InetSocketAddress address = InetSocketAddress::ConvertFrom (from);
-      NS_LOG_INFO ("Received " << packet.GetSize() << " bytes from " << 
+      NS_LOG_INFO ("Received " << packet->GetSize() << " bytes from " << 
         address.GetIpv4());
 
       NS_LOG_LOGIC ("Echoing packet");
--- a/src/applications/udp-echo/udp-echo-server.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/applications/udp-echo/udp-echo-server.h	Mon Oct 29 12:48:01 2007 -0700
@@ -44,7 +44,7 @@
   virtual void StartApplication (void);
   virtual void StopApplication (void);
 
-  void Receive(Ptr<Socket> socket, const Packet &packet, const Address &from);
+  void Receive(Ptr<Socket> socket, Ptr<Packet> packet, const Address &from);
 
   Ptr<Node> m_node;
   uint16_t m_port;
--- a/src/common/packet-metadata-test.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/common/packet-metadata-test.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -199,7 +199,7 @@
 public:
   PacketMetadataTest ();
   virtual ~PacketMetadataTest ();
-  bool CheckHistory (Packet p, const char *file, int line, uint32_t n, ...);
+  bool CheckHistory (Ptr<Packet> p, const char *file, int line, uint32_t n, ...);
   virtual bool RunTests (void);
 private:
   template <int N>
@@ -217,7 +217,7 @@
   template <int N>
   void RegisterTrailer (void);
   void CleanupPrints (void);
-  Packet DoAddHeader (Packet p);
+  Ptr<Packet> DoAddHeader (Ptr<Packet> p);
   bool Check (const char *file, int line, std::list<int> expected);
 
 
@@ -358,7 +358,7 @@
 }
 
 bool 
-PacketMetadataTest::CheckHistory (Packet p, const char *file, int line, uint32_t n, ...)
+PacketMetadataTest::CheckHistory (Ptr<Packet> p, const char *file, int line, uint32_t n, ...)
 {
   m_headerError = false;
   m_trailerError = false;
@@ -373,7 +373,7 @@
   va_end (ap);
 
   m_printer.PrintForward ();
-  p.Print (Failure (), m_printer);
+  p->Print (Failure (), m_printer);
   bool ok = Check (file, line, expected);
   CleanupPrints ();
   if (!ok)
@@ -382,7 +382,7 @@
     }
 
   m_printer.PrintBackward ();
-  p.Print (Failure (), m_printer);
+  p->Print (Failure (), m_printer);
   expected.reverse ();
   ok = Check (file, line, expected);
   CleanupPrints ();
@@ -393,25 +393,25 @@
   {                                             \
     HistoryHeader<n> header;                    \
     RegisterHeader<n> ();                       \
-    p.AddHeader (header);                       \
+    p->AddHeader (header);                      \
   }
 #define ADD_TRAILER(p, n)                       \
   {                                             \
     HistoryTrailer<n> trailer;                  \
     RegisterTrailer<n> ();                      \
-    p.AddTrailer (trailer);                     \
+    p->AddTrailer (trailer);                    \
   }
 #define REM_HEADER(p, n)                        \
   {                                             \
     HistoryHeader<n> header;                    \
     RegisterHeader<n> ();                       \
-    p.RemoveHeader (header);                    \
+    p->RemoveHeader (header);                   \
   }
 #define REM_TRAILER(p, n)                       \
   {                                             \
     HistoryTrailer<n> trailer;                  \
     RegisterTrailer<n> ();                      \
-    p.RemoveTrailer (trailer);                  \
+    p->RemoveTrailer (trailer);                 \
   }
 #define CHECK_HISTORY(p, ...)                   \
   {                                             \
@@ -421,9 +421,9 @@
         ok = false;                             \
       }                                         \
     Buffer buffer;                              \
-    buffer = p.Serialize ();                    \
-    Packet otherPacket;                         \
-    otherPacket.Deserialize  (buffer);          \
+    buffer = p->Serialize ();                   \
+    Ptr<Packet> otherPacket = Create<Packet> ();\
+    otherPacket->Deserialize  (buffer);         \
     if (!CheckHistory (otherPacket, __FILE__,   \
                       __LINE__, __VA_ARGS__))   \
       {                                         \
@@ -432,8 +432,8 @@
   }
 
 
-Packet 
-PacketMetadataTest::DoAddHeader (Packet p)
+Ptr<Packet>
+PacketMetadataTest::DoAddHeader (Ptr<Packet> p)
 {
   ADD_HEADER (p, 10);
   return p;
@@ -446,14 +446,14 @@
 
   PacketMetadata::Enable ();
 
-  Packet p = Packet (0);
-  Packet p1 = Packet (0);
+  Ptr<Packet> p = Create<Packet> (0);
+  Ptr<Packet> p1 = Create<Packet> (0);
 
-  p = Packet (10);
+  p = Create<Packet> (10);
   ADD_TRAILER (p, 100);
   CHECK_HISTORY (p, 2, 10, 100);
 
-  p = Packet (10);
+  p = Create<Packet> (10);
   ADD_HEADER (p, 1);
   ADD_HEADER (p, 2);
   ADD_HEADER (p, 3);
@@ -466,7 +466,7 @@
   CHECK_HISTORY (p, 6, 
                  6, 5, 3, 2, 1, 10);
 
-  p = Packet (10);
+  p = Create<Packet> (10);
   ADD_HEADER (p, 1);
   ADD_HEADER (p, 2);
   ADD_HEADER (p, 3);
@@ -474,7 +474,7 @@
   CHECK_HISTORY (p, 3, 
                  2, 1, 10);
 
-  p = Packet (10);
+  p = Create<Packet> (10);
   ADD_HEADER (p, 1);
   ADD_HEADER (p, 2);
   ADD_HEADER (p, 3);
@@ -483,7 +483,7 @@
   CHECK_HISTORY (p, 2, 
                  1, 10);
 
-  p = Packet (10);
+  p = Create<Packet> (10);
   ADD_HEADER (p, 1);
   ADD_HEADER (p, 2);
   ADD_HEADER (p, 3);
@@ -492,11 +492,11 @@
   REM_HEADER (p, 1);
   CHECK_HISTORY (p, 1, 10);
 
-  p = Packet (10);
+  p = Create<Packet> (10);
   ADD_HEADER (p, 1);
   ADD_HEADER (p, 2);
   ADD_HEADER (p, 3);
-  p1 = p;
+  p1 = p->Copy ();
   REM_HEADER (p1, 3);
   REM_HEADER (p1, 2);
   REM_HEADER (p1, 1);
@@ -524,88 +524,88 @@
   REM_TRAILER (p, 5);
   CHECK_HISTORY (p, 5, 
                  3, 2, 1, 10, 4);
-  p1 = p;
+  p1 = p->Copy ();
   REM_TRAILER (p, 4);
   CHECK_HISTORY (p, 4, 
                  3, 2, 1, 10);
   CHECK_HISTORY (p1, 5, 
                  3, 2, 1, 10, 4);
-  p1.RemoveAtStart (3);
+  p1->RemoveAtStart (3);
   CHECK_HISTORY (p1, 4, 
                  2, 1, 10, 4);
-  p1.RemoveAtStart (1);
+  p1->RemoveAtStart (1);
   CHECK_HISTORY (p1, 4, 
                  1, 1, 10, 4);
-  p1.RemoveAtStart (1);
+  p1->RemoveAtStart (1);
   CHECK_HISTORY (p1, 3, 
                  1, 10, 4);
-  p1.RemoveAtEnd (4);
+  p1->RemoveAtEnd (4);
   CHECK_HISTORY (p1, 2, 
                  1, 10);
-  p1.RemoveAtStart (1);
+  p1->RemoveAtStart (1);
   CHECK_HISTORY (p1, 1, 10);
 
-  p = Packet (10);
+  p = Create<Packet> (10);
   ADD_HEADER (p, 8);
   ADD_TRAILER (p, 8);
   ADD_TRAILER (p, 8);
-  p.RemoveAtStart (8+10+8);
+  p->RemoveAtStart (8+10+8);
   CHECK_HISTORY (p, 1, 8);
 
-  p = Packet (10);
+  p = Create<Packet> (10);
   ADD_HEADER (p, 10);
   ADD_HEADER (p, 8);
   ADD_TRAILER (p, 6);
   ADD_TRAILER (p, 7);
   ADD_TRAILER (p, 9);
-  p.RemoveAtStart (5);
-  p.RemoveAtEnd (12);
+  p->RemoveAtStart (5);
+  p->RemoveAtEnd (12);
   CHECK_HISTORY (p, 5, 3, 10, 10, 6, 4);
 
-  p = Packet (10);
+  p = Create<Packet> (10);
   ADD_HEADER (p, 10);
   ADD_TRAILER (p, 6);
-  p.RemoveAtEnd (18);
+  p->RemoveAtEnd (18);
   ADD_TRAILER (p, 5);
   ADD_HEADER (p, 3);
   CHECK_HISTORY (p, 3, 3, 8, 5);
-  p.RemoveAtStart (12);
+  p->RemoveAtStart (12);
   CHECK_HISTORY (p, 1, 4);
-  p.RemoveAtEnd (2);
+  p->RemoveAtEnd (2);
   CHECK_HISTORY (p, 1, 2);
   ADD_HEADER (p, 10);
   CHECK_HISTORY (p, 2, 10, 2);
-  p.RemoveAtEnd (5);
+  p->RemoveAtEnd (5);
   CHECK_HISTORY (p, 1, 7);
 
-  Packet p2 = Packet (0);
-  Packet p3 = Packet (0);
+  Ptr<Packet> p2 = Create<Packet> (0);
+  Ptr<Packet> p3 = Create<Packet> (0);
 
-  p = Packet (40);
+  p = Create<Packet> (40);
   ADD_HEADER (p, 5);
   ADD_HEADER (p, 8);
   CHECK_HISTORY (p, 3, 8, 5, 40);
-  p1 = p.CreateFragment (0, 5);
-  p2 = p.CreateFragment (5, 5);
-  p3 = p.CreateFragment (10, 43);
+  p1 = p->CreateFragment (0, 5);
+  p2 = p->CreateFragment (5, 5);
+  p3 = p->CreateFragment (10, 43);
   CHECK_HISTORY (p1, 1, 5);
   CHECK_HISTORY (p2, 2, 3, 2);
   CHECK_HISTORY (p3, 2, 3, 40);
-  p1.AddAtEnd (p2);
+  p1->AddAtEnd (p2);
   CHECK_HISTORY (p1, 2, 8, 2);
   CHECK_HISTORY (p2, 2, 3, 2);
-  p1.AddAtEnd (p3);
+  p1->AddAtEnd (p3);
   CHECK_HISTORY (p1, 3, 8, 5, 40);
   CHECK_HISTORY (p2, 2, 3, 2);
   CHECK_HISTORY (p3, 2, 3, 40);
-  p1 = p.CreateFragment (0, 5);
+  p1 = p->CreateFragment (0, 5);
   CHECK_HISTORY (p1, 1, 5);
 
-  p3 = Packet (50);
+  p3 = Create<Packet> (50);
   ADD_HEADER (p3, 8);
   CHECK_HISTORY (p3, 2, 8, 50);
   CHECK_HISTORY (p1, 1, 5);
-  p1.AddAtEnd (p3);
+  p1->AddAtEnd (p3);
   CHECK_HISTORY (p1, 3, 5, 8, 50);
   ADD_HEADER (p1, 5);
   CHECK_HISTORY (p1, 4, 5, 5, 8, 50);
@@ -613,71 +613,71 @@
   CHECK_HISTORY (p1, 5, 5, 5, 8, 50, 2);
   REM_HEADER (p1, 5);
   CHECK_HISTORY (p1, 4, 5, 8, 50, 2);
-  p1.RemoveAtEnd (60);
+  p1->RemoveAtEnd (60);
   CHECK_HISTORY (p1, 1, 5);
-  p1.AddAtEnd (p2);
+  p1->AddAtEnd (p2);
   CHECK_HISTORY (p1, 2, 8, 2);
   CHECK_HISTORY (p2, 2, 3, 2);
 
-  p3 = Packet (40);
+  p3 = Create<Packet> (40);
   ADD_HEADER (p3, 5);
   ADD_HEADER (p3, 5);
   CHECK_HISTORY (p3, 3, 5, 5, 40);
-  p1 = p3.CreateFragment (0, 5);
-  p2 = p3.CreateFragment (5, 5);
+  p1 = p3->CreateFragment (0, 5);
+  p2 = p3->CreateFragment (5, 5);
   CHECK_HISTORY (p1, 1, 5);
   CHECK_HISTORY (p2, 1, 5);
-  p1.AddAtEnd (p2);
+  p1->AddAtEnd (p2);
   CHECK_HISTORY (p1, 2, 5, 5);
 
-  p = Packet (0);
+  p = Create<Packet> (0);
   CHECK_HISTORY (p, 0);
 
-  p3 = Packet (0);
+  p3 = Create<Packet> (0);
   ADD_HEADER (p3, 5);
   ADD_HEADER (p3, 5);
   CHECK_HISTORY (p3, 2, 5, 5);
-  p1 = p3.CreateFragment (0, 4);
-  p2 = p3.CreateFragment (9, 1);
+  p1 = p3->CreateFragment (0, 4);
+  p2 = p3->CreateFragment (9, 1);
   CHECK_HISTORY (p1, 1, 4);
   CHECK_HISTORY (p2, 1, 1);
-  p1.AddAtEnd (p2);
+  p1->AddAtEnd (p2);
   CHECK_HISTORY (p1, 2, 4, 1);
 
 
-  p = Packet (2000);
+  p = Create<Packet> (2000);
   CHECK_HISTORY (p, 1, 2000);
   
-  p = Packet ();
+  p = Create<Packet> ();
   ADD_TRAILER (p, 10);
   ADD_HEADER (p, 5);
-  p1 = p.CreateFragment (0, 8);
-  p2 = p.CreateFragment (8, 7);
-  p1.AddAtEnd (p2);
+  p1 = p->CreateFragment (0, 8);
+  p2 = p->CreateFragment (8, 7);
+  p1->AddAtEnd (p2);
   CHECK_HISTORY (p, 2, 5, 10);
 
-  p = Packet ();
+  p = Create<Packet> ();
   ADD_TRAILER (p, 10);
   REM_TRAILER (p, 10);
   ADD_TRAILER (p, 10);
   CHECK_HISTORY (p, 1, 10);
 
-  p = Packet ();
+  p = Create<Packet> ();
   ADD_HEADER (p, 10);
   REM_HEADER (p, 10);
   ADD_HEADER (p, 10);
   CHECK_HISTORY (p, 1, 10);
 
-  p = Packet ();
+  p = Create<Packet> ();
   ADD_HEADER (p, 10);
   p = DoAddHeader (p);
   CHECK_HISTORY (p, 2, 10, 10);
 
-  p = Packet (10);
+  p = Create<Packet> (10);
   ADD_HEADER (p, 8);
   ADD_TRAILER (p, 8);
   ADD_TRAILER (p, 8);
-  p.RemoveAtStart (8+10+8);
+  p->RemoveAtStart (8+10+8);
   CHECK_HISTORY (p, 1, 8);
 
   return ok;
--- a/src/common/packet.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/common/packet.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -26,22 +26,72 @@
 
 uint32_t Packet::m_globalUid = 0;
 
+void 
+Packet::Ref (void) const
+{
+  m_refCount++;
+}
+void 
+Packet::Unref (void) const
+{
+  m_refCount--;
+  if (m_refCount == 0)
+    {
+      delete this;
+    }
+}
+
+Ptr<Packet> 
+Packet::Copy (void) const
+{
+  // we need to invoke the copy constructor directly
+  // rather than calling Create because the copy constructor
+  // is private.
+  return Ptr<Packet> (new Packet (*this), false);
+}
+
 Packet::Packet ()
   : m_buffer (),
-    m_metadata (m_globalUid, 0)
+    m_tags (),
+    m_metadata (m_globalUid, 0),
+    m_refCount (1)
 {
   m_globalUid++;
 }
 
+Packet::Packet (const Packet &o)
+  : m_buffer (o.m_buffer),
+    m_tags (o.m_tags),
+    m_metadata (o.m_metadata),
+    m_refCount (1)
+{}
+
+Packet &
+Packet::operator = (const Packet &o)
+{
+  if (this == &o)
+    {
+      return *this;
+    }
+  m_buffer = o.m_buffer;
+  m_tags = o.m_tags;
+  m_metadata = o.m_metadata;
+  return *this;
+}
+
 Packet::Packet (uint32_t size)
   : m_buffer (size),
-    m_metadata (m_globalUid, size)
+    m_tags (),
+    m_metadata (m_globalUid, size),
+    m_refCount (1)
 {
   m_globalUid++;
 }
 Packet::Packet (uint8_t const*buffer, uint32_t size)
   : m_buffer (),
-    m_metadata (m_globalUid, size)
+    m_tags (),
+    m_metadata (m_globalUid, size),
+    m_refCount (1)
 {
   m_globalUid++;
   m_buffer.AddAtStart (size);
@@ -52,17 +102,20 @@
 Packet::Packet (Buffer buffer, Tags tags, PacketMetadata metadata)
   : m_buffer (buffer),
     m_tags (tags),
-    m_metadata (metadata)
+    m_metadata (metadata),
+    m_refCount (1)
 {}
 
-Packet 
+Ptr<Packet>
 Packet::CreateFragment (uint32_t start, uint32_t length) const
 {
   Buffer buffer = m_buffer.CreateFragment (start, length);
   NS_ASSERT (m_buffer.GetSize () >= start + length);
   uint32_t end = m_buffer.GetSize () - (start + length);
   PacketMetadata metadata = m_metadata.CreateFragment (start, end);
-  return Packet (buffer, m_tags, metadata);
+  // again, call the constructor directly rather than
+  // through Create because it is private.
+  return Ptr<Packet> (new Packet (buffer, m_tags, metadata), false);
 }
 
 uint32_t 
@@ -72,9 +125,9 @@
 }
 
 void 
-Packet::AddAtEnd (Packet packet)
+Packet::AddAtEnd (Ptr<const Packet> packet)
 {
-  Buffer src = packet.m_buffer.CreateFullCopy ();
+  Buffer src = packet->m_buffer.CreateFullCopy ();
   Buffer dst = m_buffer.CreateFullCopy ();
 
   dst.AddAtEnd (src.GetSize ());
@@ -86,7 +139,7 @@
    * XXX: we might need to merge the tag list of the
    * other packet into the current packet.
    */
-  m_metadata.AddAtEnd (packet.m_metadata);
+  m_metadata.AddAtEnd (packet->m_metadata);
 }
 void
 Packet::AddPaddingAtEnd (uint32_t size)
@@ -233,20 +286,20 @@
 {
   bool ok = true;
 
-  Packet pkt1 (reinterpret_cast<const uint8_t*> ("hello"), 5);
-  Packet pkt2 (reinterpret_cast<const uint8_t*> (" world"), 6);
-  Packet packet;
-  packet.AddAtEnd (pkt1);
-  packet.AddAtEnd (pkt2);
+  Ptr<Packet> pkt1 = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello"), 5);
+  Ptr<Packet> pkt2 = Create<Packet> (reinterpret_cast<const uint8_t*> (" world"), 6);
+  Ptr<Packet> packet = Create<Packet> ();
+  packet->AddAtEnd (pkt1);
+  packet->AddAtEnd (pkt2);
   
-  if (packet.GetSize () != 11)
+  if (packet->GetSize () != 11)
     {
-      Failure () << "expected size 11, got " << packet.GetSize () << std::endl;
+      Failure () << "expected size 11, got " << packet->GetSize () << std::endl;
       ok = false;
     }
 
-  std::string msg = std::string (reinterpret_cast<const char *>(packet.PeekData ()),
-                                 packet.GetSize ());
+  std::string msg = std::string (reinterpret_cast<const char *>(packet->PeekData ()),
+                                 packet->GetSize ());
   if (msg != "hello world")
     {
       Failure () << "expected 'hello world', got '" << msg << "'" << std::endl;
--- a/src/common/packet.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/common/packet.h	Mon Oct 29 12:48:01 2007 -0700
@@ -30,6 +30,7 @@
 #include "tag.h"
 #include "ns3/callback.h"
 #include "ns3/assert.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -74,6 +75,11 @@
  */
 class Packet {
 public:
+  void Ref (void) const;
+  void Unref (void) const;
+
+  Ptr<Packet> Copy (void) const;
+
   /**
    * Create an empty packet with a new uid (as returned
    * by getUid).
@@ -107,7 +113,7 @@
    * \param length length of fragment to create
    * \returns a fragment of the original packet
    */
-  Packet CreateFragment (uint32_t start, uint32_t length) const;
+  Ptr<Packet> CreateFragment (uint32_t start, uint32_t length) const;
   /**
    * \returns the size in bytes of the packet (including the zero-filled
    *          initial payload)
@@ -210,7 +216,7 @@
    *
    * \param packet packet to concatenate
    */
-  void AddAtEnd (Packet packet);
+  void AddAtEnd (Ptr<const Packet> packet);
   /**
    * \param size number of padding bytes to add.
    */
@@ -332,9 +338,12 @@
   void Deserialize (Buffer buffer);
 private:
   Packet (Buffer buffer, Tags tags, PacketMetadata metadata);
+  Packet (const Packet &o);
+  Packet &operator = (const Packet &o);
   Buffer m_buffer;
   Tags m_tags;
   PacketMetadata m_metadata;
+  mutable uint32_t m_refCount;
   static uint32_t m_globalUid;
 };
 
--- a/src/common/pcap-writer.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/common/pcap-writer.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -89,7 +89,7 @@
 
 
 void 
-PcapWriter::WritePacket (Packet const packet)
+PcapWriter::WritePacket (Ptr<const Packet> packet)
 {
   if (m_writer != 0) 
     {
@@ -98,9 +98,9 @@
       uint64_t us = current % 1000000;
       Write32 (s & 0xffffffff);
       Write32 (us & 0xffffffff);
-      Write32 (packet.GetSize ());
-      Write32 (packet.GetSize ());
-      WriteData (packet.PeekData (), packet.GetSize ());
+      Write32 (packet->GetSize ());
+      Write32 (packet->GetSize ());
+      WriteData (packet->PeekData (), packet->GetSize ());
     }
 }
 
--- a/src/common/pcap-writer.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/common/pcap-writer.h	Mon Oct 29 12:48:01 2007 -0700
@@ -24,10 +24,11 @@
 
 #include "ns3/callback.h"
 #include <stdint.h>
-#include "packet.h"
 
 namespace ns3 {
 
+class Packet;
+
 /**
  * \brief Pcap output for Packet logger
  *
@@ -62,7 +63,7 @@
   /**
    * \param packet packet to write to output file
    */
-  void WritePacket (Packet const packet);
+  void WritePacket (Ptr<const Packet> packet);
 
 private:
   void WriteData (uint8_t const*buffer, uint32_t size);
--- a/src/core/ptr.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/core/ptr.h	Mon Oct 29 12:48:01 2007 -0700
@@ -100,6 +100,8 @@
 
   T *operator -> () const;
   T *operator -> ();
+  const T &operator * () const;
+  const T &operator * ();
   // allow if (!sp)
   bool operator! ();
   // allow if (sp)
@@ -221,73 +223,49 @@
 template <typename T>
 Ptr<T> Create (void)
 {
-  T *obj = new T ();
-  Ptr<T> p = obj;
-  obj->Unref ();
-  return p;
+  return Ptr<T> (new T (), false);
 }
 
 template <typename T, typename T1>
 Ptr<T> Create (T1 a1)
 {
-  T *obj = new T (a1);
-  Ptr<T> p = obj;
-  obj->Unref ();
-  return p;
+  return Ptr<T> (new T (a1), false);
 }
 
 template <typename T, typename T1, typename T2>
 Ptr<T> Create (T1 a1, T2 a2)
 {
-  T *obj = new T (a1, a2);
-  Ptr<T> p = obj;
-  obj->Unref ();
-  return p;
+  return Ptr<T> (new T (a1, a2), false);
 }
 
 template <typename T, typename T1, typename T2, typename T3>
 Ptr<T> Create (T1 a1, T2 a2, T3 a3)
 {
-  T *obj = new T (a1, a2, a3);
-  Ptr<T> p = obj;
-  obj->Unref ();
-  return p;
+  return Ptr<T> (new T (a1, a2, a3), false);
 }
 
 template <typename T, typename T1, typename T2, typename T3, typename T4>
 Ptr<T> Create (T1 a1, T2 a2, T3 a3, T4 a4)
 {
-  T *obj = new T (a1, a2, a3, a4);
-  Ptr<T> p = obj;
-  obj->Unref ();
-  return p;
+  return Ptr<T> (new T (a1, a2, a3, a4), false);
 }
 
 template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
 Ptr<T> Create (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
 {
-  T *obj = new T (a1, a2, a3, a4, a5);
-  Ptr<T> p = obj;
-  obj->Unref ();
-  return p;
+  return Ptr<T> (new T (a1, a2, a3, a4, a5), false);
 }
 
 template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
 Ptr<T> Create (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
 {
-  T *obj = new T (a1, a2, a3, a4, a5, a6);
-  Ptr<T> p = obj;
-  obj->Unref ();
-  return p;
+  return Ptr<T> (new T (a1, a2, a3, a4, a5, a6), false);
 }
 
 template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
 Ptr<T> Create (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
 {
-  T *obj = new T (a1, a2, a3, a4, a5, a6, a7);
-  Ptr<T> p = obj;
-  obj->Unref ();
-  return p;
+  return Ptr<T> (new T (a1, a2, a3, a4, a5, a6, a7), false);
 }
 
 template <typename T>
@@ -457,6 +435,21 @@
 }
 
 template <typename T>
+const T &
+Ptr<T>::operator * () const
+{
+  return *m_ptr;
+}
+
+template <typename T>
+const T &
+Ptr<T>::operator * ()
+{
+  return *m_ptr;
+}
+
+
+template <typename T>
 bool 
 Ptr<T>::operator! () 
 {
--- a/src/devices/csma/csma-channel.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/devices/csma/csma-channel.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -205,11 +205,11 @@
 }
 
 bool
-CsmaChannel::TransmitStart(Packet& p, uint32_t srcId)
+CsmaChannel::TransmitStart(Ptr<Packet> p, uint32_t srcId)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &p << ", " << srcId << ")");
-  NS_LOG_INFO ("UID is " << p.GetUid () << ")");
+  NS_LOG_PARAM ("(" << p << ", " << srcId << ")");
+  NS_LOG_INFO ("UID is " << p->GetUid () << ")");
 
   if (m_state != IDLE)
     {
@@ -240,8 +240,8 @@
 CsmaChannel::TransmitEnd()
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &m_currentPkt << ", " << m_currentSrc << ")");
-  NS_LOG_INFO ("UID is " << m_currentPkt.GetUid () << ")");
+  NS_LOG_PARAM ("(" << m_currentPkt << ", " << m_currentSrc << ")");
+  NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")");
 
   NS_ASSERT(m_state == TRANSMITTING);
   m_state = PROPAGATING;
@@ -266,8 +266,8 @@
 CsmaChannel::PropagationCompleteEvent()
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &m_currentPkt << ")");
-  NS_LOG_INFO ("UID is " << m_currentPkt.GetUid () << ")");
+  NS_LOG_PARAM ("(" << m_currentPkt << ")");
+  NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")");
 
   NS_ASSERT(m_state == PROPAGATING);
 
@@ -278,7 +278,7 @@
     {
       if (it->IsActive())
       {
-        it->devicePtr->Receive (m_currentPkt);
+        it->devicePtr->Receive (m_currentPkt->Copy ());
       }
     }
   m_state = IDLE;
--- a/src/devices/csma/csma-channel.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/devices/csma/csma-channel.h	Mon Oct 29 12:48:01 2007 -0700
@@ -23,12 +23,13 @@
 
 #include "ns3/channel.h"
 #include "ns3/ptr.h"
-#include "ns3/packet.h"
 #include "ns3/nstime.h"
 #include "ns3/data-rate.h"
 
 namespace ns3 {
 
+class Packet;
+
 class CsmaNetDevice;
 
   /**
@@ -185,7 +186,7 @@
    * \return True if the channel is not busy and the transmitting net
    * device is currently active.
    */
-  bool TransmitStart (Packet& p, uint32_t srcId);
+  bool TransmitStart (Ptr<Packet> p, uint32_t srcId);
   /**
    * \brief Indicates that the net device has finished transmitting
    * the packet over the channel
@@ -286,7 +287,7 @@
    * packet to have been transmitted on the channel if the channel is
    * free.)
    */
-  Packet                              m_currentPkt;
+  Ptr<Packet>                         m_currentPkt;
   /**
    * Device Id of the source that is currently transmitting on the
    * channel. Or last source to have transmitted a packet on the
--- a/src/devices/csma/csma-net-device.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/devices/csma/csma-net-device.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -219,7 +219,7 @@
 }
 
 void 
-CsmaNetDevice::AddHeader (Packet& p, Mac48Address dest,
+CsmaNetDevice::AddHeader (Ptr<Packet> p, Mac48Address dest,
                             uint16_t protocolNumber)
 {
   NS_LOG_FUNCTION;
@@ -237,7 +237,7 @@
   switch (m_encapMode) 
     {
     case ETHERNET_V1:
-      lengthType = p.GetSize() + header.GetSerializedSize() + trailer.GetSerializedSize();
+      lengthType = p->GetSize() + header.GetSerializedSize() + trailer.GetSerializedSize();
       break;
     case IP_ARP:
       lengthType = protocolNumber;
@@ -245,20 +245,20 @@
     case LLC: {
       LlcSnapHeader llc;
       llc.SetType (protocolNumber);
-      p.AddHeader (llc);
+      p->AddHeader (llc);
     } break;
     case RAW:
       NS_ASSERT (false);
       break;
     }
   header.SetLengthType (lengthType);
-  p.AddHeader(header);
+  p->AddHeader(header);
   trailer.CalcFcs(p);
-  p.AddTrailer(trailer);
+  p->AddTrailer(trailer);
 }
 
 bool 
-CsmaNetDevice::ProcessHeader (Packet& p, uint16_t & param)
+CsmaNetDevice::ProcessHeader (Ptr<Packet> p, uint16_t & param)
 {
   NS_LOG_FUNCTION;
   if (m_encapMode == RAW)
@@ -268,9 +268,9 @@
   EthernetHeader header (false);
   EthernetTrailer trailer;
       
-  p.RemoveTrailer(trailer);
+  p->RemoveTrailer(trailer);
   trailer.CheckFcs(p);
-  p.RemoveHeader(header);
+  p->RemoveHeader(header);
 
   if ((header.GetDestination() != GetBroadcast ()) &&
       (header.GetDestination() != GetAddress ()))
@@ -286,7 +286,7 @@
       break;
     case LLC: {
       LlcSnapHeader llc;
-      p.RemoveHeader (llc);
+      p->RemoveHeader (llc);
       param = llc.GetType ();
     } break;
     case RAW:
@@ -311,15 +311,13 @@
 }
 
 bool
-CsmaNetDevice::SendTo (
-  const Packet& packet, 
-  const Address& dest, 
-  uint16_t protocolNumber)
+CsmaNetDevice::SendTo (Ptr<Packet> packet, 
+                       const Address& dest, 
+                       uint16_t protocolNumber)
 {
   NS_LOG_FUNCTION;
-  Packet p = packet;
-  NS_LOG_LOGIC ("p=" << &p);
-  NS_LOG_LOGIC ("UID is " << p.GetUid () << ")");
+  NS_LOG_LOGIC ("p=" << packet);
+  NS_LOG_LOGIC ("UID is " << packet->GetUid () << ")");
 
   NS_ASSERT (IsLinkUp ());
 
@@ -328,10 +326,10 @@
     return false;
 
   Mac48Address destination = Mac48Address::ConvertFrom (dest);
-  AddHeader(p, destination, protocolNumber);
+  AddHeader(packet, destination, protocolNumber);
 
   // Place the packet to be sent on the send queue
-  if (m_queue->Enqueue(p) == false )
+  if (m_queue->Enqueue(packet) == false )
     {
       return false;
     }
@@ -341,7 +339,8 @@
   if (m_txMachineState == READY) 
     {
       // Store the next packet to be transmitted
-      if (m_queue->Dequeue (m_currentPkt))
+      m_currentPkt = m_queue->Dequeue ();
+      if (m_currentPkt != 0)
         {
           TransmitStart();
         }
@@ -353,8 +352,8 @@
 CsmaNetDevice::TransmitStart ()
 {
   NS_LOG_FUNCTION;
-  NS_LOG_LOGIC ("m_currentPkt=" << &m_currentPkt);
-  NS_LOG_LOGIC ("UID is " << m_currentPkt.GetUid ());
+  NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
+  NS_LOG_LOGIC ("UID is " << m_currentPkt->GetUid ());
 //
 // This function is called to start the process of transmitting a packet.
 // We need to tell the channel that we've started wiggling the wire and
@@ -393,7 +392,7 @@
     {
       // Channel is free, transmit packet
       m_txMachineState = BUSY;
-      Time tEvent = Seconds (m_bps.CalculateTxTime(m_currentPkt.GetSize()));
+      Time tEvent = Seconds (m_bps.CalculateTxTime(m_currentPkt->GetSize()));
       
       NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << 
         tEvent.GetSeconds () << "sec");
@@ -420,12 +419,11 @@
 CsmaNetDevice::TransmitAbort (void)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt.GetUid () << ")");
+  NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
 
   // Try to transmit a new packet
-  bool found;
-  found = m_queue->Dequeue (m_currentPkt);
-  NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?");
+  m_currentPkt = m_queue->Dequeue ();
+  NS_ASSERT_MSG(m_currentPkt != 0, "IsEmpty false but no Packet on queue?");
   m_backoff.ResetBackoffTime();
   m_txMachineState = READY;
   TransmitStart ();
@@ -446,7 +444,7 @@
   NS_ASSERT(m_channel->GetState() == TRANSMITTING);
   m_txMachineState = GAP;
 
-  NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt.GetUid () << ")");
+  NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
   m_channel->TransmitEnd (); 
 
   NS_LOG_LOGIC ("Schedule TransmitReadyEvent in "
@@ -476,9 +474,8 @@
     }
   else
     {
-      bool found;
-      found = m_queue->Dequeue (m_currentPkt);
-      NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?");
+      m_currentPkt = m_queue->Dequeue ();
+      NS_ASSERT_MSG(m_currentPkt != 0, "IsEmpty false but no Packet on queue?");
       TransmitStart ();
     }
 }
@@ -491,12 +488,12 @@
   resolver->AddComposite ("queue", m_queue);
   resolver->AddSource ("rx",
                        TraceDoc ("receive MAC packet",
-                                 "const Packet &", "packet received"),
+                                 "Ptr<const Packet>", "packet received"),
                        m_rxTrace,
                        CsmaTraceType (CsmaTraceType::RX));
   resolver->AddSource ("drop",
                        TraceDoc ("drop MAC packet",
-                                 "const Packet &", "packet dropped"),
+                                 "Ptr<const Packet>", "packet dropped"),
                        m_dropTrace,
                        CsmaTraceType (CsmaTraceType::DROP));
   resolver->SetParentResolver (NetDevice::GetTraceResolver ());
@@ -532,7 +529,7 @@
 }
 
 void
-CsmaNetDevice::Receive (const Packet& packet)
+CsmaNetDevice::Receive (Ptr<Packet> packet)
 {
   NS_LOG_FUNCTION;
 
@@ -541,26 +538,25 @@
   Mac48Address broadcast;
   Mac48Address multicast;
   Mac48Address destination;
-  Packet p = packet;
 
-  NS_LOG_LOGIC ("UID is " << p.GetUid());
+  NS_LOG_LOGIC ("UID is " << packet->GetUid());
 
   // Only receive if send side of net device is enabled
   if (!IsReceiveEnabled())
     {
-      m_dropTrace (p);
+      m_dropTrace (packet);
       return;
     }
 
   if (m_encapMode == RAW)
     {
       ForwardUp (packet, 0, GetBroadcast ());
-      m_dropTrace (p);
+      m_dropTrace (packet);
       return;
     }
-  p.RemoveTrailer(trailer);
-  trailer.CheckFcs(p);
-  p.RemoveHeader(header);
+  packet->RemoveTrailer(trailer);
+  trailer.CheckFcs(packet);
+  packet->RemoveHeader(header);
 
   NS_LOG_LOGIC ("Pkt destination is " << header.GetDestination ());
 //
@@ -589,11 +585,11 @@
       (header.GetDestination () != destination))
     {
       NS_LOG_LOGIC ("Dropping pkt ");
-      m_dropTrace (p);
+      m_dropTrace (packet);
       return;
     }
 
-  m_rxTrace (p);
+  m_rxTrace (packet);
 //
 // protocol must be initialized to avoid a compiler warning in the RAW
 // case that breaks the optimized build.
@@ -608,7 +604,7 @@
       break;
     case LLC: {
       LlcSnapHeader llc;
-      p.RemoveHeader (llc);
+      packet->RemoveHeader (llc);
       protocol = llc.GetType ();
     } break;
     case RAW:
@@ -616,7 +612,7 @@
       break;
     }
   
-  ForwardUp (p, protocol, header.GetSource ());
+  ForwardUp (packet, protocol, header.GetSource ());
   return;
 }
 
--- a/src/devices/csma/csma-net-device.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/devices/csma/csma-net-device.h	Mon Oct 29 12:48:01 2007 -0700
@@ -203,7 +203,7 @@
    * @see CsmaChannel
    * \param p a reference to the received packet
    */
-  void Receive (const Packet& p);
+  void Receive (Ptr<Packet> p);
 
   /**
    * @brief Make and return a MAC multicast address using the provided
@@ -279,7 +279,7 @@
    * \param protocolNumber In some protocols, identifies the type of
    * payload contained in this packet.
    */
-  void AddHeader (Packet& p, Mac48Address dest, 
+  void AddHeader (Ptr<Packet> p, Mac48Address dest, 
                   uint16_t protocolNumber);
   /**
    * Removes, from a packet of data, all headers and trailers that
@@ -291,7 +291,7 @@
    * \return Returns true if the packet should be forwarded up the
    * protocol stack.
    */
-  bool ProcessHeader (Packet& p, uint16_t & param);
+  bool ProcessHeader (Ptr<Packet> p, uint16_t & param);
 
 private:
   // disable copy constructor and operator =
@@ -316,7 +316,7 @@
    * \param protocolNumber -- this parameter is not used here
    * \return true if success, false on failure
    */
-  virtual bool SendTo (const Packet& p, const Address& dest, uint16_t protocolNumber);
+  virtual bool SendTo (Ptr<Packet> p, const Address& dest, uint16_t protocolNumber);
 
   /**
    * Start Sending a Packet Down the Wire.
@@ -438,7 +438,7 @@
    * currently transmitting) or packet that is currently being
    * transmitted.
    */
-  Packet m_currentPkt;
+  Ptr<Packet> m_currentPkt;
   /**
    * The CsmaChannel to which this CsmaNetDevice has been
    * attached.
@@ -461,8 +461,8 @@
    * @see class CallBackTraceSource
    * @see class TraceResolver
    */
-  CallbackTraceSource<const Packet &> m_rxTrace;
-  CallbackTraceSource<const Packet &> m_dropTrace;
+  CallbackTraceSource<Ptr<const Packet> > m_rxTrace;
+  CallbackTraceSource<Ptr<const Packet> > m_dropTrace;
 
 };
 
--- a/src/devices/point-to-point/point-to-point-channel.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/devices/point-to-point/point-to-point-channel.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -94,13 +94,13 @@
 }
 
 bool
-PointToPointChannel::TransmitStart(Packet& p,
-                                        Ptr<PointToPointNetDevice> src,
-                                        const Time& txTime)
+PointToPointChannel::TransmitStart(Ptr<Packet> p,
+                                   Ptr<PointToPointNetDevice> src,
+                                   const Time& txTime)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &p << ", " << src << ")");
-  NS_LOG_LOGIC ("UID is " << p.GetUid () << ")");
+  NS_LOG_PARAM ("(" << p << ", " << src << ")");
+  NS_LOG_LOGIC ("UID is " << p->GetUid () << ")");
 
   NS_ASSERT(m_link[0].m_state != INITIALIZING);
   NS_ASSERT(m_link[1].m_state != INITIALIZING);
--- a/src/devices/point-to-point/point-to-point-channel.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/devices/point-to-point/point-to-point-channel.h	Mon Oct 29 12:48:01 2007 -0700
@@ -22,13 +22,13 @@
 #include <list>
 #include "ns3/channel.h"
 #include "ns3/ptr.h"
-#include "ns3/packet.h"
 #include "ns3/nstime.h"
 #include "ns3/data-rate.h"
 
 namespace ns3 {
 
 class PointToPointNetDevice;
+class Packet;
 
 /**
  * \brief Simple Point To Point Channel.
@@ -75,7 +75,7 @@
    * \param delay Transmission delay through the channel
    */
   PointToPointChannel (const std::string& name,
-                 const DataRate& bps, const Time& delay);
+                       const DataRate& bps, const Time& delay);
 
   /**
    * \brief Attach a given netdevice to this channel
@@ -89,8 +89,9 @@
    * \param src Source PointToPointNetDevice
    * \param txTime Transmit time to apply
    */
-  bool TransmitStart (Packet& p, Ptr<PointToPointNetDevice> src,
+  bool TransmitStart (Ptr<Packet> p, Ptr<PointToPointNetDevice> src,
                       const Time& txTime);
+
   /**
    * \brief Get number of devices on this channel
    * \returns number of devices on this channel
--- a/src/devices/point-to-point/point-to-point-net-device.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/devices/point-to-point/point-to-point-net-device.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -97,20 +97,20 @@
 }
 
 void 
-PointToPointNetDevice::AddHeader(Packet& p, uint16_t protocolNumber)
+PointToPointNetDevice::AddHeader(Ptr<Packet> p, uint16_t protocolNumber)
 {
   NS_LOG_FUNCTION;
   LlcSnapHeader llc;
   llc.SetType (protocolNumber);
-  p.AddHeader (llc);
+  p->AddHeader (llc);
 }
 
 bool 
-PointToPointNetDevice::ProcessHeader(Packet& p, uint16_t& param)
+PointToPointNetDevice::ProcessHeader(Ptr<Packet> p, uint16_t& param)
 {
   NS_LOG_FUNCTION;
   LlcSnapHeader llc;
-  p.RemoveHeader (llc);
+  p->RemoveHeader (llc);
 
   param = llc.GetType ();
 
@@ -136,19 +136,18 @@
   m_tInterframeGap = t;
 }
 
-bool PointToPointNetDevice::SendTo (const Packet& packet, const Address& dest, 
+bool PointToPointNetDevice::SendTo (Ptr<Packet> packet, const Address& dest, 
                                     uint16_t protocolNumber)
 {
   NS_LOG_FUNCTION;
-  Packet p = packet;
-  NS_LOG_LOGIC ("p=" << &p << ", dest=" << &dest);
-  NS_LOG_LOGIC ("UID is " << p.GetUid ());
+  NS_LOG_LOGIC ("p=" << packet << ", dest=" << &dest);
+  NS_LOG_LOGIC ("UID is " << packet->GetUid ());
 
   // GFR Comment. Why is this an assertion? Can't a link legitimately
   // "go down" during the simulation?  Shouldn't we just wait for it
   // to come back up?
   NS_ASSERT (IsLinkUp ());
-  AddHeader(p, protocolNumber);
+  AddHeader(packet, protocolNumber);
 
 //
 // This class simulates a point to point device.  In the case of a serial
@@ -160,22 +159,22 @@
   if (m_txMachineState == READY) 
     {
 // We still enqueue and dequeue it to hit the tracing hooks
-      m_queue->Enqueue (p);
-      m_queue->Dequeue (p);
-      return TransmitStart (p);
+      m_queue->Enqueue (packet);
+      packet = m_queue->Dequeue ();
+      return TransmitStart (packet);
     }
   else
     {
-      return m_queue->Enqueue(p);
+      return m_queue->Enqueue(packet);
     }
 }
 
   bool
-PointToPointNetDevice::TransmitStart (Packet &p)
+PointToPointNetDevice::TransmitStart (Ptr<Packet> p)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &p << ")");
-  NS_LOG_LOGIC ("UID is " << p.GetUid () << ")");
+  NS_LOG_PARAM ("(" << p << ")");
+  NS_LOG_LOGIC ("UID is " << p->GetUid () << ")");
 //
 // This function is called to start the process of transmitting a packet.
 // We need to tell the channel that we've started wiggling the wire and
@@ -183,7 +182,7 @@
 //
   NS_ASSERT_MSG(m_txMachineState == READY, "Must be READY to transmit");
   m_txMachineState = BUSY;
-  Time txTime = Seconds (m_bps.CalculateTxTime(p.GetSize()));
+  Time txTime = Seconds (m_bps.CalculateTxTime(p->GetSize()));
   Time txCompleteTime = txTime + m_tInterframeGap;
 
   NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << 
@@ -206,8 +205,11 @@
 //
   NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting");
   m_txMachineState = READY;
-  Packet p;
-  if (!m_queue->Dequeue(p)) return; // Nothing to do at this point
+  Ptr<Packet> p = m_queue->Dequeue ();
+  if (p == 0)
+    {
+      return; // Nothing to do at this point
+    }
   TransmitStart(p);
 }
 
@@ -219,7 +221,7 @@
   resolver->AddComposite ("queue", m_queue);
   resolver->AddSource ("rx",
                        TraceDoc ("receive MAC packet",
-                                 "const Packet &", "packet received"),
+                                 "Ptr<const Packet>", "packet received"),
                        m_rxTrace,
                        PointToPointTraceType ());
   resolver->SetParentResolver (NetDevice::GetTraceResolver ());
@@ -262,12 +264,11 @@
   m_queue = q;
 }
 
-void PointToPointNetDevice::Receive (Packet& p)
+void PointToPointNetDevice::Receive (Ptr<Packet> packet)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &p << ")");
+  NS_LOG_PARAM ("(" << packet << ")");
   uint16_t protocol = 0;
-  Packet packet = p;
 
   m_rxTrace (packet);
   ProcessHeader(packet, protocol);
--- a/src/devices/point-to-point/point-to-point-net-device.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/devices/point-to-point/point-to-point-net-device.h	Mon Oct 29 12:48:01 2007 -0700
@@ -144,7 +144,7 @@
    * @see PointToPointChannel
    * @param p a reference to the received packet
    */
-  void Receive (Packet& p);
+  void Receive (Ptr<Packet> p);
 
 private:
   /**
@@ -193,14 +193,14 @@
    * Adds the necessary headers and trailers to a packet of data in order to
    * respect the protocol implemented by the agent.
    */
-  void AddHeader(Packet& p, uint16_t protocolNumber);
+  void AddHeader(Ptr<Packet> p, uint16_t protocolNumber);
   /**
    * Removes, from a packet of data, all headers and trailers that
    * relate to the protocol implemented by the agent
    * \return Returns true if the packet should be forwarded up the
    * protocol stack.
    */
-  bool ProcessHeader(Packet& p, uint16_t& param);
+  bool ProcessHeader(Ptr<Packet> p, uint16_t& param);
   /**
    * Send a Packet Down the Wire.
    *
@@ -214,7 +214,7 @@
    * @param protocolNumber Protocol Number used to find protocol touse
    * @returns true if success, false on failure
    */
-  virtual bool SendTo (const Packet& p, const Address& dest, 
+  virtual bool SendTo (Ptr<Packet> p, const Address& dest, 
                        uint16_t protocolNumber);
   /**
    * Start Sending a Packet Down the Wire.
@@ -231,7 +231,7 @@
    * @param p a reference to the packet to send
    * @returns true if success, false on failure
    */
-  bool TransmitStart (Packet &p);
+  bool TransmitStart (Ptr<Packet> p);
   /**
    * Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
    *
@@ -287,7 +287,7 @@
    * @see class CallBackTraceSource
    * @see class TraceResolver
    */
-  CallbackTraceSource<const Packet &> m_rxTrace;
+  CallbackTraceSource<Ptr<const Packet> > m_rxTrace;
   /** 
    * Default data rate.  Used for all newly created p2p net devices
    */
--- a/src/internet-node/arp-cache.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/arp-cache.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -147,7 +147,7 @@
   //NS_ASSERT (m_waiting != 0);
   UpdateSeen ();
 }
-Packet 
+Ptr<Packet>
 ArpCache::Entry::MarkAlive (Address macAddress) 
 {
   NS_ASSERT (m_state == WAIT_REPLY);
@@ -155,25 +155,25 @@
   m_macAddress = macAddress;
   m_state = ALIVE;
   UpdateSeen ();
-  Packet waiting = m_waiting;
+  Ptr<Packet> waiting = m_waiting;
   //m_waiting = 0;
   return waiting;
 }
 
-Packet 
-ArpCache::Entry::UpdateWaitReply (Packet waiting)
+Ptr<Packet>
+ArpCache::Entry::UpdateWaitReply (Ptr<Packet> waiting)
 {
   NS_ASSERT (m_state == WAIT_REPLY);
   /* We are already waiting for an answer so
    * we dump the previously waiting packet and
    * replace it with this one.
    */
-  Packet old = m_waiting;
+  Ptr<Packet> old = m_waiting;
   m_waiting = waiting;
   return old;
 }
 void 
-ArpCache::Entry::MarkWaitReply (Packet waiting)
+ArpCache::Entry::MarkWaitReply (Ptr<Packet> waiting)
 {
   NS_ASSERT (m_state == ALIVE || m_state == DEAD);
   //NS_ASSERT (m_waiting == 0);
--- a/src/internet-node/arp-cache.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/arp-cache.h	Mon Oct 29 12:48:01 2007 -0700
@@ -101,16 +101,16 @@
      * \param macAddress
      * \return 
      */
-    Packet MarkAlive (Address macAddress);
+    Ptr<Packet> MarkAlive (Address macAddress);
     /**
      * \param waiting
      */
-    void MarkWaitReply (Packet waiting);
+    void MarkWaitReply (Ptr<Packet> waiting);
     /**
      * \param waiting
      * \return 
      */
-    Packet UpdateWaitReply (Packet waiting);
+    Ptr<Packet> UpdateWaitReply (Ptr<Packet> waiting);
     /**
      * \return True if the state of this entry is dead; false otherwise.
      */
@@ -144,7 +144,7 @@
     ArpCacheEntryState_e m_state;
     Time m_lastSeen;
     Address m_macAddress;
-    Packet m_waiting;
+    Ptr<Packet> m_waiting;
   };
 
 private:
--- a/src/internet-node/arp-ipv4-interface.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/arp-ipv4-interface.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -61,10 +61,10 @@
 }
 
 void 
-ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest)
+ArpIpv4Interface::SendTo (Ptr<Packet> p, Ipv4Address dest)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &p << ", " << dest << ")");
+  NS_LOG_PARAM ("(" << p << ", " << dest << ")");
 
   NS_ASSERT (GetDevice () != 0);
   if (GetDevice ()->NeedsArp ())
--- a/src/internet-node/arp-ipv4-interface.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/arp-ipv4-interface.h	Mon Oct 29 12:48:01 2007 -0700
@@ -45,7 +45,7 @@
 protected:
   virtual Ptr<TraceResolver> GetTraceResolver (void) const;
 private:
-  virtual void SendTo (Packet p, Ipv4Address dest);
+  virtual void SendTo (Ptr<Packet> p, Ipv4Address dest);
   Ptr<Node> m_node;
 };
 
--- a/src/internet-node/arp-l3-protocol.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/arp-l3-protocol.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -82,13 +82,12 @@
 }
 
 void 
-ArpL3Protocol::Receive(Ptr<NetDevice> device, const Packet& p, uint16_t protocol, const Address &from)
+ArpL3Protocol::Receive(Ptr<NetDevice> device, Ptr<Packet> packet, uint16_t protocol, const Address &from)
 {
   NS_LOG_FUNCTION;
   ArpCache *cache = FindCache (device);
   ArpHeader arp;
-  Packet packet = p;
-  packet.RemoveHeader (arp);
+  packet->RemoveHeader (arp);
   
   NS_LOG_LOGIC ("ARP: received "<< (arp.IsRequest ()? "request" : "reply") <<
             " node="<<m_node->GetId ()<<", got request from " <<
@@ -118,7 +117,7 @@
                         arp.GetSourceIpv4Address ()
                      << " for waiting entry -- flush");
               Address from_mac = arp.GetSourceHardwareAddress ();
-              Packet waiting = entry->MarkAlive (from_mac);
+              Ptr<Packet> waiting = entry->MarkAlive (from_mac);
 	      cache->GetInterface ()->Send (waiting, arp.GetSourceIpv4Address ());
             } 
           else 
@@ -145,7 +144,7 @@
     }
 }
 bool 
-ArpL3Protocol::Lookup (Packet &packet, Ipv4Address destination, 
+ArpL3Protocol::Lookup (Ptr<Packet> packet, Ipv4Address destination, 
                        Ptr<NetDevice> device,
                        Address *hardwareDestination)
 {
@@ -197,7 +196,7 @@
             {
               NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
                         ", wait reply for " << destination << " valid -- drop previous");
-              Packet old = entry->UpdateWaitReply (packet);
+              Ptr<Packet> old = entry->UpdateWaitReply (packet);
 	      // XXX report 'old' packet as 'dropped'
             }
         }
@@ -229,8 +228,8 @@
 		  cache->GetInterface ()->GetAddress (), 
                   cache->GetDevice ()->GetBroadcast (),
                   to);
-  Packet packet;
-  packet.AddHeader (arp);
+  Ptr<Packet> packet = Create<Packet> ();
+  packet->AddHeader (arp);
   cache->GetDevice ()->Send (packet, cache->GetDevice ()->GetBroadcast (), PROT_NUMBER);
 }
 
@@ -246,8 +245,8 @@
   arp.SetReply (cache->GetDevice ()->GetAddress (),
                 cache->GetInterface ()->GetAddress (),
                 toMac, toIp);
-  Packet packet;
-  packet.AddHeader (arp);
+  Ptr<Packet> packet = Create<Packet> ();
+  packet->AddHeader (arp);
   cache->GetDevice ()->Send (packet, toMac, PROT_NUMBER);
 }
 
--- a/src/internet-node/arp-l3-protocol.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/arp-l3-protocol.h	Mon Oct 29 12:48:01 2007 -0700
@@ -51,7 +51,7 @@
   /**
    * \brief Recieve a packet
    */
-  void Receive(Ptr<NetDevice> device, const Packet& p, uint16_t protocol, const Address &from);
+  void Receive(Ptr<NetDevice> device, Ptr<Packet> p, uint16_t protocol, const Address &from);
   /**
    * \brief Perform an ARP lookup
    * \param p
@@ -60,7 +60,7 @@
    * \param hardwareDestination
    * \return 
    */
-  bool Lookup (Packet &p, Ipv4Address destination, 
+  bool Lookup (Ptr<Packet> p, Ipv4Address destination, 
 	       Ptr<NetDevice> device,
 	       Address *hardwareDestination);
 protected:
--- a/src/internet-node/ascii-trace.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/ascii-trace.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -58,46 +58,46 @@
 
 void 
 AsciiTrace::LogDevQueueEnqueue (TraceContext const &context, 
-  Packet const &packet)
+                                Ptr<const Packet> packet)
 {
   m_os << "+ ";
   m_os << Simulator::Now ().GetSeconds () << " ";
   context.Print (m_os);
-  m_os << " pkt-uid=" << packet.GetUid () << " ";
-  packet.Print (m_os);
+  m_os << " pkt-uid=" << packet->GetUid () << " ";
+  packet->Print (m_os);
   m_os << std::endl;
 }
 
 void 
 AsciiTrace::LogDevQueueDequeue (TraceContext const &context, 
-  Packet const &packet)
+                                Ptr<const Packet> packet)
 {
   m_os << "- ";
   m_os << Simulator::Now ().GetSeconds () << " ";
   context.Print (m_os);
-  m_os << " pkt-uid=" << packet.GetUid () << " ";
-  packet.Print (m_os);
+  m_os << " pkt-uid=" << packet->GetUid () << " ";
+  packet->Print (m_os);
   m_os << std::endl;
 }
 
 void 
 AsciiTrace::LogDevQueueDrop (TraceContext const &context, 
-  Packet const &packet)
+                             Ptr<const Packet> packet)
 {
   m_os << "d ";
   m_os << Simulator::Now ().GetSeconds () << " ";
   context.Print (m_os);
-  m_os << " pkt-uid=" << packet.GetUid () << " ";
-  packet.Print (m_os);
+  m_os << " pkt-uid=" << packet->GetUid () << " ";
+  packet->Print (m_os);
   m_os << std::endl;
 }
 void 
-AsciiTrace::LogDevRx (TraceContext const &context, const Packet &p)
+AsciiTrace::LogDevRx (TraceContext const &context, Ptr<const Packet> p)
 {
   m_os << "r " << Simulator::Now ().GetSeconds () << " ";
   context.Print (m_os);
-  m_os << " pkt-uid=" << p.GetUid () << " ";
-  p.Print (m_os);
+  m_os << " pkt-uid=" << p->GetUid () << " ";
+  p->Print (m_os);
   m_os << std::endl;  
 }
 
--- a/src/internet-node/ascii-trace.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/ascii-trace.h	Mon Oct 29 12:48:01 2007 -0700
@@ -23,6 +23,7 @@
 
 #include <string>
 #include <fstream>
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -37,10 +38,10 @@
   void TraceAllQueues (void);
   void TraceAllNetDeviceRx (void);
 private:
-  void LogDevQueueEnqueue (TraceContext const &context, const Packet &p);
-  void LogDevQueueDequeue (TraceContext const &context, const Packet &p);
-  void LogDevQueueDrop (TraceContext const &context, const Packet &p);
-  void LogDevRx (TraceContext const &context, const Packet &p);
+  void LogDevQueueEnqueue (TraceContext const &context, Ptr<const Packet> p);
+  void LogDevQueueDequeue (TraceContext const &context, Ptr<const Packet> p);
+  void LogDevQueueDrop (TraceContext const &context, Ptr<const Packet> p);
+  void LogDevRx (TraceContext const &context, Ptr<const Packet> p);
   std::ofstream m_os;
 };
 
--- a/src/internet-node/internet-node.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/internet-node.h	Mon Oct 29 12:48:01 2007 -0700
@@ -31,8 +31,6 @@
 
 namespace ns3 {
 
-class Packet;
-
 class InternetNode : public Node 
 {
 public:
@@ -44,7 +42,6 @@
   virtual void DoDispose(void);
   virtual Ptr<TraceResolver> GetTraceResolver (void) const;
 private:
-  bool ReceiveFromDevice (Ptr<NetDevice> device, const Packet &p, uint16_t protocolNumber) const;
   void Construct (void);
 };
 
--- a/src/internet-node/ipv4-end-point.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/ipv4-end-point.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -20,6 +20,7 @@
  */
 
 #include "ipv4-end-point.h"
+#include "ns3/packet.h"
 
 namespace ns3 {
 
@@ -72,7 +73,7 @@
 }
 
 void 
-Ipv4EndPoint::SetRxCallback (Callback<void,const Packet &, Ipv4Address, uint16_t> callback)
+Ipv4EndPoint::SetRxCallback (Callback<void,Ptr<Packet>, Ipv4Address, uint16_t> callback)
 {
   m_rxCallback = callback;
 }
@@ -84,7 +85,7 @@
 }
 
 void 
-Ipv4EndPoint::ForwardUp (const Packet &p, Ipv4Address saddr, uint16_t sport)
+Ipv4EndPoint::ForwardUp (Ptr<Packet> p, Ipv4Address saddr, uint16_t sport)
 {
   if (!m_rxCallback.IsNull ())
   {
--- a/src/internet-node/ipv4-end-point.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/ipv4-end-point.h	Mon Oct 29 12:48:01 2007 -0700
@@ -44,17 +44,17 @@
 
   void SetPeer (Ipv4Address address, uint16_t port);
 
-  void SetRxCallback (Callback<void,const Packet &, Ipv4Address, uint16_t> callback);
+  void SetRxCallback (Callback<void,Ptr<Packet>, Ipv4Address, uint16_t> callback);
   void SetDestroyCallback (Callback<void> callback);
 
-  void ForwardUp (const Packet &p, Ipv4Address saddr, uint16_t sport);
+  void ForwardUp (Ptr<Packet> p, Ipv4Address saddr, uint16_t sport);
 
 private:
   Ipv4Address m_localAddr;
   uint16_t m_localPort;
   Ipv4Address m_peerAddr;
   uint16_t m_peerPort;
-  Callback<void,const Packet &, Ipv4Address, uint16_t> m_rxCallback;
+  Callback<void,Ptr<Packet>, Ipv4Address, uint16_t> m_rxCallback;
   Callback<void> m_destroyCallback;
 };
 
--- a/src/internet-node/ipv4-interface.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/ipv4-interface.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -24,6 +24,7 @@
 #include "ns3/net-device.h"
 #include "ns3/trace-resolver.h"
 #include "ns3/log.h"
+#include "ns3/packet.h"
 
 NS_LOG_COMPONENT_DEFINE ("Ipv4Interface");
 
@@ -166,7 +167,7 @@
 
 // public wrapper on private virtual function
 void 
-Ipv4Interface::Send(Packet p, Ipv4Address dest)
+Ipv4Interface::Send(Ptr<Packet> p, Ipv4Address dest)
 {
   NS_LOG_FUNCTION;
   if (IsUp()) {
--- a/src/internet-node/ipv4-interface.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/ipv4-interface.h	Mon Oct 29 12:48:01 2007 -0700
@@ -145,12 +145,12 @@
    * This method will eventually call the private
    * SendTo method which must be implemented by subclasses.
    */ 
-  void Send(Packet p, Ipv4Address dest);
+  void Send(Ptr<Packet> p, Ipv4Address dest);
 
 protected:
   virtual void DoDispose (void);
 private:
-  virtual void SendTo (Packet p, Ipv4Address dest) = 0;
+  virtual void SendTo (Ptr<Packet> p, Ipv4Address dest) = 0;
   Ptr<NetDevice> m_netdevice;
   bool m_ifup;
   Ipv4Address m_address;
--- a/src/internet-node/ipv4-l3-protocol.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/ipv4-l3-protocol.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -201,17 +201,17 @@
   Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
   resolver->AddSource ("tx", 
                        TraceDoc ("send ipv4 packet to outgoing interface",
-                                 "const Packet &", "packet sent",
+                                 "Ptr<const Packet>", "packet sent",
                                  "uint32_t", "index of output ipv4 interface"),
                        m_txTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::TX));
   resolver->AddSource ("rx",
                        TraceDoc ("receive ipv4 packet from incoming interface",
-                                 "const Packet &", "packet received",
+                                 "Ptr<const Packet>", "packet received",
                                  "uint32_t", "index of input ipv4 interface"),
                        m_rxTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::RX));
   resolver->AddSource ("drop", 
                        TraceDoc ("drop ipv4 packet",
-                                 "const Packet &", "packet dropped"),
+                                 "Ptr<const Packet>", "packet dropped"),
                        m_dropTrace, Ipv4L3ProtocolTraceContextElement (Ipv4L3ProtocolTraceContextElement::DROP));
   resolver->AddArray ("interfaces", 
                       m_interfaces.begin (), m_interfaces.end (), 
@@ -281,11 +281,11 @@
 void
 Ipv4L3Protocol::Lookup (
   Ipv4Header const &ipHeader,
-  Packet packet,
+  Ptr<Packet> packet,
   Ipv4RoutingProtocol::RouteReplyCallback routeReply)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &ipHeader << ", " << &packet << &routeReply << ")");
+  NS_LOG_PARAM ("(" << &ipHeader << ", " << packet << &routeReply << ")");
 
   Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply);
 }
@@ -294,11 +294,11 @@
 Ipv4L3Protocol::Lookup (
   uint32_t ifIndex,
   Ipv4Header const &ipHeader,
-  Packet packet,
+  Ptr<Packet> packet,
   Ipv4RoutingProtocol::RouteReplyCallback routeReply)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << ifIndex << ", " << &ipHeader << ", " << &packet << 
+  NS_LOG_PARAM ("(" << ifIndex << ", " << &ipHeader << ", " << packet << 
     &routeReply << ")");
 
   for (Ipv4RoutingProtocolList::const_iterator rprotoIter = 
@@ -537,10 +537,10 @@
 }  
 
 void 
-Ipv4L3Protocol::Receive( Ptr<NetDevice> device, const Packet& p, uint16_t protocol, const Address &from)
+Ipv4L3Protocol::Receive( Ptr<NetDevice> device, Ptr<Packet> packet, uint16_t protocol, const Address &from)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &device << ", " << &p << ", " << protocol << ", " << 
+  NS_LOG_PARAM ("(" << &device << ", " << packet << ", " << protocol << ", " << 
     from << ")");
 
   NS_LOG_LOGIC ("Packet from " << from);
@@ -554,14 +554,13 @@
       ipv4Interface = *i;
       if (ipv4Interface->GetDevice () == device)
         {
-          m_rxTrace (p, index);
+          m_rxTrace (packet, index);
           break;
         }
       index++;
     }
-  Packet packet = p;
   Ipv4Header ipHeader;
-  packet.RemoveHeader (ipHeader);
+  packet->RemoveHeader (ipHeader);
 
   if (!ipHeader.IsChecksumOk ()) 
     {
@@ -579,13 +578,13 @@
 
 
 void 
-Ipv4L3Protocol::Send (Packet const &packet, 
+Ipv4L3Protocol::Send (Ptr<Packet> packet, 
             Ipv4Address source, 
             Ipv4Address destination,
             uint8_t protocol)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &packet << ", " << source << ", " << ", " << 
+  NS_LOG_PARAM ("(" << packet << ", " << source << ", " << ", " << 
     destination << ", " << protocol << ")");
 
   Ipv4Header ipHeader;
@@ -593,7 +592,7 @@
   ipHeader.SetSource (source);
   ipHeader.SetDestination (destination);
   ipHeader.SetProtocol (protocol);
-  ipHeader.SetPayloadSize (packet.GetSize ());
+  ipHeader.SetPayloadSize (packet->GetSize ());
   ipHeader.SetTtl (m_defaultTtl);
   ipHeader.SetMayFragment ();
   ipHeader.SetIdentification (m_identification);
@@ -607,10 +606,10 @@
            ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
         {
           Ptr<Ipv4Interface> outInterface = *ifaceIter;
-          Packet packetCopy = packet;
+          Ptr<Packet> packetCopy = packet->Copy ();
 
-          NS_ASSERT (packetCopy.GetSize () <= outInterface->GetMtu ());
-          packetCopy.AddHeader (ipHeader);
+          NS_ASSERT (packetCopy->GetSize () <= outInterface->GetMtu ());
+          packetCopy->AddHeader (ipHeader);
           m_txTrace (packetCopy, ifaceIndex);
           outInterface->Send (packetCopy, destination);
         }
@@ -633,11 +632,11 @@
 void
 Ipv4L3Protocol::SendRealOut (bool found,
                              Ipv4Route const &route,
-                             Packet packet,
+                             Ptr<Packet> packet,
                              Ipv4Header const &ipHeader)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << found << ", " << &route << ", " << &packet << 
+  NS_LOG_PARAM ("(" << found << ", " << &route << ", " << packet << 
     &ipHeader << ")");
 
   if (!found)
@@ -649,9 +648,9 @@
 
   NS_LOG_LOGIC ("Send via interface " << route.GetInterface ());
 
-  packet.AddHeader (ipHeader);
+  packet->AddHeader (ipHeader);
   Ptr<Ipv4Interface> outInterface = GetInterface (route.GetInterface ());
-  NS_ASSERT (packet.GetSize () <= outInterface->GetMtu ());
+  NS_ASSERT (packet->GetSize () <= outInterface->GetMtu ());
   m_txTrace (packet, route.GetInterface ());
   if (route.IsGateway ()) 
     {
@@ -668,12 +667,12 @@
 bool
 Ipv4L3Protocol::Forwarding (
   uint32_t ifIndex, 
-  Packet const &packet, 
+  Ptr<Packet> packet, 
   Ipv4Header &ipHeader, 
   Ptr<NetDevice> device)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << ifIndex << ", " << &packet << ", " << &ipHeader << 
+  NS_LOG_PARAM ("(" << ifIndex << ", " << packet << ", " << &ipHeader << 
     ", " << device << ")");
 
   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
@@ -747,11 +746,11 @@
 }
 
 void
-Ipv4L3Protocol::ForwardUp (Packet p, Ipv4Header const&ip,
+Ipv4L3Protocol::ForwardUp (Ptr<Packet> p, Ipv4Header const&ip,
                            Ptr<Ipv4Interface> incomingInterface)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &p << ", " << &ip << ")");
+  NS_LOG_PARAM ("(" << p << ", " << &ip << ")");
 
   Ptr<Ipv4L4Demux> demux = m_node->QueryInterface<Ipv4L4Demux> (Ipv4L4Demux::iid);
   Ptr<Ipv4L4Protocol> protocol = demux->GetProtocol (ip.GetProtocol ());
--- a/src/internet-node/ipv4-l3-protocol.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/ipv4-l3-protocol.h	Mon Oct 29 12:48:01 2007 -0700
@@ -129,7 +129,7 @@
    *    - implement a per-NetDevice ARP cache
    *    - send back arp replies on the right device
    */
-  void Receive( Ptr<NetDevice> device, const Packet& p, uint16_t protocol, const Address &from);
+  void Receive( Ptr<NetDevice> device, Ptr<Packet> p, uint16_t protocol, const Address &from);
 
   /**
    * \param packet packet to send
@@ -140,7 +140,7 @@
    * Higher-level layers call this method to send a packet
    * down the stack to the MAC and PHY layers.
    */
-  void Send (Packet const &packet, Ipv4Address source, 
+  void Send (Ptr<Packet> packet, Ipv4Address source, 
 	     Ipv4Address destination, uint8_t protocol);
 
 
@@ -162,7 +162,7 @@
                         uint32_t interface);
 
   void Lookup (Ipv4Header const &ipHeader,
-               Packet packet,
+               Ptr<Packet> packet,
                Ipv4RoutingProtocol::RouteReplyCallback routeReply);
 
   uint32_t GetNRoutes (void);
@@ -218,18 +218,18 @@
 private:
   void Lookup (uint32_t ifIndex,
                Ipv4Header const &ipHeader,
-               Packet packet,
+               Ptr<Packet> packet,
                Ipv4RoutingProtocol::RouteReplyCallback routeReply);
 
   void SendRealOut (bool found,
                     Ipv4Route const &route,
-                    Packet packet,
+                    Ptr<Packet> packet,
                     Ipv4Header const &ipHeader);
   bool Forwarding (uint32_t ifIndex, 
-                   Packet const &packet, 
+                   Ptr<Packet> packet, 
                    Ipv4Header &ipHeader, 
                    Ptr<NetDevice> device);
-  void ForwardUp (Packet p, Ipv4Header const&ip, Ptr<Ipv4Interface> incomingInterface);
+  void ForwardUp (Ptr<Packet> p, Ipv4Header const&ip, Ptr<Ipv4Interface> incomingInterface);
   uint32_t AddIpv4Interface (Ptr<Ipv4Interface> interface);
   void SetupLoopback (void);
 
@@ -243,9 +243,9 @@
   uint8_t m_defaultTtl;
   uint16_t m_identification;
   Ptr<Node> m_node;
-  CallbackTraceSource<Packet const &, uint32_t> m_txTrace;
-  CallbackTraceSource<Packet const &, uint32_t> m_rxTrace;
-  CallbackTraceSource<Packet const &> m_dropTrace;
+  CallbackTraceSource<Ptr<const Packet>, uint32_t> m_txTrace;
+  CallbackTraceSource<Ptr<const Packet>, uint32_t> m_rxTrace;
+  CallbackTraceSource<Ptr<const Packet> > m_dropTrace;
 
   Ipv4RoutingProtocolList m_routingProtocols;
 
--- a/src/internet-node/ipv4-l4-protocol.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/ipv4-l4-protocol.h	Mon Oct 29 12:48:01 2007 -0700
@@ -65,7 +65,7 @@
    * Called from lower-level layers to send the packet up
    * in the stack. 
    */
-  virtual void Receive(Packet& p, 
+  virtual void Receive(Ptr<Packet> p, 
                        Ipv4Address const &source,
                        Ipv4Address const &destination,
                        Ptr<Ipv4Interface> incomingInterface) = 0;
--- a/src/internet-node/ipv4-loopback-interface.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/ipv4-loopback-interface.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -24,6 +24,7 @@
 #include "ns3/net-device.h"
 #include "ns3/node.h"
 #include "ns3/mac48-address.h"
+#include "ns3/packet.h"
 #include "ipv4-loopback-interface.h"
 #include "ipv4-l3-protocol.h"
 
@@ -44,10 +45,10 @@
 }
 
 void 
-Ipv4LoopbackInterface::SendTo (Packet packet, Ipv4Address dest)
+Ipv4LoopbackInterface::SendTo (Ptr<Packet> packet, Ipv4Address dest)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &packet << ", " << dest << ")");
+  NS_LOG_PARAM ("(" << packet << ", " << dest << ")");
 
   Ptr<Ipv4L3Protocol> ipv4 = 
     m_node->QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
--- a/src/internet-node/ipv4-loopback-interface.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/ipv4-loopback-interface.h	Mon Oct 29 12:48:01 2007 -0700
@@ -42,7 +42,7 @@
   virtual ~Ipv4LoopbackInterface ();
 
  private:
-  virtual void SendTo (Packet p, Ipv4Address dest);
+  virtual void SendTo (Ptr<Packet> p, Ipv4Address dest);
 
   Ptr<Node> m_node;
 };
--- a/src/internet-node/ipv4-static-routing.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/ipv4-static-routing.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -518,11 +518,11 @@
 Ipv4StaticRouting::RequestRoute (
   uint32_t ifIndex,
   Ipv4Header const &ipHeader,
-  Packet packet,
+  Ptr<Packet> packet,
   RouteReplyCallback routeReply)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << ifIndex << &ipHeader << ", " << &packet << ", " << 
+  NS_LOG_PARAM ("(" << ifIndex << &ipHeader << ", " << packet << ", " << 
     &routeReply << ")");
 
   NS_LOG_LOGIC ("source = " << ipHeader.GetSource ());
@@ -542,7 +542,7 @@
 
           for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i)
             {
-              Packet p = packet;
+              Ptr<Packet> p = packet->Copy ();
               Ipv4Header h = ipHeader;
               Ipv4Route route = 
                 Ipv4Route::CreateHostRouteTo(h.GetDestination (), 
--- a/src/internet-node/ipv4-static-routing.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/ipv4-static-routing.h	Mon Oct 29 12:48:01 2007 -0700
@@ -141,7 +141,7 @@
  */
   virtual bool RequestRoute (uint32_t ifIndex,
                              Ipv4Header const &ipHeader,
-                             Packet packet,
+                             Ptr<Packet> packet,
                              RouteReplyCallback routeReply);
 
 /**
--- a/src/internet-node/pcap-trace.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/pcap-trace.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -28,6 +28,7 @@
 #include "ns3/pcap-writer.h"
 #include "ns3/node-list.h"
 #include "ns3/node.h"
+#include "ns3/packet.h"
 
 #include "ipv4-l3-protocol.h"
 
@@ -80,7 +81,7 @@
 }
 
 void 
-PcapTrace::LogIp (TraceContext const &context, Packet const &p, uint32_t interfaceIndex)
+PcapTrace::LogIp (TraceContext const &context, Ptr<const Packet> p, uint32_t interfaceIndex)
 {
   NodeListIndex nodeIndex;
   context.GetElement (nodeIndex);
--- a/src/internet-node/pcap-trace.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/pcap-trace.h	Mon Oct 29 12:48:01 2007 -0700
@@ -23,6 +23,7 @@
 
 #include <string>
 #include <vector>
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -39,7 +40,7 @@
   void TraceAllIp (void);
 private:
   PcapWriter *GetStream (uint32_t nodeId, uint32_t interfaceId);
-  void LogIp (TraceContext const &context, Packet const &p, uint32_t interfaceIndex);
+  void LogIp (TraceContext const &context, Ptr<const Packet> p, uint32_t interfaceIndex);
   std::string m_filename;
   struct Trace {
     uint32_t nodeId;
--- a/src/internet-node/udp-l4-protocol.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/udp-l4-protocol.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -122,45 +122,45 @@
 }
 
 void 
-UdpL4Protocol::Receive(Packet& packet, 
+UdpL4Protocol::Receive(Ptr<Packet> packet, 
                        Ipv4Address const &source,
                        Ipv4Address const &destination,
                        Ptr<Ipv4Interface> interface)
 {
   NS_LOG_FUNCTION; 
-  NS_LOG_PARAM ("(" << &packet << ", " << source << ", " << destination << 
+  NS_LOG_PARAM ("(" << packet << ", " << source << ", " << destination << 
     ")");
 
   UdpHeader udpHeader;
-  packet.RemoveHeader (udpHeader);
+  packet->RemoveHeader (udpHeader);
   Ipv4EndPointDemux::EndPoints endPoints =
     m_endPoints->Lookup (destination, udpHeader.GetDestination (),
                          source, udpHeader.GetSource (), interface);
   for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin ();
        endPoint != endPoints.end (); endPoint++)
     {
-      (*endPoint)->ForwardUp (packet, source, udpHeader.GetSource ());
+      (*endPoint)->ForwardUp (packet->Copy (), source, udpHeader.GetSource ());
     }
 }
 
 void
-UdpL4Protocol::Send (Packet packet, 
-           Ipv4Address saddr, Ipv4Address daddr, 
-           uint16_t sport, uint16_t dport)
+UdpL4Protocol::Send (Ptr<Packet> packet, 
+                     Ipv4Address saddr, Ipv4Address daddr, 
+                     uint16_t sport, uint16_t dport)
 {
   NS_LOG_FUNCTION; 
-  NS_LOG_PARAM ("(" << &packet << ", " << saddr << ", " << daddr << ", " << 
+  NS_LOG_PARAM ("(" << packet << ", " << saddr << ", " << daddr << ", " << 
     sport << ", " << dport << ")");
 
   UdpHeader udpHeader;
   udpHeader.SetDestination (dport);
   udpHeader.SetSource (sport);
-  udpHeader.SetPayloadSize (packet.GetSize ());
+  udpHeader.SetPayloadSize (packet->GetSize ());
   udpHeader.InitializeChecksum (saddr,
-                               daddr,
-                               PROT_NUMBER);
+                                daddr,
+                                PROT_NUMBER);
 
-  packet.AddHeader (udpHeader);
+  packet->AddHeader (udpHeader);
 
   Ptr<Ipv4L3Protocol> ipv4 = m_node->QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
   if (ipv4 != 0)
--- a/src/internet-node/udp-l4-protocol.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/udp-l4-protocol.h	Mon Oct 29 12:48:01 2007 -0700
@@ -73,7 +73,7 @@
    * \param sport The source port number
    * \param dport The destination port number
    */
-  void Send (Packet packet,
+  void Send (Ptr<Packet> packet,
              Ipv4Address saddr, Ipv4Address daddr, 
              uint16_t sport, uint16_t dport);
   /**
@@ -84,7 +84,7 @@
    * \param interface the interface from which the packet is coming.
    */
   // inherited from Ipv4L4Protocol
-  virtual void Receive(Packet& p, 
+  virtual void Receive(Ptr<Packet> p, 
                        Ipv4Address const &source,
                        Ipv4Address const &destination,
                        Ptr<Ipv4Interface> interface);
--- a/src/internet-node/udp-socket.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/udp-socket.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -187,10 +187,10 @@
 }
 
 int 
-UdpSocket::Send (const Packet &p)
+UdpSocket::Send (Ptr<Packet> p)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &p << ")");
+  NS_LOG_PARAM ("(" << p << ")");
 
   if (!m_connected)
     {
@@ -201,7 +201,7 @@
 }
 
 int 
-UdpSocket::DoSend (const Packet &p)
+UdpSocket::DoSend (Ptr<Packet> p)
 {
   NS_LOG_FUNCTION;
   if (m_endPoint == 0)
@@ -223,10 +223,10 @@
 }
 
 int
-UdpSocket::DoSendTo (const Packet &p, const Address &address)
+UdpSocket::DoSendTo (Ptr<Packet> p, const Address &address)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &p << ", " << address << ")");
+  NS_LOG_PARAM ("(" << p << ", " << address << ")");
 
   if (!m_connected)
     {
@@ -245,10 +245,10 @@
 }
 
 int
-UdpSocket::DoSendTo (const Packet &p, Ipv4Address dest, uint16_t port)
+UdpSocket::DoSendTo (Ptr<Packet> p, Ipv4Address dest, uint16_t port)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &p << ", " << dest << ", " << port << ")");
+  NS_LOG_PARAM ("(" << p << ", " << dest << ", " << port << ")");
 
   Ipv4Route routeToDest;
 
@@ -281,9 +281,9 @@
         {
           Ipv4Address addri = ipv4->GetAddress (i);
           Ipv4Mask maski = ipv4->GetNetworkMask (i);
-          m_udp->Send (p, addri, addri.GetSubnetDirectedBroadcast (maski),
+          m_udp->Send (p->Copy (), addri, addri.GetSubnetDirectedBroadcast (maski),
                        m_endPoint->GetLocalPort (), port);
-          NotifyDataSent (p.GetSize ());
+          NotifyDataSent (p->GetSize ());
         }
     }
   else if (ipv4->GetIfIndexForDestination(dest, localIfIndex))
@@ -291,7 +291,7 @@
       NS_LOG_LOGIC ("Route exists");
       m_udp->Send (p, ipv4->GetAddress (localIfIndex), dest,
 		   m_endPoint->GetLocalPort (), port);
-      NotifyDataSent (p.GetSize ());
+      NotifyDataSent (p->GetSize ());
       return 0;
     }
   else
@@ -305,10 +305,10 @@
 }
 
 int 
-UdpSocket::SendTo(const Address &address, const Packet &p)
+UdpSocket::SendTo(const Address &address, Ptr<Packet> p)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << address << ", " << &p << ")");
+  NS_LOG_PARAM ("(" << address << ", " << p << ")");
   InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
   Ipv4Address ipv4 = transport.GetIpv4 ();
   uint16_t port = transport.GetPort ();
@@ -316,10 +316,10 @@
 }
 
 void 
-UdpSocket::ForwardUp (const Packet &packet, Ipv4Address ipv4, uint16_t port)
+UdpSocket::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &packet << ", " << ipv4 << ", " << port << ")");
+  NS_LOG_PARAM ("(" << packet << ", " << ipv4 << ", " << port << ")");
 
   if (m_shutdownRecv)
     {
@@ -327,8 +327,7 @@
     }
   
   Address address = InetSocketAddress (ipv4, port);
-  Packet p = packet;
-  NotifyDataReceived (p, address);
+  NotifyDataReceived (packet, address);
 }
 
 } //namespace ns3
@@ -350,15 +349,15 @@
 
 class UdpSocketTest: public Test
 {
-  Packet m_receivedPacket;
-  Packet m_receivedPacket2;
+  Ptr<Packet> m_receivedPacket;
+  Ptr<Packet> m_receivedPacket2;
 
 public:
   virtual bool RunTests (void);
   UdpSocketTest ();
 
-  void ReceivePacket (Ptr<Socket> socket, const Packet &packet, const Address &from);
-  void ReceivePacket2 (Ptr<Socket> socket, const Packet &packet, const Address &from);
+  void ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from);
+  void ReceivePacket2 (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from);
 };
 
 
@@ -366,12 +365,12 @@
   : Test ("UdpSocket") {}
 
 
-void UdpSocketTest::ReceivePacket (Ptr<Socket> socket, const Packet &packet, const Address &from)
+void UdpSocketTest::ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from)
 {
   m_receivedPacket = packet;
 }
 
-void UdpSocketTest::ReceivePacket2 (Ptr<Socket> socket, const Packet &packet, const Address &from)
+void UdpSocketTest::ReceivePacket2 (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from)
 {
   m_receivedPacket2 = packet;
 }
@@ -421,20 +420,21 @@
   // ------ Now the tests ------------
 
   // Unicast test
-  m_receivedPacket = Packet ();
+  m_receivedPacket = Create<Packet> ();
   NS_TEST_ASSERT_EQUAL (txSocket->SendTo (InetSocketAddress (Ipv4Address("10.0.0.1"), 1234),
-                                          Packet (123)), 0);
+                                          Create<Packet> (123)), 0);
   Simulator::Run ();
-  NS_TEST_ASSERT_EQUAL (m_receivedPacket.GetSize (), 123);
+  NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
 
 
   // Simple broadcast test
 
-  m_receivedPacket = Packet ();
+  m_receivedPacket = Create<Packet> ();
   NS_TEST_ASSERT_EQUAL (txSocket->SendTo (InetSocketAddress (Ipv4Address("255.255.255.255"), 1234),
-                                          Packet (123)), 0);
+                                          Create<Packet> (123)), 0);
   Simulator::Run ();
-  NS_TEST_ASSERT_EQUAL (m_receivedPacket.GetSize (), 123);
+  NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
+
 
   // Broadcast test with multiple receiving sockets
 
@@ -444,13 +444,13 @@
   rxSocket2->SetRecvCallback (MakeCallback (&UdpSocketTest::ReceivePacket2, this));
   NS_TEST_ASSERT_EQUAL (rxSocket2->Bind (InetSocketAddress (Ipv4Address ("0.0.0.0"), 1234)), 0);
 
-  m_receivedPacket = Packet ();
-  m_receivedPacket2 = Packet ();
+  m_receivedPacket = Create<Packet> ();
+  m_receivedPacket2 = Create<Packet> ();
   NS_TEST_ASSERT_EQUAL (txSocket->SendTo (InetSocketAddress (Ipv4Address("255.255.255.255"), 1234),
-                                          Packet (123)), 0);
+                                          Create<Packet> (123)), 0);
   Simulator::Run ();
-  NS_TEST_ASSERT_EQUAL (m_receivedPacket.GetSize (), 123);
-  NS_TEST_ASSERT_EQUAL (m_receivedPacket2.GetSize (), 123);
+  NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
+  NS_TEST_ASSERT_EQUAL (m_receivedPacket2->GetSize (), 123);
 
   Simulator::Destroy ();
 
--- a/src/internet-node/udp-socket.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/internet-node/udp-socket.h	Mon Oct 29 12:48:01 2007 -0700
@@ -51,8 +51,8 @@
   virtual int ShutdownSend (void);
   virtual int ShutdownRecv (void);
   virtual int Connect(const Address &address);
-  virtual int Send (const Packet &p);
-  virtual int SendTo(const Address &address,const Packet &p);
+  virtual int Send (Ptr<Packet> p);
+  virtual int SendTo(const Address &address,Ptr<Packet> p);
 
 private:
 
@@ -60,11 +60,11 @@
   friend class Udp;
   // invoked by Udp class
   int FinishBind (void);
-  void ForwardUp (const Packet &p, Ipv4Address ipv4, uint16_t port);
+  void ForwardUp (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port);
   void Destroy (void);
-  int DoSend (const Packet &p);
-  int DoSendTo (const Packet &p, const Address &daddr);
-  int DoSendTo (const Packet &p, Ipv4Address daddr, uint16_t dport);
+  int DoSend (Ptr<Packet> p);
+  int DoSendTo (Ptr<Packet> p, const Address &daddr);
+  int DoSendTo (Ptr<Packet> p, Ipv4Address daddr, uint16_t dport);
 
   Ipv4EndPoint *m_endPoint;
   Ptr<Node> m_node;
--- a/src/node/drop-tail-queue.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/node/drop-tail-queue.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -58,10 +58,10 @@
 }
 
 bool 
-DropTailQueue::DoEnqueue (const Packet& p)
+DropTailQueue::DoEnqueue (Ptr<Packet> p)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &p << ")");
+  NS_LOG_PARAM ("(" << p << ")");
 
   if (m_packets.size () >= m_maxPackets)
     {
@@ -74,11 +74,10 @@
   return true;
 }
 
-bool
-DropTailQueue::DoDequeue (Packet& p)
+Ptr<Packet>
+DropTailQueue::DoDequeue (void)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &p << ")");
 
   if (m_packets.empty()) 
     {
@@ -86,19 +85,18 @@
       return false;
     }
 
-  p = m_packets.front ();
+  Ptr<Packet> p = m_packets.front ();
   m_packets.pop ();
 
-  NS_LOG_LOGIC ("Popped " << &p);
+  NS_LOG_LOGIC ("Popped " << p);
 
-  return true;
+  return p;
 }
 
-bool
-DropTailQueue::DoPeek (Packet& p)
+Ptr<Packet>
+DropTailQueue::DoPeek (void)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &p << ")");
 
   if (m_packets.empty()) 
     {
@@ -106,9 +104,9 @@
       return false;
     }
 
-  p = m_packets.front ();
+  Ptr<Packet> p = m_packets.front ();
 
-  return true;
+  return p;
 }
 
 }; // namespace ns3
--- a/src/node/drop-tail-queue.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/node/drop-tail-queue.h	Mon Oct 29 12:48:01 2007 -0700
@@ -57,12 +57,12 @@
   uint32_t GetMaxPackets (void);
 
 private:
-  virtual bool DoEnqueue (const Packet& p);
-  virtual bool DoDequeue (Packet &p);
-  virtual bool DoPeek (Packet &p);
+  virtual bool DoEnqueue (Ptr<Packet> p);
+  virtual Ptr<Packet> DoDequeue (void);
+  virtual Ptr<Packet> DoPeek (void);
 
 private:
-  std::queue<Packet> m_packets;
+  std::queue<Ptr<Packet> > m_packets;
   uint32_t m_maxPackets;
 };
 
--- a/src/node/ethernet-trailer.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/node/ethernet-trailer.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -56,7 +56,7 @@
 }
 
 bool
-EthernetTrailer::CheckFcs (const Packet& p) const
+EthernetTrailer::CheckFcs (Ptr<Packet> p) const
 {
   if (!m_calcFcs)
     {
@@ -68,7 +68,7 @@
 }
 
 void
-EthernetTrailer::CalcFcs (const Packet& p)
+EthernetTrailer::CalcFcs (Ptr<Packet> p)
 {
   NS_LOG_WARN ("FCS calculation is not yet enabled");
 }
--- a/src/node/ethernet-trailer.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/node/ethernet-trailer.h	Mon Oct 29 12:48:01 2007 -0700
@@ -23,10 +23,12 @@
 #define ETHERNET_TRAILER_H
 
 #include "ns3/trailer.h"
-#include "ns3/packet.h"
 #include <string>
 
 namespace ns3 {
+
+class Packet;
+
 /**
  * \brief Packet trailer for Ethernet
  *
@@ -55,7 +57,7 @@
    * calculated. The packet should not currently contain an FCS
    * trailer.
    */
-  void CalcFcs (const Packet& p);
+  void CalcFcs (Ptr<Packet> p);
   /**
    * \brief Sets the FCS to a new value
    * \param fcs New FCS value
@@ -74,7 +76,7 @@
    * If FCS checking is disabled, this method will always
    * return true.
    */
-  bool CheckFcs (const Packet& p) const;
+  bool CheckFcs (Ptr<Packet> p) const;
 
   /**
    *\return Returns the size of the trailer
--- a/src/node/ipv4.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/node/ipv4.h	Mon Oct 29 12:48:01 2007 -0700
@@ -66,7 +66,7 @@
    * inserted and consequently the protocol type has to change).
    *
    */
-  typedef Callback<void, bool, const Ipv4Route&, Packet, const Ipv4Header&> RouteReplyCallback;
+  typedef Callback<void, bool, const Ipv4Route&, Ptr<Packet>, const Ipv4Header&> RouteReplyCallback;
 
   /**
    * \brief Asynchronously requests a route for a given packet and IP header
@@ -103,7 +103,7 @@
    */
   virtual bool RequestRoute (uint32_t ifIndex,
                              const Ipv4Header &ipHeader,
-                             Packet packet,
+                             Ptr<Packet> packet,
                              RouteReplyCallback routeReply) = 0;
 
 /**
--- a/src/node/net-device.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/node/net-device.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -24,6 +24,7 @@
 #include "ns3/object.h"
 #include "ns3/log.h"
 #include "ns3/trace-resolver.h"
+#include "ns3/packet.h"
 #include "channel.h"
 #include "net-device.h"
 #include "node.h"
@@ -212,7 +213,7 @@
 
 // Receive packet from above
 bool 
-NetDevice::Send(const Packet& p, const Address& dest, uint16_t protocolNumber)
+NetDevice::Send(Ptr<Packet> p, const Address& dest, uint16_t protocolNumber)
 {
   NS_LOG_FUNCTION;
   if (m_isUp)
@@ -234,12 +235,12 @@
 
 // Receive packets from below
 bool
-NetDevice::ForwardUp(const Packet& p, uint16_t param, const Address &from)
+NetDevice::ForwardUp(Ptr<Packet> p, uint16_t param, const Address &from)
 {
   NS_LOG_FUNCTION;
   bool retval = false;
 
-  NS_LOG_LOGIC ("UID is " << p.GetUid() << " device is: " << GetName());
+  NS_LOG_LOGIC ("UID is " << p->GetUid() << " device is: " << GetName());
   
   if (!m_receiveCallback.IsNull ())
     {
--- a/src/node/net-device.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/node/net-device.h	Mon Oct 29 12:48:01 2007 -0700
@@ -25,7 +25,6 @@
 #include <string>
 #include <stdint.h>
 #include "ns3/callback.h"
-#include "ns3/packet.h"
 #include "ns3/object.h"
 #include "ns3/ptr.h"
 #include "address.h"
@@ -37,6 +36,7 @@
 class TraceResolver;
 class TraceContext;
 class Channel;
+class Packet;
 
 /**
  * \brief Network layer to device interface
@@ -210,7 +210,7 @@
    * 
    * \return whether the Send operation succeeded 
    */
-  bool Send(const Packet& p, const Address& dest, uint16_t protocolNumber);
+  bool Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
   /**
    * \returns the node base class which contains this network
    *          interface.
@@ -239,7 +239,7 @@
    * \returns true if the callback could handle the packet successfully, false
    *          otherwise.
    */
-  typedef Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t,const Address &> ReceiveCallback;
+  typedef Callback<bool,Ptr<NetDevice>,Ptr<Packet>,uint16_t,const Address &> ReceiveCallback;
 
   /**
    * \param cb callback to invoke whenever a packet has been received and must
@@ -304,7 +304,7 @@
    * forwards it to the higher layers by calling this method
    * which is responsible for passing it up to the Rx callback.
    */
-  bool ForwardUp (const Packet& p, uint16_t param, const Address &address);
+  bool ForwardUp (Ptr<Packet> p, uint16_t param, const Address &address);
 
 
   /**
@@ -327,7 +327,7 @@
    * method.  When the link is Up, this method is invoked to ask 
    * subclasses to forward packets. Subclasses MUST override this method.
    */
-  virtual bool SendTo (const Packet& p, const Address &dest, uint16_t protocolNumber) = 0;
+  virtual bool SendTo (Ptr<Packet> p, const Address &dest, uint16_t protocolNumber) = 0;
   /**
    * \returns true if this NetDevice needs the higher-layers
    *          to perform ARP over it, false otherwise.
--- a/src/node/node.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/node/node.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -23,6 +23,7 @@
 #include "net-device.h"
 #include "application.h"
 #include "packet-socket-factory.h"
+#include "ns3/packet.h"
 #include "ns3/simulator.h"
 #include "ns3/composite-trace-resolver.h"
 
@@ -199,7 +200,7 @@
 }
 
 bool
-Node::ReceiveFromDevice (Ptr<NetDevice> device, const Packet &packet, 
+Node::ReceiveFromDevice (Ptr<NetDevice> device, Ptr<Packet> packet, 
                          uint16_t protocol, const Address &from)
 {
   bool found = false;
--- a/src/node/node.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/node/node.h	Mon Oct 29 12:48:01 2007 -0700
@@ -26,6 +26,7 @@
 #include "ns3/object.h"
 #include "ns3/callback.h"
 #include "ns3/trace-context-element.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -154,7 +155,7 @@
   /**
    * A protocol handler
    */
-  typedef Callback<void,Ptr<NetDevice>, const Packet &,uint16_t,const Address &> ProtocolHandler;
+  typedef Callback<void,Ptr<NetDevice>, Ptr<Packet>,uint16_t,const Address &> ProtocolHandler;
   /**
    * \param handler the handler to register
    * \param protocolType the type of protocol this handler is 
@@ -198,7 +199,7 @@
    */
   virtual void NotifyDeviceAdded (Ptr<NetDevice> device);
 
-  bool ReceiveFromDevice (Ptr<NetDevice> device, const Packet &packet, 
+  bool ReceiveFromDevice (Ptr<NetDevice> device, Ptr<Packet>, 
                           uint16_t protocol, const Address &from);
   void Construct (void);
 
--- a/src/node/packet-socket.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/node/packet-socket.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -23,6 +23,7 @@
 #include "packet-socket-address.h"
 #include "ns3/log.h"
 #include "ns3/node.h"
+#include "ns3/packet.h"
 
 NS_LOG_COMPONENT_DEFINE ("PacketSocket");
 
@@ -203,7 +204,7 @@
 }
 
 int
-PacketSocket::Send (const Packet &p)
+PacketSocket::Send (Ptr<Packet> p)
 {
   NS_LOG_FUNCTION;
   if (m_state == STATE_OPEN ||
@@ -216,7 +217,7 @@
 }
 
 int
-PacketSocket::SendTo(const Address &address, const Packet &p)
+PacketSocket::SendTo(const Address &address, Ptr<Packet> p)
 {
   NS_LOG_FUNCTION;
   PacketSocketAddress ad;
@@ -266,7 +267,7 @@
     }
   if (!error)
     {
-      NotifyDataSent (p.GetSize ());
+      NotifyDataSent (p->GetSize ());
     }
 
   if (error)
@@ -281,7 +282,7 @@
 }
 
 void 
-PacketSocket::ForwardUp (Ptr<NetDevice> device, const Packet &packet, 
+PacketSocket::ForwardUp (Ptr<NetDevice> device, Ptr<Packet> packet, 
                          uint16_t protocol, const Address &from)
 {
   NS_LOG_FUNCTION;
@@ -290,15 +291,13 @@
       return;
     }
 
-  Packet p = packet;
-
   PacketSocketAddress address;
   address.SetPhysicalAddress (from);
   address.SetSingleDevice (device->GetIfIndex ());
   address.SetProtocol (protocol);
 
-  NS_LOG_LOGIC ("UID is " << packet.GetUid() << " PacketSocket " << this);
-  NotifyDataReceived (p, address);
+  NS_LOG_LOGIC ("UID is " << packet->GetUid() << " PacketSocket " << this);
+  NotifyDataReceived (packet, address);
 }
 
 }//namespace ns3
--- a/src/node/packet-socket.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/node/packet-socket.h	Mon Oct 29 12:48:01 2007 -0700
@@ -82,15 +82,15 @@
   virtual int ShutdownSend (void);
   virtual int ShutdownRecv (void);
   virtual int Connect(const Address &address);
-  virtual int Send (const Packet &p);
-  virtual int SendTo(const Address &address,const Packet &p);
+  virtual int Send (Ptr<Packet> p);
+  virtual int SendTo(const Address &address,Ptr<Packet> p);
 
 
 private:
 
 private:
   void Init (void);
-  void ForwardUp (Ptr<NetDevice> device, const Packet &packet, 
+  void ForwardUp (Ptr<NetDevice> device, Ptr<Packet> packet, 
                   uint16_t protocol, const Address &from);
   int DoBind (const PacketSocketAddress &address);
   virtual void DoDispose (void);
--- a/src/node/queue.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/node/queue.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -121,25 +121,25 @@
   Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
   resolver->AddSource ("enqueue", 
                        TraceDoc ("store packet in queue",
-                                 "const Packet &", "packet queued"),
+                                 "Ptr<const Packet>", "packet queued"),
                        m_traceEnqueue, QueueTraceType (QueueTraceType::ENQUEUE));
   resolver->AddSource ("dequeue", 
                        TraceDoc ("remove packet from queue",
-                                 "const Packet &", "packet dequeued"),
+                                 "Ptr<const Packet>", "packet dequeued"),
                        m_traceDequeue, QueueTraceType (QueueTraceType::DEQUEUE));
   resolver->AddSource ("drop", 
                        TraceDoc ("drop packet from queue", 
-                                 "const Packet &", "packet dropped"),
+                                 "Ptr<const Packet>", "packet dropped"),
                        m_traceDrop, QueueTraceType (QueueTraceType::DROP));
   resolver->SetParentResolver (Object::GetTraceResolver ());
   return resolver;
 }
 
 bool 
-Queue::Enqueue (const Packet& p)
+Queue::Enqueue (Ptr<Packet> p)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &p << ")");
+  NS_LOG_PARAM ("(" << p << ")");
   NS_LOG_LOGIC ("m_traceEnqueue (p)");
 
   m_traceEnqueue (p);
@@ -147,23 +147,22 @@
   bool retval = DoEnqueue (p);
   if (retval)
     {
-      m_nBytes += p.GetSize ();
+      m_nBytes += p->GetSize ();
       m_nPackets++;
     }
   return retval;
 }
 
-bool
-Queue::Dequeue (Packet &p)
+Ptr<Packet>
+Queue::Dequeue (void)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &p << ")");
 
-  bool retval = DoDequeue (p);
+  Ptr<Packet> packet = DoDequeue ();
 
-  if (retval)
+  if (packet != 0)
     {
-      m_nBytes -= p.GetSize ();
+      m_nBytes -= packet->GetSize ();
       m_nPackets--;
 
       NS_ASSERT (m_nBytes >= 0);
@@ -171,11 +170,9 @@
 
       NS_LOG_LOGIC("m_traceDequeue (p)");
 
-      const Packet packet = p;
       m_traceDequeue (packet);
     }
-
-  return retval;
+  return packet;
 }
 
 void
@@ -185,12 +182,11 @@
   NS_ASSERT_MSG (0, "Don't know what to do with dequeued packets!");
 }
 
-bool
-Queue::Peek (Packet &p)
+Ptr<Packet>
+Queue::Peek (void)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &p << ")");
-  return DoPeek (p);
+  return DoPeek ();
 }
 
 
@@ -261,13 +257,13 @@
 }
 
 void
-Queue::Drop (const Packet& p)
+Queue::Drop (Ptr<Packet> p)
 {
   NS_LOG_FUNCTION;
-  NS_LOG_PARAM ("(" << &p << ")");
+  NS_LOG_PARAM ("(" << p << ")");
 
   m_nTotalDroppedPackets++;
-  m_nTotalDroppedBytes += p.GetSize ();
+  m_nTotalDroppedBytes += p->GetSize ();
 
   NS_LOG_LOGIC ("m_traceDrop (p)");
   m_traceDrop (p);
--- a/src/node/queue.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/node/queue.h	Mon Oct 29 12:48:01 2007 -0700
@@ -91,17 +91,17 @@
    * Place a packet into the rear of the Queue
    * \return True if the operation was successful; false otherwise
    */
-  bool Enqueue (const Packet& p);
+  bool Enqueue (Ptr<Packet> p);
   /**
    * Remove a packet from the front of the Queue
-   * \return True if the operation was successful; false otherwise
+   * \return 0 if the operation was not successful; the packet otherwise.
    */
-  bool Dequeue (Packet &p);
+  Ptr<Packet> Dequeue (void);
   /**
    * Get a copy of the item at the front of the queue without removing it
-   * \return True if the operation was successful; false otherwise
+   * \return 0 if the operation was not successful; the packet otherwise.
    */
-  bool Peek (Packet &p);
+  Ptr<Packet> Peek (void);
 
   /**
    * XXX Doesn't do anything right now, think its supposed to flush the queue
@@ -173,19 +173,19 @@
 
 private:
 
-  virtual bool DoEnqueue (const Packet& p) = 0;
-  virtual bool DoDequeue (Packet &p) = 0;
-  virtual bool DoPeek (Packet &p) = 0;
+  virtual bool DoEnqueue (Ptr<Packet> p) = 0;
+  virtual Ptr<Packet> DoDequeue (void) = 0;
+  virtual Ptr<Packet> DoPeek (void) = 0;
 
 protected:
   Ptr<TraceResolver> GetTraceResolver (void) const;
   // called by subclasses to notify parent of packet drops.
-  void Drop (const Packet& p);
+  void Drop (Ptr<Packet> packet);
 
 private:
-  CallbackTraceSource<const Packet &> m_traceEnqueue;
-  CallbackTraceSource<const Packet &> m_traceDequeue;
-  CallbackTraceSource<const Packet &> m_traceDrop;
+  CallbackTraceSource<Ptr<const Packet> > m_traceEnqueue;
+  CallbackTraceSource<Ptr<const Packet> > m_traceDequeue;
+  CallbackTraceSource<Ptr<const Packet> > m_traceDrop;
 
   uint32_t m_nBytes;
   uint32_t m_nTotalReceivedBytes;
--- a/src/node/socket.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/node/socket.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -72,7 +72,7 @@
 }
 
 void 
-Socket::SetRecvCallback (Callback<void, Ptr<Socket>, const Packet &,const Address&> receivedData)
+Socket::SetRecvCallback (Callback<void, Ptr<Socket>, Ptr<Packet>,const Address&> receivedData)
 {
   NS_LOG_FUNCTION;
   m_receivedData = receivedData;
@@ -164,7 +164,7 @@
 }
 
 void 
-Socket::NotifyDataReceived (const Packet &p, const Address &from)
+Socket::NotifyDataReceived (Ptr<Packet> p, const Address &from)
 {
   NS_LOG_FUNCTION;
   if (!m_receivedData.IsNull ())
--- a/src/node/socket.h	Mon Oct 29 14:11:20 2007 +0000
+++ b/src/node/socket.h	Mon Oct 29 12:48:01 2007 -0700
@@ -121,7 +121,7 @@
    * \param receivedData Invoked whenever new data is received.
    *
    */
-  void SetRecvCallback (Callback<void, Ptr<Socket>, const Packet &,const Address&> receivedData);
+  void SetRecvCallback (Callback<void, Ptr<Socket>, Ptr<Packet>,const Address&> receivedData);
 
   /** 
    * \param address the address to try to allocate
@@ -174,7 +174,7 @@
    * \returns -1 in case of error or the number of bytes copied in the 
    *          internal buffer and accepted for transmission.
    */
-  virtual int Send (const Packet &p) = 0;
+  virtual int Send (Ptr<Packet> p) = 0;
   
   /**
    * \brief Send data to a specified peer.
@@ -183,7 +183,7 @@
    * \returns -1 in case of error or the number of bytes copied in the 
    *          internal buffer and accepted for transmission.
    */
-  virtual int SendTo(const Address &address,const Packet &p) = 0;
+  virtual int SendTo(const Address &address,Ptr<Packet> p) = 0;
 
 protected:
   void NotifyCloseCompleted (void);
@@ -194,7 +194,7 @@
   void NotifyNewConnectionCreated (Ptr<Socket> socket, const Address &from);
   void NotifyCloseRequested (void);
   void NotifyDataSent (uint32_t size);
-  void NotifyDataReceived (const Packet &p, const Address &from);
+  void NotifyDataReceived (Ptr<Packet> p, const Address &from);
 
   Callback<void,Ptr<Socket> >    m_closeCompleted;
   Callback<void, Ptr<Socket> >   m_connectionSucceeded;
@@ -204,7 +204,7 @@
   Callback<bool, Ptr<Socket>, const Address &>   m_connectionRequest;
   Callback<void, Ptr<Socket>, const Address&>    m_newConnectionCreated;
   Callback<void, Ptr<Socket>, uint32_t>          m_dataSent;
-  Callback<void, Ptr<Socket>, const Packet &,const Address&> m_receivedData;
+  Callback<void, Ptr<Socket>, Ptr<Packet>,const Address&> m_receivedData;
 };
 
 } //namespace ns3
--- a/utils/bench-packets.cc	Mon Oct 29 14:11:20 2007 +0000
+++ b/utils/bench-packets.cc	Mon Oct 29 12:48:01 2007 -0700
@@ -115,12 +115,12 @@
   BenchHeader<8> udp;
 
   for (uint32_t i = 0; i < n; i++) {
-      Packet p (2000);
-      p.AddHeader (udp);
-      p.AddHeader (ipv4);
-      Packet o = p;
-      o.RemoveHeader (ipv4);
-      o.RemoveHeader (udp);
+    Ptr<Packet> p = Create<Packet> (2000);
+    p->AddHeader (udp);
+    p->AddHeader (ipv4);
+    Ptr<Packet> o = p->Copy ();
+    o->RemoveHeader (ipv4);
+    o->RemoveHeader (udp);
   }
 }
 
@@ -131,25 +131,25 @@
   BenchHeader<8> udp;
 
   for (uint32_t i = 0; i < n; i++) {
-      Packet p (2000);
-      p.AddHeader (udp);
-      p.AddHeader (ipv4);
+    Ptr<Packet> p = Create<Packet> (2000);
+    p->AddHeader (udp);
+    p->AddHeader (ipv4);
   }
 }
 
 static void
-ptrC2 (Packet p)
+ptrC2 (Ptr<Packet> p)
 {
   BenchHeader<8> udp;
 
-  p.RemoveHeader (udp);
+  p->RemoveHeader (udp);
 }
 
 static void 
-ptrC1 (Packet p)
+ptrC1 (Ptr<Packet> p)
 {
   BenchHeader<25> ipv4;
-  p.RemoveHeader (ipv4);
+  p->RemoveHeader (ipv4);
   ptrC2 (p);
 }
 
@@ -160,10 +160,10 @@
   BenchHeader<8> udp;
 
   for (uint32_t i = 0; i < n; i++) {
-      Packet p (2000);
-      p.AddHeader (udp);
-      p.AddHeader (ipv4);
-      ptrC1 (p);
+    Ptr<Packet> p = Create<Packet> (2000);
+    p->AddHeader (udp);
+    p->AddHeader (ipv4);
+    ptrC1 (p);
   }
 }
 
@@ -174,13 +174,13 @@
   PacketPrinter printer;
   BenchHeader<25> ipv4;
   BenchHeader<8> udp;
-  Packet p (2000);
-  p.AddHeader (udp);
-  p.AddHeader (ipv4);
+  Ptr<Packet> p = Create<Packet> (2000);
+  p->AddHeader (udp);
+  p->AddHeader (ipv4);
 
   for (uint32_t i = 0; i < n; i++) 
     {
-      p.Print (std::cerr, printer);
+      p->Print (std::cerr, printer);
     }  
 }
 #endif