138451Smsmith/* $NetBSD: netif.c,v 1.10 1997/09/06 13:57:14 drochner Exp $ */ 238451Smsmith 338451Smsmith/* 438451Smsmith * Copyright (c) 1993 Adam Glass 538451Smsmith * All rights reserved. 638451Smsmith * 738451Smsmith * Redistribution and use in source and binary forms, with or without 838451Smsmith * modification, are permitted provided that the following conditions 938451Smsmith * are met: 1038451Smsmith * 1. Redistributions of source code must retain the above copyright 1138451Smsmith * notice, this list of conditions and the following disclaimer. 1238451Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1338451Smsmith * notice, this list of conditions and the following disclaimer in the 1438451Smsmith * documentation and/or other materials provided with the distribution. 1538451Smsmith * 3. All advertising materials mentioning features or use of this software 1638451Smsmith * must display the following acknowledgement: 1738451Smsmith * This product includes software developed by Adam Glass. 1838451Smsmith * 4. The name of the Author may not be used to endorse or promote products 1938451Smsmith * derived from this software without specific prior written permission. 2038451Smsmith * 2138451Smsmith * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND 2238451Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2338451Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2438451Smsmith * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2538451Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2638451Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2738451Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2838451Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2938451Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3038451Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3138451Smsmith * SUCH DAMAGE. 3238451Smsmith */ 3338451Smsmith 3484221Sdillon#include <sys/cdefs.h> 3584221Sdillon__FBSDID("$FreeBSD$"); 3684221Sdillon 3738451Smsmith#include <sys/param.h> 3838451Smsmith#include <sys/types.h> 3938451Smsmith#include <sys/cdefs.h> 4038451Smsmith#include <sys/mount.h> 4138451Smsmith#include <string.h> 4238451Smsmith 4338451Smsmith#include <netinet/in.h> 4438451Smsmith#include <netinet/in_systm.h> 4538451Smsmith 4638451Smsmith#include "stand.h" 4738451Smsmith#include "net.h" 4838451Smsmith#include "netif.h" 4938451Smsmith 5038451Smsmithstruct iodesc sockets[SOPEN_MAX]; 5138451Smsmith#ifdef NETIF_DEBUG 5238451Smsmithint netif_debug = 0; 5338451Smsmith#endif 5438451Smsmith 5538451Smsmith/* 5638451Smsmith * netif_init: 5738451Smsmith * 5838451Smsmith * initialize the generic network interface layer 5938451Smsmith */ 6038451Smsmith 6138451Smsmithvoid 6238451Smsmithnetif_init() 6338451Smsmith{ 6438451Smsmith struct netif_driver *drv; 6538451Smsmith int d, i; 6638451Smsmith 6738451Smsmith#ifdef NETIF_DEBUG 6838451Smsmith if (netif_debug) 6938451Smsmith printf("netif_init: called\n"); 7038451Smsmith#endif 7138451Smsmith for (d = 0; netif_drivers[d]; d++) { 7238451Smsmith drv = netif_drivers[d]; 7338451Smsmith for (i = 0; i < drv->netif_nifs; i++) 7438451Smsmith drv->netif_ifs[i].dif_used = 0; 7538451Smsmith } 7638451Smsmith} 7738451Smsmith 7838451Smsmithint 7938451Smsmithnetif_match(nif, machdep_hint) 8038451Smsmith struct netif *nif; 8138451Smsmith void *machdep_hint; 8238451Smsmith{ 8338451Smsmith struct netif_driver *drv = nif->nif_driver; 8438451Smsmith 8538451Smsmith#if 0 8638451Smsmith if (netif_debug) 8738451Smsmith printf("%s%d: netif_match (%d)\n", drv->netif_bname, 8838451Smsmith nif->nif_unit, nif->nif_sel); 8938451Smsmith#endif 9038451Smsmith return drv->netif_match(nif, machdep_hint); 9138451Smsmith} 9238451Smsmith 9338451Smsmithstruct netif * 9438451Smsmithnetif_select(machdep_hint) 9538451Smsmith void *machdep_hint; 9638451Smsmith{ 9738451Smsmith int d, u, unit_done, s; 9838451Smsmith struct netif_driver *drv; 9938451Smsmith struct netif cur_if; 10038451Smsmith static struct netif best_if; 10138451Smsmith int best_val; 10238451Smsmith int val; 10338451Smsmith 10438451Smsmith best_val = 0; 10538451Smsmith best_if.nif_driver = NULL; 10638451Smsmith 10738451Smsmith for (d = 0; netif_drivers[d] != NULL; d++) { 10838451Smsmith cur_if.nif_driver = netif_drivers[d]; 10938451Smsmith drv = cur_if.nif_driver; 11038451Smsmith 11138451Smsmith for (u = 0; u < drv->netif_nifs; u++) { 11238451Smsmith cur_if.nif_unit = u; 11338451Smsmith unit_done = 0; 11438451Smsmith 11538451Smsmith#ifdef NETIF_DEBUG 11638451Smsmith if (netif_debug) 11738451Smsmith printf("\t%s%d:", drv->netif_bname, 11838451Smsmith cur_if.nif_unit); 11938451Smsmith#endif 12038451Smsmith 12138451Smsmith for (s = 0; s < drv->netif_ifs[u].dif_nsel; s++) { 12238451Smsmith cur_if.nif_sel = s; 12338451Smsmith 12438451Smsmith if (drv->netif_ifs[u].dif_used & (1 << s)) { 12538451Smsmith#ifdef NETIF_DEBUG 12638451Smsmith if (netif_debug) 12738451Smsmith printf(" [%d used]", s); 12838451Smsmith#endif 12938451Smsmith continue; 13038451Smsmith } 13138451Smsmith 13238451Smsmith val = netif_match(&cur_if, machdep_hint); 13338451Smsmith#ifdef NETIF_DEBUG 13438451Smsmith if (netif_debug) 13538451Smsmith printf(" [%d -> %d]", s, val); 13638451Smsmith#endif 13738451Smsmith if (val > best_val) { 13838451Smsmith best_val = val; 13938451Smsmith best_if = cur_if; 14038451Smsmith } 14138451Smsmith } 14238451Smsmith#ifdef NETIF_DEBUG 14338451Smsmith if (netif_debug) 14438451Smsmith printf("\n"); 14538451Smsmith#endif 14638451Smsmith } 14738451Smsmith } 14838451Smsmith 14938451Smsmith if (best_if.nif_driver == NULL) 15038451Smsmith return NULL; 15138451Smsmith 15238451Smsmith best_if.nif_driver-> 15338451Smsmith netif_ifs[best_if.nif_unit].dif_used |= (1 << best_if.nif_sel); 15438451Smsmith 15538451Smsmith#ifdef NETIF_DEBUG 15638451Smsmith if (netif_debug) 15738451Smsmith printf("netif_select: %s%d(%d) wins\n", 15838451Smsmith best_if.nif_driver->netif_bname, 15938451Smsmith best_if.nif_unit, best_if.nif_sel); 16038451Smsmith#endif 16138451Smsmith return &best_if; 16238451Smsmith} 16338451Smsmith 16438451Smsmithint 16538451Smsmithnetif_probe(nif, machdep_hint) 16638451Smsmith struct netif *nif; 16738451Smsmith void *machdep_hint; 16838451Smsmith{ 16938451Smsmith struct netif_driver *drv = nif->nif_driver; 17038451Smsmith 17138451Smsmith#ifdef NETIF_DEBUG 17238451Smsmith if (netif_debug) 17338451Smsmith printf("%s%d: netif_probe\n", drv->netif_bname, nif->nif_unit); 17438451Smsmith#endif 17538451Smsmith return drv->netif_probe(nif, machdep_hint); 17638451Smsmith} 17738451Smsmith 17838451Smsmithvoid 17938451Smsmithnetif_attach(nif, desc, machdep_hint) 18038451Smsmith struct netif *nif; 18138451Smsmith struct iodesc *desc; 18238451Smsmith void *machdep_hint; 18338451Smsmith{ 18438451Smsmith struct netif_driver *drv = nif->nif_driver; 18538451Smsmith 18638451Smsmith#ifdef NETIF_DEBUG 18738451Smsmith if (netif_debug) 18838451Smsmith printf("%s%d: netif_attach\n", drv->netif_bname, nif->nif_unit); 18938451Smsmith#endif 19038451Smsmith desc->io_netif = nif; 19138451Smsmith#ifdef PARANOID 19238451Smsmith if (drv->netif_init == NULL) 19338451Smsmith panic("%s%d: no netif_init support\n", drv->netif_bname, 19438451Smsmith nif->nif_unit); 19538451Smsmith#endif 19638451Smsmith drv->netif_init(desc, machdep_hint); 19738451Smsmith bzero(drv->netif_ifs[nif->nif_unit].dif_stats, 19838451Smsmith sizeof(struct netif_stats)); 19938451Smsmith} 20038451Smsmith 20138451Smsmithvoid 20238451Smsmithnetif_detach(nif) 20338451Smsmith struct netif *nif; 20438451Smsmith{ 20538451Smsmith struct netif_driver *drv = nif->nif_driver; 20638451Smsmith 20738451Smsmith#ifdef NETIF_DEBUG 20838451Smsmith if (netif_debug) 20938451Smsmith printf("%s%d: netif_detach\n", drv->netif_bname, nif->nif_unit); 21038451Smsmith#endif 21138451Smsmith#ifdef PARANOID 21238451Smsmith if (drv->netif_end == NULL) 21338451Smsmith panic("%s%d: no netif_end support\n", drv->netif_bname, 21438451Smsmith nif->nif_unit); 21538451Smsmith#endif 21638451Smsmith drv->netif_end(nif); 21738451Smsmith} 21838451Smsmith 21938451Smsmithssize_t 22038451Smsmithnetif_get(desc, pkt, len, timo) 22138451Smsmith struct iodesc *desc; 22238451Smsmith void *pkt; 22338451Smsmith size_t len; 22438451Smsmith time_t timo; 22538451Smsmith{ 22638451Smsmith#ifdef NETIF_DEBUG 22738451Smsmith struct netif *nif = desc->io_netif; 22838451Smsmith#endif 22938451Smsmith struct netif_driver *drv = desc->io_netif->nif_driver; 23038451Smsmith ssize_t rv; 23138451Smsmith 23238451Smsmith#ifdef NETIF_DEBUG 23338451Smsmith if (netif_debug) 23438451Smsmith printf("%s%d: netif_get\n", drv->netif_bname, nif->nif_unit); 23538451Smsmith#endif 23638451Smsmith#ifdef PARANOID 23738451Smsmith if (drv->netif_get == NULL) 23838451Smsmith panic("%s%d: no netif_get support\n", drv->netif_bname, 23938451Smsmith nif->nif_unit); 24038451Smsmith#endif 24138451Smsmith rv = drv->netif_get(desc, pkt, len, timo); 24238451Smsmith#ifdef NETIF_DEBUG 24338451Smsmith if (netif_debug) 24438451Smsmith printf("%s%d: netif_get returning %d\n", drv->netif_bname, 24538451Smsmith nif->nif_unit, (int)rv); 24638451Smsmith#endif 24738451Smsmith return rv; 24838451Smsmith} 24938451Smsmith 25038451Smsmithssize_t 25138451Smsmithnetif_put(desc, pkt, len) 25238451Smsmith struct iodesc *desc; 25338451Smsmith void *pkt; 25438451Smsmith size_t len; 25538451Smsmith{ 25638451Smsmith#ifdef NETIF_DEBUG 25738451Smsmith struct netif *nif = desc->io_netif; 25838451Smsmith#endif 25938451Smsmith struct netif_driver *drv = desc->io_netif->nif_driver; 26038451Smsmith ssize_t rv; 26138451Smsmith 26238451Smsmith#ifdef NETIF_DEBUG 26338451Smsmith if (netif_debug) 26438451Smsmith printf("%s%d: netif_put\n", drv->netif_bname, nif->nif_unit); 26538451Smsmith#endif 26638451Smsmith#ifdef PARANOID 26738451Smsmith if (drv->netif_put == NULL) 26838451Smsmith panic("%s%d: no netif_put support\n", drv->netif_bname, 26938451Smsmith nif->nif_unit); 27038451Smsmith#endif 27138451Smsmith rv = drv->netif_put(desc, pkt, len); 27238451Smsmith#ifdef NETIF_DEBUG 27338451Smsmith if (netif_debug) 27438451Smsmith printf("%s%d: netif_put returning %d\n", drv->netif_bname, 27538451Smsmith nif->nif_unit, (int)rv); 27638451Smsmith#endif 27738451Smsmith return rv; 27838451Smsmith} 27938451Smsmith 28038451Smsmithstruct iodesc * 28138451Smsmithsocktodesc(sock) 28238451Smsmith int sock; 28338451Smsmith{ 28438451Smsmith if (sock >= SOPEN_MAX) { 28538451Smsmith errno = EBADF; 28638451Smsmith return (NULL); 28738451Smsmith } 28838451Smsmith return (&sockets[sock]); 28938451Smsmith} 29038451Smsmith 29138451Smsmithint 29238451Smsmithnetif_open(machdep_hint) 29338451Smsmith void *machdep_hint; 29438451Smsmith{ 29538451Smsmith int fd; 29692913Sobrien struct iodesc *s; 29738451Smsmith struct netif *nif; 29838451Smsmith 29938451Smsmith /* find a free socket */ 30038451Smsmith for (fd = 0, s = sockets; fd < SOPEN_MAX; fd++, s++) 30138451Smsmith if (s->io_netif == (struct netif *)0) 30238451Smsmith goto fnd; 30338451Smsmith errno = EMFILE; 30438451Smsmith return (-1); 30538451Smsmith 30638451Smsmithfnd: 30738451Smsmith bzero(s, sizeof(*s)); 30838451Smsmith netif_init(); 30938451Smsmith nif = netif_select(machdep_hint); 31038451Smsmith if (!nif) 31138451Smsmith panic("netboot: no interfaces left untried"); 31238451Smsmith if (netif_probe(nif, machdep_hint)) { 31338451Smsmith printf("netboot: couldn't probe %s%d\n", 31438451Smsmith nif->nif_driver->netif_bname, nif->nif_unit); 31538451Smsmith errno = EINVAL; 31638451Smsmith return(-1); 31738451Smsmith } 31838451Smsmith netif_attach(nif, s, machdep_hint); 31938451Smsmith 32038451Smsmith return(fd); 32138451Smsmith} 32238451Smsmith 32338451Smsmithint 32438451Smsmithnetif_close(sock) 32538451Smsmith int sock; 32638451Smsmith{ 32738451Smsmith if (sock >= SOPEN_MAX) { 32838451Smsmith errno = EBADF; 32938451Smsmith return(-1); 33038451Smsmith } 33138451Smsmith netif_detach(sockets[sock].io_netif); 33238451Smsmith sockets[sock].io_netif = (struct netif *)0; 33338451Smsmith 33438451Smsmith return(0); 33538451Smsmith} 336