1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker * Copyright (c) 2020, The OpenThread Authors.
3*cfb92d14SAndroid Build Coastguard Worker * All rights reserved.
4*cfb92d14SAndroid Build Coastguard Worker *
5*cfb92d14SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*cfb92d14SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met:
7*cfb92d14SAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
8*cfb92d14SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
9*cfb92d14SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
10*cfb92d14SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
11*cfb92d14SAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
12*cfb92d14SAndroid Build Coastguard Worker * 3. Neither the name of the copyright holder nor the
13*cfb92d14SAndroid Build Coastguard Worker * names of its contributors may be used to endorse or promote products
14*cfb92d14SAndroid Build Coastguard Worker * derived from this software without specific prior written permission.
15*cfb92d14SAndroid Build Coastguard Worker *
16*cfb92d14SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*cfb92d14SAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*cfb92d14SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*cfb92d14SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*cfb92d14SAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*cfb92d14SAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*cfb92d14SAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*cfb92d14SAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*cfb92d14SAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*cfb92d14SAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*cfb92d14SAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE.
27*cfb92d14SAndroid Build Coastguard Worker */
28*cfb92d14SAndroid Build Coastguard Worker
29*cfb92d14SAndroid Build Coastguard Worker #include "common/encoding.hpp"
30*cfb92d14SAndroid Build Coastguard Worker #include "common/message.hpp"
31*cfb92d14SAndroid Build Coastguard Worker #include "common/numeric_limits.hpp"
32*cfb92d14SAndroid Build Coastguard Worker #include "common/random.hpp"
33*cfb92d14SAndroid Build Coastguard Worker #include "common/string.hpp"
34*cfb92d14SAndroid Build Coastguard Worker #include "instance/instance.hpp"
35*cfb92d14SAndroid Build Coastguard Worker #include "net/checksum.hpp"
36*cfb92d14SAndroid Build Coastguard Worker #include "net/icmp6.hpp"
37*cfb92d14SAndroid Build Coastguard Worker #include "net/ip4_types.hpp"
38*cfb92d14SAndroid Build Coastguard Worker #include "net/udp6.hpp"
39*cfb92d14SAndroid Build Coastguard Worker #include "utils/verhoeff_checksum.hpp"
40*cfb92d14SAndroid Build Coastguard Worker
41*cfb92d14SAndroid Build Coastguard Worker #include "test_platform.h"
42*cfb92d14SAndroid Build Coastguard Worker #include "test_util.hpp"
43*cfb92d14SAndroid Build Coastguard Worker
44*cfb92d14SAndroid Build Coastguard Worker namespace ot {
45*cfb92d14SAndroid Build Coastguard Worker
CalculateChecksum(const void * aBuffer,uint16_t aLength)46*cfb92d14SAndroid Build Coastguard Worker uint16_t CalculateChecksum(const void *aBuffer, uint16_t aLength)
47*cfb92d14SAndroid Build Coastguard Worker {
48*cfb92d14SAndroid Build Coastguard Worker // Calculates checksum over a given buffer data. This implementation
49*cfb92d14SAndroid Build Coastguard Worker // is inspired by the algorithm from RFC-1071.
50*cfb92d14SAndroid Build Coastguard Worker
51*cfb92d14SAndroid Build Coastguard Worker uint32_t sum = 0;
52*cfb92d14SAndroid Build Coastguard Worker const uint8_t *bytes = reinterpret_cast<const uint8_t *>(aBuffer);
53*cfb92d14SAndroid Build Coastguard Worker
54*cfb92d14SAndroid Build Coastguard Worker while (aLength >= sizeof(uint16_t))
55*cfb92d14SAndroid Build Coastguard Worker {
56*cfb92d14SAndroid Build Coastguard Worker sum += BigEndian::ReadUint16(bytes);
57*cfb92d14SAndroid Build Coastguard Worker bytes += sizeof(uint16_t);
58*cfb92d14SAndroid Build Coastguard Worker aLength -= sizeof(uint16_t);
59*cfb92d14SAndroid Build Coastguard Worker }
60*cfb92d14SAndroid Build Coastguard Worker
61*cfb92d14SAndroid Build Coastguard Worker if (aLength > 0)
62*cfb92d14SAndroid Build Coastguard Worker {
63*cfb92d14SAndroid Build Coastguard Worker sum += (static_cast<uint32_t>(bytes[0]) << 8);
64*cfb92d14SAndroid Build Coastguard Worker }
65*cfb92d14SAndroid Build Coastguard Worker
66*cfb92d14SAndroid Build Coastguard Worker // Fold 32-bit sum to 16 bits.
67*cfb92d14SAndroid Build Coastguard Worker
68*cfb92d14SAndroid Build Coastguard Worker while (sum >> 16)
69*cfb92d14SAndroid Build Coastguard Worker {
70*cfb92d14SAndroid Build Coastguard Worker sum = (sum & 0xffff) + (sum >> 16);
71*cfb92d14SAndroid Build Coastguard Worker }
72*cfb92d14SAndroid Build Coastguard Worker
73*cfb92d14SAndroid Build Coastguard Worker return static_cast<uint16_t>(sum & 0xffff);
74*cfb92d14SAndroid Build Coastguard Worker }
75*cfb92d14SAndroid Build Coastguard Worker
CalculateChecksum(const Ip6::Address & aSource,const Ip6::Address & aDestination,uint8_t aIpProto,const Message & aMessage)76*cfb92d14SAndroid Build Coastguard Worker uint16_t CalculateChecksum(const Ip6::Address &aSource,
77*cfb92d14SAndroid Build Coastguard Worker const Ip6::Address &aDestination,
78*cfb92d14SAndroid Build Coastguard Worker uint8_t aIpProto,
79*cfb92d14SAndroid Build Coastguard Worker const Message &aMessage)
80*cfb92d14SAndroid Build Coastguard Worker {
81*cfb92d14SAndroid Build Coastguard Worker // This method calculates the checksum over an IPv6 message.
82*cfb92d14SAndroid Build Coastguard Worker constexpr uint16_t kMaxPayload = 1024;
83*cfb92d14SAndroid Build Coastguard Worker
84*cfb92d14SAndroid Build Coastguard Worker OT_TOOL_PACKED_BEGIN
85*cfb92d14SAndroid Build Coastguard Worker struct PseudoHeader
86*cfb92d14SAndroid Build Coastguard Worker {
87*cfb92d14SAndroid Build Coastguard Worker Ip6::Address mSource;
88*cfb92d14SAndroid Build Coastguard Worker Ip6::Address mDestination;
89*cfb92d14SAndroid Build Coastguard Worker uint32_t mPayloadLength;
90*cfb92d14SAndroid Build Coastguard Worker uint32_t mProtocol;
91*cfb92d14SAndroid Build Coastguard Worker } OT_TOOL_PACKED_END;
92*cfb92d14SAndroid Build Coastguard Worker
93*cfb92d14SAndroid Build Coastguard Worker OT_TOOL_PACKED_BEGIN
94*cfb92d14SAndroid Build Coastguard Worker struct ChecksumData
95*cfb92d14SAndroid Build Coastguard Worker {
96*cfb92d14SAndroid Build Coastguard Worker PseudoHeader mPseudoHeader;
97*cfb92d14SAndroid Build Coastguard Worker uint8_t mPayload[kMaxPayload];
98*cfb92d14SAndroid Build Coastguard Worker } OT_TOOL_PACKED_END;
99*cfb92d14SAndroid Build Coastguard Worker
100*cfb92d14SAndroid Build Coastguard Worker ChecksumData data;
101*cfb92d14SAndroid Build Coastguard Worker uint16_t payloadLength;
102*cfb92d14SAndroid Build Coastguard Worker
103*cfb92d14SAndroid Build Coastguard Worker payloadLength = aMessage.GetLength() - aMessage.GetOffset();
104*cfb92d14SAndroid Build Coastguard Worker
105*cfb92d14SAndroid Build Coastguard Worker data.mPseudoHeader.mSource = aSource;
106*cfb92d14SAndroid Build Coastguard Worker data.mPseudoHeader.mDestination = aDestination;
107*cfb92d14SAndroid Build Coastguard Worker data.mPseudoHeader.mProtocol = BigEndian::HostSwap32(aIpProto);
108*cfb92d14SAndroid Build Coastguard Worker data.mPseudoHeader.mPayloadLength = BigEndian::HostSwap32(payloadLength);
109*cfb92d14SAndroid Build Coastguard Worker
110*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(aMessage.Read(aMessage.GetOffset(), data.mPayload, payloadLength));
111*cfb92d14SAndroid Build Coastguard Worker
112*cfb92d14SAndroid Build Coastguard Worker return CalculateChecksum(&data, sizeof(PseudoHeader) + payloadLength);
113*cfb92d14SAndroid Build Coastguard Worker }
114*cfb92d14SAndroid Build Coastguard Worker
CalculateChecksum(const Ip4::Address & aSource,const Ip4::Address & aDestination,uint8_t aIpProto,const Message & aMessage)115*cfb92d14SAndroid Build Coastguard Worker uint16_t CalculateChecksum(const Ip4::Address &aSource,
116*cfb92d14SAndroid Build Coastguard Worker const Ip4::Address &aDestination,
117*cfb92d14SAndroid Build Coastguard Worker uint8_t aIpProto,
118*cfb92d14SAndroid Build Coastguard Worker const Message &aMessage)
119*cfb92d14SAndroid Build Coastguard Worker {
120*cfb92d14SAndroid Build Coastguard Worker // This method calculates the checksum over an IPv4 message.
121*cfb92d14SAndroid Build Coastguard Worker constexpr uint16_t kMaxPayload = 1024;
122*cfb92d14SAndroid Build Coastguard Worker
123*cfb92d14SAndroid Build Coastguard Worker OT_TOOL_PACKED_BEGIN
124*cfb92d14SAndroid Build Coastguard Worker struct PseudoHeader
125*cfb92d14SAndroid Build Coastguard Worker {
126*cfb92d14SAndroid Build Coastguard Worker Ip4::Address mSource;
127*cfb92d14SAndroid Build Coastguard Worker Ip4::Address mDestination;
128*cfb92d14SAndroid Build Coastguard Worker uint16_t mPayloadLength;
129*cfb92d14SAndroid Build Coastguard Worker uint16_t mProtocol;
130*cfb92d14SAndroid Build Coastguard Worker } OT_TOOL_PACKED_END;
131*cfb92d14SAndroid Build Coastguard Worker
132*cfb92d14SAndroid Build Coastguard Worker OT_TOOL_PACKED_BEGIN
133*cfb92d14SAndroid Build Coastguard Worker struct ChecksumData
134*cfb92d14SAndroid Build Coastguard Worker {
135*cfb92d14SAndroid Build Coastguard Worker PseudoHeader mPseudoHeader;
136*cfb92d14SAndroid Build Coastguard Worker uint8_t mPayload[kMaxPayload];
137*cfb92d14SAndroid Build Coastguard Worker } OT_TOOL_PACKED_END;
138*cfb92d14SAndroid Build Coastguard Worker
139*cfb92d14SAndroid Build Coastguard Worker ChecksumData data;
140*cfb92d14SAndroid Build Coastguard Worker uint16_t payloadLength;
141*cfb92d14SAndroid Build Coastguard Worker
142*cfb92d14SAndroid Build Coastguard Worker payloadLength = aMessage.GetLength() - aMessage.GetOffset();
143*cfb92d14SAndroid Build Coastguard Worker
144*cfb92d14SAndroid Build Coastguard Worker data.mPseudoHeader.mSource = aSource;
145*cfb92d14SAndroid Build Coastguard Worker data.mPseudoHeader.mDestination = aDestination;
146*cfb92d14SAndroid Build Coastguard Worker data.mPseudoHeader.mProtocol = BigEndian::HostSwap16(aIpProto);
147*cfb92d14SAndroid Build Coastguard Worker data.mPseudoHeader.mPayloadLength = BigEndian::HostSwap16(payloadLength);
148*cfb92d14SAndroid Build Coastguard Worker
149*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(aMessage.Read(aMessage.GetOffset(), data.mPayload, payloadLength));
150*cfb92d14SAndroid Build Coastguard Worker
151*cfb92d14SAndroid Build Coastguard Worker return CalculateChecksum(&data, sizeof(PseudoHeader) + payloadLength);
152*cfb92d14SAndroid Build Coastguard Worker }
153*cfb92d14SAndroid Build Coastguard Worker
CorruptMessage(Message & aMessage)154*cfb92d14SAndroid Build Coastguard Worker void CorruptMessage(Message &aMessage)
155*cfb92d14SAndroid Build Coastguard Worker {
156*cfb92d14SAndroid Build Coastguard Worker // Change a random bit in the message.
157*cfb92d14SAndroid Build Coastguard Worker
158*cfb92d14SAndroid Build Coastguard Worker uint16_t byteOffset;
159*cfb92d14SAndroid Build Coastguard Worker uint8_t bitOffset;
160*cfb92d14SAndroid Build Coastguard Worker uint8_t byte;
161*cfb92d14SAndroid Build Coastguard Worker
162*cfb92d14SAndroid Build Coastguard Worker byteOffset = Random::NonCrypto::GetUint16InRange(0, aMessage.GetLength());
163*cfb92d14SAndroid Build Coastguard Worker
164*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(aMessage.Read(byteOffset, byte));
165*cfb92d14SAndroid Build Coastguard Worker
166*cfb92d14SAndroid Build Coastguard Worker bitOffset = Random::NonCrypto::GetUint8InRange(0, kBitsPerByte);
167*cfb92d14SAndroid Build Coastguard Worker
168*cfb92d14SAndroid Build Coastguard Worker byte ^= (1 << bitOffset);
169*cfb92d14SAndroid Build Coastguard Worker
170*cfb92d14SAndroid Build Coastguard Worker aMessage.Write(byteOffset, byte);
171*cfb92d14SAndroid Build Coastguard Worker }
172*cfb92d14SAndroid Build Coastguard Worker
TestUdpMessageChecksum(void)173*cfb92d14SAndroid Build Coastguard Worker void TestUdpMessageChecksum(void)
174*cfb92d14SAndroid Build Coastguard Worker {
175*cfb92d14SAndroid Build Coastguard Worker constexpr uint16_t kMinSize = sizeof(Ip6::Udp::Header);
176*cfb92d14SAndroid Build Coastguard Worker constexpr uint16_t kMaxSize = kBufferSize * 3 + 24;
177*cfb92d14SAndroid Build Coastguard Worker
178*cfb92d14SAndroid Build Coastguard Worker const char *kSourceAddress = "fd00:1122:3344:5566:7788:99aa:bbcc:ddee";
179*cfb92d14SAndroid Build Coastguard Worker const char *kDestAddress = "fd01:2345:6789:abcd:ef01:2345:6789:abcd";
180*cfb92d14SAndroid Build Coastguard Worker
181*cfb92d14SAndroid Build Coastguard Worker Instance *instance = static_cast<Instance *>(testInitInstance());
182*cfb92d14SAndroid Build Coastguard Worker
183*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(instance != nullptr);
184*cfb92d14SAndroid Build Coastguard Worker
185*cfb92d14SAndroid Build Coastguard Worker for (uint16_t size = kMinSize; size <= kMaxSize; size++)
186*cfb92d14SAndroid Build Coastguard Worker {
187*cfb92d14SAndroid Build Coastguard Worker Message *message = instance->Get<Ip6::Ip6>().NewMessage(sizeof(Ip6::Udp::Header));
188*cfb92d14SAndroid Build Coastguard Worker Ip6::Udp::Header udpHeader;
189*cfb92d14SAndroid Build Coastguard Worker Ip6::MessageInfo messageInfo;
190*cfb92d14SAndroid Build Coastguard Worker
191*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message != nullptr, "Ip6::NewMesssage() failed");
192*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->SetLength(size));
193*cfb92d14SAndroid Build Coastguard Worker
194*cfb92d14SAndroid Build Coastguard Worker // Write UDP header with a random payload.
195*cfb92d14SAndroid Build Coastguard Worker
196*cfb92d14SAndroid Build Coastguard Worker Random::NonCrypto::Fill(udpHeader);
197*cfb92d14SAndroid Build Coastguard Worker udpHeader.SetChecksum(0);
198*cfb92d14SAndroid Build Coastguard Worker message->Write(0, udpHeader);
199*cfb92d14SAndroid Build Coastguard Worker
200*cfb92d14SAndroid Build Coastguard Worker if (size > sizeof(udpHeader))
201*cfb92d14SAndroid Build Coastguard Worker {
202*cfb92d14SAndroid Build Coastguard Worker uint8_t buffer[kMaxSize];
203*cfb92d14SAndroid Build Coastguard Worker uint16_t payloadSize = size - sizeof(udpHeader);
204*cfb92d14SAndroid Build Coastguard Worker
205*cfb92d14SAndroid Build Coastguard Worker Random::NonCrypto::FillBuffer(buffer, payloadSize);
206*cfb92d14SAndroid Build Coastguard Worker message->WriteBytes(sizeof(udpHeader), &buffer[0], payloadSize);
207*cfb92d14SAndroid Build Coastguard Worker }
208*cfb92d14SAndroid Build Coastguard Worker
209*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(messageInfo.GetSockAddr().FromString(kSourceAddress));
210*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(messageInfo.GetPeerAddr().FromString(kDestAddress));
211*cfb92d14SAndroid Build Coastguard Worker
212*cfb92d14SAndroid Build Coastguard Worker // Verify that the `Checksum::UpdateMessageChecksum` correctly
213*cfb92d14SAndroid Build Coastguard Worker // updates the checksum field in the UDP header on the message.
214*cfb92d14SAndroid Build Coastguard Worker
215*cfb92d14SAndroid Build Coastguard Worker Checksum::UpdateMessageChecksum(*message, messageInfo.GetSockAddr(), messageInfo.GetPeerAddr(), Ip6::kProtoUdp);
216*cfb92d14SAndroid Build Coastguard Worker
217*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(message->GetOffset(), udpHeader));
218*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(udpHeader.GetChecksum() != 0);
219*cfb92d14SAndroid Build Coastguard Worker
220*cfb92d14SAndroid Build Coastguard Worker // Verify that the calculated UDP checksum is valid.
221*cfb92d14SAndroid Build Coastguard Worker
222*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(CalculateChecksum(messageInfo.GetSockAddr(), messageInfo.GetPeerAddr(), Ip6::kProtoUdp,
223*cfb92d14SAndroid Build Coastguard Worker *message) == 0xffff);
224*cfb92d14SAndroid Build Coastguard Worker
225*cfb92d14SAndroid Build Coastguard Worker // Verify that `Checksum::VerifyMessageChecksum()` accepts the
226*cfb92d14SAndroid Build Coastguard Worker // message and its calculated checksum.
227*cfb92d14SAndroid Build Coastguard Worker
228*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Checksum::VerifyMessageChecksum(*message, messageInfo, Ip6::kProtoUdp));
229*cfb92d14SAndroid Build Coastguard Worker
230*cfb92d14SAndroid Build Coastguard Worker // Corrupt the message and verify that checksum is no longer accepted.
231*cfb92d14SAndroid Build Coastguard Worker
232*cfb92d14SAndroid Build Coastguard Worker CorruptMessage(*message);
233*cfb92d14SAndroid Build Coastguard Worker
234*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Checksum::VerifyMessageChecksum(*message, messageInfo, Ip6::kProtoUdp) != kErrorNone,
235*cfb92d14SAndroid Build Coastguard Worker "Checksum passed on corrupted message");
236*cfb92d14SAndroid Build Coastguard Worker
237*cfb92d14SAndroid Build Coastguard Worker message->Free();
238*cfb92d14SAndroid Build Coastguard Worker }
239*cfb92d14SAndroid Build Coastguard Worker }
240*cfb92d14SAndroid Build Coastguard Worker
TestIcmp6MessageChecksum(void)241*cfb92d14SAndroid Build Coastguard Worker void TestIcmp6MessageChecksum(void)
242*cfb92d14SAndroid Build Coastguard Worker {
243*cfb92d14SAndroid Build Coastguard Worker constexpr uint16_t kMinSize = sizeof(Ip6::Icmp::Header);
244*cfb92d14SAndroid Build Coastguard Worker constexpr uint16_t kMaxSize = kBufferSize * 3 + 24;
245*cfb92d14SAndroid Build Coastguard Worker
246*cfb92d14SAndroid Build Coastguard Worker const char *kSourceAddress = "fd00:feef:dccd:baab:9889:7667:5444:3223";
247*cfb92d14SAndroid Build Coastguard Worker const char *kDestAddress = "fd01:abab:beef:cafe:1234:5678:9abc:0";
248*cfb92d14SAndroid Build Coastguard Worker
249*cfb92d14SAndroid Build Coastguard Worker Instance *instance = static_cast<Instance *>(testInitInstance());
250*cfb92d14SAndroid Build Coastguard Worker
251*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(instance != nullptr, "Null OpenThread instance\n");
252*cfb92d14SAndroid Build Coastguard Worker
253*cfb92d14SAndroid Build Coastguard Worker for (uint16_t size = kMinSize; size <= kMaxSize; size++)
254*cfb92d14SAndroid Build Coastguard Worker {
255*cfb92d14SAndroid Build Coastguard Worker Message *message = instance->Get<Ip6::Ip6>().NewMessage(sizeof(Ip6::Icmp::Header));
256*cfb92d14SAndroid Build Coastguard Worker Ip6::Icmp::Header icmp6Header;
257*cfb92d14SAndroid Build Coastguard Worker Ip6::MessageInfo messageInfo;
258*cfb92d14SAndroid Build Coastguard Worker
259*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message != nullptr, "Ip6::NewMesssage() failed");
260*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->SetLength(size));
261*cfb92d14SAndroid Build Coastguard Worker
262*cfb92d14SAndroid Build Coastguard Worker // Write ICMP6 header with a random payload.
263*cfb92d14SAndroid Build Coastguard Worker
264*cfb92d14SAndroid Build Coastguard Worker Random::NonCrypto::Fill(icmp6Header);
265*cfb92d14SAndroid Build Coastguard Worker icmp6Header.SetChecksum(0);
266*cfb92d14SAndroid Build Coastguard Worker message->Write(0, icmp6Header);
267*cfb92d14SAndroid Build Coastguard Worker
268*cfb92d14SAndroid Build Coastguard Worker if (size > sizeof(icmp6Header))
269*cfb92d14SAndroid Build Coastguard Worker {
270*cfb92d14SAndroid Build Coastguard Worker uint8_t buffer[kMaxSize];
271*cfb92d14SAndroid Build Coastguard Worker uint16_t payloadSize = size - sizeof(icmp6Header);
272*cfb92d14SAndroid Build Coastguard Worker
273*cfb92d14SAndroid Build Coastguard Worker Random::NonCrypto::FillBuffer(buffer, payloadSize);
274*cfb92d14SAndroid Build Coastguard Worker message->WriteBytes(sizeof(icmp6Header), &buffer[0], payloadSize);
275*cfb92d14SAndroid Build Coastguard Worker }
276*cfb92d14SAndroid Build Coastguard Worker
277*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(messageInfo.GetSockAddr().FromString(kSourceAddress));
278*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(messageInfo.GetPeerAddr().FromString(kDestAddress));
279*cfb92d14SAndroid Build Coastguard Worker
280*cfb92d14SAndroid Build Coastguard Worker // Verify that the `Checksum::UpdateMessageChecksum` correctly
281*cfb92d14SAndroid Build Coastguard Worker // updates the checksum field in the ICMP6 header on the message.
282*cfb92d14SAndroid Build Coastguard Worker
283*cfb92d14SAndroid Build Coastguard Worker Checksum::UpdateMessageChecksum(*message, messageInfo.GetSockAddr(), messageInfo.GetPeerAddr(),
284*cfb92d14SAndroid Build Coastguard Worker Ip6::kProtoIcmp6);
285*cfb92d14SAndroid Build Coastguard Worker
286*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(message->GetOffset(), icmp6Header));
287*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(icmp6Header.GetChecksum() != 0, "Failed to update checksum");
288*cfb92d14SAndroid Build Coastguard Worker
289*cfb92d14SAndroid Build Coastguard Worker // Verify that the calculated ICMP6 checksum is valid.
290*cfb92d14SAndroid Build Coastguard Worker
291*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(CalculateChecksum(messageInfo.GetSockAddr(), messageInfo.GetPeerAddr(), Ip6::kProtoIcmp6,
292*cfb92d14SAndroid Build Coastguard Worker *message) == 0xffff);
293*cfb92d14SAndroid Build Coastguard Worker
294*cfb92d14SAndroid Build Coastguard Worker // Verify that `Checksum::VerifyMessageChecksum()` accepts the
295*cfb92d14SAndroid Build Coastguard Worker // message and its calculated checksum.
296*cfb92d14SAndroid Build Coastguard Worker
297*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Checksum::VerifyMessageChecksum(*message, messageInfo, Ip6::kProtoIcmp6));
298*cfb92d14SAndroid Build Coastguard Worker
299*cfb92d14SAndroid Build Coastguard Worker // Corrupt the message and verify that checksum is no longer accepted.
300*cfb92d14SAndroid Build Coastguard Worker
301*cfb92d14SAndroid Build Coastguard Worker CorruptMessage(*message);
302*cfb92d14SAndroid Build Coastguard Worker
303*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Checksum::VerifyMessageChecksum(*message, messageInfo, Ip6::kProtoIcmp6) != kErrorNone,
304*cfb92d14SAndroid Build Coastguard Worker "Checksum passed on corrupted message");
305*cfb92d14SAndroid Build Coastguard Worker
306*cfb92d14SAndroid Build Coastguard Worker message->Free();
307*cfb92d14SAndroid Build Coastguard Worker }
308*cfb92d14SAndroid Build Coastguard Worker }
309*cfb92d14SAndroid Build Coastguard Worker
TestTcp4MessageChecksum(void)310*cfb92d14SAndroid Build Coastguard Worker void TestTcp4MessageChecksum(void)
311*cfb92d14SAndroid Build Coastguard Worker {
312*cfb92d14SAndroid Build Coastguard Worker constexpr size_t kMinSize = sizeof(Ip4::Tcp::Header);
313*cfb92d14SAndroid Build Coastguard Worker constexpr size_t kMaxSize = kBufferSize * 3 + 24;
314*cfb92d14SAndroid Build Coastguard Worker
315*cfb92d14SAndroid Build Coastguard Worker const char *kSourceAddress = "12.34.56.78";
316*cfb92d14SAndroid Build Coastguard Worker const char *kDestAddress = "87.65.43.21";
317*cfb92d14SAndroid Build Coastguard Worker
318*cfb92d14SAndroid Build Coastguard Worker Ip4::Address sourceAddress;
319*cfb92d14SAndroid Build Coastguard Worker Ip4::Address destAddress;
320*cfb92d14SAndroid Build Coastguard Worker
321*cfb92d14SAndroid Build Coastguard Worker Instance *instance = static_cast<Instance *>(testInitInstance());
322*cfb92d14SAndroid Build Coastguard Worker
323*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(instance != nullptr);
324*cfb92d14SAndroid Build Coastguard Worker
325*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(sourceAddress.FromString(kSourceAddress));
326*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(destAddress.FromString(kDestAddress));
327*cfb92d14SAndroid Build Coastguard Worker
328*cfb92d14SAndroid Build Coastguard Worker for (uint16_t size = kMinSize; size <= kMaxSize; size++)
329*cfb92d14SAndroid Build Coastguard Worker {
330*cfb92d14SAndroid Build Coastguard Worker Message *message = instance->Get<Ip6::Ip6>().NewMessage(sizeof(Ip4::Tcp::Header));
331*cfb92d14SAndroid Build Coastguard Worker Ip4::Tcp::Header tcpHeader;
332*cfb92d14SAndroid Build Coastguard Worker
333*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message != nullptr, "Ip6::NewMesssage() failed");
334*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->SetLength(size));
335*cfb92d14SAndroid Build Coastguard Worker
336*cfb92d14SAndroid Build Coastguard Worker // Write TCP header with a random payload.
337*cfb92d14SAndroid Build Coastguard Worker
338*cfb92d14SAndroid Build Coastguard Worker Random::NonCrypto::Fill(tcpHeader);
339*cfb92d14SAndroid Build Coastguard Worker message->Write(0, tcpHeader);
340*cfb92d14SAndroid Build Coastguard Worker
341*cfb92d14SAndroid Build Coastguard Worker if (size > sizeof(tcpHeader))
342*cfb92d14SAndroid Build Coastguard Worker {
343*cfb92d14SAndroid Build Coastguard Worker uint8_t buffer[kMaxSize];
344*cfb92d14SAndroid Build Coastguard Worker uint16_t payloadSize = size - sizeof(tcpHeader);
345*cfb92d14SAndroid Build Coastguard Worker
346*cfb92d14SAndroid Build Coastguard Worker Random::NonCrypto::FillBuffer(buffer, payloadSize);
347*cfb92d14SAndroid Build Coastguard Worker message->WriteBytes(sizeof(tcpHeader), &buffer[0], payloadSize);
348*cfb92d14SAndroid Build Coastguard Worker }
349*cfb92d14SAndroid Build Coastguard Worker
350*cfb92d14SAndroid Build Coastguard Worker // Verify that the `Checksum::UpdateMessageChecksum` correctly
351*cfb92d14SAndroid Build Coastguard Worker // updates the checksum field in the UDP header on the message.
352*cfb92d14SAndroid Build Coastguard Worker
353*cfb92d14SAndroid Build Coastguard Worker Checksum::UpdateMessageChecksum(*message, sourceAddress, destAddress, Ip4::kProtoTcp);
354*cfb92d14SAndroid Build Coastguard Worker
355*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(message->GetOffset(), tcpHeader));
356*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(tcpHeader.GetChecksum() != 0);
357*cfb92d14SAndroid Build Coastguard Worker
358*cfb92d14SAndroid Build Coastguard Worker // Verify that the calculated UDP checksum is valid.
359*cfb92d14SAndroid Build Coastguard Worker
360*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(CalculateChecksum(sourceAddress, destAddress, Ip4::kProtoTcp, *message) == 0xffff);
361*cfb92d14SAndroid Build Coastguard Worker message->Free();
362*cfb92d14SAndroid Build Coastguard Worker }
363*cfb92d14SAndroid Build Coastguard Worker }
364*cfb92d14SAndroid Build Coastguard Worker
TestUdp4MessageChecksum(void)365*cfb92d14SAndroid Build Coastguard Worker void TestUdp4MessageChecksum(void)
366*cfb92d14SAndroid Build Coastguard Worker {
367*cfb92d14SAndroid Build Coastguard Worker constexpr uint16_t kMinSize = sizeof(Ip4::Udp::Header);
368*cfb92d14SAndroid Build Coastguard Worker constexpr uint16_t kMaxSize = kBufferSize * 3 + 24;
369*cfb92d14SAndroid Build Coastguard Worker
370*cfb92d14SAndroid Build Coastguard Worker const char *kSourceAddress = "12.34.56.78";
371*cfb92d14SAndroid Build Coastguard Worker const char *kDestAddress = "87.65.43.21";
372*cfb92d14SAndroid Build Coastguard Worker
373*cfb92d14SAndroid Build Coastguard Worker Ip4::Address sourceAddress;
374*cfb92d14SAndroid Build Coastguard Worker Ip4::Address destAddress;
375*cfb92d14SAndroid Build Coastguard Worker
376*cfb92d14SAndroid Build Coastguard Worker Instance *instance = static_cast<Instance *>(testInitInstance());
377*cfb92d14SAndroid Build Coastguard Worker
378*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(sourceAddress.FromString(kSourceAddress));
379*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(destAddress.FromString(kDestAddress));
380*cfb92d14SAndroid Build Coastguard Worker
381*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(instance != nullptr);
382*cfb92d14SAndroid Build Coastguard Worker
383*cfb92d14SAndroid Build Coastguard Worker for (uint16_t size = kMinSize; size <= kMaxSize; size++)
384*cfb92d14SAndroid Build Coastguard Worker {
385*cfb92d14SAndroid Build Coastguard Worker Message *message = instance->Get<Ip6::Ip6>().NewMessage(sizeof(Ip4::Udp::Header));
386*cfb92d14SAndroid Build Coastguard Worker Ip4::Udp::Header udpHeader;
387*cfb92d14SAndroid Build Coastguard Worker
388*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message != nullptr, "Ip6::NewMesssage() failed");
389*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->SetLength(size));
390*cfb92d14SAndroid Build Coastguard Worker
391*cfb92d14SAndroid Build Coastguard Worker // Write UDP header with a random payload.
392*cfb92d14SAndroid Build Coastguard Worker
393*cfb92d14SAndroid Build Coastguard Worker Random::NonCrypto::Fill(udpHeader);
394*cfb92d14SAndroid Build Coastguard Worker udpHeader.SetChecksum(0);
395*cfb92d14SAndroid Build Coastguard Worker message->Write(0, udpHeader);
396*cfb92d14SAndroid Build Coastguard Worker
397*cfb92d14SAndroid Build Coastguard Worker if (size > sizeof(udpHeader))
398*cfb92d14SAndroid Build Coastguard Worker {
399*cfb92d14SAndroid Build Coastguard Worker uint8_t buffer[kMaxSize];
400*cfb92d14SAndroid Build Coastguard Worker uint16_t payloadSize = size - sizeof(udpHeader);
401*cfb92d14SAndroid Build Coastguard Worker
402*cfb92d14SAndroid Build Coastguard Worker Random::NonCrypto::FillBuffer(buffer, payloadSize);
403*cfb92d14SAndroid Build Coastguard Worker message->WriteBytes(sizeof(udpHeader), &buffer[0], payloadSize);
404*cfb92d14SAndroid Build Coastguard Worker }
405*cfb92d14SAndroid Build Coastguard Worker
406*cfb92d14SAndroid Build Coastguard Worker // Verify that the `Checksum::UpdateMessageChecksum` correctly
407*cfb92d14SAndroid Build Coastguard Worker // updates the checksum field in the UDP header on the message.
408*cfb92d14SAndroid Build Coastguard Worker
409*cfb92d14SAndroid Build Coastguard Worker Checksum::UpdateMessageChecksum(*message, sourceAddress, destAddress, Ip4::kProtoUdp);
410*cfb92d14SAndroid Build Coastguard Worker
411*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(message->GetOffset(), udpHeader));
412*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(udpHeader.GetChecksum() != 0);
413*cfb92d14SAndroid Build Coastguard Worker
414*cfb92d14SAndroid Build Coastguard Worker // Verify that the calculated UDP checksum is valid.
415*cfb92d14SAndroid Build Coastguard Worker
416*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(CalculateChecksum(sourceAddress, destAddress, Ip4::kProtoUdp, *message) == 0xffff);
417*cfb92d14SAndroid Build Coastguard Worker message->Free();
418*cfb92d14SAndroid Build Coastguard Worker }
419*cfb92d14SAndroid Build Coastguard Worker }
420*cfb92d14SAndroid Build Coastguard Worker
TestIcmp4MessageChecksum(void)421*cfb92d14SAndroid Build Coastguard Worker void TestIcmp4MessageChecksum(void)
422*cfb92d14SAndroid Build Coastguard Worker {
423*cfb92d14SAndroid Build Coastguard Worker // A captured ICMP echo request (ping) message. Checksum field is set to zero.
424*cfb92d14SAndroid Build Coastguard Worker const uint8_t kExampleIcmpMessage[] = "\x08\x00\x00\x00\x67\x2e\x00\x00\x62\xaf\xf1\x61\x00\x04\xfc\x24"
425*cfb92d14SAndroid Build Coastguard Worker "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17"
426*cfb92d14SAndroid Build Coastguard Worker "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27"
427*cfb92d14SAndroid Build Coastguard Worker "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37";
428*cfb92d14SAndroid Build Coastguard Worker uint16_t kChecksumForExampleMessage = 0x5594;
429*cfb92d14SAndroid Build Coastguard Worker Instance *instance = static_cast<Instance *>(testInitInstance());
430*cfb92d14SAndroid Build Coastguard Worker Message *message = instance->Get<Ip6::Ip6>().NewMessage(sizeof(kExampleIcmpMessage));
431*cfb92d14SAndroid Build Coastguard Worker
432*cfb92d14SAndroid Build Coastguard Worker Ip4::Address source;
433*cfb92d14SAndroid Build Coastguard Worker Ip4::Address dest;
434*cfb92d14SAndroid Build Coastguard Worker
435*cfb92d14SAndroid Build Coastguard Worker uint8_t mPayload[sizeof(kExampleIcmpMessage)];
436*cfb92d14SAndroid Build Coastguard Worker Ip4::Icmp::Header icmpHeader;
437*cfb92d14SAndroid Build Coastguard Worker
438*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->AppendBytes(kExampleIcmpMessage, sizeof(kExampleIcmpMessage)));
439*cfb92d14SAndroid Build Coastguard Worker
440*cfb92d14SAndroid Build Coastguard Worker // Random IPv4 address, ICMP message checksum does not include a presudo header like TCP and UDP.
441*cfb92d14SAndroid Build Coastguard Worker source.mFields.m32 = 0x12345678;
442*cfb92d14SAndroid Build Coastguard Worker dest.mFields.m32 = 0x87654321;
443*cfb92d14SAndroid Build Coastguard Worker
444*cfb92d14SAndroid Build Coastguard Worker Checksum::UpdateMessageChecksum(*message, source, dest, Ip4::kProtoIcmp);
445*cfb92d14SAndroid Build Coastguard Worker
446*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(0, icmpHeader));
447*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(icmpHeader.GetChecksum() == kChecksumForExampleMessage);
448*cfb92d14SAndroid Build Coastguard Worker
449*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(message->GetOffset(), mPayload, sizeof(mPayload)));
450*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(CalculateChecksum(mPayload, sizeof(mPayload)) == 0xffff);
451*cfb92d14SAndroid Build Coastguard Worker }
452*cfb92d14SAndroid Build Coastguard Worker
453*cfb92d14SAndroid Build Coastguard Worker class ChecksumTester
454*cfb92d14SAndroid Build Coastguard Worker {
455*cfb92d14SAndroid Build Coastguard Worker public:
TestExampleVector(void)456*cfb92d14SAndroid Build Coastguard Worker static void TestExampleVector(void)
457*cfb92d14SAndroid Build Coastguard Worker {
458*cfb92d14SAndroid Build Coastguard Worker // Example from RFC 1071
459*cfb92d14SAndroid Build Coastguard Worker const uint8_t kTestVector[] = {0x00, 0x01, 0xf2, 0x03, 0xf4, 0xf5, 0xf6, 0xf7};
460*cfb92d14SAndroid Build Coastguard Worker const uint16_t kTestVectorChecksum = 0xddf2;
461*cfb92d14SAndroid Build Coastguard Worker
462*cfb92d14SAndroid Build Coastguard Worker Checksum checksum;
463*cfb92d14SAndroid Build Coastguard Worker
464*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(checksum.GetValue() == 0, "Incorrect initial checksum value");
465*cfb92d14SAndroid Build Coastguard Worker
466*cfb92d14SAndroid Build Coastguard Worker checksum.AddData(kTestVector, sizeof(kTestVector));
467*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(checksum.GetValue() == kTestVectorChecksum);
468*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(checksum.GetValue() == CalculateChecksum(kTestVector, sizeof(kTestVector)), );
469*cfb92d14SAndroid Build Coastguard Worker }
470*cfb92d14SAndroid Build Coastguard Worker };
471*cfb92d14SAndroid Build Coastguard Worker
472*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
473*cfb92d14SAndroid Build Coastguard Worker
TestVerhoeffChecksum(void)474*cfb92d14SAndroid Build Coastguard Worker void TestVerhoeffChecksum(void)
475*cfb92d14SAndroid Build Coastguard Worker {
476*cfb92d14SAndroid Build Coastguard Worker static constexpr uint16_t kMaxStringSize = 50;
477*cfb92d14SAndroid Build Coastguard Worker
478*cfb92d14SAndroid Build Coastguard Worker const char *kExamples[] = {"307318421", "487300178", "123455672", "0", "15",
479*cfb92d14SAndroid Build Coastguard Worker "999999994", "000000001", "100000000", "2363"};
480*cfb92d14SAndroid Build Coastguard Worker
481*cfb92d14SAndroid Build Coastguard Worker const char *kInvalidFormats[] = {
482*cfb92d14SAndroid Build Coastguard Worker "307 318421",
483*cfb92d14SAndroid Build Coastguard Worker "307318421 ",
484*cfb92d14SAndroid Build Coastguard Worker " 307318421",
485*cfb92d14SAndroid Build Coastguard Worker "ABCDE",
486*cfb92d14SAndroid Build Coastguard Worker };
487*cfb92d14SAndroid Build Coastguard Worker
488*cfb92d14SAndroid Build Coastguard Worker char string[kMaxStringSize];
489*cfb92d14SAndroid Build Coastguard Worker char checksum;
490*cfb92d14SAndroid Build Coastguard Worker char expectedChecksum;
491*cfb92d14SAndroid Build Coastguard Worker
492*cfb92d14SAndroid Build Coastguard Worker printf("\nVerhoeffChecksum\n");
493*cfb92d14SAndroid Build Coastguard Worker
494*cfb92d14SAndroid Build Coastguard Worker for (const char *example : kExamples)
495*cfb92d14SAndroid Build Coastguard Worker {
496*cfb92d14SAndroid Build Coastguard Worker uint16_t length = StringLength(example, kMaxStringSize - 1);
497*cfb92d14SAndroid Build Coastguard Worker
498*cfb92d14SAndroid Build Coastguard Worker memcpy(string, example, length + 1);
499*cfb92d14SAndroid Build Coastguard Worker
500*cfb92d14SAndroid Build Coastguard Worker printf("- \"%s\"\n", string);
501*cfb92d14SAndroid Build Coastguard Worker
502*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Utils::VerhoeffChecksum::Validate(string));
503*cfb92d14SAndroid Build Coastguard Worker
504*cfb92d14SAndroid Build Coastguard Worker expectedChecksum = string[length - 1];
505*cfb92d14SAndroid Build Coastguard Worker
506*cfb92d14SAndroid Build Coastguard Worker string[length - 1] = (expectedChecksum == '0') ? '9' : (expectedChecksum - 1);
507*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Utils::VerhoeffChecksum::Validate(string) == kErrorFailed);
508*cfb92d14SAndroid Build Coastguard Worker
509*cfb92d14SAndroid Build Coastguard Worker string[length - 1] = '\0';
510*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(Utils::VerhoeffChecksum::Calculate(string, checksum));
511*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(checksum == expectedChecksum);
512*cfb92d14SAndroid Build Coastguard Worker
513*cfb92d14SAndroid Build Coastguard Worker string[length - 1] = expectedChecksum == '0' ? '9' : (expectedChecksum - 1);
514*cfb92d14SAndroid Build Coastguard Worker }
515*cfb92d14SAndroid Build Coastguard Worker
516*cfb92d14SAndroid Build Coastguard Worker printf("\nInvalid format:\n");
517*cfb92d14SAndroid Build Coastguard Worker
518*cfb92d14SAndroid Build Coastguard Worker for (const char *example : kInvalidFormats)
519*cfb92d14SAndroid Build Coastguard Worker {
520*cfb92d14SAndroid Build Coastguard Worker printf("- \"%s\"\n", example);
521*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Utils::VerhoeffChecksum::Validate(example) == kErrorInvalidArgs);
522*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(Utils::VerhoeffChecksum::Calculate(example, checksum) == kErrorInvalidArgs);
523*cfb92d14SAndroid Build Coastguard Worker }
524*cfb92d14SAndroid Build Coastguard Worker }
525*cfb92d14SAndroid Build Coastguard Worker
526*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
527*cfb92d14SAndroid Build Coastguard Worker
528*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
529*cfb92d14SAndroid Build Coastguard Worker
main(void)530*cfb92d14SAndroid Build Coastguard Worker int main(void)
531*cfb92d14SAndroid Build Coastguard Worker {
532*cfb92d14SAndroid Build Coastguard Worker ot::ChecksumTester::TestExampleVector();
533*cfb92d14SAndroid Build Coastguard Worker ot::TestUdpMessageChecksum();
534*cfb92d14SAndroid Build Coastguard Worker ot::TestIcmp6MessageChecksum();
535*cfb92d14SAndroid Build Coastguard Worker ot::TestTcp4MessageChecksum();
536*cfb92d14SAndroid Build Coastguard Worker ot::TestUdp4MessageChecksum();
537*cfb92d14SAndroid Build Coastguard Worker ot::TestIcmp4MessageChecksum();
538*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_VERHOEFF_CHECKSUM_ENABLE
539*cfb92d14SAndroid Build Coastguard Worker ot::TestVerhoeffChecksum();
540*cfb92d14SAndroid Build Coastguard Worker #endif
541*cfb92d14SAndroid Build Coastguard Worker
542*cfb92d14SAndroid Build Coastguard Worker printf("All tests passed\n");
543*cfb92d14SAndroid Build Coastguard Worker return 0;
544*cfb92d14SAndroid Build Coastguard Worker }
545