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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8#include "mac48-address.h"
9
10#include "ns3/address.h"
11#include "ns3/assert.h"
12#include "ns3/log.h"
13#include "ns3/simulator.h"
14
15#include <cstring>
16#include <iomanip>
17#include <iostream>
18
19namespace ns3
20{
21
22NS_LOG_COMPONENT_DEFINE("Mac48Address");
23
25
27
29{
30 NS_LOG_FUNCTION(this << str);
31 NS_ASSERT_MSG(strlen(str) <= 17, "Mac48Address: illegal string (too long) " << str);
32
33 unsigned int bytes[6];
34 int charsRead = 0;
35
36 int i = sscanf(str,
37 "%02x:%02x:%02x:%02x:%02x:%02x%n",
38 bytes,
39 bytes + 1,
40 bytes + 2,
41 bytes + 3,
42 bytes + 4,
43 bytes + 5,
44 &charsRead);
45 NS_ASSERT_MSG(i == 6 && !str[charsRead], "Mac48Address: illegal string " << str);
46
47 std::copy(std::begin(bytes), std::end(bytes), std::begin(m_address));
48}
49
50void
51Mac48Address::CopyFrom(const uint8_t buffer[6])
52{
53 NS_LOG_FUNCTION(this << &buffer);
54 std::memcpy(m_address, buffer, 6);
55}
56
57void
58Mac48Address::CopyTo(uint8_t buffer[6]) const
59{
60 NS_LOG_FUNCTION(this << &buffer);
61 std::memcpy(buffer, m_address, 6);
62}
63
64bool
66{
67 NS_LOG_FUNCTION(&address);
68 return address.CheckCompatible(GetType(), 6);
69}
70
71Mac48Address::operator Address() const
72{
73 return ConvertTo();
74}
75
78{
79 NS_LOG_FUNCTION(this);
80 return Address(GetType(), m_address, 6);
81}
82
85{
86 NS_LOG_FUNCTION(&address);
87 NS_ASSERT(address.CheckCompatible(GetType(), 6));
88 Mac48Address retval;
89 address.CopyTo(retval.m_address);
90 return retval;
91}
92
95{
97
98 if (m_allocationIndex == 0)
99 {
101 }
102
104 Mac48Address address;
105 address.m_address[0] = (m_allocationIndex >> 40) & 0xff;
106 address.m_address[1] = (m_allocationIndex >> 32) & 0xff;
107 address.m_address[2] = (m_allocationIndex >> 24) & 0xff;
108 address.m_address[3] = (m_allocationIndex >> 16) & 0xff;
109 address.m_address[4] = (m_allocationIndex >> 8) & 0xff;
110 address.m_address[5] = m_allocationIndex & 0xff;
111 return address;
112}
113
114void
120
121uint8_t
123{
125 static uint8_t type = Address::Register();
126 return type;
127}
128
129bool
131{
132 NS_LOG_FUNCTION(this);
133 return *this == GetBroadcast();
134}
135
136bool
138{
139 NS_LOG_FUNCTION(this);
140 return (m_address[0] & 0x01) == 0x01;
141}
142
145{
147 static Mac48Address broadcast("ff:ff:ff:ff:ff:ff");
148 return broadcast;
149}
150
153{
155 static Mac48Address multicast("01:00:5e:00:00:00");
156 return multicast;
157}
158
161{
163 static Mac48Address multicast("33:33:00:00:00:00");
164 return multicast;
165}
166
169{
170 NS_LOG_FUNCTION(multicastGroup);
172 //
173 // We now have the multicast address in an abstract 48-bit container. We
174 // need to pull it out so we can play with it. When we're done, we have the
175 // high order bits in etherBuffer[0], etc.
176 //
177 uint8_t etherBuffer[6];
178 etherAddr.CopyTo(etherBuffer);
179
180 //
181 // Now we need to pull the raw bits out of the Ipv4 destination address.
182 //
183 uint8_t ipBuffer[4];
184 multicastGroup.Serialize(ipBuffer);
185
186 //
187 // RFC 1112 says that an Ipv4 host group address is mapped to an EUI-48
188 // multicast address by placing the low-order 23-bits of the IP address into
189 // the low-order 23 bits of the Ethernet multicast address
190 // 01-00-5E-00-00-00 (hex).
191 //
192 etherBuffer[3] |= ipBuffer[1] & 0x7f;
193 etherBuffer[4] = ipBuffer[2];
194 etherBuffer[5] = ipBuffer[3];
195
196 //
197 // Now, etherBuffer has the desired ethernet multicast address. We have to
198 // suck these bits back into the Mac48Address,
199 //
200 Mac48Address result;
201 result.CopyFrom(etherBuffer);
202 return result;
203}
204
207{
208 NS_LOG_FUNCTION(addr);
210 uint8_t etherBuffer[6];
211 uint8_t ipBuffer[16];
212
213 /* a MAC multicast IPv6 address is like 33:33 and the four low bytes */
214 /* for 2001:db8::2fff:fe11:ac10 => 33:33:FE:11:AC:10 */
215 etherAddr.CopyTo(etherBuffer);
216 addr.Serialize(ipBuffer);
217
218 etherBuffer[2] = ipBuffer[12];
219 etherBuffer[3] = ipBuffer[13];
220 etherBuffer[4] = ipBuffer[14];
221 etherBuffer[5] = ipBuffer[15];
222
223 etherAddr.CopyFrom(etherBuffer);
224
225 return etherAddr;
226}
227
228std::ostream&
229operator<<(std::ostream& os, const Mac48Address& address)
230{
231 uint8_t ad[6];
232 address.CopyTo(ad);
233
234 os.setf(std::ios::hex, std::ios::basefield);
235 os.fill('0');
236 for (uint8_t i = 0; i < 5; i++)
237 {
238 os << std::setw(2) << (uint32_t)ad[i] << ":";
239 }
240 // Final byte not suffixed by ":"
241 os << std::setw(2) << (uint32_t)ad[5];
242 os.setf(std::ios::dec, std::ios::basefield);
243 os.fill(' ');
244 return os;
245}
246
247std::istream&
248operator>>(std::istream& is, Mac48Address& address)
249{
250 std::string v;
251 is >> v;
252
253 std::string::size_type col = 0;
254 for (uint8_t i = 0; i < 6; ++i)
255 {
256 std::string tmp;
257 std::string::size_type next;
258 next = v.find(':', col);
259 if (next == std::string::npos)
260 {
261 tmp = v.substr(col, v.size() - col);
262 address.m_address[i] = std::stoul(tmp, nullptr, 16);
263 break;
264 }
265 else
266 {
267 tmp = v.substr(col, next - col);
268 address.m_address[i] = std::stoul(tmp, nullptr, 16);
269 col = next + 1;
270 }
271 }
272 return is;
273}
274
275} // namespace ns3
a polymophic address class
Definition address.h:90
static uint8_t Register()
Allocate a new type id for a new type of address.
Definition address.cc:135
Ipv4 addresses are stored in host order in this class.
void Serialize(uint8_t buf[4]) const
Serialize this address to a 4-byte buffer.
Describes an IPv6 address.
void Serialize(uint8_t buf[16]) const
Serialize this address to a 16-byte buffer.
an EUI-48 address
static Mac48Address GetMulticast(Ipv4Address address)
static void ResetAllocationIndex()
Reset the Mac48Address allocation index.
Mac48Address()=default
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:611
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
#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:191
#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:148
std::istream & operator>>(std::istream &is, Angles &a)
Definition angles.cc:172