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