netbsd32_ioctl.c revision 1.5.4.1 1 /* $NetBSD: netbsd32_ioctl.c,v 1.5.4.1 2000/08/26 01:08:57 mrg Exp $ */
2
3 /*
4 * Copyright (c) 1998 Matthew R. Green
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. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31 /*
32 * handle ioctl conversions from netbsd32 -> sparc64
33 */
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/filedesc.h>
38 #include <sys/ioctl.h>
39 #include <sys/file.h>
40 #include <sys/proc.h>
41 #include <sys/socketvar.h>
42 #include <sys/audioio.h>
43 #include <sys/disklabel.h>
44 #include <sys/dkio.h>
45 #include <sys/malloc.h>
46 #include <sys/proc.h>
47 #include <sys/sockio.h>
48 #include <sys/socket.h>
49 #include <sys/ttycom.h>
50 #include <sys/mount.h>
51 #include <sys/syscallargs.h>
52
53 #include <machine/fbio.h>
54 #include <machine/openpromio.h>
55
56 #include <net/if.h>
57 #include <net/route.h>
58
59 #include <netinet/in.h>
60 #include <netinet/in_var.h>
61 #include <netinet/igmp.h>
62 #include <netinet/igmp_var.h>
63 #include <netinet/ip_mroute.h>
64
65 #include <compat/netbsd32/netbsd32.h>
66 #include <compat/netbsd32/netbsd32_ioctl.h>
67 #include <compat/netbsd32/netbsd32_syscallargs.h>
68
69
70 void
71 netbsd32_to_fbcmap(s32p, p, cmd)
72 struct netbsd32_fbcmap *s32p;
73 struct fbcmap *p;
74 u_long cmd;
75 {
76
77 p->index = s32p->index;
78 p->count = s32p->count;
79 p->red = (u_char *)(u_long)s32p->red;
80 p->green = (u_char *)(u_long)s32p->green;
81 p->blue = (u_char *)(u_long)s32p->blue;
82 }
83
84 void
85 netbsd32_to_fbcursor(s32p, p, cmd)
86 struct netbsd32_fbcursor *s32p;
87 struct fbcursor *p;
88 u_long cmd;
89 {
90
91 p->set = s32p->set;
92 p->enable = s32p->enable;
93 p->pos = s32p->pos;
94 p->hot = s32p->hot;
95 netbsd32_to_fbcmap(&s32p->cmap, &p->cmap, cmd);
96 p->size = s32p->size;
97 p->image = (char *)(u_long)s32p->image;
98 p->mask = (char *)(u_long)s32p->mask;
99 }
100
101 void
102 netbsd32_to_opiocdesc(s32p, p, cmd)
103 struct netbsd32_opiocdesc *s32p;
104 struct opiocdesc *p;
105 u_long cmd;
106 {
107
108 p->op_nodeid = s32p->op_nodeid;
109 p->op_namelen = s32p->op_namelen;
110 p->op_name = (char *)(u_long)s32p->op_name;
111 p->op_buflen = s32p->op_buflen;
112 p->op_buf = (char *)(u_long)s32p->op_buf;
113 }
114
115 void
116 netbsd32_to_partinfo(s32p, p, cmd)
117 struct netbsd32_partinfo *s32p;
118 struct partinfo *p;
119 u_long cmd;
120 {
121
122 p->disklab = (struct disklabel *)(u_long)s32p->disklab;
123 p->part = (struct partition *)(u_long)s32p->part;
124 }
125
126 void
127 netbsd32_to_format_op(s32p, p, cmd)
128 struct netbsd32_format_op *s32p;
129 struct format_op *p;
130 u_long cmd;
131 {
132
133 p->df_buf = (char *)(u_long)s32p->df_buf;
134 p->df_count = s32p->df_count;
135 p->df_startblk = s32p->df_startblk;
136 memcpy(p->df_reg, s32p->df_reg, sizeof(s32p->df_reg));
137 }
138
139 #if 0 /* XXX see below */
140 void
141 netbsd32_to_ifreq(s32p, p, cmd)
142 struct netbsd32_ifreq *s32p;
143 struct ifreq *p;
144 u_long cmd; /* XXX unused yet */
145 {
146
147 /*
148 * XXX
149 * struct ifreq says the same, but sometimes the ifr_data
150 * union member needs to be converted to 64 bits... this
151 * is very driver specific and so we ignore it for now..
152 */
153 memcpy(p, s32p, sizeof *s32p);
154 }
155 #endif
156
157 void
158 netbsd32_to_ifconf(s32p, p, cmd)
159 struct netbsd32_ifconf *s32p;
160 struct ifconf *p;
161 u_long cmd;
162 {
163
164 p->ifc_len = s32p->ifc_len;
165 /* ifc_buf & ifc_req are the same size so this works */
166 p->ifc_buf = (caddr_t)(u_long)s32p->ifc_buf;
167 }
168
169 void
170 netbsd32_to_ifmediareq(s32p, p, cmd)
171 struct netbsd32_ifmediareq *s32p;
172 struct ifmediareq *p;
173 u_long cmd;
174 {
175
176 memcpy(p, s32p, sizeof *s32p);
177 p->ifm_ulist = (int *)(u_long)s32p->ifm_ulist;
178 }
179
180 void
181 netbsd32_to_ifdrv(s32p, p, cmd)
182 struct netbsd32_ifdrv *s32p;
183 struct ifdrv *p;
184 u_long cmd;
185 {
186
187 memcpy(p, s32p, sizeof *s32p);
188 p->ifd_data = (void *)(u_long)s32p->ifd_data;
189 }
190
191 void
192 netbsd32_to_sioc_vif_req(s32p, p, cmd)
193 struct netbsd32_sioc_vif_req *s32p;
194 struct sioc_vif_req *p;
195 u_long cmd;
196 {
197
198 p->vifi = s32p->vifi;
199 p->icount = (u_long)s32p->icount;
200 p->ocount = (u_long)s32p->ocount;
201 p->ibytes = (u_long)s32p->ibytes;
202 p->obytes = (u_long)s32p->obytes;
203 }
204
205 void
206 netbsd32_to_sioc_sg_req(s32p, p, cmd)
207 struct netbsd32_sioc_sg_req *s32p;
208 struct sioc_sg_req *p;
209 u_long cmd;
210 {
211
212 p->src = s32p->src;
213 p->grp = s32p->grp;
214 p->pktcnt = (u_long)s32p->pktcnt;
215 p->bytecnt = (u_long)s32p->bytecnt;
216 p->wrong_if = (u_long)s32p->wrong_if;
217 }
218
219 /*
220 * handle ioctl conversions from sparc64 -> netbsd32
221 */
222
223 void
224 netbsd32_from_fbcmap(p, s32p)
225 struct fbcmap *p;
226 struct netbsd32_fbcmap *s32p;
227 {
228
229 s32p->index = p->index;
230 s32p->count = p->count;
231 /* filled in */
232 #if 0
233 s32p->red = (netbsd32_u_charp)p->red;
234 s32p->green = (netbsd32_u_charp)p->green;
235 s32p->blue = (netbsd32_u_charp)p->blue;
236 #endif
237 }
238
239 void
240 netbsd32_from_fbcursor(p, s32p)
241 struct fbcursor *p;
242 struct netbsd32_fbcursor *s32p;
243 {
244
245 s32p->set = p->set;
246 s32p->enable = p->enable;
247 s32p->pos = p->pos;
248 s32p->hot = p->hot;
249 netbsd32_from_fbcmap(&p->cmap, &s32p->cmap);
250 s32p->size = p->size;
251 /* filled in */
252 #if 0
253 s32p->image = (netbsd32_charp)p->image;
254 s32p->mask = (netbsd32_charp)p->mask;
255 #endif
256 }
257
258 void
259 netbsd32_from_opiocdesc(p, s32p)
260 struct opiocdesc *p;
261 struct netbsd32_opiocdesc *s32p;
262 {
263
264 s32p->op_nodeid = p->op_nodeid;
265 s32p->op_namelen = p->op_namelen;
266 s32p->op_name = (netbsd32_charp)(u_long)p->op_name;
267 s32p->op_buflen = p->op_buflen;
268 s32p->op_buf = (netbsd32_charp)(u_long)p->op_buf;
269 }
270
271 void
272 netbsd32_from_partinfo(p, s32p)
273 struct partinfo *p;
274 struct netbsd32_partinfo *s32p;
275 {
276
277 s32p->disklab = (netbsd32_disklabel_tp_t)(u_long)p->disklab;
278 s32p->part = s32p->part;
279 }
280
281 void
282 netbsd32_from_format_op(p, s32p)
283 struct format_op *p;
284 struct netbsd32_format_op *s32p;
285 {
286
287 /* filled in */
288 #if 0
289 s32p->df_buf = (netbsd32_charp)p->df_buf;
290 #endif
291 s32p->df_count = p->df_count;
292 s32p->df_startblk = p->df_startblk;
293 memcpy(s32p->df_reg, p->df_reg, sizeof(p->df_reg));
294 }
295
296 #if 0 /* XXX see below */
297 void
298 netbsd32_from_ifreq(p, s32p, cmd)
299 struct ifreq *p;
300 struct netbsd32_ifreq *s32p;
301 u_long cmd; /* XXX unused yet */
302 {
303
304 /*
305 * XXX
306 * struct ifreq says the same, but sometimes the ifr_data
307 * union member needs to be converted to 64 bits... this
308 * is very driver specific and so we ignore it for now..
309 */
310 *s32p = *p;
311 }
312 #endif
313
314 void
315 netbsd32_from_ifconf(p, s32p)
316 struct ifconf *p;
317 struct netbsd32_ifconf *s32p;
318 {
319
320 s32p->ifc_len = p->ifc_len;
321 /* ifc_buf & ifc_req are the same size so this works */
322 s32p->ifc_buf = (netbsd32_caddr_t)(u_long)p->ifc_buf;
323 }
324
325 void
326 netbsd32_from_ifmediareq(p, s32p)
327 struct ifmediareq *p;
328 struct netbsd32_ifmediareq *s32p;
329 {
330
331 memcpy(s32p, p, sizeof *p);
332 /* filled in? */
333 #if 0
334 s32p->ifm_ulist = (netbsd32_intp_t)p->ifm_ulist;
335 #endif
336 }
337
338 void
339 netbsd32_from_ifdrv(p, s32p)
340 struct ifdrv *p;
341 struct netbsd32_ifdrv *s32p;
342 {
343
344 memcpy(s32p, p, sizeof *p);
345 /* filled in? */
346 #if 0
347 s32p->ifm_data = (netbsd32_u_longp_t)p->ifm_data;
348 #endif
349 }
350
351 void
352 netbsd32_from_sioc_vif_req(p, s32p)
353 struct sioc_vif_req *p;
354 struct netbsd32_sioc_vif_req *s32p;
355 {
356
357 s32p->vifi = p->vifi;
358 s32p->icount = (netbsd32_u_long)p->icount;
359 s32p->ocount = (netbsd32_u_long)p->ocount;
360 s32p->ibytes = (netbsd32_u_long)p->ibytes;
361 s32p->obytes = (netbsd32_u_long)p->obytes;
362 }
363
364 void
365 netbsd32_from_sioc_sg_req(p, s32p)
366 struct sioc_sg_req *p;
367 struct netbsd32_sioc_sg_req *s32p;
368 {
369
370 s32p->src = p->src;
371 s32p->grp = p->grp;
372 s32p->pktcnt = (netbsd32_u_long)p->pktcnt;
373 s32p->bytecnt = (netbsd32_u_long)p->bytecnt;
374 s32p->wrong_if = (netbsd32_u_long)p->wrong_if;
375 }
376
377
378 /*
379 * main ioctl syscall.
380 *
381 * ok, here we are in the biggy. we have to do fix ups depending
382 * on the ioctl command before and afterwards.
383 */
384 int
385 netbsd32_ioctl(p, v, retval)
386 struct proc *p;
387 void *v;
388 register_t *retval;
389 {
390 struct netbsd32_ioctl_args /* {
391 syscallarg(int) fd;
392 syscallarg(netbsd32_u_long) com;
393 syscallarg(netbsd32_voidp) data;
394 } */ *uap = v;
395 struct file *fp;
396 struct filedesc *fdp;
397 u_long com;
398 int error = 0;
399 u_int size, size32;
400 caddr_t data, memp = NULL;
401 caddr_t data32, memp32 = NULL;
402 int tmp;
403 #define STK_PARAMS 128
404 u_long stkbuf[STK_PARAMS/sizeof(u_long)];
405 u_long stkbuf32[STK_PARAMS/sizeof(u_long)];
406
407 /*
408 * we need to translate some commands (_IOW) before calling sys_ioctl,
409 * some after (_IOR), and some both (_IOWR).
410 */
411 #if 0
412 {
413 char *dirs[8] = { "NONE!", "VOID", "OUT", "VOID|OUT!", "IN", "VOID|IN!",
414 "INOUT", "VOID|IN|OUT!" };
415
416 printf("netbsd32_ioctl(%d, %x, %x): %s group %c base %d len %d\n",
417 SCARG(uap, fd), SCARG(uap, com), SCARG(uap, data),
418 dirs[((SCARG(uap, com) & IOC_DIRMASK)>>29)],
419 IOCGROUP(SCARG(uap, com)), IOCBASECMD(SCARG(uap, com)),
420 IOCPARM_LEN(SCARG(uap, com)));
421 }
422 #endif
423
424 fdp = p->p_fd;
425 if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
426 (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL ||
427 (fp->f_iflags & FIF_WANTCLOSE) != 0)
428 return (EBADF);
429
430 FILE_USE(fp);
431
432 if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
433 error = EBADF;
434 goto out;
435 }
436
437 switch (com = SCARG(uap, com)) {
438 case FIONCLEX:
439 fdp->fd_ofileflags[SCARG(uap, fd)] &= ~UF_EXCLOSE;
440 goto out;
441
442 case FIOCLEX:
443 fdp->fd_ofileflags[SCARG(uap, fd)] |= UF_EXCLOSE;
444 goto out;
445 }
446
447 /*
448 * Interpret high order word to find amount of data to be
449 * copied to/from the user's address space.
450 */
451 size32 = IOCPARM_LEN(com);
452 if (size32 > IOCPARM_MAX) {
453 error = ENOTTY;
454 goto out;
455 }
456 memp = NULL;
457 if (size32 > sizeof(stkbuf)) {
458 memp32 = (caddr_t)malloc((u_long)size32, M_IOCTLOPS, M_WAITOK);
459 data32 = memp32;
460 } else
461 data32 = (caddr_t)stkbuf32;
462 if (com&IOC_IN) {
463 if (size32) {
464 error = copyin((caddr_t)(u_long)SCARG(uap, data),
465 data32, size32);
466 if (error) {
467 if (memp32)
468 free(memp32, M_IOCTLOPS);
469 goto out;
470 }
471 } else
472 *(caddr_t *)data32 = (caddr_t)(u_long)SCARG(uap, data);
473 } else if ((com&IOC_OUT) && size32)
474 /*
475 * Zero the buffer so the user always
476 * gets back something deterministic.
477 */
478 memset(data32, 0, size32);
479 else if (com&IOC_VOID)
480 *(caddr_t *)data = (caddr_t)(u_long)SCARG(uap, data);
481
482 /* we define some handy macros here... */
483 #define IOCTL_STRUCT_CONV_TO(cmd, type) \
484 com = cmd; \
485 size = IOCPARM_LEN(com); \
486 if (size > sizeof(stkbuf)) \
487 data = memp = malloc(size, M_IOCTLOPS, M_WAITOK); \
488 else \
489 data = (caddr_t)stkbuf; \
490 __CONCAT(netbsd32_to_, type)((struct __CONCAT(netbsd32_, type) *) \
491 data32, (struct type *)data, com); \
492 error = (*fp->f_ops->fo_ioctl)(fp, com, data, p); \
493 __CONCAT(netbsd32_from_, type)((struct type *)data, \
494 (struct __CONCAT(netbsd32_, type) *)data32); \
495 break
496
497 /*
498 * convert various structures, pointers, and other objects that
499 * change size from 32 bit -> 64 bit, for all ioctl commands.
500 */
501 switch (SCARG(uap, com)) {
502 case FIONBIO:
503 if ((tmp = *(int *)data) != 0)
504 fp->f_flag |= FNONBLOCK;
505 else
506 fp->f_flag &= ~FNONBLOCK;
507 error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p);
508 break;
509
510 case FIOASYNC:
511 if ((tmp = *(int *)data) != 0)
512 fp->f_flag |= FASYNC;
513 else
514 fp->f_flag &= ~FASYNC;
515 error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p);
516 break;
517
518 case FIOSETOWN:
519 tmp = *(int *)data;
520 if (fp->f_type == DTYPE_SOCKET) {
521 ((struct socket *)fp->f_data)->so_pgid = tmp;
522 error = 0;
523 break;
524 }
525 if (tmp <= 0) {
526 tmp = -tmp;
527 } else {
528 struct proc *p1 = pfind(tmp);
529 if (p1 == 0) {
530 error = ESRCH;
531 break;
532 }
533 tmp = p1->p_pgrp->pg_id;
534 }
535 error = (*fp->f_ops->fo_ioctl)
536 (fp, TIOCSPGRP, (caddr_t)&tmp, p);
537 break;
538
539 case FIOGETOWN:
540 if (fp->f_type == DTYPE_SOCKET) {
541 error = 0;
542 *(int *)data = ((struct socket *)fp->f_data)->so_pgid;
543 break;
544 }
545 error = (*fp->f_ops->fo_ioctl)(fp, TIOCGPGRP, data, p);
546 *(int *)data = -*(int *)data;
547 break;
548
549 /*
550 * Here are calls that need explicit conversion.
551 */
552 case FBIOPUTCMAP32:
553 IOCTL_STRUCT_CONV_TO(FBIOPUTCMAP, fbcmap);
554 case FBIOGETCMAP32:
555 IOCTL_STRUCT_CONV_TO(FBIOGETCMAP, fbcmap);
556
557 case FBIOSCURSOR32:
558 IOCTL_STRUCT_CONV_TO(FBIOSCURSOR, fbcursor);
559 case FBIOGCURSOR32:
560 IOCTL_STRUCT_CONV_TO(FBIOGCURSOR, fbcursor);
561
562 case OPIOCGET32:
563 IOCTL_STRUCT_CONV_TO(OPIOCGET, opiocdesc);
564 case OPIOCSET32:
565 IOCTL_STRUCT_CONV_TO(OPIOCSET, opiocdesc);
566 case OPIOCNEXTPROP32:
567 IOCTL_STRUCT_CONV_TO(OPIOCNEXTPROP, opiocdesc);
568
569 case DIOCGPART32:
570 IOCTL_STRUCT_CONV_TO(DIOCGPART, partinfo);
571
572 case DIOCRFORMAT32:
573 IOCTL_STRUCT_CONV_TO(DIOCRFORMAT, format_op);
574 case DIOCWFORMAT32:
575 IOCTL_STRUCT_CONV_TO(DIOCWFORMAT, format_op);
576
577 /*
578 * only a few ifreq syscalls need conversion and those are
579 * all driver specific... XXX
580 */
581 #if 0
582 case SIOCGADDRROM3232:
583 IOCTL_STRUCT_CONV_TO(SIOCGADDRROM32, ifreq);
584 case SIOCGCHIPID32:
585 IOCTL_STRUCT_CONV_TO(SIOCGCHIPID, ifreq);
586 case SIOCSIFADDR32:
587 IOCTL_STRUCT_CONV_TO(SIOCSIFADDR, ifreq);
588 case OSIOCGIFADDR32:
589 IOCTL_STRUCT_CONV_TO(OSIOCGIFADDR, ifreq);
590 case SIOCGIFADDR32:
591 IOCTL_STRUCT_CONV_TO(SIOCGIFADDR, ifreq);
592 case SIOCSIFDSTADDR32:
593 IOCTL_STRUCT_CONV_TO(SIOCSIFDSTADDR, ifreq);
594 case OSIOCGIFDSTADDR32:
595 IOCTL_STRUCT_CONV_TO(OSIOCGIFDSTADDR, ifreq);
596 case SIOCGIFDSTADDR32:
597 IOCTL_STRUCT_CONV_TO(SIOCGIFDSTADDR, ifreq);
598 case SIOCSIFFLAGS32:
599 IOCTL_STRUCT_CONV_TO(SIOCSIFFLAGS, ifreq);
600 case SIOCGIFFLAGS32:
601 IOCTL_STRUCT_CONV_TO(SIOCGIFFLAGS, ifreq);
602 case OSIOCGIFBRDADDR32:
603 IOCTL_STRUCT_CONV_TO(OSIOCGIFBRDADDR, ifreq);
604 case SIOCGIFBRDADDR32:
605 IOCTL_STRUCT_CONV_TO(SIOCGIFBRDADDR, ifreq);
606 case SIOCSIFBRDADDR32:
607 IOCTL_STRUCT_CONV_TO(SIOCSIFBRDADDR, ifreq);
608 case OSIOCGIFNETMASK32:
609 IOCTL_STRUCT_CONV_TO(OSIOCGIFNETMASK, ifreq);
610 case SIOCGIFNETMASK32:
611 IOCTL_STRUCT_CONV_TO(SIOCGIFNETMASK, ifreq);
612 case SIOCSIFNETMASK32:
613 IOCTL_STRUCT_CONV_TO(SIOCSIFNETMASK, ifreq);
614 case SIOCGIFMETRIC32:
615 IOCTL_STRUCT_CONV_TO(SIOCGIFMETRIC, ifreq);
616 case SIOCSIFMETRIC32:
617 IOCTL_STRUCT_CONV_TO(SIOCSIFMETRIC, ifreq);
618 case SIOCDIFADDR32:
619 IOCTL_STRUCT_CONV_TO(SIOCDIFADDR, ifreq);
620 case SIOCADDMULTI32:
621 IOCTL_STRUCT_CONV_TO(SIOCADDMULTI, ifreq);
622 case SIOCDELMULTI32:
623 IOCTL_STRUCT_CONV_TO(SIOCDELMULTI, ifreq);
624 case SIOCSIFMEDIA32:
625 IOCTL_STRUCT_CONV_TO(SIOCSIFMEDIA, ifreq);
626 case SIOCSIFMTU32:
627 IOCTL_STRUCT_CONV_TO(SIOCSIFMTU, ifreq);
628 case SIOCGIFMTU32:
629 IOCTL_STRUCT_CONV_TO(SIOCGIFMTU, ifreq);
630 case SIOCSIFASYNCMAP32:
631 IOCTL_STRUCT_CONV_TO(SIOCSIFASYNCMAP, ifreq);
632 case SIOCGIFASYNCMAP32:
633 IOCTL_STRUCT_CONV_TO(SIOCGIFASYNCMAP, ifreq);
634 /* IOCTL_STRUCT_CONV_TO(BIOCGETIF, ifreq); READ ONLY */
635 case BIOCSETIF32:
636 IOCTL_STRUCT_CONV_TO(BIOCSETIF, ifreq);
637 case SIOCPHASE132:
638 IOCTL_STRUCT_CONV_TO(SIOCPHASE1, ifreq);
639 case SIOCPHASE232:
640 IOCTL_STRUCT_CONV_TO(SIOCPHASE2, ifreq);
641 #endif
642
643 case OSIOCGIFCONF32:
644 IOCTL_STRUCT_CONV_TO(OSIOCGIFCONF, ifconf);
645 case SIOCGIFCONF32:
646 IOCTL_STRUCT_CONV_TO(SIOCGIFCONF, ifconf);
647
648 case SIOCGIFMEDIA32:
649 IOCTL_STRUCT_CONV_TO(SIOCGIFMEDIA, ifmediareq);
650
651 case SIOCSDRVSPEC32:
652 IOCTL_STRUCT_CONV_TO(SIOCSDRVSPEC, ifdrv);
653
654 case SIOCGETVIFCNT32:
655 IOCTL_STRUCT_CONV_TO(SIOCGETVIFCNT, sioc_vif_req);
656
657 case SIOCGETSGCNT32:
658 IOCTL_STRUCT_CONV_TO(SIOCGETSGCNT, sioc_sg_req);
659
660 default:
661 error = (*fp->f_ops->fo_ioctl)(fp, com, data32, p);
662 break;
663 }
664
665 /*
666 * Copy any data to user, size was
667 * already set and checked above.
668 */
669 if (error == 0 && (com&IOC_OUT) && size32)
670 error = copyout(data32, (caddr_t)(u_long)SCARG(uap, data), size32);
671
672 /* if we malloced data, free it here */
673 if (memp32)
674 free(memp32, M_IOCTLOPS);
675 if (memp)
676 free(memp, M_IOCTLOPS);
677
678 out:
679 FILE_UNUSE(fp, p);
680 return (error);
681 }
682