• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2016, 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 IPv6 packet processing.
32  */
33 
34 #ifndef IP6_HPP_
35 #define IP6_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <stddef.h>
40 
41 #include <openthread/ip6.h>
42 #include <openthread/nat64.h>
43 #include <openthread/udp.h>
44 
45 #include "common/callback.hpp"
46 #include "common/encoding.hpp"
47 #include "common/frame_data.hpp"
48 #include "common/locator.hpp"
49 #include "common/log.hpp"
50 #include "common/message.hpp"
51 #include "common/non_copyable.hpp"
52 #include "common/owned_ptr.hpp"
53 #include "common/time_ticker.hpp"
54 #include "common/timer.hpp"
55 #include "net/checksum.hpp"
56 #include "net/icmp6.hpp"
57 #include "net/ip6_address.hpp"
58 #include "net/ip6_headers.hpp"
59 #include "net/ip6_mpl.hpp"
60 #include "net/ip6_types.hpp"
61 #include "net/netif.hpp"
62 #include "net/socket.hpp"
63 #include "net/tcp6.hpp"
64 #include "net/udp6.hpp"
65 
66 namespace ot {
67 
68 /**
69  * @namespace ot::Ip6
70  *
71  * @brief
72  *   This namespace includes definitions for IPv6 networking.
73  */
74 namespace Ip6 {
75 
76 /**
77  * @addtogroup core-ipv6
78  *
79  * @brief
80  *   This module includes definitions for the IPv6 network layer.
81  *
82  * @{
83  *
84  * @defgroup core-ip6-icmp6 ICMPv6
85  * @defgroup core-ip6-ip6 IPv6
86  * @defgroup core-ip6-mpl MPL
87  * @defgroup core-ip6-netif Network Interfaces
88  *
89  * @}
90  */
91 
92 /**
93  * @addtogroup core-ip6-ip6
94  *
95  * @brief
96  *   This module includes definitions for core IPv6 networking.
97  *
98  * @{
99  */
100 
101 /**
102  * Implements the core IPv6 message processing.
103  */
104 class Ip6 : public InstanceLocator, private NonCopyable
105 {
106     friend class ot::Instance;
107     friend class ot::TimeTicker;
108     friend class Mpl;
109 
110 public:
111     typedef otIp6ReceiveCallback ReceiveCallback; ///< IPv6 receive callback function pointer.
112 
113     /**
114      * Initializes the object.
115      *
116      * @param[in]  aInstance   A reference to the otInstance object.
117      */
118     explicit Ip6(Instance &aInstance);
119 
120     /**
121      * Allocates a new message buffer from the buffer pool with default settings (link security
122      * enabled and `kPriorityMedium`).
123      *
124      * @returns A pointer to the message or `nullptr` if insufficient message buffers are available.
125      */
126     Message *NewMessage(void);
127 
128     /**
129      * Allocates a new message buffer from the buffer pool with default settings (link security
130      * enabled and `kPriorityMedium`).
131      *
132      * @param[in]  aReserved  The number of header bytes to reserve following the IPv6 header.
133      *
134      * @returns A pointer to the message or `nullptr` if insufficient message buffers are available.
135      */
136     Message *NewMessage(uint16_t aReserved);
137 
138     /**
139      * Allocates a new message buffer from the buffer pool.
140      *
141      * @param[in]  aReserved  The number of header bytes to reserve following the IPv6 header.
142      * @param[in]  aSettings  The message settings.
143      *
144      * @returns A pointer to the message or `nullptr` if insufficient message buffers are available.
145      */
146     Message *NewMessage(uint16_t aReserved, const Message::Settings &aSettings);
147 
148     /**
149      * Allocates a new message buffer from the buffer pool and writes the IPv6 datagram to the message.
150      *
151      * The message priority is always determined from IPv6 message itself (@p aData) and the priority included in
152      * @p aSetting is ignored.
153      *
154      * @param[in]  aData        A pointer to the IPv6 datagram buffer.
155      * @param[in]  aDataLength  The size of the IPV6 datagram buffer pointed by @p aData.
156      * @param[in]  aSettings    The message settings.
157      *
158      * @returns A pointer to the message or `nullptr` if malformed IPv6 header or insufficient message buffers are
159      *          available.
160      */
161     Message *NewMessageFromData(const uint8_t *aData, uint16_t aDataLength, const Message::Settings &aSettings);
162 
163     /**
164      * Converts the IPv6 DSCP value to message priority level.
165      *
166      * @param[in]  aDscp  The IPv6 DSCP value.
167      *
168      * @returns The message priority level.
169      */
170     static Message::Priority DscpToPriority(uint8_t aDscp);
171 
172     /**
173      * Sends an IPv6 datagram.
174      *
175      * @param[in]  aMessage      A reference to the message.
176      * @param[in]  aMessageInfo  A reference to the message info associated with @p aMessage.
177      * @param[in]  aIpProto      The Internet Protocol value.
178      *
179      * @retval kErrorNone     Successfully enqueued the message into an output interface.
180      * @retval kErrorNoBufs   Insufficient available buffer to add the IPv6 headers.
181      */
182     Error SendDatagram(Message &aMessage, MessageInfo &aMessageInfo, uint8_t aIpProto);
183 
184     /**
185      * Sends a raw IPv6 datagram with a fully formed IPv6 header.
186      *
187      * @param[in]  aMessage   An owned pointer to a message (ownership is transferred to the method).
188      *
189      * @retval kErrorNone     Successfully processed the message.
190      * @retval kErrorDrop     Message was well-formed but not fully processed due to packet processing rules.
191      * @retval kErrorNoBufs   Could not allocate necessary message buffers when processing the datagram.
192      * @retval kErrorNoRoute  No route to host.
193      * @retval kErrorParse    Encountered a malformed header when processing the message.
194      */
195     Error SendRaw(OwnedPtr<Message> aMessage);
196 
197     /**
198      * Processes a received IPv6 datagram.
199      *
200      * @param[in]  aMessage          An owned pointer to a message.
201      *
202      * @retval kErrorNone     Successfully processed the message.
203      * @retval kErrorDrop     Message was well-formed but not fully processed due to packet processing rules.
204      * @retval kErrorNoBufs   Could not allocate necessary message buffers when processing the datagram.
205      * @retval kErrorNoRoute  No route to host.
206      * @retval kErrorParse    Encountered a malformed header when processing the message.
207      */
208     Error HandleDatagram(OwnedPtr<Message> aMessagePtr, bool aIsReassembled = false);
209 
210     /**
211      * Sets the callback to provide received raw IPv6 datagrams.
212      *
213      * By default, this callback does not pass Thread control traffic. See `SetReceiveIp6FilterEnabled()` to change
214      * the Thread control traffic filter setting.
215      *
216      * @param[in]  aCallback    The receive callback function. Can be `nullptr` to disable the callback.
217      * @param[in]  aContext     A pointer to application-specific context.
218      */
SetReceiveCallback(ReceiveCallback aCallback,void * aContext)219     void SetReceiveCallback(ReceiveCallback aCallback, void *aContext) { mReceiveCallback.Set(aCallback, aContext); }
220 
221 #if OPENTHREAD_CONFIG_NAT64_TRANSLATOR_ENABLE
222     typedef otNat64ReceiveIp4Callback Ip4ReceiveCallback; ///< NAT64 IPv4 receive callback function pointer.
223 
224     /**
225      * Sets the callback to provide received translated IPv4 datagrams.
226      *
227      * @param[in]  aCallback  The NAT64 IPv4 callbac, used when translated IPv4 datagram is received.
228      * @param[in]  aContext   A pointer to application-specific context.
229      */
SetNat64ReceiveIp4Callback(Ip4ReceiveCallback aCallback,void * aContext)230     void SetNat64ReceiveIp4Callback(Ip4ReceiveCallback aCallback, void *aContext)
231     {
232         mIp4ReceiveCallback.Set(aCallback, aContext);
233     }
234 #endif
235 
236     /**
237      * Indicates whether or not Thread control traffic is filtered out when delivering IPv6 datagrams
238      * via the callback specified in `SetReceiveIp6Callback()`.
239      *
240      * @returns  TRUE if Thread control traffic is filtered out, FALSE otherwise.
241      */
IsReceiveIp6FilterEnabled(void) const242     bool IsReceiveIp6FilterEnabled(void) const { return mReceiveFilterEnabled; }
243 
244     /**
245      * Sets whether or not Thread control traffic is filtered out when delivering IPv6 datagrams
246      * via the callback specified in `SetReceiveIp6Callback()`.
247      *
248      * @param[in]  aEnabled  TRUE if Thread control traffic is filtered out, FALSE otherwise.
249      */
SetReceiveIp6FilterEnabled(bool aEnabled)250     void SetReceiveIp6FilterEnabled(bool aEnabled) { mReceiveFilterEnabled = aEnabled; }
251 
252     /**
253      * Performs default source address selection.
254      *
255      * @param[in,out]  aMessageInfo  A reference to the message information.
256      *
257      * @retval  kErrorNone      Found a source address and updated SockAddr of @p aMessageInfo.
258      * @retval  kErrorNotFound  No source address was found and @p aMessageInfo is unchanged.
259      */
260     Error SelectSourceAddress(MessageInfo &aMessageInfo) const;
261 
262     /**
263      * Performs default source address selection.
264      *
265      * @param[in]  aDestination  The destination address.
266      *
267      * @returns A pointer to the selected IPv6 source address or `nullptr` if no source address was found.
268      */
269     const Address *SelectSourceAddress(const Address &aDestination) const;
270 
271     /**
272      * Returns a reference to the send queue.
273      *
274      * @returns A reference to the send queue.
275      */
GetSendQueue(void) const276     const PriorityQueue &GetSendQueue(void) const { return mSendQueue; }
277 
278     /**
279      * Converts an IP protocol number to a string.
280      *
281      * @param[in] aIpProto  An IP protocol number.
282      *
283      * @returns The string representation of @p aIpProto.
284      */
285     static const char *IpProtoToString(uint8_t aIpProto);
286 
287     /**
288      * Converts an IP header ECN value to a string.
289      *
290      * @param[in] aEcn   The 2-bit ECN value.
291      *
292      * @returns The string representation of @p aEcn.
293      */
294     static const char *EcnToString(Ecn aEcn);
295 
296 #if OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
297 
298     typedef otBorderRoutingCounters BrCounters; ///< Border Routing counters.
299 
300     /**
301      * Returns a reference to the Border Routing counters.
302      *
303      * @returns A reference to the Border Routing counters.
304      */
GetBorderRoutingCounters(void) const305     const BrCounters &GetBorderRoutingCounters(void) const { return mBrCounters; }
306 
307     /**
308      * Returns a reference to the Border Routing counters.
309      *
310      * @returns A reference to the Border Routing counters.
311      */
GetBorderRoutingCounters(void)312     BrCounters &GetBorderRoutingCounters(void) { return mBrCounters; }
313 
314     /**
315      * Resets the Border Routing counters.
316      */
ResetBorderRoutingCounters(void)317     void ResetBorderRoutingCounters(void) { ClearAllBytes(mBrCounters); }
318 
319 #endif // OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
320 
321 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
322 
323     /**
324      * Enables or disables the filter that drops TMF UDP messages from untrusted origin.
325      *
326      * @param[in]  aEnabled  TRUE to enable filter, FALSE otherwise.
327      */
SetTmfOriginFilterEnabled(bool aEnabled)328     void SetTmfOriginFilterEnabled(bool aEnabled) { mTmfOriginFilterEnabled = aEnabled; }
329 
330     /**
331      * Indicates whether the filter that drops TMF UDP messages from untrusted origin is enabled or not.
332      *
333      * @returns TRUE if the filter is enabled, FALSE otherwise.
334      */
IsTmfOriginFilterEnabled(void)335     bool IsTmfOriginFilterEnabled(void) { return mTmfOriginFilterEnabled; }
336 
337 #endif
338 
339 private:
340     static constexpr uint8_t kDefaultHopLimit   = OPENTHREAD_CONFIG_IP6_HOP_LIMIT_DEFAULT;
341     static constexpr uint8_t kReassemblyTimeout = OPENTHREAD_CONFIG_IP6_REASSEMBLY_TIMEOUT;
342 
343     static constexpr uint16_t kMinimalMtu = 1280;
344 
345     static uint8_t PriorityToDscp(Message::Priority aPriority);
346     static Error   TakeOrCopyMessagePtr(OwnedPtr<Message> &aTargetPtr,
347                                         OwnedPtr<Message> &aMessagePtr,
348                                         Message::Ownership aMessageOwnership);
349 
350     void  EnqueueDatagram(Message &aMessage);
351     void  HandleSendQueue(void);
352     Error PassToHost(OwnedPtr<Message> &aMessagePtr,
353                      const Header      &aHeader,
354                      uint8_t            aIpProto,
355                      bool               aReceive,
356                      Message::Ownership aMessageOwnership);
357     Error HandleExtensionHeaders(OwnedPtr<Message> &aMessagePtr,
358                                  const Header      &aHeader,
359                                  uint8_t           &aNextHeader,
360                                  bool              &aReceive);
361     Error FragmentDatagram(Message &aMessage, uint8_t aIpProto);
362     Error HandleFragment(Message &aMessage);
363 #if OPENTHREAD_CONFIG_IP6_FRAGMENTATION_ENABLE
364     void CleanupFragmentationBuffer(void);
365     void HandleTimeTick(void);
366     void UpdateReassemblyList(void);
367     void SendIcmpError(Message &aMessage, Icmp::Header::Type aIcmpType, Icmp::Header::Code aIcmpCode);
368 #endif
369     Error ReadHopByHopHeader(const Message &aMessage, OffsetRange &aOffsetRange, HopByHopHeader &aHbhHeader) const;
370     Error AddMplOption(Message &aMessage, Header &aHeader);
371     Error PrepareMulticastToLargerThanRealmLocal(Message &aMessage, const Header &aHeader);
372     Error InsertMplOption(Message &aMessage, Header &aHeader);
373     Error RemoveMplOption(Message &aMessage);
374     Error HandleOptions(Message &aMessage, const Header &aHeader, bool &aReceive);
375     Error Receive(Header            &aIp6Header,
376                   OwnedPtr<Message> &aMessagePtr,
377                   uint8_t            aIpProto,
378                   Message::Ownership aMessageOwnership);
379     bool  IsOnLink(const Address &aAddress) const;
380     Error RouteLookup(const Address &aSource, const Address &aDestination) const;
381 #if OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
382     void UpdateBorderRoutingCounters(const Header &aHeader, uint16_t aMessageLength, bool aIsInbound);
383 #endif
384 
385     using SendQueueTask = TaskletIn<Ip6, &Ip6::HandleSendQueue>;
386 
387     bool mReceiveFilterEnabled;
388 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
389     bool mTmfOriginFilterEnabled;
390 #endif
391     Callback<ReceiveCallback> mReceiveCallback;
392 #if OPENTHREAD_CONFIG_NAT64_TRANSLATOR_ENABLE
393     Callback<Ip4ReceiveCallback> mIp4ReceiveCallback;
394 #endif
395     PriorityQueue mSendQueue;
396     SendQueueTask mSendQueueTask;
397     Icmp          mIcmp;
398     Udp           mUdp;
399     Mpl           mMpl;
400 #if OPENTHREAD_CONFIG_TCP_ENABLE
401     Tcp mTcp;
402 #endif
403 #if OPENTHREAD_CONFIG_IP6_FRAGMENTATION_ENABLE
404     MessageQueue mReassemblyList;
405 #endif
406 #if OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
407     BrCounters mBrCounters;
408 #endif
409 };
410 
411 /**
412  * Represents parsed IPv6 header along with UDP/TCP/ICMP6 headers from a received message/frame.
413  */
414 class Headers : private Clearable<Headers>
415 {
416     friend class Clearable<Headers>;
417 
418 public:
419     /**
420      * Parses the IPv6 and UDP/TCP/ICMP6 headers from a given message.
421      *
422      * @param[in] aMessage   The message to parse the headers from.
423      *
424      * @retval kErrorNone    The headers are parsed successfully.
425      * @retval kErrorParse   Failed to parse the headers.
426      */
427     Error ParseFrom(const Message &aMessage);
428 
429     /**
430      * Decompresses lowpan frame and parses the IPv6 and UDP/TCP/ICMP6 headers.
431      *
432      * @param[in]  aMessage         The message from which to read the lowpan frame.
433      * @param[in]  aOffset          The offset in @p aMessage to start reading the frame.
434      * @param[in]  aMacAddrs        The MAC source and destination addresses.
435      *
436      * @retval kErrorNone           Successfully decompressed and parsed IPv6 and UDP/TCP/ICMP6 headers.
437      * @retval kErrorNotFound       Lowpan frame is a next fragment and does not contain IPv6 headers.
438      * @retval kErrorParse          Failed to parse the headers.
439      */
440     Error DecompressFrom(const Message &aMessage, uint16_t aOffset, const Mac::Addresses &aMacAddrs);
441 
442     /**
443      * Decompresses lowpan frame and parses the IPv6 and UDP/TCP/ICMP6 headers.
444      *
445      * @param[in]  aFrameData       The lowpan frame data.
446      * @param[in]  aMacAddrs        The MAC source and destination addresses.
447      * @param[in]  aInstance        The OpenThread instance.
448      *
449      * @retval kErrorNone           Successfully decompressed and parsed IPv6 and UDP/TCP/ICMP6 headers.
450      * @retval kErrorNotFound       Lowpan frame is a next fragment and does not contain IPv6 headers.
451      * @retval kErrorParse          Failed to parse the headers.
452      */
453     Error DecompressFrom(const FrameData &aFrameData, const Mac::Addresses &aMacAddrs, Instance &aInstance);
454 
455     /**
456      * Returns the IPv6 header.
457      *
458      * @returns The IPv6 header.
459      */
GetIp6Header(void) const460     const Header &GetIp6Header(void) const { return mIp6Header; }
461 
462     /**
463      * Returns the IP protocol number from IPv6 Next Header field.
464      *
465      * @returns The IP protocol number.
466      */
GetIpProto(void) const467     uint8_t GetIpProto(void) const { return mIp6Header.GetNextHeader(); }
468 
469     /**
470      * Returns the IPv6 Payload Length value.
471      *
472      * @returns The IPv6 Payload Length value.
473      */
GetIpLength(void) const474     uint8_t GetIpLength(void) const { return mIp6Header.GetPayloadLength(); }
475 
476     /**
477      * Returns the IPv6 Hop Limit value.
478      *
479      * @returns The IPv6 Hop Limit value.
480      */
GetIpHopLimit(void) const481     uint8_t GetIpHopLimit(void) const { return mIp6Header.GetHopLimit(); }
482 
483     /**
484      * Returns the 2-bit Explicit Congestion Notification (ECN) from Traffic Class field from IPv6 header.
485      *
486      * @returns The ECN value.
487      */
GetEcn(void) const488     Ecn GetEcn(void) const { return mIp6Header.GetEcn(); }
489 
490     /**
491      * Indicates if the protocol number from IPv6 header is UDP.
492      *
493      * @retval TRUE   If the protocol number in IPv6 header is UDP.
494      * @retval FALSE  If the protocol number in IPv6 header is not UDP.
495      */
IsUdp(void) const496     bool IsUdp(void) const { return GetIpProto() == kProtoUdp; }
497 
498     /**
499      * Indicates if the protocol number from IPv6 header is TCP.
500      *
501      * @retval TRUE   If the protocol number in IPv6 header is TCP.
502      * @retval FALSE  If the protocol number in IPv6 header is not TCP.
503      */
IsTcp(void) const504     bool IsTcp(void) const { return GetIpProto() == kProtoTcp; }
505 
506     /**
507      * Indicates if the protocol number from IPv6 header is ICMPv6.
508      *
509      * @retval TRUE   If the protocol number in IPv6 header is ICMPv6.
510      * @retval FALSE  If the protocol number in IPv6 header is not ICMPv6.
511      */
IsIcmp6(void) const512     bool IsIcmp6(void) const { return GetIpProto() == kProtoIcmp6; }
513 
514     /**
515      * Returns the source IPv6 address from IPv6 header.
516      *
517      * @returns The source IPv6 address.
518      */
GetSourceAddress(void) const519     const Address &GetSourceAddress(void) const { return mIp6Header.GetSource(); }
520 
521     /**
522      * Returns the destination IPv6 address from IPv6 header.
523      *
524      * @returns The destination IPv6 address.
525      */
GetDestinationAddress(void) const526     const Address &GetDestinationAddress(void) const { return mIp6Header.GetDestination(); }
527 
528     /**
529      * Returns the UDP header.
530      *
531      * MUST be used when `IsUdp() == true`. Otherwise its behavior is undefined
532      *
533      * @returns The UDP header.
534      */
GetUdpHeader(void) const535     const Udp::Header &GetUdpHeader(void) const { return mHeader.mUdp; }
536 
537     /**
538      * Returns the TCP header.
539      *
540      * MUST be used when `IsTcp() == true`. Otherwise its behavior is undefined
541      *
542      * @returns The TCP header.
543      */
GetTcpHeader(void) const544     const Tcp::Header &GetTcpHeader(void) const { return mHeader.mTcp; }
545 
546     /**
547      * Returns the ICMPv6 header.
548      *
549      * MUST be used when `IsIcmp6() == true`. Otherwise its behavior is undefined
550      *
551      * @returns The ICMPv6 header.
552      */
GetIcmpHeader(void) const553     const Icmp::Header &GetIcmpHeader(void) const { return mHeader.mIcmp; }
554 
555     /**
556      * Returns the source port number if header is UDP or TCP, or zero otherwise
557      *
558      * @returns The source port number under UDP / TCP or zero.
559      */
560     uint16_t GetSourcePort(void) const;
561 
562     /**
563      * Sets the source port number if the header is UDP or TCP, does nothing otherwise
564      *
565      * @param[in]  aSrcPort  The UDP / TCP source Port.
566      */
567     void SetSourcePort(uint16_t aSrcPort);
568 
569     /**
570      * Returns the destination port number if header is UDP or TCP, or zero otherwise.
571      *
572      * @returns The destination port number under UDP / TCP or zero.
573      */
574     uint16_t GetDestinationPort(void) const;
575 
576     /**
577      * Returns the checksum values from corresponding UDP, TCP, or ICMPv6 header.
578      *
579      * @returns The checksum value.
580      */
581     uint16_t GetChecksum(void) const;
582 
583 private:
584     Header mIp6Header;
585     union
586     {
587         Udp::Header  mUdp;
588         Tcp::Header  mTcp;
589         Icmp::Header mIcmp;
590     } mHeader;
591 };
592 
593 /**
594  * @}
595  */
596 
597 } // namespace Ip6
598 } // namespace ot
599 
600 #endif // IP6_HPP_
601