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