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