A Discrete-Event Network Simulator
API
mac48-address.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 #include "mac48-address.h"
21 #include "ns3/address.h"
22 #include "ns3/assert.h"
23 #include "ns3/log.h"
24 #include <iomanip>
25 #include <iostream>
26 #include <cstring>
27 
28 namespace ns3 {
29 
30 NS_LOG_COMPONENT_DEFINE ("Mac48Address");
31 
33 
34 #define ASCII_a (0x41)
35 #define ASCII_z (0x5a)
36 #define ASCII_A (0x61)
37 #define ASCII_Z (0x7a)
38 #define ASCII_COLON (0x3a)
39 #define ASCII_ZERO (0x30)
40 
46 static char
48 {
49  NS_LOG_FUNCTION (c);
50  if (c >= ASCII_a && c <= ASCII_z) {
51  return c;
52  } else if (c >= ASCII_A && c <= ASCII_Z) {
53  return c + (ASCII_a - ASCII_A);
54  } else {
55  return c;
56  }
57 }
58 
59 
61 {
62  NS_LOG_FUNCTION (this);
63  std::memset (m_address, 0, 6);
64 }
65 Mac48Address::Mac48Address (const char *str)
66 {
67  NS_LOG_FUNCTION (this << str);
68  int i = 0;
69  while (*str != 0 && i < 6)
70  {
71  uint8_t byte = 0;
72  while (*str != ASCII_COLON && *str != 0)
73  {
74  byte <<= 4;
75  char low = AsciiToLowCase (*str);
76  if (low >= ASCII_a)
77  {
78  byte |= low - ASCII_a + 10;
79  }
80  else
81  {
82  byte |= low - ASCII_ZERO;
83  }
84  str++;
85  }
86  m_address[i] = byte;
87  i++;
88  if (*str == 0)
89  {
90  break;
91  }
92  str++;
93  }
94  NS_ASSERT (i == 6);
95 }
96 void
97 Mac48Address::CopyFrom (const uint8_t buffer[6])
98 {
99  NS_LOG_FUNCTION (this << &buffer);
100  std::memcpy (m_address, buffer, 6);
101 }
102 void
103 Mac48Address::CopyTo (uint8_t buffer[6]) const
104 {
105  NS_LOG_FUNCTION (this << &buffer);
106  std::memcpy (buffer, m_address, 6);
107 }
108 
109 bool
111 {
113  return address.CheckCompatible (GetType (), 6);
114 }
115 Mac48Address::operator Address () const
116 {
117  return ConvertTo ();
118 }
119 Address
121 {
122  NS_LOG_FUNCTION (this);
123  return Address (GetType (), m_address, 6);
124 }
127 {
129  NS_ASSERT (address.CheckCompatible (GetType (), 6));
130  Mac48Address retval;
131  address.CopyTo (retval.m_address);
132  return retval;
133 }
136 {
138  static uint64_t id = 0;
139  id++;
141  address.m_address[0] = (id >> 40) & 0xff;
142  address.m_address[1] = (id >> 32) & 0xff;
143  address.m_address[2] = (id >> 24) & 0xff;
144  address.m_address[3] = (id >> 16) & 0xff;
145  address.m_address[4] = (id >> 8) & 0xff;
146  address.m_address[5] = (id >> 0) & 0xff;
147  return address;
148 }
149 uint8_t
151 {
153  static uint8_t type = Address::Register ();
154  return type;
155 }
156 
157 bool
159 {
160  NS_LOG_FUNCTION (this);
161  return *this == GetBroadcast ();
162 }
163 bool
165 {
166  NS_LOG_FUNCTION (this);
167  return (m_address[0] & 0x01) == 0x01;
168 }
171 {
173  static Mac48Address broadcast = Mac48Address ("ff:ff:ff:ff:ff:ff");
174  return broadcast;
175 }
178 {
180  static Mac48Address multicast = Mac48Address ("01:00:5e:00:00:00");
181  return multicast;
182 }
185 {
187  static Mac48Address multicast = Mac48Address ("33:33:00:00:00:00");
188  return multicast;
189 }
192 {
193  NS_LOG_FUNCTION (multicastGroup);
195  //
196  // We now have the multicast address in an abstract 48-bit container. We
197  // need to pull it out so we can play with it. When we're done, we have the
198  // high order bits in etherBuffer[0], etc.
199  //
200  uint8_t etherBuffer[6];
201  etherAddr.CopyTo (etherBuffer);
202 
203  //
204  // Now we need to pull the raw bits out of the Ipv4 destination address.
205  //
206  uint8_t ipBuffer[4];
207  multicastGroup.Serialize (ipBuffer);
208 
209  //
210  // RFC 1112 says that an Ipv4 host group address is mapped to an EUI-48
211  // multicast address by placing the low-order 23-bits of the IP address into
212  // the low-order 23 bits of the Ethernet multicast address
213  // 01-00-5E-00-00-00 (hex).
214  //
215  etherBuffer[3] |= ipBuffer[1] & 0x7f;
216  etherBuffer[4] = ipBuffer[2];
217  etherBuffer[5] = ipBuffer[3];
218 
219  //
220  // Now, etherBuffer has the desired ethernet multicast address. We have to
221  // suck these bits back into the Mac48Address,
222  //
224  result.CopyFrom (etherBuffer);
225  return result;
226 }
228 {
229  NS_LOG_FUNCTION (addr);
231  uint8_t etherBuffer[6];
232  uint8_t ipBuffer[16];
233 
234  /* a MAC multicast IPv6 address is like 33:33 and the four low bytes */
235  /* for 2001:db8::2fff:fe11:ac10 => 33:33:FE:11:AC:10 */
236  etherAddr.CopyTo (etherBuffer);
237  addr.Serialize (ipBuffer);
238 
239  etherBuffer[2] = ipBuffer[12];
240  etherBuffer[3] = ipBuffer[13];
241  etherBuffer[4] = ipBuffer[14];
242  etherBuffer[5] = ipBuffer[15];
243 
244  etherAddr.CopyFrom (etherBuffer);
245 
246  return etherAddr;
247 }
248 
249 std::ostream& operator<< (std::ostream& os, const Mac48Address & address)
250 {
251  uint8_t ad[6];
252  address.CopyTo (ad);
253 
254  os.setf (std::ios::hex, std::ios::basefield);
255  os.fill ('0');
256  for (uint8_t i=0; i < 5; i++)
257  {
258  os << std::setw (2) << (uint32_t)ad[i] << ":";
259  }
260  // Final byte not suffixed by ":"
261  os << std::setw (2) << (uint32_t)ad[5];
262  os.setf (std::ios::dec, std::ios::basefield);
263  os.fill (' ');
264  return os;
265 }
266 
267 std::istream& operator>> (std::istream& is, Mac48Address & address)
268 {
269  std::string v;
270  is >> v;
271 
272  std::string::size_type col = 0;
273  for (uint8_t i = 0; i < 6; ++i)
274  {
275  std::string tmp;
276  std::string::size_type next;
277  next = v.find (":", col);
278  if (next == std::string::npos)
279  {
280  tmp = v.substr (col, v.size ()-col);
281  address.m_address[i] = strtoul (tmp.c_str(), 0, 16);
282  break;
283  }
284  else
285  {
286  tmp = v.substr (col, next-col);
287  address.m_address[i] = strtoul (tmp.c_str(), 0, 16);
288  col = next + 1;
289  }
290  }
291  return is;
292 }
293 
294 
295 } // namespace ns3
a polymophic address class
Definition: address.h:91
static uint8_t Register(void)
Allocate a new type id for a new type of address.
Definition: address.cc:138
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
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:44
static Mac48Address Allocate(void)
Allocate a new Mac48Address.
static Mac48Address GetMulticast(Ipv4Address address)
static Mac48Address GetBroadcast(void)
static bool IsMatchingType(const Address &address)
bool IsGroup(void) const
static uint8_t GetType(void)
Return the Type of address.
void CopyFrom(const uint8_t buffer[6])
static Mac48Address GetMulticast6Prefix(void)
Get the multicast prefix for IPv6 (33:33:00:00:00:00).
Address ConvertTo(void) const
bool IsBroadcast(void) const
static Mac48Address ConvertFrom(const Address &address)
static Mac48Address GetMulticastPrefix(void)
uint8_t m_address[6]
address value
void CopyTo(uint8_t buffer[6]) const
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#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:44
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:162
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:139
static char AsciiToLowCase(char c)
Converts a char to lower case.
unsigned char byte
Definition: qkd-encryptor.h:64