3 * Copyright (c) 2020-2021 Project CHIP Authors
4 * Copyright (c) 2019 Google LLC
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 * This file defines common preprocessor defintions, constants,
23 * functions, and globals for unit and functional tests for the
28 #include "TestInetLayerCommon.hpp"
34 #include <nlbyteorder.hpp>
36 #include <inet/InetLayer.h>
38 #include <support/CodeUtils.h>
40 #include "TestInetCommon.h"
42 using namespace ::chip;
43 using namespace ::chip::Inet;
44 using namespace ::chip::System;
54 uint16_t mSequenceNumber;
55 } __attribute__((packed));
57 typedef struct ICMPEchoHeader ICMPv4EchoHeader;
58 typedef struct ICMPEchoHeader ICMPv6EchoHeader;
62 static const uint8_t kICMPv4_EchoRequest = 8;
63 static const uint8_t kICMPv4_EchoReply = 0;
65 static const uint8_t kICMPv6_EchoRequest = 128;
66 static const uint8_t kICMPv6_EchoReply = 129;
69 const uint8_t gICMPv4Types[kICMPv4_FilterTypes] =
75 const uint8_t gICMPv6Types[kICMPv6_FilterTypes] =
82 bool gSendIntervalExpired = true;
84 uint32_t gSendIntervalMs = 1000;
86 const char * gInterfaceName = nullptr;
88 InterfaceId gInterfaceId = INET_NULL_INTERFACEID;
90 uint16_t gSendSize = 59;
92 uint32_t gOptFlags = 0;
98 return ((gOptFlags & kOptFlagListen) == kOptFlagListen);
103 return (!IsReceiver());
106 bool IsTesting(const TestStatus & aTestStatus)
110 lStatus = (!aTestStatus.mFailed && !aTestStatus.mSucceeded);
115 bool WasSuccessful(const TestStatus & aTestStatus)
117 bool lStatus = false;
119 if (aTestStatus.mFailed)
121 else if (aTestStatus.mSucceeded)
127 static void FillDataBufferPattern(uint8_t * aBuffer, uint16_t aLength, uint16_t aPatternStartOffset, uint8_t aFirstValue)
129 for (uint16_t i = aPatternStartOffset; i < aLength; i++)
131 const uint8_t lValue = static_cast<uint8_t>(aFirstValue & 0xFF);
139 static bool CheckDataBufferPattern(const uint8_t * aBuffer, uint16_t aLength, uint16_t aPatternStartOffset, uint8_t aFirstValue)
143 for (uint16_t i = aPatternStartOffset; i < aLength; i++)
145 const uint8_t lValue = aBuffer[i];
148 VerifyOrExit(lValue == static_cast<uint8_t>(aFirstValue),
149 printf("Bad data value at offset %u (0x%04x): "
150 "expected 0x%02x, found 0x%02x\n",
151 i, i, aFirstValue, lValue);
153 DumpMemory(aBuffer + aPatternStartOffset,
154 aLength - aPatternStartOffset,
166 static PacketBufferHandle MakeDataBuffer(uint16_t aDesiredLength, uint16_t aPatternStartOffset, uint8_t aFirstValue)
168 PacketBufferHandle lBuffer;
170 VerifyOrExit(aPatternStartOffset <= aDesiredLength, );
172 lBuffer = PacketBufferHandle::New(aDesiredLength);
173 VerifyOrExit(!lBuffer.IsNull(), );
175 aDesiredLength = min(lBuffer->MaxDataLength(), aDesiredLength);
177 FillDataBufferPattern(lBuffer->Start(), aDesiredLength, aPatternStartOffset, aFirstValue);
179 lBuffer->SetDataLength(aDesiredLength);
185 static PacketBufferHandle MakeDataBuffer(uint16_t aDesiredLength, uint16_t aPatternStartOffset)
187 constexpr uint8_t lFirstValue = 0;
188 PacketBufferHandle lBuffer = MakeDataBuffer(aDesiredLength, aPatternStartOffset, lFirstValue);
189 VerifyOrExit(!lBuffer.IsNull(), );
195 template <typename tType>
196 static PacketBufferHandle MakeICMPDataBuffer(uint16_t aDesiredUserLength, uint16_t aHeaderLength, uint16_t aPatternStartOffset,
199 static uint16_t lSequenceNumber = 0;
200 PacketBufferHandle lBuffer;
202 // To ensure there is enough room for the user data and the ICMP
203 // header, include both the user data size and the ICMP header length.
205 lBuffer = MakeDataBuffer(static_cast<uint16_t>(aDesiredUserLength + aHeaderLength), aPatternStartOffset);
207 if (!lBuffer.IsNull())
209 tType * lHeader = reinterpret_cast<tType *>(lBuffer->Start());
211 lHeader->mType = aType;
213 lHeader->mChecksum = 0;
214 lHeader->mID = static_cast<uint16_t>(rand() & UINT16_MAX);
215 lHeader->mSequenceNumber = nlByteOrderSwap16HostToBig(lSequenceNumber++);
221 PacketBufferHandle MakeICMPv4DataBuffer(uint16_t aDesiredUserLength)
223 constexpr uint16_t lICMPHeaderLength = sizeof(ICMPv4EchoHeader);
224 constexpr uint16_t lPatternStartOffset = lICMPHeaderLength;
225 const uint8_t lType = gICMPv4Types[kICMP_EchoRequestIndex];
227 return MakeICMPDataBuffer<ICMPv4EchoHeader>(aDesiredUserLength, lICMPHeaderLength, lPatternStartOffset, lType);
230 PacketBufferHandle MakeICMPv6DataBuffer(uint16_t aDesiredUserLength)
232 constexpr uint16_t lICMPHeaderLength = sizeof(ICMPv6EchoHeader);
233 constexpr uint16_t lPatternStartOffset = lICMPHeaderLength;
234 const uint8_t lType = gICMPv6Types[kICMP_EchoRequestIndex];
236 return MakeICMPDataBuffer<ICMPv6EchoHeader>(aDesiredUserLength, lICMPHeaderLength, lPatternStartOffset, lType);
239 PacketBufferHandle MakeDataBuffer(uint16_t aDesiredLength, uint8_t aFirstValue)
241 constexpr uint16_t lPatternStartOffset = 0;
242 return MakeDataBuffer(aDesiredLength, lPatternStartOffset, aFirstValue);
245 PacketBufferHandle MakeDataBuffer(uint16_t aDesiredLength)
247 constexpr uint16_t lPatternStartOffset = 0;
248 return MakeDataBuffer(aDesiredLength, lPatternStartOffset);
251 static bool HandleDataReceived(const PacketBufferHandle & aBuffer, TransferStats & aStats, bool aStatsByPacket, bool aCheckBuffer,
252 uint16_t aPatternStartOffset, uint8_t aFirstValue)
255 uint16_t lTotalDataLength = 0;
257 // Walk through each buffer in the packet chain, checking the
258 // buffer for the expected pattern, if requested.
260 for (PacketBufferHandle lBuffer = aBuffer.Retain(); !lBuffer.IsNull(); lBuffer.Advance())
262 const uint16_t lDataLength = lBuffer->DataLength();
266 const uint8_t * p = lBuffer->Start();
268 lStatus = CheckDataBufferPattern(p, lDataLength, aPatternStartOffset, aFirstValue);
269 VerifyOrExit(lStatus == true, );
272 lTotalDataLength = static_cast<uint16_t>(lTotalDataLength + lBuffer->DataLength());
273 aFirstValue = static_cast<uint8_t>(aFirstValue + lBuffer->DataLength());
276 // If we are accumulating stats by packet rather than by size,
277 // then increment by one (1) rather than the total buffer length.
279 aStats.mReceive.mActual += ((aStatsByPacket) ? 1 : lTotalDataLength);
285 static bool HandleICMPDataReceived(PacketBufferHandle aBuffer, uint16_t aHeaderLength, TransferStats & aStats, bool aStatsByPacket,
288 const uint16_t lPatternStartOffset = 0;
291 aBuffer->ConsumeHead(aHeaderLength);
293 lStatus = HandleDataReceived(aBuffer, aStats, aStatsByPacket, aCheckBuffer, lPatternStartOffset);
298 bool HandleICMPv4DataReceived(PacketBufferHandle && aBuffer, TransferStats & aStats, bool aStatsByPacket, bool aCheckBuffer)
300 const uint16_t lICMPHeaderLength = sizeof(ICMPv4EchoHeader);
303 lStatus = HandleICMPDataReceived(std::move(aBuffer), lICMPHeaderLength, aStats, aStatsByPacket, aCheckBuffer);
308 bool HandleICMPv6DataReceived(PacketBufferHandle && aBuffer, TransferStats & aStats, bool aStatsByPacket, bool aCheckBuffer)
310 const uint16_t lICMPHeaderLength = sizeof(ICMPv6EchoHeader);
313 lStatus = HandleICMPDataReceived(std::move(aBuffer), lICMPHeaderLength, aStats, aStatsByPacket, aCheckBuffer);
318 bool HandleDataReceived(const PacketBufferHandle & aBuffer, TransferStats & aStats, bool aStatsByPacket, bool aCheckBuffer,
321 const uint16_t lPatternStartOffset = 0;
324 lStatus = HandleDataReceived(aBuffer, aStats, aStatsByPacket, aCheckBuffer, lPatternStartOffset, aFirstValue);
329 bool HandleDataReceived(const PacketBufferHandle & aBuffer, TransferStats & aStats, bool aStatsByPacket, bool aCheckBuffer)
331 const uint8_t lFirstValue = 0;
332 const uint16_t lPatternStartOffset = 0;
335 lStatus = HandleDataReceived(aBuffer, aStats, aStatsByPacket, aCheckBuffer, lPatternStartOffset, lFirstValue);
340 bool HandleUDPDataReceived(const PacketBufferHandle & aBuffer, TransferStats & aStats, bool aStatsByPacket, bool aCheckBuffer)
344 lStatus = HandleDataReceived(aBuffer, aStats, aStatsByPacket, aCheckBuffer);
349 bool HandleTCPDataReceived(const PacketBufferHandle & aBuffer, TransferStats & aStats, bool aStatsByPacket, bool aCheckBuffer)
353 lStatus = HandleDataReceived(aBuffer, aStats, aStatsByPacket, aCheckBuffer);
358 // Timer Callback Handler
360 void HandleSendTimerComplete(System::Layer * aSystemLayer, void * aAppState, System::Error aError)
362 INET_FAIL_ERROR(aError, "Send timer completed with error");
364 gSendIntervalExpired = true;
369 // Raw Endpoint Callback Handlers
371 void HandleRawMessageReceived(const IPEndPointBasis * aEndPoint, const PacketBufferHandle & aBuffer,
372 const IPPacketInfo * aPacketInfo)
374 char lSourceAddressBuffer[INET6_ADDRSTRLEN];
375 char lDestinationAddressBuffer[INET6_ADDRSTRLEN];
377 aPacketInfo->SrcAddress.ToString(lSourceAddressBuffer);
378 aPacketInfo->DestAddress.ToString(lDestinationAddressBuffer);
380 printf("Raw message received from %s to %s (%zu bytes)\n", lSourceAddressBuffer, lDestinationAddressBuffer,
381 static_cast<size_t>(aBuffer->DataLength()));
384 void HandleRawReceiveError(const IPEndPointBasis * aEndPoint, const INET_ERROR & aError, const IPPacketInfo * aPacketInfo)
386 char lAddressBuffer[INET6_ADDRSTRLEN];
388 if (aPacketInfo != nullptr)
390 aPacketInfo->SrcAddress.ToString(lAddressBuffer);
394 strcpy(lAddressBuffer, "(unknown)");
397 printf("IP receive error from %s %s\n", lAddressBuffer, ErrorStr(aError));
400 // UDP Endpoint Callback Handlers
402 void HandleUDPMessageReceived(const IPEndPointBasis * aEndPoint, const PacketBufferHandle & aBuffer,
403 const IPPacketInfo * aPacketInfo)
405 char lSourceAddressBuffer[INET6_ADDRSTRLEN];
406 char lDestinationAddressBuffer[INET6_ADDRSTRLEN];
408 aPacketInfo->SrcAddress.ToString(lSourceAddressBuffer);
409 aPacketInfo->DestAddress.ToString(lDestinationAddressBuffer);
411 printf("UDP packet received from %s:%u to %s:%u (%zu bytes)\n", lSourceAddressBuffer, aPacketInfo->SrcPort,
412 lDestinationAddressBuffer, aPacketInfo->DestPort, static_cast<size_t>(aBuffer->DataLength()));
415 void HandleUDPReceiveError(const IPEndPointBasis * aEndPoint, const INET_ERROR & aError, const IPPacketInfo * aPacketInfo)
417 char lAddressBuffer[INET6_ADDRSTRLEN];
418 uint16_t lSourcePort;
420 if (aPacketInfo != nullptr)
422 aPacketInfo->SrcAddress.ToString(lAddressBuffer);
423 lSourcePort = aPacketInfo->SrcPort;
427 strcpy(lAddressBuffer, "(unknown)");
431 printf("UDP receive error from %s:%u: %s\n", lAddressBuffer, lSourcePort, ErrorStr(aError));
434 } // namespace Common