A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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 */
19/**
20 * This is the test code for ipv6-raw-socket-impl.cc.
21 */
22
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
55using namespace ns3;
56
57/**
58 * \ingroup internet-test
59 *
60 * \brief IPv6 RAW Socket Test
61 */
63{
64 Ptr<Packet> m_receivedPacket; //!< Received packet (1).
65 Ptr<Packet> m_receivedPacket2; //!< Received packet (2).
66
67 /**
68 * \brief Send data.
69 * \param socket The sending socket.
70 * \param to Destination address.
71 */
72 void DoSendData(Ptr<Socket> socket, std::string to);
73 /**
74 * \brief Send data.
75 * \param socket The sending socket.
76 * \param to Destination address.
77 */
78 void SendData(Ptr<Socket> socket, std::string to);
79
80 public:
81 void DoRun() override;
83
84 /**
85 * \brief Receive data.
86 * \param socket The receiving socket.
87 * \param packet The received packet.
88 * \param from The sender.
89 */
90 void ReceivePacket(Ptr<Socket> socket, Ptr<Packet> packet, const Address& from);
91 /**
92 * \brief Receive data.
93 * \param socket The receiving socket.
94 * \param packet The received packet.
95 * \param from The sender.
96 */
97 void ReceivePacket2(Ptr<Socket> socket, Ptr<Packet> packet, const Address& from);
98 /**
99 * \brief Receive data.
100 * \param socket The receiving socket.
101 */
102 void ReceivePkt(Ptr<Socket> socket);
103 /**
104 * \brief Receive data.
105 * \param socket The receiving socket.
106 */
107 void ReceivePkt2(Ptr<Socket> socket);
108};
109
111 : TestCase("Ipv6 Raw socket implementation")
112{
113}
114
115void
117{
118 m_receivedPacket = packet;
119}
120
121void
123{
124 m_receivedPacket2 = packet;
125}
126
127void
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");
134 m_receivedPacket = socket->Recv(std::numeric_limits<uint32_t>::max(), 0);
135 NS_TEST_ASSERT_MSG_EQ(availableData,
137 "Received packet size is not equal to Rx buffer size");
138}
139
140void
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");
148 m_receivedPacket2 = socket->RecvFrom(std::numeric_limits<uint32_t>::max(), 0, addr);
149 NS_TEST_ASSERT_MSG_EQ(availableData,
151 "Received packet size is not equal to Rx buffer size");
153 NS_TEST_EXPECT_MSG_EQ(v6addr.GetIpv6(), Ipv6Address("2001:db8::2"), "recvfrom");
154}
155
156void
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
163void
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);
175}
176
177void
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();
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();
246 rxSocket2->SetRecvCallback(MakeCallback(&Ipv6RawSocketImplTest::ReceivePkt2, this));
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();
288 rxSocket2->SetRecvCallback(MakeCallback(&Ipv6RawSocketImplTest::ReceivePkt2, this));
289 rxSocket2->SetAttribute("Protocol", UintegerValue(Ipv6Header::IPV6_ICMPV6));
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(),
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
322}
323
324/**
325 * \ingroup internet-test
326 *
327 * \brief IPv6 RAW Socket TestSuite
328 */
330{
331 public:
333 : TestSuite("ipv6-raw", Type::UNIT)
334 {
335 AddTestCase(new Ipv6RawSocketImplTest, TestCase::Duration::QUICK);
336 }
337};
338
339static Ipv6RawTestSuite g_ipv6rawTestSuite; //!< Static variable for test initialization
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
AttributeValue implementation for Boolean.
Definition: boolean.h:37
An implementation of the ICMPv6 protocol.
An Inet6 address class.
void SetPort(uint16_t port)
Set the port.
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
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
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
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 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
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
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...
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void ScheduleWithContext(uint32_t context, const Time &delay, FUNC f, Ts &&... args)
Schedule an event with the given context.
Definition: simulator.h:588
static void Run()
Run the simulation.
Definition: simulator.cc:178
@ ERROR_NOTCONN
Definition: socket.h:87
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
static constexpr auto UNIT
Definition: test.h:1286
Hold an unsigned integer type.
Definition: uinteger.h:45
#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:145
#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:252
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
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:706