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 return;
268}
269/*
270 * This method is called by AggregateObject and completes the aggregation
271 * by setting the node in the ipv4 stack
272 */
273void
275{
276 NS_LOG_FUNCTION (this);
277 if (m_node == 0)
278 {
279 Ptr<Node>node = this->GetObject<Node>();
280 // verify that it's a valid node and that
281 // the node has not been set before
282 if (node != 0)
283 {
284 this->SetNode (node);
285 }
286 }
288}
289
290void
292{
293 NS_LOG_FUNCTION (this << routingProtocol);
294 m_routingProtocol = routingProtocol;
295 m_routingProtocol->SetIpv4 (this);
296}
297
298
301{
302 NS_LOG_FUNCTION (this);
303 return m_routingProtocol;
304}
305
306void
308{
309 NS_LOG_FUNCTION (this);
310 for (L4List_t::iterator i = m_protocols.begin (); i != m_protocols.end (); ++i)
311 {
312 i->second = 0;
313 }
314 m_protocols.clear ();
315
316 for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); ++i)
317 {
318 *i = 0;
319 }
320 m_interfaces.clear ();
322
323 m_sockets.clear ();
324 m_node = 0;
326
327 for (MapFragments_t::iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
328 {
329 it->second = 0;
330 }
331
332 m_fragments.clear ();
333 m_timeoutEventList.clear ();
335 {
337 }
338
339 if (m_cleanDpd.IsRunning ())
340 {
342 }
343 m_dups.clear ();
344
346}
347
348void
350{
351 NS_LOG_FUNCTION (this);
352
354 Ptr<LoopbackNetDevice> device = 0;
355 // First check whether an existing LoopbackNetDevice exists on the node
356 for (uint32_t i = 0; i < m_node->GetNDevices (); i++)
357 {
358 if ((device = DynamicCast<LoopbackNetDevice> (m_node->GetDevice (i))))
359 {
360 break;
361 }
362 }
363 if (device == 0)
364 {
365 device = CreateObject<LoopbackNetDevice> ();
366 m_node->AddDevice (device);
367 }
368 interface->SetDevice (device);
369 interface->SetNode (m_node);
371 interface->AddAddress (ifaceAddr);
372 uint32_t index = AddIpv4Interface (interface);
373 Ptr<Node> node = GetObject<Node> ();
376 interface->SetUp ();
377 if (m_routingProtocol != 0)
378 {
379 m_routingProtocol->NotifyInterfaceUp (index);
380 }
381}
382
383void
385{
386 NS_LOG_FUNCTION (this << static_cast<uint32_t> (ttl));
387 m_defaultTtl = ttl;
388}
389
392{
393 NS_LOG_FUNCTION (this << device);
394 NS_ASSERT (m_node != 0);
395
397
398 NS_ASSERT (tc != 0);
399
404
405 tc->RegisterProtocolHandler (MakeCallback (&Ipv4L3Protocol::Receive, this),
407 tc->RegisterProtocolHandler (MakeCallback (&ArpL3Protocol::Receive, PeekPointer (GetObject<ArpL3Protocol> ())),
409
411 interface->SetNode (m_node);
412 interface->SetDevice (device);
413 interface->SetTrafficControl (tc);
414 interface->SetForwarding (m_ipForward);
415 return AddIpv4Interface (interface);
416}
417
420{
421 NS_LOG_FUNCTION (this << interface);
422 uint32_t index = m_interfaces.size ();
423 m_interfaces.push_back (interface);
424 m_reverseInterfacesContainer[interface->GetDevice ()] = index;
425 return index;
426}
427
430{
431 NS_LOG_FUNCTION (this << index);
432 if (index < m_interfaces.size ())
433 {
434 return m_interfaces[index];
435 }
436 return 0;
437}
438
441{
442 NS_LOG_FUNCTION (this);
443 return m_interfaces.size ();
444}
445
446int32_t
448 Ipv4Address address) const
449{
450 NS_LOG_FUNCTION (this << address);
451 int32_t interface = 0;
452 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
453 i != m_interfaces.end ();
454 i++, interface++)
455 {
456 for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
457 {
458 if ((*i)->GetAddress (j).GetLocal () == address)
459 {
460 return interface;
461 }
462 }
463 }
464
465 return -1;
466}
467
468int32_t
471 Ipv4Mask mask) const
472{
473 NS_LOG_FUNCTION (this << address << mask);
474 int32_t interface = 0;
475 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
476 i != m_interfaces.end ();
477 i++, interface++)
478 {
479 for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
480 {
481 if ((*i)->GetAddress (j).GetLocal ().CombineMask (mask) == address.CombineMask (mask))
482 {
483 return interface;
484 }
485 }
486 }
487
488 return -1;
489}
490
491int32_t
493 Ptr<const NetDevice> device) const
494{
495 NS_LOG_FUNCTION (this << device);
496
497 Ipv4InterfaceReverseContainer::const_iterator iter = m_reverseInterfacesContainer.find (device);
498 if (iter != m_reverseInterfacesContainer.end ())
499 {
500 return (*iter).second;
501 }
502
503 return -1;
504}
505
506bool
508{
509 NS_LOG_FUNCTION (this << address << iif);
510 // First check the incoming interface for a unicast address match
511 for (uint32_t i = 0; i < GetNAddresses (iif); i++)
512 {
513 Ipv4InterfaceAddress iaddr = GetAddress (iif, i);
514 if (address == iaddr.GetLocal ())
515 {
516 NS_LOG_LOGIC ("For me (destination " << address << " match)");
517 return true;
518 }
519 if (address == iaddr.GetBroadcast ())
520 {
521 NS_LOG_LOGIC ("For me (interface broadcast address)");
522 return true;
523 }
524 }
525
526 if (address.IsMulticast ())
527 {
528#ifdef NOTYET
529 if (MulticastCheckGroup (iif, address ))
530#endif
531 if (true)
532 {
533 NS_LOG_LOGIC ("For me (Ipv4Addr multicast address)");
534 return true;
535 }
536 }
537
538 if (address.IsBroadcast ())
539 {
540 NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)");
541 return true;
542 }
543
544 if (GetWeakEsModel ()) // Check other interfaces
545 {
546 for (uint32_t j = 0; j < GetNInterfaces (); j++)
547 {
548 if (j == uint32_t (iif)) continue;
549 for (uint32_t i = 0; i < GetNAddresses (j); i++)
550 {
551 Ipv4InterfaceAddress iaddr = GetAddress (j, i);
552 if (address == iaddr.GetLocal ())
553 {
554 NS_LOG_LOGIC ("For me (destination " << address << " match) on another interface");
555 return true;
556 }
557 // This is a small corner case: match another interface's broadcast address
558 if (address == iaddr.GetBroadcast ())
559 {
560 NS_LOG_LOGIC ("For me (interface broadcast address on another interface)");
561 return true;
562 }
563 }
564 }
565 }
566 return false;
567}
568
569void
570Ipv4L3Protocol::Receive ( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
571 const Address &to, NetDevice::PacketType packetType)
572{
573 NS_LOG_FUNCTION (this << device << p << protocol << from << to << packetType);
574
575 NS_LOG_LOGIC ("Packet from " << from << " received on node " <<
576 m_node->GetId ());
577
578
579 int32_t interface = GetInterfaceForDevice(device);
580 NS_ASSERT_MSG (interface != -1, "Received a packet from an interface that is not known to IPv4");
581
582 Ptr<Packet> packet = p->Copy ();
583
584 Ptr<Ipv4Interface> ipv4Interface = m_interfaces[interface];
585
586 if (ipv4Interface->IsUp ())
587 {
588 m_rxTrace (packet, this, interface);
589 }
590 else
591 {
592 NS_LOG_LOGIC ("Dropping received packet -- interface is down");
593 Ipv4Header ipHeader;
594 packet->RemoveHeader (ipHeader);
595 m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, this, interface);
596 return;
597 }
598
599 Ipv4Header ipHeader;
601 {
602 ipHeader.EnableChecksum ();
603 }
604 packet->RemoveHeader (ipHeader);
605
606 // Trim any residual frame padding from underlying devices
607 if (ipHeader.GetPayloadSize () < packet->GetSize ())
608 {
609 packet->RemoveAtEnd (packet->GetSize () - ipHeader.GetPayloadSize ());
610 }
611
612 if (!ipHeader.IsChecksumOk ())
613 {
614 NS_LOG_LOGIC ("Dropping received packet -- checksum not ok");
615 m_dropTrace (ipHeader, packet, DROP_BAD_CHECKSUM, this, interface);
616 return;
617 }
618
619 // the packet is valid, we update the ARP cache entry (if present)
620 Ptr<ArpCache> arpCache = ipv4Interface->GetArpCache ();
621 if (arpCache)
622 {
623 // case one, it's a a direct routing.
624 ArpCache::Entry *entry = arpCache->Lookup (ipHeader.GetSource ());
625 if (entry)
626 {
627 if (entry->IsAlive ())
628 {
629 entry->UpdateSeen ();
630 }
631 }
632 else
633 {
634 // It's not in the direct routing, so it's the router, and it could have multiple IP addresses.
635 // In doubt, update all of them.
636 // Note: it's a confirmed behavior for Linux routers.
637 std::list<ArpCache::Entry *> entryList = arpCache->LookupInverse (from);
638 std::list<ArpCache::Entry *>::iterator iter;
639 for (iter = entryList.begin (); iter != entryList.end (); iter ++)
640 {
641 if ((*iter)->IsAlive ())
642 {
643 (*iter)->UpdateSeen ();
644 }
645 }
646 }
647 }
648
649 for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
650 {
651 NS_LOG_LOGIC ("Forwarding to raw socket");
652 Ptr<Ipv4RawSocketImpl> socket = *i;
653 socket->ForwardUp (packet, ipHeader, ipv4Interface);
654 }
655
656 if (m_enableDpd && ipHeader.GetDestination ().IsMulticast () && UpdateDuplicate (packet, ipHeader))
657 {
658 NS_LOG_LOGIC ("Dropping received packet -- duplicate.");
659 m_dropTrace (ipHeader, packet, DROP_DUPLICATE, this, interface);
660 return;
661 }
662
663 NS_ASSERT_MSG (m_routingProtocol != 0, "Need a routing protocol object to process packets");
664 if (!m_routingProtocol->RouteInput (packet, ipHeader, device,
669 ))
670 {
671 NS_LOG_WARN ("No route found for forwarding packet. Drop.");
672 m_dropTrace (ipHeader, packet, DROP_NO_ROUTE, this, interface);
673 }
674}
675
678{
679 NS_LOG_FUNCTION (this);
681 if (prot != 0)
682 {
683 return prot->GetObject<Icmpv4L4Protocol> ();
684 }
685 else
686 {
687 return 0;
688 }
689}
690
691bool
693{
694 NS_LOG_FUNCTION (this << ad);
695
696 if (ad.IsBroadcast () || ad.IsMulticast ())
697 {
698 return false;
699 }
700 else
701 {
702 // check for subnet-broadcast
703 for (uint32_t ifaceIndex = 0; ifaceIndex < GetNInterfaces (); ifaceIndex++)
704 {
705 for (uint32_t j = 0; j < GetNAddresses (ifaceIndex); j++)
706 {
707 Ipv4InterfaceAddress ifAddr = GetAddress (ifaceIndex, j);
708 NS_LOG_LOGIC ("Testing address " << ad << " with subnet-directed broadcast " << ifAddr.GetBroadcast () );
709 if (ad == ifAddr.GetBroadcast () )
710 {
711 return false;
712 }
713 }
714 }
715 }
716
717 return true;
718}
719
720bool
722{
723 NS_LOG_FUNCTION (this << ad << interfaceMask);
724 return !ad.IsMulticast () && !ad.IsSubnetDirectedBroadcast (interfaceMask);
725}
726
727void
729 Ipv4Header ipHeader,
730 Ptr<Ipv4Route> route)
731{
732 NS_LOG_FUNCTION (this << packet << ipHeader << route);
734 {
735 ipHeader.EnableChecksum ();
736 }
737 SendRealOut (route, packet, ipHeader);
738}
739
740void
742 Ptr<Ipv4> ipv4, uint32_t interface)
743{
744 if (!m_txTrace.IsEmpty ())
745 {
746 Ptr<Packet> packetCopy = packet->Copy ();
747 packetCopy->AddHeader (ipHeader);
748 m_txTrace (packetCopy, ipv4, interface);
749 }
750}
751
752void
754 Ipv4Address source,
755 Ipv4Address destination,
756 uint8_t protocol,
757 Ptr<Ipv4Route> route)
758{
759 NS_LOG_FUNCTION (this << packet << source << destination << uint32_t (protocol) << route);
760
761 bool mayFragment = true;
762
763 // we need a copy of the packet with its tags in case we need to invoke recursion.
764 Ptr<Packet> pktCopyWithTags = packet->Copy ();
765
766 uint8_t ttl = m_defaultTtl;
767 SocketIpTtlTag ipTtlTag;
768 bool ipTtlTagFound = packet->RemovePacketTag (ipTtlTag);
769 if (ipTtlTagFound)
770 {
771 ttl = ipTtlTag.GetTtl ();
772 }
773
774 uint8_t tos = 0;
775 SocketIpTosTag ipTosTag;
776 bool ipTosTagFound = packet->RemovePacketTag (ipTosTag);
777 if (ipTosTagFound)
778 {
779 tos = ipTosTag.GetTos ();
780 }
781
782 // can construct the header here
783 Ipv4Header ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tos, mayFragment);
784
785 // Handle a few cases:
786 // 1) packet is passed in with a route entry
787 // 1a) packet is passed in with a route entry but route->GetGateway is not set (e.g., on-demand)
788 // 1b) packet is passed in with a route entry and valid gateway
789 // 2) packet is passed without a route and packet is destined to limited broadcast address
790 // 3) packet is passed without a route and packet is destined to a subnet-directed broadcast address
791 // 4) packet is passed without a route, packet is not broadcast (e.g., a raw socket call, or ICMP)
792
793 // 1) packet is passed in with route entry
794 if (route)
795 {
796 // 1a) route->GetGateway is not set (e.g., on-demand)
797 if (!route->GetGateway ().IsInitialized ())
798 {
799 // This could arise because the synchronous RouteOutput() call
800 // returned to the transport protocol with a source address but
801 // there was no next hop available yet (since a route may need
802 // to be queried).
803 NS_FATAL_ERROR ("Ipv4L3Protocol::Send case 1a: packet passed with a route but the Gateway address is uninitialized. This case not yet implemented.");
804 }
805
806 // 1b) with a valid gateway
807 NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 1b: passed in with route and valid gateway");
808 int32_t interface = GetInterfaceForDevice (route->GetOutputDevice ());
809 m_sendOutgoingTrace (ipHeader, packet, interface);
810 if (m_enableDpd && ipHeader.GetDestination ().IsMulticast ())
811 {
812 UpdateDuplicate (packet, ipHeader);
813 }
814 SendRealOut (route, packet->Copy (), ipHeader);
815 return;
816 }
817
818 // 2) packet is destined to limited broadcast address or link-local multicast address
819 if (destination.IsBroadcast () || destination.IsLocalMulticast ())
820 {
821 NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 2: limited broadcast - no route");
822 uint32_t ifaceIndex = 0;
823 for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
824 ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
825 {
826 Ptr<Ipv4Interface> outInterface = *ifaceIter;
827 // ANY source matches any interface
828 bool sendIt = source.IsAny ();
829 // check if some specific address on outInterface matches
830 for (uint32_t index = 0; !sendIt && index < outInterface->GetNAddresses (); index++)
831 {
832 if (outInterface->GetAddress (index).GetLocal () == source)
833 {
834 sendIt = true;
835 }
836 }
837
838 if (sendIt)
839 {
840 // create a proxy route for this interface
841 Ptr<Ipv4Route> route = Create<Ipv4Route> ();
842 route->SetDestination (destination);
843 route->SetGateway (Ipv4Address::GetAny ());
844 route->SetSource (source);
845 route->SetOutputDevice (outInterface->GetDevice ());
846 DecreaseIdentification (source, destination, protocol);
847 Send (pktCopyWithTags, source, destination, protocol, route);
848 }
849 }
850 return;
851 }
852
853 // 3) check: packet is destined to a subnet-directed broadcast address
854 for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
855 ifaceIter != m_interfaces.end (); ifaceIter++)
856 {
857 Ptr<Ipv4Interface> outInterface = *ifaceIter;
858 uint32_t ifaceIndex = GetInterfaceForDevice (outInterface->GetDevice ());
859 for (uint32_t j = 0; j < GetNAddresses (ifaceIndex); j++)
860 {
861 Ipv4InterfaceAddress ifAddr = GetAddress (ifaceIndex, j);
862 NS_LOG_LOGIC ("Testing address " << ifAddr.GetLocal () << " with mask " << ifAddr.GetMask ());
863 if (destination.IsSubnetDirectedBroadcast (ifAddr.GetMask ()) &&
864 destination.CombineMask (ifAddr.GetMask ()) == ifAddr.GetLocal ().CombineMask (ifAddr.GetMask ()) )
865 {
866 NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 3: subnet directed bcast to " << ifAddr.GetLocal () << " - no route");
867 // create a proxy route for this interface
868 Ptr<Ipv4Route> route = Create<Ipv4Route> ();
869 route->SetDestination (destination);
870 route->SetGateway (Ipv4Address::GetAny ());
871 route->SetSource (source);
872 route->SetOutputDevice (outInterface->GetDevice ());
873 DecreaseIdentification (source, destination, protocol);
874 Send (pktCopyWithTags, source, destination, protocol, route);
875 return;
876 }
877 }
878 }
879
880 // 4) packet is not broadcast, and route is NULL (e.g., a raw socket call)
881 NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 4: not broadcast and passed in with no route " << destination);
882 Socket::SocketErrno errno_;
883 Ptr<NetDevice> oif (0); // unused for now
884 Ptr<Ipv4Route> newRoute;
885 if (m_routingProtocol != 0)
886 {
887 newRoute = m_routingProtocol->RouteOutput (pktCopyWithTags, ipHeader, oif, errno_);
888 }
889 else
890 {
891 NS_LOG_ERROR ("Ipv4L3Protocol::Send: m_routingProtocol == 0");
892 }
893 if (newRoute)
894 {
895 DecreaseIdentification (source, destination, protocol);
896 Send (pktCopyWithTags, source, destination, protocol, newRoute);
897 }
898 else
899 {
900 NS_LOG_WARN ("No route to host. Drop.");
901 m_dropTrace (ipHeader, packet, DROP_NO_ROUTE, this, 0);
902 DecreaseIdentification (source, destination, protocol);
903 }
904}
905
906void
908 Ipv4Address destination,
909 uint8_t protocol)
910{
911 uint64_t src = source.Get ();
912 uint64_t dst = destination.Get ();
913 uint64_t srcDst = dst | (src << 32);
914 std::pair<uint64_t, uint8_t> key = std::make_pair (srcDst, protocol);
915 m_identification[key]--;
916}
917
920 Ipv4Address source,
921 Ipv4Address destination,
922 uint8_t protocol,
923 uint16_t payloadSize,
924 uint8_t ttl,
925 uint8_t tos,
926 bool mayFragment)
927{
928 NS_LOG_FUNCTION (this << source << destination << (uint16_t)protocol << payloadSize << (uint16_t)ttl << (uint16_t)tos << mayFragment);
929 Ipv4Header ipHeader;
930 ipHeader.SetSource (source);
931 ipHeader.SetDestination (destination);
932 ipHeader.SetProtocol (protocol);
933 ipHeader.SetPayloadSize (payloadSize);
934 ipHeader.SetTtl (ttl);
935 ipHeader.SetTos (tos);
936
937 uint64_t src = source.Get ();
938 uint64_t dst = destination.Get ();
939 uint64_t srcDst = dst | (src << 32);
940 std::pair<uint64_t, uint8_t> key = std::make_pair (srcDst, protocol);
941
942 if (mayFragment == true)
943 {
944 ipHeader.SetMayFragment ();
945 ipHeader.SetIdentification (m_identification[key]);
946 m_identification[key]++;
947 }
948 else
949 {
950 ipHeader.SetDontFragment ();
951 // RFC 6864 does not state anything about atomic datagrams
952 // identification requirement:
953 // >> Originating sources MAY set the IPv4 ID field of atomic datagrams
954 // to any value.
955 ipHeader.SetIdentification (m_identification[key]);
956 m_identification[key]++;
957 }
959 {
960 ipHeader.EnableChecksum ();
961 }
962 return ipHeader;
963}
964
965void
967 Ptr<Packet> packet,
968 Ipv4Header const &ipHeader)
969{
970 NS_LOG_FUNCTION (this << route << packet << &ipHeader);
971 if (route == 0)
972 {
973 NS_LOG_WARN ("No route to host. Drop.");
974 m_dropTrace (ipHeader, packet, DROP_NO_ROUTE, this, 0);
975 return;
976 }
977 Ptr<NetDevice> outDev = route->GetOutputDevice ();
978 int32_t interface = GetInterfaceForDevice (outDev);
979 NS_ASSERT (interface >= 0);
980 Ptr<Ipv4Interface> outInterface = GetInterface (interface);
981 NS_LOG_LOGIC ("Send via NetDevice ifIndex " << outDev->GetIfIndex () << " ipv4InterfaceIndex " << interface);
982
983 Ipv4Address target;
984 std::string targetLabel;
985 if (route->GetGateway ().IsAny ())
986 {
987 target = ipHeader.GetDestination ();
988 targetLabel = "destination";
989 }
990 else
991 {
992 target = route->GetGateway ();
993 targetLabel = "gateway";
994 }
995
996 if (outInterface->IsUp ())
997 {
998 NS_LOG_LOGIC ("Send to " << targetLabel << " " << target);
999 if ( packet->GetSize () + ipHeader.GetSerializedSize () > outInterface->GetDevice ()->GetMtu () )
1000 {
1001 std::list<Ipv4PayloadHeaderPair> listFragments;
1002 DoFragmentation (packet, ipHeader, outInterface->GetDevice ()->GetMtu (), listFragments);
1003 for ( std::list<Ipv4PayloadHeaderPair>::iterator it = listFragments.begin (); it != listFragments.end (); it++ )
1004 {
1005 NS_LOG_LOGIC ("Sending fragment " << *(it->first) );
1006 CallTxTrace (it->second, it->first, this, interface);
1007 outInterface->Send (it->first, it->second, target);
1008 }
1009 }
1010 else
1011 {
1012 CallTxTrace (ipHeader, packet, this, interface);
1013 outInterface->Send (packet, ipHeader, target);
1014 }
1015 }
1016}
1017
1018// This function analogous to Linux ip_mr_forward()
1019void
1021{
1022 NS_LOG_FUNCTION (this << mrtentry << p << header);
1023 NS_LOG_LOGIC ("Multicast forwarding logic for node: " << m_node->GetId ());
1024
1025 std::map<uint32_t, uint32_t> ttlMap = mrtentry->GetOutputTtlMap ();
1026 std::map<uint32_t, uint32_t>::iterator mapIter;
1027
1028 for (mapIter = ttlMap.begin (); mapIter != ttlMap.end (); mapIter++)
1029 {
1030 uint32_t interface = mapIter->first;
1031 //uint32_t outputTtl = mapIter->second; // Unused for now
1032
1033 Ptr<Packet> packet = p->Copy ();
1034 Ipv4Header ipHeader = header;
1035 ipHeader.SetTtl (header.GetTtl () - 1);
1036 if (ipHeader.GetTtl () == 0)
1037 {
1038 NS_LOG_WARN ("TTL exceeded. Drop.");
1039 m_dropTrace (header, packet, DROP_TTL_EXPIRED, this, interface);
1040 return;
1041 }
1042 NS_LOG_LOGIC ("Forward multicast via interface " << interface);
1043 Ptr<Ipv4Route> rtentry = Create<Ipv4Route> ();
1044 rtentry->SetSource (ipHeader.GetSource ());
1045 rtentry->SetDestination (ipHeader.GetDestination ());
1046 rtentry->SetGateway (Ipv4Address::GetAny ());
1047 rtentry->SetOutputDevice (GetNetDevice (interface));
1048
1049 m_multicastForwardTrace (ipHeader, packet, interface);
1050 SendRealOut (rtentry, packet, ipHeader);
1051 continue;
1052 }
1053}
1054
1055// This function analogous to Linux ip_forward()
1056void
1058{
1059 NS_LOG_FUNCTION (this << rtentry << p << header);
1060 NS_LOG_LOGIC ("Forwarding logic for node: " << m_node->GetId ());
1061 // Forwarding
1062 Ipv4Header ipHeader = header;
1063 Ptr<Packet> packet = p->Copy ();
1064 int32_t interface = GetInterfaceForDevice (rtentry->GetOutputDevice ());
1065 ipHeader.SetTtl (ipHeader.GetTtl () - 1);
1066 if (ipHeader.GetTtl () == 0)
1067 {
1068 // Do not reply to multicast/broadcast IP address
1069 if (ipHeader.GetDestination ().IsBroadcast () == false &&
1070 ipHeader.GetDestination ().IsMulticast () == false)
1071 {
1073 icmp->SendTimeExceededTtl (ipHeader, packet, false);
1074 }
1075 NS_LOG_WARN ("TTL exceeded. Drop.");
1076 m_dropTrace (header, packet, DROP_TTL_EXPIRED, this, interface);
1077 return;
1078 }
1079 // in case the packet still has a priority tag attached, remove it
1080 SocketPriorityTag priorityTag;
1081 packet->RemovePacketTag (priorityTag);
1082 uint8_t priority = Socket::IpTos2Priority (ipHeader.GetTos ());
1083 // add a priority tag if the priority is not null
1084 if (priority)
1085 {
1086 priorityTag.SetPriority (priority);
1087 packet->AddPacketTag (priorityTag);
1088 }
1089
1090 m_unicastForwardTrace (ipHeader, packet, interface);
1091 SendRealOut (rtentry, packet, ipHeader);
1092}
1093
1094void
1096{
1097 NS_LOG_FUNCTION (this << packet << &ip << iif);
1098 Ptr<Packet> p = packet->Copy (); // need to pass a non-const packet up
1099 Ipv4Header ipHeader = ip;
1100
1101 if ( !ipHeader.IsLastFragment () || ipHeader.GetFragmentOffset () != 0 )
1102 {
1103 NS_LOG_LOGIC ("Received a fragment, processing " << *p );
1104 bool isPacketComplete;
1105 isPacketComplete = ProcessFragment (p, ipHeader, iif);
1106 if ( isPacketComplete == false)
1107 {
1108 return;
1109 }
1110 NS_LOG_LOGIC ("Got last fragment, Packet is complete " << *p );
1111 ipHeader.SetFragmentOffset (0);
1112 ipHeader.SetPayloadSize (p->GetSize ());
1113 }
1114
1115 m_localDeliverTrace (ipHeader, p, iif);
1116
1117 Ptr<IpL4Protocol> protocol = GetProtocol (ipHeader.GetProtocol (), iif);
1118 if (protocol != 0)
1119 {
1120 // we need to make a copy in the unlikely event we hit the
1121 // RX_ENDPOINT_UNREACH codepath
1122 Ptr<Packet> copy = p->Copy ();
1123 enum IpL4Protocol::RxStatus status =
1124 protocol->Receive (p, ipHeader, GetInterface (iif));
1125 switch (status) {
1127 // fall through
1129 // fall through
1131 break;
1133 if (ipHeader.GetDestination ().IsBroadcast () == true ||
1134 ipHeader.GetDestination ().IsMulticast () == true)
1135 {
1136 break; // Do not reply to broadcast or multicast
1137 }
1138 // Another case to suppress ICMP is a subnet-directed broadcast
1139 bool subnetDirected = false;
1140 for (uint32_t i = 0; i < GetNAddresses (iif); i++)
1141 {
1142 Ipv4InterfaceAddress addr = GetAddress (iif, i);
1143 if (addr.GetLocal ().CombineMask (addr.GetMask ()) == ipHeader.GetDestination ().CombineMask (addr.GetMask ()) &&
1144 ipHeader.GetDestination ().IsSubnetDirectedBroadcast (addr.GetMask ()))
1145 {
1146 subnetDirected = true;
1147 }
1148 }
1149 if (subnetDirected == false)
1150 {
1151 GetIcmp ()->SendDestUnreachPort (ipHeader, copy);
1152 }
1153 }
1154 }
1155}
1156
1157bool
1159{
1160 NS_LOG_FUNCTION (this << i << address);
1161 Ptr<Ipv4Interface> interface = GetInterface (i);
1162 bool retVal = interface->AddAddress (address);
1163 if (m_routingProtocol != 0)
1164 {
1165 m_routingProtocol->NotifyAddAddress (i, address);
1166 }
1167 return retVal;
1168}
1169
1171Ipv4L3Protocol::GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const
1172{
1173 NS_LOG_FUNCTION (this << interfaceIndex << addressIndex);
1174 Ptr<Ipv4Interface> interface = GetInterface (interfaceIndex);
1175 return interface->GetAddress (addressIndex);
1176}
1177
1178uint32_t
1180{
1181 NS_LOG_FUNCTION (this << interface);
1182 Ptr<Ipv4Interface> iface = GetInterface (interface);
1183 return iface->GetNAddresses ();
1184}
1185
1186bool
1188{
1189 NS_LOG_FUNCTION (this << i << addressIndex);
1190 Ptr<Ipv4Interface> interface = GetInterface (i);
1191 Ipv4InterfaceAddress address = interface->RemoveAddress (addressIndex);
1192 if (address != Ipv4InterfaceAddress ())
1193 {
1194 if (m_routingProtocol != 0)
1195 {
1196 m_routingProtocol->NotifyRemoveAddress (i, address);
1197 }
1198 return true;
1199 }
1200 return false;
1201}
1202
1203bool
1205{
1206 NS_LOG_FUNCTION (this << i << address);
1207
1209 {
1210 NS_LOG_WARN ("Cannot remove loopback address.");
1211 return false;
1212 }
1213 Ptr<Ipv4Interface> interface = GetInterface (i);
1214 Ipv4InterfaceAddress ifAddr = interface->RemoveAddress (address);
1215 if (ifAddr != Ipv4InterfaceAddress ())
1216 {
1217 if (m_routingProtocol != 0)
1218 {
1219 m_routingProtocol->NotifyRemoveAddress (i, ifAddr);
1220 }
1221 return true;
1222 }
1223 return false;
1224}
1225
1228{
1229 NS_LOG_FUNCTION (this << interfaceIdx << " " << dest);
1230 if (GetNAddresses (interfaceIdx) == 1) // common case
1231 {
1232 return GetAddress (interfaceIdx, 0).GetLocal ();
1233 }
1234 // no way to determine the scope of the destination, so adopt the
1235 // following rule: pick the first available address (index 0) unless
1236 // a subsequent address is on link (in which case, pick the primary
1237 // address if there are multiple)
1238 Ipv4Address candidate = GetAddress (interfaceIdx, 0).GetLocal ();
1239 for (uint32_t i = 0; i < GetNAddresses (interfaceIdx); i++)
1240 {
1241 Ipv4InterfaceAddress test = GetAddress (interfaceIdx, i);
1242 if (test.GetLocal ().CombineMask (test.GetMask ()) == dest.CombineMask (test.GetMask ()))
1243 {
1244 if (test.IsSecondary () == false)
1245 {
1246 return test.GetLocal ();
1247 }
1248 }
1249 }
1250 return candidate;
1251}
1252
1256{
1257 NS_LOG_FUNCTION (this << device << dst << scope);
1258 Ipv4Address addr ("0.0.0.0");
1259 Ipv4InterfaceAddress iaddr;
1260 bool found = false;
1261
1262 if (device != 0)
1263 {
1264 int32_t i = GetInterfaceForDevice (device);
1265 NS_ASSERT_MSG (i >= 0, "No device found on node");
1266 for (uint32_t j = 0; j < GetNAddresses (i); j++)
1267 {
1268 iaddr = GetAddress (i, j);
1269 if (iaddr.IsSecondary ()) continue;
1270 if (iaddr.GetScope () > scope) continue;
1271 if (dst.CombineMask (iaddr.GetMask ()) == iaddr.GetLocal ().CombineMask (iaddr.GetMask ()) )
1272 {
1273 return iaddr.GetLocal ();
1274 }
1275 if (!found)
1276 {
1277 addr = iaddr.GetLocal ();
1278 found = true;
1279 }
1280 }
1281 }
1282 if (found)
1283 {
1284 return addr;
1285 }
1286
1287 // Iterate among all interfaces
1288 for (uint32_t i = 0; i < GetNInterfaces (); i++)
1289 {
1290 for (uint32_t j = 0; j < GetNAddresses (i); j++)
1291 {
1292 iaddr = GetAddress (i, j);
1293 if (iaddr.IsSecondary ()) continue;
1294 if (iaddr.GetScope () != Ipv4InterfaceAddress::LINK
1295 && iaddr.GetScope () <= scope)
1296 {
1297 return iaddr.GetLocal ();
1298 }
1299 }
1300 }
1301 NS_LOG_WARN ("Could not find source address for " << dst << " and scope "
1302 << scope << ", returning 0");
1303 return addr;
1304}
1305
1306void
1308{
1309 NS_LOG_FUNCTION (this << i << metric);
1310 Ptr<Ipv4Interface> interface = GetInterface (i);
1311 interface->SetMetric (metric);
1312}
1313
1314uint16_t
1316{
1317 NS_LOG_FUNCTION (this << i);
1318 Ptr<Ipv4Interface> interface = GetInterface (i);
1319 return interface->GetMetric ();
1320}
1321
1322uint16_t
1324{
1325 NS_LOG_FUNCTION (this << i);
1326 Ptr<Ipv4Interface> interface = GetInterface (i);
1327 return interface->GetDevice ()->GetMtu ();
1328}
1329
1330bool
1332{
1333 NS_LOG_FUNCTION (this << i);
1334 Ptr<Ipv4Interface> interface = GetInterface (i);
1335 return interface->IsUp ();
1336}
1337
1338void
1340{
1341 NS_LOG_FUNCTION (this << i);
1342 Ptr<Ipv4Interface> interface = GetInterface (i);
1343
1344 // RFC 791, pg.25:
1345 // Every internet module must be able to forward a datagram of 68
1346 // octets without further fragmentation. This is because an internet
1347 // header may be up to 60 octets, and the minimum fragment is 8 octets.
1348 if (interface->GetDevice ()->GetMtu () >= 68)
1349 {
1350 interface->SetUp ();
1351
1352 if (m_routingProtocol != 0)
1353 {
1354 m_routingProtocol->NotifyInterfaceUp (i);
1355 }
1356 }
1357 else
1358 {
1359 NS_LOG_LOGIC ("Interface " << int(i) << " is set to be down for IPv4. Reason: not respecting minimum IPv4 MTU (68 octects)");
1360 }
1361}
1362
1363void
1365{
1366 NS_LOG_FUNCTION (this << ifaceIndex);
1367 Ptr<Ipv4Interface> interface = GetInterface (ifaceIndex);
1368 interface->SetDown ();
1369
1370 if (m_routingProtocol != 0)
1371 {
1372 m_routingProtocol->NotifyInterfaceDown (ifaceIndex);
1373 }
1374}
1375
1376bool
1378{
1379 NS_LOG_FUNCTION (this << i);
1380 Ptr<Ipv4Interface> interface = GetInterface (i);
1381 NS_LOG_LOGIC ("Forwarding state: " << interface->IsForwarding ());
1382 return interface->IsForwarding ();
1383}
1384
1385void
1387{
1388 NS_LOG_FUNCTION (this << i);
1389 Ptr<Ipv4Interface> interface = GetInterface (i);
1390 interface->SetForwarding (val);
1391}
1392
1395{
1396 NS_LOG_FUNCTION (this << i);
1397 return GetInterface (i)->GetDevice ();
1398}
1399
1400void
1402{
1403 NS_LOG_FUNCTION (this << forward);
1404 m_ipForward = forward;
1405 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
1406 {
1407 (*i)->SetForwarding (forward);
1408 }
1409}
1410
1411bool
1413{
1414 NS_LOG_FUNCTION (this);
1415 return m_ipForward;
1416}
1417
1418void
1420{
1421 NS_LOG_FUNCTION (this << model);
1422 m_weakEsModel = model;
1423}
1424
1425bool
1427{
1428 NS_LOG_FUNCTION (this);
1429 return m_weakEsModel;
1430}
1431
1432void
1434{
1435 NS_LOG_FUNCTION (this << p << ipHeader << sockErrno);
1436 NS_LOG_LOGIC ("Route input failure-- dropping packet to " << ipHeader << " with errno " << sockErrno);
1437 m_dropTrace (ipHeader, p, DROP_ROUTE_ERROR, this, 0);
1438
1439 // \todo Send an ICMP no route.
1440}
1441
1442void
1443Ipv4L3Protocol::DoFragmentation (Ptr<Packet> packet, const Ipv4Header & ipv4Header, uint32_t outIfaceMtu, std::list<Ipv4PayloadHeaderPair>& listFragments)
1444{
1445 // BEWARE: here we do assume that the header options are not present.
1446 // a much more complex handling is necessary in case there are options.
1447 // If (when) IPv4 option headers will be implemented, the following code shall be changed.
1448 // Of course also the reassemby code shall be changed as well.
1449
1450 NS_LOG_FUNCTION (this << *packet << outIfaceMtu << &listFragments);
1451
1452 Ptr<Packet> p = packet->Copy ();
1453
1454 NS_ASSERT_MSG( (ipv4Header.GetSerializedSize() == 5*4),
1455 "IPv4 fragmentation implementation only works without option headers." );
1456
1457 uint16_t offset = 0;
1458 bool moreFragment = true;
1459 uint16_t originalOffset = ipv4Header.GetFragmentOffset();
1460 bool isLastFragment = ipv4Header.IsLastFragment();
1461 uint32_t currentFragmentablePartSize = 0;
1462
1463 // IPv4 fragments are all 8 bytes aligned but the last.
1464 // The IP payload size is:
1465 // floor( ( outIfaceMtu - ipv4Header.GetSerializedSize() ) /8 ) *8
1466 uint32_t fragmentSize = (outIfaceMtu - ipv4Header.GetSerializedSize () ) & ~uint32_t (0x7);
1467
1468 NS_LOG_LOGIC ("Fragmenting - Target Size: " << fragmentSize );
1469
1470 do
1471 {
1472 Ipv4Header fragmentHeader = ipv4Header;
1473
1474 if (p->GetSize () > offset + fragmentSize )
1475 {
1476 moreFragment = true;
1477 currentFragmentablePartSize = fragmentSize;
1478 fragmentHeader.SetMoreFragments ();
1479 }
1480 else
1481 {
1482 moreFragment = false;
1483 currentFragmentablePartSize = p->GetSize () - offset;
1484 if (!isLastFragment)
1485 {
1486 fragmentHeader.SetMoreFragments ();
1487 }
1488 else
1489 {
1490 fragmentHeader.SetLastFragment ();
1491 }
1492 }
1493
1494 NS_LOG_LOGIC ("Fragment creation - " << offset << ", " << currentFragmentablePartSize );
1495 Ptr<Packet> fragment = p->CreateFragment (offset, currentFragmentablePartSize);
1496 NS_LOG_LOGIC ("Fragment created - " << offset << ", " << fragment->GetSize () );
1497
1498 fragmentHeader.SetFragmentOffset (offset+originalOffset);
1499 fragmentHeader.SetPayloadSize (currentFragmentablePartSize);
1500
1501 if (Node::ChecksumEnabled ())
1502 {
1503 fragmentHeader.EnableChecksum ();
1504 }
1505
1506 NS_LOG_LOGIC ("Fragment check - " << fragmentHeader.GetFragmentOffset () );
1507
1508 NS_LOG_LOGIC ("New fragment Header " << fragmentHeader);
1509
1510 std::ostringstream oss;
1511 oss << fragmentHeader;
1512 fragment->Print (oss);
1513
1514 NS_LOG_LOGIC ("New fragment " << *fragment);
1515
1516 listFragments.emplace_back (fragment, fragmentHeader);
1517
1518 offset += currentFragmentablePartSize;
1519
1520 }
1521 while (moreFragment);
1522
1523 return;
1524}
1525
1526bool
1528{
1529 NS_LOG_FUNCTION (this << packet << ipHeader << iif);
1530
1531 uint64_t addressCombination = uint64_t (ipHeader.GetSource ().Get ()) << 32 | uint64_t (ipHeader.GetDestination ().Get ());
1532 uint32_t idProto = uint32_t (ipHeader.GetIdentification ()) << 16 | uint32_t (ipHeader.GetProtocol ());
1533 FragmentKey_t key;
1534 bool ret = false;
1535 Ptr<Packet> p = packet->Copy ();
1536
1537 key.first = addressCombination;
1538 key.second = idProto;
1539
1540 Ptr<Fragments> fragments;
1541
1542 MapFragments_t::iterator it = m_fragments.find (key);
1543 if (it == m_fragments.end ())
1544 {
1545 fragments = Create<Fragments> ();
1546 m_fragments.insert (std::make_pair (key, fragments));
1547
1548 FragmentsTimeoutsListI_t iter = SetTimeout (key, ipHeader, iif);
1549 fragments->SetTimeoutIter (iter);
1550 }
1551 else
1552 {
1553 fragments = it->second;
1554 }
1555
1556 NS_LOG_LOGIC ("Adding fragment - Size: " << packet->GetSize ( ) << " - Offset: " << (ipHeader.GetFragmentOffset ()) );
1557
1558 fragments->AddFragment (p, ipHeader.GetFragmentOffset (), !ipHeader.IsLastFragment () );
1559
1560 if ( fragments->IsEntire () )
1561 {
1562 packet = fragments->GetPacket ();
1563 m_timeoutEventList.erase (fragments->GetTimeoutIter ());
1564 fragments = 0;
1565 m_fragments.erase (key);
1566 ret = true;
1567 }
1568
1569 return ret;
1570}
1571
1573 : m_moreFragment (0)
1574{
1575 NS_LOG_FUNCTION (this);
1576}
1577
1579{
1580 NS_LOG_FUNCTION (this);
1581}
1582
1583void
1584Ipv4L3Protocol::Fragments::AddFragment (Ptr<Packet> fragment, uint16_t fragmentOffset, bool moreFragment)
1585{
1586 NS_LOG_FUNCTION (this << fragment << fragmentOffset << moreFragment);
1587
1588 std::list<std::pair<Ptr<Packet>, uint16_t> >::iterator it;
1589
1590 for (it = m_fragments.begin (); it != m_fragments.end (); it++)
1591 {
1592 if (it->second > fragmentOffset)
1593 {
1594 break;
1595 }
1596 }
1597
1598 if (it == m_fragments.end ())
1599 {
1600 m_moreFragment = moreFragment;
1601 }
1602
1603 m_fragments.insert (it, std::pair<Ptr<Packet>, uint16_t> (fragment, fragmentOffset));
1604}
1605
1606bool
1608{
1609 NS_LOG_FUNCTION (this);
1610
1611 bool ret = !m_moreFragment && m_fragments.size () > 0;
1612
1613 if (ret)
1614 {
1615 uint16_t lastEndOffset = 0;
1616
1617 for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
1618 {
1619 // overlapping fragments do exist
1620 NS_LOG_LOGIC ("Checking overlaps " << lastEndOffset << " - " << it->second );
1621
1622 if (lastEndOffset < it->second)
1623 {
1624 ret = false;
1625 break;
1626 }
1627 // fragments might overlap in strange ways
1628 uint16_t fragmentEnd = it->first->GetSize () + it->second;
1629 lastEndOffset = std::max ( lastEndOffset, fragmentEnd );
1630 }
1631 }
1632
1633 return ret;
1634}
1635
1638{
1639 NS_LOG_FUNCTION (this);
1640
1641 std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin ();
1642
1643 Ptr<Packet> p = it->first->Copy ();
1644 uint16_t lastEndOffset = p->GetSize ();
1645 it++;
1646
1647 for ( ; it != m_fragments.end (); it++)
1648 {
1649 if ( lastEndOffset > it->second )
1650 {
1651 // The fragments are overlapping.
1652 // We do not overwrite the "old" with the "new" because we do not know when each arrived.
1653 // This is different from what Linux does.
1654 // It is not possible to emulate a fragmentation attack.
1655 uint32_t newStart = lastEndOffset - it->second;
1656 if ( it->first->GetSize () > newStart )
1657 {
1658 uint32_t newSize = it->first->GetSize () - newStart;
1659 Ptr<Packet> tempFragment = it->first->CreateFragment (newStart, newSize);
1660 p->AddAtEnd (tempFragment);
1661 }
1662 }
1663 else
1664 {
1665 NS_LOG_LOGIC ("Adding: " << *(it->first) );
1666 p->AddAtEnd (it->first);
1667 }
1668 lastEndOffset = p->GetSize ();
1669 }
1670
1671 return p;
1672}
1673
1676{
1677 NS_LOG_FUNCTION (this);
1678
1679 std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin ();
1680
1681 Ptr<Packet> p = Create<Packet> ();
1682 uint16_t lastEndOffset = 0;
1683
1684 if ( m_fragments.begin ()->second > 0 )
1685 {
1686 return p;
1687 }
1688
1689 for ( it = m_fragments.begin (); it != m_fragments.end (); it++)
1690 {
1691 if ( lastEndOffset > it->second )
1692 {
1693 uint32_t newStart = lastEndOffset - it->second;
1694 uint32_t newSize = it->first->GetSize () - newStart;
1695 Ptr<Packet> tempFragment = it->first->CreateFragment (newStart, newSize);
1696 p->AddAtEnd (tempFragment);
1697 }
1698 else if ( lastEndOffset == it->second )
1699 {
1700 NS_LOG_LOGIC ("Adding: " << *(it->first) );
1701 p->AddAtEnd (it->first);
1702 }
1703 lastEndOffset = p->GetSize ();
1704 }
1705
1706 return p;
1707}
1708
1709void
1711{
1712 m_timeoutIter = iter;
1713 return;
1714}
1715
1718{
1719 return m_timeoutIter;
1720}
1721
1722
1723void
1725{
1726 NS_LOG_FUNCTION (this << &key << &ipHeader << iif);
1727
1728 MapFragments_t::iterator it = m_fragments.find (key);
1729 Ptr<Packet> packet = it->second->GetPartialPacket ();
1730
1731 // if we have at least 8 bytes, we can send an ICMP.
1732 if ( packet->GetSize () > 8 )
1733 {
1735 icmp->SendTimeExceededTtl (ipHeader, packet, true);
1736 }
1737 m_dropTrace (ipHeader, packet, DROP_FRAGMENT_TIMEOUT, this, iif);
1738
1739 // clear the buffers
1740 it->second = 0;
1741
1742 m_fragments.erase (key);
1743}
1744
1745bool
1747{
1748 NS_LOG_FUNCTION (this << p << header);
1749
1750 // \todo RFC 6621 mandates SHA-1 hash. For now ns3 hash should be fine.
1751 uint8_t proto = header.GetProtocol ();
1752 Ipv4Address src = header.GetSource ();
1753 Ipv4Address dst = header.GetDestination ();
1754 uint64_t id = header.GetIdentification ();
1755
1756 // concat hash value onto id
1757 uint64_t hash = id << 32;
1758 if (header.GetFragmentOffset () || !header.IsLastFragment ())
1759 {
1760 // use I-DPD (RFC 6621, Sec 6.2.1)
1761 hash |= header.GetFragmentOffset ();
1762 }
1763 else
1764 {
1765 // use H-DPD (RFC 6621, Sec 6.2.2)
1766
1767 // serialize packet
1768 Ptr<Packet> pkt = p->Copy ();
1769 pkt->AddHeader (header);
1770
1771 std::ostringstream oss (std::ios_base::binary);
1772 pkt->CopyData (&oss, pkt->GetSize ());
1773 std::string bytes = oss.str ();
1774
1775 NS_ASSERT_MSG (bytes.size () >= 20, "Degenerate header serialization");
1776
1777 // zero out mutable fields
1778 bytes[1] = 0; // DSCP / ECN
1779 bytes[6] = bytes[7] = 0; // Flags / Fragment offset
1780 bytes[8] = 0; // TTL
1781 bytes[10] = bytes[11] = 0; // Header checksum
1782 if (header.GetSerializedSize () > 20) // assume options should be 0'd
1783 {
1784 std::fill_n (bytes.begin () + 20, header.GetSerializedSize () - 20, 0);
1785 }
1786
1787 // concat hash onto ID
1788 hash |= (uint64_t)Hash32 (bytes);
1789 }
1790
1791 // set cleanup job for new duplicate entries
1793 {
1795 }
1796
1797 // assume this is a new entry
1798 DupTuple_t key {hash, proto, src, dst};
1799 NS_LOG_DEBUG ("Packet " << p->GetUid () << " key = (" <<
1800 std::hex << std::get<0> (key) << ", " <<
1801 std::dec << +std::get<1> (key) << ", " <<
1802 std::get<2> (key) << ", " <<
1803 std::get<3> (key) << ")");
1804
1805 // place a new entry, on collision the existing entry iterator is returned
1806 DupMap_t::iterator iter;
1807 bool inserted, isDup;
1808 std::tie (iter, inserted) = m_dups.emplace (key, Seconds (0));
1809 isDup = !inserted && iter->second > Simulator::Now ();
1810
1811 // set the expiration event
1812 iter->second = Simulator::Now () + m_expire;
1813 return isDup;
1814}
1815
1816void
1818{
1819 NS_LOG_FUNCTION (this);
1820
1821 DupMap_t::size_type n = 0;
1822 Time expire = Simulator::Now ();
1823 auto iter = m_dups.cbegin ();
1824 while (iter != m_dups.cend ())
1825 {
1826 if (iter->second < expire)
1827 {
1828 NS_LOG_LOGIC ("Remove key = (" <<
1829 std::hex << std::get<0> (iter->first) << ", " <<
1830 std::dec << +std::get<1> (iter->first) << ", " <<
1831 std::get<2> (iter->first) << ", " <<
1832 std::get<3> (iter->first) << ")");
1833 iter = m_dups.erase (iter);
1834 ++n;
1835 }
1836 else
1837 {
1838 ++iter;
1839 }
1840 }
1841
1842 NS_LOG_DEBUG ("Purged " << n << " expired duplicate entries out of " << (n + m_dups.size ()));
1843
1844 // keep cleaning up if necessary
1845 if (!m_dups.empty () && m_purge.IsStrictlyPositive ())
1846 {
1848 }
1849}
1850
1853{
1855
1856 if (m_timeoutEventList.empty ())
1857 {
1859 }
1860 m_timeoutEventList.emplace_back (now, key, ipHeader, iif);
1861
1863
1864 return (iter);
1865}
1866
1867void
1869{
1870 Time now = Simulator::Now ();
1871
1872 while (!m_timeoutEventList.empty () && std::get<0> (*m_timeoutEventList.begin ()) == now)
1873 {
1874 HandleFragmentsTimeout (std::get<1> (*m_timeoutEventList.begin ()),
1875 std::get<2> (*m_timeoutEventList.begin ()),
1876 std::get<3> (*m_timeoutEventList.begin ()));
1877 m_timeoutEventList.pop_front ();
1878 }
1879
1880 if (m_timeoutEventList.empty ())
1881 {
1882 return;
1883 }
1884
1885 Time difference = std::get<0> (*m_timeoutEventList.begin ()) - now;
1887
1888 return;
1889}
1890
1891} // 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:178
bool IsAlive(void)
Definition: arp-cache.cc:375
void UpdateSeen(void)
Update the entry when seeing a packet.
Definition: arp-cache.cc:532
std::list< ArpCache::Entry * > LookupInverse(Address destination)
Do lookup in the ARP cache against a MAC address.
Definition: arp-cache.cc:300
ArpCache::Entry * Lookup(Ipv4Address destination)
Do lookup in the ARP cache against an IP address.
Definition: arp-cache.cc:318
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.
virtual uint32_t GetIfIndex(void) const =0
virtual uint16_t GetMtu(void) const =0
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:556
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:402
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:791
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:611
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:842
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
bool IsStrictlyPositive(void) const
Exactly equivalent to t > 0.
Definition: nstime.h:332
AttributeValue implementation for Time.
Definition: nstime.h:1308
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:1309
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:257
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#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:265
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:1244
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
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:44
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:415
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:536
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
Definition: second.py:1
#define list