A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Groups
Pages
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 <iomanip>
24
#include <iostream>
25
#include <
string.h
>
26
27
namespace
ns3 {
28
29
ATTRIBUTE_HELPER_CPP
(Mac48Address);
30
31
#define ASCII_a (0x41)
32
#define ASCII_z (0x5a)
33
#define ASCII_A (0x61)
34
#define ASCII_Z (0x7a)
35
#define ASCII_COLON (0x3a)
36
#define ASCII_ZERO (0x30)
37
38
static
char
39
AsciiToLowCase
(
char
c)
40
{
41
if
(c >=
ASCII_a
&& c <=
ASCII_z
) {
42
return
c;
43
}
else
if
(c >=
ASCII_A
&& c <=
ASCII_Z
) {
44
return
c + (
ASCII_a
-
ASCII_A
);
45
}
else
{
46
return
c;
47
}
48
}
49
50
51
Mac48Address::Mac48Address
()
52
{
53
memset (
m_address
, 0, 6);
54
}
55
Mac48Address::Mac48Address
(
const
char
*str)
56
{
57
int
i = 0;
58
while
(*str != 0 && i < 6)
59
{
60
uint8_t byte = 0;
61
while
(*str !=
ASCII_COLON
&& *str != 0)
62
{
63
byte <<= 4;
64
char
low =
AsciiToLowCase
(*str);
65
if
(low >=
ASCII_a
)
66
{
67
byte |= low -
ASCII_a
+ 10;
68
}
69
else
70
{
71
byte |= low -
ASCII_ZERO
;
72
}
73
str++;
74
}
75
m_address
[i] = byte;
76
i++;
77
if
(*str == 0)
78
{
79
break
;
80
}
81
str++;
82
}
83
NS_ASSERT
(i == 6);
84
}
85
void
86
Mac48Address::CopyFrom
(
const
uint8_t buffer[6])
87
{
88
memcpy (
m_address
, buffer, 6);
89
}
90
void
91
Mac48Address::CopyTo
(uint8_t buffer[6])
const
92
{
93
memcpy (buffer,
m_address
, 6);
94
}
95
96
bool
97
Mac48Address::IsMatchingType
(
const
Address
&address)
98
{
99
return
address.
CheckCompatible
(
GetType
(), 6);
100
}
101
Mac48Address::operator
Address
()
const
102
{
103
return
ConvertTo ();
104
}
105
Address
106
Mac48Address::ConvertTo
(
void
)
const
107
{
108
return
Address
(
GetType
(),
m_address
, 6);
109
}
110
Mac48Address
111
Mac48Address::ConvertFrom
(
const
Address
&address)
112
{
113
NS_ASSERT
(address.
CheckCompatible
(
GetType
(), 6));
114
Mac48Address
retval;
115
address.
CopyTo
(retval.m_address);
116
return
retval;
117
}
118
Mac48Address
119
Mac48Address::Allocate
(
void
)
120
{
121
static
uint64_t
id
= 0;
122
id
++;
123
Mac48Address
address;
124
address.
m_address
[0] = (
id
>> 40) & 0xff;
125
address.
m_address
[1] = (
id
>> 32) & 0xff;
126
address.
m_address
[2] = (
id
>> 24) & 0xff;
127
address.
m_address
[3] = (
id
>> 16) & 0xff;
128
address.
m_address
[4] = (
id
>> 8) & 0xff;
129
address.
m_address
[5] = (
id
>> 0) & 0xff;
130
return
address;
131
}
132
uint8_t
133
Mac48Address::GetType
(
void
)
134
{
135
static
uint8_t type =
Address::Register
();
136
return
type;
137
}
138
139
bool
140
Mac48Address::IsBroadcast
(
void
)
const
141
{
142
return
*
this
==
GetBroadcast
();
143
}
144
bool
145
Mac48Address::IsGroup
(
void
)
const
146
{
147
return
(
m_address
[0] & 0x01) == 0x01;
148
}
149
Mac48Address
150
Mac48Address::GetBroadcast
(
void
)
151
{
152
static
Mac48Address
broadcast =
Mac48Address
(
"ff:ff:ff:ff:ff:ff"
);
153
return
broadcast;
154
}
155
Mac48Address
156
Mac48Address::GetMulticastPrefix
(
void
)
157
{
158
static
Mac48Address
multicast =
Mac48Address
(
"01:00:5e:00:00:00"
);
159
return
multicast;
160
}
161
Mac48Address
162
Mac48Address::GetMulticast6Prefix
(
void
)
163
{
164
static
Mac48Address
multicast =
Mac48Address
(
"33:33:00:00:00:00"
);
165
return
multicast;
166
}
167
Mac48Address
168
Mac48Address::GetMulticast
(
Ipv4Address
multicastGroup)
169
{
170
Mac48Address
etherAddr =
Mac48Address::GetMulticastPrefix
();
171
//
172
// We now have the multicast address in an abstract 48-bit container. We
173
// need to pull it out so we can play with it. When we're done, we have the
174
// high order bits in etherBuffer[0], etc.
175
//
176
uint8_t etherBuffer[6];
177
etherAddr.
CopyTo
(etherBuffer);
178
179
//
180
// Now we need to pull the raw bits out of the Ipv4 destination address.
181
//
182
uint8_t ipBuffer[4];
183
multicastGroup.
Serialize
(ipBuffer);
184
185
//
186
// RFC 1112 says that an Ipv4 host group address is mapped to an EUI-48
187
// multicast address by placing the low-order 23-bits of the IP address into
188
// the low-order 23 bits of the Ethernet multicast address
189
// 01-00-5E-00-00-00 (hex).
190
//
191
etherBuffer[3] |= ipBuffer[1] & 0x7f;
192
etherBuffer[4] = ipBuffer[2];
193
etherBuffer[5] = ipBuffer[3];
194
195
//
196
// Now, etherBuffer has the desired ethernet multicast address. We have to
197
// suck these bits back into the Mac48Address,
198
//
199
Mac48Address
result;
200
result.
CopyFrom
(etherBuffer);
201
return
result;
202
}
203
Mac48Address
Mac48Address::GetMulticast
(
Ipv6Address
addr)
204
{
205
Mac48Address
etherAddr =
Mac48Address::GetMulticast6Prefix
();
206
uint8_t etherBuffer[6];
207
uint8_t ipBuffer[16];
208
209
/* a MAC multicast IPv6 address is like 33:33 and the four low bytes */
210
/* for 2001:db8::2fff:fe11:ac10 => 33:33:FE:11:AC:10 */
211
etherAddr.
CopyTo
(etherBuffer);
212
addr.
Serialize
(ipBuffer);
213
214
etherBuffer[2] = ipBuffer[12];
215
etherBuffer[3] = ipBuffer[13];
216
etherBuffer[4] = ipBuffer[14];
217
etherBuffer[5] = ipBuffer[15];
218
219
etherAddr.
CopyFrom
(etherBuffer);
220
221
return
etherAddr;
222
}
223
224
std::ostream&
operator<<
(std::ostream& os,
const
Mac48Address
& address)
225
{
226
uint8_t ad[6];
227
address.
CopyTo
(ad);
228
229
os.setf (std::ios::hex, std::ios::basefield);
230
os.fill (
'0'
);
231
for
(uint8_t i=0; i < 5; i++)
232
{
233
os << std::setw (2) << (uint32_t)ad[i] <<
":"
;
234
}
235
// Final byte not suffixed by ":"
236
os << std::setw (2) << (uint32_t)ad[5];
237
os.setf (std::ios::dec, std::ios::basefield);
238
os.fill (
' '
);
239
return
os;
240
}
241
242
static
uint8_t
243
AsInt
(std::string v)
244
{
245
std::istringstream iss;
246
iss.str (v);
247
uint32_t retval;
248
iss >> std::hex >> retval >> std::dec;
249
return
retval;
250
}
251
252
std::istream&
operator>>
(std::istream& is,
Mac48Address
& address)
253
{
254
std::string v;
255
is >> v;
256
257
std::string::size_type col = 0;
258
for
(uint8_t i = 0; i < 6; ++i)
259
{
260
std::string tmp;
261
std::string::size_type next;
262
next = v.find (
":"
, col);
263
if
(next == std::string::npos)
264
{
265
tmp = v.substr (col, v.size ()-col);
266
address.
m_address
[i] =
AsInt
(tmp);
267
break
;
268
}
269
else
270
{
271
tmp = v.substr (col, next-col);
272
address.
m_address
[i] =
AsInt
(tmp);
273
col = next + 1;
274
}
275
}
276
return
is;
277
}
278
279
280
}
// namespace ns3
src
network
utils
mac48-address.cc
Generated on Tue Nov 13 2012 10:32:20 for ns-3 by
1.8.1.2