]> andersk Git - openssh.git/blame - openbsd-compat/fake-getaddrinfo.c
- (djm) Sync openbsd-compat/ with OpenBSD CVS head
[openssh.git] / openbsd-compat / fake-getaddrinfo.c
CommitLineData
48e671d5 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.
48e671d5 10 */
11
12#include "includes.h"
13#include "ssh.h"
14
0b202697 15RCSID("$Id$");
16
48e671d5 17#ifndef HAVE_GAI_STRERROR
4a35ae8b 18char *gai_strerror(int ecode)
48e671d5 19{
5daf7064 20 switch (ecode) {
21 case EAI_NODATA:
22 return "no address associated with hostname.";
23 case EAI_MEMORY:
24 return "memory allocation failure.";
25 default:
26 return "unknown error.";
27 }
48e671d5 28}
29#endif /* !HAVE_GAI_STRERROR */
30
31#ifndef HAVE_FREEADDRINFO
5daf7064 32void freeaddrinfo(struct addrinfo *ai)
48e671d5 33{
5daf7064 34 struct addrinfo *next;
35
36 do {
37 next = ai->ai_next;
38 free(ai);
39 } while (NULL != (ai = next));
48e671d5 40}
41#endif /* !HAVE_FREEADDRINFO */
42
43#ifndef HAVE_GETADDRINFO
b1848832 44static struct addrinfo *malloc_ai(int port, u_long addr,
45 const struct addrinfo *hints)
48e671d5 46{
5daf7064 47 struct addrinfo *ai;
48
49 ai = malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
50 if (ai == NULL)
51 return(NULL);
52
53 memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
54
55 ai->ai_addr = (struct sockaddr *)(ai + 1);
56 /* XXX -- ssh doesn't use sa_len */
57 ai->ai_addrlen = sizeof(struct sockaddr_in);
58 ai->ai_addr->sa_family = ai->ai_family = AF_INET;
48e671d5 59
5daf7064 60 ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
61 ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
62
b1848832 63 /* XXX: the following is not generally correct, but does what we want */
64 if (hints->ai_socktype)
65 ai->ai_socktype = hints->ai_socktype;
66 else
67 ai->ai_socktype = SOCK_STREAM;
68
69 if (hints->ai_protocol)
70 ai->ai_protocol = hints->ai_protocol;
71
5daf7064 72 return(ai);
48e671d5 73}
74
5daf7064 75int getaddrinfo(const char *hostname, const char *servname,
76 const struct addrinfo *hints, struct addrinfo **res)
48e671d5 77{
5daf7064 78 struct addrinfo *cur, *prev = NULL;
79 struct hostent *hp;
ecc03386 80 struct servent *sp;
9c13d877 81 struct in_addr in;
ecc03386 82 int i;
83 long int port;
62086365 84 u_long addr;
5daf7064 85
ecc03386 86 port = 0;
87 if (servname != NULL) {
88 char *cp;
89
90 port = strtol(servname, &cp, 10);
91 if (port > 0 && port <= 65535 && *cp == '\0')
92 port = htons(port);
93 else if ((sp = getservbyname(servname, NULL)) != NULL)
94 port = sp->s_port;
95 else
96 port = 0;
97 }
5daf7064 98
99 if (hints && hints->ai_flags & AI_PASSIVE) {
62086365 100 addr = htonl(0x00000000);
101 if (hostname && inet_aton(hostname, &in) != 0)
102 addr = in.s_addr;
b1848832 103 if (NULL != (*res = malloc_ai(port, addr, hints)))
5daf7064 104 return 0;
105 else
106 return EAI_MEMORY;
107 }
108
109 if (!hostname) {
b1848832 110 if (NULL != (*res = malloc_ai(port, htonl(0x7f000001), hints)))
5daf7064 111 return 0;
112 else
113 return EAI_MEMORY;
114 }
115
dc2a6d09 116 if (inet_aton(hostname, &in)) {
b1848832 117 if (NULL != (*res = malloc_ai(port, in.s_addr, hints)))
5daf7064 118 return 0;
119 else
120 return EAI_MEMORY;
121 }
122
123 hp = gethostbyname(hostname);
124 if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
125 for (i = 0; hp->h_addr_list[i]; i++) {
b1848832 126 cur = malloc_ai(port,
127 ((struct in_addr *)hp->h_addr_list[i])->s_addr, hints);
5daf7064 128 if (cur == NULL) {
129 if (*res)
130 freeaddrinfo(*res);
131 return EAI_MEMORY;
132 }
133
134 if (prev)
135 prev->ai_next = cur;
136 else
137 *res = cur;
138
139 prev = cur;
140 }
141 return 0;
142 }
143
144 return EAI_NODATA;
48e671d5 145}
146#endif /* !HAVE_GETADDRINFO */
This page took 0.158332 seconds and 5 git commands to generate.