A Discrete-Event Network Simulator
API
dsdv-rtable.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010 Hemanth Narra
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Hemanth Narra <hemanth@ittc.ku.com>
18  *
19  * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
20  * ResiliNets Research Group https://resilinets.org/
21  * Information and Telecommunication Technology Center (ITTC)
22  * and Department of Electrical Engineering and Computer Science
23  * The University of Kansas Lawrence, KS USA.
24  *
25  * Work supported in part by NSF FIND (Future Internet Design) Program
26  * under grant CNS-0626918 (Postmodern Internet Architecture),
27  * NSF grant CNS-1050226 (Multilayer Network Resilience Analysis and Experimentation on GENI),
28  * US Department of Defense (DoD), and ITTC at The University of Kansas.
29  */
30 #include "dsdv-rtable.h"
31 
32 #include "ns3/log.h"
33 #include "ns3/simulator.h"
34 
35 #include <iomanip>
36 
37 namespace ns3
38 {
39 
40 NS_LOG_COMPONENT_DEFINE("DsdvRoutingTable");
41 
42 namespace dsdv
43 {
45  Ipv4Address dst,
46  uint32_t seqNo,
48  uint32_t hops,
49  Ipv4Address nextHop,
50  Time lifetime,
51  Time settlingTime,
52  bool areChanged)
53  : m_seqNo(seqNo),
54  m_hops(hops),
55  m_lifeTime(lifetime),
56  m_iface(iface),
57  m_flag(VALID),
58  m_settlingTime(settlingTime),
59  m_entriesChanged(areChanged)
60 {
61  m_ipv4Route = Create<Ipv4Route>();
62  m_ipv4Route->SetDestination(dst);
63  m_ipv4Route->SetGateway(nextHop);
64  m_ipv4Route->SetSource(m_iface.GetLocal());
65  m_ipv4Route->SetOutputDevice(dev);
66 }
67 
69 {
70 }
71 
73 {
74 }
75 
76 bool
78 {
79  if (m_ipv4AddressEntry.empty())
80  {
81  return false;
82  }
83  std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = m_ipv4AddressEntry.find(id);
84  if (i == m_ipv4AddressEntry.end())
85  {
86  return false;
87  }
88  rt = i->second;
89  return true;
90 }
91 
92 bool
94 {
95  if (m_ipv4AddressEntry.empty())
96  {
97  return false;
98  }
99  std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = m_ipv4AddressEntry.find(id);
100  if (i == m_ipv4AddressEntry.end())
101  {
102  return false;
103  }
104  if (forRouteInput == true && id == i->second.GetInterface().GetBroadcast())
105  {
106  return false;
107  }
108  rt = i->second;
109  return true;
110 }
111 
112 bool
114 {
115  if (m_ipv4AddressEntry.erase(dst) != 0)
116  {
117  // NS_LOG_DEBUG("Route erased");
118  return true;
119  }
120  return false;
121 }
122 
123 uint32_t
125 {
126  return m_ipv4AddressEntry.size();
127 }
128 
129 bool
131 {
132  std::pair<std::map<Ipv4Address, RoutingTableEntry>::iterator, bool> result =
133  m_ipv4AddressEntry.insert(std::make_pair(rt.GetDestination(), rt));
134  return result.second;
135 }
136 
137 bool
139 {
140  std::map<Ipv4Address, RoutingTableEntry>::iterator i =
142  if (i == m_ipv4AddressEntry.end())
143  {
144  return false;
145  }
146  i->second = rt;
147  return true;
148 }
149 
150 void
152 {
153  if (m_ipv4AddressEntry.empty())
154  {
155  return;
156  }
157  for (std::map<Ipv4Address, RoutingTableEntry>::iterator i = m_ipv4AddressEntry.begin();
158  i != m_ipv4AddressEntry.end();)
159  {
160  if (i->second.GetInterface() == iface)
161  {
162  std::map<Ipv4Address, RoutingTableEntry>::iterator tmp = i;
163  ++i;
164  m_ipv4AddressEntry.erase(tmp);
165  }
166  else
167  {
168  ++i;
169  }
170  }
171 }
172 
173 void
174 RoutingTable::GetListOfAllRoutes(std::map<Ipv4Address, RoutingTableEntry>& allRoutes)
175 {
176  for (std::map<Ipv4Address, RoutingTableEntry>::iterator i = m_ipv4AddressEntry.begin();
177  i != m_ipv4AddressEntry.end();
178  ++i)
179  {
180  if (i->second.GetDestination() != Ipv4Address("127.0.0.1") && i->second.GetFlag() == VALID)
181  {
182  allRoutes.insert(std::make_pair(i->first, i->second));
183  }
184  }
185 }
186 
187 void
189  std::map<Ipv4Address, RoutingTableEntry>& unreachable)
190 {
191  unreachable.clear();
192  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = m_ipv4AddressEntry.begin();
193  i != m_ipv4AddressEntry.end();
194  ++i)
195  {
196  if (i->second.GetNextHop() == nextHop)
197  {
198  unreachable.insert(std::make_pair(i->first, i->second));
199  }
200  }
201 }
202 
203 void
205 {
206  std::ostream* os = stream->GetStream();
207  // Copy the current ostream state
208  std::ios oldState(nullptr);
209  oldState.copyfmt(*os);
210 
211  *os << std::resetiosflags(std::ios::adjustfield) << std::setiosflags(std::ios::left);
212 
213  std::ostringstream dest;
214  std::ostringstream gw;
215  std::ostringstream iface;
216  std::ostringstream ltime;
217  std::ostringstream stime;
218  dest << m_ipv4Route->GetDestination();
219  gw << m_ipv4Route->GetGateway();
220  iface << m_iface.GetLocal();
221  ltime << std::setprecision(3) << (Simulator::Now() - m_lifeTime).As(unit);
222  stime << m_settlingTime.As(unit);
223 
224  *os << std::setw(16) << dest.str();
225  *os << std::setw(16) << gw.str();
226  *os << std::setw(16) << iface.str();
227  *os << std::setw(16) << m_hops;
228  *os << std::setw(16) << m_seqNo;
229  *os << std::setw(16) << ltime.str();
230  *os << stime.str() << std::endl;
231  // Restore the previous ostream state
232  (*os).copyfmt(oldState);
233 }
234 
235 void
236 RoutingTable::Purge(std::map<Ipv4Address, RoutingTableEntry>& removedAddresses)
237 {
238  if (m_ipv4AddressEntry.empty())
239  {
240  return;
241  }
242  for (std::map<Ipv4Address, RoutingTableEntry>::iterator i = m_ipv4AddressEntry.begin();
243  i != m_ipv4AddressEntry.end();)
244  {
245  std::map<Ipv4Address, RoutingTableEntry>::iterator itmp = i;
246  if (i->second.GetLifeTime() > m_holddownTime && (i->second.GetHop() > 0))
247  {
248  for (std::map<Ipv4Address, RoutingTableEntry>::iterator j = m_ipv4AddressEntry.begin();
249  j != m_ipv4AddressEntry.end();)
250  {
251  if ((j->second.GetNextHop() == i->second.GetDestination()) &&
252  (i->second.GetHop() != j->second.GetHop()))
253  {
254  std::map<Ipv4Address, RoutingTableEntry>::iterator jtmp = j;
255  removedAddresses.insert(std::make_pair(j->first, j->second));
256  ++j;
257  m_ipv4AddressEntry.erase(jtmp);
258  }
259  else
260  {
261  ++j;
262  }
263  }
264  removedAddresses.insert(std::make_pair(i->first, i->second));
265  ++i;
266  m_ipv4AddressEntry.erase(itmp);
267  }
269  /* else if (i->second.GetLifeTime() > m_holddownTime)
270  {
271  ++i;
272  itmp->second.SetFlag(INVALID);
273  }*/
274  else
275  {
276  ++i;
277  }
278  }
279 }
280 
281 void
282 RoutingTable::Print(Ptr<OutputStreamWrapper> stream, Time::Unit unit /*= Time::S*/) const
283 {
284  std::ostream* os = stream->GetStream();
285  // Copy the current ostream state
286  std::ios oldState(nullptr);
287  oldState.copyfmt(*os);
288 
289  *os << std::resetiosflags(std::ios::adjustfield) << std::setiosflags(std::ios::left);
290 
291  *os << "\nDSDV Routing table\n";
292  *os << std::setw(16) << "Destination";
293  *os << std::setw(16) << "Gateway";
294  *os << std::setw(16) << "Interface";
295  *os << std::setw(16) << "HopCount";
296  *os << std::setw(16) << "SeqNum";
297  *os << std::setw(16) << "LifeTime";
298  *os << "SettlingTime" << std::endl;
299  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator i = m_ipv4AddressEntry.begin();
300  i != m_ipv4AddressEntry.end();
301  ++i)
302  {
303  i->second.Print(stream, unit);
304  }
305  *os << std::endl;
306  // Restore the previous ostream state
307  (*os).copyfmt(oldState);
308 }
309 
310 bool
312 {
313  std::pair<std::map<Ipv4Address, EventId>::iterator, bool> result =
314  m_ipv4Events.insert(std::make_pair(address, id));
315  return result.second;
316 }
317 
318 bool
320 {
321  EventId event;
322  std::map<Ipv4Address, EventId>::const_iterator i = m_ipv4Events.find(address);
323  if (m_ipv4Events.empty())
324  {
325  return false;
326  }
327  if (i == m_ipv4Events.end())
328  {
329  return false;
330  }
331  event = i->second;
332  if (event.IsRunning())
333  {
334  return true;
335  }
336  else
337  {
338  return false;
339  }
340 }
341 
342 bool
344 {
345  EventId event;
346  std::map<Ipv4Address, EventId>::const_iterator i = m_ipv4Events.find(address);
347  if (m_ipv4Events.empty() || i == m_ipv4Events.end())
348  {
349  return false;
350  }
351  event = i->second;
352  Simulator::Cancel(event);
353  m_ipv4Events.erase(address);
354  return true;
355 }
356 
357 bool
359 {
360  EventId event;
361  std::map<Ipv4Address, EventId>::const_iterator i = m_ipv4Events.find(address);
362  if (m_ipv4Events.empty() || i == m_ipv4Events.end())
363  {
364  return false;
365  }
366  event = i->second;
367  if (event.IsRunning())
368  {
369  return false;
370  }
371  if (event.IsExpired())
372  {
373  event.Cancel();
374  m_ipv4Events.erase(address);
375  return true;
376  }
377  else
378  {
379  m_ipv4Events.erase(address);
380  return true;
381  }
382 }
383 
384 EventId
386 {
387  std::map<Ipv4Address, EventId>::const_iterator i = m_ipv4Events.find(address);
388  if (m_ipv4Events.empty() || i == m_ipv4Events.end())
389  {
390  return EventId();
391  }
392  else
393  {
394  return i->second;
395  }
396 }
397 } // namespace dsdv
398 } // namespace ns3
An identifier for simulation events.
Definition: event-id.h:55
bool IsExpired() const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:69
bool IsRunning() const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:76
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:43
a class to store IPv4 address information on an interface
Ipv4Address GetLocal() const
Get the local address.
std::ostream * GetStream()
Return a pointer to an ostream previously set in the wrapper.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition: simulator.cc:276
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:417
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:111
Routing table entry.
Definition: dsdv-rtable.h:59
uint32_t m_seqNo
Destination Sequence Number.
Definition: dsdv-rtable.h:295
void Print(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print routing table entry.
Definition: dsdv-rtable.cc:204
Time m_lifeTime
Expiration or deletion time of the route Lifetime field in the routing table plays dual role – for an...
Definition: dsdv-rtable.h:304
Ipv4Address GetDestination() const
Get destination IP address.
Definition: dsdv-rtable.h:90
~RoutingTableEntry()
Definition: dsdv-rtable.cc:68
Ipv4InterfaceAddress m_iface
Output interface address.
Definition: dsdv-rtable.h:313
RoutingTableEntry(Ptr< NetDevice > dev=nullptr, Ipv4Address dst=Ipv4Address(), uint32_t seqNo=0, Ipv4InterfaceAddress iface=Ipv4InterfaceAddress(), uint32_t hops=0, Ipv4Address nextHop=Ipv4Address(), Time lifetime=Simulator::Now(), Time settlingTime=Simulator::Now(), bool changedEntries=false)
c-tor
Definition: dsdv-rtable.cc:44
Ptr< Ipv4Route > m_ipv4Route
Ip route, include.
Definition: dsdv-rtable.h:311
Time m_settlingTime
Time for which the node retains an update with changed metric before broadcasting it.
Definition: dsdv-rtable.h:318
uint32_t m_hops
Hop Count (number of hops needed to reach destination)
Definition: dsdv-rtable.h:297
bool LookupRoute(Ipv4Address dst, RoutingTableEntry &rt)
Lookup routing table entry with destination address dst.
Definition: dsdv-rtable.cc:77
Time m_holddownTime
hold down time of an expired route
Definition: dsdv-rtable.h:466
bool DeleteRoute(Ipv4Address dst)
Delete routing table entry with destination address dst, if it exists.
Definition: dsdv-rtable.cc:113
bool ForceDeleteIpv4Event(Ipv4Address address)
Force delete an update waiting for settling time to complete as a better update to same destination w...
Definition: dsdv-rtable.cc:343
bool AddRoute(RoutingTableEntry &r)
Add routing table entry if it doesn't yet exist in routing table.
Definition: dsdv-rtable.cc:130
bool DeleteIpv4Event(Ipv4Address address)
Clear up the entry from the map after the event is completed.
Definition: dsdv-rtable.cc:358
bool Update(RoutingTableEntry &rt)
Updating the routing Table with routing table entry rt.
Definition: dsdv-rtable.cc:138
std::map< Ipv4Address, RoutingTableEntry > m_ipv4AddressEntry
an entry in the routing table.
Definition: dsdv-rtable.h:462
void GetListOfDestinationWithNextHop(Ipv4Address nxtHp, std::map< Ipv4Address, RoutingTableEntry > &dstList)
Lookup list of addresses for which nxtHp is the next Hop address.
Definition: dsdv-rtable.cc:188
void Print(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print routing table.
Definition: dsdv-rtable.cc:282
void DeleteAllRoutesFromInterface(Ipv4InterfaceAddress iface)
Delete all route from interface with address iface.
Definition: dsdv-rtable.cc:151
EventId GetEventId(Ipv4Address address)
Get the EventId associated with that address.
Definition: dsdv-rtable.cc:385
bool AddIpv4Event(Ipv4Address address, EventId id)
Add an event for a destination address so that the update to for that destination is sent after the e...
Definition: dsdv-rtable.cc:311
uint32_t RoutingTableSize()
Provides the number of routes present in that nodes routing table.
Definition: dsdv-rtable.cc:124
std::map< Ipv4Address, EventId > m_ipv4Events
an entry in the event table.
Definition: dsdv-rtable.h:464
bool AnyRunningEvent(Ipv4Address address)
Force delete an update waiting for settling time to complete as a better update to same destination w...
Definition: dsdv-rtable.cc:319
void Purge(std::map< Ipv4Address, RoutingTableEntry > &removedAddresses)
Delete all outdated entries if Lifetime is expired.
Definition: dsdv-rtable.cc:236
void GetListOfAllRoutes(std::map< Ipv4Address, RoutingTableEntry > &allRoutes)
Lookup list of all addresses in the routing table.
Definition: dsdv-rtable.cc:174
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
address
Definition: first.py:40
Every class exported by the ns3 library is enclosed in the ns3 namespace.