14a5d661aSToomas Soome /* $NetBSD: netif.c,v 1.10 1997/09/06 13:57:14 drochner Exp $ */ 24a5d661aSToomas Soome 34a5d661aSToomas Soome /* 44a5d661aSToomas Soome * Copyright (c) 1993 Adam Glass 54a5d661aSToomas Soome * All rights reserved. 64a5d661aSToomas Soome * 74a5d661aSToomas Soome * Redistribution and use in source and binary forms, with or without 84a5d661aSToomas Soome * modification, are permitted provided that the following conditions 94a5d661aSToomas Soome * are met: 104a5d661aSToomas Soome * 1. Redistributions of source code must retain the above copyright 114a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer. 124a5d661aSToomas Soome * 2. Redistributions in binary form must reproduce the above copyright 134a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer in the 144a5d661aSToomas Soome * documentation and/or other materials provided with the distribution. 154a5d661aSToomas Soome * 3. All advertising materials mentioning features or use of this software 164a5d661aSToomas Soome * must display the following acknowledgement: 174a5d661aSToomas Soome * This product includes software developed by Adam Glass. 184a5d661aSToomas Soome * 4. The name of the Author may not be used to endorse or promote products 194a5d661aSToomas Soome * derived from this software without specific prior written permission. 204a5d661aSToomas Soome * 214a5d661aSToomas Soome * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND 224a5d661aSToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 234a5d661aSToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 244a5d661aSToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 254a5d661aSToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 264a5d661aSToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 274a5d661aSToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 284a5d661aSToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 294a5d661aSToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 304a5d661aSToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 314a5d661aSToomas Soome * SUCH DAMAGE. 324a5d661aSToomas Soome */ 334a5d661aSToomas Soome 344a5d661aSToomas Soome #include <sys/cdefs.h> 354a5d661aSToomas Soome 364a5d661aSToomas Soome #include <sys/param.h> 374a5d661aSToomas Soome #include <sys/types.h> 384a5d661aSToomas Soome #include <sys/cdefs.h> 394a5d661aSToomas Soome #include <sys/mount.h> 404a5d661aSToomas Soome #include <string.h> 414a5d661aSToomas Soome 424a5d661aSToomas Soome #include <netinet/in.h> 434a5d661aSToomas Soome #include <netinet/in_systm.h> 444a5d661aSToomas Soome 454a5d661aSToomas Soome #include "stand.h" 464a5d661aSToomas Soome #include "net.h" 474a5d661aSToomas Soome #include "netif.h" 484a5d661aSToomas Soome 494a5d661aSToomas Soome struct iodesc sockets[SOPEN_MAX]; 504a5d661aSToomas Soome #ifdef NETIF_DEBUG 514a5d661aSToomas Soome int netif_debug = 0; 524a5d661aSToomas Soome #endif 534a5d661aSToomas Soome 544a5d661aSToomas Soome /* 554a5d661aSToomas Soome * netif_init: 564a5d661aSToomas Soome * 574a5d661aSToomas Soome * initialize the generic network interface layer 584a5d661aSToomas Soome */ 594a5d661aSToomas Soome 604a5d661aSToomas Soome void 61*7b2a1233SToomas Soome netif_init(void) 624a5d661aSToomas Soome { 634a5d661aSToomas Soome struct netif_driver *drv; 644a5d661aSToomas Soome int d, i; 654a5d661aSToomas Soome 664a5d661aSToomas Soome #ifdef NETIF_DEBUG 674a5d661aSToomas Soome if (netif_debug) 684a5d661aSToomas Soome printf("netif_init: called\n"); 694a5d661aSToomas Soome #endif 704a5d661aSToomas Soome for (d = 0; netif_drivers[d]; d++) { 714a5d661aSToomas Soome drv = netif_drivers[d]; 724a5d661aSToomas Soome for (i = 0; i < drv->netif_nifs; i++) 734a5d661aSToomas Soome drv->netif_ifs[i].dif_used = 0; 744a5d661aSToomas Soome } 754a5d661aSToomas Soome } 764a5d661aSToomas Soome 774a5d661aSToomas Soome int 78*7b2a1233SToomas Soome netif_match(struct netif *nif, void *machdep_hint) 794a5d661aSToomas Soome { 804a5d661aSToomas Soome struct netif_driver *drv = nif->nif_driver; 814a5d661aSToomas Soome 82*7b2a1233SToomas Soome #if NETIF_DEBUG 834a5d661aSToomas Soome if (netif_debug) 844a5d661aSToomas Soome printf("%s%d: netif_match (%d)\n", drv->netif_bname, 854a5d661aSToomas Soome nif->nif_unit, nif->nif_sel); 864a5d661aSToomas Soome #endif 874a5d661aSToomas Soome return drv->netif_match(nif, machdep_hint); 884a5d661aSToomas Soome } 894a5d661aSToomas Soome 904a5d661aSToomas Soome struct netif * 91*7b2a1233SToomas Soome netif_select(void *machdep_hint) 924a5d661aSToomas Soome { 934a5d661aSToomas Soome int d, u, unit_done, s; 944a5d661aSToomas Soome struct netif_driver *drv; 954a5d661aSToomas Soome struct netif cur_if; 964a5d661aSToomas Soome static struct netif best_if; 974a5d661aSToomas Soome int best_val; 984a5d661aSToomas Soome int val; 994a5d661aSToomas Soome 1004a5d661aSToomas Soome best_val = 0; 1014a5d661aSToomas Soome best_if.nif_driver = NULL; 1024a5d661aSToomas Soome 1034a5d661aSToomas Soome for (d = 0; netif_drivers[d] != NULL; d++) { 1044a5d661aSToomas Soome cur_if.nif_driver = netif_drivers[d]; 1054a5d661aSToomas Soome drv = cur_if.nif_driver; 1064a5d661aSToomas Soome 1074a5d661aSToomas Soome for (u = 0; u < drv->netif_nifs; u++) { 1084a5d661aSToomas Soome cur_if.nif_unit = u; 1094a5d661aSToomas Soome unit_done = 0; 1104a5d661aSToomas Soome 1114a5d661aSToomas Soome #ifdef NETIF_DEBUG 1124a5d661aSToomas Soome if (netif_debug) 1134a5d661aSToomas Soome printf("\t%s%d:", drv->netif_bname, 1144a5d661aSToomas Soome cur_if.nif_unit); 1154a5d661aSToomas Soome #endif 1164a5d661aSToomas Soome 1174a5d661aSToomas Soome for (s = 0; s < drv->netif_ifs[u].dif_nsel; s++) { 1184a5d661aSToomas Soome cur_if.nif_sel = s; 1194a5d661aSToomas Soome 1204a5d661aSToomas Soome if (drv->netif_ifs[u].dif_used & (1 << s)) { 1214a5d661aSToomas Soome #ifdef NETIF_DEBUG 1224a5d661aSToomas Soome if (netif_debug) 1234a5d661aSToomas Soome printf(" [%d used]", s); 1244a5d661aSToomas Soome #endif 1254a5d661aSToomas Soome continue; 1264a5d661aSToomas Soome } 1274a5d661aSToomas Soome 1284a5d661aSToomas Soome val = netif_match(&cur_if, machdep_hint); 1294a5d661aSToomas Soome #ifdef NETIF_DEBUG 1304a5d661aSToomas Soome if (netif_debug) 1314a5d661aSToomas Soome printf(" [%d -> %d]", s, val); 1324a5d661aSToomas Soome #endif 1334a5d661aSToomas Soome if (val > best_val) { 1344a5d661aSToomas Soome best_val = val; 1354a5d661aSToomas Soome best_if = cur_if; 1364a5d661aSToomas Soome } 1374a5d661aSToomas Soome } 1384a5d661aSToomas Soome #ifdef NETIF_DEBUG 1394a5d661aSToomas Soome if (netif_debug) 1404a5d661aSToomas Soome printf("\n"); 1414a5d661aSToomas Soome #endif 1424a5d661aSToomas Soome } 1434a5d661aSToomas Soome } 1444a5d661aSToomas Soome 1454a5d661aSToomas Soome if (best_if.nif_driver == NULL) 1464a5d661aSToomas Soome return NULL; 1474a5d661aSToomas Soome 1484a5d661aSToomas Soome best_if.nif_driver-> 1494a5d661aSToomas Soome netif_ifs[best_if.nif_unit].dif_used |= (1 << best_if.nif_sel); 1504a5d661aSToomas Soome 1514a5d661aSToomas Soome #ifdef NETIF_DEBUG 1524a5d661aSToomas Soome if (netif_debug) 1534a5d661aSToomas Soome printf("netif_select: %s%d(%d) wins\n", 1544a5d661aSToomas Soome best_if.nif_driver->netif_bname, 1554a5d661aSToomas Soome best_if.nif_unit, best_if.nif_sel); 1564a5d661aSToomas Soome #endif 1574a5d661aSToomas Soome return &best_if; 1584a5d661aSToomas Soome } 1594a5d661aSToomas Soome 1604a5d661aSToomas Soome int 161*7b2a1233SToomas Soome netif_probe(struct netif *nif, void *machdep_hint) 1624a5d661aSToomas Soome { 1634a5d661aSToomas Soome struct netif_driver *drv = nif->nif_driver; 1644a5d661aSToomas Soome 1654a5d661aSToomas Soome #ifdef NETIF_DEBUG 1664a5d661aSToomas Soome if (netif_debug) 1674a5d661aSToomas Soome printf("%s%d: netif_probe\n", drv->netif_bname, nif->nif_unit); 1684a5d661aSToomas Soome #endif 1694a5d661aSToomas Soome return drv->netif_probe(nif, machdep_hint); 1704a5d661aSToomas Soome } 1714a5d661aSToomas Soome 1724a5d661aSToomas Soome void 173*7b2a1233SToomas Soome netif_attach(struct netif *nif, struct iodesc *desc, void *machdep_hint) 1744a5d661aSToomas Soome { 1754a5d661aSToomas Soome struct netif_driver *drv = nif->nif_driver; 1764a5d661aSToomas Soome 1774a5d661aSToomas Soome #ifdef NETIF_DEBUG 1784a5d661aSToomas Soome if (netif_debug) 1794a5d661aSToomas Soome printf("%s%d: netif_attach\n", drv->netif_bname, nif->nif_unit); 1804a5d661aSToomas Soome #endif 1814a5d661aSToomas Soome desc->io_netif = nif; 1824a5d661aSToomas Soome #ifdef PARANOID 1834a5d661aSToomas Soome if (drv->netif_init == NULL) 1844a5d661aSToomas Soome panic("%s%d: no netif_init support\n", drv->netif_bname, 1854a5d661aSToomas Soome nif->nif_unit); 1864a5d661aSToomas Soome #endif 1874a5d661aSToomas Soome drv->netif_init(desc, machdep_hint); 1884a5d661aSToomas Soome bzero(drv->netif_ifs[nif->nif_unit].dif_stats, 1894a5d661aSToomas Soome sizeof(struct netif_stats)); 1904a5d661aSToomas Soome } 1914a5d661aSToomas Soome 1924a5d661aSToomas Soome void 193*7b2a1233SToomas Soome netif_detach(struct netif *nif) 1944a5d661aSToomas Soome { 1954a5d661aSToomas Soome struct netif_driver *drv = nif->nif_driver; 1964a5d661aSToomas Soome 1974a5d661aSToomas Soome #ifdef NETIF_DEBUG 1984a5d661aSToomas Soome if (netif_debug) 1994a5d661aSToomas Soome printf("%s%d: netif_detach\n", drv->netif_bname, nif->nif_unit); 2004a5d661aSToomas Soome #endif 2014a5d661aSToomas Soome #ifdef PARANOID 2024a5d661aSToomas Soome if (drv->netif_end == NULL) 2034a5d661aSToomas Soome panic("%s%d: no netif_end support\n", drv->netif_bname, 2044a5d661aSToomas Soome nif->nif_unit); 2054a5d661aSToomas Soome #endif 2064a5d661aSToomas Soome drv->netif_end(nif); 2074a5d661aSToomas Soome } 2084a5d661aSToomas Soome 2094a5d661aSToomas Soome ssize_t 210*7b2a1233SToomas Soome netif_get(struct iodesc *desc, void **pkt, time_t timo) 2114a5d661aSToomas Soome { 2124a5d661aSToomas Soome #ifdef NETIF_DEBUG 2134a5d661aSToomas Soome struct netif *nif = desc->io_netif; 2144a5d661aSToomas Soome #endif 2154a5d661aSToomas Soome struct netif_driver *drv = desc->io_netif->nif_driver; 2164a5d661aSToomas Soome ssize_t rv; 2174a5d661aSToomas Soome 2184a5d661aSToomas Soome #ifdef NETIF_DEBUG 2194a5d661aSToomas Soome if (netif_debug) 2204a5d661aSToomas Soome printf("%s%d: netif_get\n", drv->netif_bname, nif->nif_unit); 2214a5d661aSToomas Soome #endif 2224a5d661aSToomas Soome #ifdef PARANOID 2234a5d661aSToomas Soome if (drv->netif_get == NULL) 2244a5d661aSToomas Soome panic("%s%d: no netif_get support\n", drv->netif_bname, 2254a5d661aSToomas Soome nif->nif_unit); 2264a5d661aSToomas Soome #endif 227*7b2a1233SToomas Soome rv = drv->netif_get(desc, pkt, timo); 2284a5d661aSToomas Soome #ifdef NETIF_DEBUG 2294a5d661aSToomas Soome if (netif_debug) 2304a5d661aSToomas Soome printf("%s%d: netif_get returning %d\n", drv->netif_bname, 2314a5d661aSToomas Soome nif->nif_unit, (int)rv); 2324a5d661aSToomas Soome #endif 233*7b2a1233SToomas Soome return (rv); 2344a5d661aSToomas Soome } 2354a5d661aSToomas Soome 2364a5d661aSToomas Soome ssize_t 237*7b2a1233SToomas Soome netif_put(struct iodesc *desc, void *pkt, size_t len) 2384a5d661aSToomas Soome { 2394a5d661aSToomas Soome #ifdef NETIF_DEBUG 2404a5d661aSToomas Soome struct netif *nif = desc->io_netif; 2414a5d661aSToomas Soome #endif 2424a5d661aSToomas Soome struct netif_driver *drv = desc->io_netif->nif_driver; 2434a5d661aSToomas Soome ssize_t rv; 2444a5d661aSToomas Soome 2454a5d661aSToomas Soome #ifdef NETIF_DEBUG 2464a5d661aSToomas Soome if (netif_debug) 2474a5d661aSToomas Soome printf("%s%d: netif_put\n", drv->netif_bname, nif->nif_unit); 2484a5d661aSToomas Soome #endif 2494a5d661aSToomas Soome #ifdef PARANOID 2504a5d661aSToomas Soome if (drv->netif_put == NULL) 2514a5d661aSToomas Soome panic("%s%d: no netif_put support\n", drv->netif_bname, 2524a5d661aSToomas Soome nif->nif_unit); 2534a5d661aSToomas Soome #endif 2544a5d661aSToomas Soome rv = drv->netif_put(desc, pkt, len); 2554a5d661aSToomas Soome #ifdef NETIF_DEBUG 2564a5d661aSToomas Soome if (netif_debug) 2574a5d661aSToomas Soome printf("%s%d: netif_put returning %d\n", drv->netif_bname, 2584a5d661aSToomas Soome nif->nif_unit, (int)rv); 2594a5d661aSToomas Soome #endif 260*7b2a1233SToomas Soome return (rv); 2614a5d661aSToomas Soome } 2624a5d661aSToomas Soome 2634a5d661aSToomas Soome struct iodesc * 264*7b2a1233SToomas Soome socktodesc(int sock) 2654a5d661aSToomas Soome { 2664a5d661aSToomas Soome if (sock >= SOPEN_MAX) { 2674a5d661aSToomas Soome errno = EBADF; 2684a5d661aSToomas Soome return (NULL); 2694a5d661aSToomas Soome } 2704a5d661aSToomas Soome return (&sockets[sock]); 2714a5d661aSToomas Soome } 2724a5d661aSToomas Soome 2734a5d661aSToomas Soome int 274*7b2a1233SToomas Soome netif_open(void *machdep_hint) 2754a5d661aSToomas Soome { 2764a5d661aSToomas Soome int fd; 2774a5d661aSToomas Soome struct iodesc *s; 2784a5d661aSToomas Soome struct netif *nif; 2794a5d661aSToomas Soome 2804a5d661aSToomas Soome /* find a free socket */ 2814a5d661aSToomas Soome for (fd = 0, s = sockets; fd < SOPEN_MAX; fd++, s++) 2824a5d661aSToomas Soome if (s->io_netif == (struct netif *)0) 2834a5d661aSToomas Soome goto fnd; 2844a5d661aSToomas Soome errno = EMFILE; 2854a5d661aSToomas Soome return (-1); 2864a5d661aSToomas Soome 2874a5d661aSToomas Soome fnd: 2884a5d661aSToomas Soome bzero(s, sizeof(*s)); 2894a5d661aSToomas Soome netif_init(); 2904a5d661aSToomas Soome nif = netif_select(machdep_hint); 2914a5d661aSToomas Soome if (!nif) 2924a5d661aSToomas Soome panic("netboot: no interfaces left untried"); 2934a5d661aSToomas Soome if (netif_probe(nif, machdep_hint)) { 2944a5d661aSToomas Soome printf("netboot: couldn't probe %s%d\n", 2954a5d661aSToomas Soome nif->nif_driver->netif_bname, nif->nif_unit); 2964a5d661aSToomas Soome errno = EINVAL; 2974a5d661aSToomas Soome return (-1); 2984a5d661aSToomas Soome } 2994a5d661aSToomas Soome netif_attach(nif, s, machdep_hint); 3004a5d661aSToomas Soome 3014a5d661aSToomas Soome return (fd); 3024a5d661aSToomas Soome } 3034a5d661aSToomas Soome 3044a5d661aSToomas Soome int 305*7b2a1233SToomas Soome netif_close(int sock) 3064a5d661aSToomas Soome { 3074a5d661aSToomas Soome if (sock >= SOPEN_MAX) { 3084a5d661aSToomas Soome errno = EBADF; 3094a5d661aSToomas Soome return (-1); 3104a5d661aSToomas Soome } 3114a5d661aSToomas Soome netif_detach(sockets[sock].io_netif); 3124a5d661aSToomas Soome sockets[sock].io_netif = (struct netif *)0; 3134a5d661aSToomas Soome 3144a5d661aSToomas Soome return (0); 3154a5d661aSToomas Soome } 316