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