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))
245 if (GetWeakEsModel())
247 for (
uint32_t j = 0; j < GetNInterfaces(); j++)
253 for (
uint32_t i = 0; i < GetNAddresses(j); i++)
255 Ipv4InterfaceAddress iaddr = GetAddress(j, i);
256 if (address == iaddr.GetLocal())
259 <<
" match) on another interface");
263 if (address == iaddr.GetBroadcast())
265 NS_LOG_LOGIC(
"For me (interface broadcast address on another interface)");
275Ipv4L3ClickProtocol::SetIpForward(
bool forward)
278 m_ipForward = forward;
279 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin(); i != m_interfaces.end(); i++)
281 (*i)->SetForwarding(forward);
286Ipv4L3ClickProtocol::GetIpForward()
const
292Ipv4L3ClickProtocol::SetWeakEsModel(
bool model)
294 m_weakEsModel = model;
298Ipv4L3ClickProtocol::GetWeakEsModel()
const
300 return m_weakEsModel;
304Ipv4L3ClickProtocol::GetNetDevice(
uint32_t i)
307 return GetInterface(i)->GetDevice();
311Ipv4L3ClickProtocol::SetDefaultTtl(uint8_t ttl)
318Ipv4L3ClickProtocol::SetupLoopback()
322 Ptr<Ipv4Interface>
interface =
CreateObject<Ipv4Interface>();
323 Ptr<LoopbackNetDevice> device =
nullptr;
325 for (
uint32_t i = 0; i < m_node->GetNDevices(); i++)
327 if ((device = DynamicCast<LoopbackNetDevice>(m_node->GetDevice(i))))
334 device = CreateObject<LoopbackNetDevice>();
335 m_node->AddDevice(device);
337 interface->SetDevice(device);
338 interface->SetNode(m_node);
339 Ipv4InterfaceAddress ifaceAddr =
340 Ipv4InterfaceAddress(Ipv4Address::GetLoopback(), Ipv4Mask::GetLoopback());
341 interface->AddAddress(ifaceAddr);
342 uint32_t index = AddIpv4Interface(interface);
343 Ptr<Node> node = GetObject<Node>();
344 node->RegisterProtocolHandler(
MakeCallback(&Ipv4L3ClickProtocol::Receive,
this),
345 Ipv4L3ClickProtocol::PROT_NUMBER,
348 if (m_routingProtocol)
350 m_routingProtocol->NotifyInterfaceUp(index);
355Ipv4L3ClickProtocol::CreateRawSocket()
358 Ptr<Ipv4RawSocketImpl> socket = CreateObject<Ipv4RawSocketImpl>();
359 socket->SetNode(m_node);
360 m_sockets.push_back(socket);
365Ipv4L3ClickProtocol::DeleteRawSocket(Ptr<Socket> socket)
368 for (SocketList::iterator i = m_sockets.begin(); i != m_sockets.end(); ++i)
379Ipv4L3ClickProtocol::SetNode(Ptr<Node> node)
387Ipv4L3ClickProtocol::AddAddress(
uint32_t i, Ipv4InterfaceAddress address)
390 Ptr<Ipv4Interface>
interface = GetInterface(i);
391 bool retVal = interface->AddAddress(address);
392 if (m_routingProtocol)
394 m_routingProtocol->NotifyAddAddress(i, address);
400Ipv4L3ClickProtocol::GetAddress(
uint32_t interfaceIndex,
uint32_t addressIndex)
const
403 Ptr<Ipv4Interface>
interface = GetInterface(interfaceIndex);
404 return interface->GetAddress(addressIndex);
408Ipv4L3ClickProtocol::GetNAddresses(
uint32_t interface)
const
411 Ptr<Ipv4Interface> iface = GetInterface(interface);
412 return iface->GetNAddresses();
419 Ptr<Ipv4Interface>
interface = GetInterface(i);
420 Ipv4InterfaceAddress
address = interface->RemoveAddress(addressIndex);
421 if (address != Ipv4InterfaceAddress())
423 if (m_routingProtocol)
425 m_routingProtocol->NotifyRemoveAddress(i, address);
433Ipv4L3ClickProtocol::RemoveAddress(
uint32_t i, Ipv4Address address)
437 if (address == Ipv4Address::GetLoopback())
442 Ptr<Ipv4Interface>
interface = GetInterface(i);
443 Ipv4InterfaceAddress ifAddr = interface->RemoveAddress(address);
444 if (ifAddr != Ipv4InterfaceAddress())
446 if (m_routingProtocol)
448 m_routingProtocol->NotifyRemoveAddress(i, ifAddr);
456Ipv4L3ClickProtocol::SourceAddressSelection(
uint32_t interfaceIdx, Ipv4Address dest)
459 if (GetNAddresses(interfaceIdx) == 1)
461 return GetAddress(interfaceIdx, 0).GetLocal();
467 Ipv4Address candidate = GetAddress(interfaceIdx, 0).GetLocal();
468 for (
uint32_t i = 0; i < GetNAddresses(interfaceIdx); i++)
470 Ipv4InterfaceAddress
test = GetAddress(interfaceIdx, i);
471 if (
test.GetLocal().CombineMask(
test.GetMask()) == dest.CombineMask(
test.GetMask()))
473 if (
test.IsSecondary() ==
false)
475 return test.GetLocal();
483Ipv4L3ClickProtocol::SelectSourceAddress(Ptr<const NetDevice> device,
485 Ipv4InterfaceAddress::InterfaceAddressScope_e scope)
488 Ipv4Address addr(
"0.0.0.0");
489 Ipv4InterfaceAddress iaddr;
494 int32_t i = GetInterfaceForDevice(device);
496 for (
uint32_t j = 0; j < GetNAddresses(i); j++)
498 iaddr = GetAddress(i, j);
499 if (iaddr.IsSecondary())
503 if (iaddr.GetScope() > scope)
507 if (dst.CombineMask(iaddr.GetMask()) == iaddr.GetLocal().CombineMask(iaddr.GetMask()))
509 return iaddr.GetLocal();
513 addr = iaddr.GetLocal();
524 for (
uint32_t i = 0; i < GetNInterfaces(); i++)
526 for (
uint32_t j = 0; j < GetNAddresses(i); j++)
528 iaddr = GetAddress(i, j);
529 if (iaddr.IsSecondary())
533 if (iaddr.GetScope() != Ipv4InterfaceAddress::LINK && iaddr.GetScope() <= scope)
535 return iaddr.GetLocal();
539 NS_LOG_WARN(
"Could not find source address for " << dst <<
" and scope " << scope
545Ipv4L3ClickProtocol::SetMetric(
uint32_t i, uint16_t metric)
548 Ptr<Ipv4Interface>
interface = GetInterface(i);
549 interface->SetMetric(metric);
553Ipv4L3ClickProtocol::GetMetric(
uint32_t i)
const
556 Ptr<Ipv4Interface>
interface = GetInterface(i);
557 return interface->GetMetric();
561Ipv4L3ClickProtocol::GetMtu(
uint32_t i)
const
564 Ptr<Ipv4Interface>
interface = GetInterface(i);
565 return interface->GetDevice()->GetMtu();
569Ipv4L3ClickProtocol::IsUp(
uint32_t i)
const
572 Ptr<Ipv4Interface>
interface = GetInterface(i);
573 return interface->IsUp();
577Ipv4L3ClickProtocol::SetUp(
uint32_t i)
580 Ptr<Ipv4Interface>
interface = GetInterface(i);
583 if (m_routingProtocol)
585 m_routingProtocol->NotifyInterfaceUp(i);
590Ipv4L3ClickProtocol::SetDown(
uint32_t ifaceIndex)
593 Ptr<Ipv4Interface>
interface = GetInterface(ifaceIndex);
594 interface->SetDown();
596 if (m_routingProtocol)
598 m_routingProtocol->NotifyInterfaceDown(ifaceIndex);
603Ipv4L3ClickProtocol::IsForwarding(
uint32_t i)
const
606 Ptr<Ipv4Interface>
interface = GetInterface(i);
607 NS_LOG_LOGIC(
"Forwarding state: " << interface->IsForwarding());
608 return interface->IsForwarding();
612Ipv4L3ClickProtocol::SetForwarding(
uint32_t i,
bool val)
615 Ptr<Ipv4Interface>
interface = GetInterface(i);
616 interface->SetForwarding(val);
620Ipv4L3ClickProtocol::SetPromisc(
uint32_t i)
623 Ptr<NetDevice> netdev = GetNetDevice(i);
625 Ptr<Node> node = GetObject<Node>();
627 node->RegisterProtocolHandler(
MakeCallback(&Ipv4L3ClickProtocol::Receive,
this),
634Ipv4L3ClickProtocol::AddInterface(Ptr<NetDevice> device)
637 Ptr<Node> node = GetObject<Node>();
638 node->RegisterProtocolHandler(
MakeCallback(&Ipv4L3ClickProtocol::Receive,
this),
639 Ipv4L3ClickProtocol::PROT_NUMBER,
641 node->RegisterProtocolHandler(
MakeCallback(&Ipv4L3ClickProtocol::Receive,
this),
642 ArpL3Protocol::PROT_NUMBER,
645 Ptr<Ipv4Interface>
interface =
CreateObject<Ipv4Interface>();
646 interface->SetNode(m_node);
647 interface->SetDevice(device);
648 interface->SetForwarding(m_ipForward);
649 return AddIpv4Interface(interface);
653Ipv4L3ClickProtocol::AddIpv4Interface(Ptr<Ipv4Interface> interface)
656 uint32_t index = m_interfaces.size();
657 m_interfaces.push_back(interface);
658 m_reverseInterfacesContainer[interface->GetDevice()] = index;
666Ipv4L3ClickProtocol::BuildHeader(Ipv4Address source,
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();
701Ipv4L3ClickProtocol::Send(Ptr<Packet> packet,
703 Ipv4Address destination,
705 Ptr<Ipv4Route> 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);
730Ipv4L3ClickProtocol::SendWithHeader(Ptr<Packet> packet, Ipv4Header ipHeader, Ptr<Ipv4Route> route)
734 Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting>(m_routingProtocol);
735 if (Node::ChecksumEnabled())
737 ipHeader.EnableChecksum();
739 packet->AddHeader(ipHeader);
740 click->Send(packet->Copy(), ipHeader.GetSource(), ipHeader.GetDestination());
744Ipv4L3ClickProtocol::SendDown(Ptr<Packet> p,
int ifid)
753 Ptr<NetDevice> netdev = GetNetDevice(ifid);
755 EthernetHeader header;
756 p->RemoveHeader(header);
760 if (header.GetLengthType() <= 1500)
763 p->RemoveHeader(llc);
764 protocol = llc.GetType();
768 protocol = header.GetLengthType();
773 netdev->Send(p, header.GetDestination(), protocol);
777Ipv4L3ClickProtocol::Receive(Ptr<NetDevice> device,
782 NetDevice::PacketType packetType)
786 NS_LOG_LOGIC(
"Packet from " << from <<
" received on node " << m_node->GetId());
789 if (protocol == Ipv4L3ClickProtocol::PROT_NUMBER && m_sockets.size() > 0)
791 Ptr<Packet> packetForRawSocket = p->Copy();
792 int32_t interface = GetInterfaceForDevice(device);
794 "Received a packet from an interface that is not known to IPv4");
795 Ptr<Ipv4Interface> ipv4Interface = m_interfaces[interface];
796 if (!ipv4Interface->IsUp())
798 NS_LOG_LOGIC(
"Dropping received packet -- interface is down");
803 if (Node::ChecksumEnabled())
805 ipHeader.EnableChecksum();
807 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(),
829 Mac48Address::ConvertFrom(device->GetAddress()),
830 Mac48Address::ConvertFrom(to));
834Ipv4L3ClickProtocol::LocalDeliver(Ptr<const Packet> packet,
const Ipv4Header& ip,
uint32_t iif)
837 Ptr<Packet> p = packet->Copy();
839 m_localDeliverTrace(ip, packet, iif);
841 Ptr<IpL4Protocol> protocol = GetProtocol(ip.GetProtocol());
846 Ptr<Packet> copy = p->Copy();
847 enum IpL4Protocol::RxStatus status = protocol->Receive(p, ip, GetInterface(iif));
850 case IpL4Protocol::RX_OK:
852 case IpL4Protocol::RX_ENDPOINT_CLOSED:
854 case IpL4Protocol::RX_CSUM_FAILED:
856 case IpL4Protocol::RX_ENDPOINT_UNREACH:
857 if (ip.GetDestination().IsBroadcast() ==
true ||
858 ip.GetDestination().IsMulticast() ==
true)
863 bool subnetDirected =
false;
864 for (
uint32_t i = 0; i < GetNAddresses(iif); i++)
866 Ipv4InterfaceAddress addr = GetAddress(iif, i);
867 if (addr.GetLocal().CombineMask(addr.GetMask()) ==
868 ip.GetDestination().CombineMask(addr.GetMask()) &&
869 ip.GetDestination().IsSubnetDirectedBroadcast(addr.GetMask()))
871 subnetDirected =
true;
874 if (subnetDirected ==
false)
876 GetIcmp()->SendDestUnreachPort(ip, copy);
883Ipv4L3ClickProtocol::GetIcmp()
const
885 Ptr<IpL4Protocol> prot = GetProtocol(Icmpv4L4Protocol::GetStaticProtocolNumber());
888 return prot->GetObject<Icmpv4L4Protocol>();
897Ipv4L3ClickProtocol::Insert(Ptr<IpL4Protocol> protocol)
900 L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), -1);
901 if (m_protocols.find(key) != m_protocols.end())
903 NS_LOG_WARN(
"Overwriting default protocol " <<
int(protocol->GetProtocolNumber()));
905 m_protocols[key] = protocol;
909Ipv4L3ClickProtocol::Insert(Ptr<IpL4Protocol> protocol,
uint32_t interfaceIndex)
913 L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), interfaceIndex);
914 if (m_protocols.find(key) != m_protocols.end())
916 NS_LOG_WARN(
"Overwriting protocol " <<
int(protocol->GetProtocolNumber())
917 <<
" on interface " <<
int(interfaceIndex));
919 m_protocols[key] = protocol;
923Ipv4L3ClickProtocol::Remove(Ptr<IpL4Protocol> protocol)
927 L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), -1);
928 L4List_t::iterator iter = m_protocols.find(key);
929 if (iter == m_protocols.end())
931 NS_LOG_WARN(
"Trying to remove an non-existent default protocol "
932 <<
int(protocol->GetProtocolNumber()));
936 m_protocols.erase(key);
941Ipv4L3ClickProtocol::Remove(Ptr<IpL4Protocol> protocol,
uint32_t interfaceIndex)
945 L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), interfaceIndex);
946 L4List_t::iterator iter = m_protocols.find(key);
947 if (iter == m_protocols.end())
949 NS_LOG_WARN(
"Trying to remove an non-existent protocol "
950 <<
int(protocol->GetProtocolNumber()) <<
" on interface "
951 <<
int(interfaceIndex));
955 m_protocols.erase(key);
960Ipv4L3ClickProtocol::GetProtocol(
int protocolNumber)
const
964 return GetProtocol(protocolNumber, -1);
968Ipv4L3ClickProtocol::GetProtocol(
int protocolNumber,
int32_t interfaceIndex)
const
973 L4List_t::const_iterator i;
974 if (interfaceIndex >= 0)
977 key = std::make_pair(protocolNumber, interfaceIndex);
978 i = m_protocols.find(key);
979 if (i != m_protocols.end())
985 key = std::make_pair(protocolNumber, -1);
986 i = m_protocols.find(key);
987 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