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  * This class implements message information for an IPv6 message.
59  *
60  */
61 class MessageInfo : public otMessageInfo, public Clearable<MessageInfo>
62 {
63 public:
64     /**
65      * This constructor initializes the object.
66      *
67      */
MessageInfo(void)68     MessageInfo(void) { Clear(); }
69 
70     /**
71      * This method 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      * This method 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      * This method 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      * This method 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      * This method 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      * This method 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      * This method 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      * This method 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      * This method 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      * This method 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      * This method 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      * This method 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      * This method 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      * This method 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      * This method returns a pointer to the link-specific information object.
185      *
186      * @returns A pointer to the link-specific information object.
187      *
188      */
GetLinkInfo(void) const189     const void *GetLinkInfo(void) const { return mLinkInfo; }
190 
191     /**
192      * This method sets the pointer to the link-specific information object.
193      *
194      * @param[in]  aLinkInfo  A pointer to the link-specific information object.
195      *
196      */
SetLinkInfo(const void * aLinkInfo)197     void SetLinkInfo(const void *aLinkInfo) { mLinkInfo = aLinkInfo; }
198 
199     /**
200      * This method returns a pointer to the link-specific information as a `ThreadLinkInfo`.
201      *
202      * @returns A pointer to to the link-specific information object as `ThreadLinkInfo`.
203      *
204      */
GetThreadLinkInfo(void) const205     const ThreadLinkInfo *GetThreadLinkInfo(void) const { return reinterpret_cast<const ThreadLinkInfo *>(mLinkInfo); }
206 
207     /**
208      * This method gets the ECN status.
209      *
210      * @returns The ECN status, as represented in the IP header.
211      *
212      */
GetEcn(void) const213     Ecn GetEcn(void) const { return static_cast<Ecn>(mEcn); }
214 
215     /**
216      * This method sets the ECN status.
217      *
218      * @param[in]  aEcn  The ECN status, as represented in the IP header.
219      *
220      */
SetEcn(Ecn aEcn)221     void SetEcn(Ecn aEcn) { mEcn = aEcn; }
222 
223     /**
224      * This method indicates whether peer is via the host interface.
225      *
226      * @retval TRUE if the peer is via the host interface.
227      * @retval FALSE if the peer is via the Thread interface.
228      *
229      */
IsHostInterface(void) const230     bool IsHostInterface(void) const { return mIsHostInterface; }
231 
232     /**
233      * This method indicates whether or not to apply hop limit 0.
234      *
235      * @retval TRUE  if applying hop limit 0 when `mHopLimit` field is 0.
236      * @retval FALSE if applying default `OPENTHREAD_CONFIG_IP6_HOP_LIMIT_DEFAULT` when `mHopLimit` field is 0.
237      *
238      */
ShouldAllowZeroHopLimit(void) const239     bool ShouldAllowZeroHopLimit(void) const { return mAllowZeroHopLimit; }
240 
241     /**
242      * This method sets whether the peer is via the host interface.
243      *
244      * @param[in]  aIsHost  TRUE if the peer is via the host interface, FALSE otherwise.
245      *
246      */
SetIsHostInterface(bool aIsHost)247     void SetIsHostInterface(bool aIsHost) { mIsHostInterface = aIsHost; }
248 };
249 
250 /**
251  * This class implements a socket address.
252  *
253  */
254 class SockAddr : public otSockAddr, public Clearable<SockAddr>, public Unequatable<SockAddr>
255 {
256 public:
257     static constexpr uint16_t kInfoStringSize = OT_IP6_SOCK_ADDR_STRING_SIZE; ///< Info string size (`ToString()`).
258 
259     /**
260      * This type defines the fixed-length `String` object returned from `ToString()`.
261      *
262      */
263     typedef String<kInfoStringSize> InfoString;
264 
265     /**
266      * This constructor initializes the socket address (all fields are set to zero).
267      *
268      */
SockAddr(void)269     SockAddr(void) { Clear(); }
270 
271     /**
272      * This constructor initializes the socket address with a given port number.
273      *
274      * @param[in] aPort   A port number.
275      *
276      */
SockAddr(uint16_t aPort)277     explicit SockAddr(uint16_t aPort)
278     {
279         mPort = aPort;
280         GetAddress().Clear();
281     }
282 
283     /**
284      * This constructor initializes the socket address with a given address and port number.
285      *
286      * @param[in] aAddress  An IPv6 address.
287      * @param[in] aPort     A port number.
288      *
289      */
SockAddr(const Address & aAddress,uint16_t aPort)290     SockAddr(const Address &aAddress, uint16_t aPort)
291     {
292         mAddress = aAddress;
293         mPort    = aPort;
294     }
295 
296     /**
297      * This method returns a reference to the IPv6 address.
298      *
299      * @returns A reference to the IPv6 address.
300      *
301      */
GetAddress(void)302     Address &GetAddress(void) { return AsCoreType(&mAddress); }
303 
304     /**
305      * This method returns a reference to the IPv6 address.
306      *
307      * @returns A reference to the IPv6 address.
308      *
309      */
GetAddress(void) const310     const Address &GetAddress(void) const { return AsCoreType(&mAddress); }
311 
312     /**
313      * This method sets the IPv6 address.
314      *
315      * @param[in] aAddress The IPv6 address.
316      *
317      */
SetAddress(const Address & aAddress)318     void SetAddress(const Address &aAddress) { mAddress = aAddress; }
319 
320     /**
321      * This method returns the socket address port number.
322      *
323      * @returns The port number
324      *
325      */
GetPort(void) const326     uint16_t GetPort(void) const { return mPort; }
327 
328     /**
329      * This method sets the socket address port number.
330      *
331      * @param[in] aPort  The port number.
332      *
333      */
SetPort(uint16_t aPort)334     void SetPort(uint16_t aPort) { mPort = aPort; }
335 
336     /**
337      * This method overloads operator `==` to evaluate whether or not two `SockAddr` instances are equal (same address
338      * and port number).
339      *
340      * @param[in]  aOther  The other `SockAddr` instance to compare with.
341      *
342      * @retval TRUE   If the two `SockAddr` instances are equal.
343      * @retval FALSE  If the two `SockAddr` instances not equal.
344      *
345      */
operator ==(const SockAddr & aOther) const346     bool operator==(const SockAddr &aOther) const
347     {
348         return (GetPort() == aOther.GetPort()) && (GetAddress() == aOther.GetAddress());
349     }
350 
351     /**
352      * This method converts the socket address to a string.
353      *
354      * The string is formatted as "[<ipv6 address>]:<port number>".
355      *
356      * @returns An `InfoString` containing the string representation of the `SockAddr`
357      *
358      */
359     InfoString ToString(void) const;
360 
361     /**
362      * This method converts a given IPv6 socket address to a human-readable string.
363      *
364      * The IPv6 socket address string is formatted as "[<ipv6 address>]:<port>".
365      *
366      * If the resulting string does not fit in @p aBuffer (within its @p aSize characters), the string will be
367      * truncated but the outputted string is always null-terminated.
368      *
369      * @param[out] aBuffer   A pointer to a char array to output the string (MUST NOT be NULL).
370      * @param[in]  aSize     The size of @p aBuffer (in bytes).
371      *
372      */
373     void ToString(char *aBuffer, uint16_t aSize) const;
374 
375 private:
376     void ToString(StringWriter &aWriter) const;
377 };
378 
379 /**
380  * @}
381  */
382 
383 } // namespace Ip6
384 
385 DefineCoreType(otMessageInfo, Ip6::MessageInfo);
386 DefineCoreType(otSockAddr, Ip6::SockAddr);
387 
388 } // namespace ot
389 
390 #endif // NET_SOCKET_HPP_
391