A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ipv6-address-helper.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008-2009 Strasbourg University
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
7 */
8
10
11#include "ns3/assert.h"
12#include "ns3/ipv6-address-generator.h"
13#include "ns3/ipv6.h"
14#include "ns3/log.h"
15#include "ns3/loopback-net-device.h"
16#include "ns3/mac16-address.h"
17#include "ns3/mac48-address.h"
18#include "ns3/mac64-address.h"
19#include "ns3/net-device-queue-interface.h"
20#include "ns3/net-device.h"
21#include "ns3/node.h"
22#include "ns3/ptr.h"
23#include "ns3/traffic-control-helper.h"
24#include "ns3/traffic-control-layer.h"
25
26namespace ns3
27{
28
29NS_LOG_COMPONENT_DEFINE("Ipv6AddressHelper");
30
39
41{
42 NS_LOG_FUNCTION(this << network << prefix << base);
43
44 m_network = network;
45 m_prefix = prefix;
46 m_address = base;
47 m_base = base;
48
49 NS_ASSERT_MSG(m_network == network.CombinePrefix(prefix),
50 "Ipv6AddressHelper: network address and prefix mismatch: " << m_network << " "
51 << m_prefix);
52
54 "Ipv6AddressHelper: base address and prefix mismatch: " << base << " "
55 << m_prefix);
56}
57
58void
60{
61 NS_LOG_FUNCTION(this << network << prefix << base);
62
63 m_network = network;
64 m_prefix = prefix;
65 m_address = base;
66 m_base = base;
67
68 NS_ASSERT_MSG(m_network == network.CombinePrefix(prefix),
69 "Ipv6AddressHelper::SetBase(): network address and prefix mismatch: "
70 << m_network << " " << m_prefix);
71
73 "Ipv6AddressHelper::SetBase(): base address and prefix mismatch: " << base << " "
74 << m_prefix);
75}
76
79{
80 NS_LOG_FUNCTION(this << addr);
82 {
83 Ipv6Address address =
86 return address;
87 }
88 else if (Mac48Address::IsMatchingType(addr))
89 {
90 Ipv6Address address =
93 return address;
94 }
95 else if (Mac16Address::IsMatchingType(addr))
96 {
97 Ipv6Address address =
100 return address;
101 }
102 else if (Mac8Address::IsMatchingType(addr))
103 {
104 Ipv6Address address =
107 return address;
108 }
109 else
110 {
111 NS_FATAL_ERROR("Did not pass in a valid Mac Address (8, 16, 48 or 64 bits)");
112 }
113 /* never reached */
114 return Ipv6Address("::");
115}
116
119{
120 NS_LOG_FUNCTION(this);
121 //
122 // The way this is expected to be used is that an address and network number
123 // are initialized, and then NewAddress() is called repeatedly to allocate and
124 // get new addresses on a given subnet. The client will expect that the first
125 // address she gets back is the one she used to initialize the generator with.
126 // This implies that this operation is a post-increment.
127
128 uint8_t netBuf[16];
129 uint8_t hostBuf[16];
130 uint8_t addrBuf[16];
131 m_network.GetBytes(netBuf);
132 m_address.GetBytes(hostBuf);
133
135 "Ipv6AddressHelper::NewAddress(): Too many hosts in the network: "
136 << m_address << " " << m_prefix);
137
138 for (uint8_t i = 0; i < 16; i++)
139 {
140 addrBuf[i] = netBuf[i] | hostBuf[i];
141 }
142
143 Ipv6Address addr = Ipv6Address(addrBuf);
144
145 // Remember: hostBuf[15] is the Least Significant Byte.
146 uint16_t sum;
147 sum = static_cast<uint16_t>(hostBuf[15]) + 1;
148 hostBuf[15] += 1;
149 for (uint8_t index = 0; index < 15; index++)
150 {
151 if (sum > hostBuf[15 - index])
152 {
153 sum = static_cast<uint16_t>(hostBuf[14 - index]) + 1;
154 hostBuf[14 - index] += 1;
155 }
156 else
157 {
158 break;
159 }
160 }
161 m_address = Ipv6Address(hostBuf);
162
164 return addr;
165}
166
167void
169{
170 NS_LOG_FUNCTION(this);
171
172 uint8_t netBuf[16];
173 uint8_t addBuf[16];
174 m_network.GetBytes(netBuf);
175
176 uint8_t prefixIndex = (m_prefix.GetPrefixLength() - 1) / 8;
177 uint8_t prefixPosition = (8 - (m_prefix.GetPrefixLength() % 8)) % 8;
178
179 for (uint8_t index = 0; index < 16; index++)
180 {
181 addBuf[index] = 0;
182 if (index == prefixIndex)
183 {
184 addBuf[index] = (1 << prefixPosition);
185 }
186 }
187
188 uint16_t sum[16];
189 for (uint8_t index = 0; index < 16; index++)
190 {
191 sum[index] = static_cast<uint16_t>(netBuf[index]) + static_cast<uint16_t>(addBuf[index]);
192 netBuf[index] += addBuf[index];
193 }
194
195 for (uint8_t index = 0; index < 15; index++)
196 {
197 if (sum[15 - index] > netBuf[15 - index])
198 {
199 sum[14 - index] = static_cast<uint16_t>(netBuf[14 - index]) + 1;
200 netBuf[14 - index] += 1;
201 }
202 }
203
204 m_network = Ipv6Address(netBuf);
206}
207
210{
211 NS_LOG_FUNCTION(this);
212 std::vector<bool> withConfiguration(c.GetN(), true);
213 return Assign(c, withConfiguration);
214}
215
217Ipv6AddressHelper::Assign(const NetDeviceContainer& c, std::vector<bool> withConfiguration)
218{
219 NS_LOG_FUNCTION(this);
220 std::vector<bool> onLink(c.GetN(), true);
221 return Assign(c, withConfiguration, onLink);
222}
223
226 std::vector<bool> withConfiguration,
227 std::vector<bool> onLink)
228{
229 NS_LOG_FUNCTION(this);
231 for (uint32_t i = 0; i < c.GetN(); ++i)
232 {
233 Ptr<NetDevice> device = c.Get(i);
234
235 Ptr<Node> node = device->GetNode();
236 NS_ASSERT_MSG(node, "Ipv6AddressHelper::Allocate (): Bad node");
237
238 Ptr<Ipv6> ipv6 = node->GetObject<Ipv6>();
239 NS_ASSERT_MSG(ipv6, "Ipv6AddressHelper::Allocate (): Bad ipv6");
240
241 int32_t ifIndex = ipv6->GetInterfaceForDevice(device);
242 if (ifIndex == -1)
243 {
244 ifIndex = ipv6->AddInterface(device);
245 }
246 NS_ASSERT_MSG(ifIndex >= 0,
247 "Ipv6AddressHelper::Allocate (): "
248 "Interface index not found");
249
250 // the first round is to make sure that the interface is set up, including its link-local
251 // addresses.
252 ipv6->SetUp(ifIndex);
253
254 ipv6->SetMetric(ifIndex, 1);
255
256 if (withConfiguration.at(i))
257 {
258 Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress(NewAddress(device->GetAddress()),
259 Ipv6Prefix(64),
260 onLink.at(i));
261 ipv6->AddAddress(ifIndex, ipv6Addr, onLink.at(i));
262 }
263
264 ipv6->SetUp(ifIndex);
265 retval.Add(ipv6, ifIndex);
266
267 // Install the default traffic control configuration if the traffic
268 // control layer has been aggregated, if this is not
269 // a loopback interface, and there is no queue disc installed already
270 Ptr<TrafficControlLayer> tc = node->GetObject<TrafficControlLayer>();
271 if (tc && !DynamicCast<LoopbackNetDevice>(device) && !tc->GetRootQueueDiscOnDevice(device))
272 {
273 Ptr<NetDeviceQueueInterface> ndqi = device->GetObject<NetDeviceQueueInterface>();
274 // It is useless to install a queue disc if the device has no
275 // NetDeviceQueueInterface attached: the device queue is never
276 // stopped and every packet enqueued in the queue disc is
277 // immediately dequeued, hence there will never be backlog
278 if (ndqi)
279 {
280 std::size_t nTxQueues = ndqi->GetNTxQueues();
281 NS_LOG_LOGIC("Installing default traffic control configuration ("
282 << nTxQueues << " device queue(s))");
284 tcHelper.Install(device);
285 }
286 }
287 }
288 return retval;
289}
290
291// Helper API that is redundant with Assign (c, false);
294{
295 NS_LOG_FUNCTION(this);
296 std::vector<bool> withConfiguration(c.GetN(), false);
297 return Assign(c, withConfiguration);
298}
299
302{
303 NS_LOG_FUNCTION(this);
304
305 std::vector<bool> withConfiguration(c.GetN(), true);
306 std::vector<bool> onLink(c.GetN(), false);
307
308 return Assign(c, withConfiguration, onLink);
309}
310
311} /* namespace ns3 */
a polymophic address class
Definition address.h:90
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.
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:71
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.
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.
static bool IsMatchingType(const Address &address)
Check that a generic Address is compatible with Mac8Address.
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.
Smart pointer class similar to boost::intrusive_ptr.
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:75
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580