* Translates the name of a service location (for example, a host name) and/or * a service name and returns a set of socket addresses and associated * information to be used in creating a socket with which to address the * specified service. * Memory for the result is allocated internally and must be freed by calling * lwip_freeaddrinfo()! * * Due to a limitation in dns_gethostbyname, only t
| 266 | * @todo: implement AI_V4MAPPED, AI_ADDRCONFIG |
| 267 | */ |
| 268 | int |
| 269 | lwip_getaddrinfo(const char *nodename, const char *servname, |
| 270 | const struct addrinfo *hints, struct addrinfo **res) |
| 271 | { |
| 272 | err_t err; |
| 273 | ip_addr_t addr; |
| 274 | struct addrinfo *ai; |
| 275 | struct sockaddr_storage *sa = NULL; |
| 276 | int port_nr = 0; |
| 277 | size_t total_size; |
| 278 | size_t namelen = 0; |
| 279 | int ai_family; |
| 280 | |
| 281 | if (res == NULL) { |
| 282 | return EAI_FAIL; |
| 283 | } |
| 284 | *res = NULL; |
| 285 | if ((nodename == NULL) && (servname == NULL)) { |
| 286 | return EAI_NONAME; |
| 287 | } |
| 288 | |
| 289 | if (hints != NULL) { |
| 290 | ai_family = hints->ai_family; |
| 291 | if ((ai_family != AF_UNSPEC) |
| 292 | #if LWIP_IPV4 |
| 293 | && (ai_family != AF_INET) |
| 294 | #endif /* LWIP_IPV4 */ |
| 295 | #if LWIP_IPV6 |
| 296 | && (ai_family != AF_INET6) |
| 297 | #endif /* LWIP_IPV6 */ |
| 298 | ) { |
| 299 | return EAI_FAMILY; |
| 300 | } |
| 301 | } else { |
| 302 | ai_family = AF_UNSPEC; |
| 303 | } |
| 304 | |
| 305 | if (servname != NULL) { |
| 306 | /* service name specified: convert to port number |
| 307 | * @todo?: currently, only ASCII integers (port numbers) are supported (AI_NUMERICSERV)! */ |
| 308 | port_nr = atoi(servname); |
| 309 | if ((port_nr <= 0) || (port_nr > 0xffff)) { |
| 310 | return EAI_SERVICE; |
| 311 | } |
| 312 | } |
| 313 | |
| 314 | if (nodename != NULL) { |
| 315 | /* service location specified, try to resolve */ |
| 316 | if ((hints != NULL) && (hints->ai_flags & AI_NUMERICHOST)) { |
| 317 | /* no DNS lookup, just parse for an address string */ |
| 318 | if (!ipaddr_aton(nodename, &addr)) { |
| 319 | return EAI_NONAME; |
| 320 | } |
| 321 | #if LWIP_IPV4 && LWIP_IPV6 |
| 322 | if ((IP_IS_V6_VAL(addr) && ai_family == AF_INET) || |
| 323 | (IP_IS_V4_VAL(addr) && ai_family == AF_INET6)) { |
| 324 | return EAI_NONAME; |
| 325 | } |