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