1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  22 /*      All Rights Reserved     */
  23 
  24 
  25 /*
  26  * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
  27  */
  28 
  29 #ifndef _SYS_TIHDR_H
  30 #define _SYS_TIHDR_H
  31 
  32 #include <sys/types.h>
  33 /*
  34  * Include declarations implicit to TPI and shared with user level code
  35  */
  36 #include <sys/tpicommon.h>
  37 
  38 #ifdef  __cplusplus
  39 extern "C" {
  40 #endif
  41 
  42 /*
  43  * The feature test macro, _SUN_TPI_VERSION makes some of additional
  44  * declarations available and changes some existing ones. There was
  45  * some changes done to this interface and this feature test macro
  46  * enables transitioning to those changes while maintaining retaining
  47  * backward compatibility.
  48  *
  49  * The following is all the information
  50  * needed by the Transport Service Interface.
  51  */
  52 
  53 /*
  54  * The following are the definitions of the Transport
  55  * Service Interface primitives.
  56  */
  57 
  58 /*
  59  * Primitives that are initiated by the transport user.
  60  */
  61 #define T_CONN_REQ      0       /* connection request           */
  62 #if _SUN_TPI_VERSION > 1
  63 #define O_T_CONN_RES    1       /* old connection response      */
  64 #else
  65 #define T_CONN_RES      1       /* connection response          */
  66 #endif /* _SUN_TPI_VERSION > 1 */
  67 #define T_DISCON_REQ    2       /* disconnect request           */
  68 #define T_DATA_REQ      3       /* data request                 */
  69 #define T_EXDATA_REQ    4       /* expedited data request       */
  70 #define T_INFO_REQ      5       /* information request          */
  71 /*
  72  * Bind Request primitive (TLI inspired
  73  * address binding semantics). If requested address is
  74  * found to be busy, an alternative free address is
  75  * returned. (Requires comparison of requested address to
  76  * returned address to verify if the requested address was
  77  * bound)
  78  *
  79  */
  80 #if _SUN_TPI_VERSION > 0
  81 #define O_T_BIND_REQ    6
  82 #else
  83 #define T_BIND_REQ      6
  84 #endif /* _SUN_TPI_VERSION > 0 */
  85 
  86 #define T_UNBIND_REQ    7       /* unbind request               */
  87 #define T_UNITDATA_REQ  8       /* unitdata request             */
  88 
  89 /*
  90  * Option management request (with TLI inspired semantics )
  91  * The preferred name for this primitive in new code is T_SVR4_OPTMGMT_REQ.
  92  * This primitive had the name T_OPTMGMT_REQ in old SVR4 derived TPI.
  93  * This primitive is used for TLI and Socket API support.
  94  * The packing of options in option buffer is private contract
  95  * between transport provider and its users and can differ
  96  * between different transports.
  97  * (The name O_T_OPTMGMT_REQ continues to exist for Solaris 2.6
  98  *  compilation environment compatibility only)
  99  *
 100  */
 101 #define T_SVR4_OPTMGMT_REQ      9
 102 #if _SUN_TPI_VERSION > 0
 103 #define O_T_OPTMGMT_REQ T_SVR4_OPTMGMT_REQ
 104 #else
 105 #define T_OPTMGMT_REQ   T_SVR4_OPTMGMT_REQ
 106 #endif  /* _SUN_TPI_VERSION > 0 */
 107 
 108 #define T_ORDREL_REQ    10      /* orderly release req          */
 109 
 110 /*
 111  * Primitives that are initiated by the transport provider.
 112  */
 113 #define T_CONN_IND      11      /* connection indication        */
 114 #define T_CONN_CON      12      /* connection confirmation      */
 115 #define T_DISCON_IND    13      /* disconnect indication        */
 116 #define T_DATA_IND      14      /* data indication              */
 117 #define T_EXDATA_IND    15      /* expeditied data indication   */
 118 #define T_INFO_ACK      16      /* information acknowledgment   */
 119 #define T_BIND_ACK      17      /* bind acknowledment           */
 120 #define T_ERROR_ACK     18      /* error acknowledgment         */
 121 #define T_OK_ACK        19      /* ok acknowledgment            */
 122 #define T_UNITDATA_IND  20      /* unitdata indication          */
 123 #define T_UDERROR_IND   21      /* unitdata error indication    */
 124 #define T_OPTMGMT_ACK   22      /* manage options ack           */
 125 #define T_ORDREL_IND    23      /* orderly release ind          */
 126 /*
 127  * Primitives added to namespace and contain a mix of ones
 128  * initiated by transport user or provider.
 129  */
 130 #define T_ADDR_REQ      24      /* address request              */
 131 #define T_ADDR_ACK      25      /* address acknowledgement      */
 132 
 133 #if _SUN_TPI_VERSION > 0
 134 /*
 135  * Bind request primitive with better address
 136  * binding semantics. (XTI inspired)
 137  * If the requested address is found to be busy,
 138  * an error is returned. (No need to compare addresses on successful
 139  * bind acknowledgement).
 140  */
 141 #define T_BIND_REQ      26      /* bind request                 */
 142 
 143 /*
 144  * Option management request (with XTI inspired semantics)
 145  * The packing of options in option buffer is required to
 146  * be with 'struct T_opthdr' data structure defined later in
 147  * this header.
 148  */
 149 #define T_OPTMGMT_REQ   27 /* manage options req - T_opthdr option header */
 150 #endif /* _SUN_TPI_VERSION > 0 */
 151 
 152 #if _SUN_TPI_VERSION > 1
 153 /*
 154  * The connection response that expects its ACCEPTOR_id to have been
 155  * filled in from the value supplied via a T_CAPABILITY_ACK.
 156  */
 157 #define T_CONN_RES      28      /* connection response          */
 158 
 159 /*
 160  * Capability request and ack.  These primitives are optional and
 161  * subsume the functionality of T_INFO_{REQ,ACK}.
 162  */
 163 #define T_CAPABILITY_REQ        30
 164 #define T_CAPABILITY_ACK        31
 165 #endif /* _SUN_TPI_VERSION > 1 */
 166 
 167 #ifdef _KERNEL
 168 /*
 169  * Sun private TPI extensions. They are currently used for transparently
 170  * passing options through the connection-oriented loopback transport.
 171  * Values assigned to them may change.
 172  *
 173  * T_EXTCONN_IND (extended T_CONN_IND) is used to return dst as well as
 174  * src addr/port.
 175  */
 176 #define T_OPTDATA_REQ   0x1001  /* data (with options) request  */
 177 #define T_OPTDATA_IND   0x1002  /* data (with options) indication */
 178 #define T_EXTCONN_IND   0x1003  /* extended T_CONN_IND to return dst as well */
 179 
 180 #endif /* _KERNEL */
 181 
 182 /*
 183  * The following are the events that drive the state machine
 184  */
 185 /* Initialization events */
 186 #define TE_BIND_REQ     0       /* bind request                         */
 187 #define TE_UNBIND_REQ   1       /* unbind request                       */
 188 #define TE_OPTMGMT_REQ  2       /* manage options req                   */
 189 #define TE_BIND_ACK     3       /* bind acknowledment                   */
 190 #define TE_OPTMGMT_ACK  4       /* manage options ack                   */
 191 #define TE_ERROR_ACK    5       /* error acknowledgment                 */
 192 #define TE_OK_ACK1      6       /* ok ack  seqcnt == 0                  */
 193 #define TE_OK_ACK2      7       /* ok ack  seqcnt == 1, q == resq       */
 194 #define TE_OK_ACK3      8       /* ok ack  seqcnt == 1, q != resq       */
 195 #define TE_OK_ACK4      9       /* ok ack  seqcnt > 1                        */
 196 
 197 /* Connection oriented events */
 198 #define TE_CONN_REQ     10      /* connection request                   */
 199 #define TE_CONN_RES     11      /* connection response                  */
 200 #define TE_DISCON_REQ   12      /* disconnect request                   */
 201 #define TE_DATA_REQ     13      /* data request                         */
 202 #define TE_EXDATA_REQ   14      /* expedited data request               */
 203 #define TE_ORDREL_REQ   15      /* orderly release req                  */
 204 #define TE_CONN_IND     16      /* connection indication                */
 205 #define TE_CONN_CON     17      /* connection confirmation              */
 206 #define TE_DATA_IND     18      /* data indication                      */
 207 #define TE_EXDATA_IND   19      /* expedited data indication            */
 208 #define TE_ORDREL_IND   20      /* orderly release ind                  */
 209 #define TE_DISCON_IND1  21      /* disconnect indication seq == 0       */
 210 #define TE_DISCON_IND2  22      /* disconnect indication seq == 1       */
 211 #define TE_DISCON_IND3  23      /* disconnect indication seq > 1     */
 212 #define TE_PASS_CONN    24      /* pass connection                      */
 213 
 214 /* Unit data events */
 215 #define TE_UNITDATA_REQ 25      /* unitdata request                     */
 216 #define TE_UNITDATA_IND 26      /* unitdata indication                  */
 217 #define TE_UDERROR_IND  27      /* unitdata error indication            */
 218 
 219 #define TE_NOEVENTS     28
 220 /*
 221  * The following are the possible states of the Transport
 222  * Service Interface
 223  */
 224 
 225 #define TS_UNBND                0       /* unbound                      */
 226 #define TS_WACK_BREQ            1       /* waiting ack of BIND_REQ      */
 227 #define TS_WACK_UREQ            2       /* waiting ack of UNBIND_REQ    */
 228 #define TS_IDLE                 3       /* idle                         */
 229 #define TS_WACK_OPTREQ          4       /* wait ack options request     */
 230 #define TS_WACK_CREQ            5       /* waiting ack of CONN_REQ      */
 231 #define TS_WCON_CREQ            6       /* waiting confirm of CONN_REQ  */
 232 #define TS_WRES_CIND            7       /* waiting response of CONN_IND */
 233 #define TS_WACK_CRES            8       /* waiting ack of CONN_RES      */
 234 #define TS_DATA_XFER            9       /* data transfer                */
 235 #define TS_WIND_ORDREL          10      /* releasing rd but not wr      */
 236 #define TS_WREQ_ORDREL          11      /* wait to release wr but not rd */
 237 #define TS_WACK_DREQ6           12      /* waiting ack of DISCON_REQ    */
 238 #define TS_WACK_DREQ7           13      /* waiting ack of DISCON_REQ    */
 239 #define TS_WACK_DREQ9           14      /* waiting ack of DISCON_REQ    */
 240 #define TS_WACK_DREQ10          15      /* waiting ack of DISCON_REQ    */
 241 #define TS_WACK_DREQ11          16      /* waiting ack of DISCON_REQ    */
 242 
 243 #define TS_NOSTATES             17
 244 
 245 
 246 /*
 247  * The following structure definitions define the format of the
 248  * stream message block of the above primitives.
 249  * (everything is declared t_scalar_t to ensure proper alignment
 250  * across different machines)
 251  */
 252 
 253 /* connection request */
 254 
 255 struct T_conn_req {
 256         t_scalar_t      PRIM_type;      /* always T_CONN_REQ            */
 257         t_scalar_t      DEST_length;    /* dest addr length             */
 258         t_scalar_t      DEST_offset;    /* dest addr offset             */
 259         t_scalar_t      OPT_length;     /* options length               */
 260         t_scalar_t      OPT_offset;     /* options offset               */
 261 };
 262 
 263 /* connect response */
 264 
 265 /*
 266  * Historical compatibility note for "struct T_conn_res" usage.
 267  *        "QUEUE_ptr" field of type "queue_t" is obsolete to support
 268  *        code portability  and application binary compatibility
 269  *        between ILP32(32-bit) and LP64 (64-bit) environments.
 270  *        Use field "ACCEPTOR_id" instead.
 271  *        For compatibility, drivers using (_SUN_TPI_VERSION >= 2) interface
 272  *        can support treating ACCEPTOR_id content as queue pointer
 273  *        only when PRIM_type is O_T_CONN_RES.
 274  */
 275 struct T_conn_res {
 276         t_scalar_t      PRIM_type;      /* T_CONN_RES (or O_T_CONN_RES) */
 277         t_uscalar_t     ACCEPTOR_id;    /* id of accepting endpoint     */
 278         t_scalar_t      OPT_length;     /* options length               */
 279         t_scalar_t      OPT_offset;     /* options offset               */
 280         t_scalar_t      SEQ_number;     /* sequence number              */
 281 };
 282 
 283 /* disconnect request */
 284 
 285 struct T_discon_req {
 286         t_scalar_t      PRIM_type;      /* always T_DISCON_REQ          */
 287         t_scalar_t      SEQ_number;     /* sequnce number               */
 288 };
 289 
 290 /* data request */
 291 
 292 struct T_data_req {
 293         t_scalar_t      PRIM_type;      /* always T_DATA_REQ            */
 294         t_scalar_t      MORE_flag;      /* more data                    */
 295 };
 296 
 297 /* expedited data request */
 298 
 299 struct T_exdata_req {
 300         t_scalar_t      PRIM_type;      /* always T_EXDATA_REQ          */
 301         t_scalar_t      MORE_flag;      /* more data                    */
 302 };
 303 
 304 /* information request */
 305 
 306 struct T_info_req {
 307         t_scalar_t      PRIM_type;      /* always T_INFO_REQ            */
 308 };
 309 
 310 /* bind request */
 311 
 312 struct T_bind_req {
 313         t_scalar_t      PRIM_type;      /* T_BIND_REQ (or O_T_BIND_REQ) */
 314         t_scalar_t      ADDR_length;    /* addr length                  */
 315         t_scalar_t      ADDR_offset;    /* addr offset                  */
 316         t_uscalar_t     CONIND_number;  /* connect indications requested */
 317 };
 318 
 319 /* unbind request */
 320 
 321 struct T_unbind_req {
 322         t_scalar_t      PRIM_type;      /* always T_UNBIND_REQ          */
 323 };
 324 
 325 /* unitdata request */
 326 
 327 struct T_unitdata_req {
 328         t_scalar_t      PRIM_type;      /* always T_UNITDATA_REQ        */
 329         t_scalar_t      DEST_length;    /* dest addr length             */
 330         t_scalar_t      DEST_offset;    /* dest addr offset             */
 331         t_scalar_t      OPT_length;     /* options length               */
 332         t_scalar_t      OPT_offset;     /* options offset               */
 333 };
 334 
 335 /* manage options request */
 336 
 337 struct T_optmgmt_req {
 338         t_scalar_t      PRIM_type;      /* T_OPTMGMT_REQ or             */
 339                                         /* T_SVR4_OPTMGMT_REQ           */
 340         t_scalar_t      OPT_length;     /* options length               */
 341         t_scalar_t      OPT_offset;     /* options offset               */
 342         t_scalar_t      MGMT_flags;     /* options flags                */
 343 };
 344 
 345 /* orderly release request */
 346 
 347 struct T_ordrel_req {
 348         t_scalar_t      PRIM_type;      /* always T_ORDREL_REQ          */
 349 };
 350 
 351 /* protocol address request */
 352 
 353 struct T_addr_req {
 354         t_scalar_t      PRIM_type;      /* always T_ADDR_REQ            */
 355 };
 356 
 357 /* connect indication */
 358 
 359 struct T_conn_ind {
 360         t_scalar_t      PRIM_type;      /* always T_CONN_IND            */
 361         t_scalar_t      SRC_length;     /* src addr length              */
 362         t_scalar_t      SRC_offset;     /* src addr offset              */
 363         t_scalar_t      OPT_length;     /* option length                */
 364         t_scalar_t      OPT_offset;     /* option offset                */
 365         t_scalar_t      SEQ_number;     /* sequnce number               */
 366 };
 367 
 368 /* connect confirmation */
 369 
 370 struct T_conn_con {
 371         t_scalar_t      PRIM_type;      /* always T_CONN_CON            */
 372         t_scalar_t      RES_length;     /* responding addr length       */
 373         t_scalar_t      RES_offset;     /* responding addr offset       */
 374         t_scalar_t      OPT_length;     /* option length                */
 375         t_scalar_t      OPT_offset;     /* option offset                */
 376 };
 377 
 378 /* disconnect indication */
 379 
 380 struct T_discon_ind {
 381         t_scalar_t      PRIM_type;      /* always T_DISCON_IND          */
 382         t_scalar_t      DISCON_reason;  /* disconnect reason            */
 383         t_scalar_t      SEQ_number;     /* sequnce number               */
 384 };
 385 
 386 /* data indication */
 387 
 388 struct T_data_ind {
 389         t_scalar_t      PRIM_type;      /* always T_DATA_IND            */
 390         t_scalar_t      MORE_flag;      /* more data                    */
 391 };
 392 
 393 /* expedited data indication */
 394 
 395 struct T_exdata_ind {
 396         t_scalar_t      PRIM_type;      /* always T_EXDATA_IND          */
 397         t_scalar_t      MORE_flag;      /* more data                    */
 398 };
 399 
 400 /* information acknowledgment */
 401 
 402 struct T_info_ack {
 403         t_scalar_t      PRIM_type;      /* always T_INFO_ACK            */
 404         t_scalar_t      TSDU_size;      /* max TSDU size                */
 405         t_scalar_t      ETSDU_size;     /* max ETSDU size               */
 406         t_scalar_t      CDATA_size;     /* max connect data size        */
 407         t_scalar_t      DDATA_size;     /* max discon data size         */
 408         t_scalar_t      ADDR_size;      /* address size                 */
 409         t_scalar_t      OPT_size;       /* options size                 */
 410         t_scalar_t      TIDU_size;      /* max TIDU size                */
 411         t_scalar_t      SERV_type;      /* provider service type        */
 412         t_scalar_t      CURRENT_state;  /* current state                */
 413         t_scalar_t      PROVIDER_flag;  /* provider flags               */
 414 };
 415 
 416 /*
 417  * The following are definitions of flags available to the transport
 418  * provider to set in the PROVIDER_flag field of the T_info_ack
 419  * structure.
 420  */
 421 
 422 #if _SUN_TPI_VERSION > 0
 423 #define SENDZERO        0x0001  /* provider can handle --length TSDUs */
 424 
 425 #define OLD_SENDZERO    0x1000  /* reserved for compatibility with */
 426                                 /* old providers- old value of */
 427                                 /* SENDZERO defined in <sys/timod.h> */
 428 #else
 429 #define SENDZERO        0x1000  /* old SENDZERO value */
 430 #endif /* _SUN_TPI_VERSION > 0 */
 431 
 432 #define EXPINLINE       0x0002  /* provider wants ETSDUs in band 0 */
 433 /*
 434  * Flag XPG4_1:
 435  *              transport provider supports TPI modifications motivated by and
 436  *              in conjunction with XTI inspired TPI support and all the
 437  *              compatibility baggage that implies.
 438  *    It implies, - primitives T_ADDR_REQ & T_ADDR_ACK supported
 439  *                - primitives O_T_BIND_REQ & T_BIND_REQ separately supported
 440  *                - primitives T_SVR4_OPTMGMT_REQ & T_OPTMGMT_REQ separately
 441  *                  supported.
 442  */
 443 #define XPG4_1          0x0004
 444 
 445 /* bind acknowledgment */
 446 
 447 struct T_bind_ack {
 448         t_scalar_t      PRIM_type;      /* always T_BIND_ACK            */
 449         t_scalar_t      ADDR_length;    /* addr length                  */
 450         t_scalar_t      ADDR_offset;    /* addr offset                  */
 451         t_uscalar_t     CONIND_number;  /* connect ind to be queued     */
 452 };
 453 
 454 /* error acknowledgment */
 455 
 456 struct T_error_ack {
 457         t_scalar_t      PRIM_type;      /* always T_ERROR_ACK           */
 458         t_scalar_t      ERROR_prim;     /* primitive in error           */
 459         t_scalar_t      TLI_error;      /* TLI error code               */
 460         t_scalar_t      UNIX_error;     /* UNIX error code              */
 461 };
 462 
 463 /* ok acknowledgment */
 464 
 465 struct T_ok_ack {
 466         t_scalar_t      PRIM_type;      /* always T_OK_ACK              */
 467         t_scalar_t      CORRECT_prim;   /* correct primitive            */
 468 };
 469 
 470 /* unitdata indication */
 471 
 472 struct T_unitdata_ind {
 473         t_scalar_t      PRIM_type;      /* always T_UNITDATA_IND        */
 474         t_scalar_t      SRC_length;     /* source addr length           */
 475         t_scalar_t      SRC_offset;     /* source addr offset           */
 476         t_scalar_t      OPT_length;     /* options length               */
 477         t_scalar_t      OPT_offset;     /* options offset               */
 478 };
 479 
 480 /* unitdata error indication */
 481 
 482 struct T_uderror_ind {
 483         t_scalar_t      PRIM_type;      /* always T_UDERROR_IND         */
 484         t_scalar_t      DEST_length;    /* dest addr length             */
 485         t_scalar_t      DEST_offset;    /* dest addr offset             */
 486         t_scalar_t      OPT_length;     /* options length               */
 487         t_scalar_t      OPT_offset;     /* options offset               */
 488         t_scalar_t      ERROR_type;     /* error type                   */
 489 };
 490 
 491 /* manage options ack */
 492 
 493 struct T_optmgmt_ack {
 494         t_scalar_t      PRIM_type;      /* always T_OPTMGMT_ACK         */
 495         t_scalar_t      OPT_length;     /* options length               */
 496         t_scalar_t      OPT_offset;     /* options offset               */
 497         t_scalar_t      MGMT_flags;     /* managment flags              */
 498 };
 499 
 500 /* orderly release indication */
 501 
 502 struct T_ordrel_ind {
 503         t_scalar_t      PRIM_type;      /* always T_ORDREL_IND          */
 504 };
 505 
 506 
 507 /* protocol address acknowledgment */
 508 
 509 struct T_addr_ack {
 510         t_scalar_t      PRIM_type;      /* always T_ADDR_ACK            */
 511         t_scalar_t      LOCADDR_length; /* length of local address      */
 512         t_scalar_t      LOCADDR_offset; /* offset of local address      */
 513         t_scalar_t      REMADDR_length; /* length of remote address     */
 514         t_scalar_t      REMADDR_offset; /* offset of remote address     */
 515 };
 516 
 517 #if _SUN_TPI_VERSION > 1
 518 /*
 519  * Capability request and ack.  These primitives are optional and
 520  * subsume the functionality of T_INFO_{REQ,ACK}.
 521  */
 522 struct T_capability_req {
 523         t_scalar_t      PRIM_type;      /* always T_CAPABILITY_REQ      */
 524         t_uscalar_t     CAP_bits1;      /* capability bits #1           */
 525 };
 526 
 527 struct T_capability_ack {
 528         t_scalar_t      PRIM_type;      /* always T_CAPABILITY_ACK      */
 529         t_uscalar_t     CAP_bits1;      /* capability bits #1           */
 530         struct T_info_ack
 531                         INFO_ack;       /* info acknowledgement         */
 532         t_uscalar_t     ACCEPTOR_id;    /* accepting endpoint id        */
 533 };
 534 
 535 #define TC1_INFO        (1u << 0) /* Info request/ack             */
 536 #define TC1_ACCEPTOR_ID (1u << 1) /* Acceptor_id request/ack      */
 537 #define TC1_CAP_BITS2   (1u << 31)        /* Reserved for future use      */
 538 
 539 #endif /* _SUN_TPI_VERSION > 1 */
 540 
 541 #ifdef _KERNEL
 542 /*
 543  * Private Sun TPI extensions.
 544  */
 545 
 546 /* data (with options) request */
 547 struct T_optdata_req {
 548         t_scalar_t      PRIM_type;      /* always T_OPTDATA_REQ         */
 549         t_scalar_t      DATA_flag;      /* flags like "more data"       */
 550         t_scalar_t      OPT_length;     /* options length               */
 551         t_scalar_t      OPT_offset;     /* options offset               */
 552 };
 553 
 554 /* data (with options) indication */
 555 struct T_optdata_ind {
 556         t_scalar_t      PRIM_type;      /* always T_OPTDATA_IND         */
 557         t_scalar_t      DATA_flag;      /* flags like "more data"       */
 558         t_scalar_t      OPT_length;     /* options length               */
 559         t_scalar_t      OPT_offset;     /* options offset               */
 560 };
 561 
 562 /* extended connect indication to return dst addr/port as well as src */
 563 struct T_extconn_ind {
 564         t_scalar_t      PRIM_type;      /* always T_EXTCONN_IND         */
 565         t_scalar_t      SRC_length;     /* src addr length              */
 566         t_scalar_t      SRC_offset;     /* src addr offset              */
 567         t_scalar_t      OPT_length;     /* option length                */
 568         t_scalar_t      OPT_offset;     /* option offset                */
 569         t_scalar_t      SEQ_number;     /* sequnce number               */
 570         t_scalar_t      DEST_length;    /* dest addr length             */
 571         t_scalar_t      DEST_offset;    /* dest addr offset             */
 572 };
 573 #endif /* _KERNEL */
 574 
 575 /*
 576  * The following is a union of the primitives
 577  */
 578 union T_primitives {
 579         t_scalar_t              type;           /* primitive type       */
 580         struct T_conn_req       conn_req;       /* connect request      */
 581         struct T_conn_res       conn_res;       /* connect response     */
 582         struct T_discon_req     discon_req;     /* disconnect request   */
 583         struct T_data_req       data_req;       /* data request         */
 584         struct T_exdata_req     exdata_req;     /* expedited data req   */
 585         struct T_info_req       info_req;       /* information req      */
 586         struct T_bind_req       bind_req;       /* bind request         */
 587         struct T_unbind_req     unbind_req;     /* unbind request       */
 588         struct T_unitdata_req   unitdata_req;   /* unitdata requset     */
 589         struct T_optmgmt_req    optmgmt_req;    /* manage opt req       */
 590         struct T_ordrel_req     ordrel_req;     /* orderly rel req      */
 591         struct T_addr_req       addr_req;       /* address request      */
 592         struct T_conn_ind       conn_ind;       /* connect indication   */
 593         struct T_conn_con       conn_con;       /* connect corfirm      */
 594         struct T_discon_ind     discon_ind;     /* discon indication    */
 595         struct T_data_ind       data_ind;       /* data indication      */
 596         struct T_exdata_ind     exdata_ind;     /* expedited data ind   */
 597         struct T_info_ack       info_ack;       /* info ack             */
 598         struct T_bind_ack       bind_ack;       /* bind ack             */
 599         struct T_error_ack      error_ack;      /* error ack            */
 600         struct T_ok_ack         ok_ack;         /* ok ack               */
 601         struct T_unitdata_ind   unitdata_ind;   /* unitdata ind         */
 602         struct T_uderror_ind    uderror_ind;    /* unitdata error ind   */
 603         struct T_optmgmt_ack    optmgmt_ack;    /* manage opt ack       */
 604         struct T_ordrel_ind     ordrel_ind;     /* orderly rel ind      */
 605         struct T_addr_ack       addr_ack;       /* address ack          */
 606 #if _SUN_TPI_VERSION > 1
 607         struct T_capability_req capability_req; /* capability req       */
 608         struct T_capability_ack capability_ack; /* capability ack       */
 609 #endif /* _SUN_TPI_VERSION > 1 */
 610 #ifdef _KERNEL
 611         struct T_optdata_req    optdata_req;    /* option data request  */
 612         struct T_optdata_ind    optdata_ind;    /* option data ind      */
 613         struct T_extconn_ind    extconn_ind;    /* above plus dst addr  */
 614 #endif /* _KERNEL */
 615 };
 616 
 617 /*
 618  * TPI specification is not clear on how to pack options in option
 619  * buffers. What follows is the Solaris TPI interpretation of it.
 620  *
 621  * struct T_opthdr data structure is used to pack options in T_OPTMGMT_{REQ,ACK}
 622  * message primitives in buffer delimited by [OPT_offset, OPT_length] fields in
 623  * struct T_optmgmt_req/T_optmgmt_ack data structures.
 624  *
 625  * It is also used to pack options in similar buffers for data structures in
 626  * T_CONN_{REQ,IND,RES,CONN} primitives and T_UNITDATA_{REQ,IND} primitives
 627  * Needs to be on t_uscalar_t (32-bit word) aligned boundary.
 628  *
 629  * Note: T_SVR4_OPTMGMT_REQ primitive can, but need not, use this data
 630  *       structure for packing options. The format of option buffer for
 631  *       T_SVR4_OPTMGMT_REQ primitive is undefined and is a private contract
 632  *       between transport provider and its users.
 633  *
 634  * |<--------------first option---------------->|     |<--second option--...
 635  * ______________________________________ _ _ _ ____________________________
 636  * | len | level | name | status |  value.......| / / | len ...
 637  * -------------------------------------- - - - ----------------------------
 638  * |32bit| 32bit |32bit |  32bit |                 ^  | 32bit...
 639  *                                                 |
 640  *                                                 |
 641  *                                        alignment characters
 642  */
 643 struct T_opthdr {
 644         t_uscalar_t     len;    /* total length of option (header+value) */
 645         t_uscalar_t     level;  /* protocol level */
 646         t_uscalar_t     name;   /* option name */
 647         t_uscalar_t     status; /* status value */
 648         /* option value aligned on t_uscalar_t (32-bit) alignment boundary */
 649 };
 650 
 651 /*
 652  * ------------------------------------------------------------------------
 653  * Common experimental private TPI alignment related macros. Not for
 654  * use outside Solaris bundled code and can change in any release.
 655  * The alignment boundary _TPI_ALIGN_SIZE represents an implementation
 656  * choice for aligning many data objects which are directly or indirectly
 657  * associated with Solaris TPI implementation.
 658  * ------------------------------------------------------------------------
 659  */
 660 
 661 #define __TPI_ALIGN_SIZE                (sizeof (t_scalar_t))
 662 #define __TPI_ALIGN(x) \
 663         (((uintptr_t)(x) + __TPI_ALIGN_SIZE - 1) & ~(__TPI_ALIGN_SIZE - 1))
 664 #define __TPI_SIZE_ISALIGNED(x) \
 665                 (((uintptr_t)(x) & (__TPI_ALIGN_SIZE - 1)) == 0)
 666 
 667 /*
 668  * TPI primitive in message must be aligned at _TPI_ALIGN_SIZE boundary
 669  */
 670 #define __TPI_PRIM_ISALIGNED(x) __TPI_SIZE_ISALIGNED(x)
 671 
 672 /*
 673  * TPI option header "struct opthdr" objects must be aligned
 674  * at __TPI_ALIGN_SIZE boundary.
 675  */
 676 #define __TPI_OPT_ISALIGNED(x)  __TPI_SIZE_ISALIGNED(x)
 677 #define _TPI_ALIGN_OPT(x)       __TPI_ALIGN(x)
 678 
 679 /*
 680  * TPI option header "struct T_opthdr" objects must be aligned
 681  * at __TPI_ALIGN_SIZE boundary.
 682  */
 683 #define __TPI_TOPT_ISALIGNED(x) __TPI_SIZE_ISALIGNED(x)
 684 #define _TPI_ALIGN_TOPT(x)      __TPI_ALIGN(x)
 685 
 686 /*
 687  * --------------------------------------------------------------------
 688  * Private experimental macros. Not for use outside Solaris bundled
 689  * source code and can change in any release.
 690  * Macros that operate on struct T_opthdr. These are roughly modelled
 691  * after the corresponding Socket CMSG_*() and XTI T_OPT_*() macros, but
 692  * are applied to TPI option buffers.
 693  * --------------------------------------------------------------------
 694  *
 695  * unsigned char *
 696  * _TPI_TOPT_DATA(struct T_opthdr *tohp):
 697  *      Get start of data part after option header
 698  */
 699 #define _TPI_TOPT_DATA(tohp)    \
 700         ((unsigned char *)((char *)(tohp) + sizeof (struct T_opthdr)))
 701 
 702 /*
 703  * t_uscalar_t
 704  * _TPI_TOPT_DATALEN(tohp)
 705  *      Get length of contents of option data excluding header (and
 706  *      padding etc if any).
 707  */
 708 #define _TPI_TOPT_DATALEN(tohp) ((tohp)->len - sizeof (struct T_opthdr))
 709 
 710 /*
 711  * struct T_opthdr *
 712  * _TPI_TOPT_FIRSTHDR(char *pbuf, t_scalar_t buflen):
 713  *      Get pointer to the first option header in buffer 'pbuf'
 714  *      Return NULL if there is not enough room for the header
 715  *
 716  * struct T_opthdr *
 717  * _TPI_TOPT_NEXTHDR(char *pbuf, t_scalar_t buflen,
 718  *                                      struct T_opthdr *popt):
 719  *      Skip to next option header
 720  *
 721  * Notes:  _TPI_TOPT_NEXTHDR performs the roundup of the length.
 722  *
 723  *      If _TPI_TOPT_{FIRST,NEXT}HDR returns a non-null value, the user of
 724  *      _TPI_TOPT_{FIRST,NEXT}HDR must still verify that the resulting pointer
 725  *      is valid, by making a call to _TPI_TOPT_VALID. The _TPI_TOPT_VALID
 726  *      macro does not assume that the last option buffer is padded.
 727  */
 728 #define _TPI_TOPT_FIRSTHDR(pbuf, buflen) \
 729         ((((buflen) >= (unsigned int) sizeof (struct T_opthdr)) && \
 730                 __TPI_TOPT_ISALIGNED(pbuf)) ? \
 731             (struct T_opthdr *)(pbuf) : (struct T_opthdr *)0)
 732 
 733 #define _TPI_TOPT_NEXTHDR(pbuf, buflen, popt) \
 734         (((char *)(popt) + _TPI_ALIGN_TOPT((popt)->len)) < \
 735             ((char *)(pbuf) + (buflen)) ?  \
 736         (struct T_opthdr *)((char *)(popt) + _TPI_ALIGN_TOPT((popt)->len)) : \
 737             (struct T_opthdr *)0)
 738 
 739 /*
 740  * bool_t
 741  * _TPI_TOPT_VALID(struct T_opthdr *tohp, char *start, char *end)
 742  *      Validate the option header at tohp, for its alignment and length.
 743  *      1. check that tohp is aligned at t_scalar_t boundary
 744  *      2. check that start <= tohp < end
 745  *      3. validate the length, should be >= sizeof(T_opthdr) and
 746  *         check that there is no pointer arithmetic overflow.
 747  *         (could be caused by a very large value for tohp->len)
 748  */
 749 
 750 #define _TPI_TOPT_VALID(tohp, start, end)                       \
 751         (__TPI_TOPT_ISALIGNED(tohp) &&                          \
 752         ((uintptr_t)(tohp) >= (uintptr_t)(start)) &&         \
 753         ((uintptr_t)(tohp) < (uintptr_t)(end)) &&            \
 754         ((ssize_t)(tohp)->len >= sizeof (struct T_opthdr)) &&     \
 755         ((uintptr_t)(tohp) + (tohp)->len <= (uintptr_t)(end)) && \
 756         ((uintptr_t)(tohp) + (tohp)->len >= (uintptr_t)(tohp) +   \
 757             sizeof (struct T_opthdr)))
 758 
 759 #ifdef __cplusplus
 760 }
 761 #endif
 762 
 763 #endif /* _SYS_TIHDR_H */