A Discrete-Event Network Simulator
API
sixlowpan-iphc-stateful-test.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2020 Universita' di Firenze, Italy
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 * Author: Tommaso Pecorella <tommaso.pecorella@unifi.it>
19 */
20
21#include "ns3/test.h"
22#include "ns3/socket-factory.h"
23#include "ns3/simulator.h"
24#include "ns3/socket.h"
25#include "ns3/boolean.h"
26
27#include "ns3/log.h"
28#include "ns3/node.h"
29#include "ns3/inet6-socket-address.h"
30#include "ns3/internet-stack-helper.h"
31#include "ns3/ipv6-address-helper.h"
32#include "ns3/icmpv6-l4-protocol.h"
33
34#include "ns3/sixlowpan-net-device.h"
35#include "ns3/sixlowpan-header.h"
36#include "ns3/sixlowpan-helper.h"
37#include "mock-net-device.h"
38
39#include <string>
40#include <limits>
41#include <vector>
42
43using namespace ns3;
44
51{
55 typedef struct
56 {
60 } Data;
61
62
63 std::vector<Data> m_txPackets;
64 std::vector<Data> m_rxPackets;
65
76 bool ReceiveFromMockDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
77 Address const &source, Address const &destination, NetDevice::PacketType packetType);
78
89 bool PromiscReceiveFromSixLowPanDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
90 Address const &source, Address const &destination, NetDevice::PacketType packetType);
91
99
102
103public:
104 virtual void DoRun (void);
106};
107
109 : TestCase ("Sixlowpan IPHC stateful implementation")
110{
111}
112
113bool
115 Address const &source, Address const &destination, NetDevice::PacketType packetType)
116{
117 Data incomingPkt;
118 incomingPkt.packet = packet->Copy ();
119 incomingPkt.src = source;
120 incomingPkt.dst = destination;
121 m_txPackets.push_back (incomingPkt);
122
123 Ptr<MockNetDevice> mockDev = DynamicCast<MockNetDevice> (m_mockDevices.Get(1));
124 if (mockDev)
125 {
126 uint32_t id = mockDev->GetNode ()->GetId ();
127 Simulator::ScheduleWithContext (id, Time(1), &MockNetDevice::Receive, mockDev, incomingPkt.packet, protocol, destination, source, packetType);
128 }
129 return true;
130}
131
132bool
134 Address const &source, Address const &destination, NetDevice::PacketType packetType)
135{
136 Data incomingPkt;
137 incomingPkt.packet = packet->Copy ();
138 incomingPkt.src = source;
139 incomingPkt.dst = destination;
140 m_rxPackets.push_back (incomingPkt);
141
142 return true;
143}
144
145void
147{
148 Ptr<Packet> pkt = Create<Packet> (10);
149 Ipv6Header ipHdr;
150 ipHdr.SetSource (from);
151 ipHdr.SetDestination (to);
152 ipHdr.SetHopLimit (64);
153 ipHdr.SetPayloadLength (10);
154 ipHdr.SetNextHeader (0xff);
155 pkt->AddHeader (ipHdr);
156
157 device->Send (pkt, Mac48Address ("00:00:00:00:00:02"), 0);
158}
159
160void
162{
164 nodes.Create(2);
165
166 // First node, setup NetDevices.
167 Ptr<MockNetDevice> mockNetDevice0 = CreateObject<MockNetDevice> ();
168 nodes.Get (0)->AddDevice (mockNetDevice0);
169 mockNetDevice0->SetNode (nodes.Get (0));
170 mockNetDevice0->SetAddress (Mac48Address ("00:00:00:00:00:01"));
171 mockNetDevice0->SetMtu (150);
172 mockNetDevice0->SetSendCallback ( MakeCallback (&SixlowpanIphcStatefulImplTest::ReceiveFromMockDevice, this) );
173 m_mockDevices.Add (mockNetDevice0);
174
175 // Second node, setup NetDevices.
176 Ptr<MockNetDevice> mockNetDevice1 = CreateObject<MockNetDevice> ();
177 nodes.Get (1)->AddDevice (mockNetDevice1);
178 mockNetDevice1->SetNode (nodes.Get (1));
179 mockNetDevice1->SetAddress (Mac48Address ("00:00:00:00:00:02"));
180 mockNetDevice1->SetMtu (150);
181 m_mockDevices.Add (mockNetDevice1);
182
183 InternetStackHelper internetv6;
184 internetv6.Install (nodes);
185
186 SixLowPanHelper sixlowpan;
187 m_sixDevices = sixlowpan.Install (m_mockDevices);
189
191 ipv6.SetBase (Ipv6Address ("2001:2::"), Ipv6Prefix (64));
192 Ipv6InterfaceContainer deviceInterfaces;
193 deviceInterfaces = ipv6.Assign (m_sixDevices);
194
195 // This is a hack to prevent Router Solicitations and Duplicate Address Detection being sent.
196 for (auto i = nodes.Begin (); i != nodes.End (); i++)
197 {
198 Ptr<Node> node = *i;
199 Ptr<Ipv6L3Protocol> ipv6L3 = (*i)->GetObject<Ipv6L3Protocol> ();
200 if (ipv6L3)
201 {
202 ipv6L3->SetAttribute ("IpForward", BooleanValue (true));
203 ipv6L3->SetAttribute ("SendIcmpv6Redirect", BooleanValue (false));
204 }
205 Ptr<Icmpv6L4Protocol> icmpv6 = (*i)->GetObject<Icmpv6L4Protocol> ();
206 if (icmpv6)
207 {
208 icmpv6->SetAttribute ("DAD", BooleanValue (false));
209 }
210 }
211
212 sixlowpan.AddContext (m_sixDevices, 0, Ipv6Prefix ("2001:2::", 64), Time (Minutes (30)));
213 sixlowpan.AddContext (m_sixDevices, 1, Ipv6Prefix ("2001:1::", 64), Time (Minutes (30)));
214
215 Ipv6Address srcElided = deviceInterfaces.GetAddress (0, 1);
216 Ipv6Address dstElided = Ipv6Address::MakeAutoconfiguredAddress (Mac48Address ("00:00:00:00:00:02"), Ipv6Prefix ("2001:2::", 64));
217
218 Simulator::Schedule (Seconds (1), &SixlowpanIphcStatefulImplTest::SendOnePacket, this, m_sixDevices.Get (0),
219 Ipv6Address::GetAny (),
220 dstElided);
221
222 Simulator::Schedule (Seconds (2), &SixlowpanIphcStatefulImplTest::SendOnePacket, this, m_sixDevices.Get (0),
223 Ipv6Address ("2001:2::f00d:f00d:cafe:cafe"),
224 Ipv6Address ("2001:1::0000:00ff:fe00:cafe"));
225
226 Simulator::Schedule (Seconds (3), &SixlowpanIphcStatefulImplTest::SendOnePacket, this, m_sixDevices.Get (0),
227 Ipv6Address ("2001:1::0000:00ff:fe00:cafe"),
228 Ipv6Address ("2001:1::f00d:f00d:cafe:cafe"));
229
230 Simulator::Schedule (Seconds (4), &SixlowpanIphcStatefulImplTest::SendOnePacket, this, m_sixDevices.Get (0),
231 srcElided,
232 Ipv6Address ("2001:1::f00d:f00d:cafe:cafe"));
233
234 Simulator::Stop (Seconds (10));
235
236 Simulator::Run ();
237 Simulator::Destroy ();
238
239 // ------ Now the tests ------------
240
241 SixLowPanIphc iphcHdr;
242 Ipv6Header ipv6Hdr;
243
244 // first packet sent, expected CID(0) SAC(1) SAM (0) M(0) DAC(1) DAM (3)
245 m_txPackets[0].packet->RemoveHeader (iphcHdr);
246 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetCid (), false, "CID should be false, is true");
247 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSac (), true, "SAC should be true, is false");
248 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSam (), SixLowPanIphc::HC_INLINE, "SAM should be HC_INLINE, it is not");
249 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetM (), false, "M should be false, is true");
250 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDac (), true, "DAC should be true, is false");
251 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSrcContextId (), 0, "Src context should be 0, it is not");
252 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDstContextId (), 0, "Dst context should be 0, it is not");
253 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDam (), SixLowPanIphc::HC_COMPR_0, "DAM should be HC_COMPR_0, it is not");
254
255 // first packet received, expected :: -> dstElided
256 m_rxPackets[0].packet->RemoveHeader (ipv6Hdr);
257 NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetSource (), Ipv6Address::GetAny (), "Src address wrongly rebuilt");
258 NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetDestination (), dstElided, "Dst address wrongly rebuilt");
259
260 // second packet sent, expected CID(1) SAC(1) SAM (1) M(0) DAC(1) DAM (2)
261 m_txPackets[1].packet->RemoveHeader (iphcHdr);
262 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetCid (), true, "CID should be true, is false");
263 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSac (), true, "SAC should be true, is false");
264 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSam (), SixLowPanIphc::HC_COMPR_64, "SAM should be HC_COMPR_64, it is not");
265 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetM (), false, "M should be false, is true");
266 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDac (), true, "DAC should be true, is false");
267 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSrcContextId (), 0, "Src context should be 0, it is not");
268 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDstContextId (), 1, "Dst context should be 1, it is not");
269 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDam (), SixLowPanIphc::HC_COMPR_16, "DAM should be HC_COMPR_16, it is not");
270
271 // second packet received, expected 2001:2::f00d:f00d:cafe:cafe -> 2001:1::0000:00ff:fe00:cafe
272 m_rxPackets[1].packet->RemoveHeader (ipv6Hdr);
273 NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetSource (), Ipv6Address ("2001:2::f00d:f00d:cafe:cafe"), "Src address wrongly rebuilt");
274 NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetDestination (), Ipv6Address ("2001:1::0000:00ff:fe00:cafe"), "Dst address wrongly rebuilt");
275
276 // third packet sent, expected CID(17) SAC(1) SAM (2) M(0) DAC(1) DAM (1)
277 m_txPackets[2].packet->RemoveHeader (iphcHdr);
278 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetCid (), true, "CID should be true, is false");
279 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSac (), true, "SAC should be true, is false");
280 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSam (), SixLowPanIphc::HC_COMPR_16, "SAM should be HC_COMPR_16, it is not");
281 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetM (), false, "M should be false, is true");
282 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDac (), true, "DAC should be true, is false");
283 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSrcContextId (), 1, "Src context should be 1, it is not");
284 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDstContextId (), 1, "Dst context should be 1, it is not");
285 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDam (), SixLowPanIphc::HC_COMPR_64, "DAM should be HC_COMPR_64, it is not");
286
287 // third packet received, expected 2001:1::0000:00ff:fe00:cafe -> 2001:1::f00d:f00d:cafe:cafe
288 m_rxPackets[2].packet->RemoveHeader (ipv6Hdr);
289 NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetSource (), Ipv6Address ("2001:1::0000:00ff:fe00:cafe"), "Src address wrongly rebuilt");
290 NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetDestination (), Ipv6Address ("2001:1::f00d:f00d:cafe:cafe"), "Dst address wrongly rebuilt");
291
292 // fourth packet sent, expected CID(1) SAC(1) SAM (3) M(0) DAC(1) DAM (1)
293 m_txPackets[3].packet->RemoveHeader (iphcHdr);
294 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetCid (), true, "CID should be true, is false");
295 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSac (), true, "SAC should be true, is false");
296 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSam (), SixLowPanIphc::HC_COMPR_0, "SAM should be HC_COMPR_0, it is not");
297 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetM (), false, "M should be false, is true");
298 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDac (), true, "DAC should be true, is false");
299 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSrcContextId (), 0, "Src context should be 0, it is not");
300 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDstContextId (), 1, "Dst context should be 1, it is not");
301 NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDam (), SixLowPanIphc::HC_COMPR_64, "DAM should be HC_COMPR_64, it is not");
302
303 // fourth packet received, expected srcElided -> 2001:1::f00d:f00d:cafe:cafe
304 m_rxPackets[3].packet->RemoveHeader (ipv6Hdr);
305 NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetSource (), srcElided, "Src address wrongly rebuilt");
306 NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetDestination (), Ipv6Address ("2001:1::f00d:f00d:cafe:cafe"), "Dst address wrongly rebuilt");
307
308 m_rxPackets.clear ();
309 m_txPackets.clear ();
310}
311
312
319{
320public:
322private:
323};
324
326 : TestSuite ("sixlowpan-iphc-stateful", UNIT)
327{
328 AddTestCase (new SixlowpanIphcStatefulImplTest (), TestCase::QUICK);
329}
330
6LoWPAN IPHC stateful compression Test
std::vector< Data > m_txPackets
Transmitted packets.
bool ReceiveFromMockDevice(Ptr< NetDevice > device, Ptr< const Packet > packet, uint16_t protocol, Address const &source, Address const &destination, NetDevice::PacketType packetType)
Receive from a MockDevice.
bool PromiscReceiveFromSixLowPanDevice(Ptr< NetDevice > device, Ptr< const Packet > packet, uint16_t protocol, Address const &source, Address const &destination, NetDevice::PacketType packetType)
Promiscuous receive from a SixLowPanNetDevice.
NetDeviceContainer m_mockDevices
MockNetDevice container.
std::vector< Data > m_rxPackets
Received packets.
void SendOnePacket(Ptr< NetDevice > device, Ipv6Address from, Ipv6Address to)
Send one packet.
NetDeviceContainer m_sixDevices
SixLowPanNetDevice container.
virtual void DoRun(void)
Implementation to actually run this TestCase.
a polymophic address class
Definition: address.h:91
AttributeValue implementation for Boolean.
Definition: boolean.h:37
An implementation of the ICMPv6 protocol.
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.
void SetBase(Ipv6Address network, Ipv6Prefix prefix, Ipv6Address base=Ipv6Address("::1"))
Set the base network number, network prefix, and base interface ID.
Ipv6InterfaceContainer Assign(const NetDeviceContainer &c)
Allocate an Ipv6InterfaceContainer with auto-assigned addresses.
Describes an IPv6 address.
Definition: ipv6-address.h:50
Packet header for IPv6.
Definition: ipv6-header.h:36
void SetDestination(Ipv6Address dst)
Set the "Destination address" field.
Definition: ipv6-header.cc:115
Ipv6Address GetSource(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:105
void SetSource(Ipv6Address src)
Set the "Source address" field.
Definition: ipv6-header.cc:95
void SetHopLimit(uint8_t limit)
Set the "Hop limit" field (TTL).
Definition: ipv6-header.cc:85
void SetPayloadLength(uint16_t len)
Set the "Payload length" field.
Definition: ipv6-header.cc:65
Ipv6Address GetDestination(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:125
void SetNextHeader(uint8_t next)
Set the "Next header" field.
Definition: ipv6-header.cc:75
Keep track of a set of IPv6 interfaces.
Ipv6Address GetAddress(uint32_t i, uint32_t j) const
Get the address for the specified index.
IPv6 layer implementation.
Describes an IPv6 prefix.
Definition: ipv6-address.h:456
an EUI-48 address
Definition: mac48-address.h:44
holds a vector of ns3::NetDevice pointers
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
virtual void SetPromiscReceiveCallback(PromiscReceiveCallback cb)=0
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)=0
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:297
keep track of a set of node pointers.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
Setup a sixlowpan stack to be used as a shim between IPv6 and a generic NetDevice.
NetDeviceContainer Install(NetDeviceContainer c)
Install the SixLoWPAN stack on top of an existing NetDevice.
void AddContext(NetDeviceContainer c, uint8_t contextId, Ipv6Prefix context, Time validity)
Adds a compression Context to a set of NetDevices.
LOWPAN_IPHC base Encoding - see RFC 6282.
bool GetM(void) const
Get the M (Multicast) compression.
bool GetSac(void) const
Get the SAC (Source Address Compression) compression.
bool GetDac(void) const
Get the DAC (Destination Address Compression) compression.
uint8_t GetDstContextId(void) const
Get the DstContextId.
bool GetCid(void) const
Get the CID (Context Identifier Extension) compression.
HeaderCompression_e GetSam(void) const
Get the SAM (Source Address Mode) compression.
HeaderCompression_e GetDam(void) const
Get the DAM (Destination Address Mode) compression.
uint8_t GetSrcContextId(void) const
Get the SrcContextId.
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
#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:240
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Time Minutes(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1236
nodes
Definition: first.py:32
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:793
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
static SixlowpanIphcStatefulTestSuite g_sixlowpanIphcStatefulTestSuite
Static variable for test initialization.
Structure to hold the Rx/Tx packets.