A Discrete-Event Network Simulator
API
olsr-routing-protocol.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2004 Francisco J. Ros
4  * Copyright (c) 2007 INESC Porto
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Authors: Francisco J. Ros <fjrm@dif.um.es>
20  * Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
21  */
22 
23 
30 
31 #define NS_LOG_APPEND_CONTEXT \
32  if (GetObject<Node> ()) { std::clog << "[node " << GetObject<Node> ()->GetId () << "] "; }
33 
34 
35 #include "olsr-routing-protocol.h"
36 #include "ns3/socket-factory.h"
37 #include "ns3/udp-socket-factory.h"
38 #include "ns3/simulator.h"
39 #include "ns3/log.h"
40 #include "ns3/names.h"
41 #include "ns3/inet-socket-address.h"
42 #include "ns3/ipv4-routing-protocol.h"
43 #include "ns3/ipv4-routing-table-entry.h"
44 #include "ns3/ipv4-route.h"
45 #include "ns3/boolean.h"
46 #include "ns3/uinteger.h"
47 #include "ns3/enum.h"
48 #include "ns3/trace-source-accessor.h"
49 #include "ns3/ipv4-header.h"
50 #include "ns3/ipv4-packet-info-tag.h"
51 
52 /********** Useful macros **********/
53 
60 #define DELAY(time) (((time) < (Simulator::Now ())) ? Seconds (0.000001) : \
61  (time - Simulator::Now () + Seconds (0.000001)))
62 
63 
64 
70 #define OLSR_REFRESH_INTERVAL m_helloInterval
71 
72 
73 /********** Holding times **********/
74 
76 #define OLSR_NEIGHB_HOLD_TIME Time (3 * OLSR_REFRESH_INTERVAL)
77 #define OLSR_TOP_HOLD_TIME Time (3 * m_tcInterval)
79 #define OLSR_DUP_HOLD_TIME Seconds (30)
81 #define OLSR_MID_HOLD_TIME Time (3 * m_midInterval)
83 #define OLSR_HNA_HOLD_TIME Time (3 * m_hnaInterval)
85 
86 /********** Link types **********/
87 
89 #define OLSR_UNSPEC_LINK 0
90 #define OLSR_ASYM_LINK 1
92 #define OLSR_SYM_LINK 2
94 #define OLSR_LOST_LINK 3
96 
97 /********** Neighbor types **********/
98 
100 #define OLSR_NOT_NEIGH 0
101 #define OLSR_SYM_NEIGH 1
103 #define OLSR_MPR_NEIGH 2
105 
106 
107 /********** Willingness **********/
108 
110 #define OLSR_WILL_NEVER 0
111 #define OLSR_WILL_LOW 1
113 #define OLSR_WILL_DEFAULT 3
115 #define OLSR_WILL_HIGH 6
117 #define OLSR_WILL_ALWAYS 7
119 
120 
121 /********** Miscellaneous constants **********/
122 
124 #define OLSR_MAXJITTER (m_helloInterval.GetSeconds () / 4)
125 #define OLSR_MAX_SEQ_NUM 65535
127 #define JITTER (Seconds (m_uniformRandomVariable->GetValue (0, OLSR_MAXJITTER)))
129 
130 
132 #define OLSR_MAX_MSGS 64
133 
135 #define OLSR_MAX_HELLOS 12
136 
138 #define OLSR_MAX_ADDRS 64
139 
140 
141 namespace ns3 {
142 
143 NS_LOG_COMPONENT_DEFINE ("OlsrRoutingProtocol");
144 
145 namespace olsr {
146 
147 /********** OLSR class **********/
148 
149 NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol);
150 
151 /* see https://www.iana.org/assignments/service-names-port-numbers */
152 const uint16_t RoutingProtocol::OLSR_PORT_NUMBER = 698;
153 
154 TypeId
156 {
157  static TypeId tid = TypeId ("ns3::olsr::RoutingProtocol")
159  .SetGroupName ("Olsr")
160  .AddConstructor<RoutingProtocol> ()
161  .AddAttribute ("HelloInterval", "HELLO messages emission interval.",
162  TimeValue (Seconds (2)),
164  MakeTimeChecker ())
165  .AddAttribute ("TcInterval", "TC messages emission interval.",
166  TimeValue (Seconds (5)),
168  MakeTimeChecker ())
169  .AddAttribute ("MidInterval", "MID messages emission interval. Normally it is equal to TcInterval.",
170  TimeValue (Seconds (5)),
172  MakeTimeChecker ())
173  .AddAttribute ("HnaInterval", "HNA messages emission interval. Normally it is equal to TcInterval.",
174  TimeValue (Seconds (5)),
176  MakeTimeChecker ())
177  .AddAttribute ("Willingness", "Willingness of a node to carry and forward traffic for other nodes.",
181  OLSR_WILL_LOW, "low",
182  OLSR_WILL_DEFAULT, "default",
183  OLSR_WILL_HIGH, "high",
184  OLSR_WILL_ALWAYS, "always"))
185  .AddTraceSource ("Rx", "Receive OLSR packet.",
187  "ns3::olsr::RoutingProtocol::PacketTxRxTracedCallback")
188  .AddTraceSource ("Tx", "Send OLSR packet.",
190  "ns3::olsr::RoutingProtocol::PacketTxRxTracedCallback")
191  .AddTraceSource ("RoutingTableChanged", "The OLSR routing table has changed.",
193  "ns3::olsr::RoutingProtocol::TableChangeTracedCallback")
194  ;
195  return tid;
196 }
197 
198 
200  : m_routingTableAssociation (0),
201  m_ipv4 (0),
202  m_helloTimer (Timer::CANCEL_ON_DESTROY),
203  m_tcTimer (Timer::CANCEL_ON_DESTROY),
204  m_midTimer (Timer::CANCEL_ON_DESTROY),
205  m_hnaTimer (Timer::CANCEL_ON_DESTROY),
206  m_queuedMessagesTimer (Timer::CANCEL_ON_DESTROY)
207 {
208  m_uniformRandomVariable = CreateObject<UniformRandomVariable> ();
209 
210  m_hnaRoutingTable = Create<Ipv4StaticRouting> ();
211 }
212 
214 {
215 }
216 
217 void
219 {
220  NS_ASSERT (ipv4 != 0);
221  NS_ASSERT (m_ipv4 == 0);
222  NS_LOG_DEBUG ("Created olsr::RoutingProtocol");
228 
232 
234 
235  m_ipv4 = ipv4;
236 
237  m_hnaRoutingTable->SetIpv4 (ipv4);
238 }
239 
240 Ptr<Ipv4>
242 {
243  return m_ipv4;
244 }
245 
247 {
248  m_ipv4 = 0;
249  m_hnaRoutingTable = 0;
251 
252  if (m_recvSocket)
253  {
254  m_recvSocket->Close ();
255  m_recvSocket = 0;
256  }
257 
258  for (std::map< Ptr<Socket>, Ipv4InterfaceAddress >::iterator iter = m_sendSockets.begin ();
259  iter != m_sendSockets.end (); iter++)
260  {
261  iter->first->Close ();
262  }
263  m_sendSockets.clear ();
264  m_table.clear ();
265 
267 }
268 
269 void
271 {
272  std::ostream* os = stream->GetStream ();
273 
274  *os << "Node: " << m_ipv4->GetObject<Node> ()->GetId ()
275  << ", Time: " << Now ().As (unit)
276  << ", Local time: " << GetObject<Node> ()->GetLocalTime ().As (unit)
277  << ", OLSR Routing table" << std::endl;
278 
279  *os << "Destination\t\tNextHop\t\tInterface\tDistance\n";
280 
281  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
282  iter != m_table.end (); iter++)
283  {
284  *os << iter->first << "\t\t";
285  *os << iter->second.nextAddr << "\t\t";
286  if (Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) != "")
287  {
288  *os << Names::FindName (m_ipv4->GetNetDevice (iter->second.interface)) << "\t\t";
289  }
290  else
291  {
292  *os << iter->second.interface << "\t\t";
293  }
294  *os << iter->second.distance << "\t";
295  *os << "\n";
296  }
297 
298  // Also print the HNA routing table
299  if (m_hnaRoutingTable->GetNRoutes () > 0)
300  {
301  *os << " HNA Routing Table: ";
302  m_hnaRoutingTable->PrintRoutingTable (stream, unit);
303  }
304  else
305  {
306  *os << " HNA Routing Table: empty" << std::endl;
307  }
308 }
309 
311 {
312  if (m_mainAddress == Ipv4Address ())
313  {
314  Ipv4Address loopback ("127.0.0.1");
315  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
316  {
317  // Use primary address, if multiple
318  Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
319  if (addr != loopback)
320  {
321  m_mainAddress = addr;
322  break;
323  }
324  }
325 
327  }
328 
329  NS_LOG_DEBUG ("Starting OLSR on node " << m_mainAddress);
330 
331  Ipv4Address loopback ("127.0.0.1");
332 
333  bool canRunOlsr = false;
334  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
335  {
336  Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
337  if (addr == loopback)
338  {
339  continue;
340  }
341 
342  if (addr != m_mainAddress)
343  {
344  // Create never expiring interface association tuple entries for our
345  // own network interfaces, so that GetMainAddress () works to
346  // translate the node's own interface addresses into the main address.
347  IfaceAssocTuple tuple;
348  tuple.ifaceAddr = addr;
349  tuple.mainAddr = m_mainAddress;
350  AddIfaceAssocTuple (tuple);
352  }
353 
354  if (m_interfaceExclusions.find (i) != m_interfaceExclusions.end ())
355  {
356  continue;
357  }
358 
359  // Create a socket to listen on all the interfaces
360  if (m_recvSocket == 0)
361  {
362  m_recvSocket = Socket::CreateSocket (GetObject<Node> (),
367  if (m_recvSocket->Bind (inetAddr))
368  {
369  NS_FATAL_ERROR ("Failed to bind() OLSR socket");
370  }
373  }
374 
375  // Create a socket to send packets from this specific interfaces
376  Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
378  socket->SetAllowBroadcast (true);
379  socket->SetIpTtl (1);
380  InetSocketAddress inetAddr (m_ipv4->GetAddress (i, 0).GetLocal (), OLSR_PORT_NUMBER);
382  socket->BindToNetDevice (m_ipv4->GetNetDevice (i));
383  if (socket->Bind (inetAddr))
384  {
385  NS_FATAL_ERROR ("Failed to bind() OLSR socket");
386  }
387  socket->SetRecvPktInfo (true);
388  m_sendSockets[socket] = m_ipv4->GetAddress (i, 0);
389 
390  canRunOlsr = true;
391  }
392 
393  if (canRunOlsr)
394  {
395  HelloTimerExpire ();
396  TcTimerExpire ();
397  MidTimerExpire ();
398  HnaTimerExpire ();
399 
400  NS_LOG_DEBUG ("OLSR on node " << m_mainAddress << " started");
401  }
402 }
403 
404 void RoutingProtocol::SetMainInterface (uint32_t interface)
405 {
406  m_mainAddress = m_ipv4->GetAddress (interface, 0).GetLocal ();
407 }
408 
409 void RoutingProtocol::SetInterfaceExclusions (std::set<uint32_t> exceptions)
410 {
411  m_interfaceExclusions = exceptions;
412 }
413 
414 //
415 // \brief Processes an incoming %OLSR packet following \RFC{3626} specification.
416 void
418 {
419  Ptr<Packet> receivedPacket;
420  Address sourceAddress;
421  receivedPacket = socket->RecvFrom (sourceAddress);
422 
423  Ipv4PacketInfoTag interfaceInfo;
424  if (!receivedPacket->RemovePacketTag (interfaceInfo))
425  {
426  NS_ABORT_MSG ("No incoming interface on OLSR message, aborting.");
427  }
428  uint32_t incomingIf = interfaceInfo.GetRecvIf ();
429  Ptr<Node> node = this->GetObject<Node> ();
430  Ptr<NetDevice> dev = node->GetDevice (incomingIf);
431  uint32_t recvInterfaceIndex = m_ipv4->GetInterfaceForDevice (dev);
432 
433  if (m_interfaceExclusions.find (recvInterfaceIndex) != m_interfaceExclusions.end ())
434  {
435  return;
436  }
437 
438 
439  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
440  Ipv4Address senderIfaceAddr = inetSourceAddr.GetIpv4 ();
441 
442  int32_t interfaceForAddress = m_ipv4->GetInterfaceForAddress (senderIfaceAddr);
443  if (interfaceForAddress != -1)
444  {
445  NS_LOG_LOGIC ("Ignoring a packet sent by myself.");
446  return;
447  }
448 
449  Ipv4Address receiverIfaceAddr = m_ipv4->GetAddress (recvInterfaceIndex, 0).GetLocal ();
450  NS_ASSERT (receiverIfaceAddr != Ipv4Address ());
451  NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " received a OLSR packet from "
452  << senderIfaceAddr << " to " << receiverIfaceAddr);
453 
454  // All routing messages are sent from and to port RT_PORT,
455  // so we check it.
456  NS_ASSERT (inetSourceAddr.GetPort () == OLSR_PORT_NUMBER);
457 
458  Ptr<Packet> packet = receivedPacket;
459 
460  olsr::PacketHeader olsrPacketHeader;
461  packet->RemoveHeader (olsrPacketHeader);
462  NS_ASSERT (olsrPacketHeader.GetPacketLength () >= olsrPacketHeader.GetSerializedSize ());
463  uint32_t sizeLeft = olsrPacketHeader.GetPacketLength () - olsrPacketHeader.GetSerializedSize ();
464 
465  MessageList messages;
466 
467  while (sizeLeft)
468  {
469  MessageHeader messageHeader;
470  if (packet->RemoveHeader (messageHeader) == 0)
471  {
472  NS_ASSERT (false);
473  }
474 
475  sizeLeft -= messageHeader.GetSerializedSize ();
476 
477  NS_LOG_DEBUG ("Olsr Msg received with type "
478  << std::dec << int (messageHeader.GetMessageType ())
479  << " TTL=" << int (messageHeader.GetTimeToLive ())
480  << " origAddr=" << messageHeader.GetOriginatorAddress ());
481  messages.push_back (messageHeader);
482  }
483 
484  m_rxPacketTrace (olsrPacketHeader, messages);
485 
486  for (MessageList::const_iterator messageIter = messages.begin ();
487  messageIter != messages.end (); messageIter++)
488  {
489  const MessageHeader &messageHeader = *messageIter;
490  // If ttl is less than or equal to zero, or
491  // the receiver is the same as the originator,
492  // the message must be silently dropped
493  if (messageHeader.GetTimeToLive () == 0
494  || messageHeader.GetOriginatorAddress () == m_mainAddress)
495  {
496  packet->RemoveAtStart (messageHeader.GetSerializedSize ()
497  - messageHeader.GetSerializedSize ());
498  continue;
499  }
500 
501  // If the message has been processed it must not be processed again
502  bool do_forwarding = true;
504  (messageHeader.GetOriginatorAddress (),
505  messageHeader.GetMessageSequenceNumber ());
506 
507  // Get main address of the peer, which may be different from the packet source address
508 // const IfaceAssocTuple *ifaceAssoc = m_state.FindIfaceAssocTuple (inetSourceAddr.GetIpv4 ());
509 // Ipv4Address peerMainAddress;
510 // if (ifaceAssoc != NULL)
511 // {
512 // peerMainAddress = ifaceAssoc->mainAddr;
513 // }
514 // else
515 // {
516 // peerMainAddress = inetSourceAddr.GetIpv4 () ;
517 // }
518 
519  if (duplicated == NULL)
520  {
521  switch (messageHeader.GetMessageType ())
522  {
525  << " OLSR node " << m_mainAddress
526  << " received HELLO message of size " << messageHeader.GetSerializedSize ());
527  ProcessHello (messageHeader, receiverIfaceAddr, senderIfaceAddr);
528  break;
529 
532  << " OLSR node " << m_mainAddress
533  << " received TC message of size " << messageHeader.GetSerializedSize ());
534  ProcessTc (messageHeader, senderIfaceAddr);
535  break;
536 
539  << " OLSR node " << m_mainAddress
540  << " received MID message of size " << messageHeader.GetSerializedSize ());
541  ProcessMid (messageHeader, senderIfaceAddr);
542  break;
545  << " OLSR node " << m_mainAddress
546  << " received HNA message of size " << messageHeader.GetSerializedSize ());
547  ProcessHna (messageHeader, senderIfaceAddr);
548  break;
549 
550  default:
551  NS_LOG_DEBUG ("OLSR message type " <<
552  int (messageHeader.GetMessageType ()) <<
553  " not implemented");
554  }
555  }
556  else
557  {
558  NS_LOG_DEBUG ("OLSR message is duplicated, not reading it.");
559 
560  // If the message has been considered for forwarding, it should
561  // not be retransmitted again
562  for (std::vector<Ipv4Address>::const_iterator it = duplicated->ifaceList.begin ();
563  it != duplicated->ifaceList.end (); it++)
564  {
565  if (*it == receiverIfaceAddr)
566  {
567  do_forwarding = false;
568  break;
569  }
570  }
571  }
572 
573  if (do_forwarding)
574  {
575  // HELLO messages are never forwarded.
576  // TC and MID messages are forwarded using the default algorithm.
577  // Remaining messages are also forwarded using the default algorithm.
578  if (messageHeader.GetMessageType () != olsr::MessageHeader::HELLO_MESSAGE)
579  {
580  ForwardDefault (messageHeader, duplicated,
581  receiverIfaceAddr, inetSourceAddr.GetIpv4 ());
582  }
583  }
584  }
585 
586  // After processing all OLSR messages, we must recompute the routing table
588 }
589 
596 int
598 {
599  int degree = 0;
600  for (TwoHopNeighborSet::const_iterator it = m_state.GetTwoHopNeighbors ().begin ();
601  it != m_state.GetTwoHopNeighbors ().end (); it++)
602  {
603  TwoHopNeighborTuple const &nb2hop_tuple = *it;
604  if (nb2hop_tuple.neighborMainAddr == tuple.neighborMainAddr)
605  {
606  const NeighborTuple *nb_tuple =
608  if (nb_tuple == NULL)
609  {
610  degree++;
611  }
612  }
613  }
614  return degree;
615 }
616 
617 namespace {
625 void
627 {
628  // first gather all 2-hop neighbors to be removed
629  std::set<Ipv4Address> toRemove;
630  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
631  {
632  if (twoHopNeigh->neighborMainAddr == neighborMainAddr)
633  {
634  toRemove.insert (twoHopNeigh->twoHopNeighborAddr);
635  }
636  }
637  // Now remove all matching records from N2
638  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); )
639  {
640  if (toRemove.find (twoHopNeigh->twoHopNeighborAddr) != toRemove.end ())
641  {
642  twoHopNeigh = N2.erase (twoHopNeigh);
643  }
644  else
645  {
646  twoHopNeigh++;
647  }
648  }
649 }
650 } // unnamed namespace
651 
652 void
654 {
655  NS_LOG_FUNCTION (this);
656 
657  // MPR computation should be done for each interface. See section 8.3.1
658  // (RFC 3626) for details.
659  MprSet mprSet;
660 
661  // N is the subset of neighbors of the node, which are
662  // neighbor "of the interface I"
663  NeighborSet N;
664  for (NeighborSet::const_iterator neighbor = m_state.GetNeighbors ().begin ();
665  neighbor != m_state.GetNeighbors ().end (); neighbor++)
666  {
667  if (neighbor->status == NeighborTuple::STATUS_SYM) // I think that we need this check
668  {
669  N.push_back (*neighbor);
670  }
671  }
672 
673  // N2 is the set of 2-hop neighbors reachable from "the interface
674  // I", excluding:
675  // (i) the nodes only reachable by members of N with willingness WILL_NEVER
676  // (ii) the node performing the computation
677  // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
678  // link to this node on some interface.
680  for (TwoHopNeighborSet::const_iterator twoHopNeigh = m_state.GetTwoHopNeighbors ().begin ();
681  twoHopNeigh != m_state.GetTwoHopNeighbors ().end (); twoHopNeigh++)
682  {
683  // excluding:
684  // (ii) the node performing the computation
685  if (twoHopNeigh->twoHopNeighborAddr == m_mainAddress)
686  {
687  continue;
688  }
689 
690  // excluding:
691  // (i) the nodes only reachable by members of N with willingness WILL_NEVER
692  bool ok = false;
693  for (NeighborSet::const_iterator neigh = N.begin ();
694  neigh != N.end (); neigh++)
695  {
696  if (neigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
697  {
698  if (neigh->willingness == OLSR_WILL_NEVER)
699  {
700  ok = false;
701  break;
702  }
703  else
704  {
705  ok = true;
706  break;
707  }
708  }
709  }
710  if (!ok)
711  {
712  continue;
713  }
714 
715  // excluding:
716  // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
717  // link to this node on some interface.
718  for (NeighborSet::const_iterator neigh = N.begin ();
719  neigh != N.end (); neigh++)
720  {
721  if (neigh->neighborMainAddr == twoHopNeigh->twoHopNeighborAddr)
722  {
723  ok = false;
724  break;
725  }
726  }
727 
728  if (ok)
729  {
730  N2.push_back (*twoHopNeigh);
731  }
732  }
733 
734 #ifdef NS3_LOG_ENABLE
735  {
736  std::ostringstream os;
737  os << "[";
738  for (TwoHopNeighborSet::const_iterator iter = N2.begin ();
739  iter != N2.end (); iter++)
740  {
741  TwoHopNeighborSet::const_iterator next = iter;
742  next++;
743  os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
744  if (next != N2.end ())
745  {
746  os << ", ";
747  }
748  }
749  os << "]";
750  NS_LOG_DEBUG ("N2: " << os.str ());
751  }
752 #endif //NS3_LOG_ENABLE
753 
754  // 1. Start with an MPR set made of all members of N with
755  // N_willingness equal to WILL_ALWAYS
756  for (NeighborSet::const_iterator neighbor = N.begin (); neighbor != N.end (); neighbor++)
757  {
758  if (neighbor->willingness == OLSR_WILL_ALWAYS)
759  {
760  mprSet.insert (neighbor->neighborMainAddr);
761  // (not in RFC but I think is needed: remove the 2-hop
762  // neighbors reachable by the MPR from N2)
763  CoverTwoHopNeighbors (neighbor->neighborMainAddr, N2);
764  }
765  }
766 
767  // 2. Calculate D(y), where y is a member of N, for all nodes in N.
768  // (we do this later)
769 
770  // 3. Add to the MPR set those nodes in N, which are the *only*
771  // nodes to provide reachability to a node in N2.
772  std::set<Ipv4Address> coveredTwoHopNeighbors;
773  for (TwoHopNeighborSet::const_iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
774  {
775  bool onlyOne = true;
776  // try to find another neighbor that can reach twoHopNeigh->twoHopNeighborAddr
777  for (TwoHopNeighborSet::const_iterator otherTwoHopNeigh = N2.begin (); otherTwoHopNeigh != N2.end (); otherTwoHopNeigh++)
778  {
779  if (otherTwoHopNeigh->twoHopNeighborAddr == twoHopNeigh->twoHopNeighborAddr
780  && otherTwoHopNeigh->neighborMainAddr != twoHopNeigh->neighborMainAddr)
781  {
782  onlyOne = false;
783  break;
784  }
785  }
786  if (onlyOne)
787  {
788  NS_LOG_LOGIC ("Neighbor " << twoHopNeigh->neighborMainAddr
789  << " is the only that can reach 2-hop neigh. "
790  << twoHopNeigh->twoHopNeighborAddr
791  << " => select as MPR.");
792 
793  mprSet.insert (twoHopNeigh->neighborMainAddr);
794 
795  // take note of all the 2-hop neighbors reachable by the newly elected MPR
796  for (TwoHopNeighborSet::const_iterator otherTwoHopNeigh = N2.begin ();
797  otherTwoHopNeigh != N2.end (); otherTwoHopNeigh++)
798  {
799  if (otherTwoHopNeigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
800  {
801  coveredTwoHopNeighbors.insert (otherTwoHopNeigh->twoHopNeighborAddr);
802  }
803  }
804  }
805  }
806  // Remove the nodes from N2 which are now covered by a node in the MPR set.
807  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
808  twoHopNeigh != N2.end (); )
809  {
810  if (coveredTwoHopNeighbors.find (twoHopNeigh->twoHopNeighborAddr) != coveredTwoHopNeighbors.end ())
811  {
812  // This works correctly only because it is known that twoHopNeigh is reachable by exactly one neighbor,
813  // so only one record in N2 exists for each of them. This record is erased here.
814  NS_LOG_LOGIC ("2-hop neigh. " << twoHopNeigh->twoHopNeighborAddr << " is already covered by an MPR.");
815  twoHopNeigh = N2.erase (twoHopNeigh);
816  }
817  else
818  {
819  twoHopNeigh++;
820  }
821  }
822 
823  // 4. While there exist nodes in N2 which are not covered by at
824  // least one node in the MPR set:
825  while (N2.begin () != N2.end ())
826  {
827 
828 #ifdef NS3_LOG_ENABLE
829  {
830  std::ostringstream os;
831  os << "[";
832  for (TwoHopNeighborSet::const_iterator iter = N2.begin ();
833  iter != N2.end (); iter++)
834  {
835  TwoHopNeighborSet::const_iterator next = iter;
836  next++;
837  os << iter->neighborMainAddr << "->" << iter->twoHopNeighborAddr;
838  if (next != N2.end ())
839  {
840  os << ", ";
841  }
842  }
843  os << "]";
844  NS_LOG_DEBUG ("Step 4 iteration: N2=" << os.str ());
845  }
846 #endif //NS3_LOG_ENABLE
847 
848 
849  // 4.1. For each node in N, calculate the reachability, i.e., the
850  // number of nodes in N2 which are not yet covered by at
851  // least one node in the MPR set, and which are reachable
852  // through this 1-hop neighbor
853  std::map<int, std::vector<const NeighborTuple *> > reachability;
854  std::set<int> rs;
855  for (NeighborSet::iterator it = N.begin (); it != N.end (); it++)
856  {
857  NeighborTuple const &nb_tuple = *it;
858  int r = 0;
859  for (TwoHopNeighborSet::iterator it2 = N2.begin (); it2 != N2.end (); it2++)
860  {
861  TwoHopNeighborTuple const &nb2hop_tuple = *it2;
862  if (nb_tuple.neighborMainAddr == nb2hop_tuple.neighborMainAddr)
863  {
864  r++;
865  }
866  }
867  rs.insert (r);
868  reachability[r].push_back (&nb_tuple);
869  }
870 
871  // 4.2. Select as a MPR the node with highest N_willingness among
872  // the nodes in N with non-zero reachability. In case of
873  // multiple choice select the node which provides
874  // reachability to the maximum number of nodes in N2. In
875  // case of multiple nodes providing the same amount of
876  // reachability, select the node as MPR whose D(y) is
877  // greater. Remove the nodes from N2 which are now covered
878  // by a node in the MPR set.
879  NeighborTuple const *max = NULL;
880  int max_r = 0;
881  for (std::set<int>::iterator it = rs.begin (); it != rs.end (); it++)
882  {
883  int r = *it;
884  if (r == 0)
885  {
886  continue;
887  }
888  for (std::vector<const NeighborTuple *>::iterator it2 = reachability[r].begin ();
889  it2 != reachability[r].end (); it2++)
890  {
891  const NeighborTuple *nb_tuple = *it2;
892  if (max == NULL || nb_tuple->willingness > max->willingness)
893  {
894  max = nb_tuple;
895  max_r = r;
896  }
897  else if (nb_tuple->willingness == max->willingness)
898  {
899  if (r > max_r)
900  {
901  max = nb_tuple;
902  max_r = r;
903  }
904  else if (r == max_r)
905  {
906  if (Degree (*nb_tuple) > Degree (*max))
907  {
908  max = nb_tuple;
909  max_r = r;
910  }
911  }
912  }
913  }
914  }
915 
916  if (max != NULL)
917  {
918  mprSet.insert (max->neighborMainAddr);
919  CoverTwoHopNeighbors (max->neighborMainAddr, N2);
920  NS_LOG_LOGIC (N2.size () << " 2-hop neighbors left to cover!");
921  }
922  }
923 
924 #ifdef NS3_LOG_ENABLE
925  {
926  std::ostringstream os;
927  os << "[";
928  for (MprSet::const_iterator iter = mprSet.begin ();
929  iter != mprSet.end (); iter++)
930  {
931  MprSet::const_iterator next = iter;
932  next++;
933  os << *iter;
934  if (next != mprSet.end ())
935  {
936  os << ", ";
937  }
938  }
939  os << "]";
940  NS_LOG_DEBUG ("Computed MPR set for node " << m_mainAddress << ": " << os.str ());
941  }
942 #endif //NS3_LOG_ENABLE
943 
944  m_state.SetMprSet (mprSet);
945 }
946 
949 {
950  const IfaceAssocTuple *tuple =
951  m_state.FindIfaceAssocTuple (iface_addr);
952 
953  if (tuple != NULL)
954  {
955  return tuple->mainAddr;
956  }
957  else
958  {
959  return iface_addr;
960  }
961 }
962 
963 void
965 {
966  NS_LOG_DEBUG (Simulator::Now ().As (Time::S) << " : Node " << m_mainAddress
967  << ": RoutingTableComputation begin...");
968 
969  // 1. All the entries from the routing table are removed.
970  Clear ();
971 
972  // 2. The new routing entries are added starting with the
973  // symmetric neighbors (h=1) as the destination nodes.
974  const NeighborSet &neighborSet = m_state.GetNeighbors ();
975  for (NeighborSet::const_iterator it = neighborSet.begin ();
976  it != neighborSet.end (); it++)
977  {
978  NeighborTuple const &nb_tuple = *it;
979  NS_LOG_DEBUG ("Looking at neighbor tuple: " << nb_tuple);
980  if (nb_tuple.status == NeighborTuple::STATUS_SYM)
981  {
982  bool nb_main_addr = false;
983  const LinkTuple *lt = NULL;
984  const LinkSet &linkSet = m_state.GetLinks ();
985  for (LinkSet::const_iterator it2 = linkSet.begin ();
986  it2 != linkSet.end (); it2++)
987  {
988  LinkTuple const &link_tuple = *it2;
989  NS_LOG_DEBUG ("Looking at link tuple: " << link_tuple
990  << (link_tuple.time >= Simulator::Now () ? "" : " (expired)"));
991  if ((GetMainAddress (link_tuple.neighborIfaceAddr) == nb_tuple.neighborMainAddr)
992  && link_tuple.time >= Simulator::Now ())
993  {
994  NS_LOG_LOGIC ("Link tuple matches neighbor " << nb_tuple.neighborMainAddr
995  << " => adding routing table entry to neighbor");
996  lt = &link_tuple;
997  AddEntry (link_tuple.neighborIfaceAddr,
998  link_tuple.neighborIfaceAddr,
999  link_tuple.localIfaceAddr,
1000  1);
1001  if (link_tuple.neighborIfaceAddr == nb_tuple.neighborMainAddr)
1002  {
1003  nb_main_addr = true;
1004  }
1005  }
1006  else
1007  {
1008  NS_LOG_LOGIC ("Link tuple: linkMainAddress= " << GetMainAddress (link_tuple.neighborIfaceAddr)
1009  << "; neighborMainAddr = " << nb_tuple.neighborMainAddr
1010  << "; expired=" << int (link_tuple.time < Simulator::Now ())
1011  << " => IGNORE");
1012  }
1013  }
1014 
1015  // If, in the above, no R_dest_addr is equal to the main
1016  // address of the neighbor, then another new routing entry
1017  // with MUST be added, with:
1018  // R_dest_addr = main address of the neighbor;
1019  // R_next_addr = L_neighbor_iface_addr of one of the
1020  // associated link tuple with L_time >= current time;
1021  // R_dist = 1;
1022  // R_iface_addr = L_local_iface_addr of the
1023  // associated link tuple.
1024  if (!nb_main_addr && lt != NULL)
1025  {
1026  NS_LOG_LOGIC ("no R_dest_addr is equal to the main address of the neighbor "
1027  "=> adding additional routing entry");
1028  AddEntry (nb_tuple.neighborMainAddr,
1029  lt->neighborIfaceAddr,
1030  lt->localIfaceAddr,
1031  1);
1032  }
1033  }
1034  }
1035 
1036  // 3. for each node in N2, i.e., a 2-hop neighbor which is not a
1037  // neighbor node or the node itself, and such that there exist at
1038  // least one entry in the 2-hop neighbor set where
1039  // N_neighbor_main_addr correspond to a neighbor node with
1040  // willingness different of WILL_NEVER,
1041  const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
1042  for (TwoHopNeighborSet::const_iterator it = twoHopNeighbors.begin ();
1043  it != twoHopNeighbors.end (); it++)
1044  {
1045  TwoHopNeighborTuple const &nb2hop_tuple = *it;
1046 
1047  NS_LOG_LOGIC ("Looking at two-hop neighbor tuple: " << nb2hop_tuple);
1048 
1049  // a 2-hop neighbor which is not a neighbor node or the node itself
1050  if (m_state.FindSymNeighborTuple (nb2hop_tuple.twoHopNeighborAddr))
1051  {
1052  NS_LOG_LOGIC ("Two-hop neighbor tuple is also neighbor; skipped.");
1053  continue;
1054  }
1055 
1056  if (nb2hop_tuple.twoHopNeighborAddr == m_mainAddress)
1057  {
1058  NS_LOG_LOGIC ("Two-hop neighbor is self; skipped.");
1059  continue;
1060  }
1061 
1062  // ...and such that there exist at least one entry in the 2-hop
1063  // neighbor set where N_neighbor_main_addr correspond to a
1064  // neighbor node with willingness different of WILL_NEVER...
1065  bool nb2hopOk = false;
1066  for (NeighborSet::const_iterator neighbor = neighborSet.begin ();
1067  neighbor != neighborSet.end (); neighbor++)
1068  {
1069  if (neighbor->neighborMainAddr == nb2hop_tuple.neighborMainAddr
1070  && neighbor->willingness != OLSR_WILL_NEVER)
1071  {
1072  nb2hopOk = true;
1073  break;
1074  }
1075  }
1076  if (!nb2hopOk)
1077  {
1078  NS_LOG_LOGIC ("Two-hop neighbor tuple skipped: 2-hop neighbor "
1079  << nb2hop_tuple.twoHopNeighborAddr
1080  << " is attached to neighbor " << nb2hop_tuple.neighborMainAddr
1081  << ", which was not found in the Neighbor Set.");
1082  continue;
1083  }
1084 
1085  // one selects one 2-hop tuple and creates one entry in the routing table with:
1086  // R_dest_addr = the main address of the 2-hop neighbor;
1087  // R_next_addr = the R_next_addr of the entry in the
1088  // routing table with:
1089  // R_dest_addr == N_neighbor_main_addr
1090  // of the 2-hop tuple;
1091  // R_dist = 2;
1092  // R_iface_addr = the R_iface_addr of the entry in the
1093  // routing table with:
1094  // R_dest_addr == N_neighbor_main_addr
1095  // of the 2-hop tuple;
1096  RoutingTableEntry entry;
1097  bool foundEntry = Lookup (nb2hop_tuple.neighborMainAddr, entry);
1098  if (foundEntry)
1099  {
1100  NS_LOG_LOGIC ("Adding routing entry for two-hop neighbor.");
1101  AddEntry (nb2hop_tuple.twoHopNeighborAddr,
1102  entry.nextAddr,
1103  entry.interface,
1104  2);
1105  }
1106  else
1107  {
1108  NS_LOG_LOGIC ("NOT adding routing entry for two-hop neighbor ("
1109  << nb2hop_tuple.twoHopNeighborAddr
1110  << " not found in the routing table)");
1111  }
1112  }
1113 
1114  for (uint32_t h = 2;; h++)
1115  {
1116  bool added = false;
1117 
1118  // 3.1. For each topology entry in the topology table, if its
1119  // T_dest_addr does not correspond to R_dest_addr of any
1120  // route entry in the routing table AND its T_last_addr
1121  // corresponds to R_dest_addr of a route entry whose R_dist
1122  // is equal to h, then a new route entry MUST be recorded in
1123  // the routing table (if it does not already exist)
1124  const TopologySet &topology = m_state.GetTopologySet ();
1125  for (TopologySet::const_iterator it = topology.begin ();
1126  it != topology.end (); it++)
1127  {
1128  const TopologyTuple &topology_tuple = *it;
1129  NS_LOG_LOGIC ("Looking at topology tuple: " << topology_tuple);
1130 
1131  RoutingTableEntry destAddrEntry, lastAddrEntry;
1132  bool have_destAddrEntry = Lookup (topology_tuple.destAddr, destAddrEntry);
1133  bool have_lastAddrEntry = Lookup (topology_tuple.lastAddr, lastAddrEntry);
1134  if (!have_destAddrEntry && have_lastAddrEntry && lastAddrEntry.distance == h)
1135  {
1136  NS_LOG_LOGIC ("Adding routing table entry based on the topology tuple.");
1137  // then a new route entry MUST be recorded in
1138  // the routing table (if it does not already exist) where:
1139  // R_dest_addr = T_dest_addr;
1140  // R_next_addr = R_next_addr of the recorded
1141  // route entry where:
1142  // R_dest_addr == T_last_addr
1143  // R_dist = h+1; and
1144  // R_iface_addr = R_iface_addr of the recorded
1145  // route entry where:
1146  // R_dest_addr == T_last_addr.
1147  AddEntry (topology_tuple.destAddr,
1148  lastAddrEntry.nextAddr,
1149  lastAddrEntry.interface,
1150  h + 1);
1151  added = true;
1152  }
1153  else
1154  {
1155  NS_LOG_LOGIC ("NOT adding routing table entry based on the topology tuple: "
1156  "have_destAddrEntry=" << have_destAddrEntry
1157  << " have_lastAddrEntry=" << have_lastAddrEntry
1158  << " lastAddrEntry.distance=" << (int) lastAddrEntry.distance
1159  << " (h=" << h << ")");
1160  }
1161  }
1162 
1163  if (!added)
1164  {
1165  break;
1166  }
1167  }
1168 
1169  // 4. For each entry in the multiple interface association base
1170  // where there exists a routing entry such that:
1171  // R_dest_addr == I_main_addr (of the multiple interface association entry)
1172  // AND there is no routing entry such that:
1173  // R_dest_addr == I_iface_addr
1174  const IfaceAssocSet &ifaceAssocSet = m_state.GetIfaceAssocSet ();
1175  for (IfaceAssocSet::const_iterator it = ifaceAssocSet.begin ();
1176  it != ifaceAssocSet.end (); it++)
1177  {
1178  IfaceAssocTuple const &tuple = *it;
1179  RoutingTableEntry entry1, entry2;
1180  bool have_entry1 = Lookup (tuple.mainAddr, entry1);
1181  bool have_entry2 = Lookup (tuple.ifaceAddr, entry2);
1182  if (have_entry1 && !have_entry2)
1183  {
1184  // then a route entry is created in the routing table with:
1185  // R_dest_addr = I_iface_addr (of the multiple interface
1186  // association entry)
1187  // R_next_addr = R_next_addr (of the recorded route entry)
1188  // R_dist = R_dist (of the recorded route entry)
1189  // R_iface_addr = R_iface_addr (of the recorded route entry).
1190  AddEntry (tuple.ifaceAddr,
1191  entry1.nextAddr,
1192  entry1.interface,
1193  entry1.distance);
1194  }
1195  }
1196 
1197  // 5. For each tuple in the association set,
1198  // If there is no entry in the routing table with:
1199  // R_dest_addr == A_network_addr/A_netmask
1200  // and if the announced network is not announced by the node itself,
1201  // then a new routing entry is created.
1202  const AssociationSet &associationSet = m_state.GetAssociationSet ();
1203 
1204  // Clear HNA routing table
1205  for (uint32_t i = 0; i < m_hnaRoutingTable->GetNRoutes (); i++)
1206  {
1207  m_hnaRoutingTable->RemoveRoute (0);
1208  }
1209 
1210  for (AssociationSet::const_iterator it = associationSet.begin ();
1211  it != associationSet.end (); it++)
1212  {
1213  AssociationTuple const &tuple = *it;
1214 
1215  // Test if HNA associations received from other gateways
1216  // are also announced by this node. In such a case, no route
1217  // is created for this association tuple (go to the next one).
1218  bool goToNextAssociationTuple = false;
1219  const Associations &localHnaAssociations = m_state.GetAssociations ();
1220  NS_LOG_DEBUG ("Nb local associations: " << localHnaAssociations.size ());
1221  for (Associations::const_iterator assocIterator = localHnaAssociations.begin ();
1222  assocIterator != localHnaAssociations.end (); assocIterator++)
1223  {
1224  Association const &localHnaAssoc = *assocIterator;
1225  if (localHnaAssoc.networkAddr == tuple.networkAddr && localHnaAssoc.netmask == tuple.netmask)
1226  {
1227  NS_LOG_DEBUG ("HNA association received from another GW is part of local HNA associations: no route added for network "
1228  << tuple.networkAddr << "/" << tuple.netmask);
1229  goToNextAssociationTuple = true;
1230  }
1231  }
1232  if (goToNextAssociationTuple)
1233  {
1234  continue;
1235  }
1236 
1237  RoutingTableEntry gatewayEntry;
1238 
1239  bool gatewayEntryExists = Lookup (tuple.gatewayAddr, gatewayEntry);
1240  bool addRoute = false;
1241 
1242  uint32_t routeIndex = 0;
1243 
1244  for (routeIndex = 0; routeIndex < m_hnaRoutingTable->GetNRoutes (); routeIndex++)
1245  {
1246  Ipv4RoutingTableEntry route = m_hnaRoutingTable->GetRoute (routeIndex);
1247  if (route.GetDestNetwork () == tuple.networkAddr
1248  && route.GetDestNetworkMask () == tuple.netmask)
1249  {
1250  break;
1251  }
1252  }
1253 
1254  if (routeIndex == m_hnaRoutingTable->GetNRoutes ())
1255  {
1256  addRoute = true;
1257  }
1258  else if (gatewayEntryExists && m_hnaRoutingTable->GetMetric (routeIndex) > gatewayEntry.distance)
1259  {
1260  m_hnaRoutingTable->RemoveRoute (routeIndex);
1261  addRoute = true;
1262  }
1263 
1264  if (addRoute && gatewayEntryExists)
1265  {
1266  m_hnaRoutingTable->AddNetworkRouteTo (tuple.networkAddr,
1267  tuple.netmask,
1268  gatewayEntry.nextAddr,
1269  gatewayEntry.interface,
1270  gatewayEntry.distance);
1271 
1272  }
1273  }
1274 
1275  NS_LOG_DEBUG ("Node " << m_mainAddress << ": RoutingTableComputation end.");
1277 }
1278 
1279 
1280 void
1282  const Ipv4Address &receiverIface,
1283  const Ipv4Address &senderIface)
1284 {
1285  NS_LOG_FUNCTION (msg << receiverIface << senderIface);
1286 
1287  const olsr::MessageHeader::Hello &hello = msg.GetHello ();
1288 
1289  LinkSensing (msg, hello, receiverIface, senderIface);
1290 
1291 #ifdef NS3_LOG_ENABLE
1292  {
1293  const LinkSet &links = m_state.GetLinks ();
1295  << " ** BEGIN dump Link Set for OLSR Node " << m_mainAddress);
1296  for (LinkSet::const_iterator link = links.begin (); link != links.end (); link++)
1297  {
1298  NS_LOG_DEBUG (*link);
1299  }
1300  NS_LOG_DEBUG ("** END dump Link Set for OLSR Node " << m_mainAddress);
1301 
1302  const NeighborSet &neighbors = m_state.GetNeighbors ();
1304  << " ** BEGIN dump Neighbor Set for OLSR Node " << m_mainAddress);
1305  for (NeighborSet::const_iterator neighbor = neighbors.begin (); neighbor != neighbors.end (); neighbor++)
1306  {
1307  NS_LOG_DEBUG (*neighbor);
1308  }
1309  NS_LOG_DEBUG ("** END dump Neighbor Set for OLSR Node " << m_mainAddress);
1310  }
1311 #endif // NS3_LOG_ENABLE
1312 
1313  PopulateNeighborSet (msg, hello);
1314  PopulateTwoHopNeighborSet (msg, hello);
1315 
1316 #ifdef NS3_LOG_ENABLE
1317  {
1318  const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
1320  << " ** BEGIN dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
1321  for (TwoHopNeighborSet::const_iterator tuple = twoHopNeighbors.begin ();
1322  tuple != twoHopNeighbors.end (); tuple++)
1323  {
1324  NS_LOG_DEBUG (*tuple);
1325  }
1326  NS_LOG_DEBUG ("** END dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
1327  }
1328 #endif // NS3_LOG_ENABLE
1329 
1330  MprComputation ();
1331  PopulateMprSelectorSet (msg, hello);
1332 }
1333 
1334 void
1336  const Ipv4Address &senderIface)
1337 {
1338  const olsr::MessageHeader::Tc &tc = msg.GetTc ();
1339  Time now = Simulator::Now ();
1340 
1341  // 1. If the sender interface of this message is not in the symmetric
1342  // 1-hop neighborhood of this node, the message MUST be discarded.
1343  const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
1344  if (link_tuple == NULL)
1345  {
1346  return;
1347  }
1348 
1349  // 2. If there exist some tuple in the topology set where:
1350  // T_last_addr == originator address AND
1351  // T_seq > ANSN,
1352  // then further processing of this TC message MUST NOT be
1353  // performed.
1354  const TopologyTuple *topologyTuple =
1356  if (topologyTuple != NULL)
1357  {
1358  return;
1359  }
1360 
1361  // 3. All tuples in the topology set where:
1362  // T_last_addr == originator address AND
1363  // T_seq < ANSN
1364  // MUST be removed from the topology set.
1366 
1367  // 4. For each of the advertised neighbor main address received in
1368  // the TC message:
1369  for (std::vector<Ipv4Address>::const_iterator i = tc.neighborAddresses.begin ();
1370  i != tc.neighborAddresses.end (); i++)
1371  {
1372  const Ipv4Address &addr = *i;
1373  // 4.1. If there exist some tuple in the topology set where:
1374  // T_dest_addr == advertised neighbor main address, AND
1375  // T_last_addr == originator address,
1376  // then the holding time of that tuple MUST be set to:
1377  // T_time = current time + validity time.
1378  TopologyTuple *topologyTuple =
1380 
1381  if (topologyTuple != NULL)
1382  {
1383  topologyTuple->expirationTime = now + msg.GetVTime ();
1384  }
1385  else
1386  {
1387  // 4.2. Otherwise, a new tuple MUST be recorded in the topology
1388  // set where:
1389  // T_dest_addr = advertised neighbor main address,
1390  // T_last_addr = originator address,
1391  // T_seq = ANSN,
1392  // T_time = current time + validity time.
1393  TopologyTuple topologyTuple;
1394  topologyTuple.destAddr = addr;
1395  topologyTuple.lastAddr = msg.GetOriginatorAddress ();
1396  topologyTuple.sequenceNumber = tc.ansn;
1397  topologyTuple.expirationTime = now + msg.GetVTime ();
1398  AddTopologyTuple (topologyTuple);
1399 
1400  // Schedules topology tuple deletion
1403  this,
1404  topologyTuple.destAddr,
1405  topologyTuple.lastAddr));
1406  }
1407  }
1408 
1409 #ifdef NS3_LOG_ENABLE
1410  {
1411  const TopologySet &topology = m_state.GetTopologySet ();
1413  << " ** BEGIN dump TopologySet for OLSR Node " << m_mainAddress);
1414  for (TopologySet::const_iterator tuple = topology.begin ();
1415  tuple != topology.end (); tuple++)
1416  {
1417  NS_LOG_DEBUG (*tuple);
1418  }
1419  NS_LOG_DEBUG ("** END dump TopologySet Set for OLSR Node " << m_mainAddress);
1420  }
1421 #endif // NS3_LOG_ENABLE
1422 }
1423 
1424 void
1426  const Ipv4Address &senderIface)
1427 {
1428  const olsr::MessageHeader::Mid &mid = msg.GetMid ();
1429  Time now = Simulator::Now ();
1430 
1431  NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface);
1432  // 1. If the sender interface of this message is not in the symmetric
1433  // 1-hop neighborhood of this node, the message MUST be discarded.
1434  const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderIface, now);
1435  if (linkTuple == NULL)
1436  {
1437  NS_LOG_LOGIC ("Node " << m_mainAddress <<
1438  ": the sender interface of this message is not in the "
1439  "symmetric 1-hop neighborhood of this node,"
1440  " the message MUST be discarded.");
1441  return;
1442  }
1443 
1444  // 2. For each interface address listed in the MID message
1445  for (std::vector<Ipv4Address>::const_iterator i = mid.interfaceAddresses.begin ();
1446  i != mid.interfaceAddresses.end (); i++)
1447  {
1448  bool updated = false;
1450  for (IfaceAssocSet::iterator tuple = ifaceAssoc.begin ();
1451  tuple != ifaceAssoc.end (); tuple++)
1452  {
1453  if (tuple->ifaceAddr == *i
1454  && tuple->mainAddr == msg.GetOriginatorAddress ())
1455  {
1456  NS_LOG_LOGIC ("IfaceAssoc updated: " << *tuple);
1457  tuple->time = now + msg.GetVTime ();
1458  updated = true;
1459  }
1460  }
1461  if (!updated)
1462  {
1463  IfaceAssocTuple tuple;
1464  tuple.ifaceAddr = *i;
1465  tuple.mainAddr = msg.GetOriginatorAddress ();
1466  tuple.time = now + msg.GetVTime ();
1467  AddIfaceAssocTuple (tuple);
1468  NS_LOG_LOGIC ("New IfaceAssoc added: " << tuple);
1469  // Schedules iface association tuple deletion
1470  Simulator::Schedule (DELAY (tuple.time),
1472  }
1473  }
1474 
1475  // 3. (not part of the RFC) iterate over all NeighborTuple's and
1476  // TwoHopNeighborTuples, update the neighbor addresses taking into account
1477  // the new MID information.
1478  NeighborSet &neighbors = m_state.GetNeighbors ();
1479  for (NeighborSet::iterator neighbor = neighbors.begin (); neighbor != neighbors.end (); neighbor++)
1480  {
1481  neighbor->neighborMainAddr = GetMainAddress (neighbor->neighborMainAddr);
1482  }
1483 
1484  TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
1485  for (TwoHopNeighborSet::iterator twoHopNeighbor = twoHopNeighbors.begin ();
1486  twoHopNeighbor != twoHopNeighbors.end (); twoHopNeighbor++)
1487  {
1488  twoHopNeighbor->neighborMainAddr = GetMainAddress (twoHopNeighbor->neighborMainAddr);
1489  twoHopNeighbor->twoHopNeighborAddr = GetMainAddress (twoHopNeighbor->twoHopNeighborAddr);
1490  }
1491  NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface << " -> END.");
1492 }
1493 
1494 void
1496  const Ipv4Address &senderIface)
1497 {
1498 
1499  const olsr::MessageHeader::Hna &hna = msg.GetHna ();
1500  Time now = Simulator::Now ();
1501 
1502  // 1. If the sender interface of this message is not in the symmetric
1503  // 1-hop neighborhood of this node, the message MUST be discarded.
1504  const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
1505  if (link_tuple == NULL)
1506  {
1507  return;
1508  }
1509 
1510  // 2. Otherwise, for each (network address, netmask) pair in the
1511  // message:
1512 
1513  for (std::vector<olsr::MessageHeader::Hna::Association>::const_iterator it = hna.associations.begin ();
1514  it != hna.associations.end (); it++)
1515  {
1516  AssociationTuple *tuple = m_state.FindAssociationTuple (msg.GetOriginatorAddress (),it->address,it->mask);
1517 
1518  // 2.1 if an entry in the association set already exists, where:
1519  // A_gateway_addr == originator address
1520  // A_network_addr == network address
1521  // A_netmask == netmask
1522  // then the holding time for that tuple MUST be set to:
1523  // A_time = current time + validity time
1524  if (tuple != NULL)
1525  {
1526  tuple->expirationTime = now + msg.GetVTime ();
1527  }
1528 
1529  // 2.2 otherwise, a new tuple MUST be recorded with:
1530  // A_gateway_addr = originator address
1531  // A_network_addr = network address
1532  // A_netmask = netmask
1533  // A_time = current time + validity time
1534  else
1535  {
1536  AssociationTuple assocTuple = {
1537  msg.GetOriginatorAddress (),
1538  it->address,
1539  it->mask,
1540  now + msg.GetVTime ()
1541  };
1542  AddAssociationTuple (assocTuple);
1543 
1544  //Schedule Association Tuple deletion
1547  assocTuple.gatewayAddr,assocTuple.networkAddr,assocTuple.netmask);
1548  }
1549 
1550  }
1551 }
1552 
1553 void
1555  DuplicateTuple *duplicated,
1556  const Ipv4Address &localIface,
1557  const Ipv4Address &senderAddress)
1558 {
1559  Time now = Simulator::Now ();
1560 
1561  // If the sender interface address is not in the symmetric
1562  // 1-hop neighborhood the message must not be forwarded
1563  const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderAddress, now);
1564  if (linkTuple == NULL)
1565  {
1566  return;
1567  }
1568 
1569  // If the message has already been considered for forwarding,
1570  // it must not be retransmitted again
1571  if (duplicated != NULL && duplicated->retransmitted)
1572  {
1573  NS_LOG_LOGIC (Simulator::Now () << "Node " << m_mainAddress << " does not forward a message received"
1574  " from " << olsrMessage.GetOriginatorAddress () << " because it is duplicated");
1575  return;
1576  }
1577 
1578  // If the sender interface address is an interface address
1579  // of a MPR selector of this node and ttl is greater than 1,
1580  // the message must be retransmitted
1581  bool retransmitted = false;
1582  if (olsrMessage.GetTimeToLive () > 1)
1583  {
1584  const MprSelectorTuple *mprselTuple =
1585  m_state.FindMprSelectorTuple (GetMainAddress (senderAddress));
1586  if (mprselTuple != NULL)
1587  {
1588  olsrMessage.SetTimeToLive (olsrMessage.GetTimeToLive () - 1);
1589  olsrMessage.SetHopCount (olsrMessage.GetHopCount () + 1);
1590  // We have to introduce a random delay to avoid
1591  // synchronization with neighbors.
1592  QueueMessage (olsrMessage, JITTER);
1593  retransmitted = true;
1594  }
1595  }
1596 
1597  // Update duplicate tuple...
1598  if (duplicated != NULL)
1599  {
1600  duplicated->expirationTime = now + OLSR_DUP_HOLD_TIME;
1601  duplicated->retransmitted = retransmitted;
1602  duplicated->ifaceList.push_back (localIface);
1603  }
1604  // ...or create a new one
1605  else
1606  {
1607  DuplicateTuple newDup;
1608  newDup.address = olsrMessage.GetOriginatorAddress ();
1609  newDup.sequenceNumber = olsrMessage.GetMessageSequenceNumber ();
1610  newDup.expirationTime = now + OLSR_DUP_HOLD_TIME;
1611  newDup.retransmitted = retransmitted;
1612  newDup.ifaceList.push_back (localIface);
1613  AddDuplicateTuple (newDup);
1614  // Schedule dup tuple deletion
1617  newDup.address, newDup.sequenceNumber);
1618  }
1619 }
1620 
1621 void
1623 {
1624  m_queuedMessages.push_back (message);
1625  if (not m_queuedMessagesTimer.IsRunning ())
1626  {
1629  }
1630 }
1631 
1632 void
1634  const MessageList &containedMessages)
1635 {
1636  NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " sending a OLSR packet");
1637 
1638  // Add a header
1639  olsr::PacketHeader header;
1640  header.SetPacketLength (header.GetSerializedSize () + packet->GetSize ());
1642  packet->AddHeader (header);
1643 
1644  // Trace it
1645  m_txPacketTrace (header, containedMessages);
1646 
1647  // Send it
1648  for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator i =
1649  m_sendSockets.begin (); i != m_sendSockets.end (); i++)
1650  {
1651  Ptr<Packet> pkt = packet->Copy ();
1652  Ipv4Address bcast = i->second.GetLocal ().GetSubnetDirectedBroadcast (i->second.GetMask ());
1653  i->first->SendTo (pkt, 0, InetSocketAddress (bcast, OLSR_PORT_NUMBER));
1654  }
1655 }
1656 
1657 void
1659 {
1660  Ptr<Packet> packet = Create<Packet> ();
1661  int numMessages = 0;
1662 
1663  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": SendQueuedMessages");
1664 
1665  MessageList msglist;
1666 
1667  for (std::vector<olsr::MessageHeader>::const_iterator message = m_queuedMessages.begin ();
1668  message != m_queuedMessages.end ();
1669  message++)
1670  {
1671  Ptr<Packet> p = Create<Packet> ();
1672  p->AddHeader (*message);
1673  packet->AddAtEnd (p);
1674  msglist.push_back (*message);
1675  if (++numMessages == OLSR_MAX_MSGS)
1676  {
1677  SendPacket (packet, msglist);
1678  msglist.clear ();
1679  // Reset variables for next packet
1680  numMessages = 0;
1681  packet = Create<Packet> ();
1682  }
1683  }
1684 
1685  if (packet->GetSize ())
1686  {
1687  SendPacket (packet, msglist);
1688  }
1689 
1690  m_queuedMessages.clear ();
1691 }
1692 
1693 void
1695 {
1696  NS_LOG_FUNCTION (this);
1697 
1698  olsr::MessageHeader msg;
1699  Time now = Simulator::Now ();
1700 
1703  msg.SetTimeToLive (1);
1704  msg.SetHopCount (0);
1706  olsr::MessageHeader::Hello &hello = msg.GetHello ();
1707 
1708  hello.SetHTime (m_helloInterval);
1709  hello.willingness = m_willingness;
1710 
1711  std::vector<olsr::MessageHeader::Hello::LinkMessage>
1712  &linkMessages = hello.linkMessages;
1713 
1714  const LinkSet &links = m_state.GetLinks ();
1715  for (LinkSet::const_iterator link_tuple = links.begin ();
1716  link_tuple != links.end (); link_tuple++)
1717  {
1718  if (!(GetMainAddress (link_tuple->localIfaceAddr) == m_mainAddress
1719  && link_tuple->time >= now))
1720  {
1721  continue;
1722  }
1723 
1724  uint8_t link_type, nb_type = 0xff;
1725 
1726  // Establishes link type
1727  if (link_tuple->symTime >= now)
1728  {
1729  link_type = OLSR_SYM_LINK;
1730  }
1731  else if (link_tuple->asymTime >= now)
1732  {
1733  link_type = OLSR_ASYM_LINK;
1734  }
1735  else
1736  {
1737  link_type = OLSR_LOST_LINK;
1738  }
1739  // Establishes neighbor type.
1740  if (m_state.FindMprAddress (GetMainAddress (link_tuple->neighborIfaceAddr)))
1741  {
1742  nb_type = OLSR_MPR_NEIGH;
1743  NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1744  << " to be MPR_NEIGH.");
1745  }
1746  else
1747  {
1748  bool ok = false;
1749  for (NeighborSet::const_iterator nb_tuple = m_state.GetNeighbors ().begin ();
1750  nb_tuple != m_state.GetNeighbors ().end ();
1751  nb_tuple++)
1752  {
1753  if (nb_tuple->neighborMainAddr == GetMainAddress (link_tuple->neighborIfaceAddr))
1754  {
1755  if (nb_tuple->status == NeighborTuple::STATUS_SYM)
1756  {
1757  NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1758  << " to be SYM_NEIGH.");
1759  nb_type = OLSR_SYM_NEIGH;
1760  }
1761  else if (nb_tuple->status == NeighborTuple::STATUS_NOT_SYM)
1762  {
1763  nb_type = OLSR_NOT_NEIGH;
1764  NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
1765  << " to be NOT_NEIGH.");
1766  }
1767  else
1768  {
1769  NS_FATAL_ERROR ("There is a neighbor tuple with an unknown status!\n");
1770  }
1771  ok = true;
1772  break;
1773  }
1774  }
1775  if (!ok)
1776  {
1777  NS_LOG_WARN ("I don't know the neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr) << "!!!");
1778  continue;
1779  }
1780  }
1781 
1783  linkMessage.linkCode = (link_type & 0x03) | ((nb_type << 2) & 0x0f);
1784  linkMessage.neighborInterfaceAddresses.push_back
1785  (link_tuple->neighborIfaceAddr);
1786 
1787  std::vector<Ipv4Address> interfaces =
1788  m_state.FindNeighborInterfaces (link_tuple->neighborIfaceAddr);
1789 
1790  linkMessage.neighborInterfaceAddresses.insert
1791  (linkMessage.neighborInterfaceAddresses.end (),
1792  interfaces.begin (), interfaces.end ());
1793 
1794  linkMessages.push_back (linkMessage);
1795  }
1796  NS_LOG_DEBUG ("OLSR HELLO message size: " << int (msg.GetSerializedSize ())
1797  << " (with " << int (linkMessages.size ()) << " link messages)");
1798  QueueMessage (msg, JITTER);
1799 }
1800 
1801 void
1803 {
1804  NS_LOG_FUNCTION (this);
1805 
1806  olsr::MessageHeader msg;
1807 
1810  msg.SetTimeToLive (255);
1811  msg.SetHopCount (0);
1813 
1814  olsr::MessageHeader::Tc &tc = msg.GetTc ();
1815  tc.ansn = m_ansn;
1816 
1817  for (MprSelectorSet::const_iterator mprsel_tuple = m_state.GetMprSelectors ().begin ();
1818  mprsel_tuple != m_state.GetMprSelectors ().end (); mprsel_tuple++)
1819  {
1820  tc.neighborAddresses.push_back (mprsel_tuple->mainAddr);
1821  }
1822  QueueMessage (msg, JITTER);
1823 }
1824 
1825 void
1827 {
1828  olsr::MessageHeader msg;
1829  olsr::MessageHeader::Mid &mid = msg.GetMid ();
1830 
1831  // A node which has only a single interface address participating in
1832  // the MANET (i.e., running OLSR), MUST NOT generate any MID
1833  // message.
1834 
1835  // A node with several interfaces, where only one is participating
1836  // in the MANET and running OLSR (e.g., a node is connected to a
1837  // wired network as well as to a MANET) MUST NOT generate any MID
1838  // messages.
1839 
1840  // A node with several interfaces, where more than one is
1841  // participating in the MANET and running OLSR MUST generate MID
1842  // messages as specified.
1843 
1844  // [ Note: assuming here that all interfaces participate in the
1845  // MANET; later we may want to make this configurable. ]
1846 
1847  Ipv4Address loopback ("127.0.0.1");
1848  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
1849  {
1850  Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
1851  if (addr != m_mainAddress && addr != loopback && m_interfaceExclusions.find (i) == m_interfaceExclusions.end ())
1852  {
1853  mid.interfaceAddresses.push_back (addr);
1854  }
1855  }
1856  if (mid.interfaceAddresses.size () == 0)
1857  {
1858  return;
1859  }
1860 
1863  msg.SetTimeToLive (255);
1864  msg.SetHopCount (0);
1866 
1867  QueueMessage (msg, JITTER);
1868 }
1869 
1870 void
1872 {
1873 
1874  olsr::MessageHeader msg;
1875 
1878  msg.SetTimeToLive (255);
1879  msg.SetHopCount (0);
1881  olsr::MessageHeader::Hna &hna = msg.GetHna ();
1882 
1883  std::vector<olsr::MessageHeader::Hna::Association> &associations = hna.associations;
1884 
1885  // Add all local HNA associations to the HNA message
1886  const Associations &localHnaAssociations = m_state.GetAssociations ();
1887  for (Associations::const_iterator it = localHnaAssociations.begin ();
1888  it != localHnaAssociations.end (); it++)
1889  {
1890  olsr::MessageHeader::Hna::Association assoc = { it->networkAddr, it->netmask};
1891  associations.push_back (assoc);
1892  }
1893  // If there is no HNA associations to send, return without queuing the message
1894  if (associations.size () == 0)
1895  {
1896  return;
1897  }
1898 
1899  // Else, queue the message to be sent later on
1900  QueueMessage (msg, JITTER);
1901 }
1902 
1903 void
1905 {
1906  // Check if the (networkAddr, netmask) tuple already exist
1907  // in the list of local HNA associations
1908  const Associations &localHnaAssociations = m_state.GetAssociations ();
1909  for (Associations::const_iterator assocIterator = localHnaAssociations.begin ();
1910  assocIterator != localHnaAssociations.end (); assocIterator++)
1911  {
1912  Association const &localHnaAssoc = *assocIterator;
1913  if (localHnaAssoc.networkAddr == networkAddr && localHnaAssoc.netmask == netmask)
1914  {
1915  NS_LOG_INFO ("HNA association for network " << networkAddr << "/" << netmask << " already exists.");
1916  return;
1917  }
1918  }
1919  // If the tuple does not already exist, add it to the list of local HNA associations.
1920  NS_LOG_INFO ("Adding HNA association for network " << networkAddr << "/" << netmask << ".");
1921  m_state.InsertAssociation ( (Association) { networkAddr, netmask} );
1922 }
1923 
1924 void
1926 {
1927  NS_LOG_INFO ("Removing HNA association for network " << networkAddr << "/" << netmask << ".");
1928  m_state.EraseAssociation ( (Association) { networkAddr, netmask} );
1929 }
1930 
1931 void
1933 {
1934  // If a routing table has already been associated, remove
1935  // corresponding entries from the list of local HNA associations
1936  if (m_routingTableAssociation != 0)
1937  {
1938  NS_LOG_INFO ("Removing HNA entries coming from the old routing table association.");
1939  for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes (); i++)
1940  {
1941  Ipv4RoutingTableEntry route = m_routingTableAssociation->GetRoute (i);
1942  // If the outgoing interface for this route is a non-olsr interface
1943  if (UsesNonOlsrOutgoingInterface (route))
1944  {
1945  // remove the corresponding entry
1947  }
1948  }
1949  }
1950 
1951  // Sets the routingTableAssociation to its new value
1952  m_routingTableAssociation = routingTable;
1953 
1954  // Iterate over entries of the associated routing table and
1955  // add the routes using non-olsr outgoing interfaces to the list
1956  // of local HNA associations
1957  NS_LOG_DEBUG ("Nb local associations before adding some entries from"
1958  " the associated routing table: " << m_state.GetAssociations ().size ());
1959  for (uint32_t i = 0; i < m_routingTableAssociation->GetNRoutes (); i++)
1960  {
1961  Ipv4RoutingTableEntry route = m_routingTableAssociation->GetRoute (i);
1962  Ipv4Address destNetworkAddress = route.GetDestNetwork ();
1963  Ipv4Mask destNetmask = route.GetDestNetworkMask ();
1964 
1965  // If the outgoing interface for this route is a non-olsr interface,
1966  if (UsesNonOlsrOutgoingInterface (route))
1967  {
1968  // Add this entry's network address and netmask to the list of local HNA entries
1969  AddHostNetworkAssociation (destNetworkAddress, destNetmask);
1970  }
1971  }
1972  NS_LOG_DEBUG ("Nb local associations after having added some entries from "
1973  "the associated routing table: " << m_state.GetAssociations ().size ());
1974 }
1975 
1976 bool
1978 {
1979  std::set<uint32_t>::const_iterator ci = m_interfaceExclusions.find (route.GetInterface ());
1980  // The outgoing interface is a non-OLSR interface if a match is found
1981  // before reaching the end of the list of excluded interfaces
1982  return ci != m_interfaceExclusions.end ();
1983 }
1984 
1985 void
1987  const olsr::MessageHeader::Hello &hello,
1988  const Ipv4Address &receiverIface,
1989  const Ipv4Address &senderIface)
1990 {
1991  Time now = Simulator::Now ();
1992  bool updated = false;
1993  bool created = false;
1994  NS_LOG_DEBUG ("@" << now.As (Time::S) << ": Olsr node " << m_mainAddress
1995  << ": LinkSensing(receiverIface=" << receiverIface
1996  << ", senderIface=" << senderIface << ") BEGIN");
1997 
1998  NS_ASSERT (msg.GetVTime () > Seconds (0));
1999  LinkTuple *link_tuple = m_state.FindLinkTuple (senderIface);
2000  if (link_tuple == NULL)
2001  {
2002  LinkTuple newLinkTuple;
2003  // We have to create a new tuple
2004  newLinkTuple.neighborIfaceAddr = senderIface;
2005  newLinkTuple.localIfaceAddr = receiverIface;
2006  newLinkTuple.symTime = now - Seconds (1);
2007  newLinkTuple.time = now + msg.GetVTime ();
2008  link_tuple = &m_state.InsertLinkTuple (newLinkTuple);
2009  created = true;
2010  NS_LOG_LOGIC ("Existing link tuple did not exist => creating new one");
2011  }
2012  else
2013  {
2014  NS_LOG_LOGIC ("Existing link tuple already exists => will update it");
2015  updated = true;
2016  }
2017 
2018  link_tuple->asymTime = now + msg.GetVTime ();
2019  for (std::vector<olsr::MessageHeader::Hello::LinkMessage>::const_iterator linkMessage =
2020  hello.linkMessages.begin ();
2021  linkMessage != hello.linkMessages.end ();
2022  linkMessage++)
2023  {
2024  int lt = linkMessage->linkCode & 0x03; // Link Type
2025  int nt = (linkMessage->linkCode >> 2) & 0x03; // Neighbor Type
2026 
2027 #ifdef NS3_LOG_ENABLE
2028  const char *linkTypeName;
2029  switch (lt)
2030  {
2031  case OLSR_UNSPEC_LINK:
2032  linkTypeName = "UNSPEC_LINK";
2033  break;
2034  case OLSR_ASYM_LINK:
2035  linkTypeName = "ASYM_LINK";
2036  break;
2037  case OLSR_SYM_LINK:
2038  linkTypeName = "SYM_LINK";
2039  break;
2040  case OLSR_LOST_LINK:
2041  linkTypeName = "LOST_LINK";
2042  break;
2043  default:
2044  linkTypeName = "(invalid value!)";
2045 
2046  }
2047 
2048  const char *neighborTypeName;
2049  switch (nt)
2050  {
2051  case OLSR_NOT_NEIGH:
2052  neighborTypeName = "NOT_NEIGH";
2053  break;
2054  case OLSR_SYM_NEIGH:
2055  neighborTypeName = "SYM_NEIGH";
2056  break;
2057  case OLSR_MPR_NEIGH:
2058  neighborTypeName = "MPR_NEIGH";
2059  break;
2060  default:
2061  neighborTypeName = "(invalid value!)";
2062  }
2063 
2064  NS_LOG_DEBUG ("Looking at HELLO link messages with Link Type "
2065  << lt << " (" << linkTypeName
2066  << ") and Neighbor Type " << nt
2067  << " (" << neighborTypeName << ")");
2068 #endif // NS3_LOG_ENABLE
2069 
2070  // We must not process invalid advertised links
2071  if ((lt == OLSR_SYM_LINK && nt == OLSR_NOT_NEIGH)
2072  || (nt != OLSR_SYM_NEIGH && nt != OLSR_MPR_NEIGH
2073  && nt != OLSR_NOT_NEIGH))
2074  {
2075  NS_LOG_LOGIC ("HELLO link code is invalid => IGNORING");
2076  continue;
2077  }
2078 
2079  for (std::vector<Ipv4Address>::const_iterator neighIfaceAddr =
2080  linkMessage->neighborInterfaceAddresses.begin ();
2081  neighIfaceAddr != linkMessage->neighborInterfaceAddresses.end ();
2082  neighIfaceAddr++)
2083  {
2084  NS_LOG_DEBUG (" -> Neighbor: " << *neighIfaceAddr);
2085  if (*neighIfaceAddr == receiverIface)
2086  {
2087  if (lt == OLSR_LOST_LINK)
2088  {
2089  NS_LOG_LOGIC ("link is LOST => expiring it");
2090  link_tuple->symTime = now - Seconds (1);
2091  updated = true;
2092  }
2093  else if (lt == OLSR_SYM_LINK || lt == OLSR_ASYM_LINK)
2094  {
2095  NS_LOG_DEBUG (*link_tuple << ": link is SYM or ASYM => should become SYM now"
2096  " (symTime being increased to " << now + msg.GetVTime ());
2097  link_tuple->symTime = now + msg.GetVTime ();
2098  link_tuple->time = link_tuple->symTime + OLSR_NEIGHB_HOLD_TIME;
2099  updated = true;
2100  }
2101  else
2102  {
2103  NS_FATAL_ERROR ("bad link type");
2104  }
2105  break;
2106  }
2107  else
2108  {
2109  NS_LOG_DEBUG (" \\-> *neighIfaceAddr (" << *neighIfaceAddr
2110  << " != receiverIface (" << receiverIface << ") => IGNORING!");
2111  }
2112  }
2113  NS_LOG_DEBUG ("Link tuple updated: " << int (updated));
2114  }
2115  link_tuple->time = std::max (link_tuple->time, link_tuple->asymTime);
2116 
2117  if (updated)
2118  {
2119  LinkTupleUpdated (*link_tuple, hello.willingness);
2120  }
2121 
2122  // Schedules link tuple deletion
2123  if (created)
2124  {
2125  LinkTupleAdded (*link_tuple, hello.willingness);
2126  m_events.Track (Simulator::Schedule (DELAY (std::min (link_tuple->time, link_tuple->symTime)),
2128  link_tuple->neighborIfaceAddr));
2129  }
2130  NS_LOG_DEBUG ("@" << now.As (Time::S) << ": Olsr node " << m_mainAddress
2131  << ": LinkSensing END");
2132 }
2133 
2134 void
2136  const olsr::MessageHeader::Hello &hello)
2137 {
2139  if (nb_tuple != NULL)
2140  {
2141  nb_tuple->willingness = hello.willingness;
2142  }
2143 }
2144 
2145 void
2147  const olsr::MessageHeader::Hello &hello)
2148 {
2149  Time now = Simulator::Now ();
2150 
2151  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet BEGIN");
2152 
2153  for (LinkSet::const_iterator link_tuple = m_state.GetLinks ().begin ();
2154  link_tuple != m_state.GetLinks ().end (); link_tuple++)
2155  {
2156  NS_LOG_LOGIC ("Looking at link tuple: " << *link_tuple);
2157  if (GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ())
2158  {
2159  NS_LOG_LOGIC ("Link tuple ignored: "
2160  "GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ()");
2161  NS_LOG_LOGIC ("(GetMainAddress(" << link_tuple->neighborIfaceAddr << "): "
2162  << GetMainAddress (link_tuple->neighborIfaceAddr)
2163  << "; msg.GetOriginatorAddress (): " << msg.GetOriginatorAddress ());
2164  continue;
2165  }
2166 
2167  if (link_tuple->symTime < now)
2168  {
2169  NS_LOG_LOGIC ("Link tuple ignored: expired.");
2170  continue;
2171  }
2172 
2173  typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
2174  for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
2175  linkMessage != hello.linkMessages.end (); linkMessage++)
2176  {
2177  int neighborType = (linkMessage->linkCode >> 2) & 0x3;
2178 #ifdef NS3_LOG_ENABLE
2179  const char *neighborTypeNames[3] = { "NOT_NEIGH", "SYM_NEIGH", "MPR_NEIGH" };
2180  const char *neighborTypeName = ((neighborType < 3) ?
2181  neighborTypeNames[neighborType]
2182  : "(invalid value)");
2183  NS_LOG_DEBUG ("Looking at Link Message from HELLO message: neighborType="
2184  << neighborType << " (" << neighborTypeName << ")");
2185 #endif // NS3_LOG_ENABLE
2186 
2187  for (std::vector<Ipv4Address>::const_iterator nb2hop_addr_iter =
2188  linkMessage->neighborInterfaceAddresses.begin ();
2189  nb2hop_addr_iter != linkMessage->neighborInterfaceAddresses.end ();
2190  nb2hop_addr_iter++)
2191  {
2192  Ipv4Address nb2hop_addr = GetMainAddress (*nb2hop_addr_iter);
2193  NS_LOG_DEBUG ("Looking at 2-hop neighbor address from HELLO message: "
2194  << *nb2hop_addr_iter
2195  << " (main address is " << nb2hop_addr << ")");
2196  if (neighborType == OLSR_SYM_NEIGH || neighborType == OLSR_MPR_NEIGH)
2197  {
2198  // If the main address of the 2-hop neighbor address == main address
2199  // of the receiving node, silently discard the 2-hop
2200  // neighbor address.
2201  if (nb2hop_addr == m_mainAddress)
2202  {
2203  NS_LOG_LOGIC ("Ignoring 2-hop neighbor (it is the node itself)");
2204  continue;
2205  }
2206 
2207  // Otherwise, a 2-hop tuple is created
2208  TwoHopNeighborTuple *nb2hop_tuple =
2210  NS_LOG_LOGIC ("Adding the 2-hop neighbor"
2211  << (nb2hop_tuple ? " (refreshing existing entry)" : ""));
2212  if (nb2hop_tuple == NULL)
2213  {
2214  TwoHopNeighborTuple new_nb2hop_tuple;
2215  new_nb2hop_tuple.neighborMainAddr = msg.GetOriginatorAddress ();
2216  new_nb2hop_tuple.twoHopNeighborAddr = nb2hop_addr;
2217  new_nb2hop_tuple.expirationTime = now + msg.GetVTime ();
2218  AddTwoHopNeighborTuple (new_nb2hop_tuple);
2219  // Schedules nb2hop tuple deletion
2220  m_events.Track (Simulator::Schedule (DELAY (new_nb2hop_tuple.expirationTime),
2222  new_nb2hop_tuple.neighborMainAddr,
2223  new_nb2hop_tuple.twoHopNeighborAddr));
2224  }
2225  else
2226  {
2227  nb2hop_tuple->expirationTime = now + msg.GetVTime ();
2228  }
2229  }
2230  else if (neighborType == OLSR_NOT_NEIGH)
2231  {
2232  // For each 2-hop node listed in the HELLO message
2233  // with Neighbor Type equal to NOT_NEIGH all 2-hop
2234  // tuples where: N_neighbor_main_addr == Originator
2235  // Address AND N_2hop_addr == main address of the
2236  // 2-hop neighbor are deleted.
2237  NS_LOG_LOGIC ("2-hop neighbor is NOT_NEIGH => deleting matching 2-hop neighbor state");
2239  }
2240  else
2241  {
2242  NS_LOG_LOGIC ("*** WARNING *** Ignoring link message (inside HELLO) with bad"
2243  " neighbor type value: " << neighborType);
2244  }
2245  }
2246  }
2247  }
2248 
2249  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet END");
2250 }
2251 
2252 void
2254  const olsr::MessageHeader::Hello &hello)
2255 {
2256  NS_LOG_FUNCTION (this);
2257 
2258  Time now = Simulator::Now ();
2259 
2260  typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
2261  for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
2262  linkMessage != hello.linkMessages.end ();
2263  linkMessage++)
2264  {
2265  int nt = linkMessage->linkCode >> 2;
2266  if (nt == OLSR_MPR_NEIGH)
2267  {
2268  NS_LOG_DEBUG ("Processing a link message with neighbor type MPR_NEIGH");
2269 
2270  for (std::vector<Ipv4Address>::const_iterator nb_iface_addr =
2271  linkMessage->neighborInterfaceAddresses.begin ();
2272  nb_iface_addr != linkMessage->neighborInterfaceAddresses.end ();
2273  nb_iface_addr++)
2274  {
2275  if (GetMainAddress (*nb_iface_addr) == m_mainAddress)
2276  {
2277  NS_LOG_DEBUG ("Adding entry to mpr selector set for neighbor " << *nb_iface_addr);
2278 
2279  // We must create a new entry into the mpr selector set
2280  MprSelectorTuple *existing_mprsel_tuple =
2282  if (existing_mprsel_tuple == NULL)
2283  {
2284  MprSelectorTuple mprsel_tuple;
2285 
2286  mprsel_tuple.mainAddr = msg.GetOriginatorAddress ();
2287  mprsel_tuple.expirationTime = now + msg.GetVTime ();
2288  AddMprSelectorTuple (mprsel_tuple);
2289 
2290  // Schedules mpr selector tuple deletion
2292  (DELAY (mprsel_tuple.expirationTime),
2294  mprsel_tuple.mainAddr));
2295  }
2296  else
2297  {
2298  existing_mprsel_tuple->expirationTime = now + msg.GetVTime ();
2299  }
2300  }
2301  }
2302  }
2303  }
2304  NS_LOG_DEBUG ("Computed MPR selector set for node " << m_mainAddress << ": " << m_state.PrintMprSelectorSet ());
2305 }
2306 
2307 
2308 #if 0
2309 void
2317 OLSR::mac_failed (Ptr<Packet> p)
2318 {
2319  double now = Simulator::Now ();
2320  struct hdr_ip* ih = HDR_IP (p);
2321  struct hdr_cmn* ch = HDR_CMN (p);
2322 
2323  debug ("%f: Node %d MAC Layer detects a breakage on link to %d\n",
2324  now,
2325  OLSR::node_id (ra_addr ()),
2326  OLSR::node_id (ch->next_hop ()));
2327 
2328  if ((uint32_t)ih->daddr () == IP_BROADCAST)
2329  {
2330  drop (p, DROP_RTR_MAC_CALLBACK);
2331  return;
2332  }
2333 
2334  OLSR_link_tuple* link_tuple = state_.find_link_tuple (ch->next_hop ());
2335  if (link_tuple != NULL)
2336  {
2337  link_tuple->lost_time () = now + OLSR_NEIGHB_HOLD_TIME;
2338  link_tuple->time () = now + OLSR_NEIGHB_HOLD_TIME;
2339  nb_loss (link_tuple);
2340  }
2341  drop (p, DROP_RTR_MAC_CALLBACK);
2342 }
2343 #endif
2344 
2345 
2346 
2347 
2348 void
2350 {
2352  << ": OLSR Node " << m_mainAddress
2353  << " LinkTuple " << tuple.neighborIfaceAddr << " -> neighbor loss.");
2357 
2358  MprComputation ();
2360 }
2361 
2362 void
2364 {
2365  /*debug("%f: Node %d adds dup tuple: addr = %d seq_num = %d\n",
2366  Simulator::Now (),
2367  OLSR::node_id(ra_addr()),
2368  OLSR::node_id(tuple->addr()),
2369  tuple->seq_num());*/
2370  m_state.InsertDuplicateTuple (tuple);
2371 }
2372 
2373 void
2375 {
2376  /*debug("%f: Node %d removes dup tuple: addr = %d seq_num = %d\n",
2377  Simulator::Now (),
2378  OLSR::node_id(ra_addr()),
2379  OLSR::node_id(tuple->addr()),
2380  tuple->seq_num());*/
2381  m_state.EraseDuplicateTuple (tuple);
2382 }
2383 
2384 void
2385 RoutingProtocol::LinkTupleAdded (const LinkTuple &tuple, uint8_t willingness)
2386 {
2387  // Creates associated neighbor tuple
2388  NeighborTuple nb_tuple;
2390  nb_tuple.willingness = willingness;
2391 
2392  if (tuple.symTime >= Simulator::Now ())
2393  {
2394  nb_tuple.status = NeighborTuple::STATUS_SYM;
2395  }
2396  else
2397  {
2399  }
2400 
2401  AddNeighborTuple (nb_tuple);
2402 }
2403 
2404 void
2406 {
2408  << ": OLSR Node " << m_mainAddress
2409  << " LinkTuple " << tuple << " REMOVED.");
2410 
2412  m_state.EraseLinkTuple (tuple);
2413 }
2414 
2415 void
2416 RoutingProtocol::LinkTupleUpdated (const LinkTuple &tuple, uint8_t willingness)
2417 {
2418  // Each time a link tuple changes, the associated neighbor tuple must be recomputed
2419 
2421  << ": OLSR Node " << m_mainAddress
2422  << " LinkTuple " << tuple << " UPDATED.");
2423 
2424  NeighborTuple *nb_tuple =
2426 
2427  if (nb_tuple == NULL)
2428  {
2429  LinkTupleAdded (tuple, willingness);
2431  }
2432 
2433  if (nb_tuple != NULL)
2434  {
2435  int statusBefore = nb_tuple->status;
2436 
2437  bool hasSymmetricLink = false;
2438 
2439  const LinkSet &linkSet = m_state.GetLinks ();
2440  for (LinkSet::const_iterator it = linkSet.begin ();
2441  it != linkSet.end (); it++)
2442  {
2443  const LinkTuple &link_tuple = *it;
2444  if (GetMainAddress (link_tuple.neighborIfaceAddr) == nb_tuple->neighborMainAddr
2445  && link_tuple.symTime >= Simulator::Now ())
2446  {
2447  hasSymmetricLink = true;
2448  break;
2449  }
2450  }
2451 
2452  if (hasSymmetricLink)
2453  {
2454  nb_tuple->status = NeighborTuple::STATUS_SYM;
2455  NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_SYM; changed:"
2456  << int (statusBefore != nb_tuple->status));
2457  }
2458  else
2459  {
2461  NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_NOT_SYM; changed:"
2462  << int (statusBefore != nb_tuple->status));
2463  }
2464  }
2465  else
2466  {
2467  NS_LOG_WARN ("ERROR! Wanted to update a NeighborTuple but none was found!");
2468  }
2469 }
2470 
2471 void
2473 {
2474 // debug("%f: Node %d adds neighbor tuple: nb_addr = %d status = %s\n",
2475 // Simulator::Now (),
2476 // OLSR::node_id(ra_addr()),
2477 // OLSR::node_id(tuple->neighborMainAddr),
2478 // ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
2479 
2480  m_state.InsertNeighborTuple (tuple);
2481  IncrementAnsn ();
2482 }
2483 
2484 void
2486 {
2487 // debug("%f: Node %d removes neighbor tuple: nb_addr = %d status = %s\n",
2488 // Simulator::Now (),
2489 // OLSR::node_id(ra_addr()),
2490 // OLSR::node_id(tuple->neighborMainAddr),
2491 // ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
2492 
2493  m_state.EraseNeighborTuple (tuple);
2494  IncrementAnsn ();
2495 }
2496 
2497 void
2499 {
2500 // debug("%f: Node %d adds 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
2501 // Simulator::Now (),
2502 // OLSR::node_id(ra_addr()),
2503 // OLSR::node_id(tuple->neighborMainAddr),
2504 // OLSR::node_id(tuple->twoHopNeighborAddr));
2505 
2507 }
2508 
2509 void
2511 {
2512 // debug("%f: Node %d removes 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
2513 // Simulator::Now (),
2514 // OLSR::node_id(ra_addr()),
2515 // OLSR::node_id(tuple->neighborMainAddr),
2516 // OLSR::node_id(tuple->twoHopNeighborAddr));
2517 
2519 }
2520 
2521 void
2523 {
2524  m_ansn = (m_ansn + 1) % (OLSR_MAX_SEQ_NUM + 1);
2525 }
2526 
2527 void
2529 {
2530 // debug("%f: Node %d adds MPR selector tuple: nb_addr = %d\n",
2531 // Simulator::Now (),
2532 // OLSR::node_id(ra_addr()),
2533 // OLSR::node_id(tuple->main_addr()));
2534 
2536  IncrementAnsn ();
2537 }
2538 
2539 void
2541 {
2542 // debug("%f: Node %d removes MPR selector tuple: nb_addr = %d\n",
2543 // Simulator::Now (),
2544 // OLSR::node_id(ra_addr()),
2545 // OLSR::node_id(tuple->main_addr()));
2546 
2548  IncrementAnsn ();
2549 }
2550 
2551 void
2553 {
2554 // debug("%f: Node %d adds topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
2555 // Simulator::Now (),
2556 // OLSR::node_id(ra_addr()),
2557 // OLSR::node_id(tuple->dest_addr()),
2558 // OLSR::node_id(tuple->last_addr()),
2559 // tuple->seq());
2560 
2561  m_state.InsertTopologyTuple (tuple);
2562 }
2563 
2564 void
2566 {
2567 // debug("%f: Node %d removes topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
2568 // Simulator::Now (),
2569 // OLSR::node_id(ra_addr()),
2570 // OLSR::node_id(tuple->dest_addr()),
2571 // OLSR::node_id(tuple->last_addr()),
2572 // tuple->seq());
2573 
2574  m_state.EraseTopologyTuple (tuple);
2575 }
2576 
2577 void
2579 {
2580 // debug("%f: Node %d adds iface association tuple: main_addr = %d iface_addr = %d\n",
2581 // Simulator::Now (),
2582 // OLSR::node_id(ra_addr()),
2583 // OLSR::node_id(tuple->main_addr()),
2584 // OLSR::node_id(tuple->iface_addr()));
2585 
2587 }
2588 
2589 void
2591 {
2592 // debug("%f: Node %d removes iface association tuple: main_addr = %d iface_addr = %d\n",
2593 // Simulator::Now (),
2594 // OLSR::node_id(ra_addr()),
2595 // OLSR::node_id(tuple->main_addr()),
2596 // OLSR::node_id(tuple->iface_addr()));
2597 
2598  m_state.EraseIfaceAssocTuple (tuple);
2599 }
2600 
2601 void
2603 {
2605 }
2606 
2607 void
2609 {
2611 }
2612 
2614 {
2616  return m_packetSequenceNumber;
2617 }
2618 
2620 {
2622  return m_messageSequenceNumber;
2623 }
2624 
2625 void
2627 {
2628  SendHello ();
2630 }
2631 
2632 void
2634 {
2635  if (m_state.GetMprSelectors ().size () > 0)
2636  {
2637  SendTc ();
2638  }
2639  else
2640  {
2641  NS_LOG_DEBUG ("Not sending any TC, no one selected me as MPR.");
2642  }
2644 }
2645 
2646 void
2648 {
2649  SendMid ();
2651 }
2652 
2653 void
2655 {
2656  if (m_state.GetAssociations ().size () > 0)
2657  {
2658  SendHna ();
2659  }
2660  else
2661  {
2662  NS_LOG_DEBUG ("Not sending any HNA, no associations to advertise.");
2663  }
2665 }
2666 
2667 void
2669 {
2670  DuplicateTuple *tuple =
2671  m_state.FindDuplicateTuple (address, sequenceNumber);
2672  if (tuple == NULL)
2673  {
2674  return;
2675  }
2676  if (tuple->expirationTime < Simulator::Now ())
2677  {
2678  RemoveDuplicateTuple (*tuple);
2679  }
2680  else
2681  {
2684  address, sequenceNumber));
2685  }
2686 }
2687 
2688 void
2690 {
2691  Time now = Simulator::Now ();
2692 
2693  // the tuple parameter may be a stale copy; get a newer version from m_state
2694  LinkTuple *tuple = m_state.FindLinkTuple (neighborIfaceAddr);
2695  if (tuple == NULL)
2696  {
2697  return;
2698  }
2699  if (tuple->time < now)
2700  {
2701  RemoveLinkTuple (*tuple);
2702  }
2703  else if (tuple->symTime < now)
2704  {
2706  {
2707  m_linkTupleTimerFirstTime = false;
2708  }
2709  else
2710  {
2711  NeighborLoss (*tuple);
2712  }
2713 
2716  neighborIfaceAddr));
2717  }
2718  else
2719  {
2722  neighborIfaceAddr));
2723  }
2724 }
2725 
2726 void
2728 {
2729  TwoHopNeighborTuple *tuple;
2730  tuple = m_state.FindTwoHopNeighborTuple (neighborMainAddr, twoHopNeighborAddr);
2731  if (tuple == NULL)
2732  {
2733  return;
2734  }
2735  if (tuple->expirationTime < Simulator::Now ())
2736  {
2737  RemoveTwoHopNeighborTuple (*tuple);
2738  }
2739  else
2740  {
2743  this, neighborMainAddr, twoHopNeighborAddr));
2744  }
2745 }
2746 
2747 void
2749 {
2750  MprSelectorTuple *tuple = m_state.FindMprSelectorTuple (mainAddr);
2751  if (tuple == NULL)
2752  {
2753  return;
2754  }
2755  if (tuple->expirationTime < Simulator::Now ())
2756  {
2757  RemoveMprSelectorTuple (*tuple);
2758  }
2759  else
2760  {
2763  this, mainAddr));
2764  }
2765 }
2766 
2767 void
2769 {
2770  TopologyTuple *tuple = m_state.FindTopologyTuple (destAddr, lastAddr);
2771  if (tuple == NULL)
2772  {
2773  return;
2774  }
2775  if (tuple->expirationTime < Simulator::Now ())
2776  {
2777  RemoveTopologyTuple (*tuple);
2778  }
2779  else
2780  {
2783  this, tuple->destAddr, tuple->lastAddr));
2784  }
2785 }
2786 
2787 void
2789 {
2790  IfaceAssocTuple *tuple = m_state.FindIfaceAssocTuple (ifaceAddr);
2791  if (tuple == NULL)
2792  {
2793  return;
2794  }
2795  if (tuple->time < Simulator::Now ())
2796  {
2797  RemoveIfaceAssocTuple (*tuple);
2798  }
2799  else
2800  {
2803  this, ifaceAddr));
2804  }
2805 }
2806 
2807 void
2809 {
2810  AssociationTuple *tuple = m_state.FindAssociationTuple (gatewayAddr, networkAddr, netmask);
2811  if (tuple == NULL)
2812  {
2813  return;
2814  }
2815  if (tuple->expirationTime < Simulator::Now ())
2816  {
2817  RemoveAssociationTuple (*tuple);
2818  }
2819  else
2820  {
2823  this, gatewayAddr, networkAddr, netmask));
2824  }
2825 }
2826 
2827 void
2829 {
2831  m_table.clear ();
2832 }
2833 
2834 void
2836 {
2837  m_table.erase (dest);
2838 }
2839 
2840 bool
2842  RoutingTableEntry &outEntry) const
2843 {
2844  // Get the iterator at "dest" position
2845  std::map<Ipv4Address, RoutingTableEntry>::const_iterator it =
2846  m_table.find (dest);
2847  // If there is no route to "dest", return NULL
2848  if (it == m_table.end ())
2849  {
2850  return false;
2851  }
2852  outEntry = it->second;
2853  return true;
2854 }
2855 
2856 bool
2858  RoutingTableEntry &outEntry) const
2859 {
2860  outEntry = entry;
2861  while (outEntry.destAddr != outEntry.nextAddr)
2862  {
2863  if (not Lookup (outEntry.nextAddr, outEntry))
2864  {
2865  return false;
2866  }
2867  }
2868  return true;
2869 }
2870 
2873 {
2874  NS_LOG_FUNCTION (this << " " << m_ipv4->GetObject<Node> ()->GetId () << " " << header.GetDestination () << " " << oif);
2875  Ptr<Ipv4Route> rtentry;
2876  RoutingTableEntry entry1, entry2;
2877  bool found = false;
2878 
2879  if (Lookup (header.GetDestination (), entry1) != 0)
2880  {
2881  bool foundSendEntry = FindSendEntry (entry1, entry2);
2882  if (!foundSendEntry)
2883  {
2884  NS_FATAL_ERROR ("FindSendEntry failure");
2885  }
2886  uint32_t interfaceIdx = entry2.interface;
2887  if (oif && m_ipv4->GetInterfaceForDevice (oif) != static_cast<int> (interfaceIdx))
2888  {
2889  // We do not attempt to perform a constrained routing search
2890  // if the caller specifies the oif; we just enforce that
2891  // that the found route matches the requested outbound interface
2892  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
2893  << ": RouteOutput for dest=" << header.GetDestination ()
2894  << " Route interface " << interfaceIdx
2895  << " does not match requested output interface "
2896  << m_ipv4->GetInterfaceForDevice (oif));
2897  sockerr = Socket::ERROR_NOROUTETOHOST;
2898  return rtentry;
2899  }
2900  rtentry = Create<Ipv4Route> ();
2901  rtentry->SetDestination (header.GetDestination ());
2902  // the source address is the interface address that matches
2903  // the destination address (when multiple are present on the
2904  // outgoing interface, one is selected via scoping rules)
2905  NS_ASSERT (m_ipv4);
2906  uint32_t numOifAddresses = m_ipv4->GetNAddresses (interfaceIdx);
2907  NS_ASSERT (numOifAddresses > 0);
2908  Ipv4InterfaceAddress ifAddr;
2909  if (numOifAddresses == 1)
2910  {
2911  ifAddr = m_ipv4->GetAddress (interfaceIdx, 0);
2912  }
2913  else
2914  {
2916  NS_FATAL_ERROR ("XXX Not implemented yet: IP aliasing and OLSR");
2917  }
2918  rtentry->SetSource (ifAddr.GetLocal ());
2919  rtentry->SetGateway (entry2.nextAddr);
2920  rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
2921  sockerr = Socket::ERROR_NOTERROR;
2922  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
2923  << ": RouteOutput for dest=" << header.GetDestination ()
2924  << " --> nextHop=" << entry2.nextAddr
2925  << " interface=" << entry2.interface);
2926  NS_LOG_DEBUG ("Found route to " << rtentry->GetDestination () << " via nh " << rtentry->GetGateway () << " with source addr " << rtentry->GetSource () << " and output dev " << rtentry->GetOutputDevice ());
2927  found = true;
2928  }
2929  else
2930  {
2931  rtentry = m_hnaRoutingTable->RouteOutput (p, header, oif, sockerr);
2932 
2933  if (rtentry)
2934  {
2935  found = true;
2936  NS_LOG_DEBUG ("Found route to " << rtentry->GetDestination () << " via nh " << rtentry->GetGateway () << " with source addr " << rtentry->GetSource () << " and output dev " << rtentry->GetOutputDevice ());
2937  }
2938  }
2939 
2940  if (!found)
2941  {
2942  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
2943  << ": RouteOutput for dest=" << header.GetDestination ()
2944  << " No route to host");
2945  sockerr = Socket::ERROR_NOROUTETOHOST;
2946  }
2947  return rtentry;
2948 }
2949 
2951  const Ipv4Header &header, Ptr<const NetDevice> idev,
2954 {
2955  NS_LOG_FUNCTION (this << " " << m_ipv4->GetObject<Node> ()->GetId () << " " << header.GetDestination ());
2956 
2957  Ipv4Address dst = header.GetDestination ();
2958  Ipv4Address origin = header.GetSource ();
2959 
2960  // Consume self-originated packets
2961  if (IsMyOwnAddress (origin) == true)
2962  {
2963  return true;
2964  }
2965 
2966  // Local delivery
2967  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
2968  uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
2969  if (m_ipv4->IsDestinationAddress (dst, iif))
2970  {
2971  if (!lcb.IsNull ())
2972  {
2973  NS_LOG_LOGIC ("Local delivery to " << dst);
2974  lcb (p, header, iif);
2975  return true;
2976  }
2977  else
2978  {
2979  // The local delivery callback is null. This may be a multicast
2980  // or broadcast packet, so return false so that another
2981  // multicast routing protocol can handle it. It should be possible
2982  // to extend this to explicitly check whether it is a unicast
2983  // packet, and invoke the error callback if so
2984  NS_LOG_LOGIC ("Null local delivery callback");
2985  return false;
2986  }
2987  }
2988 
2989  NS_LOG_LOGIC ("Forward packet");
2990  // Forwarding
2991  Ptr<Ipv4Route> rtentry;
2992  RoutingTableEntry entry1, entry2;
2993  if (Lookup (header.GetDestination (), entry1))
2994  {
2995  bool foundSendEntry = FindSendEntry (entry1, entry2);
2996  if (!foundSendEntry)
2997  {
2998  NS_FATAL_ERROR ("FindSendEntry failure");
2999  }
3000  rtentry = Create<Ipv4Route> ();
3001  rtentry->SetDestination (header.GetDestination ());
3002  uint32_t interfaceIdx = entry2.interface;
3003  // the source address is the interface address that matches
3004  // the destination address (when multiple are present on the
3005  // outgoing interface, one is selected via scoping rules)
3006  NS_ASSERT (m_ipv4);
3007  uint32_t numOifAddresses = m_ipv4->GetNAddresses (interfaceIdx);
3008  NS_ASSERT (numOifAddresses > 0);
3009  Ipv4InterfaceAddress ifAddr;
3010  if (numOifAddresses == 1)
3011  {
3012  ifAddr = m_ipv4->GetAddress (interfaceIdx, 0);
3013  }
3014  else
3015  {
3017  NS_FATAL_ERROR ("XXX Not implemented yet: IP aliasing and OLSR");
3018  }
3019  rtentry->SetSource (ifAddr.GetLocal ());
3020  rtentry->SetGateway (entry2.nextAddr);
3021  rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
3022 
3023  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3024  << ": RouteInput for dest=" << header.GetDestination ()
3025  << " --> nextHop=" << entry2.nextAddr
3026  << " interface=" << entry2.interface);
3027 
3028  ucb (rtentry, p, header);
3029  return true;
3030  }
3031  else
3032  {
3033  NS_LOG_LOGIC ("No dynamic route, check network routes");
3034  if (m_hnaRoutingTable->RouteInput (p, header, idev, ucb, mcb, lcb, ecb))
3035  {
3036  return true;
3037  }
3038  else
3039  {
3040 
3041 #ifdef NS3_LOG_ENABLE
3042  NS_LOG_DEBUG ("Olsr node " << m_mainAddress
3043  << ": RouteInput for dest=" << header.GetDestination ()
3044  << " --> NOT FOUND; ** Dumping routing table...");
3045 
3046  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
3047  iter != m_table.end (); iter++)
3048  {
3049  NS_LOG_DEBUG ("dest=" << iter->first << " --> next=" << iter->second.nextAddr
3050  << " via interface " << iter->second.interface);
3051  }
3052 
3053  NS_LOG_DEBUG ("** Routing table dump end.");
3054 #endif // NS3_LOG_ENABLE
3055 
3056  return false;
3057  }
3058  }
3059 }
3060 void
3062 {
3063 }
3064 void
3066 {
3067 }
3068 void
3070 {
3071 }
3072 void
3074 {
3075 }
3076 
3077 
3078 void
3080  Ipv4Address const &next,
3081  uint32_t interface,
3082  uint32_t distance)
3083 {
3084  NS_LOG_FUNCTION (this << dest << next << interface << distance << m_mainAddress);
3085 
3086  NS_ASSERT (distance > 0);
3087 
3088  // Creates a new rt entry with specified values
3089  RoutingTableEntry &entry = m_table[dest];
3090 
3091  entry.destAddr = dest;
3092  entry.nextAddr = next;
3093  entry.interface = interface;
3094  entry.distance = distance;
3095 }
3096 
3097 void
3099  Ipv4Address const &next,
3100  Ipv4Address const &interfaceAddress,
3101  uint32_t distance)
3102 {
3103  NS_LOG_FUNCTION (this << dest << next << interfaceAddress << distance << m_mainAddress);
3104 
3105  NS_ASSERT (distance > 0);
3106  NS_ASSERT (m_ipv4);
3107 
3108  RoutingTableEntry entry;
3109  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
3110  {
3111  for (uint32_t j = 0; j < m_ipv4->GetNAddresses (i); j++)
3112  {
3113  if (m_ipv4->GetAddress (i,j).GetLocal () == interfaceAddress)
3114  {
3115  AddEntry (dest, next, i, distance);
3116  return;
3117  }
3118  }
3119  }
3120  NS_ASSERT (false); // should not be reached
3121  AddEntry (dest, next, 0, distance);
3122 }
3123 
3124 
3125 std::vector<RoutingTableEntry>
3127 {
3128  std::vector<RoutingTableEntry> retval;
3129  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
3130  iter != m_table.end (); iter++)
3131  {
3132  retval.push_back (iter->second);
3133  }
3134  return retval;
3135 }
3136 
3137 MprSet
3139 {
3140  return m_state.GetMprSet ();
3141 }
3142 
3143 const MprSelectorSet &
3145 {
3146  return m_state.GetMprSelectors ();
3147 }
3148 
3149 const NeighborSet &
3151 {
3152  return m_state.GetNeighbors ();
3153 }
3154 
3155 const TwoHopNeighborSet &
3157 {
3158  return m_state.GetTwoHopNeighbors ();
3159 }
3160 
3161 const TopologySet &
3163 {
3164  return m_state.GetTopologySet ();
3165 }
3166 
3167 const OlsrState &
3169 {
3170  return m_state;
3171 }
3172 
3173 int64_t
3175 {
3176  NS_LOG_FUNCTION (this << stream);
3178  return 1;
3179 }
3180 
3181 bool
3183 {
3184  std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j;
3185  for (j = m_sendSockets.begin (); j != m_sendSockets.end (); ++j)
3186  {
3187  Ipv4InterfaceAddress iface = j->second;
3188  if (a == iface.GetLocal ())
3189  {
3190  return true;
3191  }
3192  }
3193  return false;
3194 }
3195 
3196 void
3198 {
3199 #ifdef NS3_LOG_ENABLE
3200  Time now = Simulator::Now ();
3201  NS_LOG_DEBUG ("Dumping for node with main address " << m_mainAddress);
3202  NS_LOG_DEBUG (" Neighbor set");
3203  for (NeighborSet::const_iterator iter = m_state.GetNeighbors ().begin ();
3204  iter != m_state.GetNeighbors ().end (); iter++)
3205  {
3206  NS_LOG_DEBUG (" " << *iter);
3207  }
3208  NS_LOG_DEBUG (" Two-hop neighbor set");
3209  for (TwoHopNeighborSet::const_iterator iter = m_state.GetTwoHopNeighbors ().begin ();
3210  iter != m_state.GetTwoHopNeighbors ().end (); iter++)
3211  {
3212  if (now < iter->expirationTime)
3213  {
3214  NS_LOG_DEBUG (" " << *iter);
3215  }
3216  }
3217  NS_LOG_DEBUG (" Routing table");
3218  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin (); iter != m_table.end (); iter++)
3219  {
3220  NS_LOG_DEBUG (" dest=" << iter->first << " --> next=" << iter->second.nextAddr << " via interface " << iter->second.interface);
3221  }
3222  NS_LOG_DEBUG ("");
3223 #endif //NS3_LOG_ENABLE
3224 }
3225 
3228 {
3229  return m_hnaRoutingTable;
3230 }
3231 
3232 } // namespace olsr
3233 } // namespace ns3
3234 
3235 
std::vector< TopologyTuple > TopologySet
Topology Set type.
void HnaTimerExpire(void)
Sends an HNA message (if the node has associated hosts/networks) and reschedules the HNA timer...
uint8_t GetHopCount() const
Get the hop count.
Definition: olsr-header.h:254
An MPR-Selector Tuple.
uint8_t GetTimeToLive() const
Get the time to live.
Definition: olsr-header.h:237
Ipv4Address networkAddr
Network Address of network reachable through gatewayAddr.
static TypeId GetTypeId(void)
Get the type ID.
std::set< uint32_t > m_interfaceExclusions
Set of interfaces excluded by OSLR.
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
#define JITTER
Random number between [0-OLSR_MAXJITTER] used to jitter OLSR packet transmission. ...
An OLSR&#39;s routing table entry.
uint32_t distance
Distance in hops to the destination.
#define OLSR_MPR_NEIGH
Asymmetric neighbor type.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
IfaceAssocSet & GetIfaceAssocSetMutable()
Gets a mutable reference to the interface association set.
Definition: olsr-state.h:343
an Inet address class
void AddTopologyTuple(const TopologyTuple &tuple)
Adds a topology tuple to the Topology Set.
static Ipv4Address GetAny(void)
#define OLSR_MAX_SEQ_NUM
Maximum allowed sequence number.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
const TopologySet & GetTopologySet() const
Gets the topology set.
Definition: olsr-state.h:291
TwoHopNeighborTuple * FindTwoHopNeighborTuple(const Ipv4Address &neighbor, const Ipv4Address &twoHopNeighbor)
Finds a 2-hop neighbor tuple.
Definition: olsr-state.cc:200
void IfaceAssocTupleTimerExpire(Ipv4Address ifaceAddr)
Removes interface association tuple_ if expired.
uint16_t sequenceNumber
Sequence number.
const TwoHopNeighborSet & GetTwoHopNeighbors() const
Gets the 2-hop neighbor set.
Definition: olsr-state.h:162
void RemoveMprSelectorTuple(const MprSelectorTuple &tuple)
Removes an MPR selector tuple from the MPR Selector Set.
Callback template class.
Definition: callback.h:1278
Timer m_helloTimer
Timer for the HELLO message.
#define OLSR_WILL_DEFAULT
Willingness for forwarding packets from other nodes: medium.
void Clear(void)
Clears the routing table and frees the memory assigned to each one of its entries.
void MidTimerExpire(void)
Sends a MID message (if the node has more than one interface) and resets the MID timer.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
std::vector< Association > Associations
Association Set type.
Time m_midInterval
MID messages&#39; emission interval.
uint32_t GetId(void) const
Definition: node.cc:109
A simple virtual Timer class.
Definition: timer.h:73
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
#define OLSR_DUP_HOLD_TIME
Dup holding time.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
void EraseMprSelectorTuples(const Ipv4Address &mainAddr)
Erases all MPR selector tuples belonging to the same address.
Definition: olsr-state.cc:66
This header can store HELP, TC, MID and HNA messages.
Definition: olsr-header.h:157
uint16_t m_messageSequenceNumber
Messages sequence number counter.
virtual bool SetAllowBroadcast(bool allowBroadcast)=0
Configure whether broadcast datagram transmissions are allowed.
TC Message Format
Definition: olsr-header.h:458
Mid & GetMid()
Set the message type to MID and return the message content.
Definition: olsr-header.h:574
#define min(a, b)
Definition: 80211b.c:42
void InsertAssociationTuple(const AssociationTuple &tuple)
Inserts a known association tuple.
Definition: olsr-state.cc:549
Ipv4Address destAddr
Address of the destination node.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:269
#define OLSR_TOP_HOLD_TIME
Top holding time.
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:144
virtual int ShutdownSend(void)=0
void LinkTupleUpdated(const LinkTuple &tuple, uint8_t willingness)
This function is invoked when a link tuple is updated.
uint32_t GetRecvIf(void) const
Get the tag&#39;s receiving interface.
void InsertNeighborTuple(const NeighborTuple &tuple)
Inserts a neighbor tuple.
Definition: olsr-state.cc:182
void SetPacketSequenceNumber(uint16_t seqnum)
Set the packet sequence number.
Definition: olsr-header.h:103
uint16_t m_ansn
Advertised Neighbor Set sequence number.
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
MprSet GetMprSet() const
Gets the MPR set.
Definition: olsr-state.cc:286
const NeighborSet & GetNeighbors(void) const
Get the one hop neighbors.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define OLSR_WILL_ALWAYS
Willingness for forwarding packets from other nodes: always.
void SetMprSet(MprSet mprSet)
Sets the MPR set to the one specified.
Definition: olsr-state.cc:281
uint16_t GetPacketLength() const
Get the packet total length.
Definition: olsr-header.h:94
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
virtual uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:189
void AddEntry(const Ipv4Address &dest, const Ipv4Address &next, uint32_t interface, uint32_t distance)
Adds a new entry into the routing table.
Ptr< const Ipv4StaticRouting > GetRoutingTableAssociation(void) const
Returns the internal HNA table.
bool m_linkTupleTimerFirstTime
Flag to indicate if it is the first time the LinkTupleTimer fires.
void TcTimerExpire(void)
Sends a TC message (if there exists any MPR selector) and reschedules the TC timer.
virtual void NotifyInterfaceUp(uint32_t interface)
void SetHTime(Time time)
Set the HELLO emission interval.
Definition: olsr-header.h:393
void SendQueuedMessages(void)
Creates as many OLSR packets as needed in order to send all buffered OLSR messages.
const IfaceAssocSet & GetIfaceAssocSet() const
Gets the interface association set.
Definition: olsr-state.h:335
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
void DupTupleTimerExpire(Ipv4Address address, uint16_t sequenceNumber)
Removes tuple if expired.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
bool FindMprAddress(const Ipv4Address &address)
Checks if there&#39;s an MPR with a specific address.
Definition: olsr-state.cc:274
uint16_t GetPacketSequenceNumber(void)
Increments packet sequence number and returns the new value.
enum ns3::olsr::NeighborTuple::Status status
Status of the link.
Timer m_queuedMessagesTimer
timer for throttling outgoing messages
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
void InsertMprSelectorTuple(const MprSelectorTuple &tuple)
Inserts a MPR selector tuple.
Definition: olsr-state.cc:83
void AddHostNetworkAssociation(Ipv4Address networkAddr, Ipv4Mask netmask)
Injects the specified (networkAddr, netmask) tuple in the list of local HNA associations to be sent b...
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Tc & GetTc()
Set the message type to TC and return the message content.
Definition: olsr-header.h:608
std::vector< LinkMessage > linkMessages
Link messages container.
Definition: olsr-header.h:408
Ipv4Address m_mainAddress
the node main address.
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:389
Time expirationTime
Time at which this tuple expires and must be removed.
Ipv4Address GetDestNetwork(void) const
NeighborTuple * FindNeighborTuple(const Ipv4Address &mainAddr)
Finds a neighbor tuple.
Definition: olsr-state.cc:112
#define OLSR_WILL_LOW
Willingness for forwarding packets from other nodes: low.
uint16_t ansn
Advertised Neighbor Sequence Number.
Definition: olsr-header.h:461
Ipv4Mask netmask
IPv4 Network mask.
void LinkTupleTimerExpire(Ipv4Address neighborIfaceAddr)
Removes tuple_ if expired.
void EraseIfaceAssocTuple(const IfaceAssocTuple &tuple)
Erases a interface association tuple.
Definition: olsr-state.cc:484
void SetMainInterface(uint32_t interface)
Set the OLSR main address to the first address on the indicated interface.
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
Ipv4Mask netmask
Netmask of network reachable through gatewayAddr.
void SetHopCount(uint8_t hopCount)
Set the hop count.
Definition: olsr-header.h:246
void Nb2hopTupleTimerExpire(Ipv4Address neighborMainAddr, Ipv4Address twoHopNeighborAddr)
Removes 2_hop neighbor tuple_ if expired.
void RemoveAssociationTuple(const AssociationTuple &tuple)
Removes a host network association tuple to the Association Set.
void ProcessTc(const olsr::MessageHeader &msg, const Ipv4Address &senderIface)
Processes a TC message following RFC 3626 specification.
#define OLSR_NEIGHB_HOLD_TIME
Neighbor holding time.
LinkTuple * FindSymLinkTuple(const Ipv4Address &ifaceAddr, Time time)
Finds a symmetrical link tuple.
Definition: olsr-state.cc:344
void MprComputation(void)
Computates MPR set of a node following RFC 3626 hints.
const NeighborSet & GetNeighbors() const
Gets the neighbor set.
Definition: olsr-state.h:103
a polymophic address class
Definition: address.h:90
LinkTuple * FindLinkTuple(const Ipv4Address &ifaceAddr)
Finds a link tuple.
Definition: olsr-state.cc:330
void SendMid(void)
Creates a new OLSR MID message which is buffered for being sent later on.
void LinkSensing(const olsr::MessageHeader &msg, const olsr::MessageHeader::Hello &hello, const Ipv4Address &receiverIface, const Ipv4Address &senderIface)
Updates Link Set according to a new received HELLO message (following RFC 3626 specification).
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
void SetVTime(Time time)
Set the validity time.
Definition: olsr-header.h:195
void SendHna(void)
Creates a new OLSR HNA message which is buffered for being sent later on.
void EraseDuplicateTuple(const DuplicateTuple &tuple)
Erases a duplicate tuple.
Definition: olsr-state.cc:308
void EraseTopologyTuple(const TopologyTuple &tuple)
Erases a topology tuple.
Definition: olsr-state.cc:417
void MprSelTupleTimerExpire(Ipv4Address mainAddr)
Removes MPR selector tuple_ if expired.
#define OLSR_SYM_LINK
Symmetric link type.
void SetSource(Ipv4Address src)
Definition: ipv4-route.cc:49
std::map< Ipv4Address, RoutingTableEntry > m_table
Data structure for the routing table.
std::vector< Ipv4Address > interfaceAddresses
Interface Address container.
Definition: olsr-header.h:315
const NeighborTuple * FindSymNeighborTuple(const Ipv4Address &mainAddr) const
Finds a symmetrical neighbor tuple.
Definition: olsr-state.cc:126
std::vector< Ipv4Address > neighborAddresses
Neighbor address container.
Definition: olsr-header.h:460
void SetTimeToLive(uint8_t timeToLive)
Set the time to live.
Definition: olsr-header.h:229
TracedCallback< const PacketHeader &, const MessageList & > m_rxPacketTrace
Rx packet trace.
void RemoveIfaceAssocTuple(const IfaceAssocTuple &tuple)
Removed an interface association tuple to the Interface Association Set.
void SetRecvPktInfo(bool flag)
Enable/Disable receive packet information to socket.
Definition: socket.cc:358
const LinkSet & GetLinks() const
Gets the Link set.
Definition: olsr-state.h:256
Packet header for IPv4.
Definition: ipv4-header.h:33
EventGarbageCollector m_events
Running events.
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print the Routing Table entries.
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:335
Ipv4Address lastAddr
Main address of a node which is a neighbor of the destination.
const MprSelectorSet & GetMprSelectors() const
Gets the MPR selectors.
Definition: olsr-state.h:61
Ipv4Mask GetDestNetworkMask(void) const
A record of an IPv4 routing table entry for Ipv4GlobalRouting and Ipv4StaticRouting.
uint8_t m_willingness
Willingness for forwarding packets on behalf of other nodes.
void PopulateNeighborSet(const olsr::MessageHeader &msg, const olsr::MessageHeader::Hello &hello)
Updates the Neighbor Set according to the information contained in a new received HELLO message (foll...
Time expirationTime
Time at which this tuple expires and must be removed.
void EraseOlderTopologyTuples(const Ipv4Address &lastAddr, uint16_t ansn)
Erases a topology tuple.
Definition: olsr-state.cc:431
void RemoveHostNetworkAssociation(Ipv4Address networkAddr, Ipv4Mask netmask)
Removes the specified (networkAddr, netmask) tuple from the list of local HNA associations to be sent...
Hold variables of type enum.
Definition: enum.h:54
std::map< Ptr< Socket >, Ipv4InterfaceAddress > m_sendSockets
Container of sockets and the interfaces they are opened onto.
#define max(a, b)
Definition: 80211b.c:43
Ipv4Address mainAddr
Main address of the node.
Association item structure.
Definition: olsr-header.h:519
TopologyTuple * FindTopologyTuple(const Ipv4Address &destAddr, const Ipv4Address &lastAddr)
Finds a topology tuple.
Definition: olsr-state.cc:388
void AddIfaceAssocTuple(const IfaceAssocTuple &tuple)
Adds an interface association tuple to the Interface Association Set.
void QueueMessage(const olsr::MessageHeader &message, Time delay)
Enques an OLSR message which will be sent with a delay of (0, delay].
AttributeValue implementation for Time.
Definition: nstime.h:1342
Ipv4Address mainAddr
Main address of a node which have selected this node as a MPR.
void SendPacket(Ptr< Packet > packet, const MessageList &containedMessages)
Send an OLSR message.
void Schedule(void)
Schedule a new event using the currently-configured delay, function, and arguments.
Definition: timer.cc:158
void SetGateway(Ipv4Address gw)
Definition: ipv4-route.cc:63
OLSR routing protocol for IPv4.
void SetFunction(FN fn)
Definition: timer.h:278
An Association Tuple.
bool FindSendEntry(const RoutingTableEntry &entry, RoutingTableEntry &outEntry) const
Finds the appropriate entry which must be used in order to forward a data packet to a next hop (given...
void ProcessHello(const olsr::MessageHeader &msg, const Ipv4Address &receiverIface, const Ipv4Address &senderIface)
Processes a HELLO message following RFC 3626 specification.
std::string PrintMprSelectorSet() const
Prints the MPR selector sets.
Definition: olsr-state.cc:89
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: enum.h:203
#define DELAY(time)
Gets the delay between a given time and the current time.
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:109
IfaceAssocTuple * FindIfaceAssocTuple(const Ipv4Address &ifaceAddr)
Finds a interface association tuple.
Definition: olsr-state.cc:456
void AddAssociationTuple(const AssociationTuple &tuple)
Adds a host network association tuple to the Association Set.
void SetPacketLength(uint16_t length)
Set the packet total length.
Definition: olsr-header.h:85
Ptr< Ipv4StaticRouting > m_hnaRoutingTable
Routing table for HNA routes.
Hna & GetHna()
Set the message type to HNA and return the message content.
Definition: olsr-header.h:625
virtual uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:130
Time expirationTime
Time at which this tuple expires and must be removed.
virtual bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb)
Route an input packet (to be forwarded or locally delivered)
Timer m_tcTimer
Timer for the TC message.
Ptr< Socket > m_recvSocket
Receiving socket.
void InsertDuplicateTuple(const DuplicateTuple &tuple)
Inserts a duplicate tuple.
Definition: olsr-state.cc:322
std::vector< LinkTuple > LinkSet
Link Set type.
void RemoveDuplicateTuple(const DuplicateTuple &tuple)
Removes a duplicate tuple from the Duplicate Set.
Time GetVTime() const
Get the validity time.
Definition: olsr-header.h:203
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
Definition: socket.cc:128
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:71
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)
void EraseLinkTuple(const LinkTuple &tuple)
Erases a link tuple.
Definition: olsr-state.cc:365
void CoverTwoHopNeighbors(Ipv4Address neighborMainAddr, TwoHopNeighborSet &N2)
Remove all covered 2-hop neighbors from N2 set.
Time m_helloInterval
HELLO messages&#39; emission interval.
const Associations & GetAssociations() const
Gets the association set the node has.
Definition: olsr-state.h:385
void SetDelay(const Time &delay)
Definition: timer.cc:75
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
const MprSelectorSet & GetMprSelectors(void) const
Gets the MPR selectors.
#define OLSR_UNSPEC_LINK
Unspecified link type.
#define OLSR_NOT_NEIGH
Not neighbor type.
#define OLSR_ASYM_LINK
Asymmetric link type.
MessageType GetMessageType() const
Get the message type.
Definition: olsr-header.h:186
void SetRoutingTableAssociation(Ptr< Ipv4StaticRouting > routingTable)
Associates the specified Ipv4StaticRouting routing table to the OLSR routing protocol.
Ipv4Address destAddr
Main address of the destination.
std::vector< IfaceAssocTuple > IfaceAssocSet
Interface Association Set type.
AssociationTuple * FindAssociationTuple(const Ipv4Address &gatewayAddr, const Ipv4Address &networkAddr, const Ipv4Mask &netmask)
Finds an association tuple.
Definition: olsr-state.cc:521
void TopologyTupleTimerExpire(Ipv4Address destAddr, Ipv4Address lastAddr)
Removes topology tuple_ if expired.
Time m_tcInterval
TC messages&#39; emission interval.
void AddTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Adds a 2-hop neighbor tuple to the 2-hop Neighbor Set.
const AssociationSet & GetAssociationSet() const
Gets the association set known to the node.
Definition: olsr-state.h:376
std::vector< Ipv4Address > FindNeighborInterfaces(const Ipv4Address &neighborMainAddr) const
Returns a vector of all interfaces of a given neighbor, with the exception of the "main" one...
Definition: olsr-state.cc:504
Ipv4Address GetOriginatorAddress() const
Get the originator address.
Definition: olsr-header.h:220
void AssociationTupleTimerExpire(Ipv4Address gatewayAddr, Ipv4Address networkAddr, Ipv4Mask netmask)
Removes association tuple_ if expired.
void NeighborLoss(const LinkTuple &tuple)
Performs all actions needed when a neighbor loss occurs.
void SetOriginatorAddress(Ipv4Address originatorAddress)
Set the originator address.
Definition: olsr-header.h:212
void RemoveTopologyTuple(const TopologyTuple &tuple)
Removes a topology tuple to the Topology Set.
uint8_t willingness
A value between 0 and 7 specifying the node&#39;s willingness to carry traffic on behalf of other nodes...
Time expirationTime
Time at which this tuple expires and must be removed.
void InsertIfaceAssocTuple(const IfaceAssocTuple &tuple)
Inserts a interface association tuple.
Definition: olsr-state.cc:498
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
virtual void DoDispose(void)
Destructor implementation.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
void RecvOlsr(Ptr< Socket > socket)
Receive an OLSR message.
Ipv4Address neighborMainAddr
Main address of a neighbor node.
uint8_t willingness
The willingness of a node to carry and forward traffic for other nodes.
Definition: olsr-header.h:407
uint32_t GetInterface(void) const
address
Definition: first.py:44
std::vector< Association > associations
Association container.
Definition: olsr-header.h:525
Ipv4Address twoHopNeighborAddr
Main address of a 2-hop neighbor with a symmetric link to nb_main_addr.
bool IsMyOwnAddress(const Ipv4Address &a) const
Check that address is one of my interfaces.
bool Lookup(const Ipv4Address &dest, RoutingTableEntry &outEntry) const
Looks up an entry for the specified destination address.
static TypeId GetTypeId(void)
Get the type ID.
uint16_t GetPort(void) const
This class encapsulates all data structures needed for maintaining internal state of an OLSR node...
Definition: olsr-state.h:34
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
const TopologySet & GetTopologySet(void) const
Gets the topology set.
std::vector< RoutingTableEntry > GetRoutingTableEntries(void) const
Get the routing table entries.
Ptr< Ipv4StaticRouting > m_routingTableAssociation
Associations from an Ipv4StaticRouting instance.
void AddNeighborTuple(const NeighborTuple &tuple)
Adds a neighbor tuple to the Neighbor Set.
void SendHello(void)
Creates a new OLSR HELLO message which is buffered for being sent later on.
MprSelectorTuple * FindMprSelectorTuple(const Ipv4Address &mainAddr)
Finds a MPR selector tuple.
Definition: olsr-state.cc:38
void RemoveLinkTuple(const LinkTuple &tuple)
Removes a link tuple from the Link Set.
bool UsesNonOlsrOutgoingInterface(const Ipv4RoutingTableEntry &route)
Tests whether or not the specified route uses a non-OLSR outgoing interface.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:1343
std::vector< MessageHeader > MessageList
Definition: olsr-header.h:695
Definition: olsr.py:1
void EraseAssociationTuple(const AssociationTuple &tuple)
Erases a known association tuple.
Definition: olsr-state.cc:535
void SendTc(void)
Creates a new OLSR TC message which is buffered for being sent later on.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
void SetOutputDevice(Ptr< NetDevice > outputDevice)
Equivalent in Linux to dst_entry.dev.
Definition: ipv4-route.cc:77
Time time
Time at which this tuple expires and must be removed.
virtual void NotifyInterfaceDown(uint32_t interface)
Ipv4Address GetSubnetDirectedBroadcast(Ipv4Mask const &mask) const
Generate subnet-directed broadcast address corresponding to mask.
The basic layout of any packet in OLSR is as follows (omitting IP and UDP headers): ...
Definition: olsr-header.h:75
uint16_t m_packetSequenceNumber
Packets sequence number counter.
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:330
void PopulateTwoHopNeighborSet(const olsr::MessageHeader &msg, const olsr::MessageHeader::Hello &hello)
Updates the 2-hop Neighbor Set according to the information contained in a new received HELLO message...
This class implements Linux struct pktinfo in order to deliver ancillary information to the socket in...
void RemoveTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Removes a 2-hop neighbor tuple from the 2-hop Neighbor Set.
void RemoveEntry(const Ipv4Address &dest)
Deletes the entry whose destination address is given.
void ForwardDefault(olsr::MessageHeader olsrMessage, DuplicateTuple *duplicated, const Ipv4Address &localIface, const Ipv4Address &senderAddress)
OLSR&#39;s default forwarding algorithm.
void ProcessHna(const olsr::MessageHeader &msg, const Ipv4Address &senderIface)
Processes a HNA message following RFC 3626 specification.
bool IsRunning(void) const
Definition: timer.cc:127
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
HNA (Host Network Association) Message Format
Definition: olsr-header.h:514
virtual Ptr< Ipv4Route > RouteOutput(Ptr< Packet > p, const Ipv4Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr)
Query routing cache for an existing route, for an outbound packet.
double max(double x, double y)
int Degree(NeighborTuple const &tuple)
This auxiliary function (defined in RFC 3626) is used for calculating the MPR Set.
uint16_t GetMessageSequenceNumber() const
Get the message sequence number.
Definition: olsr-header.h:271
#define OLSR_WILL_HIGH
Willingness for forwarding packets from other nodes: high.
Hello & GetHello()
Set the message type to HELLO and return the message content.
Definition: olsr-header.h:591
uint32_t interface
Interface index.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
std::vector< NeighborTuple > NeighborSet
Neighbor Set type.
void EraseAssociation(const Association &tuple)
Erases an association.
Definition: olsr-state.cc:555
Ptr< Ipv4 > m_ipv4
IPv4 object the routing is linked to.
uint32_t GetSize(void) const
Returns the routing table size.
HELLO Message Format
Definition: olsr-header.h:376
void HelloTimerExpire(void)
Sends a HELLO message and reschedules the HELLO timer.
a class to store IPv4 address information on an interface
Ipv4Address GetMainAddress(Ipv4Address iface_addr) const
Gets the main address associated with a given interface address.
virtual void SetIpv4(Ptr< Ipv4 > ipv4)
void PopulateMprSelectorSet(const olsr::MessageHeader &msg, const olsr::MessageHeader::Hello &hello)
Updates the MPR Selector Set according to the information contained in a new received HELLO message (...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
DuplicateTuple * FindDuplicateTuple(const Ipv4Address &address, uint16_t sequenceNumber)
Finds a duplicate tuple.
Definition: olsr-state.cc:294
void InsertTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Inserts a 2-hop neighbor tuple.
Definition: olsr-state.cc:266
Ipv4Address ifaceAddr
Interface address of a node.
#define OLSR_LOST_LINK
Lost link type.
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:963
Ipv4Address nextAddr
Address of the next hop.
TracedCallback< const PacketHeader &, const MessageList & > m_txPacketTrace
Tx packet trace.
std::set< Ipv4Address > MprSet
MPR Set type.
A network Node.
Definition: node.h:56
#define OLSR_SYM_NEIGH
Symmetric neighbor type.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
Timer m_midTimer
Timer for the MID message.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1278
interfaces
Definition: first.py:48
static const uint16_t OLSR_PORT_NUMBER
port number (698)
MID Message Format
Definition: olsr-header.h:313
#define OLSR_MID_HOLD_TIME
MID holding time.
std::vector< TwoHopNeighborTuple > TwoHopNeighborSet
2-hop Neighbor Set type.
void EraseTwoHopNeighborTuple(const TwoHopNeighborTuple &tuple)
Erases a 2-hop neighbor tuple.
Definition: olsr-state.cc:216
void Track(EventId event)
Tracks a new event.
uint16_t GetMessageSequenceNumber(void)
Increments message sequence number and returns the new value.
Ptr< const AttributeChecker > MakeEnumChecker(int v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:161
static std::string FindName(Ptr< Object > object)
Given a pointer to an object, look to see if that object has a name associated with it and...
Definition: names.cc:817
Ipv4Address GetLocal(void) const
Get the local address.
Abstract base class for IPv4 routing protocols.
#define OLSR_WILL_NEVER
Willingness for forwarding packets from other nodes: never.
#define OLSR_MAX_MSGS
Maximum number of messages per packet.
void LinkTupleAdded(const LinkTuple &tuple, uint8_t willingness)
Adds a link tuple.
void SetInterfaceExclusions(std::set< uint32_t > exceptions)
Set the interfaces to be excluded.
LinkTuple & InsertLinkTuple(const LinkTuple &tuple)
Inserts a link tuple.
Definition: olsr-state.cc:379
Time m_hnaInterval
HNA messages&#39; emission interval.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:472
void Dump(void)
Dump the neighbor table, two-hop neighbor table, and routing table to logging output (NS_LOG_DEBUG lo...
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
Ipv4Address neighborMainAddr
Main address of a neighbor.
Timer m_hnaTimer
Timer for the HNA message.
std::vector< MprSelectorTuple > MprSelectorSet
MPR Selector Set type.
second
Definition: nstime.h:115
virtual void DoInitialize(void)
Initialize() implementation.
void EraseNeighborTuple(const NeighborTuple &neighborTuple)
Erases a neighbor tuple.
Definition: olsr-state.cc:154
const TwoHopNeighborSet & GetTwoHopNeighbors(void) const
Get the two hop neighbors.
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)=0
Read a single packet from the socket and retrieve the sender address.
void AddDuplicateTuple(const DuplicateTuple &tuple)
Adds a duplicate tuple to the Duplicate Set.
void SetMessageSequenceNumber(uint16_t messageSequenceNumber)
Set the message sequence number.
Definition: olsr-header.h:263
Ipv4Address address
Originator address of the message.
TopologyTuple * FindNewerTopologyTuple(const Ipv4Address &lastAddr, uint16_t ansn)
Finds a topology tuple.
Definition: olsr-state.cc:403
void RemoveNeighborTuple(const NeighborTuple &tuple)
Removes a neighbor tuple from the Neighbor Set.
virtual Ptr< Ipv4 > GetIpv4(void) const
virtual int Close(void)=0
Close a socket.
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
Ipv4Address gatewayAddr
Main address of the gateway.
OlsrState m_state
Internal state with all needed data structs.
const OlsrState & GetOlsrState(void) const
Gets the underlying OLSR state object.
void RoutingTableComputation(void)
Creates the routing table of the node following RFC 3626 hints.
void AddMprSelectorTuple(const MprSelectorTuple &tuple)
Adds an MPR selector tuple to the MPR Selector Set.
TracedCallback< uint32_t > m_routingTableChanged
Routing table chanes challback.
#define OLSR_HNA_HOLD_TIME
HNA holding time.
Ipv4Address networkAddr
IPv4 Network address.
a unique identifier for an interface.
Definition: type-id.h:58
An Interface Association Tuple.
bool retransmitted
Indicates whether the message has been retransmitted or not.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
void EraseMprSelectorTuple(const MprSelectorTuple &tuple)
Erases a MPR selector tuple.
Definition: olsr-state.cc:52
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
void InsertAssociation(const Association &tuple)
Inserts an association tuple.
Definition: olsr-state.cc:569
uint16_t sequenceNumber
Message sequence number.
std::vector< AssociationTuple > AssociationSet
Association Set type.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
virtual void SetIpTtl(uint8_t ipTtl)
Manually set IP Time to Live field.
Definition: socket.cc:513
olsr::MessageList m_queuedMessages
A list of pending messages which are buffered awaiting for being sent.
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random variables.
void SetDestination(Ipv4Address dest)
Definition: ipv4-route.cc:35
Ipv4Address GetIpv4(void) const
Time expirationTime
Time at which this tuple expires and must be removed.
void EraseTwoHopNeighborTuples(const Ipv4Address &neighbor)
Erases the 2-hop neighbor tuples with the same 1-hop neighbor.
Definition: olsr-state.cc:249
void IncrementAnsn(void)
Increments the ANSN counter.
void InsertTopologyTuple(const TopologyTuple &tuple)
Inserts a topology tuple.
Definition: olsr-state.cc:448
MprSet GetMprSet(void) const
Gets the MPR set.
std::vector< Ipv4Address > ifaceList
List of interfaces which the message has been received on.
void ProcessMid(const olsr::MessageHeader &msg, const Ipv4Address &senderIface)
Processes a MID message following RFC 3626 specification.