From a05600515e0060f4569c7a1bcdb25c3362e5277d Mon Sep 17 00:00:00 2001 From: Tommaso Pecorella Date: Sun, 30 Jun 2013 14:10:49 +0200 Subject: [PATCH] Bug 1712 - The IP (v4 and v6) forwarding needs a test --- RELEASE_NOTES | 1 + src/internet/test/ipv4-forwarding-test.cc | 221 +++++++++++++++++++++ src/internet/test/ipv6-forwarding-test.cc | 228 ++++++++++++++++++++++ src/internet/wscript | 2 + 4 files changed, 452 insertions(+) create mode 100644 src/internet/test/ipv4-forwarding-test.cc create mode 100644 src/internet/test/ipv6-forwarding-test.cc diff --git a/RELEASE_NOTES b/RELEASE_NOTES index da5dbb191..a4192fbee 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -37,6 +37,7 @@ Bugs fixed - Bug 1700 - Ipv6RawSocket does not honor the bound address when sending packets - Bug 1701 - Ipv6StaticRouting: the source address should match the destination scope - Bug 1703 - Nodes don't react to a DAD +- Bug 1712 - The IP (v4 and v6) forwarding needs a test - Bug 1718 - Ipv4StaticRouting log component is misspelled - Bug 1719 - IPv6 default state is set to not forward packets - Bug 1720 - IPv6 Fragmentation cause crashes diff --git a/src/internet/test/ipv4-forwarding-test.cc b/src/internet/test/ipv4-forwarding-test.cc new file mode 100644 index 000000000..6e43faa1b --- /dev/null +++ b/src/internet/test/ipv4-forwarding-test.cc @@ -0,0 +1,221 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2013 Universita' di Firenze + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Tommaso Pecorella + */ + +#include "ns3/test.h" +#include "ns3/socket-factory.h" +#include "ns3/udp-socket-factory.h" +#include "ns3/simulator.h" +#include "ns3/simple-channel.h" +#include "ns3/simple-net-device.h" +#include "ns3/drop-tail-queue.h" +#include "ns3/socket.h" +#include "ns3/boolean.h" + +#include "ns3/log.h" +#include "ns3/node.h" +#include "ns3/inet-socket-address.h" + +#include "ns3/arp-l3-protocol.h" +#include "ns3/ipv4-l3-protocol.h" +#include "ns3/icmpv4-l4-protocol.h" +#include "ns3/udp-l4-protocol.h" +#include "ns3/ipv4-static-routing.h" + +#include +#include + +using namespace ns3; + +static void +AddInternetStack (Ptr node) +{ + //ARP + Ptr arp = CreateObject (); + node->AggregateObject (arp); + //IPV4 + Ptr ipv4 = CreateObject (); + //Routing for Ipv4 + Ptr ipv4Routing = CreateObject (); + ipv4->SetRoutingProtocol (ipv4Routing); + node->AggregateObject (ipv4); + node->AggregateObject (ipv4Routing); + //ICMP + Ptr icmp = CreateObject (); + node->AggregateObject (icmp); + //UDP + Ptr udp = CreateObject (); + node->AggregateObject (udp); +} + + +class Ipv4ForwardingTest : public TestCase +{ + Ptr m_receivedPacket; + void DoSendData (Ptr socket, std::string to); + void SendData (Ptr socket, std::string to); + +public: + virtual void DoRun (void); + Ipv4ForwardingTest (); + + void ReceivePkt (Ptr socket); +}; + +Ipv4ForwardingTest::Ipv4ForwardingTest () + : TestCase ("UDP socket implementation") +{ +} + +void Ipv4ForwardingTest::ReceivePkt (Ptr socket) +{ + uint32_t availableData; + availableData = socket->GetRxAvailable (); + m_receivedPacket = socket->Recv (std::numeric_limits::max (), 0); + NS_ASSERT (availableData == m_receivedPacket->GetSize ()); +} + +void +Ipv4ForwardingTest::DoSendData (Ptr socket, std::string to) +{ + Address realTo = InetSocketAddress (Ipv4Address (to.c_str ()), 1234); + NS_TEST_EXPECT_MSG_EQ (socket->SendTo (Create (123), 0, realTo), + 123, "XXX"); +} + +void +Ipv4ForwardingTest::SendData (Ptr socket, std::string to) +{ + m_receivedPacket = Create (); + Simulator::ScheduleWithContext (socket->GetNode ()->GetId (), Seconds (0), + &Ipv4ForwardingTest::DoSendData, this, socket, to); + Simulator::Run (); +} + +void +Ipv4ForwardingTest::DoRun (void) +{ + // Create topology + + // Receiver Node + Ptr rxNode = CreateObject (); + AddInternetStack (rxNode); + Ptr rxDev; + { // first interface + rxDev = CreateObject (); + rxDev->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ())); + rxNode->AddDevice (rxDev); + Ptr ipv4 = rxNode->GetObject (); + uint32_t netdev_idx = ipv4->AddInterface (rxDev); + Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("10.0.0.2"), Ipv4Mask (0xffff0000U)); + ipv4->AddAddress (netdev_idx, ipv4Addr); + ipv4->SetUp (netdev_idx); + } + + // Forwarding Node + Ptr fwNode = CreateObject (); + AddInternetStack (fwNode); + Ptr fwDev1, fwDev2; + { // first interface + fwDev1 = CreateObject (); + fwDev1->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ())); + fwNode->AddDevice (fwDev1); + Ptr ipv4 = fwNode->GetObject (); + uint32_t netdev_idx = ipv4->AddInterface (fwDev1); + Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("10.0.0.1"), Ipv4Mask (0xffff0000U)); + ipv4->AddAddress (netdev_idx, ipv4Addr); + ipv4->SetUp (netdev_idx); + } + + { // second interface + fwDev2 = CreateObject (); + fwDev2->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ())); + fwNode->AddDevice (fwDev2); + Ptr ipv4 = fwNode->GetObject (); + uint32_t netdev_idx = ipv4->AddInterface (fwDev2); + Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("10.1.0.1"), Ipv4Mask (0xffff0000U)); + ipv4->AddAddress (netdev_idx, ipv4Addr); + ipv4->SetUp (netdev_idx); + } + + // Sender Node + Ptr txNode = CreateObject (); + AddInternetStack (txNode); + Ptr txDev; + { + txDev = CreateObject (); + txDev->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ())); + txNode->AddDevice (txDev); + Ptr ipv4 = txNode->GetObject (); + uint32_t netdev_idx = ipv4->AddInterface (txDev); + Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("10.1.0.2"), Ipv4Mask (0xffff0000U)); + ipv4->AddAddress (netdev_idx, ipv4Addr); + ipv4->SetUp (netdev_idx); + Ptr ipv4StaticRouting = txNode->GetObject (); + ipv4StaticRouting->SetDefaultRoute(Ipv4Address("10.1.0.1"), netdev_idx); + } + + // link the two nodes + Ptr channel1 = CreateObject (); + rxDev->SetChannel (channel1); + fwDev1->SetChannel (channel1); + + Ptr channel2 = CreateObject (); + fwDev2->SetChannel (channel2); + txDev->SetChannel (channel2); + + // Create the UDP sockets + Ptr rxSocketFactory = rxNode->GetObject (); + Ptr rxSocket = rxSocketFactory->CreateSocket (); + NS_TEST_EXPECT_MSG_EQ (rxSocket->Bind (InetSocketAddress (Ipv4Address ("10.0.0.2"), 1234)), 0, "trivial"); + rxSocket->SetRecvCallback (MakeCallback (&Ipv4ForwardingTest::ReceivePkt, this)); + + Ptr txSocketFactory = txNode->GetObject (); + Ptr txSocket = txSocketFactory->CreateSocket (); + txSocket->SetAllowBroadcast (true); + + // ------ Now the tests ------------ + + // Unicast test + SendData (txSocket, "10.0.0.2"); + NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 123, "IPv4 Forwarding on"); + + m_receivedPacket->RemoveAllByteTags (); + m_receivedPacket = 0; + + Ptr ipv4 = fwNode->GetObject (); + ipv4->SetAttribute("IpForward", BooleanValue (false)); + SendData (txSocket, "10.0.0.2"); + NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 0, "IPv4 Forwarding off"); + + Simulator::Destroy (); + +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +class Ipv4ForwardingTestSuite : public TestSuite +{ +public: + Ipv4ForwardingTestSuite () : TestSuite ("ipv4-forwarding", UNIT) + { + AddTestCase (new Ipv4ForwardingTest, TestCase::QUICK); + } +} g_ipv4forwardingTestSuite; diff --git a/src/internet/test/ipv6-forwarding-test.cc b/src/internet/test/ipv6-forwarding-test.cc new file mode 100644 index 000000000..ba99358ef --- /dev/null +++ b/src/internet/test/ipv6-forwarding-test.cc @@ -0,0 +1,228 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2013 Universita' di Firenze + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Tommaso Pecorella + */ + +#include "ns3/test.h" +#include "ns3/socket-factory.h" +#include "ns3/udp-socket-factory.h" +#include "ns3/simulator.h" +#include "ns3/simple-channel.h" +#include "ns3/simple-net-device.h" +#include "ns3/drop-tail-queue.h" +#include "ns3/socket.h" +#include "ns3/boolean.h" + +#include "ns3/log.h" +#include "ns3/node.h" +#include "ns3/inet6-socket-address.h" + +#include "ns3/ipv6-l3-protocol.h" +#include "ns3/icmpv6-l4-protocol.h" +#include "ns3/udp-l4-protocol.h" +#include "ns3/ipv6-static-routing.h" + +#include +#include + +using namespace ns3; + +static void +AddInternetStack6 (Ptr node) +{ + //IPV6 + Ptr ipv6 = CreateObject (); + //Routing for Ipv6 + Ptr ipv6Routing = CreateObject (); + ipv6->SetRoutingProtocol (ipv6Routing); + node->AggregateObject (ipv6); + node->AggregateObject (ipv6Routing); + //ICMP + Ptr icmp = CreateObject (); + node->AggregateObject (icmp); + //Ipv6 Extensions + ipv6->RegisterExtensions (); + ipv6->RegisterOptions (); + //UDP + Ptr udp = CreateObject (); + node->AggregateObject (udp); +} + + + +class Ipv6ForwardingTest : public TestCase +{ + Ptr m_receivedPacket; + void DoSendData (Ptr socket, std::string to); + void SendData (Ptr socket, std::string to); + +public: + virtual void DoRun (void); + Ipv6ForwardingTest (); + + void ReceivePkt (Ptr socket); +}; + +Ipv6ForwardingTest::Ipv6ForwardingTest () + : TestCase ("UDP6 socket implementation") +{ +} + +void Ipv6ForwardingTest::ReceivePkt (Ptr socket) +{ + uint32_t availableData; + availableData = socket->GetRxAvailable (); + m_receivedPacket = socket->Recv (std::numeric_limits::max (), 0); + NS_ASSERT (availableData == m_receivedPacket->GetSize ()); + //cast availableData to void, to suppress 'availableData' set but not used + //compiler warning + (void) availableData; +} + +void +Ipv6ForwardingTest::DoSendData (Ptr socket, std::string to) +{ + Address realTo = Inet6SocketAddress (Ipv6Address (to.c_str ()), 1234); + NS_TEST_EXPECT_MSG_EQ (socket->SendTo (Create (123), 0, realTo), + 123, "XXX"); +} + +void +Ipv6ForwardingTest::SendData (Ptr socket, std::string to) +{ + m_receivedPacket = Create (); + Simulator::ScheduleWithContext (socket->GetNode ()->GetId (), Seconds (0), + &Ipv6ForwardingTest::DoSendData, this, socket, to); + Simulator::Run (); +} + +void +Ipv6ForwardingTest::DoRun (void) +{ + // Create topology + + // Receiver Node + Ptr rxNode = CreateObject (); + AddInternetStack6 (rxNode); + Ptr rxDev; + { // first interface + rxDev = CreateObject (); + rxDev->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ())); + rxNode->AddDevice (rxDev); + Ptr ipv6 = rxNode->GetObject (); + uint32_t netdev_idx = ipv6->AddInterface (rxDev); + Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (Ipv6Address ("2001:1::2"), Ipv6Prefix (64)); + ipv6->AddAddress (netdev_idx, ipv6Addr); + ipv6->SetUp (netdev_idx); + } + + // Forwarding Node + Ptr fwNode = CreateObject (); + AddInternetStack6 (fwNode); + Ptr fwDev1, fwDev2; + { // first interface + fwDev1 = CreateObject (); + fwDev1->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ())); + fwNode->AddDevice (fwDev1); + Ptr ipv6 = fwNode->GetObject (); + uint32_t netdev_idx = ipv6->AddInterface (fwDev1); + Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (Ipv6Address ("2001:1::1"), Ipv6Prefix (64)); + ipv6->AddAddress (netdev_idx, ipv6Addr); + ipv6->SetUp (netdev_idx); + } + + Ipv6Address nextHop; + { // second interface + fwDev2 = CreateObject (); + fwDev2->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ())); + fwNode->AddDevice (fwDev2); + Ptr ipv6 = fwNode->GetObject (); + uint32_t netdev_idx = ipv6->AddInterface (fwDev2); + Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (Ipv6Address ("2001:2::1"), Ipv6Prefix (64)); + nextHop = ipv6->GetAddress(netdev_idx, 0).GetAddress(); + ipv6->AddAddress (netdev_idx, ipv6Addr); + ipv6->SetUp (netdev_idx); + } + + // Sender Node + Ptr txNode = CreateObject (); + AddInternetStack6 (txNode); + Ptr txDev; + { + txDev = CreateObject (); + txDev->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ())); + txNode->AddDevice (txDev); + Ptr ipv6 = txNode->GetObject (); + uint32_t netdev_idx = ipv6->AddInterface (txDev); + Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (Ipv6Address ("2001:2::2"), Ipv6Prefix (64)); + ipv6->AddAddress (netdev_idx, ipv6Addr); + ipv6->SetUp (netdev_idx); + Ptr ipv6StaticRouting = txNode->GetObject (); + ipv6StaticRouting->SetDefaultRoute(nextHop, netdev_idx); + } + + // link the two nodes + Ptr channel1 = CreateObject (); + rxDev->SetChannel (channel1); + fwDev1->SetChannel (channel1); + + Ptr channel2 = CreateObject (); + fwDev2->SetChannel (channel2); + txDev->SetChannel (channel2); + + // Create the UDP sockets + Ptr rxSocketFactory = rxNode->GetObject (); + Ptr rxSocket = rxSocketFactory->CreateSocket (); + NS_TEST_EXPECT_MSG_EQ (rxSocket->Bind (Inet6SocketAddress (Ipv6Address ("2001:1::2"), 1234)), 0, "trivial"); + rxSocket->SetRecvCallback (MakeCallback (&Ipv6ForwardingTest::ReceivePkt, this)); + + Ptr txSocketFactory = txNode->GetObject (); + Ptr txSocket = txSocketFactory->CreateSocket (); + txSocket->SetAllowBroadcast (true); + + // ------ Now the tests ------------ + + // Unicast test + SendData (txSocket, "2001:1::2"); + NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 123, "IPv6 Forwarding on"); + + m_receivedPacket->RemoveAllByteTags (); + m_receivedPacket = 0; + + Ptr ipv6 = fwNode->GetObject (); + ipv6->SetAttribute("IpForward", BooleanValue (false)); + SendData (txSocket, "2001:1::2"); + NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 0, "IPv6 Forwarding off"); + + m_receivedPacket->RemoveAllByteTags (); + + Simulator::Destroy (); + +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +class Ipv6ForwardingTestSuite : public TestSuite +{ +public: + Ipv6ForwardingTestSuite () : TestSuite ("ipv6-forwarding", UNIT) + { + AddTestCase (new Ipv6ForwardingTest, TestCase::QUICK); + } +} g_ipv6forwardingTestSuite; diff --git a/src/internet/wscript b/src/internet/wscript index f03f51f79..932075fc2 100644 --- a/src/internet/wscript +++ b/src/internet/wscript @@ -201,6 +201,7 @@ def build(bld): 'test/ipv4-raw-test.cc', 'test/ipv4-header-test.cc', 'test/ipv4-fragmentation-test.cc', + 'test/ipv4-forwarding-test.cc', 'test/error-channel.cc', 'test/error-net-device.cc', 'test/ipv4-test.cc', @@ -214,6 +215,7 @@ def build(bld): 'test/ipv6-address-generator-test-suite.cc', 'test/ipv6-dual-stack-test-suite.cc', 'test/ipv6-fragmentation-test.cc', + 'test/ipv6-forwarding-test.cc', 'test/ipv6-address-helper-test-suite.cc', 'test/rtt-test.cc', ]