1 /* 2 * Copyright (c) 1993 Markus Wild. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. The name of the author may not be used to endorse or promote products 11 * derived from this software without specific prior written permission 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * 24 * loosely from: Header: sun_ioctl.c,v 1.7 93/05/28 04:40:43 torek Exp 25 * $Id: sunos_ioctl.c,v 1.10 1994/05/21 08:22:08 deraadt Exp $ 26 */ 27 28 #include <sys/param.h> 29 #include <sys/proc.h> 30 #include <sys/file.h> 31 #include <sys/filedesc.h> 32 #include <sys/ioctl.h> 33 #include <sys/termios.h> 34 #include <sys/tty.h> 35 #include <sys/socket.h> 36 #include <sys/ioctl.h> 37 #include <net/if.h> 38 39 /* 40 * SunOS ioctl calls. 41 * This file is something of a hodge-podge. 42 * Support gets added as things turn up.... 43 */ 44 45 struct sun_ttysize { 46 int ts_row; 47 int ts_col; 48 }; 49 50 struct sun_termio { 51 u_short c_iflag; 52 u_short c_oflag; 53 u_short c_cflag; 54 u_short c_lflag; 55 char c_line; 56 unsigned char c_cc[8]; 57 }; 58 #define SUN_TCGETA _IOR('T', 1, struct sun_termio) 59 #define SUN_TCSETA _IOW('T', 2, struct sun_termio) 60 #define SUN_TCSETAW _IOW('T', 3, struct sun_termio) 61 #define SUN_TCSETAF _IOW('T', 4, struct sun_termio) 62 #define SUN_TCSBRK _IO('T', 5) 63 64 struct sun_termios { 65 u_long c_iflag; 66 u_long c_oflag; 67 u_long c_cflag; 68 u_long c_lflag; 69 char c_line; 70 u_char c_cc[17]; 71 }; 72 #define SUN_TCXONC _IO('T', 6) 73 #define SUN_TCFLSH _IO('T', 7) 74 #define SUN_TCGETS _IOR('T', 8, struct sun_termios) 75 #define SUN_TCSETS _IOW('T', 9, struct sun_termios) 76 #define SUN_TCSETSW _IOW('T', 10, struct sun_termios) 77 #define SUN_TCSETSF _IOW('T', 11, struct sun_termios) 78 #define SUN_TCSNDBRK _IO('T', 12) 79 #define SUN_TCDRAIN _IO('T', 13) 80 81 static struct speedtab sptab[] = { 82 { 0, 0 }, 83 { 50, 1 }, 84 { 75, 2 }, 85 { 110, 3 }, 86 { 134, 4 }, 87 { 135, 4 }, 88 { 150, 5 }, 89 { 200, 6 }, 90 { 300, 7 }, 91 { 600, 8 }, 92 { 1200, 9 }, 93 { 1800, 10 }, 94 { 2400, 11 }, 95 { 4800, 12 }, 96 { 9600, 13 }, 97 { 19200, 14 }, 98 { 38400, 15 }, 99 { -1, -1 } 100 }; 101 102 static u_long s2btab[] = { 103 0, 104 50, 105 75, 106 110, 107 134, 108 150, 109 200, 110 300, 111 600, 112 1200, 113 1800, 114 2400, 115 4800, 116 9600, 117 19200, 118 38400, 119 }; 120 121 /* 122 * these two conversion functions have mostly been done 123 * with some perl cut&paste, then handedited to comment 124 * out what doesn't exist under NetBSD. 125 * A note from Markus's code: 126 * (l & BITMASK1) / BITMASK1 * BITMASK2 is translated 127 * optimally by gcc m68k, much better than any ?: stuff. 128 * Code may vary with different architectures of course. 129 * 130 * I don't know what optimizer you used, but seeing divu's and 131 * bfextu's in the m68k assembly output did not encourage me... 132 * as well, gcc on the sparc definately generates much better 133 * code with ?:. 134 */ 135 136 static void 137 stios2btios(st, bt) 138 struct sun_termios *st; 139 struct termios *bt; 140 { 141 register u_long l, r; 142 143 l = st->c_iflag; 144 r = ((l & 0x00000001) ? IGNBRK : 0); 145 r |= ((l & 0x00000002) ? BRKINT : 0); 146 r |= ((l & 0x00000004) ? IGNPAR : 0); 147 r |= ((l & 0x00000008) ? PARMRK : 0); 148 r |= ((l & 0x00000010) ? INPCK : 0); 149 r |= ((l & 0x00000020) ? ISTRIP : 0); 150 r |= ((l & 0x00000040) ? INLCR : 0); 151 r |= ((l & 0x00000080) ? IGNCR : 0); 152 r |= ((l & 0x00000100) ? ICRNL : 0); 153 /* ((l & 0x00000200) ? IUCLC : 0) */ 154 r |= ((l & 0x00000400) ? IXON : 0); 155 r |= ((l & 0x00000800) ? IXANY : 0); 156 r |= ((l & 0x00001000) ? IXOFF : 0); 157 r |= ((l & 0x00002000) ? IMAXBEL : 0); 158 bt->c_iflag = r; 159 160 l = st->c_oflag; 161 r = ((l & 0x00000001) ? OPOST : 0); 162 /* ((l & 0x00000002) ? OLCUC : 0) */ 163 r |= ((l & 0x00000004) ? ONLCR : 0); 164 /* ((l & 0x00000008) ? OCRNL : 0) */ 165 /* ((l & 0x00000010) ? ONOCR : 0) */ 166 /* ((l & 0x00000020) ? ONLRET : 0) */ 167 /* ((l & 0x00000040) ? OFILL : 0) */ 168 /* ((l & 0x00000080) ? OFDEL : 0) */ 169 /* ((l & 0x00000100) ? NLDLY : 0) */ 170 /* ((l & 0x00000100) ? NL1 : 0) */ 171 /* ((l & 0x00000600) ? CRDLY : 0) */ 172 /* ((l & 0x00000200) ? CR1 : 0) */ 173 /* ((l & 0x00000400) ? CR2 : 0) */ 174 /* ((l & 0x00000600) ? CR3 : 0) */ 175 /* ((l & 0x00001800) ? TABDLY : 0) */ 176 /* ((l & 0x00000800) ? TAB1 : 0) */ 177 /* ((l & 0x00001000) ? TAB2 : 0) */ 178 r |= ((l & 0x00001800) ? OXTABS : 0); 179 /* ((l & 0x00002000) ? BSDLY : 0) */ 180 /* ((l & 0x00002000) ? BS1 : 0) */ 181 /* ((l & 0x00004000) ? VTDLY : 0) */ 182 /* ((l & 0x00004000) ? VT1 : 0) */ 183 /* ((l & 0x00008000) ? FFDLY : 0) */ 184 /* ((l & 0x00008000) ? FF1 : 0) */ 185 /* ((l & 0x00010000) ? PAGEOUT : 0) */ 186 /* ((l & 0x00020000) ? WRAP : 0) */ 187 bt->c_oflag = r; 188 189 l = st->c_cflag; 190 r = ((l & 0x00000010) ? CS6 : 0); 191 r |= ((l & 0x00000020) ? CS7 : 0); 192 r |= ((l & 0x00000030) ? CS8 : 0); 193 r |= ((l & 0x00000040) ? CSTOPB : 0); 194 r |= ((l & 0x00000080) ? CREAD : 0); 195 r |= ((l & 0x00000100) ? PARENB : 0); 196 r |= ((l & 0x00000200) ? PARODD : 0); 197 r |= ((l & 0x00000400) ? HUPCL : 0); 198 r |= ((l & 0x00000800) ? CLOCAL : 0); 199 /* ((l & 0x00001000) ? LOBLK : 0) */ 200 r |= ((l & 0x80000000) ? (CRTS_IFLOW|CCTS_OFLOW) : 0); 201 bt->c_cflag = r; 202 203 bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f]; 204 205 l = st->c_lflag; 206 r = ((l & 0x00000001) ? ISIG : 0); 207 r |= ((l & 0x00000002) ? ICANON : 0); 208 /* ((l & 0x00000004) ? XCASE : 0) */ 209 r |= ((l & 0x00000008) ? ECHO : 0); 210 r |= ((l & 0x00000010) ? ECHOE : 0); 211 r |= ((l & 0x00000020) ? ECHOK : 0); 212 r |= ((l & 0x00000040) ? ECHONL : 0); 213 r |= ((l & 0x00000080) ? NOFLSH : 0); 214 r |= ((l & 0x00000100) ? TOSTOP : 0); 215 r |= ((l & 0x00000200) ? ECHOCTL : 0); 216 r |= ((l & 0x00000400) ? ECHOPRT : 0); 217 r |= ((l & 0x00000800) ? ECHOKE : 0); 218 /* ((l & 0x00001000) ? DEFECHO : 0) */ 219 r |= ((l & 0x00002000) ? FLUSHO : 0); 220 r |= ((l & 0x00004000) ? PENDIN : 0); 221 bt->c_lflag = r; 222 223 bt->c_cc[VINTR] = st->c_cc[0] ? st->c_cc[0] : _POSIX_VDISABLE; 224 bt->c_cc[VQUIT] = st->c_cc[1] ? st->c_cc[1] : _POSIX_VDISABLE; 225 bt->c_cc[VERASE] = st->c_cc[2] ? st->c_cc[2] : _POSIX_VDISABLE; 226 bt->c_cc[VKILL] = st->c_cc[3] ? st->c_cc[3] : _POSIX_VDISABLE; 227 bt->c_cc[VEOF] = st->c_cc[4] ? st->c_cc[4] : _POSIX_VDISABLE; 228 bt->c_cc[VEOL] = st->c_cc[5] ? st->c_cc[5] : _POSIX_VDISABLE; 229 bt->c_cc[VEOL2] = st->c_cc[6] ? st->c_cc[6] : _POSIX_VDISABLE; 230 /* bt->c_cc[VSWTCH] = st->c_cc[7] ? st->c_cc[7] : _POSIX_VDISABLE; */ 231 bt->c_cc[VSTART] = st->c_cc[8] ? st->c_cc[8] : _POSIX_VDISABLE; 232 bt->c_cc[VSTOP] = st->c_cc[9] ? st->c_cc[9] : _POSIX_VDISABLE; 233 bt->c_cc[VSUSP] = st->c_cc[10] ? st->c_cc[10] : _POSIX_VDISABLE; 234 bt->c_cc[VDSUSP] = st->c_cc[11] ? st->c_cc[11] : _POSIX_VDISABLE; 235 bt->c_cc[VREPRINT] = st->c_cc[12] ? st->c_cc[12] : _POSIX_VDISABLE; 236 bt->c_cc[VDISCARD] = st->c_cc[13] ? st->c_cc[13] : _POSIX_VDISABLE; 237 bt->c_cc[VWERASE] = st->c_cc[14] ? st->c_cc[14] : _POSIX_VDISABLE; 238 bt->c_cc[VLNEXT] = st->c_cc[15] ? st->c_cc[15] : _POSIX_VDISABLE; 239 bt->c_cc[VSTATUS] = st->c_cc[16] ? st->c_cc[16] : _POSIX_VDISABLE; 240 } 241 242 243 static void 244 btios2stios(bt, st) 245 struct termios *bt; 246 struct sun_termios *st; 247 { 248 register u_long l, r; 249 250 l = bt->c_iflag; 251 r = ((l & IGNBRK) ? 0x00000001 : 0); 252 r |= ((l & BRKINT) ? 0x00000002 : 0); 253 r |= ((l & IGNPAR) ? 0x00000004 : 0); 254 r |= ((l & PARMRK) ? 0x00000008 : 0); 255 r |= ((l & INPCK) ? 0x00000010 : 0); 256 r |= ((l & ISTRIP) ? 0x00000020 : 0); 257 r |= ((l & INLCR) ? 0x00000040 : 0); 258 r |= ((l & IGNCR) ? 0x00000080 : 0); 259 r |= ((l & ICRNL) ? 0x00000100 : 0); 260 /* ((l & IUCLC) ? 0x00000200 : 0) */ 261 r |= ((l & IXON) ? 0x00000400 : 0); 262 r |= ((l & IXANY) ? 0x00000800 : 0); 263 r |= ((l & IXOFF) ? 0x00001000 : 0); 264 r |= ((l & IMAXBEL) ? 0x00002000 : 0); 265 st->c_iflag = r; 266 267 l = bt->c_oflag; 268 r = ((l & OPOST) ? 0x00000001 : 0); 269 /* ((l & OLCUC) ? 0x00000002 : 0) */ 270 r |= ((l & ONLCR) ? 0x00000004 : 0); 271 /* ((l & OCRNL) ? 0x00000008 : 0) */ 272 /* ((l & ONOCR) ? 0x00000010 : 0) */ 273 /* ((l & ONLRET) ? 0x00000020 : 0) */ 274 /* ((l & OFILL) ? 0x00000040 : 0) */ 275 /* ((l & OFDEL) ? 0x00000080 : 0) */ 276 /* ((l & NLDLY) ? 0x00000100 : 0) */ 277 /* ((l & NL1) ? 0x00000100 : 0) */ 278 /* ((l & CRDLY) ? 0x00000600 : 0) */ 279 /* ((l & CR1) ? 0x00000200 : 0) */ 280 /* ((l & CR2) ? 0x00000400 : 0) */ 281 /* ((l & CR3) ? 0x00000600 : 0) */ 282 /* ((l & TABDLY) ? 0x00001800 : 0) */ 283 /* ((l & TAB1) ? 0x00000800 : 0) */ 284 /* ((l & TAB2) ? 0x00001000 : 0) */ 285 r |= ((l & OXTABS) ? 0x00001800 : 0); 286 /* ((l & BSDLY) ? 0x00002000 : 0) */ 287 /* ((l & BS1) ? 0x00002000 : 0) */ 288 /* ((l & VTDLY) ? 0x00004000 : 0) */ 289 /* ((l & VT1) ? 0x00004000 : 0) */ 290 /* ((l & FFDLY) ? 0x00008000 : 0) */ 291 /* ((l & FF1) ? 0x00008000 : 0) */ 292 /* ((l & PAGEOUT) ? 0x00010000 : 0) */ 293 /* ((l & WRAP) ? 0x00020000 : 0) */ 294 st->c_oflag = r; 295 296 l = bt->c_cflag; 297 r = ((l & CS6) ? 0x00000010 : 0); 298 r |= ((l & CS7) ? 0x00000020 : 0); 299 r |= ((l & CS8) ? 0x00000030 : 0); 300 r |= ((l & CSTOPB) ? 0x00000040 : 0); 301 r |= ((l & CREAD) ? 0x00000080 : 0); 302 r |= ((l & PARENB) ? 0x00000100 : 0); 303 r |= ((l & PARODD) ? 0x00000200 : 0); 304 r |= ((l & HUPCL) ? 0x00000400 : 0); 305 r |= ((l & CLOCAL) ? 0x00000800 : 0); 306 /* ((l & LOBLK) ? 0x00001000 : 0) */ 307 r |= ((l & (CRTS_IFLOW|CCTS_OFLOW)) ? 0x80000000 : 0); 308 st->c_cflag = r; 309 310 l = bt->c_lflag; 311 r = ((l & ISIG) ? 0x00000001 : 0); 312 r |= ((l & ICANON) ? 0x00000002 : 0); 313 /* ((l & XCASE) ? 0x00000004 : 0) */ 314 r |= ((l & ECHO) ? 0x00000008 : 0); 315 r |= ((l & ECHOE) ? 0x00000010 : 0); 316 r |= ((l & ECHOK) ? 0x00000020 : 0); 317 r |= ((l & ECHONL) ? 0x00000040 : 0); 318 r |= ((l & NOFLSH) ? 0x00000080 : 0); 319 r |= ((l & TOSTOP) ? 0x00000100 : 0); 320 r |= ((l & ECHOCTL) ? 0x00000200 : 0); 321 r |= ((l & ECHOPRT) ? 0x00000400 : 0); 322 r |= ((l & ECHOKE) ? 0x00000800 : 0); 323 /* ((l & DEFECHO) ? 0x00001000 : 0) */ 324 r |= ((l & FLUSHO) ? 0x00002000 : 0); 325 r |= ((l & PENDIN) ? 0x00004000 : 0); 326 st->c_lflag = r; 327 328 l = ttspeedtab(bt->c_ospeed, sptab); 329 if (l >= 0) 330 st->c_cflag |= l; 331 332 st->c_cc[0] = bt->c_cc[VINTR] != _POSIX_VDISABLE? bt->c_cc[VINTR]:0; 333 st->c_cc[1] = bt->c_cc[VQUIT] != _POSIX_VDISABLE? bt->c_cc[VQUIT]:0; 334 st->c_cc[2] = bt->c_cc[VERASE] != _POSIX_VDISABLE? bt->c_cc[VERASE]:0; 335 st->c_cc[3] = bt->c_cc[VKILL] != _POSIX_VDISABLE? bt->c_cc[VKILL]:0; 336 st->c_cc[4] = bt->c_cc[VEOF] != _POSIX_VDISABLE? bt->c_cc[VEOF]:0; 337 st->c_cc[5] = bt->c_cc[VEOL] != _POSIX_VDISABLE? bt->c_cc[VEOL]:0; 338 st->c_cc[6] = bt->c_cc[VEOL2] != _POSIX_VDISABLE? bt->c_cc[VEOL2]:0; 339 st->c_cc[7] = 0; 340 /* bt->c_cc[VSWTCH] != _POSIX_VDISABLE? bt->c_cc[VSWTCH]: */ 341 st->c_cc[8] = bt->c_cc[VSTART] != _POSIX_VDISABLE? bt->c_cc[VSTART]:0; 342 st->c_cc[9] = bt->c_cc[VSTOP] != _POSIX_VDISABLE? bt->c_cc[VSTOP]:0; 343 st->c_cc[10]= bt->c_cc[VSUSP] != _POSIX_VDISABLE? bt->c_cc[VSUSP]:0; 344 st->c_cc[11]= bt->c_cc[VDSUSP] != _POSIX_VDISABLE? bt->c_cc[VDSUSP]:0; 345 st->c_cc[12]= bt->c_cc[VREPRINT]!= _POSIX_VDISABLE? bt->c_cc[VREPRINT]:0; 346 st->c_cc[13]= bt->c_cc[VDISCARD]!= _POSIX_VDISABLE? bt->c_cc[VDISCARD]:0; 347 st->c_cc[14]= bt->c_cc[VWERASE] != _POSIX_VDISABLE? bt->c_cc[VWERASE]:0; 348 st->c_cc[15]= bt->c_cc[VLNEXT] != _POSIX_VDISABLE? bt->c_cc[VLNEXT]:0; 349 st->c_cc[16]= bt->c_cc[VSTATUS] != _POSIX_VDISABLE? bt->c_cc[VSTATUS]:0; 350 351 st->c_line = 0; 352 } 353 354 static void 355 stios2stio(ts, t) 356 struct sun_termios *ts; 357 struct sun_termio *t; 358 { 359 t->c_iflag = ts->c_iflag; 360 t->c_oflag = ts->c_oflag; 361 t->c_cflag = ts->c_cflag; 362 t->c_lflag = ts->c_lflag; 363 t->c_line = ts->c_line; 364 bcopy(ts->c_cc, t->c_cc, 8); 365 } 366 367 static void 368 stio2stios(t, ts) 369 struct sun_termio *t; 370 struct sun_termios *ts; 371 { 372 ts->c_iflag = t->c_iflag; 373 ts->c_oflag = t->c_oflag; 374 ts->c_cflag = t->c_cflag; 375 ts->c_lflag = t->c_lflag; 376 ts->c_line = t->c_line; 377 bcopy(t->c_cc, ts->c_cc, 8); /* don't touch the upper fields! */ 378 } 379 380 struct sun_ioctl_args { 381 int fd; 382 int cmd; 383 caddr_t data; 384 }; 385 386 int 387 sun_ioctl(p, uap, retval) 388 register struct proc *p; 389 register struct sun_ioctl_args *uap; 390 int *retval; 391 { 392 register struct filedesc *fdp = p->p_fd; 393 register struct file *fp; 394 register int (*ctl)(); 395 int error; 396 397 if ( (unsigned)uap->fd >= fdp->fd_nfiles || 398 (fp = fdp->fd_ofiles[uap->fd]) == NULL) 399 return EBADF; 400 401 if ((fp->f_flag & (FREAD|FWRITE)) == 0) 402 return EBADF; 403 404 ctl = fp->f_ops->fo_ioctl; 405 406 switch (uap->cmd) { 407 case _IOR('t', 0, int): 408 uap->cmd = TIOCGETD; 409 break; 410 case _IOW('t', 1, int): 411 { 412 int disc; 413 414 if ((error = copyin(uap->data, (caddr_t)&disc, 415 sizeof disc)) != 0) 416 return error; 417 418 /* map SunOS NTTYDISC into our termios discipline */ 419 if (disc == 2) 420 disc = 0; 421 /* all other disciplines are not supported by NetBSD */ 422 if (disc) 423 return ENXIO; 424 425 return (*ctl)(fp, TIOCSETD, (caddr_t)&disc, p); 426 } 427 case _IOW('t', 101, int): /* sun SUN_TIOCSSOFTCAR */ 428 { 429 int x; /* unused */ 430 431 return copyin((caddr_t)&x, uap->data, sizeof x); 432 } 433 case _IOR('t', 100, int): /* sun SUN_TIOCSSOFTCAR */ 434 { 435 int x = 0; 436 437 return copyout((caddr_t)&x, uap->data, sizeof x); 438 } 439 case _IO('t', 36): /* sun TIOCCONS, no parameters */ 440 { 441 int on = 1; 442 return (*ctl)(fp, TIOCCONS, (caddr_t)&on, p); 443 } 444 case _IOW('t', 37, struct sun_ttysize): 445 { 446 struct winsize ws; 447 struct sun_ttysize ss; 448 449 if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0) 450 return (error); 451 452 if ((error = copyin (uap->data, &ss, sizeof (ss))) != 0) 453 return error; 454 455 ws.ws_row = ss.ts_row; 456 ws.ws_col = ss.ts_col; 457 458 return ((*ctl)(fp, TIOCSWINSZ, (caddr_t)&ws, p)); 459 } 460 case _IOW('t', 38, struct sun_ttysize): 461 { 462 struct winsize ws; 463 struct sun_ttysize ss; 464 465 if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0) 466 return (error); 467 468 ss.ts_row = ws.ws_row; 469 ss.ts_col = ws.ws_col; 470 471 return copyout ((caddr_t)&ss, uap->data, sizeof (ss)); 472 } 473 case _IOW('t', 130, int): 474 uap->cmd = TIOCSPGRP; 475 break; 476 case _IOR('t', 131, int): 477 uap->cmd = TIOCGPGRP; 478 break; 479 case _IO('t', 132): 480 uap->cmd = TIOCSCTTY; 481 break; 482 case SUN_TCGETA: 483 case SUN_TCGETS: 484 { 485 struct termios bts; 486 struct sun_termios sts; 487 struct sun_termio st; 488 489 if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0) 490 return error; 491 492 btios2stios (&bts, &sts); 493 if (uap->cmd == SUN_TCGETA) { 494 stios2stio (&sts, &st); 495 return copyout((caddr_t)&st, uap->data, sizeof (st)); 496 } else 497 return copyout((caddr_t)&sts, uap->data, sizeof (sts)); 498 /*NOTREACHED*/ 499 } 500 case SUN_TCSETA: 501 case SUN_TCSETAW: 502 case SUN_TCSETAF: 503 { 504 struct termios bts; 505 struct sun_termios sts; 506 struct sun_termio st; 507 508 if ((error = copyin(uap->data, (caddr_t)&st, 509 sizeof (st))) != 0) 510 return error; 511 512 /* get full BSD termios so we don't lose information */ 513 if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0) 514 return error; 515 516 /* 517 * convert to sun termios, copy in information from 518 * termio, and convert back, then set new values. 519 */ 520 btios2stios(&bts, &sts); 521 stio2stios(&st, &sts); 522 stios2btios(&sts, &bts); 523 524 return (*ctl)(fp, uap->cmd - SUN_TCSETA + TIOCSETA, 525 (caddr_t)&bts, p); 526 } 527 case SUN_TCSETS: 528 case SUN_TCSETSW: 529 case SUN_TCSETSF: 530 { 531 struct termios bts; 532 struct sun_termios sts; 533 534 if ((error = copyin (uap->data, (caddr_t)&sts, 535 sizeof (sts))) != 0) 536 return error; 537 stios2btios (&sts, &bts); 538 return (*ctl)(fp, uap->cmd - SUN_TCSETS + TIOCSETA, 539 (caddr_t)&bts, p); 540 } 541 /* 542 * Pseudo-tty ioctl translations. 543 */ 544 case _IOW('t', 32, int): { /* TIOCTCNTL */ 545 int error, on; 546 547 if (error = copyin (uap->data, (caddr_t)&on, sizeof (on))) 548 return error; 549 return (*ctl)(fp, TIOCUCNTL, (caddr_t)&on, p); 550 } 551 case _IOW('t', 33, int): { /* TIOCSIGNAL */ 552 int error, sig; 553 554 if (error = copyin (uap->data, (caddr_t)&sig, sizeof (sig))) 555 return error; 556 return (*ctl)(fp, TIOCSIG, (caddr_t)&sig, p); 557 } 558 559 /* 560 * Socket ioctl translations. 561 */ 562 #define IFREQ_IN(a) { \ 563 struct ifreq ifreq; \ 564 if (error = copyin (uap->data, (caddr_t)&ifreq, sizeof (ifreq))) \ 565 return error; \ 566 return (*ctl)(fp, a, (caddr_t)&ifreq, p); \ 567 } 568 #define IFREQ_INOUT(a) { \ 569 struct ifreq ifreq; \ 570 if (error = copyin (uap->data, (caddr_t)&ifreq, sizeof (ifreq))) \ 571 return error; \ 572 if (error = (*ctl)(fp, a, (caddr_t)&ifreq, p)) \ 573 return error; \ 574 return copyout ((caddr_t)&ifreq, uap->data, sizeof (ifreq)); \ 575 } 576 577 case _IOW('i', 12, struct ifreq): 578 /* SIOCSIFADDR */ 579 break; 580 581 case _IOWR('i', 13, struct ifreq): 582 IFREQ_INOUT(OSIOCGIFADDR); 583 584 case _IOW('i', 14, struct ifreq): 585 /* SIOCSIFDSTADDR */ 586 break; 587 588 case _IOWR('i', 15, struct ifreq): 589 IFREQ_INOUT(OSIOCGIFDSTADDR); 590 591 case _IOW('i', 16, struct ifreq): 592 /* SIOCSIFFLAGS */ 593 break; 594 595 case _IOWR('i', 17, struct ifreq): 596 /* SIOCGIFFLAGS */ 597 break; 598 599 case _IOW('i', 21, struct ifreq): 600 IFREQ_IN(SIOCSIFMTU); 601 602 case _IOWR('i', 22, struct ifreq): 603 IFREQ_INOUT(SIOCGIFMTU); 604 605 case _IOWR('i', 23, struct ifreq): 606 IFREQ_INOUT(SIOCGIFBRDADDR); 607 608 case _IOW('i', 24, struct ifreq): 609 IFREQ_IN(SIOCSIFBRDADDR); 610 611 case _IOWR('i', 25, struct ifreq): 612 IFREQ_INOUT(OSIOCGIFNETMASK); 613 614 case _IOW('i', 26, struct ifreq): 615 IFREQ_IN(SIOCSIFNETMASK); 616 617 case _IOWR('i', 27, struct ifreq): 618 IFREQ_INOUT(SIOCGIFMETRIC); 619 620 case _IOWR('i', 28, struct ifreq): 621 IFREQ_IN(SIOCSIFMETRIC); 622 623 case _IOW('i', 30, struct arpreq): 624 /* SIOCSARP */ 625 break; 626 627 case _IOWR('i', 31, struct arpreq): 628 /* SIOCGARP */ 629 break; 630 631 case _IOW('i', 32, struct arpreq): 632 /* SIOCDARP */ 633 break; 634 635 case _IOW('i', 18, struct ifreq): /* SIOCSIFMEM */ 636 case _IOWR('i', 19, struct ifreq): /* SIOCGIFMEM */ 637 case _IOW('i', 40, struct ifreq): /* SIOCUPPER */ 638 case _IOW('i', 41, struct ifreq): /* SIOCLOWER */ 639 case _IOW('i', 44, struct ifreq): /* SIOCSETSYNC */ 640 case _IOWR('i', 45, struct ifreq): /* SIOCGETSYNC */ 641 case _IOWR('i', 46, struct ifreq): /* SIOCSDSTATS */ 642 case _IOWR('i', 47, struct ifreq): /* SIOCSESTATS */ 643 case _IOW('i', 48, int): /* SIOCSPROMISC */ 644 case _IOW('i', 49, struct ifreq): /* SIOCADDMULTI */ 645 case _IOW('i', 50, struct ifreq): /* SIOCDELMULTI */ 646 return EOPNOTSUPP; 647 648 case _IOWR('i', 20, struct ifconf): /* SIOCGIFCONF */ 649 { 650 struct ifconf ifconf; 651 652 /* 653 * XXX: two more problems 654 * 1. our sockaddr's are variable length, not always sizeof(sockaddr) 655 * 2. this returns a name per protocol, ie. it returns two "lo0"'s 656 */ 657 if (error = copyin (uap->data, (caddr_t)&ifconf, sizeof (ifconf))) 658 return error; 659 if (error = (*ctl)(fp, OSIOCGIFCONF, (caddr_t)&ifconf, p)) 660 return error; 661 return copyout ((caddr_t)&ifconf, uap->data, sizeof (ifconf)); 662 } 663 } 664 return (ioctl(p, uap, retval)); 665 } 666