1 /* 2 * Copyright (c) 1993 Adam Glass 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Adam Glass. 16 * 4. The name of the Author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * $Id: netif.c,v 1.1 1994/05/08 16:11:29 brezak Exp $ 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 50 /* 51 * netif_init: 52 * 53 * initialize the generic network interface layer 54 */ 55 56 void 57 netif_init() 58 { 59 struct netif_driver *drv; 60 int d, i; 61 62 #ifdef NETIF_DEBUG 63 if (netif_debug) 64 printf("netif_init: called\n"); 65 #endif 66 for (d = 0; d < n_netif_drivers; d++) { 67 drv = netif_drivers[d]; 68 for (i = 0; i < drv->netif_nifs; i++) 69 drv->netif_ifs[i].dif_used = 0; 70 } 71 } 72 73 int 74 netif_match(nif, machdep_hint) 75 struct netif *nif; 76 void *machdep_hint; 77 { 78 struct netif_driver *drv = nif->nif_driver; 79 80 #if 0 81 if (netif_debug) 82 printf("%s%d: netif_match (%d)\n", drv->netif_bname, 83 nif->nif_unit, nif->nif_sel); 84 #endif 85 return drv->netif_match(nif, machdep_hint); 86 } 87 88 struct netif * 89 netif_select(machdep_hint) 90 void *machdep_hint; 91 { 92 int d, u, unit_done, s; 93 struct netif_driver *drv; 94 struct netif cur_if; 95 static struct netif best_if; 96 int best_val; 97 int val; 98 99 best_val = 0; 100 best_if.nif_driver = NULL; 101 102 #ifdef NETIF_DEBUG 103 if (netif_debug) 104 printf("netif_select: %d interfaces\n", n_netif_drivers); 105 #endif 106 107 for (d = 0; d < n_netif_drivers; 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 int 220 netif_get(desc, pkt, len, timo) 221 struct iodesc *desc; 222 void *pkt; 223 int len; 224 time_t timo; 225 { 226 struct netif *nif = desc->io_netif; 227 struct netif_driver *drv = desc->io_netif->nif_driver; 228 int 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, rv); 244 #endif 245 return rv; 246 } 247 248 int 249 netif_put(desc, pkt, len) 250 struct iodesc *desc; 251 void *pkt; 252 int len; 253 { 254 struct netif *nif = desc->io_netif; 255 struct netif_driver *drv = desc->io_netif->nif_driver; 256 int rv; 257 258 #ifdef NETIF_DEBUG 259 if (netif_debug) 260 printf("%s%d: netif_put\n", drv->netif_bname, nif->nif_unit); 261 #endif 262 #ifdef PARANOID 263 if (drv->netif_put == NULL) 264 panic("%s%d: no netif_put support\n", drv->netif_bname, 265 nif->nif_unit); 266 #endif 267 rv = drv->netif_put(desc, pkt, len); 268 #ifdef NETIF_DEBUG 269 if (netif_debug) 270 printf("%s%d: netif_put returning %d\n", drv->netif_bname, 271 nif->nif_unit, rv); 272 #endif 273 return rv; 274 } 275 276 struct iodesc * 277 socktodesc(sock) 278 int sock; 279 { 280 if (sock >= SOPEN_MAX) { 281 return(NULL); 282 } 283 return (&sockets[sock]); 284 } 285 286 int 287 netif_open(machdep_hint) 288 void *machdep_hint; 289 { 290 int fd; 291 register struct iodesc *s; 292 struct netif *nif; 293 294 /* find a free socket */ 295 for (fd = 0, s = sockets; fd < SOPEN_MAX; fd++, s++) 296 if (s->io_netif == (struct netif *)0) 297 goto fnd; 298 return (-1); 299 300 fnd: 301 bzero(s, sizeof(*s)); 302 netif_init(); 303 nif = netif_select(machdep_hint); 304 if (!nif) 305 panic("netboot: no interfaces left untried"); 306 if (netif_probe(nif, machdep_hint)) { 307 printf("netboot: couldn't probe %s%d\n", 308 nif->nif_driver->netif_bname, nif->nif_unit); 309 errno = EINVAL; 310 return(-1); 311 } 312 netif_attach(nif, s, machdep_hint); 313 314 return(fd); 315 } 316 317 int 318 netif_close(sock) 319 int sock; 320 { 321 if (sock >= SOPEN_MAX) { 322 errno = EBADF; 323 return(-1); 324 } 325 netif_detach(sockets[sock].io_netif); 326 sockets[sock].io_netif = (struct netif *)0; 327 328 return(0); 329 } 330