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 "address.h"
23 #include <string.h>
24 #include <iostream>
25 #include <iomanip>
26 
27 namespace ns3 {
28 
30  : m_type (0),
31  m_len (0)
32 {
33  // Buffer left uninitialized
34 }
35 
36 Address::Address (uint8_t type, const uint8_t *buffer, uint8_t len)
37  : m_type (type),
38  m_len (len)
39 {
41  memcpy (m_data, buffer, m_len);
42 }
43 Address::Address (const Address & address)
44  : m_type (address.m_type),
45  m_len (address.m_len)
46 {
48  memcpy (m_data, address.m_data, m_len);
49 }
50 Address &
52 {
54  m_type = address.m_type;
55  m_len = address.m_len;
57  memcpy (m_data, address.m_data, m_len);
58  return *this;
59 }
60 
61 bool
62 Address::IsInvalid (void) const
63 {
64  return m_len == 0 && m_type == 0;
65 }
66 
67 uint8_t
68 Address::GetLength (void) const
69 {
71  return m_len;
72 }
73 uint32_t
74 Address::CopyTo (uint8_t buffer[MAX_SIZE]) const
75 {
76  NS_ASSERT (m_len <= MAX_SIZE);
77  memcpy (buffer, m_data, m_len);
78  return m_len;
79 }
80 uint32_t
81 Address::CopyAllTo (uint8_t *buffer, uint8_t len) const
82 {
83  NS_ASSERT (len >= m_len + 2);
84  buffer[0] = m_type;
85  buffer[1] = m_len;
86  memcpy (buffer + 2, m_data, m_len);
87  return m_len + 2;
88 }
89 
90 uint32_t
91 Address::CopyFrom (const uint8_t *buffer, uint8_t len)
92 {
93  NS_ASSERT (len <= MAX_SIZE);
94  memcpy (m_data, buffer, len);
95  m_len = len;
96  return m_len;
97 }
98 uint32_t
99 Address::CopyAllFrom (const uint8_t *buffer, uint8_t len)
100 {
101  NS_ASSERT (len >= 2);
102  m_type = buffer[0];
103  m_len = buffer[1];
104 
105  NS_ASSERT (len >= m_len + 2);
106  memcpy (m_data, buffer + 2, m_len);
107  return m_len + 2;
108 }
109 bool
110 Address::CheckCompatible (uint8_t type, uint8_t len) const
111 {
112  NS_ASSERT (len <= MAX_SIZE);
113  return m_len == len && (m_type == type || m_type == 0);
114 }
115 bool
116 Address::IsMatchingType (uint8_t type) const
117 {
118  return m_type == type;
119 }
120 
121 uint8_t
123 {
124  static uint8_t type = 1;
125  type++;
126  return type;
127 }
128 
129 uint32_t
131 {
132  return 1 + 1 + m_len;
133 }
134 
135 void
137 {
138  buffer.WriteU8 (m_type);
139  buffer.WriteU8 (m_len);
140  buffer.Write (m_data, m_len);
141 }
142 
143 void
145 {
146  m_type = buffer.ReadU8 ();
147  m_len = buffer.ReadU8 ();
148  NS_ASSERT (m_len <= MAX_SIZE);
149  buffer.Read (m_data, m_len);
150 }
151 
153 
154 
155 bool operator == (const Address &a, const Address &b)
156 {
157  /* Two addresses can be equal even if their types are
158  * different if one of the two types is zero. a type of
159  * zero identifies an Address which might contain meaningful
160  * payload but for which the type field could not be set because
161  * we did not know it. This can typically happen in the ARP
162  * layer where we receive an address from an ArpHeader but
163  * we do not know its type: we really want to be able to
164  * compare addresses without knowing their real type.
165  */
166  if (a.m_type != b.m_type &&
167  a.m_type != 0 &&
168  b.m_type != 0)
169  {
170  return false;
171  }
172  if (a.m_len != b.m_len)
173  {
174  return false;
175  }
176  return memcmp (a.m_data, b.m_data, a.m_len) == 0;
177 }
178 bool operator != (const Address &a, const Address &b)
179 {
180  return !(a == b);
181 }
182 bool operator < (const Address &a, const Address &b)
183 {
184  if (a.m_type < b.m_type)
185  {
186  return true;
187  }
188  else if (a.m_type > b.m_type)
189  {
190  return false;
191  }
192  if (a.m_len < b.m_len)
193  {
194  return true;
195  }
196  else if (a.m_len > b.m_len)
197  {
198  return false;
199  }
200  NS_ASSERT (a.GetLength () == b.GetLength ());
201  for (uint8_t i = 0; i < a.GetLength (); i++)
202  {
203  if (a.m_data[i] < b.m_data[i])
204  {
205  return true;
206  }
207  else if (a.m_data[i] > b.m_data[i])
208  {
209  return false;
210  }
211  }
212  return false;
213 }
214 
215 std::ostream& operator<< (std::ostream& os, const Address & address)
216 {
217  os.setf (std::ios::hex, std::ios::basefield);
218  os.fill ('0');
219  os << std::setw (2) << (uint32_t) address.m_type << "-" << std::setw (2) << (uint32_t) address.m_len << "-";
220  for (uint8_t i = 0; i < (address.m_len-1); ++i)
221  {
222  os << std::setw (2) << (uint32_t)address.m_data[i] << ":";
223  }
224  // Final byte not suffixed by ":"
225  os << std::setw (2) << (uint32_t) address.m_data[address.m_len-1];
226  os.setf (std::ios::dec, std::ios::basefield);
227  os.fill (' ');
228  return os;
229 }
230 
231 static uint8_t
232 AsInt (std::string v)
233 {
234  std::istringstream iss;
235  iss.str (v);
236  uint32_t retval;
237  iss >> std::hex >> retval >> std::dec;
238  return retval;
239 }
240 
241 std::istream& operator>> (std::istream& is, Address & address)
242 {
243  std::string v;
244  is >> v;
245  std::string::size_type firstDash, secondDash;
246  firstDash = v.find ("-");
247  secondDash = v.find ("-", firstDash+1);
248  std::string type = v.substr (0, firstDash-0);
249  std::string len = v.substr (firstDash+1, secondDash-(firstDash+1));
250 
251  address.m_type = AsInt (type);
252  address.m_len = AsInt (len);
253  NS_ASSERT (address.m_len <= Address::MAX_SIZE);
254 
255  std::string::size_type col = secondDash + 1;
256  for (uint8_t i = 0; i < address.m_len; ++i)
257  {
258  std::string tmp;
259  std::string::size_type next;
260  next = v.find (":", col);
261  if (next == std::string::npos)
262  {
263  tmp = v.substr (col, v.size ()-col);
264  address.m_data[i] = AsInt (tmp);
265  break;
266  }
267  else
268  {
269  tmp = v.substr (col, next-col);
270  address.m_data[i] = AsInt (tmp);
271  col = next + 1;
272  }
273  }
274  return is;
275 }
276 
277 
278 
279 } // namespace ns3