summaryrefslogtreecommitdiff
path: root/src/lib/libc/net
diff options
context:
space:
mode:
authorcvs2svn <admin@example.com>1998-10-19 21:47:13 +0000
committercvs2svn <admin@example.com>1998-10-19 21:47:13 +0000
commitf954a53a9a7dced3fb4c80b1e8dd267981ae025d (patch)
treec667406046ddb1efca5ed4316b02e43494241660 /src/lib/libc/net
parent536c76cbb863bab152f19842ab88772c01e922c7 (diff)
downloadopenbsd-OPENBSD_2_4.tar.gz
openbsd-OPENBSD_2_4.tar.bz2
openbsd-OPENBSD_2_4.zip
This commit was manufactured by cvs2git to create branch 'OPENBSD_2_4'.OPENBSD_2_4
Diffstat (limited to 'src/lib/libc/net')
-rw-r--r--src/lib/libc/net/Makefile.inc56
-rw-r--r--src/lib/libc/net/base64.c317
-rw-r--r--src/lib/libc/net/byteorder.3155
-rw-r--r--src/lib/libc/net/ethers.3109
-rw-r--r--src/lib/libc/net/ethers.c270
-rw-r--r--src/lib/libc/net/gethostbyname.3266
-rw-r--r--src/lib/libc/net/gethostnamadr.c1079
-rw-r--r--src/lib/libc/net/getnetbyaddr.c56
-rw-r--r--src/lib/libc/net/getnetbyname.c62
-rw-r--r--src/lib/libc/net/getnetent.3148
-rw-r--r--src/lib/libc/net/getnetent.c129
-rw-r--r--src/lib/libc/net/getnetnamadr.c382
-rw-r--r--src/lib/libc/net/getproto.c55
-rw-r--r--src/lib/libc/net/getprotoent.3144
-rw-r--r--src/lib/libc/net/getprotoent.c123
-rw-r--r--src/lib/libc/net/getprotoname.c62
-rw-r--r--src/lib/libc/net/getservbyname.c65
-rw-r--r--src/lib/libc/net/getservbyport.c60
-rw-r--r--src/lib/libc/net/getservent.3155
-rw-r--r--src/lib/libc/net/getservent.c125
-rw-r--r--src/lib/libc/net/herror.c121
-rw-r--r--src/lib/libc/net/htonl.c25
-rw-r--r--src/lib/libc/net/htons.c29
-rw-r--r--src/lib/libc/net/inet.3319
-rw-r--r--src/lib/libc/net/inet_addr.c187
-rw-r--r--src/lib/libc/net/inet_lnaof.c59
-rw-r--r--src/lib/libc/net/inet_makeaddr.c62
-rw-r--r--src/lib/libc/net/inet_net.3149
-rw-r--r--src/lib/libc/net/inet_net_ntop.c139
-rw-r--r--src/lib/libc/net/inet_net_pton.c207
-rw-r--r--src/lib/libc/net/inet_neta.c83
-rw-r--r--src/lib/libc/net/inet_netof.c58
-rw-r--r--src/lib/libc/net/inet_network.c92
-rw-r--r--src/lib/libc/net/inet_ntoa.c59
-rw-r--r--src/lib/libc/net/inet_ntop.c194
-rw-r--r--src/lib/libc/net/inet_pton.c220
-rw-r--r--src/lib/libc/net/ipx.3126
-rw-r--r--src/lib/libc/net/ipx_addr.c229
-rw-r--r--src/lib/libc/net/ipx_ntoa.c58
-rw-r--r--src/lib/libc/net/iso_addr.3110
-rw-r--r--src/lib/libc/net/iso_addr.c119
-rw-r--r--src/lib/libc/net/link_addr.3131
-rw-r--r--src/lib/libc/net/linkaddr.c158
-rw-r--r--src/lib/libc/net/ns.3130
-rw-r--r--src/lib/libc/net/ns_addr.c228
-rw-r--r--src/lib/libc/net/ns_ntoa.c101
-rw-r--r--src/lib/libc/net/nsap_addr.c109
-rw-r--r--src/lib/libc/net/ntohl.c25
-rw-r--r--src/lib/libc/net/ntohs.c29
-rw-r--r--src/lib/libc/net/rcmd.3227
-rw-r--r--src/lib/libc/net/rcmd.c607
-rw-r--r--src/lib/libc/net/rcmdsh.3108
-rw-r--r--src/lib/libc/net/rcmdsh.c124
-rw-r--r--src/lib/libc/net/recv.c50
-rw-r--r--src/lib/libc/net/res_comp.c510
-rw-r--r--src/lib/libc/net/res_data.c117
-rw-r--r--src/lib/libc/net/res_debug.c1518
-rw-r--r--src/lib/libc/net/res_init.c518
-rw-r--r--src/lib/libc/net/res_mkquery.c195
-rw-r--r--src/lib/libc/net/res_query.c398
-rw-r--r--src/lib/libc/net/res_random.c233
-rw-r--r--src/lib/libc/net/res_send.c780
-rw-r--r--src/lib/libc/net/resolver.3345
-rw-r--r--src/lib/libc/net/send.c50
-rw-r--r--src/lib/libc/net/sethostent.c60
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
6CFLAGS+=-DRESOLVSORT
7
8SRCS+= 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
24MAN+= 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
28MLINKS+=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
33MLINKS+=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
35MLINKS+=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
39MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \
40 getnetent.3 getnetbyname.3 getnetent.3 setnetent.3
41MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \
42 getprotoent.3 getprotobynumber.3 getprotoent.3 setprotoent.3
43MLINKS+=getservent.3 endservent.3 getservent.3 getservbyname.3 \
44 getservent.3 getservbyport.3 getservent.3 setservent.3
45MLINKS+=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
49MLINKS+=iso_addr.3 iso_ntoa.3
50MLINKS+=link_addr.3 link_ntoa.3
51MLINKS+=ipx.3 ipx_addr.3 ipx.3 ipx_ntoa.3
52MLINKS+=ns.3 ns_addr.3 ns.3 ns_ntoa.3
53MLINKS+=rcmd.3 iruserok.3 rcmd.3 rresvport.3 rcmd.3 ruserok.3
54MLINKS+=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
61static const char Base64[] =
62 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
63static const char Pad64 = '=';
64
65/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
66 The following encoding technique is taken from RFC 1521 by Borenstein
67 and Freed. It is reproduced here in a slightly edited form for
68 convenience.
69
70 A 65-character subset of US-ASCII is used, enabling 6 bits to be
71 represented per printable character. (The extra 65th character, "=",
72 is used to signify a special processing function.)
73
74 The encoding process represents 24-bit groups of input bits as output
75 strings of 4 encoded characters. Proceeding from left to right, a
76 24-bit input group is formed by concatenating 3 8-bit input groups.
77 These 24 bits are then treated as 4 concatenated 6-bit groups, each
78 of which is translated into a single digit in the base64 alphabet.
79
80 Each 6-bit group is used as an index into an array of 64 printable
81 characters. The character referenced by the index is placed in the
82 output string.
83
84 Table 1: The Base64 Alphabet
85
86 Value Encoding Value Encoding Value Encoding Value Encoding
87 0 A 17 R 34 i 51 z
88 1 B 18 S 35 j 52 0
89 2 C 19 T 36 k 53 1
90 3 D 20 U 37 l 54 2
91 4 E 21 V 38 m 55 3
92 5 F 22 W 39 n 56 4
93 6 G 23 X 40 o 57 5
94 7 H 24 Y 41 p 58 6
95 8 I 25 Z 42 q 59 7
96 9 J 26 a 43 r 60 8
97 10 K 27 b 44 s 61 9
98 11 L 28 c 45 t 62 +
99 12 M 29 d 46 u 63 /
100 13 N 30 e 47 v
101 14 O 31 f 48 w (pad) =
102 15 P 32 g 49 x
103 16 Q 33 h 50 y
104
105 Special processing is performed if fewer than 24 bits are available
106 at the end of the data being encoded. A full encoding quantum is
107 always completed at the end of a quantity. When fewer than 24 input
108 bits are available in an input group, zero bits are added (on the
109 right) to form an integral number of 6-bit groups. Padding at the
110 end of the data is performed using the '=' character.
111
112 Since all base64 input is an integral number of octets, only the
113 -------------------------------------------------
114 following cases can arise:
115
116 (1) the final quantum of encoding input is an integral
117 multiple of 24 bits; here, the final unit of encoded
118 output will be an integral multiple of 4 characters
119 with no "=" padding,
120 (2) the final quantum of encoding input is exactly 8 bits;
121 here, the final unit of encoded output will be two
122 characters followed by two "=" padding characters, or
123 (3) the final quantum of encoding input is exactly 16 bits;
124 here, the final unit of encoded output will be three
125 characters followed by one "=" padding character.
126 */
127
128int
129b64_ntop(src, srclength, target, targsize)
130 u_char const *src;
131 size_t srclength;
132 char *target;
133 size_t targsize;
134{
135 size_t datalength = 0;
136 u_char input[3];
137 u_char output[4];
138 int i;
139
140 while (2 < srclength) {
141 input[0] = *src++;
142 input[1] = *src++;
143 input[2] = *src++;
144 srclength -= 3;
145
146 output[0] = input[0] >> 2;
147 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
148 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
149 output[3] = input[2] & 0x3f;
150 Assert(output[0] < 64);
151 Assert(output[1] < 64);
152 Assert(output[2] < 64);
153 Assert(output[3] < 64);
154
155 if (datalength + 4 > targsize)
156 return (-1);
157 target[datalength++] = Base64[output[0]];
158 target[datalength++] = Base64[output[1]];
159 target[datalength++] = Base64[output[2]];
160 target[datalength++] = Base64[output[3]];
161 }
162
163 /* Now we worry about padding. */
164 if (0 != srclength) {
165 /* Get what's left. */
166 input[0] = input[1] = input[2] = '\0';
167 for (i = 0; i < srclength; i++)
168 input[i] = *src++;
169
170 output[0] = input[0] >> 2;
171 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
172 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
173 Assert(output[0] < 64);
174 Assert(output[1] < 64);
175 Assert(output[2] < 64);
176
177 if (datalength + 4 > targsize)
178 return (-1);
179 target[datalength++] = Base64[output[0]];
180 target[datalength++] = Base64[output[1]];
181 if (srclength == 1)
182 target[datalength++] = Pad64;
183 else
184 target[datalength++] = Base64[output[2]];
185 target[datalength++] = Pad64;
186 }
187 if (datalength >= targsize)
188 return (-1);
189 target[datalength] = '\0'; /* Returned value doesn't count \0. */
190 return (datalength);
191}
192
193/* skips all whitespace anywhere.
194 converts characters, four at a time, starting at (or after)
195 src from base - 64 numbers into three 8 bit bytes in the target area.
196 it returns the number of data bytes stored at the target, or -1 on error.
197 */
198
199int
200b64_pton(src, target, targsize)
201 char const *src;
202 u_char *target;
203 size_t targsize;
204{
205 int tarindex, state, ch;
206 char *pos;
207
208 state = 0;
209 tarindex = 0;
210
211 while ((ch = *src++) != '\0') {
212 if (isspace(ch)) /* Skip whitespace anywhere. */
213 continue;
214
215 if (ch == Pad64)
216 break;
217
218 pos = strchr(Base64, ch);
219 if (pos == 0) /* A non-base64 character. */
220 return (-1);
221
222 switch (state) {
223 case 0:
224 if (target) {
225 if (tarindex >= targsize)
226 return (-1);
227 target[tarindex] = (pos - Base64) << 2;
228 }
229 state = 1;
230 break;
231 case 1:
232 if (target) {
233 if (tarindex + 1 >= targsize)
234 return (-1);
235 target[tarindex] |= (pos - Base64) >> 4;
236 target[tarindex+1] = ((pos - Base64) & 0x0f)
237 << 4 ;
238 }
239 tarindex++;
240 state = 2;
241 break;
242 case 2:
243 if (target) {
244 if (tarindex + 1 >= targsize)
245 return (-1);
246 target[tarindex] |= (pos - Base64) >> 2;
247 target[tarindex+1] = ((pos - Base64) & 0x03)
248 << 6;
249 }
250 tarindex++;
251 state = 3;
252 break;
253 case 3:
254 if (target) {
255 if (tarindex >= targsize)
256 return (-1);
257 target[tarindex] |= (pos - Base64);
258 }
259 tarindex++;
260 state = 0;
261 break;
262 }
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
85These routines convert 16 and 32 bit quantities between different
86byte orderings. The "swap" functions reverse the byte ordering of
87the given quantity, the others converts either from/to the native
88byte order used by the host to/from either little- or big-endian (a.k.a
89network) order.
90.Pp
91Apart from the "swap" functions, the names can be described by this form:
92{src-order}to{dst-order}{size}.
93Both {src-order} and {dst-order} can take the following forms:
94.Bl -tag -width "be "
95.It Em h
96host order
97.It Em n
98network order (big-endian)
99.It Em be
100big-endian (Most significant byte first)
101.It Em le
102little-endian (Least significant byte first)
103.El
104.Pp
105One of the specified orderings must be "h".
106{Size} will take these forms:
107.Bl -tag -width "32 "
108.It Em l
109long (32-bit, used in conjunction with forms involving "n")
110.It Em s
111short (16-bit, used in conjunction with forms involving "n")
112.It Em 16
11316-bit
114.It Em 32
11532-bit
116.El
117.Pp
118The "swap" functions are of the form: swap{size}.
119.Pp
120Names involving "n" convert quantities between network
121byte order and host byte order. The last letter (s/l) is a mnemonic
122for the traditional names for such quantities, short and long,
123respectively. Today, the C concept of "short"/"long" integers
124need not coincide with this traditional misunderstanding.
125On machines which have a byte order which is the same as the network
126order, routines are defined as null macros.
127.Pp
128The functions involving either "be", "le" or "swap" use the numbers
129(16/32) for specifying the bitwidth of the quantities they operate on.
130Currently all supported architectures are either big- or little-endian
131so either the "be" or the "le" variants are implemented as null macros.
132.Pp
133The routines mentioned above which have either {src-order} or {dst-order}
134set to "n" are most often used in
135conjunction with Internet addresses and ports as returned by
136.Xr gethostbyname 3
137and
138.Xr getservent 3 .
139.Sh SEE ALSO
140.Xr gethostbyname 3 ,
141.Xr getservent 3
142.Sh HISTORY
143The
144.Nm byteorder
145functions appeared in
146.Bx 4.2 .
147.Sh BUGS
148On the
149.Tn vax ,
150.Tn alpha ,
151.Tn i386 ,
152and so far
153.Tn mips
154bytes are handled backwards from most everyone else in
155the 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
29Ethernet addresses are represented by the
30following structure:
31.Bd -literal -offset indent
32struct ether_addr {
33 u_int8_t ether_addr_octet[6];
34};
35.Ed
36.Pp
37The
38.Fn ether_ntoa
39function converts this structure into an ASCII string of the form
40``xx:xx:xx:xx:xx:xx'', consisting of 6 hexadecimal numbers separated
41by colons. It returns a pointer to a static buffer that is reused for
42each call.
43The
44.Fn ether_aton
45converts an ASCII string of the same form and to a structure
46containing the 6 octets of the address. It returns a pointer to a
47static structure that is reused for each call.
48.Pp
49The
50.Fn ether_ntohost
51and
52.Fn ether_hostton
53functions interrogate the data base mapping host names to Ethernet
54addresses,
55.Pa /etc/ethers .
56The
57.Fn ether_ntohost
58function looks up the given Ethernet address and writes the associated
59host name into the character buffer passed. This buffer should be
60.Ev MAXHOSTNAMELEN
61characters in size.
62The
63.Fn ether_hostton
64function looks up the given host name and writes the associated
65Ethernet address into the structure passed. Both functions return
66zero if they find the requested host name or address, and -1 if not.
67.Pp
68Each call reads
69.Pa /etc/ethers
70from the beginning; if a + appears alone on a line in the file, then
71.Fn ether_hostton
72will consult the
73.Pa ethers.byname
74YP map, and
75.Fn ether_ntohost
76will consult the
77.Pa ethers.byaddr
78YP map.
79.Pp
80The
81.Fn ether_line
82function parses a line from the
83.Pa /etc/ethers
84file and fills in the passed ``struct ether_addr'' and character
85buffer with the Ethernet address and host name on the line. It
86returns zero if the line was successfully parsed and -1 if not.
87The character buffer buffer should be
88.Ev MAXHOSTNAMELEN
89characters 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
97The
98.Fn ether_ntoa ,
99.Fn ether_aton ,
100.Fn ether_ntohost ,
101.Fn ether_hostton ,
102and
103.Fn ether_line
104functions were adopted from SunOS and appeared in
105NetBSD 0.9b.
106.Sh BUGS
107The data space used by these functions is static; if future use
108requires the data, it should be copied before any subsequent calls to
109these 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)
37static 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
57static char * _ether_aton __P((char *, struct ether_addr *));
58
59char *
60ether_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
80static 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
107struct ether_addr *
108ether_aton(s)
109 char *s;
110{
111 static struct ether_addr n;
112
113 return (_ether_aton(s, &n) ? &n : NULL);
114}
115
116int
117ether_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
187int
188ether_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
242int
243ether_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
267bad:
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
67The
68.Fn gethostbyname
69and
70.Fn gethostbyaddr
71functions
72each return a pointer to an object with the
73following structure describing an internet host
74referenced by name or by address, respectively.
75This structure contains either the information obtained from the name server,
76.Xr named 8 ,
77broken-out fields from a line in
78.Pa /etc/hosts ,
79or database entries supplied by the
80.Xr yp 8
81system .
82If the local name server is not running these routines do a lookup in
83.Pa /etc/hosts .
84.Bd -literal
85struct 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
95The members of this structure are:
96.Bl -tag -width h_addr_list
97.It Fa h_name
98Official name of the host.
99.It Fa h_aliases
100A zero terminated array of alternate names for the host.
101.It Fa h_addrtype
102The type of address being returned.
103.It Fa h_length
104The length, in bytes, of the address.
105.It Fa h_addr_list
106A zero terminated array of network addresses for the host.
107Host addresses are returned in network byte order.
108.It Fa h_addr
109The first address in
110.Fa h_addr_list ;
111this is for backward compatibility.
112.El
113.Pp
114When using the nameserver,
115.Fn gethostbyname
116will search for the named host in the current domain and its parents
117unless the name ends in a dot.
118If the name contains no dot, and if the environment variable
119.Dq Ev HOSTALIASES
120contains the name of an alias file, the alias file will first be searched
121for an alias matching the input name.
122See
123.Xr hostname 7
124for the domain search procedure and the alias file format.
125.Pp
126.Fn Gethostbyname2
127is an advanced form of
128.Fn gethostbyname
129which allows lookups in address families other than
130.Dv AF_INET ,
131for example
132.Dv AF_INET6 .
133.Pp
134The
135.Fn sethostent
136function
137may be used to request the use of a connected
138.Tn TCP
139socket for queries.
140If the
141.Fa stayopen
142flag is non-zero,
143this sets the option to send all queries to the name server using
144.Tn TCP
145and to retain the connection after each call to
146.Fn gethostbyname
147or
148.Fn gethostbyaddr .
149Otherwise, queries are performed using
150.Tn UDP
151datagrams.
152.Pp
153The
154.Fn endhostent
155function
156closes the
157.Tn TCP
158connection.
159.Pp
160The
161.Fn herror
162function prints an error message describing the failure. If its argument
163.Fa string
164is
165.Pf non Dv -NULL ,
166it is prepended to the message string and separated from it by a colon
167and a space. The error message is printed with a trailing newline.
168The contents of the error message is the same as that returned by
169.Fn hstrerror
170with 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
177Error return status from
178.Fn gethostbyname ,
179.Fn gethostbyname2 ,
180and
181.Fn gethostbyaddr
182is indicated by return of a null pointer.
183The external integer
184.Va h_errno
185may then be checked to see whether this is a temporary failure
186or an invalid or unknown host.
187.Pp
188The variable
189.Va h_errno
190can have the following values:
191.Bl -tag -width HOST_NOT_FOUND
192.It Dv HOST_NOT_FOUND
193No such host is known.
194.It Dv TRY_AGAIN
195This is usually a temporary error
196and means that the local server did not receive
197a response from an authoritative server.
198A retry at some later time may succeed.
199.It Dv NO_RECOVERY
200Some unexpected server failure was encountered.
201This is a non-recoverable error.
202.It Dv NO_DATA
203The requested name is valid but does not have an IP address;
204this is not a temporary error.
205This means that the name is known to the name server but there is no address
206associated with this name.
207Another type of request to the name server using this domain name
208will result in an answer;
209for 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
217The
218.Fn gethostent
219function
220reads the next line of
221.Pa /etc/hosts ,
222opening the file if necessary.
223.Pp
224The
225.Fn sethostent
226function
227opens and/or rewinds the file
228.Pa /etc/hosts .
229If the
230.Fa stayopen
231argument is non-zero,
232the file will not be closed after each call to
233.Fn gethostbyname ,
234.Fn gethostbyname2 ,
235or
236.Fn gethostbyaddr .
237.Pp
238The
239.Fn endhostent
240function
241closes the file.
242.Sh HISTORY
243The
244.Fn herror
245function appeared in
246.Bx 4.3 .
247The
248.Fn endhostent ,
249.Fn gethostbyaddr ,
250.Fn gethostbyname ,
251.Fn gethostent ,
252and
253.Fn sethostent
254functions appeared in
255.Bx 4.2 .
256.Sh BUGS
257These functions use static data storage;
258if the data is needed for future use, it should be
259copied before any subsequent calls overwrite it.
260Only the Internet
261address formats are currently understood.
262.Pp
263YP does not support any address families other than
264.Dv AF_INET
265and uses
266the 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)
55static 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
82static char *h_addr_ptrs[MAXADDRS + 1];
83
84#ifdef YP
85static char *__ypdomain;
86#endif
87
88static struct hostent host;
89static char *host_aliases[MAXALIASES];
90static char hostbuf[BUFSIZ+1];
91static 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
96static FILE *hostf = NULL;
97static int stayopen = 0;
98
99static void map_v4v6_address __P((const char *src, char *dst));
100static void map_v4v6_hostent __P((struct hostent *hp, char **bp, int *len));
101
102#ifdef RESOLVSORT
103static void addrsort __P((char **, int));
104#endif
105
106int _hokchar __P((const char *));
107
108static 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
117typedef union {
118 HEADER hdr;
119 u_char buf[MAXPACKET];
120} querybuf;
121
122typedef union {
123 int32_t al;
124 char ac;
125} align;
126
127static struct hostent *getanswer __P((const querybuf *, int, const char *,
128 int));
129
130extern int h_errno;
131
132int
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
159static struct hostent *
160getanswer(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
426struct hostent *
427gethostbyname(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
444struct hostent *
445gethostbyname2(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
588struct hostent *
589gethostbyaddr(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
699void
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
710void
711_endhtent()
712{
713 if (hostf && !stayopen) {
714 (void) fclose(hostf);
715 hostf = NULL;
716 }
717}
718
719struct 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
797struct 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
812struct 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
835struct 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
851struct 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
870nextline:
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 }
918done:
919 *q = NULL;
920 *hap = NULL;
921 return (&host);
922}
923
924struct 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
954struct 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
981static void
982map_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
1001static void
1002map_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
1030struct hostent *
1031gethostent()
1032{
1033 return (_gethtent());
1034}
1035
1036#ifdef RESOLVSORT
1037static void
1038addrsort(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)
35static 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
40extern int _net_stayopen;
41
42struct 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)
35static 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
41extern int _net_stayopen;
42
43struct 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 }
58found:
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
55The
56.Fn getnetent ,
57.Fn getnetbyname ,
58and
59.Fn getnetbyaddr
60functions
61each return a pointer to an object with the
62following structure
63containing the broken-out
64fields of a line in the network data base,
65.Pa /etc/networks .
66.Bd -literal -offset indent
67struct 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
75The members of this structure are:
76.Bl -tag -width n_addrtype
77.It Fa n_name
78The official name of the network.
79.It Fa n_aliases
80A zero terminated list of alternate names for the network.
81.It Fa n_addrtype
82The type of the network number returned; currently only AF_INET.
83.It Fa n_net
84The network number. Network numbers are returned in machine byte
85order.
86.El
87.Pp
88The
89.Fn getnetent
90function
91reads the next line of the file, opening the file if necessary.
92.Pp
93The
94.Fn setnetent
95function
96opens and rewinds the file. If the
97.Fa stayopen
98flag is non-zero,
99the net data base will not be closed after each call to
100.Fn getnetbyname
101or
102.Fn getnetbyaddr .
103.Pp
104The
105.Fn endnetent
106function
107closes the file.
108.Pp
109The
110.Fn getnetbyname
111function
112and
113.Fn getnetbyaddr
114search the domain name server if the system is configured to use one.
115If the search fails, or no name server is configured, they sequentially
116search from the beginning of the file until a matching net name or
117net address and type is found, or until
118.Dv EOF
119is encountered.
120Network 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
126Null pointer
127(0) returned on
128.Dv EOF
129or error.
130.Sh SEE ALSO
131.Xr networks 5 ,
132.Xr resolver 3
133.Sh HISTORY
134The
135.Fn getnetent ,
136.Fn getnetbyaddr ,
137.Fn getnetbyname ,
138.Fn setnetent ,
139and
140.Fn endnetent
141functions appeared in
142.Bx 4.2 .
143.Sh BUGS
144The data space used by these functions is static; if future use
145requires the data, it should be copied before any subsequent calls
146to these functions overwrite it. Only Internet network numbers
147are currently understood. Expecting network numbers to fit in no
148more 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)
35static 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
48static FILE *netf;
49static char line[BUFSIZ+1];
50static struct netent net;
51static char *net_aliases[MAXALIASES];
52int _net_stayopen;
53
54void
55setnetent(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
65void
66endnetent()
67{
68 if (netf) {
69 fclose(netf);
70 netf = NULL;
71 }
72 _net_stayopen = 0;
73}
74
75struct netent *
76getnetent()
77{
78 char *p, *cp, **q;
79 size_t len;
80
81 if (netf == NULL && (netf = fopen(_PATH_NETWORKS, "r" )) == NULL)
82 return (NULL);
83again:
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
76static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93";
77static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03";
78static char rcsid[] = "$From: getnetnamadr.c,v 8.7 1996/08/05 08:31:35 vixie Exp $";
79#else
80static 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
98extern int h_errno;
99
100struct netent *_getnetbyaddr __P((in_addr_t net, int type));
101struct netent *_getnetbyname __P((const char *name));
102
103int _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
115typedef union {
116 HEADER hdr;
117 u_char buf[MAXPACKET];
118} querybuf;
119
120typedef union {
121 long al;
122 char ac;
123} align;
124
125static struct netent *
126getnetanswer(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
245struct netent *
246getnetbyaddr(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
331struct netent *
332getnetbyname(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)
35static 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
40extern int _proto_stayopen;
41
42struct protoent *
43getprotobynumber(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
55The
56.Fn getprotoent ,
57.Fn getprotobyname ,
58and
59.Fn getprotobynumber
60functions
61each return a pointer to an object with the
62following structure
63containing the broken-out
64fields of a line in the network protocol data base,
65.Pa /etc/protocols .
66.Bd -literal -offset indent
67.Pp
68struct 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
75The members of this structure are:
76.Bl -tag -width p_aliases
77.It Fa p_name
78The official name of the protocol.
79.It Fa p_aliases
80A zero terminated list of alternate names for the protocol.
81.It Fa p_proto
82The protocol number.
83.El
84.Pp
85The
86.Fn getprotoent
87function
88reads the next line of the file, opening the file if necessary.
89.Pp
90The
91.Fn setprotoent
92function
93opens and rewinds the file. If the
94.Fa stayopen
95flag is non-zero,
96the net data base will not be closed after each call to
97.Fn getprotobyname
98or
99.Fn getprotobynumber .
100.Pp
101The
102.Fn endprotoent
103function
104closes the file.
105.Pp
106The
107.Fn getprotobyname
108function
109and
110.Fn getprotobynumber
111sequentially search from the beginning
112of the file until a matching
113protocol name or
114protocol number is found,
115or until
116.Dv EOF
117is encountered.
118.Sh RETURN VALUES
119Null pointer
120(0) returned on
121.Dv EOF
122or 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
130The
131.Fn getprotoent ,
132.Fn getprotobynumber ,
133.Fn getprotobyname ,
134.Fn setprotoent ,
135and
136.Fn endprotoent
137functions appeared in
138.Bx 4.2 .
139.Sh BUGS
140These functions use a static data space;
141if the data is needed for future use, it should be
142copied before any subsequent calls overwrite it.
143Only the Internet
144protocols 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)
35static 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
47static FILE *protof = NULL;
48static char line[BUFSIZ+1];
49static struct protoent proto;
50static char *proto_aliases[MAXALIASES];
51int _proto_stayopen;
52
53void
54setprotoent(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
64void
65endprotoent()
66{
67 if (protof) {
68 fclose(protof);
69 protof = NULL;
70 }
71 _proto_stayopen = 0;
72}
73
74struct protoent *
75getprotoent()
76{
77 char *p, *cp, **q;
78 size_t len;
79
80 if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL)
81 return (NULL);
82again:
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)
35static 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
41extern int _proto_stayopen;
42
43struct protoent *
44getprotobyname(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 }
58found:
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)
35static 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
41extern int _serv_stayopen;
42
43struct servent *
44getservbyname(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;
58gotname:
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)
35static 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
41extern int _serv_stayopen;
42
43struct servent *
44getservbyport(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
57The
58.Fn getservent ,
59.Fn getservbyname ,
60and
61.Fn getservbyport
62functions
63each return a pointer to an object with the
64following structure
65containing the broken-out
66fields of a line in the network services data base,
67.Pa /etc/services .
68.Bd -literal -offset indent
69struct 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
77The members of this structure are:
78.Bl -tag -width s_aliases
79.It Fa s_name
80The official name of the service.
81.It Fa s_aliases
82A zero terminated list of alternate names for the service.
83.It Fa s_port
84The port number at which the service resides.
85Port numbers are returned in network byte order.
86.It Fa s_proto
87The name of the protocol to use when contacting the
88service.
89.El
90.Pp
91The
92.Fn getservent
93function
94reads the next line of the file, opening the file if necessary.
95.Pp
96The
97.Fn setservent
98function
99opens and rewinds the file. If the
100.Fa stayopen
101flag is non-zero,
102the net data base will not be closed after each call to
103.Fn getservbyname
104or
105.Fn getservbyport .
106.Pp
107The
108.Fn endservent
109function
110closes the file.
111.Pp
112The
113.Fn getservbyname
114and
115.Fn getservbyport
116functions
117sequentially search from the beginning
118of the file until a matching
119protocol name or
120port number is found,
121or until
122.Dv EOF
123is encountered.
124If a protocol name is also supplied (non-
125.Dv NULL ) ,
126searches 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
133Null pointer
134(0) returned on
135.Dv EOF
136or error.
137.Sh SEE ALSO
138.Xr getprotoent 3 ,
139.Xr services 5
140.Sh HISTORY
141The
142.Fn getservent ,
143.Fn getservbyport ,
144.Fn getservbyname ,
145.Fn setservent ,
146and
147.Fn endservent
148functions appeared in
149.Bx 4.2 .
150.Sh BUGS
151These functions use static data storage;
152if the data is needed for future use, it should be
153copied before any subsequent calls overwrite it.
154Expecting port numbers to fit in a 32 bit
155quantity 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)
35static 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
47static FILE *servf = NULL;
48static char line[BUFSIZ+1];
49static struct servent serv;
50static char *serv_aliases[MAXALIASES];
51int _serv_stayopen;
52
53void
54setservent(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
64void
65endservent()
66{
67 if (servf) {
68 fclose(servf);
69 servf = NULL;
70 }
71 _serv_stayopen = 0;
72}
73
74struct servent *
75getservent()
76{
77 char *p, *cp, **q;
78 size_t len;
79
80 if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL)
81 return (NULL);
82again:
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
60static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: herror.c,v 8.3 1996/08/05 08:31:35 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: herror.c,v 1.4 1997/03/13 19:07:28 downsj Exp $";
64#endif
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
74const 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};
81int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
82
83extern int h_errno;
84
85/*
86 * herror --
87 * print the error indicated by the h_errno value.
88 */
89void
90herror(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
112const char *
113hstrerror(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)
7static 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
15u_int32_t
16htonl(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)
7static 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
15u_int16_t
16#ifdef __STDC__
17htons(u_int16_t x)
18#else
19htons(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
74The routines
75.Fn inet_aton ,
76.Fn inet_addr
77and
78.Fn inet_network
79interpret character strings representing
80numbers expressed in the Internet standard
81.Ql \&.
82notation.
83The
84.Fn inet_pton
85function converts a presentation format address (that is, printable form
86as held in a character string) to network format (usually a
87.Ft struct in_addr
88or some other internal binary representation, in network byte order). It
89returns 1 if the address was valid for the specified address family, or
900 if the address wasn't parseable in the specified address family, or -1
91if some system error occurred (in which case
92.Va errno
93will have been set). This function is presently valid for AF_INET and
94AF_INET6. The
95.Fn inet_aton
96routine interprets the specified character string as an Internet address,
97placing the address into the structure provided.
98It returns 1 if the string was successfully interpreted,
99or 0 if the string is invalid.
100The
101.Fn inet_addr
102and
103.Fn inet_network
104functions return numbers suitable for use
105as Internet addresses and Internet network
106numbers, respectively.
107.Pp
108The function
109.Fn inet_ntop
110converts an address from network format (usually a
111.Ft struct in_addr
112or some other binary form, in network byte order) to presentation format
113(suitable for external display purposes). It returns NULL if a system
114error occurs (in which case,
115.Va errno
116will have been set), or it returns a pointer to the destination string.
117The routine
118.Fn inet_ntoa
119takes an Internet address and returns an
120.Tn ASCII
121string representing the address in
122.Ql \&.
123notation. The routine
124.Fn inet_makeaddr
125takes an Internet network number and a local
126network address and constructs an Internet address
127from it. The routines
128.Fn inet_netof
129and
130.Fn inet_lnaof
131break apart Internet host addresses, returning
132the network number and local network address part,
133respectively.
134.Pp
135All Internet addresses are returned in network
136order (bytes ordered from left to right).
137All network numbers and local address parts are
138returned as machine format integer values.
139.Sh INTERNET ADDRESSES (IP VERSION 4)
140Values specified using the
141.Ql \&.
142notation take one
143of the following forms:
144.Bd -literal -offset indent
145a.b.c.d
146a.b.c
147a.b
148a
149.Ed
150.Pp
151When four parts are specified, each is interpreted
152as a byte of data and assigned, from left to right,
153to the four bytes of an Internet address. Note
154that when an Internet address is viewed as a 32-bit
155integer quantity on a system that uses little-endian
156byte order (such as the
157.Tn Intel 386, 486
158and
159.Tn Pentium
160processors) the bytes referred to above appear as
161.Dq Li d.c.b.a .
162That is, little-endian bytes are ordered from right to left.
163.Pp
164When a three part address is specified, the last
165part is interpreted as a 16-bit quantity and placed
166in the right-most two bytes of the network address.
167This makes the three part address format convenient
168for specifying Class B network addresses as
169.Dq Li 128.net.host .
170.Pp
171When a two part address is supplied, the last part
172is interpreted as a 24-bit quantity and placed in
173the right most three bytes of the network address.
174This makes the two part address format convenient
175for specifying Class A network addresses as
176.Dq Li net.host .
177.Pp
178When only one part is given, the value is stored
179directly in the network address without any byte
180rearrangement.
181.Pp
182All numbers supplied as
183.Dq parts
184in a
185.Ql \&.
186notation
187may be decimal, octal, or hexadecimal, as specified
188in the C language (i.e., a leading 0x or 0X implies
189hexadecimal; otherwise, a leading 0 implies octal;
190otherwise, the number is interpreted as decimal).
191.Sh INTERNET ADDRESSES (IP VERSION 6)
192The presentation format of an IPv6 address is given in [RFC1884 2.2]:
193.Pp
194There are three conventional forms for representing IPv6 addresses as
195text strings:
196.Bl -enum
197.It
198The preferred form is x:x:x:x:x:x:x:x, where the 'x's are the
199hexadecimal values of the eight 16-bit pieces of the address.
200Examples:
201.Bd -literal -offset indent
202FEDC:BA98:7654:3210:FEDC:BA98:7654:3210
2031080:0:0:0:8:800:200C:417A
204.Ed
205.Pp
206Note that it is not necessary to write the leading zeros in an
207individual field, but there must be at least one numeral in
208every field (except for the case described in 2.).
209.It
210Due to the method of allocating certain styles of IPv6
211addresses, it will be common for addresses to contain long
212strings of zero bits. In order to make writing addresses
213.Pp
214containing zero bits easier a special syntax is available to
215compress the zeros. The use of ``::'' indicates multiple groups
216of 16-bits of zeros. The ``::'' can only appear once in an
217address. The ``::'' can also be used to compress the leading
218and/or trailing zeros in an address.
219.Pp
220For example the following addresses:
221.Bd -literal -offset indent
2221080:0:0:0:8:800:200C:417A a unicast address
223FF01:0:0:0:0:0:0:43 a multicast address
2240:0:0:0:0:0:0:1 the loopback address
2250:0:0:0:0:0:0:0 the unspecified addresses
226.Ed
227.Pp
228may be represented as:
229.Bd -literal -offset indent
2301080::8:800:200C:417A a unicast address
231FF01::43 a multicast address
232::1 the loopback address
233:: the unspecified addresses
234.Ed
235.It
236An alternative form that is sometimes more convenient when
237dealing with a mixed environment of IPv4 and IPv6 nodes is
238x:x:x:x:x:x:d.d.d.d, where the 'x's are the hexadecimal values
239of the six high-order 16-bit pieces of the address, and the 'd's
240are the decimal values of the four low-order 8-bit pieces of the
241address (standard IPv4 representation). Examples:
242.Bd -literal -offset indent
2430:0:0:0:0:0:13.1.68.3
2440:0:0:0:0:FFFF:129.144.52.38
245.Ed
246.Pp
247or 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
254The constant
255.Dv INADDR_NONE
256is returned by
257.Fn inet_addr
258and
259.Fn inet_network
260for 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
269The
270.Nm inet_ntop
271and
272.Nm inet_pton
273functions conforms to the IETF IPng BSD API and address formatting
274specifications. Note that
275.Nm inet_pton
276does not accept 1-, 2-, or 3-part dotted addresses; all four parts
277must be specified. This is a narrower input set than that accepted by
278.Nm inet_aton .
279.Sh HISTORY
280The
281.Nm inet_addr ,
282.Nm inet_network ,
283.Nm inet_makeaddr ,
284.Nm inet_lnaof
285and
286.Nm inet_netof
287functions appeared in
288.Bx 4.2 .
289The
290.Nm inet_aton
291and
292.Nm inet_ntoa
293functions appeared in
294.Bx 4.3 .
295The
296.Nm inet_pton
297and
298.Nm inet_ntop
299functions appeared in BIND 4.9.4.
300.Sh BUGS
301The value
302.Dv INADDR_NONE
303(0xffffffff) is a valid broadcast address, but
304.Fn inet_addr
305cannot return that value without indicating failure.
306The newer
307.Fn inet_aton
308function does not share this problem.
309.Pp
310The problem of host byte ordering versus network byte ordering is
311confusing.
312.Pp
313The string returned by
314.Fn inet_ntoa
315resides in a static memory area.
316.Pp
317.Fn inet_addr
318should 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
60static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
61static char rcsid[] = "$From: inet_addr.c,v 8.5 1996/08/05 08:31:35 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: inet_addr.c,v 1.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 */
77in_addr_t
78inet_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 */
95int
96inet_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)
35static 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 */
47in_addr_t
48inet_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)
35static 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 */
46struct in_addr
47inet_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
54The
55.Fn inet_net_ntop
56function converts an Internet network number from network format (usually a
57.Ft struct in_addr
58or some other binary form, in network byte order) to CIDR presentation format
59(suitable for external display purposes).
60.Fa bits
61is the number of bits in
62.Fa src
63that are the network number.
64It returns NULL if a system error occurs (in which case,
65.Va errno
66will have been set), or it returns a pointer to the destination string.
67.Pp
68The
69.Fn inet_net_pton
70function converts a presentation format Internet network number (that is,
71printable form as held in a character string) to network format (usually a
72.Ft struct in_addr
73or some other internal binary representation, in network byte order).
74It returns the number of bits (either computed based on the class, or
75specified with /CIDR), or -1 if a failure occurred
76(in which case
77.Va errno
78will have been set.
79It will be set to
80.Er ENOENT
81if the Internet network number was not valid).
82.Pp
83The currently supported value for
84.Fa af
85is: AF_INET.
86.Fa size
87is the size of the result buffer
88.Fa dst .
89.Pp
90.Sh NETWORK NUMBERS (IP VERSION 4)
91Internet network numbers may be specified in one of the following forms:
92.Bd -literal -offset indent
93a.b.c.d/bits
94a.b.c.d
95a.b.c
96a.b
97a
98.Ed
99.Pp
100When four parts are specified, each is interpreted
101as a byte of data and assigned, from left to right,
102to the four bytes of an Internet network number. Note
103that when an Internet network number is viewed as a 32-bit
104integer quantity on a system that uses little-endian
105byte order (such as the
106.Tn Intel 386, 486
107and
108.Tn Pentium
109processors) the bytes referred to above appear as
110.Dq Li d.c.b.a .
111That is, little-endian bytes are ordered from right to left.
112.Pp
113When a three part number is specified, the last
114part is interpreted as a 16-bit quantity and placed
115in the right-most two bytes of the Internet network number.
116This makes the three part number format convenient
117for specifying Class B network numbers as
118.Dq Li 128.net.host .
119.Pp
120When a two part number is supplied, the last part
121is interpreted as a 24-bit quantity and placed in
122the right most three bytes of the Internet network number.
123This makes the two part number format convenient
124for specifying Class A network numbers as
125.Dq Li net.host .
126.Pp
127When only one part is given, the value is stored
128directly in the Internet network number without any byte
129rearrangement.
130.Pp
131All numbers supplied as
132.Dq parts
133in a
134.Ql \&.
135notation
136may be decimal, octal, or hexadecimal, as specified
137in the C language (i.e., a leading 0x or 0X implies
138hexadecimal; otherwise, a leading 0 implies octal;
139otherwise, 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
145The
146.Nm inet_net_ntop
147and
148.Nm inet_net_pton
149functions 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
22static const char rcsid[] = "$From: inet_net_ntop.c,v 8.2 1996/08/08 06:54:44 vixie Exp $";
23#else
24static const char rcsid[] = "$OpenBSD: inet_net_ntop.c,v 1.1 1997/03/13 19:07:30 downsj Exp $";
25#endif
26#endif
27
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <netinet/in.h>
31#include <arpa/inet.h>
32
33#include <errno.h>
34#include <stdio.h>
35#include <string.h>
36#include <stdlib.h>
37
38static char * inet_net_ntop_ipv4 __P((const u_char *src, int bits,
39 char *dst, size_t size));
40
41/*
42 * char *
43 * inet_net_ntop(af, src, bits, dst, size)
44 * convert network number from network to presentation format.
45 * generates CIDR style result always.
46 * return:
47 * pointer to dst, or NULL if an error occurred (check errno).
48 * author:
49 * Paul Vixie (ISC), July 1996
50 */
51char *
52inet_net_ntop(af, src, bits, dst, size)
53 int af;
54 const void *src;
55 int bits;
56 char *dst;
57 size_t size;
58{
59 switch (af) {
60 case AF_INET:
61 return (inet_net_ntop_ipv4(src, bits, dst, size));
62 default:
63 errno = EAFNOSUPPORT;
64 return (NULL);
65 }
66}
67
68/*
69 * static char *
70 * inet_net_ntop_ipv4(src, bits, dst, size)
71 * convert IPv4 network number from network to presentation format.
72 * generates CIDR style result always.
73 * return:
74 * pointer to dst, or NULL if an error occurred (check errno).
75 * note:
76 * network byte order assumed. this means 192.5.5.240/28 has
77 * 0x11110000 in its fourth octet.
78 * author:
79 * Paul Vixie (ISC), July 1996
80 */
81static char *
82inet_net_ntop_ipv4(src, bits, dst, size)
83 const u_char *src;
84 int bits;
85 char *dst;
86 size_t size;
87{
88 char *odst = dst;
89 char *t;
90 u_int m;
91 int b;
92
93 if (bits < 0 || bits > 32) {
94 errno = EINVAL;
95 return (NULL);
96 }
97 if (bits == 0) {
98 if (size < sizeof "0")
99 goto emsgsize;
100 *dst++ = '0';
101 *dst = '\0';
102 }
103
104 /* Format whole octets. */
105 for (b = bits / 8; b > 0; b--) {
106 if (size < sizeof "255.")
107 goto emsgsize;
108 t = dst;
109 dst += sprintf(dst, "%u", *src++);
110 if (b > 1) {
111 *dst++ = '.';
112 *dst = '\0';
113 }
114 size -= (size_t)(dst - t);
115 }
116
117 /* Format partial octet. */
118 b = bits % 8;
119 if (b > 0) {
120 if (size < sizeof ".255")
121 goto emsgsize;
122 t = dst;
123 if (dst != odst)
124 *dst++ = '.';
125 m = ((1 << b) - 1) << (8 - b);
126 dst += sprintf(dst, "%u", *src & m);
127 size -= (size_t)(dst - t);
128 }
129
130 /* Format CIDR /width. */
131 if (size < sizeof "/32")
132 goto emsgsize;
133 dst += sprintf(dst, "/%u", bits);
134 return (odst);
135
136 emsgsize:
137 errno = EMSGSIZE;
138 return (NULL);
139}
diff --git a/src/lib/libc/net/inet_net_pton.c b/src/lib/libc/net/inet_net_pton.c
new file mode 100644
index 0000000000..b529e83664
--- /dev/null
+++ b/src/lib/libc/net/inet_net_pton.c
@@ -0,0 +1,207 @@
1/* $OpenBSD: inet_net_pton.c,v 1.1 1997/03/13 19:07:30 downsj Exp $ */
2
3/*
4 * Copyright (c) 1996 by Internet Software Consortium.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
11 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
12 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
13 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
16 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
17 * SOFTWARE.
18 */
19
20#if defined(LIBC_SCCS) && !defined(lint)
21#if 0
22static const char rcsid[] = "$From: inet_net_pton.c,v 8.3 1996/11/11 06:36:52 vixie Exp $";
23#else
24static const char rcsid[] = "$OpenBSD: inet_net_pton.c,v 1.1 1997/03/13 19:07:30 downsj Exp $";
25#endif
26#endif
27
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <netinet/in.h>
31#include <arpa/inet.h>
32
33#include <assert.h>
34#include <ctype.h>
35#include <errno.h>
36#include <stdio.h>
37#include <string.h>
38#include <stdlib.h>
39
40static int inet_net_pton_ipv4 __P((const char *src, u_char *dst,
41 size_t size));
42
43/*
44 * static int
45 * inet_net_pton(af, src, dst, size)
46 * convert network number from presentation to network format.
47 * accepts hex octets, hex strings, decimal octets, and /CIDR.
48 * "size" is in bytes and describes "dst".
49 * return:
50 * number of bits, either imputed classfully or specified with /CIDR,
51 * or -1 if some failure occurred (check errno). ENOENT means it was
52 * not a valid network specification.
53 * author:
54 * Paul Vixie (ISC), June 1996
55 */
56int
57inet_net_pton(af, src, dst, size)
58 int af;
59 const char *src;
60 void *dst;
61 size_t size;
62{
63 switch (af) {
64 case AF_INET:
65 return (inet_net_pton_ipv4(src, dst, size));
66 default:
67 errno = EAFNOSUPPORT;
68 return (-1);
69 }
70}
71
72/*
73 * static int
74 * inet_net_pton_ipv4(src, dst, size)
75 * convert IPv4 network number from presentation to network format.
76 * accepts hex octets, hex strings, decimal octets, and /CIDR.
77 * "size" is in bytes and describes "dst".
78 * return:
79 * number of bits, either imputed classfully or specified with /CIDR,
80 * or -1 if some failure occurred (check errno). ENOENT means it was
81 * not an IPv4 network specification.
82 * note:
83 * network byte order assumed. this means 192.5.5.240/28 has
84 * 0x11110000 in its fourth octet.
85 * author:
86 * Paul Vixie (ISC), June 1996
87 */
88static int
89inet_net_pton_ipv4(src, dst, size)
90 const char *src;
91 u_char *dst;
92 size_t size;
93{
94 static const char
95 xdigits[] = "0123456789abcdef",
96 digits[] = "0123456789";
97 int n, ch, tmp, dirty, bits;
98 const u_char *odst = dst;
99
100 ch = *src++;
101 if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
102 && isascii(src[1]) && isxdigit(src[1])) {
103 /* Hexadecimal: Eat nybble string. */
104 if (size <= 0)
105 goto emsgsize;
106 *dst = 0, dirty = 0;
107 src++; /* skip x or X. */
108 while ((ch = *src++) != '\0' &&
109 isascii(ch) && isxdigit(ch)) {
110 if (isupper(ch))
111 ch = tolower(ch);
112 n = strchr(xdigits, ch) - xdigits;
113 assert(n >= 0 && n <= 15);
114 *dst |= n;
115 if (!dirty++)
116 *dst <<= 4;
117 else if (size-- > 0)
118 *++dst = 0, dirty = 0;
119 else
120 goto emsgsize;
121 }
122 if (dirty)
123 size--;
124 } else if (isascii(ch) && isdigit(ch)) {
125 /* Decimal: eat dotted digit string. */
126 for (;;) {
127 tmp = 0;
128 do {
129 n = strchr(digits, ch) - digits;
130 assert(n >= 0 && n <= 9);
131 tmp *= 10;
132 tmp += n;
133 if (tmp > 255)
134 goto enoent;
135 } while ((ch = *src++) != '\0' &&
136 isascii(ch) && isdigit(ch));
137 if (size-- <= 0)
138 goto emsgsize;
139 *dst++ = (u_char) tmp;
140 if (ch == '\0' || ch == '/')
141 break;
142 if (ch != '.')
143 goto enoent;
144 ch = *src++;
145 if (!isascii(ch) || !isdigit(ch))
146 goto enoent;
147 }
148 } else
149 goto enoent;
150
151 bits = -1;
152 if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) {
153 /* CIDR width specifier. Nothing can follow it. */
154 ch = *src++; /* Skip over the /. */
155 bits = 0;
156 do {
157 n = strchr(digits, ch) - digits;
158 assert(n >= 0 && n <= 9);
159 bits *= 10;
160 bits += n;
161 } while ((ch = *src++) != '\0' &&
162 isascii(ch) && isdigit(ch));
163 if (ch != '\0')
164 goto enoent;
165 if (bits > 32)
166 goto emsgsize;
167 }
168
169 /* Firey death and destruction unless we prefetched EOS. */
170 if (ch != '\0')
171 goto enoent;
172
173 /* If nothing was written to the destination, we found no address. */
174 if (dst == odst)
175 goto enoent;
176 /* If no CIDR spec was given, infer width from net class. */
177 if (bits == -1) {
178 if (*odst >= 240) /* Class E */
179 bits = 32;
180 else if (*odst >= 224) /* Class D */
181 bits = 4;
182 else if (*odst >= 192) /* Class C */
183 bits = 24;
184 else if (*odst >= 128) /* Class B */
185 bits = 16;
186 else /* Class A */
187 bits = 8;
188 /* If imputed mask is narrower than specified octets, widen. */
189 if (bits >= 8 && bits < ((dst - odst) * 8))
190 bits = (dst - odst) * 8;
191 }
192 /* Extend network to cover the actual mask. */
193 while (bits > ((dst - odst) * 8)) {
194 if (size-- <= 0)
195 goto emsgsize;
196 *dst++ = '\0';
197 }
198 return (bits);
199
200 enoent:
201 errno = ENOENT;
202 return (-1);
203
204 emsgsize:
205 errno = EMSGSIZE;
206 return (-1);
207}
diff --git a/src/lib/libc/net/inet_neta.c b/src/lib/libc/net/inet_neta.c
new file mode 100644
index 0000000000..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
22static const char rcsid[] = "$Id: inet_neta.c,v 1.2 1997/04/05 21:13:12 millert Exp $";
23#else
24static 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 */
48char *
49inet_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)
35static 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 */
46in_addr_t
47inet_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)
35static 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 */
48in_addr_t
49inet_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
57again:
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)
35static 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
47char *
48inet_ntoa(in)
49 struct in_addr in;
50{
51 static char b[18];
52 register char *p;
53
54 p = (char *)&in;
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
21static char rcsid[] = "$From: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $";
22#else
23static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.1 1997/03/13 19:07:32 downsj Exp $";
24#endif
25#endif /* LIBC_SCCS and not lint */
26
27#include <sys/param.h>
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <netinet/in.h>
31#include <arpa/inet.h>
32#include <arpa/nameser.h>
33#include <string.h>
34#include <errno.h>
35#include <stdio.h>
36
37/*
38 * WARNING: Don't even consider trying to compile this on a system where
39 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
40 */
41
42static const char *inet_ntop4 __P((const u_char *src, char *dst, size_t size));
43static const char *inet_ntop6 __P((const u_char *src, char *dst, size_t size));
44
45/* char *
46 * inet_ntop(af, src, dst, size)
47 * convert a network format address to presentation format.
48 * return:
49 * pointer to presentation format address (`dst'), or NULL (see errno).
50 * author:
51 * Paul Vixie, 1996.
52 */
53const char *
54inet_ntop(af, src, dst, size)
55 int af;
56 const void *src;
57 char *dst;
58 size_t size;
59{
60 switch (af) {
61 case AF_INET:
62 return (inet_ntop4(src, dst, size));
63 case AF_INET6:
64 return (inet_ntop6(src, dst, size));
65 default:
66 errno = EAFNOSUPPORT;
67 return (NULL);
68 }
69 /* NOTREACHED */
70}
71
72/* const char *
73 * inet_ntop4(src, dst, size)
74 * format an IPv4 address, more or less like inet_ntoa()
75 * return:
76 * `dst' (as a const)
77 * notes:
78 * (1) uses no statics
79 * (2) takes a u_char* not an in_addr as input
80 * author:
81 * Paul Vixie, 1996.
82 */
83static const char *
84inet_ntop4(src, dst, size)
85 const u_char *src;
86 char *dst;
87 size_t size;
88{
89 static const char fmt[] = "%u.%u.%u.%u";
90 char tmp[sizeof "255.255.255.255"];
91
92 if (sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) > size) {
93 errno = ENOSPC;
94 return (NULL);
95 }
96 strcpy(dst, tmp);
97 return (dst);
98}
99
100/* const char *
101 * inet_ntop6(src, dst, size)
102 * convert IPv6 binary address into presentation (printable) format
103 * author:
104 * Paul Vixie, 1996.
105 */
106static const char *
107inet_ntop6(src, dst, size)
108 const u_char *src;
109 char *dst;
110 size_t size;
111{
112 /*
113 * Note that int32_t and int16_t need only be "at least" large enough
114 * to contain a value of the specified size. On some systems, like
115 * Crays, there is no such thing as an integer variable with 16 bits.
116 * Keep this in mind if you think this function should have been coded
117 * to use pointer overlays. All the world's not a VAX.
118 */
119 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
120 struct { int base, len; } best, cur;
121 u_int words[IN6ADDRSZ / INT16SZ];
122 int i;
123
124 /*
125 * Preprocess:
126 * Copy the input (bytewise) array into a wordwise array.
127 * Find the longest run of 0x00's in src[] for :: shorthanding.
128 */
129 memset(words, '\0', sizeof words);
130 for (i = 0; i < IN6ADDRSZ; i++)
131 words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
132 best.base = -1;
133 cur.base = -1;
134 for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
135 if (words[i] == 0) {
136 if (cur.base == -1)
137 cur.base = i, cur.len = 1;
138 else
139 cur.len++;
140 } else {
141 if (cur.base != -1) {
142 if (best.base == -1 || cur.len > best.len)
143 best = cur;
144 cur.base = -1;
145 }
146 }
147 }
148 if (cur.base != -1) {
149 if (best.base == -1 || cur.len > best.len)
150 best = cur;
151 }
152 if (best.base != -1 && best.len < 2)
153 best.base = -1;
154
155 /*
156 * Format the result.
157 */
158 tp = tmp;
159 for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
160 /* Are we inside the best run of 0x00's? */
161 if (best.base != -1 && i >= best.base &&
162 i < (best.base + best.len)) {
163 if (i == best.base)
164 *tp++ = ':';
165 continue;
166 }
167 /* Are we following an initial run of 0x00s or any real hex? */
168 if (i != 0)
169 *tp++ = ':';
170 /* Is this address an encapsulated IPv4? */
171 if (i == 6 && best.base == 0 &&
172 (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
173 if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
174 return (NULL);
175 tp += strlen(tp);
176 break;
177 }
178 tp += sprintf(tp, "%x", words[i]);
179 }
180 /* Was it a trailing run of 0x00's? */
181 if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
182 *tp++ = ':';
183 *tp++ = '\0';
184
185 /*
186 * Check for overflow, copy, and we're done.
187 */
188 if ((size_t)(tp - tmp) > size) {
189 errno = ENOSPC;
190 return (NULL);
191 }
192 strcpy(dst, tmp);
193 return (dst);
194}
diff --git a/src/lib/libc/net/inet_pton.c b/src/lib/libc/net/inet_pton.c
new file mode 100644
index 0000000000..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
21static char rcsid[] = "$From: inet_pton.c,v 8.7 1996/08/05 08:31:35 vixie Exp $";
22#else
23static char rcsid[] = "$OpenBSD: inet_pton.c,v 1.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
41static int inet_pton4 __P((const char *src, u_char *dst));
42static int inet_pton6 __P((const char *src, u_char *dst));
43
44/* int
45 * inet_pton(af, src, dst)
46 * convert from presentation format (which usually means ASCII printable)
47 * to network format (which is usually some kind of binary format).
48 * return:
49 * 1 if the address was valid for the specified address family
50 * 0 if the address wasn't valid (`dst' is untouched in this case)
51 * -1 if some other error occurred (`dst' is untouched in this case, too)
52 * author:
53 * Paul Vixie, 1996.
54 */
55int
56inet_pton(af, src, dst)
57 int af;
58 const char *src;
59 void *dst;
60{
61 switch (af) {
62 case AF_INET:
63 return (inet_pton4(src, dst));
64 case AF_INET6:
65 return (inet_pton6(src, dst));
66 default:
67 errno = EAFNOSUPPORT;
68 return (-1);
69 }
70 /* NOTREACHED */
71}
72
73/* int
74 * inet_pton4(src, dst)
75 * like inet_aton() but without all the hexadecimal and shorthand.
76 * return:
77 * 1 if `src' is a valid dotted quad, else 0.
78 * notice:
79 * does not touch `dst' unless it's returning 1.
80 * author:
81 * Paul Vixie, 1996.
82 */
83static int
84inet_pton4(src, dst)
85 const char *src;
86 u_char *dst;
87{
88 static const char digits[] = "0123456789";
89 int saw_digit, octets, ch;
90 u_char tmp[INADDRSZ], *tp;
91
92 saw_digit = 0;
93 octets = 0;
94 *(tp = tmp) = 0;
95 while ((ch = *src++) != '\0') {
96 const char *pch;
97
98 if ((pch = strchr(digits, ch)) != NULL) {
99 u_int new = *tp * 10 + (pch - digits);
100
101 if (new > 255)
102 return (0);
103 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 */
137static int
138inet_pton6(src, dst)
139 const char *src;
140 u_char *dst;
141{
142 static const char xdigits_l[] = "0123456789abcdef",
143 xdigits_u[] = "0123456789ABCDEF";
144 u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
145 const char *xdigits, *curtok;
146 int ch, saw_xdigit;
147 u_int val;
148
149 memset((tp = tmp), '\0', IN6ADDRSZ);
150 endp = tp + IN6ADDRSZ;
151 colonp = NULL;
152 /* Leading :: requires some special handling. */
153 if (*src == ':')
154 if (*++src != ':')
155 return (0);
156 curtok = src;
157 saw_xdigit = 0;
158 val = 0;
159 while ((ch = *src++) != '\0') {
160 const char *pch;
161
162 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
163 pch = strchr((xdigits = xdigits_u), ch);
164 if (pch != NULL) {
165 val <<= 4;
166 val |= (pch - xdigits);
167 if (val > 0xffff)
168 return (0);
169 saw_xdigit = 1;
170 continue;
171 }
172 if (ch == ':') {
173 curtok = src;
174 if (!saw_xdigit) {
175 if (colonp)
176 return (0);
177 colonp = tp;
178 continue;
179 }
180 if (tp + INT16SZ > endp)
181 return (0);
182 *tp++ = (u_char) (val >> 8) & 0xff;
183 *tp++ = (u_char) val & 0xff;
184 saw_xdigit = 0;
185 val = 0;
186 continue;
187 }
188 if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
189 inet_pton4(curtok, tp) > 0) {
190 tp += INADDRSZ;
191 saw_xdigit = 0;
192 break; /* '\0' was seen by inet_pton4(). */
193 }
194 return (0);
195 }
196 if (saw_xdigit) {
197 if (tp + INT16SZ > endp)
198 return (0);
199 *tp++ = (u_char) (val >> 8) & 0xff;
200 *tp++ = (u_char) val & 0xff;
201 }
202 if (colonp != NULL) {
203 /*
204 * Since some memmove()'s erroneously fail to handle
205 * overlapping regions, we'll do the shift by hand.
206 */
207 const int n = tp - colonp;
208 int i;
209
210 for (i = 1; i <= n; i++) {
211 endp[- i] = colonp[n - i];
212 colonp[n - i] = 0;
213 }
214 tp = endp;
215 }
216 if (tp != endp)
217 return (0);
218 memcpy(dst, tmp, IN6ADDRSZ);
219 return (1);
220}
diff --git a/src/lib/libc/net/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
49The routine
50.Fn ipx_addr
51interprets character strings representing
52.Tn IPX
53addresses, returning binary information suitable
54for use in system calls.
55The routine
56.Fn ipx_ntoa
57takes
58.Tn IPX
59addresses and returns
60.Tn ASCII
61strings representing the address in a
62notation in common use:
63.Bd -filled -offset indent
64<network number>.<host number>.<port number>
65.Ed
66.Pp
67Trailing zero fields are suppressed, and each number is printed in hexadecimal,
68in a format suitable for input to
69.Fn ipx_addr .
70Any fields lacking super-decimal digits will have a
71trailing
72.Ql H
73appended.
74.Pp
75An effort has been made to insure that
76.Fn ipx_addr
77be compatible with most formats in common use.
78It will first separate an address into 1 to 3 fields using a single delimiter
79chosen from
80period
81.Ql \&. ,
82colon
83.Ql \&:
84or pound-sign
85.Ql \&# .
86Each field is then examined for byte separators (colon or period).
87If there are byte separators, each subfield separated is taken to be
88a small hexadecimal number, and the entirety is taken as a network-byte-ordered
89quantity to be zero extended in the high-network-order bytes.
90Next, the field is inspected for hyphens, in which case
91the field is assumed to be a number in decimal notation
92with hyphens separating the millenia.
93Next, the field is assumed to be a number:
94It is interpreted
95as hexadecimal if there is a leading
96.Ql 0x
97(as in C),
98a trailing
99.Ql H
100(as in Mesa), or there are any super-decimal digits present.
101It is interpreted as octal is there is a leading
102.Ql 0
103and there are no super-octal digits.
104Otherwise, it is converted as a decimal number.
105.Sh RETURN VALUES
106None. (See
107.Sx BUGS . )
108.Sh SEE ALSO
109.Xr ns 4 ,
110.Xr hosts 5 ,
111.Xr networks 5
112.Sh HISTORY
113The precursor
114.Fn ns_addr
115and
116.Fn ns_ntoa
117functions appeared in
118.Bx 4.3 .
119.Sh BUGS
120The string returned by
121.Fn ipx_ntoa
122resides in a static memory area.
123The function
124.Fn ipx_addr
125should diagnose improperly formed input, and there should be an unambiguous
126way 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)
40static 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
48static struct ipx_addr addr, zero_addr;
49
50static void Field(), cvtbase();
51
52struct ipx_addr
53ipx_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
99static void
100Field(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
203static void
204cvtbase(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)
35static 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
42char *
43ipx_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
49The routine
50.Fn iso_addr
51interprets character strings representing
52.Tn OSI
53addresses, returning binary information suitable
54for use in system calls.
55The routine
56.Fn iso_ntoa
57takes
58.Tn OSI
59addresses and returns
60.Tn ASCII
61strings representing NSAPs (network service
62access points) in a
63notation inverse to that accepted by
64.Fn iso_addr .
65.Pp
66Unfortunately, no universal standard exists for representing
67.Tn OSI
68network addresses.
69.Pp
70The format employed by
71.Fn iso_addr
72is a sequence of hexadecimal
73.Dq digits
74(optionally separated by periods),
75of the form:
76.Bd -filled -offset indent
77<hex digits>.<hex digits>.<hex digits>
78.Ed
79.Pp
80Each pair of hexadecimal digits represents a byte
81with the leading digit indicating the higher-ordered bits.
82A period following an even number of bytes has no
83effect (but may be used to increase legibility).
84A period following an odd number of bytes has the
85effect of causing the byte of address being translated
86to have its higher order bits filled with zeros.
87.Sh RETURN VALUES
88.Fn iso_ntoa
89always returns a null terminated string.
90.Fn iso_addr
91always returns a pointer to a struct iso_addr.
92(See
93.Sx BUGS . )
94.Sh SEE ALSO
95.Xr iso 4
96.Sh HISTORY
97The
98.Fn iso_addr
99and
100.Fn iso_ntoa
101functions appeared in
102.Bx 4.3 Reno .
103.Sh BUGS
104The returned values
105reside in a static memory area.
106.Pp
107The function
108.Fn iso_addr
109should diagnose improperly formed input, and there should be an unambiguous
110way 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)
35static 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
51struct iso_addr *
52iso_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}
93static char hexlist[] = "0123456789abcdef";
94
95char *
96iso_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
53The routine
54.Fn link_addr
55interprets character strings representing
56link-level addresses, returning binary information suitable
57for use in system calls.
58The routine
59.Fn link_ntoa
60takes
61a link-level
62address and returns an
63.Tn ASCII
64string representing some of the information present,
65including the link level address itself, and the interface name
66or number, if present.
67This facility is experimental and is
68still subject to change.
69.Pp
70For
71.Fn link_addr ,
72the string
73.Fa addr
74may contain
75an optional network interface identifier of the form
76.Dq "name unit-number" ,
77suitable for the first argument to
78.Xr ifconfig 4 ,
79followed in all cases by a colon and
80an interface address in the form of
81groups of hexadecimal digits
82separated by periods.
83Each group represents a byte of address;
84address bytes are filled left to right from
85low 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
92Thus
93.Li le0:8.0.9.13.d.30
94represents an ethernet address
95to be transmitted on the first Lance ethernet interface.
96.Sh RETURN VALUES
97.Fn link_ntoa
98always returns a null terminated string.
99.Fn link_addr
100has no return value.
101(See
102.Sx BUGS . )
103.Sh SEE ALSO
104.Xr iso 4 ,
105.Sh HISTORY
106The
107.Fn link_addr
108and
109.Fn link_ntoa
110functions appeared in
111.Bx 4.3 Reno .
112.Sh BUGS
113The returned values for link_ntoa
114reside in a static memory area.
115.Pp
116The function
117.Fn link_addr
118should diagnose improperly formed input, and there should be an unambiguous
119way to recognize this.
120.Pp
121If the
122.Va sdl_len
123field of the link socket address
124.Fa sdl
125is 0,
126.Fn link_ntoa
127will not insert a colon before the interface address bytes.
128If this translated address is given to
129.Fn link_addr
130without inserting an initial colon,
131the 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)
35static 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
54void
55link_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
123static char hexlist[] = "0123456789abcdef";
124
125char *
126link_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)
42address 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
51The routine
52.Fn ns_addr
53interprets character strings representing
54.Tn XNS
55addresses, returning binary information suitable
56for use in system calls.
57The routine
58.Fn ns_ntoa
59takes
60.Tn XNS
61addresses and returns
62.Tn ASCII
63strings representing the address in a
64notation in common use in the Xerox Development Environment:
65.Bd -filled -offset indent
66<network number>.<host number>.<port number>
67.Ed
68.Pp
69Trailing zero fields are suppressed, and each number is printed in hexadecimal,
70in a format suitable for input to
71.Fn ns_addr .
72Any fields lacking super-decimal digits will have a
73trailing
74.Ql H
75appended.
76.Pp
77Unfortunately, no universal standard exists for representing
78.Tn XNS
79addresses.
80An effort has been made to insure that
81.Fn ns_addr
82be compatible with most formats in common use.
83It will first separate an address into 1 to 3 fields using a single delimiter
84chosen from
85period
86.Ql \&. ,
87colon
88.Ql \&:
89or pound-sign
90.Ql \&# .
91Each field is then examined for byte separators (colon or period).
92If there are byte separators, each subfield separated is taken to be
93a small hexadecimal number, and the entirety is taken as a network-byte-ordered
94quantity to be zero extended in the high-network-order bytes.
95Next, the field is inspected for hyphens, in which case
96the field is assumed to be a number in decimal notation
97with hyphens separating the millenia.
98Next, the field is assumed to be a number:
99It is interpreted
100as hexadecimal if there is a leading
101.Ql 0x
102(as in C),
103a trailing
104.Ql H
105(as in Mesa), or there are any super-decimal digits present.
106It is interpreted as octal is there is a leading
107.Ql 0
108and there are no super-octal digits.
109Otherwise, it is converted as a decimal number.
110.Sh RETURN VALUES
111None. (See
112.Sx BUGS . )
113.Sh SEE ALSO
114.Xr hosts 5 ,
115.Xr networks 5 ,
116.Sh HISTORY
117The
118.Fn ns_addr
119and
120.Fn ns_toa
121functions appeared in
122.Bx 4.3 .
123.Sh BUGS
124The string returned by
125.Fn ns_ntoa
126resides in a static memory area.
127The function
128.Fn ns_addr
129should diagnose improperly formed input, and there should be an unambiguous
130way 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)
38static 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
46static struct ns_addr addr, zero_addr;
47
48static void Field __P((char *, u_int8_t *, int));
49static void cvtbase __P((long, int, int[], int, u_int8_t[], int));
50
51struct ns_addr
52ns_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
98static void
99Field(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
202static void
203cvtbase(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)
35static 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
42static char *spectHex __P((char *));
43
44char *
45ns_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
81static char *
82spectHex(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
22static char rcsid[] = "$From: nsap_addr.c,v 8.3 1996/08/05 08:31:35 vixie Exp $";
23#else
24static char rcsid[] = "$OpenBSD: nsap_addr.c,v 1.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
36static char
37xtob(c)
38 register int c;
39{
40 return (c - (((c >= '0') && (c <= '9')) ? '0' : '7'));
41}
42
43u_int
44inet_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
78char *
79inet_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)
7static 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
15u_int32_t
16ntohl(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)
7static 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
15u_int16_t
16#ifdef __STDC__
17ntohs(u_int16_t x)
18#else
19ntohs(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
54The
55.Fn rcmd
56function
57is used by the super-user to execute a command on a remote
58machine using an authentication scheme based on reserved
59port numbers. If the calling process is not setuid and the
60.Li RSH
61environment variable is set and
62.Fa inport
63is
64.Li shell/tcp ,
65.Xr rcmdsh 3
66is called instead with the value of
67.Li RSH .
68Alternately, if the user is not the super-user,
69.Fn rcmd
70will invoke
71.Xr rcmdsh 3
72to run the command via
73.Xr rsh 1 .
74The
75.Fn rresvport
76function
77returns a descriptor to a socket
78with an address in the privileged port space.
79The
80.Fn iruserok
81and
82.Fn ruserok
83functions are used by servers
84to authenticate clients requesting service with
85.Fn rcmd .
86All four functions are present in the same file and are used
87by the
88.Xr rshd 8
89server (among others).
90.Pp
91The
92.Fn rcmd
93function
94looks up the host
95.Fa *ahost
96using
97.Xr gethostbyname 3 ,
98returning \-1 if the host does not exist.
99Otherwise
100.Fa *ahost
101is set to the standard name of the host
102and a connection is established to a server
103residing at the well-known Internet port
104.Fa inport .
105If the user is not the super-user, the only valid port is
106.Li shell/tcp ,
107(usually port 514).
108.Pp
109If the connection succeeds,
110a socket in the Internet domain of type
111.Dv SOCK_STREAM
112is returned to the caller, and given to the remote
113command as
114.Em stdin
115and
116.Em stdout .
117If
118.Fa fd2p
119is non-zero, then an auxiliary channel to a control
120process will be set up, and a descriptor for it will be placed
121in
122.Fa *fd2p .
123The control process will return diagnostic
124output from the command (unit 2) on this channel, and will also
125accept bytes on this channel as being
126.Tn UNIX
127signal numbers, to be
128forwarded to the process group of the command.
129If
130.Fa fd2p
131is 0, then the
132.Em stderr
133(unit 2 of the remote
134command) will be made the same as the
135.Em stdout
136and no
137provision is made for sending arbitrary signals to the remote process,
138although you may be able to get its attention by using out-of-band data.
139Note that if the user is not the super-user,
140.Fa fd2p
141must be 0.
142.Pp
143The protocol is described in detail in
144.Xr rshd 8 .
145.Pp
146The
147.Fn rresvport
148function is used to obtain a socket with a privileged
149address bound to it. This socket is suitable for use
150by
151.Fn rcmd
152and several other functions. Privileged Internet ports are those
153in the range 0 to 1023. Only the super-user
154is allowed to bind an address of this sort to a socket.
155.Fn rresvport
156needs to be seeded with a port number; if that port
157is not available it will find another.
158.Pp
159The
160.Fn iruserok
161and
162.Fn ruserok
163functions take a remote host's IP address or name, respectively,
164two user names and a flag indicating whether the local user's
165name is that of the super-user.
166Then, if the user is
167.Em NOT
168the super-user, it checks the
169.Pa /etc/hosts.equiv
170file.
171If that lookup is not done, or is unsuccessful, the
172.Pa .rhosts
173in the local user's home directory is checked to see if the request for
174service is allowed.
175.Pp
176If this file does not exist, is not a regular file, is owned by anyone
177other than the user or the super-user, or is writeable by anyone other
178than the owner, the check automatically fails.
179Zero is returned if the machine name is listed in the
180.Dq Pa hosts.equiv
181file, or the host and remote user name are found in the
182.Dq Pa .rhosts
183file; otherwise
184.Fn iruserok
185and
186.Fn ruserok
187return \-1.
188If the local domain (as obtained from
189.Xr gethostname 3 )
190is the same as the remote domain, only the machine name need be specified.
191.Pp
192If the IP address of the remote host is known,
193.Fn iruserok
194should be used in preference to
195.Fn ruserok ,
196as it does not require trusting the DNS server for the remote host's domain.
197.Sh DIAGNOSTICS
198The
199.Fn rcmd
200function
201returns a valid socket descriptor on success.
202It returns \-1 on error and prints a diagnostic message on the standard error.
203.Pp
204The
205.Fn rresvport
206function
207returns a valid, bound socket descriptor on success.
208It returns \-1 on error with the global value
209.Va errno
210set according to the reason for failure.
211The error code
212.Dv EAGAIN
213is 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
225These
226functions 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)
37static 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
60int __ivaliduser __P((FILE *, in_addr_t, const char *, const char *));
61static int __icheckhost __P((u_int32_t, const char *));
62static char *__gethostloop __P((u_int32_t));
63
64int
65rcmd(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 }
183again:
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);
245bad2:
246 if (lport)
247 (void)close(*fd2p);
248bad:
249 if (readsp)
250 free(readsp);
251 (void)close(s);
252 sigsetmask(oldmask);
253 return (-1);
254}
255
256int
257rresvport(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
288int __check_rhosts_file = 1;
289char *__rcmd_errstr;
290
291int
292ruserok(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 */
323int
324iruserok(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");
339again:
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 */
398int
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 }
537bail:
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 */
545static 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 */
573static 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
45The
46.Fn rcmdsh
47function
48is used by normal users to execute a command on
49a remote machine using an authentication scheme based
50on reserved port numbers using
51.Xr rshd 8
52or the value of
53.Fa rshprog
54(if non-NULL).
55.Pp
56The
57.Fn rcmdsh
58function
59looks up the host
60.Fa *ahost
61using
62.Xr gethostbyname 3 ,
63returning \-1 if the host does not exist.
64Otherwise
65.Fa *ahost
66is set to the standard name of the host
67and a connection is established to a server
68residing 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
74is ignored; it is only included to provide an interface similar to
75.Xr rcmd 3 .
76.Pp
77If the connection succeeds,
78a socket in the
79.Tn UNIX
80domain of type
81.Dv SOCK_STREAM
82is returned to the caller, and given to the remote
83command as
84.Em stdin
85and
86.Em stdout ,
87and
88.Em stderr .
89.Sh DIAGNOSTICS
90The
91.Fn rcmdsh
92function
93returns a valid socket descriptor on success.
94It 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
101If
102.Xr rsh 1
103gets an error a file descriptor is still returned instead of \-1.
104.Sh HISTORY
105The
106.Fn rcmdsh
107function 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)
9static 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 */
30int
31rcmdsh(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)
35static 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
43ssize_t
44recv(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
60static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: res_comp.c,v 8.11 1996/12/02 09:17:22 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: res_comp.c,v 1.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
79static 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 */
89int
90dn_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 */
173int
174dn_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 */
253int
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
282static int
283mklower(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 */
297static int
298dn_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
367int
368res_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 */
397int
398res_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 */
414int
415res_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 */
444int
445res_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
460u_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 */
474u_int16_t
475res_getshort(msgp)
476 register const u_char *msgp;
477{
478 return (_getshort(msgp));
479}
480#endif
481
482u_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
492void
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
504void
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
60static char rcsid[] = "$From: res_data.c,v 8.2 1996/08/05 08:31:35 vixie Exp $";
61#else
62static char rcsid[] = "$OpenBSD: res_data.c,v 1.1 1997/03/13 19:07:36 downsj Exp $";
63#endif
64#endif /* LIBC_SCCS and not lint */
65
66#include <sys/types.h>
67#include <sys/param.h>
68#include <sys/socket.h>
69#include <sys/time.h>
70#include <netinet/in.h>
71#include <arpa/inet.h>
72#include <arpa/nameser.h>
73
74#include <stdio.h>
75#include <ctype.h>
76#include <resolv.h>
77#include <unistd.h>
78#include <stdlib.h>
79#include <string.h>
80
81const char *_res_opcodes[] = {
82 "QUERY",
83 "IQUERY",
84 "CQUERYM",
85 "CQUERYU", /* experimental */
86 "NOTIFY", /* experimental */
87 "5",
88 "6",
89 "7",
90 "8",
91 "UPDATEA",
92 "UPDATED",
93 "UPDATEDA",
94 "UPDATEM",
95 "UPDATEMA",
96 "ZONEINIT",
97 "ZONEREF",
98};
99
100const char *_res_resultcodes[] = {
101 "NOERROR",
102 "FORMERR",
103 "SERVFAIL",
104 "NXDOMAIN",
105 "NOTIMP",
106 "REFUSED",
107 "6",
108 "7",
109 "8",
110 "9",
111 "10",
112 "11",
113 "12",
114 "13",
115 "14",
116 "NOCHANGE",
117};
diff --git a/src/lib/libc/net/res_debug.c b/src/lib/libc/net/res_debug.c
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
82static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
83static char rcsid[] = "$From: res_debug.c,v 8.19 1996/11/26 10:11:23 vixie Exp $";
84#else
85static char rcsid[] = "$OpenBSD: res_debug.c,v 1.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
105extern const char *_res_opcodes[];
106extern const char *_res_resultcodes[];
107
108/* XXX: we should use getservbyport() instead. */
109static const char *
110dewks(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. */
167static const char *
168deproto(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
190static const u_char *
191do_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
231void
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 */
242void
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 */
262void
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
390void
391__fp_query(msg, file)
392 const u_char *msg;
393 FILE *file;
394{
395 fp_nquery(msg, PACKETSZ, file);
396}
397
398const 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
416const 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
428const u_char *
429__p_fqnname(cp, msg, msglen, name, namelen)
430 const u_char *cp, *msg;
431 int msglen;
432 char *name;
433 int namelen;
434{
435 int n, newlen;
436
437 if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
438 return (NULL);
439 newlen = strlen (name);
440 if (newlen == 0 || name[newlen - 1] != '.') {
441 if (newlen+1 >= namelen) /* Lack space for final dot */
442 return (NULL);
443 else
444 strcpy(name + newlen, ".");
445 }
446 return (cp + n);
447}
448
449/* XXX: the rest of these functions need to become length-limited, too. (vix)
450 */
451
452const 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 */
470const 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 */
863const 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 */
877const 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
927int
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
945const 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
968const 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 */
992const 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 */
1002const 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 */
1012const 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 */
1039const char *
1040p_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
1093static 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. */
1097static const char *
1098precsize_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. */
1115static u_int8_t
1116precsize_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. */
1157static u_int32_t
1158latlon2ul(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. */
1256int
1257loc_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. */
1368const char *
1369loc_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. */
1472int
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 */
1503char *
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
60static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
61static char rcsid[] = "$From: res_init.c,v 8.7 1996/09/28 06:51:07 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: res_init.c,v 1.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
105static void res_setoptions __P((char *, char *));
106
107#ifdef RESOLVSORT
108static const char sort_mask[] = "/&";
109#define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)
110static u_int32_t net_mask __P((struct in_addr));
111#endif
112
113/*
114 * Resolver state default settings.
115 */
116
117struct __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 */
144int
145res_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 */
457static void
458res_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. */
506static u_int32_t
507net_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
60static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: res_mkquery.c,v 8.5 1996/08/27 08:33:28 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: res_mkquery.c,v 1.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 */
82int
83res_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
60static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: res_query.c,v 8.9 1996/09/22 00:13:28 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: res_query.c,v 1.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
88const char *hostalias __P((const char *));
89int 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 */
101int
102res_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 */
177int
178res_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 */
316int
317res_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
353const char *
354hostalias(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
79const static u_int16_t pfacts[PFAC_N] = {
80 2,
81 3,
82 2729
83};
84
85static u_int16_t ru_x;
86static u_int16_t ru_seed;
87static u_int16_t ru_a, ru_b;
88static u_int16_t ru_g;
89static u_int16_t ru_counter = 0;
90static u_int16_t ru_msb = 0;
91static long ru_reseed;
92static u_int32_t tmp; /* Storage for unused random */
93static struct timeval tv;
94
95static u_int16_t pmod __P((u_int16_t, u_int16_t, u_int16_t));
96static 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__
104static u_int16_t
105pmod(u_int16_t gen, u_int16_t exp, u_int16_t mod)
106#else
107static u_int16_t
108pmod(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 */
135static void
136res_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
184u_int
185res_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
211void
212main(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
60static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: res_send.c,v 8.12 1996/10/08 04:51:06 vixie Exp $";
62#else
63static char rcsid[] = "$OpenBSD: res_send.c,v 1.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
95static int s = -1; /* socket used for communications */
96static int connected = 0; /* is the socket connected */
97static 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
156static res_send_qhook Qhook = NULL;
157static res_send_rhook Rhook = NULL;
158
159void
160res_send_setqhook(hook)
161 res_send_qhook hook;
162{
163
164 Qhook = hook;
165}
166
167void
168res_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 */
184int
185res_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 */
217int
218res_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 */
255int
256res_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
281int
282res_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 */
404read_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 */
771void
772res_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
98These routines are used for making, sending and interpreting
99query and reply messages with Internet domain name servers.
100.Pp
101Global configuration and state information that is used by the
102resolver routines is kept in the structure
103.Em _res .
104Most of the values have reasonable defaults and can be ignored.
105Options
106stored in
107.Em _res.options
108are defined in
109.Pa resolv.h
110and are as follows.
111Options are stored as a simple bit mask containing the bitwise ``or''
112of the options enabled.
113.Bl -tag -width RES_USE_INET6
114.It Dv RES_INIT
115True if the initial name server address and default domain name are
116initialized (i.e.,
117.Fn res_init
118has been called).
119.It Dv RES_DEBUG
120Print debugging messages.
121.It Dv RES_AAONLY
122Accept authoritative answers only.
123With this option,
124.Fn res_send
125should continue until it finds an authoritative answer or finds an error.
126Currently this is not implemented.
127.It Dv RES_USEVC
128Use
129.Tn TCP
130connections for queries instead of
131.Tn UDP
132datagrams.
133.It Dv RES_STAYOPEN
134Used with
135.Dv RES_USEVC
136to keep the
137.Tn TCP
138connection open between
139queries.
140This is useful only in programs that regularly do many queries.
141.Tn UDP
142should be the normal mode used.
143.It Dv RES_IGNTC
144Unused currently (ignore truncation errors, i.e., don't retry with
145.Tn TCP ) .
146.It Dv RES_RECURSE
147Set the recursion-desired bit in queries.
148This is the default.
149.Pf ( Fn res_send
150does not do iterative queries and expects the name server
151to handle recursion.)
152.It Dv RES_DEFNAMES
153If set,
154.Fn res_search
155will append the default domain name to single-component names
156(those that do not contain a dot).
157This option is enabled by default.
158.It Dv RES_DNSRCH
159If this option is set,
160.Fn res_search
161will search for host names in the current domain and in parent domains; see
162.Xr hostname 7 .
163This is used by the standard host lookup routine
164.Xr gethostbyname 3 .
165This option is enabled by default.
166.It Dv RES_USE_INET6
167Enable support for IPv6 addresses.
168.El
169.Pp
170The
171.Fn res_init
172routine
173reads the configuration file (if any; see
174.Xr resolv.conf 5 )
175to get the default domain name,
176search list and
177the Internet address of the local name server(s).
178If no server is configured, the host running
179the resolver is tried.
180The current domain name is defined by the hostname
181if not specified in the configuration file;
182it can be overridden by the environment variable
183.Ev LOCALDOMAIN .
184This environment variable may contain several blank-separated
185tokens if you wish to override the
186.Fa search list
187on a per-process basis.
188This is similar to the
189.Fa search
190command in the configuration file.
191Another environment variable
192.Ev RES_OPTIONS
193can be set to override certain internal resolver options which
194are otherwise set by changing fields in the
195.Fa _res
196structure or are inherited from the configuration file's
197.Fa options
198command.
199The syntax of the
200.Ev RES_OPTIONS
201environment variable is explained in
202.Xr resolv.conf 5 .
203Initialization normally occurs on the first call
204to one of the following routines.
205.Pp
206The
207.Fn res_query
208function provides an interface to the server query mechanism.
209It constructs a query, sends it to the local server,
210awaits a response, and makes preliminary checks on the reply.
211The query requests information of the specified
212.Fa type
213and
214.Fa class
215for the specified fully-qualified domain name
216.Fa dname .
217The reply message is left in the
218.Fa answer
219buffer with length
220.Fa anslen
221supplied by the caller.
222.Pp
223The
224.Fn res_search
225routine makes a query and awaits a response like
226.Fn res_query ,
227but in addition, it implements the default and search rules
228controlled by the
229.Dv RES_DEFNAMES
230and
231.Dv RES_DNSRCH
232options.
233It returns the first successful reply.
234.Pp
235The remaining routines are lower-level routines used by
236.Fn res_query .
237The
238.Fn res_mkquery
239function
240constructs a standard query message and places it in
241.Fa buf .
242It returns the size of the query, or \-1 if the query is
243larger than
244.Fa buflen .
245The query type
246.Fa op
247is usually
248.Dv QUERY ,
249but can be any of the query types defined in
250.Aq Pa arpa/nameser.h .
251The domain name for the query is given by
252.Fa dname .
253.Fa Newrr
254is currently unused but is intended for making update messages.
255.Pp
256The
257.Fn res_send
258routine
259sends a pre-formatted query and returns an answer.
260It will call
261.Fn res_init
262if
263.Dv RES_INIT
264is not set, send the query to the local name server, and
265handle timeouts and retries.
266The length of the reply message is returned, or
267\-1 if there were errors.
268.Pp
269The
270.Fn dn_comp
271function
272compresses the domain name
273.Fa exp_dn
274and stores it in
275.Fa comp_dn .
276The size of the compressed name is returned or \-1 if there were errors.
277The size of the array pointed to by
278.Fa comp_dn
279is given by
280.Fa length .
281The compression uses
282an array of pointers
283.Fa dnptrs
284to previously-compressed names in the current message.
285The first pointer points
286to the beginning of the message and the list ends with
287.Dv NULL .
288The limit to the array is specified by
289.Fa lastdnptr .
290A side effect of
291.Fn dn_comp
292is to update the list of pointers for
293labels inserted into the message
294as the name is compressed.
295If
296.Em dnptr
297is
298.Dv NULL, names are not compressed.
299If
300.Fa lastdnptr
301is
302.Dv NULL ,
303the list of labels is not updated.
304.Pp
305The
306.Fn dn_expand
307entry
308expands the compressed domain name
309.Fa comp_dn
310to a full domain name
311The compressed name is contained in a query or reply message;
312.Fa msg
313is a pointer to the beginning of the message.
314The uncompressed name is placed in the buffer indicated by
315.Fa exp_dn
316which is of size
317.Fa length .
318The 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
322The configuration file
323see
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
342The
343.Nm
344function 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)
35static 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
43ssize_t
44send(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)
35static 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
44void
45sethostent(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
55void
56endhostent()
57{
58 _res.options &= ~(RES_STAYOPEN | RES_USEVC);
59 res_close();
60}