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