netif.c revision 38451
1269257Sdes/* $NetBSD: netif.c,v 1.10 1997/09/06 13:57:14 drochner Exp $ */ 2269257Sdes 3269257Sdes/* 4269257Sdes * Copyright (c) 1993 Adam Glass 5269257Sdes * All rights reserved. 6269257Sdes * 7269257Sdes * Redistribution and use in source and binary forms, with or without 8269257Sdes * modification, are permitted provided that the following conditions 9269257Sdes * are met: 10269257Sdes * 1. Redistributions of source code must retain the above copyright 11269257Sdes * notice, this list of conditions and the following disclaimer. 12269257Sdes * 2. Redistributions in binary form must reproduce the above copyright 13269257Sdes * notice, this list of conditions and the following disclaimer in the 14269257Sdes * documentation and/or other materials provided with the distribution. 15269257Sdes * 3. All advertising materials mentioning features or use of this software 16269257Sdes * must display the following acknowledgement: 17269257Sdes * This product includes software developed by Adam Glass. 18269257Sdes * 4. The name of the Author may not be used to endorse or promote products 19269257Sdes * derived from this software without specific prior written permission. 20269257Sdes * 21269257Sdes * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND 22269257Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23269257Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24269257Sdes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25269257Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26269257Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27269257Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28269257Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29269257Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30269257Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31269257Sdes * SUCH DAMAGE. 32269257Sdes */ 33269257Sdes 34269257Sdes#include <sys/param.h> 35238104Sdes#include <sys/types.h> 36269257Sdes#include <sys/cdefs.h> 37238104Sdes#include <sys/mount.h> 38269257Sdes#include <string.h> 39269257Sdes 40269257Sdes#include <netinet/in.h> 41269257Sdes#include <netinet/in_systm.h> 42269257Sdes 43269257Sdes#include "stand.h" 44269257Sdes#include "net.h" 45238104Sdes#include "netif.h" 46269257Sdes 47269257Sdesstruct iodesc sockets[SOPEN_MAX]; 48269257Sdes#ifdef NETIF_DEBUG 49269257Sdesint netif_debug = 0; 50269257Sdes#endif 51269257Sdes 52238104Sdes/* 53269257Sdes * netif_init: 54269257Sdes * 55238104Sdes * initialize the generic network interface layer 56269257Sdes */ 57269257Sdes 58269257Sdesvoid 59269257Sdesnetif_init() 60238104Sdes{ 61269257Sdes struct netif_driver *drv; 62269257Sdes int d, i; 63269257Sdes 64269257Sdes#ifdef NETIF_DEBUG 65269257Sdes if (netif_debug) 66269257Sdes printf("netif_init: called\n"); 67269257Sdes#endif 68269257Sdes for (d = 0; netif_drivers[d]; d++) { 69269257Sdes drv = netif_drivers[d]; 70269257Sdes for (i = 0; i < drv->netif_nifs; i++) 71269257Sdes drv->netif_ifs[i].dif_used = 0; 72269257Sdes } 73269257Sdes} 74269257Sdes 75238104Sdesint 76269257Sdesnetif_match(nif, machdep_hint) 77269257Sdes struct netif *nif; 78269257Sdes void *machdep_hint; 79269257Sdes{ 80269257Sdes struct netif_driver *drv = nif->nif_driver; 81269257Sdes 82269257Sdes#if 0 83269257Sdes if (netif_debug) 84269257Sdes printf("%s%d: netif_match (%d)\n", drv->netif_bname, 85269257Sdes nif->nif_unit, nif->nif_sel); 86269257Sdes#endif 87269257Sdes return drv->netif_match(nif, machdep_hint); 88238104Sdes} 89269257Sdes 90269257Sdesstruct netif * 91269257Sdesnetif_select(machdep_hint) 92269257Sdes void *machdep_hint; 93269257Sdes{ 94269257Sdes int d, u, unit_done, s; 95269257Sdes struct netif_driver *drv; 96269257Sdes struct netif cur_if; 97269257Sdes static struct netif best_if; 98269257Sdes int best_val; 99269257Sdes int val; 100269257Sdes 101238104Sdes best_val = 0; 102269257Sdes best_if.nif_driver = NULL; 103269257Sdes 104269257Sdes for (d = 0; netif_drivers[d] != NULL; d++) { 105269257Sdes cur_if.nif_driver = netif_drivers[d]; 106269257Sdes drv = cur_if.nif_driver; 107269257Sdes 108269257Sdes for (u = 0; u < drv->netif_nifs; u++) { 109269257Sdes cur_if.nif_unit = u; 110269257Sdes unit_done = 0; 111269257Sdes 112269257Sdes#ifdef NETIF_DEBUG 113269257Sdes if (netif_debug) 114269257Sdes printf("\t%s%d:", drv->netif_bname, 115269257Sdes cur_if.nif_unit); 116269257Sdes#endif 117269257Sdes 118269257Sdes for (s = 0; s < drv->netif_ifs[u].dif_nsel; s++) { 119238104Sdes cur_if.nif_sel = s; 120269257Sdes 121269257Sdes if (drv->netif_ifs[u].dif_used & (1 << s)) { 122269257Sdes#ifdef NETIF_DEBUG 123269257Sdes if (netif_debug) 124269257Sdes printf(" [%d used]", s); 125269257Sdes#endif 126269257Sdes continue; 127269257Sdes } 128269257Sdes 129269257Sdes val = netif_match(&cur_if, machdep_hint); 130269257Sdes#ifdef NETIF_DEBUG 131269257Sdes if (netif_debug) 132269257Sdes printf(" [%d -> %d]", s, val); 133269257Sdes#endif 134269257Sdes if (val > best_val) { 135269257Sdes best_val = val; 136238104Sdes best_if = cur_if; 137269257Sdes } 138269257Sdes } 139269257Sdes#ifdef NETIF_DEBUG 140269257Sdes if (netif_debug) 141269257Sdes printf("\n"); 142269257Sdes#endif 143269257Sdes } 144269257Sdes } 145269257Sdes 146269257Sdes if (best_if.nif_driver == NULL) 147269257Sdes return NULL; 148269257Sdes 149269257Sdes best_if.nif_driver-> 150269257Sdes netif_ifs[best_if.nif_unit].dif_used |= (1 << best_if.nif_sel); 151269257Sdes 152269257Sdes#ifdef NETIF_DEBUG 153238104Sdes if (netif_debug) 154269257Sdes printf("netif_select: %s%d(%d) wins\n", 155269257Sdes best_if.nif_driver->netif_bname, 156269257Sdes best_if.nif_unit, best_if.nif_sel); 157238104Sdes#endif 158269257Sdes return &best_if; 159269257Sdes} 160269257Sdes 161269257Sdesint 162269257Sdesnetif_probe(nif, machdep_hint) 163269257Sdes struct netif *nif; 164269257Sdes void *machdep_hint; 165269257Sdes{ 166269257Sdes struct netif_driver *drv = nif->nif_driver; 167269257Sdes 168269257Sdes#ifdef NETIF_DEBUG 169269257Sdes if (netif_debug) 170238104Sdes printf("%s%d: netif_probe\n", drv->netif_bname, nif->nif_unit); 171238104Sdes#endif 172269257Sdes return drv->netif_probe(nif, machdep_hint); 173269257Sdes} 174269257Sdes 175238104Sdesvoid 176269257Sdesnetif_attach(nif, desc, machdep_hint) 177269257Sdes struct netif *nif; 178269257Sdes struct iodesc *desc; 179269257Sdes void *machdep_hint; 180269257Sdes{ 181269257Sdes struct netif_driver *drv = nif->nif_driver; 182269257Sdes 183269257Sdes#ifdef NETIF_DEBUG 184269257Sdes if (netif_debug) 185269257Sdes printf("%s%d: netif_attach\n", drv->netif_bname, nif->nif_unit); 186269257Sdes#endif 187269257Sdes desc->io_netif = nif; 188238104Sdes#ifdef PARANOID 189238104Sdes if (drv->netif_init == NULL) 190269257Sdes panic("%s%d: no netif_init support\n", drv->netif_bname, 191269257Sdes nif->nif_unit); 192269257Sdes#endif 193269257Sdes drv->netif_init(desc, machdep_hint); 194269257Sdes bzero(drv->netif_ifs[nif->nif_unit].dif_stats, 195269257Sdes sizeof(struct netif_stats)); 196269257Sdes} 197269257Sdes 198269257Sdesvoid 199269257Sdesnetif_detach(nif) 200269257Sdes struct netif *nif; 201269257Sdes{ 202269257Sdes struct netif_driver *drv = nif->nif_driver; 203269257Sdes 204269257Sdes#ifdef NETIF_DEBUG 205269257Sdes if (netif_debug) 206269257Sdes printf("%s%d: netif_detach\n", drv->netif_bname, nif->nif_unit); 207238104Sdes#endif 208269257Sdes#ifdef PARANOID 209269257Sdes if (drv->netif_end == NULL) 210269257Sdes panic("%s%d: no netif_end support\n", drv->netif_bname, 211269257Sdes nif->nif_unit); 212269257Sdes#endif 213269257Sdes drv->netif_end(nif); 214269257Sdes} 215269257Sdes 216269257Sdesssize_t 217269257Sdesnetif_get(desc, pkt, len, timo) 218269257Sdes struct iodesc *desc; 219269257Sdes void *pkt; 220269257Sdes size_t len; 221238104Sdes time_t timo; 222269257Sdes{ 223269257Sdes#ifdef NETIF_DEBUG 224269257Sdes struct netif *nif = desc->io_netif; 225269257Sdes#endif 226269257Sdes struct netif_driver *drv = desc->io_netif->nif_driver; 227269257Sdes ssize_t rv; 228269257Sdes 229269257Sdes#ifdef NETIF_DEBUG 230269257Sdes if (netif_debug) 231269257Sdes printf("%s%d: netif_get\n", drv->netif_bname, nif->nif_unit); 232269257Sdes#endif 233269257Sdes#ifdef PARANOID 234269257Sdes if (drv->netif_get == NULL) 235238104Sdes panic("%s%d: no netif_get support\n", drv->netif_bname, 236269257Sdes nif->nif_unit); 237269257Sdes#endif 238269257Sdes rv = drv->netif_get(desc, pkt, len, timo); 239269257Sdes#ifdef NETIF_DEBUG 240269257Sdes if (netif_debug) 241269257Sdes printf("%s%d: netif_get returning %d\n", drv->netif_bname, 242269257Sdes nif->nif_unit, (int)rv); 243269257Sdes#endif 244269257Sdes return rv; 245269257Sdes} 246269257Sdes 247269257Sdesssize_t 248269257Sdesnetif_put(desc, pkt, len) 249269257Sdes struct iodesc *desc; 250269257Sdes void *pkt; 251238104Sdes size_t len; 252269257Sdes{ 253269257Sdes#ifdef NETIF_DEBUG 254238104Sdes struct netif *nif = desc->io_netif; 255269257Sdes#endif 256269257Sdes struct netif_driver *drv = desc->io_netif->nif_driver; 257269257Sdes ssize_t rv; 258269257Sdes 259269257Sdes#ifdef NETIF_DEBUG 260269257Sdes if (netif_debug) 261269257Sdes printf("%s%d: netif_put\n", drv->netif_bname, nif->nif_unit); 262269257Sdes#endif 263269257Sdes#ifdef PARANOID 264269257Sdes if (drv->netif_put == NULL) 265269257Sdes panic("%s%d: no netif_put support\n", drv->netif_bname, 266269257Sdes nif->nif_unit); 267269257Sdes#endif 268269257Sdes rv = drv->netif_put(desc, pkt, len); 269269257Sdes#ifdef NETIF_DEBUG 270269257Sdes if (netif_debug) 271269257Sdes printf("%s%d: netif_put returning %d\n", drv->netif_bname, 272269257Sdes nif->nif_unit, (int)rv); 273269257Sdes#endif 274269257Sdes return rv; 275269257Sdes} 276269257Sdes 277269257Sdesstruct iodesc * 278269257Sdessocktodesc(sock) 279269257Sdes int sock; 280269257Sdes{ 281269257Sdes if (sock >= SOPEN_MAX) { 282269257Sdes errno = EBADF; 283269257Sdes return (NULL); 284269257Sdes } 285269257Sdes return (&sockets[sock]); 286269257Sdes} 287269257Sdes 288269257Sdesint 289269257Sdesnetif_open(machdep_hint) 290269257Sdes void *machdep_hint; 291269257Sdes{ 292269257Sdes int fd; 293269257Sdes register struct iodesc *s; 294269257Sdes struct netif *nif; 295269257Sdes 296269257Sdes /* find a free socket */ 297269257Sdes for (fd = 0, s = sockets; fd < SOPEN_MAX; fd++, s++) 298238104Sdes if (s->io_netif == (struct netif *)0) 299269257Sdes goto fnd; 300269257Sdes errno = EMFILE; 301269257Sdes return (-1); 302269257Sdes 303269257Sdesfnd: 304269257Sdes bzero(s, sizeof(*s)); 305269257Sdes netif_init(); 306269257Sdes nif = netif_select(machdep_hint); 307238104Sdes if (!nif) 308269257Sdes panic("netboot: no interfaces left untried"); 309269257Sdes if (netif_probe(nif, machdep_hint)) { 310269257Sdes printf("netboot: couldn't probe %s%d\n", 311269257Sdes nif->nif_driver->netif_bname, nif->nif_unit); 312269257Sdes errno = EINVAL; 313269257Sdes return(-1); 314269257Sdes } 315269257Sdes netif_attach(nif, s, machdep_hint); 316269257Sdes 317269257Sdes return(fd); 318269257Sdes} 319269257Sdes 320269257Sdesint 321269257Sdesnetif_close(sock) 322238104Sdes int sock; 323269257Sdes{ 324269257Sdes if (sock >= SOPEN_MAX) { 325269257Sdes errno = EBADF; 326269257Sdes return(-1); 327269257Sdes } 328269257Sdes netif_detach(sockets[sock].io_netif); 329269257Sdes sockets[sock].io_netif = (struct netif *)0; 330269257Sdes 331269257Sdes return(0); 332269257Sdes} 333269257Sdes