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
484
489
490uint8_t
492{
494
495 return OPT_NUMBER;
496}
497
498uint8_t
500 Ptr<Packet> dsrP,
501 Ipv4Address ipv4Address,
502 Ipv4Address source,
503 const Ipv4Header& ipv4Header,
504 uint8_t protocol,
505 bool& isPromisc,
506 Ipv4Address promiscSource)
507{
508 NS_LOG_FUNCTION(this << packet << dsrP << ipv4Address << source << ipv4Header
509 << (uint32_t)protocol << isPromisc);
510 // Fields from IP header
511 Ipv4Address srcAddress = ipv4Header.GetSource();
512 /*
513 * \ when the ip source address is equal to the address of our own, this is request packet
514 * originated \ by the node itself, discard it
515 */
516 if (source == ipv4Address)
517 {
518 NS_LOG_DEBUG("Discard the packet since it was originated from same source address");
519 m_dropTrace(packet); // call the drop trace to show in the tracing
520 return 0;
521 }
522 /*
523 * Get the node associated with the ipv4 address and get several objects from the node and leave
524 * for further use
525 */
526 Ptr<Node> node = GetNodeWithAddress(ipv4Address);
527 Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting>();
528
529 Ptr<Packet> p =
530 packet->Copy(); // Note: The packet here doesn't contain the fixed size dsr header
531 /*
532 * @brief Get the number of routers' address field before removing the header
533 * @peek the packet and get the value
534 */
535 uint8_t buf[2];
536 p->CopyData(buf, sizeof(buf));
537 uint8_t numberAddress = (buf[1] - 6) / 4;
538 NS_LOG_DEBUG("The number of Ip addresses " << (uint32_t)numberAddress);
539 if (numberAddress >= 255)
540 {
541 NS_LOG_DEBUG("Discard the packet, malformed header since two many ip addresses in route");
542 m_dropTrace(packet); // call the drop trace to show in the tracing
543 return 0;
544 }
545
546 /*
547 * Create the dsr rreq header
548 */
550 /*
551 * Set the number of addresses with the value from peek data and remove the rreq header
552 */
553 rreq.SetNumberAddress(numberAddress);
554 // Remove the route request header
555 p->RemoveHeader(rreq);
556 // Verify the option length
557 uint8_t length = rreq.GetLength();
558 if (length % 2 != 0)
559 {
560 NS_LOG_LOGIC("Malformed header. Drop!");
561 m_dropTrace(packet); // call drop trace
562 return 0;
563 }
564 // Check the rreq id for verifying the request id
565 uint16_t requestId = rreq.GetId();
566 // The target address is where we want to send the data packets
567 Ipv4Address targetAddress = rreq.GetTarget();
568 // Get the node list and source address from the route request header
569 std::vector<Ipv4Address> mainVector = rreq.GetNodesAddresses();
570 std::vector<Ipv4Address> nodeList(mainVector);
571 // Get the real source address of this request, it will be used when checking if we have
572 // received the save route request before or not
573 Ipv4Address sourceAddress = nodeList.front();
574 PrintVector(nodeList);
575 /*
576 * Construct the dsr routing header for later use
577 */
578 DsrRoutingHeader dsrRoutingHeader;
579 dsrRoutingHeader.SetNextHeader(protocol);
580 dsrRoutingHeader.SetMessageType(1);
581 dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
582 dsrRoutingHeader.SetDestId(255);
583
584 // check whether we have received this request or not, if not, it will save the request in the
585 // table for later use, if not found, return false, and push the newly received source request
586 // entry in the cache
587
588 // Get the TTL value, this is used to test if the packet will be forwarded or not
589 uint8_t ttl = ipv4Header.GetTtl();
590 bool dupRequest = false; // initialize the duplicate request check value
591 if (ttl)
592 {
593 // if the ttl value is not 0, then this request will be forwarded, then we need to
594 // save it in the source entry
595 dupRequest = dsr->FindSourceEntry(sourceAddress, targetAddress, requestId);
596 }
597 /*
598 * Before processing the route request, we need to check two things
599 * 1. if this is the exact same request we have just received, ignore it
600 * 2. if our address is already in the path list, ignore it
601 * 3. otherwise process further
602 */
603
604 if (dupRequest)
605 {
606 // We have received this same route request before, not forwarding it now
607 NS_LOG_LOGIC("Duplicate request. Drop!");
608 m_dropTrace(packet); // call drop trace
609 return 0;
610 }
611
612 else if (CheckDuplicates(ipv4Address, nodeList))
613 {
614 /*
615 * if the route contains the node address already, drop the request packet
616 */
617 m_dropTrace(packet); // call drop trace
618 NS_LOG_DEBUG("Our node address is already seen in the route, drop the request");
619 return 0;
620 }
621 else
622 {
623 // A node ignores all RREQs received from any node in its blacklist
624 DsrRouteCacheEntry toPrev;
625 bool isRouteInCache = dsr->LookupRoute(targetAddress, toPrev);
627 toPrev.GetVector(); // The route from our own route cache to dst
628 PrintVector(ip);
629 std::vector<Ipv4Address> saveRoute(nodeList);
630 PrintVector(saveRoute);
631 bool areThereDuplicates = IfDuplicates(ip, saveRoute);
632 /*
633 * When the reverse route is created or updated, the following actions on the route are
634 * also carried out:
635 * 3. the next hop in the routing table becomes the node from which the RREQ was received
636 * 4. the hop count is copied from the Hop Count in the RREQ message;
637 */
638
639 // A node generates a RREP if either:
640 // (i) it is itself the destination,
641 /*
642 * The target address equal to our own ip address
643 */
644 NS_LOG_DEBUG("The target address over here " << targetAddress << " and the ip address "
645 << ipv4Address << " and the source address "
646 << mainVector[0]);
647 if (targetAddress == ipv4Address)
648 {
649 Ipv4Address nextHop; // Declare the next hop address to use
650 if (nodeList.size() == 1)
651 {
652 NS_LOG_DEBUG("These two nodes are neighbors");
653 m_finalRoute.clear();
654 /// TODO has changed the srcAddress to source, should not matter either way, check
655 /// later
656 m_finalRoute.push_back(source); // push back the request originator's address
657 m_finalRoute.push_back(ipv4Address); // push back our own address
658 nextHop = srcAddress;
659 }
660 else
661 {
662 std::vector<Ipv4Address> changeRoute(nodeList);
663 changeRoute.push_back(ipv4Address); // push back our own address
664 m_finalRoute.clear(); // get a clear route vector
665 for (auto i = changeRoute.begin(); i != changeRoute.end(); ++i)
666 {
667 m_finalRoute.push_back(*i); // Get the full route from source to destination
668 }
670 nextHop = ReverseSearchNextHop(ipv4Address, m_finalRoute); // get the next hop
671 }
672
674 rrep.SetNodesAddress(m_finalRoute); // Set the node addresses in the route reply header
675 NS_LOG_DEBUG("The nextHop address " << nextHop);
676 Ipv4Address replyDst = m_finalRoute.front();
677 /*
678 * This part add dsr header to the packet and send route reply packet
679 */
680 DsrRoutingHeader dsrRoutingHeader;
681 dsrRoutingHeader.SetNextHeader(protocol);
682 dsrRoutingHeader.SetMessageType(1);
683 dsrRoutingHeader.SetSourceId(GetIDfromIP(ipv4Address));
684 dsrRoutingHeader.SetDestId(GetIDfromIP(replyDst));
685 // Set the route for route reply
686 SetRoute(nextHop, ipv4Address);
687
688 uint8_t length =
689 rrep.GetLength(); // Get the length of the rrep header excluding the type header
690 dsrRoutingHeader.SetPayloadLength(length + 2);
691 dsrRoutingHeader.AddDsrOption(rrep);
692 Ptr<Packet> newPacket = Create<Packet>();
693 newPacket->AddHeader(dsrRoutingHeader);
694 dsr->ScheduleInitialReply(newPacket, ipv4Address, nextHop, m_ipv4Route);
695 /*
696 * Create the route entry to the rreq originator and save it to route cache, also need
697 * to reverse the route
698 */
701 {
703 Ipv4Address dst = m_finalRoute.back();
704 bool addRoute = false;
705 if (numberAddress > 0)
706 {
707 DsrRouteCacheEntry toSource(/*ip=*/m_finalRoute,
708 /*dst=*/dst,
709 /*exp=*/ActiveRouteTimeout);
710 if (dsr->IsLinkCache())
711 {
712 addRoute = dsr->AddRoute_Link(m_finalRoute, ipv4Address);
713 }
714 else
715 {
716 addRoute = dsr->AddRoute(toSource);
717 }
718 }
719 else
720 {
721 NS_LOG_DEBUG("Abnormal RouteRequest");
722 return 0;
723 }
724
725 if (addRoute)
726 {
727 /*
728 * Found a route to the dst, construct the source route option header
729 */
730 DsrOptionSRHeader sourceRoute;
731 NS_LOG_DEBUG("The route length " << m_finalRoute.size());
732 sourceRoute.SetNodesAddress(m_finalRoute);
733
734 /// TODO !!!!!!!!!!!!!!
735 /// Think about this part, we just added the route,
736 /// probability no need to increase stability now?????
737 // if (dsr->IsLinkCache ())
738 // {
739 // dsr->UseExtends (m_finalRoute);
740 // }
741 sourceRoute.SetSegmentsLeft(m_finalRoute.size() - 2);
742 // The salvage value here is 0
743 sourceRoute.SetSalvage(0);
744 Ipv4Address nextHop =
745 SearchNextHop(ipv4Address, m_finalRoute); // Get the next hop address
746 NS_LOG_DEBUG("The nextHop address " << nextHop);
747
748 if (nextHop == "0.0.0.0")
749 {
750 dsr->PacketNewRoute(dsrP, ipv4Address, dst, protocol);
751 return 0;
752 }
753 SetRoute(nextHop, ipv4Address);
754 /*
755 * Send the data packet from the send buffer
756 */
757 dsr->SendPacketFromBuffer(sourceRoute, nextHop, protocol);
758 // Cancel the route request timer for destination after sending the data packet
759 dsr->CancelRreqTimer(dst, true);
760 }
761 else
762 {
763 NS_LOG_DEBUG("The route is failed to add in cache");
764 return 0;
765 }
766 }
767 else
768 {
769 NS_LOG_DEBUG("Unable to reverse route");
770 return 0;
771 }
772 isPromisc = false;
773 return rreq.GetSerializedSize();
774 }
775
776 /*
777 * (ii) or it has an active route to the destination, send reply based on request header and
778 * route cache, need to delay based on a random value from d = H * (h - 1 + r), which can
779 * avoid possible route reply storm. Also, verify if two vectors do not contain duplicates
780 * (part of the route to the destination from route cache and route collected so far). If
781 * so, do not use the route found and forward the route request.
782 */
783 else if (isRouteInCache && !areThereDuplicates)
784 {
785 m_finalRoute.clear(); // Clear the final route vector
786 /**
787 * push back the intermediate node address from the source to this node
788 */
789 for (auto i = saveRoute.begin(); i != saveRoute.end(); ++i)
790 {
791 m_finalRoute.push_back(*i);
792 }
793 /**
794 * push back the route vector we found in our route cache to destination, including this
795 * node's address
796 */
797 for (auto j = ip.begin(); j != ip.end(); ++j)
798 {
799 m_finalRoute.push_back(*j);
800 }
801 /*
802 * Create the route entry to the rreq originator and save it to route cache, also need
803 * to reverse the route
804 */
805 bool addRoute = false;
806 std::vector<Ipv4Address> reverseRoute(m_finalRoute);
807
808 if (ReverseRoutes(reverseRoute))
809 {
810 saveRoute.push_back(ipv4Address);
811 ReverseRoutes(saveRoute);
812 Ipv4Address dst = saveRoute.back();
813 NS_LOG_DEBUG("This is the route save in route cache");
814 PrintVector(saveRoute);
815
816 DsrRouteCacheEntry toSource(/*ip=*/saveRoute,
817 /*dst=*/dst,
818 /*exp=*/ActiveRouteTimeout);
819 NS_ASSERT(saveRoute.front() == ipv4Address);
820 // Add the route entry in the route cache
821 if (dsr->IsLinkCache())
822 {
823 addRoute = dsr->AddRoute_Link(saveRoute, ipv4Address);
824 }
825 else
826 {
827 addRoute = dsr->AddRoute(toSource);
828 }
829
830 if (addRoute)
831 {
832 NS_LOG_LOGIC("We have added the route and search send buffer for packet with "
833 "destination "
834 << dst);
835 /*
836 * Found a route the dst, construct the source route option header
837 */
838 DsrOptionSRHeader sourceRoute;
839 PrintVector(saveRoute);
840
841 sourceRoute.SetNodesAddress(saveRoute);
842 // if (dsr->IsLinkCache ())
843 // {
844 // dsr->UseExtends (saveRoute);
845 // }
846 sourceRoute.SetSegmentsLeft(saveRoute.size() - 2);
847 uint8_t salvage = 0;
848 sourceRoute.SetSalvage(salvage);
849 Ipv4Address nextHop =
850 SearchNextHop(ipv4Address, saveRoute); // Get the next hop address
851 NS_LOG_DEBUG("The nextHop address " << nextHop);
852
853 if (nextHop == "0.0.0.0")
854 {
855 dsr->PacketNewRoute(dsrP, ipv4Address, dst, protocol);
856 return 0;
857 }
858 SetRoute(nextHop, ipv4Address);
859 /*
860 * Schedule the packet retry
861 */
862 dsr->SendPacketFromBuffer(sourceRoute, nextHop, protocol);
863 // Cancel the route request timer for destination
864 dsr->CancelRreqTimer(dst, true);
865 }
866 else
867 {
868 NS_LOG_DEBUG("The route is failed to add in cache");
869 return 0;
870 }
871 }
872 else
873 {
874 NS_LOG_DEBUG("Unable to reverse the route");
875 return 0;
876 }
877
878 /*
879 * Need to first pin down the next hop address before removing duplicates
880 */
881 Ipv4Address nextHop = ReverseSearchNextHop(ipv4Address, m_finalRoute);
882 /*
883 * First remove the duplicate ip address to automatically shorten the route, and then
884 * reversely search the next hop address
885 */
886 // Set the route
887 SetRoute(nextHop, ipv4Address);
888
889 uint16_t hops = m_finalRoute.size();
891 rrep.SetNodesAddress(m_finalRoute); // Set the node addresses in the route reply header
892 // Get the real source of the reply
893 Ipv4Address realSource = m_finalRoute.back();
895 NS_LOG_DEBUG("This is the full route from " << realSource << " to "
896 << m_finalRoute.front());
897 /*
898 * This part add dsr header to the packet and send route reply packet
899 */
900 DsrRoutingHeader dsrRoutingHeader;
901 dsrRoutingHeader.SetNextHeader(protocol);
902 dsrRoutingHeader.SetMessageType(1);
903 dsrRoutingHeader.SetSourceId(GetIDfromIP(realSource));
904 dsrRoutingHeader.SetDestId(255);
905
906 uint8_t length =
907 rrep.GetLength(); // Get the length of the rrep header excluding the type header
908 dsrRoutingHeader.SetPayloadLength(length + 2);
909 dsrRoutingHeader.AddDsrOption(rrep);
910 Ptr<Packet> newPacket = Create<Packet>();
911 newPacket->AddHeader(dsrRoutingHeader);
912 dsr->ScheduleCachedReply(newPacket, ipv4Address, nextHop, m_ipv4Route, hops);
913 isPromisc = false;
914 return rreq.GetSerializedSize();
915 }
916 /*
917 * (iii) no route in any type has been found
918 */
919 else
920 {
921 mainVector.push_back(ipv4Address);
922 NS_ASSERT(mainVector.front() == source);
923 NS_LOG_DEBUG("Print out the main vector");
924 PrintVector(mainVector);
925 rreq.SetNodesAddress(mainVector);
926
927 Ptr<Packet> errP = p->Copy();
928 if (errP->GetSize())
929 {
930 NS_LOG_DEBUG("Error header included");
932 p->RemoveHeader(rerr);
933 Ipv4Address errorSrc = rerr.GetErrorSrc();
934 Ipv4Address unreachNode = rerr.GetUnreachNode();
935 Ipv4Address errorDst = rerr.GetErrorDst();
936
937 if ((errorSrc == srcAddress) && (unreachNode == ipv4Address))
938 {
939 NS_LOG_DEBUG("The error link back to work again");
940 uint16_t length = rreq.GetLength();
941 NS_LOG_DEBUG("The RREQ header length " << length);
942 dsrRoutingHeader.AddDsrOption(rreq);
943 dsrRoutingHeader.SetPayloadLength(length + 2);
944 }
945 else
946 {
947 dsr->DeleteAllRoutesIncludeLink(errorSrc, unreachNode, ipv4Address);
948
950 newUnreach.SetErrorType(1);
951 newUnreach.SetErrorSrc(errorSrc);
952 newUnreach.SetUnreachNode(unreachNode);
953 newUnreach.SetErrorDst(errorDst);
954 newUnreach.SetSalvage(rerr.GetSalvage()); // Set the value about whether to
955 // salvage a packet or not
956 uint16_t length = rreq.GetLength() + newUnreach.GetLength();
957 NS_LOG_DEBUG("The RREQ and newUnreach header length " << length);
958 dsrRoutingHeader.SetPayloadLength(length + 4);
959 dsrRoutingHeader.AddDsrOption(rreq);
960 dsrRoutingHeader.AddDsrOption(newUnreach);
961 }
962 }
963 else
964 {
965 uint16_t length = rreq.GetLength();
966 NS_LOG_DEBUG("The RREQ header length " << length);
967 dsrRoutingHeader.AddDsrOption(rreq);
968 dsrRoutingHeader.SetPayloadLength(length + 2);
969 }
970 // Get the TTL value
971 uint8_t ttl = ipv4Header.GetTtl();
972 /*
973 * Decrease the TTL value in the packet tag by one, this tag will go to ip layer 3 send
974 * function and drop packet when TTL value equals to 0
975 */
976 NS_LOG_DEBUG("The ttl value here " << (uint32_t)ttl);
977 if (ttl)
978 {
979 Ptr<Packet> interP = Create<Packet>();
980 SocketIpTtlTag tag;
981 tag.SetTtl(ttl - 1);
982 interP->AddPacketTag(tag);
983 interP->AddHeader(dsrRoutingHeader);
984 dsr->ScheduleInterRequest(interP);
985 isPromisc = false;
986 }
987 return rreq.GetSerializedSize();
988 }
989 }
990 // unreachable: return rreq.GetSerializedSize ();
991}
992
994
995TypeId
997{
998 static TypeId tid = TypeId("ns3::dsr::DsrOptionRrep")
1000 .SetGroupName("Dsr")
1001 .AddConstructor<DsrOptionRrep>();
1002 return tid;
1003}
1004
1009
1014
1015uint8_t
1017{
1019
1020 return OPT_NUMBER;
1021}
1022
1023uint8_t
1025 Ptr<Packet> dsrP,
1026 Ipv4Address ipv4Address,
1027 Ipv4Address source,
1028 const Ipv4Header& ipv4Header,
1029 uint8_t protocol,
1030 bool& isPromisc,
1031 Ipv4Address promiscSource)
1032{
1033 NS_LOG_FUNCTION(this << packet << dsrP << ipv4Address << source << ipv4Header
1034 << (uint32_t)protocol << isPromisc);
1035
1036 Ptr<Packet> p = packet->Copy();
1037
1038 // Get the number of routers' address field
1039 uint8_t buf[2];
1040 p->CopyData(buf, sizeof(buf));
1041 uint8_t numberAddress = (buf[1] - 2) / 4;
1042
1044 rrep.SetNumberAddress(numberAddress); // Set the number of ip address in the header to reserver
1045 // space for deserialize header
1046 p->RemoveHeader(rrep);
1047
1048 Ptr<Node> node = GetNodeWithAddress(ipv4Address);
1049 Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting>();
1050
1051 NS_LOG_DEBUG("The next header value " << (uint32_t)protocol);
1052
1053 std::vector<Ipv4Address> nodeList = rrep.GetNodesAddress();
1054 /**
1055 * Get the destination address, which is the last element in the nodeList
1056 */
1057 Ipv4Address targetAddress = nodeList.front();
1058 // If the RREP option has reached to the destination
1059 if (targetAddress == ipv4Address)
1060 {
1061 RemoveDuplicates(nodeList); // This is for the route reply from intermediate node since we
1062 // didn't remove duplicate there
1063 if (nodeList.empty())
1064 {
1065 NS_LOG_DEBUG("The route we have contains 0 entries");
1066 return 0;
1067 }
1068 /**
1069 * Get the destination address for the data packet, which is the last element in the
1070 * nodeList
1071 */
1072 Ipv4Address dst = nodeList.back();
1073 /**
1074 * Add the newly found route to the route cache
1075 * The route looks like:
1076 * \\ "srcAddress" + "intermediate node address" + "targetAddress"
1077 */
1078 DsrRouteCacheEntry toDestination(/*ip=*/nodeList,
1079 /*dst=*/dst,
1080 /*exp=*/ActiveRouteTimeout);
1081 NS_ASSERT(nodeList.front() == ipv4Address);
1082 bool addRoute = false;
1083 if (dsr->IsLinkCache())
1084 {
1085 addRoute = dsr->AddRoute_Link(nodeList, ipv4Address);
1086 }
1087 else
1088 {
1089 addRoute = dsr->AddRoute(toDestination);
1090 }
1091
1092 if (addRoute)
1093 {
1095 "We have added the route and search send buffer for packet with destination "
1096 << dst);
1097 /**
1098 * Found a route the dst, construct the source route option header
1099 */
1100 DsrOptionSRHeader sourceRoute;
1101 NS_LOG_DEBUG("The route length " << nodeList.size());
1102 sourceRoute.SetNodesAddress(nodeList);
1103 sourceRoute.SetSegmentsLeft(nodeList.size() - 2);
1104 sourceRoute.SetSalvage(0);
1105 Ipv4Address nextHop = SearchNextHop(ipv4Address, nodeList); // Get the next hop address
1106 NS_LOG_DEBUG("The nextHop address " << nextHop);
1107 if (nextHop == "0.0.0.0")
1108 {
1109 dsr->PacketNewRoute(dsrP, ipv4Address, dst, protocol);
1110 return 0;
1111 }
1112 PrintVector(nodeList);
1113 SetRoute(nextHop, ipv4Address);
1114 // Cancel the route request timer for destination
1115 dsr->CancelRreqTimer(dst, true);
1116 /**
1117 * Schedule the packet retry
1118 */
1119 dsr->SendPacketFromBuffer(sourceRoute, nextHop, protocol);
1120 }
1121 else
1122 {
1123 NS_LOG_DEBUG("Failed to add the route");
1124 return 0;
1125 }
1126 }
1127 else
1128 {
1129 uint8_t length = rrep.GetLength() -
1130 2; // The get length - 2 is to get aligned for the malformed header check
1131 NS_LOG_DEBUG("The length of rrep option " << (uint32_t)length);
1132
1133 if (length % 2 != 0)
1134 {
1135 NS_LOG_LOGIC("Malformed header. Drop!");
1136 m_dropTrace(packet);
1137 return 0;
1138 }
1139 PrintVector(nodeList);
1140 /*
1141 * This node is only an intermediate node, but it needs to save the possible route to the
1142 * destination when cutting the route
1143 */
1144 std::vector<Ipv4Address> routeCopy = nodeList;
1145 std::vector<Ipv4Address> cutRoute = CutRoute(ipv4Address, nodeList);
1146 PrintVector(cutRoute);
1147 if (cutRoute.size() >= 2)
1148 {
1149 Ipv4Address dst = cutRoute.back();
1150 NS_LOG_DEBUG("The route destination after cut " << dst);
1151 DsrRouteCacheEntry toDestination(/*ip=*/cutRoute,
1152 /*dst=*/dst,
1153 /*exp=*/ActiveRouteTimeout);
1154 NS_ASSERT(cutRoute.front() == ipv4Address);
1155 bool addRoute = false;
1156 if (dsr->IsLinkCache())
1157 {
1158 addRoute = dsr->AddRoute_Link(nodeList, ipv4Address);
1159 }
1160 else
1161 {
1162 addRoute = dsr->AddRoute(toDestination);
1163 }
1164 if (addRoute)
1165 {
1166 dsr->CancelRreqTimer(dst, true);
1167 }
1168 else
1169 {
1170 NS_LOG_DEBUG("The route not added");
1171 }
1172 }
1173 else
1174 {
1175 NS_LOG_DEBUG("The route is corrupted");
1176 }
1177 /*
1178 * Reverse search the vector for next hop address
1179 */
1180 Ipv4Address nextHop = ReverseSearchNextHop(ipv4Address, routeCopy);
1181 NS_ASSERT(routeCopy.back() == source);
1182 PrintVector(routeCopy);
1183 NS_LOG_DEBUG("The nextHop address " << nextHop << " and the source in the route reply "
1184 << source);
1185 /*
1186 * Set the route entry we will use to send reply
1187 */
1188 SetRoute(nextHop, ipv4Address);
1189 /*
1190 * This part add dsr routing header to the packet and send reply
1191 */
1192 DsrRoutingHeader dsrRoutingHeader;
1193 dsrRoutingHeader.SetNextHeader(protocol);
1194
1195 length = rrep.GetLength(); // Get the length of the rrep header excluding the type header
1196 NS_LOG_DEBUG("The reply header length " << (uint32_t)length);
1197 dsrRoutingHeader.SetPayloadLength(length + 2);
1198 dsrRoutingHeader.SetMessageType(1);
1199 dsrRoutingHeader.SetSourceId(GetIDfromIP(source));
1200 dsrRoutingHeader.SetDestId(GetIDfromIP(targetAddress));
1201 dsrRoutingHeader.AddDsrOption(rrep);
1202 Ptr<Packet> newPacket = Create<Packet>();
1203 newPacket->AddHeader(dsrRoutingHeader);
1204 dsr->SendReply(newPacket, ipv4Address, nextHop, m_ipv4Route);
1205 isPromisc = false;
1206 }
1207 return rrep.GetSerializedSize();
1208}
1209
1211
1212TypeId
1214{
1215 static TypeId tid = TypeId("ns3::dsr::DsrOptionSR")
1217 .SetGroupName("Dsr")
1218 .AddConstructor<DsrOptionSR>();
1219 return tid;
1220}
1221
1226
1231
1232uint8_t
1234{
1236 return OPT_NUMBER;
1237}
1238
1239uint8_t
1241 Ptr<Packet> dsrP,
1242 Ipv4Address ipv4Address,
1243 Ipv4Address source,
1244 const Ipv4Header& ipv4Header,
1245 uint8_t protocol,
1246 bool& isPromisc,
1247 Ipv4Address promiscSource)
1248{
1249 NS_LOG_FUNCTION(this << packet << dsrP << ipv4Address << source << ipv4Address << ipv4Header
1250 << (uint32_t)protocol << isPromisc);
1251 Ptr<Packet> p = packet->Copy();
1252 // Get the number of routers' address field
1253 uint8_t buf[2];
1254 p->CopyData(buf, sizeof(buf));
1255 uint8_t numberAddress = (buf[1] - 2) / 4;
1256 DsrOptionSRHeader sourceRoute;
1257 sourceRoute.SetNumberAddress(numberAddress);
1258 p->RemoveHeader(sourceRoute);
1259
1260 // The route size saved in the source route
1261 std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress();
1262 uint8_t segsLeft = sourceRoute.GetSegmentsLeft();
1263 uint8_t salvage = sourceRoute.GetSalvage();
1264 /*
1265 * Get the node from IP address and get the DSR extension object
1266 */
1267 Ptr<Node> node = GetNodeWithAddress(ipv4Address);
1268 Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting>();
1269 /*
1270 * Get the source and destination address from ipv4 header
1271 */
1272 Ipv4Address srcAddress = ipv4Header.GetSource();
1273 Ipv4Address destAddress = ipv4Header.GetDestination();
1274
1275 // Get the node list destination
1276 Ipv4Address destination = nodeList.back();
1277 /*
1278 * If it's a promiscuous receive data packet,
1279 * 1. see if automatic route shortening possible or not
1280 * 2. see if it is a passive acknowledgment
1281 */
1282 if (isPromisc)
1283 {
1284 NS_LOG_LOGIC("We process promiscuous receipt data packet");
1285 if (ContainAddressAfter(ipv4Address, destAddress, nodeList))
1286 {
1287 NS_LOG_LOGIC("Send back the gratuitous reply");
1288 dsr->SendGratuitousReply(source, srcAddress, nodeList, protocol);
1289 }
1290
1291 uint16_t fragmentOffset = ipv4Header.GetFragmentOffset();
1292 uint16_t identification = ipv4Header.GetIdentification();
1293
1294 if (destAddress != destination)
1295 {
1296 NS_LOG_DEBUG("Process the promiscuously received packet");
1297 bool findPassive = false;
1298 int32_t nNodes = NodeList::GetNNodes();
1299 for (int32_t i = 0; i < nNodes; ++i)
1300 {
1301 NS_LOG_DEBUG("Working with node " << i);
1302
1303 Ptr<Node> node = NodeList::GetNode(i);
1304 Ptr<dsr::DsrRouting> dsrNode = node->GetObject<dsr::DsrRouting>();
1305 // The source and destination addresses here are the real source and destination for
1306 // the packet
1307 findPassive = dsrNode->PassiveEntryCheck(packet,
1308 source,
1309 destination,
1310 segsLeft,
1311 fragmentOffset,
1312 identification,
1313 false);
1314 if (findPassive)
1315 {
1316 break;
1317 }
1318 }
1319
1320 if (findPassive)
1321 {
1322 NS_LOG_DEBUG("We find one previously received passive entry");
1323 /*
1324 * Get the node from IP address and get the DSR extension object
1325 * the srcAddress would be the source address from ip header
1326 */
1327 PrintVector(nodeList);
1328
1329 NS_LOG_DEBUG("promisc source " << promiscSource);
1330 Ptr<Node> node = GetNodeWithAddress(promiscSource);
1331 Ptr<dsr::DsrRouting> dsrSrc = node->GetObject<dsr::DsrRouting>();
1332 dsrSrc->CancelPassiveTimer(packet, source, destination, segsLeft);
1333 }
1334 else
1335 {
1336 NS_LOG_DEBUG("Saved the entry for further use");
1337 dsr->PassiveEntryCheck(packet,
1338 source,
1339 destination,
1340 segsLeft,
1341 fragmentOffset,
1342 identification,
1343 true);
1344 }
1345 }
1346 /// Safely terminate promiscuously received packet
1347 return 0;
1348 }
1349 else
1350 {
1351 /*
1352 * Get the number of address from the source route header
1353 */
1354 uint8_t length = sourceRoute.GetLength();
1355 uint8_t nextAddressIndex;
1356 Ipv4Address nextAddress;
1357
1358 // Get the option type value
1359 uint32_t size = p->GetSize();
1360 auto data = new uint8_t[size];
1361 p->CopyData(data, size);
1362 uint8_t optionType = 0;
1363 optionType = *(data);
1364 /// When the option type is 160, means there is ACK request header after the source route,
1365 /// we need to send back acknowledgment
1366 if (optionType == 160)
1367 {
1368 NS_LOG_LOGIC("Remove the ack request header and add ack header to the packet");
1369 // Here we remove the ack packet to the previous hop
1370 DsrOptionAckReqHeader ackReq;
1371 p->RemoveHeader(ackReq);
1372 uint16_t ackId = ackReq.GetAckId();
1373 /*
1374 * Send back acknowledgment packet to the earlier hop
1375 * If the node list is not empty, find the previous hop from the node list,
1376 * otherwise, use srcAddress
1377 */
1378 Ipv4Address ackAddress = srcAddress;
1379 if (!nodeList.empty())
1380 {
1381 if (segsLeft > numberAddress) // The segmentsLeft field should not be larger than
1382 // the total number of ip addresses
1383 {
1384 NS_LOG_LOGIC("Malformed header. Drop!");
1385 m_dropTrace(packet);
1386 return 0;
1387 }
1388 // -fstrict-overflow sensitive, see bug 1868
1389 if (numberAddress - segsLeft < 2) // The index is invalid
1390 {
1391 NS_LOG_LOGIC("Malformed header. Drop!");
1392 m_dropTrace(packet);
1393 return 0;
1394 }
1395 ackAddress = nodeList[numberAddress - segsLeft - 2];
1396 }
1397 m_ipv4Route = SetRoute(ackAddress, ipv4Address);
1398 NS_LOG_DEBUG("Send back ACK to the earlier hop " << ackAddress << " from us "
1399 << ipv4Address);
1400 dsr->SendAck(ackId, ackAddress, source, destination, protocol, m_ipv4Route);
1401 }
1402 /*
1403 * After send back ACK, check if the segments left value has turned to 0 or not, if yes,
1404 * update the route entry and return header length
1405 */
1406 if (segsLeft == 0)
1407 {
1408 NS_LOG_DEBUG("This is the final destination");
1409 isPromisc = false;
1410 return sourceRoute.GetSerializedSize();
1411 }
1412
1413 if (length % 2 != 0)
1414 {
1415 NS_LOG_LOGIC("Malformed header. Drop!");
1416 m_dropTrace(packet);
1417 return 0;
1418 }
1419
1420 if (segsLeft > numberAddress) // The segmentsLeft field should not be larger than the total
1421 // number of ip addresses
1422 {
1423 NS_LOG_LOGIC("Malformed header. Drop!");
1424 m_dropTrace(packet);
1425 return 0;
1426 }
1427
1428 DsrOptionSRHeader newSourceRoute;
1429 newSourceRoute.SetSegmentsLeft(segsLeft - 1);
1430 newSourceRoute.SetSalvage(salvage);
1431 newSourceRoute.SetNodesAddress(nodeList);
1432 nextAddressIndex = numberAddress - segsLeft;
1433 nextAddress = newSourceRoute.GetNodeAddress(nextAddressIndex);
1434 NS_LOG_DEBUG("The next address of source route option "
1435 << nextAddress << " and the nextAddressIndex: " << (uint32_t)nextAddressIndex
1436 << " and the segments left : " << (uint32_t)segsLeft);
1437 /*
1438 * Get the target Address in the node list
1439 */
1440 Ipv4Address targetAddress = nodeList.back();
1441 Ipv4Address realSource = nodeList.front();
1442 /*
1443 * Search the vector for next hop address
1444 */
1445 Ipv4Address nextHop = SearchNextHop(ipv4Address, nodeList);
1446 PrintVector(nodeList);
1447
1448 if (nextHop == "0.0.0.0")
1449 {
1450 NS_LOG_DEBUG("Before new packet " << *dsrP);
1451 dsr->PacketNewRoute(dsrP, realSource, targetAddress, protocol);
1452 return 0;
1453 }
1454
1455 if (ipv4Address == nextHop)
1456 {
1457 NS_LOG_DEBUG("We have reached the destination");
1458 newSourceRoute.SetSegmentsLeft(0);
1459 return newSourceRoute.GetSerializedSize();
1460 }
1461 // Verify the multicast address, leave it here for now
1462 if (nextAddress.IsMulticast() || destAddress.IsMulticast())
1463 {
1464 m_dropTrace(packet);
1465 return 0;
1466 }
1467 // Set the route and forward the data packet
1468 SetRoute(nextAddress, ipv4Address);
1469 NS_LOG_DEBUG("dsr packet size " << dsrP->GetSize());
1470 dsr->ForwardPacket(dsrP,
1471 newSourceRoute,
1472 ipv4Header,
1473 realSource,
1474 nextAddress,
1475 targetAddress,
1476 protocol,
1477 m_ipv4Route);
1478 }
1479 return sourceRoute.GetSerializedSize();
1480}
1481
1483
1484TypeId
1486{
1487 static TypeId tid = TypeId("ns3::dsr::DsrOptionRerr")
1489 .SetGroupName("Dsr")
1490 .AddConstructor<DsrOptionRerr>();
1491 return tid;
1492}
1493
1498
1503
1504uint8_t
1510
1511uint8_t
1513 Ptr<Packet> dsrP,
1514 Ipv4Address ipv4Address,
1515 Ipv4Address source,
1516 const Ipv4Header& ipv4Header,
1517 uint8_t protocol,
1518 bool& isPromisc,
1519 Ipv4Address promiscSource)
1520{
1521 NS_LOG_FUNCTION(this << packet << dsrP << ipv4Address << source << ipv4Header
1522 << (uint32_t)protocol << isPromisc);
1523 Ptr<Packet> p = packet->Copy();
1524 uint32_t size = p->GetSize();
1525 auto data = new uint8_t[size];
1526 p->CopyData(data, size);
1527 uint8_t errorType = *(data + 2);
1528 /*
1529 * Get the node from Ip address and get the dsr extension object
1530 */
1531 Ptr<Node> node = GetNodeWithAddress(ipv4Address);
1532 Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting>();
1533 NS_LOG_DEBUG("The error type value here " << (uint32_t)errorType);
1534 if (errorType == 1) // unreachable ip address
1535 {
1536 /*
1537 * Remove the route error header from the packet, and get the error type
1538 */
1539 DsrOptionRerrUnreachHeader rerrUnreach;
1540 p->RemoveHeader(rerrUnreach);
1541 /*
1542 * Get the error destination address
1543 */
1544 Ipv4Address unreachAddress = rerrUnreach.GetUnreachNode();
1545 Ipv4Address errorSource = rerrUnreach.GetErrorSrc();
1546
1547 NS_LOG_DEBUG("The error source is " << rerrUnreach.GetErrorDst()
1548 << "and the unreachable node is " << unreachAddress);
1549 /*
1550 * Get the serialized size of the rerr header
1551 */
1552 uint32_t rerrSize = rerrUnreach.GetSerializedSize();
1553 /*
1554 * Delete all the routes including the unreachable node address from the route cache
1555 */
1556 Ptr<Node> node = GetNodeWithAddress(ipv4Address);
1557 dsr->DeleteAllRoutesIncludeLink(errorSource, unreachAddress, ipv4Address);
1558
1559 Ptr<Packet> newP = p->Copy();
1560 uint32_t serialized = DoSendError(newP, rerrUnreach, rerrSize, ipv4Address, protocol);
1561 return serialized;
1562 }
1563 else
1564 {
1565 /*
1566 * Two other type of error headers:
1567 * 1. flow state not supported type-specific information
1568 * 2. unsupported option with option number
1569 */
1570 /*
1571 * Remove the route error header from the packet, and get the error type
1572 */
1573 DsrOptionRerrUnsupportedHeader rerrUnsupported;
1574 p->RemoveHeader(rerrUnsupported);
1575
1576 /// @todo This is for the other two error options, not supporting for now
1577 // uint32_t rerrSize = rerrUnsupported.GetSerializedSize();
1578 // uint32_t serialized = DoSendError (p, rerrUnsupported, rerrSize, ipv4Address, protocol);
1579 uint32_t serialized = 0;
1580 return serialized;
1581 }
1582}
1583
1584uint8_t
1587 uint32_t rerrSize,
1588 Ipv4Address ipv4Address,
1589 uint8_t protocol)
1590{
1591 // Get the number of routers' address field
1592 uint8_t buf[2];
1593 p->CopyData(buf, sizeof(buf));
1594 uint8_t numberAddress = (buf[1] - 2) / 4;
1595
1596 // Here remove the source route header and schedule next hop error transmission
1597 NS_LOG_DEBUG("The number of addresses " << (uint32_t)numberAddress);
1598 DsrOptionSRHeader sourceRoute;
1599 sourceRoute.SetNumberAddress(numberAddress);
1600 p->RemoveHeader(sourceRoute);
1601 NS_ASSERT(p->GetSize() == 0);
1602 /*
1603 * Get the node from ip address and the dsr extension object
1604 */
1605 Ptr<Node> node = GetNodeWithAddress(ipv4Address);
1606 Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting>();
1607 /*
1608 * Get the segments left field and the next address
1609 */
1610 uint8_t segmentsLeft = sourceRoute.GetSegmentsLeft();
1611 uint8_t length = sourceRoute.GetLength();
1612 uint8_t nextAddressIndex;
1613 Ipv4Address nextAddress;
1614 /*
1615 * Get the route size and the error target address
1616 */
1617 std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress();
1618 Ipv4Address targetAddress = nodeList.back();
1619 /*
1620 * The total serialized size for both the rerr and source route headers
1621 */
1622 uint32_t serializedSize = rerrSize + sourceRoute.GetSerializedSize();
1623
1624 if (length % 2 != 0)
1625 {
1626 NS_LOG_LOGIC("Malformed header. Drop!");
1627 m_dropTrace(p);
1628 return 0;
1629 }
1630
1631 if (segmentsLeft > numberAddress)
1632 {
1633 NS_LOG_LOGIC("Malformed header. Drop!");
1634 m_dropTrace(p);
1635 return 0;
1636 }
1637 /*
1638 * When the error packet has reached to the destination
1639 */
1640 if (segmentsLeft == 0 && targetAddress == ipv4Address)
1641 {
1642 NS_LOG_INFO("This is the destination of the error, send error request");
1643 dsr->SendErrorRequest(rerr, protocol);
1644 return serializedSize;
1645 }
1646
1647 // Get the next Router Address
1648 DsrOptionSRHeader newSourceRoute;
1649 newSourceRoute.SetSegmentsLeft(segmentsLeft - 1);
1650 nextAddressIndex = numberAddress - segmentsLeft;
1651 nextAddress = sourceRoute.GetNodeAddress(nextAddressIndex);
1652 newSourceRoute.SetSalvage(sourceRoute.GetSalvage());
1653 newSourceRoute.SetNodesAddress(nodeList);
1654 nextAddress = newSourceRoute.GetNodeAddress(nextAddressIndex);
1655
1656 /// to test if the next address is multicast or not
1657 if (nextAddress.IsMulticast() || targetAddress.IsMulticast())
1658 {
1659 m_dropTrace(p);
1660 return serializedSize;
1661 }
1662
1663 // Set the route entry
1664 SetRoute(nextAddress, ipv4Address);
1665 dsr->ForwardErrPacket(rerr, newSourceRoute, nextAddress, protocol, m_ipv4Route);
1666 return serializedSize;
1667}
1668
1670
1671TypeId
1673{
1674 static TypeId tid = TypeId("ns3::dsr::DsrOptionAckReq")
1676 .SetGroupName("Dsr")
1677 .AddConstructor<DsrOptionAckReq>();
1678 return tid;
1679}
1680
1685
1690
1691uint8_t
1697
1698uint8_t
1700 Ptr<Packet> dsrP,
1701 Ipv4Address ipv4Address,
1702 Ipv4Address source,
1703 const Ipv4Header& ipv4Header,
1704 uint8_t protocol,
1705 bool& isPromisc,
1706 Ipv4Address promiscSource)
1707{
1708 NS_LOG_FUNCTION(this << packet << dsrP << ipv4Address << source << ipv4Header
1709 << (uint32_t)protocol << isPromisc);
1710 /*
1711 * Current implementation of the ack request header processing is coded in source route header
1712 * processing
1713 */
1714 /*
1715 * Remove the ack request header
1716 */
1717 Ptr<Packet> p = packet->Copy();
1718 DsrOptionAckReqHeader ackReq;
1719 p->RemoveHeader(ackReq);
1720 /*
1721 * Get the node with ip address and get the dsr extension and route cache objects
1722 */
1723 Ptr<Node> node = GetNodeWithAddress(ipv4Address);
1724 Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting>();
1725
1726 NS_LOG_DEBUG("The next header value " << (uint32_t)protocol);
1727
1728 return ackReq.GetSerializedSize();
1729}
1730
1732
1733TypeId
1735{
1736 static TypeId tid = TypeId("ns3::dsr::DsrOptionAck")
1738 .SetGroupName("Dsr")
1739 .AddConstructor<DsrOptionAck>();
1740 return tid;
1741}
1742
1747
1752
1753uint8_t
1755{
1757 return OPT_NUMBER;
1758}
1759
1760uint8_t
1762 Ptr<Packet> dsrP,
1763 Ipv4Address ipv4Address,
1764 Ipv4Address source,
1765 const Ipv4Header& ipv4Header,
1766 uint8_t protocol,
1767 bool& isPromisc,
1768 Ipv4Address promiscSource)
1769{
1770 NS_LOG_FUNCTION(this << packet << dsrP << ipv4Address << source << ipv4Header
1771 << (uint32_t)protocol << isPromisc);
1772 /*
1773 * Remove the ACK header
1774 */
1775 Ptr<Packet> p = packet->Copy();
1777 p->RemoveHeader(ack);
1778 /*
1779 * Get the ACK source and destination address
1780 */
1781 Ipv4Address realSrc = ack.GetRealSrc();
1782 Ipv4Address realDst = ack.GetRealDst();
1783 uint16_t ackId = ack.GetAckId();
1784 /*
1785 * Get the node with ip address and get the dsr extension and route cache objects
1786 */
1787 Ptr<Node> node = GetNodeWithAddress(ipv4Address);
1788 Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting>();
1789 dsr->UpdateRouteEntry(realDst);
1790 /*
1791 * Cancel the packet retransmit timer when receiving the ack packet
1792 */
1793 dsr->CallCancelPacketTimer(ackId, ipv4Header, realSrc, realDst);
1794 return ack.GetSerializedSize();
1795}
1796
1797} // namespace dsr
1798} // 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:49
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.
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.
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.
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.
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.
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.
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.
Introspection did not find any typical Config paths.
Definition dsr-options.h:65
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:97
#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
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition uinteger.h:35
#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.
uint8_t data[writeSize]