~ubuntu-branches/ubuntu/karmic/dante/karmic

« back to all changes in this revision

Viewing changes to lib/Rgethostbyname.c

  • Committer: Bazaar Package Importer
  • Author(s): Thijs Kinkhorst
  • Date: 2006-10-19 12:09:39 UTC
  • mfrom: (3.1.1 dapper)
  • Revision ID: james.westby@ubuntu.com-20061019120939-t818x24e2tn8be5k
Tags: 1.1.18-2.1
* Non-maintainer upload for RC bug.
* Make sure changelogs are installed into all packages (Closes: #393568).

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
 *
42
42
 */
43
43
 
 
44
/*
 
45
 * getaddrinfo() contributed by Motoyuki Kasahara <m-kasahr@sra.co.jp>
 
46
 * getipnodebyname() contributed by Lennart Dahlstr�m <lennart@appgate.com>
 
47
 */
 
48
 
44
49
#include "common.h"
45
50
 
46
51
static const char rcsid[] =
47
 
"$Id: Rgethostbyname.c,v 1.41 2003/07/01 13:21:23 michaels Exp $";
 
52
"$Id: Rgethostbyname.c,v 1.46 2005/05/10 11:44:57 michaels Exp $";
48
53
 
49
54
struct hostent *
50
55
Rgethostbyname2(name, af)
107
112
 
108
113
        switch (af) {
109
114
                case AF_INET: {
110
 
                        static char ipv4[sizeof(in_addr_t)];
 
115
                        static char ipv4[INET_ADDRSTRLEN];
111
116
 
112
117
                        hostent->h_length                       = sizeof(ipv4);
113
118
                        *hostent->h_addr_list   = ipv4;
114
119
                        break;
115
120
                }
116
121
 
117
 
#ifdef SOCKS_IPV6
 
122
#if HAVE_IPV6_SUPPORT
118
123
                case AF_INET6: {
119
 
                        static char ipv6[16]; /* XXX */
 
124
                        static char ipv6[INET6_ADDRSTRLEN];
120
125
 
121
126
                        hostent->h_length                       = sizeof(ipv6);
122
127
                        *hostent->h_addr_list   = ipv6;
123
128
                        break;
124
129
                }
125
 
#endif  /* SOCKS_IPV6 */
 
130
#endif /* HAVE_IPV6_SUPPORT */
126
131
 
127
132
                default:
128
133
                        errno = ENOPROTOOPT;
145
150
 
146
151
        return Rgethostbyname2(name, AF_INET);
147
152
}
 
153
 
 
154
#if HAVE_GETADDRINFO
 
155
 
 
156
int
 
157
Rgetaddrinfo(nodename, servname, hints, res)
 
158
        const char *nodename;
 
159
        const char *servname;
 
160
        const struct addrinfo *hints;
 
161
        struct addrinfo **res;
 
162
{
 
163
        const char *function = "Rgetaddrinfo()"; 
 
164
        struct addrinfo fakehints;
 
165
        struct in_addr ipindex;
 
166
        char addrstr[INET6_ADDRSTRLEN];
 
167
        char addrbuf[sizeof(struct in6_addr)];
 
168
        int fakeip_flag;
 
169
        int gaierr;
 
170
 
 
171
        clientinit();
 
172
 
 
173
        if (nodename != NULL)
 
174
                slog(LOG_DEBUG, "%s: %s", function, nodename);
 
175
 
 
176
        fakeip_flag = 1;
 
177
 
 
178
        if (nodename == NULL
 
179
        || (hints != NULL && hints->ai_flags & AI_NUMERICHOST)) {
 
180
                fakeip_flag = 0;
 
181
 
 
182
        } else if (hints == NULL || hints->ai_protocol == PF_UNSPEC) {
 
183
#if HAVE_IPV6_SUPPORT
 
184
                if (inet_pton(AF_INET6, nodename, addrbuf) == 1
 
185
                ||  inet_pton(AF_INET,  nodename, addrbuf) == 1)
 
186
                        fakeip_flag = 0;
 
187
#else  /* HAVE_IPV6_SUPPORT */
 
188
                if (inet_pton(AF_INET,  nodename, addrbuf) == 1)
 
189
                        fakeip_flag = 0;
 
190
#endif  /* HAVE_IPV6_SUPPORT */
 
191
 
 
192
#if HAVE_IPV6_SUPPORT
 
193
        } else if (hints->ai_protocol == PF_INET6) {
 
194
                if (inet_pton(AF_INET6, nodename, addrbuf) == 1)
 
195
                        fakeip_flag = 0;
 
196
#endif  /* HAVE_IPV6_SUPPORT */
 
197
 
 
198
        } else if (hints->ai_protocol == PF_INET) {
 
199
                if (inet_pton(AF_INET,  nodename, addrbuf) == 1)
 
200
                        fakeip_flag = 0;
 
201
        }
 
202
 
 
203
        switch (sockscf.resolveprotocol) {
 
204
                case RESOLVEPROTOCOL_TCP:
 
205
                case RESOLVEPROTOCOL_UDP:
 
206
                        gaierr = getaddrinfo(nodename, servname, hints, res);
 
207
                        if (gaierr == 0 || !fakeip_flag)
 
208
                                return gaierr;
 
209
                        break;
 
210
 
 
211
                case RESOLVEPROTOCOL_FAKE:
 
212
                        if (!fakeip_flag)
 
213
                                return getaddrinfo(nodename, servname, hints, res);
 
214
                        break;
 
215
 
 
216
                default:
 
217
                        SERRX(sockscf.resolveprotocol);
 
218
        }
 
219
 
 
220
        if (!fakeip_flag || nodename == NULL)
 
221
                return EAI_NONAME;
 
222
 
 
223
        if (sockscf.resolveprotocol != RESOLVEPROTOCOL_FAKE) 
 
224
                slog(LOG_DEBUG, "%s: getaddrinfo(%s): %s",
 
225
                function, nodename, gai_strerror(gaierr));
 
226
 
 
227
        if ((ipindex.s_addr = socks_addfakeip(nodename)) == htonl(INADDR_NONE))
 
228
                return EAI_NONAME;
 
229
        strcpy(addrstr, inet_ntoa(ipindex));
 
230
 
 
231
        if (hints == NULL) {
 
232
                fakehints.ai_flags      = AI_NUMERICHOST;
 
233
                fakehints.ai_family     = PF_INET;
 
234
                fakehints.ai_socktype   = 0;
 
235
                fakehints.ai_protocol   = 0;
 
236
        } else {
 
237
                fakehints.ai_flags      = hints->ai_flags | AI_NUMERICHOST;
 
238
                fakehints.ai_family     = hints->ai_family;
 
239
                fakehints.ai_socktype   = hints->ai_socktype;
 
240
                fakehints.ai_protocol   = hints->ai_protocol;
 
241
        }
 
242
        fakehints.ai_addrlen    = 0;
 
243
        fakehints.ai_canonname  = NULL;
 
244
        fakehints.ai_addr       = NULL;
 
245
        fakehints.ai_next       = NULL;
 
246
        
 
247
        return getaddrinfo(addrstr, servname, &fakehints, res);
 
248
}
 
249
 
 
250
#endif /* HAVE_GETADDRINFO */
 
251
 
 
252
#if HAVE_GETIPNODEBYNAME
 
253
/*
 
254
 * Solaris appears to implement getaddrinfo() by calling
 
255
 * getipnodebyname(), but since they are in different libraries, they
 
256
 * must be implemented independently.
 
257
 *
 
258
 * XXX thread safety
 
259
 */
 
260
 
 
261
struct hostent *
 
262
Rgetipnodebyname2(name, af, flags, error_num)
 
263
        const char *name;
 
264
        int af;
 
265
        int flags;
 
266
        int *error_num;
 
267
{
 
268
        const char *function = "Rgetipnodebyname2()"; 
 
269
        char **addrlist;
 
270
        struct in_addr ipindex;
 
271
        struct hostent *hostent;
 
272
 
 
273
        /* needs to be done before getipnodebyname calls. */
 
274
        clientinit();
 
275
 
 
276
        slog(LOG_DEBUG, "%s: %s", function, name); 
 
277
 
 
278
        switch (sockscf.resolveprotocol) {
 
279
                case RESOLVEPROTOCOL_TCP:
 
280
                case RESOLVEPROTOCOL_UDP:
 
281
                        slog(LOG_DEBUG, "%s: using udp/tcp", function); 
 
282
                        if ((hostent = getipnodebyname(name, af, flags, 
 
283
                                                       error_num)) != NULL)
 
284
                          return hostent;
 
285
                        break;
 
286
 
 
287
                case RESOLVEPROTOCOL_FAKE:
 
288
                        slog(LOG_DEBUG, "%s: using fake", function); 
 
289
                        hostent = NULL;
 
290
                        h_errno = NO_RECOVERY;
 
291
                        break;
 
292
 
 
293
                default:
 
294
                        SERRX(sockscf.resolveprotocol);
 
295
        }
 
296
 
 
297
        if (h_errno != NO_RECOVERY)
 
298
                return hostent;
 
299
 
 
300
        hostent = (struct hostent *) malloc(sizeof(struct hostent));
 
301
 
 
302
        /* anything that fails from here is due to resource shortage. */
 
303
        h_errno = TRY_AGAIN;
 
304
 
 
305
        if ((hostent->h_name = strdup(name)) == NULL) {
 
306
                free(hostent);
 
307
                return NULL;
 
308
        }
 
309
 
 
310
        hostent->h_aliases      = NULL;
 
311
        hostent->h_addrtype     = af;
 
312
 
 
313
        /* * 2; NULL terminated. */
 
314
        if ((addrlist = (char **)malloc(sizeof(addrlist) * 2)) == NULL) {
 
315
                free(hostent->h_name);
 
316
                free(hostent);
 
317
                return NULL;
 
318
        }
 
319
 
 
320
        switch (af) {
 
321
                case AF_INET: {
 
322
                        static char ipv4[INET_ADDRSTRLEN];
 
323
 
 
324
                        slog(LOG_DEBUG, "%s: AF_INET", function); 
 
325
                        hostent->h_length = sizeof(ipv4);
 
326
                        *addrlist = ipv4;
 
327
                        break;
 
328
                }
 
329
 
 
330
                case AF_INET6: {
 
331
                        static char ipv6[INET6_ADDRSTRLEN];
 
332
 
 
333
                        slog(LOG_DEBUG, "%s: AF_INET6", function); 
 
334
                        hostent->h_length = sizeof(ipv6);
 
335
                        *addrlist = ipv6;
 
336
                        break;
 
337
                }
 
338
 
 
339
 
 
340
                default:
 
341
                    slog(LOG_DEBUG, "%s: AF_????? (%d)", function, af);
 
342
                        errno = ENOPROTOOPT;
 
343
                        free(hostent->h_name);
 
344
                        free(hostent);
 
345
                        return NULL;
 
346
        }
 
347
 
 
348
        if ((ipindex.s_addr = socks_addfakeip(name)) == htonl(INADDR_NONE)) {
 
349
                free(hostent->h_name);
 
350
                free(*addrlist);
 
351
                free(addrlist);
 
352
                free(hostent);
 
353
                return NULL;
 
354
        }
 
355
 
 
356
        switch (af) {
 
357
                case AF_INET: {
 
358
         memcpy(*addrlist, &ipindex.s_addr, sizeof(in_addr_t));
 
359
                        break;
 
360
                }
 
361
 
 
362
                case AF_INET6: {
 
363
                   unsigned char ff[] = {0xff,0xff};
 
364
                        memset(*addrlist, 0, 10);
 
365
                        memcpy(*addrlist+10, ff, 2);
 
366
                memcpy(*addrlist+12, &ipindex.s_addr, 
 
367
              sizeof(in_addr_t));
 
368
                        break;
 
369
                }
 
370
 
 
371
 
 
372
                default:
 
373
                        slog(LOG_DEBUG, "%s: AF_????? (%d)", function, af);
 
374
                        errno = ENOPROTOOPT;
 
375
                        free(hostent->h_name);
 
376
                        free(*addrlist);
 
377
                        free(addrlist);
 
378
                        free(hostent);
 
379
                        return NULL;
 
380
        }
 
381
 
 
382
        slog(LOG_DEBUG, "%s: after inet_pton (0x%x, %s)", function, (unsigned int)*addrlist, inet_ntoa(ipindex)); 
 
383
        hostent->h_addr_list = addrlist++;
 
384
        *addrlist = NULL;
 
385
 
 
386
        return hostent;
 
387
}
 
388
 
 
389
struct hostent *
 
390
Rgetipnodebyname(name, af, flags, error_num)
 
391
        const char *name;
 
392
        int af;
 
393
        int flags;
 
394
        int *error_num;
 
395
{
 
396
   struct hostent *hent;
 
397
        const char *function = "Rgetipnodebyname()";
 
398
 
 
399
        slog(LOG_DEBUG, "%s: %s, %d", function, name, af);
 
400
 
 
401
        if ((hent = Rgetipnodebyname2(name, af, flags, error_num)) == NULL)
 
402
            *error_num = h_errno;
 
403
 
 
404
        return hent;
 
405
            
 
406
}
 
407
 
 
408
void 
 
409
Rfreehostent(ptr)
 
410
        struct hostent *ptr;
 
411
{
 
412
        struct in_addr addr;
 
413
        
 
414
        if(socks_getfakeip(ptr->h_name, &addr)) {
 
415
              free(ptr->h_name);
 
416
              free(*(ptr->h_addr_list));
 
417
              free(ptr->h_addr_list);
 
418
              free(ptr);
 
419
        } else freehostent(ptr);
 
420
}
 
421
 
 
422
#endif /* HAVE_GETIPNODEBYNAME */