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