xref: /openbsd-src/sys/arch/alpha/stand/netboot/dev_net.c (revision e3d385664cbc435ceb49334c27255356e826313a)
1 /*	$OpenBSD: dev_net.c,v 1.7 2023/01/16 07:29:35 deraadt Exp $	*/
2 /*	$NetBSD: dev_net.c,v 1.4 1997/04/06 08:41:24 cgd Exp $	*/
3 
4 /*
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  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /*
30  * This module implements a "raw device" interface suitable for
31  * use by the stand-alone I/O library NFS code.  This interface
32  * does not support any "block" access, and exists only for the
33  * purpose of initializing the network interface, getting boot
34  * parameters, and performing the NFS mount.
35  *
36  * At open time, this does:
37  *
38  * find interface      - netif_open()
39  * RARP for IP address - rarp_getipaddress()
40  * RPC/bootparams      - callrpc(d, RPC_BOOTPARAMS, ...)
41  * RPC/mountd          - nfs_mount(sock, ip, path)
42  *
43  * the root file handle from mountd is saved in a global
44  * for use by the NFS open code (NFS/lookup).
45  */
46 
47 #include <stdarg.h>
48 #include <sys/param.h>
49 #include <sys/socket.h>
50 #include <net/if.h>
51 #include <netinet/in.h>
52 #include <netinet/if_ether.h>
53 
54 #include <lib/libsa/stand.h>
55 #include <lib/libsa/net.h>
56 #include <lib/libsa/netif.h>
57 #include <lib/libsa/bootparam.h>
58 #include "dev_net.h"
59 
60 extern int debug;
61 extern int nfs_root_node[];	/* XXX - get from nfs_mount() */
62 
63 /*
64  * Various globals needed by the network code:
65  */
66 
67 #if 0
68 /* for arp.c, rarp.c */
69 u_char bcea[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
70 #endif
71 
72 /*
73  * Local things...
74  */
75 static int netdev_sock = -1;
76 static int netdev_opens;
77 
78 int net_getparams(int);
79 int nfs_mount(int, struct in_addr, char *);
80 
81 /*
82  * Called by devopen after it sets f->f_dev to our devsw entry.
83  * This opens the low-level device and sets f->f_devdata.
84  * This is declared with variable arguments...
85  */
86 int
net_open(struct open_file * f,...)87 net_open(struct open_file *f, ...)
88 {
89 	va_list ap;
90 	char *devname;		/* Device part of file name (or NULL). */
91 	int error = 0;
92 
93 	va_start(ap, f);
94 	devname = va_arg(ap, char *);
95 	va_end(ap);
96 
97 #ifdef	NETIF_DEBUG
98 	if (debug)
99 		printf("net_open: %s\n", devname);
100 #endif
101 
102 	/* On first open, do netif open, mount, etc. */
103 	if (netdev_opens == 0) {
104 		/* Find network interface. */
105 		if (netdev_sock < 0) {
106 			netdev_sock = netif_open(devname);
107 			if (netdev_sock < 0) {
108 				printf("net_open: netif_open() failed\n");
109 				return (ENXIO);
110 			}
111 			if (debug)
112 				printf("net_open: netif_open() succeeded\n");
113 		}
114 		if (rootip.s_addr == 0) {
115 			/* Get root IP address, and path, etc. */
116 			error = net_getparams(netdev_sock);
117 			if (error) {
118 				/* getparams makes its own noise */
119 				goto fail;
120 			}
121 			/* Get the NFS file handle (mountd). */
122 			error = nfs_mount(netdev_sock, rootip, rootpath);
123 			if (error) {
124 				printf("net_open: NFS mount error=%d\n", error);
125 				rootip.s_addr = 0;
126 			fail:
127 				netif_close(netdev_sock);
128 				netdev_sock = -1;
129 				return (error);
130 			}
131 			if (debug)
132 				printf("net_open: NFS mount succeeded\n");
133 		}
134 	}
135 	netdev_opens++;
136 	f->f_devdata = nfs_root_node;
137 	return (error);
138 }
139 
140 int
net_close(f)141 net_close(f)
142 	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 		if (debug)
162 			printf("net_close: calling netif_close()\n");
163 		netif_close(netdev_sock);
164 		netdev_sock = -1;
165 	}
166 	return (0);
167 }
168 
169 int
net_ioctl()170 net_ioctl()
171 {
172 	return EIO;
173 }
174 
175 int
net_strategy()176 net_strategy()
177 {
178 	return EIO;
179 }
180 
181 int
net_getparams(sock)182 net_getparams(sock)
183 	int sock;
184 {
185 	/*
186 	 * Get info for NFS boot: our IP address, our hostname,
187 	 * server IP address, and our root path on the server.
188 	 * There are two ways to do this:  The old, Sun way,
189 	 * and the more modern, BOOTP way. (RFC951, RFC1048)
190 	 */
191 
192 #ifdef	SUN_BOOTPARAMS
193 	/* Get our IP address.  (rarp.c) */
194 	if (rarp_getipaddress(sock)) {
195 		printf("net_open: RARP failed\n");
196 		return (EIO);
197 	}
198 #else	/* BOOTPARAMS */
199 	/*
200 	 * Get boot info using BOOTP. (RFC951, RFC1048)
201 	 * This also gets the server IP address, gateway,
202 	 * root path, etc.
203 	 */
204 	bootp(sock);
205 	if (myip.s_addr == 0) {
206 		printf("net_open: BOOTP failed\n");
207 		return (EIO);
208 	}
209 #endif	/* BOOTPARAMS */
210 
211 	printf("boot: client addr: %s\n", inet_ntoa(myip));
212 
213 #ifdef	SUN_BOOTPARAMS
214 	/* Get our hostname, server IP address, gateway. */
215 	if (bp_whoami(sock)) {
216 		printf("net_open: bootparam/whoami RPC failed\n");
217 		return (EIO);
218 	}
219 #endif	/* BOOTPARAMS */
220 
221 	printf("boot: client name: %s\n", hostname);
222 	if (gateip.s_addr) {
223 		printf("boot: subnet mask: %s\n", intoa(netmask));
224 		printf("boot: net gateway: %s\n", inet_ntoa(gateip));
225 	}
226 
227 #ifdef	SUN_BOOTPARAMS
228 	/* Get the root pathname. */
229 	if (bp_getfile(sock, "root", &rootip, rootpath)) {
230 		printf("net_open: bootparam/getfile RPC failed\n");
231 		return (EIO);
232 	}
233 #endif	/* BOOTPARAMS */
234 
235 	printf("boot: server addr: %s\n", inet_ntoa(rootip));
236 	printf("boot: server path: %s\n", rootpath);
237 
238 	return (0);
239 }
240