1/* $NetBSD: svr4_32_socket.c,v 1.11 2007/12/20 23:03:06 dsl Exp $ */ 2 3/*- 4 * Copyright (c) 1996 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Christos Zoulas. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 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. 18 * 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. 30 */ 31 32/* 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. 41 */ 42 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 $"); 45 46#include <sys/param.h> 47#include <sys/kernel.h> 48#include <sys/systm.h> 49#include <sys/queue.h> 50#include <sys/mbuf.h> 51#include <sys/file.h> 52#include <sys/mount.h> 53#include <sys/socket.h> 54#include <sys/socketvar.h> 55#include <sys/syscallargs.h> 56#include <sys/un.h> 57#include <sys/stat.h> 58 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> 67 68struct 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; 75}; 76 77#if 0 78static TAILQ_HEAD(svr4_sockcache_head, svr4_sockcache_entry) svr4_head; 79static int initialized = 0; 80 81struct sockaddr_un * 82svr4_32_find_socket(struct proc *p, struct file *fp, dev_t dev, svr4_ino_t ino) 83{ 84 struct svr4_sockcache_entry *e; 85 void *cookie = ((struct socket *) fp->f_data)->so_internal; 86 87 if (!initialized) { 88 DPRINTF(("svr4_32_find_socket: uninitialized [%p,%d,%d]\n", 89 p, dev, ino)); 90 TAILQ_INIT(&svr4_head); 91 initialized = 1; 92 return NULL; 93 } 94 95 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) { 99#ifdef DIAGNOSTIC 100 if (e->cookie != NULL && e->cookie != cookie) 101 panic("svr4_32 socket cookie mismatch"); 102#endif 103 e->cookie = cookie; 104 DPRINTF(("%s\n", e->sock.sun_path)); 105 return &e->sock; 106 } 107 108 DPRINTF(("not found\n")); 109 return NULL; 110} 111#endif 112 113#if 0 114void 115svr4_32_delete_socket(struct proc *p, struct file *fp) 116{ 117 struct svr4_sockcache_entry *e; 118 void *cookie = ((struct socket *) fp->f_data)->so_internal; 119 120 if (!initialized) { 121 TAILQ_INIT(&svr4_head); 122 initialized = 1; 123 return; 124 } 125 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)); 131 free(e, M_TEMP); 132 return; 133 } 134} 135#endif 136 137#if 0 138int 139svr4_32_add_socket(struct proc *p, const char *path, struct stat *st) 140{ 141 struct svr4_sockcache_entry *e; 142 size_t len; 143 int error; 144 145 if (!initialized) { 146 TAILQ_INIT(&svr4_head); 147 initialized = 1; 148 } 149 150 e = malloc(sizeof(*e), M_TEMP, M_WAITOK); 151 e->cookie = NULL; 152 e->dev = st->st_dev; 153 e->ino = st->st_ino; 154 e->p = p; 155 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)); 159 free(e, M_TEMP); 160 return error; 161 } 162 163 e->sock.sun_family = AF_LOCAL; 164 e->sock.sun_len = len; 165 166 TAILQ_INSERT_HEAD(&svr4_head, e, entries); 167 DPRINTF(("svr4_32_add_socket: %s [%p,%d,%d]\n", e->sock.sun_path, 168 p, e->dev, e->ino)); 169 return 0; 170} 171#endif 172 173int 174svr4_32_sys_socket(struct lwp *l, const struct svr4_32_sys_socket_args *uap, register_t *retval) 175{ 176 struct sys___socket30_args uap0; 177 178 /* 179 * We need to use a separate args since native has a different 180 * padding. 181 */ 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; 187 break; 188 189 case SVR4_SOCK_STREAM: 190 SCARG(&uap0, type) = SOCK_STREAM; 191 break; 192 193 case SVR4_SOCK_RAW: 194 SCARG(&uap0, type) = SOCK_RAW; 195 break; 196 197 case SVR4_SOCK_RDM: 198 SCARG(&uap0, type) = SOCK_RDM; 199 break; 200 201 case SVR4_SOCK_SEQPACKET: 202 SCARG(&uap0, type) = SOCK_SEQPACKET; 203 break; 204 default: 205 return EINVAL; 206 } 207 return sys___socket30(l, &uap0, retval); 208} 209