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