A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 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));
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);
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);
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 static uint8_t
252 AsInt (std::string v)
253 {
255  std::istringstream iss;
256  iss.str (v);
257  uint8_t retval;
258  iss >> std::hex >> retval >> std::dec;
259  return retval;
260 }
261 
262 std::istream& operator>> (std::istream& is, Address & address)
263 {
264  std::string v;
265  is >> v;
266  std::string::size_type firstDash, secondDash;
267  firstDash = v.find ("-");
268  secondDash = v.find ("-", firstDash+1);
269  std::string type = v.substr (0, firstDash-0);
270  std::string len = v.substr (firstDash+1, secondDash-(firstDash+1));
271 
272  address.m_type = AsInt (type);
273  address.m_len = AsInt (len);
274  NS_ASSERT (address.m_len <= Address::MAX_SIZE);
275 
276  std::string::size_type col = secondDash + 1;
277  for (uint8_t i = 0; i < address.m_len; ++i)
278  {
279  std::string tmp;
280  std::string::size_type next;
281  next = v.find (":", col);
282  if (next == std::string::npos)
283  {
284  tmp = v.substr (col, v.size ()-col);
285  address.m_data[i] = AsInt (tmp);
286  break;
287  }
288  else
289  {
290  tmp = v.substr (col, next-col);
291  address.m_data[i] = AsInt (tmp);
292  col = next + 1;
293  }
294  }
295  return is;
296 }
297 
298 
299 
300 } // namespace ns3
bool IsInvalid(void) const
Definition: address.cc:68
uint8_t m_len
Definition: address.h:218
std::istream & operator>>(std::istream &is, Angles &a)
initialize a struct Angles from input
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:345
bool IsMatchingType(uint8_t type) const
Definition: address.cc:131
#define NS_ASSERT(condition)
Definition: assert.h:64
bool operator<(const Room &a, const Room &b)
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log.h:309
static uint8_t AsInt(std::string v)
Definition: address.cc:252
Address()
Create an invalid address.
Definition: address.cc:32
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
Address & operator=(const Address &address)
Definition: address.cc:57
uint8_t m_type
Definition: address.h:217
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:163
uint32_t GetSerializedSize(void) const
Get the number of bytes needed to serialize the underlying Address Typically, this is GetLength () + ...
Definition: address.cc:147
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:43
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:1213
uint32_t CopyFrom(const uint8_t *buffer, uint8_t len)
Definition: address.cc:101
uint8_t m_data[MAX_SIZE]
Definition: address.h:219
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
Serialize this address in host byte order to a byte buffer.
Definition: address.cc:154
bool operator==(const EventId &a, const EventId &b)
Definition: event-id.cc:89
void Read(uint8_t *buffer, uint32_t size)
Definition: tag-buffer.cc:176
tuple address
Definition: first.py:37
ATTRIBUTE_HELPER_CPP(ObjectFactory)
NS_LOG_COMPONENT_DEFINE("Address")
static uint8_t Register(void)
Allocate a new type id for a new type of address.
Definition: address.cc:138