xref: /netbsd-src/sys/arch/hp300/stand/common/netio.c (revision d0fed6c87ddc40a8bffa6f99e7433ddfc864dd83)
1 /*	$NetBSD: netio.c,v 1.2 1997/03/15 18:09:50 is Exp $	*/
2 
3 /*
4  * Copyright (c) 1995, 1996 Jason R. Thorpe
5  * Copyright (c) 1995 Gordon W. Ross
6  * All rights reserved.
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. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  * 4. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by Gordon W. Ross
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /*
35  * This module implements a "raw device" interface suitable for
36  * use by the stand-alone I/O library NFS code.  This interface
37  * does not support any "block" access, and exists only for the
38  * purpose of initializing the network interface, getting boot
39  * parameters, and performing the NFS mount.
40  *
41  * At open time, this does:
42  *
43  * find interface      - netif_open()
44  * RARP for IP address - rarp_getipaddress()
45  * RPC/bootparams      - callrpc(d, RPC_BOOTPARAMS, ...)
46  * RPC/mountd          - nfs_mount(sock, ip, path)
47  *
48  * the root file handle from mountd is saved in a global
49  * for use by the NFS open code (NFS/lookup).
50  */
51 
52 #include <sys/param.h>
53 #include <sys/socket.h>
54 
55 #include <net/if.h>
56 #include <netinet/in.h>
57 #include <lib/libsa/if_ether.h>
58 #include <netinet/in_systm.h>
59 
60 #include <lib/libsa/stand.h>
61 #include <lib/libsa/net.h>
62 #include <lib/libsa/netif.h>
63 #include <lib/libsa/bootparam.h>
64 #include <lib/libsa/nfs.h>
65 
66 #include <hp300/stand/common/samachdep.h>
67 
68 extern int nfs_root_node[];	/* XXX - get from nfs_mount() */
69 
70 struct	in_addr myip, rootip, gateip;
71 n_long	netmask;
72 char rootpath[FNAME_SIZE];
73 
74 int netdev_sock = -1;
75 static int open_count;
76 
77 int netio_ask = 0;		/* default to bootparam, can override */
78 
79 static	char input_line[100];
80 
81 /* Why be any different? */
82 #define SUN_BOOTPARAMS
83 
84 /*
85  * Called by devopen after it sets f->f_dev to our devsw entry.
86  * This opens the low-level device and sets f->f_devdata.
87  */
88 int
89 netopen(f, devname)
90 	struct open_file *f;
91 	char *devname;		/* Device part of file name (or NULL). */
92 {
93 	int error = 0;
94 
95 	/* On first open, do netif open, mount, etc. */
96 	if (open_count == 0) {
97 		/* Find network interface. */
98 		if ((netdev_sock = netif_open(devname)) < 0)
99 			return (error=ENXIO);
100 		if ((error = netmountroot(f, devname)) != 0)
101 			return (error);
102 	}
103 	open_count++;
104 	f->f_devdata = nfs_root_node;
105 	return (error);
106 }
107 
108 int
109 netclose(f)
110 	struct open_file *f;
111 {
112 	/* On last close, do netif close, etc. */
113 	if (open_count > 0)
114 		if (--open_count == 0)
115 			netif_close(netdev_sock);
116 	f->f_devdata = NULL;
117 }
118 
119 int
120 netstrategy(devdata, func, dblk, size, v_buf, rsize)
121 	void *devdata;
122 	int func;
123 	daddr_t dblk;
124 	size_t size;
125 	void *v_buf;
126 	size_t *rsize;
127 {
128 
129 	*rsize = size;
130 	return EIO;
131 }
132 
133 int
134 netmountroot(f, devname)
135 	struct open_file *f;
136 	char *devname;		/* Device part of file name (or NULL). */
137 {
138 	int error;
139 	struct iodesc *d;
140 
141 #ifdef DEBUG
142 	printf("netmountroot: %s\n", devname);
143 #endif
144 
145 	if (netio_ask) {
146  get_my_ip:
147 		printf("My IP address? ");
148 		bzero(input_line, sizeof(input_line));
149 		gets(input_line);
150 		if ((myip.s_addr = inet_addr(input_line)) ==
151 		    htonl(INADDR_NONE)) {
152 			printf("invalid IP address: %s\n", input_line);
153 			goto get_my_ip;
154 		}
155 
156  get_my_netmask:
157 		printf("My netmask? ");
158 		bzero(input_line, sizeof(input_line));
159 		gets(input_line);
160 		if ((netmask = inet_addr(input_line)) ==
161 		    htonl(INADDR_NONE)) {
162 			printf("invalid netmask: %s\n", input_line);
163 			goto get_my_netmask;
164 		}
165 
166  get_my_gateway:
167 		printf("My gateway? ");
168 		bzero(input_line, sizeof(input_line));
169 		gets(input_line);
170 		if ((gateip.s_addr = inet_addr(input_line)) ==
171 		    htonl(INADDR_NONE)) {
172 			printf("invalid IP address: %s\n", input_line);
173 			goto get_my_gateway;
174 		}
175 
176  get_server_ip:
177 		printf("Server IP address? ");
178 		bzero(input_line, sizeof(input_line));
179 		gets(input_line);
180 		if ((rootip.s_addr = inet_addr(input_line)) ==
181 		    htonl(INADDR_NONE)) {
182 			printf("invalid IP address: %s\n", input_line);
183 			goto get_server_ip;
184 		}
185 
186  get_server_path:
187 		printf("Server path? ");
188 		bzero(rootpath, sizeof(rootpath));
189 		gets(rootpath);
190 		if (rootpath[0] == '\0' || rootpath[0] == '\n')
191 			goto get_server_path;
192 
193 		if ((d = socktodesc(netdev_sock)) == NULL)
194 			return (EMFILE);
195 
196 		d->myip = myip;
197 
198 		goto do_nfs_mount;
199 	}
200 
201 	/*
202 	 * Get info for NFS boot: our IP address, our hostname,
203 	 * server IP address, and our root path on the server.
204 	 * There are two ways to do this:  The old, Sun way,
205 	 * and the more modern, BOOTP way. (RFC951, RFC1048)
206 	 */
207 
208 #ifdef	SUN_BOOTPARAMS
209 	/* Get boot info using RARP and Sun bootparams. */
210 
211 	/* Get our IP address.  (rarp.c) */
212 	if (rarp_getipaddress(netdev_sock) == -1)
213 		return (errno);
214 
215 	printf("boot: client IP address: %s\n", inet_ntoa(myip));
216 
217 	/* Get our hostname, server IP address. */
218 	if (bp_whoami(netdev_sock))
219 		return (errno);
220 
221 	printf("boot: client name: %s\n", hostname);
222 
223 	/* Get the root pathname. */
224 	if (bp_getfile(netdev_sock, "root", &rootip, rootpath))
225 		return (errno);
226 
227 #else
228 
229 	/* Get boot info using BOOTP way. (RFC951, RFC1048) */
230 	bootp(netdev_sock);
231 
232 	printf("Using IP address: %s\n", inet_ntoa(myip));
233 
234 	printf("myip: %s (%s)", hostname, inet_ntoa(myip));
235 	if (gateip)
236 		printf(", gateip: %s", inet_ntoa(gateip));
237 	if (mask)
238 		printf(", mask: %s", intoa(netmask));
239 	printf("\n");
240 
241 #endif /* SUN_BOOTPARAMS */
242 
243 	printf("root addr=%s path=%s\n", inet_ntoa(rootip), rootpath);
244 
245  do_nfs_mount:
246 	/* Get the NFS file handle (mount). */
247 	error = nfs_mount(netdev_sock, rootip, rootpath);
248 
249 	return (error);
250 }
251