00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <string.h>
00022
00023 #include "ns3/log.h"
00024 #include "ipv6-address.h"
00025 #include "ns3/assert.h"
00026 #include "mac48-address.h"
00027
00028 #include <iomanip>
00029
00030 NS_LOG_COMPONENT_DEFINE ("Ipv6Address");
00031
00032 namespace ns3 {
00033
00034 #ifdef __cplusplus
00035 extern "C"
00036 {
00037 #endif
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 static uint32_t lookuphash (unsigned char* k, uint32_t length, uint32_t level)
00048 {
00049 #define mix(a,b,c) \
00050 { \
00051 a -= b; a -= c; a ^= (c>>13); \
00052 b -= c; b -= a; b ^= (a<<8); \
00053 c -= a; c -= b; c ^= (b>>13); \
00054 a -= b; a -= c; a ^= (c>>12); \
00055 b -= c; b -= a; b ^= (a<<16); \
00056 c -= a; c -= b; c ^= (b>>5); \
00057 a -= b; a -= c; a ^= (c>>3); \
00058 b -= c; b -= a; b ^= (a<<10); \
00059 c -= a; c -= b; c ^= (b>>15); \
00060 }
00061
00062 typedef uint32_t ub4;
00063 typedef unsigned char ub1;
00064 uint32_t a,b,c,len;
00065
00066
00067 len = length;
00068 a = b = 0x9e3779b9;
00069 c = level;
00070
00071
00072 while (len >= 12)
00073 {
00074 a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24));
00075 b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24));
00076 c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24));
00077 mix(a,b,c);
00078 k += 12; len -= 12;
00079 }
00080
00081
00082 c += length;
00083 switch(len)
00084 {
00085 case 11: c+=((ub4)k[10]<<24);
00086 case 10: c+=((ub4)k[9]<<16);
00087 case 9 : c+=((ub4)k[8]<<8);
00088
00089 case 8 : b+=((ub4)k[7]<<24);
00090 case 7 : b+=((ub4)k[6]<<16);
00091 case 6 : b+=((ub4)k[5]<<8);
00092 case 5 : b+=k[4];
00093 case 4 : a+=((ub4)k[3]<<24);
00094 case 3 : a+=((ub4)k[2]<<16);
00095 case 2 : a+=((ub4)k[1]<<8);
00096 case 1 : a+=k[0];
00097
00098 }
00099 mix(a,b,c);
00100
00101 return c;
00102 }
00103 #ifdef __cplusplus
00104 }
00105 #endif
00106
00107
00108
00109
00110
00111
00112
00113 static int AsciiToIpv6Host (char const *address, uint8_t addr[16])
00114 {
00115 static const char xdigits_l[] = "0123456789abcdef",
00116 xdigits_u[] = "0123456789ABCDEF";
00117 unsigned char tmp[16 ], *tp, *endp, *colonp;
00118 const char *xdigits, *curtok;
00119 int ch, seen_xdigits;
00120 unsigned int val;
00121
00122 memset((tp = tmp), '\0', 16 );
00123 endp = tp + 16 ;
00124 colonp = NULL;
00125
00126 if (*address == ':')
00127 if (*++address != ':')
00128 return (0);
00129 curtok = address;
00130 seen_xdigits = 0;
00131 val = 0;
00132 while ((ch = *address++) != '\0')
00133 {
00134 const char *pch;
00135
00136 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
00137 pch = strchr((xdigits = xdigits_u), ch);
00138 if (pch != NULL)
00139 {
00140 val <<= 4;
00141 val |= (pch - xdigits);
00142 if (++seen_xdigits > 4)
00143 return (0);
00144 continue;
00145 }
00146 if (ch == ':')
00147 {
00148 curtok = address;
00149 if (!seen_xdigits)
00150 {
00151 if (colonp)
00152 return (0);
00153 colonp = tp;
00154 continue;
00155 }
00156 if (tp + 2 > endp)
00157 return (0);
00158 *tp++ = (unsigned char) (val >> 8) & 0xff;
00159 *tp++ = (unsigned char) val & 0xff;
00160 seen_xdigits = 0;
00161 val = 0;
00162 continue;
00163 }
00164
00165
00166 #if 0
00167 if (ch == '.' && ((tp + 4 ) <= endp) &&
00168 inet_pton4(curtok, tp) > 0)
00169 {
00170 tp += 4 ;
00171 seen_xdigits = 0;
00172 break;
00173 }
00174 #endif
00175 return (0);
00176 }
00177 if (seen_xdigits)
00178 {
00179 if (tp + 2 > endp)
00180 return (0);
00181 *tp++ = (unsigned char) (val >> 8) & 0xff;
00182 *tp++ = (unsigned char) val & 0xff;
00183 }
00184 if (colonp != NULL)
00185 {
00186
00187
00188
00189
00190 const int n = tp - colonp;
00191 int i;
00192
00193 if (tp == endp)
00194 return (0);
00195 for (i = 1; i <= n; i++)
00196 {
00197 endp[- i] = colonp[n - i];
00198 colonp[n - i] = 0;
00199 }
00200 tp = endp;
00201 }
00202 if (tp != endp)
00203 return (0);
00204
00205
00206 memcpy(addr, tmp, 16);
00207 return (1);
00208 }
00209
00210 Ipv6Address::Ipv6Address ()
00211 {
00212 memset(m_address, 0x00, 16);
00213 }
00214
00215 Ipv6Address::Ipv6Address (Ipv6Address const& addr)
00216 {
00217 memcpy(m_address, addr.m_address, 16);
00218 }
00219
00220 Ipv6Address::Ipv6Address (Ipv6Address const* addr)
00221 {
00222 memcpy(m_address, addr->m_address, 16);
00223 }
00224
00225 Ipv6Address::Ipv6Address (char const* address)
00226 {
00227 AsciiToIpv6Host (address, m_address);
00228 }
00229
00230 Ipv6Address::Ipv6Address (uint8_t address[16])
00231 {
00232
00233 memcpy(m_address, address, 16);
00234 }
00235
00236 Ipv6Address::~Ipv6Address ()
00237 {
00238
00239 }
00240
00241 void Ipv6Address::Set (char const* address)
00242 {
00243 AsciiToIpv6Host (address, m_address);
00244 }
00245
00246 void Ipv6Address::Set (uint8_t address[16])
00247 {
00248
00249 memcpy(m_address, address, 16);
00250 }
00251
00252 void Ipv6Address::Serialize (uint8_t buf[16]) const
00253 {
00254 memcpy(buf, m_address, 16);
00255 }
00256
00257 Ipv6Address Ipv6Address::Deserialize (const uint8_t buf[16])
00258 {
00259 Ipv6Address ipv6((uint8_t*)buf);
00260 return ipv6;
00261 }
00262
00263 Ipv6Address Ipv6Address::MakeAutoconfiguredAddress (Mac48Address addr, Ipv6Address prefix)
00264 {
00265 Ipv6Address ret;
00266 uint8_t buf[16];
00267 uint8_t buf2[16];
00268
00269 addr.CopyTo(buf);
00270 prefix.GetBytes(buf2);
00271
00272 memcpy(buf2 + 8, buf, 3);
00273 buf2[11] = 0xff;
00274 buf2[12] = 0xfe;
00275 memcpy(buf2 + 13, buf + 3, 3);
00276 buf2[8] |= 0x02;
00277
00278 ret.Set(buf2);
00279 return ret;
00280 }
00281
00282 Ipv6Address Ipv6Address::MakeAutoconfiguredLinkLocalAddress (Mac48Address addr)
00283 {
00284 Ipv6Address ret;
00285 uint8_t buf[16];
00286 uint8_t buf2[16];
00287
00288 addr.CopyTo(buf);
00289
00290 memset(buf2, 0x00, sizeof(buf2));
00291 buf2[0] = 0xfe;
00292 buf2[1] = 0x80;
00293 memcpy(buf2 + 8, buf, 3);
00294 buf2[11] = 0xff;
00295 buf2[12] = 0xfe;
00296 memcpy(buf2 + 13, buf + 3, 3);
00297 buf2[8] |= 0x02;
00298
00299 ret.Set(buf2);
00300 return ret;
00301 }
00302
00303 Ipv6Address Ipv6Address::MakeSolicitedAddress (Ipv6Address addr)
00304 {
00305 uint8_t buf[16];
00306 uint8_t buf2[16];
00307 Ipv6Address ret;
00308
00309 addr.Serialize(buf2);
00310
00311 memset(buf, 0x00, sizeof(buf));
00312 buf[0] = 0xff;
00313 buf[1] = 0x02;
00314 buf[11] = 0x01;
00315 buf[12] = 0xff;
00316 buf[13] = buf2[13];
00317 buf[14] = buf2[14];
00318 buf[15] = buf2[15];
00319
00320 ret.Set(buf);
00321 return ret;
00322 }
00323
00324 void Ipv6Address::Print (std::ostream& os) const
00325 {
00326 os << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[0]
00327 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[1] << ":"
00328 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[2]
00329 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[3] << ":"
00330 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[4]
00331 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[5] << ":"
00332 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[6]
00333 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[7] << ":"
00334 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[8]
00335 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[9] << ":"
00336 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[10]
00337 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[11] << ":"
00338 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[12]
00339 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[13] << ":"
00340 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[14]
00341 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[15];
00342 }
00343
00344 bool Ipv6Address::IsLocalhost () const
00345 {
00346 static Ipv6Address localhost("::1");
00347 return (*this == localhost);
00348 }
00349
00350 bool Ipv6Address::IsMulticast () const
00351 {
00352 if(m_address[0] == 0xff)
00353 {
00354 return true;
00355 }
00356 return false;
00357 }
00358
00359 Ipv6Address Ipv6Address::CombinePrefix (Ipv6Prefix const & prefix)
00360 {
00361 Ipv6Address ipv6;
00362 uint8_t addr[16];
00363 uint8_t pref[16];
00364 unsigned int i = 0;
00365
00366 memcpy(addr, m_address, 16);
00367 ((Ipv6Prefix)prefix).GetBytes(pref);
00368
00369
00370 for(i = 0 ; i < 16 ; i++)
00371 {
00372 addr[i] = addr[i] & pref[i];
00373 }
00374 ipv6.Set(addr);
00375 return ipv6;
00376 }
00377
00378 bool Ipv6Address::IsSolicitedMulticast () const
00379 {
00380 uint8_t buf[16];
00381
00382 Serialize(buf);
00383
00384 if(buf[0] == 0xff &&
00385 buf[1] == 0x02 &&
00386 buf[11] == 0x01 &&
00387 buf[12] == 0xff)
00388 {
00389 return true;
00390 }
00391 return false;
00392 }
00393
00394 bool Ipv6Address::IsAllNodesMulticast () const
00395 {
00396 static Ipv6Address allnodes("ff02::1");
00397 return (*this == allnodes);
00398 }
00399
00400 bool Ipv6Address::IsAllRoutersMulticast () const
00401 {
00402 static Ipv6Address allrouters("ff02::2");
00403 return (*this == allrouters);
00404 }
00405
00406 bool Ipv6Address::IsAllHostsMulticast () const
00407 {
00408 static Ipv6Address allhosts("ff02::3");
00409 return (*this == allhosts);
00410 }
00411
00412 bool Ipv6Address::IsAny () const
00413 {
00414 static Ipv6Address any("::");
00415 return (*this == any);
00416 }
00417
00418 bool Ipv6Address::IsMatchingType (const Address& address)
00419 {
00420 return address.CheckCompatible(GetType(), 16);
00421 }
00422
00423 Ipv6Address::operator Address () const
00424 {
00425 return ConvertTo ();
00426 }
00427
00428 Address Ipv6Address::ConvertTo (void) const
00429 {
00430 uint8_t buf[16];
00431 Serialize (buf);
00432 return Address(GetType(), buf, 16);
00433 }
00434
00435 Ipv6Address Ipv6Address::ConvertFrom (const Address &address)
00436 {
00437 NS_ASSERT (address.CheckCompatible (GetType (), 16));
00438 uint8_t buf[16];
00439 address.CopyTo (buf);
00440 return Deserialize (buf);
00441 }
00442
00443 uint8_t Ipv6Address::GetType (void)
00444 {
00445 static uint8_t type = Address::Register();
00446 return type;
00447 }
00448
00449 Ipv6Address Ipv6Address::GetZero ()
00450 {
00451 Ipv6Address zero("::");
00452 return zero;
00453 }
00454
00455 Ipv6Address Ipv6Address::GetAny ()
00456 {
00457 Ipv6Address any("::");
00458 return any;
00459 }
00460
00461 Ipv6Address Ipv6Address::GetAllNodesMulticast ()
00462 {
00463 Ipv6Address nmc("ff02::1");
00464 return nmc;
00465 }
00466
00467 Ipv6Address Ipv6Address::GetAllRoutersMulticast ()
00468 {
00469 Ipv6Address rmc("ff02::2");
00470 return rmc;
00471 }
00472
00473 Ipv6Address Ipv6Address::GetAllHostsMulticast ()
00474 {
00475 Ipv6Address hmc("ff02::3");
00476 return hmc;
00477 }
00478
00479 Ipv6Address Ipv6Address::GetLoopback ()
00480 {
00481 static Ipv6Address loopback("::1");
00482 return loopback;
00483 }
00484
00485 void Ipv6Address::GetBytes (uint8_t buf[16]) const
00486 {
00487 memcpy(buf, m_address, 16);
00488 }
00489
00490 bool Ipv6Address::IsLinkLocal () const
00491 {
00492 Ipv6Address linkLocal("fe80::0");
00493 if(!IsMulticast() && ((Ipv6Address*)this)->CombinePrefix(Ipv6Prefix(64))==linkLocal)
00494 {
00495 return true;
00496 }
00497 return false;
00498 }
00499
00500 bool Ipv6Address::IsEqual (const Ipv6Address& other) const
00501 {
00502 if(!memcmp(m_address, other.m_address, 16))
00503 {
00504 return true;
00505 }
00506 return false;
00507 }
00508
00509 std::ostream& operator << (std::ostream& os, Ipv6Address const& address)
00510 {
00511 address.Print(os);
00512 return os;
00513 }
00514
00515 std::istream& operator >> (std::istream& is, Ipv6Address& address)
00516 {
00517 std::string str;
00518 is >> str;
00519 address = Ipv6Address (str.c_str ());
00520 return is;
00521 }
00522
00523 Ipv6Prefix::Ipv6Prefix ()
00524 {
00525 memset(m_prefix, 0x00, 16);
00526 }
00527
00528 Ipv6Prefix::Ipv6Prefix (char const* prefix)
00529 {
00530 AsciiToIpv6Host(prefix, m_prefix);
00531 }
00532
00533 Ipv6Prefix::Ipv6Prefix (uint8_t prefix[16])
00534 {
00535 memcpy(m_prefix, prefix, 16);
00536 }
00537
00538 Ipv6Prefix::Ipv6Prefix (uint8_t prefix)
00539 {
00540 unsigned int nb=0;
00541 unsigned int mod=0;
00542 unsigned int i=0;
00543
00544 memset(m_prefix, 0x00, 16);
00545
00546 NS_ASSERT(prefix <= 128);
00547
00548 nb = prefix / 8;
00549 mod = prefix % 8;
00550
00551 memset(m_prefix, 0xff, nb);
00552
00553 if(mod)
00554 {
00555 m_prefix[nb] = 0xff << (8-mod);
00556 }
00557
00558 if(nb < 16)
00559 {
00560 nb++;
00561 for(i = nb; i < 16 ; i++)
00562 {
00563 m_prefix[i] = 0x00;
00564 }
00565 }
00566 }
00567
00568 Ipv6Prefix::Ipv6Prefix (Ipv6Prefix const& prefix)
00569 {
00570 memcpy(m_prefix, prefix.m_prefix, 16);
00571 }
00572
00573 Ipv6Prefix::Ipv6Prefix (Ipv6Prefix const* prefix)
00574 {
00575 memcpy(m_prefix, prefix->m_prefix, 16);
00576 }
00577
00578 Ipv6Prefix::~Ipv6Prefix ()
00579 {
00580
00581 }
00582
00583 bool Ipv6Prefix::IsMatch (Ipv6Address a, Ipv6Address b) const
00584 {
00585 uint8_t addrA[16];
00586 uint8_t addrB[16];
00587 unsigned int i = 0;
00588
00589 a.GetBytes(addrA);
00590 b.GetBytes(addrB);
00591
00592
00593 for(i = 0 ; i < 16 ; i++)
00594 {
00595 if((addrA[i] & m_prefix[i]) != (addrB[i] & m_prefix[i]))
00596 {
00597 return false;
00598 }
00599 }
00600 return true;
00601 }
00602
00603 void Ipv6Prefix::Print (std::ostream &os) const
00604 {
00605 os << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[0]
00606 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[1] << ":"
00607 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[2]
00608 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[3] << ":"
00609 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[4]
00610 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[5] << ":"
00611 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[6]
00612 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[7] << ":"
00613 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[8]
00614 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[9] << ":"
00615 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[10]
00616 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[11] << ":"
00617 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[12]
00618 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[13] << ":"
00619 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[14]
00620 << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[15];
00621 }
00622
00623 Ipv6Prefix Ipv6Prefix::GetLoopback ()
00624 {
00625 Ipv6Prefix prefix((uint8_t)128);
00626 return prefix;
00627 }
00628
00629 Ipv6Prefix Ipv6Prefix::GetZero ()
00630 {
00631 Ipv6Prefix prefix((uint8_t)0);
00632 return prefix;
00633 }
00634
00635 void Ipv6Prefix::GetBytes (uint8_t buf[16]) const
00636 {
00637 memcpy(buf, m_prefix, 16);
00638 }
00639
00640 bool Ipv6Prefix::IsEqual (const Ipv6Prefix& other) const
00641 {
00642 if(!memcmp(m_prefix, other.m_prefix, 16))
00643 {
00644 return true;
00645 }
00646 return false;
00647 }
00648
00649 std::ostream& operator<< (std::ostream& os, Ipv6Prefix const& prefix)
00650 {
00651 prefix.Print (os);
00652 return os;
00653 }
00654
00655 std::istream& operator >> (std::istream& is, Ipv6Prefix& prefix)
00656 {
00657 std::string str;
00658 is >> str;
00659 prefix = Ipv6Prefix (str.c_str ());
00660 return is;
00661 }
00662
00663 bool operator == (Ipv6Prefix const &a, Ipv6Prefix const &b)
00664 {
00665 return a.IsEqual (b);
00666 }
00667
00668 bool operator != (Ipv6Prefix const &a, Ipv6Prefix const &b)
00669 {
00670 return !a.IsEqual (b);
00671 }
00672
00673 size_t Ipv6AddressHash::operator() (Ipv6Address const &x) const
00674 {
00675 uint8_t buf[16];
00676
00677 x.GetBytes(buf);
00678
00679 return lookuphash(buf, sizeof(buf), 0);
00680 }
00681
00682 ATTRIBUTE_HELPER_CPP (Ipv6Address);
00683 ATTRIBUTE_HELPER_CPP (Ipv6Prefix);
00684
00685 }
00686