1 /* $NetBSD: svr4_32_socket.c,v 1.11 2007/12/20 23:03:06 dsl Exp $ */
4 * Copyright (c) 1996 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 * In SVR4 unix domain sockets are referenced sometimes
34 * (in putmsg(2) for example) as a [device, inode] pair instead of a pathname.
35 * Since there is no iname() routine in the kernel, and we need access to
36 * a mapping from inode to pathname, we keep our own table. This is a simple
37 * linked list that contains the pathname, the [device, inode] pair, the
38 * file corresponding to that socket and the process. When the
39 * socket gets closed we remove the item from the list. The list gets loaded
40 * every time a stat(2) call finds a socket.
43 #include <sys/cdefs.h>
44 __KERNEL_RCSID(0, "$NetBSD: svr4_32_socket.c,v 1.11 2007/12/20 23:03:06 dsl Exp $");
46 #include <sys/param.h>
47 #include <sys/kernel.h>
48 #include <sys/systm.h>
49 #include <sys/queue.h>
52 #include <sys/mount.h>
53 #include <sys/socket.h>
54 #include <sys/socketvar.h>
55 #include <sys/syscallargs.h>
59 #include <compat/svr4_32/svr4_32_types.h>
60 #include <compat/svr4_32/svr4_32_util.h>
61 #include <compat/svr4_32/svr4_32_socket.h>
62 #include <compat/svr4_32/svr4_32_signal.h>
63 #include <compat/svr4/svr4_sockmod.h>
64 #include <compat/svr4_32/svr4_32_lwp.h>
65 #include <compat/svr4_32/svr4_32_ucontext.h>
66 #include <compat/svr4_32/svr4_32_syscallargs.h>
68 struct svr4_sockcache_entry
{
69 struct proc
*p
; /* Process for the socket */
70 void *cookie
; /* Internal cookie used for matching */
71 struct sockaddr_un sock
;/* Pathname for the socket */
72 dev_t dev
; /* Device where the socket lives on */
73 svr4_ino_t ino
; /* Inode where the socket lives on */
74 TAILQ_ENTRY(svr4_sockcache_entry
) entries
;
78 static TAILQ_HEAD(svr4_sockcache_head
, svr4_sockcache_entry
) svr4_head
;
79 static int initialized
= 0;
82 svr4_32_find_socket(struct proc
*p
, struct file
*fp
, dev_t dev
, svr4_ino_t ino
)
84 struct svr4_sockcache_entry
*e
;
85 void *cookie
= ((struct socket
*) fp
->f_data
)->so_internal
;
88 DPRINTF(("svr4_32_find_socket: uninitialized [%p,%d,%d]\n",
90 TAILQ_INIT(&svr4_head
);
96 DPRINTF(("svr4_32_find_socket: [%p,%d,%d]: ", p
, dev
, ino
));
97 for (e
= svr4_head
.tqh_first
; e
!= NULL
; e
= e
->entries
.tqe_next
)
98 if (e
->p
== p
&& e
->dev
== dev
&& e
->ino
== ino
) {
100 if (e
->cookie
!= NULL
&& e
->cookie
!= cookie
)
101 panic("svr4_32 socket cookie mismatch");
104 DPRINTF(("%s\n", e
->sock
.sun_path
));
108 DPRINTF(("not found\n"));
115 svr4_32_delete_socket(struct proc
*p
, struct file
*fp
)
117 struct svr4_sockcache_entry
*e
;
118 void *cookie
= ((struct socket
*) fp
->f_data
)->so_internal
;
121 TAILQ_INIT(&svr4_head
);
126 for (e
= svr4_head
.tqh_first
; e
!= NULL
; e
= e
->entries
.tqe_next
)
127 if (e
->p
== p
&& e
->cookie
== cookie
) {
128 TAILQ_REMOVE(&svr4_head
, e
, entries
);
129 DPRINTF(("svr4_delete_socket: %s [%p,%d,%d]\n",
130 e
->sock
.sun_path
, p
, e
->dev
, e
->ino
));
139 svr4_32_add_socket(struct proc
*p
, const char *path
, struct stat
*st
)
141 struct svr4_sockcache_entry
*e
;
146 TAILQ_INIT(&svr4_head
);
150 e
= malloc(sizeof(*e
), M_TEMP
, M_WAITOK
);
156 if ((error
= copyinstr(path
, e
->sock
.sun_path
,
157 sizeof(e
->sock
.sun_path
), &len
)) != 0) {
158 DPRINTF(("svr4_32_add_socket: copyinstr failed %d\n", error
));
163 e
->sock
.sun_family
= AF_LOCAL
;
164 e
->sock
.sun_len
= len
;
166 TAILQ_INSERT_HEAD(&svr4_head
, e
, entries
);
167 DPRINTF(("svr4_32_add_socket: %s [%p,%d,%d]\n", e
->sock
.sun_path
,
174 svr4_32_sys_socket(struct lwp
*l
, const struct svr4_32_sys_socket_args
*uap
, register_t
*retval
)
176 struct sys___socket30_args uap0
;
179 * We need to use a separate args since native has a different
182 SCARG(&uap0
, domain
) = SCARG(uap
, domain
);
183 SCARG(&uap0
, protocol
) = SCARG(uap
, protocol
);
184 switch (SCARG(uap
, type
)) {
185 case SVR4_SOCK_DGRAM
:
186 SCARG(&uap0
, type
) = SOCK_DGRAM
;
189 case SVR4_SOCK_STREAM
:
190 SCARG(&uap0
, type
) = SOCK_STREAM
;
194 SCARG(&uap0
, type
) = SOCK_RAW
;
198 SCARG(&uap0
, type
) = SOCK_RDM
;
201 case SVR4_SOCK_SEQPACKET
:
202 SCARG(&uap0
, type
) = SOCK_SEQPACKET
;
207 return sys___socket30(l
, &uap0
, retval
);