svr4_stream.c revision 98124
1248619Sdes/* 2106121Sdes * Copyright (c) 1998 Mark Newton. All rights reserved. 3106121Sdes * Copyright (c) 1994, 1996 Christos Zoulas. All rights reserved. 4106121Sdes * 5106121Sdes * Redistribution and use in source and binary forms, with or without 6106121Sdes * modification, are permitted provided that the following conditions 7106121Sdes * are met: 8106121Sdes * 1. Redistributions of source code must retain the above copyright 9106121Sdes * notice, this list of conditions and the following disclaimer. 10106121Sdes * 2. Redistributions in binary form must reproduce the above copyright 11106121Sdes * notice, this list of conditions and the following disclaimer in the 12106121Sdes * documentation and/or other materials provided with the distribution. 13106121Sdes * 3. All advertising materials mentioning features or use of this software 14106121Sdes * must display the following acknowledgement: 15106121Sdes * This product includes software developed by Christos Zoulas. 16124208Sdes * 4. The name of the author may not be used to endorse or promote products 17106121Sdes * derived from this software without specific prior written permission. 18106121Sdes * 19106121Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20106121Sdes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21106121Sdes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22106121Sdes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23106121Sdes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24106121Sdes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25106121Sdes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26106121Sdes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27106121Sdes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28106121Sdes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29106121Sdes * 30106121Sdes * $FreeBSD: head/sys/compat/svr4/svr4_stream.c 98124 2002-06-11 21:14:02Z alfred $ 31106121Sdes */ 32106121Sdes 33106121Sdes/* 34106121Sdes * Pretend that we have streams... 35157016Sdes * Yes, this is gross. 36157016Sdes * 37106121Sdes * ToDo: The state machine for getmsg needs re-thinking 38106121Sdes */ 39106121Sdes 40106121Sdes#define COMPAT_43 1 41137015Sdes 42137015Sdes#include <sys/param.h> 43106121Sdes#include <sys/systm.h> 44106121Sdes#include <sys/fcntl.h> 45106121Sdes#include <sys/filedesc.h> 46106121Sdes#include <sys/filio.h> 47137015Sdes#include <sys/lock.h> 48106121Sdes#include <sys/malloc.h> 49106121Sdes#include <sys/file.h> /* Must come after sys/malloc.h */ 50106121Sdes#include <sys/mbuf.h> 51106121Sdes#include <sys/mutex.h> 52106121Sdes#include <sys/proc.h> 53106121Sdes#include <sys/protosw.h> 54106121Sdes#include <sys/signal.h> 55106121Sdes#include <sys/signalvar.h> 56106121Sdes#include <sys/socket.h> 57106121Sdes#include <sys/socketvar.h> 58137015Sdes#include <sys/stat.h> 59106121Sdes#include <sys/sysproto.h> 60106121Sdes#include <sys/uio.h> 61106121Sdes#include <sys/ktrace.h> /* Must come after sys/uio.h */ 62106121Sdes#include <sys/un.h> 63106121Sdes 64106121Sdes#include <netinet/in.h> 65106121Sdes 66106121Sdes#include <compat/svr4/svr4.h> 67106121Sdes#include <compat/svr4/svr4_types.h> 68106121Sdes#include <compat/svr4/svr4_util.h> 69106121Sdes#include <compat/svr4/svr4_signal.h> 70106121Sdes#include <compat/svr4/svr4_proto.h> 71106121Sdes#include <compat/svr4/svr4_stropts.h> 72106121Sdes#include <compat/svr4/svr4_timod.h> 73106121Sdes#include <compat/svr4/svr4_sockmod.h> 74106121Sdes#include <compat/svr4/svr4_ioctl.h> 75106121Sdes#include <compat/svr4/svr4_socket.h> 76106121Sdes 77106121Sdes/* Utils */ 78106121Sdesstatic int clean_pipe(struct thread *, const char *); 79106121Sdesstatic void getparm(struct file *, struct svr4_si_sockparms *); 80106121Sdesstatic int svr4_do_putmsg(struct thread *, struct svr4_sys_putmsg_args *, 81106121Sdes struct file *); 82106121Sdesstatic int svr4_do_getmsg(struct thread *, struct svr4_sys_getmsg_args *, 83106121Sdes struct file *); 84106121Sdes 85106121Sdes/* Address Conversions */ 86106121Sdesstatic void sockaddr_to_netaddr_in(struct svr4_strmcmd *, 87106121Sdes const struct sockaddr_in *); 88106121Sdesstatic void sockaddr_to_netaddr_un(struct svr4_strmcmd *, 89106121Sdes const struct sockaddr_un *); 90106121Sdesstatic void netaddr_to_sockaddr_in(struct sockaddr_in *, 91106121Sdes const struct svr4_strmcmd *); 92106121Sdesstatic void netaddr_to_sockaddr_un(struct sockaddr_un *, 93106121Sdes const struct svr4_strmcmd *); 94106121Sdes 95106121Sdes/* stream ioctls */ 96106121Sdesstatic int i_nread(struct file *, struct thread *, register_t *, int, 97106121Sdes u_long, caddr_t); 98106121Sdesstatic int i_fdinsert(struct file *, struct thread *, register_t *, int, 99106121Sdes u_long, caddr_t); 100106121Sdesstatic int i_str(struct file *, struct thread *, register_t *, int, 101106121Sdes u_long, caddr_t); 102106121Sdesstatic int i_setsig(struct file *, struct thread *, register_t *, int, 103106121Sdes u_long, caddr_t); 104106121Sdesstatic int i_getsig(struct file *, struct thread *, register_t *, int, 105106121Sdes u_long, caddr_t); 106106121Sdesstatic int _i_bind_rsvd(struct file *, struct thread *, register_t *, int, 107106121Sdes u_long, caddr_t); 108106121Sdesstatic int _i_rele_rsvd(struct file *, struct thread *, register_t *, int, 109106121Sdes u_long, caddr_t); 110106121Sdes 111106121Sdes/* i_str sockmod calls */ 112106121Sdesstatic int sockmod(struct file *, int, struct svr4_strioctl *, 113106121Sdes struct thread *); 114106121Sdesstatic int si_listen(struct file *, int, struct svr4_strioctl *, 115106121Sdes struct thread *); 116106121Sdesstatic int si_ogetudata(struct file *, int, struct svr4_strioctl *, 117106121Sdes struct thread *); 118106121Sdesstatic int si_sockparams(struct file *, int, struct svr4_strioctl *, 119106121Sdes struct thread *); 120106121Sdesstatic int si_shutdown (struct file *, int, struct svr4_strioctl *, 121106121Sdes struct thread *); 122106121Sdesstatic int si_getudata(struct file *, int, struct svr4_strioctl *, 123106121Sdes struct thread *); 124106121Sdes 125106121Sdes/* i_str timod calls */ 126106121Sdesstatic int timod(struct file *, int, struct svr4_strioctl *, struct thread *); 127106121Sdesstatic int ti_getinfo(struct file *, int, struct svr4_strioctl *, 128106121Sdes struct thread *); 129106121Sdesstatic int ti_bind(struct file *, int, struct svr4_strioctl *, struct thread *); 130106121Sdes 131106121Sdes/* infrastructure */ 132106121Sdesstatic int svr4_sendit(struct thread *td, int s, struct msghdr *mp, int flags); 133106121Sdes 134106121Sdesstatic int svr4_recvit(struct thread *td, int s, struct msghdr *mp, 135106121Sdes caddr_t namelenp); 136106121Sdes 137106121Sdes/* <sigh> Ok, so we shouldn't use sendit() in uipc_syscalls.c because 138106121Sdes * it isn't part of a "public" interface; We're supposed to use 139106121Sdes * pru_sosend instead. Same goes for recvit()/pru_soreceive() for 140106121Sdes * that matter. Solution: Suck sendit()/recvit() into here where we 141106121Sdes * can do what we like. 142106121Sdes * 143106121Sdes * I hate code duplication. 144106121Sdes * 145106121Sdes * I will take out all the #ifdef COMPAT_OLDSOCK gumph, though. 146106121Sdes */ 147106121Sdesstatic int 148106121Sdessvr4_sendit(td, s, mp, flags) 149106121Sdes register struct thread *td; 150106121Sdes int s; 151106121Sdes register struct msghdr *mp; 152106121Sdes int flags; 153106121Sdes{ 154106121Sdes struct uio auio; 155106121Sdes register struct iovec *iov; 156106121Sdes register int i; 157106121Sdes struct mbuf *control; 158106121Sdes struct sockaddr *to; 159106121Sdes int len, error; 160106121Sdes struct socket *so; 161106121Sdes#ifdef KTRACE 162106121Sdes struct iovec *ktriov = NULL; 163106121Sdes struct uio ktruio; 164106121Sdes#endif 165106121Sdes 166106121Sdes if ((error = fgetsock(td, s, &so, NULL)) != 0) 167106121Sdes return (error); 168106121Sdes auio.uio_iov = mp->msg_iov; 169106121Sdes auio.uio_iovcnt = mp->msg_iovlen; 170181111Sdes auio.uio_segflg = UIO_USERSPACE; 171181111Sdes auio.uio_rw = UIO_WRITE; 172181111Sdes auio.uio_td = td; 173181111Sdes auio.uio_offset = 0; /* XXX */ 174181111Sdes auio.uio_resid = 0; 175181111Sdes iov = mp->msg_iov; 176106121Sdes for (i = 0; i < mp->msg_iovlen; i++, iov++) { 177106121Sdes if ((auio.uio_resid += iov->iov_len) < 0) { 178106121Sdes error = EINVAL; 179106121Sdes goto done1; 180106121Sdes } 181106121Sdes } 182106121Sdes if (mp->msg_name) { 183106121Sdes error = getsockaddr(&to, mp->msg_name, mp->msg_namelen); 184106121Sdes if (error) 185106121Sdes goto done1; 186106121Sdes } else { 187106121Sdes to = 0; 188106121Sdes } 189106121Sdes if (mp->msg_control) { 190106121Sdes if (mp->msg_controllen < sizeof(struct cmsghdr)) { 191106121Sdes error = EINVAL; 192106121Sdes goto bad; 193106121Sdes } 194106121Sdes error = sockargs(&control, mp->msg_control, 195106121Sdes mp->msg_controllen, MT_CONTROL); 196106121Sdes if (error) 197106121Sdes goto bad; 198106121Sdes } else { 199106121Sdes control = 0; 200106121Sdes } 201106121Sdes#ifdef KTRACE 202106121Sdes if (KTRPOINT(td, KTR_GENIO)) { 203106121Sdes int iovlen = auio.uio_iovcnt * sizeof (struct iovec); 204106121Sdes 205248619Sdes MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 206248619Sdes bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 207248619Sdes ktruio = auio; 208248619Sdes } 209137015Sdes#endif 210106121Sdes len = auio.uio_resid; 211106121Sdes error = so->so_proto->pr_usrreqs->pru_sosend(so, to, &auio, 0, control, 212106121Sdes flags, td); 213106121Sdes if (error) { 214106121Sdes if (auio.uio_resid != len && (error == ERESTART || 215106121Sdes error == EINTR || error == EWOULDBLOCK)) 216106121Sdes error = 0; 217106121Sdes if (error == EPIPE) { 218106121Sdes PROC_LOCK(td->td_proc); 219106121Sdes psignal(td->td_proc, SIGPIPE); 220106121Sdes PROC_UNLOCK(td->td_proc); 221106121Sdes } 222106121Sdes } 223106121Sdes if (error == 0) 224106121Sdes td->td_retval[0] = len - auio.uio_resid; 225106121Sdes#ifdef KTRACE 226106121Sdes if (ktriov != NULL) { 227248619Sdes if (error == 0) { 228137015Sdes ktruio.uio_iov = ktriov; 229137015Sdes ktruio.uio_resid = td->td_retval[0]; 230137015Sdes ktrgenio(s, UIO_WRITE, &ktruio, error); 231106121Sdes } 232106121Sdes FREE(ktriov, M_TEMP); 233106121Sdes } 234106121Sdes#endif 235106121Sdesbad: 236106121Sdes if (to) 237106121Sdes FREE(to, M_SONAME); 238181111Sdesdone1: 239106121Sdes fputsock(so); 240181111Sdes return (error); 241181111Sdes} 242106121Sdes 243106121Sdesstatic int 244106121Sdessvr4_recvit(td, s, mp, namelenp) 245181111Sdes register struct thread *td; 246106121Sdes int s; 247106121Sdes register struct msghdr *mp; 248106121Sdes caddr_t namelenp; 249106121Sdes{ 250106121Sdes struct uio auio; 251106121Sdes register struct iovec *iov; 252106121Sdes register int i; 253106121Sdes int len, error; 254106121Sdes struct mbuf *m, *control = 0; 255106121Sdes caddr_t ctlbuf; 256106121Sdes struct socket *so; 257106121Sdes struct sockaddr *fromsa = 0; 258106121Sdes#ifdef KTRACE 259106121Sdes struct iovec *ktriov = NULL; 260106121Sdes struct uio ktruio; 261106121Sdes#endif 262106121Sdes 263106121Sdes if ((error = fgetsock(td, s, &so, NULL)) != 0) 264106121Sdes return (error); 265106121Sdes auio.uio_iov = mp->msg_iov; 266106121Sdes auio.uio_iovcnt = mp->msg_iovlen; 267106121Sdes auio.uio_segflg = UIO_USERSPACE; 268106121Sdes auio.uio_rw = UIO_READ; 269106121Sdes auio.uio_td = td; 270106121Sdes auio.uio_offset = 0; /* XXX */ 271106121Sdes auio.uio_resid = 0; 272106121Sdes iov = mp->msg_iov; 273106121Sdes for (i = 0; i < mp->msg_iovlen; i++, iov++) { 274106121Sdes if ((auio.uio_resid += iov->iov_len) < 0) { 275106121Sdes error = EINVAL; 276106121Sdes goto done1; 277106121Sdes } 278106121Sdes } 279248619Sdes#ifdef KTRACE 280248619Sdes if (KTRPOINT(td, KTR_GENIO)) { 281248619Sdes int iovlen = auio.uio_iovcnt * sizeof (struct iovec); 282248619Sdes 283248619Sdes MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 284106121Sdes bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 285106121Sdes ktruio = auio; 286106121Sdes } 287106121Sdes#endif 288106121Sdes len = auio.uio_resid; 289106121Sdes error = so->so_proto->pr_usrreqs->pru_soreceive(so, &fromsa, &auio, 290106121Sdes (struct mbuf **)0, mp->msg_control ? &control : (struct mbuf **)0, 291106121Sdes &mp->msg_flags); 292106121Sdes if (error) { 293106121Sdes if (auio.uio_resid != len && (error == ERESTART || 294106121Sdes error == EINTR || error == EWOULDBLOCK)) 295106121Sdes error = 0; 296106121Sdes } 297106121Sdes#ifdef KTRACE 298106121Sdes if (ktriov != NULL) { 299106121Sdes if (error == 0) { 300106121Sdes ktruio.uio_iov = ktriov; 301106121Sdes ktruio.uio_resid = len - auio.uio_resid; 302106121Sdes ktrgenio(s, UIO_READ, &ktruio, error); 303106121Sdes } 304106121Sdes FREE(ktriov, M_TEMP); 305106121Sdes } 306106121Sdes#endif 307106121Sdes if (error) 308106121Sdes goto out; 309106121Sdes td->td_retval[0] = len - auio.uio_resid; 310106121Sdes if (mp->msg_name) { 311106121Sdes len = mp->msg_namelen; 312106121Sdes if (len <= 0 || fromsa == 0) 313106121Sdes len = 0; 314106121Sdes else { 315106121Sdes#ifndef MIN 316106121Sdes#define MIN(a,b) ((a)>(b)?(b):(a)) 317106121Sdes#endif 318181111Sdes /* save sa_len before it is destroyed by MSG_COMPAT */ 319181111Sdes len = MIN(len, fromsa->sa_len); 320106121Sdes error = copyout(fromsa, 321106121Sdes (caddr_t)mp->msg_name, (unsigned)len); 322106121Sdes if (error) 323106121Sdes goto out; 324106121Sdes } 325106121Sdes mp->msg_namelen = len; 326106121Sdes if (namelenp && 327106121Sdes (error = copyout((caddr_t)&len, namelenp, sizeof (int)))) { 328181111Sdes goto out; 329181111Sdes } 330106121Sdes } 331106121Sdes if (mp->msg_control) { 332106121Sdes len = mp->msg_controllen; 333106121Sdes m = control; 334106121Sdes mp->msg_controllen = 0; 335106121Sdes ctlbuf = (caddr_t) mp->msg_control; 336106121Sdes 337106121Sdes while (m && len > 0) { 338106121Sdes unsigned int tocopy; 339106121Sdes 340106121Sdes if (len >= m->m_len) 341106121Sdes tocopy = m->m_len; 342106121Sdes else { 343106121Sdes mp->msg_flags |= MSG_CTRUNC; 344106121Sdes tocopy = len; 345106121Sdes } 346106121Sdes 347106121Sdes if ((error = copyout((caddr_t)mtod(m, caddr_t), 348106121Sdes ctlbuf, tocopy)) != 0) 349106121Sdes goto out; 350106121Sdes 351106121Sdes ctlbuf += tocopy; 352106121Sdes len -= tocopy; 353106121Sdes m = m->m_next; 354106121Sdes } 355106121Sdes mp->msg_controllen = ctlbuf - (caddr_t)mp->msg_control; 356106121Sdes } 357106121Sdesout: 358106121Sdes if (fromsa) 359106121Sdes FREE(fromsa, M_SONAME); 360106121Sdes if (control) 361106121Sdes m_freem(control); 362248619Sdesdone1: 363248619Sdes fputsock(so); 364248619Sdes return (error); 365248619Sdes} 366248619Sdes 367106121Sdes#ifdef DEBUG_SVR4 368106121Sdesstatic void bufprint(u_char *, size_t); 369106121Sdesstatic int show_ioc(const char *, struct svr4_strioctl *); 370106121Sdesstatic int show_strbuf(struct svr4_strbuf *); 371106121Sdesstatic void show_msg(const char *, int, struct svr4_strbuf *, 372106121Sdes struct svr4_strbuf *, int); 373106121Sdes 374106121Sdesstatic void 375106121Sdesbufprint(buf, len) 376106121Sdes u_char *buf; 377106121Sdes size_t len; 378106121Sdes{ 379106121Sdes size_t i; 380106121Sdes 381106121Sdes uprintf("\n\t"); 382106121Sdes for (i = 0; i < len; i++) { 383106121Sdes uprintf("%x ", buf[i]); 384106121Sdes if (i && (i % 16) == 0) 385106121Sdes uprintf("\n\t"); 386106121Sdes } 387106121Sdes} 388106121Sdes 389106121Sdesstatic int 390106121Sdesshow_ioc(str, ioc) 391106121Sdes const char *str; 392106121Sdes struct svr4_strioctl *ioc; 393181111Sdes{ 394181111Sdes u_char *ptr = (u_char *) malloc(ioc->len, M_TEMP, M_WAITOK); 395106121Sdes int error; 396106121Sdes 397106121Sdes uprintf("%s cmd = %ld, timeout = %d, len = %d, buf = %p { ", 398248619Sdes str, ioc->cmd, ioc->timeout, ioc->len, ioc->buf); 399248619Sdes 400248619Sdes if ((error = copyin(ioc->buf, ptr, ioc->len)) != 0) { 401248619Sdes free((char *) ptr, M_TEMP); 402248619Sdes return error; 403248619Sdes } 404106121Sdes 405106121Sdes bufprint(ptr, ioc->len); 406106121Sdes 407106121Sdes uprintf("}\n"); 408106121Sdes 409106121Sdes free((char *) ptr, M_TEMP); 410106121Sdes return 0; 411106121Sdes} 412106121Sdes 413106121Sdes 414106121Sdesstatic int 415106121Sdesshow_strbuf(str) 416106121Sdes struct svr4_strbuf *str; 417106121Sdes{ 418106121Sdes int error; 419106121Sdes u_char *ptr = NULL; 420106121Sdes int maxlen = str->maxlen; 421106121Sdes int len = str->len; 422106121Sdes 423106121Sdes if (maxlen < 0) 424106121Sdes maxlen = 0; 425106121Sdes 426106121Sdes if (len >= maxlen) 427106121Sdes len = maxlen; 428106121Sdes 429106121Sdes if (len > 0) { 430106121Sdes ptr = (u_char *) malloc(len, M_TEMP, M_WAITOK); 431106121Sdes 432106121Sdes if ((error = copyin(str->buf, ptr, len)) != 0) { 433106121Sdes free((char *) ptr, M_TEMP); 434106121Sdes return error; 435106121Sdes } 436106121Sdes } 437106121Sdes 438106121Sdes uprintf(", { %d, %d, %p=[ ", str->maxlen, str->len, str->buf); 439106121Sdes 440106121Sdes if (ptr) 441248619Sdes bufprint(ptr, len); 442248619Sdes 443248619Sdes uprintf("]}"); 444248619Sdes 445248619Sdes if (ptr) 446248619Sdes free((char *) ptr, M_TEMP); 447248619Sdes 448137015Sdes return 0; 449106121Sdes} 450106121Sdes 451106121Sdes 452106121Sdesstatic void 453248619Sdesshow_msg(str, fd, ctl, dat, flags) 454248619Sdes const char *str; 455248619Sdes int fd; 456248619Sdes struct svr4_strbuf *ctl; 457248619Sdes struct svr4_strbuf *dat; 458248619Sdes int flags; 459106121Sdes{ 460106121Sdes struct svr4_strbuf buf; 461106121Sdes int error; 462106121Sdes 463106121Sdes uprintf("%s(%d", str, fd); 464106121Sdes if (ctl != NULL) { 465106121Sdes if ((error = copyin(ctl, &buf, sizeof(buf))) != 0) 466106121Sdes return; 467106121Sdes show_strbuf(&buf); 468106121Sdes } 469106121Sdes else 470106121Sdes uprintf(", NULL"); 471106121Sdes 472106121Sdes if (dat != NULL) { 473106121Sdes if ((error = copyin(dat, &buf, sizeof(buf))) != 0) 474106121Sdes return; 475106121Sdes show_strbuf(&buf); 476106121Sdes } 477106121Sdes else 478106121Sdes uprintf(", NULL"); 479106121Sdes 480106121Sdes uprintf(", %x);\n", flags); 481106121Sdes} 482106121Sdes 483106121Sdes#endif /* DEBUG_SVR4 */ 484106121Sdes 485106121Sdes/* 486106121Sdes * We are faced with an interesting situation. On svr4 unix sockets 487106121Sdes * are really pipes. But we really have sockets, and we might as 488106121Sdes * well use them. At the point where svr4 calls TI_BIND, it has 489106121Sdes * already created a named pipe for the socket using mknod(2). 490106121Sdes * We need to create a socket with the same name when we bind, 491106121Sdes * so we need to remove the pipe before, otherwise we'll get address 492106121Sdes * already in use. So we *carefully* remove the pipe, to avoid 493106121Sdes * using this as a random file removal tool. We use system calls 494106121Sdes * to avoid code duplication. 495106121Sdes */ 496106121Sdesstatic int 497106121Sdesclean_pipe(td, path) 498106121Sdes struct thread *td; 499106121Sdes const char *path; 500106121Sdes{ 501106121Sdes struct lstat_args la; 502106121Sdes struct unlink_args ua; 503106121Sdes struct stat st; 504106121Sdes int error; 505106121Sdes caddr_t sg = stackgap_init(); 506106121Sdes size_t l = strlen(path) + 1; 507106121Sdes void *tpath; 508181111Sdes 509181111Sdes tpath = stackgap_alloc(&sg, l); 510106121Sdes SCARG(&la, ub) = stackgap_alloc(&sg, sizeof(struct stat)); 511106121Sdes 512106121Sdes if ((error = copyout(path, tpath, l)) != 0) 513106121Sdes return error; 514106121Sdes 515106121Sdes SCARG(&la, path) = tpath; 516106121Sdes 517106121Sdes if ((error = lstat(td, &la)) != 0) 518106121Sdes return 0; 519106121Sdes 520181111Sdes if ((error = copyin(SCARG(&la, ub), &st, sizeof(st))) != 0) 521181111Sdes return 0; 522106121Sdes 523106121Sdes /* 524106121Sdes * Make sure we are dealing with a mode 0 named pipe. 525106121Sdes */ 526106121Sdes if ((st.st_mode & S_IFMT) != S_IFIFO) 527106121Sdes return 0; 528106121Sdes 529106121Sdes if ((st.st_mode & ALLPERMS) != 0) 530106121Sdes return 0; 531106121Sdes 532106121Sdes SCARG(&ua, path) = SCARG(&la, path); 533106121Sdes 534106121Sdes if ((error = unlink(td, &ua)) != 0) { 535106121Sdes DPRINTF(("clean_pipe: unlink failed %d\n", error)); 536106121Sdes return error; 537106121Sdes } 538106121Sdes 539106121Sdes return 0; 540106121Sdes} 541106121Sdes 542106121Sdes 543106121Sdesstatic void 544106121Sdessockaddr_to_netaddr_in(sc, sain) 545106121Sdes struct svr4_strmcmd *sc; 546106121Sdes const struct sockaddr_in *sain; 547106121Sdes{ 548106121Sdes struct svr4_netaddr_in *na; 549106121Sdes na = SVR4_ADDROF(sc); 550106121Sdes 551106121Sdes na->family = sain->sin_family; 552106121Sdes na->port = sain->sin_port; 553106121Sdes na->addr = sain->sin_addr.s_addr; 554106121Sdes DPRINTF(("sockaddr_in -> netaddr %d %d %lx\n", na->family, na->port, 555106121Sdes na->addr)); 556106121Sdes} 557106121Sdes 558248619Sdes 559248619Sdesstatic void 560248619Sdessockaddr_to_netaddr_un(sc, saun) 561248619Sdes struct svr4_strmcmd *sc; 562248619Sdes const struct sockaddr_un *saun; 563248619Sdes{ 564106121Sdes struct svr4_netaddr_un *na; 565106121Sdes char *dst, *edst = ((char *) sc) + sc->offs + sizeof(na->family) + 1 - 566106121Sdes sizeof(*sc); 567106121Sdes const char *src; 568106121Sdes 569248619Sdes na = SVR4_ADDROF(sc); 570248619Sdes na->family = saun->sun_family; 571248619Sdes for (src = saun->sun_path, dst = na->path; (*dst++ = *src++) != '\0'; ) 572248619Sdes if (dst == edst) 573248619Sdes break; 574248619Sdes DPRINTF(("sockaddr_un -> netaddr %d %s\n", na->family, na->path)); 575106121Sdes} 576106121Sdes 577106121Sdes 578106121Sdesstatic void 579106121Sdesnetaddr_to_sockaddr_in(sain, sc) 580106121Sdes struct sockaddr_in *sain; 581106121Sdes const struct svr4_strmcmd *sc; 582106121Sdes{ 583106121Sdes const struct svr4_netaddr_in *na; 584106121Sdes 585106121Sdes 586106121Sdes na = SVR4_C_ADDROF(sc); 587106121Sdes memset(sain, 0, sizeof(*sain)); 588106121Sdes sain->sin_len = sizeof(*sain); 589106121Sdes sain->sin_family = na->family; 590106121Sdes sain->sin_port = na->port; 591106121Sdes sain->sin_addr.s_addr = na->addr; 592106121Sdes DPRINTF(("netaddr -> sockaddr_in %d %d %x\n", sain->sin_family, 593106121Sdes sain->sin_port, sain->sin_addr.s_addr)); 594106121Sdes} 595106121Sdes 596106121Sdes 597106121Sdesstatic void 598106121Sdesnetaddr_to_sockaddr_un(saun, sc) 599106121Sdes struct sockaddr_un *saun; 600106121Sdes const struct svr4_strmcmd *sc; 601106121Sdes{ 602106121Sdes const struct svr4_netaddr_un *na; 603106121Sdes char *dst, *edst = &saun->sun_path[sizeof(saun->sun_path) - 1]; 604106121Sdes const char *src; 605106121Sdes 606106121Sdes na = SVR4_C_ADDROF(sc); 607106121Sdes memset(saun, 0, sizeof(*saun)); 608106121Sdes saun->sun_family = na->family; 609106121Sdes for (src = na->path, dst = saun->sun_path; (*dst++ = *src++) != '\0'; ) 610106121Sdes if (dst == edst) 611106121Sdes break; 612106121Sdes saun->sun_len = dst - saun->sun_path; 613106121Sdes DPRINTF(("netaddr -> sockaddr_un %d %s\n", saun->sun_family, 614106121Sdes saun->sun_path)); 615106121Sdes} 616106121Sdes 617106121Sdes 618106121Sdesstatic void 619106121Sdesgetparm(fp, pa) 620106121Sdes struct file *fp; 621106121Sdes struct svr4_si_sockparms *pa; 622106121Sdes{ 623106121Sdes struct svr4_strm *st; 624106121Sdes struct socket *so; 625106121Sdes 626106121Sdes st = svr4_stream_get(fp); 627106121Sdes if (st == NULL) 628106121Sdes return; 629106121Sdes 630106121Sdes so = (struct socket *) fp->f_data; 631106121Sdes 632106121Sdes pa->family = st->s_family; 633106121Sdes 634181111Sdes switch (so->so_type) { 635181111Sdes case SOCK_DGRAM: 636106121Sdes pa->type = SVR4_T_CLTS; 637106121Sdes pa->protocol = IPPROTO_UDP; 638106121Sdes DPRINTF(("getparm(dgram)\n")); 639106121Sdes return; 640106121Sdes 641106121Sdes case SOCK_STREAM: 642106121Sdes pa->type = SVR4_T_COTS; /* What about T_COTS_ORD? XXX */ 643106121Sdes pa->protocol = IPPROTO_IP; 644106121Sdes DPRINTF(("getparm(stream)\n")); 645106121Sdes return; 646106121Sdes 647106121Sdes case SOCK_RAW: 648106121Sdes pa->type = SVR4_T_CLTS; 649181111Sdes pa->protocol = IPPROTO_RAW; 650181111Sdes DPRINTF(("getparm(raw)\n")); 651106121Sdes return; 652106121Sdes 653106121Sdes default: 654 pa->type = 0; 655 pa->protocol = 0; 656 DPRINTF(("getparm(type %d?)\n", so->so_type)); 657 return; 658 } 659} 660 661 662static int 663si_ogetudata(fp, fd, ioc, td) 664 struct file *fp; 665 int fd; 666 struct svr4_strioctl *ioc; 667 struct thread *td; 668{ 669 int error; 670 struct svr4_si_oudata ud; 671 struct svr4_si_sockparms pa; 672 673 if (ioc->len != sizeof(ud) && ioc->len != sizeof(ud) - sizeof(int)) { 674 DPRINTF(("SI_OGETUDATA: Wrong size %d != %d\n", 675 sizeof(ud), ioc->len)); 676 return EINVAL; 677 } 678 679 if ((error = copyin(ioc->buf, &ud, sizeof(ud))) != 0) 680 return error; 681 682 getparm(fp, &pa); 683 684 switch (pa.family) { 685 case AF_INET: 686 ud.tidusize = 16384; 687 ud.addrsize = sizeof(struct svr4_sockaddr_in); 688 if (pa.type == SVR4_SOCK_STREAM) 689 ud.etsdusize = 1; 690 else 691 ud.etsdusize = 0; 692 break; 693 694 case AF_LOCAL: 695 ud.tidusize = 65536; 696 ud.addrsize = 128; 697 ud.etsdusize = 128; 698 break; 699 700 default: 701 DPRINTF(("SI_OGETUDATA: Unsupported address family %d\n", 702 pa.family)); 703 return ENOSYS; 704 } 705 706 /* I have no idea what these should be! */ 707 ud.optsize = 128; 708 ud.tsdusize = 128; 709 710 ud.servtype = pa.type; 711 712 /* XXX: Fixme */ 713 ud.so_state = 0; 714 ud.so_options = 0; 715 return copyout(&ud, ioc->buf, ioc->len); 716} 717 718 719static int 720si_sockparams(fp, fd, ioc, td) 721 struct file *fp; 722 int fd; 723 struct svr4_strioctl *ioc; 724 struct thread *td; 725{ 726 struct svr4_si_sockparms pa; 727 728 getparm(fp, &pa); 729 return copyout(&pa, ioc->buf, sizeof(pa)); 730} 731 732 733static int 734si_listen(fp, fd, ioc, td) 735 struct file *fp; 736 int fd; 737 struct svr4_strioctl *ioc; 738 struct thread *td; 739{ 740 int error; 741 struct svr4_strm *st = svr4_stream_get(fp); 742 struct svr4_strmcmd lst; 743 struct listen_args la; 744 745 if (st == NULL) 746 return EINVAL; 747 748 if ((error = copyin(ioc->buf, &lst, ioc->len)) != 0) 749 return error; 750 751 if (lst.cmd != SVR4_TI_OLD_BIND_REQUEST) { 752 DPRINTF(("si_listen: bad request %ld\n", lst.cmd)); 753 return EINVAL; 754 } 755 756 /* 757 * We are making assumptions again... 758 */ 759 SCARG(&la, s) = fd; 760 DPRINTF(("SI_LISTEN: fileno %d backlog = %d\n", fd, 5)); 761 SCARG(&la, backlog) = 5; 762 763 if ((error = listen(td, &la)) != 0) { 764 DPRINTF(("SI_LISTEN: listen failed %d\n", error)); 765 return error; 766 } 767 768 st->s_cmd = SVR4_TI__ACCEPT_WAIT; 769 lst.cmd = SVR4_TI_BIND_REPLY; 770 771 switch (st->s_family) { 772 case AF_INET: 773 /* XXX: Fill the length here */ 774 break; 775 776 case AF_LOCAL: 777 lst.len = 140; 778 lst.pad[28] = 0x00000000; /* magic again */ 779 lst.pad[29] = 0x00000800; /* magic again */ 780 lst.pad[30] = 0x80001400; /* magic again */ 781 break; 782 783 default: 784 DPRINTF(("SI_LISTEN: Unsupported address family %d\n", 785 st->s_family)); 786 return ENOSYS; 787 } 788 789 790 if ((error = copyout(&lst, ioc->buf, ioc->len)) != 0) 791 return error; 792 793 return 0; 794} 795 796 797static int 798si_getudata(fp, fd, ioc, td) 799 struct file *fp; 800 int fd; 801 struct svr4_strioctl *ioc; 802 struct thread *td; 803{ 804 int error; 805 struct svr4_si_udata ud; 806 807 if (sizeof(ud) != ioc->len) { 808 DPRINTF(("SI_GETUDATA: Wrong size %d != %d\n", 809 sizeof(ud), ioc->len)); 810 return EINVAL; 811 } 812 813 if ((error = copyin(ioc->buf, &ud, sizeof(ud))) != 0) 814 return error; 815 816 getparm(fp, &ud.sockparms); 817 818 switch (ud.sockparms.family) { 819 case AF_INET: 820 DPRINTF(("getudata_inet\n")); 821 ud.tidusize = 16384; 822 ud.tsdusize = 16384; 823 ud.addrsize = sizeof(struct svr4_sockaddr_in); 824 if (ud.sockparms.type == SVR4_SOCK_STREAM) 825 ud.etsdusize = 1; 826 else 827 ud.etsdusize = 0; 828 ud.optsize = 0; 829 break; 830 831 case AF_LOCAL: 832 DPRINTF(("getudata_local\n")); 833 ud.tidusize = 65536; 834 ud.tsdusize = 128; 835 ud.addrsize = 128; 836 ud.etsdusize = 128; 837 ud.optsize = 128; 838 break; 839 840 default: 841 DPRINTF(("SI_GETUDATA: Unsupported address family %d\n", 842 ud.sockparms.family)); 843 return ENOSYS; 844 } 845 846 847 ud.servtype = ud.sockparms.type; 848 DPRINTF(("ud.servtype = %d\n", ud.servtype)); 849 /* XXX: Fixme */ 850 ud.so_state = 0; 851 ud.so_options = 0; 852 return copyout(&ud, ioc->buf, sizeof(ud)); 853} 854 855 856static int 857si_shutdown(fp, fd, ioc, td) 858 struct file *fp; 859 int fd; 860 struct svr4_strioctl *ioc; 861 struct thread *td; 862{ 863 int error; 864 struct shutdown_args ap; 865 866 if (ioc->len != sizeof(SCARG(&ap, how))) { 867 DPRINTF(("SI_SHUTDOWN: Wrong size %d != %d\n", 868 sizeof(SCARG(&ap, how)), ioc->len)); 869 return EINVAL; 870 } 871 872 if ((error = copyin(ioc->buf, &SCARG(&ap, how), ioc->len)) != 0) 873 return error; 874 875 SCARG(&ap, s) = fd; 876 877 return shutdown(td, &ap); 878} 879 880 881static int 882sockmod(fp, fd, ioc, td) 883 struct file *fp; 884 int fd; 885 struct svr4_strioctl *ioc; 886 struct thread *td; 887{ 888 switch (ioc->cmd) { 889 case SVR4_SI_OGETUDATA: 890 DPRINTF(("SI_OGETUDATA\n")); 891 return si_ogetudata(fp, fd, ioc, td); 892 893 case SVR4_SI_SHUTDOWN: 894 DPRINTF(("SI_SHUTDOWN\n")); 895 return si_shutdown(fp, fd, ioc, td); 896 897 case SVR4_SI_LISTEN: 898 DPRINTF(("SI_LISTEN\n")); 899 return si_listen(fp, fd, ioc, td); 900 901 case SVR4_SI_SETMYNAME: 902 DPRINTF(("SI_SETMYNAME\n")); 903 return 0; 904 905 case SVR4_SI_SETPEERNAME: 906 DPRINTF(("SI_SETPEERNAME\n")); 907 return 0; 908 909 case SVR4_SI_GETINTRANSIT: 910 DPRINTF(("SI_GETINTRANSIT\n")); 911 return 0; 912 913 case SVR4_SI_TCL_LINK: 914 DPRINTF(("SI_TCL_LINK\n")); 915 return 0; 916 917 case SVR4_SI_TCL_UNLINK: 918 DPRINTF(("SI_TCL_UNLINK\n")); 919 return 0; 920 921 case SVR4_SI_SOCKPARAMS: 922 DPRINTF(("SI_SOCKPARAMS\n")); 923 return si_sockparams(fp, fd, ioc, td); 924 925 case SVR4_SI_GETUDATA: 926 DPRINTF(("SI_GETUDATA\n")); 927 return si_getudata(fp, fd, ioc, td); 928 929 default: 930 DPRINTF(("Unknown sockmod ioctl %lx\n", ioc->cmd)); 931 return 0; 932 933 } 934} 935 936 937static int 938ti_getinfo(fp, fd, ioc, td) 939 struct file *fp; 940 int fd; 941 struct svr4_strioctl *ioc; 942 struct thread *td; 943{ 944 int error; 945 struct svr4_infocmd info; 946 947 memset(&info, 0, sizeof(info)); 948 949 if ((error = copyin(ioc->buf, &info, ioc->len)) != 0) 950 return error; 951 952 if (info.cmd != SVR4_TI_INFO_REQUEST) 953 return EINVAL; 954 955 info.cmd = SVR4_TI_INFO_REPLY; 956 info.tsdu = 0; 957 info.etsdu = 1; 958 info.cdata = -2; 959 info.ddata = -2; 960 info.addr = 16; 961 info.opt = -1; 962 info.tidu = 16384; 963 info.serv = 2; 964 info.current = 0; 965 info.provider = 2; 966 967 ioc->len = sizeof(info); 968 if ((error = copyout(&info, ioc->buf, ioc->len)) != 0) 969 return error; 970 971 return 0; 972} 973 974 975static int 976ti_bind(fp, fd, ioc, td) 977 struct file *fp; 978 int fd; 979 struct svr4_strioctl *ioc; 980 struct thread *td; 981{ 982 int error; 983 struct svr4_strm *st = svr4_stream_get(fp); 984 struct sockaddr_in sain; 985 struct sockaddr_un saun; 986 caddr_t sg; 987 void *skp, *sup = NULL; 988 int sasize; 989 struct svr4_strmcmd bnd; 990 struct bind_args ba; 991 992 if (st == NULL) { 993 DPRINTF(("ti_bind: bad file descriptor\n")); 994 return EINVAL; 995 } 996 997 if ((error = copyin(ioc->buf, &bnd, ioc->len)) != 0) 998 return error; 999 1000 if (bnd.cmd != SVR4_TI_OLD_BIND_REQUEST) { 1001 DPRINTF(("ti_bind: bad request %ld\n", bnd.cmd)); 1002 return EINVAL; 1003 } 1004 1005 switch (st->s_family) { 1006 case AF_INET: 1007 skp = &sain; 1008 sasize = sizeof(sain); 1009 1010 if (bnd.offs == 0) 1011 goto reply; 1012 1013 netaddr_to_sockaddr_in(&sain, &bnd); 1014 1015 DPRINTF(("TI_BIND: fam %d, port %d, addr %x\n", 1016 sain.sin_family, sain.sin_port, 1017 sain.sin_addr.s_addr)); 1018 break; 1019 1020 case AF_LOCAL: 1021 skp = &saun; 1022 sasize = sizeof(saun); 1023 if (bnd.offs == 0) 1024 goto reply; 1025 1026 netaddr_to_sockaddr_un(&saun, &bnd); 1027 1028 if (saun.sun_path[0] == '\0') 1029 goto reply; 1030 1031 DPRINTF(("TI_BIND: fam %d, path %s\n", 1032 saun.sun_family, saun.sun_path)); 1033 1034 if ((error = clean_pipe(td, saun.sun_path)) != 0) 1035 return error; 1036 1037 bnd.pad[28] = 0x00001000; /* magic again */ 1038 break; 1039 1040 default: 1041 DPRINTF(("TI_BIND: Unsupported address family %d\n", 1042 st->s_family)); 1043 return ENOSYS; 1044 } 1045 1046 sg = stackgap_init(); 1047 sup = stackgap_alloc(&sg, sasize); 1048 1049 if ((error = copyout(skp, sup, sasize)) != 0) 1050 return error; 1051 1052 SCARG(&ba, s) = fd; 1053 DPRINTF(("TI_BIND: fileno %d\n", fd)); 1054 SCARG(&ba, name) = (void *) sup; 1055 SCARG(&ba, namelen) = sasize; 1056 1057 if ((error = bind(td, &ba)) != 0) { 1058 DPRINTF(("TI_BIND: bind failed %d\n", error)); 1059 return error; 1060 } 1061 1062reply: 1063 if (sup == NULL) { 1064 memset(&bnd, 0, sizeof(bnd)); 1065 bnd.len = sasize + 4; 1066 bnd.offs = 0x10; /* XXX */ 1067 } 1068 1069 bnd.cmd = SVR4_TI_BIND_REPLY; 1070 1071 if ((error = copyout(&bnd, ioc->buf, ioc->len)) != 0) 1072 return error; 1073 1074 return 0; 1075} 1076 1077 1078static int 1079timod(fp, fd, ioc, td) 1080 struct file *fp; 1081 int fd; 1082 struct svr4_strioctl *ioc; 1083 struct thread *td; 1084{ 1085 switch (ioc->cmd) { 1086 case SVR4_TI_GETINFO: 1087 DPRINTF(("TI_GETINFO\n")); 1088 return ti_getinfo(fp, fd, ioc, td); 1089 1090 case SVR4_TI_OPTMGMT: 1091 DPRINTF(("TI_OPTMGMT\n")); 1092 return 0; 1093 1094 case SVR4_TI_BIND: 1095 DPRINTF(("TI_BIND\n")); 1096 return ti_bind(fp, fd, ioc, td); 1097 1098 case SVR4_TI_UNBIND: 1099 DPRINTF(("TI_UNBIND\n")); 1100 return 0; 1101 1102 default: 1103 DPRINTF(("Unknown timod ioctl %lx\n", ioc->cmd)); 1104 return 0; 1105 } 1106} 1107 1108 1109int 1110svr4_stream_ti_ioctl(fp, td, retval, fd, cmd, dat) 1111 struct file *fp; 1112 struct thread *td; 1113 register_t *retval; 1114 int fd; 1115 u_long cmd; 1116 caddr_t dat; 1117{ 1118 struct svr4_strbuf skb, *sub = (struct svr4_strbuf *) dat; 1119 struct svr4_strm *st = svr4_stream_get(fp); 1120 int error; 1121 void *skp, *sup; 1122 struct sockaddr_in sain; 1123 struct sockaddr_un saun; 1124 struct svr4_strmcmd sc; 1125 int sasize; 1126 caddr_t sg; 1127 int *lenp; 1128 1129 DPRINTF(("svr4_stream_ti_ioctl\n")); 1130 1131 if (st == NULL) 1132 return EINVAL; 1133 1134 sc.offs = 0x10; 1135 1136 if ((error = copyin(sub, &skb, sizeof(skb))) != 0) { 1137 DPRINTF(("ti_ioctl: error copying in strbuf\n")); 1138 return error; 1139 } 1140 1141 switch (st->s_family) { 1142 case AF_INET: 1143 skp = &sain; 1144 sasize = sizeof(sain); 1145 break; 1146 1147 case AF_LOCAL: 1148 skp = &saun; 1149 sasize = sizeof(saun); 1150 break; 1151 1152 default: 1153 DPRINTF(("ti_ioctl: Unsupported address family %d\n", 1154 st->s_family)); 1155 return ENOSYS; 1156 } 1157 1158 sg = stackgap_init(); 1159 sup = stackgap_alloc(&sg, sasize); 1160 lenp = stackgap_alloc(&sg, sizeof(*lenp)); 1161 1162 if ((error = copyout(&sasize, lenp, sizeof(*lenp))) != 0) { 1163 DPRINTF(("ti_ioctl: error copying out lenp\n")); 1164 return error; 1165 } 1166 1167 switch (cmd) { 1168 case SVR4_TI_GETMYNAME: 1169 DPRINTF(("TI_GETMYNAME\n")); 1170 { 1171 struct getsockname_args ap; 1172 SCARG(&ap, fdes) = fd; 1173 SCARG(&ap, asa) = sup; 1174 SCARG(&ap, alen) = lenp; 1175 if ((error = getsockname(td, &ap)) != 0) { 1176 DPRINTF(("ti_ioctl: getsockname error\n")); 1177 return error; 1178 } 1179 } 1180 break; 1181 1182 case SVR4_TI_GETPEERNAME: 1183 DPRINTF(("TI_GETPEERNAME\n")); 1184 { 1185 struct getpeername_args ap; 1186 SCARG(&ap, fdes) = fd; 1187 SCARG(&ap, asa) = sup; 1188 SCARG(&ap, alen) = lenp; 1189 if ((error = getpeername(td, &ap)) != 0) { 1190 DPRINTF(("ti_ioctl: getpeername error\n")); 1191 return error; 1192 } 1193 } 1194 break; 1195 1196 case SVR4_TI_SETMYNAME: 1197 DPRINTF(("TI_SETMYNAME\n")); 1198 return 0; 1199 1200 case SVR4_TI_SETPEERNAME: 1201 DPRINTF(("TI_SETPEERNAME\n")); 1202 return 0; 1203 default: 1204 DPRINTF(("ti_ioctl: Unknown ioctl %lx\n", cmd)); 1205 return ENOSYS; 1206 } 1207 1208 if ((error = copyin(sup, skp, sasize)) != 0) { 1209 DPRINTF(("ti_ioctl: error copying in socket data\n")); 1210 return error; 1211 } 1212 1213 if ((error = copyin(lenp, &sasize, sizeof(*lenp))) != 0) { 1214 DPRINTF(("ti_ioctl: error copying in socket size\n")); 1215 return error; 1216 } 1217 1218 switch (st->s_family) { 1219 case AF_INET: 1220 sockaddr_to_netaddr_in(&sc, &sain); 1221 skb.len = sasize; 1222 break; 1223 1224 case AF_LOCAL: 1225 sockaddr_to_netaddr_un(&sc, &saun); 1226 skb.len = sasize + 4; 1227 break; 1228 1229 default: 1230 return ENOSYS; 1231 } 1232 1233 1234 if ((error = copyout(SVR4_ADDROF(&sc), skb.buf, sasize)) != 0) { 1235 DPRINTF(("ti_ioctl: error copying out socket data\n")); 1236 return error; 1237 } 1238 1239 1240 if ((error = copyout(&skb, sub, sizeof(skb))) != 0) { 1241 DPRINTF(("ti_ioctl: error copying out strbuf\n")); 1242 return error; 1243 } 1244 1245 return error; 1246} 1247 1248 1249 1250 1251static int 1252i_nread(fp, td, retval, fd, cmd, dat) 1253 struct file *fp; 1254 struct thread *td; 1255 register_t *retval; 1256 int fd; 1257 u_long cmd; 1258 caddr_t dat; 1259{ 1260 int error; 1261 int nread = 0; 1262 1263 /* 1264 * We are supposed to return the message length in nread, and the 1265 * number of messages in retval. We don't have the notion of number 1266 * of stream messages, so we just find out if we have any bytes waiting 1267 * for us, and if we do, then we assume that we have at least one 1268 * message waiting for us. 1269 */ 1270 if ((error = fo_ioctl(fp, FIONREAD, (caddr_t) &nread, td)) != 0) 1271 return error; 1272 1273 if (nread != 0) 1274 *retval = 1; 1275 else 1276 *retval = 0; 1277 1278 return copyout(&nread, dat, sizeof(nread)); 1279} 1280 1281static int 1282i_fdinsert(fp, td, retval, fd, cmd, dat) 1283 struct file *fp; 1284 struct thread *td; 1285 register_t *retval; 1286 int fd; 1287 u_long cmd; 1288 caddr_t dat; 1289{ 1290 /* 1291 * Major hack again here. We assume that we are using this to 1292 * implement accept(2). If that is the case, we have already 1293 * called accept, and we have stored the file descriptor in 1294 * afd. We find the file descriptor that the code wants to use 1295 * in fd insert, and then we dup2() our accepted file descriptor 1296 * to it. 1297 */ 1298 int error; 1299 struct svr4_strm *st = svr4_stream_get(fp); 1300 struct svr4_strfdinsert fdi; 1301 struct dup2_args d2p; 1302 struct close_args clp; 1303 1304 if (st == NULL) { 1305 DPRINTF(("fdinsert: bad file type\n")); 1306 return EINVAL; 1307 } 1308 1309 if (st->s_afd == -1) { 1310 DPRINTF(("fdinsert: accept fd not found\n")); 1311 return ENOENT; 1312 } 1313 1314 if ((error = copyin(dat, &fdi, sizeof(fdi))) != 0) { 1315 DPRINTF(("fdinsert: copyin failed %d\n", error)); 1316 return error; 1317 } 1318 1319 SCARG(&d2p, from) = st->s_afd; 1320 SCARG(&d2p, to) = fdi.fd; 1321 1322 if ((error = dup2(td, &d2p)) != 0) { 1323 DPRINTF(("fdinsert: dup2(%d, %d) failed %d\n", 1324 st->s_afd, fdi.fd, error)); 1325 return error; 1326 } 1327 1328 SCARG(&clp, fd) = st->s_afd; 1329 1330 if ((error = close(td, &clp)) != 0) { 1331 DPRINTF(("fdinsert: close(%d) failed %d\n", 1332 st->s_afd, error)); 1333 return error; 1334 } 1335 1336 st->s_afd = -1; 1337 1338 *retval = 0; 1339 return 0; 1340} 1341 1342 1343static int 1344_i_bind_rsvd(fp, td, retval, fd, cmd, dat) 1345 struct file *fp; 1346 struct thread *td; 1347 register_t *retval; 1348 int fd; 1349 u_long cmd; 1350 caddr_t dat; 1351{ 1352 struct mkfifo_args ap; 1353 1354 /* 1355 * This is a supposed to be a kernel and library only ioctl. 1356 * It gets called before ti_bind, when we have a unix 1357 * socket, to physically create the socket transport and 1358 * ``reserve'' it. I don't know how this get reserved inside 1359 * the kernel, but we are going to create it nevertheless. 1360 */ 1361 SCARG(&ap, path) = dat; 1362 SCARG(&ap, mode) = S_IFIFO; 1363 1364 return mkfifo(td, &ap); 1365} 1366 1367static int 1368_i_rele_rsvd(fp, td, retval, fd, cmd, dat) 1369 struct file *fp; 1370 struct thread *td; 1371 register_t *retval; 1372 int fd; 1373 u_long cmd; 1374 caddr_t dat; 1375{ 1376 struct unlink_args ap; 1377 1378 /* 1379 * This is a supposed to be a kernel and library only ioctl. 1380 * I guess it is supposed to release the socket. 1381 */ 1382 SCARG(&ap, path) = dat; 1383 1384 return unlink(td, &ap); 1385} 1386 1387static int 1388i_str(fp, td, retval, fd, cmd, dat) 1389 struct file *fp; 1390 struct thread *td; 1391 register_t *retval; 1392 int fd; 1393 u_long cmd; 1394 caddr_t dat; 1395{ 1396 int error; 1397 struct svr4_strioctl ioc; 1398 1399 if ((error = copyin(dat, &ioc, sizeof(ioc))) != 0) 1400 return error; 1401 1402#ifdef DEBUG_SVR4 1403 if ((error = show_ioc(">", &ioc)) != 0) 1404 return error; 1405#endif /* DEBUG_SVR4 */ 1406 1407 switch (ioc.cmd & 0xff00) { 1408 case SVR4_SIMOD: 1409 if ((error = sockmod(fp, fd, &ioc, td)) != 0) 1410 return error; 1411 break; 1412 1413 case SVR4_TIMOD: 1414 if ((error = timod(fp, fd, &ioc, td)) != 0) 1415 return error; 1416 break; 1417 1418 default: 1419 DPRINTF(("Unimplemented module %c %ld\n", 1420 (char) (cmd >> 8), cmd & 0xff)); 1421 return 0; 1422 } 1423 1424#ifdef DEBUG_SVR4 1425 if ((error = show_ioc("<", &ioc)) != 0) 1426 return error; 1427#endif /* DEBUG_SVR4 */ 1428 return copyout(&ioc, dat, sizeof(ioc)); 1429} 1430 1431static int 1432i_setsig(fp, td, retval, fd, cmd, dat) 1433 struct file *fp; 1434 struct thread *td; 1435 register_t *retval; 1436 int fd; 1437 u_long cmd; 1438 caddr_t dat; 1439{ 1440 /* 1441 * This is the best we can do for now; we cannot generate 1442 * signals only for specific events so the signal mask gets 1443 * ignored; we save it just to pass it to a possible I_GETSIG... 1444 * 1445 * We alse have to fix the O_ASYNC fcntl bit, so the 1446 * process will get SIGPOLLs. 1447 */ 1448 struct fcntl_args fa; 1449 int error; 1450 register_t oflags, flags; 1451 struct svr4_strm *st = svr4_stream_get(fp); 1452 1453 if (st == NULL) { 1454 DPRINTF(("i_setsig: bad file descriptor\n")); 1455 return EINVAL; 1456 } 1457 /* get old status flags */ 1458 SCARG(&fa, fd) = fd; 1459 SCARG(&fa, cmd) = F_GETFL; 1460 if ((error = fcntl(td, &fa)) != 0) 1461 return error; 1462 1463 oflags = td->td_retval[0]; 1464 1465 /* update the flags */ 1466 if (dat != NULL) { 1467 int mask; 1468 1469 flags = oflags | O_ASYNC; 1470 if ((error = copyin(dat, &mask, sizeof(mask))) != 0) { 1471 DPRINTF(("i_setsig: bad eventmask pointer\n")); 1472 return error; 1473 } 1474 if (mask & SVR4_S_ALLMASK) { 1475 DPRINTF(("i_setsig: bad eventmask data %x\n", mask)); 1476 return EINVAL; 1477 } 1478 st->s_eventmask = mask; 1479 } 1480 else { 1481 flags = oflags & ~O_ASYNC; 1482 st->s_eventmask = 0; 1483 } 1484 1485 /* set the new flags, if changed */ 1486 if (flags != oflags) { 1487 SCARG(&fa, cmd) = F_SETFL; 1488 SCARG(&fa, arg) = (long) flags; 1489 if ((error = fcntl(td, &fa)) != 0) 1490 return error; 1491 flags = td->td_retval[0]; 1492 } 1493 1494 /* set up SIGIO receiver if needed */ 1495 if (dat != NULL) { 1496 SCARG(&fa, cmd) = F_SETOWN; 1497 SCARG(&fa, arg) = (long) td->td_proc->p_pid; 1498 return fcntl(td, &fa); 1499 } 1500 return 0; 1501} 1502 1503static int 1504i_getsig(fp, td, retval, fd, cmd, dat) 1505 struct file *fp; 1506 struct thread *td; 1507 register_t *retval; 1508 int fd; 1509 u_long cmd; 1510 caddr_t dat; 1511{ 1512 int error; 1513 1514 if (dat != NULL) { 1515 struct svr4_strm *st = svr4_stream_get(fp); 1516 1517 if (st == NULL) { 1518 DPRINTF(("i_getsig: bad file descriptor\n")); 1519 return EINVAL; 1520 } 1521 if ((error = copyout(&st->s_eventmask, dat, 1522 sizeof(st->s_eventmask))) != 0) { 1523 DPRINTF(("i_getsig: bad eventmask pointer\n")); 1524 return error; 1525 } 1526 } 1527 return 0; 1528} 1529 1530int 1531svr4_stream_ioctl(fp, td, retval, fd, cmd, dat) 1532 struct file *fp; 1533 struct thread *td; 1534 register_t *retval; 1535 int fd; 1536 u_long cmd; 1537 caddr_t dat; 1538{ 1539 *retval = 0; 1540 1541 /* 1542 * All the following stuff assumes "sockmod" is pushed... 1543 */ 1544 switch (cmd) { 1545 case SVR4_I_NREAD: 1546 DPRINTF(("I_NREAD\n")); 1547 return i_nread(fp, td, retval, fd, cmd, dat); 1548 1549 case SVR4_I_PUSH: 1550 DPRINTF(("I_PUSH %p\n", dat)); 1551#if defined(DEBUG_SVR4) 1552 show_strbuf((struct svr4_strbuf *)dat); 1553#endif 1554 return 0; 1555 1556 case SVR4_I_POP: 1557 DPRINTF(("I_POP\n")); 1558 return 0; 1559 1560 case SVR4_I_LOOK: 1561 DPRINTF(("I_LOOK\n")); 1562 return 0; 1563 1564 case SVR4_I_FLUSH: 1565 DPRINTF(("I_FLUSH\n")); 1566 return 0; 1567 1568 case SVR4_I_SRDOPT: 1569 DPRINTF(("I_SRDOPT\n")); 1570 return 0; 1571 1572 case SVR4_I_GRDOPT: 1573 DPRINTF(("I_GRDOPT\n")); 1574 return 0; 1575 1576 case SVR4_I_STR: 1577 DPRINTF(("I_STR\n")); 1578 return i_str(fp, td, retval, fd, cmd, dat); 1579 1580 case SVR4_I_SETSIG: 1581 DPRINTF(("I_SETSIG\n")); 1582 return i_setsig(fp, td, retval, fd, cmd, dat); 1583 1584 case SVR4_I_GETSIG: 1585 DPRINTF(("I_GETSIG\n")); 1586 return i_getsig(fp, td, retval, fd, cmd, dat); 1587 1588 case SVR4_I_FIND: 1589 DPRINTF(("I_FIND\n")); 1590 /* 1591 * Here we are not pushing modules really, we just 1592 * pretend all are present 1593 */ 1594 *retval = 0; 1595 return 0; 1596 1597 case SVR4_I_LINK: 1598 DPRINTF(("I_LINK\n")); 1599 return 0; 1600 1601 case SVR4_I_UNLINK: 1602 DPRINTF(("I_UNLINK\n")); 1603 return 0; 1604 1605 case SVR4_I_ERECVFD: 1606 DPRINTF(("I_ERECVFD\n")); 1607 return 0; 1608 1609 case SVR4_I_PEEK: 1610 DPRINTF(("I_PEEK\n")); 1611 return 0; 1612 1613 case SVR4_I_FDINSERT: 1614 DPRINTF(("I_FDINSERT\n")); 1615 return i_fdinsert(fp, td, retval, fd, cmd, dat); 1616 1617 case SVR4_I_SENDFD: 1618 DPRINTF(("I_SENDFD\n")); 1619 return 0; 1620 1621 case SVR4_I_RECVFD: 1622 DPRINTF(("I_RECVFD\n")); 1623 return 0; 1624 1625 case SVR4_I_SWROPT: 1626 DPRINTF(("I_SWROPT\n")); 1627 return 0; 1628 1629 case SVR4_I_GWROPT: 1630 DPRINTF(("I_GWROPT\n")); 1631 return 0; 1632 1633 case SVR4_I_LIST: 1634 DPRINTF(("I_LIST\n")); 1635 return 0; 1636 1637 case SVR4_I_PLINK: 1638 DPRINTF(("I_PLINK\n")); 1639 return 0; 1640 1641 case SVR4_I_PUNLINK: 1642 DPRINTF(("I_PUNLINK\n")); 1643 return 0; 1644 1645 case SVR4_I_SETEV: 1646 DPRINTF(("I_SETEV\n")); 1647 return 0; 1648 1649 case SVR4_I_GETEV: 1650 DPRINTF(("I_GETEV\n")); 1651 return 0; 1652 1653 case SVR4_I_STREV: 1654 DPRINTF(("I_STREV\n")); 1655 return 0; 1656 1657 case SVR4_I_UNSTREV: 1658 DPRINTF(("I_UNSTREV\n")); 1659 return 0; 1660 1661 case SVR4_I_FLUSHBAND: 1662 DPRINTF(("I_FLUSHBAND\n")); 1663 return 0; 1664 1665 case SVR4_I_CKBAND: 1666 DPRINTF(("I_CKBAND\n")); 1667 return 0; 1668 1669 case SVR4_I_GETBAND: 1670 DPRINTF(("I_GETBANK\n")); 1671 return 0; 1672 1673 case SVR4_I_ATMARK: 1674 DPRINTF(("I_ATMARK\n")); 1675 return 0; 1676 1677 case SVR4_I_SETCLTIME: 1678 DPRINTF(("I_SETCLTIME\n")); 1679 return 0; 1680 1681 case SVR4_I_GETCLTIME: 1682 DPRINTF(("I_GETCLTIME\n")); 1683 return 0; 1684 1685 case SVR4_I_CANPUT: 1686 DPRINTF(("I_CANPUT\n")); 1687 return 0; 1688 1689 case SVR4__I_BIND_RSVD: 1690 DPRINTF(("_I_BIND_RSVD\n")); 1691 return _i_bind_rsvd(fp, td, retval, fd, cmd, dat); 1692 1693 case SVR4__I_RELE_RSVD: 1694 DPRINTF(("_I_RELE_RSVD\n")); 1695 return _i_rele_rsvd(fp, td, retval, fd, cmd, dat); 1696 1697 default: 1698 DPRINTF(("unimpl cmd = %lx\n", cmd)); 1699 break; 1700 } 1701 1702 return 0; 1703} 1704 1705 1706 1707int 1708svr4_sys_putmsg(td, uap) 1709 register struct thread *td; 1710 struct svr4_sys_putmsg_args *uap; 1711{ 1712 struct file *fp; 1713 int error; 1714 1715 if ((error = fget(td, uap->fd, &fp)) != 0) { 1716#ifdef DEBUG_SVR4 1717 uprintf("putmsg: bad fp\n"); 1718#endif 1719 return EBADF; 1720 } 1721 error = svr4_do_putmsg(td, uap, fp); 1722 fdrop(fp, td); 1723 return (error); 1724} 1725 1726static int 1727svr4_do_putmsg(td, uap, fp) 1728 struct thread *td; 1729 struct svr4_sys_putmsg_args *uap; 1730 struct file *fp; 1731{ 1732 struct svr4_strbuf dat, ctl; 1733 struct svr4_strmcmd sc; 1734 struct sockaddr_in sain; 1735 struct sockaddr_un saun; 1736 void *skp, *sup; 1737 int sasize, *retval; 1738 struct svr4_strm *st; 1739 int error; 1740 caddr_t sg; 1741 1742 retval = td->td_retval; 1743 1744#ifdef DEBUG_SVR4 1745 show_msg(">putmsg", SCARG(uap, fd), SCARG(uap, ctl), 1746 SCARG(uap, dat), SCARG(uap, flags)); 1747#endif /* DEBUG_SVR4 */ 1748 1749 FILE_LOCK_ASSERT(fp, MA_NOTOWNED); 1750 1751 if (SCARG(uap, ctl) != NULL) { 1752 if ((error = copyin(SCARG(uap, ctl), &ctl, sizeof(ctl))) != 0) { 1753#ifdef DEBUG_SVR4 1754 uprintf("putmsg: copyin(): %d\n", error); 1755#endif 1756 return error; 1757 } 1758 } 1759 else 1760 ctl.len = -1; 1761 1762 if (SCARG(uap, dat) != NULL) { 1763 if ((error = copyin(SCARG(uap, dat), &dat, sizeof(dat))) != 0) { 1764#ifdef DEBUG_SVR4 1765 uprintf("putmsg: copyin(): %d (2)\n", error); 1766#endif 1767 return error; 1768 } 1769 } 1770 else 1771 dat.len = -1; 1772 1773 /* 1774 * Only for sockets for now. 1775 */ 1776 if ((st = svr4_stream_get(fp)) == NULL) { 1777 DPRINTF(("putmsg: bad file type\n")); 1778 return EINVAL; 1779 } 1780 1781 if (ctl.len > sizeof(sc)) { 1782 DPRINTF(("putmsg: Bad control size %d != %d\n", ctl.len, 1783 sizeof(struct svr4_strmcmd))); 1784 return EINVAL; 1785 } 1786 1787 if ((error = copyin(ctl.buf, &sc, ctl.len)) != 0) 1788 return error; 1789 1790 switch (st->s_family) { 1791 case AF_INET: 1792 if (sc.len != sizeof(sain)) { 1793 if (sc.cmd == SVR4_TI_DATA_REQUEST) { 1794 struct write_args wa; 1795 1796 /* Solaris seems to use sc.cmd = 3 to 1797 * send "expedited" data. telnet uses 1798 * this for options processing, sending EOF, 1799 * etc. I'm sure other things use it too. 1800 * I don't have any documentation 1801 * on it, so I'm making a guess that this 1802 * is how it works. newton@atdot.dotat.org XXX 1803 */ 1804 DPRINTF(("sending expedited data ??\n")); 1805 SCARG(&wa, fd) = SCARG(uap, fd); 1806 SCARG(&wa, buf) = dat.buf; 1807 SCARG(&wa, nbyte) = dat.len; 1808 return write(td, &wa); 1809 } 1810 DPRINTF(("putmsg: Invalid inet length %ld\n", sc.len)); 1811 return EINVAL; 1812 } 1813 netaddr_to_sockaddr_in(&sain, &sc); 1814 skp = &sain; 1815 sasize = sizeof(sain); 1816 error = sain.sin_family != st->s_family; 1817 break; 1818 1819 case AF_LOCAL: 1820 if (ctl.len == 8) { 1821 /* We are doing an accept; succeed */ 1822 DPRINTF(("putmsg: Do nothing\n")); 1823 *retval = 0; 1824 return 0; 1825 } 1826 else { 1827 /* Maybe we've been given a device/inode pair */ 1828 udev_t *dev = SVR4_ADDROF(&sc); 1829 ino_t *ino = (ino_t *) &dev[1]; 1830 skp = svr4_find_socket(td, fp, *dev, *ino); 1831 if (skp == NULL) { 1832 skp = &saun; 1833 /* I guess we have it by name */ 1834 netaddr_to_sockaddr_un(skp, &sc); 1835 } 1836 sasize = sizeof(saun); 1837 } 1838 break; 1839 1840 default: 1841 DPRINTF(("putmsg: Unsupported address family %d\n", 1842 st->s_family)); 1843 return ENOSYS; 1844 } 1845 1846 sg = stackgap_init(); 1847 sup = stackgap_alloc(&sg, sasize); 1848 1849 if ((error = copyout(skp, sup, sasize)) != 0) 1850 return error; 1851 1852 switch (st->s_cmd = sc.cmd) { 1853 case SVR4_TI_CONNECT_REQUEST: /* connect */ 1854 { 1855 struct connect_args co; 1856 1857 SCARG(&co, s) = SCARG(uap, fd); 1858 SCARG(&co, name) = (void *) sup; 1859 SCARG(&co, namelen) = (int) sasize; 1860 1861 return connect(td, &co); 1862 } 1863 1864 case SVR4_TI_SENDTO_REQUEST: /* sendto */ 1865 { 1866 struct msghdr msg; 1867 struct iovec aiov; 1868 1869 msg.msg_name = (caddr_t) sup; 1870 msg.msg_namelen = sasize; 1871 msg.msg_iov = &aiov; 1872 msg.msg_iovlen = 1; 1873 msg.msg_control = 0; 1874 msg.msg_flags = 0; 1875 aiov.iov_base = dat.buf; 1876 aiov.iov_len = dat.len; 1877#if 0 1878 error = so->so_proto->pr_usrreqs->pru_sosend(so, 0, 1879 uio, 0, 0, 0, uio->uio_td); 1880#endif 1881 error = svr4_sendit(td, SCARG(uap, fd), &msg, 1882 SCARG(uap, flags)); 1883 DPRINTF(("sendto_request error: %d\n", error)); 1884 *retval = 0; 1885 return error; 1886 } 1887 1888 default: 1889 DPRINTF(("putmsg: Unimplemented command %lx\n", sc.cmd)); 1890 return ENOSYS; 1891 } 1892} 1893 1894int 1895svr4_sys_getmsg(td, uap) 1896 struct thread *td; 1897 struct svr4_sys_getmsg_args *uap; 1898{ 1899 struct file *fp; 1900 int error; 1901 1902 if ((error = fget(td, uap->fd, &fp)) != 0) { 1903#ifdef DEBUG_SVR4 1904 uprintf("getmsg: bad fp\n"); 1905#endif 1906 return EBADF; 1907 } 1908 error = svr4_do_getmsg(td, uap, fp); 1909 fdrop(fp, td); 1910 return (error); 1911} 1912 1913int 1914svr4_do_getmsg(td, uap, fp) 1915 register struct thread *td; 1916 struct svr4_sys_getmsg_args *uap; 1917 struct file *fp; 1918{ 1919 struct getpeername_args ga; 1920 struct accept_args aa; 1921 struct svr4_strbuf dat, ctl; 1922 struct svr4_strmcmd sc; 1923 int error, *retval; 1924 struct msghdr msg; 1925 struct iovec aiov; 1926 struct sockaddr_in sain; 1927 struct sockaddr_un saun; 1928 void *skp, *sup; 1929 int sasize; 1930 struct svr4_strm *st; 1931 int *flen; 1932 int fl; 1933 caddr_t sg; 1934 1935 retval = td->td_retval; 1936 1937 FILE_LOCK_ASSERT(fp, MA_NOTOWNED); 1938 1939 memset(&sc, 0, sizeof(sc)); 1940 1941#ifdef DEBUG_SVR4 1942 show_msg(">getmsg", SCARG(uap, fd), SCARG(uap, ctl), 1943 SCARG(uap, dat), 0); 1944#endif /* DEBUG_SVR4 */ 1945 1946 if (SCARG(uap, ctl) != NULL) { 1947 if ((error = copyin(SCARG(uap, ctl), &ctl, sizeof(ctl))) != 0) 1948 return error; 1949 } 1950 else { 1951 ctl.len = -1; 1952 ctl.maxlen = 0; 1953 } 1954 1955 if (SCARG(uap, dat) != NULL) { 1956 if ((error = copyin(SCARG(uap, dat), &dat, sizeof(dat))) != 0) 1957 return error; 1958 } 1959 else { 1960 dat.len = -1; 1961 dat.maxlen = 0; 1962 } 1963 1964 /* 1965 * Only for sockets for now. 1966 */ 1967 if ((st = svr4_stream_get(fp)) == NULL) { 1968 DPRINTF(("getmsg: bad file type\n")); 1969 return EINVAL; 1970 } 1971 1972 if (ctl.maxlen == -1 || dat.maxlen == -1) { 1973 DPRINTF(("getmsg: Cannot handle -1 maxlen (yet)\n")); 1974 return ENOSYS; 1975 } 1976 1977 switch (st->s_family) { 1978 case AF_INET: 1979 skp = &sain; 1980 sasize = sizeof(sain); 1981 break; 1982 1983 case AF_LOCAL: 1984 skp = &saun; 1985 sasize = sizeof(saun); 1986 break; 1987 1988 default: 1989 DPRINTF(("getmsg: Unsupported address family %d\n", 1990 st->s_family)); 1991 return ENOSYS; 1992 } 1993 1994 sg = stackgap_init(); 1995 sup = stackgap_alloc(&sg, sasize); 1996 flen = (int *) stackgap_alloc(&sg, sizeof(*flen)); 1997 1998 fl = sasize; 1999 if ((error = copyout(&fl, flen, sizeof(fl))) != 0) 2000 return error; 2001 2002 switch (st->s_cmd) { 2003 case SVR4_TI_CONNECT_REQUEST: 2004 DPRINTF(("getmsg: TI_CONNECT_REQUEST\n")); 2005 /* 2006 * We do the connect in one step, so the putmsg should 2007 * have gotten the error. 2008 */ 2009 sc.cmd = SVR4_TI_OK_REPLY; 2010 sc.len = 0; 2011 2012 ctl.len = 8; 2013 dat.len = -1; 2014 fl = 1; 2015 st->s_cmd = sc.cmd; 2016 break; 2017 2018 case SVR4_TI_OK_REPLY: 2019 DPRINTF(("getmsg: TI_OK_REPLY\n")); 2020 /* 2021 * We are immediately after a connect reply, so we send 2022 * a connect verification. 2023 */ 2024 2025 SCARG(&ga, fdes) = SCARG(uap, fd); 2026 SCARG(&ga, asa) = (void *) sup; 2027 SCARG(&ga, alen) = flen; 2028 2029 if ((error = getpeername(td, &ga)) != 0) { 2030 DPRINTF(("getmsg: getpeername failed %d\n", error)); 2031 return error; 2032 } 2033 2034 if ((error = copyin(sup, skp, sasize)) != 0) 2035 return error; 2036 2037 sc.cmd = SVR4_TI_CONNECT_REPLY; 2038 sc.pad[0] = 0x4; 2039 sc.offs = 0x18; 2040 sc.pad[1] = 0x14; 2041 sc.pad[2] = 0x04000402; 2042 2043 switch (st->s_family) { 2044 case AF_INET: 2045 sc.len = sasize; 2046 sockaddr_to_netaddr_in(&sc, &sain); 2047 break; 2048 2049 case AF_LOCAL: 2050 sc.len = sasize + 4; 2051 sockaddr_to_netaddr_un(&sc, &saun); 2052 break; 2053 2054 default: 2055 return ENOSYS; 2056 } 2057 2058 ctl.len = 40; 2059 dat.len = -1; 2060 fl = 0; 2061 st->s_cmd = sc.cmd; 2062 break; 2063 2064 case SVR4_TI__ACCEPT_OK: 2065 DPRINTF(("getmsg: TI__ACCEPT_OK\n")); 2066 /* 2067 * We do the connect in one step, so the putmsg should 2068 * have gotten the error. 2069 */ 2070 sc.cmd = SVR4_TI_OK_REPLY; 2071 sc.len = 1; 2072 2073 ctl.len = 8; 2074 dat.len = -1; 2075 fl = 1; 2076 st->s_cmd = SVR4_TI__ACCEPT_WAIT; 2077 break; 2078 2079 case SVR4_TI__ACCEPT_WAIT: 2080 DPRINTF(("getmsg: TI__ACCEPT_WAIT\n")); 2081 /* 2082 * We are after a listen, so we try to accept... 2083 */ 2084 SCARG(&aa, s) = SCARG(uap, fd); 2085 SCARG(&aa, name) = (void *) sup; 2086 SCARG(&aa, anamelen) = flen; 2087 2088 if ((error = accept(td, &aa)) != 0) { 2089 DPRINTF(("getmsg: accept failed %d\n", error)); 2090 return error; 2091 } 2092 2093 st->s_afd = *retval; 2094 2095 DPRINTF(("getmsg: Accept fd = %d\n", st->s_afd)); 2096 2097 if ((error = copyin(sup, skp, sasize)) != 0) 2098 return error; 2099 2100 sc.cmd = SVR4_TI_ACCEPT_REPLY; 2101 sc.offs = 0x18; 2102 sc.pad[0] = 0x0; 2103 2104 switch (st->s_family) { 2105 case AF_INET: 2106 sc.pad[1] = 0x28; 2107 sockaddr_to_netaddr_in(&sc, &sain); 2108 ctl.len = 40; 2109 sc.len = sasize; 2110 break; 2111 2112 case AF_LOCAL: 2113 sc.pad[1] = 0x00010000; 2114 sc.pad[2] = 0xf6bcdaa0; /* I don't know what that is */ 2115 sc.pad[3] = 0x00010000; 2116 ctl.len = 134; 2117 sc.len = sasize + 4; 2118 break; 2119 2120 default: 2121 return ENOSYS; 2122 } 2123 2124 dat.len = -1; 2125 fl = 0; 2126 st->s_cmd = SVR4_TI__ACCEPT_OK; 2127 break; 2128 2129 case SVR4_TI_SENDTO_REQUEST: 2130 DPRINTF(("getmsg: TI_SENDTO_REQUEST\n")); 2131 if (ctl.maxlen > 36 && ctl.len < 36) 2132 ctl.len = 36; 2133 2134 if ((error = copyin(ctl.buf, &sc, ctl.len)) != 0) 2135 return error; 2136 2137 switch (st->s_family) { 2138 case AF_INET: 2139 sockaddr_to_netaddr_in(&sc, &sain); 2140 break; 2141 2142 case AF_LOCAL: 2143 sockaddr_to_netaddr_un(&sc, &saun); 2144 break; 2145 2146 default: 2147 return ENOSYS; 2148 } 2149 2150 msg.msg_name = (caddr_t) sup; 2151 msg.msg_namelen = sasize; 2152 msg.msg_iov = &aiov; 2153 msg.msg_iovlen = 1; 2154 msg.msg_control = 0; 2155 aiov.iov_base = dat.buf; 2156 aiov.iov_len = dat.maxlen; 2157 msg.msg_flags = 0; 2158 2159 error = svr4_recvit(td, SCARG(uap, fd), &msg, (caddr_t) flen); 2160 2161 if (error) { 2162 DPRINTF(("getmsg: recvit failed %d\n", error)); 2163 return error; 2164 } 2165 2166 if ((error = copyin(msg.msg_name, skp, sasize)) != 0) 2167 return error; 2168 2169 sc.cmd = SVR4_TI_RECVFROM_IND; 2170 2171 switch (st->s_family) { 2172 case AF_INET: 2173 sc.len = sasize; 2174 sockaddr_to_netaddr_in(&sc, &sain); 2175 break; 2176 2177 case AF_LOCAL: 2178 sc.len = sasize + 4; 2179 sockaddr_to_netaddr_un(&sc, &saun); 2180 break; 2181 2182 default: 2183 return ENOSYS; 2184 } 2185 2186 dat.len = *retval; 2187 fl = 0; 2188 st->s_cmd = sc.cmd; 2189 break; 2190 2191 default: 2192 st->s_cmd = sc.cmd; 2193 if (st->s_cmd == SVR4_TI_CONNECT_REQUEST) { 2194 struct read_args ra; 2195 2196 /* More weirdness: Again, I can't find documentation 2197 * to back this up, but when a process does a generic 2198 * "getmsg()" call it seems that the command field is 2199 * zero and the length of the data area is zero. I 2200 * think processes expect getmsg() to fill in dat.len 2201 * after reading at most dat.maxlen octets from the 2202 * stream. Since we're using sockets I can let 2203 * read() look after it and frob return values 2204 * appropriately (or inappropriately :-) 2205 * -- newton@atdot.dotat.org XXX 2206 */ 2207 SCARG(&ra, fd) = SCARG(uap, fd); 2208 SCARG(&ra, buf) = dat.buf; 2209 SCARG(&ra, nbyte) = dat.maxlen; 2210 if ((error = read(td, &ra)) != 0) { 2211 return error; 2212 } 2213 dat.len = *retval; 2214 *retval = 0; 2215 st->s_cmd = SVR4_TI_SENDTO_REQUEST; 2216 break; 2217 } 2218 DPRINTF(("getmsg: Unknown state %x\n", st->s_cmd)); 2219 return EINVAL; 2220 } 2221 2222 if (SCARG(uap, ctl)) { 2223 if (ctl.len != -1) 2224 if ((error = copyout(&sc, ctl.buf, ctl.len)) != 0) 2225 return error; 2226 2227 if ((error = copyout(&ctl, SCARG(uap, ctl), sizeof(ctl))) != 0) 2228 return error; 2229 } 2230 2231 if (SCARG(uap, dat)) { 2232 if ((error = copyout(&dat, SCARG(uap, dat), sizeof(dat))) != 0) 2233 return error; 2234 } 2235 2236 if (SCARG(uap, flags)) { /* XXX: Need translation */ 2237 if ((error = copyout(&fl, SCARG(uap, flags), sizeof(fl))) != 0) 2238 return error; 2239 } 2240 2241 *retval = 0; 2242 2243#ifdef DEBUG_SVR4 2244 show_msg("<getmsg", SCARG(uap, fd), SCARG(uap, ctl), 2245 SCARG(uap, dat), fl); 2246#endif /* DEBUG_SVR4 */ 2247 return error; 2248} 2249 2250int svr4_sys_send(td, uap) 2251 struct thread *td; 2252 struct svr4_sys_send_args *uap; 2253{ 2254 struct osend_args osa; 2255 SCARG(&osa, s) = SCARG(uap, s); 2256 SCARG(&osa, buf) = SCARG(uap, buf); 2257 SCARG(&osa, len) = SCARG(uap, len); 2258 SCARG(&osa, flags) = SCARG(uap, flags); 2259 return osend(td, &osa); 2260} 2261 2262int svr4_sys_recv(td, uap) 2263 struct thread *td; 2264 struct svr4_sys_recv_args *uap; 2265{ 2266 struct orecv_args ora; 2267 SCARG(&ora, s) = SCARG(uap, s); 2268 SCARG(&ora, buf) = SCARG(uap, buf); 2269 SCARG(&ora, len) = SCARG(uap, len); 2270 SCARG(&ora, flags) = SCARG(uap, flags); 2271 return orecv(td, &ora); 2272} 2273 2274/* 2275 * XXX This isn't necessary, but it's handy for inserting debug code into 2276 * sendto(). Let's leave it here for now... 2277 */ 2278int 2279svr4_sys_sendto(td, uap) 2280 struct thread *td; 2281 struct svr4_sys_sendto_args *uap; 2282{ 2283 struct sendto_args sa; 2284 2285 SCARG(&sa, s) = SCARG(uap, s); 2286 SCARG(&sa, buf) = SCARG(uap, buf); 2287 SCARG(&sa, len) = SCARG(uap, len); 2288 SCARG(&sa, flags) = SCARG(uap, flags); 2289 SCARG(&sa, to) = (caddr_t)SCARG(uap, to); 2290 SCARG(&sa, tolen) = SCARG(uap, tolen); 2291 2292 DPRINTF(("calling sendto()\n")); 2293 return sendto(td, &sa); 2294} 2295 2296