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 ()
78 Ipv4L3ClickProtocol::DoDispose (
void)
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;
101 Ipv4L3ClickProtocol::NotifyNewAggregate ()
105 Ptr<Node>node = this->GetObject<Node> ();
110 this->SetNode (node);
113 Ipv4::NotifyNewAggregate ();
117 Ipv4L3ClickProtocol::SetRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol)
120 m_routingProtocol = routingProtocol;
121 m_routingProtocol->SetIpv4 (
this);
125 Ptr<Ipv4RoutingProtocol>
126 Ipv4L3ClickProtocol::GetRoutingProtocol (
void)
const
128 return m_routingProtocol;
132 Ipv4L3ClickProtocol::GetInterface (uint32_t index)
const
135 if (index < m_interfaces.size ())
137 return m_interfaces[index];
143 Ipv4L3ClickProtocol::GetNInterfaces (
void)
const
146 return m_interfaces.size ();
150 Ipv4L3ClickProtocol::GetInterfaceForAddress (
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)
173 Ipv4L3ClickProtocol::GetInterfaceForPrefix (
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))
197 Ipv4L3ClickProtocol::GetInterfaceForDevice (
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;
212 Ipv4L3ClickProtocol::IsDestinationAddress (Ipv4Address
address, uint32_t iif)
const
217 for (uint32_t i = 0; i < GetNAddresses (iif); i++)
219 Ipv4InterfaceAddress iaddr = GetAddress (iif, i);
220 if (
address == iaddr.GetLocal ())
225 if (
address == iaddr.GetBroadcast ())
235 if (MulticastCheckGroup (iif,
address ))
250 if (GetWeakEsModel ())
252 for (uint32_t j = 0; j < GetNInterfaces (); j++)
254 if (j == uint32_t (iif))
258 for (uint32_t i = 0; i < GetNAddresses (j); i++)
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)");
279 Ipv4L3ClickProtocol::SetIpForward (
bool forward)
282 m_ipForward = forward;
283 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
285 (*i)->SetForwarding (forward);
290 Ipv4L3ClickProtocol::GetIpForward (
void)
const
296 Ipv4L3ClickProtocol::SetWeakEsModel (
bool model)
298 m_weakEsModel = model;
302 Ipv4L3ClickProtocol::GetWeakEsModel (
void)
const
304 return m_weakEsModel;
308 Ipv4L3ClickProtocol::GetNetDevice (uint32_t i)
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);
343 Ipv4InterfaceAddress ifaceAddr = Ipv4InterfaceAddress (Ipv4Address::GetLoopback (), Ipv4Mask::GetLoopback ());
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);
357 Ipv4L3ClickProtocol::CreateRawSocket (
void)
360 Ptr<Ipv4RawSocketImpl> socket = CreateObject<Ipv4RawSocketImpl> ();
361 socket->SetNode (m_node);
362 m_sockets.push_back (socket);
366 Ipv4L3ClickProtocol::DeleteRawSocket (Ptr<Socket> socket)
369 for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
382 Ipv4L3ClickProtocol::SetNode (Ptr<Node> node)
390 Ipv4L3ClickProtocol::AddAddress (uint32_t i, Ipv4InterfaceAddress
address)
393 Ptr<Ipv4Interface>
interface = GetInterface (i);
394 bool retVal = interface->AddAddress (
address);
395 if (m_routingProtocol != 0)
397 m_routingProtocol->NotifyAddAddress (i,
address);
403 Ipv4L3ClickProtocol::GetAddress (uint32_t interfaceIndex, uint32_t addressIndex)
const
406 Ptr<Ipv4Interface>
interface = GetInterface (interfaceIndex);
407 return interface->GetAddress (addressIndex);
411 Ipv4L3ClickProtocol::GetNAddresses (uint32_t interface)
const
414 Ptr<Ipv4Interface> iface = GetInterface (interface);
415 return iface->GetNAddresses ();
419 Ipv4L3ClickProtocol::RemoveAddress (uint32_t i, uint32_t addressIndex)
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);
436 Ipv4L3ClickProtocol::RemoveAddress (uint32_t i, Ipv4Address
address)
440 if (
address == Ipv4Address::GetLoopback())
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);
459 Ipv4L3ClickProtocol::SourceAddressSelection (uint32_t interfaceIdx, Ipv4Address dest)
462 if (GetNAddresses (interfaceIdx) == 1)
464 return GetAddress (interfaceIdx, 0).GetLocal ();
470 Ipv4Address candidate = GetAddress (interfaceIdx, 0).GetLocal ();
471 for (uint32_t i = 0; i < GetNAddresses (interfaceIdx); i++)
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 ();
486 Ipv4L3ClickProtocol::SelectSourceAddress (Ptr<const NetDevice> device,
487 Ipv4Address dst, Ipv4InterfaceAddress::InterfaceAddressScope_e scope)
490 Ipv4Address addr (
"0.0.0.0");
491 Ipv4InterfaceAddress iaddr;
496 int32_t i = GetInterfaceForDevice (device);
498 for (uint32_t j = 0; j < GetNAddresses (i); j++)
500 iaddr = GetAddress (i, j);
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 ();
526 for (uint32_t i = 0; i < GetNInterfaces (); i++)
528 for (uint32_t j = 0; j < GetNAddresses (i); j++)
530 iaddr = GetAddress (i, j);
531 if (iaddr.IsSecondary ())
535 if (iaddr.GetScope () != Ipv4InterfaceAddress::LINK
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");
548 Ipv4L3ClickProtocol::SetMetric (uint32_t i, uint16_t metric)
551 Ptr<Ipv4Interface>
interface = GetInterface (i);
552 interface->SetMetric (metric);
556 Ipv4L3ClickProtocol::GetMetric (uint32_t i)
const
559 Ptr<Ipv4Interface>
interface = GetInterface (i);
560 return interface->GetMetric ();
564 Ipv4L3ClickProtocol::GetMtu (uint32_t i)
const
567 Ptr<Ipv4Interface>
interface = GetInterface (i);
568 return interface->GetDevice ()->GetMtu ();
572 Ipv4L3ClickProtocol::IsUp (uint32_t i)
const
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);
593 Ipv4L3ClickProtocol::SetDown (uint32_t ifaceIndex)
596 Ptr<Ipv4Interface>
interface = GetInterface (ifaceIndex);
597 interface->SetDown ();
599 if (m_routingProtocol != 0)
601 m_routingProtocol->NotifyInterfaceDown (ifaceIndex);
606 Ipv4L3ClickProtocol::IsForwarding (uint32_t i)
const
609 Ptr<Ipv4Interface>
interface = GetInterface (i);
610 NS_LOG_LOGIC (
"Forwarding state: " << interface->IsForwarding ());
611 return interface->IsForwarding ();
615 Ipv4L3ClickProtocol::SetForwarding (uint32_t i,
bool val)
618 Ptr<Ipv4Interface>
interface = GetInterface (i);
619 interface->SetForwarding (val);
623 Ipv4L3ClickProtocol::SetPromisc (uint32_t i)
626 Ptr<NetDevice> netdev = GetNetDevice (i);
628 Ptr<Node> node = GetObject<Node> ();
630 node->RegisterProtocolHandler (
MakeCallback (&Ipv4L3ClickProtocol::Receive,
this),
635 Ipv4L3ClickProtocol::AddInterface (Ptr<NetDevice> device)
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),
642 ArpL3Protocol::PROT_NUMBER, device);
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);
693 if (Node::ChecksumEnabled ())
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);
721 if (Node::ChecksumEnabled ())
723 ipHeader.EnableChecksum ();
725 packet->AddHeader (ipHeader);
726 click->Send (packet->Copy (), source, destination);
731 Ipv4L3ClickProtocol::SendWithHeader (Ptr<Packet> packet,
733 Ptr<Ipv4Route> route)
737 Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (m_routingProtocol);
738 if (Node::ChecksumEnabled ())
740 ipHeader.EnableChecksum ();
742 packet->AddHeader (ipHeader);
743 click->Send (packet->Copy (), ipHeader.GetSource (), ipHeader.GetDestination ());
747 Ipv4L3ClickProtocol::SendDown (Ptr<Packet> p,
int ifid)
756 Ptr<NetDevice> netdev = GetNetDevice (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,
781 const Address &to, NetDevice::PacketType packetType)
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");
802 if (Node::ChecksumEnabled ())
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 ();
822 hdr.SetSource (Mac48Address::ConvertFrom (from));
823 hdr.SetDestination (Mac48Address::ConvertFrom (to));
824 hdr.SetLengthType (protocol);
825 packet->AddHeader (hdr);
827 Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (GetRoutingProtocol ());
828 click->Receive (packet->Copy (), Mac48Address::ConvertFrom (device->GetAddress ()), Mac48Address::ConvertFrom (to));
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 ();
845 enum IpL4Protocol::RxStatus status =
846 protocol->Receive (p, ip, GetInterface (iif));
849 case IpL4Protocol::RX_OK:
851 case IpL4Protocol::RX_ENDPOINT_CLOSED:
853 case IpL4Protocol::RX_CSUM_FAILED:
855 case IpL4Protocol::RX_ENDPOINT_UNREACH:
856 if (ip.GetDestination ().IsBroadcast () ==
true
857 || ip.GetDestination ().IsMulticast () ==
true)
862 bool subnetDirected =
false;
863 for (uint32_t i = 0; i < GetNAddresses (iif); i++)
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
883 Ptr<IpL4Protocol> prot = GetProtocol (Icmpv4L4Protocol::GetStaticProtocolNumber ());
886 return prot->GetObject<Icmpv4L4Protocol> ();
895 Ipv4L3ClickProtocol::Insert (Ptr<IpL4Protocol> protocol)
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;
907 Ipv4L3ClickProtocol::Insert (Ptr<IpL4Protocol> protocol, uint32_t interfaceIndex)
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;
920 Ipv4L3ClickProtocol::Remove (Ptr<IpL4Protocol> 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);
937 Ipv4L3ClickProtocol::Remove (Ptr<IpL4Protocol> protocol, uint32_t interfaceIndex)
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);
954 Ipv4L3ClickProtocol::GetProtocol (
int protocolNumber)
const
958 return GetProtocol (protocolNumber, -1);
962 Ipv4L3ClickProtocol::GetProtocol (
int protocolNumber, int32_t interfaceIndex)
const
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 ())
static TypeId GetTypeId(void)
Get the type ID.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
static void Send(Ptr< NetDevice > dev, int level, std::string emuMode)
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
ObjectPtrContainerValue ObjectVectorValue
ObjectVectorValue is an alias for ObjectPtrContainerValue.
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
@ key
the parser read a key of a value in an object
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
void SetUp(char *deviceName)