summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordownsj <>1997-03-13 19:07:41 +0000
committerdownsj <>1997-03-13 19:07:41 +0000
commit05882f672fb3bf8797e68cc2d68f8406e1cb7b07 (patch)
treef9cdfe48f1a2f821eb8d11d33976f3f19cd834db /src
parentb0e0ca363d82adf8768f67857659b9590e0e6954 (diff)
downloadopenbsd-05882f672fb3bf8797e68cc2d68f8406e1cb7b07.tar.gz
openbsd-05882f672fb3bf8797e68cc2d68f8406e1cb7b07.tar.bz2
openbsd-05882f672fb3bf8797e68cc2d68f8406e1cb7b07.zip
Integrate BIND 4.9.5 resolver and associated routines.
Includes the DNS aware getnetby*() routines and IPv6 support.
Diffstat (limited to 'src')
-rw-r--r--src/lib/libc/net/Makefile.inc15
-rw-r--r--src/lib/libc/net/base64.c319
-rw-r--r--src/lib/libc/net/gethostbyname.348
-rw-r--r--src/lib/libc/net/gethostnamadr.c775
-rw-r--r--src/lib/libc/net/getnetbyaddr.c6
-rw-r--r--src/lib/libc/net/getnetbyname.c4
-rw-r--r--src/lib/libc/net/getnetent.323
-rw-r--r--src/lib/libc/net/getnetnamadr.c291
-rw-r--r--src/lib/libc/net/herror.c26
-rw-r--r--src/lib/libc/net/inet_addr.c82
-rw-r--r--src/lib/libc/net/inet_net_ntop.c139
-rw-r--r--src/lib/libc/net/inet_net_pton.c207
-rw-r--r--src/lib/libc/net/inet_neta.c82
-rw-r--r--src/lib/libc/net/inet_ntop.c194
-rw-r--r--src/lib/libc/net/inet_pton.c220
-rw-r--r--src/lib/libc/net/nsap_addr.c55
-rw-r--r--src/lib/libc/net/res_comp.c174
-rw-r--r--src/lib/libc/net/res_data.c117
-rw-r--r--src/lib/libc/net/res_debug.c1055
-rw-r--r--src/lib/libc/net/res_init.c259
-rw-r--r--src/lib/libc/net/res_mkquery.c139
-rw-r--r--src/lib/libc/net/res_query.c116
-rw-r--r--src/lib/libc/net/res_send.c111
23 files changed, 3665 insertions, 792 deletions
diff --git a/src/lib/libc/net/Makefile.inc b/src/lib/libc/net/Makefile.inc
index 04831f4f2d..03f7349e5e 100644
--- a/src/lib/libc/net/Makefile.inc
+++ b/src/lib/libc/net/Makefile.inc
@@ -1,15 +1,16 @@
1# $OpenBSD: Makefile.inc,v 1.8 1996/09/01 21:25:34 millert Exp $ 1# $OpenBSD: Makefile.inc,v 1.9 1997/03/13 19:07:21 downsj Exp $
2 2
3# net sources 3# net sources
4.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/net ${.CURDIR}/net 4.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/net ${.CURDIR}/net
5 5
6SRCS+= gethostnamadr.c getnetbyaddr.c getnetbyname.c getnetent.c \ 6SRCS+= base64.c gethostnamadr.c getnetbyaddr.c getnetbyname.c getnetent.c \
7 getproto.c getprotoent.c getprotoname.c getservbyname.c \ 7 getnetnamadr.c getproto.c getprotoent.c getprotoname.c getservbyname.c \
8 getservbyport.c getservent.c herror.c inet_addr.c inet_lnaof.c \ 8 getservbyport.c getservent.c herror.c inet_addr.c inet_lnaof.c \
9 inet_makeaddr.c inet_netof.c inet_network.c inet_ntoa.c \ 9 inet_makeaddr.c inet_neta.c inet_netof.c inet_network.c \
10 ipx_addr.c ipx_ntoa.c \ 10 inet_net_ntop.c inet_net_pton.c inet_ntoa.c inet_ntop.c \
11 inet_pton.c ipx_addr.c ipx_ntoa.c \
11 iso_addr.c linkaddr.c ns_addr.c ns_ntoa.c nsap_addr.c rcmd.c recv.c \ 12 iso_addr.c linkaddr.c ns_addr.c ns_ntoa.c nsap_addr.c rcmd.c recv.c \
12 res_comp.c res_debug.c res_init.c res_mkquery.c res_query.c \ 13 res_comp.c res_data.c res_debug.c res_init.c res_mkquery.c res_query.c \
13 res_send.c send.c sethostent.c ethers.c rcmdsh.c 14 res_send.c send.c sethostent.c ethers.c rcmdsh.c
14 15
15# machine-dependent net sources 16# machine-dependent net sources
@@ -28,7 +29,7 @@ MLINKS+=ethers.3 ether_aton.3 ethers.3 ether_hostton.3 ethers.3 ether_line.3 \
28 ethers.3 ether_ntoa.3 ethers.3 ether_ntohost.3 29 ethers.3 ether_ntoa.3 ethers.3 ether_ntohost.3
29MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \ 30MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \
30 gethostbyname.3 sethostent.3 gethostbyname.3 gethostent.3 \ 31 gethostbyname.3 sethostent.3 gethostbyname.3 gethostent.3 \
31 gethostbyname.3 herror.3 32 gethostbyname.3 herror.3 gethostbyname.3 gethostbyname2.3
32MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \ 33MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \
33 getnetent.3 getnetbyname.3 getnetent.3 setnetent.3 34 getnetent.3 getnetbyname.3 getnetent.3 setnetent.3
34MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \ 35MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \
diff --git a/src/lib/libc/net/base64.c b/src/lib/libc/net/base64.c
new file mode 100644
index 0000000000..59788bee1b
--- /dev/null
+++ b/src/lib/libc/net/base64.c
@@ -0,0 +1,319 @@
1/* $OpenBSD: base64.c,v 1.1 1997/03/13 19:07:22 downsj Exp $ */
2
3/*
4 * Copyright (c) 1996 by Internet Software Consortium.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
12 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
13 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
16 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
17 * SOFTWARE.
18 */
19
20/*
21 * Portions Copyright (c) 1995 by International Business Machines, Inc.
22 *
23 * International Business Machines, Inc. (hereinafter called IBM) grants
24 * permission under its copyrights to use, copy, modify, and distribute this
25 * Software with or without fee, provided that the above copyright notice and
26 * all paragraphs of this notice appear in all copies, and that the name of IBM
27 * not be used in connection with the marketing of any product incorporating
28 * the Software or modifications thereof, without specific, written prior
29 * permission.
30 *
31 * To the extent it has a right to do so, IBM grants an immunity from suit
32 * under its patents, if any, for the use, sale or manufacture of products to
33 * the extent that such products are used for performing Domain Name System
34 * dynamic updates in TCP/IP networks by means of the Software. No immunity is
35 * granted for any product per se or for any other function of any product.
36 *
37 * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
38 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
39 * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
40 * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
41 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
42 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <sys/types.h>
46#include <sys/param.h>
47#include <sys/socket.h>
48#include <netinet/in.h>
49#include <arpa/inet.h>
50#include <arpa/nameser.h>
51
52#include <ctype.h>
53#include <resolv.h>
54#include <stdio.h>
55
56#include <stdlib.h>
57#include <string.h>
58
59#define Assert(Cond) if (!(Cond)) abort()
60
61static const char Base64[] =
62 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
63static const char Pad64 = '=';
64
65/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
66 The following encoding technique is taken from RFC 1521 by Borenstein
67 and Freed. It is reproduced here in a slightly edited form for
68 convenience.
69
70 A 65-character subset of US-ASCII is used, enabling 6 bits to be
71 represented per printable character. (The extra 65th character, "=",
72 is used to signify a special processing function.)
73
74 The encoding process represents 24-bit groups of input bits as output
75 strings of 4 encoded characters. Proceeding from left to right, a
76 24-bit input group is formed by concatenating 3 8-bit input groups.
77 These 24 bits are then treated as 4 concatenated 6-bit groups, each
78 of which is translated into a single digit in the base64 alphabet.
79
80 Each 6-bit group is used as an index into an array of 64 printable
81 characters. The character referenced by the index is placed in the
82 output string.
83
84 Table 1: The Base64 Alphabet
85
86 Value Encoding Value Encoding Value Encoding Value Encoding
87 0 A 17 R 34 i 51 z
88 1 B 18 S 35 j 52 0
89 2 C 19 T 36 k 53 1
90 3 D 20 U 37 l 54 2
91 4 E 21 V 38 m 55 3
92 5 F 22 W 39 n 56 4
93 6 G 23 X 40 o 57 5
94 7 H 24 Y 41 p 58 6
95 8 I 25 Z 42 q 59 7
96 9 J 26 a 43 r 60 8
97 10 K 27 b 44 s 61 9
98 11 L 28 c 45 t 62 +
99 12 M 29 d 46 u 63 /
100 13 N 30 e 47 v
101 14 O 31 f 48 w (pad) =
102 15 P 32 g 49 x
103 16 Q 33 h 50 y
104
105 Special processing is performed if fewer than 24 bits are available
106 at the end of the data being encoded. A full encoding quantum is
107 always completed at the end of a quantity. When fewer than 24 input
108 bits are available in an input group, zero bits are added (on the
109 right) to form an integral number of 6-bit groups. Padding at the
110 end of the data is performed using the '=' character.
111
112 Since all base64 input is an integral number of octets, only the
113 -------------------------------------------------
114 following cases can arise:
115
116 (1) the final quantum of encoding input is an integral
117 multiple of 24 bits; here, the final unit of encoded
118 output will be an integral multiple of 4 characters
119 with no "=" padding,
120 (2) the final quantum of encoding input is exactly 8 bits;
121 here, the final unit of encoded output will be two
122 characters followed by two "=" padding characters, or
123 (3) the final quantum of encoding input is exactly 16 bits;
124 here, the final unit of encoded output will be three
125 characters followed by one "=" padding character.
126 */
127
128int
129b64_ntop(src, srclength, target, targsize)
130 u_char const *src;
131 size_t srclength;
132 char *target;
133 size_t targsize;
134{
135 size_t datalength = 0;
136 u_char input[3];
137 u_char output[4];
138 int i;
139
140 while (2 < srclength) {
141 input[0] = *src++;
142 input[1] = *src++;
143 input[2] = *src++;
144 srclength -= 3;
145
146 output[0] = input[0] >> 2;
147 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
148 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
149 output[3] = input[2] & 0x3f;
150 Assert(output[0] < 64);
151 Assert(output[1] < 64);
152 Assert(output[2] < 64);
153 Assert(output[3] < 64);
154
155 if (datalength + 4 > targsize)
156 return (-1);
157 target[datalength++] = Base64[output[0]];
158 target[datalength++] = Base64[output[1]];
159 target[datalength++] = Base64[output[2]];
160 target[datalength++] = Base64[output[3]];
161 }
162
163 /* Now we worry about padding. */
164 if (0 != srclength) {
165 /* Get what's left. */
166 input[0] = input[1] = input[2] = '\0';
167 for (i = 0; i < srclength; i++)
168 input[i] = *src++;
169
170 output[0] = input[0] >> 2;
171 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
172 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
173 Assert(output[0] < 64);
174 Assert(output[1] < 64);
175 Assert(output[2] < 64);
176
177 if (datalength + 4 > targsize)
178 return (-1);
179 target[datalength++] = Base64[output[0]];
180 target[datalength++] = Base64[output[1]];
181 if (srclength == 1)
182 target[datalength++] = Pad64;
183 else
184 target[datalength++] = Base64[output[2]];
185 target[datalength++] = Pad64;
186 }
187 if (datalength >= targsize)
188 return (-1);
189 target[datalength] = '\0'; /* Returned value doesn't count \0. */
190 return (datalength);
191}
192
193/* skips all whitespace anywhere.
194 converts characters, four at a time, starting at (or after)
195 src from base - 64 numbers into three 8 bit bytes in the target area.
196 it returns the number of data bytes stored at the target, or -1 on error.
197 */
198
199int
200b64_pton(src, target, targsize)
201 char const *src;
202 u_char *target;
203 size_t targsize;
204{
205 int tarindex, state, ch;
206 char *pos;
207
208 state = 0;
209 tarindex = 0;
210
211 while ((ch = *src++) != '\0') {
212 if (isspace(ch)) /* Skip whitespace anywhere. */
213 continue;
214
215 if (ch == Pad64)
216 break;
217
218 pos = strchr(Base64, ch);
219 if (pos == 0) /* A non-base64 character. */
220 return (-1);
221
222 switch (state) {
223 case 0:
224 if (target) {
225 if (tarindex >= targsize)
226 return (-1);
227 target[tarindex] = (pos - Base64) << 2;
228 }
229 state = 1;
230 break;
231 case 1:
232 if (target) {
233 if (tarindex + 1 >= targsize)
234 return (-1);
235 target[tarindex] |= (pos - Base64) >> 4;
236 target[tarindex+1] = ((pos - Base64) & 0x0f)
237 << 4 ;
238 }
239 tarindex++;
240 state = 2;
241 break;
242 case 2:
243 if (target) {
244 if (tarindex + 1 >= targsize)
245 return (-1);
246 target[tarindex] |= (pos - Base64) >> 2;
247 target[tarindex+1] = ((pos - Base64) & 0x03)
248 << 6;
249 }
250 tarindex++;
251 state = 3;
252 break;
253 case 3:
254 if (target) {
255 if (tarindex >= targsize)
256 return (-1);
257 target[tarindex] |= (pos - Base64);
258 }
259 tarindex++;
260 state = 0;
261 break;
262 default:
263 abort();
264 }
265 }
266
267 /*
268 * We are done decoding Base-64 chars. Let's see if we ended
269 * on a byte boundary, and/or with erroneous trailing characters.
270 */
271
272 if (ch == Pad64) { /* We got a pad char. */
273 ch = *src++; /* Skip it, get next. */
274 switch (state) {
275 case 0: /* Invalid = in first position */
276 case 1: /* Invalid = in second position */
277 return (-1);
278
279 case 2: /* Valid, means one byte of info */
280 /* Skip any number of spaces. */
281 for (NULL; ch != '\0'; ch = *src++)
282 if (!isspace(ch))
283 break;
284 /* Make sure there is another trailing = sign. */
285 if (ch != Pad64)
286 return (-1);
287 ch = *src++; /* Skip the = */
288 /* Fall through to "single trailing =" case. */
289 /* FALLTHROUGH */
290
291 case 3: /* Valid, means two bytes of info */
292 /*
293 * We know this char is an =. Is there anything but
294 * whitespace after it?
295 */
296 for (NULL; ch != '\0'; ch = *src++)
297 if (!isspace(ch))
298 return (-1);
299
300 /*
301 * Now make sure for cases 2 and 3 that the "extra"
302 * bits that slopped past the last full byte were
303 * zeros. If we don't check them, they become a
304 * subliminal channel.
305 */
306 if (target && target[tarindex] != 0)
307 return (-1);
308 }
309 } else {
310 /*
311 * We ended by seeing the end of the string. Make sure we
312 * have no partial bytes lying around.
313 */
314 if (state != 0)
315 return (-1);
316 }
317
318 return (tarindex);
319}
diff --git a/src/lib/libc/net/gethostbyname.3 b/src/lib/libc/net/gethostbyname.3
index 8dfdb88cf0..1394fa3467 100644
--- a/src/lib/libc/net/gethostbyname.3
+++ b/src/lib/libc/net/gethostbyname.3
@@ -1,4 +1,4 @@
1.\" $OpenBSD: gethostbyname.3,v 1.3 1996/08/19 08:28:38 tholo Exp $ 1.\" $OpenBSD: gethostbyname.3,v 1.4 1997/03/13 19:07:23 downsj Exp $
2.\" 2.\"
3.\" Copyright (c) 1983, 1987, 1991, 1993 3.\" Copyright (c) 1983, 1987, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -31,11 +31,12 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 32.\" SUCH DAMAGE.
33.\" 33.\"
34.Dd April 19, 1994 34.Dd March 13, 1997
35.Dt GETHOSTBYNAME 3 35.Dt GETHOSTBYNAME 3
36.Os BSD 4.2 36.Os
37.Sh NAME 37.Sh NAME
38.Nm gethostbyname , 38.Nm gethostbyname ,
39.Nm gethostbyname2 ,
39.Nm gethostbyaddr , 40.Nm gethostbyaddr ,
40.Nm gethostent , 41.Nm gethostent ,
41.Nm sethostent , 42.Nm sethostent ,
@@ -48,6 +49,8 @@
48.Ft struct hostent * 49.Ft struct hostent *
49.Fn gethostbyname "const char *name" 50.Fn gethostbyname "const char *name"
50.Ft struct hostent * 51.Ft struct hostent *
52.Fn gethostbyname2 "const char *name" "int af"
53.Ft struct hostent *
51.Fn gethostbyaddr "const char *addr" "int len" "int type" 54.Fn gethostbyaddr "const char *addr" "int len" "int type"
52.Ft struct hostent * 55.Ft struct hostent *
53.Fn gethostent void 56.Fn gethostent void
@@ -93,8 +96,7 @@ Official name of the host.
93.It Fa h_aliases 96.It Fa h_aliases
94A zero terminated array of alternate names for the host. 97A zero terminated array of alternate names for the host.
95.It Fa h_addrtype 98.It Fa h_addrtype
96The type of address being returned; currently always 99The type of address being returned.
97.Dv AF_INET .
98.It Fa h_length 100.It Fa h_length
99The length, in bytes, of the address. 101The length, in bytes, of the address.
100.It Fa h_addr_list 102.It Fa h_addr_list
@@ -104,6 +106,7 @@ Host addresses are returned in network byte order.
104The first address in 106The first address in
105.Fa h_addr_list ; 107.Fa h_addr_list ;
106this is for backward compatibility. 108this is for backward compatibility.
109.El
107.Pp 110.Pp
108When using the nameserver, 111When using the nameserver,
109.Fn gethostbyname 112.Fn gethostbyname
@@ -117,6 +120,14 @@ See
117.Xr hostname 7 120.Xr hostname 7
118for the domain search procedure and the alias file format. 121for the domain search procedure and the alias file format.
119.Pp 122.Pp
123.Fn Gethostbyname2
124is an advanced form of
125.Fn gethostbyname
126which allows lookups in address families other than
127.Dv AF_INET ,
128for example
129.Dv AF_INET6 .
130.Pp
120The 131The
121.Fn sethostent 132.Fn sethostent
122function 133function
@@ -148,7 +159,8 @@ connection.
148.El 159.El
149.Sh DIAGNOSTICS 160.Sh DIAGNOSTICS
150Error return status from 161Error return status from
151.Fn gethostbyname 162.Fn gethostbyname ,
163.Fn gethostbyname2 ,
152and 164and
153.Fn gethostbyaddr 165.Fn gethostbyaddr
154is indicated by return of a null pointer. 166is indicated by return of a null pointer.
@@ -198,20 +210,6 @@ for example, a mail-forwarder may be registered for this domain.
198The 210The
199.Fn gethostent 211.Fn gethostent
200function 212function
201is defined, and
202.Fn sethostent
203and
204.Fn endhostent
205are redefined,
206when
207.Xr libc 3
208is built to use only the routines to lookup in
209.Pa /etc/hosts
210and not the name server.
211.Pp
212The
213.Fn gethostent
214function
215reads the next line of 213reads the next line of
216.Pa /etc/hosts , 214.Pa /etc/hosts ,
217opening the file if necessary. 215opening the file if necessary.
@@ -225,7 +223,8 @@ If the
225.Fa stayopen 223.Fa stayopen
226argument is non-zero, 224argument is non-zero,
227the file will not be closed after each call to 225the file will not be closed after each call to
228.Fn gethostbyname 226.Fn gethostbyname ,
227.Fn gethostbyname2 ,
229or 228or
230.Fn gethostbyaddr . 229.Fn gethostbyaddr .
231.Pp 230.Pp
@@ -252,4 +251,9 @@ These functions use static data storage;
252if the data is needed for future use, it should be 251if the data is needed for future use, it should be
253copied before any subsequent calls overwrite it. 252copied before any subsequent calls overwrite it.
254Only the Internet 253Only the Internet
255address format is currently understood. 254address formats are currently understood.
255.Pp
256YP does not support any address families other than
257.Dv AF_INET
258and uses
259the traditional database format.
diff --git a/src/lib/libc/net/gethostnamadr.c b/src/lib/libc/net/gethostnamadr.c
index 83e0225a65..9826b46805 100644
--- a/src/lib/libc/net/gethostnamadr.c
+++ b/src/lib/libc/net/gethostnamadr.c
@@ -52,7 +52,7 @@
52 */ 52 */
53 53
54#if defined(LIBC_SCCS) && !defined(lint) 54#if defined(LIBC_SCCS) && !defined(lint)
55static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.13 1997/01/30 05:56:06 deraadt Exp $"; 55static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.14 1997/03/13 19:07:24 downsj Exp $";
56#endif /* LIBC_SCCS and not lint */ 56#endif /* LIBC_SCCS and not lint */
57 57
58#include <sys/param.h> 58#include <sys/param.h>
@@ -66,6 +66,7 @@ static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.13 1997/01/30 05:56:06 dera
66#include <ctype.h> 66#include <ctype.h>
67#include <errno.h> 67#include <errno.h>
68#include <string.h> 68#include <string.h>
69#include <syslog.h>
69#ifdef YP 70#ifdef YP
70#include <rpc/rpc.h> 71#include <rpc/rpc.h>
71#include <rpcsvc/yp.h> 72#include <rpcsvc/yp.h>
@@ -73,6 +74,8 @@ static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.13 1997/01/30 05:56:06 dera
73#include "ypinternal.h" 74#include "ypinternal.h"
74#endif 75#endif
75 76
77#define MULTI_PTRS_ARE_ALIASES 1 /* XXX - experimental */
78
76#define MAXALIASES 35 79#define MAXALIASES 35
77#define MAXADDRS 35 80#define MAXADDRS 35
78 81
@@ -85,10 +88,22 @@ static char *__ypdomain;
85static struct hostent host; 88static struct hostent host;
86static char *host_aliases[MAXALIASES]; 89static char *host_aliases[MAXALIASES];
87static char hostbuf[BUFSIZ+1]; 90static char hostbuf[BUFSIZ+1];
88static struct in_addr host_addr; 91static u_char host_addr[16]; /* IPv4 or IPv6 */
89static FILE *hostf = NULL; 92static FILE *hostf = NULL;
90static int stayopen = 0; 93static int stayopen = 0;
91 94
95static void map_v4v6_address __P((const char *src, char *dst));
96static void map_v4v6_hostent __P((struct hostent *hp, char **bp, int *len));
97
98#ifdef RESOLVSORT
99static void addrsort __P((char **, int));
100#endif
101
102static int hokchar __P((const char *));
103
104static const char AskedForGot[] =
105 "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
106
92#if PACKETSZ > 1024 107#if PACKETSZ > 1024
93#define MAXPACKET PACKETSZ 108#define MAXPACKET PACKETSZ
94#else 109#else
@@ -105,15 +120,14 @@ typedef union {
105 char ac; 120 char ac;
106} align; 121} align;
107 122
108static int qcomp __P((struct in_addr **, struct in_addr **)); 123static struct hostent *getanswer __P((const querybuf *, int, const char *,
109static struct hostent *getanswer __P((querybuf *, int, int)); 124 int));
110static int hbadchar __P((char *));
111 125
112extern int h_errno; 126extern int h_errno;
113 127
114static int 128static int
115hbadchar(p) 129hokchar(p)
116 char *p; 130 const char *p;
117{ 131{
118 char c; 132 char c;
119 133
@@ -121,7 +135,7 @@ hbadchar(p)
121 * Many people do not obey RFC 822 and 1035. The valid 135 * Many people do not obey RFC 822 and 1035. The valid
122 * characters are a-z, A-Z, 0-9, '-' and . But the others 136 * characters are a-z, A-Z, 0-9, '-' and . But the others
123 * tested for below can happen, and we must be more permissive 137 * tested for below can happen, and we must be more permissive
124 * until those idiots clean up their act. 138 * than the resolver until those idiots clean up their act.
125 */ 139 */
126 while ((c = *p++)) { 140 while ((c = *p++)) {
127 if (('a' >= c && c <= 'z') || 141 if (('a' >= c && c <= 'z') ||
@@ -130,28 +144,50 @@ hbadchar(p)
130 continue; 144 continue;
131 if (strchr("-_/.[]\\", c) || 145 if (strchr("-_/.[]\\", c) ||
132 (c == '.' && p[1] == '.')) 146 (c == '.' && p[1] == '.'))
133 return 1; 147 return 0;
134 } 148 }
135 return 0; 149 return 1;
136} 150}
137 151
138static struct hostent * 152static struct hostent *
139getanswer(answer, anslen, iquery) 153getanswer(answer, anslen, qname, qtype)
140 querybuf *answer; 154 const querybuf *answer;
141 int anslen; 155 int anslen;
142 int iquery; 156 const char *qname;
157 int qtype;
143{ 158{
144 register HEADER *hp; 159 register const HEADER *hp;
145 register u_char *cp; 160 register const u_char *cp;
146 register int n; 161 register int n;
147 u_char *eom; 162 const u_char *eom;
148 char *bp, **ap; 163 char *bp, **ap, **hap;
149 int type, class, buflen, ancount, qdcount; 164 int type, class, buflen, ancount, qdcount;
150 int haveanswer, getclass = C_ANY; 165 int haveanswer, had_error;
151 char **hap; 166 int toobig = 0;
152 int good = 1; 167 char tbuf[MAXDNAME];
168 const char *tname;
169 int (*name_ok) __P((const char *));
153 170
171 tname = qname;
172 host.h_name = NULL;
154 eom = answer->buf + anslen; 173 eom = answer->buf + anslen;
174 switch (qtype) {
175 case T_A:
176 case T_AAAA:
177#ifdef USE_RESOLV_NAME_OK
178 name_ok = res_hnok;
179 break;
180#endif
181 case T_PTR:
182#ifdef USE_RESOLV_NAME_OK
183 name_ok = res_dnok;
184#else
185 name_ok = hokchar;
186#endif
187 break;
188 default:
189 return (NULL); /* XXX should be abort(); */
190 }
155 /* 191 /*
156 * find first satisfactory answer 192 * find first satisfactory answer
157 */ 193 */
@@ -159,34 +195,29 @@ getanswer(answer, anslen, iquery)
159 ancount = ntohs(hp->ancount); 195 ancount = ntohs(hp->ancount);
160 qdcount = ntohs(hp->qdcount); 196 qdcount = ntohs(hp->qdcount);
161 bp = hostbuf; 197 bp = hostbuf;
162 buflen = sizeof(hostbuf); 198 buflen = sizeof hostbuf;
163 cp = answer->buf + sizeof(HEADER); 199 cp = answer->buf + HFIXEDSZ;
164 if (qdcount) { 200 if (qdcount != 1) {
165 if (iquery) { 201 h_errno = NO_RECOVERY;
166 if ((n = dn_expand((u_char *)answer->buf, 202 return (NULL);
167 (u_char *)eom, (u_char *)cp, bp, 203 }
168 buflen)) < 0) { 204 n = dn_expand(answer->buf, eom, cp, bp, buflen);
169 h_errno = NO_RECOVERY; 205 if ((n < 0) || !(*name_ok)(bp)) {
170 return ((struct hostent *) NULL); 206 h_errno = NO_RECOVERY;
171 } 207 return (NULL);
172 cp += n + QFIXEDSZ; 208 }
173 host.h_name = bp; 209 cp += n + QFIXEDSZ;
174 n = strlen(bp); 210 if (qtype == T_A || qtype == T_AAAA) {
175 if (n >= MAXHOSTNAMELEN) 211 /* res_send() has already verified that the query name is the
176 host.h_name[MAXHOSTNAMELEN-1] = '\0'; 212 * same as the one we sent; this just gets the expanded name
177 n++; 213 * (i.e., with the succeeding search-domain tacked on).
178 bp += n; 214 */
179 buflen -= n; 215 n = strlen(bp) + 1; /* for the \0 */
180 } else 216 host.h_name = bp;
181 cp += __dn_skipname(cp, eom) + QFIXEDSZ; 217 bp += n;
182 while (--qdcount > 0) 218 buflen -= n;
183 cp += __dn_skipname(cp, eom) + QFIXEDSZ; 219 /* The qname can be abbreviated, but h_name is now absolute. */
184 } else if (iquery) { 220 qname = host.h_name;
185 if (hp->aa)
186 h_errno = HOST_NOT_FOUND;
187 else
188 h_errno = TRY_AGAIN;
189 return ((struct hostent *) NULL);
190 } 221 }
191 ap = host_aliases; 222 ap = host_aliases;
192 *ap = NULL; 223 *ap = NULL;
@@ -195,124 +226,258 @@ getanswer(answer, anslen, iquery)
195 *hap = NULL; 226 *hap = NULL;
196 host.h_addr_list = h_addr_ptrs; 227 host.h_addr_list = h_addr_ptrs;
197 haveanswer = 0; 228 haveanswer = 0;
198 if (ancount > MAXADDRS) 229 had_error = 0;
199 ancount = MAXADDRS; 230 while (ancount-- > 0 && cp < eom && !had_error) {
200 while (--ancount >= 0 && cp < eom) { 231 n = dn_expand(answer->buf, eom, cp, bp, buflen);
201 if ((n = dn_expand((u_char *)answer->buf, (u_char *)eom, 232 if ((n < 0) || !(*name_ok)(bp)) {
202 (u_char *)cp, bp, buflen)) < 0) 233 had_error++;
203 break; 234 continue;
204 cp += n; 235 }
236 cp += n; /* name */
205 type = _getshort(cp); 237 type = _getshort(cp);
206 cp += sizeof(u_int16_t); 238 cp += INT16SZ; /* type */
207 class = _getshort(cp); 239 class = _getshort(cp);
208 cp += sizeof(u_int16_t) + sizeof(u_int32_t); 240 cp += INT16SZ + INT32SZ; /* class, TTL */
209 n = _getshort(cp); 241 n = _getshort(cp);
210 cp += sizeof(u_int16_t); 242 cp += INT16SZ; /* len */
211 if (type == T_CNAME) { 243 if (class != C_IN) {
244 /* XXX - debug? syslog? */
212 cp += n; 245 cp += n;
246 continue; /* XXX - had_error++ ? */
247 }
248 if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
213 if (ap >= &host_aliases[MAXALIASES-1]) 249 if (ap >= &host_aliases[MAXALIASES-1])
214 continue; 250 continue;
251 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
252 if ((n < 0) || !(*name_ok)(tbuf)) {
253 had_error++;
254 continue;
255 }
256 cp += n;
257 /* Store alias. */
215 *ap++ = bp; 258 *ap++ = bp;
216 n = strlen(bp) + 1; 259 n = strlen(bp) + 1; /* for the \0 */
217 if (n > MAXHOSTNAMELEN) 260 bp += n;
218 bp[MAXHOSTNAMELEN-1] = '\0'; 261 buflen -= n;
262 /* Get canonical name. */
263 n = strlen(tbuf) + 1; /* for the \0 */
264 if (n > buflen) {
265 had_error++;
266 continue;
267 }
268 strcpy(bp, tbuf);
269 host.h_name = bp;
219 bp += n; 270 bp += n;
220 buflen -= n; 271 buflen -= n;
221 continue; 272 continue;
222 } 273 }
223 if (iquery && type == T_PTR) { 274 if (qtype == T_PTR && type == T_CNAME) {
224 if ((n = dn_expand((u_char *)answer->buf, 275 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
225 (u_char *)eom, (u_char *)cp, bp, 276 if ((n < 0) || !res_hnok(tbuf)) {
226 buflen)) < 0) 277 had_error++;
227 break; 278 continue;
279 }
228 cp += n; 280 cp += n;
229 host.h_name = bp; 281 /* Get canonical name. */
230 n = strlen(host.h_name); 282 n = strlen(tbuf) + 1; /* for the \0 */
231 if (n >= MAXHOSTNAMELEN) 283 if (n > buflen) {
232 host.h_name[MAXHOSTNAMELEN-1] = '\0'; 284 had_error++;
233 goto gotent; 285 continue;
286 }
287 strcpy(bp, tbuf);
288 tname = bp;
289 bp += n;
290 buflen -= n;
291 continue;
234 } 292 }
235 if (iquery || type != T_A) { 293 if (type != qtype) {
236#ifdef DEBUG 294 syslog(LOG_NOTICE|LOG_AUTH,
237 if (_res.options & RES_DEBUG) 295 "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
238 printf("unexpected answer type %d, size %d\n", 296 qname, p_class(C_IN), p_type(qtype),
239 type, n); 297 p_type(type));
240#endif
241 cp += n; 298 cp += n;
242 continue; 299 continue; /* XXX - had_error++ ? */
243 } 300 }
244 301 switch (type) {
245 if (haveanswer) { 302 case T_PTR:
246 if (n != host.h_length) { 303 if (strcasecmp(tname, bp) != 0) {
304 syslog(LOG_NOTICE|LOG_AUTH,
305 AskedForGot, qname, bp);
247 cp += n; 306 cp += n;
248 continue; 307 continue; /* XXX - had_error++ ? */
249 } 308 }
250 if (class != getclass) { 309 n = dn_expand(answer->buf, eom, cp, bp, buflen);
310 if ((n < 0) || !res_hnok(bp)) {
311 had_error++;
312 break;
313 }
314#if MULTI_PTRS_ARE_ALIASES
315 cp += n;
316 if (!haveanswer)
317 host.h_name = bp;
318 else if (ap < &host_aliases[MAXALIASES-1])
319 *ap++ = bp;
320 else
321 n = -1;
322 if (n != -1) {
323 n = strlen(bp) + 1; /* for the \0 */
324 bp += n;
325 buflen -= n;
326 }
327 break;
328#else
329 host.h_name = bp;
330 if (_res.options & RES_USE_INET6) {
331 n = strlen(bp) + 1; /* for the \0 */
332 bp += n;
333 buflen -= n;
334 map_v4v6_hostent(&host, &bp, &buflen);
335 }
336 h_errno = NETDB_SUCCESS;
337 return (&host);
338#endif
339 case T_A:
340 case T_AAAA:
341 if (strcasecmp(host.h_name, bp) != 0) {
342 syslog(LOG_NOTICE|LOG_AUTH,
343 AskedForGot, host.h_name, bp);
344 cp += n;
345 continue; /* XXX - had_error++ ? */
346 }
347 if (n != host.h_length) {
251 cp += n; 348 cp += n;
252 continue; 349 continue;
253 } 350 }
254 } else { 351 if (!haveanswer) {
255 host.h_length = n; 352 register int nn;
256 getclass = class; 353
257 host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
258 if (host.h_addrtype == AF_INET)
259 host.h_length = INADDRSZ;
260 if (!iquery) {
261 host.h_name = bp; 354 host.h_name = bp;
262 bp += strlen(bp) + 1; 355 nn = strlen(bp) + 1; /* for the \0 */
263 if (strlen(host.h_name) >= MAXHOSTNAMELEN) 356 bp += nn;
264 host.h_name[MAXHOSTNAMELEN-1] = '\0'; 357 buflen -= nn;
265 } 358 }
266 }
267 359
268 bp += sizeof(align) - ((u_long)bp % sizeof(align)); 360 bp += sizeof(align) - ((u_long)bp % sizeof(align));
269 361
270 if (bp + n >= &hostbuf[sizeof(hostbuf)]) { 362 if (bp + n >= &hostbuf[sizeof hostbuf]) {
363#ifdef DEBUG
364 if (_res.options & RES_DEBUG)
365 printf("size (%d) too big\n", n);
366#endif
367 had_error++;
368 continue;
369 }
370 if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
371 if (!toobig++)
271#ifdef DEBUG 372#ifdef DEBUG
272 if (_res.options & RES_DEBUG) 373 if (_res.options & RES_DEBUG)
273 printf("size (%d) too big\n", n); 374 printf("Too many addresses (%d)\n", MAXADDRS);
274#endif 375#endif
376 cp += n;
377 continue;
378 }
379 bcopy(cp, *hap++ = bp, n);
380 bp += n;
381 buflen -= n;
382 cp += n;
275 break; 383 break;
384 default:
385 abort();
276 } 386 }
277 bcopy(cp, *hap++ = bp, n); 387 if (!had_error)
278 bp +=n; 388 haveanswer++;
279 cp += n;
280 haveanswer++;
281 }
282 if (!haveanswer) {
283 h_errno = TRY_AGAIN;
284 return ((struct hostent *) NULL);
285 }
286 *ap = NULL;
287 *hap = NULL;
288 if (_res.nsort) {
289 qsort(host.h_addr_list, haveanswer,
290 sizeof(struct in_addr),
291 (int (*)__P((const void *, const void *)))qcomp);
292 } 389 }
293gotent: 390 if (haveanswer) {
294 if (hbadchar(host.h_name)) 391 *ap = NULL;
295 good = 0; 392 *hap = NULL;
296 for (ap = host_aliases; good && *ap; ap++) 393# if defined(RESOLVSORT)
297 if (hbadchar(*ap)) 394 /*
298 good = 0; 395 * Note: we sort even if host can take only one address
299 if (good) 396 * in its return structures - should give it the "best"
397 * address in that case, not some random one
398 */
399 if (_res.nsort && haveanswer > 1 && qtype == T_A)
400 addrsort(h_addr_ptrs, haveanswer);
401# endif /*RESOLVSORT*/
402 if (!host.h_name) {
403 n = strlen(qname) + 1; /* for the \0 */
404 if (n > buflen)
405 goto try_again;
406 strcpy(bp, qname);
407 host.h_name = bp;
408 bp += n;
409 buflen -= n;
410 }
411 if (_res.options & RES_USE_INET6)
412 map_v4v6_hostent(&host, &bp, &buflen);
413 h_errno = NETDB_SUCCESS;
300 return (&host); 414 return (&host);
301 h_errno = NO_RECOVERY; 415 }
302 return ((struct hostent *) NULL); 416 try_again:
417 h_errno = TRY_AGAIN;
418 return (NULL);
303} 419}
304 420
305struct hostent * 421struct hostent *
306gethostbyname(name) 422gethostbyname(name)
307 const char *name; 423 const char *name;
308{ 424{
425 struct hostent *hp;
426 extern struct hostent *_gethtbyname2();
427
428 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
429 return (_gethtbyname2(name, AF_INET));
430
431 if (_res.options & RES_USE_INET6) {
432 hp = gethostbyname2(name, AF_INET6);
433 if (hp)
434 return (hp);
435 }
436 return (gethostbyname2(name, AF_INET));
437}
438
439struct hostent *
440gethostbyname2(name, af)
441 const char *name;
442 int af;
443{
309 querybuf buf; 444 querybuf buf;
310 register const char *cp; 445 register const char *cp;
311 int n, i; 446 char *bp;
312 extern struct hostent *_gethtbyname(), *_yp_gethtbyname(); 447 int n, size, type, len, i;
448 extern struct hostent *_gethtbyname2(), *_yp_gethtbyname();
313 register struct hostent *hp; 449 register struct hostent *hp;
314 char lookups[MAXDNSLUS]; 450 char lookups[MAXDNSLUS];
315 451
452 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
453 return (_gethtbyname2(name, af));
454
455 switch (af) {
456 case AF_INET:
457 size = INADDRSZ;
458 type = T_A;
459 break;
460 case AF_INET6:
461 size = IN6ADDRSZ;
462 type = T_AAAA;
463 break;
464 default:
465 h_errno = NETDB_INTERNAL;
466 errno = EAFNOSUPPORT;
467 return (NULL);
468 }
469
470 host.h_addrtype = af;
471 host.h_length = size;
472
473 /*
474 * if there aren't any dots, it could be a user-level alias.
475 * this is also done in res_query() since we are not the only
476 * function that looks up host names.
477 */
478 if (!strchr(name, '.') && (cp = __hostalias(name)))
479 name = cp;
480
316 /* 481 /*
317 * disallow names consisting only of digits/dots, unless 482 * disallow names consisting only of digits/dots, unless
318 * they end in a dot. 483 * they end in a dot.
@@ -327,26 +492,58 @@ gethostbyname(name)
327 * Fake up a hostent as if we'd actually 492 * Fake up a hostent as if we'd actually
328 * done a lookup. 493 * done a lookup.
329 */ 494 */
330 if (!inet_aton(name, &host_addr)) { 495 if (inet_pton(af, name, host_addr) <= 0) {
331 h_errno = HOST_NOT_FOUND; 496 h_errno = HOST_NOT_FOUND;
332 return((struct hostent *) NULL); 497 return (NULL);
333 } 498 }
334 host.h_name = (char *)name; 499 strncpy(hostbuf, name, MAXDNAME);
500 hostbuf[MAXDNAME] = '\0';
501 bp = hostbuf + MAXDNAME;
502 len = sizeof hostbuf - MAXDNAME;
503 host.h_name = hostbuf;
335 host.h_aliases = host_aliases; 504 host.h_aliases = host_aliases;
336 host_aliases[0] = NULL; 505 host_aliases[0] = NULL;
337 host.h_addrtype = AF_INET; 506 h_addr_ptrs[0] = (char *)host_addr;
338 host.h_length = sizeof(u_int32_t);
339 h_addr_ptrs[0] = (char *)&host_addr;
340 h_addr_ptrs[1] = NULL; 507 h_addr_ptrs[1] = NULL;
341 host.h_addr_list = h_addr_ptrs; 508 host.h_addr_list = h_addr_ptrs;
509 if (_res.options & RES_USE_INET6)
510 map_v4v6_hostent(&host, &bp, &len);
511 h_errno = NETDB_SUCCESS;
342 return (&host); 512 return (&host);
343 } 513 }
344 if (!isdigit(*cp) && *cp != '.') 514 if (!isdigit(*cp) && *cp != '.')
345 break; 515 break;
346 } 516 }
347 517 if (isxdigit(name[0]) || name[0] == ':')
348 if ((_res.options & RES_INIT) == 0 && res_init() == -1) 518 for (cp = name;; ++cp) {
349 return (_gethtbyname(name)); 519 if (!*cp) {
520 if (*--cp == '.')
521 break;
522 /*
523 * All-IPv6-legal, no dot at the end.
524 * Fake up a hostent as if we'd actually
525 * done a lookup.
526 */
527 if (inet_pton(af, name, host_addr) <= 0) {
528 h_errno = HOST_NOT_FOUND;
529 return (NULL);
530 }
531 strncpy(hostbuf, name, MAXDNAME);
532 hostbuf[MAXDNAME] = '\0';
533 bp = hostbuf + MAXDNAME;
534 len = sizeof hostbuf - MAXDNAME;
535 host.h_name = hostbuf;
536 host.h_aliases = host_aliases;
537 host_aliases[0] = NULL;
538 h_addr_ptrs[0] = (char *)host_addr;
539 h_addr_ptrs[1] = NULL;
540 host.h_addr_list = h_addr_ptrs;
541 h_errno = NETDB_SUCCESS;
542 return (&host);
543 }
544 if (!isxdigit(*cp) && *cp != ':' && *cp != '.')
545 break;
546 }
350 547
351 bcopy(_res.lookups, lookups, sizeof lookups); 548 bcopy(_res.lookups, lookups, sizeof lookups);
352 if (lookups[0] == '\0') 549 if (lookups[0] == '\0')
@@ -357,11 +554,13 @@ gethostbyname(name)
357 switch (lookups[i]) { 554 switch (lookups[i]) {
358#ifdef YP 555#ifdef YP
359 case 'y': 556 case 'y':
360 hp = _yp_gethtbyname(name); 557 /* YP only suports AF_INET. */
558 if (af == AF_INET)
559 hp = _yp_gethtbyname(name);
361 break; 560 break;
362#endif 561#endif
363 case 'b': 562 case 'b':
364 if ((n = res_search(name, C_IN, T_A, buf.buf, 563 if ((n = res_search(name, C_IN, type, buf.buf,
365 sizeof(buf))) < 0) { 564 sizeof(buf))) < 0) {
366#ifdef DEBUG 565#ifdef DEBUG
367 if (_res.options & RES_DEBUG) 566 if (_res.options & RES_DEBUG)
@@ -369,10 +568,10 @@ gethostbyname(name)
369#endif 568#endif
370 break; 569 break;
371 } 570 }
372 hp = getanswer(&buf, n, 0); 571 hp = getanswer(&buf, n, name, type);
373 break; 572 break;
374 case 'f': 573 case 'f':
375 hp = _gethtbyname(name); 574 hp = _gethtbyname2(name, af);
376 break; 575 break;
377 } 576 }
378 } 577 }
@@ -380,27 +579,69 @@ gethostbyname(name)
380} 579}
381 580
382struct hostent * 581struct hostent *
383gethostbyaddr(addr, len, type) 582gethostbyaddr(addr, len, af)
384 const char *addr; 583 const char *addr; /* XXX should have been def'd as u_char! */
385 int len, type; 584 int len, af;
386{ 585{
387 int n, i; 586 const u_char *uaddr = (const u_char *)addr;
587 static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
588 static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
589 int n, size, i;
388 querybuf buf; 590 querybuf buf;
389 register struct hostent *hp; 591 register struct hostent *hp;
390 char qbuf[MAXDNAME]; 592 char qbuf[MAXDNAME+1], *qp;
391 extern struct hostent *_gethtbyaddr(), *_yp_gethtbyaddr(); 593 extern struct hostent *_gethtbyaddr(), *_yp_gethtbyaddr();
392 char lookups[MAXDNSLUS]; 594 char lookups[MAXDNSLUS];
393 595
394 if (type != AF_INET)
395 return ((struct hostent *) NULL);
396 (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
397 ((unsigned)addr[3] & 0xff),
398 ((unsigned)addr[2] & 0xff),
399 ((unsigned)addr[1] & 0xff),
400 ((unsigned)addr[0] & 0xff));
401
402 if ((_res.options & RES_INIT) == 0 && res_init() == -1) 596 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
403 return (_gethtbyaddr(addr, len, type)); 597 return (_gethtbyaddr(addr, len, af));
598
599 if (af == AF_INET6 && len == IN6ADDRSZ &&
600 (!bcmp(uaddr, mapped, sizeof mapped) ||
601 !bcmp(uaddr, tunnelled, sizeof tunnelled))) {
602 /* Unmap. */
603 addr += sizeof mapped;
604 uaddr += sizeof mapped;
605 af = AF_INET;
606 len = INADDRSZ;
607 }
608 switch (af) {
609 case AF_INET:
610 size = INADDRSZ;
611 break;
612 case AF_INET6:
613 size = IN6ADDRSZ;
614 break;
615 default:
616 errno = EAFNOSUPPORT;
617 h_errno = NETDB_INTERNAL;
618 return (NULL);
619 }
620 if (size != len) {
621 errno = EINVAL;
622 h_errno = NETDB_INTERNAL;
623 return (NULL);
624 }
625 switch (af) {
626 case AF_INET:
627 (void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
628 (uaddr[3] & 0xff),
629 (uaddr[2] & 0xff),
630 (uaddr[1] & 0xff),
631 (uaddr[0] & 0xff));
632 break;
633 case AF_INET6:
634 qp = qbuf;
635 for (n = IN6ADDRSZ - 1; n >= 0; n--) {
636 qp += sprintf(qp, "%x.%x.",
637 uaddr[n] & 0xf,
638 (uaddr[n] >> 4) & 0xf);
639 }
640 strcpy(qp, "ip6.int");
641 break;
642 default:
643 abort();
644 }
404 645
405 bcopy(_res.lookups, lookups, sizeof lookups); 646 bcopy(_res.lookups, lookups, sizeof lookups);
406 if (lookups[0] == '\0') 647 if (lookups[0] == '\0')
@@ -411,29 +652,38 @@ gethostbyaddr(addr, len, type)
411 switch (lookups[i]) { 652 switch (lookups[i]) {
412#ifdef YP 653#ifdef YP
413 case 'y': 654 case 'y':
414 hp = _yp_gethtbyaddr(addr); 655 /* YP only supports AF_INET. */
656 if (af == AF_INET)
657 hp = _yp_gethtbyaddr(addr);
415 break; 658 break;
416#endif 659#endif
417 case 'b': 660 case 'b':
418 n = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf)); 661 n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf,
662 sizeof buf.buf);
419 if (n < 0) { 663 if (n < 0) {
420#ifdef DEBUG 664#ifdef DEBUG
421 if (_res.options & RES_DEBUG) 665 if (_res.options & RES_DEBUG)
422 printf("res_query failed\n"); 666 printf("res_query failed\n");
423#endif 667#endif
424 break; 668 return (NULL);
425 } 669 }
426 hp = getanswer(&buf, n, 1); 670 if (!(hp = getanswer(&buf, n, qbuf, T_PTR)))
427 if (hp == NULL) 671 return (NULL); /* h_errno was set by getanswer() */
428 break; 672 hp->h_addrtype = af;
429 hp->h_addrtype = type;
430 hp->h_length = len; 673 hp->h_length = len;
431 h_addr_ptrs[0] = (char *)&host_addr; 674 bcopy(addr, host_addr, len);
432 h_addr_ptrs[1] = (char *)0; 675 h_addr_ptrs[0] = (char *)host_addr;
433 host_addr = *(struct in_addr *)addr; 676 h_addr_ptrs[1] = NULL;
677 if (af == AF_INET && (_res.options & RES_USE_INET6)) {
678 map_v4v6_address((char*)host_addr,
679 (char*)host_addr);
680 hp->h_addrtype = AF_INET6;
681 hp->h_length = IN6ADDRSZ;
682 }
683 h_errno = NETDB_SUCCESS;
434 break; 684 break;
435 case 'f': 685 case 'f':
436 hp = _gethtbyaddr(addr, len, type); 686 hp = _gethtbyaddr(addr, len, af);
437 break; 687 break;
438 } 688 }
439 } 689 }
@@ -465,35 +715,51 @@ _gethtent()
465{ 715{
466 char *p; 716 char *p;
467 register char *cp, **q; 717 register char *cp, **q;
718 int af, len;
468 719
469 if (hostf == NULL && (hostf = fopen(_PATH_HOSTS, "r" )) == NULL) 720 if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) {
721 h_errno = NETDB_INTERNAL;
470 return (NULL); 722 return (NULL);
471again: 723 }
472 if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL) 724 again:
725 if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) {
726 h_errno = HOST_NOT_FOUND;
473 return (NULL); 727 return (NULL);
728 }
474 if (*p == '#') 729 if (*p == '#')
475 goto again; 730 goto again;
476 cp = strpbrk(p, "#\n"); 731 if (!(cp = strpbrk(p, "#\n")))
477 if (cp == NULL)
478 goto again; 732 goto again;
479 *cp = '\0'; 733 *cp = '\0';
480 cp = strpbrk(p, " \t"); 734 if (!(cp = strpbrk(p, " \t")))
481 if (cp == NULL)
482 goto again; 735 goto again;
483 *cp++ = '\0'; 736 *cp++ = '\0';
484 /* THIS STUFF IS INTERNET SPECIFIC */ 737 if ((_res.options & RES_USE_INET6) &&
485 h_addr_ptrs[0] = (char *)&host_addr; 738 inet_pton(AF_INET6, p, host_addr) > 0) {
739 af = AF_INET6;
740 len = IN6ADDRSZ;
741 } else if (inet_pton(AF_INET, p, host_addr) > 0) {
742 if (_res.options & RES_USE_INET6) {
743 map_v4v6_address((char*)host_addr, (char*)host_addr);
744 af = AF_INET6;
745 len = IN6ADDRSZ;
746 } else {
747 af = AF_INET;
748 len = INADDRSZ;
749 }
750 } else {
751 goto again;
752 }
753 h_addr_ptrs[0] = (char *)host_addr;
486 h_addr_ptrs[1] = NULL; 754 h_addr_ptrs[1] = NULL;
487 (void) inet_aton(p, &host_addr);
488 host.h_addr_list = h_addr_ptrs; 755 host.h_addr_list = h_addr_ptrs;
489 host.h_length = sizeof(u_int32_t); 756 host.h_length = len;
490 host.h_addrtype = AF_INET; 757 host.h_addrtype = af;
491 while (*cp == ' ' || *cp == '\t') 758 while (*cp == ' ' || *cp == '\t')
492 cp++; 759 cp++;
493 host.h_name = cp; 760 host.h_name = cp;
494 q = host.h_aliases = host_aliases; 761 q = host.h_aliases = host_aliases;
495 cp = strpbrk(cp, " \t"); 762 if (cp = strpbrk(cp, " \t"))
496 if (cp != NULL)
497 *cp++ = '\0'; 763 *cp++ = '\0';
498 while (cp && *cp) { 764 while (cp && *cp) {
499 if (*cp == ' ' || *cp == '\t') { 765 if (*cp == ' ' || *cp == '\t') {
@@ -502,11 +768,17 @@ again:
502 } 768 }
503 if (q < &host_aliases[MAXALIASES - 1]) 769 if (q < &host_aliases[MAXALIASES - 1])
504 *q++ = cp; 770 *q++ = cp;
505 cp = strpbrk(cp, " \t"); 771 if (cp = strpbrk(cp, " \t"))
506 if (cp != NULL)
507 *cp++ = '\0'; 772 *cp++ = '\0';
508 } 773 }
509 *q = NULL; 774 *q = NULL;
775 if (_res.options & RES_USE_INET6) {
776 char *bp = hostbuf;
777 int buflen = sizeof hostbuf;
778
779 map_v4v6_hostent(&host, &bp, &buflen);
780 }
781 h_errno = NETDB_SUCCESS;
510 return (&host); 782 return (&host);
511} 783}
512 784
@@ -514,58 +786,55 @@ struct hostent *
514_gethtbyname(name) 786_gethtbyname(name)
515 const char *name; 787 const char *name;
516{ 788{
789 extern struct hostent *_gethtbyname2();
790 struct hostent *hp;
791
792 if (_res.options & RES_USE_INET6) {
793 hp = _gethtbyname2(name, AF_INET6);
794 if (hp)
795 return (hp);
796 }
797 return (_gethtbyname2(name, AF_INET));
798}
799
800struct hostent *
801_gethtbyname2(name, af)
802 const char *name;
803 int af;
804{
517 register struct hostent *p; 805 register struct hostent *p;
518 register char **cp; 806 register char **cp;
519 807
520 _sethtent(0); 808 _sethtent(0);
521 while (p = _gethtent()) { 809 while (p = _gethtent()) {
810 if (p->h_addrtype != af)
811 continue;
522 if (strcasecmp(p->h_name, name) == 0) 812 if (strcasecmp(p->h_name, name) == 0)
523 break; 813 break;
524 for (cp = p->h_aliases; *cp != 0; cp++) 814 for (cp = p->h_aliases; *cp != 0; cp++)
525 if (strcasecmp(*cp, name) == 0) 815 if (strcasecmp(*cp, name) == 0)
526 goto found; 816 goto found;
527 } 817 }
528found: 818 found:
529 _endhtent(); 819 _endhtent();
530 if (p==NULL)
531 h_errno = HOST_NOT_FOUND;
532 return (p); 820 return (p);
533} 821}
534 822
535struct hostent * 823struct hostent *
536_gethtbyaddr(addr, len, type) 824_gethtbyaddr(addr, len, af)
537 const char *addr; 825 const char *addr;
538 int len, type; 826 int len, af;
539{ 827{
540 register struct hostent *p; 828 register struct hostent *p;
541 829
542 _sethtent(0); 830 _sethtent(0);
543 while (p = _gethtent()) 831 while (p = _gethtent())
544 if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len)) 832 if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len))
545 break; 833 break;
546 _endhtent(); 834 _endhtent();
547 if (p==NULL)
548 h_errno = HOST_NOT_FOUND;
549 return (p); 835 return (p);
550} 836}
551 837
552static int
553qcomp(a1, a2)
554 struct in_addr **a1, **a2;
555{
556 int pos1, pos2;
557
558 for (pos1 = 0; pos1 < _res.nsort; pos1++)
559 if (_res.sort_list[pos1].addr.s_addr ==
560 ((*a1)->s_addr & _res.sort_list[pos1].mask))
561 break;
562 for (pos2 = 0; pos2 < _res.nsort; pos2++)
563 if (_res.sort_list[pos2].addr.s_addr ==
564 ((*a2)->s_addr & _res.sort_list[pos2].mask))
565 break;
566 return pos1 - pos2;
567}
568
569#ifdef YP 838#ifdef YP
570struct hostent * 839struct hostent *
571_yphostent(line) 840_yphostent(line)
@@ -687,10 +956,104 @@ _yp_gethtbyname(name)
687 __ypcurrent = NULL; 956 __ypcurrent = NULL;
688 r = yp_match(__ypdomain, "hosts.byname", name, 957 r = yp_match(__ypdomain, "hosts.byname", name,
689 strlen(name), &__ypcurrent, &__ypcurrentlen); 958 strlen(name), &__ypcurrent, &__ypcurrentlen);
690 if (r==0) 959 if (r == 0)
691 hp = _yphostent(__ypcurrent); 960 hp = _yphostent(__ypcurrent);
692 if (hp==NULL) 961 if (hp == NULL)
693 h_errno = HOST_NOT_FOUND; 962 h_errno = HOST_NOT_FOUND;
694 return (hp); 963 return (hp);
695} 964}
696#endif 965#endif
966
967static void
968map_v4v6_address(src, dst)
969 const char *src;
970 char *dst;
971{
972 u_char *p = (u_char *)dst;
973 char tmp[INADDRSZ];
974 int i;
975
976 /* Stash a temporary copy so our caller can update in place. */
977 bcopy(src, tmp, INADDRSZ);
978 /* Mark this ipv6 addr as a mapped ipv4. */
979 for (i = 0; i < 10; i++)
980 *p++ = 0x00;
981 *p++ = 0xff;
982 *p++ = 0xff;
983 /* Retrieve the saved copy and we're done. */
984 bcopy(tmp, (void*)p, INADDRSZ);
985}
986
987static void
988map_v4v6_hostent(hp, bpp, lenp)
989 struct hostent *hp;
990 char **bpp;
991 int *lenp;
992{
993 char **ap;
994
995 if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ)
996 return;
997 hp->h_addrtype = AF_INET6;
998 hp->h_length = IN6ADDRSZ;
999 for (ap = hp->h_addr_list; *ap; ap++) {
1000 int i = sizeof(align) - ((u_long)*bpp % sizeof(align));
1001
1002 if (*lenp < (i + IN6ADDRSZ)) {
1003 /* Out of memory. Truncate address list here. XXX */
1004 *ap = NULL;
1005 return;
1006 }
1007 *bpp += i;
1008 *lenp -= i;
1009 map_v4v6_address(*ap, *bpp);
1010 *ap = *bpp;
1011 *bpp += IN6ADDRSZ;
1012 *lenp -= IN6ADDRSZ;
1013 }
1014}
1015
1016#ifdef RESOLVSORT
1017static void
1018addrsort(ap, num)
1019 char **ap;
1020 int num;
1021{
1022 int i, j;
1023 char **p;
1024 short aval[MAXADDRS];
1025 int needsort = 0;
1026
1027 p = ap;
1028 for (i = 0; i < num; i++, p++) {
1029 for (j = 0 ; (unsigned)j < _res.nsort; j++)
1030 if (_res.sort_list[j].addr.s_addr ==
1031 (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
1032 break;
1033 aval[i] = j;
1034 if (needsort == 0 && i > 0 && j < aval[i-1])
1035 needsort = i;
1036 }
1037 if (!needsort)
1038 return;
1039
1040 while (needsort < num) {
1041 for (j = needsort - 1; j >= 0; j--) {
1042 if (aval[j] > aval[j+1]) {
1043 char *hp;
1044
1045 i = aval[j];
1046 aval[j] = aval[j+1];
1047 aval[j+1] = i;
1048
1049 hp = ap[j];
1050 ap[j] = ap[j+1];
1051 ap[j+1] = hp;
1052
1053 } else
1054 break;
1055 }
1056 needsort++;
1057 }
1058}
1059#endif
diff --git a/src/lib/libc/net/getnetbyaddr.c b/src/lib/libc/net/getnetbyaddr.c
index aabd741a88..3d2b6e0352 100644
--- a/src/lib/libc/net/getnetbyaddr.c
+++ b/src/lib/libc/net/getnetbyaddr.c
@@ -32,7 +32,7 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: getnetbyaddr.c,v 1.2 1996/08/19 08:28:42 tholo Exp $"; 35static char rcsid[] = "$OpenBSD: getnetbyaddr.c,v 1.3 1997/03/13 19:07:25 downsj Exp $";
36#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
37 37
38#include <netdb.h> 38#include <netdb.h>
@@ -40,8 +40,8 @@ static char rcsid[] = "$OpenBSD: getnetbyaddr.c,v 1.2 1996/08/19 08:28:42 tholo
40extern int _net_stayopen; 40extern int _net_stayopen;
41 41
42struct netent * 42struct netent *
43getnetbyaddr(net, type) 43_getnetbyaddr(net, type)
44 register long net; 44 register unsigned long net;
45 register int type; 45 register int type;
46{ 46{
47 register struct netent *p; 47 register struct netent *p;
diff --git a/src/lib/libc/net/getnetbyname.c b/src/lib/libc/net/getnetbyname.c
index d2a5b8679a..764c78b361 100644
--- a/src/lib/libc/net/getnetbyname.c
+++ b/src/lib/libc/net/getnetbyname.c
@@ -32,7 +32,7 @@
32 */ 32 */
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: getnetbyname.c,v 1.3 1996/08/19 08:28:44 tholo Exp $"; 35static char rcsid[] = "$OpenBSD: getnetbyname.c,v 1.4 1997/03/13 19:07:26 downsj Exp $";
36#endif /* LIBC_SCCS and not lint */ 36#endif /* LIBC_SCCS and not lint */
37 37
38#include <netdb.h> 38#include <netdb.h>
@@ -41,7 +41,7 @@ static char rcsid[] = "$OpenBSD: getnetbyname.c,v 1.3 1996/08/19 08:28:44 tholo
41extern int _net_stayopen; 41extern int _net_stayopen;
42 42
43struct netent * 43struct netent *
44getnetbyname(name) 44_getnetbyname(name)
45 register const char *name; 45 register const char *name;
46{ 46{
47 register struct netent *p; 47 register struct netent *p;
diff --git a/src/lib/libc/net/getnetent.3 b/src/lib/libc/net/getnetent.3
index 9cd54a817c..a3aebf4310 100644
--- a/src/lib/libc/net/getnetent.3
+++ b/src/lib/libc/net/getnetent.3
@@ -1,4 +1,4 @@
1.\" $OpenBSD: getnetent.3,v 1.2 1996/08/19 08:28:45 tholo Exp $ 1.\" $OpenBSD: getnetent.3,v 1.3 1997/03/13 19:07:26 downsj Exp $
2.\" 2.\"
3.\" Copyright (c) 1983, 1991, 1993 3.\" Copyright (c) 1983, 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
@@ -31,9 +31,9 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 32.\" SUCH DAMAGE.
33.\" 33.\"
34.Dd June 4, 1993 34.Dd March 13, 1997
35.Dt GETNETENT 3 35.Dt GETNETENT 3
36.Os BSD 4.2 36.Os
37.Sh NAME 37.Sh NAME
38.Nm getnetent , 38.Nm getnetent ,
39.Nm getnetbyaddr , 39.Nm getnetbyaddr ,
@@ -48,7 +48,7 @@
48.Ft struct netent * 48.Ft struct netent *
49.Fn getnetbyname "char *name" 49.Fn getnetbyname "char *name"
50.Ft struct netent * 50.Ft struct netent *
51.Fn getnetbyaddr "long net" "int type" 51.Fn getnetbyaddr "unsigned long net" "int type"
52.Fn setnetent "int stayopen" 52.Fn setnetent "int stayopen"
53.Fn endnetent 53.Fn endnetent
54.Sh DESCRIPTION 54.Sh DESCRIPTION
@@ -111,11 +111,10 @@ The
111function 111function
112and 112and
113.Fn getnetbyaddr 113.Fn getnetbyaddr
114sequentially search from the beginning 114search the domain name server if the system is configured to use one.
115of the file until a matching 115If the search fails, or no name server is configured, they sequentially
116net name or 116search from the beginning of the file until a matching net name or
117net address and type is found, 117net address and type is found, or until
118or until
119.Dv EOF 118.Dv EOF
120is encountered. 119is encountered.
121Network numbers are supplied in host order. 120Network numbers are supplied in host order.
@@ -129,7 +128,8 @@ Null pointer
129.Dv EOF 128.Dv EOF
130or error. 129or error.
131.Sh SEE ALSO 130.Sh SEE ALSO
132.Xr networks 5 131.Xr networks 5 ,
132.Xr resolver 3
133.Sh HISTORY 133.Sh HISTORY
134The 134The
135.Fn getnetent , 135.Fn getnetent ,
@@ -147,5 +147,4 @@ copied before any subsequent calls to these functions overwrite it.
147Only Internet network 147Only Internet network
148numbers are currently understood. 148numbers are currently understood.
149Expecting network numbers to fit 149Expecting network numbers to fit
150in no more than 32 bits is probably 150in no more than 32 bits is naive.
151naive.
diff --git a/src/lib/libc/net/getnetnamadr.c b/src/lib/libc/net/getnetnamadr.c
new file mode 100644
index 0000000000..cc6ccc4275
--- /dev/null
+++ b/src/lib/libc/net/getnetnamadr.c
@@ -0,0 +1,291 @@
1/* $OpenBSD: getnetnamadr.c,v 1.1 1997/03/13 19:07:27 downsj Exp $ */
2
3/* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
4 * Dep. Matematica Universidade de Coimbra, Portugal, Europe
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 */
10/*
11 * Copyright (c) 1983, 1993
12 * The Regents of the University of California. All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 * 3. All advertising materials mentioning features or use of this software
23 * must display the following acknowledgement:
24 * This product includes software developed by the University of
25 * California, Berkeley and its contributors.
26 * 4. Neither the name of the University nor the names of its contributors
27 * may be used to endorse or promote products derived from this software
28 * without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
31 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
34 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * SUCH DAMAGE.
41 */
42
43#if defined(LIBC_SCCS) && !defined(lint)
44#if 0
45static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93";
46static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03";
47static char rcsid[] = "$From: getnetnamadr.c,v 8.7 1996/08/05 08:31:35 vixie Exp $";
48#else
49static char rcsid[] = "$OpenBSD: getnetnamadr.c,v 1.1 1997/03/13 19:07:27 downsj Exp $";
50#endif
51#endif /* LIBC_SCCS and not lint */
52
53#include <sys/types.h>
54#include <sys/param.h>
55#include <sys/socket.h>
56#include <netinet/in.h>
57#include <arpa/inet.h>
58#include <arpa/nameser.h>
59
60#include <stdio.h>
61#include <netdb.h>
62#include <resolv.h>
63#include <ctype.h>
64#include <errno.h>
65#include <string.h>
66
67extern int h_errno;
68
69struct netent *_getnetbyaddr __P((long net, int type));
70struct netent *_getnetbyname __P((const char *name));
71
72#define BYADDR 0
73#define BYNAME 1
74#define MAXALIASES 35
75
76#if PACKETSZ > 1024
77#define MAXPACKET PACKETSZ
78#else
79#define MAXPACKET 1024
80#endif
81
82typedef union {
83 HEADER hdr;
84 u_char buf[MAXPACKET];
85} querybuf;
86
87typedef union {
88 long al;
89 char ac;
90} align;
91
92static struct netent *
93getnetanswer(answer, anslen, net_i)
94 querybuf *answer;
95 int anslen;
96 int net_i;
97{
98
99 register HEADER *hp;
100 register u_char *cp;
101 register int n;
102 u_char *eom;
103 int type, class, buflen, ancount, qdcount, haveanswer, i, nchar;
104 char aux1[30], aux2[30], ans[30], *in, *st, *pauxt, *bp, **ap,
105 *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0;
106static struct netent net_entry;
107static char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1];
108
109 /*
110 * find first satisfactory answer
111 *
112 * answer --> +------------+ ( MESSAGE )
113 * | Header |
114 * +------------+
115 * | Question | the question for the name server
116 * +------------+
117 * | Answer | RRs answering the question
118 * +------------+
119 * | Authority | RRs pointing toward an authority
120 * | Additional | RRs holding additional information
121 * +------------+
122 */
123 eom = answer->buf + anslen;
124 hp = &answer->hdr;
125 ancount = ntohs(hp->ancount); /* #/records in the answer section */
126 qdcount = ntohs(hp->qdcount); /* #/entries in the question section */
127 bp = netbuf;
128 buflen = sizeof(netbuf);
129 cp = answer->buf + HFIXEDSZ;
130 if (!qdcount) {
131 if (hp->aa)
132 h_errno = HOST_NOT_FOUND;
133 else
134 h_errno = TRY_AGAIN;
135 return (NULL);
136 }
137 while (qdcount-- > 0)
138 cp += __dn_skipname(cp, eom) + QFIXEDSZ;
139 ap = net_aliases;
140 *ap = NULL;
141 net_entry.n_aliases = net_aliases;
142 haveanswer = 0;
143 while (--ancount >= 0 && cp < eom) {
144 n = dn_expand(answer->buf, eom, cp, bp, buflen);
145 if ((n < 0) || !res_dnok(bp))
146 break;
147 cp += n;
148 ans[0] = '\0';
149 (void)strcpy(&ans[0], bp);
150 GETSHORT(type, cp);
151 GETSHORT(class, cp);
152 cp += INT32SZ; /* TTL */
153 GETSHORT(n, cp);
154 if (class == C_IN && type == T_PTR) {
155 n = dn_expand(answer->buf, eom, cp, bp, buflen);
156 if ((n < 0) || !res_hnok(bp)) {
157 cp += n;
158 return (NULL);
159 }
160 cp += n;
161 *ap++ = bp;
162 bp += strlen(bp) + 1;
163 net_entry.n_addrtype =
164 (class == C_IN) ? AF_INET : AF_UNSPEC;
165 haveanswer++;
166 }
167 }
168 if (haveanswer) {
169 *ap = NULL;
170 switch (net_i) {
171 case BYADDR:
172 net_entry.n_name = *net_entry.n_aliases;
173 net_entry.n_net = 0L;
174 break;
175 case BYNAME:
176 in = *net_entry.n_aliases;
177 net_entry.n_name = &ans[0];
178 aux2[0] = '\0';
179 for (i = 0; i < 4; i++) {
180 for (st = in, nchar = 0;
181 *st != '.';
182 st++, nchar++)
183 ;
184 if (nchar != 1 || *in != '0' || flag) {
185 flag = 1;
186 (void)strncpy(paux1,
187 (i==0) ? in : in-1,
188 (i==0) ?nchar : nchar+1);
189 paux1[(i==0) ? nchar : nchar+1] = '\0';
190 pauxt = paux2;
191 paux2 = strcat(paux1, paux2);
192 paux1 = pauxt;
193 }
194 in = ++st;
195 }
196 net_entry.n_net = inet_network(paux2);
197 break;
198 }
199 net_entry.n_aliases++;
200 return (&net_entry);
201 }
202 h_errno = TRY_AGAIN;
203 return (NULL);
204}
205
206struct netent *
207getnetbyaddr(net, net_type)
208 register u_long net;
209 register int net_type;
210{
211 unsigned int netbr[4];
212 int nn, anslen;
213 querybuf buf;
214 char qbuf[MAXDNAME];
215 unsigned long net2;
216 struct netent *net_entry;
217
218 if (net_type != AF_INET)
219 return (_getnetbyaddr(net, net_type));
220
221 for (nn = 4, net2 = net; net2; net2 >>= 8)
222 netbr[--nn] = net2 & 0xff;
223 switch (nn) {
224 case 3: /* Class A */
225 snprintf(qbuf, sizeof(qbuf), "0.0.0.%u.in-addr.arpa", netbr[3]);
226 break;
227 case 2: /* Class B */
228 snprintf(qbuf, sizeof(qbuf), "0.0.%u.%u.in-addr.arpa",
229 netbr[3], netbr[2]);
230 break;
231 case 1: /* Class C */
232 snprintf(qbuf, sizeof(qbuf), "0.%u.%u.%u.in-addr.arpa",
233 netbr[3], netbr[2], netbr[1]);
234 break;
235 case 0: /* Class D - E */
236 snprintf(qbuf, sizeof(qbuf), "%u.%u.%u.%u.in-addr.arpa",
237 netbr[3], netbr[2], netbr[1], netbr[0]);
238 break;
239 }
240 anslen = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf));
241 if (anslen < 0) {
242#ifdef DEBUG
243 if (_res.options & RES_DEBUG)
244 printf("res_query failed\n");
245#endif
246 if (errno == ECONNREFUSED)
247 return (_getnetbyaddr(net, net_type));
248 return (NULL);
249 }
250 net_entry = getnetanswer(&buf, anslen, BYADDR);
251 if (net_entry) {
252 unsigned u_net = net; /* maybe net should be unsigned ? */
253
254 /* Strip trailing zeros */
255 while ((u_net & 0xff) == 0 && u_net != 0)
256 u_net >>= 8;
257 net_entry->n_net = u_net;
258 return (net_entry);
259 }
260 return (_getnetbyaddr(net, net_type));
261}
262
263struct netent *
264getnetbyname(net)
265 register const char *net;
266{
267 int anslen;
268 querybuf buf;
269 char qbuf[MAXDNAME];
270 struct netent *net_entry;
271
272 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
273 h_errno = NETDB_INTERNAL;
274 return (NULL);
275 }
276 strcpy(&qbuf[0], net);
277 anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf));
278 if (anslen < 0) {
279#ifdef DEBUG
280 if (_res.options & RES_DEBUG)
281 printf("res_query failed\n");
282#endif
283 if (errno == ECONNREFUSED)
284 return (_getnetbyname(net));
285 return (_getnetbyname(net));
286 }
287 net_entry = getnetanswer(&buf, anslen, BYNAME);
288 if (net_entry)
289 return (net_entry);
290 return (_getnetbyname(net));
291}
diff --git a/src/lib/libc/net/herror.c b/src/lib/libc/net/herror.c
index 40da6562ad..737bb115a7 100644
--- a/src/lib/libc/net/herror.c
+++ b/src/lib/libc/net/herror.c
@@ -1,7 +1,11 @@
1/*- 1/* $OpenBSD: herror.c,v 1.4 1997/03/13 19:07:28 downsj Exp $ */
2
3/*
4 * ++Copyright++ 1987, 1993
5 * -
2 * Copyright (c) 1987, 1993 6 * Copyright (c) 1987, 1993
3 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
4 * 8 *
5 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
7 * are met: 11 * are met:
@@ -12,12 +16,12 @@
12 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 17 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement: 18 * must display the following acknowledgement:
15 * This product includes software developed by the University of 19 * This product includes software developed by the University of
16 * California, Berkeley and its contributors. 20 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors 21 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software 22 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 23 * without specific prior written permission.
20 * 24 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -52,16 +56,22 @@
52 */ 56 */
53 57
54#if defined(LIBC_SCCS) && !defined(lint) 58#if defined(LIBC_SCCS) && !defined(lint)
55static char rcsid[] = "$OpenBSD: herror.c,v 1.3 1996/08/19 08:29:02 tholo Exp $"; 59#if 0
60static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: herror.c,v 8.3 1996/08/05 08:31:35 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: herror.c,v 1.4 1997/03/13 19:07:28 downsj Exp $";
64#endif
56#endif /* LIBC_SCCS and not lint */ 65#endif /* LIBC_SCCS and not lint */
57 66
58#include <sys/types.h> 67#include <sys/types.h>
68#include <sys/param.h>
59#include <sys/uio.h> 69#include <sys/uio.h>
60#include <netdb.h> 70#include <netdb.h>
61#include <unistd.h> 71#include <unistd.h>
62#include <string.h> 72#include <string.h>
63 73
64const char *h_errlist[] = { 74const char *h_errlist[] = {
65 "Resolver Error 0 (no error)", 75 "Resolver Error 0 (no error)",
66 "Unknown host", /* 1 HOST_NOT_FOUND */ 76 "Unknown host", /* 1 HOST_NOT_FOUND */
67 "Host name lookup failure", /* 2 TRY_AGAIN */ 77 "Host name lookup failure", /* 2 TRY_AGAIN */
diff --git a/src/lib/libc/net/inet_addr.c b/src/lib/libc/net/inet_addr.c
index 99a6f66ad2..ef8ee4963b 100644
--- a/src/lib/libc/net/inet_addr.c
+++ b/src/lib/libc/net/inet_addr.c
@@ -1,7 +1,11 @@
1/* $OpenBSD: inet_addr.c,v 1.4 1997/03/13 19:07:29 downsj Exp $ */
2
1/* 3/*
4 * ++Copyright++ 1983, 1990, 1993
5 * -
2 * Copyright (c) 1983, 1990, 1993 6 * Copyright (c) 1983, 1990, 1993
3 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
4 * 8 *
5 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
7 * are met: 11 * are met:
@@ -12,12 +16,12 @@
12 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 17 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement: 18 * must display the following acknowledgement:
15 * This product includes software developed by the University of 19 * This product includes software developed by the University of
16 * California, Berkeley and its contributors. 20 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors 21 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software 22 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 23 * without specific prior written permission.
20 * 24 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -29,12 +33,38 @@
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE. 35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * --Copyright--
32 */ 56 */
33 57
34#if defined(LIBC_SCCS) && !defined(lint) 58#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: inet_addr.c,v 1.3 1996/08/19 08:29:08 tholo Exp $"; 59#if 0
60static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
61static char rcsid[] = "$From: inet_addr.c,v 8.5 1996/08/05 08:31:35 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: inet_addr.c,v 1.4 1997/03/13 19:07:29 downsj Exp $";
64#endif
36#endif /* LIBC_SCCS and not lint */ 65#endif /* LIBC_SCCS and not lint */
37 66
67#include <sys/types.h>
38#include <sys/param.h> 68#include <sys/param.h>
39#include <netinet/in.h> 69#include <netinet/in.h>
40#include <arpa/inet.h> 70#include <arpa/inet.h>
@@ -73,50 +103,52 @@ inet_aton(cp, addr)
73 u_int parts[4]; 103 u_int parts[4];
74 register u_int *pp = parts; 104 register u_int *pp = parts;
75 105
106 c = *cp;
76 for (;;) { 107 for (;;) {
77 /* 108 /*
78 * Collect number up to ``.''. 109 * Collect number up to ``.''.
79 * Values are specified as for C: 110 * Values are specified as for C:
80 * 0x=hex, 0=octal, other=decimal. 111 * 0x=hex, 0=octal, isdigit=decimal.
81 */ 112 */
113 if (!isdigit(c))
114 return (0);
82 val = 0; base = 10; 115 val = 0; base = 10;
83 if (*cp == '0') { 116 if (c == '0') {
84 if (*++cp == 'x' || *cp == 'X') 117 c = *++cp;
85 base = 16, cp++; 118 if (c == 'x' || c == 'X')
119 base = 16, c = *++cp;
86 else 120 else
87 base = 8; 121 base = 8;
88 } 122 }
89 while ((c = *cp) != '\0') { 123 for (;;) {
90 if (isascii(c) && isdigit(c)) { 124 if (isascii(c) && isdigit(c)) {
91 val = (val * base) + (c - '0'); 125 val = (val * base) + (c - '0');
92 cp++; 126 c = *++cp;
93 continue; 127 } else if (base == 16 && isascii(c) && isxdigit(c)) {
94 } 128 val = (val << 4) |
95 if (base == 16 && isascii(c) && isxdigit(c)) {
96 val = (val << 4) +
97 (c + 10 - (islower(c) ? 'a' : 'A')); 129 (c + 10 - (islower(c) ? 'a' : 'A'));
98 cp++; 130 c = *++cp;
99 continue; 131 } else
100 } 132 break;
101 break;
102 } 133 }
103 if (*cp == '.') { 134 if (c == '.') {
104 /* 135 /*
105 * Internet format: 136 * Internet format:
106 * a.b.c.d 137 * a.b.c.d
107 * a.b.c (with c treated as 16-bits) 138 * a.b.c (with c treated as 16 bits)
108 * a.b (with b treated as 24 bits) 139 * a.b (with b treated as 24 bits)
109 */ 140 */
110 if (pp >= parts + 3 || val > 0xff) 141 if (pp >= parts + 3)
111 return (0); 142 return (0);
112 *pp++ = val, cp++; 143 *pp++ = val;
144 c = *++cp;
113 } else 145 } else
114 break; 146 break;
115 } 147 }
116 /* 148 /*
117 * Check for trailing characters. 149 * Check for trailing characters.
118 */ 150 */
119 if (*cp && (!isascii(*cp) || !isspace(*cp))) 151 if (c != '\0' && (!isascii(c) || !isspace(c)))
120 return (0); 152 return (0);
121 /* 153 /*
122 * Concoct the address according to 154 * Concoct the address according to
diff --git a/src/lib/libc/net/inet_net_ntop.c b/src/lib/libc/net/inet_net_ntop.c
new file mode 100644
index 0000000000..943ec44550
--- /dev/null
+++ b/src/lib/libc/net/inet_net_ntop.c
@@ -0,0 +1,139 @@
1/* $OpenBSD: inet_net_ntop.c,v 1.1 1997/03/13 19:07:30 downsj Exp $ */
2
3/*
4 * Copyright (c) 1996 by Internet Software Consortium.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
12 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
13 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
16 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
17 * SOFTWARE.
18 */
19
20#if defined(LIBC_SCCS) && !defined(lint)
21#if 0
22static const char rcsid[] = "$From: inet_net_ntop.c,v 8.2 1996/08/08 06:54:44 vixie Exp $";
23#else
24static const char rcsid[] = "$OpenBSD: inet_net_ntop.c,v 1.1 1997/03/13 19:07:30 downsj Exp $";
25#endif
26#endif
27
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <netinet/in.h>
31#include <arpa/inet.h>
32
33#include <errno.h>
34#include <stdio.h>
35#include <string.h>
36#include <stdlib.h>
37
38static char * inet_net_ntop_ipv4 __P((const u_char *src, int bits,
39 char *dst, size_t size));
40
41/*
42 * char *
43 * inet_net_ntop(af, src, bits, dst, size)
44 * convert network number from network to presentation format.
45 * generates CIDR style result always.
46 * return:
47 * pointer to dst, or NULL if an error occurred (check errno).
48 * author:
49 * Paul Vixie (ISC), July 1996
50 */
51char *
52inet_net_ntop(af, src, bits, dst, size)
53 int af;
54 const void *src;
55 int bits;
56 char *dst;
57 size_t size;
58{
59 switch (af) {
60 case AF_INET:
61 return (inet_net_ntop_ipv4(src, bits, dst, size));
62 default:
63 errno = EAFNOSUPPORT;
64 return (NULL);
65 }
66}
67
68/*
69 * static char *
70 * inet_net_ntop_ipv4(src, bits, dst, size)
71 * convert IPv4 network number from network to presentation format.
72 * generates CIDR style result always.
73 * return:
74 * pointer to dst, or NULL if an error occurred (check errno).
75 * note:
76 * network byte order assumed. this means 192.5.5.240/28 has
77 * 0x11110000 in its fourth octet.
78 * author:
79 * Paul Vixie (ISC), July 1996
80 */
81static char *
82inet_net_ntop_ipv4(src, bits, dst, size)
83 const u_char *src;
84 int bits;
85 char *dst;
86 size_t size;
87{
88 char *odst = dst;
89 char *t;
90 u_int m;
91 int b;
92
93 if (bits < 0 || bits > 32) {
94 errno = EINVAL;
95 return (NULL);
96 }
97 if (bits == 0) {
98 if (size < sizeof "0")
99 goto emsgsize;
100 *dst++ = '0';
101 *dst = '\0';
102 }
103
104 /* Format whole octets. */
105 for (b = bits / 8; b > 0; b--) {
106 if (size < sizeof "255.")
107 goto emsgsize;
108 t = dst;
109 dst += sprintf(dst, "%u", *src++);
110 if (b > 1) {
111 *dst++ = '.';
112 *dst = '\0';
113 }
114 size -= (size_t)(dst - t);
115 }
116
117 /* Format partial octet. */
118 b = bits % 8;
119 if (b > 0) {
120 if (size < sizeof ".255")
121 goto emsgsize;
122 t = dst;
123 if (dst != odst)
124 *dst++ = '.';
125 m = ((1 << b) - 1) << (8 - b);
126 dst += sprintf(dst, "%u", *src & m);
127 size -= (size_t)(dst - t);
128 }
129
130 /* Format CIDR /width. */
131 if (size < sizeof "/32")
132 goto emsgsize;
133 dst += sprintf(dst, "/%u", bits);
134 return (odst);
135
136 emsgsize:
137 errno = EMSGSIZE;
138 return (NULL);
139}
diff --git a/src/lib/libc/net/inet_net_pton.c b/src/lib/libc/net/inet_net_pton.c
new file mode 100644
index 0000000000..b529e83664
--- /dev/null
+++ b/src/lib/libc/net/inet_net_pton.c
@@ -0,0 +1,207 @@
1/* $OpenBSD: inet_net_pton.c,v 1.1 1997/03/13 19:07:30 downsj Exp $ */
2
3/*
4 * Copyright (c) 1996 by Internet Software Consortium.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
12 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
13 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
16 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
17 * SOFTWARE.
18 */
19
20#if defined(LIBC_SCCS) && !defined(lint)
21#if 0
22static const char rcsid[] = "$From: inet_net_pton.c,v 8.3 1996/11/11 06:36:52 vixie Exp $";
23#else
24static const char rcsid[] = "$OpenBSD: inet_net_pton.c,v 1.1 1997/03/13 19:07:30 downsj Exp $";
25#endif
26#endif
27
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <netinet/in.h>
31#include <arpa/inet.h>
32
33#include <assert.h>
34#include <ctype.h>
35#include <errno.h>
36#include <stdio.h>
37#include <string.h>
38#include <stdlib.h>
39
40static int inet_net_pton_ipv4 __P((const char *src, u_char *dst,
41 size_t size));
42
43/*
44 * static int
45 * inet_net_pton(af, src, dst, size)
46 * convert network number from presentation to network format.
47 * accepts hex octets, hex strings, decimal octets, and /CIDR.
48 * "size" is in bytes and describes "dst".
49 * return:
50 * number of bits, either imputed classfully or specified with /CIDR,
51 * or -1 if some failure occurred (check errno). ENOENT means it was
52 * not a valid network specification.
53 * author:
54 * Paul Vixie (ISC), June 1996
55 */
56int
57inet_net_pton(af, src, dst, size)
58 int af;
59 const char *src;
60 void *dst;
61 size_t size;
62{
63 switch (af) {
64 case AF_INET:
65 return (inet_net_pton_ipv4(src, dst, size));
66 default:
67 errno = EAFNOSUPPORT;
68 return (-1);
69 }
70}
71
72/*
73 * static int
74 * inet_net_pton_ipv4(src, dst, size)
75 * convert IPv4 network number from presentation to network format.
76 * accepts hex octets, hex strings, decimal octets, and /CIDR.
77 * "size" is in bytes and describes "dst".
78 * return:
79 * number of bits, either imputed classfully or specified with /CIDR,
80 * or -1 if some failure occurred (check errno). ENOENT means it was
81 * not an IPv4 network specification.
82 * note:
83 * network byte order assumed. this means 192.5.5.240/28 has
84 * 0x11110000 in its fourth octet.
85 * author:
86 * Paul Vixie (ISC), June 1996
87 */
88static int
89inet_net_pton_ipv4(src, dst, size)
90 const char *src;
91 u_char *dst;
92 size_t size;
93{
94 static const char
95 xdigits[] = "0123456789abcdef",
96 digits[] = "0123456789";
97 int n, ch, tmp, dirty, bits;
98 const u_char *odst = dst;
99
100 ch = *src++;
101 if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
102 && isascii(src[1]) && isxdigit(src[1])) {
103 /* Hexadecimal: Eat nybble string. */
104 if (size <= 0)
105 goto emsgsize;
106 *dst = 0, dirty = 0;
107 src++; /* skip x or X. */
108 while ((ch = *src++) != '\0' &&
109 isascii(ch) && isxdigit(ch)) {
110 if (isupper(ch))
111 ch = tolower(ch);
112 n = strchr(xdigits, ch) - xdigits;
113 assert(n >= 0 && n <= 15);
114 *dst |= n;
115 if (!dirty++)
116 *dst <<= 4;
117 else if (size-- > 0)
118 *++dst = 0, dirty = 0;
119 else
120 goto emsgsize;
121 }
122 if (dirty)
123 size--;
124 } else if (isascii(ch) && isdigit(ch)) {
125 /* Decimal: eat dotted digit string. */
126 for (;;) {
127 tmp = 0;
128 do {
129 n = strchr(digits, ch) - digits;
130 assert(n >= 0 && n <= 9);
131 tmp *= 10;
132 tmp += n;
133 if (tmp > 255)
134 goto enoent;
135 } while ((ch = *src++) != '\0' &&
136 isascii(ch) && isdigit(ch));
137 if (size-- <= 0)
138 goto emsgsize;
139 *dst++ = (u_char) tmp;
140 if (ch == '\0' || ch == '/')
141 break;
142 if (ch != '.')
143 goto enoent;
144 ch = *src++;
145 if (!isascii(ch) || !isdigit(ch))
146 goto enoent;
147 }
148 } else
149 goto enoent;
150
151 bits = -1;
152 if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) {
153 /* CIDR width specifier. Nothing can follow it. */
154 ch = *src++; /* Skip over the /. */
155 bits = 0;
156 do {
157 n = strchr(digits, ch) - digits;
158 assert(n >= 0 && n <= 9);
159 bits *= 10;
160 bits += n;
161 } while ((ch = *src++) != '\0' &&
162 isascii(ch) && isdigit(ch));
163 if (ch != '\0')
164 goto enoent;
165 if (bits > 32)
166 goto emsgsize;
167 }
168
169 /* Firey death and destruction unless we prefetched EOS. */
170 if (ch != '\0')
171 goto enoent;
172
173 /* If nothing was written to the destination, we found no address. */
174 if (dst == odst)
175 goto enoent;
176 /* If no CIDR spec was given, infer width from net class. */
177 if (bits == -1) {
178 if (*odst >= 240) /* Class E */
179 bits = 32;
180 else if (*odst >= 224) /* Class D */
181 bits = 4;
182 else if (*odst >= 192) /* Class C */
183 bits = 24;
184 else if (*odst >= 128) /* Class B */
185 bits = 16;
186 else /* Class A */
187 bits = 8;
188 /* If imputed mask is narrower than specified octets, widen. */
189 if (bits >= 8 && bits < ((dst - odst) * 8))
190 bits = (dst - odst) * 8;
191 }
192 /* Extend network to cover the actual mask. */
193 while (bits > ((dst - odst) * 8)) {
194 if (size-- <= 0)
195 goto emsgsize;
196 *dst++ = '\0';
197 }
198 return (bits);
199
200 enoent:
201 errno = ENOENT;
202 return (-1);
203
204 emsgsize:
205 errno = EMSGSIZE;
206 return (-1);
207}
diff --git a/src/lib/libc/net/inet_neta.c b/src/lib/libc/net/inet_neta.c
new file mode 100644
index 0000000000..dffd1631b1
--- /dev/null
+++ b/src/lib/libc/net/inet_neta.c
@@ -0,0 +1,82 @@
1/* $OpenBSD: inet_neta.c,v 1.1 1997/03/13 19:07:31 downsj Exp $ */
2
3/*
4 * Copyright (c) 1996 by Internet Software Consortium.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
12 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
13 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
16 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
17 * SOFTWARE.
18 */
19
20#if defined(LIBC_SCCS) && !defined(lint)
21#if 0
22static const char rcsid[] = "$Id: inet_neta.c,v 1.1 1997/03/13 19:07:31 downsj Exp $";
23#else
24static const char rcsid[] = "$OpenBSD: inet_neta.c,v 1.1 1997/03/13 19:07:31 downsj Exp $";
25#endif
26#endif
27
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <netinet/in.h>
31#include <arpa/inet.h>
32
33#include <errno.h>
34#include <stdio.h>
35
36/*
37 * char *
38 * inet_neta(src, dst, size)
39 * format a u_long network number into presentation format.
40 * return:
41 * pointer to dst, or NULL if an error occurred (check errno).
42 * note:
43 * format of ``src'' is as for inet_network().
44 * author:
45 * Paul Vixie (ISC), July 1996
46 */
47char *
48inet_neta(src, dst, size)
49 u_long src;
50 char *dst;
51 size_t size;
52{
53 char *odst = dst;
54 char *tp;
55
56 while (src & 0xffffffff) {
57 u_char b = (src & 0xff000000) >> 24;
58
59 src <<= 8;
60 if (b) {
61 if (size < sizeof "255.")
62 goto emsgsize;
63 tp = dst;
64 dst += sprintf(dst, "%u", b);
65 if (src != 0L) {
66 *dst++ = '.';
67 *dst = '\0';
68 }
69 size -= (size_t)(dst - tp);
70 }
71 }
72 if (dst == odst) {
73 if (size < sizeof "0.0.0.0")
74 goto emsgsize;
75 strcpy(dst, "0.0.0.0");
76 }
77 return (odst);
78
79 emsgsize:
80 errno = EMSGSIZE;
81 return (NULL);
82}
diff --git a/src/lib/libc/net/inet_ntop.c b/src/lib/libc/net/inet_ntop.c
new file mode 100644
index 0000000000..64d0d13768
--- /dev/null
+++ b/src/lib/libc/net/inet_ntop.c
@@ -0,0 +1,194 @@
1/* $OpenBSD: inet_ntop.c,v 1.1 1997/03/13 19:07:32 downsj Exp $ */
2
3/* Copyright (c) 1996 by Internet Software Consortium.
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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
10 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
11 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
12 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
15 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
16 * SOFTWARE.
17 */
18
19#if defined(LIBC_SCCS) && !defined(lint)
20#if 0
21static char rcsid[] = "$From: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $";
22#else
23static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.1 1997/03/13 19:07:32 downsj Exp $";
24#endif
25#endif /* LIBC_SCCS and not lint */
26
27#include <sys/param.h>
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <netinet/in.h>
31#include <arpa/inet.h>
32#include <arpa/nameser.h>
33#include <string.h>
34#include <errno.h>
35#include <stdio.h>
36
37/*
38 * WARNING: Don't even consider trying to compile this on a system where
39 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
40 */
41
42static const char *inet_ntop4 __P((const u_char *src, char *dst, size_t size));
43static const char *inet_ntop6 __P((const u_char *src, char *dst, size_t size));
44
45/* char *
46 * inet_ntop(af, src, dst, size)
47 * convert a network format address to presentation format.
48 * return:
49 * pointer to presentation format address (`dst'), or NULL (see errno).
50 * author:
51 * Paul Vixie, 1996.
52 */
53const char *
54inet_ntop(af, src, dst, size)
55 int af;
56 const void *src;
57 char *dst;
58 size_t size;
59{
60 switch (af) {
61 case AF_INET:
62 return (inet_ntop4(src, dst, size));
63 case AF_INET6:
64 return (inet_ntop6(src, dst, size));
65 default:
66 errno = EAFNOSUPPORT;
67 return (NULL);
68 }
69 /* NOTREACHED */
70}
71
72/* const char *
73 * inet_ntop4(src, dst, size)
74 * format an IPv4 address, more or less like inet_ntoa()
75 * return:
76 * `dst' (as a const)
77 * notes:
78 * (1) uses no statics
79 * (2) takes a u_char* not an in_addr as input
80 * author:
81 * Paul Vixie, 1996.
82 */
83static const char *
84inet_ntop4(src, dst, size)
85 const u_char *src;
86 char *dst;
87 size_t size;
88{
89 static const char fmt[] = "%u.%u.%u.%u";
90 char tmp[sizeof "255.255.255.255"];
91
92 if (sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) > size) {
93 errno = ENOSPC;
94 return (NULL);
95 }
96 strcpy(dst, tmp);
97 return (dst);
98}
99
100/* const char *
101 * inet_ntop6(src, dst, size)
102 * convert IPv6 binary address into presentation (printable) format
103 * author:
104 * Paul Vixie, 1996.
105 */
106static const char *
107inet_ntop6(src, dst, size)
108 const u_char *src;
109 char *dst;
110 size_t size;
111{
112 /*
113 * Note that int32_t and int16_t need only be "at least" large enough
114 * to contain a value of the specified size. On some systems, like
115 * Crays, there is no such thing as an integer variable with 16 bits.
116 * Keep this in mind if you think this function should have been coded
117 * to use pointer overlays. All the world's not a VAX.
118 */
119 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
120 struct { int base, len; } best, cur;
121 u_int words[IN6ADDRSZ / INT16SZ];
122 int i;
123
124 /*
125 * Preprocess:
126 * Copy the input (bytewise) array into a wordwise array.
127 * Find the longest run of 0x00's in src[] for :: shorthanding.
128 */
129 memset(words, '\0', sizeof words);
130 for (i = 0; i < IN6ADDRSZ; i++)
131 words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
132 best.base = -1;
133 cur.base = -1;
134 for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
135 if (words[i] == 0) {
136 if (cur.base == -1)
137 cur.base = i, cur.len = 1;
138 else
139 cur.len++;
140 } else {
141 if (cur.base != -1) {
142 if (best.base == -1 || cur.len > best.len)
143 best = cur;
144 cur.base = -1;
145 }
146 }
147 }
148 if (cur.base != -1) {
149 if (best.base == -1 || cur.len > best.len)
150 best = cur;
151 }
152 if (best.base != -1 && best.len < 2)
153 best.base = -1;
154
155 /*
156 * Format the result.
157 */
158 tp = tmp;
159 for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
160 /* Are we inside the best run of 0x00's? */
161 if (best.base != -1 && i >= best.base &&
162 i < (best.base + best.len)) {
163 if (i == best.base)
164 *tp++ = ':';
165 continue;
166 }
167 /* Are we following an initial run of 0x00s or any real hex? */
168 if (i != 0)
169 *tp++ = ':';
170 /* Is this address an encapsulated IPv4? */
171 if (i == 6 && best.base == 0 &&
172 (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
173 if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
174 return (NULL);
175 tp += strlen(tp);
176 break;
177 }
178 tp += sprintf(tp, "%x", words[i]);
179 }
180 /* Was it a trailing run of 0x00's? */
181 if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
182 *tp++ = ':';
183 *tp++ = '\0';
184
185 /*
186 * Check for overflow, copy, and we're done.
187 */
188 if ((size_t)(tp - tmp) > size) {
189 errno = ENOSPC;
190 return (NULL);
191 }
192 strcpy(dst, tmp);
193 return (dst);
194}
diff --git a/src/lib/libc/net/inet_pton.c b/src/lib/libc/net/inet_pton.c
new file mode 100644
index 0000000000..8ffe81ed12
--- /dev/null
+++ b/src/lib/libc/net/inet_pton.c
@@ -0,0 +1,220 @@
1/* $OpenBSD: inet_pton.c,v 1.1 1997/03/13 19:07:33 downsj Exp $ */
2
3/* Copyright (c) 1996 by Internet Software Consortium.
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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
10 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
11 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
12 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
15 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
16 * SOFTWARE.
17 */
18
19#if defined(LIBC_SCCS) && !defined(lint)
20#if 0
21static char rcsid[] = "$From: inet_pton.c,v 8.7 1996/08/05 08:31:35 vixie Exp $";
22#else
23static char rcsid[] = "$OpenBSD: inet_pton.c,v 1.1 1997/03/13 19:07:33 downsj Exp $";
24#endif
25#endif /* LIBC_SCCS and not lint */
26
27#include <sys/param.h>
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <netinet/in.h>
31#include <arpa/inet.h>
32#include <arpa/nameser.h>
33#include <string.h>
34#include <errno.h>
35
36/*
37 * WARNING: Don't even consider trying to compile this on a system where
38 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
39 */
40
41static int inet_pton4 __P((const char *src, u_char *dst));
42static int inet_pton6 __P((const char *src, u_char *dst));
43
44/* int
45 * inet_pton(af, src, dst)
46 * convert from presentation format (which usually means ASCII printable)
47 * to network format (which is usually some kind of binary format).
48 * return:
49 * 1 if the address was valid for the specified address family
50 * 0 if the address wasn't valid (`dst' is untouched in this case)
51 * -1 if some other error occurred (`dst' is untouched in this case, too)
52 * author:
53 * Paul Vixie, 1996.
54 */
55int
56inet_pton(af, src, dst)
57 int af;
58 const char *src;
59 void *dst;
60{
61 switch (af) {
62 case AF_INET:
63 return (inet_pton4(src, dst));
64 case AF_INET6:
65 return (inet_pton6(src, dst));
66 default:
67 errno = EAFNOSUPPORT;
68 return (-1);
69 }
70 /* NOTREACHED */
71}
72
73/* int
74 * inet_pton4(src, dst)
75 * like inet_aton() but without all the hexadecimal and shorthand.
76 * return:
77 * 1 if `src' is a valid dotted quad, else 0.
78 * notice:
79 * does not touch `dst' unless it's returning 1.
80 * author:
81 * Paul Vixie, 1996.
82 */
83static int
84inet_pton4(src, dst)
85 const char *src;
86 u_char *dst;
87{
88 static const char digits[] = "0123456789";
89 int saw_digit, octets, ch;
90 u_char tmp[INADDRSZ], *tp;
91
92 saw_digit = 0;
93 octets = 0;
94 *(tp = tmp) = 0;
95 while ((ch = *src++) != '\0') {
96 const char *pch;
97
98 if ((pch = strchr(digits, ch)) != NULL) {
99 u_int new = *tp * 10 + (pch - digits);
100
101 if (new > 255)
102 return (0);
103 *tp = new;
104 if (! saw_digit) {
105 if (++octets > 4)
106 return (0);
107 saw_digit = 1;
108 }
109 } else if (ch == '.' && saw_digit) {
110 if (octets == 4)
111 return (0);
112 *++tp = 0;
113 saw_digit = 0;
114 } else
115 return (0);
116 }
117 if (octets < 4)
118 return (0);
119
120 memcpy(dst, tmp, INADDRSZ);
121 return (1);
122}
123
124/* int
125 * inet_pton6(src, dst)
126 * convert presentation level address to network order binary form.
127 * return:
128 * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
129 * notice:
130 * (1) does not touch `dst' unless it's returning 1.
131 * (2) :: in a full address is silently ignored.
132 * credit:
133 * inspired by Mark Andrews.
134 * author:
135 * Paul Vixie, 1996.
136 */
137static int
138inet_pton6(src, dst)
139 const char *src;
140 u_char *dst;
141{
142 static const char xdigits_l[] = "0123456789abcdef",
143 xdigits_u[] = "0123456789ABCDEF";
144 u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
145 const char *xdigits, *curtok;
146 int ch, saw_xdigit;
147 u_int val;
148
149 memset((tp = tmp), '\0', IN6ADDRSZ);
150 endp = tp + IN6ADDRSZ;
151 colonp = NULL;
152 /* Leading :: requires some special handling. */
153 if (*src == ':')
154 if (*++src != ':')
155 return (0);
156 curtok = src;
157 saw_xdigit = 0;
158 val = 0;
159 while ((ch = *src++) != '\0') {
160 const char *pch;
161
162 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
163 pch = strchr((xdigits = xdigits_u), ch);
164 if (pch != NULL) {
165 val <<= 4;
166 val |= (pch - xdigits);
167 if (val > 0xffff)
168 return (0);
169 saw_xdigit = 1;
170 continue;
171 }
172 if (ch == ':') {
173 curtok = src;
174 if (!saw_xdigit) {
175 if (colonp)
176 return (0);
177 colonp = tp;
178 continue;
179 }
180 if (tp + INT16SZ > endp)
181 return (0);
182 *tp++ = (u_char) (val >> 8) & 0xff;
183 *tp++ = (u_char) val & 0xff;
184 saw_xdigit = 0;
185 val = 0;
186 continue;
187 }
188 if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
189 inet_pton4(curtok, tp) > 0) {
190 tp += INADDRSZ;
191 saw_xdigit = 0;
192 break; /* '\0' was seen by inet_pton4(). */
193 }
194 return (0);
195 }
196 if (saw_xdigit) {
197 if (tp + INT16SZ > endp)
198 return (0);
199 *tp++ = (u_char) (val >> 8) & 0xff;
200 *tp++ = (u_char) val & 0xff;
201 }
202 if (colonp != NULL) {
203 /*
204 * Since some memmove()'s erroneously fail to handle
205 * overlapping regions, we'll do the shift by hand.
206 */
207 const int n = tp - colonp;
208 int i;
209
210 for (i = 1; i <= n; i++) {
211 endp[- i] = colonp[n - i];
212 colonp[n - i] = 0;
213 }
214 tp = endp;
215 }
216 if (tp != endp)
217 return (0);
218 memcpy(dst, tmp, IN6ADDRSZ);
219 return (1);
220}
diff --git a/src/lib/libc/net/nsap_addr.c b/src/lib/libc/net/nsap_addr.c
index ce0a60a7d8..e62d952a07 100644
--- a/src/lib/libc/net/nsap_addr.c
+++ b/src/lib/libc/net/nsap_addr.c
@@ -1,40 +1,31 @@
1/* $OpenBSD: nsap_addr.c,v 1.3 1997/03/13 19:07:34 downsj Exp $ */
2
1/* 3/*
2 * Copyright (c) 1989, 1993 4 * Copyright (c) 1996 by Internet Software Consortium.
3 * The Regents of the University of California. All rights reserved.
4 * 5 *
5 * Redistribution and use in source and binary forms, with or without 6 * Permission to use, copy, modify, and distribute this software for any
6 * modification, are permitted provided that the following conditions 7 * purpose with or without fee is hereby granted, provided that the above
7 * are met: 8 * copyright notice and this permission notice appear in all copies.
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 * 9 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 10 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 12 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 13 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 16 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 17 * SOFTWARE.
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */ 18 */
33 19
34#if defined(LIBC_SCCS) && !defined(lint) 20#if defined(LIBC_SCCS) && !defined(lint)
35static char rcsid[] = "$OpenBSD: nsap_addr.c,v 1.2 1996/08/19 08:29:32 tholo Exp $"; 21#if 0
22static char rcsid[] = "$From: nsap_addr.c,v 8.3 1996/08/05 08:31:35 vixie Exp $";
23#else
24static char rcsid[] = "$OpenBSD: nsap_addr.c,v 1.3 1997/03/13 19:07:34 downsj Exp $";
25#endif
36#endif /* LIBC_SCCS and not lint */ 26#endif /* LIBC_SCCS and not lint */
37 27
28#include <sys/types.h>
38#include <sys/param.h> 29#include <sys/param.h>
39#include <sys/socket.h> 30#include <sys/socket.h>
40#include <netinet/in.h> 31#include <netinet/in.h>
@@ -49,12 +40,6 @@ xtob(c)
49 return (c - (((c >= '0') && (c <= '9')) ? '0' : '7')); 40 return (c - (((c >= '0') && (c <= '9')) ? '0' : '7'));
50} 41}
51 42
52/* These have to be here for BIND and its utilities (DiG, nslookup, et al)
53 * but should not be promulgated since the calling interface is not pretty.
54 * (They do, however, implement the RFC standard way of representing ISO NSAPs
55 * and as such, are preferred over the more general iso_addr.c routines.
56 */
57
58u_int 43u_int
59inet_nsap_addr(ascii, binary, maxlen) 44inet_nsap_addr(ascii, binary, maxlen)
60 const char *ascii; 45 const char *ascii;
diff --git a/src/lib/libc/net/res_comp.c b/src/lib/libc/net/res_comp.c
index f64a81d7ce..2e98003b85 100644
--- a/src/lib/libc/net/res_comp.c
+++ b/src/lib/libc/net/res_comp.c
@@ -1,7 +1,11 @@
1/*- 1/* $OpenBSD: res_comp.c,v 1.4 1997/03/13 19:07:35 downsj Exp $ */
2
3/*
4 * ++Copyright++ 1985, 1993
5 * -
2 * Copyright (c) 1985, 1993 6 * Copyright (c) 1985, 1993
3 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
4 * 8 *
5 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
7 * are met: 11 * are met:
@@ -12,12 +16,12 @@
12 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 17 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement: 18 * must display the following acknowledgement:
15 * This product includes software developed by the University of 19 * This product includes software developed by the University of
16 * California, Berkeley and its contributors. 20 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors 21 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software 22 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 23 * without specific prior written permission.
20 * 24 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -52,19 +56,28 @@
52 */ 56 */
53 57
54#if defined(LIBC_SCCS) && !defined(lint) 58#if defined(LIBC_SCCS) && !defined(lint)
55static char rcsid[] = "$OpenBSD: res_comp.c,v 1.3 1996/08/19 08:29:42 tholo Exp $"; 59#if 0
60static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: res_comp.c,v 8.11 1996/12/02 09:17:22 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: res_comp.c,v 1.4 1997/03/13 19:07:35 downsj Exp $";
64#endif
56#endif /* LIBC_SCCS and not lint */ 65#endif /* LIBC_SCCS and not lint */
57 66
67#include <sys/types.h>
58#include <sys/param.h> 68#include <sys/param.h>
59#include <arpa/nameser.h>
60#include <netinet/in.h> 69#include <netinet/in.h>
61#include <resolv.h> 70#include <arpa/nameser.h>
71
62#include <stdio.h> 72#include <stdio.h>
73#include <resolv.h>
63#include <ctype.h> 74#include <ctype.h>
75
64#include <unistd.h> 76#include <unistd.h>
65#include <string.h> 77#include <string.h>
66 78
67static int dn_find __P((u_char *, u_char *, u_char **, u_char **)); 79static int dn_find __P((u_char *exp_dn, u_char *msg,
80 u_char **dnptrs, u_char **lastdnptr));
68 81
69/* 82/*
70 * Expand compressed domain name 'comp_dn' to full domain name. 83 * Expand compressed domain name 'comp_dn' to full domain name.
@@ -106,7 +119,7 @@ dn_expand(msg, eomorig, comp_dn, exp_dn, length)
106 return (-1); 119 return (-1);
107 checked += n + 1; 120 checked += n + 1;
108 while (--n >= 0) { 121 while (--n >= 0) {
109 if ((c = *cp++) == '.' || c == '\\') { 122 if (((c = *cp++) == '.') || (c == '\\')) {
110 if (dn + n + 2 >= eom) 123 if (dn + n + 2 >= eom)
111 return (-1); 124 return (-1);
112 *dn++ = '\\'; 125 *dn++ = '\\';
@@ -138,9 +151,6 @@ dn_expand(msg, eomorig, comp_dn, exp_dn, length)
138 } 151 }
139 } 152 }
140 *dn = '\0'; 153 *dn = '\0';
141 for (dn = exp_dn; (c = *dn) != '\0'; dn++)
142 if (isascii(c) && isspace(c))
143 return (-1);
144 if (len < 0) 154 if (len < 0)
145 len = cp - comp_dn; 155 len = cp - comp_dn;
146 return (len); 156 return (len);
@@ -263,7 +273,7 @@ __dn_skipname(comp_dn, eom)
263 break; 273 break;
264 } 274 }
265 if (cp > eom) 275 if (cp > eom)
266 return -1; 276 return (-1);
267 return (cp - comp_dn); 277 return (cp - comp_dn);
268} 278}
269 279
@@ -330,14 +340,122 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr)
330} 340}
331 341
332/* 342/*
333 * Routines to insert/extract short/long's. Must account for byte 343 * Verify that a domain name uses an acceptable character set.
334 * order and non-alignment problems. This code at least has the
335 * advantage of being portable.
336 *
337 * used by sendmail.
338 */ 344 */
339 345
340u_short 346/*
347 * Note the conspicuous absence of ctype macros in these definitions. On
348 * non-ASCII hosts, we can't depend on string literals or ctype macros to
349 * tell us anything about network-format data. The rest of the BIND system
350 * is not careful about this, but for some reason, we're doing it right here.
351 */
352#define PERIOD 0x2e
353#define hyphenchar(c) ((c) == 0x2d)
354#define bslashchar(c) ((c) == 0x5c)
355#define periodchar(c) ((c) == PERIOD)
356#define asterchar(c) ((c) == 0x2a)
357#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
358 || ((c) >= 0x61 && (c) <= 0x7a))
359#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
360
361#define borderchar(c) (alphachar(c) || digitchar(c))
362#define middlechar(c) (borderchar(c) || hyphenchar(c))
363#define domainchar(c) ((c) > 0x20 && (c) < 0x7f)
364
365int
366res_hnok(dn)
367 const char *dn;
368{
369 int ppch = '\0', pch = PERIOD, ch = *dn++;
370
371 while (ch != '\0') {
372 int nch = *dn++;
373
374 if (periodchar(ch)) {
375 NULL;
376 } else if (periodchar(pch)) {
377 if (!borderchar(ch))
378 return (0);
379 } else if (periodchar(nch) || nch == '\0') {
380 if (!borderchar(ch))
381 return (0);
382 } else {
383 if (!middlechar(ch))
384 return (0);
385 }
386 ppch = pch, pch = ch, ch = nch;
387 }
388 return (1);
389}
390
391/*
392 * hostname-like (A, MX, WKS) owners can have "*" as their first label
393 * but must otherwise be as a host name.
394 */
395int
396res_ownok(dn)
397 const char *dn;
398{
399 if (asterchar(dn[0])) {
400 if (periodchar(dn[1]))
401 return (res_hnok(dn+2));
402 if (dn[1] == '\0')
403 return (1);
404 }
405 return (res_hnok(dn));
406}
407
408/*
409 * SOA RNAMEs and RP RNAMEs can have any printable character in their first
410 * label, but the rest of the name has to look like a host name.
411 */
412int
413res_mailok(dn)
414 const char *dn;
415{
416 int ch, escaped = 0;
417
418 /* "." is a valid missing representation */
419 if (*dn == '\0')
420 return(1);
421
422 /* otherwise <label>.<hostname> */
423 while ((ch = *dn++) != '\0') {
424 if (!domainchar(ch))
425 return (0);
426 if (!escaped && periodchar(ch))
427 break;
428 if (escaped)
429 escaped = 0;
430 else if (bslashchar(ch))
431 escaped = 1;
432 }
433 if (periodchar(ch))
434 return (res_hnok(dn));
435 return(0);
436}
437
438/*
439 * This function is quite liberal, since RFC 1034's character sets are only
440 * recommendations.
441 */
442int
443res_dnok(dn)
444 const char *dn;
445{
446 int ch;
447
448 while ((ch = *dn++) != '\0')
449 if (!domainchar(ch))
450 return (0);
451 return (1);
452}
453
454/*
455 * Routines to insert/extract short/long's.
456 */
457
458u_int16_t
341_getshort(msgp) 459_getshort(msgp)
342 register const u_char *msgp; 460 register const u_char *msgp;
343{ 461{
@@ -347,6 +465,18 @@ _getshort(msgp)
347 return (u); 465 return (u);
348} 466}
349 467
468#ifdef NeXT
469/*
470 * nExt machines have some funky library conventions, which we must maintain.
471 */
472u_int16_t
473res_getshort(msgp)
474 register const u_char *msgp;
475{
476 return (_getshort(msgp));
477}
478#endif
479
350u_int32_t 480u_int32_t
351_getlong(msgp) 481_getlong(msgp)
352 register const u_char *msgp; 482 register const u_char *msgp;
@@ -359,7 +489,7 @@ _getlong(msgp)
359 489
360void 490void
361#if defined(__STDC__) || defined(__cplusplus) 491#if defined(__STDC__) || defined(__cplusplus)
362__putshort(register u_int16_t s, register u_char *msgp) 492__putshort(register u_int16_t s, register u_char *msgp) /* must match proto */
363#else 493#else
364__putshort(s, msgp) 494__putshort(s, msgp)
365 register u_int16_t s; 495 register u_int16_t s;
diff --git a/src/lib/libc/net/res_data.c b/src/lib/libc/net/res_data.c
new file mode 100644
index 0000000000..b0d19c36bb
--- /dev/null
+++ b/src/lib/libc/net/res_data.c
@@ -0,0 +1,117 @@
1/* $OpenBSD: res_data.c,v 1.1 1997/03/13 19:07:36 downsj Exp $ */
2
3/*
4 * ++Copyright++ 1995
5 * -
6 * Copyright (c) 1995
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 * -
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 * -
55 * --Copyright--
56 */
57
58#if defined(LIBC_SCCS) && !defined(lint)
59#if 0
60static char rcsid[] = "$From: res_data.c,v 8.2 1996/08/05 08:31:35 vixie Exp $";
61#else
62static char rcsid[] = "$OpenBSD: res_data.c,v 1.1 1997/03/13 19:07:36 downsj Exp $";
63#endif
64#endif /* LIBC_SCCS and not lint */
65
66#include <sys/types.h>
67#include <sys/param.h>
68#include <sys/socket.h>
69#include <sys/time.h>
70#include <netinet/in.h>
71#include <arpa/inet.h>
72#include <arpa/nameser.h>
73
74#include <stdio.h>
75#include <ctype.h>
76#include <resolv.h>
77#include <unistd.h>
78#include <stdlib.h>
79#include <string.h>
80
81const char *_res_opcodes[] = {
82 "QUERY",
83 "IQUERY",
84 "CQUERYM",
85 "CQUERYU", /* experimental */
86 "NOTIFY", /* experimental */
87 "5",
88 "6",
89 "7",
90 "8",
91 "UPDATEA",
92 "UPDATED",
93 "UPDATEDA",
94 "UPDATEM",
95 "UPDATEMA",
96 "ZONEINIT",
97 "ZONEREF",
98};
99
100const char *_res_resultcodes[] = {
101 "NOERROR",
102 "FORMERR",
103 "SERVFAIL",
104 "NXDOMAIN",
105 "NOTIMP",
106 "REFUSED",
107 "6",
108 "7",
109 "8",
110 "9",
111 "10",
112 "11",
113 "12",
114 "13",
115 "14",
116 "NOCHANGE",
117};
diff --git a/src/lib/libc/net/res_debug.c b/src/lib/libc/net/res_debug.c
index ae6c030a1f..7fd6d4a21c 100644
--- a/src/lib/libc/net/res_debug.c
+++ b/src/lib/libc/net/res_debug.c
@@ -1,7 +1,11 @@
1/*- 1/* $OpenBSD: res_debug.c,v 1.5 1997/03/13 19:07:37 downsj Exp $ */
2
3/*
4 * ++Copyright++ 1985, 1990, 1993
5 * -
2 * Copyright (c) 1985, 1990, 1993 6 * Copyright (c) 1985, 1990, 1993
3 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
4 * 8 *
5 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
7 * are met: 11 * are met:
@@ -48,63 +52,61 @@
48 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
49 * SOFTWARE. 53 * SOFTWARE.
50 * - 54 * -
55 * Portions Copyright (c) 1995 by International Business Machines, Inc.
56 *
57 * International Business Machines, Inc. (hereinafter called IBM) grants
58 * permission under its copyrights to use, copy, modify, and distribute this
59 * Software with or without fee, provided that the above copyright notice and
60 * all paragraphs of this notice appear in all copies, and that the name of IBM
61 * not be used in connection with the marketing of any product incorporating
62 * the Software or modifications thereof, without specific, written prior
63 * permission.
64 *
65 * To the extent it has a right to do so, IBM grants an immunity from suit
66 * under its patents, if any, for the use, sale or manufacture of products to
67 * the extent that such products are used for performing Domain Name System
68 * dynamic updates in TCP/IP networks by means of the Software. No immunity is
69 * granted for any product per se or for any other function of any product.
70 *
71 * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
72 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
73 * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
74 * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
75 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
76 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
51 * --Copyright-- 77 * --Copyright--
52 */ 78 */
53 79
54#if defined(LIBC_SCCS) && !defined(lint) 80#if defined(LIBC_SCCS) && !defined(lint)
55static char rcsid[] = "$OpenBSD: res_debug.c,v 1.4 1996/09/15 09:31:18 tholo Exp $"; 81#if 0
82static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
83static char rcsid[] = "$From: res_debug.c,v 8.19 1996/11/26 10:11:23 vixie Exp $";
84#else
85static char rcsid[] = "$OpenBSD: res_debug.c,v 1.5 1997/03/13 19:07:37 downsj Exp $";
86#endif
56#endif /* LIBC_SCCS and not lint */ 87#endif /* LIBC_SCCS and not lint */
57 88
58#include <sys/param.h> 89#include <sys/param.h>
90#include <sys/types.h>
91#include <sys/socket.h>
59#include <netinet/in.h> 92#include <netinet/in.h>
60#include <arpa/inet.h> 93#include <arpa/inet.h>
61#include <arpa/nameser.h> 94#include <arpa/nameser.h>
95
96#include <ctype.h>
97#include <netdb.h>
62#include <resolv.h> 98#include <resolv.h>
63#include <stdio.h> 99#include <stdio.h>
100#include <time.h>
101
102#include <stdlib.h>
64#include <string.h> 103#include <string.h>
65#include <netdb.h>
66 104
67void __fp_query(); 105extern const char *_res_opcodes[];
68 106extern const char *_res_resultcodes[];
69char *_res_opcodes[] = {
70 "QUERY",
71 "IQUERY",
72 "CQUERYM",
73 "CQUERYU", /* experimental */
74 "NOTIFY", /* experimental */
75 "5",
76 "6",
77 "7",
78 "8",
79 "UPDATEA",
80 "UPDATED",
81 "UPDATEDA",
82 "UPDATEM",
83 "UPDATEMA",
84 "ZONEINIT",
85 "ZONEREF",
86};
87 107
88char *_res_resultcodes[] = { 108/* XXX: we should use getservbyport() instead. */
89 "NOERROR", 109static const char *
90 "FORMERR",
91 "SERVFAIL",
92 "NXDOMAIN",
93 "NOTIMP",
94 "REFUSED",
95 "6",
96 "7",
97 "8",
98 "9",
99 "10",
100 "11",
101 "12",
102 "13",
103 "14",
104 "NOCHANGE",
105};
106
107static char *
108dewks(wks) 110dewks(wks)
109 int wks; 111 int wks;
110{ 112{
@@ -200,7 +202,8 @@ do_rrset(msg, len, cp, cnt, pflag, file, hs)
200 */ 202 */
201 sflag = (_res.pfcode & pflag); 203 sflag = (_res.pfcode & pflag);
202 if (n = ntohs(cnt)) { 204 if (n = ntohs(cnt)) {
203 if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) 205 if ((!_res.pfcode) ||
206 ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
204 fprintf(file, hs); 207 fprintf(file, hs);
205 while (--n >= 0) { 208 while (--n >= 0) {
206 if ((!_res.pfcode) || sflag) { 209 if ((!_res.pfcode) || sflag) {
@@ -208,20 +211,21 @@ do_rrset(msg, len, cp, cnt, pflag, file, hs)
208 } else { 211 } else {
209 unsigned int dlen; 212 unsigned int dlen;
210 cp += __dn_skipname(cp, cp + MAXCDNAME); 213 cp += __dn_skipname(cp, cp + MAXCDNAME);
211 cp += sizeof(u_int16_t); 214 cp += INT16SZ;
212 cp += sizeof(u_int16_t); 215 cp += INT16SZ;
213 cp += sizeof(u_int32_t); 216 cp += INT32SZ;
214 dlen = _getshort((u_char*)cp); 217 dlen = _getshort((u_char*)cp);
215 cp += sizeof(u_int16_t); 218 cp += INT16SZ;
216 cp += dlen; 219 cp += dlen;
217 } 220 }
218 if ((cp - msg) > len) 221 if ((cp - msg) > len)
219 return (NULL); 222 return (NULL);
220 } 223 }
221 if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) 224 if ((!_res.pfcode) ||
225 ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
222 putc('\n', file); 226 putc('\n', file);
223 } 227 }
224 return(cp); 228 return (cp);
225} 229}
226 230
227void 231void
@@ -268,7 +272,7 @@ __fp_nquery(msg, len, file)
268 if ((_res.options & RES_INIT) == 0 && res_init() == -1) 272 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
269 return; 273 return;
270 274
271#define TruncTest(x) if (x >= endMark) goto trunc 275#define TruncTest(x) if (x > endMark) goto trunc
272#define ErrorTest(x) if (x == NULL) goto error 276#define ErrorTest(x) if (x == NULL) goto error
273 277
274 /* 278 /*
@@ -276,9 +280,9 @@ __fp_nquery(msg, len, file)
276 */ 280 */
277 hp = (HEADER *)msg; 281 hp = (HEADER *)msg;
278 cp = msg + HFIXEDSZ; 282 cp = msg + HFIXEDSZ;
279 endMark = cp + len; 283 endMark = msg + len;
280 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) { 284 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) {
281 fprintf(file,";; ->>HEADER<<- opcode: %s, status: %s, id: %d", 285 fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d",
282 _res_opcodes[hp->opcode], 286 _res_opcodes[hp->opcode],
283 _res_resultcodes[hp->rcode], 287 _res_resultcodes[hp->rcode],
284 ntohs(hp->id)); 288 ntohs(hp->id));
@@ -287,22 +291,28 @@ __fp_nquery(msg, len, file)
287 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX)) 291 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX))
288 putc(';', file); 292 putc(';', file);
289 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) { 293 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
290 fprintf(file,"; flags:"); 294 fprintf(file, "; flags:");
291 if (hp->qr) 295 if (hp->qr)
292 fprintf(file," qr"); 296 fprintf(file, " qr");
293 if (hp->aa) 297 if (hp->aa)
294 fprintf(file," aa"); 298 fprintf(file, " aa");
295 if (hp->tc) 299 if (hp->tc)
296 fprintf(file," tc"); 300 fprintf(file, " tc");
297 if (hp->rd) 301 if (hp->rd)
298 fprintf(file," rd"); 302 fprintf(file, " rd");
299 if (hp->ra) 303 if (hp->ra)
300 fprintf(file," ra"); 304 fprintf(file, " ra");
305 if (hp->unused)
306 fprintf(file, " UNUSED-BIT-ON");
307 if (hp->ad)
308 fprintf(file, " ad");
309 if (hp->cd)
310 fprintf(file, " cd");
301 } 311 }
302 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) { 312 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
303 fprintf(file,"; Ques: %d", ntohs(hp->qdcount)); 313 fprintf(file, "; Ques: %d", ntohs(hp->qdcount));
304 fprintf(file,", Ans: %d", ntohs(hp->ancount)); 314 fprintf(file, ", Ans: %d", ntohs(hp->ancount));
305 fprintf(file,", Auth: %d", ntohs(hp->nscount)); 315 fprintf(file, ", Auth: %d", ntohs(hp->nscount));
306 fprintf(file, ", Addit: %d", ntohs(hp->arcount)); 316 fprintf(file, ", Addit: %d", ntohs(hp->arcount));
307 } 317 }
308 if ((!_res.pfcode) || (_res.pfcode & 318 if ((!_res.pfcode) || (_res.pfcode &
@@ -314,10 +324,10 @@ __fp_nquery(msg, len, file)
314 */ 324 */
315 if (n = ntohs(hp->qdcount)) { 325 if (n = ntohs(hp->qdcount)) {
316 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) 326 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
317 fprintf(file,";; QUESTIONS:\n"); 327 fprintf(file, ";; QUESTIONS:\n");
318 while (--n >= 0) { 328 while (--n >= 0) {
319 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) 329 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
320 fprintf(file,";;\t"); 330 fprintf(file, ";;\t");
321 TruncTest(cp); 331 TruncTest(cp);
322 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) 332 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
323 cp = p_cdnname(cp, msg, len, file); 333 cp = p_cdnname(cp, msg, len, file);
@@ -372,7 +382,7 @@ __fp_nquery(msg, len, file)
372 return; 382 return;
373 trunc: 383 trunc:
374 fprintf(file, "\n;; ...truncated\n"); 384 fprintf(file, "\n;; ...truncated\n");
375 return; 385 return;
376 error: 386 error:
377 fprintf(file, "\n;; ...malformed\n"); 387 fprintf(file, "\n;; ...malformed\n");
378} 388}
@@ -411,6 +421,30 @@ __p_cdname(cp, msg, file)
411 return (p_cdnname(cp, msg, PACKETSZ, file)); 421 return (p_cdnname(cp, msg, PACKETSZ, file));
412} 422}
413 423
424
425/* Return a fully-qualified domain name from a compressed name (with
426 length supplied). */
427
428const u_char *
429__p_fqnname(cp, msg, msglen, name, namelen)
430 const u_char *cp, *msg;
431 int msglen;
432 char *name;
433 int namelen;
434{
435 int n, newlen;
436
437 if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
438 return (NULL);
439 newlen = strlen (name);
440 if (newlen == 0 || name[newlen - 1] != '.')
441 if (newlen+1 >= namelen) /* Lack space for final dot */
442 return (NULL);
443 else
444 strcpy(name + newlen, ".");
445 return (cp + n);
446}
447
414/* XXX: the rest of these functions need to become length-limited, too. (vix) 448/* XXX: the rest of these functions need to become length-limited, too. (vix)
415 */ 449 */
416 450
@@ -420,18 +454,13 @@ __p_fqname(cp, msg, file)
420 FILE *file; 454 FILE *file;
421{ 455{
422 char name[MAXDNAME]; 456 char name[MAXDNAME];
423 int n; 457 const u_char *n;
424 458
425 if ((n = dn_expand(msg, cp + MAXCDNAME, cp, name, sizeof name)) < 0) 459 n = __p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
460 if (n == NULL)
426 return (NULL); 461 return (NULL);
427 if (name[0] == '\0') { 462 fputs(name, file);
428 putc('.', file); 463 return (n);
429 } else {
430 fputs(name, file);
431 if (name[strlen(name) - 1] != '.')
432 putc('.', file);
433 }
434 return (cp + n);
435} 464}
436 465
437/* 466/*
@@ -447,21 +476,27 @@ __p_rr(cp, msg, file)
447 const u_char *cp1, *cp2; 476 const u_char *cp1, *cp2;
448 u_int32_t tmpttl, t; 477 u_int32_t tmpttl, t;
449 int lcnt; 478 int lcnt;
479 u_int16_t keyflags;
480 char rrname[MAXDNAME]; /* The fqdn of this RR */
481 char base64_key[MAX_KEY_BASE64];
450 482
451 if ((_res.options & RES_INIT) == 0 && res_init() == -1) { 483 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
452 h_errno = NETDB_INTERNAL; 484 h_errno = NETDB_INTERNAL;
453 return (NULL); 485 return (NULL);
454 } 486 }
455 if ((cp = p_fqname(cp, msg, file)) == NULL) 487 cp = __p_fqnname(cp, msg, MAXCDNAME, rrname, sizeof rrname);
488 if (!cp)
456 return (NULL); /* compression error */ 489 return (NULL); /* compression error */
457 type = _getshort(cp); 490 fputs(rrname, file);
458 cp += sizeof(u_int16_t); 491
459 class = _getshort(cp); 492 type = _getshort((u_char*)cp);
460 cp += sizeof(u_int16_t); 493 cp += INT16SZ;
461 tmpttl = _getlong(cp); 494 class = _getshort((u_char*)cp);
462 cp += sizeof(u_int32_t); 495 cp += INT16SZ;
463 dlen = _getshort(cp); 496 tmpttl = _getlong((u_char*)cp);
464 cp += sizeof(u_int16_t); 497 cp += INT32SZ;
498 dlen = _getshort((u_char*)cp);
499 cp += INT16SZ;
465 cp1 = cp; 500 cp1 = cp;
466 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID)) 501 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID))
467 fprintf(file, "\t%lu", (u_long)tmpttl); 502 fprintf(file, "\t%lu", (u_long)tmpttl);
@@ -476,9 +511,9 @@ __p_rr(cp, msg, file)
476 switch (class) { 511 switch (class) {
477 case C_IN: 512 case C_IN:
478 case C_HS: 513 case C_HS:
479 bcopy(cp, (char *)&inaddr, sizeof(inaddr)); 514 bcopy(cp, (char *)&inaddr, INADDRSZ);
480 if (dlen == 4) { 515 if (dlen == 4) {
481 fprintf(file,"\t%s", inet_ntoa(inaddr)); 516 fprintf(file, "\t%s", inet_ntoa(inaddr));
482 cp += dlen; 517 cp += dlen;
483 } else if (dlen == 7) { 518 } else if (dlen == 7) {
484 char *address; 519 char *address;
@@ -486,11 +521,11 @@ __p_rr(cp, msg, file)
486 u_short port; 521 u_short port;
487 522
488 address = inet_ntoa(inaddr); 523 address = inet_ntoa(inaddr);
489 cp += sizeof(inaddr); 524 cp += INADDRSZ;
490 protocol = *cp; 525 protocol = *(u_char*)cp;
491 cp += sizeof(u_char); 526 cp += sizeof (u_char);
492 port = _getshort(cp); 527 port = _getshort((u_char*)cp);
493 cp += sizeof(u_int16_t); 528 cp += INT16SZ;
494 fprintf(file, "\t%s\t; proto %d, port %d", 529 fprintf(file, "\t%s\t; proto %d, port %d",
495 address, protocol, port); 530 address, protocol, port);
496 } 531 }
@@ -513,15 +548,27 @@ __p_rr(cp, msg, file)
513 case T_HINFO: 548 case T_HINFO:
514 case T_ISDN: 549 case T_ISDN:
515 cp2 = cp + dlen; 550 cp2 = cp + dlen;
516 if (n = *cp++) { 551 (void) fputs("\t\"", file);
517 fprintf(file,"\t%.*s", n, cp); 552 if ((n = (unsigned char) *cp++) != 0) {
518 cp += n; 553 for (c = n; c > 0 && cp < cp2; c--) {
554 if (strchr("\n\"\\", *cp))
555 (void) putc('\\', file);
556 (void) putc(*cp++, file);
557 }
519 } 558 }
520 if ((cp < cp2) && (n = *cp++)) { 559 putc('"', file);
521 fprintf(file,"\t%.*s", n, cp); 560 if (cp < cp2 && (n = (unsigned char) *cp++) != 0) {
522 cp += n; 561 (void) fputs ("\t\"", file);
523 } else if (type == T_HINFO) 562 for (c = n; c > 0 && cp < cp2; c--) {
563 if (strchr("\n\"\\", *cp))
564 (void) putc('\\', file);
565 (void) putc(*cp++, file);
566 }
567 putc('"', file);
568 } else if (type == T_HINFO) {
569 (void) fputs("\"?\"", file);
524 fprintf(file, "\n;; *** Warning *** OS-type missing"); 570 fprintf(file, "\n;; *** Warning *** OS-type missing");
571 }
525 break; 572 break;
526 573
527 case T_SOA: 574 case T_SOA:
@@ -532,18 +579,18 @@ __p_rr(cp, msg, file)
532 if ((cp = p_fqname(cp, msg, file)) == NULL) 579 if ((cp = p_fqname(cp, msg, file)) == NULL)
533 return (NULL); 580 return (NULL);
534 fputs(" (\n", file); 581 fputs(" (\n", file);
535 t = _getlong(cp); cp += sizeof(u_int32_t); 582 t = _getlong((u_char*)cp); cp += INT32SZ;
536 fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t); 583 fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t);
537 t = _getlong(cp); cp += sizeof(u_int32_t); 584 t = _getlong((u_char*)cp); cp += INT32SZ;
538 fprintf(file, "\t\t\t%lu\t; refresh (%s)\n", 585 fprintf(file, "\t\t\t%lu\t; refresh (%s)\n",
539 (u_long)t, __p_time(t)); 586 (u_long)t, __p_time(t));
540 t = _getlong(cp); cp += sizeof(u_int32_t); 587 t = _getlong((u_char*)cp); cp += INT32SZ;
541 fprintf(file, "\t\t\t%lu\t; retry (%s)\n", 588 fprintf(file, "\t\t\t%lu\t; retry (%s)\n",
542 (u_long)t, __p_time(t)); 589 (u_long)t, __p_time(t));
543 t = _getlong(cp); cp += sizeof(u_int32_t); 590 t = _getlong((u_char*)cp); cp += INT32SZ;
544 fprintf(file, "\t\t\t%lu\t; expire (%s)\n", 591 fprintf(file, "\t\t\t%lu\t; expire (%s)\n",
545 (u_long)t, __p_time(t)); 592 (u_long)t, __p_time(t));
546 t = _getlong(cp); cp += sizeof(u_int32_t); 593 t = _getlong((u_char*)cp); cp += INT32SZ;
547 fprintf(file, "\t\t\t%lu )\t; minimum (%s)", 594 fprintf(file, "\t\t\t%lu )\t; minimum (%s)",
548 (u_long)t, __p_time(t)); 595 (u_long)t, __p_time(t));
549 break; 596 break;
@@ -551,14 +598,14 @@ __p_rr(cp, msg, file)
551 case T_MX: 598 case T_MX:
552 case T_AFSDB: 599 case T_AFSDB:
553 case T_RT: 600 case T_RT:
554 fprintf(file, "\t%d ", _getshort(cp)); 601 fprintf(file, "\t%d ", _getshort((u_char*)cp));
555 cp += INT16SZ; 602 cp += INT16SZ;
556 if ((cp = p_fqname(cp, msg, file)) == NULL) 603 if ((cp = p_fqname(cp, msg, file)) == NULL)
557 return (NULL); 604 return (NULL);
558 break; 605 break;
559 606
560 case T_PX: 607 case T_PX:
561 fprintf(file, "\t%d ", _getshort(cp)); 608 fprintf(file, "\t%d ", _getshort((u_char*)cp));
562 cp += INT16SZ; 609 cp += INT16SZ;
563 if ((cp = p_fqname(cp, msg, file)) == NULL) 610 if ((cp = p_fqname(cp, msg, file)) == NULL)
564 return (NULL); 611 return (NULL);
@@ -567,28 +614,93 @@ __p_rr(cp, msg, file)
567 return (NULL); 614 return (NULL);
568 break; 615 break;
569 616
570 case T_TXT:
571 case T_X25: 617 case T_X25:
618 cp2 = cp + dlen;
572 (void) fputs("\t\"", file); 619 (void) fputs("\t\"", file);
620 if ((n = (unsigned char) *cp++) != 0) {
621 for (c = n; c > 0 && cp < cp2; c--) {
622 if (strchr("\n\"\\", *cp))
623 (void) putc('\\', file);
624 (void) putc(*cp++, file);
625 }
626 }
627 putc('"', file);
628 break;
629
630 case T_TXT:
631 (void) putc('\t', file);
573 cp2 = cp1 + dlen; 632 cp2 = cp1 + dlen;
574 while (cp < cp2) { 633 while (cp < cp2) {
634 putc('"', file);
575 if (n = (unsigned char) *cp++) { 635 if (n = (unsigned char) *cp++) {
576 for (c = n; c > 0 && cp < cp2; c--) 636 for (c = n; c > 0 && cp < cp2; c--) {
577 if ((*cp == '\n') || (*cp == '"')) { 637 if (strchr("\n\"\\", *cp))
578 (void) putc('\\', file); 638 (void) putc('\\', file);
579 (void) putc(*cp++, file); 639 (void) putc(*cp++, file);
580 } else 640 }
581 (void) putc(*cp++, file);
582 } 641 }
642 putc('"', file);
643 if (cp < cp2)
644 putc(' ', file);
583 } 645 }
584 putc('"', file); 646 break;
585 break;
586 647
587 case T_NSAP: 648 case T_NSAP:
588 (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL)); 649 (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
589 cp += dlen; 650 cp += dlen;
590 break; 651 break;
591 652
653 case T_AAAA: {
654 char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
655
656 fprintf(file, "\t%s", inet_ntop(AF_INET6, cp, t, sizeof t));
657 cp += dlen;
658 break;
659 }
660
661 case T_LOC: {
662 char t[255];
663
664 fprintf(file, "\t%s", loc_ntoa(cp, t));
665 cp += dlen;
666 break;
667 }
668
669 case T_NAPTR: {
670 u_int order, preference;
671
672 order = _getshort(cp); cp += INT16SZ;
673 preference = _getshort(cp); cp += INT16SZ;
674 fprintf(file, "\t%u %u ",order, preference);
675 /* Flags */
676 n = *cp++;
677 fprintf(file,"\"%.*s\" ", (int)n, cp);
678 cp += n;
679 /* Service */
680 n = *cp++;
681 fprintf(file,"\"%.*s\" ", (int)n, cp);
682 cp += n;
683 /* Regexp */
684 n = *cp++;
685 fprintf(file,"\"%.*s\" ", (int)n, cp);
686 cp += n;
687 if ((cp = p_fqname(cp, msg, file)) == NULL)
688 return (NULL);
689 break;
690 }
691
692 case T_SRV: {
693 u_int priority, weight, port;
694
695 priority = _getshort(cp); cp += INT16SZ;
696 weight = _getshort(cp); cp += INT16SZ;
697 port = _getshort(cp); cp += INT16SZ;
698 fprintf(file, "\t%u %u %u ", priority, weight, port);
699 if ((cp = p_fqname(cp, msg, file)) == NULL)
700 return (NULL);
701 break;
702 }
703
592 case T_MINFO: 704 case T_MINFO:
593 case T_RP: 705 case T_RP:
594 putc('\t', file); 706 putc('\t', file);
@@ -601,33 +713,33 @@ __p_rr(cp, msg, file)
601 713
602 case T_UINFO: 714 case T_UINFO:
603 putc('\t', file); 715 putc('\t', file);
604 fputs((char *) cp, file); 716 fputs((char *)cp, file);
605 cp += dlen; 717 cp += dlen;
606 break; 718 break;
607 719
608 case T_UID: 720 case T_UID:
609 case T_GID: 721 case T_GID:
610 if (dlen == 4) { 722 if (dlen == 4) {
611 fprintf(file,"\t%u", _getlong(cp)); 723 fprintf(file, "\t%u", _getlong((u_char*)cp));
612 cp += sizeof(int32_t); 724 cp += INT32SZ;
613 } 725 }
614 break; 726 break;
615 727
616 case T_WKS: 728 case T_WKS:
617 if (dlen < sizeof(u_int32_t) + 1) 729 if (dlen < INT32SZ + 1)
618 break; 730 break;
619 bcopy(cp, (char *)&inaddr, sizeof(inaddr)); 731 bcopy(cp, (char *)&inaddr, INADDRSZ);
620 cp += sizeof(u_int32_t); 732 cp += INT32SZ;
621 fprintf(file, "\t%s %s ( ", 733 fprintf(file, "\t%s %s ( ",
622 inet_ntoa(inaddr), 734 inet_ntoa(inaddr),
623 deproto((int) *cp)); 735 deproto((int) *cp));
624 cp += sizeof(u_char); 736 cp += sizeof (u_char);
625 n = 0; 737 n = 0;
626 lcnt = 0; 738 lcnt = 0;
627 while (cp < cp1 + dlen) { 739 while (cp < cp1 + dlen) {
628 c = *cp++; 740 c = *cp++;
629 do { 741 do {
630 if (c & 0200) { 742 if (c & 0200) {
631 if (lcnt == 0) { 743 if (lcnt == 0) {
632 fputs("\n\t\t\t", file); 744 fputs("\n\t\t\t", file);
633 lcnt = 5; 745 lcnt = 5;
@@ -636,12 +748,78 @@ __p_rr(cp, msg, file)
636 putc(' ', file); 748 putc(' ', file);
637 lcnt--; 749 lcnt--;
638 } 750 }
639 c <<= 1; 751 c <<= 1;
640 } while (++n & 07); 752 } while (++n & 07);
641 } 753 }
642 putc(')', file); 754 putc(')', file);
643 break; 755 break;
644 756
757 case T_KEY:
758 putc('\t', file);
759 keyflags = _getshort(cp);
760 cp += 2;
761 fprintf(file,"0x%04x", keyflags ); /* flags */
762 fprintf(file," %u", *cp++); /* protocol */
763 fprintf(file," %u (", *cp++); /* algorithm */
764
765 n = b64_ntop(cp, (cp1 + dlen) - cp,
766 base64_key, sizeof base64_key);
767 for (c = 0; c < n; ++c) {
768 if (0 == (c & 0x3F))
769 fprintf(file, "\n\t");
770 putc(base64_key[c], file); /* public key data */
771 }
772
773 fprintf(file, " )");
774 if (n < 0)
775 fprintf(file, "\t; BAD BASE64");
776 fflush(file);
777 cp = cp1 + dlen;
778 break;
779
780 case T_SIG:
781 type = _getshort((u_char*)cp);
782 cp += INT16SZ;
783 fprintf(file, " %s", p_type(type));
784 fprintf(file, "\t%d", *cp++); /* algorithm */
785 /* Check label value and print error if wrong. */
786 n = *cp++;
787 c = dn_count_labels (rrname);
788 if (n != c)
789 fprintf(file, "\t; LABELS WRONG (%d should be %d)\n\t",
790 n, c);
791 /* orig ttl */
792 n = _getlong((u_char*)cp);
793 if (n != tmpttl)
794 fprintf(file, " %u", n);
795 cp += INT32SZ;
796 /* sig expire */
797 fprintf(file, " (\n\t%s",
798 __p_secstodate(_getlong((u_char*)cp)));
799 cp += INT32SZ;
800 /* time signed */
801 fprintf(file, " %s", __p_secstodate(_getlong((u_char*)cp)));
802 cp += INT32SZ;
803 /* sig footprint */
804 fprintf(file," %u ", _getshort((u_char*)cp));
805 cp += INT16SZ;
806 /* signer's name */
807 cp = p_fqname(cp, msg, file);
808 n = b64_ntop(cp, (cp1 + dlen) - cp,
809 base64_key, sizeof base64_key);
810 for (c = 0; c < n; c++) {
811 if (0 == (c & 0x3F))
812 fprintf (file, "\n\t");
813 putc(base64_key[c], file); /* signature */
814 }
815 /* Clean up... */
816 fprintf(file, " )");
817 if (n < 0)
818 fprintf(file, "\t; BAD BASE64");
819 fflush(file);
820 cp = cp1+dlen;
821 break;
822
645#ifdef ALLOW_T_UNSPEC 823#ifdef ALLOW_T_UNSPEC
646 case T_UNSPEC: 824 case T_UNSPEC:
647 { 825 {
@@ -660,7 +838,7 @@ __p_rr(cp, msg, file)
660#endif /* ALLOW_T_UNSPEC */ 838#endif /* ALLOW_T_UNSPEC */
661 839
662 default: 840 default:
663 fprintf(file,"\t?%d?", type); 841 fprintf(file, "\t?%d?", type);
664 cp += dlen; 842 cp += dlen;
665 } 843 }
666#if 0 844#if 0
@@ -669,7 +847,7 @@ __p_rr(cp, msg, file)
669 putc('\n', file); 847 putc('\n', file);
670#endif 848#endif
671 if (cp - cp1 != dlen) { 849 if (cp - cp1 != dlen) {
672 fprintf(file,";; packet size error (found %d, dlen was %d)\n", 850 fprintf(file, ";; packet size error (found %d, dlen was %d)\n",
673 cp - cp1, dlen); 851 cp - cp1, dlen);
674 cp = NULL; 852 cp = NULL;
675 } 853 }
@@ -677,54 +855,144 @@ __p_rr(cp, msg, file)
677} 855}
678 856
679/* 857/*
858 * Names of RR classes and qclasses. Classes and qclasses are the same, except
859 * that C_ANY is a qclass but not a class. (You can ask for records of class
860 * C_ANY, but you can't have any records of that class in the database.)
861 */
862const struct res_sym __p_class_syms[] = {
863 {C_IN, "IN"},
864 {C_CHAOS, "CHAOS"},
865 {C_HS, "HS"},
866 {C_HS, "HESIOD"},
867 {C_ANY, "ANY"},
868 {C_IN, (char *)0}
869};
870
871/*
872 * Names of RR types and qtypes. Types and qtypes are the same, except
873 * that T_ANY is a qtype but not a type. (You can ask for records of type
874 * T_ANY, but you can't have any records of that type in the database.)
875 */
876const struct res_sym __p_type_syms[] = {
877 {T_A, "A", "address"},
878 {T_NS, "NS", "name server"},
879 {T_MD, "MD", "mail destination (deprecated)"},
880 {T_MF, "MF", "mail forwarder (deprecated)"},
881 {T_CNAME, "CNAME", "canonical name"},
882 {T_SOA, "SOA", "start of authority"},
883 {T_MB, "MB", "mailbox"},
884 {T_MG, "MG", "mail group member"},
885 {T_MR, "MR", "mail rename"},
886 {T_NULL, "NULL", "null"},
887 {T_WKS, "WKS", "well-known service (deprecated)"},
888 {T_PTR, "PTR", "domain name pointer"},
889 {T_HINFO, "HINFO", "host information"},
890 {T_MINFO, "MINFO", "mailbox information"},
891 {T_MX, "MX", "mail exchanger"},
892 {T_TXT, "TXT", "text"},
893 {T_RP, "RP", "responsible person"},
894 {T_AFSDB, "AFSDB", "DCE or AFS server"},
895 {T_X25, "X25", "X25 address"},
896 {T_ISDN, "ISDN", "ISDN address"},
897 {T_RT, "RT", "router"},
898 {T_NSAP, "NSAP", "nsap address"},
899 {T_NSAP_PTR, "NSAP_PTR", "domain name pointer"},
900 {T_SIG, "SIG", "signature"},
901 {T_KEY, "KEY", "key"},
902 {T_PX, "PX", "mapping information"},
903 {T_GPOS, "GPOS", "geographical position (withdrawn)"},
904 {T_AAAA, "AAAA", "IPv6 address"},
905 {T_LOC, "LOC", "location"},
906 {T_NXT, "NXT", "next valid name (unimplemented)"},
907 {T_EID, "EID", "endpoint identifier (unimplemented)"},
908 {T_NIMLOC, "NIMLOC", "NIMROD locator (unimplemented)"},
909 {T_SRV, "SRV", "server selection"},
910 {T_ATMA, "ATMA", "ATM address (unimplemented)"},
911 {T_IXFR, "IXFR", "incremental zone transfer"},
912 {T_AXFR, "AXFR", "zone transfer"},
913 {T_MAILB, "MAILB", "mailbox-related data (deprecated)"},
914 {T_MAILA, "MAILA", "mail agent (deprecated)"},
915 {T_UINFO, "UINFO", "user information (nonstandard)"},
916 {T_UID, "UID", "user ID (nonstandard)"},
917 {T_GID, "GID", "group ID (nonstandard)"},
918 {T_NAPTR, "NAPTR", "URN Naming Authority"},
919#ifdef ALLOW_T_UNSPEC
920 {T_UNSPEC, "UNSPEC", "unspecified data (nonstandard)"},
921#endif /* ALLOW_T_UNSPEC */
922 {T_ANY, "ANY", "\"any\""},
923 {0, NULL, NULL}
924};
925
926int
927__sym_ston(syms, name, success)
928 const struct res_sym *syms;
929 char *name;
930 int *success;
931{
932 for (NULL; syms->name != 0; syms++) {
933 if (strcasecmp (name, syms->name) == 0) {
934 if (success)
935 *success = 1;
936 return (syms->number);
937 }
938 }
939 if (success)
940 *success = 0;
941 return (syms->number); /* The default value. */
942}
943
944const char *
945__sym_ntos(syms, number, success)
946 const struct res_sym *syms;
947 int number;
948 int *success;
949{
950 static char unname[20];
951
952 for (NULL; syms->name != 0; syms++) {
953 if (number == syms->number) {
954 if (success)
955 *success = 1;
956 return (syms->name);
957 }
958 }
959
960 sprintf (unname, "%d", number);
961 if (success)
962 *success = 0;
963 return (unname);
964}
965
966
967const char *
968__sym_ntop(syms, number, success)
969 const struct res_sym *syms;
970 int number;
971 int *success;
972{
973 static char unname[20];
974
975 for (NULL; syms->name != 0; syms++) {
976 if (number == syms->number) {
977 if (success)
978 *success = 1;
979 return (syms->humanname);
980 }
981 }
982 sprintf(unname, "%d", number);
983 if (success)
984 *success = 0;
985 return (unname);
986}
987
988/*
680 * Return a string for the type 989 * Return a string for the type
681 */ 990 */
682const char * 991const char *
683__p_type(type) 992__p_type(type)
684 int type; 993 int type;
685{ 994{
686 static char nbuf[20]; 995 return (__sym_ntos (__p_type_syms, type, (int *)0));
687
688 switch (type) {
689 case T_A: return "A";
690 case T_NS: return "NS";
691 case T_CNAME: return "CNAME";
692 case T_SOA: return "SOA";
693 case T_MB: return "MB";
694 case T_MG: return "MG";
695 case T_MR: return "MR";
696 case T_NULL: return "NULL";
697 case T_WKS: return "WKS";
698 case T_PTR: return "PTR";
699 case T_HINFO: return "HINFO";
700 case T_MINFO: return "MINFO";
701 case T_MX: return "MX";
702 case T_TXT: return "TXT";
703 case T_RP: return "RP";
704 case T_AFSDB: return "AFSDB";
705 case T_X25: return "X25";
706 case T_ISDN: return "ISDN";
707 case T_RT: return "RT";
708 case T_NSAP: return "NSAP";
709 case T_NSAP_PTR: return "NSAP_PTR";
710 case T_SIG: return "SIG";
711 case T_KEY: return "KEY";
712 case T_PX: return "PX";
713 case T_GPOS: return "GPOS";
714 case T_AAAA: return "AAAA";
715 case T_LOC: return "LOC";
716 case T_AXFR: return "AXFR";
717 case T_MAILB: return "MAILB";
718 case T_MAILA: return "MAILA";
719 case T_ANY: return "ANY";
720 case T_UINFO: return "UINFO";
721 case T_UID: return "UID";
722 case T_GID: return "GID";
723#ifdef ALLOW_T_UNSPEC
724 case T_UNSPEC: return "UNSPEC";
725#endif /* ALLOW_T_UNSPEC */
726 default: (void)sprintf(nbuf, "%d", type); return (nbuf);
727 }
728} 996}
729 997
730/* 998/*
@@ -734,14 +1002,7 @@ const char *
734__p_class(class) 1002__p_class(class)
735 int class; 1003 int class;
736{ 1004{
737 static char nbuf[20]; 1005 return (__sym_ntos (__p_class_syms, class, (int *)0));
738
739 switch (class) {
740 case C_IN: return "IN";
741 case C_HS: return "HS";
742 case C_ANY: return "ANY";
743 default: (void)sprintf(nbuf, "%d", class); return (nbuf);
744 }
745} 1006}
746 1007
747/* 1008/*
@@ -774,8 +1035,8 @@ __p_option(option)
774/* 1035/*
775 * Return a mnemonic for a time to live 1036 * Return a mnemonic for a time to live
776 */ 1037 */
777char * 1038const char *
778__p_time(value) 1039p_time(value)
779 u_int32_t value; 1040 u_int32_t value;
780{ 1041{
781 static char nbuf[40]; 1042 static char nbuf[40];
@@ -784,7 +1045,7 @@ __p_time(value)
784 1045
785 if (value == 0) { 1046 if (value == 0) {
786 strcpy(nbuf, "0 secs"); 1047 strcpy(nbuf, "0 secs");
787 return(nbuf); 1048 return (nbuf);
788 } 1049 }
789 1050
790 secs = value % 60; 1051 secs = value % 60;
@@ -819,5 +1080,437 @@ __p_time(value)
819 *p++ = ' '; 1080 *p++ = ' ';
820 (void)sprintf(p, "%d sec%s", PLURALIZE(secs)); 1081 (void)sprintf(p, "%d sec%s", PLURALIZE(secs));
821 } 1082 }
822 return(nbuf); 1083 return (nbuf);
1084}
1085
1086/*
1087 * routines to convert between on-the-wire RR format and zone file format.
1088 * Does not contain conversion to/from decimal degrees; divide or multiply
1089 * by 60*60*1000 for that.
1090 */
1091
1092static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
1093 1000000,10000000,100000000,1000000000};
1094
1095/* takes an XeY precision/size value, returns a string representation. */
1096static const char *
1097precsize_ntoa(prec)
1098 u_int8_t prec;
1099{
1100 static char retbuf[sizeof "90000000.00"];
1101 unsigned long val;
1102 int mantissa, exponent;
1103
1104 mantissa = (int)((prec >> 4) & 0x0f) % 10;
1105 exponent = (int)((prec >> 0) & 0x0f) % 10;
1106
1107 val = mantissa * poweroften[exponent];
1108
1109 (void) sprintf(retbuf, "%ld.%.2ld", val/100, val%100);
1110 return (retbuf);
1111}
1112
1113/* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */
1114static u_int8_t
1115precsize_aton(strptr)
1116 char **strptr;
1117{
1118 unsigned int mval = 0, cmval = 0;
1119 u_int8_t retval = 0;
1120 register char *cp;
1121 register int exponent;
1122 register int mantissa;
1123
1124 cp = *strptr;
1125
1126 while (isdigit(*cp))
1127 mval = mval * 10 + (*cp++ - '0');
1128
1129 if (*cp == '.') { /* centimeters */
1130 cp++;
1131 if (isdigit(*cp)) {
1132 cmval = (*cp++ - '0') * 10;
1133 if (isdigit(*cp)) {
1134 cmval += (*cp++ - '0');
1135 }
1136 }
1137 }
1138 cmval = (mval * 100) + cmval;
1139
1140 for (exponent = 0; exponent < 9; exponent++)
1141 if (cmval < poweroften[exponent+1])
1142 break;
1143
1144 mantissa = cmval / poweroften[exponent];
1145 if (mantissa > 9)
1146 mantissa = 9;
1147
1148 retval = (mantissa << 4) | exponent;
1149
1150 *strptr = cp;
1151
1152 return (retval);
1153}
1154
1155/* converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */
1156static u_int32_t
1157latlon2ul(latlonstrptr,which)
1158 char **latlonstrptr;
1159 int *which;
1160{
1161 register char *cp;
1162 u_int32_t retval;
1163 int deg = 0, min = 0, secs = 0, secsfrac = 0;
1164
1165 cp = *latlonstrptr;
1166
1167 while (isdigit(*cp))
1168 deg = deg * 10 + (*cp++ - '0');
1169
1170 while (isspace(*cp))
1171 cp++;
1172
1173 if (!(isdigit(*cp)))
1174 goto fndhemi;
1175
1176 while (isdigit(*cp))
1177 min = min * 10 + (*cp++ - '0');
1178
1179 while (isspace(*cp))
1180 cp++;
1181
1182 if (!(isdigit(*cp)))
1183 goto fndhemi;
1184
1185 while (isdigit(*cp))
1186 secs = secs * 10 + (*cp++ - '0');
1187
1188 if (*cp == '.') { /* decimal seconds */
1189 cp++;
1190 if (isdigit(*cp)) {
1191 secsfrac = (*cp++ - '0') * 100;
1192 if (isdigit(*cp)) {
1193 secsfrac += (*cp++ - '0') * 10;
1194 if (isdigit(*cp)) {
1195 secsfrac += (*cp++ - '0');
1196 }
1197 }
1198 }
1199 }
1200
1201 while (!isspace(*cp)) /* if any trailing garbage */
1202 cp++;
1203
1204 while (isspace(*cp))
1205 cp++;
1206
1207 fndhemi:
1208 switch (*cp) {
1209 case 'N': case 'n':
1210 case 'E': case 'e':
1211 retval = ((unsigned)1<<31)
1212 + (((((deg * 60) + min) * 60) + secs) * 1000)
1213 + secsfrac;
1214 break;
1215 case 'S': case 's':
1216 case 'W': case 'w':
1217 retval = ((unsigned)1<<31)
1218 - (((((deg * 60) + min) * 60) + secs) * 1000)
1219 - secsfrac;
1220 break;
1221 default:
1222 retval = 0; /* invalid value -- indicates error */
1223 break;
1224 }
1225
1226 switch (*cp) {
1227 case 'N': case 'n':
1228 case 'S': case 's':
1229 *which = 1; /* latitude */
1230 break;
1231 case 'E': case 'e':
1232 case 'W': case 'w':
1233 *which = 2; /* longitude */
1234 break;
1235 default:
1236 *which = 0; /* error */
1237 break;
1238 }
1239
1240 cp++; /* skip the hemisphere */
1241
1242 while (!isspace(*cp)) /* if any trailing garbage */
1243 cp++;
1244
1245 while (isspace(*cp)) /* move to next field */
1246 cp++;
1247
1248 *latlonstrptr = cp;
1249
1250 return (retval);
1251}
1252
1253/* converts a zone file representation in a string to an RDATA on-the-wire
1254 * representation. */
1255int
1256loc_aton(ascii, binary)
1257 const char *ascii;
1258 u_char *binary;
1259{
1260 const char *cp, *maxcp;
1261 u_char *bcp;
1262
1263 u_int32_t latit = 0, longit = 0, alt = 0;
1264 u_int32_t lltemp1 = 0, lltemp2 = 0;
1265 int altmeters = 0, altfrac = 0, altsign = 1;
1266 u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */
1267 u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */
1268 u_int8_t siz = 0x12; /* default = 1e2 cm = 1.00m */
1269 int which1 = 0, which2 = 0;
1270
1271 cp = ascii;
1272 maxcp = cp + strlen(ascii);
1273
1274 lltemp1 = latlon2ul(&cp, &which1);
1275
1276 lltemp2 = latlon2ul(&cp, &which2);
1277
1278 switch (which1 + which2) {
1279 case 3: /* 1 + 2, the only valid combination */
1280 if ((which1 == 1) && (which2 == 2)) { /* normal case */
1281 latit = lltemp1;
1282 longit = lltemp2;
1283 } else if ((which1 == 2) && (which2 == 1)) { /* reversed */
1284 longit = lltemp1;
1285 latit = lltemp2;
1286 } else { /* some kind of brokenness */
1287 return (0);
1288 }
1289 break;
1290 default: /* we didn't get one of each */
1291 return (0);
1292 }
1293
1294 /* altitude */
1295 if (*cp == '-') {
1296 altsign = -1;
1297 cp++;
1298 }
1299
1300 if (*cp == '+')
1301 cp++;
1302
1303 while (isdigit(*cp))
1304 altmeters = altmeters * 10 + (*cp++ - '0');
1305
1306 if (*cp == '.') { /* decimal meters */
1307 cp++;
1308 if (isdigit(*cp)) {
1309 altfrac = (*cp++ - '0') * 10;
1310 if (isdigit(*cp)) {
1311 altfrac += (*cp++ - '0');
1312 }
1313 }
1314 }
1315
1316 alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
1317
1318 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1319 cp++;
1320
1321 while (isspace(*cp) && (cp < maxcp))
1322 cp++;
1323
1324 if (cp >= maxcp)
1325 goto defaults;
1326
1327 siz = precsize_aton(&cp);
1328
1329 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1330 cp++;
1331
1332 while (isspace(*cp) && (cp < maxcp))
1333 cp++;
1334
1335 if (cp >= maxcp)
1336 goto defaults;
1337
1338 hp = precsize_aton(&cp);
1339
1340 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1341 cp++;
1342
1343 while (isspace(*cp) && (cp < maxcp))
1344 cp++;
1345
1346 if (cp >= maxcp)
1347 goto defaults;
1348
1349 vp = precsize_aton(&cp);
1350
1351 defaults:
1352
1353 bcp = binary;
1354 *bcp++ = (u_int8_t) 0; /* version byte */
1355 *bcp++ = siz;
1356 *bcp++ = hp;
1357 *bcp++ = vp;
1358 PUTLONG(latit,bcp);
1359 PUTLONG(longit,bcp);
1360 PUTLONG(alt,bcp);
1361
1362 return (16); /* size of RR in octets */
1363}
1364
1365/* takes an on-the-wire LOC RR and formats it in a human readable format. */
1366const char *
1367loc_ntoa(binary, ascii)
1368 const u_char *binary;
1369 char *ascii;
1370{
1371 static char *error = "?";
1372 register const u_char *cp = binary;
1373
1374 int latdeg, latmin, latsec, latsecfrac;
1375 int longdeg, longmin, longsec, longsecfrac;
1376 char northsouth, eastwest;
1377 int altmeters, altfrac, altsign;
1378
1379 const int referencealt = 100000 * 100;
1380
1381 int32_t latval, longval, altval;
1382 u_int32_t templ;
1383 u_int8_t sizeval, hpval, vpval, versionval;
1384
1385 char *sizestr, *hpstr, *vpstr;
1386
1387 versionval = *cp++;
1388
1389 if (versionval) {
1390 sprintf(ascii, "; error: unknown LOC RR version");
1391 return (ascii);
1392 }
1393
1394 sizeval = *cp++;
1395
1396 hpval = *cp++;
1397 vpval = *cp++;
1398
1399 GETLONG(templ, cp);
1400 latval = (templ - ((unsigned)1<<31));
1401
1402 GETLONG(templ, cp);
1403 longval = (templ - ((unsigned)1<<31));
1404
1405 GETLONG(templ, cp);
1406 if (templ < referencealt) { /* below WGS 84 spheroid */
1407 altval = referencealt - templ;
1408 altsign = -1;
1409 } else {
1410 altval = templ - referencealt;
1411 altsign = 1;
1412 }
1413
1414 if (latval < 0) {
1415 northsouth = 'S';
1416 latval = -latval;
1417 } else
1418 northsouth = 'N';
1419
1420 latsecfrac = latval % 1000;
1421 latval = latval / 1000;
1422 latsec = latval % 60;
1423 latval = latval / 60;
1424 latmin = latval % 60;
1425 latval = latval / 60;
1426 latdeg = latval;
1427
1428 if (longval < 0) {
1429 eastwest = 'W';
1430 longval = -longval;
1431 } else
1432 eastwest = 'E';
1433
1434 longsecfrac = longval % 1000;
1435 longval = longval / 1000;
1436 longsec = longval % 60;
1437 longval = longval / 60;
1438 longmin = longval % 60;
1439 longval = longval / 60;
1440 longdeg = longval;
1441
1442 altfrac = altval % 100;
1443 altmeters = (altval / 100) * altsign;
1444
1445 if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL)
1446 sizestr = error;
1447 if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL)
1448 hpstr = error;
1449 if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL)
1450 vpstr = error;
1451
1452 sprintf(ascii,
1453 "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
1454 latdeg, latmin, latsec, latsecfrac, northsouth,
1455 longdeg, longmin, longsec, longsecfrac, eastwest,
1456 altmeters, altfrac, sizestr, hpstr, vpstr);
1457
1458 if (sizestr != error)
1459 free(sizestr);
1460 if (hpstr != error)
1461 free(hpstr);
1462 if (vpstr != error)
1463 free(vpstr);
1464
1465 return (ascii);
1466}
1467
1468
1469/* Return the number of DNS hierarchy levels in the name. */
1470int
1471__dn_count_labels(name)
1472 char *name;
1473{
1474 int i, len, count;
1475
1476 len = strlen(name);
1477
1478 for(i = 0, count = 0; i < len; i++) {
1479 if (name[i] == '.')
1480 count++;
1481 }
1482
1483 /* don't count initial wildcard */
1484 if (name[0] == '*')
1485 if (count)
1486 count--;
1487
1488 /* don't count the null label for root. */
1489 /* if terminating '.' not found, must adjust */
1490 /* count to include last label */
1491 if (len > 0 && name[len-1] != '.')
1492 count++;
1493 return (count);
1494}
1495
1496
1497/*
1498 * Make dates expressed in seconds-since-Jan-1-1970 easy to read.
1499 * SIG records are required to be printed like this, by the Secure DNS RFC.
1500 */
1501char *
1502__p_secstodate (secs)
1503 unsigned long secs;
1504{
1505 static char output[15]; /* YYYYMMDDHHMMSS and null */
1506 time_t clock = secs;
1507 struct tm *time;
1508
1509 time = gmtime(&clock);
1510 time->tm_year += 1900;
1511 time->tm_mon += 1;
1512 sprintf(output, "%04d%02d%02d%02d%02d%02d",
1513 time->tm_year, time->tm_mon, time->tm_mday,
1514 time->tm_hour, time->tm_min, time->tm_sec);
1515 return (output);
823} 1516}
diff --git a/src/lib/libc/net/res_init.c b/src/lib/libc/net/res_init.c
index 6f4f39ef9f..46b9361126 100644
--- a/src/lib/libc/net/res_init.c
+++ b/src/lib/libc/net/res_init.c
@@ -1,7 +1,11 @@
1/*- 1/* $OpenBSD: res_init.c,v 1.11 1997/03/13 19:07:38 downsj Exp $ */
2
3/*
4 * ++Copyright++ 1985, 1989, 1993
5 * -
2 * Copyright (c) 1985, 1989, 1993 6 * Copyright (c) 1985, 1989, 1993
3 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
4 * 8 *
5 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
7 * are met: 11 * are met:
@@ -12,12 +16,12 @@
12 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 17 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement: 18 * must display the following acknowledgement:
15 * This product includes software developed by the University of 19 * This product includes software developed by the University of
16 * California, Berkeley and its contributors. 20 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors 21 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software 22 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 23 * without specific prior written permission.
20 * 24 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -52,33 +56,69 @@
52 */ 56 */
53 57
54#if defined(LIBC_SCCS) && !defined(lint) 58#if defined(LIBC_SCCS) && !defined(lint)
55static char rcsid[] = "$OpenBSD: res_init.c,v 1.10 1996/09/22 11:52:07 deraadt Exp $"; 59#if 0
60static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
61static char rcsid[] = "$From: res_init.c,v 8.7 1996/09/28 06:51:07 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: res_init.c,v 1.11 1997/03/13 19:07:38 downsj Exp $";
64#endif
56#endif /* LIBC_SCCS and not lint */ 65#endif /* LIBC_SCCS and not lint */
57 66
67#include <sys/types.h>
58#include <sys/param.h> 68#include <sys/param.h>
59#include <sys/socket.h> 69#include <sys/socket.h>
70#include <sys/time.h>
60#include <netinet/in.h> 71#include <netinet/in.h>
61#include <arpa/inet.h> 72#include <arpa/inet.h>
62#include <arpa/nameser.h> 73#include <arpa/nameser.h>
74
75#include <stdio.h>
76#include <ctype.h>
63#include <resolv.h> 77#include <resolv.h>
64#include <unistd.h> 78#include <unistd.h>
65#include <stdio.h>
66#include <stdlib.h> 79#include <stdlib.h>
67#include <string.h> 80#include <string.h>
68 81
82/*-------------------------------------- info about "sortlist" --------------
83 * Marc Majka 1994/04/16
84 * Allan Nathanson 1994/10/29 (BIND 4.9.3.x)
85 *
86 * NetInfo resolver configuration directory support.
87 *
88 * Allow a NetInfo directory to be created in the hierarchy which
89 * contains the same information as the resolver configuration file.
90 *
91 * - The local domain name is stored as the value of the "domain" property.
92 * - The Internet address(es) of the name server(s) are stored as values
93 * of the "nameserver" property.
94 * - The name server addresses are stored as values of the "nameserver"
95 * property.
96 * - The search list for host-name lookup is stored as values of the
97 * "search" property.
98 * - The sortlist comprised of IP address netmask pairs are stored as
99 * values of the "sortlist" property. The IP address and optional netmask
100 * should be seperated by a slash (/) or ampersand (&) character.
101 * - Internal resolver variables can be set from the value of the "options"
102 * property.
103 */
104
69static void res_setoptions __P((char *, char *)); 105static void res_setoptions __P((char *, char *));
106
107#ifdef RESOLVSORT
108static const char sort_mask[] = "/&";
109#define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)
70static u_int32_t net_mask __P((struct in_addr)); 110static u_int32_t net_mask __P((struct in_addr));
111#endif
71 112
72/* 113/*
73 * Resolver state default settings 114 * Resolver state default settings.
74 */ 115 */
75 116
76struct __res_state _res = { 117struct __res_state _res
77 RES_TIMEOUT, /* retransmition time interval */ 118# if defined(__BIND_RES_TEXT)
78 4, /* number of times to retransmit */ 119 = { RES_TIMEOUT, } /* Motorola, et al. */
79 RES_DEFAULT, /* options flags */ 120# endif
80 1, /* number of name servers */ 121 ;
81};
82 122
83/* 123/*
84 * Set up default settings. If the configuration file exist, the values 124 * Set up default settings. If the configuration file exist, the values
@@ -105,25 +145,60 @@ int
105res_init() 145res_init()
106{ 146{
107 register FILE *fp; 147 register FILE *fp;
108 register char *cp, **pp, *net; 148 register char *cp, **pp;
109 register int n; 149 register int n;
110 char buf[BUFSIZ], buf2[BUFSIZ]; 150 char buf[BUFSIZ];
111 int nserv = 0; /* number of nameserver records read from file */ 151 int nserv = 0; /* number of nameserver records read from file */
112 int haveenv = 0; 152 int haveenv = 0;
113 int havesearch = 0; 153 int havesearch = 0;
154#ifdef RESOLVSORT
114 int nsort = 0; 155 int nsort = 0;
156 char *net;
157#endif
158#ifndef RFC1535
159 int dots;
160#endif
115 161
116 if (_res.id == 0) 162 /*
163 * These three fields used to be statically initialized. This made
164 * it hard to use this code in a shared library. It is necessary,
165 * now that we're doing dynamic initialization here, that we preserve
166 * the old semantics: if an application modifies one of these three
167 * fields of _res before res_init() is called, res_init() will not
168 * alter them. Of course, if an application is setting them to
169 * _zero_ before calling res_init(), hoping to override what used
170 * to be the static default, we can't detect it and unexpected results
171 * will follow. Zero for any of these fields would make no sense,
172 * so one can safely assume that the applications were already getting
173 * unexpected results.
174 *
175 * _res.options is tricky since some apps were known to diddle the bits
176 * before res_init() was first called. We can't replicate that semantic
177 * with dynamic initialization (they may have turned bits off that are
178 * set in RES_DEFAULT). Our solution is to declare such applications
179 * "broken". They could fool us by setting RES_INIT but none do (yet).
180 */
181 if (!_res.retrans)
182 _res.retrans = RES_TIMEOUT;
183 if (!_res.retry)
184 _res.retry = 4;
185 if (!(_res.options & RES_INIT))
186 _res.options = RES_DEFAULT;
187
188 /*
189 * This one used to initialize implicitly to zero, so unless the app
190 * has set it to something in particular, we can randomize it now.
191 */
192 if (!_res.id)
117 _res.id = res_randomid(); 193 _res.id = res_randomid();
118 194
119 _res.nsaddr.sin_len = sizeof(struct sockaddr_in);
120 _res.nsaddr.sin_family = AF_INET;
121 _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
122#ifdef USELOOPBACK 195#ifdef USELOOPBACK
123 _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1); 196 _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
124#else 197#else
125 _res.nsaddr.sin_addr.s_addr = INADDR_ANY; 198 _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
126#endif 199#endif
200 _res.nsaddr.sin_family = AF_INET;
201 _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
127 _res.nscount = 1; 202 _res.nscount = 1;
128 _res.ndots = 1; 203 _res.ndots = 1;
129 _res.pfcode = 0; 204 _res.pfcode = 0;
@@ -133,8 +208,6 @@ res_init()
133 if (issetugid() == 0 && (cp = getenv("LOCALDOMAIN")) != NULL) { 208 if (issetugid() == 0 && (cp = getenv("LOCALDOMAIN")) != NULL) {
134 (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); 209 (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
135 _res.defdname[sizeof(_res.defdname) - 1] = '\0'; 210 _res.defdname[sizeof(_res.defdname) - 1] = '\0';
136 if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
137 *cp = '\0';
138 haveenv++; 211 haveenv++;
139 212
140 /* 213 /*
@@ -148,7 +221,7 @@ res_init()
148 pp = _res.dnsrch; 221 pp = _res.dnsrch;
149 *pp++ = cp; 222 *pp++ = cp;
150 for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { 223 for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
151 if (*cp == '\n') /* silly backwards compat */ 224 if (*cp == '\n') /* silly backwards compat */
152 break; 225 break;
153 else if (*cp == ' ' || *cp == '\t') { 226 else if (*cp == ' ' || *cp == '\t') {
154 *cp = 0; 227 *cp = 0;
@@ -166,16 +239,21 @@ res_init()
166 *pp++ = 0; 239 *pp++ = 0;
167 } 240 }
168 241
242#define MATCH(line, name) \
243 (!strncmp(line, name, sizeof(name) - 1) && \
244 (line[sizeof(name) - 1] == ' ' || \
245 line[sizeof(name) - 1] == '\t'))
246
169 if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) { 247 if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
170 strncpy(_res.lookups, "bf", sizeof _res.lookups); 248 strncpy(_res.lookups, "bf", sizeof _res.lookups);
171 249
172 /* read the config file */ 250 /* read the config file */
173 while (fgets(buf, sizeof(buf), fp) != NULL) { 251 while (fgets(buf, sizeof(buf), fp) != NULL) {
174 /* skip comments */ 252 /* skip comments */
175 if ((*buf == ';') || (*buf == '#')) 253 if (*buf == ';' || *buf == '#')
176 continue; 254 continue;
177 /* read default domain name */ 255 /* read default domain name */
178 if (!strncmp(buf, "domain", sizeof("domain") - 1)) { 256 if (MATCH(buf, "domain")) {
179 if (haveenv) /* skip if have from environ */ 257 if (haveenv) /* skip if have from environ */
180 continue; 258 continue;
181 cp = buf + sizeof("domain") - 1; 259 cp = buf + sizeof("domain") - 1;
@@ -183,8 +261,7 @@ res_init()
183 cp++; 261 cp++;
184 if ((*cp == '\0') || (*cp == '\n')) 262 if ((*cp == '\0') || (*cp == '\n'))
185 continue; 263 continue;
186 (void)strncpy(_res.defdname, cp, 264 strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
187 sizeof(_res.defdname) - 1);
188 _res.defdname[sizeof(_res.defdname) - 1] = '\0'; 265 _res.defdname[sizeof(_res.defdname) - 1] = '\0';
189 if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL) 266 if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
190 *cp = '\0'; 267 *cp = '\0';
@@ -219,7 +296,7 @@ res_init()
219 continue; 296 continue;
220 } 297 }
221 /* set search list */ 298 /* set search list */
222 if (!strncmp(buf, "search", sizeof("search") - 1)) { 299 if (MATCH(buf, "search")) {
223 if (haveenv) /* skip if have from environ */ 300 if (haveenv) /* skip if have from environ */
224 continue; 301 continue;
225 cp = buf + sizeof("search") - 1; 302 cp = buf + sizeof("search") - 1;
@@ -227,8 +304,7 @@ res_init()
227 cp++; 304 cp++;
228 if ((*cp == '\0') || (*cp == '\n')) 305 if ((*cp == '\0') || (*cp == '\n'))
229 continue; 306 continue;
230 (void)strncpy(_res.defdname, cp, 307 strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
231 sizeof(_res.defdname) - 1);
232 _res.defdname[sizeof(_res.defdname) - 1] = '\0'; 308 _res.defdname[sizeof(_res.defdname) - 1] = '\0';
233 if ((cp = strchr(_res.defdname, '\n')) != NULL) 309 if ((cp = strchr(_res.defdname, '\n')) != NULL)
234 *cp = '\0'; 310 *cp = '\0';
@@ -257,84 +333,110 @@ res_init()
257 continue; 333 continue;
258 } 334 }
259 /* read nameservers to query */ 335 /* read nameservers to query */
260 if (!strncmp(buf, "nameserver", sizeof("nameserver") - 1) && 336 if (MATCH(buf, "nameserver") && nserv < MAXNS) {
261 nserv < MAXNS) { 337 struct in_addr a;
262 struct in_addr a;
263 338
264 cp = buf + sizeof("nameserver") - 1; 339 cp = buf + sizeof("nameserver") - 1;
265 while (*cp == ' ' || *cp == '\t') 340 while (*cp == ' ' || *cp == '\t')
266 cp++; 341 cp++;
267 if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) { 342 if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
268 _res.nsaddr_list[nserv].sin_len = sizeof(struct sockaddr_in); 343 _res.nsaddr_list[nserv].sin_addr = a;
269 _res.nsaddr_list[nserv].sin_family = AF_INET; 344 _res.nsaddr_list[nserv].sin_family = AF_INET;
270 _res.nsaddr_list[nserv].sin_port = 345 _res.nsaddr_list[nserv].sin_port =
271 htons(NAMESERVER_PORT); 346 htons(NAMESERVER_PORT);
272 _res.nsaddr_list[nserv].sin_addr = a;
273 nserv++; 347 nserv++;
274 } 348 }
275 continue; 349 continue;
276 } 350 }
277 if (!strncmp(buf, "sortlist", sizeof("sortlist") - 1)) { 351#ifdef RESOLVSORT
352 if (MATCH(buf, "sortlist")) {
278 struct in_addr a; 353 struct in_addr a;
279 354
280 cp = buf + sizeof("sortlist") - 1; 355 cp = buf + sizeof("sortlist") - 1;
281 while (*cp == ' ' || *cp == '\t') 356 while (nsort < MAXRESOLVSORT) {
282 cp++; 357 while (*cp == ' ' || *cp == '\t')
283 while (sscanf(cp,"%[0-9./]s", buf2) && nsort < MAXRESOLVSORT) { 358 cp++;
284 if (net = strchr(buf2, '/')) 359 if (*cp == '\0' || *cp == '\n' || *cp == ';')
285 *net = '\0'; 360 break;
286 if (inet_aton(buf2, &a)) { 361 net = cp;
362 while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
363 isascii(*cp) && !isspace(*cp))
364 cp++;
365 n = *cp;
366 *cp = 0;
367 if (inet_aton(net, &a)) {
287 _res.sort_list[nsort].addr = a; 368 _res.sort_list[nsort].addr = a;
288 if (net && inet_aton(net+1, &a)) { 369 if (ISSORTMASK(n)) {
289 _res.sort_list[nsort].mask = a.s_addr; 370 *cp++ = n;
290 } else { 371 net = cp;
291 _res.sort_list[nsort].mask = 372 while (*cp && *cp != ';' &&
373 isascii(*cp) && !isspace(*cp))
374 cp++;
375 n = *cp;
376 *cp = 0;
377 if (inet_aton(net, &a)) {
378 _res.sort_list[nsort].mask = a.s_addr;
379 } else {
380 _res.sort_list[nsort].mask =
292 net_mask(_res.sort_list[nsort].addr); 381 net_mask(_res.sort_list[nsort].addr);
382 }
383 } else {
384 _res.sort_list[nsort].mask =
385 net_mask(_res.sort_list[nsort].addr);
293 } 386 }
294 nsort++; 387 nsort++;
295 } 388 }
296 if (net) 389 *cp = n;
297 *net = '/';
298 cp += strlen(buf2);
299 while (*cp == ' ' || *cp == '\t')
300 cp++;
301 } 390 }
302 continue; 391 continue;
303 } 392 }
304 if (!strncmp(buf, "options", sizeof("options") -1)) { 393#endif
394 if (MATCH(buf, "options")) {
305 res_setoptions(buf + sizeof("options") - 1, "conf"); 395 res_setoptions(buf + sizeof("options") - 1, "conf");
306 continue; 396 continue;
307 } 397 }
308 } 398 }
309 if (nserv > 1) 399 if (nserv > 1)
310 _res.nscount = nserv; 400 _res.nscount = nserv;
401#ifdef RESOLVSORT
311 _res.nsort = nsort; 402 _res.nsort = nsort;
403#endif
312 (void) fclose(fp); 404 (void) fclose(fp);
313 } 405 }
314 if (_res.defdname[0] == 0) { 406 if (_res.defdname[0] == 0 &&
315 if (gethostname(buf, sizeof(_res.defdname) - 1) == 0 && 407 gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
316 (cp = strchr(buf, '.'))) 408 (cp = strchr(buf, '.')) != NULL)
317 (void)strcpy(_res.defdname, cp + 1); 409 strcpy(_res.defdname, cp + 1);
318 }
319 410
320 /* find components of local domain that might be searched */ 411 /* find components of local domain that might be searched */
321 if (havesearch == 0) { 412 if (havesearch == 0) {
322 pp = _res.dnsrch; 413 pp = _res.dnsrch;
323 *pp++ = _res.defdname; 414 *pp++ = _res.defdname;
324#ifndef SEARCH_LOCAL_DOMAINS
325 *pp = NULL; 415 *pp = NULL;
326#else 416
327 for (cp = _res.defdname, n = 0; *cp; cp++) 417#ifndef RFC1535
328 if (*cp == '.') 418 dots = 0;
329 n++; 419 for (cp = _res.defdname; *cp; cp++)
420 dots += (*cp == '.');
421
330 cp = _res.defdname; 422 cp = _res.defdname;
331 for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDFLSRCH; 423 while (pp < _res.dnsrch + MAXDFLSRCH) {
332 n--) { 424 if (dots < LOCALDOMAINPARTS)
333 cp = strchr(cp, '.'); 425 break;
334 *pp++ = ++cp; 426 cp = strchr(cp, '.') + 1; /* we know there is one */
427 *pp++ = cp;
428 dots--;
335 } 429 }
336 *pp++ = 0; 430 *pp = NULL;
337#endif 431#ifdef DEBUG
432 if (_res.options & RES_DEBUG) {
433 printf(";; res_init()... default dnsrch list:\n");
434 for (pp = _res.dnsrch; *pp; pp++)
435 printf(";;\t%s\n", *pp);
436 printf(";;\t..END..\n");
437 }
438#endif /* DEBUG */
439#endif /* !RFC1535 */
338 } 440 }
339 441
340 if (issetugid()) 442 if (issetugid())
@@ -354,28 +456,26 @@ res_setoptions(options, source)
354 int i; 456 int i;
355 457
356#ifdef DEBUG 458#ifdef DEBUG
357 if (_res.options & RES_DEBUG) { 459 if (_res.options & RES_DEBUG)
358 printf(";; res_setoptions(\"%s\", \"%s\")...\n", 460 printf(";; res_setoptions(\"%s\", \"%s\")...\n",
359 options, source); 461 options, source);
360 }
361#endif 462#endif
362 while (*cp) { 463 while (*cp) {
363 /* skip leading and inner runs of spaces */ 464 /* skip leading and inner runs of spaces */
364 while (*cp == ' ' || *cp == '\t') 465 while (*cp == ' ' || *cp == '\t')
365 cp++; 466 cp++;
366 /* search for and process individual options */ 467 /* search for and process individual options */
367 if (!strncmp(cp, "ndots:", sizeof("ndots:")-1)) { 468 if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) {
368 i = atoi(cp + sizeof("ndots:") - 1); 469 i = atoi(cp + sizeof("ndots:") - 1);
369 if (i <= RES_MAXNDOTS) 470 if (i <= RES_MAXNDOTS)
370 _res.ndots = i; 471 _res.ndots = i;
371 else 472 else
372 _res.ndots = RES_MAXNDOTS; 473 _res.ndots = RES_MAXNDOTS;
373#ifdef DEBUG 474#ifdef DEBUG
374 if (_res.options & RES_DEBUG) { 475 if (_res.options & RES_DEBUG)
375 printf(";;\tndots=%d\n", _res.ndots); 476 printf(";;\tndots=%d\n", _res.ndots);
376 }
377#endif 477#endif
378 } else if (!strncmp(cp, "debug", sizeof("debug")-1)) { 478 } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
379#ifdef DEBUG 479#ifdef DEBUG
380 if (!(_res.options & RES_DEBUG)) { 480 if (!(_res.options & RES_DEBUG)) {
381 printf(";; res_setoptions(\"%s\", \"%s\")..\n", 481 printf(";; res_setoptions(\"%s\", \"%s\")..\n",
@@ -384,6 +484,8 @@ res_setoptions(options, source)
384 } 484 }
385 printf(";;\tdebug\n"); 485 printf(";;\tdebug\n");
386#endif 486#endif
487 } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {
488 _res.options |= RES_USE_INET6;
387 } else { 489 } else {
388 /* XXX - print a warning here? */ 490 /* XXX - print a warning here? */
389 } 491 }
@@ -393,6 +495,8 @@ res_setoptions(options, source)
393 } 495 }
394} 496}
395 497
498#ifdef RESOLVSORT
499/* XXX - should really support CIDR which means explicit masks always. */
396static u_int32_t 500static u_int32_t
397net_mask(in) /* XXX - should really use system's version of this */ 501net_mask(in) /* XXX - should really use system's version of this */
398 struct in_addr in; 502 struct in_addr in;
@@ -401,12 +505,13 @@ net_mask(in) /* XXX - should really use system's version of this */
401 505
402 if (IN_CLASSA(i)) 506 if (IN_CLASSA(i))
403 return (htonl(IN_CLASSA_NET)); 507 return (htonl(IN_CLASSA_NET));
404 if (IN_CLASSB(i)) 508 else if (IN_CLASSB(i))
405 return (htonl(IN_CLASSB_NET)); 509 return (htonl(IN_CLASSB_NET));
406 return (htonl(IN_CLASSC_NET)); 510 return (htonl(IN_CLASSC_NET));
407} 511}
512#endif
408 513
409u_int16_t 514u_int
410res_randomid() 515res_randomid()
411{ 516{
412 struct timeval now; 517 struct timeval now;
diff --git a/src/lib/libc/net/res_mkquery.c b/src/lib/libc/net/res_mkquery.c
index 6fbd6a3859..5faba01748 100644
--- a/src/lib/libc/net/res_mkquery.c
+++ b/src/lib/libc/net/res_mkquery.c
@@ -1,7 +1,11 @@
1/*- 1/* $OpenBSD: res_mkquery.c,v 1.6 1997/03/13 19:07:39 downsj Exp $ */
2
3/*
4 * ++Copyright++ 1985, 1993
5 * -
2 * Copyright (c) 1985, 1993 6 * Copyright (c) 1985, 1993
3 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
4 * 8 *
5 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
7 * are met: 11 * are met:
@@ -12,12 +16,12 @@
12 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 17 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement: 18 * must display the following acknowledgement:
15 * This product includes software developed by the University of 19 * This product includes software developed by the University of
16 * California, Berkeley and its contributors. 20 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors 21 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software 22 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 23 * without specific prior written permission.
20 * 24 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -52,14 +56,22 @@
52 */ 56 */
53 57
54#if defined(LIBC_SCCS) && !defined(lint) 58#if defined(LIBC_SCCS) && !defined(lint)
55static char rcsid[] = "$OpenBSD: res_mkquery.c,v 1.5 1996/12/14 06:49:39 tholo Exp $"; 59#if 0
60static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: res_mkquery.c,v 8.5 1996/08/27 08:33:28 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: res_mkquery.c,v 1.6 1997/03/13 19:07:39 downsj Exp $";
64#endif
56#endif /* LIBC_SCCS and not lint */ 65#endif /* LIBC_SCCS and not lint */
57 66
67#include <sys/types.h>
58#include <sys/param.h> 68#include <sys/param.h>
59#include <netinet/in.h> 69#include <netinet/in.h>
60#include <arpa/nameser.h> 70#include <arpa/nameser.h>
61#include <resolv.h> 71
62#include <stdio.h> 72#include <stdio.h>
73#include <netdb.h>
74#include <resolv.h>
63#include <string.h> 75#include <string.h>
64 76
65/* 77/*
@@ -70,9 +82,9 @@ static char rcsid[] = "$OpenBSD: res_mkquery.c,v 1.5 1996/12/14 06:49:39 tholo E
70int 82int
71res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen) 83res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
72 int op; /* opcode of query */ 84 int op; /* opcode of query */
73 const char *dname; /* domain name */ 85 const char *dname; /* domain name */
74 int class, type; /* class and type of query */ 86 int class, type; /* class and type of query */
75 const u_char *data; /* resource record data */ 87 const u_char *data; /* resource record data */
76 int datalen; /* length of data */ 88 int datalen; /* length of data */
77 const u_char *newrr_in; /* new rr for modify or append */ 89 const u_char *newrr_in; /* new rr for modify or append */
78 u_char *buf; /* buffer to put query */ 90 u_char *buf; /* buffer to put query */
@@ -81,11 +93,12 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
81 register HEADER *hp; 93 register HEADER *hp;
82 register u_char *cp; 94 register u_char *cp;
83 register int n; 95 register int n;
84#ifdef ALLOW_UPDATES 96 u_char *dnptrs[20], **dpp, **lastdnptr;
85 struct rrec *newrr = (struct rrec *) newrr_in;
86#endif /* ALLOW_UPDATES */
87 u_char *dnptrs[10], **dpp, **lastdnptr;
88 97
98 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
99 h_errno = NETDB_INTERNAL;
100 return (-1);
101 }
89#ifdef DEBUG 102#ifdef DEBUG
90 if (_res.options & RES_DEBUG) 103 if (_res.options & RES_DEBUG)
91 printf(";; res_mkquery(%d, %s, %d, %d)\n", 104 printf(";; res_mkquery(%d, %s, %d, %d)\n",
@@ -94,37 +107,36 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
94 /* 107 /*
95 * Initialize header fields. 108 * Initialize header fields.
96 */ 109 */
97 if ((buf == NULL) || (buflen < sizeof(HEADER))) 110 if ((buf == NULL) || (buflen < HFIXEDSZ))
98 return(-1); 111 return (-1);
99 bzero(buf, sizeof(HEADER)); 112 bzero(buf, HFIXEDSZ);
100 hp = (HEADER *) buf; 113 hp = (HEADER *) buf;
101 hp->id = htons(++_res.id); 114 hp->id = htons(++_res.id);
102 hp->opcode = op; 115 hp->opcode = op;
103 hp->pr = (_res.options & RES_PRIMARY) != 0;
104 hp->rd = (_res.options & RES_RECURSE) != 0; 116 hp->rd = (_res.options & RES_RECURSE) != 0;
105 hp->rcode = NOERROR; 117 hp->rcode = NOERROR;
106 cp = buf + sizeof(HEADER); 118 cp = buf + HFIXEDSZ;
107 buflen -= sizeof(HEADER); 119 buflen -= HFIXEDSZ;
108 dpp = dnptrs; 120 dpp = dnptrs;
109 *dpp++ = buf; 121 *dpp++ = buf;
110 *dpp++ = NULL; 122 *dpp++ = NULL;
111 lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]); 123 lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
112 /* 124 /*
113 * perform opcode specific processing 125 * perform opcode specific processing
114 */ 126 */
115 switch (op) { 127 switch (op) {
116 case QUERY: 128 case QUERY: /*FALLTHROUGH*/
117 case NS_NOTIFY_OP: 129 case NS_NOTIFY_OP:
118 if ((buflen -= QFIXEDSZ) < 0) 130 if ((buflen -= QFIXEDSZ) < 0)
119 return(-1); 131 return (-1);
120 if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) 132 if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
121 return (-1); 133 return (-1);
122 cp += n; 134 cp += n;
123 buflen -= n; 135 buflen -= n;
124 __putshort(type, cp); 136 __putshort(type, cp);
125 cp += sizeof(u_int16_t); 137 cp += INT16SZ;
126 __putshort(class, cp); 138 __putshort(class, cp);
127 cp += sizeof(u_int16_t); 139 cp += INT16SZ;
128 hp->qdcount = htons(1); 140 hp->qdcount = htons(1);
129 if (op == QUERY || data == NULL) 141 if (op == QUERY || data == NULL)
130 break; 142 break;
@@ -132,18 +144,19 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
132 * Make an additional record for completion domain. 144 * Make an additional record for completion domain.
133 */ 145 */
134 buflen -= RRFIXEDSZ; 146 buflen -= RRFIXEDSZ;
135 if ((n = dn_comp((const char *)data, cp, buflen, dnptrs, lastdnptr)) < 0) 147 n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr);
148 if (n < 0)
136 return (-1); 149 return (-1);
137 cp += n; 150 cp += n;
138 buflen -= n; 151 buflen -= n;
139 __putshort(T_NULL, cp); 152 __putshort(T_NULL, cp);
140 cp += sizeof(u_int16_t); 153 cp += INT16SZ;
141 __putshort(class, cp); 154 __putshort(class, cp);
142 cp += sizeof(u_int16_t); 155 cp += INT16SZ;
143 __putlong(0, cp); 156 __putlong(0, cp);
144 cp += sizeof(u_int32_t); 157 cp += INT32SZ;
145 __putshort(0, cp); 158 __putshort(0, cp);
146 cp += sizeof(u_int16_t); 159 cp += INT16SZ;
147 hp->arcount = htons(1); 160 hp->arcount = htons(1);
148 break; 161 break;
149 162
@@ -155,13 +168,13 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
155 return (-1); 168 return (-1);
156 *cp++ = '\0'; /* no domain name */ 169 *cp++ = '\0'; /* no domain name */
157 __putshort(type, cp); 170 __putshort(type, cp);
158 cp += sizeof(u_int16_t); 171 cp += INT16SZ;
159 __putshort(class, cp); 172 __putshort(class, cp);
160 cp += sizeof(u_int16_t); 173 cp += INT16SZ;
161 __putlong(0, cp); 174 __putlong(0, cp);
162 cp += sizeof(u_int32_t); 175 cp += INT32SZ;
163 __putshort(datalen, cp); 176 __putshort(datalen, cp);
164 cp += sizeof(u_int16_t); 177 cp += INT16SZ;
165 if (datalen) { 178 if (datalen) {
166 bcopy(data, cp, datalen); 179 bcopy(data, cp, datalen);
167 cp += datalen; 180 cp += datalen;
@@ -169,64 +182,6 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
169 hp->ancount = htons(1); 182 hp->ancount = htons(1);
170 break; 183 break;
171 184
172#ifdef ALLOW_UPDATES
173 /*
174 * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA
175 * (Record to be modified is followed by its replacement in msg.)
176 */
177 case UPDATEM:
178 case UPDATEMA:
179
180 case UPDATED:
181 /*
182 * The res code for UPDATED and UPDATEDA is the same; user
183 * calls them differently: specifies data for UPDATED; server
184 * ignores data if specified for UPDATEDA.
185 */
186 case UPDATEDA:
187 buflen -= RRFIXEDSZ + datalen;
188 if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
189 return (-1);
190 cp += n;
191 __putshort(type, cp);
192 cp += sizeof(u_int16_t);
193 __putshort(class, cp);
194 cp += sizeof(u_int16_t);
195 __putlong(0, cp);
196 cp += sizeof(u_int32_t);
197 __putshort(datalen, cp);
198 cp += sizeof(u_int16_t);
199 if (datalen) {
200 bcopy(data, cp, datalen);
201 cp += datalen;
202 }
203 if ( (op == UPDATED) || (op == UPDATEDA) ) {
204 hp->ancount = htons(0);
205 break;
206 }
207 /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */
208
209 case UPDATEA: /* Add new resource record */
210 buflen -= RRFIXEDSZ + datalen;
211 if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
212 return (-1);
213 cp += n;
214 __putshort(newrr->r_type, cp);
215 cp += sizeof(u_int16_t);
216 __putshort(newrr->r_class, cp);
217 cp += sizeof(u_int16_t);
218 __putlong(0, cp);
219 cp += sizeof(u_int32_t);
220 __putshort(newrr->r_size, cp);
221 cp += sizeof(u_int16_t);
222 if (newrr->r_size) {
223 bcopy(newrr->r_data, cp, newrr->r_size);
224 cp += newrr->r_size;
225 }
226 hp->ancount = htons(0);
227 break;
228
229#endif /* ALLOW_UPDATES */
230 default: 185 default:
231 return (-1); 186 return (-1);
232 } 187 }
diff --git a/src/lib/libc/net/res_query.c b/src/lib/libc/net/res_query.c
index fb2d22c119..fcb3954009 100644
--- a/src/lib/libc/net/res_query.c
+++ b/src/lib/libc/net/res_query.c
@@ -1,7 +1,11 @@
1/*- 1/* $OpenBSD: res_query.c,v 1.8 1997/03/13 19:07:40 downsj Exp $ */
2
3/*
4 * ++Copyright++ 1988, 1993
5 * -
2 * Copyright (c) 1988, 1993 6 * Copyright (c) 1988, 1993
3 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
4 * 8 *
5 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
7 * are met: 11 * are met:
@@ -12,12 +16,12 @@
12 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 17 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement: 18 * must display the following acknowledgement:
15 * This product includes software developed by the University of 19 * This product includes software developed by the University of
16 * California, Berkeley and its contributors. 20 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors 21 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software 22 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 23 * without specific prior written permission.
20 * 24 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -52,16 +56,23 @@
52 */ 56 */
53 57
54#if defined(LIBC_SCCS) && !defined(lint) 58#if defined(LIBC_SCCS) && !defined(lint)
55static char rcsid[] = "$OpenBSD: res_query.c,v 1.7 1996/08/27 03:32:54 deraadt Exp $"; 59#if 0
60static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: res_query.c,v 8.9 1996/09/22 00:13:28 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: res_query.c,v 1.8 1997/03/13 19:07:40 downsj Exp $";
64#endif
56#endif /* LIBC_SCCS and not lint */ 65#endif /* LIBC_SCCS and not lint */
57 66
67#include <sys/types.h>
58#include <sys/param.h> 68#include <sys/param.h>
59#include <netinet/in.h> 69#include <netinet/in.h>
60#include <arpa/inet.h> 70#include <arpa/inet.h>
61#include <arpa/nameser.h> 71#include <arpa/nameser.h>
72
73#include <stdio.h>
62#include <netdb.h> 74#include <netdb.h>
63#include <resolv.h> 75#include <resolv.h>
64#include <stdio.h>
65#include <ctype.h> 76#include <ctype.h>
66#include <errno.h> 77#include <errno.h>
67#include <stdlib.h> 78#include <stdlib.h>
@@ -73,7 +84,7 @@ static char rcsid[] = "$OpenBSD: res_query.c,v 1.7 1996/08/27 03:32:54 deraadt E
73#define MAXPACKET 1024 84#define MAXPACKET 1024
74#endif 85#endif
75 86
76char *__hostalias __P((const char *)); 87const char *hostalias __P((const char *));
77int h_errno; 88int h_errno;
78 89
79/* 90/*
@@ -109,7 +120,7 @@ res_query(name, class, type, answer, anslen)
109#endif 120#endif
110 121
111 n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL, 122 n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
112 buf, sizeof(buf)); 123 buf, sizeof(buf));
113 if (n <= 0) { 124 if (n <= 0) {
114#ifdef DEBUG 125#ifdef DEBUG
115 if (_res.options & RES_DEBUG) 126 if (_res.options & RES_DEBUG)
@@ -128,7 +139,6 @@ res_query(name, class, type, answer, anslen)
128 return (n); 139 return (n);
129 } 140 }
130 141
131 hp = (HEADER *) answer;
132 if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { 142 if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
133#ifdef DEBUG 143#ifdef DEBUG
134 if (_res.options & RES_DEBUG) 144 if (_res.options & RES_DEBUG)
@@ -136,21 +146,21 @@ res_query(name, class, type, answer, anslen)
136 ntohs(hp->ancount)); 146 ntohs(hp->ancount));
137#endif 147#endif
138 switch (hp->rcode) { 148 switch (hp->rcode) {
139 case NXDOMAIN: 149 case NXDOMAIN:
140 h_errno = HOST_NOT_FOUND; 150 h_errno = HOST_NOT_FOUND;
141 break; 151 break;
142 case SERVFAIL: 152 case SERVFAIL:
143 h_errno = TRY_AGAIN; 153 h_errno = TRY_AGAIN;
144 break; 154 break;
145 case NOERROR: 155 case NOERROR:
146 h_errno = NO_DATA; 156 h_errno = NO_DATA;
147 break; 157 break;
148 case FORMERR: 158 case FORMERR:
149 case NOTIMP: 159 case NOTIMP:
150 case REFUSED: 160 case REFUSED:
151 default: 161 default:
152 h_errno = NO_RECOVERY; 162 h_errno = NO_RECOVERY;
153 break; 163 break;
154 } 164 }
155 return (-1); 165 return (-1);
156 } 166 }
@@ -161,9 +171,7 @@ res_query(name, class, type, answer, anslen)
161 * Formulate a normal query, send, and retrieve answer in supplied buffer. 171 * Formulate a normal query, send, and retrieve answer in supplied buffer.
162 * Return the size of the response on success, -1 on error. 172 * Return the size of the response on success, -1 on error.
163 * If enabled, implement search rules until answer or unrecoverable failure 173 * If enabled, implement search rules until answer or unrecoverable failure
164 * is detected. Error number is left in h_errno. 174 * is detected. Error code, if any, is left in h_errno.
165 * Only useful for queries in the same name hierarchy as the local host
166 * (not, for example, for host address-to-name lookups in domain in-addr.arpa).
167 */ 175 */
168int 176int
169res_search(name, class, type, answer, anslen) 177res_search(name, class, type, answer, anslen)
@@ -172,7 +180,7 @@ res_search(name, class, type, answer, anslen)
172 u_char *answer; /* buffer to put answer */ 180 u_char *answer; /* buffer to put answer */
173 int anslen; /* size of answer */ 181 int anslen; /* size of answer */
174{ 182{
175 register char *cp, **domain; 183 register const char *cp, * const *domain;
176 HEADER *hp = (HEADER *) answer; 184 HEADER *hp = (HEADER *) answer;
177 u_int dots; 185 u_int dots;
178 int trailing_dot, ret, saved_herrno; 186 int trailing_dot, ret, saved_herrno;
@@ -182,15 +190,11 @@ res_search(name, class, type, answer, anslen)
182 h_errno = NETDB_INTERNAL; 190 h_errno = NETDB_INTERNAL;
183 return (-1); 191 return (-1);
184 } 192 }
185
186 got_nodata = 0;
187 errno = 0; 193 errno = 0;
188 h_errno = HOST_NOT_FOUND; /* default, if we never query */ 194 h_errno = HOST_NOT_FOUND; /* default, if we never query */
189 dots = 0; 195 dots = 0;
190 for (cp = (char *)name; *cp; cp++) { 196 for (cp = name; *cp; cp++)
191 if (*cp == '.') 197 dots += (*cp == '.');
192 dots++;
193 }
194 trailing_dot = 0; 198 trailing_dot = 0;
195 if (cp > name && *--cp == '.') 199 if (cp > name && *--cp == '.')
196 trailing_dot++; 200 trailing_dot++;
@@ -206,7 +210,6 @@ res_search(name, class, type, answer, anslen)
206 * 'as is'. The threshold can be set with the "ndots" option. 210 * 'as is'. The threshold can be set with the "ndots" option.
207 */ 211 */
208 saved_herrno = -1; 212 saved_herrno = -1;
209 tried_as_is = 0;
210 if (dots >= _res.ndots) { 213 if (dots >= _res.ndots) {
211 ret = res_querydomain(name, NULL, class, type, answer, anslen); 214 ret = res_querydomain(name, NULL, class, type, answer, anslen);
212 if (ret > 0) 215 if (ret > 0)
@@ -223,13 +226,17 @@ res_search(name, class, type, answer, anslen)
223 */ 226 */
224 if ((!dots && (_res.options & RES_DEFNAMES)) || 227 if ((!dots && (_res.options & RES_DEFNAMES)) ||
225 (dots && !trailing_dot && (_res.options & RES_DNSRCH))) { 228 (dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
226 for (domain = _res.dnsrch; *domain; domain++) { 229 int done = 0;
227 int done = 0; 230
231 for (domain = (const char * const *)_res.dnsrch;
232 *domain && !done;
233 domain++) {
228 234
229 ret = res_querydomain(name, *domain, class, type, 235 ret = res_querydomain(name, *domain, class, type,
230 answer, anslen); 236 answer, anslen);
231 if (ret > 0) 237 if (ret > 0)
232 return (ret); 238 return (ret);
239
233 /* 240 /*
234 * If no server present, give up. 241 * If no server present, give up.
235 * If name isn't found in this domain, 242 * If name isn't found in this domain,
@@ -266,20 +273,16 @@ res_search(name, class, type, answer, anslen)
266 /* anything else implies that we're done */ 273 /* anything else implies that we're done */
267 done++; 274 done++;
268 } 275 }
269 /* 276
270 * if we got here for some reason other than DNSRCH, 277 /* if we got here for some reason other than DNSRCH,
271 * we only wanted one iteration of the loop, so stop. 278 * we only wanted one iteration of the loop, so stop.
272 */ 279 */
273 if (!(_res.options & RES_DNSRCH)) 280 if (!(_res.options & RES_DNSRCH))
274 done++; 281 done++;
275
276 if (done)
277 break;
278 } 282 }
279 } 283 }
280 284
281 /* 285 /* if we have not already tried the name "as is", do that now.
282 * if we have not already tried the name "as is", do that now.
283 * note that we do this regardless of how many dots were in the 286 * note that we do this regardless of how many dots were in the
284 * name or whether it ends with a dot. 287 * name or whether it ends with a dot.
285 */ 288 */
@@ -287,11 +290,9 @@ res_search(name, class, type, answer, anslen)
287 ret = res_querydomain(name, NULL, class, type, answer, anslen); 290 ret = res_querydomain(name, NULL, class, type, answer, anslen);
288 if (ret > 0) 291 if (ret > 0)
289 return (ret); 292 return (ret);
290 saved_herrno = h_errno;
291 } 293 }
292 294
293 /* 295 /* if we got here, we didn't satisfy the search.
294 * if we got here, we didn't satisfy the search.
295 * if we did an initial full query, return that query's h_errno 296 * if we did an initial full query, return that query's h_errno
296 * (note that we wouldn't be here if that query had succeeded). 297 * (note that we wouldn't be here if that query had succeeded).
297 * else if we ever got a nodata, send that back as the reason. 298 * else if we ever got a nodata, send that back as the reason.
@@ -318,7 +319,7 @@ res_querydomain(name, domain, class, type, answer, anslen)
318 u_char *answer; /* buffer to put answer */ 319 u_char *answer; /* buffer to put answer */
319 int anslen; /* size of answer */ 320 int anslen; /* size of answer */
320{ 321{
321 char nbuf[2*MAXDNAME+2]; 322 char nbuf[MAXDNAME];
322 const char *longname = nbuf; 323 const char *longname = nbuf;
323 int n; 324 int n;
324 325
@@ -329,7 +330,7 @@ res_querydomain(name, domain, class, type, answer, anslen)
329#ifdef DEBUG 330#ifdef DEBUG
330 if (_res.options & RES_DEBUG) 331 if (_res.options & RES_DEBUG)
331 printf(";; res_querydomain(%s, %s, %d, %d)\n", 332 printf(";; res_querydomain(%s, %s, %d, %d)\n",
332 name, domain?domain:"<Nil>", class, type); 333 name, domain?domain:"<Nil>", class, type);
333#endif 334#endif
334 if (domain == NULL) { 335 if (domain == NULL) {
335 /* 336 /*
@@ -343,14 +344,13 @@ res_querydomain(name, domain, class, type, answer, anslen)
343 } else 344 } else
344 longname = name; 345 longname = name;
345 } else 346 } else
346 (void)sprintf(nbuf, "%.*s.%.*s", 347 sprintf(nbuf, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain);
347 MAXDNAME, name, MAXDNAME, domain);
348 348
349 return (res_query(longname, class, type, answer, anslen)); 349 return (res_query(longname, class, type, answer, anslen));
350} 350}
351 351
352char * 352const char *
353__hostalias(name) 353hostalias(name)
354 register const char *name; 354 register const char *name;
355{ 355{
356 register char *cp1, *cp2; 356 register char *cp1, *cp2;
@@ -379,7 +379,7 @@ __hostalias(name)
379 break; 379 break;
380 for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2) 380 for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2)
381 ; 381 ;
382 (void)strncpy(abuf, cp1, sizeof(abuf) - 1); 382 strncpy(abuf, cp1, sizeof(abuf) - 1);
383 abuf[sizeof(abuf) - 1] = *cp2 = '\0'; 383 abuf[sizeof(abuf) - 1] = *cp2 = '\0';
384 fclose(fp); 384 fclose(fp);
385 return (abuf); 385 return (abuf);
diff --git a/src/lib/libc/net/res_send.c b/src/lib/libc/net/res_send.c
index 1efd17df2b..bfc01f9b6a 100644
--- a/src/lib/libc/net/res_send.c
+++ b/src/lib/libc/net/res_send.c
@@ -1,4 +1,8 @@
1/*- 1/* $OpenBSD: res_send.c,v 1.4 1997/03/13 19:07:41 downsj Exp $ */
2
3/*
4 * ++Copyright++ 1985, 1989, 1993
5 * -
2 * Copyright (c) 1985, 1989, 1993 6 * Copyright (c) 1985, 1989, 1993
3 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
4 * 8 *
@@ -52,7 +56,12 @@
52 */ 56 */
53 57
54#if defined(LIBC_SCCS) && !defined(lint) 58#if defined(LIBC_SCCS) && !defined(lint)
55static char rcsid[] = "$OpenBSD: res_send.c,v 1.3 1996/08/19 08:29:49 tholo Exp $"; 59#if 0
60static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: res_send.c,v 8.12 1996/10/08 04:51:06 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: res_send.c,v 1.4 1997/03/13 19:07:41 downsj Exp $";
64#endif
56#endif /* LIBC_SCCS and not lint */ 65#endif /* LIBC_SCCS and not lint */
57 66
58 /* change this to "0" 67 /* change this to "0"
@@ -66,6 +75,7 @@ static char rcsid[] = "$OpenBSD: res_send.c,v 1.3 1996/08/19 08:29:49 tholo Exp
66 * Send query to name server and wait for reply. 75 * Send query to name server and wait for reply.
67 */ 76 */
68 77
78#include <sys/types.h>
69#include <sys/param.h> 79#include <sys/param.h>
70#include <sys/time.h> 80#include <sys/time.h>
71#include <sys/socket.h> 81#include <sys/socket.h>
@@ -78,24 +88,24 @@ static char rcsid[] = "$OpenBSD: res_send.c,v 1.3 1996/08/19 08:29:49 tholo Exp
78#include <netdb.h> 88#include <netdb.h>
79#include <errno.h> 89#include <errno.h>
80#include <resolv.h> 90#include <resolv.h>
81#if defined(BSD) && (BSD >= 199306) 91#include <stdlib.h>
82# include <stdlib.h> 92#include <string.h>
83# include <string.h> 93#include <unistd.h>
84# include <unistd.h>
85#else
86# include "../conf/portability.h"
87#endif
88
89#if defined(USE_OPTIONS_H)
90# include <../conf/options.h>
91#endif
92
93void _res_close __P((void));
94 94
95static int s = -1; /* socket used for communications */ 95static int s = -1; /* socket used for communications */
96static int connected = 0; /* is the socket connected */ 96static int connected = 0; /* is the socket connected */
97static int vc = 0; /* is the socket a virtual ciruit? */ 97static int vc = 0; /* is the socket a virtual ciruit? */
98 98
99#ifndef FD_SET
100/* XXX - should be in portability.h */
101#define NFDBITS 32
102#define FD_SETSIZE 32
103#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
104#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
105#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
106#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
107#endif
108
99#define CAN_RECONNECT 1 109#define CAN_RECONNECT 1
100 110
101#ifndef DEBUG 111#ifndef DEBUG
@@ -301,7 +311,7 @@ res_send(buf, buflen, ans, anssiz)
301 struct sockaddr_in *nsap = &_res.nsaddr_list[ns]; 311 struct sockaddr_in *nsap = &_res.nsaddr_list[ns];
302 same_ns: 312 same_ns:
303 if (badns & (1 << ns)) { 313 if (badns & (1 << ns)) {
304 _res_close(); 314 res_close();
305 goto next_ns; 315 goto next_ns;
306 } 316 }
307 317
@@ -318,7 +328,7 @@ res_send(buf, buflen, ans, anssiz)
318 done = 1; 328 done = 1;
319 break; 329 break;
320 case res_nextns: 330 case res_nextns:
321 _res_close(); 331 res_close();
322 goto next_ns; 332 goto next_ns;
323 case res_done: 333 case res_done:
324 return (resplen); 334 return (resplen);
@@ -353,7 +363,7 @@ res_send(buf, buflen, ans, anssiz)
353 truncated = 0; 363 truncated = 0;
354 if ((s < 0) || (!vc)) { 364 if ((s < 0) || (!vc)) {
355 if (s >= 0) 365 if (s >= 0)
356 _res_close(); 366 res_close();
357 367
358 s = socket(PF_INET, SOCK_STREAM, 0); 368 s = socket(PF_INET, SOCK_STREAM, 0);
359 if (s < 0) { 369 if (s < 0) {
@@ -368,7 +378,7 @@ res_send(buf, buflen, ans, anssiz)
368 Aerror(stderr, "connect/vc", 378 Aerror(stderr, "connect/vc",
369 errno, *nsap); 379 errno, *nsap);
370 badns |= (1 << ns); 380 badns |= (1 << ns);
371 _res_close(); 381 res_close();
372 goto next_ns; 382 goto next_ns;
373 } 383 }
374 vc = 1; 384 vc = 1;
@@ -385,12 +395,13 @@ res_send(buf, buflen, ans, anssiz)
385 terrno = errno; 395 terrno = errno;
386 Perror(stderr, "write failed", errno); 396 Perror(stderr, "write failed", errno);
387 badns |= (1 << ns); 397 badns |= (1 << ns);
388 _res_close(); 398 res_close();
389 goto next_ns; 399 goto next_ns;
390 } 400 }
391 /* 401 /*
392 * Receive length & response 402 * Receive length & response
393 */ 403 */
404read_len:
394 cp = ans; 405 cp = ans;
395 len = INT16SZ; 406 len = INT16SZ;
396 while ((n = read(s, (char *)cp, (int)len)) > 0) { 407 while ((n = read(s, (char *)cp, (int)len)) > 0) {
@@ -401,7 +412,7 @@ res_send(buf, buflen, ans, anssiz)
401 if (n <= 0) { 412 if (n <= 0) {
402 terrno = errno; 413 terrno = errno;
403 Perror(stderr, "read failed", errno); 414 Perror(stderr, "read failed", errno);
404 _res_close(); 415 res_close();
405 /* 416 /*
406 * A long running process might get its TCP 417 * A long running process might get its TCP
407 * connection reset if the remote server was 418 * connection reset if the remote server was
@@ -413,10 +424,10 @@ res_send(buf, buflen, ans, anssiz)
413 */ 424 */
414 if (terrno == ECONNRESET && !connreset) { 425 if (terrno == ECONNRESET && !connreset) {
415 connreset = 1; 426 connreset = 1;
416 _res_close(); 427 res_close();
417 goto same_ns; 428 goto same_ns;
418 } 429 }
419 _res_close(); 430 res_close();
420 goto next_ns; 431 goto next_ns;
421 } 432 }
422 resplen = _getshort(ans); 433 resplen = _getshort(ans);
@@ -437,7 +448,7 @@ res_send(buf, buflen, ans, anssiz)
437 if (n <= 0) { 448 if (n <= 0) {
438 terrno = errno; 449 terrno = errno;
439 Perror(stderr, "read(vc)", errno); 450 Perror(stderr, "read(vc)", errno);
440 _res_close(); 451 res_close();
441 goto next_ns; 452 goto next_ns;
442 } 453 }
443 if (truncated) { 454 if (truncated) {
@@ -459,6 +470,20 @@ res_send(buf, buflen, ans, anssiz)
459 break; 470 break;
460 } 471 }
461 } 472 }
473 /*
474 * The calling applicating has bailed out of
475 * a previous call and failed to arrange to have
476 * the circuit closed or the server has got
477 * itself confused. Anyway drop the packet and
478 * wait for the correct one.
479 */
480 if (hp->id != anhp->id) {
481 DprintQ((_res.options & RES_DEBUG) ||
482 (_res.pfcode & RES_PRF_REPLY),
483 (stdout, ";; old answer (unexpected):\n"),
484 ans, (resplen>anssiz)?anssiz:resplen);
485 goto read_len;
486 }
462 } else { 487 } else {
463 /* 488 /*
464 * Use datagrams. 489 * Use datagrams.
@@ -470,7 +495,7 @@ res_send(buf, buflen, ans, anssiz)
470 495
471 if ((s < 0) || vc) { 496 if ((s < 0) || vc) {
472 if (vc) 497 if (vc)
473 _res_close(); 498 res_close();
474 s = socket(PF_INET, SOCK_DGRAM, 0); 499 s = socket(PF_INET, SOCK_DGRAM, 0);
475 if (s < 0) { 500 if (s < 0) {
476#if !CAN_RECONNECT 501#if !CAN_RECONNECT
@@ -510,7 +535,7 @@ res_send(buf, buflen, ans, anssiz)
510 "connect(dg)", 535 "connect(dg)",
511 errno, *nsap); 536 errno, *nsap);
512 badns |= (1 << ns); 537 badns |= (1 << ns);
513 _res_close(); 538 res_close();
514 goto next_ns; 539 goto next_ns;
515 } 540 }
516 connected = 1; 541 connected = 1;
@@ -518,7 +543,7 @@ res_send(buf, buflen, ans, anssiz)
518 if (send(s, (char*)buf, buflen, 0) != buflen) { 543 if (send(s, (char*)buf, buflen, 0) != buflen) {
519 Perror(stderr, "send", errno); 544 Perror(stderr, "send", errno);
520 badns |= (1 << ns); 545 badns |= (1 << ns);
521 _res_close(); 546 res_close();
522 goto next_ns; 547 goto next_ns;
523 } 548 }
524 } else { 549 } else {
@@ -555,7 +580,7 @@ res_send(buf, buflen, ans, anssiz)
555 != buflen) { 580 != buflen) {
556 Aerror(stderr, "sendto", errno, *nsap); 581 Aerror(stderr, "sendto", errno, *nsap);
557 badns |= (1 << ns); 582 badns |= (1 << ns);
558 _res_close(); 583 res_close();
559 goto next_ns; 584 goto next_ns;
560 } 585 }
561 } 586 }
@@ -575,8 +600,10 @@ res_send(buf, buflen, ans, anssiz)
575 n = select(s+1, &dsmask, (fd_set *)NULL, 600 n = select(s+1, &dsmask, (fd_set *)NULL,
576 (fd_set *)NULL, &timeout); 601 (fd_set *)NULL, &timeout);
577 if (n < 0) { 602 if (n < 0) {
603 if (errno == EINTR)
604 goto wait;
578 Perror(stderr, "select", errno); 605 Perror(stderr, "select", errno);
579 _res_close(); 606 res_close();
580 goto next_ns; 607 goto next_ns;
581 } 608 }
582 if (n == 0) { 609 if (n == 0) {
@@ -586,7 +613,7 @@ res_send(buf, buflen, ans, anssiz)
586 Dprint(_res.options & RES_DEBUG, 613 Dprint(_res.options & RES_DEBUG,
587 (stdout, ";; timeout\n")); 614 (stdout, ";; timeout\n"));
588 gotsomewhere = 1; 615 gotsomewhere = 1;
589 _res_close(); 616 res_close();
590 goto next_ns; 617 goto next_ns;
591 } 618 }
592 errno = 0; 619 errno = 0;
@@ -595,7 +622,7 @@ res_send(buf, buflen, ans, anssiz)
595 (struct sockaddr *)&from, &fromlen); 622 (struct sockaddr *)&from, &fromlen);
596 if (resplen <= 0) { 623 if (resplen <= 0) {
597 Perror(stderr, "recvfrom", errno); 624 Perror(stderr, "recvfrom", errno);
598 _res_close(); 625 res_close();
599 goto next_ns; 626 goto next_ns;
600 } 627 }
601 gotsomewhere = 1; 628 gotsomewhere = 1;
@@ -608,7 +635,7 @@ res_send(buf, buflen, ans, anssiz)
608 DprintQ((_res.options & RES_DEBUG) || 635 DprintQ((_res.options & RES_DEBUG) ||
609 (_res.pfcode & RES_PRF_REPLY), 636 (_res.pfcode & RES_PRF_REPLY),
610 (stdout, ";; old answer:\n"), 637 (stdout, ";; old answer:\n"),
611 ans, resplen); 638 ans, (resplen>anssiz)?anssiz:resplen);
612 goto wait; 639 goto wait;
613 } 640 }
614#if CHECK_SRVR_ADDR 641#if CHECK_SRVR_ADDR
@@ -622,7 +649,7 @@ res_send(buf, buflen, ans, anssiz)
622 DprintQ((_res.options & RES_DEBUG) || 649 DprintQ((_res.options & RES_DEBUG) ||
623 (_res.pfcode & RES_PRF_REPLY), 650 (_res.pfcode & RES_PRF_REPLY),
624 (stdout, ";; not our server:\n"), 651 (stdout, ";; not our server:\n"),
625 ans, resplen); 652 ans, (resplen>anssiz)?anssiz:resplen);
626 goto wait; 653 goto wait;
627 } 654 }
628#endif 655#endif
@@ -637,7 +664,7 @@ res_send(buf, buflen, ans, anssiz)
637 DprintQ((_res.options & RES_DEBUG) || 664 DprintQ((_res.options & RES_DEBUG) ||
638 (_res.pfcode & RES_PRF_REPLY), 665 (_res.pfcode & RES_PRF_REPLY),
639 (stdout, ";; wrong query name:\n"), 666 (stdout, ";; wrong query name:\n"),
640 ans, resplen); 667 ans, (resplen>anssiz)?anssiz:resplen);
641 goto wait; 668 goto wait;
642 } 669 }
643 if (anhp->rcode == SERVFAIL || 670 if (anhp->rcode == SERVFAIL ||
@@ -645,9 +672,9 @@ res_send(buf, buflen, ans, anssiz)
645 anhp->rcode == REFUSED) { 672 anhp->rcode == REFUSED) {
646 DprintQ(_res.options & RES_DEBUG, 673 DprintQ(_res.options & RES_DEBUG,
647 (stdout, "server rejected query:\n"), 674 (stdout, "server rejected query:\n"),
648 ans, resplen); 675 ans, (resplen>anssiz)?anssiz:resplen);
649 badns |= (1 << ns); 676 badns |= (1 << ns);
650 _res_close(); 677 res_close();
651 /* don't retry if called from dig */ 678 /* don't retry if called from dig */
652 if (!_res.pfcode) 679 if (!_res.pfcode)
653 goto next_ns; 680 goto next_ns;
@@ -660,7 +687,7 @@ res_send(buf, buflen, ans, anssiz)
660 Dprint(_res.options & RES_DEBUG, 687 Dprint(_res.options & RES_DEBUG,
661 (stdout, ";; truncated answer\n")); 688 (stdout, ";; truncated answer\n"));
662 v_circuit = 1; 689 v_circuit = 1;
663 _res_close(); 690 res_close();
664 goto same_ns; 691 goto same_ns;
665 } 692 }
666 } /*if vc/dg*/ 693 } /*if vc/dg*/
@@ -671,7 +698,7 @@ res_send(buf, buflen, ans, anssiz)
671 DprintQ((_res.options & RES_DEBUG) || 698 DprintQ((_res.options & RES_DEBUG) ||
672 (_res.pfcode & RES_PRF_REPLY), 699 (_res.pfcode & RES_PRF_REPLY),
673 (stdout, ""), 700 (stdout, ""),
674 ans, resplen); 701 ans, (resplen>anssiz)?anssiz:resplen);
675 /* 702 /*
676 * If using virtual circuits, we assume that the first server 703 * If using virtual circuits, we assume that the first server
677 * is preferred over the rest (i.e. it is on the local 704 * is preferred over the rest (i.e. it is on the local
@@ -682,7 +709,7 @@ res_send(buf, buflen, ans, anssiz)
682 */ 709 */
683 if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) || 710 if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) ||
684 !(_res.options & RES_STAYOPEN)) { 711 !(_res.options & RES_STAYOPEN)) {
685 _res_close(); 712 res_close();
686 } 713 }
687 if (Rhook) { 714 if (Rhook) {
688 int done = 0, loops = 0; 715 int done = 0, loops = 0;
@@ -698,7 +725,7 @@ res_send(buf, buflen, ans, anssiz)
698 done = 1; 725 done = 1;
699 break; 726 break;
700 case res_nextns: 727 case res_nextns:
701 _res_close(); 728 res_close();
702 goto next_ns; 729 goto next_ns;
703 case res_modified: 730 case res_modified:
704 /* give the hook another try */ 731 /* give the hook another try */
@@ -717,7 +744,7 @@ res_send(buf, buflen, ans, anssiz)
717 next_ns: ; 744 next_ns: ;
718 } /*foreach ns*/ 745 } /*foreach ns*/
719 } /*foreach retry*/ 746 } /*foreach retry*/
720 _res_close(); 747 res_close();
721 if (!v_circuit) 748 if (!v_circuit)
722 if (!gotsomewhere) 749 if (!gotsomewhere)
723 errno = ECONNREFUSED; /* no nameservers found */ 750 errno = ECONNREFUSED; /* no nameservers found */
@@ -736,7 +763,7 @@ res_send(buf, buflen, ans, anssiz)
736 * This routine is not expected to be user visible. 763 * This routine is not expected to be user visible.
737 */ 764 */
738void 765void
739_res_close() 766res_close()
740{ 767{
741 if (s >= 0) { 768 if (s >= 0) {
742 (void) close(s); 769 (void) close(s);