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