1 /* $OpenBSD: net.c,v 1.9 2023/06/01 17:24:56 krw Exp $ */
2 /* $NetBSD: net.c,v 1.1 2000/08/20 14:58:38 mrg Exp $ */
3
4 /*
5 * Copyright (C) 1995 Wolfgang Solfrank.
6 * Copyright (C) 1995 TooLs GmbH.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by TooLs GmbH.
20 * 4. The name of TooLs GmbH may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
29 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 /*
36 * This module implements a "raw device" interface suitable for
37 * use by the stand-alone I/O library NFS code. This interface
38 * does not support any "block" access, and exists only for the
39 * purpose of initializing the network interface, getting boot
40 * parameters, and performing the NFS mount.
41 *
42 * At open time, this does:
43 *
44 * find interface - netif_open()
45 * BOOTP - bootp()
46 * RPC/mountd - nfs_mount()
47 *
48 * The root file handle from mountd is saved in a global
49 * for use by the NFS open code (NFS/lookup).
50 *
51 * Note: this is based in part on sys/arch/sparc/stand/net.c
52 */
53
54 #include <sys/param.h>
55 #include <sys/socket.h>
56
57 #include <net/if.h>
58 #include <netinet/in.h>
59
60 #include <lib/libsa/stand.h>
61 #include <lib/libsa/net.h>
62 #include <lib/libsa/netif.h>
63 #include <lib/libsa/bootparam.h>
64 #include <lib/libsa/bootp.h>
65 #include <lib/libsa/nfs.h>
66
67 #include "ofdev.h"
68
69 int net_mountroot_bootparams(void);
70 int net_mountroot_bootp(void);
71 int net_mountroot(void);
72
73 extern char rootpath[FNAME_SIZE];
74
75 static int netdev_sock = -1;
76 static int open_count;
77
78 /*
79 * Called by devopen after it sets f->f_dev to our devsw entry.
80 * This opens the low-level device and sets f->f_devdata.
81 */
82 int
net_open(struct of_dev * op)83 net_open(struct of_dev *op)
84 {
85 int error = 0;
86
87 /*
88 * On first open, do netif open, mount, etc.
89 */
90 if (open_count == 0) {
91 /* Find network interface. */
92 if ((netdev_sock = netif_open(op)) < 0) {
93 error = errno;
94 goto bad;
95 }
96 if ((error = net_mountroot()) != 0)
97 goto bad;
98 }
99 open_count++;
100 bad:
101 if (netdev_sock >= 0 && open_count == 0) {
102 netif_close(netdev_sock);
103 netdev_sock = -1;
104 }
105 return error;
106 }
107
108 void
net_close(struct of_dev * op)109 net_close(struct of_dev *op)
110 {
111 /*
112 * On last close, do netif close, etc.
113 */
114 if (open_count > 0)
115 if (--open_count == 0) {
116 netif_close(netdev_sock);
117 netdev_sock = -1;
118 }
119 }
120
121 int
net_mountroot_bootparams(void)122 net_mountroot_bootparams(void)
123 {
124 /* Get our IP address. (rarp.c) */
125 if (rarp_getipaddress(netdev_sock) == -1)
126 return (errno);
127
128 printf("Using BOOTPARAMS protocol: ");
129 printf("ip address: %s", inet_ntoa(myip));
130
131 /* Get our hostname, server IP address. */
132 if (bp_whoami(netdev_sock))
133 return (errno);
134
135 printf(", hostname: %s\n", hostname);
136
137 /* Get the root pathname. */
138 if (bp_getfile(netdev_sock, "root", &rootip, rootpath))
139 return (errno);
140
141 return (0);
142 }
143
144 int
net_mountroot_bootp(void)145 net_mountroot_bootp(void)
146 {
147 bootp(netdev_sock);
148
149 if (myip.s_addr == 0)
150 return(ENOENT);
151
152 printf("Using BOOTP protocol: ");
153 printf("ip address: %s", inet_ntoa(myip));
154
155 if (hostname[0])
156 printf(", hostname: %s", hostname);
157 if (netmask)
158 printf(", netmask: %s", intoa(netmask));
159 if (gateip.s_addr)
160 printf(", gateway: %s", inet_ntoa(gateip));
161 printf("\n");
162
163 return (0);
164 }
165
166 int
net_mountroot(void)167 net_mountroot(void)
168 {
169 int error;
170
171 #ifdef DEBUG
172 printf("net_mountroot\n");
173 #endif
174
175 /*
176 * Get info for NFS boot: our IP address, our hostname,
177 * server IP address, and our root path on the server.
178 * There are two ways to do this: The old, Sun way,
179 * and the more modern, BOOTP way. (RFC951, RFC1048)
180 */
181
182 /* Historically, we've used BOOTPARAMS, so try that first */
183 error = net_mountroot_bootparams();
184 if (error != 0)
185 /* Next, try BOOTP */
186 error = net_mountroot_bootp();
187 if (error != 0)
188 return (error);
189
190 printf("root addr=%s path=%s\n", inet_ntoa(rootip), rootpath);
191
192 /* Get the NFS file handle (mount). */
193 if (nfs_mount(netdev_sock, rootip, rootpath) != 0)
194 return (errno);
195
196 return (0);
197 }
198