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