diff --git a/RELEASE_NOTES b/RELEASE_NOTES index c373fb09b..57fe07017 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -29,9 +29,11 @@ New user-visible features - (lr-wpan) Extended addressing mode is now supported. - (tcp) Implemented the core functionality of TCP Pacing. - (internet) Ipv[4,6]AddressGenerator can now check if an address or a network is allocated. +- (internet) Ipv6AddressHelper is now more pedantic but you can use more than one in a script. Bugs fixed ---------- +- Bug 1745 - There can be only one Ipv6AddressHelper in a script - Bug 2505 - network: Avoid asserts in Header/Trailer deserialization - Bug 2656 - wifi: Minstrel and MinstrelHt provide different results for 802.11a/b/g - Bug 2653 - tcp: Avoid saving smaller TS in case of packet reordering diff --git a/examples/ipv6/radvd-two-prefix.cc b/examples/ipv6/radvd-two-prefix.cc index da88e7904..3ee513ec0 100644 --- a/examples/ipv6/radvd-two-prefix.cc +++ b/examples/ipv6/radvd-two-prefix.cc @@ -135,7 +135,7 @@ int main (int argc, char** argv) iic1.Add (iicr1); /* add another IPv6 address for second prefix advertised on first subnet */ - ipv6.SetBase (Ipv6Address ("2001:ABCD::2"), Ipv6Prefix (64)); + ipv6.SetBase (Ipv6Address ("2001:ABCD::"), Ipv6Prefix (64)); ipv6.Assign (tmp2); /* second subnet R - n1 */ diff --git a/src/internet/helper/ipv6-address-helper.cc b/src/internet/helper/ipv6-address-helper.cc index 7151376b6..05d898887 100644 --- a/src/internet/helper/ipv6-address-helper.cc +++ b/src/internet/helper/ipv6-address-helper.cc @@ -42,23 +42,44 @@ NS_LOG_COMPONENT_DEFINE ("Ipv6AddressHelper"); Ipv6AddressHelper::Ipv6AddressHelper () { NS_LOG_FUNCTION (this); - Ipv6AddressGenerator::Init (Ipv6Address ("2001:db8::"), Ipv6Prefix (64)); + m_network = Ipv6Address ("2001:db8::"); + m_prefix = 64; + m_address = Ipv6Address ("::1"); + m_base = m_address; } Ipv6AddressHelper::Ipv6AddressHelper (Ipv6Address network, Ipv6Prefix prefix, Ipv6Address base) { NS_LOG_FUNCTION (this << network << prefix << base); - Ipv6AddressGenerator::Init (network, prefix, base); + + m_network = network; + m_prefix = prefix; + m_address = base; + m_base = base; + + NS_ASSERT_MSG (m_network == network.CombinePrefix (prefix), + "Ipv6AddressHelper: network address and prefix mismatch: " << m_network << " " << m_prefix); + + NS_ASSERT_MSG (base.CombinePrefix (prefix) == Ipv6Address::GetZero (), + "Ipv6AddressHelper: base address and prefix mismatch: " << base << " " << m_prefix); } void Ipv6AddressHelper::SetBase (Ipv6Address network, Ipv6Prefix prefix, - Ipv6Address base) + Ipv6Address base) { NS_LOG_FUNCTION (this << network << prefix << base); - /// \todo for now we do not enforce the prefix because the underlying - /// Ipv6AddressGenerator does not handle prefixes well that are not 64 bits - Ipv6AddressGenerator::Init (network, Ipv6Prefix (64), base); + + m_network = network; + m_prefix = prefix; + m_address = base; + m_base = base; + + NS_ASSERT_MSG (m_network == network.CombinePrefix (prefix), + "Ipv6AddressHelper::SetBase(): network address and prefix mismatch: " << m_network << " " << m_prefix); + + NS_ASSERT_MSG (base.CombinePrefix (prefix) == Ipv6Address::GetZero (), + "Ipv6AddressHelper::SetBase(): base address and prefix mismatch: " << base << " " << m_prefix); } @@ -67,22 +88,19 @@ Ipv6Address Ipv6AddressHelper::NewAddress (Address addr) NS_LOG_FUNCTION (this << addr); if (Mac64Address::IsMatchingType (addr)) { - Ipv6Address network = Ipv6AddressGenerator::GetNetwork (Ipv6Prefix (64)); - Ipv6Address address = Ipv6Address::MakeAutoconfiguredAddress (Mac64Address::ConvertFrom (addr), network); + Ipv6Address address = Ipv6Address::MakeAutoconfiguredAddress (Mac64Address::ConvertFrom (addr), m_network); Ipv6AddressGenerator::AddAllocated (address); return address; } else if (Mac48Address::IsMatchingType (addr)) { - Ipv6Address network = Ipv6AddressGenerator::GetNetwork (Ipv6Prefix (64)); - Ipv6Address address = Ipv6Address::MakeAutoconfiguredAddress (Mac48Address::ConvertFrom (addr), network); + Ipv6Address address = Ipv6Address::MakeAutoconfiguredAddress (Mac48Address::ConvertFrom (addr), m_network); Ipv6AddressGenerator::AddAllocated (address); return address; } else if (Mac16Address::IsMatchingType (addr)) { - Ipv6Address network = Ipv6AddressGenerator::GetNetwork (Ipv6Prefix (64)); - Ipv6Address address = Ipv6Address::MakeAutoconfiguredAddress (Mac16Address::ConvertFrom (addr), network); + Ipv6Address address = Ipv6Address::MakeAutoconfiguredAddress (Mac16Address::ConvertFrom (addr), m_network); Ipv6AddressGenerator::AddAllocated (address); return address; } @@ -103,14 +121,71 @@ Ipv6Address Ipv6AddressHelper::NewAddress (void) // get new addresses on a given subnet. The client will expect that the first // address she gets back is the one she used to initialize the generator with. // This implies that this operation is a post-increment. -// - return Ipv6AddressGenerator::NextAddress (Ipv6Prefix (64)); + + uint8_t netBuf[16]; + uint8_t hostBuf[16]; + uint8_t addrBuf[16]; + m_network.GetBytes (netBuf); + m_address.GetBytes (hostBuf); + uint128_t host = 0; + + NS_ASSERT_MSG (m_address.CombinePrefix (m_prefix) == Ipv6Address::GetZero (), + "Ipv6AddressHelper::NewAddress(): Too many hosts in the network: " << m_address << " " << m_prefix); + + for (uint8_t i=0; i<16; i++) + { + addrBuf[i] = netBuf[i] | hostBuf[i]; + } + + Ipv6Address addr = Ipv6Address (addrBuf); + + // To add one more address we have to go through some conversions... + for (uint8_t i=0; i<15; i++) + { + host |= hostBuf[i]; + host <<= 8; + } + host |= hostBuf[15]; + + host += 1; + for (uint8_t i=0; i<16; i++) + { + hostBuf[15-i] = (host & 0xff); + host >>= 8; + } + m_address = Ipv6Address (hostBuf); + + Ipv6AddressGenerator::AddAllocated (addr); + return addr; } void Ipv6AddressHelper::NewNetwork (void) { NS_LOG_FUNCTION (this); - Ipv6AddressGenerator::NextNetwork (Ipv6Prefix (64)); + + uint8_t netBuf[16]; + m_network.GetBytes (netBuf); + uint128_t network = 0; + + for (uint8_t i=0; i<15; i++) + { + network |= netBuf[i]; + network <<= 8; + } + network |= netBuf[15]; + + std::cout << "** Shifting the network by " << 128 - int(m_prefix.GetPrefixLength ()) << " bits" << std::endl; + network >>= 128 - m_prefix.GetPrefixLength (); + network += 1; + network <<= 128 - m_prefix.GetPrefixLength (); + + for (uint8_t i=0; i<16; i++) + { + netBuf[15-i] = (network & 0xff); + network >>= 8; + } + m_network = Ipv6Address (netBuf); + m_address = m_base; } Ipv6InterfaceContainer Ipv6AddressHelper::Assign (const NetDeviceContainer &c) diff --git a/src/internet/helper/ipv6-address-helper.h b/src/internet/helper/ipv6-address-helper.h index 7b7bc6efc..8a8fc86dd 100644 --- a/src/internet/helper/ipv6-address-helper.h +++ b/src/internet/helper/ipv6-address-helper.h @@ -167,6 +167,11 @@ public: */ Ipv6InterfaceContainer AssignWithoutAddress (const NetDeviceContainer &c); +private: + Ipv6Address m_network; //!< network address + Ipv6Prefix m_prefix; //!< prefix length + Ipv6Address m_address; //!< host address + Ipv6Address m_base; //!< host base address }; } /* namespace ns3 */ diff --git a/src/internet/test/ipv6-address-helper-test-suite.cc b/src/internet/test/ipv6-address-helper-test-suite.cc index 26acfb70a..49a388a41 100644 --- a/src/internet/test/ipv6-address-helper-test-suite.cc +++ b/src/internet/test/ipv6-address-helper-test-suite.cc @@ -81,9 +81,9 @@ IpAddressHelperTestCasev6::DoRun (void) // Increment network ip1.NewNetwork (); ipAddr1 = ip1.NewAddress (); - NS_TEST_ASSERT_MSG_EQ (ipAddr1, Ipv6Address ("2001:db81:0:1::15"), "Ipv6AddressHelper failure"); + NS_TEST_ASSERT_MSG_EQ (ipAddr1, Ipv6Address ("2001:db82::15"), "Ipv6AddressHelper failure"); // Reset - ip1.SetBase (Ipv6Address ("2001:dddd::"), Ipv6Prefix (32), Ipv6Address ("::1")); + ip1.SetBase (Ipv6Address ("2001:dddd::"), Ipv6Prefix (64), Ipv6Address ("::1")); ipAddr1 = ip1.NewAddress (); // ::1 ipAddr1 = ip1.NewAddress (); // ::2 ipAddr1 = ip1.NewAddress (); // ::3 @@ -93,7 +93,7 @@ IpAddressHelperTestCasev6::DoRun (void) NS_TEST_ASSERT_MSG_EQ (ipAddr1, Ipv6Address ("2001:dddd:0:2::1"), "Ipv6AddressHelper failure"); // Set again - ip1.SetBase (Ipv6Address ("2001:db82::1"), Ipv6Prefix (32)); + ip1.SetBase (Ipv6Address ("2001:db82::"), Ipv6Prefix (32)); ipAddr1 = ip1.NewAddress (); NS_TEST_ASSERT_MSG_EQ (ipAddr1, Ipv6Address ("2001:db82::1"), "Ipv6AddressHelper failure");