A Discrete-Event Network Simulator
API
mac48-address.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007 INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18  */
19 #include "mac48-address.h"
20 
21 #include "ns3/address.h"
22 #include "ns3/assert.h"
23 #include "ns3/log.h"
24 #include "ns3/simulator.h"
25 
26 #include <cstring>
27 #include <iomanip>
28 #include <iostream>
29 
30 namespace ns3
31 {
32 
33 NS_LOG_COMPONENT_DEFINE("Mac48Address");
34 
36 
37 #define ASCII_a (0x41)
38 #define ASCII_z (0x5a)
39 #define ASCII_A (0x61)
40 #define ASCII_Z (0x7a)
41 #define ASCII_COLON (0x3a)
42 #define ASCII_ZERO (0x30)
43 
49 static char
51 {
52  NS_LOG_FUNCTION(c);
53  if (c >= ASCII_a && c <= ASCII_z)
54  {
55  return c;
56  }
57  else if (c >= ASCII_A && c <= ASCII_Z)
58  {
59  return c + (ASCII_a - ASCII_A);
60  }
61  else
62  {
63  return c;
64  }
65 }
66 
68 
70 {
71  NS_LOG_FUNCTION(this);
72  std::memset(m_address, 0, 6);
73 }
74 
76 {
77  NS_LOG_FUNCTION(this << str);
78  int i = 0;
79  while (*str != 0 && i < 6)
80  {
81  uint8_t byte = 0;
82  while (*str != ASCII_COLON && *str != 0)
83  {
84  byte <<= 4;
85  char low = AsciiToLowCase(*str);
86  if (low >= ASCII_a)
87  {
88  byte |= low - ASCII_a + 10;
89  }
90  else
91  {
92  byte |= low - ASCII_ZERO;
93  }
94  str++;
95  }
96  m_address[i] = byte;
97  i++;
98  if (*str == 0)
99  {
100  break;
101  }
102  str++;
103  }
104  NS_ASSERT(i == 6);
105 }
106 
107 void
108 Mac48Address::CopyFrom(const uint8_t buffer[6])
109 {
110  NS_LOG_FUNCTION(this << &buffer);
111  std::memcpy(m_address, buffer, 6);
112 }
113 
114 void
115 Mac48Address::CopyTo(uint8_t buffer[6]) const
116 {
117  NS_LOG_FUNCTION(this << &buffer);
118  std::memcpy(buffer, m_address, 6);
119 }
120 
121 bool
123 {
125  return address.CheckCompatible(GetType(), 6);
126 }
127 
128 Mac48Address::operator Address() const
129 {
130  return ConvertTo();
131 }
132 
133 Address
135 {
136  NS_LOG_FUNCTION(this);
137  return Address(GetType(), m_address, 6);
138 }
139 
142 {
144  NS_ASSERT(address.CheckCompatible(GetType(), 6));
145  Mac48Address retval;
146  address.CopyTo(retval.m_address);
147  return retval;
148 }
149 
152 {
154 
155  if (m_allocationIndex == 0)
156  {
158  }
159 
162  address.m_address[0] = (m_allocationIndex >> 40) & 0xff;
163  address.m_address[1] = (m_allocationIndex >> 32) & 0xff;
164  address.m_address[2] = (m_allocationIndex >> 24) & 0xff;
165  address.m_address[3] = (m_allocationIndex >> 16) & 0xff;
166  address.m_address[4] = (m_allocationIndex >> 8) & 0xff;
167  address.m_address[5] = m_allocationIndex & 0xff;
168  return address;
169 }
170 
171 void
173 {
175  m_allocationIndex = 0;
176 }
177 
178 uint8_t
180 {
182  static uint8_t type = Address::Register();
183  return type;
184 }
185 
186 bool
188 {
189  NS_LOG_FUNCTION(this);
190  return *this == GetBroadcast();
191 }
192 
193 bool
195 {
196  NS_LOG_FUNCTION(this);
197  return (m_address[0] & 0x01) == 0x01;
198 }
199 
202 {
204  static Mac48Address broadcast = Mac48Address("ff:ff:ff:ff:ff:ff");
205  return broadcast;
206 }
207 
210 {
212  static Mac48Address multicast = Mac48Address("01:00:5e:00:00:00");
213  return multicast;
214 }
215 
218 {
220  static Mac48Address multicast = Mac48Address("33:33:00:00:00:00");
221  return multicast;
222 }
223 
226 {
227  NS_LOG_FUNCTION(multicastGroup);
229  //
230  // We now have the multicast address in an abstract 48-bit container. We
231  // need to pull it out so we can play with it. When we're done, we have the
232  // high order bits in etherBuffer[0], etc.
233  //
234  uint8_t etherBuffer[6];
235  etherAddr.CopyTo(etherBuffer);
236 
237  //
238  // Now we need to pull the raw bits out of the Ipv4 destination address.
239  //
240  uint8_t ipBuffer[4];
241  multicastGroup.Serialize(ipBuffer);
242 
243  //
244  // RFC 1112 says that an Ipv4 host group address is mapped to an EUI-48
245  // multicast address by placing the low-order 23-bits of the IP address into
246  // the low-order 23 bits of the Ethernet multicast address
247  // 01-00-5E-00-00-00 (hex).
248  //
249  etherBuffer[3] |= ipBuffer[1] & 0x7f;
250  etherBuffer[4] = ipBuffer[2];
251  etherBuffer[5] = ipBuffer[3];
252 
253  //
254  // Now, etherBuffer has the desired ethernet multicast address. We have to
255  // suck these bits back into the Mac48Address,
256  //
257  Mac48Address result;
258  result.CopyFrom(etherBuffer);
259  return result;
260 }
261 
264 {
265  NS_LOG_FUNCTION(addr);
267  uint8_t etherBuffer[6];
268  uint8_t ipBuffer[16];
269 
270  /* a MAC multicast IPv6 address is like 33:33 and the four low bytes */
271  /* for 2001:db8::2fff:fe11:ac10 => 33:33:FE:11:AC:10 */
272  etherAddr.CopyTo(etherBuffer);
273  addr.Serialize(ipBuffer);
274 
275  etherBuffer[2] = ipBuffer[12];
276  etherBuffer[3] = ipBuffer[13];
277  etherBuffer[4] = ipBuffer[14];
278  etherBuffer[5] = ipBuffer[15];
279 
280  etherAddr.CopyFrom(etherBuffer);
281 
282  return etherAddr;
283 }
284 
285 std::ostream&
286 operator<<(std::ostream& os, const Mac48Address& address)
287 {
288  uint8_t ad[6];
289  address.CopyTo(ad);
290 
291  os.setf(std::ios::hex, std::ios::basefield);
292  os.fill('0');
293  for (uint8_t i = 0; i < 5; i++)
294  {
295  os << std::setw(2) << (uint32_t)ad[i] << ":";
296  }
297  // Final byte not suffixed by ":"
298  os << std::setw(2) << (uint32_t)ad[5];
299  os.setf(std::ios::dec, std::ios::basefield);
300  os.fill(' ');
301  return os;
302 }
303 
304 std::istream&
305 operator>>(std::istream& is, Mac48Address& address)
306 {
307  std::string v;
308  is >> v;
309 
310  std::string::size_type col = 0;
311  for (uint8_t i = 0; i < 6; ++i)
312  {
313  std::string tmp;
314  std::string::size_type next;
315  next = v.find(':', col);
316  if (next == std::string::npos)
317  {
318  tmp = v.substr(col, v.size() - col);
319  address.m_address[i] = std::stoul(tmp, nullptr, 16);
320  break;
321  }
322  else
323  {
324  tmp = v.substr(col, next - col);
325  address.m_address[i] = std::stoul(tmp, nullptr, 16);
326  col = next + 1;
327  }
328  }
329  return is;
330 }
331 
332 } // namespace ns3
a polymophic address class
Definition: address.h:100
static uint8_t Register()
Allocate a new type id for a new type of address.
Definition: address.cc:146
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:43
void Serialize(uint8_t buf[4]) const
Serialize this address to a 4-byte buffer.
Describes an IPv6 address.
Definition: ipv6-address.h:50
void Serialize(uint8_t buf[16]) const
Serialize this address to a 16-byte buffer.
an EUI-48 address
Definition: mac48-address.h:46
static Mac48Address GetMulticast(Ipv4Address address)
static void ResetAllocationIndex()
Reset the Mac48Address allocation index.
bool IsGroup() const
static bool IsMatchingType(const Address &address)
void CopyFrom(const uint8_t buffer[6])
static uint8_t GetType()
Return the Type of address.
static Mac48Address ConvertFrom(const Address &address)
uint8_t m_address[6]
address value
static Mac48Address GetBroadcast()
static Mac48Address Allocate()
Allocate a new Mac48Address.
static Mac48Address GetMulticast6Prefix()
Get the multicast prefix for IPv6 (33:33:00:00:00:00).
void CopyTo(uint8_t buffer[6]) const
static Mac48Address GetMulticastPrefix()
static uint64_t m_allocationIndex
Address allocation index.
Address ConvertTo() const
bool IsBroadcast() const
static EventId ScheduleDestroy(FUNC f, Ts &&... args)
Schedule an event to run at the end of the simulation, when Simulator::Destroy() is called.
Definition: simulator.h:625
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#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 ",...
#define ASCII_Z
#define ASCII_A
#define ASCII_z
#define ASCII_COLON
#define ASCII_ZERO
#define ASCII_a
address
Definition: first.py:40
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ATTRIBUTE_HELPER_CPP(Length)
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:153
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:129
static char AsciiToLowCase(char c)
Converts a char to lower case.