A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
dsr-options.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011 Yufei Cheng
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Yufei Cheng <yfcheng@ittc.ku.edu>
18 *
19 * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
20 * ResiliNets Research Group https://resilinets.org/
21 * Information and Telecommunication Technology Center (ITTC)
22 * and Department of Electrical Engineering and Computer Science
23 * The University of Kansas Lawrence, KS USA.
24 *
25 * Work supported in part by NSF FIND (Future Internet Design) Program
26 * under grant CNS-0626918 (Postmodern Internet Architecture),
27 * NSF grant CNS-1050226 (Multilayer Network Resilience Analysis and Experimentation on GENI),
28 * US Department of Defense (DoD), and ITTC at The University of Kansas.
29 */
30
31#define NS_LOG_APPEND_CONTEXT \
32 if (GetObject<Node>()) \
33 { \
34 std::clog << "[node " << GetObject<Node>()->GetId() << "] "; \
35 }
36
37#include "dsr-options.h"
38
39#include "dsr-option-header.h"
40#include "dsr-rcache.h"
41
42#include "ns3/assert.h"
43#include "ns3/fatal-error.h"
44#include "ns3/icmpv4-l4-protocol.h"
45#include "ns3/ip-l4-protocol.h"
46#include "ns3/ipv4-address.h"
47#include "ns3/ipv4-header.h"
48#include "ns3/ipv4-interface.h"
49#include "ns3/ipv4-l3-protocol.h"
50#include "ns3/ipv4-route.h"
51#include "ns3/log.h"
52#include "ns3/node-list.h"
53#include "ns3/node.h"
54#include "ns3/object-vector.h"
55#include "ns3/pointer.h"
56#include "ns3/ptr.h"
57#include "ns3/trace-source-accessor.h"
58#include "ns3/udp-header.h"
59#include "ns3/uinteger.h"
60
61#include <algorithm>
62#include <ctime>
63#include <list>
64#include <map>
65
66namespace ns3
67{
68
69NS_LOG_COMPONENT_DEFINE("DsrOptions");
70
71namespace dsr
72{
73
75
76TypeId
78{
79 static TypeId tid = TypeId("ns3::dsr::DsrOptions")
81 .SetGroupName("Dsr")
82 .AddAttribute("OptionNumber",
83 "The Dsr option number.",
86 MakeUintegerChecker<uint8_t>())
87 .AddTraceSource("Drop",
88 "Packet dropped.",
90 "ns3::Packet::TracedCallback")
91 .AddTraceSource("Rx",
92 "Receive DSR packet.",
94 "ns3::dsr::DsrOptionSRHeader::TracedCallback");
95 return tid;
96}
97
99{
101}
102
104{
106}
107
108void
110{
111 NS_LOG_FUNCTION(this << node);
112 m_node = node;
113}
114
117{
119 return m_node;
120}
121
122bool
124 Ipv4Address destAddress,
125 std::vector<Ipv4Address>& nodeList)
126{
127 NS_LOG_FUNCTION(this << ipv4Address << destAddress);
128 auto it = find(nodeList.begin(), nodeList.end(), destAddress);
129
130 for (auto i = it; i != nodeList.end(); ++i)
131 {
132 if ((ipv4Address == (*i)) && ((*i) != nodeList.back()))
133 {
134 return true;
135 }
136 }
137 return false;
138}
139
140std::vector<Ipv4Address>
141DsrOptions::CutRoute(Ipv4Address ipv4Address, std::vector<Ipv4Address>& nodeList)
142{
143 NS_LOG_FUNCTION(this << ipv4Address);
144 auto it = find(nodeList.begin(), nodeList.end(), ipv4Address);
145 std::vector<Ipv4Address> cutRoute;
146 for (auto i = it; i != nodeList.end(); ++i)
147 {
148 cutRoute.push_back(*i);
149 }
150 return cutRoute;
151}
152
155{
156 NS_LOG_FUNCTION(this << nextHop << srcAddress);
157 m_ipv4Route = Create<Ipv4Route>();
158 m_ipv4Route->SetDestination(nextHop);
159 m_ipv4Route->SetGateway(nextHop);
160 m_ipv4Route->SetSource(srcAddress);
161 return m_ipv4Route;
162}
163
164bool
165DsrOptions::ReverseRoutes(std::vector<Ipv4Address>& vec)
166{
167 NS_LOG_FUNCTION(this);
168
169 std::reverse(vec.begin(), vec.end());
170
171 return true;
172}
173
175DsrOptions::SearchNextHop(Ipv4Address ipv4Address, std::vector<Ipv4Address>& vec)
176{
177 NS_LOG_FUNCTION(this << ipv4Address);
178 Ipv4Address nextHop;
179 NS_LOG_DEBUG("the vector size " << vec.size());
180 if (vec.size() == 2)
181 {
182 NS_LOG_DEBUG("The two nodes are neighbors");
183 nextHop = vec[1];
184 return nextHop;
185 }
186
187 if (ipv4Address == vec.back())
188 {
189 NS_LOG_DEBUG("We have reached to the final destination " << ipv4Address << " "
190 << vec.back());
191 return ipv4Address;
192 }
193 for (auto i = vec.begin(); i != vec.end(); ++i)
194 {
195 if (ipv4Address == (*i))
196 {
197 nextHop = *(++i);
198 return nextHop;
199 }
200 }
201
202 NS_LOG_DEBUG("next hop address not found, route corrupted");
203 Ipv4Address none = "0.0.0.0";
204 return none;
205}
206
208DsrOptions::ReverseSearchNextHop(Ipv4Address ipv4Address, std::vector<Ipv4Address>& vec)
209{
210 NS_LOG_FUNCTION(this << ipv4Address);
211 Ipv4Address nextHop;
212 if (vec.size() == 2)
213 {
214 NS_LOG_DEBUG("The two nodes are neighbors");
215 nextHop = vec[0];
216 return nextHop;
217 }
218
219 for (auto ri = vec.rbegin(); ri != vec.rend(); ++ri)
220 {
221 if (ipv4Address == (*ri))
222 {
223 nextHop = *(++ri);
224 return nextHop;
225 }
226 }
227
228 NS_LOG_DEBUG("next hop address not found, route corrupted");
229 Ipv4Address none = "0.0.0.0";
230 return none;
231}
232
234DsrOptions::ReverseSearchNextTwoHop(Ipv4Address ipv4Address, std::vector<Ipv4Address>& vec)
235{
236 NS_LOG_FUNCTION(this << ipv4Address);
237 Ipv4Address nextTwoHop;
238 NS_LOG_DEBUG("The vector size " << vec.size());
239 NS_ASSERT(vec.size() > 2);
240 for (auto ri = vec.rbegin(); ri != vec.rend(); ++ri)
241 {
242 if (ipv4Address == (*ri))
243 {
244 nextTwoHop = *(ri + 2);
245 return nextTwoHop;
246 }
247 }
248 NS_FATAL_ERROR("next hop address not found, route corrupted");
249 Ipv4Address none = "0.0.0.0";
250 return none;
251}
252
253void
254DsrOptions::PrintVector(std::vector<Ipv4Address>& vec)
255{
256 NS_LOG_FUNCTION(this);
257 /*
258 * Check elements in a route vector
259 */
260 if (vec.empty())
261 {
262 NS_LOG_DEBUG("The vector is empty");
263 }
264 else
265 {
266 NS_LOG_DEBUG("Print all the elements in a vector");
267 for (auto i = vec.begin(); i != vec.end(); ++i)
268 {
269 NS_LOG_DEBUG("The ip address " << *i);
270 }
271 }
272}
273
274bool
275DsrOptions::IfDuplicates(std::vector<Ipv4Address>& vec, std::vector<Ipv4Address>& vec2)
276{
277 NS_LOG_FUNCTION(this);
278 for (auto i = vec.begin(); i != vec.end(); ++i)
279 {
280 for (auto j = vec2.begin(); j != vec2.end(); ++j)
281 {
282 if ((*i) == (*j))
283 {
284 return true;
285 }
286 }
287 }
288 return false;
289}
290
291bool
292DsrOptions::CheckDuplicates(Ipv4Address ipv4Address, std::vector<Ipv4Address>& vec)
293{
294 NS_LOG_FUNCTION(this << ipv4Address);
295 for (auto i = vec.begin(); i != vec.end(); ++i)
296 {
297 if ((*i) == ipv4Address)
298 {
299 return true;
300 }
301 }
302 return false;
303}
304
305void
306DsrOptions::RemoveDuplicates(std::vector<Ipv4Address>& vec)
307{
308 NS_LOG_FUNCTION(this);
309 // Remove duplicate ip address from the route if any, should not happen with normal behavior
310 // nodes
311 std::vector<Ipv4Address> vec2(vec); // declare vec2 as a copy of the vec
312 PrintVector(vec2); // Print all the ip address in the route
313 vec.clear(); // clear vec
314 for (auto i = vec2.begin(); i != vec2.end(); ++i)
315 {
316 if (vec.empty())
317 {
318 vec.push_back(*i);
319 continue;
320 }
321
322 for (auto j = vec.begin(); j != vec.end(); ++j)
323 {
324 if ((*i) == (*j))
325 {
326 if ((j + 1) != vec.end())
327 {
328 vec.erase(j + 1, vec.end()); // Automatic shorten the route
329 }
330
331 break;
332 }
333 else if (j == (vec.end() - 1))
334 {
335 vec.push_back(*i);
336 break;
337 }
338 }
339 }
340}
341
344{
345 NS_LOG_FUNCTION(this << address);
346 int32_t nNodes = NodeList::GetNNodes();
347 for (int32_t i = 0; i < nNodes; ++i)
348 {
350 Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
351 if (ipv4->GetAddress(1, 0).GetLocal() == address)
352 {
353 return i;
354 }
355 }
356 return 255;
357}
358
361{
362 NS_LOG_FUNCTION(this << ipv4Address);
363 int32_t nNodes = NodeList::GetNNodes();
364 for (int32_t i = 0; i < nNodes; ++i)
365 {
367 Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
368 int32_t ifIndex = ipv4->GetInterfaceForAddress(ipv4Address);
369 if (ifIndex != -1)
370 {
371 return node;
372 }
373 }
374 return nullptr;
375}
376
378
379TypeId
381{
382 static TypeId tid = TypeId("ns3::dsr::DsrOptionPad1")
384 .SetGroupName("Dsr")
385 .AddConstructor<DsrOptionPad1>();
386 return tid;
387}
388
390{
392}
393
395{
397}
398
399uint8_t
401{
403
404 return OPT_NUMBER;
405}
406
407uint8_t
409 Ptr<Packet> dsrP,
410 Ipv4Address ipv4Address,
411 Ipv4Address source,
412 const Ipv4Header& ipv4Header,
413 uint8_t protocol,
414 bool& isPromisc,
415 Ipv4Address promiscSource)
416{
417 NS_LOG_FUNCTION(this << packet << dsrP << ipv4Address << source << ipv4Header
418 << (uint32_t)protocol << isPromisc);
419 Ptr<Packet> p = packet->Copy();
420 DsrOptionPad1Header pad1Header;
421 p->RemoveHeader(pad1Header);
422
423 isPromisc = false;
424
425 return pad1Header.GetSerializedSize();
426}
427
429
430TypeId
432{
433 static TypeId tid = TypeId("ns3::dsr::DsrOptionPadn")
435 .SetGroupName("Dsr")
436 .AddConstructor<DsrOptionPadn>();
437 return tid;
438}
439
441{
443}
444
446{
448}
449
450uint8_t
452{
454 return OPT_NUMBER;
455}
456
457uint8_t
459 Ptr<Packet> dsrP,
460 Ipv4Address ipv4Address,
461 Ipv4Address source,
462 const Ipv4Header& ipv4Header,
463 uint8_t protocol,
464 bool& isPromisc,
465 Ipv4Address promiscSource)
466{
467 NS_LOG_FUNCTION(this << packet << dsrP << ipv4Address << source << ipv4Header
468 << (uint32_t)protocol << isPromisc);
469
470 Ptr<Packet> p = packet->Copy();
471 DsrOptionPadnHeader padnHeader;
472 p->RemoveHeader(padnHeader);
473
474 isPromisc = false;
475
476 return padnHeader.GetSerializedSize();
477}
478
480
481TypeId
483{
484 static TypeId tid = TypeId("ns3::dsr::DsrOptionRreq")
486 .SetGroupName("Dsr")
487 .AddConstructor<DsrOptionRreq>();
488 return tid;
489}
490
491TypeId
493{
494 return GetTypeId();
495}
496
498{
500}
501
503{
505}
506
507uint8_t
509{
511
512 return OPT_NUMBER;
513}
514
515uint8_t
517 Ptr<Packet> dsrP,
518 Ipv4Address ipv4Address,
519 Ipv4Address source,
520 const Ipv4Header& ipv4Header,
521 uint8_t protocol,
522 bool& isPromisc,
523 Ipv4Address promiscSource)
524{
525 NS_LOG_FUNCTION(this << packet << dsrP << ipv4Address << source << ipv4Header
526 << (uint32_t)protocol << isPromisc);
527 // Fields from IP header
528 Ipv4Address srcAddress = ipv4Header.GetSource();
529 /*
530 * \ when the ip source address is equal to the address of our own, this is request packet
531 * originated \ by the node itself, discard it
532 */
533 if (source == ipv4Address)
534 {
535 NS_LOG_DEBUG("Discard the packet since it was originated from same source address");
536 m_dropTrace(packet); // call the drop trace to show in the tracing
537 return 0;
538 }
539 /*
540 * Get the node associated with the ipv4 address and get several objects from the node and leave
541 * for further use
542 */
543 Ptr<Node> node = GetNodeWithAddress(ipv4Address);
544 Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting>();
545
546 Ptr<Packet> p =
547 packet->Copy(); // Note: The packet here doesn't contain the fixed size dsr header
548 /*
549 * \brief Get the number of routers' address field before removing the header
550 * \peek the packet and get the value
551 */
552 uint8_t buf[2];
553 p->CopyData(buf, sizeof(buf));
554 uint8_t numberAddress = (buf[1] - 6) / 4;
555 NS_LOG_DEBUG("The number of Ip addresses " << (uint32_t)numberAddress);
556 if (numberAddress >= 255)
557 {
558 NS_LOG_DEBUG("Discard the packet, malformed header since two many ip addresses in route");
559 m_dropTrace(packet); // call the drop trace to show in the tracing
560 return 0;
561 }
562
563 /*
564 * Create the dsr rreq header
565 */
567 /*
568 * Set the number of addresses with the value from peek data and remove the rreq header
569 */
570 rreq.SetNumberAddress(numberAddress);
571 // Remove the route request header
572 p->RemoveHeader(rreq);
573 // Verify the option length
574 uint8_t length = rreq.GetLength();
575 if (length % 2 != 0)
576 {
577 NS_LOG_LOGIC("Malformed header. Drop!");
578 m_dropTrace(packet); // call drop trace
579 return 0;
580 }
581 // Check the rreq id for verifying the request id
582 uint16_t requestId = rreq.GetId();
583 // The target address is where we want to send the data packets
584 Ipv4Address targetAddress = rreq.GetTarget();
585 // Get the node list and source address from the route request header
586 std::vector<Ipv4Address> mainVector = rreq.GetNodesAddresses();
587 std::vector<Ipv4Address> nodeList(mainVector);
588 // Get the real source address of this request, it will be used when checking if we have
589 // received the save route request before or not
590 Ipv4Address sourceAddress = nodeList.front();
591 PrintVector(nodeList);
592 /*
593 * Construct the dsr routing header for later use
594 */
595 DsrRoutingHeader dsrRoutingHeader;
596 dsrRoutingHeader.SetNextHeader(protocol);
597 dsrRoutingHeader.SetMessageType(1);
598 dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
599 dsrRoutingHeader.SetDestId(255);
600
601 // check whether we have received this request or not, if not, it will save the request in the
602 // table for later use, if not found, return false, and push the newly received source request
603 // entry in the cache
604
605 // Get the TTL value, this is used to test if the packet will be forwarded or not
606 uint8_t ttl = ipv4Header.GetTtl();
607 bool dupRequest = false; // initialize the duplicate request check value
608 if (ttl)
609 {
610 // if the ttl value is not 0, then this request will be forwarded, then we need to
611 // save it in the source entry
612 dupRequest = dsr->FindSourceEntry(sourceAddress, targetAddress, requestId);
613 }
614 /*
615 * Before processing the route request, we need to check two things
616 * 1. if this is the exact same request we have just received, ignore it
617 * 2. if our address is already in the path list, ignore it
618 * 3. otherwise process further
619 */
620
621 if (dupRequest)
622 {
623 // We have received this same route request before, not forwarding it now
624 NS_LOG_LOGIC("Duplicate request. Drop!");
625 m_dropTrace(packet); // call drop trace
626 return 0;
627 }
628
629 else if (CheckDuplicates(ipv4Address, nodeList))
630 {
631 /*
632 * if the route contains the node address already, drop the request packet
633 */
634 m_dropTrace(packet); // call drop trace
635 NS_LOG_DEBUG("Our node address is already seen in the route, drop the request");
636 return 0;
637 }
638 else
639 {
640 // A node ignores all RREQs received from any node in its blacklist
641 DsrRouteCacheEntry toPrev;
642 bool isRouteInCache = dsr->LookupRoute(targetAddress, toPrev);
644 toPrev.GetVector(); // The route from our own route cache to dst
645 PrintVector(ip);
646 std::vector<Ipv4Address> saveRoute(nodeList);
647 PrintVector(saveRoute);
648 bool areThereDuplicates = IfDuplicates(ip, saveRoute);
649 /*
650 * When the reverse route is created or updated, the following actions on the route are
651 * also carried out:
652 * 3. the next hop in the routing table becomes the node from which the RREQ was received
653 * 4. the hop count is copied from the Hop Count in the RREQ message;
654 */
655
656 // A node generates a RREP if either:
657 // (i) it is itself the destination,
658 /*
659 * The target address equal to our own ip address
660 */
661 NS_LOG_DEBUG("The target address over here " << targetAddress << " and the ip address "
662 << ipv4Address << " and the source address "
663 << mainVector[0]);
664 if (targetAddress == ipv4Address)
665 {
666 Ipv4Address nextHop; // Declare the next hop address to use
667 if (nodeList.size() == 1)
668 {
669 NS_LOG_DEBUG("These two nodes are neighbors");
670 m_finalRoute.clear();
673 m_finalRoute.push_back(source); // push back the request originator's address
674 m_finalRoute.push_back(ipv4Address); // push back our own address
675 nextHop = srcAddress;
676 }
677 else
678 {
679 std::vector<Ipv4Address> changeRoute(nodeList);
680 changeRoute.push_back(ipv4Address); // push back our own address
681 m_finalRoute.clear(); // get a clear route vector
682 for (auto i = changeRoute.begin(); i != changeRoute.end(); ++i)
683 {
684 m_finalRoute.push_back(*i); // Get the full route from source to destination
685 }
687 nextHop = ReverseSearchNextHop(ipv4Address, m_finalRoute); // get the next hop
688 }
689
691 rrep.SetNodesAddress(m_finalRoute); // Set the node addresses in the route reply header
692 NS_LOG_DEBUG("The nextHop address " << nextHop);
693 Ipv4Address replyDst = m_finalRoute.front();
694 /*
695 * This part add dsr header to the packet and send route reply packet
696 */
697 DsrRoutingHeader dsrRoutingHeader;
698 dsrRoutingHeader.SetNextHeader(protocol);
699 dsrRoutingHeader.SetMessageType(1);
700 dsrRoutingHeader.SetSourceId(GetIDfromIP(ipv4Address));
701 dsrRoutingHeader.SetDestId(GetIDfromIP(replyDst));
702 // Set the route for route reply
703 SetRoute(nextHop, ipv4Address);
704
705 uint8_t length =
706 rrep.GetLength(); // Get the length of the rrep header excluding the type header
707 dsrRoutingHeader.SetPayloadLength(length + 2);
708 dsrRoutingHeader.AddDsrOption(rrep);
709 Ptr<Packet> newPacket = Create<Packet>();
710 newPacket->AddHeader(dsrRoutingHeader);
711 dsr->ScheduleInitialReply(newPacket, ipv4Address, nextHop, m_ipv4Route);
712 /*
713 * Create the route entry to the rreq originator and save it to route cache, also need
714 * to reverse the route
715 */
718 {
720 Ipv4Address dst = m_finalRoute.back();
721 bool addRoute = false;
722 if (numberAddress > 0)
723 {
724 DsrRouteCacheEntry toSource(/*ip=*/m_finalRoute,
725 /*dst=*/dst,
726 /*exp=*/ActiveRouteTimeout);
727 if (dsr->IsLinkCache())
728 {
729 addRoute = dsr->AddRoute_Link(m_finalRoute, ipv4Address);
730 }
731 else
732 {
733 addRoute = dsr->AddRoute(toSource);
734 }
735 }
736 else
737 {
738 NS_LOG_DEBUG("Abnormal RouteRequest");
739 return 0;
740 }
741
742 if (addRoute)
743 {
744 /*
745 * Found a route to the dst, construct the source route option header
746 */
747 DsrOptionSRHeader sourceRoute;
748 NS_LOG_DEBUG("The route length " << m_finalRoute.size());
749 sourceRoute.SetNodesAddress(m_finalRoute);
750
754 // if (dsr->IsLinkCache ())
755 // {
756 // dsr->UseExtends (m_finalRoute);
757 // }
758 sourceRoute.SetSegmentsLeft(m_finalRoute.size() - 2);
759 // The salvage value here is 0
760 sourceRoute.SetSalvage(0);
761 Ipv4Address nextHop =
762 SearchNextHop(ipv4Address, m_finalRoute); // Get the next hop address
763 NS_LOG_DEBUG("The nextHop address " << nextHop);
764
765 if (nextHop == "0.0.0.0")
766 {
767 dsr->PacketNewRoute(dsrP, ipv4Address, dst, protocol);
768 return 0;
769 }
770 SetRoute(nextHop, ipv4Address);
771 /*
772 * Send the data packet from the send buffer
773 */
774 dsr->SendPacketFromBuffer(sourceRoute, nextHop, protocol);
775 // Cancel the route request timer for destination after sending the data packet
776 dsr->CancelRreqTimer(dst, true);
777 }
778 else
779 {
780 NS_LOG_DEBUG("The route is failed to add in cache");
781 return 0;
782 }
783 }
784 else
785 {
786 NS_LOG_DEBUG("Unable to reverse route");
787 return 0;
788 }
789 isPromisc = false;
790 return rreq.GetSerializedSize();
791 }
792
793 /*
794 * (ii) or it has an active route to the destination, send reply based on request header and
795 * route cache, need to delay based on a random value from d = H * (h - 1 + r), which can
796 * avoid possible route reply storm. Also, verify if two vectors do not contain duplicates
797 * (part of the route to the destination from route cache and route collected so far). If
798 * so, do not use the route found and forward the route request.
799 */
800 else if (isRouteInCache && !areThereDuplicates)
801 {
802 m_finalRoute.clear(); // Clear the final route vector
806 for (auto i = saveRoute.begin(); i != saveRoute.end(); ++i)
807 {
808 m_finalRoute.push_back(*i);
809 }
814 for (auto j = ip.begin(); j != ip.end(); ++j)
815 {
816 m_finalRoute.push_back(*j);
817 }
818 /*
819 * Create the route entry to the rreq originator and save it to route cache, also need
820 * to reverse the route
821 */
822 bool addRoute = false;
823 std::vector<Ipv4Address> reverseRoute(m_finalRoute);
824
825 if (ReverseRoutes(reverseRoute))
826 {
827 saveRoute.push_back(ipv4Address);
828 ReverseRoutes(saveRoute);
829 Ipv4Address dst = saveRoute.back();
830 NS_LOG_DEBUG("This is the route save in route cache");
831 PrintVector(saveRoute);
832
833 DsrRouteCacheEntry toSource(/*ip=*/saveRoute,
834 /*dst=*/dst,
835 /*exp=*/ActiveRouteTimeout);
836 NS_ASSERT(saveRoute.front() == ipv4Address);
837 // Add the route entry in the route cache
838 if (dsr->IsLinkCache())
839 {
840 addRoute = dsr->AddRoute_Link(saveRoute, ipv4Address);
841 }
842 else
843 {
844 addRoute = dsr->AddRoute(toSource);
845 }
846
847 if (addRoute)
848 {
849 NS_LOG_LOGIC("We have added the route and search send buffer for packet with "
850 "destination "
851 << dst);
852 /*
853 * Found a route the dst, construct the source route option header
854 */
855 DsrOptionSRHeader sourceRoute;
856 PrintVector(saveRoute);
857
858 sourceRoute.SetNodesAddress(saveRoute);
859 // if (dsr->IsLinkCache ())
860 // {
861 // dsr->UseExtends (saveRoute);
862 // }
863 sourceRoute.SetSegmentsLeft(saveRoute.size() - 2);
864 uint8_t salvage = 0;
865 sourceRoute.SetSalvage(salvage);
866 Ipv4Address nextHop =
867 SearchNextHop(ipv4Address, saveRoute); // Get the next hop address
868 NS_LOG_DEBUG("The nextHop address " << nextHop);
869
870 if (nextHop == "0.0.0.0")
871 {
872 dsr->PacketNewRoute(dsrP, ipv4Address, dst, protocol);
873 return 0;
874 }
875 SetRoute(nextHop, ipv4Address);
876 /*
877 * Schedule the packet retry
878 */
879 dsr->SendPacketFromBuffer(sourceRoute, nextHop, protocol);
880 // Cancel the route request timer for destination
881 dsr->CancelRreqTimer(dst, true);
882 }
883 else
884 {
885 NS_LOG_DEBUG("The route is failed to add in cache");
886 return 0;
887 }
888 }
889 else
890 {
891 NS_LOG_DEBUG("Unable to reverse the route");
892 return 0;
893 }
894
895 /*
896 * Need to first pin down the next hop address before removing duplicates
897 */
898 Ipv4Address nextHop = ReverseSearchNextHop(ipv4Address, m_finalRoute);
899 /*
900 * First remove the duplicate ip address to automatically shorten the route, and then
901 * reversely search the next hop address
902 */
903 // Set the route
904 SetRoute(nextHop, ipv4Address);
905
906 uint16_t hops = m_finalRoute.size();
908 rrep.SetNodesAddress(m_finalRoute); // Set the node addresses in the route reply header
909 // Get the real source of the reply
910 Ipv4Address realSource = m_finalRoute.back();
912 NS_LOG_DEBUG("This is the full route from " << realSource << " to "
913 << m_finalRoute.front());
914 /*
915 * This part add dsr header to the packet and send route reply packet
916 */
917 DsrRoutingHeader dsrRoutingHeader;
918 dsrRoutingHeader.SetNextHeader(protocol);
919 dsrRoutingHeader.SetMessageType(1);
920 dsrRoutingHeader.SetSourceId(GetIDfromIP(realSource));
921 dsrRoutingHeader.SetDestId(255);
922
923 uint8_t length =
924 rrep.GetLength(); // Get the length of the rrep header excluding the type header
925 dsrRoutingHeader.SetPayloadLength(length + 2);
926 dsrRoutingHeader.AddDsrOption(rrep);
927 Ptr<Packet> newPacket = Create<Packet>();
928 newPacket->AddHeader(dsrRoutingHeader);
929 dsr->ScheduleCachedReply(newPacket, ipv4Address, nextHop, m_ipv4Route, hops);
930 isPromisc = false;
931 return rreq.GetSerializedSize();
932 }
933 /*
934 * (iii) no route in any type has been found
935 */
936 else
937 {
938 mainVector.push_back(ipv4Address);
939 NS_ASSERT(mainVector.front() == source);
940 NS_LOG_DEBUG("Print out the main vector");
941 PrintVector(mainVector);
942 rreq.SetNodesAddress(mainVector);
943
944 Ptr<Packet> errP = p->Copy();
945 if (errP->GetSize())
946 {
947 NS_LOG_DEBUG("Error header included");
949 p->RemoveHeader(rerr);
950 Ipv4Address errorSrc = rerr.GetErrorSrc();
951 Ipv4Address unreachNode = rerr.GetUnreachNode();
952 Ipv4Address errorDst = rerr.GetErrorDst();
953
954 if ((errorSrc == srcAddress) && (unreachNode == ipv4Address))
955 {
956 NS_LOG_DEBUG("The error link back to work again");
957 uint16_t length = rreq.GetLength();
958 NS_LOG_DEBUG("The RREQ header length " << length);
959 dsrRoutingHeader.AddDsrOption(rreq);
960 dsrRoutingHeader.SetPayloadLength(length + 2);
961 }
962 else
963 {
964 dsr->DeleteAllRoutesIncludeLink(errorSrc, unreachNode, ipv4Address);
965
967 newUnreach.SetErrorType(1);
968 newUnreach.SetErrorSrc(errorSrc);
969 newUnreach.SetUnreachNode(unreachNode);
970 newUnreach.SetErrorDst(errorDst);
971 newUnreach.SetSalvage(rerr.GetSalvage()); // Set the value about whether to
972 // salvage a packet or not
973 uint16_t length = rreq.GetLength() + newUnreach.GetLength();
974 NS_LOG_DEBUG("The RREQ and newUnreach header length " << length);
975 dsrRoutingHeader.SetPayloadLength(length + 4);
976 dsrRoutingHeader.AddDsrOption(rreq);
977 dsrRoutingHeader.AddDsrOption(newUnreach);
978 }
979 }
980 else
981 {
982 uint16_t length = rreq.GetLength();
983 NS_LOG_DEBUG("The RREQ header length " << length);
984 dsrRoutingHeader.AddDsrOption(rreq);
985 dsrRoutingHeader.SetPayloadLength(length + 2);
986 }
987 // Get the TTL value
988 uint8_t ttl = ipv4Header.GetTtl();
989 /*
990 * Decrease the TTL value in the packet tag by one, this tag will go to ip layer 3 send
991 * function and drop packet when TTL value equals to 0
992 */
993 NS_LOG_DEBUG("The ttl value here " << (uint32_t)ttl);
994 if (ttl)
995 {
996 Ptr<Packet> interP = Create<Packet>();
997 SocketIpTtlTag tag;
998 tag.SetTtl(ttl - 1);
999 interP->AddPacketTag(tag);
1000 interP->AddHeader(dsrRoutingHeader);
1001 dsr->ScheduleInterRequest(interP);
1002 isPromisc = false;
1003 }
1004 return rreq.GetSerializedSize();
1005 }
1006 }
1007 // unreachable: return rreq.GetSerializedSize ();
1008}
1009
1011
1012TypeId
1014{
1015 static TypeId tid = TypeId("ns3::dsr::DsrOptionRrep")
1017 .SetGroupName("Dsr")
1018 .AddConstructor<DsrOptionRrep>();
1019 return tid;
1020}
1021
1023{
1025}
1026
1028{
1030}
1031
1032TypeId
1034{
1035 return GetTypeId();
1036}
1037
1038uint8_t
1040{
1042
1043 return OPT_NUMBER;
1044}
1045
1046uint8_t
1048 Ptr<Packet> dsrP,
1049 Ipv4Address ipv4Address,
1050 Ipv4Address source,
1051 const Ipv4Header& ipv4Header,
1052 uint8_t protocol,
1053 bool& isPromisc,
1054 Ipv4Address promiscSource)
1055{
1056 NS_LOG_FUNCTION(this << packet << dsrP << ipv4Address << source << ipv4Header
1057 << (uint32_t)protocol << isPromisc);
1058
1059 Ptr<Packet> p = packet->Copy();
1060
1061 // Get the number of routers' address field
1062 uint8_t buf[2];
1063 p->CopyData(buf, sizeof(buf));
1064 uint8_t numberAddress = (buf[1] - 2) / 4;
1065
1067 rrep.SetNumberAddress(numberAddress); // Set the number of ip address in the header to reserver
1068 // space for deserialize header
1069 p->RemoveHeader(rrep);
1070
1071 Ptr<Node> node = GetNodeWithAddress(ipv4Address);
1072 Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting>();
1073
1074 NS_LOG_DEBUG("The next header value " << (uint32_t)protocol);
1075
1076 std::vector<Ipv4Address> nodeList = rrep.GetNodesAddress();
1080 Ipv4Address targetAddress = nodeList.front();
1081 // If the RREP option has reached to the destination
1082 if (targetAddress == ipv4Address)
1083 {
1084 RemoveDuplicates(nodeList); // This is for the route reply from intermediate node since we
1085 // didn't remove duplicate there
1086 if (nodeList.empty())
1087 {
1088 NS_LOG_DEBUG("The route we have contains 0 entries");
1089 return 0;
1090 }
1095 Ipv4Address dst = nodeList.back();
1101 DsrRouteCacheEntry toDestination(/*ip=*/nodeList,
1102 /*dst=*/dst,
1103 /*exp=*/ActiveRouteTimeout);
1104 NS_ASSERT(nodeList.front() == ipv4Address);
1105 bool addRoute = false;
1106 if (dsr->IsLinkCache())
1107 {
1108 addRoute = dsr->AddRoute_Link(nodeList, ipv4Address);
1109 }
1110 else
1111 {
1112 addRoute = dsr->AddRoute(toDestination);
1113 }
1114
1115 if (addRoute)
1116 {
1118 "We have added the route and search send buffer for packet with destination "
1119 << dst);
1123 DsrOptionSRHeader sourceRoute;
1124 NS_LOG_DEBUG("The route length " << nodeList.size());
1125 sourceRoute.SetNodesAddress(nodeList);
1126 sourceRoute.SetSegmentsLeft(nodeList.size() - 2);
1127 sourceRoute.SetSalvage(0);
1128 Ipv4Address nextHop = SearchNextHop(ipv4Address, nodeList); // Get the next hop address
1129 NS_LOG_DEBUG("The nextHop address " << nextHop);
1130 if (nextHop == "0.0.0.0")
1131 {
1132 dsr->PacketNewRoute(dsrP, ipv4Address, dst, protocol);
1133 return 0;
1134 }
1135 PrintVector(nodeList);
1136 SetRoute(nextHop, ipv4Address);
1137 // Cancel the route request timer for destination
1138 dsr->CancelRreqTimer(dst, true);
1142 dsr->SendPacketFromBuffer(sourceRoute, nextHop, protocol);
1143 }
1144 else
1145 {
1146 NS_LOG_DEBUG("Failed to add the route");
1147 return 0;
1148 }
1149 }
1150 else
1151 {
1152 uint8_t length = rrep.GetLength() -
1153 2; // The get length - 2 is to get aligned for the malformed header check
1154 NS_LOG_DEBUG("The length of rrep option " << (uint32_t)length);
1155
1156 if (length % 2 != 0)
1157 {
1158 NS_LOG_LOGIC("Malformed header. Drop!");
1159 m_dropTrace(packet);
1160 return 0;
1161 }
1162 PrintVector(nodeList);
1163 /*
1164 * This node is only an intermediate node, but it needs to save the possible route to the
1165 * destination when cutting the route
1166 */
1167 std::vector<Ipv4Address> routeCopy = nodeList;
1168 std::vector<Ipv4Address> cutRoute = CutRoute(ipv4Address, nodeList);
1169 PrintVector(cutRoute);
1170 if (cutRoute.size() >= 2)
1171 {
1172 Ipv4Address dst = cutRoute.back();
1173 NS_LOG_DEBUG("The route destination after cut " << dst);
1174 DsrRouteCacheEntry toDestination(/*ip=*/cutRoute,
1175 /*dst=*/dst,
1176 /*exp=*/ActiveRouteTimeout);
1177 NS_ASSERT(cutRoute.front() == ipv4Address);
1178 bool addRoute = false;
1179 if (dsr->IsLinkCache())
1180 {
1181 addRoute = dsr->AddRoute_Link(nodeList, ipv4Address);
1182 }
1183 else
1184 {
1185 addRoute = dsr->AddRoute(toDestination);
1186 }
1187 if (addRoute)
1188 {
1189 dsr->CancelRreqTimer(dst, true);
1190 }
1191 else
1192 {
1193 NS_LOG_DEBUG("The route not added");
1194 }
1195 }
1196 else
1197 {
1198 NS_LOG_DEBUG("The route is corrupted");
1199 }
1200 /*
1201 * Reverse search the vector for next hop address
1202 */
1203 Ipv4Address nextHop = ReverseSearchNextHop(ipv4Address, routeCopy);
1204 NS_ASSERT(routeCopy.back() == source);
1205 PrintVector(routeCopy);
1206 NS_LOG_DEBUG("The nextHop address " << nextHop << " and the source in the route reply "
1207 << source);
1208 /*
1209 * Set the route entry we will use to send reply
1210 */
1211 SetRoute(nextHop, ipv4Address);
1212 /*
1213 * This part add dsr routing header to the packet and send reply
1214 */
1215 DsrRoutingHeader dsrRoutingHeader;
1216 dsrRoutingHeader.SetNextHeader(protocol);
1217
1218 length = rrep.GetLength(); // Get the length of the rrep header excluding the type header
1219 NS_LOG_DEBUG("The reply header length " << (uint32_t)length);
1220 dsrRoutingHeader.SetPayloadLength(length + 2);
1221 dsrRoutingHeader.SetMessageType(1);
1222 dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
1223 dsrRoutingHeader.SetDestId(GetIDfromIP(targetAddress));
1224 dsrRoutingHeader.AddDsrOption(rrep);
1225 Ptr<Packet> newPacket = Create<Packet>();
1226 newPacket->AddHeader(dsrRoutingHeader);
1227 dsr->SendReply(newPacket, ipv4Address, nextHop, m_ipv4Route);
1228 isPromisc = false;
1229 }
1230 return rrep.GetSerializedSize();
1231}
1232
1234
1235TypeId
1237{
1238 static TypeId tid = TypeId("ns3::dsr::DsrOptionSR")
1240 .SetGroupName("Dsr")
1241 .AddConstructor<DsrOptionSR>();
1242 return tid;
1243}
1244
1246{
1248}
1249
1251{
1253}
1254
1255TypeId
1257{
1258 return GetTypeId();
1259}
1260
1261uint8_t
1263{
1265 return OPT_NUMBER;
1266}
1267
1268uint8_t
1270 Ptr<Packet> dsrP,
1271 Ipv4Address ipv4Address,
1272 Ipv4Address source,
1273 const Ipv4Header& ipv4Header,
1274 uint8_t protocol,
1275 bool& isPromisc,
1276 Ipv4Address promiscSource)
1277{
1278 NS_LOG_FUNCTION(this << packet << dsrP << ipv4Address << source << ipv4Address << ipv4Header
1279 << (uint32_t)protocol << isPromisc);
1280 Ptr<Packet> p = packet->Copy();
1281 // Get the number of routers' address field
1282 uint8_t buf[2];
1283 p->CopyData(buf, sizeof(buf));
1284 uint8_t numberAddress = (buf[1] - 2) / 4;
1285 DsrOptionSRHeader sourceRoute;
1286 sourceRoute.SetNumberAddress(numberAddress);
1287 p->RemoveHeader(sourceRoute);
1288
1289 // The route size saved in the source route
1290 std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress();
1291 uint8_t segsLeft = sourceRoute.GetSegmentsLeft();
1292 uint8_t salvage = sourceRoute.GetSalvage();
1293 /*
1294 * Get the node from IP address and get the DSR extension object
1295 */
1296 Ptr<Node> node = GetNodeWithAddress(ipv4Address);
1297 Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting>();
1298 /*
1299 * Get the source and destination address from ipv4 header
1300 */
1301 Ipv4Address srcAddress = ipv4Header.GetSource();
1302 Ipv4Address destAddress = ipv4Header.GetDestination();
1303
1304 // Get the node list destination
1305 Ipv4Address destination = nodeList.back();
1306 /*
1307 * If it's a promiscuous receive data packet,
1308 * 1. see if automatic route shortening possible or not
1309 * 2. see if it is a passive acknowledgment
1310 */
1311 if (isPromisc)
1312 {
1313 NS_LOG_LOGIC("We process promiscuous receipt data packet");
1314 if (ContainAddressAfter(ipv4Address, destAddress, nodeList))
1315 {
1316 NS_LOG_LOGIC("Send back the gratuitous reply");
1317 dsr->SendGratuitousReply(source, srcAddress, nodeList, protocol);
1318 }
1319
1320 uint16_t fragmentOffset = ipv4Header.GetFragmentOffset();
1321 uint16_t identification = ipv4Header.GetIdentification();
1322
1323 if (destAddress != destination)
1324 {
1325 NS_LOG_DEBUG("Process the promiscuously received packet");
1326 bool findPassive = false;
1327 int32_t nNodes = NodeList::GetNNodes();
1328 for (int32_t i = 0; i < nNodes; ++i)
1329 {
1330 NS_LOG_DEBUG("Working with node " << i);
1331
1332 Ptr<Node> node = NodeList::GetNode(i);
1333 Ptr<dsr::DsrRouting> dsrNode = node->GetObject<dsr::DsrRouting>();
1334 // The source and destination addresses here are the real source and destination for
1335 // the packet
1336 findPassive = dsrNode->PassiveEntryCheck(packet,
1337 source,
1338 destination,
1339 segsLeft,
1340 fragmentOffset,
1341 identification,
1342 false);
1343 if (findPassive)
1344 {
1345 break;
1346 }
1347 }
1348
1349 if (findPassive)
1350 {
1351 NS_LOG_DEBUG("We find one previously received passive entry");
1352 /*
1353 * Get the node from IP address and get the DSR extension object
1354 * the srcAddress would be the source address from ip header
1355 */
1356 PrintVector(nodeList);
1357
1358 NS_LOG_DEBUG("promisc source " << promiscSource);
1359 Ptr<Node> node = GetNodeWithAddress(promiscSource);
1360 Ptr<dsr::DsrRouting> dsrSrc = node->GetObject<dsr::DsrRouting>();
1361 dsrSrc->CancelPassiveTimer(packet, source, destination, segsLeft);
1362 }
1363 else
1364 {
1365 NS_LOG_DEBUG("Saved the entry for further use");
1366 dsr->PassiveEntryCheck(packet,
1367 source,
1368 destination,
1369 segsLeft,
1370 fragmentOffset,
1371 identification,
1372 true);
1373 }
1374 }
1376 return 0;
1377 }
1378 else
1379 {
1380 /*
1381 * Get the number of address from the source route header
1382 */
1383 uint8_t length = sourceRoute.GetLength();
1384 uint8_t nextAddressIndex;
1385 Ipv4Address nextAddress;
1386
1387 // Get the option type value
1388 uint32_t size = p->GetSize();
1389 auto data = new uint8_t[size];
1390 p->CopyData(data, size);
1391 uint8_t optionType = 0;
1392 optionType = *(data);
1395 if (optionType == 160)
1396 {
1397 NS_LOG_LOGIC("Remove the ack request header and add ack header to the packet");
1398 // Here we remove the ack packet to the previous hop
1399 DsrOptionAckReqHeader ackReq;
1400 p->RemoveHeader(ackReq);
1401 uint16_t ackId = ackReq.GetAckId();
1402 /*
1403 * Send back acknowledgment packet to the earlier hop
1404 * If the node list is not empty, find the previous hop from the node list,
1405 * otherwise, use srcAddress
1406 */
1407 Ipv4Address ackAddress = srcAddress;
1408 if (!nodeList.empty())
1409 {
1410 if (segsLeft > numberAddress) // The segmentsLeft field should not be larger than
1411 // the total number of ip addresses
1412 {
1413 NS_LOG_LOGIC("Malformed header. Drop!");
1414 m_dropTrace(packet);
1415 return 0;
1416 }
1417 // -fstrict-overflow sensitive, see bug 1868
1418 if (numberAddress - segsLeft < 2) // The index is invalid
1419 {
1420 NS_LOG_LOGIC("Malformed header. Drop!");
1421 m_dropTrace(packet);
1422 return 0;
1423 }
1424 ackAddress = nodeList[numberAddress - segsLeft - 2];
1425 }
1426 m_ipv4Route = SetRoute(ackAddress, ipv4Address);
1427 NS_LOG_DEBUG("Send back ACK to the earlier hop " << ackAddress << " from us "
1428 << ipv4Address);
1429 dsr->SendAck(ackId, ackAddress, source, destination, protocol, m_ipv4Route);
1430 }
1431 /*
1432 * After send back ACK, check if the segments left value has turned to 0 or not, if yes,
1433 * update the route entry and return header length
1434 */
1435 if (segsLeft == 0)
1436 {
1437 NS_LOG_DEBUG("This is the final destination");
1438 isPromisc = false;
1439 return sourceRoute.GetSerializedSize();
1440 }
1441
1442 if (length % 2 != 0)
1443 {
1444 NS_LOG_LOGIC("Malformed header. Drop!");
1445 m_dropTrace(packet);
1446 return 0;
1447 }
1448
1449 if (segsLeft > numberAddress) // The segmentsLeft field should not be larger than the total
1450 // number of ip addresses
1451 {
1452 NS_LOG_LOGIC("Malformed header. Drop!");
1453 m_dropTrace(packet);
1454 return 0;
1455 }
1456
1457 DsrOptionSRHeader newSourceRoute;
1458 newSourceRoute.SetSegmentsLeft(segsLeft - 1);
1459 newSourceRoute.SetSalvage(salvage);
1460 newSourceRoute.SetNodesAddress(nodeList);
1461 nextAddressIndex = numberAddress - segsLeft;
1462 nextAddress = newSourceRoute.GetNodeAddress(nextAddressIndex);
1463 NS_LOG_DEBUG("The next address of source route option "
1464 << nextAddress << " and the nextAddressIndex: " << (uint32_t)nextAddressIndex
1465 << " and the segments left : " << (uint32_t)segsLeft);
1466 /*
1467 * Get the target Address in the node list
1468 */
1469 Ipv4Address targetAddress = nodeList.back();
1470 Ipv4Address realSource = nodeList.front();
1471 /*
1472 * Search the vector for next hop address
1473 */
1474 Ipv4Address nextHop = SearchNextHop(ipv4Address, nodeList);
1475 PrintVector(nodeList);
1476
1477 if (nextHop == "0.0.0.0")
1478 {
1479 NS_LOG_DEBUG("Before new packet " << *dsrP);
1480 dsr->PacketNewRoute(dsrP, realSource, targetAddress, protocol);
1481 return 0;
1482 }
1483
1484 if (ipv4Address == nextHop)
1485 {
1486 NS_LOG_DEBUG("We have reached the destination");
1487 newSourceRoute.SetSegmentsLeft(0);
1488 return newSourceRoute.GetSerializedSize();
1489 }
1490 // Verify the multicast address, leave it here for now
1491 if (nextAddress.IsMulticast() || destAddress.IsMulticast())
1492 {
1493 m_dropTrace(packet);
1494 return 0;
1495 }
1496 // Set the route and forward the data packet
1497 SetRoute(nextAddress, ipv4Address);
1498 NS_LOG_DEBUG("dsr packet size " << dsrP->GetSize());
1499 dsr->ForwardPacket(dsrP,
1500 newSourceRoute,
1501 ipv4Header,
1502 realSource,
1503 nextAddress,
1504 targetAddress,
1505 protocol,
1506 m_ipv4Route);
1507 }
1508 return sourceRoute.GetSerializedSize();
1509}
1510
1512
1513TypeId
1515{
1516 static TypeId tid = TypeId("ns3::dsr::DsrOptionRerr")
1518 .SetGroupName("Dsr")
1519 .AddConstructor<DsrOptionRerr>();
1520 return tid;
1521}
1522
1524{
1526}
1527
1529{
1531}
1532
1533TypeId
1535{
1536 return GetTypeId();
1537}
1538
1539uint8_t
1541{
1543 return OPT_NUMBER;
1544}
1545
1546uint8_t
1548 Ptr<Packet> dsrP,
1549 Ipv4Address ipv4Address,
1550 Ipv4Address source,
1551 const Ipv4Header& ipv4Header,
1552 uint8_t protocol,
1553 bool& isPromisc,
1554 Ipv4Address promiscSource)
1555{
1556 NS_LOG_FUNCTION(this << packet << dsrP << ipv4Address << source << ipv4Header
1557 << (uint32_t)protocol << isPromisc);
1558 Ptr<Packet> p = packet->Copy();
1559 uint32_t size = p->GetSize();
1560 auto data = new uint8_t[size];
1561 p->CopyData(data, size);
1562 uint8_t errorType = *(data + 2);
1563 /*
1564 * Get the node from Ip address and get the dsr extension object
1565 */
1566 Ptr<Node> node = GetNodeWithAddress(ipv4Address);
1567 Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting>();
1568 NS_LOG_DEBUG("The error type value here " << (uint32_t)errorType);
1569 if (errorType == 1) // unreachable ip address
1570 {
1571 /*
1572 * Remove the route error header from the packet, and get the error type
1573 */
1574 DsrOptionRerrUnreachHeader rerrUnreach;
1575 p->RemoveHeader(rerrUnreach);
1576 /*
1577 * Get the error destination address
1578 */
1579 Ipv4Address unreachAddress = rerrUnreach.GetUnreachNode();
1580 Ipv4Address errorSource = rerrUnreach.GetErrorSrc();
1581
1582 NS_LOG_DEBUG("The error source is " << rerrUnreach.GetErrorDst()
1583 << "and the unreachable node is " << unreachAddress);
1584 /*
1585 * Get the serialized size of the rerr header
1586 */
1587 uint32_t rerrSize = rerrUnreach.GetSerializedSize();
1588 /*
1589 * Delete all the routes including the unreachable node address from the route cache
1590 */
1591 Ptr<Node> node = GetNodeWithAddress(ipv4Address);
1592 dsr->DeleteAllRoutesIncludeLink(errorSource, unreachAddress, ipv4Address);
1593
1594 Ptr<Packet> newP = p->Copy();
1595 uint32_t serialized = DoSendError(newP, rerrUnreach, rerrSize, ipv4Address, protocol);
1596 return serialized;
1597 }
1598 else
1599 {
1600 /*
1601 * Two other type of error headers:
1602 * 1. flow state not supported type-specific information
1603 * 2. unsupported option with option number
1604 */
1605 /*
1606 * Remove the route error header from the packet, and get the error type
1607 */
1608 DsrOptionRerrUnsupportedHeader rerrUnsupported;
1609 p->RemoveHeader(rerrUnsupported);
1610
1612 // uint32_t rerrSize = rerrUnsupported.GetSerializedSize();
1613 // uint32_t serialized = DoSendError (p, rerrUnsupported, rerrSize, ipv4Address, protocol);
1614 uint32_t serialized = 0;
1615 return serialized;
1616 }
1617}
1618
1619uint8_t
1622 uint32_t rerrSize,
1623 Ipv4Address ipv4Address,
1624 uint8_t protocol)
1625{
1626 // Get the number of routers' address field
1627 uint8_t buf[2];
1628 p->CopyData(buf, sizeof(buf));
1629 uint8_t numberAddress = (buf[1] - 2) / 4;
1630
1631 // Here remove the source route header and schedule next hop error transmission
1632 NS_LOG_DEBUG("The number of addresses " << (uint32_t)numberAddress);
1633 DsrOptionSRHeader sourceRoute;
1634 sourceRoute.SetNumberAddress(numberAddress);
1635 p->RemoveHeader(sourceRoute);
1636 NS_ASSERT(p->GetSize() == 0);
1637 /*
1638 * Get the node from ip address and the dsr extension object
1639 */
1640 Ptr<Node> node = GetNodeWithAddress(ipv4Address);
1641 Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting>();
1642 /*
1643 * Get the segments left field and the next address
1644 */
1645 uint8_t segmentsLeft = sourceRoute.GetSegmentsLeft();
1646 uint8_t length = sourceRoute.GetLength();
1647 uint8_t nextAddressIndex;
1648 Ipv4Address nextAddress;
1649 /*
1650 * Get the route size and the error target address
1651 */
1652 std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress();
1653 Ipv4Address targetAddress = nodeList.back();
1654 /*
1655 * The total serialized size for both the rerr and source route headers
1656 */
1657 uint32_t serializedSize = rerrSize + sourceRoute.GetSerializedSize();
1658
1659 if (length % 2 != 0)
1660 {
1661 NS_LOG_LOGIC("Malformed header. Drop!");
1662 m_dropTrace(p);
1663 return 0;
1664 }
1665
1666 if (segmentsLeft > numberAddress)
1667 {
1668 NS_LOG_LOGIC("Malformed header. Drop!");
1669 m_dropTrace(p);
1670 return 0;
1671 }
1672 /*
1673 * When the error packet has reached to the destination
1674 */
1675 if (segmentsLeft == 0 && targetAddress == ipv4Address)
1676 {
1677 NS_LOG_INFO("This is the destination of the error, send error request");
1678 dsr->SendErrorRequest(rerr, protocol);
1679 return serializedSize;
1680 }
1681
1682 // Get the next Router Address
1683 DsrOptionSRHeader newSourceRoute;
1684 newSourceRoute.SetSegmentsLeft(segmentsLeft - 1);
1685 nextAddressIndex = numberAddress - segmentsLeft;
1686 nextAddress = sourceRoute.GetNodeAddress(nextAddressIndex);
1687 newSourceRoute.SetSalvage(sourceRoute.GetSalvage());
1688 newSourceRoute.SetNodesAddress(nodeList);
1689 nextAddress = newSourceRoute.GetNodeAddress(nextAddressIndex);
1690
1692 if (nextAddress.IsMulticast() || targetAddress.IsMulticast())
1693 {
1694 m_dropTrace(p);
1695 return serializedSize;
1696 }
1697
1698 // Set the route entry
1699 SetRoute(nextAddress, ipv4Address);
1700 dsr->ForwardErrPacket(rerr, newSourceRoute, nextAddress, protocol, m_ipv4Route);
1701 return serializedSize;
1702}
1703
1705
1706TypeId
1708{
1709 static TypeId tid = TypeId("ns3::dsr::DsrOptionAckReq")
1711 .SetGroupName("Dsr")
1712 .AddConstructor<DsrOptionAckReq>();
1713 return tid;
1714}
1715
1717{
1719}
1720
1722{
1724}
1725
1726TypeId
1728{
1729 return GetTypeId();
1730}
1731
1732uint8_t
1734{
1736 return OPT_NUMBER;
1737}
1738
1739uint8_t
1741 Ptr<Packet> dsrP,
1742 Ipv4Address ipv4Address,
1743 Ipv4Address source,
1744 const Ipv4Header& ipv4Header,
1745 uint8_t protocol,
1746 bool& isPromisc,
1747 Ipv4Address promiscSource)
1748{
1749 NS_LOG_FUNCTION(this << packet << dsrP << ipv4Address << source << ipv4Header
1750 << (uint32_t)protocol << isPromisc);
1751 /*
1752 * Current implementation of the ack request header processing is coded in source route header
1753 * processing
1754 */
1755 /*
1756 * Remove the ack request header
1757 */
1758 Ptr<Packet> p = packet->Copy();
1759 DsrOptionAckReqHeader ackReq;
1760 p->RemoveHeader(ackReq);
1761 /*
1762 * Get the node with ip address and get the dsr extension and route cache objects
1763 */
1764 Ptr<Node> node = GetNodeWithAddress(ipv4Address);
1765 Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting>();
1766
1767 NS_LOG_DEBUG("The next header value " << (uint32_t)protocol);
1768
1769 return ackReq.GetSerializedSize();
1770}
1771
1773
1774TypeId
1776{
1777 static TypeId tid = TypeId("ns3::dsr::DsrOptionAck")
1779 .SetGroupName("Dsr")
1780 .AddConstructor<DsrOptionAck>();
1781 return tid;
1782}
1783
1785{
1787}
1788
1790{
1792}
1793
1794TypeId
1796{
1797 return GetTypeId();
1798}
1799
1800uint8_t
1802{
1804 return OPT_NUMBER;
1805}
1806
1807uint8_t
1809 Ptr<Packet> dsrP,
1810 Ipv4Address ipv4Address,
1811 Ipv4Address source,
1812 const Ipv4Header& ipv4Header,
1813 uint8_t protocol,
1814 bool& isPromisc,
1815 Ipv4Address promiscSource)
1816{
1817 NS_LOG_FUNCTION(this << packet << dsrP << ipv4Address << source << ipv4Header
1818 << (uint32_t)protocol << isPromisc);
1819 /*
1820 * Remove the ACK header
1821 */
1822 Ptr<Packet> p = packet->Copy();
1824 p->RemoveHeader(ack);
1825 /*
1826 * Get the ACK source and destination address
1827 */
1828 Ipv4Address realSrc = ack.GetRealSrc();
1829 Ipv4Address realDst = ack.GetRealDst();
1830 uint16_t ackId = ack.GetAckId();
1831 /*
1832 * Get the node with ip address and get the dsr extension and route cache objects
1833 */
1834 Ptr<Node> node = GetNodeWithAddress(ipv4Address);
1835 Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting>();
1836 dsr->UpdateRouteEntry(realDst);
1837 /*
1838 * Cancel the packet retransmit timer when receiving the ack packet
1839 */
1840 dsr->CallCancelPacketTimer(ackId, ipv4Header, realSrc, realDst);
1841 return ack.GetSerializedSize();
1842}
1843
1844} // namespace dsr
1845} // namespace ns3
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
bool IsMulticast() const
Packet header for IPv4.
Definition: ipv4-header.h:34
Ipv4Address GetSource() const
Definition: ipv4-header.cc:302
uint16_t GetIdentification() const
Definition: ipv4-header.cc:71
Ipv4Address GetDestination() const
Definition: ipv4-header.cc:316
uint16_t GetFragmentOffset() const
Definition: ipv4-header.cc:254
uint8_t GetTtl() const
Definition: ipv4-header.cc:274
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:80
static uint32_t GetNNodes()
Definition: node-list.cc:258
static Ptr< Node > GetNode(uint32_t n)
Definition: node-list.cc:251
A base class which provides memory management and object aggregation.
Definition: object.h:89
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer.
Definition: socket.h:1124
void SetTtl(uint8_t ttl)
Set the tag's TTL.
Definition: socket.cc:604
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
Hold an unsigned integer type.
Definition: uinteger.h:45
void SetSourceId(uint16_t sourceId)
brief Set the source ID of the header.
void SetNextHeader(uint8_t protocol)
Set the "Next header" field.
void SetDestId(uint16_t destId)
brief Set the dest ID of the header.
void SetMessageType(uint8_t messageType)
brief Set the message type of the header.
void SetPayloadLength(uint16_t length)
brief Set the payload length of the header.
Acknowledgement (ACK) Message Format.
uint16_t GetAckId() const
Set the Ack id number.
Ipv4Address GetRealDst() const
Get Error source ip address.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
Ipv4Address GetRealSrc() const
Get Error source ip address.
Dsr Option Ack.
Definition: dsr-options.h:606
uint8_t Process(Ptr< Packet > packet, Ptr< Packet > dsrP, Ipv4Address ipv4Address, Ipv4Address source, const Ipv4Header &ipv4Header, uint8_t protocol, bool &isPromisc, Ipv4Address promiscSource) override
Process method.
TypeId GetInstanceTypeId() const override
Get the instance type ID.
static const uint8_t OPT_NUMBER
The Dsr Ack option number.
Definition: dsr-options.h:611
static TypeId GetTypeId()
Get the type ID.
uint8_t GetOptionNumber() const override
Get the option number.
Acknowledgement Request (ACK_RREQ) Message Format.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
uint16_t GetAckId() const
Set the Ack request id number.
static TypeId GetTypeId()
Get the type ID.
uint8_t GetOptionNumber() const override
Get the option number.
uint8_t Process(Ptr< Packet > packet, Ptr< Packet > dsrP, Ipv4Address ipv4Address, Ipv4Address source, const Ipv4Header &ipv4Header, uint8_t protocol, bool &isPromisc, Ipv4Address promiscSource) override
Process method.
static const uint8_t OPT_NUMBER
Dsr ack request option number.
Definition: dsr-options.h:564
TypeId GetInstanceTypeId() const override
Get the instance type ID.
void AddDsrOption(const DsrOptionHeader &option)
Serialize the option, prepending pad1 or padn option as necessary.
uint8_t GetLength() const
Get the option length.
Header of Dsr Option Pad1.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
Dsr Option Pad1.
Definition: dsr-options.h:291
uint8_t GetOptionNumber() const override
Get the option number.
Definition: dsr-options.cc:400
static TypeId GetTypeId()
Get the type ID.
Definition: dsr-options.cc:380
uint8_t Process(Ptr< Packet > packet, Ptr< Packet > dsrP, Ipv4Address ipv4Address, Ipv4Address source, const Ipv4Header &ipv4Header, uint8_t protocol, bool &isPromisc, Ipv4Address promiscSource) override
Process method.
Definition: dsr-options.cc:408
static const uint8_t OPT_NUMBER
Pad1 option number.
Definition: dsr-options.h:296
Header of Dsr Option Padn.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
IPv4 Option Padn.
Definition: dsr-options.h:323
static const uint8_t OPT_NUMBER
PadN option number.
Definition: dsr-options.h:328
uint8_t Process(Ptr< Packet > packet, Ptr< Packet > dsrP, Ipv4Address ipv4Address, Ipv4Address source, const Ipv4Header &ipv4Header, uint8_t protocol, bool &isPromisc, Ipv4Address promiscSource) override
Process method.
Definition: dsr-options.cc:458
static TypeId GetTypeId()
Get the type ID.
Definition: dsr-options.cc:431
uint8_t GetOptionNumber() const override
Get the option number.
Definition: dsr-options.cc:451
void SetErrorType(uint8_t errorType)
Set the route error type.
Dsr Option Route Error.
Definition: dsr-options.h:497
uint8_t DoSendError(Ptr< Packet > p, DsrOptionRerrUnreachHeader &rerr, uint32_t rerrSize, Ipv4Address ipv4Address, uint8_t protocol)
Do Send error message.
static const uint8_t OPT_NUMBER
Dsr Route Error option number.
Definition: dsr-options.h:502
static TypeId GetTypeId()
Get the type ID.
uint8_t Process(Ptr< Packet > packet, Ptr< Packet > dsrP, Ipv4Address ipv4Address, Ipv4Address source, const Ipv4Header &ipv4Header, uint8_t protocol, bool &isPromisc, Ipv4Address promiscSource) override
Process method.
uint8_t GetOptionNumber() const override
Get the option number.
TypeId GetInstanceTypeId() const override
Get the instance type ID.
Route Error (RERR) Unreachable node address option Message Format.
Ipv4Address GetErrorSrc() const override
Get the route error source address.
void SetErrorDst(Ipv4Address errorDstAddress) override
Set the error destination ip address.
void SetErrorSrc(Ipv4Address errorSrcAddress) override
Set the route error source address.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
uint8_t GetSalvage() const override
Get the salvage value of the packet.
void SetUnreachNode(Ipv4Address unreachNode)
Set the unreachable node ip address.
void SetSalvage(uint8_t salvage) override
Set the salvage value of the packet.
Ipv4Address GetUnreachNode() const
Get the unreachable node ip address.
Ipv4Address GetErrorDst() const override
Get the error destination ip address.
Route Error (RERR) Unsupported option Message Format.
Route Reply (RREP) Message Format.
void SetNumberAddress(uint8_t n)
Set the number of ipv4 address.
std::vector< Ipv4Address > GetNodesAddress() const
Get the vector of ipv4 address.
void SetNodesAddress(std::vector< Ipv4Address > ipv4Address)
Set the vector of ipv4 address.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
Dsr Option Route Reply.
Definition: dsr-options.h:407
static const uint8_t OPT_NUMBER
Router alert option number.
Definition: dsr-options.h:412
static TypeId GetTypeId()
Get the type ID.
TypeId GetInstanceTypeId() const override
Get the instance type ID.
uint8_t GetOptionNumber() const override
Get the option number.
uint8_t Process(Ptr< Packet > packet, Ptr< Packet > dsrP, Ipv4Address ipv4Address, Ipv4Address source, const Ipv4Header &ipv4Header, uint8_t protocol, bool &isPromisc, Ipv4Address promiscSource) override
Process method.
Route Request (RREQ) Message Format.
void SetNodesAddress(std::vector< Ipv4Address > ipv4Address)
Set the vector of ipv4 address.
void SetNumberAddress(uint8_t n)
Set the number of ipv4 address.
Ipv4Address GetTarget()
Get the target ipv4 address.
std::vector< Ipv4Address > GetNodesAddresses() const
Get the vector of ipv4 address.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
uint16_t GetId() const
Set the request id number.
Dsr Option Rreq.
Definition: dsr-options.h:355
static TypeId GetTypeId()
Get the type ID.
Definition: dsr-options.cc:482
TypeId GetInstanceTypeId() const override
Get the instance type ID.
Definition: dsr-options.cc:492
static const uint8_t OPT_NUMBER
Rreq option number.
Definition: dsr-options.h:360
uint8_t Process(Ptr< Packet > packet, Ptr< Packet > dsrP, Ipv4Address ipv4Address, Ipv4Address source, const Ipv4Header &ipv4Header, uint8_t protocol, bool &isPromisc, Ipv4Address promiscSource) override
Process method.
Definition: dsr-options.cc:516
uint8_t GetOptionNumber() const override
Get the option number.
Definition: dsr-options.cc:508
~DsrOptionRreq() override
Destructor.
Definition: dsr-options.cc:502
DsrOptionRreq()
Constructor.
Definition: dsr-options.cc:497
Source Route (SR) Message Format.
Ipv4Address GetNodeAddress(uint8_t index) const
Get a Node IPv4 Address.
std::vector< Ipv4Address > GetNodesAddress() const
Get the vector of ipv4 address.
void SetNumberAddress(uint8_t n)
Set the number of ipv4 address.
void SetSalvage(uint8_t salvage)
Set the salvage value for a packet.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
void SetSegmentsLeft(uint8_t segmentsLeft)
Set the number of segments left to send.
uint8_t GetSalvage() const
Get the salvage value for a packet.
void SetNodesAddress(std::vector< Ipv4Address > ipv4Address)
Set the vector of ipv4 address.
uint8_t GetSegmentsLeft() const
Get the number of segments left to send.
Dsr Option Source Route.
Definition: dsr-options.h:454
TypeId GetInstanceTypeId() const override
Get the instance type ID.
static const uint8_t OPT_NUMBER
Source Route option number.
Definition: dsr-options.h:459
uint8_t Process(Ptr< Packet > packet, Ptr< Packet > dsrP, Ipv4Address ipv4Address, Ipv4Address source, const Ipv4Header &ipv4Header, uint8_t protocol, bool &isPromisc, Ipv4Address promiscSource) override
Process method.
uint8_t GetOptionNumber() const override
Get the option number.
static TypeId GetTypeId()
Get the type ID.
Introspection did not find any typical Config paths.
Definition: dsr-options.h:76
Ipv4Address SearchNextHop(Ipv4Address ipv4Address, std::vector< Ipv4Address > &vec)
Search for the next hop in the route.
Definition: dsr-options.cc:175
Ipv4Address ReverseSearchNextTwoHop(Ipv4Address ipv4Address, std::vector< Ipv4Address > &vec)
Reverse search for the next two hop in the route.
Definition: dsr-options.cc:234
TracedCallback< Ptr< const Packet > > m_dropTrace
Drop trace callback.
Definition: dsr-options.h:244
Ptr< Node > GetNodeWithAddress(Ipv4Address ipv4Address)
Get the node object with Ipv4Address.
Definition: dsr-options.cc:360
DsrOptions()
Constructor.
Definition: dsr-options.cc:98
Ptr< Node > GetNode() const
Get the node.
Definition: dsr-options.cc:116
Time ActiveRouteTimeout
The active route timeout value.
Definition: dsr-options.h:276
bool CheckDuplicates(Ipv4Address ipv4Address, std::vector< Ipv4Address > &vec)
Check if the route already contains the node ip address.
Definition: dsr-options.cc:292
void SetNode(Ptr< Node > node)
Set the node.
Definition: dsr-options.cc:109
virtual uint8_t GetOptionNumber() const =0
Get the option number.
~DsrOptions() override
Destructor.
Definition: dsr-options.cc:103
std::vector< Ipv4Address > m_finalRoute
The vector of final Ipv4 address.
Definition: dsr-options.h:272
void PrintVector(std::vector< Ipv4Address > &vec)
Print out the elements in the route vector.
Definition: dsr-options.cc:254
bool IfDuplicates(std::vector< Ipv4Address > &vec, std::vector< Ipv4Address > &vec2)
Check if the two vectors contain duplicate or not.
Definition: dsr-options.cc:275
bool ReverseRoutes(std::vector< Ipv4Address > &vec)
Reverse the routes.
Definition: dsr-options.cc:165
void RemoveDuplicates(std::vector< Ipv4Address > &vec)
Remove the duplicates from the route.
Definition: dsr-options.cc:306
uint32_t GetIDfromIP(Ipv4Address address)
Get the node id with Ipv4Address.
Definition: dsr-options.cc:343
static TypeId GetTypeId()
Get the type identificator.
Definition: dsr-options.cc:77
std::vector< Ipv4Address > CutRoute(Ipv4Address ipv4Address, std::vector< Ipv4Address > &nodeList)
Cut the route from ipv4Address to the end of the route vector.
Definition: dsr-options.cc:141
bool ContainAddressAfter(Ipv4Address ipv4Address, Ipv4Address destAddress, std::vector< Ipv4Address > &nodeList)
Search for the ipv4 address in the node list.
Definition: dsr-options.cc:123
TracedCallback< const DsrOptionSRHeader & > m_rxPacketTrace
The receive trace back, only triggered when final destination receive data packet.
Definition: dsr-options.h:280
Ipv4Address ReverseSearchNextHop(Ipv4Address ipv4Address, std::vector< Ipv4Address > &vec)
Reverse search for the next hop in the route.
Definition: dsr-options.cc:208
Ptr< Ipv4Route > m_ipv4Route
The ipv4 route.
Definition: dsr-options.h:260
virtual Ptr< Ipv4Route > SetRoute(Ipv4Address nextHop, Ipv4Address srcAddress)
Set the route to use for data packets, used by the option headers when sending data/control packets.
Definition: dsr-options.cc:154
Ptr< Node > m_node
the node
Definition: dsr-options.h:283
DsrRouteCacheEntry class for entries in the route cache.
Definition: dsr-rcache.h:229
IP_VECTOR GetVector() const
Get the IP vector.
Definition: dsr-rcache.h:309
std::vector< Ipv4Address > IP_VECTOR
Define the vector to hold Ip address.
Definition: dsr-rcache.h:231
Header of Dsr Routing.
Dsr Routing base.
Definition: dsr-routing.h:98
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint8_t data[writeSize]