/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (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 (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2020 Joyent, Inc. */ #ifndef _SYS_TIHDR_H #define _SYS_TIHDR_H #include /* * Include declarations implicit to TPI and shared with user level code */ #include #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. * 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 */ #endif /* _KERNEL */ /* * 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 */ #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 */