xref: /openbsd/sys/lib/libsa/netif.c (revision db3296cf)
1 /*	$OpenBSD: netif.c,v 1.7 2003/06/01 17:00:33 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 
47 struct iodesc sockets[SOPEN_MAX];
48 #ifdef NETIF_DEBUG
49 int netif_debug = 0;
50 #endif
51 
52 /*
53  * netif_init:
54  *
55  * initialize the generic network interface layer
56  */
57 
58 void
59 netif_init()
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 
75 int
76 netif_match(nif, machdep_hint)
77 	struct netif *nif;
78 	void *machdep_hint;
79 {
80 	struct netif_driver *drv = nif->nif_driver;
81 
82 #if 0
83 	if (netif_debug)
84 		printf("%s%d: netif_match (%d)\n", drv->netif_bname,
85 		    nif->nif_unit, nif->nif_sel);
86 #endif
87 	return drv->netif_match(nif, machdep_hint);
88 }
89 
90 struct netif *
91 netif_select(machdep_hint)
92 	void *machdep_hint;
93 {
94 	int d, u, unit_done, s;
95 	struct netif_driver *drv;
96 	struct netif cur_if;
97 	static struct netif best_if;
98 	int best_val;
99 	int val;
100 
101 	best_val = 0;
102 	best_if.nif_driver = NULL;
103 
104 #ifdef NETIF_DEBUG
105 	if (netif_debug)
106 		printf("netif_select: %d interfaces\n", n_netif_drivers);
107 #endif
108 
109 	for (d = 0; d < n_netif_drivers; d++) {
110 		cur_if.nif_driver = netif_drivers[d];
111 		drv = cur_if.nif_driver;
112 
113 		for (u = 0; u < drv->netif_nifs; u++) {
114 			cur_if.nif_unit = u;
115 			unit_done = 0;
116 
117 #ifdef NETIF_DEBUG
118 			if (netif_debug)
119 				printf("\t%s%d:", drv->netif_bname,
120 				    cur_if.nif_unit);
121 #endif
122 
123 			for (s = 0; s < drv->netif_ifs[u].dif_nsel; s++) {
124 				cur_if.nif_sel = s;
125 
126 				if (drv->netif_ifs[u].dif_used & (1 << s)) {
127 #ifdef NETIF_DEBUG
128 					if (netif_debug)
129 						printf(" [%d used]", s);
130 #endif
131 					continue;
132 				}
133 
134 				val = netif_match(&cur_if, machdep_hint);
135 #ifdef NETIF_DEBUG
136 				if (netif_debug)
137 					printf(" [%d -> %d]", s, val);
138 #endif
139 				if (val > best_val) {
140 					best_val = val;
141 					best_if = cur_if;
142 				}
143 			}
144 #ifdef NETIF_DEBUG
145 			if (netif_debug)
146 				printf("\n");
147 #endif
148 		}
149 	}
150 
151 	if (best_if.nif_driver == NULL)
152 		return NULL;
153 
154 	best_if.nif_driver->
155 	    netif_ifs[best_if.nif_unit].dif_used |= (1 << best_if.nif_sel);
156 
157 #ifdef NETIF_DEBUG
158 	if (netif_debug)
159 		printf("netif_select: %s%d(%d) wins\n",
160 			best_if.nif_driver->netif_bname,
161 			best_if.nif_unit, best_if.nif_sel);
162 #endif
163 	return &best_if;
164 }
165 
166 int
167 netif_probe(nif, machdep_hint)
168 	struct netif *nif;
169 	void *machdep_hint;
170 {
171 	struct netif_driver *drv = nif->nif_driver;
172 
173 #ifdef NETIF_DEBUG
174 	if (netif_debug)
175 		printf("%s%d: netif_probe\n", drv->netif_bname, nif->nif_unit);
176 #endif
177 	return drv->netif_probe(nif, machdep_hint);
178 }
179 
180 void
181 netif_attach(nif, desc, machdep_hint)
182 	struct netif *nif;
183 	struct iodesc *desc;
184 	void *machdep_hint;
185 {
186 	struct netif_driver *drv = nif->nif_driver;
187 
188 #ifdef NETIF_DEBUG
189 	if (netif_debug)
190 		printf("%s%d: netif_attach\n", drv->netif_bname, nif->nif_unit);
191 #endif
192 	desc->io_netif = nif;
193 #ifdef PARANOID
194 	if (drv->netif_init == NULL)
195 		panic("%s%d: no netif_init support", drv->netif_bname,
196 		    nif->nif_unit);
197 #endif
198 	drv->netif_init(desc, machdep_hint);
199 	bzero(drv->netif_ifs[nif->nif_unit].dif_stats,
200 	    sizeof(struct netif_stats));
201 }
202 
203 void
204 netif_detach(nif)
205 	struct netif *nif;
206 {
207 	struct netif_driver *drv = nif->nif_driver;
208 
209 #ifdef NETIF_DEBUG
210 	if (netif_debug)
211 		printf("%s%d: netif_detach\n", drv->netif_bname, nif->nif_unit);
212 #endif
213 #ifdef PARANOID
214 	if (drv->netif_end == NULL)
215 		panic("%s%d: no netif_end support", drv->netif_bname,
216 		    nif->nif_unit);
217 #endif
218 	drv->netif_end(nif);
219 }
220 
221 ssize_t
222 netif_get(desc, pkt, len, timo)
223 	struct iodesc *desc;
224 	void *pkt;
225 	size_t len;
226 	time_t timo;
227 {
228 #ifdef NETIF_DEBUG
229 	struct netif *nif = desc->io_netif;
230 #endif
231 	struct netif_driver *drv = desc->io_netif->nif_driver;
232 	ssize_t rv;
233 
234 #ifdef NETIF_DEBUG
235 	if (netif_debug)
236 		printf("%s%d: netif_get\n", drv->netif_bname, nif->nif_unit);
237 #endif
238 #ifdef PARANOID
239 	if (drv->netif_get == NULL)
240 		panic("%s%d: no netif_get support", drv->netif_bname,
241 		    nif->nif_unit);
242 #endif
243 	rv = drv->netif_get(desc, pkt, len, timo);
244 #ifdef NETIF_DEBUG
245 	if (netif_debug)
246 		printf("%s%d: netif_get returning %d\n", drv->netif_bname,
247 		    nif->nif_unit, rv);
248 #endif
249 	return rv;
250 }
251 
252 ssize_t
253 netif_put(desc, pkt, len)
254 	struct iodesc *desc;
255 	void *pkt;
256 	size_t len;
257 {
258 #ifdef NETIF_DEBUG
259 	struct netif *nif = desc->io_netif;
260 #endif
261 	struct netif_driver *drv = desc->io_netif->nif_driver;
262 	ssize_t rv;
263 
264 #ifdef NETIF_DEBUG
265 	if (netif_debug)
266 		printf("%s%d: netif_put\n", drv->netif_bname, nif->nif_unit);
267 #endif
268 #ifdef PARANOID
269 	if (drv->netif_put == NULL)
270 		panic("%s%d: no netif_put support", drv->netif_bname,
271 		    nif->nif_unit);
272 #endif
273 	rv = drv->netif_put(desc, pkt, len);
274 #ifdef NETIF_DEBUG
275 	if (netif_debug)
276 		printf("%s%d: netif_put returning %d\n", drv->netif_bname,
277 		    nif->nif_unit, rv);
278 #endif
279 	return rv;
280 }
281 
282 struct iodesc *
283 socktodesc(sock)
284 	int sock;
285 {
286 	if (sock >= SOPEN_MAX) {
287 		errno = EBADF;
288 		return (NULL);
289 	}
290 	return (&sockets[sock]);
291 }
292 
293 int
294 netif_open(machdep_hint)
295 	void *machdep_hint;
296 {
297 	int fd;
298 	register struct iodesc *s;
299 	struct netif *nif;
300 
301 	/* find a free socket */
302 	for (fd = 0, s = sockets; fd < SOPEN_MAX; fd++, s++)
303 		if (s->io_netif == (struct netif *)0)
304 			goto fnd;
305 	errno = EMFILE;
306 	return (-1);
307 
308 fnd:
309 	bzero(s, sizeof(*s));
310 	netif_init();
311 	nif = netif_select(machdep_hint);
312 	if (!nif)
313 		panic("netboot: no interfaces left untried");
314 	if (netif_probe(nif, machdep_hint)) {
315 		printf("netboot: couldn't probe %s%d\n",
316 		    nif->nif_driver->netif_bname, nif->nif_unit);
317 		errno = EINVAL;
318 		return(-1);
319 	}
320 	netif_attach(nif, s, machdep_hint);
321 
322 	return(fd);
323 }
324 
325 int
326 netif_close(sock)
327 	int sock;
328 {
329 	if (sock >= SOPEN_MAX) {
330 		errno = EBADF;
331 		return(-1);
332 	}
333 	netif_detach(sockets[sock].io_netif);
334 	sockets[sock].io_netif = (struct netif *)0;
335 
336 	return(0);
337 }
338