1 /* 2 * fake library for ssh 3 * 4 * This file includes getaddrinfo(), freeaddrinfo() and gai_strerror(). 5 * These funtions are defined in rfc2133. 6 * 7 * But these functions are not implemented correctly. The minimum subset 8 * is implemented for ssh use only. For exapmle, this routine assumes 9 * that ai_family is AF_INET. Don't use it for another purpose. 10 */ 11 12 #include "includes.h" 13 #include "ssh.h" 14 15 RCSID("$Id: fake-getaddrinfo.c,v 1.2 2001/02/09 01:55:36 djm Exp $"); 16 17 #pragma ident "%Z%%M% %I% %E% SMI" 18 19 #ifndef HAVE_GAI_STRERROR 20 char *gai_strerror(int ecode) 21 { 22 switch (ecode) { 23 case EAI_NODATA: 24 return "no address associated with hostname."; 25 case EAI_MEMORY: 26 return "memory allocation failure."; 27 default: 28 return "unknown error."; 29 } 30 } 31 #endif /* !HAVE_GAI_STRERROR */ 32 33 #ifndef HAVE_FREEADDRINFO 34 void freeaddrinfo(struct addrinfo *ai) 35 { 36 struct addrinfo *next; 37 38 do { 39 next = ai->ai_next; 40 free(ai); 41 } while (NULL != (ai = next)); 42 } 43 #endif /* !HAVE_FREEADDRINFO */ 44 45 #ifndef HAVE_GETADDRINFO 46 static struct addrinfo *malloc_ai(int port, u_long addr) 47 { 48 struct addrinfo *ai; 49 50 ai = malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); 51 if (ai == NULL) 52 return(NULL); 53 54 memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); 55 56 ai->ai_addr = (struct sockaddr *)(ai + 1); 57 /* XXX -- ssh doesn't use sa_len */ 58 ai->ai_addrlen = sizeof(struct sockaddr_in); 59 ai->ai_addr->sa_family = ai->ai_family = AF_INET; 60 61 ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; 62 ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; 63 64 return(ai); 65 } 66 67 int getaddrinfo(const char *hostname, const char *servname, 68 const struct addrinfo *hints, struct addrinfo **res) 69 { 70 struct addrinfo *cur, *prev = NULL; 71 struct hostent *hp; 72 struct in_addr in; 73 int i, port; 74 75 if (servname) 76 port = htons(atoi(servname)); 77 else 78 port = 0; 79 80 if (hints && hints->ai_flags & AI_PASSIVE) { 81 if (NULL != (*res = malloc_ai(port, htonl(0x00000000)))) 82 return 0; 83 else 84 return EAI_MEMORY; 85 } 86 87 if (!hostname) { 88 if (NULL != (*res = malloc_ai(port, htonl(0x7f000001)))) 89 return 0; 90 else 91 return EAI_MEMORY; 92 } 93 94 if (inet_aton(hostname, &in)) { 95 if (NULL != (*res = malloc_ai(port, in.s_addr))) 96 return 0; 97 else 98 return EAI_MEMORY; 99 } 100 101 hp = gethostbyname(hostname); 102 if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { 103 for (i = 0; hp->h_addr_list[i]; i++) { 104 cur = malloc_ai(port, ((struct in_addr *)hp->h_addr_list[i])->s_addr); 105 if (cur == NULL) { 106 if (*res) 107 freeaddrinfo(*res); 108 return EAI_MEMORY; 109 } 110 111 if (prev) 112 prev->ai_next = cur; 113 else 114 *res = cur; 115 116 prev = cur; 117 } 118 return 0; 119 } 120 121 return EAI_NODATA; 122 } 123 #endif /* !HAVE_GETADDRINFO */ 124