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