svr4_stream.c revision 92761
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 92761 2002-03-20 05:48:58Z alfred $ 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/fcntl.h> 45#include <sys/filedesc.h> 46#include <sys/filio.h> 47#include <sys/lock.h> 48#include <sys/malloc.h> 49#include <sys/file.h> /* Must come after sys/malloc.h */ 50#include <sys/mbuf.h> 51#include <sys/mutex.h> 52#include <sys/proc.h> 53#include <sys/protosw.h> 54#include <sys/signal.h> 55#include <sys/signalvar.h> 56#include <sys/socket.h> 57#include <sys/socketvar.h> 58#include <sys/stat.h> 59#include <sys/sysproto.h> 60#include <sys/uio.h> 61#include <sys/ktrace.h> /* Must come after sys/uio.h */ 62#include <sys/un.h> 63 64#include <netinet/in.h> 65 66#include <compat/svr4/svr4.h> 67#include <compat/svr4/svr4_types.h> 68#include <compat/svr4/svr4_util.h> 69#include <compat/svr4/svr4_signal.h> 70#include <compat/svr4/svr4_proto.h> 71#include <compat/svr4/svr4_stropts.h> 72#include <compat/svr4/svr4_timod.h> 73#include <compat/svr4/svr4_sockmod.h> 74#include <compat/svr4/svr4_ioctl.h> 75#include <compat/svr4/svr4_socket.h> 76 77/* Utils */ 78static int clean_pipe(struct thread *, const char *); 79static void getparm(struct file *, struct svr4_si_sockparms *); 80static int svr4_do_putmsg(struct thread *, struct svr4_sys_putmsg_args *, 81 struct file *); 82static int svr4_do_getmsg(struct thread *, struct svr4_sys_getmsg_args *, 83 struct file *); 84 85/* Address Conversions */ 86static void sockaddr_to_netaddr_in(struct svr4_strmcmd *, 87 const struct sockaddr_in *); 88static void sockaddr_to_netaddr_un(struct svr4_strmcmd *, 89 const struct sockaddr_un *); 90static void netaddr_to_sockaddr_in(struct sockaddr_in *, 91 const struct svr4_strmcmd *); 92static void netaddr_to_sockaddr_un(struct sockaddr_un *, 93 const struct svr4_strmcmd *); 94 95/* stream ioctls */ 96static int i_nread(struct file *, struct thread *, register_t *, int, 97 u_long, caddr_t); 98static int i_fdinsert(struct file *, struct thread *, register_t *, int, 99 u_long, caddr_t); 100static int i_str(struct file *, struct thread *, register_t *, int, 101 u_long, caddr_t); 102static int i_setsig(struct file *, struct thread *, register_t *, int, 103 u_long, caddr_t); 104static int i_getsig(struct file *, struct thread *, register_t *, int, 105 u_long, caddr_t); 106static int _i_bind_rsvd(struct file *, struct thread *, register_t *, int, 107 u_long, caddr_t); 108static int _i_rele_rsvd(struct file *, struct thread *, register_t *, int, 109 u_long, caddr_t); 110 111/* i_str sockmod calls */ 112static int sockmod(struct file *, int, struct svr4_strioctl *, 113 struct thread *); 114static int si_listen(struct file *, int, struct svr4_strioctl *, 115 struct thread *); 116static int si_ogetudata(struct file *, int, struct svr4_strioctl *, 117 struct thread *); 118static int si_sockparams(struct file *, int, struct svr4_strioctl *, 119 struct thread *); 120static int si_shutdown (struct file *, int, struct svr4_strioctl *, 121 struct thread *); 122static int si_getudata(struct file *, int, struct svr4_strioctl *, 123 struct thread *); 124 125/* i_str timod calls */ 126static int timod(struct file *, int, struct svr4_strioctl *, struct thread *); 127static int ti_getinfo(struct file *, int, struct svr4_strioctl *, 128 struct thread *); 129static int ti_bind(struct file *, int, struct svr4_strioctl *, struct thread *); 130 131/* infrastructure */ 132static int svr4_sendit(struct thread *td, int s, struct msghdr *mp, int flags); 133 134static int svr4_recvit(struct thread *td, int s, struct msghdr *mp, 135 caddr_t namelenp); 136 137/* <sigh> Ok, so we shouldn't use sendit() in uipc_syscalls.c because 138 * it isn't part of a "public" interface; We're supposed to use 139 * pru_sosend instead. Same goes for recvit()/pru_soreceive() for 140 * that matter. Solution: Suck sendit()/recvit() into here where we 141 * can do what we like. 142 * 143 * I hate code duplication. 144 * 145 * I will take out all the #ifdef COMPAT_OLDSOCK gumph, though. 146 */ 147static int 148svr4_sendit(td, s, mp, flags) 149 register struct thread *td; 150 int s; 151 register struct msghdr *mp; 152 int flags; 153{ 154 struct uio auio; 155 register struct iovec *iov; 156 register int i; 157 struct mbuf *control; 158 struct sockaddr *to; 159 int len, error; 160 struct socket *so; 161#ifdef KTRACE 162 struct iovec *ktriov = NULL; 163 struct uio ktruio; 164#endif 165 166 if ((error = fgetsock(td, s, &so, NULL)) != 0) 167 return (error); 168 auio.uio_iov = mp->msg_iov; 169 auio.uio_iovcnt = mp->msg_iovlen; 170 auio.uio_segflg = UIO_USERSPACE; 171 auio.uio_rw = UIO_WRITE; 172 auio.uio_td = td; 173 auio.uio_offset = 0; /* XXX */ 174 auio.uio_resid = 0; 175 iov = mp->msg_iov; 176 for (i = 0; i < mp->msg_iovlen; i++, iov++) { 177 if ((auio.uio_resid += iov->iov_len) < 0) { 178 error = EINVAL; 179 goto done1; 180 } 181 } 182 if (mp->msg_name) { 183 error = getsockaddr(&to, mp->msg_name, mp->msg_namelen); 184 if (error) 185 goto done1; 186 } else { 187 to = 0; 188 } 189 if (mp->msg_control) { 190 if (mp->msg_controllen < sizeof(struct cmsghdr)) { 191 error = EINVAL; 192 goto bad; 193 } 194 error = sockargs(&control, mp->msg_control, 195 mp->msg_controllen, MT_CONTROL); 196 if (error) 197 goto bad; 198 } else { 199 control = 0; 200 } 201#ifdef KTRACE 202 if (KTRPOINT(td->td_proc, KTR_GENIO)) { 203 int iovlen = auio.uio_iovcnt * sizeof (struct iovec); 204 205 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 206 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 207 ktruio = auio; 208 } 209#endif 210 len = auio.uio_resid; 211 error = so->so_proto->pr_usrreqs->pru_sosend(so, to, &auio, 0, control, 212 flags, td); 213 if (error) { 214 if (auio.uio_resid != len && (error == ERESTART || 215 error == EINTR || error == EWOULDBLOCK)) 216 error = 0; 217 if (error == EPIPE) { 218 PROC_LOCK(td->td_proc); 219 psignal(td->td_proc, SIGPIPE); 220 PROC_UNLOCK(td->td_proc); 221 } 222 } 223 if (error == 0) 224 td->td_retval[0] = len - auio.uio_resid; 225#ifdef KTRACE 226 if (ktriov != NULL) { 227 if (error == 0) { 228 ktruio.uio_iov = ktriov; 229 ktruio.uio_resid = td->td_retval[0]; 230 ktrgenio(td->td_proc->p_tracep, s, UIO_WRITE, &ktruio, error); 231 } 232 FREE(ktriov, M_TEMP); 233 } 234#endif 235bad: 236 if (to) 237 FREE(to, M_SONAME); 238done1: 239 fputsock(so); 240 return (error); 241} 242 243static int 244svr4_recvit(td, s, mp, namelenp) 245 register struct thread *td; 246 int s; 247 register struct msghdr *mp; 248 caddr_t namelenp; 249{ 250 struct uio auio; 251 register struct iovec *iov; 252 register int i; 253 int len, error; 254 struct mbuf *m, *control = 0; 255 caddr_t ctlbuf; 256 struct socket *so; 257 struct sockaddr *fromsa = 0; 258#ifdef KTRACE 259 struct iovec *ktriov = NULL; 260 struct uio ktruio; 261#endif 262 263 if ((error = fgetsock(td, s, &so, NULL)) != 0) 264 return (error); 265 auio.uio_iov = mp->msg_iov; 266 auio.uio_iovcnt = mp->msg_iovlen; 267 auio.uio_segflg = UIO_USERSPACE; 268 auio.uio_rw = UIO_READ; 269 auio.uio_td = td; 270 auio.uio_offset = 0; /* XXX */ 271 auio.uio_resid = 0; 272 iov = mp->msg_iov; 273 for (i = 0; i < mp->msg_iovlen; i++, iov++) { 274 if ((auio.uio_resid += iov->iov_len) < 0) { 275 error = EINVAL; 276 goto done1; 277 } 278 } 279#ifdef KTRACE 280 if (KTRPOINT(td->td_proc, KTR_GENIO)) { 281 int iovlen = auio.uio_iovcnt * sizeof (struct iovec); 282 283 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 284 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 285 ktruio = auio; 286 } 287#endif 288 len = auio.uio_resid; 289 error = so->so_proto->pr_usrreqs->pru_soreceive(so, &fromsa, &auio, 290 (struct mbuf **)0, mp->msg_control ? &control : (struct mbuf **)0, 291 &mp->msg_flags); 292 if (error) { 293 if (auio.uio_resid != len && (error == ERESTART || 294 error == EINTR || error == EWOULDBLOCK)) 295 error = 0; 296 } 297#ifdef KTRACE 298 if (ktriov != NULL) { 299 if (error == 0) { 300 ktruio.uio_iov = ktriov; 301 ktruio.uio_resid = len - auio.uio_resid; 302 ktrgenio(td->td_proc->p_tracep, s, UIO_READ, &ktruio, error); 303 } 304 FREE(ktriov, M_TEMP); 305 } 306#endif 307 if (error) 308 goto out; 309 td->td_retval[0] = len - auio.uio_resid; 310 if (mp->msg_name) { 311 len = mp->msg_namelen; 312 if (len <= 0 || fromsa == 0) 313 len = 0; 314 else { 315#ifndef MIN 316#define MIN(a,b) ((a)>(b)?(b):(a)) 317#endif 318 /* save sa_len before it is destroyed by MSG_COMPAT */ 319 len = MIN(len, fromsa->sa_len); 320 error = copyout(fromsa, 321 (caddr_t)mp->msg_name, (unsigned)len); 322 if (error) 323 goto out; 324 } 325 mp->msg_namelen = len; 326 if (namelenp && 327 (error = copyout((caddr_t)&len, namelenp, sizeof (int)))) { 328 goto out; 329 } 330 } 331 if (mp->msg_control) { 332 len = mp->msg_controllen; 333 m = control; 334 mp->msg_controllen = 0; 335 ctlbuf = (caddr_t) mp->msg_control; 336 337 while (m && len > 0) { 338 unsigned int tocopy; 339 340 if (len >= m->m_len) 341 tocopy = m->m_len; 342 else { 343 mp->msg_flags |= MSG_CTRUNC; 344 tocopy = len; 345 } 346 347 if ((error = copyout((caddr_t)mtod(m, caddr_t), 348 ctlbuf, tocopy)) != 0) 349 goto out; 350 351 ctlbuf += tocopy; 352 len -= tocopy; 353 m = m->m_next; 354 } 355 mp->msg_controllen = ctlbuf - (caddr_t)mp->msg_control; 356 } 357out: 358 if (fromsa) 359 FREE(fromsa, M_SONAME); 360 if (control) 361 m_freem(control); 362done1: 363 fputsock(so); 364 return (error); 365} 366 367#ifdef DEBUG_SVR4 368static void bufprint(u_char *, size_t); 369static int show_ioc(const char *, struct svr4_strioctl *); 370static int show_strbuf(struct svr4_strbuf *); 371static void show_msg(const char *, int, struct svr4_strbuf *, 372 struct svr4_strbuf *, int); 373 374static void 375bufprint(buf, len) 376 u_char *buf; 377 size_t len; 378{ 379 size_t i; 380 381 uprintf("\n\t"); 382 for (i = 0; i < len; i++) { 383 uprintf("%x ", buf[i]); 384 if (i && (i % 16) == 0) 385 uprintf("\n\t"); 386 } 387} 388 389static int 390show_ioc(str, ioc) 391 const char *str; 392 struct svr4_strioctl *ioc; 393{ 394 u_char *ptr = (u_char *) malloc(ioc->len, M_TEMP, M_WAITOK); 395 int error; 396 397 uprintf("%s cmd = %ld, timeout = %d, len = %d, buf = %p { ", 398 str, ioc->cmd, ioc->timeout, ioc->len, ioc->buf); 399 400 if ((error = copyin(ioc->buf, ptr, ioc->len)) != 0) { 401 free((char *) ptr, M_TEMP); 402 return error; 403 } 404 405 bufprint(ptr, ioc->len); 406 407 uprintf("}\n"); 408 409 free((char *) ptr, M_TEMP); 410 return 0; 411} 412 413 414static int 415show_strbuf(str) 416 struct svr4_strbuf *str; 417{ 418 int error; 419 u_char *ptr = NULL; 420 int maxlen = str->maxlen; 421 int len = str->len; 422 423 if (maxlen < 0) 424 maxlen = 0; 425 426 if (len >= maxlen) 427 len = maxlen; 428 429 if (len > 0) { 430 ptr = (u_char *) malloc(len, M_TEMP, M_WAITOK); 431 432 if ((error = copyin(str->buf, ptr, len)) != 0) { 433 free((char *) ptr, M_TEMP); 434 return error; 435 } 436 } 437 438 uprintf(", { %d, %d, %p=[ ", str->maxlen, str->len, str->buf); 439 440 if (ptr) 441 bufprint(ptr, len); 442 443 uprintf("]}"); 444 445 if (ptr) 446 free((char *) ptr, M_TEMP); 447 448 return 0; 449} 450 451 452static void 453show_msg(str, fd, ctl, dat, flags) 454 const char *str; 455 int fd; 456 struct svr4_strbuf *ctl; 457 struct svr4_strbuf *dat; 458 int flags; 459{ 460 struct svr4_strbuf buf; 461 int error; 462 463 uprintf("%s(%d", str, fd); 464 if (ctl != NULL) { 465 if ((error = copyin(ctl, &buf, sizeof(buf))) != 0) 466 return; 467 show_strbuf(&buf); 468 } 469 else 470 uprintf(", NULL"); 471 472 if (dat != NULL) { 473 if ((error = copyin(dat, &buf, sizeof(buf))) != 0) 474 return; 475 show_strbuf(&buf); 476 } 477 else 478 uprintf(", NULL"); 479 480 uprintf(", %x);\n", flags); 481} 482 483#endif /* DEBUG_SVR4 */ 484 485/* 486 * We are faced with an interesting situation. On svr4 unix sockets 487 * are really pipes. But we really have sockets, and we might as 488 * well use them. At the point where svr4 calls TI_BIND, it has 489 * already created a named pipe for the socket using mknod(2). 490 * We need to create a socket with the same name when we bind, 491 * so we need to remove the pipe before, otherwise we'll get address 492 * already in use. So we *carefully* remove the pipe, to avoid 493 * using this as a random file removal tool. We use system calls 494 * to avoid code duplication. 495 */ 496static int 497clean_pipe(td, path) 498 struct thread *td; 499 const char *path; 500{ 501 struct lstat_args la; 502 struct unlink_args ua; 503 struct stat st; 504 int error; 505 caddr_t sg = stackgap_init(); 506 size_t l = strlen(path) + 1; 507 void *tpath; 508 509 tpath = stackgap_alloc(&sg, l); 510 SCARG(&la, ub) = stackgap_alloc(&sg, sizeof(struct stat)); 511 512 if ((error = copyout(path, tpath, l)) != 0) 513 return error; 514 515 SCARG(&la, path) = tpath; 516 517 if ((error = lstat(td, &la)) != 0) 518 return 0; 519 520 if ((error = copyin(SCARG(&la, ub), &st, sizeof(st))) != 0) 521 return 0; 522 523 /* 524 * Make sure we are dealing with a mode 0 named pipe. 525 */ 526 if ((st.st_mode & S_IFMT) != S_IFIFO) 527 return 0; 528 529 if ((st.st_mode & ALLPERMS) != 0) 530 return 0; 531 532 SCARG(&ua, path) = SCARG(&la, path); 533 534 if ((error = unlink(td, &ua)) != 0) { 535 DPRINTF(("clean_pipe: unlink failed %d\n", error)); 536 return error; 537 } 538 539 return 0; 540} 541 542 543static void 544sockaddr_to_netaddr_in(sc, sain) 545 struct svr4_strmcmd *sc; 546 const struct sockaddr_in *sain; 547{ 548 struct svr4_netaddr_in *na; 549 na = SVR4_ADDROF(sc); 550 551 na->family = sain->sin_family; 552 na->port = sain->sin_port; 553 na->addr = sain->sin_addr.s_addr; 554 DPRINTF(("sockaddr_in -> netaddr %d %d %lx\n", na->family, na->port, 555 na->addr)); 556} 557 558 559static void 560sockaddr_to_netaddr_un(sc, saun) 561 struct svr4_strmcmd *sc; 562 const struct sockaddr_un *saun; 563{ 564 struct svr4_netaddr_un *na; 565 char *dst, *edst = ((char *) sc) + sc->offs + sizeof(na->family) + 1 - 566 sizeof(*sc); 567 const char *src; 568 569 na = SVR4_ADDROF(sc); 570 na->family = saun->sun_family; 571 for (src = saun->sun_path, dst = na->path; (*dst++ = *src++) != '\0'; ) 572 if (dst == edst) 573 break; 574 DPRINTF(("sockaddr_un -> netaddr %d %s\n", na->family, na->path)); 575} 576 577 578static void 579netaddr_to_sockaddr_in(sain, sc) 580 struct sockaddr_in *sain; 581 const struct svr4_strmcmd *sc; 582{ 583 const struct svr4_netaddr_in *na; 584 585 586 na = SVR4_C_ADDROF(sc); 587 memset(sain, 0, sizeof(*sain)); 588 sain->sin_len = sizeof(*sain); 589 sain->sin_family = na->family; 590 sain->sin_port = na->port; 591 sain->sin_addr.s_addr = na->addr; 592 DPRINTF(("netaddr -> sockaddr_in %d %d %x\n", sain->sin_family, 593 sain->sin_port, sain->sin_addr.s_addr)); 594} 595 596 597static void 598netaddr_to_sockaddr_un(saun, sc) 599 struct sockaddr_un *saun; 600 const struct svr4_strmcmd *sc; 601{ 602 const struct svr4_netaddr_un *na; 603 char *dst, *edst = &saun->sun_path[sizeof(saun->sun_path) - 1]; 604 const char *src; 605 606 na = SVR4_C_ADDROF(sc); 607 memset(saun, 0, sizeof(*saun)); 608 saun->sun_family = na->family; 609 for (src = na->path, dst = saun->sun_path; (*dst++ = *src++) != '\0'; ) 610 if (dst == edst) 611 break; 612 saun->sun_len = dst - saun->sun_path; 613 DPRINTF(("netaddr -> sockaddr_un %d %s\n", saun->sun_family, 614 saun->sun_path)); 615} 616 617 618static void 619getparm(fp, pa) 620 struct file *fp; 621 struct svr4_si_sockparms *pa; 622{ 623 struct svr4_strm *st; 624 struct socket *so; 625 626 st = svr4_stream_get(fp); 627 if (st == NULL) 628 return; 629 630 so = (struct socket *) fp->f_data; 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, td) 664 struct file *fp; 665 int fd; 666 struct svr4_strioctl *ioc; 667 struct thread *td; 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, td) 721 struct file *fp; 722 int fd; 723 struct svr4_strioctl *ioc; 724 struct thread *td; 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, td) 735 struct file *fp; 736 int fd; 737 struct svr4_strioctl *ioc; 738 struct thread *td; 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(td, &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, td) 799 struct file *fp; 800 int fd; 801 struct svr4_strioctl *ioc; 802 struct thread *td; 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, td) 858 struct file *fp; 859 int fd; 860 struct svr4_strioctl *ioc; 861 struct thread *td; 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(td, &ap); 878} 879 880 881static int 882sockmod(fp, fd, ioc, td) 883 struct file *fp; 884 int fd; 885 struct svr4_strioctl *ioc; 886 struct thread *td; 887{ 888 switch (ioc->cmd) { 889 case SVR4_SI_OGETUDATA: 890 DPRINTF(("SI_OGETUDATA\n")); 891 return si_ogetudata(fp, fd, ioc, td); 892 893 case SVR4_SI_SHUTDOWN: 894 DPRINTF(("SI_SHUTDOWN\n")); 895 return si_shutdown(fp, fd, ioc, td); 896 897 case SVR4_SI_LISTEN: 898 DPRINTF(("SI_LISTEN\n")); 899 return si_listen(fp, fd, ioc, td); 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, td); 924 925 case SVR4_SI_GETUDATA: 926 DPRINTF(("SI_GETUDATA\n")); 927 return si_getudata(fp, fd, ioc, td); 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, td) 939 struct file *fp; 940 int fd; 941 struct svr4_strioctl *ioc; 942 struct thread *td; 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, td) 977 struct file *fp; 978 int fd; 979 struct svr4_strioctl *ioc; 980 struct thread *td; 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(td, 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(td, &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, td) 1080 struct file *fp; 1081 int fd; 1082 struct svr4_strioctl *ioc; 1083 struct thread *td; 1084{ 1085 switch (ioc->cmd) { 1086 case SVR4_TI_GETINFO: 1087 DPRINTF(("TI_GETINFO\n")); 1088 return ti_getinfo(fp, fd, ioc, td); 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, td); 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, td, retval, fd, cmd, dat) 1111 struct file *fp; 1112 struct thread *td; 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(td, &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(td, &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, td, retval, fd, cmd, dat) 1253 struct file *fp; 1254 struct thread *td; 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, td)) != 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, td, retval, fd, cmd, dat) 1283 struct file *fp; 1284 struct thread *td; 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(td, &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(td, &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, td, retval, fd, cmd, dat) 1345 struct file *fp; 1346 struct thread *td; 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(td, &ap); 1365} 1366 1367static int 1368_i_rele_rsvd(fp, td, retval, fd, cmd, dat) 1369 struct file *fp; 1370 struct thread *td; 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(td, &ap); 1385} 1386 1387static int 1388i_str(fp, td, retval, fd, cmd, dat) 1389 struct file *fp; 1390 struct thread *td; 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, td)) != 0) 1410 return error; 1411 break; 1412 1413 case SVR4_TIMOD: 1414 if ((error = timod(fp, fd, &ioc, td)) != 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, td, retval, fd, cmd, dat) 1433 struct file *fp; 1434 struct thread *td; 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(td, &fa)) != 0) 1461 return error; 1462 1463 oflags = td->td_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(td, &fa)) != 0) 1490 return error; 1491 flags = td->td_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) td->td_proc->p_pid; 1498 return fcntl(td, &fa); 1499 } 1500 return 0; 1501} 1502 1503static int 1504i_getsig(fp, td, retval, fd, cmd, dat) 1505 struct file *fp; 1506 struct thread *td; 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, td, retval, fd, cmd, dat) 1532 struct file *fp; 1533 struct thread *td; 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, td, retval, fd, cmd, dat); 1548 1549 case SVR4_I_PUSH: 1550 DPRINTF(("I_PUSH %p\n", dat)); 1551#if defined(DEBUG_SVR4) 1552 show_strbuf((struct svr4_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, td, retval, fd, cmd, dat); 1579 1580 case SVR4_I_SETSIG: 1581 DPRINTF(("I_SETSIG\n")); 1582 return i_setsig(fp, td, retval, fd, cmd, dat); 1583 1584 case SVR4_I_GETSIG: 1585 DPRINTF(("I_GETSIG\n")); 1586 return i_getsig(fp, td, 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, td, 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, td, retval, fd, cmd, dat); 1692 1693 case SVR4__I_RELE_RSVD: 1694 DPRINTF(("_I_RELE_RSVD\n")); 1695 return _i_rele_rsvd(fp, td, 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(td, uap) 1709 register struct thread *td; 1710 struct svr4_sys_putmsg_args *uap; 1711{ 1712 struct file *fp; 1713 int error; 1714 1715 if ((error = fget(td, uap->fd, &fp)) != 0) { 1716#ifdef DEBUG_SVR4 1717 uprintf("putmsg: bad fp\n"); 1718#endif 1719 return EBADF; 1720 } 1721 error = svr4_do_putmsg(td, uap, fp); 1722 fdrop(fp, td); 1723 return (error); 1724} 1725 1726static int 1727svr4_do_putmsg(td, uap, fp) 1728 struct thread *td; 1729 struct svr4_sys_putmsg_args *uap; 1730 struct file *fp; 1731{ 1732 struct svr4_strbuf dat, ctl; 1733 struct svr4_strmcmd sc; 1734 struct sockaddr_in sain; 1735 struct sockaddr_un saun; 1736 void *skp, *sup; 1737 int sasize, *retval; 1738 struct svr4_strm *st; 1739 int error; 1740 caddr_t sg; 1741 1742 retval = td->td_retval; 1743 1744#ifdef DEBUG_SVR4 1745 show_msg(">putmsg", SCARG(uap, fd), SCARG(uap, ctl), 1746 SCARG(uap, dat), SCARG(uap, flags)); 1747#endif /* DEBUG_SVR4 */ 1748 1749 FILE_LOCK_ASSERT(fp, MA_NOTOWNED); 1750 1751 if (SCARG(uap, ctl) != NULL) { 1752 if ((error = copyin(SCARG(uap, ctl), &ctl, sizeof(ctl))) != 0) { 1753#ifdef DEBUG_SVR4 1754 uprintf("putmsg: copyin(): %d\n", error); 1755#endif 1756 return error; 1757 } 1758 } 1759 else 1760 ctl.len = -1; 1761 1762 if (SCARG(uap, dat) != NULL) { 1763 if ((error = copyin(SCARG(uap, dat), &dat, sizeof(dat))) != 0) { 1764#ifdef DEBUG_SVR4 1765 uprintf("putmsg: copyin(): %d (2)\n", error); 1766#endif 1767 return error; 1768 } 1769 } 1770 else 1771 dat.len = -1; 1772 1773 /* 1774 * Only for sockets for now. 1775 */ 1776 if ((st = svr4_stream_get(fp)) == NULL) { 1777 DPRINTF(("putmsg: bad file type\n")); 1778 return EINVAL; 1779 } 1780 1781 if (ctl.len > sizeof(sc)) { 1782 DPRINTF(("putmsg: Bad control size %d != %d\n", ctl.len, 1783 sizeof(struct svr4_strmcmd))); 1784 return EINVAL; 1785 } 1786 1787 if ((error = copyin(ctl.buf, &sc, ctl.len)) != 0) 1788 return error; 1789 1790 switch (st->s_family) { 1791 case AF_INET: 1792 if (sc.len != sizeof(sain)) { 1793 if (sc.cmd == SVR4_TI_DATA_REQUEST) { 1794 struct write_args wa; 1795 1796 /* Solaris seems to use sc.cmd = 3 to 1797 * send "expedited" data. telnet uses 1798 * this for options processing, sending EOF, 1799 * etc. I'm sure other things use it too. 1800 * I don't have any documentation 1801 * on it, so I'm making a guess that this 1802 * is how it works. newton@atdot.dotat.org XXX 1803 */ 1804 DPRINTF(("sending expedited data ??\n")); 1805 SCARG(&wa, fd) = SCARG(uap, fd); 1806 SCARG(&wa, buf) = dat.buf; 1807 SCARG(&wa, nbyte) = dat.len; 1808 return write(td, &wa); 1809 } 1810 DPRINTF(("putmsg: Invalid inet length %ld\n", sc.len)); 1811 return EINVAL; 1812 } 1813 netaddr_to_sockaddr_in(&sain, &sc); 1814 skp = &sain; 1815 sasize = sizeof(sain); 1816 error = sain.sin_family != st->s_family; 1817 break; 1818 1819 case AF_LOCAL: 1820 if (ctl.len == 8) { 1821 /* We are doing an accept; succeed */ 1822 DPRINTF(("putmsg: Do nothing\n")); 1823 *retval = 0; 1824 return 0; 1825 } 1826 else { 1827 /* Maybe we've been given a device/inode pair */ 1828 udev_t *dev = SVR4_ADDROF(&sc); 1829 ino_t *ino = (ino_t *) &dev[1]; 1830 skp = svr4_find_socket(td, fp, *dev, *ino); 1831 if (skp == NULL) { 1832 skp = &saun; 1833 /* I guess we have it by name */ 1834 netaddr_to_sockaddr_un(skp, &sc); 1835 } 1836 sasize = sizeof(saun); 1837 } 1838 break; 1839 1840 default: 1841 DPRINTF(("putmsg: Unsupported address family %d\n", 1842 st->s_family)); 1843 return ENOSYS; 1844 } 1845 1846 sg = stackgap_init(); 1847 sup = stackgap_alloc(&sg, sasize); 1848 1849 if ((error = copyout(skp, sup, sasize)) != 0) 1850 return error; 1851 1852 switch (st->s_cmd = sc.cmd) { 1853 case SVR4_TI_CONNECT_REQUEST: /* connect */ 1854 { 1855 struct connect_args co; 1856 1857 SCARG(&co, s) = SCARG(uap, fd); 1858 SCARG(&co, name) = (void *) sup; 1859 SCARG(&co, namelen) = (int) sasize; 1860 1861 return connect(td, &co); 1862 } 1863 1864 case SVR4_TI_SENDTO_REQUEST: /* sendto */ 1865 { 1866 struct msghdr msg; 1867 struct iovec aiov; 1868 1869 msg.msg_name = (caddr_t) sup; 1870 msg.msg_namelen = sasize; 1871 msg.msg_iov = &aiov; 1872 msg.msg_iovlen = 1; 1873 msg.msg_control = 0; 1874 msg.msg_flags = 0; 1875 aiov.iov_base = dat.buf; 1876 aiov.iov_len = dat.len; 1877#if 0 1878 error = so->so_proto->pr_usrreqs->pru_sosend(so, 0, 1879 uio, 0, 0, 0, uio->uio_td); 1880#endif 1881 error = svr4_sendit(td, SCARG(uap, fd), &msg, 1882 SCARG(uap, flags)); 1883 DPRINTF(("sendto_request error: %d\n", error)); 1884 *retval = 0; 1885 return error; 1886 } 1887 1888 default: 1889 DPRINTF(("putmsg: Unimplemented command %lx\n", sc.cmd)); 1890 return ENOSYS; 1891 } 1892} 1893 1894int 1895svr4_sys_getmsg(td, uap) 1896 struct thread *td; 1897 struct svr4_sys_getmsg_args *uap; 1898{ 1899 struct file *fp; 1900 int error; 1901 1902 if ((error = fget(td, uap->fd, &fp)) != 0) { 1903#ifdef DEBUG_SVR4 1904 uprintf("getmsg: bad fp\n"); 1905#endif 1906 return EBADF; 1907 } 1908 error = svr4_do_getmsg(td, uap, fp); 1909 fdrop(fp, td); 1910 return (error); 1911} 1912 1913int 1914svr4_do_getmsg(td, uap, fp) 1915 register struct thread *td; 1916 struct svr4_sys_getmsg_args *uap; 1917 struct file *fp; 1918{ 1919 struct getpeername_args ga; 1920 struct accept_args aa; 1921 struct svr4_strbuf dat, ctl; 1922 struct svr4_strmcmd sc; 1923 int error, *retval; 1924 struct msghdr msg; 1925 struct iovec aiov; 1926 struct sockaddr_in sain; 1927 struct sockaddr_un saun; 1928 void *skp, *sup; 1929 int sasize; 1930 struct svr4_strm *st; 1931 int *flen; 1932 int fl; 1933 caddr_t sg; 1934 1935 retval = td->td_retval; 1936 1937 FILE_LOCK_ASSERT(fp, MA_NOTOWNED); 1938 1939 memset(&sc, 0, sizeof(sc)); 1940 1941#ifdef DEBUG_SVR4 1942 show_msg(">getmsg", SCARG(uap, fd), SCARG(uap, ctl), 1943 SCARG(uap, dat), 0); 1944#endif /* DEBUG_SVR4 */ 1945 1946 if (SCARG(uap, ctl) != NULL) { 1947 if ((error = copyin(SCARG(uap, ctl), &ctl, sizeof(ctl))) != 0) 1948 return error; 1949 } 1950 else { 1951 ctl.len = -1; 1952 ctl.maxlen = 0; 1953 } 1954 1955 if (SCARG(uap, dat) != NULL) { 1956 if ((error = copyin(SCARG(uap, dat), &dat, sizeof(dat))) != 0) 1957 return error; 1958 } 1959 else { 1960 dat.len = -1; 1961 dat.maxlen = 0; 1962 } 1963 1964 /* 1965 * Only for sockets for now. 1966 */ 1967 if ((st = svr4_stream_get(fp)) == NULL) { 1968 DPRINTF(("getmsg: bad file type\n")); 1969 return EINVAL; 1970 } 1971 1972 if (ctl.maxlen == -1 || dat.maxlen == -1) { 1973 DPRINTF(("getmsg: Cannot handle -1 maxlen (yet)\n")); 1974 return ENOSYS; 1975 } 1976 1977 switch (st->s_family) { 1978 case AF_INET: 1979 skp = &sain; 1980 sasize = sizeof(sain); 1981 break; 1982 1983 case AF_LOCAL: 1984 skp = &saun; 1985 sasize = sizeof(saun); 1986 break; 1987 1988 default: 1989 DPRINTF(("getmsg: Unsupported address family %d\n", 1990 st->s_family)); 1991 return ENOSYS; 1992 } 1993 1994 sg = stackgap_init(); 1995 sup = stackgap_alloc(&sg, sasize); 1996 flen = (int *) stackgap_alloc(&sg, sizeof(*flen)); 1997 1998 fl = sasize; 1999 if ((error = copyout(&fl, flen, sizeof(fl))) != 0) 2000 return error; 2001 2002 switch (st->s_cmd) { 2003 case SVR4_TI_CONNECT_REQUEST: 2004 DPRINTF(("getmsg: TI_CONNECT_REQUEST\n")); 2005 /* 2006 * We do the connect in one step, so the putmsg should 2007 * have gotten the error. 2008 */ 2009 sc.cmd = SVR4_TI_OK_REPLY; 2010 sc.len = 0; 2011 2012 ctl.len = 8; 2013 dat.len = -1; 2014 fl = 1; 2015 st->s_cmd = sc.cmd; 2016 break; 2017 2018 case SVR4_TI_OK_REPLY: 2019 DPRINTF(("getmsg: TI_OK_REPLY\n")); 2020 /* 2021 * We are immediately after a connect reply, so we send 2022 * a connect verification. 2023 */ 2024 2025 SCARG(&ga, fdes) = SCARG(uap, fd); 2026 SCARG(&ga, asa) = (void *) sup; 2027 SCARG(&ga, alen) = flen; 2028 2029 if ((error = getpeername(td, &ga)) != 0) { 2030 DPRINTF(("getmsg: getpeername failed %d\n", error)); 2031 return error; 2032 } 2033 2034 if ((error = copyin(sup, skp, sasize)) != 0) 2035 return error; 2036 2037 sc.cmd = SVR4_TI_CONNECT_REPLY; 2038 sc.pad[0] = 0x4; 2039 sc.offs = 0x18; 2040 sc.pad[1] = 0x14; 2041 sc.pad[2] = 0x04000402; 2042 2043 switch (st->s_family) { 2044 case AF_INET: 2045 sc.len = sasize; 2046 sockaddr_to_netaddr_in(&sc, &sain); 2047 break; 2048 2049 case AF_LOCAL: 2050 sc.len = sasize + 4; 2051 sockaddr_to_netaddr_un(&sc, &saun); 2052 break; 2053 2054 default: 2055 return ENOSYS; 2056 } 2057 2058 ctl.len = 40; 2059 dat.len = -1; 2060 fl = 0; 2061 st->s_cmd = sc.cmd; 2062 break; 2063 2064 case SVR4_TI__ACCEPT_OK: 2065 DPRINTF(("getmsg: TI__ACCEPT_OK\n")); 2066 /* 2067 * We do the connect in one step, so the putmsg should 2068 * have gotten the error. 2069 */ 2070 sc.cmd = SVR4_TI_OK_REPLY; 2071 sc.len = 1; 2072 2073 ctl.len = 8; 2074 dat.len = -1; 2075 fl = 1; 2076 st->s_cmd = SVR4_TI__ACCEPT_WAIT; 2077 break; 2078 2079 case SVR4_TI__ACCEPT_WAIT: 2080 DPRINTF(("getmsg: TI__ACCEPT_WAIT\n")); 2081 /* 2082 * We are after a listen, so we try to accept... 2083 */ 2084 SCARG(&aa, s) = SCARG(uap, fd); 2085 SCARG(&aa, name) = (void *) sup; 2086 SCARG(&aa, anamelen) = flen; 2087 2088 if ((error = accept(td, &aa)) != 0) { 2089 DPRINTF(("getmsg: accept failed %d\n", error)); 2090 return error; 2091 } 2092 2093 st->s_afd = *retval; 2094 2095 DPRINTF(("getmsg: Accept fd = %d\n", st->s_afd)); 2096 2097 if ((error = copyin(sup, skp, sasize)) != 0) 2098 return error; 2099 2100 sc.cmd = SVR4_TI_ACCEPT_REPLY; 2101 sc.offs = 0x18; 2102 sc.pad[0] = 0x0; 2103 2104 switch (st->s_family) { 2105 case AF_INET: 2106 sc.pad[1] = 0x28; 2107 sockaddr_to_netaddr_in(&sc, &sain); 2108 ctl.len = 40; 2109 sc.len = sasize; 2110 break; 2111 2112 case AF_LOCAL: 2113 sc.pad[1] = 0x00010000; 2114 sc.pad[2] = 0xf6bcdaa0; /* I don't know what that is */ 2115 sc.pad[3] = 0x00010000; 2116 ctl.len = 134; 2117 sc.len = sasize + 4; 2118 break; 2119 2120 default: 2121 return ENOSYS; 2122 } 2123 2124 dat.len = -1; 2125 fl = 0; 2126 st->s_cmd = SVR4_TI__ACCEPT_OK; 2127 break; 2128 2129 case SVR4_TI_SENDTO_REQUEST: 2130 DPRINTF(("getmsg: TI_SENDTO_REQUEST\n")); 2131 if (ctl.maxlen > 36 && ctl.len < 36) 2132 ctl.len = 36; 2133 2134 if ((error = copyin(ctl.buf, &sc, ctl.len)) != 0) 2135 return error; 2136 2137 switch (st->s_family) { 2138 case AF_INET: 2139 sockaddr_to_netaddr_in(&sc, &sain); 2140 break; 2141 2142 case AF_LOCAL: 2143 sockaddr_to_netaddr_un(&sc, &saun); 2144 break; 2145 2146 default: 2147 return ENOSYS; 2148 } 2149 2150 msg.msg_name = (caddr_t) sup; 2151 msg.msg_namelen = sasize; 2152 msg.msg_iov = &aiov; 2153 msg.msg_iovlen = 1; 2154 msg.msg_control = 0; 2155 aiov.iov_base = dat.buf; 2156 aiov.iov_len = dat.maxlen; 2157 msg.msg_flags = 0; 2158 2159 error = svr4_recvit(td, SCARG(uap, fd), &msg, (caddr_t) flen); 2160 2161 if (error) { 2162 DPRINTF(("getmsg: recvit failed %d\n", error)); 2163 return error; 2164 } 2165 2166 if ((error = copyin(msg.msg_name, skp, sasize)) != 0) 2167 return error; 2168 2169 sc.cmd = SVR4_TI_RECVFROM_IND; 2170 2171 switch (st->s_family) { 2172 case AF_INET: 2173 sc.len = sasize; 2174 sockaddr_to_netaddr_in(&sc, &sain); 2175 break; 2176 2177 case AF_LOCAL: 2178 sc.len = sasize + 4; 2179 sockaddr_to_netaddr_un(&sc, &saun); 2180 break; 2181 2182 default: 2183 return ENOSYS; 2184 } 2185 2186 dat.len = *retval; 2187 fl = 0; 2188 st->s_cmd = sc.cmd; 2189 break; 2190 2191 default: 2192 st->s_cmd = sc.cmd; 2193 if (st->s_cmd == SVR4_TI_CONNECT_REQUEST) { 2194 struct read_args ra; 2195 2196 /* More weirdness: Again, I can't find documentation 2197 * to back this up, but when a process does a generic 2198 * "getmsg()" call it seems that the command field is 2199 * zero and the length of the data area is zero. I 2200 * think processes expect getmsg() to fill in dat.len 2201 * after reading at most dat.maxlen octets from the 2202 * stream. Since we're using sockets I can let 2203 * read() look after it and frob return values 2204 * appropriately (or inappropriately :-) 2205 * -- newton@atdot.dotat.org XXX 2206 */ 2207 SCARG(&ra, fd) = SCARG(uap, fd); 2208 SCARG(&ra, buf) = dat.buf; 2209 SCARG(&ra, nbyte) = dat.maxlen; 2210 if ((error = read(td, &ra)) != 0) { 2211 return error; 2212 } 2213 dat.len = *retval; 2214 *retval = 0; 2215 st->s_cmd = SVR4_TI_SENDTO_REQUEST; 2216 break; 2217 } 2218 DPRINTF(("getmsg: Unknown state %x\n", st->s_cmd)); 2219 return EINVAL; 2220 } 2221 2222 if (SCARG(uap, ctl)) { 2223 if (ctl.len != -1) 2224 if ((error = copyout(&sc, ctl.buf, ctl.len)) != 0) 2225 return error; 2226 2227 if ((error = copyout(&ctl, SCARG(uap, ctl), sizeof(ctl))) != 0) 2228 return error; 2229 } 2230 2231 if (SCARG(uap, dat)) { 2232 if ((error = copyout(&dat, SCARG(uap, dat), sizeof(dat))) != 0) 2233 return error; 2234 } 2235 2236 if (SCARG(uap, flags)) { /* XXX: Need translation */ 2237 if ((error = copyout(&fl, SCARG(uap, flags), sizeof(fl))) != 0) 2238 return error; 2239 } 2240 2241 *retval = 0; 2242 2243#ifdef DEBUG_SVR4 2244 show_msg("<getmsg", SCARG(uap, fd), SCARG(uap, ctl), 2245 SCARG(uap, dat), fl); 2246#endif /* DEBUG_SVR4 */ 2247 return error; 2248} 2249 2250int svr4_sys_send(td, uap) 2251 struct thread *td; 2252 struct svr4_sys_send_args *uap; 2253{ 2254 struct osend_args osa; 2255 SCARG(&osa, s) = SCARG(uap, s); 2256 SCARG(&osa, buf) = SCARG(uap, buf); 2257 SCARG(&osa, len) = SCARG(uap, len); 2258 SCARG(&osa, flags) = SCARG(uap, flags); 2259 return osend(td, &osa); 2260} 2261 2262int svr4_sys_recv(td, uap) 2263 struct thread *td; 2264 struct svr4_sys_recv_args *uap; 2265{ 2266 struct orecv_args ora; 2267 SCARG(&ora, s) = SCARG(uap, s); 2268 SCARG(&ora, buf) = SCARG(uap, buf); 2269 SCARG(&ora, len) = SCARG(uap, len); 2270 SCARG(&ora, flags) = SCARG(uap, flags); 2271 return orecv(td, &ora); 2272} 2273 2274/* 2275 * XXX This isn't necessary, but it's handy for inserting debug code into 2276 * sendto(). Let's leave it here for now... 2277 */ 2278int 2279svr4_sys_sendto(td, uap) 2280 struct thread *td; 2281 struct svr4_sys_sendto_args *uap; 2282{ 2283 struct sendto_args sa; 2284 2285 SCARG(&sa, s) = SCARG(uap, s); 2286 SCARG(&sa, buf) = SCARG(uap, buf); 2287 SCARG(&sa, len) = SCARG(uap, len); 2288 SCARG(&sa, flags) = SCARG(uap, flags); 2289 SCARG(&sa, to) = (caddr_t)SCARG(uap, to); 2290 SCARG(&sa, tolen) = SCARG(uap, tolen); 2291 2292 DPRINTF(("calling sendto()\n")); 2293 return sendto(td, &sa); 2294} 2295 2296