12949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* 22949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 32949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * All rights reserved. 42949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 52949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Redistribution and use in source and binary forms, with or without 62949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * modification, are permitted provided that the following conditions 72949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * are met: 82949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 92949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * notice, this list of conditions and the following disclaimer. 102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * documentation and/or other materials provided with the distribution. 132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 3. Neither the name of the project nor the names of its contributors 142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * may be used to endorse or promote products derived from this software 152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * without specific prior written permission. 162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * SUCH DAMAGE. 282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */ 292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* 312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Issues to be discussed: 322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * - Thread safe-ness must be checked 332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * - Return values. There seems to be no standard for return value (RFC2553) 342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * but INRIA implementation returns EAI_xxx defined for getaddrinfo(). 352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * - RFC2553 says that we should raise error on short buffer. X/Open says 362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * we need to truncate the result. We obey RFC2553 (and X/Open should be 372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * modified). 382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */ 392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_CONFIG_H 412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <config.h> 422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif 432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <sys/types.h> 452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <sys/socket.h> 462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <net/if.h> 472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <netinet/in.h> 482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <arpa/inet.h> 492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <arpa/nameser.h> 502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <netdb.h> 512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <resolv.h> 522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <string.h> 532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <stddef.h> 542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <errno.h> 552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef NEED_ADDRINFO_H 572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "addrinfo.h" 582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif 592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define SUCCESS 0 612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define ANY 0 622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define YES 1 632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define NO 0 642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic struct afd { 662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project int a_af; 672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project int a_addrlen; 682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project int a_socklen; 692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project int a_off; 702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project} afdl [] = { 712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef INET6 722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6), 732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project offsetof(struct sockaddr_in6, sin6_addr)}, 742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif 752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in), 762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project offsetof(struct sockaddr_in, sin_addr)}, 772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project {0, 0, 0}, 782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}; 792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstruct sockinet { 812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project u_char si_len; 822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project u_char si_family; 832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project u_short si_port; 842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}; 852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define ENI_NOSOCKET 0 872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define ENI_NOSERVNAME 1 882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define ENI_NOHOSTNAME 2 892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define ENI_MEMORY 3 902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define ENI_SYSTEM 4 912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define ENI_FAMILY 5 922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define ENI_SALEN 6 932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectint 952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectgetnameinfo(sa, salen, host, hostlen, serv, servlen, flags) 962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project const struct sockaddr *sa; 972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project size_t salen; 982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project char *host; 992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project size_t hostlen; 1002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project char *serv; 1012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project size_t servlen; 1022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project int flags; 1032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{ 1042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project struct afd *afd; 1052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project struct servent *sp; 1062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project struct hostent *hp; 1072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project u_short port; 1082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project int family, i; 1092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project char *addr, *p; 110892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes uint32_t v4a; 1112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project int h_error; 1122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project char numserv[512]; 1132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project char numaddr[512]; 1142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (sa == NULL) 1162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_NOSOCKET; 1172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_SA_LEN /*XXX*/ 1192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (sa->sa_len != salen) 1202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_SALEN; 1212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif 1222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project family = sa->sa_family; 1242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project for (i = 0; afdl[i].a_af; i++) 1252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (afdl[i].a_af == family) { 1262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project afd = &afdl[i]; 1272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project goto found; 1282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 1292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_FAMILY; 1302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project found: 1322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (salen != afd->a_socklen) 1332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_SALEN; 1342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project port = ((struct sockinet *)sa)->si_port; /* network byte order */ 1362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project addr = (char *)sa + afd->a_off; 1372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (serv == NULL || servlen == 0) { 1392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project /* 1402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * do nothing in this case. 1412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * in case you are wondering if "&&" is more correct than 1422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * "||" here: RFC2553 says that serv == NULL OR servlen == 0 1432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * means that the caller does not want the result. 1442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */ 1452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } else { 1462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (flags & NI_NUMERICSERV) 1472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project sp = NULL; 1482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project else { 1492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project sp = getservbyport(port, 1502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project (flags & NI_DGRAM) ? "udp" : "tcp"); 1512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 1522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (sp) { 1532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (strlen(sp->s_name) + 1 > servlen) 1542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_MEMORY; 1552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project strcpy(serv, sp->s_name); 1562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } else { 1572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project snprintf(numserv, sizeof(numserv), "%d", ntohs(port)); 1582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (strlen(numserv) + 1 > servlen) 1592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_MEMORY; 1602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project strcpy(serv, numserv); 1612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 1622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 1632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project switch (sa->sa_family) { 1652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project case AF_INET: 166892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes v4a = (uint32_t) 1672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr); 1682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) 1692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project flags |= NI_NUMERICHOST; 1702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project v4a >>= IN_CLASSA_NSHIFT; 1712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (v4a == 0) 1722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project flags |= NI_NUMERICHOST; 1732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project break; 1742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef INET6 1752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project case AF_INET6: 1762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project { 1772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project struct sockaddr_in6 *sin6; 1782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project sin6 = (struct sockaddr_in6 *)sa; 1792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project switch (sin6->sin6_addr.s6_addr[0]) { 1802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project case 0x00: 1812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) 1822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project ; 1832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project else if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)) 1842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project ; 1852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project else 1862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project flags |= NI_NUMERICHOST; 1872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project break; 1882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project default: 1892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 1902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project flags |= NI_NUMERICHOST; 1912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 1922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) 1932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project flags |= NI_NUMERICHOST; 1942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project break; 1952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 1962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 1972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project break; 1982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif 1992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 2002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (host == NULL || hostlen == 0) { 2012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project /* 2022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * do nothing in this case. 2032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * in case you are wondering if "&&" is more correct than 2042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * "||" here: RFC2553 says that host == NULL OR hostlen == 0 2052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * means that the caller does not want the result. 2062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */ 2072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } else if (flags & NI_NUMERICHOST) { 2082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project /* NUMERICHOST and NAMEREQD conflicts with each other */ 2092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (flags & NI_NAMEREQD) 2102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_NOHOSTNAME; 2112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) 2122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project == NULL) 2132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_SYSTEM; 2142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (strlen(numaddr) + 1 > hostlen) 2152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_MEMORY; 2162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project strcpy(host, numaddr); 2172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#if defined(INET6) && defined(NI_WITHSCOPEID) 2182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (afd->a_af == AF_INET6 && 2192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project (IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)addr) || 2202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project IN6_IS_ADDR_MULTICAST((struct in6_addr *)addr)) && 2212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project ((struct sockaddr_in6 *)sa)->sin6_scope_id) { 2222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifndef ALWAYS_WITHSCOPE 2232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (flags & NI_WITHSCOPEID) 2242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif /* !ALWAYS_WITHSCOPE */ 2252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project { 2262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project char *ep = strchr(host, '\0'); 2272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project unsigned int ifindex = 2282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project ((struct sockaddr_in6 *)sa)->sin6_scope_id; 2292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 2302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *ep = SCOPE_DELIMITER; 2312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if ((if_indextoname(ifindex, ep + 1)) == NULL) 2322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project /* XXX what should we do? */ 2332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project strncpy(ep + 1, "???", 3); 2342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 2352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 2362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif /* INET6 */ 2372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } else { 2382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef USE_GETIPNODEBY 2392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error); 2402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#else 2412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af); 2422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_H_ERRNO 2432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project h_error = h_errno; 2442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#else 2452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project h_error = EINVAL; 2462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif 2472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif 2482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 2492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (hp) { 2502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (flags & NI_NOFQDN) { 2512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project p = strchr(hp->h_name, '.'); 2522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (p) *p = '\0'; 2532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 2542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (strlen(hp->h_name) + 1 > hostlen) { 2552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef USE_GETIPNODEBY 2562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project freehostent(hp); 2572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif 2582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_MEMORY; 2592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 2602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project strcpy(host, hp->h_name); 2612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef USE_GETIPNODEBY 2622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project freehostent(hp); 2632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif 2642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } else { 2652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (flags & NI_NAMEREQD) 2662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_NOHOSTNAME; 2672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) 2682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project == NULL) 2692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_NOHOSTNAME; 2702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (strlen(numaddr) + 1 > hostlen) 2712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_MEMORY; 2722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project strcpy(host, numaddr); 2732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 2742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 2752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return SUCCESS; 2762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project} 277