diff --git a/examples/test-ipv6.cc b/examples/test-ipv6.cc index 117ecf882..ab90f1aa1 100644 --- a/examples/test-ipv6.cc +++ b/examples/test-ipv6.cc @@ -20,7 +20,6 @@ */ #include "ns3/log.h" -//#include "ns3/ipv6.h" #include "ns3/ipv6-address.h" #include "ns3/node.h" #include "ns3/mac48-address.h" @@ -38,24 +37,24 @@ main (int argc, char *argv[]) Mac48Address m_addresses[10]; - m_addresses[0]=("00:00:00:00:00:01"); - m_addresses[1]=("00:00:00:00:00:02"); - m_addresses[2]=("00:00:00:00:00:03"); - m_addresses[3]=("00:00:00:00:00:04"); - m_addresses[4]=("00:00:00:00:00:05"); - m_addresses[5]=("00:00:00:00:00:06"); - m_addresses[6]=("00:00:00:00:00:07"); - m_addresses[7]=("00:00:00:00:00:08"); - m_addresses[8]=("00:00:00:00:00:09"); - m_addresses[9]=("00:00:00:00:00:10"); + m_addresses[0] = ("00:00:00:00:00:01"); + m_addresses[1] = ("00:00:00:00:00:02"); + m_addresses[2] = ("00:00:00:00:00:03"); + m_addresses[3] = ("00:00:00:00:00:04"); + m_addresses[4] = ("00:00:00:00:00:05"); + m_addresses[5] = ("00:00:00:00:00:06"); + m_addresses[6] = ("00:00:00:00:00:07"); + m_addresses[7] = ("00:00:00:00:00:08"); + m_addresses[8] = ("00:00:00:00:00:09"); + m_addresses[9] = ("00:00:00:00:00:10"); Ipv6Address prefix1 ("2001:1::"); NS_LOG_INFO ("prefix = " << prefix1); for (uint32_t i = 0; i < 10 ; ++i) { - NS_LOG_INFO ("address = " < + */ + #ifndef ICMPV4_H #define ICMPV4_H diff --git a/src/internet-stack/icmpv6-header.h b/src/internet-stack/icmpv6-header.h index f867afedc..8cf5027f3 100644 --- a/src/internet-stack/icmpv6-header.h +++ b/src/internet-stack/icmpv6-header.h @@ -47,7 +47,7 @@ class Icmpv6Header : public Header ICMPV6_ERROR_PACKET_TOO_BIG, ICMPV6_ERROR_TIME_EXCEEDED, ICMPV6_ERROR_PARAMETER_ERROR, - ICMPV6_ECHO_REQUEST=128, + ICMPV6_ECHO_REQUEST = 128, ICMPV6_ECHO_REPLY, ICMPV6_SUBSCRIBE_REQUEST, ICMPV6_SUBSCRIBE_REPORT, diff --git a/src/internet-stack/icmpv6-l4-protocol.cc b/src/internet-stack/icmpv6-l4-protocol.cc index 71d6016b3..b783c6a93 100644 --- a/src/internet-stack/icmpv6-l4-protocol.cc +++ b/src/internet-stack/icmpv6-l4-protocol.cc @@ -278,7 +278,7 @@ void Icmpv6L4Protocol::ReceiveLLA (Icmpv6OptionLinkLayerAddress lla, Ipv6Address { NS_LOG_FUNCTION (this << lla << src << dst << interface); Address hardwareAddress; - NdiscCache::Entry* entry = NULL; + NdiscCache::Entry* entry = 0; Ptr cache = FindCache (interface->GetDevice ()); /* check if we have this address in our cache */ @@ -347,7 +347,7 @@ void Icmpv6L4Protocol::HandleRS (Ptr packet, Ipv6Address const &src, Ipv packet->RemoveHeader (rsHeader); Address hardwareAddress; Icmpv6OptionLinkLayerAddress lla (1); - NdiscCache::Entry* entry = NULL; + NdiscCache::Entry* entry = 0; Ptr cache = FindCache (interface->GetDevice ()); if (src != Ipv6Address::GetAny ()) @@ -664,7 +664,7 @@ void Icmpv6L4Protocol::HandleRedirection (Ptr packet, Ipv6Address const if (hasLla) { /* update the cache if needed */ - NdiscCache::Entry* entry = NULL; + NdiscCache::Entry* entry = 0; Ptr cache = FindCache (interface->GetDevice ()); entry = cache->Lookup (redirTarget); diff --git a/src/node/ipv6-address.cc b/src/node/ipv6-address.cc index 92049da87..818cb3a16 100644 --- a/src/node/ipv6-address.cc +++ b/src/node/ipv6-address.cc @@ -33,119 +33,141 @@ namespace ns3 { #ifdef __cplusplus extern "C" -{ +{ /* } */ #endif - /** - * \brief Get a hash key. - * \param k the key - * \param length the length of the key - * \param level the previous hash, or an arbitrary value - * \return hash - * \note Adpated from Jens Jakobsen implementation (chillispot). - */ - static uint32_t lookuphash (unsigned char* k, uint32_t length, uint32_t level) +/** + * \brief Get a hash key. + * \param k the key + * \param length the length of the key + * \param level the previous hash, or an arbitrary value + * \return hash + * \note Adapted from Jens Jakobsen implementation (chillispot). + */ +static uint32_t lookuphash (unsigned char* k, uint32_t length, uint32_t level) +{ +#define mix(a, b, c) \ +({ \ + (a) -= (b); (a) -= (c); (a) ^= ((c) >> 13); \ + (b) -= (c); (b) -= (a); (b) ^= ((a) << 8); \ + (c) -= (a); (c) -= (b); (c) ^= ((b) >> 13); \ + (a) -= (b); (a) -= (c); (a) ^= ((c) >> 12); \ + (b) -= (c); (b) -= (a); (b) ^= ((a) << 16); \ + (c) -= (a); (c) -= (b); (c) ^= ((b) >> 5); \ + (a) -= (b); (a) -= (c); (a) ^= ((c) >> 3); \ + (b) -= (c); (b) -= (a); (b) ^= ((a) << 10); \ + (c) -= (a); (c) -= (b); (c) ^= ((b) >> 15); \ +}) + + typedef uint32_t ub4; /* unsigned 4-byte quantities */ + typedef unsigned char ub1; /* unsigned 1-byte quantities */ + uint32_t a = 0; + uint32_t b = 0; + uint32_t c = 0; + uint32_t len = 0; + + /* Set up the internal state */ + len = length; + a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */ + c = level; /* the previous hash value */ + + /* handle most of the key */ + while (len >= 12) { -#define mix(a,b,c) \ - { \ - a -= b; a -= c; a ^= (c>>13); \ - b -= c; b -= a; b ^= (a<<8); \ - c -= a; c -= b; c ^= (b>>13); \ - a -= b; a -= c; a ^= (c>>12); \ - b -= c; b -= a; b ^= (a<<16); \ - c -= a; c -= b; c ^= (b>>5); \ - a -= b; a -= c; a ^= (c>>3); \ - b -= c; b -= a; b ^= (a<<10); \ - c -= a; c -= b; c ^= (b>>15); \ - } - - typedef uint32_t ub4; /* unsigned 4-byte quantities */ - typedef unsigned char ub1; /* unsigned 1-byte quantities */ - uint32_t a,b,c,len; - - /* Set up the internal state */ - len = length; - a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */ - c = level; /* the previous hash value */ - - /*---------------------------------------- handle most of the key */ - while (len >= 12) - { - a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24)); - b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24)); - c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24)); - mix(a, b, c); - k += 12; len -= 12; - } - - /*------------------------------------- handle the last 11 bytes */ - c += length; - switch (len) /* all the case statements fall through */ - { - case 11: c+=((ub4)k[10]<<24); - case 10: c+=((ub4)k[9]<<16); - case 9 : c+=((ub4)k[8]<<8); - /* the first byte of c is reserved for the length */ - case 8 : b+=((ub4)k[7]<<24); - case 7 : b+=((ub4)k[6]<<16); - case 6 : b+=((ub4)k[5]<<8); - case 5 : b+=k[4]; - case 4 : a+=((ub4)k[3]<<24); - case 3 : a+=((ub4)k[2]<<16); - case 2 : a+=((ub4)k[1]<<8); - case 1 : a+=k[0]; - /* case 0: nothing left to add */ - } - mix(a, b, c); - /*-------------------------------------------- report the result */ - return c; + a += (k[0] + ((ub4)k[1] << 8) + ((ub4)k[2] << 16) + ((ub4)k[3] << 24)); + b += (k[4] + ((ub4)k[5] << 8) + ((ub4)k[6] << 16) + ((ub4)k[7] << 24)); + c += (k[8] + ((ub4)k[9] << 8) + ((ub4)k[10] << 16) + ((ub4)k[11] << 24)); + mix (a, b, c); + k += 12; + len -= 12; } + + /* handle the last 11 bytes */ + c += length; + switch (len) /* all the case statements fall through */ + { + case 11: c += ((ub4)k[10] << 24); + case 10: c += ((ub4)k[9] << 16); + case 9 : c += ((ub4)k[8] << 8); /* the first byte of c is reserved for the length */ + case 8 : b += ((ub4)k[7] << 24); + case 7 : b += ((ub4)k[6] << 16); + case 6 : b += ((ub4)k[5] << 8); + case 5 : b += k[4]; + case 4 : a += ((ub4)k[3] << 24); + case 3 : a += ((ub4)k[2] << 16); + case 2 : a += ((ub4)k[1] << 8); + case 1 : a += k[0]; + /* case 0: nothing left to add */ + } + mix (a, b, c); + +#undef mix + + /* report the result */ + return c; +} + #ifdef __cplusplus } #endif /** * \brief Convert an IPv6 C-string into a 128-bit representation. - * \return 1 if OK, 0 if failure (bad format, ...) + * \return true if success, false otherwise (bad format, ...) * \note This function is strongly inspired by inet_pton6() from Paul Vixie. * \todo Handle IPv6 address with decimal value for last four bytes. */ -static int AsciiToIpv6Host (char const *address, uint8_t addr[16]) +static bool AsciiToIpv6Host (const char *address, uint8_t addr[16]) { - static const char xdigits_l[] = "0123456789abcdef", - xdigits_u[] = "0123456789ABCDEF"; - unsigned char tmp[16 /*NS_IN6ADDRSZ*/], *tp, *endp, *colonp; - const char *xdigits, *curtok; - int ch, seen_xdigits; - unsigned int val; + static const char xdigits_l[] = "0123456789abcdef"; + static const char xdigits_u[] = "0123456789ABCDEF"; + unsigned char tmp[16]; + unsigned char* tp = tmp; + unsigned char* endp = 0; + unsigned char* colonp = 0; + const char* xdigits = 0; + const char* curtok = 0; + int ch = 0; + int seen_xdigits = 0; + unsigned int val = 0; + + memset (tp, 0x00, 16); + endp = tp + 16; - memset ((tp = tmp), '\0', 16 /* NS_IN6ADDRSZ*/); - endp = tp + 16 /*NS_IN6ADDRSZ*/; - colonp = NULL; /* Leading :: requires some special handling. */ if (*address == ':') + { if (*++address != ':') + { return (0); + } + } curtok = address; - seen_xdigits = 0; - val = 0; + while ((ch = *address++) != '\0') { - const char *pch; + const char *pch = 0; - if ((pch = strchr ((xdigits = xdigits_l), ch)) == NULL) + if ((pch = strchr ((xdigits = xdigits_l), ch)) == 0) + { pch = strchr ((xdigits = xdigits_u), ch); - if (pch != NULL) + } + + if (pch != 0) { val <<= 4; val |= (pch - xdigits); + if (++seen_xdigits > 4) + { return (0); + } continue; } if (ch == ':') { curtok = address; + if (!seen_xdigits) { if (colonp) @@ -153,8 +175,12 @@ static int AsciiToIpv6Host (char const *address, uint8_t addr[16]) colonp = tp; continue; } - if (tp + 2 /*NS_INT16SZ*/ > endp) + + if (tp + 2 > endp) + { return (0); + } + *tp++ = (unsigned char) (val >> 8) & 0xff; *tp++ = (unsigned char) val & 0xff; seen_xdigits = 0; @@ -174,35 +200,45 @@ static int AsciiToIpv6Host (char const *address, uint8_t addr[16]) #endif return (0); } + if (seen_xdigits) { - if (tp + 2/* NS_INT16SZ*/ > endp) + if (tp + 2 > endp) + { return (0); + } *tp++ = (unsigned char) (val >> 8) & 0xff; *tp++ = (unsigned char) val & 0xff; } - if (colonp != NULL) + + if (colonp != 0) { /* * Since some memmove ()'s erroneously fail to handle * overlapping regions, we'll do the shift by hand. */ const int n = tp - colonp; - int i; + int i = 0; if (tp == endp) + { return (0); + } + for (i = 1; i <= n; i++) { endp[- i] = colonp[n - i]; colonp[n - i] = 0; } + tp = endp; } - if (tp != endp) - return (0); - /* memcpy (dst, tmp, NS_IN6ADDRSZ); */ + if (tp != endp) + { + return (0); + } + memcpy (addr, tmp, 16); return (1); } @@ -357,7 +393,7 @@ bool Ipv6Address::IsMulticast () const return false; } -Ipv6Address Ipv6Address::CombinePrefix (Ipv6Prefix const & prefix) +Ipv6Address Ipv6Address::CombinePrefix (Ipv6Prefix const& prefix) { Ipv6Address ipv6; uint8_t addr[16]; @@ -447,33 +483,21 @@ uint8_t Ipv6Address::GetType (void) return type; } -Ipv6Address Ipv6Address::GetZero () -{ - Ipv6Address zero ("::"); - return zero; -} - -Ipv6Address Ipv6Address::GetAny () -{ - Ipv6Address any ("::"); - return any; -} - Ipv6Address Ipv6Address::GetAllNodesMulticast () { - Ipv6Address nmc ("ff02::1"); + static Ipv6Address nmc ("ff02::1"); return nmc; } Ipv6Address Ipv6Address::GetAllRoutersMulticast () { - Ipv6Address rmc ("ff02::2"); + static Ipv6Address rmc ("ff02::2"); return rmc; } Ipv6Address Ipv6Address::GetAllHostsMulticast () { - Ipv6Address hmc ("ff02::3"); + static Ipv6Address hmc ("ff02::3"); return hmc; } @@ -483,6 +507,18 @@ Ipv6Address Ipv6Address::GetLoopback () return loopback; } +Ipv6Address Ipv6Address::GetZero () +{ + static Ipv6Address zero ("::"); + return zero; +} + +Ipv6Address Ipv6Address::GetAny () +{ + static Ipv6Address any ("::"); + return any; +} + Ipv6Address Ipv6Address::GetOnes () { static Ipv6Address ones ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); @@ -629,7 +665,7 @@ void Ipv6Prefix::Print (std::ostream &os) const Ipv6Prefix Ipv6Prefix::GetLoopback () { - Ipv6Prefix prefix ((uint8_t)128); + static Ipv6Prefix prefix ((uint8_t)128); return prefix; } @@ -641,7 +677,7 @@ Ipv6Prefix Ipv6Prefix::GetOnes () Ipv6Prefix Ipv6Prefix::GetZero () { - Ipv6Prefix prefix ((uint8_t)0); + static Ipv6Prefix prefix ((uint8_t)0); return prefix; } @@ -665,7 +701,7 @@ uint8_t Ipv6Prefix::GetPrefixLength () const prefixLength++; } } - + return prefixLength; } @@ -678,7 +714,7 @@ bool Ipv6Prefix::IsEqual (const Ipv6Prefix& other) const return false; } -std::ostream& operator<< (std::ostream& os, Ipv6Prefix const& prefix) +std::ostream& operator << (std::ostream& os, Ipv6Prefix const& prefix) { prefix.Print (os); return os;