1 /*
2  * Copyright (c) 2017-2019, Texas Instruments Incorporated
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
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*****************************************************************************/
34 /* Include files                                                             */
35 /*****************************************************************************/
36 
37 #ifndef __SL_NET_UTILS_H__
38 #define __SL_NET_UTILS_H__
39 
40 #include <stddef.h>
41 
42 #include "slnetsock.h"
43 
44 #ifdef    __cplusplus
45 extern "C" {
46 #endif
47 
48 /*!
49     \defgroup SlNetUtils SlNetUtils group
50 
51     \short Sockets related commands and configuration
52 
53 */
54 /*!
55 
56     \addtogroup SlNetUtils
57     @{
58 
59 */
60 
61 /*****************************************************************************/
62 /* Macro declarations                                                        */
63 /*****************************************************************************/
64 #define SLNETUTIL_AI_PASSIVE     0x00000001
65 #define SLNETUTIL_AI_NUMERICHOST 0x00000004
66 
67 /*****************************************************************************/
68 /* Structure/Enum declarations                                               */
69 /*****************************************************************************/
70 
71 typedef struct SlNetUtil_addrInfo_t {
72     int                          ai_flags;
73     int                          ai_family;
74     int                          ai_socktype;
75     int                          ai_protocol;
76     size_t                       ai_addrlen;
77     struct SlNetSock_Addr_t     *ai_addr;
78     char                        *ai_canonname;
79     struct SlNetUtil_addrInfo_t *ai_next;
80 } SlNetUtil_addrInfo_t;
81 
82 /* Creating one address parameter from 4 separate address parameters */
83 #define SLNETUTIL_IPV4_VAL(add_3,add_2,add_1,add_0)                         ((((uint32_t)add_3 << 24) & 0xFF000000) | (((uint32_t)add_2 << 16) & 0xFF0000) | (((uint32_t)add_1 << 8) & 0xFF00) | ((uint32_t)add_0 & 0xFF) )
84 
85 /*****************************************************************************/
86 /* Function prototypes                                                       */
87 /*****************************************************************************/
88 
89 /*!
90 
91     \brief Initialize the SlNetUtil module
92 
93     \param[in] flags            Reserved
94 
95     \return                     Zero on success, or negative error code on failure
96 */
97 int32_t SlNetUtil_init(int32_t flags);
98 
99 /*!
100     \brief Return text descriptions of getAddrInfo error codes
101 
102     \param[in] errorCode A getAddrInfo error code
103 
104     \return             Text description of the passed in getAddrInfo error code.
105                         If the error code does not exist returns "Unknown Error"
106  */
107 const char *SlNetUtil_gaiStrErr(int32_t errorCode);
108 
109 /*!
110     \brief Get host IP by name\n
111     Obtain the IP Address of machine on network, by machine name.
112 
113     \param[in]     ifBitmap     Specifies the interfaces which the host ip
114                                 needs to be retrieved from according to the
115                                 priority until one of them will return an answer.\n
116                                 Value 0 is used in order to choose automatic
117                                 interfaces selection according to the priority
118                                 interface list.
119                                 Value can be combination of interfaces by OR'ing
120                                 multiple interfaces bit identifiers (SLNETIFC_IDENT_
121                                 defined in slnetif.h)
122                                 Note: interface identifier bit must be configured
123                                 prior to this socket creation using SlNetIf_add().
124     \param[in]     name         Host name
125     \param[in]     nameLen      Name length
126     \param[out]    ipAddr       A buffer used to store the IP address(es) from
127                                 the resulting DNS resolution. The caller is
128                                 responsible for allocating this buffer. Upon
129                                 return, this buffer can be accessed as an array
130                                 of IPv4 or IPv6 addresses, depending on the
131                                 protocol passed in for the family parameter.
132                                 Addresses are stored in host byte order.
133     \param[in,out] ipAddrLen    Initially holds the number of IP addresses
134                                 that the ipAddr buffer parameter is capable of
135                                 storing. Upon successful return, the ipAddrLen
136                                 parameter contains the number of IP addresses
137                                 that were actually written into the ipAddr
138                                 buffer, as a result of successful DNS
139                                 resolution, or zero if DNS resolution failed.
140     \param[in]     family       Protocol family
141 
142     \return                     The interface ID of the interface which was
143                                 able to successfully run the function, or
144                                 negative on failure.\n
145                                 #SLNETERR_POOL_IS_EMPTY may be return in case
146                                 there are no resources in the system\n
147                                 Possible DNS error codes:
148                                 - #SLNETERR_NET_APP_DNS_QUERY_NO_RESPONSE
149                                 - #SLNETERR_NET_APP_DNS_NO_SERVER
150                                 - #SLNETERR_NET_APP_DNS_QUERY_FAILED
151                                 - #SLNETERR_NET_APP_DNS_MALFORMED_PACKET
152                                 - #SLNETERR_NET_APP_DNS_MISMATCHED_RESPONSE
153 
154     \slnetutil_init_precondition
155 
156     \warning
157             In case an IP address in a string format is set as input, without
158             any prefix (e.g. "1.2.3.4") the device will not try to access the
159             DNS and it will return the input address in the \c ipAddr field
160     \par  Example
161     - Getting IPv4 using get host by name:
162     \code
163     // A buffer capable of storing a single 32-bit IPv4 address
164     uint32_t DestIP[1];
165 
166     // The number of IP addresses that DestIP can hold
167     uint16_t DestIPListSize = 1;
168 
169     int32_t ifID;
170     int16_t  SockId;
171     SlNetSock_AddrIn_t LocalAddr; //address of the server to connect to
172     int32_t LocalAddrSize;
173 
174     ifID = SlNetUtil_getHostByName(0, "www.ti.com", strlen("www.ti.com"), DestIP, &DestIPListSize, SLNETSOCK_PF_INET);
175 
176     LocalAddr.sin_family = SLNETSOCK_AF_INET;
177     LocalAddr.sin_addr.s_addr = SlNetUtil_htonl(DestIP[0]);
178     LocalAddr.sin_port = SlNetUtil_htons(80);
179     LocalAddrSize = sizeof(SlNetSock_AddrIn_t);
180 
181     SockId = SlNetSock_create(SLNETSOCK_AF_INET, SLNETSOCK_SOCK_STREAM, ifID, 0);
182 
183     if (SockId >= 0)
184     {
185         status = SlNetSock_connect(SockId, (SlNetSock_Addr_t *)&LocalAddr, LocalAddrSize);
186     }
187     \endcode
188 */
189 int32_t SlNetUtil_getHostByName(uint32_t ifBitmap, char *name, const uint16_t nameLen, uint32_t *ipAddr, uint16_t *ipAddrLen, const uint8_t family);
190 
191 
192 /*!
193     \brief Network address and service translation
194 
195     Create an IPv4 or IPv6 socket address structure, to be used with bind()
196     and/or connect() to create a client or server socket
197 
198     This is a "minimal" version for support on embedded devices. Supports a
199     host name or an IPv4 or IPv6 address string passed in via the 'node'
200     parameter for creating a client socket.  A value of NULL should be passed
201     for 'node' with AI_PASSIVE flag set to create a (non-loopback) server
202     socket.
203 
204     The caller is responsible for freeing the allocated results by calling
205     SlNetUtil_freeAddrInfo().
206 
207     \param[in] ifID     Specifies the interface which needs
208                         to used for socket operations.\n
209                         The values of the interface identifier
210                         is defined with the prefix SLNETIF_ID_
211                         which defined in slnetif.h
212 
213     \param[in] node     An IP address or a host name.
214 
215     \param[in] service  The port number of the service to bind or connect to.
216 
217     \param[in] hints    An SlNetUtil_addrInfo_t struct used to filter the
218                         results returned.
219 
220     \param[out] res     one or more SlNetUtil_addrInfo_t structs, each of which
221                         can be used to bind or connect a socket.
222 
223     \return             Returns 0 on success, or an error code on failure.
224 
225     \sa                 SlNetUtil_freeAddrInfo()
226 */
227 int32_t SlNetUtil_getAddrInfo(uint16_t ifID, const char *node,
228         const char *service, const struct SlNetUtil_addrInfo_t *hints,
229         struct SlNetUtil_addrInfo_t **res);
230 
231 /*!
232     \brief Free the results returned from SlNetUtil_getAddrInfo
233 
234     Free the chain of SlNetUtil_addrInfo_t structs allocated and returned by
235     SlNetUtil_getAddrInfo
236 
237     \param[in] res linked list of results returned from SlNetUtil_getAddrInfo
238 
239     \return        None.
240 
241     \sa            SlNetUtil_getAddrInfo()
242 */
243 void SlNetUtil_freeAddrInfo(struct SlNetUtil_addrInfo_t *res);
244 
245 /*!
246     \brief Reorder the bytes of a 32-bit unsigned value
247 
248     This function is used to reorder the bytes of a 32-bit unsigned value
249     from host order to network order.
250 
251     \param[in] val              Variable in host order
252 
253     \return                     Return the variable in network order
254 
255     \slnetutil_init_precondition
256 
257     \sa         SlNetSock_bind()
258     \sa         SlNetSock_connect()
259     \sa         SlNetSock_recvFrom()
260     \sa         SlNetSock_accept()
261 */
262 uint32_t SlNetUtil_htonl(uint32_t val);
263 
264 
265 /*!
266     \brief Reorder the bytes of a 32-bit unsigned value
267 
268     This function is used to reorder the bytes of a 32-bit unsigned
269     value from network order to host order.
270 
271     \param[in] val              Variable in network order
272 
273     \return                     Return the variable in host order
274 
275     \slnetutil_init_precondition
276 
277     \sa         SlNetSock_bind()
278     \sa         SlNetSock_connect()
279     \sa         SlNetSock_recvFrom()
280     \sa         SlNetSock_accept()
281 */
282 uint32_t SlNetUtil_ntohl(uint32_t val);
283 
284 
285 /*!
286     \brief Reorder the bytes of a 16-bit unsigned value
287 
288     This functions is used to reorder the bytes of a 16-bit unsigned
289     value from host order to network order.
290 
291     \param[in] val              Variable in host order
292 
293     \return                     Return the variable in network order
294 
295     \slnetutil_init_precondition
296 
297     \sa         SlNetSock_bind()
298     \sa         SlNetSock_connect()
299     \sa         SlNetSock_recvFrom()
300     \sa         SlNetSock_accept()
301 */
302 uint16_t SlNetUtil_htons(uint16_t val);
303 
304 
305 /*!
306     \brief Reorder the bytes of a 16-bit unsigned value
307 
308     This functions is used to reorder the bytes of a 16-bit unsigned value
309     from network order to host order.
310 
311     \param[in] val              Variable in network order
312 
313     \return                     Return the variable in host order
314 
315     \slnetutil_init_precondition
316 
317     \sa         SlNetSock_bind()
318     \sa         SlNetSock_connect()
319     \sa         SlNetSock_recvFrom()
320     \sa         SlNetSock_accept()
321 */
322 uint16_t SlNetUtil_ntohs(uint16_t val);
323 
324 /*!
325     \brief Convert an IPv4 address in string format to binary format
326 
327     This function converts an IPv4 address stored as a character string to a
328     32-bit binary value in network byte order. Note that a leading zero or a
329     "0x" in the address string are interpreted as octal or hexadecimal,
330     respectively. The function stores the IPv4 address in the address structure
331     pointed to by the addr parameter.
332 
333     \param[in] str   IPv4 address string in dotted decimal format
334 
335     \param[out] addr pointer to an IPv4 address structure. The converted binary
336                      address is stored in this structure upon return (in network byte order)
337 
338     \return          returns nonzero if the address string is valid, zero if not
339 */
340 int SlNetUtil_inetAton(const char *str, struct SlNetSock_InAddr_t *addr);
341 
342 /*!
343     \brief Converts IP address in binary representation to string representation
344 
345     This functions is used to converts IP address in binary representation
346     to IP address in string representation.
347 
348     \param[in]  addrFamily     Specifies the address family of the created
349                                socket
350                                For example:
351                                  - #SLNETSOCK_AF_INET for network address IPv4
352                                  - #SLNETSOCK_AF_INET6 for network address IPv6
353     \param[in]  binaryAddr     Pointer to an IP address structure indicating the
354                                address in binary representation. The address
355                                is assumed to be in network-byte order
356     \param[out] strAddr        Pointer to the address string representation
357                                for IPv4 or IPv6 according to the address
358                                family
359     \param[in]  strAddrLen     Specifies the length of the StrAddress_dst,
360                                the maximum length of the address in string
361                                representation for IPv4 or IPv6 according to
362                                the address family
363 
364     \return                    strAddr on success, or NULL on failure
365 
366     \slnetutil_init_precondition
367 
368     \par    Example
369     - IPv4 demo of inet_ntop()
370     \code
371         SlNetSock_AddrIn_t sa;
372         char str[SLNETSOCK_INET_ADDRSTRLEN];
373 
374         // store this IP address in sa:
375         SlNetUtil_inetPton(SLNETSOCK_AF_INET, "192.0.2.33", &(sa.sin_addr));
376         // now get it back and print it
377         SlNetUtil_inetNtop(SLNETSOCK_AF_INET, &(sa.sin_addr), str, SLNETSOCK_INET_ADDRSTRLEN);
378     \endcode
379 */
380 const char *SlNetUtil_inetNtop(int16_t addrFamily, const void *binaryAddr, char *strAddr, SlNetSocklen_t strAddrLen);
381 
382 
383 /*!
384     \brief Converts IP address in string representation to binary representation
385 
386     This functions is used to converts IP address in string representation
387     to IP address in binary representation.
388 
389     \param[in]  addrFamily     Specifies the address family of the created
390                                socket
391                                For example:
392                                  - #SLNETSOCK_AF_INET for network address IPv4
393                                  - #SLNETSOCK_AF_INET6 for network address IPv6
394     \param[in]  strAddr        Specifies the IP address in string representation
395                                for IPv4 or IPv6 according to the address family
396     \param[out] binaryAddr     Pointer to an address structure that will be
397                                filled by the IP address in Binary representation.
398                                The address is returned in network-byte order
399 
400     \return                    1 on success, -1 on failure, or 0 if the input
401                                isn't a valid IP address
402 
403     \slnetutil_init_precondition
404 
405     \par    Example
406     - IPv6 demo of inet_pton()
407     \code
408         SlNetSock_AddrIn6_t sa;
409 
410         // store this IP address in sa:
411         SlNetUtil_inetPton(SLNETSOCK_AF_INET6, "0:0:0:0:0:0:0:0", &(sa.sin6_addr));
412     \endcode
413 */
414 int32_t SlNetUtil_inetPton(int16_t addrFamily, const char *strAddr, void *binaryAddr);
415 
416 /*!
417 
418  Close the Doxygen group.
419  @}
420 
421 */
422 
423 
424 #ifdef  __cplusplus
425 }
426 #endif /* __cplusplus */
427 
428 #endif /* __SL_NET_UTILS_H__ */
429