netif.c revision 38451
1269257Sdes/*	$NetBSD: netif.c,v 1.10 1997/09/06 13:57:14 drochner Exp $	*/
2269257Sdes
3269257Sdes/*
4269257Sdes * Copyright (c) 1993 Adam Glass
5269257Sdes * All rights reserved.
6269257Sdes *
7269257Sdes * Redistribution and use in source and binary forms, with or without
8269257Sdes * modification, are permitted provided that the following conditions
9269257Sdes * are met:
10269257Sdes * 1. Redistributions of source code must retain the above copyright
11269257Sdes *    notice, this list of conditions and the following disclaimer.
12269257Sdes * 2. Redistributions in binary form must reproduce the above copyright
13269257Sdes *    notice, this list of conditions and the following disclaimer in the
14269257Sdes *    documentation and/or other materials provided with the distribution.
15269257Sdes * 3. All advertising materials mentioning features or use of this software
16269257Sdes *    must display the following acknowledgement:
17269257Sdes *	This product includes software developed by Adam Glass.
18269257Sdes * 4. The name of the Author may not be used to endorse or promote products
19269257Sdes *    derived from this software without specific prior written permission.
20269257Sdes *
21269257Sdes * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND
22269257Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23269257Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24269257Sdes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25269257Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26269257Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27269257Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28269257Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29269257Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30269257Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31269257Sdes * SUCH DAMAGE.
32269257Sdes */
33269257Sdes
34269257Sdes#include <sys/param.h>
35238104Sdes#include <sys/types.h>
36269257Sdes#include <sys/cdefs.h>
37238104Sdes#include <sys/mount.h>
38269257Sdes#include <string.h>
39269257Sdes
40269257Sdes#include <netinet/in.h>
41269257Sdes#include <netinet/in_systm.h>
42269257Sdes
43269257Sdes#include "stand.h"
44269257Sdes#include "net.h"
45238104Sdes#include "netif.h"
46269257Sdes
47269257Sdesstruct iodesc sockets[SOPEN_MAX];
48269257Sdes#ifdef NETIF_DEBUG
49269257Sdesint netif_debug = 0;
50269257Sdes#endif
51269257Sdes
52238104Sdes/*
53269257Sdes * netif_init:
54269257Sdes *
55238104Sdes * initialize the generic network interface layer
56269257Sdes */
57269257Sdes
58269257Sdesvoid
59269257Sdesnetif_init()
60238104Sdes{
61269257Sdes	struct netif_driver *drv;
62269257Sdes	int d, i;
63269257Sdes
64269257Sdes#ifdef NETIF_DEBUG
65269257Sdes	if (netif_debug)
66269257Sdes		printf("netif_init: called\n");
67269257Sdes#endif
68269257Sdes	for (d = 0; netif_drivers[d]; d++) {
69269257Sdes		drv = netif_drivers[d];
70269257Sdes		for (i = 0; i < drv->netif_nifs; i++)
71269257Sdes			drv->netif_ifs[i].dif_used = 0;
72269257Sdes	}
73269257Sdes}
74269257Sdes
75238104Sdesint
76269257Sdesnetif_match(nif, machdep_hint)
77269257Sdes	struct netif *nif;
78269257Sdes	void *machdep_hint;
79269257Sdes{
80269257Sdes	struct netif_driver *drv = nif->nif_driver;
81269257Sdes
82269257Sdes#if 0
83269257Sdes	if (netif_debug)
84269257Sdes		printf("%s%d: netif_match (%d)\n", drv->netif_bname,
85269257Sdes		    nif->nif_unit, nif->nif_sel);
86269257Sdes#endif
87269257Sdes	return drv->netif_match(nif, machdep_hint);
88238104Sdes}
89269257Sdes
90269257Sdesstruct netif *
91269257Sdesnetif_select(machdep_hint)
92269257Sdes	void *machdep_hint;
93269257Sdes{
94269257Sdes	int d, u, unit_done, s;
95269257Sdes	struct netif_driver *drv;
96269257Sdes	struct netif cur_if;
97269257Sdes	static struct netif best_if;
98269257Sdes	int best_val;
99269257Sdes	int val;
100269257Sdes
101238104Sdes	best_val = 0;
102269257Sdes	best_if.nif_driver = NULL;
103269257Sdes
104269257Sdes	for (d = 0; netif_drivers[d] != NULL; d++) {
105269257Sdes		cur_if.nif_driver = netif_drivers[d];
106269257Sdes		drv = cur_if.nif_driver;
107269257Sdes
108269257Sdes		for (u = 0; u < drv->netif_nifs; u++) {
109269257Sdes			cur_if.nif_unit = u;
110269257Sdes			unit_done = 0;
111269257Sdes
112269257Sdes#ifdef NETIF_DEBUG
113269257Sdes			if (netif_debug)
114269257Sdes				printf("\t%s%d:", drv->netif_bname,
115269257Sdes				    cur_if.nif_unit);
116269257Sdes#endif
117269257Sdes
118269257Sdes			for (s = 0; s < drv->netif_ifs[u].dif_nsel; s++) {
119238104Sdes				cur_if.nif_sel = s;
120269257Sdes
121269257Sdes				if (drv->netif_ifs[u].dif_used & (1 << s)) {
122269257Sdes#ifdef NETIF_DEBUG
123269257Sdes					if (netif_debug)
124269257Sdes						printf(" [%d used]", s);
125269257Sdes#endif
126269257Sdes					continue;
127269257Sdes				}
128269257Sdes
129269257Sdes				val = netif_match(&cur_if, machdep_hint);
130269257Sdes#ifdef NETIF_DEBUG
131269257Sdes				if (netif_debug)
132269257Sdes					printf(" [%d -> %d]", s, val);
133269257Sdes#endif
134269257Sdes				if (val > best_val) {
135269257Sdes					best_val = val;
136238104Sdes					best_if = cur_if;
137269257Sdes				}
138269257Sdes			}
139269257Sdes#ifdef NETIF_DEBUG
140269257Sdes			if (netif_debug)
141269257Sdes				printf("\n");
142269257Sdes#endif
143269257Sdes		}
144269257Sdes	}
145269257Sdes
146269257Sdes	if (best_if.nif_driver == NULL)
147269257Sdes		return NULL;
148269257Sdes
149269257Sdes	best_if.nif_driver->
150269257Sdes	    netif_ifs[best_if.nif_unit].dif_used |= (1 << best_if.nif_sel);
151269257Sdes
152269257Sdes#ifdef NETIF_DEBUG
153238104Sdes	if (netif_debug)
154269257Sdes		printf("netif_select: %s%d(%d) wins\n",
155269257Sdes			best_if.nif_driver->netif_bname,
156269257Sdes			best_if.nif_unit, best_if.nif_sel);
157238104Sdes#endif
158269257Sdes	return &best_if;
159269257Sdes}
160269257Sdes
161269257Sdesint
162269257Sdesnetif_probe(nif, machdep_hint)
163269257Sdes	struct netif *nif;
164269257Sdes	void *machdep_hint;
165269257Sdes{
166269257Sdes	struct netif_driver *drv = nif->nif_driver;
167269257Sdes
168269257Sdes#ifdef NETIF_DEBUG
169269257Sdes	if (netif_debug)
170238104Sdes		printf("%s%d: netif_probe\n", drv->netif_bname, nif->nif_unit);
171238104Sdes#endif
172269257Sdes	return drv->netif_probe(nif, machdep_hint);
173269257Sdes}
174269257Sdes
175238104Sdesvoid
176269257Sdesnetif_attach(nif, desc, machdep_hint)
177269257Sdes	struct netif *nif;
178269257Sdes	struct iodesc *desc;
179269257Sdes	void *machdep_hint;
180269257Sdes{
181269257Sdes	struct netif_driver *drv = nif->nif_driver;
182269257Sdes
183269257Sdes#ifdef NETIF_DEBUG
184269257Sdes	if (netif_debug)
185269257Sdes		printf("%s%d: netif_attach\n", drv->netif_bname, nif->nif_unit);
186269257Sdes#endif
187269257Sdes	desc->io_netif = nif;
188238104Sdes#ifdef PARANOID
189238104Sdes	if (drv->netif_init == NULL)
190269257Sdes		panic("%s%d: no netif_init support\n", drv->netif_bname,
191269257Sdes		    nif->nif_unit);
192269257Sdes#endif
193269257Sdes	drv->netif_init(desc, machdep_hint);
194269257Sdes	bzero(drv->netif_ifs[nif->nif_unit].dif_stats,
195269257Sdes	    sizeof(struct netif_stats));
196269257Sdes}
197269257Sdes
198269257Sdesvoid
199269257Sdesnetif_detach(nif)
200269257Sdes	struct netif *nif;
201269257Sdes{
202269257Sdes	struct netif_driver *drv = nif->nif_driver;
203269257Sdes
204269257Sdes#ifdef NETIF_DEBUG
205269257Sdes	if (netif_debug)
206269257Sdes		printf("%s%d: netif_detach\n", drv->netif_bname, nif->nif_unit);
207238104Sdes#endif
208269257Sdes#ifdef PARANOID
209269257Sdes	if (drv->netif_end == NULL)
210269257Sdes		panic("%s%d: no netif_end support\n", drv->netif_bname,
211269257Sdes		    nif->nif_unit);
212269257Sdes#endif
213269257Sdes	drv->netif_end(nif);
214269257Sdes}
215269257Sdes
216269257Sdesssize_t
217269257Sdesnetif_get(desc, pkt, len, timo)
218269257Sdes	struct iodesc *desc;
219269257Sdes	void *pkt;
220269257Sdes	size_t len;
221238104Sdes	time_t timo;
222269257Sdes{
223269257Sdes#ifdef NETIF_DEBUG
224269257Sdes	struct netif *nif = desc->io_netif;
225269257Sdes#endif
226269257Sdes	struct netif_driver *drv = desc->io_netif->nif_driver;
227269257Sdes	ssize_t rv;
228269257Sdes
229269257Sdes#ifdef NETIF_DEBUG
230269257Sdes	if (netif_debug)
231269257Sdes		printf("%s%d: netif_get\n", drv->netif_bname, nif->nif_unit);
232269257Sdes#endif
233269257Sdes#ifdef PARANOID
234269257Sdes	if (drv->netif_get == NULL)
235238104Sdes		panic("%s%d: no netif_get support\n", drv->netif_bname,
236269257Sdes		    nif->nif_unit);
237269257Sdes#endif
238269257Sdes	rv = drv->netif_get(desc, pkt, len, timo);
239269257Sdes#ifdef NETIF_DEBUG
240269257Sdes	if (netif_debug)
241269257Sdes		printf("%s%d: netif_get returning %d\n", drv->netif_bname,
242269257Sdes		    nif->nif_unit, (int)rv);
243269257Sdes#endif
244269257Sdes	return rv;
245269257Sdes}
246269257Sdes
247269257Sdesssize_t
248269257Sdesnetif_put(desc, pkt, len)
249269257Sdes	struct iodesc *desc;
250269257Sdes	void *pkt;
251238104Sdes	size_t len;
252269257Sdes{
253269257Sdes#ifdef NETIF_DEBUG
254238104Sdes	struct netif *nif = desc->io_netif;
255269257Sdes#endif
256269257Sdes	struct netif_driver *drv = desc->io_netif->nif_driver;
257269257Sdes	ssize_t rv;
258269257Sdes
259269257Sdes#ifdef NETIF_DEBUG
260269257Sdes	if (netif_debug)
261269257Sdes		printf("%s%d: netif_put\n", drv->netif_bname, nif->nif_unit);
262269257Sdes#endif
263269257Sdes#ifdef PARANOID
264269257Sdes	if (drv->netif_put == NULL)
265269257Sdes		panic("%s%d: no netif_put support\n", drv->netif_bname,
266269257Sdes		    nif->nif_unit);
267269257Sdes#endif
268269257Sdes	rv = drv->netif_put(desc, pkt, len);
269269257Sdes#ifdef NETIF_DEBUG
270269257Sdes	if (netif_debug)
271269257Sdes		printf("%s%d: netif_put returning %d\n", drv->netif_bname,
272269257Sdes		    nif->nif_unit, (int)rv);
273269257Sdes#endif
274269257Sdes	return rv;
275269257Sdes}
276269257Sdes
277269257Sdesstruct iodesc *
278269257Sdessocktodesc(sock)
279269257Sdes	int sock;
280269257Sdes{
281269257Sdes	if (sock >= SOPEN_MAX) {
282269257Sdes		errno = EBADF;
283269257Sdes		return (NULL);
284269257Sdes	}
285269257Sdes	return (&sockets[sock]);
286269257Sdes}
287269257Sdes
288269257Sdesint
289269257Sdesnetif_open(machdep_hint)
290269257Sdes	void *machdep_hint;
291269257Sdes{
292269257Sdes	int fd;
293269257Sdes	register struct iodesc *s;
294269257Sdes	struct netif *nif;
295269257Sdes
296269257Sdes	/* find a free socket */
297269257Sdes	for (fd = 0, s = sockets; fd < SOPEN_MAX; fd++, s++)
298238104Sdes		if (s->io_netif == (struct netif *)0)
299269257Sdes			goto fnd;
300269257Sdes	errno = EMFILE;
301269257Sdes	return (-1);
302269257Sdes
303269257Sdesfnd:
304269257Sdes	bzero(s, sizeof(*s));
305269257Sdes	netif_init();
306269257Sdes	nif = netif_select(machdep_hint);
307238104Sdes	if (!nif)
308269257Sdes		panic("netboot: no interfaces left untried");
309269257Sdes	if (netif_probe(nif, machdep_hint)) {
310269257Sdes		printf("netboot: couldn't probe %s%d\n",
311269257Sdes		    nif->nif_driver->netif_bname, nif->nif_unit);
312269257Sdes		errno = EINVAL;
313269257Sdes		return(-1);
314269257Sdes	}
315269257Sdes	netif_attach(nif, s, machdep_hint);
316269257Sdes
317269257Sdes	return(fd);
318269257Sdes}
319269257Sdes
320269257Sdesint
321269257Sdesnetif_close(sock)
322238104Sdes	int sock;
323269257Sdes{
324269257Sdes	if (sock >= SOPEN_MAX) {
325269257Sdes		errno = EBADF;
326269257Sdes		return(-1);
327269257Sdes	}
328269257Sdes	netif_detach(sockets[sock].io_netif);
329269257Sdes	sockets[sock].io_netif = (struct netif *)0;
330269257Sdes
331269257Sdes	return(0);
332269257Sdes}
333269257Sdes