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