blob: 7a60a2778239ba9e8975c74bb557dcb7eb7dca86 [file] [log] [blame]
Grant Ericksonacb73dc2020-04-10 13:48:10 -07001/*
2 *
Kevin Schoedela8681872021-01-28 15:53:13 -05003 * Copyright (c) 2020-2021 Project CHIP Authors
Grant Ericksonacb73dc2020-04-10 13:48:10 -07004 * Copyright (c) 2019 Google LLC
5 * All rights reserved.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20/**
21 * @file
22 * This file defines common preprocessor defintions, constants,
23 * functions, and globals for unit and functional tests for the
24 * Inet layer.
25 *
26 */
27
28#include "TestInetLayerCommon.hpp"
29
30#include <stdlib.h>
31#include <string.h>
szatmz0a88e212020-12-09 13:56:49 -050032#include <utility>
Grant Ericksonacb73dc2020-04-10 13:48:10 -070033
34#include <nlbyteorder.hpp>
35
Kevin Schoedelfe681d92021-11-30 15:28:04 -050036#include <inet/IPPacketInfo.h>
Zang MingJie53dd5832021-09-03 03:05:16 +080037#include <lib/support/CodeUtils.h>
Grant Ericksonacb73dc2020-04-10 13:48:10 -070038
39#include "TestInetCommon.h"
40
41using namespace ::chip;
42using namespace ::chip::Inet;
43using namespace ::chip::System;
44
45// Type Definitions
46
47struct ICMPEchoHeader
48{
49 uint8_t mType;
50 uint8_t mCode;
51 uint16_t mChecksum;
52 uint16_t mID;
53 uint16_t mSequenceNumber;
54} __attribute__((packed));
55
56typedef struct ICMPEchoHeader ICMPv4EchoHeader;
57typedef struct ICMPEchoHeader ICMPv6EchoHeader;
58
59// Global Variables
60
61static const uint8_t kICMPv4_EchoRequest = 8;
62static const uint8_t kICMPv4_EchoReply = 0;
63
64static const uint8_t kICMPv6_EchoRequest = 128;
65static const uint8_t kICMPv6_EchoReply = 129;
66
67// clang-format off
68const uint8_t gICMPv4Types[kICMPv4_FilterTypes] =
69{
70 kICMPv4_EchoRequest,
71 kICMPv4_EchoReply
72};
73
74const uint8_t gICMPv6Types[kICMPv6_FilterTypes] =
75{
76 kICMPv6_EchoRequest,
77 kICMPv6_EchoReply
78};
79// clang-format on
80
81bool gSendIntervalExpired = true;
82
83uint32_t gSendIntervalMs = 1000;
84
Michael Spangc76e82d2020-09-23 14:32:23 -040085const char * gInterfaceName = nullptr;
Grant Ericksonacb73dc2020-04-10 13:48:10 -070086
Kevin Schoedel014d85c2021-10-27 09:25:05 -040087InterfaceId gInterfaceId = InterfaceId::Null();
Grant Ericksonacb73dc2020-04-10 13:48:10 -070088
89uint16_t gSendSize = 59;
90
91uint32_t gOptFlags = 0;
92
93namespace Common {
94
Michael Spangb0e38c22020-09-30 14:20:50 -040095bool IsReceiver()
Grant Ericksonacb73dc2020-04-10 13:48:10 -070096{
97 return ((gOptFlags & kOptFlagListen) == kOptFlagListen);
98}
99
Michael Spangb0e38c22020-09-30 14:20:50 -0400100bool IsSender()
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700101{
102 return (!IsReceiver());
103}
104
105bool IsTesting(const TestStatus & aTestStatus)
106{
107 bool lStatus;
108
109 lStatus = (!aTestStatus.mFailed && !aTestStatus.mSucceeded);
110
111 return (lStatus);
112}
113
114bool WasSuccessful(const TestStatus & aTestStatus)
115{
116 bool lStatus = false;
117
118 if (aTestStatus.mFailed)
119 lStatus = false;
120 else if (aTestStatus.mSucceeded)
121 lStatus = true;
122
123 return (lStatus);
124}
125
126static void FillDataBufferPattern(uint8_t * aBuffer, uint16_t aLength, uint16_t aPatternStartOffset, uint8_t aFirstValue)
127{
128 for (uint16_t i = aPatternStartOffset; i < aLength; i++)
129 {
130 const uint8_t lValue = static_cast<uint8_t>(aFirstValue & 0xFF);
131
132 aBuffer[i] = lValue;
133
134 aFirstValue++;
135 }
136}
137
138static bool CheckDataBufferPattern(const uint8_t * aBuffer, uint16_t aLength, uint16_t aPatternStartOffset, uint8_t aFirstValue)
139{
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700140 for (uint16_t i = aPatternStartOffset; i < aLength; i++)
141 {
142 const uint8_t lValue = aBuffer[i];
143
Kevin Schoedelf9550e12021-06-21 17:08:48 -0400144 if (lValue != static_cast<uint8_t>(aFirstValue))
145 {
146 printf("Bad data value at offset %u (0x%04x): "
147 "expected 0x%02x, found 0x%02x\n",
148 i, i, aFirstValue, lValue);
149 DumpMemory(aBuffer + aPatternStartOffset, aLength - aPatternStartOffset, "0x", 16);
150 return false;
151 }
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700152
153 aFirstValue++;
154 }
155
Kevin Schoedelf9550e12021-06-21 17:08:48 -0400156 return true;
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700157}
158
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500159static PacketBufferHandle MakeDataBuffer(uint16_t aDesiredLength, uint16_t aPatternStartOffset, uint8_t aFirstValue)
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700160{
Kevin Schoedelf9550e12021-06-21 17:08:48 -0400161 VerifyOrReturnError(aPatternStartOffset <= aDesiredLength, PacketBufferHandle());
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700162
Kevin Schoedelf9550e12021-06-21 17:08:48 -0400163 PacketBufferHandle lBuffer = PacketBufferHandle::New(aDesiredLength);
164 VerifyOrReturnError(!lBuffer.IsNull(), lBuffer);
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700165
166 aDesiredLength = min(lBuffer->MaxDataLength(), aDesiredLength);
167
168 FillDataBufferPattern(lBuffer->Start(), aDesiredLength, aPatternStartOffset, aFirstValue);
169
170 lBuffer->SetDataLength(aDesiredLength);
171
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500172 return lBuffer;
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700173}
174
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500175static PacketBufferHandle MakeDataBuffer(uint16_t aDesiredLength, uint16_t aPatternStartOffset)
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700176{
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500177 constexpr uint8_t lFirstValue = 0;
Kevin Schoedelf9550e12021-06-21 17:08:48 -0400178 return MakeDataBuffer(aDesiredLength, aPatternStartOffset, lFirstValue);
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700179}
180
181template <typename tType>
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500182static PacketBufferHandle MakeICMPDataBuffer(uint16_t aDesiredUserLength, uint16_t aHeaderLength, uint16_t aPatternStartOffset,
183 uint8_t aType)
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700184{
185 static uint16_t lSequenceNumber = 0;
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500186 PacketBufferHandle lBuffer;
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700187
188 // To ensure there is enough room for the user data and the ICMP
189 // header, include both the user data size and the ICMP header length.
190
Andrei Litvin2f169042020-12-01 10:58:43 -0500191 lBuffer = MakeDataBuffer(static_cast<uint16_t>(aDesiredUserLength + aHeaderLength), aPatternStartOffset);
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700192
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500193 if (!lBuffer.IsNull())
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700194 {
195 tType * lHeader = reinterpret_cast<tType *>(lBuffer->Start());
196
197 lHeader->mType = aType;
198 lHeader->mCode = 0;
199 lHeader->mChecksum = 0;
Andrei Litvin2f169042020-12-01 10:58:43 -0500200 lHeader->mID = static_cast<uint16_t>(rand() & UINT16_MAX);
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700201 lHeader->mSequenceNumber = nlByteOrderSwap16HostToBig(lSequenceNumber++);
202 }
203
204 return (lBuffer);
205}
206
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500207PacketBufferHandle MakeICMPv4DataBuffer(uint16_t aDesiredUserLength)
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700208{
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500209 constexpr uint16_t lICMPHeaderLength = sizeof(ICMPv4EchoHeader);
210 constexpr uint16_t lPatternStartOffset = lICMPHeaderLength;
211 const uint8_t lType = gICMPv4Types[kICMP_EchoRequestIndex];
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700212
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500213 return MakeICMPDataBuffer<ICMPv4EchoHeader>(aDesiredUserLength, lICMPHeaderLength, lPatternStartOffset, lType);
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700214}
215
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500216PacketBufferHandle MakeICMPv6DataBuffer(uint16_t aDesiredUserLength)
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700217{
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500218 constexpr uint16_t lICMPHeaderLength = sizeof(ICMPv6EchoHeader);
219 constexpr uint16_t lPatternStartOffset = lICMPHeaderLength;
220 const uint8_t lType = gICMPv6Types[kICMP_EchoRequestIndex];
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700221
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500222 return MakeICMPDataBuffer<ICMPv6EchoHeader>(aDesiredUserLength, lICMPHeaderLength, lPatternStartOffset, lType);
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700223}
224
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500225PacketBufferHandle MakeDataBuffer(uint16_t aDesiredLength, uint8_t aFirstValue)
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700226{
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500227 constexpr uint16_t lPatternStartOffset = 0;
228 return MakeDataBuffer(aDesiredLength, lPatternStartOffset, aFirstValue);
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700229}
230
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500231PacketBufferHandle MakeDataBuffer(uint16_t aDesiredLength)
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700232{
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500233 constexpr uint16_t lPatternStartOffset = 0;
234 return MakeDataBuffer(aDesiredLength, lPatternStartOffset);
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700235}
236
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500237static bool HandleDataReceived(const PacketBufferHandle & aBuffer, TransferStats & aStats, bool aStatsByPacket, bool aCheckBuffer,
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700238 uint16_t aPatternStartOffset, uint8_t aFirstValue)
239{
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700240 uint16_t lTotalDataLength = 0;
241
242 // Walk through each buffer in the packet chain, checking the
243 // buffer for the expected pattern, if requested.
244
Kevin Schoedelf8c29d42020-12-09 12:57:54 -0500245 for (PacketBufferHandle lBuffer = aBuffer.Retain(); !lBuffer.IsNull(); lBuffer.Advance())
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700246 {
247 const uint16_t lDataLength = lBuffer->DataLength();
Kevin Schoedelf9550e12021-06-21 17:08:48 -0400248 const uint8_t * const p = lBuffer->Start();
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700249
Kevin Schoedelf9550e12021-06-21 17:08:48 -0400250 if (aCheckBuffer && !CheckDataBufferPattern(p, lDataLength, aPatternStartOffset, aFirstValue))
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700251 {
Kevin Schoedelf9550e12021-06-21 17:08:48 -0400252 return false;
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700253 }
254
Kevin Schoedelf9550e12021-06-21 17:08:48 -0400255 lTotalDataLength = static_cast<uint16_t>(lTotalDataLength + lDataLength);
256 aFirstValue = static_cast<uint8_t>(aFirstValue + lDataLength);
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700257 }
258
259 // If we are accumulating stats by packet rather than by size,
260 // then increment by one (1) rather than the total buffer length.
261
262 aStats.mReceive.mActual += ((aStatsByPacket) ? 1 : lTotalDataLength);
263
Kevin Schoedelf9550e12021-06-21 17:08:48 -0400264 return true;
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700265}
266
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500267static bool HandleICMPDataReceived(PacketBufferHandle aBuffer, uint16_t aHeaderLength, TransferStats & aStats, bool aStatsByPacket,
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700268 bool aCheckBuffer)
269{
270 const uint16_t lPatternStartOffset = 0;
271 bool lStatus;
272
273 aBuffer->ConsumeHead(aHeaderLength);
274
275 lStatus = HandleDataReceived(aBuffer, aStats, aStatsByPacket, aCheckBuffer, lPatternStartOffset);
276
277 return (lStatus);
278}
279
Kevin Schoedelf4e7b552021-01-15 15:23:31 -0500280bool HandleICMPv4DataReceived(PacketBufferHandle && aBuffer, TransferStats & aStats, bool aStatsByPacket, bool aCheckBuffer)
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700281{
282 const uint16_t lICMPHeaderLength = sizeof(ICMPv4EchoHeader);
283 bool lStatus;
284
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500285 lStatus = HandleICMPDataReceived(std::move(aBuffer), lICMPHeaderLength, aStats, aStatsByPacket, aCheckBuffer);
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700286
287 return (lStatus);
288}
289
Kevin Schoedelf4e7b552021-01-15 15:23:31 -0500290bool HandleICMPv6DataReceived(PacketBufferHandle && aBuffer, TransferStats & aStats, bool aStatsByPacket, bool aCheckBuffer)
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700291{
292 const uint16_t lICMPHeaderLength = sizeof(ICMPv6EchoHeader);
293 bool lStatus;
294
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500295 lStatus = HandleICMPDataReceived(std::move(aBuffer), lICMPHeaderLength, aStats, aStatsByPacket, aCheckBuffer);
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700296
297 return (lStatus);
298}
299
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500300bool HandleDataReceived(const PacketBufferHandle & aBuffer, TransferStats & aStats, bool aStatsByPacket, bool aCheckBuffer,
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700301 uint8_t aFirstValue)
302{
303 const uint16_t lPatternStartOffset = 0;
304 bool lStatus;
305
306 lStatus = HandleDataReceived(aBuffer, aStats, aStatsByPacket, aCheckBuffer, lPatternStartOffset, aFirstValue);
307
308 return (lStatus);
309}
310
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500311bool HandleDataReceived(const PacketBufferHandle & aBuffer, TransferStats & aStats, bool aStatsByPacket, bool aCheckBuffer)
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700312{
313 const uint8_t lFirstValue = 0;
314 const uint16_t lPatternStartOffset = 0;
315 bool lStatus;
316
317 lStatus = HandleDataReceived(aBuffer, aStats, aStatsByPacket, aCheckBuffer, lPatternStartOffset, lFirstValue);
318
319 return (lStatus);
320}
321
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500322bool HandleUDPDataReceived(const PacketBufferHandle & aBuffer, TransferStats & aStats, bool aStatsByPacket, bool aCheckBuffer)
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700323{
324 bool lStatus;
325
326 lStatus = HandleDataReceived(aBuffer, aStats, aStatsByPacket, aCheckBuffer);
327
328 return (lStatus);
329}
330
Kevin Schoedelf54b9252020-11-24 11:59:12 -0500331bool HandleTCPDataReceived(const PacketBufferHandle & aBuffer, TransferStats & aStats, bool aStatsByPacket, bool aCheckBuffer)
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700332{
333 bool lStatus;
334
335 lStatus = HandleDataReceived(aBuffer, aStats, aStatsByPacket, aCheckBuffer);
336
337 return (lStatus);
338}
339
340// Timer Callback Handler
341
Kevin Schoedel7359d192021-08-11 17:26:23 -0400342void HandleSendTimerComplete(System::Layer * aSystemLayer, void * aAppState)
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700343{
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700344 gSendIntervalExpired = true;
345
346 DriveSend();
347}
348
349// Raw Endpoint Callback Handlers
350
Kevin Schoedel52db0e42021-10-28 13:59:25 -0400351void HandleRawMessageReceived(const UDPEndPoint * aEndPoint, const PacketBufferHandle & aBuffer, const IPPacketInfo * aPacketInfo)
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700352{
353 char lSourceAddressBuffer[INET6_ADDRSTRLEN];
354 char lDestinationAddressBuffer[INET6_ADDRSTRLEN];
355
Boris Zbarsky381bed12021-02-10 12:48:21 -0500356 aPacketInfo->SrcAddress.ToString(lSourceAddressBuffer);
357 aPacketInfo->DestAddress.ToString(lDestinationAddressBuffer);
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700358
andrei-menzopol57471cb2022-04-20 23:31:17 +0300359 printf("Raw message received from %s to %s (%u bytes)\n", lSourceAddressBuffer, lDestinationAddressBuffer,
360 static_cast<unsigned int>(aBuffer->DataLength()));
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700361}
362
Kevin Schoedel52db0e42021-10-28 13:59:25 -0400363void HandleRawReceiveError(const UDPEndPoint * aEndPoint, const CHIP_ERROR & aError, const IPPacketInfo * aPacketInfo)
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700364{
365 char lAddressBuffer[INET6_ADDRSTRLEN];
366
Michael Spangc76e82d2020-09-23 14:32:23 -0400367 if (aPacketInfo != nullptr)
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700368 {
Boris Zbarsky381bed12021-02-10 12:48:21 -0500369 aPacketInfo->SrcAddress.ToString(lAddressBuffer);
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700370 }
371 else
372 {
373 strcpy(lAddressBuffer, "(unknown)");
374 }
375
376 printf("IP receive error from %s %s\n", lAddressBuffer, ErrorStr(aError));
377}
378
379// UDP Endpoint Callback Handlers
380
Kevin Schoedel52db0e42021-10-28 13:59:25 -0400381void HandleUDPMessageReceived(const UDPEndPoint * aEndPoint, const PacketBufferHandle & aBuffer, const IPPacketInfo * aPacketInfo)
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700382{
383 char lSourceAddressBuffer[INET6_ADDRSTRLEN];
384 char lDestinationAddressBuffer[INET6_ADDRSTRLEN];
385
Boris Zbarsky381bed12021-02-10 12:48:21 -0500386 aPacketInfo->SrcAddress.ToString(lSourceAddressBuffer);
387 aPacketInfo->DestAddress.ToString(lDestinationAddressBuffer);
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700388
andrei-menzopol57471cb2022-04-20 23:31:17 +0300389 printf("UDP packet received from %s:%u to %s:%u (%u bytes)\n", lSourceAddressBuffer, aPacketInfo->SrcPort,
390 lDestinationAddressBuffer, aPacketInfo->DestPort, static_cast<unsigned int>(aBuffer->DataLength()));
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700391}
392
Kevin Schoedel52db0e42021-10-28 13:59:25 -0400393void HandleUDPReceiveError(const UDPEndPoint * aEndPoint, const CHIP_ERROR & aError, const IPPacketInfo * aPacketInfo)
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700394{
395 char lAddressBuffer[INET6_ADDRSTRLEN];
396 uint16_t lSourcePort;
397
Michael Spangc76e82d2020-09-23 14:32:23 -0400398 if (aPacketInfo != nullptr)
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700399 {
Boris Zbarsky381bed12021-02-10 12:48:21 -0500400 aPacketInfo->SrcAddress.ToString(lAddressBuffer);
Grant Ericksonacb73dc2020-04-10 13:48:10 -0700401 lSourcePort = aPacketInfo->SrcPort;
402 }
403 else
404 {
405 strcpy(lAddressBuffer, "(unknown)");
406 lSourcePort = 0;
407 }
408
409 printf("UDP receive error from %s:%u: %s\n", lAddressBuffer, lSourcePort, ErrorStr(aError));
410}
411
Michael Spangc9b04712020-09-23 10:14:41 -0400412} // namespace Common