A Discrete-Event Network Simulator
API
ipv6-dual-stack-test-suite.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007 Georgia Tech Research Corporation
3  * Copyright (c) 2009 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Authors: Ken Renard <kenneth.d.renard.ctr@mail.mil>
19  *
20  */
21 
22 #include "ns3/arp-l3-protocol.h"
23 #include "ns3/config.h"
24 #include "ns3/icmpv4-l4-protocol.h"
25 #include "ns3/icmpv6-l4-protocol.h"
26 #include "ns3/inet-socket-address.h"
27 #include "ns3/inet6-socket-address.h"
28 #include "ns3/ipv4-l3-protocol.h"
29 #include "ns3/ipv4-list-routing.h"
30 #include "ns3/ipv4-static-routing.h"
31 #include "ns3/ipv6-l3-protocol.h"
32 #include "ns3/ipv6-list-routing.h"
33 #include "ns3/ipv6-static-routing.h"
34 #include "ns3/log.h"
35 #include "ns3/node.h"
36 #include "ns3/simple-channel.h"
37 #include "ns3/simple-net-device.h"
38 #include "ns3/simulator.h"
39 #include "ns3/socket-factory.h"
40 #include "ns3/tcp-l4-protocol.h"
41 #include "ns3/tcp-socket-factory.h"
42 #include "ns3/test.h"
43 #include "ns3/traffic-control-layer.h"
44 #include "ns3/udp-l4-protocol.h"
45 #include "ns3/uinteger.h"
46 
47 #include <string>
48 
49 using namespace ns3;
50 
51 NS_LOG_COMPONENT_DEFINE("Ipv6DualStackTestSuite");
52 
59 {
60  public:
62 
63  private:
64  void DoRun() override;
65  void DoTeardown() override;
66 
70  void SetUpSim();
71 
74 
80  void ServerHandleConnectionCreated1(Ptr<Socket> s, const Address& addr);
86  void ServerHandleConnectionCreated2(Ptr<Socket> s, const Address& addr);
92  void ServerHandleConnectionCreated3(Ptr<Socket> s, const Address& addr);
98  void ServerHandleConnectionCreated4(Ptr<Socket> s, const Address& addr);
99 
104 
109 
114 };
115 
116 Ptr<Node>
118 {
119  Ptr<Node> node = CreateObject<Node>();
120 
121  // Traffic Control
122  Ptr<TrafficControlLayer> tc = CreateObject<TrafficControlLayer>();
123  node->AggregateObject(tc);
124 
125  // ARP
126  Ptr<ArpL3Protocol> arp = CreateObject<ArpL3Protocol>();
127  node->AggregateObject(arp);
128  arp->SetTrafficControl(tc);
129 
130  // IPV4
131  Ptr<Ipv4L3Protocol> ipv4 = CreateObject<Ipv4L3Protocol>();
132  // Routing for Ipv4
133  Ptr<Ipv4ListRouting> ipv4Routing = CreateObject<Ipv4ListRouting>();
134  ipv4->SetRoutingProtocol(ipv4Routing);
135  Ptr<Ipv4StaticRouting> ipv4staticRouting = CreateObject<Ipv4StaticRouting>();
136  ipv4Routing->AddRoutingProtocol(ipv4staticRouting, 0);
137  node->AggregateObject(ipv4);
138 
139  // ICMPv4
140  Ptr<Icmpv4L4Protocol> icmp = CreateObject<Icmpv4L4Protocol>();
141  node->AggregateObject(icmp);
142 
143  // UDP
144  Ptr<UdpL4Protocol> udp = CreateObject<UdpL4Protocol>();
145  node->AggregateObject(udp);
146 
147  // TCP
148  Ptr<TcpL4Protocol> tcp = CreateObject<TcpL4Protocol>();
149  node->AggregateObject(tcp);
150 
151  // IPV6
152  Ptr<Ipv6L3Protocol> ipv6 = CreateObject<Ipv6L3Protocol>();
153 
154  // Routing for Ipv6
155  Ptr<Ipv6ListRouting> ipv6Routing = CreateObject<Ipv6ListRouting>();
156  ipv6->SetRoutingProtocol(ipv6Routing);
157  Ptr<Ipv6StaticRouting> ipv6staticRouting = CreateObject<Ipv6StaticRouting>();
158  ipv6Routing->AddRoutingProtocol(ipv6staticRouting, 0);
159  node->AggregateObject(ipv6);
160 
161  // ICMPv6
162  Ptr<Icmpv6L4Protocol> icmp6 = CreateObject<Icmpv6L4Protocol>();
163  node->AggregateObject(icmp6);
164 
165  // Ipv6 Extensions
166  ipv6->RegisterExtensions();
167  ipv6->RegisterOptions();
168 
169  return node;
170 }
171 
174  Ipv4Address v4Addr,
175  Ipv4Mask v4Mask,
176  Ipv6Address v6Addr,
177  Ipv6Prefix v6Prefix)
178 {
179  Ptr<SimpleNetDevice> dev = CreateObject<SimpleNetDevice>();
181  node->AddDevice(dev);
182 
183  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
184  uint32_t ndid = ipv4->AddInterface(dev);
185  Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress(v4Addr, v4Mask);
186  ipv4->AddAddress(ndid, ipv4Addr);
187  ipv4->SetUp(ndid);
188 
189  Ptr<Ipv6> ipv6 = node->GetObject<Ipv6>();
190  ndid = ipv6->AddInterface(dev);
191  Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress(v6Addr, v6Prefix);
192  ipv6->AddAddress(ndid, ipv6Addr);
193  ipv6->SetUp(ndid);
194 
195  return dev;
196 }
197 
198 void
200 {
201  node0 = CreateDualStackNode();
202  node1 = CreateDualStackNode();
203 
205  Ipv4Address("10.0.0.1"),
206  Ipv4Mask(0xffffff00),
207  Ipv6Address("2001::1"),
208  Ipv6Prefix(64));
210  Ipv4Address("10.0.0.2"),
211  Ipv4Mask(0xffffff00),
212  Ipv6Address("2001::2"),
213  Ipv6Prefix(64));
214 
215  Ptr<SimpleChannel> channel = CreateObject<SimpleChannel>();
216  dev0->SetChannel(channel);
217  dev1->SetChannel(channel);
218 
219  Ptr<SocketFactory> sockFactory0 = node0->GetObject<TcpSocketFactory>();
220  Ptr<SocketFactory> sockFactory1 = node1->GetObject<TcpSocketFactory>();
221 
222  server1 = sockFactory0->CreateSocket();
223  server2 = sockFactory0->CreateSocket();
224  server3 = sockFactory0->CreateSocket();
225  server4 = sockFactory0->CreateSocket();
226 
227  source1 = sockFactory1->CreateSocket();
228  source2 = sockFactory1->CreateSocket();
229  source3 = sockFactory1->CreateSocket();
230  source4 = sockFactory1->CreateSocket();
231 }
232 
233 void
235 {
236  receivedAddr1 = addr;
237 }
238 
239 void
241 {
242  receivedAddr2 = addr;
243 }
244 
245 void
247 {
248  receivedAddr3 = addr;
249 }
250 
251 void
253 {
254  receivedAddr4 = addr;
255 }
256 
258  : TestCase("DualStackTestCase")
259 {
264 }
265 
266 void
268 {
269  SetUpSim();
270 
271  uint16_t port1 = 5000;
272  uint16_t port2 = 5001;
273  uint16_t port3 = 5002;
274  uint16_t port4 = 5003;
275 
276  /* Server 1: listen on 0.0.0.0 for IPv4 connection */
277  server1->Bind(InetSocketAddress(Ipv4Address::GetAny(), port1));
278  server1->Listen();
280  MakeNullCallback<bool, Ptr<Socket>, const Address&>(),
282 
283  /* Server 2: listen on 0.0.0.0 for IPv4 connection - should reject IPv6 */
284  server2->Bind(InetSocketAddress(Ipv4Address::GetAny(), port2));
285  server2->Listen();
287  MakeNullCallback<bool, Ptr<Socket>, const Address&>(),
289 
290  /* Server 3: listen on :: for IPv4 (mapped into IPv6 address) connection */
291  server3->Bind(Inet6SocketAddress(Ipv6Address::GetAny(), port3));
292  server3->Listen();
294  MakeNullCallback<bool, Ptr<Socket>, const Address&>(),
296 
297  /* Server 4: listen on :: for IPv6 connection */
298  server4->Bind(Inet6SocketAddress(Ipv6Address::GetAny(), port4));
299  server4->Listen();
301  MakeNullCallback<bool, Ptr<Socket>, const Address&>(),
303 
304  /* Source 1: connect to server 1 via IPv4 */
305  source1->Connect(InetSocketAddress(Ipv4Address("10.0.0.1"), port1));
306 
307  /* Source 2: connect to server 2 via IPv6 */
308  source2->Connect(Inet6SocketAddress(Ipv6Address("2001::1"), port2));
309 
310  /* Source 3: connect to server 3 via IPv4 */
311  source3->Connect(InetSocketAddress(Ipv4Address("10.0.0.1"), port3));
312 
313  /* Source 4: connect to server 4 via IPv6 */
314  source4->Connect(Inet6SocketAddress(Ipv6Address("2001::1"), port4));
315 
316  Simulator::Run();
317 
318  /* Server 1: should have connection from Ipv4 address of Node 1 */
319  NS_TEST_EXPECT_MSG_EQ(InetSocketAddress::IsMatchingType(receivedAddr1),
320  true,
321  "Accepted address is of proper type");
322  NS_TEST_EXPECT_MSG_EQ(InetSocketAddress::ConvertFrom(receivedAddr1).GetIpv4(),
323  Ipv4Address("10.0.0.2"),
324  "Accepted address is correct");
325 
326  /* Server 2: should have no connection */
328  true,
329  "IPv4 socket correctly ignored IPv6 connection");
330 
331  /* Server 3: should have connection from Ipv4-mapped IPv6 address of Node 1 */
332  NS_TEST_EXPECT_MSG_EQ(Inet6SocketAddress::IsMatchingType(receivedAddr3),
333  true,
334  "Accepted address is of proper type");
335  NS_TEST_EXPECT_MSG_EQ(Inet6SocketAddress::ConvertFrom(receivedAddr3).GetIpv6(),
336  Ipv6Address("::ffff:0a00:0002"),
337  "Accepted address is correct");
338 
339  /* Server 4: should have connection from IPv6 address of Node 1 */
340  NS_TEST_EXPECT_MSG_EQ(Inet6SocketAddress::IsMatchingType(receivedAddr4),
341  true,
342  "Accepted address is of proper type");
343  NS_TEST_EXPECT_MSG_EQ(Inet6SocketAddress::ConvertFrom(receivedAddr4).GetIpv6(),
344  Ipv6Address("2001::2"),
345  "Accepted address is correct");
346 }
347 
348 void
350 {
351  Simulator::Destroy();
352 }
353 
360 {
361  public:
363  : TestSuite("ipv6-dual-stack", UNIT)
364  {
365  AddTestCase(new DualStackTestCase(), TestCase::QUICK);
366  }
367 };
368 
IPv6 dual stack Test.
void SetUpSim()
Setup the test.
void ServerHandleConnectionCreated1(Ptr< Socket > s, const Address &addr)
Handle connection created (1).
Ptr< Socket > server4
Server socket (4).
Ptr< Socket > server2
Server socket (2).
void ServerHandleConnectionCreated3(Ptr< Socket > s, const Address &addr)
Handle connection created (3).
Address receivedAddr3
Received address (3).
Ptr< Socket > server3
Server socket (3).
void ServerHandleConnectionCreated4(Ptr< Socket > s, const Address &addr)
Handle connection created (4).
Address receivedAddr4
Received address (4).
Ptr< Socket > source1
Sending socket (1).
void ServerHandleConnectionCreated2(Ptr< Socket > s, const Address &addr)
Handle connection created (2).
Ptr< Socket > source2
Sending socket (2).
Ptr< Socket > server1
Server socket (1).
Address receivedAddr2
Received address (2).
void DoRun() override
Implementation to actually run this TestCase.
Address receivedAddr1
Received address (1).
Ptr< Socket > source3
Sending socket (3).
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
Ptr< Socket > source4
Sending socket (4).
IPv6 dual stack TestSuite.
a polymophic address class
Definition: address.h:101
bool IsInvalid() const
Definition: address.cc:71
An Inet6 address class.
an Inet address class
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:80
a class to store IPv4 address information on an interface
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:257
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.
Describes an IPv6 prefix.
Definition: ipv6-address.h:455
static Mac48Address ConvertFrom(const Address &address)
static Mac48Address Allocate()
Allocate a new Mac48Address.
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:138
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:259
void SetAcceptCallback(Callback< bool, Ptr< Socket >, const Address & > connectionRequest, Callback< void, Ptr< Socket >, const Address & > newConnectionCreated)
Accept connection requests from remote hosts.
Definition: socket.cc:105
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
virtual int Listen()=0
Listen for incoming connections.
API to create TCP socket instances.
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
Callback< R, Args... > MakeNullCallback()
Definition: callback.h:747
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#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
Ptr< Node > CreateDualStackNode()
static Ipv6DualStackTestSuite g_ipv6DualStackTestSuite
Static variable for test initialization.
Ptr< SimpleNetDevice > AddSimpleNetDevice(Ptr< Node > node, Ipv4Address v4Addr, Ipv4Mask v4Mask, Ipv6Address v6Addr, Ipv6Prefix v6Prefix)
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
channel
Definition: third.py:88