A Discrete-Event Network Simulator
API
address.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2007 INRIA
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19 */
20
21#include "ns3/assert.h"
22#include "ns3/log.h"
23#include "address.h"
24#include <cstring>
25#include <iostream>
26#include <iomanip>
27
28namespace ns3 {
29
30NS_LOG_COMPONENT_DEFINE ("Address");
31
33 : m_type (0),
34 m_len (0)
35{
36 // Buffer left uninitialized
37 NS_LOG_FUNCTION (this);
38
39}
40
41Address::Address (uint8_t type, const uint8_t *buffer, uint8_t len)
42 : m_type (type),
43 m_len (len)
44{
45 NS_LOG_FUNCTION (this << static_cast<uint32_t> (type) << &buffer << static_cast<uint32_t> (len));
47 std::memcpy (m_data, buffer, m_len);
48}
50 : m_type (address.m_type),
51 m_len (address.m_len)
52{
54 std::memcpy (m_data, address.m_data, m_len);
55}
56Address &
58{
60 m_type = address.m_type;
61 m_len = address.m_len;
63 std::memcpy (m_data, address.m_data, m_len);
64 return *this;
65}
66
67bool
69{
70 NS_LOG_FUNCTION (this);
71 return m_len == 0 && m_type == 0;
72}
73
74uint8_t
76{
77 NS_LOG_FUNCTION (this);
79 return m_len;
80}
82Address::CopyTo (uint8_t buffer[MAX_SIZE]) const
83{
84 NS_LOG_FUNCTION (this << &buffer);
86 std::memcpy (buffer, m_data, m_len);
87 return m_len;
88}
90Address::CopyAllTo (uint8_t *buffer, uint8_t len) const
91{
92 NS_LOG_FUNCTION (this << &buffer << static_cast<uint32_t> (len));
93 NS_ASSERT (len - m_len > 1);
94 buffer[0] = m_type;
95 buffer[1] = m_len;
96 std::memcpy (buffer + 2, m_data, m_len);
97 return m_len + 2;
98}
99
101Address::CopyFrom (const uint8_t *buffer, uint8_t len)
102{
103 NS_LOG_FUNCTION (this << &buffer << static_cast<uint32_t> (len));
104 NS_ASSERT (len <= MAX_SIZE);
105 std::memcpy (m_data, buffer, len);
106 m_len = len;
107 return m_len;
108}
110Address::CopyAllFrom (const uint8_t *buffer, uint8_t len)
111{
112 NS_LOG_FUNCTION (this << &buffer << static_cast<uint32_t> (len));
113 NS_ASSERT (len >= 2);
114 m_type = buffer[0];
115 m_len = buffer[1];
116
117 NS_ASSERT (len - m_len > 1);
118 std::memcpy (m_data, buffer + 2, m_len);
119 return m_len + 2;
120}
121bool
122Address::CheckCompatible (uint8_t type, uint8_t len) const
123{
124 NS_LOG_FUNCTION (this << static_cast<uint32_t> (type) << static_cast<uint32_t> (len));
125 NS_ASSERT (len <= MAX_SIZE);
128 return (m_len == len && m_type == type) || (m_len >= len && m_type == 0);
129}
130bool
131Address::IsMatchingType (uint8_t type) const
132{
133 NS_LOG_FUNCTION (this << static_cast<uint32_t> (type));
134 return m_type == type;
135}
136
137uint8_t
139{
141 static uint8_t type = 1;
142 type++;
143 return type;
144}
145
148{
149 NS_LOG_FUNCTION (this);
150 return 1 + 1 + m_len;
151}
152
153void
155{
156 NS_LOG_FUNCTION (this << &buffer);
157 buffer.WriteU8 (m_type);
158 buffer.WriteU8 (m_len);
159 buffer.Write (m_data, m_len);
160}
161
162void
164{
165 NS_LOG_FUNCTION (this << &buffer);
166 m_type = buffer.ReadU8 ();
167 m_len = buffer.ReadU8 ();
169 buffer.Read (m_data, m_len);
170}
171
173
174
175bool operator == (const Address &a, const Address &b)
176{
177 /* Two addresses can be equal even if their types are
178 * different if one of the two types is zero. a type of
179 * zero identifies an Address which might contain meaningful
180 * payload but for which the type field could not be set because
181 * we did not know it. This can typically happen in the ARP
182 * layer where we receive an address from an ArpHeader but
183 * we do not know its type: we really want to be able to
184 * compare addresses without knowing their real type.
185 */
186 if (a.m_type != b.m_type &&
187 a.m_type != 0 &&
188 b.m_type != 0)
189 {
190 return false;
191 }
192 if (a.m_len != b.m_len)
193 {
194 return false;
195 }
196 return std::memcmp (a.m_data, b.m_data, a.m_len) == 0;
197}
198bool operator != (const Address &a, const Address &b)
199{
200 return !(a == b);
201}
202bool operator < (const Address &a, const Address &b)
203{
204 if (a.m_type < b.m_type)
205 {
206 return true;
207 }
208 else if (a.m_type > b.m_type)
209 {
210 return false;
211 }
212 if (a.m_len < b.m_len)
213 {
214 return true;
215 }
216 else if (a.m_len > b.m_len)
217 {
218 return false;
219 }
220 NS_ASSERT (a.GetLength () == b.GetLength ());
221 for (uint8_t i = 0; i < a.GetLength (); i++)
222 {
223 if (a.m_data[i] < b.m_data[i])
224 {
225 return true;
226 }
227 else if (a.m_data[i] > b.m_data[i])
228 {
229 return false;
230 }
231 }
232 return false;
233}
234
235std::ostream& operator<< (std::ostream& os, const Address & address)
236{
237 os.setf (std::ios::hex, std::ios::basefield);
238 os.fill ('0');
239 os << std::setw (2) << (uint32_t) address.m_type << "-" << std::setw (2) << (uint32_t) address.m_len << "-";
240 for (uint8_t i = 0; i < (address.m_len-1); ++i)
241 {
242 os << std::setw (2) << (uint32_t)address.m_data[i] << ":";
243 }
244 // Final byte not suffixed by ":"
245 os << std::setw (2) << (uint32_t) address.m_data[address.m_len-1];
246 os.setf (std::ios::dec, std::ios::basefield);
247 os.fill (' ');
248 return os;
249}
250
251std::istream& operator>> (std::istream& is, Address & address)
252{
253 std::string v;
254 is >> v;
255 std::string::size_type firstDash, secondDash;
256 firstDash = v.find ("-");
257 secondDash = v.find ("-", firstDash+1);
258 std::string type = v.substr (0, firstDash-0);
259 std::string len = v.substr (firstDash+1, secondDash-(firstDash+1));
260
261 address.m_type = strtoul (type.c_str(), 0, 16);
262 address.m_len = strtoul (len.c_str(), 0, 16);
264
265 std::string::size_type col = secondDash + 1;
266 for (uint8_t i = 0; i < address.m_len; ++i)
267 {
268 std::string tmp;
269 std::string::size_type next;
270 next = v.find (":", col);
271 if (next == std::string::npos)
272 {
273 tmp = v.substr (col, v.size ()-col);
274 address.m_data[i] = strtoul (tmp.c_str(), 0, 16);
275 break;
276 }
277 else
278 {
279 tmp = v.substr (col, next-col);
280 address.m_data[i] = strtoul (tmp.c_str(), 0, 16);
281 col = next + 1;
282 }
283 }
284 return is;
285}
286
287
288
289} // namespace ns3
a polymophic address class
Definition: address.h:91
uint8_t GetLength(void) const
Get the length of the underlying address.
Definition: address.cc:75
void Serialize(TagBuffer buffer) const
Serialize this address in host byte order to a byte buffer.
Definition: address.cc:154
uint32_t CopyFrom(const uint8_t *buffer, uint8_t len)
Definition: address.cc:101
uint8_t m_len
Length of the address.
Definition: address.h:274
uint8_t m_data[MAX_SIZE]
The address value.
Definition: address.h:275
uint32_t GetSerializedSize(void) const
Get the number of bytes needed to serialize the underlying Address Typically, this is GetLength () + ...
Definition: address.cc:147
static uint8_t Register(void)
Allocate a new type id for a new type of address.
Definition: address.cc:138
uint8_t m_type
Type of the address.
Definition: address.h:273
Address & operator=(const Address &address)
Basic assignment operator.
Definition: address.cc:57
Address()
Create an invalid address.
Definition: address.cc:32
uint32_t CopyAllFrom(const uint8_t *buffer, uint8_t len)
Definition: address.cc:110
bool CheckCompatible(uint8_t type, uint8_t len) const
Definition: address.cc:122
bool IsInvalid(void) const
Definition: address.cc:68
uint32_t CopyTo(uint8_t buffer[MAX_SIZE]) const
Copy the address bytes into a buffer.
Definition: address.cc:82
void Deserialize(TagBuffer buffer)
Definition: address.cc:163
bool IsMatchingType(uint8_t type) const
Definition: address.cc:131
uint32_t CopyAllTo(uint8_t *buffer, uint8_t len) const
Definition: address.cc:90
read and write tag data
Definition: tag-buffer.h:52
void Read(uint8_t *buffer, uint32_t size)
Definition: tag-buffer.cc:176
TAG_BUFFER_INLINE void WriteU8(uint8_t v)
Definition: tag-buffer.h:172
void Write(const uint8_t *buffer, uint32_t size)
Definition: tag-buffer.cc:125
TAG_BUFFER_INLINE uint8_t ReadU8(void)
Definition: tag-buffer.h:195
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#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:44
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool operator==(const EventId &a, const EventId &b)
Definition: event-id.h:158
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:139
ATTRIBUTE_HELPER_CPP(Length)
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:162
bool operator<(const EventId &a, const EventId &b)
Definition: event-id.h:176
bool operator!=(Callback< R, T1, T2, T3, T4, T5, T6, T7, T8, T9 > a, Callback< R, T1, T2, T3, T4, T5, T6, T7, T8, T9 > b)
Inequality test.
Definition: callback.h:1612