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