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