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 
38 
40 {
41  NS_LOG_FUNCTION(this << str);
42  NS_ASSERT_MSG(strlen(str) <= 17, "Mac48Address: illegal string (too long) " << str);
43 
44  unsigned int bytes[6];
45  int charsRead = 0;
46 
47  int i = sscanf(str,
48  "%02x:%02x:%02x:%02x:%02x:%02x%n",
49  bytes,
50  bytes + 1,
51  bytes + 2,
52  bytes + 3,
53  bytes + 4,
54  bytes + 5,
55  &charsRead);
56  NS_ASSERT_MSG(i == 6 && !str[charsRead], "Mac48Address: illegal string " << str);
57 
58  std::copy(std::begin(bytes), std::end(bytes), std::begin(m_address));
59 }
60 
61 void
62 Mac48Address::CopyFrom(const uint8_t buffer[6])
63 {
64  NS_LOG_FUNCTION(this << &buffer);
65  std::memcpy(m_address, buffer, 6);
66 }
67 
68 void
69 Mac48Address::CopyTo(uint8_t buffer[6]) const
70 {
71  NS_LOG_FUNCTION(this << &buffer);
72  std::memcpy(buffer, m_address, 6);
73 }
74 
75 bool
77 {
79  return address.CheckCompatible(GetType(), 6);
80 }
81 
82 Mac48Address::operator Address() const
83 {
84  return ConvertTo();
85 }
86 
87 Address
89 {
90  NS_LOG_FUNCTION(this);
91  return Address(GetType(), m_address, 6);
92 }
93 
96 {
98  NS_ASSERT(address.CheckCompatible(GetType(), 6));
99  Mac48Address retval;
100  address.CopyTo(retval.m_address);
101  return retval;
102 }
103 
106 {
108 
109  if (m_allocationIndex == 0)
110  {
112  }
113 
116  address.m_address[0] = (m_allocationIndex >> 40) & 0xff;
117  address.m_address[1] = (m_allocationIndex >> 32) & 0xff;
118  address.m_address[2] = (m_allocationIndex >> 24) & 0xff;
119  address.m_address[3] = (m_allocationIndex >> 16) & 0xff;
120  address.m_address[4] = (m_allocationIndex >> 8) & 0xff;
121  address.m_address[5] = m_allocationIndex & 0xff;
122  return address;
123 }
124 
125 void
127 {
129  m_allocationIndex = 0;
130 }
131 
132 uint8_t
134 {
136  static uint8_t type = Address::Register();
137  return type;
138 }
139 
140 bool
142 {
143  NS_LOG_FUNCTION(this);
144  return *this == GetBroadcast();
145 }
146 
147 bool
149 {
150  NS_LOG_FUNCTION(this);
151  return (m_address[0] & 0x01) == 0x01;
152 }
153 
156 {
158  static Mac48Address broadcast("ff:ff:ff:ff:ff:ff");
159  return broadcast;
160 }
161 
164 {
166  static Mac48Address multicast("01:00:5e:00:00:00");
167  return multicast;
168 }
169 
172 {
174  static Mac48Address multicast("33:33:00:00:00:00");
175  return multicast;
176 }
177 
180 {
181  NS_LOG_FUNCTION(multicastGroup);
183  //
184  // We now have the multicast address in an abstract 48-bit container. We
185  // need to pull it out so we can play with it. When we're done, we have the
186  // high order bits in etherBuffer[0], etc.
187  //
188  uint8_t etherBuffer[6];
189  etherAddr.CopyTo(etherBuffer);
190 
191  //
192  // Now we need to pull the raw bits out of the Ipv4 destination address.
193  //
194  uint8_t ipBuffer[4];
195  multicastGroup.Serialize(ipBuffer);
196 
197  //
198  // RFC 1112 says that an Ipv4 host group address is mapped to an EUI-48
199  // multicast address by placing the low-order 23-bits of the IP address into
200  // the low-order 23 bits of the Ethernet multicast address
201  // 01-00-5E-00-00-00 (hex).
202  //
203  etherBuffer[3] |= ipBuffer[1] & 0x7f;
204  etherBuffer[4] = ipBuffer[2];
205  etherBuffer[5] = ipBuffer[3];
206 
207  //
208  // Now, etherBuffer has the desired ethernet multicast address. We have to
209  // suck these bits back into the Mac48Address,
210  //
211  Mac48Address result;
212  result.CopyFrom(etherBuffer);
213  return result;
214 }
215 
218 {
219  NS_LOG_FUNCTION(addr);
221  uint8_t etherBuffer[6];
222  uint8_t ipBuffer[16];
223 
224  /* a MAC multicast IPv6 address is like 33:33 and the four low bytes */
225  /* for 2001:db8::2fff:fe11:ac10 => 33:33:FE:11:AC:10 */
226  etherAddr.CopyTo(etherBuffer);
227  addr.Serialize(ipBuffer);
228 
229  etherBuffer[2] = ipBuffer[12];
230  etherBuffer[3] = ipBuffer[13];
231  etherBuffer[4] = ipBuffer[14];
232  etherBuffer[5] = ipBuffer[15];
233 
234  etherAddr.CopyFrom(etherBuffer);
235 
236  return etherAddr;
237 }
238 
239 std::ostream&
240 operator<<(std::ostream& os, const Mac48Address& address)
241 {
242  uint8_t ad[6];
243  address.CopyTo(ad);
244 
245  os.setf(std::ios::hex, std::ios::basefield);
246  os.fill('0');
247  for (uint8_t i = 0; i < 5; i++)
248  {
249  os << std::setw(2) << (uint32_t)ad[i] << ":";
250  }
251  // Final byte not suffixed by ":"
252  os << std::setw(2) << (uint32_t)ad[5];
253  os.setf(std::ios::dec, std::ios::basefield);
254  os.fill(' ');
255  return os;
256 }
257 
258 std::istream&
259 operator>>(std::istream& is, Mac48Address& address)
260 {
261  std::string v;
262  is >> v;
263 
264  std::string::size_type col = 0;
265  for (uint8_t i = 0; i < 6; ++i)
266  {
267  std::string tmp;
268  std::string::size_type next;
269  next = v.find(':', col);
270  if (next == std::string::npos)
271  {
272  tmp = v.substr(col, v.size() - col);
273  address.m_address[i] = std::stoul(tmp, nullptr, 16);
274  break;
275  }
276  else
277  {
278  tmp = v.substr(col, next - col);
279  address.m_address[i] = std::stoul(tmp, nullptr, 16);
280  col = next + 1;
281  }
282  }
283  return is;
284 }
285 
286 } // namespace ns3
a polymophic address class
Definition: address.h:101
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.
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:622
#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_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:86
#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 ",...
address
Definition: first.py:47
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ATTRIBUTE_HELPER_CPP(ValueClassTest)
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:183
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:159