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 
28 namespace ns3 {
29 
30 NS_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 
41 Address::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 }
56 Address &
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 
67 bool
68 Address::IsInvalid (void) const
69 {
70  NS_LOG_FUNCTION (this);
71  return m_len == 0 && m_type == 0;
72 }
73 
74 uint8_t
75 Address::GetLength (void) const
76 {
77  NS_LOG_FUNCTION (this);
79  return m_len;
80 }
81 uint32_t
82 Address::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 }
89 uint32_t
90 Address::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 
100 uint32_t
101 Address::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 }
109 uint32_t
110 Address::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 }
121 bool
122 Address::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 }
130 bool
131 Address::IsMatchingType (uint8_t type) const
132 {
133  NS_LOG_FUNCTION (this << static_cast<uint32_t> (type));
134  return m_type == type;
135 }
136 
137 uint8_t
139 {
141  static uint8_t type = 1;
142  type++;
143  return type;
144 }
145 
146 uint32_t
148 {
149  NS_LOG_FUNCTION (this);
150  return 1 + 1 + m_len;
151 }
152 
153 void
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 
162 void
164 {
165  NS_LOG_FUNCTION (this << &buffer);
166  m_type = buffer.ReadU8 ();
167  m_len = buffer.ReadU8 ();
168  NS_ASSERT (m_len <= MAX_SIZE);
169  buffer.Read (m_data, m_len);
170 }
171 
173 
174 
175 bool 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 }
198 bool operator != (const Address &a, const Address &b)
199 {
200  return !(a == b);
201 }
202 bool 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 
235 std::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 
251 std::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
ATTRIBUTE_HELPER_CPP(Length)
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
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:162
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:139