A Discrete-Event Network Simulator
API
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 
21 #include "ipv4-l3-click-protocol.h"
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 
38 namespace ns3
39 {
40 
41 NS_LOG_COMPONENT_DEFINE("Ipv4L3ClickProtocol");
42 
43 const uint16_t Ipv4L3ClickProtocol::PROT_NUMBER = 0x0800;
44 
45 NS_OBJECT_ENSURE_REGISTERED(Ipv4L3ClickProtocol);
46 
47 TypeId
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 
78 void
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 
101 void
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 
117 void
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 
142 uint32_t
144 {
146  return m_interfaces.size();
147 }
148 
149 int32_t
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 
169 int32_t
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 
189 int32_t
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 
203 bool
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 
270 void
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 
281 bool
283 {
284  return m_ipForward;
285 }
286 
287 void
289 {
290  m_strongEndSystemModel = !model;
291 }
292 
293 bool
295 {
296  return !m_strongEndSystemModel;
297 }
298 
299 void
301 {
302  m_strongEndSystemModel = model;
303 }
304 
305 bool
307 {
308  return m_strongEndSystemModel;
309 }
310 
313 {
314  NS_LOG_FUNCTION(this << i);
315  return GetInterface(i)->GetDevice();
316 }
317 
318 void
320 {
322  m_defaultTtl = ttl;
323 }
324 
325 void
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>();
354  device);
355  interface->SetUp();
356  if (m_routingProtocol)
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 
372 void
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 
386 void
388 {
389  m_node = node;
390  // Add a LoopbackNetDevice if needed, and an Ipv4Interface on top of it
391  SetupLoopback();
392 }
393 
394 bool
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 
408 Ipv4L3ClickProtocol::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 
415 uint32_t
416 Ipv4L3ClickProtocol::GetNAddresses(uint32_t interface) const
417 {
418  NS_LOG_FUNCTION(this << interface);
419  Ptr<Ipv4Interface> iface = GetInterface(interface);
420  return iface->GetNAddresses();
421 }
422 
423 bool
424 Ipv4L3ClickProtocol::RemoveAddress(uint32_t i, uint32_t addressIndex)
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 
440 bool
442 {
443  NS_LOG_FUNCTION(this << i << address);
444 
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");
497  Ipv4InterfaceAddress iaddr;
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 
552 void
553 Ipv4L3ClickProtocol::SetMetric(uint32_t i, uint16_t metric)
554 {
555  NS_LOG_FUNCTION(i << metric);
556  Ptr<Ipv4Interface> interface = GetInterface(i);
557  interface->SetMetric(metric);
558 }
559 
560 uint16_t
562 {
563  NS_LOG_FUNCTION(i);
564  Ptr<Ipv4Interface> interface = GetInterface(i);
565  return interface->GetMetric();
566 }
567 
568 uint16_t
570 {
571  NS_LOG_FUNCTION(this << i);
572  Ptr<Ipv4Interface> interface = GetInterface(i);
573  return interface->GetDevice()->GetMtu();
574 }
575 
576 bool
577 Ipv4L3ClickProtocol::IsUp(uint32_t i) const
578 {
579  NS_LOG_FUNCTION(this << i);
580  Ptr<Ipv4Interface> interface = GetInterface(i);
581  return interface->IsUp();
582 }
583 
584 void
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 
597 void
598 Ipv4L3ClickProtocol::SetDown(uint32_t ifaceIndex)
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 
610 bool
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 
619 void
621 {
622  NS_LOG_FUNCTION(this << i);
623  Ptr<Ipv4Interface> interface = GetInterface(i);
624  interface->SetForwarding(val);
625 }
626 
627 void
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);
636  0,
637  netdev,
638  true);
639 }
640 
641 uint32_t
643 {
644  NS_LOG_FUNCTION(this << &device);
645  Ptr<Node> node = GetObject<Node>();
648  device);
651  device);
652 
654  interface->SetNode(m_node);
655  interface->SetDevice(device);
656  interface->SetForwarding(m_ipForward);
657  return AddIpv4Interface(interface);
658 }
659 
660 uint32_t
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 
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  }
701  if (Node::ChecksumEnabled())
702  {
703  ipHeader.EnableChecksum();
704  }
705  return ipHeader;
706 }
707 
708 void
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);
729  if (Node::ChecksumEnabled())
730  {
731  ipHeader.EnableChecksum();
732  }
733  packet->AddHeader(ipHeader);
734  click->Send(packet->Copy(), source, destination);
735 }
736 
737 void
739 {
740  NS_LOG_FUNCTION(this << packet << ipHeader << route);
741 
742  Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting>(m_routingProtocol);
743  if (Node::ChecksumEnabled())
744  {
745  ipHeader.EnableChecksum();
746  }
747  packet->AddHeader(ipHeader);
748  click->Send(packet->Copy(), ipHeader.GetSource(), ipHeader.GetDestination());
749 }
750 
751 void
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 
784 void
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 
841 void
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 
849  Ptr<IpL4Protocol> protocol = GetProtocol(ip.GetProtocol());
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  {
858  case IpL4Protocol::RX_OK:
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 
903 void
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 
915 void
916 Ipv4L3ClickProtocol::Insert(Ptr<IpL4Protocol> protocol, uint32_t interfaceIndex)
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 
929 void
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 
947 void
948 Ipv4L3ClickProtocol::Remove(Ptr<IpL4Protocol> protocol, uint32_t interfaceIndex)
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 
967 Ipv4L3ClickProtocol::GetProtocol(int protocolNumber) const
968 {
969  NS_LOG_FUNCTION(this << protocolNumber);
970 
971  return GetProtocol(protocolNumber, -1);
972 }
973 
975 Ipv4L3ClickProtocol::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.
virtual RxStatus Receive(Ptr< Packet > p, const Ipv4Header &header, Ptr< Ipv4Interface > incomingInterface)=0
Called from lower-level layers to send the packet up in the stack.
virtual int GetProtocolNumber() const =0
Returns the protocol number of this protocol.
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.
uint32_t GetNAddresses() const
void SetNode(Ptr< Node > node)
Set node associated with interface.
Ipv4InterfaceAddress GetAddress(uint32_t index) const
bool AddAddress(Ipv4InterfaceAddress address)
uint16_t GetMetric() const
bool IsUp() const
These are IP interface states and may be distinct from NetDevice states, such as found in real implem...
void SetUp()
Enable this interface.
Ptr< NetDevice > GetDevice() const
void SetDown()
Disable this interface.
void SetForwarding(bool val)
void SetMetric(uint16_t metric)
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()
bool ForwardUp(Ptr< const Packet > p, Ipv4Header ipHeader, Ptr< Ipv4Interface > incomingInterface)
Forward up to receive method.
void SetNode(Ptr< Node > node)
Set the node associated with this socket.
Header for the LLC/SNAP encapsulation.
uint16_t GetType()
Return the Ethertype.
static Mac48Address ConvertFrom(const Address &address)
virtual uint32_t GetIfIndex() const =0
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:138
uint32_t GetNDevices() const
Definition: node.cc:162
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:152
static bool ChecksumEnabled()
Definition: node.cc:285
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:238
virtual void NotifyNewAggregate()
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:331
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:352
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:967
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer.
Definition: socket.h:1122
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:931
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
#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:579
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
address
Definition: first.py:47
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:704
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