Home | History | Annotate | Line # | Download | only in netbsd32
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