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