A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ipv6-dual-stack-test-suite.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007 Georgia Tech Research Corporation
4  * Copyright (c) 2009 INRIA
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Authors: Ken Renard <kenneth.d.renard.ctr@mail.mil>
20  *
21  */
22 
23 #include "ns3/test.h"
24 #include "ns3/socket-factory.h"
25 #include "ns3/tcp-socket-factory.h"
26 #include "ns3/simulator.h"
27 #include "ns3/simple-channel.h"
28 #include "ns3/simple-net-device.h"
29 #include "ns3/config.h"
30 #include "ns3/ipv4-static-routing.h"
31 #include "ns3/ipv4-list-routing.h"
32 #include "ns3/ipv6-static-routing.h"
33 #include "ns3/ipv6-list-routing.h"
34 #include "ns3/node.h"
35 #include "ns3/inet-socket-address.h"
36 #include "ns3/inet6-socket-address.h"
37 #include "ns3/uinteger.h"
38 #include "ns3/log.h"
39 
40 #include "ns3/ipv4-end-point.h"
41 #include "ns3/arp-l3-protocol.h"
42 #include "ns3/ipv4-l3-protocol.h"
43 #include "ns3/ipv6-l3-protocol.h"
44 #include "ns3/icmpv4-l4-protocol.h"
45 #include "ns3/icmpv6-l4-protocol.h"
46 #include "ns3/udp-l4-protocol.h"
47 #include "ns3/tcp-l4-protocol.h"
48 
49 #include <string>
50 
51 NS_LOG_COMPONENT_DEFINE ("Ipv6DualStackTestSuite");
52 
53 using namespace ns3;
54 
56 {
57 public:
59 private:
60  virtual void DoRun (void);
61  virtual void DoTeardown (void);
62 
63  void SetUpSim ();
64  Ptr<Node> node0;
65  Ptr<Node> node1;
66 
67  void ServerHandleConnectionCreated1 (Ptr<Socket> s, const Address & addr);
68  void ServerHandleConnectionCreated2 (Ptr<Socket> s, const Address & addr);
69  void ServerHandleConnectionCreated3 (Ptr<Socket> s, const Address & addr);
70  void ServerHandleConnectionCreated4 (Ptr<Socket> s, const Address & addr);
71 
72  Ptr<Socket> server1;
73  Ptr<Socket> server2;
74  Ptr<Socket> server3;
75  Ptr<Socket> server4;
76 
77  Ptr<Socket> source1;
78  Ptr<Socket> source2;
79  Ptr<Socket> source3;
80  Ptr<Socket> source4;
81 
82  Address receivedAddr1;
83  Address receivedAddr2;
84  Address receivedAddr3;
85  Address receivedAddr4;
86 };
87 
89 CreateDualStackNode ()
90 {
91  Ptr<Node> node = CreateObject<Node> ();
92 
93  //ARP
94  Ptr<ArpL3Protocol> arp = CreateObject<ArpL3Protocol> ();
95  node->AggregateObject (arp);
96 
97  //IPV4
98  Ptr<Ipv4L3Protocol> ipv4 = CreateObject<Ipv4L3Protocol> ();
99  //Routing for Ipv4
100  Ptr<Ipv4ListRouting> ipv4Routing = CreateObject<Ipv4ListRouting> ();
101  ipv4->SetRoutingProtocol (ipv4Routing);
102  Ptr<Ipv4StaticRouting> ipv4staticRouting = CreateObject<Ipv4StaticRouting> ();
103  ipv4Routing->AddRoutingProtocol (ipv4staticRouting, 0);
104  node->AggregateObject (ipv4);
105 
106  //ICMPv4
107  Ptr<Icmpv4L4Protocol> icmp = CreateObject<Icmpv4L4Protocol> ();
108  node->AggregateObject (icmp);
109 
110  //UDP
111  Ptr<UdpL4Protocol> udp = CreateObject<UdpL4Protocol> ();
112  node->AggregateObject (udp);
113 
114  //TCP
115  Ptr<TcpL4Protocol> tcp = CreateObject<TcpL4Protocol> ();
116  node->AggregateObject (tcp);
117 
118  //IPV6
119  Ptr<Ipv6L3Protocol> ipv6 = CreateObject<Ipv6L3Protocol> ();
120 
121  //Routing for Ipv6
122  Ptr<Ipv6ListRouting> ipv6Routing = CreateObject<Ipv6ListRouting> ();
123  ipv6->SetRoutingProtocol (ipv6Routing);
124  Ptr<Ipv6StaticRouting> ipv6staticRouting = CreateObject<Ipv6StaticRouting> ();
125  ipv6Routing->AddRoutingProtocol (ipv6staticRouting, 0);
126  node->AggregateObject (ipv6);
127 
128  //ICMPv6
129  Ptr<Icmpv6L4Protocol> icmp6 = CreateObject<Icmpv6L4Protocol> ();
130  node->AggregateObject (icmp6);
131 
132  //Ipv6 Extensions
133  ipv6->RegisterExtensions ();
134  ipv6->RegisterOptions ();
135 
136  return node;
137 }
138 
140 AddSimpleNetDevice (Ptr<Node> node, Ipv4Address v4Addr, Ipv4Mask v4Mask,
141  Ipv6Address v6Addr, Ipv6Prefix v6Prefix)
142 {
143  Ptr<SimpleNetDevice> dev = CreateObject<SimpleNetDevice> ();
145  node->AddDevice (dev);
146 
147  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
148  uint32_t ndid = ipv4->AddInterface (dev);
149  Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (v4Addr, v4Mask);
150  ipv4->AddAddress (ndid, ipv4Addr);
151  ipv4->SetUp (ndid);
152 
153  Ptr<Ipv6> ipv6 = node->GetObject<Ipv6> ();
154  ndid = ipv6->AddInterface (dev);
155  Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (v6Addr, v6Prefix);
156  ipv6->AddAddress (ndid, ipv6Addr);
157  ipv6->SetUp (ndid);
158 
159  return dev;
160 }
161 
162 void
163 DualStackTestCase::SetUpSim ()
164 {
165  node0 = CreateDualStackNode ();
166  node1 = CreateDualStackNode ();
167 
168  Ptr<SimpleNetDevice> dev0 = AddSimpleNetDevice(node0, Ipv4Address("10.0.0.1"),
169  Ipv4Mask(0xffffff00), Ipv6Address("2001::1"), Ipv6Prefix(64));
170  Ptr<SimpleNetDevice> dev1 = AddSimpleNetDevice(node1, Ipv4Address("10.0.0.2"),
171  Ipv4Mask(0xffffff00), Ipv6Address("2001::2"), Ipv6Prefix(64));
172 
173  Ptr<SimpleChannel> channel = CreateObject<SimpleChannel> ();
174  dev0->SetChannel (channel);
175  dev1->SetChannel (channel);
176 
177  Ptr<SocketFactory> sockFactory0 = node0->GetObject<TcpSocketFactory> ();
178  Ptr<SocketFactory> sockFactory1 = node1->GetObject<TcpSocketFactory> ();
179 
180  server1 = sockFactory0->CreateSocket ();
181  server2 = sockFactory0->CreateSocket ();
182  server3 = sockFactory0->CreateSocket ();
183  server4 = sockFactory0->CreateSocket ();
184 
185  source1 = sockFactory1->CreateSocket ();
186  source2 = sockFactory1->CreateSocket ();
187  source3 = sockFactory1->CreateSocket ();
188  source4 = sockFactory1->CreateSocket ();
189 
190  return;
191 }
192 
193 void
194 DualStackTestCase::ServerHandleConnectionCreated1 (Ptr<Socket> s, const Address & addr)
195 {
196  receivedAddr1 = addr;
197  return;
198 }
199 
200 void
201 DualStackTestCase::ServerHandleConnectionCreated2 (Ptr<Socket> s, const Address & addr)
202 {
203  receivedAddr2 = addr;
204  return;
205 }
206 
207 void
208 DualStackTestCase::ServerHandleConnectionCreated3 (Ptr<Socket> s, const Address & addr)
209 {
210  receivedAddr3 = addr;
211  return;
212 }
213 
214 void
215 DualStackTestCase::ServerHandleConnectionCreated4 (Ptr<Socket> s, const Address & addr)
216 {
217  receivedAddr4 = addr;
218  return;
219 }
220 
221 
222 DualStackTestCase::DualStackTestCase ()
223  : TestCase ("DualStackTestCase")
224 {
225  receivedAddr1 = Address ();
226  receivedAddr2 = Address ();
227  receivedAddr3 = Address ();
228  receivedAddr4 = Address ();
229 }
230 
231 void
233 {
234  SetUpSim ();
235 
236  uint16_t port1 = 5000;
237  uint16_t port2 = 5001;
238  uint16_t port3 = 5002;
239  uint16_t port4 = 5003;
240 
241  /* Server 1: listen on 0.0.0.0 for IPv4 connection */
242  server1->Bind (InetSocketAddress(Ipv4Address::GetAny(), port1));
243  server1->Listen ();
244  server1->SetAcceptCallback (MakeNullCallback<bool, Ptr< Socket >, const Address &> (),
245  MakeCallback (&DualStackTestCase::ServerHandleConnectionCreated1, this));
246 
247  /* Server 2: listen on 0.0.0.0 for IPv4 connection - should reject IPv6 */
248  server2->Bind (InetSocketAddress(Ipv4Address::GetAny(), port2));
249  server2->Listen ();
250  server2->SetAcceptCallback (MakeNullCallback<bool, Ptr< Socket >, const Address &> (),
251  MakeCallback (&DualStackTestCase::ServerHandleConnectionCreated2, this));
252 
253  /* Server 3: listen on :: for IPv4 (mapped into IPv6 address) connection */
254  server3->Bind (Inet6SocketAddress(Ipv6Address::GetAny(), port3));
255  server3->Listen ();
256  server3->SetAcceptCallback (MakeNullCallback<bool, Ptr< Socket >, const Address &> (),
257  MakeCallback (&DualStackTestCase::ServerHandleConnectionCreated3, this));
258 
259  /* Server 4: listen on :: for IPv6 connection */
260  server4->Bind (Inet6SocketAddress(Ipv6Address::GetAny(), port4));
261  server4->Listen ();
262  server4->SetAcceptCallback (MakeNullCallback<bool, Ptr< Socket >, const Address &> (),
263  MakeCallback (&DualStackTestCase::ServerHandleConnectionCreated4, this));
264 
265 
266  /* Source 1: connect to server 1 via IPv4 */
267  source1->Connect(InetSocketAddress(Ipv4Address("10.0.0.1"), port1));
268 
269  /* Source 2: connect to server 2 via IPv6 */
270  source2->Connect(Inet6SocketAddress(Ipv6Address("2001::1"), port2));
271 
272  /* Source 3: connect to server 3 via IPv4 */
273  source3->Connect(InetSocketAddress(Ipv4Address("10.0.0.1"), port3));
274 
275  /* Source 4: connect to server 4 via IPv6 */
276  source4->Connect(Inet6SocketAddress(Ipv6Address("2001::1"), port4));
277 
278  Simulator::Run();
279 
280  /* Server 1: should have connection from Ipv4 address of Node 1 */
281  NS_TEST_EXPECT_MSG_EQ (InetSocketAddress::IsMatchingType(receivedAddr1), true, "Accepted address is of proper type");
282  NS_TEST_EXPECT_MSG_EQ(InetSocketAddress::ConvertFrom(receivedAddr1).GetIpv4 (), Ipv4Address("10.0.0.2"), "Accepted address is correct");
283 
284  /* Server 2: should have no connection */
285  NS_TEST_EXPECT_MSG_EQ(receivedAddr2.IsInvalid(), true, "IPv4 socket correctly ignored IPv6 connection");
286 
287  /* Server 3: should have connection from Ipv4-mapped IPv6 address of Node 1 */
288  NS_TEST_EXPECT_MSG_EQ (Inet6SocketAddress::IsMatchingType(receivedAddr3), true, "Accepted address is of proper type");
289  NS_TEST_EXPECT_MSG_EQ(Inet6SocketAddress::ConvertFrom(receivedAddr3).GetIpv6 (), Ipv6Address("::ffff:0a00:0002"), "Accepted address is correct");
290 
291  /* Server 4: should have connection from IPv6 address of Node 1 */
292  NS_TEST_EXPECT_MSG_EQ (Inet6SocketAddress::IsMatchingType(receivedAddr4), true, "Accepted address is of proper type");
293  NS_TEST_EXPECT_MSG_EQ(Inet6SocketAddress::ConvertFrom(receivedAddr4).GetIpv6 (), Ipv6Address("2001::2"), "Accepted address is correct");
294 }
295 
296 void
298 {
299  Simulator::Destroy ();
300 }
301 
302 
303 static class Ipv6DualStackTestSuite : public TestSuite
304 {
305 public:
307  : TestSuite ("ipv6-dual-stack", UNIT)
308  {
309  AddTestCase (new DualStackTestCase(), TestCase::QUICK);
310  }
311 } g_ipv6DualStackTestSuite;
bool IsInvalid(void) const
Definition: address.cc:68
virtual uint32_t AddInterface(Ptr< NetDevice > device)=0
an Inet address class
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition: ipv6.h:79
API to create TCP socket instances.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:210
A suite of tests to run.
Definition: test.h:962
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
IPv6 address associated with an interface.
virtual Ptr< Socket > CreateSocket(void)=0
encapsulates test code
Definition: test.h:834
TestSuite(std::string name, Type type=UNIT)
Constuct a new test suite.
Definition: test.cc:354
a polymophic address class
Definition: address.h:86
virtual int Listen(void)=0
Listen for incoming connections.
static Mac48Address Allocate(void)
virtual void SetUp(uint32_t interface)=0
An Inet6 address class.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:502
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
Definition: socket.cc:70
void AggregateObject(Ptr< Object > other)
Definition: object.cc:242
static Mac48Address ConvertFrom(const Address &address)
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:75
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
Callback< R > MakeNullCallback(void)
Definition: callback.h:781
void AddTestCase(TestCase *testCase) NS_DEPRECATED
Add an individual test case to this test suite.
Definition: test.cc:172
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:103
virtual void DoTeardown(void)
Implementation to do any local setup required for this test case.
virtual uint32_t AddInterface(Ptr< NetDevice > device)=0
Add a NetDevice interface.
virtual void RegisterExtensions()
Register the IPv6 Extensions.
Describes an IPv6 address.
Definition: ipv6-address.h:44
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
void SetRoutingProtocol(Ptr< Ipv6RoutingProtocol > routingProtocol)
Set routing protocol for this stack.
uint32_t AddDevice(Ptr< NetDevice > device)
Definition: node.cc:119
a class to store IPv4 address information on an interface
virtual void DoRun(void)
Implementation to actually run this test case.
virtual void SetAddress(Address address)
virtual void RegisterOptions()
Register the IPv6 Options.
Describes an IPv6 prefix. It is just a bitmask like Ipv4Mask.
Definition: ipv6-address.h:326
virtual bool AddAddress(uint32_t interface, Ipv4InterfaceAddress address)=0
virtual bool AddAddress(uint32_t interface, Ipv6InterfaceAddress address)=0
Add an address on the specified IPv6 interface.
Ptr< T > GetObject(void) const
Definition: object.h:332
virtual void SetUp(uint32_t interface)=0
Set the interface into the "up" state.
void SetRoutingProtocol(Ptr< Ipv4RoutingProtocol > routingProtocol)
Register a new routing protocol to be used by this Ipv4 stack.