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