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