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