dev_net.c revision 1.3 1 1.3 nonaka /* $NetBSD: dev_net.c,v 1.3 2019/09/26 12:21:03 nonaka Exp $ */
2 1.1 nonaka
3 1.2 nonaka /*-
4 1.2 nonaka * Copyright (c) 1997 The NetBSD Foundation, Inc.
5 1.2 nonaka * All rights reserved.
6 1.2 nonaka *
7 1.2 nonaka * This code is derived from software contributed to The NetBSD Foundation
8 1.2 nonaka * by Gordon W. Ross.
9 1.2 nonaka *
10 1.2 nonaka * Redistribution and use in source and binary forms, with or without
11 1.2 nonaka * modification, are permitted provided that the following conditions
12 1.2 nonaka * are met:
13 1.2 nonaka * 1. Redistributions of source code must retain the above copyright
14 1.2 nonaka * notice, this list of conditions and the following disclaimer.
15 1.2 nonaka * 2. Redistributions in binary form must reproduce the above copyright
16 1.2 nonaka * notice, this list of conditions and the following disclaimer in the
17 1.2 nonaka * documentation and/or other materials provided with the distribution.
18 1.2 nonaka *
19 1.2 nonaka * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.2 nonaka * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.2 nonaka * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.2 nonaka * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.2 nonaka * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.2 nonaka * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.2 nonaka * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.2 nonaka * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.2 nonaka * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.2 nonaka * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.2 nonaka * POSSIBILITY OF SUCH DAMAGE.
30 1.2 nonaka */
31 1.2 nonaka
32 1.2 nonaka /*
33 1.2 nonaka * This module implements a "raw device" interface suitable for
34 1.2 nonaka * use by the stand-alone I/O library NFS code. This interface
35 1.2 nonaka * does not support any "block" access, and exists only for the
36 1.2 nonaka * purpose of initializing the network interface, getting boot
37 1.2 nonaka * parameters, and performing the NFS mount.
38 1.2 nonaka *
39 1.2 nonaka * At open time, this does:
40 1.2 nonaka *
41 1.2 nonaka * find interface - netif_open()
42 1.2 nonaka * RARP for IP address - rarp_getipaddress()
43 1.2 nonaka * RPC/bootparams - callrpc(d, RPC_BOOTPARAMS, ...)
44 1.2 nonaka * RPC/mountd - nfs_mount(sock, ip, path)
45 1.2 nonaka */
46 1.2 nonaka
47 1.2 nonaka #include <sys/param.h>
48 1.2 nonaka #include <sys/socket.h>
49 1.2 nonaka #include <net/if.h>
50 1.2 nonaka #include <netinet/in.h>
51 1.2 nonaka #include <netinet/in_systm.h>
52 1.2 nonaka
53 1.2 nonaka #include <lib/libkern/libkern.h>
54 1.2 nonaka
55 1.2 nonaka #include "stand.h"
56 1.2 nonaka #include "net.h"
57 1.2 nonaka #include "netif.h"
58 1.2 nonaka #include "nfs.h"
59 1.2 nonaka #include "bootparam.h"
60 1.2 nonaka #include "dev_net.h"
61 1.2 nonaka #ifdef SUPPORT_BOOTP
62 1.2 nonaka #include "bootp.h"
63 1.2 nonaka #endif
64 1.2 nonaka
65 1.2 nonaka static int netdev_sock = -1;
66 1.2 nonaka static int netdev_opens;
67 1.2 nonaka
68 1.2 nonaka static int net_getparams(int);
69 1.2 nonaka
70 1.2 nonaka /*
71 1.2 nonaka * Called by devopen after it sets f->f_dev to our devsw entry.
72 1.2 nonaka * This opens the low-level device and sets f->f_devdata.
73 1.2 nonaka * This is declared with variable arguments...
74 1.2 nonaka */
75 1.2 nonaka int
76 1.2 nonaka net_open(struct open_file *f, ...)
77 1.2 nonaka {
78 1.2 nonaka va_list ap;
79 1.3 nonaka struct devdesc *dev;
80 1.2 nonaka int error = 0;
81 1.2 nonaka
82 1.2 nonaka va_start(ap, f);
83 1.3 nonaka dev = va_arg(ap, struct devdesc *);
84 1.2 nonaka va_end(ap);
85 1.2 nonaka
86 1.2 nonaka #ifdef NETIF_DEBUG
87 1.2 nonaka if (debug)
88 1.3 nonaka printf("%s\n", dev->devname);
89 1.2 nonaka #endif
90 1.2 nonaka
91 1.2 nonaka /* On first open, do netif open, mount, etc. */
92 1.2 nonaka if (netdev_opens == 0) {
93 1.2 nonaka /* Find network interface. */
94 1.2 nonaka if (netdev_sock < 0) {
95 1.3 nonaka netdev_sock = netif_open(dev);
96 1.2 nonaka if (netdev_sock < 0) {
97 1.2 nonaka printf("netif_open() failed\n");
98 1.2 nonaka return ENXIO;
99 1.2 nonaka }
100 1.2 nonaka #ifdef NETIF_DEBUG
101 1.2 nonaka if (debug)
102 1.2 nonaka printf("netif_open() succeeded\n");
103 1.2 nonaka #endif
104 1.2 nonaka }
105 1.2 nonaka if (rootip.s_addr == 0) {
106 1.2 nonaka /* Get root IP address, and path, etc. */
107 1.2 nonaka error = net_getparams(netdev_sock);
108 1.2 nonaka if (error) {
109 1.2 nonaka /* getparams makes its own noise */
110 1.2 nonaka netif_close(netdev_sock);
111 1.2 nonaka netdev_sock = -1;
112 1.2 nonaka return error;
113 1.2 nonaka }
114 1.2 nonaka }
115 1.2 nonaka }
116 1.2 nonaka netdev_opens++;
117 1.2 nonaka f->f_devdata = &netdev_sock;
118 1.2 nonaka return error;
119 1.2 nonaka }
120 1.2 nonaka
121 1.2 nonaka int
122 1.2 nonaka net_close(struct open_file *f)
123 1.2 nonaka {
124 1.2 nonaka
125 1.2 nonaka #ifdef NETIF_DEBUG
126 1.2 nonaka if (debug)
127 1.2 nonaka printf("net_close: opens=%d\n", netdev_opens);
128 1.2 nonaka #endif
129 1.2 nonaka
130 1.2 nonaka /* On last close, do netif close, etc. */
131 1.2 nonaka f->f_devdata = NULL;
132 1.2 nonaka /* Extra close call? */
133 1.2 nonaka if (netdev_opens <= 0)
134 1.2 nonaka return 0;
135 1.2 nonaka netdev_opens--;
136 1.2 nonaka /* Not last close? */
137 1.2 nonaka if (netdev_opens > 0)
138 1.2 nonaka return 0;
139 1.2 nonaka rootip.s_addr = 0;
140 1.2 nonaka if (netdev_sock >= 0) {
141 1.2 nonaka #ifdef NETIF_DEBUG
142 1.2 nonaka if (debug)
143 1.2 nonaka printf("%s: calling netif_close()\n", __func__);
144 1.2 nonaka #endif
145 1.2 nonaka netif_close(netdev_sock);
146 1.2 nonaka netdev_sock = -1;
147 1.2 nonaka }
148 1.2 nonaka return 0;
149 1.2 nonaka }
150 1.2 nonaka
151 1.2 nonaka int
152 1.2 nonaka net_ioctl(struct open_file *f, u_long cmd, void *data)
153 1.2 nonaka {
154 1.2 nonaka
155 1.2 nonaka return EIO;
156 1.2 nonaka }
157 1.2 nonaka
158 1.2 nonaka int
159 1.2 nonaka net_strategy(void *devdata, int rw, daddr_t blk, size_t size, void *buf,
160 1.2 nonaka size_t *rsize)
161 1.2 nonaka {
162 1.2 nonaka
163 1.2 nonaka return EIO;
164 1.2 nonaka }
165 1.2 nonaka
166 1.2 nonaka
167 1.2 nonaka #ifdef SUPPORT_BOOTP
168 1.2 nonaka int try_bootp;
169 1.2 nonaka #endif
170 1.2 nonaka
171 1.2 nonaka static int
172 1.2 nonaka net_getparams(int sock)
173 1.2 nonaka {
174 1.2 nonaka char buf[MAXHOSTNAMELEN];
175 1.2 nonaka n_long smask;
176 1.2 nonaka
177 1.2 nonaka #ifdef SUPPORT_BOOTP
178 1.2 nonaka /*
179 1.2 nonaka * Try to get boot info using BOOTP. If we succeed, then
180 1.2 nonaka * the server IP address, gateway, and root path will all
181 1.2 nonaka * be initialized. If any remain uninitialized, we will
182 1.2 nonaka * use RARP and RPC/bootparam (the Sun way) to get them.
183 1.2 nonaka */
184 1.2 nonaka if (try_bootp)
185 1.2 nonaka bootp(sock);
186 1.2 nonaka if (myip.s_addr != 0)
187 1.2 nonaka return 0;
188 1.2 nonaka #ifdef NETIF_DEBUG
189 1.2 nonaka if (debug)
190 1.2 nonaka printf("BOOTP failed, trying RARP/RPC...\n");
191 1.2 nonaka #endif
192 1.2 nonaka #endif
193 1.2 nonaka
194 1.2 nonaka /*
195 1.2 nonaka * Use RARP to get our IP address. This also sets our
196 1.2 nonaka * netmask to the "natural" default for our address.
197 1.2 nonaka */
198 1.2 nonaka if (rarp_getipaddress(sock)) {
199 1.2 nonaka printf("RARP failed\n");
200 1.2 nonaka return EIO;
201 1.2 nonaka }
202 1.2 nonaka #ifdef NETIF_DEBUG
203 1.2 nonaka if (debug)
204 1.2 nonaka printf("client addr: %s\n", inet_ntoa(myip));
205 1.2 nonaka #endif
206 1.2 nonaka
207 1.2 nonaka /* Get our hostname, server IP address, gateway. */
208 1.2 nonaka if (bp_whoami(sock)) {
209 1.2 nonaka printf("bootparam/whoami RPC failed\n");
210 1.2 nonaka return EIO;
211 1.2 nonaka }
212 1.2 nonaka #ifdef NETIF_DEBUG
213 1.2 nonaka if (debug)
214 1.2 nonaka printf("client name: %s\n", hostname);
215 1.2 nonaka #endif
216 1.2 nonaka
217 1.2 nonaka /*
218 1.2 nonaka * Ignore the gateway from whoami (unreliable).
219 1.2 nonaka * Use the "gateway" parameter instead.
220 1.2 nonaka */
221 1.2 nonaka smask = 0;
222 1.2 nonaka gateip.s_addr = 0;
223 1.2 nonaka if (bp_getfile(sock, "gateway", &gateip, buf)) {
224 1.2 nonaka printf("%s: gateway bootparam missing\n", __func__);
225 1.2 nonaka } else {
226 1.2 nonaka /* Got it! Parse the netmask. */
227 1.2 nonaka smask = inet_addr(buf);
228 1.2 nonaka }
229 1.2 nonaka if (smask) {
230 1.2 nonaka netmask = smask;
231 1.2 nonaka #ifdef NETIF_DEBUG
232 1.2 nonaka if (debug)
233 1.2 nonaka printf("subnet mask: %s\n", intoa(netmask));
234 1.2 nonaka #endif
235 1.2 nonaka }
236 1.2 nonaka #ifdef NETIF_DEBUG
237 1.2 nonaka if (debug)
238 1.2 nonaka if (gateip.s_addr)
239 1.2 nonaka printf("net gateway: %s\n", inet_ntoa(gateip));
240 1.2 nonaka #endif
241 1.2 nonaka
242 1.2 nonaka /* Get the root server and pathname. */
243 1.2 nonaka if (bp_getfile(sock, "root", &rootip, rootpath)) {
244 1.2 nonaka printf("bootparam/getfile RPC failed\n");
245 1.2 nonaka return EIO;
246 1.2 nonaka }
247 1.2 nonaka
248 1.2 nonaka #ifdef NETIF_DEBUG
249 1.2 nonaka if (debug) {
250 1.2 nonaka printf("server addr: %s\n", inet_ntoa(rootip));
251 1.2 nonaka printf("server path: %s\n", rootpath);
252 1.2 nonaka }
253 1.2 nonaka #endif
254 1.2 nonaka
255 1.2 nonaka return 0;
256 1.2 nonaka }
257