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