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