xref: /minix3/sys/lib/libsa/netif.c (revision 58a2b0008e28f606a7f7f5faaeaba4faac57a1ea)
1*58a2b000SEvgeniy Ivanov /*	$NetBSD: netif.c,v 1.24 2009/01/17 14:00:36 tsutsui Exp $	*/
2*58a2b000SEvgeniy Ivanov 
3*58a2b000SEvgeniy Ivanov /*
4*58a2b000SEvgeniy Ivanov  * Copyright (c) 1993 Adam Glass
5*58a2b000SEvgeniy Ivanov  * All rights reserved.
6*58a2b000SEvgeniy Ivanov  *
7*58a2b000SEvgeniy Ivanov  * Redistribution and use in source and binary forms, with or without
8*58a2b000SEvgeniy Ivanov  * modification, are permitted provided that the following conditions
9*58a2b000SEvgeniy Ivanov  * are met:
10*58a2b000SEvgeniy Ivanov  * 1. Redistributions of source code must retain the above copyright
11*58a2b000SEvgeniy Ivanov  *    notice, this list of conditions and the following disclaimer.
12*58a2b000SEvgeniy Ivanov  * 2. Redistributions in binary form must reproduce the above copyright
13*58a2b000SEvgeniy Ivanov  *    notice, this list of conditions and the following disclaimer in the
14*58a2b000SEvgeniy Ivanov  *    documentation and/or other materials provided with the distribution.
15*58a2b000SEvgeniy Ivanov  * 3. All advertising materials mentioning features or use of this software
16*58a2b000SEvgeniy Ivanov  *    must display the following acknowledgement:
17*58a2b000SEvgeniy Ivanov  *	This product includes software developed by Adam Glass.
18*58a2b000SEvgeniy Ivanov  * 4. The name of the Author may not be used to endorse or promote products
19*58a2b000SEvgeniy Ivanov  *    derived from this software without specific prior written permission.
20*58a2b000SEvgeniy Ivanov  *
21*58a2b000SEvgeniy Ivanov  * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND
22*58a2b000SEvgeniy Ivanov  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23*58a2b000SEvgeniy Ivanov  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24*58a2b000SEvgeniy Ivanov  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25*58a2b000SEvgeniy Ivanov  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26*58a2b000SEvgeniy Ivanov  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27*58a2b000SEvgeniy Ivanov  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28*58a2b000SEvgeniy Ivanov  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29*58a2b000SEvgeniy Ivanov  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30*58a2b000SEvgeniy Ivanov  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*58a2b000SEvgeniy Ivanov  * SUCH DAMAGE.
32*58a2b000SEvgeniy Ivanov  */
33*58a2b000SEvgeniy Ivanov 
34*58a2b000SEvgeniy Ivanov #include <sys/param.h>
35*58a2b000SEvgeniy Ivanov #include <sys/cdefs.h>
36*58a2b000SEvgeniy Ivanov #include <sys/mount.h>
37*58a2b000SEvgeniy Ivanov #ifdef _STANDALONE
38*58a2b000SEvgeniy Ivanov #include <lib/libkern/libkern.h>
39*58a2b000SEvgeniy Ivanov #else
40*58a2b000SEvgeniy Ivanov #include <string.h>
41*58a2b000SEvgeniy Ivanov #endif
42*58a2b000SEvgeniy Ivanov 
43*58a2b000SEvgeniy Ivanov #include <netinet/in.h>
44*58a2b000SEvgeniy Ivanov #include <netinet/in_systm.h>
45*58a2b000SEvgeniy Ivanov 
46*58a2b000SEvgeniy Ivanov #include "stand.h"
47*58a2b000SEvgeniy Ivanov #include "netif.h"
48*58a2b000SEvgeniy Ivanov 
49*58a2b000SEvgeniy Ivanov struct iodesc sockets[SOPEN_MAX];
50*58a2b000SEvgeniy Ivanov #ifdef NETIF_DEBUG
51*58a2b000SEvgeniy Ivanov int netif_debug = 0;
52*58a2b000SEvgeniy Ivanov #endif
53*58a2b000SEvgeniy Ivanov 
54*58a2b000SEvgeniy Ivanov /*
55*58a2b000SEvgeniy Ivanov  * netif_init:
56*58a2b000SEvgeniy Ivanov  *
57*58a2b000SEvgeniy Ivanov  * initialize the generic network interface layer
58*58a2b000SEvgeniy Ivanov  */
59*58a2b000SEvgeniy Ivanov 
60*58a2b000SEvgeniy Ivanov void
61*58a2b000SEvgeniy Ivanov netif_init(void)
62*58a2b000SEvgeniy Ivanov {
63*58a2b000SEvgeniy Ivanov 	struct netif_driver *drv;
64*58a2b000SEvgeniy Ivanov 	int d, i;
65*58a2b000SEvgeniy Ivanov 
66*58a2b000SEvgeniy Ivanov #ifdef NETIF_DEBUG
67*58a2b000SEvgeniy Ivanov 	if (netif_debug)
68*58a2b000SEvgeniy Ivanov 		printf("netif_init: called\n");
69*58a2b000SEvgeniy Ivanov #endif
70*58a2b000SEvgeniy Ivanov 	for (d = 0; d < n_netif_drivers; d++) {
71*58a2b000SEvgeniy Ivanov 		drv = netif_drivers[d];
72*58a2b000SEvgeniy Ivanov 		for (i = 0; i < drv->netif_nifs; i++)
73*58a2b000SEvgeniy Ivanov 			drv->netif_ifs[i].dif_used = 0;
74*58a2b000SEvgeniy Ivanov 	}
75*58a2b000SEvgeniy Ivanov }
76*58a2b000SEvgeniy Ivanov 
77*58a2b000SEvgeniy Ivanov int	netif_match(struct netif *, void *);
78*58a2b000SEvgeniy Ivanov 
79*58a2b000SEvgeniy Ivanov int
80*58a2b000SEvgeniy Ivanov netif_match(struct netif *nif, void *machdep_hint)
81*58a2b000SEvgeniy Ivanov {
82*58a2b000SEvgeniy Ivanov 	struct netif_driver *drv = nif->nif_driver;
83*58a2b000SEvgeniy Ivanov 
84*58a2b000SEvgeniy Ivanov #if 0
85*58a2b000SEvgeniy Ivanov 	if (netif_debug)
86*58a2b000SEvgeniy Ivanov 		printf("%s%d: netif_match (%d)\n", drv->netif_bname,
87*58a2b000SEvgeniy Ivanov 		    nif->nif_unit, nif->nif_sel);
88*58a2b000SEvgeniy Ivanov #endif
89*58a2b000SEvgeniy Ivanov 	return drv->netif_match(nif, machdep_hint);
90*58a2b000SEvgeniy Ivanov }
91*58a2b000SEvgeniy Ivanov 
92*58a2b000SEvgeniy Ivanov struct netif *
93*58a2b000SEvgeniy Ivanov netif_select(void *machdep_hint)
94*58a2b000SEvgeniy Ivanov {
95*58a2b000SEvgeniy Ivanov 	int d, u, unit_done, s;
96*58a2b000SEvgeniy Ivanov 	struct netif_driver *drv;
97*58a2b000SEvgeniy Ivanov 	struct netif cur_if;
98*58a2b000SEvgeniy Ivanov 	static struct netif best_if;
99*58a2b000SEvgeniy Ivanov 	int best_val;
100*58a2b000SEvgeniy Ivanov 	int val;
101*58a2b000SEvgeniy Ivanov 
102*58a2b000SEvgeniy Ivanov 	best_val = 0;
103*58a2b000SEvgeniy Ivanov 	best_if.nif_driver = NULL;
104*58a2b000SEvgeniy Ivanov 
105*58a2b000SEvgeniy Ivanov #ifdef NETIF_DEBUG
106*58a2b000SEvgeniy Ivanov 	if (netif_debug)
107*58a2b000SEvgeniy Ivanov 		printf("netif_select: %d interfaces\n", n_netif_drivers);
108*58a2b000SEvgeniy Ivanov #endif
109*58a2b000SEvgeniy Ivanov 
110*58a2b000SEvgeniy Ivanov 	for (d = 0; d < n_netif_drivers; d++) {
111*58a2b000SEvgeniy Ivanov 		cur_if.nif_driver = netif_drivers[d];
112*58a2b000SEvgeniy Ivanov 		drv = cur_if.nif_driver;
113*58a2b000SEvgeniy Ivanov 
114*58a2b000SEvgeniy Ivanov 		for (u = 0; u < drv->netif_nifs; u++) {
115*58a2b000SEvgeniy Ivanov 			cur_if.nif_unit = u;
116*58a2b000SEvgeniy Ivanov 			unit_done = 0;
117*58a2b000SEvgeniy Ivanov 
118*58a2b000SEvgeniy Ivanov #ifdef NETIF_DEBUG
119*58a2b000SEvgeniy Ivanov 			if (netif_debug)
120*58a2b000SEvgeniy Ivanov 				printf("\t%s%d:", drv->netif_bname,
121*58a2b000SEvgeniy Ivanov 				    cur_if.nif_unit);
122*58a2b000SEvgeniy Ivanov #endif
123*58a2b000SEvgeniy Ivanov 
124*58a2b000SEvgeniy Ivanov 			for (s = 0; s < drv->netif_ifs[u].dif_nsel; s++) {
125*58a2b000SEvgeniy Ivanov 				cur_if.nif_sel = s;
126*58a2b000SEvgeniy Ivanov 
127*58a2b000SEvgeniy Ivanov 				if (drv->netif_ifs[u].dif_used & (1 << s)) {
128*58a2b000SEvgeniy Ivanov #ifdef NETIF_DEBUG
129*58a2b000SEvgeniy Ivanov 					if (netif_debug)
130*58a2b000SEvgeniy Ivanov 						printf(" [%d used]", s);
131*58a2b000SEvgeniy Ivanov #endif
132*58a2b000SEvgeniy Ivanov 					continue;
133*58a2b000SEvgeniy Ivanov 				}
134*58a2b000SEvgeniy Ivanov 
135*58a2b000SEvgeniy Ivanov 				val = netif_match(&cur_if, machdep_hint);
136*58a2b000SEvgeniy Ivanov #ifdef NETIF_DEBUG
137*58a2b000SEvgeniy Ivanov 				if (netif_debug)
138*58a2b000SEvgeniy Ivanov 					printf(" [%d -> %d]", s, val);
139*58a2b000SEvgeniy Ivanov #endif
140*58a2b000SEvgeniy Ivanov 				if (val > best_val) {
141*58a2b000SEvgeniy Ivanov 					best_val = val;
142*58a2b000SEvgeniy Ivanov 					best_if = cur_if;
143*58a2b000SEvgeniy Ivanov 				}
144*58a2b000SEvgeniy Ivanov 			}
145*58a2b000SEvgeniy Ivanov #ifdef NETIF_DEBUG
146*58a2b000SEvgeniy Ivanov 			if (netif_debug)
147*58a2b000SEvgeniy Ivanov 				printf("\n");
148*58a2b000SEvgeniy Ivanov #endif
149*58a2b000SEvgeniy Ivanov 		}
150*58a2b000SEvgeniy Ivanov 	}
151*58a2b000SEvgeniy Ivanov 
152*58a2b000SEvgeniy Ivanov 	if (best_if.nif_driver == NULL)
153*58a2b000SEvgeniy Ivanov 		return NULL;
154*58a2b000SEvgeniy Ivanov 
155*58a2b000SEvgeniy Ivanov 	best_if.nif_driver->
156*58a2b000SEvgeniy Ivanov 	    netif_ifs[best_if.nif_unit].dif_used |= (1 << best_if.nif_sel);
157*58a2b000SEvgeniy Ivanov 
158*58a2b000SEvgeniy Ivanov #ifdef NETIF_DEBUG
159*58a2b000SEvgeniy Ivanov 	if (netif_debug)
160*58a2b000SEvgeniy Ivanov 		printf("netif_select: %s%d(%d) wins\n",
161*58a2b000SEvgeniy Ivanov 			best_if.nif_driver->netif_bname,
162*58a2b000SEvgeniy Ivanov 			best_if.nif_unit, best_if.nif_sel);
163*58a2b000SEvgeniy Ivanov #endif
164*58a2b000SEvgeniy Ivanov 	return &best_if;
165*58a2b000SEvgeniy Ivanov }
166*58a2b000SEvgeniy Ivanov 
167*58a2b000SEvgeniy Ivanov int
168*58a2b000SEvgeniy Ivanov netif_probe(struct netif *nif, void *machdep_hint)
169*58a2b000SEvgeniy Ivanov {
170*58a2b000SEvgeniy Ivanov 	struct netif_driver *drv = nif->nif_driver;
171*58a2b000SEvgeniy Ivanov 
172*58a2b000SEvgeniy Ivanov #ifdef NETIF_DEBUG
173*58a2b000SEvgeniy Ivanov 	if (netif_debug)
174*58a2b000SEvgeniy Ivanov 		printf("%s%d: netif_probe\n", drv->netif_bname, nif->nif_unit);
175*58a2b000SEvgeniy Ivanov #endif
176*58a2b000SEvgeniy Ivanov 	return drv->netif_probe(nif, machdep_hint);
177*58a2b000SEvgeniy Ivanov }
178*58a2b000SEvgeniy Ivanov 
179*58a2b000SEvgeniy Ivanov void
180*58a2b000SEvgeniy Ivanov netif_attach(struct netif *nif, struct iodesc *desc, void *machdep_hint)
181*58a2b000SEvgeniy Ivanov {
182*58a2b000SEvgeniy Ivanov 	struct netif_driver *drv = nif->nif_driver;
183*58a2b000SEvgeniy Ivanov 
184*58a2b000SEvgeniy Ivanov #ifdef NETIF_DEBUG
185*58a2b000SEvgeniy Ivanov 	if (netif_debug)
186*58a2b000SEvgeniy Ivanov 		printf("%s%d: netif_attach\n", drv->netif_bname, nif->nif_unit);
187*58a2b000SEvgeniy Ivanov #endif
188*58a2b000SEvgeniy Ivanov 	desc->io_netif = nif;
189*58a2b000SEvgeniy Ivanov #ifdef PARANOID
190*58a2b000SEvgeniy Ivanov 	if (drv->netif_init == NULL)
191*58a2b000SEvgeniy Ivanov 		panic("%s%d: no netif_init support", drv->netif_bname,
192*58a2b000SEvgeniy Ivanov 		    nif->nif_unit);
193*58a2b000SEvgeniy Ivanov #endif
194*58a2b000SEvgeniy Ivanov 	drv->netif_init(desc, machdep_hint);
195*58a2b000SEvgeniy Ivanov 	(void)memset(drv->netif_ifs[nif->nif_unit].dif_stats, 0,
196*58a2b000SEvgeniy Ivanov 	    sizeof(struct netif_stats));
197*58a2b000SEvgeniy Ivanov }
198*58a2b000SEvgeniy Ivanov 
199*58a2b000SEvgeniy Ivanov void
200*58a2b000SEvgeniy Ivanov netif_detach(struct netif *nif)
201*58a2b000SEvgeniy Ivanov {
202*58a2b000SEvgeniy Ivanov 	struct netif_driver *drv = nif->nif_driver;
203*58a2b000SEvgeniy Ivanov 
204*58a2b000SEvgeniy Ivanov #ifdef NETIF_DEBUG
205*58a2b000SEvgeniy Ivanov 	if (netif_debug)
206*58a2b000SEvgeniy Ivanov 		printf("%s%d: netif_detach\n", drv->netif_bname, nif->nif_unit);
207*58a2b000SEvgeniy Ivanov #endif
208*58a2b000SEvgeniy Ivanov #ifdef PARANOID
209*58a2b000SEvgeniy Ivanov 	if (drv->netif_end == NULL)
210*58a2b000SEvgeniy Ivanov 		panic("%s%d: no netif_end support", drv->netif_bname,
211*58a2b000SEvgeniy Ivanov 		    nif->nif_unit);
212*58a2b000SEvgeniy Ivanov #endif
213*58a2b000SEvgeniy Ivanov 	drv->netif_end(nif);
214*58a2b000SEvgeniy Ivanov }
215*58a2b000SEvgeniy Ivanov 
216*58a2b000SEvgeniy Ivanov ssize_t
217*58a2b000SEvgeniy Ivanov netif_get(struct iodesc *desc, void *pkt, size_t len, saseconds_t timo)
218*58a2b000SEvgeniy Ivanov {
219*58a2b000SEvgeniy Ivanov 	struct netif *nif = desc->io_netif;
220*58a2b000SEvgeniy Ivanov 	struct netif_driver *drv = nif->nif_driver;
221*58a2b000SEvgeniy Ivanov 	ssize_t rv;
222*58a2b000SEvgeniy Ivanov 
223*58a2b000SEvgeniy Ivanov #ifdef NETIF_DEBUG
224*58a2b000SEvgeniy Ivanov 	if (netif_debug)
225*58a2b000SEvgeniy Ivanov 		printf("%s%d: netif_get\n", drv->netif_bname, nif->nif_unit);
226*58a2b000SEvgeniy Ivanov #endif
227*58a2b000SEvgeniy Ivanov #ifdef PARANOID
228*58a2b000SEvgeniy Ivanov 	if (drv->netif_get == NULL)
229*58a2b000SEvgeniy Ivanov 		panic("%s%d: no netif_get support", drv->netif_bname,
230*58a2b000SEvgeniy Ivanov 		    nif->nif_unit);
231*58a2b000SEvgeniy Ivanov #endif
232*58a2b000SEvgeniy Ivanov 	rv = drv->netif_get(desc, pkt, len, timo);
233*58a2b000SEvgeniy Ivanov #ifdef NETIF_DEBUG
234*58a2b000SEvgeniy Ivanov 	if (netif_debug)
235*58a2b000SEvgeniy Ivanov 		printf("%s%d: netif_get returning %d\n", drv->netif_bname,
236*58a2b000SEvgeniy Ivanov 		    nif->nif_unit, (int)rv);
237*58a2b000SEvgeniy Ivanov #endif
238*58a2b000SEvgeniy Ivanov 	return rv;
239*58a2b000SEvgeniy Ivanov }
240*58a2b000SEvgeniy Ivanov 
241*58a2b000SEvgeniy Ivanov ssize_t
242*58a2b000SEvgeniy Ivanov netif_put(struct iodesc *desc, void *pkt, size_t len)
243*58a2b000SEvgeniy Ivanov {
244*58a2b000SEvgeniy Ivanov 	struct netif *nif = desc->io_netif;
245*58a2b000SEvgeniy Ivanov 	struct netif_driver *drv = nif->nif_driver;
246*58a2b000SEvgeniy Ivanov 	ssize_t rv;
247*58a2b000SEvgeniy Ivanov 
248*58a2b000SEvgeniy Ivanov #ifdef NETIF_DEBUG
249*58a2b000SEvgeniy Ivanov 	if (netif_debug)
250*58a2b000SEvgeniy Ivanov 		printf("%s%d: netif_put\n", drv->netif_bname, nif->nif_unit);
251*58a2b000SEvgeniy Ivanov #endif
252*58a2b000SEvgeniy Ivanov #ifdef PARANOID
253*58a2b000SEvgeniy Ivanov 	if (drv->netif_put == NULL)
254*58a2b000SEvgeniy Ivanov 		panic("%s%d: no netif_put support", drv->netif_bname,
255*58a2b000SEvgeniy Ivanov 		    nif->nif_unit);
256*58a2b000SEvgeniy Ivanov #endif
257*58a2b000SEvgeniy Ivanov 	rv = drv->netif_put(desc, pkt, len);
258*58a2b000SEvgeniy Ivanov #ifdef NETIF_DEBUG
259*58a2b000SEvgeniy Ivanov 	if (netif_debug)
260*58a2b000SEvgeniy Ivanov 		printf("%s%d: netif_put returning %d\n", drv->netif_bname,
261*58a2b000SEvgeniy Ivanov 		    nif->nif_unit, (int)rv);
262*58a2b000SEvgeniy Ivanov #endif
263*58a2b000SEvgeniy Ivanov 	return rv;
264*58a2b000SEvgeniy Ivanov }
265*58a2b000SEvgeniy Ivanov 
266*58a2b000SEvgeniy Ivanov struct iodesc *
267*58a2b000SEvgeniy Ivanov socktodesc(int sock)
268*58a2b000SEvgeniy Ivanov {
269*58a2b000SEvgeniy Ivanov #if !defined(LIBSA_NO_FD_CHECKING)
270*58a2b000SEvgeniy Ivanov 	if (sock >= SOPEN_MAX) {
271*58a2b000SEvgeniy Ivanov 		errno = EBADF;
272*58a2b000SEvgeniy Ivanov 		return NULL;
273*58a2b000SEvgeniy Ivanov 	}
274*58a2b000SEvgeniy Ivanov #endif
275*58a2b000SEvgeniy Ivanov 	return &sockets[sock];
276*58a2b000SEvgeniy Ivanov }
277*58a2b000SEvgeniy Ivanov 
278*58a2b000SEvgeniy Ivanov int
279*58a2b000SEvgeniy Ivanov netif_open(void *machdep_hint)
280*58a2b000SEvgeniy Ivanov {
281*58a2b000SEvgeniy Ivanov 	int fd;
282*58a2b000SEvgeniy Ivanov 	struct iodesc *s;
283*58a2b000SEvgeniy Ivanov 	struct netif *nif;
284*58a2b000SEvgeniy Ivanov 
285*58a2b000SEvgeniy Ivanov 	/* find a free socket */
286*58a2b000SEvgeniy Ivanov 	for (fd = 0, s = sockets; fd < SOPEN_MAX; fd++, s++)
287*58a2b000SEvgeniy Ivanov 		if (s->io_netif == (struct netif *)0)
288*58a2b000SEvgeniy Ivanov 			goto fnd;
289*58a2b000SEvgeniy Ivanov 	errno = EMFILE;
290*58a2b000SEvgeniy Ivanov 	return -1;
291*58a2b000SEvgeniy Ivanov 
292*58a2b000SEvgeniy Ivanov fnd:
293*58a2b000SEvgeniy Ivanov 	(void)memset(s, 0, sizeof(*s));
294*58a2b000SEvgeniy Ivanov 	netif_init();
295*58a2b000SEvgeniy Ivanov 	nif = netif_select(machdep_hint);
296*58a2b000SEvgeniy Ivanov 	if (!nif)
297*58a2b000SEvgeniy Ivanov 		panic("netboot: no interfaces left untried");
298*58a2b000SEvgeniy Ivanov 	if (netif_probe(nif, machdep_hint)) {
299*58a2b000SEvgeniy Ivanov 		printf("netboot: couldn't probe %s%d\n",
300*58a2b000SEvgeniy Ivanov 		    nif->nif_driver->netif_bname, nif->nif_unit);
301*58a2b000SEvgeniy Ivanov 		errno = EINVAL;
302*58a2b000SEvgeniy Ivanov 		return -1;
303*58a2b000SEvgeniy Ivanov 	}
304*58a2b000SEvgeniy Ivanov 	netif_attach(nif, s, machdep_hint);
305*58a2b000SEvgeniy Ivanov 
306*58a2b000SEvgeniy Ivanov 	return fd;
307*58a2b000SEvgeniy Ivanov }
308*58a2b000SEvgeniy Ivanov 
309*58a2b000SEvgeniy Ivanov int
310*58a2b000SEvgeniy Ivanov netif_close(int sock)
311*58a2b000SEvgeniy Ivanov {
312*58a2b000SEvgeniy Ivanov #if !defined(LIBSA_NO_FD_CHECKING)
313*58a2b000SEvgeniy Ivanov 	if (sock >= SOPEN_MAX) {
314*58a2b000SEvgeniy Ivanov 		errno = EBADF;
315*58a2b000SEvgeniy Ivanov 		return -1;
316*58a2b000SEvgeniy Ivanov 	}
317*58a2b000SEvgeniy Ivanov #endif
318*58a2b000SEvgeniy Ivanov 	netif_detach(sockets[sock].io_netif);
319*58a2b000SEvgeniy Ivanov 	sockets[sock].io_netif = (struct netif *)0;
320*58a2b000SEvgeniy Ivanov 
321*58a2b000SEvgeniy Ivanov 	return 0;
322*58a2b000SEvgeniy Ivanov }
323