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 sockets.
32  */
33 
34 #ifndef NET_SOCKET_HPP_
35 #define NET_SOCKET_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include "common/clearable.hpp"
40 #include "common/equatable.hpp"
41 #include "net/ip6_address.hpp"
42 #include "net/ip6_types.hpp"
43 
44 namespace ot {
45 
46 class ThreadLinkInfo;
47 
48 namespace Ip6 {
49 
50 /**
51  * @addtogroup core-ip6-ip6
52  *
53  * @{
54  *
55  */
56 
57 /**
58  * Implements message information for an IPv6 message.
59  *
60  */
61 class MessageInfo : public otMessageInfo, public Clearable<MessageInfo>
62 {
63 public:
64     /**
65      * Initializes the object.
66      *
67      */
MessageInfo(void)68     MessageInfo(void) { Clear(); }
69 
70     /**
71      * Returns a reference to the local socket address.
72      *
73      * @returns A reference to the local socket address.
74      *
75      */
GetSockAddr(void)76     Address &GetSockAddr(void) { return AsCoreType(&mSockAddr); }
77 
78     /**
79      * Returns a reference to the local socket address.
80      *
81      * @returns A reference to the local socket address.
82      *
83      */
GetSockAddr(void) const84     const Address &GetSockAddr(void) const { return AsCoreType(&mSockAddr); }
85 
86     /**
87      * Sets the local socket address.
88      *
89      * @param[in]  aAddress  The IPv6 address.
90      *
91      */
SetSockAddr(const Address & aAddress)92     void SetSockAddr(const Address &aAddress) { mSockAddr = aAddress; }
93 
94     /**
95      * Gets the local socket port.
96      *
97      * @returns The local socket port.
98      *
99      */
GetSockPort(void) const100     uint16_t GetSockPort(void) const { return mSockPort; }
101 
102     /**
103      * Gets the local socket port.
104      *
105      * @param[in]  aPort  The port value.
106      *
107      */
SetSockPort(uint16_t aPort)108     void SetSockPort(uint16_t aPort) { mSockPort = aPort; }
109 
110     /**
111      * Returns a reference to the peer socket address.
112      *
113      * @returns A reference to the peer socket address.
114      *
115      */
GetPeerAddr(void)116     Address &GetPeerAddr(void) { return AsCoreType(&mPeerAddr); }
117 
118     /**
119      * Returns a reference to the peer socket address.
120      *
121      * @returns A reference to the peer socket address.
122      *
123      */
GetPeerAddr(void) const124     const Address &GetPeerAddr(void) const { return AsCoreType(&mPeerAddr); }
125 
126     /**
127      * Sets the peer's socket address.
128      *
129      * @param[in]  aAddress  The IPv6 address.
130      *
131      */
SetPeerAddr(const Address & aAddress)132     void SetPeerAddr(const Address &aAddress) { mPeerAddr = aAddress; }
133 
134     /**
135      * Gets the peer socket port.
136      *
137      * @returns The peer socket port.
138      *
139      */
GetPeerPort(void) const140     uint16_t GetPeerPort(void) const { return mPeerPort; }
141 
142     /**
143      * Gets the peer socket port.
144      *
145      * @param[in]  aPort  The port value.
146      *
147      */
SetPeerPort(uint16_t aPort)148     void SetPeerPort(uint16_t aPort) { mPeerPort = aPort; }
149 
150     /**
151      * Gets the Hop Limit.
152      *
153      * @returns The Hop Limit.
154      *
155      */
GetHopLimit(void) const156     uint8_t GetHopLimit(void) const { return mHopLimit; }
157 
158     /**
159      * Sets the Hop Limit.
160      *
161      * @param[in]  aHopLimit  The Hop Limit.
162      *
163      */
SetHopLimit(uint8_t aHopLimit)164     void SetHopLimit(uint8_t aHopLimit) { mHopLimit = aHopLimit; }
165 
166     /**
167      * Returns whether multicast may be looped back.
168      *
169      * @retval TRUE   If message may be looped back.
170      * @retval FALSE  If message must not be looped back.
171      *
172      */
GetMulticastLoop(void) const173     bool GetMulticastLoop(void) const { return mMulticastLoop; }
174 
175     /**
176      * Sets whether multicast may be looped back.
177      *
178      * @param[in]  aMulticastLoop  Whether allow looping back multicast.
179      *
180      */
SetMulticastLoop(bool aMulticastLoop)181     void SetMulticastLoop(bool aMulticastLoop) { mMulticastLoop = aMulticastLoop; }
182 
183     /**
184      * Gets the ECN status.
185      *
186      * @returns The ECN status, as represented in the IP header.
187      *
188      */
GetEcn(void) const189     Ecn GetEcn(void) const { return static_cast<Ecn>(mEcn); }
190 
191     /**
192      * Sets the ECN status.
193      *
194      * @param[in]  aEcn  The ECN status, as represented in the IP header.
195      *
196      */
SetEcn(Ecn aEcn)197     void SetEcn(Ecn aEcn) { mEcn = aEcn; }
198 
199     /**
200      * Indicates whether peer is via the host interface.
201      *
202      * @retval TRUE if the peer is via the host interface.
203      * @retval FALSE if the peer is via the Thread interface.
204      *
205      */
IsHostInterface(void) const206     bool IsHostInterface(void) const { return mIsHostInterface; }
207 
208     /**
209      * Indicates whether or not to apply hop limit 0.
210      *
211      * @retval TRUE  if applying hop limit 0 when `mHopLimit` field is 0.
212      * @retval FALSE if applying default `OPENTHREAD_CONFIG_IP6_HOP_LIMIT_DEFAULT` when `mHopLimit` field is 0.
213      *
214      */
ShouldAllowZeroHopLimit(void) const215     bool ShouldAllowZeroHopLimit(void) const { return mAllowZeroHopLimit; }
216 
217     /**
218      * Sets whether the peer is via the host interface.
219      *
220      * @param[in]  aIsHost  TRUE if the peer is via the host interface, FALSE otherwise.
221      *
222      */
SetIsHostInterface(bool aIsHost)223     void SetIsHostInterface(bool aIsHost) { mIsHostInterface = aIsHost; }
224 };
225 
226 /**
227  * Implements a socket address.
228  *
229  */
230 class SockAddr : public otSockAddr, public Clearable<SockAddr>, public Unequatable<SockAddr>
231 {
232 public:
233     static constexpr uint16_t kInfoStringSize = OT_IP6_SOCK_ADDR_STRING_SIZE; ///< Info string size (`ToString()`).
234 
235     /**
236      * Defines the fixed-length `String` object returned from `ToString()`.
237      *
238      */
239     typedef String<kInfoStringSize> InfoString;
240 
241     /**
242      * Initializes the socket address (all fields are set to zero).
243      *
244      */
SockAddr(void)245     SockAddr(void) { Clear(); }
246 
247     /**
248      * Initializes the socket address with a given port number.
249      *
250      * @param[in] aPort   A port number.
251      *
252      */
SockAddr(uint16_t aPort)253     explicit SockAddr(uint16_t aPort)
254     {
255         mPort = aPort;
256         GetAddress().Clear();
257     }
258 
259     /**
260      * Initializes the socket address with a given address and port number.
261      *
262      * @param[in] aAddress  An IPv6 address.
263      * @param[in] aPort     A port number.
264      *
265      */
SockAddr(const Address & aAddress,uint16_t aPort)266     SockAddr(const Address &aAddress, uint16_t aPort)
267     {
268         mAddress = aAddress;
269         mPort    = aPort;
270     }
271 
272     /**
273      * Returns a reference to the IPv6 address.
274      *
275      * @returns A reference to the IPv6 address.
276      *
277      */
GetAddress(void)278     Address &GetAddress(void) { return AsCoreType(&mAddress); }
279 
280     /**
281      * Returns a reference to the IPv6 address.
282      *
283      * @returns A reference to the IPv6 address.
284      *
285      */
GetAddress(void) const286     const Address &GetAddress(void) const { return AsCoreType(&mAddress); }
287 
288     /**
289      * Sets the IPv6 address.
290      *
291      * @param[in] aAddress The IPv6 address.
292      *
293      */
SetAddress(const Address & aAddress)294     void SetAddress(const Address &aAddress) { mAddress = aAddress; }
295 
296     /**
297      * Returns the socket address port number.
298      *
299      * @returns The port number
300      *
301      */
GetPort(void) const302     uint16_t GetPort(void) const { return mPort; }
303 
304     /**
305      * Sets the socket address port number.
306      *
307      * @param[in] aPort  The port number.
308      *
309      */
SetPort(uint16_t aPort)310     void SetPort(uint16_t aPort) { mPort = aPort; }
311 
312     /**
313      * Overloads operator `==` to evaluate whether or not two `SockAddr` instances are equal (same address
314      * and port number).
315      *
316      * @param[in]  aOther  The other `SockAddr` instance to compare with.
317      *
318      * @retval TRUE   If the two `SockAddr` instances are equal.
319      * @retval FALSE  If the two `SockAddr` instances not equal.
320      *
321      */
operator ==(const SockAddr & aOther) const322     bool operator==(const SockAddr &aOther) const
323     {
324         return (GetPort() == aOther.GetPort()) && (GetAddress() == aOther.GetAddress());
325     }
326 
327     /**
328      * Converts the socket address to a string.
329      *
330      * The string is formatted as "[<ipv6 address>]:<port number>".
331      *
332      * @returns An `InfoString` containing the string representation of the `SockAddr`
333      *
334      */
335     InfoString ToString(void) const;
336 
337     /**
338      * Converts a given IPv6 socket address to a human-readable string.
339      *
340      * The IPv6 socket address string is formatted as "[<ipv6 address>]:<port>".
341      *
342      * If the resulting string does not fit in @p aBuffer (within its @p aSize characters), the string will be
343      * truncated but the outputted string is always null-terminated.
344      *
345      * @param[out] aBuffer   A pointer to a char array to output the string (MUST NOT be NULL).
346      * @param[in]  aSize     The size of @p aBuffer (in bytes).
347      *
348      */
349     void ToString(char *aBuffer, uint16_t aSize) const;
350 
351 private:
352     void ToString(StringWriter &aWriter) const;
353 };
354 
355 /**
356  * @}
357  */
358 
359 } // namespace Ip6
360 
361 DefineCoreType(otMessageInfo, Ip6::MessageInfo);
362 DefineCoreType(otSockAddr, Ip6::SockAddr);
363 
364 } // namespace ot
365 
366 #endif // NET_SOCKET_HPP_
367