A Discrete-Event Network Simulator
API
ipv6-address-helper.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2008-2009 Strasbourg University
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: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
19  */
20 
21 #include "ns3/assert.h"
22 #include "ns3/log.h"
23 #include "ns3/ptr.h"
24 #include "ns3/node.h"
25 #include "ns3/net-device.h"
26 #include "ns3/loopback-net-device.h"
27 #include "ns3/mac16-address.h"
28 #include "ns3/mac48-address.h"
29 #include "ns3/mac64-address.h"
30 #include "ns3/ipv6.h"
31 #include "ns3/ipv6-address-generator.h"
32 #include "ns3/traffic-control-helper.h"
33 #include "ns3/traffic-control-layer.h"
34 #include "ns3/net-device-queue-interface.h"
35 
36 #include "ipv6-address-helper.h"
37 
38 namespace ns3
39 {
40 
41 NS_LOG_COMPONENT_DEFINE ("Ipv6AddressHelper");
42 
44 {
45  NS_LOG_FUNCTION (this);
46  m_network = Ipv6Address ("2001:db8::");
47  m_prefix = 64;
48  m_address = Ipv6Address ("::1");
49  m_base = m_address;
50 }
51 
53  Ipv6Address base)
54 {
55  NS_LOG_FUNCTION (this << network << prefix << base);
56 
57  m_network = network;
58  m_prefix = prefix;
59  m_address = base;
60  m_base = base;
61 
62  NS_ASSERT_MSG (m_network == network.CombinePrefix (prefix),
63  "Ipv6AddressHelper: network address and prefix mismatch: " << m_network << " " << m_prefix);
64 
66  "Ipv6AddressHelper: base address and prefix mismatch: " << base << " " << m_prefix);
67 }
68 
70  Ipv6Address base)
71 {
72  NS_LOG_FUNCTION (this << network << prefix << base);
73 
74  m_network = network;
75  m_prefix = prefix;
76  m_address = base;
77  m_base = base;
78 
79  NS_ASSERT_MSG (m_network == network.CombinePrefix (prefix),
80  "Ipv6AddressHelper::SetBase(): network address and prefix mismatch: " << m_network << " " << m_prefix);
81 
83  "Ipv6AddressHelper::SetBase(): base address and prefix mismatch: " << base << " " << m_prefix);
84 }
85 
86 
88 {
89  NS_LOG_FUNCTION (this << addr);
91  {
94  return address;
95  }
96  else if (Mac48Address::IsMatchingType (addr))
97  {
100  return address;
101  }
102  else if (Mac16Address::IsMatchingType (addr))
103  {
106  return address;
107  }
108  else if (Mac8Address::IsMatchingType (addr))
109  {
112  return address;
113  }
114  else
115  {
116  NS_FATAL_ERROR ("Did not pass in a valid Mac Address (8, 16, 48 or 64 bits)");
117  }
118  /* never reached */
119  return Ipv6Address ("::");
120 }
121 
123 {
124  NS_LOG_FUNCTION (this);
125 //
126 // The way this is expected to be used is that an address and network number
127 // are initialized, and then NewAddress() is called repeatedly to allocate and
128 // get new addresses on a given subnet. The client will expect that the first
129 // address she gets back is the one she used to initialize the generator with.
130 // This implies that this operation is a post-increment.
131 
132  uint8_t netBuf[16];
133  uint8_t hostBuf[16];
134  uint8_t addrBuf[16];
135  m_network.GetBytes (netBuf);
136  m_address.GetBytes (hostBuf);
137 
139  "Ipv6AddressHelper::NewAddress(): Too many hosts in the network: " << m_address << " " << m_prefix);
140 
141  for (uint8_t i=0; i<16; i++)
142  {
143  addrBuf[i] = netBuf[i] | hostBuf[i];
144  }
145 
146  Ipv6Address addr = Ipv6Address (addrBuf);
147 
148  // Remember: hostBuf[15] is the Least Significant Byte.
149  uint16_t sum;
150  sum = static_cast<uint16_t> (hostBuf[15]) + 1;
151  hostBuf[15] += 1;
152  for (uint8_t index=0; index<15; index++)
153  {
154  if (sum > hostBuf[15-index])
155  {
156  sum = static_cast<uint16_t> (hostBuf[14-index]) + 1;
157  hostBuf[14-index] += 1;
158  }
159  else
160  {
161  break;
162  }
163  }
164  m_address = Ipv6Address (hostBuf);
165 
167  return addr;
168 }
169 
171 {
172  NS_LOG_FUNCTION (this);
173 
174  uint8_t netBuf[16];
175  uint8_t addBuf[16];
176  m_network.GetBytes (netBuf);
177 
178  uint8_t prefixIndex = (m_prefix.GetPrefixLength ()-1)/8;
179  uint8_t prefixPosition = (8-(m_prefix.GetPrefixLength ()%8))%8;
180 
181  for (uint8_t index=0; index<16; index++)
182  {
183  addBuf[index] = 0;
184  if (index==prefixIndex)
185  {
186  addBuf[index] = (1<<prefixPosition);
187  }
188  }
189 
190  uint16_t sum[16];
191  for (uint8_t index=0; index<16; index++)
192  {
193  sum[index] = static_cast<uint16_t> (netBuf[index]) + static_cast<uint16_t> (addBuf[index]);
194  netBuf[index] += addBuf[index];
195  }
196 
197  for (uint8_t index=0; index<15; index++)
198  {
199  if (sum[15-index] > netBuf[15-index])
200  {
201  sum[14-index] = static_cast<uint16_t> (netBuf[14-index]) + 1;
202  netBuf[14-index] += 1;
203  }
204  }
205 
206  m_network = Ipv6Address (netBuf);
207  m_address = m_base;
208 }
209 
211 {
212  NS_LOG_FUNCTION (this);
213  Ipv6InterfaceContainer retval;
214 
215  for (uint32_t i = 0; i < c.GetN (); ++i)
216  {
217  Ptr<NetDevice> device = c.Get (i);
218 
219  Ptr<Node> node = device->GetNode ();
220  NS_ASSERT_MSG (node, "Ipv6AddressHelper::Allocate (): Bad node");
221 
222  Ptr<Ipv6> ipv6 = node->GetObject<Ipv6> ();
223  NS_ASSERT_MSG (ipv6, "Ipv6AddressHelper::Allocate (): Bad ipv6");
224  int32_t ifIndex = 0;
225 
226  ifIndex = ipv6->GetInterfaceForDevice (device);
227  if (ifIndex == -1)
228  {
229  ifIndex = ipv6->AddInterface (device);
230  }
231  NS_ASSERT_MSG (ifIndex >= 0, "Ipv6AddressHelper::Allocate (): "
232  "Interface index not found");
233 
234  // the first round is to make sure that the interface is set up, including its link-local addresses.
235  ipv6->SetUp (ifIndex);
236 
237  Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (NewAddress (device->GetAddress ()), Ipv6Prefix (64));
238  ipv6->SetMetric (ifIndex, 1);
239  ipv6->AddAddress (ifIndex, ipv6Addr);
240  ipv6->SetUp (ifIndex);
241 
242  retval.Add (ipv6, ifIndex);
243 
244  // Install the default traffic control configuration if the traffic
245  // control layer has been aggregated, if this is not
246  // a loopback interface, and there is no queue disc installed already
248  if (tc && DynamicCast<LoopbackNetDevice> (device) == 0 && tc->GetRootQueueDiscOnDevice (device) == 0)
249  {
250  Ptr<NetDeviceQueueInterface> ndqi = device->GetObject<NetDeviceQueueInterface> ();
251  // It is useless to install a queue disc if the device has no
252  // NetDeviceQueueInterface attached: the device queue is never
253  // stopped and every packet enqueued in the queue disc is
254  // immediately dequeued, hence there will never be backlog
255  if (ndqi)
256  {
257  std::size_t nTxQueues = ndqi->GetNTxQueues ();
258  NS_LOG_LOGIC ("Installing default traffic control configuration ("
259  << nTxQueues << " device queue(s))");
261  tcHelper.Install (device);
262  }
263  }
264  }
265  return retval;
266 }
267 
268 Ipv6InterfaceContainer Ipv6AddressHelper::Assign (const NetDeviceContainer &c, std::vector<bool> withConfiguration)
269 {
270  NS_LOG_FUNCTION (this);
271  Ipv6InterfaceContainer retval;
272  for (uint32_t i = 0; i < c.GetN (); ++i)
273  {
274  Ptr<NetDevice> device = c.Get (i);
275 
276  Ptr<Node> node = device->GetNode ();
277  NS_ASSERT_MSG (node, "Ipv6AddressHelper::Allocate (): Bad node");
278 
279  Ptr<Ipv6> ipv6 = node->GetObject<Ipv6> ();
280  NS_ASSERT_MSG (ipv6, "Ipv6AddressHelper::Allocate (): Bad ipv6");
281 
282  int32_t ifIndex = ipv6->GetInterfaceForDevice (device);
283  if (ifIndex == -1)
284  {
285  ifIndex = ipv6->AddInterface (device);
286  }
287  NS_ASSERT_MSG (ifIndex >= 0, "Ipv6AddressHelper::Allocate (): "
288  "Interface index not found");
289 
290  // the first round is to make sure that the interface is set up, including its link-local addresses.
291  ipv6->SetUp (ifIndex);
292 
293  ipv6->SetMetric (ifIndex, 1);
294 
295  if (withConfiguration.at (i))
296  {
297  Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (NewAddress (device->GetAddress ()), Ipv6Prefix (64));
298  ipv6->AddAddress (ifIndex, ipv6Addr);
299  }
300 
301  ipv6->SetUp (ifIndex);
302  retval.Add (ipv6, ifIndex);
303 
304  // Install the default traffic control configuration if the traffic
305  // control layer has been aggregated, if this is not
306  // a loopback interface, and there is no queue disc installed already
308  if (tc && DynamicCast<LoopbackNetDevice> (device) == 0 && tc->GetRootQueueDiscOnDevice (device) == 0)
309  {
310  Ptr<NetDeviceQueueInterface> ndqi = device->GetObject<NetDeviceQueueInterface> ();
311  // It is useless to install a queue disc if the device has no
312  // NetDeviceQueueInterface attached: the device queue is never
313  // stopped and every packet enqueued in the queue disc is
314  // immediately dequeued, hence there will never be backlog
315  if (ndqi)
316  {
317  std::size_t nTxQueues = ndqi->GetNTxQueues ();
318  NS_LOG_LOGIC ("Installing default traffic control configuration ("
319  << nTxQueues << " device queue(s))");
321  tcHelper.Install (device);
322  }
323  }
324  }
325  return retval;
326 }
327 
328 // Helper API that is redundant with Assign (c, false);
330 {
331  NS_LOG_FUNCTION (this);
332  std::vector<bool> withConfiguration;
333  for (uint32_t i = 0; i < c.GetN (); ++i)
334  {
335  withConfiguration.push_back (false);
336  }
337  return Assign (c, withConfiguration);
338 }
339 
340 } /* namespace ns3 */
341 
static bool IsMatchingType(const Address &address)
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
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 "...
QueueDiscContainer Install(NetDeviceContainer c)
Keep track of a set of IPv6 interfaces.
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition: ipv6.h:81
Introspection did not find any typical Config paths.
static Mac16Address ConvertFrom(const Address &address)
static bool IsMatchingType(const Address &address)
void Add(Ptr< Ipv6 > ipv6, uint32_t interface)
Add a couple IPv6/interface.
static Ipv6Address MakeAutoconfiguredAddress(Address addr, Ipv6Address prefix)
Make the autoconfigured IPv6 address from a Mac address.
void GetBytes(uint8_t buf[16]) const
Get the bytes corresponding to the address.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
IPv6 address associated with an interface.
void SetBase(Ipv6Address network, Ipv6Prefix prefix, Ipv6Address base=Ipv6Address("::1"))
Set the base network number, network prefix, and base interface ID.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
static bool IsMatchingType(const Address &address)
Check that a generic Address is compatible with Mac8Address.
Definition: mac8-address.cc:63
Ipv6Address m_address
host address
a polymophic address class
Definition: address.h:90
Ipv6InterfaceContainer Assign(const NetDeviceContainer &c)
Allocate an Ipv6InterfaceContainer with auto-assigned addresses.
static Ipv6Address GetZero()
Get the 0 (::) Ipv6Address.
Ipv6Prefix m_prefix
prefix length
holds a vector of ns3::NetDevice pointers
Build a set of QueueDisc objects.
Ipv6Address CombinePrefix(Ipv6Prefix const &prefix) const
Combine this address with a prefix.
Network device transmission queue interface.
static Mac48Address ConvertFrom(const Address &address)
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:461
Every class exported by the ns3 library is enclosed in the ns3 namespace.
address
Definition: first.py:44
static TrafficControlHelper Default(std::size_t nTxQueues=1)
uint8_t GetPrefixLength() const
Get prefix length.
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
Describes an IPv6 address.
Definition: ipv6-address.h:49
static Mac64Address ConvertFrom(const Address &address)
static bool AddAllocated(const Ipv6Address addr)
Add the Ipv6Address to the list of IPv6 entries.
uint32_t GetN(void) const
Get the number of Ptr<NetDevice> stored in this container.
Ipv6Address m_network
network address
Describes an IPv6 prefix.
Definition: ipv6-address.h:459
static bool IsMatchingType(const Address &address)
Ipv6InterfaceContainer AssignWithoutAddress(const NetDeviceContainer &c)
Allocate an Ipv6InterfaceContainer but do not assign any IPv6 addresses.
static Mac8Address ConvertFrom(const Address &address)
Convert a generic address to a Mac8Address.
Definition: mac8-address.cc:54
Ipv6AddressHelper()
Constructor.
void NewNetwork(void)
Allocate a new network.
Ipv6Address m_base
host base address
Ipv6Address NewAddress(void)
Allocate a new Ipv6Address with interface ID equal to the next one in the underlying generator...