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