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