netif.c revision 1.8
1/*	$OpenBSD: netif.c,v 1.8 2003/08/11 06:23:09 deraadt Exp $	*/
2/*	$NetBSD: netif.c,v 1.7 1996/10/13 02:29:03 christos Exp $	*/
3
4/*
5 * Copyright (c) 1993 Adam Glass
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *	This product includes software developed by Adam Glass.
19 * 4. The name of the Author may not be used to endorse or promote products
20 *    derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#include <sys/param.h>
36#include <sys/types.h>
37#include <sys/cdefs.h>
38#include <sys/mount.h>
39
40#include <netinet/in.h>
41#include <netinet/in_systm.h>
42
43#include "stand.h"
44#include "net.h"
45#include "netif.h"
46
47struct iodesc sockets[SOPEN_MAX];
48#ifdef NETIF_DEBUG
49int netif_debug = 0;
50#endif
51
52/*
53 * netif_init:
54 *
55 * initialize the generic network interface layer
56 */
57
58void
59netif_init(void)
60{
61	struct netif_driver *drv;
62	int d, i;
63
64#ifdef NETIF_DEBUG
65	if (netif_debug)
66		printf("netif_init: called\n");
67#endif
68	for (d = 0; d < n_netif_drivers; d++) {
69		drv = netif_drivers[d];
70		for (i = 0; i < drv->netif_nifs; i++)
71			drv->netif_ifs[i].dif_used = 0;
72	}
73}
74
75static int
76netif_match(struct netif *nif, void *machdep_hint)
77{
78	struct netif_driver *drv = nif->nif_driver;
79
80#if 0
81	if (netif_debug)
82		printf("%s%d: netif_match (%d)\n", drv->netif_bname,
83		    nif->nif_unit, nif->nif_sel);
84#endif
85	return drv->netif_match(nif, machdep_hint);
86}
87
88struct netif *
89netif_select(void *machdep_hint)
90{
91	int d, u, unit_done, s;
92	struct netif_driver *drv;
93	struct netif cur_if;
94	static struct netif best_if;
95	int best_val;
96	int val;
97
98	best_val = 0;
99	best_if.nif_driver = NULL;
100
101#ifdef NETIF_DEBUG
102	if (netif_debug)
103		printf("netif_select: %d interfaces\n", n_netif_drivers);
104#endif
105
106	for (d = 0; d < n_netif_drivers; d++) {
107		cur_if.nif_driver = netif_drivers[d];
108		drv = cur_if.nif_driver;
109
110		for (u = 0; u < drv->netif_nifs; u++) {
111			cur_if.nif_unit = u;
112			unit_done = 0;
113
114#ifdef NETIF_DEBUG
115			if (netif_debug)
116				printf("\t%s%d:", drv->netif_bname,
117				    cur_if.nif_unit);
118#endif
119
120			for (s = 0; s < drv->netif_ifs[u].dif_nsel; s++) {
121				cur_if.nif_sel = s;
122
123				if (drv->netif_ifs[u].dif_used & (1 << s)) {
124#ifdef NETIF_DEBUG
125					if (netif_debug)
126						printf(" [%d used]", s);
127#endif
128					continue;
129				}
130
131				val = netif_match(&cur_if, machdep_hint);
132#ifdef NETIF_DEBUG
133				if (netif_debug)
134					printf(" [%d -> %d]", s, val);
135#endif
136				if (val > best_val) {
137					best_val = val;
138					best_if = cur_if;
139				}
140			}
141#ifdef NETIF_DEBUG
142			if (netif_debug)
143				printf("\n");
144#endif
145		}
146	}
147
148	if (best_if.nif_driver == NULL)
149		return NULL;
150
151	best_if.nif_driver->netif_ifs[best_if.nif_unit].dif_used |=
152	    (1 << best_if.nif_sel);
153
154#ifdef NETIF_DEBUG
155	if (netif_debug)
156		printf("netif_select: %s%d(%d) wins\n",
157		    best_if.nif_driver->netif_bname,
158		    best_if.nif_unit, best_if.nif_sel);
159#endif
160	return &best_if;
161}
162
163int
164netif_probe(struct netif *nif, void *machdep_hint)
165{
166	struct netif_driver *drv = nif->nif_driver;
167
168#ifdef NETIF_DEBUG
169	if (netif_debug)
170		printf("%s%d: netif_probe\n", drv->netif_bname, nif->nif_unit);
171#endif
172	return drv->netif_probe(nif, machdep_hint);
173}
174
175void
176netif_attach(struct netif *nif, struct iodesc *desc, void *machdep_hint)
177{
178	struct netif_driver *drv = nif->nif_driver;
179
180#ifdef NETIF_DEBUG
181	if (netif_debug)
182		printf("%s%d: netif_attach\n", drv->netif_bname, nif->nif_unit);
183#endif
184	desc->io_netif = nif;
185#ifdef PARANOID
186	if (drv->netif_init == NULL)
187		panic("%s%d: no netif_init support", drv->netif_bname,
188		    nif->nif_unit);
189#endif
190	drv->netif_init(desc, machdep_hint);
191	bzero(drv->netif_ifs[nif->nif_unit].dif_stats,
192	    sizeof(struct netif_stats));
193}
194
195void
196netif_detach(struct netif *nif)
197{
198	struct netif_driver *drv = nif->nif_driver;
199
200#ifdef NETIF_DEBUG
201	if (netif_debug)
202		printf("%s%d: netif_detach\n", drv->netif_bname, nif->nif_unit);
203#endif
204#ifdef PARANOID
205	if (drv->netif_end == NULL)
206		panic("%s%d: no netif_end support", drv->netif_bname,
207		    nif->nif_unit);
208#endif
209	drv->netif_end(nif);
210}
211
212ssize_t
213netif_get(struct iodesc *desc, void *pkt, size_t len, time_t timo)
214{
215#ifdef NETIF_DEBUG
216	struct netif *nif = desc->io_netif;
217#endif
218	struct netif_driver *drv = desc->io_netif->nif_driver;
219	ssize_t rv;
220
221#ifdef NETIF_DEBUG
222	if (netif_debug)
223		printf("%s%d: netif_get\n", drv->netif_bname, nif->nif_unit);
224#endif
225#ifdef PARANOID
226	if (drv->netif_get == NULL)
227		panic("%s%d: no netif_get support", drv->netif_bname,
228		    nif->nif_unit);
229#endif
230	rv = drv->netif_get(desc, pkt, len, timo);
231#ifdef NETIF_DEBUG
232	if (netif_debug)
233		printf("%s%d: netif_get returning %d\n", drv->netif_bname,
234		    nif->nif_unit, rv);
235#endif
236	return rv;
237}
238
239ssize_t
240netif_put(struct iodesc *desc, void *pkt, size_t len)
241{
242#ifdef NETIF_DEBUG
243	struct netif *nif = desc->io_netif;
244#endif
245	struct netif_driver *drv = desc->io_netif->nif_driver;
246	ssize_t rv;
247
248#ifdef NETIF_DEBUG
249	if (netif_debug)
250		printf("%s%d: netif_put\n", drv->netif_bname, nif->nif_unit);
251#endif
252#ifdef PARANOID
253	if (drv->netif_put == NULL)
254		panic("%s%d: no netif_put support", drv->netif_bname,
255		    nif->nif_unit);
256#endif
257	rv = drv->netif_put(desc, pkt, len);
258#ifdef NETIF_DEBUG
259	if (netif_debug)
260		printf("%s%d: netif_put returning %d\n", drv->netif_bname,
261		    nif->nif_unit, rv);
262#endif
263	return rv;
264}
265
266struct iodesc *
267socktodesc(sock)
268	int sock;
269{
270	if (sock >= SOPEN_MAX) {
271		errno = EBADF;
272		return (NULL);
273	}
274	return (&sockets[sock]);
275}
276
277int
278netif_open(void *machdep_hint)
279{
280	int fd;
281	struct iodesc *s;
282	struct netif *nif;
283
284	/* find a free socket */
285	for (fd = 0, s = sockets; fd < SOPEN_MAX; fd++, s++)
286		if (s->io_netif == (struct netif *)0)
287			goto fnd;
288	errno = EMFILE;
289	return (-1);
290
291fnd:
292	bzero(s, sizeof(*s));
293	netif_init();
294	nif = netif_select(machdep_hint);
295	if (!nif)
296		panic("netboot: no interfaces left untried");
297	if (netif_probe(nif, machdep_hint)) {
298		printf("netboot: couldn't probe %s%d\n",
299		    nif->nif_driver->netif_bname, nif->nif_unit);
300		errno = EINVAL;
301		return(-1);
302	}
303	netif_attach(nif, s, machdep_hint);
304
305	return(fd);
306}
307
308int
309netif_close(int sock)
310{
311	if (sock >= SOPEN_MAX) {
312		errno = EBADF;
313		return(-1);
314	}
315	netif_detach(sockets[sock].io_netif);
316	sockets[sock].io_netif = (struct netif *)0;
317
318	return(0);
319}
320