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