]> andersk Git - openssh.git/blob - fake-getaddrinfo.c
- Big manpage and config file cleanup from Andre Lucas
[openssh.git] / fake-getaddrinfo.c
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  * In the case not using 'configure --enable-ipv6', this getaddrinfo.c
12  * will be used if you have broken getaddrinfo or no getaddrinfo.
13  */
14
15 #include "includes.h"
16 #include "ssh.h"
17
18 #ifndef HAVE_GAI_STRERROR
19 char *
20 gai_strerror(ecode)
21 int ecode;
22 {
23   switch (ecode) {
24   case EAI_NODATA:
25     return "no address associated with hostname.";
26   case EAI_MEMORY:
27     return "memory allocation failure.";
28   default:
29     return "unknown error.";
30   }
31 }    
32 #endif /* !HAVE_GAI_STRERROR */
33
34 #ifndef HAVE_FREEADDRINFO
35 void
36 freeaddrinfo(ai)
37 struct addrinfo *ai;
38 {
39   struct addrinfo *next;
40   
41   do {
42     next = ai->ai_next;
43     free(ai);
44   } while (ai = next);
45 }
46 #endif /* !HAVE_FREEADDRINFO */
47
48 #ifndef HAVE_GETADDRINFO
49 static struct addrinfo *
50 malloc_ai(port, addr)
51 int port;
52 u_long addr;
53 {
54   struct addrinfo *ai;
55
56   if (ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) +
57                                      sizeof(struct sockaddr_in))) {
58     memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
59     ai->ai_addr = (struct sockaddr *)(ai + 1);
60     /* XXX -- ssh doesn't use sa_len */
61     ai->ai_addrlen = sizeof(struct sockaddr_in);
62     ai->ai_addr->sa_family = ai->ai_family = AF_INET;
63     ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
64     ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
65     return ai;
66   } else {
67     return NULL;
68   }
69 }
70
71 int
72 getaddrinfo(hostname, servname, hints, res)
73 const char *hostname, *servname;
74 const struct addrinfo *hints;
75 struct addrinfo **res;
76 {
77   struct addrinfo *cur, *prev = NULL;
78   struct hostent *hp;
79   int i, port;
80   
81   if (servname)
82     port = htons(atoi(servname));
83   else
84     port = 0;
85   if (hints && hints->ai_flags & AI_PASSIVE)
86     if (*res = malloc_ai(port, htonl(0x00000000)))
87       return 0;
88     else
89       return EAI_MEMORY;
90   if (!hostname)
91     if (*res = malloc_ai(port, htonl(0x7f000001)))
92       return 0;
93     else
94       return EAI_MEMORY;
95   if (inet_addr(hostname) != -1)
96     if (*res = malloc_ai(port, inet_addr(hostname)))
97       return 0;
98     else
99       return EAI_MEMORY;
100   if ((hp = gethostbyname(hostname)) &&
101       hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
102     for (i = 0; hp->h_addr_list[i]; i++)
103       if (cur = malloc_ai(port,
104                           ((struct in_addr *)hp->h_addr_list[i])->s_addr)) {
105         if (prev)
106           prev->ai_next = cur;
107         else
108           *res = cur;
109         prev = cur;
110       } else {
111         if (*res)
112           freeaddrinfo(*res);
113         return EAI_MEMORY;
114       }
115     return 0;
116   }
117   return EAI_NODATA;
118 }
119 #endif /* !HAVE_GETADDRINFO */
This page took 0.126984 seconds and 5 git commands to generate.