A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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
30namespace ns3
31{
32
33NS_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
49static char
51{
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
107void
108Mac48Address::CopyFrom(const uint8_t buffer[6])
109{
110 NS_LOG_FUNCTION(this << &buffer);
111 std::memcpy(m_address, buffer, 6);
112}
113
114void
115Mac48Address::CopyTo(uint8_t buffer[6]) const
116{
117 NS_LOG_FUNCTION(this << &buffer);
118 std::memcpy(buffer, m_address, 6);
119}
120
121bool
123{
124 NS_LOG_FUNCTION(&address);
125 return address.CheckCompatible(GetType(), 6);
126}
127
128Mac48Address::operator Address() const
129{
130 return ConvertTo();
131}
132
135{
136 NS_LOG_FUNCTION(this);
137 return Address(GetType(), m_address, 6);
138}
139
142{
143 NS_LOG_FUNCTION(&address);
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
161 Mac48Address address;
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
171void
173{
176}
177
178uint8_t
180{
182 static uint8_t type = Address::Register();
183 return type;
184}
185
186bool
188{
189 NS_LOG_FUNCTION(this);
190 return *this == GetBroadcast();
191}
192
193bool
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
285std::ostream&
286operator<<(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
304std::istream&
305operator>>(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:42
void Serialize(uint8_t buf[4]) const
Serialize this address to a 4-byte buffer.
Describes an IPv6 address.
Definition: ipv6-address.h:49
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 ATTRIBUTE_HELPER_CPP(type)
Define the attribute value, accessor and checkers for class type
#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 ",...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:129
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:153
static char AsciiToLowCase(char c)
Converts a char to lower case.
#define ASCII_Z
#define ASCII_A
#define ASCII_z
#define ASCII_COLON
#define ASCII_ZERO
#define ASCII_a