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