25#include "ns3/arp-l3-protocol.h"
26#include "ns3/ethernet-header.h"
27#include "ns3/icmpv4-l4-protocol.h"
28#include "ns3/ip-l4-protocol.h"
29#include "ns3/ipv4-click-routing.h"
30#include "ns3/ipv4-raw-socket-impl.h"
31#include "ns3/llc-snap-header.h"
32#include "ns3/loopback-net-device.h"
33#include "ns3/net-device.h"
35#include "ns3/object-vector.h"
36#include "ns3/socket.h"
37#include "ns3/uinteger.h"
44const uint16_t Ipv4L3ClickProtocol::PROT_NUMBER = 0x0800;
52 TypeId(
"ns3::Ipv4L3ClickProtocol")
54 .AddConstructor<Ipv4L3ClickProtocol>()
55 .SetGroupName(
"Click")
58 "The TTL value set by default on all outgoing packets generated on this node.",
61 MakeUintegerChecker<uint8_t>())
62 .AddAttribute(
"InterfaceList",
63 "The set of Ipv4 interfaces associated to this Ipv4 stack.",
66 MakeObjectVectorChecker<Ipv4Interface>());
70Ipv4L3ClickProtocol::Ipv4L3ClickProtocol()
75Ipv4L3ClickProtocol::~Ipv4L3ClickProtocol()
80Ipv4L3ClickProtocol::DoDispose()
83 for (L4List_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
89 for (Ipv4InterfaceList::iterator i = m_interfaces.begin(); i != m_interfaces.end(); ++i)
94 m_reverseInterfacesContainer.clear();
98 m_routingProtocol =
nullptr;
103Ipv4L3ClickProtocol::NotifyNewAggregate()
107 Ptr<Node> node = this->GetObject<Node>();
115 Ipv4::NotifyNewAggregate();
119Ipv4L3ClickProtocol::SetRoutingProtocol(Ptr<Ipv4RoutingProtocol> routingProtocol)
122 m_routingProtocol = routingProtocol;
123 m_routingProtocol->SetIpv4(
this);
126Ptr<Ipv4RoutingProtocol>
127Ipv4L3ClickProtocol::GetRoutingProtocol()
const
129 return m_routingProtocol;
133Ipv4L3ClickProtocol::GetInterface(
uint32_t index)
const
136 if (index < m_interfaces.size())
138 return m_interfaces[index];
144Ipv4L3ClickProtocol::GetNInterfaces()
const
147 return m_interfaces.size();
151Ipv4L3ClickProtocol::GetInterfaceForAddress(Ipv4Address address)
const
156 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin(); i != m_interfaces.end();
159 for (
uint32_t j = 0; j < (*i)->GetNAddresses(); j++)
161 if ((*i)->GetAddress(j).GetLocal() == address)
172Ipv4L3ClickProtocol::GetInterfaceForPrefix(Ipv4Address address, Ipv4Mask mask)
const
177 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin(); i != m_interfaces.end();
180 for (
uint32_t j = 0; j < (*i)->GetNAddresses(); j++)
182 if ((*i)->GetAddress(j).GetLocal().CombineMask(mask) ==
address.CombineMask(mask))
193Ipv4L3ClickProtocol::GetInterfaceForDevice(Ptr<const NetDevice> device)
const
197 Ipv4InterfaceReverseContainer::const_iterator iter = m_reverseInterfacesContainer.find(device);
198 if (iter != m_reverseInterfacesContainer.end())
200 return (*iter).second;
207Ipv4L3ClickProtocol::IsDestinationAddress(Ipv4Address address,
uint32_t iif)
const
212 for (
uint32_t i = 0; i < GetNAddresses(iif); i++)
214 Ipv4InterfaceAddress iaddr = GetAddress(iif, i);
215 if (address == iaddr.GetLocal())
217 NS_LOG_LOGIC(
"For me (destination " << address <<
" match)");
220 if (address == iaddr.GetBroadcast())
230 if (MulticastCheckGroup(iif, address))
244 if (GetWeakEsModel())
246 for (
uint32_t j = 0; j < GetNInterfaces(); j++)
252 for (
uint32_t i = 0; i < GetNAddresses(j); i++)
254 Ipv4InterfaceAddress iaddr = GetAddress(j, i);
255 if (address == iaddr.GetLocal())
258 <<
" match) on another interface");
262 if (address == iaddr.GetBroadcast())
264 NS_LOG_LOGIC(
"For me (interface broadcast address on another interface)");
274Ipv4L3ClickProtocol::SetIpForward(
bool forward)
277 m_ipForward = forward;
278 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin(); i != m_interfaces.end(); i++)
280 (*i)->SetForwarding(forward);
285Ipv4L3ClickProtocol::GetIpForward()
const
291Ipv4L3ClickProtocol::SetWeakEsModel(
bool model)
293 m_weakEsModel = model;
297Ipv4L3ClickProtocol::GetWeakEsModel()
const
299 return m_weakEsModel;
303Ipv4L3ClickProtocol::GetNetDevice(
uint32_t i)
306 return GetInterface(i)->GetDevice();
310Ipv4L3ClickProtocol::SetDefaultTtl(uint8_t ttl)
317Ipv4L3ClickProtocol::SetupLoopback()
321 Ptr<Ipv4Interface>
interface =
CreateObject<Ipv4Interface>();
322 Ptr<LoopbackNetDevice> device =
nullptr;
324 for (
uint32_t i = 0; i < m_node->GetNDevices(); i++)
326 if ((device = DynamicCast<LoopbackNetDevice>(m_node->GetDevice(i))))
333 device = CreateObject<LoopbackNetDevice>();
334 m_node->AddDevice(device);
336 interface->SetDevice(device);
337 interface->SetNode(m_node);
338 Ipv4InterfaceAddress ifaceAddr =
339 Ipv4InterfaceAddress(Ipv4Address::GetLoopback(), Ipv4Mask::GetLoopback());
340 interface->AddAddress(ifaceAddr);
341 uint32_t index = AddIpv4Interface(interface);
342 Ptr<Node> node = GetObject<Node>();
343 node->RegisterProtocolHandler(
MakeCallback(&Ipv4L3ClickProtocol::Receive,
this),
344 Ipv4L3ClickProtocol::PROT_NUMBER,
347 if (m_routingProtocol)
349 m_routingProtocol->NotifyInterfaceUp(index);
354Ipv4L3ClickProtocol::CreateRawSocket()
357 Ptr<Ipv4RawSocketImpl> socket = CreateObject<Ipv4RawSocketImpl>();
358 socket->SetNode(m_node);
359 m_sockets.push_back(socket);
364Ipv4L3ClickProtocol::DeleteRawSocket(Ptr<Socket> socket)
367 for (SocketList::iterator i = m_sockets.begin(); i != m_sockets.end(); ++i)
378Ipv4L3ClickProtocol::SetNode(Ptr<Node> node)
386Ipv4L3ClickProtocol::AddAddress(
uint32_t i, Ipv4InterfaceAddress address)
389 Ptr<Ipv4Interface>
interface = GetInterface(i);
390 bool retVal = interface->AddAddress(address);
391 if (m_routingProtocol)
393 m_routingProtocol->NotifyAddAddress(i, address);
399Ipv4L3ClickProtocol::GetAddress(
uint32_t interfaceIndex,
uint32_t addressIndex)
const
402 Ptr<Ipv4Interface>
interface = GetInterface(interfaceIndex);
403 return interface->GetAddress(addressIndex);
407Ipv4L3ClickProtocol::GetNAddresses(
uint32_t interface)
const
410 Ptr<Ipv4Interface> iface = GetInterface(interface);
411 return iface->GetNAddresses();
418 Ptr<Ipv4Interface>
interface = GetInterface(i);
419 Ipv4InterfaceAddress
address = interface->RemoveAddress(addressIndex);
420 if (address != Ipv4InterfaceAddress())
422 if (m_routingProtocol)
424 m_routingProtocol->NotifyRemoveAddress(i, address);
432Ipv4L3ClickProtocol::RemoveAddress(
uint32_t i, Ipv4Address address)
436 if (address == Ipv4Address::GetLoopback())
441 Ptr<Ipv4Interface>
interface = GetInterface(i);
442 Ipv4InterfaceAddress ifAddr = interface->RemoveAddress(address);
443 if (ifAddr != Ipv4InterfaceAddress())
445 if (m_routingProtocol)
447 m_routingProtocol->NotifyRemoveAddress(i, ifAddr);
455Ipv4L3ClickProtocol::SourceAddressSelection(
uint32_t interfaceIdx, Ipv4Address dest)
458 if (GetNAddresses(interfaceIdx) == 1)
460 return GetAddress(interfaceIdx, 0).GetLocal();
466 Ipv4Address candidate = GetAddress(interfaceIdx, 0).GetLocal();
467 for (
uint32_t i = 0; i < GetNAddresses(interfaceIdx); i++)
469 Ipv4InterfaceAddress
test = GetAddress(interfaceIdx, i);
470 if (
test.GetLocal().CombineMask(
test.GetMask()) == dest.CombineMask(
test.GetMask()))
472 if (!
test.IsSecondary())
474 return test.GetLocal();
482Ipv4L3ClickProtocol::SelectSourceAddress(Ptr<const NetDevice> device,
484 Ipv4InterfaceAddress::InterfaceAddressScope_e scope)
487 Ipv4Address addr(
"0.0.0.0");
488 Ipv4InterfaceAddress iaddr;
493 int32_t i = GetInterfaceForDevice(device);
495 for (
uint32_t j = 0; j < GetNAddresses(i); j++)
497 iaddr = GetAddress(i, j);
498 if (iaddr.IsSecondary())
502 if (iaddr.GetScope() > scope)
506 if (dst.CombineMask(iaddr.GetMask()) == iaddr.GetLocal().CombineMask(iaddr.GetMask()))
508 return iaddr.GetLocal();
512 addr = iaddr.GetLocal();
523 for (
uint32_t i = 0; i < GetNInterfaces(); i++)
525 for (
uint32_t j = 0; j < GetNAddresses(i); j++)
527 iaddr = GetAddress(i, j);
528 if (iaddr.IsSecondary())
532 if (iaddr.GetScope() != Ipv4InterfaceAddress::LINK && iaddr.GetScope() <= scope)
534 return iaddr.GetLocal();
538 NS_LOG_WARN(
"Could not find source address for " << dst <<
" and scope " << scope
544Ipv4L3ClickProtocol::SetMetric(
uint32_t i, uint16_t metric)
547 Ptr<Ipv4Interface>
interface = GetInterface(i);
548 interface->SetMetric(metric);
552Ipv4L3ClickProtocol::GetMetric(
uint32_t i)
const
555 Ptr<Ipv4Interface>
interface = GetInterface(i);
556 return interface->GetMetric();
560Ipv4L3ClickProtocol::GetMtu(
uint32_t i)
const
563 Ptr<Ipv4Interface>
interface = GetInterface(i);
564 return interface->GetDevice()->GetMtu();
568Ipv4L3ClickProtocol::IsUp(
uint32_t i)
const
571 Ptr<Ipv4Interface>
interface = GetInterface(i);
572 return interface->IsUp();
576Ipv4L3ClickProtocol::SetUp(
uint32_t i)
579 Ptr<Ipv4Interface>
interface = GetInterface(i);
582 if (m_routingProtocol)
584 m_routingProtocol->NotifyInterfaceUp(i);
589Ipv4L3ClickProtocol::SetDown(
uint32_t ifaceIndex)
592 Ptr<Ipv4Interface>
interface = GetInterface(ifaceIndex);
593 interface->SetDown();
595 if (m_routingProtocol)
597 m_routingProtocol->NotifyInterfaceDown(ifaceIndex);
602Ipv4L3ClickProtocol::IsForwarding(
uint32_t i)
const
605 Ptr<Ipv4Interface>
interface = GetInterface(i);
606 NS_LOG_LOGIC(
"Forwarding state: " << interface->IsForwarding());
607 return interface->IsForwarding();
611Ipv4L3ClickProtocol::SetForwarding(
uint32_t i,
bool val)
614 Ptr<Ipv4Interface>
interface = GetInterface(i);
615 interface->SetForwarding(val);
619Ipv4L3ClickProtocol::SetPromisc(
uint32_t i)
622 Ptr<NetDevice> netdev = GetNetDevice(i);
624 Ptr<Node> node = GetObject<Node>();
626 node->RegisterProtocolHandler(
MakeCallback(&Ipv4L3ClickProtocol::Receive,
this),
633Ipv4L3ClickProtocol::AddInterface(Ptr<NetDevice> device)
636 Ptr<Node> node = GetObject<Node>();
637 node->RegisterProtocolHandler(
MakeCallback(&Ipv4L3ClickProtocol::Receive,
this),
638 Ipv4L3ClickProtocol::PROT_NUMBER,
640 node->RegisterProtocolHandler(
MakeCallback(&Ipv4L3ClickProtocol::Receive,
this),
641 ArpL3Protocol::PROT_NUMBER,
644 Ptr<Ipv4Interface>
interface =
CreateObject<Ipv4Interface>();
645 interface->SetNode(m_node);
646 interface->SetDevice(device);
647 interface->SetForwarding(m_ipForward);
648 return AddIpv4Interface(interface);
652Ipv4L3ClickProtocol::AddIpv4Interface(Ptr<Ipv4Interface> interface)
655 uint32_t index = m_interfaces.size();
656 m_interfaces.push_back(interface);
657 m_reverseInterfacesContainer[interface->GetDevice()] = index;
665Ipv4L3ClickProtocol::BuildHeader(Ipv4Address source,
666 Ipv4Address destination,
668 uint16_t payloadSize,
674 ipHeader.SetSource(source);
675 ipHeader.SetDestination(destination);
676 ipHeader.SetProtocol(protocol);
677 ipHeader.SetPayloadSize(payloadSize);
678 ipHeader.SetTtl(ttl);
681 ipHeader.SetMayFragment();
682 ipHeader.SetIdentification(m_identification);
687 ipHeader.SetDontFragment();
689 ipHeader.SetIdentification(m_identification);
692 if (Node::ChecksumEnabled())
694 ipHeader.EnableChecksum();
700Ipv4L3ClickProtocol::Send(Ptr<Packet> packet,
702 Ipv4Address destination,
704 Ptr<Ipv4Route> route)
709 bool mayFragment =
true;
710 uint8_t ttl = m_defaultTtl;
712 bool found = packet->RemovePacketTag(tag);
718 ipHeader = BuildHeader(source, destination, protocol, packet->GetSize(), ttl, mayFragment);
719 Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting>(m_routingProtocol);
720 if (Node::ChecksumEnabled())
722 ipHeader.EnableChecksum();
724 packet->AddHeader(ipHeader);
725 click->Send(packet->Copy(), source, destination);
729Ipv4L3ClickProtocol::SendWithHeader(Ptr<Packet> packet, Ipv4Header ipHeader, Ptr<Ipv4Route> route)
733 Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting>(m_routingProtocol);
734 if (Node::ChecksumEnabled())
736 ipHeader.EnableChecksum();
738 packet->AddHeader(ipHeader);
739 click->Send(packet->Copy(), ipHeader.GetSource(), ipHeader.GetDestination());
743Ipv4L3ClickProtocol::SendDown(Ptr<Packet> p,
int ifid)
752 Ptr<NetDevice> netdev = GetNetDevice(ifid);
754 EthernetHeader header;
755 p->RemoveHeader(header);
759 if (header.GetLengthType() <= 1500)
762 p->RemoveHeader(llc);
763 protocol = llc.GetType();
767 protocol = header.GetLengthType();
772 netdev->Send(p, header.GetDestination(), protocol);
776Ipv4L3ClickProtocol::Receive(Ptr<NetDevice> device,
781 NetDevice::PacketType packetType)
785 NS_LOG_LOGIC(
"Packet from " << from <<
" received on node " << m_node->GetId());
788 if (protocol == Ipv4L3ClickProtocol::PROT_NUMBER && !m_sockets.empty())
790 Ptr<Packet> packetForRawSocket = p->Copy();
791 int32_t interface = GetInterfaceForDevice(device);
793 "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);
808 for (SocketList::iterator i = m_sockets.begin(); i != m_sockets.end(); ++i)
811 Ptr<Ipv4RawSocketImpl> socket = *i;
812 socket->ForwardUp(packetForRawSocket, ipHeader, ipv4Interface);
816 Ptr<Packet> packet = p->Copy();
821 hdr.SetSource(Mac48Address::ConvertFrom(from));
822 hdr.SetDestination(Mac48Address::ConvertFrom(to));
823 hdr.SetLengthType(protocol);
824 packet->AddHeader(hdr);
826 Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting>(GetRoutingProtocol());
827 click->Receive(packet->Copy(),
828 Mac48Address::ConvertFrom(device->GetAddress()),
829 Mac48Address::ConvertFrom(to));
833Ipv4L3ClickProtocol::LocalDeliver(Ptr<const Packet> packet,
const Ipv4Header& ip,
uint32_t iif)
836 Ptr<Packet> p = packet->Copy();
838 m_localDeliverTrace(ip, packet, iif);
840 Ptr<IpL4Protocol> protocol = GetProtocol(ip.GetProtocol());
845 Ptr<Packet> copy = p->Copy();
846 IpL4Protocol::RxStatus status = 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() || ip.GetDestination().IsMulticast())
861 bool subnetDirected =
false;
862 for (
uint32_t i = 0; i < GetNAddresses(iif); i++)
864 Ipv4InterfaceAddress addr = GetAddress(iif, i);
865 if (addr.GetLocal().CombineMask(addr.GetMask()) ==
866 ip.GetDestination().CombineMask(addr.GetMask()) &&
867 ip.GetDestination().IsSubnetDirectedBroadcast(addr.GetMask()))
869 subnetDirected =
true;
874 GetIcmp()->SendDestUnreachPort(ip, copy);
881Ipv4L3ClickProtocol::GetIcmp()
const
883 Ptr<IpL4Protocol> prot = GetProtocol(Icmpv4L4Protocol::GetStaticProtocolNumber());
886 return prot->GetObject<Icmpv4L4Protocol>();
895Ipv4L3ClickProtocol::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;
907Ipv4L3ClickProtocol::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())
915 <<
" on interface " <<
int(interfaceIndex));
917 m_protocols[key] = protocol;
921Ipv4L3ClickProtocol::Remove(Ptr<IpL4Protocol> protocol)
925 L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), -1);
926 L4List_t::iterator iter = m_protocols.find(key);
927 if (iter == m_protocols.end())
929 NS_LOG_WARN(
"Trying to remove an non-existent default protocol "
930 <<
int(protocol->GetProtocolNumber()));
934 m_protocols.erase(key);
939Ipv4L3ClickProtocol::Remove(Ptr<IpL4Protocol> protocol,
uint32_t interfaceIndex)
943 L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), interfaceIndex);
944 L4List_t::iterator iter = m_protocols.find(key);
945 if (iter == m_protocols.end())
947 NS_LOG_WARN(
"Trying to remove an non-existent protocol "
948 <<
int(protocol->GetProtocolNumber()) <<
" on interface "
949 <<
int(interfaceIndex));
953 m_protocols.erase(key);
958Ipv4L3ClickProtocol::GetProtocol(
int protocolNumber)
const
962 return GetProtocol(protocolNumber, -1);
966Ipv4L3ClickProtocol::GetProtocol(
int protocolNumber,
int32_t interfaceIndex)
const
971 L4List_t::const_iterator i;
972 if (interfaceIndex >= 0)
975 key = std::make_pair(protocolNumber, interfaceIndex);
976 i = m_protocols.find(key);
977 if (i != m_protocols.end())
983 key = std::make_pair(protocolNumber, -1);
984 i = m_protocols.find(key);
985 if (i != m_protocols.end())
static TypeId GetTypeId()
Get the type ID.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
#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)
#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.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
-ns3 Test suite for the ns3 wrapper script