1 /* $NetBSD: netif.c,v 1.3 1995/02/20 00:19:09 mycroft 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 34 #include <sys/param.h> 35 #include <sys/types.h> 36 #include <sys/cdefs.h> 37 #include <sys/mount.h> 38 #include <time.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; d < n_netif_drivers; 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 #ifdef NETIF_DEBUG 106 if (netif_debug) 107 printf("netif_select: %d interfaces\n", n_netif_drivers); 108 #endif 109 110 for (d = 0; d < n_netif_drivers; d++) { 111 cur_if.nif_driver = netif_drivers[d]; 112 drv = cur_if.nif_driver; 113 114 for (u = 0; u < drv->netif_nifs; u++) { 115 cur_if.nif_unit = u; 116 unit_done = 0; 117 118 #ifdef NETIF_DEBUG 119 if (netif_debug) 120 printf("\t%s%d:", drv->netif_bname, 121 cur_if.nif_unit); 122 #endif 123 124 for (s = 0; s < drv->netif_ifs[u].dif_nsel; s++) { 125 cur_if.nif_sel = s; 126 127 if (drv->netif_ifs[u].dif_used & (1 << s)) { 128 #ifdef NETIF_DEBUG 129 if (netif_debug) 130 printf(" [%d used]", s); 131 #endif 132 continue; 133 } 134 135 val = netif_match(&cur_if, machdep_hint); 136 #ifdef NETIF_DEBUG 137 if (netif_debug) 138 printf(" [%d -> %d]", s, val); 139 #endif 140 if (val > best_val) { 141 best_val = val; 142 best_if = cur_if; 143 } 144 } 145 #ifdef NETIF_DEBUG 146 if (netif_debug) 147 printf("\n"); 148 #endif 149 } 150 } 151 152 if (best_if.nif_driver == NULL) 153 return NULL; 154 155 best_if.nif_driver-> 156 netif_ifs[best_if.nif_unit].dif_used |= (1 << best_if.nif_sel); 157 158 #ifdef NETIF_DEBUG 159 if (netif_debug) 160 printf("netif_select: %s%d(%d) wins\n", 161 best_if.nif_driver->netif_bname, 162 best_if.nif_unit, best_if.nif_sel); 163 #endif 164 return &best_if; 165 } 166 167 int 168 netif_probe(nif, machdep_hint) 169 struct netif *nif; 170 void *machdep_hint; 171 { 172 struct netif_driver *drv = nif->nif_driver; 173 174 #ifdef NETIF_DEBUG 175 if (netif_debug) 176 printf("%s%d: netif_probe\n", drv->netif_bname, nif->nif_unit); 177 #endif 178 return drv->netif_probe(nif, machdep_hint); 179 } 180 181 void 182 netif_attach(nif, desc, machdep_hint) 183 struct netif *nif; 184 struct iodesc *desc; 185 void *machdep_hint; 186 { 187 struct netif_driver *drv = nif->nif_driver; 188 189 #ifdef NETIF_DEBUG 190 if (netif_debug) 191 printf("%s%d: netif_attach\n", drv->netif_bname, nif->nif_unit); 192 #endif 193 desc->io_netif = nif; 194 #ifdef PARANOID 195 if (drv->netif_init == NULL) 196 panic("%s%d: no netif_init support\n", drv->netif_bname, 197 nif->nif_unit); 198 #endif 199 drv->netif_init(desc, machdep_hint); 200 bzero(drv->netif_ifs[nif->nif_unit].dif_stats, 201 sizeof(struct netif_stats)); 202 } 203 204 void 205 netif_detach(nif) 206 struct netif *nif; 207 { 208 struct netif_driver *drv = nif->nif_driver; 209 210 #ifdef NETIF_DEBUG 211 if (netif_debug) 212 printf("%s%d: netif_detach\n", drv->netif_bname, nif->nif_unit); 213 #endif 214 #ifdef PARANOID 215 if (drv->netif_end == NULL) 216 panic("%s%d: no netif_end support\n", drv->netif_bname, 217 nif->nif_unit); 218 #endif 219 drv->netif_end(nif); 220 } 221 222 int 223 netif_get(desc, pkt, len, timo) 224 struct iodesc *desc; 225 void *pkt; 226 int len; 227 time_t timo; 228 { 229 struct netif *nif = desc->io_netif; 230 struct netif_driver *drv = desc->io_netif->nif_driver; 231 int 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, rv); 247 #endif 248 return rv; 249 } 250 251 int 252 netif_put(desc, pkt, len) 253 struct iodesc *desc; 254 void *pkt; 255 int len; 256 { 257 struct netif *nif = desc->io_netif; 258 struct netif_driver *drv = desc->io_netif->nif_driver; 259 int rv; 260 261 #ifdef NETIF_DEBUG 262 if (netif_debug) 263 printf("%s%d: netif_put\n", drv->netif_bname, nif->nif_unit); 264 #endif 265 #ifdef PARANOID 266 if (drv->netif_put == NULL) 267 panic("%s%d: no netif_put support\n", drv->netif_bname, 268 nif->nif_unit); 269 #endif 270 rv = drv->netif_put(desc, pkt, len); 271 #ifdef NETIF_DEBUG 272 if (netif_debug) 273 printf("%s%d: netif_put returning %d\n", drv->netif_bname, 274 nif->nif_unit, rv); 275 #endif 276 return rv; 277 } 278 279 struct iodesc * 280 socktodesc(sock) 281 int sock; 282 { 283 if (sock >= SOPEN_MAX) { 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 register 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 return (-1); 302 303 fnd: 304 bzero(s, sizeof(*s)); 305 netif_init(); 306 nif = netif_select(machdep_hint); 307 if (!nif) 308 panic("netboot: no interfaces left untried"); 309 if (netif_probe(nif, machdep_hint)) { 310 printf("netboot: couldn't probe %s%d\n", 311 nif->nif_driver->netif_bname, nif->nif_unit); 312 errno = EINVAL; 313 return(-1); 314 } 315 netif_attach(nif, s, machdep_hint); 316 317 return(fd); 318 } 319 320 int 321 netif_close(sock) 322 int sock; 323 { 324 if (sock >= SOPEN_MAX) { 325 errno = EBADF; 326 return(-1); 327 } 328 netif_detach(sockets[sock].io_netif); 329 sockets[sock].io_netif = (struct netif *)0; 330 331 return(0); 332 } 333