1/* $NetBSD: netif.c,v 1.10 1997/09/06 13:57:14 drochner Exp $ */ 2 3/* 4 * Copyright (c) 1993 Adam Glass 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Adam Glass. 18 * 4. The name of the Author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#include <sys/cdefs.h> 35__FBSDID("$FreeBSD$"); 36 37#include <sys/param.h> 38#include <sys/types.h> 39#include <sys/cdefs.h> 40#include <sys/mount.h> 41#include <string.h> 42 43#include <netinet/in.h> 44#include <netinet/in_systm.h> 45 46#include "stand.h" 47#include "net.h" 48#include "netif.h" 49 50struct iodesc sockets[SOPEN_MAX]; 51#ifdef NETIF_DEBUG 52int netif_debug = 0; 53#endif 54 55/* 56 * netif_init: 57 * 58 * initialize the generic network interface layer 59 */ 60 61void 62netif_init() 63{ 64 struct netif_driver *drv; 65 int d, i; 66 67#ifdef NETIF_DEBUG 68 if (netif_debug) 69 printf("netif_init: called\n"); 70#endif 71 for (d = 0; netif_drivers[d]; d++) { 72 drv = netif_drivers[d]; 73 for (i = 0; i < drv->netif_nifs; i++) 74 drv->netif_ifs[i].dif_used = 0; 75 } 76} 77 78int 79netif_match(nif, machdep_hint) 80 struct netif *nif; 81 void *machdep_hint; 82{ 83 struct netif_driver *drv = nif->nif_driver; 84 85#if 0 86 if (netif_debug) 87 printf("%s%d: netif_match (%d)\n", drv->netif_bname, 88 nif->nif_unit, nif->nif_sel); 89#endif 90 return drv->netif_match(nif, machdep_hint); 91} 92 93struct netif * 94netif_select(machdep_hint) 95 void *machdep_hint; 96{ 97 int d, u, unit_done, s; 98 struct netif_driver *drv; 99 struct netif cur_if; 100 static struct netif best_if; 101 int best_val; 102 int val; 103 104 best_val = 0; 105 best_if.nif_driver = NULL; 106 107 for (d = 0; netif_drivers[d] != NULL; d++) { 108 cur_if.nif_driver = netif_drivers[d]; 109 drv = cur_if.nif_driver; 110 111 for (u = 0; u < drv->netif_nifs; u++) { 112 cur_if.nif_unit = u; 113 unit_done = 0; 114 115#ifdef NETIF_DEBUG 116 if (netif_debug) 117 printf("\t%s%d:", drv->netif_bname, 118 cur_if.nif_unit); 119#endif 120 121 for (s = 0; s < drv->netif_ifs[u].dif_nsel; s++) { 122 cur_if.nif_sel = s; 123 124 if (drv->netif_ifs[u].dif_used & (1 << s)) { 125#ifdef NETIF_DEBUG 126 if (netif_debug) 127 printf(" [%d used]", s); 128#endif 129 continue; 130 } 131 132 val = netif_match(&cur_if, machdep_hint); 133#ifdef NETIF_DEBUG 134 if (netif_debug) 135 printf(" [%d -> %d]", s, val); 136#endif 137 if (val > best_val) { 138 best_val = val; 139 best_if = cur_if; 140 } 141 } 142#ifdef NETIF_DEBUG 143 if (netif_debug) 144 printf("\n"); 145#endif 146 } 147 } 148 149 if (best_if.nif_driver == NULL) 150 return NULL; 151 152 best_if.nif_driver-> 153 netif_ifs[best_if.nif_unit].dif_used |= (1 << best_if.nif_sel); 154 155#ifdef NETIF_DEBUG 156 if (netif_debug) 157 printf("netif_select: %s%d(%d) wins\n", 158 best_if.nif_driver->netif_bname, 159 best_if.nif_unit, best_if.nif_sel); 160#endif 161 return &best_if; 162} 163 164int 165netif_probe(nif, machdep_hint) 166 struct netif *nif; 167 void *machdep_hint; 168{ 169 struct netif_driver *drv = nif->nif_driver; 170 171#ifdef NETIF_DEBUG 172 if (netif_debug) 173 printf("%s%d: netif_probe\n", drv->netif_bname, nif->nif_unit); 174#endif 175 return drv->netif_probe(nif, machdep_hint); 176} 177 178void 179netif_attach(nif, desc, machdep_hint) 180 struct netif *nif; 181 struct iodesc *desc; 182 void *machdep_hint; 183{ 184 struct netif_driver *drv = nif->nif_driver; 185 186#ifdef NETIF_DEBUG 187 if (netif_debug) 188 printf("%s%d: netif_attach\n", drv->netif_bname, nif->nif_unit); 189#endif 190 desc->io_netif = nif; 191#ifdef PARANOID 192 if (drv->netif_init == NULL) 193 panic("%s%d: no netif_init support\n", drv->netif_bname, 194 nif->nif_unit); 195#endif 196 drv->netif_init(desc, machdep_hint); 197 bzero(drv->netif_ifs[nif->nif_unit].dif_stats, 198 sizeof(struct netif_stats)); 199} 200 201void 202netif_detach(nif) 203 struct netif *nif; 204{ 205 struct netif_driver *drv = nif->nif_driver; 206 207#ifdef NETIF_DEBUG 208 if (netif_debug) 209 printf("%s%d: netif_detach\n", drv->netif_bname, nif->nif_unit); 210#endif 211#ifdef PARANOID 212 if (drv->netif_end == NULL) 213 panic("%s%d: no netif_end support\n", drv->netif_bname, 214 nif->nif_unit); 215#endif 216 drv->netif_end(nif); 217} 218 219ssize_t 220netif_get(desc, pkt, len, timo) 221 struct iodesc *desc; 222 void *pkt; 223 size_t len; 224 time_t timo; 225{ 226#ifdef NETIF_DEBUG 227 struct netif *nif = desc->io_netif; 228#endif 229 struct netif_driver *drv = desc->io_netif->nif_driver; 230 ssize_t rv; 231 232#ifdef NETIF_DEBUG 233 if (netif_debug) 234 printf("%s%d: netif_get\n", drv->netif_bname, nif->nif_unit); 235#endif 236#ifdef PARANOID 237 if (drv->netif_get == NULL) 238 panic("%s%d: no netif_get support\n", drv->netif_bname, 239 nif->nif_unit); 240#endif 241 rv = drv->netif_get(desc, pkt, len, timo); 242#ifdef NETIF_DEBUG 243 if (netif_debug) 244 printf("%s%d: netif_get returning %d\n", drv->netif_bname, 245 nif->nif_unit, (int)rv); 246#endif 247 return rv; 248} 249 250ssize_t 251netif_put(desc, pkt, len) 252 struct iodesc *desc; 253 void *pkt; 254 size_t len; 255{ 256#ifdef NETIF_DEBUG 257 struct netif *nif = desc->io_netif; 258#endif 259 struct netif_driver *drv = desc->io_netif->nif_driver; 260 ssize_t rv; 261 262#ifdef NETIF_DEBUG 263 if (netif_debug) 264 printf("%s%d: netif_put\n", drv->netif_bname, nif->nif_unit); 265#endif 266#ifdef PARANOID 267 if (drv->netif_put == NULL) 268 panic("%s%d: no netif_put support\n", drv->netif_bname, 269 nif->nif_unit); 270#endif 271 rv = drv->netif_put(desc, pkt, len); 272#ifdef NETIF_DEBUG 273 if (netif_debug) 274 printf("%s%d: netif_put returning %d\n", drv->netif_bname, 275 nif->nif_unit, (int)rv); 276#endif 277 return rv; 278} 279 280struct iodesc * 281socktodesc(sock) 282 int sock; 283{ 284 if (sock >= SOPEN_MAX) { 285 errno = EBADF; 286 return (NULL); 287 } 288 return (&sockets[sock]); 289} 290 291int 292netif_open(machdep_hint) 293 void *machdep_hint; 294{ 295 int fd; 296 struct iodesc *s; 297 struct netif *nif; 298 299 /* find a free socket */ 300 for (fd = 0, s = sockets; fd < SOPEN_MAX; fd++, s++) 301 if (s->io_netif == (struct netif *)0) 302 goto fnd; 303 errno = EMFILE; 304 return (-1); 305 306fnd: 307 bzero(s, sizeof(*s)); 308 netif_init(); 309 nif = netif_select(machdep_hint); 310 if (!nif) 311 panic("netboot: no interfaces left untried"); 312 if (netif_probe(nif, machdep_hint)) { 313 printf("netboot: couldn't probe %s%d\n", 314 nif->nif_driver->netif_bname, nif->nif_unit); 315 errno = EINVAL; 316 return(-1); 317 } 318 netif_attach(nif, s, machdep_hint); 319 320 return(fd); 321} 322 323int 324netif_close(sock) 325 int sock; 326{ 327 if (sock >= SOPEN_MAX) { 328 errno = EBADF; 329 return(-1); 330 } 331 netif_detach(sockets[sock].io_netif); 332 sockets[sock].io_netif = (struct netif *)0; 333 334 return(0); 335} 336