xref: /trueos/sys/sys/mach/message.h (revision 16d1bdc48d4af6c24d88395d77ebe359f763877c)
1 /*
2  * Copyright 1991-1998 by Open Software Foundation, Inc.
3  *              All Rights Reserved
4  *
5  * Permission to use, copy, modify, and distribute this software and
6  * its documentation for any purpose and without fee is hereby granted,
7  * provided that the above copyright notice appears in all copies and
8  * that both the copyright notice and this permission notice appear in
9  * supporting documentation.
10  *
11  * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
12  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
13  * FOR A PARTICULAR PURPOSE.
14  *
15  * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
16  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17  * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
18  * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
19  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  */
21 /*
22  * MkLinux
23  */
24 /* CMU_HIST */
25 /*
26  * Revision 2.11.2.2  92/03/03  16:22:15  jeffreyh
27  * 	Changes from TRUNK
28  * 	[92/02/26  12:10:31  jeffreyh]
29  *
30  * Revision 2.12  92/01/15  13:44:29  rpd
31  * 	Changed MACH_IPC_COMPAT conditionals to default to not present.
32  *
33  * Revision 2.11.2.1  92/01/03  16:36:23  jsb
34  * 	Added MACH_MSGH_BITS_MIGRATED (NORMA_IPC internal).
35  * 	[91/12/25  16:42:44  jsb]
36  *
37  * Revision 2.11  91/10/09  16:12:14  af
38  * 	Revision 2.10.1.1  91/10/05  15:44:57  rpd
39  *  	Added check for __STDC__ to get function prototypes.
40  *  	Removed MACH_MSGH_KIND_NOTIFICATION compatibility definition.
41  *
42  * Revision 2.10  91/08/28  11:15:27  jsb
43  * 	Replaced msgh_kind with msgh_seqno.
44  * 	[91/08/09            rpd]
45  *
46  * Revision 2.9  91/08/03  18:19:05  jsb
47  * 	Added MACH_MSGH_BITS_COMPLEX_{PORTS,DATA}.
48  * 	[91/07/04  12:38:13  jsb]
49  *
50  * Revision 2.8  91/05/14  16:56:21  mrt
51  * 	Correcting copyright
52  *
53  * Revision 2.7  91/02/05  17:34:12  mrt
54  * 	Changed to new Mach copyright
55  * 	[91/02/01  17:19:32  mrt]
56  *
57  * Revision 2.6  90/06/19  22:59:59  rpd
58  * 	Changed mach_msg_timeout_t to unsigned.
59  * 	[90/06/06            rpd]
60  *
61  * Revision 2.5  90/06/02  14:59:06  rpd
62  * 	Revised the comments.
63  * 	[90/05/13            rpd]
64  * 	Converted to new IPC.
65  * 	[90/03/26  22:36:07  rpd]
66  *
67  *
68  * Condensed history:
69  *	Named unused bits in message structures (rpd).
70  *	Added MSG_TYPE_POLYMORPHIC (rpd).
71  *	Put ownership rights under MACH_IPC_XXXHACK (rpd).
72  * 	Removed some unused defines (rpd).
73  *	Made MSG_TYPE_PORT_NAME a separate type (rpd).
74  *	Added SEND_SWITCH (mwyoung).
75  *	Added SEND_MSG_SIZE_CHANGE (mwyoung).
76  *	Added msg_size_t, msg_timeout_t (mwyoung).
77  *	Added MSG_TYPE_INTERNAL_MEMORY (mwyoung).
78  *	Use unsigned ints/shorts (avie).
79  *	Added SEND_INTERRUPT (mwyoung).
80  */
81 /* CMU_ENDHIST */
82 /*
83  * Mach Operating System
84  * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
85  * All Rights Reserved.
86  *
87  * Permission to use, copy, modify and distribute this software and its
88  * documentation is hereby granted, provided that both the copyright
89  * notice and this permission notice appear in all copies of the
90  * software, derivative works or modified versions, and any portions
91  * thereof, and that both notices appear in supporting documentation.
92  *
93  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
94  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
95  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
96  *
97  * Carnegie Mellon requests users of this software to return to
98  *
99  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
100  *  School of Computer Science
101  *  Carnegie Mellon University
102  *  Pittsburgh PA 15213-3890
103  *
104  * any improvements or extensions that they make and grant Carnegie Mellon
105  * the rights to redistribute these changes.
106  */
107 /*
108  */
109 /*
110  *	File:	mach/message.h
111  *
112  *	Mach IPC message and primitive function definitions.
113  */
114 
115 #ifndef	_MACH_MESSAGE_H_
116 #define _MACH_MESSAGE_H_
117 
118 #define MACH_ASSERT 0
119 #define MACH_KDB 0
120 #define NCPUS (SMP ? 32 : 1)
121 #define NORMA_VM 0
122 
123 #include <sys/cdefs.h>
124 #include <sys/types.h>
125 #include <sys/param.h>
126 #include <vm/vm.h>
127 #include <sys/mach/kern_return.h>
128 #include <sys/mach/port.h>
129 
130 
131 /*
132  *  The timeout mechanism uses mach_msg_timeout_t values,
133  *  passed by value.  The timeout units are milliseconds.
134  *  It is controlled with the MACH_SEND_TIMEOUT
135  *  and MACH_RCV_TIMEOUT options.
136  */
137 
138 typedef natural_t mach_msg_timeout_t;
139 
140 typedef char *mach_msg_trailer_info_t;
141 
142 /*
143  *  The value to be used when there is no timeout.
144  *  (No MACH_SEND_TIMEOUT/MACH_RCV_TIMEOUT option.)
145  */
146 
147 #define MACH_MSG_TIMEOUT_NONE		((mach_msg_timeout_t) 0)
148 
149 /*
150  *  The kernel uses MACH_MSGH_BITS_COMPLEX as a hint.  It it isn't on, it
151  *  assumes the body of the message doesn't contain port rights or OOL
152  *  data.  The field is set in received messages.  A user task must
153  *  use caution in interpreting the body of a message if the bit isn't
154  *  on, because the mach_msg_type's in the body might "lie" about the
155  *  contents.  If the bit isn't on, but the mach_msg_types
156  *  in the body specify rights or OOL data, the behavior is undefined.
157  *  (Ie, an error may or may not be produced.)
158  *
159  *  The value of MACH_MSGH_BITS_REMOTE determines the interpretation
160  *  of the msgh_remote_port field.  It is handled like a msgt_name.
161  *
162  *  The value of MACH_MSGH_BITS_LOCAL determines the interpretation
163  *  of the msgh_local_port field.  It is handled like a msgt_name.
164  *
165  *  MACH_MSGH_BITS() combines two MACH_MSG_TYPE_* values, for the remote
166  *  and local fields, into a single value suitable for msgh_bits.
167  *
168  *  MACH_MSGH_BITS_CIRCULAR should be zero; is is used internally.
169  *
170  *  MACH_MSGH_BITS_RTALLOC indicates that rtalloc/rtfree should be used
171  *  instead of kalloc/kfree for the kmsg and associated data buffers.
172  *
173  *  The unused bits should be zero and are reserved for the kernel
174  *  or for future interface expansion.
175  */
176 
177 #define MACH_MSGH_BITS_ZERO		0x00000000
178 
179 #define MACH_MSGH_BITS_REMOTE_MASK	0x0000001f
180 #define MACH_MSGH_BITS_LOCAL_MASK	0x00001f00
181 #define MACH_MSGH_BITS_VOUCHER_MASK	0x001f0000
182 
183 #define	MACH_MSGH_BITS_PORTS_MASK		\
184 		(MACH_MSGH_BITS_REMOTE_MASK |	\
185 		 MACH_MSGH_BITS_LOCAL_MASK |	\
186 		 MACH_MSGH_BITS_VOUCHER_MASK)
187 
188 #define MACH_MSGH_BITS_COMPLEX		0x80000000U
189 #define	MACH_MSGH_BITS_CIRCULAR		0x10000000	/* internal use only */
190 
191 #define MACH_MSGH_BITS(remote, local)				\
192 	((remote) | ((local) << 8))
193 #define	MACH_MSGH_BITS_SET_PORTS(remote, local, voucher)	\
194 	(((remote) & MACH_MSGH_BITS_REMOTE_MASK) | 		\
195 	 (((local) << 8) & MACH_MSGH_BITS_LOCAL_MASK) | 	\
196 	 (((voucher) << 16) & MACH_MSGH_BITS_VOUCHER_MASK))
197 #define MACH_MSGH_BITS_SET(remote, local, voucher, other)	\
198 	(MACH_MSGH_BITS_SET_PORTS((remote), (local), (voucher)) \
199 	 | ((other) &~ MACH_MSGH_BITS_PORTS_MASK))
200 
201 #define	MACH_MSGH_BITS_REMOTE(bits)				\
202 		((bits) & MACH_MSGH_BITS_REMOTE_MASK)
203 #define	MACH_MSGH_BITS_LOCAL(bits)				\
204 		(((bits) & MACH_MSGH_BITS_LOCAL_MASK) >> 8)
205 #define	MACH_MSGH_BITS_PORTS(bits)				\
206 		((bits) & MACH_MSGH_BITS_PORTS_MASK)
207 #define	MACH_MSGH_BITS_OTHER(bits)				\
208 		((bits) &~ MACH_MSGH_BITS_PORTS_MASK)
209 
210 /*
211  *  Every message starts with a message header.
212  *  Following the message header are zero or more pairs of
213  *  type descriptors (mach_msg_type_t/mach_msg_type_long_t) and
214  *  data values.  The size of the message must be specified in bytes,
215  *  and includes the message header, type descriptors, inline
216  *  data, and inline pointer for out-of-line data.
217  *
218  *  The msgh_remote_port field specifies the destination of the message.
219  *  It must specify a valid send or send-once right for a port.
220  *
221  *  The msgh_local_port field specifies a "reply port".  Normally,
222  *  This field carries a send-once right that the receiver will use
223  *  to reply to the message.  It may carry the values MACH_PORT_NULL,
224  *  MACH_PORT_DEAD, a send-once right, or a send right.
225  *
226  *  The msgh_seqno field carries a sequence number associated with the
227  *  received-from port.  A port's sequence number is incremented every
228  *  time a message is received from it.  In sent messages, the field's
229  *  value is ignored.
230  *
231  *  The msgh_id field is uninterpreted by the message primitives.
232  *  It normally carries information specifying the format
233  *  or meaning of the message.
234  */
235 
236 typedef unsigned int mach_msg_bits_t;
237 typedef	natural_t mach_msg_size_t;
238 typedef integer_t mach_msg_id_t;
239 
240 
241 #define MACH_MSG_SIZE_NULL (mach_msg_size_t *) 0
242 
243 typedef uint8_t mach_msg_type_name_t;
244 
245 #define MACH_MSG_TYPE_MOVE_RECEIVE	16	/* Must hold receive rights */
246 #define MACH_MSG_TYPE_MOVE_SEND		17	/* Must hold send rights */
247 #define MACH_MSG_TYPE_MOVE_SEND_ONCE	18	/* Must hold sendonce rights */
248 #define MACH_MSG_TYPE_COPY_SEND		19	/* Must hold send rights */
249 #define MACH_MSG_TYPE_MAKE_SEND		20	/* Must hold receive rights */
250 #define MACH_MSG_TYPE_MAKE_SEND_ONCE	21	/* Must hold receive rights */
251 
252 #define MACH_MSG_TYPE_DISPOSE_RECEIVE	24	/* must hold receive right */
253 #define MACH_MSG_TYPE_DISPOSE_SEND	25	/* must hold send right(s) */
254 #define MACH_MSG_TYPE_DISPOSE_SEND_ONCE 26	/* must hold sendonce right */
255 
256 typedef unsigned int mach_msg_copy_options_t;
257 
258 #define MACH_MSG_PHYSICAL_COPY		0
259 #define MACH_MSG_VIRTUAL_COPY   	1
260 #define MACH_MSG_ALLOCATE		2
261 #define MACH_MSG_OVERWRITE		3
262 #ifdef  _KERNEL
263 #define MACH_MSG_KALLOC_COPY_T		4
264 #define MACH_MSG_PAGE_LIST_COPY_T	5
265 #endif  /* MACH_KERNEL */
266 
267 
268 typedef unsigned int mach_msg_descriptor_type_t;
269 
270 #define MACH_MSG_PORT_DESCRIPTOR 		0
271 #define MACH_MSG_OOL_DESCRIPTOR  		1
272 #define MACH_MSG_OOL_PORTS_DESCRIPTOR 		2
273 #define MACH_MSG_OOL_VOLATILE_DESCRIPTOR  	3
274 
275 
276 #pragma pack(4)
277 
278 typedef struct
279 {
280   natural_t         pad1;
281   mach_msg_size_t		pad2;
282   unsigned int			pad3 : 24;
283   mach_msg_descriptor_type_t	type : 8;
284 } mach_msg_type_descriptor_t;
285 
286 typedef struct
287 {
288 	mach_port_t			name;
289 #if !(defined(_KERNEL) && defined(__LP64__))
290 	mach_msg_size_t		pad1;
291 	unsigned int			pad2 : 16;
292 #else
293 	mach_msg_size_t		pad1 : 8;
294 	unsigned int			pad2 : 8;
295 #endif
296 	mach_msg_type_name_t		disposition : 8;
297 	mach_msg_descriptor_type_t	type : 8;
298 #if defined(_KERNEL)
299   uint32_t      pad_end;
300 #endif
301 } mach_msg_port_descriptor_t;
302 
303 typedef struct
304 {
305   uint32_t			address;
306   mach_msg_size_t       	size;
307   boolean_t     		deallocate: 8;
308   mach_msg_copy_options_t       copy: 8;
309   unsigned int     		pad1: 8;
310   mach_msg_descriptor_type_t    type: 8;
311 } mach_msg_ool_descriptor32_t;
312 
313 typedef struct
314 {
315   uint64_t			address;
316   boolean_t     		deallocate: 8;
317   mach_msg_copy_options_t       copy: 8;
318   unsigned int     		pad1: 8;
319   mach_msg_descriptor_type_t    type: 8;
320   mach_msg_size_t       	size;
321 } mach_msg_ool_descriptor64_t;
322 
323 typedef struct
324 {
325   void* address;
326 #ifndef __LP64__
327   mach_msg_size_t       	size;
328 #endif
329   boolean_t     		deallocate: 8;
330   mach_msg_copy_options_t       copy: 8;
331   unsigned int     		pad1: 8;
332   mach_msg_descriptor_type_t    type: 8;
333 #ifdef __LP64__
334   mach_msg_size_t       	size;
335 #endif
336 #if defined(KERNEL) && !defined(__LP64__)
337   uint32_t          pad_end;
338 #endif
339 } mach_msg_ool_descriptor_t;
340 
341 typedef struct
342 {
343   uint32_t			address;
344   mach_msg_size_t		count;
345   boolean_t     		deallocate: 8;
346   mach_msg_copy_options_t       copy: 8;
347   mach_msg_type_name_t		disposition : 8;
348   mach_msg_descriptor_type_t	type : 8;
349 } mach_msg_ool_ports_descriptor32_t;
350 
351 typedef struct
352 {
353   uint64_t			address;
354   boolean_t     		deallocate: 8;
355   mach_msg_copy_options_t       copy: 8;
356   mach_msg_type_name_t		disposition : 8;
357   mach_msg_descriptor_type_t	type : 8;
358   mach_msg_size_t		count;
359 } mach_msg_ool_ports_descriptor64_t;
360 
361 typedef struct
362 {
363   void*				address;
364   boolean_t     		deallocate: 8;
365   mach_msg_copy_options_t       copy: 8;
366   mach_msg_type_name_t		disposition : 8;
367   mach_msg_descriptor_type_t  type : 8;
368   mach_msg_size_t   count;
369 } mach_msg_ool_ports_descriptor_t;
370 
371 typedef union
372 {
373   mach_msg_port_descriptor_t		port;
374   mach_msg_ool_descriptor_t		out_of_line;
375   mach_msg_ool_ports_descriptor_t	ool_ports;
376   mach_msg_type_descriptor_t		type;
377 } mach_msg_descriptor_t;
378 
379 typedef struct
380 {
381         mach_msg_size_t msgh_descriptor_count;
382 } mach_msg_body_t;
383 
384 #define MACH_MSG_BODY_NULL (mach_msg_body_t *) 0
385 #define MACH_MSG_DESCRIPTOR_NULL (mach_msg_descriptor_t *) 0
386 
387 typedef	struct
388 {
389   mach_msg_bits_t	msgh_bits;
390   mach_msg_size_t	msgh_size;
391   mach_port_t		msgh_remote_port;
392   mach_port_t		msgh_local_port;
393   mach_port_name_t 	msgh_voucher_port;
394   mach_msg_id_t		msgh_id;
395 } mach_msg_header_t;
396 
397 #define	msgh_reserved		msgh_voucher_port
398 #define MACH_MSG_NULL (mach_msg_header_t *) 0
399 
400 typedef struct
401 {
402         mach_msg_header_t       header;
403         mach_msg_body_t         body;
404 } mach_msg_base_t;
405 
406 typedef	unsigned int mach_msg_trailer_type_t;
407 
408 #define	MACH_MSG_TRAILER_FORMAT_0	0
409 
410 typedef	unsigned int mach_msg_trailer_size_t;
411 
412 typedef struct
413 {
414   mach_msg_trailer_type_t	msgh_trailer_type;
415   mach_msg_trailer_size_t	msgh_trailer_size;
416 } mach_msg_trailer_t;
417 
418 typedef struct
419 {
420   mach_msg_trailer_type_t       msgh_trailer_type;
421   mach_msg_trailer_size_t       msgh_trailer_size;
422   mach_port_seqno_t             msgh_seqno;
423 } mach_msg_seqno_trailer_t;
424 
425 typedef struct
426 {
427   unsigned int			val[2];
428 } security_token_t;
429 
430 typedef struct
431 {
432   mach_msg_trailer_type_t	msgh_trailer_type;
433   mach_msg_trailer_size_t	msgh_trailer_size;
434   mach_port_seqno_t		msgh_seqno;
435   security_token_t		msgh_sender;
436 } mach_msg_security_trailer_t;
437 
438 /*
439  * The audit token is an opaque token which identifies
440  * Mach tasks and senders of Mach messages as subjects
441  * to the BSM audit system.  Only the appropriate BSM
442  * library routines should be used to interpret the
443  * contents of the audit token as the representation
444  * of the subject identity within the token may change
445  * over time.
446  */
447 typedef struct
448 {
449   unsigned int                  val[8];
450 } audit_token_t;
451 
452 typedef struct
453 {
454   mach_msg_trailer_type_t       msgh_trailer_type;
455   mach_msg_trailer_size_t       msgh_trailer_size;
456   mach_port_seqno_t             msgh_seqno;
457   security_token_t              msgh_sender;
458   audit_token_t                 msgh_audit;
459 } mach_msg_audit_trailer_t;
460 
461 typedef struct
462 {
463   mach_msg_trailer_type_t       msgh_trailer_type;
464   mach_msg_trailer_size_t       msgh_trailer_size;
465   mach_port_seqno_t             msgh_seqno;
466   security_token_t              msgh_sender;
467   audit_token_t                 msgh_audit;
468   mach_port_context_t           msgh_context;
469 } mach_msg_context_trailer_t;
470 
471 typedef struct
472 {
473   mach_port_name_t sender;
474 } msg_labels_t;
475 
476 /*
477    Trailer type to pass MAC policy label info as a mach message trailer.
478 */
479 
480 typedef struct
481 {
482   mach_msg_trailer_type_t       msgh_trailer_type;
483   mach_msg_trailer_size_t       msgh_trailer_size;
484   mach_port_seqno_t             msgh_seqno;
485   security_token_t              msgh_sender;
486   audit_token_t                 msgh_audit;
487   mach_port_context_t           msgh_context;
488   int                           msgh_ad;
489   msg_labels_t                  msgh_labels;
490 } mach_msg_mac_trailer_t;
491 
492 
493 #define MACH_MSG_TRAILER_MINIMUM_SIZE  sizeof(mach_msg_trailer_t)
494 
495 /*
496  * These values can change from release to release - but clearly
497  * code cannot request additional trailer elements one was not
498  * compiled to understand.  Therefore, it is safe to use this
499  * constant when the same module specified the receive options.
500  * Otherwise, you run the risk that the options requested by
501  * another module may exceed the local modules notion of
502  * MAX_TRAILER_SIZE.
503  */
504 
505 typedef mach_msg_mac_trailer_t mach_msg_max_trailer_t;
506 #define MAX_TRAILER_SIZE ((mach_msg_size_t)sizeof(mach_msg_max_trailer_t))
507 
508 typedef mach_msg_security_trailer_t mach_msg_format_0_trailer_t;
509 
510 #define MACH_MSG_TRAILER_FORMAT_0_SIZE sizeof(mach_msg_format_0_trailer_t)
511 #define MACH_MSG_TRAILER_MINIMUM_SIZE  sizeof(mach_msg_trailer_t)
512 #define   KERNEL_SECURITY_TOKEN_VALUE  { {0, 1} }
513 extern security_token_t KERNEL_SECURITY_TOKEN;
514 
515 #define   KERNEL_AUDIT_TOKEN_VALUE  { {0, 0, 0, 0, 0, 0, 0, 0} }
516 extern audit_token_t KERNEL_AUDIT_TOKEN;
517 
518 typedef	integer_t mach_msg_options_t;
519 
520 typedef struct
521 {
522   mach_msg_header_t	header;
523 } mach_msg_empty_send_t;
524 
525 typedef struct
526 {
527   mach_msg_header_t	header;
528   mach_msg_trailer_t	trailer;
529 } mach_msg_empty_rcv_t;
530 
531 typedef union
532 {
533   mach_msg_empty_send_t	send;
534   mach_msg_empty_rcv_t	rcv;
535 } mach_msg_empty_t;
536 
537 #pragma pack()
538 
539 /* utility to round the message size - will become machine dependent */
540 #define round_msg(x)	(((mach_msg_size_t)(x) + sizeof (natural_t) - 1) & \
541 				~(sizeof (natural_t) - 1))
542 
543 /*
544  *  There is no fixed upper bound to the size of Mach messages.
545  */
546 
547 #define	MACH_MSG_SIZE_MAX	((mach_msg_size_t) ~0)
548 
549 /*
550  *  Compatibility definitions, for code written
551  *  when there was a msgh_kind instead of msgh_seqno.
552  */
553 
554 #define MACH_MSGH_KIND_NORMAL		0x00000000
555 #if	0
556 /* code using this is likely to break, so better not to have it defined */
557 #define MACH_MSGH_KIND_NOTIFICATION	0x00000001
558 #endif
559 #define	msgh_kind			msgh_seqno
560 #define mach_msg_kind_t			mach_port_seqno_t
561 
562 /*
563  *  The msgt_number field specifies the number of data elements.
564  *  The msgt_size field specifies the size of each data element, in bits.
565  *  The msgt_name field specifies the type of each data element.
566  *  If msgt_inline is TRUE, the data follows the type descriptor
567  *  in the body of the message.  If msgt_inline is FALSE, then a pointer
568  *  to the data should follow the type descriptor, and the data is
569  *  sent out-of-line.  In this case, if msgt_deallocate is TRUE,
570  *  then the out-of-line data is moved (instead of copied) into the message.
571  *  If msgt_longform is TRUE, then the type descriptor is actually
572  *  a mach_msg_type_long_t.
573  *
574  *  The actual amount of inline data following the descriptor must
575  *  a multiple of the word size.  For out-of-line data, this is a
576  *  pointer.  For inline data, the supplied data size (calculated
577  *  from msgt_number/msgt_size) is rounded up.  This guarantees
578  *  that type descriptors always fall on word boundaries.
579  *
580  *  For port rights, msgt_size must be 8*sizeof(mach_port_t).
581  *  If the data is inline, msgt_deallocate should be FALSE.
582  *  The msgt_unused bit should be zero.
583  *  The msgt_name, msgt_size, msgt_number fields in
584  *  a mach_msg_type_long_t should be zero.
585  */
586 
587 typedef natural_t mach_msg_type_size_t;
588 typedef natural_t mach_msg_type_number_t;
589 
590 /*
591  *  Values received/carried in messages.  Tells the receiver what
592  *  sort of port right he now has.
593  *
594  *  MACH_MSG_TYPE_PORT_NAME is used to transfer a port name
595  *  which should remain uninterpreted by the kernel.  (Port rights
596  *  are not transferred, just the port name.)
597  */
598 
599 #define MACH_MSG_TYPE_PORT_NONE		0
600 
601 #define MACH_MSG_TYPE_PORT_NAME		15
602 #define MACH_MSG_TYPE_PORT_RECEIVE	MACH_MSG_TYPE_MOVE_RECEIVE
603 #define MACH_MSG_TYPE_PORT_SEND		MACH_MSG_TYPE_MOVE_SEND
604 #define MACH_MSG_TYPE_PORT_SEND_ONCE	MACH_MSG_TYPE_MOVE_SEND_ONCE
605 
606 #define MACH_MSG_TYPE_LAST		22		/* Last assigned */
607 
608 /*
609  *  A dummy value.  Mostly used to indicate that the actual value
610  *  will be filled in later, dynamically.
611  */
612 
613 #define MACH_MSG_TYPE_POLYMORPHIC	((mach_msg_type_name_t) -1)
614 
615 /*
616  *	Is a given item a port type?
617  */
618 
619 #define MACH_MSG_TYPE_PORT_ANY(x)			\
620 	(((x) >= MACH_MSG_TYPE_MOVE_RECEIVE) &&		\
621 	 ((x) <= MACH_MSG_TYPE_MAKE_SEND_ONCE))
622 
623 #define	MACH_MSG_TYPE_PORT_ANY_SEND(x)			\
624 	(((x) >= MACH_MSG_TYPE_MOVE_SEND) &&		\
625 	 ((x) <= MACH_MSG_TYPE_MAKE_SEND_ONCE))
626 
627 #define	MACH_MSG_TYPE_PORT_ANY_RIGHT(x)			\
628 	(((x) >= MACH_MSG_TYPE_MOVE_RECEIVE) &&		\
629 	 ((x) <= MACH_MSG_TYPE_MOVE_SEND_ONCE))
630 
631 typedef integer_t mach_msg_option_t;
632 
633 #define MACH_MSG_OPTION_NONE	0x00000000
634 
635 #define	MACH_SEND_MSG		0x00000001
636 #define	MACH_RCV_MSG		0x00000002
637 #define MACH_RCV_LARGE          0x00000004      /* report large message sizes */
638 #define MACH_RCV_LARGE_IDENTITY 0x00000008      /* identify source of large messages */
639 
640 
641 #define MACH_SEND_TIMEOUT	0x00000010
642 #define MACH_SEND_INTERRUPT	0x00000040	/* libmach implements */
643 #define MACH_SEND_NOTIFY	0x00000080
644 #define MACH_SEND_ALWAYS	0x00010000	/* internal use only */
645 #define MACH_SEND_TRAILER	0x00020000
646 
647 
648 
649 #define MACH_RCV_TIMEOUT	0x00000100
650 #define MACH_RCV_NOTIFY		0x00000200
651 #define MACH_RCV_INTERRUPT	0x00000400	/* libmach implements */
652 #define MACH_RCV_VOUCHER	0x00000800	/* willing to receive voucher port */
653 #define MACH_RCV_OVERWRITE	0x00001000
654 
655 /*
656  * NOTE: a 0x00------ RCV mask implies to ask for
657  * a MACH_MSG_TRAILER_FORMAT_0 with 0 Elements,
658  * which is equivalent to a mach_msg_trailer_t.
659  */
660 #define MACH_RCV_TRAILER_NULL   0
661 #define MACH_RCV_TRAILER_SEQNO  1
662 #define MACH_RCV_TRAILER_SENDER 2
663 #define MACH_RCV_TRAILER_AUDIT  3
664 #define MACH_RCV_TRAILER_CTX    4
665 #define MACH_RCV_TRAILER_AV     7
666 #define MACH_RCV_TRAILER_LABELS 8
667 
668 
669 #define MACH_RCV_TRAILER_TYPE(x)     (((x) & 0xf) << 28)
670 #define MACH_RCV_TRAILER_ELEMENTS(x) (((x) & 0xf) << 24)
671 #define MACH_RCV_TRAILER_MASK 	     ((0xff << 24))
672 
673 
674 #define GET_RCV_ELEMENTS(y) (((y) >> 24) & 0xf)
675 
676 #ifdef _KERNEL
677 /* The options that the kernel honors when passed from user space */
678 #define MACH_SEND_USER		 (MACH_SEND_MSG | \
679 				  MACH_SEND_TIMEOUT | MACH_SEND_NOTIFY | \
680 				  MACH_SEND_TRAILER)
681 
682 #define MACH_RCV_USER		 (MACH_RCV_MSG | \
683 				  MACH_RCV_TIMEOUT | MACH_RCV_OVERWRITE | \
684 				  MACH_RCV_LARGE | MACH_RCV_LARGE_IDENTITY | \
685 				  MACH_RCV_TRAILER_MASK)
686 
687 #define MACH_MSG_OPTION_USER	 (MACH_SEND_USER | MACH_RCV_USER)
688 #endif
689 
690 /*
691  * XXXMAC: note that in the case of MACH_RCV_TRAILER_LABELS,
692  * we just fall through to mach_msg_max_trailer_t.
693  * This is correct behavior since mach_msg_max_trailer_t is defined as
694  * mac_msg_mac_trailer_t which is used for the LABELS trailer.
695  * It also makes things work properly if MACH_RCV_TRAILER_LABELS is ORed
696  * with one of the other options.
697  */
698 
699 #define REQUESTED_TRAILER_SIZE_NATIVE(y)                        \
700         ((mach_msg_trailer_size_t)                              \
701          ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_NULL) ?      \
702           sizeof(mach_msg_trailer_t) :                          \
703           ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_SEQNO) ?    \
704            sizeof(mach_msg_seqno_trailer_t) :                   \
705           ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_SENDER) ?   \
706            sizeof(mach_msg_security_trailer_t) :                \
707            ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_AUDIT) ?   \
708             sizeof(mach_msg_audit_trailer_t) :                  \
709             ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_CTX) ?    \
710              sizeof(mach_msg_context_trailer_t) :               \
711              ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_AV) ?    \
712               sizeof(mach_msg_mac_trailer_t) :                  \
713              sizeof(mach_msg_max_trailer_t))))))))
714 
715 #define REQUESTED_TRAILER_SIZE(y) REQUESTED_TRAILER_SIZE_NATIVE(y)
716 
717 /*
718  *  Much code assumes that mach_msg_return_t == kern_return_t.
719  *  This definition is useful for descriptive purposes.
720  *
721  *  See <mach/error.h> for the format of error codes.
722  *  IPC errors are system 4.  Send errors are subsystem 0;
723  *  receive errors are subsystem 1.  The code field is always non-zero.
724  *  The high bits of the code field communicate extra information
725  *  for some error codes.  MACH_MSG_MASK masks off these special bits.
726  */
727 
728 typedef kern_return_t mach_msg_return_t;
729 
730 #define MACH_MSG_SUCCESS		0x00000000
731 
732 
733 #define	MACH_MSG_MASK			0x00003e00
734 		/* All special error code bits defined below. */
735 #define	MACH_MSG_IPC_SPACE		0x00002000
736 		/* No room in IPC name space for another capability name. */
737 #define	MACH_MSG_VM_SPACE		0x00001000
738 		/* No room in VM address space for out-of-line memory. */
739 #define	MACH_MSG_IPC_KERNEL		0x00000800
740 		/* Kernel resource shortage handling an IPC capability. */
741 #define	MACH_MSG_VM_KERNEL		0x00000400
742 		/* Kernel resource shortage handling out-of-line memory. */
743 #define MACH_MSG_INVALID_RT_DESCRIPTOR	0x00000200
744 		/* Descriptor has an option incompatible with RT
745 		   behavior */
746 
747 #define MACH_SEND_IN_PROGRESS		0x10000001
748 		/* Thread is waiting to send.  (Internal use only.) */
749 #define MACH_SEND_INVALID_DATA		0x10000002
750 		/* Bogus in-line data. */
751 #define MACH_SEND_INVALID_DEST		0x10000003
752 		/* Bogus destination port. */
753 #define MACH_SEND_TIMED_OUT		0x10000004
754 		/* Message not sent before timeout expired. */
755 #define MACH_SEND_INVALID_VOUCHER	0x10000005
756 		/* Bogus voucher port. */
757 #define MACH_SEND_INTERRUPTED		0x10000007
758 		/* Software interrupt. */
759 #define MACH_SEND_MSG_TOO_SMALL		0x10000008
760 		/* Data doesn't contain a complete message. */
761 #define MACH_SEND_INVALID_REPLY		0x10000009
762 		/* Bogus reply port. */
763 #define MACH_SEND_INVALID_RIGHT		0x1000000a
764 		/* Bogus port rights in the message body. */
765 #define MACH_SEND_INVALID_NOTIFY	0x1000000b
766 		/* Bogus notify port argument. */
767 #define MACH_SEND_INVALID_MEMORY	0x1000000c
768 		/* Invalid out-of-line memory pointer. */
769 #define MACH_SEND_NO_BUFFER		0x1000000d
770 		/* No message buffer is available. */
771 #define MACH_SEND_TOO_LARGE		0x1000000e
772 		/* Send is too large for port */
773 #define MACH_SEND_INVALID_TYPE		0x1000000f
774 		/* Invalid msg-type specification. */
775 #define MACH_SEND_INVALID_HEADER	0x10000010
776 		/* A field in the header had a bad value. */
777 #define MACH_SEND_INVALID_TRAILER	0x10000011
778 		/* The trailer to be sent does not match kernel format. */
779 
780 #define MACH_SEND_INVALID_RT_OOL_SIZE	0x10000015
781 		/* The OOL buffer size is too large for RT behavior */
782 
783 #define MACH_RCV_IN_PROGRESS		0x10004001
784 		/* Thread is waiting for receive.  (Internal use only.) */
785 #define MACH_RCV_INVALID_NAME		0x10004002
786 		/* Bogus name for receive port/port-set. */
787 #define MACH_RCV_TIMED_OUT		0x10004003
788 		/* Didn't get a message within the timeout value. */
789 #define MACH_RCV_TOO_LARGE		0x10004004
790 		/* Message buffer is not large enough for inline data. */
791 #define MACH_RCV_INTERRUPTED		0x10004005
792 		/* Software interrupt. */
793 #define MACH_RCV_PORT_CHANGED		0x10004006
794 		/* Port moved into a set during the receive. */
795 #define MACH_RCV_INVALID_NOTIFY		0x10004007
796 		/* Bogus notify port argument. */
797 #define MACH_RCV_INVALID_DATA		0x10004008
798 		/* Bogus message buffer for inline data. */
799 #define MACH_RCV_PORT_DIED		0x10004009
800 		/* Port/set was sent away/died during receive. */
801 #define	MACH_RCV_IN_SET			0x1000400a
802 		/* Port is a member of a port set. */
803 #define	MACH_RCV_HEADER_ERROR		0x1000400b
804 		/* Error receiving message header.  See special bits. */
805 #define	MACH_RCV_BODY_ERROR		0x1000400c
806 		/* Error receiving message body.  See special bits. */
807 #define	MACH_RCV_INVALID_TYPE		0x1000400d
808 		/* Invalid msg-type specification in scatter list. */
809 #define	MACH_RCV_SCATTER_SMALL		0x1000400e
810 		/* Out-of-line overwrite region is not large enough */
811 #define MACH_RCV_INVALID_TRAILER	0x1000400f
812 		/* trailer type or number of trailer elements not supported */
813 #define MACH_RCV_IN_PROGRESS_TIMED      0x10004011
814                 /* Waiting for receive with timeout. (Internal use only.) */
815 
816 extern mach_msg_return_t	mach_msg_overwrite_trap(
817 					mach_msg_header_t *msg,
818 					mach_msg_option_t option,
819 					mach_msg_size_t send_size,
820 					mach_msg_size_t rcv_size,
821 					mach_port_name_t rcv_name,
822 					mach_msg_timeout_t timeout,
823 					mach_port_name_t notify,
824 					mach_msg_header_t *rcv_msg,
825 					mach_msg_size_t rcv_limit);
826 
827 extern mach_msg_return_t	mach_msg_overwrite(
828 					mach_msg_header_t *msg,
829 					mach_msg_option_t option,
830 					mach_msg_size_t send_size,
831 					mach_msg_size_t rcv_size,
832 					mach_port_name_t rcv_name,
833 					mach_msg_timeout_t timeout,
834 					mach_port_name_t notify,
835 					mach_msg_header_t *rcv_msg,
836 					mach_msg_size_t rcv_limit);
837 
838 extern mach_msg_return_t	mach_msg_trap(
839 					mach_msg_header_t *msg,
840 					mach_msg_option_t option,
841 					mach_msg_size_t send_size,
842 					mach_msg_size_t rcv_size,
843 					mach_port_name_t rcv_name,
844 					mach_msg_timeout_t timeout,
845 					mach_port_name_t notify);
846 
847 extern mach_msg_return_t	mach_msg(
848 					mach_msg_header_t *msg,
849 					mach_msg_option_t option,
850 					mach_msg_size_t send_size,
851 					mach_msg_size_t rcv_size,
852 					mach_port_name_t rcv_name,
853 					mach_msg_timeout_t timeout,
854 					mach_port_name_t notify);
855 
856 
857 #if defined(_KERNEL) && defined(MACH_INTERNAL)
858 struct thread_shuttle;
859 
860 extern mach_msg_return_t	mach_msg_receive_results(
861 					struct thread_shuttle *thread);
862 #endif
863 
864 #endif	/* _MACH_MESSAGE_H_ */
865