A Discrete-Event Network Simulator
API
ipv4-l3-protocol.cc
Go to the documentation of this file.
1 // -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*-
2 //
3 // Copyright (c) 2006 Georgia Tech Research Corporation
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License version 2 as
7 // published by the Free Software Foundation;
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 //
18 // Author: George F. Riley<riley@ece.gatech.edu>
19 //
20 
21 #include "ns3/packet.h"
22 #include "ns3/log.h"
23 #include "ns3/callback.h"
24 #include "ns3/ipv4-address.h"
25 #include "ns3/ipv4-route.h"
26 #include "ns3/node.h"
27 #include "ns3/socket.h"
28 #include "ns3/net-device.h"
29 #include "ns3/uinteger.h"
30 #include "ns3/string.h"
31 #include "ns3/boolean.h"
32 #include "ns3/trace-source-accessor.h"
33 #include "ns3/object-vector.h"
34 #include "ns3/ipv4-header.h"
35 #include "ns3/boolean.h"
36 #include "ns3/ipv4-routing-table-entry.h"
37 #include "ns3/traffic-control-layer.h"
38 
39 #include "loopback-net-device.h"
40 #include "arp-l3-protocol.h"
41 #include "arp-cache.h"
42 #include "ipv4-l3-protocol.h"
43 #include "icmpv4-l4-protocol.h"
44 #include "ipv4-interface.h"
45 #include "ipv4-raw-socket-impl.h"
46 
47 namespace ns3 {
48 
49 NS_LOG_COMPONENT_DEFINE ("Ipv4L3Protocol");
50 
51 const uint16_t Ipv4L3Protocol::PROT_NUMBER = 0x0800;
52 
53 NS_OBJECT_ENSURE_REGISTERED (Ipv4L3Protocol);
54 
55 TypeId
57 {
58  static TypeId tid = TypeId ("ns3::Ipv4L3Protocol")
59  .SetParent<Ipv4> ()
60  .SetGroupName ("Internet")
61  .AddConstructor<Ipv4L3Protocol> ()
62  .AddAttribute ("DefaultTtl",
63  "The TTL value set by default on "
64  "all outgoing packets generated on this node.",
65  UintegerValue (64),
67  MakeUintegerChecker<uint8_t> ())
68  .AddAttribute ("FragmentExpirationTimeout",
69  "When this timeout expires, the fragments "
70  "will be cleared from the buffer.",
71  TimeValue (Seconds (30)),
73  MakeTimeChecker ())
74  .AddAttribute ("EnableDuplicatePacketDetection",
75  "Enable multicast duplicate packet detection based on RFC 6621",
76  BooleanValue (false),
79  .AddAttribute ("DuplicateExpire", "Expiration delay for duplicate cache entries",
80  TimeValue (MilliSeconds (1)),
82  MakeTimeChecker ())
83  .AddAttribute ("PurgeExpiredPeriod",
84  "Time between purges of expired duplicate packet entries, "
85  "0 means never purge",
86  TimeValue (Seconds (1)),
89  .AddTraceSource ("Tx",
90  "Send ipv4 packet to outgoing interface.",
92  "ns3::Ipv4L3Protocol::TxRxTracedCallback")
93  .AddTraceSource ("Rx",
94  "Receive ipv4 packet from incoming interface.",
96  "ns3::Ipv4L3Protocol::TxRxTracedCallback")
97  .AddTraceSource ("Drop",
98  "Drop ipv4 packet",
100  "ns3::Ipv4L3Protocol::DropTracedCallback")
101  .AddAttribute ("InterfaceList",
102  "The set of Ipv4 interfaces associated to this Ipv4 stack.",
105  MakeObjectVectorChecker<Ipv4Interface> ())
106 
107  .AddTraceSource ("SendOutgoing",
108  "A newly-generated packet by this node is "
109  "about to be queued for transmission",
111  "ns3::Ipv4L3Protocol::SentTracedCallback")
112  .AddTraceSource ("UnicastForward",
113  "A unicast IPv4 packet was received by this node "
114  "and is being forwarded to another node",
116  "ns3::Ipv4L3Protocol::SentTracedCallback")
117  .AddTraceSource ("LocalDeliver",
118  "An IPv4 packet was received by/for this node, "
119  "and it is being forward up the stack",
121  "ns3::Ipv4L3Protocol::SentTracedCallback")
122 
123  ;
124  return tid;
125 }
126 
128 {
129  NS_LOG_FUNCTION (this);
130 }
131 
133 {
134  NS_LOG_FUNCTION (this);
135 }
136 
137 void
139 {
140  NS_LOG_FUNCTION (this << protocol);
141  L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), -1);
142  if (m_protocols.find (key) != m_protocols.end ())
143  {
144  NS_LOG_WARN ("Overwriting default protocol " << int(protocol->GetProtocolNumber ()));
145  }
146  m_protocols[key] = protocol;
147 }
148 
149 void
150 Ipv4L3Protocol::Insert (Ptr<IpL4Protocol> protocol, uint32_t interfaceIndex)
151 {
152  NS_LOG_FUNCTION (this << protocol << interfaceIndex);
153 
154  L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), interfaceIndex);
155  if (m_protocols.find (key) != m_protocols.end ())
156  {
157  NS_LOG_WARN ("Overwriting protocol " << int(protocol->GetProtocolNumber ()) << " on interface " << int(interfaceIndex));
158  }
159  m_protocols[key] = protocol;
160 }
161 
162 void
164 {
165  NS_LOG_FUNCTION (this << protocol);
166 
167  L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), -1);
168  L4List_t::iterator iter = m_protocols.find (key);
169  if (iter == m_protocols.end ())
170  {
171  NS_LOG_WARN ("Trying to remove an non-existent default protocol " << int(protocol->GetProtocolNumber ()));
172  }
173  else
174  {
175  m_protocols.erase (key);
176  }
177 }
178 
179 void
180 Ipv4L3Protocol::Remove (Ptr<IpL4Protocol> protocol, uint32_t interfaceIndex)
181 {
182  NS_LOG_FUNCTION (this << protocol << interfaceIndex);
183 
184  L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), interfaceIndex);
185  L4List_t::iterator iter = m_protocols.find (key);
186  if (iter == m_protocols.end ())
187  {
188  NS_LOG_WARN ("Trying to remove an non-existent protocol " << int(protocol->GetProtocolNumber ()) << " on interface " << int(interfaceIndex));
189  }
190  else
191  {
192  m_protocols.erase (key);
193  }
194 }
195 
197 Ipv4L3Protocol::GetProtocol (int protocolNumber) const
198 {
199  NS_LOG_FUNCTION (this << protocolNumber);
200 
201  return GetProtocol (protocolNumber, -1);
202 }
203 
205 Ipv4L3Protocol::GetProtocol (int protocolNumber, int32_t interfaceIndex) const
206 {
207  NS_LOG_FUNCTION (this << protocolNumber << interfaceIndex);
208 
209  L4ListKey_t key;
210  L4List_t::const_iterator i;
211  if (interfaceIndex >= 0)
212  {
213  // try the interface-specific protocol.
214  key = std::make_pair (protocolNumber, interfaceIndex);
215  i = m_protocols.find (key);
216  if (i != m_protocols.end ())
217  {
218  return i->second;
219  }
220  }
221  // try the generic protocol.
222  key = std::make_pair (protocolNumber, -1);
223  i = m_protocols.find (key);
224  if (i != m_protocols.end ())
225  {
226  return i->second;
227  }
228 
229  return 0;
230 }
231 
232 void
234 {
235  NS_LOG_FUNCTION (this << node);
236  m_node = node;
237  // Add a LoopbackNetDevice if needed, and an Ipv4Interface on top of it
238  SetupLoopback ();
239 }
240 
243 {
244  NS_LOG_FUNCTION (this);
245  Ptr<Ipv4RawSocketImpl> socket = CreateObject<Ipv4RawSocketImpl> ();
246  socket->SetNode (m_node);
247  m_sockets.push_back (socket);
248  return socket;
249 }
250 void
252 {
253  NS_LOG_FUNCTION (this << socket);
254  for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
255  {
256  if ((*i) == socket)
257  {
258  m_sockets.erase (i);
259  return;
260  }
261  }
262  return;
263 }
264 /*
265  * This method is called by AggregateObject and completes the aggregation
266  * by setting the node in the ipv4 stack
267  */
268 void
270 {
271  NS_LOG_FUNCTION (this);
272  if (m_node == 0)
273  {
274  Ptr<Node>node = this->GetObject<Node>();
275  // verify that it's a valid node and that
276  // the node has not been set before
277  if (node != 0)
278  {
279  this->SetNode (node);
280  }
281  }
283 }
284 
285 void
287 {
288  NS_LOG_FUNCTION (this << routingProtocol);
289  m_routingProtocol = routingProtocol;
290  m_routingProtocol->SetIpv4 (this);
291 }
292 
293 
296 {
297  NS_LOG_FUNCTION (this);
298  return m_routingProtocol;
299 }
300 
301 void
303 {
304  NS_LOG_FUNCTION (this);
305  for (L4List_t::iterator i = m_protocols.begin (); i != m_protocols.end (); ++i)
306  {
307  i->second = 0;
308  }
309  m_protocols.clear ();
310 
311  for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); ++i)
312  {
313  *i = 0;
314  }
315  m_interfaces.clear ();
317 
318  m_sockets.clear ();
319  m_node = 0;
320  m_routingProtocol = 0;
321 
322  for (MapFragments_t::iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
323  {
324  it->second = 0;
325  }
326 
327  for (MapFragmentsTimers_t::iterator it = m_fragmentsTimers.begin (); it != m_fragmentsTimers.end (); it++)
328  {
329  if (it->second.IsRunning ())
330  {
331  it->second.Cancel ();
332  }
333  }
334 
335  m_fragments.clear ();
336  m_fragmentsTimers.clear ();
337 
338  if (m_cleanDpd.IsRunning ())
339  {
340  m_cleanDpd.Cancel ();
341  }
342  m_dups.clear ();
343 
345 }
346 
347 void
349 {
350  NS_LOG_FUNCTION (this);
351 
353  Ptr<LoopbackNetDevice> device = 0;
354  // First check whether an existing LoopbackNetDevice exists on the node
355  for (uint32_t i = 0; i < m_node->GetNDevices (); i++)
356  {
357  if ((device = DynamicCast<LoopbackNetDevice> (m_node->GetDevice (i))))
358  {
359  break;
360  }
361  }
362  if (device == 0)
363  {
364  device = CreateObject<LoopbackNetDevice> ();
365  m_node->AddDevice (device);
366  }
367  interface->SetDevice (device);
368  interface->SetNode (m_node);
370  interface->AddAddress (ifaceAddr);
371  uint32_t index = AddIpv4Interface (interface);
372  Ptr<Node> node = GetObject<Node> ();
375  interface->SetUp ();
376  if (m_routingProtocol != 0)
377  {
378  m_routingProtocol->NotifyInterfaceUp (index);
379  }
380 }
381 
382 void
384 {
385  NS_LOG_FUNCTION (this << static_cast<uint32_t> (ttl));
386  m_defaultTtl = ttl;
387 }
388 
389 uint32_t
391 {
392  NS_LOG_FUNCTION (this << device);
393  NS_ASSERT (m_node != 0);
394 
396 
397  NS_ASSERT (tc != 0);
398 
403 
404  tc->RegisterProtocolHandler (MakeCallback (&Ipv4L3Protocol::Receive, this),
406  tc->RegisterProtocolHandler (MakeCallback (&ArpL3Protocol::Receive, PeekPointer (GetObject<ArpL3Protocol> ())),
408 
410  interface->SetNode (m_node);
411  interface->SetDevice (device);
412  interface->SetTrafficControl (tc);
413  interface->SetForwarding (m_ipForward);
414  return AddIpv4Interface (interface);
415 }
416 
417 uint32_t
419 {
420  NS_LOG_FUNCTION (this << interface);
421  uint32_t index = m_interfaces.size ();
422  m_interfaces.push_back (interface);
423  m_reverseInterfacesContainer[interface->GetDevice ()] = index;
424  return index;
425 }
426 
428 Ipv4L3Protocol::GetInterface (uint32_t index) const
429 {
430  NS_LOG_FUNCTION (this << index);
431  if (index < m_interfaces.size ())
432  {
433  return m_interfaces[index];
434  }
435  return 0;
436 }
437 
438 uint32_t
440 {
441  NS_LOG_FUNCTION (this);
442  return m_interfaces.size ();
443 }
444 
445 int32_t
447  Ipv4Address address) const
448 {
449  NS_LOG_FUNCTION (this << address);
450  int32_t interface = 0;
451  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
452  i != m_interfaces.end ();
453  i++, interface++)
454  {
455  for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
456  {
457  if ((*i)->GetAddress (j).GetLocal () == address)
458  {
459  return interface;
460  }
461  }
462  }
463 
464  return -1;
465 }
466 
467 int32_t
470  Ipv4Mask mask) const
471 {
472  NS_LOG_FUNCTION (this << address << mask);
473  int32_t interface = 0;
474  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
475  i != m_interfaces.end ();
476  i++, interface++)
477  {
478  for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
479  {
480  if ((*i)->GetAddress (j).GetLocal ().CombineMask (mask) == address.CombineMask (mask))
481  {
482  return interface;
483  }
484  }
485  }
486 
487  return -1;
488 }
489 
490 int32_t
492  Ptr<const NetDevice> device) const
493 {
494  NS_LOG_FUNCTION (this << device);
495 
496  Ipv4InterfaceReverseContainer::const_iterator iter = m_reverseInterfacesContainer.find (device);
497  if (iter != m_reverseInterfacesContainer.end ())
498  {
499  return (*iter).second;
500  }
501 
502  return -1;
503 }
504 
505 bool
507 {
508  NS_LOG_FUNCTION (this << address << iif);
509  // First check the incoming interface for a unicast address match
510  for (uint32_t i = 0; i < GetNAddresses (iif); i++)
511  {
512  Ipv4InterfaceAddress iaddr = GetAddress (iif, i);
513  if (address == iaddr.GetLocal ())
514  {
515  NS_LOG_LOGIC ("For me (destination " << address << " match)");
516  return true;
517  }
518  if (address == iaddr.GetBroadcast ())
519  {
520  NS_LOG_LOGIC ("For me (interface broadcast address)");
521  return true;
522  }
523  }
524 
525  if (address.IsMulticast ())
526  {
527 #ifdef NOTYET
528  if (MulticastCheckGroup (iif, address ))
529 #endif
530  if (true)
531  {
532  NS_LOG_LOGIC ("For me (Ipv4Addr multicast address)");
533  return true;
534  }
535  }
536 
537  if (address.IsBroadcast ())
538  {
539  NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)");
540  return true;
541  }
542 
543  if (GetWeakEsModel ()) // Check other interfaces
544  {
545  for (uint32_t j = 0; j < GetNInterfaces (); j++)
546  {
547  if (j == uint32_t (iif)) continue;
548  for (uint32_t i = 0; i < GetNAddresses (j); i++)
549  {
550  Ipv4InterfaceAddress iaddr = GetAddress (j, i);
551  if (address == iaddr.GetLocal ())
552  {
553  NS_LOG_LOGIC ("For me (destination " << address << " match) on another interface");
554  return true;
555  }
556  // This is a small corner case: match another interface's broadcast address
557  if (address == iaddr.GetBroadcast ())
558  {
559  NS_LOG_LOGIC ("For me (interface broadcast address on another interface)");
560  return true;
561  }
562  }
563  }
564  }
565  return false;
566 }
567 
568 void
569 Ipv4L3Protocol::Receive ( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
570  const Address &to, NetDevice::PacketType packetType)
571 {
572  NS_LOG_FUNCTION (this << device << p << protocol << from << to << packetType);
573 
574  NS_LOG_LOGIC ("Packet from " << from << " received on node " <<
575  m_node->GetId ());
576 
577 
578  int32_t interface = GetInterfaceForDevice(device);
579  NS_ASSERT_MSG (interface != -1, "Received a packet from an interface that is not known to IPv4");
580 
581  Ptr<Packet> packet = p->Copy ();
582 
583  Ptr<Ipv4Interface> ipv4Interface = m_interfaces[interface];
584 
585  if (ipv4Interface->IsUp ())
586  {
587  m_rxTrace (packet, m_node->GetObject<Ipv4> (), interface);
588  }
589  else
590  {
591  NS_LOG_LOGIC ("Dropping received packet -- interface is down");
592  Ipv4Header ipHeader;
593  packet->RemoveHeader (ipHeader);
594  m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ipv4> (), interface);
595  return;
596  }
597 
598  Ipv4Header ipHeader;
599  if (Node::ChecksumEnabled ())
600  {
601  ipHeader.EnableChecksum ();
602  }
603  packet->RemoveHeader (ipHeader);
604 
605  // Trim any residual frame padding from underlying devices
606  if (ipHeader.GetPayloadSize () < packet->GetSize ())
607  {
608  packet->RemoveAtEnd (packet->GetSize () - ipHeader.GetPayloadSize ());
609  }
610 
611  if (!ipHeader.IsChecksumOk ())
612  {
613  NS_LOG_LOGIC ("Dropping received packet -- checksum not ok");
614  m_dropTrace (ipHeader, packet, DROP_BAD_CHECKSUM, m_node->GetObject<Ipv4> (), interface);
615  return;
616  }
617 
618  // the packet is valid, we update the ARP cache entry (if present)
619  Ptr<ArpCache> arpCache = ipv4Interface->GetArpCache ();
620  if (arpCache)
621  {
622  // case one, it's a a direct routing.
623  ArpCache::Entry *entry = arpCache->Lookup (ipHeader.GetSource ());
624  if (entry)
625  {
626  if (entry->IsAlive ())
627  {
628  entry->UpdateSeen ();
629  }
630  }
631  else
632  {
633  // It's not in the direct routing, so it's the router, and it could have multiple IP addresses.
634  // In doubt, update all of them.
635  // Note: it's a confirmed behavior for Linux routers.
636  std::list<ArpCache::Entry *> entryList = arpCache->LookupInverse (from);
637  std::list<ArpCache::Entry *>::iterator iter;
638  for (iter = entryList.begin (); iter != entryList.end (); iter ++)
639  {
640  if ((*iter)->IsAlive ())
641  {
642  (*iter)->UpdateSeen ();
643  }
644  }
645  }
646  }
647 
648  for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
649  {
650  NS_LOG_LOGIC ("Forwarding to raw socket");
651  Ptr<Ipv4RawSocketImpl> socket = *i;
652  socket->ForwardUp (packet, ipHeader, ipv4Interface);
653  }
654 
655  if (m_enableDpd && ipHeader.GetDestination ().IsMulticast () && UpdateDuplicate (packet, ipHeader))
656  {
657  NS_LOG_LOGIC ("Dropping received packet -- duplicate.");
658  m_dropTrace (ipHeader, packet, DROP_DUPLICATE, m_node->GetObject<Ipv4> (), interface);
659  return;
660  }
661 
662  NS_ASSERT_MSG (m_routingProtocol != 0, "Need a routing protocol object to process packets");
663  if (!m_routingProtocol->RouteInput (packet, ipHeader, device,
668  ))
669  {
670  NS_LOG_WARN ("No route found for forwarding packet. Drop.");
671  m_dropTrace (ipHeader, packet, DROP_NO_ROUTE, m_node->GetObject<Ipv4> (), interface);
672  }
673 }
674 
677 {
678  NS_LOG_FUNCTION (this);
680  if (prot != 0)
681  {
682  return prot->GetObject<Icmpv4L4Protocol> ();
683  }
684  else
685  {
686  return 0;
687  }
688 }
689 
690 bool
692 {
693  NS_LOG_FUNCTION (this << ad);
694 
695  if (ad.IsBroadcast () || ad.IsMulticast ())
696  {
697  return false;
698  }
699  else
700  {
701  // check for subnet-broadcast
702  for (uint32_t ifaceIndex = 0; ifaceIndex < GetNInterfaces (); ifaceIndex++)
703  {
704  for (uint32_t j = 0; j < GetNAddresses (ifaceIndex); j++)
705  {
706  Ipv4InterfaceAddress ifAddr = GetAddress (ifaceIndex, j);
707  NS_LOG_LOGIC ("Testing address " << ad << " with subnet-directed broadcast " << ifAddr.GetBroadcast () );
708  if (ad == ifAddr.GetBroadcast () )
709  {
710  return false;
711  }
712  }
713  }
714  }
715 
716  return true;
717 }
718 
719 bool
721 {
722  NS_LOG_FUNCTION (this << ad << interfaceMask);
723  return !ad.IsMulticast () && !ad.IsSubnetDirectedBroadcast (interfaceMask);
724 }
725 
726 void
728  Ipv4Header ipHeader,
729  Ptr<Ipv4Route> route)
730 {
731  NS_LOG_FUNCTION (this << packet << ipHeader << route);
732  if (Node::ChecksumEnabled ())
733  {
734  ipHeader.EnableChecksum ();
735  }
736  SendRealOut (route, packet, ipHeader);
737 }
738 
739 void
741  Ptr<Ipv4> ipv4, uint32_t interface)
742 {
743  Ptr<Packet> packetCopy = packet->Copy ();
744  packetCopy->AddHeader (ipHeader);
745  m_txTrace (packetCopy, ipv4, interface);
746 }
747 
748 void
750  Ipv4Address source,
751  Ipv4Address destination,
752  uint8_t protocol,
753  Ptr<Ipv4Route> route)
754 {
755  NS_LOG_FUNCTION (this << packet << source << destination << uint32_t (protocol) << route);
756 
757  Ipv4Header ipHeader;
758  bool mayFragment = true;
759  uint8_t ttl = m_defaultTtl;
760  SocketIpTtlTag tag;
761  bool found = packet->RemovePacketTag (tag);
762  if (found)
763  {
764  ttl = tag.GetTtl ();
765  }
766 
767  uint8_t tos = 0;
768  SocketIpTosTag ipTosTag;
769  found = packet->RemovePacketTag (ipTosTag);
770  if (found)
771  {
772  tos = ipTosTag.GetTos ();
773  }
774 
775  // Handle a few cases:
776  // 1) packet is destined to limited broadcast address
777  // 2) packet is destined to a subnet-directed broadcast address
778  // 3) packet is not broadcast, and is passed in with a route entry
779  // 4) packet is not broadcast, and is passed in with a route entry but route->GetGateway is not set (e.g., on-demand)
780  // 5) packet is not broadcast, and route is NULL (e.g., a raw socket call, or ICMP)
781 
782  // 1) packet is destined to limited broadcast address or link-local multicast address
783  if (destination.IsBroadcast () || destination.IsLocalMulticast ())
784  {
785  NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 1: limited broadcast");
786  ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tos, mayFragment);
787  uint32_t ifaceIndex = 0;
788  for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
789  ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
790  {
791  Ptr<Ipv4Interface> outInterface = *ifaceIter;
792  bool sendIt = false;
793  if (source == Ipv4Address::GetAny ())
794  {
795  sendIt = true;
796  }
797  for (uint32_t index = 0; index < outInterface->GetNAddresses (); index++)
798  {
799  if (outInterface->GetAddress (index).GetLocal () == source)
800  {
801  sendIt = true;
802  }
803  }
804  if (sendIt)
805  {
806  Ptr<Packet> packetCopy = packet->Copy ();
807 
808  NS_ASSERT (packetCopy->GetSize () <= outInterface->GetDevice ()->GetMtu ());
809 
810  m_sendOutgoingTrace (ipHeader, packetCopy, ifaceIndex);
811  CallTxTrace (ipHeader, packetCopy, m_node->GetObject<Ipv4> (), ifaceIndex);
812  outInterface->Send (packetCopy, ipHeader, destination);
813  }
814  }
815  return;
816  }
817 
818  // 2) check: packet is destined to a subnet-directed broadcast address
819  uint32_t ifaceIndex = 0;
820  for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
821  ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
822  {
823  Ptr<Ipv4Interface> outInterface = *ifaceIter;
824  for (uint32_t j = 0; j < GetNAddresses (ifaceIndex); j++)
825  {
826  Ipv4InterfaceAddress ifAddr = GetAddress (ifaceIndex, j);
827  NS_LOG_LOGIC ("Testing address " << ifAddr.GetLocal () << " with mask " << ifAddr.GetMask ());
828  if (destination.IsSubnetDirectedBroadcast (ifAddr.GetMask ()) &&
829  destination.CombineMask (ifAddr.GetMask ()) == ifAddr.GetLocal ().CombineMask (ifAddr.GetMask ()) )
830  {
831  NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 2: subnet directed bcast to " << ifAddr.GetLocal ());
832  ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tos, mayFragment);
833  Ptr<Packet> packetCopy = packet->Copy ();
834  m_sendOutgoingTrace (ipHeader, packetCopy, ifaceIndex);
835  CallTxTrace (ipHeader, packetCopy, m_node->GetObject<Ipv4> (), ifaceIndex);
836  outInterface->Send (packetCopy, ipHeader, destination);
837  return;
838  }
839  }
840  }
841 
842  // 3) packet is not broadcast, and is passed in with a route entry
843  // with a valid Ipv4Address as the gateway
844  if (route && route->GetGateway () != Ipv4Address ())
845  {
846  NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 3: passed in with route");
847  ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tos, mayFragment);
848  int32_t interface = GetInterfaceForDevice (route->GetOutputDevice ());
849  m_sendOutgoingTrace (ipHeader, packet, interface);
850  SendRealOut (route, packet->Copy (), ipHeader);
851  return;
852  }
853  // 4) packet is not broadcast, and is passed in with a route entry but route->GetGateway is not set (e.g., on-demand)
854  if (route && route->GetGateway () == Ipv4Address ())
855  {
856  // This could arise because the synchronous RouteOutput() call
857  // returned to the transport protocol with a source address but
858  // there was no next hop available yet (since a route may need
859  // to be queried).
860  NS_FATAL_ERROR ("Ipv4L3Protocol::Send case 4: This case not yet implemented");
861  }
862  // 5) packet is not broadcast, and route is NULL (e.g., a raw socket call)
863  NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 5: passed in with no route " << destination);
864  Socket::SocketErrno errno_;
865  Ptr<NetDevice> oif (0); // unused for now
866  ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tos, mayFragment);
867  Ptr<Ipv4Route> newRoute;
868  if (m_routingProtocol != 0)
869  {
870  newRoute = m_routingProtocol->RouteOutput (packet, ipHeader, oif, errno_);
871  }
872  else
873  {
874  NS_LOG_ERROR ("Ipv4L3Protocol::Send: m_routingProtocol == 0");
875  }
876  if (newRoute)
877  {
878  int32_t interface = GetInterfaceForDevice (newRoute->GetOutputDevice ());
879  m_sendOutgoingTrace (ipHeader, packet, interface);
880  SendRealOut (newRoute, packet->Copy (), ipHeader);
881  }
882  else
883  {
884  NS_LOG_WARN ("No route to host. Drop.");
885  m_dropTrace (ipHeader, packet, DROP_NO_ROUTE, m_node->GetObject<Ipv4> (), 0);
886  }
887 }
888 
889 // \todo when should we set ip_id? check whether we are incrementing
890 // m_identification on packets that may later be dropped in this stack
891 // and whether that deviates from Linux
894  Ipv4Address source,
895  Ipv4Address destination,
896  uint8_t protocol,
897  uint16_t payloadSize,
898  uint8_t ttl,
899  uint8_t tos,
900  bool mayFragment)
901 {
902  NS_LOG_FUNCTION (this << source << destination << (uint16_t)protocol << payloadSize << (uint16_t)ttl << (uint16_t)tos << mayFragment);
903  Ipv4Header ipHeader;
904  ipHeader.SetSource (source);
905  ipHeader.SetDestination (destination);
906  ipHeader.SetProtocol (protocol);
907  ipHeader.SetPayloadSize (payloadSize);
908  ipHeader.SetTtl (ttl);
909  ipHeader.SetTos (tos);
910 
911  uint64_t src = source.Get ();
912  uint64_t dst = destination.Get ();
913  uint64_t srcDst = dst | (src << 32);
914  std::pair<uint64_t, uint8_t> key = std::make_pair (srcDst, protocol);
915 
916  if (mayFragment == true)
917  {
918  ipHeader.SetMayFragment ();
919  ipHeader.SetIdentification (m_identification[key]);
920  m_identification[key]++;
921  }
922  else
923  {
924  ipHeader.SetDontFragment ();
925  // RFC 6864 does not state anything about atomic datagrams
926  // identification requirement:
927  // >> Originating sources MAY set the IPv4 ID field of atomic datagrams
928  // to any value.
929  ipHeader.SetIdentification (m_identification[key]);
930  m_identification[key]++;
931  }
932  if (Node::ChecksumEnabled ())
933  {
934  ipHeader.EnableChecksum ();
935  }
936  return ipHeader;
937 }
938 
939 void
941  Ptr<Packet> packet,
942  Ipv4Header const &ipHeader)
943 {
944  NS_LOG_FUNCTION (this << route << packet << &ipHeader);
945  if (route == 0)
946  {
947  NS_LOG_WARN ("No route to host. Drop.");
948  m_dropTrace (ipHeader, packet, DROP_NO_ROUTE, m_node->GetObject<Ipv4> (), 0);
949  return;
950  }
951  Ptr<NetDevice> outDev = route->GetOutputDevice ();
952  int32_t interface = GetInterfaceForDevice (outDev);
953  NS_ASSERT (interface >= 0);
954  Ptr<Ipv4Interface> outInterface = GetInterface (interface);
955  NS_LOG_LOGIC ("Send via NetDevice ifIndex " << outDev->GetIfIndex () << " ipv4InterfaceIndex " << interface);
956 
957  if (!route->GetGateway ().IsEqual (Ipv4Address ("0.0.0.0")))
958  {
959  if (outInterface->IsUp ())
960  {
961  NS_LOG_LOGIC ("Send to gateway " << route->GetGateway ());
962  if ( packet->GetSize () + ipHeader.GetSerializedSize () > outInterface->GetDevice ()->GetMtu () )
963  {
964  std::list<Ipv4PayloadHeaderPair> listFragments;
965  DoFragmentation (packet, ipHeader, outInterface->GetDevice ()->GetMtu (), listFragments);
966  for ( std::list<Ipv4PayloadHeaderPair>::iterator it = listFragments.begin (); it != listFragments.end (); it++ )
967  {
968  CallTxTrace (it->second, it->first, m_node->GetObject<Ipv4> (), interface);
969  outInterface->Send (it->first, it->second, route->GetGateway ());
970  }
971  }
972  else
973  {
974  CallTxTrace (ipHeader, packet, m_node->GetObject<Ipv4> (), interface);
975  outInterface->Send (packet, ipHeader, route->GetGateway ());
976  }
977  }
978  else
979  {
980  NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << route->GetGateway ());
981  m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ipv4> (), interface);
982  }
983  }
984  else
985  {
986  if (outInterface->IsUp ())
987  {
988  NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestination ());
989  if ( packet->GetSize () + ipHeader.GetSerializedSize () > outInterface->GetDevice ()->GetMtu () )
990  {
991  std::list<Ipv4PayloadHeaderPair> listFragments;
992  DoFragmentation (packet, ipHeader, outInterface->GetDevice ()->GetMtu (), listFragments);
993  for ( std::list<Ipv4PayloadHeaderPair>::iterator it = listFragments.begin (); it != listFragments.end (); it++ )
994  {
995  NS_LOG_LOGIC ("Sending fragment " << *(it->first) );
996  CallTxTrace (it->second, it->first, m_node->GetObject<Ipv4> (), interface);
997  outInterface->Send (it->first, it->second, ipHeader.GetDestination ());
998  }
999  }
1000  else
1001  {
1002  CallTxTrace (ipHeader, packet, m_node->GetObject<Ipv4> (), interface);
1003  outInterface->Send (packet, ipHeader, ipHeader.GetDestination ());
1004  }
1005  }
1006  else
1007  {
1008  NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << ipHeader.GetDestination ());
1009  m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ipv4> (), interface);
1010  }
1011  }
1012 }
1013 
1014 // This function analogous to Linux ip_mr_forward()
1015 void
1017 {
1018  NS_LOG_FUNCTION (this << mrtentry << p << header);
1019  NS_LOG_LOGIC ("Multicast forwarding logic for node: " << m_node->GetId ());
1020 
1021  std::map<uint32_t, uint32_t> ttlMap = mrtentry->GetOutputTtlMap ();
1022  std::map<uint32_t, uint32_t>::iterator mapIter;
1023 
1024  for (mapIter = ttlMap.begin (); mapIter != ttlMap.end (); mapIter++)
1025  {
1026  uint32_t interfaceId = mapIter->first;
1027  //uint32_t outputTtl = mapIter->second; // Unused for now
1028 
1029  Ptr<Packet> packet = p->Copy ();
1030  Ipv4Header h = header;
1031  h.SetTtl (header.GetTtl () - 1);
1032  if (h.GetTtl () == 0)
1033  {
1034  NS_LOG_WARN ("TTL exceeded. Drop.");
1035  m_dropTrace (header, packet, DROP_TTL_EXPIRED, m_node->GetObject<Ipv4> (), interfaceId);
1036  return;
1037  }
1038  NS_LOG_LOGIC ("Forward multicast via interface " << interfaceId);
1039  Ptr<Ipv4Route> rtentry = Create<Ipv4Route> ();
1040  rtentry->SetSource (h.GetSource ());
1041  rtentry->SetDestination (h.GetDestination ());
1042  rtentry->SetGateway (Ipv4Address::GetAny ());
1043  rtentry->SetOutputDevice (GetNetDevice (interfaceId));
1044  SendRealOut (rtentry, packet, h);
1045  continue;
1046  }
1047 }
1048 
1049 // This function analogous to Linux ip_forward()
1050 void
1052 {
1053  NS_LOG_FUNCTION (this << rtentry << p << header);
1054  NS_LOG_LOGIC ("Forwarding logic for node: " << m_node->GetId ());
1055  // Forwarding
1056  Ipv4Header ipHeader = header;
1057  Ptr<Packet> packet = p->Copy ();
1058  int32_t interface = GetInterfaceForDevice (rtentry->GetOutputDevice ());
1059  ipHeader.SetTtl (ipHeader.GetTtl () - 1);
1060  if (ipHeader.GetTtl () == 0)
1061  {
1062  // Do not reply to multicast/broadcast IP address
1063  if (ipHeader.GetDestination ().IsBroadcast () == false &&
1064  ipHeader.GetDestination ().IsMulticast () == false)
1065  {
1066  Ptr<Icmpv4L4Protocol> icmp = GetIcmp ();
1067  icmp->SendTimeExceededTtl (ipHeader, packet, false);
1068  }
1069  NS_LOG_WARN ("TTL exceeded. Drop.");
1070  m_dropTrace (header, packet, DROP_TTL_EXPIRED, m_node->GetObject<Ipv4> (), interface);
1071  return;
1072  }
1073  // in case the packet still has a priority tag attached, remove it
1074  SocketPriorityTag priorityTag;
1075  packet->RemovePacketTag (priorityTag);
1076  uint8_t priority = Socket::IpTos2Priority (ipHeader.GetTos ());
1077  // add a priority tag if the priority is not null
1078  if (priority)
1079  {
1080  priorityTag.SetPriority (priority);
1081  packet->AddPacketTag (priorityTag);
1082  }
1083 
1084  m_unicastForwardTrace (ipHeader, packet, interface);
1085  SendRealOut (rtentry, packet, ipHeader);
1086 }
1087 
1088 void
1090 {
1091  NS_LOG_FUNCTION (this << packet << &ip << iif);
1092  Ptr<Packet> p = packet->Copy (); // need to pass a non-const packet up
1093  Ipv4Header ipHeader = ip;
1094 
1095  if ( !ipHeader.IsLastFragment () || ipHeader.GetFragmentOffset () != 0 )
1096  {
1097  NS_LOG_LOGIC ("Received a fragment, processing " << *p );
1098  bool isPacketComplete;
1099  isPacketComplete = ProcessFragment (p, ipHeader, iif);
1100  if ( isPacketComplete == false)
1101  {
1102  return;
1103  }
1104  NS_LOG_LOGIC ("Got last fragment, Packet is complete " << *p );
1105  ipHeader.SetFragmentOffset (0);
1106  ipHeader.SetPayloadSize (p->GetSize ());
1107  }
1108 
1109  m_localDeliverTrace (ipHeader, p, iif);
1110 
1111  Ptr<IpL4Protocol> protocol = GetProtocol (ipHeader.GetProtocol (), iif);
1112  if (protocol != 0)
1113  {
1114  // we need to make a copy in the unlikely event we hit the
1115  // RX_ENDPOINT_UNREACH codepath
1116  Ptr<Packet> copy = p->Copy ();
1117  enum IpL4Protocol::RxStatus status =
1118  protocol->Receive (p, ipHeader, GetInterface (iif));
1119  switch (status) {
1120  case IpL4Protocol::RX_OK:
1121  // fall through
1123  // fall through
1125  break;
1127  if (ipHeader.GetDestination ().IsBroadcast () == true ||
1128  ipHeader.GetDestination ().IsMulticast () == true)
1129  {
1130  break; // Do not reply to broadcast or multicast
1131  }
1132  // Another case to suppress ICMP is a subnet-directed broadcast
1133  bool subnetDirected = false;
1134  for (uint32_t i = 0; i < GetNAddresses (iif); i++)
1135  {
1136  Ipv4InterfaceAddress addr = GetAddress (iif, i);
1137  if (addr.GetLocal ().CombineMask (addr.GetMask ()) == ipHeader.GetDestination ().CombineMask (addr.GetMask ()) &&
1138  ipHeader.GetDestination ().IsSubnetDirectedBroadcast (addr.GetMask ()))
1139  {
1140  subnetDirected = true;
1141  }
1142  }
1143  if (subnetDirected == false)
1144  {
1145  GetIcmp ()->SendDestUnreachPort (ipHeader, copy);
1146  }
1147  }
1148  }
1149 }
1150 
1151 bool
1153 {
1154  NS_LOG_FUNCTION (this << i << address);
1155  Ptr<Ipv4Interface> interface = GetInterface (i);
1156  bool retVal = interface->AddAddress (address);
1157  if (m_routingProtocol != 0)
1158  {
1159  m_routingProtocol->NotifyAddAddress (i, address);
1160  }
1161  return retVal;
1162 }
1163 
1165 Ipv4L3Protocol::GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const
1166 {
1167  NS_LOG_FUNCTION (this << interfaceIndex << addressIndex);
1168  Ptr<Ipv4Interface> interface = GetInterface (interfaceIndex);
1169  return interface->GetAddress (addressIndex);
1170 }
1171 
1172 uint32_t
1173 Ipv4L3Protocol::GetNAddresses (uint32_t interface) const
1174 {
1175  NS_LOG_FUNCTION (this << interface);
1176  Ptr<Ipv4Interface> iface = GetInterface (interface);
1177  return iface->GetNAddresses ();
1178 }
1179 
1180 bool
1181 Ipv4L3Protocol::RemoveAddress (uint32_t i, uint32_t addressIndex)
1182 {
1183  NS_LOG_FUNCTION (this << i << addressIndex);
1184  Ptr<Ipv4Interface> interface = GetInterface (i);
1185  Ipv4InterfaceAddress address = interface->RemoveAddress (addressIndex);
1186  if (address != Ipv4InterfaceAddress ())
1187  {
1188  if (m_routingProtocol != 0)
1189  {
1190  m_routingProtocol->NotifyRemoveAddress (i, address);
1191  }
1192  return true;
1193  }
1194  return false;
1195 }
1196 
1197 bool
1199 {
1200  NS_LOG_FUNCTION (this << i << address);
1201 
1203  {
1204  NS_LOG_WARN ("Cannot remove loopback address.");
1205  return false;
1206  }
1207  Ptr<Ipv4Interface> interface = GetInterface (i);
1208  Ipv4InterfaceAddress ifAddr = interface->RemoveAddress (address);
1209  if (ifAddr != Ipv4InterfaceAddress ())
1210  {
1211  if (m_routingProtocol != 0)
1212  {
1213  m_routingProtocol->NotifyRemoveAddress (i, ifAddr);
1214  }
1215  return true;
1216  }
1217  return false;
1218 }
1219 
1222 {
1223  NS_LOG_FUNCTION (this << interfaceIdx << " " << dest);
1224  if (GetNAddresses (interfaceIdx) == 1) // common case
1225  {
1226  return GetAddress (interfaceIdx, 0).GetLocal ();
1227  }
1228  // no way to determine the scope of the destination, so adopt the
1229  // following rule: pick the first available address (index 0) unless
1230  // a subsequent address is on link (in which case, pick the primary
1231  // address if there are multiple)
1232  Ipv4Address candidate = GetAddress (interfaceIdx, 0).GetLocal ();
1233  for (uint32_t i = 0; i < GetNAddresses (interfaceIdx); i++)
1234  {
1235  Ipv4InterfaceAddress test = GetAddress (interfaceIdx, i);
1236  if (test.GetLocal ().CombineMask (test.GetMask ()) == dest.CombineMask (test.GetMask ()))
1237  {
1238  if (test.IsSecondary () == false)
1239  {
1240  return test.GetLocal ();
1241  }
1242  }
1243  }
1244  return candidate;
1245 }
1246 
1247 Ipv4Address
1250 {
1251  NS_LOG_FUNCTION (this << device << dst << scope);
1252  Ipv4Address addr ("0.0.0.0");
1253  Ipv4InterfaceAddress iaddr;
1254  bool found = false;
1255 
1256  if (device != 0)
1257  {
1258  int32_t i = GetInterfaceForDevice (device);
1259  NS_ASSERT_MSG (i >= 0, "No device found on node");
1260  for (uint32_t j = 0; j < GetNAddresses (i); j++)
1261  {
1262  iaddr = GetAddress (i, j);
1263  if (iaddr.IsSecondary ()) continue;
1264  if (iaddr.GetScope () > scope) continue;
1265  if (dst.CombineMask (iaddr.GetMask ()) == iaddr.GetLocal ().CombineMask (iaddr.GetMask ()) )
1266  {
1267  return iaddr.GetLocal ();
1268  }
1269  if (!found)
1270  {
1271  addr = iaddr.GetLocal ();
1272  found = true;
1273  }
1274  }
1275  }
1276  if (found)
1277  {
1278  return addr;
1279  }
1280 
1281  // Iterate among all interfaces
1282  for (uint32_t i = 0; i < GetNInterfaces (); i++)
1283  {
1284  for (uint32_t j = 0; j < GetNAddresses (i); j++)
1285  {
1286  iaddr = GetAddress (i, j);
1287  if (iaddr.IsSecondary ()) continue;
1288  if (iaddr.GetScope () != Ipv4InterfaceAddress::LINK
1289  && iaddr.GetScope () <= scope)
1290  {
1291  return iaddr.GetLocal ();
1292  }
1293  }
1294  }
1295  NS_LOG_WARN ("Could not find source address for " << dst << " and scope "
1296  << scope << ", returning 0");
1297  return addr;
1298 }
1299 
1300 void
1301 Ipv4L3Protocol::SetMetric (uint32_t i, uint16_t metric)
1302 {
1303  NS_LOG_FUNCTION (this << i << metric);
1304  Ptr<Ipv4Interface> interface = GetInterface (i);
1305  interface->SetMetric (metric);
1306 }
1307 
1308 uint16_t
1309 Ipv4L3Protocol::GetMetric (uint32_t i) const
1310 {
1311  NS_LOG_FUNCTION (this << i);
1312  Ptr<Ipv4Interface> interface = GetInterface (i);
1313  return interface->GetMetric ();
1314 }
1315 
1316 uint16_t
1317 Ipv4L3Protocol::GetMtu (uint32_t i) const
1318 {
1319  NS_LOG_FUNCTION (this << i);
1320  Ptr<Ipv4Interface> interface = GetInterface (i);
1321  return interface->GetDevice ()->GetMtu ();
1322 }
1323 
1324 bool
1325 Ipv4L3Protocol::IsUp (uint32_t i) const
1326 {
1327  NS_LOG_FUNCTION (this << i);
1328  Ptr<Ipv4Interface> interface = GetInterface (i);
1329  return interface->IsUp ();
1330 }
1331 
1332 void
1334 {
1335  NS_LOG_FUNCTION (this << i);
1336  Ptr<Ipv4Interface> interface = GetInterface (i);
1337 
1338  // RFC 791, pg.25:
1339  // Every internet module must be able to forward a datagram of 68
1340  // octets without further fragmentation. This is because an internet
1341  // header may be up to 60 octets, and the minimum fragment is 8 octets.
1342  if (interface->GetDevice ()->GetMtu () >= 68)
1343  {
1344  interface->SetUp ();
1345 
1346  if (m_routingProtocol != 0)
1347  {
1348  m_routingProtocol->NotifyInterfaceUp (i);
1349  }
1350  }
1351  else
1352  {
1353  NS_LOG_LOGIC ("Interface " << int(i) << " is set to be down for IPv4. Reason: not respecting minimum IPv4 MTU (68 octects)");
1354  }
1355 }
1356 
1357 void
1358 Ipv4L3Protocol::SetDown (uint32_t ifaceIndex)
1359 {
1360  NS_LOG_FUNCTION (this << ifaceIndex);
1361  Ptr<Ipv4Interface> interface = GetInterface (ifaceIndex);
1362  interface->SetDown ();
1363 
1364  if (m_routingProtocol != 0)
1365  {
1366  m_routingProtocol->NotifyInterfaceDown (ifaceIndex);
1367  }
1368 }
1369 
1370 bool
1372 {
1373  NS_LOG_FUNCTION (this << i);
1374  Ptr<Ipv4Interface> interface = GetInterface (i);
1375  NS_LOG_LOGIC ("Forwarding state: " << interface->IsForwarding ());
1376  return interface->IsForwarding ();
1377 }
1378 
1379 void
1380 Ipv4L3Protocol::SetForwarding (uint32_t i, bool val)
1381 {
1382  NS_LOG_FUNCTION (this << i);
1383  Ptr<Ipv4Interface> interface = GetInterface (i);
1384  interface->SetForwarding (val);
1385 }
1386 
1389 {
1390  NS_LOG_FUNCTION (this << i);
1391  return GetInterface (i)->GetDevice ();
1392 }
1393 
1394 void
1396 {
1397  NS_LOG_FUNCTION (this << forward);
1398  m_ipForward = forward;
1399  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
1400  {
1401  (*i)->SetForwarding (forward);
1402  }
1403 }
1404 
1405 bool
1407 {
1408  NS_LOG_FUNCTION (this);
1409  return m_ipForward;
1410 }
1411 
1412 void
1414 {
1415  NS_LOG_FUNCTION (this << model);
1416  m_weakEsModel = model;
1417 }
1418 
1419 bool
1421 {
1422  NS_LOG_FUNCTION (this);
1423  return m_weakEsModel;
1424 }
1425 
1426 void
1428 {
1429  NS_LOG_FUNCTION (this << p << ipHeader << sockErrno);
1430  NS_LOG_LOGIC ("Route input failure-- dropping packet to " << ipHeader << " with errno " << sockErrno);
1431  m_dropTrace (ipHeader, p, DROP_ROUTE_ERROR, m_node->GetObject<Ipv4> (), 0);
1432 
1433  // \todo Send an ICMP no route.
1434 }
1435 
1436 void
1437 Ipv4L3Protocol::DoFragmentation (Ptr<Packet> packet, const Ipv4Header & ipv4Header, uint32_t outIfaceMtu, std::list<Ipv4PayloadHeaderPair>& listFragments)
1438 {
1439  // BEWARE: here we do assume that the header options are not present.
1440  // a much more complex handling is necessary in case there are options.
1441  // If (when) IPv4 option headers will be implemented, the following code shall be changed.
1442  // Of course also the reassemby code shall be changed as well.
1443 
1444  NS_LOG_FUNCTION (this << *packet << outIfaceMtu << &listFragments);
1445 
1446  Ptr<Packet> p = packet->Copy ();
1447 
1448  NS_ASSERT_MSG( (ipv4Header.GetSerializedSize() == 5*4),
1449  "IPv4 fragmentation implementation only works without option headers." );
1450 
1451  uint16_t offset = 0;
1452  bool moreFragment = true;
1453  uint16_t originalOffset = ipv4Header.GetFragmentOffset();
1454  bool isLastFragment = ipv4Header.IsLastFragment();
1455  uint32_t currentFragmentablePartSize = 0;
1456 
1457  // IPv4 fragments are all 8 bytes aligned but the last.
1458  // The IP payload size is:
1459  // floor( ( outIfaceMtu - ipv4Header.GetSerializedSize() ) /8 ) *8
1460  uint32_t fragmentSize = (outIfaceMtu - ipv4Header.GetSerializedSize () ) & ~uint32_t (0x7);
1461 
1462  NS_LOG_LOGIC ("Fragmenting - Target Size: " << fragmentSize );
1463 
1464  do
1465  {
1466  Ipv4Header fragmentHeader = ipv4Header;
1467 
1468  if (p->GetSize () > offset + fragmentSize )
1469  {
1470  moreFragment = true;
1471  currentFragmentablePartSize = fragmentSize;
1472  fragmentHeader.SetMoreFragments ();
1473  }
1474  else
1475  {
1476  moreFragment = false;
1477  currentFragmentablePartSize = p->GetSize () - offset;
1478  if (!isLastFragment)
1479  {
1480  fragmentHeader.SetMoreFragments ();
1481  }
1482  else
1483  {
1484  fragmentHeader.SetLastFragment ();
1485  }
1486  }
1487 
1488  NS_LOG_LOGIC ("Fragment creation - " << offset << ", " << currentFragmentablePartSize );
1489  Ptr<Packet> fragment = p->CreateFragment (offset, currentFragmentablePartSize);
1490  NS_LOG_LOGIC ("Fragment created - " << offset << ", " << fragment->GetSize () );
1491 
1492  fragmentHeader.SetFragmentOffset (offset+originalOffset);
1493  fragmentHeader.SetPayloadSize (currentFragmentablePartSize);
1494 
1495  if (Node::ChecksumEnabled ())
1496  {
1497  fragmentHeader.EnableChecksum ();
1498  }
1499 
1500  NS_LOG_LOGIC ("Fragment check - " << fragmentHeader.GetFragmentOffset () );
1501 
1502  NS_LOG_LOGIC ("New fragment Header " << fragmentHeader);
1503 
1504  std::ostringstream oss;
1505  oss << fragmentHeader;
1506  fragment->Print (oss);
1507 
1508  NS_LOG_LOGIC ("New fragment " << *fragment);
1509 
1510  listFragments.push_back (Ipv4PayloadHeaderPair (fragment, fragmentHeader));
1511 
1512  offset += currentFragmentablePartSize;
1513 
1514  }
1515  while (moreFragment);
1516 
1517  return;
1518 }
1519 
1520 bool
1521 Ipv4L3Protocol::ProcessFragment (Ptr<Packet>& packet, Ipv4Header& ipHeader, uint32_t iif)
1522 {
1523  NS_LOG_FUNCTION (this << packet << ipHeader << iif);
1524 
1525  uint64_t addressCombination = uint64_t (ipHeader.GetSource ().Get ()) << 32 | uint64_t (ipHeader.GetDestination ().Get ());
1526  uint32_t idProto = uint32_t (ipHeader.GetIdentification ()) << 16 | uint32_t (ipHeader.GetProtocol ());
1527  std::pair<uint64_t, uint32_t> key;
1528  bool ret = false;
1529  Ptr<Packet> p = packet->Copy ();
1530 
1531  key.first = addressCombination;
1532  key.second = idProto;
1533 
1534  Ptr<Fragments> fragments;
1535 
1536  MapFragments_t::iterator it = m_fragments.find (key);
1537  if (it == m_fragments.end ())
1538  {
1539  fragments = Create<Fragments> ();
1540  m_fragments.insert (std::make_pair (key, fragments));
1543  key, ipHeader, iif);
1544  }
1545  else
1546  {
1547  fragments = it->second;
1548  }
1549 
1550  NS_LOG_LOGIC ("Adding fragment - Size: " << packet->GetSize ( ) << " - Offset: " << (ipHeader.GetFragmentOffset ()) );
1551 
1552  fragments->AddFragment (p, ipHeader.GetFragmentOffset (), !ipHeader.IsLastFragment () );
1553 
1554  if ( fragments->IsEntire () )
1555  {
1556  packet = fragments->GetPacket ();
1557  fragments = 0;
1558  m_fragments.erase (key);
1559  if (m_fragmentsTimers[key].IsRunning ())
1560  {
1561  NS_LOG_LOGIC ("Stopping WaitFragmentsTimer at " << Simulator::Now ().GetSeconds () << " due to complete packet");
1562  m_fragmentsTimers[key].Cancel ();
1563  }
1564  m_fragmentsTimers.erase (key);
1565  ret = true;
1566  }
1567 
1568  return ret;
1569 }
1570 
1572  : m_moreFragment (0)
1573 {
1574  NS_LOG_FUNCTION (this);
1575 }
1576 
1578 {
1579  NS_LOG_FUNCTION (this);
1580 }
1581 
1582 void
1583 Ipv4L3Protocol::Fragments::AddFragment (Ptr<Packet> fragment, uint16_t fragmentOffset, bool moreFragment)
1584 {
1585  NS_LOG_FUNCTION (this << fragment << fragmentOffset << moreFragment);
1586 
1587  std::list<std::pair<Ptr<Packet>, uint16_t> >::iterator it;
1588 
1589  for (it = m_fragments.begin (); it != m_fragments.end (); it++)
1590  {
1591  if (it->second > fragmentOffset)
1592  {
1593  break;
1594  }
1595  }
1596 
1597  if (it == m_fragments.end ())
1598  {
1599  m_moreFragment = moreFragment;
1600  }
1601 
1602  m_fragments.insert (it, std::pair<Ptr<Packet>, uint16_t> (fragment, fragmentOffset));
1603 }
1604 
1605 bool
1607 {
1608  NS_LOG_FUNCTION (this);
1609 
1610  bool ret = !m_moreFragment && m_fragments.size () > 0;
1611 
1612  if (ret)
1613  {
1614  uint16_t lastEndOffset = 0;
1615 
1616  for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
1617  {
1618  // overlapping fragments do exist
1619  NS_LOG_LOGIC ("Checking overlaps " << lastEndOffset << " - " << it->second );
1620 
1621  if (lastEndOffset < it->second)
1622  {
1623  ret = false;
1624  break;
1625  }
1626  // fragments might overlap in strange ways
1627  uint16_t fragmentEnd = it->first->GetSize () + it->second;
1628  lastEndOffset = std::max ( lastEndOffset, fragmentEnd );
1629  }
1630  }
1631 
1632  return ret;
1633 }
1634 
1637 {
1638  NS_LOG_FUNCTION (this);
1639 
1640  std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin ();
1641 
1642  Ptr<Packet> p = it->first->Copy ();
1643  uint16_t lastEndOffset = p->GetSize ();
1644  it++;
1645 
1646  for ( ; it != m_fragments.end (); it++)
1647  {
1648  if ( lastEndOffset > it->second )
1649  {
1650  // The fragments are overlapping.
1651  // We do not overwrite the "old" with the "new" because we do not know when each arrived.
1652  // This is different from what Linux does.
1653  // It is not possible to emulate a fragmentation attack.
1654  uint32_t newStart = lastEndOffset - it->second;
1655  if ( it->first->GetSize () > newStart )
1656  {
1657  uint32_t newSize = it->first->GetSize () - newStart;
1658  Ptr<Packet> tempFragment = it->first->CreateFragment (newStart, newSize);
1659  p->AddAtEnd (tempFragment);
1660  }
1661  }
1662  else
1663  {
1664  NS_LOG_LOGIC ("Adding: " << *(it->first) );
1665  p->AddAtEnd (it->first);
1666  }
1667  lastEndOffset = p->GetSize ();
1668  }
1669 
1670  return p;
1671 }
1672 
1675 {
1676  NS_LOG_FUNCTION (this);
1677 
1678  std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin ();
1679 
1680  Ptr<Packet> p = Create<Packet> ();
1681  uint16_t lastEndOffset = 0;
1682 
1683  if ( m_fragments.begin ()->second > 0 )
1684  {
1685  return p;
1686  }
1687 
1688  for ( it = m_fragments.begin (); it != m_fragments.end (); it++)
1689  {
1690  if ( lastEndOffset > it->second )
1691  {
1692  uint32_t newStart = lastEndOffset - it->second;
1693  uint32_t newSize = it->first->GetSize () - newStart;
1694  Ptr<Packet> tempFragment = it->first->CreateFragment (newStart, newSize);
1695  p->AddAtEnd (tempFragment);
1696  }
1697  else if ( lastEndOffset == it->second )
1698  {
1699  NS_LOG_LOGIC ("Adding: " << *(it->first) );
1700  p->AddAtEnd (it->first);
1701  }
1702  lastEndOffset = p->GetSize ();
1703  }
1704 
1705  return p;
1706 }
1707 
1708 void
1709 Ipv4L3Protocol::HandleFragmentsTimeout (std::pair<uint64_t, uint32_t> key, Ipv4Header & ipHeader, uint32_t iif)
1710 {
1711  NS_LOG_FUNCTION (this << &key << &ipHeader << iif);
1712 
1713  MapFragments_t::iterator it = m_fragments.find (key);
1714  Ptr<Packet> packet = it->second->GetPartialPacket ();
1715 
1716  // if we have at least 8 bytes, we can send an ICMP.
1717  if ( packet->GetSize () > 8 )
1718  {
1719  Ptr<Icmpv4L4Protocol> icmp = GetIcmp ();
1720  icmp->SendTimeExceededTtl (ipHeader, packet, true);
1721  }
1722  m_dropTrace (ipHeader, packet, DROP_FRAGMENT_TIMEOUT, m_node->GetObject<Ipv4> (), iif);
1723 
1724  // clear the buffers
1725  it->second = 0;
1726 
1727  m_fragments.erase (key);
1728  m_fragmentsTimers.erase (key);
1729 }
1730 
1731 bool
1733 {
1734  NS_LOG_FUNCTION (this << p << header);
1735 
1736  // \todo RFC 6621 mandates SHA-1 hash. For now ns3 hash should be fine.
1737  uint8_t proto = header.GetProtocol ();
1738  Ipv4Address src = header.GetSource ();
1739  Ipv4Address dst = header.GetDestination ();
1740  uint64_t id = header.GetIdentification ();
1741 
1742  // concat hash value onto id
1743  uint64_t hash = id << 32;
1744  if (header.GetFragmentOffset () || !header.IsLastFragment ())
1745  {
1746  // use I-DPD (RFC 6621, Sec 6.2.1)
1747  hash |= header.GetFragmentOffset ();
1748  }
1749  else
1750  {
1751  // use H-DPD (RFC 6621, Sec 6.2.2)
1752 
1753  // serialize packet
1754  Ptr<Packet> pkt = p->Copy ();
1755  pkt->AddHeader (header);
1756 
1757  std::ostringstream oss (std::ios_base::binary);
1758  pkt->CopyData (&oss, pkt->GetSize ());
1759  std::string bytes = oss.str ();
1760 
1761  NS_ASSERT_MSG (bytes.size () >= 20, "Degenerate header serialization");
1762 
1763  // zero out mutable fields
1764  bytes[1] = 0; // DSCP / ECN
1765  bytes[6] = bytes[7] = 0; // Flags / Fragment offset
1766  bytes[8] = 0; // TTL
1767  bytes[10] = bytes[11] = 0; // Header checksum
1768  if (header.GetSerializedSize () > 20) // assume options should be 0'd
1769  {
1770  std::fill_n (bytes.begin () + 20, header.GetSerializedSize () - 20, 0);
1771  }
1772 
1773  // concat hash onto ID
1774  hash |= (uint64_t)Hash32 (bytes);
1775  }
1776 
1777  // set cleanup job for new duplicate entries
1779  {
1781  }
1782 
1783  // assume this is a new entry
1784  DupTuple_t key {hash, proto, src, dst};
1785  NS_LOG_DEBUG ("Packet " << p->GetUid () << " key = (" <<
1786  std::hex << std::get<0> (key) << ", " <<
1787  std::dec << +std::get<1> (key) << ", " <<
1788  std::get<2> (key) << ", " <<
1789  std::get<3> (key) << ")");
1790 
1791  // place a new entry, on collision the existing entry iterator is returned
1792  DupMap_t::iterator iter;
1793  bool inserted, isDup;
1794  std::tie (iter, inserted) = m_dups.emplace (key, Seconds (0));
1795  isDup = !inserted && iter->second > Simulator::Now ();
1796 
1797  // set the expiration event
1798  iter->second = Simulator::Now () + m_expire;
1799  return isDup;
1800 }
1801 
1802 void
1804 {
1805  NS_LOG_FUNCTION (this);
1806 
1807  DupMap_t::size_type n = 0;
1808  Time expire = Simulator::Now ();
1809  auto iter = m_dups.cbegin ();
1810  while (iter != m_dups.cend ())
1811  {
1812  if (iter->second < expire)
1813  {
1814  NS_LOG_LOGIC ("Remove key = (" <<
1815  std::hex << std::get<0> (iter->first) << ", " <<
1816  std::dec << +std::get<1> (iter->first) << ", " <<
1817  std::get<2> (iter->first) << ", " <<
1818  std::get<3> (iter->first) << ")");
1819  iter = m_dups.erase (iter);
1820  ++n;
1821  }
1822  else
1823  {
1824  ++iter;
1825  }
1826  }
1827 
1828  NS_LOG_DEBUG ("Purged " << n << " expired duplicate entries out of " << (n + m_dups.size ()));
1829 
1830  // keep cleaning up if necessary
1831  if (!m_dups.empty () && m_purge.IsStrictlyPositive ())
1832  {
1834  }
1835 }
1836 
1837 
1838 } // namespace ns3
virtual Ipv4Address SourceAddressSelection(uint32_t interface, Ipv4Address dest)
Choose the source address to use with destination address.
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:285
void SetDown(void)
Disable this interface.
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
uint8_t GetTos(void) const
Get the tag&#39;s TOS.
Definition: socket.cc:791
void SetPayloadSize(uint16_t size)
Definition: ipv4-header.cc:56
bool m_weakEsModel
Weak ES model state.
void SetForwarding(bool val)
uint64_t GetUid(void) const
Returns the packet&#39;s Uid.
Definition: packet.cc:390
void SetDefaultTtl(uint8_t ttl)
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
virtual void SetIpForward(bool forward)
Set or unset the IP forwarding state.
void Receive(Ptr< NetDevice > device, Ptr< const Packet > p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
Receive a packet.
void Send(Ptr< Packet > p, const Ipv4Header &hdr, Ipv4Address dest)
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:298
static Ipv4Address GetAny(void)
void Print(std::ostream &os) const
Print the packet contents.
Definition: packet.cc:434
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
uint32_t GetNAddresses(uint32_t interface) const
bool IsDestinationAddress(Ipv4Address address, uint32_t iif) const
Determine whether address and interface corresponding to received packet can be accepted for local de...
virtual void NotifyNewAggregate()
This function will notify other components connected to the node that a new stack member is now conne...
AttributeValue implementation for Boolean.
Definition: boolean.h:36
Time m_fragmentExpirationTimeout
Expiration timeout.
Definition: second.py:1
uint32_t GetId(void) const
Definition: node.cc:107
bool IsBroadcast(void) const
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
Introspection did not find any typical Config paths.
TracedCallback< const Ipv4Header &, Ptr< const Packet >, uint32_t > m_sendOutgoingTrace
Trace of sent packets.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:258
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:142
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:84
static bool ChecksumEnabled(void)
Definition: node.cc:276
ArpCache::Entry * Lookup(Ipv4Address destination)
Do lookup in the ARP cache against an IP address.
Definition: arp-cache.cc:318
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
The IPv4 representation of a network interface.
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-vector.h:81
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
Definition: packet.cc:227
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:564
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:204
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1070
void SetNode(Ptr< Node > node)
Set the node associated with this socket.
DupMap_t m_dups
map of packet duplicate tuples to expiry event
void SetFragmentOffset(uint16_t offsetBytes)
The offset is measured in bytes for the packet start.
Definition: ipv4-header.cc:238
bool IsLastFragment(void) const
Definition: ipv4-header.cc:212
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
bool IsStrictlyPositive(void) const
Definition: nstime.h:308
void RemoveDuplicates(void)
Remove duplicate packet entry.
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
virtual void Receive(Ptr< NetDevice > device, Ptr< const Packet > p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
Called by NetDevices, incoming packet.
bool AddAddress(Ipv4InterfaceAddress address)
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:278
uint32_t AddInterface(Ptr< NetDevice > device)
TracedCallback< const Ipv4Header &, Ptr< const Packet >, DropReason, Ptr< Ipv4 >, uint32_t > m_dropTrace
Trace of dropped packets.
bool IsEntire() const
If all fragments have been added.
static uint8_t IpTos2Priority(uint8_t ipTos)
Return the priority corresponding to a given TOS value.
Definition: socket.cc:402
int32_t GetInterfaceForAddress(Ipv4Address addr) const
Return the interface number of the interface that has been assigned the specified IP address...
virtual int GetProtocolNumber(void) const =0
Returns the protocol number of this protocol.
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer...
Definition: socket.h:1115
void SetDontFragment(void)
Don&#39;t fragment this packet: if you need to anyway, drop it.
Definition: ipv4-header.cc:219
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
virtual bool GetIpForward(void) const
Get the IP forwarding state.
bool IsAlive(void)
Definition: arp-cache.cc:375
Ipv4InterfaceAddress GetAddress(uint32_t index) const
Ptr< Ipv4RoutingProtocol > m_routingProtocol
Routing protocol associated with the stack.
uint32_t GetNInterfaces(void) const
void SetUp(uint32_t i)
L4List_t m_protocols
List of transport protocol.
void SetNode(Ptr< Node > node)
Set node associated with interface.
a polymophic address class
Definition: address.h:90
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Ptr< Packet > GetPartialPacket() const
Get the complete part of the packet.
bool m_enableDpd
Enable multicast duplicate packet detection.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
uint8_t GetProtocol(void) const
Definition: ipv4-header.cc:272
void SetSource(Ipv4Address src)
Definition: ipv4-route.cc:49
Ipv4InterfaceList m_interfaces
List of IPv4 interfaces.
TracedCallback< Ptr< const Packet >, Ptr< Ipv4 >, uint32_t > m_rxTrace
Trace of received packets.
Packet header for IPv4.
Definition: ipv4-header.h:33
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:335
bool IsMulticast(void) const
std::tuple< uint64_t, uint8_t, Ipv4Address, Ipv4Address > DupTuple_t
IETF RFC 6621, Section 6.2 de-duplication w/o IPSec RFC 6621 recommended duplicate packet tuple: {IPV...
void SetLastFragment(void)
This packet is the last packet of a fragmented ipv4 packet.
Definition: ipv4-header.cc:206
Ptr< Icmpv4L4Protocol > GetIcmp(void) const
Get ICMPv4 protocol.
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1389
#define max(a, b)
Definition: 80211b.c:43
bool IsSubnetDirectedBroadcast(Ipv4Mask const &mask) const
Generate subnet-directed broadcast address corresponding to mask.
void SetupLoopback(void)
Setup loopback interface.
Ipv4Address CombineMask(Ipv4Mask const &mask) const
Combine this address with a network mask.
AttributeValue implementation for Time.
Definition: nstime.h:1124
bool IsUnicast(Ipv4Address ad) const
Check if an IPv4 address is unicast according to the node.
void SetGateway(Ipv4Address gw)
Definition: ipv4-route.cc:63
TracedCallback< Ptr< const Packet >, Ptr< Ipv4 >, uint32_t > m_txTrace
Trace of transmitted packets.
Hold an unsigned integer type.
Definition: uinteger.h:44
TracedCallback< const Ipv4Header &, Ptr< const Packet >, uint32_t > m_localDeliverTrace
Trace of locally delivered packets.
void EnableChecksum(void)
Enable checksum calculation for this header.
Definition: ipv4-header.cc:49
Ptr< Ipv4Interface > GetInterface(uint32_t i) const
Get an interface.
void SetMetric(uint32_t i, uint16_t metric)
virtual void DoDispose(void)
Destructor implementation.
EventId m_cleanDpd
event to cleanup expired duplicate entries
indicates whether the socket has a priority set.
Definition: socket.h:1307
void CallTxTrace(const Ipv4Header &ipHeader, Ptr< Packet > packet, Ptr< Ipv4 > ipv4, uint32_t interface)
Make a copy of the packet, add the header and invoke the TX trace callback.
virtual uint32_t GetSerializedSize(void) const
Definition: ipv4-header.cc:375
bool IsLocalMulticast(void) const
virtual bool GetWeakEsModel(void) const
Get the Weak Es Model status.
Ptr< Socket > CreateRawSocket(void)
Creates a raw socket.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
virtual enum RxStatus Receive(Ptr< Packet > p, Ipv4Header const &header, Ptr< Ipv4Interface > incomingInterface)=0
Called from lower-level layers to send the packet up in the stack.
void SetIdentification(uint16_t identification)
Definition: ipv4-header.cc:75
void Send(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol, Ptr< Ipv4Route > route)
void SetMayFragment(void)
If you need to fragment this packet, you can do it.
Definition: ipv4-header.cc:225
static TypeId GetTypeId(void)
Get the type ID.
Ipv4Address GetBroadcast(void) const
Get the broadcast address.
MapFragments_t m_fragments
Fragmented packets.
Ipv4Mask GetMask(void) const
Get the network mask.
void SendWithHeader(Ptr< Packet > packet, Ipv4Header ipHeader, Ptr< Ipv4Route > route)
uint16_t GetFragmentOffset(void) const
Definition: ipv4-header.cc:246
void IpForward(Ptr< Ipv4Route > rtentry, Ptr< const Packet > p, const Ipv4Header &header)
Forward a packet.
Ptr< Ipv4RoutingProtocol > GetRoutingProtocol(void) const
Get the routing protocol to be used by this Ipv4 stack.
#define list
bool RemoveAddress(uint32_t interfaceIndex, uint32_t addressIndex)
Remove the address at addressIndex on named interface.
int32_t GetInterfaceForPrefix(Ipv4Address addr, Ipv4Mask mask) const
Return the interface number of first interface found that has an Ipv4 address within the prefix speci...
void AddFragment(Ptr< Packet > fragment, uint16_t fragmentOffset, bool moreFragment)
Add a fragment.
bool UpdateDuplicate(Ptr< const Packet > p, const Ipv4Header &header)
Registers duplicate entry, return false if new.
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:76
bool m_ipForward
Forwarding packets (i.e.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:459
void SetForwarding(uint32_t i, bool val)
void DoFragmentation(Ptr< Packet > packet, const Ipv4Header &ipv4Header, uint32_t outIfaceMtu, std::list< Ipv4PayloadHeaderPair > &listFragments)
Fragment a packet.
Time m_expire
duplicate entry expiration delay
Implement the IPv4 layer.
Ptr< NetDevice > GetOutputDevice(void) const
Definition: ipv4-route.cc:84
static const uint16_t PROT_NUMBER
ARP protocol number (0x0806)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::pair< Ptr< Packet >, Ipv4Header > Ipv4PayloadHeaderPair
Pair of a packet and an Ipv4 header.
address
Definition: first.py:37
uint32_t Hash32(const char *buffer, const std::size_t size)
Compute 32-bit hash of a byte buffer, using the default hash function.
Definition: hash.h:276
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
Ptr< NetDevice > GetDevice(void) const
void SetMoreFragments(void)
This packet is not the last packet of a fragmented ipv4 packet.
Definition: ipv4-header.cc:200
Ptr< ArpCache > GetArpCache() const
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
void RemoveAtEnd(uint32_t size)
Remove size bytes from the end of the current packet.
Definition: packet.cc:355
std::pair< int, int32_t > L4ListKey_t
Container of the IPv4 L4 keys: protocol number, interface index.
void SetTos(uint8_t tos)
Definition: ipv4-header.cc:82
Time m_purge
time between purging expired duplicate entries
bool IsForwarding(uint32_t i) const
Ptr< Node > m_node
Node attached to stack.
void RouteInputError(Ptr< const Packet > p, const Ipv4Header &ipHeader, Socket::SocketErrno sockErrno)
Fallback when no route is found.
Ipv4Header BuildHeader(Ipv4Address source, Ipv4Address destination, uint8_t protocol, uint16_t payloadSize, uint8_t ttl, uint8_t tos, bool mayFragment)
Construct an IPv4 header.
void SendRealOut(Ptr< Ipv4Route > route, Ptr< Packet > packet, Ipv4Header const &ipHeader)
Send packet with route.
A record that that holds information about an ArpCache entry.
Definition: arp-cache.h:188
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:1125
Ipv4InterfaceAddress::InterfaceAddressScope_e GetScope(void) const
Get address scope.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:193
void SetOutputDevice(Ptr< NetDevice > outputDevice)
Equivalent in Linux to dst_entry.dev.
Definition: ipv4-route.cc:77
static Ipv4Address GetLoopback(void)
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
static Ipv4Mask GetLoopback(void)
bool IsUp(void) const
These are IP interface states and may be distinct from NetDevice states, such as found in real implem...
Ipv4Address GetGateway(void) const
Definition: ipv4-route.cc:70
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:227
Ptr< NetDevice > GetNetDevice(uint32_t i)
uint8_t GetTtl(void) const
Definition: ipv4-header.cc:265
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
void UpdateSeen(void)
Update the entry when seeing a packet.
Definition: arp-cache.cc:532
bool ProcessFragment(Ptr< Packet > &packet, Ipv4Header &ipHeader, uint32_t iif)
Process a packet fragment.
uint32_t AddIpv4Interface(Ptr< Ipv4Interface > interface)
Add an IPv4 interface to the stack.
uint16_t GetMetric(uint32_t i) const
uint16_t GetMetric(void) const
virtual void Remove(Ptr< IpL4Protocol > protocol)
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
virtual void SetWeakEsModel(bool model)
Set or unset the Weak Es Model.
void SetNode(Ptr< Node > node)
Set node associated with this stack.
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:128
int32_t GetInterfaceForDevice(Ptr< const NetDevice > device) const
a class to store IPv4 address information on an interface
Ptr< Packet > GetPacket() const
Get the entire packet.
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:863
SocketList m_sockets
List of IPv4 raw sockets.
void DeleteRawSocket(Ptr< Socket > socket)
Deletes a particular raw socket.
bool AddAddress(uint32_t i, Ipv4InterfaceAddress address)
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:264
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:378
static uint16_t GetStaticProtocolNumber(void)
Get the protocol number.
virtual void Insert(Ptr< IpL4Protocol > protocol)
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:870
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:272
void LocalDeliver(Ptr< const Packet > p, Ipv4Header const &ip, uint32_t iif)
Deliver a packet.
void IpMulticastForward(Ptr< Ipv4MulticastRoute > mrtentry, Ptr< const Packet > p, const Ipv4Header &header)
Forward a multicast packet.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1062
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:65
MapFragmentsTimers_t m_fragmentsTimers
Expiration events.
void SetTtl(uint8_t ttl)
Definition: ipv4-header.cc:259
Ipv4InterfaceAddress GetAddress(uint32_t interfaceIndex, uint32_t addressIndex) const
Because addresses can be removed, the addressIndex is not guaranteed to be static across calls to thi...
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 after calling L3Demux::Lookup The ARP subclass needs to know from which...
bool ForwardUp(Ptr< const Packet > p, Ipv4Header ipHeader, Ptr< Ipv4Interface > incomingInterface)
Forward up to receive method.
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
bool IsSecondary(void) const
Check if the address is a secondary address.
Ipv4Address GetLocal(void) const
Get the local address.
uint8_t m_defaultTtl
Default TTL.
bool IsChecksumOk(void) const
Definition: ipv4-header.cc:312
uint16_t GetPayloadSize(void) const
Definition: ipv4-header.cc:62
Ptr< T > CreateObject(void)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:528
Interface is down so can not send packet.
void SetMetric(uint16_t metric)
RxStatus
Rx status codes.
std::list< ArpCache::Entry * > LookupInverse(Address destination)
Do lookup in the ARP cache against a MAC address.
Definition: arp-cache.cc:300
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:256
uint32_t Get(void) const
Get the host-order 32-bit IP address.
uint32_t GetNAddresses(void) const
uint16_t GetMtu(uint32_t i) const
virtual void NotifyNewAggregate(void)
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:325
bool IsEqual(const Ipv4Address &other) const
Comparison operation between two Ipv4Addresses.
Definition: ipv4-address.h:83
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:296
TracedCallback< const Ipv4Header &, Ptr< const Packet >, uint32_t > m_unicastForwardTrace
Trace of unicast forwarded packets.
Container for a set of ns3::Object pointers.
This is the implementation of the ICMP protocol as described in RFC 792.
uint16_t GetIdentification(void) const
Definition: ipv4-header.cc:69
void SetPriority(uint8_t priority)
Set the tag&#39;s priority.
Definition: socket.cc:842
Ipv4InterfaceReverseContainer m_reverseInterfacesContainer
Container of NetDevice / Interface index associations.
indicates whether the socket has IP_TOS set.
Definition: socket.h:1261
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: uinteger.h:45
a unique identifier for an interface.
Definition: type-id.h:58
std::map< std::pair< uint64_t, uint8_t >, uint16_t > m_identification
Identification (for each {src, dst, proto} tuple)
Duplicate packet received.
bool IsUp(uint32_t i) const
void SetDown(uint32_t i)
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:915
virtual Ptr< IpL4Protocol > GetProtocol(int protocolNumber) const
void HandleFragmentsTimeout(std::pair< uint64_t, uint32_t > key, Ipv4Header &ipHeader, uint32_t iif)
Process the timeout for packet fragments.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
uint8_t GetTtl(void) const
Get the tag&#39;s TTL.
Definition: socket.cc:611
static const uint16_t PROT_NUMBER
Protocol number (0x0800)
void SetDestination(Ipv4Address dest)
Definition: ipv4-route.cc:35
uint32_t GetNDevices(void) const
Definition: node.cc:150
void SetUp(void)
Enable this interface.
Ipv4Address SelectSourceAddress(Ptr< const NetDevice > device, Ipv4Address dst, Ipv4InterfaceAddress::InterfaceAddressScope_e scope)
Return the first primary source address with scope less than or equal to the requested scope...
void SetRoutingProtocol(Ptr< Ipv4RoutingProtocol > routingProtocol)
Register a new routing protocol to be used by this Ipv4 stack.