src/internet-node/ipv4-l3-protocol.cc
changeset 1742 cf76416ce75b
parent 1737 e72c130c3a59
parent 1412 9ce52d4f530b
child 1744 d658b8810b5a
equal deleted inserted replaced
1741:aa837ce15faf 1742:cf76416ce75b
    20 //
    20 //
    21 
    21 
    22 #include "ns3/packet.h"
    22 #include "ns3/packet.h"
    23 #include "ns3/debug.h"
    23 #include "ns3/debug.h"
    24 #include "ns3/composite-trace-resolver.h"
    24 #include "ns3/composite-trace-resolver.h"
    25 #include "ns3/array-trace-resolver.h"
       
    26 #include "ns3/callback.h"
    25 #include "ns3/callback.h"
    27 #include "ns3/ipv4-address.h"
    26 #include "ns3/ipv4-address.h"
    28 #include "ns3/ipv4-route.h"
    27 #include "ns3/ipv4-route.h"
    29 #include "ns3/node.h"
    28 #include "ns3/node.h"
    30 #include "ns3/net-device.h"
    29 #include "ns3/net-device.h"
    86 Ipv4L3ProtocolTraceContextElement::GetUid (void)
    85 Ipv4L3ProtocolTraceContextElement::GetUid (void)
    87 {
    86 {
    88   static uint16_t uid = AllocateUid<Ipv4L3ProtocolTraceContextElement> ("Ipv4L3ProtocolTraceContextElement");
    87   static uint16_t uid = AllocateUid<Ipv4L3ProtocolTraceContextElement> ("Ipv4L3ProtocolTraceContextElement");
    89   return uid;
    88   return uid;
    90 }
    89 }
    91 
    90 std::string 
    92 
    91 Ipv4L3ProtocolTraceContextElement::GetTypeName (void) const
    93 Ipv4l3ProtocolInterfaceIndex::Ipv4l3ProtocolInterfaceIndex ()
    92 {
       
    93   return "ns3::Ipv4L3ProtocolTraceContextElement";
       
    94 }
       
    95 
       
    96 
       
    97 Ipv4L3ProtocolInterfaceIndex::Ipv4L3ProtocolInterfaceIndex ()
    94   : m_index (0)
    98   : m_index (0)
    95 {}
    99 {}
    96 Ipv4l3ProtocolInterfaceIndex::Ipv4l3ProtocolInterfaceIndex (uint32_t index)
   100 Ipv4L3ProtocolInterfaceIndex::Ipv4L3ProtocolInterfaceIndex (uint32_t index)
    97   : m_index (index)
   101   : m_index (index)
    98 {}
   102 {}
    99 uint32_t 
   103 uint32_t 
   100 Ipv4l3ProtocolInterfaceIndex::Get (void) const
   104 Ipv4L3ProtocolInterfaceIndex::Get (void) const
   101 {
   105 {
   102   return m_index;
   106   return m_index;
   103 }
   107 }
   104 void 
   108 void 
   105 Ipv4l3ProtocolInterfaceIndex::Print (std::ostream &os) const
   109 Ipv4L3ProtocolInterfaceIndex::Print (std::ostream &os) const
   106 {
   110 {
   107   os << "ipv4-interface=" << m_index;
   111   os << "ipv4-interface=" << m_index;
   108 }
   112 }
   109 uint16_t 
   113 uint16_t 
   110 Ipv4l3ProtocolInterfaceIndex::GetUid (void)
   114 Ipv4L3ProtocolInterfaceIndex::GetUid (void)
   111 {
   115 {
   112   static uint16_t uid = AllocateUid<Ipv4l3ProtocolInterfaceIndex> ("Ipv4l3ProtocolInterfaceIndex");
   116   static uint16_t uid = AllocateUid<Ipv4L3ProtocolInterfaceIndex> ("Ipv4L3ProtocolInterfaceIndex");
   113   return uid;
   117   return uid;
       
   118 }
       
   119 std::string
       
   120 Ipv4L3ProtocolInterfaceIndex::GetTypeName (void) const
       
   121 {
       
   122   return "ns3::Ipv4L3ProtocolInterfaceIndex";
   114 }
   123 }
   115 
   124 
   116 
   125 
   117 Ipv4L3Protocol::Ipv4L3Protocol(Ptr<Node> node)
   126 Ipv4L3Protocol::Ipv4L3Protocol(Ptr<Node> node)
   118   : m_nInterfaces (0),
   127   : m_nInterfaces (0),
   129 {}
   138 {}
   130 
   139 
   131 void 
   140 void 
   132 Ipv4L3Protocol::DoDispose (void)
   141 Ipv4L3Protocol::DoDispose (void)
   133 {
   142 {
   134   for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
       
   135     {
       
   136       delete (*i);
       
   137     }
       
   138   m_interfaces.clear ();
   143   m_interfaces.clear ();
   139   m_node = 0;
   144   m_node = 0;
   140   m_staticRouting->Dispose ();
   145   m_staticRouting->Dispose ();
   141   m_staticRouting = 0;
   146   m_staticRouting = 0;
   142   Object::DoDispose ();
   147   Object::DoDispose ();
   143 }
   148 }
   144 
   149 
   145 void
   150 void
   146 Ipv4L3Protocol::SetupLoopback (void)
   151 Ipv4L3Protocol::SetupLoopback (void)
   147 {
   152 {
   148   Ipv4LoopbackInterface * interface = new Ipv4LoopbackInterface (m_node);
   153   Ptr<Ipv4LoopbackInterface> interface = Create<Ipv4LoopbackInterface> (m_node);
   149   interface->SetAddress (Ipv4Address::GetLoopback ());
   154   interface->SetAddress (Ipv4Address::GetLoopback ());
   150   interface->SetNetworkMask (Ipv4Mask::GetLoopback ());
   155   interface->SetNetworkMask (Ipv4Mask::GetLoopback ());
   151   uint32_t index = AddIpv4Interface (interface);
   156   uint32_t index = AddIpv4Interface (interface);
   152   AddHostRouteTo (Ipv4Address::GetLoopback (), index);
   157   AddHostRouteTo (Ipv4Address::GetLoopback (), index);
   153   interface->SetUp ();
   158   interface->SetUp ();
   154 }
   159 }
   155 
   160 
   156 TraceResolver *
   161 Ptr<TraceResolver>
   157 Ipv4L3Protocol::CreateTraceResolver (TraceContext const &context)
   162 Ipv4L3Protocol::GetTraceResolver (void) const
   158 {
   163 {
   159   CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
   164   Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
   160   resolver->Add ("tx", m_txTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::TX));
   165   resolver->AddSource ("tx", 
   161   resolver->Add ("rx", m_rxTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::RX));
   166                        TraceDoc ("send ipv4 packet to outgoing interface",
   162   resolver->Add ("drop", m_dropTrace, Ipv4L3ProtocolTraceContextElement (Ipv4L3ProtocolTraceContextElement::DROP));
   167                                  "const Packet &", "packet sent",
   163   resolver->Add ("interfaces", 
   168                                  "uint32_t", "index of output ipv4 interface"),
   164                  MakeCallback (&Ipv4L3Protocol::InterfacesCreateTraceResolver, this));
   169                        m_txTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::TX));
   165   return resolver;
   170   resolver->AddSource ("rx",
   166 }
   171                        TraceDoc ("receive ipv4 packet from incoming interface",
   167 
   172                                  "const Packet &", "packet received",
   168 TraceResolver *
   173                                  "uint32_t", "index of input ipv4 interface"),
   169 Ipv4L3Protocol::InterfacesCreateTraceResolver (TraceContext const &context) const
   174                        m_rxTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::RX));
   170 {
   175   resolver->AddSource ("drop", 
   171   ArrayTraceResolver<Ipv4Interface *, Ipv4l3ProtocolInterfaceIndex> *resolver = 
   176                        TraceDoc ("drop ipv4 packet",
   172     new ArrayTraceResolver<Ipv4Interface *,Ipv4l3ProtocolInterfaceIndex> 
   177                                  "const Packet &", "packet dropped"),
   173     (context,
   178                        m_dropTrace, Ipv4L3ProtocolTraceContextElement (Ipv4L3ProtocolTraceContextElement::DROP));
   174      MakeCallback (&Ipv4L3Protocol::GetNInterfaces, this),
   179   resolver->AddArray ("interfaces", 
   175      MakeCallback (&Ipv4L3Protocol::GetInterface, this));
   180                       m_interfaces.begin (), m_interfaces.end (), 
       
   181                       Ipv4L3ProtocolInterfaceIndex ());
   176   return resolver;
   182   return resolver;
   177 }
   183 }
   178 
   184 
   179 void 
   185 void 
   180 Ipv4L3Protocol::SetDefaultTtl (uint8_t ttl)
   186 Ipv4L3Protocol::SetDefaultTtl (uint8_t ttl)
   263 
   269 
   264 
   270 
   265 uint32_t 
   271 uint32_t 
   266 Ipv4L3Protocol::AddInterface (Ptr<NetDevice> device)
   272 Ipv4L3Protocol::AddInterface (Ptr<NetDevice> device)
   267 {
   273 {
   268   Ipv4Interface *interface = new ArpIpv4Interface (m_node, device);
   274   Ptr<Ipv4Interface> interface = Create<ArpIpv4Interface> (m_node, device);
   269   return AddIpv4Interface (interface);
   275   return AddIpv4Interface (interface);
   270 }
   276 }
   271 uint32_t 
   277 uint32_t 
   272 Ipv4L3Protocol::AddIpv4Interface (Ipv4Interface *interface)
   278 Ipv4L3Protocol::AddIpv4Interface (Ptr<Ipv4Interface>interface)
   273 {
   279 {
   274   uint32_t index = m_nInterfaces;
   280   uint32_t index = m_nInterfaces;
   275   m_interfaces.push_back (interface);
   281   m_interfaces.push_back (interface);
   276   m_nInterfaces++;
   282   m_nInterfaces++;
   277   return index;
   283   return index;
   278 }
   284 }
   279 Ipv4Interface *
   285 Ptr<Ipv4Interface>
   280 Ipv4L3Protocol::GetInterface (uint32_t index) const
   286 Ipv4L3Protocol::GetInterface (uint32_t index) const
   281 {
   287 {
   282   uint32_t tmp = 0;
   288   uint32_t tmp = 0;
   283   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
   289   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
   284     {
   290     {
   294 Ipv4L3Protocol::GetNInterfaces (void) const
   300 Ipv4L3Protocol::GetNInterfaces (void) const
   295 {
   301 {
   296   return m_nInterfaces;
   302   return m_nInterfaces;
   297 }
   303 }
   298 
   304 
   299 Ipv4Interface *
   305 Ptr<Ipv4Interface>
   300 Ipv4L3Protocol::FindInterfaceForDevice (Ptr<const NetDevice> device)
   306 Ipv4L3Protocol::FindInterfaceForDevice (Ptr<const NetDevice> device)
   301 {
   307 {
   302   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
   308   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
   303     {
   309     {
   304       if ((*i)->GetDevice () == device)
   310       if ((*i)->GetDevice () == device)
   362     {
   368     {
   363       uint32_t ifaceIndex = 0;
   369       uint32_t ifaceIndex = 0;
   364       for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
   370       for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
   365            ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
   371            ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
   366         {
   372         {
   367           Ipv4Interface *outInterface = *ifaceIter;
   373           Ptr<Ipv4Interface> outInterface = *ifaceIter;
   368           Packet packetCopy = packet;
   374           Packet packetCopy = packet;
   369 
   375 
   370           NS_ASSERT (packetCopy.GetSize () <= outInterface->GetMtu ());
   376           NS_ASSERT (packetCopy.GetSize () <= outInterface->GetMtu ());
   371           packetCopy.AddHeader (ipHeader);
   377           packetCopy.AddHeader (ipHeader);
   372           m_txTrace (packetCopy, ifaceIndex);
   378           m_txTrace (packetCopy, ifaceIndex);
   399       NS_DEBUG ("no route to host. drop.");
   405       NS_DEBUG ("no route to host. drop.");
   400       m_dropTrace (packet);
   406       m_dropTrace (packet);
   401       return;
   407       return;
   402     }
   408     }
   403   packet.AddHeader (ipHeader);
   409   packet.AddHeader (ipHeader);
   404   Ipv4Interface *outInterface = GetInterface (route.GetInterface ());
   410   Ptr<Ipv4Interface> outInterface = GetInterface (route.GetInterface ());
   405   NS_ASSERT (packet.GetSize () <= outInterface->GetMtu ());
   411   NS_ASSERT (packet.GetSize () <= outInterface->GetMtu ());
   406   m_txTrace (packet, route.GetInterface ());
   412   m_txTrace (packet, route.GetInterface ());
   407   if (route.IsGateway ()) 
   413   if (route.IsGateway ()) 
   408     {
   414     {
   409       outInterface->Send (packet, route.GetGateway ());
   415       outInterface->Send (packet, route.GetGateway ());
   429     }
   435     }
   430   
   436   
   431   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
   437   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
   432        i != m_interfaces.end (); i++) 
   438        i != m_interfaces.end (); i++) 
   433     {
   439     {
   434       Ipv4Interface *interface = *i;
   440       Ptr<Ipv4Interface> interface = *i;
   435       if (interface->GetDevice () == device)
   441       if (interface->GetDevice () == device)
   436 	{
   442 	{
   437 	  if (ipHeader.GetDestination ().IsEqual (interface->GetBroadcast ())) 
   443 	  if (ipHeader.GetDestination ().IsEqual (interface->GetBroadcast ())) 
   438 	    {
   444 	    {
   439 	      NS_DEBUG ("for me 2");
   445 	      NS_DEBUG ("for me 2");
   479 }
   485 }
   480 
   486 
   481 void 
   487 void 
   482 Ipv4L3Protocol::SetAddress (uint32_t i, Ipv4Address address)
   488 Ipv4L3Protocol::SetAddress (uint32_t i, Ipv4Address address)
   483 {
   489 {
   484   Ipv4Interface *interface = GetInterface (i);
   490   Ptr<Ipv4Interface> interface = GetInterface (i);
   485   interface->SetAddress (address);
   491   interface->SetAddress (address);
   486 }
   492 }
   487 void 
   493 void 
   488 Ipv4L3Protocol::SetNetworkMask (uint32_t i, Ipv4Mask mask)
   494 Ipv4L3Protocol::SetNetworkMask (uint32_t i, Ipv4Mask mask)
   489 {
   495 {
   490   Ipv4Interface *interface = GetInterface (i);
   496   Ptr<Ipv4Interface> interface = GetInterface (i);
   491   interface->SetNetworkMask (mask);
   497   interface->SetNetworkMask (mask);
   492 }
   498 }
   493 Ipv4Mask 
   499 Ipv4Mask 
   494 Ipv4L3Protocol::GetNetworkMask (uint32_t i) const
   500 Ipv4L3Protocol::GetNetworkMask (uint32_t i) const
   495 {
   501 {
   496   Ipv4Interface *interface = GetInterface (i);
   502   Ptr<Ipv4Interface> interface = GetInterface (i);
   497   return interface->GetNetworkMask ();
   503   return interface->GetNetworkMask ();
   498 }
   504 }
   499 Ipv4Address 
   505 Ipv4Address 
   500 Ipv4L3Protocol::GetAddress (uint32_t i) const
   506 Ipv4L3Protocol::GetAddress (uint32_t i) const
   501 {
   507 {
   502   Ipv4Interface *interface = GetInterface (i);
   508   Ptr<Ipv4Interface> interface = GetInterface (i);
   503   return interface->GetAddress ();
   509   return interface->GetAddress ();
   504 }
   510 }
   505 uint16_t 
   511 uint16_t 
   506 Ipv4L3Protocol::GetMtu (uint32_t i) const
   512 Ipv4L3Protocol::GetMtu (uint32_t i) const
   507 {
   513 {
   508   Ipv4Interface *interface = GetInterface (i);
   514   Ptr<Ipv4Interface> interface = GetInterface (i);
   509   return interface->GetMtu ();
   515   return interface->GetMtu ();
   510 }
   516 }
   511 bool 
   517 bool 
   512 Ipv4L3Protocol::IsUp (uint32_t i) const
   518 Ipv4L3Protocol::IsUp (uint32_t i) const
   513 {
   519 {
   514   Ipv4Interface *interface = GetInterface (i);
   520   Ptr<Ipv4Interface> interface = GetInterface (i);
   515   return interface->IsUp ();
   521   return interface->IsUp ();
   516 }
   522 }
   517 void 
   523 void 
   518 Ipv4L3Protocol::SetUp (uint32_t i)
   524 Ipv4L3Protocol::SetUp (uint32_t i)
   519 {
   525 {
   520   Ipv4Interface *interface = GetInterface (i);
   526   Ptr<Ipv4Interface> interface = GetInterface (i);
   521   interface->SetUp ();
   527   interface->SetUp ();
   522 
   528 
   523   // If interface address and network mask have been set, add a route
   529   // If interface address and network mask have been set, add a route
   524   // to the network of the interface (like e.g. ifconfig does on a
   530   // to the network of the interface (like e.g. ifconfig does on a
   525   // Linux box)
   531   // Linux box)
   531     }
   537     }
   532 }
   538 }
   533 void 
   539 void 
   534 Ipv4L3Protocol::SetDown (uint32_t ifaceIndex)
   540 Ipv4L3Protocol::SetDown (uint32_t ifaceIndex)
   535 {
   541 {
   536   Ipv4Interface *interface = GetInterface (ifaceIndex);
   542   Ptr<Ipv4Interface> interface = GetInterface (ifaceIndex);
   537   interface->SetDown ();
   543   interface->SetDown ();
   538 
   544 
   539   // Remove all routes that are going through this interface
   545   // Remove all routes that are going through this interface
   540   bool modified = true;
   546   bool modified = true;
   541   while (modified)
   547   while (modified)