A Discrete-Event Network Simulator
API
ipv6-raw-test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Hajime Tazaki
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Hajime Tazaki <tazaki@sfc.wide.ad.jp>
18  */
23 #include "ns3/boolean.h"
24 #include "ns3/icmpv6-l4-protocol.h"
25 #include "ns3/inet6-socket-address.h"
26 #include "ns3/internet-stack-helper.h"
27 #include "ns3/ipv6-address-helper.h"
28 #include "ns3/ipv6-l3-protocol.h"
29 #include "ns3/ipv6-list-routing.h"
30 #include "ns3/ipv6-raw-socket-factory.h"
31 #include "ns3/ipv6-static-routing.h"
32 #include "ns3/log.h"
33 #include "ns3/node-container.h"
34 #include "ns3/node.h"
35 #include "ns3/simple-channel.h"
36 #include "ns3/simple-net-device-helper.h"
37 #include "ns3/simple-net-device.h"
38 #include "ns3/simulator.h"
39 #include "ns3/socket-factory.h"
40 #include "ns3/socket.h"
41 #include "ns3/test.h"
42 #include "ns3/uinteger.h"
43 
44 #ifdef __WIN32__
45 #include "ns3/win32-internet.h"
46 #else
47 #include <netinet/in.h>
48 #include <sys/socket.h>
49 #endif
50 
51 #include <limits>
52 #include <string>
53 #include <sys/types.h>
54 
55 using namespace ns3;
56 
63 {
66 
72  void DoSendData(Ptr<Socket> socket, std::string to);
78  void SendData(Ptr<Socket> socket, std::string to);
79 
80  public:
81  void DoRun() override;
83 
90  void ReceivePacket(Ptr<Socket> socket, Ptr<Packet> packet, const Address& from);
97  void ReceivePacket2(Ptr<Socket> socket, Ptr<Packet> packet, const Address& from);
102  void ReceivePkt(Ptr<Socket> socket);
107  void ReceivePkt2(Ptr<Socket> socket);
108 };
109 
111  : TestCase("Ipv6 Raw socket implementation")
112 {
113 }
114 
115 void
117 {
118  m_receivedPacket = packet;
119 }
120 
121 void
123 {
124  m_receivedPacket2 = packet;
125 }
126 
127 void
129 {
130  uint32_t availableData;
131  availableData = socket->GetRxAvailable();
132  m_receivedPacket = socket->Recv(2, MSG_PEEK);
133  NS_TEST_ASSERT_MSG_EQ(m_receivedPacket->GetSize(), 2, "ReceivedPacket size is not equal to 2");
135  NS_TEST_ASSERT_MSG_EQ(availableData,
137  "Received packet size is not equal to Rx buffer size");
138 }
139 
140 void
142 {
143  uint32_t availableData;
144  Address addr;
145  availableData = socket->GetRxAvailable();
146  m_receivedPacket2 = socket->Recv(2, MSG_PEEK);
147  NS_TEST_ASSERT_MSG_EQ(m_receivedPacket2->GetSize(), 2, "ReceivedPacket size is not equal to 2");
149  NS_TEST_ASSERT_MSG_EQ(availableData,
151  "Received packet size is not equal to Rx buffer size");
152  Inet6SocketAddress v6addr = Inet6SocketAddress::ConvertFrom(addr);
153  NS_TEST_EXPECT_MSG_EQ(v6addr.GetIpv6(), Ipv6Address("2001:db8::2"), "recvfrom");
154 }
155 
156 void
158 {
159  Address realTo = Inet6SocketAddress(Ipv6Address(to.c_str()), 0);
160  NS_TEST_EXPECT_MSG_EQ(socket->SendTo(Create<Packet>(123), 0, realTo), 123, to);
161 }
162 
163 void
165 {
166  m_receivedPacket = Create<Packet>();
167  m_receivedPacket2 = Create<Packet>();
168  Simulator::ScheduleWithContext(socket->GetNode()->GetId(),
169  Seconds(0),
171  this,
172  socket,
173  to);
174  Simulator::Run();
175 }
176 
177 void
179 {
180  // Create topology
181 
182  // Receiver Node
183  Ptr<Node> rxNode = CreateObject<Node>();
184  // Sender Node
185  Ptr<Node> txNode = CreateObject<Node>();
186 
187  NodeContainer nodes(rxNode, txNode);
188 
189  SimpleNetDeviceHelper helperChannel1;
190  helperChannel1.SetNetDevicePointToPointMode(true);
191  NetDeviceContainer net1 = helperChannel1.Install(nodes);
192 
193  SimpleNetDeviceHelper helperChannel2;
194  helperChannel2.SetNetDevicePointToPointMode(true);
195  NetDeviceContainer net2 = helperChannel2.Install(nodes);
196 
197  InternetStackHelper internetv6;
198  internetv6.Install(nodes);
199 
200  txNode->GetObject<Icmpv6L4Protocol>()->SetAttribute("DAD", BooleanValue(false));
201  rxNode->GetObject<Icmpv6L4Protocol>()->SetAttribute("DAD", BooleanValue(false));
202 
203  Ipv6AddressHelper ipv6helper;
204  Ipv6InterfaceContainer iic1 = ipv6helper.AssignWithoutAddress(net1);
205  Ipv6InterfaceContainer iic2 = ipv6helper.AssignWithoutAddress(net2);
206 
207  Ptr<NetDevice> device;
208  Ptr<Ipv6> ipv6;
209  int32_t ifIndex;
210  Ipv6InterfaceAddress ipv6Addr;
211 
212  ipv6 = rxNode->GetObject<Ipv6>();
213  device = net1.Get(0);
214  ifIndex = ipv6->GetInterfaceForDevice(device);
215  ipv6Addr = Ipv6InterfaceAddress(Ipv6Address("2001:db8::1"), Ipv6Prefix(64));
216  ipv6->AddAddress(ifIndex, ipv6Addr);
217 
218  device = net2.Get(0);
219  ifIndex = ipv6->GetInterfaceForDevice(device);
220  ipv6Addr = Ipv6InterfaceAddress(Ipv6Address("2001:db8:1::3"), Ipv6Prefix(64));
221  ipv6->AddAddress(ifIndex, ipv6Addr);
222 
223  ipv6 = txNode->GetObject<Ipv6>();
224  device = net1.Get(1);
225  ifIndex = ipv6->GetInterfaceForDevice(device);
226  ipv6Addr = Ipv6InterfaceAddress(Ipv6Address("2001:db8::2"), Ipv6Prefix(64));
227  ipv6->AddAddress(ifIndex, ipv6Addr);
228  ipv6->SetForwarding(ifIndex, true);
229 
230  device = net2.Get(1);
231  ifIndex = ipv6->GetInterfaceForDevice(device);
232  ipv6Addr = Ipv6InterfaceAddress(Ipv6Address("2001:db8:1::4"), Ipv6Prefix(64));
233  ipv6->AddAddress(ifIndex, ipv6Addr);
234  ipv6->SetForwarding(ifIndex, true);
235 
236  // Create the Ipv6 Raw sockets
237  Ptr<SocketFactory> rxSocketFactory = rxNode->GetObject<Ipv6RawSocketFactory>();
238  Ptr<Socket> rxSocket = rxSocketFactory->CreateSocket();
239  NS_TEST_EXPECT_MSG_EQ(rxSocket->Bind(Inet6SocketAddress(Ipv6Address::GetAny(), 0)),
240  0,
241  "trivial");
242  rxSocket->SetAttribute("Protocol", UintegerValue(Ipv6Header::IPV6_ICMPV6));
243  rxSocket->SetRecvCallback(MakeCallback(&Ipv6RawSocketImplTest::ReceivePkt, this));
244 
245  Ptr<Socket> rxSocket2 = rxSocketFactory->CreateSocket();
247  rxSocket2->SetAttribute("Protocol", UintegerValue(Ipv6Header::IPV6_ICMPV6));
248  NS_TEST_EXPECT_MSG_EQ(rxSocket2->Bind(Inet6SocketAddress(Ipv6Address("2001:db8:1::3"), 0)),
249  0,
250  "trivial");
251 
252  Ptr<SocketFactory> txSocketFactory = txNode->GetObject<Ipv6RawSocketFactory>();
253  Ptr<Socket> txSocket = txSocketFactory->CreateSocket();
254  txSocket->SetAttribute("Protocol", UintegerValue(Ipv6Header::IPV6_ICMPV6));
255 
256  // ------ Now the tests ------------
257 
258  // Unicast test
259  SendData(txSocket, "2001:db8::1");
260 
261  NS_TEST_EXPECT_MSG_EQ(m_receivedPacket->GetSize(), 163, "recv: 2001:db8::1");
263  0,
264  "second interface should not receive it");
265 
268 
269  // Simple Link-local multicast test
270  txSocket->Bind(Inet6SocketAddress(Ipv6Address("2001:db8::2"), 0));
271  SendData(txSocket, "ff02::1");
272  NS_TEST_EXPECT_MSG_EQ(m_receivedPacket->GetSize(), 163, "recv: ff02::1");
274  0,
275  "second socket should not receive it (it is bound specifically to the "
276  "second interface's address");
277 
280 
281  // Broadcast test with multiple receiving sockets
282 
283  // When receiving broadcast packets, all sockets sockets bound to
284  // the address/port should receive a copy of the same packet -- if
285  // the socket address matches.
286  rxSocket2->Dispose();
287  rxSocket2 = rxSocketFactory->CreateSocket();
289  rxSocket2->SetAttribute("Protocol", UintegerValue(Ipv6Header::IPV6_ICMPV6));
290  NS_TEST_EXPECT_MSG_EQ(rxSocket2->Bind(Inet6SocketAddress(Ipv6Address::GetAny(), 0)),
291  0,
292  "trivial");
293 
294  SendData(txSocket, "ff02::1");
295  NS_TEST_EXPECT_MSG_EQ(m_receivedPacket->GetSize(), 163, "recv: ff02::1");
296  NS_TEST_EXPECT_MSG_EQ(m_receivedPacket2->GetSize(), 163, "recv: ff02::1");
297 
298  m_receivedPacket = nullptr;
299  m_receivedPacket2 = nullptr;
300 
301  // Simple getpeername tests
302 
303  Address peerAddress;
304  int err = txSocket->GetPeerName(peerAddress);
305  NS_TEST_EXPECT_MSG_EQ(err, -1, "socket GetPeerName() should fail when socket is not connected");
306  NS_TEST_EXPECT_MSG_EQ(txSocket->GetErrno(),
307  Socket::ERROR_NOTCONN,
308  "socket error code should be ERROR_NOTCONN");
309 
310  Inet6SocketAddress peer("2001:db8::1", 1234);
311  err = txSocket->Connect(peer);
312  NS_TEST_EXPECT_MSG_EQ(err, 0, "socket Connect() should succeed");
313 
314  err = txSocket->GetPeerName(peerAddress);
315  NS_TEST_EXPECT_MSG_EQ(err, 0, "socket GetPeerName() should succeed when socket is connected");
316  peer.SetPort(0);
317  NS_TEST_EXPECT_MSG_EQ(peerAddress,
318  peer,
319  "address from socket GetPeerName() should equal the connected address");
320 
321  Simulator::Destroy();
322 }
323 
330 {
331  public:
333  : TestSuite("ipv6-raw", UNIT)
334  {
335  AddTestCase(new Ipv6RawSocketImplTest, TestCase::QUICK);
336  }
337 };
338 
#define max(a, b)
Definition: 80211b.c:42
IPv6 RAW Socket Test.
Ptr< Packet > m_receivedPacket2
Received packet (2).
Ptr< Packet > m_receivedPacket
Received packet (1).
void ReceivePacket2(Ptr< Socket > socket, Ptr< Packet > packet, const Address &from)
Receive data.
void ReceivePkt2(Ptr< Socket > socket)
Receive data.
void DoRun() override
Implementation to actually run this TestCase.
void DoSendData(Ptr< Socket > socket, std::string to)
Send data.
void ReceivePkt(Ptr< Socket > socket)
Receive data.
void ReceivePacket(Ptr< Socket > socket, Ptr< Packet > packet, const Address &from)
Receive data.
void SendData(Ptr< Socket > socket, std::string to)
Send data.
IPv6 RAW Socket TestSuite.
a polymophic address class
Definition: address.h:101
An implementation of the ICMPv6 protocol.
An Inet6 address class.
void SetPort(uint16_t port)
Set the port.
Ipv6Address GetIpv6() const
Get the IPv6 address.
aggregate IP/TCP/UDP functionality to existing Nodes.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
Helper class to auto-assign global IPv6 unicast addresses.
Describes an IPv6 address.
Definition: ipv6-address.h:49
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition: ipv6.h:82
IPv6 address associated with an interface.
Keep track of a set of IPv6 interfaces.
Describes an IPv6 prefix.
Definition: ipv6-address.h:455
API to create IPv6 RAW socket instances.
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
keep track of a set of node pointers.
uint32_t GetId() const
Definition: node.cc:117
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:204
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
void Dispose()
Dispose of this Object.
Definition: object.cc:219
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
void RemoveAllByteTags()
Remove all byte tags stored in this packet.
Definition: packet.cc:393
build a set of SimpleNetDevice objects
void SetNetDevicePointToPointMode(bool pointToPointMode)
SimpleNetDevice is Broadcast capable and ARP needing.
NetDeviceContainer Install(Ptr< Node > node) const
This method creates an ns3::SimpleChannel with the attributes configured by SimpleNetDeviceHelper::Se...
virtual uint32_t GetRxAvailable() const =0
Return number of bytes which can be returned from one or multiple calls to Recv.
void SetRecvCallback(Callback< void, Ptr< Socket >> receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:128
virtual Ptr< Packet > Recv(uint32_t maxSize, uint32_t flags)=0
Read data from the socket.
virtual Ptr< Node > GetNode() const =0
Return the node this socket is associated with.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)=0
Read a single packet from the socket and retrieve the sender address.
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
@ UNIT
This test suite implements a Unit Test.
Definition: test.h:1265
Hold an unsigned integer type.
Definition: uinteger.h:45
void ReceivePacket(Ptr< Socket > socket)
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:251
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
static Ipv6RawTestSuite g_ipv6rawTestSuite
Static variable for test initialization.
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704