A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ipv4-static-routing.cc
1 // -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*-
2 //
3 // Copyright (c) 2006 Georgia Tech Research Corporation
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License version 2 as
7 // published by the Free Software Foundation;
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 //
18 // Author: George F. Riley<riley@ece.gatech.edu>
19 // Gustavo Carneiro <gjc@inescporto.pt>
20 
21 #define NS_LOG_APPEND_CONTEXT \
22  if (m_ipv4 && m_ipv4->GetObject<Node> ()) { \
23  std::clog << Simulator::Now ().GetSeconds () \
24  << " [node " << m_ipv4->GetObject<Node> ()->GetId () << "] "; }
25 
26 #include <iomanip>
27 #include "ns3/log.h"
28 #include "ns3/names.h"
29 #include "ns3/packet.h"
30 #include "ns3/node.h"
31 #include "ns3/simulator.h"
32 #include "ns3/ipv4-route.h"
33 #include "ns3/output-stream-wrapper.h"
34 #include "ipv4-static-routing.h"
35 #include "ipv4-routing-table-entry.h"
36 
37 NS_LOG_COMPONENT_DEFINE ("Ipv4StaticRoung");
38 
39 using std::make_pair;
40 
41 namespace ns3 {
42 
43 NS_OBJECT_ENSURE_REGISTERED (Ipv4StaticRouting);
44 
45 TypeId
46 Ipv4StaticRouting::GetTypeId (void)
47 {
48  static TypeId tid = TypeId ("ns3::Ipv4StaticRouting")
49  .SetParent<Ipv4RoutingProtocol> ()
50  .AddConstructor<Ipv4StaticRouting> ()
51  ;
52  return tid;
53 }
54 
55 Ipv4StaticRouting::Ipv4StaticRouting ()
56  : m_ipv4 (0)
57 {
58  NS_LOG_FUNCTION (this);
59 }
60 
61 void
63  Ipv4Mask networkMask,
64  Ipv4Address nextHop,
65  uint32_t interface,
66  uint32_t metric)
67 {
68  NS_LOG_FUNCTION (this << network << " " << networkMask << " " << nextHop << " " << interface << " " << metric);
71  networkMask,
72  nextHop,
73  interface);
74  m_networkRoutes.push_back (make_pair (route,metric));
75 }
76 
77 void
79  Ipv4Mask networkMask,
80  uint32_t interface,
81  uint32_t metric)
82 {
83  NS_LOG_FUNCTION (this << network << " " << networkMask << " " << interface << " " << metric);
86  networkMask,
87  interface);
88  m_networkRoutes.push_back (make_pair (route,metric));
89 }
90 
91 void
93  Ipv4Address nextHop,
94  uint32_t interface,
95  uint32_t metric)
96 {
97  NS_LOG_FUNCTION (this << dest << " " << nextHop << " " << interface << " " << metric);
98  AddNetworkRouteTo (dest, Ipv4Mask::GetOnes (), nextHop, interface, metric);
99 }
100 
101 void
103  uint32_t interface,
104  uint32_t metric)
105 {
106  NS_LOG_FUNCTION (this << dest << " " << interface << " " << metric);
107  AddNetworkRouteTo (dest, Ipv4Mask::GetOnes (), interface, metric);
108 }
109 
110 void
112  uint32_t interface,
113  uint32_t metric)
114 {
115  NS_LOG_FUNCTION (this << nextHop << " " << interface << " " << metric);
116  AddNetworkRouteTo (Ipv4Address ("0.0.0.0"), Ipv4Mask::GetZero (), nextHop, interface, metric);
117 }
118 
119 void
121  Ipv4Address group,
122  uint32_t inputInterface,
123  std::vector<uint32_t> outputInterfaces)
124 {
125  NS_LOG_FUNCTION (this << origin << " " << group << " " << inputInterface << " " << &outputInterfaces);
128  inputInterface, outputInterfaces);
129  m_multicastRoutes.push_back (route);
130 }
131 
132 // default multicast routes are stored as a network route
133 // these routes are _not_ consulted in the forwarding process-- only
134 // for originating packets
135 void
137 {
138  NS_LOG_FUNCTION (this << outputInterface);
140  Ipv4Address network = Ipv4Address ("224.0.0.0");
141  Ipv4Mask networkMask = Ipv4Mask ("240.0.0.0");
143  networkMask,
144  outputInterface);
145  m_networkRoutes.push_back (make_pair (route,0));
146 }
147 
148 uint32_t
150 {
151  NS_LOG_FUNCTION (this);
152  return m_multicastRoutes.size ();
153 }
154 
157 {
158  NS_LOG_FUNCTION (this << index);
159  NS_ASSERT_MSG (index < m_multicastRoutes.size (),
160  "Ipv4StaticRouting::GetMulticastRoute (): Index out of range");
161 
162  if (index < m_multicastRoutes.size ())
163  {
164  uint32_t tmp = 0;
165  for (MulticastRoutesCI i = m_multicastRoutes.begin ();
166  i != m_multicastRoutes.end ();
167  i++)
168  {
169  if (tmp == index)
170  {
171  return *i;
172  }
173  tmp++;
174  }
175  }
176  return 0;
177 }
178 
179 bool
181  Ipv4Address group,
182  uint32_t inputInterface)
183 {
184  NS_LOG_FUNCTION (this << origin << " " << group << " " << inputInterface);
185  for (MulticastRoutesI i = m_multicastRoutes.begin ();
186  i != m_multicastRoutes.end ();
187  i++)
188  {
189  Ipv4MulticastRoutingTableEntry *route = *i;
190  if (origin == route->GetOrigin () &&
191  group == route->GetGroup () &&
192  inputInterface == route->GetInputInterface ())
193  {
194  delete *i;
195  m_multicastRoutes.erase (i);
196  return true;
197  }
198  }
199  return false;
200 }
201 
202 void
204 {
205  NS_LOG_FUNCTION (this << index);
206  uint32_t tmp = 0;
207  for (MulticastRoutesI i = m_multicastRoutes.begin ();
208  i != m_multicastRoutes.end ();
209  i++)
210  {
211  if (tmp == index)
212  {
213  delete *i;
214  m_multicastRoutes.erase (i);
215  return;
216  }
217  tmp++;
218  }
219 }
220 
222 Ipv4StaticRouting::LookupStatic (Ipv4Address dest, Ptr<NetDevice> oif)
223 {
224  NS_LOG_FUNCTION (this << dest << " " << oif);
225  Ptr<Ipv4Route> rtentry = 0;
226  uint16_t longest_mask = 0;
227  uint32_t shortest_metric = 0xffffffff;
228  /* when sending on local multicast, there have to be interface specified */
229  if (dest.IsLocalMulticast ())
230  {
231  NS_ASSERT_MSG (oif, "Try to send on link-local multicast address, and no interface index is given!");
232 
233  rtentry = Create<Ipv4Route> ();
234  rtentry->SetDestination (dest);
235  rtentry->SetGateway (Ipv4Address::GetZero ());
236  rtentry->SetOutputDevice (oif);
237  rtentry->SetSource (m_ipv4->GetAddress (oif->GetIfIndex (), 0).GetLocal ());
238  return rtentry;
239  }
240 
241 
242  for (NetworkRoutesI i = m_networkRoutes.begin ();
243  i != m_networkRoutes.end ();
244  i++)
245  {
246  Ipv4RoutingTableEntry *j=i->first;
247  uint32_t metric =i->second;
248  Ipv4Mask mask = (j)->GetDestNetworkMask ();
249  uint16_t masklen = mask.GetPrefixLength ();
250  Ipv4Address entry = (j)->GetDestNetwork ();
251  NS_LOG_LOGIC ("Searching for route to " << dest << ", checking against route to " << entry << "/" << masklen);
252  if (mask.IsMatch (dest, entry))
253  {
254  NS_LOG_LOGIC ("Found global network route " << j << ", mask length " << masklen << ", metric " << metric);
255  if (oif != 0)
256  {
257  if (oif != m_ipv4->GetNetDevice (j->GetInterface ()))
258  {
259  NS_LOG_LOGIC ("Not on requested interface, skipping");
260  continue;
261  }
262  }
263  if (masklen < longest_mask) // Not interested if got shorter mask
264  {
265  NS_LOG_LOGIC ("Previous match longer, skipping");
266  continue;
267  }
268  if (masklen > longest_mask) // Reset metric if longer masklen
269  {
270  shortest_metric = 0xffffffff;
271  }
272  longest_mask = masklen;
273  if (metric > shortest_metric)
274  {
275  NS_LOG_LOGIC ("Equal mask length, but previous metric shorter, skipping");
276  continue;
277  }
278  shortest_metric = metric;
279  Ipv4RoutingTableEntry* route = (j);
280  uint32_t interfaceIdx = route->GetInterface ();
281  rtentry = Create<Ipv4Route> ();
282  rtentry->SetDestination (route->GetDest ());
283  rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetDest ()));
284  rtentry->SetGateway (route->GetGateway ());
285  rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
286  }
287  }
288  if (rtentry != 0)
289  {
290  NS_LOG_LOGIC ("Matching route via " << rtentry->GetGateway () << " at the end");
291  }
292  else
293  {
294  NS_LOG_LOGIC ("No matching route to " << dest << " found");
295  }
296  return rtentry;
297 }
298 
299 Ptr<Ipv4MulticastRoute>
300 Ipv4StaticRouting::LookupStatic (
301  Ipv4Address origin,
302  Ipv4Address group,
303  uint32_t interface)
304 {
305  NS_LOG_FUNCTION (this << origin << " " << group << " " << interface);
306  Ptr<Ipv4MulticastRoute> mrtentry = 0;
307 
308  for (MulticastRoutesI i = m_multicastRoutes.begin ();
309  i != m_multicastRoutes.end ();
310  i++)
311  {
312  Ipv4MulticastRoutingTableEntry *route = *i;
313 //
314 // We've been passed an origin address, a multicast group address and an
315 // interface index. We have to decide if the current route in the list is
316 // a match.
317 //
318 // The first case is the restrictive case where the origin, group and index
319 // matches.
320 //
321  if (origin == route->GetOrigin () && group == route->GetGroup ())
322  {
323  // Skipping this case (SSM) for now
324  NS_LOG_LOGIC ("Found multicast source specific route" << *i);
325  }
326  if (group == route->GetGroup ())
327  {
328  if (interface == Ipv4::IF_ANY ||
329  interface == route->GetInputInterface ())
330  {
331  NS_LOG_LOGIC ("Found multicast route" << *i);
332  mrtentry = Create<Ipv4MulticastRoute> ();
333  mrtentry->SetGroup (route->GetGroup ());
334  mrtentry->SetOrigin (route->GetOrigin ());
335  mrtentry->SetParent (route->GetInputInterface ());
336  for (uint32_t j = 0; j < route->GetNOutputInterfaces (); j++)
337  {
338  if (route->GetOutputInterface (j))
339  {
340  NS_LOG_LOGIC ("Setting output interface index " << route->GetOutputInterface (j));
341  mrtentry->SetOutputTtl (route->GetOutputInterface (j), Ipv4MulticastRoute::MAX_TTL - 1);
342  }
343  }
344  return mrtentry;
345  }
346  }
347  }
348  return mrtentry;
349 }
350 
351 uint32_t
353 {
354  NS_LOG_FUNCTION (this);
355  return m_networkRoutes.size ();;
356 }
357 
360 {
361  NS_LOG_FUNCTION (this);
362  // Basically a repeat of LookupStatic, retained for backward compatibility
363  Ipv4Address dest ("0.0.0.0");
364  uint32_t shortest_metric = 0xffffffff;
365  Ipv4RoutingTableEntry *result = 0;
366  for (NetworkRoutesI i = m_networkRoutes.begin ();
367  i != m_networkRoutes.end ();
368  i++)
369  {
370  Ipv4RoutingTableEntry *j = i->first;
371  uint32_t metric = i->second;
372  Ipv4Mask mask = (j)->GetDestNetworkMask ();
373  uint16_t masklen = mask.GetPrefixLength ();
374  if (masklen != 0)
375  {
376  continue;
377  }
378  if (metric > shortest_metric)
379  {
380  continue;
381  }
382  shortest_metric = metric;
383  result = j;
384  }
385  if (result)
386  {
387  return result;
388  }
389  else
390  {
391  return Ipv4RoutingTableEntry ();
392  }
393 }
394 
396 Ipv4StaticRouting::GetRoute (uint32_t index) const
397 {
398  NS_LOG_FUNCTION (this << index);
399  uint32_t tmp = 0;
400  for (NetworkRoutesCI j = m_networkRoutes.begin ();
401  j != m_networkRoutes.end ();
402  j++)
403  {
404  if (tmp == index)
405  {
406  return j->first;
407  }
408  tmp++;
409  }
410  NS_ASSERT (false);
411  // quiet compiler.
412  return 0;
413 }
414 
415 uint32_t
416 Ipv4StaticRouting::GetMetric (uint32_t index) const
417 {
418  NS_LOG_FUNCTION (this << index);
419  uint32_t tmp = 0;
420  for (NetworkRoutesCI j = m_networkRoutes.begin ();
421  j != m_networkRoutes.end ();
422  j++)
423  {
424  if (tmp == index)
425  {
426  return j->second;
427  }
428  tmp++;
429  }
430  NS_ASSERT (false);
431  // quiet compiler.
432  return 0;
433 }
434 void
436 {
437  NS_LOG_FUNCTION (this << index);
438  uint32_t tmp = 0;
439  for (NetworkRoutesI j = m_networkRoutes.begin ();
440  j != m_networkRoutes.end ();
441  j++)
442  {
443  if (tmp == index)
444  {
445  delete j->first;
446  m_networkRoutes.erase (j);
447  return;
448  }
449  tmp++;
450  }
451  NS_ASSERT (false);
452 }
453 
455 Ipv4StaticRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
456 {
457  NS_LOG_FUNCTION (this << p<< header << oif << sockerr);
458  Ipv4Address destination = header.GetDestination ();
459  Ptr<Ipv4Route> rtentry = 0;
460 
461  // Multicast goes here
462  if (destination.IsMulticast ())
463  {
464  // Note: Multicast routes for outbound packets are stored in the
465  // normal unicast table. An implication of this is that it is not
466  // possible to source multicast datagrams on multiple interfaces.
467  // This is a well-known property of sockets implementation on
468  // many Unix variants.
469  // So, we just log it and fall through to LookupStatic ()
470  NS_LOG_LOGIC ("RouteOutput()::Multicast destination");
471  }
472  rtentry = LookupStatic (destination, oif);
473  if (rtentry)
474  {
475  sockerr = Socket::ERROR_NOTERROR;
476  }
477  else
478  {
479  sockerr = Socket::ERROR_NOROUTETOHOST;
480  }
481  return rtentry;
482 }
483 
484 bool
488 {
489  NS_LOG_FUNCTION (this << p << ipHeader << ipHeader.GetSource () << ipHeader.GetDestination () << idev << &ucb << &mcb << &lcb << &ecb);
490 
491  NS_ASSERT (m_ipv4 != 0);
492  // Check if input device supports IP
493  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
494  uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
495 
496  // Multicast recognition; handle local delivery here
497  //
498  if (ipHeader.GetDestination ().IsMulticast ())
499  {
500  NS_LOG_LOGIC ("Multicast destination");
501  Ptr<Ipv4MulticastRoute> mrtentry = LookupStatic (ipHeader.GetSource (),
502  ipHeader.GetDestination (), m_ipv4->GetInterfaceForDevice (idev));
503 
504  if (mrtentry)
505  {
506  NS_LOG_LOGIC ("Multicast route found");
507  mcb (mrtentry, p, ipHeader); // multicast forwarding callback
508  return true;
509  }
510  else
511  {
512  NS_LOG_LOGIC ("Multicast route not found");
513  return false; // Let other routing protocols try to handle this
514  }
515  }
516  if (ipHeader.GetDestination ().IsBroadcast ())
517  {
518  NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)");
519  // TODO: Local Deliver for broadcast
520  // TODO: Forward broadcast
521  }
522 
523  NS_LOG_LOGIC ("Unicast destination");
524  // TODO: Configurable option to enable RFC 1222 Strong End System Model
525  // Right now, we will be permissive and allow a source to send us
526  // a packet to one of our other interface addresses; that is, the
527  // destination unicast address does not match one of the iif addresses,
528  // but we check our other interfaces. This could be an option
529  // (to remove the outer loop immediately below and just check iif).
530  for (uint32_t j = 0; j < m_ipv4->GetNInterfaces (); j++)
531  {
532  for (uint32_t i = 0; i < m_ipv4->GetNAddresses (j); i++)
533  {
534  Ipv4InterfaceAddress iaddr = m_ipv4->GetAddress (j, i);
535  Ipv4Address addr = iaddr.GetLocal ();
536  if (addr.IsEqual (ipHeader.GetDestination ()))
537  {
538  if (j == iif)
539  {
540  NS_LOG_LOGIC ("For me (destination " << addr << " match)");
541  }
542  else
543  {
544  NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << ipHeader.GetDestination ());
545  }
546  lcb (p, ipHeader, iif);
547  return true;
548  }
549  if (ipHeader.GetDestination ().IsEqual (iaddr.GetBroadcast ()))
550  {
551  NS_LOG_LOGIC ("For me (interface broadcast address)");
552  lcb (p, ipHeader, iif);
553  return true;
554  }
555  NS_LOG_LOGIC ("Address "<< addr << " not a match");
556  }
557  }
558  // Check if input device supports IP forwarding
559  if (m_ipv4->IsForwarding (iif) == false)
560  {
561  NS_LOG_LOGIC ("Forwarding disabled for this interface");
562  ecb (p, ipHeader, Socket::ERROR_NOROUTETOHOST);
563  return false;
564  }
565  // Next, try to find a route
566  Ptr<Ipv4Route> rtentry = LookupStatic (ipHeader.GetDestination ());
567  if (rtentry != 0)
568  {
569  NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
570  ucb (rtentry, p, ipHeader); // unicast forwarding callback
571  return true;
572  }
573  else
574  {
575  NS_LOG_LOGIC ("Did not find unicast destination- returning false");
576  return false; // Let other routing protocols try to handle this
577  }
578 }
579 
580 Ipv4StaticRouting::~Ipv4StaticRouting ()
581 {
582  NS_LOG_FUNCTION (this);
583 }
584 
585 void
587 {
588  NS_LOG_FUNCTION (this);
589  for (NetworkRoutesI j = m_networkRoutes.begin ();
590  j != m_networkRoutes.end ();
591  j = m_networkRoutes.erase (j))
592  {
593  delete (j->first);
594  }
595  for (MulticastRoutesI i = m_multicastRoutes.begin ();
596  i != m_multicastRoutes.end ();
597  i = m_multicastRoutes.erase (i))
598  {
599  delete (*i);
600  }
601  m_ipv4 = 0;
603 }
604 
605 void
607 {
608  NS_LOG_FUNCTION (this << i);
609  // If interface address and network mask have been set, add a route
610  // to the network of the interface (like e.g. ifconfig does on a
611  // Linux box)
612  for (uint32_t j = 0; j < m_ipv4->GetNAddresses (i); j++)
613  {
614  if (m_ipv4->GetAddress (i,j).GetLocal () != Ipv4Address () &&
615  m_ipv4->GetAddress (i,j).GetMask () != Ipv4Mask () &&
616  m_ipv4->GetAddress (i,j).GetMask () != Ipv4Mask::GetOnes ())
617  {
618  AddNetworkRouteTo (m_ipv4->GetAddress (i,j).GetLocal ().CombineMask (m_ipv4->GetAddress (i,j).GetMask ()),
619  m_ipv4->GetAddress (i,j).GetMask (), i);
620  }
621  }
622 }
623 
624 void
626 {
627  NS_LOG_FUNCTION (this << i);
628  // Remove all static routes that are going through this interface
629  uint32_t j = 0;
630  while (j < GetNRoutes ())
631  {
632  Ipv4RoutingTableEntry route = GetRoute (j);
633  if (route.GetInterface () == i)
634  {
635  RemoveRoute (j);
636  }
637  else
638  {
639  j++;
640  }
641  }
642 }
643 
644 void
646 {
647  NS_LOG_FUNCTION (this << interface << " " << address.GetLocal ());
648  if (!m_ipv4->IsUp (interface))
649  {
650  return;
651  }
652 
653  Ipv4Address networkAddress = address.GetLocal ().CombineMask (address.GetMask ());
654  Ipv4Mask networkMask = address.GetMask ();
655  if (address.GetLocal () != Ipv4Address () &&
656  address.GetMask () != Ipv4Mask ())
657  {
658  AddNetworkRouteTo (networkAddress,
659  networkMask, interface);
660  }
661 }
662 void
664 {
665  NS_LOG_FUNCTION (this << interface << " " << address.GetLocal ());
666  if (!m_ipv4->IsUp (interface))
667  {
668  return;
669  }
670  Ipv4Address networkAddress = address.GetLocal ().CombineMask (address.GetMask ());
671  Ipv4Mask networkMask = address.GetMask ();
672  // Remove all static routes that are going through this interface
673  // which reference this network
674  for (uint32_t j = 0; j < GetNRoutes (); j++)
675  {
676  Ipv4RoutingTableEntry route = GetRoute (j);
677  if (route.GetInterface () == interface &&
678  route.IsNetwork () &&
679  route.GetDestNetwork () == networkAddress &&
680  route.GetDestNetworkMask () == networkMask)
681  {
682  RemoveRoute (j);
683  }
684  }
685 }
686 
687 void
689 {
690  NS_LOG_FUNCTION (this << ipv4);
691  NS_ASSERT (m_ipv4 == 0 && ipv4 != 0);
692  m_ipv4 = ipv4;
693  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
694  {
695  if (m_ipv4->IsUp (i))
696  {
697  NotifyInterfaceUp (i);
698  }
699  else
700  {
702  }
703  }
704 }
705 // Formatted like output of "route -n" command
706 void
708 {
709  NS_LOG_FUNCTION (this << stream);
710  std::ostream* os = stream->GetStream ();
711  if (GetNRoutes () > 0)
712  {
713  *os << "Destination Gateway Genmask Flags Metric Ref Use Iface" << std::endl;
714  for (uint32_t j = 0; j < GetNRoutes (); j++)
715  {
716  std::ostringstream dest, gw, mask, flags;
717  Ipv4RoutingTableEntry route = GetRoute (j);
718  dest << route.GetDest ();
719  *os << std::setiosflags (std::ios::left) << std::setw (16) << dest.str ();
720  gw << route.GetGateway ();
721  *os << std::setiosflags (std::ios::left) << std::setw (16) << gw.str ();
722  mask << route.GetDestNetworkMask ();
723  *os << std::setiosflags (std::ios::left) << std::setw (16) << mask.str ();
724  flags << "U";
725  if (route.IsHost ())
726  {
727  flags << "HS";
728  }
729  else if (route.IsGateway ())
730  {
731  flags << "GS";
732  }
733  *os << std::setiosflags (std::ios::left) << std::setw (6) << flags.str ();
734  *os << std::setiosflags (std::ios::left) << std::setw (7) << GetMetric (j);
735  // Ref ct not implemented
736  *os << "-" << " ";
737  // Use not implemented
738  *os << "-" << " ";
739  if (Names::FindName (m_ipv4->GetNetDevice (route.GetInterface ())) != "")
740  {
741  *os << Names::FindName (m_ipv4->GetNetDevice (route.GetInterface ()));
742  }
743  else
744  {
745  *os << route.GetInterface ();
746  }
747  *os << std::endl;
748  }
749  }
750 }
752 Ipv4StaticRouting::SourceAddressSelection (uint32_t interfaceIdx, Ipv4Address dest)
753 {
754  NS_LOG_FUNCTION (this << interfaceIdx << " " << dest);
755  if (m_ipv4->GetNAddresses (interfaceIdx) == 1) // common case
756  {
757  return m_ipv4->GetAddress (interfaceIdx, 0).GetLocal ();
758  }
759  // no way to determine the scope of the destination, so adopt the
760  // following rule: pick the first available address (index 0) unless
761  // a subsequent address is on link (in which case, pick the primary
762  // address if there are multiple)
763  Ipv4Address candidate = m_ipv4->GetAddress (interfaceIdx, 0).GetLocal ();
764  for (uint32_t i = 0; i < m_ipv4->GetNAddresses (interfaceIdx); i++)
765  {
766  Ipv4InterfaceAddress test = m_ipv4->GetAddress (interfaceIdx, i);
767  if (test.GetLocal ().CombineMask (test.GetMask ()) == dest.CombineMask (test.GetMask ()))
768  {
769  if (test.IsSecondary () == false)
770  {
771  return test.GetLocal ();
772  }
773  }
774  }
775  return candidate;
776 }
777 
778 } // namespace ns3
static Ipv4Mask GetOnes(void)
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
Callback template class.
Definition: callback.h:369
void SetDefaultRoute(Ipv4Address nextHop, uint32_t interface, uint32_t metric=0)
Add a default route to the static routing table.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:210
void RemoveRoute(uint32_t i)
Remove a route from the static unicast routing table.
Ipv4Address GetOrigin(void) const
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:303
bool IsLocalMulticast(void) const
Ipv4RoutingTableEntry GetDefaultRoute(void)
Get the default route with lowest metric from the static routing table.
#define NS_ASSERT(condition)
Definition: assert.h:64
Ipv4Address GetDestNetwork(void) const
Ipv4MulticastRoutingTableEntry GetMulticastRoute(uint32_t i) const
Get a route from the static multicast routing table.
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
uint32_t GetInputInterface(void) const
bool IsMulticast(void) const
Ipv4Address CombineMask(Ipv4Mask const &mask) const
Combine this address with a network mask.
virtual void DoDispose(void)
Definition: object.cc:335
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:290
void AddHostRouteTo(Ipv4Address dest, Ipv4Address nextHop, uint32_t interface, uint32_t metric=0)
Add a host route to the static routing table.
static Ipv4MulticastRoutingTableEntry CreateMulticastRoute(Ipv4Address origin, Ipv4Address group, uint32_t inputInterface, std::vector< uint32_t > outputInterfaces)
void SetSource(Ipv4Address src)
Definition: ipv4-route.cc:49
uint32_t GetInterface(void) const
Packet header for IPv4.
Definition: ipv4-header.h:31
virtual void NotifyInterfaceDown(uint32_t interface)
bool RemoveMulticastRoute(Ipv4Address origin, Ipv4Address group, uint32_t inputInterface)
Remove a route from the static multicast routing table.
bool IsGateway(void) const
void SetGateway(Ipv4Address gw)
Definition: ipv4-route.cc:63
static Ipv4RoutingTableEntry CreateNetworkRouteTo(Ipv4Address network, Ipv4Mask networkMask, Ipv4Address nextHop, uint32_t interface)
static Ipv4Mask GetZero(void)
bool IsBroadcast(void) const
Ipv4RoutingTableEntry GetRoute(uint32_t i) const
Get a route from the static unicast routing table.
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)
bool IsNetwork(void) const
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
Ipv4Address GetGateway(void) const
Definition: ipv4-route.cc:70
uint32_t GetMetric(uint32_t index) const
Get a metric for route from the static unicast routing table.
uint32_t GetNRoutes(void) const
Get the number of individual unicast routes that have been added to the routing table.
bool IsEqual(const Ipv4Address &other) const
Comparison operation between two Ipv4Addresses.
Definition: ipv4-address.h:81
Ipv4Address GetDest(void) const
static Ipv4Address GetZero(void)
void SetOutputDevice(Ptr< NetDevice > outputDevice)
Definition: ipv4-route.cc:77
A record of an IPv4 multicast route for Ipv4GlobalRouting and Ipv4StaticRouting.
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream) const
Print the Routing Table entries.
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
void AddNetworkRouteTo(Ipv4Address network, Ipv4Mask networkMask, Ipv4Address nextHop, uint32_t interface, uint32_t metric=0)
Add a network route to the static routing table.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
virtual void DoDispose(void)
a class to store IPv4 address information on an interface
virtual void NotifyInterfaceUp(uint32_t interface)
Ipv4Address GetGroup(void) const
Ipv4Address GetGateway(void) const
virtual void SetIpv4(Ptr< Ipv4 > ipv4)
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)
static std::string FindName(Ptr< Object > object)
Definition: names.cc:664
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
bool IsHost(void) const
uint32_t GetNMulticastRoutes(void) const
Get the number of individual multicast routes that have been added to the routing table...
Ipv4Mask GetDestNetworkMask(void) const
std::ostream * GetStream(void)
uint16_t GetPrefixLength(void) const
void SetDestination(Ipv4Address dest)
Definition: ipv4-route.cc:35
void SetDefaultMulticastRoute(uint32_t outputInterface)
Add a default multicast route to the static routing table.
void AddMulticastRoute(Ipv4Address origin, Ipv4Address group, uint32_t inputInterface, std::vector< uint32_t > outputInterfaces)
Add a multicast route to the static routing table.
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.