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