xref: /openbsd/sys/arch/luna88k/stand/boot/dev_net.c (revision e5dd7070)
1 /*	$OpenBSD: dev_net.c,v 1.3 2014/07/13 15:31:20 mpi Exp $	*/
2 /*	$NetBSD: dev_net.c,v 1.26 2011/07/17 20:54:52 joerg Exp $	*/
3 
4 /*-
5  * Copyright (c) 1997 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Gordon W. Ross.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * This module implements a "raw device" interface suitable for
35  * use by the stand-alone I/O library NFS code.  This interface
36  * does not support any "block" access, and exists only for the
37  * purpose of initializing the network interface, getting boot
38  * parameters, and performing the NFS mount.
39  *
40  * At open time, this does:
41  *
42  * find interface      - netif_open()
43  * RARP for IP address - rarp_getipaddress()
44  * RPC/bootparams      - callrpc(d, RPC_BOOTPARAMS, ...)
45  * RPC/mountd          - nfs_mount(sock, ip, path)
46  *
47  * the root file handle from mountd is saved in a global
48  * for use by the NFS open code (NFS/lookup).
49  */
50 
51 #include <sys/param.h>
52 #include <sys/socket.h>
53 #include <netinet/in.h>
54 
55 #include <lib/libkern/libkern.h>
56 
57 #include <lib/libsa/stand.h>
58 #include <lib/libsa/net.h>
59 #include <lib/libsa/netif.h>
60 #include <lib/libsa/nfs.h>
61 #include <lib/libsa/bootparam.h>
62 #include "dev_net.h"
63 #ifdef SUPPORT_BOOTP
64 #include <lib/libsa/bootp.h>
65 #endif
66 
67 extern int nfs_root_node[];	/* XXX - get from nfs_mount() */
68 
69 static int netdev_sock = -1;
70 static int netdev_opens;
71 
72 static int net_getparams(int);
73 
74 #ifdef DEBUG
75 int debug;
76 #endif
77 
78 /*
79  * Called by devopen after it sets f->f_dev to our devsw entry.
80  * This opens the low-level device and sets f->f_devdata.
81  * This is declared with variable arguments...
82  */
83 int
84 net_open(struct open_file *f, ...)
85 {
86 	va_list ap;
87 	char *devname;		/* Device part of file name (or NULL). */
88 	int error = 0;
89 
90 	va_start(ap, f);
91 	devname = va_arg(ap, char *);
92 	va_end(ap);
93 
94 #ifdef	NETIF_DEBUG
95 	if (debug)
96 		printf("%s\n", devname);
97 #endif
98 
99 	/* On first open, do netif open, mount, etc. */
100 	if (netdev_opens == 0) {
101 		/* Find network interface. */
102 		if (netdev_sock < 0) {
103 			netdev_sock = netif_open(devname);
104 			if (netdev_sock < 0) {
105 				printf("netif_open() failed\n");
106 				return ENXIO;
107 			}
108 #ifdef NETIF_DEBUG
109 			if (debug)
110 				printf("netif_open() succeeded\n");
111 #endif
112 		}
113 		if (rootip.s_addr == 0) {
114 			/* Get root IP address, and path, etc. */
115 			error = net_getparams(netdev_sock);
116 			if (error) {
117 				/* getparams makes its own noise */
118 				goto fail;
119 			}
120 			/* Get the NFS file handle (mountd). */
121 			error = nfs_mount(netdev_sock, rootip, rootpath);
122 			if (error) {
123 				printf("NFS mount error=%d\n", errno);
124 				rootip.s_addr = 0;
125 			fail:
126 				netif_close(netdev_sock);
127 				netdev_sock = -1;
128 				return error;
129 			}
130 #ifdef NETIF_DEBUG
131 			if (debug)
132 				printf("NFS mount succeeded\n");
133 #endif
134 		}
135 	}
136 	netdev_opens++;
137 	f->f_devdata = nfs_root_node;
138 	return error;
139 }
140 
141 int
142 net_close(struct open_file *f)
143 {
144 
145 #ifdef	NETIF_DEBUG
146 	if (debug)
147 		printf("net_close: opens=%d\n", netdev_opens);
148 #endif
149 
150 	/* On last close, do netif close, etc. */
151 	f->f_devdata = NULL;
152 	/* Extra close call? */
153 	if (netdev_opens <= 0)
154 		return 0;
155 	netdev_opens--;
156 	/* Not last close? */
157 	if (netdev_opens > 0)
158 		return 0;
159 	rootip.s_addr = 0;
160 	if (netdev_sock >= 0) {
161 #ifdef NETIF_DEBUG
162 		if (debug)
163 			printf("net_close: calling netif_close()\n");
164 #endif
165 		netif_close(netdev_sock);
166 		netdev_sock = -1;
167 	}
168 	return 0;
169 }
170 
171 int
172 net_ioctl(struct open_file *f, u_long cmd, void *data)
173 {
174 
175 	return EIO;
176 }
177 
178 int
179 net_strategy(void *devdata, int rw, daddr32_t blk, size_t size, void *buf,
180 	size_t *rsize)
181 {
182 
183 	return EIO;
184 }
185 
186 
187 /*
188  * Get info for NFS boot: our IP address, our hostname,
189  * server IP address, and our root path on the server.
190  * There are two ways to do this:  The old, Sun way,
191  * and the more modern, BOOTP way. (RFC951, RFC1048)
192  *
193  * The default is to use the Sun bootparams RPC
194  * (because that is what the kernel will do).
195  * MD code can make try_bootp initialied data,
196  * which will override this common definition.
197  */
198 #ifdef	SUPPORT_BOOTP
199 int try_bootp;
200 #endif
201 
202 static int
203 net_getparams(int sock)
204 {
205 	char buf[MAXHOSTNAMELEN];
206 	u_int32_t smask;
207 
208 #ifdef	SUPPORT_BOOTP
209 	/*
210 	 * Try to get boot info using BOOTP.  If we succeed, then
211 	 * the server IP address, gateway, and root path will all
212 	 * be initialized.  If any remain uninitialized, we will
213 	 * use RARP and RPC/bootparam (the Sun way) to get them.
214 	 */
215 	if (try_bootp)
216 		bootp(sock);
217 	if (myip.s_addr != 0)
218 		return 0;
219 #ifdef NETIF_DEBUG
220 	if (debug)
221 		printf("BOOTP failed, trying RARP/RPC...\n");
222 #endif
223 #endif
224 
225 	/*
226 	 * Use RARP to get our IP address.  This also sets our
227 	 * netmask to the "natural" default for our address.
228 	 */
229 	if (rarp_getipaddress(sock)) {
230 		printf("RARP failed\n");
231 		return EIO;
232 	}
233 #ifdef NETIF_DEBUG
234 	if (debug)
235 		printf("client addr: %s\n", inet_ntoa(myip));
236 #endif
237 
238 	/* Get our hostname, server IP address, gateway. */
239 	if (bp_whoami(sock)) {
240 		printf("bootparam/whoami RPC failed\n");
241 		return EIO;
242 	}
243 #ifdef NETIF_DEBUG
244 	if (debug)
245 		printf("client name: %s\n", hostname);
246 #endif
247 
248 	/*
249 	 * Ignore the gateway from whoami (unreliable).
250 	 * Use the "gateway" parameter instead.
251 	 */
252 	smask = 0;
253 	gateip.s_addr = 0;
254 	if (bp_getfile(sock, "gateway", &gateip, buf)) {
255 		printf("nfs_open: gateway bootparam missing\n");
256 	} else {
257 		/* Got it!  Parse the netmask. */
258 		smask = inet_addr(buf);
259 	}
260 	if (smask) {
261 		netmask = smask;
262 #ifdef NETIF_DEBUG
263 		if (debug)
264 			printf("subnet mask: %s\n", intoa(netmask));
265 #endif
266 	}
267 #ifdef NETIF_DEBUG
268 	if (debug)
269 		if (gateip.s_addr)
270 			printf("net gateway: %s\n", inet_ntoa(gateip));
271 #endif
272 
273 	/* Get the root server and pathname. */
274 	if (bp_getfile(sock, "root", &rootip, rootpath)) {
275 		printf("bootparam/getfile RPC failed\n");
276 		return EIO;
277 	}
278 
279 #ifdef NETIF_DEBUG
280 	if (debug) {
281 		printf("server addr: %s\n", inet_ntoa(rootip));
282 		printf("server path: %s\n", rootpath);
283 	}
284 #endif
285 
286 	return 0;
287 }
288