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