00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "mac48-address.h"
00021 #include "address.h"
00022 #include "ns3/assert.h"
00023 #include <iomanip>
00024 #include <iostream>
00025 #include <string.h>
00026
00027 namespace ns3 {
00028
00029 ATTRIBUTE_HELPER_CPP (Mac48Address);
00030
00031 #define ASCII_a (0x41)
00032 #define ASCII_z (0x5a)
00033 #define ASCII_A (0x61)
00034 #define ASCII_Z (0x7a)
00035 #define ASCII_COLON (0x3a)
00036 #define ASCII_ZERO (0x30)
00037
00038 static char
00039 AsciiToLowCase (char c)
00040 {
00041 if (c >= ASCII_a && c <= ASCII_z) {
00042 return c;
00043 } else if (c >= ASCII_A && c <= ASCII_Z) {
00044 return c + (ASCII_a - ASCII_A);
00045 } else {
00046 return c;
00047 }
00048 }
00049
00050
00051 Mac48Address::Mac48Address ()
00052 {
00053 memset (m_address, 0, 6);
00054 }
00055 Mac48Address::Mac48Address (const char *str)
00056 {
00057 int i = 0;
00058 while (*str != 0 && i < 6)
00059 {
00060 uint8_t byte = 0;
00061 while (*str != ASCII_COLON && *str != 0)
00062 {
00063 byte <<= 4;
00064 char low = AsciiToLowCase (*str);
00065 if (low >= ASCII_a)
00066 {
00067 byte |= low - ASCII_a + 10;
00068 }
00069 else
00070 {
00071 byte |= low - ASCII_ZERO;
00072 }
00073 str++;
00074 }
00075 m_address[i] = byte;
00076 i++;
00077 if (*str == 0)
00078 {
00079 break;
00080 }
00081 str++;
00082 }
00083 NS_ASSERT (i == 6);
00084 }
00085 void
00086 Mac48Address::CopyFrom (const uint8_t buffer[6])
00087 {
00088 memcpy (m_address, buffer, 6);
00089 }
00090 void
00091 Mac48Address::CopyTo (uint8_t buffer[6]) const
00092 {
00093 memcpy (buffer, m_address, 6);
00094 }
00095
00096 bool
00097 Mac48Address::IsMatchingType (const Address &address)
00098 {
00099 return address.CheckCompatible (GetType (), 6);
00100 }
00101 Mac48Address::operator Address () const
00102 {
00103 return ConvertTo ();
00104 }
00105 Address
00106 Mac48Address::ConvertTo (void) const
00107 {
00108 return Address (GetType (), m_address, 6);
00109 }
00110 Mac48Address
00111 Mac48Address::ConvertFrom (const Address &address)
00112 {
00113 NS_ASSERT (address.CheckCompatible (GetType (), 6));
00114 Mac48Address retval;
00115 address.CopyTo (retval.m_address);
00116 return retval;
00117 }
00118 Mac48Address
00119 Mac48Address::Allocate (void)
00120 {
00121 static uint64_t id = 0;
00122 id++;
00123 Mac48Address address;
00124 address.m_address[0] = (id >> 40) & 0xff;
00125 address.m_address[1] = (id >> 32) & 0xff;
00126 address.m_address[2] = (id >> 24) & 0xff;
00127 address.m_address[3] = (id >> 16) & 0xff;
00128 address.m_address[4] = (id >> 8) & 0xff;
00129 address.m_address[5] = (id >> 0) & 0xff;
00130 return address;
00131 }
00132 uint8_t
00133 Mac48Address::GetType (void)
00134 {
00135 static uint8_t type = Address::Register ();
00136 return type;
00137 }
00138
00139 bool
00140 Mac48Address::IsBroadcast (void) const
00141 {
00142 return *this == GetBroadcast ();
00143 }
00144 bool
00145 Mac48Address::IsMulticast (void) const
00146 {
00147 uint8_t mcBuf[6];
00148 CopyTo (mcBuf);
00149 mcBuf[3] &= 0x80;
00150 mcBuf[4] = 0;
00151 mcBuf[5] = 0;
00152 Mac48Address prefix;
00153 prefix.CopyFrom (mcBuf);
00154 return prefix == Mac48Address::GetMulticastPrefix ();
00155 }
00156 bool
00157 Mac48Address::IsGroup (void) const
00158 {
00159 return (m_address[0] & 0x01) == 0x01;
00160 }
00161 Mac48Address
00162 Mac48Address::GetBroadcast (void)
00163 {
00164 static Mac48Address broadcast = Mac48Address ("ff:ff:ff:ff:ff:ff");
00165 return broadcast;
00166 }
00167 Mac48Address
00168 Mac48Address::GetMulticastPrefix (void)
00169 {
00170 static Mac48Address multicast = Mac48Address ("01:00:5e:00:00:00");
00171 return multicast;
00172 }
00173 Mac48Address
00174 Mac48Address::GetMulticast6Prefix (void)
00175 {
00176 static Mac48Address multicast = Mac48Address ("33:33:00:00:00:00");
00177 return multicast;
00178 }
00179 Mac48Address
00180 Mac48Address::GetMulticast (Ipv4Address multicastGroup)
00181 {
00182 Mac48Address etherAddr = Mac48Address::GetMulticastPrefix ();
00183
00184
00185
00186
00187
00188 uint8_t etherBuffer[6];
00189 etherAddr.CopyTo (etherBuffer);
00190
00191
00192
00193
00194 uint8_t ipBuffer[4];
00195 multicastGroup.Serialize (ipBuffer);
00196
00197
00198
00199
00200
00201
00202
00203 etherBuffer[3] |= ipBuffer[1] & 0x7f;
00204 etherBuffer[4] = ipBuffer[2];
00205 etherBuffer[5] = ipBuffer[3];
00206
00207
00208
00209
00210
00211 Mac48Address result;
00212 result.CopyFrom (etherBuffer);
00213 return result;
00214 }
00215 Mac48Address Mac48Address::GetMulticast(Ipv6Address addr)
00216 {
00217 Mac48Address etherAddr = Mac48Address::GetMulticast6Prefix();
00218 uint8_t etherBuffer[6];
00219 uint8_t ipBuffer[16];
00220
00221
00222
00223 etherAddr.CopyTo (etherBuffer);
00224 addr.Serialize (ipBuffer);
00225
00226 etherBuffer[2] = ipBuffer[12];
00227 etherBuffer[3] = ipBuffer[13];
00228 etherBuffer[4] = ipBuffer[14];
00229 etherBuffer[5] = ipBuffer[15];
00230
00231 etherAddr.CopyFrom (etherBuffer);
00232
00233 return etherAddr;
00234 }
00235
00236 bool operator == (const Mac48Address &a, const Mac48Address &b)
00237 {
00238 return memcmp (a.m_address, b.m_address, 6) == 0;
00239 }
00240 bool operator != (const Mac48Address &a, const Mac48Address &b)
00241 {
00242 return ! (a == b);
00243 }
00244
00245 bool operator < (const Mac48Address &a, const Mac48Address &b)
00246 {
00247 uint8_t aP[6];
00248 uint8_t bP[6];
00249 a.CopyTo (aP);
00250 b.CopyTo (bP);
00251 for (uint8_t i = 0; i < 6; i++)
00252 {
00253 if (a.m_address[i] < b.m_address[i])
00254 {
00255 return true;
00256 }
00257 else if (a.m_address[i] > b.m_address[i])
00258 {
00259 return false;
00260 }
00261 }
00262 return false;
00263 }
00264
00265
00266 std::ostream& operator<< (std::ostream& os, const Mac48Address & address)
00267 {
00268 uint8_t ad[6];
00269 address.CopyTo (ad);
00270
00271 os.setf (std::ios::hex, std::ios::basefield);
00272 os.fill('0');
00273 for (uint8_t i=0; i < 5; i++)
00274 {
00275 os << std::setw(2) << (uint32_t)ad[i] << ":";
00276 }
00277
00278 os << std::setw(2) << (uint32_t)ad[5];
00279 os.setf (std::ios::dec, std::ios::basefield);
00280 os.fill(' ');
00281 return os;
00282 }
00283
00284 static uint8_t
00285 AsInt (std::string v)
00286 {
00287 std::istringstream iss;
00288 iss.str (v);
00289 uint32_t retval;
00290 iss >> std::hex >> retval >> std::dec;
00291 return retval;
00292 }
00293
00294 std::istream& operator>> (std::istream& is, Mac48Address & address)
00295 {
00296 std::string v;
00297 is >> v;
00298
00299 std::string::size_type col = 0;
00300 for (uint8_t i = 0; i < 6; ++i)
00301 {
00302 std::string tmp;
00303 std::string::size_type next;
00304 next = v.find (":", col);
00305 if (next == std::string::npos)
00306 {
00307 tmp = v.substr (col, v.size ()-col);
00308 address.m_address[i] = AsInt (tmp);
00309 break;
00310 }
00311 else
00312 {
00313 tmp = v.substr (col, next-col);
00314 address.m_address[i] = AsInt (tmp);
00315 col = next + 1;
00316 }
00317 }
00318 return is;
00319 }
00320
00321
00322 }