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 }
49 Address::Address (const Address & address)
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);
126  return m_len == len && (m_type == type || m_type == 0);
127 }
128 bool
129 Address::IsMatchingType (uint8_t type) const
130 {
131  NS_LOG_FUNCTION (this << static_cast<uint32_t> (type));
132  return m_type == type;
133 }
134 
135 uint8_t
137 {
139  static uint8_t type = 1;
140  type++;
141  return type;
142 }
143 
144 uint32_t
146 {
147  NS_LOG_FUNCTION (this);
148  return 1 + 1 + m_len;
149 }
150 
151 void
153 {
154  NS_LOG_FUNCTION (this << &buffer);
155  buffer.WriteU8 (m_type);
156  buffer.WriteU8 (m_len);
157  buffer.Write (m_data, m_len);
158 }
159 
160 void
162 {
163  NS_LOG_FUNCTION (this << &buffer);
164  m_type = buffer.ReadU8 ();
165  m_len = buffer.ReadU8 ();
166  NS_ASSERT (m_len <= MAX_SIZE);
167  buffer.Read (m_data, m_len);
168 }
169 
171 
172 
173 bool operator == (const Address &a, const Address &b)
174 {
175  /* Two addresses can be equal even if their types are
176  * different if one of the two types is zero. a type of
177  * zero identifies an Address which might contain meaningful
178  * payload but for which the type field could not be set because
179  * we did not know it. This can typically happen in the ARP
180  * layer where we receive an address from an ArpHeader but
181  * we do not know its type: we really want to be able to
182  * compare addresses without knowing their real type.
183  */
184  if (a.m_type != b.m_type &&
185  a.m_type != 0 &&
186  b.m_type != 0)
187  {
188  return false;
189  }
190  if (a.m_len != b.m_len)
191  {
192  return false;
193  }
194  return std::memcmp (a.m_data, b.m_data, a.m_len) == 0;
195 }
196 bool operator != (const Address &a, const Address &b)
197 {
198  return !(a == b);
199 }
200 bool operator < (const Address &a, const Address &b)
201 {
202  if (a.m_type < b.m_type)
203  {
204  return true;
205  }
206  else if (a.m_type > b.m_type)
207  {
208  return false;
209  }
210  if (a.m_len < b.m_len)
211  {
212  return true;
213  }
214  else if (a.m_len > b.m_len)
215  {
216  return false;
217  }
218  NS_ASSERT (a.GetLength () == b.GetLength ());
219  for (uint8_t i = 0; i < a.GetLength (); i++)
220  {
221  if (a.m_data[i] < b.m_data[i])
222  {
223  return true;
224  }
225  else if (a.m_data[i] > b.m_data[i])
226  {
227  return false;
228  }
229  }
230  return false;
231 }
232 
233 std::ostream& operator<< (std::ostream& os, const Address & address)
234 {
235  os.setf (std::ios::hex, std::ios::basefield);
236  os.fill ('0');
237  os << std::setw (2) << (uint32_t) address.m_type << "-" << std::setw (2) << (uint32_t) address.m_len << "-";
238  for (uint8_t i = 0; i < (address.m_len-1); ++i)
239  {
240  os << std::setw (2) << (uint32_t)address.m_data[i] << ":";
241  }
242  // Final byte not suffixed by ":"
243  os << std::setw (2) << (uint32_t) address.m_data[address.m_len-1];
244  os.setf (std::ios::dec, std::ios::basefield);
245  os.fill (' ');
246  return os;
247 }
248 
249 static uint8_t
250 AsInt (std::string v)
251 {
253  std::istringstream iss;
254  iss.str (v);
255  uint32_t retval;
256  iss >> std::hex >> retval >> std::dec;
257  return retval;
258 }
259 
260 std::istream& operator>> (std::istream& is, Address & address)
261 {
262  std::string v;
263  is >> v;
264  std::string::size_type firstDash, secondDash;
265  firstDash = v.find ("-");
266  secondDash = v.find ("-", firstDash+1);
267  std::string type = v.substr (0, firstDash-0);
268  std::string len = v.substr (firstDash+1, secondDash-(firstDash+1));
269 
270  address.m_type = AsInt (type);
271  address.m_len = AsInt (len);
272  NS_ASSERT (address.m_len <= Address::MAX_SIZE);
273 
274  std::string::size_type col = secondDash + 1;
275  for (uint8_t i = 0; i < address.m_len; ++i)
276  {
277  std::string tmp;
278  std::string::size_type next;
279  next = v.find (":", col);
280  if (next == std::string::npos)
281  {
282  tmp = v.substr (col, v.size ()-col);
283  address.m_data[i] = AsInt (tmp);
284  break;
285  }
286  else
287  {
288  tmp = v.substr (col, next-col);
289  address.m_data[i] = AsInt (tmp);
290  col = next + 1;
291  }
292  }
293  return is;
294 }
295 
296 
297 
298 } // namespace ns3