source: rtems-libbsd/freebsd/lib/libc/net/gethostnamadr.c @ 2404264

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 2404264 was 2404264, checked in by Sebastian Huber <sebastian.huber@…>, on 10/30/13 at 12:23:59

Revert superfluous changes

  • Property mode set to 100644
File size: 17.3 KB
Line 
1/*-
2 * Copyright (c) 1994, Garrett Wollman
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26#include <sys/cdefs.h>
27__FBSDID("$FreeBSD$");
28
29#include "namespace.h"
30#include "reentrant.h"
31#include <rtems/bsd/sys/param.h>
32#include <sys/socket.h>
33#include <netinet/in.h>
34#include <arpa/inet.h>
35#include <netdb.h>
36#include <stdio.h>
37#include <ctype.h>
38#include <errno.h>
39#include <stdlib.h>
40#include <string.h>
41#include <stdarg.h>
42#include <nsswitch.h>
43#include <arpa/nameser.h>               /* XXX hack for _res */
44#include <resolv.h>                     /* XXX hack for _res */
45#include "un-namespace.h"
46#include "netdb_private.h"
47#ifdef NS_CACHING
48#include "nscache.h"
49#endif
50
51extern int _ht_gethostbyname(void *, void *, va_list);
52extern int _dns_gethostbyname(void *, void *, va_list);
53extern int _nis_gethostbyname(void *, void *, va_list);
54extern int _ht_gethostbyaddr(void *, void *, va_list);
55extern int _dns_gethostbyaddr(void *, void *, va_list);
56extern int _nis_gethostbyaddr(void *, void *, va_list);
57
58static int gethostbyname_internal(const char *, int, struct hostent *, char *,
59    size_t, struct hostent **, int *, res_state);
60
61/* Host lookup order if nsswitch.conf is broken or nonexistant */
62static const ns_src default_src[] = {
63        { NSSRC_FILES, NS_SUCCESS },
64        { NSSRC_DNS, NS_SUCCESS },
65        { 0 }
66};
67#ifdef NS_CACHING
68static int host_id_func(char *, size_t *, va_list, void *);
69static int host_marshal_func(char *, size_t *, void *, va_list, void *);
70static int host_unmarshal_func(char *, size_t, void *, va_list, void *);
71#endif
72
73NETDB_THREAD_ALLOC(hostent)
74NETDB_THREAD_ALLOC(hostent_data)
75NETDB_THREAD_ALLOC(hostdata)
76
77static void
78hostent_free(void *ptr)
79{
80        free(ptr);
81}
82
83static void
84hostent_data_free(void *ptr)
85{
86        struct hostent_data *hed = ptr;
87
88        if (hed == NULL)
89                return;
90        hed->stayopen = 0;
91        _endhosthtent(hed);
92        free(hed);
93}
94
95static void
96hostdata_free(void *ptr)
97{
98        free(ptr);
99}
100
101int
102__copy_hostent(struct hostent *he, struct hostent *hptr, char *buf,
103    size_t buflen)
104{
105        char *cp;
106        char **ptr;
107        int i, n;
108        int nptr, len;
109
110        /* Find out the amount of space required to store the answer. */
111        nptr = 2; /* NULL ptrs */
112        len = (char *)ALIGN(buf) - buf;
113        for (i = 0; he->h_addr_list[i]; i++, nptr++) {
114                len += he->h_length;
115        }
116        for (i = 0; he->h_aliases[i]; i++, nptr++) {
117                len += strlen(he->h_aliases[i]) + 1;
118        }
119        len += strlen(he->h_name) + 1;
120        len += nptr * sizeof(char*);
121
122        if (len > buflen) {
123                errno = ERANGE;
124                return (-1);
125        }
126
127        /* copy address size and type */
128        hptr->h_addrtype = he->h_addrtype;
129        n = hptr->h_length = he->h_length;
130
131        ptr = (char **)ALIGN(buf);
132        cp = (char *)ALIGN(buf) + nptr * sizeof(char *);
133
134        /* copy address list */
135        hptr->h_addr_list = ptr;
136        for (i = 0; he->h_addr_list[i]; i++ , ptr++) {
137                memcpy(cp, he->h_addr_list[i], n);
138                hptr->h_addr_list[i] = cp;
139                cp += n;
140        }
141        hptr->h_addr_list[i] = NULL;
142        ptr++;
143
144        /* copy official name */
145        n = strlen(he->h_name) + 1;
146        strcpy(cp, he->h_name);
147        hptr->h_name = cp;
148        cp += n;
149
150        /* copy aliases */
151        hptr->h_aliases = ptr;
152        for (i = 0 ; he->h_aliases[i]; i++) {
153                n = strlen(he->h_aliases[i]) + 1;
154                strcpy(cp, he->h_aliases[i]);
155                hptr->h_aliases[i] = cp;
156                cp += n;
157        }
158        hptr->h_aliases[i] = NULL;
159
160        return (0);
161}
162
163#ifdef NS_CACHING
164static int
165host_id_func(char *buffer, size_t *buffer_size, va_list ap, void *cache_mdata)
166{
167        res_state statp;
168        u_long res_options;
169
170        const int op_id = 1;
171        char *str;
172        void *addr;
173        socklen_t len;
174        int type;
175
176        size_t desired_size, size;
177        enum nss_lookup_type lookup_type;
178        char *p;
179        int res = NS_UNAVAIL;
180
181        statp = __res_state();
182        res_options = statp->options & (RES_RECURSE | RES_DEFNAMES |
183            RES_DNSRCH | RES_NOALIASES | RES_USE_INET6);
184
185        lookup_type = (enum nss_lookup_type)cache_mdata;
186        switch (lookup_type) {
187        case nss_lt_name:
188                str = va_arg(ap, char *);
189                type = va_arg(ap, int);
190
191                size = strlen(str);
192                desired_size = sizeof(res_options) + sizeof(int) +
193                    sizeof(enum nss_lookup_type) + sizeof(int) + size + 1;
194
195                if (desired_size > *buffer_size) {
196                        res = NS_RETURN;
197                        goto fin;
198                }
199
200                p = buffer;
201
202                memcpy(p, &res_options, sizeof(res_options));
203                p += sizeof(res_options);
204
205                memcpy(p, &op_id, sizeof(int));
206                p += sizeof(int);
207
208                memcpy(p, &lookup_type, sizeof(enum nss_lookup_type));
209                p += sizeof(int);
210
211                memcpy(p, &type, sizeof(int));
212                p += sizeof(int);
213
214                memcpy(p, str, size + 1);
215
216                res = NS_SUCCESS;
217                break;
218        case nss_lt_id:
219                addr = va_arg(ap, void *);
220                len = va_arg(ap, socklen_t);
221                type = va_arg(ap, int);
222
223                desired_size = sizeof(res_options) + sizeof(int) +
224                    sizeof(enum nss_lookup_type) + sizeof(int) +
225                    sizeof(socklen_t) + len;
226
227                if (desired_size > *buffer_size) {
228                        res = NS_RETURN;
229                        goto fin;
230                }
231
232                p = buffer;
233                memcpy(p, &res_options, sizeof(res_options));
234                p += sizeof(res_options);
235
236                memcpy(p, &op_id, sizeof(int));
237                p += sizeof(int);
238
239                memcpy(p, &lookup_type, sizeof(enum nss_lookup_type));
240                p += sizeof(int);
241
242                memcpy(p, &type, sizeof(int));
243                p += sizeof(int);
244
245                memcpy(p, &len, sizeof(socklen_t));
246                p += sizeof(socklen_t);
247
248                memcpy(p, addr, len);
249
250                res = NS_SUCCESS;
251                break;
252        default:
253                /* should be unreachable */
254                return (NS_UNAVAIL);
255        }
256
257fin:
258        *buffer_size = desired_size;
259        return (res);
260}
261
262static int
263host_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap,
264    void *cache_mdata)
265{
266        char *str;
267        void *addr;
268        socklen_t len;
269        int type;
270        struct hostent *ht;
271
272        struct hostent new_ht;
273        size_t desired_size, aliases_size, addr_size, size;
274        char *p, **iter;
275
276        switch ((enum nss_lookup_type)cache_mdata) {
277        case nss_lt_name:
278                str = va_arg(ap, char *);
279                type = va_arg(ap, int);
280                break;
281        case nss_lt_id:
282                addr = va_arg(ap, void *);
283                len = va_arg(ap, socklen_t);
284                type = va_arg(ap, int);
285                break;
286        default:
287                /* should be unreachable */
288                return (NS_UNAVAIL);
289        }
290        ht = va_arg(ap, struct hostent *);
291
292        desired_size = _ALIGNBYTES + sizeof(struct hostent) + sizeof(char *);
293        if (ht->h_name != NULL)
294                desired_size += strlen(ht->h_name) + 1;
295
296        if (ht->h_aliases != NULL) {
297                aliases_size = 0;
298                for (iter = ht->h_aliases; *iter; ++iter) {
299                        desired_size += strlen(*iter) + 1;
300                        ++aliases_size;
301                }
302
303                desired_size += _ALIGNBYTES +
304                    (aliases_size + 1) * sizeof(char *);
305        }
306
307        if (ht->h_addr_list != NULL) {
308                addr_size = 0;
309                for (iter = ht->h_addr_list; *iter; ++iter)
310                        ++addr_size;
311
312                desired_size += addr_size * _ALIGN(ht->h_length);
313                desired_size += _ALIGNBYTES + (addr_size + 1) * sizeof(char *);
314        }
315
316        if (desired_size > *buffer_size) {
317                /* this assignment is here for future use */
318                *buffer_size = desired_size;
319                return (NS_RETURN);
320        }
321
322        memcpy(&new_ht, ht, sizeof(struct hostent));
323        memset(buffer, 0, desired_size);
324
325        *buffer_size = desired_size;
326        p = buffer + sizeof(struct hostent) + sizeof(char *);
327        memcpy(buffer + sizeof(struct hostent), &p, sizeof(char *));
328        p = (char *)_ALIGN(p);
329
330        if (new_ht.h_name != NULL) {
331                size = strlen(new_ht.h_name);
332                memcpy(p, new_ht.h_name, size);
333                new_ht.h_name = p;
334                p += size + 1;
335        }
336
337        if (new_ht.h_aliases != NULL) {
338                p = (char *)_ALIGN(p);
339                memcpy(p, new_ht.h_aliases, sizeof(char *) * aliases_size);
340                new_ht.h_aliases = (char **)p;
341                p += sizeof(char *) * (aliases_size + 1);
342
343                for (iter = new_ht.h_aliases; *iter; ++iter) {
344                        size = strlen(*iter);
345                        memcpy(p, *iter, size);
346                        *iter = p;
347                        p += size + 1;
348                }
349        }
350
351        if (new_ht.h_addr_list != NULL) {
352                p = (char *)_ALIGN(p);
353                memcpy(p, new_ht.h_addr_list, sizeof(char *) * addr_size);
354                new_ht.h_addr_list = (char **)p;
355                p += sizeof(char *) * (addr_size + 1);
356
357                size = _ALIGN(new_ht.h_length);
358                for (iter = new_ht.h_addr_list; *iter; ++iter) {
359                        memcpy(p, *iter, size);
360                        *iter = p;
361                        p += size + 1;
362                }
363        }
364        memcpy(buffer, &new_ht, sizeof(struct hostent));
365        return (NS_SUCCESS);
366}
367
368static int
369host_unmarshal_func(char *buffer, size_t buffer_size, void *retval, va_list ap,
370    void *cache_mdata)
371{
372        char *str;
373        void *addr;
374        socklen_t len;
375        int type;
376        struct hostent *ht;
377
378        char *p;
379        char **iter;
380        char *orig_buf;
381        size_t orig_buf_size;
382
383        switch ((enum nss_lookup_type)cache_mdata) {
384        case nss_lt_name:
385                str = va_arg(ap, char *);
386                type = va_arg(ap, int);
387                break;
388        case nss_lt_id:
389                addr = va_arg(ap, void *);
390                len = va_arg(ap, socklen_t);
391                type = va_arg(ap, int);
392                break;
393        default:
394                /* should be unreachable */
395                return (NS_UNAVAIL);
396        }
397
398        ht = va_arg(ap, struct hostent *);
399        orig_buf = va_arg(ap, char *);
400        orig_buf_size = va_arg(ap, size_t);
401
402        if (orig_buf_size <
403            buffer_size - sizeof(struct hostent) - sizeof(char *)) {
404                errno = ERANGE;
405                return (NS_RETURN);
406        }
407
408        memcpy(ht, buffer, sizeof(struct hostent));
409        memcpy(&p, buffer + sizeof(struct hostent), sizeof(char *));
410
411        orig_buf = (char *)_ALIGN(orig_buf);
412        memcpy(orig_buf, buffer + sizeof(struct hostent) + sizeof(char *) +
413            _ALIGN(p) - (size_t)p,
414            buffer_size - sizeof(struct hostent) - sizeof(char *) -
415            _ALIGN(p) + (size_t)p);
416        p = (char *)_ALIGN(p);
417
418        NS_APPLY_OFFSET(ht->h_name, orig_buf, p, char *);
419        if (ht->h_aliases != NULL) {
420                NS_APPLY_OFFSET(ht->h_aliases, orig_buf, p, char **);
421
422                for (iter = ht->h_aliases; *iter; ++iter)
423                        NS_APPLY_OFFSET(*iter, orig_buf, p, char *);
424        }
425
426        if (ht->h_addr_list != NULL) {
427                NS_APPLY_OFFSET(ht->h_addr_list, orig_buf, p, char **);
428
429                for (iter = ht->h_addr_list; *iter; ++iter)
430                        NS_APPLY_OFFSET(*iter, orig_buf, p, char *);
431        }
432
433        *((struct hostent **)retval) = ht;
434        return (NS_SUCCESS);
435}
436#endif /* NS_CACHING */
437
438static int
439fakeaddr(const char *name, int af, struct hostent *hp, char *buf,
440    size_t buflen, res_state statp)
441{
442        struct hostent_data *hed;
443        struct hostent he;
444
445        if ((hed = __hostent_data_init()) == NULL) {
446                errno = ENOMEM;
447                RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
448                return (-1);
449        }
450
451        if ((af != AF_INET ||
452            inet_aton(name, (struct in_addr *)hed->host_addr) != 1) &&
453            inet_pton(af, name, hed->host_addr) != 1) {
454                RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
455                return (-1);
456        }
457        strncpy(hed->hostbuf, name, MAXDNAME);
458        hed->hostbuf[MAXDNAME] = '\0';
459#ifdef INET6
460        if (af == AF_INET && (statp->options & RES_USE_INET6) != 0U) {
461                _map_v4v6_address((char *)hed->host_addr,
462                    (char *)hed->host_addr);
463                af = AF_INET6;
464        }
465#endif
466        he.h_addrtype = af;
467        switch(af) {
468        case AF_INET:
469                he.h_length = NS_INADDRSZ;
470                break;
471#ifdef INET6
472        case AF_INET6:
473                he.h_length = NS_IN6ADDRSZ;
474                break;
475#endif
476        default:
477                errno = EAFNOSUPPORT;
478                RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
479                return (-1);
480        }
481        he.h_name = hed->hostbuf;
482        he.h_aliases = hed->host_aliases;
483        hed->host_aliases[0] = NULL;
484        hed->h_addr_ptrs[0] = (char *)hed->host_addr;
485        hed->h_addr_ptrs[1] = NULL;
486        he.h_addr_list = hed->h_addr_ptrs;
487        if (__copy_hostent(&he, hp, buf, buflen) != 0) {
488                RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
489                return (-1);
490        }
491        RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
492        return (0);
493}
494
495int
496gethostbyname_r(const char *name, struct hostent *he, char *buffer,
497    size_t buflen, struct hostent **result, int *h_errnop)
498{
499        res_state statp;
500
501        statp = __res_state();
502        if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1) {
503                RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
504                return (-1);
505        }
506        if (statp->options & RES_USE_INET6) {
507                if (fakeaddr(name, AF_INET, he, buffer, buflen, statp) == 0) {
508                        *result = he;
509                        return (0);
510                }
511                if (gethostbyname_internal(name, AF_INET6, he, buffer, buflen,
512                    result, h_errnop, statp) == 0)
513                        return (0);
514        }
515        return (gethostbyname_internal(name, AF_INET, he, buffer, buflen,
516            result, h_errnop, statp));
517}
518
519int
520gethostbyname2_r(const char *name, int af, struct hostent *he, char *buffer,
521    size_t buflen, struct hostent **result, int *h_errnop)
522{
523        res_state statp;
524
525        statp = __res_state();
526        if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1) {
527                RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
528                return (-1);
529        }
530        return (gethostbyname_internal(name, af, he, buffer, buflen, result,
531            h_errnop, statp));
532}
533
534int
535gethostbyname_internal(const char *name, int af, struct hostent *hp, char *buf,
536    size_t buflen, struct hostent **result, int *h_errnop, res_state statp)
537{
538        const char *cp;
539        int rval, ret_errno = 0;
540        char abuf[MAXDNAME];
541
542#ifdef NS_CACHING
543        static const nss_cache_info cache_info =
544                NS_COMMON_CACHE_INFO_INITIALIZER(
545                hosts, (void *)nss_lt_name,
546                host_id_func, host_marshal_func, host_unmarshal_func);
547#endif
548        static const ns_dtab dtab[] = {
549                NS_FILES_CB(_ht_gethostbyname, NULL)
550                { NSSRC_DNS, _dns_gethostbyname, NULL },
551                NS_NIS_CB(_nis_gethostbyname, NULL) /* force -DHESIOD */
552#ifdef NS_CACHING
553                NS_CACHE_CB(&cache_info)
554#endif
555                { 0 }
556        };
557
558        switch (af) {
559        case AF_INET:
560        case AF_INET6:
561                break;
562        default:
563                RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
564                *h_errnop = statp->res_h_errno;
565                errno = EAFNOSUPPORT;
566                return (-1);
567        }
568
569        /*
570         * if there aren't any dots, it could be a user-level alias.
571         * this is also done in res_query() since we are not the only
572         * function that looks up host names.
573         */
574        if (!strchr(name, '.') &&
575            (cp = res_hostalias(statp, name, abuf, sizeof abuf)))
576                name = cp;
577
578        if (fakeaddr(name, af, hp, buf, buflen, statp) == 0) {
579                *result = hp;
580                return (0);
581        }
582
583        rval = _nsdispatch((void *)result, dtab, NSDB_HOSTS,
584            "gethostbyname2_r", default_src, name, af, hp, buf, buflen,
585            &ret_errno, h_errnop);
586
587        if (rval != NS_SUCCESS) {
588                errno = ret_errno;
589                return ((ret_errno != 0) ? ret_errno : -1);
590        }
591        return (0);
592}
593
594int
595gethostbyaddr_r(const void *addr, socklen_t len, int af, struct hostent *hp,
596    char *buf, size_t buflen, struct hostent **result, int *h_errnop)
597{
598        const u_char *uaddr = (const u_char *)addr;
599        const struct in6_addr *addr6;
600        socklen_t size;
601        int rval, ret_errno = 0;
602        res_state statp;
603
604#ifdef NS_CACHING
605        static const nss_cache_info cache_info =
606                NS_COMMON_CACHE_INFO_INITIALIZER(
607                hosts, (void *)nss_lt_id,
608                host_id_func, host_marshal_func, host_unmarshal_func);
609#endif
610        static const ns_dtab dtab[] = {
611                NS_FILES_CB(_ht_gethostbyaddr, NULL)
612                { NSSRC_DNS, _dns_gethostbyaddr, NULL },
613                NS_NIS_CB(_nis_gethostbyaddr, NULL) /* force -DHESIOD */
614#ifdef NS_CACHING
615                NS_CACHE_CB(&cache_info)
616#endif
617                { 0 }
618        };
619
620        statp = __res_state();
621        if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1) {
622                RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
623                *h_errnop = statp->res_h_errno;
624                return (-1);
625        }
626
627        if (af == AF_INET6 && len == NS_IN6ADDRSZ) {
628                addr6 = (const struct in6_addr *)addr;
629                if (IN6_IS_ADDR_LINKLOCAL(addr6)) {
630                        RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
631                        *h_errnop = statp->res_h_errno;
632                        return (-1);
633                }
634                if (IN6_IS_ADDR_V4MAPPED(addr6) ||
635                    IN6_IS_ADDR_V4COMPAT(addr6)) {
636                        /* Unmap. */
637                        uaddr += NS_IN6ADDRSZ - NS_INADDRSZ;
638                        af = AF_INET;
639                        len = NS_INADDRSZ;
640                }
641        }
642        switch (af) {
643        case AF_INET:
644                size = NS_INADDRSZ;
645                break;
646        case AF_INET6:
647                size = NS_IN6ADDRSZ;
648                break;
649        default:
650                errno = EAFNOSUPPORT;
651                RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
652                *h_errnop = statp->res_h_errno;
653                return (-1);
654        }
655        if (size != len) {
656                errno = EINVAL;
657                RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
658                *h_errnop = statp->res_h_errno;
659                return (-1);
660        }
661
662        rval = _nsdispatch((void *)result, dtab, NSDB_HOSTS,
663            "gethostbyaddr_r", default_src, uaddr, len, af, hp, buf, buflen,
664            &ret_errno, h_errnop);
665
666        if (rval != NS_SUCCESS) {
667                errno = ret_errno;
668                return ((ret_errno != 0) ? ret_errno : -1);
669        }
670        return (0);
671}
672
673struct hostent *
674gethostbyname(const char *name)
675{
676        struct hostdata *hd;
677        struct hostent *rval;
678        int ret_h_errno;
679
680        if ((hd = __hostdata_init()) == NULL)
681                return (NULL);
682        if (gethostbyname_r(name, &hd->host, hd->data, sizeof(hd->data), &rval,
683            &ret_h_errno) != 0)
684                return (NULL);
685        return (rval);
686}
687
688struct hostent *
689gethostbyname2(const char *name, int af)
690{
691        struct hostdata *hd;
692        struct hostent *rval;
693        int ret_h_errno;
694
695        if ((hd = __hostdata_init()) == NULL)
696                return (NULL);
697        if (gethostbyname2_r(name, af, &hd->host, hd->data, sizeof(hd->data),
698            &rval, &ret_h_errno) != 0)
699                return (NULL);
700        return (rval);
701}
702
703struct hostent *
704gethostbyaddr(const void *addr, socklen_t len, int af)
705{
706        struct hostdata *hd;
707        struct hostent *rval;
708        int ret_h_errno;
709
710        if ((hd = __hostdata_init()) == NULL)
711                return (NULL);
712        if (gethostbyaddr_r(addr, len, af, &hd->host, hd->data,
713            sizeof(hd->data), &rval, &ret_h_errno) != 0)
714                return (NULL);
715        return (rval);
716}
717
718void
719sethostent(int stayopen)
720{
721        struct hostent_data *hed;
722
723        if ((hed = __hostent_data_init()) == NULL)
724                return;
725        _sethosthtent(stayopen, hed);
726        _sethostdnsent(stayopen);
727}
728
729void
730endhostent(void)
731{
732        struct hostent_data *hed;
733
734        if ((hed = __hostent_data_init()) == NULL)
735                return;
736        _endhosthtent(hed);
737        _endhostdnsent();
738}
Note: See TracBrowser for help on using the repository browser.