1 /* $NetBSD: svr4_32_stream.c,v 1.13 2003/10/21 09:02:50 petrov 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.13 2003/10/21 09:02:50 petrov 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___lstat13_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___lstat13(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
450 if (ioc->len != sizeof(ud) && ioc->len != sizeof(ud) - sizeof(int)) {
451 DPRINTF(("SI_OGETUDATA: Wrong size %ld != %d\n",
452 (unsigned long)sizeof(ud), ioc->len));
453 return EINVAL;
454 }
455
456 if ((error = copyin((caddr_t)(u_long)ioc->buf, &ud, sizeof(ud))) != 0)
457 return error;
458
459 getparm(fp, &pa);
460
461 switch (pa.family) {
462 case AF_INET:
463 ud.tidusize = 16384;
464 ud.addrsize = sizeof(struct sockaddr_in);
465 if (pa.type == SVR4_SOCK_STREAM)
466 ud.etsdusize = 1;
467 else
468 ud.etsdusize = 0;
469 break;
470
471 case AF_LOCAL:
472 ud.tidusize = 65536;
473 ud.addrsize = 128;
474 ud.etsdusize = 128;
475 break;
476
477 default:
478 DPRINTF(("SI_OGETUDATA: Unsupported address family %d\n",
479 pa.family));
480 return ENOSYS;
481 }
482
483 /* I have no idea what these should be! */
484 ud.optsize = 128;
485 ud.tsdusize = 128;
486
487 ud.servtype = pa.type;
488
489 /* XXX: Fixme */
490 ud.so_state = 0;
491 ud.so_options = 0;
492 return copyout(&ud, (caddr_t)(u_long)ioc->buf, ioc->len);
493 }
494
495
496 static int
497 si_sockparams(fp, fd, ioc, l)
498 struct file *fp;
499 int fd;
500 struct svr4_32_strioctl *ioc;
501 struct lwp *l;
502 {
503 struct svr4_si_sockparms pa;
504
505 getparm(fp, &pa);
506 return copyout(&pa, (caddr_t)(u_long)ioc->buf, sizeof(pa));
507 }
508
509
510 static int
511 si_listen(fp, fd, ioc, l)
512 struct file *fp;
513 int fd;
514 struct svr4_32_strioctl *ioc;
515 struct lwp *l;
516 {
517 int error;
518 struct svr4_strm *st = svr4_32_stream_get(fp);
519 register_t retval;
520 struct svr4_32_strmcmd lst;
521 struct sys_listen_args la;
522
523 if (st == NULL)
524 return EINVAL;
525
526 if (ioc->len > sizeof(lst))
527 return EINVAL;
528
529 if ((error = copyin((caddr_t)(u_long)ioc->buf, &lst, ioc->len)) != 0)
530 return error;
531
532 if (lst.cmd != SVR4_TI_OLD_BIND_REQUEST) {
533 DPRINTF(("si_listen: bad request %ld\n", lst.cmd));
534 return EINVAL;
535 }
536
537 /*
538 * We are making assumptions again...
539 */
540 SCARG(&la, s) = fd;
541 DPRINTF(("SI_LISTEN: fileno %d backlog = %d\n", fd, 5));
542 SCARG(&la, backlog) = 5;
543
544 if ((error = sys_listen(l, &la, &retval)) != 0) {
545 DPRINTF(("SI_LISTEN: listen failed %d\n", error));
546 return error;
547 }
548
549 st->s_cmd = SVR4_TI__ACCEPT_WAIT;
550 lst.cmd = SVR4_TI_BIND_REPLY;
551
552 switch (st->s_family) {
553 case AF_INET:
554 /* XXX: Fill the length here */
555 break;
556
557 case AF_LOCAL:
558 lst.len = 140;
559 lst.pad[28] = 0x00000000; /* magic again */
560 lst.pad[29] = 0x00000800; /* magic again */
561 lst.pad[30] = 0x80001400; /* magic again */
562 break;
563
564 default:
565 DPRINTF(("SI_LISTEN: Unsupported address family %d\n",
566 st->s_family));
567 return ENOSYS;
568 }
569
570
571 if ((error = copyout(&lst, (caddr_t)(u_long)ioc->buf, ioc->len)) != 0)
572 return error;
573
574 return 0;
575 }
576
577
578 static int
579 si_getudata(fp, fd, ioc, l)
580 struct file *fp;
581 int fd;
582 struct svr4_32_strioctl *ioc;
583 struct lwp *l;
584 {
585 int error;
586 struct svr4_si_udata ud;
587
588 if (sizeof(ud) != ioc->len) {
589 DPRINTF(("SI_GETUDATA: Wrong size %ld != %d\n",
590 (unsigned long)sizeof(ud), ioc->len));
591 return EINVAL;
592 }
593
594 if ((error = copyin((caddr_t)(u_long)ioc->buf, &ud, sizeof(ud))) != 0)
595 return error;
596
597 getparm(fp, &ud.sockparms);
598
599 switch (ud.sockparms.family) {
600 case AF_INET:
601 ud.tidusize = 16384;
602 ud.tsdusize = 16384;
603 ud.addrsize = sizeof(struct sockaddr_in);
604 if (ud.sockparms.type == SVR4_SOCK_STREAM)
605 ud.etsdusize = 1;
606 else
607 ud.etsdusize = 0;
608 ud.optsize = 0;
609 break;
610
611 case AF_LOCAL:
612 ud.tidusize = 65536;
613 ud.tsdusize = 128;
614 ud.addrsize = 128;
615 ud.etsdusize = 128;
616 ud.optsize = 128;
617 break;
618
619 default:
620 DPRINTF(("SI_GETUDATA: Unsupported address family %d\n",
621 ud.sockparms.family));
622 return ENOSYS;
623 }
624
625
626 ud.servtype = ud.sockparms.type;
627
628 /* XXX: Fixme */
629 ud.so_state = 0;
630 ud.so_options = 0;
631 return copyout(&ud, (caddr_t)(u_long)ioc->buf, sizeof(ud));
632 }
633
634
635 static int
636 si_shutdown(fp, fd, ioc, l)
637 struct file *fp;
638 int fd;
639 struct svr4_32_strioctl *ioc;
640 struct lwp *l;
641 {
642 int error;
643 struct sys_shutdown_args ap;
644 register_t retval;
645
646 if (ioc->len != sizeof(SCARG(&ap, how))) {
647 DPRINTF(("SI_SHUTDOWN: Wrong size %ld != %d\n",
648 (unsigned long)sizeof(SCARG(&ap, how)), ioc->len));
649 return EINVAL;
650 }
651
652 if ((error = copyin((caddr_t)(u_long)ioc->buf, &SCARG(&ap, how), ioc->len)) != 0)
653 return error;
654
655 SCARG(&ap, s) = fd;
656
657 return sys_shutdown(l, &ap, &retval);
658 }
659
660 static int
661 sockmod(fp, fd, ioc, l)
662 struct file *fp;
663 int fd;
664 struct svr4_32_strioctl *ioc;
665 struct lwp *l;
666 {
667 switch (ioc->cmd) {
668 case SVR4_SI_OGETUDATA:
669 DPRINTF(("SI_OGETUDATA\n"));
670 return si_ogetudata(fp, fd, ioc, l);
671
672 case SVR4_SI_SHUTDOWN:
673 DPRINTF(("SI_SHUTDOWN\n"));
674 return si_shutdown(fp, fd, ioc, l);
675
676 case SVR4_SI_LISTEN:
677 DPRINTF(("SI_LISTEN\n"));
678 return si_listen(fp, fd, ioc, l);
679
680 case SVR4_SI_SETMYNAME:
681 DPRINTF(("SI_SETMYNAME\n"));
682 return 0;
683
684 case SVR4_SI_SETPEERNAME:
685 DPRINTF(("SI_SETPEERNAME\n"));
686 return 0;
687
688 case SVR4_SI_GETINTRANSIT:
689 DPRINTF(("SI_GETINTRANSIT\n"));
690 return 0;
691
692 case SVR4_SI_TCL_LINK:
693 DPRINTF(("SI_TCL_LINK\n"));
694 return 0;
695
696 case SVR4_SI_TCL_UNLINK:
697 DPRINTF(("SI_TCL_UNLINK\n"));
698 return 0;
699
700 case SVR4_SI_SOCKPARAMS:
701 DPRINTF(("SI_SOCKPARAMS\n"));
702 return si_sockparams(fp, fd, ioc, l);
703
704 case SVR4_SI_GETUDATA:
705 DPRINTF(("SI_GETUDATA\n"));
706 return si_getudata(fp, fd, ioc, l);
707
708 default:
709 DPRINTF(("Unknown sockmod ioctl %lx\n", ioc->cmd));
710 return 0;
711
712 }
713 }
714
715 static int
716 ti_getinfo(fp, fd, ioc, l)
717 struct file *fp;
718 int fd;
719 struct svr4_32_strioctl *ioc;
720 struct lwp *l;
721 {
722 int error;
723 struct svr4_32_infocmd info;
724
725 memset(&info, 0, sizeof(info));
726
727 if (ioc->len > sizeof(info))
728 return EINVAL;
729
730 if ((error = copyin((caddr_t)(u_long)ioc->buf, &info, ioc->len)) != 0)
731 return error;
732
733 if (info.cmd != SVR4_TI_INFO_REQUEST)
734 return EINVAL;
735
736 info.cmd = SVR4_TI_INFO_REPLY;
737 info.tsdu = 0;
738 info.etsdu = 1;
739 info.cdata = -2;
740 info.ddata = -2;
741 info.addr = 16;
742 info.opt = -1;
743 info.tidu = 16384;
744 info.serv = 2;
745 info.current = 0;
746 info.provider = 2;
747
748 ioc->len = sizeof(info);
749 if ((error = copyout(&info, (caddr_t)(u_long)ioc->buf, ioc->len)) != 0)
750 return error;
751
752 return 0;
753 }
754
755
756 static int
757 ti_bind(fp, fd, ioc, l)
758 struct file *fp;
759 int fd;
760 struct svr4_32_strioctl *ioc;
761 struct lwp *l;
762 {
763 int error;
764 struct proc *p = l->l_proc;
765 struct svr4_strm *st = svr4_32_stream_get(fp);
766 struct sockaddr_in sain;
767 struct sockaddr_un saun;
768 register_t retval;
769 caddr_t sg;
770 void *skp, *sup = NULL;
771 int sasize;
772 struct svr4_32_strmcmd bnd;
773 struct sys_bind_args ba;
774
775 if (st == NULL) {
776 DPRINTF(("ti_bind: bad file descriptor\n"));
777 return EINVAL;
778 }
779
780 if (ioc->len > sizeof(bnd))
781 return EINVAL;
782
783 if ((error = copyin((caddr_t)(u_long)ioc->buf, &bnd, ioc->len)) != 0)
784 return error;
785
786 if (bnd.cmd != SVR4_TI_OLD_BIND_REQUEST) {
787 DPRINTF(("ti_bind: bad request %ld\n", bnd.cmd));
788 return EINVAL;
789 }
790
791 switch (st->s_family) {
792 case AF_INET:
793 skp = &sain;
794 sasize = sizeof(sain);
795
796 if (bnd.offs == 0)
797 goto reply;
798
799 netaddr_to_sockaddr_in(&sain, &bnd);
800
801 DPRINTF(("TI_BIND: fam %d, port %d, addr %x\n",
802 sain.sin_family, sain.sin_port,
803 sain.sin_addr.s_addr));
804 break;
805
806 case AF_LOCAL:
807 skp = &saun;
808 sasize = sizeof(saun);
809 if (bnd.offs == 0)
810 goto reply;
811
812 netaddr_to_sockaddr_un(&saun, &bnd);
813
814 if (saun.sun_path[0] == '\0')
815 goto reply;
816
817 DPRINTF(("TI_BIND: fam %d, path %s\n",
818 saun.sun_family, saun.sun_path));
819
820 if ((error = clean_pipe(l, saun.sun_path)) != 0)
821 return error;
822
823 bnd.pad[28] = 0x00001000; /* magic again */
824 break;
825
826 default:
827 DPRINTF(("TI_BIND: Unsupported address family %d\n",
828 st->s_family));
829 return ENOSYS;
830 }
831
832 sg = stackgap_init(p, 0);
833 sup = stackgap_alloc(p, &sg, sasize);
834
835 if ((error = copyout(skp, sup, sasize)) != 0)
836 return error;
837
838 SCARG(&ba, s) = fd;
839 DPRINTF(("TI_BIND: fileno %d\n", fd));
840 SCARG(&ba, name) = (void *) sup;
841 SCARG(&ba, namelen) = sasize;
842
843 if ((error = sys_bind(l, &ba, &retval)) != 0) {
844 DPRINTF(("TI_BIND: bind failed %d\n", error));
845 return error;
846 }
847
848 reply:
849 if (sup == NULL) {
850 memset(&bnd, 0, sizeof(bnd));
851 bnd.len = sasize + 4;
852 bnd.offs = 0x10; /* XXX */
853 }
854
855 bnd.cmd = SVR4_TI_BIND_REPLY;
856
857 if ((error = copyout(&bnd, (caddr_t)(u_long)ioc->buf, ioc->len)) != 0)
858 return error;
859
860 return 0;
861 }
862
863
864 static int
865 timod(fp, fd, ioc, l)
866 struct file *fp;
867 int fd;
868 struct svr4_32_strioctl *ioc;
869 struct lwp *l;
870 {
871 switch (ioc->cmd) {
872 case SVR4_TI_GETINFO:
873 DPRINTF(("TI_GETINFO\n"));
874 return ti_getinfo(fp, fd, ioc, l);
875
876 case SVR4_TI_OPTMGMT:
877 DPRINTF(("TI_OPTMGMT\n"));
878 return 0;
879
880 case SVR4_TI_BIND:
881 DPRINTF(("TI_BIND\n"));
882 return ti_bind(fp, fd, ioc, l);
883
884 case SVR4_TI_UNBIND:
885 DPRINTF(("TI_UNBIND\n"));
886 return 0;
887
888 default:
889 DPRINTF(("Unknown timod ioctl %lx\n", ioc->cmd));
890 return 0;
891 }
892 }
893
894 int
895 svr4_32_stream_ti_ioctl(fp, l, retval, fd, cmd, dat)
896 struct file *fp;
897 struct lwp *l;
898 register_t *retval;
899 int fd;
900 u_long cmd;
901 caddr_t dat;
902 {
903 struct proc *p = l->l_proc;
904 struct svr4_32_strbuf skb, *sub = (struct svr4_32_strbuf *) dat;
905 struct svr4_strm *st = svr4_32_stream_get(fp);
906 int error;
907 void *skp, *sup;
908 struct sockaddr_in sain;
909 struct sockaddr_un saun;
910 struct svr4_32_strmcmd sc;
911 int sasize;
912 caddr_t sg;
913 int *lenp;
914
915 if (st == NULL)
916 return EINVAL;
917
918 sc.offs = 0x10;
919
920 if ((error = copyin(sub, &skb, sizeof(skb))) != 0) {
921 DPRINTF(("ti_ioctl: error copying in strbuf\n"));
922 return error;
923 }
924
925 switch (st->s_family) {
926 case AF_INET:
927 skp = &sain;
928 sasize = sizeof(sain);
929 break;
930
931 case AF_LOCAL:
932 skp = &saun;
933 sasize = sizeof(saun);
934 break;
935
936 default:
937 DPRINTF(("ti_ioctl: Unsupported address family %d\n",
938 st->s_family));
939 return ENOSYS;
940 }
941
942 sg = stackgap_init(p, 0);
943 sup = stackgap_alloc(p, &sg, sasize);
944 lenp = stackgap_alloc(p, &sg, sizeof(*lenp));
945
946 if ((error = copyout(&sasize, lenp, sizeof(*lenp))) != 0) {
947 DPRINTF(("ti_ioctl: error copying out lenp\n"));
948 return error;
949 }
950
951 switch (cmd) {
952 case SVR4_TI_GETMYNAME:
953 DPRINTF(("TI_GETMYNAME\n"));
954 {
955 struct sys_getsockname_args ap;
956 SCARG(&ap, fdes) = fd;
957 SCARG(&ap, asa) = sup;
958 SCARG(&ap, alen) = lenp;
959 if ((error = sys_getsockname(l, &ap, retval)) != 0) {
960 DPRINTF(("ti_ioctl: getsockname error\n"));
961 return error;
962 }
963 }
964 break;
965
966 case SVR4_TI_GETPEERNAME:
967 DPRINTF(("TI_GETPEERNAME\n"));
968 {
969 struct sys_getpeername_args ap;
970 SCARG(&ap, fdes) = fd;
971 SCARG(&ap, asa) = sup;
972 SCARG(&ap, alen) = lenp;
973 if ((error = sys_getpeername(l, &ap, retval)) != 0) {
974 DPRINTF(("ti_ioctl: getpeername error\n"));
975 return error;
976 }
977 }
978 break;
979
980 case SVR4_TI_SETMYNAME:
981 DPRINTF(("TI_SETMYNAME\n"));
982 return 0;
983
984 case SVR4_TI_SETPEERNAME:
985 DPRINTF(("TI_SETPEERNAME\n"));
986 return 0;
987 default:
988 DPRINTF(("ti_ioctl: Unknown ioctl %lx\n", cmd));
989 return ENOSYS;
990 }
991
992 if ((error = copyin(sup, skp, sasize)) != 0) {
993 DPRINTF(("ti_ioctl: error copying in socket data\n"));
994 return error;
995 }
996
997 if ((error = copyin(lenp, &sasize, sizeof(*lenp))) != 0) {
998 DPRINTF(("ti_ioctl: error copying in socket size\n"));
999 return error;
1000 }
1001
1002 switch (st->s_family) {
1003 case AF_INET:
1004 sockaddr_to_netaddr_in(&sc, &sain);
1005 skb.len = sasize;
1006 break;
1007
1008 case AF_LOCAL:
1009 sockaddr_to_netaddr_un(&sc, &saun);
1010 skb.len = sasize + 4;
1011 break;
1012
1013 default:
1014 return ENOSYS;
1015 }
1016
1017
1018 if ((error = copyout(SVR4_ADDROF(&sc), (caddr_t)(u_long)skb.buf,
1019 sasize)) != 0) {
1020 DPRINTF(("ti_ioctl: error copying out socket data\n"));
1021 return error;
1022 }
1023
1024
1025 if ((error = copyout(&skb, sub, sizeof(skb))) != 0) {
1026 DPRINTF(("ti_ioctl: error copying out strbuf\n"));
1027 return error;
1028 }
1029
1030 return error;
1031 }
1032
1033
1034 static int
1035 i_nread(fp, l, retval, fd, cmd, dat)
1036 struct file *fp;
1037 struct lwp *l;
1038 register_t *retval;
1039 int fd;
1040 u_long cmd;
1041 caddr_t dat;
1042 {
1043 int error;
1044 int nread = 0;
1045
1046 /*
1047 * We are supposed to return the message length in nread, and the
1048 * number of messages in retval. We don't have the notion of number
1049 * of stream messages, so we just find out if we have any bytes waiting
1050 * for us, and if we do, then we assume that we have at least one
1051 * message waiting for us.
1052 */
1053 if ((error = (*fp->f_ops->fo_ioctl)(fp, FIONREAD,
1054 (caddr_t) &nread, l->l_proc)) != 0)
1055 return error;
1056
1057 if (nread != 0)
1058 *retval = 1;
1059 else
1060 *retval = 0;
1061
1062 return copyout(&nread, dat, sizeof(nread));
1063 }
1064
1065 static int
1066 i_fdinsert(fp, l, retval, fd, cmd, dat)
1067 struct file *fp;
1068 struct lwp *l;
1069 register_t *retval;
1070 int fd;
1071 u_long cmd;
1072 caddr_t dat;
1073 {
1074 /*
1075 * Major hack again here. We assume that we are using this to
1076 * implement accept(2). If that is the case, we have already
1077 * called accept, and we have stored the file descriptor in
1078 * afd. We find the file descriptor that the code wants to use
1079 * in fd insert, and then we dup2() our accepted file descriptor
1080 * to it.
1081 */
1082 int error;
1083 struct svr4_strm *st = svr4_32_stream_get(fp);
1084 struct svr4_32_strfdinsert fdi;
1085 struct sys_dup2_args d2p;
1086 struct sys_close_args clp;
1087
1088 if (st == NULL) {
1089 DPRINTF(("fdinsert: bad file type\n"));
1090 return EINVAL;
1091 }
1092
1093 if (st->s_afd == -1) {
1094 DPRINTF(("fdinsert: accept fd not found\n"));
1095 return ENOENT;
1096 }
1097
1098 if ((error = copyin(dat, &fdi, sizeof(fdi))) != 0) {
1099 DPRINTF(("fdinsert: copyin failed %d\n", error));
1100 return error;
1101 }
1102
1103 SCARG(&d2p, from) = st->s_afd;
1104 SCARG(&d2p, to) = fdi.fd;
1105
1106 if ((error = sys_dup2(l, &d2p, retval)) != 0) {
1107 DPRINTF(("fdinsert: dup2(%d, %d) failed %d\n",
1108 st->s_afd, fdi.fd, error));
1109 return error;
1110 }
1111
1112 SCARG(&clp, fd) = st->s_afd;
1113
1114 if ((error = sys_close(l, &clp, retval)) != 0) {
1115 DPRINTF(("fdinsert: close(%d) failed %d\n",
1116 st->s_afd, error));
1117 return error;
1118 }
1119
1120 st->s_afd = -1;
1121
1122 *retval = 0;
1123 return 0;
1124 }
1125
1126
1127 static int
1128 _i_bind_rsvd(fp, l, retval, fd, cmd, dat)
1129 struct file *fp;
1130 struct lwp *l;
1131 register_t *retval;
1132 int fd;
1133 u_long cmd;
1134 caddr_t dat;
1135 {
1136 struct sys_mknod_args ap;
1137
1138 /*
1139 * This is a supposed to be a kernel and library only ioctl.
1140 * It gets called before ti_bind, when we have a unix
1141 * socket, to physically create the socket transport and
1142 * ``reserve'' it. I don't know how this get reserved inside
1143 * the kernel, but we are going to create it nevertheless.
1144 */
1145 SCARG(&ap, path) = dat;
1146 SCARG(&ap, mode) = S_IFIFO;
1147
1148 return sys_mkfifo(l, &ap, retval);
1149 }
1150
1151 static int
1152 _i_rele_rsvd(fp, l, retval, fd, cmd, dat)
1153 struct file *fp;
1154 struct lwp *l;
1155 register_t *retval;
1156 int fd;
1157 u_long cmd;
1158 caddr_t dat;
1159 {
1160 struct sys_unlink_args ap;
1161
1162 /*
1163 * This is a supposed to be a kernel and library only ioctl.
1164 * I guess it is supposed to release the socket.
1165 */
1166 SCARG(&ap, path) = dat;
1167
1168 return sys_unlink(l, &ap, retval);
1169 }
1170
1171 static int
1172 i_str(fp, l, retval, fd, cmd, dat)
1173 struct file *fp;
1174 struct lwp *l;
1175 register_t *retval;
1176 int fd;
1177 u_long cmd;
1178 caddr_t dat;
1179 {
1180 int error;
1181 struct svr4_32_strioctl ioc;
1182
1183 /*
1184 * Noop on non sockets
1185 */
1186 if (fp->f_type != DTYPE_SOCKET)
1187 return 0;
1188
1189 if ((error = copyin(dat, &ioc, sizeof(ioc))) != 0)
1190 return error;
1191
1192 #ifdef DEBUG_SVR4
1193 if ((error = show_ioc(">", &ioc)) != 0)
1194 return error;
1195 #endif /* DEBUG_SVR4 */
1196
1197 switch (ioc.cmd & 0xff00) {
1198 case SVR4_SIMOD:
1199 if ((error = sockmod(fp, fd, &ioc, l)) != 0)
1200 return error;
1201 break;
1202
1203 case SVR4_TIMOD:
1204 if ((error = timod(fp, fd, &ioc, l)) != 0)
1205 return error;
1206 break;
1207
1208 default:
1209 DPRINTF(("Unimplemented module %c %ld\n",
1210 (char) (cmd >> 8), cmd & 0xff));
1211 return 0;
1212 }
1213
1214 #ifdef DEBUG_SVR4
1215 if ((error = show_ioc("<", &ioc)) != 0)
1216 return error;
1217 #endif /* DEBUG_SVR4 */
1218 return copyout(&ioc, dat, sizeof(ioc));
1219 }
1220
1221 static int
1222 i_setsig(fp, l, retval, fd, cmd, dat)
1223 struct file *fp;
1224 struct lwp *l;
1225 register_t *retval;
1226 int fd;
1227 u_long cmd;
1228 caddr_t dat;
1229 {
1230 /*
1231 * This is the best we can do for now; we cannot generate
1232 * signals only for specific events so the signal mask gets
1233 * ignored; we save it just to pass it to a possible I_GETSIG...
1234 *
1235 * We alse have to fix the O_ASYNC fcntl bit, so the
1236 * process will get SIGPOLLs.
1237 */
1238 struct sys_fcntl_args fa;
1239 int error;
1240 register_t oflags, flags;
1241 struct svr4_strm *st = svr4_32_stream_get(fp);
1242
1243 if (st == NULL) {
1244 DPRINTF(("i_setsig: bad file descriptor\n"));
1245 return EINVAL;
1246 }
1247 /* get old status flags */
1248 SCARG(&fa, fd) = fd;
1249 SCARG(&fa, cmd) = F_GETFL;
1250 if ((error = sys_fcntl(l, &fa, &oflags)) != 0)
1251 return error;
1252
1253 /* update the flags */
1254 if (dat != NULL) {
1255 int mask;
1256
1257 flags = oflags | O_ASYNC;
1258 mask = (int)(u_long)dat;
1259 if (mask & ~SVR4_S_ALLMASK) {
1260 DPRINTF(("i_setsig: bad eventmask data %x\n", mask));
1261 return EINVAL;
1262 }
1263 st->s_eventmask = mask;
1264 }
1265 else {
1266 flags = oflags & ~O_ASYNC;
1267 st->s_eventmask = 0;
1268 }
1269
1270 /* set the new flags, if changed */
1271 if (flags != oflags) {
1272 SCARG(&fa, cmd) = F_SETFL;
1273 SCARG(&fa, arg) = (void *) flags;
1274 if ((error = sys_fcntl(l, &fa, &flags)) != 0)
1275 return error;
1276 }
1277
1278 /* set up SIGIO receiver if needed */
1279 if (dat != NULL) {
1280 SCARG(&fa, cmd) = F_SETOWN;
1281 SCARG(&fa, arg) = (void *)(u_long)l->l_proc->p_pid;
1282 return sys_fcntl(l, &fa, &flags);
1283 }
1284 return 0;
1285 }
1286
1287 static int
1288 i_getsig(fp, l, retval, fd, cmd, dat)
1289 struct file *fp;
1290 struct lwp *l;
1291 register_t *retval;
1292 int fd;
1293 u_long cmd;
1294 caddr_t dat;
1295 {
1296 int error;
1297
1298 if (dat != NULL) {
1299 struct svr4_strm *st = svr4_32_stream_get(fp);
1300
1301 if (st == NULL) {
1302 DPRINTF(("i_getsig: bad file descriptor\n"));
1303 return EINVAL;
1304 }
1305 if ((error = copyout(&st->s_eventmask, dat,
1306 sizeof(st->s_eventmask))) != 0) {
1307 DPRINTF(("i_getsig: bad eventmask pointer\n"));
1308 return error;
1309 }
1310 }
1311 return 0;
1312 }
1313
1314 int
1315 svr4_32_stream_ioctl(fp, l, retval, fd, cmd, dat)
1316 struct file *fp;
1317 struct lwp *l;
1318 register_t *retval;
1319 int fd;
1320 u_long cmd;
1321 caddr_t dat;
1322 {
1323 *retval = 0;
1324 /*
1325 * All the following stuff assumes "sockmod" is pushed...
1326 */
1327 switch (cmd) {
1328 case SVR4_I_NREAD:
1329 DPRINTF(("I_NREAD\n"));
1330 return i_nread(fp, l, retval, fd, cmd, dat);
1331
1332 case SVR4_I_PUSH:
1333 DPRINTF(("I_PUSH\n"));
1334 return 0;
1335
1336 case SVR4_I_POP:
1337 DPRINTF(("I_POP\n"));
1338 return 0;
1339
1340 case SVR4_I_LOOK:
1341 DPRINTF(("I_LOOK\n"));
1342 return 0;
1343
1344 case SVR4_I_FLUSH:
1345 DPRINTF(("I_FLUSH\n"));
1346 return 0;
1347
1348 case SVR4_I_SRDOPT:
1349 DPRINTF(("I_SRDOPT\n"));
1350 return 0;
1351
1352 case SVR4_I_GRDOPT:
1353 DPRINTF(("I_GRDOPT\n"));
1354 return 0;
1355
1356 case SVR4_I_STR:
1357 DPRINTF(("I_STR\n"));
1358 return i_str(fp, l, retval, fd, cmd, dat);
1359
1360 case SVR4_I_SETSIG:
1361 DPRINTF(("I_SETSIG\n"));
1362 return i_setsig(fp, l, retval, fd, cmd, dat);
1363
1364 case SVR4_I_GETSIG:
1365 DPRINTF(("I_GETSIG\n"));
1366 return i_getsig(fp, l, retval, fd, cmd, dat);
1367
1368 case SVR4_I_FIND:
1369 DPRINTF(("I_FIND\n"));
1370 /*
1371 * Here we are not pushing modules really, we just
1372 * pretend all are present
1373 */
1374 *retval = 1;
1375 return 0;
1376
1377 case SVR4_I_LINK:
1378 DPRINTF(("I_LINK\n"));
1379 return 0;
1380
1381 case SVR4_I_UNLINK:
1382 DPRINTF(("I_UNLINK\n"));
1383 return 0;
1384
1385 case SVR4_I_ERECVFD:
1386 DPRINTF(("I_ERECVFD\n"));
1387 return 0;
1388
1389 case SVR4_I_PEEK:
1390 DPRINTF(("I_PEEK\n"));
1391 return 0;
1392
1393 case SVR4_I_FDINSERT:
1394 DPRINTF(("I_FDINSERT\n"));
1395 return i_fdinsert(fp, l, retval, fd, cmd, dat);
1396
1397 case SVR4_I_SENDFD:
1398 DPRINTF(("I_SENDFD\n"));
1399 return 0;
1400
1401 case SVR4_I_RECVFD:
1402 DPRINTF(("I_RECVFD\n"));
1403 return 0;
1404
1405 case SVR4_I_SWROPT:
1406 DPRINTF(("I_SWROPT\n"));
1407 return 0;
1408
1409 case SVR4_I_GWROPT:
1410 DPRINTF(("I_GWROPT\n"));
1411 return 0;
1412
1413 case SVR4_I_LIST:
1414 DPRINTF(("I_LIST\n"));
1415 return 0;
1416
1417 case SVR4_I_PLINK:
1418 DPRINTF(("I_PLINK\n"));
1419 return 0;
1420
1421 case SVR4_I_PUNLINK:
1422 DPRINTF(("I_PUNLINK\n"));
1423 return 0;
1424
1425 case SVR4_I_SETEV:
1426 DPRINTF(("I_SETEV\n"));
1427 return 0;
1428
1429 case SVR4_I_GETEV:
1430 DPRINTF(("I_GETEV\n"));
1431 return 0;
1432
1433 case SVR4_I_STREV:
1434 DPRINTF(("I_STREV\n"));
1435 return 0;
1436
1437 case SVR4_I_UNSTREV:
1438 DPRINTF(("I_UNSTREV\n"));
1439 return 0;
1440
1441 case SVR4_I_FLUSHBAND:
1442 DPRINTF(("I_FLUSHBAND\n"));
1443 return 0;
1444
1445 case SVR4_I_CKBAND:
1446 DPRINTF(("I_CKBAND\n"));
1447 return 0;
1448
1449 case SVR4_I_GETBAND:
1450 DPRINTF(("I_GETBANK\n"));
1451 return 0;
1452
1453 case SVR4_I_ATMARK:
1454 DPRINTF(("I_ATMARK\n"));
1455 return 0;
1456
1457 case SVR4_I_SETCLTIME:
1458 DPRINTF(("I_SETCLTIME\n"));
1459 return 0;
1460
1461 case SVR4_I_GETCLTIME:
1462 DPRINTF(("I_GETCLTIME\n"));
1463 return 0;
1464
1465 case SVR4_I_CANPUT:
1466 DPRINTF(("I_CANPUT\n"));
1467 return 0;
1468
1469 case SVR4__I_BIND_RSVD:
1470 DPRINTF(("_I_BIND_RSVD\n"));
1471 return _i_bind_rsvd(fp, l, retval, fd, cmd, dat);
1472
1473 case SVR4__I_RELE_RSVD:
1474 DPRINTF(("_I_RELE_RSVD\n"));
1475 return _i_rele_rsvd(fp, l, retval, fd, cmd, dat);
1476
1477 default:
1478 DPRINTF(("unimpl cmd = %lx\n", cmd));
1479 break;
1480 }
1481 return 0;
1482 }
1483
1484
1485
1486
1487 int
1488 svr4_32_sys_putmsg(l, v, retval)
1489 struct lwp *l;
1490 void *v;
1491 register_t *retval;
1492 {
1493 struct svr4_32_sys_putmsg_args *uap = v;
1494 struct proc *p = l->l_proc;
1495 struct filedesc *fdp = p->p_fd;
1496 struct file *fp;
1497 struct svr4_32_strbuf dat, ctl;
1498 struct svr4_32_strmcmd sc;
1499 struct sockaddr_in sain;
1500 struct sockaddr_un saun;
1501 void *skp, *sup;
1502 int sasize;
1503 struct svr4_strm *st;
1504 int error;
1505 caddr_t sg;
1506
1507 #ifdef DEBUG_SVR4
1508 show_msg(">putmsg", SCARG(uap, fd), SCARG(uap, ctl),
1509 SCARG(uap, dat), SCARG(uap, flags));
1510 #endif /* DEBUG_SVR4 */
1511
1512 if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
1513 return EBADF;
1514
1515 if (SCARG(uap, ctl)) {
1516 if ((error = copyin((caddr_t)(u_long)SCARG(uap, ctl),
1517 &ctl, sizeof(ctl))) != 0)
1518 return error;
1519 }
1520 else
1521 ctl.len = -1;
1522
1523 if (SCARG(uap, dat)) {
1524 if ((error = copyin((caddr_t)(u_long)SCARG(uap, dat),
1525 &dat, sizeof(dat))) != 0)
1526 return error;
1527 }
1528 else
1529 dat.len = -1;
1530
1531 /*
1532 * Only for sockets for now.
1533 */
1534 if ((st = svr4_32_stream_get(fp)) == NULL) {
1535 DPRINTF(("putmsg: bad file type\n"));
1536 return EINVAL;
1537 }
1538
1539 if (ctl.len > sizeof(sc)) {
1540 DPRINTF(("putmsg: Bad control size %ld != %d\n",
1541 (unsigned long)sizeof(struct svr4_32_strmcmd), ctl.len));
1542 return EINVAL;
1543 }
1544
1545 if ((error = copyin((caddr_t)(u_long)ctl.buf, &sc, ctl.len)) != 0)
1546 return error;
1547
1548 switch (st->s_family) {
1549 case AF_INET:
1550 if (sc.len != sizeof(sain)) {
1551 #ifdef notyet
1552 if (sc.cmd == SVR4_TI_DATA_REQUEST) {
1553 struct sys_write_args wa;
1554
1555 /* Solaris seems to use sc.cmd = 3 to
1556 * send "expedited" data. telnet uses
1557 * this for options processing, sending EOF,
1558 * etc. I'm sure other things use it too.
1559 * I don't have any documentation
1560 * on it, so I'm making a guess that this
1561 * is how it works. newton@atdot.dotat.org XXX
1562 *
1563 * Hmm, expedited data seems to be sc.cmd = 4.
1564 * I think 3 is normal data. (christos)
1565 */
1566 DPRINTF(("sending expedited data (?)\n"));
1567 SCARG(&wa, fd) = SCARG(uap, fd);
1568 SCARG(&wa, buf) = dat.buf;
1569 SCARG(&wa, nbyte) = dat.len;
1570 return sys_write(p, &wa, retval);
1571 }
1572 #endif
1573 DPRINTF(("putmsg: Invalid inet length %ld\n", sc.len));
1574 return EINVAL;
1575 }
1576 netaddr_to_sockaddr_in(&sain, &sc);
1577 skp = &sain;
1578 sasize = sizeof(sain);
1579 error = sain.sin_family != st->s_family;
1580 break;
1581
1582 case AF_LOCAL:
1583 if (ctl.len == 8) {
1584 /* We are doing an accept; succeed */
1585 DPRINTF(("putmsg: Do nothing\n"));
1586 *retval = 0;
1587 return 0;
1588 }
1589 else {
1590 /* Maybe we've been given a device/inode pair */
1591 dev_t *dev = SVR4_ADDROF(&sc);
1592 ino_t *ino = (ino_t *) &dev[1];
1593 skp = svr4_find_socket(p, fp, *dev, *ino);
1594 if (skp == NULL) {
1595 skp = &saun;
1596 /* I guess we have it by name */
1597 netaddr_to_sockaddr_un(skp, &sc);
1598 }
1599 sasize = sizeof(saun);
1600 }
1601 break;
1602
1603 default:
1604 DPRINTF(("putmsg: Unsupported address family %d\n",
1605 st->s_family));
1606 return ENOSYS;
1607 }
1608
1609 sg = stackgap_init(p, 0);
1610 sup = stackgap_alloc(p, &sg, sasize);
1611
1612 if ((error = copyout(skp, sup, sasize)) != 0)
1613 return error;
1614
1615 switch (st->s_cmd = sc.cmd) {
1616 case SVR4_TI_CONNECT_REQUEST: /* connect */
1617 {
1618 struct sys_connect_args co;
1619
1620 SCARG(&co, s) = SCARG(uap, fd);
1621 SCARG(&co, name) = (void *) sup;
1622 SCARG(&co, namelen) = (int) sasize;
1623 return sys_connect(l, &co, retval);
1624 }
1625
1626 case SVR4_TI_SENDTO_REQUEST: /* sendto */
1627 {
1628 struct msghdr msg;
1629 struct iovec aiov;
1630
1631 msg.msg_name = (caddr_t) sup;
1632 msg.msg_namelen = sasize;
1633 msg.msg_iov = &aiov;
1634 msg.msg_iovlen = 1;
1635 msg.msg_control = 0;
1636 msg.msg_flags = 0;
1637 aiov.iov_base = (caddr_t)(u_long)dat.buf;
1638 aiov.iov_len = dat.len;
1639 error = sendit(p, SCARG(uap, fd), &msg,
1640 SCARG(uap, flags), retval);
1641
1642 *retval = 0;
1643 return error;
1644 }
1645
1646 default:
1647 DPRINTF(("putmsg: Unimplemented command %lx\n", sc.cmd));
1648 return ENOSYS;
1649 }
1650 }
1651
1652
1653 int
1654 svr4_32_sys_getmsg(l, v, retval)
1655 struct lwp *l;
1656 void *v;
1657 register_t *retval;
1658 {
1659 struct svr4_32_sys_getmsg_args *uap = v;
1660 struct proc *p = l->l_proc;
1661 struct filedesc *fdp = p->p_fd;
1662 struct file *fp;
1663 struct sys_getpeername_args ga;
1664 struct sys_accept_args aa;
1665 struct svr4_32_strbuf dat, ctl;
1666 struct svr4_32_strmcmd sc;
1667 int error;
1668 struct msghdr msg;
1669 struct iovec aiov;
1670 struct sockaddr_in sain;
1671 struct sockaddr_un saun;
1672 void *skp, *sup;
1673 int sasize;
1674 struct svr4_strm *st;
1675 int *flen;
1676 int fl;
1677 caddr_t sg;
1678
1679 memset(&sc, 0, sizeof(sc));
1680
1681 #ifdef DEBUG_SVR4
1682 show_msg(">getmsg", SCARG(uap, fd), SCARG(uap, ctl),
1683 SCARG(uap, dat), 0);
1684 #endif /* DEBUG_SVR4 */
1685
1686 if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
1687 return EBADF;
1688
1689 if (SCARG(uap, ctl)) {
1690 if ((error = copyin((caddr_t)(u_long)SCARG(uap, ctl),
1691 &ctl, sizeof(ctl))) != 0)
1692 return error;
1693 }
1694 else {
1695 ctl.len = -1;
1696 ctl.maxlen = 0;
1697 }
1698
1699 if (SCARG(uap, dat)) {
1700 if ((error = copyin((caddr_t)(u_long)SCARG(uap, dat),
1701 &dat, sizeof(dat))) != 0)
1702 return error;
1703 }
1704 else {
1705 dat.len = -1;
1706 dat.maxlen = 0;
1707 }
1708
1709 /*
1710 * Only for sockets for now.
1711 */
1712 if ((st = svr4_32_stream_get(fp)) == NULL) {
1713 DPRINTF(("getmsg: bad file type\n"));
1714 return EINVAL;
1715 }
1716
1717 if (ctl.maxlen == -1 || dat.maxlen == -1) {
1718 DPRINTF(("getmsg: Cannot handle -1 maxlen (yet)\n"));
1719 return ENOSYS;
1720 }
1721
1722 switch (st->s_family) {
1723 case AF_INET:
1724 skp = &sain;
1725 sasize = sizeof(sain);
1726 break;
1727
1728 case AF_LOCAL:
1729 skp = &saun;
1730 sasize = sizeof(saun);
1731 break;
1732
1733 default:
1734 DPRINTF(("getmsg: Unsupported address family %d\n",
1735 st->s_family));
1736 return ENOSYS;
1737 }
1738
1739 sg = stackgap_init(p, 0);
1740 sup = stackgap_alloc(p, &sg, sasize);
1741 flen = (int *) stackgap_alloc(p, &sg, sizeof(*flen));
1742
1743 fl = sasize;
1744 if ((error = copyout(&fl, flen, sizeof(fl))) != 0)
1745 return error;
1746
1747 switch (st->s_cmd) {
1748 case SVR4_TI_CONNECT_REQUEST:
1749 DPRINTF(("getmsg: TI_CONNECT_REQUEST\n"));
1750 /*
1751 * We do the connect in one step, so the putmsg should
1752 * have gotten the error.
1753 */
1754 sc.cmd = SVR4_TI_OK_REPLY;
1755 sc.len = 0;
1756
1757 ctl.len = 8;
1758 dat.len = -1;
1759 fl = 1;
1760 st->s_cmd = sc.cmd;
1761 break;
1762
1763 case SVR4_TI_OK_REPLY:
1764 DPRINTF(("getmsg: TI_OK_REPLY\n"));
1765 /*
1766 * We are immediately after a connect reply, so we send
1767 * a connect verification.
1768 */
1769
1770 SCARG(&ga, fdes) = SCARG(uap, fd);
1771 SCARG(&ga, asa) = (void *) sup;
1772 SCARG(&ga, alen) = flen;
1773
1774 if ((error = sys_getpeername(l, &ga, retval)) != 0) {
1775 DPRINTF(("getmsg: getpeername failed %d\n", error));
1776 return error;
1777 }
1778
1779 if ((error = copyin(sup, skp, sasize)) != 0)
1780 return error;
1781
1782 sc.cmd = SVR4_TI_CONNECT_REPLY;
1783 sc.pad[0] = 0x4;
1784 sc.offs = 0x18;
1785 sc.pad[1] = 0x14;
1786 sc.pad[2] = 0x04000402;
1787
1788 switch (st->s_family) {
1789 case AF_INET:
1790 sc.len = sasize;
1791 sockaddr_to_netaddr_in(&sc, &sain);
1792 break;
1793
1794 case AF_LOCAL:
1795 sc.len = sasize + 4;
1796 sockaddr_to_netaddr_un(&sc, &saun);
1797 break;
1798
1799 default:
1800 return ENOSYS;
1801 }
1802
1803 ctl.len = 40;
1804 dat.len = -1;
1805 fl = 0;
1806 st->s_cmd = sc.cmd;
1807 break;
1808
1809 case SVR4_TI__ACCEPT_OK:
1810 DPRINTF(("getmsg: TI__ACCEPT_OK\n"));
1811 /*
1812 * We do the connect in one step, so the putmsg should
1813 * have gotten the error.
1814 */
1815 sc.cmd = SVR4_TI_OK_REPLY;
1816 sc.len = 1;
1817
1818 ctl.len = 8;
1819 dat.len = -1;
1820 fl = 1;
1821 st->s_cmd = SVR4_TI__ACCEPT_WAIT;
1822 break;
1823
1824 case SVR4_TI__ACCEPT_WAIT:
1825 DPRINTF(("getmsg: TI__ACCEPT_WAIT\n"));
1826 /*
1827 * We are after a listen, so we try to accept...
1828 */
1829 SCARG(&aa, s) = SCARG(uap, fd);
1830 SCARG(&aa, name) = (void *) sup;
1831 SCARG(&aa, anamelen) = flen;
1832
1833 if ((error = sys_accept(l, &aa, retval)) != 0) {
1834 DPRINTF(("getmsg: accept failed %d\n", error));
1835 return error;
1836 }
1837
1838 st->s_afd = *retval;
1839
1840 DPRINTF(("getmsg: Accept fd = %d\n", st->s_afd));
1841
1842 if ((error = copyin(sup, skp, sasize)) != 0)
1843 return error;
1844
1845 sc.cmd = SVR4_TI_ACCEPT_REPLY;
1846 sc.offs = 0x18;
1847 sc.pad[0] = 0x0;
1848
1849 switch (st->s_family) {
1850 case AF_INET:
1851 sc.pad[1] = 0x28;
1852 sockaddr_to_netaddr_in(&sc, &sain);
1853 ctl.len = 40;
1854 sc.len = sasize;
1855 break;
1856
1857 case AF_LOCAL:
1858 sc.pad[1] = 0x00010000;
1859 sc.pad[2] = 0xf6bcdaa0; /* I don't know what that is */
1860 sc.pad[3] = 0x00010000;
1861 ctl.len = 134;
1862 sc.len = sasize + 4;
1863 break;
1864
1865 default:
1866 return ENOSYS;
1867 }
1868
1869 dat.len = -1;
1870 fl = 0;
1871 st->s_cmd = SVR4_TI__ACCEPT_OK;
1872 break;
1873
1874 case SVR4_TI_SENDTO_REQUEST:
1875 DPRINTF(("getmsg: TI_SENDTO_REQUEST\n"));
1876 if (ctl.maxlen > 36 && ctl.len < 36)
1877 ctl.len = 36;
1878 if (ctl.len > sizeof(sc))
1879 ctl.len = sizeof(sc);
1880
1881 if ((error = copyin((caddr_t)(u_long)ctl.buf, &sc, ctl.len)) != 0)
1882 return error;
1883
1884 switch (st->s_family) {
1885 case AF_INET:
1886 sockaddr_to_netaddr_in(&sc, &sain);
1887 break;
1888
1889 case AF_LOCAL:
1890 sockaddr_to_netaddr_un(&sc, &saun);
1891 break;
1892
1893 default:
1894 return ENOSYS;
1895 }
1896
1897 msg.msg_name = (caddr_t) sup;
1898 msg.msg_namelen = sasize;
1899 msg.msg_iov = &aiov;
1900 msg.msg_iovlen = 1;
1901 msg.msg_control = 0;
1902 aiov.iov_base = (caddr_t)(u_long)dat.buf;
1903 aiov.iov_len = dat.maxlen;
1904 msg.msg_flags = 0;
1905
1906 error = recvit(p, SCARG(uap, fd), &msg, (caddr_t) flen,
1907 retval);
1908
1909 if (error) {
1910 DPRINTF(("getmsg: recvit failed %d\n", error));
1911 return error;
1912 }
1913
1914 if ((error = copyin(msg.msg_name, skp, sasize)) != 0)
1915 return error;
1916
1917 sc.cmd = SVR4_TI_RECVFROM_IND;
1918
1919 switch (st->s_family) {
1920 case AF_INET:
1921 sc.len = sasize;
1922 sockaddr_to_netaddr_in(&sc, &sain);
1923 break;
1924
1925 case AF_LOCAL:
1926 sc.len = sasize + 4;
1927 sockaddr_to_netaddr_un(&sc, &saun);
1928 break;
1929
1930 default:
1931 return ENOSYS;
1932 }
1933
1934 dat.len = *retval;
1935 fl = 0;
1936 st->s_cmd = sc.cmd;
1937 break;
1938
1939 default:
1940 st->s_cmd = sc.cmd;
1941 #ifdef notyet
1942 if (st->s_cmd == SVR4_TI_CONNECT_REQUEST) {
1943 struct sys_read_args ra;
1944
1945 /* More weirdness: Again, I can't find documentation
1946 * to back this up, but when a process does a generic
1947 * "getmsg()" call it seems that the command field is
1948 * zero and the length of the data area is zero. I
1949 * think processes expect getmsg() to fill in dat.len
1950 * after reading at most dat.maxlen octets from the
1951 * stream. Since we're using sockets I can let
1952 * read() look after it and frob return values
1953 * appropriately (or inappropriately :-)
1954 * -- newton@atdot.dotat.org XXX
1955 */
1956 SCARG(&ra, fd) = SCARG(uap, fd);
1957 SCARG(&ra, buf) = dat.buf;
1958 SCARG(&ra, nbyte) = dat.maxlen;
1959 if ((error = sys_read(p, &ra, retval)) != 0)
1960 return error;
1961 dat.len = *retval;
1962 *retval = 0;
1963 st->s_cmd = SVR4_TI_SENDTO_REQUEST;
1964 break;
1965
1966 }
1967 #endif
1968 DPRINTF(("getmsg: Unknown state %x\n", st->s_cmd));
1969 return EINVAL;
1970 }
1971
1972 if (SCARG(uap, ctl)) {
1973 if (ctl.len != -1)
1974 if ((error = copyout(&sc, (caddr_t)(u_long)ctl.buf,
1975 ctl.len)) != 0)
1976 return error;
1977
1978 if ((error = copyout(&ctl, (caddr_t)(u_long)SCARG(uap, ctl),
1979 sizeof(ctl))) != 0)
1980 return error;
1981 }
1982
1983 if (SCARG(uap, dat)) {
1984 if ((error = copyout(&dat, (caddr_t)(u_long)SCARG(uap, dat),
1985 sizeof(dat))) != 0)
1986 return error;
1987 }
1988
1989 if (SCARG(uap, flags)) { /* XXX: Need translation */
1990 if ((error = copyout(&fl, (caddr_t)(u_long)SCARG(uap, flags),
1991 sizeof(fl))) != 0)
1992 return error;
1993 }
1994
1995 *retval = 0;
1996
1997 #ifdef DEBUG_SVR4
1998 show_msg("<getmsg", SCARG(uap, fd), SCARG(uap, ctl),
1999 SCARG(uap, dat), fl);
2000 #endif /* DEBUG_SVR4 */
2001 return error;
2002 }
Cache object: 7aa6fbe67b76fe23563125e8dda2fed4
|