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