/ tests / nodecontainer_test.cpp
nodecontainer_test.cpp
  1  // SPDX-FileCopyrightText: Copyright (C) 2024-2025 Marek Küthe <m.k@mk16.de>
  2  //
  3  // SPDX-License-Identifier: GPL-3.0-or-later
  4  
  5  #include <gtest/gtest.h>
  6  #include <memory>
  7  #include <sstream>
  8  #include <stdexcept>
  9  #include <cstdint>
 10  #include <tins/tins.h>
 11  #include "nodecontainer.hpp"
 12  #include "nodeinfo.hpp"
 13  
 14  using namespace crazytrace;
 15  
 16  class NodeContainerTest : public testing::Test
 17  {
 18      protected:
 19          // cppcheck-suppress duplInheritedMember
 20          static void SetUpTestSuite()
 21          {
 22              testing::Test::SetUpTestSuite();
 23  
 24              /* Container 1 */
 25              container1 = std::make_unique<NodeContainer>();
 26  
 27              c1_child_node1 = std::make_shared<NodeInfo>();
 28              c1_child_node1->set_hoplimit(20);
 29              c1_child_node1->set_mac_address(
 30                  Tins::HWAddress<6>("52:54:00:b2:fa:7f"));
 31              c1_child_node1->add_address(Tins::IPv6Address("fd00::11"));
 32              c1_child_node1->add_address(Tins::IPv6Address("fd00::12"));
 33              container1->add_node(c1_child_node1);
 34  
 35              c1_child_node2 = std::make_shared<NodeInfo>();
 36              c1_child_node2->set_hoplimit(30);
 37              c1_child_node2->set_mac_address(
 38                  Tins::HWAddress<6>("52:54:00:b2:fa:7e"));
 39              c1_child_node2->add_address(Tins::IPv6Address("fd00::21"));
 40              container1->add_node(c1_child_node2);
 41  
 42              c1_child_node3 = std::make_shared<NodeInfo>();
 43              c1_child_node3->set_mac_address(
 44                  Tins::HWAddress<6>("52:54:00:b2:fa:7d"));
 45              c1_child_node3->add_address(Tins::IPv6Address("fd00::3"));
 46  
 47              c1_child_node3_child1 = std::make_shared<NodeInfo>();
 48              c1_child_node3_child1->add_address(Tins::IPv6Address("fd00::3:1"));
 49              c1_child_node3->add_node(c1_child_node3_child1);
 50  
 51              c1_child_node3_child2 = std::make_shared<NodeInfo>();
 52              c1_child_node3_child2->add_address(Tins::IPv6Address("fd00::3:2"));
 53  
 54              c1_child_node3_child2_child1 = std::make_shared<NodeInfo>();
 55              c1_child_node3_child2_child1->add_address(
 56                  Tins::IPv6Address("fd00::3:2:1"));
 57              c1_child_node3_child2->add_node(c1_child_node3_child2_child1);
 58  
 59              c1_child_node3->add_node(c1_child_node3_child2);
 60              container1->add_node(c1_child_node3);
 61  
 62              /* Container 2 */
 63              container2 = std::make_unique<NodeContainer>();
 64  
 65              c2_child_node1 = std::make_shared<NodeInfo>();
 66              c2_child_node1->set_mac_address(
 67                  Tins::HWAddress<6>("52:54:00:b2:fa:7f"));
 68              c2_child_node1->add_address(Tins::IPv6Address("fd01::"));
 69              container2->add_node(c2_child_node1);
 70  
 71              /* Container 3 */
 72              container3 = std::make_unique<NodeContainer>();
 73          }
 74  
 75          Tins::EthernetII
 76              create_echo_request(const Tins::HWAddress<6>& source_mac,
 77                                  const Tins::HWAddress<6>& destination_mac,
 78                                  const Tins::IPv6Address& source_address,
 79                                  const Tins::IPv6Address& destination_address,
 80                                  const uint8_t hoplimit,
 81                                  const uint16_t icmp_identifier,
 82                                  const uint16_t icmp_sequence,
 83                                  const Tins::RawPDU::payload_type& payload)
 84          {
 85              Tins::EthernetII packet =
 86                  Tins::EthernetII(destination_mac, source_mac) /
 87                  Tins::IPv6(destination_address, source_address) /
 88                  Tins::ICMPv6(Tins::ICMPv6::Types::ECHO_REQUEST);
 89              Tins::IPv6& inner_ipv6 = packet.rfind_pdu<Tins::IPv6>();
 90              inner_ipv6.hop_limit(hoplimit);
 91              Tins::ICMPv6& inner_icmpv6 = inner_ipv6.rfind_pdu<Tins::ICMPv6>();
 92              inner_icmpv6.identifier(icmp_identifier);
 93              inner_icmpv6.sequence(icmp_sequence);
 94              inner_icmpv6.inner_pdu(Tins::RawPDU(payload));
 95  
 96              const Tins::PDU::serialization_type serialized_packet =
 97                  packet.serialize();
 98              if (serialized_packet.size() > std::numeric_limits<uint32_t>::max())
 99                  throw std::invalid_argument(
100                      "serialized_packet.size() > "
101                      "std::numeric_limits<uint32_t>::max()");
102              const Tins::EthernetII final_packet(
103                  serialized_packet.data(),
104                  static_cast<uint32_t>(serialized_packet.size()));
105  
106              return final_packet;
107          }
108  
109          Tins::EthernetII
110              create_udp_request(const Tins::HWAddress<6>& source_mac,
111                                 const Tins::HWAddress<6>& destination_mac,
112                                 const Tins::IPv6Address& source_address,
113                                 const Tins::IPv6Address& destination_address,
114                                 const uint8_t hoplimit,
115                                 const uint16_t udp_dport,
116                                 const uint16_t udp_sport,
117                                 const Tins::RawPDU::payload_type& payload)
118          {
119              Tins::EthernetII packet =
120                  Tins::EthernetII(destination_mac, source_mac) /
121                  Tins::IPv6(destination_address, source_address) /
122                  Tins::UDP(udp_dport, udp_sport);
123              Tins::IPv6& inner_ipv6 = packet.rfind_pdu<Tins::IPv6>();
124              inner_ipv6.hop_limit(hoplimit);
125              Tins::UDP& inner_udp = inner_ipv6.rfind_pdu<Tins::UDP>();
126              inner_udp.inner_pdu(Tins::RawPDU(payload));
127  
128              const Tins::PDU::serialization_type serialized_packet =
129                  packet.serialize();
130              if (serialized_packet.size() > std::numeric_limits<uint32_t>::max())
131                  throw std::invalid_argument(
132                      "serialized_packet.size() > "
133                      "std::numeric_limits<uint32_t>::max()");
134              const Tins::EthernetII final_packet(
135                  serialized_packet.data(),
136                  static_cast<uint32_t>(serialized_packet.size()));
137  
138              return final_packet;
139          }
140  
141          Tins::EthernetII
142              create_ndp_request(const Tins::HWAddress<6>& source_mac,
143                                 const Tins::IPv6Address& source_address,
144                                 const Tins::IPv6Address& target_address,
145                                 const uint8_t hoplimit)
146          {
147              Tins::EthernetII packet =
148                  Tins::EthernetII(Tins::HWAddress<6>("33:33:ff:48:b2:ae"),
149                                   source_mac) /
150                  Tins::IPv6(Tins::IPv6Address("ff02::1:ff48:b2ae"),
151                             source_address) /
152                  Tins::ICMPv6(Tins::ICMPv6::Types::NEIGHBOUR_SOLICIT);
153              Tins::IPv6& inner_ipv6 = packet.rfind_pdu<Tins::IPv6>();
154              inner_ipv6.hop_limit(hoplimit);
155              Tins::ICMPv6& inner_icmpv6 = inner_ipv6.rfind_pdu<Tins::ICMPv6>();
156              inner_icmpv6.target_addr(target_address);
157  
158              const Tins::PDU::serialization_type serialized_packet =
159                  packet.serialize();
160              if (serialized_packet.size() > std::numeric_limits<uint32_t>::max())
161                  throw std::invalid_argument(
162                      "serialized_packet.size() > "
163                      "std::numeric_limits<uint32_t>::max()");
164              const Tins::EthernetII final_packet(
165                  serialized_packet.data(),
166                  static_cast<uint32_t>(serialized_packet.size()));
167  
168              return final_packet;
169          }
170  
171          // NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables)
172          static std::unique_ptr<NodeContainer> container1;
173          static std::shared_ptr<NodeInfo> c1_child_node1;
174          static std::shared_ptr<NodeInfo> c1_child_node2;
175          static std::shared_ptr<NodeInfo> c1_child_node3;
176          static std::shared_ptr<NodeInfo> c1_child_node3_child1;
177          static std::shared_ptr<NodeInfo> c1_child_node3_child2;
178          static std::shared_ptr<NodeInfo> c1_child_node3_child2_child1;
179          static std::unique_ptr<NodeContainer> container2;
180          static std::shared_ptr<NodeInfo> c2_child_node1;
181          static std::unique_ptr<NodeContainer> container3;
182          // NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
183  };
184  
185  // NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables)
186  std::unique_ptr<NodeContainer> NodeContainerTest::container1;
187  std::shared_ptr<NodeInfo> NodeContainerTest::c1_child_node1;
188  std::shared_ptr<NodeInfo> NodeContainerTest::c1_child_node2;
189  std::shared_ptr<NodeInfo> NodeContainerTest::c1_child_node3;
190  std::shared_ptr<NodeInfo> NodeContainerTest::c1_child_node3_child1;
191  std::shared_ptr<NodeInfo> NodeContainerTest::c1_child_node3_child2;
192  std::shared_ptr<NodeInfo> NodeContainerTest::c1_child_node3_child2_child1;
193  std::unique_ptr<NodeContainer> NodeContainerTest::container2;
194  std::shared_ptr<NodeInfo> NodeContainerTest::c2_child_node1;
195  std::unique_ptr<NodeContainer> NodeContainerTest::container3;
196  
197  // NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
198  
199  TEST_F(NodeContainerTest, Print)
200  {
201      std::ostringstream test_output;
202  
203      container1->print(test_output);
204      EXPECT_EQ(
205          test_output.str(),
206          "NodeContainer: 3 childnodes\nChilds:\n\tNodeInfo: hoplimit=20 "
207          "fd00::11 fd00::12 52:54:00:b2:fa:7f\n\tNodeInfo: hoplimit=30 fd00::21 "
208          "52:54:00:b2:fa:7e\n\tNodeInfo: hoplimit=64 fd00::3 "
209          "52:54:00:b2:fa:7d\n\tChilds:\n\t\tNodeInfo: hoplimit=64 "
210          "fd00::3:1\n\t\tNodeInfo: hoplimit=64 "
211          "fd00::3:2\n\t\tChilds:\n\t\t\tNodeInfo: hoplimit=64 fd00::3:2:1\n");
212      test_output.str("");
213  
214      container2->print(test_output);
215      EXPECT_EQ(test_output.str(),
216                "NodeContainer: 1 childnodes\nChilds:\n\tNodeInfo: hoplimit=64 "
217                "fd01:: 52:54:00:b2:fa:7f\n");
218      test_output.str("");
219  
220      container3->print(test_output);
221      EXPECT_EQ(test_output.str(), "NodeContainer: 0 childnodes\n");
222  }
223  
224  TEST_F(NodeContainerTest, Output)
225  {
226      std::ostringstream test_output;
227  
228      test_output << *container1;
229      EXPECT_EQ(test_output.str(), "NodeContainer: 3 childnodes");
230      test_output.str("");
231  
232      test_output << *container2;
233      EXPECT_EQ(test_output.str(), "NodeContainer: 1 childnodes");
234      test_output.str("");
235  
236      test_output << *container3;
237      EXPECT_EQ(test_output.str(), "NodeContainer: 0 childnodes");
238  }
239  
240  TEST_F(NodeContainerTest, MaxDepth)
241  {
242      EXPECT_EQ(container1->max_depth(), 3);
243      EXPECT_EQ(container2->max_depth(), 1);
244      EXPECT_EQ(container3->max_depth(), 0);
245  }
246  
247  TEST_F(NodeContainerTest, Comparison)
248  {
249      NodeContainer container;
250  
251      auto c1_child_node1 = std::make_shared<NodeInfo>();
252      c1_child_node1->set_hoplimit(20);
253      c1_child_node1->set_mac_address(Tins::HWAddress<6>("52:54:00:b2:fa:7f"));
254      c1_child_node1->add_address(Tins::IPv6Address("fd00::11"));
255      c1_child_node1->add_address(Tins::IPv6Address("fd00::12"));
256      container.add_node(c1_child_node1);
257  
258      auto c1_child_node2 = std::make_shared<NodeInfo>();
259      c1_child_node2->set_hoplimit(30);
260      c1_child_node2->set_mac_address(Tins::HWAddress<6>("52:54:00:b2:fa:7e"));
261      c1_child_node2->add_address(Tins::IPv6Address("fd00::21"));
262      container.add_node(c1_child_node2);
263  
264      auto c1_child_node3 = std::make_shared<NodeInfo>();
265      c1_child_node3->set_mac_address(Tins::HWAddress<6>("52:54:00:b2:fa:7d"));
266      c1_child_node3->add_address(Tins::IPv6Address("fd00::3"));
267  
268      auto c1_child_node3_child1 = std::make_shared<NodeInfo>();
269      c1_child_node3_child1->add_address(Tins::IPv6Address("fd00::3:1"));
270      c1_child_node3->add_node(c1_child_node3_child1);
271  
272      auto c1_child_node3_child2 = std::make_shared<NodeInfo>();
273      c1_child_node3_child2->add_address(Tins::IPv6Address("fd00::3:2"));
274  
275      auto c1_child_node3_child2_child1 = std::make_shared<NodeInfo>();
276      c1_child_node3_child2_child1->add_address(Tins::IPv6Address("fd00::3:2:1"));
277      c1_child_node3_child2->add_node(c1_child_node3_child2_child1);
278  
279      c1_child_node3->add_node(c1_child_node3_child2);
280      container.add_node(c1_child_node3);
281  
282      EXPECT_EQ(*container1, container);
283      EXPECT_NE(*container2, container);
284      EXPECT_NE(*container3, container);
285  }
286  
287  TEST_F(NodeContainerTest, GetReplyForEchoRequest)
288  {
289      const Tins::HWAddress<6> source_mac("52:54:01:b2:fa:7f");
290      const Tins::HWAddress<6> destination_mac("52:54:00:b2:fa:7d");
291      const Tins::IPv6Address source_address("fd01::1");
292      const Tins::IPv6Address destination_address("fd00::3:2:1");
293      constexpr int hoplimit = 55;
294      constexpr int icmp_identifier = 56;
295      constexpr int icmp_sequence = 1;
296      const Tins::RawPDU::payload_type payload = {8, 4, 5, 9, 255, 0, 0, 0, 0, 0};
297  
298      const Tins::EthernetII request_packet =
299          create_echo_request(source_mac,
300                              destination_mac,
301                              source_address,
302                              destination_address,
303                              hoplimit,
304                              icmp_identifier,
305                              icmp_sequence,
306                              payload);
307  
308      const NodeRequest echo_request(request_packet);
309      const NodeReply echo_reply = container1->get_reply(echo_request);
310  
311      NodeReply expected_reply(NodeReplyType::ICMP_ECHO_REPLY,
312                               source_mac,
313                               source_address,
314                               destination_mac,
315                               destination_address);
316      expected_reply.icmp_echo_reply(icmp_identifier, icmp_sequence, payload);
317      expected_reply.set_hoplimit(62);
318      EXPECT_EQ(echo_reply, expected_reply);
319  }
320  
321  TEST_F(NodeContainerTest, GetReplyTimeExceededForEchoRequest)
322  {
323      const Tins::HWAddress<6> source_mac("52:54:01:b2:fa:7f");
324      const Tins::HWAddress<6> destination_mac("52:54:00:b2:fa:7d");
325      const Tins::IPv6Address source_address("fd01::1");
326      const Tins::IPv6Address destination_address("fd00::3:2:1");
327      constexpr int hoplimit = 1;
328      constexpr int icmp_identifier = 56;
329      constexpr int icmp_sequence = 1;
330      const Tins::RawPDU::payload_type payload = {8, 4, 5, 9, 255, 0, 0, 0, 0, 0};
331  
332      const Tins::EthernetII request_packet =
333          create_echo_request(source_mac,
334                              destination_mac,
335                              source_address,
336                              destination_address,
337                              hoplimit,
338                              icmp_identifier,
339                              icmp_sequence,
340                              payload);
341  
342      const NodeRequest echo_request(request_packet);
343      const NodeReply echo_reply = container1->get_reply(echo_request);
344  
345      const Tins::IPv6Address time_exceeded_hop("fd00::3");
346  
347      NodeReply expected_reply(
348          NodeReplyType::ICMP_TIME_EXCEEDED_ICMP_ECHO_REQUEST,
349          source_mac,
350          source_address,
351          destination_mac,
352          time_exceeded_hop);
353      expected_reply.icmp_echo_reply(icmp_identifier, icmp_sequence, payload);
354      expected_reply.packet_reassembly(destination_address);
355      expected_reply.set_hoplimit(64);
356      EXPECT_EQ(echo_reply, expected_reply);
357  }
358  
359  TEST_F(NodeContainerTest, GetReplyForUdpRequest)
360  {
361      const Tins::HWAddress<6> source_mac("52:54:01:b2:fa:7f");
362      const Tins::HWAddress<6> destination_mac("52:54:00:b2:fa:7d");
363      const Tins::IPv6Address source_address("fd01::1");
364      const Tins::IPv6Address destination_address("fd00::3");
365      constexpr int hoplimit = 5;
366      constexpr int udp_dport = 33434;
367      constexpr int udp_sport = 16383;
368      const Tins::RawPDU::payload_type payload = {8, 4, 5, 9, 255, 0, 0, 0, 0, 0};
369  
370      const Tins::EthernetII request_packet =
371          create_udp_request(source_mac,
372                             destination_mac,
373                             source_address,
374                             destination_address,
375                             hoplimit,
376                             udp_dport,
377                             udp_sport,
378                             payload);
379  
380      const NodeRequest echo_request(request_packet);
381      const NodeReply echo_reply = container1->get_reply(echo_request);
382  
383      NodeReply expected_reply(NodeReplyType::ICMP_PORT_UNREACHABLE,
384                               source_mac,
385                               source_address,
386                               destination_mac,
387                               destination_address);
388      expected_reply.udp_response(payload, udp_dport, udp_sport);
389      expected_reply.packet_reassembly(destination_address);
390      expected_reply.set_hoplimit(64);
391      EXPECT_EQ(echo_reply, expected_reply);
392  }
393  
394  TEST_F(NodeContainerTest, GetTimeExceededReplyForUdpRequest)
395  {
396      const Tins::HWAddress<6> source_mac("52:54:01:b2:fa:7f");
397      const Tins::HWAddress<6> destination_mac("52:54:00:b2:fa:7d");
398      const Tins::IPv6Address source_address("fd01::1");
399      const Tins::IPv6Address destination_address("fd00::3:2:1");
400      constexpr int hoplimit = 1;
401      constexpr int udp_dport = 33434;
402      constexpr int udp_sport = 16383;
403      const Tins::RawPDU::payload_type payload = {8, 4, 5, 9, 255, 0, 0, 0, 0, 0};
404  
405      const Tins::EthernetII request_packet =
406          create_udp_request(source_mac,
407                             destination_mac,
408                             source_address,
409                             destination_address,
410                             hoplimit,
411                             udp_dport,
412                             udp_sport,
413                             payload);
414  
415      const NodeRequest echo_request(request_packet);
416      const NodeReply echo_reply = container1->get_reply(echo_request);
417  
418      const Tins::IPv6Address time_exceeded_hop("fd00::3");
419  
420      NodeReply expected_reply(NodeReplyType::ICMP_TIME_EXCEEDED_UDP,
421                               source_mac,
422                               source_address,
423                               destination_mac,
424                               time_exceeded_hop);
425      expected_reply.udp_response(payload, udp_dport, udp_sport);
426      expected_reply.packet_reassembly(destination_address);
427      expected_reply.set_hoplimit(64);
428      EXPECT_EQ(echo_reply, expected_reply);
429  }
430  
431  TEST_F(NodeContainerTest, GetNoReplyForNonExistAddress)
432  {
433      const Tins::HWAddress<6> source_mac("52:54:01:b2:fa:7f");
434      const Tins::HWAddress<6> destination_mac("52:54:00:b2:fa:7d");
435      const Tins::IPv6Address source_address("fd01::1");
436      const Tins::IPv6Address destination_address("fd00::3:2:1");
437      constexpr int hoplimit = 1;
438      constexpr int udp_dport = 33434;
439      constexpr int udp_sport = 16383;
440      const Tins::RawPDU::payload_type payload = {8, 4, 5, 9, 255, 0, 0, 0, 0, 0};
441  
442      const Tins::EthernetII request_packet =
443          create_udp_request(source_mac,
444                             destination_mac,
445                             source_address,
446                             destination_address,
447                             hoplimit,
448                             udp_dport,
449                             udp_sport,
450                             payload);
451  
452      const NodeRequest echo_request(request_packet);
453      const NodeReply echo_reply = container2->get_reply(echo_request);
454  
455      const NodeReply expected_reply(NodeReplyType::NOREPLY);
456      EXPECT_EQ(echo_reply, expected_reply);
457  }
458  
459  TEST_F(NodeContainerTest, GetNoReplyForUnknownPacket)
460  {
461      const Tins::HWAddress<6> source_mac("52:54:01:b2:fa:7f");
462      const Tins::HWAddress<6> destination_mac("52:54:00:b2:fa:7d");
463      const Tins::IPv4Address source_address("10.10.10.10");
464      const Tins::IPv4Address destination_address("10.10.10.11");
465  
466      Tins::EthernetII packet = Tins::EthernetII(destination_mac, source_mac) /
467                                Tins::IP(destination_address, source_address);
468  
469      const Tins::PDU::serialization_type serialized_packet = packet.serialize();
470      ASSERT_LE(serialized_packet.size(), std::numeric_limits<uint32_t>::max());
471      const Tins::EthernetII final_packet(
472          serialized_packet.data(),
473          static_cast<uint32_t>(serialized_packet.size()));
474  
475      const NodeRequest echo_request(final_packet);
476      const NodeReply echo_reply = container1->get_reply(echo_request);
477  
478      const NodeReply expected_reply(NodeReplyType::NOREPLY);
479      EXPECT_EQ(echo_reply, expected_reply);
480  }
481  
482  TEST_F(NodeContainerTest, GetReplyForNdpRequest)
483  {
484      const Tins::HWAddress<6> source_mac("52:54:01:b2:fa:7f");
485      const Tins::HWAddress<6> target_mac("52:54:00:b2:fa:7d");
486      const Tins::IPv6Address source_address("fd01::1");
487      const Tins::IPv6Address target_address("fd00::3");
488      constexpr int hoplimit = 5;
489  
490      const Tins::EthernetII request_packet = create_ndp_request(
491          source_mac, source_address, target_address, hoplimit);
492  
493      const NodeRequest echo_request(request_packet);
494      const NodeReply echo_reply = container1->get_reply(echo_request);
495  
496      const NodeReply expected_reply(NodeReplyType::ICMP_NDP,
497                                     source_mac,
498                                     source_address,
499                                     target_mac,
500                                     target_address);
501      EXPECT_EQ(echo_reply, expected_reply);
502  }
503  
504  TEST_F(NodeContainerTest, GetNoReplyForNdpRequestDueToHoplimit)
505  {
506      const Tins::HWAddress<6> source_mac("52:54:01:b2:fa:7f");
507      const Tins::IPv6Address source_address("fd01::1");
508      const Tins::IPv6Address target_address("fd00::3");
509      constexpr int hoplimit = 0;
510  
511      const Tins::EthernetII request_packet = create_ndp_request(
512          source_mac, source_address, target_address, hoplimit);
513  
514      const NodeRequest echo_request(request_packet);
515      const NodeReply echo_reply = container1->get_reply(echo_request);
516  
517      const NodeReply expected_reply(NodeReplyType::NOREPLY);
518      EXPECT_EQ(echo_reply, expected_reply);
519  }
520  
521  TEST_F(NodeContainerTest, GetNoReplyForNdpRequestDueToNonExistTarget)
522  {
523      const Tins::HWAddress<6> source_mac("52:54:01:b2:fa:7f");
524      const Tins::IPv6Address source_address("fd01::1");
525      const Tins::IPv6Address target_address("fd00::3");
526      constexpr int hoplimit = 5;
527  
528      const Tins::EthernetII request_packet = create_ndp_request(
529          source_mac, source_address, target_address, hoplimit);
530  
531      const NodeRequest echo_request(request_packet);
532      const NodeReply echo_reply = container2->get_reply(echo_request);
533  
534      const NodeReply expected_reply(NodeReplyType::NOREPLY);
535      EXPECT_EQ(echo_reply, expected_reply);
536  }