• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * @file
3  * NETDB API (sockets)
4  */
5 
6 /*
7  * Redistribution and use in source and binary forms, with or without modification,
8  * are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  *    this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  *    this list of conditions and the following disclaimer in the documentation
14  *    and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
19  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
21  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
23  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
26  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
27  * OF SUCH DAMAGE.
28  *
29  * This file is part of the lwIP TCP/IP stack.
30  *
31  * Author: Simon Goldschmidt
32  *
33  */
34 
35 /**
36 * @defgroup  netdbapi netdb APIs
37 * @ingroup User_interfaces
38 * This contains all the netdb user interfaces.
39 */
40 #ifndef LWIP_HDR_NETDB_H
41 #define LWIP_HDR_NETDB_H
42 
43 #include "lwip/opt.h"
44 #if LWIP_LITEOS_COMPAT
45 #include <netdb.h>
46 #endif
47 #if LWIP_DNS && LWIP_SOCKET
48 
49 #include "lwip/arch.h"
50 #include "lwip/inet.h"
51 #include "lwip/sockets.h"
52 
53 #if defined (__cplusplus) && __cplusplus
54 extern "C" {
55 #endif
56 
57 #if !LWIP_LITEOS_COMPAT
58 /* some rarely used options */
59 #ifndef LWIP_DNS_API_DECLARE_H_ERRNO
60 #define LWIP_DNS_API_DECLARE_H_ERRNO  1
61 #endif
62 
63 #ifndef LWIP_DNS_API_DEFINE_ERRORS
64 #define LWIP_DNS_API_DEFINE_ERRORS    1
65 #endif
66 
67 #ifndef LWIP_DNS_API_DEFINE_FLAGS
68 #define LWIP_DNS_API_DEFINE_FLAGS     1
69 #endif
70 
71 #ifndef LWIP_DNS_API_DECLARE_STRUCTS
72 #define LWIP_DNS_API_DECLARE_STRUCTS  1
73 #endif
74 
75 #if LWIP_DNS_API_DEFINE_ERRORS
76 /** Errors used by the DNS API functions, h_errno can be one of them */
77 #define EAI_NONAME      200
78 #define EAI_SERVICE     201
79 #define EAI_FAIL        202
80 #define EAI_MEMORY      203
81 #define EAI_FAMILY      204
82 #define EAI_BADFLAGS    205
83 #define EAI_OVERFLOW    206
84 #define EAI_ADDRFAMILY  207
85 #define EAI_AGAIN       208
86 
87 /* h_errno values */
88 #define HOST_NOT_FOUND  210
89 #define NO_DATA         211
90 #define NO_RECOVERY     212
91 #define TRY_AGAIN       213
92 #endif /* LWIP_DNS_API_DEFINE_ERRORS */
93 
94 #if LWIP_DNS_API_DEFINE_FLAGS
95 /* input flags for struct addrinfo */
96 #define AI_PASSIVE      0x01
97 #define AI_CANONNAME    0x02
98 #define AI_NUMERICHOST  0x04
99 #define AI_NUMERICSERV  0x08
100 #define AI_V4MAPPED     0x10
101 #define AI_ALL          0x20
102 #define AI_ADDRCONFIG   0x40
103 
104 /* input flags for getnameinfo api */
105 #define NI_NUMERICHOST  1
106 #define NI_NUMERICSERV  2
107 #define NI_NOFQDN       4
108 #define NI_NAMEREQD     8
109 #define NI_DGRAM        16
110 
111 #endif /* LWIP_DNS_API_DEFINE_FLAGS */
112 
113 #if LWIP_DNS_API_DECLARE_STRUCTS
114 /**
115 @brief This structure provides information about a host.
116 */
117 struct hostent {
118   char  *h_name;      /**< Indicates the official name of the host. */
119   char **h_aliases;   /**< Indicates a pointer to an array of pointers to alternative host names,
120                            terminated by a null pointer. */
121   int    h_addrtype;  /**< Indicates the address type. */
122   int    h_length;    /**< Indicates the length, in bytes, of the address. */
123   char **h_addr_list; /**< Indicates a pointer to an array of pointers to network addresses (in
124                            network byte order) for the host, terminated by a null pointer. */
125 #define h_addr h_addr_list[0] /* for backward compatibility */
126 };
127 /**
128 @brief Provides address information that specifies the
129        criteria for selecting the socket address structures returned in the
130        list pointed to by the res parameter of the lwip_getaddrinfo() function.
131 */
132 struct addrinfo {
133   int               ai_flags;      /**< Specifies input flags. */
134   int               ai_family;     /**< Specifies the desired address family.
135                    Valid values for this field include AF_INET and AF_INET6.   */
136   int               ai_socktype;   /**< Specifies the preferred socket type, for example
137                    SOCK_STREAM or SOCK_DGRAM.  Specifying 0 in this
138                    field indicates that socket addresses of any type can be
139                    returned by lwip_getaddrinfo(). */
140   int               ai_protocol;   /**< Specifies the protocol for the returned socket
141                    addresses.  Specifying 0 in this field indicates that
142                    socket addresses with any protocol can be returned by
143                    lwip_getaddrinfo(). */
144   socklen_t         ai_addrlen;    /**< Specifies the length of socket address. */
145   struct sockaddr  *ai_addr;       /**< Specifies the socket address of socket. */
146   char             *ai_canonname;  /**< Specifies the canonical name of the service location. */
147   struct addrinfo  *ai_next;       /**< Pointer to next in the list. */
148 };
149 #endif /* LWIP_DNS_API_DECLARE_STRUCTS */
150 
151 #if LWIP_DNS_API_DECLARE_H_ERRNO
152 /* application accessible error code set by the DNS API functions */
153 extern int h_errno;
154 #endif /* LWIP_DNS_API_DECLARE_H_ERRNO */
155 
156 #endif
157 
158 #define NETDB_ELEM_SIZE           (sizeof(struct addrinfo) + sizeof(struct sockaddr_storage) + DNS_MAX_NAME_LENGTH + 1)
159 #ifndef NI_MAXHOST
160 /* Maximum size of a fully-qualified domain name */
161 #define NI_MAXHOST      1025
162 #endif
163 /* Maximum size of a service name */
164 #define NI_MAXSERV      32
165 
166 #if LWIP_GETHOSTBYNAME || (defined(LWIP_COMPAT_SOCKETS) && (LWIP_COMPAT_SOCKETS != 2))
167 /**
168  * @ingroup netdbapi
169  * @brief This API is used to resolve a hostname (string) into an IP address
170          and return a structure of type hostent for the given host name.
171  * @param name  Indicates either a hostname that is to be resolved or an IPv4 or IPv6
172        address.
173  * @return
174  * Pointer to the hostent structure containing addresses of address family AF_INET or AF_INET6 for the host with the
175  * name 'name' : On success \n
176  * Null pointer: On error \n
177         h_errno variable holds an error number.  When non-NULL, the return
178         value may point at static data, see the notes below.
179         The h_errno variable will contain one among the following error codes in case of failure\n
180         HOST_NOT_FOUND : Hostname not found in DNS Server.\n
181         TRY_AGAIN : Didnt receive information from an authoritative server.\n
182         NO_DATA : Hostname is genuine, but there are no A/AAAA records for it in the server.\n
183         NO_RECOVERY : Some server failure occured which cant be recovered.\n
184         EFAULT : If the parameter "name" is passed as NULL.\n
185         EINVAL : Some internal errors.\n
186 
187  * @note
188  *    - This function is not thread-safe and should not be used in multiple threads.
189  *    - If name is an IPv4 or IPv6 address, no lookup is performed and lwip_gethostbyname()
190  *      copies the name into the h_name field and its struct in_addr equivalent
191  *      into the h_addr_list[0] field of the returned hostent structure.\n
192  *    - This API can give more than one resolved IP address.\n
193  *    - While parsing the multiple answer recrods in DNS response message, if
194  *      it encounters any malformed answer record then it stops parsing and returns
195  *      success if it has successfully parsed some record or else it returns failure.\n
196  *    - DNS Query for the name, if needed, will be sent out immediately.\n
197  *    - If the time gap between the transmission of first DNS Query and the periodic
198  *      retransmission of the same query is less than 100ms, then the periodic retransmission
199  *      will be postponed by another 1100ms.
200  */
201 struct hostent *lwip_gethostbyname(const char *name);
202 #endif /* LWIP_GETHOSTBYNAME || (defined(LWIP_COMPAT_SOCKETS) && (LWIP_COMPAT_SOCKETS != 2)) */
203 
204 #if (defined(LWIP_COMPAT_SOCKETS) && LWIP_COMPAT_SOCKETS != 2) || LWIP_ENABLE_BASIC_SHELL_CMD
205 /**
206  * @ingroup netdbapi
207  * @brief This function is the thread-safe variant of the lwip_gethostbyname() function.
208  * It is used to resolve a hostname (string) into an IP address and return a structure of type hostent for the given
209  * host name. Here name is either a hostname, or an IPv4/IPv6 address in standard dot/colon notation respectively.
210  * Instead of using a static buffer, this function takes buf and h_errnop pointers as arguments
211  * and uses these for the result.
212  * @param name The hostname that is to be resolved.
213  * @param ret The pre-allocated structure where the result is stored.
214  * @param buf The pre-allocated buffer where additional data is stored.
215  * @param buflen The size of the buffer.
216  * @param result This is a double pointer to hostent which is set to ret on success
217  *               and set to zero on error scenario.
218  * @param h_errnop Indicates the pointer to an int where to store errors (instead of modifying
219  *                 the global h_errno)
220  * @return
221  * 0: On success \n
222  * -1: On failure.
223  *      The h_errnop variable will contain one among the following error codes in case of failure.\n
224  *      HOST_NOT_FOUND : Hostname not found in DNS Server.\n
225  *      TRY_AGAIN : Didnt receive information from an authoritative server.\n
226  *      NO_DATA : Hostname is genuine, but there are no A/AAAA records for it in the server.\n
227  *      NO_RECOVERY : Some server failure occured which cant be recovered.\n
228  *      EINVAL : Invalid arguments.\n
229  *      ERANGE : Result not representable due to storage size limitations.\n
230  * @note
231  *    - Additional error information is stored in *h_errnop instead of h_errno to be thread-safe.\n
232  *    - If name is an IPv4 or IPv6 address, no lookup is performed and lwip_gethostbyname_r()
233  *      copies the name into the h_name field and its struct in_addr equivalent
234  *      into the h_addr_list[0] field of the returned hostent structure.\n
235  *    - This API can give more than one resolved IP address.\n
236  *    - While parsing the multiple answer recrods in DNS response message, if
237  *      it encounters any malformed answer record then it stops parsing and returns
238  *      success if it has successfully parsed some record or else it returns failure.\n
239  *    - DNS Query for the name, if needed, will be sent out immediately.\n
240  *    - If the time gap between the transmission of first DNS Query and the periodic
241  *      retransmission of the same query is less than 100ms, then the periodic retransmission
242  *      will be postponed by another 1100ms.
243  */
244 int lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
245                          size_t buflen, struct hostent **result, int *h_errnop);
246 #endif /* (defined(LWIP_COMPAT_SOCKETS) && LWIP_COMPAT_SOCKETS != 2) || LWIP_ENABLE_BASIC_SHELL_CMD */
247 
248 #if (defined(LWIP_COMPAT_SOCKETS) && LWIP_COMPAT_SOCKETS != 2) || LWIP_ENABLE_LOS_SHELL_CMD
249 /**
250  * @ingroup netdbapi
251  * @brief This API is used to free one or more addrinfo
252  *      structures returned by the lwip_getaddrinfo() function, along with any additional
253  *      storage associated with those structures. If the ai_next field of the
254  *      structure ai is not null, the entire list of structures is freed.
255  *
256  * @param ai  The struct addrinfo to free.
257  * @return
258  * None
259  */
260 void lwip_freeaddrinfo(struct addrinfo *ai);
261 
262 
263 /**
264  * @ingroup netdbapi
265  * @brief  Translates the name of a service location (for example, a host name) and
266  * a service name and returns a set of socket addresses and associated
267  * information to be used in creating a socket with which to address the
268  * specified service.
269  * Memory for the result is allocated internally and must be freed by calling
270  * lwip_freeaddrinfo(). \n
271  *
272  * The servname parameter supports only port numbers, and does not support service names.
273  * @param nodename  Indicates a descriptive name or address string of the host. NULL denotes a
274   local address.
275  * @param servname Indicates the port number of the service as string or NULL.
276  * @param hints Indicates a structure containing input values that set socktype and protocol.
277  * @param res Indicates a pointer to a pointer indicating where to store the result. This is set to NULL on failure.
278  * @return
279  * 0: On success \n
280  * Non-zero error number: On failure\n
281  * EAI_FAIL   : If the input parameter res is NULL or the name server returned a permanent failure indication.\n
282  * EAI_FAMILY : The requested address family is not supported.\n
283  * EAI_NONAME : The node or service is not known; or both node and service are
284                 NULL; or service was not a numeric port-number string. Currently,
285                 service supports only AI_NUMERICSERV flag.\n
286  * EAI_MEMORY : Out of memory.\n
287  * EAI_ADDRFAMILY : The specified network host does not have any network addresses in the requested address family.\n
288  * EAI_AGAIN : The name server returned a temporary failure indication. Try again later.
289 
290  * @par Note
291  * - Either nodename or servname, but not both, may be NULL.
292  * - No support for translation of service names.\n
293  * - If the specified network host does not have any network addresses in the requested address family,
294  *   EAI_FAIL will be returned.
295  * - Either nodename or servname, but not both, may be NULL.
296  */
297 int lwip_getaddrinfo(const char *nodename,
298                      const char *servname,
299                      const struct addrinfo *hints,
300                      struct addrinfo **res);
301 #endif /* (defined(LWIP_COMPAT_SOCKETS) && LWIP_COMPAT_SOCKETS != 2) || LWIP_ENABLE_LOS_SHELL_CMD */
302 
303 #if LWIP_DNS_REVERSE
304 /**
305  * @ingroup netdbapi
306  * @brief   Converts a socket address to a corresponding host and service, in a
307  * protocol-independent manner. It is reentrant and allows programs to eliminate
308  * IPv4-versus-IPv6 dependencies.
309  * Memory for the result is allocated by the caller.
310  *
311  * @param sa  Indicates a pointer to a generic socket address structure
312  *            (of type sockaddr_in or sockaddr_in6) that holds the
313  *            input IP address and port number.
314  * @param salen Indicates the size of the generic socket address structure "sa".
315  * @param host Indicates a pointer to caller-allocated buffer which will holds the null terminated hostname string.
316  * @param hostlen Indicates the size of "host" buffer.
317  * @param serv Indicates a pointer to caller-allocated buffer which will holds the null terminated service-name string.
318  * @param servlen Indicates the size of "serv" buffer.
319  * @param flags Used to modify the behaviour of lwip_getnameinfo() and can have the following values:
320  * - NI_NAMEREQD : If set, then an error is returned if the hostname cannot be determined.
321  * - NI_DGRAM : If set, then the service is datagram (UDP) based rather than stream (TCP) based and causes
322  *              getservbyport() to be called with a second  argument of "udp" instead of its default of "tcp".
323  *              This is required for the few ports (512-514) that have different services for UDP and TCP.
324  * - NI_NOFQDN : If set, return only the hostname part of the fully qualified domain name for local hosts.
325  * - NI_NUMERICHOST : If set, then the numeric form of the hostname is returned. (When not set, this will still happen
326  *                    in case the node's name cannot be determined.)
327  * - NI_NUMERICSERV : If set, then the numeric form of the service address is returned.  (When not set, this will still
328  *                    happen in case the service's name cannot be determined.)
329  * @return
330  * 0: On success \n
331  * Non-zero error number: On failure
332  * EAI_FAIL   : A nonrecoverable error occurred..
333  * EAI_FAMILY : The requested address family is not supported.
334  * EAI_NONAME : The name does not resolve for the supplied arguments. NI_NAMEREQD is set and the host's name cannot be
335  *              located, or neither hostname nor service name were requested.
336  * EAI_OVERFLOW : The buffer pointed to by host or serv was too small.
337  * EAI_BADFLAGS : The "flags" argument has an invalid value..
338 
339  * @par Note
340  * - No support for translation of service names.\n
341  * - Since there is no support for Service names, the flags - NI_DGRAM, NI_NUMERICSERV is not supported.
342  * - NI_NOFQDN is not currently implemented
343  * - Reverse DNS Query for the IP Address, if needed, will be sent out immediately.\n
344  * - If the time gap between the transmission of first Reverse DNS Query and the periodic
345  *   retransmission of the same query is less than 100ms, then the periodic retransmission
346  *   will be postponed by another 1100ms.
347  */
348 int lwip_getnameinfo(const struct sockaddr *sa,
349                      socklen_t salen,
350                      char *host,
351                      size_t hostlen,
352                      char *serv,
353                      size_t servlen,
354                      int flags);
355 #endif /* LWIP_DNS_REVERSE */
356 
357 #if defined(LWIP_COMPAT_SOCKETS) && LWIP_COMPAT_SOCKETS != 2
358 /** @ingroup netdbapi */
359 #define gethostbyname(name) lwip_gethostbyname(name)
360 /** @ingroup netdbapi */
361 #define gethostbyname_r(name, ret, buf, buflen, result, h_errnop) \
362        lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop)
363 /** @ingroup netdbapi */
364 #define freeaddrinfo(addrinfo) lwip_freeaddrinfo(addrinfo)
365 /** @ingroup netdbapi */
366 #define getaddrinfo(nodname, servname, hints, res) \
367        lwip_getaddrinfo(nodname, servname, hints, res)
368 
369 /* @ingroup netdbapi */
370 #define getnameinfo(sock, sock_size, host, host_len, servname, servname_size, flags) \
371        lwip_getnameinfo(sock, sock_size, host, host_len, servname, servname_size, flags)
372 #endif /* defined(LWIP_COMPAT_SOCKETS) && LWIP_COMPAT_SOCKETS != 2 */
373 
374 #if defined (__cplusplus) && __cplusplus
375 }
376 #endif
377 
378 #endif /* LWIP_DNS && LWIP_SOCKET */
379 
380 #endif /* LWIP_HDR_NETDB_H */
381