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