1 /* $NetBSD: svr4_32_stream.c,v 1.18 2006/05/20 22:15:20 christos Exp $ */
2
3 /*-
4 * Copyright (c) 1994 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christos Zoulas.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 /*
40 * Pretend that we have streams...
41 * Yes, this is gross.
42 *
43 * ToDo: The state machine for getmsg needs re-thinking
44 */
45
46 #include <sys/cdefs.h>
47 __KERNEL_RCSID(0, "$NetBSD: svr4_32_stream.c,v 1.18 2006/05/20 22:15:20 christos Exp $");
48
49 #include <sys/param.h>
50 #include <sys/kernel.h>
51 #include <sys/systm.h>
52 #include <sys/buf.h>
53 #include <sys/malloc.h>
54 #include <sys/ioctl.h>
55 #include <sys/tty.h>
56 #include <sys/file.h>
57 #include <sys/filedesc.h>
58 #include <sys/select.h>
59 #include <sys/socket.h>
60 #include <sys/socketvar.h>
61 #include <sys/un.h>
62 #include <net/if.h>
63 #include <netinet/in.h>
64 #include <sys/mount.h>
65 #include <sys/proc.h>
66 #include <sys/vnode.h>
67 #include <sys/device.h>
68 #include <sys/stat.h>
69
70 #include <sys/sa.h>
71 #include <sys/syscallargs.h>
72
73 #include <compat/svr4_32/svr4_32_types.h>
74 #include <compat/svr4_32/svr4_32_util.h>
75 #include <compat/svr4_32/svr4_32_signal.h>
76 #include <compat/svr4_32/svr4_32_lwp.h>
77 #include <compat/svr4_32/svr4_32_ucontext.h>
78 #include <compat/svr4_32/svr4_32_syscallargs.h>
79 #include <compat/svr4_32/svr4_32_stropts.h>
80 #include <compat/svr4_32/svr4_32_timod.h>
81 #include <compat/svr4/svr4_sockmod.h>
82 #include <compat/svr4_32/svr4_32_ioctl.h>
83 #include <compat/svr4_32/svr4_32_socket.h>
84
85
86 /* Utils */
87 static int clean_pipe __P((struct lwp *, const char *));
88 static void getparm __P((struct file *, struct svr4_si_sockparms *));
89
90 /* Address Conversions */
91 static void sockaddr_to_netaddr_in __P((struct svr4_32_strmcmd *,
92 const struct sockaddr_in *));
93 static void sockaddr_to_netaddr_un __P((struct svr4_32_strmcmd *,
94 const struct sockaddr_un *));
95 static void netaddr_to_sockaddr_in __P((struct sockaddr_in *,
96 const struct svr4_32_strmcmd *));
97 static void netaddr_to_sockaddr_un __P((struct sockaddr_un *,
98 const struct svr4_32_strmcmd *));
99
100 /* stream ioctls */
101 static int i_nread __P((struct file *, struct lwp *, register_t *, int,
102 u_long, caddr_t));
103 static int i_fdinsert __P((struct file *, struct lwp *, register_t *, int,
104 u_long, caddr_t));
105 static int i_str __P((struct file *, struct lwp *, register_t *, int,
106 u_long, caddr_t));
107 static int i_setsig __P((struct file *, struct lwp *, register_t *, int,
108 u_long, caddr_t));
109 static int i_getsig __P((struct file *, struct lwp *, register_t *, int,
110 u_long, caddr_t));
111 static int _i_bind_rsvd __P((struct file *, struct lwp *, register_t *, int,
112 u_long, caddr_t));
113 static int _i_rele_rsvd __P((struct file *, struct lwp *, register_t *, int,
114 u_long, caddr_t));
115
116
117 /* i_str sockmod calls */
118 static int sockmod __P((struct file *, int, struct svr4_32_strioctl *,
119 struct lwp *));
120 static int si_listen __P((struct file *, int, struct svr4_32_strioctl *,
121 struct lwp *));
122 static int si_ogetudata __P((struct file *, int, struct svr4_32_strioctl *,
123 struct lwp *));
124 static int si_sockparams __P((struct file *, int, struct svr4_32_strioctl *,
125 struct lwp *));
126 static int si_shutdown __P((struct file *, int, struct svr4_32_strioctl *,
127 struct lwp *));
128 static int si_getudata __P((struct file *, int, struct svr4_32_strioctl *,
129 struct lwp *));
130
131 /* i_str timod calls */
132 static int timod __P((struct file *, int, struct svr4_32_strioctl *,
133 struct lwp *));
134 static int ti_getinfo __P((struct file *, int, struct svr4_32_strioctl *,
135 struct lwp *));
136 static int ti_bind __P((struct file *, int, struct svr4_32_strioctl *,
137 struct lwp *));
138
139 #ifdef DEBUG_SVR4
140 static void bufprint __P((u_char *, size_t));
141 static int show_ioc __P((const char *, struct svr4_32_strioctl *));
142 static int show_strbuf __P((struct svr4_32_strbuf *));
143 static void show_msg __P((const char *, int, struct svr4_32_strbuf *,
144 struct svr4_32_strbuf *, int));
145
146 static void
147 bufprint(buf, len)
148 u_char *buf;
149 size_t len;
150 {
151 size_t i;
152
153 uprintf("\n\t");
154 for (i = 0; i < len; i++) {
155 uprintf("%x ", buf[i]);
156 if (i && (i % 16) == 0)
157 uprintf("\n\t");
158 }
159 }
160
161 static int
162 show_ioc(str, ioc)
163 const char *str;
164 struct svr4_32_strioctl *ioc;
165 {
166 u_char *ptr;
167 int error;
168
169 len = ioc->len;
170 if (len > 1024)
171 len = 1024;
172
173 ptr = (u_char *) malloc(len, M_TEMP, M_WAITOK);
174 uprintf("%s cmd = %ld, timeout = %d, len = %d, buf = %p { ",
175 str, ioc->cmd, ioc->timeout, ioc->len, ioc->buf);
176
177 if ((error = copyin(ioc->buf, ptr, len)) != 0) {
178 free((char *) ptr, M_TEMP);
179 return error;
180 }
181
182 bufprint(ptr, len);
183
184 uprintf("}\n");
185
186 free((char *) ptr, M_TEMP);
187 return 0;
188 }
189
190
191 static int
192 show_strbuf(str)
193 struct svr4_32_strbuf *str;
194 {
195 int error;
196 u_char *ptr = NULL;
197 int maxlen = str->maxlen;
198 int len = str->len;
199
200 if (maxlen > 8192)
201 maxlen = 8192;
202
203 if (maxlen < 0)
204 maxlen = 0;
205
206 if (len >= maxlen)
207 len = maxlen;
208
209 if (len > 0) {
210 ptr = (u_char *) malloc(len, M_TEMP, M_WAITOK);
211
212 if ((error = copyin(str->buf, ptr, len)) != 0) {
213 free((char *) ptr, M_TEMP);
214 return error;
215 }
216 }
217
218 uprintf(", { %d, %d, %p=[ ", str->maxlen, str->len, str->buf);
219
220 if (ptr)
221 bufprint(ptr, len);
222
223 uprintf("]}");
224
225 if (ptr)
226 free((char *) ptr, M_TEMP);
227
228 return 0;
229 }
230
231
232 static void
233 show_msg(str, fd, ctl, dat, flags)
234 const char *str;
235 int fd;
236 struct svr4_32_strbuf *ctl;
237 struct svr4_32_strbuf *dat;
238 int flags;
239 {
240 struct svr4_32_strbuf buf;
241 int error;
242
243 uprintf("%s(%d", str, fd);
244 if (ctl != NULL) {
245 if ((error = copyin(ctl, &buf, sizeof(buf))) != 0)
246 return;
247 show_strbuf(&buf);
248 }
249 else
250 uprintf(", NULL");
251
252 if (dat != NULL) {
253 if ((error = copyin(dat, &buf, sizeof(buf))) != 0)
254 return;
255 show_strbuf(&buf);
256 }
257 else
258 uprintf(", NULL");
259
260 uprintf(", %x);\n", flags);
261 }
262
263 #endif /* DEBUG_SVR4 */
264
265
266 /*
267 * We are faced with an interesting situation. On svr4 unix sockets
268 * are really pipes. But we really have sockets, and we might as
269 * well use them. At the point where svr4 calls TI_BIND, it has
270 * already created a named pipe for the socket using mknod(2).
271 * We need to create a socket with the same name when we bind,
272 * so we need to remove the pipe before, otherwise we'll get address
273 * already in use. So we *carefully* remove the pipe, to avoid
274 * using this as a random file removal tool. We use system calls
275 * to avoid code duplication.
276 */
277 static int
278 clean_pipe(l, path)
279 struct lwp *l;
280 const char *path;
281 {
282 struct sys___lstat30_args la;
283 struct proc *p = l->l_proc;
284 struct sys_unlink_args ua;
285 register_t retval;
286 struct stat st;
287 int error;
288 caddr_t sg = stackgap_init(p, 0);
289 size_t len = strlen(path) + 1;
290 void *tpath;
291
292 tpath = stackgap_alloc(p, &sg, len);
293 SCARG(&la, ub) = stackgap_alloc(p, &sg, sizeof(struct stat));
294
295 if ((error = copyout(path, tpath, len)) != 0)
296 return error;
297
298 SCARG(&la, path) = tpath;
299
300 if ((error = sys___lstat30(l, &la, &retval)) != 0)
301 return 0;
302
303 if ((error = copyin(SCARG(&la, ub), &st, sizeof(st))) != 0)
304 return 0;
305
306 /*
307 * Make sure we are dealing with a mode 0 named pipe.
308 */
309 if ((st.st_mode & S_IFMT) != S_IFIFO)
310 return 0;
311
312 if ((st.st_mode & ALLPERMS) != 0)
313 return 0;
314
315 SCARG(&ua, path) = SCARG(&la, path);
316
317 if ((error = sys_unlink(l, &ua, &retval)) != 0) {
318 DPRINTF(("clean_pipe: unlink failed %d\n", error));
319 return error;
320 }
321
322 return 0;
323 }
324
325 static void
326 sockaddr_to_netaddr_in(sc, sain)
327 struct svr4_32_strmcmd *sc;
328 const struct sockaddr_in *sain;
329 {
330 struct svr4_32_netaddr_in *na;
331 na = SVR4_ADDROF(sc);
332
333 na->family = sain->sin_family;
334 na->port = sain->sin_port;
335 na->addr = sain->sin_addr.s_addr;
336 DPRINTF(("sockaddr_in -> netaddr %d %d %lx\n", na->family, na->port,
337 na->addr));
338 }
339
340
341 static void
342 sockaddr_to_netaddr_un(sc, saun)
343 struct svr4_32_strmcmd *sc;
344 const struct sockaddr_un *saun;
345 {
346 struct svr4_32_netaddr_un *na;
347 char *dst, *edst = ((char *) sc) + sc->offs + sizeof(na->family) + 1 -
348 sizeof(*sc);
349 const char *src;
350
351 na = SVR4_ADDROF(sc);
352 na->family = saun->sun_family;
353 for (src = saun->sun_path, dst = na->path; (*dst++ = *src++) != '\0'; )
354 if (dst == edst)
355 break;
356 DPRINTF(("sockaddr_un -> netaddr %d %s\n", na->family, na->path));
357 }
358
359
360 static void
361 netaddr_to_sockaddr_in(sain, sc)
362 struct sockaddr_in *sain;
363 const struct svr4_32_strmcmd *sc;
364 {
365 const struct svr4_32_netaddr_in *na;
366
367
368 na = SVR4_C_ADDROF(sc);
369 memset(sain, 0, sizeof(*sain));
370 sain->sin_len = sizeof(*sain);
371 sain->sin_family = na->family;
372 sain->sin_port = na->port;
373 sain->sin_addr.s_addr = na->addr;
374 DPRINTF(("netaddr -> sockaddr_in %d %d %x\n", sain->sin_family,
375 sain->sin_port, sain->sin_addr.s_addr));
376 }
377
378
379 static void
380 netaddr_to_sockaddr_un(saun, sc)
381 struct sockaddr_un *saun;
382 const struct svr4_32_strmcmd *sc;
383 {
384 const struct svr4_32_netaddr_un *na;
385 char *dst, *edst = &saun->sun_path[sizeof(saun->sun_path) - 1];
386 const char *src;
387
388 na = SVR4_C_ADDROF(sc);
389 memset(saun, 0, sizeof(*saun));
390 saun->sun_family = na->family;
391 for (src = na->path, dst = saun->sun_path; (*dst++ = *src++) != '\0'; )
392 if (dst == edst)
393 break;
394 saun->sun_len = dst - saun->sun_path;
395 DPRINTF(("netaddr -> sockaddr_un %d %s\n", saun->sun_family,
396 saun->sun_path));
397 }
398
399 static void
400 getparm(fp, pa)
401 struct file *fp;
402 struct svr4_si_sockparms *pa;
403 {
404 struct svr4_strm *st = svr4_32_stream_get(fp);
405 struct socket *so = (struct socket *) fp->f_data;
406
407 if (st == NULL)
408 return;
409
410 pa->family = st->s_family;
411
412 switch (so->so_type) {
413 case SOCK_DGRAM:
414 pa->type = SVR4_T_CLTS;
415 pa->protocol = IPPROTO_UDP;
416 DPRINTF(("getparm(dgram)\n"));
417 return;
418
419 case SOCK_STREAM:
420 pa->type = SVR4_T_COTS; /* What about T_COTS_ORD? XXX */
421 pa->protocol = IPPROTO_IP;
422 DPRINTF(("getparm(stream)\n"));
423 return;
424
425 case SOCK_RAW:
426 pa->type = SVR4_T_CLTS;
427 pa->protocol = IPPROTO_RAW;
428 DPRINTF(("getparm(raw)\n"));
429 return;
430
431 default:
432 pa->type = 0;
433 pa->protocol = 0;
434 DPRINTF(("getparm(type %d?)\n", so->so_type));
435 return;
436 }
437 }
438
439 static int
440 si_ogetudata(fp, fd, ioc, l)
441 struct file *fp;
442 int fd;
443 struct svr4_32_strioctl *ioc;
444 struct lwp *l;
445 {
446 int error;
447 struct svr4_si_oudata ud;
448 struct svr4_si_sockparms pa;
449 (void)memset(&pa, 0, sizeof(pa)); /* XXX: GCC */
450
451 if (ioc->len != sizeof(ud) && ioc->len != sizeof(ud) - sizeof(int)) {
452 DPRINTF(("SI_OGETUDATA: Wrong size %ld != %d\n",
453 (unsigned long)sizeof(ud), ioc->len));
454 return EINVAL;
455 }
456
457 if ((error = copyin((caddr_t)(u_long)ioc->buf, &ud, sizeof(ud))) != 0)
458 return error;
459
460 getparm(fp, &pa);
461
462 switch (pa.family) {
463 case AF_INET:
464 ud.tidusize = 16384;
465 ud.addrsize = sizeof(struct sockaddr_in);
466 if (pa.type == SVR4_SOCK_STREAM)
467 ud.etsdusize = 1;
468 else
469 ud.etsdusize = 0;
470 break;
471
472 case AF_LOCAL:
473 ud.tidusize = 65536;
474 ud.addrsize = 128;
475 ud.etsdusize = 128;
476 break;
477
478 default:
479 DPRINTF(("SI_OGETUDATA: Unsupported address family %d\n",
480 pa.family));
481 return ENOSYS;
482 }
483
484 /* I have no idea what these should be! */
485 ud.optsize = 128;
486 ud.tsdusize = 128;
487
488 ud.servtype = pa.type;
489
490 /* XXX: Fixme */
491 ud.so_state = 0;
492 ud.so_options = 0;
493 return copyout(&ud, (caddr_t)(u_long)ioc->buf, ioc->len);
494 }
495
496
497 static int
498 si_sockparams(fp, fd, ioc, l)
499 struct file *fp;
500 int fd;
501 struct svr4_32_strioctl *ioc;
502 struct lwp *l;
503 {
504 struct svr4_si_sockparms pa;
505
506 getparm(fp, &pa);
507 return copyout(&pa, (caddr_t)(u_long)ioc->buf, sizeof(pa));
508 }
509
510
511 static int
512 si_listen(fp, fd, ioc, l)
513 struct file *fp;
514 int fd;
515 struct svr4_32_strioctl *ioc;
516 struct lwp *l;
517 {
518 int error;
519 struct svr4_strm *st = svr4_32_stream_get(fp);
520 register_t retval;
521 struct svr4_32_strmcmd lst;
522 struct sys_listen_args la;
523
524 if (st == NULL)
525 return EINVAL;
526
527 if (ioc->len > sizeof(lst))
528 return EINVAL;
529
530 if ((error = copyin((caddr_t)(u_long)ioc->buf, &lst, ioc->len)) != 0)
531 return error;
532
533 if (lst.cmd != SVR4_TI_OLD_BIND_REQUEST) {
534 DPRINTF(("si_listen: bad request %ld\n", lst.cmd));
535 return EINVAL;
536 }
537
538 /*
539 * We are making assumptions again...
540 */
541 SCARG(&la, s) = fd;
542 DPRINTF(("SI_LISTEN: fileno %d backlog = %d\n", fd, 5));
543 SCARG(&la, backlog) = 5;
544
545 if ((error = sys_listen(l, &la, &retval)) != 0) {
546 DPRINTF(("SI_LISTEN: listen failed %d\n", error));
547 return error;
548 }
549
550 st->s_cmd = SVR4_TI__ACCEPT_WAIT;
551 lst.cmd = SVR4_TI_BIND_REPLY;
552
553 switch (st->s_family) {
554 case AF_INET:
555 /* XXX: Fill the length here */
556 break;
557
558 case AF_LOCAL:
559 lst.len = 140;
560 lst.pad[28] = 0x00000000; /* magic again */
561 lst.pad[29] = 0x00000800; /* magic again */
562 lst.pad[30] = 0x80001400; /* magic again */
563 break;
564
565 default:
566 DPRINTF(("SI_LISTEN: Unsupported address family %d\n",
567 st->s_family));
568 return ENOSYS;
569 }
570
571
572 if ((error = copyout(&lst, (caddr_t)(u_long)ioc->buf, ioc->len)) != 0)
573 return error;
574
575 return 0;
576 }
577
578
579 static int
580 si_getudata(fp, fd, ioc, l)
581 struct file *fp;
582 int fd;
583 struct svr4_32_strioctl *ioc;
584 struct lwp *l;
585 {
586 int error;
587 struct svr4_si_udata ud;
588
589 if (sizeof(ud) != ioc->len) {
590 DPRINTF(("SI_GETUDATA: Wrong size %ld != %d\n",
591 (unsigned long)sizeof(ud), ioc->len));
592 return EINVAL;
593 }
594
595 if ((error = copyin((caddr_t)(u_long)ioc->buf, &ud, sizeof(ud))) != 0)
596 return error;
597
598 getparm(fp, &ud.sockparms);
599
600 switch (ud.sockparms.family) {
601 case AF_INET:
602 ud.tidusize = 16384;
603 ud.tsdusize = 16384;
604 ud.addrsize = sizeof(struct sockaddr_in);
605 if (ud.sockparms.type == SVR4_SOCK_STREAM)
606 ud.etsdusize = 1;
607 else
608 ud.etsdusize = 0;
609 ud.optsize = 0;
610 break;
611
612 case AF_LOCAL:
613 ud.tidusize = 65536;
614 ud.tsdusize = 128;
615 ud.addrsize = 128;
616 ud.etsdusize = 128;
617 ud.optsize = 128;
618 break;
619
620 default:
621 DPRINTF(("SI_GETUDATA: Unsupported address family %d\n",
622 ud.sockparms.family));
623 return ENOSYS;
624 }
625
626
627 ud.servtype = ud.sockparms.type;
628
629 /* XXX: Fixme */
630 ud.so_state = 0;
631 ud.so_options = 0;
632 return copyout(&ud, (caddr_t)(u_long)ioc->buf, sizeof(ud));
633 }
634
635
636 static int
637 si_shutdown(fp, fd, ioc, l)
638 struct file *fp;
639 int fd;
640 struct svr4_32_strioctl *ioc;
641 struct lwp *l;
642 {
643 int error;
644 struct sys_shutdown_args ap;
645 register_t retval;
646
647 if (ioc->len != sizeof(SCARG(&ap, how))) {
648 DPRINTF(("SI_SHUTDOWN: Wrong size %ld != %d\n",
649 (unsigned long)sizeof(SCARG(&ap, how)), ioc->len));
650 return EINVAL;
651 }
652
653 if ((error = copyin((caddr_t)(u_long)ioc->buf, &SCARG(&ap, how), ioc->len)) != 0)
654 return error;
655
656 SCARG(&ap, s) = fd;
657
658 return sys_shutdown(l, &ap, &retval);
659 }
660
661 static int
662 sockmod(fp, fd, ioc, l)
663 struct file *fp;
664 int fd;
665 struct svr4_32_strioctl *ioc;
666 struct lwp *l;
667 {
668 switch (ioc->cmd) {
669 case SVR4_SI_OGETUDATA:
670 DPRINTF(("SI_OGETUDATA\n"));
671 return si_ogetudata(fp, fd, ioc, l);
672
673 case SVR4_SI_SHUTDOWN:
674 DPRINTF(("SI_SHUTDOWN\n"));
675 return si_shutdown(fp, fd, ioc, l);
676
677 case SVR4_SI_LISTEN:
678 DPRINTF(("SI_LISTEN\n"));
679 return si_listen(fp, fd, ioc, l);
680
681 case SVR4_SI_SETMYNAME:
682 DPRINTF(("SI_SETMYNAME\n"));
683 return 0;
684
685 case SVR4_SI_SETPEERNAME:
686 DPRINTF(("SI_SETPEERNAME\n"));
687 return 0;
688
689 case SVR4_SI_GETINTRANSIT:
690 DPRINTF(("SI_GETINTRANSIT\n"));
691 return 0;
692
693 case SVR4_SI_TCL_LINK:
694 DPRINTF(("SI_TCL_LINK\n"));
695 return 0;
696
697 case SVR4_SI_TCL_UNLINK:
698 DPRINTF(("SI_TCL_UNLINK\n"));
699 return 0;
700
701 case SVR4_SI_SOCKPARAMS:
702 DPRINTF(("SI_SOCKPARAMS\n"));
703 return si_sockparams(fp, fd, ioc, l);
704
705 case SVR4_SI_GETUDATA:
706 DPRINTF(("SI_GETUDATA\n"));
707 return si_getudata(fp, fd, ioc, l);
708
709 default:
710 DPRINTF(("Unknown sockmod ioctl %lx\n", ioc->cmd));
711 return 0;
712
713 }
714 }
715
716 static int
717 ti_getinfo(fp, fd, ioc, l)
718 struct file *fp;
719 int fd;
720 struct svr4_32_strioctl *ioc;
721 struct lwp *l;
722 {
723 int error;
724 struct svr4_32_infocmd info;
725
726 memset(&info, 0, sizeof(info));
727
728 if (ioc->len > sizeof(info))
729 return EINVAL;
730
731 if ((error = copyin((caddr_t)(u_long)ioc->buf, &info, ioc->len)) != 0)
732 return error;
733
734 if (info.cmd != SVR4_TI_INFO_REQUEST)
735 return EINVAL;
736
737 info.cmd = SVR4_TI_INFO_REPLY;
738 info.tsdu = 0;
739 info.etsdu = 1;
740 info.cdata = -2;
741 info.ddata = -2;
742 info.addr = 16;
743 info.opt = -1;
744 info.tidu = 16384;
745 info.serv = 2;
746 info.current = 0;
747 info.provider = 2;
748
749 ioc->len = sizeof(info);
750 if ((error = copyout(&info, (caddr_t)(u_long)ioc->buf, ioc->len)) != 0)
751 return error;
752
753 return 0;
754 }
755
756
757 static int
758 ti_bind(fp, fd, ioc, l)
759 struct file *fp;
760 int fd;
761 struct svr4_32_strioctl *ioc;
762 struct lwp *l;
763 {
764 int error;
765 struct proc *p = l->l_proc;
766 struct svr4_strm *st = svr4_32_stream_get(fp);
767 struct sockaddr_in sain;
768 struct sockaddr_un saun;
769 register_t retval;
770 caddr_t sg;
771 void *skp, *sup = NULL;
772 int sasize;
773 struct svr4_32_strmcmd bnd;
774 struct sys_bind_args ba;
775
776 if (st == NULL) {
777 DPRINTF(("ti_bind: bad file descriptor\n"));
778 return EINVAL;
779 }
780
781 if (ioc->len > sizeof(bnd))
782 return EINVAL;
783
784 if ((error = copyin((caddr_t)(u_long)ioc->buf, &bnd, ioc->len)) != 0)
785 return error;
786
787 if (bnd.cmd != SVR4_TI_OLD_BIND_REQUEST) {
788 DPRINTF(("ti_bind: bad request %ld\n", bnd.cmd));
789 return EINVAL;
790 }
791
792 switch (st->s_family) {
793 case AF_INET:
794 skp = &sain;
795 sasize = sizeof(sain);
796
797 if (bnd.offs == 0)
798 goto reply;
799
800 netaddr_to_sockaddr_in(&sain, &bnd);
801
802 DPRINTF(("TI_BIND: fam %d, port %d, addr %x\n",
803 sain.sin_family, sain.sin_port,
804 sain.sin_addr.s_addr));
805 break;
806
807 case AF_LOCAL:
808 skp = &saun;
809 sasize = sizeof(saun);
810 if (bnd.offs == 0)
811 goto reply;
812
813 netaddr_to_sockaddr_un(&saun, &bnd);
814
815 if (saun.sun_path[0] == '\0')
816 goto reply;
817
818 DPRINTF(("TI_BIND: fam %d, path %s\n",
819 saun.sun_family, saun.sun_path));
820
821 if ((error = clean_pipe(l, saun.sun_path)) != 0)
822 return error;
823
824 bnd.pad[28] = 0x00001000; /* magic again */
825 break;
826
827 default:
828 DPRINTF(("TI_BIND: Unsupported address family %d\n",
829 st->s_family));
830 return ENOSYS;
831 }
832
833 sg = stackgap_init(p, 0);
834 sup = stackgap_alloc(p, &sg, sasize);
835
836 if ((error = copyout(skp, sup, sasize)) != 0)
837 return error;
838
839 SCARG(&ba, s) = fd;
840 DPRINTF(("TI_BIND: fileno %d\n", fd));
841 SCARG(&ba, name) = (void *) sup;
842 SCARG(&ba, namelen) = sasize;
843
844 if ((error = sys_bind(l, &ba, &retval)) != 0) {
845 DPRINTF(("TI_BIND: bind failed %d\n", error));
846 return error;
847 }
848
849 reply:
850 if (sup == NULL) {
851 memset(&bnd, 0, sizeof(bnd));
852 bnd.len = sasize + 4;
853 bnd.offs = 0x10; /* XXX */
854 }
855
856 bnd.cmd = SVR4_TI_BIND_REPLY;
857
858 if ((error = copyout(&bnd, (caddr_t)(u_long)ioc->buf, ioc->len)) != 0)
859 return error;
860
861 return 0;
862 }
863
864
865 static int
866 timod(fp, fd, ioc, l)
867 struct file *fp;
868 int fd;
869 struct svr4_32_strioctl *ioc;
870 struct lwp *l;
871 {
872 switch (ioc->cmd) {
873 case SVR4_TI_GETINFO:
874 DPRINTF(("TI_GETINFO\n"));
875 return ti_getinfo(fp, fd, ioc, l);
876
877 case SVR4_TI_OPTMGMT:
878 DPRINTF(("TI_OPTMGMT\n"));
879 return 0;
880
881 case SVR4_TI_BIND:
882 DPRINTF(("TI_BIND\n"));
883 return ti_bind(fp, fd, ioc, l);
884
885 case SVR4_TI_UNBIND:
886 DPRINTF(("TI_UNBIND\n"));
887 return 0;
888
889 default:
890 DPRINTF(("Unknown timod ioctl %lx\n", ioc->cmd));
891 return 0;
892 }
893 }
894
895 int
896 svr4_32_stream_ti_ioctl(fp, l, retval, fd, cmd, dat)
897 struct file *fp;
898 struct lwp *l;
899 register_t *retval;
900 int fd;
901 u_long cmd;
902 caddr_t dat;
903 {
904 struct proc *p = l->l_proc;
905 struct svr4_32_strbuf skb, *sub = (struct svr4_32_strbuf *) dat;
906 struct svr4_strm *st = svr4_32_stream_get(fp);
907 int error;
908 void *skp, *sup;
909 struct sockaddr_in sain;
910 struct sockaddr_un saun;
911 struct svr4_32_strmcmd sc;
912 int sasize;
913 caddr_t sg;
914 int *lenp;
915
916 if (st == NULL)
917 return EINVAL;
918
919 sc.offs = 0x10;
920
921 if ((error = copyin(sub, &skb, sizeof(skb))) != 0) {
922 DPRINTF(("ti_ioctl: error copying in strbuf\n"));
923 return error;
924 }
925
926 switch (st->s_family) {
927 case AF_INET:
928 skp = &sain;
929 sasize = sizeof(sain);
930 break;
931
932 case AF_LOCAL:
933 skp = &saun;
934 sasize = sizeof(saun);
935 break;
936
937 default:
938 DPRINTF(("ti_ioctl: Unsupported address family %d\n",
939 st->s_family));
940 return ENOSYS;
941 }
942
943 sg = stackgap_init(p, 0);
944 sup = stackgap_alloc(p, &sg, sasize);
945 lenp = stackgap_alloc(p, &sg, sizeof(*lenp));
946
947 if ((error = copyout(&sasize, lenp, sizeof(*lenp))) != 0) {
948 DPRINTF(("ti_ioctl: error copying out lenp\n"));
949 return error;
950 }
951
952 switch (cmd) {
953 case SVR4_TI_GETMYNAME:
954 DPRINTF(("TI_GETMYNAME\n"));
955 {
956 struct sys_getsockname_args ap;
957 SCARG(&ap, fdes) = fd;
958 SCARG(&ap, asa) = sup;
959 SCARG(&ap, alen) = (socklen_t *)lenp;
960 if ((error = sys_getsockname(l, &ap, retval)) != 0) {
961 DPRINTF(("ti_ioctl: getsockname error\n"));
962 return error;
963 }
964 }
965 break;
966
967 case SVR4_TI_GETPEERNAME:
968 DPRINTF(("TI_GETPEERNAME\n"));
969 {
970 struct sys_getpeername_args ap;
971 SCARG(&ap, fdes) = fd;
972 SCARG(&ap, asa) = sup;
973 SCARG(&ap, alen) = (socklen_t *)lenp;
974 if ((error = sys_getpeername(l, &ap, retval)) != 0) {
975 DPRINTF(("ti_ioctl: getpeername error\n"));
976 return error;
977 }
978 }
979 break;
980
981 case SVR4_TI_SETMYNAME:
982 DPRINTF(("TI_SETMYNAME\n"));
983 return 0;
984
985 case SVR4_TI_SETPEERNAME:
986 DPRINTF(("TI_SETPEERNAME\n"));
987 return 0;
988 default:
989 DPRINTF(("ti_ioctl: Unknown ioctl %lx\n", cmd));
990 return ENOSYS;
991 }
992
993 if ((error = copyin(sup, skp, sasize)) != 0) {
994 DPRINTF(("ti_ioctl: error copying in socket data\n"));
995 return error;
996 }
997
998 if ((error = copyin(lenp, &sasize, sizeof(*lenp))) != 0) {
999 DPRINTF(("ti_ioctl: error copying in socket size\n"));
1000 return error;
1001 }
1002
1003 switch (st->s_family) {
1004 case AF_INET:
1005 sockaddr_to_netaddr_in(&sc, &sain);
1006 skb.len = sasize;
1007 break;
1008
1009 case AF_LOCAL:
1010 sockaddr_to_netaddr_un(&sc, &saun);
1011 skb.len = sasize + 4;
1012 break;
1013
1014 default:
1015 return ENOSYS;
1016 }
1017
1018
1019 if ((error = copyout(SVR4_ADDROF(&sc), (caddr_t)(u_long)skb.buf,
1020 sasize)) != 0) {
1021 DPRINTF(("ti_ioctl: error copying out socket data\n"));
1022 return error;
1023 }
1024
1025
1026 if ((error = copyout(&skb, sub, sizeof(skb))) != 0) {
1027 DPRINTF(("ti_ioctl: error copying out strbuf\n"));
1028 return error;
1029 }
1030
1031 return error;
1032 }
1033
1034
1035 static int
1036 i_nread(fp, l, retval, fd, cmd, dat)
1037 struct file *fp;
1038 struct lwp *l;
1039 register_t *retval;
1040 int fd;
1041 u_long cmd;
1042 caddr_t dat;
1043 {
1044 int error;
1045 int nread = 0;
1046
1047 /*
1048 * We are supposed to return the message length in nread, and the
1049 * number of messages in retval. We don't have the notion of number
1050 * of stream messages, so we just find out if we have any bytes waiting
1051 * for us, and if we do, then we assume that we have at least one
1052 * message waiting for us.
1053 */
1054 if ((error = (*fp->f_ops->fo_ioctl)(fp, FIONREAD,
1055 (caddr_t) &nread, l)) != 0)
1056 return error;
1057
1058 if (nread != 0)
1059 *retval = 1;
1060 else
1061 *retval = 0;
1062
1063 return copyout(&nread, dat, sizeof(nread));
1064 }
1065
1066 static int
1067 i_fdinsert(fp, l, retval, fd, cmd, dat)
1068 struct file *fp;
1069 struct lwp *l;
1070 register_t *retval;
1071 int fd;
1072 u_long cmd;
1073 caddr_t dat;
1074 {
1075 /*
1076 * Major hack again here. We assume that we are using this to
1077 * implement accept(2). If that is the case, we have already
1078 * called accept, and we have stored the file descriptor in
1079 * afd. We find the file descriptor that the code wants to use
1080 * in fd insert, and then we dup2() our accepted file descriptor
1081 * to it.
1082 */
1083 int error;
1084 struct svr4_strm *st = svr4_32_stream_get(fp);
1085 struct svr4_32_strfdinsert fdi;
1086 struct sys_dup2_args d2p;
1087 struct sys_close_args clp;
1088
1089 if (st == NULL) {
1090 DPRINTF(("fdinsert: bad file type\n"));
1091 return EINVAL;
1092 }
1093
1094 if (st->s_afd == -1) {
1095 DPRINTF(("fdinsert: accept fd not found\n"));
1096 return ENOENT;
1097 }
1098
1099 if ((error = copyin(dat, &fdi, sizeof(fdi))) != 0) {
1100 DPRINTF(("fdinsert: copyin failed %d\n", error));
1101 return error;
1102 }
1103
1104 SCARG(&d2p, from) = st->s_afd;
1105 SCARG(&d2p, to) = fdi.fd;
1106
1107 if ((error = sys_dup2(l, &d2p, retval)) != 0) {
1108 DPRINTF(("fdinsert: dup2(%d, %d) failed %d\n",
1109 st->s_afd, fdi.fd, error));
1110 return error;
1111 }
1112
1113 SCARG(&clp, fd) = st->s_afd;
1114
1115 if ((error = sys_close(l, &clp, retval)) != 0) {
1116 DPRINTF(("fdinsert: close(%d) failed %d\n",
1117 st->s_afd, error));
1118 return error;
1119 }
1120
1121 st->s_afd = -1;
1122
1123 *retval = 0;
1124 return 0;
1125 }
1126
1127
1128 static int
1129 _i_bind_rsvd(fp, l, retval, fd, cmd, dat)
1130 struct file *fp;
1131 struct lwp *l;
1132 register_t *retval;
1133 int fd;
1134 u_long cmd;
1135 caddr_t dat;
1136 {
1137 struct sys_mknod_args ap;
1138
1139 /*
1140 * This is a supposed to be a kernel and library only ioctl.
1141 * It gets called before ti_bind, when we have a unix
1142 * socket, to physically create the socket transport and
1143 * ``reserve'' it. I don't know how this get reserved inside
1144 * the kernel, but we are going to create it nevertheless.
1145 */
1146 SCARG(&ap, path) = dat;
1147 SCARG(&ap, mode) = S_IFIFO;
1148
1149 return sys_mkfifo(l, &ap, retval);
1150 }
1151
1152 static int
1153 _i_rele_rsvd(fp, l, retval, fd, cmd, dat)
1154 struct file *fp;
1155 struct lwp *l;
1156 register_t *retval;
1157 int fd;
1158 u_long cmd;
1159 caddr_t dat;
1160 {
1161 struct sys_unlink_args ap;
1162
1163 /*
1164 * This is a supposed to be a kernel and library only ioctl.
1165 * I guess it is supposed to release the socket.
1166 */
1167 SCARG(&ap, path) = dat;
1168
1169 return sys_unlink(l, &ap, retval);
1170 }
1171
1172 static int
1173 i_str(fp, l, retval, fd, cmd, dat)
1174 struct file *fp;
1175 struct lwp *l;
1176 register_t *retval;
1177 int fd;
1178 u_long cmd;
1179 caddr_t dat;
1180 {
1181 int error;
1182 struct svr4_32_strioctl ioc;
1183
1184 /*
1185 * Noop on non sockets
1186 */
1187 if (fp->f_type != DTYPE_SOCKET)
1188 return 0;
1189
1190 if ((error = copyin(dat, &ioc, sizeof(ioc))) != 0)
1191 return error;
1192
1193 #ifdef DEBUG_SVR4
1194 if ((error = show_ioc(">", &ioc)) != 0)
1195 return error;
1196 #endif /* DEBUG_SVR4 */
1197
1198 switch (ioc.cmd & 0xff00) {
1199 case SVR4_SIMOD:
1200 if ((error = sockmod(fp, fd, &ioc, l)) != 0)
1201 return error;
1202 break;
1203
1204 case SVR4_TIMOD:
1205 if ((error = timod(fp, fd, &ioc, l)) != 0)
1206 return error;
1207 break;
1208
1209 default:
1210 DPRINTF(("Unimplemented module %c %ld\n",
1211 (char) (cmd >> 8), cmd & 0xff));
1212 return 0;
1213 }
1214
1215 #ifdef DEBUG_SVR4
1216 if ((error = show_ioc("<", &ioc)) != 0)
1217 return error;
1218 #endif /* DEBUG_SVR4 */
1219 return copyout(&ioc, dat, sizeof(ioc));
1220 }
1221
1222 static int
1223 i_setsig(fp, l, retval, fd, cmd, dat)
1224 struct file *fp;
1225 struct lwp *l;
1226 register_t *retval;
1227 int fd;
1228 u_long cmd;
1229 caddr_t dat;
1230 {
1231 /*
1232 * This is the best we can do for now; we cannot generate
1233 * signals only for specific events so the signal mask gets
1234 * ignored; we save it just to pass it to a possible I_GETSIG...
1235 *
1236 * We alse have to fix the O_ASYNC fcntl bit, so the
1237 * process will get SIGPOLLs.
1238 */
1239 struct sys_fcntl_args fa;
1240 int error;
1241 register_t oflags, flags;
1242 struct svr4_strm *st = svr4_32_stream_get(fp);
1243
1244 if (st == NULL) {
1245 DPRINTF(("i_setsig: bad file descriptor\n"));
1246 return EINVAL;
1247 }
1248 /* get old status flags */
1249 SCARG(&fa, fd) = fd;
1250 SCARG(&fa, cmd) = F_GETFL;
1251 if ((error = sys_fcntl(l, &fa, &oflags)) != 0)
1252 return error;
1253
1254 /* update the flags */
1255 if (dat != NULL) {
1256 int mask;
1257
1258 flags = oflags | O_ASYNC;
1259 mask = (int)(u_long)dat;
1260 if (mask & ~SVR4_S_ALLMASK) {
1261 DPRINTF(("i_setsig: bad eventmask data %x\n", mask));
1262 return EINVAL;
1263 }
1264 st->s_eventmask = mask;
1265 }
1266 else {
1267 flags = oflags & ~O_ASYNC;
1268 st->s_eventmask = 0;
1269 }
1270
1271 /* set the new flags, if changed */
1272 if (flags != oflags) {
1273 SCARG(&fa, cmd) = F_SETFL;
1274 SCARG(&fa, arg) = (void *) flags;
1275 if ((error = sys_fcntl(l, &fa, &flags)) != 0)
1276 return error;
1277 }
1278
1279 /* set up SIGIO receiver if needed */
1280 if (dat != NULL) {
1281 SCARG(&fa, cmd) = F_SETOWN;
1282 SCARG(&fa, arg) = (void *)(u_long)l->l_proc->p_pid;
1283 return sys_fcntl(l, &fa, &flags);
1284 }
1285 return 0;
1286 }
1287
1288 static int
1289 i_getsig(fp, l, retval, fd, cmd, dat)
1290 struct file *fp;
1291 struct lwp *l;
1292 register_t *retval;
1293 int fd;
1294 u_long cmd;
1295 caddr_t dat;
1296 {
1297 int error;
1298
1299 if (dat != NULL) {
1300 struct svr4_strm *st = svr4_32_stream_get(fp);
1301
1302 if (st == NULL) {
1303 DPRINTF(("i_getsig: bad file descriptor\n"));
1304 return EINVAL;
1305 }
1306 if ((error = copyout(&st->s_eventmask, dat,
1307 sizeof(st->s_eventmask))) != 0) {
1308 DPRINTF(("i_getsig: bad eventmask pointer\n"));
1309 return error;
1310 }
1311 }
1312 return 0;
1313 }
1314
1315 int
1316 svr4_32_stream_ioctl(fp, l, retval, fd, cmd, dat)
1317 struct file *fp;
1318 struct lwp *l;
1319 register_t *retval;
1320 int fd;
1321 u_long cmd;
1322 caddr_t dat;
1323 {
1324 *retval = 0;
1325 /*
1326 * All the following stuff assumes "sockmod" is pushed...
1327 */
1328 switch (cmd) {
1329 case SVR4_I_NREAD:
1330 DPRINTF(("I_NREAD\n"));
1331 return i_nread(fp, l, retval, fd, cmd, dat);
1332
1333 case SVR4_I_PUSH:
1334 DPRINTF(("I_PUSH\n"));
1335 return 0;
1336
1337 case SVR4_I_POP:
1338 DPRINTF(("I_POP\n"));
1339 return 0;
1340
1341 case SVR4_I_LOOK:
1342 DPRINTF(("I_LOOK\n"));
1343 return 0;
1344
1345 case SVR4_I_FLUSH:
1346 DPRINTF(("I_FLUSH\n"));
1347 return 0;
1348
1349 case SVR4_I_SRDOPT:
1350 DPRINTF(("I_SRDOPT\n"));
1351 return 0;
1352
1353 case SVR4_I_GRDOPT:
1354 DPRINTF(("I_GRDOPT\n"));
1355 return 0;
1356
1357 case SVR4_I_STR:
1358 DPRINTF(("I_STR\n"));
1359 return i_str(fp, l, retval, fd, cmd, dat);
1360
1361 case SVR4_I_SETSIG:
1362 DPRINTF(("I_SETSIG\n"));
1363 return i_setsig(fp, l, retval, fd, cmd, dat);
1364
1365 case SVR4_I_GETSIG:
1366 DPRINTF(("I_GETSIG\n"));
1367 return i_getsig(fp, l, retval, fd, cmd, dat);
1368
1369 case SVR4_I_FIND:
1370 DPRINTF(("I_FIND\n"));
1371 /*
1372 * Here we are not pushing modules really, we just
1373 * pretend all are present
1374 */
1375 *retval = 1;
1376 return 0;
1377
1378 case SVR4_I_LINK:
1379 DPRINTF(("I_LINK\n"));
1380 return 0;
1381
1382 case SVR4_I_UNLINK:
1383 DPRINTF(("I_UNLINK\n"));
1384 return 0;
1385
1386 case SVR4_I_ERECVFD:
1387 DPRINTF(("I_ERECVFD\n"));
1388 return 0;
1389
1390 case SVR4_I_PEEK:
1391 DPRINTF(("I_PEEK\n"));
1392 return 0;
1393
1394 case SVR4_I_FDINSERT:
1395 DPRINTF(("I_FDINSERT\n"));
1396 return i_fdinsert(fp, l, retval, fd, cmd, dat);
1397
1398 case SVR4_I_SENDFD:
1399 DPRINTF(("I_SENDFD\n"));
1400 return 0;
1401
1402 case SVR4_I_RECVFD:
1403 DPRINTF(("I_RECVFD\n"));
1404 return 0;
1405
1406 case SVR4_I_SWROPT:
1407 DPRINTF(("I_SWROPT\n"));
1408 return 0;
1409
1410 case SVR4_I_GWROPT:
1411 DPRINTF(("I_GWROPT\n"));
1412 return 0;
1413
1414 case SVR4_I_LIST:
1415 DPRINTF(("I_LIST\n"));
1416 return 0;
1417
1418 case SVR4_I_PLINK:
1419 DPRINTF(("I_PLINK\n"));
1420 return 0;
1421
1422 case SVR4_I_PUNLINK:
1423 DPRINTF(("I_PUNLINK\n"));
1424 return 0;
1425
1426 case SVR4_I_SETEV:
1427 DPRINTF(("I_SETEV\n"));
1428 return 0;
1429
1430 case SVR4_I_GETEV:
1431 DPRINTF(("I_GETEV\n"));
1432 return 0;
1433
1434 case SVR4_I_STREV:
1435 DPRINTF(("I_STREV\n"));
1436 return 0;
1437
1438 case SVR4_I_UNSTREV:
1439 DPRINTF(("I_UNSTREV\n"));
1440 return 0;
1441
1442 case SVR4_I_FLUSHBAND:
1443 DPRINTF(("I_FLUSHBAND\n"));
1444 return 0;
1445
1446 case SVR4_I_CKBAND:
1447 DPRINTF(("I_CKBAND\n"));
1448 return 0;
1449
1450 case SVR4_I_GETBAND:
1451 DPRINTF(("I_GETBANK\n"));
1452 return 0;
1453
1454 case SVR4_I_ATMARK:
1455 DPRINTF(("I_ATMARK\n"));
1456 return 0;
1457
1458 case SVR4_I_SETCLTIME:
1459 DPRINTF(("I_SETCLTIME\n"));
1460 return 0;
1461
1462 case SVR4_I_GETCLTIME:
1463 DPRINTF(("I_GETCLTIME\n"));
1464 return 0;
1465
1466 case SVR4_I_CANPUT:
1467 DPRINTF(("I_CANPUT\n"));
1468 return 0;
1469
1470 case SVR4__I_BIND_RSVD:
1471 DPRINTF(("_I_BIND_RSVD\n"));
1472 return _i_bind_rsvd(fp, l, retval, fd, cmd, dat);
1473
1474 case SVR4__I_RELE_RSVD:
1475 DPRINTF(("_I_RELE_RSVD\n"));
1476 return _i_rele_rsvd(fp, l, retval, fd, cmd, dat);
1477
1478 default:
1479 DPRINTF(("unimpl cmd = %lx\n", cmd));
1480 break;
1481 }
1482 return 0;
1483 }
1484
1485
1486
1487
1488 int
1489 svr4_32_sys_putmsg(l, v, retval)
1490 struct lwp *l;
1491 void *v;
1492 register_t *retval;
1493 {
1494 struct svr4_32_sys_putmsg_args *uap = v;
1495 struct proc *p = l->l_proc;
1496 struct filedesc *fdp = p->p_fd;
1497 struct file *fp;
1498 struct svr4_32_strbuf dat, ctl;
1499 struct svr4_32_strmcmd sc;
1500 struct sockaddr_in sain;
1501 struct sockaddr_un saun;
1502 void *skp, *sup;
1503 int sasize;
1504 struct svr4_strm *st;
1505 int error;
1506 caddr_t sg;
1507
1508 #ifdef DEBUG_SVR4
1509 show_msg(">putmsg", SCARG(uap, fd), SCARG(uap, ctl),
1510 SCARG(uap, dat), SCARG(uap, flags));
1511 #endif /* DEBUG_SVR4 */
1512
1513 if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
1514 return EBADF;
1515
1516 if (SCARG(uap, ctl)) {
1517 if ((error = copyin((caddr_t)(u_long)SCARG(uap, ctl),
1518 &ctl, sizeof(ctl))) != 0)
1519 return error;
1520 }
1521 else
1522 ctl.len = -1;
1523
1524 if (SCARG(uap, dat)) {
1525 if ((error = copyin((caddr_t)(u_long)SCARG(uap, dat),
1526 &dat, sizeof(dat))) != 0)
1527 return error;
1528 }
1529 else
1530 dat.len = -1;
1531
1532 /*
1533 * Only for sockets for now.
1534 */
1535 if ((st = svr4_32_stream_get(fp)) == NULL) {
1536 DPRINTF(("putmsg: bad file type\n"));
1537 return EINVAL;
1538 }
1539
1540 if (ctl.len > sizeof(sc)) {
1541 DPRINTF(("putmsg: Bad control size %ld != %d\n",
1542 (unsigned long)sizeof(struct svr4_32_strmcmd), ctl.len));
1543 return EINVAL;
1544 }
1545
1546 if ((error = copyin((caddr_t)(u_long)ctl.buf, &sc, ctl.len)) != 0)
1547 return error;
1548
1549 switch (st->s_family) {
1550 case AF_INET:
1551 if (sc.len != sizeof(sain)) {
1552 #ifdef notyet
1553 if (sc.cmd == SVR4_TI_DATA_REQUEST) {
1554 struct sys_write_args wa;
1555
1556 /* Solaris seems to use sc.cmd = 3 to
1557 * send "expedited" data. telnet uses
1558 * this for options processing, sending EOF,
1559 * etc. I'm sure other things use it too.
1560 * I don't have any documentation
1561 * on it, so I'm making a guess that this
1562 * is how it works. newton@atdot.dotat.org XXX
1563 *
1564 * Hmm, expedited data seems to be sc.cmd = 4.
1565 * I think 3 is normal data. (christos)
1566 */
1567 DPRINTF(("sending expedited data (?)\n"));
1568 SCARG(&wa, fd) = SCARG(uap, fd);
1569 SCARG(&wa, buf) = dat.buf;
1570 SCARG(&wa, nbyte) = dat.len;
1571 return sys_write(p, &wa, retval);
1572 }
1573 #endif
1574 DPRINTF(("putmsg: Invalid inet length %ld\n", sc.len));
1575 return EINVAL;
1576 }
1577 netaddr_to_sockaddr_in(&sain, &sc);
1578 skp = &sain;
1579 sasize = sizeof(sain);
1580 error = sain.sin_family != st->s_family;
1581 break;
1582
1583 case AF_LOCAL:
1584 if (ctl.len == 8) {
1585 /* We are doing an accept; succeed */
1586 DPRINTF(("putmsg: Do nothing\n"));
1587 *retval = 0;
1588 return 0;
1589 }
1590 else {
1591 /* Maybe we've been given a device/inode pair */
1592 dev_t *dev = SVR4_ADDROF(&sc);
1593 svr4_ino_t *ino = (svr4_ino_t *) &dev[1];
1594 skp = svr4_find_socket(p, fp, *dev, *ino);
1595 if (skp == NULL) {
1596 skp = &saun;
1597 /* I guess we have it by name */
1598 netaddr_to_sockaddr_un(skp, &sc);
1599 }
1600 sasize = sizeof(saun);
1601 }
1602 break;
1603
1604 default:
1605 DPRINTF(("putmsg: Unsupported address family %d\n",
1606 st->s_family));
1607 return ENOSYS;
1608 }
1609
1610 sg = stackgap_init(p, 0);
1611 sup = stackgap_alloc(p, &sg, sasize);
1612
1613 if ((error = copyout(skp, sup, sasize)) != 0)
1614 return error;
1615
1616 switch (st->s_cmd = sc.cmd) {
1617 case SVR4_TI_CONNECT_REQUEST: /* connect */
1618 {
1619 struct sys_connect_args co;
1620
1621 SCARG(&co, s) = SCARG(uap, fd);
1622 SCARG(&co, name) = (void *) sup;
1623 SCARG(&co, namelen) = (int) sasize;
1624 return sys_connect(l, &co, retval);
1625 }
1626
1627 case SVR4_TI_SENDTO_REQUEST: /* sendto */
1628 {
1629 struct msghdr msg;
1630 struct iovec aiov;
1631
1632 msg.msg_name = (caddr_t) sup;
1633 msg.msg_namelen = sasize;
1634 msg.msg_iov = &aiov;
1635 msg.msg_iovlen = 1;
1636 msg.msg_control = 0;
1637 msg.msg_flags = 0;
1638 aiov.iov_base = (caddr_t)(u_long)dat.buf;
1639 aiov.iov_len = dat.len;
1640 error = sendit(l, SCARG(uap, fd), &msg,
1641 SCARG(uap, flags), retval);
1642
1643 *retval = 0;
1644 return error;
1645 }
1646
1647 default:
1648 DPRINTF(("putmsg: Unimplemented command %lx\n", sc.cmd));
1649 return ENOSYS;
1650 }
1651 }
1652
1653
1654 int
1655 svr4_32_sys_getmsg(l, v, retval)
1656 struct lwp *l;
1657 void *v;
1658 register_t *retval;
1659 {
1660 struct svr4_32_sys_getmsg_args *uap = v;
1661 struct proc *p = l->l_proc;
1662 struct filedesc *fdp = p->p_fd;
1663 struct file *fp;
1664 struct sys_getpeername_args ga;
1665 struct sys_accept_args aa;
1666 struct svr4_32_strbuf dat, ctl;
1667 struct svr4_32_strmcmd sc;
1668 int error;
1669 struct msghdr msg;
1670 struct iovec aiov;
1671 struct sockaddr_in sain;
1672 struct sockaddr_un saun;
1673 void *skp, *sup;
1674 int sasize;
1675 struct svr4_strm *st;
1676 int *flen;
1677 int fl;
1678 caddr_t sg;
1679
1680 memset(&sc, 0, sizeof(sc));
1681
1682 #ifdef DEBUG_SVR4
1683 show_msg(">getmsg", SCARG(uap, fd), SCARG(uap, ctl),
1684 SCARG(uap, dat), 0);
1685 #endif /* DEBUG_SVR4 */
1686
1687 if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
1688 return EBADF;
1689
1690 if (SCARG(uap, ctl)) {
1691 if ((error = copyin((caddr_t)(u_long)SCARG(uap, ctl),
1692 &ctl, sizeof(ctl))) != 0)
1693 return error;
1694 }
1695 else {
1696 ctl.len = -1;
1697 ctl.maxlen = 0;
1698 }
1699
1700 if (SCARG(uap, dat)) {
1701 if ((error = copyin((caddr_t)(u_long)SCARG(uap, dat),
1702 &dat, sizeof(dat))) != 0)
1703 return error;
1704 }
1705 else {
1706 dat.len = -1;
1707 dat.maxlen = 0;
1708 }
1709
1710 /*
1711 * Only for sockets for now.
1712 */
1713 if ((st = svr4_32_stream_get(fp)) == NULL) {
1714 DPRINTF(("getmsg: bad file type\n"));
1715 return EINVAL;
1716 }
1717
1718 if (ctl.maxlen == -1 || dat.maxlen == -1) {
1719 DPRINTF(("getmsg: Cannot handle -1 maxlen (yet)\n"));
1720 return ENOSYS;
1721 }
1722
1723 switch (st->s_family) {
1724 case AF_INET:
1725 skp = &sain;
1726 sasize = sizeof(sain);
1727 break;
1728
1729 case AF_LOCAL:
1730 skp = &saun;
1731 sasize = sizeof(saun);
1732 break;
1733
1734 default:
1735 DPRINTF(("getmsg: Unsupported address family %d\n",
1736 st->s_family));
1737 return ENOSYS;
1738 }
1739
1740 sg = stackgap_init(p, 0);
1741 sup = stackgap_alloc(p, &sg, sasize);
1742 flen = (int *) stackgap_alloc(p, &sg, sizeof(*flen));
1743
1744 fl = sasize;
1745 if ((error = copyout(&fl, flen, sizeof(fl))) != 0)
1746 return error;
1747
1748 switch (st->s_cmd) {
1749 case SVR4_TI_CONNECT_REQUEST:
1750 DPRINTF(("getmsg: TI_CONNECT_REQUEST\n"));
1751 /*
1752 * We do the connect in one step, so the putmsg should
1753 * have gotten the error.
1754 */
1755 sc.cmd = SVR4_TI_OK_REPLY;
1756 sc.len = 0;
1757
1758 ctl.len = 8;
1759 dat.len = -1;
1760 fl = 1;
1761 st->s_cmd = sc.cmd;
1762 break;
1763
1764 case SVR4_TI_OK_REPLY:
1765 DPRINTF(("getmsg: TI_OK_REPLY\n"));
1766 /*
1767 * We are immediately after a connect reply, so we send
1768 * a connect verification.
1769 */
1770
1771 SCARG(&ga, fdes) = SCARG(uap, fd);
1772 SCARG(&ga, asa) = (void *) sup;
1773 SCARG(&ga, alen) = (socklen_t *)flen;
1774
1775 if ((error = sys_getpeername(l, &ga, retval)) != 0) {
1776 DPRINTF(("getmsg: getpeername failed %d\n", error));
1777 return error;
1778 }
1779
1780 if ((error = copyin(sup, skp, sasize)) != 0)
1781 return error;
1782
1783 sc.cmd = SVR4_TI_CONNECT_REPLY;
1784 sc.pad[0] = 0x4;
1785 sc.offs = 0x18;
1786 sc.pad[1] = 0x14;
1787 sc.pad[2] = 0x04000402;
1788
1789 switch (st->s_family) {
1790 case AF_INET:
1791 sc.len = sasize;
1792 sockaddr_to_netaddr_in(&sc, &sain);
1793 break;
1794
1795 case AF_LOCAL:
1796 sc.len = sasize + 4;
1797 sockaddr_to_netaddr_un(&sc, &saun);
1798 break;
1799
1800 default:
1801 return ENOSYS;
1802 }
1803
1804 ctl.len = 40;
1805 dat.len = -1;
1806 fl = 0;
1807 st->s_cmd = sc.cmd;
1808 break;
1809
1810 case SVR4_TI__ACCEPT_OK:
1811 DPRINTF(("getmsg: TI__ACCEPT_OK\n"));
1812 /*
1813 * We do the connect in one step, so the putmsg should
1814 * have gotten the error.
1815 */
1816 sc.cmd = SVR4_TI_OK_REPLY;
1817 sc.len = 1;
1818
1819 ctl.len = 8;
1820 dat.len = -1;
1821 fl = 1;
1822 st->s_cmd = SVR4_TI__ACCEPT_WAIT;
1823 break;
1824
1825 case SVR4_TI__ACCEPT_WAIT:
1826 DPRINTF(("getmsg: TI__ACCEPT_WAIT\n"));
1827 /*
1828 * We are after a listen, so we try to accept...
1829 */
1830 SCARG(&aa, s) = SCARG(uap, fd);
1831 SCARG(&aa, name) = (void *) sup;
1832 SCARG(&aa, anamelen) = (socklen_t *)flen;
1833
1834 if ((error = sys_accept(l, &aa, retval)) != 0) {
1835 DPRINTF(("getmsg: accept failed %d\n", error));
1836 return error;
1837 }
1838
1839 st->s_afd = *retval;
1840
1841 DPRINTF(("getmsg: Accept fd = %d\n", st->s_afd));
1842
1843 if ((error = copyin(sup, skp, sasize)) != 0)
1844 return error;
1845
1846 sc.cmd = SVR4_TI_ACCEPT_REPLY;
1847 sc.offs = 0x18;
1848 sc.pad[0] = 0x0;
1849
1850 switch (st->s_family) {
1851 case AF_INET:
1852 sc.pad[1] = 0x28;
1853 sockaddr_to_netaddr_in(&sc, &sain);
1854 ctl.len = 40;
1855 sc.len = sasize;
1856 break;
1857
1858 case AF_LOCAL:
1859 sc.pad[1] = 0x00010000;
1860 sc.pad[2] = 0xf6bcdaa0; /* I don't know what that is */
1861 sc.pad[3] = 0x00010000;
1862 ctl.len = 134;
1863 sc.len = sasize + 4;
1864 break;
1865
1866 default:
1867 return ENOSYS;
1868 }
1869
1870 dat.len = -1;
1871 fl = 0;
1872 st->s_cmd = SVR4_TI__ACCEPT_OK;
1873 break;
1874
1875 case SVR4_TI_SENDTO_REQUEST:
1876 DPRINTF(("getmsg: TI_SENDTO_REQUEST\n"));
1877 if (ctl.maxlen > 36 && ctl.len < 36)
1878 ctl.len = 36;
1879 if (ctl.len > sizeof(sc))
1880 ctl.len = sizeof(sc);
1881
1882 if ((error = copyin((caddr_t)(u_long)ctl.buf, &sc, ctl.len)) != 0)
1883 return error;
1884
1885 switch (st->s_family) {
1886 case AF_INET:
1887 sockaddr_to_netaddr_in(&sc, &sain);
1888 break;
1889
1890 case AF_LOCAL:
1891 sockaddr_to_netaddr_un(&sc, &saun);
1892 break;
1893
1894 default:
1895 return ENOSYS;
1896 }
1897
1898 msg.msg_name = (caddr_t) sup;
1899 msg.msg_namelen = sasize;
1900 msg.msg_iov = &aiov;
1901 msg.msg_iovlen = 1;
1902 msg.msg_control = 0;
1903 aiov.iov_base = (caddr_t)(u_long)dat.buf;
1904 aiov.iov_len = dat.maxlen;
1905 msg.msg_flags = 0;
1906
1907 error = recvit(l, SCARG(uap, fd), &msg, (caddr_t) flen,
1908 retval);
1909
1910 if (error) {
1911 DPRINTF(("getmsg: recvit failed %d\n", error));
1912 return error;
1913 }
1914
1915 if ((error = copyin(msg.msg_name, skp, sasize)) != 0)
1916 return error;
1917
1918 sc.cmd = SVR4_TI_RECVFROM_IND;
1919
1920 switch (st->s_family) {
1921 case AF_INET:
1922 sc.len = sasize;
1923 sockaddr_to_netaddr_in(&sc, &sain);
1924 break;
1925
1926 case AF_LOCAL:
1927 sc.len = sasize + 4;
1928 sockaddr_to_netaddr_un(&sc, &saun);
1929 break;
1930
1931 default:
1932 return ENOSYS;
1933 }
1934
1935 dat.len = *retval;
1936 fl = 0;
1937 st->s_cmd = sc.cmd;
1938 break;
1939
1940 default:
1941 st->s_cmd = sc.cmd;
1942 #ifdef notyet
1943 if (st->s_cmd == SVR4_TI_CONNECT_REQUEST) {
1944 struct sys_read_args ra;
1945
1946 /* More weirdness: Again, I can't find documentation
1947 * to back this up, but when a process does a generic
1948 * "getmsg()" call it seems that the command field is
1949 * zero and the length of the data area is zero. I
1950 * think processes expect getmsg() to fill in dat.len
1951 * after reading at most dat.maxlen octets from the
1952 * stream. Since we're using sockets I can let
1953 * read() look after it and frob return values
1954 * appropriately (or inappropriately :-)
1955 * -- newton@atdot.dotat.org XXX
1956 */
1957 SCARG(&ra, fd) = SCARG(uap, fd);
1958 SCARG(&ra, buf) = dat.buf;
1959 SCARG(&ra, nbyte) = dat.maxlen;
1960 if ((error = sys_read(p, &ra, retval)) != 0)
1961 return error;
1962 dat.len = *retval;
1963 *retval = 0;
1964 st->s_cmd = SVR4_TI_SENDTO_REQUEST;
1965 break;
1966
1967 }
1968 #endif
1969 DPRINTF(("getmsg: Unknown state %x\n", st->s_cmd));
1970 return EINVAL;
1971 }
1972
1973 if (SCARG(uap, ctl)) {
1974 if (ctl.len != -1)
1975 if ((error = copyout(&sc, (caddr_t)(u_long)ctl.buf,
1976 ctl.len)) != 0)
1977 return error;
1978
1979 if ((error = copyout(&ctl, (caddr_t)(u_long)SCARG(uap, ctl),
1980 sizeof(ctl))) != 0)
1981 return error;
1982 }
1983
1984 if (SCARG(uap, dat)) {
1985 if ((error = copyout(&dat, (caddr_t)(u_long)SCARG(uap, dat),
1986 sizeof(dat))) != 0)
1987 return error;
1988 }
1989
1990 if (SCARG(uap, flags)) { /* XXX: Need translation */
1991 if ((error = copyout(&fl, (caddr_t)(u_long)SCARG(uap, flags),
1992 sizeof(fl))) != 0)
1993 return error;
1994 }
1995
1996 *retval = 0;
1997
1998 #ifdef DEBUG_SVR4
1999 show_msg("<getmsg", SCARG(uap, fd), SCARG(uap, ctl),
2000 SCARG(uap, dat), fl);
2001 #endif /* DEBUG_SVR4 */
2002 return error;
2003 }
Cache object: cb30a7874f901010e7d9f183f1315696
|