1 /* $NetBSD: getnameinfo.c,v 1.2 2017/01/28 21:31:50 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1999 - 2001 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include <config.h> 37 38 #include <krb5/roken.h> 39 40 static int 41 doit (int af, 42 const void *addr, 43 size_t addrlen, 44 int port, 45 char *host, size_t hostlen, 46 char *serv, size_t servlen, 47 int flags) 48 { 49 if (host != NULL) { 50 if (flags & NI_NUMERICHOST) { 51 if (inet_ntop (af, addr, host, hostlen) == NULL) 52 return EAI_SYSTEM; 53 } else { 54 struct hostent *he = gethostbyaddr (addr, 55 addrlen, 56 af); 57 if (he != NULL) { 58 strlcpy (host, hostent_find_fqdn(he), hostlen); 59 if (flags & NI_NOFQDN) { 60 char *dot = strchr (host, '.'); 61 if (dot != NULL) 62 *dot = '\0'; 63 } 64 } else if (flags & NI_NAMEREQD) { 65 return EAI_NONAME; 66 } else if (inet_ntop (af, addr, host, hostlen) == NULL) 67 return EAI_SYSTEM; 68 } 69 } 70 71 if (serv != NULL) { 72 if (flags & NI_NUMERICSERV) { 73 snprintf (serv, servlen, "%u", ntohs(port)); 74 } else { 75 const char *proto = "tcp"; 76 struct servent *se; 77 78 if (flags & NI_DGRAM) 79 proto = "udp"; 80 81 se = getservbyport (port, proto); 82 if (se == NULL) { 83 snprintf (serv, servlen, "%u", ntohs(port)); 84 } else { 85 strlcpy (serv, se->s_name, servlen); 86 } 87 } 88 } 89 return 0; 90 } 91 92 /* 93 * 94 */ 95 96 ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL 97 getnameinfo(const struct sockaddr *sa, socklen_t salen, 98 char *host, size_t hostlen, 99 char *serv, size_t servlen, 100 int flags) 101 { 102 switch (sa->sa_family) { 103 #ifdef HAVE_IPV6 104 case AF_INET6 : { 105 const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa; 106 107 return doit (AF_INET6, &sin6->sin6_addr, sizeof(sin6->sin6_addr), 108 sin6->sin6_port, 109 host, hostlen, 110 serv, servlen, 111 flags); 112 } 113 #endif 114 case AF_INET : { 115 const struct sockaddr_in *sin4 = (const struct sockaddr_in *)sa; 116 117 return doit (AF_INET, &sin4->sin_addr, sizeof(sin4->sin_addr), 118 sin4->sin_port, 119 host, hostlen, 120 serv, servlen, 121 flags); 122 } 123 default : 124 return EAI_FAMILY; 125 } 126 } 127