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