25 #include "ns3/ipv4-click-routing.h" 
   27 #include "ns3/socket.h" 
   28 #include "ns3/ethernet-header.h" 
   29 #include "ns3/llc-snap-header.h" 
   30 #include "ns3/net-device.h" 
   31 #include "ns3/uinteger.h" 
   32 #include "ns3/object-vector.h" 
   34 #include "ns3/ipv4-raw-socket-impl.h" 
   35 #include "ns3/arp-l3-protocol.h" 
   36 #include "ns3/ip-l4-protocol.h" 
   37 #include "ns3/icmpv4-l4-protocol.h" 
   38 #include "ns3/loopback-net-device.h" 
   44 const uint16_t Ipv4L3ClickProtocol::PROT_NUMBER = 0x0800;
 
   52   static TypeId tid = TypeId (
"ns3::Ipv4L3ClickProtocol")
 
   54     .AddConstructor<Ipv4L3ClickProtocol> ()
 
   55     .SetGroupName (
"Click")
 
   56     .AddAttribute (
"DefaultTtl", 
"The TTL value set by default on all outgoing packets generated on this node.",
 
   59                    MakeUintegerChecker<uint8_t> ())
 
   60     .AddAttribute (
"InterfaceList", 
"The set of Ipv4 interfaces associated to this Ipv4 stack.",
 
   63                    MakeObjectVectorChecker<Ipv4Interface> ())
 
   68 Ipv4L3ClickProtocol::Ipv4L3ClickProtocol ()
 
   69   : m_identification (0)
 
   73 Ipv4L3ClickProtocol::~Ipv4L3ClickProtocol ()
 
   81   for (L4List_t::iterator i = m_protocols.begin (); i != m_protocols.end (); ++i)
 
   87   for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); ++i)
 
   91   m_interfaces.clear ();
 
   92   m_reverseInterfacesContainer.clear ();
 
   96   m_routingProtocol = 0;
 
  105       Ptr<Node>node = this->GetObject<Node> ();
 
  110           this->SetNode (node);
 
  120   m_routingProtocol = routingProtocol;
 
  121   m_routingProtocol->SetIpv4 (
this);
 
  125 Ptr<Ipv4RoutingProtocol>
 
  128   return m_routingProtocol;
 
  132 Ipv4L3ClickProtocol::GetInterface (uint32_t index)
 const 
  135   if (index < m_interfaces.size ())
 
  137       return m_interfaces[index];
 
  146   return m_interfaces.size ();
 
  155   int32_t 
interface = 0;
 
  156   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
 
  157        i != m_interfaces.end ();
 
  160       for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
 
  162           if ((*i)->GetAddress (j).GetLocal () == 
address)
 
  179   int32_t 
interface = 0;
 
  180   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
 
  181        i != m_interfaces.end ();
 
  184       for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
 
  186           if ((*i)->GetAddress (j).GetLocal ().CombineMask (mask) == 
address.CombineMask (mask))
 
  198   Ptr<const NetDevice> device)
 const 
  202   Ipv4InterfaceReverseContainer::const_iterator iter = m_reverseInterfacesContainer.find (device);
 
  203   if (iter != m_reverseInterfacesContainer.end ())
 
  205       return (*iter).second;
 
  219       Ipv4InterfaceAddress iaddr = 
GetAddress (iif, i);
 
  220       if (
address == iaddr.GetLocal ())
 
  225       if (
address == iaddr.GetBroadcast ())
 
  235       if (MulticastCheckGroup (iif, 
address ))
 
  254           if (j == uint32_t (iif))
 
  260               Ipv4InterfaceAddress iaddr = 
GetAddress (j, i);
 
  261               if (
address == iaddr.GetLocal ())
 
  267               if (
address == iaddr.GetBroadcast ())
 
  269                   NS_LOG_LOGIC (
"For me (interface broadcast address on another interface)");
 
  282   m_ipForward = forward;
 
  283   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
 
  285       (*i)->SetForwarding (forward);
 
  298   m_weakEsModel = model;
 
  304   return m_weakEsModel;
 
  311   return GetInterface (i)->GetDevice ();
 
  315 Ipv4L3ClickProtocol::SetDefaultTtl (uint8_t ttl)
 
  322 Ipv4L3ClickProtocol::SetupLoopback (
void)
 
  326   Ptr<Ipv4Interface> 
