12#include "ns3/address.h"
13#include "ns3/assert.h"
14#include "ns3/ipv6-l3-protocol.h"
16#include "ns3/loopback-net-device.h"
18#include "ns3/simulator.h"
61 NS_ASSERT_MSG(idLen == 6 || idLen == 8,
"Duid: Invalid identifier length.");
68 m_blob[1] = idLen == 6 ? 1 : 27;
82 NS_ASSERT_MSG(idLen == 6 || idLen == 8,
"Duid: Invalid identifier length.");
89 m_blob[1] = idLen == 6 ? 1 : 27;
112 "Duid: Invalid identifier length (max length is 65529 bytes).");
128 NS_ASSERT_MSG(uuid.size() == 16,
"Duid: Invalid identifier length (UUID must be 128 bits).");
130 m_blob.resize(uuid.size());
132 std::move(uuid.cbegin(), uuid.cend(),
m_blob.begin());
138 NS_LOG_FUNCTION(
this << std::to_underlying(duidType) << node << enIdentifierLength);
150 std::vector<uint8_t> identifier(enIdentifierLength);
151 HtoN(node->GetId(), identifier.begin());
160 std::vector<uint8_t> identifier(16);
161 HtoN(node->GetId(), identifier.begin());
175 uint32_t nInterfaces = ipv6->GetNInterfaces();
182 for (
uint32_t i = 0; i < nInterfaces; i++)
193 if (device->IsLinkUp())
195 NS_LOG_DEBUG(
"Interface " << device->GetIfIndex() <<
" up on node " << node->GetId());
196 Address address = device->GetAddress();
197 if (address.GetLength() > maxAddressLength)
199 maxAddressLength = address.GetLength();
200 duidAddress = address;
207 NS_LOG_DEBUG(
"DUID of node " << node->GetId() <<
" is " << duidAddress);
245 dest[0] = (source >> 24);
246 dest[1] = (source >> 16) & 0xFF;
247 dest[2] = (source >> 8) & 0xFF;
248 dest[3] = source & 0xFF;
254 uint8_t duidLen =
x.GetLength();
255 std::vector<uint8_t> buffer =
x.GetIdentifier();
257 std::string s(buffer.begin(), buffer.begin() + duidLen);
258 return std::hash<std::string>{}(s);
266 return std::is_eq(*this <=> other);
283 auto fold16 = [](std::vector<uint8_t>::const_iterator a) -> uint16_t {
284 auto f =
static_cast<uint16_t
>(a[0]) << 8;
285 f +=
static_cast<uint16_t
>(a[1]);
289 auto fold32 = [](std::vector<uint8_t>::const_iterator a) ->
uint32_t {
290 auto f =
static_cast<uint32_t>(a[0]) << 24;
291 f +=
static_cast<uint32_t>(a[1]) << 16;
292 f +=
static_cast<uint32_t>(a[2]) << 8;
297 auto format = [](std::vector<uint8_t>::const_iterator start,
298 std::vector<uint8_t>::const_iterator end) -> std::string {
299 std::ostringstream str;
301 std::for_each(start, end, [&](
int i) { str << std::setfill(
'0') << std::setw(2) << i; });
309 os <<
" HWtype: " << fold16(duid.
m_blob.cbegin());
310 os <<
" Time: " << fold32(duid.
m_blob.cbegin() + 2);
312 os <<
" Identifier: 0x" << format(identifierStart, duid.
m_blob.cend());
317 os <<
" EnNumber: 0x"
320 os <<
" Identifier: 0x" << format(identifierStart, duid.
m_blob.cend());
325 os <<
" HWtype: " << fold16(duid.
m_blob.cbegin());
327 os <<
" Identifier: 0x" << format(identifierStart, duid.
m_blob.cend());
332 auto identifierStart = duid.
m_blob.cbegin();
333 os <<
" UUID: 0x" << format(identifierStart, duid.
m_blob.cend());
cairo_uint64_t x
_cairo_uint_96by64_32x64_divrem:
a polymophic address class
uint8_t GetLength() const
Get the length of the underlying address.
uint32_t CopyTo(uint8_t buffer[MAX_SIZE]) const
Copy the address bytes into a buffer.
iterator in a Buffer instance
void Write(const uint8_t *buffer, uint32_t size)
void Read(uint8_t *buffer, uint32_t size)
void WriteHtonU16(uint16_t data)
size_t operator()(const Duid &x) const noexcept
Returns the hash of a DUID.
Implements the unique identifier for DHCPv6.
uint32_t Deserialize(Buffer::Iterator start, uint32_t len)
Deserialize the DUID.
uint8_t GetLength() const
Get the length of the DUID.
void InitializeLL(Ptr< Node > node)
Initialize the DUID-LL for a client or server.
Type m_duidType
DUID type.
bool operator==(const Duid &other) const
Comparison operator.
void Serialize(Buffer::Iterator start) const
Serialize the DUID.
void HtoN(uint32_t source, std::vector< uint8_t >::iterator dest)
Utility function to convert a 32-bit number to an array with its bytes in network order.
bool IsInvalid() const
Check if the DUID is invalid.
void InitializeEN(uint32_t enNumber, const std::vector< uint8_t > &identifier)
Initialize the DUID-EN for a client or server.
void InitializeUUID(const std::vector< uint8_t > &uuid)
Initialize the DUID-EN for a client or server.
void Initialize(Type duidType, Ptr< Node > node, uint32_t enIdentifierLength)
Initialize a DUID.
std::vector< uint8_t > GetIdentifier() const
Return the identifier of the node.
uint32_t GetSerializedSize() const
Get the DUID serialized size.
Type GetDuidType() const
Get the DUID type.
std::vector< uint8_t > m_blob
DUID data, content depending on the DUID type.
void InitializeLLT(Ptr< Node > node)
Initialize the DUID-LLT for a client or server.
Address FindSuitableNetDeviceAddress(Ptr< Node > node)
Find a suitable NetDevice address to create a DUID-LL or DUID-LLT.
IPv6 layer implementation.
Smart pointer class similar to boost::intrusive_ptr.
static Time Now()
Return the current simulation virtual time.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#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.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
std::strong_ordering operator<=>(const Duid &a, const Duid &b)