diff options
author | downsj <> | 1997-03-13 19:07:41 +0000 |
---|---|---|
committer | downsj <> | 1997-03-13 19:07:41 +0000 |
commit | 05882f672fb3bf8797e68cc2d68f8406e1cb7b07 (patch) | |
tree | f9cdfe48f1a2f821eb8d11d33976f3f19cd834db /src | |
parent | b0e0ca363d82adf8768f67857659b9590e0e6954 (diff) | |
download | openbsd-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.inc | 15 | ||||
-rw-r--r-- | src/lib/libc/net/base64.c | 319 | ||||
-rw-r--r-- | src/lib/libc/net/gethostbyname.3 | 48 | ||||
-rw-r--r-- | src/lib/libc/net/gethostnamadr.c | 775 | ||||
-rw-r--r-- | src/lib/libc/net/getnetbyaddr.c | 6 | ||||
-rw-r--r-- | src/lib/libc/net/getnetbyname.c | 4 | ||||
-rw-r--r-- | src/lib/libc/net/getnetent.3 | 23 | ||||
-rw-r--r-- | src/lib/libc/net/getnetnamadr.c | 291 | ||||
-rw-r--r-- | src/lib/libc/net/herror.c | 26 | ||||
-rw-r--r-- | src/lib/libc/net/inet_addr.c | 82 | ||||
-rw-r--r-- | src/lib/libc/net/inet_net_ntop.c | 139 | ||||
-rw-r--r-- | src/lib/libc/net/inet_net_pton.c | 207 | ||||
-rw-r--r-- | src/lib/libc/net/inet_neta.c | 82 | ||||
-rw-r--r-- | src/lib/libc/net/inet_ntop.c | 194 | ||||
-rw-r--r-- | src/lib/libc/net/inet_pton.c | 220 | ||||
-rw-r--r-- | src/lib/libc/net/nsap_addr.c | 55 | ||||
-rw-r--r-- | src/lib/libc/net/res_comp.c | 174 | ||||
-rw-r--r-- | src/lib/libc/net/res_data.c | 117 | ||||
-rw-r--r-- | src/lib/libc/net/res_debug.c | 1055 | ||||
-rw-r--r-- | src/lib/libc/net/res_init.c | 259 | ||||
-rw-r--r-- | src/lib/libc/net/res_mkquery.c | 139 | ||||
-rw-r--r-- | src/lib/libc/net/res_query.c | 116 | ||||
-rw-r--r-- | src/lib/libc/net/res_send.c | 111 |
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 | ||
6 | SRCS+= gethostnamadr.c getnetbyaddr.c getnetbyname.c getnetent.c \ | 6 | SRCS+= 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 |
29 | MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \ | 30 | MLINKS+=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 |
32 | MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \ | 33 | MLINKS+=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 |
34 | MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \ | 35 | MLINKS+=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 | |||
61 | static const char Base64[] = | ||
62 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | ||
63 | static 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 | |||
128 | int | ||
129 | b64_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 | |||
199 | int | ||
200 | b64_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 |
94 | A zero terminated array of alternate names for the host. | 97 | A zero terminated array of alternate names for the host. |
95 | .It Fa h_addrtype | 98 | .It Fa h_addrtype |
96 | The type of address being returned; currently always | 99 | The type of address being returned. |
97 | .Dv AF_INET . | ||
98 | .It Fa h_length | 100 | .It Fa h_length |
99 | The length, in bytes, of the address. | 101 | The 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. | |||
104 | The first address in | 106 | The first address in |
105 | .Fa h_addr_list ; | 107 | .Fa h_addr_list ; |
106 | this is for backward compatibility. | 108 | this is for backward compatibility. |
109 | .El | ||
107 | .Pp | 110 | .Pp |
108 | When using the nameserver, | 111 | When using the nameserver, |
109 | .Fn gethostbyname | 112 | .Fn gethostbyname |
@@ -117,6 +120,14 @@ See | |||
117 | .Xr hostname 7 | 120 | .Xr hostname 7 |
118 | for the domain search procedure and the alias file format. | 121 | for the domain search procedure and the alias file format. |
119 | .Pp | 122 | .Pp |
123 | .Fn Gethostbyname2 | ||
124 | is an advanced form of | ||
125 | .Fn gethostbyname | ||
126 | which allows lookups in address families other than | ||
127 | .Dv AF_INET , | ||
128 | for example | ||
129 | .Dv AF_INET6 . | ||
130 | .Pp | ||
120 | The | 131 | The |
121 | .Fn sethostent | 132 | .Fn sethostent |
122 | function | 133 | function |
@@ -148,7 +159,8 @@ connection. | |||
148 | .El | 159 | .El |
149 | .Sh DIAGNOSTICS | 160 | .Sh DIAGNOSTICS |
150 | Error return status from | 161 | Error return status from |
151 | .Fn gethostbyname | 162 | .Fn gethostbyname , |
163 | .Fn gethostbyname2 , | ||
152 | and | 164 | and |
153 | .Fn gethostbyaddr | 165 | .Fn gethostbyaddr |
154 | is indicated by return of a null pointer. | 166 | is indicated by return of a null pointer. |
@@ -198,20 +210,6 @@ for example, a mail-forwarder may be registered for this domain. | |||
198 | The | 210 | The |
199 | .Fn gethostent | 211 | .Fn gethostent |
200 | function | 212 | function |
201 | is defined, and | ||
202 | .Fn sethostent | ||
203 | and | ||
204 | .Fn endhostent | ||
205 | are redefined, | ||
206 | when | ||
207 | .Xr libc 3 | ||
208 | is built to use only the routines to lookup in | ||
209 | .Pa /etc/hosts | ||
210 | and not the name server. | ||
211 | .Pp | ||
212 | The | ||
213 | .Fn gethostent | ||
214 | function | ||
215 | reads the next line of | 213 | reads the next line of |
216 | .Pa /etc/hosts , | 214 | .Pa /etc/hosts , |
217 | opening the file if necessary. | 215 | opening the file if necessary. |
@@ -225,7 +223,8 @@ If the | |||
225 | .Fa stayopen | 223 | .Fa stayopen |
226 | argument is non-zero, | 224 | argument is non-zero, |
227 | the file will not be closed after each call to | 225 | the file will not be closed after each call to |
228 | .Fn gethostbyname | 226 | .Fn gethostbyname , |
227 | .Fn gethostbyname2 , | ||
229 | or | 228 | or |
230 | .Fn gethostbyaddr . | 229 | .Fn gethostbyaddr . |
231 | .Pp | 230 | .Pp |
@@ -252,4 +251,9 @@ These functions use static data storage; | |||
252 | if the data is needed for future use, it should be | 251 | if the data is needed for future use, it should be |
253 | copied before any subsequent calls overwrite it. | 252 | copied before any subsequent calls overwrite it. |
254 | Only the Internet | 253 | Only the Internet |
255 | address format is currently understood. | 254 | address formats are currently understood. |
255 | .Pp | ||
256 | YP does not support any address families other than | ||
257 | .Dv AF_INET | ||
258 | and uses | ||
259 | the 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) |
55 | static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.13 1997/01/30 05:56:06 deraadt Exp $"; | 55 | static 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; | |||
85 | static struct hostent host; | 88 | static struct hostent host; |
86 | static char *host_aliases[MAXALIASES]; | 89 | static char *host_aliases[MAXALIASES]; |
87 | static char hostbuf[BUFSIZ+1]; | 90 | static char hostbuf[BUFSIZ+1]; |
88 | static struct in_addr host_addr; | 91 | static u_char host_addr[16]; /* IPv4 or IPv6 */ |
89 | static FILE *hostf = NULL; | 92 | static FILE *hostf = NULL; |
90 | static int stayopen = 0; | 93 | static int stayopen = 0; |
91 | 94 | ||
95 | static void map_v4v6_address __P((const char *src, char *dst)); | ||
96 | static void map_v4v6_hostent __P((struct hostent *hp, char **bp, int *len)); | ||
97 | |||
98 | #ifdef RESOLVSORT | ||
99 | static void addrsort __P((char **, int)); | ||
100 | #endif | ||
101 | |||
102 | static int hokchar __P((const char *)); | ||
103 | |||
104 | static 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 | ||
108 | static int qcomp __P((struct in_addr **, struct in_addr **)); | 123 | static struct hostent *getanswer __P((const querybuf *, int, const char *, |
109 | static struct hostent *getanswer __P((querybuf *, int, int)); | 124 | int)); |
110 | static int hbadchar __P((char *)); | ||
111 | 125 | ||
112 | extern int h_errno; | 126 | extern int h_errno; |
113 | 127 | ||
114 | static int | 128 | static int |
115 | hbadchar(p) | 129 | hokchar(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 | ||
138 | static struct hostent * | 152 | static struct hostent * |
139 | getanswer(answer, anslen, iquery) | 153 | getanswer(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 | } |
293 | gotent: | 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 | ||
305 | struct hostent * | 421 | struct hostent * |
306 | gethostbyname(name) | 422 | gethostbyname(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 | |||
439 | struct hostent * | ||
440 | gethostbyname2(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 | ||
382 | struct hostent * | 581 | struct hostent * |
383 | gethostbyaddr(addr, len, type) | 582 | gethostbyaddr(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); |
471 | again: | 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 | |||
800 | struct 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 | } |
528 | found: | 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 | ||
535 | struct hostent * | 823 | struct 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 | ||
552 | static int | ||
553 | qcomp(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 |
570 | struct hostent * | 839 | struct 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 | |||
967 | static void | ||
968 | map_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 | |||
987 | static void | ||
988 | map_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 | ||
1017 | static void | ||
1018 | addrsort(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) |
35 | static char rcsid[] = "$OpenBSD: getnetbyaddr.c,v 1.2 1996/08/19 08:28:42 tholo Exp $"; | 35 | static 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 | |||
40 | extern int _net_stayopen; | 40 | extern int _net_stayopen; |
41 | 41 | ||
42 | struct netent * | 42 | struct netent * |
43 | getnetbyaddr(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) |
35 | static char rcsid[] = "$OpenBSD: getnetbyname.c,v 1.3 1996/08/19 08:28:44 tholo Exp $"; | 35 | static 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 | |||
41 | extern int _net_stayopen; | 41 | extern int _net_stayopen; |
42 | 42 | ||
43 | struct netent * | 43 | struct netent * |
44 | getnetbyname(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 | |||
111 | function | 111 | function |
112 | and | 112 | and |
113 | .Fn getnetbyaddr | 113 | .Fn getnetbyaddr |
114 | sequentially search from the beginning | 114 | search the domain name server if the system is configured to use one. |
115 | of the file until a matching | 115 | If the search fails, or no name server is configured, they sequentially |
116 | net name or | 116 | search from the beginning of the file until a matching net name or |
117 | net address and type is found, | 117 | net address and type is found, or until |
118 | or until | ||
119 | .Dv EOF | 118 | .Dv EOF |
120 | is encountered. | 119 | is encountered. |
121 | Network numbers are supplied in host order. | 120 | Network numbers are supplied in host order. |
@@ -129,7 +128,8 @@ Null pointer | |||
129 | .Dv EOF | 128 | .Dv EOF |
130 | or error. | 129 | or 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 |
134 | The | 134 | The |
135 | .Fn getnetent , | 135 | .Fn getnetent , |
@@ -147,5 +147,4 @@ copied before any subsequent calls to these functions overwrite it. | |||
147 | Only Internet network | 147 | Only Internet network |
148 | numbers are currently understood. | 148 | numbers are currently understood. |
149 | Expecting network numbers to fit | 149 | Expecting network numbers to fit |
150 | in no more than 32 bits is probably | 150 | in no more than 32 bits is naive. |
151 | naive. | ||
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 | ||
45 | static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93"; | ||
46 | static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03"; | ||
47 | static char rcsid[] = "$From: getnetnamadr.c,v 8.7 1996/08/05 08:31:35 vixie Exp $"; | ||
48 | #else | ||
49 | static 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 | |||
67 | extern int h_errno; | ||
68 | |||
69 | struct netent *_getnetbyaddr __P((long net, int type)); | ||
70 | struct 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 | |||
82 | typedef union { | ||
83 | HEADER hdr; | ||
84 | u_char buf[MAXPACKET]; | ||
85 | } querybuf; | ||
86 | |||
87 | typedef union { | ||
88 | long al; | ||
89 | char ac; | ||
90 | } align; | ||
91 | |||
92 | static struct netent * | ||
93 | getnetanswer(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; | ||
106 | static struct netent net_entry; | ||
107 | static 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 | |||
206 | struct netent * | ||
207 | getnetbyaddr(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 | |||
263 | struct netent * | ||
264 | getnetbyname(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) |
55 | static char rcsid[] = "$OpenBSD: herror.c,v 1.3 1996/08/19 08:29:02 tholo Exp $"; | 59 | #if 0 |
60 | static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93"; | ||
61 | static char rcsid[] = "$From: herror.c,v 8.3 1996/08/05 08:31:35 vixie Exp $"; | ||
62 | #else | ||
63 | static 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 | ||
64 | const char *h_errlist[] = { | 74 | const 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) |
35 | static char rcsid[] = "$OpenBSD: inet_addr.c,v 1.3 1996/08/19 08:29:08 tholo Exp $"; | 59 | #if 0 |
60 | static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; | ||
61 | static char rcsid[] = "$From: inet_addr.c,v 8.5 1996/08/05 08:31:35 vixie Exp $"; | ||
62 | #else | ||
63 | static 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 | ||
22 | static const char rcsid[] = "$From: inet_net_ntop.c,v 8.2 1996/08/08 06:54:44 vixie Exp $"; | ||
23 | #else | ||
24 | static 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 | |||
38 | static 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 | */ | ||
51 | char * | ||
52 | inet_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 | */ | ||
81 | static char * | ||
82 | inet_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 | ||
22 | static const char rcsid[] = "$From: inet_net_pton.c,v 8.3 1996/11/11 06:36:52 vixie Exp $"; | ||
23 | #else | ||
24 | static 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 | |||
40 | static 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 | */ | ||
56 | int | ||
57 | inet_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 | */ | ||
88 | static int | ||
89 | inet_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 | ||
22 | static const char rcsid[] = "$Id: inet_neta.c,v 1.1 1997/03/13 19:07:31 downsj Exp $"; | ||
23 | #else | ||
24 | static 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 | */ | ||
47 | char * | ||
48 | inet_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 | ||
21 | static char rcsid[] = "$From: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $"; | ||
22 | #else | ||
23 | static 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 | |||
42 | static const char *inet_ntop4 __P((const u_char *src, char *dst, size_t size)); | ||
43 | static 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 | */ | ||
53 | const char * | ||
54 | inet_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 | */ | ||
83 | static const char * | ||
84 | inet_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 | */ | ||
106 | static const char * | ||
107 | inet_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 | ||
21 | static char rcsid[] = "$From: inet_pton.c,v 8.7 1996/08/05 08:31:35 vixie Exp $"; | ||
22 | #else | ||
23 | static 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 | |||
41 | static int inet_pton4 __P((const char *src, u_char *dst)); | ||
42 | static 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 | */ | ||
55 | int | ||
56 | inet_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 | */ | ||
83 | static int | ||
84 | inet_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 | */ | ||
137 | static int | ||
138 | inet_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) |
35 | static char rcsid[] = "$OpenBSD: nsap_addr.c,v 1.2 1996/08/19 08:29:32 tholo Exp $"; | 21 | #if 0 |
22 | static char rcsid[] = "$From: nsap_addr.c,v 8.3 1996/08/05 08:31:35 vixie Exp $"; | ||
23 | #else | ||
24 | static 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 | |||
58 | u_int | 43 | u_int |
59 | inet_nsap_addr(ascii, binary, maxlen) | 44 | inet_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) |
55 | static char rcsid[] = "$OpenBSD: res_comp.c,v 1.3 1996/08/19 08:29:42 tholo Exp $"; | 59 | #if 0 |
60 | static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93"; | ||
61 | static char rcsid[] = "$From: res_comp.c,v 8.11 1996/12/02 09:17:22 vixie Exp $"; | ||
62 | #else | ||
63 | static 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 | ||
67 | static int dn_find __P((u_char *, u_char *, u_char **, u_char **)); | 79 | static 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 | ||
340 | u_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 | |||
365 | int | ||
366 | res_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 | */ | ||
395 | int | ||
396 | res_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 | */ | ||
412 | int | ||
413 | res_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 | */ | ||
442 | int | ||
443 | res_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 | |||
458 | u_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 | */ | ||
472 | u_int16_t | ||
473 | res_getshort(msgp) | ||
474 | register const u_char *msgp; | ||
475 | { | ||
476 | return (_getshort(msgp)); | ||
477 | } | ||
478 | #endif | ||
479 | |||
350 | u_int32_t | 480 | u_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 | ||
360 | void | 490 | void |
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 | ||
60 | static char rcsid[] = "$From: res_data.c,v 8.2 1996/08/05 08:31:35 vixie Exp $"; | ||
61 | #else | ||
62 | static 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 | |||
81 | const 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 | |||
100 | const 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) |
55 | static char rcsid[] = "$OpenBSD: res_debug.c,v 1.4 1996/09/15 09:31:18 tholo Exp $"; | 81 | #if 0 |
82 | static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; | ||
83 | static char rcsid[] = "$From: res_debug.c,v 8.19 1996/11/26 10:11:23 vixie Exp $"; | ||
84 | #else | ||
85 | static 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 | ||
67 | void __fp_query(); | 105 | extern const char *_res_opcodes[]; |
68 | 106 | extern const char *_res_resultcodes[]; | |
69 | char *_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 | ||
88 | char *_res_resultcodes[] = { | 108 | /* XXX: we should use getservbyport() instead. */ |
89 | "NOERROR", | 109 | static 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 | |||
107 | static char * | ||
108 | dewks(wks) | 110 | dewks(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 | ||
227 | void | 231 | void |
@@ -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 | |||
428 | const 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 | */ | ||
862 | const 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 | */ | ||
876 | const 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 | |||
926 | int | ||
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 | |||
944 | const 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 | |||
967 | const 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 | */ |
682 | const char * | 991 | const 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 | */ |
777 | char * | 1038 | const char * |
778 | __p_time(value) | 1039 | p_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 | |||
1092 | static 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. */ | ||
1096 | static const char * | ||
1097 | precsize_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. */ | ||
1114 | static u_int8_t | ||
1115 | precsize_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. */ | ||
1156 | static u_int32_t | ||
1157 | latlon2ul(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. */ | ||
1255 | int | ||
1256 | loc_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. */ | ||
1366 | const char * | ||
1367 | loc_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. */ | ||
1470 | int | ||
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 | */ | ||
1501 | char * | ||
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) |
55 | static char rcsid[] = "$OpenBSD: res_init.c,v 1.10 1996/09/22 11:52:07 deraadt Exp $"; | 59 | #if 0 |
60 | static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; | ||
61 | static char rcsid[] = "$From: res_init.c,v 8.7 1996/09/28 06:51:07 vixie Exp $"; | ||
62 | #else | ||
63 | static 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 | |||
69 | static void res_setoptions __P((char *, char *)); | 105 | static void res_setoptions __P((char *, char *)); |
106 | |||
107 | #ifdef RESOLVSORT | ||
108 | static const char sort_mask[] = "/&"; | ||
109 | #define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL) | ||
70 | static u_int32_t net_mask __P((struct in_addr)); | 110 | static 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 | ||
76 | struct __res_state _res = { | 117 | struct __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 | |||
105 | res_init() | 145 | res_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. */ | ||
396 | static u_int32_t | 500 | static u_int32_t |
397 | net_mask(in) /* XXX - should really use system's version of this */ | 501 | net_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 | ||
409 | u_int16_t | 514 | u_int |
410 | res_randomid() | 515 | res_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) |
55 | static char rcsid[] = "$OpenBSD: res_mkquery.c,v 1.5 1996/12/14 06:49:39 tholo Exp $"; | 59 | #if 0 |
60 | static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93"; | ||
61 | static char rcsid[] = "$From: res_mkquery.c,v 8.5 1996/08/27 08:33:28 vixie Exp $"; | ||
62 | #else | ||
63 | static 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 | |||
70 | int | 82 | int |
71 | res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen) | 83 | res_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) |
55 | static char rcsid[] = "$OpenBSD: res_query.c,v 1.7 1996/08/27 03:32:54 deraadt Exp $"; | 59 | #if 0 |
60 | static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; | ||
61 | static char rcsid[] = "$From: res_query.c,v 8.9 1996/09/22 00:13:28 vixie Exp $"; | ||
62 | #else | ||
63 | static 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 | ||
76 | char *__hostalias __P((const char *)); | 87 | const char *hostalias __P((const char *)); |
77 | int h_errno; | 88 | int 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 | */ |
168 | int | 176 | int |
169 | res_search(name, class, type, answer, anslen) | 177 | res_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 | ||
352 | char * | 352 | const char * |
353 | __hostalias(name) | 353 | hostalias(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) |
55 | static char rcsid[] = "$OpenBSD: res_send.c,v 1.3 1996/08/19 08:29:49 tholo Exp $"; | 59 | #if 0 |
60 | static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; | ||
61 | static char rcsid[] = "$From: res_send.c,v 8.12 1996/10/08 04:51:06 vixie Exp $"; | ||
62 | #else | ||
63 | static 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 | |||
93 | void _res_close __P((void)); | ||
94 | 94 | ||
95 | static int s = -1; /* socket used for communications */ | 95 | static int s = -1; /* socket used for communications */ |
96 | static int connected = 0; /* is the socket connected */ | 96 | static int connected = 0; /* is the socket connected */ |
97 | static int vc = 0; /* is the socket a virtual ciruit? */ | 97 | static 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 | */ |
404 | read_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 | */ |
738 | void | 765 | void |
739 | _res_close() | 766 | res_close() |
740 | { | 767 | { |
741 | if (s >= 0) { | 768 | if (s >= 0) { |
742 | (void) close(s); | 769 | (void) close(s); |