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