+int expect;
+long addr;
+int len;
+{
+ union T_primitives m;
+ int c = 0;
+
+ if (len < sizeof m.type) goto dump;
+
+ if (umove (tcp, addr, &m.type) < 0) goto dump;
+
+#define GET(type, struct) \
+ do { \
+ if (len < sizeof m.struct) goto dump; \
+ if (umove (tcp, addr, &m.struct) < 0) goto dump;\
+ tprintf ("{"); \
+ if (expect != type) { \
+ ++c; \
+ tprintf (#type); \
+ } \
+ } \
+ while (0)
+
+#define COMMA() \
+ do { if (c++) tprintf (", "); } while (0)
+
+
+#define STRUCT(struct, elem, print) \
+ do { \
+ COMMA (); \
+ if (m.struct.elem##_length < 0 || \
+ m.struct.elem##_offset < sizeof m.struct || \
+ m.struct.elem##_offset + m.struct.elem##_length > len) \
+ { \
+ tprintf (#elem "_length=%ld, " #elem "_offset=%ld",\
+ m.struct.elem##_length, \
+ m.struct.elem##_offset); \
+ } \
+ else { \
+ tprintf (#elem "="); \
+ print (tcp, \
+ addr + m.struct.elem##_offset, \
+ m.struct.elem##_length); \
+ } \
+ } \
+ while (0)
+
+#define ADDR(struct, elem) STRUCT (struct, elem, printstr)
+
+ switch (m.type) {
+#ifdef T_CONN_REQ
+ case T_CONN_REQ: /* connect request */
+ GET (T_CONN_REQ, conn_req);
+ ADDR (conn_req, DEST);
+ ADDR (conn_req, OPT);
+ break;
+#endif
+#ifdef T_CONN_RES
+ case T_CONN_RES: /* connect response */
+ GET (T_CONN_RES, conn_res);
+#ifdef HAVE_STRUCT_T_CONN_RES_QUEUE_PTR
+ COMMA ();
+ tprintf ("QUEUE=%p", m.conn_res.QUEUE_ptr);
+#elif defined HAVE_STRUCT_T_CONN_RES_ACCEPTOR_ID
+ COMMA ();
+ tprintf ("ACCEPTOR=%#lx", m.conn_res.ACCEPTOR_id);
+#endif
+ ADDR (conn_res, OPT);
+ COMMA ();
+ tprintf ("SEQ=%ld", m.conn_res.SEQ_number);
+ break;
+#endif
+#ifdef T_DISCON_REQ
+ case T_DISCON_REQ: /* disconnect request */
+ GET (T_DISCON_REQ, discon_req);
+ COMMA ();
+ tprintf ("SEQ=%ld", m.discon_req.SEQ_number);
+ break;
+#endif
+#ifdef T_DATA_REQ
+ case T_DATA_REQ: /* data request */
+ GET (T_DATA_REQ, data_req);
+ COMMA ();
+ tprintf ("MORE=%ld", m.data_req.MORE_flag);
+ break;
+#endif
+#ifdef T_EXDATA_REQ
+ case T_EXDATA_REQ: /* expedited data req */
+ GET (T_EXDATA_REQ, exdata_req);
+ COMMA ();
+ tprintf ("MORE=%ld", m.exdata_req.MORE_flag);
+ break;
+#endif
+#ifdef T_INFO_REQ
+ case T_INFO_REQ: /* information req */
+ GET (T_INFO_REQ, info_req);
+ break;
+#endif
+#ifdef T_BIND_REQ
+ case T_BIND_REQ: /* bind request */
+#ifdef O_T_BIND_REQ
+ case O_T_BIND_REQ: /* Ugly xti/tli hack */
+#endif
+ GET (T_BIND_REQ, bind_req);
+ ADDR (bind_req, ADDR);
+ COMMA ();
+ tprintf ("CONIND=%ld", m.bind_req.CONIND_number);
+ break;
+#endif
+#ifdef T_UNBIND_REQ
+ case T_UNBIND_REQ: /* unbind request */
+ GET (T_UNBIND_REQ, unbind_req);
+ break;
+#endif
+#ifdef T_UNITDATA_REQ
+ case T_UNITDATA_REQ: /* unitdata requset */
+ GET (T_UNITDATA_REQ, unitdata_req);
+ ADDR (unitdata_req, DEST);
+ ADDR (unitdata_req, OPT);
+ break;
+#endif
+#ifdef T_OPTMGMT_REQ
+ case T_OPTMGMT_REQ: /* manage opt req */
+ GET (T_OPTMGMT_REQ, optmgmt_req);
+ COMMA ();
+ tprintf ("MGMT=");
+ printflags (transport_user_flags, m.optmgmt_req.MGMT_flags,
+ "T_???");
+ STRUCT (optmgmt_req, OPT, print_optmgmt);
+ break;
+#endif
+#ifdef T_ORDREL_REQ
+ case T_ORDREL_REQ: /* orderly rel req */
+ GET (T_ORDREL_REQ, ordrel_req);
+ break;
+#endif
+#ifdef T_CONN_IND
+ case T_CONN_IND: /* connect indication */
+ GET (T_CONN_IND, conn_ind);
+ ADDR (conn_ind, SRC);
+ ADDR (conn_ind, OPT);
+ tprintf (", SEQ=%ld", m.conn_ind.SEQ_number);
+ break;
+#endif
+#ifdef T_CONN_CON
+ case T_CONN_CON: /* connect corfirm */
+ GET (T_CONN_CON, conn_con);
+ ADDR (conn_con, RES);
+ ADDR (conn_con, OPT);
+ break;
+#endif
+#ifdef T_DISCON_IND
+ case T_DISCON_IND: /* discon indication */
+ GET (T_DISCON_IND, discon_ind);
+ COMMA ();
+ tprintf ("DISCON=%ld, SEQ=%ld",
+ m.discon_ind.DISCON_reason, m.discon_ind.SEQ_number);
+ break;
+#endif
+#ifdef T_DATA_IND
+ case T_DATA_IND: /* data indication */
+ GET (T_DATA_IND, data_ind);
+ COMMA ();
+ tprintf ("MORE=%ld", m.data_ind.MORE_flag);
+ break;
+#endif
+#ifdef T_EXDATA_IND
+ case T_EXDATA_IND: /* expedited data ind */
+ GET (T_EXDATA_IND, exdata_ind);
+ COMMA ();
+ tprintf ("MORE=%ld", m.exdata_ind.MORE_flag);
+ break;
+#endif
+#ifdef T_INFO_ACK
+ case T_INFO_ACK: /* info ack */
+ GET (T_INFO_ACK, info_ack);
+ COMMA ();
+ tprintf ("TSDU=%ld, ETSDU=%ld, CDATA=%ld, DDATA=%ld, "
+ "ADDR=%ld, OPT=%ld, TIDU=%ld, SERV=",
+ m.info_ack.TSDU_size, m.info_ack.ETSDU_size,
+ m.info_ack.CDATA_size, m.info_ack.DDATA_size,
+ m.info_ack.ADDR_size, m.info_ack.OPT_size,
+ m.info_ack.TIDU_size);
+ printxval (service_type, m.info_ack.SERV_type, "T_???");
+ tprintf (", CURRENT=");
+ printxval (ts_state, m.info_ack.CURRENT_state, "TS_???");
+ tprintf (", PROVIDER=");
+ printflags (provider_flags, m.info_ack.PROVIDER_flag, "???");
+ break;
+#endif
+#ifdef T_BIND_ACK
+ case T_BIND_ACK: /* bind ack */
+ GET (T_BIND_ACK, bind_ack);
+ ADDR (bind_ack, ADDR);
+ tprintf (", CONIND=%ld", m.bind_ack.CONIND_number);
+ break;
+#endif
+#ifdef T_ERROR_ACK
+ case T_ERROR_ACK: /* error ack */
+ GET (T_ERROR_ACK, error_ack);
+ COMMA ();
+ tprintf ("ERROR=");
+ printxval (transport_user_options,
+ m.error_ack.ERROR_prim, "TI_???");
+ tprintf (", TLI=");
+ printxval (tli_errors, m.error_ack.TLI_error, "T???");
+ tprintf ("UNIX=%s", strerror (m.error_ack.UNIX_error));
+ break;
+#endif
+#ifdef T_OK_ACK
+ case T_OK_ACK: /* ok ack */
+ GET (T_OK_ACK, ok_ack);
+ COMMA ();
+ tprintf ("CORRECT=");
+ printxval (transport_user_options,
+ m.ok_ack.CORRECT_prim, "TI_???");
+ break;
+#endif
+#ifdef T_UNITDATA_IND
+ case T_UNITDATA_IND: /* unitdata ind */
+ GET (T_UNITDATA_IND, unitdata_ind);
+ ADDR (unitdata_ind, SRC);
+ ADDR (unitdata_ind, OPT);
+ break;
+#endif
+#ifdef T_UDERROR_IND
+ case T_UDERROR_IND: /* unitdata error ind */
+ GET (T_UDERROR_IND, uderror_ind);
+ ADDR (uderror_ind, DEST);
+ ADDR (uderror_ind, OPT);
+ tprintf (", ERROR=%ld", m.uderror_ind.ERROR_type);
+ break;
+#endif
+#ifdef T_OPTMGMT_ACK
+ case T_OPTMGMT_ACK: /* manage opt ack */
+ GET (T_OPTMGMT_ACK, optmgmt_ack);
+ COMMA ();
+ tprintf ("MGMT=");
+ printflags (transport_user_flags, m.optmgmt_ack.MGMT_flags,
+ "T_???");
+ STRUCT (optmgmt_ack, OPT, print_optmgmt);
+ break;
+#endif
+#ifdef T_ORDREL_IND
+ case T_ORDREL_IND: /* orderly rel ind */
+ GET (T_ORDREL_IND, ordrel_ind);
+ break;
+#endif
+#ifdef T_ADDR_REQ
+ case T_ADDR_REQ: /* address req */
+ GET (T_ADDR_REQ, addr_req);
+ break;
+#endif
+#ifdef T_ADDR_ACK
+ case T_ADDR_ACK: /* address response */
+ GET (T_ADDR_ACK, addr_ack);
+ ADDR (addr_ack, LOCADDR);
+ ADDR (addr_ack, REMADDR);
+ break;
+#endif
+ default:
+ dump:
+ c = -1;
+ printstr(tcp, addr, len);
+ break;
+ }
+
+ if (c >= 0) tprintf ("}");
+
+#undef ADDR
+#undef COMMA
+#undef STRUCT
+
+ return 0;
+}
+
+
+#endif /* TI_BIND */
+
+
+static int internal_stream_ioctl(struct tcb *tcp, int arg)