A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
dsr-options.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2011 Yufei Cheng
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Yufei Cheng <yfcheng@ittc.ku.edu>
19  *
20  * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
21  * ResiliNets Research Group http://wiki.ittc.ku.edu/resilinets
22  * Information and Telecommunication Technology Center (ITTC)
23  * and Department of Electrical Engineering and Computer Science
24  * The University of Kansas Lawrence, KS USA.
25  *
26  * Work supported in part by NSF FIND (Future Internet Design) Program
27  * under grant CNS-0626918 (Postmodern Internet Architecture),
28  * NSF grant CNS-1050226 (Multilayer Network Resilience Analysis and Experimentation on GENI),
29  * US Department of Defense (DoD), and ITTC at The University of Kansas.
30  */
31 
32 #define NS_LOG_APPEND_CONTEXT \
33  if (GetObject<Node> ()) { std::clog << "[node " << GetObject<Node> ()->GetId () << "] "; }
34 
35 #include <list>
36 #include <ctime>
37 #include <map>
38 
39 #include "ns3/ptr.h"
40 #include "ns3/log.h"
41 #include "ns3/assert.h"
42 #include "ns3/fatal-error.h"
43 #include "ns3/node.h"
44 #include "ns3/uinteger.h"
45 #include "ns3/trace-source-accessor.h"
46 #include "ns3/udp-header.h"
47 #include "ns3/pointer.h"
48 #include "ns3/node-list.h"
49 #include "ns3/uinteger.h"
50 #include "ns3/object-vector.h"
51 #include "ns3/ipv4-l3-protocol.h"
52 #include "ns3/ipv4-interface.h"
53 #include "ns3/ipv4-header.h"
54 #include "ns3/ipv4-address.h"
55 #include "ns3/ipv4-route.h"
56 #include "ns3/icmpv4-l4-protocol.h"
57 #include "ns3/ip-l4-protocol.h"
58 
59 #include "dsr-option-header.h"
60 #include "dsr-options.h"
61 #include "dsr-rcache.h"
62 
63 NS_LOG_COMPONENT_DEFINE ("DsrOptions");
64 
65 namespace ns3 {
66 namespace dsr {
67 
68 NS_OBJECT_ENSURE_REGISTERED (DsrOptions);
69 
71 {
72  static TypeId tid = TypeId ("ns3::dsr::DsrOptions")
73  .SetParent<Object> ()
74  .AddAttribute ("OptionNumber", "The Dsr option number.",
75  UintegerValue (0),
76  MakeUintegerAccessor (&DsrOptions::GetOptionNumber),
77  MakeUintegerChecker<uint8_t> ())
78  .AddTraceSource ("Rx", "Receive DSR packet.",
80  ;
81  return tid;
82 }
83 
85 {
87 }
88 
90 {
92 }
93 
95 {
96  NS_LOG_FUNCTION (this << node);
97  m_node = node;
98 }
99 
101 {
103  return m_node;
104 }
105 
106 bool DsrOptions::ContainAddressAfter (Ipv4Address ipv4Address, Ipv4Address destAddress, std::vector<Ipv4Address> &nodeList)
107 {
108  NS_LOG_FUNCTION (this << ipv4Address << destAddress);
109  std::vector<Ipv4Address>::iterator it = find (nodeList.begin (), nodeList.end (), destAddress);
110 
111  for (std::vector<Ipv4Address>::iterator i = it; i != nodeList.end (); ++i)
112  {
113  if ((ipv4Address == (*i)) && ((*i) != nodeList.back ()))
114  {
115  return true;
116  }
117  }
118  return false;
119 }
120 
121 std::vector<Ipv4Address>
122 DsrOptions::CutRoute (Ipv4Address ipv4Address, std::vector<Ipv4Address> &nodeList)
123 {
124  NS_LOG_FUNCTION (this << ipv4Address);
125  std::vector<Ipv4Address>::iterator it = find (nodeList.begin (), nodeList.end (), ipv4Address);
126  std::vector<Ipv4Address> cutRoute;
127  for (std::vector<Ipv4Address>::iterator i = it; i != nodeList.end (); ++i)
128  {
129  cutRoute.push_back (*i);
130  }
131  return cutRoute;
132 }
133 
135 {
136  NS_LOG_FUNCTION (this << nextHop << srcAddress);
137  m_ipv4Route = Create<Ipv4Route> ();
138  m_ipv4Route->SetDestination (nextHop);
139  m_ipv4Route->SetGateway (nextHop);
140  m_ipv4Route->SetSource (srcAddress);
141  return m_ipv4Route;
142 }
143 
144 bool DsrOptions::ReverseRoutes (std::vector<Ipv4Address> & vec)
145 {
146  NS_LOG_FUNCTION (this);
147  std::vector<Ipv4Address> vec2 (vec);
148  vec.clear (); // To ensure vec is empty before start
149  for (std::vector<Ipv4Address>::reverse_iterator ri = vec2.rbegin (); ri
150  != vec2.rend (); ++ri)
151  {
152  vec.push_back (*ri);
153  }
154 
155  if ((vec.size () == vec2.size ()) && (vec.front () == vec2.back ()))
156  {
157  return true;
158  }
159  return false;
160 }
161 
162 Ipv4Address DsrOptions::SearchNextHop (Ipv4Address ipv4Address, std::vector<Ipv4Address>& vec)
163 {
164  NS_LOG_FUNCTION (this << ipv4Address);
165  Ipv4Address nextHop;
166  NS_LOG_DEBUG ("the vector size " << vec.size ());
167  if (vec.size () == 2)
168  {
169  NS_LOG_DEBUG ("The two nodes are neighbors");
170  nextHop = vec[1];
171  return nextHop;
172  }
173  else
174  {
175  if (ipv4Address == vec.back ())
176  {
177  NS_LOG_DEBUG ("We have reached to the final destination " << ipv4Address << " " << vec.back ());
178  return ipv4Address;
179  }
180  for (std::vector<Ipv4Address>::const_iterator i = vec.begin (); i != vec.end (); ++i)
181  {
182  if (ipv4Address == (*i))
183  {
184  nextHop = *(++i);
185  return nextHop;
186  }
187  }
188  }
189  NS_LOG_DEBUG ("next hop address not found, route corrupted");
190  Ipv4Address none = "0.0.0.0";
191  return none;
192 }
193 
194 Ipv4Address DsrOptions::ReverseSearchNextHop (Ipv4Address ipv4Address, std::vector<Ipv4Address>& vec)
195 {
196  NS_LOG_FUNCTION (this << ipv4Address);
197  Ipv4Address nextHop;
198  if (vec.size () == 2)
199  {
200  NS_LOG_DEBUG ("The two nodes are neighbors");
201  nextHop = vec[0];
202  return nextHop;
203  }
204  else
205  {
206  for (std::vector<Ipv4Address>::reverse_iterator ri = vec.rbegin (); ri != vec.rend (); ++ri)
207  {
208  if (ipv4Address == (*ri))
209  {
210  nextHop = *(++ri);
211  return nextHop;
212  }
213  }
214  }
215  NS_LOG_DEBUG ("next hop address not found, route corrupted");
216  Ipv4Address none = "0.0.0.0";
217  return none;
218 }
219 
220 Ipv4Address DsrOptions::ReverseSearchNextTwoHop (Ipv4Address ipv4Address, std::vector<Ipv4Address>& vec)
221 {
222  NS_LOG_FUNCTION (this << ipv4Address);
223  Ipv4Address nextTwoHop;
224  NS_LOG_DEBUG ("The vector size " << vec.size ());
225  NS_ASSERT (vec.size () > 2);
226  for (std::vector<Ipv4Address>::reverse_iterator ri = vec.rbegin (); ri != vec.rend (); ++ri)
227  {
228  if (ipv4Address == (*ri))
229  {
230  nextTwoHop = *(ri + 2);
231  return nextTwoHop;
232  }
233  }
234  NS_FATAL_ERROR ("next hop address not found, route corrupted");
235  Ipv4Address none = "0.0.0.0";
236  return none;
237 }
238 
239 void DsrOptions::PrintVector (std::vector<Ipv4Address>& vec)
240 {
241  NS_LOG_FUNCTION (this);
242  /*
243  * Check elements in a route vector
244  */
245  if (!vec.size ())
246  {
247  NS_LOG_DEBUG ("The vector is empty");
248  }
249  else
250  {
251  NS_LOG_DEBUG ("Print all the elements in a vector");
252  for (std::vector<Ipv4Address>::const_iterator i = vec.begin (); i != vec.end (); ++i)
253  {
254  NS_LOG_DEBUG ("The ip address " << *i);
255  }
256  }
257 }
258 
259 bool DsrOptions::IfDuplicates (std::vector<Ipv4Address>& vec, std::vector<Ipv4Address>& vec2)
260 {
261  NS_LOG_FUNCTION (this);
262  for (std::vector<Ipv4Address>::const_iterator i = vec.begin (); i != vec.end (); ++i)
263  {
264  for (std::vector<Ipv4Address>::const_iterator j = vec2.begin (); j != vec2.end (); ++j)
265  {
266  if ((*i) == (*j))
267  {
268  return true;
269  }
270  else
271  {
272  continue;
273  }
274  }
275  }
276  return false;
277 }
278 
279 bool DsrOptions::CheckDuplicates (Ipv4Address ipv4Address, std::vector<Ipv4Address>& vec)
280 {
281  NS_LOG_FUNCTION (this << ipv4Address);
282  for (std::vector<Ipv4Address>::const_iterator i = vec.begin (); i != vec.end (); ++i)
283  {
284  if ((*i) == ipv4Address)
285  {
286  return true;
287  }
288  else
289  {
290  continue;
291  }
292  }
293  return false;
294 }
295 
296 void DsrOptions::RemoveDuplicates (std::vector<Ipv4Address>& vec)
297 {
298  NS_LOG_FUNCTION (this);
299  //Remove duplicate ip address from the route if any, should not happen with normal behavior 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 (std::vector<Ipv4Address>::const_iterator i = vec2.begin (); i != vec2.end (); ++i)
304  {
305  if (vec.empty ())
306  {
307  vec.push_back (*i);
308  continue;
309  }
310  else
311  {
312  for (std::vector<Ipv4Address>::iterator j = vec.begin (); j != vec.end (); ++j)
313  {
314  if ((*i) == (*j))
315  {
316  if ((j + 1) != vec.end ())
317  {
318  vec.erase (j + 1, vec.end ()); // Automatic shorten the route
319  break;
320  }
321  else
322  {
323  break;
324  }
325  }
326  else if (j == (vec.end () - 1))
327  {
328  vec.push_back (*i);
329  break;
330  }
331  else
332  {
333  continue;
334  }
335  }
336  }
337  }
338 }
339 
340 uint32_t
342 {
343  NS_LOG_FUNCTION (this << address);
344  int32_t nNodes = NodeList::GetNNodes ();
345  for (int32_t i = 0; i < nNodes; ++i)
346  {
347  Ptr<Node> node = NodeList::GetNode (i);
348  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
349  if (ipv4->GetAddress (1, 0).GetLocal () == address)
350  {
351  return i;
352  }
353  }
354  return 255;
355 }
356 
358 {
359  NS_LOG_FUNCTION (this << ipv4Address);
360  int32_t nNodes = NodeList::GetNNodes ();
361  for (int32_t i = 0; i < nNodes; ++i)
362  {
363  Ptr<Node> node = NodeList::GetNode (i);
364  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
365  int32_t ifIndex = ipv4->GetInterfaceForAddress (ipv4Address);
366  if (ifIndex != -1)
367  {
368  return node;
369  }
370  }
371  return 0;
372 }
373 
375 
377 {
378  static TypeId tid = TypeId ("ns3::dsr::DsrOptionPad1")
379  .SetParent<DsrOptions> ()
380  .AddConstructor<DsrOptionPad1> ()
381  ;
382  return tid;
383 }
384 
386 {
388 }
389 
391 {
393 }
394 
396 {
398 
399  return OPT_NUMBER;
400 }
401 
402 uint8_t DsrOptionPad1::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc, Ipv4Address promiscSource)
403 {
404  NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Header << (uint32_t)protocol << isPromisc);
405  Ptr<Packet> p = packet->Copy ();
406  DsrOptionPad1Header pad1Header;
407  p->RemoveHeader (pad1Header);
408 
409  isPromisc = false;
410 
411  return pad1Header.GetSerializedSize ();
412 }
413 
415 
417 {
418  static TypeId tid = TypeId ("ns3::dsr::DsrOptionPadn")
419  .SetParent<DsrOptions> ()
420  .AddConstructor<DsrOptionPadn> ()
421  ;
422  return tid;
423 }
424 
426 {
428 }
429 
431 {
433 }
434 
436 {
438  return OPT_NUMBER;
439 }
440 
441 uint8_t DsrOptionPadn::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc, Ipv4Address promiscSource)
442 {
443  NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Header << (uint32_t)protocol << isPromisc);
444 
445  Ptr<Packet> p = packet->Copy ();
446  DsrOptionPadnHeader padnHeader;
447  p->RemoveHeader (padnHeader);
448 
449  isPromisc = false;
450 
451  return padnHeader.GetSerializedSize ();
452 }
453 
455 
457 {
458  static TypeId tid = TypeId ("ns3::dsr::DsrOptionRreq")
459  .SetParent<DsrOptions> ()
460  .AddConstructor<DsrOptionRreq> ()
461  ;
462  return tid;
463 }
464 
466 {
467  return GetTypeId ();
468 }
469 
471 {
473 }
474 
476 {
478 }
479 
481 {
483 
484  return OPT_NUMBER;
485 }
486 
487 uint8_t DsrOptionRreq::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc, Ipv4Address promiscSource)
488 {
489  NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Header << (uint32_t)protocol << isPromisc);
490  // Fields from IP header
491  Ipv4Address srcAddress = ipv4Header.GetSource ();
492  /*
493  * \ when the ip source address is equal to the address of our own, this is request packet originated
494  * \ by the node itself, discard it
495  */
496  if (srcAddress == ipv4Address)
497  {
498  NS_LOG_DEBUG ("Discard the packet");
499  m_dropTrace (packet); // call the drop trace to show in the tracing
500  return 0;
501  }
502  /*
503  * Get the node associated with the ipv4 address and get several objects from the node and leave for further use
504  */
505  Ptr<Node> node = GetNodeWithAddress (ipv4Address);
507 
508  Ptr<Packet> p = packet->Copy (); // Note: The packet here doesn't contain the fixed size dsr header
509  /*
510  * \brief Get the number of routers' address field before removing the header
511  * \peek the packet and get the value
512  */
513  uint8_t buf[2];
514  p->CopyData (buf, sizeof(buf));
515  uint8_t numberAddress = (buf[1] - 6) / 4;
516  NS_LOG_DEBUG ("The number of Ip addresses " << (uint32_t)numberAddress);
517  if (numberAddress >= 255)
518  {
519  NS_LOG_DEBUG ("Discard the packet, malformed header since two many ip addresses in route");
520  m_dropTrace (packet); // call the drop trace to show in the tracing
521  return 0;
522  }
523 
524  /*
525  * Create the dsr rreq header
526  */
527  DsrOptionRreqHeader rreq;
528  /*
529  * Set the number of addresses with the value from peek data and remove the rreq header
530  */
531  rreq.SetNumberAddress (numberAddress);
532  // Remove the route request header
533  p->RemoveHeader (rreq);
534  // Verify the option length
535  uint8_t length = rreq.GetLength ();
536  if (length % 2 != 0)
537  {
538  NS_LOG_LOGIC ("Malformed header. Drop!");
539  m_dropTrace (packet); // call drop trace
540  return 0;
541  }
542  // Check the rreq id for verifying the request id
543  uint16_t requestId = rreq.GetId ();
544  // The target address is where we want to send the data packets
545  Ipv4Address targetAddress = rreq.GetTarget ();
546  // Get the node list and source address from the route request header
547  std::vector<Ipv4Address> mainVector = rreq.GetNodesAddresses ();
548  std::vector<Ipv4Address> nodeList (mainVector);
549  // Get the real source address of this request, it will be used when checking if we have received the save
550  // route request before or not
551  Ipv4Address sourceAddress = nodeList.front ();
552  PrintVector (nodeList);
553  /*
554  * Construct the dsr routing header for later use
555  */
556  DsrRoutingHeader dsrRoutingHeader;
557  dsrRoutingHeader.SetNextHeader (protocol);
558  dsrRoutingHeader.SetMessageType (1);
559  dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
560  dsrRoutingHeader.SetDestId (255);
561 
562  // check whether we have received this request or not, if not, it will save the request in the table for
563  // later use, if not found, return false, and push the newly received source request entry in the cache
564 
565  // Get the TTL value, this is used to test if the packet will be forwarded or not
566  uint8_t ttl = ipv4Header.GetTtl ();
567  bool dupRequest = false; // initialize the duplicate request check value
568  if (ttl)
569  {
570  // if the ttl value is not 0, then this request will be forwarded, then we need to
571  // save it in the source entry
572  dupRequest = dsr->FindSourceEntry (sourceAddress, targetAddress, requestId);
573  }
574  /*
575  * Before processing the route request, we need to check two things
576  * 1. if this is the exact same request we have just received, ignore it
577  * 2. if our address is already in the path list, ignore it
578  * 3. otherwise process further
579  */
580 
581  if (dupRequest)
582  {
583  // We have received this same route reqeust before, not forwarding it now
584  NS_LOG_LOGIC ("Duplicate request. Drop!");
585  m_dropTrace (packet); // call drop trace
586  return 0;
587  }
588 
589  else if (CheckDuplicates (ipv4Address, nodeList))
590  {
591  /*
592  * if the route contains the node address already, drop the request packet
593  */
594  m_dropTrace (packet); // call drop trace
595  NS_LOG_DEBUG ("Our node address is already seen in the route, drop the request");
596  return 0;
597  }
598  else
599  {
600  // A node ignores all RREQs received from any node in its blacklist
601  RouteCacheEntry toPrev;
602  /*
603  * When the reverse route is created or updated, the following actions on the route are also carried out:
604  * 3. the next hop in the routing table becomes the node from which the RREQ was received
605  * 4. the hop count is copied from the Hop Count in the RREQ message;
606  */
607 
608  // A node generates a RREP if either:
609  // (i) it is itself the destination,
610  /*
611  * The target address equal to our own ip address
612  */
613  NS_LOG_DEBUG ("The target address over here " << targetAddress << " and the ip address " << ipv4Address << " and the source address " << mainVector[0]);
614  if (targetAddress == ipv4Address)
615  {
616  Ipv4Address nextHop; // Declare the next hop address to use
617  if (nodeList.size () == 1)
618  {
619  NS_LOG_DEBUG ("These two nodes are neighbors");
620  m_finalRoute.clear ();
621  m_finalRoute.push_back (srcAddress); // push back the request originator's address
622  m_finalRoute.push_back (ipv4Address); // push back our own address
623  nextHop = srcAddress;
624  }
625  else
626  {
627  std::vector<Ipv4Address> changeRoute (nodeList);
628  changeRoute.push_back (ipv4Address); // push back our own address
629  m_finalRoute.clear (); // get a clear route vector
630  for (std::vector<Ipv4Address>::iterator i = changeRoute.begin (); i != changeRoute.end (); ++i)
631  {
632  m_finalRoute.push_back (*i); // Get the full route from source to destination
633  }
635  nextHop = ReverseSearchNextHop (ipv4Address, m_finalRoute); // get the next hop
636  }
637 
638  DsrOptionRrepHeader rrep;
639  rrep.SetNodesAddress (m_finalRoute); // Set the node addresses in the route reply header
640  NS_LOG_DEBUG ("The nextHop address " << nextHop);
641  Ipv4Address replyDst = m_finalRoute.front ();
642  /*
643  * This part add dsr header to the packet and send route reply packet
644  */
645  DsrRoutingHeader dsrRoutingHeader;
646  dsrRoutingHeader.SetNextHeader (protocol);
647  dsrRoutingHeader.SetMessageType (1);
648  dsrRoutingHeader.SetSourceId (GetIDfromIP (ipv4Address));
649  dsrRoutingHeader.SetDestId (GetIDfromIP (replyDst));
650  // Set the route for route reply
651  SetRoute (nextHop, ipv4Address);
652 
653  uint8_t length = rrep.GetLength (); // Get the length of the rrep header excluding the type header
654  dsrRoutingHeader.SetPayloadLength (length + 2);
655  dsrRoutingHeader.AddDsrOption (rrep);
656  Ptr<Packet> newPacket = Create<Packet> ();
657  newPacket->AddHeader (dsrRoutingHeader);
658  dsr->ScheduleInitialReply (newPacket, ipv4Address, nextHop, m_ipv4Route);
659  /*
660  * Create the route entry to the rreq originator and save it to route cache, also need to reverse the route
661  */
664  {
666  Ipv4Address dst = m_finalRoute.back ();
667  bool addRoute = false;
668  if (numberAddress > 0)
669  {
670  RouteCacheEntry toSource (/*IP_VECTOR=*/ m_finalRoute, /*dst=*/
671  dst, /*expire time=*/ ActiveRouteTimeout);
672  if (dsr->IsLinkCache ())
673  {
674  addRoute = dsr->AddRoute_Link (m_finalRoute, ipv4Address);
675  }
676  else
677  {
678  addRoute = dsr->AddRoute (toSource);
679  }
680  }
681  else
682  {
683  NS_LOG_DEBUG ("Abnormal RouteRequest");
684  return 0;
685  }
686 
687  if (addRoute)
688  {
689  /*
690  * Found a route to the dst, construct the source route option header
691  */
692  DsrOptionSRHeader sourceRoute;
693  NS_LOG_DEBUG ("The route length " << m_finalRoute.size ());
694  sourceRoute.SetNodesAddress (m_finalRoute);
695  if (dsr->IsLinkCache ())
696  {
697  dsr->UseExtends (m_finalRoute);
698  }
699  sourceRoute.SetSegmentsLeft ((m_finalRoute.size () - 2));
700  // The salvage value here is 0
701  sourceRoute.SetSalvage (0);
702  Ipv4Address nextHop = SearchNextHop (ipv4Address, m_finalRoute); // Get the next hop address
703  NS_LOG_DEBUG ("The nextHop address " << nextHop);
704 
705  if (nextHop == "0.0.0.0")
706  {
707  dsr->PacketNewRoute (dsrP, ipv4Address, dst, protocol);
708  return 0;
709  }
710  SetRoute (nextHop, ipv4Address);
711  /*
712  * Send the data packet from the send buffer
713  */
714  dsr->SendPacketFromBuffer (sourceRoute, nextHop, protocol);
715  // Cancel the route request timer for destination after sending the data packet
716  dsr->CancelRreqTimer (dst, true);
717  }
718  else
719  {
720  NS_LOG_DEBUG ("The route is failed to add in cache");
721  return 0;
722  }
723  }
724  else
725  {
726  NS_LOG_DEBUG ("Unable to reverse route");
727  return 0;
728  }
729  isPromisc = false;
730  return rreq.GetSerializedSize ();
731  }
732 
733  /*
734  * (ii) or it has an active route to the destination, send reply based on request header and route cache,
735  * need to delay based on a random value from d = H * (h - 1 + r), which can avoid possible route
736  * reply storm.
737  */
738  else if (dsr->LookupRoute (targetAddress, toPrev))
739  {
740  RouteCacheEntry::IP_VECTOR ip = toPrev.GetVector (); // The route from our own route cache to dst
741  PrintVector (ip);
742  std::vector<Ipv4Address> saveRoute (nodeList);
743  PrintVector (saveRoute);
744  // Verify if the two vector contains duplicates, if so, do not use
745  // the route found and forward the route request
746  if (!(IfDuplicates (ip, saveRoute)))
747  {
748  m_finalRoute.clear (); // Clear the final route vector
752  for (std::vector<Ipv4Address>::iterator i = saveRoute.begin (); i != saveRoute.end (); ++i)
753  {
754  m_finalRoute.push_back (*i);
755  }
759  for (std::vector<Ipv4Address>::iterator j = ip.begin (); j != ip.end (); ++j)
760  {
761  m_finalRoute.push_back (*j);
762  }
763  /*
764  * Create the route entry to the rreq originator and save it to route cache, also need to reverse the route
765  */
766  bool addRoute = false;
767  std::vector<Ipv4Address> reverseRoute (m_finalRoute);
768 
769  if (ReverseRoutes (reverseRoute))
770  {
771  saveRoute.push_back (ipv4Address);
772  ReverseRoutes (saveRoute);
773  Ipv4Address dst = saveRoute.back ();
774  NS_LOG_DEBUG ("This is the route save in route cache");
775  PrintVector (saveRoute);
776 
777  RouteCacheEntry toSource (/*IP_VECTOR=*/ saveRoute, /*dst=*/ dst, /*expire time=*/ ActiveRouteTimeout);
778  NS_ASSERT (saveRoute.front () == ipv4Address);
779  // Add the route entry in the route cache
780  if (dsr->IsLinkCache ())
781  {
782  addRoute = dsr->AddRoute_Link (saveRoute, ipv4Address);
783  }
784  else
785  {
786  addRoute = dsr->AddRoute (toSource);
787  }
788 
789  if (addRoute)
790  {
791  NS_LOG_LOGIC ("We have added the route and search send buffer for packet with destination " << dst);
792  /*
793  * Found a route the dst, construct the source route option header
794  */
795  DsrOptionSRHeader sourceRoute;
796  PrintVector (saveRoute);
797 
798  sourceRoute.SetNodesAddress (saveRoute);
799  if (dsr->IsLinkCache ())
800  {
801  dsr->UseExtends (saveRoute);
802  }
803  sourceRoute.SetSegmentsLeft ((saveRoute.size () - 2));
804  uint8_t salvage = 0;
805  sourceRoute.SetSalvage (salvage);
806  Ipv4Address nextHop = SearchNextHop (ipv4Address, saveRoute); // Get the next hop address
807  NS_LOG_DEBUG ("The nextHop address " << nextHop);
808 
809  if (nextHop == "0.0.0.0")
810  {
811  dsr->PacketNewRoute (dsrP, ipv4Address, dst, protocol);
812  return 0;
813  }
814  SetRoute (nextHop, ipv4Address);
815  /*
816  * Schedule the packet retry
817  */
818  dsr->SendPacketFromBuffer (sourceRoute, nextHop, protocol);
819  // Cancel the route request timer for destination
820  dsr->CancelRreqTimer (dst, true);
821  }
822  else
823  {
824  NS_LOG_DEBUG ("The route is failed to add in cache");
825  return 0;
826  }
827  }
828  else
829  {
830  NS_LOG_DEBUG ("Unable to reverse the route");
831  return 0;
832  }
833 
834  /*
835  * Need to first pin down the next hop address before removing duplicates
836  */
837  Ipv4Address nextHop = ReverseSearchNextHop (ipv4Address, m_finalRoute);
838  NS_LOG_DEBUG ("The nextHop address " << nextHop);
839  /*
840  * First remove the duplicate ip address to automatically shorten the route, and then reversely
841  * search the next hop address
842  */
843  // Set the route
844  SetRoute (nextHop, ipv4Address);
845 
846  uint16_t hops = m_finalRoute.size ();
847  DsrOptionRrepHeader rrep;
848  rrep.SetNodesAddress (m_finalRoute); // Set the node addresses in the route reply header
849  // Get the real source of the reply
850  Ipv4Address realSource = m_finalRoute.back ();
852  NS_LOG_DEBUG ("This is the full route from " << realSource << " to " << m_finalRoute.front ());
853  /*
854  * This part add dsr header to the packet and send route reply packet
855  */
856  DsrRoutingHeader dsrRoutingHeader;
857  dsrRoutingHeader.SetNextHeader (protocol);
858  dsrRoutingHeader.SetMessageType (1);
859  dsrRoutingHeader.SetSourceId (GetIDfromIP (realSource));
860  dsrRoutingHeader.SetDestId (255);
861 
862  uint8_t length = rrep.GetLength (); // Get the length of the rrep header excluding the type header
863  dsrRoutingHeader.SetPayloadLength (length + 2);
864  dsrRoutingHeader.AddDsrOption (rrep);
865  Ptr<Packet> newPacket = Create<Packet> ();
866  newPacket->AddHeader (dsrRoutingHeader);
867  dsr->ScheduleCachedReply (newPacket, ipv4Address, nextHop, m_ipv4Route, hops);
868  isPromisc = false;
869  }
870  else
871  {
872  NS_LOG_DEBUG ("There is duplicate ip addresses in the two route parts");
873  }
874  return rreq.GetSerializedSize ();
875  }
876  /*
877  * (iii) no route in any type has been found
878  */
879  else
880  {
881  mainVector.push_back (ipv4Address);
882  NS_ASSERT (mainVector.front () == source);
883  NS_LOG_DEBUG ("Print out the main vector");
884  PrintVector (mainVector);
885  rreq.SetNodesAddress (mainVector);
886 
887  Ptr<Packet> errP = p->Copy ();
888  if (errP->GetSize ())
889  {
890  NS_LOG_DEBUG ("Error header included");
892  p->RemoveHeader (rerr);
893  Ipv4Address errorSrc = rerr.GetErrorSrc ();
894  Ipv4Address unreachNode = rerr.GetUnreachNode ();
895  Ipv4Address errorDst = rerr.GetErrorDst ();
896 
897  if ((errorSrc == srcAddress) && (unreachNode == ipv4Address))
898  {
899  NS_LOG_DEBUG ("The error link back to work again");
900  uint16_t length = rreq.GetLength ();
901  NS_LOG_DEBUG ("The RREQ header length " << length);
902  dsrRoutingHeader.AddDsrOption (rreq);
903  dsrRoutingHeader.SetPayloadLength (length + 2);
904  }
905  else
906  {
907  dsr->DeleteAllRoutesIncludeLink (errorSrc, unreachNode, ipv4Address);
908 
909  DsrOptionRerrUnreachHeader newUnreach;
910  newUnreach.SetErrorType (1);
911  newUnreach.SetErrorSrc (errorSrc);
912  newUnreach.SetUnreachNode (unreachNode);
913  newUnreach.SetErrorDst (errorDst);
914  newUnreach.SetSalvage (rerr.GetSalvage ()); // Set the value about whether to salvage a packet or not
915  uint16_t length = rreq.GetLength () + newUnreach.GetLength ();
916  NS_LOG_DEBUG ("The RREQ and newUnreach header length " << length);
917  dsrRoutingHeader.SetPayloadLength (length + 4);
918  dsrRoutingHeader.AddDsrOption (rreq);
919  dsrRoutingHeader.AddDsrOption (newUnreach);
920  }
921  }
922  else
923  {
924  uint16_t length = rreq.GetLength ();
925  NS_LOG_DEBUG ("The RREQ header length " << length);
926  dsrRoutingHeader.AddDsrOption (rreq);
927  dsrRoutingHeader.SetPayloadLength (length + 2);
928  }
929  // Get the TTL value
930  uint8_t ttl = ipv4Header.GetTtl ();
931  /*
932  * Decrease the TTL value in the packet tag by one, this tag will go to ip layer 3 send function
933  * and drop packet when TTL value equals to 0
934  */
935  NS_LOG_DEBUG ("The ttl value here " << (uint32_t)ttl);
936  if (ttl)
937  {
938  Ptr<Packet> interP = Create<Packet> ();
939  SocketIpTtlTag tag;
940  tag.SetTtl (ttl - 1);
941  interP->AddPacketTag (tag);
942  interP->AddHeader (dsrRoutingHeader);
943  dsr->ScheduleInterRequest (interP);
944  isPromisc = false;
945  }
946  return rreq.GetSerializedSize ();
947  }
948  }
949  return rreq.GetSerializedSize ();
950 }
951 
953 
955 {
956  static TypeId tid = TypeId ("ns3::dsr::DsrOptionRrep")
957  .SetParent<DsrOptions> ()
958  .AddConstructor<DsrOptionRrep> ()
959  ;
960  return tid;
961 }
962 
964 {
966 }
967 
969 {
971 }
972 
974 {
975  return GetTypeId ();
976 }
977 
979 {
981 
982  return OPT_NUMBER;
983 }
984 
985 uint8_t DsrOptionRrep::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc, Ipv4Address promiscSource)
986 {
987  NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Header << (uint32_t)protocol << isPromisc);
988 
989  Ptr<Packet> p = packet->Copy ();
990 
991  // Get the number of routers' address field
992  uint8_t buf[2];
993  p->CopyData (buf, sizeof(buf));
994  uint8_t numberAddress = (buf[1] - 2) / 4;
995 
996  DsrOptionRrepHeader rrep;
997  rrep.SetNumberAddress (numberAddress); // Set the number of ip address in the header to reserver space for deserialize header
998  p->RemoveHeader (rrep);
999 
1000  Ptr<Node> node = GetNodeWithAddress (ipv4Address);
1002 
1003  NS_LOG_DEBUG ("The next header value " << (uint32_t)protocol);
1004 
1005  std::vector<Ipv4Address> nodeList = rrep.GetNodesAddress ();
1009  Ipv4Address targetAddress = nodeList.front ();
1010  // If the RREP option has reached to the destination
1011  if (targetAddress == ipv4Address)
1012  {
1013  RemoveDuplicates (nodeList); // This is for the route reply from intermediate node since we didn't remove
1014  // duplicate there
1015  if (nodeList.size () == 0)
1016  {
1017  NS_LOG_DEBUG ("The route we have contains 0 entries");
1018  return 0;
1019  }
1023  Ipv4Address dst = nodeList.back ();
1029  RouteCacheEntry toDestination (/*IP_VECTOR=*/ nodeList, /*dst=*/ dst, /*expire time=*/ ActiveRouteTimeout);
1030  NS_ASSERT (nodeList.front () == ipv4Address);
1031  bool addRoute = false;
1032  if (dsr->IsLinkCache ())
1033  {
1034  addRoute = dsr->AddRoute_Link (nodeList, ipv4Address);
1035  }
1036  else
1037  {
1038  addRoute = dsr->AddRoute (toDestination);
1039  }
1040 
1041  if (addRoute)
1042  {
1043  NS_LOG_DEBUG ("We have added the route and search send buffer for packet with destination " << dst);
1047  DsrOptionSRHeader sourceRoute;
1048  NS_LOG_DEBUG ("The route length " << nodeList.size ());
1049  sourceRoute.SetNodesAddress (nodeList);
1050  sourceRoute.SetSegmentsLeft ((nodeList.size () - 2));
1051  sourceRoute.SetSalvage (0);
1052  Ipv4Address nextHop = SearchNextHop (ipv4Address, nodeList); // Get the next hop address
1053  NS_LOG_DEBUG ("The nextHop address " << nextHop);
1054  if (nextHop == "0.0.0.0")
1055  {
1056  dsr->PacketNewRoute (dsrP, ipv4Address, dst, protocol);
1057  return 0;
1058  }
1059  PrintVector (nodeList);
1060  SetRoute (nextHop, ipv4Address);
1061  // Cancel the route request timer for destination
1062  dsr->CancelRreqTimer (dst, true);
1066  dsr->SendPacketFromBuffer (sourceRoute, nextHop, protocol);
1067  }
1068  else
1069  {
1070  NS_LOG_DEBUG ("Failed to add the route");
1071  return 0;
1072  }
1073  }
1074  else
1075  {
1076  uint8_t length = rrep.GetLength () - 2; // The get length - 2 is to get aligned for the malformed header check
1077  NS_LOG_DEBUG ("The length of rrep option " << (uint32_t)length);
1078 
1079  if (length % 2 != 0)
1080  {
1081  NS_LOG_LOGIC ("Malformed header. Drop!");
1082  m_dropTrace (packet);
1083  return 0;
1084  }
1085  PrintVector (nodeList);
1086  /*
1087  * This node is only an intermediate node, but it needs to save the possible route to the destination when cutting the route
1088  */
1089  std::vector<Ipv4Address> routeCopy = nodeList;
1090  std::vector<Ipv4Address> cutRoute = CutRoute (ipv4Address, nodeList);
1091  PrintVector (cutRoute);
1092  if (cutRoute.size () >= 2)
1093  {
1094  Ipv4Address dst = cutRoute.back ();
1095  NS_LOG_DEBUG ("The route destination after cut " << dst);
1096  RouteCacheEntry toDestination (/*IP_VECTOR=*/ cutRoute, /*dst=*/ dst, /*expire time=*/ ActiveRouteTimeout);
1097  NS_ASSERT (cutRoute.front () == ipv4Address);
1098  bool addRoute = false;
1099  if (dsr->IsLinkCache ())
1100  {
1101  addRoute = dsr->AddRoute_Link (nodeList, ipv4Address);
1102  }
1103  else
1104  {
1105  addRoute = dsr->AddRoute (toDestination);
1106  }
1107  if (addRoute)
1108  {
1109  dsr->CancelRreqTimer (dst, true);
1110  }
1111  else
1112  {
1113  NS_LOG_DEBUG ("The route not added");
1114  }
1115  }
1116  else
1117  {
1118  NS_LOG_DEBUG ("The route is corrupted");
1119  }
1120  /*
1121  * Reverse search the vector for next hop address
1122  */
1123  Ipv4Address nextHop = ReverseSearchNextHop (ipv4Address, routeCopy);
1124  NS_ASSERT (routeCopy.back () == source);
1125  PrintVector (routeCopy);
1126  NS_LOG_DEBUG ("The nextHop address " << nextHop << " and the source in the route reply " << source);
1127  /*
1128  * Set the route entry we will use to send reply
1129  */
1130  SetRoute (nextHop, ipv4Address);
1131  /*
1132  * This part add dsr routing header to the packet and send reply
1133  */
1134  DsrRoutingHeader dsrRoutingHeader;
1135  dsrRoutingHeader.SetNextHeader (protocol);
1136 
1137  length = rrep.GetLength (); // Get the length of the rrep header excluding the type header
1138  NS_LOG_DEBUG ("The reply header length " << (uint32_t)length);
1139  dsrRoutingHeader.SetPayloadLength (length + 2);
1140  dsrRoutingHeader.SetMessageType (1);
1141  dsrRoutingHeader.SetSourceId (GetIDfromIP (source));
1142  dsrRoutingHeader.SetDestId (GetIDfromIP (targetAddress));
1143  dsrRoutingHeader.AddDsrOption (rrep);
1144  Ptr<Packet> newPacket = Create<Packet> ();
1145  newPacket->AddHeader (dsrRoutingHeader);
1146  dsr->SendReply (newPacket, ipv4Address, nextHop, m_ipv4Route);
1147  isPromisc = false;
1148  }
1149  return rrep.GetSerializedSize ();
1150 }
1151 
1153 
1155 {
1156  static TypeId tid = TypeId ("ns3::dsr::DsrOptionSR")
1157  .SetParent<DsrOptions> ()
1158  .AddConstructor<DsrOptionSR> ()
1159  ;
1160  return tid;
1161 }
1162 
1164 {
1166 }
1167 
1169 {
1171 }
1172 
1174 {
1175  return GetTypeId ();
1176 }
1177 
1179 {
1181  return OPT_NUMBER;
1182 }
1183 
1184 uint8_t DsrOptionSR::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc, Ipv4Address promiscSource)
1185 {
1186  NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Address << ipv4Header << (uint32_t)protocol << isPromisc);
1187  Ptr<Packet> p = packet->Copy ();
1188  // Get the number of routers' address field
1189  uint8_t buf[2];
1190  p->CopyData (buf, sizeof(buf));
1191  uint8_t numberAddress = (buf[1] - 2) / 4;
1192  DsrOptionSRHeader sourceRoute;
1193  sourceRoute.SetNumberAddress (numberAddress);
1194  p->RemoveHeader (sourceRoute);
1195 
1196  // The route size saved in the source route
1197  std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
1198  uint8_t segsLeft = sourceRoute.GetSegmentsLeft ();
1199  uint8_t salvage = sourceRoute.GetSalvage ();
1200  /*
1201  * Get the node from IP address and get the DSR extension object
1202  */
1203  Ptr<Node> node = GetNodeWithAddress (ipv4Address);
1205  /*
1206  * Get the source and destination address from ipv4 header
1207  */
1208  Ipv4Address srcAddress = ipv4Header.GetSource ();
1209  Ipv4Address destAddress = ipv4Header.GetDestination ();
1210 
1211  // Get the node list destination
1212  Ipv4Address destination = nodeList.back ();
1213  /*
1214  * If it's a promiscuous receive data packet,
1215  * 1. see if automatic route shortening possible or not
1216  * 2. see if it is a passive acknowledgment
1217  */
1218  if (isPromisc)
1219  {
1220  NS_LOG_LOGIC ("We process promiscuous receipt data packet");
1221  if (ContainAddressAfter (ipv4Address, destAddress, nodeList))
1222  {
1223  NS_LOG_LOGIC ("Send back the gratuitous reply");
1224  dsr->SendGratuitousReply (source, srcAddress, nodeList, protocol);
1225  }
1226 
1227  uint16_t fragmentOffset = ipv4Header.GetFragmentOffset ();
1228  uint16_t identification = ipv4Header.GetIdentification ();
1229 
1230  if (destAddress != destination)
1231  {
1232  NS_LOG_DEBUG ("Process the promiscuously received packet");
1233  bool findPassive = false;
1234  int32_t nNodes = NodeList::GetNNodes ();
1235  for (int32_t i = 0; i < nNodes; ++i)
1236  {
1237  NS_LOG_DEBUG ("Working with node " << i);
1238 
1239  Ptr<Node> node = NodeList::GetNode (i);
1240  Ptr<dsr::DsrRouting> dsrNode = node->GetObject<dsr::DsrRouting> ();
1241  // The source and destination addresses here are the real source and destination for the packet
1242  findPassive = dsrNode->PassiveEntryCheck (packet, source, destination, segsLeft, fragmentOffset, identification, false);
1243  if (findPassive)
1244  {
1245  break;
1246  }
1247  }
1248 
1249  if (findPassive)
1250  {
1251  NS_LOG_DEBUG ("We find one previously received passive entry");
1252  /*
1253  * Get the node from IP address and get the DSR extension object
1254  * the srcAddress would be the source address from ip header
1255  */
1256  PrintVector (nodeList);
1257 
1258  NS_LOG_DEBUG ("promisc source " << promiscSource);
1259  Ptr<Node> node = GetNodeWithAddress (promiscSource);
1260  Ptr<dsr::DsrRouting> dsrSrc = node->GetObject<dsr::DsrRouting> ();
1261  dsrSrc->CancelPassiveTimer (packet, source, destination, segsLeft);
1262  }
1263  else
1264  {
1265  NS_LOG_DEBUG ("Saved the entry for further use");
1266  dsr->PassiveEntryCheck (packet, source, destination, segsLeft, fragmentOffset, identification, true);
1267  }
1268  }
1270  return 0;
1271  }
1272  else
1273  {
1274  /*
1275  * Get the number of address from the source route header
1276  */
1277  uint8_t length = sourceRoute.GetLength ();
1278  uint8_t nextAddressIndex;
1279  Ipv4Address nextAddress;
1280 
1281  // Get the option type value
1282  uint32_t size = p->GetSize ();
1283  uint8_t *data = new uint8_t[size];
1284  p->CopyData (data, size);
1285  uint8_t optionType = 0;
1286  optionType = *(data);
1289  if (optionType == 160)
1290  {
1291  NS_LOG_LOGIC ("Remove the ack request header and add ack header to the packet");
1292  // Here we remove the ack packet to the previous hop
1293  DsrOptionAckReqHeader ackReq;
1294  p->RemoveHeader (ackReq);
1295  uint16_t ackId = ackReq.GetAckId ();
1296  /*
1297  * Send back acknowledgment packet to the earlier hop
1298  * If the node list is not empty, find the previous hop from the node list,
1299  * otherwise, use srcAddress
1300  */
1301  Ipv4Address ackAddress = srcAddress;
1302  if (!nodeList.empty ())
1303  {
1304  if (segsLeft > numberAddress) // The segmentsLeft field should not be larger than the total number of ip addresses
1305  {
1306  NS_LOG_LOGIC ("Malformed header. Drop!");
1307  m_dropTrace (packet);
1308  return 0;
1309  }
1310  if (numberAddress - segsLeft - 2 < 0) // The index is invalid
1311  {
1312  NS_LOG_LOGIC ("Malformed header. Drop!");
1313  m_dropTrace (packet);
1314  return 0;
1315  }
1316  ackAddress = nodeList[numberAddress - segsLeft - 2];
1317  }
1318  m_ipv4Route = SetRoute (ackAddress, ipv4Address);
1319  NS_LOG_DEBUG ("Send back ACK to the earlier hop " << ackAddress << " from us " << ipv4Address);
1320  dsr->SendAck (ackId, ackAddress, source, destination, protocol, m_ipv4Route);
1321  }
1322  /*
1323  * After send back ACK, check if the segments left value has turned to 0 or not, if yes, update the route entry
1324  * and return header length
1325  */
1326  if (segsLeft == 0)
1327  {
1328  NS_LOG_DEBUG ("This is the final destination");
1329  isPromisc = false;
1330  return sourceRoute.GetSerializedSize ();
1331  }
1332 
1333  if (length % 2 != 0)
1334  {
1335  NS_LOG_LOGIC ("Malformed header. Drop!");
1336  m_dropTrace (packet);
1337  return 0;
1338  }
1339 
1340  if (segsLeft > numberAddress) // The segmentsLeft field should not be larger than the total number of ip addresses
1341  {
1342  NS_LOG_LOGIC ("Malformed header. Drop!");
1343  m_dropTrace (packet);
1344  return 0;
1345  }
1346 
1347  DsrOptionSRHeader newSourceRoute;
1348  newSourceRoute.SetSegmentsLeft (segsLeft - 1);
1349  newSourceRoute.SetSalvage (salvage);
1350  newSourceRoute.SetNodesAddress (nodeList);
1351  nextAddressIndex = numberAddress - segsLeft;
1352  nextAddress = newSourceRoute.GetNodeAddress (nextAddressIndex);
1353  NS_LOG_DEBUG ("The next address of source route option " << nextAddress << " and the nextAddressIndex: " << (uint32_t)nextAddressIndex << " and the segments left : " << (uint32_t)segsLeft);
1354  /*
1355  * Get the target Address in the node list
1356  */
1357  Ipv4Address targetAddress = nodeList.back ();
1358  Ipv4Address realSource = nodeList.front ();
1359  /*
1360  * Search the vector for next hop address
1361  */
1362  Ipv4Address nextHop = SearchNextHop (ipv4Address, nodeList);
1363  PrintVector (nodeList);
1364 
1365  if (nextHop == "0.0.0.0")
1366  {
1367  NS_LOG_DEBUG ("Before new packet " << *dsrP);
1368  dsr->PacketNewRoute (dsrP, realSource, targetAddress, protocol);
1369  return 0;
1370  }
1371 
1372  if (ipv4Address == nextHop)
1373  {
1374  NS_LOG_DEBUG ("We have reached the destination");
1375  newSourceRoute.SetSegmentsLeft (0);
1376  return newSourceRoute.GetSerializedSize ();
1377  }
1378  // Verify the multicast address, leave it here for now
1379  if (nextAddress.IsMulticast () || destAddress.IsMulticast ())
1380  {
1381  m_dropTrace (packet);
1382  return 0;
1383  }
1384  // Set the route and forward the data packet
1385  SetRoute (nextAddress, ipv4Address);
1386  NS_LOG_DEBUG ("dsr packet size " << dsrP->GetSize ());
1387  dsr->ForwardPacket (dsrP, newSourceRoute, ipv4Header, realSource, nextAddress, targetAddress, protocol, m_ipv4Route);
1388  }
1389  return sourceRoute.GetSerializedSize ();
1390 }
1391 
1393 
1395 {
1396  static TypeId tid = TypeId ("ns3::dsr::DsrOptionRerr")
1397  .SetParent<DsrOptions> ()
1398  .AddConstructor<DsrOptionRerr> ()
1399  ;
1400  return tid;
1401 }
1402 
1404 {
1406 }
1407 
1409 {
1411 }
1412 
1414 {
1415  return GetTypeId ();
1416 }
1417 
1419 {
1421  return OPT_NUMBER;
1422 }
1423 
1424 uint8_t DsrOptionRerr::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc, Ipv4Address promiscSource)
1425 {
1426  NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Header << (uint32_t)protocol << isPromisc);
1427  Ptr<Packet> p = packet->Copy ();
1428  uint32_t size = p->GetSize ();
1429  uint8_t *data = new uint8_t[size];
1430  p->CopyData (data, size);
1431  uint8_t errorType = *(data + 2);
1432  /*
1433  * Get the node from Ip address and get the dsr extension object
1434  */
1435  Ptr<Node> node = GetNodeWithAddress (ipv4Address);
1437  /*
1438  * The error serialized size
1439  */
1440  uint32_t rerrSize;
1441  NS_LOG_DEBUG ("The error type value here " << (uint32_t)errorType);
1442  if (errorType == 1) // unreachable ip address
1443  {
1444  /*
1445  * Remove the route error header from the packet, and get the error type
1446  */
1447  DsrOptionRerrUnreachHeader rerrUnreach;
1448  p->RemoveHeader (rerrUnreach);
1449  /*
1450  * Get the error destination address
1451  */
1452  Ipv4Address unreachAddress = rerrUnreach.GetUnreachNode ();
1453  Ipv4Address errorSource = rerrUnreach.GetErrorSrc ();
1454 
1455  NS_LOG_DEBUG ("The error source is " << rerrUnreach.GetErrorDst () << "and the unreachable node is " << unreachAddress);
1456  /*
1457  * Get the serialized size of the rerr header
1458  */
1459  rerrSize = rerrUnreach.GetSerializedSize ();
1460  /*
1461  * Delete all the routes including the unreachable node address from the route cache
1462  */
1463  Ptr<Node> node = GetNodeWithAddress (ipv4Address);
1464  dsr->DeleteAllRoutesIncludeLink (errorSource, unreachAddress, ipv4Address);
1465 
1466  Ptr<Packet> newP = p->Copy ();
1467  uint32_t serialized = DoSendError (newP, rerrUnreach, rerrSize, ipv4Address, protocol);
1468  return serialized;
1469  }
1470  else
1471  {
1472  /*
1473  * Two other type of error headers:
1474  * 1. flow state not supported type-specific information
1475  * 2. unsupported option with option number
1476  */
1477  /*
1478  * Remove the route error header from the packet, and get the error type
1479  */
1480  DsrOptionRerrUnsupportHeader rerrUnsupport;
1481  p->RemoveHeader (rerrUnsupport);
1482  rerrSize = rerrUnsupport.GetSerializedSize ();
1483 
1484  // This is for the other two error options, not supporting for now TODO
1485 // uint32_t serialized = DoSendError (p, rerrUnsupport, rerrSize, ipv4Address, protocol);
1486  uint32_t serialized = 0;
1487  return serialized;
1488  }
1489 }
1490 
1491 uint8_t DsrOptionRerr::DoSendError (Ptr<Packet> p, DsrOptionRerrUnreachHeader &rerr, uint32_t rerrSize, Ipv4Address ipv4Address, uint8_t protocol)
1492 {
1493  // Get the number of routers' address field
1494  uint8_t buf[2];
1495  p->CopyData (buf, sizeof(buf));
1496  uint8_t numberAddress = (buf[1] - 2) / 4;
1497 
1498  // Here remove the source route header and schedule next hop error transmission
1499  NS_LOG_DEBUG ("The number of addresses " << (uint32_t)numberAddress);
1500  DsrOptionSRHeader sourceRoute;
1501  sourceRoute.SetNumberAddress (numberAddress);
1502  p->RemoveHeader (sourceRoute);
1503  NS_ASSERT (p->GetSize () == 0);
1504  /*
1505  * Get the node from ip address and the dsr extension object
1506  */
1507  Ptr<Node> node = GetNodeWithAddress (ipv4Address);
1508  Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting> ();
1509  /*
1510  * Get the segments left field and the next address
1511  */
1512  uint8_t segmentsLeft = sourceRoute.GetSegmentsLeft ();
1513  uint8_t length = sourceRoute.GetLength ();
1514  uint8_t nextAddressIndex;
1515  Ipv4Address nextAddress;
1516  /*
1517  * Get the route size and the error target address
1518  */
1519  std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
1520  Ipv4Address targetAddress = nodeList.back ();
1521  /*
1522  * The total serialized size for both the rerr and source route headers
1523  */
1524  uint32_t serializedSize = rerrSize + sourceRoute.GetSerializedSize ();
1525 
1526  if (length % 2 != 0)
1527  {
1528  NS_LOG_LOGIC ("Malformed header. Drop!");
1529  m_dropTrace (p);
1530  return 0;
1531  }
1532 
1533  if (segmentsLeft > numberAddress)
1534  {
1535  NS_LOG_LOGIC ("Malformed header. Drop!");
1536  m_dropTrace (p);
1537  return 0;
1538  }
1539  /*
1540  * When the error packet has reached to the destination
1541  */
1542  if (segmentsLeft == 0 && targetAddress == ipv4Address)
1543  {
1544  NS_LOG_INFO ("This is the destination of the error, send error request");
1545  dsr->SendErrorRequest (rerr, protocol);
1546  return serializedSize;
1547  }
1548 
1549  // Get the next Router Address
1550  DsrOptionSRHeader newSourceRoute;
1551  newSourceRoute.SetSegmentsLeft (segmentsLeft - 1);
1552  nextAddressIndex = numberAddress - segmentsLeft;
1553  nextAddress = sourceRoute.GetNodeAddress (nextAddressIndex);
1554  newSourceRoute.SetSalvage (sourceRoute.GetSalvage ());
1555  newSourceRoute.SetNodesAddress (nodeList);
1556  nextAddress = newSourceRoute.GetNodeAddress (nextAddressIndex);
1557 
1558  // / to test if the next address is multicast or not
1559  if (nextAddress.IsMulticast () || targetAddress.IsMulticast ())
1560  {
1561  m_dropTrace (p);
1562  return serializedSize;
1563  }
1564 
1565  // Set the route entry
1566  SetRoute (nextAddress, ipv4Address);
1567  dsr->ForwardErrPacket (rerr, newSourceRoute, nextAddress, protocol, m_ipv4Route);
1568  return serializedSize;
1569 }
1570 
1572 
1574 {
1575  static TypeId tid = TypeId ("ns3::dsr::DsrOptionAckReq")
1576  .SetParent<DsrOptions> ()
1577  .AddConstructor<DsrOptionAckReq> ()
1578  ;
1579  return tid;
1580 }
1581 
1583 {
1585 }
1586 
1588 {
1590 }
1591 
1593 {
1594  return GetTypeId ();
1595 }
1596 
1598 {
1600  return OPT_NUMBER;
1601 }
1602 
1603 uint8_t DsrOptionAckReq::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc, Ipv4Address promiscSource)
1604 {
1605  NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Header << (uint32_t)protocol << isPromisc);
1606  /*
1607  * Current implementation of the ack request header processing is coded in source route header processing
1608  */
1609  /*
1610  * Remove the ack request header
1611  */
1612  Ptr<Packet> p = packet->Copy ();
1613  DsrOptionAckReqHeader ackReq;
1614  p->RemoveHeader (ackReq);
1615  /*
1616  * Get the node with ip address and get the dsr extension and reoute cache objects
1617  */
1618  Ptr<Node> node = GetNodeWithAddress (ipv4Address);
1620 
1621  NS_LOG_DEBUG ("The next header value " << (uint32_t)protocol);
1622 
1623  return ackReq.GetSerializedSize ();
1624 }
1625 
1627 
1629 {
1630  static TypeId tid = TypeId ("ns3::dsr::DsrOptionAck")
1631  .SetParent<DsrOptions> ()
1632  .AddConstructor<DsrOptionAck> ()
1633  ;
1634  return tid;
1635 }
1636 
1638 {
1640 }
1641 
1643 {
1645 }
1646 
1648 {
1649  return GetTypeId ();
1650 }
1651 
1653 {
1655  return OPT_NUMBER;
1656 }
1657 
1658 uint8_t DsrOptionAck::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc, Ipv4Address promiscSource)
1659 {
1660  NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Header << (uint32_t)protocol << isPromisc);
1661  /*
1662  * Remove the ACK header
1663  */
1664  Ptr<Packet> p = packet->Copy ();
1665  DsrOptionAckHeader ack;
1666  p->RemoveHeader (ack);
1667  /*
1668  * Get the ACK source and destination address
1669  */
1670  Ipv4Address realSrc = ack.GetRealSrc ();
1671  Ipv4Address realDst = ack.GetRealDst ();
1672  uint16_t ackId = ack.GetAckId ();
1673  /*
1674  * Get the node with ip address and get the dsr extension and route cache objects
1675  */
1676  Ptr<Node> node = GetNodeWithAddress (ipv4Address);
1678  dsr->UpdateRouteEntry (realDst);
1679  /*
1680  * Cancel the packet retransmit timer when receiving the ack packet
1681  */
1682  dsr->CallCancelPacketTimer (ackId, ipv4Header, realSrc, realDst);
1683  return ack.GetSerializedSize ();
1684 }
1685 
1686 } // namespace dsr
1687 } // namespace ns3