xref: /netbsd-src/sys/arch/i386/stand/efiboot/dev_net.c (revision fcd0bf31a0548706309f86fd396cfc7cce6348d1)
1*fcd0bf31Snonaka /*	$NetBSD: dev_net.c,v 1.3 2019/09/26 12:21:03 nonaka Exp $	*/
2b014c9faSnonaka 
3179a5458Snonaka /*-
4179a5458Snonaka  * Copyright (c) 1997 The NetBSD Foundation, Inc.
5179a5458Snonaka  * All rights reserved.
6179a5458Snonaka  *
7179a5458Snonaka  * This code is derived from software contributed to The NetBSD Foundation
8179a5458Snonaka  * by Gordon W. Ross.
9179a5458Snonaka  *
10179a5458Snonaka  * Redistribution and use in source and binary forms, with or without
11179a5458Snonaka  * modification, are permitted provided that the following conditions
12179a5458Snonaka  * are met:
13179a5458Snonaka  * 1. Redistributions of source code must retain the above copyright
14179a5458Snonaka  *    notice, this list of conditions and the following disclaimer.
15179a5458Snonaka  * 2. Redistributions in binary form must reproduce the above copyright
16179a5458Snonaka  *    notice, this list of conditions and the following disclaimer in the
17179a5458Snonaka  *    documentation and/or other materials provided with the distribution.
18179a5458Snonaka  *
19179a5458Snonaka  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20179a5458Snonaka  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21179a5458Snonaka  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22179a5458Snonaka  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23179a5458Snonaka  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24179a5458Snonaka  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25179a5458Snonaka  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26179a5458Snonaka  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27179a5458Snonaka  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28179a5458Snonaka  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29179a5458Snonaka  * POSSIBILITY OF SUCH DAMAGE.
30179a5458Snonaka  */
31179a5458Snonaka 
32179a5458Snonaka /*
33179a5458Snonaka  * This module implements a "raw device" interface suitable for
34179a5458Snonaka  * use by the stand-alone I/O library NFS code.  This interface
35179a5458Snonaka  * does not support any "block" access, and exists only for the
36179a5458Snonaka  * purpose of initializing the network interface, getting boot
37179a5458Snonaka  * parameters, and performing the NFS mount.
38179a5458Snonaka  *
39179a5458Snonaka  * At open time, this does:
40179a5458Snonaka  *
41179a5458Snonaka  * find interface      - netif_open()
42179a5458Snonaka  * RARP for IP address - rarp_getipaddress()
43179a5458Snonaka  * RPC/bootparams      - callrpc(d, RPC_BOOTPARAMS, ...)
44179a5458Snonaka  * RPC/mountd          - nfs_mount(sock, ip, path)
45179a5458Snonaka  */
46179a5458Snonaka 
47179a5458Snonaka #include <sys/param.h>
48179a5458Snonaka #include <sys/socket.h>
49179a5458Snonaka #include <net/if.h>
50179a5458Snonaka #include <netinet/in.h>
51179a5458Snonaka #include <netinet/in_systm.h>
52179a5458Snonaka 
53179a5458Snonaka #include <lib/libkern/libkern.h>
54179a5458Snonaka 
55179a5458Snonaka #include "stand.h"
56179a5458Snonaka #include "net.h"
57179a5458Snonaka #include "netif.h"
58179a5458Snonaka #include "nfs.h"
59179a5458Snonaka #include "bootparam.h"
60179a5458Snonaka #include "dev_net.h"
61179a5458Snonaka #ifdef SUPPORT_BOOTP
62179a5458Snonaka #include "bootp.h"
63179a5458Snonaka #endif
64179a5458Snonaka 
65179a5458Snonaka static int netdev_sock = -1;
66179a5458Snonaka static int netdev_opens;
67179a5458Snonaka 
68179a5458Snonaka static int net_getparams(int);
69179a5458Snonaka 
70179a5458Snonaka /*
71179a5458Snonaka  * Called by devopen after it sets f->f_dev to our devsw entry.
72179a5458Snonaka  * This opens the low-level device and sets f->f_devdata.
73179a5458Snonaka  * This is declared with variable arguments...
74179a5458Snonaka  */
75179a5458Snonaka int
net_open(struct open_file * f,...)76179a5458Snonaka net_open(struct open_file *f, ...)
77179a5458Snonaka {
78179a5458Snonaka 	va_list ap;
79*fcd0bf31Snonaka 	struct devdesc *dev;
80179a5458Snonaka 	int error = 0;
81179a5458Snonaka 
82179a5458Snonaka 	va_start(ap, f);
83*fcd0bf31Snonaka 	dev = va_arg(ap, struct devdesc *);
84179a5458Snonaka 	va_end(ap);
85179a5458Snonaka 
86179a5458Snonaka #ifdef	NETIF_DEBUG
87179a5458Snonaka 	if (debug)
88*fcd0bf31Snonaka 		printf("%s\n", dev->devname);
89179a5458Snonaka #endif
90179a5458Snonaka 
91179a5458Snonaka 	/* On first open, do netif open, mount, etc. */
92179a5458Snonaka 	if (netdev_opens == 0) {
93179a5458Snonaka 		/* Find network interface. */
94179a5458Snonaka 		if (netdev_sock < 0) {
95*fcd0bf31Snonaka 			netdev_sock = netif_open(dev);
96179a5458Snonaka 			if (netdev_sock < 0) {
97179a5458Snonaka 				printf("netif_open() failed\n");
98179a5458Snonaka 				return ENXIO;
99179a5458Snonaka 			}
100179a5458Snonaka #ifdef NETIF_DEBUG
101179a5458Snonaka 			if (debug)
102179a5458Snonaka 				printf("netif_open() succeeded\n");
103179a5458Snonaka #endif
104179a5458Snonaka 		}
105179a5458Snonaka 		if (rootip.s_addr == 0) {
106179a5458Snonaka 			/* Get root IP address, and path, etc. */
107179a5458Snonaka 			error = net_getparams(netdev_sock);
108179a5458Snonaka 			if (error) {
109179a5458Snonaka 				/* getparams makes its own noise */
110179a5458Snonaka 				netif_close(netdev_sock);
111179a5458Snonaka 				netdev_sock = -1;
112179a5458Snonaka 				return error;
113179a5458Snonaka 			}
114179a5458Snonaka 		}
115179a5458Snonaka 	}
116179a5458Snonaka 	netdev_opens++;
117179a5458Snonaka 	f->f_devdata = &netdev_sock;
118179a5458Snonaka 	return error;
119179a5458Snonaka }
120179a5458Snonaka 
121179a5458Snonaka int
net_close(struct open_file * f)122179a5458Snonaka net_close(struct open_file *f)
123179a5458Snonaka {
124179a5458Snonaka 
125179a5458Snonaka #ifdef	NETIF_DEBUG
126179a5458Snonaka 	if (debug)
127179a5458Snonaka 		printf("net_close: opens=%d\n", netdev_opens);
128179a5458Snonaka #endif
129179a5458Snonaka 
130179a5458Snonaka 	/* On last close, do netif close, etc. */
131179a5458Snonaka 	f->f_devdata = NULL;
132179a5458Snonaka 	/* Extra close call? */
133179a5458Snonaka 	if (netdev_opens <= 0)
134179a5458Snonaka 		return 0;
135179a5458Snonaka 	netdev_opens--;
136179a5458Snonaka 	/* Not last close? */
137179a5458Snonaka 	if (netdev_opens > 0)
138179a5458Snonaka 		return 0;
139179a5458Snonaka 	rootip.s_addr = 0;
140179a5458Snonaka 	if (netdev_sock >= 0) {
141179a5458Snonaka #ifdef NETIF_DEBUG
142179a5458Snonaka 		if (debug)
143179a5458Snonaka 			printf("%s: calling netif_close()\n", __func__);
144179a5458Snonaka #endif
145179a5458Snonaka 		netif_close(netdev_sock);
146179a5458Snonaka 		netdev_sock = -1;
147179a5458Snonaka 	}
148179a5458Snonaka 	return 0;
149179a5458Snonaka }
150179a5458Snonaka 
151179a5458Snonaka int
net_ioctl(struct open_file * f,u_long cmd,void * data)152179a5458Snonaka net_ioctl(struct open_file *f, u_long cmd, void *data)
153179a5458Snonaka {
154179a5458Snonaka 
155179a5458Snonaka 	return EIO;
156179a5458Snonaka }
157179a5458Snonaka 
158179a5458Snonaka int
net_strategy(void * devdata,int rw,daddr_t blk,size_t size,void * buf,size_t * rsize)159179a5458Snonaka net_strategy(void *devdata, int rw, daddr_t blk, size_t size, void *buf,
160179a5458Snonaka 	size_t *rsize)
161179a5458Snonaka {
162179a5458Snonaka 
163179a5458Snonaka 	return EIO;
164179a5458Snonaka }
165179a5458Snonaka 
166179a5458Snonaka 
167179a5458Snonaka #ifdef	SUPPORT_BOOTP
168179a5458Snonaka int try_bootp;
169179a5458Snonaka #endif
170179a5458Snonaka 
171179a5458Snonaka static int
net_getparams(int sock)172179a5458Snonaka net_getparams(int sock)
173179a5458Snonaka {
174179a5458Snonaka 	char buf[MAXHOSTNAMELEN];
175179a5458Snonaka 	n_long smask;
176179a5458Snonaka 
177179a5458Snonaka #ifdef	SUPPORT_BOOTP
178179a5458Snonaka 	/*
179179a5458Snonaka 	 * Try to get boot info using BOOTP.  If we succeed, then
180179a5458Snonaka 	 * the server IP address, gateway, and root path will all
181179a5458Snonaka 	 * be initialized.  If any remain uninitialized, we will
182179a5458Snonaka 	 * use RARP and RPC/bootparam (the Sun way) to get them.
183179a5458Snonaka 	 */
184179a5458Snonaka 	if (try_bootp)
185179a5458Snonaka 		bootp(sock);
186179a5458Snonaka 	if (myip.s_addr != 0)
187179a5458Snonaka 		return 0;
188179a5458Snonaka #ifdef NETIF_DEBUG
189179a5458Snonaka 	if (debug)
190179a5458Snonaka 		printf("BOOTP failed, trying RARP/RPC...\n");
191179a5458Snonaka #endif
192179a5458Snonaka #endif
193179a5458Snonaka 
194179a5458Snonaka 	/*
195179a5458Snonaka 	 * Use RARP to get our IP address.  This also sets our
196179a5458Snonaka 	 * netmask to the "natural" default for our address.
197179a5458Snonaka 	 */
198179a5458Snonaka 	if (rarp_getipaddress(sock)) {
199179a5458Snonaka 		printf("RARP failed\n");
200179a5458Snonaka 		return EIO;
201179a5458Snonaka 	}
202179a5458Snonaka #ifdef NETIF_DEBUG
203179a5458Snonaka 	if (debug)
204179a5458Snonaka 		printf("client addr: %s\n", inet_ntoa(myip));
205179a5458Snonaka #endif
206179a5458Snonaka 
207179a5458Snonaka 	/* Get our hostname, server IP address, gateway. */
208179a5458Snonaka 	if (bp_whoami(sock)) {
209179a5458Snonaka 		printf("bootparam/whoami RPC failed\n");
210179a5458Snonaka 		return EIO;
211179a5458Snonaka 	}
212179a5458Snonaka #ifdef NETIF_DEBUG
213179a5458Snonaka 	if (debug)
214179a5458Snonaka 		printf("client name: %s\n", hostname);
215179a5458Snonaka #endif
216179a5458Snonaka 
217179a5458Snonaka 	/*
218179a5458Snonaka 	 * Ignore the gateway from whoami (unreliable).
219179a5458Snonaka 	 * Use the "gateway" parameter instead.
220179a5458Snonaka 	 */
221179a5458Snonaka 	smask = 0;
222179a5458Snonaka 	gateip.s_addr = 0;
223179a5458Snonaka 	if (bp_getfile(sock, "gateway", &gateip, buf)) {
224179a5458Snonaka 		printf("%s: gateway bootparam missing\n", __func__);
225179a5458Snonaka 	} else {
226179a5458Snonaka 		/* Got it!  Parse the netmask. */
227179a5458Snonaka 		smask = inet_addr(buf);
228179a5458Snonaka 	}
229179a5458Snonaka 	if (smask) {
230179a5458Snonaka 		netmask = smask;
231179a5458Snonaka #ifdef NETIF_DEBUG
232179a5458Snonaka 		if (debug)
233179a5458Snonaka 			printf("subnet mask: %s\n", intoa(netmask));
234179a5458Snonaka #endif
235179a5458Snonaka 	}
236179a5458Snonaka #ifdef NETIF_DEBUG
237179a5458Snonaka 	if (debug)
238179a5458Snonaka 		if (gateip.s_addr)
239179a5458Snonaka 			printf("net gateway: %s\n", inet_ntoa(gateip));
240179a5458Snonaka #endif
241179a5458Snonaka 
242179a5458Snonaka 	/* Get the root server and pathname. */
243179a5458Snonaka 	if (bp_getfile(sock, "root", &rootip, rootpath)) {
244179a5458Snonaka 		printf("bootparam/getfile RPC failed\n");
245179a5458Snonaka 		return EIO;
246179a5458Snonaka 	}
247179a5458Snonaka 
248179a5458Snonaka #ifdef NETIF_DEBUG
249179a5458Snonaka 	if (debug) {
250179a5458Snonaka 		printf("server addr: %s\n", inet_ntoa(rootip));
251179a5458Snonaka 		printf("server path: %s\n", rootpath);
252179a5458Snonaka 	}
253179a5458Snonaka #endif
254179a5458Snonaka 
255179a5458Snonaka 	return 0;
256179a5458Snonaka }
257