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