getnameinfo.c revision 2949f58a438f6fd85f66a8b7ed4708042cde4b37
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#ifndef lint 452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic const char rcsid[] _U_ = 462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project "@(#) $Header: /tcpdump/master/tcpdump/missing/getnameinfo.c,v 1.11 2003/11/16 09:36:49 guy Exp $"; 472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif 482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <sys/types.h> 502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <sys/socket.h> 512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <net/if.h> 522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <netinet/in.h> 532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <arpa/inet.h> 542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <arpa/nameser.h> 552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <netdb.h> 562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <resolv.h> 572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <string.h> 582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <stddef.h> 592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <errno.h> 602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef NEED_ADDRINFO_H 622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "addrinfo.h" 632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif 642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define SUCCESS 0 662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define ANY 0 672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define YES 1 682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define NO 0 692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic struct afd { 712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project int a_af; 722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project int a_addrlen; 732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project int a_socklen; 742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project int a_off; 752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project} afdl [] = { 762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef INET6 772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6), 782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project offsetof(struct sockaddr_in6, sin6_addr)}, 792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif 802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in), 812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project offsetof(struct sockaddr_in, sin_addr)}, 822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project {0, 0, 0}, 832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}; 842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstruct sockinet { 862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project u_char si_len; 872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project u_char si_family; 882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project u_short si_port; 892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}; 902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define ENI_NOSOCKET 0 922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define ENI_NOSERVNAME 1 932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define ENI_NOHOSTNAME 2 942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define ENI_MEMORY 3 952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define ENI_SYSTEM 4 962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define ENI_FAMILY 5 972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define ENI_SALEN 6 982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectint 1002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectgetnameinfo(sa, salen, host, hostlen, serv, servlen, flags) 1012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project const struct sockaddr *sa; 1022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project size_t salen; 1032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project char *host; 1042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project size_t hostlen; 1052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project char *serv; 1062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project size_t servlen; 1072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project int flags; 1082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{ 1092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project struct afd *afd; 1102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project struct servent *sp; 1112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project struct hostent *hp; 1122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project u_short port; 1132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project int family, i; 1142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project char *addr, *p; 1152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project u_int32_t v4a; 1162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project int h_error; 1172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project char numserv[512]; 1182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project char numaddr[512]; 1192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (sa == NULL) 1212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_NOSOCKET; 1222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_SA_LEN /*XXX*/ 1242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (sa->sa_len != salen) 1252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_SALEN; 1262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif 1272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project family = sa->sa_family; 1292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project for (i = 0; afdl[i].a_af; i++) 1302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (afdl[i].a_af == family) { 1312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project afd = &afdl[i]; 1322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project goto found; 1332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 1342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_FAMILY; 1352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project found: 1372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (salen != afd->a_socklen) 1382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_SALEN; 1392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project port = ((struct sockinet *)sa)->si_port; /* network byte order */ 1412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project addr = (char *)sa + afd->a_off; 1422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (serv == NULL || servlen == 0) { 1442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project /* 1452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * do nothing in this case. 1462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * in case you are wondering if "&&" is more correct than 1472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * "||" here: RFC2553 says that serv == NULL OR servlen == 0 1482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * means that the caller does not want the result. 1492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */ 1502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } else { 1512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (flags & NI_NUMERICSERV) 1522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project sp = NULL; 1532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project else { 1542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project sp = getservbyport(port, 1552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project (flags & NI_DGRAM) ? "udp" : "tcp"); 1562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 1572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (sp) { 1582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (strlen(sp->s_name) + 1 > servlen) 1592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_MEMORY; 1602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project strcpy(serv, sp->s_name); 1612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } else { 1622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project snprintf(numserv, sizeof(numserv), "%d", ntohs(port)); 1632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (strlen(numserv) + 1 > servlen) 1642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_MEMORY; 1652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project strcpy(serv, numserv); 1662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 1672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 1682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 1692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project switch (sa->sa_family) { 1702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project case AF_INET: 1712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project v4a = (u_int32_t) 1722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr); 1732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) 1742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project flags |= NI_NUMERICHOST; 1752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project v4a >>= IN_CLASSA_NSHIFT; 1762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (v4a == 0) 1772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project flags |= NI_NUMERICHOST; 1782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project break; 1792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef INET6 1802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project case AF_INET6: 1812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project { 1822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project struct sockaddr_in6 *sin6; 1832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project sin6 = (struct sockaddr_in6 *)sa; 1842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project switch (sin6->sin6_addr.s6_addr[0]) { 1852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project case 0x00: 1862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) 1872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project ; 1882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project else if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)) 1892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project ; 1902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project else 1912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project flags |= NI_NUMERICHOST; 1922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project break; 1932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project default: 1942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 1952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project flags |= NI_NUMERICHOST; 1962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 1972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) 1982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project flags |= NI_NUMERICHOST; 1992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project break; 2002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 2012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 2022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project break; 2032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif 2042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 2052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (host == NULL || hostlen == 0) { 2062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project /* 2072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * do nothing in this case. 2082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * in case you are wondering if "&&" is more correct than 2092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * "||" here: RFC2553 says that host == NULL OR hostlen == 0 2102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * means that the caller does not want the result. 2112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */ 2122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } else if (flags & NI_NUMERICHOST) { 2132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project /* NUMERICHOST and NAMEREQD conflicts with each other */ 2142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (flags & NI_NAMEREQD) 2152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_NOHOSTNAME; 2162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) 2172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project == NULL) 2182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_SYSTEM; 2192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (strlen(numaddr) + 1 > hostlen) 2202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_MEMORY; 2212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project strcpy(host, numaddr); 2222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#if defined(INET6) && defined(NI_WITHSCOPEID) 2232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (afd->a_af == AF_INET6 && 2242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project (IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)addr) || 2252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project IN6_IS_ADDR_MULTICAST((struct in6_addr *)addr)) && 2262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project ((struct sockaddr_in6 *)sa)->sin6_scope_id) { 2272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifndef ALWAYS_WITHSCOPE 2282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (flags & NI_WITHSCOPEID) 2292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif /* !ALWAYS_WITHSCOPE */ 2302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project { 2312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project char *ep = strchr(host, '\0'); 2322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project unsigned int ifindex = 2332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project ((struct sockaddr_in6 *)sa)->sin6_scope_id; 2342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 2352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *ep = SCOPE_DELIMITER; 2362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if ((if_indextoname(ifindex, ep + 1)) == NULL) 2372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project /* XXX what should we do? */ 2382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project strncpy(ep + 1, "???", 3); 2392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 2402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 2412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif /* INET6 */ 2422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } else { 2432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef USE_GETIPNODEBY 2442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error); 2452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#else 2462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af); 2472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_H_ERRNO 2482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project h_error = h_errno; 2492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#else 2502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project h_error = EINVAL; 2512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif 2522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif 2532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project 2542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (hp) { 2552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (flags & NI_NOFQDN) { 2562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project p = strchr(hp->h_name, '.'); 2572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (p) *p = '\0'; 2582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 2592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (strlen(hp->h_name) + 1 > hostlen) { 2602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef USE_GETIPNODEBY 2612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project freehostent(hp); 2622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif 2632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_MEMORY; 2642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 2652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project strcpy(host, hp->h_name); 2662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef USE_GETIPNODEBY 2672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project freehostent(hp); 2682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif 2692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } else { 2702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (flags & NI_NAMEREQD) 2712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_NOHOSTNAME; 2722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) 2732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project == NULL) 2742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_NOHOSTNAME; 2752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project if (strlen(numaddr) + 1 > hostlen) 2762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return ENI_MEMORY; 2772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project strcpy(host, numaddr); 2782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 2792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project } 2802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project return SUCCESS; 2812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project} 282