A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ipv4-l3-click-protocol.cc
Go to the documentation of this file.
1//
2// Copyright (c) 2006 Georgia Tech Research Corporation
3//
4// This program is free software; you can redistribute it and/or modify
5// it under the terms of the GNU General Public License version 2 as
6// published by the Free Software Foundation;
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program; if not, write to the Free Software
15// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16//
17// Author: George F. Riley <riley@ece.gatech.edu>
18// Author: Lalith Suresh <suresh.lalith@gmail.com>
19//
20
22
23#include "ipv4-click-routing.h"
24
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-raw-socket-impl.h"
30#include "ns3/llc-snap-header.h"
31#include "ns3/loopback-net-device.h"
32#include "ns3/net-device.h"
33#include "ns3/node.h"
34#include "ns3/object-vector.h"
35#include "ns3/socket.h"
36#include "ns3/uinteger.h"
37
38namespace ns3
39{
40
41NS_LOG_COMPONENT_DEFINE("Ipv4L3ClickProtocol");
42
43const uint16_t Ipv4L3ClickProtocol::PROT_NUMBER = 0x0800;
44
45NS_OBJECT_ENSURE_REGISTERED(Ipv4L3ClickProtocol);
46
47TypeId
49{
50 static TypeId tid =
51 TypeId("ns3::Ipv4L3ClickProtocol")
52 .SetParent<Ipv4>()
53 .AddConstructor<Ipv4L3ClickProtocol>()
54 .SetGroupName("Click")
55 .AddAttribute(
56 "DefaultTtl",
57 "The TTL value set by default on all outgoing packets generated on this node.",
58 UintegerValue(64),
60 MakeUintegerChecker<uint8_t>())
61 .AddAttribute("InterfaceList",
62 "The set of Ipv4 interfaces associated to this Ipv4 stack.",
65 MakeObjectVectorChecker<Ipv4Interface>());
66 return tid;
67}
68
70 : m_identification(0)
71{
72}
73
75{
76}
77
78void
80{
81 NS_LOG_FUNCTION(this);
82 for (auto i = m_protocols.begin(); i != m_protocols.end(); ++i)
83 {
84 i->second = nullptr;
85 }
86 m_protocols.clear();
87
88 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); ++i)
89 {
90 *i = nullptr;
91 }
92 m_interfaces.clear();
94
95 m_sockets.clear();
96 m_node = nullptr;
97 m_routingProtocol = nullptr;
99}
100
101void
103{
104 if (!m_node)
105 {
106 Ptr<Node> node = this->GetObject<Node>();
107 // verify that it's a valid node and that
108 // the node has not been set before
109 if (node)
110 {
111 this->SetNode(node);
112 }
113 }
115}
116
117void
119{
120 NS_LOG_FUNCTION(this);
121 m_routingProtocol = routingProtocol;
122 m_routingProtocol->SetIpv4(this);
123}
124
127{
128 return m_routingProtocol;
129}
130
133{
134 NS_LOG_FUNCTION(this << index);
135 if (index < m_interfaces.size())
136 {
137 return m_interfaces[index];
138 }
139 return nullptr;
140}
141
144{
146 return m_interfaces.size();
147}
148
151{
152 NS_LOG_FUNCTION(this << address);
153
154 int32_t interface = 0;
155 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++, interface++)
156 {
157 for (uint32_t j = 0; j < (*i)->GetNAddresses(); j++)
158 {
159 if ((*i)->GetAddress(j).GetLocal() == address)
160 {
161 return interface;
162 }
163 }
164 }
165
166 return -1;
167}
168
171{
172 NS_LOG_FUNCTION(this << address << mask);
173
174 int32_t interface = 0;
175 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++, interface++)
176 {
177 for (uint32_t j = 0; j < (*i)->GetNAddresses(); j++)
178 {
179 if ((*i)->GetAddress(j).GetLocal().CombineMask(mask) == address.CombineMask(mask))
180 {
181 return interface;
182 }
183 }
184 }
185
186 return -1;
187}
188
191{
192 NS_LOG_FUNCTION(this << device->GetIfIndex());
193
194 auto iter = m_reverseInterfacesContainer.find(device);
195 if (iter != m_reverseInterfacesContainer.end())
196 {
197 return (*iter).second;
198 }
199
200 return -1;
201}
202
203bool
205{
206 NS_LOG_FUNCTION(this << address << " " << iif);
207
208 // First check the incoming interface for a unicast address match
209 for (uint32_t i = 0; i < GetNAddresses(iif); i++)
210 {
211 Ipv4InterfaceAddress iaddr = GetAddress(iif, i);
212 if (address == iaddr.GetLocal())
213 {
214 NS_LOG_LOGIC("For me (destination " << address << " match)");
215 return true;
216 }
217 if (address == iaddr.GetBroadcast())
218 {
219 NS_LOG_LOGIC("For me (interface broadcast address)");
220 return true;
221 }
222 }
223
224 if (address.IsMulticast())
225 {
226#ifdef NOTYET
227 if (MulticastCheckGroup(iif, address))
228#endif
229 {
230 NS_LOG_LOGIC("For me (Ipv4Addr multicast address");
231 return true;
232 }
233 }
234
235 if (address.IsBroadcast())
236 {
237 NS_LOG_LOGIC("For me (Ipv4Addr broadcast address)");
238 return true;
239 }
240
241 if (!GetStrongEndSystemModel()) // Check other interfaces
242 {
243 for (uint32_t j = 0; j < GetNInterfaces(); j++)
244 {
245 if (j == uint32_t(iif))
246 {
247 continue;
248 }
249 for (uint32_t i = 0; i < GetNAddresses(j); i++)
250 {
251 Ipv4InterfaceAddress iaddr = GetAddress(j, i);
252 if (address == iaddr.GetLocal())
253 {
254 NS_LOG_LOGIC("For me (destination " << address
255 << " match) on another interface");
256 return true;
257 }
258 // This is a small corner case: match another interface's broadcast address
259 if (address == iaddr.GetBroadcast())
260 {
261 NS_LOG_LOGIC("For me (interface broadcast address on another interface)");
262 return true;
263 }
264 }
265 }
266 }
267 return false;
268}
269
270void
272{
273 NS_LOG_FUNCTION(this << forward);
274 m_ipForward = forward;
275 for (auto i = m_interfaces.begin(); i != m_interfaces.end(); i++)
276 {
277 (*i)->SetForwarding(forward);
278 }
279}
280
281bool
283{
284 return m_ipForward;
285}
286
287void
289{
290 m_strongEndSystemModel = !model;
291}
292
293bool
295{
297}
298
299void
301{
303}
304
305bool
307{
309}
310
313{
314 NS_LOG_FUNCTION(this << i);
315 return GetInterface(i)->GetDevice();
316}
317
318void
320{
322 m_defaultTtl = ttl;
323}
324
325void
327{
329
331 Ptr<LoopbackNetDevice> device = nullptr;
332 // First check whether an existing LoopbackNetDevice exists on the node
333 for (uint32_t i = 0; i < m_node->GetNDevices(); i++)
334 {
335 if ((device = DynamicCast<LoopbackNetDevice>(m_node->GetDevice(i))))
336 {
337 break;
338 }
339 }
340 if (!device)
341 {
342 device = CreateObject<LoopbackNetDevice>();
343 m_node->AddDevice(device);
344 }
345 interface->SetDevice(device);
346 interface->SetNode(m_node);
347 Ipv4InterfaceAddress ifaceAddr =
349 interface->AddAddress(ifaceAddr);
350 uint32_t index = AddIpv4Interface(interface);
351 Ptr<Node> node = GetObject<Node>();
352 node->RegisterProtocolHandler(MakeCallback(&Ipv4L3ClickProtocol::Receive, this),
354 device);
355 interface->SetUp();
357 {
358 m_routingProtocol->NotifyInterfaceUp(index);
359 }
360}
361
364{
365 NS_LOG_FUNCTION(this);
366 Ptr<Ipv4RawSocketImpl> socket = CreateObject<Ipv4RawSocketImpl>();
367 socket->SetNode(m_node);
368 m_sockets.push_back(socket);
369 return socket;
370}
371
372void
374{
375 NS_LOG_FUNCTION(this << socket);
376 for (auto i = m_sockets.begin(); i != m_sockets.end(); ++i)
377 {
378 if ((*i) == socket)
379 {
380 m_sockets.erase(i);
381 return;
382 }
383 }
384}
385
386void
388{
389 m_node = node;
390 // Add a LoopbackNetDevice if needed, and an Ipv4Interface on top of it
392}
393
394bool
396{
397 NS_LOG_FUNCTION(this << i << address);
398 Ptr<Ipv4Interface> interface = GetInterface(i);
399 bool retVal = interface->AddAddress(address);
400 if (m_routingProtocol)
401 {
402 m_routingProtocol->NotifyAddAddress(i, address);
403 }
404 return retVal;
405}
406
408Ipv4L3ClickProtocol::GetAddress(uint32_t interfaceIndex, uint32_t addressIndex) const
409{
410 NS_LOG_FUNCTION(this << interfaceIndex << addressIndex);
411 Ptr<Ipv4Interface> interface = GetInterface(interfaceIndex);
412 return interface->GetAddress(addressIndex);
413}
414
417{
418 NS_LOG_FUNCTION(this << interface);
419 Ptr<Ipv4Interface> iface = GetInterface(interface);
420 return iface->GetNAddresses();
421}
422
423bool
425{
426 NS_LOG_FUNCTION(this << i << addressIndex);
427 Ptr<Ipv4Interface> interface = GetInterface(i);
428 Ipv4InterfaceAddress address = interface->RemoveAddress(addressIndex);
429 if (address != Ipv4InterfaceAddress())
430 {
431 if (m_routingProtocol)
432 {
433 m_routingProtocol->NotifyRemoveAddress(i, address);
434 }
435 return true;
436 }
437 return false;
438}
439
440bool
442{
443 NS_LOG_FUNCTION(this << i << address);
444
445 if (address == Ipv4Address::GetLoopback())
446 {
447 NS_LOG_WARN("Cannot remove loopback address.");
448 return false;
449 }
450 Ptr<Ipv4Interface> interface = GetInterface(i);
451 Ipv4InterfaceAddress ifAddr = interface->RemoveAddress(address);
452 if (ifAddr != Ipv4InterfaceAddress())
453 {
454 if (m_routingProtocol)
455 {
456 m_routingProtocol->NotifyRemoveAddress(i, ifAddr);
457 }
458 return true;
459 }
460 return false;
461}
462
465{
466 NS_LOG_FUNCTION(this << interfaceIdx << " " << dest);
467 if (GetNAddresses(interfaceIdx) == 1) // common case
468 {
469 return GetAddress(interfaceIdx, 0).GetLocal();
470 }
471 // no way to determine the scope of the destination, so adopt the
472 // following rule: pick the first available address (index 0) unless
473 // a subsequent address is on link (in which case, pick the primary
474 // address if there are multiple)
475 Ipv4Address candidate = GetAddress(interfaceIdx, 0).GetLocal();
476 for (uint32_t i = 0; i < GetNAddresses(interfaceIdx); i++)
477 {
478 Ipv4InterfaceAddress test = GetAddress(interfaceIdx, i);
479 if (test.GetLocal().CombineMask(test.GetMask()) == dest.CombineMask(test.GetMask()))
480 {
481 if (!test.IsSecondary())
482 {
483 return test.GetLocal();
484 }
485 }
486 }
487 return candidate;
488}
489
492 Ipv4Address dst,
494{
495 NS_LOG_FUNCTION(device << dst << scope);
496 Ipv4Address addr("0.0.0.0");
498 bool found = false;
499
500 if (device)
501 {
502 int32_t i = GetInterfaceForDevice(device);
503 NS_ASSERT_MSG(i >= 0, "No device found on node");
504 for (uint32_t j = 0; j < GetNAddresses(i); j++)
505 {
506 iaddr = GetAddress(i, j);
507 if (iaddr.IsSecondary())
508 {
509 continue;
510 }
511 if (iaddr.GetScope() > scope)
512 {
513 continue;
514 }
515 if (dst.CombineMask(iaddr.GetMask()) == iaddr.GetLocal().CombineMask(iaddr.GetMask()))
516 {
517 return iaddr.GetLocal();
518 }
519 if (!found)
520 {
521 addr = iaddr.GetLocal();
522 found = true;
523 }
524 }
525 }
526 if (found)
527 {
528 return addr;
529 }
530
531 // Iterate among all interfaces
532 for (uint32_t i = 0; i < GetNInterfaces(); i++)
533 {
534 for (uint32_t j = 0; j < GetNAddresses(i); j++)
535 {
536 iaddr = GetAddress(i, j);
537 if (iaddr.IsSecondary())
538 {
539 continue;
540 }
541 if (iaddr.GetScope() != Ipv4InterfaceAddress::LINK && iaddr.GetScope() <= scope)
542 {
543 return iaddr.GetLocal();
544 }
545 }
546 }
547 NS_LOG_WARN("Could not find source address for " << dst << " and scope " << scope
548 << ", returning 0");
549 return addr;
550}
551
552void
554{
555 NS_LOG_FUNCTION(i << metric);
556 Ptr<Ipv4Interface> interface = GetInterface(i);
557 interface->SetMetric(metric);
558}
559
560uint16_t
562{
564 Ptr<Ipv4Interface> interface = GetInterface(i);
565 return interface->GetMetric();
566}
567
568uint16_t
570{
571 NS_LOG_FUNCTION(this << i);
572 Ptr<Ipv4Interface> interface = GetInterface(i);
573 return interface->GetDevice()->GetMtu();
574}
575
576bool
578{
579 NS_LOG_FUNCTION(this << i);
580 Ptr<Ipv4Interface> interface = GetInterface(i);
581 return interface->IsUp();
582}
583
584void
586{
587 NS_LOG_FUNCTION(this << i);
588 Ptr<Ipv4Interface> interface = GetInterface(i);
589 interface->SetUp();
590
591 if (m_routingProtocol)
592 {
593 m_routingProtocol->NotifyInterfaceUp(i);
594 }
595}
596
597void
599{
600 NS_LOG_FUNCTION(this << ifaceIndex);
601 Ptr<Ipv4Interface> interface = GetInterface(ifaceIndex);
602 interface->SetDown();
603
604 if (m_routingProtocol)
605 {
606 m_routingProtocol->NotifyInterfaceDown(ifaceIndex);
607 }
608}
609
610bool
612{
613 NS_LOG_FUNCTION(this << i);
614 Ptr<Ipv4Interface> interface = GetInterface(i);
615 NS_LOG_LOGIC("Forwarding state: " << interface->IsForwarding());
616 return interface->IsForwarding();
617}
618
619void
621{
622 NS_LOG_FUNCTION(this << i);
623 Ptr<Ipv4Interface> interface = GetInterface(i);
624 interface->SetForwarding(val);
625}
626
627void
629{
630 NS_ASSERT(i <= m_node->GetNDevices());
631 Ptr<NetDevice> netdev = GetNetDevice(i);
632 NS_ASSERT(netdev);
633 Ptr<Node> node = GetObject<Node>();
634 NS_ASSERT(node);
635 node->RegisterProtocolHandler(MakeCallback(&Ipv4L3ClickProtocol::Receive, this),
636 0,
637 netdev,
638 true);
639}
640
643{
644 NS_LOG_FUNCTION(this << &device);
645 Ptr<Node> node = GetObject<Node>();
646 node->RegisterProtocolHandler(MakeCallback(&Ipv4L3ClickProtocol::Receive, this),
648 device);
649 node->RegisterProtocolHandler(MakeCallback(&Ipv4L3ClickProtocol::Receive, this),
651 device);
652
654 interface->SetNode(m_node);
655 interface->SetDevice(device);
656 interface->SetForwarding(m_ipForward);
657 return AddIpv4Interface(interface);
658}
659
662{
663 NS_LOG_FUNCTION(this << interface);
664 uint32_t index = m_interfaces.size();
665 m_interfaces.push_back(interface);
666 m_reverseInterfacesContainer[interface->GetDevice()] = index;
667 return index;
668}
669
670/// \todo when should we set ip_id? check whether we are incrementing
671/// m_identification on packets that may later be dropped in this stack
672/// and whether that deviates from Linux
675 Ipv4Address destination,
676 uint8_t protocol,
677 uint16_t payloadSize,
678 uint8_t ttl,
679 bool mayFragment)
680{
682 Ipv4Header ipHeader;
683 ipHeader.SetSource(source);
684 ipHeader.SetDestination(destination);
685 ipHeader.SetProtocol(protocol);
686 ipHeader.SetPayloadSize(payloadSize);
687 ipHeader.SetTtl(ttl);
688 if (mayFragment)
689 {
690 ipHeader.SetMayFragment();
693 }
694 else
695 {
696 ipHeader.SetDontFragment();
697 // TBD: set to zero here; will cause traces to change
700 }
702 {
703 ipHeader.EnableChecksum();
704 }
705 return ipHeader;
706}
707
708void
710 Ipv4Address source,
711 Ipv4Address destination,
712 uint8_t protocol,
713 Ptr<Ipv4Route> route)
714{
715 NS_LOG_FUNCTION(this << packet << source << destination << uint32_t(protocol) << route);
716
717 Ipv4Header ipHeader;
718 bool mayFragment = true;
719 uint8_t ttl = m_defaultTtl;
720 SocketIpTtlTag tag;
721 bool found = packet->RemovePacketTag(tag);
722 if (found)
723 {
724 ttl = tag.GetTtl();
725 }
726
727 ipHeader = BuildHeader(source, destination, protocol, packet->GetSize(), ttl, mayFragment);
728 Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting>(m_routingProtocol);
730 {
731 ipHeader.EnableChecksum();
732 }
733 packet->AddHeader(ipHeader);
734 click->Send(packet->Copy(), source, destination);
735}
736
737void
739{
740 NS_LOG_FUNCTION(this << packet << ipHeader << route);
741
742 Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting>(m_routingProtocol);
744 {
745 ipHeader.EnableChecksum();
746 }
747 packet->AddHeader(ipHeader);
748 click->Send(packet->Copy(), ipHeader.GetSource(), ipHeader.GetDestination());
749}
750
751void
753{
754 // Called by Ipv4ClickRouting.
755
756 // NetDevice::Send () attaches ethernet headers,
757 // so the one that Click attaches isn't required
758 // but we need the destination address and
759 // protocol values from the header.
760
761 Ptr<NetDevice> netdev = GetNetDevice(ifid);
762
763 EthernetHeader header;
764 p->RemoveHeader(header);
765
766 uint16_t protocol;
767
768 if (header.GetLengthType() <= 1500)
769 {
770 LlcSnapHeader llc;
771 p->RemoveHeader(llc);
772 protocol = llc.GetType();
773 }
774 else
775 {
776 protocol = header.GetLengthType();
777 }
778
779 // Use the destination address and protocol obtained
780 // from above to send the packet.
781 netdev->Send(p, header.GetDestination(), protocol);
782}
783
784void
787 uint16_t protocol,
788 const Address& from,
789 const Address& to,
790 NetDevice::PacketType packetType)
791{
792 NS_LOG_FUNCTION(this << device << p << from << to);
793
794 NS_LOG_LOGIC("Packet from " << from << " received on node " << m_node->GetId());
795
796 // Forward packet to raw sockets, if any
797 if (protocol == Ipv4L3ClickProtocol::PROT_NUMBER && !m_sockets.empty())
798 {
799 Ptr<Packet> packetForRawSocket = p->Copy();
800 int32_t interface = GetInterfaceForDevice(device);
801 NS_ASSERT_MSG(interface != -1,
802 "Received a packet from an interface that is not known to IPv4");
803 Ptr<Ipv4Interface> ipv4Interface = m_interfaces[interface];
804 if (!ipv4Interface->IsUp())
805 {
806 NS_LOG_LOGIC("Dropping received packet -- interface is down");
807 return;
808 }
809
810 Ipv4Header ipHeader;
811 if (Node::ChecksumEnabled())
812 {
813 ipHeader.EnableChecksum();
814 }
815 packetForRawSocket->RemoveHeader(ipHeader);
816
817 for (auto i = m_sockets.begin(); i != m_sockets.end(); ++i)
818 {
819 NS_LOG_LOGIC("Forwarding to raw socket");
820 Ptr<Ipv4RawSocketImpl> socket = *i;
821 socket->ForwardUp(packetForRawSocket, ipHeader, ipv4Interface);
822 }
823 }
824
825 Ptr<Packet> packet = p->Copy();
826
827 // Add an ethernet frame. This allows
828 // Click to work with csma and wifi
829 EthernetHeader hdr;
832 hdr.SetLengthType(protocol);
833 packet->AddHeader(hdr);
834
835 Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting>(GetRoutingProtocol());
836 click->Receive(packet->Copy(),
837 Mac48Address::ConvertFrom(device->GetAddress()),
839}
840
841void
843{
844 NS_LOG_FUNCTION(this << packet << &ip);
845 Ptr<Packet> p = packet->Copy(); // need to pass a non-const packet up
846
847 m_localDeliverTrace(ip, packet, iif);
848
850 if (protocol)
851 {
852 // we need to make a copy in the unlikely event we hit the
853 // RX_ENDPOINT_UNREACH codepath
854 Ptr<Packet> copy = p->Copy();
855 IpL4Protocol::RxStatus status = protocol->Receive(p, ip, GetInterface(iif));
856 switch (status)
857 {
859 // fall through
861 // fall through
863 break;
866 {
867 break; // Do not reply to broadcast or multicast
868 }
869 // Another case to suppress ICMP is a subnet-directed broadcast
870 bool subnetDirected = false;
871 for (uint32_t i = 0; i < GetNAddresses(iif); i++)
872 {
873 Ipv4InterfaceAddress addr = GetAddress(iif, i);
874 if (addr.GetLocal().CombineMask(addr.GetMask()) ==
875 ip.GetDestination().CombineMask(addr.GetMask()) &&
877 {
878 subnetDirected = true;
879 }
880 }
881 if (!subnetDirected)
882 {
883 GetIcmp()->SendDestUnreachPort(ip, copy);
884 }
885 }
886 }
887}
888
891{
893 if (prot)
894 {
895 return prot->GetObject<Icmpv4L4Protocol>();
896 }
897 else
898 {
899 return nullptr;
900 }
901}
902
903void
905{
906 NS_LOG_FUNCTION(this << protocol);
907 L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), -1);
908 if (m_protocols.find(key) != m_protocols.end())
909 {
910 NS_LOG_WARN("Overwriting default protocol " << int(protocol->GetProtocolNumber()));
911 }
912 m_protocols[key] = protocol;
913}
914
915void
917{
918 NS_LOG_FUNCTION(this << protocol << interfaceIndex);
919
920 L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), interfaceIndex);
921 if (m_protocols.find(key) != m_protocols.end())
922 {
923 NS_LOG_WARN("Overwriting protocol " << int(protocol->GetProtocolNumber())
924 << " on interface " << int(interfaceIndex));
925 }
926 m_protocols[key] = protocol;
927}
928
929void
931{
932 NS_LOG_FUNCTION(this << protocol);
933
934 L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), -1);
935 auto iter = m_protocols.find(key);
936 if (iter == m_protocols.end())
937 {
938 NS_LOG_WARN("Trying to remove an non-existent default protocol "
939 << int(protocol->GetProtocolNumber()));
940 }
941 else
942 {
943 m_protocols.erase(key);
944 }
945}
946
947void
949{
950 NS_LOG_FUNCTION(this << protocol << interfaceIndex);
951
952 L4ListKey_t key = std::make_pair(protocol->GetProtocolNumber(), interfaceIndex);
953 auto iter = m_protocols.find(key);
954 if (iter == m_protocols.end())
955 {
956 NS_LOG_WARN("Trying to remove an non-existent protocol "
957 << int(protocol->GetProtocolNumber()) << " on interface "
958 << int(interfaceIndex));
959 }
960 else
961 {
962 m_protocols.erase(key);
963 }
964}
965
967Ipv4L3ClickProtocol::GetProtocol(int protocolNumber) const
968{
969 NS_LOG_FUNCTION(this << protocolNumber);
970
971 return GetProtocol(protocolNumber, -1);
972}
973
975Ipv4L3ClickProtocol::GetProtocol(int protocolNumber, int32_t interfaceIndex) const
976{
977 NS_LOG_FUNCTION(this << protocolNumber << interfaceIndex);
978
979 L4ListKey_t key;
980 if (interfaceIndex >= 0)
981 {
982 // try the interface-specific protocol.
983 key = std::make_pair(protocolNumber, interfaceIndex);
984 auto i = m_protocols.find(key);
985 if (i != m_protocols.end())
986 {
987 return i->second;
988 }
989 }
990 // try the generic protocol.
991 key = std::make_pair(protocolNumber, -1);
992 auto i = m_protocols.find(key);
993 if (i != m_protocols.end())
994 {
995 return i->second;
996 }
997
998 return nullptr;
999}
1000
1001} // namespace ns3
a polymophic address class
Definition: address.h:101
static const uint16_t PROT_NUMBER
ARP protocol number (0x0806)
Packet header for Ethernet.
uint16_t GetLengthType() const
void SetDestination(Mac48Address destination)
Mac48Address GetDestination() const
void SetLengthType(uint16_t size)
void SetSource(Mac48Address source)
This is the implementation of the ICMP protocol as described in RFC 792.
static uint16_t GetStaticProtocolNumber()
Get the protocol number.
RxStatus
Rx status codes.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
static Ipv4Address GetLoopback()
bool IsMulticast() const
bool IsSubnetDirectedBroadcast(const Ipv4Mask &mask) const
Generate subnet-directed broadcast address corresponding to mask.
Ipv4Address CombineMask(const Ipv4Mask &mask) const
Combine this address with a network mask.
bool IsBroadcast() const
Packet header for IPv4.
Definition: ipv4-header.h:34
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:309
Ipv4Address GetSource() const
Definition: ipv4-header.cc:302
void SetDontFragment()
Don't fragment this packet: if you need to anyway, drop it.
Definition: ipv4-header.cc:224
void SetPayloadSize(uint16_t size)
Definition: ipv4-header.cc:57
uint8_t GetProtocol() const
Definition: ipv4-header.cc:281
void SetTtl(uint8_t ttl)
Definition: ipv4-header.cc:267
Ipv4Address GetDestination() const
Definition: ipv4-header.cc:316
void SetMayFragment()
If you need to fragment this packet, you can do it.
Definition: ipv4-header.cc:231
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:288
void SetIdentification(uint16_t identification)
Definition: ipv4-header.cc:78
void EnableChecksum()
Enable checksum calculation for this header.
Definition: ipv4-header.cc:50
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:295
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:80
a class to store IPv4 address information on an interface
Ipv4Mask GetMask() const
Get the network mask.
Ipv4InterfaceAddress::InterfaceAddressScope_e GetScope() const
Get address scope.
Ipv4Address GetLocal() const
Get the local address.
bool IsSecondary() const
Check if the address is a secondary address.
Ipv4Address GetBroadcast() const
Get the broadcast address.
The IPv4 representation of a network interface.
void SetNode(Ptr< Node > node)
Set node associated with interface.
Ptr< NetDevice > GetDevice() const
L4List_t m_protocols
List of IPv4 L4 protocols.
void SetPromisc(uint32_t i)
Sets an interface to run on promiscuous mode.
uint32_t AddIpv4Interface(Ptr< Ipv4Interface > interface)
Adds an Ipv4Interface to the interfaces list.
Ipv4Header BuildHeader(Ipv4Address source, Ipv4Address destination, uint8_t protocol, uint16_t payloadSize, uint8_t ttl, bool mayFragment)
Build IPv4 header.
bool GetIpForward() const override
Get the IP forwarding state.
std::pair< int, int32_t > L4ListKey_t
Container of the IPv4 L4 keys: protocol number, interface index.
Ptr< Ipv4Interface > GetInterface(uint32_t i) const
Get a pointer to the i'th Ipv4Interface.
Ipv4InterfaceReverseContainer m_reverseInterfacesContainer
Container of NetDevice / Interface index associations.
TracedCallback< const Ipv4Header &, Ptr< const Packet >, uint32_t > m_localDeliverTrace
void LocalDeliver(Ptr< const Packet > p, const Ipv4Header &ip, uint32_t iif)
Ipv4ClickRouting calls this to locally deliver a packet.
bool RemoveAddress(uint32_t interfaceIndex, uint32_t addressIndex) override
Remove the address at addressIndex on named interface.
void Receive(Ptr< NetDevice > device, Ptr< const Packet > p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
Lower layer calls this method to send a packet to Click.
SocketList m_sockets
List of sockets.
bool IsForwarding(uint32_t i) const override
uint32_t GetNAddresses(uint32_t interface) const override
uint16_t GetMtu(uint32_t i) const override
Ptr< Ipv4RoutingProtocol > m_routingProtocol
IPv4 routing protocol.
Ptr< Socket > CreateRawSocket() override
Creates a raw-socket.
static TypeId GetTypeId()
Get Type ID.
void Remove(Ptr< IpL4Protocol > protocol) override
int32_t GetInterfaceForDevice(Ptr< const NetDevice > device) const override
void SetIpForward(bool forward) override
Set or unset the IP forwarding state.
void SetStrongEndSystemModel(bool model) override
Set or unset the Strong End System Model.
void SetUp(uint32_t i) override
Ptr< Ipv4RoutingProtocol > GetRoutingProtocol() const override
Get the routing protocol to be used by this Ipv4 stack.
void SetupLoopback()
Sets up a Loopback device.
void SetMetric(uint32_t i, uint16_t metric) override
Ipv4Address SourceAddressSelection(uint32_t interface, Ipv4Address dest) override
Choose the source address to use with destination address.
Ipv4InterfaceList m_interfaces
List of interfaces.
void NotifyNewAggregate() override
This function will notify other components connected to the node that a new stack member is now conne...
Ipv4InterfaceAddress GetAddress(uint32_t interfaceIndex, uint32_t addressIndex) const override
Because addresses can be removed, the addressIndex is not guaranteed to be static across calls to thi...
uint32_t GetNInterfaces() const override
void Send(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol, Ptr< Ipv4Route > route) override
bool IsUp(uint32_t i) const override
Ptr< NetDevice > GetNetDevice(uint32_t i) override
int32_t GetInterfaceForAddress(Ipv4Address addr) const override
Return the interface number of the interface that has been assigned the specified IP address.
void Insert(Ptr< IpL4Protocol > protocol) override
void SetDown(uint32_t i) override
bool m_strongEndSystemModel
Whether to use Strong End System Model.
Ptr< IpL4Protocol > GetProtocol(int protocolNumber) const override
void SetWeakEsModel(bool model) override
Set or unset the Weak Es Model.
bool AddAddress(uint32_t i, Ipv4InterfaceAddress address) override
uint32_t AddInterface(Ptr< NetDevice > device) override
void SetNode(Ptr< Node > node)
Calls m_node = node and sets up Loopback if needed.
void DoDispose() override
Destructor implementation.
void DeleteRawSocket(Ptr< Socket > socket) override
Deletes a particular raw socket.
static const uint16_t PROT_NUMBER
Protocol number for Ipv4 L3 (0x0800).
uint16_t m_identification
Identification.
uint16_t GetMetric(uint32_t i) const override
bool IsDestinationAddress(Ipv4Address address, uint32_t iif) const override
Determine whether address and interface corresponding to received packet can be accepted for local de...
void SendDown(Ptr< Packet > packet, int ifid)
Ptr< Icmpv4L4Protocol > GetIcmp() const
Returns the Icmpv4L4Protocol for the node.
bool GetWeakEsModel() const override
Get the Weak Es Model status.
void SendWithHeader(Ptr< Packet > packet, Ipv4Header ipHeader, Ptr< Ipv4Route > route) override
bool GetStrongEndSystemModel() const override
Get the Strong End System Model status.
void SetRoutingProtocol(Ptr< Ipv4RoutingProtocol > routingProtocol) override
Register a new routing protocol to be used by this Ipv4 stack.
bool m_ipForward
Whether IP forwarding is enabled.
uint8_t m_defaultTtl
Default TTL.
int32_t GetInterfaceForPrefix(Ipv4Address addr, Ipv4Mask mask) const override
Return the interface number of first interface found that has an Ipv4 address within the prefix speci...
void SetForwarding(uint32_t i, bool val) override
Ipv4Address SelectSourceAddress(Ptr< const NetDevice > device, Ipv4Address dst, Ipv4InterfaceAddress::InterfaceAddressScope_e scope) override
Return the first primary source address with scope less than or equal to the requested scope,...
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:257
static Ipv4Mask GetLoopback()
Header for the LLC/SNAP encapsulation.
uint16_t GetType()
Return the Ethertype.
static Mac48Address ConvertFrom(const Address &address)
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:300
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:135
uint32_t GetNDevices() const
Definition: node.cc:158
uint32_t GetId() const
Definition: node.cc:117
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:149
static bool ChecksumEnabled()
Definition: node.cc:278
virtual void NotifyNewAggregate()
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:423
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:444
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer.
Definition: socket.h:1124
uint8_t GetTtl() const
Get the tag's TTL.
Definition: socket.cc:611
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
Hold an unsigned integer type.
Definition: uinteger.h:45
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
ObjectPtrContainerValue ObjectVectorValue
ObjectVectorValue is an alias for ObjectPtrContainerValue.
Definition: object-vector.h:40
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-vector.h:76
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#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.
Definition: log.h:261
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:630
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
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...
Definition: callback.h:706
-ns3 Test suite for the ns3 wrapper script