interface = 
CreateObject<Ipv4Interface> ();
 
  327   Ptr<LoopbackNetDevice> device = 0;
 
  329   for (uint32_t i = 0; i < m_node->GetNDevices (); i++)
 
  331       if ((device = DynamicCast<LoopbackNetDevice> (m_node->GetDevice (i))))
 
  338       device = CreateObject<LoopbackNetDevice> ();
 
  339       m_node->AddDevice (device);
 
  341   interface->SetDevice (device);
 
  342   interface->SetNode (m_node);
 
  344   interface->AddAddress (ifaceAddr);
 
  345   uint32_t index = AddIpv4Interface (interface);
 
  346   Ptr<Node> node = GetObject<Node> ();
 
  347   node->RegisterProtocolHandler (
MakeCallback (&Ipv4L3ClickProtocol::Receive, 
this),
 
  348                                  Ipv4L3ClickProtocol::PROT_NUMBER, device);
 
  350   if (m_routingProtocol != 0)
 
  352       m_routingProtocol->NotifyInterfaceUp (index);
 
  360   Ptr<Ipv4RawSocketImpl> socket = CreateObject<Ipv4RawSocketImpl> ();
 
  361   socket->SetNode (m_node);
 
  362   m_sockets.push_back (socket);
 
  369   for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
 
  382 Ipv4L3ClickProtocol::SetNode (Ptr<Node> node)
 
  393   Ptr<Ipv4Interface> 
interface = GetInterface (i);
 
  394   bool retVal = interface->AddAddress (
address);
 
  395   if (m_routingProtocol != 0)
 
  397       m_routingProtocol->NotifyAddAddress (i, 
address);
 
  406   Ptr<Ipv4Interface> 
interface = GetInterface (interfaceIndex);
 
  407   return interface->GetAddress (addressIndex);
 
  414   Ptr<Ipv4Interface> iface = GetInterface (interface);
 
  415   return iface->GetNAddresses ();
 
  422   Ptr<Ipv4Interface> 
interface = GetInterface (i);
 
  423   Ipv4InterfaceAddress 
address = interface->RemoveAddress (addressIndex);
 
  424   if (
address != Ipv4InterfaceAddress ())
 
  426       if (m_routingProtocol != 0)
 
  428           m_routingProtocol->NotifyRemoveAddress (i, 
address);
 
  445   Ptr<Ipv4Interface> 
interface = GetInterface (i);
 
  446   Ipv4InterfaceAddress ifAddr = interface->RemoveAddress (
address);
 
  447   if (ifAddr != Ipv4InterfaceAddress ())
 
  449       if (m_routingProtocol != 0)
 
  451           m_routingProtocol->NotifyRemoveAddress (i, ifAddr);
 
  473       Ipv4InterfaceAddress test = 
GetAddress (interfaceIdx, i);
 
  474       if (test.GetLocal ().CombineMask (test.GetMask ()) == dest.CombineMask (test.GetMask ()))
 
  476           if (test.IsSecondary () == 
false)
 
  478               return test.GetLocal ();
 
  490   Ipv4Address addr (
"0.0.0.0");
 
  491   Ipv4InterfaceAddress iaddr;
 
  501           if (iaddr.IsSecondary ())
 
  505           if (iaddr.GetScope () > scope)
 
  509           if (dst.CombineMask (iaddr.GetMask ())  == iaddr.GetLocal ().CombineMask (iaddr.GetMask ()) )
 
  511               return iaddr.GetLocal ();
 
  515               addr = iaddr.GetLocal ();
 
  531           if (iaddr.IsSecondary ())
 
  536               && iaddr.GetScope () <= scope)
 
  538               return iaddr.GetLocal ();
 
  542   NS_LOG_WARN (
"Could not find source address for " << dst << 
" and scope " 
  543                                                     << scope << 
", returning 0");
 
  551   Ptr<Ipv4Interface> 
interface = GetInterface (i);
 
  552   interface->SetMetric (metric);
 
  559   Ptr<Ipv4Interface> 
interface = GetInterface (i);
 
  560   return interface->GetMetric ();
 
  567   Ptr<Ipv4Interface> 
interface = GetInterface (i);
 
  568   return interface->GetDevice ()->GetMtu ();
 
  575   Ptr<Ipv4Interface> 
interface = GetInterface (i);
 
  576   return interface->IsUp ();
 
  583   Ptr<Ipv4Interface> 
