stream.c revision 561c7995d7524afbf92689593b9ba5f9615d0982
1/* 2 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com> 3 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * $Id$ 29 */ 30 31#include "defs.h" 32#include <sys/syscall.h> 33 34#ifdef HAVE_POLL_H 35#include <poll.h> 36#endif 37#ifdef HAVE_SYS_POLL_H 38#include <sys/poll.h> 39#endif 40#ifdef HAVE_STROPTS_H 41#include <stropts.h> 42#endif 43#ifdef HAVE_SYS_CONF_H 44#include <sys/conf.h> 45#endif 46#ifdef HAVE_SYS_STREAM_H 47#include <sys/stream.h> 48#endif 49#ifdef HAVE_SYS_TIHDR_H 50#include <sys/tihdr.h> 51#endif 52 53#if defined(HAVE_SYS_STREAM_H) || defined(LINUX) || defined(FREEBSD) 54 55#ifndef HAVE_STROPTS_H 56#define RS_HIPRI 1 57struct strbuf { 58 int maxlen; /* no. of bytes in buffer */ 59 int len; /* no. of bytes returned */ 60 char *buf; /* pointer to data */ 61}; 62#define MORECTL 1 63#define MOREDATA 2 64#endif /* !HAVE_STROPTS_H */ 65 66#ifdef HAVE_SYS_TIUSER_H 67#include <sys/tiuser.h> 68#include <sys/sockmod.h> 69#include <sys/timod.h> 70#endif /* HAVE_SYS_TIUSER_H */ 71 72#ifndef FREEBSD 73static struct xlat msgflags[] = { 74 { RS_HIPRI, "RS_HIPRI" }, 75 { 0, NULL }, 76}; 77 78 79static void 80printstrbuf(tcp, sbp, getting) 81struct tcb *tcp; 82struct strbuf *sbp; 83int getting; 84{ 85 if (sbp->maxlen == -1 && getting) 86 tprintf("{maxlen=-1}"); 87 else { 88 tprintf("{"); 89 if (getting) 90 tprintf("maxlen=%d, ", sbp->maxlen); 91 tprintf("len=%d, buf=", sbp->len); 92 printstr(tcp, (unsigned long) sbp->buf, sbp->len); 93 tprintf("}"); 94 } 95} 96 97static void 98printstrbufarg(tcp, arg, getting) 99struct tcb *tcp; 100int arg; 101int getting; 102{ 103 struct strbuf buf; 104 105 if (arg == 0) 106 tprintf("NULL"); 107 else if (umove(tcp, arg, &buf) < 0) 108 tprintf("{...}"); 109 else 110 printstrbuf(tcp, &buf, getting); 111 tprintf(", "); 112} 113 114int 115sys_putmsg(tcp) 116struct tcb *tcp; 117{ 118 int i; 119 120 if (entering(tcp)) { 121 /* fd */ 122 tprintf("%ld, ", tcp->u_arg[0]); 123 /* control and data */ 124 for (i = 1; i < 3; i++) 125 printstrbufarg(tcp, tcp->u_arg[i], 0); 126 /* flags */ 127 if (!printflags(msgflags, tcp->u_arg[3])) 128 tprintf("0"); 129 } 130 return 0; 131} 132 133int 134sys_getmsg(tcp) 135struct tcb *tcp; 136{ 137 int i, flags; 138 139 if (entering(tcp)) { 140 /* fd */ 141 tprintf("%lu, ", tcp->u_arg[0]); 142 } else { 143 if (syserror(tcp)) { 144 tprintf("%#lx, %#lx, %#lx", 145 tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]); 146 return 0; 147 } 148 /* control and data */ 149 for (i = 1; i < 3; i++) 150 printstrbufarg(tcp, tcp->u_arg[i], 1); 151 /* pointer to flags */ 152 if (tcp->u_arg[3] == 0) 153 tprintf("NULL"); 154 else if (umove(tcp, tcp->u_arg[3], &flags) < 0) 155 tprintf("[?]"); 156 else { 157 tprintf("["); 158 if (!printflags(msgflags, flags)) 159 tprintf("0"); 160 tprintf("]"); 161 } 162 /* decode return value */ 163 switch (tcp->u_rval) { 164 case MORECTL: 165 tcp->auxstr = "MORECTL"; 166 break; 167 case MORECTL|MOREDATA: 168 tcp->auxstr = "MORECTL|MOREDATA"; 169 break; 170 case MOREDATA: 171 tcp->auxstr = "MORECTL"; 172 break; 173 default: 174 tcp->auxstr = NULL; 175 break; 176 } 177 } 178 return RVAL_HEX | RVAL_STR; 179} 180 181#if defined SYS_putpmsg || defined SYS_getpmsg 182static struct xlat pmsgflags[] = { 183#ifdef MSG_HIPRI 184 { MSG_HIPRI, "MSG_HIPRI" }, 185#endif 186#ifdef MSG_AND 187 { MSG_ANY, "MSG_ANY" }, 188#endif 189#ifdef MSG_BAND 190 { MSG_BAND, "MSG_BAND" }, 191#endif 192 { 0, NULL }, 193}; 194#endif 195 196#ifdef SYS_putpmsg 197int 198sys_putpmsg(tcp) 199struct tcb *tcp; 200{ 201 int i; 202 203 if (entering(tcp)) { 204 /* fd */ 205 tprintf("%ld, ", tcp->u_arg[0]); 206 /* control and data */ 207 for (i = 1; i < 3; i++) 208 printstrbufarg(tcp, tcp->u_arg[i], 0); 209 /* band */ 210 tprintf("%ld, ", tcp->u_arg[3]); 211 /* flags */ 212 if (!printflags(pmsgflags, tcp->u_arg[4])) 213 tprintf("0"); 214 } 215 return 0; 216} 217#endif /* SYS_putpmsg */ 218 219#ifdef SYS_getpmsg 220int 221sys_getpmsg(tcp) 222struct tcb *tcp; 223{ 224 int i, flags; 225 226 if (entering(tcp)) { 227 /* fd */ 228 tprintf("%lu, ", tcp->u_arg[0]); 229 } else { 230 if (syserror(tcp)) { 231 tprintf("%#lx, %#lx, %#lx, %#lx", tcp->u_arg[1], 232 tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[4]); 233 return 0; 234 } 235 /* control and data */ 236 for (i = 1; i < 3; i++) 237 printstrbufarg(tcp, tcp->u_arg[i], 1); 238 /* pointer to band */ 239 printnum(tcp, tcp->u_arg[3], "%d"); 240 tprintf(", "); 241 /* pointer to flags */ 242 if (tcp->u_arg[4] == 0) 243 tprintf("NULL"); 244 else if (umove(tcp, tcp->u_arg[4], &flags) < 0) 245 tprintf("[?]"); 246 else { 247 tprintf("["); 248 if (!printflags(pmsgflags, flags)) 249 tprintf("0"); 250 tprintf("]"); 251 } 252 /* decode return value */ 253 switch (tcp->u_rval) { 254 case MORECTL: 255 tcp->auxstr = "MORECTL"; 256 break; 257 case MORECTL|MOREDATA: 258 tcp->auxstr = "MORECTL|MOREDATA"; 259 break; 260 case MOREDATA: 261 tcp->auxstr = "MORECTL"; 262 break; 263 default: 264 tcp->auxstr = NULL; 265 break; 266 } 267 } 268 return RVAL_HEX | RVAL_STR; 269} 270#endif /* SYS_getpmsg */ 271 272#endif /* !FREEBSD */ 273 274 275#ifdef HAVE_SYS_POLL_H 276 277static struct xlat pollflags[] = { 278#ifdef POLLIN 279 { POLLIN, "POLLIN" }, 280 { POLLPRI, "POLLPRI" }, 281 { POLLOUT, "POLLOUT" }, 282#ifdef POLLRDNORM 283 { POLLRDNORM, "POLLRDNORM" }, 284#endif 285#ifdef POLLWRNORM 286 { POLLWRNORM, "POLLWRNORM" }, 287#endif 288#ifdef POLLRDBAND 289 { POLLRDBAND, "POLLRDBAND" }, 290#endif 291#ifdef POLLWRBAND 292 { POLLWRBAND, "POLLWRBAND" }, 293#endif 294 { POLLERR, "POLLERR" }, 295 { POLLHUP, "POLLHUP" }, 296 { POLLNVAL, "POLLNVAL" }, 297#endif 298 { 0, NULL }, 299}; 300 301int 302sys_poll(tcp) 303struct tcb *tcp; 304{ 305 struct pollfd *pollp; 306 307 if (exiting(tcp)) { 308 int i; 309 int nfds = tcp->u_arg[1]; 310 311 if (nfds <= 0) { 312 tprintf("%#lx, %d, %ld\n", 313 tcp->u_arg[0], nfds, tcp->u_arg[2]); 314 return 0; 315 } 316 pollp = (struct pollfd *) malloc(nfds * sizeof(*pollp)); 317 if (pollp == NULL) { 318 fprintf(stderr, "sys_poll: no memory\n"); 319 tprintf("%#lx, %d, %ld", 320 tcp->u_arg[0], nfds, tcp->u_arg[2]); 321 return 0; 322 } 323 if (umoven(tcp, tcp->u_arg[0], 324 (nfds * sizeof(*pollp)), (char *) pollp) < 0) { 325 tprintf("%#lx", tcp->u_arg[0]); 326 } 327 else { 328 tprintf("["); 329 for (i = 0; i < nfds; i++) { 330 if (i) 331 tprintf(", "); 332 if (pollp[i].fd < 0) { 333 tprintf("{fd=%d}", pollp[i].fd); 334 continue; 335 } 336 tprintf("{fd=%d, events=", pollp[i].fd); 337 if (!printflags(pollflags, pollp[i].events)) 338 tprintf("0"); 339 if (!syserror(tcp) && pollp[i].revents) { 340 tprintf(", revents="); 341 if (!printflags(pollflags, 342 pollp[i].revents)) 343 tprintf("0"); 344 } 345 tprintf("}"); 346 } 347 tprintf("]"); 348 } 349 tprintf(", %d, ", nfds); 350#ifdef INFTIM 351 if (tcp->u_arg[2] == INFTIM) 352 tprintf("INFTIM"); 353 else 354#endif 355 tprintf("%ld", tcp->u_arg[2]); 356 free(pollp); 357 } 358 return 0; 359} 360 361#else /* !HAVE_SYS_POLL_H */ 362int 363sys_poll(tcp) 364struct tcb *tcp; 365{ 366 return 0; 367} 368#endif 369 370#if !defined(LINUX) && !defined(FREEBSD) 371 372static struct xlat stream_flush_options[] = { 373 { FLUSHR, "FLUSHR" }, 374 { FLUSHW, "FLUSHW" }, 375 { FLUSHRW, "FLUSHRW" }, 376#ifdef FLUSHBAND 377 { FLUSHBAND, "FLUSHBAND" }, 378#endif 379 { 0, NULL }, 380}; 381 382static struct xlat stream_setsig_flags[] = { 383 { S_INPUT, "S_INPUT" }, 384 { S_HIPRI, "S_HIPRI" }, 385 { S_OUTPUT, "S_OUTPUT" }, 386 { S_MSG, "S_MSG" }, 387#ifdef S_ERROR 388 { S_ERROR, "S_ERROR" }, 389#endif 390#ifdef S_HANGUP 391 { S_HANGUP, "S_HANGUP" }, 392#endif 393#ifdef S_RDNORM 394 { S_RDNORM, "S_RDNORM" }, 395#endif 396#ifdef S_WRNORM 397 { S_WRNORM, "S_WRNORM" }, 398#endif 399#ifdef S_RDBAND 400 { S_RDBAND, "S_RDBAND" }, 401#endif 402#ifdef S_WRBAND 403 { S_WRBAND, "S_WRBAND" }, 404#endif 405#ifdef S_BANDURG 406 { S_BANDURG, "S_BANDURG" }, 407#endif 408 { 0, NULL }, 409}; 410 411static struct xlat stream_read_options[] = { 412 { RNORM, "RNORM" }, 413 { RMSGD, "RMSGD" }, 414 { RMSGN, "RMSGN" }, 415 { 0, NULL }, 416}; 417 418static struct xlat stream_read_flags[] = { 419#ifdef RPROTDAT 420 { RPROTDAT, "RPROTDAT" }, 421#endif 422#ifdef RPROTDIS 423 { RPROTDIS, "RPROTDIS" }, 424#endif 425#ifdef RPROTNORM 426 { RPROTNORM, "RPROTNORM" }, 427#endif 428 { 0, NULL }, 429}; 430 431#ifndef RMODEMASK 432#define RMODEMASK (~0) 433#endif 434 435#ifdef I_SWROPT 436static struct xlat stream_write_flags[] = { 437 { SNDZERO, "SNDZERO" }, 438 { SNDPIPE, "SNDPIPE" }, 439 { 0, NULL }, 440}; 441#endif /* I_SWROPT */ 442 443#ifdef I_ATMARK 444static struct xlat stream_atmark_options[] = { 445 { ANYMARK, "ANYMARK" }, 446 { LASTMARK, "LASTMARK" }, 447 { 0, NULL }, 448}; 449#endif /* I_ATMARK */ 450 451#ifdef TI_BIND 452static struct xlat transport_user_options[] = { 453 { T_CONN_REQ, "T_CONN_REQ" }, 454 { T_CONN_RES, "T_CONN_RES" }, 455 { T_DISCON_REQ, "T_DISCON_REQ" }, 456 { T_DATA_REQ, "T_DATA_REQ" }, 457 { T_EXDATA_REQ, "T_EXDATA_REQ" }, 458 { T_INFO_REQ, "T_INFO_REQ" }, 459 { T_BIND_REQ, "T_BIND_REQ" }, 460 { T_UNBIND_REQ, "T_UNBIND_REQ" }, 461 { T_UNITDATA_REQ,"T_UNITDATA_REQ"}, 462 { T_OPTMGMT_REQ,"T_OPTMGMT_REQ" }, 463 { T_ORDREL_REQ, "T_ORDREL_REQ" }, 464 { 0, NULL }, 465}; 466 467static struct xlat transport_user_flags [] = { 468 { 0, "0" }, 469 { T_MORE, "T_MORE" }, 470 { T_EXPEDITED, "T_EXPEDITED" }, 471 { T_NEGOTIATE, "T_NEGOTIATE" }, 472 { T_CHECK, "T_CHECK" }, 473 { T_DEFAULT, "T_DEFAULT" }, 474 { T_SUCCESS, "T_SUCCESS" }, 475 { T_FAILURE, "T_FAILURE" }, 476 { T_CURRENT, "T_CURRENT" }, 477 { T_PARTSUCCESS,"T_PARTSUCCESS" }, 478 { T_READONLY, "T_READONLY" }, 479 { T_NOTSUPPORT, "T_NOTSUPPORT" }, 480 { 0, NULL }, 481}; 482 483 484#ifdef HAVE_STRUCT_T_OPTHDR 485 486static struct xlat xti_level [] = { 487 { XTI_GENERIC, "XTI_GENERIC" }, 488 { 0, NULL }, 489}; 490 491static struct xlat xti_generic [] = { 492 { XTI_DEBUG, "XTI_DEBUG" }, 493 { XTI_LINGER, "XTI_LINGER" }, 494 { XTI_RCVBUF, "XTI_RCVBUF" }, 495 { XTI_RCVLOWAT, "XTI_RCVLOWAT" }, 496 { XTI_SNDBUF, "XTI_SNDBUF" }, 497 { XTI_SNDLOWAT, "XTI_SNDLOWAT" }, 498 { 0, NULL }, 499}; 500 501 502 503void 504print_xti_optmgmt (tcp, addr, len) 505struct tcb *tcp; 506long addr; 507int len; 508{ 509 int c = 0; 510 struct t_opthdr hdr; 511 512 while (len >= (int) sizeof hdr) { 513 if (umove(tcp, addr, &hdr) < 0) break; 514 if (c++) { 515 tprintf (", "); 516 } 517 else if (len > hdr.len + sizeof hdr) { 518 tprintf ("["); 519 } 520 tprintf ("{level="); 521 printxval (xti_level, hdr.level, "???"); 522 tprintf (", name="); 523 switch (hdr.level) { 524 case XTI_GENERIC: 525 printxval (xti_generic, hdr.name, "XTI_???"); 526 break; 527 default: 528 tprintf ("%ld", hdr.name); 529 break; 530 } 531 tprintf (", status="); 532 printxval (transport_user_flags, hdr.status, "T_???"); 533 addr += sizeof hdr; 534 len -= sizeof hdr; 535 if ((hdr.len -= sizeof hdr) > 0) { 536 if (hdr.len > len) break; 537 tprintf (", val="); 538 if (len == sizeof (int)) 539 printnum (tcp, addr, "%d"); 540 else 541 printstr (tcp, addr, hdr.len); 542 addr += hdr.len; 543 len -= hdr.len; 544 } 545 tprintf ("}"); 546 } 547 if (len > 0) { 548 if (c++) tprintf (", "); 549 printstr (tcp, addr, len); 550 } 551 if (c > 1) tprintf ("]"); 552} 553 554#endif 555 556 557static void 558print_optmgmt (tcp, addr, len) 559struct tcb *tcp; 560long addr; 561int len; 562{ 563 /* We don't know how to tell if TLI (socket) or XTI 564 optmgmt is being used yet, assume TLI. */ 565#if defined (HAVE_STRUCT_OPTHDR) 566 print_sock_optmgmt (tcp, addr, len); 567#elif defined (HAVE_STRUCT_T_OPTHDR) 568 print_xti_optmgmt (tcp, addr, len); 569#else 570 printstr (tcp, addr, len); 571#endif 572} 573 574 575 576 577static struct xlat service_type [] = { 578 { T_COTS, "T_COTS" }, 579 { T_COTS_ORD, "T_COTS_ORD" }, 580 { T_CLTS, "T_CLTS" }, 581 { 0, NULL }, 582}; 583 584static struct xlat ts_state [] = { 585 { TS_UNBND, "TS_UNBND" }, 586 { TS_WACK_BREQ, "TS_WACK_BREQ" }, 587 { TS_WACK_UREQ, "TS_WACK_UREQ" }, 588 { TS_IDLE, "TS_IDLE" }, 589 { TS_WACK_OPTREQ,"TS_WACK_OPTREQ"}, 590 { TS_WACK_CREQ, "TS_WACK_CREQ" }, 591 { TS_WCON_CREQ, "TS_WCON_CREQ" }, 592 { TS_WRES_CIND, "TS_WRES_CIND" }, 593 { TS_WACK_CRES, "TS_WACK_CRES" }, 594 { TS_DATA_XFER, "TS_DATA_XFER" }, 595 { TS_WIND_ORDREL,"TS_WIND_ORDREL"}, 596 { TS_WREQ_ORDREL,"TS_WREQ_ORDREL"}, 597 { TS_WACK_DREQ6,"TS_WACK_DREQ6" }, 598 { TS_WACK_DREQ7,"TS_WACK_DREQ7" }, 599 { TS_WACK_DREQ9,"TS_WACK_DREQ9" }, 600 { TS_WACK_DREQ10,"TS_WACK_DREQ10"}, 601 { TS_WACK_DREQ11,"TS_WACK_DREQ11"}, 602 { 0, NULL }, 603}; 604 605static struct xlat provider_flags [] = { 606 { 0, "0" }, 607 { SENDZERO, "SENDZERO" }, 608 { EXPINLINE, "EXPINLINE" }, 609 { XPG4_1, "XPG4_1" }, 610 { 0, NULL }, 611}; 612 613 614static struct xlat tli_errors [] = { 615 { TBADADDR, "TBADADDR" }, 616 { TBADOPT, "TBADOPT" }, 617 { TACCES, "TACCES" }, 618 { TBADF, "TBADF" }, 619 { TNOADDR, "TNOADDR" }, 620 { TOUTSTATE, "TOUTSTATE" }, 621 { TBADSEQ, "TBADSEQ" }, 622 { TSYSERR, "TSYSERR" }, 623 { TLOOK, "TLOOK" }, 624 { TBADDATA, "TBADDATA" }, 625 { TBUFOVFLW, "TBUFOVFLW" }, 626 { TFLOW, "TFLOW" }, 627 { TNODATA, "TNODATA" }, 628 { TNODIS, "TNODIS" }, 629 { TNOUDERR, "TNOUDERR" }, 630 { TBADFLAG, "TBADFLAG" }, 631 { TNOREL, "TNOREL" }, 632 { TNOTSUPPORT, "TNOTSUPPORT" }, 633 { TSTATECHNG, "TSTATECHNG" }, 634 { TNOSTRUCTYPE, "TNOSTRUCTYPE" }, 635 { TBADNAME, "TBADNAME" }, 636 { TBADQLEN, "TBADQLEN" }, 637 { TADDRBUSY, "TADDRBUSY" }, 638 { TINDOUT, "TINDOUT" }, 639 { TPROVMISMATCH,"TPROVMISMATCH" }, 640 { TRESQLEN, "TRESQLEN" }, 641 { TRESADDR, "TRESADDR" }, 642 { TQFULL, "TQFULL" }, 643 { TPROTO, "TPROTO" }, 644 { 0, NULL }, 645}; 646 647 648static int 649print_transport_message (tcp, expect, addr, len) 650struct tcb *tcp; 651int expect; 652long addr; 653int len; 654{ 655 union T_primitives m; 656 int c = 0; 657 658 if (len < sizeof m.type) goto dump; 659 660 if (umove (tcp, addr, &m.type) < 0) goto dump; 661 662#define GET(type, struct) \ 663 do { \ 664 if (len < sizeof m.struct) goto dump; \ 665 if (umove (tcp, addr, &m.struct) < 0) goto dump;\ 666 tprintf ("{"); \ 667 if (expect != type) { \ 668 ++c; \ 669 tprintf (#type); \ 670 } \ 671 } \ 672 while (0) 673 674#define COMMA() \ 675 do { if (c++) tprintf (", "); } while (0) 676 677 678#define STRUCT(struct, elem, print) \ 679 do { \ 680 COMMA (); \ 681 if (m.struct.elem##_length < 0 || \ 682 m.struct.elem##_offset < sizeof m.struct || \ 683 m.struct.elem##_offset + m.struct.elem##_length > len) \ 684 { \ 685 tprintf (#elem "_length=%ld, " #elem "_offset=%ld",\ 686 m.struct.elem##_length, \ 687 m.struct.elem##_offset); \ 688 } \ 689 else { \ 690 tprintf (#elem "="); \ 691 print (tcp, \ 692 addr + m.struct.elem##_offset, \ 693 m.struct.elem##_length); \ 694 } \ 695 } \ 696 while (0) 697 698#define ADDR(struct, elem) STRUCT (struct, elem, printstr) 699 700 switch (m.type) { 701#ifdef T_CONN_REQ 702 case T_CONN_REQ: /* connect request */ 703 GET (T_CONN_REQ, conn_req); 704 ADDR (conn_req, DEST); 705 ADDR (conn_req, OPT); 706 break; 707#endif 708#ifdef T_CONN_RES 709 case T_CONN_RES: /* connect response */ 710 GET (T_CONN_RES, conn_res); 711#ifdef HAVE_STRUCT_T_CONN_RES_QUEUE_PTR 712 COMMA (); 713 tprintf ("QUEUE=%p", m.conn_res.QUEUE_ptr); 714#elif defined HAVE_STRUCT_T_CONN_RES_ACCEPTOR_ID 715 COMMA (); 716 tprintf ("ACCEPTOR=%#lx", m.conn_res.ACCEPTOR_id); 717#endif 718 ADDR (conn_res, OPT); 719 COMMA (); 720 tprintf ("SEQ=%ld", m.conn_res.SEQ_number); 721 break; 722#endif 723#ifdef T_DISCON_REQ 724 case T_DISCON_REQ: /* disconnect request */ 725 GET (T_DISCON_REQ, discon_req); 726 COMMA (); 727 tprintf ("SEQ=%ld", m.discon_req.SEQ_number); 728 break; 729#endif 730#ifdef T_DATA_REQ 731 case T_DATA_REQ: /* data request */ 732 GET (T_DATA_REQ, data_req); 733 COMMA (); 734 tprintf ("MORE=%ld", m.data_req.MORE_flag); 735 break; 736#endif 737#ifdef T_EXDATA_REQ 738 case T_EXDATA_REQ: /* expedited data req */ 739 GET (T_EXDATA_REQ, exdata_req); 740 COMMA (); 741 tprintf ("MORE=%ld", m.exdata_req.MORE_flag); 742 break; 743#endif 744#ifdef T_INFO_REQ 745 case T_INFO_REQ: /* information req */ 746 GET (T_INFO_REQ, info_req); 747 break; 748#endif 749#ifdef T_BIND_REQ 750 case T_BIND_REQ: /* bind request */ 751#ifdef O_T_BIND_REQ 752 case O_T_BIND_REQ: /* Ugly xti/tli hack */ 753#endif 754 GET (T_BIND_REQ, bind_req); 755 ADDR (bind_req, ADDR); 756 COMMA (); 757 tprintf ("CONIND=%ld", m.bind_req.CONIND_number); 758 break; 759#endif 760#ifdef T_UNBIND_REQ 761 case T_UNBIND_REQ: /* unbind request */ 762 GET (T_UNBIND_REQ, unbind_req); 763 break; 764#endif 765#ifdef T_UNITDATA_REQ 766 case T_UNITDATA_REQ: /* unitdata requset */ 767 GET (T_UNITDATA_REQ, unitdata_req); 768 ADDR (unitdata_req, DEST); 769 ADDR (unitdata_req, OPT); 770 break; 771#endif 772#ifdef T_OPTMGMT_REQ 773 case T_OPTMGMT_REQ: /* manage opt req */ 774 GET (T_OPTMGMT_REQ, optmgmt_req); 775 COMMA (); 776 tprintf ("MGMT="); 777 printflags (transport_user_flags, m.optmgmt_req.MGMT_flags); 778 STRUCT (optmgmt_req, OPT, print_optmgmt); 779 break; 780#endif 781#ifdef T_ORDREL_REQ 782 case T_ORDREL_REQ: /* orderly rel req */ 783 GET (T_ORDREL_REQ, ordrel_req); 784 break; 785#endif 786#ifdef T_CONN_IND 787 case T_CONN_IND: /* connect indication */ 788 GET (T_CONN_IND, conn_ind); 789 ADDR (conn_ind, SRC); 790 ADDR (conn_ind, OPT); 791 tprintf (", SEQ=%ld", m.conn_ind.SEQ_number); 792 break; 793#endif 794#ifdef T_CONN_CON 795 case T_CONN_CON: /* connect corfirm */ 796 GET (T_CONN_CON, conn_con); 797 ADDR (conn_con, RES); 798 ADDR (conn_con, OPT); 799 break; 800#endif 801#ifdef T_DISCON_IND 802 case T_DISCON_IND: /* discon indication */ 803 GET (T_DISCON_IND, discon_ind); 804 COMMA (); 805 tprintf ("DISCON=%ld, SEQ=%ld", 806 m.discon_ind.DISCON_reason, m.discon_ind.SEQ_number); 807 break; 808#endif 809#ifdef T_DATA_IND 810 case T_DATA_IND: /* data indication */ 811 GET (T_DATA_IND, data_ind); 812 COMMA (); 813 tprintf ("MORE=%ld", m.data_ind.MORE_flag); 814 break; 815#endif 816#ifdef T_EXDATA_IND 817 case T_EXDATA_IND: /* expedited data ind */ 818 GET (T_EXDATA_IND, exdata_ind); 819 COMMA (); 820 tprintf ("MORE=%ld", m.exdata_ind.MORE_flag); 821 break; 822#endif 823#ifdef T_INFO_ACK 824 case T_INFO_ACK: /* info ack */ 825 GET (T_INFO_ACK, info_ack); 826 COMMA (); 827 tprintf ("TSDU=%ld, ETSDU=%ld, CDATA=%ld, DDATA=%ld, " 828 "ADDR=%ld, OPT=%ld, TIDU=%ld, SERV=", 829 m.info_ack.TSDU_size, m.info_ack.ETSDU_size, 830 m.info_ack.CDATA_size, m.info_ack.DDATA_size, 831 m.info_ack.ADDR_size, m.info_ack.OPT_size, 832 m.info_ack.TIDU_size); 833 printxval (service_type, m.info_ack.SERV_type, "T_???"); 834 tprintf (", CURRENT="); 835 printxval (ts_state, m.info_ack.CURRENT_state, "TS_???"); 836 tprintf (", PROVIDER="); 837 printflags (provider_flags, m.info_ack.PROVIDER_flag); 838 break; 839#endif 840#ifdef T_BIND_ACK 841 case T_BIND_ACK: /* bind ack */ 842 GET (T_BIND_ACK, bind_ack); 843 ADDR (bind_ack, ADDR); 844 tprintf (", CONIND=%ld", m.bind_ack.CONIND_number); 845 break; 846#endif 847#ifdef T_ERROR_ACK 848 case T_ERROR_ACK: /* error ack */ 849 GET (T_ERROR_ACK, error_ack); 850 COMMA (); 851 tprintf ("ERROR="); 852 printxval (transport_user_options, 853 m.error_ack.ERROR_prim, "TI_???"); 854 tprintf (", TLI="); 855 printxval (tli_errors, m.error_ack.TLI_error, "T???"); 856 tprintf ("UNIX=%s", strerror (m.error_ack.UNIX_error)); 857 break; 858#endif 859#ifdef T_OK_ACK 860 case T_OK_ACK: /* ok ack */ 861 GET (T_OK_ACK, ok_ack); 862 COMMA (); 863 tprintf ("CORRECT="); 864 printxval (transport_user_options, 865 m.ok_ack.CORRECT_prim, "TI_???"); 866 break; 867#endif 868#ifdef T_UNITDATA_IND 869 case T_UNITDATA_IND: /* unitdata ind */ 870 GET (T_UNITDATA_IND, unitdata_ind); 871 ADDR (unitdata_ind, SRC); 872 ADDR (unitdata_ind, OPT); 873 break; 874#endif 875#ifdef T_UDERROR_IND 876 case T_UDERROR_IND: /* unitdata error ind */ 877 GET (T_UDERROR_IND, uderror_ind); 878 ADDR (uderror_ind, DEST); 879 ADDR (uderror_ind, OPT); 880 tprintf (", ERROR=%ld", m.uderror_ind.ERROR_type); 881 break; 882#endif 883#ifdef T_OPTMGMT_ACK 884 case T_OPTMGMT_ACK: /* manage opt ack */ 885 GET (T_OPTMGMT_ACK, optmgmt_ack); 886 COMMA (); 887 tprintf ("MGMT="); 888 printflags (transport_user_flags, m.optmgmt_ack.MGMT_flags); 889 STRUCT (optmgmt_ack, OPT, print_optmgmt); 890 break; 891#endif 892#ifdef T_ORDREL_IND 893 case T_ORDREL_IND: /* orderly rel ind */ 894 GET (T_ORDREL_IND, ordrel_ind); 895 break; 896#endif 897#ifdef T_ADDR_REQ 898 case T_ADDR_REQ: /* address req */ 899 GET (T_ADDR_REQ, addr_req); 900 break; 901#endif 902#ifdef T_ADDR_ACK 903 case T_ADDR_ACK: /* address response */ 904 GET (T_ADDR_ACK, addr_ack); 905 ADDR (addr_ack, LOCADDR); 906 ADDR (addr_ack, REMADDR); 907 break; 908#endif 909 default: 910 dump: 911 c = -1; 912 printstr(tcp, addr, len); 913 break; 914 } 915 916 if (c >= 0) tprintf ("}"); 917 918#undef ADDR 919#undef COMMA 920#undef STRUCT 921 922 return 0; 923} 924 925 926#endif /* TI_BIND */ 927 928 929static int 930internal_stream_ioctl(tcp, arg) 931struct tcb *tcp; 932int arg; 933{ 934 struct strioctl si; 935 char *name; 936 int in_and_out; 937 int timod = 0; 938#ifdef SI_GETUDATA 939 struct si_udata udata; 940#endif /* SI_GETUDATA */ 941 942 if (!arg) 943 return 0; 944 if (umove(tcp, arg, &si) < 0) { 945 if (entering(tcp)) 946 tprintf(", {...}"); 947 return 1; 948 } 949 if (entering(tcp)) { 950 name = ioctl_lookup(si.ic_cmd); 951 if (name) 952 tprintf(", {ic_cmd=%s", name); 953 else 954 tprintf(", {ic_cmd=%#x", si.ic_cmd); 955 if (si.ic_timout == INFTIM) 956 tprintf(", ic_timout=INFTIM, "); 957 else 958 tprintf(" ic_timout=%d, ", si.ic_timout); 959 } 960 in_and_out = 1; 961 switch (si.ic_cmd) { 962#ifdef SI_GETUDATA 963 case SI_GETUDATA: 964 in_and_out = 0; 965 break; 966#endif /* SI_GETUDATA */ 967 } 968 if (in_and_out) { 969 if (entering(tcp)) 970 tprintf("/* in */ "); 971 else 972 tprintf(", /* out */ "); 973 } 974 if (in_and_out || entering(tcp)) 975 tprintf("ic_len=%d, ic_dp=", si.ic_len); 976 switch (si.ic_cmd) { 977#ifdef TI_BIND 978 case TI_BIND: 979 /* in T_BIND_REQ, out T_BIND_ACK */ 980 ++timod; 981 if (entering(tcp)) { 982 print_transport_message (tcp, 983 T_BIND_REQ, 984 si.ic_dp, si.ic_len); 985 } 986 else { 987 print_transport_message (tcp, 988 T_BIND_ACK, 989 si.ic_dp, si.ic_len); 990 } 991 break; 992#endif /* TI_BIND */ 993#ifdef TI_UNBIND 994 case TI_UNBIND: 995 /* in T_UNBIND_REQ, out T_OK_ACK */ 996 ++timod; 997 if (entering(tcp)) { 998 print_transport_message (tcp, 999 T_UNBIND_REQ, 1000 si.ic_dp, si.ic_len); 1001 } 1002 else { 1003 print_transport_message (tcp, 1004 T_OK_ACK, 1005 si.ic_dp, si.ic_len); 1006 } 1007 break; 1008#endif /* TI_UNBIND */ 1009#ifdef TI_GETINFO 1010 case TI_GETINFO: 1011 /* in T_INFO_REQ, out T_INFO_ACK */ 1012 ++timod; 1013 if (entering(tcp)) { 1014 print_transport_message (tcp, 1015 T_INFO_REQ, 1016 si.ic_dp, si.ic_len); 1017 } 1018 else { 1019 print_transport_message (tcp, 1020 T_INFO_ACK, 1021 si.ic_dp, si.ic_len); 1022 } 1023 break; 1024#endif /* TI_GETINFO */ 1025#ifdef TI_OPTMGMT 1026 case TI_OPTMGMT: 1027 /* in T_OPTMGMT_REQ, out T_OPTMGMT_ACK */ 1028 ++timod; 1029 if (entering(tcp)) { 1030 print_transport_message (tcp, 1031 T_OPTMGMT_REQ, 1032 si.ic_dp, si.ic_len); 1033 } 1034 else { 1035 print_transport_message (tcp, 1036 T_OPTMGMT_ACK, 1037 si.ic_dp, si.ic_len); 1038 } 1039 break; 1040#endif /* TI_OPTMGMT */ 1041#ifdef SI_GETUDATA 1042 case SI_GETUDATA: 1043 if (entering(tcp)) 1044 break; 1045#if 0 1046 tprintf("struct si_udata "); 1047#endif 1048 if (umove(tcp, (int) si.ic_dp, &udata) < 0) 1049 tprintf("{...}"); 1050 else { 1051 tprintf("{tidusize=%d, addrsize=%d, ", 1052 udata.tidusize, udata.addrsize); 1053 tprintf("optsize=%d, etsdusize=%d, ", 1054 udata.optsize, udata.etsdusize); 1055 tprintf("servtype=%d, so_state=%d, ", 1056 udata.servtype, udata.so_state); 1057 tprintf("so_options=%d", udata.so_options); 1058#if 0 1059 tprintf(", tsdusize=%d", udata.tsdusize); 1060#endif 1061 tprintf("}"); 1062 } 1063 break; 1064#endif /* SI_GETUDATA */ 1065 default: 1066 printstr(tcp, (long) si.ic_dp, si.ic_len); 1067 break; 1068 } 1069 if (exiting(tcp)) { 1070 tprintf("}"); 1071 if (timod && tcp->u_rval) { 1072 tcp->auxstr = xlookup (tli_errors, tcp->u_rval); 1073 return RVAL_STR + 1; 1074 } 1075 } 1076 1077 return 1; 1078} 1079 1080int 1081stream_ioctl(tcp, code, arg) 1082struct tcb *tcp; 1083int code, arg; 1084{ 1085#ifdef I_LIST 1086 int i; 1087#endif 1088 int val; 1089#ifdef I_FLUSHBAND 1090 struct bandinfo bi; 1091#endif 1092 struct strpeek sp; 1093 struct strfdinsert sfi; 1094 struct strrecvfd srf; 1095#ifdef I_LIST 1096 struct str_list sl; 1097#endif 1098 1099 /* I_STR is a special case because the data is read & written. */ 1100 if (code == I_STR) 1101 return internal_stream_ioctl(tcp, arg); 1102 if (entering(tcp)) 1103 return 0; 1104 1105 switch (code) { 1106 case I_PUSH: 1107 case I_LOOK: 1108 case I_FIND: 1109 /* arg is a string */ 1110 tprintf(", "); 1111 printpath(tcp, arg); 1112 return 1; 1113 case I_POP: 1114 /* doesn't take an argument */ 1115 return 1; 1116 case I_FLUSH: 1117 /* argument is an option */ 1118 tprintf(", "); 1119 printxval(stream_flush_options, arg, "FLUSH???"); 1120 return 1; 1121#ifdef I_FLUSHBAND 1122 case I_FLUSHBAND: 1123 /* argument is a pointer to a bandinfo struct */ 1124 if (umove(tcp, arg, &bi) < 0) 1125 tprintf(", {...}"); 1126 else { 1127 tprintf(", {bi_pri=%d, bi_flag=", bi.bi_pri); 1128 if (!printflags(stream_flush_options, bi.bi_flag)) 1129 tprintf("0"); 1130 tprintf("}"); 1131 } 1132 return 1; 1133#endif /* I_FLUSHBAND */ 1134 case I_SETSIG: 1135 /* argument is a set of flags */ 1136 tprintf(", "); 1137 if (!printflags(stream_setsig_flags, arg)) 1138 tprintf("0"); 1139 return 1; 1140 case I_GETSIG: 1141 /* argument is a pointer to a set of flags */ 1142 if (syserror(tcp)) 1143 return 0; 1144 tprintf(", ["); 1145 if (umove(tcp, arg, &val) < 0) 1146 tprintf("?"); 1147 else if (!printflags(stream_setsig_flags, val)) 1148 tprintf("0"); 1149 tprintf("]"); 1150 return 1; 1151 case I_PEEK: 1152 /* argument is a pointer to a strpeek structure */ 1153 if (syserror(tcp) || !arg) 1154 return 0; 1155 if (umove(tcp, arg, &sp) < 0) { 1156 tprintf(", {...}"); 1157 return 1; 1158 } 1159 tprintf(", {ctlbuf="); 1160 printstrbuf(tcp, &sp.ctlbuf, 1); 1161 tprintf(", databuf="); 1162 printstrbuf(tcp, &sp.databuf, 1); 1163 tprintf(", flags="); 1164 if (!printflags(msgflags, sp.flags)) 1165 tprintf("0"); 1166 tprintf("}"); 1167 return 1; 1168 case I_SRDOPT: 1169 /* argument is an option with flags */ 1170 tprintf(", "); 1171 printxval(stream_read_options, arg & RMODEMASK, "R???"); 1172 addflags(stream_read_flags, arg & ~RMODEMASK); 1173 return 1; 1174 case I_GRDOPT: 1175 /* argument is an pointer to an option with flags */ 1176 if (syserror(tcp)) 1177 return 0; 1178 tprintf(", ["); 1179 if (umove(tcp, arg, &val) < 0) 1180 tprintf("?"); 1181 else { 1182 printxval(stream_read_options, 1183 arg & RMODEMASK, "R???"); 1184 addflags(stream_read_flags, arg & ~RMODEMASK); 1185 } 1186 tprintf("]"); 1187 return 1; 1188 case I_NREAD: 1189#ifdef I_GETBAND 1190 case I_GETBAND: 1191#endif 1192#ifdef I_SETCLTIME 1193 case I_SETCLTIME: 1194#endif 1195#ifdef I_GETCLTIME 1196 case I_GETCLTIME: 1197#endif 1198 /* argument is a pointer to a decimal integer */ 1199 if (syserror(tcp)) 1200 return 0; 1201 tprintf(", "); 1202 printnum(tcp, arg, "%d"); 1203 return 1; 1204 case I_FDINSERT: 1205 /* argument is a pointer to a strfdinsert structure */ 1206 if (syserror(tcp) || !arg) 1207 return 0; 1208 if (umove(tcp, arg, &sfi) < 0) { 1209 tprintf(", {...}"); 1210 return 1; 1211 } 1212 tprintf(", {ctlbuf="); 1213 printstrbuf(tcp, &sfi.ctlbuf, 1); 1214 tprintf(", databuf="); 1215 printstrbuf(tcp, &sfi.databuf, 1); 1216 tprintf(", flags="); 1217 if (!printflags(msgflags, sfi.flags)) 1218 tprintf("0"); 1219 tprintf(", filedes=%d, offset=%d}", sfi.fildes, sfi.offset); 1220 return 1; 1221#ifdef I_SWROPT 1222 case I_SWROPT: 1223 /* argument is a set of flags */ 1224 tprintf(", "); 1225 if (!printflags(stream_write_flags, arg)) 1226 tprintf("0"); 1227 return 1; 1228#endif /* I_SWROPT */ 1229#ifdef I_GWROPT 1230 case I_GWROPT: 1231 /* argument is an pointer to an option with flags */ 1232 if (syserror(tcp)) 1233 return 0; 1234 tprintf(", ["); 1235 if (umove(tcp, arg, &val) < 0) 1236 tprintf("?"); 1237 else if (!printflags(stream_write_flags, arg)) 1238 tprintf("0"); 1239 tprintf("]"); 1240 return 1; 1241#endif /* I_GWROPT */ 1242 case I_SENDFD: 1243#ifdef I_CKBAND 1244 case I_CKBAND: 1245#endif 1246#ifdef I_CANPUT 1247 case I_CANPUT: 1248#endif 1249 case I_LINK: 1250 case I_UNLINK: 1251 case I_PLINK: 1252 case I_PUNLINK: 1253 /* argument is a decimal integer */ 1254 tprintf(", %d", arg); 1255 return 1; 1256 case I_RECVFD: 1257 /* argument is a pointer to a strrecvfd structure */ 1258 if (syserror(tcp) || !arg) 1259 return 0; 1260 if (umove(tcp, arg, &srf) < 0) { 1261 tprintf(", {...}"); 1262 return 1; 1263 } 1264 tprintf(", {fd=%d, uid=%lu, gid=%lu}", srf.fd, 1265 (unsigned long) srf.uid, (unsigned long) srf.gid); 1266 return 1; 1267#ifdef I_LIST 1268 case I_LIST: 1269 if (syserror(tcp)) 1270 return 0; 1271 if (arg == 0) { 1272 tprintf(", NULL"); 1273 return 1; 1274 } 1275 if (umove(tcp, arg, &sl) < 0) { 1276 tprintf(", {...}"); 1277 return 1; 1278 } 1279 tprintf(", {sl_nmods=%d, sl_modlist=[", sl.sl_nmods); 1280 for (i = 0; i < tcp->u_rval; i++) { 1281 if (i) 1282 tprintf(", "); 1283 printpath(tcp, (int) sl.sl_modlist[i].l_name); 1284 } 1285 tprintf("]}"); 1286 return 1; 1287#endif /* I_LIST */ 1288#ifdef I_ATMARK 1289 case I_ATMARK: 1290 tprintf(", "); 1291 printxval(stream_atmark_options, arg, "???MARK"); 1292 return 1; 1293#endif /* I_ATMARK */ 1294 default: 1295 return 0; 1296 } 1297} 1298 1299#endif /* !LINUX && !FREEBSD */ 1300 1301#endif /* HAVE_SYS_STREAM_H || LINUX || FREEBSD */ 1302