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