1 /*
2  * Mar  8, 2000 by Hajimu UMEMOTO <ume@mahoroba.org>
3  * $Id: getnameinfo.c 99 2004-01-04 10:13:44Z ume $
4  *
5  * This module is besed on ssh-1.2.27-IPv6-1.5 written by
6  * KIKUCHI Takahiro <kick@kyoto.wide.ad.jp>
7  */
8 /*
9  * fake library for ssh
10  *
11  * This file includes getnameinfo().
12  * These funtions are defined in rfc2133.
13  *
14  * But these functions are not implemented correctly. The minimum subset
15  * is implemented for ssh use only. For exapmle, this routine assumes
16  * that ai_family is AF_INET. Don't use it for another purpose.
17  *
18  * In the case not using 'configure --enable-ipv6', this getnameinfo.c
19  * will be used if you have broken getnameinfo or no getnameinfo.
20  */
21 
22 #include <string.h>
23 #include "gai.h"
24 
25 #ifndef HAVE_SOCKLEN_T
26 typedef unsigned int socklen_t;
27 #endif /* HAVE_SOCKLEN_T */
28 
29 int
getnameinfo(const struct sockaddr * sa,socklen_t salen,char * host,size_t hostlen,char * serv,size_t servlen,int flags)30 getnameinfo(const struct sockaddr *sa, socklen_t salen,
31 	    char *host, size_t hostlen, char *serv, size_t servlen, int flags)
32 {
33     struct sockaddr_in *sin = (struct sockaddr_in *)sa;
34     struct hostent *hp;
35     char tmpserv[16];
36 
37     if (serv) {
38 	snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port));
39 	if (strlen(tmpserv) > servlen)
40 	    return EAI_MEMORY;
41 	else
42 	    strcpy(serv, tmpserv);
43     }
44     if (host) {
45 	if (flags & NI_NUMERICHOST) {
46 	    if (flags & NI_NAMEREQD)
47 		return EAI_NONAME;
48 	    if (strlen(inet_ntoa(sin->sin_addr)) >= hostlen)
49 		return EAI_MEMORY;
50 	    else {
51 		strcpy(host, inet_ntoa(sin->sin_addr));
52 		return 0;
53 	    }
54 	} else {
55 	    hp = gethostbyaddr((char *)&sin->sin_addr,
56 			       sizeof(struct in_addr), AF_INET);
57 	    if (hp)
58 		if (strlen(hp->h_name) >= hostlen)
59 		    return EAI_MEMORY;
60 		else {
61 		    strcpy(host, hp->h_name);
62 		    return 0;
63 		}
64 	    else if (flags & NI_NAMEREQD)
65 		return EAI_NONAME;
66 	    else if (strlen(inet_ntoa(sin->sin_addr)) >= hostlen)
67 		return EAI_MEMORY;
68 	    else {
69 		strcpy(host, inet_ntoa(sin->sin_addr));
70 		return 0;
71 	    }
72 	}
73     }
74     return 0;
75 }
76