A Discrete-Event Network Simulator
API
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 
29 namespace ns3
30 {
31 
32 NS_LOG_COMPONENT_DEFINE("Address");
33 
35  : m_type(0),
36  m_len(0)
37 {
38  // Buffer left uninitialized
39  NS_LOG_FUNCTION(this);
40 }
41 
42 Address::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 
59 Address&
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 
70 bool
72 {
73  NS_LOG_FUNCTION(this);
74  return m_len == 0 && m_type == 0;
75 }
76 
77 uint8_t
79 {
80  NS_LOG_FUNCTION(this);
82  return m_len;
83 }
84 
85 uint32_t
86 Address::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 
94 uint32_t
95 Address::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 
105 uint32_t
106 Address::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 
115 uint32_t
116 Address::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 
128 bool
129 Address::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);
135  return (m_len == len && m_type == type) || (m_len >= len && m_type == 0);
136 }
137 
138 bool
140 {
141  NS_LOG_FUNCTION(this << static_cast<uint32_t>(type));
142  return m_type == type;
143 }
144 
145 uint8_t
147 {
149  static uint8_t type = 1;
150  type++;
151  return type;
152 }
153 
154 uint32_t
156 {
157  NS_LOG_FUNCTION(this);
158  return 1 + 1 + m_len;
159 }
160 
161 void
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 
170 void
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 
182 bool
183 operator==(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 
205 bool
206 operator!=(const Address& a, const Address& b)
207 {
208  return !(a == b);
209 }
210 
211 bool
212 operator<(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 
245 std::ostream&
246 operator<<(std::ostream& os, const Address& address)
247 {
248  os.setf(std::ios::hex, std::ios::basefield);
249  os.fill('0');
250  os << std::setw(2) << (uint32_t)address.m_type << "-" << std::setw(2) << (uint32_t)address.m_len
251  << "-";
252  for (uint8_t i = 0; i < (address.m_len - 1); ++i)
253  {
254  os << std::setw(2) << (uint32_t)address.m_data[i] << ":";
255  }
256  // Final byte not suffixed by ":"
257  os << std::setw(2) << (uint32_t)address.m_data[address.m_len - 1];
258  os.setf(std::ios::dec, std::ios::basefield);
259  os.fill(' ');
260  return os;
261 }
262 
263 std::istream&
264 operator>>(std::istream& is, Address& address)
265 {
266  std::string v;
267  is >> v;
268  std::string::size_type firstDash;
269  std::string::size_type secondDash;
270  firstDash = v.find('-');
271  secondDash = v.find('-', firstDash + 1);
272  std::string type = v.substr(0, firstDash);
273  std::string len = v.substr(firstDash + 1, secondDash - (firstDash + 1));
274 
275  address.m_type = std::stoul(type, nullptr, 16);
276  address.m_len = std::stoul(len, nullptr, 16);
278 
279  std::string::size_type col = secondDash + 1;
280  for (uint8_t i = 0; i < address.m_len; ++i)
281  {
282  std::string tmp;
283  std::string::size_type next;
284  next = v.find(':', col);
285  if (next == std::string::npos)
286  {
287  tmp = v.substr(col, v.size() - col);
288  address.m_data[i] = std::stoul(tmp, nullptr, 16);
289  break;
290  }
291  else
292  {
293  tmp = v.substr(col, next - col);
294  address.m_data[i] = std::stoul(tmp, nullptr, 16);
295  col = next + 1;
296  }
297  }
298  return is;
299 }
300 
301 } // 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 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 ",...
address
Definition: first.py:47
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:678
bool operator==(const EventId &a, const EventId &b)
Definition: event-id.h:157
ATTRIBUTE_HELPER_CPP(ValueClassTest)
bool operator<(const EventId &a, const EventId &b)
Definition: event-id.h:170
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:183
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:159