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