xref: /titanic_52/usr/src/boot/lib/libstand/netif.c (revision 7b2a1233f92b2b3cb858f2fdb69378a9ab0a42f1)
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