1 /* $OpenBSD: gethostnamadr.c,v 1.8 2013/05/29 06:43:49 eric Exp $ */
3 * Copyright (c) 2012,2013 Eric Faurot <eric@openbsd.org>
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 #include <sys/types.h>
19 #include <netinet/in.h>
29 static int _gethostbyname(const char *, int, struct hostent
*, char *, size_t,
31 static int _fillhostent(const struct hostent
*, struct hostent
*, char *,
34 static struct hostent _hostent
;
35 static char _entbuf
[4096];
37 static char *_empty
[] = { NULL
, };
40 _fillhostent(const struct hostent
*h
, struct hostent
*r
, char *buf
, size_t len
)
42 char **ptr
, *end
, *pos
;
48 r
->h_aliases
= _empty
;
49 r
->h_addr_list
= _empty
;
52 ptr
= (char **)ALIGN(buf
);
54 if ((char *)ptr
>= end
)
57 for (naliases
= 0; h
->h_aliases
[naliases
]; naliases
++)
59 for (naddrs
= 0; h
->h_addr_list
[naddrs
]; naddrs
++)
62 pos
= (char *)(ptr
+ (naliases
+ 1) + (naddrs
+ 1));
67 r
->h_addrtype
= h
->h_addrtype
;
68 r
->h_length
= h
->h_length
;
70 r
->h_addr_list
= ptr
+ naliases
+ 1;
72 n
= strlcpy(pos
, h
->h_name
, end
- pos
);
78 for (i
= 0; i
< naliases
; i
++) {
79 n
= strlcpy(pos
, h
->h_aliases
[i
], end
- pos
);
82 r
->h_aliases
[i
] = pos
;
86 pos
= (char *)ALIGN(pos
);
90 for (i
= 0; i
< naddrs
; i
++) {
91 if (r
->h_length
> end
- pos
)
93 memmove(pos
, h
->h_addr_list
[i
], r
->h_length
);
94 r
->h_addr_list
[i
] = pos
;
102 _gethostbyname(const char *name
, int af
, struct hostent
*ret
, char *buf
,
103 size_t buflen
, int *h_errnop
)
110 as
= gethostbyname_async(name
, NULL
);
112 as
= gethostbyname2_async(name
, af
, NULL
);
117 async_run_sync(as
, &ar
);
120 *h_errnop
= ar
.ar_h_errno
;
121 if (ar
.ar_hostent
== NULL
)
124 r
= _fillhostent(ar
.ar_hostent
, ret
, buf
, buflen
);
131 gethostbyname(const char *name
)
137 if (_res
.options
& RES_USE_INET6
&&
138 (h
= gethostbyname2(name
, AF_INET6
)))
141 return gethostbyname2(name
, AF_INET
);
145 gethostbyname2(const char *name
, int af
)
151 r
= _gethostbyname(name
, af
, &_hostent
, _entbuf
, sizeof(_entbuf
),
154 h_errno
= NETDB_INTERNAL
;
165 gethostbyaddr(const void *addr
, socklen_t len
, int af
)
173 as
= gethostbyaddr_async(addr
, len
, af
, NULL
);
175 h_errno
= NETDB_INTERNAL
;
179 async_run_sync(as
, &ar
);
182 h_errno
= ar
.ar_h_errno
;
183 if (ar
.ar_hostent
== NULL
)
186 r
= _fillhostent(ar
.ar_hostent
, &_hostent
, _entbuf
, sizeof(_entbuf
));
190 h_errno
= NETDB_INTERNAL
;