diff --git a/src/internet/test/ipv4-forwarding-test.cc b/src/internet/test/ipv4-forwarding-test.cc index 3200572..f2efd1c 100644 --- a/src/internet/test/ipv4-forwarding-test.cc +++ b/src/internet/test/ipv4-forwarding-test.cc @@ -21,6 +21,7 @@ #include "ns3/test.h" #include "ns3/socket-factory.h" #include "ns3/udp-socket-factory.h" +#include "ns3/tcp-socket-factory.h" #include "ns3/simulator.h" #include "ns3/simple-channel.h" #include "ns3/simple-net-device.h" @@ -36,13 +37,18 @@ #include "ns3/ipv4-l3-protocol.h" #include "ns3/icmpv4-l4-protocol.h" #include "ns3/udp-l4-protocol.h" +#include "ns3/tcp-l4-protocol.h" #include "ns3/ipv4-static-routing.h" +#include "ns3/tcp-socket.h" +#include "ns3/ipv4-address.h" #include #include using namespace ns3; +NS_LOG_COMPONENT_DEFINE ("Ipv4ForwardingTest"); + static void AddInternetStack (Ptr node) { @@ -62,6 +68,9 @@ AddInternetStack (Ptr node) //UDP Ptr udp = CreateObject (); node->AggregateObject (udp); + //UDP + Ptr tcp = CreateObject (); + node->AggregateObject (tcp); } @@ -102,7 +111,6 @@ Ipv4ForwardingTest::DoSendData (Ptr socket, std::string to) 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 (); @@ -181,19 +189,19 @@ Ipv4ForwardingTest::DoRun (void) 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 udpRxSocketFactory = rxNode->GetObject (); + Ptr udpRxSocket = udpRxSocketFactory->CreateSocket (); + NS_TEST_EXPECT_MSG_EQ (udpRxSocket->Bind (InetSocketAddress (Ipv4Address ("10.0.0.2"), 1234)), 0, "trivial"); + udpRxSocket->SetRecvCallback (MakeCallback (&Ipv4ForwardingTest::ReceivePkt, this)); - Ptr txSocketFactory = txNode->GetObject (); - Ptr txSocket = txSocketFactory->CreateSocket (); - txSocket->SetAllowBroadcast (true); + Ptr udpTxSocketFactory = txNode->GetObject (); + Ptr udpTxSocket = udpTxSocketFactory->CreateSocket (); + udpTxSocket->SetAllowBroadcast (true); // ------ Now the tests ------------ // Unicast test - SendData (txSocket, "10.0.0.2"); + SendData (udpTxSocket, "10.0.0.2"); NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 123, "IPv4 Forwarding on"); m_receivedPacket->RemoveAllByteTags (); @@ -201,9 +209,267 @@ Ipv4ForwardingTest::DoRun (void) 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"); + SendData (udpTxSocket, "10.0.0.2"); + NS_TEST_EXPECT_MSG_EQ (m_receivedPacket, 0, "IPv4 Forwarding off; no received packet"); + + Simulator::Destroy (); + +} + +class Ipv4BindToNetDeviceTest : public TestCase +{ + Ptr m_receivedPacket; + void DoSendData (Ptr socket, std::string to, int expectedReturnValue); + void SendData (Ptr socket, std::string to, int expectedReturnValue); + //, std::string to, int expectedReturnValue + void OnConnection (Ptr socket +// , const ns3::Address& + ); + +public: + virtual void DoRun (void); + Ipv4BindToNetDeviceTest (); + + void ReceivePkt (Ptr socket); +}; + +Ipv4BindToNetDeviceTest::Ipv4BindToNetDeviceTest () + : TestCase ("Test that Socket::BindToNetDevice () works") +{ +} + +void Ipv4BindToNetDeviceTest::ReceivePkt (Ptr socket) +{ + NS_LOG_DEBUG ("Recv cb"); + uint32_t availableData; + availableData = socket->GetRxAvailable (); + m_receivedPacket = socket->Recv (std::numeric_limits::max (), 0); + NS_ASSERT (availableData == m_receivedPacket->GetSize ()); +} + +void +Ipv4BindToNetDeviceTest::DoSendData (Ptr socket, std::string to, int expectedReturnValue) +{ + Address realTo = InetSocketAddress (Ipv4Address (to.c_str ()), 1234); + NS_TEST_EXPECT_MSG_EQ (socket->SendTo (Create (123), 0, realTo), + expectedReturnValue, "SendTo failure"); +} + +void +Ipv4BindToNetDeviceTest::SendData (Ptr socket, std::string to, int expectedReturnValue) +{ + Simulator::ScheduleWithContext (socket->GetNode ()->GetId (), Seconds (0), + &Ipv4BindToNetDeviceTest::DoSendData, this, socket, to, expectedReturnValue); +} + + +void +Ipv4BindToNetDeviceTest::OnConnection (Ptr socket +// , const ns3::Address& + ) +{ + NS_LOG_DEBUG ("Send connection"); + int ret = socket->Send(Create (123)); + NS_TEST_EXPECT_MSG_EQ ( ret, 0, "Could not send packet"); +} + +void +Ipv4BindToNetDeviceTest::DoRun (void) +{ + /** Create topology + ________________________________________ + | txNode | + | txDev1 (10.0.0.1) | txDev2 (11.0.0.1) | + |___________________|___________________| + | | + | | + | | + | | + ________________________________________ + | rxNode | + | rxDev1 (10.0.0.2) | rxDev2 (11.0.0.2) | + |___________________|___________________| + **/ + + // Receiver Node + Ptr rxNode = CreateObject (); + AddInternetStack (rxNode); + Ptr rxDev1; + Ptr rxDev2; + { // first interface + rxDev1 = CreateObject (); + rxDev1->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ())); + rxNode->AddDevice (rxDev1); + Ptr ipv4 = rxNode->GetObject (); + uint32_t netdev_idx = ipv4->AddInterface (rxDev1); + Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("10.0.0.2"), Ipv4Mask (0xffff0000U)); + ipv4->AddAddress (netdev_idx, ipv4Addr); + ipv4->SetUp (netdev_idx); + } + { // second interface + rxDev2 = CreateObject (); + rxDev2->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ())); + rxNode->AddDevice (rxDev2); + Ptr ipv4 = rxNode->GetObject (); + uint32_t netdev_idx = ipv4->AddInterface (rxDev2); + Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("11.0.0.2"), Ipv4Mask (0xffff0000U)); + ipv4->AddAddress (netdev_idx, ipv4Addr); + ipv4->SetUp (netdev_idx); + } + + // Sender Node + Ptr txNode = CreateObject (); + AddInternetStack (txNode); + Ptr txDev1; + Ptr txDev2; + { + // first interface + txDev1 = CreateObject (); + txDev1->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ())); + txNode->AddDevice (txDev1); + Ptr ipv4 = txNode->GetObject (); + uint32_t netdev_idx = ipv4->AddInterface (txDev1); + Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("10.0.0.1"), Ipv4Mask (0xffff0000U)); + ipv4->AddAddress (netdev_idx, ipv4Addr); + ipv4->SetUp (netdev_idx); + } + { + // second interface + txDev2 = CreateObject (); + txDev2->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ())); + txNode->AddDevice (txDev2); + Ptr ipv4 = txNode->GetObject (); + uint32_t netdev_idx = ipv4->AddInterface (txDev2); + Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("11.0.0.1"), Ipv4Mask (0xffff0000U)); + ipv4->AddAddress (netdev_idx, ipv4Addr); + ipv4->SetUp (netdev_idx); + } + + // link the two nodes + Ptr channel1 = CreateObject (); + rxDev1->SetChannel (channel1); + txDev1->SetChannel (channel1); + + Ptr channel2 = CreateObject (); + rxDev2->SetChannel (channel2); + txDev2->SetChannel (channel2); + + // Create the UDP sockets + Ptr udpRxSocketFactory = rxNode->GetObject (); + Ptr udpRxSocket = udpRxSocketFactory->CreateSocket (); + NS_TEST_EXPECT_MSG_EQ (udpRxSocket->Bind (InetSocketAddress (Ipv4Address ("10.0.0.2"), 1234)), 0, "trivial"); + // Must call BindToNetDevice() after Bind() + udpRxSocket->SetRecvCallback (MakeCallback (&Ipv4BindToNetDeviceTest::ReceivePkt, this)); + + Ptr udpTxSocketFactory = txNode->GetObject (); + Ptr udpTxSocket = udpTxSocketFactory->CreateSocket (); + udpTxSocket->SetAllowBroadcast (true); + + // Create the TCP sockets + Ptr tcpRxSocketFactory = rxNode->GetObject (); + Ptr tcpRxSocket = tcpRxSocketFactory->CreateSocket (); + NS_TEST_EXPECT_MSG_EQ (tcpRxSocket->Bind (InetSocketAddress (Ipv4Address ("10.0.0.2"), 1234)), 0, "trivial"); + // Must call BindToNetDevice() after Bind() + tcpRxSocket->SetRecvCallback (MakeCallback (&Ipv4BindToNetDeviceTest::ReceivePkt, this)); + + Ptr tcpTxSocketFactory = txNode->GetObject (); +// Ptr tcpTxSocket = DynamicCast(tcpTxSocketFactory->CreateSocket () ); + Ptr tcpTxSocket = tcpTxSocketFactory->CreateSocket (); +// tcpTxSocket->SetAllowBroadcast (true); + + // ------ Now the UDP tests ------------ + + // Test that data is successful when RxNode binds to rxDev1 and TxNode binds + // to txDev1 + NS_LOG_DEBUG ("Bind test case 1"); + udpRxSocket->BindToNetDevice (rxDev1); + udpTxSocket->BindToNetDevice (txDev1); + SendData (udpTxSocket, "10.0.0.2", 123); // 123 is the expected Send() return value + Simulator::Run (); + NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 123, "Correctly bound NetDevices"); + m_receivedPacket = 0; + + // All three other bind combinations should fail + + NS_LOG_DEBUG ("Bind test case 2"); + udpTxSocket = udpTxSocketFactory->CreateSocket (); + udpRxSocket->BindToNetDevice (rxDev1); + udpTxSocket->BindToNetDevice (txDev2); + SendData (udpTxSocket, "10.0.0.2", -1); + Simulator::Run (); + NS_TEST_EXPECT_MSG_EQ (m_receivedPacket, 0, "No received packet"); + + NS_LOG_DEBUG ("Bind test case 3"); + udpTxSocket = udpTxSocketFactory->CreateSocket (); + udpRxSocket->BindToNetDevice (rxDev2); + udpTxSocket->BindToNetDevice (txDev2); + SendData (udpTxSocket, "10.0.0.2", -1); + Simulator::Run (); + NS_TEST_EXPECT_MSG_EQ (m_receivedPacket, 0, "No received packet"); + + NS_LOG_DEBUG ("Bind test case 4"); + udpTxSocket = udpTxSocketFactory->CreateSocket (); + udpRxSocket->BindToNetDevice (rxDev2); + udpTxSocket->BindToNetDevice (txDev1); + SendData (udpTxSocket, "10.0.0.2", 123); + Simulator::Run (); + NS_TEST_EXPECT_MSG_EQ (m_receivedPacket, 0, "No received packet"); + + // ------ Now the TCP tests ------------ + + // Test that data is successful when RxNode binds to rxDev1 and TxNode binds + // to txDev1 + NS_LOG_DEBUG ("Bind test case 1"); + InetSocketAddress serverAddr ("11.0.0.2", 1234 ); + InetSocketAddress clientAddr ("11.0.0.1", 4321 ); + +// tcpRxSocket->BindToNetDevice (rxDev1); +// tcpTxSocket->BindToNetDevice (txDev1); + tcpTxSocket->Bind( clientAddr ); +// tcpRxSocket->SetAcceptCallback( MakeNullCallback, const ns3::Address& > (), +// MakeCallback(&Ipv4BindToNetDeviceTest::OnConnection, this) ); + + tcpTxSocket->SetConnectCallback ( MakeCallback(&Ipv4BindToNetDeviceTest::OnConnection, this), + MakeNullCallback > () + ); + + tcpTxSocket->Connect( serverAddr ); + //! Make sure packet can only travel through channel2 + channel1->BlackList(txDev1, rxDev1); + +// SendData (tcpTxSocket, "10.0.0.2", 123); // 123 is the expected Send() return value + + Simulator::Run (); + NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 123, "Correctly bound NetDevices"); + m_receivedPacket = 0; + + // All three other bind combinations should fail + +// NS_LOG_DEBUG ("Bind test case 2"); +// tcpTxSocket = tcpTxSocketFactory->CreateSocket (); +// tcpRxSocket->BindToNetDevice (rxDev1); +// tcpTxSocket->BindToNetDevice (txDev2); +// SendData (tcpTxSocket, "10.0.0.2", -1); +// Simulator::Run (); +// NS_TEST_EXPECT_MSG_EQ (m_receivedPacket, 0, "No received packet"); +// +// NS_LOG_DEBUG ("Bind test case 3"); +// tcpTxSocket = tcpTxSocketFactory->CreateSocket (); +// tcpRxSocket->BindToNetDevice (rxDev2); +// tcpTxSocket->BindToNetDevice (txDev2); +// SendData (tcpTxSocket, "10.0.0.2", -1); +// Simulator::Run (); +// NS_TEST_EXPECT_MSG_EQ (m_receivedPacket, 0, "No received packet"); +// +// NS_LOG_DEBUG ("Bind test case 4"); +// tcpTxSocket = tcpTxSocketFactory->CreateSocket (); +// tcpRxSocket->BindToNetDevice (rxDev2); +// tcpTxSocket->BindToNetDevice (txDev1); +// SendData (tcpTxSocket, "10.0.0.2", 123); +// Simulator::Run (); +// NS_TEST_EXPECT_MSG_EQ (m_receivedPacket, 0, "No received packet"); + Simulator::Destroy (); } @@ -217,5 +483,6 @@ public: Ipv4ForwardingTestSuite () : TestSuite ("ipv4-forwarding", UNIT) { AddTestCase (new Ipv4ForwardingTest, TestCase::QUICK); + AddTestCase (new Ipv4BindToNetDeviceTest, TestCase::QUICK); } } g_ipv4forwardingTestSuite;