xref: /illumos-gate/usr/src/uts/common/sys/tihdr.h (revision b8ffbd3111b44e6c578236149ddc6140effd3dc2)
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 */
727