A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
address.cc
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 NS_LOG_COMPONENT_DEFINE ("Address");
29 
30 namespace ns3 {
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));
46  NS_ASSERT (m_len <= MAX_SIZE);
47  std::memcpy (m_data, buffer, m_len);
48 }
49 Address::Address (const Address & address)
50  : m_type (address.m_type),
51  m_len (address.m_len)
52 {
53  NS_ASSERT (m_len <= MAX_SIZE);
54  std::memcpy (m_data, address.m_data, m_len);
55 }
56 Address &
57 Address::operator = (const Address &address)
58 {
59  NS_ASSERT (m_len <= MAX_SIZE);
60  m_type = address.m_type;
61  m_len = address.m_len;
62  NS_ASSERT (m_len <= MAX_SIZE);
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);
78  NS_ASSERT (m_len <= MAX_SIZE);
79  return m_len;
80 }
81 uint32_t
82 Address::CopyTo (uint8_t buffer[MAX_SIZE]) const
83 {
84  NS_LOG_FUNCTION (this << &buffer);
85  NS_ASSERT (m_len <= MAX_SIZE);
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 + 2);
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 + 2);
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);
126  // Mac address type/length detection is discussed in bug 1568
127  return (m_len == len && m_type == type) || (m_len >= len && m_type == 0);
128 }
129 bool
130 Address::IsMatchingType (uint8_t type) const
131 {
132  NS_LOG_FUNCTION (this << static_cast<uint32_t> (type));
133  return m_type == type;
134 }
135 
136 uint8_t
138 {
140  static uint8_t type = 1;
141  type++;
142  return type;
143 }
144 
145 uint32_t
147 {
148  NS_LOG_FUNCTION (this);
149  return 1 + 1 + m_len;
150 }
151 
152 void
154 {
155  NS_LOG_FUNCTION (this << &buffer);
156  buffer.WriteU8 (m_type);
157  buffer.WriteU8 (m_len);
158  buffer.Write (m_data, m_len);
159 }
160 
161 void
163 {
164  NS_LOG_FUNCTION (this << &buffer);
165  m_type = buffer.ReadU8 ();
166  m_len = buffer.ReadU8 ();
167  NS_ASSERT (m_len <= MAX_SIZE);
168  buffer.Read (m_data, m_len);
169 }
170 
172 
173 
174 bool operator == (const Address &a, const Address &b)
175 {
176  /* Two addresses can be equal even if their types are
177  * different if one of the two types is zero. a type of
178  * zero identifies an Address which might contain meaningful
179  * payload but for which the type field could not be set because
180  * we did not know it. This can typically happen in the ARP
181  * layer where we receive an address from an ArpHeader but
182  * we do not know its type: we really want to be able to
183  * compare addresses without knowing their real type.
184  */
185  if (a.m_type != b.m_type &&
186  a.m_type != 0 &&
187  b.m_type != 0)
188  {
189  return false;
190  }
191  if (a.m_len != b.m_len)
192  {
193  return false;
194  }
195  return std::memcmp (a.m_data, b.m_data, a.m_len) == 0;
196 }
197 bool operator != (const Address &a, const Address &b)
198 {
199  return !(a == b);
200 }
201 bool operator < (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 
234 std::ostream& operator<< (std::ostream& os, const Address & address)
235 {
236  os.setf (std::ios::hex, std::ios::basefield);
237  os.fill ('0');
238  os << std::setw (2) << (uint32_t) address.m_type << "-" << std::setw (2) << (uint32_t) address.m_len << "-";
239  for (uint8_t i = 0; i < (address.m_len-1); ++i)
240  {
241  os << std::setw (2) << (uint32_t)address.m_data[i] << ":";
242  }
243  // Final byte not suffixed by ":"
244  os << std::setw (2) << (uint32_t) address.m_data[address.m_len-1];
245  os.setf (std::ios::dec, std::ios::basefield);
246  os.fill (' ');
247  return os;
248 }
249 
250 static uint8_t
251 AsInt (std::string v)
252 {
254  std::istringstream iss;
255  iss.str (v);
256  uint32_t retval;
257  iss >> std::hex >> retval >> std::dec;
258  return retval;
259 }
260 
261 std::istream& operator>> (std::istream& is, Address & address)
262 {
263  std::string v;
264  is >> v;
265  std::string::size_type firstDash, secondDash;
266  firstDash = v.find ("-");
267  secondDash = v.find ("-", firstDash+1);
268  std::string type = v.substr (0, firstDash-0);
269  std::string len = v.substr (firstDash+1, secondDash-(firstDash+1));
270 
271  address.m_type = AsInt (type);
272  address.m_len = AsInt (len);
273  NS_ASSERT (address.m_len <= Address::MAX_SIZE);
274 
275  std::string::size_type col = secondDash + 1;
276  for (uint8_t i = 0; i < address.m_len; ++i)
277  {
278  std::string tmp;
279  std::string::size_type next;
280  next = v.find (":", col);
281  if (next == std::string::npos)
282  {
283  tmp = v.substr (col, v.size ()-col);
284  address.m_data[i] = AsInt (tmp);
285  break;
286  }
287  else
288  {
289  tmp = v.substr (col, next-col);
290  address.m_data[i] = AsInt (tmp);
291  col = next + 1;
292  }
293  }
294  return is;
295 }
296 
297 Address& operator+ (Address & address, int increment)
298 {
299  uint64_t id;
300  id = (uint64_t)address.m_data[0] << 40 |
301  (uint64_t)address.m_data[1] << 32 |
302  (uint64_t)address.m_data[2] << 24 |
303  (uint64_t)address.m_data[3] << 16 |
304  (uint64_t)address.m_data[4] << 8 |
305  (uint64_t)address.m_data[5];
306 
307  id=id+increment;
308  uint8_t m_address[6];
309  std::memset (m_address, 0, 6);
310 
311  m_address[0] = (id >> 40) & 0xff;
312  m_address[1] = (id >> 32) & 0xff;
313  m_address[2] = (id >> 24) & 0xff;
314  m_address[3] = (id >> 16) & 0xff;
315  m_address[4] = (id >> 8) & 0xff;
316  m_address[5] = (id >> 0) & 0xff;
317  address.CopyFrom(m_address, 6);
318  return address;
319 }
320 
321 
322 } // namespace ns3
bool IsInvalid(void) const
Definition: address.cc:68
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:49
void Write(const uint8_t *buffer, uint32_t size)
Definition: tag-buffer.cc:125
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
bool IsMatchingType(uint8_t type) const
Definition: address.cc:130
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
TAG_BUFFER_INLINE uint8_t ReadU8(void)
Definition: tag-buffer.h:179
a polymophic address class
Definition: address.h:86
bool CheckCompatible(uint8_t type, uint8_t len) const
Definition: address.cc:122
uint32_t CopyAllTo(uint8_t *buffer, uint8_t len) const
Definition: address.cc:90
uint8_t GetLength(void) const
Definition: address.cc:75
uint32_t CopyAllFrom(const uint8_t *buffer, uint8_t len)
Definition: address.cc:110
void Deserialize(TagBuffer buffer)
Definition: address.cc:162
uint32_t GetSerializedSize(void) const
Definition: address.cc:146
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:43
uint32_t CopyFrom(const uint8_t *buffer, uint8_t len)
Definition: address.cc:101
#define ATTRIBUTE_HELPER_CPP(type)
TAG_BUFFER_INLINE void WriteU8(uint8_t v)
Definition: tag-buffer.h:156
read and write tag data
Definition: tag-buffer.h:51
uint32_t CopyTo(uint8_t buffer[MAX_SIZE]) const
Definition: address.cc:82
void Serialize(TagBuffer buffer) const
Definition: address.cc:153
void Read(uint8_t *buffer, uint32_t size)
Definition: tag-buffer.cc:176
static uint8_t Register(void)
Definition: address.cc:137