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 
73  bool ReceiveFromMockDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
74  Address const &source, Address const &destination, NetDevice::PacketType packetType);
75 
76  bool PromiscReceiveFromSixLowPanDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
77  Address const &source, Address const &destination, NetDevice::PacketType packetType);
78 
80 
83 
84 public:
85  virtual void DoRun (void);
87 };
88 
90  : TestCase ("Sixlowpan IPHC stateful implementation")
91 {
92 }
93 
94 bool
96  Address const &source, Address const &destination, NetDevice::PacketType packetType)
97 {
98  Data incomingPkt;
99  incomingPkt.packet = packet->Copy ();
100  incomingPkt.src = source;
101  incomingPkt.dst = destination;
102  m_txPackets.push_back (incomingPkt);
103 
104  Ptr<MockNetDevice> mockDev = DynamicCast<MockNetDevice> (m_mockDevices.Get(1));
105  if (mockDev)
106  {
107  uint32_t id = mockDev->GetNode ()->GetId ();
108  Simulator::ScheduleWithContext (id, Time(1), &MockNetDevice::Receive, mockDev, incomingPkt.packet, protocol, destination, source, packetType);
109  }
110  return true;
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_rxPackets.push_back (incomingPkt);
122 
123  return true;
124 }
125 
126 void
128 {
129  Ptr<Packet> pkt = Create<Packet> (10);
130  Ipv6Header ipHdr;
131  ipHdr.SetSourceAddress (from);
132  ipHdr.SetDestinationAddress (to);
133  ipHdr.SetHopLimit (64);
134  ipHdr.SetPayloadLength (10);
135  ipHdr.SetNextHeader (0xff);
136  pkt->AddHeader (ipHdr);
137 
138  devices.Get (0)->Send (pkt, Mac48Address ("00:00:00:00:00:02"), 0);
139 }
140 
141 void
143 {
145  nodes.Create(2);
146 
147  // First node, setup NetDevices.
148  Ptr<MockNetDevice> mockNetDevice0 = CreateObject<MockNetDevice> ();
149  nodes.Get (0)->AddDevice (mockNetDevice0);
150  mockNetDevice0->SetNode (nodes.Get (0));
151  mockNetDevice0->SetAddress (Mac48Address ("00:00:00:00:00:01"));
152  mockNetDevice0->SetMtu (150);
154  m_mockDevices.Add (mockNetDevice0);
155 
156  // Second node, setup NetDevices.
157  Ptr<MockNetDevice> mockNetDevice1 = CreateObject<MockNetDevice> ();
158  nodes.Get (1)->AddDevice (mockNetDevice1);
159  mockNetDevice1->SetNode (nodes.Get (1));
160  mockNetDevice1->SetAddress (Mac48Address ("00:00:00:00:00:02"));
161  mockNetDevice1->SetMtu (150);
162  m_mockDevices.Add (mockNetDevice1);
163 
164  InternetStackHelper internetv6;
165  internetv6.Install (nodes);
166 
167  SixLowPanHelper sixlowpan;
168  m_sixDevices = sixlowpan.Install (m_mockDevices);
170 
171  Ipv6AddressHelper ipv6;
172  ipv6.SetBase (Ipv6Address ("2001:2::"), Ipv6Prefix (64));
173  Ipv6InterfaceContainer deviceInterfaces;
174  deviceInterfaces = ipv6.Assign (m_sixDevices);
175 
176  // This is a hack to prevent Router Solicitations and Duplicate Address Detection being sent.
177  for (auto i = nodes.Begin (); i != nodes.End (); i++)
178  {
179  Ptr<Node> node = *i;
180  Ptr<Ipv6L3Protocol> ipv6L3 = (*i)->GetObject<Ipv6L3Protocol> ();
181  if (ipv6L3)
182  {
183  ipv6L3->SetAttribute ("IpForward", BooleanValue (true));
184  ipv6L3->SetAttribute ("SendIcmpv6Redirect", BooleanValue (false));
185  }
186  Ptr<Icmpv6L4Protocol> icmpv6 = (*i)->GetObject<Icmpv6L4Protocol> ();
187  if (icmpv6)
188  {
189  icmpv6->SetAttribute ("DAD", BooleanValue (false));
190  }
191  }
192 
193  sixlowpan.AddContext (m_sixDevices, 0, Ipv6Prefix ("2001:2::", 64), Time (Minutes (30)));
194  sixlowpan.AddContext (m_sixDevices, 1, Ipv6Prefix ("2001:1::", 64), Time (Minutes (30)));
195 
196  Ipv6Address srcElided = deviceInterfaces.GetAddress (0, 1);
197  Ipv6Address dstElided = Ipv6Address::MakeAutoconfiguredAddress (Mac48Address ("00:00:00:00:00:02"), Ipv6Prefix ("2001:2::", 64));
198 
199  Simulator::Schedule (Seconds (1), &SixlowpanIphcStatefulImplTest::SendOnePacket, this, m_sixDevices,
200  Ipv6Address::GetAny (),
201  dstElided);
202 
203  Simulator::Schedule (Seconds (2), &SixlowpanIphcStatefulImplTest::SendOnePacket, this, m_sixDevices,
204  Ipv6Address ("2001:2::f00d:f00d:cafe:cafe"),
205  Ipv6Address ("2001:1::0000:00ff:fe00:cafe"));
206 
207  Simulator::Schedule (Seconds (3), &SixlowpanIphcStatefulImplTest::SendOnePacket, this, m_sixDevices,
208  Ipv6Address ("2001:1::0000:00ff:fe00:cafe"),
209  Ipv6Address ("2001:1::f00d:f00d:cafe:cafe"));
210 
211  Simulator::Schedule (Seconds (4), &SixlowpanIphcStatefulImplTest::SendOnePacket, this, m_sixDevices,
212  srcElided,
213  Ipv6Address ("2001:1::f00d:f00d:cafe:cafe"));
214 
215  Simulator::Stop (Seconds (10));
216 
217  Simulator::Run ();
218  Simulator::Destroy ();
219 
220  // ------ Now the tests ------------
221 
222  SixLowPanIphc iphcHdr;
223  Ipv6Header ipv6Hdr;
224 
225  // first packet sent, expected CID(0) SAC(1) SAM (0) M(0) DAC(1) DAM (3)
226  m_txPackets[0].packet->RemoveHeader (iphcHdr);
227  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetCid (), false, "CID should be false, is true");
228  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSac (), true, "SAC should be true, is false");
229  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSam (), SixLowPanIphc::HC_INLINE, "SAM should be HC_INLINE, it is not");
230  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetM (), false, "M should be false, is true");
231  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDac (), true, "DAC should be true, is false");
232  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSrcContextId (), 0, "Src context should be 0, it is not");
233  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDstContextId (), 0, "Dst context should be 0, it is not");
234  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDam (), SixLowPanIphc::HC_COMPR_0, "DAM should be HC_COMPR_0, it is not");
235 
236  // first packet received, expected :: -> dstElided
237  m_rxPackets[0].packet->RemoveHeader (ipv6Hdr);
238  NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetSourceAddress (), Ipv6Address::GetAny (), "Src address wrongly rebuilt");
239  NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetDestinationAddress (), dstElided, "Dst address wrongly rebuilt");
240 
241  // second packet sent, expected CID(1) SAC(1) SAM (1) M(0) DAC(1) DAM (2)
242  m_txPackets[1].packet->RemoveHeader (iphcHdr);
243  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetCid (), true, "CID should be true, is false");
244  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSac (), true, "SAC should be true, is false");
245  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSam (), SixLowPanIphc::HC_COMPR_64, "SAM should be HC_COMPR_64, it is not");
246  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetM (), false, "M should be false, is true");
247  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDac (), true, "DAC should be true, is false");
248  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSrcContextId (), 0, "Src context should be 0, it is not");
249  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDstContextId (), 1, "Dst context should be 1, it is not");
250  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDam (), SixLowPanIphc::HC_COMPR_16, "DAM should be HC_COMPR_16, it is not");
251 
252  // second packet received, expected 2001:2::f00d:f00d:cafe:cafe -> 2001:1::0000:00ff:fe00:cafe
253  m_rxPackets[1].packet->RemoveHeader (ipv6Hdr);
254  NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetSourceAddress (), Ipv6Address ("2001:2::f00d:f00d:cafe:cafe"), "Src address wrongly rebuilt");
255  NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetDestinationAddress (), Ipv6Address ("2001:1::0000:00ff:fe00:cafe"), "Dst address wrongly rebuilt");
256 
257  // third packet sent, expected CID(17) SAC(1) SAM (2) M(0) DAC(1) DAM (1)
258  m_txPackets[2].packet->RemoveHeader (iphcHdr);
259  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetCid (), true, "CID should be true, is false");
260  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSac (), true, "SAC should be true, is false");
261  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSam (), SixLowPanIphc::HC_COMPR_16, "SAM should be HC_COMPR_16, it is not");
262  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetM (), false, "M should be false, is true");
263  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDac (), true, "DAC should be true, is false");
264  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSrcContextId (), 1, "Src context should be 1, it is not");
265  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDstContextId (), 1, "Dst context should be 1, it is not");
266  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDam (), SixLowPanIphc::HC_COMPR_64, "DAM should be HC_COMPR_64, it is not");
267 
268  // third packet received, expected 2001:1::0000:00ff:fe00:cafe -> 2001:1::f00d:f00d:cafe:cafe
269  m_rxPackets[2].packet->RemoveHeader (ipv6Hdr);
270  NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetSourceAddress (), Ipv6Address ("2001:1::0000:00ff:fe00:cafe"), "Src address wrongly rebuilt");
271  NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetDestinationAddress (), Ipv6Address ("2001:1::f00d:f00d:cafe:cafe"), "Dst address wrongly rebuilt");
272 
273  // fourth packet sent, expected CID(1) SAC(1) SAM (3) M(0) DAC(1) DAM (1)
274  m_txPackets[3].packet->RemoveHeader (iphcHdr);
275  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetCid (), true, "CID should be true, is false");
276  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSac (), true, "SAC should be true, is false");
277  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSam (), SixLowPanIphc::HC_COMPR_0, "SAM should be HC_COMPR_0, it is not");
278  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetM (), false, "M should be false, is true");
279  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDac (), true, "DAC should be true, is false");
280  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetSrcContextId (), 0, "Src context should be 0, it is not");
281  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDstContextId (), 1, "Dst context should be 1, it is not");
282  NS_TEST_EXPECT_MSG_EQ (iphcHdr.GetDam (), SixLowPanIphc::HC_COMPR_64, "DAM should be HC_COMPR_64, it is not");
283 
284  // fourth packet received, expected srcElided -> 2001:1::f00d:f00d:cafe:cafe
285  m_rxPackets[3].packet->RemoveHeader (ipv6Hdr);
286  NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetSourceAddress (), srcElided, "Src address wrongly rebuilt");
287  NS_TEST_EXPECT_MSG_EQ (ipv6Hdr.GetDestinationAddress (), Ipv6Address ("2001:1::f00d:f00d:cafe:cafe"), "Dst address wrongly rebuilt");
288 
289  m_rxPackets.clear ();
290  m_txPackets.clear ();
291 }
292 
293 
301 {
302 public:
304 private:
305 };
306 
308  : TestSuite ("sixlowpan-iphc-stateful", UNIT)
309 {
310  AddTestCase (new SixlowpanIphcStatefulImplTest (), TestCase::QUICK);
311 }
312 
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)
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)
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
void SendOnePacket(NetDeviceContainer devices, Ipv6Address from, Ipv6Address to)
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
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)
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:467
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:296
bool GetM(void) const
Get the M (Multicast) compression.
devices
Definition: first.py:39
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.
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.