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 ();
94 m_routingProtocol = 0;
103 Ptr<Node>node = this->GetObject<Node> ();
108 this->SetNode (node);
118 m_routingProtocol = routingProtocol;
119 m_routingProtocol->SetIpv4 (
this);
123 Ptr<Ipv4RoutingProtocol>
126 return m_routingProtocol;
130 Ipv4L3ClickProtocol::GetInterface (uint32_t index)
const
133 if (index < m_interfaces.size ())
135 return m_interfaces[index];
144 return m_interfaces.size ();
153 int32_t
interface = 0;
154 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
155 i != m_interfaces.end ();
158 for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
160 if ((*i)->GetAddress (j).GetLocal () ==
address)
177 int32_t
interface = 0;
178 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
179 i != m_interfaces.end ();
182 for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
184 if ((*i)->GetAddress (j).GetLocal ().CombineMask (mask) == address.CombineMask (mask))
196 Ptr<const NetDevice> device)
const
200 int32_t
interface = 0;
201 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
202 i != m_interfaces.end ();
205 if ((*i)->GetDevice () == device)
222 Ipv4InterfaceAddress iaddr =
GetAddress (iif, i);
223 if (address == iaddr.GetLocal ())
225 NS_LOG_LOGIC (
"For me (destination " << address <<
" match)");
228 if (address == iaddr.GetBroadcast ())
235 if (address.IsMulticast ())
238 if (MulticastCheckGroup (iif, address ))
247 if (address.IsBroadcast ())
257 if (j == uint32_t (iif))
263 Ipv4InterfaceAddress iaddr =
GetAddress (j, i);
264 if (address == iaddr.GetLocal ())
266 NS_LOG_LOGIC (
"For me (destination " << address <<
" match) on another interface");
270 if (address == iaddr.GetBroadcast ())
272 NS_LOG_LOGIC (
"For me (interface broadcast address on another interface)");
285 m_ipForward = forward;
286 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
288 (*i)->SetForwarding (forward);
301 m_weakEsModel = model;
307 return m_weakEsModel;
314 return GetInterface (i)->GetDevice ();
318 Ipv4L3ClickProtocol::SetDefaultTtl (uint8_t ttl)
325 Ipv4L3ClickProtocol::SetupLoopback (
void)
329 Ptr<Ipv4Interface>
interface =
CreateObject<Ipv4Interface> ();
330 Ptr<LoopbackNetDevice> device = 0;
332 for (uint32_t i = 0; i < m_node->GetNDevices (); i++)
334 if ((device = DynamicCast<LoopbackNetDevice> (m_node->GetDevice (i))))
341 device = CreateObject<LoopbackNetDevice> ();
342 m_node->AddDevice (device);
344 interface->SetDevice (device);
345 interface->SetNode (m_node);
347 interface->AddAddress (ifaceAddr);
348 uint32_t index = AddIpv4Interface (interface);
349 Ptr<Node> node = GetObject<Node> ();
350 node->RegisterProtocolHandler (
MakeCallback (&Ipv4L3ClickProtocol::Receive,
this),
351 Ipv4L3ClickProtocol::PROT_NUMBER, device);
353 if (m_routingProtocol != 0)
355 m_routingProtocol->NotifyInterfaceUp (index);
363 Ptr<Ipv4RawSocketImpl> socket = CreateObject<Ipv4RawSocketImpl> ();
364 socket->SetNode (m_node);
365 m_sockets.push_back (socket);
372 for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
385 Ipv4L3ClickProtocol::SetNode (Ptr<Node> node)
396 Ptr<Ipv4Interface>
interface = GetInterface (i);
397 bool retVal = interface->AddAddress (address);
398 if (m_routingProtocol != 0)
400 m_routingProtocol->NotifyAddAddress (i, address);
409 Ptr<Ipv4Interface>
interface = GetInterface (interfaceIndex);
410 return interface->GetAddress (addressIndex);
417 Ptr<Ipv4Interface> iface = GetInterface (interface);
418 return iface->GetNAddresses ();
425 Ptr<Ipv4Interface>
interface = GetInterface (i);
426 Ipv4InterfaceAddress address = interface->RemoveAddress (addressIndex);
427 if (address != Ipv4InterfaceAddress ())
429 if (m_routingProtocol != 0)
431 m_routingProtocol->NotifyRemoveAddress (i, address);
448 Ptr<Ipv4Interface>
interface = GetInterface (i);
449 Ipv4InterfaceAddress ifAddr = interface->RemoveAddress (address);
450 if (ifAddr != Ipv4InterfaceAddress ())
452 if (m_routingProtocol != 0)
454 m_routingProtocol->NotifyRemoveAddress (i, ifAddr);
466 Ipv4Address addr (
"0.0.0.0");
467 Ipv4InterfaceAddress iaddr;
477 if (iaddr.IsSecondary ())
481 if (iaddr.GetScope () > scope)
485 if (dst.CombineMask (iaddr.GetMask ()) == iaddr.GetLocal ().CombineMask (iaddr.GetMask ()) )
487 return iaddr.GetLocal ();
491 addr = iaddr.GetLocal ();
507 if (iaddr.IsSecondary ())
512 && iaddr.GetScope () <= scope)
514 return iaddr.GetLocal ();
518 NS_LOG_WARN (
"Could not find source address for " << dst <<
" and scope "
519 << scope <<
", returning 0");
527 Ptr<Ipv4Interface>
interface = GetInterface (i);
528 interface->SetMetric (metric);
535 Ptr<Ipv4Interface>
interface = GetInterface (i);
536 return interface->GetMetric ();
543 Ptr<Ipv4Interface>
interface = GetInterface (i);
544 return interface->GetDevice ()->GetMtu ();
551 Ptr<Ipv4Interface>
interface = GetInterface (i);
552 return interface->IsUp ();
559 Ptr<Ipv4Interface>
interface = GetInterface (i);
562 if (m_routingProtocol != 0)
564 m_routingProtocol->NotifyInterfaceUp (i);
572 Ptr<Ipv4Interface>
interface = GetInterface (ifaceIndex);
573 interface->SetDown ();
575 if (m_routingProtocol != 0)
577 m_routingProtocol->NotifyInterfaceDown (ifaceIndex);
585 Ptr<Ipv4Interface>
interface = GetInterface (i);
586 NS_LOG_LOGIC (
"Forwarding state: " << interface->IsForwarding ());
587 return interface->IsForwarding ();
594 Ptr<Ipv4Interface>
interface = GetInterface (i);
595 interface->SetForwarding (val);
599 Ipv4L3ClickProtocol::SetPromisc (uint32_t i)
604 Ptr<Node> node = GetObject<Node> ();
606 node->RegisterProtocolHandler (
MakeCallback (&Ipv4L3ClickProtocol::Receive,
this),
614 Ptr<Node> node = GetObject<Node> ();
615 node->RegisterProtocolHandler (
MakeCallback (&Ipv4L3ClickProtocol::Receive,
this),
616 Ipv4L3ClickProtocol::PROT_NUMBER, device);
617 node->RegisterProtocolHandler (
MakeCallback (&Ipv4L3ClickProtocol::Receive,
this),
620 Ptr<Ipv4Interface>
interface =
CreateObject<Ipv4Interface> ();
621 interface->SetNode (m_node);
622 interface->SetDevice (device);
623 interface->SetForwarding (m_ipForward);
624 return AddIpv4Interface (interface);
628 Ipv4L3ClickProtocol::AddIpv4Interface (Ptr<Ipv4Interface>interface)
631 uint32_t index = m_interfaces.size ();
632 m_interfaces.push_back (interface);
640 Ipv4L3ClickProtocol::BuildHeader (
642 Ipv4Address destination,
644 uint16_t payloadSize,
650 ipHeader.SetSource (source);
651 ipHeader.SetDestination (destination);
652 ipHeader.SetProtocol (protocol);
653 ipHeader.SetPayloadSize (payloadSize);
654 ipHeader.SetTtl (ttl);
655 if (mayFragment ==
true)
657 ipHeader.SetMayFragment ();
658 ipHeader.SetIdentification (m_identification);
663 ipHeader.SetDontFragment ();
665 ipHeader.SetIdentification (m_identification);
670 ipHeader.EnableChecksum ();
678 Ipv4Address destination,
680 Ptr<Ipv4Route> route)
682 NS_LOG_FUNCTION (
this << packet << source << destination << uint32_t (protocol) << route);
685 bool mayFragment =
true;
686 uint8_t ttl = m_defaultTtl;
688 bool found = packet->RemovePacketTag (tag);
694 ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, mayFragment);
695 Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (m_routingProtocol);
698 ipHeader.EnableChecksum ();
700 packet->AddHeader (ipHeader);
701 click->Send (packet->Copy (), source, destination);
708 Ptr<Ipv4Route> route)
712 Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (m_routingProtocol);
715 ipHeader.EnableChecksum ();
717 packet->AddHeader (ipHeader);
718 click->Send (packet->Copy (), ipHeader.GetSource (), ipHeader.GetDestination ());
722 Ipv4L3ClickProtocol::SendDown (Ptr<Packet> p,
int ifid)
733 EthernetHeader header;
734 p->RemoveHeader (header);
738 if (header.GetLengthType () <= 1500)
741 p->RemoveHeader (llc);
742 protocol = llc.GetType ();
746 protocol = header.GetLengthType ();
751 netdev->Send (p, header.GetDestination (), protocol);
755 Ipv4L3ClickProtocol::Receive ( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol,
const Address &from,
761 if (protocol == Ipv4L3ClickProtocol::PROT_NUMBER && m_sockets.size () > 0)
763 Ptr<Packet> packetForRawSocket = p->Copy ();
764 uint32_t
interface = 0;
765 Ptr<Ipv4Interface> ipv4Interface;
766 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
767 i != m_interfaces.end ();
771 if (ipv4Interface->GetDevice () == device)
773 if (ipv4Interface->IsUp ())
779 NS_LOG_LOGIC (
"Dropping received packet -- interface is down");
788 ipHeader.EnableChecksum ();
790 packetForRawSocket->RemoveHeader (ipHeader);
793 for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
796 Ptr<Ipv4RawSocketImpl> socket = *i;
797 socket->ForwardUp (packetForRawSocket, ipHeader, ipv4Interface);
801 Ptr<Packet> packet = p->Copy ();
808 hdr.SetLengthType (protocol);
809 packet->AddHeader (hdr);
816 Ipv4L3ClickProtocol::LocalDeliver (Ptr<const Packet> packet, Ipv4Header
const&ip, uint32_t iif)
819 Ptr<Packet> p = packet->Copy ();
821 m_localDeliverTrace (ip, packet, iif);
823 Ptr<IpL4Protocol> protocol =
GetProtocol (ip.GetProtocol ());
828 Ptr<Packet> copy = p->Copy ();
830 protocol->Receive (p, ip, GetInterface (iif));
840 if (ip.GetDestination ().IsBroadcast () ==
true
841 || ip.GetDestination ().IsMulticast () ==
true)
846 bool subnetDirected =
false;
849 Ipv4InterfaceAddress addr =
GetAddress (iif, i);
850 if (addr.GetLocal ().CombineMask (addr.GetMask ()) == ip.GetDestination ().CombineMask (addr.GetMask ())
851 && ip.GetDestination ().IsSubnetDirectedBroadcast (addr.GetMask ()))
853 subnetDirected =
true;
856 if (subnetDirected ==
false)
858 GetIcmp ()->SendDestUnreachPort (ip, copy);
864 Ptr<Icmpv4L4Protocol>
865 Ipv4L3ClickProtocol::GetIcmp (
void)
const
870 return prot->GetObject<Icmpv4L4Protocol> ();
881 m_protocols.push_back (protocol);
887 for (L4List_t::const_iterator i = m_protocols.begin (); i != m_protocols.end (); ++i)
889 if ((*i)->GetProtocolNumber () == protocolNumber)
static TypeId GetTypeId(void)
Get the type ID.
virtual uint32_t AddInterface(Ptr< NetDevice > device)=0
virtual int32_t GetInterfaceForPrefix(Ipv4Address address, Ipv4Mask mask) const =0
Return the interface number of first interface found that has an Ipv4 address within the prefix speci...
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
virtual void SetWeakEsModel(bool model)=0
Set or unset the Weak Es Model.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
static bool ChecksumEnabled(void)
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
PacketType
Packet types are used as they are in Linux.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
virtual void DoDispose(void)
Destructor implementation.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
virtual Ptr< NetDevice > GetNetDevice(uint32_t interface)=0
virtual void SetForwarding(uint32_t interface, bool val)=0
virtual Ptr< Ipv4RoutingProtocol > GetRoutingProtocol(void) const =0
Get the routing protocol to be used by this Ipv4 stack.
virtual bool IsDestinationAddress(Ipv4Address address, uint32_t iif) const =0
Determine whether address and interface corresponding to received packet can be accepted for local de...
virtual bool GetIpForward(void) const =0
Get the IP forwarding state.
virtual void DeleteRawSocket(Ptr< Socket > socket)=0
Deletes a particular raw socket.
virtual Ptr< IpL4Protocol > GetProtocol(int protocolNumber) const =0
virtual void SetUp(uint32_t interface)=0
virtual uint16_t GetMetric(uint32_t interface) const =0
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
ObjectPtrContainerValue ObjectVectorValue
ObjectVectorValue is an alias for ObjectPtrContainerValue.
virtual void SendWithHeader(Ptr< Packet > packet, Ipv4Header ipHeader, Ptr< Ipv4Route > route)=0
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
static Mac48Address ConvertFrom(const Address &address)
virtual void NotifyNewAggregate(void)
Notify all Objects aggregated to this one of a new Object being aggregated.
virtual bool GetWeakEsModel(void) const =0
Get the Weak Es Model status.
static const uint16_t PROT_NUMBER
ARP protocol number (0x0806)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
virtual bool IsForwarding(uint32_t interface) const =0
virtual uint16_t GetMtu(uint32_t interface) const =0
virtual void Send(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol, Ptr< Ipv4Route > route)=0
static Ipv4Address GetLoopback(void)
static Ipv4Mask GetLoopback(void)
virtual Ptr< Socket > CreateRawSocket(void)=0
Creates a raw socket.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
virtual bool IsUp(uint32_t interface) const =0
virtual void SetIpForward(bool forward)=0
Set or unset the IP forwarding state.
virtual void Insert(Ptr< IpL4Protocol > protocol)=0
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
virtual Ipv4InterfaceAddress GetAddress(uint32_t interface, uint32_t addressIndex) const =0
Because addresses can be removed, the addressIndex is not guaranteed to be static across calls to thi...
InterfaceAddressScope_e
Address scope.
static uint16_t GetStaticProtocolNumber(void)
Get the protocol number.
virtual uint32_t GetNAddresses(uint32_t interface) const =0
virtual Ipv4Address SelectSourceAddress(Ptr< const NetDevice > device, Ipv4Address dst, Ipv4InterfaceAddress::InterfaceAddressScope_e scope)=0
Return the first primary source address with scope less than or equal to the requested scope...
virtual void SetMetric(uint32_t interface, uint16_t metric)=0
virtual int32_t GetInterfaceForDevice(Ptr< const NetDevice > device) const =0
virtual bool AddAddress(uint32_t interface, Ipv4InterfaceAddress address)=0
Ptr< T > CreateObject(void)
Create an object by type, with varying number of constructor parameters.
virtual int32_t GetInterfaceForAddress(Ipv4Address address) const =0
Return the interface number of the interface that has been assigned the specified IP address...
virtual void SetDown(uint32_t interface)=0
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
virtual bool RemoveAddress(uint32_t interface, uint32_t addressIndex)=0
Remove the address at addressIndex on named interface.
TypeId SetParent(TypeId tid)
virtual uint32_t GetNInterfaces(void) const =0
virtual void SetRoutingProtocol(Ptr< Ipv4RoutingProtocol > routingProtocol)=0
Register a new routing protocol to be used by this Ipv4 stack.