diff options
Diffstat (limited to 'lib/libstand/netif.c')
| -rw-r--r-- | lib/libstand/netif.c | 335 | 
1 files changed, 335 insertions, 0 deletions
diff --git a/lib/libstand/netif.c b/lib/libstand/netif.c new file mode 100644 index 000000000000..baae9a91f8f8 --- /dev/null +++ b/lib/libstand/netif.c @@ -0,0 +1,335 @@ +/*	$NetBSD: netif.c,v 1.10 1997/09/06 13:57:14 drochner Exp $	*/ + +/* + * Copyright (c) 1993 Adam Glass + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *	This product includes software developed by Adam Glass. + * 4. The name of the Author may not be used to endorse or promote products + *    derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/cdefs.h> +#include <sys/mount.h> +#include <string.h> + +#include <netinet/in.h> +#include <netinet/in_systm.h> + +#include "stand.h" +#include "net.h" +#include "netif.h" + +struct iodesc sockets[SOPEN_MAX]; +#ifdef NETIF_DEBUG +int netif_debug = 0; +#endif + +/* + * netif_init: + * + * initialize the generic network interface layer + */ + +void +netif_init() +{ +	struct netif_driver *drv; +	int d, i; +     +#ifdef NETIF_DEBUG +	if (netif_debug) +		printf("netif_init: called\n"); +#endif +	for (d = 0; netif_drivers[d]; d++) { +		drv = netif_drivers[d]; +		for (i = 0; i < drv->netif_nifs; i++) +			drv->netif_ifs[i].dif_used = 0; +	} +} + +int +netif_match(nif, machdep_hint) +	struct netif *nif; +	void *machdep_hint; +{ +	struct netif_driver *drv = nif->nif_driver; + +#if 0 +	if (netif_debug) +		printf("%s%d: netif_match (%d)\n", drv->netif_bname, +		    nif->nif_unit, nif->nif_sel); +#endif +	return drv->netif_match(nif, machdep_hint); +} + +struct netif * +netif_select(machdep_hint) +	void *machdep_hint; +{ +	int d, u, unit_done, s; +	struct netif_driver *drv; +	struct netif cur_if; +	static struct netif best_if; +	int best_val; +	int val; + +	best_val = 0; +	best_if.nif_driver = NULL; + +	for (d = 0; netif_drivers[d] != NULL; d++) { +		cur_if.nif_driver = netif_drivers[d]; +		drv = cur_if.nif_driver; + +		for (u = 0; u < drv->netif_nifs; u++) { +			cur_if.nif_unit = u; +			unit_done = 0; +		 +#ifdef NETIF_DEBUG +			if (netif_debug) +				printf("\t%s%d:", drv->netif_bname, +				    cur_if.nif_unit); +#endif + +			for (s = 0; s < drv->netif_ifs[u].dif_nsel; s++) { +				cur_if.nif_sel = s; + +				if (drv->netif_ifs[u].dif_used & (1 << s)) { +#ifdef NETIF_DEBUG +					if (netif_debug) +						printf(" [%d used]", s); +#endif +					continue; +				} + +				val = netif_match(&cur_if, machdep_hint); +#ifdef NETIF_DEBUG +				if (netif_debug) +					printf(" [%d -> %d]", s, val); +#endif +				if (val > best_val) { +					best_val = val; +					best_if = cur_if; +				} +			} +#ifdef NETIF_DEBUG +			if (netif_debug) +				printf("\n"); +#endif +		} +	} + +	if (best_if.nif_driver == NULL) +		return NULL; + +	best_if.nif_driver-> +	    netif_ifs[best_if.nif_unit].dif_used |= (1 << best_if.nif_sel); + +#ifdef NETIF_DEBUG +	if (netif_debug) +		printf("netif_select: %s%d(%d) wins\n", +			best_if.nif_driver->netif_bname, +			best_if.nif_unit, best_if.nif_sel); +#endif +	return &best_if; +} + +int +netif_probe(nif, machdep_hint) +	struct netif *nif; +	void *machdep_hint; +{ +	struct netif_driver *drv = nif->nif_driver; + +#ifdef NETIF_DEBUG +	if (netif_debug) +		printf("%s%d: netif_probe\n", drv->netif_bname, nif->nif_unit); +#endif +	return drv->netif_probe(nif, machdep_hint); +} + +void +netif_attach(nif, desc, machdep_hint) +	struct netif *nif; +	struct iodesc *desc; +	void *machdep_hint; +{ +	struct netif_driver *drv = nif->nif_driver; + +#ifdef NETIF_DEBUG +	if (netif_debug) +		printf("%s%d: netif_attach\n", drv->netif_bname, nif->nif_unit); +#endif +	desc->io_netif = nif;  +#ifdef PARANOID +	if (drv->netif_init == NULL) +		panic("%s%d: no netif_init support\n", drv->netif_bname, +		    nif->nif_unit); +#endif +	drv->netif_init(desc, machdep_hint); +	bzero(drv->netif_ifs[nif->nif_unit].dif_stats,  +	    sizeof(struct netif_stats)); +} + +void +netif_detach(nif) +	struct netif *nif; +{ +	struct netif_driver *drv = nif->nif_driver; + +#ifdef NETIF_DEBUG +	if (netif_debug) +		printf("%s%d: netif_detach\n", drv->netif_bname, nif->nif_unit); +#endif +#ifdef PARANOID +	if (drv->netif_end == NULL) +		panic("%s%d: no netif_end support\n", drv->netif_bname, +		    nif->nif_unit); +#endif +	drv->netif_end(nif); +} + +ssize_t +netif_get(desc, pkt, len, timo) +	struct iodesc *desc; +	void *pkt; +	size_t len; +	time_t timo; +{ +#ifdef NETIF_DEBUG +	struct netif *nif = desc->io_netif; +#endif +	struct netif_driver *drv = desc->io_netif->nif_driver; +	ssize_t rv; + +#ifdef NETIF_DEBUG +	if (netif_debug) +		printf("%s%d: netif_get\n", drv->netif_bname, nif->nif_unit); +#endif +#ifdef PARANOID +	if (drv->netif_get == NULL) +		panic("%s%d: no netif_get support\n", drv->netif_bname, +		    nif->nif_unit); +#endif +	rv = drv->netif_get(desc, pkt, len, timo); +#ifdef NETIF_DEBUG +	if (netif_debug) +		printf("%s%d: netif_get returning %d\n", drv->netif_bname, +		    nif->nif_unit, (int)rv); +#endif +	return rv; +} + +ssize_t +netif_put(desc, pkt, len) +	struct iodesc *desc; +	void *pkt; +	size_t len; +{ +#ifdef NETIF_DEBUG +	struct netif *nif = desc->io_netif; +#endif +	struct netif_driver *drv = desc->io_netif->nif_driver; +	ssize_t rv; + +#ifdef NETIF_DEBUG +	if (netif_debug) +		printf("%s%d: netif_put\n", drv->netif_bname, nif->nif_unit); +#endif +#ifdef PARANOID +	if (drv->netif_put == NULL) +		panic("%s%d: no netif_put support\n", drv->netif_bname, +		    nif->nif_unit); +#endif +	rv = drv->netif_put(desc, pkt, len); +#ifdef NETIF_DEBUG +	if (netif_debug) +		printf("%s%d: netif_put returning %d\n", drv->netif_bname, +		    nif->nif_unit, (int)rv); +#endif +	return rv; +} + +struct iodesc * +socktodesc(sock) +	int sock; +{ +	if (sock >= SOPEN_MAX) { +		errno = EBADF; +		return (NULL); +	} +	return (&sockets[sock]); +} + +int +netif_open(machdep_hint) +	void *machdep_hint; +{ +	int fd; +	register struct iodesc *s; +	struct netif *nif; +	 +	/* find a free socket */ +	for (fd = 0, s = sockets; fd < SOPEN_MAX; fd++, s++) +		if (s->io_netif == (struct netif *)0) +			goto fnd; +	errno = EMFILE; +	return (-1); + +fnd: +	bzero(s, sizeof(*s)); +	netif_init(); +	nif = netif_select(machdep_hint); +	if (!nif)  +		panic("netboot: no interfaces left untried"); +	if (netif_probe(nif, machdep_hint)) { +		printf("netboot: couldn't probe %s%d\n", +		    nif->nif_driver->netif_bname, nif->nif_unit); +		errno = EINVAL; +		return(-1); +	} +	netif_attach(nif, s, machdep_hint); + +	return(fd); +} + +int +netif_close(sock) +	int sock; +{ +	if (sock >= SOPEN_MAX) { +		errno = EBADF; +		return(-1); +	} +	netif_detach(sockets[sock].io_netif); +	sockets[sock].io_netif = (struct netif *)0; + +	return(0); +}  | 
