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