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