Home | History | Annotate | Line # | Download | only in libsa
netif.c revision 1.15.6.1
      1 /*	$NetBSD: netif.c,v 1.15.6.1 2002/01/08 00:32:53 nathanw 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