xref: /netbsd-src/sys/arch/sparc/stand/ofwboot/net.c (revision 6adfa96ca4053a8cc5283d65fec1589936e549d1)
1*6adfa96cSmrg /*	$NetBSD: net.c,v 1.10 2021/04/12 03:55:41 mrg Exp $	*/
2e144281cSmrg 
3e144281cSmrg /*
4e144281cSmrg  * Copyright (C) 1995 Wolfgang Solfrank.
5e144281cSmrg  * Copyright (C) 1995 TooLs GmbH.
6e144281cSmrg  * All rights reserved.
7e144281cSmrg  *
8e144281cSmrg  * Redistribution and use in source and binary forms, with or without
9e144281cSmrg  * modification, are permitted provided that the following conditions
10e144281cSmrg  * are met:
11e144281cSmrg  * 1. Redistributions of source code must retain the above copyright
12e144281cSmrg  *    notice, this list of conditions and the following disclaimer.
13e144281cSmrg  * 2. Redistributions in binary form must reproduce the above copyright
14e144281cSmrg  *    notice, this list of conditions and the following disclaimer in the
15e144281cSmrg  *    documentation and/or other materials provided with the distribution.
16e144281cSmrg  * 3. All advertising materials mentioning features or use of this software
17e144281cSmrg  *    must display the following acknowledgement:
18e144281cSmrg  *	This product includes software developed by TooLs GmbH.
19e144281cSmrg  * 4. The name of TooLs GmbH may not be used to endorse or promote products
20e144281cSmrg  *    derived from this software without specific prior written permission.
21e144281cSmrg  *
22e144281cSmrg  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23e144281cSmrg  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24e144281cSmrg  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25e144281cSmrg  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26e144281cSmrg  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27e144281cSmrg  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28e144281cSmrg  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29e144281cSmrg  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30e144281cSmrg  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31e144281cSmrg  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32e144281cSmrg  */
33e144281cSmrg 
34e144281cSmrg /*
35e144281cSmrg  * This module implements a "raw device" interface suitable for
36e144281cSmrg  * use by the stand-alone I/O library NFS code.  This interface
37e144281cSmrg  * does not support any "block" access, and exists only for the
38e144281cSmrg  * purpose of initializing the network interface, getting boot
39e144281cSmrg  * parameters, and performing the NFS mount.
40e144281cSmrg  *
41e144281cSmrg  * At open time, this does:
42e144281cSmrg  *
43e144281cSmrg  * find interface	- netif_open()
44e144281cSmrg  * BOOTP		- bootp()
45e144281cSmrg  * RPC/mountd		- nfs_mount()
46e144281cSmrg  *
47e144281cSmrg  * The root file handle from mountd is saved in a global
48e144281cSmrg  * for use by the NFS open code (NFS/lookup).
49e144281cSmrg  *
50e144281cSmrg  * Note: this is based in part on sys/arch/sparc/stand/net.c
51e144281cSmrg  */
52e144281cSmrg 
53e144281cSmrg #include <sys/param.h>
54e144281cSmrg #include <sys/socket.h>
55e144281cSmrg 
56e144281cSmrg #include <net/if.h>
57e144281cSmrg #include <netinet/in.h>
58e144281cSmrg #include <netinet/in_systm.h>
59e144281cSmrg 
60e144281cSmrg #include <lib/libsa/stand.h>
61e144281cSmrg #include <lib/libsa/net.h>
62e144281cSmrg #include <lib/libsa/netif.h>
63c95f237aStsutsui #include <lib/libsa/bootp.h>
64fa20324cSchristos #include <lib/libsa/bootparam.h>
65fa20324cSchristos #include <lib/libsa/nfs.h>
66e144281cSmrg 
67e144281cSmrg #include <lib/libkern/libkern.h>
68e144281cSmrg 
694c3c91e6Suwe #include "ofdev.h"
70c95f237aStsutsui #include "net.h"
714c3c91e6Suwe 
724c3c91e6Suwe 
734c3c91e6Suwe static int net_mountroot_bootparams(void);
744c3c91e6Suwe static int net_mountroot_bootp(void);
75e144281cSmrg 
76e144281cSmrg static	int netdev_sock = -1;
77e144281cSmrg static	int open_count;
78e144281cSmrg 
79e144281cSmrg /*
80e144281cSmrg  * Called by devopen after it sets f->f_dev to our devsw entry.
81e144281cSmrg  * This opens the low-level device and sets f->f_devdata.
82e144281cSmrg  */
83e144281cSmrg int
net_open(struct of_dev * op)844c3c91e6Suwe net_open(struct of_dev *op)
85e144281cSmrg {
86e144281cSmrg 	int error = 0;
87e144281cSmrg 
88e144281cSmrg 	/*
89e144281cSmrg 	 * On first open, do netif open, mount, etc.
90e144281cSmrg 	 */
91e144281cSmrg 	if (open_count == 0) {
92e144281cSmrg 		/* Find network interface. */
93e144281cSmrg 		if ((netdev_sock = netif_open(op)) < 0) {
94e144281cSmrg 			error = errno;
95e144281cSmrg 			goto bad;
96e144281cSmrg 		}
97e144281cSmrg 	}
98e144281cSmrg 	open_count++;
99e144281cSmrg bad:
100e144281cSmrg 	if (netdev_sock >= 0 && open_count == 0) {
101e144281cSmrg 		netif_close(netdev_sock);
102e144281cSmrg 		netdev_sock = -1;
103e144281cSmrg 	}
104e144281cSmrg 	return error;
105e144281cSmrg }
106e144281cSmrg 
107e144281cSmrg int
net_close(struct of_dev * op)1084c3c91e6Suwe net_close(struct of_dev *op)
109e144281cSmrg {
1104c3c91e6Suwe 
111e144281cSmrg 	/*
112e144281cSmrg 	 * On last close, do netif close, etc.
113e144281cSmrg 	 */
114e144281cSmrg 	if (open_count > 0)
115e144281cSmrg 		if (--open_count == 0) {
116e144281cSmrg 			netif_close(netdev_sock);
117e144281cSmrg 			netdev_sock = -1;
118e144281cSmrg 		}
119c95f237aStsutsui 	return 0;
120e144281cSmrg }
121e144281cSmrg 
122b49ed2c0Sroy static void
net_clear_params(void)123b49ed2c0Sroy net_clear_params(void)
124b49ed2c0Sroy {
125b49ed2c0Sroy 
126b49ed2c0Sroy 	myip.s_addr = 0;
127b49ed2c0Sroy 	netmask = 0;
128b49ed2c0Sroy 	gateip.s_addr = 0;
129b49ed2c0Sroy 	*hostname = '\0';
130b49ed2c0Sroy 	rootip.s_addr = 0;
131b49ed2c0Sroy 	*rootpath = '\0';
132b49ed2c0Sroy }
133b49ed2c0Sroy 
134e144281cSmrg int
net_mountroot_bootparams(void)1354c3c91e6Suwe net_mountroot_bootparams(void)
136e144281cSmrg {
1374c3c91e6Suwe 
138b49ed2c0Sroy 	net_clear_params();
139b49ed2c0Sroy 
140e144281cSmrg 	/* Get our IP address.  (rarp.c) */
141e144281cSmrg 	if (rarp_getipaddress(netdev_sock) == -1)
142e144281cSmrg 		return (errno);
143b49ed2c0Sroy 	printf("Using BOOTPARAMS protocol:\n  ip addr=%s\n", inet_ntoa(myip));
144e144281cSmrg 	if (bp_whoami(netdev_sock))
145e144281cSmrg 		return (errno);
146b49ed2c0Sroy 	printf("  hostname=%s\n", hostname);
147e144281cSmrg 	if (bp_getfile(netdev_sock, "root", &rootip, rootpath))
148e144281cSmrg 		return (errno);
149e144281cSmrg 
150e144281cSmrg 	return (0);
151e144281cSmrg }
152e144281cSmrg 
153e144281cSmrg int
net_mountroot_bootp(void)1544c3c91e6Suwe net_mountroot_bootp(void)
155e144281cSmrg {
156b49ed2c0Sroy 	int attempts;
1574c3c91e6Suwe 
158b49ed2c0Sroy 	/* We need a few attempts here as some DHCP servers
159b49ed2c0Sroy 	 * require >1 packet and my wireless bridge is always
160b49ed2c0Sroy 	 * in learning mode until the 2nd attempt ... */
161b49ed2c0Sroy 	for (attempts = 0; attempts < 3; attempts++) {
162b49ed2c0Sroy 		net_clear_params();
163e144281cSmrg 		bootp(netdev_sock);
164b49ed2c0Sroy 		if (myip.s_addr != 0)
165b49ed2c0Sroy 			break;
166b49ed2c0Sroy 	}
167e144281cSmrg 	if (myip.s_addr == 0)
168e144281cSmrg 		return(ENOENT);
169e144281cSmrg 
170b49ed2c0Sroy 	printf("Using BOOTP protocol:\n ip addr=%s\n", inet_ntoa(myip));
171e144281cSmrg 	if (hostname[0])
172b49ed2c0Sroy 		printf("  hostname=%s\n", hostname);
173e144281cSmrg 	if (netmask)
174b49ed2c0Sroy 		printf("  netmask=%s\n", intoa(netmask));
175e144281cSmrg 	if (gateip.s_addr)
176b49ed2c0Sroy 		printf("  gateway=%s\n", inet_ntoa(gateip));
177e144281cSmrg 
178e144281cSmrg 	return (0);
179e144281cSmrg }
180e144281cSmrg 
1818aa95513Stsutsui /*
1828aa95513Stsutsui  * libsa's tftp_open expects a pointer to netdev_sock, i.e. an (int *),
1838aa95513Stsutsui  * in f_devdata, a pointer to which gets handed down from devopen().
1848aa95513Stsutsui  *
1858aa95513Stsutsui  * Do not expect booting via different methods to have the same
1868aa95513Stsutsui  * requirements or semantics.
1878aa95513Stsutsui  *
1888aa95513Stsutsui  * net_tftp_bootp uses net_mountroot_bootp because that incidentially does
1898aa95513Stsutsui  * most of what it needs to do. It of course in no manner actually mounts
1908aa95513Stsutsui  * anything, all that routine actually does is prepare the socket for the
1918aa95513Stsutsui  * necessary net access, and print info for the user.
1928aa95513Stsutsui  */
1938aa95513Stsutsui 
194e144281cSmrg int
net_tftp_bootp(int ** sock)1958aa95513Stsutsui net_tftp_bootp(int **sock)
19617740d28Smlelstv {
19717740d28Smlelstv 
198b49ed2c0Sroy 	net_mountroot_bootp();
19917740d28Smlelstv 	if (myip.s_addr == 0)
20017740d28Smlelstv 		return(ENOENT);
20117740d28Smlelstv 
2028aa95513Stsutsui 	*sock = &netdev_sock;
20317740d28Smlelstv 	return (0);
20417740d28Smlelstv }
20517740d28Smlelstv 
20617740d28Smlelstv int
net_mountroot(void)2074c3c91e6Suwe net_mountroot(void)
208e144281cSmrg {
209e144281cSmrg 	int error;
210e144281cSmrg 
211e144281cSmrg #ifdef DEBUG
212e144281cSmrg 	printf("net_mountroot\n");
213e144281cSmrg #endif
214e144281cSmrg 
215e144281cSmrg 	/*
216e144281cSmrg 	 * Get info for NFS boot: our IP address, our hostname,
217e144281cSmrg 	 * server IP address, and our root path on the server.
218e144281cSmrg 	 * There are two ways to do this:  The old, Sun way,
219e144281cSmrg 	 * and the more modern, BOOTP way. (RFC951, RFC1048)
220e144281cSmrg 	 */
221e144281cSmrg 
222aaa7dba0Slukem 		/* Try BOOTP first */
223e144281cSmrg 	error = net_mountroot_bootp();
224aaa7dba0Slukem 		/* Historically, we've used BOOTPARAMS, so try that next */
225aaa7dba0Slukem 	if (error != 0)
226aaa7dba0Slukem 		error = net_mountroot_bootparams();
227e144281cSmrg 	if (error != 0)
228e144281cSmrg 		return (error);
229e144281cSmrg 
230b49ed2c0Sroy 	printf("  root addr=%s\n  path=%s\n", inet_ntoa(rootip), rootpath);
231e144281cSmrg 
232e144281cSmrg 	/* Get the NFS file handle (mount). */
233e144281cSmrg 	if (nfs_mount(netdev_sock, rootip, rootpath) != 0)
234e144281cSmrg 		return (errno);
235e144281cSmrg 
236e144281cSmrg 	return (0);
237e144281cSmrg }
238