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