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 .AddAttribute (
"DefaultTtl",
"The TTL value set by default on all outgoing packets generated on this node.",
57 MakeUintegerAccessor (&Ipv4L3ClickProtocol::m_defaultTtl),
58 MakeUintegerChecker<uint8_t> ())
59 .AddAttribute (
"InterfaceList",
"The set of Ipv4 interfaces associated to this Ipv4 stack.",
62 MakeObjectVectorChecker<Ipv4Interface> ())
67 Ipv4L3ClickProtocol::Ipv4L3ClickProtocol ()
68 : m_identification (0)
72 Ipv4L3ClickProtocol::~Ipv4L3ClickProtocol ()
80 for (L4List_t::iterator i = m_protocols.begin (); i != m_protocols.end (); ++i)
86 for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); ++i)
90 m_interfaces.clear ();
93 m_routingProtocol = 0;
102 Ptr<Node>node = this->GetObject<Node> ();
107 this->SetNode (node);
117 m_routingProtocol = routingProtocol;
118 m_routingProtocol->SetIpv4 (
this);
122 Ptr<Ipv4RoutingProtocol>
125 return m_routingProtocol;
129 Ipv4L3ClickProtocol::GetInterface (uint32_t index)
const
132 if (index < m_interfaces.size ())
134 return m_interfaces[index];
143 return m_interfaces.size ();
148 Ipv4Address address)
const
152 int32_t
interface = 0;
153 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
154 i != m_interfaces.end ();
157 for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
159 if ((*i)->GetAddress (j).GetLocal () == address)
176 int32_t
interface = 0;
177 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
178 i != m_interfaces.end ();
181 for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
183 if ((*i)->GetAddress (j).GetLocal ().CombineMask (mask) == address.CombineMask (mask))
195 Ptr<const NetDevice> device)
const
199 int32_t
interface = 0;
200 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
201 i != m_interfaces.end ();
204 if ((*i)->GetDevice () == device)
221 Ipv4InterfaceAddress iaddr =
GetAddress (iif, i);
222 if (address == iaddr.GetLocal ())
224 NS_LOG_LOGIC (
"For me (destination " << address <<
" match)");
227 if (address == iaddr.GetBroadcast ())
234 if (address.IsMulticast ())
237 if (MulticastCheckGroup (iif, address ))
246 if (address.IsBroadcast ())
256 if (j == uint32_t (iif))
262 Ipv4InterfaceAddress iaddr =
GetAddress (j, i);
263 if (address == iaddr.GetLocal ())
265 NS_LOG_LOGIC (
"For me (destination " << address <<
" match) on another interface");
269 if (address == iaddr.GetBroadcast ())
271 NS_LOG_LOGIC (
"For me (interface broadcast address on another interface)");
284 m_ipForward = forward;
285 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
287 (*i)->SetForwarding (forward);
300 m_weakEsModel = model;
306 return m_weakEsModel;
313 return GetInterface (i)->GetDevice ();
317 Ipv4L3ClickProtocol::SetDefaultTtl (uint8_t ttl)
324 Ipv4L3ClickProtocol::SetupLoopback (
void)
328 Ptr<Ipv4Interface>
interface =
CreateObject<Ipv4Interface> ();
329 Ptr<LoopbackNetDevice> device = 0;
331 for (uint32_t i = 0; i < m_node->GetNDevices (); i++)
333 if (device = DynamicCast<LoopbackNetDevice> (m_node->GetDevice (i)))
340 device = CreateObject<LoopbackNetDevice> ();
341 m_node->AddDevice (device);
343 interface->SetDevice (device);
344 interface->SetNode (m_node);
346 interface->AddAddress (ifaceAddr);
347 uint32_t index = AddIpv4Interface (interface);
348 Ptr<Node> node = GetObject<Node> ();
349 node->RegisterProtocolHandler (
MakeCallback (&Ipv4L3ClickProtocol::Receive,
this),
350 Ipv4L3ClickProtocol::PROT_NUMBER, device);
352 if (m_routingProtocol != 0)
354 m_routingProtocol->NotifyInterfaceUp (index);
362 Ptr<Ipv4RawSocketImpl> socket = CreateObject<Ipv4RawSocketImpl> ();
363 socket->SetNode (m_node);
364 m_sockets.push_back (socket);
371 for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
384 Ipv4L3ClickProtocol::SetNode (Ptr<Node> node)
395 Ptr<Ipv4Interface>
interface = GetInterface (i);
396 bool retVal = interface->AddAddress (address);
397 if (m_routingProtocol != 0)
399 m_routingProtocol->NotifyAddAddress (i, address);
408 Ptr<Ipv4Interface>
interface = GetInterface (interfaceIndex);
409 return interface->GetAddress (addressIndex);
416 Ptr<Ipv4Interface> iface = GetInterface (interface);
417 return iface->GetNAddresses ();
424 Ptr<Ipv4Interface>
interface = GetInterface (i);
425 Ipv4InterfaceAddress address = interface->RemoveAddress (addressIndex);
426 if (address != Ipv4InterfaceAddress ())
428 if (m_routingProtocol != 0)
430 m_routingProtocol->NotifyRemoveAddress (i, address);
442 Ipv4Address addr (
"0.0.0.0");
443 Ipv4InterfaceAddress iaddr;
453 if (iaddr.IsSecondary ())
457 if (iaddr.GetScope () > scope)
461 if (dst.CombineMask (iaddr.GetMask ()) == iaddr.GetLocal ().CombineMask (iaddr.GetMask ()) )
463 return iaddr.GetLocal ();
467 addr = iaddr.GetLocal ();
483 if (iaddr.IsSecondary ())
488 && iaddr.GetScope () <= scope)
490 return iaddr.GetLocal ();
494 NS_LOG_WARN (
"Could not find source address for " << dst <<
" and scope "
495 << scope <<
", returning 0");
503 Ptr<Ipv4Interface>
interface = GetInterface (i);
504 interface->SetMetric (metric);
511 Ptr<Ipv4Interface>
interface = GetInterface (i);
512 return interface->GetMetric ();
519 Ptr<Ipv4Interface>
interface = GetInterface (i);
520 return interface->GetDevice ()->GetMtu ();
527 Ptr<Ipv4Interface>
interface = GetInterface (i);
528 return interface->IsUp ();
535 Ptr<Ipv4Interface>
interface = GetInterface (i);
538 if (m_routingProtocol != 0)
540 m_routingProtocol->NotifyInterfaceUp (i);
548 Ptr<Ipv4Interface>
interface = GetInterface (ifaceIndex);
549 interface->SetDown ();
551 if (m_routingProtocol != 0)
553 m_routingProtocol->NotifyInterfaceDown (ifaceIndex);
561 Ptr<Ipv4Interface>
interface = GetInterface (i);
562 NS_LOG_LOGIC (
"Forwarding state: " << interface->IsForwarding ());
563 return interface->IsForwarding ();
570 Ptr<Ipv4Interface>
interface = GetInterface (i);
571 interface->SetForwarding (val);
575 Ipv4L3ClickProtocol::SetPromisc (uint32_t i)
580 Ptr<Node> node = GetObject<Node> ();
582 node->RegisterProtocolHandler (
MakeCallback (&Ipv4L3ClickProtocol::Receive,
this),
590 Ptr<Node> node = GetObject<Node> ();
591 node->RegisterProtocolHandler (
MakeCallback (&Ipv4L3ClickProtocol::Receive,
this),
592 Ipv4L3ClickProtocol::PROT_NUMBER, device);
593 node->RegisterProtocolHandler (
MakeCallback (&Ipv4L3ClickProtocol::Receive,
this),
596 Ptr<Ipv4Interface>
interface =
CreateObject<Ipv4Interface> ();
597 interface->SetNode (m_node);
598 interface->SetDevice (device);
599 interface->SetForwarding (m_ipForward);
600 return AddIpv4Interface (interface);
604 Ipv4L3ClickProtocol::AddIpv4Interface (Ptr<Ipv4Interface>interface)
607 uint32_t index = m_interfaces.size ();
608 m_interfaces.push_back (interface);
616 Ipv4L3ClickProtocol::BuildHeader (
618 Ipv4Address destination,
620 uint16_t payloadSize,
626 ipHeader.SetSource (source);
627 ipHeader.SetDestination (destination);
628 ipHeader.SetProtocol (protocol);
629 ipHeader.SetPayloadSize (payloadSize);
630 ipHeader.SetTtl (ttl);
631 if (mayFragment ==
true)
633 ipHeader.SetMayFragment ();
634 ipHeader.SetIdentification (m_identification);
639 ipHeader.SetDontFragment ();
641 ipHeader.SetIdentification (m_identification);
646 ipHeader.EnableChecksum ();
654 Ipv4Address destination,
656 Ptr<Ipv4Route> route)
658 NS_LOG_FUNCTION (
this << packet << source << destination << uint32_t (protocol) << route);
661 bool mayFragment =
true;
662 uint8_t ttl = m_defaultTtl;
664 bool found = packet->RemovePacketTag (tag);
670 ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, mayFragment);
671 Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (m_routingProtocol);
674 ipHeader.EnableChecksum ();
676 packet->AddHeader (ipHeader);
677 click->Send (packet->Copy (), source, destination);
684 Ptr<Ipv4Route> route)
688 Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (m_routingProtocol);
691 ipHeader.EnableChecksum ();
693 packet->AddHeader (ipHeader);
694 click->Send (packet->Copy (), ipHeader.GetSource (), ipHeader.GetDestination ());
698 Ipv4L3ClickProtocol::SendDown (Ptr<Packet> p,
int ifid)
709 EthernetHeader header;
710 p->RemoveHeader (header);
714 if (header.GetLengthType () <= 1500)
717 p->RemoveHeader (llc);
718 protocol = llc.GetType ();
722 protocol = header.GetLengthType ();
727 netdev->Send (p, header.GetDestination (), protocol);
731 Ipv4L3ClickProtocol::Receive ( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol,
const Address &from,
737 if (protocol == Ipv4L3ClickProtocol::PROT_NUMBER && m_sockets.size () > 0)
739 Ptr<Packet> packetForRawSocket = p->Copy ();
740 uint32_t
interface = 0;
741 Ptr<Ipv4Interface> ipv4Interface;
742 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
743 i != m_interfaces.end ();
747 if (ipv4Interface->GetDevice () == device)
749 if (ipv4Interface->IsUp ())
755 NS_LOG_LOGIC (
"Dropping received packet -- interface is down");
764 ipHeader.EnableChecksum ();
766 packetForRawSocket->RemoveHeader (ipHeader);
769 for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
772 Ptr<Ipv4RawSocketImpl> socket = *i;
773 socket->ForwardUp (packetForRawSocket, ipHeader, ipv4Interface);
777 Ptr<Packet> packet = p->Copy ();
784 hdr.SetLengthType (protocol);
785 packet->AddHeader (hdr);
792 Ipv4L3ClickProtocol::LocalDeliver (Ptr<const Packet> packet, Ipv4Header
const&ip, uint32_t iif)
795 Ptr<Packet> p = packet->Copy ();
797 m_localDeliverTrace (ip, packet, iif);
799 Ptr<IpL4Protocol> protocol =
GetProtocol (ip.GetProtocol ());
804 Ptr<Packet> copy = p->Copy ();
806 protocol->Receive (p, ip, GetInterface (iif));
816 if (ip.GetDestination ().IsBroadcast () ==
true
817 || ip.GetDestination ().IsMulticast () ==
true)
822 bool subnetDirected =
false;
825 Ipv4InterfaceAddress addr =
GetAddress (iif, i);
826 if (addr.GetLocal ().CombineMask (addr.GetMask ()) == ip.GetDestination ().CombineMask (addr.GetMask ())
827 && ip.GetDestination ().IsSubnetDirectedBroadcast (addr.GetMask ()))
829 subnetDirected =
true;
832 if (subnetDirected ==
false)
834 GetIcmp ()->SendDestUnreachPort (ip, copy);
840 Ptr<Icmpv4L4Protocol>
841 Ipv4L3ClickProtocol::GetIcmp (
void)
const
846 return prot->GetObject<Icmpv4L4Protocol> ();
857 m_protocols.push_back (protocol);
863 for (L4List_t::const_iterator i = m_protocols.begin (); i != m_protocols.end (); ++i)
865 if ((*i)->GetProtocolNumber () == protocolNumber)