svr4_stream.c revision 43412
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 31/* 32 * Pretend that we have streams... 33 * Yes, this is gross. 34 * 35 * ToDo: The state machine for getmsg needs re-thinking 36 */ 37 38#define COMPAT_43 1 39 40#include <sys/param.h> 41#include <sys/kernel.h> 42#include <sys/systm.h> 43#include <sys/buf.h> 44#include <sys/malloc.h> 45#include <sys/tty.h> 46#include <sys/file.h> 47#include <sys/filedesc.h> 48#include <sys/unistd.h> 49#include <sys/fcntl.h> 50#include <sys/filio.h> 51#include <sys/select.h> 52#include <sys/socket.h> 53#include <sys/socketvar.h> 54#include <sys/un.h> 55#include <net/if.h> 56#include <netinet/in.h> 57#include <sys/mount.h> 58#include <sys/mbuf.h> 59#include <sys/protosw.h> 60#include <sys/signal.h> 61#include <sys/signalvar.h> 62#include <sys/uio.h> 63#include <sys/ktrace.h> 64#include <sys/proc.h> 65#include <sys/vnode.h> 66#include <sys/device.h> 67#include <sys/stat.h> 68 69#include <sys/sysproto.h> 70 71#include <svr4/svr4.h> 72#include <svr4/svr4_types.h> 73#include <svr4/svr4_util.h> 74#include <svr4/svr4_signal.h> 75#include <svr4/svr4_proto.h> 76#include <svr4/svr4_stropts.h> 77#include <svr4/svr4_timod.h> 78#include <svr4/svr4_sockmod.h> 79#include <svr4/svr4_ioctl.h> 80#include <svr4/svr4_socket.h> 81 82/* Utils */ 83static int clean_pipe __P((struct proc *, const char *)); 84static void getparm __P((struct file *, struct svr4_si_sockparms *)); 85 86/* Address Conversions */ 87static void sockaddr_to_netaddr_in __P((struct svr4_strmcmd *, 88 const struct sockaddr_in *)); 89static void sockaddr_to_netaddr_un __P((struct svr4_strmcmd *, 90 const struct sockaddr_un *)); 91static void netaddr_to_sockaddr_in __P((struct sockaddr_in *, 92 const struct svr4_strmcmd *)); 93static void netaddr_to_sockaddr_un __P((struct sockaddr_un *, 94 const struct svr4_strmcmd *)); 95 96/* stream ioctls */ 97static int i_nread __P((struct file *, struct proc *, register_t *, int, 98 u_long, caddr_t)); 99static int i_fdinsert __P((struct file *, struct proc *, register_t *, int, 100 u_long, caddr_t)); 101static int i_str __P((struct file *, struct proc *, register_t *, int, 102 u_long, caddr_t)); 103static int i_setsig __P((struct file *, struct proc *, register_t *, int, 104 u_long, caddr_t)); 105static int i_getsig __P((struct file *, struct proc *, register_t *, int, 106 u_long, caddr_t)); 107static int _i_bind_rsvd __P((struct file *, struct proc *, register_t *, int, 108 u_long, caddr_t)); 109static int _i_rele_rsvd __P((struct file *, struct proc *, register_t *, int, 110 u_long, caddr_t)); 111 112/* i_str sockmod calls */ 113static int sockmod __P((struct file *, int, struct svr4_strioctl *, 114 struct proc *)); 115static int si_listen __P((struct file *, int, struct svr4_strioctl *, 116 struct proc *)); 117static int si_ogetudata __P((struct file *, int, struct svr4_strioctl *, 118 struct proc *)); 119static int si_sockparams __P((struct file *, int, struct svr4_strioctl *, 120 struct proc *)); 121static int si_shutdown __P((struct file *, int, struct svr4_strioctl *, 122 struct proc *)); 123static int si_getudata __P((struct file *, int, struct svr4_strioctl *, 124 struct proc *)); 125 126/* i_str timod calls */ 127static int timod __P((struct file *, int, struct svr4_strioctl *, 128 struct proc *)); 129static int ti_getinfo __P((struct file *, int, struct svr4_strioctl *, 130 struct proc *)); 131static int ti_bind __P((struct file *, int, struct svr4_strioctl *, 132 struct proc *)); 133 134/* infrastructure */ 135static int svr4_sendit __P((struct proc *p, int s, struct msghdr *mp, 136 int flags)); 137 138static int svr4_recvit __P((struct proc *p, int s, struct msghdr *mp, 139 caddr_t namelenp)); 140 141/* <sigh> Ok, so we shouldn't use sendit() in uipc_syscalls.c because 142 * it isn't part of a "public" interface; We're supposed to use 143 * pru_sosend instead. Same goes for recvit()/pru_soreceive() for 144 * that matter. Solution: Suck sendit()/recvit() into here where we 145 * can do what we like. 146 * 147 * I hate code duplication. 148 * 149 * I will take out all the #ifdef COMPAT_OLDSOCK gumph, though. 150 */ 151static int 152svr4_sendit(p, s, mp, flags) 153 register struct proc *p; 154 int s; 155 register struct msghdr *mp; 156 int flags; 157{ 158 struct file *fp; 159 struct uio auio; 160 register struct iovec *iov; 161 register int i; 162 struct mbuf *control; 163 struct sockaddr *to; 164 int len, error; 165 struct socket *so; 166#ifdef KTRACE 167 struct iovec *ktriov = NULL; 168#endif 169 170 error = getsock(p->p_fd, s, &fp); 171 if (error) 172 return (error); 173 auio.uio_iov = mp->msg_iov; 174 auio.uio_iovcnt = mp->msg_iovlen; 175 auio.uio_segflg = UIO_USERSPACE; 176 auio.uio_rw = UIO_WRITE; 177 auio.uio_procp = p; 178 auio.uio_offset = 0; /* XXX */ 179 auio.uio_resid = 0; 180 iov = mp->msg_iov; 181 for (i = 0; i < mp->msg_iovlen; i++, iov++) { 182 if ((auio.uio_resid += iov->iov_len) < 0) 183 return (EINVAL); 184 } 185 if (mp->msg_name) { 186 error = getsockaddr(&to, mp->msg_name, mp->msg_namelen); 187 if (error) 188 return (error); 189 } else 190 to = 0; 191 if (mp->msg_control) { 192 if (mp->msg_controllen < sizeof(struct cmsghdr)) { 193 error = EINVAL; 194 goto bad; 195 } 196 error = sockargs(&control, mp->msg_control, 197 mp->msg_controllen, MT_CONTROL); 198 if (error) 199 goto bad; 200 } else 201 control = 0; 202#ifdef KTRACE 203 if (KTRPOINT(p, KTR_GENIO)) { 204 int iovlen = auio.uio_iovcnt * sizeof (struct iovec); 205 206 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 207 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 208 } 209#endif 210 len = auio.uio_resid; 211 so = (struct socket *)fp->f_data; 212 error = so->so_proto->pr_usrreqs->pru_sosend(so, to, &auio, 0, control, 213 flags, p); 214 if (error) { 215 if (auio.uio_resid != len && (error == ERESTART || 216 error == EINTR || error == EWOULDBLOCK)) 217 error = 0; 218 if (error == EPIPE) 219 psignal(p, SIGPIPE); 220 } 221 if (error == 0) 222 p->p_retval[0] = len - auio.uio_resid; 223#ifdef KTRACE 224 if (ktriov != NULL) { 225 if (error == 0) 226 ktrgenio(p->p_tracep, s, UIO_WRITE, 227 ktriov, p->p_retval[0], error); 228 FREE(ktriov, M_TEMP); 229 } 230#endif 231bad: 232 if (to) 233 FREE(to, M_SONAME); 234 return (error); 235} 236 237static int 238svr4_recvit(p, s, mp, namelenp) 239 register struct proc *p; 240 int s; 241 register struct msghdr *mp; 242 caddr_t namelenp; 243{ 244 struct file *fp; 245 struct uio auio; 246 register struct iovec *iov; 247 register int i; 248 int len, error; 249 struct mbuf *m, *control = 0; 250 caddr_t ctlbuf; 251 struct socket *so; 252 struct sockaddr *fromsa = 0; 253#ifdef KTRACE 254 struct iovec *ktriov = NULL; 255#endif 256 257 error = getsock(p->p_fd, s, &fp); 258 if (error) 259 return (error); 260 auio.uio_iov = mp->msg_iov; 261 auio.uio_iovcnt = mp->msg_iovlen; 262 auio.uio_segflg = UIO_USERSPACE; 263 auio.uio_rw = UIO_READ; 264 auio.uio_procp = p; 265 auio.uio_offset = 0; /* XXX */ 266 auio.uio_resid = 0; 267 iov = mp->msg_iov; 268 for (i = 0; i < mp->msg_iovlen; i++, iov++) { 269 if ((auio.uio_resid += iov->iov_len) < 0) 270 return (EINVAL); 271 } 272#ifdef KTRACE 273 if (KTRPOINT(p, KTR_GENIO)) { 274 int iovlen = auio.uio_iovcnt * sizeof (struct iovec); 275 276 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 277 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 278 } 279#endif 280 len = auio.uio_resid; 281 so = (struct socket *)fp->f_data; 282 error = so->so_proto->pr_usrreqs->pru_soreceive(so, &fromsa, &auio, 283 (struct mbuf **)0, mp->msg_control ? &control : (struct mbuf **)0, 284 &mp->msg_flags); 285 if (error) { 286 if (auio.uio_resid != len && (error == ERESTART || 287 error == EINTR || error == EWOULDBLOCK)) 288 error = 0; 289 } 290#ifdef KTRACE 291 if (ktriov != NULL) { 292 if (error == 0) 293 ktrgenio(p->p_tracep, s, UIO_READ, 294 ktriov, len - auio.uio_resid, error); 295 FREE(ktriov, M_TEMP); 296 } 297#endif 298 if (error) 299 goto out; 300 p->p_retval[0] = len - auio.uio_resid; 301 if (mp->msg_name) { 302 len = mp->msg_namelen; 303 if (len <= 0 || fromsa == 0) 304 len = 0; 305 else { 306#ifndef MIN 307#define MIN(a,b) ((a)>(b)?(b):(a)) 308#endif 309 /* save sa_len before it is destroyed by MSG_COMPAT */ 310 len = MIN(len, fromsa->sa_len); 311 error = copyout(fromsa, 312 (caddr_t)mp->msg_name, (unsigned)len); 313 if (error) 314 goto out; 315 } 316 mp->msg_namelen = len; 317 if (namelenp && 318 (error = copyout((caddr_t)&len, namelenp, sizeof (int)))) { 319 goto out; 320 } 321 } 322 if (mp->msg_control) { 323 len = mp->msg_controllen; 324 m = control; 325 mp->msg_controllen = 0; 326 ctlbuf = (caddr_t) mp->msg_control; 327 328 while (m && len > 0) { 329 unsigned int tocopy; 330 331 if (len >= m->m_len) 332 tocopy = m->m_len; 333 else { 334 mp->msg_flags |= MSG_CTRUNC; 335 tocopy = len; 336 } 337 338 if (error = copyout((caddr_t)mtod(m, caddr_t), 339 ctlbuf, tocopy)) 340 goto out; 341 342 ctlbuf += tocopy; 343 len -= tocopy; 344 m = m->m_next; 345 } 346 mp->msg_controllen = ctlbuf - mp->msg_control; 347 } 348out: 349 if (fromsa) 350 FREE(fromsa, M_SONAME); 351 if (control) 352 m_freem(control); 353 return (error); 354} 355 356#ifdef DEBUG_SVR4 357static void bufprint __P((u_char *, size_t)); 358static int show_ioc __P((const char *, struct svr4_strioctl *)); 359static int show_strbuf __P((struct svr4_strbuf *)); 360static void show_msg __P((const char *, int, struct svr4_strbuf *, 361 struct svr4_strbuf *, int)); 362 363static void 364bufprint(buf, len) 365 u_char *buf; 366 size_t len; 367{ 368 size_t i; 369 370 uprintf("\n\t"); 371 for (i = 0; i < len; i++) { 372 uprintf("%x ", buf[i]); 373 if (i && (i % 16) == 0) 374 uprintf("\n\t"); 375 } 376} 377 378static int 379show_ioc(str, ioc) 380 const char *str; 381 struct svr4_strioctl *ioc; 382{ 383 u_char *ptr = (u_char *) malloc(ioc->len, M_TEMP, M_WAITOK); 384 int error; 385 386 uprintf("%s cmd = %ld, timeout = %d, len = %d, buf = %p { ", 387 str, ioc->cmd, ioc->timeout, ioc->len, ioc->buf); 388 389 if ((error = copyin(ioc->buf, ptr, ioc->len)) != 0) { 390 free((char *) ptr, M_TEMP); 391 return error; 392 } 393 394 bufprint(ptr, ioc->len); 395 396 uprintf("}\n"); 397 398 free((char *) ptr, M_TEMP); 399 return 0; 400} 401 402 403static int 404show_strbuf(str) 405 struct svr4_strbuf *str; 406{ 407 int error; 408 u_char *ptr = NULL; 409 int maxlen = str->maxlen; 410 int len = str->len; 411 412 if (maxlen < 0) 413 maxlen = 0; 414 415 if (len >= maxlen) 416 len = maxlen; 417 418 if (len > 0) { 419 ptr = (u_char *) malloc(len, M_TEMP, M_WAITOK); 420 421 if ((error = copyin(str->buf, ptr, len)) != 0) { 422 free((char *) ptr, M_TEMP); 423 return error; 424 } 425 } 426 427 uprintf(", { %d, %d, %p=[ ", str->maxlen, str->len, str->buf); 428 429 if (ptr) 430 bufprint(ptr, len); 431 432 uprintf("]}"); 433 434 if (ptr) 435 free((char *) ptr, M_TEMP); 436 437 return 0; 438} 439 440 441static void 442show_msg(str, fd, ctl, dat, flags) 443 const char *str; 444 int fd; 445 struct svr4_strbuf *ctl; 446 struct svr4_strbuf *dat; 447 int flags; 448{ 449 struct svr4_strbuf buf; 450 int error; 451 452 uprintf("%s(%d", str, fd); 453 if (ctl != NULL) { 454 if ((error = copyin(ctl, &buf, sizeof(buf))) != 0) 455 return; 456 show_strbuf(&buf); 457 } 458 else 459 uprintf(", NULL"); 460 461 if (dat != NULL) { 462 if ((error = copyin(dat, &buf, sizeof(buf))) != 0) 463 return; 464 show_strbuf(&buf); 465 } 466 else 467 uprintf(", NULL"); 468 469 uprintf(", %x);\n", flags); 470} 471 472#endif /* DEBUG_SVR4 */ 473 474/* 475 * We are faced with an interesting situation. On svr4 unix sockets 476 * are really pipes. But we really have sockets, and we might as 477 * well use them. At the point where svr4 calls TI_BIND, it has 478 * already created a named pipe for the socket using mknod(2). 479 * We need to create a socket with the same name when we bind, 480 * so we need to remove the pipe before, otherwise we'll get address 481 * already in use. So we *carefully* remove the pipe, to avoid 482 * using this as a random file removal tool. We use system calls 483 * to avoid code duplication. 484 */ 485static int 486clean_pipe(p, path) 487 struct proc *p; 488 const char *path; 489{ 490 struct lstat_args la; 491 struct unlink_args ua; 492 struct stat st; 493 int error; 494 caddr_t sg = stackgap_init(); 495 size_t l = strlen(path) + 1; 496 void *tpath; 497 498 tpath = stackgap_alloc(&sg, l); 499 SCARG(&la, ub) = stackgap_alloc(&sg, sizeof(struct stat)); 500 501 if ((error = copyout(path, tpath, l)) != 0) 502 return error; 503 504 SCARG(&la, path) = tpath; 505 506 if ((error = lstat(p, &la)) != 0) 507 return 0; 508 509 if ((error = copyin(SCARG(&la, ub), &st, sizeof(st))) != 0) 510 return 0; 511 512 /* 513 * Make sure we are dealing with a mode 0 named pipe. 514 */ 515 if ((st.st_mode & S_IFMT) != S_IFIFO) 516 return 0; 517 518 if ((st.st_mode & ALLPERMS) != 0) 519 return 0; 520 521 SCARG(&ua, path) = SCARG(&la, path); 522 523 if ((error = unlink(p, &ua)) != 0) { 524 DPRINTF(("clean_pipe: unlink failed %d\n", error)); 525 return error; 526 } 527 528 return 0; 529} 530 531 532static void 533sockaddr_to_netaddr_in(sc, sain) 534 struct svr4_strmcmd *sc; 535 const struct sockaddr_in *sain; 536{ 537 struct svr4_netaddr_in *na; 538 na = SVR4_ADDROF(sc); 539 540 na->family = sain->sin_family; 541 na->port = sain->sin_port; 542 na->addr = sain->sin_addr.s_addr; 543 DPRINTF(("sockaddr_in -> netaddr %d %d %lx\n", na->family, na->port, 544 na->addr)); 545} 546 547 548static void 549sockaddr_to_netaddr_un(sc, saun) 550 struct svr4_strmcmd *sc; 551 const struct sockaddr_un *saun; 552{ 553 struct svr4_netaddr_un *na; 554 char *dst, *edst = ((char *) sc) + sc->offs + sizeof(na->family) + 1 - 555 sizeof(*sc); 556 const char *src; 557 558 na = SVR4_ADDROF(sc); 559 na->family = saun->sun_family; 560 for (src = saun->sun_path, dst = na->path; (*dst++ = *src++) != '\0'; ) 561 if (dst == edst) 562 break; 563 DPRINTF(("sockaddr_un -> netaddr %d %s\n", na->family, na->path)); 564} 565 566 567static void 568netaddr_to_sockaddr_in(sain, sc) 569 struct sockaddr_in *sain; 570 const struct svr4_strmcmd *sc; 571{ 572 const struct svr4_netaddr_in *na; 573 574 575 na = SVR4_C_ADDROF(sc); 576 memset(sain, 0, sizeof(*sain)); 577 sain->sin_len = sizeof(*sain); 578 sain->sin_family = na->family; 579 sain->sin_port = na->port; 580 sain->sin_addr.s_addr = na->addr; 581 DPRINTF(("netaddr -> sockaddr_in %d %d %x\n", sain->sin_family, 582 sain->sin_port, sain->sin_addr.s_addr)); 583} 584 585 586static void 587netaddr_to_sockaddr_un(saun, sc) 588 struct sockaddr_un *saun; 589 const struct svr4_strmcmd *sc; 590{ 591 const struct svr4_netaddr_un *na; 592 char *dst, *edst = &saun->sun_path[sizeof(saun->sun_path) - 1]; 593 const char *src; 594 595 na = SVR4_C_ADDROF(sc); 596 memset(saun, 0, sizeof(*saun)); 597 saun->sun_family = na->family; 598 for (src = na->path, dst = saun->sun_path; (*dst++ = *src++) != '\0'; ) 599 if (dst == edst) 600 break; 601 saun->sun_len = dst - saun->sun_path; 602 DPRINTF(("netaddr -> sockaddr_un %d %s\n", saun->sun_family, 603 saun->sun_path)); 604} 605 606 607static void 608getparm(fp, pa) 609 struct file *fp; 610 struct svr4_si_sockparms *pa; 611{ 612 struct svr4_strm *st = svr4_stream_get(fp); 613 struct socket *so = (struct socket *) fp->f_data; 614 615 if (st == NULL) 616 return; 617 618 pa->family = st->s_family; 619 620 switch (so->so_type) { 621 case SOCK_DGRAM: 622 pa->type = SVR4_T_CLTS; 623 pa->protocol = IPPROTO_UDP; 624 DPRINTF(("getparm(dgram)\n")); 625 return; 626 627 case SOCK_STREAM: 628 pa->type = SVR4_T_COTS; /* What about T_COTS_ORD? XXX */ 629 pa->protocol = IPPROTO_IP; 630 DPRINTF(("getparm(stream)\n")); 631 return; 632 633 case SOCK_RAW: 634 pa->type = SVR4_T_CLTS; 635 pa->protocol = IPPROTO_RAW; 636 DPRINTF(("getparm(raw)\n")); 637 return; 638 639 default: 640 pa->type = 0; 641 pa->protocol = 0; 642 DPRINTF(("getparm(type %d?)\n", so->so_type)); 643 return; 644 } 645} 646 647 648static int 649si_ogetudata(fp, fd, ioc, p) 650 struct file *fp; 651 int fd; 652 struct svr4_strioctl *ioc; 653 struct proc *p; 654{ 655 int error; 656 struct svr4_si_oudata ud; 657 struct svr4_si_sockparms pa; 658 659 if (ioc->len != sizeof(ud) && ioc->len != sizeof(ud) - sizeof(int)) { 660 DPRINTF(("SI_OGETUDATA: Wrong size %d != %d\n", 661 sizeof(ud), ioc->len)); 662 return EINVAL; 663 } 664 665 if ((error = copyin(ioc->buf, &ud, sizeof(ud))) != 0) 666 return error; 667 668 getparm(fp, &pa); 669 670 switch (pa.family) { 671 case AF_INET: 672 ud.tidusize = 16384; 673 ud.addrsize = sizeof(struct svr4_sockaddr_in); 674 if (pa.type == SVR4_SOCK_STREAM) 675 ud.etsdusize = 1; 676 else 677 ud.etsdusize = 0; 678 break; 679 680 case AF_LOCAL: 681 ud.tidusize = 65536; 682 ud.addrsize = 128; 683 ud.etsdusize = 128; 684 break; 685 686 default: 687 DPRINTF(("SI_OGETUDATA: Unsupported address family %d\n", 688 pa.family)); 689 return ENOSYS; 690 } 691 692 /* I have no idea what these should be! */ 693 ud.optsize = 128; 694 ud.tsdusize = 128; 695 696 ud.servtype = pa.type; 697 698 /* XXX: Fixme */ 699 ud.so_state = 0; 700 ud.so_options = 0; 701 return copyout(&ud, ioc->buf, ioc->len); 702} 703 704 705static int 706si_sockparams(fp, fd, ioc, p) 707 struct file *fp; 708 int fd; 709 struct svr4_strioctl *ioc; 710 struct proc *p; 711{ 712 struct svr4_si_sockparms pa; 713 714 getparm(fp, &pa); 715 return copyout(&pa, ioc->buf, sizeof(pa)); 716} 717 718 719static int 720si_listen(fp, fd, ioc, p) 721 struct file *fp; 722 int fd; 723 struct svr4_strioctl *ioc; 724 struct proc *p; 725{ 726 int error; 727 struct svr4_strm *st = svr4_stream_get(fp); 728 struct svr4_strmcmd lst; 729 struct listen_args la; 730 731 if (st == NULL) 732 return EINVAL; 733 734 if ((error = copyin(ioc->buf, &lst, ioc->len)) != 0) 735 return error; 736 737 if (lst.cmd != SVR4_TI_OLD_BIND_REQUEST) { 738 DPRINTF(("si_listen: bad request %ld\n", lst.cmd)); 739 return EINVAL; 740 } 741 742 /* 743 * We are making assumptions again... 744 */ 745 SCARG(&la, s) = fd; 746 DPRINTF(("SI_LISTEN: fileno %d backlog = %d\n", fd, 5)); 747 SCARG(&la, backlog) = 5; 748 749 if ((error = listen(p, &la)) != 0) { 750 DPRINTF(("SI_LISTEN: listen failed %d\n", error)); 751 return error; 752 } 753 754 st->s_cmd = SVR4_TI__ACCEPT_WAIT; 755 lst.cmd = SVR4_TI_BIND_REPLY; 756 757 switch (st->s_family) { 758 case AF_INET: 759 /* XXX: Fill the length here */ 760 break; 761 762 case AF_LOCAL: 763 lst.len = 140; 764 lst.pad[28] = 0x00000000; /* magic again */ 765 lst.pad[29] = 0x00000800; /* magic again */ 766 lst.pad[30] = 0x80001400; /* magic again */ 767 break; 768 769 default: 770 DPRINTF(("SI_LISTEN: Unsupported address family %d\n", 771 st->s_family)); 772 return ENOSYS; 773 } 774 775 776 if ((error = copyout(&lst, ioc->buf, ioc->len)) != 0) 777 return error; 778 779 return 0; 780} 781 782 783static int 784si_getudata(fp, fd, ioc, p) 785 struct file *fp; 786 int fd; 787 struct svr4_strioctl *ioc; 788 struct proc *p; 789{ 790 int error; 791 struct svr4_si_udata ud; 792 793 if (sizeof(ud) != ioc->len) { 794 DPRINTF(("SI_GETUDATA: Wrong size %d != %d\n", 795 sizeof(ud), ioc->len)); 796 return EINVAL; 797 } 798 799 if ((error = copyin(ioc->buf, &ud, sizeof(ud))) != 0) 800 return error; 801 802 getparm(fp, &ud.sockparms); 803 804 switch (ud.sockparms.family) { 805 case AF_INET: 806 DPRINTF(("getudata_inet\n")); 807 ud.tidusize = 16384; 808 ud.tsdusize = 16384; 809 ud.addrsize = sizeof(struct svr4_sockaddr_in); 810 if (ud.sockparms.type == SVR4_SOCK_STREAM) 811 ud.etsdusize = 1; 812 else 813 ud.etsdusize = 0; 814 ud.optsize = 0; 815 break; 816 817 case AF_LOCAL: 818 DPRINTF(("getudata_local\n")); 819 ud.tidusize = 65536; 820 ud.tsdusize = 128; 821 ud.addrsize = 128; 822 ud.etsdusize = 128; 823 ud.optsize = 128; 824 break; 825 826 default: 827 DPRINTF(("SI_GETUDATA: Unsupported address family %d\n", 828 ud.sockparms.family)); 829 return ENOSYS; 830 } 831 832 833 ud.servtype = ud.sockparms.type; 834 DPRINTF(("ud.servtype = %d\n", ud.servtype)); 835 /* XXX: Fixme */ 836 ud.so_state = 0; 837 ud.so_options = 0; 838 return copyout(&ud, ioc->buf, sizeof(ud)); 839} 840 841 842static int 843si_shutdown(fp, fd, ioc, p) 844 struct file *fp; 845 int fd; 846 struct svr4_strioctl *ioc; 847 struct proc *p; 848{ 849 int error; 850 struct shutdown_args ap; 851 852 if (ioc->len != sizeof(SCARG(&ap, how))) { 853 DPRINTF(("SI_SHUTDOWN: Wrong size %d != %d\n", 854 sizeof(SCARG(&ap, how)), ioc->len)); 855 return EINVAL; 856 } 857 858 if ((error = copyin(ioc->buf, &SCARG(&ap, how), ioc->len)) != 0) 859 return error; 860 861 SCARG(&ap, s) = fd; 862 863 return shutdown(p, &ap); 864} 865 866 867static int 868sockmod(fp, fd, ioc, p) 869 struct file *fp; 870 int fd; 871 struct svr4_strioctl *ioc; 872 struct proc *p; 873{ 874 switch (ioc->cmd) { 875 case SVR4_SI_OGETUDATA: 876 DPRINTF(("SI_OGETUDATA\n")); 877 return si_ogetudata(fp, fd, ioc, p); 878 879 case SVR4_SI_SHUTDOWN: 880 DPRINTF(("SI_SHUTDOWN\n")); 881 return si_shutdown(fp, fd, ioc, p); 882 883 case SVR4_SI_LISTEN: 884 DPRINTF(("SI_LISTEN\n")); 885 return si_listen(fp, fd, ioc, p); 886 887 case SVR4_SI_SETMYNAME: 888 DPRINTF(("SI_SETMYNAME\n")); 889 return 0; 890 891 case SVR4_SI_SETPEERNAME: 892 DPRINTF(("SI_SETPEERNAME\n")); 893 return 0; 894 895 case SVR4_SI_GETINTRANSIT: 896 DPRINTF(("SI_GETINTRANSIT\n")); 897 return 0; 898 899 case SVR4_SI_TCL_LINK: 900 DPRINTF(("SI_TCL_LINK\n")); 901 return 0; 902 903 case SVR4_SI_TCL_UNLINK: 904 DPRINTF(("SI_TCL_UNLINK\n")); 905 return 0; 906 907 case SVR4_SI_SOCKPARAMS: 908 DPRINTF(("SI_SOCKPARAMS\n")); 909 return si_sockparams(fp, fd, ioc, p); 910 911 case SVR4_SI_GETUDATA: 912 DPRINTF(("SI_GETUDATA\n")); 913 return si_getudata(fp, fd, ioc, p); 914 915 default: 916 DPRINTF(("Unknown sockmod ioctl %lx\n", ioc->cmd)); 917 return 0; 918 919 } 920} 921 922 923static int 924ti_getinfo(fp, fd, ioc, p) 925 struct file *fp; 926 int fd; 927 struct svr4_strioctl *ioc; 928 struct proc *p; 929{ 930 int error; 931 struct svr4_infocmd info; 932 933 memset(&info, 0, sizeof(info)); 934 935 if ((error = copyin(ioc->buf, &info, ioc->len)) != 0) 936 return error; 937 938 if (info.cmd != SVR4_TI_INFO_REQUEST) 939 return EINVAL; 940 941 info.cmd = SVR4_TI_INFO_REPLY; 942 info.tsdu = 0; 943 info.etsdu = 1; 944 info.cdata = -2; 945 info.ddata = -2; 946 info.addr = 16; 947 info.opt = -1; 948 info.tidu = 16384; 949 info.serv = 2; 950 info.current = 0; 951 info.provider = 2; 952 953 ioc->len = sizeof(info); 954 if ((error = copyout(&info, ioc->buf, ioc->len)) != 0) 955 return error; 956 957 return 0; 958} 959 960 961static int 962ti_bind(fp, fd, ioc, p) 963 struct file *fp; 964 int fd; 965 struct svr4_strioctl *ioc; 966 struct proc *p; 967{ 968 int error; 969 struct svr4_strm *st = svr4_stream_get(fp); 970 struct sockaddr_in sain; 971 struct sockaddr_un saun; 972 caddr_t sg; 973 void *skp, *sup = NULL; 974 int sasize; 975 struct svr4_strmcmd bnd; 976 struct bind_args ba; 977 978 if (st == NULL) { 979 DPRINTF(("ti_bind: bad file descriptor\n")); 980 return EINVAL; 981 } 982 983 if ((error = copyin(ioc->buf, &bnd, ioc->len)) != 0) 984 return error; 985 986 if (bnd.cmd != SVR4_TI_OLD_BIND_REQUEST) { 987 DPRINTF(("ti_bind: bad request %ld\n", bnd.cmd)); 988 return EINVAL; 989 } 990 991 switch (st->s_family) { 992 case AF_INET: 993 skp = &sain; 994 sasize = sizeof(sain); 995 996 if (bnd.offs == 0) 997 goto reply; 998 999 netaddr_to_sockaddr_in(&sain, &bnd); 1000 1001 DPRINTF(("TI_BIND: fam %d, port %d, addr %x\n", 1002 sain.sin_family, sain.sin_port, 1003 sain.sin_addr.s_addr)); 1004 break; 1005 1006 case AF_LOCAL: 1007 skp = &saun; 1008 sasize = sizeof(saun); 1009 if (bnd.offs == 0) 1010 goto reply; 1011 1012 netaddr_to_sockaddr_un(&saun, &bnd); 1013 1014 if (saun.sun_path[0] == '\0') 1015 goto reply; 1016 1017 DPRINTF(("TI_BIND: fam %d, path %s\n", 1018 saun.sun_family, saun.sun_path)); 1019 1020 if ((error = clean_pipe(p, saun.sun_path)) != 0) 1021 return error; 1022 1023 bnd.pad[28] = 0x00001000; /* magic again */ 1024 break; 1025 1026 default: 1027 DPRINTF(("TI_BIND: Unsupported address family %d\n", 1028 st->s_family)); 1029 return ENOSYS; 1030 } 1031 1032 sg = stackgap_init(); 1033 sup = stackgap_alloc(&sg, sasize); 1034 1035 if ((error = copyout(skp, sup, sasize)) != 0) 1036 return error; 1037 1038 SCARG(&ba, s) = fd; 1039 DPRINTF(("TI_BIND: fileno %d\n", fd)); 1040 SCARG(&ba, name) = (void *) sup; 1041 SCARG(&ba, namelen) = sasize; 1042 1043 if ((error = bind(p, &ba)) != 0) { 1044 DPRINTF(("TI_BIND: bind failed %d\n", error)); 1045 return error; 1046 } 1047 1048reply: 1049 if (sup == NULL) { 1050 memset(&bnd, 0, sizeof(bnd)); 1051 bnd.len = sasize + 4; 1052 bnd.offs = 0x10; /* XXX */ 1053 } 1054 1055 bnd.cmd = SVR4_TI_BIND_REPLY; 1056 1057 if ((error = copyout(&bnd, ioc->buf, ioc->len)) != 0) 1058 return error; 1059 1060 return 0; 1061} 1062 1063 1064static int 1065timod(fp, fd, ioc, p) 1066 struct file *fp; 1067 int fd; 1068 struct svr4_strioctl *ioc; 1069 struct proc *p; 1070{ 1071 switch (ioc->cmd) { 1072 case SVR4_TI_GETINFO: 1073 DPRINTF(("TI_GETINFO\n")); 1074 return ti_getinfo(fp, fd, ioc, p); 1075 1076 case SVR4_TI_OPTMGMT: 1077 DPRINTF(("TI_OPTMGMT\n")); 1078 return 0; 1079 1080 case SVR4_TI_BIND: 1081 DPRINTF(("TI_BIND\n")); 1082 return ti_bind(fp, fd, ioc, p); 1083 1084 case SVR4_TI_UNBIND: 1085 DPRINTF(("TI_UNBIND\n")); 1086 return 0; 1087 1088 default: 1089 DPRINTF(("Unknown timod ioctl %lx\n", ioc->cmd)); 1090 return 0; 1091 } 1092} 1093 1094 1095int 1096svr4_stream_ti_ioctl(fp, p, retval, fd, cmd, dat) 1097 struct file *fp; 1098 struct proc *p; 1099 register_t *retval; 1100 int fd; 1101 u_long cmd; 1102 caddr_t dat; 1103{ 1104 struct svr4_strbuf skb, *sub = (struct svr4_strbuf *) dat; 1105 struct svr4_strm *st = svr4_stream_get(fp); 1106 int error; 1107 void *skp, *sup; 1108 struct sockaddr_in sain; 1109 struct sockaddr_un saun; 1110 struct svr4_strmcmd sc; 1111 int sasize; 1112 caddr_t sg; 1113 int *lenp; 1114 1115 DPRINTF(("svr4_stream_ti_ioctl\n")); 1116 1117 if (st == NULL) 1118 return EINVAL; 1119 1120 sc.offs = 0x10; 1121 1122 if ((error = copyin(sub, &skb, sizeof(skb))) != 0) { 1123 DPRINTF(("ti_ioctl: error copying in strbuf\n")); 1124 return error; 1125 } 1126 1127 switch (st->s_family) { 1128 case AF_INET: 1129 skp = &sain; 1130 sasize = sizeof(sain); 1131 break; 1132 1133 case AF_LOCAL: 1134 skp = &saun; 1135 sasize = sizeof(saun); 1136 break; 1137 1138 default: 1139 DPRINTF(("ti_ioctl: Unsupported address family %d\n", 1140 st->s_family)); 1141 return ENOSYS; 1142 } 1143 1144 sg = stackgap_init(); 1145 sup = stackgap_alloc(&sg, sasize); 1146 lenp = stackgap_alloc(&sg, sizeof(*lenp)); 1147 1148 if ((error = copyout(&sasize, lenp, sizeof(*lenp))) != 0) { 1149 DPRINTF(("ti_ioctl: error copying out lenp\n")); 1150 return error; 1151 } 1152 1153 switch (cmd) { 1154 case SVR4_TI_GETMYNAME: 1155 DPRINTF(("TI_GETMYNAME\n")); 1156 { 1157 struct getsockname_args ap; 1158 SCARG(&ap, fdes) = fd; 1159 SCARG(&ap, asa) = sup; 1160 SCARG(&ap, alen) = lenp; 1161 if ((error = getsockname(p, &ap)) != 0) { 1162 DPRINTF(("ti_ioctl: getsockname error\n")); 1163 return error; 1164 } 1165 } 1166 break; 1167 1168 case SVR4_TI_GETPEERNAME: 1169 DPRINTF(("TI_GETPEERNAME\n")); 1170 { 1171 struct getpeername_args ap; 1172 SCARG(&ap, fdes) = fd; 1173 SCARG(&ap, asa) = sup; 1174 SCARG(&ap, alen) = lenp; 1175 if ((error = getpeername(p, &ap)) != 0) { 1176 DPRINTF(("ti_ioctl: getpeername error\n")); 1177 return error; 1178 } 1179 } 1180 break; 1181 1182 case SVR4_TI_SETMYNAME: 1183 DPRINTF(("TI_SETMYNAME\n")); 1184 return 0; 1185 1186 case SVR4_TI_SETPEERNAME: 1187 DPRINTF(("TI_SETPEERNAME\n")); 1188 return 0; 1189 default: 1190 DPRINTF(("ti_ioctl: Unknown ioctl %lx\n", cmd)); 1191 return ENOSYS; 1192 } 1193 1194 if ((error = copyin(sup, skp, sasize)) != 0) { 1195 DPRINTF(("ti_ioctl: error copying in socket data\n")); 1196 return error; 1197 } 1198 1199 if ((error = copyin(lenp, &sasize, sizeof(*lenp))) != 0) { 1200 DPRINTF(("ti_ioctl: error copying in socket size\n")); 1201 return error; 1202 } 1203 1204 switch (st->s_family) { 1205 case AF_INET: 1206 sockaddr_to_netaddr_in(&sc, &sain); 1207 skb.len = sasize; 1208 break; 1209 1210 case AF_LOCAL: 1211 sockaddr_to_netaddr_un(&sc, &saun); 1212 skb.len = sasize + 4; 1213 break; 1214 1215 default: 1216 return ENOSYS; 1217 } 1218 1219 1220 if ((error = copyout(SVR4_ADDROF(&sc), skb.buf, sasize)) != 0) { 1221 DPRINTF(("ti_ioctl: error copying out socket data\n")); 1222 return error; 1223 } 1224 1225 1226 if ((error = copyout(&skb, sub, sizeof(skb))) != 0) { 1227 DPRINTF(("ti_ioctl: error copying out strbuf\n")); 1228 return error; 1229 } 1230 1231 return error; 1232} 1233 1234 1235 1236 1237static int 1238i_nread(fp, p, retval, fd, cmd, dat) 1239 struct file *fp; 1240 struct proc *p; 1241 register_t *retval; 1242 int fd; 1243 u_long cmd; 1244 caddr_t dat; 1245{ 1246 int error; 1247 int nread = 0; 1248 1249 /* 1250 * We are supposed to return the message length in nread, and the 1251 * number of messages in retval. We don't have the notion of number 1252 * of stream messages, so we just find out if we have any bytes waiting 1253 * for us, and if we do, then we assume that we have at least one 1254 * message waiting for us. 1255 */ 1256 if ((error = (*fp->f_ops->fo_ioctl)(fp, FIONREAD, 1257 (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 dev_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