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 */
8
9#include "address.h"
10
11#include "ns3/assert.h"
12#include "ns3/log.h"
13
14#include <cstring>
15#include <iomanip>
16#include <iostream>
17
18namespace ns3
19{
20
22
24 : m_type(0),
25 m_len(0)
26{
27 // Buffer left uninitialized
28 NS_LOG_FUNCTION(this);
29}
30
31Address::Address(uint8_t type, const uint8_t* buffer, uint8_t len)
32 : m_type(type),
33 m_len(len)
34{
35 NS_LOG_FUNCTION(this << static_cast<uint32_t>(type) << &buffer << static_cast<uint32_t>(len));
37 std::memcpy(m_data, buffer, m_len);
38}
39
41 : m_type(address.m_type),
42 m_len(address.m_len)
43{
45 std::memcpy(m_data, address.m_data, m_len);
46}
47
50{
52 m_type = address.m_type;
53 m_len = address.m_len;
55 std::memcpy(m_data, address.m_data, m_len);
56 return *this;
57}
58
59bool
61{
62 NS_LOG_FUNCTION(this);
63 return m_len == 0 && m_type == 0;
64}
65
66uint8_t
68{
69 NS_LOG_FUNCTION(this);
71 return m_len;
72}
73
75Address::CopyTo(uint8_t buffer[MAX_SIZE]) const
76{
77 NS_LOG_FUNCTION(this << &buffer);
79 std::memcpy(buffer, m_data, m_len);
80 return m_len;
81}
82
84Address::CopyAllTo(uint8_t* buffer, uint8_t len) const
85{
86 NS_LOG_FUNCTION(this << &buffer << static_cast<uint32_t>(len));
87 NS_ASSERT(len - m_len > 1);
88 buffer[0] = m_type;
89 buffer[1] = m_len;
90 std::memcpy(buffer + 2, m_data, m_len);
91 return m_len + 2;
92}
93
95Address::CopyFrom(const uint8_t* buffer, uint8_t len)
96{
97 NS_LOG_FUNCTION(this << &buffer << static_cast<uint32_t>(len));
98 NS_ASSERT(len <= MAX_SIZE);
99 std::memcpy(m_data, buffer, len);
100 m_len = len;
101 return m_len;
102}
103
105Address::CopyAllFrom(const uint8_t* buffer, uint8_t len)
106{
107 NS_LOG_FUNCTION(this << &buffer << static_cast<uint32_t>(len));
108 NS_ASSERT(len >= 2);
109 m_type = buffer[0];
110 m_len = buffer[1];
111
112 NS_ASSERT(len - m_len > 1);
113 std::memcpy(m_data, buffer + 2, m_len);
114 return m_len + 2;
115}
116
117bool
118Address::CheckCompatible(uint8_t type, uint8_t len) const
119{
120 NS_LOG_FUNCTION(this << static_cast<uint32_t>(type) << static_cast<uint32_t>(len));
121 NS_ASSERT(len <= MAX_SIZE);
122 /// @internal
123 /// Mac address type/length detection is discussed in \bugid{1568}
124 return (m_len == len && m_type == type) || (m_len >= len && m_type == 0);
125}
126
127bool
128Address::IsMatchingType(uint8_t type) const
129{
130 NS_LOG_FUNCTION(this << static_cast<uint32_t>(type));
131 return m_type == type;
132}
133
134uint8_t
136{
138 static uint8_t type = 1;
139 type++;
140 return type;
141}
142
145{
146 NS_LOG_FUNCTION(this);
147 return 1 + 1 + m_len;
148}
149
150void
152{
153 NS_LOG_FUNCTION(this << &buffer);
154 buffer.WriteU8(m_type);
155 buffer.WriteU8(m_len);
156 buffer.Write(m_data, m_len);
157}
158
159void
161{
162 NS_LOG_FUNCTION(this << &buffer);
163 m_type = buffer.ReadU8();
164 m_len = buffer.ReadU8();
166 buffer.Read(m_data, m_len);
167}
168
170
171bool
172operator==(const Address& a, const Address& b)
173{
174 /* Two addresses can be equal even if their types are
175 * different if one of the two types is zero. a type of
176 * zero identifies an Address which might contain meaningful
177 * payload but for which the type field could not be set because
178 * we did not know it. This can typically happen in the ARP
179 * layer where we receive an address from an ArpHeader but
180 * we do not know its type: we really want to be able to
181 * compare addresses without knowing their real type.
182 */
183 if (a.m_type != b.m_type && a.m_type != 0 && b.m_type != 0)
184 {
185 return false;
186 }
187 if (a.m_len != b.m_len)
188 {
189 return false;
190 }
191 return std::memcmp(a.m_data, b.m_data, a.m_len) == 0;
192}
193
194bool
195operator!=(const Address& a, const Address& b)
196{
197 return !(a == b);
198}
199
200bool
201operator<(const Address& a, const Address& b)
202{
203 if (a.m_type < b.m_type)
204 {
205 return true;
206 }
207 else if (a.m_type > b.m_type)
208 {
209 return false;
210 }
211 if (a.m_len < b.m_len)
212 {
213 return true;
214 }
215 else if (a.m_len > b.m_len)
216 {
217 return false;
218 }
219 NS_ASSERT(a.GetLength() == b.GetLength());
220 for (uint8_t i = 0; i < a.GetLength(); i++)
221 {
222 if (a.m_data[i] < b.m_data[i])
223 {
224 return true;
225 }
226 else if (a.m_data[i] > b.m_data[i])
227 {
228 return false;
229 }
230 }
231 return false;
232}
233
234std::ostream&
235operator<<(std::ostream& os, const Address& address)
236{
237 if (address.m_len == 0)
238 {
239 return os;
240 }
241 os.setf(std::ios::hex, std::ios::basefield);
242 os.fill('0');
243 os << std::setw(2) << (uint32_t)address.m_type << "-" << std::setw(2) << (uint32_t)address.m_len
244 << "-";
245 for (uint8_t i = 0; i < (address.m_len - 1); ++i)
246 {
247 os << std::setw(2) << (uint32_t)address.m_data[i] << ":";
248 }
249 // Final byte not suffixed by ":"
250 os << std::setw(2) << (uint32_t)address.m_data[address.m_len - 1];
251 os.setf(std::ios::dec, std::ios::basefield);
252 os.fill(' ');
253 return os;
254}
255
256std::istream&
257operator>>(std::istream& is, Address& address)
258{
259 std::string v;
260 is >> v;
261 std::string::size_type firstDash;
262 std::string::size_type secondDash;
263 firstDash = v.find('-');
264 secondDash = v.find('-', firstDash + 1);
265 std::string type = v.substr(0, firstDash);
266 std::string len = v.substr(firstDash + 1, secondDash - (firstDash + 1));
267
268 address.m_type = std::stoul(type, nullptr, 16);
269 address.m_len = std::stoul(len, nullptr, 16);
270 NS_ASSERT(address.m_len <= Address::MAX_SIZE);
271
272 std::string::size_type col = secondDash + 1;
273 for (uint8_t i = 0; i < address.m_len; ++i)
274 {
275 std::string tmp;
276 std::string::size_type next;
277 next = v.find(':', col);
278 if (next == std::string::npos)
279 {
280 tmp = v.substr(col, v.size() - col);
281 address.m_data[i] = std::stoul(tmp, nullptr, 16);
282 break;
283 }
284 else
285 {
286 tmp = v.substr(col, next - col);
287 address.m_data[i] = std::stoul(tmp, nullptr, 16);
288 col = next + 1;
289 }
290 }
291 return is;
292}
293
294} // namespace ns3
a polymophic address class
Definition address.h:90
uint32_t GetSerializedSize() const
Get the number of bytes needed to serialize the underlying Address Typically, this is GetLength () + ...
Definition address.cc:144
void Serialize(TagBuffer buffer) const
Serialize this address in host byte order to a byte buffer.
Definition address.cc:151
uint32_t CopyFrom(const uint8_t *buffer, uint8_t len)
Definition address.cc:95
static constexpr uint32_t MAX_SIZE
The maximum size of a byte buffer which can be stored in an Address instance.
Definition address.h:96
bool IsInvalid() const
Definition address.cc:60
uint8_t m_len
Length of the address.
Definition address.h:271
uint8_t m_data[MAX_SIZE]
The address value.
Definition address.h:272
uint8_t m_type
Type of the address.
Definition address.h:270
Address & operator=(const Address &address)
Basic assignment operator.
Definition address.cc:49
Address()
Create an invalid address.
Definition address.cc:23
uint32_t CopyAllFrom(const uint8_t *buffer, uint8_t len)
Definition address.cc:105
bool CheckCompatible(uint8_t type, uint8_t len) const
Definition address.cc:118
static uint8_t Register()
Allocate a new type id for a new type of address.
Definition address.cc:135
uint8_t GetLength() const
Get the length of the underlying address.
Definition address.cc:67
uint32_t CopyTo(uint8_t buffer[MAX_SIZE]) const
Copy the address bytes into a buffer.
Definition address.cc:75
void Deserialize(TagBuffer buffer)
Definition address.cc:160
bool IsMatchingType(uint8_t type) const
Definition address.cc:128
uint32_t CopyAllTo(uint8_t *buffer, uint8_t len) const
Definition address.cc:84
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 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:191
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#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.
bool operator!=(Callback< R, Args... > a, Callback< R, Args... > b)
Inequality test.
Definition callback.h:658
bool operator==(const EventId &a, const EventId &b)
Definition event-id.h:155
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
bool operator<(const EventId &a, const EventId &b)
Definition event-id.h:168