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