1 /* 2 * Copyright (c) 2022, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file 31 * This file includes definitions for IPv4 packet processing. 32 */ 33 34 #ifndef IP4_TYPES_HPP_ 35 #define IP4_TYPES_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include <stddef.h> 40 41 #include <openthread/nat64.h> 42 43 #include "common/clearable.hpp" 44 #include "common/encoding.hpp" 45 #include "common/message.hpp" 46 #include "net/ip6_types.hpp" 47 #include "net/netif.hpp" 48 #include "net/socket.hpp" 49 #include "net/tcp6.hpp" 50 #include "net/udp6.hpp" 51 52 namespace ot { 53 54 namespace Ip6 { 55 // Forward declaration for ExtractFromIp4Address 56 class Address; 57 } // namespace Ip6 58 59 /** 60 * @namespace ot::Ip4 61 * 62 * @brief 63 * This namespace includes definitions for IPv4 networking used by NAT64. 64 * 65 */ 66 namespace Ip4 { 67 68 using Ecn = Ip6::Ecn; 69 70 /** 71 * @addtogroup core-ipv4 72 * 73 * @brief 74 * This module includes definitions for the IPv4 network layer. 75 * 76 */ 77 78 /** 79 * @addtogroup core-ip4-ip4 80 * 81 * @brief 82 * This module includes definitions for IPv4 networking used by NAT64. 83 * 84 * @{ 85 * 86 */ 87 88 // Forward declaration for Address::SynthesizeFromCidrAndHost 89 class Cidr; 90 91 /** 92 * Represents an IPv4 address. 93 * 94 */ 95 OT_TOOL_PACKED_BEGIN 96 class Address : public otIp4Address, public Equatable<Address>, public Clearable<Address> 97 { 98 public: 99 static constexpr uint16_t kSize = 4; ///< Size of an IPv4 Address (in bytes). 100 static constexpr uint16_t kAddressStringSize = 17; ///< String size used by `ToString()`. 101 102 /** 103 * Defines the fixed-length `String` object returned from `ToString()`. 104 * 105 */ 106 typedef String<kAddressStringSize> InfoString; 107 108 /** 109 * Gets the IPv4 address as a pointer to a byte array. 110 * 111 * @returns A pointer to a byte array containing the IPv4 address. 112 * 113 */ GetBytes(void) const114 const uint8_t *GetBytes(void) const { return mFields.m8; } 115 116 /** 117 * Sets the IPv4 address from a given byte array. 118 * 119 * @param[in] aBuffer Pointer to an array containing the IPv4 address. `kSize` bytes from the buffer 120 * are copied to form the IPv4 address. 121 * 122 */ SetBytes(const uint8_t * aBuffer)123 void SetBytes(const uint8_t *aBuffer) { memcpy(mFields.m8, aBuffer, kSize); } 124 125 /** 126 * Sets the IPv4 address by performing NAT64 address translation from a given IPv6 address as specified 127 * in RFC 6052. 128 * 129 * The NAT64 @p aPrefixLength MUST be one of the following values: 32, 40, 48, 56, 64, or 96, otherwise the behavior 130 * of this method is undefined. 131 * 132 * @param[in] aPrefixLength The prefix length to use for IPv4/IPv6 translation. 133 * @param[in] aIp6Address The IPv6 address to translate to IPv4. 134 * 135 */ 136 void ExtractFromIp6Address(uint8_t aPrefixLength, const Ip6::Address &aIp6Address); 137 138 /** 139 * Sets the IPv4 address from the given CIDR and the host field. 140 * 141 * @param[in] aCidr The CIDR for the IPv4 address. 142 * @param[in] aHost The host bits of the IPv4 address in host byte order. The aHost will be masked by host mask. 143 * 144 */ 145 void SynthesizeFromCidrAndHost(const Cidr &aCidr, uint32_t aHost); 146 147 /** 148 * Parses an IPv4 address string terminated by `aTerminatorChar`. 149 * 150 * The string MUST follow the quad-dotted notation of four decimal values (ranging from 0 to 255 each). For 151 * example, "127.0.0.1" 152 * 153 * @param[in] aString A pointer to the null-terminated string. 154 * 155 * @retval kErrorNone Successfully parsed the IPv4 address string. 156 * @retval kErrorParse Failed to parse the IPv4 address string. 157 * 158 */ 159 Error FromString(const char *aString, char aTerminatorChar = kNullChar); 160 161 /** 162 * Converts the address to a string. 163 * 164 * The string format uses quad-dotted notation of four bytes in the address (e.g., "127.0.0.1"). 165 * 166 * If the resulting string does not fit in @p aBuffer (within its @p aSize characters), the string will be 167 * truncated but the outputted string is always null-terminated. 168 * 169 * @param[out] aBuffer A pointer to a char array to output the string (MUST NOT be `nullptr`). 170 * @param[in] aSize The size of @p aBuffer (in bytes). 171 * 172 */ 173 void ToString(char *aBuffer, uint16_t aSize) const; 174 175 /** 176 * Converts the IPv4 address to a string. 177 * 178 * The string format uses quad-dotted notation of four bytes in the address (e.g., "127.0.0.1"). 179 * 180 * @returns An `InfoString` representing the IPv4 address. 181 * 182 */ 183 InfoString ToString(void) const; 184 185 private: 186 void ToString(StringWriter &aWriter) const; 187 } OT_TOOL_PACKED_END; 188 189 /** 190 * Represents an IPv4 CIDR block. 191 * 192 */ 193 class Cidr : public otIp4Cidr, public Unequatable<Cidr>, public Clearable<Address> 194 { 195 friend class Address; 196 197 public: 198 static constexpr uint16_t kCidrSuffixSize = 3; ///< Suffix to represent CIDR (/dd). 199 200 /** 201 * Defines the fixed-length `String` object returned from `ToString()`. 202 * 203 */ 204 typedef String<Address::kAddressStringSize + kCidrSuffixSize> InfoString; 205 206 /** 207 * Converts the IPv4 CIDR string to binary. 208 * 209 * The string format uses quad-dotted notation of four bytes in the address with the length of prefix (e.g., 210 * "127.0.0.1/32"). 211 * 212 * @param[in] aString A pointer to the null-terminated string. 213 * 214 * @retval kErrorNone Successfully parsed the IPv4 CIDR string. 215 * @retval kErrorParse Failed to parse the IPv4 CIDR string. 216 * 217 */ 218 Error FromString(const char *aString); 219 220 /** 221 * Converts the IPv4 CIDR to a string. 222 * 223 * The string format uses quad-dotted notation of four bytes in the address with the length of prefix (e.g., 224 * "127.0.0.1/32"). 225 * 226 * If the resulting string does not fit in @p aBuffer (within its @p aSize characters), the string will be 227 * truncated but the outputted string is always null-terminated. 228 * 229 * @param[out] aBuffer A pointer to a char array to output the string (MUST NOT be `nullptr`). 230 * @param[in] aSize The size of @p aBuffer (in bytes). 231 * 232 */ 233 void ToString(char *aBuffer, uint16_t aSize) const; 234 235 /** 236 * Converts the IPv4 CIDR to a string. 237 * 238 * The string format uses quad-dotted notation of four bytes in the address with the length of prefix (e.g., 239 * "127.0.0.1/32"). 240 * 241 * @returns An `InfoString` representing the IPv4 cidr. 242 * 243 */ 244 InfoString ToString(void) const; 245 246 /** 247 * Gets the prefix as a pointer to a byte array. 248 * 249 * @returns A pointer to a byte array containing the Prefix. 250 * 251 */ GetBytes(void) const252 const uint8_t *GetBytes(void) const { return mAddress.mFields.m8; } 253 254 /** 255 * Overloads operator `==` to evaluate whether or not two prefixes are equal. 256 * 257 * @param[in] aOther The other prefix to compare with. 258 * 259 * @retval TRUE If the two prefixes are equal. 260 * @retval FALSE If the two prefixes are not equal. 261 * 262 */ 263 bool operator==(const Cidr &aOther) const; 264 265 /** 266 * Sets the CIDR. 267 * 268 * @param[in] aAddress A pointer to buffer containing the CIDR bytes. The length of aAddress should be 4 bytes. 269 * @param[in] aLength The length of CIDR in bits. 270 * 271 */ 272 void Set(const uint8_t *aAddress, uint8_t aLength); 273 274 private: HostMask(void) const275 uint32_t HostMask(void) const 276 { 277 // Note: Using LL suffix to make it a uint64 since /32 is a valid CIDR, and right shifting 32 bits is undefined 278 // for uint32. 279 return BigEndian::HostSwap32(0xffffffffLL >> mLength); 280 } 281 SubnetMask(void) const282 uint32_t SubnetMask(void) const { return ~HostMask(); } 283 284 void ToString(StringWriter &aWriter) const; 285 }; 286 287 /** 288 * Implements IPv4 header generation and parsing. 289 * 290 */ 291 OT_TOOL_PACKED_BEGIN 292 class Header : public Clearable<Header> 293 { 294 public: 295 static constexpr uint8_t kVersionIhlOffset = 0; 296 static constexpr uint8_t kTrafficClassOffset = 1; 297 static constexpr uint8_t kTotalLengthOffset = 2; 298 static constexpr uint8_t kIdentificationOffset = 4; 299 static constexpr uint8_t kFlagsFragmentOffset = 6; 300 static constexpr uint8_t kTtlOffset = 8; 301 static constexpr uint8_t kProtocolOffset = 9; 302 static constexpr uint8_t kHeaderChecksumOffset = 10; 303 static constexpr uint8_t kSourceAddressOffset = 12; 304 static constexpr uint8_t kDestinationAddressOffset = 16; 305 306 /** 307 * Indicates whether or not the header appears to be well-formed. 308 * 309 * @retval TRUE If the header appears to be well-formed. 310 * @retval FALSE If the header does not appear to be well-formed. 311 * 312 */ IsValid(void) const313 bool IsValid(void) const { return IsVersion4(); } 314 315 /** 316 * Initializes the Version to 4 and sets Traffic Class and Flow fields to zero. 317 * 318 * The other fields in the IPv4 header remain unchanged. 319 * 320 */ InitVersionIhl(void)321 void InitVersionIhl(void) { SetVersionIhl(kVersIhlInit); } 322 323 /** 324 * Sets the version and Ihl of the IPv4 header. 325 * 326 * @param[in] aVersionIhl The octet for the version and Ihl field. 327 * 328 */ SetVersionIhl(uint8_t aVersionIhl)329 void SetVersionIhl(uint8_t aVersionIhl) { mVersIhl = aVersionIhl; } 330 331 /** 332 * Indicates whether or not the IPv4 Version is set to 6. 333 * 334 * @retval TRUE If the IPv4 Version is set to 4. 335 * @retval FALSE If the IPv4 Version is not set to 4. 336 * 337 */ IsVersion4(void) const338 bool IsVersion4(void) const { return (mVersIhl & kVersionMask) == kVersion4; } 339 340 /** 341 * Returns the octet for DSCP + ECN. 342 * 343 * @retval The octet for DSCP and ECN. 344 * 345 */ GetDscpEcn(void) const346 uint8_t GetDscpEcn(void) const { return mDscpEcn; } 347 348 /** 349 * Gets the 6-bit Differentiated Services Code Point (DSCP) from Traffic Class field. 350 * 351 * @returns The DSCP value. 352 * 353 */ GetDscp(void) const354 uint8_t GetDscp(void) const { return (mDscpEcn & kDscpMask) >> kDscpOffset; } 355 356 /** 357 * Sets 6-bit Differentiated Services Code Point (DSCP) in IPv4 header. 358 * 359 * @param[in] aDscp The DSCP value. 360 * 361 */ SetDscp(uint8_t aDscp)362 void SetDscp(uint8_t aDscp) { mDscpEcn = static_cast<uint8_t>((mDscpEcn & ~kDscpMask) | (aDscp << kDscpOffset)); } 363 364 /** 365 * Gets the 2-bit Explicit Congestion Notification (ECN) from Traffic Class field. 366 * 367 * @returns The ECN value. 368 * 369 */ GetEcn(void) const370 Ecn GetEcn(void) const { return static_cast<Ecn>(mDscpEcn & kEcnMask); } 371 372 /** 373 * Sets the 2-bit Explicit Congestion Notification (ECN) in IPv4 header.. 374 * 375 * @param[in] aEcn The ECN value. 376 * 377 */ SetEcn(Ecn aEcn)378 void SetEcn(Ecn aEcn) { mDscpEcn = ((mDscpEcn & ~kEcnMask) | aEcn); } 379 380 /** 381 * Returns the IPv4 Payload Length value. 382 * 383 * @returns The IPv4 Payload Length value. 384 * 385 */ GetTotalLength(void) const386 uint16_t GetTotalLength(void) const { return BigEndian::HostSwap16(mTotalLength); } 387 388 /** 389 * Sets the IPv4 Payload Length value. 390 * 391 * @param[in] aLength The IPv4 Payload Length value. 392 * 393 */ SetTotalLength(uint16_t aLength)394 void SetTotalLength(uint16_t aLength) { mTotalLength = BigEndian::HostSwap16(aLength); } 395 396 /** 397 * Returns the IPv4 payload protocol. 398 * 399 * @returns The IPv4 payload protocol value. 400 * 401 */ GetProtocol(void) const402 uint8_t GetProtocol(void) const { return mProtocol; } 403 404 /** 405 * Sets the IPv4 payload protocol. 406 * 407 * @param[in] aProtocol The IPv4 payload protocol. 408 * 409 */ SetProtocol(uint8_t aProtocol)410 void SetProtocol(uint8_t aProtocol) { mProtocol = aProtocol; } 411 412 /** 413 * Returns the IPv4 header checksum, the checksum is in host endian. 414 * 415 * @returns The checksum field in the IPv4 header. 416 * 417 */ GetChecksum(void) const418 uint16_t GetChecksum(void) const { return BigEndian::HostSwap16(mHeaderChecksum); } 419 420 /** 421 * Sets the IPv4 header checksum, the checksum is in host endian. 422 * 423 * @param[in] aChecksum The checksum for the IPv4 header. 424 * 425 */ SetChecksum(uint16_t aChecksum)426 void SetChecksum(uint16_t aChecksum) { mHeaderChecksum = BigEndian::HostSwap16(aChecksum); } 427 428 /** 429 * Returns the IPv4 Identification value. 430 * 431 * @returns The IPv4 Identification value. 432 * 433 */ GetIdentification(void) const434 uint16_t GetIdentification(void) const { return BigEndian::HostSwap16(mIdentification); } 435 436 /** 437 * Sets the IPv4 Identification value. 438 * 439 * @param[in] aIdentification The IPv4 Identification value. 440 * 441 */ SetIdentification(uint16_t aIdentification)442 void SetIdentification(uint16_t aIdentification) { mIdentification = BigEndian::HostSwap16(aIdentification); } 443 444 /** 445 * Returns the IPv4 Time-to-Live value. 446 * 447 * @returns The IPv4 Time-to-Live value. 448 * 449 */ GetTtl(void) const450 uint8_t GetTtl(void) const { return mTtl; } 451 452 /** 453 * Sets the IPv4 Time-to-Live value. 454 * 455 * @param[in] aTtl The IPv4 Time-to-Live value. 456 * 457 */ SetTtl(uint8_t aTtl)458 void SetTtl(uint8_t aTtl) { mTtl = aTtl; } 459 460 /** 461 * Returns the IPv4 Source address. 462 * 463 * @returns A reference to the IPv4 Source address. 464 * 465 */ GetSource(void)466 Address &GetSource(void) { return mSource; } 467 468 /** 469 * Returns the IPv4 Source address. 470 * 471 * @returns A reference to the IPv4 Source address. 472 * 473 */ GetSource(void) const474 const Address &GetSource(void) const { return mSource; } 475 476 /** 477 * Sets the IPv4 Source address. 478 * 479 * @param[in] aSource A reference to the IPv4 Source address. 480 * 481 */ SetSource(const Address & aSource)482 void SetSource(const Address &aSource) { mSource = aSource; } 483 484 /** 485 * Returns the IPv4 Destination address. 486 * 487 * @returns A reference to the IPv4 Destination address. 488 * 489 */ GetDestination(void)490 Address &GetDestination(void) { return mDestination; } 491 492 /** 493 * Returns the IPv4 Destination address. 494 * 495 * @returns A reference to the IPv4 Destination address. 496 * 497 */ GetDestination(void) const498 const Address &GetDestination(void) const { return mDestination; } 499 500 /** 501 * Sets the IPv4 Destination address. 502 * 503 * @param[in] aDestination A reference to the IPv4 Destination address. 504 * 505 */ SetDestination(const Address & aDestination)506 void SetDestination(const Address &aDestination) { mDestination = aDestination; } 507 508 /** 509 * Parses and validates the IPv4 header from a given message. 510 * 511 * The header is read from @p aMessage at offset zero. 512 * 513 * @param[in] aMessage The IPv4 message. 514 * 515 * @retval kErrorNone Successfully parsed the IPv4 header from @p aMessage. 516 * @retval kErrorParse Malformed IPv4 header or message (e.g., message does not contained expected payload length). 517 * 518 */ 519 Error ParseFrom(const Message &aMessage); 520 521 /** 522 * Returns the Df flag in the IPv4 header. 523 * 524 * @returns Whether don't fragment flag is set. 525 * 526 */ GetDf(void) const527 bool GetDf(void) const { return BigEndian::HostSwap16(mFlagsFragmentOffset) & kFlagsDf; } 528 529 /** 530 * Returns the Mf flag in the IPv4 header. 531 * 532 * @returns Whether more fragments flag is set. 533 * 534 */ GetMf(void) const535 bool GetMf(void) const { return BigEndian::HostSwap16(mFlagsFragmentOffset) & kFlagsMf; } 536 537 /** 538 * Returns the fragment offset in the IPv4 header. 539 * 540 * @returns The fragment offset of the IPv4 packet. 541 * 542 */ GetFragmentOffset(void) const543 uint16_t GetFragmentOffset(void) const { return BigEndian::HostSwap16(mFlagsFragmentOffset) & kFragmentOffsetMask; } 544 545 private: 546 // IPv4 header 547 // 548 // +---------------+---------------+---------------+---------------+ 549 // |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0| 550 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 551 // |Version| IHL | DSCP |ECN| Total Length | 552 // | Identification |Flags| Fragment Offset | 553 // | TTL | Protocol | Header Checksum | 554 // | Source IP Address | 555 // | Dest IP Address | 556 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 557 558 static constexpr uint8_t kVersion4 = 0x40; // Use with `mVersIhl` 559 static constexpr uint8_t kVersionMask = 0xf0; // Use with `mVersIhl` 560 static constexpr uint8_t kIhlMask = 0x0f; // Use with `mVersIhl` 561 static constexpr uint8_t kDscpOffset = 2; // Use with `mDscpEcn` 562 static constexpr uint16_t kDscpMask = 0xfc; // Use with `mDscpEcn` 563 static constexpr uint8_t kEcnOffset = 0; // Use with `mDscpEcn` 564 static constexpr uint8_t kEcnMask = 0x03; // Use with `mDscpEcn` 565 static constexpr uint16_t kFlagsMask = 0xe000; // Use with `mFlagsFragmentOffset` 566 static constexpr uint16_t kFlagsDf = 0x4000; // Use with `mFlagsFragmentOffset` 567 static constexpr uint16_t kFlagsMf = 0x2000; // Use with `mFlagsFragmentOffset` 568 static constexpr uint16_t kFragmentOffsetMask = 0x1fff; // Use with `mFlagsFragmentOffset` 569 static constexpr uint32_t kVersIhlInit = 0x45; // Version 4, Header length = 5x8 bytes. 570 571 uint8_t mVersIhl; 572 uint8_t mDscpEcn; 573 uint16_t mTotalLength; 574 uint16_t mIdentification; 575 uint16_t mFlagsFragmentOffset; 576 uint8_t mTtl; 577 uint8_t mProtocol; 578 uint16_t mHeaderChecksum; 579 Address mSource; 580 Address mDestination; 581 } OT_TOOL_PACKED_END; 582 583 /** 584 * Implements ICMP(v4). 585 * Note: ICMP(v4) messages will only be generated / handled by NAT64. So only header definition is required. 586 * 587 */ 588 class Icmp 589 { 590 public: 591 /** 592 * Represents an IPv4 ICMP header. 593 * 594 */ 595 OT_TOOL_PACKED_BEGIN 596 class Header : public Clearable<Header> 597 { 598 public: 599 static constexpr uint16_t kChecksumFieldOffset = 2; 600 // A few ICMP types, only the ICMP types work with NAT64 are listed here. 601 enum Type : uint8_t 602 { 603 kTypeEchoReply = 0, 604 kTypeDestinationUnreachable = 3, 605 kTypeEchoRequest = 8, 606 kTypeTimeExceeded = 11, 607 }; 608 609 enum Code : uint8_t 610 { 611 kCodeNone = 0, 612 // Destination Unreachable codes 613 kCodeNetworkUnreachable = 0, 614 kCodeHostUnreachable = 1, 615 kCodeProtocolUnreachable = 2, 616 kCodePortUnreachable = 3, 617 kCodeSourceRouteFailed = 5, 618 kCodeNetworkUnknown = 6, 619 kCodeHostUnknown = 7, 620 }; 621 622 /** 623 * Returns the type of the ICMP message. 624 * 625 * @returns The type field of the ICMP message. 626 * 627 */ GetType(void) const628 uint8_t GetType(void) const { return mType; } 629 630 /** 631 * Sets the type of the ICMP message. 632 * 633 * @param[in] aType The type of the ICMP message. 634 * 635 */ SetType(uint8_t aType)636 void SetType(uint8_t aType) { mType = aType; } 637 638 /** 639 * Returns the code of the ICMP message. 640 * 641 * @returns The code field of the ICMP message. 642 * 643 */ GetCode(void) const644 uint8_t GetCode(void) const { return mCode; } 645 646 /** 647 * Sets the code of the ICMP message. 648 * 649 * @param[in] aCode The code of the ICMP message. 650 * 651 */ SetCode(uint8_t aCode)652 void SetCode(uint8_t aCode) { mCode = aCode; } 653 654 /** 655 * Sets the checksum field in the ICMP message. 656 * 657 * @returns The checksum of the ICMP message. 658 * 659 */ GetChecksum(void) const660 uint16_t GetChecksum(void) const { return BigEndian::HostSwap16(mChecksum); } 661 662 /** 663 * Sets the checksum field in the ICMP message. 664 * 665 * @param[in] aChecksum The checksum of the ICMP message. 666 * 667 */ SetChecksum(uint16_t aChecksum)668 void SetChecksum(uint16_t aChecksum) { mChecksum = BigEndian::HostSwap16(aChecksum); } 669 670 /** 671 * Returns the rest of header field in the ICMP message. 672 * 673 * @returns The rest of header field in the ICMP message. The returned buffer has 4 octets. 674 * 675 */ GetRestOfHeader(void) const676 const uint8_t *GetRestOfHeader(void) const { return mRestOfHeader; } 677 678 /** 679 * Sets the rest of header field in the ICMP message. 680 * 681 * @param[in] aRestOfHeader The rest of header field in the ICMP message. The buffer should have 4 octets. 682 * 683 */ SetRestOfHeader(const uint8_t * aRestOfHeader)684 void SetRestOfHeader(const uint8_t *aRestOfHeader) 685 { 686 memcpy(mRestOfHeader, aRestOfHeader, sizeof(mRestOfHeader)); 687 } 688 689 private: 690 uint8_t mType; 691 uint8_t mCode; 692 uint16_t mChecksum; 693 uint8_t mRestOfHeader[4]; 694 } OT_TOOL_PACKED_END; 695 }; 696 697 // Internet Protocol Numbers 698 static constexpr uint8_t kProtoTcp = Ip6::kProtoTcp; ///< Transmission Control Protocol 699 static constexpr uint8_t kProtoUdp = Ip6::kProtoUdp; ///< User Datagram 700 static constexpr uint8_t kProtoIcmp = 1; ///< ICMP for IPv4 701 702 using Tcp = Ip6::Tcp; // TCP in IPv4 is the same as TCP in IPv6 703 using Udp = Ip6::Udp; // UDP in IPv4 is the same as UDP in IPv6 704 705 /** 706 * @} 707 * 708 */ 709 710 } // namespace Ip4 711 712 DefineCoreType(otIp4Address, Ip4::Address); 713 DefineCoreType(otIp4Cidr, Ip4::Cidr); 714 715 } // namespace ot 716 717 #endif // IP4_TYPES_HPP_ 718