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 
58 {
62  typedef struct
63  {
67  } Data;
68 
69 
70  std::vector<Data> m_txPackets;
71  std::vector<Data> m_rxPackets;
72 
83  bool ReceiveFromMockDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
84  Address const &source, Address const &destination, NetDevice::PacketType packetType);
85 
96  bool PromiscReceiveFromSixLowPanDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
97  Address const &source, Address const &destination, NetDevice::PacketType packetType);
98 
105  void SendOnePacket (Ptr<NetDevice> device, Ipv6Address from, Ipv6Address to);
106 
109 
110 public:
111  virtual void DoRun (void);
113 };
114 
116  : TestCase ("Sixlowpan IPHC stateful implementation")
117 {
118 }
119 
120 bool
122  Address const &source, Address const &destination, NetDevice::PacketType packetType)
123 {
124  Data incomingPkt;
125  incomingPkt.packet = packet->Copy ();
126  incomingPkt.src = source;
127  incomingPkt.dst = destination;
128  m_txPackets.push_back (incomingPkt);
129 
130  Ptr<MockNetDevice> mockDev = DynamicCast<MockNetDevice> (m_mockDevices.Get(1));
131  if (mockDev)
132  {
133  uint32_t id = mockDev->GetNode ()->GetId ();
134  Simulator::ScheduleWithContext (id, Time(1), &MockNetDevice::Receive, mockDev, incomingPkt.packet, protocol, destination, source, packetType);
135  }
136  return true;
137 }
138 
139 bool
141  Address const &source, Address const &destination, NetDevice::PacketType packetType)
142 {
143  Data incomingPkt;
144  incomingPkt.packet = packet->Copy ();
145  incomingPkt.src = source;
146  incomingPkt.dst = destination;
147  m_rxPackets.push_back (incomingPkt);
148 
149  return true;
150 }
151 
152 void
154 {
155  Ptr<Packet> pkt = Create<Packet> (10);
156  Ipv6Header ipHdr;
157  ipHdr.SetSourceAddress (from);
158  ipHdr.SetDestinationAddress (to);
159  ipHdr.SetHopLimit (64);
160  ipHdr.SetPayloadLength (10);
161  ipHdr.SetNextHeader (0xff);
162  pkt->AddHeader (ipHdr);
163 
164  device->Send (pkt, Mac48Address ("00:00:00:00:00:02"), 0);
165 }
166 
167 void
169 {
171  nodes.Create(2);
172 
173  // First node, setup NetDevices.
174  Ptr<MockNetDevice> mockNetDevice0 = CreateObject<MockNetDevice> ();
175  nodes.Get (0)->AddDevice (mockNetDevice0);
176  mockNetDevice0->SetNode (nodes.Get (0));
177  mockNetDevice0->SetAddress (Mac48Address ("00:00:00:00:00:01"));
178  mockNetDevice0->SetMtu (150);
180  m_mockDevices.Add (mockNetDevice0);
181 
182  // Second node, setup NetDevices.
183  Ptr<MockNetDevice> mockNetDevice1 = CreateObject<MockNetDevice> ();
184  nodes.Get (1)->AddDevice (mockNetDevice1);
185  mockNetDevice1->SetNode (nodes.Get (1));
186  mockNetDevice1->SetAddress (Mac48Address ("00:00:00:00:00:02"));
187  mockNetDevice1->SetMtu (150);
188  m_mockDevices.Add (mockNetDevice1);
189 
190  InternetStackHelper internetv6;
191  internetv6.Install (nodes);
192 
193  SixLowPanHelper sixlowpan;
194  m_sixDevices = sixlowpan.Install (m_mockDevices);
196 
197  Ipv6AddressHelper ipv6;
198  ipv6.SetBase (Ipv6Address ("2001:2::"), Ipv6Prefix (64));
199  Ipv6InterfaceContainer deviceInterfaces;
200  deviceInterfaces = ipv6.Assign (m_sixDevices);
201 
202  // This is a hack to prevent Router Solicitations and Duplicate Address Detection being sent.
203  for (auto i = nodes.Begin (); i != nodes.End (); i++)
204  {
205  Ptr<Node> node = *i;
206  Ptr<Ipv6L3Protocol> ipv6L3 = (*i)->GetObject<Ipv6L3Protocol> ();
207  if (ipv6L3)
208  {
209  ipv6L3->SetAttribute ("IpForward", BooleanValue (true));
210  ipv6L3->SetAttribute ("SendIcmpv6Redirect", BooleanValue (false));
211  }
212  Ptr<Icmpv6L4Protocol> icmpv6 = (*i)->GetObject<Icmpv6L4Protocol> ();
213  if (icmpv6)
214  {
215  icmpv6->SetAttribute ("DAD", BooleanValue (false));
216  }
217  }
218 
219  sixlowpan.AddContext (m_sixDevices, 0, Ipv6Prefix ("2001:2::", 64), Time (Minutes (30)));
220  sixlowpan.AddContext (m_sixDevices, 1, Ipv6Prefix ("2001:1::", 64), Time (Minutes (30)));
221 
222  Ipv6Address srcElided = deviceInterfaces.GetAddress (0, 1);
223  Ipv6Address dstElided = Ipv6Address::MakeAutoconfiguredAddress (Mac48Address ("00:00:00:00:00:02"), Ipv6Prefix ("2001:2::", 64));
224 
225  Simulator::Schedule (Seconds (1), &SixlowpanIphcStatefulImplTest::SendOnePacket, this, m_sixDevices.Get (0),
226  Ipv6Address::GetAny (),
227  dstElided);
228 
229  Simulator::Schedule (Seconds (2), &SixlowpanIphcStatefulImplTest::SendOnePacket, this, m_sixDevices.Get (0),
230  Ipv6Address ("2001:2::f00d:f00d:cafe:cafe"),
231  Ipv6Address ("2001:1::0000:00ff:fe00:cafe"));
232 
233  Simulator::Schedule (Seconds (3), &SixlowpanIphcStatefulImplTest::SendOnePacket, this, m_sixDevices.Get (0),
234  Ipv6Address ("2001:1::0000:00ff:fe00:cafe"),
235  Ipv6Address ("2001:1::f00d:f00d:cafe:cafe"));
236 
237  Simulator::Schedule (Seconds (4), &SixlowpanIphcStatefulImplTest::SendOnePacket, this, m_sixDevices.Get (0),
238  srcElided,
239  Ipv6Address ("2001:1::f00d:f00d:cafe:cafe"));
240 
241  Simulator::Stop (Seconds (10));
242 
243  Simulator::Run ();
244  Simulator::Destroy ();
245 
246  // ------ Now the tests ------------
247 
248  SixLowPanIphc iphcHdr;
249  Ipv6Header ipv6Hdr;
250 
251  // first packet sent, expected CID(0) SAC(1) SAM (0) M(0) DAC(1) DAM (3)
252  m_txPackets[0].packet->RemoveHeader (iphcHdr);
253  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetCid (), false, "CID should be false, is true");
254  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSac (), true, "SAC should be true, is false");
255  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSam (), SixLowPanIphc::HC_INLINE, "SAM should be HC_INLINE, it is not");
256  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetM (), false, "M should be false, is true");
257  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDac (), true, "DAC should be true, is false");
258  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSrcContextId (), 0, "Src context should be 0, it is not");
259  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDstContextId (), 0, "Dst context should be 0, it is not");
260  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDam (), SixLowPanIphc::HC_COMPR_0, "DAM should be HC_COMPR_0, it is not");
261 
262  // first packet received, expected :: -> dstElided
263  m_rxPackets[0].packet->RemoveHeader (ipv6Hdr);
264  NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetSourceAddress (), Ipv6Address::GetAny (), "Src address wrongly rebuilt");
265  NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetDestinationAddress (), dstElided, "Dst address wrongly rebuilt");
266 
267  // second packet sent, expected CID(1) SAC(1) SAM (1) M(0) DAC(1) DAM (2)
268  m_txPackets[1].packet->RemoveHeader (iphcHdr);
269  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetCid (), true, "CID should be true, is false");
270  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSac (), true, "SAC should be true, is false");
271  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSam (), SixLowPanIphc::HC_COMPR_64, "SAM should be HC_COMPR_64, it is not");
272  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetM (), false, "M should be false, is true");
273  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDac (), true, "DAC should be true, is false");
274  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSrcContextId (), 0, "Src context should be 0, it is not");
275  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDstContextId (), 1, "Dst context should be 1, it is not");
276  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDam (), SixLowPanIphc::HC_COMPR_16, "DAM should be HC_COMPR_16, it is not");
277 
278  // second packet received, expected 2001:2::f00d:f00d:cafe:cafe -> 2001:1::0000:00ff:fe00:cafe
279  m_rxPackets[1].packet->RemoveHeader (ipv6Hdr);
280  NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetSourceAddress (), Ipv6Address ("2001:2::f00d:f00d:cafe:cafe"), "Src address wrongly rebuilt");
281  NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetDestinationAddress (), Ipv6Address ("2001:1::0000:00ff:fe00:cafe"), "Dst address wrongly rebuilt");
282 
283  // third packet sent, expected CID(17) SAC(1) SAM (2) M(0) DAC(1) DAM (1)
284  m_txPackets[2].packet->RemoveHeader (iphcHdr);
285  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetCid (), true, "CID should be true, is false");
286  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSac (), true, "SAC should be true, is false");
287  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSam (), SixLowPanIphc::HC_COMPR_16, "SAM should be HC_COMPR_16, it is not");
288  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetM (), false, "M should be false, is true");
289  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDac (), true, "DAC should be true, is false");
290  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSrcContextId (), 1, "Src context should be 1, it is not");
291  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDstContextId (), 1, "Dst context should be 1, it is not");
292  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDam (), SixLowPanIphc::HC_COMPR_64, "DAM should be HC_COMPR_64, it is not");
293 
294  // third packet received, expected 2001:1::0000:00ff:fe00:cafe -> 2001:1::f00d:f00d:cafe:cafe
295  m_rxPackets[2].packet->RemoveHeader (ipv6Hdr);
296  NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetSourceAddress (), Ipv6Address ("2001:1::0000:00ff:fe00:cafe"), "Src address wrongly rebuilt");
297  NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetDestinationAddress (), Ipv6Address ("2001:1::f00d:f00d:cafe:cafe"), "Dst address wrongly rebuilt");
298 
299  // fourth packet sent, expected CID(1) SAC(1) SAM (3) M(0) DAC(1) DAM (1)
300  m_txPackets[3].packet->RemoveHeader (iphcHdr);
301  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetCid (), true, "CID should be true, is false");
302  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSac (), true, "SAC should be true, is false");
303  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSam (), SixLowPanIphc::HC_COMPR_0, "SAM should be HC_COMPR_0, it is not");
304  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetM (), false, "M should be false, is true");
305  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDac (), true, "DAC should be true, is false");
306  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSrcContextId (), 0, "Src context should be 0, it is not");
307  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDstContextId (), 1, "Dst context should be 1, it is not");
308  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDam (), SixLowPanIphc::HC_COMPR_64, "DAM should be HC_COMPR_64, it is not");
309 
310  // fourth packet received, expected srcElided -> 2001:1::f00d:f00d:cafe:cafe
311  m_rxPackets[3].packet->RemoveHeader (ipv6Hdr);
312  NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetSourceAddress (), srcElided, "Src address wrongly rebuilt");
313  NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetDestinationAddress (), Ipv6Address ("2001:1::f00d:f00d:cafe:cafe"), "Dst address wrongly rebuilt");
314 
315  m_rxPackets.clear ();
316  m_txPackets.clear ();
317 }
318 
319 
327 {
328 public:
330 private:
331 };
332 
334  : TestSuite ("sixlowpan-iphc-stateful", UNIT)
335 {
336  AddTestCase (new SixlowpanIphcStatefulImplTest (), TestCase::QUICK);
337 }
338 
NetDeviceContainer m_mockDevices
MockNetDevice container.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
uint8_t GetDstContextId(void) const
Get the DstContextId.
Packet header for IPv6.
Definition: ipv6-header.h:34
AttributeValue implementation for Boolean.
Definition: boolean.h:36
uint32_t GetId(void) const
Definition: node.cc:109
Keep track of a set of IPv6 interfaces.
IPv6 layer implementation.
A suite of tests to run.
Definition: test.h:1343
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.
LOWPAN_IPHC base Encoding - see RFC 6282.
virtual void DoRun(void)
Implementation to actually run this TestCase.
HeaderCompression_e GetSam(void) const
Get the SAM (Source Address Mode) compression.
aggregate IP/TCP/UDP functionality to existing Nodes.
#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:283
NetDeviceContainer m_sixDevices
SixLowPanNetDevice container.
void SetBase(Ipv6Address network, Ipv6Prefix prefix, Ipv6Address base=Ipv6Address("::1"))
Set the base network number, network prefix, and base interface ID.
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:813
encapsulates test code
Definition: test.h:1153
void SetSendCallback(PromiscReceiveCallback cb)
Add a callback to be invoked when the MockNetDevice has a packet to "send".
a polymophic address class
Definition: address.h:90
Ipv6InterfaceContainer Assign(const NetDeviceContainer &c)
Allocate an Ipv6InterfaceContainer with auto-assigned addresses.
uint8_t GetSrcContextId(void) const
Get the SrcContextId.
nodes
Definition: first.py:32
HeaderCompression_e GetDam(void) const
Get the DAM (Destination Address Mode) compression.
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.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
static SixlowpanIphcStatefulTestSuite g_sixlowpanIphcStatefulTestSuite
Static variable for test initialization.
holds a vector of ns3::NetDevice pointers
An implementation of the ICMPv6 protocol.
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:100
NetDeviceContainer Install(NetDeviceContainer c)
Install the SixLoWPAN stack on top of an existing NetDevice.
bool GetCid(void) const
Get the CID (Context Identifier Extension) compression.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)=0
an EUI-48 address
Definition: mac48-address.h:43
std::vector< Data > m_rxPackets
Received packets.
bool GetSac(void) const
Get the SAC (Source Address Compression) compression.
void SendOnePacket(Ptr< LrWpanPhy > sender, Ptr< LrWpanPhy > receiver)
Send one packet.
Structure to hold the Rx/Tx packets.
virtual void SetNode(Ptr< Node > node)
Ipv6Address GetAddress(uint32_t i, uint32_t j) const
Get the address for the specified index.
Helper class to auto-assign global IPv6 unicast addresses.
void SetSourceAddress(Ipv6Address src)
Set the "Source address" field.
Definition: ipv6-header.cc:95
Time Minutes(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1281
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
Describes an IPv6 address.
Definition: ipv6-address.h:49
6LoWPAN IPHC stateful compression Test
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
Describes an IPv6 prefix.
Definition: ipv6-address.h:466
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:296
bool GetM(void) const
Get the M (Multicast) compression.
Setup a sixlowpan stack to be used as a shim between IPv6 and a generic NetDevice.
virtual Ptr< Node > GetNode(void) const
Ipv6Address GetDestinationAddress(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:110
virtual bool SetMtu(const uint16_t mtu)
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
bool GetDac(void) const
Get the DAC (Destination Address Compression) compression.
void SendOnePacket(Ptr< NetDevice > device, Ipv6Address from, Ipv6Address to)
Send one packet.
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:1642
std::vector< Data > m_txPackets
Transmitted packets.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
virtual void SetAddress(Address address)
Set the address of this interface.
void AddContext(NetDeviceContainer c, uint8_t contextId, Ipv6Prefix context, Time validity)
Adds a compression Context to a set of NetDevices.