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