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