1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2008-2009 Strasbourg University
4  *               2013 Universita' di Firenze
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  * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
20  *         Tommaso Pecorella <tommaso.pecorella@unifi.it>
21  */
22 
23 #include "ns3/node-list.h"
24 #include "ns3/names.h"
25 
26 #include "ipv6-interface-container.h"
27 #include "ns3/ipv6-static-routing-helper.h"
28 
29 namespace ns3 {
30 
Ipv6InterfaceContainer()31 Ipv6InterfaceContainer::Ipv6InterfaceContainer ()
32 {
33 }
34 
35 Ipv6InterfaceContainer::Iterator
Begin(void) const36 Ipv6InterfaceContainer::Begin (void) const
37 {
38   return m_interfaces.begin ();
39 }
40 
41 Ipv6InterfaceContainer::Iterator
End(void) const42 Ipv6InterfaceContainer::End (void) const
43 {
44   return m_interfaces.end ();
45 }
46 
GetN() const47 uint32_t Ipv6InterfaceContainer::GetN () const
48 {
49   return m_interfaces.size ();
50 }
51 
GetInterfaceIndex(uint32_t i) const52 uint32_t Ipv6InterfaceContainer::GetInterfaceIndex (uint32_t i) const
53 {
54   return m_interfaces[i].second;
55 }
56 
GetAddress(uint32_t i,uint32_t j) const57 Ipv6Address Ipv6InterfaceContainer::GetAddress (uint32_t i, uint32_t j) const
58 {
59   Ptr<Ipv6> ipv6 = m_interfaces[i].first;
60   uint32_t interface = m_interfaces[i].second;
61   return ipv6->GetAddress (interface, j).GetAddress ();
62 }
63 
Add(Ptr<Ipv6> ipv6,uint32_t interface)64 void Ipv6InterfaceContainer::Add (Ptr<Ipv6> ipv6, uint32_t interface)
65 {
66   m_interfaces.push_back (std::make_pair (ipv6, interface));
67 }
68 
Add(std::string ipv6Name,uint32_t interface)69 void Ipv6InterfaceContainer::Add (std::string ipv6Name, uint32_t interface)
70 {
71   Ptr<Ipv6> ipv6 = Names::Find<Ipv6> (ipv6Name);
72   m_interfaces.push_back (std::make_pair (ipv6, interface));
73 }
74 
Add(const Ipv6InterfaceContainer & c)75 void Ipv6InterfaceContainer::Add (const Ipv6InterfaceContainer& c)
76 {
77   for (InterfaceVector::const_iterator it = c.m_interfaces.begin (); it != c.m_interfaces.end (); it++)
78     {
79       m_interfaces.push_back (*it);
80     }
81 }
82 
SetForwarding(uint32_t i,bool router)83 void Ipv6InterfaceContainer::SetForwarding (uint32_t i, bool router)
84 {
85   Ptr<Ipv6> ipv6 = m_interfaces[i].first;
86   ipv6->SetForwarding (m_interfaces[i].second, router);
87 }
88 
SetDefaultRouteInAllNodes(uint32_t router)89 void Ipv6InterfaceContainer::SetDefaultRouteInAllNodes (uint32_t router)
90 {
91   Ptr<Ipv6> ipv6 = m_interfaces[router].first;
92   uint32_t other;
93 
94   Ipv6Address routerAddress = GetLinkLocalAddress (router);
95   NS_ASSERT_MSG (routerAddress != Ipv6Address::GetAny (), "No link-local address found on router, aborting");
96 
97   for (other = 0; other < m_interfaces.size (); other++)
98     {
99       if (other != router)
100         {
101           Ptr<Ipv6StaticRouting> routing = 0;
102           Ipv6StaticRoutingHelper routingHelper;
103 
104           ipv6 = m_interfaces[other].first;
105           routing = routingHelper.GetStaticRouting (ipv6);
106           NS_ASSERT_MSG (routing != 0, "Default router setup failed because no Ipv6StaticRouting was found on the node.");
107           routing->SetDefaultRoute (routerAddress, m_interfaces[other].second);
108         }
109     }
110 }
111 
SetDefaultRouteInAllNodes(Ipv6Address routerAddress)112 void Ipv6InterfaceContainer::SetDefaultRouteInAllNodes (Ipv6Address routerAddress)
113 {
114   uint32_t routerIndex = 0;
115   bool found = false;
116   for (uint32_t index = 0; index < m_interfaces.size (); index++)
117     {
118       Ptr<Ipv6> ipv6 = m_interfaces[index].first;
119       for (uint32_t i = 0; i < ipv6->GetNAddresses (m_interfaces[index].second); i++)
120         {
121           Ipv6Address addr = ipv6->GetAddress (m_interfaces[index].second, i).GetAddress ();
122           if (addr == routerAddress)
123             {
124               routerIndex = index;
125               found = true;
126               break;
127             }
128         }
129       if (found)
130         {
131           break;
132         }
133     }
134   NS_ASSERT_MSG (found != true, "No such address in the interfaces. Aborting.");
135 
136   for (uint32_t other = 0; other < m_interfaces.size (); other++)
137     {
138       if (other != routerIndex)
139         {
140           Ptr<Ipv6StaticRouting> routing = 0;
141           Ipv6StaticRoutingHelper routingHelper;
142 
143           Ptr<Ipv6> ipv6 = m_interfaces[other].first;
144           routing = routingHelper.GetStaticRouting (ipv6);
145           NS_ASSERT_MSG (routing != 0, "Default router setup failed because no Ipv6StaticRouting was found on the node.");
146           routing->SetDefaultRoute (routerAddress, m_interfaces[other].second);
147         }
148     }
149 }
150 
151 
SetDefaultRoute(uint32_t i,uint32_t router)152 void Ipv6InterfaceContainer::SetDefaultRoute (uint32_t i, uint32_t router)
153 {
154   NS_ASSERT_MSG (i != router, "A node shouldn't set itself as the default router, isn't it? Aborting.");
155 
156   Ptr<Ipv6> ipv6 = m_interfaces[i].first;
157 
158   Ipv6Address routerAddress = GetLinkLocalAddress (router);
159   NS_ASSERT_MSG (routerAddress != Ipv6Address::GetAny (), "No link-local address found on router, aborting");
160 
161   Ptr<Ipv6StaticRouting> routing = 0;
162   Ipv6StaticRoutingHelper routingHelper;
163 
164   routing = routingHelper.GetStaticRouting (ipv6);
165   NS_ASSERT_MSG (routing != 0, "Default router setup failed because no Ipv6StaticRouting was found on the node.");
166   routing->SetDefaultRoute (routerAddress, m_interfaces[i].second);
167 }
168 
169 
SetDefaultRoute(uint32_t i,Ipv6Address routerAddr)170 void Ipv6InterfaceContainer::SetDefaultRoute (uint32_t i, Ipv6Address routerAddr)
171 {
172   uint32_t routerIndex = 0;
173   bool found = false;
174   for (uint32_t index = 0; index < m_interfaces.size (); index++)
175     {
176       Ptr<Ipv6> ipv6 = m_interfaces[index].first;
177       for (uint32_t i = 0; i < ipv6->GetNAddresses (m_interfaces[index].second); i++)
178         {
179           Ipv6Address addr = ipv6->GetAddress (m_interfaces[index].second, i).GetAddress ();
180           if (addr == routerAddr)
181             {
182               routerIndex = index;
183               found = true;
184               break;
185             }
186         }
187       if (found)
188         {
189           break;
190         }
191     }
192   NS_ASSERT_MSG (found != true, "No such address in the interfaces. Aborting.");
193 
194   NS_ASSERT_MSG (i != routerIndex, "A node shouldn't set itself as the default router, isn't it? Aborting.");
195 
196   Ptr<Ipv6> ipv6 = m_interfaces[i].first;
197   Ipv6Address routerLinkLocalAddress = GetLinkLocalAddress (routerIndex);
198   Ptr<Ipv6StaticRouting> routing = 0;
199   Ipv6StaticRoutingHelper routingHelper;
200 
201   routing = routingHelper.GetStaticRouting (ipv6);
202   NS_ASSERT_MSG (routing != 0, "Default router setup failed because no Ipv6StaticRouting was found on the node.");
203   routing->SetDefaultRoute (routerLinkLocalAddress, m_interfaces[i].second);
204 }
205 
206 
GetLinkLocalAddress(uint32_t index)207 Ipv6Address Ipv6InterfaceContainer::GetLinkLocalAddress (uint32_t index)
208 {
209   Ptr<Ipv6> ipv6 = m_interfaces[index].first;
210   for (uint32_t i = 0; i < ipv6->GetNAddresses (m_interfaces[index].second); i++)
211     {
212       Ipv6InterfaceAddress iAddress;
213       iAddress = ipv6->GetAddress (m_interfaces[index].second, i);
214       if (iAddress.GetScope () == Ipv6InterfaceAddress::LINKLOCAL)
215         {
216           return iAddress.GetAddress ();
217         }
218     }
219   return Ipv6Address::GetAny ();
220 }
221 
GetLinkLocalAddress(Ipv6Address address)222 Ipv6Address Ipv6InterfaceContainer::GetLinkLocalAddress (Ipv6Address address)
223 {
224   if (address.IsLinkLocal ())
225     {
226       return address;
227     }
228 
229   uint32_t nodeIndex = 0;
230   bool found = false;
231   for (uint32_t index = 0; index < m_interfaces.size (); index++)
232     {
233       Ptr<Ipv6> ipv6 = m_interfaces[index].first;
234       for (uint32_t i = 0; i < ipv6->GetNAddresses (m_interfaces[index].second); i++)
235         {
236           Ipv6Address addr = ipv6->GetAddress (m_interfaces[index].second, i).GetAddress ();
237           if (addr == address)
238             {
239               nodeIndex = index;
240               found = true;
241               break;
242             }
243         }
244       if (found)
245         {
246           break;
247         }
248     }
249   NS_ASSERT_MSG (found != true, "No such address in the interfaces. Aborting.");
250 
251   Ptr<Ipv6> ipv6 = m_interfaces[nodeIndex].first;
252   for (uint32_t i = 0; i < ipv6->GetNAddresses (m_interfaces[nodeIndex].second); i++)
253     {
254       Ipv6InterfaceAddress iAddress;
255       iAddress = ipv6->GetAddress (m_interfaces[nodeIndex].second, i);
256       if (iAddress.GetScope () == Ipv6InterfaceAddress::LINKLOCAL)
257         {
258           return iAddress.GetAddress ();
259         }
260     }
261   return Ipv6Address::GetAny ();
262 }
263 
264 
265 } /* namespace ns3 */
266 
267