A Discrete-Event Network Simulator
API
ipv6-address-helper.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008-2009 Strasbourg University
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: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
18  */
19 
20 #include "ipv6-address-helper.h"
21 
22 #include "ns3/assert.h"
23 #include "ns3/ipv6-address-generator.h"
24 #include "ns3/ipv6.h"
25 #include "ns3/log.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/net-device-queue-interface.h"
31 #include "ns3/net-device.h"
32 #include "ns3/node.h"
33 #include "ns3/ptr.h"
34 #include "ns3/traffic-control-helper.h"
35 #include "ns3/traffic-control-layer.h"
36 
37 namespace ns3
38 {
39 
40 NS_LOG_COMPONENT_DEFINE("Ipv6AddressHelper");
41 
43 {
44  NS_LOG_FUNCTION(this);
45  m_network = Ipv6Address("2001:db8::");
46  m_prefix = 64;
47  m_address = Ipv6Address("::1");
48  m_base = m_address;
49 }
50 
52 {
53  NS_LOG_FUNCTION(this << network << prefix << base);
54 
55  m_network = network;
56  m_prefix = prefix;
57  m_address = base;
58  m_base = base;
59 
60  NS_ASSERT_MSG(m_network == network.CombinePrefix(prefix),
61  "Ipv6AddressHelper: network address and prefix mismatch: " << m_network << " "
62  << m_prefix);
63 
65  "Ipv6AddressHelper: base address and prefix mismatch: " << base << " "
66  << m_prefix);
67 }
68 
69 void
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: "
81  << m_network << " " << m_prefix);
82 
84  "Ipv6AddressHelper::SetBase(): base address and prefix mismatch: " << base << " "
85  << m_prefix);
86 }
87 
90 {
91  NS_LOG_FUNCTION(this << addr);
93  {
97  return address;
98  }
99  else if (Mac48Address::IsMatchingType(addr))
100  {
104  return address;
105  }
106  else if (Mac16Address::IsMatchingType(addr))
107  {
111  return address;
112  }
113  else if (Mac8Address::IsMatchingType(addr))
114  {
118  return address;
119  }
120  else
121  {
122  NS_FATAL_ERROR("Did not pass in a valid Mac Address (8, 16, 48 or 64 bits)");
123  }
124  /* never reached */
125  return Ipv6Address("::");
126 }
127 
130 {
131  NS_LOG_FUNCTION(this);
132  //
133  // The way this is expected to be used is that an address and network number
134  // are initialized, and then NewAddress() is called repeatedly to allocate and
135  // get new addresses on a given subnet. The client will expect that the first
136  // address she gets back is the one she used to initialize the generator with.
137  // This implies that this operation is a post-increment.
138 
139  uint8_t netBuf[16];
140  uint8_t hostBuf[16];
141  uint8_t addrBuf[16];
142  m_network.GetBytes(netBuf);
143  m_address.GetBytes(hostBuf);
144 
146  "Ipv6AddressHelper::NewAddress(): Too many hosts in the network: "
147  << m_address << " " << m_prefix);
148 
149  for (uint8_t i = 0; i < 16; i++)
150  {
151  addrBuf[i] = netBuf[i] | hostBuf[i];
152  }
153 
154  Ipv6Address addr = Ipv6Address(addrBuf);
155 
156  // Remember: hostBuf[15] is the Least Significant Byte.
157  uint16_t sum;
158  sum = static_cast<uint16_t>(hostBuf[15]) + 1;
159  hostBuf[15] += 1;
160  for (uint8_t index = 0; index < 15; index++)
161  {
162  if (sum > hostBuf[15 - index])
163  {
164  sum = static_cast<uint16_t>(hostBuf[14 - index]) + 1;
165  hostBuf[14 - index] += 1;
166  }
167  else
168  {
169  break;
170  }
171  }
172  m_address = Ipv6Address(hostBuf);
173 
175  return addr;
176 }
177 
178 void
180 {
181  NS_LOG_FUNCTION(this);
182 
183  uint8_t netBuf[16];
184  uint8_t addBuf[16];
185  m_network.GetBytes(netBuf);
186 
187  uint8_t prefixIndex = (m_prefix.GetPrefixLength() - 1) / 8;
188  uint8_t prefixPosition = (8 - (m_prefix.GetPrefixLength() % 8)) % 8;
189 
190  for (uint8_t index = 0; index < 16; index++)
191  {
192  addBuf[index] = 0;
193  if (index == prefixIndex)
194  {
195  addBuf[index] = (1 << prefixPosition);
196  }
197  }
198 
199  uint16_t sum[16];
200  for (uint8_t index = 0; index < 16; index++)
201  {
202  sum[index] = static_cast<uint16_t>(netBuf[index]) + static_cast<uint16_t>(addBuf[index]);
203  netBuf[index] += addBuf[index];
204  }
205 
206  for (uint8_t index = 0; index < 15; index++)
207  {
208  if (sum[15 - index] > netBuf[15 - index])
209  {
210  sum[14 - index] = static_cast<uint16_t>(netBuf[14 - index]) + 1;
211  netBuf[14 - index] += 1;
212  }
213  }
214 
215  m_network = Ipv6Address(netBuf);
216  m_address = m_base;
217 }
218 
221 {
222  NS_LOG_FUNCTION(this);
223  std::vector<bool> withConfiguration(c.GetN(), true);
224  return Assign(c, withConfiguration);
225 }
226 
228 Ipv6AddressHelper::Assign(const NetDeviceContainer& c, std::vector<bool> withConfiguration)
229 {
230  NS_LOG_FUNCTION(this);
231  std::vector<bool> onLink(c.GetN(), true);
232  return Assign(c, withConfiguration, onLink);
233 }
234 
237  std::vector<bool> withConfiguration,
238  std::vector<bool> onLink)
239 {
240  NS_LOG_FUNCTION(this);
241  Ipv6InterfaceContainer retval;
242  for (uint32_t i = 0; i < c.GetN(); ++i)
243  {
244  Ptr<NetDevice> device = c.Get(i);
245 
246  Ptr<Node> node = device->GetNode();
247  NS_ASSERT_MSG(node, "Ipv6AddressHelper::Allocate (): Bad node");
248 
249  Ptr<Ipv6> ipv6 = node->GetObject<Ipv6>();
250  NS_ASSERT_MSG(ipv6, "Ipv6AddressHelper::Allocate (): Bad ipv6");
251 
252  int32_t ifIndex = ipv6->GetInterfaceForDevice(device);
253  if (ifIndex == -1)
254  {
255  ifIndex = ipv6->AddInterface(device);
256  }
257  NS_ASSERT_MSG(ifIndex >= 0,
258  "Ipv6AddressHelper::Allocate (): "
259  "Interface index not found");
260 
261  // the first round is to make sure that the interface is set up, including its link-local
262  // addresses.
263  ipv6->SetUp(ifIndex);
264 
265  ipv6->SetMetric(ifIndex, 1);
266 
267  if (withConfiguration.at(i))
268  {
269  Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress(NewAddress(device->GetAddress()),
270  Ipv6Prefix(64),
271  onLink.at(i));
272  ipv6->AddAddress(ifIndex, ipv6Addr, onLink.at(i));
273  }
274 
275  ipv6->SetUp(ifIndex);
276  retval.Add(ipv6, ifIndex);
277 
278  // Install the default traffic control configuration if the traffic
279  // control layer has been aggregated, if this is not
280  // a loopback interface, and there is no queue disc installed already
282  if (tc && !DynamicCast<LoopbackNetDevice>(device) && !tc->GetRootQueueDiscOnDevice(device))
283  {
284  Ptr<NetDeviceQueueInterface> ndqi = device->GetObject<NetDeviceQueueInterface>();
285  // It is useless to install a queue disc if the device has no
286  // NetDeviceQueueInterface attached: the device queue is never
287  // stopped and every packet enqueued in the queue disc is
288  // immediately dequeued, hence there will never be backlog
289  if (ndqi)
290  {
291  std::size_t nTxQueues = ndqi->GetNTxQueues();
292  NS_LOG_LOGIC("Installing default traffic control configuration ("
293  << nTxQueues << " device queue(s))");
295  tcHelper.Install(device);
296  }
297  }
298  }
299  return retval;
300 }
301 
302 // Helper API that is redundant with Assign (c, false);
305 {
306  NS_LOG_FUNCTION(this);
307  std::vector<bool> withConfiguration(c.GetN(), false);
308  return Assign(c, withConfiguration);
309 }
310 
313 {
314  NS_LOG_FUNCTION(this);
315 
316  std::vector<bool> withConfiguration(c.GetN(), true);
317  std::vector<bool> onLink(c.GetN(), false);
318 
319  return Assign(c, withConfiguration, onLink);
320 }
321 
322 } /* namespace ns3 */
a polymophic address class
Definition: address.h:101
static bool AddAllocated(const Ipv6Address addr)
Add the Ipv6Address to the list of IPv6 entries.
Ipv6InterfaceContainer AssignWithoutAddress(const NetDeviceContainer &c)
Allocate an Ipv6InterfaceContainer but do not assign any IPv6 addresses.
void SetBase(Ipv6Address network, Ipv6Prefix prefix, Ipv6Address base=Ipv6Address("::1"))
Set the base network number, network prefix, and base interface ID.
Ipv6Address m_base
host base address
void NewNetwork()
Allocate a new network.
Ipv6Address m_network
network address
Ipv6Address m_address
host address
Ipv6InterfaceContainer AssignWithoutOnLink(const NetDeviceContainer &c)
Allocate an Ipv6InterfaceContainer with auto-assigned addresses, but do not set the on-link property ...
Ipv6Prefix m_prefix
prefix length
Ipv6InterfaceContainer Assign(const NetDeviceContainer &c)
Allocate an Ipv6InterfaceContainer with auto-assigned addresses.
Ipv6Address NewAddress()
Allocate a new Ipv6Address with interface ID equal to the next one in the underlying generator.
Describes an IPv6 address.
Definition: ipv6-address.h:49
static Ipv6Address GetZero()
Get the 0 (::) Ipv6Address.
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.
Ipv6Address CombinePrefix(const Ipv6Prefix &prefix) const
Combine this address with a prefix.
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition: ipv6.h:82
IPv6 address associated with an interface.
Keep track of a set of IPv6 interfaces.
void Add(Ptr< Ipv6 > ipv6, uint32_t interface)
Add a couple IPv6/interface.
Describes an IPv6 prefix.
Definition: ipv6-address.h:455
uint8_t GetPrefixLength() const
Get prefix length.
static bool IsMatchingType(const Address &address)
static Mac16Address ConvertFrom(const Address &address)
static bool IsMatchingType(const Address &address)
static Mac48Address ConvertFrom(const Address &address)
static bool IsMatchingType(const Address &address)
static Mac64Address ConvertFrom(const Address &address)
static Mac8Address ConvertFrom(const Address &address)
Convert a generic address to a Mac8Address.
Definition: mac8-address.cc:56
static bool IsMatchingType(const Address &address)
Check that a generic Address is compatible with Mac8Address.
Definition: mac8-address.cc:65
holds a vector of ns3::NetDevice pointers
uint32_t GetN() const
Get the number of Ptr<NetDevice> stored in this container.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
Network device transmission queue interface.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Build a set of QueueDisc objects.
QueueDiscContainer Install(NetDeviceContainer c)
static TrafficControlHelper Default(std::size_t nTxQueues=1)
The Traffic Control layer aims at introducing an equivalent of the Linux Traffic Control infrastructu...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
address
Definition: first.py:47
Every class exported by the ns3 library is enclosed in the ns3 namespace.