tihdr.h revision c28749e97052f09388969427adf7df641cdcdc22
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_TIHDR_H
#define _SYS_TIHDR_H
#pragma ident "%Z%%M% %I% %E% SMI" /* from SVr4.0 11.4 */
#include <sys/types.h>
/*
* Include declarations implicit to TPI and shared with user level code
*/
#include <sys/tpicommon.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* The feature test macro, _SUN_TPI_VERSION makes some of additional
* declarations available and changes some existing ones. There was
* some changes done to this interface and this feature test macro
* enables transitioning to those changes while maintaining retaining
* backward compatibility.
*
* The following is all the information
* needed by the Transport Service Interface.
*/
/*
* The following are the definitions of the Transport
* Service Interface primitives.
*/
/*
* Primitives that are initiated by the transport user.
*/
#define T_CONN_REQ 0 /* connection request */
#if _SUN_TPI_VERSION > 1
#define O_T_CONN_RES 1 /* old connection response */
#else
#define T_CONN_RES 1 /* connection response */
#endif /* _SUN_TPI_VERSION > 1 */
#define T_DISCON_REQ 2 /* disconnect request */
#define T_DATA_REQ 3 /* data request */
#define T_EXDATA_REQ 4 /* expedited data request */
#define T_INFO_REQ 5 /* information request */
/*
* Bind Request primitive (TLI inspired
* address binding semantics). If requested address is
* found to be busy, an alternative free address is
* returned. (Requires comparison of requested address to
* returned address to verify if the requested address was
* bound)
*
*/
#if _SUN_TPI_VERSION > 0
#define O_T_BIND_REQ 6
#else
#define T_BIND_REQ 6
#endif /* _SUN_TPI_VERSION > 0 */
#define T_UNBIND_REQ 7 /* unbind request */
#define T_UNITDATA_REQ 8 /* unitdata request */
/*
* Option management request (with TLI inspired semantics )
* The preferred name for this primitive in new code is T_SVR4_OPTMGMT_REQ.
* This primitive had the name T_OPTMGMT_REQ in old SVR4 derived TPI.
* This primitive is used for TLI and Socket API support.
* The packing of options in option buffer is private contract
* between transport provider and its users and can differ
* between different transports.
* (The name O_T_OPTMGMT_REQ continues to exist for Solaris 2.6
* compilation environment compatibility only)
*
*/
#define T_SVR4_OPTMGMT_REQ 9
#if _SUN_TPI_VERSION > 0
#define O_T_OPTMGMT_REQ T_SVR4_OPTMGMT_REQ
#else
#define T_OPTMGMT_REQ T_SVR4_OPTMGMT_REQ
#endif /* _SUN_TPI_VERSION > 0 */
#define T_ORDREL_REQ 10 /* orderly release req */
/*
* Primitives that are initiated by the transport provider.
*/
#define T_CONN_IND 11 /* connection indication */
#define T_CONN_CON 12 /* connection confirmation */
#define T_DISCON_IND 13 /* disconnect indication */
#define T_DATA_IND 14 /* data indication */
#define T_EXDATA_IND 15 /* expeditied data indication */
#define T_INFO_ACK 16 /* information acknowledgment */
#define T_BIND_ACK 17 /* bind acknowledment */
#define T_ERROR_ACK 18 /* error acknowledgment */
#define T_OK_ACK 19 /* ok acknowledgment */
#define T_UNITDATA_IND 20 /* unitdata indication */
#define T_UDERROR_IND 21 /* unitdata error indication */
#define T_OPTMGMT_ACK 22 /* manage options ack */
#define T_ORDREL_IND 23 /* orderly release ind */
/*
* Primitives added to namespace and contain a mix of ones
* initiated by transport user or provider.
*/
#define T_ADDR_REQ 24 /* address request */
#define T_ADDR_ACK 25 /* address acknowledgement */
#if _SUN_TPI_VERSION > 0
/*
* Bind request primitive with better address
* binding semantics. (XTI inspired)
* If the requested address is found to be busy,
* an error is returned. (No need to compare addresses on successful
* bind acknowledgement).
*/
#define T_BIND_REQ 26 /* bind request */
/*
* Option management request (with XTI inspired semantics)
* The packing of options in option buffer is required to
* be with 'struct T_opthdr' data structure defined later in
* this header.
*/
#define T_OPTMGMT_REQ 27 /* manage options req - T_opthdr option header */
#endif /* _SUN_TPI_VERSION > 0 */
#if _SUN_TPI_VERSION > 1
/*
* The connection response that expects its ACCEPTOR_id to have been
* filled in from the value supplied via a T_CAPABILITY_ACK.
*/
#define T_CONN_RES 28 /* connection response */
/*
* Capability request and ack. These primitives are optional and
* subsume the functionality of T_INFO_{REQ,ACK}.
*/
#define T_CAPABILITY_REQ 30
#define T_CAPABILITY_ACK 31
#endif /* _SUN_TPI_VERSION > 1 */
#ifdef _KERNEL
/*
* Sun private TPI extensions. They are currently used for transparently
* passing options through the connection-oriented loopback transport,
* and for setting the kernel SSL proxy.
* Values assigned to them may change.
*
* T_EXTCONN_IND (extended T_CONN_IND) is used to return dst as well as
* src addr/port.
*/
#define T_OPTDATA_REQ 0x1001 /* data (with options) request */
#define T_OPTDATA_IND 0x1002 /* data (with options) indication */
#define T_EXTCONN_IND 0x1003 /* extended T_CONN_IND to return dst as well */
#define T_SSL_PROXY_BIND_REQ 0x1004 /* extended T_BIND_REQ to carry a */
/* kssl_entry_t to the transport. */
#define T_SSL_PROXY_CONN_IND 0x1005 /* conn_ind from an SSL proxy */
/* endpoint, carrying a kssl_ctx_t */
#endif /* _KERNEL */
/*
* The following are the events that drive the state machine
*/
/* Initialization events */
#define TE_BIND_REQ 0 /* bind request */
#define TE_UNBIND_REQ 1 /* unbind request */
#define TE_OPTMGMT_REQ 2 /* manage options req */
#define TE_BIND_ACK 3 /* bind acknowledment */
#define TE_OPTMGMT_ACK 4 /* manage options ack */
#define TE_ERROR_ACK 5 /* error acknowledgment */
#define TE_OK_ACK1 6 /* ok ack seqcnt == 0 */
#define TE_OK_ACK2 7 /* ok ack seqcnt == 1, q == resq */
#define TE_OK_ACK3 8 /* ok ack seqcnt == 1, q != resq */
#define TE_OK_ACK4 9 /* ok ack seqcnt > 1 */
/* Connection oriented events */
#define TE_CONN_REQ 10 /* connection request */
#define TE_CONN_RES 11 /* connection response */
#define TE_DISCON_REQ 12 /* disconnect request */
#define TE_DATA_REQ 13 /* data request */
#define TE_EXDATA_REQ 14 /* expedited data request */
#define TE_ORDREL_REQ 15 /* orderly release req */
#define TE_CONN_IND 16 /* connection indication */
#define TE_CONN_CON 17 /* connection confirmation */
#define TE_DATA_IND 18 /* data indication */
#define TE_EXDATA_IND 19 /* expedited data indication */
#define TE_ORDREL_IND 20 /* orderly release ind */
#define TE_DISCON_IND1 21 /* disconnect indication seq == 0 */
#define TE_DISCON_IND2 22 /* disconnect indication seq == 1 */
#define TE_DISCON_IND3 23 /* disconnect indication seq > 1 */
#define TE_PASS_CONN 24 /* pass connection */
/* Unit data events */
#define TE_UNITDATA_REQ 25 /* unitdata request */
#define TE_UNITDATA_IND 26 /* unitdata indication */
#define TE_UDERROR_IND 27 /* unitdata error indication */
#define TE_NOEVENTS 28
/*
* The following are the possible states of the Transport
* Service Interface
*/
#define TS_UNBND 0 /* unbound */
#define TS_WACK_BREQ 1 /* waiting ack of BIND_REQ */
#define TS_WACK_UREQ 2 /* waiting ack of UNBIND_REQ */
#define TS_IDLE 3 /* idle */
#define TS_WACK_OPTREQ 4 /* wait ack options request */
#define TS_WACK_CREQ 5 /* waiting ack of CONN_REQ */
#define TS_WCON_CREQ 6 /* waiting confirm of CONN_REQ */
#define TS_WRES_CIND 7 /* waiting response of CONN_IND */
#define TS_WACK_CRES 8 /* waiting ack of CONN_RES */
#define TS_DATA_XFER 9 /* data transfer */
#define TS_WIND_ORDREL 10 /* releasing rd but not wr */
#define TS_WREQ_ORDREL 11 /* wait to release wr but not rd */
#define TS_WACK_DREQ6 12 /* waiting ack of DISCON_REQ */
#define TS_WACK_DREQ7 13 /* waiting ack of DISCON_REQ */
#define TS_WACK_DREQ9 14 /* waiting ack of DISCON_REQ */
#define TS_WACK_DREQ10 15 /* waiting ack of DISCON_REQ */
#define TS_WACK_DREQ11 16 /* waiting ack of DISCON_REQ */
#define TS_NOSTATES 17
/*
* The following structure definitions define the format of the
* stream message block of the above primitives.
* (everything is declared t_scalar_t to ensure proper alignment
* across different machines)
*/
/* connection request */
struct T_conn_req {
t_scalar_t PRIM_type; /* always T_CONN_REQ */
t_scalar_t DEST_length; /* dest addr length */
t_scalar_t DEST_offset; /* dest addr offset */
t_scalar_t OPT_length; /* options length */
t_scalar_t OPT_offset; /* options offset */
};
/* connect response */
/*
* Historical compatibility note for "struct T_conn_res" usage.
* "QUEUE_ptr" field of type "queue_t" is obsolete to support
* code portability and application binary compatibility
* between ILP32(32-bit) and LP64 (64-bit) environments.
* Use field "ACCEPTOR_id" instead.
* For compatibility, drivers using (_SUN_TPI_VERSION >= 2) interface
* can support treating ACCEPTOR_id content as queue pointer
* only when PRIM_type is O_T_CONN_RES.
*/
struct T_conn_res {
t_scalar_t PRIM_type; /* T_CONN_RES (or O_T_CONN_RES) */
t_uscalar_t ACCEPTOR_id; /* id of accepting endpoint */
t_scalar_t OPT_length; /* options length */
t_scalar_t OPT_offset; /* options offset */
t_scalar_t SEQ_number; /* sequence number */
};
/* disconnect request */
struct T_discon_req {
t_scalar_t PRIM_type; /* always T_DISCON_REQ */
t_scalar_t SEQ_number; /* sequnce number */
};
/* data request */
struct T_data_req {
t_scalar_t PRIM_type; /* always T_DATA_REQ */
t_scalar_t MORE_flag; /* more data */
};
/* expedited data request */
struct T_exdata_req {
t_scalar_t PRIM_type; /* always T_EXDATA_REQ */
t_scalar_t MORE_flag; /* more data */
};
/* information request */
struct T_info_req {
t_scalar_t PRIM_type; /* always T_INFO_REQ */
};
/* bind request */
struct T_bind_req {
t_scalar_t PRIM_type; /* T_BIND_REQ (or O_T_BIND_REQ) */
t_scalar_t ADDR_length; /* addr length */
t_scalar_t ADDR_offset; /* addr offset */
t_uscalar_t CONIND_number; /* connect indications requested */
};
/* unbind request */
struct T_unbind_req {
t_scalar_t PRIM_type; /* always T_UNBIND_REQ */
};
/* unitdata request */
struct T_unitdata_req {
t_scalar_t PRIM_type; /* always T_UNITDATA_REQ */
t_scalar_t DEST_length; /* dest addr length */
t_scalar_t DEST_offset; /* dest addr offset */
t_scalar_t OPT_length; /* options length */
t_scalar_t OPT_offset; /* options offset */
};
/* manage options request */
struct T_optmgmt_req {
t_scalar_t PRIM_type; /* T_OPTMGMT_REQ or */
/* T_SVR4_OPTMGMT_REQ */
t_scalar_t OPT_length; /* options length */
t_scalar_t OPT_offset; /* options offset */
t_scalar_t MGMT_flags; /* options flags */
};
/* orderly release request */
struct T_ordrel_req {
t_scalar_t PRIM_type; /* always T_ORDREL_REQ */
};
/* protocol address request */
struct T_addr_req {
t_scalar_t PRIM_type; /* always T_ADDR_REQ */
};
/* connect indication */
struct T_conn_ind {
t_scalar_t PRIM_type; /* always T_CONN_IND */
t_scalar_t SRC_length; /* src addr length */
t_scalar_t SRC_offset; /* src addr offset */
t_scalar_t OPT_length; /* option length */
t_scalar_t OPT_offset; /* option offset */
t_scalar_t SEQ_number; /* sequnce number */
};
/* connect confirmation */
struct T_conn_con {
t_scalar_t PRIM_type; /* always T_CONN_CON */
t_scalar_t RES_length; /* responding addr length */
t_scalar_t RES_offset; /* responding addr offset */
t_scalar_t OPT_length; /* option length */
t_scalar_t OPT_offset; /* option offset */
};
/* disconnect indication */
struct T_discon_ind {
t_scalar_t PRIM_type; /* always T_DISCON_IND */
t_scalar_t DISCON_reason; /* disconnect reason */
t_scalar_t SEQ_number; /* sequnce number */
};
/* data indication */
struct T_data_ind {
t_scalar_t PRIM_type; /* always T_DATA_IND */
t_scalar_t MORE_flag; /* more data */
};
/* expedited data indication */
struct T_exdata_ind {
t_scalar_t PRIM_type; /* always T_EXDATA_IND */
t_scalar_t MORE_flag; /* more data */
};
/* information acknowledgment */
struct T_info_ack {
t_scalar_t PRIM_type; /* always T_INFO_ACK */
t_scalar_t TSDU_size; /* max TSDU size */
t_scalar_t ETSDU_size; /* max ETSDU size */
t_scalar_t CDATA_size; /* max connect data size */
t_scalar_t DDATA_size; /* max discon data size */
t_scalar_t ADDR_size; /* address size */
t_scalar_t OPT_size; /* options size */
t_scalar_t TIDU_size; /* max TIDU size */
t_scalar_t SERV_type; /* provider service type */
t_scalar_t CURRENT_state; /* current state */
t_scalar_t PROVIDER_flag; /* provider flags */
};
/*
* The following are definitions of flags available to the transport
* provider to set in the PROVIDER_flag field of the T_info_ack
* structure.
*/
#if _SUN_TPI_VERSION > 0
#define SENDZERO 0x0001 /* provider can handle --length TSDUs */
#define OLD_SENDZERO 0x1000 /* reserved for compatibility with */
/* old providers- old value of */
/* SENDZERO defined in <sys/timod.h> */
#else
#define SENDZERO 0x1000 /* old SENDZERO value */
#endif /* _SUN_TPI_VERSION > 0 */
#define EXPINLINE 0x0002 /* provider wants ETSDUs in band 0 */
/*
* Flag XPG4_1:
* transport provider supports TPI modifications motivated by and
* in conjunction with XTI inspired TPI support and all the
* compatibility baggage that implies.
* It implies, - primitives T_ADDR_REQ & T_ADDR_ACK supported
* - primitives O_T_BIND_REQ & T_BIND_REQ separately supported
* - primitives T_SVR4_OPTMGMT_REQ & T_OPTMGMT_REQ separately
* supported.
*/
#define XPG4_1 0x0004
/* bind acknowledgment */
struct T_bind_ack {
t_scalar_t PRIM_type; /* always T_BIND_ACK */
t_scalar_t ADDR_length; /* addr length */
t_scalar_t ADDR_offset; /* addr offset */
t_uscalar_t CONIND_number; /* connect ind to be queued */
};
/* error acknowledgment */
struct T_error_ack {
t_scalar_t PRIM_type; /* always T_ERROR_ACK */
t_scalar_t ERROR_prim; /* primitive in error */
t_scalar_t TLI_error; /* TLI error code */
t_scalar_t UNIX_error; /* UNIX error code */
};
/* ok acknowledgment */
struct T_ok_ack {
t_scalar_t PRIM_type; /* always T_OK_ACK */
t_scalar_t CORRECT_prim; /* correct primitive */
};
/* unitdata indication */
struct T_unitdata_ind {
t_scalar_t PRIM_type; /* always T_UNITDATA_IND */
t_scalar_t SRC_length; /* source addr length */
t_scalar_t SRC_offset; /* source addr offset */
t_scalar_t OPT_length; /* options length */
t_scalar_t OPT_offset; /* options offset */
};
/* unitdata error indication */
struct T_uderror_ind {
t_scalar_t PRIM_type; /* always T_UDERROR_IND */
t_scalar_t DEST_length; /* dest addr length */
t_scalar_t DEST_offset; /* dest addr offset */
t_scalar_t OPT_length; /* options length */
t_scalar_t OPT_offset; /* options offset */
t_scalar_t ERROR_type; /* error type */
};
/* manage options ack */
struct T_optmgmt_ack {
t_scalar_t PRIM_type; /* always T_OPTMGMT_ACK */
t_scalar_t OPT_length; /* options length */
t_scalar_t OPT_offset; /* options offset */
t_scalar_t MGMT_flags; /* managment flags */
};
/* orderly release indication */
struct T_ordrel_ind {
t_scalar_t PRIM_type; /* always T_ORDREL_IND */
};
/* protocol address acknowledgment */
struct T_addr_ack {
t_scalar_t PRIM_type; /* always T_ADDR_ACK */
t_scalar_t LOCADDR_length; /* length of local address */
t_scalar_t LOCADDR_offset; /* offset of local address */
t_scalar_t REMADDR_length; /* length of remote address */
t_scalar_t REMADDR_offset; /* offset of remote address */
};
#if _SUN_TPI_VERSION > 1
/*
* Capability request and ack. These primitives are optional and
* subsume the functionality of T_INFO_{REQ,ACK}.
*/
struct T_capability_req {
t_scalar_t PRIM_type; /* always T_CAPABILITY_REQ */
t_uscalar_t CAP_bits1; /* capability bits #1 */
};
struct T_capability_ack {
t_scalar_t PRIM_type; /* always T_CAPABILITY_ACK */
t_uscalar_t CAP_bits1; /* capability bits #1 */
struct T_info_ack
INFO_ack; /* info acknowledgement */
t_uscalar_t ACCEPTOR_id; /* accepting endpoint id */
};
#define TC1_INFO (1u << 0) /* Info request/ack */
#define TC1_ACCEPTOR_ID (1u << 1) /* Acceptor_id request/ack */
#define TC1_CAP_BITS2 (1u << 31) /* Reserved for future use */
#endif /* _SUN_TPI_VERSION > 1 */
#ifdef _KERNEL
/*
* Private Sun TPI extensions.
*/
/* data (with options) request */
struct T_optdata_req {
t_scalar_t PRIM_type; /* always T_OPTDATA_REQ */
t_scalar_t DATA_flag; /* flags like "more data" */
t_scalar_t OPT_length; /* options length */
t_scalar_t OPT_offset; /* options offset */
};
/* data (with options) indication */
struct T_optdata_ind {
t_scalar_t PRIM_type; /* always T_OPTDATA_IND */
t_scalar_t DATA_flag; /* flags like "more data" */
t_scalar_t OPT_length; /* options length */
t_scalar_t OPT_offset; /* options offset */
};
/* extended connect indication to return dst addr/port as well as src */
struct T_extconn_ind {
t_scalar_t PRIM_type; /* always T_EXTCONN_IND */
t_scalar_t SRC_length; /* src addr length */
t_scalar_t SRC_offset; /* src addr offset */
t_scalar_t OPT_length; /* option length */
t_scalar_t OPT_offset; /* option offset */
t_scalar_t SEQ_number; /* sequnce number */
t_scalar_t DEST_length; /* dest addr length */
t_scalar_t DEST_offset; /* dest addr offset */
};
#endif /* _KERNEL */
/*
* The following is a union of the primitives
*/
union T_primitives {
t_scalar_t type; /* primitive type */
struct T_conn_req conn_req; /* connect request */
struct T_conn_res conn_res; /* connect response */
struct T_discon_req discon_req; /* disconnect request */
struct T_data_req data_req; /* data request */
struct T_exdata_req exdata_req; /* expedited data req */
struct T_info_req info_req; /* information req */
struct T_bind_req bind_req; /* bind request */
struct T_unbind_req unbind_req; /* unbind request */
struct T_unitdata_req unitdata_req; /* unitdata requset */
struct T_optmgmt_req optmgmt_req; /* manage opt req */
struct T_ordrel_req ordrel_req; /* orderly rel req */
struct T_addr_req addr_req; /* address request */
struct T_conn_ind conn_ind; /* connect indication */
struct T_conn_con conn_con; /* connect corfirm */
struct T_discon_ind discon_ind; /* discon indication */
struct T_data_ind data_ind; /* data indication */
struct T_exdata_ind exdata_ind; /* expedited data ind */
struct T_info_ack info_ack; /* info ack */
struct T_bind_ack bind_ack; /* bind ack */
struct T_error_ack error_ack; /* error ack */
struct T_ok_ack ok_ack; /* ok ack */
struct T_unitdata_ind unitdata_ind; /* unitdata ind */
struct T_uderror_ind uderror_ind; /* unitdata error ind */
struct T_optmgmt_ack optmgmt_ack; /* manage opt ack */
struct T_ordrel_ind ordrel_ind; /* orderly rel ind */
struct T_addr_ack addr_ack; /* address ack */
#if _SUN_TPI_VERSION > 1
struct T_capability_req capability_req; /* capability req */
struct T_capability_ack capability_ack; /* capability ack */
#endif /* _SUN_TPI_VERSION > 1 */
#ifdef _KERNEL
struct T_optdata_req optdata_req; /* option data request */
struct T_optdata_ind optdata_ind; /* option data ind */
struct T_extconn_ind extconn_ind; /* above plus dst addr */
#endif /* _KERNEL */
};
/*
* TPI specification is not clear on how to pack options in option
* buffers. What follows is the Solaris TPI interpretation of it.
*
* struct T_opthdr data structure is used to pack options in T_OPTMGMT_{REQ,ACK}
* message primitives in buffer delimited by [OPT_offset, OPT_length] fields in
* struct T_optmgmt_req/T_optmgmt_ack data structures.
*
* It is also used to pack options in similar buffers for data structures in
* T_CONN_{REQ,IND,RES,CONN} primitives and T_UNITDATA_{REQ,IND} primitives
* Needs to be on t_uscalar_t (32-bit word) aligned boundary.
*
* Note: T_SVR4_OPTMGMT_REQ primitive can, but need not, use this data
* structure for packing options. The format of option buffer for
* T_SVR4_OPTMGMT_REQ primitive is undefined and is a private contract
* between transport provider and its users.
*
* |<--------------first option---------------->| |<--second option--...
* ______________________________________ _ _ _ ____________________________
* | len | level | name | status | value.......| / / | len ...
* -------------------------------------- - - - ----------------------------
* |32bit| 32bit |32bit | 32bit | ^ | 32bit...
* |
* |
* alignment characters
*/
struct T_opthdr {
t_uscalar_t len; /* total length of option (header+value) */
t_uscalar_t level; /* protocol level */
t_uscalar_t name; /* option name */
t_uscalar_t status; /* status value */
/* option value aligned on t_uscalar_t (32-bit) alignment boundary */
};
/*
* ------------------------------------------------------------------------
* Common experimental private TPI alignment related macros. Not for
* use outside Solaris bundled code and can change in any release.
* The alignment boundary _TPI_ALIGN_SIZE represents an implementation
* choice for aligning many data objects which are directly or indirectly
* associated with Solaris TPI implementation.
* ------------------------------------------------------------------------
*/
#define __TPI_ALIGN_SIZE (sizeof (t_scalar_t))
#define __TPI_ALIGN(x) \
(((uintptr_t)(x) + __TPI_ALIGN_SIZE - 1) & ~(__TPI_ALIGN_SIZE - 1))
#define __TPI_SIZE_ISALIGNED(x) \
(((uintptr_t)(x) & (__TPI_ALIGN_SIZE - 1)) == 0)
/*
* TPI primitive in message must be aligned at _TPI_ALIGN_SIZE boundary
*/
#define __TPI_PRIM_ISALIGNED(x) __TPI_SIZE_ISALIGNED(x)
/*
* TPI option header "struct opthdr" objects must be aligned
* at __TPI_ALIGN_SIZE boundary.
*/
#define __TPI_OPT_ISALIGNED(x) __TPI_SIZE_ISALIGNED(x)
#define _TPI_ALIGN_OPT(x) __TPI_ALIGN(x)
/*
* TPI option header "struct T_opthdr" objects must be aligned
* at __TPI_ALIGN_SIZE boundary.
*/
#define __TPI_TOPT_ISALIGNED(x) __TPI_SIZE_ISALIGNED(x)
#define _TPI_ALIGN_TOPT(x) __TPI_ALIGN(x)
/*
* --------------------------------------------------------------------
* Private experimental macros. Not for use outside Solaris bundled
* source code and can change in any release.
* Macros that operate on struct T_opthdr. These are roughly modelled
* after the corresponding Socket CMSG_*() and XTI T_OPT_*() macros, but
* are applied to TPI option buffers.
* --------------------------------------------------------------------
*
* unsigned char *
* _TPI_TOPT_DATA(struct T_opthdr *tohp):
* Get start of data part after option header
*/
#define _TPI_TOPT_DATA(tohp) \
((unsigned char *)((char *)(tohp) + sizeof (struct T_opthdr)))
/*
* t_uscalar_t
* _TPI_TOPT_DATALEN(tohp)
* Get length of contents of option data excluding header (and
* padding etc if any).
*/
#define _TPI_TOPT_DATALEN(tohp) ((tohp)->len - sizeof (struct T_opthdr))
/*
* struct T_opthdr *
* _TPI_TOPT_FIRSTHDR(char *pbuf, t_scalar_t buflen):
* Get pointer to the first option header in buffer 'pbuf'
* Return NULL if there is not enough room for the header
*
* struct T_opthdr *
* _TPI_TOPT_NEXTHDR(char *pbuf, t_scalar_t buflen,
* struct T_opthdr *popt):
* Skip to next option header
*
* Notes: _TPI_TOPT_NEXTHDR performs the roundup of the length.
*
* If _TPI_TOPT_{FIRST,NEXT}HDR returns a non-null value, the user of
* _TPI_TOPT_{FIRST,NEXT}HDR must still verify that the resulting pointer
* is valid, by making a call to _TPI_TOPT_VALID. The _TPI_TOPT_VALID
* macro does not assume that the last option buffer is padded.
*/
#define _TPI_TOPT_FIRSTHDR(pbuf, buflen) \
((((buflen) >= (unsigned int) sizeof (struct T_opthdr)) && \
__TPI_TOPT_ISALIGNED(pbuf)) ? \
(struct T_opthdr *)(pbuf) : (struct T_opthdr *)0)
#define _TPI_TOPT_NEXTHDR(pbuf, buflen, popt) \
(((char *)(popt) + _TPI_ALIGN_TOPT((popt)->len)) < \
((char *)(pbuf) + (buflen)) ? \
(struct T_opthdr *)((char *)(popt) + _TPI_ALIGN_TOPT((popt)->len)) : \
(struct T_opthdr *)0)
/*
* bool_t
* _TPI_TOPT_VALID(struct T_opthdr *tohp, char *start, char *end)
* Validate the option header at tohp, for its alignment and length.
* 1. check that tohp is aligned at t_scalar_t boundary
* 2. check that start <= tohp < end
* 3. validate the length, should be >= sizeof(T_opthdr) and
* check that there is no pointer arithmetic overflow.
* (could be caused by a very large value for tohp->len)
*/
#define _TPI_TOPT_VALID(tohp, start, end) \
(__TPI_TOPT_ISALIGNED(tohp) && \
((uintptr_t)(tohp) >= (uintptr_t)(start)) && \
((uintptr_t)(tohp) < (uintptr_t)(end)) && \
((ssize_t)(tohp)->len >= sizeof (struct T_opthdr)) && \
((uintptr_t)(tohp) + (tohp)->len <= (uintptr_t)(end)) && \
((uintptr_t)(tohp) + (tohp)->len >= (uintptr_t)(tohp) + \
sizeof (struct T_opthdr)))
#ifdef __cplusplus
}
#endif
#endif /* _SYS_TIHDR_H */