GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libc/asr/gethostnamadr.c Lines: 0 84 0.0 %
Date: 2017-11-07 Branches: 0 40 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: gethostnamadr.c,v 1.13 2015/09/14 07:38:37 guenther Exp $	*/
2
/*
3
 * Copyright (c) 2012,2013 Eric Faurot <eric@openbsd.org>
4
 *
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.
8
 *
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.
16
 */
17
18
#include <sys/param.h>	/* ALIGN */
19
#include <sys/types.h>
20
#include <sys/socket.h>
21
#include <netinet/in.h>
22
#include <netdb.h>
23
24
#include <asr.h>
25
#include <errno.h>
26
#include <resolv.h>
27
#include <stdint.h>
28
#include <stdlib.h>
29
#include <string.h>
30
31
static int _gethostbyname(const char *, int, struct hostent *, char *, size_t,
32
    int *);
33
static int _fillhostent(const struct hostent *, struct hostent *, char *,
34
    size_t);
35
36
static struct hostent	 _hostent;
37
static char		 _entbuf[4096];
38
39
static char *_empty[] = { NULL, };
40
41
static int
42
_fillhostent(const struct hostent *h, struct hostent *r, char *buf, size_t len)
43
{
44
	char	**ptr, *end, *pos;
45
	size_t	n, i;
46
	int	naliases, naddrs;
47
48
	bzero(buf, len);
49
	bzero(r, sizeof(*r));
50
	r->h_aliases = _empty;
51
	r->h_addr_list = _empty;
52
53
	end = buf + len;
54
	ptr = (char **)ALIGN(buf);
55
56
	if ((char *)ptr >= end)
57
		return (ERANGE);
58
59
	for (naliases = 0; h->h_aliases[naliases]; naliases++)
60
		;
61
	for (naddrs = 0; h->h_addr_list[naddrs]; naddrs++)
62
		;
63
64
	pos = (char *)(ptr + (naliases + 1) + (naddrs + 1));
65
	if (pos >= end)
66
		return (ERANGE);
67
68
	r->h_name = NULL;
69
	r->h_addrtype = h->h_addrtype;
70
	r->h_length = h->h_length;
71
	r->h_aliases = ptr;
72
	r->h_addr_list = ptr + naliases + 1;
73
74
	n = strlcpy(pos, h->h_name, end - pos);
75
	if (n >= end - pos)
76
		return (ERANGE);
77
	r->h_name = pos;
78
	pos += n + 1;
79
80
	for (i = 0; i < naliases; i++) {
81
		n = strlcpy(pos, h->h_aliases[i], end - pos);
82
		if (n >= end - pos)
83
			return (ERANGE);
84
		r->h_aliases[i] = pos;
85
		pos += n + 1;
86
	}
87
88
	pos = (char *)ALIGN(pos);
89
	if (pos >= end)
90
		return (ERANGE);
91
92
	for (i = 0; i < naddrs; i++) {
93
		if (r->h_length > end - pos)
94
			return (ERANGE);
95
		memmove(pos, h->h_addr_list[i], r->h_length);
96
		r->h_addr_list[i] = pos;
97
		pos += r->h_length;
98
	}
99
100
	return (0);
101
}
102
103
static int
104
_gethostbyname(const char *name, int af, struct hostent *ret, char *buf,
105
    size_t buflen, int *h_errnop)
106
{
107
	struct asr_query *as;
108
	struct asr_result ar;
109
	int r;
110
111
	if (af == -1)
112
		as = gethostbyname_async(name, NULL);
113
	else
114
		as = gethostbyname2_async(name, af, NULL);
115
116
	if (as == NULL)
117
		return (errno);
118
119
	asr_run_sync(as, &ar);
120
121
	errno = ar.ar_errno;
122
	*h_errnop = ar.ar_h_errno;
123
	if (ar.ar_hostent == NULL)
124
		return (0);
125
126
	r = _fillhostent(ar.ar_hostent, ret, buf, buflen);
127
	free(ar.ar_hostent);
128
129
	return (r);
130
}
131
132
struct hostent *
133
gethostbyname(const char *name)
134
{
135
	struct hostent	*h;
136
137
	res_init();
138
139
	if (_res.options & RES_USE_INET6 &&
140
	    (h = gethostbyname2(name, AF_INET6)))
141
		return (h);
142
143
	return gethostbyname2(name, AF_INET);
144
}
145
DEF_WEAK(gethostbyname);
146
147
struct hostent *
148
gethostbyname2(const char *name, int af)
149
{
150
	int	r;
151
152
	res_init();
153
154
	r = _gethostbyname(name, af, &_hostent, _entbuf, sizeof(_entbuf),
155
	    &h_errno);
156
	if (r) {
157
		h_errno = NETDB_INTERNAL;
158
		errno = r;
159
	}
160
161
	if (h_errno)
162
		return (NULL);
163
164
	return (&_hostent);
165
}
166
DEF_WEAK(gethostbyname2);
167
168
struct hostent *
169
gethostbyaddr(const void *addr, socklen_t len, int af)
170
{
171
	struct asr_query *as;
172
	struct asr_result ar;
173
	int r;
174
175
	res_init();
176
177
	as = gethostbyaddr_async(addr, len, af, NULL);
178
	if (as == NULL) {
179
		h_errno = NETDB_INTERNAL;
180
		return (NULL);
181
	}
182
183
	asr_run_sync(as, &ar);
184
185
	errno = ar.ar_errno;
186
	h_errno = ar.ar_h_errno;
187
	if (ar.ar_hostent == NULL)
188
		return (NULL);
189
190
	r = _fillhostent(ar.ar_hostent, &_hostent, _entbuf, sizeof(_entbuf));
191
	free(ar.ar_hostent);
192
193
	if (r) {
194
		h_errno = NETDB_INTERNAL;
195
		errno = r;
196
		return (NULL);
197
	}
198
199
	return (&_hostent);
200
}