interface = GetInterface (i);
 
  586   if (m_routingProtocol != 0)
 
  588       m_routingProtocol->NotifyInterfaceUp (i);
 
  596   Ptr<Ipv4Interface> 
interface = GetInterface (ifaceIndex);
 
  597   interface->SetDown ();
 
  599   if (m_routingProtocol != 0)
 
  601       m_routingProtocol->NotifyInterfaceDown (ifaceIndex);
 
  609   Ptr<Ipv4Interface> 
interface = GetInterface (i);
 
  610   NS_LOG_LOGIC (
"Forwarding state: " << interface->IsForwarding ());
 
  611   return interface->IsForwarding ();
 
  618   Ptr<Ipv4Interface> 
interface = GetInterface (i);
 
  619   interface->SetForwarding (val);
 
  623 Ipv4L3ClickProtocol::SetPromisc (uint32_t i)
 
  628   Ptr<Node> node = GetObject<Node> ();
 
  630   node->RegisterProtocolHandler (
MakeCallback (&Ipv4L3ClickProtocol::Receive, 
this),
 
  638   Ptr<Node> node = GetObject<Node> ();
 
  639   node->RegisterProtocolHandler (
MakeCallback (&Ipv4L3ClickProtocol::Receive, 
this),
 
  640                                  Ipv4L3ClickProtocol::PROT_NUMBER, device);
 
  641   node->RegisterProtocolHandler (
MakeCallback (&Ipv4L3ClickProtocol::Receive, 
this),
 
  644   Ptr<Ipv4Interface> 
interface = 
CreateObject<Ipv4Interface> ();
 
  645   interface->SetNode (m_node);
 
  646   interface->SetDevice (device);
 
  647   interface->SetForwarding (m_ipForward);
 
  648   return AddIpv4Interface (interface);
 
  652 Ipv4L3ClickProtocol::AddIpv4Interface (Ptr<Ipv4Interface>interface)
 
  655   uint32_t index = m_interfaces.size ();
 
  656   m_interfaces.push_back (interface);
 
  657   m_reverseInterfacesContainer[interface->GetDevice ()] = index;
 
  665 Ipv4L3ClickProtocol::BuildHeader (
 
  667   Ipv4Address destination,
 
  669   uint16_t payloadSize,
 
  675   ipHeader.SetSource (source);
 
  676   ipHeader.SetDestination (destination);
 
  677   ipHeader.SetProtocol (protocol);
 
  678   ipHeader.SetPayloadSize (payloadSize);
 
  679   ipHeader.SetTtl (ttl);
 
  680   if (mayFragment == 
true)
 
  682       ipHeader.SetMayFragment ();
 
  683       ipHeader.SetIdentification (m_identification);
 
  688       ipHeader.SetDontFragment ();
 
  690       ipHeader.SetIdentification (m_identification);
 
  695       ipHeader.EnableChecksum ();
 
  703                            Ipv4Address destination,
 
  705                            Ptr<Ipv4Route> route)
 
  707   NS_LOG_FUNCTION (
this << packet << source << destination << uint32_t (protocol) << route);
 
  710   bool mayFragment = 
true;
 
  711   uint8_t ttl = m_defaultTtl;
 
  713   bool found = packet->RemovePacketTag (tag);
 
  719   ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, mayFragment);
 
  720   Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (m_routingProtocol);
 
  723       ipHeader.EnableChecksum ();
 
  725   packet->AddHeader (ipHeader);
 
  726   click->Send (packet->Copy (), source, destination);
 
  733                                      Ptr<Ipv4Route> route)
 
  737   Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (m_routingProtocol);
 
  740       ipHeader.EnableChecksum ();
 
  742   packet->AddHeader (ipHeader);
 
  743   click->Send (packet->Copy (), ipHeader.GetSource (), ipHeader.GetDestination ());
 
  747 Ipv4L3ClickProtocol::SendDown (Ptr<Packet> p, 
int ifid)
 
  758   EthernetHeader header;
 
  759   p->RemoveHeader (header);
 
  763   if (header.GetLengthType () <= 1500)
 
  766       p->RemoveHeader (llc);
 
  767       protocol = llc.GetType ();
 
  771       protocol = header.GetLengthType ();
 
  776   netdev->Send (p, header.GetDestination (), protocol);
 
  780 Ipv4L3ClickProtocol::Receive ( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, 
const Address &from,
 
  785   NS_LOG_LOGIC (
"Packet from " << from << 
" received on node " <<
 
  789   if (protocol == Ipv4L3ClickProtocol::PROT_NUMBER && m_sockets.size () > 0)
 
  791       Ptr<Packet> packetForRawSocket = p->Copy ();
 
  792       int32_t 
interface = GetInterfaceForDevice(device);
 
  793       NS_ASSERT_MSG (interface != -1, 
"Received a packet from an interface that is not known to IPv4");
 
  794       Ptr<Ipv4Interface> ipv4Interface = m_interfaces[interface];
 
  795       if (!ipv4Interface->IsUp ())
 
  797           NS_LOG_LOGIC (
"Dropping received packet -- interface is down");
 
  804           ipHeader.EnableChecksum ();
 
  806       packetForRawSocket->RemoveHeader (ipHeader);
 
  809       for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
 
  812           Ptr<Ipv4RawSocketImpl> socket = *i;
 
  813           socket->ForwardUp (packetForRawSocket, ipHeader, ipv4Interface);
 
  817   Ptr<Packet> packet = p->Copy ();
 
  824   hdr.SetLengthType (protocol);
 
  825   packet->AddHeader (hdr);
 
  832 Ipv4L3ClickProtocol::LocalDeliver (Ptr<const Packet> packet, Ipv4Header 
const&ip, uint32_t iif)
 
  835   Ptr<Packet> p = packet->Copy (); 
 
  837   m_localDeliverTrace (ip, packet, iif);
 
  839   Ptr<IpL4Protocol> protocol = 
GetProtocol (ip.GetProtocol ());
 
  844       Ptr<Packet> copy = p->Copy ();
 
  846         protocol->Receive (p, ip, GetInterface (iif));
 
  856           if (ip.GetDestination ().IsBroadcast () == 
true 
  857               || ip.GetDestination ().IsMulticast () == 
true)
 
  862           bool subnetDirected = 
false;
 
  865               Ipv4InterfaceAddress addr = 
GetAddress (iif, i);
 
  866               if (addr.GetLocal ().CombineMask (addr.GetMask ()) == ip.GetDestination ().CombineMask (addr.GetMask ())
 
  867                   && ip.GetDestination ().IsSubnetDirectedBroadcast (addr.GetMask ()))
 
  869                   subnetDirected = 
true;
 
  872           if (subnetDirected == 
false)
 
  874               GetIcmp ()->SendDestUnreachPort (ip, copy);
 
  880 Ptr<Icmpv4L4Protocol>
 
  881 Ipv4L3ClickProtocol::GetIcmp (
void)
 const 
  886       return prot->GetObject<Icmpv4L4Protocol> ();
 
  898   L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), -1);
 
  899   if (m_protocols.find (key) != m_protocols.end ())
 
  901       NS_LOG_WARN (
"Overwriting default protocol " << 
int(protocol->GetProtocolNumber ()));
 
  903   m_protocols[key] = protocol;
 
  911   L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), interfaceIndex);
 
  912   if (m_protocols.find (key) != m_protocols.end ())
 
  914       NS_LOG_WARN (
"Overwriting protocol " << 
int(protocol->GetProtocolNumber ()) << 
" on interface " << 
int(interfaceIndex));
 
  916   m_protocols[key] = protocol;
 
  924   L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), -1);
 
  925   L4List_t::iterator iter = m_protocols.find (key);
 
  926   if (iter == m_protocols.end ())
 
  928       NS_LOG_WARN (
"Trying to remove an non-existent default protocol " << 
int(protocol->GetProtocolNumber ()));
 
  932       m_protocols.erase (key);
 
  941   L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), interfaceIndex);
 
  942   L4List_t::iterator iter = m_protocols.find (key);
 
  943   if (iter == m_protocols.end ())
 
  945       NS_LOG_WARN (
"Trying to remove an non-existent protocol " << 
int(protocol->GetProtocolNumber ()) << 
" on interface " << 
int(interfaceIndex));
 
  949       m_protocols.erase (key);
 
  967   L4List_t::const_iterator i;
 
  968   if (interfaceIndex >= 0)
 
  971       key = std::make_pair (protocolNumber, interfaceIndex);
 
  972       i = m_protocols.find (key);
 
  973       if (i != m_protocols.end ())
 
  979   key = std::make_pair (protocolNumber, -1);
 
  980   i = m_protocols.find (key);
 
  981   if (i != m_protocols.end ())