1 /* $NetBSD: svr4_stream.c,v 1.76 2008/04/23 13:58:06 ad Exp $ */
4 * Copyright (c) 1994, 2008 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Pretend that we have streams...
36 * ToDo: The state machine for getmsg needs re-thinking
38 * The svr4_32 version is built from this file as well.
41 #include <sys/cdefs.h>
42 __KERNEL_RCSID(0, "$NetBSD: svr4_stream.c,v 1.76 2008/04/23 13:58:06 ad Exp $");
44 #include <sys/param.h>
45 #include <sys/kernel.h>
46 #include <sys/systm.h>
48 #include <sys/malloc.h>
49 #include <sys/ioctl.h>
52 #include <sys/filedesc.h>
53 #include <sys/namei.h>
54 #include <sys/select.h>
55 #include <sys/socket.h>
56 #include <sys/socketvar.h>
57 #include <sys/protosw.h>
60 #include <netinet/in.h>
62 #include <sys/mount.h>
64 #include <sys/vfs_syscalls.h>
65 #include <sys/vnode.h>
66 #include <sys/device.h>
69 #include <sys/syscallargs.h>
72 #define compat(name) <compat/svr4/svr4_##name>
74 #define compat(name) <compat/svr4_32/svr4_32_##name>
77 #include compat(types.h)
78 #include compat(util.h)
79 #include compat(signal.h)
80 #include compat(lwp.h)
81 #include compat(ucontext.h)
82 #include compat(syscallargs.h)
83 #include compat(stropts.h)
84 #include compat(timod.h)
85 #include <compat/svr4/svr4_sockmod.h>
86 #include compat(ioctl.h)
87 #include compat(socket.h)
93 #define SCARG_PTR(uap, arg) SCARG(uap, arg)
94 #define NETBSD32PTR(ptr) (ptr)
98 #define SCARG_PTR(uap, arg) SCARG_P32(uap, arg)
99 #define NETBSD32PTR(ptr) NETBSD32PTR64(ptr)
101 /* Rename stuff that is different for the svr4_32 build */
102 #define svr4_infocmd svr4_32_infocmd
103 #define svr4_ino_t svr4_32_ino_t
104 #define svr4_netaddr_in svr4_32_netaddr_in
105 #define svr4_netaddr_un svr4_32_netaddr_un
106 #define svr4_strbuf svr4_32_strbuf
107 #define svr4_stream_get svr4_32_stream_get
108 #define svr4_stream_ioctl svr4_32_stream_ioctl
109 #define svr4_stream_ti_ioctl svr4_32_stream_ti_ioctl
110 #define svr4_strfdinsert svr4_32_strfdinsert
111 #define svr4_strioctl svr4_32_strioctl
112 #define svr4_strmcmd svr4_32_strmcmd
113 #define svr4_sys_getmsg svr4_32_sys_getmsg
114 #define svr4_sys_getmsg_args svr4_32_sys_getmsg_args
115 #define svr4_sys_putmsg svr4_32_sys_putmsg
116 #define svr4_sys_putmsg_args svr4_32_sys_putmsg_args
121 static int clean_pipe(struct lwp
*, const char *);
122 static void getparm(file_t
*, struct svr4_si_sockparms
*);
124 /* Address Conversions */
125 static void sockaddr_to_netaddr_in(struct svr4_strmcmd
*,
126 const struct sockaddr_in
*);
127 static void sockaddr_to_netaddr_un(struct svr4_strmcmd
*,
128 const struct sockaddr_un
*);
129 static void netaddr_to_sockaddr_in(struct sockaddr_in
*,
130 const struct svr4_strmcmd
*);
131 static void netaddr_to_sockaddr_un(struct sockaddr_un
*,
132 const struct svr4_strmcmd
*);
135 static int i_nread(file_t
*, struct lwp
*, register_t
*, int,
137 static int i_fdinsert(file_t
*, struct lwp
*, register_t
*, int,
139 static int i_str(file_t
*, struct lwp
*, register_t
*, int,
141 static int i_setsig(file_t
*, struct lwp
*, register_t
*, int,
143 static int i_getsig(file_t
*, struct lwp
*, register_t
*, int,
145 static int _i_bind_rsvd(file_t
*, struct lwp
*, register_t
*, int,
147 static int _i_rele_rsvd(file_t
*, struct lwp
*, register_t
*, int,
150 /* i_str sockmod calls */
151 static int sockmod(file_t
*, int, struct svr4_strioctl
*,
153 static int si_listen(file_t
*, int, struct svr4_strioctl
*,
155 static int si_ogetudata(file_t
*, int, struct svr4_strioctl
*,
157 static int si_sockparams(file_t
*, int, struct svr4_strioctl
*,
159 static int si_shutdown(file_t
*, int, struct svr4_strioctl
*,
161 static int si_getudata(file_t
*, int, struct svr4_strioctl
*,
164 /* i_str timod calls */
165 static int timod(file_t
*, int, struct svr4_strioctl
*,
167 static int ti_getinfo(file_t
*, int, struct svr4_strioctl
*,
169 static int ti_bind(file_t
*, int, struct svr4_strioctl
*,
173 static void bufprint(u_char
*, size_t);
174 static int show_ioc(const char *, struct svr4_strioctl
*);
175 static int show_strbuf(struct svr4_strbuf
*);
176 static void show_msg(const char *, int, struct svr4_strbuf
*,
177 struct svr4_strbuf
*, int);
180 bufprint(u_char
*buf
, size_t len
)
185 for (i
= 0; i
< len
; i
++) {
186 uprintf("%x ", buf
[i
]);
187 if (i
&& (i
% 16) == 0)
193 show_ioc(const char *str
, struct svr4_strioctl
*ioc
)
202 ptr
= (u_char
*) malloc(len
, M_TEMP
, M_WAITOK
);
203 uprintf("%s cmd = %ld, timeout = %d, len = %d, buf = %p { ",
204 str
, ioc
->cmd
, ioc
->timeout
, ioc
->len
, ioc
->buf
);
206 if ((error
= copyin(ioc
->buf
, ptr
, len
)) != 0) {
207 free((char *) ptr
, M_TEMP
);
215 free((char *) ptr
, M_TEMP
);
221 show_strbuf(struct svr4_strbuf
*str
)
225 int maxlen
= str
->maxlen
;
238 ptr
= (u_char
*) malloc(len
, M_TEMP
, M_WAITOK
);
240 if ((error
= copyin(str
->buf
, ptr
, len
)) != 0) {
241 free((char *) ptr
, M_TEMP
);
246 uprintf(", { %d, %d, %p=[ ", str
->maxlen
, str
->len
, str
->buf
);
254 free((char *) ptr
, M_TEMP
);
261 show_msg(const char *str
, int fd
, struct svr4_strbuf
*ctl
, struct svr4_strbuf
*dat
, int flags
)
263 struct svr4_strbuf buf
;
266 uprintf("%s(%d", str
, fd
);
268 if ((error
= copyin(ctl
, &buf
, sizeof(buf
))) != 0)
276 if ((error
= copyin(dat
, &buf
, sizeof(buf
))) != 0)
283 uprintf(", %x);\n", flags
);
286 #endif /* DEBUG_SVR4 */
290 * We are faced with an interesting situation. On svr4 unix sockets
291 * are really pipes. But we really have sockets, and we might as
292 * well use them. At the point where svr4 calls TI_BIND, it has
293 * already created a named pipe for the socket using mknod(2).
294 * We need to create a socket with the same name when we bind,
295 * so we need to remove the pipe before, otherwise we'll get address
296 * already in use. So we *carefully* remove the pipe, to avoid
297 * using this as a random file removal tool.
300 clean_pipe(struct lwp
*l
, const char *path
)
306 NDINIT(&nd
, DELETE
, NOFOLLOW
| LOCKPARENT
| LOCKLEAF
| TRYEMULROOT
,
314 * Make sure we are dealing with a mode 0 named pipe.
316 if (nd
.ni_vp
->v_type
!= VFIFO
)
318 error
= VOP_GETATTR(nd
.ni_vp
, &va
, l
->l_cred
);
321 if ((va
.va_mode
& ALLPERMS
) != 0)
324 return VOP_REMOVE(nd
.ni_dvp
, nd
.ni_vp
, &nd
.ni_cnd
);
327 if (nd
.ni_dvp
== nd
.ni_vp
)
337 sockaddr_to_netaddr_in(struct svr4_strmcmd
*sc
, const struct sockaddr_in
*sain
)
339 struct svr4_netaddr_in
*na
;
340 na
= SVR4_ADDROF(sc
);
342 na
->family
= sain
->sin_family
;
343 na
->port
= sain
->sin_port
;
344 na
->addr
= sain
->sin_addr
.s_addr
;
345 DPRINTF(("sockaddr_in -> netaddr %d %d %lx\n", na
->family
, na
->port
,
351 sockaddr_to_netaddr_un(struct svr4_strmcmd
*sc
, const struct sockaddr_un
*saun
)
353 struct svr4_netaddr_un
*na
;
354 char *dst
, *edst
= ((char *) sc
) + sc
->offs
+ sizeof(na
->family
) + 1 -
358 na
= SVR4_ADDROF(sc
);
359 na
->family
= saun
->sun_family
;
360 for (src
= saun
->sun_path
, dst
= na
->path
; (*dst
++ = *src
++) != '\0'; )
363 DPRINTF(("sockaddr_un -> netaddr %d %s\n", na
->family
, na
->path
));
368 netaddr_to_sockaddr_in(struct sockaddr_in
*sain
, const struct svr4_strmcmd
*sc
)
370 const struct svr4_netaddr_in
*na
;
373 na
= SVR4_C_ADDROF(sc
);
374 memset(sain
, 0, sizeof(*sain
));
375 sain
->sin_len
= sizeof(*sain
);
376 sain
->sin_family
= na
->family
;
377 sain
->sin_port
= na
->port
;
378 sain
->sin_addr
.s_addr
= na
->addr
;
379 DPRINTF(("netaddr -> sockaddr_in %d %d %x\n", sain
->sin_family
,
380 sain
->sin_port
, sain
->sin_addr
.s_addr
));
385 netaddr_to_sockaddr_un(struct sockaddr_un
*saun
, const struct svr4_strmcmd
*sc
)
387 const struct svr4_netaddr_un
*na
;
388 char *dst
, *edst
= &saun
->sun_path
[sizeof(saun
->sun_path
) - 1];
391 na
= SVR4_C_ADDROF(sc
);
392 memset(saun
, 0, sizeof(*saun
));
393 saun
->sun_family
= na
->family
;
394 for (src
= na
->path
, dst
= saun
->sun_path
; (*dst
++ = *src
++) != '\0'; )
397 saun
->sun_len
= dst
- saun
->sun_path
;
398 DPRINTF(("netaddr -> sockaddr_un %d %s\n", saun
->sun_family
,
404 getparm(file_t
*fp
, struct svr4_si_sockparms
*pa
)
406 struct svr4_strm
*st
= svr4_stream_get(fp
);
407 struct socket
*so
= (struct socket
*) fp
->f_data
;
412 pa
->family
= st
->s_family
;
414 switch (so
->so_type
) {
416 pa
->type
= SVR4_T_CLTS
;
417 pa
->protocol
= IPPROTO_UDP
;
418 DPRINTF(("getparm(dgram)\n"));
422 pa
->type
= SVR4_T_COTS
; /* What about T_COTS_ORD? XXX */
423 pa
->protocol
= IPPROTO_IP
;
424 DPRINTF(("getparm(stream)\n"));
428 pa
->type
= SVR4_T_CLTS
;
429 pa
->protocol
= IPPROTO_RAW
;
430 DPRINTF(("getparm(raw)\n"));
436 DPRINTF(("getparm(type %d?)\n", so
->so_type
));
443 si_ogetudata(file_t
*fp
, int fd
, struct svr4_strioctl
*ioc
,
447 struct svr4_si_oudata ud
;
448 struct svr4_si_sockparms pa
;
449 (void)memset(&pa
, 0, sizeof(pa
)); /* XXX: GCC */
451 if (ioc
->len
!= sizeof(ud
) && ioc
->len
!= sizeof(ud
) - sizeof(int)) {
452 DPRINTF(("SI_OGETUDATA: Wrong size %ld != %d\n",
453 (unsigned long)sizeof(ud
), ioc
->len
));
457 if ((error
= copyin(NETBSD32PTR(ioc
->buf
), &ud
, sizeof(ud
))) != 0)
465 ud
.addrsize
= sizeof(struct sockaddr_in
);
466 if (pa
.type
== SVR4_SOCK_STREAM
)
479 DPRINTF(("SI_OGETUDATA: Unsupported address family %d\n",
484 /* I have no idea what these should be! */
488 ud
.servtype
= pa
.type
;
493 return copyout(&ud
, NETBSD32PTR(ioc
->buf
), ioc
->len
);
498 si_sockparams(file_t
*fp
, int fd
, struct svr4_strioctl
*ioc
,
501 struct svr4_si_sockparms pa
;
504 return copyout(&pa
, NETBSD32PTR(ioc
->buf
), sizeof(pa
));
509 si_listen(file_t
*fp
, int fd
, struct svr4_strioctl
*ioc
, struct lwp
*l
)
512 struct svr4_strm
*st
= svr4_stream_get(fp
);
514 struct svr4_strmcmd lst
;
515 struct sys_listen_args la
;
520 if (ioc
->len
> sizeof(lst
))
523 if ((error
= copyin(NETBSD32PTR(ioc
->buf
), &lst
, ioc
->len
)) != 0)
526 if (lst
.cmd
!= SVR4_TI_OLD_BIND_REQUEST
) {
527 DPRINTF(("si_listen: bad request %ld\n", lst
.cmd
));
532 * We are making assumptions again...
535 DPRINTF(("SI_LISTEN: fileno %d backlog = %d\n", fd
, 5));
536 SCARG(&la
, backlog
) = 5;
538 if ((error
= sys_listen(l
, &la
, &retval
)) != 0) {
539 DPRINTF(("SI_LISTEN: listen failed %d\n", error
));
543 st
->s_cmd
= SVR4_TI__ACCEPT_WAIT
;
544 lst
.cmd
= SVR4_TI_BIND_REPLY
;
546 switch (st
->s_family
) {
548 /* XXX: Fill the length here */
553 lst
.pad
[28] = 0x00000000; /* magic again */
554 lst
.pad
[29] = 0x00000800; /* magic again */
555 lst
.pad
[30] = 0x80001400; /* magic again */
559 DPRINTF(("SI_LISTEN: Unsupported address family %d\n",
565 if ((error
= copyout(&lst
, NETBSD32PTR(ioc
->buf
), ioc
->len
)) != 0)
573 si_getudata(file_t
*fp
, int fd
, struct svr4_strioctl
*ioc
,
577 struct svr4_si_udata ud
;
579 if (sizeof(ud
) != ioc
->len
) {
580 DPRINTF(("SI_GETUDATA: Wrong size %ld != %d\n",
581 (unsigned long)sizeof(ud
), ioc
->len
));
585 if ((error
= copyin(NETBSD32PTR(ioc
->buf
), &ud
, sizeof(ud
))) != 0)
588 getparm(fp
, &ud
.sockparms
);
590 switch (ud
.sockparms
.family
) {
594 ud
.addrsize
= sizeof(struct sockaddr_in
);
595 if (ud
.sockparms
.type
== SVR4_SOCK_STREAM
)
611 DPRINTF(("SI_GETUDATA: Unsupported address family %d\n",
612 ud
.sockparms
.family
));
617 ud
.servtype
= ud
.sockparms
.type
;
622 return copyout(&ud
, NETBSD32PTR(ioc
->buf
), sizeof(ud
));
627 si_shutdown(file_t
*fp
, int fd
, struct svr4_strioctl
*ioc
,
631 struct sys_shutdown_args ap
;
634 if (ioc
->len
!= sizeof(SCARG(&ap
, how
))) {
635 DPRINTF(("SI_SHUTDOWN: Wrong size %ld != %d\n",
636 (unsigned long)sizeof(SCARG(&ap
, how
)), ioc
->len
));
640 if ((error
= copyin(NETBSD32PTR(ioc
->buf
), &SCARG(&ap
, how
), ioc
->len
)) != 0)
645 return sys_shutdown(l
, &ap
, &retval
);
650 sockmod(file_t
*fp
, int fd
, struct svr4_strioctl
*ioc
, struct lwp
*l
)
653 case SVR4_SI_OGETUDATA
:
654 DPRINTF(("SI_OGETUDATA\n"));
655 return si_ogetudata(fp
, fd
, ioc
, l
);
657 case SVR4_SI_SHUTDOWN
:
658 DPRINTF(("SI_SHUTDOWN\n"));
659 return si_shutdown(fp
, fd
, ioc
, l
);
662 DPRINTF(("SI_LISTEN\n"));
663 return si_listen(fp
, fd
, ioc
, l
);
665 case SVR4_SI_SETMYNAME
:
666 DPRINTF(("SI_SETMYNAME\n"));
669 case SVR4_SI_SETPEERNAME
:
670 DPRINTF(("SI_SETPEERNAME\n"));
673 case SVR4_SI_GETINTRANSIT
:
674 DPRINTF(("SI_GETINTRANSIT\n"));
677 case SVR4_SI_TCL_LINK
:
678 DPRINTF(("SI_TCL_LINK\n"));
681 case SVR4_SI_TCL_UNLINK
:
682 DPRINTF(("SI_TCL_UNLINK\n"));
685 case SVR4_SI_SOCKPARAMS
:
686 DPRINTF(("SI_SOCKPARAMS\n"));
687 return si_sockparams(fp
, fd
, ioc
, l
);
689 case SVR4_SI_GETUDATA
:
690 DPRINTF(("SI_GETUDATA\n"));
691 return si_getudata(fp
, fd
, ioc
, l
);
694 DPRINTF(("Unknown sockmod ioctl %lx\n", ioc
->cmd
));
702 ti_getinfo(file_t
*fp
, int fd
, struct svr4_strioctl
*ioc
,
706 struct svr4_infocmd info
;
708 memset(&info
, 0, sizeof(info
));
710 if (ioc
->len
> sizeof(info
))
713 if ((error
= copyin(NETBSD32PTR(ioc
->buf
), &info
, ioc
->len
)) != 0)
716 if (info
.cmd
!= SVR4_TI_INFO_REQUEST
)
719 info
.cmd
= SVR4_TI_INFO_REPLY
;
731 ioc
->len
= sizeof(info
);
732 if ((error
= copyout(&info
, NETBSD32PTR(ioc
->buf
), ioc
->len
)) != 0)
740 ti_bind(file_t
*fp
, int fd
, struct svr4_strioctl
*ioc
, struct lwp
*l
)
743 struct svr4_strm
*st
= svr4_stream_get(fp
);
744 struct sockaddr_in sain
;
745 struct sockaddr_un saun
;
746 void *skp
, *sup
= NULL
;
748 struct svr4_strmcmd bnd
;
752 DPRINTF(("ti_bind: bad file descriptor\n"));
756 if (ioc
->len
> sizeof(bnd
))
759 if ((error
= copyin(NETBSD32PTR(ioc
->buf
), &bnd
, ioc
->len
)) != 0)
762 if (bnd
.cmd
!= SVR4_TI_OLD_BIND_REQUEST
) {
763 DPRINTF(("ti_bind: bad request %ld\n", bnd
.cmd
));
767 switch (st
->s_family
) {
770 sasize
= sizeof(sain
);
775 netaddr_to_sockaddr_in(&sain
, &bnd
);
777 DPRINTF(("TI_BIND: fam %d, port %d, addr %x\n",
778 sain
.sin_family
, sain
.sin_port
,
779 sain
.sin_addr
.s_addr
));
784 sasize
= sizeof(saun
);
788 netaddr_to_sockaddr_un(&saun
, &bnd
);
790 if (saun
.sun_path
[0] == '\0')
793 DPRINTF(("TI_BIND: fam %d, path %s\n",
794 saun
.sun_family
, saun
.sun_path
));
796 if ((error
= clean_pipe(l
, saun
.sun_path
)) != 0)
799 bnd
.pad
[28] = 0x00001000; /* magic again */
803 DPRINTF(("TI_BIND: Unsupported address family %d\n",
808 name
= m_get(M_WAIT
, MT_SONAME
);
810 MEXTMALLOC(name
, sasize
, M_WAITOK
);
812 memcpy(mtod(name
, void *), skp
, sasize
);
814 DPRINTF(("TI_BIND: fileno %d\n", fd
));
816 error
= do_sys_bind(l
, fd
, name
);
818 DPRINTF(("TI_BIND: bind failed %d\n", error
));
824 memset(&bnd
, 0, sizeof(bnd
));
825 bnd
.len
= sasize
+ 4;
826 bnd
.offs
= 0x10; /* XXX */
829 bnd
.cmd
= SVR4_TI_BIND_REPLY
;
831 if ((error
= copyout(&bnd
, NETBSD32PTR(ioc
->buf
), ioc
->len
)) != 0)
839 timod(file_t
*fp
, int fd
, struct svr4_strioctl
*ioc
, struct lwp
*l
)
842 case SVR4_TI_GETINFO
:
843 DPRINTF(("TI_GETINFO\n"));
844 return ti_getinfo(fp
, fd
, ioc
, l
);
846 case SVR4_TI_OPTMGMT
:
847 DPRINTF(("TI_OPTMGMT\n"));
851 DPRINTF(("TI_BIND\n"));
852 return ti_bind(fp
, fd
, ioc
, l
);
855 DPRINTF(("TI_UNBIND\n"));
859 DPRINTF(("Unknown timod ioctl %lx\n", ioc
->cmd
));
866 svr4_stream_ti_ioctl(file_t
*fp
, struct lwp
*l
, register_t
*retval
, int fd
, u_long cmd
, void *dat
)
868 struct svr4_strbuf skb
, *sub
= (struct svr4_strbuf
*) dat
;
869 struct svr4_strm
*st
= svr4_stream_get(fp
);
871 struct svr4_strmcmd sc
;
879 if ((error
= copyin(sub
, &skb
, sizeof(skb
))) != 0) {
880 DPRINTF(("ti_ioctl: error copying in strbuf\n"));
885 case SVR4_TI_GETMYNAME
:
886 DPRINTF(("TI_GETMYNAME\n"));
890 case SVR4_TI_GETPEERNAME
:
891 DPRINTF(("TI_GETPEERNAME\n"));
895 case SVR4_TI_SETMYNAME
:
896 DPRINTF(("TI_SETMYNAME\n"));
899 case SVR4_TI_SETPEERNAME
:
900 DPRINTF(("TI_SETPEERNAME\n"));
903 DPRINTF(("ti_ioctl: Unknown ioctl %lx\n", cmd
));
907 error
= do_sys_getsockname(l
, fd
, cmd
, &name
);
911 switch (st
->s_family
) {
913 sockaddr_to_netaddr_in(&sc
, mtod(name
, void *));
914 skb
.len
= sizeof (struct sockaddr_in
);
918 sockaddr_to_netaddr_un(&sc
, mtod(name
, void *));
919 /* XXX: the length gets adjusted but the copyout doesn't */
920 skb
.len
= sizeof (struct sockaddr_un
) + 4;
924 DPRINTF(("ti_ioctl: Unsupported address family %d\n",
930 error
= copyout(SVR4_ADDROF(&sc
), NETBSD32PTR(skb
.buf
), name
->m_len
);
933 DPRINTF(("ti_ioctl: error copying out socket data\n"));
938 if ((error
= copyout(&skb
, sub
, sizeof(skb
))) != 0) {
939 DPRINTF(("ti_ioctl: error copying out strbuf\n"));
950 i_nread(file_t
*fp
, struct lwp
*l
, register_t
*retval
, int fd
,
951 u_long cmd
, void *dat
)
957 * We are supposed to return the message length in nread, and the
958 * number of messages in retval. We don't have the notion of number
959 * of stream messages, so we just find out if we have any bytes waiting
960 * for us, and if we do, then we assume that we have at least one
961 * message waiting for us.
963 if ((error
= (*fp
->f_ops
->fo_ioctl
)(fp
, FIONREAD
, &nread
)) != 0)
971 return copyout(&nread
, dat
, sizeof(nread
));
975 i_fdinsert(file_t
*fp
, struct lwp
*l
, register_t
*retval
, int fd
,
976 u_long cmd
, void *dat
)
979 * Major hack again here. We assume that we are using this to
980 * implement accept(2). If that is the case, we have already
981 * called accept, and we have stored the file descriptor in
982 * afd. We find the file descriptor that the code wants to use
983 * in fd insert, and then we dup2() our accepted file descriptor
987 struct svr4_strm
*st
= svr4_stream_get(fp
);
988 struct svr4_strfdinsert fdi
;
989 struct sys_dup2_args d2p
;
990 struct sys_close_args clp
;
993 DPRINTF(("fdinsert: bad file type\n"));
997 if (st
->s_afd
== -1) {
998 DPRINTF(("fdinsert: accept fd not found\n"));
1002 if ((error
= copyin(dat
, &fdi
, sizeof(fdi
))) != 0) {
1003 DPRINTF(("fdinsert: copyin failed %d\n", error
));
1007 SCARG(&d2p
, from
) = st
->s_afd
;
1008 SCARG(&d2p
, to
) = fdi
.fd
;
1010 if ((error
= sys_dup2(l
, &d2p
, retval
)) != 0) {
1011 DPRINTF(("fdinsert: dup2(%d, %d) failed %d\n",
1012 st
->s_afd
, fdi
.fd
, error
));
1016 SCARG(&clp
, fd
) = st
->s_afd
;
1018 if ((error
= sys_close(l
, &clp
, retval
)) != 0) {
1019 DPRINTF(("fdinsert: close(%d) failed %d\n",
1032 _i_bind_rsvd(file_t
*fp
, struct lwp
*l
, register_t
*retval
,
1033 int fd
, u_long cmd
, void *dat
)
1035 struct sys_mkfifo_args ap
;
1038 * This is a supposed to be a kernel and library only ioctl.
1039 * It gets called before ti_bind, when we have a unix
1040 * socket, to physically create the socket transport and
1041 * ``reserve'' it. I don't know how this get reserved inside
1042 * the kernel, but we are going to create it nevertheless.
1044 SCARG(&ap
, path
) = dat
;
1045 SCARG(&ap
, mode
) = S_IFIFO
;
1047 return sys_mkfifo(l
, &ap
, retval
);
1051 _i_rele_rsvd(file_t
*fp
, struct lwp
*l
, register_t
*retval
,
1052 int fd
, u_long cmd
, void *dat
)
1054 struct sys_unlink_args ap
;
1057 * This is a supposed to be a kernel and library only ioctl.
1058 * I guess it is supposed to release the socket.
1060 SCARG(&ap
, path
) = dat
;
1062 return sys_unlink(l
, &ap
, retval
);
1066 i_str(file_t
*fp
, struct lwp
*l
, register_t
*retval
, int fd
,
1067 u_long cmd
, void *dat
)
1070 struct svr4_strioctl ioc
;
1073 * Noop on non sockets
1075 if (fp
->f_type
!= DTYPE_SOCKET
)
1078 if ((error
= copyin(dat
, &ioc
, sizeof(ioc
))) != 0)
1082 if ((error
= show_ioc(">", &ioc
)) != 0)
1084 #endif /* DEBUG_SVR4 */
1086 switch (ioc
.cmd
& 0xff00) {
1088 if ((error
= sockmod(fp
, fd
, &ioc
, l
)) != 0)
1093 if ((error
= timod(fp
, fd
, &ioc
, l
)) != 0)
1098 DPRINTF(("Unimplemented module %c %ld\n",
1099 (char) (cmd
>> 8), cmd
& 0xff));
1104 if ((error
= show_ioc("<", &ioc
)) != 0)
1106 #endif /* DEBUG_SVR4 */
1107 return copyout(&ioc
, dat
, sizeof(ioc
));
1111 i_setsig(file_t
*fp
, struct lwp
*l
, register_t
*retval
, int fd
,
1112 u_long cmd
, void *dat
)
1115 * This is the best we can do for now; we cannot generate
1116 * signals only for specific events so the signal mask gets
1117 * ignored; we save it just to pass it to a possible I_GETSIG...
1119 * We alse have to fix the O_ASYNC fcntl bit, so the
1120 * process will get SIGPOLLs.
1122 struct sys_fcntl_args fa
;
1124 register_t oflags
, flags
;
1125 struct svr4_strm
*st
= svr4_stream_get(fp
);
1128 DPRINTF(("i_setsig: bad file descriptor\n"));
1131 /* get old status flags */
1132 SCARG(&fa
, fd
) = fd
;
1133 SCARG(&fa
, cmd
) = F_GETFL
;
1135 if ((error
= sys_fcntl(l
, &fa
, &oflags
)) != 0)
1138 /* update the flags */
1142 flags
= oflags
| O_ASYNC
;
1143 mask
= (int)(u_long
)dat
;
1144 if (mask
& ~SVR4_S_ALLMASK
) {
1145 DPRINTF(("i_setsig: bad eventmask data %x\n", mask
));
1148 st
->s_eventmask
= mask
;
1151 flags
= oflags
& ~O_ASYNC
;
1152 st
->s_eventmask
= 0;
1155 /* set the new flags, if changed */
1156 if (flags
!= oflags
) {
1157 SCARG(&fa
, cmd
) = F_SETFL
;
1158 SCARG(&fa
, arg
) = (void *) flags
;
1159 if ((error
= sys_fcntl(l
, &fa
, &flags
)) != 0)
1163 /* set up SIGIO receiver if needed */
1165 SCARG(&fa
, cmd
) = F_SETOWN
;
1166 SCARG(&fa
, arg
) = (void *)(u_long
)l
->l_proc
->p_pid
;
1167 return sys_fcntl(l
, &fa
, &flags
);
1173 i_getsig(file_t
*fp
, struct lwp
*l
, register_t
*retval
,
1174 int fd
, u_long cmd
, void *dat
)
1179 struct svr4_strm
*st
= svr4_stream_get(fp
);
1182 DPRINTF(("i_getsig: bad file descriptor\n"));
1185 if ((error
= copyout(&st
->s_eventmask
, dat
,
1186 sizeof(st
->s_eventmask
))) != 0) {
1187 DPRINTF(("i_getsig: bad eventmask pointer\n"));
1195 svr4_stream_ioctl(file_t
*fp
, struct lwp
*l
, register_t
*retval
, int fd
, u_long cmd
, void *dat
)
1200 * All the following stuff assumes "sockmod" is pushed...
1204 DPRINTF(("I_NREAD\n"));
1205 return i_nread(fp
, l
, retval
, fd
, cmd
, dat
);
1208 DPRINTF(("I_PUSH\n"));
1212 DPRINTF(("I_POP\n"));
1216 DPRINTF(("I_LOOK\n"));
1220 DPRINTF(("I_FLUSH\n"));
1224 DPRINTF(("I_SRDOPT\n"));
1228 DPRINTF(("I_GRDOPT\n"));
1232 DPRINTF(("I_STR\n"));
1233 return i_str(fp
, l
, retval
, fd
, cmd
, dat
);
1236 DPRINTF(("I_SETSIG\n"));
1237 return i_setsig(fp
, l
, retval
, fd
, cmd
, dat
);
1240 DPRINTF(("I_GETSIG\n"));
1241 return i_getsig(fp
, l
, retval
, fd
, cmd
, dat
);
1244 DPRINTF(("I_FIND\n"));
1246 * Here we are not pushing modules really, we just
1247 * pretend all are present
1253 DPRINTF(("I_LINK\n"));
1257 DPRINTF(("I_UNLINK\n"));
1260 case SVR4_I_ERECVFD
:
1261 DPRINTF(("I_ERECVFD\n"));
1265 DPRINTF(("I_PEEK\n"));
1268 case SVR4_I_FDINSERT
:
1269 DPRINTF(("I_FDINSERT\n"));
1270 return i_fdinsert(fp
, l
, retval
, fd
, cmd
, dat
);
1273 DPRINTF(("I_SENDFD\n"));
1277 DPRINTF(("I_RECVFD\n"));
1281 DPRINTF(("I_SWROPT\n"));
1285 DPRINTF(("I_GWROPT\n"));
1289 DPRINTF(("I_LIST\n"));
1293 DPRINTF(("I_PLINK\n"));
1296 case SVR4_I_PUNLINK
:
1297 DPRINTF(("I_PUNLINK\n"));
1301 DPRINTF(("I_SETEV\n"));
1305 DPRINTF(("I_GETEV\n"));
1309 DPRINTF(("I_STREV\n"));
1312 case SVR4_I_UNSTREV
:
1313 DPRINTF(("I_UNSTREV\n"));
1316 case SVR4_I_FLUSHBAND
:
1317 DPRINTF(("I_FLUSHBAND\n"));
1321 DPRINTF(("I_CKBAND\n"));
1324 case SVR4_I_GETBAND
:
1325 DPRINTF(("I_GETBANK\n"));
1329 DPRINTF(("I_ATMARK\n"));
1332 case SVR4_I_SETCLTIME
:
1333 DPRINTF(("I_SETCLTIME\n"));
1336 case SVR4_I_GETCLTIME
:
1337 DPRINTF(("I_GETCLTIME\n"));
1341 DPRINTF(("I_CANPUT\n"));
1344 case SVR4__I_BIND_RSVD
:
1345 DPRINTF(("_I_BIND_RSVD\n"));
1346 return _i_bind_rsvd(fp
, l
, retval
, fd
, cmd
, dat
);
1348 case SVR4__I_RELE_RSVD
:
1349 DPRINTF(("_I_RELE_RSVD\n"));
1350 return _i_rele_rsvd(fp
, l
, retval
, fd
, cmd
, dat
);
1353 DPRINTF(("unimpl cmd = %lx\n", cmd
));
1364 svr4_sys_putmsg(struct lwp
*l
, const struct svr4_sys_putmsg_args
*uap
, register_t
*retval
)
1366 struct proc
*p
= l
->l_proc
;
1368 struct svr4_strbuf dat
, ctl
;
1369 struct svr4_strmcmd sc
;
1370 struct sockaddr_in sain
;
1371 struct sockaddr_un saun
;
1374 struct svr4_strm
*st
;
1382 show_msg(">putmsg", SCARG(uap
, fd
), SCARG(uap
, ctl
),
1383 SCARG(uap
, dat
), SCARG(uap
, flags
));
1384 #endif /* DEBUG_SVR4 */
1386 if ((fp
= fd_getfile(SCARG(uap
, fd
))) == NULL
)
1389 KERNEL_LOCK(1, NULL
); /* svr4_find_socket */
1391 if (SCARG_PTR(uap
, ctl
) != NULL
) {
1392 if ((error
= copyin(SCARG_PTR(uap
, ctl
),
1393 &ctl
, sizeof(ctl
))) != 0)
1398 if (SCARG_PTR(uap
, dat
) != NULL
) {
1399 if ((error
= copyin(SCARG_PTR(uap
, dat
),
1400 &dat
, sizeof(dat
))) != 0)
1406 * Only for sockets for now.
1408 if ((st
= svr4_stream_get(fp
)) == NULL
) {
1409 DPRINTF(("putmsg: bad file type\n"));
1414 if (ctl
.len
> sizeof(sc
)) {
1415 DPRINTF(("putmsg: Bad control size %ld != %d\n",
1416 (unsigned long)sizeof(struct svr4_strmcmd
), ctl
.len
));
1421 if ((error
= copyin(NETBSD32PTR(ctl
.buf
), &sc
, ctl
.len
)) != 0)
1424 switch (st
->s_family
) {
1426 if (sc
.len
!= sizeof(sain
)) {
1428 if (sc
.cmd
== SVR4_TI_DATA_REQUEST
) {
1429 struct sys_write_args wa
;
1431 /* Solaris seems to use sc.cmd = 3 to
1432 * send "expedited" data. telnet uses
1433 * this for options processing, sending EOF,
1434 * etc. I'm sure other things use it too.
1435 * I don't have any documentation
1436 * on it, so I'm making a guess that this
1437 * is how it works. newton@atdot.dotat.org XXX
1439 * Hmm, expedited data seems to be sc.cmd = 4.
1440 * I think 3 is normal data. (christos)
1442 DPRINTF(("sending expedited data (?)\n"));
1443 SCARG(&wa
, fd
) = SCARG(uap
, fd
);
1444 SCARG(&wa
, buf
) = dat
.buf
;
1445 SCARG(&wa
, nbyte
) = dat
.len
;
1446 error
= sys_write(l
, &wa
, retval
);
1450 DPRINTF(("putmsg: Invalid inet length %ld\n", sc
.len
));
1454 netaddr_to_sockaddr_in(&sain
, &sc
);
1456 sasize
= sizeof(sain
);
1457 error
= sain
.sin_family
!= st
->s_family
;
1462 /* We are doing an accept; succeed */
1463 DPRINTF(("putmsg: Do nothing\n"));
1469 /* Maybe we've been given a device/inode pair */
1470 dev_t
*dev
= SVR4_ADDROF(&sc
);
1471 svr4_ino_t
*ino
= (svr4_ino_t
*) &dev
[1];
1472 skp
= svr4_find_socket(p
, fp
, *dev
, *ino
);
1475 /* I guess we have it by name */
1476 netaddr_to_sockaddr_un(skp
, &sc
);
1478 sasize
= sizeof(saun
);
1483 DPRINTF(("putmsg: Unsupported address family %d\n",
1489 nam
= m_get(M_WAIT
, MT_SONAME
);
1490 nam
->m_len
= sasize
;
1491 memcpy(mtod(nam
, void *), skp
, sasize
);
1493 switch (st
->s_cmd
= sc
.cmd
) {
1494 case SVR4_TI_CONNECT_REQUEST
: /* connect */
1495 KERNEL_UNLOCK_ONE(NULL
);
1496 return do_sys_connect(l
, SCARG(uap
, fd
), nam
);
1498 case SVR4_TI_SENDTO_REQUEST
: /* sendto */
1499 KERNEL_UNLOCK_ONE(NULL
);
1501 msg
.msg_namelen
= sasize
;
1502 msg
.msg_iov
= &aiov
;
1504 msg
.msg_control
= NULL
;
1505 msg
.msg_flags
= MSG_NAMEMBUF
;
1506 aiov
.iov_base
= NETBSD32PTR(dat
.buf
);
1507 aiov
.iov_len
= dat
.len
;
1508 error
= do_sys_sendmsg(l
, SCARG(uap
, fd
), &msg
,
1509 SCARG(uap
, flags
), retval
);
1516 DPRINTF(("putmsg: Unimplemented command %lx\n", sc
.cmd
));
1522 KERNEL_UNLOCK_ONE(NULL
);
1523 fd_putfile(SCARG(uap
, fd
));
1529 svr4_sys_getmsg(struct lwp
*l
, const struct svr4_sys_getmsg_args
*uap
, register_t
*retval
)
1532 struct svr4_strbuf dat
, ctl
;
1533 struct svr4_strmcmd sc
;
1537 struct svr4_strm
*st
;
1541 memset(&sc
, 0, sizeof(sc
));
1544 show_msg(">getmsg", SCARG(uap
, fd
), SCARG(uap
, ctl
),
1545 SCARG(uap
, dat
), 0);
1546 #endif /* DEBUG_SVR4 */
1548 if ((fp
= fd_getfile(SCARG(uap
, fd
))) == NULL
)
1551 if (SCARG_PTR(uap
, ctl
) != NULL
) {
1552 if ((error
= copyin(SCARG_PTR(uap
, ctl
), &ctl
,
1560 if (SCARG_PTR(uap
, dat
) != NULL
) {
1561 if ((error
= copyin(SCARG_PTR(uap
, dat
), &dat
,
1570 * Only for sockets for now.
1572 if ((st
= svr4_stream_get(fp
)) == NULL
) {
1573 DPRINTF(("getmsg: bad file type\n"));
1578 if (ctl
.maxlen
== -1 || dat
.maxlen
== -1) {
1579 DPRINTF(("getmsg: Cannot handle -1 maxlen (yet)\n"));
1584 switch (st
->s_family
) {
1590 DPRINTF(("getmsg: Unsupported address family %d\n",
1595 switch (st
->s_cmd
) {
1596 case SVR4_TI_CONNECT_REQUEST
:
1597 DPRINTF(("getmsg: TI_CONNECT_REQUEST\n"));
1599 * We do the connect in one step, so the putmsg should
1600 * have gotten the error.
1602 sc
.cmd
= SVR4_TI_OK_REPLY
;
1611 case SVR4_TI_OK_REPLY
:
1612 DPRINTF(("getmsg: TI_OK_REPLY\n"));
1614 * We are immediately after a connect reply, so we send
1615 * a connect verification.
1618 error
= do_sys_getsockname(l
, SCARG(uap
, fd
), PRU_SOCKADDR
,
1621 DPRINTF(("getmsg: getpeername failed %d\n", error
));
1625 sc
.cmd
= SVR4_TI_CONNECT_REPLY
;
1629 sc
.pad
[2] = 0x04000402;
1631 switch (st
->s_family
) {
1633 sc
.len
= sizeof (struct sockaddr_in
) + 4;
1634 sockaddr_to_netaddr_in(&sc
, mtod(name
, void *));
1638 sc
.len
= sizeof (struct sockaddr_un
) + 4;
1639 sockaddr_to_netaddr_un(&sc
, mtod(name
, void *));
1655 case SVR4_TI__ACCEPT_OK
:
1656 DPRINTF(("getmsg: TI__ACCEPT_OK\n"));
1658 * We do the connect in one step, so the putmsg should
1659 * have gotten the error.
1661 sc
.cmd
= SVR4_TI_OK_REPLY
;
1667 st
->s_cmd
= SVR4_TI__ACCEPT_WAIT
;
1670 case SVR4_TI__ACCEPT_WAIT
:
1671 DPRINTF(("getmsg: TI__ACCEPT_WAIT\n"));
1673 * We are after a listen, so we try to accept...
1676 error
= do_sys_accept(l
, SCARG(uap
, fd
), &name
, retval
);
1678 DPRINTF(("getmsg: accept failed %d\n", error
));
1682 st
->s_afd
= *retval
;
1684 DPRINTF(("getmsg: Accept fd = %d\n", st
->s_afd
));
1686 sc
.cmd
= SVR4_TI_ACCEPT_REPLY
;
1690 switch (st
->s_family
) {
1693 sockaddr_to_netaddr_in(&sc
, mtod(name
, void *));
1695 sc
.len
= sizeof (struct sockaddr_in
);
1699 sc
.pad
[1] = 0x00010000;
1700 sc
.pad
[2] = 0xf6bcdaa0; /* I don't know what that is */
1701 sc
.pad
[3] = 0x00010000;
1703 sc
.len
= sizeof (struct sockaddr_un
) + 4;
1715 st
->s_cmd
= SVR4_TI__ACCEPT_OK
;
1718 case SVR4_TI_SENDTO_REQUEST
:
1720 * XXX: dsl - I think this means that because we last did a
1721 * 'sendto' we'd better do a recvfrom now.
1723 DPRINTF(("getmsg: TI_SENDTO_REQUEST\n"));
1724 if (ctl
.maxlen
> 36 && ctl
.len
< 36)
1726 if (ctl
.len
> sizeof(sc
))
1727 ctl
.len
= sizeof(sc
);
1729 if ((error
= copyin(NETBSD32PTR(ctl
.buf
), &sc
, ctl
.len
)) != 0)
1732 msg
.msg_name
= NULL
;
1733 msg
.msg_namelen
= 0;
1734 msg
.msg_iov
= &aiov
;
1736 msg
.msg_control
= 0;
1737 aiov
.iov_base
= NETBSD32PTR(dat
.buf
);
1738 aiov
.iov_len
= dat
.maxlen
;
1741 error
= do_sys_recvmsg(l
, SCARG(uap
, fd
), &msg
, &name
, NULL
,
1745 DPRINTF(("getmsg: do_sys_recvmsg failed %d\n", error
));
1749 sc
.cmd
= SVR4_TI_RECVFROM_IND
;
1751 switch (st
->s_family
) {
1753 sc
.len
= sizeof (struct sockaddr_in
);
1754 sockaddr_to_netaddr_in(&sc
, mtod(name
, void *));
1758 sc
.len
= sizeof (struct sockaddr_un
) + 4;
1759 sockaddr_to_netaddr_un(&sc
, mtod(name
, void *));
1777 if (st
->s_cmd
== SVR4_TI_CONNECT_REQUEST
) {
1778 struct sys_read_args ra
;
1780 /* More weirdness: Again, I can't find documentation
1781 * to back this up, but when a process does a generic
1782 * "getmsg()" call it seems that the command field is
1783 * zero and the length of the data area is zero. I
1784 * think processes expect getmsg() to fill in dat.len
1785 * after reading at most dat.maxlen octets from the
1786 * stream. Since we're using sockets I can let
1787 * read() look after it and frob return values
1788 * appropriately (or inappropriately :-)
1789 * -- newton@atdot.dotat.org XXX
1791 SCARG(&ra
, fd
) = SCARG(uap
, fd
);
1792 SCARG(&ra
, buf
) = dat
.buf
;
1793 SCARG(&ra
, nbyte
) = dat
.maxlen
;
1794 if ((error
= sys_read(p
, &ra
, retval
)) != 0)
1798 st
->s_cmd
= SVR4_TI_SENDTO_REQUEST
;
1803 DPRINTF(("getmsg: Unknown state %x\n", st
->s_cmd
));
1808 if (SCARG_PTR(uap
, ctl
)) {
1810 if ((error
= copyout(&sc
, NETBSD32PTR(ctl
.buf
),
1814 if ((error
= copyout(&ctl
, SCARG_PTR(uap
, ctl
),
1819 if (SCARG_PTR(uap
, dat
)) {
1820 if ((error
= copyout(&dat
, SCARG_PTR(uap
, dat
),
1825 if (SCARG_PTR(uap
, flags
)) { /* XXX: Need translation */
1826 if ((error
= copyout(&fl
, SCARG_PTR(uap
, flags
),
1834 show_msg("<getmsg", SCARG(uap
, fd
), SCARG(uap
, ctl
),
1835 SCARG(uap
, dat
), fl
);
1836 #endif /* DEBUG_SVR4 */
1839 fd_putfile(SCARG(uap
, fd
));