diff options
Diffstat (limited to 'src/lib/libc/net')
65 files changed, 13214 insertions, 0 deletions
diff --git a/src/lib/libc/net/Makefile.inc b/src/lib/libc/net/Makefile.inc new file mode 100644 index 0000000000..935a1904c1 --- /dev/null +++ b/src/lib/libc/net/Makefile.inc | |||
@@ -0,0 +1,56 @@ | |||
1 | # $OpenBSD: Makefile.inc,v 1.16 1998/08/29 21:11:40 deraadt Exp $ | ||
2 | |||
3 | # net sources | ||
4 | .PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/net ${.CURDIR}/net | ||
5 | |||
6 | CFLAGS+=-DRESOLVSORT | ||
7 | |||
8 | SRCS+= base64.c gethostnamadr.c getnetbyaddr.c getnetbyname.c getnetent.c \ | ||
9 | getnetnamadr.c getproto.c getprotoent.c getprotoname.c getservbyname.c \ | ||
10 | getservbyport.c getservent.c herror.c inet_addr.c inet_lnaof.c \ | ||
11 | inet_makeaddr.c inet_neta.c inet_netof.c inet_network.c \ | ||
12 | inet_net_ntop.c inet_net_pton.c inet_ntoa.c inet_ntop.c \ | ||
13 | inet_pton.c ipx_addr.c ipx_ntoa.c \ | ||
14 | iso_addr.c linkaddr.c ns_addr.c ns_ntoa.c nsap_addr.c rcmd.c recv.c \ | ||
15 | res_comp.c res_data.c res_debug.c res_init.c res_mkquery.c res_query.c \ | ||
16 | res_random.c res_send.c send.c sethostent.c ethers.c rcmdsh.c | ||
17 | |||
18 | # machine-dependent net sources | ||
19 | # m-d Makefile.inc must include sources for: | ||
20 | # htonl() htons() ntohl() ntohs() | ||
21 | |||
22 | .include "${.CURDIR}/arch/${MACHINE_ARCH}/net/Makefile.inc" | ||
23 | |||
24 | MAN+= byteorder.3 ethers.3 gethostbyname.3 getnetent.3 getprotoent.3 \ | ||
25 | getservent.3 inet.3 inet_net.3 iso_addr.3 link_addr.3 ns.3 ipx.3 \ | ||
26 | rcmd.3 rcmdsh.3 resolver.3 | ||
27 | |||
28 | MLINKS+=byteorder.3 htonl.3 byteorder.3 htons.3 byteorder.3 ntohl.3 \ | ||
29 | byteorder.3 ntohs.3 byteorder.3 htobe16.3 byteorder.3 htobe32.3 \ | ||
30 | byteorder.3 betoh16.3 byteorder.3 betoh32.3 byteorder.3 htole16.3 \ | ||
31 | byteorder.3 htole32.3 byteorder.3 letoh16.3 byteorder.3 letoh32.3 \ | ||
32 | byteorder.3 swap16.3 byteorder.3 swap32.3 | ||
33 | MLINKS+=ethers.3 ether_aton.3 ethers.3 ether_hostton.3 ethers.3 ether_line.3 \ | ||
34 | ethers.3 ether_ntoa.3 ethers.3 ether_ntohost.3 ethers.3 ether_addr.3 | ||
35 | MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \ | ||
36 | gethostbyname.3 sethostent.3 gethostbyname.3 gethostent.3 \ | ||
37 | gethostbyname.3 herror.3 gethostbyname.3 gethostbyname2.3 \ | ||
38 | gethostbyname.3 hstrerror.3 | ||
39 | MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \ | ||
40 | getnetent.3 getnetbyname.3 getnetent.3 setnetent.3 | ||
41 | MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \ | ||
42 | getprotoent.3 getprotobynumber.3 getprotoent.3 setprotoent.3 | ||
43 | MLINKS+=getservent.3 endservent.3 getservent.3 getservbyname.3 \ | ||
44 | getservent.3 getservbyport.3 getservent.3 setservent.3 | ||
45 | MLINKS+=inet.3 addr.3 inet.3 inet_addr.3 inet.3 inet_aton.3 \ | ||
46 | inet.3 inet_lnaof.3 inet.3 inet_makeaddr.3 inet.3 inet_netof.3 \ | ||
47 | inet.3 inet_network.3 inet.3 inet_ntoa.3 inet.3 network.3 \ | ||
48 | inet.3 ntoa.3 inet.3 inet_ntop.3 inet.3 inet_pton.3 | ||
49 | MLINKS+=iso_addr.3 iso_ntoa.3 | ||
50 | MLINKS+=link_addr.3 link_ntoa.3 | ||
51 | MLINKS+=ipx.3 ipx_addr.3 ipx.3 ipx_ntoa.3 | ||
52 | MLINKS+=ns.3 ns_addr.3 ns.3 ns_ntoa.3 | ||
53 | MLINKS+=rcmd.3 iruserok.3 rcmd.3 rresvport.3 rcmd.3 ruserok.3 | ||
54 | MLINKS+=resolver.3 dn_comp.3 resolver.3 dn_expand.3 resolver.3 res_init.3 \ | ||
55 | resolver.3 res_mkquery.3 resolver.3 res_send.3 resolver.3 res_query.3 \ | ||
56 | resolver.3 res_search.3 | ||
diff --git a/src/lib/libc/net/base64.c b/src/lib/libc/net/base64.c new file mode 100644 index 0000000000..452fe5afcc --- /dev/null +++ b/src/lib/libc/net/base64.c | |||
@@ -0,0 +1,317 @@ | |||
1 | /* $OpenBSD: base64.c,v 1.3 1997/11/08 20:46:55 deraadt 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 | } | ||
263 | } | ||
264 | |||
265 | /* | ||
266 | * We are done decoding Base-64 chars. Let's see if we ended | ||
267 | * on a byte boundary, and/or with erroneous trailing characters. | ||
268 | */ | ||
269 | |||
270 | if (ch == Pad64) { /* We got a pad char. */ | ||
271 | ch = *src++; /* Skip it, get next. */ | ||
272 | switch (state) { | ||
273 | case 0: /* Invalid = in first position */ | ||
274 | case 1: /* Invalid = in second position */ | ||
275 | return (-1); | ||
276 | |||
277 | case 2: /* Valid, means one byte of info */ | ||
278 | /* Skip any number of spaces. */ | ||
279 | for (; ch != '\0'; ch = *src++) | ||
280 | if (!isspace(ch)) | ||
281 | break; | ||
282 | /* Make sure there is another trailing = sign. */ | ||
283 | if (ch != Pad64) | ||
284 | return (-1); | ||
285 | ch = *src++; /* Skip the = */ | ||
286 | /* Fall through to "single trailing =" case. */ | ||
287 | /* FALLTHROUGH */ | ||
288 | |||
289 | case 3: /* Valid, means two bytes of info */ | ||
290 | /* | ||
291 | * We know this char is an =. Is there anything but | ||
292 | * whitespace after it? | ||
293 | */ | ||
294 | for (; ch != '\0'; ch = *src++) | ||
295 | if (!isspace(ch)) | ||
296 | return (-1); | ||
297 | |||
298 | /* | ||
299 | * Now make sure for cases 2 and 3 that the "extra" | ||
300 | * bits that slopped past the last full byte were | ||
301 | * zeros. If we don't check them, they become a | ||
302 | * subliminal channel. | ||
303 | */ | ||
304 | if (target && target[tarindex] != 0) | ||
305 | return (-1); | ||
306 | } | ||
307 | } else { | ||
308 | /* | ||
309 | * We ended by seeing the end of the string. Make sure we | ||
310 | * have no partial bytes lying around. | ||
311 | */ | ||
312 | if (state != 0) | ||
313 | return (-1); | ||
314 | } | ||
315 | |||
316 | return (tarindex); | ||
317 | } | ||
diff --git a/src/lib/libc/net/byteorder.3 b/src/lib/libc/net/byteorder.3 new file mode 100644 index 0000000000..f2788b25dc --- /dev/null +++ b/src/lib/libc/net/byteorder.3 | |||
@@ -0,0 +1,155 @@ | |||
1 | .\" $OpenBSD: byteorder.3,v 1.5 1997/11/19 23:30:17 niklas Exp $ | ||
2 | .\" | ||
3 | .\" Copyright (c) 1983, 1991, 1993 | ||
4 | .\" The Regents of the University of California. All rights reserved. | ||
5 | .\" | ||
6 | .\" Redistribution and use in source and binary forms, with or without | ||
7 | .\" modification, are permitted provided that the following conditions | ||
8 | .\" are met: | ||
9 | .\" 1. Redistributions of source code must retain the above copyright | ||
10 | .\" notice, this list of conditions and the following disclaimer. | ||
11 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
12 | .\" notice, this list of conditions and the following disclaimer in the | ||
13 | .\" documentation and/or other materials provided with the distribution. | ||
14 | .\" 3. All advertising materials mentioning features or use of this software | ||
15 | .\" must display the following acknowledgement: | ||
16 | .\" This product includes software developed by the University of | ||
17 | .\" California, Berkeley and its contributors. | ||
18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
19 | .\" may be used to endorse or promote products derived from this software | ||
20 | .\" without specific prior written permission. | ||
21 | .\" | ||
22 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
23 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
24 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
26 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
27 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
28 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
29 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
30 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
32 | .\" SUCH DAMAGE. | ||
33 | .\" | ||
34 | .Dd June 4, 1993 | ||
35 | .Dt BYTEORDER 3 | ||
36 | .Os BSD 4.2 | ||
37 | .Sh NAME | ||
38 | .Nm htonl , | ||
39 | .Nm htons , | ||
40 | .Nm ntohl , | ||
41 | .Nm ntohs , | ||
42 | .Nm htobe32 , | ||
43 | .Nm htobe16 , | ||
44 | .Nm betoh32 , | ||
45 | .Nm betoh16 , | ||
46 | .Nm htole32 , | ||
47 | .Nm htole16 , | ||
48 | .Nm letoh32 , | ||
49 | .Nm letoh16 , | ||
50 | .Nm swap32 , | ||
51 | .Nm swap16 | ||
52 | .Nd convert values between different byte orderings | ||
53 | .Sh SYNOPSIS | ||
54 | .Fd #include <sys/types.h> | ||
55 | .Fd #include <machine/endian.h> | ||
56 | .Ft u_int32_t | ||
57 | .Fn htonl "u_int32_t host32" | ||
58 | .Ft u_int16_t | ||
59 | .Fn htons "u_int16_t host16" | ||
60 | .Ft u_int32_t | ||
61 | .Fn ntohl "u_int32_t net32" | ||
62 | .Ft u_int16_t | ||
63 | .Fn ntohs "u_int16_t net16" | ||
64 | .Ft u_int32_t | ||
65 | .Fn htobe32 "u_int32_t host32" | ||
66 | .Ft u_int16_t | ||
67 | .Fn htobe16 "u_int16_t host16" | ||
68 | .Ft u_int32_t | ||
69 | .Fn betoh32 "u_int32_t big32" | ||
70 | .Ft u_int16_t | ||
71 | .Fn betoh16 "u_int16_t big16" | ||
72 | .Ft u_int32_t | ||
73 | .Fn htole32 "u_int32_t host32" | ||
74 | .Ft u_int16_t | ||
75 | .Fn htole16 "u_int16_t host16" | ||
76 | .Ft u_int32_t | ||
77 | .Fn letoh32 "u_int32_t little32" | ||
78 | .Ft u_int16_t | ||
79 | .Fn letoh16 "u_int16_t little16" | ||
80 | .Ft u_int32_t | ||
81 | .Fn swap32 "u_int32_t val32" | ||
82 | .Ft u_int16_t | ||
83 | .Fn swap16 "u_int16_t val16" | ||
84 | .Sh DESCRIPTION | ||
85 | These routines convert 16 and 32 bit quantities between different | ||
86 | byte orderings. The "swap" functions reverse the byte ordering of | ||
87 | the given quantity, the others converts either from/to the native | ||
88 | byte order used by the host to/from either little- or big-endian (a.k.a | ||
89 | network) order. | ||
90 | .Pp | ||
91 | Apart from the "swap" functions, the names can be described by this form: | ||
92 | {src-order}to{dst-order}{size}. | ||
93 | Both {src-order} and {dst-order} can take the following forms: | ||
94 | .Bl -tag -width "be " | ||
95 | .It Em h | ||
96 | host order | ||
97 | .It Em n | ||
98 | network order (big-endian) | ||
99 | .It Em be | ||
100 | big-endian (Most significant byte first) | ||
101 | .It Em le | ||
102 | little-endian (Least significant byte first) | ||
103 | .El | ||
104 | .Pp | ||
105 | One of the specified orderings must be "h". | ||
106 | {Size} will take these forms: | ||
107 | .Bl -tag -width "32 " | ||
108 | .It Em l | ||
109 | long (32-bit, used in conjunction with forms involving "n") | ||
110 | .It Em s | ||
111 | short (16-bit, used in conjunction with forms involving "n") | ||
112 | .It Em 16 | ||
113 | 16-bit | ||
114 | .It Em 32 | ||
115 | 32-bit | ||
116 | .El | ||
117 | .Pp | ||
118 | The "swap" functions are of the form: swap{size}. | ||
119 | .Pp | ||
120 | Names involving "n" convert quantities between network | ||
121 | byte order and host byte order. The last letter (s/l) is a mnemonic | ||
122 | for the traditional names for such quantities, short and long, | ||
123 | respectively. Today, the C concept of "short"/"long" integers | ||
124 | need not coincide with this traditional misunderstanding. | ||
125 | On machines which have a byte order which is the same as the network | ||
126 | order, routines are defined as null macros. | ||
127 | .Pp | ||
128 | The functions involving either "be", "le" or "swap" use the numbers | ||
129 | (16/32) for specifying the bitwidth of the quantities they operate on. | ||
130 | Currently all supported architectures are either big- or little-endian | ||
131 | so either the "be" or the "le" variants are implemented as null macros. | ||
132 | .Pp | ||
133 | The routines mentioned above which have either {src-order} or {dst-order} | ||
134 | set to "n" are most often used in | ||
135 | conjunction with Internet addresses and ports as returned by | ||
136 | .Xr gethostbyname 3 | ||
137 | and | ||
138 | .Xr getservent 3 . | ||
139 | .Sh SEE ALSO | ||
140 | .Xr gethostbyname 3 , | ||
141 | .Xr getservent 3 | ||
142 | .Sh HISTORY | ||
143 | The | ||
144 | .Nm byteorder | ||
145 | functions appeared in | ||
146 | .Bx 4.2 . | ||
147 | .Sh BUGS | ||
148 | On the | ||
149 | .Tn vax , | ||
150 | .Tn alpha , | ||
151 | .Tn i386 , | ||
152 | and so far | ||
153 | .Tn mips | ||
154 | bytes are handled backwards from most everyone else in | ||
155 | the world. This is not expected to be fixed in the near future. | ||
diff --git a/src/lib/libc/net/ethers.3 b/src/lib/libc/net/ethers.3 new file mode 100644 index 0000000000..f5db308115 --- /dev/null +++ b/src/lib/libc/net/ethers.3 | |||
@@ -0,0 +1,109 @@ | |||
1 | .\" $OpenBSD: ethers.3,v 1.9 1998/05/12 09:15:19 deraadt Exp $ | ||
2 | .\" | ||
3 | .\" Written by roland@frob.com. Public domain. | ||
4 | .\" | ||
5 | .Dd December 16, 1993 | ||
6 | .Dt ETHERS 3 | ||
7 | .Os | ||
8 | .Sh NAME | ||
9 | .Nm ether_aton , | ||
10 | .Nm ether_ntoa , | ||
11 | .Nm ether_addr , | ||
12 | .Nm ether_ntohost , | ||
13 | .Nm ether_hostton , | ||
14 | .Nm ether_line | ||
15 | .Nd get ethers entry | ||
16 | .Sh SYNOPSIS | ||
17 | .Fd #include <netinet/if_ether.h> | ||
18 | .Ft char * | ||
19 | .Fn ether_ntoa "struct ether_addr *e" | ||
20 | .Ft struct ether_addr * | ||
21 | .Fn ether_aton "char *s" | ||
22 | .Ft int | ||
23 | .Fn ether_ntohost "char *hostname" "struct ether_addr *e" | ||
24 | .Ft int | ||
25 | .Fn ether_hostton "char *hostname" "struct ether_addr *e" | ||
26 | .Ft int | ||
27 | .Fn ether_line "char *l" "struct ether_addr *e" "char *hostname" | ||
28 | .Sh DESCRIPTION | ||
29 | Ethernet addresses are represented by the | ||
30 | following structure: | ||
31 | .Bd -literal -offset indent | ||
32 | struct ether_addr { | ||
33 | u_int8_t ether_addr_octet[6]; | ||
34 | }; | ||
35 | .Ed | ||
36 | .Pp | ||
37 | The | ||
38 | .Fn ether_ntoa | ||
39 | function converts this structure into an ASCII string of the form | ||
40 | ``xx:xx:xx:xx:xx:xx'', consisting of 6 hexadecimal numbers separated | ||
41 | by colons. It returns a pointer to a static buffer that is reused for | ||
42 | each call. | ||
43 | The | ||
44 | .Fn ether_aton | ||
45 | converts an ASCII string of the same form and to a structure | ||
46 | containing the 6 octets of the address. It returns a pointer to a | ||
47 | static structure that is reused for each call. | ||
48 | .Pp | ||
49 | The | ||
50 | .Fn ether_ntohost | ||
51 | and | ||
52 | .Fn ether_hostton | ||
53 | functions interrogate the data base mapping host names to Ethernet | ||
54 | addresses, | ||
55 | .Pa /etc/ethers . | ||
56 | The | ||
57 | .Fn ether_ntohost | ||
58 | function looks up the given Ethernet address and writes the associated | ||
59 | host name into the character buffer passed. This buffer should be | ||
60 | .Ev MAXHOSTNAMELEN | ||
61 | characters in size. | ||
62 | The | ||
63 | .Fn ether_hostton | ||
64 | function looks up the given host name and writes the associated | ||
65 | Ethernet address into the structure passed. Both functions return | ||
66 | zero if they find the requested host name or address, and -1 if not. | ||
67 | .Pp | ||
68 | Each call reads | ||
69 | .Pa /etc/ethers | ||
70 | from the beginning; if a + appears alone on a line in the file, then | ||
71 | .Fn ether_hostton | ||
72 | will consult the | ||
73 | .Pa ethers.byname | ||
74 | YP map, and | ||
75 | .Fn ether_ntohost | ||
76 | will consult the | ||
77 | .Pa ethers.byaddr | ||
78 | YP map. | ||
79 | .Pp | ||
80 | The | ||
81 | .Fn ether_line | ||
82 | function parses a line from the | ||
83 | .Pa /etc/ethers | ||
84 | file and fills in the passed ``struct ether_addr'' and character | ||
85 | buffer with the Ethernet address and host name on the line. It | ||
86 | returns zero if the line was successfully parsed and -1 if not. | ||
87 | The character buffer buffer should be | ||
88 | .Ev MAXHOSTNAMELEN | ||
89 | characters in size. | ||
90 | .Sh FILES | ||
91 | .Bl -tag -width /etc/ethers -compact | ||
92 | .It Pa /etc/ethers | ||
93 | .El | ||
94 | .Sh SEE ALSO | ||
95 | .Xr ethers 5 | ||
96 | .Sh HISTORY | ||
97 | The | ||
98 | .Fn ether_ntoa , | ||
99 | .Fn ether_aton , | ||
100 | .Fn ether_ntohost , | ||
101 | .Fn ether_hostton , | ||
102 | and | ||
103 | .Fn ether_line | ||
104 | functions were adopted from SunOS and appeared in | ||
105 | NetBSD 0.9b. | ||
106 | .Sh BUGS | ||
107 | The data space used by these functions is static; if future use | ||
108 | requires the data, it should be copied before any subsequent calls to | ||
109 | these functions overwrite it. | ||
diff --git a/src/lib/libc/net/ethers.c b/src/lib/libc/net/ethers.c new file mode 100644 index 0000000000..9df876b6f4 --- /dev/null +++ b/src/lib/libc/net/ethers.c | |||
@@ -0,0 +1,270 @@ | |||
1 | /* $OpenBSD: ethers.c,v 1.9 1998/06/21 22:13:44 millert Exp $ */ | ||
2 | |||
3 | /* | ||
4 | * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * 1. Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in the | ||
14 | * documentation and/or other materials provided with the distribution. | ||
15 | * 3. The name of the author may not be used to endorse or promote products | ||
16 | * derived from this software without specific prior written permission. | ||
17 | * | ||
18 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
19 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY | ||
20 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | ||
21 | * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
23 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||
24 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||
26 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||
27 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
28 | */ | ||
29 | |||
30 | /* | ||
31 | * ethers(3) a la Sun. | ||
32 | * Originally Written by Roland McGrath <roland@frob.com> 10/14/93. | ||
33 | * Substantially modified by Todd C. Miller <Todd.Miller@courtesan.com> | ||
34 | */ | ||
35 | |||
36 | #if defined(LIBC_SCCS) && !defined(lint) | ||
37 | static char rcsid[] = "$OpenBSD: ethers.c,v 1.9 1998/06/21 22:13:44 millert Exp $"; | ||
38 | #endif /* LIBC_SCCS and not lint */ | ||
39 | |||
40 | #include <sys/types.h> | ||
41 | #include <sys/socket.h> | ||
42 | #include <net/if.h> | ||
43 | #include <netinet/in.h> | ||
44 | #include <netinet/if_ether.h> | ||
45 | #include <sys/param.h> | ||
46 | #include <paths.h> | ||
47 | #include <errno.h> | ||
48 | #include <stdio.h> | ||
49 | #include <stdlib.h> | ||
50 | #include <string.h> | ||
51 | #include <ctype.h> | ||
52 | |||
53 | #ifndef _PATH_ETHERS | ||
54 | #define _PATH_ETHERS "/etc/ethers" | ||
55 | #endif | ||
56 | |||
57 | static char * _ether_aton __P((char *, struct ether_addr *)); | ||
58 | |||
59 | char * | ||
60 | ether_ntoa(e) | ||
61 | struct ether_addr *e; | ||
62 | { | ||
63 | static char a[] = "xx:xx:xx:xx:xx:xx"; | ||
64 | |||
65 | if (e->ether_addr_octet[0] > 0xFF || e->ether_addr_octet[1] > 0xFF || | ||
66 | e->ether_addr_octet[2] > 0xFF || e->ether_addr_octet[3] > 0xFF || | ||
67 | e->ether_addr_octet[4] > 0xFF || e->ether_addr_octet[5] > 0xFF) { | ||
68 | errno = EINVAL; | ||
69 | return (NULL); | ||
70 | } | ||
71 | |||
72 | (void)sprintf(a, "%02x:%02x:%02x:%02x:%02x:%02x", | ||
73 | e->ether_addr_octet[0], e->ether_addr_octet[1], | ||
74 | e->ether_addr_octet[2], e->ether_addr_octet[3], | ||
75 | e->ether_addr_octet[4], e->ether_addr_octet[5]); | ||
76 | |||
77 | return (a); | ||
78 | } | ||
79 | |||
80 | static char * | ||
81 | _ether_aton(s, e) | ||
82 | char *s; | ||
83 | struct ether_addr *e; | ||
84 | { | ||
85 | int i; | ||
86 | long l; | ||
87 | char *pp; | ||
88 | |||
89 | while (isspace(*s)) | ||
90 | s++; | ||
91 | |||
92 | /* expect 6 hex octets separated by ':' or space/NUL if last octet */ | ||
93 | for (i = 0; i < 6; i++) { | ||
94 | l = strtol(s, &pp, 16); | ||
95 | if (pp == s || l > 0xFF) | ||
96 | return (NULL); | ||
97 | if (!(*pp == ':' || (i == 5 && (isspace(*pp) || *pp == '\0')))) | ||
98 | return (NULL); | ||
99 | e->ether_addr_octet[i] = (u_char)l; | ||
100 | s = pp + 1; | ||
101 | } | ||
102 | |||
103 | /* return character after the octets ala strtol(3) */ | ||
104 | return (pp); | ||
105 | } | ||
106 | |||
107 | struct ether_addr * | ||
108 | ether_aton(s) | ||
109 | char *s; | ||
110 | { | ||
111 | static struct ether_addr n; | ||
112 | |||
113 | return (_ether_aton(s, &n) ? &n : NULL); | ||
114 | } | ||
115 | |||
116 | int | ||
117 | ether_ntohost(hostname, e) | ||
118 | char *hostname; | ||
119 | struct ether_addr *e; | ||
120 | { | ||
121 | FILE *f; | ||
122 | char buf[BUFSIZ+1], *p; | ||
123 | size_t len; | ||
124 | struct ether_addr try; | ||
125 | #ifdef YP | ||
126 | char trybuf[sizeof("xx:xx:xx:xx:xx:xx")]; | ||
127 | int trylen; | ||
128 | #endif | ||
129 | |||
130 | if (e->ether_addr_octet[0] > 0xFF || e->ether_addr_octet[1] > 0xFF || | ||
131 | e->ether_addr_octet[2] > 0xFF || e->ether_addr_octet[3] > 0xFF || | ||
132 | e->ether_addr_octet[4] > 0xFF || e->ether_addr_octet[5] > 0xFF) { | ||
133 | errno = EINVAL; | ||
134 | return (-1); | ||
135 | } | ||
136 | |||
137 | #ifdef YP | ||
138 | sprintf(trybuf, "%x:%x:%x:%x:%x:%x", | ||
139 | e->ether_addr_octet[0], e->ether_addr_octet[1], | ||
140 | e->ether_addr_octet[2], e->ether_addr_octet[3], | ||
141 | e->ether_addr_octet[4], e->ether_addr_octet[5]); | ||
142 | trylen = strlen(trybuf); | ||
143 | #endif | ||
144 | |||
145 | f = fopen(_PATH_ETHERS, "r"); | ||
146 | if (f == NULL) | ||
147 | return (-1); | ||
148 | while ((p = fgetln(f, &len)) != NULL) { | ||
149 | if (p[len-1] == '\n') | ||
150 | len--; | ||
151 | if (len > sizeof(buf) - 2) | ||
152 | continue; | ||
153 | (void)memcpy(buf, p, len); | ||
154 | buf[len] = '\n'; /* code assumes newlines later on */ | ||
155 | buf[len+1] = '\0'; | ||
156 | #ifdef YP | ||
157 | /* A + in the file means try YP now. */ | ||
158 | if (!strncmp(buf, "+\n", sizeof(buf))) { | ||
159 | char *ypbuf, *ypdom; | ||
160 | int ypbuflen; | ||
161 | |||
162 | if (yp_get_default_domain(&ypdom)) | ||
163 | continue; | ||
164 | if (yp_match(ypdom, "ethers.byaddr", trybuf, | ||
165 | trylen, &ypbuf, &ypbuflen)) | ||
166 | continue; | ||
167 | if (ether_line(ypbuf, &try, hostname) == 0) { | ||
168 | free(ypbuf); | ||
169 | (void)fclose(f); | ||
170 | return (0); | ||
171 | } | ||
172 | free(ypbuf); | ||
173 | continue; | ||
174 | } | ||
175 | #endif | ||
176 | if (ether_line(buf, &try, hostname) == 0 && | ||
177 | memcmp((void *)&try, (void *)e, sizeof(try)) == 0) { | ||
178 | (void)fclose(f); | ||
179 | return (0); | ||
180 | } | ||
181 | } | ||
182 | (void)fclose(f); | ||
183 | errno = ENOENT; | ||
184 | return (-1); | ||
185 | } | ||
186 | |||
187 | int | ||
188 | ether_hostton(hostname, e) | ||
189 | char *hostname; | ||
190 | struct ether_addr *e; | ||
191 | { | ||
192 | FILE *f; | ||
193 | char buf[BUFSIZ+1], *p; | ||
194 | char try[MAXHOSTNAMELEN]; | ||
195 | size_t len; | ||
196 | #ifdef YP | ||
197 | int hostlen = strlen(hostname); | ||
198 | #endif | ||
199 | |||
200 | f = fopen(_PATH_ETHERS, "r"); | ||
201 | if (f==NULL) | ||
202 | return (-1); | ||
203 | |||
204 | while ((p = fgetln(f, &len)) != NULL) { | ||
205 | if (p[len-1] == '\n') | ||
206 | len--; | ||
207 | if (len > sizeof(buf) - 2) | ||
208 | continue; | ||
209 | memcpy(buf, p, len); | ||
210 | buf[len] = '\n'; /* code assumes newlines later on */ | ||
211 | buf[len+1] = '\0'; | ||
212 | #ifdef YP | ||
213 | /* A + in the file means try YP now. */ | ||
214 | if (!strncmp(buf, "+\n", sizeof(buf))) { | ||
215 | char *ypbuf, *ypdom; | ||
216 | int ypbuflen; | ||
217 | |||
218 | if (yp_get_default_domain(&ypdom)) | ||
219 | continue; | ||
220 | if (yp_match(ypdom, "ethers.byname", hostname, hostlen, | ||
221 | &ypbuf, &ypbuflen)) | ||
222 | continue; | ||
223 | if (ether_line(ypbuf, e, try) == 0) { | ||
224 | free(ypbuf); | ||
225 | (void)fclose(f); | ||
226 | return (0); | ||
227 | } | ||
228 | free(ypbuf); | ||
229 | continue; | ||
230 | } | ||
231 | #endif | ||
232 | if (ether_line(buf, e, try) == 0 && strcmp(hostname, try) == 0) { | ||
233 | (void)fclose(f); | ||
234 | return (0); | ||
235 | } | ||
236 | } | ||
237 | (void)fclose(f); | ||
238 | errno = ENOENT; | ||
239 | return (-1); | ||
240 | } | ||
241 | |||
242 | int | ||
243 | ether_line(line, e, hostname) | ||
244 | char *line; | ||
245 | struct ether_addr *e; | ||
246 | char *hostname; | ||
247 | { | ||
248 | char *p; | ||
249 | size_t n; | ||
250 | |||
251 | /* Parse "xx:xx:xx:xx:xx:xx" */ | ||
252 | if ((p = _ether_aton(line, e)) == NULL || (*p != ' ' && *p != '\t')) | ||
253 | goto bad; | ||
254 | |||
255 | /* Now get the hostname */ | ||
256 | while (isspace(*p)) | ||
257 | p++; | ||
258 | if (*p == '\0') | ||
259 | goto bad; | ||
260 | n = strcspn(p, " \t\n"); | ||
261 | if (n >= MAXHOSTNAMELEN) | ||
262 | goto bad; | ||
263 | (void)strncpy(hostname, p, n); | ||
264 | hostname[n] = '\0'; | ||
265 | return (0); | ||
266 | |||
267 | bad: | ||
268 | errno = EINVAL; | ||
269 | return (-1); | ||
270 | } | ||
diff --git a/src/lib/libc/net/gethostbyname.3 b/src/lib/libc/net/gethostbyname.3 new file mode 100644 index 0000000000..37069c0a59 --- /dev/null +++ b/src/lib/libc/net/gethostbyname.3 | |||
@@ -0,0 +1,266 @@ | |||
1 | .\" $OpenBSD: gethostbyname.3,v 1.9 1998/09/07 16:44:35 aaron Exp $ | ||
2 | .\" | ||
3 | .\" Copyright (c) 1983, 1987, 1991, 1993 | ||
4 | .\" The Regents of the University of California. All rights reserved. | ||
5 | .\" | ||
6 | .\" Redistribution and use in source and binary forms, with or without | ||
7 | .\" modification, are permitted provided that the following conditions | ||
8 | .\" are met: | ||
9 | .\" 1. Redistributions of source code must retain the above copyright | ||
10 | .\" notice, this list of conditions and the following disclaimer. | ||
11 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
12 | .\" notice, this list of conditions and the following disclaimer in the | ||
13 | .\" documentation and/or other materials provided with the distribution. | ||
14 | .\" 3. All advertising materials mentioning features or use of this software | ||
15 | .\" must display the following acknowledgement: | ||
16 | .\" This product includes software developed by the University of | ||
17 | .\" California, Berkeley and its contributors. | ||
18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
19 | .\" may be used to endorse or promote products derived from this software | ||
20 | .\" without specific prior written permission. | ||
21 | .\" | ||
22 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
23 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
24 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
26 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
27 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
28 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
29 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
30 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
32 | .\" SUCH DAMAGE. | ||
33 | .\" | ||
34 | .Dd March 13, 1997 | ||
35 | .Dt GETHOSTBYNAME 3 | ||
36 | .Os | ||
37 | .Sh NAME | ||
38 | .Nm gethostbyname , | ||
39 | .Nm gethostbyname2 , | ||
40 | .Nm gethostbyaddr , | ||
41 | .Nm gethostent , | ||
42 | .Nm sethostent , | ||
43 | .Nm endhostent , | ||
44 | .Nm hstrerror , | ||
45 | .Nm herror | ||
46 | .Nd get network host entry | ||
47 | .Sh SYNOPSIS | ||
48 | .Fd #include <netdb.h> | ||
49 | .Fd extern int h_errno; | ||
50 | .Ft struct hostent * | ||
51 | .Fn gethostbyname "const char *name" | ||
52 | .Ft struct hostent * | ||
53 | .Fn gethostbyname2 "const char *name" "int af" | ||
54 | .Ft struct hostent * | ||
55 | .Fn gethostbyaddr "const char *addr" "int len" "int type" | ||
56 | .Ft struct hostent * | ||
57 | .Fn gethostent void | ||
58 | .Ft void | ||
59 | .Fn sethostent "int stayopen" | ||
60 | .Ft void | ||
61 | .Fn endhostent void | ||
62 | .Ft void | ||
63 | .Fn herror "const char *string" | ||
64 | .Ft const char * | ||
65 | .Fn hstrerror "int err" | ||
66 | .Sh DESCRIPTION | ||
67 | The | ||
68 | .Fn gethostbyname | ||
69 | and | ||
70 | .Fn gethostbyaddr | ||
71 | functions | ||
72 | each return a pointer to an object with the | ||
73 | following structure describing an internet host | ||
74 | referenced by name or by address, respectively. | ||
75 | This structure contains either the information obtained from the name server, | ||
76 | .Xr named 8 , | ||
77 | broken-out fields from a line in | ||
78 | .Pa /etc/hosts , | ||
79 | or database entries supplied by the | ||
80 | .Xr yp 8 | ||
81 | system . | ||
82 | If the local name server is not running these routines do a lookup in | ||
83 | .Pa /etc/hosts . | ||
84 | .Bd -literal | ||
85 | struct hostent { | ||
86 | char *h_name; /* official name of host */ | ||
87 | char **h_aliases; /* alias list */ | ||
88 | int h_addrtype; /* host address type */ | ||
89 | int h_length; /* length of address */ | ||
90 | char **h_addr_list; /* list of addresses from name server */ | ||
91 | }; | ||
92 | #define h_addr h_addr_list[0] /* address, for backward compatibility */ | ||
93 | .Ed | ||
94 | .Pp | ||
95 | The members of this structure are: | ||
96 | .Bl -tag -width h_addr_list | ||
97 | .It Fa h_name | ||
98 | Official name of the host. | ||
99 | .It Fa h_aliases | ||
100 | A zero terminated array of alternate names for the host. | ||
101 | .It Fa h_addrtype | ||
102 | The type of address being returned. | ||
103 | .It Fa h_length | ||
104 | The length, in bytes, of the address. | ||
105 | .It Fa h_addr_list | ||
106 | A zero terminated array of network addresses for the host. | ||
107 | Host addresses are returned in network byte order. | ||
108 | .It Fa h_addr | ||
109 | The first address in | ||
110 | .Fa h_addr_list ; | ||
111 | this is for backward compatibility. | ||
112 | .El | ||
113 | .Pp | ||
114 | When using the nameserver, | ||
115 | .Fn gethostbyname | ||
116 | will search for the named host in the current domain and its parents | ||
117 | unless the name ends in a dot. | ||
118 | If the name contains no dot, and if the environment variable | ||
119 | .Dq Ev HOSTALIASES | ||
120 | contains the name of an alias file, the alias file will first be searched | ||
121 | for an alias matching the input name. | ||
122 | See | ||
123 | .Xr hostname 7 | ||
124 | for the domain search procedure and the alias file format. | ||
125 | .Pp | ||
126 | .Fn Gethostbyname2 | ||
127 | is an advanced form of | ||
128 | .Fn gethostbyname | ||
129 | which allows lookups in address families other than | ||
130 | .Dv AF_INET , | ||
131 | for example | ||
132 | .Dv AF_INET6 . | ||
133 | .Pp | ||
134 | The | ||
135 | .Fn sethostent | ||
136 | function | ||
137 | may be used to request the use of a connected | ||
138 | .Tn TCP | ||
139 | socket for queries. | ||
140 | If the | ||
141 | .Fa stayopen | ||
142 | flag is non-zero, | ||
143 | this sets the option to send all queries to the name server using | ||
144 | .Tn TCP | ||
145 | and to retain the connection after each call to | ||
146 | .Fn gethostbyname | ||
147 | or | ||
148 | .Fn gethostbyaddr . | ||
149 | Otherwise, queries are performed using | ||
150 | .Tn UDP | ||
151 | datagrams. | ||
152 | .Pp | ||
153 | The | ||
154 | .Fn endhostent | ||
155 | function | ||
156 | closes the | ||
157 | .Tn TCP | ||
158 | connection. | ||
159 | .Pp | ||
160 | The | ||
161 | .Fn herror | ||
162 | function prints an error message describing the failure. If its argument | ||
163 | .Fa string | ||
164 | is | ||
165 | .Pf non Dv -NULL , | ||
166 | it is prepended to the message string and separated from it by a colon | ||
167 | and a space. The error message is printed with a trailing newline. | ||
168 | The contents of the error message is the same as that returned by | ||
169 | .Fn hstrerror | ||
170 | with argument | ||
171 | .Fa h_errno . | ||
172 | .Sh FILES | ||
173 | .Bl -tag -width /etc/hosts -compact | ||
174 | .It Pa /etc/hosts | ||
175 | .El | ||
176 | .Sh DIAGNOSTICS | ||
177 | Error return status from | ||
178 | .Fn gethostbyname , | ||
179 | .Fn gethostbyname2 , | ||
180 | and | ||
181 | .Fn gethostbyaddr | ||
182 | is indicated by return of a null pointer. | ||
183 | The external integer | ||
184 | .Va h_errno | ||
185 | may then be checked to see whether this is a temporary failure | ||
186 | or an invalid or unknown host. | ||
187 | .Pp | ||
188 | The variable | ||
189 | .Va h_errno | ||
190 | can have the following values: | ||
191 | .Bl -tag -width HOST_NOT_FOUND | ||
192 | .It Dv HOST_NOT_FOUND | ||
193 | No such host is known. | ||
194 | .It Dv TRY_AGAIN | ||
195 | This is usually a temporary error | ||
196 | and means that the local server did not receive | ||
197 | a response from an authoritative server. | ||
198 | A retry at some later time may succeed. | ||
199 | .It Dv NO_RECOVERY | ||
200 | Some unexpected server failure was encountered. | ||
201 | This is a non-recoverable error. | ||
202 | .It Dv NO_DATA | ||
203 | The requested name is valid but does not have an IP address; | ||
204 | this is not a temporary error. | ||
205 | This means that the name is known to the name server but there is no address | ||
206 | associated with this name. | ||
207 | Another type of request to the name server using this domain name | ||
208 | will result in an answer; | ||
209 | for example, a mail-forwarder may be registered for this domain. | ||
210 | .El | ||
211 | .Sh SEE ALSO | ||
212 | .Xr resolver 3 , | ||
213 | .Xr hosts 5 , | ||
214 | .Xr hostname 7 , | ||
215 | .Xr named 8 | ||
216 | .Sh CAVEAT | ||
217 | The | ||
218 | .Fn gethostent | ||
219 | function | ||
220 | reads the next line of | ||
221 | .Pa /etc/hosts , | ||
222 | opening the file if necessary. | ||
223 | .Pp | ||
224 | The | ||
225 | .Fn sethostent | ||
226 | function | ||
227 | opens and/or rewinds the file | ||
228 | .Pa /etc/hosts . | ||
229 | If the | ||
230 | .Fa stayopen | ||
231 | argument is non-zero, | ||
232 | the file will not be closed after each call to | ||
233 | .Fn gethostbyname , | ||
234 | .Fn gethostbyname2 , | ||
235 | or | ||
236 | .Fn gethostbyaddr . | ||
237 | .Pp | ||
238 | The | ||
239 | .Fn endhostent | ||
240 | function | ||
241 | closes the file. | ||
242 | .Sh HISTORY | ||
243 | The | ||
244 | .Fn herror | ||
245 | function appeared in | ||
246 | .Bx 4.3 . | ||
247 | The | ||
248 | .Fn endhostent , | ||
249 | .Fn gethostbyaddr , | ||
250 | .Fn gethostbyname , | ||
251 | .Fn gethostent , | ||
252 | and | ||
253 | .Fn sethostent | ||
254 | functions appeared in | ||
255 | .Bx 4.2 . | ||
256 | .Sh BUGS | ||
257 | These functions use static data storage; | ||
258 | if the data is needed for future use, it should be | ||
259 | copied before any subsequent calls overwrite it. | ||
260 | Only the Internet | ||
261 | address formats are currently understood. | ||
262 | .Pp | ||
263 | YP does not support any address families other than | ||
264 | .Dv AF_INET | ||
265 | and uses | ||
266 | the traditional database format. | ||
diff --git a/src/lib/libc/net/gethostnamadr.c b/src/lib/libc/net/gethostnamadr.c new file mode 100644 index 0000000000..7321225863 --- /dev/null +++ b/src/lib/libc/net/gethostnamadr.c | |||
@@ -0,0 +1,1079 @@ | |||
1 | /*- | ||
2 | * Copyright (c) 1985, 1988, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | * - | ||
33 | * Portions Copyright (c) 1993 by Digital Equipment Corporation. | ||
34 | * | ||
35 | * Permission to use, copy, modify, and distribute this software for any | ||
36 | * purpose with or without fee is hereby granted, provided that the above | ||
37 | * copyright notice and this permission notice appear in all copies, and that | ||
38 | * the name of Digital Equipment Corporation not be used in advertising or | ||
39 | * publicity pertaining to distribution of the document or software without | ||
40 | * specific, written prior permission. | ||
41 | * | ||
42 | * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL | ||
43 | * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES | ||
44 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT | ||
45 | * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
46 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
47 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
48 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
49 | * SOFTWARE. | ||
50 | * - | ||
51 | * --Copyright-- | ||
52 | */ | ||
53 | |||
54 | #if defined(LIBC_SCCS) && !defined(lint) | ||
55 | static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.30 1998/03/16 05:06:55 millert Exp $"; | ||
56 | #endif /* LIBC_SCCS and not lint */ | ||
57 | |||
58 | #include <sys/param.h> | ||
59 | #include <sys/socket.h> | ||
60 | #include <netinet/in.h> | ||
61 | #include <arpa/inet.h> | ||
62 | #include <arpa/nameser.h> | ||
63 | #include <netdb.h> | ||
64 | #include <resolv.h> | ||
65 | #include <stdio.h> | ||
66 | #include <ctype.h> | ||
67 | #include <errno.h> | ||
68 | #include <string.h> | ||
69 | #include <syslog.h> | ||
70 | #ifdef YP | ||
71 | #include <rpc/rpc.h> | ||
72 | #include <rpcsvc/yp.h> | ||
73 | #include <rpcsvc/ypclnt.h> | ||
74 | #include "ypinternal.h" | ||
75 | #endif | ||
76 | |||
77 | #define MULTI_PTRS_ARE_ALIASES 1 /* XXX - experimental */ | ||
78 | |||
79 | #define MAXALIASES 35 | ||
80 | #define MAXADDRS 35 | ||
81 | |||
82 | static char *h_addr_ptrs[MAXADDRS + 1]; | ||
83 | |||
84 | #ifdef YP | ||
85 | static char *__ypdomain; | ||
86 | #endif | ||
87 | |||
88 | static struct hostent host; | ||
89 | static char *host_aliases[MAXALIASES]; | ||
90 | static char hostbuf[BUFSIZ+1]; | ||
91 | static union { | ||
92 | struct in_addr _host_in_addr; | ||
93 | u_char _host_addr[16]; /* IPv4 or IPv6 */ | ||
94 | } _host_addr_u; | ||
95 | #define host_addr _host_addr_u._host_addr | ||
96 | static FILE *hostf = NULL; | ||
97 | static int stayopen = 0; | ||
98 | |||
99 | static void map_v4v6_address __P((const char *src, char *dst)); | ||
100 | static void map_v4v6_hostent __P((struct hostent *hp, char **bp, int *len)); | ||
101 | |||
102 | #ifdef RESOLVSORT | ||
103 | static void addrsort __P((char **, int)); | ||
104 | #endif | ||
105 | |||
106 | int _hokchar __P((const char *)); | ||
107 | |||
108 | static const char AskedForGot[] = | ||
109 | "gethostby*.getanswer: asked for \"%s\", got \"%s\""; | ||
110 | |||
111 | #if PACKETSZ > 1024 | ||
112 | #define MAXPACKET PACKETSZ | ||
113 | #else | ||
114 | #define MAXPACKET 1024 | ||
115 | #endif | ||
116 | |||
117 | typedef union { | ||
118 | HEADER hdr; | ||
119 | u_char buf[MAXPACKET]; | ||
120 | } querybuf; | ||
121 | |||
122 | typedef union { | ||
123 | int32_t al; | ||
124 | char ac; | ||
125 | } align; | ||
126 | |||
127 | static struct hostent *getanswer __P((const querybuf *, int, const char *, | ||
128 | int)); | ||
129 | |||
130 | extern int h_errno; | ||
131 | |||
132 | int | ||
133 | _hokchar(p) | ||
134 | const char *p; | ||
135 | { | ||
136 | char c; | ||
137 | |||
138 | /* | ||
139 | * Many people do not obey RFC 822 and 1035. The valid | ||
140 | * characters are a-z, A-Z, 0-9, '-' and . But the others | ||
141 | * tested for below can happen, and we must be more permissive | ||
142 | * than the resolver until those idiots clean up their act. | ||
143 | * We let '/' through, but not '..' | ||
144 | */ | ||
145 | while ((c = *p++)) { | ||
146 | if (('a' <= c && c <= 'z') || | ||
147 | ('A' <= c && c <= 'Z') || | ||
148 | ('0' <= c && c <= '9')) | ||
149 | continue; | ||
150 | if (strchr("-_/", c)) | ||
151 | continue; | ||
152 | if (c == '.' && *p != '.') | ||
153 | continue; | ||
154 | return 0; | ||
155 | } | ||
156 | return 1; | ||
157 | } | ||
158 | |||
159 | static struct hostent * | ||
160 | getanswer(answer, anslen, qname, qtype) | ||
161 | const querybuf *answer; | ||
162 | int anslen; | ||
163 | const char *qname; | ||
164 | int qtype; | ||
165 | { | ||
166 | register const HEADER *hp; | ||
167 | register const u_char *cp; | ||
168 | register int n; | ||
169 | const u_char *eom; | ||
170 | char *bp, **ap, **hap; | ||
171 | int type, class, buflen, ancount, qdcount; | ||
172 | int haveanswer, had_error; | ||
173 | int toobig = 0; | ||
174 | char tbuf[MAXDNAME]; | ||
175 | const char *tname; | ||
176 | int (*name_ok) __P((const char *)); | ||
177 | |||
178 | tname = qname; | ||
179 | host.h_name = NULL; | ||
180 | eom = answer->buf + anslen; | ||
181 | switch (qtype) { | ||
182 | case T_A: | ||
183 | case T_AAAA: | ||
184 | #ifdef USE_RESOLV_NAME_OK | ||
185 | name_ok = res_hnok; | ||
186 | break; | ||
187 | #endif | ||
188 | case T_PTR: | ||
189 | #ifdef USE_RESOLV_NAME_OK | ||
190 | name_ok = res_dnok; | ||
191 | #else | ||
192 | name_ok = _hokchar; | ||
193 | #endif | ||
194 | break; | ||
195 | default: | ||
196 | return (NULL); | ||
197 | } | ||
198 | /* | ||
199 | * find first satisfactory answer | ||
200 | */ | ||
201 | hp = &answer->hdr; | ||
202 | ancount = ntohs(hp->ancount); | ||
203 | qdcount = ntohs(hp->qdcount); | ||
204 | bp = hostbuf; | ||
205 | buflen = sizeof hostbuf; | ||
206 | cp = answer->buf + HFIXEDSZ; | ||
207 | if (qdcount != 1) { | ||
208 | h_errno = NO_RECOVERY; | ||
209 | return (NULL); | ||
210 | } | ||
211 | n = dn_expand(answer->buf, eom, cp, bp, buflen); | ||
212 | if ((n < 0) || !(*name_ok)(bp)) { | ||
213 | h_errno = NO_RECOVERY; | ||
214 | return (NULL); | ||
215 | } | ||
216 | cp += n + QFIXEDSZ; | ||
217 | if (qtype == T_A || qtype == T_AAAA) { | ||
218 | /* res_send() has already verified that the query name is the | ||
219 | * same as the one we sent; this just gets the expanded name | ||
220 | * (i.e., with the succeeding search-domain tacked on). | ||
221 | */ | ||
222 | n = strlen(bp) + 1; /* for the \0 */ | ||
223 | host.h_name = bp; | ||
224 | bp += n; | ||
225 | buflen -= n; | ||
226 | /* The qname can be abbreviated, but h_name is now absolute. */ | ||
227 | qname = host.h_name; | ||
228 | } | ||
229 | ap = host_aliases; | ||
230 | *ap = NULL; | ||
231 | host.h_aliases = host_aliases; | ||
232 | hap = h_addr_ptrs; | ||
233 | *hap = NULL; | ||
234 | host.h_addr_list = h_addr_ptrs; | ||
235 | haveanswer = 0; | ||
236 | had_error = 0; | ||
237 | while (ancount-- > 0 && cp < eom && !had_error) { | ||
238 | n = dn_expand(answer->buf, eom, cp, bp, buflen); | ||
239 | if ((n < 0) || !(*name_ok)(bp)) { | ||
240 | had_error++; | ||
241 | continue; | ||
242 | } | ||
243 | cp += n; /* name */ | ||
244 | type = _getshort(cp); | ||
245 | cp += INT16SZ; /* type */ | ||
246 | class = _getshort(cp); | ||
247 | cp += INT16SZ + INT32SZ; /* class, TTL */ | ||
248 | n = _getshort(cp); | ||
249 | cp += INT16SZ; /* len */ | ||
250 | if (class != C_IN) { | ||
251 | /* XXX - debug? syslog? */ | ||
252 | cp += n; | ||
253 | continue; /* XXX - had_error++ ? */ | ||
254 | } | ||
255 | if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) { | ||
256 | if (ap >= &host_aliases[MAXALIASES-1]) | ||
257 | continue; | ||
258 | n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); | ||
259 | if ((n < 0) || !(*name_ok)(tbuf)) { | ||
260 | had_error++; | ||
261 | continue; | ||
262 | } | ||
263 | cp += n; | ||
264 | /* Store alias. */ | ||
265 | *ap++ = bp; | ||
266 | n = strlen(bp) + 1; /* for the \0 */ | ||
267 | bp += n; | ||
268 | buflen -= n; | ||
269 | /* Get canonical name. */ | ||
270 | n = strlen(tbuf) + 1; /* for the \0 */ | ||
271 | if (n > buflen) { | ||
272 | had_error++; | ||
273 | continue; | ||
274 | } | ||
275 | strcpy(bp, tbuf); | ||
276 | host.h_name = bp; | ||
277 | bp += n; | ||
278 | buflen -= n; | ||
279 | continue; | ||
280 | } | ||
281 | if (qtype == T_PTR && type == T_CNAME) { | ||
282 | n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); | ||
283 | if ((n < 0) || !res_hnok(tbuf)) { | ||
284 | had_error++; | ||
285 | continue; | ||
286 | } | ||
287 | cp += n; | ||
288 | /* Get canonical name. */ | ||
289 | n = strlen(tbuf) + 1; /* for the \0 */ | ||
290 | if (n > buflen) { | ||
291 | had_error++; | ||
292 | continue; | ||
293 | } | ||
294 | strcpy(bp, tbuf); | ||
295 | tname = bp; | ||
296 | bp += n; | ||
297 | buflen -= n; | ||
298 | continue; | ||
299 | } | ||
300 | if (type != qtype) { | ||
301 | syslog(LOG_NOTICE|LOG_AUTH, | ||
302 | "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"", | ||
303 | qname, p_class(C_IN), p_type(qtype), | ||
304 | p_type(type)); | ||
305 | cp += n; | ||
306 | continue; /* XXX - had_error++ ? */ | ||
307 | } | ||
308 | switch (type) { | ||
309 | case T_PTR: | ||
310 | if (strcasecmp(tname, bp) != 0) { | ||
311 | syslog(LOG_NOTICE|LOG_AUTH, | ||
312 | AskedForGot, qname, bp); | ||
313 | cp += n; | ||
314 | continue; /* XXX - had_error++ ? */ | ||
315 | } | ||
316 | n = dn_expand(answer->buf, eom, cp, bp, buflen); | ||
317 | if ((n < 0) || !res_hnok(bp)) { | ||
318 | had_error++; | ||
319 | break; | ||
320 | } | ||
321 | #if MULTI_PTRS_ARE_ALIASES | ||
322 | cp += n; | ||
323 | if (!haveanswer) | ||
324 | host.h_name = bp; | ||
325 | else if (ap < &host_aliases[MAXALIASES-1]) | ||
326 | *ap++ = bp; | ||
327 | else | ||
328 | n = -1; | ||
329 | if (n != -1) { | ||
330 | n = strlen(bp) + 1; /* for the \0 */ | ||
331 | bp += n; | ||
332 | buflen -= n; | ||
333 | } | ||
334 | break; | ||
335 | #else | ||
336 | host.h_name = bp; | ||
337 | if (_res.options & RES_USE_INET6) { | ||
338 | n = strlen(bp) + 1; /* for the \0 */ | ||
339 | bp += n; | ||
340 | buflen -= n; | ||
341 | map_v4v6_hostent(&host, &bp, &buflen); | ||
342 | } | ||
343 | h_errno = NETDB_SUCCESS; | ||
344 | return (&host); | ||
345 | #endif | ||
346 | case T_A: | ||
347 | case T_AAAA: | ||
348 | if (strcasecmp(host.h_name, bp) != 0) { | ||
349 | syslog(LOG_NOTICE|LOG_AUTH, | ||
350 | AskedForGot, host.h_name, bp); | ||
351 | cp += n; | ||
352 | continue; /* XXX - had_error++ ? */ | ||
353 | } | ||
354 | if (n != host.h_length) { | ||
355 | cp += n; | ||
356 | continue; | ||
357 | } | ||
358 | if (!haveanswer) { | ||
359 | register int nn; | ||
360 | |||
361 | host.h_name = bp; | ||
362 | nn = strlen(bp) + 1; /* for the \0 */ | ||
363 | bp += nn; | ||
364 | buflen -= nn; | ||
365 | } | ||
366 | |||
367 | bp += sizeof(align) - ((u_long)bp % sizeof(align)); | ||
368 | |||
369 | if (bp + n >= &hostbuf[sizeof hostbuf]) { | ||
370 | #ifdef DEBUG | ||
371 | if (_res.options & RES_DEBUG) | ||
372 | printf("size (%d) too big\n", n); | ||
373 | #endif | ||
374 | had_error++; | ||
375 | continue; | ||
376 | } | ||
377 | if (hap >= &h_addr_ptrs[MAXADDRS-1]) { | ||
378 | if (!toobig++) | ||
379 | #ifdef DEBUG | ||
380 | if (_res.options & RES_DEBUG) | ||
381 | printf("Too many addresses (%d)\n", MAXADDRS); | ||
382 | #endif | ||
383 | cp += n; | ||
384 | continue; | ||
385 | } | ||
386 | bcopy(cp, *hap++ = bp, n); | ||
387 | bp += n; | ||
388 | buflen -= n; | ||
389 | cp += n; | ||
390 | break; | ||
391 | } | ||
392 | if (!had_error) | ||
393 | haveanswer++; | ||
394 | } | ||
395 | if (haveanswer) { | ||
396 | *ap = NULL; | ||
397 | *hap = NULL; | ||
398 | # if defined(RESOLVSORT) | ||
399 | /* | ||
400 | * Note: we sort even if host can take only one address | ||
401 | * in its return structures - should give it the "best" | ||
402 | * address in that case, not some random one | ||
403 | */ | ||
404 | if (_res.nsort && haveanswer > 1 && qtype == T_A) | ||
405 | addrsort(h_addr_ptrs, haveanswer); | ||
406 | # endif /*RESOLVSORT*/ | ||
407 | if (!host.h_name) { | ||
408 | n = strlen(qname) + 1; /* for the \0 */ | ||
409 | if (n > buflen) | ||
410 | goto try_again; | ||
411 | strcpy(bp, qname); | ||
412 | host.h_name = bp; | ||
413 | bp += n; | ||
414 | buflen -= n; | ||
415 | } | ||
416 | if (_res.options & RES_USE_INET6) | ||
417 | map_v4v6_hostent(&host, &bp, &buflen); | ||
418 | h_errno = NETDB_SUCCESS; | ||
419 | return (&host); | ||
420 | } | ||
421 | try_again: | ||
422 | h_errno = TRY_AGAIN; | ||
423 | return (NULL); | ||
424 | } | ||
425 | |||
426 | struct hostent * | ||
427 | gethostbyname(name) | ||
428 | const char *name; | ||
429 | { | ||
430 | struct hostent *hp; | ||
431 | extern struct hostent *_gethtbyname2(); | ||
432 | |||
433 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) | ||
434 | return (_gethtbyname2(name, AF_INET)); | ||
435 | |||
436 | if (_res.options & RES_USE_INET6) { | ||
437 | hp = gethostbyname2(name, AF_INET6); | ||
438 | if (hp) | ||
439 | return (hp); | ||
440 | } | ||
441 | return (gethostbyname2(name, AF_INET)); | ||
442 | } | ||
443 | |||
444 | struct hostent * | ||
445 | gethostbyname2(name, af) | ||
446 | const char *name; | ||
447 | int af; | ||
448 | { | ||
449 | querybuf buf; | ||
450 | register const char *cp; | ||
451 | char *bp; | ||
452 | int n, size, type, len, i; | ||
453 | extern struct hostent *_gethtbyname2(), *_yp_gethtbyname(); | ||
454 | register struct hostent *hp; | ||
455 | char lookups[MAXDNSLUS]; | ||
456 | |||
457 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) | ||
458 | return (_gethtbyname2(name, af)); | ||
459 | |||
460 | switch (af) { | ||
461 | case AF_INET: | ||
462 | size = INADDRSZ; | ||
463 | type = T_A; | ||
464 | break; | ||
465 | case AF_INET6: | ||
466 | size = IN6ADDRSZ; | ||
467 | type = T_AAAA; | ||
468 | break; | ||
469 | default: | ||
470 | h_errno = NETDB_INTERNAL; | ||
471 | errno = EAFNOSUPPORT; | ||
472 | return (NULL); | ||
473 | } | ||
474 | |||
475 | host.h_addrtype = af; | ||
476 | host.h_length = size; | ||
477 | |||
478 | /* | ||
479 | * if there aren't any dots, it could be a user-level alias. | ||
480 | * this is also done in res_query() since we are not the only | ||
481 | * function that looks up host names. | ||
482 | */ | ||
483 | if (!strchr(name, '.') && (cp = __hostalias(name))) | ||
484 | name = cp; | ||
485 | |||
486 | /* | ||
487 | * disallow names consisting only of digits/dots, unless | ||
488 | * they end in a dot. | ||
489 | */ | ||
490 | if (isdigit(name[0])) | ||
491 | for (cp = name;; ++cp) { | ||
492 | if (!*cp) { | ||
493 | if (*--cp == '.') | ||
494 | break; | ||
495 | /* | ||
496 | * All-numeric, no dot at the end. | ||
497 | * Fake up a hostent as if we'd actually | ||
498 | * done a lookup. | ||
499 | */ | ||
500 | if (inet_pton(af, name, host_addr) <= 0) { | ||
501 | h_errno = HOST_NOT_FOUND; | ||
502 | return (NULL); | ||
503 | } | ||
504 | strncpy(hostbuf, name, MAXHOSTNAMELEN-1); | ||
505 | hostbuf[MAXHOSTNAMELEN-1] = '\0'; | ||
506 | bp = hostbuf + MAXHOSTNAMELEN; | ||
507 | len = sizeof hostbuf - MAXHOSTNAMELEN; | ||
508 | host.h_name = hostbuf; | ||
509 | host.h_aliases = host_aliases; | ||
510 | host_aliases[0] = NULL; | ||
511 | h_addr_ptrs[0] = (char *)host_addr; | ||
512 | h_addr_ptrs[1] = NULL; | ||
513 | host.h_addr_list = h_addr_ptrs; | ||
514 | if (_res.options & RES_USE_INET6) | ||
515 | map_v4v6_hostent(&host, &bp, &len); | ||
516 | h_errno = NETDB_SUCCESS; | ||
517 | return (&host); | ||
518 | } | ||
519 | if (!isdigit(*cp) && *cp != '.') | ||
520 | break; | ||
521 | } | ||
522 | if ((isxdigit(name[0]) && strchr(name, ':') != NULL) || | ||
523 | name[0] == ':') | ||
524 | for (cp = name;; ++cp) { | ||
525 | if (!*cp) { | ||
526 | if (*--cp == '.') | ||
527 | break; | ||
528 | /* | ||
529 | * All-IPv6-legal, no dot at the end. | ||
530 | * Fake up a hostent as if we'd actually | ||
531 | * done a lookup. | ||
532 | */ | ||
533 | if (inet_pton(af, name, host_addr) <= 0) { | ||
534 | h_errno = HOST_NOT_FOUND; | ||
535 | return (NULL); | ||
536 | } | ||
537 | strncpy(hostbuf, name, MAXHOSTNAMELEN-1); | ||
538 | hostbuf[MAXHOSTNAMELEN-1] = '\0'; | ||
539 | bp = hostbuf + MAXHOSTNAMELEN; | ||
540 | len = sizeof hostbuf - MAXHOSTNAMELEN; | ||
541 | host.h_name = hostbuf; | ||
542 | host.h_aliases = host_aliases; | ||
543 | host_aliases[0] = NULL; | ||
544 | h_addr_ptrs[0] = (char *)host_addr; | ||
545 | h_addr_ptrs[1] = NULL; | ||
546 | host.h_addr_list = h_addr_ptrs; | ||
547 | h_errno = NETDB_SUCCESS; | ||
548 | return (&host); | ||
549 | } | ||
550 | if (!isxdigit(*cp) && *cp != ':' && *cp != '.') | ||
551 | break; | ||
552 | } | ||
553 | |||
554 | bcopy(_res.lookups, lookups, sizeof lookups); | ||
555 | if (lookups[0] == '\0') | ||
556 | strncpy(lookups, "bf", sizeof lookups); | ||
557 | |||
558 | hp = (struct hostent *)NULL; | ||
559 | for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) { | ||
560 | switch (lookups[i]) { | ||
561 | #ifdef YP | ||
562 | case 'y': | ||
563 | /* YP only supports AF_INET. */ | ||
564 | if (af == AF_INET) | ||
565 | hp = _yp_gethtbyname(name); | ||
566 | break; | ||
567 | #endif | ||
568 | case 'b': | ||
569 | if ((n = res_search(name, C_IN, type, buf.buf, | ||
570 | sizeof(buf))) < 0) { | ||
571 | #ifdef DEBUG | ||
572 | if (_res.options & RES_DEBUG) | ||
573 | printf("res_search failed\n"); | ||
574 | #endif | ||
575 | break; | ||
576 | } | ||
577 | hp = getanswer(&buf, n, name, type); | ||
578 | break; | ||
579 | case 'f': | ||
580 | hp = _gethtbyname2(name, af); | ||
581 | break; | ||
582 | } | ||
583 | } | ||
584 | /* XXX h_errno not correct in all cases... */ | ||
585 | return (hp); | ||
586 | } | ||
587 | |||
588 | struct hostent * | ||
589 | gethostbyaddr(addr, len, af) | ||
590 | const char *addr; /* XXX should have been def'd as u_char! */ | ||
591 | int len, af; | ||
592 | { | ||
593 | const u_char *uaddr = (const u_char *)addr; | ||
594 | static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff }; | ||
595 | static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 }; | ||
596 | int n, size, i; | ||
597 | querybuf buf; | ||
598 | register struct hostent *hp; | ||
599 | char qbuf[MAXDNAME+1], *qp; | ||
600 | extern struct hostent *_gethtbyaddr(), *_yp_gethtbyaddr(); | ||
601 | char lookups[MAXDNSLUS]; | ||
602 | |||
603 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) | ||
604 | return (_gethtbyaddr(addr, len, af)); | ||
605 | |||
606 | if (af == AF_INET6 && len == IN6ADDRSZ && | ||
607 | (!bcmp(uaddr, mapped, sizeof mapped) || | ||
608 | !bcmp(uaddr, tunnelled, sizeof tunnelled))) { | ||
609 | /* Unmap. */ | ||
610 | addr += sizeof mapped; | ||
611 | uaddr += sizeof mapped; | ||
612 | af = AF_INET; | ||
613 | len = INADDRSZ; | ||
614 | } | ||
615 | switch (af) { | ||
616 | case AF_INET: | ||
617 | size = INADDRSZ; | ||
618 | break; | ||
619 | case AF_INET6: | ||
620 | size = IN6ADDRSZ; | ||
621 | break; | ||
622 | default: | ||
623 | errno = EAFNOSUPPORT; | ||
624 | h_errno = NETDB_INTERNAL; | ||
625 | return (NULL); | ||
626 | } | ||
627 | if (size != len) { | ||
628 | errno = EINVAL; | ||
629 | h_errno = NETDB_INTERNAL; | ||
630 | return (NULL); | ||
631 | } | ||
632 | switch (af) { | ||
633 | case AF_INET: | ||
634 | (void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", | ||
635 | (uaddr[3] & 0xff), | ||
636 | (uaddr[2] & 0xff), | ||
637 | (uaddr[1] & 0xff), | ||
638 | (uaddr[0] & 0xff)); | ||
639 | break; | ||
640 | case AF_INET6: | ||
641 | qp = qbuf; | ||
642 | for (n = IN6ADDRSZ - 1; n >= 0; n--) { | ||
643 | qp += sprintf(qp, "%x.%x.", | ||
644 | uaddr[n] & 0xf, | ||
645 | (uaddr[n] >> 4) & 0xf); | ||
646 | } | ||
647 | strcpy(qp, "ip6.int"); | ||
648 | break; | ||
649 | } | ||
650 | |||
651 | bcopy(_res.lookups, lookups, sizeof lookups); | ||
652 | if (lookups[0] == '\0') | ||
653 | strncpy(lookups, "bf", sizeof lookups); | ||
654 | |||
655 | hp = (struct hostent *)NULL; | ||
656 | for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) { | ||
657 | switch (lookups[i]) { | ||
658 | #ifdef YP | ||
659 | case 'y': | ||
660 | /* YP only supports AF_INET. */ | ||
661 | if (af == AF_INET) | ||
662 | hp = _yp_gethtbyaddr(addr); | ||
663 | break; | ||
664 | #endif | ||
665 | case 'b': | ||
666 | n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, | ||
667 | sizeof buf.buf); | ||
668 | if (n < 0) { | ||
669 | #ifdef DEBUG | ||
670 | if (_res.options & RES_DEBUG) | ||
671 | printf("res_query failed\n"); | ||
672 | #endif | ||
673 | break; | ||
674 | } | ||
675 | if (!(hp = getanswer(&buf, n, qbuf, T_PTR))) | ||
676 | break; | ||
677 | hp->h_addrtype = af; | ||
678 | hp->h_length = len; | ||
679 | bcopy(addr, host_addr, len); | ||
680 | h_addr_ptrs[0] = (char *)host_addr; | ||
681 | h_addr_ptrs[1] = NULL; | ||
682 | if (af == AF_INET && (_res.options & RES_USE_INET6)) { | ||
683 | map_v4v6_address((char*)host_addr, | ||
684 | (char*)host_addr); | ||
685 | hp->h_addrtype = AF_INET6; | ||
686 | hp->h_length = IN6ADDRSZ; | ||
687 | } | ||
688 | h_errno = NETDB_SUCCESS; | ||
689 | break; | ||
690 | case 'f': | ||
691 | hp = _gethtbyaddr(addr, len, af); | ||
692 | break; | ||
693 | } | ||
694 | } | ||
695 | /* XXX h_errno not correct in all cases... */ | ||
696 | return (hp); | ||
697 | } | ||
698 | |||
699 | void | ||
700 | _sethtent(f) | ||
701 | int f; | ||
702 | { | ||
703 | if (hostf == NULL) | ||
704 | hostf = fopen(_PATH_HOSTS, "r" ); | ||
705 | else | ||
706 | rewind(hostf); | ||
707 | stayopen = f; | ||
708 | } | ||
709 | |||
710 | void | ||
711 | _endhtent() | ||
712 | { | ||
713 | if (hostf && !stayopen) { | ||
714 | (void) fclose(hostf); | ||
715 | hostf = NULL; | ||
716 | } | ||
717 | } | ||
718 | |||
719 | struct hostent * | ||
720 | _gethtent() | ||
721 | { | ||
722 | char *p; | ||
723 | register char *cp, **q; | ||
724 | int af; | ||
725 | size_t len; | ||
726 | |||
727 | if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) { | ||
728 | h_errno = NETDB_INTERNAL; | ||
729 | return (NULL); | ||
730 | } | ||
731 | again: | ||
732 | if ((p = fgetln(hostf, &len)) == NULL) { | ||
733 | h_errno = HOST_NOT_FOUND; | ||
734 | return (NULL); | ||
735 | } | ||
736 | if (p[len-1] == '\n') | ||
737 | len--; | ||
738 | if (len >= sizeof(hostbuf) || len == 0) | ||
739 | goto again; | ||
740 | p = memcpy(hostbuf, p, len); | ||
741 | hostbuf[len] = '\0'; | ||
742 | if (*p == '#') | ||
743 | goto again; | ||
744 | if ((cp = strchr(p, '#'))) | ||
745 | *cp = '\0'; | ||
746 | if (!(cp = strpbrk(p, " \t"))) | ||
747 | goto again; | ||
748 | *cp++ = '\0'; | ||
749 | if ((_res.options & RES_USE_INET6) && | ||
750 | inet_pton(AF_INET6, p, host_addr) > 0) { | ||
751 | af = AF_INET6; | ||
752 | len = IN6ADDRSZ; | ||
753 | } else if (inet_pton(AF_INET, p, host_addr) > 0) { | ||
754 | if (_res.options & RES_USE_INET6) { | ||
755 | map_v4v6_address((char*)host_addr, (char*)host_addr); | ||
756 | af = AF_INET6; | ||
757 | len = IN6ADDRSZ; | ||
758 | } else { | ||
759 | af = AF_INET; | ||
760 | len = INADDRSZ; | ||
761 | } | ||
762 | } else { | ||
763 | goto again; | ||
764 | } | ||
765 | h_addr_ptrs[0] = (char *)host_addr; | ||
766 | h_addr_ptrs[1] = NULL; | ||
767 | host.h_addr_list = h_addr_ptrs; | ||
768 | host.h_length = len; | ||
769 | host.h_addrtype = af; | ||
770 | while (*cp == ' ' || *cp == '\t') | ||
771 | cp++; | ||
772 | host.h_name = cp; | ||
773 | q = host.h_aliases = host_aliases; | ||
774 | if ((cp = strpbrk(cp, " \t"))) | ||
775 | *cp++ = '\0'; | ||
776 | while (cp && *cp) { | ||
777 | if (*cp == ' ' || *cp == '\t') { | ||
778 | cp++; | ||
779 | continue; | ||
780 | } | ||
781 | if (q < &host_aliases[MAXALIASES - 1]) | ||
782 | *q++ = cp; | ||
783 | if ((cp = strpbrk(cp, " \t"))) | ||
784 | *cp++ = '\0'; | ||
785 | } | ||
786 | *q = NULL; | ||
787 | if (_res.options & RES_USE_INET6) { | ||
788 | char *bp = hostbuf; | ||
789 | int buflen = sizeof hostbuf; | ||
790 | |||
791 | map_v4v6_hostent(&host, &bp, &buflen); | ||
792 | } | ||
793 | h_errno = NETDB_SUCCESS; | ||
794 | return (&host); | ||
795 | } | ||
796 | |||
797 | struct hostent * | ||
798 | _gethtbyname(name) | ||
799 | const char *name; | ||
800 | { | ||
801 | extern struct hostent *_gethtbyname2(); | ||
802 | struct hostent *hp; | ||
803 | |||
804 | if (_res.options & RES_USE_INET6) { | ||
805 | hp = _gethtbyname2(name, AF_INET6); | ||
806 | if (hp) | ||
807 | return (hp); | ||
808 | } | ||
809 | return (_gethtbyname2(name, AF_INET)); | ||
810 | } | ||
811 | |||
812 | struct hostent * | ||
813 | _gethtbyname2(name, af) | ||
814 | const char *name; | ||
815 | int af; | ||
816 | { | ||
817 | register struct hostent *p; | ||
818 | register char **cp; | ||
819 | |||
820 | _sethtent(0); | ||
821 | while ((p = _gethtent())) { | ||
822 | if (p->h_addrtype != af) | ||
823 | continue; | ||
824 | if (strcasecmp(p->h_name, name) == 0) | ||
825 | break; | ||
826 | for (cp = p->h_aliases; *cp != 0; cp++) | ||
827 | if (strcasecmp(*cp, name) == 0) | ||
828 | goto found; | ||
829 | } | ||
830 | found: | ||
831 | _endhtent(); | ||
832 | return (p); | ||
833 | } | ||
834 | |||
835 | struct hostent * | ||
836 | _gethtbyaddr(addr, len, af) | ||
837 | const char *addr; | ||
838 | int len, af; | ||
839 | { | ||
840 | register struct hostent *p; | ||
841 | |||
842 | _sethtent(0); | ||
843 | while ((p = _gethtent())) | ||
844 | if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len)) | ||
845 | break; | ||
846 | _endhtent(); | ||
847 | return (p); | ||
848 | } | ||
849 | |||
850 | #ifdef YP | ||
851 | struct hostent * | ||
852 | _yphostent(line) | ||
853 | char *line; | ||
854 | { | ||
855 | static struct in_addr host_addrs[MAXADDRS]; | ||
856 | char *p = line; | ||
857 | char *cp, **q; | ||
858 | char **hap; | ||
859 | struct in_addr *buf; | ||
860 | int more; | ||
861 | |||
862 | host.h_name = NULL; | ||
863 | host.h_addr_list = h_addr_ptrs; | ||
864 | host.h_length = INADDRSZ; | ||
865 | host.h_addrtype = AF_INET; | ||
866 | hap = h_addr_ptrs; | ||
867 | buf = host_addrs; | ||
868 | q = host.h_aliases = host_aliases; | ||
869 | |||
870 | nextline: | ||
871 | more = 0; | ||
872 | cp = strpbrk(p, " \t"); | ||
873 | if (cp == NULL) { | ||
874 | if (host.h_name == NULL) | ||
875 | return (NULL); | ||
876 | else | ||
877 | goto done; | ||
878 | } | ||
879 | *cp++ = '\0'; | ||
880 | |||
881 | *hap++ = (char *)buf; | ||
882 | (void) inet_aton(p, buf++); | ||
883 | |||
884 | while (*cp == ' ' || *cp == '\t') | ||
885 | cp++; | ||
886 | p = cp; | ||
887 | cp = strpbrk(p, " \t\n"); | ||
888 | if (cp != NULL) { | ||
889 | if (*cp == '\n') | ||
890 | more = 1; | ||
891 | *cp++ = '\0'; | ||
892 | } | ||
893 | if (!host.h_name) | ||
894 | host.h_name = p; | ||
895 | else if (strcmp(host.h_name, p)==0) | ||
896 | ; | ||
897 | else if (q < &host_aliases[MAXALIASES - 1]) | ||
898 | *q++ = p; | ||
899 | p = cp; | ||
900 | if (more) | ||
901 | goto nextline; | ||
902 | |||
903 | while (cp && *cp) { | ||
904 | if (*cp == ' ' || *cp == '\t') { | ||
905 | cp++; | ||
906 | continue; | ||
907 | } | ||
908 | if (*cp == '\n') { | ||
909 | cp++; | ||
910 | goto nextline; | ||
911 | } | ||
912 | if (q < &host_aliases[MAXALIASES - 1]) | ||
913 | *q++ = cp; | ||
914 | cp = strpbrk(cp, " \t"); | ||
915 | if (cp != NULL) | ||
916 | *cp++ = '\0'; | ||
917 | } | ||
918 | done: | ||
919 | *q = NULL; | ||
920 | *hap = NULL; | ||
921 | return (&host); | ||
922 | } | ||
923 | |||
924 | struct hostent * | ||
925 | _yp_gethtbyaddr(addr) | ||
926 | const char *addr; | ||
927 | { | ||
928 | struct hostent *hp = (struct hostent *)NULL; | ||
929 | static char *__ypcurrent; | ||
930 | int __ypcurrentlen, r; | ||
931 | char name[sizeof("xxx.xxx.xxx.xxx") + 1]; | ||
932 | |||
933 | if (!__ypdomain) { | ||
934 | if (_yp_check(&__ypdomain) == 0) | ||
935 | return (hp); | ||
936 | } | ||
937 | sprintf(name, "%u.%u.%u.%u", | ||
938 | ((unsigned)addr[0] & 0xff), | ||
939 | ((unsigned)addr[1] & 0xff), | ||
940 | ((unsigned)addr[2] & 0xff), | ||
941 | ((unsigned)addr[3] & 0xff)); | ||
942 | if (__ypcurrent) | ||
943 | free(__ypcurrent); | ||
944 | __ypcurrent = NULL; | ||
945 | r = yp_match(__ypdomain, "hosts.byaddr", name, | ||
946 | strlen(name), &__ypcurrent, &__ypcurrentlen); | ||
947 | if (r==0) | ||
948 | hp = _yphostent(__ypcurrent); | ||
949 | if (hp==NULL) | ||
950 | h_errno = HOST_NOT_FOUND; | ||
951 | return (hp); | ||
952 | } | ||
953 | |||
954 | struct hostent * | ||
955 | _yp_gethtbyname(name) | ||
956 | const char *name; | ||
957 | { | ||
958 | struct hostent *hp = (struct hostent *)NULL; | ||
959 | static char *__ypcurrent; | ||
960 | int __ypcurrentlen, r; | ||
961 | |||
962 | if (strlen(name) >= MAXHOSTNAMELEN) | ||
963 | return (NULL); | ||
964 | if (!__ypdomain) { | ||
965 | if (_yp_check(&__ypdomain) == 0) | ||
966 | return (hp); | ||
967 | } | ||
968 | if (__ypcurrent) | ||
969 | free(__ypcurrent); | ||
970 | __ypcurrent = NULL; | ||
971 | r = yp_match(__ypdomain, "hosts.byname", name, | ||
972 | strlen(name), &__ypcurrent, &__ypcurrentlen); | ||
973 | if (r == 0) | ||
974 | hp = _yphostent(__ypcurrent); | ||
975 | if (hp == NULL) | ||
976 | h_errno = HOST_NOT_FOUND; | ||
977 | return (hp); | ||
978 | } | ||
979 | #endif | ||
980 | |||
981 | static void | ||
982 | map_v4v6_address(src, dst) | ||
983 | const char *src; | ||
984 | char *dst; | ||
985 | { | ||
986 | u_char *p = (u_char *)dst; | ||
987 | char tmp[INADDRSZ]; | ||
988 | int i; | ||
989 | |||
990 | /* Stash a temporary copy so our caller can update in place. */ | ||
991 | bcopy(src, tmp, INADDRSZ); | ||
992 | /* Mark this ipv6 addr as a mapped ipv4. */ | ||
993 | for (i = 0; i < 10; i++) | ||
994 | *p++ = 0x00; | ||
995 | *p++ = 0xff; | ||
996 | *p++ = 0xff; | ||
997 | /* Retrieve the saved copy and we're done. */ | ||
998 | bcopy(tmp, (void*)p, INADDRSZ); | ||
999 | } | ||
1000 | |||
1001 | static void | ||
1002 | map_v4v6_hostent(hp, bpp, lenp) | ||
1003 | struct hostent *hp; | ||
1004 | char **bpp; | ||
1005 | int *lenp; | ||
1006 | { | ||
1007 | char **ap; | ||
1008 | |||
1009 | if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ) | ||
1010 | return; | ||
1011 | hp->h_addrtype = AF_INET6; | ||
1012 | hp->h_length = IN6ADDRSZ; | ||
1013 | for (ap = hp->h_addr_list; *ap; ap++) { | ||
1014 | int i = sizeof(align) - ((u_long)*bpp % sizeof(align)); | ||
1015 | |||
1016 | if (*lenp < (i + IN6ADDRSZ)) { | ||
1017 | /* Out of memory. Truncate address list here. XXX */ | ||
1018 | *ap = NULL; | ||
1019 | return; | ||
1020 | } | ||
1021 | *bpp += i; | ||
1022 | *lenp -= i; | ||
1023 | map_v4v6_address(*ap, *bpp); | ||
1024 | *ap = *bpp; | ||
1025 | *bpp += IN6ADDRSZ; | ||
1026 | *lenp -= IN6ADDRSZ; | ||
1027 | } | ||
1028 | } | ||
1029 | |||
1030 | struct hostent * | ||
1031 | gethostent() | ||
1032 | { | ||
1033 | return (_gethtent()); | ||
1034 | } | ||
1035 | |||
1036 | #ifdef RESOLVSORT | ||
1037 | static void | ||
1038 | addrsort(ap, num) | ||
1039 | char **ap; | ||
1040 | int num; | ||
1041 | { | ||
1042 | int i, j; | ||
1043 | char **p; | ||
1044 | short aval[MAXADDRS]; | ||
1045 | int needsort = 0; | ||
1046 | |||
1047 | p = ap; | ||
1048 | for (i = 0; i < num; i++, p++) { | ||
1049 | for (j = 0 ; (unsigned)j < _res.nsort; j++) | ||
1050 | if (_res.sort_list[j].addr.s_addr == | ||
1051 | (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask)) | ||
1052 | break; | ||
1053 | aval[i] = j; | ||
1054 | if (needsort == 0 && i > 0 && j < aval[i-1]) | ||
1055 | needsort = i; | ||
1056 | } | ||
1057 | if (!needsort) | ||
1058 | return; | ||
1059 | |||
1060 | while (needsort < num) { | ||
1061 | for (j = needsort - 1; j >= 0; j--) { | ||
1062 | if (aval[j] > aval[j+1]) { | ||
1063 | char *hp; | ||
1064 | |||
1065 | i = aval[j]; | ||
1066 | aval[j] = aval[j+1]; | ||
1067 | aval[j+1] = i; | ||
1068 | |||
1069 | hp = ap[j]; | ||
1070 | ap[j] = ap[j+1]; | ||
1071 | ap[j+1] = hp; | ||
1072 | |||
1073 | } else | ||
1074 | break; | ||
1075 | } | ||
1076 | needsort++; | ||
1077 | } | ||
1078 | } | ||
1079 | #endif | ||
diff --git a/src/lib/libc/net/getnetbyaddr.c b/src/lib/libc/net/getnetbyaddr.c new file mode 100644 index 0000000000..925d1d5895 --- /dev/null +++ b/src/lib/libc/net/getnetbyaddr.c | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1983, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: getnetbyaddr.c,v 1.5 1997/07/09 01:08:28 millert Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | #include <netdb.h> | ||
39 | |||
40 | extern int _net_stayopen; | ||
41 | |||
42 | struct netent * | ||
43 | _getnetbyaddr(net, type) | ||
44 | register in_addr_t net; | ||
45 | register int type; | ||
46 | { | ||
47 | register struct netent *p; | ||
48 | |||
49 | setnetent(_net_stayopen); | ||
50 | while ((p = getnetent())) | ||
51 | if (p->n_addrtype == type && p->n_net == net) | ||
52 | break; | ||
53 | if (!_net_stayopen) | ||
54 | endnetent(); | ||
55 | return (p); | ||
56 | } | ||
diff --git a/src/lib/libc/net/getnetbyname.c b/src/lib/libc/net/getnetbyname.c new file mode 100644 index 0000000000..4e39cf6860 --- /dev/null +++ b/src/lib/libc/net/getnetbyname.c | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1983, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: getnetbyname.c,v 1.5 1997/07/09 01:08:29 millert Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | #include <netdb.h> | ||
39 | #include <string.h> | ||
40 | |||
41 | extern int _net_stayopen; | ||
42 | |||
43 | struct netent * | ||
44 | _getnetbyname(name) | ||
45 | register const char *name; | ||
46 | { | ||
47 | register struct netent *p; | ||
48 | register char **cp; | ||
49 | |||
50 | setnetent(_net_stayopen); | ||
51 | while ((p = getnetent())) { | ||
52 | if (strcasecmp(p->n_name, name) == 0) | ||
53 | break; | ||
54 | for (cp = p->n_aliases; *cp != 0; cp++) | ||
55 | if (strcasecmp(*cp, name) == 0) | ||
56 | goto found; | ||
57 | } | ||
58 | found: | ||
59 | if (!_net_stayopen) | ||
60 | endnetent(); | ||
61 | return (p); | ||
62 | } | ||
diff --git a/src/lib/libc/net/getnetent.3 b/src/lib/libc/net/getnetent.3 new file mode 100644 index 0000000000..5864b75839 --- /dev/null +++ b/src/lib/libc/net/getnetent.3 | |||
@@ -0,0 +1,148 @@ | |||
1 | .\" $OpenBSD: getnetent.3,v 1.5 1998/03/16 05:06:56 millert Exp $ | ||
2 | .\" | ||
3 | .\" Copyright (c) 1983, 1991, 1993 | ||
4 | .\" The Regents of the University of California. All rights reserved. | ||
5 | .\" | ||
6 | .\" Redistribution and use in source and binary forms, with or without | ||
7 | .\" modification, are permitted provided that the following conditions | ||
8 | .\" are met: | ||
9 | .\" 1. Redistributions of source code must retain the above copyright | ||
10 | .\" notice, this list of conditions and the following disclaimer. | ||
11 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
12 | .\" notice, this list of conditions and the following disclaimer in the | ||
13 | .\" documentation and/or other materials provided with the distribution. | ||
14 | .\" 3. All advertising materials mentioning features or use of this software | ||
15 | .\" must display the following acknowledgement: | ||
16 | .\" This product includes software developed by the University of | ||
17 | .\" California, Berkeley and its contributors. | ||
18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
19 | .\" may be used to endorse or promote products derived from this software | ||
20 | .\" without specific prior written permission. | ||
21 | .\" | ||
22 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
23 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
24 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
26 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
27 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
28 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
29 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
30 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
32 | .\" SUCH DAMAGE. | ||
33 | .\" | ||
34 | .Dd March 13, 1997 | ||
35 | .Dt GETNETENT 3 | ||
36 | .Os | ||
37 | .Sh NAME | ||
38 | .Nm getnetent , | ||
39 | .Nm getnetbyaddr , | ||
40 | .Nm getnetbyname , | ||
41 | .Nm setnetent , | ||
42 | .Nm endnetent | ||
43 | .Nd get network entry | ||
44 | .Sh SYNOPSIS | ||
45 | .Fd #include <netdb.h> | ||
46 | .Ft struct netent * | ||
47 | .Fn getnetent | ||
48 | .Ft struct netent * | ||
49 | .Fn getnetbyname "char *name" | ||
50 | .Ft struct netent * | ||
51 | .Fn getnetbyaddr "in_addr_t net" "int type" | ||
52 | .Fn setnetent "int stayopen" | ||
53 | .Fn endnetent | ||
54 | .Sh DESCRIPTION | ||
55 | The | ||
56 | .Fn getnetent , | ||
57 | .Fn getnetbyname , | ||
58 | and | ||
59 | .Fn getnetbyaddr | ||
60 | functions | ||
61 | each return a pointer to an object with the | ||
62 | following structure | ||
63 | containing the broken-out | ||
64 | fields of a line in the network data base, | ||
65 | .Pa /etc/networks . | ||
66 | .Bd -literal -offset indent | ||
67 | struct netent { | ||
68 | char *n_name; /* official name of net */ | ||
69 | char **n_aliases; /* alias list */ | ||
70 | int n_addrtype; /* net number type */ | ||
71 | in_addr_t n_net; /* net number */ | ||
72 | }; | ||
73 | .Ed | ||
74 | .Pp | ||
75 | The members of this structure are: | ||
76 | .Bl -tag -width n_addrtype | ||
77 | .It Fa n_name | ||
78 | The official name of the network. | ||
79 | .It Fa n_aliases | ||
80 | A zero terminated list of alternate names for the network. | ||
81 | .It Fa n_addrtype | ||
82 | The type of the network number returned; currently only AF_INET. | ||
83 | .It Fa n_net | ||
84 | The network number. Network numbers are returned in machine byte | ||
85 | order. | ||
86 | .El | ||
87 | .Pp | ||
88 | The | ||
89 | .Fn getnetent | ||
90 | function | ||
91 | reads the next line of the file, opening the file if necessary. | ||
92 | .Pp | ||
93 | The | ||
94 | .Fn setnetent | ||
95 | function | ||
96 | opens and rewinds the file. If the | ||
97 | .Fa stayopen | ||
98 | flag is non-zero, | ||
99 | the net data base will not be closed after each call to | ||
100 | .Fn getnetbyname | ||
101 | or | ||
102 | .Fn getnetbyaddr . | ||
103 | .Pp | ||
104 | The | ||
105 | .Fn endnetent | ||
106 | function | ||
107 | closes the file. | ||
108 | .Pp | ||
109 | The | ||
110 | .Fn getnetbyname | ||
111 | function | ||
112 | and | ||
113 | .Fn getnetbyaddr | ||
114 | search the domain name server if the system is configured to use one. | ||
115 | If the search fails, or no name server is configured, they sequentially | ||
116 | search from the beginning of the file until a matching net name or | ||
117 | net address and type is found, or until | ||
118 | .Dv EOF | ||
119 | is encountered. | ||
120 | Network numbers are supplied in host order. | ||
121 | .Sh FILES | ||
122 | .Bl -tag -width /etc/networks -compact | ||
123 | .It Pa /etc/networks | ||
124 | .El | ||
125 | .Sh DIAGNOSTICS | ||
126 | Null pointer | ||
127 | (0) returned on | ||
128 | .Dv EOF | ||
129 | or error. | ||
130 | .Sh SEE ALSO | ||
131 | .Xr networks 5 , | ||
132 | .Xr resolver 3 | ||
133 | .Sh HISTORY | ||
134 | The | ||
135 | .Fn getnetent , | ||
136 | .Fn getnetbyaddr , | ||
137 | .Fn getnetbyname , | ||
138 | .Fn setnetent , | ||
139 | and | ||
140 | .Fn endnetent | ||
141 | functions appeared in | ||
142 | .Bx 4.2 . | ||
143 | .Sh BUGS | ||
144 | The data space used by these functions is static; if future use | ||
145 | requires the data, it should be copied before any subsequent calls | ||
146 | to these functions overwrite it. Only Internet network numbers | ||
147 | are currently understood. Expecting network numbers to fit in no | ||
148 | more than 32 bits is naive. | ||
diff --git a/src/lib/libc/net/getnetent.c b/src/lib/libc/net/getnetent.c new file mode 100644 index 0000000000..8f618a1d5e --- /dev/null +++ b/src/lib/libc/net/getnetent.c | |||
@@ -0,0 +1,129 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1983, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: getnetent.c,v 1.8 1998/03/16 05:06:57 millert Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | #include <sys/types.h> | ||
39 | #include <sys/socket.h> | ||
40 | #include <netinet/in.h> | ||
41 | #include <arpa/inet.h> | ||
42 | #include <netdb.h> | ||
43 | #include <stdio.h> | ||
44 | #include <string.h> | ||
45 | |||
46 | #define MAXALIASES 35 | ||
47 | |||
48 | static FILE *netf; | ||
49 | static char line[BUFSIZ+1]; | ||
50 | static struct netent net; | ||
51 | static char *net_aliases[MAXALIASES]; | ||
52 | int _net_stayopen; | ||
53 | |||
54 | void | ||
55 | setnetent(f) | ||
56 | int f; | ||
57 | { | ||
58 | if (netf == NULL) | ||
59 | netf = fopen(_PATH_NETWORKS, "r" ); | ||
60 | else | ||
61 | rewind(netf); | ||
62 | _net_stayopen |= f; | ||
63 | } | ||
64 | |||
65 | void | ||
66 | endnetent() | ||
67 | { | ||
68 | if (netf) { | ||
69 | fclose(netf); | ||
70 | netf = NULL; | ||
71 | } | ||
72 | _net_stayopen = 0; | ||
73 | } | ||
74 | |||
75 | struct netent * | ||
76 | getnetent() | ||
77 | { | ||
78 | char *p, *cp, **q; | ||
79 | size_t len; | ||
80 | |||
81 | if (netf == NULL && (netf = fopen(_PATH_NETWORKS, "r" )) == NULL) | ||
82 | return (NULL); | ||
83 | again: | ||
84 | if ((p = fgetln(netf, &len)) == NULL) | ||
85 | return (NULL); | ||
86 | if (p[len-1] == '\n') | ||
87 | len--; | ||
88 | if (len >= sizeof(line) || len == 0) | ||
89 | goto again; | ||
90 | p = memcpy(line, p, len); | ||
91 | line[len] = '\0'; | ||
92 | if (*p == '#') | ||
93 | goto again; | ||
94 | if ((cp = strchr(p, '#')) != NULL) | ||
95 | *cp = '\0'; | ||
96 | net.n_name = p; | ||
97 | if (strlen(net.n_name) >= MAXHOSTNAMELEN-1) | ||
98 | net.n_name[MAXHOSTNAMELEN-1] = '\0'; | ||
99 | cp = strpbrk(p, " \t"); | ||
100 | if (cp == NULL) | ||
101 | goto again; | ||
102 | *cp++ = '\0'; | ||
103 | while (*cp == ' ' || *cp == '\t') | ||
104 | cp++; | ||
105 | p = strpbrk(cp, " \t"); | ||
106 | if (p != NULL) | ||
107 | *p++ = '\0'; | ||
108 | net.n_net = inet_network(cp); | ||
109 | net.n_addrtype = AF_INET; | ||
110 | q = net.n_aliases = net_aliases; | ||
111 | if (p != NULL) | ||
112 | cp = p; | ||
113 | while (cp && *cp) { | ||
114 | if (*cp == ' ' || *cp == '\t') { | ||
115 | cp++; | ||
116 | continue; | ||
117 | } | ||
118 | if (q < &net_aliases[MAXALIASES - 1]) { | ||
119 | *q++ = cp; | ||
120 | if (strlen(cp) >= MAXHOSTNAMELEN-1) | ||
121 | cp[MAXHOSTNAMELEN-1] = '\0'; | ||
122 | } | ||
123 | cp = strpbrk(cp, " \t"); | ||
124 | if (cp != NULL) | ||
125 | *cp++ = '\0'; | ||
126 | } | ||
127 | *q = NULL; | ||
128 | return (&net); | ||
129 | } | ||
diff --git a/src/lib/libc/net/getnetnamadr.c b/src/lib/libc/net/getnetnamadr.c new file mode 100644 index 0000000000..de208bbac9 --- /dev/null +++ b/src/lib/libc/net/getnetnamadr.c | |||
@@ -0,0 +1,382 @@ | |||
1 | /* $OpenBSD: getnetnamadr.c,v 1.10 1997/12/02 01:34:05 deraadt Exp $ */ | ||
2 | |||
3 | /* | ||
4 | * Copyright (c) 1997, Jason Downs. All rights reserved. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * 3. All advertising materials mentioning features or use of this software | ||
15 | * must display the following acknowledgement: | ||
16 | * This product includes software developed by Jason Downs for the | ||
17 | * OpenBSD system. | ||
18 | * 4. Neither the name(s) of the author(s) nor the name OpenBSD | ||
19 | * may be used to endorse or promote products derived from this software | ||
20 | * without specific prior written permission. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS | ||
23 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
24 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
25 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, | ||
26 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
27 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
28 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
32 | * SUCH DAMAGE. | ||
33 | */ | ||
34 | /* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro | ||
35 | * Dep. Matematica Universidade de Coimbra, Portugal, Europe | ||
36 | * | ||
37 | * Permission to use, copy, modify, and distribute this software for any | ||
38 | * purpose with or without fee is hereby granted, provided that the above | ||
39 | * copyright notice and this permission notice appear in all copies. | ||
40 | */ | ||
41 | /* | ||
42 | * Copyright (c) 1983, 1993 | ||
43 | * The Regents of the University of California. All rights reserved. | ||
44 | * | ||
45 | * Redistribution and use in source and binary forms, with or without | ||
46 | * modification, are permitted provided that the following conditions | ||
47 | * are met: | ||
48 | * 1. Redistributions of source code must retain the above copyright | ||
49 | * notice, this list of conditions and the following disclaimer. | ||
50 | * 2. Redistributions in binary form must reproduce the above copyright | ||
51 | * notice, this list of conditions and the following disclaimer in the | ||
52 | * documentation and/or other materials provided with the distribution. | ||
53 | * 3. All advertising materials mentioning features or use of this software | ||
54 | * must display the following acknowledgement: | ||
55 | * This product includes software developed by the University of | ||
56 | * California, Berkeley and its contributors. | ||
57 | * 4. Neither the name of the University nor the names of its contributors | ||
58 | * may be used to endorse or promote products derived from this software | ||
59 | * without specific prior written permission. | ||
60 | * | ||
61 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
62 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
63 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
64 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
65 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
66 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
67 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
68 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
69 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
70 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
71 | * SUCH DAMAGE. | ||
72 | */ | ||
73 | |||
74 | #if defined(LIBC_SCCS) && !defined(lint) | ||
75 | #if 0 | ||
76 | static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93"; | ||
77 | static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03"; | ||
78 | static char rcsid[] = "$From: getnetnamadr.c,v 8.7 1996/08/05 08:31:35 vixie Exp $"; | ||
79 | #else | ||
80 | static char rcsid[] = "$OpenBSD: getnetnamadr.c,v 1.10 1997/12/02 01:34:05 deraadt Exp $"; | ||
81 | #endif | ||
82 | #endif /* LIBC_SCCS and not lint */ | ||
83 | |||
84 | #include <sys/types.h> | ||
85 | #include <sys/param.h> | ||
86 | #include <sys/socket.h> | ||
87 | #include <netinet/in.h> | ||
88 | #include <arpa/inet.h> | ||
89 | #include <arpa/nameser.h> | ||
90 | |||
91 | #include <stdio.h> | ||
92 | #include <netdb.h> | ||
93 | #include <resolv.h> | ||
94 | #include <ctype.h> | ||
95 | #include <errno.h> | ||
96 | #include <string.h> | ||
97 | |||
98 | extern int h_errno; | ||
99 | |||
100 | struct netent *_getnetbyaddr __P((in_addr_t net, int type)); | ||
101 | struct netent *_getnetbyname __P((const char *name)); | ||
102 | |||
103 | int _hokchar __P((const char *)); | ||
104 | |||
105 | #define BYADDR 0 | ||
106 | #define BYNAME 1 | ||
107 | #define MAXALIASES 35 | ||
108 | |||
109 | #if PACKETSZ > 1024 | ||
110 | #define MAXPACKET PACKETSZ | ||
111 | #else | ||
112 | #define MAXPACKET 1024 | ||
113 | #endif | ||
114 | |||
115 | typedef union { | ||
116 | HEADER hdr; | ||
117 | u_char buf[MAXPACKET]; | ||
118 | } querybuf; | ||
119 | |||
120 | typedef union { | ||
121 | long al; | ||
122 | char ac; | ||
123 | } align; | ||
124 | |||
125 | static struct netent * | ||
126 | getnetanswer(answer, anslen, net_i) | ||
127 | querybuf *answer; | ||
128 | int anslen; | ||
129 | int net_i; | ||
130 | { | ||
131 | |||
132 | register HEADER *hp; | ||
133 | register u_char *cp; | ||
134 | register int n; | ||
135 | u_char *eom; | ||
136 | int type, class, buflen, ancount, qdcount, haveanswer, i, nchar; | ||
137 | char aux1[MAXHOSTNAMELEN], aux2[MAXHOSTNAMELEN], ans[MAXHOSTNAMELEN]; | ||
138 | char *in, *st, *pauxt, *bp, **ap; | ||
139 | char *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0; | ||
140 | static struct netent net_entry; | ||
141 | static char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1]; | ||
142 | |||
143 | /* | ||
144 | * find first satisfactory answer | ||
145 | * | ||
146 | * answer --> +------------+ ( MESSAGE ) | ||
147 | * | Header | | ||
148 | * +------------+ | ||
149 | * | Question | the question for the name server | ||
150 | * +------------+ | ||
151 | * | Answer | RRs answering the question | ||
152 | * +------------+ | ||
153 | * | Authority | RRs pointing toward an authority | ||
154 | * | Additional | RRs holding additional information | ||
155 | * +------------+ | ||
156 | */ | ||
157 | eom = answer->buf + anslen; | ||
158 | hp = &answer->hdr; | ||
159 | ancount = ntohs(hp->ancount); /* #/records in the answer section */ | ||
160 | qdcount = ntohs(hp->qdcount); /* #/entries in the question section */ | ||
161 | bp = netbuf; | ||
162 | buflen = sizeof(netbuf); | ||
163 | cp = answer->buf + HFIXEDSZ; | ||
164 | if (!qdcount) { | ||
165 | if (hp->aa) | ||
166 | h_errno = HOST_NOT_FOUND; | ||
167 | else | ||
168 | h_errno = TRY_AGAIN; | ||
169 | return (NULL); | ||
170 | } | ||
171 | while (qdcount-- > 0) | ||
172 | cp += __dn_skipname(cp, eom) + QFIXEDSZ; | ||
173 | ap = net_aliases; | ||
174 | *ap = NULL; | ||
175 | net_entry.n_aliases = net_aliases; | ||
176 | haveanswer = 0; | ||
177 | while (--ancount >= 0 && cp < eom) { | ||
178 | n = dn_expand(answer->buf, eom, cp, bp, buflen); | ||
179 | #ifdef USE_RESOLV_NAME_OK | ||
180 | if ((n < 0) || !res_dnok(bp)) | ||
181 | #else | ||
182 | if ((n < 0) || !_hokchar(bp)) | ||
183 | #endif | ||
184 | break; | ||
185 | cp += n; | ||
186 | ans[0] = '\0'; | ||
187 | (void)strncpy(&ans[0], bp, sizeof ans-1); | ||
188 | ans[sizeof ans-1] = '\0'; | ||
189 | GETSHORT(type, cp); | ||
190 | GETSHORT(class, cp); | ||
191 | cp += INT32SZ; /* TTL */ | ||
192 | GETSHORT(n, cp); | ||
193 | if (class == C_IN && type == T_PTR) { | ||
194 | n = dn_expand(answer->buf, eom, cp, bp, buflen); | ||
195 | if ((n < 0) || !res_hnok(bp)) { | ||
196 | cp += n; | ||
197 | return (NULL); | ||
198 | } | ||
199 | cp += n; | ||
200 | *ap++ = bp; | ||
201 | bp += strlen(bp) + 1; | ||
202 | net_entry.n_addrtype = | ||
203 | (class == C_IN) ? AF_INET : AF_UNSPEC; | ||
204 | haveanswer++; | ||
205 | } | ||
206 | } | ||
207 | if (haveanswer) { | ||
208 | *ap = NULL; | ||
209 | switch (net_i) { | ||
210 | case BYADDR: | ||
211 | net_entry.n_name = *net_entry.n_aliases; | ||
212 | net_entry.n_net = 0L; | ||
213 | break; | ||
214 | case BYNAME: | ||
215 | in = *net_entry.n_aliases; | ||
216 | net_entry.n_name = &ans[0]; | ||
217 | aux2[0] = '\0'; | ||
218 | for (i = 0; i < 4; i++) { | ||
219 | for (st = in, nchar = 0; | ||
220 | *st != '.'; | ||
221 | st++, nchar++) | ||
222 | ; | ||
223 | if (nchar != 1 || *in != '0' || flag) { | ||
224 | flag = 1; | ||
225 | (void)strncpy(paux1, | ||
226 | (i==0) ? in : in-1, | ||
227 | (i==0) ?nchar : nchar+1); | ||
228 | paux1[(i==0) ? nchar : nchar+1] = '\0'; | ||
229 | pauxt = paux2; | ||
230 | paux2 = strcat(paux1, paux2); | ||
231 | paux1 = pauxt; | ||
232 | } | ||
233 | in = ++st; | ||
234 | } | ||
235 | net_entry.n_net = inet_network(paux2); | ||
236 | break; | ||
237 | } | ||
238 | net_entry.n_aliases++; | ||
239 | return (&net_entry); | ||
240 | } | ||
241 | h_errno = TRY_AGAIN; | ||
242 | return (NULL); | ||
243 | } | ||
244 | |||
245 | struct netent * | ||
246 | getnetbyaddr(net, net_type) | ||
247 | register in_addr_t net; | ||
248 | register int net_type; | ||
249 | { | ||
250 | unsigned int netbr[4]; | ||
251 | int nn, anslen; | ||
252 | querybuf buf; | ||
253 | char qbuf[MAXDNAME]; | ||
254 | in_addr_t net2; | ||
255 | struct netent *net_entry = NULL; | ||
256 | char lookups[MAXDNSLUS]; | ||
257 | int i; | ||
258 | |||
259 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) | ||
260 | return(_getnetbyaddr(net, net_type)); | ||
261 | |||
262 | bcopy(_res.lookups, lookups, sizeof lookups); | ||
263 | if (lookups[0] == '\0') | ||
264 | strncpy(lookups, "bf", sizeof lookups); | ||
265 | |||
266 | for (i = 0; i < MAXDNSLUS && lookups[i]; i++) { | ||
267 | switch (lookups[i]) { | ||
268 | #ifdef YP | ||
269 | case 'y': | ||
270 | /* There is no YP support. */ | ||
271 | break; | ||
272 | #endif /* YP */ | ||
273 | case 'b': | ||
274 | if (net_type != AF_INET) | ||
275 | break; /* DNS only supports AF_INET? */ | ||
276 | |||
277 | for (nn = 4, net2 = net; net2; net2 >>= 8) | ||
278 | netbr[--nn] = net2 & 0xff; | ||
279 | switch (nn) { | ||
280 | case 3: /* Class A */ | ||
281 | snprintf(qbuf, sizeof(qbuf), | ||
282 | "0.0.0.%u.in-addr.arpa", netbr[3]); | ||
283 | break; | ||
284 | case 2: /* Class B */ | ||
285 | snprintf(qbuf, sizeof(qbuf), | ||
286 | "0.0.%u.%u.in-addr.arpa", | ||
287 | netbr[3], netbr[2]); | ||
288 | break; | ||
289 | case 1: /* Class C */ | ||
290 | snprintf(qbuf, sizeof(qbuf), | ||
291 | "0.%u.%u.%u.in-addr.arpa", | ||
292 | netbr[3], netbr[2], netbr[1]); | ||
293 | break; | ||
294 | case 0: /* Class D - E */ | ||
295 | snprintf(qbuf, sizeof(qbuf), | ||
296 | "%u.%u.%u.%u.in-addr.arpa", | ||
297 | netbr[3], netbr[2], netbr[1], netbr[0]); | ||
298 | break; | ||
299 | } | ||
300 | anslen = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, | ||
301 | sizeof(buf)); | ||
302 | if (anslen < 0) { | ||
303 | #ifdef DEBUG | ||
304 | if (_res.options & RES_DEBUG) | ||
305 | printf("res_query failed\n"); | ||
306 | #endif | ||
307 | break; | ||
308 | } | ||
309 | net_entry = getnetanswer(&buf, anslen, BYADDR); | ||
310 | if (net_entry != NULL) { | ||
311 | unsigned u_net = net; /* maybe net should be unsigned ? */ | ||
312 | |||
313 | /* Strip trailing zeros */ | ||
314 | while ((u_net & 0xff) == 0 && u_net != 0) | ||
315 | u_net >>= 8; | ||
316 | net_entry->n_net = u_net; | ||
317 | return (net_entry); | ||
318 | } | ||
319 | break; | ||
320 | case 'f': | ||
321 | net_entry = _getnetbyaddr(net, net_type); | ||
322 | if (net_entry != NULL) | ||
323 | return (net_entry); | ||
324 | } | ||
325 | } | ||
326 | |||
327 | /* Nothing matched. */ | ||
328 | return (NULL); | ||
329 | } | ||
330 | |||
331 | struct netent * | ||
332 | getnetbyname(net) | ||
333 | register const char *net; | ||
334 | { | ||
335 | int anslen; | ||
336 | querybuf buf; | ||
337 | char qbuf[MAXDNAME]; | ||
338 | struct netent *net_entry = NULL; | ||
339 | char lookups[MAXDNSLUS]; | ||
340 | int i; | ||
341 | |||
342 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) | ||
343 | return (_getnetbyname(net)); | ||
344 | |||
345 | bcopy(_res.lookups, lookups, sizeof lookups); | ||
346 | if (lookups[0] == '\0') | ||
347 | strncpy(lookups, "bf", sizeof lookups); | ||
348 | |||
349 | for (i = 0; i < MAXDNSLUS && lookups[i]; i++) { | ||
350 | switch (lookups[i]) { | ||
351 | #ifdef YP | ||
352 | case 'y': | ||
353 | /* There is no YP support. */ | ||
354 | break; | ||
355 | #endif /* YP */ | ||
356 | case 'b': | ||
357 | strncpy(qbuf, net, sizeof qbuf-1); | ||
358 | qbuf[sizeof qbuf-1] = '\0'; | ||
359 | anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)&buf, | ||
360 | sizeof(buf)); | ||
361 | if (anslen < 0) { | ||
362 | #ifdef DEBUG | ||
363 | if (_res.options & RES_DEBUG) | ||
364 | printf("res_query failed\n"); | ||
365 | #endif | ||
366 | break; | ||
367 | } | ||
368 | net_entry = getnetanswer(&buf, anslen, BYNAME); | ||
369 | if (net_entry != NULL) | ||
370 | return (net_entry); | ||
371 | break; | ||
372 | case 'f': | ||
373 | net_entry = _getnetbyname(net); | ||
374 | if (net_entry != NULL) | ||
375 | return (net_entry); | ||
376 | break; | ||
377 | } | ||
378 | } | ||
379 | |||
380 | /* Nothing matched. */ | ||
381 | return (NULL); | ||
382 | } | ||
diff --git a/src/lib/libc/net/getproto.c b/src/lib/libc/net/getproto.c new file mode 100644 index 0000000000..474d8d9427 --- /dev/null +++ b/src/lib/libc/net/getproto.c | |||
@@ -0,0 +1,55 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1983, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: getproto.c,v 1.3 1997/07/09 01:08:31 millert Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | #include <netdb.h> | ||
39 | |||
40 | extern int _proto_stayopen; | ||
41 | |||
42 | struct protoent * | ||
43 | getprotobynumber(proto) | ||
44 | register int proto; | ||
45 | { | ||
46 | register struct protoent *p; | ||
47 | |||
48 | setprotoent(_proto_stayopen); | ||
49 | while ((p = getprotoent())) | ||
50 | if (p->p_proto == proto) | ||
51 | break; | ||
52 | if (!_proto_stayopen) | ||
53 | endprotoent(); | ||
54 | return (p); | ||
55 | } | ||
diff --git a/src/lib/libc/net/getprotoent.3 b/src/lib/libc/net/getprotoent.3 new file mode 100644 index 0000000000..f67987954f --- /dev/null +++ b/src/lib/libc/net/getprotoent.3 | |||
@@ -0,0 +1,144 @@ | |||
1 | .\" $OpenBSD: getprotoent.3,v 1.2 1996/08/19 08:28:50 tholo Exp $ | ||
2 | .\" | ||
3 | .\" Copyright (c) 1983, 1991, 1993 | ||
4 | .\" The Regents of the University of California. All rights reserved. | ||
5 | .\" | ||
6 | .\" Redistribution and use in source and binary forms, with or without | ||
7 | .\" modification, are permitted provided that the following conditions | ||
8 | .\" are met: | ||
9 | .\" 1. Redistributions of source code must retain the above copyright | ||
10 | .\" notice, this list of conditions and the following disclaimer. | ||
11 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
12 | .\" notice, this list of conditions and the following disclaimer in the | ||
13 | .\" documentation and/or other materials provided with the distribution. | ||
14 | .\" 3. All advertising materials mentioning features or use of this software | ||
15 | .\" must display the following acknowledgement: | ||
16 | .\" This product includes software developed by the University of | ||
17 | .\" California, Berkeley and its contributors. | ||
18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
19 | .\" may be used to endorse or promote products derived from this software | ||
20 | .\" without specific prior written permission. | ||
21 | .\" | ||
22 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
23 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
24 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
26 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
27 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
28 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
29 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
30 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
32 | .\" SUCH DAMAGE. | ||
33 | .\" | ||
34 | .Dd June 4, 1993 | ||
35 | .Dt GETPROTOENT 3 | ||
36 | .Os BSD 4.2 | ||
37 | .Sh NAME | ||
38 | .Nm getprotoent , | ||
39 | .Nm getprotobynumber , | ||
40 | .Nm getprotobyname , | ||
41 | .Nm setprotoent , | ||
42 | .Nm endprotoent | ||
43 | .Nd get protocol entry | ||
44 | .Sh SYNOPSIS | ||
45 | .Fd #include <netdb.h> | ||
46 | .Ft struct protoent * | ||
47 | .Fn getprotoent | ||
48 | .Ft struct protoent * | ||
49 | .Fn getprotobyname "char *name" | ||
50 | .Ft struct protoent * | ||
51 | .Fn getprotobynumber "int proto" | ||
52 | .Fn setprotoent "int stayopen" | ||
53 | .Fn endprotoent | ||
54 | .Sh DESCRIPTION | ||
55 | The | ||
56 | .Fn getprotoent , | ||
57 | .Fn getprotobyname , | ||
58 | and | ||
59 | .Fn getprotobynumber | ||
60 | functions | ||
61 | each return a pointer to an object with the | ||
62 | following structure | ||
63 | containing the broken-out | ||
64 | fields of a line in the network protocol data base, | ||
65 | .Pa /etc/protocols . | ||
66 | .Bd -literal -offset indent | ||
67 | .Pp | ||
68 | struct protoent { | ||
69 | char *p_name; /* official name of protocol */ | ||
70 | char **p_aliases; /* alias list */ | ||
71 | int p_proto; /* protocol number */ | ||
72 | }; | ||
73 | .Ed | ||
74 | .Pp | ||
75 | The members of this structure are: | ||
76 | .Bl -tag -width p_aliases | ||
77 | .It Fa p_name | ||
78 | The official name of the protocol. | ||
79 | .It Fa p_aliases | ||
80 | A zero terminated list of alternate names for the protocol. | ||
81 | .It Fa p_proto | ||
82 | The protocol number. | ||
83 | .El | ||
84 | .Pp | ||
85 | The | ||
86 | .Fn getprotoent | ||
87 | function | ||
88 | reads the next line of the file, opening the file if necessary. | ||
89 | .Pp | ||
90 | The | ||
91 | .Fn setprotoent | ||
92 | function | ||
93 | opens and rewinds the file. If the | ||
94 | .Fa stayopen | ||
95 | flag is non-zero, | ||
96 | the net data base will not be closed after each call to | ||
97 | .Fn getprotobyname | ||
98 | or | ||
99 | .Fn getprotobynumber . | ||
100 | .Pp | ||
101 | The | ||
102 | .Fn endprotoent | ||
103 | function | ||
104 | closes the file. | ||
105 | .Pp | ||
106 | The | ||
107 | .Fn getprotobyname | ||
108 | function | ||
109 | and | ||
110 | .Fn getprotobynumber | ||
111 | sequentially search from the beginning | ||
112 | of the file until a matching | ||
113 | protocol name or | ||
114 | protocol number is found, | ||
115 | or until | ||
116 | .Dv EOF | ||
117 | is encountered. | ||
118 | .Sh RETURN VALUES | ||
119 | Null pointer | ||
120 | (0) returned on | ||
121 | .Dv EOF | ||
122 | or error. | ||
123 | .Sh FILES | ||
124 | .Bl -tag -width /etc/protocols -compact | ||
125 | .It Pa /etc/protocols | ||
126 | .El | ||
127 | .Sh SEE ALSO | ||
128 | .Xr protocols 5 | ||
129 | .Sh HISTORY | ||
130 | The | ||
131 | .Fn getprotoent , | ||
132 | .Fn getprotobynumber , | ||
133 | .Fn getprotobyname , | ||
134 | .Fn setprotoent , | ||
135 | and | ||
136 | .Fn endprotoent | ||
137 | functions appeared in | ||
138 | .Bx 4.2 . | ||
139 | .Sh BUGS | ||
140 | These functions use a static data space; | ||
141 | if the data is needed for future use, it should be | ||
142 | copied before any subsequent calls overwrite it. | ||
143 | Only the Internet | ||
144 | protocols are currently understood. | ||
diff --git a/src/lib/libc/net/getprotoent.c b/src/lib/libc/net/getprotoent.c new file mode 100644 index 0000000000..2bef526e7a --- /dev/null +++ b/src/lib/libc/net/getprotoent.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1983, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: getprotoent.c,v 1.3 1998/03/16 05:06:59 millert Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | #include <sys/types.h> | ||
39 | #include <sys/socket.h> | ||
40 | #include <netdb.h> | ||
41 | #include <stdio.h> | ||
42 | #include <stdlib.h> | ||
43 | #include <string.h> | ||
44 | |||
45 | #define MAXALIASES 35 | ||
46 | |||
47 | static FILE *protof = NULL; | ||
48 | static char line[BUFSIZ+1]; | ||
49 | static struct protoent proto; | ||
50 | static char *proto_aliases[MAXALIASES]; | ||
51 | int _proto_stayopen; | ||
52 | |||
53 | void | ||
54 | setprotoent(f) | ||
55 | int f; | ||
56 | { | ||
57 | if (protof == NULL) | ||
58 | protof = fopen(_PATH_PROTOCOLS, "r" ); | ||
59 | else | ||
60 | rewind(protof); | ||
61 | _proto_stayopen |= f; | ||
62 | } | ||
63 | |||
64 | void | ||
65 | endprotoent() | ||
66 | { | ||
67 | if (protof) { | ||
68 | fclose(protof); | ||
69 | protof = NULL; | ||
70 | } | ||
71 | _proto_stayopen = 0; | ||
72 | } | ||
73 | |||
74 | struct protoent * | ||
75 | getprotoent() | ||
76 | { | ||
77 | char *p, *cp, **q; | ||
78 | size_t len; | ||
79 | |||
80 | if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL) | ||
81 | return (NULL); | ||
82 | again: | ||
83 | if ((p = fgetln(protof, &len)) == NULL) | ||
84 | return (NULL); | ||
85 | if (p[len-1] == '\n') | ||
86 | len--; | ||
87 | if (len >= sizeof(line) || len == 0) | ||
88 | goto again; | ||
89 | p = memcpy(line, p, len); | ||
90 | line[len] = '\0'; | ||
91 | if (*p == '#') | ||
92 | goto again; | ||
93 | if ((cp = strchr(p, '#')) != NULL) | ||
94 | *cp = '\0'; | ||
95 | proto.p_name = p; | ||
96 | cp = strpbrk(p, " \t"); | ||
97 | if (cp == NULL) | ||
98 | goto again; | ||
99 | *cp++ = '\0'; | ||
100 | while (*cp == ' ' || *cp == '\t') | ||
101 | cp++; | ||
102 | p = strpbrk(cp, " \t"); | ||
103 | if (p != NULL) | ||
104 | *p++ = '\0'; | ||
105 | proto.p_proto = atoi(cp); | ||
106 | q = proto.p_aliases = proto_aliases; | ||
107 | if (p != NULL) { | ||
108 | cp = p; | ||
109 | while (cp && *cp) { | ||
110 | if (*cp == ' ' || *cp == '\t') { | ||
111 | cp++; | ||
112 | continue; | ||
113 | } | ||
114 | if (q < &proto_aliases[MAXALIASES - 1]) | ||
115 | *q++ = cp; | ||
116 | cp = strpbrk(cp, " \t"); | ||
117 | if (cp != NULL) | ||
118 | *cp++ = '\0'; | ||
119 | } | ||
120 | } | ||
121 | *q = NULL; | ||
122 | return (&proto); | ||
123 | } | ||
diff --git a/src/lib/libc/net/getprotoname.c b/src/lib/libc/net/getprotoname.c new file mode 100644 index 0000000000..7a4e5fede5 --- /dev/null +++ b/src/lib/libc/net/getprotoname.c | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1983, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: getprotoname.c,v 1.3 1997/07/09 01:08:32 millert Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | #include <netdb.h> | ||
39 | #include <string.h> | ||
40 | |||
41 | extern int _proto_stayopen; | ||
42 | |||
43 | struct protoent * | ||
44 | getprotobyname(name) | ||
45 | register const char *name; | ||
46 | { | ||
47 | register struct protoent *p; | ||
48 | register char **cp; | ||
49 | |||
50 | setprotoent(_proto_stayopen); | ||
51 | while ((p = getprotoent())) { | ||
52 | if (strcmp(p->p_name, name) == 0) | ||
53 | break; | ||
54 | for (cp = p->p_aliases; *cp != 0; cp++) | ||
55 | if (strcmp(*cp, name) == 0) | ||
56 | goto found; | ||
57 | } | ||
58 | found: | ||
59 | if (!_proto_stayopen) | ||
60 | endprotoent(); | ||
61 | return (p); | ||
62 | } | ||
diff --git a/src/lib/libc/net/getservbyname.c b/src/lib/libc/net/getservbyname.c new file mode 100644 index 0000000000..25f0e27d06 --- /dev/null +++ b/src/lib/libc/net/getservbyname.c | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1983, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: getservbyname.c,v 1.3 1997/07/09 01:08:34 millert Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | #include <netdb.h> | ||
39 | #include <string.h> | ||
40 | |||
41 | extern int _serv_stayopen; | ||
42 | |||
43 | struct servent * | ||
44 | getservbyname(name, proto) | ||
45 | const char *name, *proto; | ||
46 | { | ||
47 | register struct servent *p; | ||
48 | register char **cp; | ||
49 | |||
50 | setservent(_serv_stayopen); | ||
51 | while ((p = getservent())) { | ||
52 | if (strcmp(name, p->s_name) == 0) | ||
53 | goto gotname; | ||
54 | for (cp = p->s_aliases; *cp; cp++) | ||
55 | if (strcmp(name, *cp) == 0) | ||
56 | goto gotname; | ||
57 | continue; | ||
58 | gotname: | ||
59 | if (proto == 0 || strcmp(p->s_proto, proto) == 0) | ||
60 | break; | ||
61 | } | ||
62 | if (!_serv_stayopen) | ||
63 | endservent(); | ||
64 | return (p); | ||
65 | } | ||
diff --git a/src/lib/libc/net/getservbyport.c b/src/lib/libc/net/getservbyport.c new file mode 100644 index 0000000000..4b063760d2 --- /dev/null +++ b/src/lib/libc/net/getservbyport.c | |||
@@ -0,0 +1,60 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1983, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: getservbyport.c,v 1.3 1997/07/09 01:08:35 millert Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | #include <netdb.h> | ||
39 | #include <string.h> | ||
40 | |||
41 | extern int _serv_stayopen; | ||
42 | |||
43 | struct servent * | ||
44 | getservbyport(port, proto) | ||
45 | int port; | ||
46 | const char *proto; | ||
47 | { | ||
48 | register struct servent *p; | ||
49 | |||
50 | setservent(_serv_stayopen); | ||
51 | while ((p = getservent())) { | ||
52 | if (p->s_port != port) | ||
53 | continue; | ||
54 | if (proto == 0 || strcmp(p->s_proto, proto) == 0) | ||
55 | break; | ||
56 | } | ||
57 | if (!_serv_stayopen) | ||
58 | endservent(); | ||
59 | return (p); | ||
60 | } | ||
diff --git a/src/lib/libc/net/getservent.3 b/src/lib/libc/net/getservent.3 new file mode 100644 index 0000000000..d1684c28c4 --- /dev/null +++ b/src/lib/libc/net/getservent.3 | |||
@@ -0,0 +1,155 @@ | |||
1 | .\" $OpenBSD: getservent.3,v 1.3 1996/08/30 02:00:11 millert Exp $ | ||
2 | .\" | ||
3 | .\" Copyright (c) 1983, 1991, 1993 | ||
4 | .\" The Regents of the University of California. All rights reserved. | ||
5 | .\" | ||
6 | .\" Redistribution and use in source and binary forms, with or without | ||
7 | .\" modification, are permitted provided that the following conditions | ||
8 | .\" are met: | ||
9 | .\" 1. Redistributions of source code must retain the above copyright | ||
10 | .\" notice, this list of conditions and the following disclaimer. | ||
11 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
12 | .\" notice, this list of conditions and the following disclaimer in the | ||
13 | .\" documentation and/or other materials provided with the distribution. | ||
14 | .\" 3. All advertising materials mentioning features or use of this software | ||
15 | .\" must display the following acknowledgement: | ||
16 | .\" This product includes software developed by the University of | ||
17 | .\" California, Berkeley and its contributors. | ||
18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
19 | .\" may be used to endorse or promote products derived from this software | ||
20 | .\" without specific prior written permission. | ||
21 | .\" | ||
22 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
23 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
24 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
26 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
27 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
28 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
29 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
30 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
32 | .\" SUCH DAMAGE. | ||
33 | .\" | ||
34 | .Dd January 12, 1994 | ||
35 | .Dt GETSERVENT 3 | ||
36 | .Os BSD 4.2 | ||
37 | .Sh NAME | ||
38 | .Nm getservent , | ||
39 | .Nm getservbyport , | ||
40 | .Nm getservbyname , | ||
41 | .Nm setservent , | ||
42 | .Nm endservent | ||
43 | .Nd get service entry | ||
44 | .Sh SYNOPSIS | ||
45 | .Fd #include <netdb.h> | ||
46 | .Ft struct servent * | ||
47 | .Fn getservent | ||
48 | .Ft struct servent * | ||
49 | .Fn getservbyname "char *name" "char *proto" | ||
50 | .Ft struct servent * | ||
51 | .Fn getservbyport "int port" "char *proto" | ||
52 | .Ft void | ||
53 | .Fn setservent "int stayopen" | ||
54 | .Ft void | ||
55 | .Fn endservent void | ||
56 | .Sh DESCRIPTION | ||
57 | The | ||
58 | .Fn getservent , | ||
59 | .Fn getservbyname , | ||
60 | and | ||
61 | .Fn getservbyport | ||
62 | functions | ||
63 | each return a pointer to an object with the | ||
64 | following structure | ||
65 | containing the broken-out | ||
66 | fields of a line in the network services data base, | ||
67 | .Pa /etc/services . | ||
68 | .Bd -literal -offset indent | ||
69 | struct servent { | ||
70 | char *s_name; /* official name of service */ | ||
71 | char **s_aliases; /* alias list */ | ||
72 | int s_port; /* port service resides at */ | ||
73 | char *s_proto; /* protocol to use */ | ||
74 | }; | ||
75 | .Ed | ||
76 | .Pp | ||
77 | The members of this structure are: | ||
78 | .Bl -tag -width s_aliases | ||
79 | .It Fa s_name | ||
80 | The official name of the service. | ||
81 | .It Fa s_aliases | ||
82 | A zero terminated list of alternate names for the service. | ||
83 | .It Fa s_port | ||
84 | The port number at which the service resides. | ||
85 | Port numbers are returned in network byte order. | ||
86 | .It Fa s_proto | ||
87 | The name of the protocol to use when contacting the | ||
88 | service. | ||
89 | .El | ||
90 | .Pp | ||
91 | The | ||
92 | .Fn getservent | ||
93 | function | ||
94 | reads the next line of the file, opening the file if necessary. | ||
95 | .Pp | ||
96 | The | ||
97 | .Fn setservent | ||
98 | function | ||
99 | opens and rewinds the file. If the | ||
100 | .Fa stayopen | ||
101 | flag is non-zero, | ||
102 | the net data base will not be closed after each call to | ||
103 | .Fn getservbyname | ||
104 | or | ||
105 | .Fn getservbyport . | ||
106 | .Pp | ||
107 | The | ||
108 | .Fn endservent | ||
109 | function | ||
110 | closes the file. | ||
111 | .Pp | ||
112 | The | ||
113 | .Fn getservbyname | ||
114 | and | ||
115 | .Fn getservbyport | ||
116 | functions | ||
117 | sequentially search from the beginning | ||
118 | of the file until a matching | ||
119 | protocol name or | ||
120 | port number is found, | ||
121 | or until | ||
122 | .Dv EOF | ||
123 | is encountered. | ||
124 | If a protocol name is also supplied (non- | ||
125 | .Dv NULL ) , | ||
126 | searches must also match the protocol. | ||
127 | .ne 1i | ||
128 | .Sh FILES | ||
129 | .Bl -tag -width /etc/services -compact | ||
130 | .It Pa /etc/services | ||
131 | .El | ||
132 | .Sh DIAGNOSTICS | ||
133 | Null pointer | ||
134 | (0) returned on | ||
135 | .Dv EOF | ||
136 | or error. | ||
137 | .Sh SEE ALSO | ||
138 | .Xr getprotoent 3 , | ||
139 | .Xr services 5 | ||
140 | .Sh HISTORY | ||
141 | The | ||
142 | .Fn getservent , | ||
143 | .Fn getservbyport , | ||
144 | .Fn getservbyname , | ||
145 | .Fn setservent , | ||
146 | and | ||
147 | .Fn endservent | ||
148 | functions appeared in | ||
149 | .Bx 4.2 . | ||
150 | .Sh BUGS | ||
151 | These functions use static data storage; | ||
152 | if the data is needed for future use, it should be | ||
153 | copied before any subsequent calls overwrite it. | ||
154 | Expecting port numbers to fit in a 32 bit | ||
155 | quantity is probably naive. | ||
diff --git a/src/lib/libc/net/getservent.c b/src/lib/libc/net/getservent.c new file mode 100644 index 0000000000..7d8cb6d8ca --- /dev/null +++ b/src/lib/libc/net/getservent.c | |||
@@ -0,0 +1,125 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1983, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: getservent.c,v 1.4 1998/03/16 05:07:00 millert Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | #include <sys/types.h> | ||
39 | #include <sys/socket.h> | ||
40 | #include <netdb.h> | ||
41 | #include <stdio.h> | ||
42 | #include <string.h> | ||
43 | #include <stdlib.h> | ||
44 | |||
45 | #define MAXALIASES 35 | ||
46 | |||
47 | static FILE *servf = NULL; | ||
48 | static char line[BUFSIZ+1]; | ||
49 | static struct servent serv; | ||
50 | static char *serv_aliases[MAXALIASES]; | ||
51 | int _serv_stayopen; | ||
52 | |||
53 | void | ||
54 | setservent(f) | ||
55 | int f; | ||
56 | { | ||
57 | if (servf == NULL) | ||
58 | servf = fopen(_PATH_SERVICES, "r" ); | ||
59 | else | ||
60 | rewind(servf); | ||
61 | _serv_stayopen |= f; | ||
62 | } | ||
63 | |||
64 | void | ||
65 | endservent() | ||
66 | { | ||
67 | if (servf) { | ||
68 | fclose(servf); | ||
69 | servf = NULL; | ||
70 | } | ||
71 | _serv_stayopen = 0; | ||
72 | } | ||
73 | |||
74 | struct servent * | ||
75 | getservent() | ||
76 | { | ||
77 | char *p, *cp, **q; | ||
78 | size_t len; | ||
79 | |||
80 | if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL) | ||
81 | return (NULL); | ||
82 | again: | ||
83 | if ((p = fgetln(servf, &len)) == NULL) | ||
84 | return (NULL); | ||
85 | if (p[len-1] == '\n') | ||
86 | len--; | ||
87 | if (len >= sizeof(line) || len == 0) | ||
88 | goto again; | ||
89 | p = memcpy(line, p, len); | ||
90 | line[len] = '\0'; | ||
91 | if (*p == '#') | ||
92 | goto again; | ||
93 | if ((cp = strchr(p, '#')) != NULL) | ||
94 | *cp = '\0'; | ||
95 | serv.s_name = p; | ||
96 | p = strpbrk(p, " \t"); | ||
97 | if (p == NULL) | ||
98 | goto again; | ||
99 | *p++ = '\0'; | ||
100 | while (*p == ' ' || *p == '\t') | ||
101 | p++; | ||
102 | cp = strpbrk(p, ",/"); | ||
103 | if (cp == NULL) | ||
104 | goto again; | ||
105 | *cp++ = '\0'; | ||
106 | serv.s_port = htons((in_port_t)atoi(p)); | ||
107 | serv.s_proto = cp; | ||
108 | q = serv.s_aliases = serv_aliases; | ||
109 | cp = strpbrk(cp, " \t"); | ||
110 | if (cp != NULL) | ||
111 | *cp++ = '\0'; | ||
112 | while (cp && *cp) { | ||
113 | if (*cp == ' ' || *cp == '\t') { | ||
114 | cp++; | ||
115 | continue; | ||
116 | } | ||
117 | if (q < &serv_aliases[MAXALIASES - 1]) | ||
118 | *q++ = cp; | ||
119 | cp = strpbrk(cp, " \t"); | ||
120 | if (cp != NULL) | ||
121 | *cp++ = '\0'; | ||
122 | } | ||
123 | *q = NULL; | ||
124 | return (&serv); | ||
125 | } | ||
diff --git a/src/lib/libc/net/herror.c b/src/lib/libc/net/herror.c new file mode 100644 index 0000000000..737bb115a7 --- /dev/null +++ b/src/lib/libc/net/herror.c | |||
@@ -0,0 +1,121 @@ | |||
1 | /* $OpenBSD: herror.c,v 1.4 1997/03/13 19:07:28 downsj Exp $ */ | ||
2 | |||
3 | /* | ||
4 | * ++Copyright++ 1987, 1993 | ||
5 | * - | ||
6 | * Copyright (c) 1987, 1993 | ||
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 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 | ||
65 | #endif /* LIBC_SCCS and not lint */ | ||
66 | |||
67 | #include <sys/types.h> | ||
68 | #include <sys/param.h> | ||
69 | #include <sys/uio.h> | ||
70 | #include <netdb.h> | ||
71 | #include <unistd.h> | ||
72 | #include <string.h> | ||
73 | |||
74 | const char *h_errlist[] = { | ||
75 | "Resolver Error 0 (no error)", | ||
76 | "Unknown host", /* 1 HOST_NOT_FOUND */ | ||
77 | "Host name lookup failure", /* 2 TRY_AGAIN */ | ||
78 | "Unknown server error", /* 3 NO_RECOVERY */ | ||
79 | "No address associated with name", /* 4 NO_ADDRESS */ | ||
80 | }; | ||
81 | int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] }; | ||
82 | |||
83 | extern int h_errno; | ||
84 | |||
85 | /* | ||
86 | * herror -- | ||
87 | * print the error indicated by the h_errno value. | ||
88 | */ | ||
89 | void | ||
90 | herror(s) | ||
91 | const char *s; | ||
92 | { | ||
93 | struct iovec iov[4]; | ||
94 | register struct iovec *v = iov; | ||
95 | |||
96 | if (s && *s) { | ||
97 | v->iov_base = (char *)s; | ||
98 | v->iov_len = strlen(s); | ||
99 | v++; | ||
100 | v->iov_base = ": "; | ||
101 | v->iov_len = 2; | ||
102 | v++; | ||
103 | } | ||
104 | v->iov_base = (char *)hstrerror(h_errno); | ||
105 | v->iov_len = strlen(v->iov_base); | ||
106 | v++; | ||
107 | v->iov_base = "\n"; | ||
108 | v->iov_len = 1; | ||
109 | writev(STDERR_FILENO, iov, (v - iov) + 1); | ||
110 | } | ||
111 | |||
112 | const char * | ||
113 | hstrerror(err) | ||
114 | int err; | ||
115 | { | ||
116 | if (err < 0) | ||
117 | return ("Resolver internal error"); | ||
118 | else if (err < h_nerr) | ||
119 | return (h_errlist[err]); | ||
120 | return ("Unknown resolver error"); | ||
121 | } | ||
diff --git a/src/lib/libc/net/htonl.c b/src/lib/libc/net/htonl.c new file mode 100644 index 0000000000..73b7432731 --- /dev/null +++ b/src/lib/libc/net/htonl.c | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * Written by J.T. Conklin <jtc@netbsd.org>. | ||
3 | * Public domain. | ||
4 | */ | ||
5 | |||
6 | #if defined(LIBC_SCCS) && !defined(lint) | ||
7 | static char *rcsid = "$OpenBSD: htonl.c,v 1.4 1996/12/12 03:19:55 tholo Exp $"; | ||
8 | #endif /* LIBC_SCCS and not lint */ | ||
9 | |||
10 | #include <sys/types.h> | ||
11 | #include <machine/endian.h> | ||
12 | |||
13 | #undef htonl | ||
14 | |||
15 | u_int32_t | ||
16 | htonl(x) | ||
17 | u_int32_t x; | ||
18 | { | ||
19 | #if BYTE_ORDER == LITTLE_ENDIAN | ||
20 | u_char *s = (u_char *)&x; | ||
21 | return (u_int32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]); | ||
22 | #else | ||
23 | return x; | ||
24 | #endif | ||
25 | } | ||
diff --git a/src/lib/libc/net/htons.c b/src/lib/libc/net/htons.c new file mode 100644 index 0000000000..47cf25952d --- /dev/null +++ b/src/lib/libc/net/htons.c | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * Written by J.T. Conklin <jtc@netbsd.org>. | ||
3 | * Public domain. | ||
4 | */ | ||
5 | |||
6 | #if defined(LIBC_SCCS) && !defined(lint) | ||
7 | static char *rcsid = "$OpenBSD: htons.c,v 1.6 1997/07/25 20:30:07 mickey Exp $"; | ||
8 | #endif /* LIBC_SCCS and not lint */ | ||
9 | |||
10 | #include <sys/types.h> | ||
11 | #include <machine/endian.h> | ||
12 | |||
13 | #undef htons | ||
14 | |||
15 | u_int16_t | ||
16 | #ifdef __STDC__ | ||
17 | htons(u_int16_t x) | ||
18 | #else | ||
19 | htons(x) | ||
20 | u_int16_t x; | ||
21 | #endif | ||
22 | { | ||
23 | #if BYTE_ORDER == LITTLE_ENDIAN | ||
24 | u_char *s = (u_char *) &x; | ||
25 | return (u_int16_t)(s[0] << 8 | s[1]); | ||
26 | #else | ||
27 | return x; | ||
28 | #endif | ||
29 | } | ||
diff --git a/src/lib/libc/net/inet.3 b/src/lib/libc/net/inet.3 new file mode 100644 index 0000000000..2fb86cd927 --- /dev/null +++ b/src/lib/libc/net/inet.3 | |||
@@ -0,0 +1,319 @@ | |||
1 | .\" $OpenBSD: inet.3,v 1.4 1997/06/23 04:01:11 millert Exp $ | ||
2 | .\" $NetBSD: inet.3,v 1.7 1997/06/18 02:25:24 lukem Exp $ | ||
3 | .\" | ||
4 | .\" Copyright (c) 1983, 1990, 1991, 1993 | ||
5 | .\" The Regents of the University of California. All rights reserved. | ||
6 | .\" | ||
7 | .\" Redistribution and use in source and binary forms, with or without | ||
8 | .\" modification, are permitted provided that the following conditions | ||
9 | .\" are met: | ||
10 | .\" 1. Redistributions of source code must retain the above copyright | ||
11 | .\" notice, this list of conditions and the following disclaimer. | ||
12 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
13 | .\" notice, this list of conditions and the following disclaimer in the | ||
14 | .\" documentation and/or other materials provided with the distribution. | ||
15 | .\" 3. All advertising materials mentioning features or use of this software | ||
16 | .\" must display the following acknowledgement: | ||
17 | .\" This product includes software developed by the University of | ||
18 | .\" California, Berkeley and its contributors. | ||
19 | .\" 4. Neither the name of the University nor the names of its contributors | ||
20 | .\" may be used to endorse or promote products derived from this software | ||
21 | .\" without specific prior written permission. | ||
22 | .\" | ||
23 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
24 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
25 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
26 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
27 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
28 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
29 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
30 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
31 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
32 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
33 | .\" SUCH DAMAGE. | ||
34 | .\" | ||
35 | .\" @(#)inet.3 8.1 (Berkeley) 6/4/93 | ||
36 | .\" | ||
37 | .Dd June 18, 1997 | ||
38 | .Dt INET 3 | ||
39 | .Os BSD 4.2 | ||
40 | .Sh NAME | ||
41 | .Nm inet_addr , | ||
42 | .Nm inet_aton , | ||
43 | .Nm inet_lnaof , | ||
44 | .Nm inet_makeaddr , | ||
45 | .Nm inet_netof , | ||
46 | .Nm inet_network , | ||
47 | .Nm inet_ntoa , | ||
48 | .Nm inet_ntop , | ||
49 | .Nm inet_pton | ||
50 | .Nd Internet address manipulation routines | ||
51 | .Sh SYNOPSIS | ||
52 | .Fd #include <sys/socket.h> | ||
53 | .Fd #include <netinet/in.h> | ||
54 | .Fd #include <arpa/inet.h> | ||
55 | .Ft in_addr_t | ||
56 | .Fn inet_addr "const char *cp" | ||
57 | .Ft int | ||
58 | .Fn inet_aton "const char *cp" "struct in_addr *addr" | ||
59 | .Ft in_addr_t | ||
60 | .Fn inet_lnaof "struct in_addr in" | ||
61 | .Ft struct in_addr | ||
62 | .Fn inet_makeaddr "unsigned long net" "unsigned long lna" | ||
63 | .Ft in_addr_t | ||
64 | .Fn inet_netof "struct in_addr in" | ||
65 | .Ft in_addr_t | ||
66 | .Fn inet_network "const char *cp" | ||
67 | .Ft char * | ||
68 | .Fn inet_ntoa "struct in_addr in" | ||
69 | .Ft const char * | ||
70 | .Fn inet_ntop "int af" "const void *src" "char *dst" "size_t size" | ||
71 | .Ft int | ||
72 | .Fn inet_pton "int af" "const char *src" "void *dst" | ||
73 | .Sh DESCRIPTION | ||
74 | The routines | ||
75 | .Fn inet_aton , | ||
76 | .Fn inet_addr | ||
77 | and | ||
78 | .Fn inet_network | ||
79 | interpret character strings representing | ||
80 | numbers expressed in the Internet standard | ||
81 | .Ql \&. | ||
82 | notation. | ||
83 | The | ||
84 | .Fn inet_pton | ||
85 | function converts a presentation format address (that is, printable form | ||
86 | as held in a character string) to network format (usually a | ||
87 | .Ft struct in_addr | ||
88 | or some other internal binary representation, in network byte order). It | ||
89 | returns 1 if the address was valid for the specified address family, or | ||
90 | 0 if the address wasn't parseable in the specified address family, or -1 | ||
91 | if some system error occurred (in which case | ||
92 | .Va errno | ||
93 | will have been set). This function is presently valid for AF_INET and | ||
94 | AF_INET6. The | ||
95 | .Fn inet_aton | ||
96 | routine interprets the specified character string as an Internet address, | ||
97 | placing the address into the structure provided. | ||
98 | It returns 1 if the string was successfully interpreted, | ||
99 | or 0 if the string is invalid. | ||
100 | The | ||
101 | .Fn inet_addr | ||
102 | and | ||
103 | .Fn inet_network | ||
104 | functions return numbers suitable for use | ||
105 | as Internet addresses and Internet network | ||
106 | numbers, respectively. | ||
107 | .Pp | ||
108 | The function | ||
109 | .Fn inet_ntop | ||
110 | converts an address from network format (usually a | ||
111 | .Ft struct in_addr | ||
112 | or some other binary form, in network byte order) to presentation format | ||
113 | (suitable for external display purposes). It returns NULL if a system | ||
114 | error occurs (in which case, | ||
115 | .Va errno | ||
116 | will have been set), or it returns a pointer to the destination string. | ||
117 | The routine | ||
118 | .Fn inet_ntoa | ||
119 | takes an Internet address and returns an | ||
120 | .Tn ASCII | ||
121 | string representing the address in | ||
122 | .Ql \&. | ||
123 | notation. The routine | ||
124 | .Fn inet_makeaddr | ||
125 | takes an Internet network number and a local | ||
126 | network address and constructs an Internet address | ||
127 | from it. The routines | ||
128 | .Fn inet_netof | ||
129 | and | ||
130 | .Fn inet_lnaof | ||
131 | break apart Internet host addresses, returning | ||
132 | the network number and local network address part, | ||
133 | respectively. | ||
134 | .Pp | ||
135 | All Internet addresses are returned in network | ||
136 | order (bytes ordered from left to right). | ||
137 | All network numbers and local address parts are | ||
138 | returned as machine format integer values. | ||
139 | .Sh INTERNET ADDRESSES (IP VERSION 4) | ||
140 | Values specified using the | ||
141 | .Ql \&. | ||
142 | notation take one | ||
143 | of the following forms: | ||
144 | .Bd -literal -offset indent | ||
145 | a.b.c.d | ||
146 | a.b.c | ||
147 | a.b | ||
148 | a | ||
149 | .Ed | ||
150 | .Pp | ||
151 | When four parts are specified, each is interpreted | ||
152 | as a byte of data and assigned, from left to right, | ||
153 | to the four bytes of an Internet address. Note | ||
154 | that when an Internet address is viewed as a 32-bit | ||
155 | integer quantity on a system that uses little-endian | ||
156 | byte order (such as the | ||
157 | .Tn Intel 386, 486 | ||
158 | and | ||
159 | .Tn Pentium | ||
160 | processors) the bytes referred to above appear as | ||
161 | .Dq Li d.c.b.a . | ||
162 | That is, little-endian bytes are ordered from right to left. | ||
163 | .Pp | ||
164 | When a three part address is specified, the last | ||
165 | part is interpreted as a 16-bit quantity and placed | ||
166 | in the right-most two bytes of the network address. | ||
167 | This makes the three part address format convenient | ||
168 | for specifying Class B network addresses as | ||
169 | .Dq Li 128.net.host . | ||
170 | .Pp | ||
171 | When a two part address is supplied, the last part | ||
172 | is interpreted as a 24-bit quantity and placed in | ||
173 | the right most three bytes of the network address. | ||
174 | This makes the two part address format convenient | ||
175 | for specifying Class A network addresses as | ||
176 | .Dq Li net.host . | ||
177 | .Pp | ||
178 | When only one part is given, the value is stored | ||
179 | directly in the network address without any byte | ||
180 | rearrangement. | ||
181 | .Pp | ||
182 | All numbers supplied as | ||
183 | .Dq parts | ||
184 | in a | ||
185 | .Ql \&. | ||
186 | notation | ||
187 | may be decimal, octal, or hexadecimal, as specified | ||
188 | in the C language (i.e., a leading 0x or 0X implies | ||
189 | hexadecimal; otherwise, a leading 0 implies octal; | ||
190 | otherwise, the number is interpreted as decimal). | ||
191 | .Sh INTERNET ADDRESSES (IP VERSION 6) | ||
192 | The presentation format of an IPv6 address is given in [RFC1884 2.2]: | ||
193 | .Pp | ||
194 | There are three conventional forms for representing IPv6 addresses as | ||
195 | text strings: | ||
196 | .Bl -enum | ||
197 | .It | ||
198 | The preferred form is x:x:x:x:x:x:x:x, where the 'x's are the | ||
199 | hexadecimal values of the eight 16-bit pieces of the address. | ||
200 | Examples: | ||
201 | .Bd -literal -offset indent | ||
202 | FEDC:BA98:7654:3210:FEDC:BA98:7654:3210 | ||
203 | 1080:0:0:0:8:800:200C:417A | ||
204 | .Ed | ||
205 | .Pp | ||
206 | Note that it is not necessary to write the leading zeros in an | ||
207 | individual field, but there must be at least one numeral in | ||
208 | every field (except for the case described in 2.). | ||
209 | .It | ||
210 | Due to the method of allocating certain styles of IPv6 | ||
211 | addresses, it will be common for addresses to contain long | ||
212 | strings of zero bits. In order to make writing addresses | ||
213 | .Pp | ||
214 | containing zero bits easier a special syntax is available to | ||
215 | compress the zeros. The use of ``::'' indicates multiple groups | ||
216 | of 16-bits of zeros. The ``::'' can only appear once in an | ||
217 | address. The ``::'' can also be used to compress the leading | ||
218 | and/or trailing zeros in an address. | ||
219 | .Pp | ||
220 | For example the following addresses: | ||
221 | .Bd -literal -offset indent | ||
222 | 1080:0:0:0:8:800:200C:417A a unicast address | ||
223 | FF01:0:0:0:0:0:0:43 a multicast address | ||
224 | 0:0:0:0:0:0:0:1 the loopback address | ||
225 | 0:0:0:0:0:0:0:0 the unspecified addresses | ||
226 | .Ed | ||
227 | .Pp | ||
228 | may be represented as: | ||
229 | .Bd -literal -offset indent | ||
230 | 1080::8:800:200C:417A a unicast address | ||
231 | FF01::43 a multicast address | ||
232 | ::1 the loopback address | ||
233 | :: the unspecified addresses | ||
234 | .Ed | ||
235 | .It | ||
236 | An alternative form that is sometimes more convenient when | ||
237 | dealing with a mixed environment of IPv4 and IPv6 nodes is | ||
238 | x:x:x:x:x:x:d.d.d.d, where the 'x's are the hexadecimal values | ||
239 | of the six high-order 16-bit pieces of the address, and the 'd's | ||
240 | are the decimal values of the four low-order 8-bit pieces of the | ||
241 | address (standard IPv4 representation). Examples: | ||
242 | .Bd -literal -offset indent | ||
243 | 0:0:0:0:0:0:13.1.68.3 | ||
244 | 0:0:0:0:0:FFFF:129.144.52.38 | ||
245 | .Ed | ||
246 | .Pp | ||
247 | or in compressed form: | ||
248 | .Bd -literal -offset indent | ||
249 | ::13.1.68.3 | ||
250 | ::FFFF:129.144.52.38 | ||
251 | .Ed | ||
252 | .El | ||
253 | .Sh DIAGNOSTICS | ||
254 | The constant | ||
255 | .Dv INADDR_NONE | ||
256 | is returned by | ||
257 | .Fn inet_addr | ||
258 | and | ||
259 | .Fn inet_network | ||
260 | for malformed requests. | ||
261 | .Sh SEE ALSO | ||
262 | .Xr byteorder 3 , | ||
263 | .Xr gethostbyname 3 , | ||
264 | .Xr getnetent 3 , | ||
265 | .Xr inet_net 3 , | ||
266 | .Xr hosts 5 , | ||
267 | .Xr networks 5 | ||
268 | .Sh STANDARDS | ||
269 | The | ||
270 | .Nm inet_ntop | ||
271 | and | ||
272 | .Nm inet_pton | ||
273 | functions conforms to the IETF IPng BSD API and address formatting | ||
274 | specifications. Note that | ||
275 | .Nm inet_pton | ||
276 | does not accept 1-, 2-, or 3-part dotted addresses; all four parts | ||
277 | must be specified. This is a narrower input set than that accepted by | ||
278 | .Nm inet_aton . | ||
279 | .Sh HISTORY | ||
280 | The | ||
281 | .Nm inet_addr , | ||
282 | .Nm inet_network , | ||
283 | .Nm inet_makeaddr , | ||
284 | .Nm inet_lnaof | ||
285 | and | ||
286 | .Nm inet_netof | ||
287 | functions appeared in | ||
288 | .Bx 4.2 . | ||
289 | The | ||
290 | .Nm inet_aton | ||
291 | and | ||
292 | .Nm inet_ntoa | ||
293 | functions appeared in | ||
294 | .Bx 4.3 . | ||
295 | The | ||
296 | .Nm inet_pton | ||
297 | and | ||
298 | .Nm inet_ntop | ||
299 | functions appeared in BIND 4.9.4. | ||
300 | .Sh BUGS | ||
301 | The value | ||
302 | .Dv INADDR_NONE | ||
303 | (0xffffffff) is a valid broadcast address, but | ||
304 | .Fn inet_addr | ||
305 | cannot return that value without indicating failure. | ||
306 | The newer | ||
307 | .Fn inet_aton | ||
308 | function does not share this problem. | ||
309 | .Pp | ||
310 | The problem of host byte ordering versus network byte ordering is | ||
311 | confusing. | ||
312 | .Pp | ||
313 | The string returned by | ||
314 | .Fn inet_ntoa | ||
315 | resides in a static memory area. | ||
316 | .Pp | ||
317 | .Fn inet_addr | ||
318 | should return a | ||
319 | .Fa "struct in_addr" . | ||
diff --git a/src/lib/libc/net/inet_addr.c b/src/lib/libc/net/inet_addr.c new file mode 100644 index 0000000000..5e4dcdafb2 --- /dev/null +++ b/src/lib/libc/net/inet_addr.c | |||
@@ -0,0 +1,187 @@ | |||
1 | /* $OpenBSD: inet_addr.c,v 1.5 1997/04/05 21:13:10 millert Exp $ */ | ||
2 | |||
3 | /* | ||
4 | * ++Copyright++ 1983, 1990, 1993 | ||
5 | * - | ||
6 | * Copyright (c) 1983, 1990, 1993 | ||
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 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.5 1997/04/05 21:13:10 millert Exp $"; | ||
64 | #endif | ||
65 | #endif /* LIBC_SCCS and not lint */ | ||
66 | |||
67 | #include <sys/types.h> | ||
68 | #include <sys/param.h> | ||
69 | #include <netinet/in.h> | ||
70 | #include <arpa/inet.h> | ||
71 | #include <ctype.h> | ||
72 | |||
73 | /* | ||
74 | * Ascii internet address interpretation routine. | ||
75 | * The value returned is in network order. | ||
76 | */ | ||
77 | in_addr_t | ||
78 | inet_addr(cp) | ||
79 | register const char *cp; | ||
80 | { | ||
81 | struct in_addr val; | ||
82 | |||
83 | if (inet_aton(cp, &val)) | ||
84 | return (val.s_addr); | ||
85 | return (INADDR_NONE); | ||
86 | } | ||
87 | |||
88 | /* | ||
89 | * Check whether "cp" is a valid ascii representation | ||
90 | * of an Internet address and convert to a binary address. | ||
91 | * Returns 1 if the address is valid, 0 if not. | ||
92 | * This replaces inet_addr, the return value from which | ||
93 | * cannot distinguish between failure and a local broadcast address. | ||
94 | */ | ||
95 | int | ||
96 | inet_aton(cp, addr) | ||
97 | register const char *cp; | ||
98 | struct in_addr *addr; | ||
99 | { | ||
100 | register in_addr_t val; | ||
101 | register int base, n; | ||
102 | register char c; | ||
103 | u_int parts[4]; | ||
104 | register u_int *pp = parts; | ||
105 | |||
106 | c = *cp; | ||
107 | for (;;) { | ||
108 | /* | ||
109 | * Collect number up to ``.''. | ||
110 | * Values are specified as for C: | ||
111 | * 0x=hex, 0=octal, isdigit=decimal. | ||
112 | */ | ||
113 | if (!isdigit(c)) | ||
114 | return (0); | ||
115 | val = 0; base = 10; | ||
116 | if (c == '0') { | ||
117 | c = *++cp; | ||
118 | if (c == 'x' || c == 'X') | ||
119 | base = 16, c = *++cp; | ||
120 | else | ||
121 | base = 8; | ||
122 | } | ||
123 | for (;;) { | ||
124 | if (isascii(c) && isdigit(c)) { | ||
125 | val = (val * base) + (c - '0'); | ||
126 | c = *++cp; | ||
127 | } else if (base == 16 && isascii(c) && isxdigit(c)) { | ||
128 | val = (val << 4) | | ||
129 | (c + 10 - (islower(c) ? 'a' : 'A')); | ||
130 | c = *++cp; | ||
131 | } else | ||
132 | break; | ||
133 | } | ||
134 | if (c == '.') { | ||
135 | /* | ||
136 | * Internet format: | ||
137 | * a.b.c.d | ||
138 | * a.b.c (with c treated as 16 bits) | ||
139 | * a.b (with b treated as 24 bits) | ||
140 | */ | ||
141 | if (pp >= parts + 3) | ||
142 | return (0); | ||
143 | *pp++ = val; | ||
144 | c = *++cp; | ||
145 | } else | ||
146 | break; | ||
147 | } | ||
148 | /* | ||
149 | * Check for trailing characters. | ||
150 | */ | ||
151 | if (c != '\0' && (!isascii(c) || !isspace(c))) | ||
152 | return (0); | ||
153 | /* | ||
154 | * Concoct the address according to | ||
155 | * the number of parts specified. | ||
156 | */ | ||
157 | n = pp - parts + 1; | ||
158 | switch (n) { | ||
159 | |||
160 | case 0: | ||
161 | return (0); /* initial nondigit */ | ||
162 | |||
163 | case 1: /* a -- 32 bits */ | ||
164 | break; | ||
165 | |||
166 | case 2: /* a.b -- 8.24 bits */ | ||
167 | if (val > 0xffffff) | ||
168 | return (0); | ||
169 | val |= parts[0] << 24; | ||
170 | break; | ||
171 | |||
172 | case 3: /* a.b.c -- 8.8.16 bits */ | ||
173 | if (val > 0xffff) | ||
174 | return (0); | ||
175 | val |= (parts[0] << 24) | (parts[1] << 16); | ||
176 | break; | ||
177 | |||
178 | case 4: /* a.b.c.d -- 8.8.8.8 bits */ | ||
179 | if (val > 0xff) | ||
180 | return (0); | ||
181 | val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); | ||
182 | break; | ||
183 | } | ||
184 | if (addr) | ||
185 | addr->s_addr = htonl(val); | ||
186 | return (1); | ||
187 | } | ||
diff --git a/src/lib/libc/net/inet_lnaof.c b/src/lib/libc/net/inet_lnaof.c new file mode 100644 index 0000000000..6aed18699b --- /dev/null +++ b/src/lib/libc/net/inet_lnaof.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1983, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: inet_lnaof.c,v 1.3 1997/04/05 21:13:11 millert Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | #include <sys/param.h> | ||
39 | #include <netinet/in.h> | ||
40 | #include <arpa/inet.h> | ||
41 | |||
42 | /* | ||
43 | * Return the local network address portion of an | ||
44 | * internet address; handles class a/b/c network | ||
45 | * number formats. | ||
46 | */ | ||
47 | in_addr_t | ||
48 | inet_lnaof(in) | ||
49 | struct in_addr in; | ||
50 | { | ||
51 | register in_addr_t i = ntohl(in.s_addr); | ||
52 | |||
53 | if (IN_CLASSA(i)) | ||
54 | return ((i)&IN_CLASSA_HOST); | ||
55 | else if (IN_CLASSB(i)) | ||
56 | return ((i)&IN_CLASSB_HOST); | ||
57 | else | ||
58 | return ((i)&IN_CLASSC_HOST); | ||
59 | } | ||
diff --git a/src/lib/libc/net/inet_makeaddr.c b/src/lib/libc/net/inet_makeaddr.c new file mode 100644 index 0000000000..196a589e4c --- /dev/null +++ b/src/lib/libc/net/inet_makeaddr.c | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1983, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: inet_makeaddr.c,v 1.3 1997/04/05 21:13:12 millert Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | #include <sys/param.h> | ||
39 | #include <netinet/in.h> | ||
40 | #include <arpa/inet.h> | ||
41 | |||
42 | /* | ||
43 | * Formulate an Internet address from network + host. Used in | ||
44 | * building addresses stored in the ifnet structure. | ||
45 | */ | ||
46 | struct in_addr | ||
47 | inet_makeaddr(net, host) | ||
48 | in_addr_t net, host; | ||
49 | { | ||
50 | in_addr_t addr; | ||
51 | |||
52 | if (net < 128) | ||
53 | addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST); | ||
54 | else if (net < 65536) | ||
55 | addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST); | ||
56 | else if (net < 16777216L) | ||
57 | addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST); | ||
58 | else | ||
59 | addr = net | host; | ||
60 | addr = htonl(addr); | ||
61 | return (*(struct in_addr *)&addr); | ||
62 | } | ||
diff --git a/src/lib/libc/net/inet_net.3 b/src/lib/libc/net/inet_net.3 new file mode 100644 index 0000000000..1a42aff6ea --- /dev/null +++ b/src/lib/libc/net/inet_net.3 | |||
@@ -0,0 +1,149 @@ | |||
1 | .\" $OpenBSD: inet_net.3,v 1.1 1997/06/23 03:37:26 millert Exp $ | ||
2 | .\" $NetBSD: inet_net.3,v 1.1 1997/06/18 02:25:27 lukem Exp $ | ||
3 | .\" | ||
4 | .\" Copyright (c) 1997 The NetBSD Foundation, Inc. | ||
5 | .\" All rights reserved. | ||
6 | .\" | ||
7 | .\" This code is derived from software contributed to The NetBSD Foundation | ||
8 | .\" by Luke Mewburn. | ||
9 | .\" | ||
10 | .\" Redistribution and use in source and binary forms, with or without | ||
11 | .\" modification, are permitted provided that the following conditions | ||
12 | .\" are met: | ||
13 | .\" 1. Redistributions of source code must retain the above copyright | ||
14 | .\" notice, this list of conditions and the following disclaimer. | ||
15 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
16 | .\" notice, this list of conditions and the following disclaimer in the | ||
17 | .\" documentation and/or other materials provided with the distribution. | ||
18 | .\" 3. All advertising materials mentioning features or use of this software | ||
19 | .\" must display the following acknowledgement: | ||
20 | .\" This product includes software developed by the NetBSD | ||
21 | .\" Foundation, Inc. and its contributors. | ||
22 | .\" 4. Neither the name of The NetBSD Foundation nor the names of its | ||
23 | .\" contributors may be used to endorse or promote products derived | ||
24 | .\" from this software without specific prior written permission. | ||
25 | .\" | ||
26 | .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | ||
27 | .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||
28 | .\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
29 | .\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE | ||
30 | .\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
31 | .\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
32 | .\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
33 | .\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
34 | .\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
35 | .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
36 | .\" POSSIBILITY OF SUCH DAMAGE. | ||
37 | .\" | ||
38 | .Dd June 18, 1997 | ||
39 | .Dt INET_NET 3 | ||
40 | .Os | ||
41 | .Sh NAME | ||
42 | .Nm inet_net_ntop , | ||
43 | .Nm inet_net_pton | ||
44 | .Nd Internet network number manipulation routines | ||
45 | .Sh SYNOPSIS | ||
46 | .Fd #include <sys/socket.h> | ||
47 | .Fd #include <netinet/in.h> | ||
48 | .Fd #include <arpa/inet.h> | ||
49 | .Ft char * | ||
50 | .Fn inet_net_ntop "int af" "const void *src" "int bits" "char *dst" "size_t size" | ||
51 | .Ft int | ||
52 | .Fn inet_net_pton "int af" "const char *src" "void *dst" "size_t size" | ||
53 | .Sh DESCRIPTION | ||
54 | The | ||
55 | .Fn inet_net_ntop | ||
56 | function converts an Internet network number from network format (usually a | ||
57 | .Ft struct in_addr | ||
58 | or some other binary form, in network byte order) to CIDR presentation format | ||
59 | (suitable for external display purposes). | ||
60 | .Fa bits | ||
61 | is the number of bits in | ||
62 | .Fa src | ||
63 | that are the network number. | ||
64 | It returns NULL if a system error occurs (in which case, | ||
65 | .Va errno | ||
66 | will have been set), or it returns a pointer to the destination string. | ||
67 | .Pp | ||
68 | The | ||
69 | .Fn inet_net_pton | ||
70 | function converts a presentation format Internet network number (that is, | ||
71 | printable form as held in a character string) to network format (usually a | ||
72 | .Ft struct in_addr | ||
73 | or some other internal binary representation, in network byte order). | ||
74 | It returns the number of bits (either computed based on the class, or | ||
75 | specified with /CIDR), or -1 if a failure occurred | ||
76 | (in which case | ||
77 | .Va errno | ||
78 | will have been set. | ||
79 | It will be set to | ||
80 | .Er ENOENT | ||
81 | if the Internet network number was not valid). | ||
82 | .Pp | ||
83 | The currently supported value for | ||
84 | .Fa af | ||
85 | is: AF_INET. | ||
86 | .Fa size | ||
87 | is the size of the result buffer | ||
88 | .Fa dst . | ||
89 | .Pp | ||
90 | .Sh NETWORK NUMBERS (IP VERSION 4) | ||
91 | Internet network numbers may be specified in one of the following forms: | ||
92 | .Bd -literal -offset indent | ||
93 | a.b.c.d/bits | ||
94 | a.b.c.d | ||
95 | a.b.c | ||
96 | a.b | ||
97 | a | ||
98 | .Ed | ||
99 | .Pp | ||
100 | When four parts are specified, each is interpreted | ||
101 | as a byte of data and assigned, from left to right, | ||
102 | to the four bytes of an Internet network number. Note | ||
103 | that when an Internet network number is viewed as a 32-bit | ||
104 | integer quantity on a system that uses little-endian | ||
105 | byte order (such as the | ||
106 | .Tn Intel 386, 486 | ||
107 | and | ||
108 | .Tn Pentium | ||
109 | processors) the bytes referred to above appear as | ||
110 | .Dq Li d.c.b.a . | ||
111 | That is, little-endian bytes are ordered from right to left. | ||
112 | .Pp | ||
113 | When a three part number is specified, the last | ||
114 | part is interpreted as a 16-bit quantity and placed | ||
115 | in the right-most two bytes of the Internet network number. | ||
116 | This makes the three part number format convenient | ||
117 | for specifying Class B network numbers as | ||
118 | .Dq Li 128.net.host . | ||
119 | .Pp | ||
120 | When a two part number is supplied, the last part | ||
121 | is interpreted as a 24-bit quantity and placed in | ||
122 | the right most three bytes of the Internet network number. | ||
123 | This makes the two part number format convenient | ||
124 | for specifying Class A network numbers as | ||
125 | .Dq Li net.host . | ||
126 | .Pp | ||
127 | When only one part is given, the value is stored | ||
128 | directly in the Internet network number without any byte | ||
129 | rearrangement. | ||
130 | .Pp | ||
131 | All numbers supplied as | ||
132 | .Dq parts | ||
133 | in a | ||
134 | .Ql \&. | ||
135 | notation | ||
136 | may be decimal, octal, or hexadecimal, as specified | ||
137 | in the C language (i.e., a leading 0x or 0X implies | ||
138 | hexadecimal; otherwise, a leading 0 implies octal; | ||
139 | otherwise, the number is interpreted as decimal). | ||
140 | .Sh SEE ALSO | ||
141 | .Xr byteorder 3 , | ||
142 | .Xr inet 3 , | ||
143 | .Xr networks 5 | ||
144 | .Sh HISTORY | ||
145 | The | ||
146 | .Nm inet_net_ntop | ||
147 | and | ||
148 | .Nm inet_net_pton | ||
149 | functions first appeared in BIND 4.9.4. | ||
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..ffcddd8d91 --- /dev/null +++ b/src/lib/libc/net/inet_neta.c | |||
@@ -0,0 +1,83 @@ | |||
1 | /* $OpenBSD: inet_neta.c,v 1.2 1997/04/05 21:13:12 millert 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.2 1997/04/05 21:13:12 millert Exp $"; | ||
23 | #else | ||
24 | static const char rcsid[] = "$OpenBSD: inet_neta.c,v 1.2 1997/04/05 21:13:12 millert 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 | |||
37 | /* | ||
38 | * char * | ||
39 | * inet_neta(src, dst, size) | ||
40 | * format an in_addr_t network number into presentation format. | ||
41 | * return: | ||
42 | * pointer to dst, or NULL if an error occurred (check errno). | ||
43 | * note: | ||
44 | * format of ``src'' is as for inet_network(). | ||
45 | * author: | ||
46 | * Paul Vixie (ISC), July 1996 | ||
47 | */ | ||
48 | char * | ||
49 | inet_neta(src, dst, size) | ||
50 | in_addr_t src; | ||
51 | char *dst; | ||
52 | size_t size; | ||
53 | { | ||
54 | char *odst = dst; | ||
55 | char *tp; | ||
56 | |||
57 | while (src & 0xffffffff) { | ||
58 | u_char b = (src & 0xff000000) >> 24; | ||
59 | |||
60 | src <<= 8; | ||
61 | if (b) { | ||
62 | if (size < sizeof "255.") | ||
63 | goto emsgsize; | ||
64 | tp = dst; | ||
65 | dst += sprintf(dst, "%u", b); | ||
66 | if (src != 0L) { | ||
67 | *dst++ = '.'; | ||
68 | *dst = '\0'; | ||
69 | } | ||
70 | size -= (size_t)(dst - tp); | ||
71 | } | ||
72 | } | ||
73 | if (dst == odst) { | ||
74 | if (size < sizeof "0.0.0.0") | ||
75 | goto emsgsize; | ||
76 | strcpy(dst, "0.0.0.0"); | ||
77 | } | ||
78 | return (odst); | ||
79 | |||
80 | emsgsize: | ||
81 | errno = EMSGSIZE; | ||
82 | return (NULL); | ||
83 | } | ||
diff --git a/src/lib/libc/net/inet_netof.c b/src/lib/libc/net/inet_netof.c new file mode 100644 index 0000000000..f3b9c01697 --- /dev/null +++ b/src/lib/libc/net/inet_netof.c | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1983, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: inet_netof.c,v 1.3 1997/04/05 21:13:13 millert Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | #include <sys/param.h> | ||
39 | #include <netinet/in.h> | ||
40 | #include <arpa/inet.h> | ||
41 | |||
42 | /* | ||
43 | * Return the network number from an internet | ||
44 | * address; handles class a/b/c network #'s. | ||
45 | */ | ||
46 | in_addr_t | ||
47 | inet_netof(in) | ||
48 | struct in_addr in; | ||
49 | { | ||
50 | register in_addr_t i = ntohl(in.s_addr); | ||
51 | |||
52 | if (IN_CLASSA(i)) | ||
53 | return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT); | ||
54 | else if (IN_CLASSB(i)) | ||
55 | return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT); | ||
56 | else | ||
57 | return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT); | ||
58 | } | ||
diff --git a/src/lib/libc/net/inet_network.c b/src/lib/libc/net/inet_network.c new file mode 100644 index 0000000000..8a9a555d62 --- /dev/null +++ b/src/lib/libc/net/inet_network.c | |||
@@ -0,0 +1,92 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1983, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: inet_network.c,v 1.7 1997/07/09 01:08:37 millert Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | #include <sys/types.h> | ||
39 | #include <netinet/in.h> | ||
40 | #include <arpa/inet.h> | ||
41 | #include <ctype.h> | ||
42 | |||
43 | /* | ||
44 | * Internet network address interpretation routine. | ||
45 | * The library routines call this routine to interpret | ||
46 | * network numbers. | ||
47 | */ | ||
48 | in_addr_t | ||
49 | inet_network(cp) | ||
50 | register const char *cp; | ||
51 | { | ||
52 | register in_addr_t val, base, n; | ||
53 | register char c; | ||
54 | in_addr_t parts[4], *pp = parts; | ||
55 | register int i; | ||
56 | |||
57 | again: | ||
58 | val = 0; base = 10; | ||
59 | if (*cp == '0') | ||
60 | base = 8, cp++; | ||
61 | if (*cp == 'x' || *cp == 'X') | ||
62 | base = 16, cp++; | ||
63 | while ((c = *cp)) { | ||
64 | if (isdigit(c)) { | ||
65 | val = (val * base) + (c - '0'); | ||
66 | cp++; | ||
67 | continue; | ||
68 | } | ||
69 | if (base == 16 && isxdigit(c)) { | ||
70 | val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A')); | ||
71 | cp++; | ||
72 | continue; | ||
73 | } | ||
74 | break; | ||
75 | } | ||
76 | if (*cp == '.') { | ||
77 | if (pp >= parts + 3) | ||
78 | return (INADDR_NONE); | ||
79 | *pp++ = val, cp++; | ||
80 | goto again; | ||
81 | } | ||
82 | if (*cp && !isspace(*cp)) | ||
83 | return (INADDR_NONE); | ||
84 | *pp++ = val; | ||
85 | n = pp - parts; | ||
86 | for (val = 0, i = 0; i < 4; i++) { | ||
87 | val <<= 8; | ||
88 | if (i < n) | ||
89 | val |= parts[i] & 0xff; | ||
90 | } | ||
91 | return (val); | ||
92 | } | ||
diff --git a/src/lib/libc/net/inet_ntoa.c b/src/lib/libc/net/inet_ntoa.c new file mode 100644 index 0000000000..148732ba5a --- /dev/null +++ b/src/lib/libc/net/inet_ntoa.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1983, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: inet_ntoa.c,v 1.2 1996/08/19 08:29:16 tholo Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | /* | ||
39 | * Convert network-format internet address | ||
40 | * to base 256 d.d.d.d representation. | ||
41 | */ | ||
42 | #include <sys/types.h> | ||
43 | #include <netinet/in.h> | ||
44 | #include <arpa/inet.h> | ||
45 | #include <stdio.h> | ||
46 | |||
47 | char * | ||
48 | inet_ntoa(in) | ||
49 | struct in_addr in; | ||
50 | { | ||
51 | static char b[18]; | ||
52 | register char *p; | ||
53 | |||
54 | p = (char *)∈ | ||
55 | #define UC(b) (((int)b)&0xff) | ||
56 | (void)snprintf(b, sizeof(b), | ||
57 | "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3])); | ||
58 | return (b); | ||
59 | } | ||
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..46b4b24819 --- /dev/null +++ b/src/lib/libc/net/inet_pton.c | |||
@@ -0,0 +1,220 @@ | |||
1 | /* $OpenBSD: inet_pton.c,v 1.2 1997/04/13 05:08:24 deraadt 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.2 1997/04/13 05:08:24 deraadt 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 | if (! saw_digit) { | ||
104 | if (++octets > 4) | ||
105 | return (0); | ||
106 | saw_digit = 1; | ||
107 | } | ||
108 | *tp = new; | ||
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/ipx.3 b/src/lib/libc/net/ipx.3 new file mode 100644 index 0000000000..073be74807 --- /dev/null +++ b/src/lib/libc/net/ipx.3 | |||
@@ -0,0 +1,126 @@ | |||
1 | .\" $OpenBSD: ipx.3,v 1.3 1997/09/09 11:45:17 kstailey Exp $ | ||
2 | .\" | ||
3 | .\" Copyright (c) 1986, 1991, 1993 | ||
4 | .\" The Regents of the University of California. All rights reserved. | ||
5 | .\" | ||
6 | .\" Redistribution and use in source and binary forms, with or without | ||
7 | .\" modification, are permitted provided that the following conditions | ||
8 | .\" are met: | ||
9 | .\" 1. Redistributions of source code must retain the above copyright | ||
10 | .\" notice, this list of conditions and the following disclaimer. | ||
11 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
12 | .\" notice, this list of conditions and the following disclaimer in the | ||
13 | .\" documentation and/or other materials provided with the distribution. | ||
14 | .\" 3. All advertising materials mentioning features or use of this software | ||
15 | .\" must display the following acknowledgement: | ||
16 | .\" This product includes software developed by the University of | ||
17 | .\" California, Berkeley and its contributors. | ||
18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
19 | .\" may be used to endorse or promote products derived from this software | ||
20 | .\" without specific prior written permission. | ||
21 | .\" | ||
22 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
23 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
24 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
26 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
27 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
28 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
29 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
30 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
32 | .\" SUCH DAMAGE. | ||
33 | .\" | ||
34 | .Dd June 4, 1993 | ||
35 | .Dt IPX 3 | ||
36 | .Os OpenBSD 1.2 | ||
37 | .Sh NAME | ||
38 | .Nm ipx_addr , | ||
39 | .Nm ipx_ntoa | ||
40 | .Nd IPX address conversion routines | ||
41 | .Sh SYNOPSIS | ||
42 | .Fd #include <sys/types.h> | ||
43 | .Fd #include <netipx/ipx.h> | ||
44 | .Ft struct ipx_addr | ||
45 | .Fn ipx_addr "char *cp" | ||
46 | .Ft char * | ||
47 | .Fn ipx_ntoa "struct ipx_addr ipx" | ||
48 | .Sh DESCRIPTION | ||
49 | The routine | ||
50 | .Fn ipx_addr | ||
51 | interprets character strings representing | ||
52 | .Tn IPX | ||
53 | addresses, returning binary information suitable | ||
54 | for use in system calls. | ||
55 | The routine | ||
56 | .Fn ipx_ntoa | ||
57 | takes | ||
58 | .Tn IPX | ||
59 | addresses and returns | ||
60 | .Tn ASCII | ||
61 | strings representing the address in a | ||
62 | notation in common use: | ||
63 | .Bd -filled -offset indent | ||
64 | <network number>.<host number>.<port number> | ||
65 | .Ed | ||
66 | .Pp | ||
67 | Trailing zero fields are suppressed, and each number is printed in hexadecimal, | ||
68 | in a format suitable for input to | ||
69 | .Fn ipx_addr . | ||
70 | Any fields lacking super-decimal digits will have a | ||
71 | trailing | ||
72 | .Ql H | ||
73 | appended. | ||
74 | .Pp | ||
75 | An effort has been made to insure that | ||
76 | .Fn ipx_addr | ||
77 | be compatible with most formats in common use. | ||
78 | It will first separate an address into 1 to 3 fields using a single delimiter | ||
79 | chosen from | ||
80 | period | ||
81 | .Ql \&. , | ||
82 | colon | ||
83 | .Ql \&: | ||
84 | or pound-sign | ||
85 | .Ql \&# . | ||
86 | Each field is then examined for byte separators (colon or period). | ||
87 | If there are byte separators, each subfield separated is taken to be | ||
88 | a small hexadecimal number, and the entirety is taken as a network-byte-ordered | ||
89 | quantity to be zero extended in the high-network-order bytes. | ||
90 | Next, the field is inspected for hyphens, in which case | ||
91 | the field is assumed to be a number in decimal notation | ||
92 | with hyphens separating the millenia. | ||
93 | Next, the field is assumed to be a number: | ||
94 | It is interpreted | ||
95 | as hexadecimal if there is a leading | ||
96 | .Ql 0x | ||
97 | (as in C), | ||
98 | a trailing | ||
99 | .Ql H | ||
100 | (as in Mesa), or there are any super-decimal digits present. | ||
101 | It is interpreted as octal is there is a leading | ||
102 | .Ql 0 | ||
103 | and there are no super-octal digits. | ||
104 | Otherwise, it is converted as a decimal number. | ||
105 | .Sh RETURN VALUES | ||
106 | None. (See | ||
107 | .Sx BUGS . ) | ||
108 | .Sh SEE ALSO | ||
109 | .Xr ns 4 , | ||
110 | .Xr hosts 5 , | ||
111 | .Xr networks 5 | ||
112 | .Sh HISTORY | ||
113 | The precursor | ||
114 | .Fn ns_addr | ||
115 | and | ||
116 | .Fn ns_ntoa | ||
117 | functions appeared in | ||
118 | .Bx 4.3 . | ||
119 | .Sh BUGS | ||
120 | The string returned by | ||
121 | .Fn ipx_ntoa | ||
122 | resides in a static memory area. | ||
123 | The function | ||
124 | .Fn ipx_addr | ||
125 | should diagnose improperly formed input, and there should be an unambiguous | ||
126 | way to recognize this. | ||
diff --git a/src/lib/libc/net/ipx_addr.c b/src/lib/libc/net/ipx_addr.c new file mode 100644 index 0000000000..a76e03e913 --- /dev/null +++ b/src/lib/libc/net/ipx_addr.c | |||
@@ -0,0 +1,229 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1986, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * This code is derived from software contributed to Berkeley by | ||
6 | * J.Q. Johnson. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer. | ||
13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer in the | ||
15 | * documentation and/or other materials provided with the distribution. | ||
16 | * 3. All advertising materials mentioning features or use of this software | ||
17 | * must display the following acknowledgement: | ||
18 | * This product includes software developed by the University of | ||
19 | * California, Berkeley and its contributors. | ||
20 | * 4. Neither the name of the University nor the names of its contributors | ||
21 | * may be used to endorse or promote products derived from this software | ||
22 | * without specific prior written permission. | ||
23 | * | ||
24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
34 | * SUCH DAMAGE. | ||
35 | * | ||
36 | * from @(#)ipx_addr.c | ||
37 | */ | ||
38 | |||
39 | #if defined(LIBC_SCCS) && !defined(lint) | ||
40 | static char rcsid[] = "$OpenBSD: ipx_addr.c,v 1.3 1997/07/09 01:08:39 millert Exp $"; | ||
41 | #endif /* LIBC_SCCS and not lint */ | ||
42 | |||
43 | #include <sys/param.h> | ||
44 | #include <netipx/ipx.h> | ||
45 | #include <stdio.h> | ||
46 | #include <string.h> | ||
47 | |||
48 | static struct ipx_addr addr, zero_addr; | ||
49 | |||
50 | static void Field(), cvtbase(); | ||
51 | |||
52 | struct ipx_addr | ||
53 | ipx_addr(name) | ||
54 | const char *name; | ||
55 | { | ||
56 | char separator; | ||
57 | char *hostname, *socketname, *cp; | ||
58 | char buf[50]; | ||
59 | |||
60 | (void)strncpy(buf, name, sizeof(buf) - 1); | ||
61 | buf[sizeof(buf) - 1] = '\0'; | ||
62 | |||
63 | /* | ||
64 | * First, figure out what he intends as a field separtor. | ||
65 | * Despite the way this routine is written, the prefered | ||
66 | * form 2-272.AA001234H.01777, i.e. XDE standard. | ||
67 | * Great efforts are made to insure backward compatability. | ||
68 | */ | ||
69 | if ((hostname = strchr(buf, '#'))) | ||
70 | separator = '#'; | ||
71 | else { | ||
72 | hostname = strchr(buf, '.'); | ||
73 | if ((cp = strchr(buf, ':')) && | ||
74 | ((hostname && cp < hostname) || (hostname == 0))) { | ||
75 | hostname = cp; | ||
76 | separator = ':'; | ||
77 | } else | ||
78 | separator = '.'; | ||
79 | } | ||
80 | if (hostname) | ||
81 | *hostname++ = 0; | ||
82 | |||
83 | addr = zero_addr; | ||
84 | Field(buf, addr.ipx_net.c_net, 4); | ||
85 | if (hostname == 0) | ||
86 | return (addr); /* No separator means net only */ | ||
87 | |||
88 | socketname = strchr(hostname, separator); | ||
89 | if (socketname) { | ||
90 | *socketname++ = 0; | ||
91 | Field(socketname, (u_char *)&addr.ipx_port, 2); | ||
92 | } | ||
93 | |||
94 | Field(hostname, addr.ipx_host.c_host, 6); | ||
95 | |||
96 | return (addr); | ||
97 | } | ||
98 | |||
99 | static void | ||
100 | Field(buf, out, len) | ||
101 | char *buf; | ||
102 | u_char *out; | ||
103 | int len; | ||
104 | { | ||
105 | register char *bp = buf; | ||
106 | int i, ibase, base16 = 0, base10 = 0, clen = 0; | ||
107 | int hb[6], *hp; | ||
108 | char *fmt; | ||
109 | |||
110 | /* | ||
111 | * first try 2-273#2-852-151-014#socket | ||
112 | */ | ||
113 | if ((*buf != '-') && | ||
114 | (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d", | ||
115 | &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) { | ||
116 | cvtbase(1000L, 256, hb, i, out, len); | ||
117 | return; | ||
118 | } | ||
119 | /* | ||
120 | * try form 8E1#0.0.AA.0.5E.E6#socket | ||
121 | */ | ||
122 | if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x", | ||
123 | &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) { | ||
124 | cvtbase(256L, 256, hb, i, out, len); | ||
125 | return; | ||
126 | } | ||
127 | /* | ||
128 | * try form 8E1#0:0:AA:0:5E:E6#socket | ||
129 | */ | ||
130 | if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x", | ||
131 | &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) { | ||
132 | cvtbase(256L, 256, hb, i, out, len); | ||
133 | return; | ||
134 | } | ||
135 | /* | ||
136 | * This is REALLY stretching it but there was a | ||
137 | * comma notation separting shorts -- definitely non standard | ||
138 | */ | ||
139 | if (1 < (i = sscanf(buf,"%x,%x,%x", | ||
140 | &hb[0], &hb[1], &hb[2]))) { | ||
141 | hb[0] = htons(hb[0]); hb[1] = htons(hb[1]); | ||
142 | hb[2] = htons(hb[2]); | ||
143 | cvtbase(65536L, 256, hb, i, out, len); | ||
144 | return; | ||
145 | } | ||
146 | |||
147 | /* Need to decide if base 10, 16 or 8 */ | ||
148 | while (*bp) switch (*bp++) { | ||
149 | |||
150 | case '0': case '1': case '2': case '3': case '4': case '5': | ||
151 | case '6': case '7': case '-': | ||
152 | break; | ||
153 | |||
154 | case '8': case '9': | ||
155 | base10 = 1; | ||
156 | break; | ||
157 | |||
158 | case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': | ||
159 | case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': | ||
160 | base16 = 1; | ||
161 | break; | ||
162 | |||
163 | case 'x': case 'X': | ||
164 | *--bp = '0'; | ||
165 | base16 = 1; | ||
166 | break; | ||
167 | |||
168 | case 'h': case 'H': | ||
169 | base16 = 1; | ||
170 | /* fall into */ | ||
171 | |||
172 | default: | ||
173 | *--bp = 0; /* Ends Loop */ | ||
174 | } | ||
175 | if (base16) { | ||
176 | fmt = "%3x"; | ||
177 | ibase = 4096; | ||
178 | } else if (base10 == 0 && *buf == '0') { | ||
179 | fmt = "%3o"; | ||
180 | ibase = 512; | ||
181 | } else { | ||
182 | fmt = "%3d"; | ||
183 | ibase = 1000; | ||
184 | } | ||
185 | |||
186 | for (bp = buf; *bp++; ) clen++; | ||
187 | if (clen == 0) clen++; | ||
188 | if (clen > 18) clen = 18; | ||
189 | i = ((clen - 1) / 3) + 1; | ||
190 | bp = clen + buf - 3; | ||
191 | hp = hb + i - 1; | ||
192 | |||
193 | while (hp > hb) { | ||
194 | (void)sscanf(bp, fmt, hp); | ||
195 | bp[0] = 0; | ||
196 | hp--; | ||
197 | bp -= 3; | ||
198 | } | ||
199 | (void)sscanf(buf, fmt, hp); | ||
200 | cvtbase((long)ibase, 256, hb, i, out, len); | ||
201 | } | ||
202 | |||
203 | static void | ||
204 | cvtbase(oldbase,newbase,input,inlen,result,reslen) | ||
205 | long oldbase; | ||
206 | int newbase; | ||
207 | int input[]; | ||
208 | int inlen; | ||
209 | unsigned char result[]; | ||
210 | int reslen; | ||
211 | { | ||
212 | int d, e; | ||
213 | long sum; | ||
214 | |||
215 | e = 1; | ||
216 | while (e > 0 && reslen > 0) { | ||
217 | d = 0; e = 0; sum = 0; | ||
218 | /* long division: input=input/newbase */ | ||
219 | while (d < inlen) { | ||
220 | sum = sum*oldbase + (long) input[d]; | ||
221 | e += (sum > 0); | ||
222 | input[d++] = sum / newbase; | ||
223 | sum %= newbase; | ||
224 | } | ||
225 | result[--reslen] = sum; /* accumulate remainder */ | ||
226 | } | ||
227 | for (d=0; d < reslen; d++) | ||
228 | result[d] = 0; | ||
229 | } | ||
diff --git a/src/lib/libc/net/ipx_ntoa.c b/src/lib/libc/net/ipx_ntoa.c new file mode 100644 index 0000000000..1dcfe7181b --- /dev/null +++ b/src/lib/libc/net/ipx_ntoa.c | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1986, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: ipx_ntoa.c,v 1.2 1996/08/19 08:29:20 tholo Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | #include <sys/param.h> | ||
39 | #include <netipx/ipx.h> | ||
40 | #include <stdio.h> | ||
41 | |||
42 | char * | ||
43 | ipx_ntoa(addr) | ||
44 | struct ipx_addr addr; | ||
45 | { | ||
46 | static char obuf[] = "xxxx.xx:xx:xx:xx:xx:xx.uuuuu"; | ||
47 | |||
48 | sprintf(obuf, "%8xH.%02x:%02x:%02x:%02x:%02x:%02x.%u", | ||
49 | ntohl(addr.ipx_net.l_net), | ||
50 | addr.ipx_host.c_host[0], | ||
51 | addr.ipx_host.c_host[1], | ||
52 | addr.ipx_host.c_host[2], | ||
53 | addr.ipx_host.c_host[3], | ||
54 | addr.ipx_host.c_host[4], | ||
55 | addr.ipx_host.c_host[5], | ||
56 | ntohs(addr.ipx_port)); | ||
57 | return (obuf); | ||
58 | } | ||
diff --git a/src/lib/libc/net/iso_addr.3 b/src/lib/libc/net/iso_addr.3 new file mode 100644 index 0000000000..d9bf9086be --- /dev/null +++ b/src/lib/libc/net/iso_addr.3 | |||
@@ -0,0 +1,110 @@ | |||
1 | .\" $OpenBSD: iso_addr.3,v 1.2 1996/08/19 08:29:22 tholo Exp $ | ||
2 | .\" | ||
3 | .\" Copyright (c) 1993 | ||
4 | .\" The Regents of the University of California. All rights reserved. | ||
5 | .\" | ||
6 | .\" Redistribution and use in source and binary forms, with or without | ||
7 | .\" modification, are permitted provided that the following conditions | ||
8 | .\" are met: | ||
9 | .\" 1. Redistributions of source code must retain the above copyright | ||
10 | .\" notice, this list of conditions and the following disclaimer. | ||
11 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
12 | .\" notice, this list of conditions and the following disclaimer in the | ||
13 | .\" documentation and/or other materials provided with the distribution. | ||
14 | .\" 3. All advertising materials mentioning features or use of this software | ||
15 | .\" must display the following acknowledgement: | ||
16 | .\" This product includes software developed by the University of | ||
17 | .\" California, Berkeley and its contributors. | ||
18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
19 | .\" may be used to endorse or promote products derived from this software | ||
20 | .\" without specific prior written permission. | ||
21 | .\" | ||
22 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
23 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
24 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
26 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
27 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
28 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
29 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
30 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
32 | .\" SUCH DAMAGE. | ||
33 | .\" | ||
34 | .Dd June 4, 1993 | ||
35 | .Dt ISO_ADDR 3 | ||
36 | .Os | ||
37 | .Sh NAME | ||
38 | .Nm iso_addr , | ||
39 | .Nm iso_ntoa | ||
40 | .Nd "elementary network address conversion routines for Open System Interconnection | ||
41 | .Sh SYNOPSIS | ||
42 | .Fd #include <sys/types.h> | ||
43 | .Fd #include <netiso/iso.h> | ||
44 | .Ft struct iso_addr * | ||
45 | .Fn iso_addr "char *cp" | ||
46 | .Ft char * | ||
47 | .Fn iso_ntoa "struct iso_addr *isoa" | ||
48 | .Sh DESCRIPTION | ||
49 | The routine | ||
50 | .Fn iso_addr | ||
51 | interprets character strings representing | ||
52 | .Tn OSI | ||
53 | addresses, returning binary information suitable | ||
54 | for use in system calls. | ||
55 | The routine | ||
56 | .Fn iso_ntoa | ||
57 | takes | ||
58 | .Tn OSI | ||
59 | addresses and returns | ||
60 | .Tn ASCII | ||
61 | strings representing NSAPs (network service | ||
62 | access points) in a | ||
63 | notation inverse to that accepted by | ||
64 | .Fn iso_addr . | ||
65 | .Pp | ||
66 | Unfortunately, no universal standard exists for representing | ||
67 | .Tn OSI | ||
68 | network addresses. | ||
69 | .Pp | ||
70 | The format employed by | ||
71 | .Fn iso_addr | ||
72 | is a sequence of hexadecimal | ||
73 | .Dq digits | ||
74 | (optionally separated by periods), | ||
75 | of the form: | ||
76 | .Bd -filled -offset indent | ||
77 | <hex digits>.<hex digits>.<hex digits> | ||
78 | .Ed | ||
79 | .Pp | ||
80 | Each pair of hexadecimal digits represents a byte | ||
81 | with the leading digit indicating the higher-ordered bits. | ||
82 | A period following an even number of bytes has no | ||
83 | effect (but may be used to increase legibility). | ||
84 | A period following an odd number of bytes has the | ||
85 | effect of causing the byte of address being translated | ||
86 | to have its higher order bits filled with zeros. | ||
87 | .Sh RETURN VALUES | ||
88 | .Fn iso_ntoa | ||
89 | always returns a null terminated string. | ||
90 | .Fn iso_addr | ||
91 | always returns a pointer to a struct iso_addr. | ||
92 | (See | ||
93 | .Sx BUGS . ) | ||
94 | .Sh SEE ALSO | ||
95 | .Xr iso 4 | ||
96 | .Sh HISTORY | ||
97 | The | ||
98 | .Fn iso_addr | ||
99 | and | ||
100 | .Fn iso_ntoa | ||
101 | functions appeared in | ||
102 | .Bx 4.3 Reno . | ||
103 | .Sh BUGS | ||
104 | The returned values | ||
105 | reside in a static memory area. | ||
106 | .Pp | ||
107 | The function | ||
108 | .Fn iso_addr | ||
109 | should diagnose improperly formed input, and there should be an unambiguous | ||
110 | way to recognize this. | ||
diff --git a/src/lib/libc/net/iso_addr.c b/src/lib/libc/net/iso_addr.c new file mode 100644 index 0000000000..01561e395b --- /dev/null +++ b/src/lib/libc/net/iso_addr.c | |||
@@ -0,0 +1,119 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1989, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: iso_addr.c,v 1.2 1996/08/19 08:29:23 tholo Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | #include <sys/types.h> | ||
39 | #include <netiso/iso.h> | ||
40 | #include <string.h> | ||
41 | |||
42 | /* States*/ | ||
43 | #define VIRGIN 0 | ||
44 | #define GOTONE 1 | ||
45 | #define GOTTWO 2 | ||
46 | /* Inputs */ | ||
47 | #define DIGIT (4*0) | ||
48 | #define END (4*1) | ||
49 | #define DELIM (4*2) | ||
50 | |||
51 | struct iso_addr * | ||
52 | iso_addr(addr) | ||
53 | register const char *addr; | ||
54 | { | ||
55 | static struct iso_addr out_addr; | ||
56 | register char *cp = out_addr.isoa_genaddr; | ||
57 | char *cplim = cp + sizeof(out_addr.isoa_genaddr); | ||
58 | register int byte = 0, state = VIRGIN, new; | ||
59 | |||
60 | bzero((char *)&out_addr, sizeof(out_addr)); | ||
61 | do { | ||
62 | if ((*addr >= '0') && (*addr <= '9')) { | ||
63 | new = *addr - '0'; | ||
64 | } else if ((*addr >= 'a') && (*addr <= 'f')) { | ||
65 | new = *addr - 'a' + 10; | ||
66 | } else if ((*addr >= 'A') && (*addr <= 'F')) { | ||
67 | new = *addr - 'A' + 10; | ||
68 | } else if (*addr == 0) | ||
69 | state |= END; | ||
70 | else | ||
71 | state |= DELIM; | ||
72 | addr++; | ||
73 | switch (state /* | INPUT */) { | ||
74 | case GOTTWO | DIGIT: | ||
75 | *cp++ = byte; /*FALLTHROUGH*/ | ||
76 | case VIRGIN | DIGIT: | ||
77 | state = GOTONE; byte = new; continue; | ||
78 | case GOTONE | DIGIT: | ||
79 | state = GOTTWO; byte = new + (byte << 4); continue; | ||
80 | default: /* | DELIM */ | ||
81 | state = VIRGIN; *cp++ = byte; byte = 0; continue; | ||
82 | case GOTONE | END: | ||
83 | case GOTTWO | END: | ||
84 | *cp++ = byte; /* FALLTHROUGH */ | ||
85 | case VIRGIN | END: | ||
86 | break; | ||
87 | } | ||
88 | break; | ||
89 | } while (cp < cplim); | ||
90 | out_addr.isoa_len = cp - out_addr.isoa_genaddr; | ||
91 | return (&out_addr); | ||
92 | } | ||
93 | static char hexlist[] = "0123456789abcdef"; | ||
94 | |||
95 | char * | ||
96 | iso_ntoa(isoa) | ||
97 | const struct iso_addr *isoa; | ||
98 | { | ||
99 | static char obuf[64]; | ||
100 | register char *out = obuf; | ||
101 | register int i; | ||
102 | register u_char *in = (u_char *)isoa->isoa_genaddr; | ||
103 | u_char *inlim = in + isoa->isoa_len; | ||
104 | |||
105 | out[1] = 0; | ||
106 | while (in < inlim) { | ||
107 | i = *in++; | ||
108 | *out++ = '.'; | ||
109 | if (i > 0xf) { | ||
110 | out[1] = hexlist[i & 0xf]; | ||
111 | i >>= 4; | ||
112 | out[0] = hexlist[i]; | ||
113 | out += 2; | ||
114 | } else | ||
115 | *out++ = hexlist[i]; | ||
116 | } | ||
117 | *out = 0; | ||
118 | return(obuf + 1); | ||
119 | } | ||
diff --git a/src/lib/libc/net/link_addr.3 b/src/lib/libc/net/link_addr.3 new file mode 100644 index 0000000000..eb6c952177 --- /dev/null +++ b/src/lib/libc/net/link_addr.3 | |||
@@ -0,0 +1,131 @@ | |||
1 | .\" $OpenBSD: link_addr.3,v 1.2 1996/08/19 08:29:25 tholo Exp $ | ||
2 | .\" | ||
3 | .\" Copyright (c) 1993 | ||
4 | .\" The Regents of the University of California. All rights reserved. | ||
5 | .\" | ||
6 | .\" This code is derived from software contributed to Berkeley by | ||
7 | .\" Donn Seeley at BSDI. | ||
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 | .Dd July 28, 1993 | ||
38 | .Dt LINK_ADDR 3 | ||
39 | .Os BSD 4.4 | ||
40 | .Sh NAME | ||
41 | .Nm link_addr , | ||
42 | .Nm link_ntoa | ||
43 | .Nd elementary address specification routines for link level access | ||
44 | .Sh SYNOPSIS | ||
45 | .Fd #include <sys/types.h> | ||
46 | .Fd #include <sys/socket.h> | ||
47 | .Fd #include <net/if_dl.h> | ||
48 | .Ft void | ||
49 | .Fn link_addr "const char *addr" "struct sockaddr_dl *sdl" | ||
50 | .Ft char * | ||
51 | .Fn link_ntoa "const struct sockaddr_dl *sdl" | ||
52 | .Sh DESCRIPTION | ||
53 | The routine | ||
54 | .Fn link_addr | ||
55 | interprets character strings representing | ||
56 | link-level addresses, returning binary information suitable | ||
57 | for use in system calls. | ||
58 | The routine | ||
59 | .Fn link_ntoa | ||
60 | takes | ||
61 | a link-level | ||
62 | address and returns an | ||
63 | .Tn ASCII | ||
64 | string representing some of the information present, | ||
65 | including the link level address itself, and the interface name | ||
66 | or number, if present. | ||
67 | This facility is experimental and is | ||
68 | still subject to change. | ||
69 | .Pp | ||
70 | For | ||
71 | .Fn link_addr , | ||
72 | the string | ||
73 | .Fa addr | ||
74 | may contain | ||
75 | an optional network interface identifier of the form | ||
76 | .Dq "name unit-number" , | ||
77 | suitable for the first argument to | ||
78 | .Xr ifconfig 4 , | ||
79 | followed in all cases by a colon and | ||
80 | an interface address in the form of | ||
81 | groups of hexadecimal digits | ||
82 | separated by periods. | ||
83 | Each group represents a byte of address; | ||
84 | address bytes are filled left to right from | ||
85 | low order bytes through high order bytes. | ||
86 | .Pp | ||
87 | .\" A regular expression may make this format clearer: | ||
88 | .\" .Bd -literal -offset indent | ||
89 | .\" ([a-z]+[0-9]+:)?[0-9a-f]+(\e.[0-9a-f]+)* | ||
90 | .\" .Ed | ||
91 | .\" .Pp | ||
92 | Thus | ||
93 | .Li le0:8.0.9.13.d.30 | ||
94 | represents an ethernet address | ||
95 | to be transmitted on the first Lance ethernet interface. | ||
96 | .Sh RETURN VALUES | ||
97 | .Fn link_ntoa | ||
98 | always returns a null terminated string. | ||
99 | .Fn link_addr | ||
100 | has no return value. | ||
101 | (See | ||
102 | .Sx BUGS . ) | ||
103 | .Sh SEE ALSO | ||
104 | .Xr iso 4 , | ||
105 | .Sh HISTORY | ||
106 | The | ||
107 | .Fn link_addr | ||
108 | and | ||
109 | .Fn link_ntoa | ||
110 | functions appeared in | ||
111 | .Bx 4.3 Reno . | ||
112 | .Sh BUGS | ||
113 | The returned values for link_ntoa | ||
114 | reside in a static memory area. | ||
115 | .Pp | ||
116 | The function | ||
117 | .Fn link_addr | ||
118 | should diagnose improperly formed input, and there should be an unambiguous | ||
119 | way to recognize this. | ||
120 | .Pp | ||
121 | If the | ||
122 | .Va sdl_len | ||
123 | field of the link socket address | ||
124 | .Fa sdl | ||
125 | is 0, | ||
126 | .Fn link_ntoa | ||
127 | will not insert a colon before the interface address bytes. | ||
128 | If this translated address is given to | ||
129 | .Fn link_addr | ||
130 | without inserting an initial colon, | ||
131 | the latter will not interpret it correctly. | ||
diff --git a/src/lib/libc/net/linkaddr.c b/src/lib/libc/net/linkaddr.c new file mode 100644 index 0000000000..fb522f3233 --- /dev/null +++ b/src/lib/libc/net/linkaddr.c | |||
@@ -0,0 +1,158 @@ | |||
1 | /*- | ||
2 | * Copyright (c) 1990, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: linkaddr.c,v 1.2 1996/08/19 08:29:27 tholo Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | #include <sys/types.h> | ||
39 | #include <sys/socket.h> | ||
40 | #include <net/if_dl.h> | ||
41 | #include <string.h> | ||
42 | |||
43 | /* States*/ | ||
44 | #define NAMING 0 | ||
45 | #define GOTONE 1 | ||
46 | #define GOTTWO 2 | ||
47 | #define RESET 3 | ||
48 | /* Inputs */ | ||
49 | #define DIGIT (4*0) | ||
50 | #define END (4*1) | ||
51 | #define DELIM (4*2) | ||
52 | #define LETTER (4*3) | ||
53 | |||
54 | void | ||
55 | link_addr(addr, sdl) | ||
56 | register const char *addr; | ||
57 | register struct sockaddr_dl *sdl; | ||
58 | { | ||
59 | register char *cp = sdl->sdl_data; | ||
60 | char *cplim = sdl->sdl_len + (char *)sdl; | ||
61 | register int byte = 0, state = NAMING, new; | ||
62 | |||
63 | bzero((char *)&sdl->sdl_family, sdl->sdl_len - 1); | ||
64 | sdl->sdl_family = AF_LINK; | ||
65 | do { | ||
66 | state &= ~LETTER; | ||
67 | if ((*addr >= '0') && (*addr <= '9')) { | ||
68 | new = *addr - '0'; | ||
69 | } else if ((*addr >= 'a') && (*addr <= 'f')) { | ||
70 | new = *addr - 'a' + 10; | ||
71 | } else if ((*addr >= 'A') && (*addr <= 'F')) { | ||
72 | new = *addr - 'A' + 10; | ||
73 | } else if (*addr == 0) { | ||
74 | state |= END; | ||
75 | } else if (state == NAMING && | ||
76 | (((*addr >= 'A') && (*addr <= 'Z')) || | ||
77 | ((*addr >= 'a') && (*addr <= 'z')))) | ||
78 | state |= LETTER; | ||
79 | else | ||
80 | state |= DELIM; | ||
81 | addr++; | ||
82 | switch (state /* | INPUT */) { | ||
83 | case NAMING | DIGIT: | ||
84 | case NAMING | LETTER: | ||
85 | *cp++ = addr[-1]; | ||
86 | continue; | ||
87 | case NAMING | DELIM: | ||
88 | state = RESET; | ||
89 | sdl->sdl_nlen = cp - sdl->sdl_data; | ||
90 | continue; | ||
91 | case GOTTWO | DIGIT: | ||
92 | *cp++ = byte; | ||
93 | /* FALLTHROUGH */ | ||
94 | case RESET | DIGIT: | ||
95 | state = GOTONE; | ||
96 | byte = new; | ||
97 | continue; | ||
98 | case GOTONE | DIGIT: | ||
99 | state = GOTTWO; | ||
100 | byte = new + (byte << 4); | ||
101 | continue; | ||
102 | default: /* | DELIM */ | ||
103 | state = RESET; | ||
104 | *cp++ = byte; | ||
105 | byte = 0; | ||
106 | continue; | ||
107 | case GOTONE | END: | ||
108 | case GOTTWO | END: | ||
109 | *cp++ = byte; | ||
110 | /* FALLTHROUGH */ | ||
111 | case RESET | END: | ||
112 | break; | ||
113 | } | ||
114 | break; | ||
115 | } while (cp < cplim); | ||
116 | sdl->sdl_alen = cp - LLADDR(sdl); | ||
117 | new = cp - (char *)sdl; | ||
118 | if (new > sizeof(*sdl)) | ||
119 | sdl->sdl_len = new; | ||
120 | return; | ||
121 | } | ||
122 | |||
123 | static char hexlist[] = "0123456789abcdef"; | ||
124 | |||
125 | char * | ||
126 | link_ntoa(sdl) | ||
127 | register const struct sockaddr_dl *sdl; | ||
128 | { | ||
129 | static char obuf[64]; | ||
130 | register char *out = obuf; | ||
131 | register int i; | ||
132 | register u_char *in = (u_char *)LLADDR(sdl); | ||
133 | u_char *inlim = in + sdl->sdl_alen; | ||
134 | int firsttime = 1; | ||
135 | |||
136 | if (sdl->sdl_nlen) { | ||
137 | bcopy(sdl->sdl_data, obuf, sdl->sdl_nlen); | ||
138 | out += sdl->sdl_nlen; | ||
139 | if (sdl->sdl_alen) | ||
140 | *out++ = ':'; | ||
141 | } | ||
142 | while (in < inlim) { | ||
143 | if (firsttime) | ||
144 | firsttime = 0; | ||
145 | else | ||
146 | *out++ = '.'; | ||
147 | i = *in++; | ||
148 | if (i > 0xf) { | ||
149 | out[1] = hexlist[i & 0xf]; | ||
150 | i >>= 4; | ||
151 | out[0] = hexlist[i]; | ||
152 | out += 2; | ||
153 | } else | ||
154 | *out++ = hexlist[i]; | ||
155 | } | ||
156 | *out = 0; | ||
157 | return (obuf); | ||
158 | } | ||
diff --git a/src/lib/libc/net/ns.3 b/src/lib/libc/net/ns.3 new file mode 100644 index 0000000000..6e096d9f4b --- /dev/null +++ b/src/lib/libc/net/ns.3 | |||
@@ -0,0 +1,130 @@ | |||
1 | .\" $OpenBSD: ns.3,v 1.2 1996/08/19 08:29:29 tholo Exp $ | ||
2 | .\" | ||
3 | .\" Copyright (c) 1986, 1991, 1993 | ||
4 | .\" The Regents of the University of California. All rights reserved. | ||
5 | .\" | ||
6 | .\" Redistribution and use in source and binary forms, with or without | ||
7 | .\" modification, are permitted provided that the following conditions | ||
8 | .\" are met: | ||
9 | .\" 1. Redistributions of source code must retain the above copyright | ||
10 | .\" notice, this list of conditions and the following disclaimer. | ||
11 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
12 | .\" notice, this list of conditions and the following disclaimer in the | ||
13 | .\" documentation and/or other materials provided with the distribution. | ||
14 | .\" 3. All advertising materials mentioning features or use of this software | ||
15 | .\" must display the following acknowledgement: | ||
16 | .\" This product includes software developed by the University of | ||
17 | .\" California, Berkeley and its contributors. | ||
18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
19 | .\" may be used to endorse or promote products derived from this software | ||
20 | .\" without specific prior written permission. | ||
21 | .\" | ||
22 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
23 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
24 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
26 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
27 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
28 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
29 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
30 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
32 | .\" SUCH DAMAGE. | ||
33 | .\" | ||
34 | .Dd June 4, 1993 | ||
35 | .Dt NS 3 | ||
36 | .Os BSD 4.3 | ||
37 | .Sh NAME | ||
38 | .Nm ns_addr , | ||
39 | .Nm ns_ntoa | ||
40 | .Nd Xerox | ||
41 | .Tn NS Ns (tm) | ||
42 | address conversion routines | ||
43 | .Sh SYNOPSIS | ||
44 | .Fd #include <sys/types.h> | ||
45 | .Fd #include <netns/ns.h> | ||
46 | .Ft struct ns_addr | ||
47 | .Fn ns_addr "char *cp" | ||
48 | .Ft char * | ||
49 | .Fn ns_ntoa "struct ns_addr ns" | ||
50 | .Sh DESCRIPTION | ||
51 | The routine | ||
52 | .Fn ns_addr | ||
53 | interprets character strings representing | ||
54 | .Tn XNS | ||
55 | addresses, returning binary information suitable | ||
56 | for use in system calls. | ||
57 | The routine | ||
58 | .Fn ns_ntoa | ||
59 | takes | ||
60 | .Tn XNS | ||
61 | addresses and returns | ||
62 | .Tn ASCII | ||
63 | strings representing the address in a | ||
64 | notation in common use in the Xerox Development Environment: | ||
65 | .Bd -filled -offset indent | ||
66 | <network number>.<host number>.<port number> | ||
67 | .Ed | ||
68 | .Pp | ||
69 | Trailing zero fields are suppressed, and each number is printed in hexadecimal, | ||
70 | in a format suitable for input to | ||
71 | .Fn ns_addr . | ||
72 | Any fields lacking super-decimal digits will have a | ||
73 | trailing | ||
74 | .Ql H | ||
75 | appended. | ||
76 | .Pp | ||
77 | Unfortunately, no universal standard exists for representing | ||
78 | .Tn XNS | ||
79 | addresses. | ||
80 | An effort has been made to insure that | ||
81 | .Fn ns_addr | ||
82 | be compatible with most formats in common use. | ||
83 | It will first separate an address into 1 to 3 fields using a single delimiter | ||
84 | chosen from | ||
85 | period | ||
86 | .Ql \&. , | ||
87 | colon | ||
88 | .Ql \&: | ||
89 | or pound-sign | ||
90 | .Ql \&# . | ||
91 | Each field is then examined for byte separators (colon or period). | ||
92 | If there are byte separators, each subfield separated is taken to be | ||
93 | a small hexadecimal number, and the entirety is taken as a network-byte-ordered | ||
94 | quantity to be zero extended in the high-network-order bytes. | ||
95 | Next, the field is inspected for hyphens, in which case | ||
96 | the field is assumed to be a number in decimal notation | ||
97 | with hyphens separating the millenia. | ||
98 | Next, the field is assumed to be a number: | ||
99 | It is interpreted | ||
100 | as hexadecimal if there is a leading | ||
101 | .Ql 0x | ||
102 | (as in C), | ||
103 | a trailing | ||
104 | .Ql H | ||
105 | (as in Mesa), or there are any super-decimal digits present. | ||
106 | It is interpreted as octal is there is a leading | ||
107 | .Ql 0 | ||
108 | and there are no super-octal digits. | ||
109 | Otherwise, it is converted as a decimal number. | ||
110 | .Sh RETURN VALUES | ||
111 | None. (See | ||
112 | .Sx BUGS . ) | ||
113 | .Sh SEE ALSO | ||
114 | .Xr hosts 5 , | ||
115 | .Xr networks 5 , | ||
116 | .Sh HISTORY | ||
117 | The | ||
118 | .Fn ns_addr | ||
119 | and | ||
120 | .Fn ns_toa | ||
121 | functions appeared in | ||
122 | .Bx 4.3 . | ||
123 | .Sh BUGS | ||
124 | The string returned by | ||
125 | .Fn ns_ntoa | ||
126 | resides in a static memory area. | ||
127 | The function | ||
128 | .Fn ns_addr | ||
129 | should diagnose improperly formed input, and there should be an unambiguous | ||
130 | way to recognize this. | ||
diff --git a/src/lib/libc/net/ns_addr.c b/src/lib/libc/net/ns_addr.c new file mode 100644 index 0000000000..8f2e4bc513 --- /dev/null +++ b/src/lib/libc/net/ns_addr.c | |||
@@ -0,0 +1,228 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1986, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * This code is derived from software contributed to Berkeley by | ||
6 | * J.Q. Johnson. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer. | ||
13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer in the | ||
15 | * documentation and/or other materials provided with the distribution. | ||
16 | * 3. All advertising materials mentioning features or use of this software | ||
17 | * must display the following acknowledgement: | ||
18 | * This product includes software developed by the University of | ||
19 | * California, Berkeley and its contributors. | ||
20 | * 4. Neither the name of the University nor the names of its contributors | ||
21 | * may be used to endorse or promote products derived from this software | ||
22 | * without specific prior written permission. | ||
23 | * | ||
24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
34 | * SUCH DAMAGE. | ||
35 | */ | ||
36 | |||
37 | #if defined(LIBC_SCCS) && !defined(lint) | ||
38 | static char rcsid[] = "$OpenBSD: ns_addr.c,v 1.4 1997/07/21 20:31:05 deraadt Exp $"; | ||
39 | #endif /* LIBC_SCCS and not lint */ | ||
40 | |||
41 | #include <sys/param.h> | ||
42 | #include <netns/ns.h> | ||
43 | #include <stdio.h> | ||
44 | #include <string.h> | ||
45 | |||
46 | static struct ns_addr addr, zero_addr; | ||
47 | |||
48 | static void Field __P((char *, u_int8_t *, int)); | ||
49 | static void cvtbase __P((long, int, int[], int, u_int8_t[], int)); | ||
50 | |||
51 | struct ns_addr | ||
52 | ns_addr(name) | ||
53 | const char *name; | ||
54 | { | ||
55 | char separator; | ||
56 | char *hostname, *socketname, *cp; | ||
57 | char buf[50]; | ||
58 | |||
59 | (void)strncpy(buf, name, sizeof(buf) - 1); | ||
60 | buf[sizeof(buf) - 1] = '\0'; | ||
61 | |||
62 | /* | ||
63 | * First, figure out what he intends as a field separtor. | ||
64 | * Despite the way this routine is written, the prefered | ||
65 | * form 2-272.AA001234H.01777, i.e. XDE standard. | ||
66 | * Great efforts are made to insure backward compatability. | ||
67 | */ | ||
68 | if ((hostname = strchr(buf, '#'))) | ||
69 | separator = '#'; | ||
70 | else { | ||
71 | hostname = strchr(buf, '.'); | ||
72 | if ((cp = strchr(buf, ':')) && | ||
73 | ((hostname && cp < hostname) || (hostname == 0))) { | ||
74 | hostname = cp; | ||
75 | separator = ':'; | ||
76 | } else | ||
77 | separator = '.'; | ||
78 | } | ||
79 | if (hostname) | ||
80 | *hostname++ = 0; | ||
81 | |||
82 | addr = zero_addr; | ||
83 | Field(buf, addr.x_net.c_net, 4); | ||
84 | if (hostname == 0) | ||
85 | return (addr); /* No separator means net only */ | ||
86 | |||
87 | socketname = strchr(hostname, separator); | ||
88 | if (socketname) { | ||
89 | *socketname++ = 0; | ||
90 | Field(socketname, (u_char *)&addr.x_port, 2); | ||
91 | } | ||
92 | |||
93 | Field(hostname, (u_char *)addr.x_host.c_host, 6); | ||
94 | |||
95 | return (addr); | ||
96 | } | ||
97 | |||
98 | static void | ||
99 | Field(buf, out, len) | ||
100 | char *buf; | ||
101 | u_char *out; | ||
102 | int len; | ||
103 | { | ||
104 | register char *bp = buf; | ||
105 | int i, ibase, base16 = 0, base10 = 0, clen = 0; | ||
106 | int hb[6], *hp; | ||
107 | char *fmt; | ||
108 | |||
109 | /* | ||
110 | * first try 2-273#2-852-151-014#socket | ||
111 | */ | ||
112 | if ((*buf != '-') && | ||
113 | (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d", | ||
114 | &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) { | ||
115 | cvtbase(1000L, 256, hb, i, out, len); | ||
116 | return; | ||
117 | } | ||
118 | /* | ||
119 | * try form 8E1#0.0.AA.0.5E.E6#socket | ||
120 | */ | ||
121 | if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x", | ||
122 | &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) { | ||
123 | cvtbase(256L, 256, hb, i, out, len); | ||
124 | return; | ||
125 | } | ||
126 | /* | ||
127 | * try form 8E1#0:0:AA:0:5E:E6#socket | ||
128 | */ | ||
129 | if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x", | ||
130 | &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) { | ||
131 | cvtbase(256L, 256, hb, i, out, len); | ||
132 | return; | ||
133 | } | ||
134 | /* | ||
135 | * This is REALLY stretching it but there was a | ||
136 | * comma notation separting shorts -- definitely non standard | ||
137 | */ | ||
138 | if (1 < (i = sscanf(buf,"%x,%x,%x", | ||
139 | &hb[0], &hb[1], &hb[2]))) { | ||
140 | hb[0] = htons(hb[0]); hb[1] = htons(hb[1]); | ||
141 | hb[2] = htons(hb[2]); | ||
142 | cvtbase(65536L, 256, hb, i, out, len); | ||
143 | return; | ||
144 | } | ||
145 | |||
146 | /* Need to decide if base 10, 16 or 8 */ | ||
147 | while (*bp) switch (*bp++) { | ||
148 | |||
149 | case '0': case '1': case '2': case '3': case '4': case '5': | ||
150 | case '6': case '7': case '-': | ||
151 | break; | ||
152 | |||
153 | case '8': case '9': | ||
154 | base10 = 1; | ||
155 | break; | ||
156 | |||
157 | case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': | ||
158 | case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': | ||
159 | base16 = 1; | ||
160 | break; | ||
161 | |||
162 | case 'x': case 'X': | ||
163 | *--bp = '0'; | ||
164 | base16 = 1; | ||
165 | break; | ||
166 | |||
167 | case 'h': case 'H': | ||
168 | base16 = 1; | ||
169 | /* fall into */ | ||
170 | |||
171 | default: | ||
172 | *--bp = 0; /* Ends Loop */ | ||
173 | } | ||
174 | if (base16) { | ||
175 | fmt = "%3x"; | ||
176 | ibase = 4096; | ||
177 | } else if (base10 == 0 && *buf == '0') { | ||
178 | fmt = "%3o"; | ||
179 | ibase = 512; | ||
180 | } else { | ||
181 | fmt = "%3d"; | ||
182 | ibase = 1000; | ||
183 | } | ||
184 | |||
185 | for (bp = buf; *bp++; ) clen++; | ||
186 | if (clen == 0) clen++; | ||
187 | if (clen > 18) clen = 18; | ||
188 | i = ((clen - 1) / 3) + 1; | ||
189 | bp = clen + buf - 3; | ||
190 | hp = hb + i - 1; | ||
191 | |||
192 | while (hp > hb) { | ||
193 | (void)sscanf(bp, fmt, hp); | ||
194 | bp[0] = 0; | ||
195 | hp--; | ||
196 | bp -= 3; | ||
197 | } | ||
198 | (void)sscanf(buf, fmt, hp); | ||
199 | cvtbase((long)ibase, 256, hb, i, out, len); | ||
200 | } | ||
201 | |||
202 | static void | ||
203 | cvtbase(oldbase,newbase,input,inlen,result,reslen) | ||
204 | long oldbase; | ||
205 | int newbase; | ||
206 | int input[]; | ||
207 | int inlen; | ||
208 | unsigned char result[]; | ||
209 | int reslen; | ||
210 | { | ||
211 | int d, e; | ||
212 | long sum; | ||
213 | |||
214 | e = 1; | ||
215 | while (e > 0 && reslen > 0) { | ||
216 | d = 0; e = 0; sum = 0; | ||
217 | /* long division: input=input/newbase */ | ||
218 | while (d < inlen) { | ||
219 | sum = sum*oldbase + (long) input[d]; | ||
220 | e += (sum > 0); | ||
221 | input[d++] = sum / newbase; | ||
222 | sum %= newbase; | ||
223 | } | ||
224 | result[--reslen] = sum; /* accumulate remainder */ | ||
225 | } | ||
226 | for (d=0; d < reslen; d++) | ||
227 | result[d] = 0; | ||
228 | } | ||
diff --git a/src/lib/libc/net/ns_ntoa.c b/src/lib/libc/net/ns_ntoa.c new file mode 100644 index 0000000000..c33f710966 --- /dev/null +++ b/src/lib/libc/net/ns_ntoa.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1986, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: ns_ntoa.c,v 1.7 1997/08/24 21:25:48 millert Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | #include <sys/param.h> | ||
39 | #include <netns/ns.h> | ||
40 | #include <stdio.h> | ||
41 | |||
42 | static char *spectHex __P((char *)); | ||
43 | |||
44 | char * | ||
45 | ns_ntoa(addr) | ||
46 | struct ns_addr addr; | ||
47 | { | ||
48 | static char obuf[40]; | ||
49 | union { union ns_net net_e; u_int32_t long_e; } net; | ||
50 | in_port_t port = htons(addr.x_port); | ||
51 | register char *cp; | ||
52 | char *cp2; | ||
53 | register u_char *up = addr.x_host.c_host; | ||
54 | u_char *uplim = up + 6; | ||
55 | |||
56 | net.net_e = addr.x_net; | ||
57 | sprintf(obuf, "%x", ntohl(net.long_e)); | ||
58 | cp = spectHex(obuf); | ||
59 | cp2 = cp + 1; | ||
60 | while (*up==0 && up < uplim) up++; | ||
61 | if (up == uplim) { | ||
62 | if (port) { | ||
63 | sprintf(cp, ".0"); | ||
64 | cp += 2; | ||
65 | } | ||
66 | } else { | ||
67 | sprintf(cp, ".%x", *up++); | ||
68 | while (up < uplim) { | ||
69 | while (*cp) cp++; | ||
70 | sprintf(cp, "%02x", *up++); | ||
71 | } | ||
72 | cp = spectHex(cp2); | ||
73 | } | ||
74 | if (port) { | ||
75 | sprintf(cp, ".%x", port); | ||
76 | spectHex(cp + 1); | ||
77 | } | ||
78 | return (obuf); | ||
79 | } | ||
80 | |||
81 | static char * | ||
82 | spectHex(p0) | ||
83 | char *p0; | ||
84 | { | ||
85 | int ok = 0; | ||
86 | int nonzero = 0; | ||
87 | register char *p = p0; | ||
88 | for (; *p; p++) switch (*p) { | ||
89 | |||
90 | case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': | ||
91 | *p += ('A' - 'a'); | ||
92 | /* fall into . . . */ | ||
93 | case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': | ||
94 | ok = 1; | ||
95 | case '1': case '2': case '3': case '4': case '5': | ||
96 | case '6': case '7': case '8': case '9': | ||
97 | nonzero = 1; | ||
98 | } | ||
99 | if (nonzero && !ok) { *p++ = 'H'; *p = 0; } | ||
100 | return (p); | ||
101 | } | ||
diff --git a/src/lib/libc/net/nsap_addr.c b/src/lib/libc/net/nsap_addr.c new file mode 100644 index 0000000000..22a5f8d66e --- /dev/null +++ b/src/lib/libc/net/nsap_addr.c | |||
@@ -0,0 +1,109 @@ | |||
1 | /* $OpenBSD: nsap_addr.c,v 1.4 1997/07/09 01:08:45 millert 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 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.4 1997/07/09 01:08:45 millert Exp $"; | ||
25 | #endif | ||
26 | #endif /* LIBC_SCCS and not lint */ | ||
27 | |||
28 | #include <sys/types.h> | ||
29 | #include <sys/param.h> | ||
30 | #include <sys/socket.h> | ||
31 | #include <netinet/in.h> | ||
32 | #include <arpa/nameser.h> | ||
33 | #include <ctype.h> | ||
34 | #include <resolv.h> | ||
35 | |||
36 | static char | ||
37 | xtob(c) | ||
38 | register int c; | ||
39 | { | ||
40 | return (c - (((c >= '0') && (c <= '9')) ? '0' : '7')); | ||
41 | } | ||
42 | |||
43 | u_int | ||
44 | inet_nsap_addr(ascii, binary, maxlen) | ||
45 | const char *ascii; | ||
46 | u_char *binary; | ||
47 | int maxlen; | ||
48 | { | ||
49 | register u_char c, nib; | ||
50 | u_int len = 0; | ||
51 | |||
52 | while ((c = *ascii++) != '\0' && len < maxlen) { | ||
53 | if (c == '.' || c == '+' || c == '/') | ||
54 | continue; | ||
55 | if (!isascii(c)) | ||
56 | return (0); | ||
57 | if (islower(c)) | ||
58 | c = toupper(c); | ||
59 | if (isxdigit(c)) { | ||
60 | nib = xtob(c); | ||
61 | if ((c = *ascii++)) { | ||
62 | c = toupper(c); | ||
63 | if (isxdigit(c)) { | ||
64 | *binary++ = (nib << 4) | xtob(c); | ||
65 | len++; | ||
66 | } else | ||
67 | return (0); | ||
68 | } | ||
69 | else | ||
70 | return (0); | ||
71 | } | ||
72 | else | ||
73 | return (0); | ||
74 | } | ||
75 | return (len); | ||
76 | } | ||
77 | |||
78 | char * | ||
79 | inet_nsap_ntoa(binlen, binary, ascii) | ||
80 | int binlen; | ||
81 | register const u_char *binary; | ||
82 | register char *ascii; | ||
83 | { | ||
84 | register int nib; | ||
85 | int i; | ||
86 | static char tmpbuf[255*3]; | ||
87 | char *start; | ||
88 | |||
89 | if (ascii) | ||
90 | start = ascii; | ||
91 | else { | ||
92 | ascii = tmpbuf; | ||
93 | start = tmpbuf; | ||
94 | } | ||
95 | |||
96 | if (binlen > 255) | ||
97 | binlen = 255; | ||
98 | |||
99 | for (i = 0; i < binlen; i++) { | ||
100 | nib = *binary >> 4; | ||
101 | *ascii++ = nib + (nib < 10 ? '0' : '7'); | ||
102 | nib = *binary++ & 0x0f; | ||
103 | *ascii++ = nib + (nib < 10 ? '0' : '7'); | ||
104 | if (((i % 2) == 0 && (i + 1) < binlen)) | ||
105 | *ascii++ = '.'; | ||
106 | } | ||
107 | *ascii = '\0'; | ||
108 | return (start); | ||
109 | } | ||
diff --git a/src/lib/libc/net/ntohl.c b/src/lib/libc/net/ntohl.c new file mode 100644 index 0000000000..7d3e227e60 --- /dev/null +++ b/src/lib/libc/net/ntohl.c | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * Written by J.T. Conklin <jtc@netbsd.org>. | ||
3 | * Public domain. | ||
4 | */ | ||
5 | |||
6 | #if defined(LIBC_SCCS) && !defined(lint) | ||
7 | static char *rcsid = "$OpenBSD: ntohl.c,v 1.4 1996/12/12 03:19:56 tholo Exp $"; | ||
8 | #endif /* LIBC_SCCS and not lint */ | ||
9 | |||
10 | #include <sys/types.h> | ||
11 | #include <machine/endian.h> | ||
12 | |||
13 | #undef ntohl | ||
14 | |||
15 | u_int32_t | ||
16 | ntohl(x) | ||
17 | u_int32_t x; | ||
18 | { | ||
19 | #if BYTE_ORDER == LITTLE_ENDIAN | ||
20 | u_char *s = (u_char *)&x; | ||
21 | return (u_int32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]); | ||
22 | #else | ||
23 | return x; | ||
24 | #endif | ||
25 | } | ||
diff --git a/src/lib/libc/net/ntohs.c b/src/lib/libc/net/ntohs.c new file mode 100644 index 0000000000..cf6414d4a6 --- /dev/null +++ b/src/lib/libc/net/ntohs.c | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * Written by J.T. Conklin <jtc@netbsd.org>. | ||
3 | * Public domain. | ||
4 | */ | ||
5 | |||
6 | #if defined(LIBC_SCCS) && !defined(lint) | ||
7 | static char *rcsid = "$OpenBSD: ntohs.c,v 1.6 1997/07/25 20:30:07 mickey Exp $"; | ||
8 | #endif /* LIBC_SCCS and not lint */ | ||
9 | |||
10 | #include <sys/types.h> | ||
11 | #include <machine/endian.h> | ||
12 | |||
13 | #undef ntohs | ||
14 | |||
15 | u_int16_t | ||
16 | #ifdef __STDC__ | ||
17 | ntohs(u_int16_t x) | ||
18 | #else | ||
19 | ntohs(x) | ||
20 | u_int16_t x; | ||
21 | #endif | ||
22 | { | ||
23 | #if BYTE_ORDER == LITTLE_ENDIAN | ||
24 | u_char *s = (u_char *) &x; | ||
25 | return (u_int16_t)(s[0] << 8 | s[1]); | ||
26 | #else | ||
27 | return x; | ||
28 | #endif | ||
29 | } | ||
diff --git a/src/lib/libc/net/rcmd.3 b/src/lib/libc/net/rcmd.3 new file mode 100644 index 0000000000..e69e822834 --- /dev/null +++ b/src/lib/libc/net/rcmd.3 | |||
@@ -0,0 +1,227 @@ | |||
1 | .\" $OpenBSD: rcmd.3,v 1.10 1997/09/29 18:25:47 deraadt Exp $ | ||
2 | .\" | ||
3 | .\" Copyright (c) 1983, 1991, 1993 | ||
4 | .\" The Regents of the University of California. All rights reserved. | ||
5 | .\" | ||
6 | .\" Redistribution and use in source and binary forms, with or without | ||
7 | .\" modification, are permitted provided that the following conditions | ||
8 | .\" are met: | ||
9 | .\" 1. Redistributions of source code must retain the above copyright | ||
10 | .\" notice, this list of conditions and the following disclaimer. | ||
11 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
12 | .\" notice, this list of conditions and the following disclaimer in the | ||
13 | .\" documentation and/or other materials provided with the distribution. | ||
14 | .\" 3. All advertising materials mentioning features or use of this software | ||
15 | .\" must display the following acknowledgement: | ||
16 | .\" This product includes software developed by the University of | ||
17 | .\" California, Berkeley and its contributors. | ||
18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
19 | .\" may be used to endorse or promote products derived from this software | ||
20 | .\" without specific prior written permission. | ||
21 | .\" | ||
22 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
23 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
24 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
26 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
27 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
28 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
29 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
30 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
32 | .\" SUCH DAMAGE. | ||
33 | .\" | ||
34 | .Dd June 4, 1993 | ||
35 | .Dt RCMD 3 | ||
36 | .Os BSD 4.2 | ||
37 | .Sh NAME | ||
38 | .Nm rcmd , | ||
39 | .Nm rresvport , | ||
40 | .Nm iruserok , | ||
41 | .Nm ruserok | ||
42 | .Nd routines for returning a stream to a remote command | ||
43 | .Sh SYNOPSIS | ||
44 | .Fd #include <unistd.h> | ||
45 | .Ft int | ||
46 | .Fn rcmd "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p" | ||
47 | .Ft int | ||
48 | .Fn rresvport "int *port" | ||
49 | .Ft int | ||
50 | .Fn iruserok "u_int32_t raddr" "int superuser" "const char *ruser" "const char *luser" | ||
51 | .Ft int | ||
52 | .Fn ruserok "const char *rhost" "int superuser" "const char *ruser" "const char *luser" | ||
53 | .Sh DESCRIPTION | ||
54 | The | ||
55 | .Fn rcmd | ||
56 | function | ||
57 | is used by the super-user to execute a command on a remote | ||
58 | machine using an authentication scheme based on reserved | ||
59 | port numbers. If the calling process is not setuid and the | ||
60 | .Li RSH | ||
61 | environment variable is set and | ||
62 | .Fa inport | ||
63 | is | ||
64 | .Li shell/tcp , | ||
65 | .Xr rcmdsh 3 | ||
66 | is called instead with the value of | ||
67 | .Li RSH . | ||
68 | Alternately, if the user is not the super-user, | ||
69 | .Fn rcmd | ||
70 | will invoke | ||
71 | .Xr rcmdsh 3 | ||
72 | to run the command via | ||
73 | .Xr rsh 1 . | ||
74 | The | ||
75 | .Fn rresvport | ||
76 | function | ||
77 | returns a descriptor to a socket | ||
78 | with an address in the privileged port space. | ||
79 | The | ||
80 | .Fn iruserok | ||
81 | and | ||
82 | .Fn ruserok | ||
83 | functions are used by servers | ||
84 | to authenticate clients requesting service with | ||
85 | .Fn rcmd . | ||
86 | All four functions are present in the same file and are used | ||
87 | by the | ||
88 | .Xr rshd 8 | ||
89 | server (among others). | ||
90 | .Pp | ||
91 | The | ||
92 | .Fn rcmd | ||
93 | function | ||
94 | looks up the host | ||
95 | .Fa *ahost | ||
96 | using | ||
97 | .Xr gethostbyname 3 , | ||
98 | returning \-1 if the host does not exist. | ||
99 | Otherwise | ||
100 | .Fa *ahost | ||
101 | is set to the standard name of the host | ||
102 | and a connection is established to a server | ||
103 | residing at the well-known Internet port | ||
104 | .Fa inport . | ||
105 | If the user is not the super-user, the only valid port is | ||
106 | .Li shell/tcp , | ||
107 | (usually port 514). | ||
108 | .Pp | ||
109 | If the connection succeeds, | ||
110 | a socket in the Internet domain of type | ||
111 | .Dv SOCK_STREAM | ||
112 | is returned to the caller, and given to the remote | ||
113 | command as | ||
114 | .Em stdin | ||
115 | and | ||
116 | .Em stdout . | ||
117 | If | ||
118 | .Fa fd2p | ||
119 | is non-zero, then an auxiliary channel to a control | ||
120 | process will be set up, and a descriptor for it will be placed | ||
121 | in | ||
122 | .Fa *fd2p . | ||
123 | The control process will return diagnostic | ||
124 | output from the command (unit 2) on this channel, and will also | ||
125 | accept bytes on this channel as being | ||
126 | .Tn UNIX | ||
127 | signal numbers, to be | ||
128 | forwarded to the process group of the command. | ||
129 | If | ||
130 | .Fa fd2p | ||
131 | is 0, then the | ||
132 | .Em stderr | ||
133 | (unit 2 of the remote | ||
134 | command) will be made the same as the | ||
135 | .Em stdout | ||
136 | and no | ||
137 | provision is made for sending arbitrary signals to the remote process, | ||
138 | although you may be able to get its attention by using out-of-band data. | ||
139 | Note that if the user is not the super-user, | ||
140 | .Fa fd2p | ||
141 | must be 0. | ||
142 | .Pp | ||
143 | The protocol is described in detail in | ||
144 | .Xr rshd 8 . | ||
145 | .Pp | ||
146 | The | ||
147 | .Fn rresvport | ||
148 | function is used to obtain a socket with a privileged | ||
149 | address bound to it. This socket is suitable for use | ||
150 | by | ||
151 | .Fn rcmd | ||
152 | and several other functions. Privileged Internet ports are those | ||
153 | in the range 0 to 1023. Only the super-user | ||
154 | is allowed to bind an address of this sort to a socket. | ||
155 | .Fn rresvport | ||
156 | needs to be seeded with a port number; if that port | ||
157 | is not available it will find another. | ||
158 | .Pp | ||
159 | The | ||
160 | .Fn iruserok | ||
161 | and | ||
162 | .Fn ruserok | ||
163 | functions take a remote host's IP address or name, respectively, | ||
164 | two user names and a flag indicating whether the local user's | ||
165 | name is that of the super-user. | ||
166 | Then, if the user is | ||
167 | .Em NOT | ||
168 | the super-user, it checks the | ||
169 | .Pa /etc/hosts.equiv | ||
170 | file. | ||
171 | If that lookup is not done, or is unsuccessful, the | ||
172 | .Pa .rhosts | ||
173 | in the local user's home directory is checked to see if the request for | ||
174 | service is allowed. | ||
175 | .Pp | ||
176 | If this file does not exist, is not a regular file, is owned by anyone | ||
177 | other than the user or the super-user, or is writeable by anyone other | ||
178 | than the owner, the check automatically fails. | ||
179 | Zero is returned if the machine name is listed in the | ||
180 | .Dq Pa hosts.equiv | ||
181 | file, or the host and remote user name are found in the | ||
182 | .Dq Pa .rhosts | ||
183 | file; otherwise | ||
184 | .Fn iruserok | ||
185 | and | ||
186 | .Fn ruserok | ||
187 | return \-1. | ||
188 | If the local domain (as obtained from | ||
189 | .Xr gethostname 3 ) | ||
190 | is the same as the remote domain, only the machine name need be specified. | ||
191 | .Pp | ||
192 | If the IP address of the remote host is known, | ||
193 | .Fn iruserok | ||
194 | should be used in preference to | ||
195 | .Fn ruserok , | ||
196 | as it does not require trusting the DNS server for the remote host's domain. | ||
197 | .Sh DIAGNOSTICS | ||
198 | The | ||
199 | .Fn rcmd | ||
200 | function | ||
201 | returns a valid socket descriptor on success. | ||
202 | It returns \-1 on error and prints a diagnostic message on the standard error. | ||
203 | .Pp | ||
204 | The | ||
205 | .Fn rresvport | ||
206 | function | ||
207 | returns a valid, bound socket descriptor on success. | ||
208 | It returns \-1 on error with the global value | ||
209 | .Va errno | ||
210 | set according to the reason for failure. | ||
211 | The error code | ||
212 | .Dv EAGAIN | ||
213 | is overloaded to mean ``All network ports in use.'' | ||
214 | .Sh SEE ALSO | ||
215 | .Xr rlogin 1 , | ||
216 | .Xr rsh 1 , | ||
217 | .Xr intro 2 , | ||
218 | .Xr rexec 3 , | ||
219 | .Xr rcmdsh 3 , | ||
220 | .Xr rexecd 8 , | ||
221 | .Xr rlogind 8 , | ||
222 | .Xr bindresvport 3 , | ||
223 | .Xr rshd 8 | ||
224 | .Sh HISTORY | ||
225 | These | ||
226 | functions appeared in | ||
227 | .Bx 4.2 . | ||
diff --git a/src/lib/libc/net/rcmd.c b/src/lib/libc/net/rcmd.c new file mode 100644 index 0000000000..c933f5b447 --- /dev/null +++ b/src/lib/libc/net/rcmd.c | |||
@@ -0,0 +1,607 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1995, 1996, 1998 Theo de Raadt. All rights reserved. | ||
3 | * Copyright (c) 1983, 1993, 1994 | ||
4 | * The Regents of the University of California. All rights reserved. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * 3. All advertising materials mentioning features or use of this software | ||
15 | * must display the following acknowledgement: | ||
16 | * This product includes software developed by the University of | ||
17 | * California, Berkeley and its contributors. | ||
18 | * This product includes software developed by Theo de Raadt. | ||
19 | * 4. Neither the name of the University nor the names of its contributors | ||
20 | * may be used to endorse or promote products derived from this software | ||
21 | * without specific prior written permission. | ||
22 | * | ||
23 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
33 | * SUCH DAMAGE. | ||
34 | */ | ||
35 | |||
36 | #if defined(LIBC_SCCS) && !defined(lint) | ||
37 | static char *rcsid = "$OpenBSD: rcmd.c,v 1.31 1998/03/19 00:30:05 millert Exp $"; | ||
38 | #endif /* LIBC_SCCS and not lint */ | ||
39 | |||
40 | #include <sys/param.h> | ||
41 | #include <sys/socket.h> | ||
42 | #include <sys/stat.h> | ||
43 | |||
44 | #include <netinet/in.h> | ||
45 | #include <arpa/inet.h> | ||
46 | |||
47 | #include <signal.h> | ||
48 | #include <fcntl.h> | ||
49 | #include <netdb.h> | ||
50 | #include <unistd.h> | ||
51 | #include <pwd.h> | ||
52 | #include <errno.h> | ||
53 | #include <stdio.h> | ||
54 | #include <ctype.h> | ||
55 | #include <string.h> | ||
56 | #include <syslog.h> | ||
57 | #include <stdlib.h> | ||
58 | #include <netgroup.h> | ||
59 | |||
60 | int __ivaliduser __P((FILE *, in_addr_t, const char *, const char *)); | ||
61 | static int __icheckhost __P((u_int32_t, const char *)); | ||
62 | static char *__gethostloop __P((u_int32_t)); | ||
63 | |||
64 | int | ||
65 | rcmd(ahost, rport, locuser, remuser, cmd, fd2p) | ||
66 | char **ahost; | ||
67 | in_port_t rport; | ||
68 | const char *locuser, *remuser, *cmd; | ||
69 | int *fd2p; | ||
70 | { | ||
71 | struct hostent *hp; | ||
72 | struct sockaddr_in sin, from; | ||
73 | fd_set *readsp = NULL; | ||
74 | int oldmask; | ||
75 | pid_t pid; | ||
76 | int s, lport, timo; | ||
77 | char c, *p; | ||
78 | |||
79 | /* call rcmdsh() with specified remote shell if appropriate. */ | ||
80 | if (!issetugid() && (p = getenv("RSH"))) { | ||
81 | struct servent *sp = getservbyname("shell", "tcp"); | ||
82 | |||
83 | if (sp && sp->s_port == rport) | ||
84 | return (rcmdsh(ahost, rport, locuser, remuser, | ||
85 | cmd, p)); | ||
86 | } | ||
87 | |||
88 | /* use rsh(1) if non-root and remote port is shell. */ | ||
89 | if (geteuid()) { | ||
90 | struct servent *sp = getservbyname("shell", "tcp"); | ||
91 | |||
92 | if (sp && sp->s_port == rport) | ||
93 | return (rcmdsh(ahost, rport, locuser, remuser, | ||
94 | cmd, NULL)); | ||
95 | } | ||
96 | |||
97 | pid = getpid(); | ||
98 | hp = gethostbyname(*ahost); | ||
99 | if (hp == NULL) { | ||
100 | herror(*ahost); | ||
101 | return (-1); | ||
102 | } | ||
103 | *ahost = hp->h_name; | ||
104 | |||
105 | oldmask = sigblock(sigmask(SIGURG)); | ||
106 | for (timo = 1, lport = IPPORT_RESERVED - 1;;) { | ||
107 | s = rresvport(&lport); | ||
108 | if (s < 0) { | ||
109 | if (errno == EAGAIN) | ||
110 | (void)fprintf(stderr, | ||
111 | "rcmd: socket: All ports in use\n"); | ||
112 | else | ||
113 | (void)fprintf(stderr, "rcmd: socket: %s\n", | ||
114 | strerror(errno)); | ||
115 | sigsetmask(oldmask); | ||
116 | return (-1); | ||
117 | } | ||
118 | fcntl(s, F_SETOWN, pid); | ||
119 | bzero(&sin, sizeof sin); | ||
120 | sin.sin_len = sizeof(struct sockaddr_in); | ||
121 | sin.sin_family = hp->h_addrtype; | ||
122 | sin.sin_port = rport; | ||
123 | bcopy(hp->h_addr_list[0], &sin.sin_addr, hp->h_length); | ||
124 | if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0) | ||
125 | break; | ||
126 | (void)close(s); | ||
127 | if (errno == EADDRINUSE) { | ||
128 | lport--; | ||
129 | continue; | ||
130 | } | ||
131 | if (errno == ECONNREFUSED && timo <= 16) { | ||
132 | (void)sleep(timo); | ||
133 | timo *= 2; | ||
134 | continue; | ||
135 | } | ||
136 | if (hp->h_addr_list[1] != NULL) { | ||
137 | int oerrno = errno; | ||
138 | |||
139 | (void)fprintf(stderr, "connect to address %s: ", | ||
140 | inet_ntoa(sin.sin_addr)); | ||
141 | errno = oerrno; | ||
142 | perror(0); | ||
143 | hp->h_addr_list++; | ||
144 | bcopy(hp->h_addr_list[0], &sin.sin_addr, hp->h_length); | ||
145 | (void)fprintf(stderr, "Trying %s...\n", | ||
146 | inet_ntoa(sin.sin_addr)); | ||
147 | continue; | ||
148 | } | ||
149 | (void)fprintf(stderr, "%s: %s\n", hp->h_name, strerror(errno)); | ||
150 | sigsetmask(oldmask); | ||
151 | return (-1); | ||
152 | } | ||
153 | #if 0 | ||
154 | /* | ||
155 | * try to rresvport() to the same port. This will make rresvport() | ||
156 | * fail it's first bind, resulting in it choosing a random port. | ||
157 | */ | ||
158 | lport--; | ||
159 | #endif | ||
160 | if (fd2p == 0) { | ||
161 | write(s, "", 1); | ||
162 | lport = 0; | ||
163 | } else { | ||
164 | char num[8]; | ||
165 | int s2 = rresvport(&lport), s3; | ||
166 | int len = sizeof(from); | ||
167 | int fdssize = howmany(MAX(s, s2)+1, NFDBITS) * sizeof(fd_mask); | ||
168 | |||
169 | if (s2 < 0) | ||
170 | goto bad; | ||
171 | readsp = (fd_set *)malloc(fdssize); | ||
172 | if (readsp == NULL) | ||
173 | goto bad; | ||
174 | listen(s2, 1); | ||
175 | (void)snprintf(num, sizeof(num), "%d", lport); | ||
176 | if (write(s, num, strlen(num)+1) != strlen(num)+1) { | ||
177 | (void)fprintf(stderr, | ||
178 | "rcmd: write (setting up stderr): %s\n", | ||
179 | strerror(errno)); | ||
180 | (void)close(s2); | ||
181 | goto bad; | ||
182 | } | ||
183 | again: | ||
184 | bzero(readsp, fdssize); | ||
185 | FD_SET(s, readsp); | ||
186 | FD_SET(s2, readsp); | ||
187 | errno = 0; | ||
188 | if (select(MAX(s, s2) + 1, readsp, 0, 0, 0) < 1 || | ||
189 | !FD_ISSET(s2, readsp)) { | ||
190 | if (errno != 0) | ||
191 | (void)fprintf(stderr, | ||
192 | "rcmd: select (setting up stderr): %s\n", | ||
193 | strerror(errno)); | ||
194 | else | ||
195 | (void)fprintf(stderr, | ||
196 | "select: protocol failure in circuit setup\n"); | ||
197 | (void)close(s2); | ||
198 | goto bad; | ||
199 | } | ||
200 | s3 = accept(s2, (struct sockaddr *)&from, &len); | ||
201 | /* | ||
202 | * XXX careful for ftp bounce attacks. If discovered, shut them | ||
203 | * down and check for the real auxiliary channel to connect. | ||
204 | */ | ||
205 | if (from.sin_family == AF_INET && from.sin_port == htons(20)) { | ||
206 | close(s3); | ||
207 | goto again; | ||
208 | } | ||
209 | (void)close(s2); | ||
210 | if (s3 < 0) { | ||
211 | (void)fprintf(stderr, | ||
212 | "rcmd: accept: %s\n", strerror(errno)); | ||
213 | lport = 0; | ||
214 | goto bad; | ||
215 | } | ||
216 | *fd2p = s3; | ||
217 | from.sin_port = ntohs(from.sin_port); | ||
218 | if (from.sin_family != AF_INET || | ||
219 | from.sin_port >= IPPORT_RESERVED || | ||
220 | from.sin_port < IPPORT_RESERVED / 2) { | ||
221 | (void)fprintf(stderr, | ||
222 | "socket: protocol failure in circuit setup.\n"); | ||
223 | goto bad2; | ||
224 | } | ||
225 | } | ||
226 | (void)write(s, locuser, strlen(locuser)+1); | ||
227 | (void)write(s, remuser, strlen(remuser)+1); | ||
228 | (void)write(s, cmd, strlen(cmd)+1); | ||
229 | if (read(s, &c, 1) != 1) { | ||
230 | (void)fprintf(stderr, | ||
231 | "rcmd: %s: %s\n", *ahost, strerror(errno)); | ||
232 | goto bad2; | ||
233 | } | ||
234 | if (c != 0) { | ||
235 | while (read(s, &c, 1) == 1) { | ||
236 | (void)write(STDERR_FILENO, &c, 1); | ||
237 | if (c == '\n') | ||
238 | break; | ||
239 | } | ||
240 | goto bad2; | ||
241 | } | ||
242 | sigsetmask(oldmask); | ||
243 | free(readsp); | ||
244 | return (s); | ||
245 | bad2: | ||
246 | if (lport) | ||
247 | (void)close(*fd2p); | ||
248 | bad: | ||
249 | if (readsp) | ||
250 | free(readsp); | ||
251 | (void)close(s); | ||
252 | sigsetmask(oldmask); | ||
253 | return (-1); | ||
254 | } | ||
255 | |||
256 | int | ||
257 | rresvport(alport) | ||
258 | int *alport; | ||
259 | { | ||
260 | struct sockaddr_in sin; | ||
261 | int s; | ||
262 | |||
263 | bzero(&sin, sizeof sin); | ||
264 | sin.sin_len = sizeof(struct sockaddr_in); | ||
265 | sin.sin_family = AF_INET; | ||
266 | sin.sin_addr.s_addr = INADDR_ANY; | ||
267 | s = socket(AF_INET, SOCK_STREAM, 0); | ||
268 | if (s < 0) | ||
269 | return (-1); | ||
270 | sin.sin_port = htons((in_port_t)*alport); | ||
271 | if (*alport < IPPORT_RESERVED - 1) { | ||
272 | if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0) | ||
273 | return (s); | ||
274 | if (errno != EADDRINUSE) { | ||
275 | (void)close(s); | ||
276 | return (-1); | ||
277 | } | ||
278 | } | ||
279 | sin.sin_port = 0; | ||
280 | if (bindresvport(s, &sin) == -1) { | ||
281 | (void)close(s); | ||
282 | return (-1); | ||
283 | } | ||
284 | *alport = (int)ntohs(sin.sin_port); | ||
285 | return (s); | ||
286 | } | ||
287 | |||
288 | int __check_rhosts_file = 1; | ||
289 | char *__rcmd_errstr; | ||
290 | |||
291 | int | ||
292 | ruserok(rhost, superuser, ruser, luser) | ||
293 | const char *rhost, *ruser, *luser; | ||
294 | int superuser; | ||
295 | { | ||
296 | struct hostent *hp; | ||
297 | char **ap; | ||
298 | int i; | ||
299 | #define MAXADDRS 35 | ||
300 | u_int32_t addrs[MAXADDRS + 1]; | ||
301 | |||
302 | if ((hp = gethostbyname(rhost)) == NULL) | ||
303 | return (-1); | ||
304 | for (i = 0, ap = hp->h_addr_list; *ap && i < MAXADDRS; ++ap, ++i) | ||
305 | bcopy(*ap, &addrs[i], sizeof(addrs[i])); | ||
306 | addrs[i] = 0; | ||
307 | |||
308 | for (i = 0; i < MAXADDRS && addrs[i]; i++) | ||
309 | if (iruserok((in_addr_t)addrs[i], superuser, ruser, luser) == 0) | ||
310 | return (0); | ||
311 | return (-1); | ||
312 | } | ||
313 | |||
314 | /* | ||
315 | * New .rhosts strategy: We are passed an ip address. We spin through | ||
316 | * hosts.equiv and .rhosts looking for a match. When the .rhosts only | ||
317 | * has ip addresses, we don't have to trust a nameserver. When it | ||
318 | * contains hostnames, we spin through the list of addresses the nameserver | ||
319 | * gives us and look for a match. | ||
320 | * | ||
321 | * Returns 0 if ok, -1 if not ok. | ||
322 | */ | ||
323 | int | ||
324 | iruserok(raddr, superuser, ruser, luser) | ||
325 | u_int32_t raddr; | ||
326 | int superuser; | ||
327 | const char *ruser, *luser; | ||
328 | { | ||
329 | register char *cp; | ||
330 | struct stat sbuf; | ||
331 | struct passwd *pwd; | ||
332 | FILE *hostf; | ||
333 | uid_t uid; | ||
334 | int first; | ||
335 | char pbuf[MAXPATHLEN]; | ||
336 | |||
337 | first = 1; | ||
338 | hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "r"); | ||
339 | again: | ||
340 | if (hostf) { | ||
341 | if (__ivaliduser(hostf, raddr, luser, ruser) == 0) { | ||
342 | (void)fclose(hostf); | ||
343 | return (0); | ||
344 | } | ||
345 | (void)fclose(hostf); | ||
346 | } | ||
347 | if (first == 1 && (__check_rhosts_file || superuser)) { | ||
348 | first = 0; | ||
349 | if ((pwd = getpwnam(luser)) == NULL) | ||
350 | return (-1); | ||
351 | (void)strcpy(pbuf, pwd->pw_dir); | ||
352 | (void)strcat(pbuf, "/.rhosts"); | ||
353 | |||
354 | /* | ||
355 | * Change effective uid while opening .rhosts. If root and | ||
356 | * reading an NFS mounted file system, can't read files that | ||
357 | * are protected read/write owner only. | ||
358 | */ | ||
359 | uid = geteuid(); | ||
360 | (void)seteuid(pwd->pw_uid); | ||
361 | hostf = fopen(pbuf, "r"); | ||
362 | (void)seteuid(uid); | ||
363 | |||
364 | if (hostf == NULL) | ||
365 | return (-1); | ||
366 | /* | ||
367 | * If not a regular file, or is owned by someone other than | ||
368 | * user or root or if writeable by anyone but the owner, quit. | ||
369 | */ | ||
370 | cp = NULL; | ||
371 | if (lstat(pbuf, &sbuf) < 0) | ||
372 | cp = ".rhosts lstat failed"; | ||
373 | else if (!S_ISREG(sbuf.st_mode)) | ||
374 | cp = ".rhosts not regular file"; | ||
375 | else if (fstat(fileno(hostf), &sbuf) < 0) | ||
376 | cp = ".rhosts fstat failed"; | ||
377 | else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) | ||
378 | cp = "bad .rhosts owner"; | ||
379 | else if (sbuf.st_mode & (S_IWGRP|S_IWOTH)) | ||
380 | cp = ".rhosts writeable by other than owner"; | ||
381 | /* If there were any problems, quit. */ | ||
382 | if (cp) { | ||
383 | __rcmd_errstr = cp; | ||
384 | (void)fclose(hostf); | ||
385 | return (-1); | ||
386 | } | ||
387 | goto again; | ||
388 | } | ||
389 | return (-1); | ||
390 | } | ||
391 | |||
392 | /* | ||
393 | * XXX | ||
394 | * Don't make static, used by lpd(8). | ||
395 | * | ||
396 | * Returns 0 if ok, -1 if not ok. | ||
397 | */ | ||
398 | int | ||
399 | __ivaliduser(hostf, raddrl, luser, ruser) | ||
400 | FILE *hostf; | ||
401 | in_addr_t raddrl; | ||
402 | const char *luser, *ruser; | ||
403 | { | ||
404 | register char *user, *p; | ||
405 | char *buf; | ||
406 | const char *auser, *ahost; | ||
407 | int hostok, userok; | ||
408 | char *rhost = (char *)-1; | ||
409 | char domain[MAXHOSTNAMELEN]; | ||
410 | u_int32_t raddr = (u_int32_t)raddrl; | ||
411 | size_t buflen; | ||
412 | |||
413 | getdomainname(domain, sizeof(domain)); | ||
414 | |||
415 | while ((buf = fgetln(hostf, &buflen))) { | ||
416 | p = buf; | ||
417 | if (*p == '#') | ||
418 | continue; | ||
419 | while (*p != '\n' && *p != ' ' && *p != '\t' && p < buf + buflen) { | ||
420 | if (!isprint(*p)) | ||
421 | goto bail; | ||
422 | *p = isupper(*p) ? tolower(*p) : *p; | ||
423 | p++; | ||
424 | } | ||
425 | if (p >= buf + buflen) | ||
426 | continue; | ||
427 | if (*p == ' ' || *p == '\t') { | ||
428 | *p++ = '\0'; | ||
429 | while ((*p == ' ' || *p == '\t') && p < buf + buflen) | ||
430 | p++; | ||
431 | if (p >= buf + buflen) | ||
432 | continue; | ||
433 | user = p; | ||
434 | while (*p != '\n' && *p != ' ' && | ||
435 | *p != '\t' && p < buf + buflen) { | ||
436 | if (!isprint(*p)) | ||
437 | goto bail; | ||
438 | p++; | ||
439 | } | ||
440 | } else | ||
441 | user = p; | ||
442 | *p = '\0'; | ||
443 | |||
444 | if (p == buf) | ||
445 | continue; | ||
446 | |||
447 | auser = *user ? user : luser; | ||
448 | ahost = buf; | ||
449 | |||
450 | if (strlen(ahost) >= MAXHOSTNAMELEN) | ||
451 | continue; | ||
452 | |||
453 | /* | ||
454 | * innetgr() must lookup a hostname (we do not attempt | ||
455 | * to change the semantics so that netgroups may have | ||
456 | * #.#.#.# addresses in the list.) | ||
457 | */ | ||
458 | if (ahost[0] == '+') | ||
459 | switch (ahost[1]) { | ||
460 | case '\0': | ||
461 | hostok = 1; | ||
462 | break; | ||
463 | case '@': | ||
464 | if (rhost == (char *)-1) | ||
465 | rhost = __gethostloop(raddr); | ||
466 | hostok = 0; | ||
467 | if (rhost) | ||
468 | hostok = innetgr(&ahost[2], rhost, | ||
469 | NULL, domain); | ||
470 | break; | ||
471 | default: | ||
472 | hostok = __icheckhost(raddr, &ahost[1]); | ||
473 | break; | ||
474 | } | ||
475 | else if (ahost[0] == '-') | ||
476 | switch (ahost[1]) { | ||
477 | case '\0': | ||
478 | hostok = -1; | ||
479 | break; | ||
480 | case '@': | ||
481 | if (rhost == (char *)-1) | ||
482 | rhost = __gethostloop(raddr); | ||
483 | hostok = 0; | ||
484 | if (rhost) | ||
485 | hostok = -innetgr(&ahost[2], rhost, | ||
486 | NULL, domain); | ||
487 | break; | ||
488 | default: | ||
489 | hostok = -__icheckhost(raddr, &ahost[1]); | ||
490 | break; | ||
491 | } | ||
492 | else | ||
493 | hostok = __icheckhost(raddr, ahost); | ||
494 | |||
495 | |||
496 | if (auser[0] == '+') | ||
497 | switch (auser[1]) { | ||
498 | case '\0': | ||
499 | userok = 1; | ||
500 | break; | ||
501 | case '@': | ||
502 | userok = innetgr(&auser[2], NULL, ruser, | ||
503 | domain); | ||
504 | break; | ||
505 | default: | ||
506 | userok = strcmp(ruser, &auser[1]) ? 0 : 1; | ||
507 | break; | ||
508 | } | ||
509 | else if (auser[0] == '-') | ||
510 | switch (auser[1]) { | ||
511 | case '\0': | ||
512 | userok = -1; | ||
513 | break; | ||
514 | case '@': | ||
515 | userok = -innetgr(&auser[2], NULL, ruser, | ||
516 | domain); | ||
517 | break; | ||
518 | default: | ||
519 | userok = strcmp(ruser, &auser[1]) ? 0 : -1; | ||
520 | break; | ||
521 | } | ||
522 | else | ||
523 | userok = strcmp(ruser, auser) ? 0 : 1; | ||
524 | |||
525 | /* Check if one component did not match */ | ||
526 | if (hostok == 0 || userok == 0) | ||
527 | continue; | ||
528 | |||
529 | /* Check if we got a forbidden pair */ | ||
530 | if (userok <= -1 || hostok <= -1) | ||
531 | return (-1); | ||
532 | |||
533 | /* Check if we got a valid pair */ | ||
534 | if (hostok >= 1 && userok >= 1) | ||
535 | return (0); | ||
536 | } | ||
537 | bail: | ||
538 | return (-1); | ||
539 | } | ||
540 | |||
541 | /* | ||
542 | * Returns "true" if match, 0 if no match. If we do not find any | ||
543 | * semblance of an A->PTR->A loop, allow a simple #.#.#.# match to work. | ||
544 | */ | ||
545 | static int | ||
546 | __icheckhost(raddr, lhost) | ||
547 | u_int32_t raddr; | ||
548 | const char *lhost; | ||
549 | { | ||
550 | register struct hostent *hp; | ||
551 | register char **pp; | ||
552 | struct in_addr in; | ||
553 | |||
554 | hp = gethostbyname(lhost); | ||
555 | if (hp != NULL) { | ||
556 | /* Spin through ip addresses. */ | ||
557 | for (pp = hp->h_addr_list; *pp; ++pp) | ||
558 | if (!bcmp(&raddr, *pp, sizeof(raddr))) | ||
559 | return (1); | ||
560 | } | ||
561 | |||
562 | in.s_addr = raddr; | ||
563 | if (strcmp(lhost, inet_ntoa(in)) == 0) | ||
564 | return (1); | ||
565 | return (0); | ||
566 | } | ||
567 | |||
568 | /* | ||
569 | * Return the hostname associated with the supplied address. | ||
570 | * Do a reverse lookup as well for security. If a loop cannot | ||
571 | * be found, pack the result of inet_ntoa() into the string. | ||
572 | */ | ||
573 | static char * | ||
574 | __gethostloop(raddr) | ||
575 | u_int32_t raddr; | ||
576 | { | ||
577 | static char remotehost[MAXHOSTNAMELEN]; | ||
578 | struct hostent *hp; | ||
579 | struct in_addr in; | ||
580 | |||
581 | hp = gethostbyaddr((char *) &raddr, sizeof(raddr), AF_INET); | ||
582 | if (hp == NULL) | ||
583 | return (NULL); | ||
584 | |||
585 | /* | ||
586 | * Look up the name and check that the supplied | ||
587 | * address is in the list | ||
588 | */ | ||
589 | strncpy(remotehost, hp->h_name, sizeof(remotehost) - 1); | ||
590 | remotehost[sizeof(remotehost) - 1] = '\0'; | ||
591 | hp = gethostbyname(remotehost); | ||
592 | if (hp == NULL) | ||
593 | return (NULL); | ||
594 | |||
595 | for (; hp->h_addr_list[0] != NULL; hp->h_addr_list++) | ||
596 | if (!bcmp(hp->h_addr_list[0], (caddr_t)&raddr, sizeof(raddr))) | ||
597 | return (remotehost); | ||
598 | |||
599 | /* | ||
600 | * either the DNS adminstrator has made a configuration | ||
601 | * mistake, or someone has attempted to spoof us | ||
602 | */ | ||
603 | in.s_addr = raddr; | ||
604 | syslog(LOG_NOTICE, "rcmd: address %s not listed for host %s", | ||
605 | inet_ntoa(in), hp->h_name); | ||
606 | return (NULL); | ||
607 | } | ||
diff --git a/src/lib/libc/net/rcmdsh.3 b/src/lib/libc/net/rcmdsh.3 new file mode 100644 index 0000000000..fd89acee8f --- /dev/null +++ b/src/lib/libc/net/rcmdsh.3 | |||
@@ -0,0 +1,108 @@ | |||
1 | .\" $OpenBSD: rcmdsh.3,v 1.3 1998/06/26 17:54:09 millert Exp $ | ||
2 | .\" | ||
3 | .\" Copyright (c) 1983, 1991, 1993 | ||
4 | .\" The Regents of the University of California. All rights reserved. | ||
5 | .\" | ||
6 | .\" Redistribution and use in source and binary forms, with or without | ||
7 | .\" modification, are permitted provided that the following conditions | ||
8 | .\" are met: | ||
9 | .\" 1. Redistributions of source code must retain the above copyright | ||
10 | .\" notice, this list of conditions and the following disclaimer. | ||
11 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
12 | .\" notice, this list of conditions and the following disclaimer in the | ||
13 | .\" documentation and/or other materials provided with the distribution. | ||
14 | .\" 3. All advertising materials mentioning features or use of this software | ||
15 | .\" must display the following acknowledgement: | ||
16 | .\" This product includes software developed by the University of | ||
17 | .\" California, Berkeley and its contributors. | ||
18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
19 | .\" may be used to endorse or promote products derived from this software | ||
20 | .\" without specific prior written permission. | ||
21 | .\" | ||
22 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
23 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
24 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
26 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
27 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
28 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
29 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
30 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
32 | .\" SUCH DAMAGE. | ||
33 | .\" | ||
34 | .Dd Sep 1, 1996 | ||
35 | .Dt RCMDSH 3 | ||
36 | .Os OpenBSD | ||
37 | .Sh NAME | ||
38 | .Nm rcmdsh | ||
39 | .Nd return a stream to a remote command without superuser | ||
40 | .Sh SYNOPSIS | ||
41 | .Fd #include <unistd.h> | ||
42 | .Ft int | ||
43 | .Fn rcmdsh "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "char *rshprog" | ||
44 | .Sh DESCRIPTION | ||
45 | The | ||
46 | .Fn rcmdsh | ||
47 | function | ||
48 | is used by normal users to execute a command on | ||
49 | a remote machine using an authentication scheme based | ||
50 | on reserved port numbers using | ||
51 | .Xr rshd 8 | ||
52 | or the value of | ||
53 | .Fa rshprog | ||
54 | (if non-NULL). | ||
55 | .Pp | ||
56 | The | ||
57 | .Fn rcmdsh | ||
58 | function | ||
59 | looks up the host | ||
60 | .Fa *ahost | ||
61 | using | ||
62 | .Xr gethostbyname 3 , | ||
63 | returning \-1 if the host does not exist. | ||
64 | Otherwise | ||
65 | .Fa *ahost | ||
66 | is set to the standard name of the host | ||
67 | and a connection is established to a server | ||
68 | residing at the well-known Internet port | ||
69 | .Li shell/tcp | ||
70 | (or whatever port is used by | ||
71 | .Fa rshprog | ||
72 | ). The parameter | ||
73 | .Fa inport | ||
74 | is ignored; it is only included to provide an interface similar to | ||
75 | .Xr rcmd 3 . | ||
76 | .Pp | ||
77 | If the connection succeeds, | ||
78 | a socket in the | ||
79 | .Tn UNIX | ||
80 | domain of type | ||
81 | .Dv SOCK_STREAM | ||
82 | is returned to the caller, and given to the remote | ||
83 | command as | ||
84 | .Em stdin | ||
85 | and | ||
86 | .Em stdout , | ||
87 | and | ||
88 | .Em stderr . | ||
89 | .Sh DIAGNOSTICS | ||
90 | The | ||
91 | .Fn rcmdsh | ||
92 | function | ||
93 | returns a valid socket descriptor on success. | ||
94 | It returns \-1 on error and prints a diagnostic message on the standard error. | ||
95 | .Sh SEE ALSO | ||
96 | .Xr rsh 1 , | ||
97 | .Xr socketpair 2 , | ||
98 | .Xr rcmd 3 , | ||
99 | .Xr rshd 8 | ||
100 | .Sh BUGS | ||
101 | If | ||
102 | .Xr rsh 1 | ||
103 | gets an error a file descriptor is still returned instead of \-1. | ||
104 | .Sh HISTORY | ||
105 | The | ||
106 | .Fn rcmdsh | ||
107 | function first appeared in | ||
108 | .Ox 2.0 . | ||
diff --git a/src/lib/libc/net/rcmdsh.c b/src/lib/libc/net/rcmdsh.c new file mode 100644 index 0000000000..93523a4c56 --- /dev/null +++ b/src/lib/libc/net/rcmdsh.c | |||
@@ -0,0 +1,124 @@ | |||
1 | /* $OpenBSD: rcmdsh.c,v 1.5 1998/04/25 16:23:58 millert Exp $ */ | ||
2 | |||
3 | /* | ||
4 | * This is an rcmd() replacement originally by | ||
5 | * Chris Siebenmann <cks@utcc.utoronto.ca>. | ||
6 | */ | ||
7 | |||
8 | #if defined(LIBC_SCCS) && !defined(lint) | ||
9 | static char *rcsid = "$OpenBSD: rcmdsh.c,v 1.5 1998/04/25 16:23:58 millert Exp $"; | ||
10 | #endif /* LIBC_SCCS and not lint */ | ||
11 | |||
12 | #include <sys/types.h> | ||
13 | #include <sys/socket.h> | ||
14 | #include <sys/wait.h> | ||
15 | #include <signal.h> | ||
16 | #include <errno.h> | ||
17 | #include <netdb.h> | ||
18 | #include <stdio.h> | ||
19 | #include <string.h> | ||
20 | #include <pwd.h> | ||
21 | #include <paths.h> | ||
22 | #include <unistd.h> | ||
23 | |||
24 | /* | ||
25 | * This is a replacement rcmd() function that uses the rsh(1) | ||
26 | * program in place of a direct rcmd(3) function call so as to | ||
27 | * avoid having to be root. Note that rport is ignored. | ||
28 | */ | ||
29 | /* ARGSUSED */ | ||
30 | int | ||
31 | rcmdsh(ahost, rport, locuser, remuser, cmd, rshprog) | ||
32 | char **ahost; | ||
33 | int rport; | ||
34 | const char *locuser, *remuser, *cmd; | ||
35 | char *rshprog; | ||
36 | { | ||
37 | struct hostent *hp; | ||
38 | int cpid, sp[2]; | ||
39 | char *p; | ||
40 | struct passwd *pw; | ||
41 | |||
42 | /* What rsh/shell to use. */ | ||
43 | if (rshprog == NULL) | ||
44 | rshprog = _PATH_RSH; | ||
45 | |||
46 | /* locuser must exist on this host. */ | ||
47 | if ((pw = getpwnam(locuser)) == NULL) { | ||
48 | (void) fprintf(stderr, "rcmdsh: unknown user: %s\n", locuser); | ||
49 | return(-1); | ||
50 | } | ||
51 | |||
52 | /* Validate remote hostname. */ | ||
53 | if (strcmp(*ahost, "localhost") != 0) { | ||
54 | if ((hp = gethostbyname(*ahost)) == NULL) { | ||
55 | herror(*ahost); | ||
56 | return(-1); | ||
57 | } | ||
58 | *ahost = hp->h_name; | ||
59 | } | ||
60 | |||
61 | /* Get a socketpair we'll use for stdin and stdout. */ | ||
62 | if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0) { | ||
63 | perror("rcmdsh: socketpair"); | ||
64 | return(-1); | ||
65 | } | ||
66 | |||
67 | cpid = fork(); | ||
68 | if (cpid < 0) { | ||
69 | perror("rcmdsh: fork failed"); | ||
70 | return(-1); | ||
71 | } else if (cpid == 0) { | ||
72 | /* | ||
73 | * Child. We use sp[1] to be stdin/stdout, and close sp[0]. | ||
74 | */ | ||
75 | (void) close(sp[0]); | ||
76 | if (dup2(sp[1], 0) < 0 || dup2(0, 1) < 0) { | ||
77 | perror("rcmdsh: dup2 failed"); | ||
78 | _exit(255); | ||
79 | } | ||
80 | /* Fork again to lose parent. */ | ||
81 | cpid = fork(); | ||
82 | if (cpid < 0) { | ||
83 | perror("rcmdsh: fork to lose parent failed"); | ||
84 | _exit(255); | ||
85 | } | ||
86 | if (cpid > 0) | ||
87 | _exit(0); | ||
88 | |||
89 | /* In grandchild here. Become local user for rshprog. */ | ||
90 | if (setuid(pw->pw_uid)) { | ||
91 | (void) fprintf(stderr, "rcmdsh: setuid(%u): %s\n", | ||
92 | pw->pw_uid, strerror(errno)); | ||
93 | _exit(255); | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * If remote host is "localhost" and local and remote user | ||
98 | * are the same, avoid running remote shell for efficiency. | ||
99 | */ | ||
100 | if (!strcmp(*ahost, "localhost") && !strcmp(locuser, remuser)) { | ||
101 | if (pw->pw_shell[0] == '\0') | ||
102 | rshprog = _PATH_BSHELL; | ||
103 | else | ||
104 | rshprog = pw->pw_shell; | ||
105 | p = strrchr(rshprog, '/'); | ||
106 | execlp(rshprog, p ? p+1 : rshprog, "-c", cmd, | ||
107 | (char *) NULL); | ||
108 | } else { | ||
109 | p = strrchr(rshprog, '/'); | ||
110 | execlp(rshprog, p ? p+1 : rshprog, *ahost, "-l", | ||
111 | remuser, cmd, (char *) NULL); | ||
112 | } | ||
113 | (void) fprintf(stderr, "rcmdsh: execlp %s failed: %s\n", | ||
114 | rshprog, strerror(errno)); | ||
115 | _exit(255); | ||
116 | } else { | ||
117 | /* Parent. close sp[1], return sp[0]. */ | ||
118 | (void) close(sp[1]); | ||
119 | /* Reap child. */ | ||
120 | (void) wait(NULL); | ||
121 | return(sp[0]); | ||
122 | } | ||
123 | /* NOTREACHED */ | ||
124 | } | ||
diff --git a/src/lib/libc/net/recv.c b/src/lib/libc/net/recv.c new file mode 100644 index 0000000000..d209a07213 --- /dev/null +++ b/src/lib/libc/net/recv.c | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1988, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: recv.c,v 1.2 1996/08/19 08:29:40 tholo Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | #include <sys/types.h> | ||
39 | #include <sys/socket.h> | ||
40 | |||
41 | #include <stddef.h> | ||
42 | |||
43 | ssize_t | ||
44 | recv(s, buf, len, flags) | ||
45 | int s, flags; | ||
46 | size_t len; | ||
47 | void *buf; | ||
48 | { | ||
49 | return (recvfrom(s, buf, len, flags, NULL, 0)); | ||
50 | } | ||
diff --git a/src/lib/libc/net/res_comp.c b/src/lib/libc/net/res_comp.c new file mode 100644 index 0000000000..f7a0358967 --- /dev/null +++ b/src/lib/libc/net/res_comp.c | |||
@@ -0,0 +1,510 @@ | |||
1 | /* $OpenBSD: res_comp.c,v 1.8 1997/07/09 01:08:49 millert Exp $ */ | ||
2 | |||
3 | /* | ||
4 | * ++Copyright++ 1985, 1993 | ||
5 | * - | ||
6 | * Copyright (c) 1985, 1993 | ||
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 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.8 1997/07/09 01:08:49 millert Exp $"; | ||
64 | #endif | ||
65 | #endif /* LIBC_SCCS and not lint */ | ||
66 | |||
67 | #include <sys/types.h> | ||
68 | #include <sys/param.h> | ||
69 | #include <netinet/in.h> | ||
70 | #include <arpa/nameser.h> | ||
71 | |||
72 | #include <stdio.h> | ||
73 | #include <resolv.h> | ||
74 | #include <ctype.h> | ||
75 | |||
76 | #include <unistd.h> | ||
77 | #include <string.h> | ||
78 | |||
79 | static int dn_find __P((u_char *exp_dn, u_char *msg, | ||
80 | u_char **dnptrs, u_char **lastdnptr)); | ||
81 | |||
82 | /* | ||
83 | * Expand compressed domain name 'comp_dn' to full domain name. | ||
84 | * 'msg' is a pointer to the begining of the message, | ||
85 | * 'eomorig' points to the first location after the message, | ||
86 | * 'exp_dn' is a pointer to a buffer of size 'length' for the result. | ||
87 | * Return size of compressed name or -1 if there was an error. | ||
88 | */ | ||
89 | int | ||
90 | dn_expand(msg, eomorig, comp_dn, exp_dn, length) | ||
91 | const u_char *msg, *eomorig, *comp_dn; | ||
92 | char *exp_dn; | ||
93 | int length; | ||
94 | { | ||
95 | register const u_char *cp; | ||
96 | register char *dn; | ||
97 | register int n, c; | ||
98 | char *eom; | ||
99 | int len = -1, checked = 0; | ||
100 | |||
101 | dn = exp_dn; | ||
102 | cp = comp_dn; | ||
103 | if (length > MAXHOSTNAMELEN-1) | ||
104 | length = MAXHOSTNAMELEN-1; | ||
105 | eom = exp_dn + length; | ||
106 | /* | ||
107 | * fetch next label in domain name | ||
108 | */ | ||
109 | while ((n = *cp++)) { | ||
110 | /* | ||
111 | * Check for indirection | ||
112 | */ | ||
113 | switch (n & INDIR_MASK) { | ||
114 | case 0: | ||
115 | if (dn != exp_dn) { | ||
116 | if (dn >= eom) | ||
117 | return (-1); | ||
118 | *dn++ = '.'; | ||
119 | } | ||
120 | if (dn+n >= eom) | ||
121 | return (-1); | ||
122 | checked += n + 1; | ||
123 | while (--n >= 0) { | ||
124 | if (((c = *cp++) == '.') || (c == '\\')) { | ||
125 | if (dn + n + 2 >= eom) | ||
126 | return (-1); | ||
127 | *dn++ = '\\'; | ||
128 | } | ||
129 | *dn++ = c; | ||
130 | if (cp >= eomorig) /* out of range */ | ||
131 | return (-1); | ||
132 | } | ||
133 | break; | ||
134 | |||
135 | case INDIR_MASK: | ||
136 | if (len < 0) | ||
137 | len = cp - comp_dn + 1; | ||
138 | cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff)); | ||
139 | if (cp < msg || cp >= eomorig) /* out of range */ | ||
140 | return (-1); | ||
141 | checked += 2; | ||
142 | /* | ||
143 | * Check for loops in the compressed name; | ||
144 | * if we've looked at the whole message, | ||
145 | * there must be a loop. | ||
146 | */ | ||
147 | if (checked >= eomorig - msg) | ||
148 | return (-1); | ||
149 | break; | ||
150 | |||
151 | default: | ||
152 | return (-1); /* flag error */ | ||
153 | } | ||
154 | } | ||
155 | *dn = '\0'; | ||
156 | if (len < 0) | ||
157 | len = cp - comp_dn; | ||
158 | return (len); | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * Compress domain name 'exp_dn' into 'comp_dn'. | ||
163 | * Return the size of the compressed name or -1. | ||
164 | * 'length' is the size of the array pointed to by 'comp_dn'. | ||
165 | * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0] | ||
166 | * is a pointer to the beginning of the message. The list ends with NULL. | ||
167 | * 'lastdnptr' is a pointer to the end of the arrary pointed to | ||
168 | * by 'dnptrs'. Side effect is to update the list of pointers for | ||
169 | * labels inserted into the message as we compress the name. | ||
170 | * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr' | ||
171 | * is NULL, we don't update the list. | ||
172 | */ | ||
173 | int | ||
174 | dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr) | ||
175 | const char *exp_dn; | ||
176 | u_char *comp_dn, **dnptrs, **lastdnptr; | ||
177 | int length; | ||
178 | { | ||
179 | register u_char *cp, *dn; | ||
180 | register int c, l; | ||
181 | u_char **cpp, **lpp, *sp, *eob; | ||
182 | u_char *msg; | ||
183 | |||
184 | dn = (u_char *)exp_dn; | ||
185 | cp = comp_dn; | ||
186 | eob = cp + length; | ||
187 | lpp = cpp = NULL; | ||
188 | if (dnptrs != NULL) { | ||
189 | if ((msg = *dnptrs++) != NULL) { | ||
190 | for (cpp = dnptrs; *cpp != NULL; cpp++) | ||
191 | ; | ||
192 | lpp = cpp; /* end of list to search */ | ||
193 | } | ||
194 | } else | ||
195 | msg = NULL; | ||
196 | for (c = *dn++; c != '\0'; ) { | ||
197 | /* look to see if we can use pointers */ | ||
198 | if (msg != NULL) { | ||
199 | if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) { | ||
200 | if (cp+1 >= eob) | ||
201 | return (-1); | ||
202 | *cp++ = (l >> 8) | INDIR_MASK; | ||
203 | *cp++ = l % 256; | ||
204 | return (cp - comp_dn); | ||
205 | } | ||
206 | /* not found, save it */ | ||
207 | if (lastdnptr != NULL && cpp < lastdnptr-1) { | ||
208 | *cpp++ = cp; | ||
209 | *cpp = NULL; | ||
210 | } | ||
211 | } | ||
212 | sp = cp++; /* save ptr to length byte */ | ||
213 | do { | ||
214 | if (c == '.') { | ||
215 | c = *dn++; | ||
216 | break; | ||
217 | } | ||
218 | if (c == '\\') { | ||
219 | if ((c = *dn++) == '\0') | ||
220 | break; | ||
221 | } | ||
222 | if (cp >= eob) { | ||
223 | if (msg != NULL) | ||
224 | *lpp = NULL; | ||
225 | return (-1); | ||
226 | } | ||
227 | *cp++ = c; | ||
228 | } while ((c = *dn++) != '\0'); | ||
229 | /* catch trailing '.'s but not '..' */ | ||
230 | if ((l = cp - sp - 1) == 0 && c == '\0') { | ||
231 | cp--; | ||
232 | break; | ||
233 | } | ||
234 | if (l <= 0 || l > MAXLABEL) { | ||
235 | if (msg != NULL) | ||
236 | *lpp = NULL; | ||
237 | return (-1); | ||
238 | } | ||
239 | *sp = l; | ||
240 | } | ||
241 | if (cp >= eob) { | ||
242 | if (msg != NULL) | ||
243 | *lpp = NULL; | ||
244 | return (-1); | ||
245 | } | ||
246 | *cp++ = '\0'; | ||
247 | return (cp - comp_dn); | ||
248 | } | ||
249 | |||
250 | /* | ||
251 | * Skip over a compressed domain name. Return the size or -1. | ||
252 | */ | ||
253 | int | ||
254 | __dn_skipname(comp_dn, eom) | ||
255 | const u_char *comp_dn, *eom; | ||
256 | { | ||
257 | register const u_char *cp; | ||
258 | register int n; | ||
259 | |||
260 | cp = comp_dn; | ||
261 | while (cp < eom && (n = *cp++)) { | ||
262 | /* | ||
263 | * check for indirection | ||
264 | */ | ||
265 | switch (n & INDIR_MASK) { | ||
266 | case 0: /* normal case, n == len */ | ||
267 | cp += n; | ||
268 | continue; | ||
269 | case INDIR_MASK: /* indirection */ | ||
270 | cp++; | ||
271 | break; | ||
272 | default: /* illegal type */ | ||
273 | return (-1); | ||
274 | } | ||
275 | break; | ||
276 | } | ||
277 | if (cp > eom) | ||
278 | return (-1); | ||
279 | return (cp - comp_dn); | ||
280 | } | ||
281 | |||
282 | static int | ||
283 | mklower(ch) | ||
284 | register int ch; | ||
285 | { | ||
286 | if (isascii(ch) && isupper(ch)) | ||
287 | return (tolower(ch)); | ||
288 | return (ch); | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * Search for expanded name from a list of previously compressed names. | ||
293 | * Return the offset from msg if found or -1. | ||
294 | * dnptrs is the pointer to the first name on the list, | ||
295 | * not the pointer to the start of the message. | ||
296 | */ | ||
297 | static int | ||
298 | dn_find(exp_dn, msg, dnptrs, lastdnptr) | ||
299 | u_char *exp_dn, *msg; | ||
300 | u_char **dnptrs, **lastdnptr; | ||
301 | { | ||
302 | register u_char *dn, *cp, **cpp; | ||
303 | register int n; | ||
304 | u_char *sp; | ||
305 | |||
306 | for (cpp = dnptrs; cpp < lastdnptr; cpp++) { | ||
307 | dn = exp_dn; | ||
308 | sp = cp = *cpp; | ||
309 | while ((n = *cp++)) { | ||
310 | /* | ||
311 | * check for indirection | ||
312 | */ | ||
313 | switch (n & INDIR_MASK) { | ||
314 | case 0: /* normal case, n == len */ | ||
315 | while (--n >= 0) { | ||
316 | if (*dn == '.') | ||
317 | goto next; | ||
318 | if (*dn == '\\') | ||
319 | dn++; | ||
320 | if (mklower(*dn++) != mklower(*cp++)) | ||
321 | goto next; | ||
322 | } | ||
323 | if ((n = *dn++) == '\0' && *cp == '\0') | ||
324 | return (sp - msg); | ||
325 | if (n == '.') | ||
326 | continue; | ||
327 | goto next; | ||
328 | |||
329 | case INDIR_MASK: /* indirection */ | ||
330 | cp = msg + (((n & 0x3f) << 8) | *cp); | ||
331 | break; | ||
332 | |||
333 | default: /* illegal type */ | ||
334 | return (-1); | ||
335 | } | ||
336 | } | ||
337 | if (*dn == '\0') | ||
338 | return (sp - msg); | ||
339 | next: ; | ||
340 | } | ||
341 | return (-1); | ||
342 | } | ||
343 | |||
344 | /* | ||
345 | * Verify that a domain name uses an acceptable character set. | ||
346 | */ | ||
347 | |||
348 | /* | ||
349 | * Note the conspicuous absence of ctype macros in these definitions. On | ||
350 | * non-ASCII hosts, we can't depend on string literals or ctype macros to | ||
351 | * tell us anything about network-format data. The rest of the BIND system | ||
352 | * is not careful about this, but for some reason, we're doing it right here. | ||
353 | */ | ||
354 | #define PERIOD 0x2e | ||
355 | #define hyphenchar(c) ((c) == 0x2d) | ||
356 | #define bslashchar(c) ((c) == 0x5c) | ||
357 | #define periodchar(c) ((c) == PERIOD) | ||
358 | #define asterchar(c) ((c) == 0x2a) | ||
359 | #define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \ | ||
360 | || ((c) >= 0x61 && (c) <= 0x7a)) | ||
361 | #define digitchar(c) ((c) >= 0x30 && (c) <= 0x39) | ||
362 | |||
363 | #define borderchar(c) (alphachar(c) || digitchar(c)) | ||
364 | #define middlechar(c) (borderchar(c) || hyphenchar(c)) | ||
365 | #define domainchar(c) ((c) > 0x20 && (c) < 0x7f) | ||
366 | |||
367 | int | ||
368 | res_hnok(dn) | ||
369 | const char *dn; | ||
370 | { | ||
371 | int pch = PERIOD, ch = *dn++; | ||
372 | |||
373 | while (ch != '\0') { | ||
374 | int nch = *dn++; | ||
375 | |||
376 | if (periodchar(ch)) { | ||
377 | ; | ||
378 | } else if (periodchar(pch)) { | ||
379 | if (!borderchar(ch)) | ||
380 | return (0); | ||
381 | } else if (periodchar(nch) || nch == '\0') { | ||
382 | if (!borderchar(ch)) | ||
383 | return (0); | ||
384 | } else { | ||
385 | if (!middlechar(ch)) | ||
386 | return (0); | ||
387 | } | ||
388 | pch = ch, ch = nch; | ||
389 | } | ||
390 | return (1); | ||
391 | } | ||
392 | |||
393 | /* | ||
394 | * hostname-like (A, MX, WKS) owners can have "*" as their first label | ||
395 | * but must otherwise be as a host name. | ||
396 | */ | ||
397 | int | ||
398 | res_ownok(dn) | ||
399 | const char *dn; | ||
400 | { | ||
401 | if (asterchar(dn[0])) { | ||
402 | if (periodchar(dn[1])) | ||
403 | return (res_hnok(dn+2)); | ||
404 | if (dn[1] == '\0') | ||
405 | return (1); | ||
406 | } | ||
407 | return (res_hnok(dn)); | ||
408 | } | ||
409 | |||
410 | /* | ||
411 | * SOA RNAMEs and RP RNAMEs can have any printable character in their first | ||
412 | * label, but the rest of the name has to look like a host name. | ||
413 | */ | ||
414 | int | ||
415 | res_mailok(dn) | ||
416 | const char *dn; | ||
417 | { | ||
418 | int ch, escaped = 0; | ||
419 | |||
420 | /* "." is a valid missing representation */ | ||
421 | if (*dn == '\0') | ||
422 | return(1); | ||
423 | |||
424 | /* otherwise <label>.<hostname> */ | ||
425 | while ((ch = *dn++) != '\0') { | ||
426 | if (!domainchar(ch)) | ||
427 | return (0); | ||
428 | if (!escaped && periodchar(ch)) | ||
429 | break; | ||
430 | if (escaped) | ||
431 | escaped = 0; | ||
432 | else if (bslashchar(ch)) | ||
433 | escaped = 1; | ||
434 | } | ||
435 | if (periodchar(ch)) | ||
436 | return (res_hnok(dn)); | ||
437 | return(0); | ||
438 | } | ||
439 | |||
440 | /* | ||
441 | * This function is quite liberal, since RFC 1034's character sets are only | ||
442 | * recommendations. | ||
443 | */ | ||
444 | int | ||
445 | res_dnok(dn) | ||
446 | const char *dn; | ||
447 | { | ||
448 | int ch; | ||
449 | |||
450 | while ((ch = *dn++) != '\0') | ||
451 | if (!domainchar(ch)) | ||
452 | return (0); | ||
453 | return (1); | ||
454 | } | ||
455 | |||
456 | /* | ||
457 | * Routines to insert/extract short/long's. | ||
458 | */ | ||
459 | |||
460 | u_int16_t | ||
461 | _getshort(msgp) | ||
462 | register const u_char *msgp; | ||
463 | { | ||
464 | register u_int16_t u; | ||
465 | |||
466 | GETSHORT(u, msgp); | ||
467 | return (u); | ||
468 | } | ||
469 | |||
470 | #ifdef NeXT | ||
471 | /* | ||
472 | * nExt machines have some funky library conventions, which we must maintain. | ||
473 | */ | ||
474 | u_int16_t | ||
475 | res_getshort(msgp) | ||
476 | register const u_char *msgp; | ||
477 | { | ||
478 | return (_getshort(msgp)); | ||
479 | } | ||
480 | #endif | ||
481 | |||
482 | u_int32_t | ||
483 | _getlong(msgp) | ||
484 | register const u_char *msgp; | ||
485 | { | ||
486 | register u_int32_t u; | ||
487 | |||
488 | GETLONG(u, msgp); | ||
489 | return (u); | ||
490 | } | ||
491 | |||
492 | void | ||
493 | #if defined(__STDC__) || defined(__cplusplus) | ||
494 | __putshort(register u_int16_t s, register u_char *msgp) /* must match proto */ | ||
495 | #else | ||
496 | __putshort(s, msgp) | ||
497 | register u_int16_t s; | ||
498 | register u_char *msgp; | ||
499 | #endif | ||
500 | { | ||
501 | PUTSHORT(s, msgp); | ||
502 | } | ||
503 | |||
504 | void | ||
505 | __putlong(l, msgp) | ||
506 | register u_int32_t l; | ||
507 | register u_char *msgp; | ||
508 | { | ||
509 | PUTLONG(l, msgp); | ||
510 | } | ||
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 new file mode 100644 index 0000000000..c2725395a0 --- /dev/null +++ b/src/lib/libc/net/res_debug.c | |||
@@ -0,0 +1,1518 @@ | |||
1 | /* $OpenBSD: res_debug.c,v 1.9 1998/03/19 00:30:06 millert Exp $ */ | ||
2 | |||
3 | /* | ||
4 | * ++Copyright++ 1985, 1990, 1993 | ||
5 | * - | ||
6 | * Copyright (c) 1985, 1990, 1993 | ||
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 | * 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. | ||
77 | * --Copyright-- | ||
78 | */ | ||
79 | |||
80 | #if defined(LIBC_SCCS) && !defined(lint) | ||
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.9 1998/03/19 00:30:06 millert Exp $"; | ||
86 | #endif | ||
87 | #endif /* LIBC_SCCS and not lint */ | ||
88 | |||
89 | #include <sys/param.h> | ||
90 | #include <sys/types.h> | ||
91 | #include <sys/socket.h> | ||
92 | #include <netinet/in.h> | ||
93 | #include <arpa/inet.h> | ||
94 | #include <arpa/nameser.h> | ||
95 | |||
96 | #include <ctype.h> | ||
97 | #include <netdb.h> | ||
98 | #include <resolv.h> | ||
99 | #include <stdio.h> | ||
100 | #include <time.h> | ||
101 | |||
102 | #include <stdlib.h> | ||
103 | #include <string.h> | ||
104 | |||
105 | extern const char *_res_opcodes[]; | ||
106 | extern const char *_res_resultcodes[]; | ||
107 | |||
108 | /* XXX: we should use getservbyport() instead. */ | ||
109 | static const char * | ||
110 | dewks(wks) | ||
111 | int wks; | ||
112 | { | ||
113 | static char nbuf[20]; | ||
114 | |||
115 | switch (wks) { | ||
116 | case 5: return "rje"; | ||
117 | case 7: return "echo"; | ||
118 | case 9: return "discard"; | ||
119 | case 11: return "systat"; | ||
120 | case 13: return "daytime"; | ||
121 | case 15: return "netstat"; | ||
122 | case 17: return "qotd"; | ||
123 | case 19: return "chargen"; | ||
124 | case 20: return "ftp-data"; | ||
125 | case 21: return "ftp"; | ||
126 | case 23: return "telnet"; | ||
127 | case 25: return "smtp"; | ||
128 | case 37: return "time"; | ||
129 | case 39: return "rlp"; | ||
130 | case 42: return "name"; | ||
131 | case 43: return "whois"; | ||
132 | case 53: return "domain"; | ||
133 | case 57: return "apts"; | ||
134 | case 59: return "apfs"; | ||
135 | case 67: return "bootps"; | ||
136 | case 68: return "bootpc"; | ||
137 | case 69: return "tftp"; | ||
138 | case 77: return "rje"; | ||
139 | case 79: return "finger"; | ||
140 | case 87: return "link"; | ||
141 | case 95: return "supdup"; | ||
142 | case 100: return "newacct"; | ||
143 | case 101: return "hostnames"; | ||
144 | case 102: return "iso-tsap"; | ||
145 | case 103: return "x400"; | ||
146 | case 104: return "x400-snd"; | ||
147 | case 105: return "csnet-ns"; | ||
148 | case 109: return "pop-2"; | ||
149 | case 111: return "sunrpc"; | ||
150 | case 113: return "auth"; | ||
151 | case 115: return "sftp"; | ||
152 | case 117: return "uucp-path"; | ||
153 | case 119: return "nntp"; | ||
154 | case 121: return "erpc"; | ||
155 | case 123: return "ntp"; | ||
156 | case 133: return "statsrv"; | ||
157 | case 136: return "profile"; | ||
158 | case 144: return "NeWS"; | ||
159 | case 161: return "snmp"; | ||
160 | case 162: return "snmp-trap"; | ||
161 | case 170: return "print-srv"; | ||
162 | default: (void) sprintf(nbuf, "%d", wks); return (nbuf); | ||
163 | } | ||
164 | } | ||
165 | |||
166 | /* XXX: we should use getprotobynumber() instead. */ | ||
167 | static const char * | ||
168 | deproto(protonum) | ||
169 | int protonum; | ||
170 | { | ||
171 | static char nbuf[20]; | ||
172 | |||
173 | switch (protonum) { | ||
174 | case 1: return "icmp"; | ||
175 | case 2: return "igmp"; | ||
176 | case 3: return "ggp"; | ||
177 | case 5: return "st"; | ||
178 | case 6: return "tcp"; | ||
179 | case 7: return "ucl"; | ||
180 | case 8: return "egp"; | ||
181 | case 9: return "igp"; | ||
182 | case 11: return "nvp-II"; | ||
183 | case 12: return "pup"; | ||
184 | case 16: return "chaos"; | ||
185 | case 17: return "udp"; | ||
186 | default: (void) sprintf(nbuf, "%d", protonum); return (nbuf); | ||
187 | } | ||
188 | } | ||
189 | |||
190 | static const u_char * | ||
191 | do_rrset(msg, len, cp, cnt, pflag, file, hs) | ||
192 | int cnt, pflag, len; | ||
193 | const u_char *cp, *msg; | ||
194 | const char *hs; | ||
195 | FILE *file; | ||
196 | { | ||
197 | int n; | ||
198 | int sflag; | ||
199 | |||
200 | /* | ||
201 | * Print answer records. | ||
202 | */ | ||
203 | sflag = (_res.pfcode & pflag); | ||
204 | if ((n = ntohs(cnt))) { | ||
205 | if ((!_res.pfcode) || | ||
206 | ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) | ||
207 | fprintf(file, hs); | ||
208 | while (--n >= 0) { | ||
209 | if ((!_res.pfcode) || sflag) { | ||
210 | cp = p_rr(cp, msg, file); | ||
211 | } else { | ||
212 | unsigned int dlen; | ||
213 | cp += __dn_skipname(cp, cp + MAXCDNAME); | ||
214 | cp += INT16SZ; | ||
215 | cp += INT16SZ; | ||
216 | cp += INT32SZ; | ||
217 | dlen = _getshort((u_char*)cp); | ||
218 | cp += INT16SZ; | ||
219 | cp += dlen; | ||
220 | } | ||
221 | if ((cp - msg) > len) | ||
222 | return (NULL); | ||
223 | } | ||
224 | if ((!_res.pfcode) || | ||
225 | ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) | ||
226 | putc('\n', file); | ||
227 | } | ||
228 | return (cp); | ||
229 | } | ||
230 | |||
231 | void | ||
232 | __p_query(msg) | ||
233 | const u_char *msg; | ||
234 | { | ||
235 | __fp_query(msg, stdout); | ||
236 | } | ||
237 | |||
238 | /* | ||
239 | * Print the current options. | ||
240 | * This is intended to be primarily a debugging routine. | ||
241 | */ | ||
242 | void | ||
243 | __fp_resstat(statp, file) | ||
244 | struct __res_state *statp; | ||
245 | FILE *file; | ||
246 | { | ||
247 | register u_long mask; | ||
248 | |||
249 | fprintf(file, ";; res options:"); | ||
250 | if (!statp) | ||
251 | statp = &_res; | ||
252 | for (mask = 1; mask != 0; mask <<= 1) | ||
253 | if (statp->options & mask) | ||
254 | fprintf(file, " %s", p_option(mask)); | ||
255 | putc('\n', file); | ||
256 | } | ||
257 | |||
258 | /* | ||
259 | * Print the contents of a query. | ||
260 | * This is intended to be primarily a debugging routine. | ||
261 | */ | ||
262 | void | ||
263 | __fp_nquery(msg, len, file) | ||
264 | const u_char *msg; | ||
265 | int len; | ||
266 | FILE *file; | ||
267 | { | ||
268 | register const u_char *cp, *endMark; | ||
269 | register const HEADER *hp; | ||
270 | register int n; | ||
271 | |||
272 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) | ||
273 | return; | ||
274 | |||
275 | #define TruncTest(x) if (x > endMark) goto trunc | ||
276 | #define ErrorTest(x) if (x == NULL) goto error | ||
277 | |||
278 | /* | ||
279 | * Print header fields. | ||
280 | */ | ||
281 | hp = (HEADER *)msg; | ||
282 | cp = msg + HFIXEDSZ; | ||
283 | endMark = msg + len; | ||
284 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) { | ||
285 | fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d", | ||
286 | _res_opcodes[hp->opcode], | ||
287 | _res_resultcodes[hp->rcode], | ||
288 | ntohs(hp->id)); | ||
289 | putc('\n', file); | ||
290 | } | ||
291 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX)) | ||
292 | putc(';', file); | ||
293 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) { | ||
294 | fprintf(file, "; flags:"); | ||
295 | if (hp->qr) | ||
296 | fprintf(file, " qr"); | ||
297 | if (hp->aa) | ||
298 | fprintf(file, " aa"); | ||
299 | if (hp->tc) | ||
300 | fprintf(file, " tc"); | ||
301 | if (hp->rd) | ||
302 | fprintf(file, " rd"); | ||
303 | if (hp->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"); | ||
311 | } | ||
312 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) { | ||
313 | fprintf(file, "; Ques: %d", ntohs(hp->qdcount)); | ||
314 | fprintf(file, ", Ans: %d", ntohs(hp->ancount)); | ||
315 | fprintf(file, ", Auth: %d", ntohs(hp->nscount)); | ||
316 | fprintf(file, ", Addit: %d", ntohs(hp->arcount)); | ||
317 | } | ||
318 | if ((!_res.pfcode) || (_res.pfcode & | ||
319 | (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) { | ||
320 | putc('\n',file); | ||
321 | } | ||
322 | /* | ||
323 | * Print question records. | ||
324 | */ | ||
325 | if ((n = ntohs(hp->qdcount))) { | ||
326 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) | ||
327 | fprintf(file, ";; QUESTIONS:\n"); | ||
328 | while (--n >= 0) { | ||
329 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) | ||
330 | fprintf(file, ";;\t"); | ||
331 | TruncTest(cp); | ||
332 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) | ||
333 | cp = p_cdnname(cp, msg, len, file); | ||
334 | else { | ||
335 | int n; | ||
336 | char name[MAXDNAME]; | ||
337 | |||
338 | if ((n = dn_expand(msg, msg+len, cp, name, | ||
339 | sizeof name)) < 0) | ||
340 | cp = NULL; | ||
341 | else | ||
342 | cp += n; | ||
343 | } | ||
344 | ErrorTest(cp); | ||
345 | TruncTest(cp); | ||
346 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) | ||
347 | fprintf(file, ", type = %s", | ||
348 | __p_type(_getshort((u_char*)cp))); | ||
349 | cp += INT16SZ; | ||
350 | TruncTest(cp); | ||
351 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) | ||
352 | fprintf(file, ", class = %s\n", | ||
353 | __p_class(_getshort((u_char*)cp))); | ||
354 | cp += INT16SZ; | ||
355 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) | ||
356 | putc('\n', file); | ||
357 | } | ||
358 | } | ||
359 | /* | ||
360 | * Print authoritative answer records | ||
361 | */ | ||
362 | TruncTest(cp); | ||
363 | cp = do_rrset(msg, len, cp, hp->ancount, RES_PRF_ANS, file, | ||
364 | ";; ANSWERS:\n"); | ||
365 | ErrorTest(cp); | ||
366 | |||
367 | /* | ||
368 | * print name server records | ||
369 | */ | ||
370 | TruncTest(cp); | ||
371 | cp = do_rrset(msg, len, cp, hp->nscount, RES_PRF_AUTH, file, | ||
372 | ";; AUTHORITY RECORDS:\n"); | ||
373 | ErrorTest(cp); | ||
374 | |||
375 | TruncTest(cp); | ||
376 | /* | ||
377 | * print additional records | ||
378 | */ | ||
379 | cp = do_rrset(msg, len, cp, hp->arcount, RES_PRF_ADD, file, | ||
380 | ";; ADDITIONAL RECORDS:\n"); | ||
381 | ErrorTest(cp); | ||
382 | return; | ||
383 | trunc: | ||
384 | fprintf(file, "\n;; ...truncated\n"); | ||
385 | return; | ||
386 | error: | ||
387 | fprintf(file, "\n;; ...malformed\n"); | ||
388 | } | ||
389 | |||
390 | void | ||
391 | __fp_query(msg, file) | ||
392 | const u_char *msg; | ||
393 | FILE *file; | ||
394 | { | ||
395 | fp_nquery(msg, PACKETSZ, file); | ||
396 | } | ||
397 | |||
398 | const u_char * | ||
399 | __p_cdnname(cp, msg, len, file) | ||
400 | const u_char *cp, *msg; | ||
401 | int len; | ||
402 | FILE *file; | ||
403 | { | ||
404 | char name[MAXDNAME]; | ||
405 | int n; | ||
406 | |||
407 | if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0) | ||
408 | return (NULL); | ||
409 | if (name[0] == '\0') | ||
410 | putc('.', file); | ||
411 | else | ||
412 | fputs(name, file); | ||
413 | return (cp + n); | ||
414 | } | ||
415 | |||
416 | const u_char * | ||
417 | __p_cdname(cp, msg, file) | ||
418 | const u_char *cp, *msg; | ||
419 | FILE *file; | ||
420 | { | ||
421 | return (p_cdnname(cp, msg, PACKETSZ, file)); | ||
422 | } | ||
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 | } | ||
446 | return (cp + n); | ||
447 | } | ||
448 | |||
449 | /* XXX: the rest of these functions need to become length-limited, too. (vix) | ||
450 | */ | ||
451 | |||
452 | const u_char * | ||
453 | __p_fqname(cp, msg, file) | ||
454 | const u_char *cp, *msg; | ||
455 | FILE *file; | ||
456 | { | ||
457 | char name[MAXDNAME]; | ||
458 | const u_char *n; | ||
459 | |||
460 | n = __p_fqnname(cp, msg, MAXCDNAME, name, sizeof name); | ||
461 | if (n == NULL) | ||
462 | return (NULL); | ||
463 | fputs(name, file); | ||
464 | return (n); | ||
465 | } | ||
466 | |||
467 | /* | ||
468 | * Print resource record fields in human readable form. | ||
469 | */ | ||
470 | const u_char * | ||
471 | __p_rr(cp, msg, file) | ||
472 | const u_char *cp, *msg; | ||
473 | FILE *file; | ||
474 | { | ||
475 | int type, class, dlen, n, c; | ||
476 | struct in_addr inaddr; | ||
477 | const u_char *cp1, *cp2; | ||
478 | u_int32_t tmpttl, t; | ||
479 | int lcnt; | ||
480 | u_int16_t keyflags; | ||
481 | char rrname[MAXDNAME]; /* The fqdn of this RR */ | ||
482 | char base64_key[MAX_KEY_BASE64]; | ||
483 | |||
484 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) { | ||
485 | h_errno = NETDB_INTERNAL; | ||
486 | return (NULL); | ||
487 | } | ||
488 | cp = __p_fqnname(cp, msg, MAXCDNAME, rrname, sizeof rrname); | ||
489 | if (!cp) | ||
490 | return (NULL); /* compression error */ | ||
491 | fputs(rrname, file); | ||
492 | |||
493 | type = _getshort((u_char*)cp); | ||
494 | cp += INT16SZ; | ||
495 | class = _getshort((u_char*)cp); | ||
496 | cp += INT16SZ; | ||
497 | tmpttl = _getlong((u_char*)cp); | ||
498 | cp += INT32SZ; | ||
499 | dlen = _getshort((u_char*)cp); | ||
500 | cp += INT16SZ; | ||
501 | cp1 = cp; | ||
502 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID)) | ||
503 | fprintf(file, "\t%lu", (u_long)tmpttl); | ||
504 | if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS)) | ||
505 | fprintf(file, "\t%s", __p_class(class)); | ||
506 | fprintf(file, "\t%s", __p_type(type)); | ||
507 | /* | ||
508 | * Print type specific data, if appropriate | ||
509 | */ | ||
510 | switch (type) { | ||
511 | case T_A: | ||
512 | switch (class) { | ||
513 | case C_IN: | ||
514 | case C_HS: | ||
515 | bcopy(cp, (char *)&inaddr, INADDRSZ); | ||
516 | if (dlen == 4) { | ||
517 | fprintf(file, "\t%s", inet_ntoa(inaddr)); | ||
518 | cp += dlen; | ||
519 | } else if (dlen == 7) { | ||
520 | char *address; | ||
521 | u_char protocol; | ||
522 | in_port_t port; | ||
523 | |||
524 | address = inet_ntoa(inaddr); | ||
525 | cp += INADDRSZ; | ||
526 | protocol = *(u_char*)cp; | ||
527 | cp += sizeof (u_char); | ||
528 | port = _getshort((u_char*)cp); | ||
529 | cp += INT16SZ; | ||
530 | fprintf(file, "\t%s\t; proto %d, port %d", | ||
531 | address, protocol, port); | ||
532 | } | ||
533 | break; | ||
534 | default: | ||
535 | cp += dlen; | ||
536 | } | ||
537 | break; | ||
538 | case T_CNAME: | ||
539 | case T_MB: | ||
540 | case T_MG: | ||
541 | case T_MR: | ||
542 | case T_NS: | ||
543 | case T_PTR: | ||
544 | putc('\t', file); | ||
545 | if ((cp = p_fqname(cp, msg, file)) == NULL) | ||
546 | return (NULL); | ||
547 | break; | ||
548 | |||
549 | case T_HINFO: | ||
550 | case T_ISDN: | ||
551 | cp2 = cp + dlen; | ||
552 | (void) fputs("\t\"", file); | ||
553 | if ((n = (unsigned char) *cp++) != 0) { | ||
554 | for (c = n; c > 0 && cp < cp2; c--) { | ||
555 | if (strchr("\n\"\\", *cp)) | ||
556 | (void) putc('\\', file); | ||
557 | (void) putc(*cp++, file); | ||
558 | } | ||
559 | } | ||
560 | putc('"', file); | ||
561 | if (cp < cp2 && (n = (unsigned char) *cp++) != 0) { | ||
562 | (void) fputs ("\t\"", file); | ||
563 | for (c = n; c > 0 && cp < cp2; c--) { | ||
564 | if (strchr("\n\"\\", *cp)) | ||
565 | (void) putc('\\', file); | ||
566 | (void) putc(*cp++, file); | ||
567 | } | ||
568 | putc('"', file); | ||
569 | } else if (type == T_HINFO) { | ||
570 | (void) fputs("\"?\"", file); | ||
571 | fprintf(file, "\n;; *** Warning *** OS-type missing"); | ||
572 | } | ||
573 | break; | ||
574 | |||
575 | case T_SOA: | ||
576 | putc('\t', file); | ||
577 | if ((cp = p_fqname(cp, msg, file)) == NULL) | ||
578 | return (NULL); | ||
579 | putc(' ', file); | ||
580 | if ((cp = p_fqname(cp, msg, file)) == NULL) | ||
581 | return (NULL); | ||
582 | fputs(" (\n", file); | ||
583 | t = _getlong((u_char*)cp); cp += INT32SZ; | ||
584 | fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t); | ||
585 | t = _getlong((u_char*)cp); cp += INT32SZ; | ||
586 | fprintf(file, "\t\t\t%lu\t; refresh (%s)\n", | ||
587 | (u_long)t, __p_time(t)); | ||
588 | t = _getlong((u_char*)cp); cp += INT32SZ; | ||
589 | fprintf(file, "\t\t\t%lu\t; retry (%s)\n", | ||
590 | (u_long)t, __p_time(t)); | ||
591 | t = _getlong((u_char*)cp); cp += INT32SZ; | ||
592 | fprintf(file, "\t\t\t%lu\t; expire (%s)\n", | ||
593 | (u_long)t, __p_time(t)); | ||
594 | t = _getlong((u_char*)cp); cp += INT32SZ; | ||
595 | fprintf(file, "\t\t\t%lu )\t; minimum (%s)", | ||
596 | (u_long)t, __p_time(t)); | ||
597 | break; | ||
598 | |||
599 | case T_MX: | ||
600 | case T_AFSDB: | ||
601 | case T_RT: | ||
602 | fprintf(file, "\t%d ", _getshort((u_char*)cp)); | ||
603 | cp += INT16SZ; | ||
604 | if ((cp = p_fqname(cp, msg, file)) == NULL) | ||
605 | return (NULL); | ||
606 | break; | ||
607 | |||
608 | case T_PX: | ||
609 | fprintf(file, "\t%d ", _getshort((u_char*)cp)); | ||
610 | cp += INT16SZ; | ||
611 | if ((cp = p_fqname(cp, msg, file)) == NULL) | ||
612 | return (NULL); | ||
613 | putc(' ', file); | ||
614 | if ((cp = p_fqname(cp, msg, file)) == NULL) | ||
615 | return (NULL); | ||
616 | break; | ||
617 | |||
618 | case T_X25: | ||
619 | cp2 = cp + dlen; | ||
620 | (void) fputs("\t\"", file); | ||
621 | if ((n = (unsigned char) *cp++) != 0) { | ||
622 | for (c = n; c > 0 && cp < cp2; c--) { | ||
623 | if (strchr("\n\"\\", *cp)) | ||
624 | (void) putc('\\', file); | ||
625 | (void) putc(*cp++, file); | ||
626 | } | ||
627 | } | ||
628 | putc('"', file); | ||
629 | break; | ||
630 | |||
631 | case T_TXT: | ||
632 | (void) putc('\t', file); | ||
633 | cp2 = cp1 + dlen; | ||
634 | while (cp < cp2) { | ||
635 | putc('"', file); | ||
636 | if ((n = (unsigned char) *cp++)) { | ||
637 | for (c = n; c > 0 && cp < cp2; c--) { | ||
638 | if (strchr("\n\"\\", *cp)) | ||
639 | (void) putc('\\', file); | ||
640 | (void) putc(*cp++, file); | ||
641 | } | ||
642 | } | ||
643 | putc('"', file); | ||
644 | if (cp < cp2) | ||
645 | putc(' ', file); | ||
646 | } | ||
647 | break; | ||
648 | |||
649 | case T_NSAP: | ||
650 | (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL)); | ||
651 | cp += dlen; | ||
652 | break; | ||
653 | |||
654 | case T_AAAA: { | ||
655 | char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; | ||
656 | |||
657 | fprintf(file, "\t%s", inet_ntop(AF_INET6, cp, t, sizeof t)); | ||
658 | cp += dlen; | ||
659 | break; | ||
660 | } | ||
661 | |||
662 | case T_LOC: { | ||
663 | char t[255]; | ||
664 | |||
665 | fprintf(file, "\t%s", loc_ntoa(cp, t)); | ||
666 | cp += dlen; | ||
667 | break; | ||
668 | } | ||
669 | |||
670 | case T_NAPTR: { | ||
671 | u_int order, preference; | ||
672 | |||
673 | order = _getshort(cp); cp += INT16SZ; | ||
674 | preference = _getshort(cp); cp += INT16SZ; | ||
675 | fprintf(file, "\t%u %u ",order, preference); | ||
676 | /* Flags */ | ||
677 | n = *cp++; | ||
678 | fprintf(file,"\"%.*s\" ", (int)n, cp); | ||
679 | cp += n; | ||
680 | /* Service */ | ||
681 | n = *cp++; | ||
682 | fprintf(file,"\"%.*s\" ", (int)n, cp); | ||
683 | cp += n; | ||
684 | /* Regexp */ | ||
685 | n = *cp++; | ||
686 | fprintf(file,"\"%.*s\" ", (int)n, cp); | ||
687 | cp += n; | ||
688 | if ((cp = p_fqname(cp, msg, file)) == NULL) | ||
689 | return (NULL); | ||
690 | break; | ||
691 | } | ||
692 | |||
693 | case T_SRV: { | ||
694 | u_int priority, weight, port; | ||
695 | |||
696 | priority = _getshort(cp); cp += INT16SZ; | ||
697 | weight = _getshort(cp); cp += INT16SZ; | ||
698 | port = _getshort(cp); cp += INT16SZ; | ||
699 | fprintf(file, "\t%u %u %u ", priority, weight, port); | ||
700 | if ((cp = p_fqname(cp, msg, file)) == NULL) | ||
701 | return (NULL); | ||
702 | break; | ||
703 | } | ||
704 | |||
705 | case T_MINFO: | ||
706 | case T_RP: | ||
707 | putc('\t', file); | ||
708 | if ((cp = p_fqname(cp, msg, file)) == NULL) | ||
709 | return (NULL); | ||
710 | putc(' ', file); | ||
711 | if ((cp = p_fqname(cp, msg, file)) == NULL) | ||
712 | return (NULL); | ||
713 | break; | ||
714 | |||
715 | case T_UINFO: | ||
716 | putc('\t', file); | ||
717 | fputs((char *)cp, file); | ||
718 | cp += dlen; | ||
719 | break; | ||
720 | |||
721 | case T_UID: | ||
722 | case T_GID: | ||
723 | if (dlen == 4) { | ||
724 | fprintf(file, "\t%u", _getlong((u_char*)cp)); | ||
725 | cp += INT32SZ; | ||
726 | } | ||
727 | break; | ||
728 | |||
729 | case T_WKS: | ||
730 | if (dlen < INT32SZ + 1) | ||
731 | break; | ||
732 | bcopy(cp, (char *)&inaddr, INADDRSZ); | ||
733 | cp += INT32SZ; | ||
734 | fprintf(file, "\t%s %s ( ", | ||
735 | inet_ntoa(inaddr), | ||
736 | deproto((int) *cp)); | ||
737 | cp += sizeof (u_char); | ||
738 | n = 0; | ||
739 | lcnt = 0; | ||
740 | while (cp < cp1 + dlen) { | ||
741 | c = *cp++; | ||
742 | do { | ||
743 | if (c & 0200) { | ||
744 | if (lcnt == 0) { | ||
745 | fputs("\n\t\t\t", file); | ||
746 | lcnt = 5; | ||
747 | } | ||
748 | fputs(dewks(n), file); | ||
749 | putc(' ', file); | ||
750 | lcnt--; | ||
751 | } | ||
752 | c <<= 1; | ||
753 | } while (++n & 07); | ||
754 | } | ||
755 | putc(')', file); | ||
756 | break; | ||
757 | |||
758 | case T_KEY: | ||
759 | putc('\t', file); | ||
760 | keyflags = _getshort(cp); | ||
761 | cp += 2; | ||
762 | fprintf(file,"0x%04x", keyflags ); /* flags */ | ||
763 | fprintf(file," %u", *cp++); /* protocol */ | ||
764 | fprintf(file," %u (", *cp++); /* algorithm */ | ||
765 | |||
766 | n = b64_ntop(cp, (cp1 + dlen) - cp, | ||
767 | base64_key, sizeof base64_key); | ||
768 | for (c = 0; c < n; ++c) { | ||
769 | if (0 == (c & 0x3F)) | ||
770 | fprintf(file, "\n\t"); | ||
771 | putc(base64_key[c], file); /* public key data */ | ||
772 | } | ||
773 | |||
774 | fprintf(file, " )"); | ||
775 | if (n < 0) | ||
776 | fprintf(file, "\t; BAD BASE64"); | ||
777 | fflush(file); | ||
778 | cp = cp1 + dlen; | ||
779 | break; | ||
780 | |||
781 | case T_SIG: | ||
782 | type = _getshort((u_char*)cp); | ||
783 | cp += INT16SZ; | ||
784 | fprintf(file, " %s", p_type(type)); | ||
785 | fprintf(file, "\t%d", *cp++); /* algorithm */ | ||
786 | /* Check label value and print error if wrong. */ | ||
787 | n = *cp++; | ||
788 | c = dn_count_labels (rrname); | ||
789 | if (n != c) | ||
790 | fprintf(file, "\t; LABELS WRONG (%d should be %d)\n\t", | ||
791 | n, c); | ||
792 | /* orig ttl */ | ||
793 | n = _getlong((u_char*)cp); | ||
794 | if (n != tmpttl) | ||
795 | fprintf(file, " %u", n); | ||
796 | cp += INT32SZ; | ||
797 | /* sig expire */ | ||
798 | fprintf(file, " (\n\t%s", | ||
799 | __p_secstodate(_getlong((u_char*)cp))); | ||
800 | cp += INT32SZ; | ||
801 | /* time signed */ | ||
802 | fprintf(file, " %s", __p_secstodate(_getlong((u_char*)cp))); | ||
803 | cp += INT32SZ; | ||
804 | /* sig footprint */ | ||
805 | fprintf(file," %u ", _getshort((u_char*)cp)); | ||
806 | cp += INT16SZ; | ||
807 | /* signer's name */ | ||
808 | cp = p_fqname(cp, msg, file); | ||
809 | n = b64_ntop(cp, (cp1 + dlen) - cp, | ||
810 | base64_key, sizeof base64_key); | ||
811 | for (c = 0; c < n; c++) { | ||
812 | if (0 == (c & 0x3F)) | ||
813 | fprintf (file, "\n\t"); | ||
814 | putc(base64_key[c], file); /* signature */ | ||
815 | } | ||
816 | /* Clean up... */ | ||
817 | fprintf(file, " )"); | ||
818 | if (n < 0) | ||
819 | fprintf(file, "\t; BAD BASE64"); | ||
820 | fflush(file); | ||
821 | cp = cp1+dlen; | ||
822 | break; | ||
823 | |||
824 | #ifdef ALLOW_T_UNSPEC | ||
825 | case T_UNSPEC: | ||
826 | { | ||
827 | int NumBytes = 8; | ||
828 | u_char *DataPtr; | ||
829 | int i; | ||
830 | |||
831 | if (dlen < NumBytes) NumBytes = dlen; | ||
832 | fprintf(file, "\tFirst %d bytes of hex data:", | ||
833 | NumBytes); | ||
834 | for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++) | ||
835 | fprintf(file, " %x", *DataPtr); | ||
836 | cp += dlen; | ||
837 | } | ||
838 | break; | ||
839 | #endif /* ALLOW_T_UNSPEC */ | ||
840 | |||
841 | default: | ||
842 | fprintf(file, "\t?%d?", type); | ||
843 | cp += dlen; | ||
844 | } | ||
845 | #if 0 | ||
846 | fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl)); | ||
847 | #else | ||
848 | putc('\n', file); | ||
849 | #endif | ||
850 | if (cp - cp1 != dlen) { | ||
851 | fprintf(file, ";; packet size error (found %ld, dlen was %d)\n", | ||
852 | (long)(cp - cp1), dlen); | ||
853 | cp = NULL; | ||
854 | } | ||
855 | return (cp); | ||
856 | } | ||
857 | |||
858 | /* | ||
859 | * Names of RR classes and qclasses. Classes and qclasses are the same, except | ||
860 | * that C_ANY is a qclass but not a class. (You can ask for records of class | ||
861 | * C_ANY, but you can't have any records of that class in the database.) | ||
862 | */ | ||
863 | const struct res_sym __p_class_syms[] = { | ||
864 | {C_IN, "IN"}, | ||
865 | {C_CHAOS, "CHAOS"}, | ||
866 | {C_HS, "HS"}, | ||
867 | {C_HS, "HESIOD"}, | ||
868 | {C_ANY, "ANY"}, | ||
869 | {C_IN, (char *)0} | ||
870 | }; | ||
871 | |||
872 | /* | ||
873 | * Names of RR types and qtypes. Types and qtypes are the same, except | ||
874 | * that T_ANY is a qtype but not a type. (You can ask for records of type | ||
875 | * T_ANY, but you can't have any records of that type in the database.) | ||
876 | */ | ||
877 | const struct res_sym __p_type_syms[] = { | ||
878 | {T_A, "A", "address"}, | ||
879 | {T_NS, "NS", "name server"}, | ||
880 | {T_MD, "MD", "mail destination (deprecated)"}, | ||
881 | {T_MF, "MF", "mail forwarder (deprecated)"}, | ||
882 | {T_CNAME, "CNAME", "canonical name"}, | ||
883 | {T_SOA, "SOA", "start of authority"}, | ||
884 | {T_MB, "MB", "mailbox"}, | ||
885 | {T_MG, "MG", "mail group member"}, | ||
886 | {T_MR, "MR", "mail rename"}, | ||
887 | {T_NULL, "NULL", "null"}, | ||
888 | {T_WKS, "WKS", "well-known service (deprecated)"}, | ||
889 | {T_PTR, "PTR", "domain name pointer"}, | ||
890 | {T_HINFO, "HINFO", "host information"}, | ||
891 | {T_MINFO, "MINFO", "mailbox information"}, | ||
892 | {T_MX, "MX", "mail exchanger"}, | ||
893 | {T_TXT, "TXT", "text"}, | ||
894 | {T_RP, "RP", "responsible person"}, | ||
895 | {T_AFSDB, "AFSDB", "DCE or AFS server"}, | ||
896 | {T_X25, "X25", "X25 address"}, | ||
897 | {T_ISDN, "ISDN", "ISDN address"}, | ||
898 | {T_RT, "RT", "router"}, | ||
899 | {T_NSAP, "NSAP", "nsap address"}, | ||
900 | {T_NSAP_PTR, "NSAP_PTR", "domain name pointer"}, | ||
901 | {T_SIG, "SIG", "signature"}, | ||
902 | {T_KEY, "KEY", "key"}, | ||
903 | {T_PX, "PX", "mapping information"}, | ||
904 | {T_GPOS, "GPOS", "geographical position (withdrawn)"}, | ||
905 | {T_AAAA, "AAAA", "IPv6 address"}, | ||
906 | {T_LOC, "LOC", "location"}, | ||
907 | {T_NXT, "NXT", "next valid name (unimplemented)"}, | ||
908 | {T_EID, "EID", "endpoint identifier (unimplemented)"}, | ||
909 | {T_NIMLOC, "NIMLOC", "NIMROD locator (unimplemented)"}, | ||
910 | {T_SRV, "SRV", "server selection"}, | ||
911 | {T_ATMA, "ATMA", "ATM address (unimplemented)"}, | ||
912 | {T_IXFR, "IXFR", "incremental zone transfer"}, | ||
913 | {T_AXFR, "AXFR", "zone transfer"}, | ||
914 | {T_MAILB, "MAILB", "mailbox-related data (deprecated)"}, | ||
915 | {T_MAILA, "MAILA", "mail agent (deprecated)"}, | ||
916 | {T_UINFO, "UINFO", "user information (nonstandard)"}, | ||
917 | {T_UID, "UID", "user ID (nonstandard)"}, | ||
918 | {T_GID, "GID", "group ID (nonstandard)"}, | ||
919 | {T_NAPTR, "NAPTR", "URN Naming Authority"}, | ||
920 | #ifdef ALLOW_T_UNSPEC | ||
921 | {T_UNSPEC, "UNSPEC", "unspecified data (nonstandard)"}, | ||
922 | #endif /* ALLOW_T_UNSPEC */ | ||
923 | {T_ANY, "ANY", "\"any\""}, | ||
924 | {0, NULL, NULL} | ||
925 | }; | ||
926 | |||
927 | int | ||
928 | __sym_ston(syms, name, success) | ||
929 | const struct res_sym *syms; | ||
930 | char *name; | ||
931 | int *success; | ||
932 | { | ||
933 | for (; syms->name != 0; syms++) { | ||
934 | if (strcasecmp (name, syms->name) == 0) { | ||
935 | if (success) | ||
936 | *success = 1; | ||
937 | return (syms->number); | ||
938 | } | ||
939 | } | ||
940 | if (success) | ||
941 | *success = 0; | ||
942 | return (syms->number); /* The default value. */ | ||
943 | } | ||
944 | |||
945 | const char * | ||
946 | __sym_ntos(syms, number, success) | ||
947 | const struct res_sym *syms; | ||
948 | int number; | ||
949 | int *success; | ||
950 | { | ||
951 | static char unname[20]; | ||
952 | |||
953 | for (; syms->name != 0; syms++) { | ||
954 | if (number == syms->number) { | ||
955 | if (success) | ||
956 | *success = 1; | ||
957 | return (syms->name); | ||
958 | } | ||
959 | } | ||
960 | |||
961 | sprintf (unname, "%d", number); | ||
962 | if (success) | ||
963 | *success = 0; | ||
964 | return (unname); | ||
965 | } | ||
966 | |||
967 | |||
968 | const char * | ||
969 | __sym_ntop(syms, number, success) | ||
970 | const struct res_sym *syms; | ||
971 | int number; | ||
972 | int *success; | ||
973 | { | ||
974 | static char unname[20]; | ||
975 | |||
976 | for (; syms->name != 0; syms++) { | ||
977 | if (number == syms->number) { | ||
978 | if (success) | ||
979 | *success = 1; | ||
980 | return (syms->humanname); | ||
981 | } | ||
982 | } | ||
983 | sprintf(unname, "%d", number); | ||
984 | if (success) | ||
985 | *success = 0; | ||
986 | return (unname); | ||
987 | } | ||
988 | |||
989 | /* | ||
990 | * Return a string for the type | ||
991 | */ | ||
992 | const char * | ||
993 | __p_type(type) | ||
994 | int type; | ||
995 | { | ||
996 | return (__sym_ntos (__p_type_syms, type, (int *)0)); | ||
997 | } | ||
998 | |||
999 | /* | ||
1000 | * Return a mnemonic for class | ||
1001 | */ | ||
1002 | const char * | ||
1003 | __p_class(class) | ||
1004 | int class; | ||
1005 | { | ||
1006 | return (__sym_ntos (__p_class_syms, class, (int *)0)); | ||
1007 | } | ||
1008 | |||
1009 | /* | ||
1010 | * Return a mnemonic for an option | ||
1011 | */ | ||
1012 | const char * | ||
1013 | __p_option(option) | ||
1014 | u_long option; | ||
1015 | { | ||
1016 | static char nbuf[40]; | ||
1017 | |||
1018 | switch (option) { | ||
1019 | case RES_INIT: return "init"; | ||
1020 | case RES_DEBUG: return "debug"; | ||
1021 | case RES_AAONLY: return "aaonly(unimpl)"; | ||
1022 | case RES_USEVC: return "usevc"; | ||
1023 | case RES_PRIMARY: return "primry(unimpl)"; | ||
1024 | case RES_IGNTC: return "igntc"; | ||
1025 | case RES_RECURSE: return "recurs"; | ||
1026 | case RES_DEFNAMES: return "defnam"; | ||
1027 | case RES_STAYOPEN: return "styopn"; | ||
1028 | case RES_DNSRCH: return "dnsrch"; | ||
1029 | case RES_INSECURE1: return "insecure1"; | ||
1030 | case RES_INSECURE2: return "insecure2"; | ||
1031 | default: sprintf(nbuf, "?0x%lx?", (u_long)option); | ||
1032 | return (nbuf); | ||
1033 | } | ||
1034 | } | ||
1035 | |||
1036 | /* | ||
1037 | * Return a mnemonic for a time to live | ||
1038 | */ | ||
1039 | const char * | ||
1040 | p_time(value) | ||
1041 | u_int32_t value; | ||
1042 | { | ||
1043 | static char nbuf[40]; | ||
1044 | int secs, mins, hours, days; | ||
1045 | register char *p; | ||
1046 | |||
1047 | if (value == 0) { | ||
1048 | strcpy(nbuf, "0 secs"); | ||
1049 | return (nbuf); | ||
1050 | } | ||
1051 | |||
1052 | secs = value % 60; | ||
1053 | value /= 60; | ||
1054 | mins = value % 60; | ||
1055 | value /= 60; | ||
1056 | hours = value % 24; | ||
1057 | value /= 24; | ||
1058 | days = value; | ||
1059 | value = 0; | ||
1060 | |||
1061 | #define PLURALIZE(x) x, (x == 1) ? "" : "s" | ||
1062 | p = nbuf; | ||
1063 | if (days) { | ||
1064 | (void)sprintf(p, "%d day%s", PLURALIZE(days)); | ||
1065 | while (*++p); | ||
1066 | } | ||
1067 | if (hours) { | ||
1068 | if (days) | ||
1069 | *p++ = ' '; | ||
1070 | (void)sprintf(p, "%d hour%s", PLURALIZE(hours)); | ||
1071 | while (*++p); | ||
1072 | } | ||
1073 | if (mins) { | ||
1074 | if (days || hours) | ||
1075 | *p++ = ' '; | ||
1076 | (void)sprintf(p, "%d min%s", PLURALIZE(mins)); | ||
1077 | while (*++p); | ||
1078 | } | ||
1079 | if (secs || ! (days || hours || mins)) { | ||
1080 | if (days || hours || mins) | ||
1081 | *p++ = ' '; | ||
1082 | (void)sprintf(p, "%d sec%s", PLURALIZE(secs)); | ||
1083 | } | ||
1084 | return (nbuf); | ||
1085 | } | ||
1086 | |||
1087 | /* | ||
1088 | * routines to convert between on-the-wire RR format and zone file format. | ||
1089 | * Does not contain conversion to/from decimal degrees; divide or multiply | ||
1090 | * by 60*60*1000 for that. | ||
1091 | */ | ||
1092 | |||
1093 | static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000, | ||
1094 | 1000000,10000000,100000000,1000000000}; | ||
1095 | |||
1096 | /* takes an XeY precision/size value, returns a string representation. */ | ||
1097 | static const char * | ||
1098 | precsize_ntoa(prec) | ||
1099 | u_int8_t prec; | ||
1100 | { | ||
1101 | static char retbuf[sizeof "90000000.00"]; | ||
1102 | unsigned long val; | ||
1103 | int mantissa, exponent; | ||
1104 | |||
1105 | mantissa = (int)((prec >> 4) & 0x0f) % 10; | ||
1106 | exponent = (int)((prec >> 0) & 0x0f) % 10; | ||
1107 | |||
1108 | val = mantissa * poweroften[exponent]; | ||
1109 | |||
1110 | (void) sprintf(retbuf, "%ld.%.2ld", val/100, val%100); | ||
1111 | return (retbuf); | ||
1112 | } | ||
1113 | |||
1114 | /* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */ | ||
1115 | static u_int8_t | ||
1116 | precsize_aton(strptr) | ||
1117 | char **strptr; | ||
1118 | { | ||
1119 | unsigned int mval = 0, cmval = 0; | ||
1120 | u_int8_t retval = 0; | ||
1121 | register char *cp; | ||
1122 | register int exponent; | ||
1123 | register int mantissa; | ||
1124 | |||
1125 | cp = *strptr; | ||
1126 | |||
1127 | while (isdigit(*cp)) | ||
1128 | mval = mval * 10 + (*cp++ - '0'); | ||
1129 | |||
1130 | if (*cp == '.') { /* centimeters */ | ||
1131 | cp++; | ||
1132 | if (isdigit(*cp)) { | ||
1133 | cmval = (*cp++ - '0') * 10; | ||
1134 | if (isdigit(*cp)) { | ||
1135 | cmval += (*cp++ - '0'); | ||
1136 | } | ||
1137 | } | ||
1138 | } | ||
1139 | cmval = (mval * 100) + cmval; | ||
1140 | |||
1141 | for (exponent = 0; exponent < 9; exponent++) | ||
1142 | if (cmval < poweroften[exponent+1]) | ||
1143 | break; | ||
1144 | |||
1145 | mantissa = cmval / poweroften[exponent]; | ||
1146 | if (mantissa > 9) | ||
1147 | mantissa = 9; | ||
1148 | |||
1149 | retval = (mantissa << 4) | exponent; | ||
1150 | |||
1151 | *strptr = cp; | ||
1152 | |||
1153 | return (retval); | ||
1154 | } | ||
1155 | |||
1156 | /* converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */ | ||
1157 | static u_int32_t | ||
1158 | latlon2ul(latlonstrptr,which) | ||
1159 | char **latlonstrptr; | ||
1160 | int *which; | ||
1161 | { | ||
1162 | register char *cp; | ||
1163 | u_int32_t retval; | ||
1164 | int deg = 0, min = 0, secs = 0, secsfrac = 0; | ||
1165 | |||
1166 | cp = *latlonstrptr; | ||
1167 | |||
1168 | while (isdigit(*cp)) | ||
1169 | deg = deg * 10 + (*cp++ - '0'); | ||
1170 | |||
1171 | while (isspace(*cp)) | ||
1172 | cp++; | ||
1173 | |||
1174 | if (!(isdigit(*cp))) | ||
1175 | goto fndhemi; | ||
1176 | |||
1177 | while (isdigit(*cp)) | ||
1178 | min = min * 10 + (*cp++ - '0'); | ||
1179 | |||
1180 | while (isspace(*cp)) | ||
1181 | cp++; | ||
1182 | |||
1183 | if (!(isdigit(*cp))) | ||
1184 | goto fndhemi; | ||
1185 | |||
1186 | while (isdigit(*cp)) | ||
1187 | secs = secs * 10 + (*cp++ - '0'); | ||
1188 | |||
1189 | if (*cp == '.') { /* decimal seconds */ | ||
1190 | cp++; | ||
1191 | if (isdigit(*cp)) { | ||
1192 | secsfrac = (*cp++ - '0') * 100; | ||
1193 | if (isdigit(*cp)) { | ||
1194 | secsfrac += (*cp++ - '0') * 10; | ||
1195 | if (isdigit(*cp)) { | ||
1196 | secsfrac += (*cp++ - '0'); | ||
1197 | } | ||
1198 | } | ||
1199 | } | ||
1200 | } | ||
1201 | |||
1202 | while (!isspace(*cp)) /* if any trailing garbage */ | ||
1203 | cp++; | ||
1204 | |||
1205 | while (isspace(*cp)) | ||
1206 | cp++; | ||
1207 | |||
1208 | fndhemi: | ||
1209 | switch (*cp) { | ||
1210 | case 'N': case 'n': | ||
1211 | case 'E': case 'e': | ||
1212 | retval = ((unsigned)1<<31) | ||
1213 | + (((((deg * 60) + min) * 60) + secs) * 1000) | ||
1214 | + secsfrac; | ||
1215 | break; | ||
1216 | case 'S': case 's': | ||
1217 | case 'W': case 'w': | ||
1218 | retval = ((unsigned)1<<31) | ||
1219 | - (((((deg * 60) + min) * 60) + secs) * 1000) | ||
1220 | - secsfrac; | ||
1221 | break; | ||
1222 | default: | ||
1223 | retval = 0; /* invalid value -- indicates error */ | ||
1224 | break; | ||
1225 | } | ||
1226 | |||
1227 | switch (*cp) { | ||
1228 | case 'N': case 'n': | ||
1229 | case 'S': case 's': | ||
1230 | *which = 1; /* latitude */ | ||
1231 | break; | ||
1232 | case 'E': case 'e': | ||
1233 | case 'W': case 'w': | ||
1234 | *which = 2; /* longitude */ | ||
1235 | break; | ||
1236 | default: | ||
1237 | *which = 0; /* error */ | ||
1238 | break; | ||
1239 | } | ||
1240 | |||
1241 | cp++; /* skip the hemisphere */ | ||
1242 | |||
1243 | while (!isspace(*cp)) /* if any trailing garbage */ | ||
1244 | cp++; | ||
1245 | |||
1246 | while (isspace(*cp)) /* move to next field */ | ||
1247 | cp++; | ||
1248 | |||
1249 | *latlonstrptr = cp; | ||
1250 | |||
1251 | return (retval); | ||
1252 | } | ||
1253 | |||
1254 | /* converts a zone file representation in a string to an RDATA on-the-wire | ||
1255 | * representation. */ | ||
1256 | int | ||
1257 | loc_aton(ascii, binary) | ||
1258 | const char *ascii; | ||
1259 | u_char *binary; | ||
1260 | { | ||
1261 | const char *maxcp; | ||
1262 | u_char *bcp; | ||
1263 | char *cp; | ||
1264 | |||
1265 | u_int32_t latit = 0, longit = 0, alt = 0; | ||
1266 | u_int32_t lltemp1 = 0, lltemp2 = 0; | ||
1267 | int altmeters = 0, altfrac = 0, altsign = 1; | ||
1268 | u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */ | ||
1269 | u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */ | ||
1270 | u_int8_t siz = 0x12; /* default = 1e2 cm = 1.00m */ | ||
1271 | int which1 = 0, which2 = 0; | ||
1272 | |||
1273 | cp = (char *)ascii; | ||
1274 | maxcp = cp + strlen(ascii); | ||
1275 | |||
1276 | lltemp1 = latlon2ul(&cp, &which1); | ||
1277 | |||
1278 | lltemp2 = latlon2ul(&cp, &which2); | ||
1279 | |||
1280 | switch (which1 + which2) { | ||
1281 | case 3: /* 1 + 2, the only valid combination */ | ||
1282 | if ((which1 == 1) && (which2 == 2)) { /* normal case */ | ||
1283 | latit = lltemp1; | ||
1284 | longit = lltemp2; | ||
1285 | } else if ((which1 == 2) && (which2 == 1)) { /* reversed */ | ||
1286 | longit = lltemp1; | ||
1287 | latit = lltemp2; | ||
1288 | } else { /* some kind of brokenness */ | ||
1289 | return (0); | ||
1290 | } | ||
1291 | break; | ||
1292 | default: /* we didn't get one of each */ | ||
1293 | return (0); | ||
1294 | } | ||
1295 | |||
1296 | /* altitude */ | ||
1297 | if (*cp == '-') { | ||
1298 | altsign = -1; | ||
1299 | cp++; | ||
1300 | } | ||
1301 | |||
1302 | if (*cp == '+') | ||
1303 | cp++; | ||
1304 | |||
1305 | while (isdigit(*cp)) | ||
1306 | altmeters = altmeters * 10 + (*cp++ - '0'); | ||
1307 | |||
1308 | if (*cp == '.') { /* decimal meters */ | ||
1309 | cp++; | ||
1310 | if (isdigit(*cp)) { | ||
1311 | altfrac = (*cp++ - '0') * 10; | ||
1312 | if (isdigit(*cp)) { | ||
1313 | altfrac += (*cp++ - '0'); | ||
1314 | } | ||
1315 | } | ||
1316 | } | ||
1317 | |||
1318 | alt = (10000000 + (altsign * (altmeters * 100 + altfrac))); | ||
1319 | |||
1320 | while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */ | ||
1321 | cp++; | ||
1322 | |||
1323 | while (isspace(*cp) && (cp < maxcp)) | ||
1324 | cp++; | ||
1325 | |||
1326 | if (cp >= maxcp) | ||
1327 | goto defaults; | ||
1328 | |||
1329 | siz = precsize_aton(&cp); | ||
1330 | |||
1331 | while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */ | ||
1332 | cp++; | ||
1333 | |||
1334 | while (isspace(*cp) && (cp < maxcp)) | ||
1335 | cp++; | ||
1336 | |||
1337 | if (cp >= maxcp) | ||
1338 | goto defaults; | ||
1339 | |||
1340 | hp = precsize_aton(&cp); | ||
1341 | |||
1342 | while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */ | ||
1343 | cp++; | ||
1344 | |||
1345 | while (isspace(*cp) && (cp < maxcp)) | ||
1346 | cp++; | ||
1347 | |||
1348 | if (cp >= maxcp) | ||
1349 | goto defaults; | ||
1350 | |||
1351 | vp = precsize_aton(&cp); | ||
1352 | |||
1353 | defaults: | ||
1354 | |||
1355 | bcp = binary; | ||
1356 | *bcp++ = (u_int8_t) 0; /* version byte */ | ||
1357 | *bcp++ = siz; | ||
1358 | *bcp++ = hp; | ||
1359 | *bcp++ = vp; | ||
1360 | PUTLONG(latit,bcp); | ||
1361 | PUTLONG(longit,bcp); | ||
1362 | PUTLONG(alt,bcp); | ||
1363 | |||
1364 | return (16); /* size of RR in octets */ | ||
1365 | } | ||
1366 | |||
1367 | /* takes an on-the-wire LOC RR and formats it in a human readable format. */ | ||
1368 | const char * | ||
1369 | loc_ntoa(binary, ascii) | ||
1370 | const u_char *binary; | ||
1371 | char *ascii; | ||
1372 | { | ||
1373 | static char *error = "?"; | ||
1374 | register const u_char *cp = binary; | ||
1375 | |||
1376 | int latdeg, latmin, latsec, latsecfrac; | ||
1377 | int longdeg, longmin, longsec, longsecfrac; | ||
1378 | char northsouth, eastwest; | ||
1379 | int altmeters, altfrac, altsign; | ||
1380 | |||
1381 | const int referencealt = 100000 * 100; | ||
1382 | |||
1383 | int32_t latval, longval, altval; | ||
1384 | u_int32_t templ; | ||
1385 | u_int8_t sizeval, hpval, vpval, versionval; | ||
1386 | |||
1387 | char *sizestr, *hpstr, *vpstr; | ||
1388 | |||
1389 | versionval = *cp++; | ||
1390 | |||
1391 | if (versionval) { | ||
1392 | sprintf(ascii, "; error: unknown LOC RR version"); | ||
1393 | return (ascii); | ||
1394 | } | ||
1395 | |||
1396 | sizeval = *cp++; | ||
1397 | |||
1398 | hpval = *cp++; | ||
1399 | vpval = *cp++; | ||
1400 | |||
1401 | GETLONG(templ, cp); | ||
1402 | latval = (templ - ((unsigned)1<<31)); | ||
1403 | |||
1404 | GETLONG(templ, cp); | ||
1405 | longval = (templ - ((unsigned)1<<31)); | ||
1406 | |||
1407 | GETLONG(templ, cp); | ||
1408 | if (templ < referencealt) { /* below WGS 84 spheroid */ | ||
1409 | altval = referencealt - templ; | ||
1410 | altsign = -1; | ||
1411 | } else { | ||
1412 | altval = templ - referencealt; | ||
1413 | altsign = 1; | ||
1414 | } | ||
1415 | |||
1416 | if (latval < 0) { | ||
1417 | northsouth = 'S'; | ||
1418 | latval = -latval; | ||
1419 | } else | ||
1420 | northsouth = 'N'; | ||
1421 | |||
1422 | latsecfrac = latval % 1000; | ||
1423 | latval = latval / 1000; | ||
1424 | latsec = latval % 60; | ||
1425 | latval = latval / 60; | ||
1426 | latmin = latval % 60; | ||
1427 | latval = latval / 60; | ||
1428 | latdeg = latval; | ||
1429 | |||
1430 | if (longval < 0) { | ||
1431 | eastwest = 'W'; | ||
1432 | longval = -longval; | ||
1433 | } else | ||
1434 | eastwest = 'E'; | ||
1435 | |||
1436 | longsecfrac = longval % 1000; | ||
1437 | longval = longval / 1000; | ||
1438 | longsec = longval % 60; | ||
1439 | longval = longval / 60; | ||
1440 | longmin = longval % 60; | ||
1441 | longval = longval / 60; | ||
1442 | longdeg = longval; | ||
1443 | |||
1444 | altfrac = altval % 100; | ||
1445 | altmeters = (altval / 100) * altsign; | ||
1446 | |||
1447 | if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL) | ||
1448 | sizestr = error; | ||
1449 | if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL) | ||
1450 | hpstr = error; | ||
1451 | if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL) | ||
1452 | vpstr = error; | ||
1453 | |||
1454 | sprintf(ascii, | ||
1455 | "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm", | ||
1456 | latdeg, latmin, latsec, latsecfrac, northsouth, | ||
1457 | longdeg, longmin, longsec, longsecfrac, eastwest, | ||
1458 | altmeters, altfrac, sizestr, hpstr, vpstr); | ||
1459 | |||
1460 | if (sizestr != error) | ||
1461 | free(sizestr); | ||
1462 | if (hpstr != error) | ||
1463 | free(hpstr); | ||
1464 | if (vpstr != error) | ||
1465 | free(vpstr); | ||
1466 | |||
1467 | return (ascii); | ||
1468 | } | ||
1469 | |||
1470 | |||
1471 | /* Return the number of DNS hierarchy levels in the name. */ | ||
1472 | int | ||
1473 | __dn_count_labels(name) | ||
1474 | char *name; | ||
1475 | { | ||
1476 | int i, len, count; | ||
1477 | |||
1478 | len = strlen(name); | ||
1479 | |||
1480 | for(i = 0, count = 0; i < len; i++) { | ||
1481 | if (name[i] == '.') | ||
1482 | count++; | ||
1483 | } | ||
1484 | |||
1485 | /* don't count initial wildcard */ | ||
1486 | if (name[0] == '*') | ||
1487 | if (count) | ||
1488 | count--; | ||
1489 | |||
1490 | /* don't count the null label for root. */ | ||
1491 | /* if terminating '.' not found, must adjust */ | ||
1492 | /* count to include last label */ | ||
1493 | if (len > 0 && name[len-1] != '.') | ||
1494 | count++; | ||
1495 | return (count); | ||
1496 | } | ||
1497 | |||
1498 | |||
1499 | /* | ||
1500 | * Make dates expressed in seconds-since-Jan-1-1970 easy to read. | ||
1501 | * SIG records are required to be printed like this, by the Secure DNS RFC. | ||
1502 | */ | ||
1503 | char * | ||
1504 | __p_secstodate (secs) | ||
1505 | unsigned long secs; | ||
1506 | { | ||
1507 | static char output[15]; /* YYYYMMDDHHMMSS and null */ | ||
1508 | time_t clock = secs; | ||
1509 | struct tm *time; | ||
1510 | |||
1511 | time = gmtime(&clock); | ||
1512 | time->tm_year += 1900; | ||
1513 | time->tm_mon += 1; | ||
1514 | sprintf(output, "%04d%02d%02d%02d%02d%02d", | ||
1515 | time->tm_year, time->tm_mon, time->tm_mday, | ||
1516 | time->tm_hour, time->tm_min, time->tm_sec); | ||
1517 | return (output); | ||
1518 | } | ||
diff --git a/src/lib/libc/net/res_init.c b/src/lib/libc/net/res_init.c new file mode 100644 index 0000000000..df176b7fa1 --- /dev/null +++ b/src/lib/libc/net/res_init.c | |||
@@ -0,0 +1,518 @@ | |||
1 | /* $OpenBSD: res_init.c,v 1.16 1998/03/16 05:07:01 millert Exp $ */ | ||
2 | |||
3 | /* | ||
4 | * ++Copyright++ 1985, 1989, 1993 | ||
5 | * - | ||
6 | * Copyright (c) 1985, 1989, 1993 | ||
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 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.16 1998/03/16 05:07:01 millert Exp $"; | ||
64 | #endif | ||
65 | #endif /* LIBC_SCCS and not lint */ | ||
66 | |||
67 | #include <sys/types.h> | ||
68 | #include <sys/param.h> | ||
69 | #include <sys/socket.h> | ||
70 | #include <sys/time.h> | ||
71 | #include <netinet/in.h> | ||
72 | #include <arpa/inet.h> | ||
73 | #include <arpa/nameser.h> | ||
74 | |||
75 | #include <stdio.h> | ||
76 | #include <ctype.h> | ||
77 | #include <resolv.h> | ||
78 | #include <unistd.h> | ||
79 | #include <stdlib.h> | ||
80 | #include <string.h> | ||
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 | |||
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) | ||
110 | static u_int32_t net_mask __P((struct in_addr)); | ||
111 | #endif | ||
112 | |||
113 | /* | ||
114 | * Resolver state default settings. | ||
115 | */ | ||
116 | |||
117 | struct __res_state _res | ||
118 | # if defined(__BIND_RES_TEXT) | ||
119 | = { RES_TIMEOUT, } /* Motorola, et al. */ | ||
120 | # endif | ||
121 | ; | ||
122 | |||
123 | /* | ||
124 | * Set up default settings. If the configuration file exist, the values | ||
125 | * there will have precedence. Otherwise, the server address is set to | ||
126 | * INADDR_ANY and the default domain name comes from the gethostname(). | ||
127 | * | ||
128 | * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1 | ||
129 | * rather than INADDR_ANY ("0.0.0.0") as the default name server address | ||
130 | * since it was noted that INADDR_ANY actually meant ``the first interface | ||
131 | * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface, | ||
132 | * it had to be "up" in order for you to reach your own name server. It | ||
133 | * was later decided that since the recommended practice is to always | ||
134 | * install local static routes through 127.0.0.1 for all your network | ||
135 | * interfaces, that we could solve this problem without a code change. | ||
136 | * | ||
137 | * The configuration file should always be used, since it is the only way | ||
138 | * to specify a default domain. If you are running a server on your local | ||
139 | * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1" | ||
140 | * in the configuration file. | ||
141 | * | ||
142 | * Return 0 if completes successfully, -1 on error | ||
143 | */ | ||
144 | int | ||
145 | res_init() | ||
146 | { | ||
147 | register FILE *fp; | ||
148 | register char *cp, **pp; | ||
149 | register int n; | ||
150 | char buf[BUFSIZ]; | ||
151 | int nserv = 0; /* number of nameserver records read from file */ | ||
152 | int haveenv = 0; | ||
153 | int havesearch = 0; | ||
154 | size_t len; | ||
155 | #ifdef RESOLVSORT | ||
156 | int nsort = 0; | ||
157 | char *net; | ||
158 | #endif | ||
159 | #ifndef RFC1535 | ||
160 | int dots; | ||
161 | #endif | ||
162 | |||
163 | /* | ||
164 | * These three fields used to be statically initialized. This made | ||
165 | * it hard to use this code in a shared library. It is necessary, | ||
166 | * now that we're doing dynamic initialization here, that we preserve | ||
167 | * the old semantics: if an application modifies one of these three | ||
168 | * fields of _res before res_init() is called, res_init() will not | ||
169 | * alter them. Of course, if an application is setting them to | ||
170 | * _zero_ before calling res_init(), hoping to override what used | ||
171 | * to be the static default, we can't detect it and unexpected results | ||
172 | * will follow. Zero for any of these fields would make no sense, | ||
173 | * so one can safely assume that the applications were already getting | ||
174 | * unexpected results. | ||
175 | * | ||
176 | * _res.options is tricky since some apps were known to diddle the bits | ||
177 | * before res_init() was first called. We can't replicate that semantic | ||
178 | * with dynamic initialization (they may have turned bits off that are | ||
179 | * set in RES_DEFAULT). Our solution is to declare such applications | ||
180 | * "broken". They could fool us by setting RES_INIT but none do (yet). | ||
181 | */ | ||
182 | if (!_res.retrans) | ||
183 | _res.retrans = RES_TIMEOUT; | ||
184 | if (!_res.retry) | ||
185 | _res.retry = 4; | ||
186 | if (!(_res.options & RES_INIT)) | ||
187 | _res.options = RES_DEFAULT; | ||
188 | |||
189 | #ifdef USELOOPBACK | ||
190 | _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1); | ||
191 | #else | ||
192 | _res.nsaddr.sin_addr.s_addr = INADDR_ANY; | ||
193 | #endif | ||
194 | _res.nsaddr.sin_family = AF_INET; | ||
195 | _res.nsaddr.sin_port = htons(NAMESERVER_PORT); | ||
196 | _res.nscount = 1; | ||
197 | _res.ndots = 1; | ||
198 | _res.pfcode = 0; | ||
199 | strncpy(_res.lookups, "f", sizeof _res.lookups); | ||
200 | |||
201 | /* Allow user to override the local domain definition */ | ||
202 | if (issetugid() == 0 && (cp = getenv("LOCALDOMAIN")) != NULL) { | ||
203 | (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); | ||
204 | _res.defdname[sizeof(_res.defdname) - 1] = '\0'; | ||
205 | haveenv++; | ||
206 | |||
207 | /* | ||
208 | * Set search list to be blank-separated strings | ||
209 | * from rest of env value. Permits users of LOCALDOMAIN | ||
210 | * to still have a search list, and anyone to set the | ||
211 | * one that they want to use as an individual (even more | ||
212 | * important now that the rfc1535 stuff restricts searches) | ||
213 | */ | ||
214 | cp = _res.defdname; | ||
215 | pp = _res.dnsrch; | ||
216 | *pp++ = cp; | ||
217 | for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { | ||
218 | if (*cp == '\n') /* silly backwards compat */ | ||
219 | break; | ||
220 | else if (*cp == ' ' || *cp == '\t') { | ||
221 | *cp = 0; | ||
222 | n = 1; | ||
223 | } else if (n) { | ||
224 | *pp++ = cp; | ||
225 | n = 0; | ||
226 | havesearch = 1; | ||
227 | } | ||
228 | } | ||
229 | /* null terminate last domain if there are excess */ | ||
230 | while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n') | ||
231 | cp++; | ||
232 | *cp = '\0'; | ||
233 | *pp++ = 0; | ||
234 | } | ||
235 | |||
236 | #define MATCH(line, name) \ | ||
237 | (!strncmp(line, name, sizeof(name) - 1) && \ | ||
238 | (line[sizeof(name) - 1] == ' ' || \ | ||
239 | line[sizeof(name) - 1] == '\t')) | ||
240 | |||
241 | if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) { | ||
242 | strncpy(_res.lookups, "bf", sizeof _res.lookups); | ||
243 | |||
244 | /* read the config file */ | ||
245 | buf[0] = '\0'; | ||
246 | while ((cp = fgetln(fp, &len)) != NULL) { | ||
247 | /* skip lines that are too long or zero length */ | ||
248 | if (len >= sizeof(buf) || len == 0) | ||
249 | continue; | ||
250 | (void)memcpy(buf, cp, len); | ||
251 | buf[len] = '\0'; | ||
252 | /* skip comments */ | ||
253 | if ((cp = strpbrk(buf, ";#")) != NULL) | ||
254 | *cp = '\0'; | ||
255 | if (buf[0] == '\0') | ||
256 | continue; | ||
257 | /* read default domain name */ | ||
258 | if (MATCH(buf, "domain")) { | ||
259 | if (haveenv) /* skip if have from environ */ | ||
260 | continue; | ||
261 | cp = buf + sizeof("domain") - 1; | ||
262 | while (*cp == ' ' || *cp == '\t') | ||
263 | cp++; | ||
264 | if ((*cp == '\0') || (*cp == '\n')) | ||
265 | continue; | ||
266 | strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); | ||
267 | _res.defdname[sizeof(_res.defdname) - 1] = '\0'; | ||
268 | if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL) | ||
269 | *cp = '\0'; | ||
270 | havesearch = 0; | ||
271 | continue; | ||
272 | } | ||
273 | /* lookup types */ | ||
274 | if (MATCH(buf, "lookup")) { | ||
275 | char *sp = NULL; | ||
276 | |||
277 | bzero(_res.lookups, sizeof _res.lookups); | ||
278 | cp = buf + sizeof("lookup") - 1; | ||
279 | for (n = 0;; cp++) { | ||
280 | if (n == MAXDNSLUS) | ||
281 | break; | ||
282 | if ((*cp == '\0') || (*cp == '\n')) { | ||
283 | if (sp) { | ||
284 | if (*sp=='y' || *sp=='b' || *sp=='f') | ||
285 | _res.lookups[n++] = *sp; | ||
286 | sp = NULL; | ||
287 | } | ||
288 | break; | ||
289 | } else if ((*cp == ' ') || (*cp == '\t') || (*cp == ',')) { | ||
290 | if (sp) { | ||
291 | if (*sp=='y' || *sp=='b' || *sp=='f') | ||
292 | _res.lookups[n++] = *sp; | ||
293 | sp = NULL; | ||
294 | } | ||
295 | } else if (sp == NULL) | ||
296 | sp = cp; | ||
297 | } | ||
298 | continue; | ||
299 | } | ||
300 | /* set search list */ | ||
301 | if (MATCH(buf, "search")) { | ||
302 | if (haveenv) /* skip if have from environ */ | ||
303 | continue; | ||
304 | cp = buf + sizeof("search") - 1; | ||
305 | while (*cp == ' ' || *cp == '\t') | ||
306 | cp++; | ||
307 | if ((*cp == '\0') || (*cp == '\n')) | ||
308 | continue; | ||
309 | strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); | ||
310 | _res.defdname[sizeof(_res.defdname) - 1] = '\0'; | ||
311 | if ((cp = strchr(_res.defdname, '\n')) != NULL) | ||
312 | *cp = '\0'; | ||
313 | /* | ||
314 | * Set search list to be blank-separated strings | ||
315 | * on rest of line. | ||
316 | */ | ||
317 | cp = _res.defdname; | ||
318 | pp = _res.dnsrch; | ||
319 | *pp++ = cp; | ||
320 | for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { | ||
321 | if (*cp == ' ' || *cp == '\t') { | ||
322 | *cp = 0; | ||
323 | n = 1; | ||
324 | } else if (n) { | ||
325 | *pp++ = cp; | ||
326 | n = 0; | ||
327 | } | ||
328 | } | ||
329 | /* null terminate last domain if there are excess */ | ||
330 | while (*cp != '\0' && *cp != ' ' && *cp != '\t') | ||
331 | cp++; | ||
332 | *cp = '\0'; | ||
333 | *pp++ = 0; | ||
334 | havesearch = 1; | ||
335 | continue; | ||
336 | } | ||
337 | /* read nameservers to query */ | ||
338 | if (MATCH(buf, "nameserver") && nserv < MAXNS) { | ||
339 | struct in_addr a; | ||
340 | |||
341 | cp = buf + sizeof("nameserver") - 1; | ||
342 | while (*cp == ' ' || *cp == '\t') | ||
343 | cp++; | ||
344 | if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) { | ||
345 | _res.nsaddr_list[nserv].sin_addr = a; | ||
346 | _res.nsaddr_list[nserv].sin_family = AF_INET; | ||
347 | _res.nsaddr_list[nserv].sin_port = | ||
348 | htons(NAMESERVER_PORT); | ||
349 | nserv++; | ||
350 | } | ||
351 | continue; | ||
352 | } | ||
353 | #ifdef RESOLVSORT | ||
354 | if (MATCH(buf, "sortlist")) { | ||
355 | struct in_addr a; | ||
356 | |||
357 | cp = buf + sizeof("sortlist") - 1; | ||
358 | while (nsort < MAXRESOLVSORT) { | ||
359 | while (*cp == ' ' || *cp == '\t') | ||
360 | cp++; | ||
361 | if (*cp == '\0' || *cp == '\n' || *cp == ';') | ||
362 | break; | ||
363 | net = cp; | ||
364 | while (*cp && !ISSORTMASK(*cp) && *cp != ';' && | ||
365 | isascii(*cp) && !isspace(*cp)) | ||
366 | cp++; | ||
367 | n = *cp; | ||
368 | *cp = 0; | ||
369 | if (inet_aton(net, &a)) { | ||
370 | _res.sort_list[nsort].addr = a; | ||
371 | if (ISSORTMASK(n)) { | ||
372 | *cp++ = n; | ||
373 | net = cp; | ||
374 | while (*cp && *cp != ';' && | ||
375 | isascii(*cp) && !isspace(*cp)) | ||
376 | cp++; | ||
377 | n = *cp; | ||
378 | *cp = 0; | ||
379 | if (inet_aton(net, &a)) { | ||
380 | _res.sort_list[nsort].mask = a.s_addr; | ||
381 | } else { | ||
382 | _res.sort_list[nsort].mask = | ||
383 | net_mask(_res.sort_list[nsort].addr); | ||
384 | } | ||
385 | } else { | ||
386 | _res.sort_list[nsort].mask = | ||
387 | net_mask(_res.sort_list[nsort].addr); | ||
388 | } | ||
389 | nsort++; | ||
390 | } | ||
391 | *cp = n; | ||
392 | } | ||
393 | continue; | ||
394 | } | ||
395 | #endif | ||
396 | if (MATCH(buf, "options")) { | ||
397 | res_setoptions(buf + sizeof("options") - 1, "conf"); | ||
398 | continue; | ||
399 | } | ||
400 | } | ||
401 | if (nserv > 1) | ||
402 | _res.nscount = nserv; | ||
403 | #ifdef RESOLVSORT | ||
404 | _res.nsort = nsort; | ||
405 | #endif | ||
406 | (void) fclose(fp); | ||
407 | } | ||
408 | if (_res.defdname[0] == 0 && | ||
409 | gethostname(buf, sizeof(_res.defdname) - 1) == 0 && | ||
410 | (cp = strchr(buf, '.')) != NULL) | ||
411 | { | ||
412 | strncpy(_res.defdname, cp + 1, | ||
413 | sizeof(_res.defdname) - 1); | ||
414 | _res.defdname[sizeof(_res.defdname) - 1] = '\0'; | ||
415 | } | ||
416 | |||
417 | /* find components of local domain that might be searched */ | ||
418 | if (havesearch == 0) { | ||
419 | pp = _res.dnsrch; | ||
420 | *pp++ = _res.defdname; | ||
421 | *pp = NULL; | ||
422 | |||
423 | #ifndef RFC1535 | ||
424 | dots = 0; | ||
425 | for (cp = _res.defdname; *cp; cp++) | ||
426 | dots += (*cp == '.'); | ||
427 | |||
428 | cp = _res.defdname; | ||
429 | while (pp < _res.dnsrch + MAXDFLSRCH) { | ||
430 | if (dots < LOCALDOMAINPARTS) | ||
431 | break; | ||
432 | cp = strchr(cp, '.') + 1; /* we know there is one */ | ||
433 | *pp++ = cp; | ||
434 | dots--; | ||
435 | } | ||
436 | *pp = NULL; | ||
437 | #ifdef DEBUG | ||
438 | if (_res.options & RES_DEBUG) { | ||
439 | printf(";; res_init()... default dnsrch list:\n"); | ||
440 | for (pp = _res.dnsrch; *pp; pp++) | ||
441 | printf(";;\t%s\n", *pp); | ||
442 | printf(";;\t..END..\n"); | ||
443 | } | ||
444 | #endif /* DEBUG */ | ||
445 | #endif /* !RFC1535 */ | ||
446 | } | ||
447 | |||
448 | if (issetugid()) | ||
449 | _res.options |= RES_NOALIASES; | ||
450 | else if ((cp = getenv("RES_OPTIONS")) != NULL) | ||
451 | res_setoptions(cp, "env"); | ||
452 | _res.options |= RES_INIT; | ||
453 | return (0); | ||
454 | } | ||
455 | |||
456 | /* ARGSUSED */ | ||
457 | static void | ||
458 | res_setoptions(options, source) | ||
459 | char *options, *source; | ||
460 | { | ||
461 | char *cp = options; | ||
462 | int i; | ||
463 | |||
464 | #ifdef DEBUG | ||
465 | if (_res.options & RES_DEBUG) | ||
466 | printf(";; res_setoptions(\"%s\", \"%s\")...\n", | ||
467 | options, source); | ||
468 | #endif | ||
469 | while (*cp) { | ||
470 | /* skip leading and inner runs of spaces */ | ||
471 | while (*cp == ' ' || *cp == '\t') | ||
472 | cp++; | ||
473 | /* search for and process individual options */ | ||
474 | if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) { | ||
475 | i = atoi(cp + sizeof("ndots:") - 1); | ||
476 | if (i <= RES_MAXNDOTS) | ||
477 | _res.ndots = i; | ||
478 | else | ||
479 | _res.ndots = RES_MAXNDOTS; | ||
480 | #ifdef DEBUG | ||
481 | if (_res.options & RES_DEBUG) | ||
482 | printf(";;\tndots=%d\n", _res.ndots); | ||
483 | #endif | ||
484 | } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) { | ||
485 | #ifdef DEBUG | ||
486 | if (!(_res.options & RES_DEBUG)) { | ||
487 | printf(";; res_setoptions(\"%s\", \"%s\")..\n", | ||
488 | options, source); | ||
489 | _res.options |= RES_DEBUG; | ||
490 | } | ||
491 | printf(";;\tdebug\n"); | ||
492 | #endif | ||
493 | } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) { | ||
494 | _res.options |= RES_USE_INET6; | ||
495 | } else { | ||
496 | /* XXX - print a warning here? */ | ||
497 | } | ||
498 | /* skip to next run of spaces */ | ||
499 | while (*cp && *cp != ' ' && *cp != '\t') | ||
500 | cp++; | ||
501 | } | ||
502 | } | ||
503 | |||
504 | #ifdef RESOLVSORT | ||
505 | /* XXX - should really support CIDR which means explicit masks always. */ | ||
506 | static u_int32_t | ||
507 | net_mask(in) /* XXX - should really use system's version of this */ | ||
508 | struct in_addr in; | ||
509 | { | ||
510 | register u_int32_t i = ntohl(in.s_addr); | ||
511 | |||
512 | if (IN_CLASSA(i)) | ||
513 | return (htonl(IN_CLASSA_NET)); | ||
514 | else if (IN_CLASSB(i)) | ||
515 | return (htonl(IN_CLASSB_NET)); | ||
516 | return (htonl(IN_CLASSC_NET)); | ||
517 | } | ||
518 | #endif | ||
diff --git a/src/lib/libc/net/res_mkquery.c b/src/lib/libc/net/res_mkquery.c new file mode 100644 index 0000000000..3e7e2ae5d3 --- /dev/null +++ b/src/lib/libc/net/res_mkquery.c | |||
@@ -0,0 +1,195 @@ | |||
1 | /* $OpenBSD: res_mkquery.c,v 1.8 1997/04/13 22:37:21 provos Exp $ */ | ||
2 | |||
3 | /* | ||
4 | * ++Copyright++ 1985, 1993 | ||
5 | * - | ||
6 | * Copyright (c) 1985, 1993 | ||
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 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.8 1997/04/13 22:37:21 provos Exp $"; | ||
64 | #endif | ||
65 | #endif /* LIBC_SCCS and not lint */ | ||
66 | |||
67 | #include <sys/types.h> | ||
68 | #include <sys/param.h> | ||
69 | #include <netinet/in.h> | ||
70 | #include <arpa/nameser.h> | ||
71 | |||
72 | #include <stdio.h> | ||
73 | #include <netdb.h> | ||
74 | #include <resolv.h> | ||
75 | #include <string.h> | ||
76 | |||
77 | /* | ||
78 | * Form all types of queries. | ||
79 | * Returns the size of the result or -1. | ||
80 | */ | ||
81 | /* ARGSUSED */ | ||
82 | int | ||
83 | res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen) | ||
84 | int op; /* opcode of query */ | ||
85 | const char *dname; /* domain name */ | ||
86 | int class, type; /* class and type of query */ | ||
87 | const u_char *data; /* resource record data */ | ||
88 | int datalen; /* length of data */ | ||
89 | const u_char *newrr_in; /* new rr for modify or append */ | ||
90 | u_char *buf; /* buffer to put query */ | ||
91 | int buflen; /* size of buffer */ | ||
92 | { | ||
93 | register HEADER *hp; | ||
94 | register u_char *cp; | ||
95 | register int n; | ||
96 | u_char *dnptrs[20], **dpp, **lastdnptr; | ||
97 | |||
98 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) { | ||
99 | h_errno = NETDB_INTERNAL; | ||
100 | return (-1); | ||
101 | } | ||
102 | #ifdef DEBUG | ||
103 | if (_res.options & RES_DEBUG) | ||
104 | printf(";; res_mkquery(%d, %s, %d, %d)\n", | ||
105 | op, dname, class, type); | ||
106 | #endif | ||
107 | /* | ||
108 | * Initialize header fields. | ||
109 | * | ||
110 | * A special random number generator is used to create non predictable | ||
111 | * and non repeating ids over a long period. It also avoids reuse | ||
112 | * by switching between two distinct number cycles. | ||
113 | */ | ||
114 | |||
115 | if ((buf == NULL) || (buflen < HFIXEDSZ)) | ||
116 | return (-1); | ||
117 | bzero(buf, HFIXEDSZ); | ||
118 | hp = (HEADER *) buf; | ||
119 | _res.id = res_randomid(); | ||
120 | hp->id = htons(_res.id); | ||
121 | hp->opcode = op; | ||
122 | hp->rd = (_res.options & RES_RECURSE) != 0; | ||
123 | hp->rcode = NOERROR; | ||
124 | cp = buf + HFIXEDSZ; | ||
125 | buflen -= HFIXEDSZ; | ||
126 | dpp = dnptrs; | ||
127 | *dpp++ = buf; | ||
128 | *dpp++ = NULL; | ||
129 | lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0]; | ||
130 | /* | ||
131 | * perform opcode specific processing | ||
132 | */ | ||
133 | switch (op) { | ||
134 | case QUERY: /*FALLTHROUGH*/ | ||
135 | case NS_NOTIFY_OP: | ||
136 | if ((buflen -= QFIXEDSZ) < 0) | ||
137 | return (-1); | ||
138 | if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) | ||
139 | return (-1); | ||
140 | cp += n; | ||
141 | buflen -= n; | ||
142 | __putshort(type, cp); | ||
143 | cp += INT16SZ; | ||
144 | __putshort(class, cp); | ||
145 | cp += INT16SZ; | ||
146 | hp->qdcount = htons(1); | ||
147 | if (op == QUERY || data == NULL) | ||
148 | break; | ||
149 | /* | ||
150 | * Make an additional record for completion domain. | ||
151 | */ | ||
152 | buflen -= RRFIXEDSZ; | ||
153 | n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr); | ||
154 | if (n < 0) | ||
155 | return (-1); | ||
156 | cp += n; | ||
157 | buflen -= n; | ||
158 | __putshort(T_NULL, cp); | ||
159 | cp += INT16SZ; | ||
160 | __putshort(class, cp); | ||
161 | cp += INT16SZ; | ||
162 | __putlong(0, cp); | ||
163 | cp += INT32SZ; | ||
164 | __putshort(0, cp); | ||
165 | cp += INT16SZ; | ||
166 | hp->arcount = htons(1); | ||
167 | break; | ||
168 | |||
169 | case IQUERY: | ||
170 | /* | ||
171 | * Initialize answer section | ||
172 | */ | ||
173 | if (buflen < 1 + RRFIXEDSZ + datalen) | ||
174 | return (-1); | ||
175 | *cp++ = '\0'; /* no domain name */ | ||
176 | __putshort(type, cp); | ||
177 | cp += INT16SZ; | ||
178 | __putshort(class, cp); | ||
179 | cp += INT16SZ; | ||
180 | __putlong(0, cp); | ||
181 | cp += INT32SZ; | ||
182 | __putshort(datalen, cp); | ||
183 | cp += INT16SZ; | ||
184 | if (datalen) { | ||
185 | bcopy(data, cp, datalen); | ||
186 | cp += datalen; | ||
187 | } | ||
188 | hp->ancount = htons(1); | ||
189 | break; | ||
190 | |||
191 | default: | ||
192 | return (-1); | ||
193 | } | ||
194 | return (cp - buf); | ||
195 | } | ||
diff --git a/src/lib/libc/net/res_query.c b/src/lib/libc/net/res_query.c new file mode 100644 index 0000000000..a08897b45a --- /dev/null +++ b/src/lib/libc/net/res_query.c | |||
@@ -0,0 +1,398 @@ | |||
1 | /* $OpenBSD: res_query.c,v 1.12 1998/08/31 18:15:29 deraadt Exp $ */ | ||
2 | |||
3 | /* | ||
4 | * ++Copyright++ 1988, 1993 | ||
5 | * - | ||
6 | * Copyright (c) 1988, 1993 | ||
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 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.12 1998/08/31 18:15:29 deraadt Exp $"; | ||
64 | #endif | ||
65 | #endif /* LIBC_SCCS and not lint */ | ||
66 | |||
67 | #include <sys/types.h> | ||
68 | #include <sys/param.h> | ||
69 | #include <netinet/in.h> | ||
70 | #include <arpa/inet.h> | ||
71 | #include <arpa/nameser.h> | ||
72 | |||
73 | #include <stdio.h> | ||
74 | #include <netdb.h> | ||
75 | #include <resolv.h> | ||
76 | #include <ctype.h> | ||
77 | #include <errno.h> | ||
78 | #include <stdlib.h> | ||
79 | #include <string.h> | ||
80 | #include <unistd.h> | ||
81 | |||
82 | #if PACKETSZ > 1024 | ||
83 | #define MAXPACKET PACKETSZ | ||
84 | #else | ||
85 | #define MAXPACKET 1024 | ||
86 | #endif | ||
87 | |||
88 | const char *hostalias __P((const char *)); | ||
89 | int h_errno; | ||
90 | |||
91 | /* | ||
92 | * Formulate a normal query, send, and await answer. | ||
93 | * Returned answer is placed in supplied buffer "answer". | ||
94 | * Perform preliminary check of answer, returning success only | ||
95 | * if no error is indicated and the answer count is nonzero. | ||
96 | * Return the size of the response on success, -1 on error. | ||
97 | * Error number is left in h_errno. | ||
98 | * | ||
99 | * Caller must parse answer and determine whether it answers the question. | ||
100 | */ | ||
101 | int | ||
102 | res_query(name, class, type, answer, anslen) | ||
103 | const char *name; /* domain name */ | ||
104 | int class, type; /* class and type of query */ | ||
105 | u_char *answer; /* buffer to put answer */ | ||
106 | int anslen; /* size of answer buffer */ | ||
107 | { | ||
108 | u_char buf[MAXPACKET]; | ||
109 | register HEADER *hp = (HEADER *) answer; | ||
110 | int n; | ||
111 | |||
112 | hp->rcode = NOERROR; /* default */ | ||
113 | |||
114 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) { | ||
115 | h_errno = NETDB_INTERNAL; | ||
116 | return (-1); | ||
117 | } | ||
118 | #ifdef DEBUG | ||
119 | if (_res.options & RES_DEBUG) | ||
120 | printf(";; res_query(%s, %d, %d)\n", name, class, type); | ||
121 | #endif | ||
122 | |||
123 | n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL, | ||
124 | buf, sizeof(buf)); | ||
125 | if (n <= 0) { | ||
126 | #ifdef DEBUG | ||
127 | if (_res.options & RES_DEBUG) | ||
128 | printf(";; res_query: mkquery failed\n"); | ||
129 | #endif | ||
130 | h_errno = NO_RECOVERY; | ||
131 | return (n); | ||
132 | } | ||
133 | n = res_send(buf, n, answer, anslen); | ||
134 | if (n < 0) { | ||
135 | #ifdef DEBUG | ||
136 | if (_res.options & RES_DEBUG) | ||
137 | printf(";; res_query: send error\n"); | ||
138 | #endif | ||
139 | h_errno = TRY_AGAIN; | ||
140 | return (n); | ||
141 | } | ||
142 | |||
143 | if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { | ||
144 | #ifdef DEBUG | ||
145 | if (_res.options & RES_DEBUG) | ||
146 | printf(";; rcode = %d, ancount=%d\n", hp->rcode, | ||
147 | ntohs(hp->ancount)); | ||
148 | #endif | ||
149 | switch (hp->rcode) { | ||
150 | case NXDOMAIN: | ||
151 | h_errno = HOST_NOT_FOUND; | ||
152 | break; | ||
153 | case SERVFAIL: | ||
154 | h_errno = TRY_AGAIN; | ||
155 | break; | ||
156 | case NOERROR: | ||
157 | h_errno = NO_DATA; | ||
158 | break; | ||
159 | case FORMERR: | ||
160 | case NOTIMP: | ||
161 | case REFUSED: | ||
162 | default: | ||
163 | h_errno = NO_RECOVERY; | ||
164 | break; | ||
165 | } | ||
166 | return (-1); | ||
167 | } | ||
168 | return (n); | ||
169 | } | ||
170 | |||
171 | /* | ||
172 | * Formulate a normal query, send, and retrieve answer in supplied buffer. | ||
173 | * Return the size of the response on success, -1 on error. | ||
174 | * If enabled, implement search rules until answer or unrecoverable failure | ||
175 | * is detected. Error code, if any, is left in h_errno. | ||
176 | */ | ||
177 | int | ||
178 | res_search(name, class, type, answer, anslen) | ||
179 | const char *name; /* domain name */ | ||
180 | int class, type; /* class and type of query */ | ||
181 | u_char *answer; /* buffer to put answer */ | ||
182 | int anslen; /* size of answer */ | ||
183 | { | ||
184 | register const char *cp, * const *domain; | ||
185 | HEADER *hp = (HEADER *) answer; | ||
186 | u_int dots; | ||
187 | int trailing_dot, ret, saved_herrno; | ||
188 | int got_nodata = 0, got_servfail = 0, tried_as_is = 0; | ||
189 | |||
190 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) { | ||
191 | h_errno = NETDB_INTERNAL; | ||
192 | return (-1); | ||
193 | } | ||
194 | errno = 0; | ||
195 | h_errno = HOST_NOT_FOUND; /* default, if we never query */ | ||
196 | dots = 0; | ||
197 | for (cp = name; *cp; cp++) | ||
198 | dots += (*cp == '.'); | ||
199 | trailing_dot = 0; | ||
200 | if (cp > name && *--cp == '.') | ||
201 | trailing_dot++; | ||
202 | |||
203 | /* | ||
204 | * if there aren't any dots, it could be a user-level alias | ||
205 | */ | ||
206 | if (!dots && (cp = __hostalias(name)) != NULL) | ||
207 | return (res_query(cp, class, type, answer, anslen)); | ||
208 | |||
209 | /* | ||
210 | * If there are dots in the name already, let's just give it a try | ||
211 | * 'as is'. The threshold can be set with the "ndots" option. | ||
212 | */ | ||
213 | saved_herrno = -1; | ||
214 | if (dots >= _res.ndots) { | ||
215 | ret = res_querydomain(name, NULL, class, type, answer, anslen); | ||
216 | if (ret > 0) | ||
217 | return (ret); | ||
218 | saved_herrno = h_errno; | ||
219 | tried_as_is++; | ||
220 | } | ||
221 | |||
222 | /* | ||
223 | * We do at least one level of search if | ||
224 | * - there is no dot and RES_DEFNAME is set, or | ||
225 | * - there is at least one dot, there is no trailing dot, | ||
226 | * and RES_DNSRCH is set. | ||
227 | */ | ||
228 | if ((!dots && (_res.options & RES_DEFNAMES)) || | ||
229 | (dots && !trailing_dot && (_res.options & RES_DNSRCH))) { | ||
230 | int done = 0; | ||
231 | |||
232 | for (domain = (const char * const *)_res.dnsrch; | ||
233 | *domain && !done; | ||
234 | domain++) { | ||
235 | |||
236 | ret = res_querydomain(name, *domain, class, type, | ||
237 | answer, anslen); | ||
238 | if (ret > 0) | ||
239 | return (ret); | ||
240 | |||
241 | /* | ||
242 | * If no server present, give up. | ||
243 | * If name isn't found in this domain, | ||
244 | * keep trying higher domains in the search list | ||
245 | * (if that's enabled). | ||
246 | * On a NO_DATA error, keep trying, otherwise | ||
247 | * a wildcard entry of another type could keep us | ||
248 | * from finding this entry higher in the domain. | ||
249 | * If we get some other error (negative answer or | ||
250 | * server failure), then stop searching up, | ||
251 | * but try the input name below in case it's | ||
252 | * fully-qualified. | ||
253 | */ | ||
254 | if (errno == ECONNREFUSED) { | ||
255 | h_errno = TRY_AGAIN; | ||
256 | return (-1); | ||
257 | } | ||
258 | |||
259 | switch (h_errno) { | ||
260 | case NO_DATA: | ||
261 | got_nodata++; | ||
262 | /* FALLTHROUGH */ | ||
263 | case HOST_NOT_FOUND: | ||
264 | /* keep trying */ | ||
265 | break; | ||
266 | case TRY_AGAIN: | ||
267 | if (hp->rcode == SERVFAIL) { | ||
268 | /* try next search element, if any */ | ||
269 | got_servfail++; | ||
270 | break; | ||
271 | } | ||
272 | /* FALLTHROUGH */ | ||
273 | default: | ||
274 | /* anything else implies that we're done */ | ||
275 | done++; | ||
276 | } | ||
277 | |||
278 | /* if we got here for some reason other than DNSRCH, | ||
279 | * we only wanted one iteration of the loop, so stop. | ||
280 | */ | ||
281 | if (!(_res.options & RES_DNSRCH)) | ||
282 | done++; | ||
283 | } | ||
284 | } | ||
285 | |||
286 | /* if we have not already tried the name "as is", do that now. | ||
287 | * note that we do this regardless of how many dots were in the | ||
288 | * name or whether it ends with a dot. | ||
289 | */ | ||
290 | if (!tried_as_is) { | ||
291 | ret = res_querydomain(name, NULL, class, type, answer, anslen); | ||
292 | if (ret > 0) | ||
293 | return (ret); | ||
294 | } | ||
295 | |||
296 | /* if we got here, we didn't satisfy the search. | ||
297 | * if we did an initial full query, return that query's h_errno | ||
298 | * (note that we wouldn't be here if that query had succeeded). | ||
299 | * else if we ever got a nodata, send that back as the reason. | ||
300 | * else send back meaningless h_errno, that being the one from | ||
301 | * the last DNSRCH we did. | ||
302 | */ | ||
303 | if (saved_herrno != -1) | ||
304 | h_errno = saved_herrno; | ||
305 | else if (got_nodata) | ||
306 | h_errno = NO_DATA; | ||
307 | else if (got_servfail) | ||
308 | h_errno = TRY_AGAIN; | ||
309 | return (-1); | ||
310 | } | ||
311 | |||
312 | /* | ||
313 | * Perform a call on res_query on the concatenation of name and domain, | ||
314 | * removing a trailing dot from name if domain is NULL. | ||
315 | */ | ||
316 | int | ||
317 | res_querydomain(name, domain, class, type, answer, anslen) | ||
318 | const char *name, *domain; | ||
319 | int class, type; /* class and type of query */ | ||
320 | u_char *answer; /* buffer to put answer */ | ||
321 | int anslen; /* size of answer */ | ||
322 | { | ||
323 | char nbuf[MAXDNAME*2+1]; | ||
324 | const char *longname = nbuf; | ||
325 | int n; | ||
326 | |||
327 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) { | ||
328 | h_errno = NETDB_INTERNAL; | ||
329 | return (-1); | ||
330 | } | ||
331 | #ifdef DEBUG | ||
332 | if (_res.options & RES_DEBUG) | ||
333 | printf(";; res_querydomain(%s, %s, %d, %d)\n", | ||
334 | name, domain?domain:"<Nil>", class, type); | ||
335 | #endif | ||
336 | if (domain == NULL) { | ||
337 | /* | ||
338 | * Check for trailing '.'; | ||
339 | * copy without '.' if present. | ||
340 | */ | ||
341 | n = strlen(name) - 1; | ||
342 | if (n != (0 - 1) && name[n] == '.' && n < sizeof(nbuf) - 1) { | ||
343 | bcopy(name, nbuf, n); | ||
344 | nbuf[n] = '\0'; | ||
345 | } else | ||
346 | longname = name; | ||
347 | } else | ||
348 | sprintf(nbuf, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain); | ||
349 | |||
350 | return (res_query(longname, class, type, answer, anslen)); | ||
351 | } | ||
352 | |||
353 | const char * | ||
354 | hostalias(name) | ||
355 | register const char *name; | ||
356 | { | ||
357 | register char *cp1, *cp2; | ||
358 | FILE *fp; | ||
359 | char *file; | ||
360 | char buf[BUFSIZ]; | ||
361 | static char abuf[MAXDNAME]; | ||
362 | size_t len; | ||
363 | |||
364 | if (_res.options & RES_NOALIASES) | ||
365 | return (NULL); | ||
366 | file = getenv("HOSTALIASES"); | ||
367 | if (issetugid() != 0 || file == NULL || (fp = fopen(file, "r")) == NULL) | ||
368 | return (NULL); | ||
369 | setbuf(fp, NULL); | ||
370 | while ((cp1 = fgetln(fp, &len)) != NULL) { | ||
371 | if (cp1[len-1] == '\n') | ||
372 | len--; | ||
373 | if (len >= sizeof(buf) || len == 0) | ||
374 | continue; | ||
375 | (void)memcpy(buf, cp1, len); | ||
376 | buf[len] = '\0'; | ||
377 | |||
378 | for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1) | ||
379 | ; | ||
380 | if (!*cp1) | ||
381 | break; | ||
382 | *cp1 = '\0'; | ||
383 | if (!strcasecmp(buf, name)) { | ||
384 | while (isspace(*++cp1)) | ||
385 | ; | ||
386 | if (!*cp1) | ||
387 | break; | ||
388 | for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2) | ||
389 | ; | ||
390 | strncpy(abuf, cp1, sizeof(abuf) - 1); | ||
391 | abuf[sizeof(abuf) - 1] = *cp2 = '\0'; | ||
392 | fclose(fp); | ||
393 | return (abuf); | ||
394 | } | ||
395 | } | ||
396 | fclose(fp); | ||
397 | return (NULL); | ||
398 | } | ||
diff --git a/src/lib/libc/net/res_random.c b/src/lib/libc/net/res_random.c new file mode 100644 index 0000000000..bd32a50c33 --- /dev/null +++ b/src/lib/libc/net/res_random.c | |||
@@ -0,0 +1,233 @@ | |||
1 | /* $OpenBSD: res_random.c,v 1.7 1997/07/25 20:30:08 mickey Exp $ */ | ||
2 | |||
3 | /* | ||
4 | * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Theo de Raadt <deraadt@openbsd.org> came up with the idea of using | ||
8 | * such a mathematical system to generate more random (yet non-repeating) | ||
9 | * ids to solve the resolver/named problem. But Niels designed the | ||
10 | * actual system based on the constraints. | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or without | ||
13 | * modification, are permitted provided that the following conditions | ||
14 | * are met: | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer. | ||
17 | * 2. Redistributions in binary form must reproduce the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer in the | ||
19 | * documentation and/or other materials provided with the distribution. | ||
20 | * 3. All advertising materials mentioning features or use of this software | ||
21 | * must display the following acknowledgement: | ||
22 | * This product includes software developed by Niels Provos. | ||
23 | * 4. The name of the author may not be used to endorse or promote products | ||
24 | * derived from this software without specific prior written permission. | ||
25 | * | ||
26 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
27 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
28 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
29 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
30 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
31 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
35 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | */ | ||
37 | |||
38 | /* | ||
39 | * seed = random 15bit | ||
40 | * n = prime, g0 = generator to n, | ||
41 | * j = random so that gcd(j,n-1) == 1 | ||
42 | * g = g0^j mod n will be a generator again. | ||
43 | * | ||
44 | * X[0] = random seed. | ||
45 | * X[n] = a*X[n-1]+b mod m is a Linear Congruential Generator | ||
46 | * with a = 7^(even random) mod m, | ||
47 | * b = random with gcd(b,m) == 1 | ||
48 | * m = 31104 and a maximal period of m-1. | ||
49 | * | ||
50 | * The transaction id is determined by: | ||
51 | * id[n] = seed xor (g^X[n] mod n) | ||
52 | * | ||
53 | * Effectivly the id is restricted to the lower 15 bits, thus | ||
54 | * yielding two different cycles by toggling the msb on and off. | ||
55 | * This avoids reuse issues caused by reseeding. | ||
56 | * | ||
57 | * The 16 bit space is very small and brute force attempts are | ||
58 | * entirly feasible, we skip a random number of transaction ids | ||
59 | * so that an attacker will not get sequential ids. | ||
60 | */ | ||
61 | |||
62 | #include <sys/types.h> | ||
63 | #include <netinet/in.h> | ||
64 | #include <sys/time.h> | ||
65 | #include <resolv.h> | ||
66 | |||
67 | #include <unistd.h> | ||
68 | #include <stdlib.h> | ||
69 | #include <string.h> | ||
70 | |||
71 | #define RU_OUT 180 /* Time after wich will be reseeded */ | ||
72 | #define RU_MAX 30000 /* Uniq cycle, avoid blackjack prediction */ | ||
73 | #define RU_GEN 2 /* Starting generator */ | ||
74 | #define RU_N 32749 /* RU_N-1 = 2*2*3*2729 */ | ||
75 | #define RU_AGEN 7 /* determine ru_a as RU_AGEN^(2*rand) */ | ||
76 | #define RU_M 31104 /* RU_M = 2^7*3^5 - don't change */ | ||
77 | |||
78 | #define PFAC_N 3 | ||
79 | const static u_int16_t pfacts[PFAC_N] = { | ||
80 | 2, | ||
81 | 3, | ||
82 | 2729 | ||
83 | }; | ||
84 | |||
85 | static u_int16_t ru_x; | ||
86 | static u_int16_t ru_seed; | ||
87 | static u_int16_t ru_a, ru_b; | ||
88 | static u_int16_t ru_g; | ||
89 | static u_int16_t ru_counter = 0; | ||
90 | static u_int16_t ru_msb = 0; | ||
91 | static long ru_reseed; | ||
92 | static u_int32_t tmp; /* Storage for unused random */ | ||
93 | static struct timeval tv; | ||
94 | |||
95 | static u_int16_t pmod __P((u_int16_t, u_int16_t, u_int16_t)); | ||
96 | static void res_initid __P((void)); | ||
97 | |||
98 | /* | ||
99 | * Do a fast modular exponation, returned value will be in the range | ||
100 | * of 0 - (mod-1) | ||
101 | */ | ||
102 | |||
103 | #ifdef __STDC__ | ||
104 | static u_int16_t | ||
105 | pmod(u_int16_t gen, u_int16_t exp, u_int16_t mod) | ||
106 | #else | ||
107 | static u_int16_t | ||
108 | pmod(gen, exp, mod) | ||
109 | u_int16_t gen, exp, mod; | ||
110 | #endif | ||
111 | { | ||
112 | u_int16_t s, t, u; | ||
113 | |||
114 | s = 1; | ||
115 | t = gen; | ||
116 | u = exp; | ||
117 | |||
118 | while (u) { | ||
119 | if (u & 1) | ||
120 | s = (s*t) % mod; | ||
121 | u >>= 1; | ||
122 | t = (t*t) % mod; | ||
123 | } | ||
124 | return (s); | ||
125 | } | ||
126 | |||
127 | /* | ||
128 | * Initalizes the seed and chooses a suitable generator. Also toggles | ||
129 | * the msb flag. The msb flag is used to generate two distinct | ||
130 | * cycles of random numbers and thus avoiding reuse of ids. | ||
131 | * | ||
132 | * This function is called from res_randomid() when needed, an | ||
133 | * application does not have to worry about it. | ||
134 | */ | ||
135 | static void | ||
136 | res_initid() | ||
137 | { | ||
138 | u_int16_t j, i; | ||
139 | int noprime = 1; | ||
140 | |||
141 | tmp = arc4random(); | ||
142 | ru_x = (tmp & 0xFFFF) % RU_M; | ||
143 | |||
144 | /* 15 bits of random seed */ | ||
145 | ru_seed = (tmp >> 16) & 0x7FFF; | ||
146 | |||
147 | tmp = arc4random(); | ||
148 | |||
149 | /* Determine the LCG we use */ | ||
150 | ru_b = (tmp & 0xfffe) | 1; | ||
151 | ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M); | ||
152 | while (ru_b % 3 == 0) | ||
153 | ru_b += 2; | ||
154 | |||
155 | tmp = arc4random(); | ||
156 | j = tmp % RU_N; | ||
157 | tmp = tmp >> 16; | ||
158 | |||
159 | /* | ||
160 | * Do a fast gcd(j,RU_N-1), so we can find a j with | ||
161 | * gcd(j, RU_N-1) == 1, giving a new generator for | ||
162 | * RU_GEN^j mod RU_N | ||
163 | */ | ||
164 | |||
165 | while (noprime) { | ||
166 | for (i=0; i<PFAC_N; i++) | ||
167 | if (j%pfacts[i] == 0) | ||
168 | break; | ||
169 | |||
170 | if (i>=PFAC_N) | ||
171 | noprime = 0; | ||
172 | else | ||
173 | j = (j+1) % RU_N; | ||
174 | } | ||
175 | |||
176 | ru_g = pmod(RU_GEN,j,RU_N); | ||
177 | ru_counter = 0; | ||
178 | |||
179 | gettimeofday(&tv, NULL); | ||
180 | ru_reseed = tv.tv_sec + RU_OUT; | ||
181 | ru_msb = ru_msb == 0x8000 ? 0 : 0x8000; | ||
182 | } | ||
183 | |||
184 | u_int | ||
185 | res_randomid() | ||
186 | { | ||
187 | int i, n; | ||
188 | |||
189 | gettimeofday(&tv, NULL); | ||
190 | if (ru_counter >= RU_MAX || tv.tv_sec > ru_reseed) | ||
191 | res_initid(); | ||
192 | |||
193 | if (!tmp) | ||
194 | tmp = arc4random(); | ||
195 | |||
196 | /* Skip a random number of ids */ | ||
197 | n = tmp & 0x7; tmp = tmp >> 3; | ||
198 | if (ru_counter + n >= RU_MAX) | ||
199 | res_initid(); | ||
200 | |||
201 | for (i=0; i<=n; i++) | ||
202 | /* Linear Congruential Generator */ | ||
203 | ru_x = (ru_a*ru_x + ru_b) % RU_M; | ||
204 | |||
205 | ru_counter += i; | ||
206 | |||
207 | return (ru_seed ^ pmod(ru_g,ru_x,RU_N)) | ru_msb; | ||
208 | } | ||
209 | |||
210 | #if 0 | ||
211 | void | ||
212 | main(int argc, char **argv) | ||
213 | { | ||
214 | int i, n; | ||
215 | u_int16_t wert; | ||
216 | |||
217 | res_initid(); | ||
218 | |||
219 | printf("Generator: %d\n", ru_g); | ||
220 | printf("Seed: %d\n", ru_seed); | ||
221 | printf("Reseed at %ld\n", ru_reseed); | ||
222 | printf("Ru_X: %d\n", ru_x); | ||
223 | printf("Ru_A: %d\n", ru_a); | ||
224 | printf("Ru_B: %d\n", ru_b); | ||
225 | |||
226 | n = atoi(argv[1]); | ||
227 | for (i=0;i<n;i++) { | ||
228 | wert = res_randomid(); | ||
229 | printf("%06d\n", wert); | ||
230 | } | ||
231 | } | ||
232 | #endif | ||
233 | |||
diff --git a/src/lib/libc/net/res_send.c b/src/lib/libc/net/res_send.c new file mode 100644 index 0000000000..0cda3510eb --- /dev/null +++ b/src/lib/libc/net/res_send.c | |||
@@ -0,0 +1,780 @@ | |||
1 | /* $OpenBSD: res_send.c,v 1.8 1998/03/19 00:30:08 millert Exp $ */ | ||
2 | |||
3 | /* | ||
4 | * ++Copyright++ 1985, 1989, 1993 | ||
5 | * - | ||
6 | * Copyright (c) 1985, 1989, 1993 | ||
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 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.8 1998/03/19 00:30:08 millert Exp $"; | ||
64 | #endif | ||
65 | #endif /* LIBC_SCCS and not lint */ | ||
66 | |||
67 | /* change this to "0" | ||
68 | * if you talk to a lot | ||
69 | * of multi-homed SunOS | ||
70 | * ("broken") name servers. | ||
71 | */ | ||
72 | #define CHECK_SRVR_ADDR 1 /* XXX - should be in options.h */ | ||
73 | |||
74 | /* | ||
75 | * Send query to name server and wait for reply. | ||
76 | */ | ||
77 | |||
78 | #include <sys/types.h> | ||
79 | #include <sys/param.h> | ||
80 | #include <sys/time.h> | ||
81 | #include <sys/socket.h> | ||
82 | #include <sys/uio.h> | ||
83 | #include <netinet/in.h> | ||
84 | #include <arpa/nameser.h> | ||
85 | #include <arpa/inet.h> | ||
86 | |||
87 | #include <stdio.h> | ||
88 | #include <netdb.h> | ||
89 | #include <errno.h> | ||
90 | #include <resolv.h> | ||
91 | #include <stdlib.h> | ||
92 | #include <string.h> | ||
93 | #include <unistd.h> | ||
94 | |||
95 | static int s = -1; /* socket used for communications */ | ||
96 | static int connected = 0; /* is the socket connected */ | ||
97 | static int vc = 0; /* is the socket a virtual ciruit? */ | ||
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 | |||
109 | #define CAN_RECONNECT 1 | ||
110 | |||
111 | #ifndef DEBUG | ||
112 | # define Dprint(cond, args) /*empty*/ | ||
113 | # define DprintQ(cond, args, query, size) /*empty*/ | ||
114 | # define Aerror(file, string, error, address) /*empty*/ | ||
115 | # define Perror(file, string, error) /*empty*/ | ||
116 | #else | ||
117 | # define Dprint(cond, args) if (cond) {fprintf args;} else {} | ||
118 | # define DprintQ(cond, args, query, size) if (cond) {\ | ||
119 | fprintf args;\ | ||
120 | __fp_nquery(query, size, stdout);\ | ||
121 | } else {} | ||
122 | static void | ||
123 | Aerror(file, string, error, address) | ||
124 | FILE *file; | ||
125 | char *string; | ||
126 | int error; | ||
127 | struct sockaddr_in address; | ||
128 | { | ||
129 | int save = errno; | ||
130 | |||
131 | if (_res.options & RES_DEBUG) { | ||
132 | fprintf(file, "res_send: %s ([%s].%u): %s\n", | ||
133 | string, | ||
134 | inet_ntoa(address.sin_addr), | ||
135 | ntohs(address.sin_port), | ||
136 | strerror(error)); | ||
137 | } | ||
138 | errno = save; | ||
139 | } | ||
140 | static void | ||
141 | Perror(file, string, error) | ||
142 | FILE *file; | ||
143 | char *string; | ||
144 | int error; | ||
145 | { | ||
146 | int save = errno; | ||
147 | |||
148 | if (_res.options & RES_DEBUG) { | ||
149 | fprintf(file, "res_send: %s: %s\n", | ||
150 | string, strerror(error)); | ||
151 | } | ||
152 | errno = save; | ||
153 | } | ||
154 | #endif | ||
155 | |||
156 | static res_send_qhook Qhook = NULL; | ||
157 | static res_send_rhook Rhook = NULL; | ||
158 | |||
159 | void | ||
160 | res_send_setqhook(hook) | ||
161 | res_send_qhook hook; | ||
162 | { | ||
163 | |||
164 | Qhook = hook; | ||
165 | } | ||
166 | |||
167 | void | ||
168 | res_send_setrhook(hook) | ||
169 | res_send_rhook hook; | ||
170 | { | ||
171 | |||
172 | Rhook = hook; | ||
173 | } | ||
174 | |||
175 | /* int | ||
176 | * res_isourserver(ina) | ||
177 | * looks up "ina" in _res.ns_addr_list[] | ||
178 | * returns: | ||
179 | * 0 : not found | ||
180 | * >0 : found | ||
181 | * author: | ||
182 | * paul vixie, 29may94 | ||
183 | */ | ||
184 | int | ||
185 | res_isourserver(inp) | ||
186 | const struct sockaddr_in *inp; | ||
187 | { | ||
188 | struct sockaddr_in ina; | ||
189 | register int ns, ret; | ||
190 | |||
191 | ina = *inp; | ||
192 | ret = 0; | ||
193 | for (ns = 0; ns < _res.nscount; ns++) { | ||
194 | register const struct sockaddr_in *srv = &_res.nsaddr_list[ns]; | ||
195 | |||
196 | if (srv->sin_family == ina.sin_family && | ||
197 | srv->sin_port == ina.sin_port && | ||
198 | (srv->sin_addr.s_addr == INADDR_ANY || | ||
199 | srv->sin_addr.s_addr == ina.sin_addr.s_addr)) { | ||
200 | ret++; | ||
201 | break; | ||
202 | } | ||
203 | } | ||
204 | return (ret); | ||
205 | } | ||
206 | |||
207 | /* int | ||
208 | * res_nameinquery(name, type, class, buf, eom) | ||
209 | * look for (name,type,class) in the query section of packet (buf,eom) | ||
210 | * returns: | ||
211 | * -1 : format error | ||
212 | * 0 : not found | ||
213 | * >0 : found | ||
214 | * author: | ||
215 | * paul vixie, 29may94 | ||
216 | */ | ||
217 | int | ||
218 | res_nameinquery(name, type, class, buf, eom) | ||
219 | const char *name; | ||
220 | register int type, class; | ||
221 | const u_char *buf, *eom; | ||
222 | { | ||
223 | register const u_char *cp = buf + HFIXEDSZ; | ||
224 | int qdcount = ntohs(((HEADER*)buf)->qdcount); | ||
225 | |||
226 | while (qdcount-- > 0) { | ||
227 | char tname[MAXDNAME+1]; | ||
228 | register int n, ttype, tclass; | ||
229 | |||
230 | n = dn_expand(buf, eom, cp, tname, sizeof tname); | ||
231 | if (n < 0) | ||
232 | return (-1); | ||
233 | cp += n; | ||
234 | ttype = _getshort(cp); cp += INT16SZ; | ||
235 | tclass = _getshort(cp); cp += INT16SZ; | ||
236 | if (ttype == type && | ||
237 | tclass == class && | ||
238 | strcasecmp(tname, name) == 0) | ||
239 | return (1); | ||
240 | } | ||
241 | return (0); | ||
242 | } | ||
243 | |||
244 | /* int | ||
245 | * res_queriesmatch(buf1, eom1, buf2, eom2) | ||
246 | * is there a 1:1 mapping of (name,type,class) | ||
247 | * in (buf1,eom1) and (buf2,eom2)? | ||
248 | * returns: | ||
249 | * -1 : format error | ||
250 | * 0 : not a 1:1 mapping | ||
251 | * >0 : is a 1:1 mapping | ||
252 | * author: | ||
253 | * paul vixie, 29may94 | ||
254 | */ | ||
255 | int | ||
256 | res_queriesmatch(buf1, eom1, buf2, eom2) | ||
257 | const u_char *buf1, *eom1; | ||
258 | const u_char *buf2, *eom2; | ||
259 | { | ||
260 | register const u_char *cp = buf1 + HFIXEDSZ; | ||
261 | int qdcount = ntohs(((HEADER*)buf1)->qdcount); | ||
262 | |||
263 | if (qdcount != ntohs(((HEADER*)buf2)->qdcount)) | ||
264 | return (0); | ||
265 | while (qdcount-- > 0) { | ||
266 | char tname[MAXDNAME+1]; | ||
267 | register int n, ttype, tclass; | ||
268 | |||
269 | n = dn_expand(buf1, eom1, cp, tname, sizeof tname); | ||
270 | if (n < 0) | ||
271 | return (-1); | ||
272 | cp += n; | ||
273 | ttype = _getshort(cp); cp += INT16SZ; | ||
274 | tclass = _getshort(cp); cp += INT16SZ; | ||
275 | if (!res_nameinquery(tname, ttype, tclass, buf2, eom2)) | ||
276 | return (0); | ||
277 | } | ||
278 | return (1); | ||
279 | } | ||
280 | |||
281 | int | ||
282 | res_send(buf, buflen, ans, anssiz) | ||
283 | const u_char *buf; | ||
284 | int buflen; | ||
285 | u_char *ans; | ||
286 | int anssiz; | ||
287 | { | ||
288 | HEADER *hp = (HEADER *) buf; | ||
289 | HEADER *anhp = (HEADER *) ans; | ||
290 | int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns; | ||
291 | register int n; | ||
292 | u_int badns; /* XXX NSMAX can't exceed #/bits in this var */ | ||
293 | |||
294 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) { | ||
295 | /* errno should have been set by res_init() in this case. */ | ||
296 | return (-1); | ||
297 | } | ||
298 | DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY), | ||
299 | (stdout, ";; res_send()\n"), buf, buflen); | ||
300 | v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ; | ||
301 | gotsomewhere = 0; | ||
302 | connreset = 0; | ||
303 | terrno = ETIMEDOUT; | ||
304 | badns = 0; | ||
305 | |||
306 | /* | ||
307 | * Send request, RETRY times, or until successful | ||
308 | */ | ||
309 | for (try = 0; try < _res.retry; try++) { | ||
310 | for (ns = 0; ns < _res.nscount; ns++) { | ||
311 | struct sockaddr_in *nsap = &_res.nsaddr_list[ns]; | ||
312 | same_ns: | ||
313 | if (badns & (1 << ns)) { | ||
314 | res_close(); | ||
315 | goto next_ns; | ||
316 | } | ||
317 | |||
318 | if (Qhook) { | ||
319 | int done = 0, loops = 0; | ||
320 | |||
321 | do { | ||
322 | res_sendhookact act; | ||
323 | |||
324 | act = (*Qhook)(&nsap, &buf, &buflen, | ||
325 | ans, anssiz, &resplen); | ||
326 | switch (act) { | ||
327 | case res_goahead: | ||
328 | done = 1; | ||
329 | break; | ||
330 | case res_nextns: | ||
331 | res_close(); | ||
332 | goto next_ns; | ||
333 | case res_done: | ||
334 | return (resplen); | ||
335 | case res_modified: | ||
336 | /* give the hook another try */ | ||
337 | if (++loops < 42) /*doug adams*/ | ||
338 | break; | ||
339 | /*FALLTHROUGH*/ | ||
340 | case res_error: | ||
341 | /*FALLTHROUGH*/ | ||
342 | default: | ||
343 | return (-1); | ||
344 | } | ||
345 | } while (!done); | ||
346 | } | ||
347 | |||
348 | Dprint(_res.options & RES_DEBUG, | ||
349 | (stdout, ";; Querying server (# %d) address = %s\n", | ||
350 | ns + 1, inet_ntoa(nsap->sin_addr))); | ||
351 | |||
352 | if (v_circuit) { | ||
353 | int truncated; | ||
354 | struct iovec iov[2]; | ||
355 | u_short len; | ||
356 | u_char *cp; | ||
357 | |||
358 | /* | ||
359 | * Use virtual circuit; | ||
360 | * at most one attempt per server. | ||
361 | */ | ||
362 | try = _res.retry; | ||
363 | truncated = 0; | ||
364 | if ((s < 0) || (!vc)) { | ||
365 | if (s >= 0) | ||
366 | res_close(); | ||
367 | |||
368 | s = socket(PF_INET, SOCK_STREAM, 0); | ||
369 | if (s < 0) { | ||
370 | terrno = errno; | ||
371 | Perror(stderr, "socket(vc)", errno); | ||
372 | return (-1); | ||
373 | } | ||
374 | errno = 0; | ||
375 | if (connect(s, (struct sockaddr *)nsap, | ||
376 | sizeof(struct sockaddr)) < 0) { | ||
377 | terrno = errno; | ||
378 | Aerror(stderr, "connect/vc", | ||
379 | errno, *nsap); | ||
380 | badns |= (1 << ns); | ||
381 | res_close(); | ||
382 | goto next_ns; | ||
383 | } | ||
384 | vc = 1; | ||
385 | } | ||
386 | /* | ||
387 | * Send length & message | ||
388 | */ | ||
389 | putshort((u_short)buflen, (u_char*)&len); | ||
390 | iov[0].iov_base = (caddr_t)&len; | ||
391 | iov[0].iov_len = INT16SZ; | ||
392 | iov[1].iov_base = (caddr_t)buf; | ||
393 | iov[1].iov_len = buflen; | ||
394 | if (writev(s, iov, 2) != (INT16SZ + buflen)) { | ||
395 | terrno = errno; | ||
396 | Perror(stderr, "write failed", errno); | ||
397 | badns |= (1 << ns); | ||
398 | res_close(); | ||
399 | goto next_ns; | ||
400 | } | ||
401 | /* | ||
402 | * Receive length & response | ||
403 | */ | ||
404 | read_len: | ||
405 | cp = ans; | ||
406 | len = INT16SZ; | ||
407 | while ((n = read(s, (char *)cp, (int)len)) > 0) { | ||
408 | cp += n; | ||
409 | if ((len -= n) <= 0) | ||
410 | break; | ||
411 | } | ||
412 | if (n <= 0) { | ||
413 | terrno = errno; | ||
414 | Perror(stderr, "read failed", errno); | ||
415 | res_close(); | ||
416 | /* | ||
417 | * A long running process might get its TCP | ||
418 | * connection reset if the remote server was | ||
419 | * restarted. Requery the server instead of | ||
420 | * trying a new one. When there is only one | ||
421 | * server, this means that a query might work | ||
422 | * instead of failing. We only allow one reset | ||
423 | * per query to prevent looping. | ||
424 | */ | ||
425 | if (terrno == ECONNRESET && !connreset) { | ||
426 | connreset = 1; | ||
427 | res_close(); | ||
428 | goto same_ns; | ||
429 | } | ||
430 | res_close(); | ||
431 | goto next_ns; | ||
432 | } | ||
433 | resplen = _getshort(ans); | ||
434 | if (resplen > anssiz) { | ||
435 | Dprint(_res.options & RES_DEBUG, | ||
436 | (stdout, ";; response truncated\n") | ||
437 | ); | ||
438 | truncated = 1; | ||
439 | len = anssiz; | ||
440 | } else | ||
441 | len = resplen; | ||
442 | cp = ans; | ||
443 | while (len != 0 && | ||
444 | (n = read(s, (char *)cp, (int)len)) > 0) { | ||
445 | cp += n; | ||
446 | len -= n; | ||
447 | } | ||
448 | if (n <= 0) { | ||
449 | terrno = errno; | ||
450 | Perror(stderr, "read(vc)", errno); | ||
451 | res_close(); | ||
452 | goto next_ns; | ||
453 | } | ||
454 | if (truncated) { | ||
455 | /* | ||
456 | * Flush rest of answer | ||
457 | * so connection stays in synch. | ||
458 | */ | ||
459 | anhp->tc = 1; | ||
460 | len = resplen - anssiz; | ||
461 | while (len != 0) { | ||
462 | char junk[PACKETSZ]; | ||
463 | |||
464 | n = (len > sizeof(junk) | ||
465 | ? sizeof(junk) | ||
466 | : len); | ||
467 | if ((n = read(s, junk, n)) > 0) | ||
468 | len -= n; | ||
469 | else | ||
470 | break; | ||
471 | } | ||
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 | } | ||
487 | } else { | ||
488 | /* | ||
489 | * Use datagrams. | ||
490 | */ | ||
491 | struct timeval timeout; | ||
492 | fd_set *dsmaskp; | ||
493 | struct sockaddr_in from; | ||
494 | int fromlen; | ||
495 | |||
496 | if ((s < 0) || vc) { | ||
497 | if (vc) | ||
498 | res_close(); | ||
499 | s = socket(PF_INET, SOCK_DGRAM, 0); | ||
500 | if (s < 0) { | ||
501 | #if !CAN_RECONNECT | ||
502 | bad_dg_sock: | ||
503 | #endif | ||
504 | terrno = errno; | ||
505 | Perror(stderr, "socket(dg)", errno); | ||
506 | return (-1); | ||
507 | } | ||
508 | connected = 0; | ||
509 | } | ||
510 | /* | ||
511 | * On a 4.3BSD+ machine (client and server, | ||
512 | * actually), sending to a nameserver datagram | ||
513 | * port with no nameserver will cause an | ||
514 | * ICMP port unreachable message to be returned. | ||
515 | * If our datagram socket is "connected" to the | ||
516 | * server, we get an ECONNREFUSED error on the next | ||
517 | * socket operation, and select returns if the | ||
518 | * error message is received. We can thus detect | ||
519 | * the absence of a nameserver without timing out. | ||
520 | * If we have sent queries to at least two servers, | ||
521 | * however, we don't want to remain connected, | ||
522 | * as we wish to receive answers from the first | ||
523 | * server to respond. | ||
524 | */ | ||
525 | if (_res.nscount == 1 || (try == 0 && ns == 0)) { | ||
526 | /* | ||
527 | * Connect only if we are sure we won't | ||
528 | * receive a response from another server. | ||
529 | */ | ||
530 | if (!connected) { | ||
531 | if (connect(s, (struct sockaddr *)nsap, | ||
532 | sizeof(struct sockaddr) | ||
533 | ) < 0) { | ||
534 | Aerror(stderr, | ||
535 | "connect(dg)", | ||
536 | errno, *nsap); | ||
537 | badns |= (1 << ns); | ||
538 | res_close(); | ||
539 | goto next_ns; | ||
540 | } | ||
541 | connected = 1; | ||
542 | } | ||
543 | if (send(s, (char*)buf, buflen, 0) != buflen) { | ||
544 | Perror(stderr, "send", errno); | ||
545 | badns |= (1 << ns); | ||
546 | res_close(); | ||
547 | goto next_ns; | ||
548 | } | ||
549 | } else { | ||
550 | /* | ||
551 | * Disconnect if we want to listen | ||
552 | * for responses from more than one server. | ||
553 | */ | ||
554 | if (connected) { | ||
555 | #if CAN_RECONNECT | ||
556 | struct sockaddr_in no_addr; | ||
557 | |||
558 | no_addr.sin_family = AF_INET; | ||
559 | no_addr.sin_addr.s_addr = INADDR_ANY; | ||
560 | no_addr.sin_port = 0; | ||
561 | (void) connect(s, | ||
562 | (struct sockaddr *) | ||
563 | &no_addr, | ||
564 | sizeof(no_addr)); | ||
565 | #else | ||
566 | int s1 = socket(PF_INET, SOCK_DGRAM,0); | ||
567 | if (s1 < 0) | ||
568 | goto bad_dg_sock; | ||
569 | (void) dup2(s1, s); | ||
570 | (void) close(s1); | ||
571 | Dprint(_res.options & RES_DEBUG, | ||
572 | (stdout, ";; new DG socket\n")) | ||
573 | #endif | ||
574 | connected = 0; | ||
575 | errno = 0; | ||
576 | } | ||
577 | if (sendto(s, (char*)buf, buflen, 0, | ||
578 | (struct sockaddr *)nsap, | ||
579 | sizeof(struct sockaddr)) | ||
580 | != buflen) { | ||
581 | Aerror(stderr, "sendto", errno, *nsap); | ||
582 | badns |= (1 << ns); | ||
583 | res_close(); | ||
584 | goto next_ns; | ||
585 | } | ||
586 | } | ||
587 | |||
588 | /* | ||
589 | * Wait for reply | ||
590 | */ | ||
591 | timeout.tv_sec = (_res.retrans << try); | ||
592 | if (try > 0) | ||
593 | timeout.tv_sec /= _res.nscount; | ||
594 | if ((long) timeout.tv_sec <= 0) | ||
595 | timeout.tv_sec = 1; | ||
596 | timeout.tv_usec = 0; | ||
597 | wait: | ||
598 | dsmaskp = (fd_set *)calloc(howmany(s+1, NFDBITS), | ||
599 | sizeof(fd_mask)); | ||
600 | if (dsmaskp == NULL) { | ||
601 | res_close(); | ||
602 | goto next_ns; | ||
603 | } | ||
604 | FD_SET(s, dsmaskp); | ||
605 | n = select(s+1, dsmaskp, (fd_set *)NULL, | ||
606 | (fd_set *)NULL, &timeout); | ||
607 | free(dsmaskp); | ||
608 | if (n < 0) { | ||
609 | if (errno == EINTR) | ||
610 | goto wait; | ||
611 | Perror(stderr, "select", errno); | ||
612 | res_close(); | ||
613 | goto next_ns; | ||
614 | } | ||
615 | if (n == 0) { | ||
616 | /* | ||
617 | * timeout | ||
618 | */ | ||
619 | Dprint(_res.options & RES_DEBUG, | ||
620 | (stdout, ";; timeout\n")); | ||
621 | gotsomewhere = 1; | ||
622 | res_close(); | ||
623 | goto next_ns; | ||
624 | } | ||
625 | errno = 0; | ||
626 | fromlen = sizeof(struct sockaddr_in); | ||
627 | resplen = recvfrom(s, (char*)ans, anssiz, 0, | ||
628 | (struct sockaddr *)&from, &fromlen); | ||
629 | if (resplen <= 0) { | ||
630 | Perror(stderr, "recvfrom", errno); | ||
631 | res_close(); | ||
632 | goto next_ns; | ||
633 | } | ||
634 | gotsomewhere = 1; | ||
635 | if (hp->id != anhp->id) { | ||
636 | /* | ||
637 | * response from old query, ignore it. | ||
638 | * XXX - potential security hazard could | ||
639 | * be detected here. | ||
640 | */ | ||
641 | DprintQ((_res.options & RES_DEBUG) || | ||
642 | (_res.pfcode & RES_PRF_REPLY), | ||
643 | (stdout, ";; old answer:\n"), | ||
644 | ans, (resplen>anssiz)?anssiz:resplen); | ||
645 | goto wait; | ||
646 | } | ||
647 | #if CHECK_SRVR_ADDR | ||
648 | if (!(_res.options & RES_INSECURE1) && | ||
649 | !res_isourserver(&from)) { | ||
650 | /* | ||
651 | * response from wrong server? ignore it. | ||
652 | * XXX - potential security hazard could | ||
653 | * be detected here. | ||
654 | */ | ||
655 | DprintQ((_res.options & RES_DEBUG) || | ||
656 | (_res.pfcode & RES_PRF_REPLY), | ||
657 | (stdout, ";; not our server:\n"), | ||
658 | ans, (resplen>anssiz)?anssiz:resplen); | ||
659 | goto wait; | ||
660 | } | ||
661 | #endif | ||
662 | if (!(_res.options & RES_INSECURE2) && | ||
663 | !res_queriesmatch(buf, buf + buflen, | ||
664 | ans, ans + anssiz)) { | ||
665 | /* | ||
666 | * response contains wrong query? ignore it. | ||
667 | * XXX - potential security hazard could | ||
668 | * be detected here. | ||
669 | */ | ||
670 | DprintQ((_res.options & RES_DEBUG) || | ||
671 | (_res.pfcode & RES_PRF_REPLY), | ||
672 | (stdout, ";; wrong query name:\n"), | ||
673 | ans, (resplen>anssiz)?anssiz:resplen); | ||
674 | goto wait; | ||
675 | } | ||
676 | if (anhp->rcode == SERVFAIL || | ||
677 | anhp->rcode == NOTIMP || | ||
678 | anhp->rcode == REFUSED) { | ||
679 | DprintQ(_res.options & RES_DEBUG, | ||
680 | (stdout, "server rejected query:\n"), | ||
681 | ans, (resplen>anssiz)?anssiz:resplen); | ||
682 | badns |= (1 << ns); | ||
683 | res_close(); | ||
684 | /* don't retry if called from dig */ | ||
685 | if (!_res.pfcode) | ||
686 | goto next_ns; | ||
687 | } | ||
688 | if (!(_res.options & RES_IGNTC) && anhp->tc) { | ||
689 | /* | ||
690 | * get rest of answer; | ||
691 | * use TCP with same server. | ||
692 | */ | ||
693 | Dprint(_res.options & RES_DEBUG, | ||
694 | (stdout, ";; truncated answer\n")); | ||
695 | v_circuit = 1; | ||
696 | res_close(); | ||
697 | goto same_ns; | ||
698 | } | ||
699 | } /*if vc/dg*/ | ||
700 | Dprint((_res.options & RES_DEBUG) || | ||
701 | ((_res.pfcode & RES_PRF_REPLY) && | ||
702 | (_res.pfcode & RES_PRF_HEAD1)), | ||
703 | (stdout, ";; got answer:\n")); | ||
704 | DprintQ((_res.options & RES_DEBUG) || | ||
705 | (_res.pfcode & RES_PRF_REPLY), | ||
706 | (stdout, ""), | ||
707 | ans, (resplen>anssiz)?anssiz:resplen); | ||
708 | /* | ||
709 | * If using virtual circuits, we assume that the first server | ||
710 | * is preferred over the rest (i.e. it is on the local | ||
711 | * machine) and only keep that one open. | ||
712 | * If we have temporarily opened a virtual circuit, | ||
713 | * or if we haven't been asked to keep a socket open, | ||
714 | * close the socket. | ||
715 | */ | ||
716 | if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) || | ||
717 | !(_res.options & RES_STAYOPEN)) { | ||
718 | res_close(); | ||
719 | } | ||
720 | if (Rhook) { | ||
721 | int done = 0, loops = 0; | ||
722 | |||
723 | do { | ||
724 | res_sendhookact act; | ||
725 | |||
726 | act = (*Rhook)(nsap, buf, buflen, | ||
727 | ans, anssiz, &resplen); | ||
728 | switch (act) { | ||
729 | case res_goahead: | ||
730 | case res_done: | ||
731 | done = 1; | ||
732 | break; | ||
733 | case res_nextns: | ||
734 | res_close(); | ||
735 | goto next_ns; | ||
736 | case res_modified: | ||
737 | /* give the hook another try */ | ||
738 | if (++loops < 42) /*doug adams*/ | ||
739 | break; | ||
740 | /*FALLTHROUGH*/ | ||
741 | case res_error: | ||
742 | /*FALLTHROUGH*/ | ||
743 | default: | ||
744 | return (-1); | ||
745 | } | ||
746 | } while (!done); | ||
747 | |||
748 | } | ||
749 | return (resplen); | ||
750 | next_ns: ; | ||
751 | } /*foreach ns*/ | ||
752 | } /*foreach retry*/ | ||
753 | res_close(); | ||
754 | if (!v_circuit) { | ||
755 | if (!gotsomewhere) | ||
756 | errno = ECONNREFUSED; /* no nameservers found */ | ||
757 | else | ||
758 | errno = ETIMEDOUT; /* no answer obtained */ | ||
759 | } else | ||
760 | errno = terrno; | ||
761 | return (-1); | ||
762 | } | ||
763 | |||
764 | /* | ||
765 | * This routine is for closing the socket if a virtual circuit is used and | ||
766 | * the program wants to close it. This provides support for endhostent() | ||
767 | * which expects to close the socket. | ||
768 | * | ||
769 | * This routine is not expected to be user visible. | ||
770 | */ | ||
771 | void | ||
772 | res_close() | ||
773 | { | ||
774 | if (s >= 0) { | ||
775 | (void) close(s); | ||
776 | s = -1; | ||
777 | connected = 0; | ||
778 | vc = 0; | ||
779 | } | ||
780 | } | ||
diff --git a/src/lib/libc/net/resolver.3 b/src/lib/libc/net/resolver.3 new file mode 100644 index 0000000000..98718d448a --- /dev/null +++ b/src/lib/libc/net/resolver.3 | |||
@@ -0,0 +1,345 @@ | |||
1 | .\" $OpenBSD: resolver.3,v 1.5 1998/09/05 17:41:44 deraadt Exp $ | ||
2 | .\" | ||
3 | .\" Copyright (c) 1985, 1991, 1993 | ||
4 | .\" The Regents of the University of California. All rights reserved. | ||
5 | .\" | ||
6 | .\" Redistribution and use in source and binary forms, with or without | ||
7 | .\" modification, are permitted provided that the following conditions | ||
8 | .\" are met: | ||
9 | .\" 1. Redistributions of source code must retain the above copyright | ||
10 | .\" notice, this list of conditions and the following disclaimer. | ||
11 | .\" 2. Redistributions in binary form must reproduce the above copyright | ||
12 | .\" notice, this list of conditions and the following disclaimer in the | ||
13 | .\" documentation and/or other materials provided with the distribution. | ||
14 | .\" 3. All advertising materials mentioning features or use of this software | ||
15 | .\" must display the following acknowledgement: | ||
16 | .\" This product includes software developed by the University of | ||
17 | .\" California, Berkeley and its contributors. | ||
18 | .\" 4. Neither the name of the University nor the names of its contributors | ||
19 | .\" may be used to endorse or promote products derived from this software | ||
20 | .\" without specific prior written permission. | ||
21 | .\" | ||
22 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
23 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
24 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
26 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
27 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
28 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
29 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
30 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
31 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
32 | .\" SUCH DAMAGE. | ||
33 | .\" | ||
34 | .Dd June 4, 1993 | ||
35 | .Dt RESOLVER 3 | ||
36 | .Os BSD 4.3 | ||
37 | .Sh NAME | ||
38 | .Nm res_query , | ||
39 | .Nm res_search , | ||
40 | .Nm res_mkquery , | ||
41 | .Nm res_send , | ||
42 | .Nm res_init , | ||
43 | .Nm dn_comp , | ||
44 | .Nm dn_expand | ||
45 | .Nd resolver routines | ||
46 | .Sh SYNOPSIS | ||
47 | .Fd #include <sys/types.h> | ||
48 | .Fd #include <netinet/in.h> | ||
49 | .Fd #include <arpa/nameser.h> | ||
50 | .Fd #include <resolv.h> | ||
51 | .Fo res_query | ||
52 | .Fa "char *dname" | ||
53 | .Fa "int class" | ||
54 | .Fa "int type" | ||
55 | .Fa "u_char *answer" | ||
56 | .Fa "int anslen" | ||
57 | .Fc | ||
58 | .Fo res_search | ||
59 | .Fa "char *dname" | ||
60 | .Fa "int class" | ||
61 | .Fa "int type" | ||
62 | .Fa "u_char *answer" | ||
63 | .Fa "int anslen" | ||
64 | .Fc | ||
65 | .Fo res_mkquery | ||
66 | .Fa "int op" | ||
67 | .Fa "char *dname" | ||
68 | .Fa "int class" | ||
69 | .Fa "int type" | ||
70 | .Fa "char *data" | ||
71 | .Fa "int datalen" | ||
72 | .Fa "struct rrec *newrr" | ||
73 | .Fa "char *buf" | ||
74 | .Fa "int buflen" | ||
75 | .Fc | ||
76 | .Fo res_send | ||
77 | .Fa "char *msg" | ||
78 | .Fa "int msglen" | ||
79 | .Fa "char *answer" | ||
80 | .Fa "int anslen" | ||
81 | .Fc | ||
82 | .Fn res_init | ||
83 | .Fo dn_comp | ||
84 | .Fa "char *exp_dn" | ||
85 | .Fa "char *comp_dn" | ||
86 | .Fa "int length" | ||
87 | .Fa "char **dnptrs" | ||
88 | .Fa "char **lastdnptr" | ||
89 | .Fc | ||
90 | .Fo dn_expand | ||
91 | .Fa "u_char *msg" | ||
92 | .Fa "u_char *eomorig" | ||
93 | .Fa "u_char *comp_dn" | ||
94 | .Fa "u_char *exp_dn" | ||
95 | .Fa "int length" | ||
96 | .Fc | ||
97 | .Sh DESCRIPTION | ||
98 | These routines are used for making, sending and interpreting | ||
99 | query and reply messages with Internet domain name servers. | ||
100 | .Pp | ||
101 | Global configuration and state information that is used by the | ||
102 | resolver routines is kept in the structure | ||
103 | .Em _res . | ||
104 | Most of the values have reasonable defaults and can be ignored. | ||
105 | Options | ||
106 | stored in | ||
107 | .Em _res.options | ||
108 | are defined in | ||
109 | .Pa resolv.h | ||
110 | and are as follows. | ||
111 | Options are stored as a simple bit mask containing the bitwise ``or'' | ||
112 | of the options enabled. | ||
113 | .Bl -tag -width RES_USE_INET6 | ||
114 | .It Dv RES_INIT | ||
115 | True if the initial name server address and default domain name are | ||
116 | initialized (i.e., | ||
117 | .Fn res_init | ||
118 | has been called). | ||
119 | .It Dv RES_DEBUG | ||
120 | Print debugging messages. | ||
121 | .It Dv RES_AAONLY | ||
122 | Accept authoritative answers only. | ||
123 | With this option, | ||
124 | .Fn res_send | ||
125 | should continue until it finds an authoritative answer or finds an error. | ||
126 | Currently this is not implemented. | ||
127 | .It Dv RES_USEVC | ||
128 | Use | ||
129 | .Tn TCP | ||
130 | connections for queries instead of | ||
131 | .Tn UDP | ||
132 | datagrams. | ||
133 | .It Dv RES_STAYOPEN | ||
134 | Used with | ||
135 | .Dv RES_USEVC | ||
136 | to keep the | ||
137 | .Tn TCP | ||
138 | connection open between | ||
139 | queries. | ||
140 | This is useful only in programs that regularly do many queries. | ||
141 | .Tn UDP | ||
142 | should be the normal mode used. | ||
143 | .It Dv RES_IGNTC | ||
144 | Unused currently (ignore truncation errors, i.e., don't retry with | ||
145 | .Tn TCP ) . | ||
146 | .It Dv RES_RECURSE | ||
147 | Set the recursion-desired bit in queries. | ||
148 | This is the default. | ||
149 | .Pf ( Fn res_send | ||
150 | does not do iterative queries and expects the name server | ||
151 | to handle recursion.) | ||
152 | .It Dv RES_DEFNAMES | ||
153 | If set, | ||
154 | .Fn res_search | ||
155 | will append the default domain name to single-component names | ||
156 | (those that do not contain a dot). | ||
157 | This option is enabled by default. | ||
158 | .It Dv RES_DNSRCH | ||
159 | If this option is set, | ||
160 | .Fn res_search | ||
161 | will search for host names in the current domain and in parent domains; see | ||
162 | .Xr hostname 7 . | ||
163 | This is used by the standard host lookup routine | ||
164 | .Xr gethostbyname 3 . | ||
165 | This option is enabled by default. | ||
166 | .It Dv RES_USE_INET6 | ||
167 | Enable support for IPv6 addresses. | ||
168 | .El | ||
169 | .Pp | ||
170 | The | ||
171 | .Fn res_init | ||
172 | routine | ||
173 | reads the configuration file (if any; see | ||
174 | .Xr resolv.conf 5 ) | ||
175 | to get the default domain name, | ||
176 | search list and | ||
177 | the Internet address of the local name server(s). | ||
178 | If no server is configured, the host running | ||
179 | the resolver is tried. | ||
180 | The current domain name is defined by the hostname | ||
181 | if not specified in the configuration file; | ||
182 | it can be overridden by the environment variable | ||
183 | .Ev LOCALDOMAIN . | ||
184 | This environment variable may contain several blank-separated | ||
185 | tokens if you wish to override the | ||
186 | .Fa search list | ||
187 | on a per-process basis. | ||
188 | This is similar to the | ||
189 | .Fa search | ||
190 | command in the configuration file. | ||
191 | Another environment variable | ||
192 | .Ev RES_OPTIONS | ||
193 | can be set to override certain internal resolver options which | ||
194 | are otherwise set by changing fields in the | ||
195 | .Fa _res | ||
196 | structure or are inherited from the configuration file's | ||
197 | .Fa options | ||
198 | command. | ||
199 | The syntax of the | ||
200 | .Ev RES_OPTIONS | ||
201 | environment variable is explained in | ||
202 | .Xr resolv.conf 5 . | ||
203 | Initialization normally occurs on the first call | ||
204 | to one of the following routines. | ||
205 | .Pp | ||
206 | The | ||
207 | .Fn res_query | ||
208 | function provides an interface to the server query mechanism. | ||
209 | It constructs a query, sends it to the local server, | ||
210 | awaits a response, and makes preliminary checks on the reply. | ||
211 | The query requests information of the specified | ||
212 | .Fa type | ||
213 | and | ||
214 | .Fa class | ||
215 | for the specified fully-qualified domain name | ||
216 | .Fa dname . | ||
217 | The reply message is left in the | ||
218 | .Fa answer | ||
219 | buffer with length | ||
220 | .Fa anslen | ||
221 | supplied by the caller. | ||
222 | .Pp | ||
223 | The | ||
224 | .Fn res_search | ||
225 | routine makes a query and awaits a response like | ||
226 | .Fn res_query , | ||
227 | but in addition, it implements the default and search rules | ||
228 | controlled by the | ||
229 | .Dv RES_DEFNAMES | ||
230 | and | ||
231 | .Dv RES_DNSRCH | ||
232 | options. | ||
233 | It returns the first successful reply. | ||
234 | .Pp | ||
235 | The remaining routines are lower-level routines used by | ||
236 | .Fn res_query . | ||
237 | The | ||
238 | .Fn res_mkquery | ||
239 | function | ||
240 | constructs a standard query message and places it in | ||
241 | .Fa buf . | ||
242 | It returns the size of the query, or \-1 if the query is | ||
243 | larger than | ||
244 | .Fa buflen . | ||
245 | The query type | ||
246 | .Fa op | ||
247 | is usually | ||
248 | .Dv QUERY , | ||
249 | but can be any of the query types defined in | ||
250 | .Aq Pa arpa/nameser.h . | ||
251 | The domain name for the query is given by | ||
252 | .Fa dname . | ||
253 | .Fa Newrr | ||
254 | is currently unused but is intended for making update messages. | ||
255 | .Pp | ||
256 | The | ||
257 | .Fn res_send | ||
258 | routine | ||
259 | sends a pre-formatted query and returns an answer. | ||
260 | It will call | ||
261 | .Fn res_init | ||
262 | if | ||
263 | .Dv RES_INIT | ||
264 | is not set, send the query to the local name server, and | ||
265 | handle timeouts and retries. | ||
266 | The length of the reply message is returned, or | ||
267 | \-1 if there were errors. | ||
268 | .Pp | ||
269 | The | ||
270 | .Fn dn_comp | ||
271 | function | ||
272 | compresses the domain name | ||
273 | .Fa exp_dn | ||
274 | and stores it in | ||
275 | .Fa comp_dn . | ||
276 | The size of the compressed name is returned or \-1 if there were errors. | ||
277 | The size of the array pointed to by | ||
278 | .Fa comp_dn | ||
279 | is given by | ||
280 | .Fa length . | ||
281 | The compression uses | ||
282 | an array of pointers | ||
283 | .Fa dnptrs | ||
284 | to previously-compressed names in the current message. | ||
285 | The first pointer points | ||
286 | to the beginning of the message and the list ends with | ||
287 | .Dv NULL . | ||
288 | The limit to the array is specified by | ||
289 | .Fa lastdnptr . | ||
290 | A side effect of | ||
291 | .Fn dn_comp | ||
292 | is to update the list of pointers for | ||
293 | labels inserted into the message | ||
294 | as the name is compressed. | ||
295 | If | ||
296 | .Em dnptr | ||
297 | is | ||
298 | .Dv NULL, names are not compressed. | ||
299 | If | ||
300 | .Fa lastdnptr | ||
301 | is | ||
302 | .Dv NULL , | ||
303 | the list of labels is not updated. | ||
304 | .Pp | ||
305 | The | ||
306 | .Fn dn_expand | ||
307 | entry | ||
308 | expands the compressed domain name | ||
309 | .Fa comp_dn | ||
310 | to a full domain name | ||
311 | The compressed name is contained in a query or reply message; | ||
312 | .Fa msg | ||
313 | is a pointer to the beginning of the message. | ||
314 | The uncompressed name is placed in the buffer indicated by | ||
315 | .Fa exp_dn | ||
316 | which is of size | ||
317 | .Fa length . | ||
318 | The size of compressed name is returned or \-1 if there was an error. | ||
319 | .Sh FILES | ||
320 | .Bl -tag -width Pa | ||
321 | /etc/resolv.conf | ||
322 | The configuration file | ||
323 | see | ||
324 | .Xr resolv.conf 5 . | ||
325 | .El | ||
326 | .Sh SEE ALSO | ||
327 | .Xr gethostbyname 3 , | ||
328 | .Xr named 8 , | ||
329 | .Xr resolv.conf 5 , | ||
330 | .Xr hostname 7 , | ||
331 | .Pp | ||
332 | .%T RFC1032 , | ||
333 | .%T RFC1033 , | ||
334 | .%T RFC1034 , | ||
335 | .%T RFC1035 , | ||
336 | .%T RFC1535 , | ||
337 | .%T RFC974 | ||
338 | .Rs | ||
339 | .%T "Name Server Operations Guide for BIND" | ||
340 | .Re | ||
341 | .Sh HISTORY | ||
342 | The | ||
343 | .Nm | ||
344 | function appeared in | ||
345 | .Bx 4.3 . | ||
diff --git a/src/lib/libc/net/send.c b/src/lib/libc/net/send.c new file mode 100644 index 0000000000..8495931ca3 --- /dev/null +++ b/src/lib/libc/net/send.c | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1988, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: send.c,v 1.2 1996/08/19 08:29:52 tholo Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | #include <sys/types.h> | ||
39 | #include <sys/socket.h> | ||
40 | |||
41 | #include <stddef.h> | ||
42 | |||
43 | ssize_t | ||
44 | send(s, msg, len, flags) | ||
45 | int s, flags; | ||
46 | size_t len; | ||
47 | const void *msg; | ||
48 | { | ||
49 | return (sendto(s, msg, len, flags, NULL, 0)); | ||
50 | } | ||
diff --git a/src/lib/libc/net/sethostent.c b/src/lib/libc/net/sethostent.c new file mode 100644 index 0000000000..5392a2f11b --- /dev/null +++ b/src/lib/libc/net/sethostent.c | |||
@@ -0,0 +1,60 @@ | |||
1 | /* | ||
2 | * Copyright (c) 1985, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
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 | */ | ||
33 | |||
34 | #if defined(LIBC_SCCS) && !defined(lint) | ||
35 | static char rcsid[] = "$OpenBSD: sethostent.c,v 1.4 1997/03/15 21:53:50 pefo Exp $"; | ||
36 | #endif /* LIBC_SCCS and not lint */ | ||
37 | |||
38 | #include <sys/param.h> | ||
39 | #include <netinet/in.h> | ||
40 | #include <arpa/nameser.h> | ||
41 | #include <netdb.h> | ||
42 | #include <resolv.h> | ||
43 | |||
44 | void | ||
45 | sethostent(stayopen) | ||
46 | int stayopen; | ||
47 | { | ||
48 | |||
49 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) | ||
50 | return; | ||
51 | if (stayopen) | ||
52 | _res.options |= RES_STAYOPEN | RES_USEVC; | ||
53 | } | ||
54 | |||
55 | void | ||
56 | endhostent() | ||
57 | { | ||
58 | _res.options &= ~(RES_STAYOPEN | RES_USEVC); | ||
59 | res_close(); | ||
60 | } | ||