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::
72operator Address() const
73{
74 return ConvertTo();
75}
76
79{
80 NS_LOG_FUNCTION(this);
81 return Address(GetType(), m_address, 6);
82}
83
86{
87 NS_LOG_FUNCTION(&address);
88 NS_ASSERT(address.CheckCompatible(GetType(), 6));
89 Mac48Address retval;
90 address.CopyTo(retval.m_address);
91 return retval;
92}
93
96{
98
99 if (m_allocationIndex == 0)
100 {
102 }
103
105 Mac48Address address;
106 address.m_address[0] = (m_allocationIndex >> 40) & 0xff;
107 address.m_address[1] = (m_allocationIndex >> 32) & 0xff;
108 address.m_address[2] = (m_allocationIndex >> 24) & 0xff;
109 address.m_address[3] = (m_allocationIndex >> 16) & 0xff;
110 address.m_address[4] = (m_allocationIndex >> 8) & 0xff;
111 address.m_address[5] = m_allocationIndex & 0xff;
112 return address;
113}
114
115void
121
122uint8_t
124{
126 static uint8_t type = Address::Register();
127 return type;
128}
129
130bool
132{
133 NS_LOG_FUNCTION(this);
134 return *this == GetBroadcast();
135}
136
137bool
139{
140 NS_LOG_FUNCTION(this);
141 return (m_address[0] & 0x01) == 0x01;
142}
143
146{
148 static Mac48Address broadcast("ff:ff:ff:ff:ff:ff");
149 return broadcast;
150}
151
154{
156 static Mac48Address multicast("01:00:5e:00:00:00");
157 return multicast;
158}
159
162{
164 static Mac48Address multicast("33:33:00:00:00:00");
165 return multicast;
166}
167
170{
171 NS_LOG_FUNCTION(multicastGroup);
173 //
174 // We now have the multicast address in an abstract 48-bit container. We
175 // need to pull it out so we can play with it. When we're done, we have the
176 // high order bits in etherBuffer[0], etc.
177 //
178 uint8_t etherBuffer[6];
179 etherAddr.CopyTo(etherBuffer);
180
181 //
182 // Now we need to pull the raw bits out of the Ipv4 destination address.
183 //
184 uint8_t ipBuffer[4];
185 multicastGroup.Serialize(ipBuffer);
186
187 //
188 // RFC 1112 says that an Ipv4 host group address is mapped to an EUI-48
189 // multicast address by placing the low-order 23-bits of the IP address into
190 // the low-order 23 bits of the Ethernet multicast address
191 // 01-00-5E-00-00-00 (hex).
192 //
193 etherBuffer[3] |= ipBuffer[1] & 0x7f;
194 etherBuffer[4] = ipBuffer[2];
195 etherBuffer[5] = ipBuffer[3];
196
197 //
198 // Now, etherBuffer has the desired ethernet multicast address. We have to
199 // suck these bits back into the Mac48Address,
200 //
201 Mac48Address result;
202 result.CopyFrom(etherBuffer);
203 return result;
204}
205
208{
209 NS_LOG_FUNCTION(addr);
211 uint8_t etherBuffer[6];
212 uint8_t ipBuffer[16];
213
214 /* a MAC multicast IPv6 address is like 33:33 and the four low bytes */
215 /* for 2001:db8::2fff:fe11:ac10 => 33:33:FE:11:AC:10 */
216 etherAddr.CopyTo(etherBuffer);
217 addr.Serialize(ipBuffer);
218
219 etherBuffer[2] = ipBuffer[12];
220 etherBuffer[3] = ipBuffer[13];
221 etherBuffer[4] = ipBuffer[14];
222 etherBuffer[5] = ipBuffer[15];
223
224 etherAddr.CopyFrom(etherBuffer);
225
226 return etherAddr;
227}
228
229std::ostream&
230operator<<(std::ostream& os, const Mac48Address& address)
231{
232 uint8_t ad[6];
233 address.CopyTo(ad);
234
235 os.setf(std::ios::hex, std::ios::basefield);
236 os.fill('0');
237 for (uint8_t i = 0; i < 5; i++)
238 {
239 os << std::setw(2) << (uint32_t)ad[i] << ":";
240 }
241 // Final byte not suffixed by ":"
242 os << std::setw(2) << (uint32_t)ad[5];
243 os.setf(std::ios::dec, std::ios::basefield);
244 os.fill(' ');
245 return os;
246}
247
248std::istream&
249operator>>(std::istream& is, Mac48Address& address)
250{
251 std::string v;
252 is >> v;
253
254 std::string::size_type col = 0;
255 for (uint8_t i = 0; i < 6; ++i)
256 {
257 std::string tmp;
258 std::string::size_type next;
259 next = v.find(':', col);
260 if (next == std::string::npos)
261 {
262 tmp = v.substr(col, v.size() - col);
263 address.m_address[i] = std::stoul(tmp, nullptr, 16);
264 break;
265 }
266 else
267 {
268 tmp = v.substr(col, next - col);
269 address.m_address[i] = std::stoul(tmp, nullptr, 16);
270 col = next + 1;
271 }
272 }
273 return is;
274}
275
276} // 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:612
#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