1 /* $OpenBSD: pxe_net.c,v 1.5 2014/08/21 14:24:08 mpi Exp $ */ 2 /* $NetBSD: dev_net.c,v 1.4 2003/03/12 13:15:08 drochner Exp $ */ 3 4 /*- 5 * Copyright (c) 1997 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Gordon W. Ross. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * This module implements a "raw device" interface suitable for 35 * use by the stand-alone I/O library NFS and TFTP code. This interface 36 * does not support any "block" access, and exists only for the 37 * purpose of initializing the network interface and getting boot 38 * parameters. 39 * 40 * At open time, this does: 41 * 42 * find interface - netif_open() 43 * BOOTP for IP address - bootp() 44 */ 45 46 #include <sys/param.h> 47 #include <sys/socket.h> 48 #include <net/if.h> 49 #include <netinet/in.h> 50 51 #include <lib/libkern/libkern.h> 52 53 #include <lib/libsa/stand.h> 54 #include <lib/libsa/net.h> 55 #include "pxe_netif.h" 56 #include "pxe_net.h" 57 58 static int netdev_sock = -1; 59 static int netdev_opens; 60 61 int net_getparams(int); 62 63 /* 64 * Called by devopen after it sets f->f_dev to our devsw entry. 65 * This opens the low-level device and sets f->f_devdata. 66 * This is declared with variable arguments... 67 */ 68 int 69 net_open(struct open_file *f, ...) 70 { 71 int error = 0; 72 73 #ifdef NETIF_DEBUG 74 if (debug) 75 printf("net_open()\n"); 76 #endif 77 78 /* On first open, do netif open, mount, etc. */ 79 if (netdev_opens == 0) { 80 /* Find network interface. */ 81 if (netdev_sock < 0) { 82 netdev_sock = pxe_netif_open(); 83 if (netdev_sock < 0) { 84 printf("net_open: netif_open() failed\n"); 85 return ENXIO; 86 } 87 #ifdef NETIF_DEBUG 88 if (debug) 89 printf("net_open: netif_open() succeeded\n"); 90 #endif 91 } 92 #ifdef notyet 93 if (rootip.s_addr == 0) { 94 /* Get root IP address, and path, etc. */ 95 error = net_getparams(netdev_sock); 96 if (error) { 97 /* getparams makes its own noise */ 98 pxe_netif_close(netdev_sock); 99 netdev_sock = -1; 100 return error; 101 } 102 } 103 #endif 104 } 105 netdev_opens++; 106 f->f_devdata = &netdev_sock; 107 return error; 108 } 109 110 int 111 net_close(struct open_file *f) 112 { 113 #ifdef NETIF_DEBUG 114 if (debug) 115 printf("net_close: opens=%d\n", netdev_opens); 116 #endif 117 118 /* On last close, do netif close, etc. */ 119 f->f_devdata = NULL; 120 /* Extra close call? */ 121 if (netdev_opens <= 0) 122 return 0; 123 netdev_opens--; 124 /* Not last close? */ 125 if (netdev_opens > 0) 126 return 0; 127 rootip.s_addr = 0; 128 if (netdev_sock >= 0) { 129 #ifdef NETIF_DEBUG 130 if (debug) 131 printf("net_close: calling netif_close()\n"); 132 #endif 133 pxe_netif_close(netdev_sock); 134 netdev_sock = -1; 135 } 136 return 0; 137 } 138 139 int 140 net_ioctl(struct open_file *f, u_long cmd, void *data) 141 { 142 return EIO; 143 } 144 145 int 146 net_strategy(void *devdata, int rw, daddr32_t blk, size_t size, void *buf, 147 size_t *rsize) 148 { 149 return EIO; 150 } 151 152 153 /* 154 * Get info for network boot: our IP address, our hostname, 155 * server IP address, and our root path on the server. 156 */ 157 extern int bootp(int); 158 159 int 160 net_getparams(int sock) 161 { 162 /* 163 * Try to get boot info using BOOTP. If we succeed, then 164 * the server IP address, gateway, and root path will all 165 * be initialized. If any remain uninitialized, we will 166 * use RARP and RPC/bootparam (the Sun way) to get them. 167 */ 168 bootp(sock); 169 if (myip.s_addr != 0) 170 return 0; 171 if (debug) 172 printf("net_getparams: BOOTP failed\n"); 173 174 return EIO; 175 } 176