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 AggregateObject 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 
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> ();
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 
380 
381  tc->RegisterProtocolHandler (MakeCallback (&Ipv4L3Protocol::Receive, this),
383  tc->RegisterProtocolHandler (MakeCallback (&ArpL3Protocol::Receive, PeekPointer (GetObject<ArpL3Protocol> ())),
385 
387  interface->SetNode (m_node);
388  interface->SetDevice (device);
389  interface->SetTrafficControl (tc);
390  interface->SetForwarding (m_ipForward);
391  return AddIpv4Interface (interface);
392 }
393 
394 uint32_t
396 {
397  NS_LOG_FUNCTION (this << interface);
398  uint32_t index = m_interfaces.size ();
399  m_interfaces.push_back (interface);
400  m_reverseInterfacesContainer[interface->GetDevice ()] = index;
401  return index;
402 }
403 
405 Ipv4L3Protocol::GetInterface (uint32_t index) const
406 {
407  NS_LOG_FUNCTION (this << index);
408  if (index < m_interfaces.size ())
409  {
410  return m_interfaces[index];
411  }
412  return 0;
413 }
414 
415 uint32_t
417 {
418  NS_LOG_FUNCTION (this);
419  return m_interfaces.size ();
420 }
421 
422 int32_t
424  Ipv4Address address) const
425 {
426  NS_LOG_FUNCTION (this << address);
427  int32_t interface = 0;
428  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
429  i != m_interfaces.end ();
430  i++, interface++)
431  {
432  for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
433  {
434  if ((*i)->GetAddress (j).GetLocal () == address)
435  {
436  return interface;
437  }
438  }
439  }
440 
441  return -1;
442 }
443 
444 int32_t
447  Ipv4Mask mask) const
448 {
449  NS_LOG_FUNCTION (this << address << mask);
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 ().CombineMask (mask) == address.CombineMask (mask))
458  {
459  return interface;
460  }
461  }
462  }
463 
464  return -1;
465 }
466 
467 int32_t
469  Ptr<const NetDevice> device) const
470 {
471  NS_LOG_FUNCTION (this << device);
472 
473  Ipv4InterfaceReverseContainer::const_iterator iter = m_reverseInterfacesContainer.find (device);
474  if (iter != m_reverseInterfacesContainer.end ())
475  {
476  return (*iter).second;
477  }
478 
479  return -1;
480 }
481 
482 bool
484 {
485  NS_LOG_FUNCTION (this << address << iif);
486  // First check the incoming interface for a unicast address match
487  for (uint32_t i = 0; i < GetNAddresses (iif); i++)
488  {
489  Ipv4InterfaceAddress iaddr = GetAddress (iif, i);
490  if (address == iaddr.GetLocal ())
491  {
492  NS_LOG_LOGIC ("For me (destination " << address << " match)");
493  return true;
494  }
495  if (address == iaddr.GetBroadcast ())
496  {
497  NS_LOG_LOGIC ("For me (interface broadcast address)");
498  return true;
499  }
500  }
501 
502  if (address.IsMulticast ())
503  {
504 #ifdef NOTYET
505  if (MulticastCheckGroup (iif, address ))
506 #endif
507  if (true)
508  {
509  NS_LOG_LOGIC ("For me (Ipv4Addr multicast address");
510  return true;
511  }
512  }
513 
514  if (address.IsBroadcast ())
515  {
516  NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)");
517  return true;
518  }
519 
520  if (GetWeakEsModel ()) // Check other interfaces
521  {
522  for (uint32_t j = 0; j < GetNInterfaces (); j++)
523  {
524  if (j == uint32_t (iif)) continue;
525  for (uint32_t i = 0; i < GetNAddresses (j); i++)
526  {
527  Ipv4InterfaceAddress iaddr = GetAddress (j, i);
528  if (address == iaddr.GetLocal ())
529  {
530  NS_LOG_LOGIC ("For me (destination " << address << " match) on another interface");
531  return true;
532  }
533  // This is a small corner case: match another interface's broadcast address
534  if (address == iaddr.GetBroadcast ())
535  {
536  NS_LOG_LOGIC ("For me (interface broadcast address on another interface)");
537  return true;
538  }
539  }
540  }
541  }
542  return false;
543 }
544 
545 void
546 Ipv4L3Protocol::Receive ( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
547  const Address &to, NetDevice::PacketType packetType)
548 {
549  NS_LOG_FUNCTION (this << device << p << protocol << from << to << packetType);
550 
551  NS_LOG_LOGIC ("Packet from " << from << " received on node " <<
552  m_node->GetId ());
553 
554 
555  int32_t interface = GetInterfaceForDevice(device);
556  NS_ASSERT_MSG (interface != -1, "Received a packet from an interface that is not known to IPv4");
557 
558  Ptr<Packet> packet = p->Copy ();
559 
560  Ptr<Ipv4Interface> ipv4Interface = m_interfaces[interface];
561 
562  if (ipv4Interface->IsUp ())
563  {
564  m_rxTrace (packet, m_node->GetObject<Ipv4> (), interface);
565  }
566  else
567  {
568  NS_LOG_LOGIC ("Dropping received packet -- interface is down");
569  Ipv4Header ipHeader;
570  packet->RemoveHeader (ipHeader);
571  m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ipv4> (), interface);
572  return;
573  }
574 
575  Ipv4Header ipHeader;
576  if (Node::ChecksumEnabled ())
577  {
578  ipHeader.EnableChecksum ();
579  }
580  packet->RemoveHeader (ipHeader);
581 
582  // Trim any residual frame padding from underlying devices
583  if (ipHeader.GetPayloadSize () < packet->GetSize ())
584  {
585  packet->RemoveAtEnd (packet->GetSize () - ipHeader.GetPayloadSize ());
586  }
587 
588  if (!ipHeader.IsChecksumOk ())
589  {
590  NS_LOG_LOGIC ("Dropping received packet -- checksum not ok");
591  m_dropTrace (ipHeader, packet, DROP_BAD_CHECKSUM, m_node->GetObject<Ipv4> (), interface);
592  return;
593  }
594 
595  // the packet is valid, we update the ARP cache entry (if present)
596  Ptr<ArpCache> arpCache = ipv4Interface->GetArpCache ();
597  if (arpCache)
598  {
599  // case one, it's a a direct routing.
600  ArpCache::Entry *entry = arpCache->Lookup (ipHeader.GetSource ());
601  if (entry)
602  {
603  if (entry->IsAlive ())
604  {
605  entry->UpdateSeen ();
606  }
607  }
608  else
609  {
610  // It's not in the direct routing, so it's the router, and it could have multiple IP addresses.
611  // In doubt, update all of them.
612  // Note: it's a confirmed behavior for Linux routers.
613  std::list<ArpCache::Entry *> entryList = arpCache->LookupInverse (from);
614  std::list<ArpCache::Entry *>::iterator iter;
615  for (iter = entryList.begin (); iter != entryList.end (); iter ++)
616  {
617  if ((*iter)->IsAlive ())
618  {
619  (*iter)->UpdateSeen ();
620  }
621  }
622  }
623  }
624 
625  for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
626  {
627  NS_LOG_LOGIC ("Forwarding to raw socket");
628  Ptr<Ipv4RawSocketImpl> socket = *i;
629  socket->ForwardUp (packet, ipHeader, ipv4Interface);
630  }
631 
632  NS_ASSERT_MSG (m_routingProtocol != 0, "Need a routing protocol object to process packets");
633  if (!m_routingProtocol->RouteInput (packet, ipHeader, device,
638  ))
639  {
640  NS_LOG_WARN ("No route found for forwarding packet. Drop.");
641  m_dropTrace (ipHeader, packet, DROP_NO_ROUTE, m_node->GetObject<Ipv4> (), interface);
642  }
643 }
644 
647 {
648  NS_LOG_FUNCTION (this);
650  if (prot != 0)
651  {
652  return prot->GetObject<Icmpv4L4Protocol> ();
653  }
654  else
655  {
656  return 0;
657  }
658 }
659 
660 bool
662 {
663  NS_LOG_FUNCTION (this << ad);
664 
665  if (ad.IsBroadcast () || ad.IsMulticast ())
666  {
667  return false;
668  }
669  else
670  {
671  // check for subnet-broadcast
672  for (uint32_t ifaceIndex = 0; ifaceIndex < GetNInterfaces (); ifaceIndex++)
673  {
674  for (uint32_t j = 0; j < GetNAddresses (ifaceIndex); j++)
675  {
676  Ipv4InterfaceAddress ifAddr = GetAddress (ifaceIndex, j);
677  NS_LOG_LOGIC ("Testing address " << ad << " with subnet-directed broadcast " << ifAddr.GetBroadcast () );
678  if (ad == ifAddr.GetBroadcast () )
679  {
680  return false;
681  }
682  }
683  }
684  }
685 
686  return true;
687 }
688 
689 bool
691 {
692  NS_LOG_FUNCTION (this << ad << interfaceMask);
693  return !ad.IsMulticast () && !ad.IsSubnetDirectedBroadcast (interfaceMask);
694 }
695 
696 void
698  Ipv4Header ipHeader,
699  Ptr<Ipv4Route> route)
700 {
701  NS_LOG_FUNCTION (this << packet << ipHeader << route);
702  if (Node::ChecksumEnabled ())
703  {
704  ipHeader.EnableChecksum ();
705  }
706  SendRealOut (route, packet, ipHeader);
707 }
708 
709 void
711  Ptr<Ipv4> ipv4, uint32_t interface)
712 {
713  Ptr<Packet> packetCopy = packet->Copy ();
714  packetCopy->AddHeader (ipHeader);
715  m_txTrace (packetCopy, ipv4, interface);
716 }
717 
718 void
720  Ipv4Address source,
721  Ipv4Address destination,
722  uint8_t protocol,
723  Ptr<Ipv4Route> route)
724 {
725  NS_LOG_FUNCTION (this << packet << source << destination << uint32_t (protocol) << route);
726 
727  Ipv4Header ipHeader;
728  bool mayFragment = true;
729  uint8_t ttl = m_defaultTtl;
730  SocketIpTtlTag tag;
731  bool found = packet->RemovePacketTag (tag);
732  if (found)
733  {
734  ttl = tag.GetTtl ();
735  }
736 
737  uint8_t tos = 0;
738  SocketIpTosTag ipTosTag;
739  found = packet->RemovePacketTag (ipTosTag);
740  if (found)
741  {
742  tos = ipTosTag.GetTos ();
743  }
744 
745  // Handle a few cases:
746  // 1) packet is destined to limited broadcast address
747  // 2) packet is destined to a subnet-directed broadcast address
748  // 3) packet is not broadcast, and is passed in with a route entry
749  // 4) packet is not broadcast, and is passed in with a route entry but route->GetGateway is not set (e.g., on-demand)
750  // 5) packet is not broadcast, and route is NULL (e.g., a raw socket call, or ICMP)
751 
752  // 1) packet is destined to limited broadcast address or link-local multicast address
753  if (destination.IsBroadcast () || destination.IsLocalMulticast ())
754  {
755  NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 1: limited broadcast");
756  ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tos, mayFragment);
757  uint32_t ifaceIndex = 0;
758  for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
759  ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
760  {
761  Ptr<Ipv4Interface> outInterface = *ifaceIter;
762  bool sendIt = false;
763  if (source == Ipv4Address::GetAny ())
764  {
765  sendIt = true;
766  }
767  for (uint32_t index = 0; index < outInterface->GetNAddresses (); index++)
768  {
769  if (outInterface->GetAddress (index).GetLocal () == source)
770  {
771  sendIt = true;
772  }
773  }
774  if (sendIt)
775  {
776  Ptr<Packet> packetCopy = packet->Copy ();
777 
778  NS_ASSERT (packetCopy->GetSize () <= outInterface->GetDevice ()->GetMtu ());
779 
780  m_sendOutgoingTrace (ipHeader, packetCopy, ifaceIndex);
781  CallTxTrace (ipHeader, packetCopy, m_node->GetObject<Ipv4> (), ifaceIndex);
782  outInterface->Send (packetCopy, ipHeader, destination);
783  }
784  }
785  return;
786  }
787 
788  // 2) check: packet is destined to a subnet-directed broadcast address
789  uint32_t ifaceIndex = 0;
790  for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
791  ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
792  {
793  Ptr<Ipv4Interface> outInterface = *ifaceIter;
794  for (uint32_t j = 0; j < GetNAddresses (ifaceIndex); j++)
795  {
796  Ipv4InterfaceAddress ifAddr = GetAddress (ifaceIndex, j);
797  NS_LOG_LOGIC ("Testing address " << ifAddr.GetLocal () << " with mask " << ifAddr.GetMask ());
798  if (destination.IsSubnetDirectedBroadcast (ifAddr.GetMask ()) &&
799  destination.CombineMask (ifAddr.GetMask ()) == ifAddr.GetLocal ().CombineMask (ifAddr.GetMask ()) )
800  {
801  NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 2: subnet directed bcast to " << ifAddr.GetLocal ());
802  ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tos, mayFragment);
803  Ptr<Packet> packetCopy = packet->Copy ();
804  m_sendOutgoingTrace (ipHeader, packetCopy, ifaceIndex);
805  CallTxTrace (ipHeader, packetCopy, m_node->GetObject<Ipv4> (), ifaceIndex);
806  outInterface->Send (packetCopy, ipHeader, destination);
807  return;
808  }
809  }
810  }
811 
812  // 3) packet is not broadcast, and is passed in with a route entry
813  // with a valid Ipv4Address as the gateway
814  if (route && route->GetGateway () != Ipv4Address ())
815  {
816  NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 3: passed in with route");
817  ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tos, mayFragment);
818  int32_t interface = GetInterfaceForDevice (route->GetOutputDevice ());
819  m_sendOutgoingTrace (ipHeader, packet, interface);
820  SendRealOut (route, packet->Copy (), ipHeader);
821  return;
822  }
823  // 4) packet is not broadcast, and is passed in with a route entry but route->GetGateway is not set (e.g., on-demand)
824  if (route && route->GetGateway () == Ipv4Address ())
825  {
826  // This could arise because the synchronous RouteOutput() call
827  // returned to the transport protocol with a source address but
828  // there was no next hop available yet (since a route may need
829  // to be queried).
830  NS_FATAL_ERROR ("Ipv4L3Protocol::Send case 4: This case not yet implemented");
831  }
832  // 5) packet is not broadcast, and route is NULL (e.g., a raw socket call)
833  NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 5: passed in with no route " << destination);
834  Socket::SocketErrno errno_;
835  Ptr<NetDevice> oif (0); // unused for now
836  ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tos, mayFragment);
837  Ptr<Ipv4Route> newRoute;
838  if (m_routingProtocol != 0)
839  {
840  newRoute = m_routingProtocol->RouteOutput (packet, ipHeader, oif, errno_);
841  }
842  else
843  {
844  NS_LOG_ERROR ("Ipv4L3Protocol::Send: m_routingProtocol == 0");
845  }
846  if (newRoute)
847  {
848  int32_t interface = GetInterfaceForDevice (newRoute->GetOutputDevice ());
849  m_sendOutgoingTrace (ipHeader, packet, interface);
850  SendRealOut (newRoute, packet->Copy (), ipHeader);
851  }
852  else
853  {
854  NS_LOG_WARN ("No route to host. Drop.");
855  m_dropTrace (ipHeader, packet, DROP_NO_ROUTE, m_node->GetObject<Ipv4> (), 0);
856  }
857 }
858 
859 // \todo when should we set ip_id? check whether we are incrementing
860 // m_identification on packets that may later be dropped in this stack
861 // and whether that deviates from Linux
864  Ipv4Address source,
865  Ipv4Address destination,
866  uint8_t protocol,
867  uint16_t payloadSize,
868  uint8_t ttl,
869  uint8_t tos,
870  bool mayFragment)
871 {
872  NS_LOG_FUNCTION (this << source << destination << (uint16_t)protocol << payloadSize << (uint16_t)ttl << (uint16_t)tos << mayFragment);
873  Ipv4Header ipHeader;
874  ipHeader.SetSource (source);
875  ipHeader.SetDestination (destination);
876  ipHeader.SetProtocol (protocol);
877  ipHeader.SetPayloadSize (payloadSize);
878  ipHeader.SetTtl (ttl);
879  ipHeader.SetTos (tos);
880 
881  uint64_t src = source.Get ();
882  uint64_t dst = destination.Get ();
883  uint64_t srcDst = dst | (src << 32);
884  std::pair<uint64_t, uint8_t> key = std::make_pair (srcDst, protocol);
885 
886  if (mayFragment == true)
887  {
888  ipHeader.SetMayFragment ();
889  ipHeader.SetIdentification (m_identification[key]);
890  m_identification[key]++;
891  }
892  else
893  {
894  ipHeader.SetDontFragment ();
895  // RFC 6864 does not state anything about atomic datagrams
896  // identification requirement:
897  // >> Originating sources MAY set the IPv4 ID field of atomic datagrams
898  // to any value.
899  ipHeader.SetIdentification (m_identification[key]);
900  m_identification[key]++;
901  }
902  if (Node::ChecksumEnabled ())
903  {
904  ipHeader.EnableChecksum ();
905  }
906  return ipHeader;
907 }
908 
909 void
911  Ptr<Packet> packet,
912  Ipv4Header const &ipHeader)
913 {
914  NS_LOG_FUNCTION (this << route << packet << &ipHeader);
915  if (route == 0)
916  {
917  NS_LOG_WARN ("No route to host. Drop.");
918  m_dropTrace (ipHeader, packet, DROP_NO_ROUTE, m_node->GetObject<Ipv4> (), 0);
919  return;
920  }
921  Ptr<NetDevice> outDev = route->GetOutputDevice ();
922  int32_t interface = GetInterfaceForDevice (outDev);
923  NS_ASSERT (interface >= 0);
924  Ptr<Ipv4Interface> outInterface = GetInterface (interface);
925  NS_LOG_LOGIC ("Send via NetDevice ifIndex " << outDev->GetIfIndex () << " ipv4InterfaceIndex " << interface);
926 
927  if (!route->GetGateway ().IsEqual (Ipv4Address ("0.0.0.0")))
928  {
929  if (outInterface->IsUp ())
930  {
931  NS_LOG_LOGIC ("Send to gateway " << route->GetGateway ());
932  if ( packet->GetSize () + ipHeader.GetSerializedSize () > outInterface->GetDevice ()->GetMtu () )
933  {
934  std::list<Ipv4PayloadHeaderPair> listFragments;
935  DoFragmentation (packet, ipHeader, outInterface->GetDevice ()->GetMtu (), listFragments);
936  for ( std::list<Ipv4PayloadHeaderPair>::iterator it = listFragments.begin (); it != listFragments.end (); it++ )
937  {
938  CallTxTrace (it->second, it->first, m_node->GetObject<Ipv4> (), interface);
939  outInterface->Send (it->first, it->second, route->GetGateway ());
940  }
941  }
942  else
943  {
944  CallTxTrace (ipHeader, packet, m_node->GetObject<Ipv4> (), interface);
945  outInterface->Send (packet, ipHeader, route->GetGateway ());
946  }
947  }
948  else
949  {
950  NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << route->GetGateway ());
951  m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ipv4> (), interface);
952  }
953  }
954  else
955  {
956  if (outInterface->IsUp ())
957  {
958  NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestination ());
959  if ( packet->GetSize () + ipHeader.GetSerializedSize () > outInterface->GetDevice ()->GetMtu () )
960  {
961  std::list<Ipv4PayloadHeaderPair> listFragments;
962  DoFragmentation (packet, ipHeader, outInterface->GetDevice ()->GetMtu (), listFragments);
963  for ( std::list<Ipv4PayloadHeaderPair>::iterator it = listFragments.begin (); it != listFragments.end (); it++ )
964  {
965  NS_LOG_LOGIC ("Sending fragment " << *(it->first) );
966  CallTxTrace (it->second, it->first, m_node->GetObject<Ipv4> (), interface);
967  outInterface->Send (it->first, it->second, ipHeader.GetDestination ());
968  }
969  }
970  else
971  {
972  CallTxTrace (ipHeader, packet, m_node->GetObject<Ipv4> (), interface);
973  outInterface->Send (packet, ipHeader, ipHeader.GetDestination ());
974  }
975  }
976  else
977  {
978  NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << ipHeader.GetDestination ());
979  m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ipv4> (), interface);
980  }
981  }
982 }
983 
984 // This function analogous to Linux ip_mr_forward()
985 void
987 {
988  NS_LOG_FUNCTION (this << mrtentry << p << header);
989  NS_LOG_LOGIC ("Multicast forwarding logic for node: " << m_node->GetId ());
990 
991  std::map<uint32_t, uint32_t> ttlMap = mrtentry->GetOutputTtlMap ();
992  std::map<uint32_t, uint32_t>::iterator mapIter;
993 
994  for (mapIter = ttlMap.begin (); mapIter != ttlMap.end (); mapIter++)
995  {
996  uint32_t interfaceId = mapIter->first;
997  //uint32_t outputTtl = mapIter->second; // Unused for now
998 
999  Ptr<Packet> packet = p->Copy ();
1000  Ipv4Header h = header;
1001  h.SetTtl (header.GetTtl () - 1);
1002  if (h.GetTtl () == 0)
1003  {
1004  NS_LOG_WARN ("TTL exceeded. Drop.");
1005  m_dropTrace (header, packet, DROP_TTL_EXPIRED, m_node->GetObject<Ipv4> (), interfaceId);
1006  return;
1007  }
1008  NS_LOG_LOGIC ("Forward multicast via interface " << interfaceId);
1009  Ptr<Ipv4Route> rtentry = Create<Ipv4Route> ();
1010  rtentry->SetSource (h.GetSource ());
1011  rtentry->SetDestination (h.GetDestination ());
1012  rtentry->SetGateway (Ipv4Address::GetAny ());
1013  rtentry->SetOutputDevice (GetNetDevice (interfaceId));
1014  SendRealOut (rtentry, packet, h);
1015  continue;
1016  }
1017 }
1018 
1019 // This function analogous to Linux ip_forward()
1020 void
1022 {
1023  NS_LOG_FUNCTION (this << rtentry << p << header);
1024  NS_LOG_LOGIC ("Forwarding logic for node: " << m_node->GetId ());
1025  // Forwarding
1026  Ipv4Header ipHeader = header;
1027  Ptr<Packet> packet = p->Copy ();
1028  int32_t interface = GetInterfaceForDevice (rtentry->GetOutputDevice ());
1029  ipHeader.SetTtl (ipHeader.GetTtl () - 1);
1030  if (ipHeader.GetTtl () == 0)
1031  {
1032  // Do not reply to ICMP or to multicast/broadcast IP address
1033  if (ipHeader.GetProtocol () != Icmpv4L4Protocol::PROT_NUMBER &&
1034  ipHeader.GetDestination ().IsBroadcast () == false &&
1035  ipHeader.GetDestination ().IsMulticast () == false)
1036  {
1037  Ptr<Icmpv4L4Protocol> icmp = GetIcmp ();
1038  icmp->SendTimeExceededTtl (ipHeader, packet, false);
1039  }
1040  NS_LOG_WARN ("TTL exceeded. Drop.");
1041  m_dropTrace (header, packet, DROP_TTL_EXPIRED, m_node->GetObject<Ipv4> (), interface);
1042  return;
1043  }
1044  // in case the packet still has a priority tag attached, remove it
1045  SocketPriorityTag priorityTag;
1046  packet->RemovePacketTag (priorityTag);
1047  uint8_t priority = Socket::IpTos2Priority (ipHeader.GetTos ());
1048  // add a priority tag if the priority is not null
1049  if (priority)
1050  {
1051  priorityTag.SetPriority (priority);
1052  packet->AddPacketTag (priorityTag);
1053  }
1054 
1055  m_unicastForwardTrace (ipHeader, packet, interface);
1056  SendRealOut (rtentry, packet, ipHeader);
1057 }
1058 
1059 void
1061 {
1062  NS_LOG_FUNCTION (this << packet << &ip << iif);
1063  Ptr<Packet> p = packet->Copy (); // need to pass a non-const packet up
1064  Ipv4Header ipHeader = ip;
1065 
1066  if ( !ipHeader.IsLastFragment () || ipHeader.GetFragmentOffset () != 0 )
1067  {
1068  NS_LOG_LOGIC ("Received a fragment, processing " << *p );
1069  bool isPacketComplete;
1070  isPacketComplete = ProcessFragment (p, ipHeader, iif);
1071  if ( isPacketComplete == false)
1072  {
1073  return;
1074  }
1075  NS_LOG_LOGIC ("Got last fragment, Packet is complete " << *p );
1076  ipHeader.SetFragmentOffset (0);
1077  ipHeader.SetPayloadSize (p->GetSize ());
1078  }
1079 
1080  m_localDeliverTrace (ipHeader, p, iif);
1081 
1082  Ptr<IpL4Protocol> protocol = GetProtocol (ipHeader.GetProtocol (), iif);
1083  if (protocol != 0)
1084  {
1085  // we need to make a copy in the unlikely event we hit the
1086  // RX_ENDPOINT_UNREACH codepath
1087  Ptr<Packet> copy = p->Copy ();
1088  enum IpL4Protocol::RxStatus status =
1089  protocol->Receive (p, ipHeader, GetInterface (iif));
1090  switch (status) {
1091  case IpL4Protocol::RX_OK:
1092  // fall through
1094  // fall through
1096  break;
1098  if (ipHeader.GetDestination ().IsBroadcast () == true ||
1099  ipHeader.GetDestination ().IsMulticast () == true)
1100  {
1101  break; // Do not reply to broadcast or multicast
1102  }
1103  // Another case to suppress ICMP is a subnet-directed broadcast
1104  bool subnetDirected = false;
1105  for (uint32_t i = 0; i < GetNAddresses (iif); i++)
1106  {
1107  Ipv4InterfaceAddress addr = GetAddress (iif, i);
1108  if (addr.GetLocal ().CombineMask (addr.GetMask ()) == ipHeader.GetDestination ().CombineMask (addr.GetMask ()) &&
1109  ipHeader.GetDestination ().IsSubnetDirectedBroadcast (addr.GetMask ()))
1110  {
1111  subnetDirected = true;
1112  }
1113  }
1114  if (subnetDirected == false)
1115  {
1116  GetIcmp ()->SendDestUnreachPort (ipHeader, copy);
1117  }
1118  }
1119  }
1120 }
1121 
1122 bool
1124 {
1125  NS_LOG_FUNCTION (this << i << address);
1126  Ptr<Ipv4Interface> interface = GetInterface (i);
1127  bool retVal = interface->AddAddress (address);
1128  if (m_routingProtocol != 0)
1129  {
1130  m_routingProtocol->NotifyAddAddress (i, address);
1131  }
1132  return retVal;
1133 }
1134 
1136 Ipv4L3Protocol::GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const
1137 {
1138  NS_LOG_FUNCTION (this << interfaceIndex << addressIndex);
1139  Ptr<Ipv4Interface> interface = GetInterface (interfaceIndex);
1140  return interface->GetAddress (addressIndex);
1141 }
1142 
1143 uint32_t
1144 Ipv4L3Protocol::GetNAddresses (uint32_t interface) const
1145 {
1146  NS_LOG_FUNCTION (this << interface);
1147  Ptr<Ipv4Interface> iface = GetInterface (interface);
1148  return iface->GetNAddresses ();
1149 }
1150 
1151 bool
1152 Ipv4L3Protocol::RemoveAddress (uint32_t i, uint32_t addressIndex)
1153 {
1154  NS_LOG_FUNCTION (this << i << addressIndex);
1155  Ptr<Ipv4Interface> interface = GetInterface (i);
1156  Ipv4InterfaceAddress address = interface->RemoveAddress (addressIndex);
1157  if (address != Ipv4InterfaceAddress ())
1158  {
1159  if (m_routingProtocol != 0)
1160  {
1161  m_routingProtocol->NotifyRemoveAddress (i, address);
1162  }
1163  return true;
1164  }
1165  return false;
1166 }
1167 
1168 bool
1170 {
1171  NS_LOG_FUNCTION (this << i << address);
1172 
1174  {
1175  NS_LOG_WARN ("Cannot remove loopback address.");
1176  return false;
1177  }
1178  Ptr<Ipv4Interface> interface = GetInterface (i);
1179  Ipv4InterfaceAddress ifAddr = interface->RemoveAddress (address);
1180  if (ifAddr != Ipv4InterfaceAddress ())
1181  {
1182  if (m_routingProtocol != 0)
1183  {
1184  m_routingProtocol->NotifyRemoveAddress (i, ifAddr);
1185  }
1186  return true;
1187  }
1188  return false;
1189 }
1190 
1193 {
1194  NS_LOG_FUNCTION (this << interfaceIdx << " " << dest);
1195  if (GetNAddresses (interfaceIdx) == 1) // common case
1196  {
1197  return GetAddress (interfaceIdx, 0).GetLocal ();
1198  }
1199  // no way to determine the scope of the destination, so adopt the
1200  // following rule: pick the first available address (index 0) unless
1201  // a subsequent address is on link (in which case, pick the primary
1202  // address if there are multiple)
1203  Ipv4Address candidate = GetAddress (interfaceIdx, 0).GetLocal ();
1204  for (uint32_t i = 0; i < GetNAddresses (interfaceIdx); i++)
1205  {
1206  Ipv4InterfaceAddress test = GetAddress (interfaceIdx, i);
1207  if (test.GetLocal ().CombineMask (test.GetMask ()) == dest.CombineMask (test.GetMask ()))
1208  {
1209  if (test.IsSecondary () == false)
1210  {
1211  return test.GetLocal ();
1212  }
1213  }
1214  }
1215  return candidate;
1216 }
1217 
1218 Ipv4Address
1221 {
1222  NS_LOG_FUNCTION (this << device << dst << scope);
1223  Ipv4Address addr ("0.0.0.0");
1224  Ipv4InterfaceAddress iaddr;
1225  bool found = false;
1226 
1227  if (device != 0)
1228  {
1229  int32_t i = GetInterfaceForDevice (device);
1230  NS_ASSERT_MSG (i >= 0, "No device found on node");
1231  for (uint32_t j = 0; j < GetNAddresses (i); j++)
1232  {
1233  iaddr = GetAddress (i, j);
1234  if (iaddr.IsSecondary ()) continue;
1235  if (iaddr.GetScope () > scope) continue;
1236  if (dst.CombineMask (iaddr.GetMask ()) == iaddr.GetLocal ().CombineMask (iaddr.GetMask ()) )
1237  {
1238  return iaddr.GetLocal ();
1239  }
1240  if (!found)
1241  {
1242  addr = iaddr.GetLocal ();
1243  found = true;
1244  }
1245  }
1246  }
1247  if (found)
1248  {
1249  return addr;
1250  }
1251 
1252  // Iterate among all interfaces
1253  for (uint32_t i = 0; i < GetNInterfaces (); i++)
1254  {
1255  for (uint32_t j = 0; j < GetNAddresses (i); j++)
1256  {
1257  iaddr = GetAddress (i, j);
1258  if (iaddr.IsSecondary ()) continue;
1259  if (iaddr.GetScope () != Ipv4InterfaceAddress::LINK
1260  && iaddr.GetScope () <= scope)
1261  {
1262  return iaddr.GetLocal ();
1263  }
1264  }
1265  }
1266  NS_LOG_WARN ("Could not find source address for " << dst << " and scope "
1267  << scope << ", returning 0");
1268  return addr;
1269 }
1270 
1271 void
1272 Ipv4L3Protocol::SetMetric (uint32_t i, uint16_t metric)
1273 {
1274  NS_LOG_FUNCTION (this << i << metric);
1275  Ptr<Ipv4Interface> interface = GetInterface (i);
1276  interface->SetMetric (metric);
1277 }
1278 
1279 uint16_t
1280 Ipv4L3Protocol::GetMetric (uint32_t i) const
1281 {
1282  NS_LOG_FUNCTION (this << i);
1283  Ptr<Ipv4Interface> interface = GetInterface (i);
1284  return interface->GetMetric ();
1285 }
1286 
1287 uint16_t
1288 Ipv4L3Protocol::GetMtu (uint32_t i) const
1289 {
1290  NS_LOG_FUNCTION (this << i);
1291  Ptr<Ipv4Interface> interface = GetInterface (i);
1292  return interface->GetDevice ()->GetMtu ();
1293 }
1294 
1295 bool
1296 Ipv4L3Protocol::IsUp (uint32_t i) const
1297 {
1298  NS_LOG_FUNCTION (this << i);
1299  Ptr<Ipv4Interface> interface = GetInterface (i);
1300  return interface->IsUp ();
1301 }
1302 
1303 void
1305 {
1306  NS_LOG_FUNCTION (this << i);
1307  Ptr<Ipv4Interface> interface = GetInterface (i);
1308 
1309  // RFC 791, pg.25:
1310  // Every internet module must be able to forward a datagram of 68
1311  // octets without further fragmentation. This is because an internet
1312  // header may be up to 60 octets, and the minimum fragment is 8 octets.
1313  if (interface->GetDevice ()->GetMtu () >= 68)
1314  {
1315  interface->SetUp ();
1316 
1317  if (m_routingProtocol != 0)
1318  {
1319  m_routingProtocol->NotifyInterfaceUp (i);
1320  }
1321  }
1322  else
1323  {
1324  NS_LOG_LOGIC ("Interface " << int(i) << " is set to be down for IPv4. Reason: not respecting minimum IPv4 MTU (68 octects)");
1325  }
1326 }
1327 
1328 void
1329 Ipv4L3Protocol::SetDown (uint32_t ifaceIndex)
1330 {
1331  NS_LOG_FUNCTION (this << ifaceIndex);
1332  Ptr<Ipv4Interface> interface = GetInterface (ifaceIndex);
1333  interface->SetDown ();
1334 
1335  if (m_routingProtocol != 0)
1336  {
1337  m_routingProtocol->NotifyInterfaceDown (ifaceIndex);
1338  }
1339 }
1340 
1341 bool
1343 {
1344  NS_LOG_FUNCTION (this << i);
1345  Ptr<Ipv4Interface> interface = GetInterface (i);
1346  NS_LOG_LOGIC ("Forwarding state: " << interface->IsForwarding ());
1347  return interface->IsForwarding ();
1348 }
1349 
1350 void
1351 Ipv4L3Protocol::SetForwarding (uint32_t i, bool val)
1352 {
1353  NS_LOG_FUNCTION (this << i);
1354  Ptr<Ipv4Interface> interface = GetInterface (i);
1355  interface->SetForwarding (val);
1356 }
1357 
1360 {
1361  NS_LOG_FUNCTION (this << i);
1362  return GetInterface (i)->GetDevice ();
1363 }
1364 
1365 void
1367 {
1368  NS_LOG_FUNCTION (this << forward);
1369  m_ipForward = forward;
1370  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
1371  {
1372  (*i)->SetForwarding (forward);
1373  }
1374 }
1375 
1376 bool
1378 {
1379  NS_LOG_FUNCTION (this);
1380  return m_ipForward;
1381 }
1382 
1383 void
1385 {
1386  NS_LOG_FUNCTION (this << model);
1387  m_weakEsModel = model;
1388 }
1389 
1390 bool
1392 {
1393  NS_LOG_FUNCTION (this);
1394  return m_weakEsModel;
1395 }
1396 
1397 void
1399 {
1400  NS_LOG_FUNCTION (this << p << ipHeader << sockErrno);
1401  NS_LOG_LOGIC ("Route input failure-- dropping packet to " << ipHeader << " with errno " << sockErrno);
1402  m_dropTrace (ipHeader, p, DROP_ROUTE_ERROR, m_node->GetObject<Ipv4> (), 0);
1403 
1404  // \todo Send an ICMP no route.
1405 }
1406 
1407 void
1408 Ipv4L3Protocol::DoFragmentation (Ptr<Packet> packet, const Ipv4Header & ipv4Header, uint32_t outIfaceMtu, std::list<Ipv4PayloadHeaderPair>& listFragments)
1409 {
1410  // BEWARE: here we do assume that the header options are not present.
1411  // a much more complex handling is necessary in case there are options.
1412  // If (when) IPv4 option headers will be implemented, the following code shall be changed.
1413  // Of course also the reassemby code shall be changed as well.
1414 
1415  NS_LOG_FUNCTION (this << *packet << outIfaceMtu << &listFragments);
1416 
1417  Ptr<Packet> p = packet->Copy ();
1418 
1419  NS_ASSERT_MSG( (ipv4Header.GetSerializedSize() == 5*4),
1420  "IPv4 fragmentation implementation only works without option headers." );
1421 
1422  uint16_t offset = 0;
1423  bool moreFragment = true;
1424  uint16_t originalOffset = ipv4Header.GetFragmentOffset();
1425  bool isLastFragment = ipv4Header.IsLastFragment();
1426  uint32_t currentFragmentablePartSize = 0;
1427 
1428  // IPv4 fragments are all 8 bytes aligned but the last.
1429  // The IP payload size is:
1430  // floor( ( outIfaceMtu - ipv4Header.GetSerializedSize() ) /8 ) *8
1431  uint32_t fragmentSize = (outIfaceMtu - ipv4Header.GetSerializedSize () ) & ~uint32_t (0x7);
1432 
1433  NS_LOG_LOGIC ("Fragmenting - Target Size: " << fragmentSize );
1434 
1435  do
1436  {
1437  Ipv4Header fragmentHeader = ipv4Header;
1438 
1439  if (p->GetSize () > offset + fragmentSize )
1440  {
1441  moreFragment = true;
1442  currentFragmentablePartSize = fragmentSize;
1443  fragmentHeader.SetMoreFragments ();
1444  }
1445  else
1446  {
1447  moreFragment = false;
1448  currentFragmentablePartSize = p->GetSize () - offset;
1449  if (!isLastFragment)
1450  {
1451  fragmentHeader.SetMoreFragments ();
1452  }
1453  else
1454  {
1455  fragmentHeader.SetLastFragment ();
1456  }
1457  }
1458 
1459  NS_LOG_LOGIC ("Fragment creation - " << offset << ", " << currentFragmentablePartSize );
1460  Ptr<Packet> fragment = p->CreateFragment (offset, currentFragmentablePartSize);
1461  NS_LOG_LOGIC ("Fragment created - " << offset << ", " << fragment->GetSize () );
1462 
1463  fragmentHeader.SetFragmentOffset (offset+originalOffset);
1464  fragmentHeader.SetPayloadSize (currentFragmentablePartSize);
1465 
1466  if (Node::ChecksumEnabled ())
1467  {
1468  fragmentHeader.EnableChecksum ();
1469  }
1470 
1471  NS_LOG_LOGIC ("Fragment check - " << fragmentHeader.GetFragmentOffset () );
1472 
1473  NS_LOG_LOGIC ("New fragment Header " << fragmentHeader);
1474 
1475  std::ostringstream oss;
1476  oss << fragmentHeader;
1477  fragment->Print (oss);
1478 
1479  NS_LOG_LOGIC ("New fragment " << *fragment);
1480 
1481  listFragments.push_back (Ipv4PayloadHeaderPair (fragment, fragmentHeader));
1482 
1483  offset += currentFragmentablePartSize;
1484 
1485  }
1486  while (moreFragment);
1487 
1488  return;
1489 }
1490 
1491 bool
1492 Ipv4L3Protocol::ProcessFragment (Ptr<Packet>& packet, Ipv4Header& ipHeader, uint32_t iif)
1493 {
1494  NS_LOG_FUNCTION (this << packet << ipHeader << iif);
1495 
1496  uint64_t addressCombination = uint64_t (ipHeader.GetSource ().Get ()) << 32 | uint64_t (ipHeader.GetDestination ().Get ());
1497  uint32_t idProto = uint32_t (ipHeader.GetIdentification ()) << 16 | uint32_t (ipHeader.GetProtocol ());
1498  std::pair<uint64_t, uint32_t> key;
1499  bool ret = false;
1500  Ptr<Packet> p = packet->Copy ();
1501 
1502  key.first = addressCombination;
1503  key.second = idProto;
1504 
1505  Ptr<Fragments> fragments;
1506 
1507  MapFragments_t::iterator it = m_fragments.find (key);
1508  if (it == m_fragments.end ())
1509  {
1510  fragments = Create<Fragments> ();
1511  m_fragments.insert (std::make_pair (key, fragments));
1514  key, ipHeader, iif);
1515  }
1516  else
1517  {
1518  fragments = it->second;
1519  }
1520 
1521  NS_LOG_LOGIC ("Adding fragment - Size: " << packet->GetSize ( ) << " - Offset: " << (ipHeader.GetFragmentOffset ()) );
1522 
1523  fragments->AddFragment (p, ipHeader.GetFragmentOffset (), !ipHeader.IsLastFragment () );
1524 
1525  if ( fragments->IsEntire () )
1526  {
1527  packet = fragments->GetPacket ();
1528  fragments = 0;
1529  m_fragments.erase (key);
1530  if (m_fragmentsTimers[key].IsRunning ())
1531  {
1532  NS_LOG_LOGIC ("Stopping WaitFragmentsTimer at " << Simulator::Now ().GetSeconds () << " due to complete packet");
1533  m_fragmentsTimers[key].Cancel ();
1534  }
1535  m_fragmentsTimers.erase (key);
1536  ret = true;
1537  }
1538 
1539  return ret;
1540 }
1541 
1543  : m_moreFragment (0)
1544 {
1545  NS_LOG_FUNCTION (this);
1546 }
1547 
1549 {
1550  NS_LOG_FUNCTION (this);
1551 }
1552 
1553 void
1554 Ipv4L3Protocol::Fragments::AddFragment (Ptr<Packet> fragment, uint16_t fragmentOffset, bool moreFragment)
1555 {
1556  NS_LOG_FUNCTION (this << fragment << fragmentOffset << moreFragment);
1557 
1558  std::list<std::pair<Ptr<Packet>, uint16_t> >::iterator it;
1559 
1560  for (it = m_fragments.begin (); it != m_fragments.end (); it++)
1561  {
1562  if (it->second > fragmentOffset)
1563  {
1564  break;
1565  }
1566  }
1567 
1568  if (it == m_fragments.end ())
1569  {
1570  m_moreFragment = moreFragment;
1571  }
1572 
1573  m_fragments.insert (it, std::pair<Ptr<Packet>, uint16_t> (fragment, fragmentOffset));
1574 }
1575 
1576 bool
1578 {
1579  NS_LOG_FUNCTION (this);
1580 
1581  bool ret = !m_moreFragment && m_fragments.size () > 0;
1582 
1583  if (ret)
1584  {
1585  uint16_t lastEndOffset = 0;
1586 
1587  for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
1588  {
1589  // overlapping fragments do exist
1590  NS_LOG_LOGIC ("Checking overlaps " << lastEndOffset << " - " << it->second );
1591 
1592  if (lastEndOffset < it->second)
1593  {
1594  ret = false;
1595  break;
1596  }
1597  // fragments might overlap in strange ways
1598  uint16_t fragmentEnd = it->first->GetSize () + it->second;
1599  lastEndOffset = std::max ( lastEndOffset, fragmentEnd );
1600  }
1601  }
1602 
1603  return ret;
1604 }
1605 
1608 {
1609  NS_LOG_FUNCTION (this);
1610 
1611  std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin ();
1612 
1613  Ptr<Packet> p = it->first->Copy ();
1614  uint16_t lastEndOffset = p->GetSize ();
1615  it++;
1616 
1617  for ( ; it != m_fragments.end (); it++)
1618  {
1619  if ( lastEndOffset > it->second )
1620  {
1621  // The fragments are overlapping.
1622  // We do not overwrite the "old" with the "new" because we do not know when each arrived.
1623  // This is different from what Linux does.
1624  // It is not possible to emulate a fragmentation attack.
1625  uint32_t newStart = lastEndOffset - it->second;
1626  if ( it->first->GetSize () > newStart )
1627  {
1628  uint32_t newSize = it->first->GetSize () - newStart;
1629  Ptr<Packet> tempFragment = it->first->CreateFragment (newStart, newSize);
1630  p->AddAtEnd (tempFragment);
1631  }
1632  }
1633  else
1634  {
1635  NS_LOG_LOGIC ("Adding: " << *(it->first) );
1636  p->AddAtEnd (it->first);
1637  }
1638  lastEndOffset = p->GetSize ();
1639  }
1640 
1641  return p;
1642 }
1643 
1646 {
1647  NS_LOG_FUNCTION (this);
1648 
1649  std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin ();
1650 
1651  Ptr<Packet> p = Create<Packet> ();
1652  uint16_t lastEndOffset = 0;
1653 
1654  if ( m_fragments.begin ()->second > 0 )
1655  {
1656  return p;
1657  }
1658 
1659  for ( it = m_fragments.begin (); it != m_fragments.end (); it++)
1660  {
1661  if ( lastEndOffset > it->second )
1662  {
1663  uint32_t newStart = lastEndOffset - it->second;
1664  uint32_t newSize = it->first->GetSize () - newStart;
1665  Ptr<Packet> tempFragment = it->first->CreateFragment (newStart, newSize);
1666  p->AddAtEnd (tempFragment);
1667  }
1668  else if ( lastEndOffset == it->second )
1669  {
1670  NS_LOG_LOGIC ("Adding: " << *(it->first) );
1671  p->AddAtEnd (it->first);
1672  }
1673  lastEndOffset = p->GetSize ();
1674  }
1675 
1676  return p;
1677 }
1678 
1679 void
1680 Ipv4L3Protocol::HandleFragmentsTimeout (std::pair<uint64_t, uint32_t> key, Ipv4Header & ipHeader, uint32_t iif)
1681 {
1682  NS_LOG_FUNCTION (this << &key << &ipHeader << iif);
1683 
1684  MapFragments_t::iterator it = m_fragments.find (key);
1685  Ptr<Packet> packet = it->second->GetPartialPacket ();
1686 
1687  // if we have at least 8 bytes, we can send an ICMP.
1688  if ( packet->GetSize () > 8 )
1689  {
1690  Ptr<Icmpv4L4Protocol> icmp = GetIcmp ();
1691  icmp->SendTimeExceededTtl (ipHeader, packet, true);
1692  }
1693  m_dropTrace (ipHeader, packet, DROP_FRAGMENT_TIMEOUT, m_node->GetObject<Ipv4> (), iif);
1694 
1695  // clear the buffers
1696  it->second = 0;
1697 
1698  m_fragments.erase (key);
1699  m_fragmentsTimers.erase (key);
1700 }
1701 } // 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)
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.
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...
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
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
void SetNode(Ptr< Node > node)
Set the node associated with this socket.
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
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.
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
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.
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.
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.
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
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
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
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
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
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.
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)
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 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
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.