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 from a given IPv4-mapped IPv6 address. 127 * 128 * @param[in] aIp6Address An IPv6 address. 129 * 130 * @retval kErrorNone Set the IPv4 address successfully. 131 * @retval kErrorPase The @p aIp6Address does not follow the IPv4-mapped IPv6 address format. 132 * 133 */ 134 Error ExtractFromIp4MappedIp6Address(const Ip6::Address &aIp6Address); 135 136 /** 137 * Sets the IPv4 address by performing NAT64 address translation from a given IPv6 address as specified 138 * in RFC 6052. 139 * 140 * The NAT64 @p aPrefixLength MUST be one of the following values: 32, 40, 48, 56, 64, or 96, otherwise the behavior 141 * of this method is undefined. 142 * 143 * @param[in] aPrefixLength The prefix length to use for IPv4/IPv6 translation. 144 * @param[in] aIp6Address The IPv6 address to translate to IPv4. 145 * 146 */ 147 void ExtractFromIp6Address(uint8_t aPrefixLength, const Ip6::Address &aIp6Address); 148 149 /** 150 * Sets the IPv4 address from the given CIDR and the host field. 151 * 152 * @param[in] aCidr The CIDR for the IPv4 address. 153 * @param[in] aHost The host bits of the IPv4 address in host byte order. The aHost will be masked by host mask. 154 * 155 */ 156 void SynthesizeFromCidrAndHost(const Cidr &aCidr, uint32_t aHost); 157 158 /** 159 * Parses an IPv4 address string terminated by `aTerminatorChar`. 160 * 161 * The string MUST follow the quad-dotted notation of four decimal values (ranging from 0 to 255 each). For 162 * example, "127.0.0.1" 163 * 164 * @param[in] aString A pointer to the null-terminated string. 165 * 166 * @retval kErrorNone Successfully parsed the IPv4 address string. 167 * @retval kErrorParse Failed to parse the IPv4 address string. 168 * 169 */ 170 Error FromString(const char *aString, char aTerminatorChar = kNullChar); 171 172 /** 173 * Converts the address to a string. 174 * 175 * The string format uses quad-dotted notation of four bytes in the address (e.g., "127.0.0.1"). 176 * 177 * If the resulting string does not fit in @p aBuffer (within its @p aSize characters), the string will be 178 * truncated but the outputted string is always null-terminated. 179 * 180 * @param[out] aBuffer A pointer to a char array to output the string (MUST NOT be `nullptr`). 181 * @param[in] aSize The size of @p aBuffer (in bytes). 182 * 183 */ 184 void ToString(char *aBuffer, uint16_t aSize) const; 185 186 /** 187 * Converts the IPv4 address to a string. 188 * 189 * The string format uses quad-dotted notation of four bytes in the address (e.g., "127.0.0.1"). 190 * 191 * @returns An `InfoString` representing the IPv4 address. 192 * 193 */ 194 InfoString ToString(void) const; 195 196 private: 197 void ToString(StringWriter &aWriter) const; 198 } OT_TOOL_PACKED_END; 199 200 /** 201 * Represents an IPv4 CIDR block. 202 * 203 */ 204 class Cidr : public otIp4Cidr, public Unequatable<Cidr>, public Clearable<Address> 205 { 206 friend class Address; 207 208 public: 209 static constexpr uint16_t kCidrSuffixSize = 3; ///< Suffix to represent CIDR (/dd). 210 211 /** 212 * Defines the fixed-length `String` object returned from `ToString()`. 213 * 214 */ 215 typedef String<Address::kAddressStringSize + kCidrSuffixSize> InfoString; 216 217 /** 218 * Converts the IPv4 CIDR string to binary. 219 * 220 * The string format uses quad-dotted notation of four bytes in the address with the length of prefix (e.g., 221 * "127.0.0.1/32"). 222 * 223 * @param[in] aString A pointer to the null-terminated string. 224 * 225 * @retval kErrorNone Successfully parsed the IPv4 CIDR string. 226 * @retval kErrorParse Failed to parse the IPv4 CIDR string. 227 * 228 */ 229 Error FromString(const char *aString); 230 231 /** 232 * Converts the IPv4 CIDR to a string. 233 * 234 * The string format uses quad-dotted notation of four bytes in the address with the length of prefix (e.g., 235 * "127.0.0.1/32"). 236 * 237 * If the resulting string does not fit in @p aBuffer (within its @p aSize characters), the string will be 238 * truncated but the outputted string is always null-terminated. 239 * 240 * @param[out] aBuffer A pointer to a char array to output the string (MUST NOT be `nullptr`). 241 * @param[in] aSize The size of @p aBuffer (in bytes). 242 * 243 */ 244 void ToString(char *aBuffer, uint16_t aSize) const; 245 246 /** 247 * Converts the IPv4 CIDR to a string. 248 * 249 * The string format uses quad-dotted notation of four bytes in the address with the length of prefix (e.g., 250 * "127.0.0.1/32"). 251 * 252 * @returns An `InfoString` representing the IPv4 cidr. 253 * 254 */ 255 InfoString ToString(void) const; 256 257 /** 258 * Gets the prefix as a pointer to a byte array. 259 * 260 * @returns A pointer to a byte array containing the Prefix. 261 * 262 */ GetBytes(void) const263 const uint8_t *GetBytes(void) const { return mAddress.mFields.m8; } 264 265 /** 266 * Overloads operator `==` to evaluate whether or not two prefixes are equal. 267 * 268 * @param[in] aOther The other prefix to compare with. 269 * 270 * @retval TRUE If the two prefixes are equal. 271 * @retval FALSE If the two prefixes are not equal. 272 * 273 */ 274 bool operator==(const Cidr &aOther) const; 275 276 /** 277 * Sets the CIDR. 278 * 279 * @param[in] aAddress A pointer to buffer containing the CIDR bytes. The length of aAddress should be 4 bytes. 280 * @param[in] aLength The length of CIDR in bits. 281 * 282 */ 283 void Set(const uint8_t *aAddress, uint8_t aLength); 284 285 private: HostMask(void) const286 uint32_t HostMask(void) const 287 { 288 // Note: Using LL suffix to make it a uint64 since /32 is a valid CIDR, and right shifting 32 bits is undefined 289 // for uint32. 290 return BigEndian::HostSwap32(0xffffffffLL >> mLength); 291 } 292 SubnetMask(void) const293 uint32_t SubnetMask(void) const { return ~HostMask(); } 294 295 void ToString(StringWriter &aWriter) const; 296 }; 297 298 /** 299 * Implements IPv4 header generation and parsing. 300 * 301 */ 302 OT_TOOL_PACKED_BEGIN 303 class Header : public Clearable<Header> 304 { 305 public: 306 static constexpr uint8_t kVersionIhlOffset = 0; 307 static constexpr uint8_t kTrafficClassOffset = 1; 308 static constexpr uint8_t kTotalLengthOffset = 2; 309 static constexpr uint8_t kIdentificationOffset = 4; 310 static constexpr uint8_t kFlagsFragmentOffset = 6; 311 static constexpr uint8_t kTtlOffset = 8; 312 static constexpr uint8_t kProtocolOffset = 9; 313 static constexpr uint8_t kHeaderChecksumOffset = 10; 314 static constexpr uint8_t kSourceAddressOffset = 12; 315 static constexpr uint8_t kDestinationAddressOffset = 16; 316 317 /** 318 * Indicates whether or not the header appears to be well-formed. 319 * 320 * @retval TRUE If the header appears to be well-formed. 321 * @retval FALSE If the header does not appear to be well-formed. 322 * 323 */ IsValid(void) const324 bool IsValid(void) const { return IsVersion4(); } 325 326 /** 327 * Initializes the Version to 4 and sets Traffic Class and Flow fields to zero. 328 * 329 * The other fields in the IPv4 header remain unchanged. 330 * 331 */ InitVersionIhl(void)332 void InitVersionIhl(void) { SetVersionIhl(kVersIhlInit); } 333 334 /** 335 * Sets the version and Ihl of the IPv4 header. 336 * 337 * @param[in] aVersionIhl The octet for the version and Ihl field. 338 * 339 */ SetVersionIhl(uint8_t aVersionIhl)340 void SetVersionIhl(uint8_t aVersionIhl) { mVersIhl = aVersionIhl; } 341 342 /** 343 * Indicates whether or not the IPv4 Version is set to 6. 344 * 345 * @retval TRUE If the IPv4 Version is set to 4. 346 * @retval FALSE If the IPv4 Version is not set to 4. 347 * 348 */ IsVersion4(void) const349 bool IsVersion4(void) const { return (mVersIhl & kVersionMask) == kVersion4; } 350 351 /** 352 * Returns the octet for DSCP + ECN. 353 * 354 * @retval The octet for DSCP and ECN. 355 * 356 */ GetDscpEcn(void) const357 uint8_t GetDscpEcn(void) const { return mDscpEcn; } 358 359 /** 360 * Gets the 6-bit Differentiated Services Code Point (DSCP) from Traffic Class field. 361 * 362 * @returns The DSCP value. 363 * 364 */ GetDscp(void) const365 uint8_t GetDscp(void) const { return (mDscpEcn & kDscpMask) >> kDscpOffset; } 366 367 /** 368 * Sets 6-bit Differentiated Services Code Point (DSCP) in IPv4 header. 369 * 370 * @param[in] aDscp The DSCP value. 371 * 372 */ SetDscp(uint8_t aDscp)373 void SetDscp(uint8_t aDscp) { mDscpEcn = static_cast<uint8_t>((mDscpEcn & ~kDscpMask) | (aDscp << kDscpOffset)); } 374 375 /** 376 * Gets the 2-bit Explicit Congestion Notification (ECN) from Traffic Class field. 377 * 378 * @returns The ECN value. 379 * 380 */ GetEcn(void) const381 Ecn GetEcn(void) const { return static_cast<Ecn>(mDscpEcn & kEcnMask); } 382 383 /** 384 * Sets the 2-bit Explicit Congestion Notification (ECN) in IPv4 header.. 385 * 386 * @param[in] aEcn The ECN value. 387 * 388 */ SetEcn(Ecn aEcn)389 void SetEcn(Ecn aEcn) { mDscpEcn = ((mDscpEcn & ~kEcnMask) | aEcn); } 390 391 /** 392 * Returns the IPv4 Payload Length value. 393 * 394 * @returns The IPv4 Payload Length value. 395 * 396 */ GetTotalLength(void) const397 uint16_t GetTotalLength(void) const { return BigEndian::HostSwap16(mTotalLength); } 398 399 /** 400 * Sets the IPv4 Payload Length value. 401 * 402 * @param[in] aLength The IPv4 Payload Length value. 403 * 404 */ SetTotalLength(uint16_t aLength)405 void SetTotalLength(uint16_t aLength) { mTotalLength = BigEndian::HostSwap16(aLength); } 406 407 /** 408 * Returns the IPv4 payload protocol. 409 * 410 * @returns The IPv4 payload protocol value. 411 * 412 */ GetProtocol(void) const413 uint8_t GetProtocol(void) const { return mProtocol; } 414 415 /** 416 * Sets the IPv4 payload protocol. 417 * 418 * @param[in] aProtocol The IPv4 payload protocol. 419 * 420 */ SetProtocol(uint8_t aProtocol)421 void SetProtocol(uint8_t aProtocol) { mProtocol = aProtocol; } 422 423 /** 424 * Returns the IPv4 header checksum, the checksum is in host endian. 425 * 426 * @returns The checksum field in the IPv4 header. 427 * 428 */ GetChecksum(void) const429 uint16_t GetChecksum(void) const { return BigEndian::HostSwap16(mHeaderChecksum); } 430 431 /** 432 * Sets the IPv4 header checksum, the checksum is in host endian. 433 * 434 * @param[in] aChecksum The checksum for the IPv4 header. 435 * 436 */ SetChecksum(uint16_t aChecksum)437 void SetChecksum(uint16_t aChecksum) { mHeaderChecksum = BigEndian::HostSwap16(aChecksum); } 438 439 /** 440 * Returns the IPv4 Identification value. 441 * 442 * @returns The IPv4 Identification value. 443 * 444 */ GetIdentification(void) const445 uint16_t GetIdentification(void) const { return BigEndian::HostSwap16(mIdentification); } 446 447 /** 448 * Sets the IPv4 Identification value. 449 * 450 * @param[in] aIdentification The IPv4 Identification value. 451 * 452 */ SetIdentification(uint16_t aIdentification)453 void SetIdentification(uint16_t aIdentification) { mIdentification = BigEndian::HostSwap16(aIdentification); } 454 455 /** 456 * Returns the IPv4 Time-to-Live value. 457 * 458 * @returns The IPv4 Time-to-Live value. 459 * 460 */ GetTtl(void) const461 uint8_t GetTtl(void) const { return mTtl; } 462 463 /** 464 * Sets the IPv4 Time-to-Live value. 465 * 466 * @param[in] aTtl The IPv4 Time-to-Live value. 467 * 468 */ SetTtl(uint8_t aTtl)469 void SetTtl(uint8_t aTtl) { mTtl = aTtl; } 470 471 /** 472 * Returns the IPv4 Source address. 473 * 474 * @returns A reference to the IPv4 Source address. 475 * 476 */ GetSource(void)477 Address &GetSource(void) { return mSource; } 478 479 /** 480 * Returns the IPv4 Source address. 481 * 482 * @returns A reference to the IPv4 Source address. 483 * 484 */ GetSource(void) const485 const Address &GetSource(void) const { return mSource; } 486 487 /** 488 * Sets the IPv4 Source address. 489 * 490 * @param[in] aSource A reference to the IPv4 Source address. 491 * 492 */ SetSource(const Address & aSource)493 void SetSource(const Address &aSource) { mSource = aSource; } 494 495 /** 496 * Returns the IPv4 Destination address. 497 * 498 * @returns A reference to the IPv4 Destination address. 499 * 500 */ GetDestination(void)501 Address &GetDestination(void) { return mDestination; } 502 503 /** 504 * Returns the IPv4 Destination address. 505 * 506 * @returns A reference to the IPv4 Destination address. 507 * 508 */ GetDestination(void) const509 const Address &GetDestination(void) const { return mDestination; } 510 511 /** 512 * Sets the IPv4 Destination address. 513 * 514 * @param[in] aDestination A reference to the IPv4 Destination address. 515 * 516 */ SetDestination(const Address & aDestination)517 void SetDestination(const Address &aDestination) { mDestination = aDestination; } 518 519 /** 520 * Parses and validates the IPv4 header from a given message. 521 * 522 * The header is read from @p aMessage at offset zero. 523 * 524 * @param[in] aMessage The IPv4 message. 525 * 526 * @retval kErrorNone Successfully parsed the IPv4 header from @p aMessage. 527 * @retval kErrorParse Malformed IPv4 header or message (e.g., message does not contained expected payload length). 528 * 529 */ 530 Error ParseFrom(const Message &aMessage); 531 532 /** 533 * Returns the Df flag in the IPv4 header. 534 * 535 * @returns Whether don't fragment flag is set. 536 * 537 */ GetDf(void) const538 bool GetDf(void) const { return BigEndian::HostSwap16(mFlagsFragmentOffset) & kFlagsDf; } 539 540 /** 541 * Returns the Mf flag in the IPv4 header. 542 * 543 * @returns Whether more fragments flag is set. 544 * 545 */ GetMf(void) const546 bool GetMf(void) const { return BigEndian::HostSwap16(mFlagsFragmentOffset) & kFlagsMf; } 547 548 /** 549 * Returns the fragment offset in the IPv4 header. 550 * 551 * @returns The fragment offset of the IPv4 packet. 552 * 553 */ GetFragmentOffset(void) const554 uint16_t GetFragmentOffset(void) const { return BigEndian::HostSwap16(mFlagsFragmentOffset) & kFragmentOffsetMask; } 555 556 private: 557 // IPv4 header 558 // 559 // +---------------+---------------+---------------+---------------+ 560 // |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| 561 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 562 // |Version| IHL | DSCP |ECN| Total Length | 563 // | Identification |Flags| Fragment Offset | 564 // | TTL | Protocol | Header Checksum | 565 // | Source IP Address | 566 // | Dest IP Address | 567 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 568 569 static constexpr uint8_t kVersion4 = 0x40; // Use with `mVersIhl` 570 static constexpr uint8_t kVersionMask = 0xf0; // Use with `mVersIhl` 571 static constexpr uint8_t kIhlMask = 0x0f; // Use with `mVersIhl` 572 static constexpr uint8_t kDscpOffset = 2; // Use with `mDscpEcn` 573 static constexpr uint16_t kDscpMask = 0xfc; // Use with `mDscpEcn` 574 static constexpr uint8_t kEcnOffset = 0; // Use with `mDscpEcn` 575 static constexpr uint8_t kEcnMask = 0x03; // Use with `mDscpEcn` 576 static constexpr uint16_t kFlagsMask = 0xe000; // Use with `mFlagsFragmentOffset` 577 static constexpr uint16_t kFlagsDf = 0x4000; // Use with `mFlagsFragmentOffset` 578 static constexpr uint16_t kFlagsMf = 0x2000; // Use with `mFlagsFragmentOffset` 579 static constexpr uint16_t kFragmentOffsetMask = 0x1fff; // Use with `mFlagsFragmentOffset` 580 static constexpr uint32_t kVersIhlInit = 0x45; // Version 4, Header length = 5x8 bytes. 581 582 uint8_t mVersIhl; 583 uint8_t mDscpEcn; 584 uint16_t mTotalLength; 585 uint16_t mIdentification; 586 uint16_t mFlagsFragmentOffset; 587 uint8_t mTtl; 588 uint8_t mProtocol; 589 uint16_t mHeaderChecksum; 590 Address mSource; 591 Address mDestination; 592 } OT_TOOL_PACKED_END; 593 594 /** 595 * Implements ICMP(v4). 596 * Note: ICMP(v4) messages will only be generated / handled by NAT64. So only header definition is required. 597 * 598 */ 599 class Icmp 600 { 601 public: 602 /** 603 * Represents an IPv4 ICMP header. 604 * 605 */ 606 OT_TOOL_PACKED_BEGIN 607 class Header : public Clearable<Header> 608 { 609 public: 610 static constexpr uint16_t kChecksumFieldOffset = 2; 611 // A few ICMP types, only the ICMP types work with NAT64 are listed here. 612 enum Type : uint8_t 613 { 614 kTypeEchoReply = 0, 615 kTypeDestinationUnreachable = 3, 616 kTypeEchoRequest = 8, 617 kTypeTimeExceeded = 11, 618 }; 619 620 enum Code : uint8_t 621 { 622 kCodeNone = 0, 623 // Destination Unreachable codes 624 kCodeNetworkUnreachable = 0, 625 kCodeHostUnreachable = 1, 626 kCodeProtocolUnreachable = 2, 627 kCodePortUnreachable = 3, 628 kCodeSourceRouteFailed = 5, 629 kCodeNetworkUnknown = 6, 630 kCodeHostUnknown = 7, 631 }; 632 633 /** 634 * Returns the type of the ICMP message. 635 * 636 * @returns The type field of the ICMP message. 637 * 638 */ GetType(void) const639 uint8_t GetType(void) const { return mType; } 640 641 /** 642 * Sets the type of the ICMP message. 643 * 644 * @param[in] aType The type of the ICMP message. 645 * 646 */ SetType(uint8_t aType)647 void SetType(uint8_t aType) { mType = aType; } 648 649 /** 650 * Returns the code of the ICMP message. 651 * 652 * @returns The code field of the ICMP message. 653 * 654 */ GetCode(void) const655 uint8_t GetCode(void) const { return mCode; } 656 657 /** 658 * Sets the code of the ICMP message. 659 * 660 * @param[in] aCode The code of the ICMP message. 661 * 662 */ SetCode(uint8_t aCode)663 void SetCode(uint8_t aCode) { mCode = aCode; } 664 665 /** 666 * Sets the checksum field in the ICMP message. 667 * 668 * @returns The checksum of the ICMP message. 669 * 670 */ GetChecksum(void) const671 uint16_t GetChecksum(void) const { return BigEndian::HostSwap16(mChecksum); } 672 673 /** 674 * Sets the checksum field in the ICMP message. 675 * 676 * @param[in] aChecksum The checksum of the ICMP message. 677 * 678 */ SetChecksum(uint16_t aChecksum)679 void SetChecksum(uint16_t aChecksum) { mChecksum = BigEndian::HostSwap16(aChecksum); } 680 681 /** 682 * Returns the rest of header field in the ICMP message. 683 * 684 * @returns The rest of header field in the ICMP message. The returned buffer has 4 octets. 685 * 686 */ GetRestOfHeader(void) const687 const uint8_t *GetRestOfHeader(void) const { return mRestOfHeader; } 688 689 /** 690 * Sets the rest of header field in the ICMP message. 691 * 692 * @param[in] aRestOfHeader The rest of header field in the ICMP message. The buffer should have 4 octets. 693 * 694 */ SetRestOfHeader(const uint8_t * aRestOfHeader)695 void SetRestOfHeader(const uint8_t *aRestOfHeader) 696 { 697 memcpy(mRestOfHeader, aRestOfHeader, sizeof(mRestOfHeader)); 698 } 699 700 private: 701 uint8_t mType; 702 uint8_t mCode; 703 uint16_t mChecksum; 704 uint8_t mRestOfHeader[4]; 705 } OT_TOOL_PACKED_END; 706 }; 707 708 // Internet Protocol Numbers 709 static constexpr uint8_t kProtoTcp = Ip6::kProtoTcp; ///< Transmission Control Protocol 710 static constexpr uint8_t kProtoUdp = Ip6::kProtoUdp; ///< User Datagram 711 static constexpr uint8_t kProtoIcmp = 1; ///< ICMP for IPv4 712 713 using Tcp = Ip6::Tcp; // TCP in IPv4 is the same as TCP in IPv6 714 using Udp = Ip6::Udp; // UDP in IPv4 is the same as UDP in IPv6 715 716 /** 717 * @} 718 * 719 */ 720 721 } // namespace Ip4 722 723 DefineCoreType(otIp4Address, Ip4::Address); 724 DefineCoreType(otIp4Cidr, Ip4::Cidr); 725 726 } // namespace ot 727 728 #endif // IP4_TYPES_HPP_ 729