A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
address.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 * Modified by: Dhiraj Lokesh <dhirajlokesh@gmail.com>
8 */
9
10#include "address.h"
11
12#include "ns3/assert.h"
13#include "ns3/log.h"
14
15#include <cstring>
16#include <iomanip>
17#include <iostream>
18
19namespace ns3
20{
21
23
25
26Address::Address(uint8_t type, const uint8_t* buffer, uint8_t len)
27 : m_type(type),
28 m_len(len)
29{
30 NS_LOG_FUNCTION(this << static_cast<uint32_t>(type) << &buffer << static_cast<uint32_t>(len));
31 NS_ASSERT_MSG(m_len <= MAX_SIZE, "Address length too large");
32 NS_ASSERT_MSG(type != UNASSIGNED_TYPE, "Type 0 is reserved for uninitialized addresses.");
33 std::copy(buffer, buffer + len, m_data.begin());
34}
35
36void
37Address::SetType(const std::string& kind, uint8_t length)
38{
39 NS_LOG_FUNCTION(this << kind << static_cast<uint32_t>(length));
40 auto search = m_typeRegistry.find({kind, length});
41 NS_ASSERT_MSG(search != m_typeRegistry.end(),
42 "No address with the given kind and length is registered.");
43
44 if (m_type != search->second)
45 {
47 "You can only change the type of a type-0 address."
48 << static_cast<uint32_t>(m_type));
49
50 m_type = search->second;
51 }
52}
53
54bool
56{
57 NS_LOG_FUNCTION(this);
58 return m_len == 0 && m_type == UNASSIGNED_TYPE;
59}
60
61uint8_t
63{
64 NS_LOG_FUNCTION(this);
66 return m_len;
67}
68
70Address::CopyTo(uint8_t buffer[MAX_SIZE]) const
71{
72 NS_LOG_FUNCTION(this << &buffer);
74 std::copy(m_data.begin(), m_data.begin() + m_len, buffer);
75 return m_len;
76}
77
79Address::CopyAllTo(uint8_t* buffer, uint8_t len) const
80{
81 NS_LOG_FUNCTION(this << &buffer << static_cast<uint32_t>(len));
82 NS_ASSERT(len - m_len > 1);
83 buffer[0] = m_type;
84 buffer[1] = m_len;
85 std::copy(m_data.begin(), m_data.begin() + m_len, buffer + 2);
86 return m_len + 2;
87}
88
90Address::CopyFrom(const uint8_t* buffer, uint8_t len)
91{
92 NS_LOG_FUNCTION(this << &buffer << static_cast<uint32_t>(len));
93 NS_ASSERT_MSG(m_len <= MAX_SIZE, "Address length too large");
95 "Type-0 addresses are reserved. Please use SetType before using CopyFrom.");
96 std::copy(buffer, buffer + len, m_data.begin());
97 m_len = len;
98 return m_len;
99}
100
102Address::CopyAllFrom(const uint8_t* buffer, uint8_t len)
103{
104 NS_LOG_FUNCTION(this << &buffer << static_cast<uint32_t>(len));
105 NS_ASSERT(len >= 2);
106 m_type = buffer[0];
107 m_len = buffer[1];
108
109 NS_ASSERT(len - m_len > 1);
110 std::copy(buffer + 2, buffer + 2 + m_len, m_data.begin());
111 return m_len + 2;
112}
113
114bool
115Address::CheckCompatible(uint8_t type, uint8_t len) const
116{
117 NS_LOG_FUNCTION(this << static_cast<uint32_t>(type) << static_cast<uint32_t>(len));
118 NS_ASSERT(len <= MAX_SIZE);
119 return (m_len == len && m_type == type);
120}
121
122bool
123Address::IsMatchingType(uint8_t type) const
124{
125 NS_LOG_FUNCTION(this << static_cast<uint32_t>(type));
126 return m_type == type;
127}
128
129uint8_t
130Address::Register(const std::string& kind, uint8_t length)
131{
132 NS_LOG_FUNCTION(kind << length);
133 static uint8_t lastRegisteredType = UNASSIGNED_TYPE;
134 NS_ASSERT_MSG(m_typeRegistry.find({kind, length}) == m_typeRegistry.end(),
135 "An address of the same kind and length is already registered.");
136 lastRegisteredType++;
137 m_typeRegistry[{kind, length}] = lastRegisteredType;
138 return lastRegisteredType;
139}
140
143{
144 NS_LOG_FUNCTION(this);
145 return 1 + 1 + m_len;
146}
147
148void
150{
151 NS_LOG_FUNCTION(this << &buffer);
152 buffer.WriteU8(m_type);
153 buffer.WriteU8(m_len);
154 buffer.Write(m_data.data(), m_len);
155}
156
157void
159{
160 NS_LOG_FUNCTION(this << &buffer);
161 m_type = buffer.ReadU8();
162 m_len = buffer.ReadU8();
164 buffer.Read(m_data.data(), m_len);
165}
166
168
169std::ostream&
170operator<<(std::ostream& os, const Address& address)
171{
172 if (address.m_type == 0)
173 {
174 os << "00-00:00";
175 return os;
176 }
177 std::ios_base::fmtflags ff = os.flags();
178 auto fill = os.fill('0');
179 os.setf(std::ios::hex, std::ios::basefield);
180 os << std::setw(2) << (uint32_t)address.m_type << "-" << std::setw(2) << (uint32_t)address.m_len
181 << "-";
182 for (uint8_t i = 0; i < (address.m_len - 1); ++i)
183 {
184 os << std::setw(2) << (uint32_t)address.m_data[i] << ":";
185 }
186 // Final byte not suffixed by ":"
187 os << std::setw(2) << (uint32_t)address.m_data[address.m_len - 1];
188 os.flags(ff); // Restore stream flags
189 os.fill(fill);
190 return os;
191}
192
193std::istream&
194operator>>(std::istream& is, Address& address)
195{
196 std::string v;
197 is >> v;
198 std::string::size_type firstDash;
199 std::string::size_type secondDash;
200 firstDash = v.find('-');
201 secondDash = v.find('-', firstDash + 1);
202 std::string type = v.substr(0, firstDash);
203 std::string len = v.substr(firstDash + 1, secondDash - (firstDash + 1));
204
205 address.m_type = std::stoul(type, nullptr, 16);
206 address.m_len = std::stoul(len, nullptr, 16);
207 NS_ASSERT(address.m_len <= Address::MAX_SIZE);
208
209 std::string::size_type col = secondDash + 1;
210 for (uint8_t i = 0; i < address.m_len; ++i)
211 {
212 std::string tmp;
213 std::string::size_type next;
214 next = v.find(':', col);
215 if (next == std::string::npos)
216 {
217 tmp = v.substr(col, v.size() - col);
218 address.m_data[i] = std::stoul(tmp, nullptr, 16);
219 break;
220 }
221 else
222 {
223 tmp = v.substr(col, next - col);
224 address.m_data[i] = std::stoul(tmp, nullptr, 16);
225 col = next + 1;
226 }
227 }
228 return is;
229}
230
231} // namespace ns3
uint32_t v
a polymophic address class
Definition address.h:114
uint32_t GetSerializedSize() const
Get the number of bytes needed to serialize the underlying Address Typically, this is GetLength () + ...
Definition address.cc:142
void Serialize(TagBuffer buffer) const
Serialize this address in host byte order to a byte buffer.
Definition address.cc:149
static constexpr uint8_t UNASSIGNED_TYPE
Unassigned Address type is reserved. Defined for clarity.
Definition address.h:150
uint32_t CopyFrom(const uint8_t *buffer, uint8_t len)
Definition address.cc:90
static constexpr uint32_t MAX_SIZE
The maximum size of a byte buffer which can be stored in an Address instance.
Definition address.h:157
bool IsInvalid() const
Definition address.cc:55
uint8_t m_len
Length of the address.
Definition address.h:325
void SetType(const std::string &kind, uint8_t length)
Set the address type.
Definition address.cc:37
std::array< uint8_t, MAX_SIZE > m_data
The address value.
Definition address.h:326
uint8_t m_type
Type of the address.
Definition address.h:324
std::unordered_map< KindType, uint8_t, Address::KeyHash > KindTypeRegistry
Type of the address registry.
Definition address.h:140
static KindTypeRegistry m_typeRegistry
Container of allocated address types.
Definition address.h:147
uint32_t CopyAllFrom(const uint8_t *buffer, uint8_t len)
Definition address.cc:102
bool CheckCompatible(uint8_t type, uint8_t len) const
Definition address.cc:115
Address()=default
Create an invalid address.
uint8_t GetLength() const
Get the length of the underlying address.
Definition address.cc:62
uint32_t CopyTo(uint8_t buffer[MAX_SIZE]) const
Copy the address bytes into a buffer.
Definition address.cc:70
void Deserialize(TagBuffer buffer)
Definition address.cc:158
static uint8_t Register(const std::string &kind, uint8_t length)
Allocate a new type id for a new type of address.
Definition address.cc:130
bool IsMatchingType(uint8_t type) const
Definition address.cc:123
uint32_t CopyAllTo(uint8_t *buffer, uint8_t len) const
Definition address.cc:79
read and write tag data
Definition tag-buffer.h:41
void Read(uint8_t *buffer, uint32_t size)
TAG_BUFFER_INLINE void WriteU8(uint8_t v)
Definition tag-buffer.h:161
TAG_BUFFER_INLINE uint8_t ReadU8()
Definition tag-buffer.h:185
void Write(const uint8_t *buffer, uint32_t size)
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#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 ATTRIBUTE_HELPER_CPP(type)
Define the attribute value, accessor and checkers for class type.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#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)
Definition angles.cc:148
std::istream & operator>>(std::istream &is, Angles &a)
Definition angles.cc:172