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 infrastructure network interface.
32  */
33 
34 #ifndef INFRA_IF_HPP_
35 #define INFRA_IF_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
40 
41 #include <openthread/platform/infra_if.h>
42 
43 #include "common/data.hpp"
44 #include "common/error.hpp"
45 #include "common/locator.hpp"
46 #include "common/string.hpp"
47 #include "net/ip6.hpp"
48 
49 namespace ot {
50 namespace BorderRouter {
51 
52 /**
53  * Represents the infrastructure network interface on a border router.
54  */
55 class InfraIf : public InstanceLocator
56 {
57 public:
58     static constexpr uint16_t kInfoStringSize = 20; ///< Max chars for the info string (`ToString()`).
59 
60     typedef String<kInfoStringSize>       InfoString;       ///< String type returned from `ToString()`.
61     typedef Data<kWithUint16Length>       Icmp6Packet;      ///< An IMCPv6 packet (data containing the IP payload)
62     typedef otPlatInfraIfLinkLayerAddress LinkLayerAddress; ///< A link-layer address
63 
64     /**
65      * Initializes the `InfraIf`.
66      *
67      * @param[in]  aInstance  A OpenThread instance.
68      */
69     explicit InfraIf(Instance &aInstance);
70 
71     /**
72      * Initializes the `InfraIf`.
73      *
74      * @param[in]  aIfIndex        The infrastructure interface index.
75      *
76      * @retval  kErrorNone         Successfully initialized the `InfraIf`.
77      * @retval  kErrorInvalidArgs  The index of the infra interface is not valid.
78      * @retval  kErrorInvalidState The `InfraIf` is already initialized.
79      */
80     Error Init(uint32_t aIfIndex);
81 
82     /**
83      * Deinitilaizes the `InfraIf`.
84      */
85     void Deinit(void);
86 
87     /**
88      * Indicates whether or not the `InfraIf` is initialized.
89      *
90      * @retval TRUE    The `InfraIf` is initialized.
91      * @retval FALSE   The `InfraIf` is not initialized.
92      */
IsInitialized(void) const93     bool IsInitialized(void) const { return mInitialized; }
94 
95     /**
96      * Indicates whether or not the infra interface is running.
97      *
98      * @retval TRUE   The infrastructure interface is running.
99      * @retval FALSE  The infrastructure interface is not running.
100      */
IsRunning(void) const101     bool IsRunning(void) const { return mIsRunning; }
102 
103     /**
104      * Returns the infrastructure interface index.
105      *
106      * @returns The interface index or zero if not initialized.
107      */
GetIfIndex(void) const108     uint32_t GetIfIndex(void) const { return mIfIndex; }
109 
110     /**
111      * Sets the infrastructure interface index.
112      *
113      * @param[in]  aIfIndex        The infrastructure interface index.
114      */
SetIfIndex(uint32_t aIfIndex)115     void SetIfIndex(uint32_t aIfIndex) { mIfIndex = aIfIndex; }
116 
117     /**
118      * Gets the infrastructure interface link-layer address.
119      *
120      * @param[out]  aLinkLayerAddress     A reference to return the interface link-layer address.
121      *
122      * @retval  kErrorNone    Successfully get the infrastructure interface link-layer address.
123      * @retval  kErrorFailed  Failed to get the infrastructure interface link-layer address.
124      */
125     Error GetLinkLayerAddress(LinkLayerAddress &aLinkLayerAddress);
126 
127     /**
128      * Indicates whether or not the infra interface has the given IPv6 address assigned.
129      *
130      * MUST be used when interface is initialized.
131      *
132      * @param[in]  aAddress       The IPv6 address.
133      *
134      * @retval TRUE   The infrastructure interface has @p aAddress.
135      * @retval FALSE  The infrastructure interface does not have @p aAddress.
136      */
137     bool HasAddress(const Ip6::Address &aAddress) const;
138 
139     /**
140      * Sends an ICMPv6 Neighbor Discovery packet on the infrastructure interface.
141      *
142      * MUST be used when interface is initialized.
143      *
144      * @param[in]  aPacket        The ICMPv6 packet to send.
145      * @param[in]  aDestination   The destination address.
146      *
147      * @retval kErrorNone    Successfully sent the ICMPv6 message.
148      * @retval kErrorFailed  Failed to send the ICMPv6 message.
149      */
150     Error Send(const Icmp6Packet &aPacket, const Ip6::Address &aDestination) const;
151 
152     /**
153      * Processes a received ICMPv6 Neighbor Discovery packet from an infrastructure interface.
154      *
155      * @param[in]  aIfIndex       The infrastructure interface index on which the ICMPv6 message is received.
156      * @param[in]  aSource        The IPv6 source address.
157      * @param[in]  aPacket        The ICMPv6 packet.
158      */
159     void HandledReceived(uint32_t aIfIndex, const Ip6::Address &aSource, const Icmp6Packet &aPacket);
160 
161     /**
162      * Sends a request to discover the NAT64 prefix on the infrastructure interface.
163      *
164      * @note  This method MUST be used when interface is initialized.
165      *
166      * @retval  kErrorNone    Successfully request NAT64 prefix discovery.
167      * @retval  kErrorFailed  Failed to request NAT64 prefix discovery.
168      */
169     Error DiscoverNat64Prefix(void) const;
170 
171     /**
172      * Processes the discovered NAT64 prefix.
173      *
174      * @param[in]  aIfIndex    The infrastructure interface index on which the host address is received.
175      * @param[in]  aPrefix     The NAT64 prefix on the infrastructure link.
176      */
177     void DiscoverNat64PrefixDone(uint32_t aIfIndex, const Ip6::Prefix &aPrefix);
178 
179     /**
180      * Handles infrastructure interface state changes.
181      *
182      * @param[in]  aIfIndex         The infrastructure interface index.
183      * @param[in]  aIsRunning       A boolean that indicates whether the infrastructure interface is running.
184      *
185      * @retval  kErrorNone          Successfully updated the infra interface status.
186      * @retval  kErrorInvalidState  The `InfraIf` is not initialized.
187      * @retval  kErrorInvalidArgs   The @p IfIndex does not match the interface index of `InfraIf`.
188      */
189     Error HandleStateChanged(uint32_t aIfIndex, bool aIsRunning);
190 
191     /**
192      * Converts the `InfraIf` to a human-readable string.
193      *
194      * @returns The string representation of `InfraIf`.
195      */
196     InfoString ToString(void) const;
197 
198 private:
199     bool     mInitialized : 1;
200     bool     mIsRunning : 1;
201     uint32_t mIfIndex;
202 };
203 
204 } // namespace BorderRouter
205 } // namespace ot
206 
207 #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
208 
209 #endif // INFRA_IF_HPP_
210