stream.c revision 6d2b34971b33d379c89c36c5ad1b0c6d5d12c453
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 COMMA (); 712 tprintf ("QUEUE=%p", m.conn_res.QUEUE_ptr); 713 ADDR (conn_res, OPT); 714 COMMA (); 715 tprintf ("SEQ=%ld", m.conn_res.SEQ_number); 716 break; 717#endif 718#ifdef T_DISCON_REQ 719 case T_DISCON_REQ: /* disconnect request */ 720 GET (T_DISCON_REQ, discon_req); 721 COMMA (); 722 tprintf ("SEQ=%ld", m.discon_req.SEQ_number); 723 break; 724#endif 725#ifdef T_DATA_REQ 726 case T_DATA_REQ: /* data request */ 727 GET (T_DATA_REQ, data_req); 728 COMMA (); 729 tprintf ("MORE=%ld", m.data_req.MORE_flag); 730 break; 731#endif 732#ifdef T_EXDATA_REQ 733 case T_EXDATA_REQ: /* expedited data req */ 734 GET (T_EXDATA_REQ, exdata_req); 735 COMMA (); 736 tprintf ("MORE=%ld", m.exdata_req.MORE_flag); 737 break; 738#endif 739#ifdef T_INFO_REQ 740 case T_INFO_REQ: /* information req */ 741 GET (T_INFO_REQ, info_req); 742 break; 743#endif 744#ifdef T_BIND_REQ 745 case T_BIND_REQ: /* bind request */ 746#ifdef O_T_BIND_REQ 747 case O_T_BIND_REQ: /* Ugly xti/tli hack */ 748#endif 749 GET (T_BIND_REQ, bind_req); 750 ADDR (bind_req, ADDR); 751 COMMA (); 752 tprintf ("CONIND=%ld", m.bind_req.CONIND_number); 753 break; 754#endif 755#ifdef T_UNBIND_REQ 756 case T_UNBIND_REQ: /* unbind request */ 757 GET (T_UNBIND_REQ, unbind_req); 758 break; 759#endif 760#ifdef T_UNITDATA_REQ 761 case T_UNITDATA_REQ: /* unitdata requset */ 762 GET (T_UNITDATA_REQ, unitdata_req); 763 ADDR (unitdata_req, DEST); 764 ADDR (unitdata_req, OPT); 765 break; 766#endif 767#ifdef T_OPTMGMT_REQ 768 case T_OPTMGMT_REQ: /* manage opt req */ 769 GET (T_OPTMGMT_REQ, optmgmt_req); 770 COMMA (); 771 tprintf ("MGMT="); 772 printflags (transport_user_flags, m.optmgmt_req.MGMT_flags); 773 STRUCT (optmgmt_req, OPT, print_optmgmt); 774 break; 775#endif 776#ifdef T_ORDREL_REQ 777 case T_ORDREL_REQ: /* orderly rel req */ 778 GET (T_ORDREL_REQ, ordrel_req); 779 break; 780#endif 781#ifdef T_CONN_IND 782 case T_CONN_IND: /* connect indication */ 783 GET (T_CONN_IND, conn_ind); 784 ADDR (conn_ind, SRC); 785 ADDR (conn_ind, OPT); 786 tprintf (", SEQ=%ld", m.conn_ind.SEQ_number); 787 break; 788#endif 789#ifdef T_CONN_CON 790 case T_CONN_CON: /* connect corfirm */ 791 GET (T_CONN_CON, conn_con); 792 ADDR (conn_con, RES); 793 ADDR (conn_con, OPT); 794 break; 795#endif 796#ifdef T_DISCON_IND 797 case T_DISCON_IND: /* discon indication */ 798 GET (T_DISCON_IND, discon_ind); 799 COMMA (); 800 tprintf ("DISCON=%ld, SEQ=%ld", 801 m.discon_ind.DISCON_reason, m.discon_ind.SEQ_number); 802 break; 803#endif 804#ifdef T_DATA_IND 805 case T_DATA_IND: /* data indication */ 806 GET (T_DATA_IND, data_ind); 807 COMMA (); 808 tprintf ("MORE=%ld", m.data_ind.MORE_flag); 809 break; 810#endif 811#ifdef T_EXDATA_IND 812 case T_EXDATA_IND: /* expedited data ind */ 813 GET (T_EXDATA_IND, exdata_ind); 814 COMMA (); 815 tprintf ("MORE=%ld", m.exdata_ind.MORE_flag); 816 break; 817#endif 818#ifdef T_INFO_ACK 819 case T_INFO_ACK: /* info ack */ 820 GET (T_INFO_ACK, info_ack); 821 COMMA (); 822 tprintf ("TSDU=%ld, ETSDU=%ld, CDATA=%ld, DDATA=%ld, " 823 "ADDR=%ld, OPT=%ld, TIDU=%ld, SERV=", 824 m.info_ack.TSDU_size, m.info_ack.ETSDU_size, 825 m.info_ack.CDATA_size, m.info_ack.DDATA_size, 826 m.info_ack.ADDR_size, m.info_ack.OPT_size, 827 m.info_ack.TIDU_size); 828 printxval (service_type, m.info_ack.SERV_type, "T_???"); 829 tprintf (", CURRENT="); 830 printxval (ts_state, m.info_ack.CURRENT_state, "TS_???"); 831 tprintf (", PROVIDER="); 832 printflags (provider_flags, m.info_ack.PROVIDER_flag); 833 break; 834#endif 835#ifdef T_BIND_ACK 836 case T_BIND_ACK: /* bind ack */ 837 GET (T_BIND_ACK, bind_ack); 838 ADDR (bind_ack, ADDR); 839 tprintf (", CONIND=%ld", m.bind_ack.CONIND_number); 840 break; 841#endif 842#ifdef T_ERROR_ACK 843 case T_ERROR_ACK: /* error ack */ 844 GET (T_ERROR_ACK, error_ack); 845 COMMA (); 846 tprintf ("ERROR="); 847 printxval (transport_user_options, 848 m.error_ack.ERROR_prim, "TI_???"); 849 tprintf (", TLI="); 850 printxval (tli_errors, m.error_ack.TLI_error, "T???"); 851 tprintf ("UNIX=%s", strerror (m.error_ack.UNIX_error)); 852 break; 853#endif 854#ifdef T_OK_ACK 855 case T_OK_ACK: /* ok ack */ 856 GET (T_OK_ACK, ok_ack); 857 COMMA (); 858 tprintf ("CORRECT="); 859 printxval (transport_user_options, 860 m.ok_ack.CORRECT_prim, "TI_???"); 861 break; 862#endif 863#ifdef T_UNITDATA_IND 864 case T_UNITDATA_IND: /* unitdata ind */ 865 GET (T_UNITDATA_IND, unitdata_ind); 866 ADDR (unitdata_ind, SRC); 867 ADDR (unitdata_ind, OPT); 868 break; 869#endif 870#ifdef T_UDERROR_IND 871 case T_UDERROR_IND: /* unitdata error ind */ 872 GET (T_UDERROR_IND, uderror_ind); 873 ADDR (uderror_ind, DEST); 874 ADDR (uderror_ind, OPT); 875 tprintf (", ERROR=%ld", m.uderror_ind.ERROR_type); 876 break; 877#endif 878#ifdef T_OPTMGMT_ACK 879 case T_OPTMGMT_ACK: /* manage opt ack */ 880 GET (T_OPTMGMT_ACK, optmgmt_ack); 881 COMMA (); 882 tprintf ("MGMT="); 883 printflags (transport_user_flags, m.optmgmt_ack.MGMT_flags); 884 STRUCT (optmgmt_ack, OPT, print_optmgmt); 885 break; 886#endif 887#ifdef T_ORDREL_IND 888 case T_ORDREL_IND: /* orderly rel ind */ 889 GET (T_ORDREL_IND, ordrel_ind); 890 break; 891#endif 892#ifdef T_ADDR_REQ 893 case T_ADDR_REQ: /* address req */ 894 GET (T_ADDR_REQ, addr_req); 895 break; 896#endif 897#ifdef T_ADDR_ACK 898 case T_ADDR_ACK: /* address response */ 899 GET (T_ADDR_ACK, addr_ack); 900 ADDR (addr_ack, LOCADDR); 901 ADDR (addr_ack, REMADDR); 902 break; 903#endif 904 default: 905 dump: 906 c = -1; 907 printstr(tcp, addr, len); 908 break; 909 } 910 911 if (c >= 0) tprintf ("}"); 912 913#undef ADDR 914#undef COMMA 915#undef STRUCT 916 917 return 0; 918} 919 920 921#endif /* TI_BIND */ 922 923 924static int 925internal_stream_ioctl(tcp, arg) 926struct tcb *tcp; 927int arg; 928{ 929 struct strioctl si; 930 char *name; 931 int in_and_out; 932 int timod = 0; 933#ifdef SI_GETUDATA 934 struct si_udata udata; 935#endif /* SI_GETUDATA */ 936 937 if (!arg) 938 return 0; 939 if (umove(tcp, arg, &si) < 0) { 940 if (entering(tcp)) 941 tprintf(", {...}"); 942 return 1; 943 } 944 if (entering(tcp)) { 945 name = ioctl_lookup(si.ic_cmd); 946 if (name) 947 tprintf(", {ic_cmd=%s", name); 948 else 949 tprintf(", {ic_cmd=%#x", si.ic_cmd); 950 if (si.ic_timout == INFTIM) 951 tprintf(", ic_timout=INFTIM, "); 952 else 953 tprintf(" ic_timout=%d, ", si.ic_timout); 954 } 955 in_and_out = 1; 956 switch (si.ic_cmd) { 957#ifdef SI_GETUDATA 958 case SI_GETUDATA: 959 in_and_out = 0; 960 break; 961#endif /* SI_GETUDATA */ 962 } 963 if (in_and_out) { 964 if (entering(tcp)) 965 tprintf("/* in */ "); 966 else 967 tprintf(", /* out */ "); 968 } 969 if (in_and_out || entering(tcp)) 970 tprintf("ic_len=%d, ic_dp=", si.ic_len); 971 switch (si.ic_cmd) { 972#ifdef TI_BIND 973 case TI_BIND: 974 /* in T_BIND_REQ, out T_BIND_ACK */ 975 ++timod; 976 if (entering(tcp)) { 977 print_transport_message (tcp, 978 T_BIND_REQ, 979 si.ic_dp, si.ic_len); 980 } 981 else { 982 print_transport_message (tcp, 983 T_BIND_ACK, 984 si.ic_dp, si.ic_len); 985 } 986 break; 987#endif /* TI_BIND */ 988#ifdef TI_UNBIND 989 case TI_UNBIND: 990 /* in T_UNBIND_REQ, out T_OK_ACK */ 991 ++timod; 992 if (entering(tcp)) { 993 print_transport_message (tcp, 994 T_UNBIND_REQ, 995 si.ic_dp, si.ic_len); 996 } 997 else { 998 print_transport_message (tcp, 999 T_OK_ACK, 1000 si.ic_dp, si.ic_len); 1001 } 1002 break; 1003#endif /* TI_UNBIND */ 1004#ifdef TI_GETINFO 1005 case TI_GETINFO: 1006 /* in T_INFO_REQ, out T_INFO_ACK */ 1007 ++timod; 1008 if (entering(tcp)) { 1009 print_transport_message (tcp, 1010 T_INFO_REQ, 1011 si.ic_dp, si.ic_len); 1012 } 1013 else { 1014 print_transport_message (tcp, 1015 T_INFO_ACK, 1016 si.ic_dp, si.ic_len); 1017 } 1018 break; 1019#endif /* TI_GETINFO */ 1020#ifdef TI_OPTMGMT 1021 case TI_OPTMGMT: 1022 /* in T_OPTMGMT_REQ, out T_OPTMGMT_ACK */ 1023 ++timod; 1024 if (entering(tcp)) { 1025 print_transport_message (tcp, 1026 T_OPTMGMT_REQ, 1027 si.ic_dp, si.ic_len); 1028 } 1029 else { 1030 print_transport_message (tcp, 1031 T_OPTMGMT_ACK, 1032 si.ic_dp, si.ic_len); 1033 } 1034 break; 1035#endif /* TI_OPTMGMT */ 1036#ifdef SI_GETUDATA 1037 case SI_GETUDATA: 1038 if (entering(tcp)) 1039 break; 1040#if 0 1041 tprintf("struct si_udata "); 1042#endif 1043 if (umove(tcp, (int) si.ic_dp, &udata) < 0) 1044 tprintf("{...}"); 1045 else { 1046 tprintf("{tidusize=%d, addrsize=%d, ", 1047 udata.tidusize, udata.addrsize); 1048 tprintf("optsize=%d, etsdusize=%d, ", 1049 udata.optsize, udata.etsdusize); 1050 tprintf("servtype=%d, so_state=%d, ", 1051 udata.servtype, udata.so_state); 1052 tprintf("so_options=%d", udata.so_options); 1053#if 0 1054 tprintf(", tsdusize=%d", udata.tsdusize); 1055#endif 1056 tprintf("}"); 1057 } 1058 break; 1059#endif /* SI_GETUDATA */ 1060 default: 1061 printstr(tcp, (long) si.ic_dp, si.ic_len); 1062 break; 1063 } 1064 if (exiting(tcp)) { 1065 tprintf("}"); 1066 if (timod && tcp->u_rval) { 1067 tcp->auxstr = xlookup (tli_errors, tcp->u_rval); 1068 return RVAL_STR + 1; 1069 } 1070 } 1071 1072 return 1; 1073} 1074 1075int 1076stream_ioctl(tcp, code, arg) 1077struct tcb *tcp; 1078int code, arg; 1079{ 1080#ifdef I_LIST 1081 int i; 1082#endif 1083 int val; 1084#ifdef I_FLUSHBAND 1085 struct bandinfo bi; 1086#endif 1087 struct strpeek sp; 1088 struct strfdinsert sfi; 1089 struct strrecvfd srf; 1090#ifdef I_LIST 1091 struct str_list sl; 1092#endif 1093 1094 /* I_STR is a special case because the data is read & written. */ 1095 if (code == I_STR) 1096 return internal_stream_ioctl(tcp, arg); 1097 if (entering(tcp)) 1098 return 0; 1099 1100 switch (code) { 1101 case I_PUSH: 1102 case I_LOOK: 1103 case I_FIND: 1104 /* arg is a string */ 1105 tprintf(", "); 1106 printpath(tcp, arg); 1107 return 1; 1108 case I_POP: 1109 /* doesn't take an argument */ 1110 return 1; 1111 case I_FLUSH: 1112 /* argument is an option */ 1113 tprintf(", "); 1114 printxval(stream_flush_options, arg, "FLUSH???"); 1115 return 1; 1116#ifdef I_FLUSHBAND 1117 case I_FLUSHBAND: 1118 /* argument is a pointer to a bandinfo struct */ 1119 if (umove(tcp, arg, &bi) < 0) 1120 tprintf(", {...}"); 1121 else { 1122 tprintf(", {bi_pri=%d, bi_flag=", bi.bi_pri); 1123 if (!printflags(stream_flush_options, bi.bi_flag)) 1124 tprintf("0"); 1125 tprintf("}"); 1126 } 1127 return 1; 1128#endif /* I_FLUSHBAND */ 1129 case I_SETSIG: 1130 /* argument is a set of flags */ 1131 tprintf(", "); 1132 if (!printflags(stream_setsig_flags, arg)) 1133 tprintf("0"); 1134 return 1; 1135 case I_GETSIG: 1136 /* argument is a pointer to a set of flags */ 1137 if (syserror(tcp)) 1138 return 0; 1139 tprintf(", ["); 1140 if (umove(tcp, arg, &val) < 0) 1141 tprintf("?"); 1142 else if (!printflags(stream_setsig_flags, val)) 1143 tprintf("0"); 1144 tprintf("]"); 1145 return 1; 1146 case I_PEEK: 1147 /* argument is a pointer to a strpeek structure */ 1148 if (syserror(tcp) || !arg) 1149 return 0; 1150 if (umove(tcp, arg, &sp) < 0) { 1151 tprintf(", {...}"); 1152 return 1; 1153 } 1154 tprintf(", {ctlbuf="); 1155 printstrbuf(tcp, &sp.ctlbuf, 1); 1156 tprintf(", databuf="); 1157 printstrbuf(tcp, &sp.databuf, 1); 1158 tprintf(", flags="); 1159 if (!printflags(msgflags, sp.flags)) 1160 tprintf("0"); 1161 tprintf("}"); 1162 return 1; 1163 case I_SRDOPT: 1164 /* argument is an option with flags */ 1165 tprintf(", "); 1166 printxval(stream_read_options, arg & RMODEMASK, "R???"); 1167 addflags(stream_read_flags, arg & ~RMODEMASK); 1168 return 1; 1169 case I_GRDOPT: 1170 /* argument is an pointer to an option with flags */ 1171 if (syserror(tcp)) 1172 return 0; 1173 tprintf(", ["); 1174 if (umove(tcp, arg, &val) < 0) 1175 tprintf("?"); 1176 else { 1177 printxval(stream_read_options, 1178 arg & RMODEMASK, "R???"); 1179 addflags(stream_read_flags, arg & ~RMODEMASK); 1180 } 1181 tprintf("]"); 1182 return 1; 1183 case I_NREAD: 1184#ifdef I_GETBAND 1185 case I_GETBAND: 1186#endif 1187#ifdef I_SETCLTIME 1188 case I_SETCLTIME: 1189#endif 1190#ifdef I_GETCLTIME 1191 case I_GETCLTIME: 1192#endif 1193 /* argument is a pointer to a decimal integer */ 1194 if (syserror(tcp)) 1195 return 0; 1196 tprintf(", "); 1197 printnum(tcp, arg, "%d"); 1198 return 1; 1199 case I_FDINSERT: 1200 /* argument is a pointer to a strfdinsert structure */ 1201 if (syserror(tcp) || !arg) 1202 return 0; 1203 if (umove(tcp, arg, &sfi) < 0) { 1204 tprintf(", {...}"); 1205 return 1; 1206 } 1207 tprintf(", {ctlbuf="); 1208 printstrbuf(tcp, &sfi.ctlbuf, 1); 1209 tprintf(", databuf="); 1210 printstrbuf(tcp, &sfi.databuf, 1); 1211 tprintf(", flags="); 1212 if (!printflags(msgflags, sfi.flags)) 1213 tprintf("0"); 1214 tprintf(", filedes=%d, offset=%d}", sfi.fildes, sfi.offset); 1215 return 1; 1216#ifdef I_SWROPT 1217 case I_SWROPT: 1218 /* argument is a set of flags */ 1219 tprintf(", "); 1220 if (!printflags(stream_write_flags, arg)) 1221 tprintf("0"); 1222 return 1; 1223#endif /* I_SWROPT */ 1224#ifdef I_GWROPT 1225 case I_GWROPT: 1226 /* argument is an pointer to an option with flags */ 1227 if (syserror(tcp)) 1228 return 0; 1229 tprintf(", ["); 1230 if (umove(tcp, arg, &val) < 0) 1231 tprintf("?"); 1232 else if (!printflags(stream_write_flags, arg)) 1233 tprintf("0"); 1234 tprintf("]"); 1235 return 1; 1236#endif /* I_GWROPT */ 1237 case I_SENDFD: 1238#ifdef I_CKBAND 1239 case I_CKBAND: 1240#endif 1241#ifdef I_CANPUT 1242 case I_CANPUT: 1243#endif 1244 case I_LINK: 1245 case I_UNLINK: 1246 case I_PLINK: 1247 case I_PUNLINK: 1248 /* argument is a decimal integer */ 1249 tprintf(", %d", arg); 1250 return 1; 1251 case I_RECVFD: 1252 /* argument is a pointer to a strrecvfd structure */ 1253 if (syserror(tcp) || !arg) 1254 return 0; 1255 if (umove(tcp, arg, &srf) < 0) { 1256 tprintf(", {...}"); 1257 return 1; 1258 } 1259 tprintf(", {fd=%d, uid=%lu, gid=%lu}", srf.fd, 1260 (unsigned long) srf.uid, (unsigned long) srf.gid); 1261 return 1; 1262#ifdef I_LIST 1263 case I_LIST: 1264 if (syserror(tcp)) 1265 return 0; 1266 if (arg == 0) { 1267 tprintf(", NULL"); 1268 return 1; 1269 } 1270 if (umove(tcp, arg, &sl) < 0) { 1271 tprintf(", {...}"); 1272 return 1; 1273 } 1274 tprintf(", {sl_nmods=%d, sl_modlist=[", sl.sl_nmods); 1275 for (i = 0; i < tcp->u_rval; i++) { 1276 if (i) 1277 tprintf(", "); 1278 printpath(tcp, (int) sl.sl_modlist[i].l_name); 1279 } 1280 tprintf("]}"); 1281 return 1; 1282#endif /* I_LIST */ 1283#ifdef I_ATMARK 1284 case I_ATMARK: 1285 tprintf(", "); 1286 printxval(stream_atmark_options, arg, "???MARK"); 1287 return 1; 1288#endif /* I_ATMARK */ 1289 default: 1290 return 0; 1291 } 1292} 1293 1294#endif /* !linux && !FREEBSD */ 1295 1296#endif /* HAVE_SYS_STREAM_H || linux || FREEBSD */ 1297