• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
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);
163 
164     /**
165      * This method converts the IPv4 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      * @returns An `InfoString` representing the IPv4 address.
170      *
171      */
172     InfoString ToString(void) const;
173 } OT_TOOL_PACKED_END;
174 
175 /**
176  * This class represents an IPv4 CIDR block.
177  *
178  */
179 class Cidr : public otIp4Cidr, public Unequatable<Cidr>, public Clearable<Address>
180 {
181     friend class Address;
182 
183 public:
184     static constexpr uint16_t kCidrSuffixSize = 3; ///< Suffix to represent CIDR (/dd).
185 
186     /**
187      * This type defines the fixed-length `String` object returned from `ToString()`.
188      *
189      */
190     typedef String<Address::kAddressStringSize + kCidrSuffixSize> InfoString;
191 
192     /**
193      * This method converts the IPv4 CIDR to a string.
194      *
195      * The string format uses quad-dotted notation of four bytes in the address with the length of prefix (e.g.,
196      * "127.0.0.1/32").
197      *
198      * @returns An `InfoString` representing the IPv4 cidr.
199      *
200      */
201     InfoString ToString(void) const;
202 
203     /**
204      * This method gets the prefix as a pointer to a byte array.
205      *
206      * @returns A pointer to a byte array containing the Prefix.
207      *
208      */
GetBytes(void) const209     const uint8_t *GetBytes(void) const { return mAddress.mFields.m8; }
210 
211     /**
212      * This method overloads operator `==` to evaluate whether or not two prefixes are equal.
213      *
214      * @param[in]  aOther  The other prefix to compare with.
215      *
216      * @retval TRUE   If the two prefixes are equal.
217      * @retval FALSE  If the two prefixes are not equal.
218      *
219      */
220     bool operator==(const Cidr &aOther) const;
221 
222     /**
223      * This method sets the CIDR.
224      *
225      * @param[in] aAddress  A pointer to buffer containing the CIDR bytes. The length of aAddress should be 4 bytes.
226      * @param[in] aLength   The length of CIDR in bits.
227      *
228      */
229     void Set(const uint8_t *aAddress, uint8_t aLength);
230 
231 private:
HostMask(void) const232     uint32_t HostMask(void) const
233     {
234         // Note: Using LL suffix to make it a uint64 since /32 is a valid CIDR, and right shifting 32 bits is undefined
235         // for uint32.
236         return HostSwap32(0xffffffffLL >> mLength);
237     }
238 
SubnetMask(void) const239     uint32_t SubnetMask(void) const { return ~HostMask(); }
240 };
241 
242 /**
243  * This class implements IPv4 header generation and parsing.
244  *
245  */
246 OT_TOOL_PACKED_BEGIN
247 class Header : public Clearable<Header>
248 {
249 public:
250     static constexpr uint8_t kVersionIhlOffset         = 0;
251     static constexpr uint8_t kTrafficClassOffset       = 1;
252     static constexpr uint8_t kTotalLengthOffset        = 2;
253     static constexpr uint8_t kIdenficationOffset       = 4;
254     static constexpr uint8_t kFlagsFragmentOffset      = 6;
255     static constexpr uint8_t kTtlOffset                = 8;
256     static constexpr uint8_t kProtocolOffset           = 9;
257     static constexpr uint8_t kHeaderChecksumOffset     = 10;
258     static constexpr uint8_t kSourceAddressOffset      = 12;
259     static constexpr uint8_t kDestinationAddressOffset = 16;
260 
261     /**
262      * This method indicates whether or not the header appears to be well-formed.
263      *
264      * @retval TRUE    If the header appears to be well-formed.
265      * @retval FALSE   If the header does not appear to be well-formed.
266      *
267      */
IsValid(void) const268     bool IsValid(void) const { return IsVersion4(); }
269 
270     /**
271      * This method initializes the Version to 4 and sets Traffic Class and Flow fields to zero.
272      *
273      * The other fields in the IPv4 header remain unchanged.
274      *
275      */
InitVersionIhl(void)276     void InitVersionIhl(void) { SetVersionIhl(kVersIhlInit); }
277 
278     /**
279      * This method sets the version and Ihl of the IPv4 header.
280      *
281      * @param[in] aVersionIhl The octet for the version and Ihl field.
282      *
283      */
SetVersionIhl(uint8_t aVersionIhl)284     void SetVersionIhl(uint8_t aVersionIhl) { mVersIhl = aVersionIhl; }
285 
286     /**
287      * This method indicates whether or not the IPv4 Version is set to 6.
288      *
289      * @retval TRUE   If the IPv4 Version is set to 4.
290      * @retval FALSE  If the IPv4 Version is not set to 4.
291      *
292      */
IsVersion4(void) const293     bool IsVersion4(void) const { return (mVersIhl & kVersionMask) == kVersion4; }
294 
295     /**
296      * This method returns the octet for DSCP + ECN.
297      *
298      * @retval The octet for DSCP and ECN.
299      *
300      */
GetDscpEcn(void) const301     uint8_t GetDscpEcn(void) const { return mDscpEcn; }
302 
303     /**
304      * This method gets the 6-bit Differentiated Services Code Point (DSCP) from Traffic Class field.
305      *
306      * @returns The DSCP value.
307      *
308      */
GetDscp(void) const309     uint8_t GetDscp(void) const { return (mDscpEcn & kDscpMask) >> kDscpOffset; }
310 
311     /**
312      * This method sets 6-bit Differentiated Services Code Point (DSCP) in IPv4 header.
313      *
314      * @param[in]  aDscp  The DSCP value.
315      *
316      */
SetDscp(uint8_t aDscp)317     void SetDscp(uint8_t aDscp) { mDscpEcn = static_cast<uint8_t>((mDscpEcn & ~kDscpMask) | (aDscp << kDscpOffset)); }
318 
319     /**
320      * This method gets the 2-bit Explicit Congestion Notification (ECN) from Traffic Class field.
321      *
322      * @returns The ECN value.
323      *
324      */
GetEcn(void) const325     Ecn GetEcn(void) const { return static_cast<Ecn>(mDscpEcn & kEcnMask); }
326 
327     /**
328      * This method sets the 2-bit Explicit Congestion Notification (ECN) in IPv4 header..
329      *
330      * @param[in]  aEcn  The ECN value.
331      *
332      */
SetEcn(Ecn aEcn)333     void SetEcn(Ecn aEcn) { mDscpEcn = ((mDscpEcn & ~kEcnMask) | aEcn); }
334 
335     /**
336      * This method returns the IPv4 Payload Length value.
337      *
338      * @returns The IPv4 Payload Length value.
339      *
340      */
GetTotalLength(void) const341     uint16_t GetTotalLength(void) const { return HostSwap16(mTotalLength); }
342 
343     /**
344      * This method sets the IPv4 Payload Length value.
345      *
346      * @param[in]  aLength  The IPv4 Payload Length value.
347      *
348      */
SetTotalLength(uint16_t aLength)349     void SetTotalLength(uint16_t aLength) { mTotalLength = HostSwap16(aLength); }
350 
351     /**
352      * This method returns the IPv4 payload protocol.
353      *
354      * @returns The IPv4 payload protocol value.
355      *
356      */
GetProtocol(void) const357     uint8_t GetProtocol(void) const { return mProtocol; }
358 
359     /**
360      * This method sets the IPv4 payload protocol.
361      *
362      * @param[in]  aProtocol  The IPv4 payload protocol.
363      *
364      */
SetProtocol(uint8_t aProtocol)365     void SetProtocol(uint8_t aProtocol) { mProtocol = aProtocol; }
366 
367     /**
368      * This method returns the IPv4 header checksum, the checksum is in host endian.
369      *
370      * @returns The checksum field in the IPv4 header.
371      *
372      */
GetChecksum(void) const373     uint16_t GetChecksum(void) const { return HostSwap16(mHeaderChecksum); }
374 
375     /**
376      * This method sets the IPv4 header checksum, the checksum is in host endian.
377      *
378      * @param[in] aChecksum The checksum for the IPv4 header.
379      *
380      */
SetChecksum(uint16_t aChecksum)381     void SetChecksum(uint16_t aChecksum) { mHeaderChecksum = HostSwap16(aChecksum); }
382 
383     /**
384      * This method returns the IPv4 Identification value.
385      *
386      * @returns The IPv4 Identification value.
387      *
388      */
GetIdentification(void) const389     uint16_t GetIdentification(void) const { return HostSwap16(mIdentification); }
390 
391     /**
392      * This method sets the IPv4 Identification value.
393      *
394      * @param[in] aIdentification The IPv4 Identification value.
395      *
396      */
SetIdentification(uint16_t aIdentification)397     void SetIdentification(uint16_t aIdentification) { mIdentification = HostSwap16(aIdentification); }
398 
399     /**
400      * This method returns the IPv4 Time-to-Live value.
401      *
402      * @returns The IPv4 Time-to-Live value.
403      *
404      */
GetTtl(void) const405     uint8_t GetTtl(void) const { return mTtl; }
406 
407     /**
408      * This method sets the IPv4 Time-to-Live value.
409      *
410      * @param[in]  aTtl  The IPv4 Time-to-Live value.
411      *
412      */
SetTtl(uint8_t aTtl)413     void SetTtl(uint8_t aTtl) { mTtl = aTtl; }
414 
415     /**
416      * This method returns the IPv4 Source address.
417      *
418      * @returns A reference to the IPv4 Source address.
419      *
420      */
GetSource(void)421     Address &GetSource(void) { return mSource; }
422 
423     /**
424      * This method returns the IPv4 Source address.
425      *
426      * @returns A reference to the IPv4 Source address.
427      *
428      */
GetSource(void) const429     const Address &GetSource(void) const { return mSource; }
430 
431     /**
432      * This method sets the IPv4 Source address.
433      *
434      * @param[in]  aSource  A reference to the IPv4 Source address.
435      *
436      */
SetSource(const Address & aSource)437     void SetSource(const Address &aSource) { mSource = aSource; }
438 
439     /**
440      * This method returns the IPv4 Destination address.
441      *
442      * @returns A reference to the IPv4 Destination address.
443      *
444      */
GetDestination(void)445     Address &GetDestination(void) { return mDestination; }
446 
447     /**
448      * This method returns the IPv4 Destination address.
449      *
450      * @returns A reference to the IPv4 Destination address.
451      *
452      */
GetDestination(void) const453     const Address &GetDestination(void) const { return mDestination; }
454 
455     /**
456      * This method sets the IPv4 Destination address.
457      *
458      * @param[in]  aDestination  A reference to the IPv4 Destination address.
459      *
460      */
SetDestination(const Address & aDestination)461     void SetDestination(const Address &aDestination) { mDestination = aDestination; }
462 
463     /**
464      * This method parses and validates the IPv4 header from a given message.
465      *
466      * The header is read from @p aMessage at offset zero.
467      *
468      * @param[in]  aMessage  The IPv4 message.
469      *
470      * @retval kErrorNone   Successfully parsed the IPv4 header from @p aMessage.
471      * @retval kErrorParse  Malformed IPv4 header or message (e.g., message does not contained expected payload length).
472      *
473      */
474     Error ParseFrom(const Message &aMessage);
475 
476     /**
477      * This method returns the Df flag in the IPv4 header.
478      *
479      * @returns Whether don't fragment flag is set.
480      *
481      */
GetDf(void) const482     bool GetDf(void) const { return HostSwap16(mFlagsFargmentOffset) & kFlagsDf; }
483 
484     /**
485      * This method returns the Mf flag in the IPv4 header.
486      *
487      * @returns Whether more fragments flag is set.
488      *
489      */
GetMf(void) const490     bool GetMf(void) const { return HostSwap16(mFlagsFargmentOffset) & kFlagsMf; }
491 
492     /**
493      * This method returns the fragment offset in the IPv4 header.
494      *
495      * @returns The fragment offset of the IPv4 packet.
496      *
497      */
GetFragmentOffset(void) const498     uint16_t GetFragmentOffset(void) const { return HostSwap16(mFlagsFargmentOffset) & kFragmentOffsetMask; }
499 
500 private:
501     // IPv4 header
502     //
503     // +---------------+---------------+---------------+---------------+
504     // |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|
505     // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
506     // |Version|  IHL  |    DSCP   |ECN|         Total Length          |
507     // |        Identification         |Flags|    Fragment Offset      |
508     // |      TTL      |    Protocol   |        Header Checksum        |
509     // |                       Source IP Address                       |
510     // |                         Dest IP Address                       |
511     // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
512 
513     static constexpr uint8_t  kVersion4           = 0x40;   // Use with `mVersIhl`
514     static constexpr uint8_t  kVersionMask        = 0xf0;   // Use with `mVersIhl`
515     static constexpr uint8_t  kIhlMask            = 0x0f;   // Use with `mVersIhl`
516     static constexpr uint8_t  kDscpOffset         = 2;      // Use with `mDscpEcn`
517     static constexpr uint16_t kDscpMask           = 0xfc;   // Use with `mDscpEcn`
518     static constexpr uint8_t  kEcnOffset          = 0;      // Use with `mDscpEcn`
519     static constexpr uint8_t  kEcnMask            = 0x03;   // Use with `mDscpEcn`
520     static constexpr uint16_t kFlagsMask          = 0xe000; // Use with `mFlagsFragmentOffset`
521     static constexpr uint16_t kFlagsDf            = 0x4000; // Use with `mFlagsFragmentOffset`
522     static constexpr uint16_t kFlagsMf            = 0x2000; // Use with `mFlagsFragmentOffset`
523     static constexpr uint16_t kFragmentOffsetMask = 0x1fff; // Use with `mFlagsFragmentOffset`
524     static constexpr uint32_t kVersIhlInit        = 0x45;   // Version 4, Header length = 5x8 bytes.
525 
526     uint8_t  mVersIhl;
527     uint8_t  mDscpEcn;
528     uint16_t mTotalLength;
529     uint16_t mIdentification;
530     uint16_t mFlagsFargmentOffset;
531     uint8_t  mTtl;
532     uint8_t  mProtocol;
533     uint16_t mHeaderChecksum;
534     Address  mSource;
535     Address  mDestination;
536 } OT_TOOL_PACKED_END;
537 
538 /**
539  * This class implements ICMP(v4).
540  * Note: ICMP(v4) messages will only be generated / handled by NAT64. So only header defination is required.
541  *
542  */
543 class Icmp
544 {
545 public:
546     /**
547      * This class represents an IPv4 ICMP header.
548      *
549      */
550     OT_TOOL_PACKED_BEGIN
551     class Header : public Clearable<Header>
552     {
553     public:
554         static constexpr uint16_t kChecksumFieldOffset = 2;
555         // A few ICMP types, only the ICMP types work with NAT64 are listed here.
556         enum Type : uint8_t
557         {
558             kTypeEchoReply              = 0,
559             kTypeDestinationUnreachable = 3,
560             kTypeEchoRequest            = 8,
561             kTypeTimeExceeded           = 11,
562         };
563 
564         enum Code : uint8_t
565         {
566             kCodeNone = 0,
567             // Destination Unreachable codes
568             kCodeNetworkUnreachable  = 0,
569             kCodeHostUnreachable     = 1,
570             kCodeProtocolUnreachable = 2,
571             kCodePortUnreachable     = 3,
572             kCodeSourceRouteFailed   = 5,
573             kCodeNetworkUnknown      = 6,
574             kCodeHostUnknown         = 7,
575         };
576 
577         /**
578          * This method returns the type of the ICMP message.
579          *
580          * @returns The type field of the ICMP message.
581          *
582          */
GetType(void) const583         uint8_t GetType(void) const { return mType; }
584 
585         /**
586          * This method sets the type of the ICMP message.
587          *
588          * @param[in] aType The type of the ICMP message.
589          *
590          */
SetType(uint8_t aType)591         void SetType(uint8_t aType) { mType = aType; }
592 
593         /**
594          * This method returns the code of the ICMP message.
595          *
596          * @returns The code field of the ICMP message.
597          *
598          */
GetCode(void) const599         uint8_t GetCode(void) const { return mCode; }
600 
601         /**
602          * This method sets the code of the ICMP message.
603          *
604          * @param[in] aCode The code of the ICMP message.
605          *
606          */
SetCode(uint8_t aCode)607         void SetCode(uint8_t aCode) { mCode = aCode; }
608 
609         /**
610          * This method sets the checksum field in the ICMP message.
611          *
612          * @returns The checksum of the ICMP message.
613          *
614          */
GetChecksum(void) const615         uint16_t GetChecksum(void) const { return HostSwap16(mChecksum); }
616 
617         /**
618          * This method sets the checksum field in the ICMP message.
619          *
620          * @param[in] aChecksum The checksum of the ICMP message.
621          *
622          */
SetChecksum(uint16_t aChecksum)623         void SetChecksum(uint16_t aChecksum) { mChecksum = HostSwap16(aChecksum); }
624 
625         /**
626          * This method returns the rest of header field in the ICMP message.
627          *
628          * @returns The rest of header field in the ICMP message. The returned buffer has 4 octets.
629          *
630          */
GetRestOfHeader(void) const631         const uint8_t *GetRestOfHeader(void) const { return mRestOfHeader; }
632 
633         /**
634          * This method sets the rest of header field in the ICMP message.
635          *
636          * @param[in] aRestOfHeader The rest of header field in the ICMP message. The buffer should have 4 octets.
637          *
638          */
SetRestOfHeader(const uint8_t * aRestOfheader)639         void SetRestOfHeader(const uint8_t *aRestOfheader)
640         {
641             memcpy(mRestOfHeader, aRestOfheader, sizeof(mRestOfHeader));
642         }
643 
644     private:
645         uint8_t  mType;
646         uint8_t  mCode;
647         uint16_t mChecksum;
648         uint8_t  mRestOfHeader[4];
649     } OT_TOOL_PACKED_END;
650 };
651 
652 // Internet Protocol Numbers
653 static constexpr uint8_t kProtoTcp  = Ip6::kProtoTcp; ///< Transmission Control Protocol
654 static constexpr uint8_t kProtoUdp  = Ip6::kProtoUdp; ///< User Datagram
655 static constexpr uint8_t kProtoIcmp = 1;              ///< ICMP for IPv4
656 
657 using Tcp = Ip6::Tcp; // TCP in IPv4 is the same as TCP in IPv6
658 using Udp = Ip6::Udp; // UDP in IPv4 is the same as UDP in IPv6
659 
660 /**
661  * @}
662  *
663  */
664 
665 } // namespace Ip4
666 
667 DefineCoreType(otIp4Address, Ip4::Address);
668 DefineCoreType(otIp4Cidr, Ip4::Cidr);
669 
670 } // namespace ot
671 
672 #endif // IP4_TYPES_HPP_
673