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 
43 using 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 
98  void SendOnePacket (Ptr<NetDevice> device, Ipv6Address from, Ipv6Address to);
99 
102 
103 public:
104  virtual void DoRun (void);
106 };
107 
109  : TestCase ("Sixlowpan IPHC stateful implementation")
110 {
111 }
112 
113 bool
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 
132 bool
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 
145 void
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 
160 void
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 
190  Ipv6AddressHelper ipv6;
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 {
320 public:
322 private:
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
void SendOnePacket(Ptr< LrWpanPhy > sender, Ptr< LrWpanPhy > receiver)
Send one packet.
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.