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