svr4_stream.c revision 225617
1/*- 2 * Copyright (c) 1998 Mark Newton. All rights reserved. 3 * Copyright (c) 1994, 1996 Christos Zoulas. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Christos Zoulas. 16 * 4. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31/* 32 * Pretend that we have streams... 33 * Yes, this is gross. 34 * 35 * ToDo: The state machine for getmsg needs re-thinking 36 */ 37 38#include <sys/cdefs.h> 39__FBSDID("$FreeBSD: head/sys/compat/svr4/svr4_stream.c 225617 2011-09-16 13:58:51Z kmacy $"); 40 41#include "opt_compat.h" 42#include "opt_ktrace.h" 43 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/capability.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/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/syscallsubr.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 *, 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#ifdef DEBUG_SVR4 136static void bufprint(u_char *, size_t); 137static int show_ioc(const char *, struct svr4_strioctl *); 138static int show_strbuf(struct svr4_strbuf *); 139static void show_msg(const char *, int, struct svr4_strbuf *, 140 struct svr4_strbuf *, int); 141 142static void 143bufprint(buf, len) 144 u_char *buf; 145 size_t len; 146{ 147 size_t i; 148 149 uprintf("\n\t"); 150 for (i = 0; i < len; i++) { 151 uprintf("%x ", buf[i]); 152 if (i && (i % 16) == 0) 153 uprintf("\n\t"); 154 } 155} 156 157static int 158show_ioc(str, ioc) 159 const char *str; 160 struct svr4_strioctl *ioc; 161{ 162 u_char *ptr = NULL; 163 int len; 164 int error; 165 166 len = ioc->len; 167 if (len > 1024) 168 len = 1024; 169 170 if (len > 0) { 171 ptr = (u_char *) malloc(len, M_TEMP, M_WAITOK); 172 if ((error = copyin(ioc->buf, ptr, len)) != 0) { 173 free((char *) ptr, M_TEMP); 174 return error; 175 } 176 } 177 178 uprintf("%s cmd = %ld, timeout = %d, len = %d, buf = %p { ", 179 str, ioc->cmd, ioc->timeout, ioc->len, ioc->buf); 180 181 if (ptr != NULL) 182 bufprint(ptr, len); 183 184 uprintf("}\n"); 185 186 if (ptr != NULL) 187 free((char *) ptr, M_TEMP); 188 return 0; 189} 190 191 192static int 193show_strbuf(str) 194 struct svr4_strbuf *str; 195{ 196 int error; 197 u_char *ptr = NULL; 198 int maxlen = str->maxlen; 199 int len = str->len; 200 201 if (maxlen > 8192) 202 maxlen = 8192; 203 204 if (maxlen < 0) 205 maxlen = 0; 206 207 if (len >= maxlen) 208 len = maxlen; 209 210 if (len > 0) { 211 ptr = (u_char *) malloc(len, M_TEMP, M_WAITOK); 212 213 if ((error = copyin(str->buf, ptr, len)) != 0) { 214 free((char *) ptr, M_TEMP); 215 return error; 216 } 217 } 218 219 uprintf(", { %d, %d, %p=[ ", str->maxlen, str->len, str->buf); 220 221 if (ptr) 222 bufprint(ptr, len); 223 224 uprintf("]}"); 225 226 if (ptr) 227 free((char *) ptr, M_TEMP); 228 229 return 0; 230} 231 232 233static void 234show_msg(str, fd, ctl, dat, flags) 235 const char *str; 236 int fd; 237 struct svr4_strbuf *ctl; 238 struct svr4_strbuf *dat; 239 int flags; 240{ 241 struct svr4_strbuf buf; 242 int error; 243 244 uprintf("%s(%d", str, fd); 245 if (ctl != NULL) { 246 if ((error = copyin(ctl, &buf, sizeof(buf))) != 0) 247 return; 248 show_strbuf(&buf); 249 } 250 else 251 uprintf(", NULL"); 252 253 if (dat != NULL) { 254 if ((error = copyin(dat, &buf, sizeof(buf))) != 0) 255 return; 256 show_strbuf(&buf); 257 } 258 else 259 uprintf(", NULL"); 260 261 uprintf(", %x);\n", flags); 262} 263 264#endif /* DEBUG_SVR4 */ 265 266/* 267 * We are faced with an interesting situation. On svr4 unix sockets 268 * are really pipes. But we really have sockets, and we might as 269 * well use them. At the point where svr4 calls TI_BIND, it has 270 * already created a named pipe for the socket using mknod(2). 271 * We need to create a socket with the same name when we bind, 272 * so we need to remove the pipe before, otherwise we'll get address 273 * already in use. So we *carefully* remove the pipe, to avoid 274 * using this as a random file removal tool. We use system calls 275 * to avoid code duplication. 276 */ 277static int 278clean_pipe(td, path) 279 struct thread *td; 280 char *path; 281{ 282 struct stat st; 283 int error; 284 285 error = kern_lstat(td, path, UIO_SYSSPACE, &st); 286 287 /* 288 * Make sure we are dealing with a mode 0 named pipe. 289 */ 290 if ((st.st_mode & S_IFMT) != S_IFIFO) 291 return (0); 292 293 if ((st.st_mode & ALLPERMS) != 0) 294 return (0); 295 296 error = kern_unlink(td, path, UIO_SYSSPACE); 297 if (error) 298 DPRINTF(("clean_pipe: unlink failed %d\n", error)); 299 return (error); 300} 301 302 303static void 304sockaddr_to_netaddr_in(sc, sain) 305 struct svr4_strmcmd *sc; 306 const struct sockaddr_in *sain; 307{ 308 struct svr4_netaddr_in *na; 309 na = SVR4_ADDROF(sc); 310 311 na->family = sain->sin_family; 312 na->port = sain->sin_port; 313 na->addr = sain->sin_addr.s_addr; 314 DPRINTF(("sockaddr_in -> netaddr %d %d %lx\n", na->family, na->port, 315 na->addr)); 316} 317 318 319static void 320sockaddr_to_netaddr_un(sc, saun) 321 struct svr4_strmcmd *sc; 322 const struct sockaddr_un *saun; 323{ 324 struct svr4_netaddr_un *na; 325 char *dst, *edst = ((char *) sc) + sc->offs + sizeof(na->family) + 1 - 326 sizeof(*sc); 327 const char *src; 328 329 na = SVR4_ADDROF(sc); 330 na->family = saun->sun_family; 331 for (src = saun->sun_path, dst = na->path; (*dst++ = *src++) != '\0'; ) 332 if (dst == edst) 333 break; 334 DPRINTF(("sockaddr_un -> netaddr %d %s\n", na->family, na->path)); 335} 336 337 338static void 339netaddr_to_sockaddr_in(sain, sc) 340 struct sockaddr_in *sain; 341 const struct svr4_strmcmd *sc; 342{ 343 const struct svr4_netaddr_in *na; 344 345 346 na = SVR4_C_ADDROF(sc); 347 memset(sain, 0, sizeof(*sain)); 348 sain->sin_len = sizeof(*sain); 349 sain->sin_family = na->family; 350 sain->sin_port = na->port; 351 sain->sin_addr.s_addr = na->addr; 352 DPRINTF(("netaddr -> sockaddr_in %d %d %x\n", sain->sin_family, 353 sain->sin_port, sain->sin_addr.s_addr)); 354} 355 356 357static void 358netaddr_to_sockaddr_un(saun, sc) 359 struct sockaddr_un *saun; 360 const struct svr4_strmcmd *sc; 361{ 362 const struct svr4_netaddr_un *na; 363 char *dst, *edst = &saun->sun_path[sizeof(saun->sun_path) - 1]; 364 const char *src; 365 366 na = SVR4_C_ADDROF(sc); 367 memset(saun, 0, sizeof(*saun)); 368 saun->sun_family = na->family; 369 for (src = na->path, dst = saun->sun_path; (*dst++ = *src++) != '\0'; ) 370 if (dst == edst) 371 break; 372 saun->sun_len = dst - saun->sun_path; 373 DPRINTF(("netaddr -> sockaddr_un %d %s\n", saun->sun_family, 374 saun->sun_path)); 375} 376 377 378static void 379getparm(fp, pa) 380 struct file *fp; 381 struct svr4_si_sockparms *pa; 382{ 383 struct svr4_strm *st; 384 struct socket *so; 385 386 st = svr4_stream_get(fp); 387 if (st == NULL) 388 return; 389 390 so = fp->f_data; 391 392 pa->family = st->s_family; 393 394 switch (so->so_type) { 395 case SOCK_DGRAM: 396 pa->type = SVR4_T_CLTS; 397 pa->protocol = IPPROTO_UDP; 398 DPRINTF(("getparm(dgram)\n")); 399 return; 400 401 case SOCK_STREAM: 402 pa->type = SVR4_T_COTS; /* What about T_COTS_ORD? XXX */ 403 pa->protocol = IPPROTO_IP; 404 DPRINTF(("getparm(stream)\n")); 405 return; 406 407 case SOCK_RAW: 408 pa->type = SVR4_T_CLTS; 409 pa->protocol = IPPROTO_RAW; 410 DPRINTF(("getparm(raw)\n")); 411 return; 412 413 default: 414 pa->type = 0; 415 pa->protocol = 0; 416 DPRINTF(("getparm(type %d?)\n", so->so_type)); 417 return; 418 } 419} 420 421 422static int 423si_ogetudata(fp, fd, ioc, td) 424 struct file *fp; 425 int fd; 426 struct svr4_strioctl *ioc; 427 struct thread *td; 428{ 429 int error; 430 struct svr4_si_oudata ud; 431 struct svr4_si_sockparms pa; 432 433 if (ioc->len != sizeof(ud) && ioc->len != sizeof(ud) - sizeof(int)) { 434 DPRINTF(("SI_OGETUDATA: Wrong size %d != %d\n", 435 sizeof(ud), ioc->len)); 436 return EINVAL; 437 } 438 439 if ((error = copyin(ioc->buf, &ud, sizeof(ud))) != 0) 440 return error; 441 442 getparm(fp, &pa); 443 444 switch (pa.family) { 445 case AF_INET: 446 ud.tidusize = 16384; 447 ud.addrsize = sizeof(struct svr4_sockaddr_in); 448 if (pa.type == SVR4_SOCK_STREAM) 449 ud.etsdusize = 1; 450 else 451 ud.etsdusize = 0; 452 break; 453 454 case AF_LOCAL: 455 ud.tidusize = 65536; 456 ud.addrsize = 128; 457 ud.etsdusize = 128; 458 break; 459 460 default: 461 DPRINTF(("SI_OGETUDATA: Unsupported address family %d\n", 462 pa.family)); 463 return ENOSYS; 464 } 465 466 /* I have no idea what these should be! */ 467 ud.optsize = 128; 468 ud.tsdusize = 128; 469 470 ud.servtype = pa.type; 471 472 /* XXX: Fixme */ 473 ud.so_state = 0; 474 ud.so_options = 0; 475 return copyout(&ud, ioc->buf, ioc->len); 476} 477 478 479static int 480si_sockparams(fp, fd, ioc, td) 481 struct file *fp; 482 int fd; 483 struct svr4_strioctl *ioc; 484 struct thread *td; 485{ 486 struct svr4_si_sockparms pa; 487 488 getparm(fp, &pa); 489 return copyout(&pa, ioc->buf, sizeof(pa)); 490} 491 492 493static int 494si_listen(fp, fd, ioc, td) 495 struct file *fp; 496 int fd; 497 struct svr4_strioctl *ioc; 498 struct thread *td; 499{ 500 int error; 501 struct svr4_strm *st = svr4_stream_get(fp); 502 struct svr4_strmcmd lst; 503 struct listen_args la; 504 505 if (st == NULL) 506 return EINVAL; 507 508 if (ioc->len < 0 || ioc->len > sizeof(lst)) 509 return EINVAL; 510 511 if ((error = copyin(ioc->buf, &lst, ioc->len)) != 0) 512 return error; 513 514 if (lst.cmd != SVR4_TI_OLD_BIND_REQUEST) { 515 DPRINTF(("si_listen: bad request %ld\n", lst.cmd)); 516 return EINVAL; 517 } 518 519 /* 520 * We are making assumptions again... 521 */ 522 la.s = fd; 523 DPRINTF(("SI_LISTEN: fileno %d backlog = %d\n", fd, 5)); 524 la.backlog = 5; 525 526 if ((error = sys_listen(td, &la)) != 0) { 527 DPRINTF(("SI_LISTEN: listen failed %d\n", error)); 528 return error; 529 } 530 531 st->s_cmd = SVR4_TI__ACCEPT_WAIT; 532 lst.cmd = SVR4_TI_BIND_REPLY; 533 534 switch (st->s_family) { 535 case AF_INET: 536 /* XXX: Fill the length here */ 537 break; 538 539 case AF_LOCAL: 540 lst.len = 140; 541 lst.pad[28] = 0x00000000; /* magic again */ 542 lst.pad[29] = 0x00000800; /* magic again */ 543 lst.pad[30] = 0x80001400; /* magic again */ 544 break; 545 546 default: 547 DPRINTF(("SI_LISTEN: Unsupported address family %d\n", 548 st->s_family)); 549 return ENOSYS; 550 } 551 552 553 if ((error = copyout(&lst, ioc->buf, ioc->len)) != 0) 554 return error; 555 556 return 0; 557} 558 559 560static int 561si_getudata(fp, fd, ioc, td) 562 struct file *fp; 563 int fd; 564 struct svr4_strioctl *ioc; 565 struct thread *td; 566{ 567 int error; 568 struct svr4_si_udata ud; 569 570 if (sizeof(ud) != ioc->len) { 571 DPRINTF(("SI_GETUDATA: Wrong size %d != %d\n", 572 sizeof(ud), ioc->len)); 573 return EINVAL; 574 } 575 576 if ((error = copyin(ioc->buf, &ud, sizeof(ud))) != 0) 577 return error; 578 579 getparm(fp, &ud.sockparms); 580 581 switch (ud.sockparms.family) { 582 case AF_INET: 583 DPRINTF(("getudata_inet\n")); 584 ud.tidusize = 16384; 585 ud.tsdusize = 16384; 586 ud.addrsize = sizeof(struct svr4_sockaddr_in); 587 if (ud.sockparms.type == SVR4_SOCK_STREAM) 588 ud.etsdusize = 1; 589 else 590 ud.etsdusize = 0; 591 ud.optsize = 0; 592 break; 593 594 case AF_LOCAL: 595 DPRINTF(("getudata_local\n")); 596 ud.tidusize = 65536; 597 ud.tsdusize = 128; 598 ud.addrsize = 128; 599 ud.etsdusize = 128; 600 ud.optsize = 128; 601 break; 602 603 default: 604 DPRINTF(("SI_GETUDATA: Unsupported address family %d\n", 605 ud.sockparms.family)); 606 return ENOSYS; 607 } 608 609 610 ud.servtype = ud.sockparms.type; 611 DPRINTF(("ud.servtype = %d\n", ud.servtype)); 612 /* XXX: Fixme */ 613 ud.so_state = 0; 614 ud.so_options = 0; 615 return copyout(&ud, ioc->buf, sizeof(ud)); 616} 617 618 619static int 620si_shutdown(fp, fd, ioc, td) 621 struct file *fp; 622 int fd; 623 struct svr4_strioctl *ioc; 624 struct thread *td; 625{ 626 int error; 627 struct shutdown_args ap; 628 629 if (ioc->len != sizeof(ap.how)) { 630 DPRINTF(("SI_SHUTDOWN: Wrong size %d != %d\n", 631 sizeof(ap.how), ioc->len)); 632 return EINVAL; 633 } 634 635 if ((error = copyin(ioc->buf, &ap.how, ioc->len)) != 0) 636 return error; 637 638 ap.s = fd; 639 640 return sys_shutdown(td, &ap); 641} 642 643 644static int 645sockmod(fp, fd, ioc, td) 646 struct file *fp; 647 int fd; 648 struct svr4_strioctl *ioc; 649 struct thread *td; 650{ 651 switch (ioc->cmd) { 652 case SVR4_SI_OGETUDATA: 653 DPRINTF(("SI_OGETUDATA\n")); 654 return si_ogetudata(fp, fd, ioc, td); 655 656 case SVR4_SI_SHUTDOWN: 657 DPRINTF(("SI_SHUTDOWN\n")); 658 return si_shutdown(fp, fd, ioc, td); 659 660 case SVR4_SI_LISTEN: 661 DPRINTF(("SI_LISTEN\n")); 662 return si_listen(fp, fd, ioc, td); 663 664 case SVR4_SI_SETMYNAME: 665 DPRINTF(("SI_SETMYNAME\n")); 666 return 0; 667 668 case SVR4_SI_SETPEERNAME: 669 DPRINTF(("SI_SETPEERNAME\n")); 670 return 0; 671 672 case SVR4_SI_GETINTRANSIT: 673 DPRINTF(("SI_GETINTRANSIT\n")); 674 return 0; 675 676 case SVR4_SI_TCL_LINK: 677 DPRINTF(("SI_TCL_LINK\n")); 678 return 0; 679 680 case SVR4_SI_TCL_UNLINK: 681 DPRINTF(("SI_TCL_UNLINK\n")); 682 return 0; 683 684 case SVR4_SI_SOCKPARAMS: 685 DPRINTF(("SI_SOCKPARAMS\n")); 686 return si_sockparams(fp, fd, ioc, td); 687 688 case SVR4_SI_GETUDATA: 689 DPRINTF(("SI_GETUDATA\n")); 690 return si_getudata(fp, fd, ioc, td); 691 692 default: 693 DPRINTF(("Unknown sockmod ioctl %lx\n", ioc->cmd)); 694 return 0; 695 696 } 697} 698 699 700static int 701ti_getinfo(fp, fd, ioc, td) 702 struct file *fp; 703 int fd; 704 struct svr4_strioctl *ioc; 705 struct thread *td; 706{ 707 int error; 708 struct svr4_infocmd info; 709 710 memset(&info, 0, sizeof(info)); 711 712 if (ioc->len < 0 || ioc->len > sizeof(info)) 713 return EINVAL; 714 715 if ((error = copyin(ioc->buf, &info, ioc->len)) != 0) 716 return error; 717 718 if (info.cmd != SVR4_TI_INFO_REQUEST) 719 return EINVAL; 720 721 info.cmd = SVR4_TI_INFO_REPLY; 722 info.tsdu = 0; 723 info.etsdu = 1; 724 info.cdata = -2; 725 info.ddata = -2; 726 info.addr = 16; 727 info.opt = -1; 728 info.tidu = 16384; 729 info.serv = 2; 730 info.current = 0; 731 info.provider = 2; 732 733 ioc->len = sizeof(info); 734 if ((error = copyout(&info, ioc->buf, ioc->len)) != 0) 735 return error; 736 737 return 0; 738} 739 740 741static int 742ti_bind(fp, fd, ioc, td) 743 struct file *fp; 744 int fd; 745 struct svr4_strioctl *ioc; 746 struct thread *td; 747{ 748 int error; 749 struct svr4_strm *st = svr4_stream_get(fp); 750 struct sockaddr_in sain; 751 struct sockaddr_un saun; 752 struct sockaddr *skp; 753 int sasize; 754 struct svr4_strmcmd bnd; 755 756 if (st == NULL) { 757 DPRINTF(("ti_bind: bad file descriptor\n")); 758 return EINVAL; 759 } 760 761 if (ioc->len < 0 || ioc->len > sizeof(bnd)) 762 return EINVAL; 763 764 if ((error = copyin(ioc->buf, &bnd, ioc->len)) != 0) 765 return error; 766 767 if (bnd.cmd != SVR4_TI_OLD_BIND_REQUEST) { 768 DPRINTF(("ti_bind: bad request %ld\n", bnd.cmd)); 769 return EINVAL; 770 } 771 772 switch (st->s_family) { 773 case AF_INET: 774 skp = (struct sockaddr *)&sain; 775 sasize = sizeof(sain); 776 777 if (bnd.offs == 0) 778 goto error; 779 780 netaddr_to_sockaddr_in(&sain, &bnd); 781 782 DPRINTF(("TI_BIND: fam %d, port %d, addr %x\n", 783 sain.sin_family, sain.sin_port, 784 sain.sin_addr.s_addr)); 785 break; 786 787 case AF_LOCAL: 788 skp = (struct sockaddr *)&saun; 789 sasize = sizeof(saun); 790 if (bnd.offs == 0) 791 goto error; 792 793 netaddr_to_sockaddr_un(&saun, &bnd); 794 795 if (saun.sun_path[0] == '\0') 796 goto error; 797 798 DPRINTF(("TI_BIND: fam %d, path %s\n", 799 saun.sun_family, saun.sun_path)); 800 801 if ((error = clean_pipe(td, saun.sun_path)) != 0) 802 return error; 803 804 bnd.pad[28] = 0x00001000; /* magic again */ 805 break; 806 807 default: 808 DPRINTF(("TI_BIND: Unsupported address family %d\n", 809 st->s_family)); 810 return ENOSYS; 811 } 812 813 DPRINTF(("TI_BIND: fileno %d\n", fd)); 814 815 if ((error = kern_bind(td, fd, skp)) != 0) { 816 DPRINTF(("TI_BIND: bind failed %d\n", error)); 817 return error; 818 } 819 goto reply; 820 821error: 822 memset(&bnd, 0, sizeof(bnd)); 823 bnd.len = sasize + 4; 824 bnd.offs = 0x10; /* XXX */ 825 826reply: 827 bnd.cmd = SVR4_TI_BIND_REPLY; 828 829 if ((error = copyout(&bnd, ioc->buf, ioc->len)) != 0) 830 return error; 831 832 return 0; 833} 834 835 836static int 837timod(fp, fd, ioc, td) 838 struct file *fp; 839 int fd; 840 struct svr4_strioctl *ioc; 841 struct thread *td; 842{ 843 switch (ioc->cmd) { 844 case SVR4_TI_GETINFO: 845 DPRINTF(("TI_GETINFO\n")); 846 return ti_getinfo(fp, fd, ioc, td); 847 848 case SVR4_TI_OPTMGMT: 849 DPRINTF(("TI_OPTMGMT\n")); 850 return 0; 851 852 case SVR4_TI_BIND: 853 DPRINTF(("TI_BIND\n")); 854 return ti_bind(fp, fd, ioc, td); 855 856 case SVR4_TI_UNBIND: 857 DPRINTF(("TI_UNBIND\n")); 858 return 0; 859 860 default: 861 DPRINTF(("Unknown timod ioctl %lx\n", ioc->cmd)); 862 return 0; 863 } 864} 865 866 867int 868svr4_stream_ti_ioctl(fp, td, retval, fd, cmd, dat) 869 struct file *fp; 870 struct thread *td; 871 register_t *retval; 872 int fd; 873 u_long cmd; 874 caddr_t dat; 875{ 876 struct svr4_strbuf skb, *sub = (struct svr4_strbuf *) dat; 877 struct svr4_strm *st = svr4_stream_get(fp); 878 int error; 879 struct sockaddr *sa; 880 socklen_t sasize, oldsasize; 881 struct svr4_strmcmd sc; 882 883 DPRINTF(("svr4_stream_ti_ioctl\n")); 884 885 if (st == NULL) 886 return EINVAL; 887 888 sc.offs = 0x10; 889 890 if ((error = copyin(sub, &skb, sizeof(skb))) != 0) { 891 DPRINTF(("ti_ioctl: error copying in strbuf\n")); 892 return error; 893 } 894 895 switch (st->s_family) { 896 case AF_INET: 897 sasize = sizeof(struct sockaddr_in); 898 break; 899 900 case AF_LOCAL: 901 sasize = sizeof(struct sockaddr_un); 902 break; 903 904 default: 905 DPRINTF(("ti_ioctl: Unsupported address family %d\n", 906 st->s_family)); 907 return ENOSYS; 908 } 909 oldsasize = sasize; 910 911 switch (cmd) { 912 case SVR4_TI_GETMYNAME: 913 DPRINTF(("TI_GETMYNAME\n")); 914 { 915 error = kern_getsockname(td, fd, &sa, &sasize); 916 if (error) { 917 DPRINTF(("ti_ioctl: getsockname error\n")); 918 return error; 919 } 920 } 921 break; 922 923 case SVR4_TI_GETPEERNAME: 924 DPRINTF(("TI_GETPEERNAME\n")); 925 { 926 error = kern_getpeername(td, fd, &sa, &sasize); 927 if (error) { 928 DPRINTF(("ti_ioctl: getpeername error\n")); 929 return error; 930 } 931 } 932 break; 933 934 case SVR4_TI_SETMYNAME: 935 DPRINTF(("TI_SETMYNAME\n")); 936 return 0; 937 938 case SVR4_TI_SETPEERNAME: 939 DPRINTF(("TI_SETPEERNAME\n")); 940 return 0; 941 default: 942 DPRINTF(("ti_ioctl: Unknown ioctl %lx\n", cmd)); 943 return ENOSYS; 944 } 945 946 if (sasize < 0 || sasize > oldsasize) { 947 free(sa, M_SONAME); 948 return EINVAL; 949 } 950 951 switch (st->s_family) { 952 case AF_INET: 953 sockaddr_to_netaddr_in(&sc, (struct sockaddr_in *)sa); 954 skb.len = sasize; 955 break; 956 957 case AF_LOCAL: 958 sockaddr_to_netaddr_un(&sc, (struct sockaddr_un *)sa); 959 skb.len = sasize + 4; 960 break; 961 962 default: 963 free(sa, M_SONAME); 964 return ENOSYS; 965 } 966 free(sa, M_SONAME); 967 968 if ((error = copyout(SVR4_ADDROF(&sc), skb.buf, sasize)) != 0) { 969 DPRINTF(("ti_ioctl: error copying out socket data\n")); 970 return error; 971 } 972 973 974 if ((error = copyout(&skb, sub, sizeof(skb))) != 0) { 975 DPRINTF(("ti_ioctl: error copying out strbuf\n")); 976 return error; 977 } 978 979 return error; 980} 981 982 983 984 985static int 986i_nread(fp, td, retval, fd, cmd, dat) 987 struct file *fp; 988 struct thread *td; 989 register_t *retval; 990 int fd; 991 u_long cmd; 992 caddr_t dat; 993{ 994 int error; 995 int nread = 0; 996 997 /* 998 * We are supposed to return the message length in nread, and the 999 * number of messages in retval. We don't have the notion of number 1000 * of stream messages, so we just find out if we have any bytes waiting 1001 * for us, and if we do, then we assume that we have at least one 1002 * message waiting for us. 1003 */ 1004 if ((error = fo_ioctl(fp, FIONREAD, (caddr_t) &nread, td->td_ucred, 1005 td)) != 0) 1006 return error; 1007 1008 if (nread != 0) 1009 *retval = 1; 1010 else 1011 *retval = 0; 1012 1013 return copyout(&nread, dat, sizeof(nread)); 1014} 1015 1016static int 1017i_fdinsert(fp, td, retval, fd, cmd, dat) 1018 struct file *fp; 1019 struct thread *td; 1020 register_t *retval; 1021 int fd; 1022 u_long cmd; 1023 caddr_t dat; 1024{ 1025 /* 1026 * Major hack again here. We assume that we are using this to 1027 * implement accept(2). If that is the case, we have already 1028 * called accept, and we have stored the file descriptor in 1029 * afd. We find the file descriptor that the code wants to use 1030 * in fd insert, and then we dup2() our accepted file descriptor 1031 * to it. 1032 */ 1033 int error; 1034 struct svr4_strm *st = svr4_stream_get(fp); 1035 struct svr4_strfdinsert fdi; 1036 struct dup2_args d2p; 1037 1038 if (st == NULL) { 1039 DPRINTF(("fdinsert: bad file type\n")); 1040 return EINVAL; 1041 } 1042 1043 mtx_lock(&Giant); 1044 if (st->s_afd == -1) { 1045 DPRINTF(("fdinsert: accept fd not found\n")); 1046 mtx_unlock(&Giant); 1047 return ENOENT; 1048 } 1049 1050 if ((error = copyin(dat, &fdi, sizeof(fdi))) != 0) { 1051 DPRINTF(("fdinsert: copyin failed %d\n", error)); 1052 mtx_unlock(&Giant); 1053 return error; 1054 } 1055 1056 d2p.from = st->s_afd; 1057 d2p.to = fdi.fd; 1058 1059 if ((error = sys_dup2(td, &d2p)) != 0) { 1060 DPRINTF(("fdinsert: dup2(%d, %d) failed %d\n", 1061 st->s_afd, fdi.fd, error)); 1062 mtx_unlock(&Giant); 1063 return error; 1064 } 1065 1066 if ((error = kern_close(td, st->s_afd)) != 0) { 1067 DPRINTF(("fdinsert: close(%d) failed %d\n", 1068 st->s_afd, error)); 1069 mtx_unlock(&Giant); 1070 return error; 1071 } 1072 1073 st->s_afd = -1; 1074 mtx_unlock(&Giant); 1075 1076 *retval = 0; 1077 return 0; 1078} 1079 1080 1081static int 1082_i_bind_rsvd(fp, td, retval, fd, cmd, dat) 1083 struct file *fp; 1084 struct thread *td; 1085 register_t *retval; 1086 int fd; 1087 u_long cmd; 1088 caddr_t dat; 1089{ 1090 struct mkfifo_args ap; 1091 1092 /* 1093 * This is a supposed to be a kernel and library only ioctl. 1094 * It gets called before ti_bind, when we have a unix 1095 * socket, to physically create the socket transport and 1096 * ``reserve'' it. I don't know how this get reserved inside 1097 * the kernel, but we are going to create it nevertheless. 1098 */ 1099 ap.path = dat; 1100 ap.mode = S_IFIFO; 1101 1102 return sys_mkfifo(td, &ap); 1103} 1104 1105static int 1106_i_rele_rsvd(fp, td, retval, fd, cmd, dat) 1107 struct file *fp; 1108 struct thread *td; 1109 register_t *retval; 1110 int fd; 1111 u_long cmd; 1112 caddr_t dat; 1113{ 1114 struct unlink_args ap; 1115 1116 /* 1117 * This is a supposed to be a kernel and library only ioctl. 1118 * I guess it is supposed to release the socket. 1119 */ 1120 ap.path = dat; 1121 1122 return sys_unlink(td, &ap); 1123} 1124 1125static int 1126i_str(fp, td, retval, fd, cmd, dat) 1127 struct file *fp; 1128 struct thread *td; 1129 register_t *retval; 1130 int fd; 1131 u_long cmd; 1132 caddr_t dat; 1133{ 1134 int error; 1135 struct svr4_strioctl ioc; 1136 1137 if ((error = copyin(dat, &ioc, sizeof(ioc))) != 0) 1138 return error; 1139 1140#ifdef DEBUG_SVR4 1141 if ((error = show_ioc(">", &ioc)) != 0) 1142 return error; 1143#endif /* DEBUG_SVR4 */ 1144 1145 switch (ioc.cmd & 0xff00) { 1146 case SVR4_SIMOD: 1147 if ((error = sockmod(fp, fd, &ioc, td)) != 0) 1148 return error; 1149 break; 1150 1151 case SVR4_TIMOD: 1152 if ((error = timod(fp, fd, &ioc, td)) != 0) 1153 return error; 1154 break; 1155 1156 default: 1157 DPRINTF(("Unimplemented module %c %ld\n", 1158 (char) (cmd >> 8), cmd & 0xff)); 1159 return 0; 1160 } 1161 1162#ifdef DEBUG_SVR4 1163 if ((error = show_ioc("<", &ioc)) != 0) 1164 return error; 1165#endif /* DEBUG_SVR4 */ 1166 return copyout(&ioc, dat, sizeof(ioc)); 1167} 1168 1169static int 1170i_setsig(fp, td, retval, fd, cmd, dat) 1171 struct file *fp; 1172 struct thread *td; 1173 register_t *retval; 1174 int fd; 1175 u_long cmd; 1176 caddr_t dat; 1177{ 1178 /* 1179 * This is the best we can do for now; we cannot generate 1180 * signals only for specific events so the signal mask gets 1181 * ignored; we save it just to pass it to a possible I_GETSIG... 1182 * 1183 * We alse have to fix the O_ASYNC fcntl bit, so the 1184 * process will get SIGPOLLs. 1185 */ 1186 int error; 1187 register_t oflags, flags; 1188 struct svr4_strm *st = svr4_stream_get(fp); 1189 1190 if (st == NULL) { 1191 DPRINTF(("i_setsig: bad file descriptor\n")); 1192 return EINVAL; 1193 } 1194 /* get old status flags */ 1195 error = kern_fcntl(td, fd, F_GETFL, 0); 1196 if (error) 1197 return (error); 1198 1199 oflags = td->td_retval[0]; 1200 1201 /* update the flags */ 1202 mtx_lock(&Giant); 1203 if (dat != NULL) { 1204 int mask; 1205 1206 flags = oflags | O_ASYNC; 1207 if ((error = copyin(dat, &mask, sizeof(mask))) != 0) { 1208 DPRINTF(("i_setsig: bad eventmask pointer\n")); 1209 return error; 1210 } 1211 if (mask & SVR4_S_ALLMASK) { 1212 DPRINTF(("i_setsig: bad eventmask data %x\n", mask)); 1213 return EINVAL; 1214 } 1215 st->s_eventmask = mask; 1216 } 1217 else { 1218 flags = oflags & ~O_ASYNC; 1219 st->s_eventmask = 0; 1220 } 1221 mtx_unlock(&Giant); 1222 1223 /* set the new flags, if changed */ 1224 if (flags != oflags) { 1225 error = kern_fcntl(td, fd, F_SETFL, flags); 1226 if (error) 1227 return (error); 1228 flags = td->td_retval[0]; 1229 } 1230 1231 /* set up SIGIO receiver if needed */ 1232 if (dat != NULL) 1233 return (kern_fcntl(td, fd, F_SETOWN, td->td_proc->p_pid)); 1234 return 0; 1235} 1236 1237static int 1238i_getsig(fp, td, retval, fd, cmd, dat) 1239 struct file *fp; 1240 struct thread *td; 1241 register_t *retval; 1242 int fd; 1243 u_long cmd; 1244 caddr_t dat; 1245{ 1246 int error, eventmask; 1247 1248 if (dat != NULL) { 1249 struct svr4_strm *st = svr4_stream_get(fp); 1250 1251 if (st == NULL) { 1252 DPRINTF(("i_getsig: bad file descriptor\n")); 1253 return EINVAL; 1254 } 1255 mtx_lock(&Giant); 1256 eventmask = st->s_eventmask; 1257 mtx_unlock(&Giant); 1258 if ((error = copyout(&eventmask, dat, 1259 sizeof(eventmask))) != 0) { 1260 DPRINTF(("i_getsig: bad eventmask pointer\n")); 1261 return error; 1262 } 1263 } 1264 return 0; 1265} 1266 1267int 1268svr4_stream_ioctl(fp, td, retval, fd, cmd, dat) 1269 struct file *fp; 1270 struct thread *td; 1271 register_t *retval; 1272 int fd; 1273 u_long cmd; 1274 caddr_t dat; 1275{ 1276 *retval = 0; 1277 1278 /* 1279 * All the following stuff assumes "sockmod" is pushed... 1280 */ 1281 switch (cmd) { 1282 case SVR4_I_NREAD: 1283 DPRINTF(("I_NREAD\n")); 1284 return i_nread(fp, td, retval, fd, cmd, dat); 1285 1286 case SVR4_I_PUSH: 1287 DPRINTF(("I_PUSH %p\n", dat)); 1288#if defined(DEBUG_SVR4) 1289 show_strbuf((struct svr4_strbuf *)dat); 1290#endif 1291 return 0; 1292 1293 case SVR4_I_POP: 1294 DPRINTF(("I_POP\n")); 1295 return 0; 1296 1297 case SVR4_I_LOOK: 1298 DPRINTF(("I_LOOK\n")); 1299 return 0; 1300 1301 case SVR4_I_FLUSH: 1302 DPRINTF(("I_FLUSH\n")); 1303 return 0; 1304 1305 case SVR4_I_SRDOPT: 1306 DPRINTF(("I_SRDOPT\n")); 1307 return 0; 1308 1309 case SVR4_I_GRDOPT: 1310 DPRINTF(("I_GRDOPT\n")); 1311 return 0; 1312 1313 case SVR4_I_STR: 1314 DPRINTF(("I_STR\n")); 1315 return i_str(fp, td, retval, fd, cmd, dat); 1316 1317 case SVR4_I_SETSIG: 1318 DPRINTF(("I_SETSIG\n")); 1319 return i_setsig(fp, td, retval, fd, cmd, dat); 1320 1321 case SVR4_I_GETSIG: 1322 DPRINTF(("I_GETSIG\n")); 1323 return i_getsig(fp, td, retval, fd, cmd, dat); 1324 1325 case SVR4_I_FIND: 1326 DPRINTF(("I_FIND\n")); 1327 /* 1328 * Here we are not pushing modules really, we just 1329 * pretend all are present 1330 */ 1331 *retval = 0; 1332 return 0; 1333 1334 case SVR4_I_LINK: 1335 DPRINTF(("I_LINK\n")); 1336 return 0; 1337 1338 case SVR4_I_UNLINK: 1339 DPRINTF(("I_UNLINK\n")); 1340 return 0; 1341 1342 case SVR4_I_ERECVFD: 1343 DPRINTF(("I_ERECVFD\n")); 1344 return 0; 1345 1346 case SVR4_I_PEEK: 1347 DPRINTF(("I_PEEK\n")); 1348 return 0; 1349 1350 case SVR4_I_FDINSERT: 1351 DPRINTF(("I_FDINSERT\n")); 1352 return i_fdinsert(fp, td, retval, fd, cmd, dat); 1353 1354 case SVR4_I_SENDFD: 1355 DPRINTF(("I_SENDFD\n")); 1356 return 0; 1357 1358 case SVR4_I_RECVFD: 1359 DPRINTF(("I_RECVFD\n")); 1360 return 0; 1361 1362 case SVR4_I_SWROPT: 1363 DPRINTF(("I_SWROPT\n")); 1364 return 0; 1365 1366 case SVR4_I_GWROPT: 1367 DPRINTF(("I_GWROPT\n")); 1368 return 0; 1369 1370 case SVR4_I_LIST: 1371 DPRINTF(("I_LIST\n")); 1372 return 0; 1373 1374 case SVR4_I_PLINK: 1375 DPRINTF(("I_PLINK\n")); 1376 return 0; 1377 1378 case SVR4_I_PUNLINK: 1379 DPRINTF(("I_PUNLINK\n")); 1380 return 0; 1381 1382 case SVR4_I_SETEV: 1383 DPRINTF(("I_SETEV\n")); 1384 return 0; 1385 1386 case SVR4_I_GETEV: 1387 DPRINTF(("I_GETEV\n")); 1388 return 0; 1389 1390 case SVR4_I_STREV: 1391 DPRINTF(("I_STREV\n")); 1392 return 0; 1393 1394 case SVR4_I_UNSTREV: 1395 DPRINTF(("I_UNSTREV\n")); 1396 return 0; 1397 1398 case SVR4_I_FLUSHBAND: 1399 DPRINTF(("I_FLUSHBAND\n")); 1400 return 0; 1401 1402 case SVR4_I_CKBAND: 1403 DPRINTF(("I_CKBAND\n")); 1404 return 0; 1405 1406 case SVR4_I_GETBAND: 1407 DPRINTF(("I_GETBANK\n")); 1408 return 0; 1409 1410 case SVR4_I_ATMARK: 1411 DPRINTF(("I_ATMARK\n")); 1412 return 0; 1413 1414 case SVR4_I_SETCLTIME: 1415 DPRINTF(("I_SETCLTIME\n")); 1416 return 0; 1417 1418 case SVR4_I_GETCLTIME: 1419 DPRINTF(("I_GETCLTIME\n")); 1420 return 0; 1421 1422 case SVR4_I_CANPUT: 1423 DPRINTF(("I_CANPUT\n")); 1424 return 0; 1425 1426 case SVR4__I_BIND_RSVD: 1427 DPRINTF(("_I_BIND_RSVD\n")); 1428 return _i_bind_rsvd(fp, td, retval, fd, cmd, dat); 1429 1430 case SVR4__I_RELE_RSVD: 1431 DPRINTF(("_I_RELE_RSVD\n")); 1432 return _i_rele_rsvd(fp, td, retval, fd, cmd, dat); 1433 1434 default: 1435 DPRINTF(("unimpl cmd = %lx\n", cmd)); 1436 break; 1437 } 1438 1439 return 0; 1440} 1441 1442 1443 1444int 1445svr4_sys_putmsg(td, uap) 1446 struct thread *td; 1447 struct svr4_sys_putmsg_args *uap; 1448{ 1449 struct file *fp; 1450 int error; 1451 1452 if ((error = fget(td, uap->fd, CAP_WRITE, &fp)) != 0) { 1453#ifdef DEBUG_SVR4 1454 uprintf("putmsg: bad fp\n"); 1455#endif 1456 return EBADF; 1457 } 1458 error = svr4_do_putmsg(td, uap, fp); 1459 fdrop(fp, td); 1460 return (error); 1461} 1462 1463static int 1464svr4_do_putmsg(td, uap, fp) 1465 struct thread *td; 1466 struct svr4_sys_putmsg_args *uap; 1467 struct file *fp; 1468{ 1469 struct svr4_strbuf dat, ctl; 1470 struct svr4_strmcmd sc; 1471 struct sockaddr_in sain; 1472 struct sockaddr_un saun; 1473 struct sockaddr *sa; 1474 int sasize, *retval; 1475 struct svr4_strm *st; 1476 int error; 1477 1478 retval = td->td_retval; 1479 1480#ifdef DEBUG_SVR4 1481 show_msg(">putmsg", uap->fd, uap->ctl, 1482 uap->dat, uap->flags); 1483#endif /* DEBUG_SVR4 */ 1484 1485 if (uap->ctl != NULL) { 1486 if ((error = copyin(uap->ctl, &ctl, sizeof(ctl))) != 0) { 1487#ifdef DEBUG_SVR4 1488 uprintf("putmsg: copyin(): %d\n", error); 1489#endif 1490 return error; 1491 } 1492 } 1493 else 1494 ctl.len = -1; 1495 1496 if (uap->dat != NULL) { 1497 if ((error = copyin(uap->dat, &dat, sizeof(dat))) != 0) { 1498#ifdef DEBUG_SVR4 1499 uprintf("putmsg: copyin(): %d (2)\n", error); 1500#endif 1501 return error; 1502 } 1503 } 1504 else 1505 dat.len = -1; 1506 1507 /* 1508 * Only for sockets for now. 1509 */ 1510 if ((st = svr4_stream_get(fp)) == NULL) { 1511 DPRINTF(("putmsg: bad file type\n")); 1512 return EINVAL; 1513 } 1514 1515 if (ctl.len < 0 || ctl.len > sizeof(sc)) { 1516 DPRINTF(("putmsg: Bad control size %d != %d\n", ctl.len, 1517 sizeof(struct svr4_strmcmd))); 1518 return EINVAL; 1519 } 1520 1521 if ((error = copyin(ctl.buf, &sc, ctl.len)) != 0) 1522 return error; 1523 1524 switch (st->s_family) { 1525 case AF_INET: 1526 if (sc.len != sizeof(sain)) { 1527 if (sc.cmd == SVR4_TI_DATA_REQUEST) { 1528 struct write_args wa; 1529 1530 /* Solaris seems to use sc.cmd = 3 to 1531 * send "expedited" data. telnet uses 1532 * this for options processing, sending EOF, 1533 * etc. I'm sure other things use it too. 1534 * I don't have any documentation 1535 * on it, so I'm making a guess that this 1536 * is how it works. newton@atdot.dotat.org XXX 1537 */ 1538 DPRINTF(("sending expedited data ??\n")); 1539 wa.fd = uap->fd; 1540 wa.buf = dat.buf; 1541 wa.nbyte = dat.len; 1542 return sys_write(td, &wa); 1543 } 1544 DPRINTF(("putmsg: Invalid inet length %ld\n", sc.len)); 1545 return EINVAL; 1546 } 1547 netaddr_to_sockaddr_in(&sain, &sc); 1548 sa = (struct sockaddr *)&sain; 1549 sasize = sizeof(sain); 1550 if (sain.sin_family != st->s_family) 1551 error = EINVAL; 1552 break; 1553 1554 case AF_LOCAL: 1555 if (ctl.len == 8) { 1556 /* We are doing an accept; succeed */ 1557 DPRINTF(("putmsg: Do nothing\n")); 1558 *retval = 0; 1559 return 0; 1560 } 1561 else { 1562 /* Maybe we've been given a device/inode pair */ 1563 dev_t *dev = SVR4_ADDROF(&sc); 1564 ino_t *ino = (ino_t *) &dev[1]; 1565 if (svr4_find_socket(td, fp, *dev, *ino, &saun) != 0) { 1566 /* I guess we have it by name */ 1567 netaddr_to_sockaddr_un(&saun, &sc); 1568 } 1569 sa = (struct sockaddr *)&saun; 1570 sasize = sizeof(saun); 1571 } 1572 break; 1573 1574 default: 1575 DPRINTF(("putmsg: Unsupported address family %d\n", 1576 st->s_family)); 1577 return ENOSYS; 1578 } 1579 1580 mtx_lock(&Giant); 1581 st->s_cmd = sc.cmd; 1582 mtx_unlock(&Giant); 1583 switch (sc.cmd) { 1584 case SVR4_TI_CONNECT_REQUEST: /* connect */ 1585 { 1586 1587 return (kern_connect(td, uap->fd, sa)); 1588 } 1589 1590 case SVR4_TI_SENDTO_REQUEST: /* sendto */ 1591 { 1592 struct msghdr msg; 1593 struct iovec aiov; 1594 1595 msg.msg_name = sa; 1596 msg.msg_namelen = sasize; 1597 msg.msg_iov = &aiov; 1598 msg.msg_iovlen = 1; 1599 msg.msg_control = 0; 1600 msg.msg_flags = 0; 1601 aiov.iov_base = dat.buf; 1602 aiov.iov_len = dat.len; 1603 error = kern_sendit(td, uap->fd, &msg, uap->flags, 1604 NULL, UIO_USERSPACE); 1605 DPRINTF(("sendto_request error: %d\n", error)); 1606 *retval = 0; 1607 return error; 1608 } 1609 1610 default: 1611 DPRINTF(("putmsg: Unimplemented command %lx\n", sc.cmd)); 1612 return ENOSYS; 1613 } 1614} 1615 1616int 1617svr4_sys_getmsg(td, uap) 1618 struct thread *td; 1619 struct svr4_sys_getmsg_args *uap; 1620{ 1621 struct file *fp; 1622 int error; 1623 1624 if ((error = fget(td, uap->fd, CAP_READ, &fp)) != 0) { 1625#ifdef DEBUG_SVR4 1626 uprintf("getmsg: bad fp\n"); 1627#endif 1628 return EBADF; 1629 } 1630 error = svr4_do_getmsg(td, uap, fp); 1631 fdrop(fp, td); 1632 return (error); 1633} 1634 1635int 1636svr4_do_getmsg(td, uap, fp) 1637 struct thread *td; 1638 struct svr4_sys_getmsg_args *uap; 1639 struct file *fp; 1640{ 1641 struct svr4_strbuf dat, ctl; 1642 struct svr4_strmcmd sc; 1643 int error, *retval; 1644 struct msghdr msg; 1645 struct iovec aiov; 1646 struct sockaddr_in sain; 1647 struct sockaddr_un saun; 1648 struct sockaddr *sa; 1649 socklen_t sasize; 1650 struct svr4_strm *st; 1651 struct file *afp; 1652 int fl; 1653 1654 retval = td->td_retval; 1655 error = 0; 1656 afp = NULL; 1657 1658 memset(&sc, 0, sizeof(sc)); 1659 1660#ifdef DEBUG_SVR4 1661 show_msg(">getmsg", uap->fd, uap->ctl, 1662 uap->dat, 0); 1663#endif /* DEBUG_SVR4 */ 1664 1665 if (uap->ctl != NULL) { 1666 if ((error = copyin(uap->ctl, &ctl, sizeof(ctl))) != 0) 1667 return error; 1668 if (ctl.len < 0) 1669 return EINVAL; 1670 } 1671 else { 1672 ctl.len = -1; 1673 ctl.maxlen = 0; 1674 } 1675 1676 if (uap->dat != NULL) { 1677 if ((error = copyin(uap->dat, &dat, sizeof(dat))) != 0) 1678 return error; 1679 } 1680 else { 1681 dat.len = -1; 1682 dat.maxlen = 0; 1683 } 1684 1685 /* 1686 * Only for sockets for now. 1687 */ 1688 if ((st = svr4_stream_get(fp)) == NULL) { 1689 DPRINTF(("getmsg: bad file type\n")); 1690 return EINVAL; 1691 } 1692 1693 if (ctl.maxlen == -1 || dat.maxlen == -1) { 1694 DPRINTF(("getmsg: Cannot handle -1 maxlen (yet)\n")); 1695 return ENOSYS; 1696 } 1697 1698 switch (st->s_family) { 1699 case AF_INET: 1700 sasize = sizeof(sain); 1701 break; 1702 1703 case AF_LOCAL: 1704 sasize = sizeof(saun); 1705 break; 1706 1707 default: 1708 DPRINTF(("getmsg: Unsupported address family %d\n", 1709 st->s_family)); 1710 return ENOSYS; 1711 } 1712 1713 mtx_lock(&Giant); 1714 switch (st->s_cmd) { 1715 case SVR4_TI_CONNECT_REQUEST: 1716 DPRINTF(("getmsg: TI_CONNECT_REQUEST\n")); 1717 /* 1718 * We do the connect in one step, so the putmsg should 1719 * have gotten the error. 1720 */ 1721 sc.cmd = SVR4_TI_OK_REPLY; 1722 sc.len = 0; 1723 1724 ctl.len = 8; 1725 dat.len = -1; 1726 fl = 1; 1727 st->s_cmd = sc.cmd; 1728 break; 1729 1730 case SVR4_TI_OK_REPLY: 1731 DPRINTF(("getmsg: TI_OK_REPLY\n")); 1732 /* 1733 * We are immediately after a connect reply, so we send 1734 * a connect verification. 1735 */ 1736 1737 error = kern_getpeername(td, uap->fd, &sa, &sasize); 1738 if (error) { 1739 mtx_unlock(&Giant); 1740 DPRINTF(("getmsg: getpeername failed %d\n", error)); 1741 return error; 1742 } 1743 1744 sc.cmd = SVR4_TI_CONNECT_REPLY; 1745 sc.pad[0] = 0x4; 1746 sc.offs = 0x18; 1747 sc.pad[1] = 0x14; 1748 sc.pad[2] = 0x04000402; 1749 1750 switch (st->s_family) { 1751 case AF_INET: 1752 sc.len = sasize; 1753 sockaddr_to_netaddr_in(&sc, (struct sockaddr_in *)sa); 1754 break; 1755 1756 case AF_LOCAL: 1757 sc.len = sasize + 4; 1758 sockaddr_to_netaddr_un(&sc, (struct sockaddr_un *)sa); 1759 break; 1760 1761 default: 1762 mtx_unlock(&Giant); 1763 free(sa, M_SONAME); 1764 return ENOSYS; 1765 } 1766 free(sa, M_SONAME); 1767 1768 ctl.len = 40; 1769 dat.len = -1; 1770 fl = 0; 1771 st->s_cmd = sc.cmd; 1772 break; 1773 1774 case SVR4_TI__ACCEPT_OK: 1775 DPRINTF(("getmsg: TI__ACCEPT_OK\n")); 1776 /* 1777 * We do the connect in one step, so the putmsg should 1778 * have gotten the error. 1779 */ 1780 sc.cmd = SVR4_TI_OK_REPLY; 1781 sc.len = 1; 1782 1783 ctl.len = 8; 1784 dat.len = -1; 1785 fl = 1; 1786 st->s_cmd = SVR4_TI__ACCEPT_WAIT; 1787 break; 1788 1789 case SVR4_TI__ACCEPT_WAIT: 1790 DPRINTF(("getmsg: TI__ACCEPT_WAIT\n")); 1791 /* 1792 * We are after a listen, so we try to accept... 1793 */ 1794 1795 error = kern_accept(td, uap->fd, &sa, &sasize, &afp); 1796 if (error) { 1797 mtx_unlock(&Giant); 1798 DPRINTF(("getmsg: accept failed %d\n", error)); 1799 return error; 1800 } 1801 1802 st->s_afd = *retval; 1803 1804 DPRINTF(("getmsg: Accept fd = %d\n", st->s_afd)); 1805 1806 sc.cmd = SVR4_TI_ACCEPT_REPLY; 1807 sc.offs = 0x18; 1808 sc.pad[0] = 0x0; 1809 1810 switch (st->s_family) { 1811 case AF_INET: 1812 sc.pad[1] = 0x28; 1813 sockaddr_to_netaddr_in(&sc, (struct sockaddr_in *)&sa); 1814 ctl.len = 40; 1815 sc.len = sasize; 1816 break; 1817 1818 case AF_LOCAL: 1819 sc.pad[1] = 0x00010000; 1820 sc.pad[2] = 0xf6bcdaa0; /* I don't know what that is */ 1821 sc.pad[3] = 0x00010000; 1822 ctl.len = 134; 1823 sc.len = sasize + 4; 1824 break; 1825 1826 default: 1827 fdclose(td->td_proc->p_fd, afp, st->s_afd, td); 1828 fdrop(afp, td); 1829 st->s_afd = -1; 1830 mtx_unlock(&Giant); 1831 free(sa, M_SONAME); 1832 return ENOSYS; 1833 } 1834 free(sa, M_SONAME); 1835 1836 dat.len = -1; 1837 fl = 0; 1838 st->s_cmd = SVR4_TI__ACCEPT_OK; 1839 break; 1840 1841 case SVR4_TI_SENDTO_REQUEST: 1842 DPRINTF(("getmsg: TI_SENDTO_REQUEST\n")); 1843 if (ctl.maxlen > 36 && ctl.len < 36) 1844 ctl.len = 36; 1845 1846 if (ctl.len > sizeof(sc)) 1847 ctl.len = sizeof(sc); 1848 1849 if ((error = copyin(ctl.buf, &sc, ctl.len)) != 0) { 1850 mtx_unlock(&Giant); 1851 return error; 1852 } 1853 1854 switch (st->s_family) { 1855 case AF_INET: 1856 sa = (struct sockaddr *)&sain; 1857 sockaddr_to_netaddr_in(&sc, &sain); 1858 break; 1859 1860 case AF_LOCAL: 1861 sa = (struct sockaddr *)&saun; 1862 sockaddr_to_netaddr_un(&sc, &saun); 1863 break; 1864 1865 default: 1866 mtx_unlock(&Giant); 1867 return ENOSYS; 1868 } 1869 1870 msg.msg_name = sa; 1871 msg.msg_namelen = sasize; 1872 msg.msg_iov = &aiov; 1873 msg.msg_iovlen = 1; 1874 msg.msg_control = 0; 1875 aiov.iov_base = dat.buf; 1876 aiov.iov_len = dat.maxlen; 1877 msg.msg_flags = 0; 1878 1879 error = kern_recvit(td, uap->fd, &msg, UIO_SYSSPACE, NULL); 1880 1881 if (error) { 1882 mtx_unlock(&Giant); 1883 DPRINTF(("getmsg: recvit failed %d\n", error)); 1884 return error; 1885 } 1886 1887 sc.cmd = SVR4_TI_RECVFROM_IND; 1888 1889 switch (st->s_family) { 1890 case AF_INET: 1891 sc.len = sasize; 1892 sockaddr_to_netaddr_in(&sc, &sain); 1893 break; 1894 1895 case AF_LOCAL: 1896 sc.len = sasize + 4; 1897 sockaddr_to_netaddr_un(&sc, &saun); 1898 break; 1899 1900 default: 1901 mtx_unlock(&Giant); 1902 return ENOSYS; 1903 } 1904 1905 dat.len = *retval; 1906 fl = 0; 1907 st->s_cmd = sc.cmd; 1908 break; 1909 1910 default: 1911 st->s_cmd = sc.cmd; 1912 if (st->s_cmd == SVR4_TI_CONNECT_REQUEST) { 1913 struct read_args ra; 1914 1915 /* More weirdness: Again, I can't find documentation 1916 * to back this up, but when a process does a generic 1917 * "getmsg()" call it seems that the command field is 1918 * zero and the length of the data area is zero. I 1919 * think processes expect getmsg() to fill in dat.len 1920 * after reading at most dat.maxlen octets from the 1921 * stream. Since we're using sockets I can let 1922 * read() look after it and frob return values 1923 * appropriately (or inappropriately :-) 1924 * -- newton@atdot.dotat.org XXX 1925 */ 1926 ra.fd = uap->fd; 1927 ra.buf = dat.buf; 1928 ra.nbyte = dat.maxlen; 1929 if ((error = sys_read(td, &ra)) != 0) { 1930 mtx_unlock(&Giant); 1931 return error; 1932 } 1933 dat.len = *retval; 1934 *retval = 0; 1935 st->s_cmd = SVR4_TI_SENDTO_REQUEST; 1936 break; 1937 } 1938 mtx_unlock(&Giant); 1939 DPRINTF(("getmsg: Unknown state %x\n", st->s_cmd)); 1940 return EINVAL; 1941 } 1942 1943 if (uap->ctl) { 1944 if (ctl.len > sizeof(sc)) 1945 ctl.len = sizeof(sc); 1946 if (ctl.len != -1) 1947 error = copyout(&sc, ctl.buf, ctl.len); 1948 1949 if (error == 0) 1950 error = copyout(&ctl, uap->ctl, sizeof(ctl)); 1951 } 1952 1953 if (uap->dat) { 1954 if (error == 0) 1955 error = copyout(&dat, uap->dat, sizeof(dat)); 1956 } 1957 1958 if (uap->flags) { /* XXX: Need translation */ 1959 if (error == 0) 1960 error = copyout(&fl, uap->flags, sizeof(fl)); 1961 } 1962 1963 if (error) { 1964 if (afp) { 1965 fdclose(td->td_proc->p_fd, afp, st->s_afd, td); 1966 fdrop(afp, td); 1967 st->s_afd = -1; 1968 } 1969 mtx_unlock(&Giant); 1970 return (error); 1971 } 1972 mtx_unlock(&Giant); 1973 if (afp) 1974 fdrop(afp, td); 1975 1976 *retval = 0; 1977 1978#ifdef DEBUG_SVR4 1979 show_msg("<getmsg", uap->fd, uap->ctl, 1980 uap->dat, fl); 1981#endif /* DEBUG_SVR4 */ 1982 return error; 1983} 1984 1985int svr4_sys_send(td, uap) 1986 struct thread *td; 1987 struct svr4_sys_send_args *uap; 1988{ 1989 struct sendto_args sta; 1990 1991 sta.s = uap->s; 1992 sta.buf = uap->buf; 1993 sta.len = uap->len; 1994 sta.flags = uap->flags; 1995 sta.to = NULL; 1996 sta.tolen = 0; 1997 1998 return (sys_sendto(td, &sta)); 1999} 2000 2001int svr4_sys_recv(td, uap) 2002 struct thread *td; 2003 struct svr4_sys_recv_args *uap; 2004{ 2005 struct recvfrom_args rfa; 2006 2007 rfa.s = uap->s; 2008 rfa.buf = uap->buf; 2009 rfa.len = uap->len; 2010 rfa.flags = uap->flags; 2011 rfa.from = NULL; 2012 rfa.fromlenaddr = NULL; 2013 2014 return (sys_recvfrom(td, &rfa)); 2015} 2016 2017/* 2018 * XXX This isn't necessary, but it's handy for inserting debug code into 2019 * sendto(). Let's leave it here for now... 2020 */ 2021int 2022svr4_sys_sendto(td, uap) 2023 struct thread *td; 2024 struct svr4_sys_sendto_args *uap; 2025{ 2026 struct sendto_args sa; 2027 2028 sa.s = uap->s; 2029 sa.buf = uap->buf; 2030 sa.len = uap->len; 2031 sa.flags = uap->flags; 2032 sa.to = (caddr_t)uap->to; 2033 sa.tolen = uap->tolen; 2034 2035 DPRINTF(("calling sendto()\n")); 2036 return sys_sendto(td, &sa); 2037} 2038 2039