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