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