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/string.h"
31#include "ns3/boolean.h"
32#include "ns3/trace-source-accessor.h"
33#include "ns3/object-vector.h"
34#include "ns3/ipv4-header.h"
35#include "ns3/boolean.h"
36#include "ns3/ipv4-routing-table-entry.h"
37#include "ns3/traffic-control-layer.h"
38
39#include "loopback-net-device.h"
40#include "arp-l3-protocol.h"
41#include "arp-cache.h"
42#include "ipv4-l3-protocol.h"
43#include "icmpv4-l4-protocol.h"
44#include "ipv4-interface.h"
46
47namespace ns3 {
48
49NS_LOG_COMPONENT_DEFINE ("Ipv4L3Protocol");
50
51const uint16_t Ipv4L3Protocol::PROT_NUMBER = 0x0800;
52
53NS_OBJECT_ENSURE_REGISTERED (Ipv4L3Protocol);
54
55TypeId
57{
58 static TypeId tid = TypeId ("ns3::Ipv4L3Protocol")
59 .SetParent<Ipv4> ()
60 .SetGroupName ("Internet")
61 .AddConstructor<Ipv4L3Protocol> ()
62 .AddAttribute ("DefaultTtl",
63 "The TTL value set by default on "
64 "all outgoing packets generated on this node.",
65 UintegerValue (64),
67 MakeUintegerChecker<uint8_t> ())
68 .AddAttribute ("FragmentExpirationTimeout",
69 "When this timeout expires, the fragments "
70 "will be cleared from the buffer.",
71 TimeValue (Seconds (30)),
74 .AddAttribute ("EnableDuplicatePacketDetection",
75 "Enable multicast duplicate packet detection based on RFC 6621",
76 BooleanValue (false),
79 .AddAttribute ("DuplicateExpire", "Expiration delay for duplicate cache entries",
83 .AddAttribute ("PurgeExpiredPeriod",
84 "Time between purges of expired duplicate packet entries, "
85 "0 means never purge",
86 TimeValue (Seconds (1)),
89 .AddTraceSource ("Tx",
90 "Send ipv4 packet to outgoing interface.",
92 "ns3::Ipv4L3Protocol::TxRxTracedCallback")
93 .AddTraceSource ("Rx",
94 "Receive ipv4 packet from incoming interface.",
96 "ns3::Ipv4L3Protocol::TxRxTracedCallback")
97 .AddTraceSource ("Drop",
98 "Drop ipv4 packet",
100 "ns3::Ipv4L3Protocol::DropTracedCallback")
101 .AddAttribute ("InterfaceList",
102 "The set of Ipv4 interfaces associated to this Ipv4 stack.",
105 MakeObjectVectorChecker<Ipv4Interface> ())
106
107 .AddTraceSource ("SendOutgoing",
108 "A newly-generated packet by this node is "
109 "about to be queued for transmission",
111 "ns3::Ipv4L3Protocol::SentTracedCallback")
112 .AddTraceSource ("UnicastForward",
113 "A unicast IPv4 packet was received by this node "
114 "and is being forwarded to another node",
116 "ns3::Ipv4L3Protocol::SentTracedCallback")
117 .AddTraceSource ("MulticastForward",
118 "A multicast IPv4 packet was received by this node "
119 "and is being forwarded to another node",
121 "ns3::Ipv4L3Protocol::SentTracedCallback")
122 .AddTraceSource ("LocalDeliver",
123 "An IPv4 packet was received by/for this node, "
124 "and it is being forward up the stack",
126 "ns3::Ipv4L3Protocol::SentTracedCallback")
127
128 ;
129 return tid;
130}
131
133{
134 NS_LOG_FUNCTION (this);
135}
136
138{
139 NS_LOG_FUNCTION (this);
140}
141
142void
144{
145 NS_LOG_FUNCTION (this << protocol);
146 L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), -1);
147 if (m_protocols.find (key) != m_protocols.end ())
148 {
149 NS_LOG_WARN ("Overwriting default protocol " << int(protocol->GetProtocolNumber ()));
150 }
151 m_protocols[key] = protocol;
152}
153
154void
156{
157 NS_LOG_FUNCTION (this << protocol << interfaceIndex);
158
159 L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), interfaceIndex);
160 if (m_protocols.find (key) != m_protocols.end ())
161 {
162 NS_LOG_WARN ("Overwriting protocol " << int(protocol->GetProtocolNumber ()) << " on interface " << int(interfaceIndex));
163 }
164 m_protocols[key] = protocol;
165}
166
167void
169{
170 NS_LOG_FUNCTION (this << protocol);
171
172 L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), -1);
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 default protocol " << int(protocol->GetProtocolNumber ()));
177 }
178 else
179 {
180 m_protocols.erase (key);
181 }
182}
183
184void
186{
187 NS_LOG_FUNCTION (this << protocol << interfaceIndex);
188
189 L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), interfaceIndex);
190 L4List_t::iterator iter = m_protocols.find (key);
191 if (iter == m_protocols.end ())
192 {
193 NS_LOG_WARN ("Trying to remove an non-existent protocol " << int(protocol->GetProtocolNumber ()) << " on interface " << int(interfaceIndex));
194 }
195 else
196 {
197 m_protocols.erase (key);
198 }
199}
200
202Ipv4L3Protocol::GetProtocol (int protocolNumber) const
203{
204 NS_LOG_FUNCTION (this << protocolNumber);
205
206 return GetProtocol (protocolNumber, -1);
207}
208
210Ipv4L3Protocol::GetProtocol (int protocolNumber, int32_t interfaceIndex) const
211{
212 NS_LOG_FUNCTION (this << protocolNumber << interfaceIndex);
213
214 L4ListKey_t key;
215 L4List_t::const_iterator i;
216 if (interfaceIndex >= 0)
217 {
218 // try the interface-specific protocol.
219 key = std::make_pair (protocolNumber, interfaceIndex);
220 i = m_protocols.find (key);
221 if (i != m_protocols.end ())
222 {
223 return i->second;
224 }
225 }
226 // try the generic protocol.
227 key = std::make_pair (protocolNumber, -1);
228 i = m_protocols.find (key);
229 if (i != m_protocols.end ())
230 {
231 return i->second;
232 }
233
234 return 0;
235}
236
237void
239{
240 NS_LOG_FUNCTION (this << node);
241 m_node = node;
242 // Add a LoopbackNetDevice if needed, and an Ipv4Interface on top of it
243 SetupLoopback ();
244}
245
248{
249 NS_LOG_FUNCTION (this);
250 Ptr<Ipv4RawSocketImpl> socket = CreateObject<Ipv4RawSocketImpl> ();
251 socket->SetNode (m_node);
252 m_sockets.push_back (socket);
253 return socket;
254}
255void
257{
258 NS_LOG_FUNCTION (this << socket);
259 for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
260 {
261 if ((*i) == socket)
262 {
263 m_sockets.erase (i);
264 return;
265 }
266 }
267}
268/*
269 * This method is called by AggregateObject and completes the aggregation
270 * by setting the node in the ipv4 stack
271 */
272void
274{
275 NS_LOG_FUNCTION (this);
276 if (!m_node)
277 {
278 Ptr<Node>node = this->GetObject<Node>();
279 // verify that it's a valid node and that
280 // the node has not been set before
281 if (node)
282 {
283 this->SetNode (node);
284 }
285 }
287}
288
289void
291{
292 NS_LOG_FUNCTION (this << routingProtocol);
293 m_routingProtocol = routingProtocol;
294 m_routingProtocol->SetIpv4 (this);
295}
296
297
300{
301 NS_LOG_FUNCTION (this);
302 return m_routingProtocol;
303}
304
305void
307{
308 NS_LOG_FUNCTION (this);
309 for (L4List_t::iterator i = m_protocols.begin (); i != m_protocols.end (); ++i)
310 {
311 i->second = 0;
312 }
313 m_protocols.clear ();
314
315 for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); ++i)
316 {
317 *i = 0;
318 }
319 m_interfaces.clear ();
321
322 m_sockets.clear ();
323 m_node = 0;
325
326 for (MapFragments_t::iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
327 {
328 it->second = 0;
329 }
330
331 m_fragments.clear ();
332 m_timeoutEventList.clear ();
334 {
336 }
337
338 if (m_cleanDpd.IsRunning ())
339 {
341 }
342 m_dups.clear ();
343
345}
346
347void
349{
350 NS_LOG_FUNCTION (this);
351
353 Ptr<LoopbackNetDevice> device = 0;
354 // First check whether an existing LoopbackNetDevice exists on the node
355 for (uint32_t i = 0; i < m_node->GetNDevices (); i++)
356 {
357 if ((device = DynamicCast<LoopbackNetDevice> (m_node->GetDevice (i))))
358 {
359 break;
360 }
361 }
362 if (!device)
363 {
364 device = CreateObject<LoopbackNetDevice> ();
365 m_node->AddDevice (device);
366 }
367 interface->SetDevice (device);
368 interface->SetNode (m_node);
370 interface->AddAddress (ifaceAddr);
371 uint32_t index = AddIpv4Interface (interface);
372 Ptr<Node> node = GetObject<Node> ();
375 interface->SetUp ();
377 {
378 m_routingProtocol->NotifyInterfaceUp (index);
379 }
380}
381
382void
384{
385 NS_LOG_FUNCTION (this << static_cast<uint32_t> (ttl));
386 m_defaultTtl = ttl;
387}
388
391{
392 NS_LOG_FUNCTION (this << device);
394
396
397 NS_ASSERT (tc);
398
403
404 tc->RegisterProtocolHandler (MakeCallback (&Ipv4L3Protocol::Receive, this),
406 tc->RegisterProtocolHandler (MakeCallback (&ArpL3Protocol::Receive, PeekPointer (GetObject<ArpL3Protocol> ())),
408
410 interface->SetNode (m_node);
411 interface->SetDevice (device);
412 interface->SetTrafficControl (tc);
413 interface->SetForwarding (m_ipForward);
414 return AddIpv4Interface (interface);
415}
416
419{
420 NS_LOG_FUNCTION (this << interface);
421 uint32_t index = m_interfaces.size ();
422 m_interfaces.push_back (interface);
423 m_reverseInterfacesContainer[interface->GetDevice ()] = index;
424 return index;
425}
426
429{
430 NS_LOG_FUNCTION (this << index);
431 if (index < m_interfaces.size ())
432 {
433 return m_interfaces[index];
434 }
435 return 0;
436}
437
440{
441 NS_LOG_FUNCTION (this);
442 return m_interfaces.size ();
443}
444
447 Ipv4Address address) const
448{
449 NS_LOG_FUNCTION (this << address);
450 int32_t interface = 0;
451 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
452 i != m_interfaces.end ();
453 i++, interface++)
454 {
455 for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
456 {
457 if ((*i)->GetAddress (j).GetLocal () == address)
458 {
459 return interface;
460 }
461 }
462 }
463
464 return -1;
465}
466
470 Ipv4Mask mask) const
471{
472 NS_LOG_FUNCTION (this << address << mask);
473 int32_t interface = 0;
474 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
475 i != m_interfaces.end ();
476 i++, interface++)
477 {
478 for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
479 {
480 if ((*i)->GetAddress (j).GetLocal ().CombineMask (mask) == address.CombineMask (mask))
481 {
482 return interface;
483 }
484 }
485 }
486
487 return -1;
488}
489
492 Ptr<const NetDevice> device) const
493{
494 NS_LOG_FUNCTION (this << device);
495
496 Ipv4InterfaceReverseContainer::const_iterator iter = m_reverseInterfacesContainer.find (device);
497 if (iter != m_reverseInterfacesContainer.end ())
498 {
499 return (*iter).second;
500 }
501
502 return -1;
503}
504
505bool
507{
508 NS_LOG_FUNCTION (this << address << iif);
509 // First check the incoming interface for a unicast address match
510 for (uint32_t i = 0; i < GetNAddresses (iif); i++)
511 {
512 Ipv4InterfaceAddress iaddr = GetAddress (iif, i);
513 if (address == iaddr.GetLocal ())
514 {
515 NS_LOG_LOGIC ("For me (destination " << address << " match)");
516 return true;
517 }
518 if (address == iaddr.GetBroadcast ())
519 {
520 NS_LOG_LOGIC ("For me (interface broadcast address)");
521 return true;
522 }
523 }
524
525 if (address.IsMulticast ())
526 {
527#ifdef NOTYET
528 if (MulticastCheckGroup (iif, address ))
529#endif
530 if (true)
531 {
532 NS_LOG_LOGIC ("For me (Ipv4Addr multicast address)");
533 return true;
534 }
535 }
536
537 if (address.IsBroadcast ())
538 {
539 NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)");
540 return true;
541 }
542
543 if (GetWeakEsModel ()) // Check other interfaces
544 {
545 for (uint32_t j = 0; j < GetNInterfaces (); j++)
546 {
547 if (j == uint32_t (iif)) continue;
548 for (uint32_t i = 0; i < GetNAddresses (j); i++)
549 {
550 Ipv4InterfaceAddress iaddr = GetAddress (j, i);
551 if (address == iaddr.GetLocal ())
552 {
553 NS_LOG_LOGIC ("For me (destination " << address << " match) on another interface");
554 return true;
555 }
556 // This is a small corner case: match another interface's broadcast address
557 if (address == iaddr.GetBroadcast ())
558 {
559 NS_LOG_LOGIC ("For me (interface broadcast address on another interface)");
560 return true;
561 }
562 }
563 }
564 }
565 return false;
566}
567
568void
569Ipv4L3Protocol::Receive ( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
570 const Address &to, NetDevice::PacketType packetType)
571{
572 NS_LOG_FUNCTION (this << device << p << protocol << from << to << packetType);
573
574 NS_LOG_LOGIC ("Packet from " << from << " received on node " <<
575 m_node->GetId ());
576
577
578 int32_t interface = GetInterfaceForDevice(device);
579 NS_ASSERT_MSG (interface != -1, "Received a packet from an interface that is not known to IPv4");
580
581 Ptr<Packet> packet = p->Copy ();
582
583 Ptr<Ipv4Interface> ipv4Interface = m_interfaces[interface];
584
585 if (ipv4Interface->IsUp ())
586 {
587 m_rxTrace (packet, this, interface);
588 }
589 else
590 {
591 NS_LOG_LOGIC ("Dropping received packet -- interface is down");
592 Ipv4Header ipHeader;
593 packet->RemoveHeader (ipHeader);
594 m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, this, interface);
595 return;
596 }
597
598 Ipv4Header ipHeader;
600 {
601 ipHeader.EnableChecksum ();
602 }
603 packet->RemoveHeader (ipHeader);
604
605 // Trim any residual frame padding from underlying devices
606 if (ipHeader.GetPayloadSize () < packet->GetSize ())
607 {
608 packet->RemoveAtEnd (packet->GetSize () - ipHeader.GetPayloadSize ());
609 }
610
611 if (!ipHeader.IsChecksumOk ())
612 {
613 NS_LOG_LOGIC ("Dropping received packet -- checksum not ok");
614 m_dropTrace (ipHeader, packet, DROP_BAD_CHECKSUM, this, interface);
615 return;
616 }
617
618 // the packet is valid, we update the ARP cache entry (if present)
619 Ptr<ArpCache> arpCache = ipv4Interface->GetArpCache ();
620 if (arpCache)
621 {
622 // case one, it's a a direct routing.
623 ArpCache::Entry *entry = arpCache->Lookup (ipHeader.GetSource ());
624 if (entry)
625 {
626 if (entry->IsAlive ())
627 {
628 entry->UpdateSeen ();
629 }
630 }
631 else
632 {
633 // It's not in the direct routing, so it's the router, and it could have multiple IP addresses.
634 // In doubt, update all of them.
635 // Note: it's a confirmed behavior for Linux routers.
636 std::list<ArpCache::Entry *> entryList = arpCache->LookupInverse (from);
637 std::list<ArpCache::Entry *>::iterator iter;
638 for (iter = entryList.begin (); iter != entryList.end (); iter ++)
639 {
640 if ((*iter)->IsAlive ())
641 {
642 (*iter)->UpdateSeen ();
643 }
644 }
645 }
646 }
647
648 for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
649 {
650 NS_LOG_LOGIC ("Forwarding to raw socket");
651 Ptr<Ipv4RawSocketImpl> socket = *i;
652 socket->ForwardUp (packet, ipHeader, ipv4Interface);
653 }
654
655 if (m_enableDpd && ipHeader.GetDestination ().IsMulticast () && UpdateDuplicate (packet, ipHeader))
656 {
657 NS_LOG_LOGIC ("Dropping received packet -- duplicate.");
658 m_dropTrace (ipHeader, packet, DROP_DUPLICATE, this, interface);
659 return;
660 }
661
662 NS_ASSERT_MSG (m_routingProtocol, "Need a routing protocol object to process packets");
663 if (!m_routingProtocol->RouteInput (packet, ipHeader, device,
668 ))
669 {
670 NS_LOG_WARN ("No route found for forwarding packet. Drop.");
671 m_dropTrace (ipHeader, packet, DROP_NO_ROUTE, this, interface);
672 }
673}
674
677{
678 NS_LOG_FUNCTION (this);
680 if (prot)
681 {
682 return prot->GetObject<Icmpv4L4Protocol> ();
683 }
684 else
685 {
686 return 0;
687 }
688}
689
690bool
692{
693 NS_LOG_FUNCTION (this << ad);
694
695 if (ad.IsBroadcast () || ad.IsMulticast ())
696 {
697 return false;
698 }
699 else
700 {
701 // check for subnet-broadcast
702 for (uint32_t ifaceIndex = 0; ifaceIndex < GetNInterfaces (); ifaceIndex++)
703 {
704 for (uint32_t j = 0; j < GetNAddresses (ifaceIndex); j++)
705 {
706 Ipv4InterfaceAddress ifAddr = GetAddress (ifaceIndex, j);
707 NS_LOG_LOGIC ("Testing address " << ad << " with subnet-directed broadcast " << ifAddr.GetBroadcast () );
708 if (ad == ifAddr.GetBroadcast () )
709 {
710 return false;
711 }
712 }
713 }
714 }
715
716 return true;
717}
718
719bool
721{
722 NS_LOG_FUNCTION (this << ad << interfaceMask);
723 return !ad.IsMulticast () && !ad.IsSubnetDirectedBroadcast (interfaceMask);
724}
725
726void
728 Ipv4Header ipHeader,
729 Ptr<Ipv4Route> route)
730{
731 NS_LOG_FUNCTION (this << packet << ipHeader << route);
733 {
734 ipHeader.EnableChecksum ();
735 }
736 SendRealOut (route, packet, ipHeader);
737}
738
739void
741 Ptr<Ipv4> ipv4, uint32_t interface)
742{
743 if (!m_txTrace.IsEmpty ())
744 {
745 Ptr<Packet> packetCopy = packet->Copy ();
746 packetCopy->AddHeader (ipHeader);
747 m_txTrace (packetCopy, ipv4, interface);
748 }
749}
750
751void
753 Ipv4Address source,
754 Ipv4Address destination,
755 uint8_t protocol,
756 Ptr<Ipv4Route> route)
757{
758 NS_LOG_FUNCTION (this << packet << source << destination << uint32_t (protocol) << route);
759
760 bool mayFragment = true;
761
762 // we need a copy of the packet with its tags in case we need to invoke recursion.
763 Ptr<Packet> pktCopyWithTags = packet->Copy ();
764
765 uint8_t ttl = m_defaultTtl;
766 SocketIpTtlTag ipTtlTag;
767 bool ipTtlTagFound = packet->RemovePacketTag (ipTtlTag);
768 if (ipTtlTagFound)
769 {
770 ttl = ipTtlTag.GetTtl ();
771 }
772
773 uint8_t tos = 0;
774 SocketIpTosTag ipTosTag;
775 bool ipTosTagFound = packet->RemovePacketTag (ipTosTag);
776 if (ipTosTagFound)
777 {
778 tos = ipTosTag.GetTos ();
779 }
780
781 // can construct the header here
782 Ipv4Header ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tos, mayFragment);
783
784 // Handle a few cases:
785 // 1) packet is passed in with a route entry
786 // 1a) packet is passed in with a route entry but route->GetGateway is not set (e.g., on-demand)
787 // 1b) packet is passed in with a route entry and valid gateway
788 // 2) packet is passed without a route and packet is destined to limited broadcast address
789 // 3) packet is passed without a route and packet is destined to a subnet-directed broadcast address
790 // 4) packet is passed without a route, packet is not broadcast (e.g., a raw socket call, or ICMP)
791
792 // 1) packet is passed in with route entry
793 if (route)
794 {
795 // 1a) route->GetGateway is not set (e.g., on-demand)
796 if (!route->GetGateway ().IsInitialized ())
797 {
798 // This could arise because the synchronous RouteOutput() call
799 // returned to the transport protocol with a source address but
800 // there was no next hop available yet (since a route may need
801 // to be queried).
802 NS_FATAL_ERROR ("Ipv4L3Protocol::Send case 1a: packet passed with a route but the Gateway address is uninitialized. This case not yet implemented.");
803 }
804
805 // 1b) with a valid gateway
806 NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 1b: passed in with route and valid gateway");
807 int32_t interface = GetInterfaceForDevice (route->GetOutputDevice ());
808 m_sendOutgoingTrace (ipHeader, packet, interface);
809 if (m_enableDpd && ipHeader.GetDestination ().IsMulticast ())
810 {
811 UpdateDuplicate (packet, ipHeader);
812 }
813 SendRealOut (route, packet->Copy (), ipHeader);
814 return;
815 }
816
817 // 2) packet is destined to limited broadcast address or link-local multicast address
818 if (destination.IsBroadcast () || destination.IsLocalMulticast ())
819 {
820 NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 2: limited broadcast - no route");
821 uint32_t ifaceIndex = 0;
822 for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
823 ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
824 {
825 Ptr<Ipv4Interface> outInterface = *ifaceIter;
826 // ANY source matches any interface
827 bool sendIt = source.IsAny ();
828 // check if some specific address on outInterface matches
829 for (uint32_t index = 0; !sendIt && index < outInterface->GetNAddresses (); index++)
830 {
831 if (outInterface->GetAddress (index).GetLocal () == source)
832 {
833 sendIt = true;
834 }
835 }
836
837 if (sendIt)
838 {
839 // create a proxy route for this interface
840 Ptr<Ipv4Route> route = Create<Ipv4Route> ();
841 route->SetDestination (destination);
842 route->SetGateway (Ipv4Address::GetAny ());
843 route->SetSource (source);
844 route->SetOutputDevice (outInterface->GetDevice ());
845 DecreaseIdentification (source, destination, protocol);
846 Send (pktCopyWithTags, source, destination, protocol, route);
847 }
848 }
849 return;
850 }
851
852 // 3) check: packet is destined to a subnet-directed broadcast address
853 for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
854 ifaceIter != m_interfaces.end (); ifaceIter++)
855 {
856 Ptr<Ipv4Interface> outInterface = *ifaceIter;
857 uint32_t ifaceIndex = GetInterfaceForDevice (outInterface->GetDevice ());
858 for (uint32_t j = 0; j < GetNAddresses (ifaceIndex); j++)
859 {
860 Ipv4InterfaceAddress ifAddr = GetAddress (ifaceIndex, j);
861 NS_LOG_LOGIC ("Testing address " << ifAddr.GetLocal () << " with mask " << ifAddr.GetMask ());
862 if (destination.IsSubnetDirectedBroadcast (ifAddr.GetMask ()) &&
863 destination.CombineMask (ifAddr.GetMask ()) == ifAddr.GetLocal ().CombineMask (ifAddr.GetMask ()) )
864 {
865 NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 3: subnet directed bcast to " << ifAddr.GetLocal () << " - no route");
866 // create a proxy route for this interface
867 Ptr<Ipv4Route> route = Create<Ipv4Route> ();
868 route->SetDestination (destination);
869 route->SetGateway (Ipv4Address::GetAny ());
870 route->SetSource (source);
871 route->SetOutputDevice (outInterface->GetDevice ());
872 DecreaseIdentification (source, destination, protocol);
873 Send (pktCopyWithTags, source, destination, protocol, route);
874 return;
875 }
876 }
877 }
878
879 // 4) packet is not broadcast, and route is NULL (e.g., a raw socket call)
880 NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 4: not broadcast and passed in with no route " << destination);
881 Socket::SocketErrno errno_;
882 Ptr<NetDevice> oif (0); // unused for now
883 Ptr<Ipv4Route> newRoute;
885 {
886 newRoute = m_routingProtocol->RouteOutput (pktCopyWithTags, ipHeader, oif, errno_);
887 }
888 else
889 {
890 NS_LOG_ERROR ("Ipv4L3Protocol::Send: m_routingProtocol == 0");
891 }
892 if (newRoute)
893 {
894 DecreaseIdentification (source, destination, protocol);
895 Send (pktCopyWithTags, source, destination, protocol, newRoute);
896 }
897 else
898 {
899 NS_LOG_WARN ("No route to host. Drop.");
900 m_dropTrace (ipHeader, packet, DROP_NO_ROUTE, this, 0);
901 DecreaseIdentification (source, destination, protocol);
902 }
903}
904
905void
907 Ipv4Address destination,
908 uint8_t protocol)
909{
910 uint64_t src = source.Get ();
911 uint64_t dst = destination.Get ();
912 uint64_t srcDst = dst | (src << 32);
913 std::pair<uint64_t, uint8_t> key = std::make_pair (srcDst, protocol);
914 m_identification[key]--;
915}
916
919 Ipv4Address source,
920 Ipv4Address destination,
921 uint8_t protocol,
922 uint16_t payloadSize,
923 uint8_t ttl,
924 uint8_t tos,
925 bool mayFragment)
926{
927 NS_LOG_FUNCTION (this << source << destination << (uint16_t)protocol << payloadSize << (uint16_t)ttl << (uint16_t)tos << mayFragment);
928 Ipv4Header ipHeader;
929 ipHeader.SetSource (source);
930 ipHeader.SetDestination (destination);
931 ipHeader.SetProtocol (protocol);
932 ipHeader.SetPayloadSize (payloadSize);
933 ipHeader.SetTtl (ttl);
934 ipHeader.SetTos (tos);
935
936 uint64_t src = source.Get ();
937 uint64_t dst = destination.Get ();
938 uint64_t srcDst = dst | (src << 32);
939 std::pair<uint64_t, uint8_t> key = std::make_pair (srcDst, protocol);
940
941 if (mayFragment == true)
942 {
943 ipHeader.SetMayFragment ();
944 ipHeader.SetIdentification (m_identification[key]);
945 m_identification[key]++;
946 }
947 else
948 {
949 ipHeader.SetDontFragment ();
950 // RFC 6864 does not state anything about atomic datagrams
951 // identification requirement:
952 // >> Originating sources MAY set the IPv4 ID field of atomic datagrams
953 // to any value.
954 ipHeader.SetIdentification (m_identification[key]);
955 m_identification[key]++;
956 }
958 {
959 ipHeader.EnableChecksum ();
960 }
961 return ipHeader;
962}
963
964void
966 Ptr<Packet> packet,
967 Ipv4Header const &ipHeader)
968{
969 NS_LOG_FUNCTION (this << route << packet << &ipHeader);
970 if (!route)
971 {
972 NS_LOG_WARN ("No route to host. Drop.");
973 m_dropTrace (ipHeader, packet, DROP_NO_ROUTE, this, 0);
974 return;
975 }
976 Ptr<NetDevice> outDev = route->GetOutputDevice ();
977 int32_t interface = GetInterfaceForDevice (outDev);
978 NS_ASSERT (interface >= 0);
979 Ptr<Ipv4Interface> outInterface = GetInterface (interface);
980 NS_LOG_LOGIC ("Send via NetDevice ifIndex " << outDev->GetIfIndex () << " ipv4InterfaceIndex " << interface);
981
982 Ipv4Address target;
983 std::string targetLabel;
984 if (route->GetGateway ().IsAny ())
985 {
986 target = ipHeader.GetDestination ();
987 targetLabel = "destination";
988 }
989 else
990 {
991 target = route->GetGateway ();
992 targetLabel = "gateway";
993 }
994
995 if (outInterface->IsUp ())
996 {
997 NS_LOG_LOGIC ("Send to " << targetLabel << " " << target);
998 if ( packet->GetSize () + ipHeader.GetSerializedSize () > outInterface->GetDevice ()->GetMtu () )
999 {
1000 std::list<Ipv4PayloadHeaderPair> listFragments;
1001 DoFragmentation (packet, ipHeader, outInterface->GetDevice ()->GetMtu (), listFragments);
1002 for ( std::list<Ipv4PayloadHeaderPair>::iterator it = listFragments.begin (); it != listFragments.end (); it++ )
1003 {
1004 NS_LOG_LOGIC ("Sending fragment " << *(it->first) );
1005 CallTxTrace (it->second, it->first, this, interface);
1006 outInterface->Send (it->first, it->second, target);
1007 }
1008 }
1009 else
1010 {
1011 CallTxTrace (ipHeader, packet, this, interface);
1012 outInterface->Send (packet, ipHeader, target);
1013 }
1014 }
1015}
1016
1017// This function analogous to Linux ip_mr_forward()
1018void
1020{
1021 NS_LOG_FUNCTION (this << mrtentry << p << header);
1022 NS_LOG_LOGIC ("Multicast forwarding logic for node: " << m_node->GetId ());
1023
1024 std::map<uint32_t, uint32_t> ttlMap = mrtentry->GetOutputTtlMap ();
1025 std::map<uint32_t, uint32_t>::iterator mapIter;
1026
1027 for (mapIter = ttlMap.begin (); mapIter != ttlMap.end (); mapIter++)
1028 {
1029 uint32_t interface = mapIter->first;
1030 //uint32_t outputTtl = mapIter->second; // Unused for now
1031
1032 Ptr<Packet> packet = p->Copy ();
1033 Ipv4Header ipHeader = header;
1034 ipHeader.SetTtl (header.GetTtl () - 1);
1035 if (ipHeader.GetTtl () == 0)
1036 {
1037 NS_LOG_WARN ("TTL exceeded. Drop.");
1038 m_dropTrace (header, packet, DROP_TTL_EXPIRED, this, interface);
1039 return;
1040 }
1041 NS_LOG_LOGIC ("Forward multicast via interface " << interface);
1042 Ptr<Ipv4Route> rtentry = Create<Ipv4Route> ();
1043 rtentry->SetSource (ipHeader.GetSource ());
1044 rtentry->SetDestination (ipHeader.GetDestination ());
1045 rtentry->SetGateway (Ipv4Address::GetAny ());
1046 rtentry->SetOutputDevice (GetNetDevice (interface));
1047
1048 m_multicastForwardTrace (ipHeader, packet, interface);
1049 SendRealOut (rtentry, packet, ipHeader);
1050 }
1051}
1052
1053// This function analogous to Linux ip_forward()
1054void
1056{
1057 NS_LOG_FUNCTION (this << rtentry << p << header);
1058 NS_LOG_LOGIC ("Forwarding logic for node: " << m_node->GetId ());
1059 // Forwarding
1060 Ipv4Header ipHeader = header;
1061 Ptr<Packet> packet = p->Copy ();
1062 int32_t interface = GetInterfaceForDevice (rtentry->GetOutputDevice ());
1063 ipHeader.SetTtl (ipHeader.GetTtl () - 1);
1064 if (ipHeader.GetTtl () == 0)
1065 {
1066 // Do not reply to multicast/broadcast IP address
1067 if (ipHeader.GetDestination ().IsBroadcast () == false &&
1068 ipHeader.GetDestination ().IsMulticast () == false)
1069 {
1071 icmp->SendTimeExceededTtl (ipHeader, packet, false);
1072 }
1073 NS_LOG_WARN ("TTL exceeded. Drop.");
1074 m_dropTrace (header, packet, DROP_TTL_EXPIRED, this, interface);
1075 return;
1076 }
1077 // in case the packet still has a priority tag attached, remove it
1078 SocketPriorityTag priorityTag;
1079 packet->RemovePacketTag (priorityTag);
1080 uint8_t priority = Socket::IpTos2Priority (ipHeader.GetTos ());
1081 // add a priority tag if the priority is not null
1082 if (priority)
1083 {
1084 priorityTag.SetPriority (priority);
1085 packet->AddPacketTag (priorityTag);
1086 }
1087
1088 m_unicastForwardTrace (ipHeader, packet, interface);
1089 SendRealOut (rtentry, packet, ipHeader);
1090}
1091
1092void
1094{
1095 NS_LOG_FUNCTION (this << packet << &ip << iif);
1096 Ptr<Packet> p = packet->Copy (); // need to pass a non-const packet up
1097 Ipv4Header ipHeader = ip;
1098
1099 if ( !ipHeader.IsLastFragment () || ipHeader.GetFragmentOffset () != 0 )
1100 {
1101 NS_LOG_LOGIC ("Received a fragment, processing " << *p );
1102 bool isPacketComplete;
1103 isPacketComplete = ProcessFragment (p, ipHeader, iif);
1104 if ( isPacketComplete == false)
1105 {
1106 return;
1107 }
1108 NS_LOG_LOGIC ("Got last fragment, Packet is complete " << *p );
1109 ipHeader.SetFragmentOffset (0);
1110 ipHeader.SetPayloadSize (p->GetSize ());
1111 }
1112
1113 m_localDeliverTrace (ipHeader, p, iif);
1114
1115 Ptr<IpL4Protocol> protocol = GetProtocol (ipHeader.GetProtocol (), iif);
1116 if (protocol)
1117 {
1118 // we need to make a copy in the unlikely event we hit the
1119 // RX_ENDPOINT_UNREACH codepath
1120 Ptr<Packet> copy = p->Copy ();
1121 enum IpL4Protocol::RxStatus status =
1122 protocol->Receive (p, ipHeader, GetInterface (iif));
1123 switch (status) {
1125 // fall through
1127 // fall through
1129 break;
1131 if (ipHeader.GetDestination ().IsBroadcast () == true ||
1132 ipHeader.GetDestination ().IsMulticast () == true)
1133 {
1134 break; // Do not reply to broadcast or multicast
1135 }
1136 // Another case to suppress ICMP is a subnet-directed broadcast
1137 bool subnetDirected = false;
1138 for (uint32_t i = 0; i < GetNAddresses (iif); i++)
1139 {
1140 Ipv4InterfaceAddress addr = GetAddress (iif, i);
1141 if (addr.GetLocal ().CombineMask (addr.GetMask ()) == ipHeader.GetDestination ().CombineMask (addr.GetMask ()) &&
1142 ipHeader.GetDestination ().IsSubnetDirectedBroadcast (addr.GetMask ()))
1143 {
1144 subnetDirected = true;
1145 }
1146 }
1147 if (subnetDirected == false)
1148 {
1149 GetIcmp ()->SendDestUnreachPort (ipHeader, copy);
1150 }
1151 }
1152 }
1153}
1154
1155bool
1157{
1158 NS_LOG_FUNCTION (this << i << address);
1159 Ptr<Ipv4Interface> interface = GetInterface (i);
1160 bool retVal = interface->AddAddress (address);
1162 {
1163 m_routingProtocol->NotifyAddAddress (i, address);
1164 }
1165 return retVal;
1166}
1167
1169Ipv4L3Protocol::GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const
1170{
1171 NS_LOG_FUNCTION (this << interfaceIndex << addressIndex);
1172 Ptr<Ipv4Interface> interface = GetInterface (interfaceIndex);
1173 return interface->GetAddress (addressIndex);
1174}
1175
1178{
1179 NS_LOG_FUNCTION (this << interface);
1180 Ptr<Ipv4Interface> iface = GetInterface (interface);
1181 return iface->GetNAddresses ();
1182}
1183
1184bool
1186{
1187 NS_LOG_FUNCTION (this << i << addressIndex);
1188 Ptr<Ipv4Interface> interface = GetInterface (i);
1189 Ipv4InterfaceAddress address = interface->RemoveAddress (addressIndex);
1190 if (address != Ipv4InterfaceAddress ())
1191 {
1193 {
1194 m_routingProtocol->NotifyRemoveAddress (i, address);
1195 }
1196 return true;
1197 }
1198 return false;
1199}
1200
1201bool
1203{
1204 NS_LOG_FUNCTION (this << i << address);
1205
1207 {
1208 NS_LOG_WARN ("Cannot remove loopback address.");
1209 return false;
1210 }
1211 Ptr<Ipv4Interface> interface = GetInterface (i);
1212 Ipv4InterfaceAddress ifAddr = interface->RemoveAddress (address);
1213 if (ifAddr != Ipv4InterfaceAddress ())
1214 {
1216 {
1217 m_routingProtocol->NotifyRemoveAddress (i, ifAddr);
1218 }
1219 return true;
1220 }
1221 return false;
1222}
1223
1226{
1227 NS_LOG_FUNCTION (this << interfaceIdx << " " << dest);
1228 if (GetNAddresses (interfaceIdx) == 1) // common case
1229 {
1230 return GetAddress (interfaceIdx, 0).GetLocal ();
1231 }
1232 // no way to determine the scope of the destination, so adopt the
1233 // following rule: pick the first available address (index 0) unless
1234 // a subsequent address is on link (in which case, pick the primary
1235 // address if there are multiple)
1236 Ipv4Address candidate = GetAddress (interfaceIdx, 0).GetLocal ();
1237 for (uint32_t i = 0; i < GetNAddresses (interfaceIdx); i++)
1238 {
1239 Ipv4InterfaceAddress test = GetAddress (interfaceIdx, i);
1240 if (test.GetLocal ().CombineMask (test.GetMask ()) == dest.CombineMask (test.GetMask ()))
1241 {
1242 if (test.IsSecondary () == false)
1243 {
1244 return test.GetLocal ();
1245 }
1246 }
1247 }
1248 return candidate;
1249}
1250
1254{
1255 NS_LOG_FUNCTION (this << device << dst << scope);
1256 Ipv4Address addr ("0.0.0.0");
1258 bool found = false;
1259
1260 if (device)
1261 {
1262 int32_t i = GetInterfaceForDevice (device);
1263 NS_ASSERT_MSG (i >= 0, "No device found on node");
1264 for (uint32_t j = 0; j < GetNAddresses (i); j++)
1265 {
1266 iaddr = GetAddress (i, j);
1267 if (iaddr.IsSecondary ()) continue;
1268 if (iaddr.GetScope () > scope) continue;
1269 if (dst.CombineMask (iaddr.GetMask ()) == iaddr.GetLocal ().CombineMask (iaddr.GetMask ()) )
1270 {
1271 return iaddr.GetLocal ();
1272 }
1273 if (!found)
1274 {
1275 addr = iaddr.GetLocal ();
1276 found = true;
1277 }
1278 }
1279 }
1280 if (found)
1281 {
1282 return addr;
1283 }
1284
1285 // Iterate among all interfaces
1286 for (uint32_t i = 0; i < GetNInterfaces (); i++)
1287 {
1288 for (uint32_t j = 0; j < GetNAddresses (i); j++)
1289 {
1290 iaddr = GetAddress (i, j);
1291 if (iaddr.IsSecondary ()) continue;
1292 if (iaddr.GetScope () != Ipv4InterfaceAddress::LINK
1293 && iaddr.GetScope () <= scope)
1294 {
1295 return iaddr.GetLocal ();
1296 }
1297 }
1298 }
1299 NS_LOG_WARN ("Could not find source address for " << dst << " and scope "
1300 << scope << ", returning 0");
1301 return addr;
1302}
1303
1304void
1306{
1307 NS_LOG_FUNCTION (this << i << metric);
1308 Ptr<Ipv4Interface> interface = GetInterface (i);
1309 interface->SetMetric (metric);
1310}
1311
1312uint16_t
1314{
1315 NS_LOG_FUNCTION (this << i);
1316 Ptr<Ipv4Interface> interface = GetInterface (i);
1317 return interface->GetMetric ();
1318}
1319
1320uint16_t
1322{
1323 NS_LOG_FUNCTION (this << i);
1324 Ptr<Ipv4Interface> interface = GetInterface (i);
1325 return interface->GetDevice ()->GetMtu ();
1326}
1327
1328bool
1330{
1331 NS_LOG_FUNCTION (this << i);
1332 Ptr<Ipv4Interface> interface = GetInterface (i);
1333 return interface->IsUp ();
1334}
1335
1336void
1338{
1339 NS_LOG_FUNCTION (this << i);
1340 Ptr<Ipv4Interface> interface = GetInterface (i);
1341
1342 // RFC 791, pg.25:
1343 // Every internet module must be able to forward a datagram of 68
1344 // octets without further fragmentation. This is because an internet
1345 // header may be up to 60 octets, and the minimum fragment is 8 octets.
1346 if (interface->GetDevice ()->GetMtu () >= 68)
1347 {
1348 interface->SetUp ();
1349
1351 {
1352 m_routingProtocol->NotifyInterfaceUp (i);
1353 }
1354 }
1355 else
1356 {
1357 NS_LOG_LOGIC ("Interface " << int(i) << " is set to be down for IPv4. Reason: not respecting minimum IPv4 MTU (68 octects)");
1358 }
1359}
1360
1361void
1363{
1364 NS_LOG_FUNCTION (this << ifaceIndex);
1365 Ptr<Ipv4Interface> interface = GetInterface (ifaceIndex);
1366 interface->SetDown ();
1367
1369 {
1370 m_routingProtocol->NotifyInterfaceDown (ifaceIndex);
1371 }
1372}
1373
1374bool
1376{
1377 NS_LOG_FUNCTION (this << i);
1378 Ptr<Ipv4Interface> interface = GetInterface (i);
1379 NS_LOG_LOGIC ("Forwarding state: " << interface->IsForwarding ());
1380 return interface->IsForwarding ();
1381}
1382
1383void
1385{
1386 NS_LOG_FUNCTION (this << i);
1387 Ptr<Ipv4Interface> interface = GetInterface (i);
1388 interface->SetForwarding (val);
1389}
1390
1393{
1394 NS_LOG_FUNCTION (this << i);
1395 return GetInterface (i)->GetDevice ();
1396}
1397
1398void
1400{
1401 NS_LOG_FUNCTION (this << forward);
1402 m_ipForward = forward;
1403 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
1404 {
1405 (*i)->SetForwarding (forward);
1406 }
1407}
1408
1409bool
1411{
1412 NS_LOG_FUNCTION (this);
1413 return m_ipForward;
1414}
1415
1416void
1418{
1419 NS_LOG_FUNCTION (this << model);
1420 m_weakEsModel = model;
1421}
1422
1423bool
1425{
1426 NS_LOG_FUNCTION (this);
1427 return m_weakEsModel;
1428}
1429
1430void
1432{
1433 NS_LOG_FUNCTION (this << p << ipHeader << sockErrno);
1434 NS_LOG_LOGIC ("Route input failure-- dropping packet to " << ipHeader << " with errno " << sockErrno);
1435 m_dropTrace (ipHeader, p, DROP_ROUTE_ERROR, this, 0);
1436
1437 // \todo Send an ICMP no route.
1438}
1439
1440void
1441Ipv4L3Protocol::DoFragmentation (Ptr<Packet> packet, const Ipv4Header & ipv4Header, uint32_t outIfaceMtu, std::list<Ipv4PayloadHeaderPair>& listFragments)
1442{
1443 // BEWARE: here we do assume that the header options are not present.
1444 // a much more complex handling is necessary in case there are options.
1445 // If (when) IPv4 option headers will be implemented, the following code shall be changed.
1446 // Of course also the reassemby code shall be changed as well.
1447
1448 NS_LOG_FUNCTION (this << *packet << outIfaceMtu << &listFragments);
1449
1450 Ptr<Packet> p = packet->Copy ();
1451
1452 NS_ASSERT_MSG( (ipv4Header.GetSerializedSize() == 5*4),
1453 "IPv4 fragmentation implementation only works without option headers." );
1454
1455 uint16_t offset = 0;
1456 bool moreFragment = true;
1457 uint16_t originalOffset = ipv4Header.GetFragmentOffset();
1458 bool isLastFragment = ipv4Header.IsLastFragment();
1459 uint32_t currentFragmentablePartSize = 0;
1460
1461 // IPv4 fragments are all 8 bytes aligned but the last.
1462 // The IP payload size is:
1463 // floor( ( outIfaceMtu - ipv4Header.GetSerializedSize() ) /8 ) *8
1464 uint32_t fragmentSize = (outIfaceMtu - ipv4Header.GetSerializedSize () ) & ~uint32_t (0x7);
1465
1466 NS_LOG_LOGIC ("Fragmenting - Target Size: " << fragmentSize );
1467
1468 do
1469 {
1470 Ipv4Header fragmentHeader = ipv4Header;
1471
1472 if (p->GetSize () > offset + fragmentSize )
1473 {
1474 moreFragment = true;
1475 currentFragmentablePartSize = fragmentSize;
1476 fragmentHeader.SetMoreFragments ();
1477 }
1478 else
1479 {
1480 moreFragment = false;
1481 currentFragmentablePartSize = p->GetSize () - offset;
1482 if (!isLastFragment)
1483 {
1484 fragmentHeader.SetMoreFragments ();
1485 }
1486 else
1487 {
1488 fragmentHeader.SetLastFragment ();
1489 }
1490 }
1491
1492 NS_LOG_LOGIC ("Fragment creation - " << offset << ", " << currentFragmentablePartSize );
1493 Ptr<Packet> fragment = p->CreateFragment (offset, currentFragmentablePartSize);
1494 NS_LOG_LOGIC ("Fragment created - " << offset << ", " << fragment->GetSize () );
1495
1496 fragmentHeader.SetFragmentOffset (offset+originalOffset);
1497 fragmentHeader.SetPayloadSize (currentFragmentablePartSize);
1498
1499 if (Node::ChecksumEnabled ())
1500 {
1501 fragmentHeader.EnableChecksum ();
1502 }
1503
1504 NS_LOG_LOGIC ("Fragment check - " << fragmentHeader.GetFragmentOffset () );
1505
1506 NS_LOG_LOGIC ("New fragment Header " << fragmentHeader);
1507
1508 std::ostringstream oss;
1509 oss << fragmentHeader;
1510 fragment->Print (oss);
1511
1512 NS_LOG_LOGIC ("New fragment " << *fragment);
1513
1514 listFragments.emplace_back (fragment, fragmentHeader);
1515
1516 offset += currentFragmentablePartSize;
1517
1518 }
1519 while (moreFragment);
1520}
1521
1522bool
1524{
1525 NS_LOG_FUNCTION (this << packet << ipHeader << iif);
1526
1527 uint64_t addressCombination = uint64_t (ipHeader.GetSource ().Get ()) << 32 | uint64_t (ipHeader.GetDestination ().Get ());
1528 uint32_t idProto = uint32_t (ipHeader.GetIdentification ()) << 16 | uint32_t (ipHeader.GetProtocol ());
1529 FragmentKey_t key;
1530 bool ret = false;
1531 Ptr<Packet> p = packet->Copy ();
1532
1533 key.first = addressCombination;
1534 key.second = idProto;
1535
1536 Ptr<Fragments> fragments;
1537
1538 MapFragments_t::iterator it = m_fragments.find (key);
1539 if (it == m_fragments.end ())
1540 {
1541 fragments = Create<Fragments> ();
1542 m_fragments.insert (std::make_pair (key, fragments));
1543
1544 FragmentsTimeoutsListI_t iter = SetTimeout (key, ipHeader, iif);
1545 fragments->SetTimeoutIter (iter);
1546 }
1547 else
1548 {
1549 fragments = it->second;
1550 }
1551
1552 NS_LOG_LOGIC ("Adding fragment - Size: " << packet->GetSize ( ) << " - Offset: " << (ipHeader.GetFragmentOffset ()) );
1553
1554 fragments->AddFragment (p, ipHeader.GetFragmentOffset (), !ipHeader.IsLastFragment () );
1555
1556 if ( fragments->IsEntire () )
1557 {
1558 packet = fragments->GetPacket ();
1559 m_timeoutEventList.erase (fragments->GetTimeoutIter ());
1560 fragments = 0;
1561 m_fragments.erase (key);
1562 ret = true;
1563 }
1564
1565 return ret;
1566}
1567
1569 : m_moreFragment (0)
1570{
1571 NS_LOG_FUNCTION (this);
1572}
1573
1574void
1575Ipv4L3Protocol::Fragments::AddFragment (Ptr<Packet> fragment, uint16_t fragmentOffset, bool moreFragment)
1576{
1577 NS_LOG_FUNCTION (this << fragment << fragmentOffset << moreFragment);
1578
1579 std::list<std::pair<Ptr<Packet>, uint16_t> >::iterator it;
1580
1581 for (it = m_fragments.begin (); it != m_fragments.end (); it++)
1582 {
1583 if (it->second > fragmentOffset)
1584 {
1585 break;
1586 }
1587 }
1588
1589 if (it == m_fragments.end ())
1590 {
1591 m_moreFragment = moreFragment;
1592 }
1593
1594 m_fragments.insert (it, std::pair<Ptr<Packet>, uint16_t> (fragment, fragmentOffset));
1595}
1596
1597bool
1599{
1600 NS_LOG_FUNCTION (this);
1601
1602 bool ret = !m_moreFragment && m_fragments.size () > 0;
1603
1604 if (ret)
1605 {
1606 uint16_t lastEndOffset = 0;
1607
1608 for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
1609 {
1610 // overlapping fragments do exist
1611 NS_LOG_LOGIC ("Checking overlaps " << lastEndOffset << " - " << it->second );
1612
1613 if (lastEndOffset < it->second)
1614 {
1615 ret = false;
1616 break;
1617 }
1618 // fragments might overlap in strange ways
1619 uint16_t fragmentEnd = it->first->GetSize () + it->second;
1620 lastEndOffset = std::max ( lastEndOffset, fragmentEnd );
1621 }
1622 }
1623
1624 return ret;
1625}
1626
1629{
1630 NS_LOG_FUNCTION (this);
1631
1632 std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin ();
1633
1634 Ptr<Packet> p = it->first->Copy ();
1635 uint16_t lastEndOffset = p->GetSize ();
1636 it++;
1637
1638 for ( ; it != m_fragments.end (); it++)
1639 {
1640 if ( lastEndOffset > it->second )
1641 {
1642 // The fragments are overlapping.
1643 // We do not overwrite the "old" with the "new" because we do not know when each arrived.
1644 // This is different from what Linux does.
1645 // It is not possible to emulate a fragmentation attack.
1646 uint32_t newStart = lastEndOffset - it->second;
1647 if ( it->first->GetSize () > newStart )
1648 {
1649 uint32_t newSize = it->first->GetSize () - newStart;
1650 Ptr<Packet> tempFragment = it->first->CreateFragment (newStart, newSize);
1651 p->AddAtEnd (tempFragment);
1652 }
1653 }
1654 else
1655 {
1656 NS_LOG_LOGIC ("Adding: " << *(it->first) );
1657 p->AddAtEnd (it->first);
1658 }
1659 lastEndOffset = p->GetSize ();
1660 }
1661
1662 return p;
1663}
1664
1667{
1668 NS_LOG_FUNCTION (this);
1669
1670 std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin ();
1671
1672 Ptr<Packet> p = Create<Packet> ();
1673 uint16_t lastEndOffset = 0;
1674
1675 if ( m_fragments.begin ()->second > 0 )
1676 {
1677 return p;
1678 }
1679
1680 for ( it = m_fragments.begin (); it != m_fragments.end (); it++)
1681 {
1682 if ( lastEndOffset > it->second )
1683 {
1684 uint32_t newStart = lastEndOffset - it->second;
1685 uint32_t newSize = it->first->GetSize () - newStart;
1686 Ptr<Packet> tempFragment = it->first->CreateFragment (newStart, newSize);
1687 p->AddAtEnd (tempFragment);
1688 }
1689 else if ( lastEndOffset == it->second )
1690 {
1691 NS_LOG_LOGIC ("Adding: " << *(it->first) );
1692 p->AddAtEnd (it->first);
1693 }
1694 lastEndOffset = p->GetSize ();
1695 }
1696
1697 return p;
1698}
1699
1700void
1702{
1703 m_timeoutIter = iter;
1704}
1705
1708{
1709 return m_timeoutIter;
1710}
1711
1712
1713void
1715{
1716 NS_LOG_FUNCTION (this << &key << &ipHeader << iif);
1717
1718 MapFragments_t::iterator it = m_fragments.find (key);
1719 Ptr<Packet> packet = it->second->GetPartialPacket ();
1720
1721 // if we have at least 8 bytes, we can send an ICMP.
1722 if ( packet->GetSize () > 8 )
1723 {
1725 icmp->SendTimeExceededTtl (ipHeader, packet, true);
1726 }
1727 m_dropTrace (ipHeader, packet, DROP_FRAGMENT_TIMEOUT, this, iif);
1728
1729 // clear the buffers
1730 it->second = 0;
1731
1732 m_fragments.erase (key);
1733}
1734
1735bool
1737{
1738 NS_LOG_FUNCTION (this << p << header);
1739
1740 // \todo RFC 6621 mandates SHA-1 hash. For now ns3 hash should be fine.
1741 uint8_t proto = header.GetProtocol ();
1742 Ipv4Address src = header.GetSource ();
1743 Ipv4Address dst = header.GetDestination ();
1744 uint64_t id = header.GetIdentification ();
1745
1746 // concat hash value onto id
1747 uint64_t hash = id << 32;
1748 if (header.GetFragmentOffset () || !header.IsLastFragment ())
1749 {
1750 // use I-DPD (RFC 6621, Sec 6.2.1)
1751 hash |= header.GetFragmentOffset ();
1752 }
1753 else
1754 {
1755 // use H-DPD (RFC 6621, Sec 6.2.2)
1756
1757 // serialize packet
1758 Ptr<Packet> pkt = p->Copy ();
1759 pkt->AddHeader (header);
1760
1761 std::ostringstream oss (std::ios_base::binary);
1762 pkt->CopyData (&oss, pkt->GetSize ());
1763 std::string bytes = oss.str ();
1764
1765 NS_ASSERT_MSG (bytes.size () >= 20, "Degenerate header serialization");
1766
1767 // zero out mutable fields
1768 bytes[1] = 0; // DSCP / ECN
1769 bytes[6] = bytes[7] = 0; // Flags / Fragment offset
1770 bytes[8] = 0; // TTL
1771 bytes[10] = bytes[11] = 0; // Header checksum
1772 if (header.GetSerializedSize () > 20) // assume options should be 0'd
1773 {
1774 std::fill_n (bytes.begin () + 20, header.GetSerializedSize () - 20, 0);
1775 }
1776
1777 // concat hash onto ID
1778 hash |= (uint64_t)Hash32 (bytes);
1779 }
1780
1781 // set cleanup job for new duplicate entries
1783 {
1785 }
1786
1787 // assume this is a new entry
1788 DupTuple_t key {hash, proto, src, dst};
1789 NS_LOG_DEBUG ("Packet " << p->GetUid () << " key = (" <<
1790 std::hex << std::get<0> (key) << ", " <<
1791 std::dec << +std::get<1> (key) << ", " <<
1792 std::get<2> (key) << ", " <<
1793 std::get<3> (key) << ")");
1794
1795 // place a new entry, on collision the existing entry iterator is returned
1796 DupMap_t::iterator iter;
1797 bool inserted, isDup;
1798 std::tie (iter, inserted) = m_dups.emplace (key, Seconds (0));
1799 isDup = !inserted && iter->second > Simulator::Now ();
1800
1801 // set the expiration event
1802 iter->second = Simulator::Now () + m_expire;
1803 return isDup;
1804}
1805
1806void
1808{
1809 NS_LOG_FUNCTION (this);
1810
1811 DupMap_t::size_type n = 0;
1812 Time expire = Simulator::Now ();
1813 auto iter = m_dups.cbegin ();
1814 while (iter != m_dups.cend ())
1815 {
1816 if (iter->second < expire)
1817 {
1818 NS_LOG_LOGIC ("Remove key = (" <<
1819 std::hex << std::get<0> (iter->first) << ", " <<
1820 std::dec << +std::get<1> (iter->first) << ", " <<
1821 std::get<2> (iter->first) << ", " <<
1822 std::get<3> (iter->first) << ")");
1823 iter = m_dups.erase (iter);
1824 ++n;
1825 }
1826 else
1827 {
1828 ++iter;
1829 }
1830 }
1831
1832 NS_LOG_DEBUG ("Purged " << n << " expired duplicate entries out of " << (n + m_dups.size ()));
1833
1834 // keep cleaning up if necessary
1835 if (!m_dups.empty () && m_purge.IsStrictlyPositive ())
1836 {
1838 }
1839}
1840
1843{
1845
1846 if (m_timeoutEventList.empty ())
1847 {
1849 }
1850 m_timeoutEventList.emplace_back (now, key, ipHeader, iif);
1851
1853
1854 return (iter);
1855}
1856
1857void
1859{
1860 Time now = Simulator::Now ();
1861
1862 while (!m_timeoutEventList.empty () && std::get<0> (*m_timeoutEventList.begin ()) == now)
1863 {
1864 HandleFragmentsTimeout (std::get<1> (*m_timeoutEventList.begin ()),
1865 std::get<2> (*m_timeoutEventList.begin ()),
1866 std::get<3> (*m_timeoutEventList.begin ()));
1867 m_timeoutEventList.pop_front ();
1868 }
1869
1870 if (m_timeoutEventList.empty ())
1871 {
1872 return;
1873 }
1874
1875 Time difference = std::get<0> (*m_timeoutEventList.begin ()) - now;
1877}
1878
1879} // namespace ns3
#define max(a, b)
Definition: 80211b.c:43
a polymophic address class
Definition: address.h:91
A record that that holds information about an ArpCache entry.
Definition: arp-cache.h:183
bool IsAlive(void)
Definition: arp-cache.cc:396
void UpdateSeen(void)
Update the entry when seeing a packet.
Definition: arp-cache.cc:569
std::list< ArpCache::Entry * > LookupInverse(Address destination)
Do lookup in the ARP cache against a MAC address.
Definition: arp-cache.cc:321
ArpCache::Entry * Lookup(Ipv4Address destination)
Do lookup in the ARP cache against an IP address.
Definition: arp-cache.cc:339
void Receive(Ptr< NetDevice > device, Ptr< const Packet > p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
Receive a packet.
static const uint16_t PROT_NUMBER
ARP protocol number (0x0806)
AttributeValue implementation for Boolean.
Definition: boolean.h:37
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:71
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
This is the implementation of the ICMP protocol as described in RFC 792.
static uint16_t GetStaticProtocolNumber(void)
Get the protocol number.
virtual int GetProtocolNumber(void) const =0
Returns the protocol number of this protocol.
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.
RxStatus
Rx status codes.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
uint32_t Get(void) const
Get the host-order 32-bit IP address.
bool IsMulticast(void) const
static Ipv4Address GetLoopback(void)
bool IsBroadcast(void) const
static Ipv4Address GetAny(void)
bool IsSubnetDirectedBroadcast(Ipv4Mask const &mask) const
Generate subnet-directed broadcast address corresponding to mask.
bool IsLocalMulticast(void) const
Ipv4Address CombineMask(Ipv4Mask const &mask) const
Combine this address with a network mask.
bool IsAny(void) const
Packet header for IPv4.
Definition: ipv4-header.h:34
void SetMoreFragments(void)
This packet is not the last packet of a fragmented ipv4 packet.
Definition: ipv4-header.cc:200
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:298
void SetLastFragment(void)
This packet is the last packet of a fragmented ipv4 packet.
Definition: ipv4-header.cc:206
virtual uint32_t GetSerializedSize(void) const
Definition: ipv4-header.cc:375
void SetPayloadSize(uint16_t size)
Definition: ipv4-header.cc:56
uint16_t GetIdentification(void) const
Definition: ipv4-header.cc:69
uint16_t GetFragmentOffset(void) const
Definition: ipv4-header.cc:246
uint8_t GetTos(void) const
Definition: ipv4-header.cc:194
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
void SetTtl(uint8_t ttl)
Definition: ipv4-header.cc:259
void SetMayFragment(void)
If you need to fragment this packet, you can do it.
Definition: ipv4-header.cc:225
void SetDontFragment(void)
Don't fragment this packet: if you need to anyway, drop it.
Definition: ipv4-header.cc:219
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
void EnableChecksum(void)
Enable checksum calculation for this header.
Definition: ipv4-header.cc:49
uint8_t GetProtocol(void) const
Definition: ipv4-header.cc:272
uint16_t GetPayloadSize(void) const
Definition: ipv4-header.cc:62
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:278
void SetFragmentOffset(uint16_t offsetBytes)
The offset is measured in bytes for the packet start.
Definition: ipv4-header.cc:238
void SetIdentification(uint16_t identification)
Definition: ipv4-header.cc:75
bool IsChecksumOk(void) const
Definition: ipv4-header.cc:312
bool IsLastFragment(void) const
Definition: ipv4-header.cc:212
void SetTos(uint8_t tos)
Definition: ipv4-header.cc:82
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:285
uint8_t GetTtl(void) const
Definition: ipv4-header.cc:265
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:77
a class to store IPv4 address information on an interface
Ipv4Address GetBroadcast(void) const
Get the broadcast address.
Ipv4InterfaceAddress::InterfaceAddressScope_e GetScope(void) const
Get address scope.
Ipv4Mask GetMask(void) const
Get the network mask.
Ipv4Address GetLocal(void) const
Get the local address.
bool IsSecondary(void) const
Check if the address is a secondary address.
The IPv4 representation of a network interface.
void SetUp(void)
Enable this interface.
void SetNode(Ptr< Node > node)
Set node associated with interface.
Ipv4InterfaceAddress GetAddress(uint32_t index) const
bool AddAddress(Ipv4InterfaceAddress address)
uint32_t GetNAddresses(void) const
Ptr< ArpCache > GetArpCache() const
uint16_t GetMetric(void) const
Ptr< NetDevice > GetDevice(void) const
void Send(Ptr< Packet > p, const Ipv4Header &hdr, Ipv4Address dest)
void SetDown(void)
Disable this interface.
bool IsUp(void) const
These are IP interface states and may be distinct from NetDevice states, such as found in real implem...
void SetForwarding(bool val)
void SetMetric(uint16_t metric)
bool IsEntire() const
If all fragments have been added.
Ptr< Packet > GetPartialPacket() const
Get the complete part of the packet.
FragmentsTimeoutsListI_t GetTimeoutIter()
Get the Timeout iterator.
void AddFragment(Ptr< Packet > fragment, uint16_t fragmentOffset, bool moreFragment)
Add a fragment.
Ptr< Packet > GetPacket() const
Get the entire packet.
void SetTimeoutIter(FragmentsTimeoutsListI_t iter)
Set the Timeout iterator.
Implement the IPv4 layer.
static const uint16_t PROT_NUMBER
Protocol number (0x0800)
std::tuple< uint64_t, uint8_t, Ipv4Address, Ipv4Address > DupTuple_t
IETF RFC 6621, Section 6.2 de-duplication w/o IPSec RFC 6621 recommended duplicate packet tuple: {IPV...
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.
@ DROP_BAD_CHECKSUM
Bad checksum.
@ DROP_NO_ROUTE
No route to host.
@ DROP_INTERFACE_DOWN
Interface is down so can not send packet.
@ DROP_DUPLICATE
Duplicate packet received.
@ DROP_TTL_EXPIRED
Packet TTL has expired.
@ DROP_ROUTE_ERROR
Route error.
@ DROP_FRAGMENT_TIMEOUT
Fragment timeout exceeded.
void DecreaseIdentification(Ipv4Address source, Ipv4Address destination, uint8_t protocol)
Decrease the identification value for a dropped or recursed packet.
Ipv4InterfaceList m_interfaces
List of IPv4 interfaces.
bool IsUp(uint32_t i) const
MapFragments_t m_fragments
Fragmented packets.
bool RemoveAddress(uint32_t interfaceIndex, uint32_t addressIndex)
Remove the address at addressIndex on named interface.
std::pair< uint64_t, uint32_t > FragmentKey_t
Key identifying a fragmented packet.
void DeleteRawSocket(Ptr< Socket > socket)
Deletes a particular raw socket.
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...
Time m_expire
duplicate entry expiration delay
virtual bool GetIpForward(void) const
Get the IP forwarding state.
bool m_ipForward
Forwarding packets (i.e.
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...
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 RouteInputError(Ptr< const Packet > p, const Ipv4Header &ipHeader, Socket::SocketErrno sockErrno)
Fallback when no route is found.
void SetForwarding(uint32_t i, bool val)
virtual void NotifyNewAggregate()
This function will notify other components connected to the node that a new stack member is now conne...
uint32_t GetNAddresses(uint32_t interface) const
uint16_t GetMtu(uint32_t i) const
virtual void SetIpForward(bool forward)
Set or unset the IP forwarding state.
virtual void SetWeakEsModel(bool model)
Set or unset the Weak Es Model.
virtual Ptr< IpL4Protocol > GetProtocol(int protocolNumber) const
Ptr< Ipv4RoutingProtocol > GetRoutingProtocol(void) const
Get the routing protocol to be used by this Ipv4 stack.
bool IsUnicast(Ipv4Address ad) const
Check if an IPv4 address is unicast according to the node.
void HandleFragmentsTimeout(FragmentKey_t key, Ipv4Header &ipHeader, uint32_t iif)
Process the timeout for packet fragments.
void DoFragmentation(Ptr< Packet > packet, const Ipv4Header &ipv4Header, uint32_t outIfaceMtu, std::list< Ipv4PayloadHeaderPair > &listFragments)
Fragment a packet.
SocketList m_sockets
List of IPv4 raw sockets.
virtual Ipv4Address SourceAddressSelection(uint32_t interface, Ipv4Address dest)
Choose the source address to use with destination address.
bool m_enableDpd
Enable multicast duplicate packet detection.
bool AddAddress(uint32_t i, Ipv4InterfaceAddress address)
std::map< std::pair< uint64_t, uint8_t >, uint16_t > m_identification
Identification (for each {src, dst, proto} tuple)
Time m_fragmentExpirationTimeout
Expiration timeout.
static TypeId GetTypeId(void)
Get the type ID.
TracedCallback< const Ipv4Header &, Ptr< const Packet >, uint32_t > m_localDeliverTrace
Trace of locally delivered packets.
virtual void Remove(Ptr< IpL4Protocol > protocol)
void HandleTimeout(void)
Handles a fragmented packet timeout.
Ptr< NetDevice > GetNetDevice(uint32_t i)
EventId m_timeoutEvent
Event for the next scheduled timeout.
void SetRoutingProtocol(Ptr< Ipv4RoutingProtocol > routingProtocol)
Register a new routing protocol to be used by this Ipv4 stack.
Time m_purge
time between purging expired duplicate entries
TracedCallback< const Ipv4Header &, Ptr< const Packet >, DropReason, Ptr< Ipv4 >, uint32_t > m_dropTrace
Trace of dropped packets.
void SetNode(Ptr< Node > node)
Set node associated with this stack.
void IpMulticastForward(Ptr< Ipv4MulticastRoute > mrtentry, Ptr< const Packet > p, const Ipv4Header &header)
Forward a multicast packet.
TracedCallback< Ptr< const Packet >, Ptr< Ipv4 >, uint32_t > m_rxTrace
Trace of received packets.
uint16_t GetMetric(uint32_t i) const
void RemoveDuplicates(void)
Remove expired duplicates packet entry.
FragmentsTimeoutsList_t m_timeoutEventList
Timeout "events" container.
bool IsForwarding(uint32_t i) const
TracedCallback< const Ipv4Header &, Ptr< const Packet >, uint32_t > m_sendOutgoingTrace
Trace of sent packets.
TracedCallback< Ptr< const Packet >, Ptr< Ipv4 >, uint32_t > m_txTrace
Trace of transmitted packets.
void SendWithHeader(Ptr< Packet > packet, Ipv4Header ipHeader, Ptr< Ipv4Route > route)
bool ProcessFragment(Ptr< Packet > &packet, Ipv4Header &ipHeader, uint32_t iif)
Process a packet fragment.
void SetUp(uint32_t i)
Ipv4InterfaceReverseContainer m_reverseInterfacesContainer
Container of NetDevice / Interface index associations.
void SetupLoopback(void)
Setup loopback interface.
void LocalDeliver(Ptr< const Packet > p, Ipv4Header const &ip, uint32_t iif)
Deliver a packet.
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,...
EventId m_cleanDpd
event to cleanup expired duplicate entries
void SetDown(uint32_t i)
L4List_t m_protocols
List of transport protocol.
Ptr< Socket > CreateRawSocket(void)
Creates a raw socket.
Ptr< Ipv4RoutingProtocol > m_routingProtocol
Routing protocol associated with the stack.
void Send(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol, Ptr< Ipv4Route > route)
void SendRealOut(Ptr< Ipv4Route > route, Ptr< Packet > packet, Ipv4Header const &ipHeader)
Send packet with route.
Ptr< Icmpv4L4Protocol > GetIcmp(void) const
Get ICMPv4 protocol.
uint32_t AddInterface(Ptr< NetDevice > device)
virtual void DoDispose(void)
Destructor implementation.
uint8_t m_defaultTtl
Default TTL.
bool m_weakEsModel
Weak ES model state.
TracedCallback< const Ipv4Header &, Ptr< const Packet >, uint32_t > m_unicastForwardTrace
Trace of unicast forwarded packets.
void SetMetric(uint32_t i, uint16_t metric)
DupMap_t m_dups
map of packet duplicate tuples to expiry event
Ptr< Node > m_node
Node attached to stack.
bool UpdateDuplicate(Ptr< const Packet > p, const Ipv4Header &header)
Registers duplicate entry, return false if new.
virtual void Insert(Ptr< IpL4Protocol > protocol)
int32_t GetInterfaceForAddress(Ipv4Address addr) const
Return the interface number of the interface that has been assigned the specified IP address.
Ptr< Ipv4Interface > GetInterface(uint32_t i) const
Get an interface.
void IpForward(Ptr< Ipv4Route > rtentry, Ptr< const Packet > p, const Ipv4Header &header)
Forward a packet.
std::list< std::tuple< Time, FragmentKey_t, Ipv4Header, uint32_t > >::iterator FragmentsTimeoutsListI_t
Container Iterator for fragment timeouts..
void SetDefaultTtl(uint8_t ttl)
int32_t GetInterfaceForDevice(Ptr< const NetDevice > device) const
uint32_t GetNInterfaces(void) const
FragmentsTimeoutsListI_t SetTimeout(FragmentKey_t key, Ipv4Header ipHeader, uint32_t iif)
Set a new timeout "event" for a fragmented packet.
virtual bool GetWeakEsModel(void) const
Get the Weak Es Model status.
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...
std::pair< int, int32_t > L4ListKey_t
Container of the IPv4 L4 keys: protocol number, interface index.
bool IsDestinationAddress(Ipv4Address address, uint32_t iif) const
Determine whether address and interface corresponding to received packet can be accepted for local de...
uint32_t AddIpv4Interface(Ptr< Ipv4Interface > interface)
Add an IPv4 interface to the stack.
TracedCallback< const Ipv4Header &, Ptr< const Packet >, uint32_t > m_multicastForwardTrace
Trace of multicast forwarded packets.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:256
static Ipv4Mask GetLoopback(void)
bool ForwardUp(Ptr< const Packet > p, Ipv4Header ipHeader, Ptr< Ipv4Interface > incomingInterface)
Forward up to receive method.
void SetNode(Ptr< Node > node)
Set the node associated with this socket.
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:297
static bool ChecksumEnabled(void)
Definition: node.cc:278
uint32_t GetId(void) const
Definition: node.cc:109
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:130
uint32_t GetNDevices(void) const
Definition: node.cc:152
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:144
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:229
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
virtual void NotifyNewAggregate(void)
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:325
Container for a set of ns3::Object pointers.
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:963
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:335
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:378
void RemoveAtEnd(uint32_t size)
Remove size bytes from the end of the current packet.
Definition: packet.cc:355
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:390
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:956
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
Definition: packet.cc:227
void Print(std::ostream &os) const
Print the packet contents.
Definition: packet.cc:434
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:555
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
static uint8_t IpTos2Priority(uint8_t ipTos)
Return the priority corresponding to a given TOS value.
Definition: socket.cc:401
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
indicates whether the socket has IP_TOS set.
Definition: socket.h:1263
uint8_t GetTos(void) const
Get the tag's TOS.
Definition: socket.cc:790
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer.
Definition: socket.h:1117
uint8_t GetTtl(void) const
Get the tag's TTL.
Definition: socket.cc:610
indicates whether the socket has a priority set.
Definition: socket.h:1309
void SetPriority(uint8_t priority)
Set the tag's priority.
Definition: socket.cc:841
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
bool IsStrictlyPositive(void) const
Exactly equivalent to t > 0.
Definition: nstime.h:333
AttributeValue implementation for Time.
Definition: nstime.h:1309
Introspection did not find any typical Config paths.
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.
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Hold an unsigned integer type.
Definition: uinteger.h:44
#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
#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:88
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:85
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-vector.h:81
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1310
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:45
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
uint32_t Hash32(const char *buffer, const std::size_t size)
Compute 32-bit hash of a byte buffer, using the default hash function.
Definition: hash.h:282
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:258
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:206
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:274
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:290
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:266
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:576
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1245
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1253
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Definition: first.py:1
address
Definition: first.py:40
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:489
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:661
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:522
Definition: second.py:1
#define list