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