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