xref: /titanic_52/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c (revision c586600796766c83eb9485c446886fd9ed2359a9)
1dc20a302Sas200622 /*
2dc20a302Sas200622  * CDDL HEADER START
3dc20a302Sas200622  *
4dc20a302Sas200622  * The contents of this file are subject to the terms of the
5dc20a302Sas200622  * Common Development and Distribution License (the "License").
6dc20a302Sas200622  * You may not use this file except in compliance with the License.
7dc20a302Sas200622  *
8dc20a302Sas200622  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9dc20a302Sas200622  * or http://www.opensolaris.org/os/licensing.
10dc20a302Sas200622  * See the License for the specific language governing permissions
11dc20a302Sas200622  * and limitations under the License.
12dc20a302Sas200622  *
13dc20a302Sas200622  * When distributing Covered Code, include this CDDL HEADER in each
14dc20a302Sas200622  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15dc20a302Sas200622  * If applicable, add the following below this CDDL HEADER, with the
16dc20a302Sas200622  * fields enclosed by brackets "[]" replaced with your own identifying
17dc20a302Sas200622  * information: Portions Copyright [yyyy] [name of copyright owner]
18dc20a302Sas200622  *
19dc20a302Sas200622  * CDDL HEADER END
20dc20a302Sas200622  */
21dc20a302Sas200622 /*
22*c5866007SKeyur Desai  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23dc20a302Sas200622  */
24dc20a302Sas200622 
25b1352070SAlan Wright #include <assert.h>
26dc20a302Sas200622 #include <strings.h>
27dc20a302Sas200622 #include <sys/param.h>
28dc20a302Sas200622 
29dc20a302Sas200622 #include <smbsrv/libsmb.h>
308d7e4166Sjose borrego #include <smbsrv/libmlrpc.h>
31dc20a302Sas200622 
32dc20a302Sas200622 #ifdef _BIG_ENDIAN
338d7e4166Sjose borrego static const int ndr_native_byte_order = NDR_REPLAB_INTG_BIG_ENDIAN;
34dc20a302Sas200622 #else
358d7e4166Sjose borrego static const int ndr_native_byte_order = NDR_REPLAB_INTG_LITTLE_ENDIAN;
36dc20a302Sas200622 #endif
37dc20a302Sas200622 
38b1352070SAlan Wright static int ndr_decode_hdr_common(ndr_stream_t *, ndr_common_header_t *);
39*c5866007SKeyur Desai static int ndr_decode_pac_hdr(ndr_stream_t *, ndr_pac_hdr_t *);
40b1352070SAlan Wright 
41b1352070SAlan Wright static int
42b1352070SAlan Wright ndr_encode_decode_common(ndr_stream_t *nds, unsigned opnum,
438d7e4166Sjose borrego     ndr_typeinfo_t *ti, void *datum)
44dc20a302Sas200622 {
45dc20a302Sas200622 	int rc;
46dc20a302Sas200622 
47dc20a302Sas200622 	/*
48dc20a302Sas200622 	 * Perform the (un)marshalling
49dc20a302Sas200622 	 */
508d7e4166Sjose borrego 	if (ndo_operation(nds, ti, opnum, datum))
518d7e4166Sjose borrego 		return (NDR_DRC_OK);
52dc20a302Sas200622 
538d7e4166Sjose borrego 	switch (nds->error) {
54dc20a302Sas200622 	case NDR_ERR_MALLOC_FAILED:
558d7e4166Sjose borrego 		rc = NDR_DRC_FAULT_OUT_OF_MEMORY;
56dc20a302Sas200622 		break;
57dc20a302Sas200622 
58dc20a302Sas200622 	case NDR_ERR_SWITCH_VALUE_INVALID:
598d7e4166Sjose borrego 		rc = NDR_DRC_FAULT_PARAM_0_INVALID;
60dc20a302Sas200622 		break;
61dc20a302Sas200622 
62dc20a302Sas200622 	case NDR_ERR_UNDERFLOW:
638d7e4166Sjose borrego 		rc = NDR_DRC_FAULT_RECEIVED_RUNT;
64dc20a302Sas200622 		break;
65dc20a302Sas200622 
66dc20a302Sas200622 	case NDR_ERR_GROW_FAILED:
678d7e4166Sjose borrego 		rc = NDR_DRC_FAULT_ENCODE_TOO_BIG;
68dc20a302Sas200622 		break;
69dc20a302Sas200622 
70dc20a302Sas200622 	default:
71b1352070SAlan Wright 		if (nds->m_op == NDR_M_OP_MARSHALL)
728d7e4166Sjose borrego 			rc = NDR_DRC_FAULT_ENCODE_FAILED;
73dc20a302Sas200622 		else
748d7e4166Sjose borrego 			rc = NDR_DRC_FAULT_DECODE_FAILED;
75dc20a302Sas200622 		break;
76dc20a302Sas200622 	}
77dc20a302Sas200622 
78dc20a302Sas200622 	return (rc);
79dc20a302Sas200622 }
80dc20a302Sas200622 
81b1352070SAlan Wright ndr_buf_t *
82b1352070SAlan Wright ndr_buf_init(ndr_typeinfo_t *ti)
83b1352070SAlan Wright {
84b1352070SAlan Wright 	ndr_buf_t		*nbuf;
85b1352070SAlan Wright 
86b1352070SAlan Wright 	if ((nbuf = calloc(1, sizeof (ndr_buf_t))) == NULL)
87b1352070SAlan Wright 		return (NULL);
88b1352070SAlan Wright 
89b1352070SAlan Wright 	if ((nbuf->nb_heap = ndr_heap_create()) == NULL) {
90b1352070SAlan Wright 		free(nbuf);
91b1352070SAlan Wright 		return (NULL);
92b1352070SAlan Wright 	}
93b1352070SAlan Wright 
94b1352070SAlan Wright 	nbuf->nb_ti = ti;
95b1352070SAlan Wright 	nbuf->nb_magic = NDR_BUF_MAGIC;
96b1352070SAlan Wright 	return (nbuf);
97b1352070SAlan Wright }
98b1352070SAlan Wright 
99b1352070SAlan Wright void
100b1352070SAlan Wright ndr_buf_fini(ndr_buf_t *nbuf)
101b1352070SAlan Wright {
102b1352070SAlan Wright 	assert(nbuf->nb_magic == NDR_BUF_MAGIC);
103b1352070SAlan Wright 
104b1352070SAlan Wright 	nds_destruct(&nbuf->nb_nds);
105b1352070SAlan Wright 	ndr_heap_destroy(nbuf->nb_heap);
106b1352070SAlan Wright 	nbuf->nb_magic = 0;
107b1352070SAlan Wright 	free(nbuf);
108b1352070SAlan Wright }
109b1352070SAlan Wright 
110b1352070SAlan Wright /*
111b1352070SAlan Wright  * Decode an NDR encoded buffer.  The buffer is expected to contain
112b1352070SAlan Wright  * a single fragment packet with a valid PDU header followed by NDR
113b1352070SAlan Wright  * encoded data.  The structure to which result points should be
114b1352070SAlan Wright  * of the appropriate type to hold the decoded output.  For example:
115b1352070SAlan Wright  *
116b1352070SAlan Wright  *	pac_info_t info;
117b1352070SAlan Wright  *
118b1352070SAlan Wright  * 	if ((nbuf = ndr_buf_init(&TYPEINFO(ndr_pac)) != NULL) {
119b1352070SAlan Wright  *		rc = ndr_decode_buf(nbuf, opnum, data, datalen, &info);
120b1352070SAlan Wright  *		...
121b1352070SAlan Wright  *		ndr_buf_fini(nbuf);
122b1352070SAlan Wright  *	}
123b1352070SAlan Wright  */
124b1352070SAlan Wright int
125*c5866007SKeyur Desai ndr_buf_decode(ndr_buf_t *nbuf, unsigned hdr_type, unsigned opnum,
126*c5866007SKeyur Desai     const char *data, size_t datalen, void *result)
127b1352070SAlan Wright {
128b1352070SAlan Wright 	ndr_common_header_t	hdr;
129*c5866007SKeyur Desai 	ndr_pac_hdr_t		pac_hdr;
130b1352070SAlan Wright 	unsigned		pdu_size_hint;
131b1352070SAlan Wright 	int			rc;
132b1352070SAlan Wright 
133b1352070SAlan Wright 	assert(nbuf->nb_magic == NDR_BUF_MAGIC);
134b1352070SAlan Wright 	assert(nbuf->nb_heap != NULL);
135b1352070SAlan Wright 	assert(nbuf->nb_ti != NULL);
136b1352070SAlan Wright 
137b1352070SAlan Wright 	if (datalen < NDR_PDU_SIZE_HINT_DEFAULT)
138b1352070SAlan Wright 		pdu_size_hint = NDR_PDU_SIZE_HINT_DEFAULT;
139b1352070SAlan Wright 	else
140b1352070SAlan Wright 		pdu_size_hint = datalen;
141b1352070SAlan Wright 
142fe1c642dSBill Krier 	rc = nds_initialize(&nbuf->nb_nds, pdu_size_hint, NDR_MODE_BUF_DECODE,
143b1352070SAlan Wright 	    nbuf->nb_heap);
144fe1c642dSBill Krier 	if (NDR_DRC_IS_FAULT(rc))
145fe1c642dSBill Krier 		return (rc);
146fe1c642dSBill Krier 
147b1352070SAlan Wright 	bcopy(data, nbuf->nb_nds.pdu_base_addr, datalen);
148b1352070SAlan Wright 
149*c5866007SKeyur Desai 	switch (hdr_type) {
150*c5866007SKeyur Desai 	case NDR_PTYPE_COMMON:
151b1352070SAlan Wright 		rc = ndr_decode_hdr_common(&nbuf->nb_nds, &hdr);
152b1352070SAlan Wright 		if (NDR_DRC_IS_FAULT(rc))
153b1352070SAlan Wright 			return (rc);
154b1352070SAlan Wright 
155b1352070SAlan Wright 		if (!NDR_IS_SINGLE_FRAG(hdr.pfc_flags))
156fe1c642dSBill Krier 			return (NDR_DRC_FAULT_DECODE_FAILED);
157*c5866007SKeyur Desai 		break;
158*c5866007SKeyur Desai 
159*c5866007SKeyur Desai 	case NDR_PTYPE_PAC:
160*c5866007SKeyur Desai 		rc = ndr_decode_pac_hdr(&nbuf->nb_nds, &pac_hdr);
161*c5866007SKeyur Desai 		if (NDR_DRC_IS_FAULT(rc))
162*c5866007SKeyur Desai 			return (rc);
163*c5866007SKeyur Desai 
164*c5866007SKeyur Desai 		if (pac_hdr.common_hdr.hdrlen != sizeof (ndr_serialtype1_hdr_t))
165*c5866007SKeyur Desai 			return (NDR_DRC_FAULT_DECODE_FAILED);
166*c5866007SKeyur Desai 		break;
167*c5866007SKeyur Desai 
168*c5866007SKeyur Desai 	default:
169*c5866007SKeyur Desai 		return (NDR_ERR_UNIMPLEMENTED);
170*c5866007SKeyur Desai 	}
171b1352070SAlan Wright 
172b1352070SAlan Wright 	rc = ndr_encode_decode_common(&nbuf->nb_nds, opnum, nbuf->nb_ti,
173b1352070SAlan Wright 	    result);
174b1352070SAlan Wright 	return (rc);
175b1352070SAlan Wright }
176b1352070SAlan Wright 
177b1352070SAlan Wright /*
178b1352070SAlan Wright  * Use the receive stream to unmarshall data (NDR_MODE_CALL_RECV).
179b1352070SAlan Wright  */
180dc20a302Sas200622 int
1818d7e4166Sjose borrego ndr_decode_call(ndr_xa_t *mxa, void *params)
182dc20a302Sas200622 {
183b1352070SAlan Wright 	ndr_stream_t	*nds = &mxa->recv_nds;
184dc20a302Sas200622 	int		rc;
185dc20a302Sas200622 
186b1352070SAlan Wright 	if (!NDR_MODE_MATCH(nds, NDR_MODE_CALL_RECV))
187b1352070SAlan Wright 		return (NDR_DRC_FAULT_MODE_MISMATCH);
188b1352070SAlan Wright 
189b1352070SAlan Wright 	rc = ndr_encode_decode_common(nds, mxa->opnum,
190b1352070SAlan Wright 	    mxa->binding->service->interface_ti, params);
191dc20a302Sas200622 
1928d7e4166Sjose borrego 	return (rc + NDR_PTYPE_REQUEST);
193dc20a302Sas200622 }
194dc20a302Sas200622 
195b1352070SAlan Wright /*
196b1352070SAlan Wright  * Use the send stream to marshall data (NDR_MODE_RETURN_SEND).
197b1352070SAlan Wright  */
198dc20a302Sas200622 int
1998d7e4166Sjose borrego ndr_encode_return(ndr_xa_t *mxa, void *params)
200dc20a302Sas200622 {
201b1352070SAlan Wright 	ndr_stream_t	*nds = &mxa->send_nds;
202dc20a302Sas200622 	int		rc;
203dc20a302Sas200622 
204b1352070SAlan Wright 	if (!NDR_MODE_MATCH(nds, NDR_MODE_RETURN_SEND))
205b1352070SAlan Wright 		return (NDR_DRC_FAULT_MODE_MISMATCH);
206b1352070SAlan Wright 
207b1352070SAlan Wright 	rc = ndr_encode_decode_common(nds, mxa->opnum,
208b1352070SAlan Wright 	    mxa->binding->service->interface_ti, params);
209dc20a302Sas200622 
2108d7e4166Sjose borrego 	return (rc + NDR_PTYPE_RESPONSE);
211dc20a302Sas200622 }
212dc20a302Sas200622 
213b1352070SAlan Wright /*
214b1352070SAlan Wright  * Use the send stream to marshall data (NDR_MODE_CALL_SEND).
215b1352070SAlan Wright  */
216dc20a302Sas200622 int
2178d7e4166Sjose borrego ndr_encode_call(ndr_xa_t *mxa, void *params)
218dc20a302Sas200622 {
219b1352070SAlan Wright 	ndr_stream_t	*nds = &mxa->send_nds;
220dc20a302Sas200622 	int		rc;
221dc20a302Sas200622 
222b1352070SAlan Wright 	if (!NDR_MODE_MATCH(nds, NDR_MODE_CALL_SEND))
223b1352070SAlan Wright 		return (NDR_DRC_FAULT_MODE_MISMATCH);
224b1352070SAlan Wright 
225b1352070SAlan Wright 	rc = ndr_encode_decode_common(nds, mxa->opnum,
226b1352070SAlan Wright 	    mxa->binding->service->interface_ti, params);
227dc20a302Sas200622 
2288d7e4166Sjose borrego 	return (rc + NDR_PTYPE_REQUEST);
229dc20a302Sas200622 }
230dc20a302Sas200622 
231b1352070SAlan Wright /*
232b1352070SAlan Wright  * Use the receive stream to unmarshall data (NDR_MODE_RETURN_RECV).
233b1352070SAlan Wright  */
234dc20a302Sas200622 int
2358d7e4166Sjose borrego ndr_decode_return(ndr_xa_t *mxa, void *params)
236dc20a302Sas200622 {
237b1352070SAlan Wright 	ndr_stream_t	*nds = &mxa->recv_nds;
238dc20a302Sas200622 	int		rc;
239dc20a302Sas200622 
240b1352070SAlan Wright 	if (!NDR_MODE_MATCH(nds, NDR_MODE_RETURN_RECV))
241b1352070SAlan Wright 		return (NDR_DRC_FAULT_MODE_MISMATCH);
242b1352070SAlan Wright 
243b1352070SAlan Wright 	rc = ndr_encode_decode_common(nds, mxa->opnum,
244b1352070SAlan Wright 	    mxa->binding->service->interface_ti, params);
245dc20a302Sas200622 
2468d7e4166Sjose borrego 	return (rc + NDR_PTYPE_RESPONSE);
247dc20a302Sas200622 }
248dc20a302Sas200622 
249dc20a302Sas200622 int
2508d7e4166Sjose borrego ndr_decode_pdu_hdr(ndr_xa_t *mxa)
251dc20a302Sas200622 {
2522c1b14e5Sjose borrego 	ndr_common_header_t	*hdr = &mxa->recv_hdr.common_hdr;
2538d7e4166Sjose borrego 	ndr_stream_t		*nds = &mxa->recv_nds;
254b1352070SAlan Wright 	int			rc;
255b1352070SAlan Wright 
256b1352070SAlan Wright 	rc = ndr_decode_hdr_common(nds, hdr);
257b1352070SAlan Wright 	if (NDR_DRC_IS_FAULT(rc))
258b1352070SAlan Wright 		return (rc);
259b1352070SAlan Wright 
260b1352070SAlan Wright 	/*
261b1352070SAlan Wright 	 * Verify the protocol version.
262b1352070SAlan Wright 	 */
263b1352070SAlan Wright 	if ((hdr->rpc_vers != 5) || (hdr->rpc_vers_minor != 0))
264*c5866007SKeyur Desai 		return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED);
265b1352070SAlan Wright 
266b1352070SAlan Wright 	mxa->ptype = hdr->ptype;
267b1352070SAlan Wright 	return (NDR_DRC_OK);
268b1352070SAlan Wright }
269b1352070SAlan Wright 
270b1352070SAlan Wright static int
271b1352070SAlan Wright ndr_decode_hdr_common(ndr_stream_t *nds, ndr_common_header_t *hdr)
272b1352070SAlan Wright {
273dc20a302Sas200622 	int			ptype;
274dc20a302Sas200622 	int			rc;
275dc20a302Sas200622 	int			charset;
276dc20a302Sas200622 	int			byte_order;
277dc20a302Sas200622 
2788d7e4166Sjose borrego 	if (nds->m_op != NDR_M_OP_UNMARSHALL)
279*c5866007SKeyur Desai 		return (NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH);
280dc20a302Sas200622 
281dc20a302Sas200622 	/*
282dc20a302Sas200622 	 * All PDU headers are at least this big
283dc20a302Sas200622 	 */
2848d7e4166Sjose borrego 	rc = NDS_GROW_PDU(nds, sizeof (ndr_common_header_t), 0);
285dc20a302Sas200622 	if (!rc)
286*c5866007SKeyur Desai 		return (NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT);
287dc20a302Sas200622 
288dc20a302Sas200622 	/*
289dc20a302Sas200622 	 * Peek at the first eight bytes to figure out what we're doing.
290dc20a302Sas200622 	 */
2918d7e4166Sjose borrego 	rc = NDS_GET_PDU(nds, 0, 8, (char *)hdr, 0, 0);
292dc20a302Sas200622 	if (!rc)
293*c5866007SKeyur Desai 		return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED);
294dc20a302Sas200622 
295dc20a302Sas200622 	/*
296dc20a302Sas200622 	 * Check for ASCII as the character set.  This is an ASCII
297dc20a302Sas200622 	 * versus EBCDIC option and has nothing to do with Unicode.
298dc20a302Sas200622 	 */
2998d7e4166Sjose borrego 	charset = hdr->packed_drep.intg_char_rep & NDR_REPLAB_CHAR_MASK;
3008d7e4166Sjose borrego 	if (charset != NDR_REPLAB_CHAR_ASCII)
301*c5866007SKeyur Desai 		return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED);
302dc20a302Sas200622 
303dc20a302Sas200622 	/*
304dc20a302Sas200622 	 * Set the byte swap flag if the PDU byte-order
305dc20a302Sas200622 	 * is different from the local byte-order.
306dc20a302Sas200622 	 */
3078d7e4166Sjose borrego 	byte_order = hdr->packed_drep.intg_char_rep & NDR_REPLAB_INTG_MASK;
3088d7e4166Sjose borrego 	nds->swap = (byte_order != ndr_native_byte_order) ? 1 : 0;
309dc20a302Sas200622 
310dc20a302Sas200622 	ptype = hdr->ptype;
3118d7e4166Sjose borrego 	if (ptype == NDR_PTYPE_REQUEST &&
3128d7e4166Sjose borrego 	    (hdr->pfc_flags & NDR_PFC_OBJECT_UUID) != 0) {
3138d7e4166Sjose borrego 		ptype = NDR_PTYPE_REQUEST_WITH;	/* fake for sizing */
314dc20a302Sas200622 	}
315dc20a302Sas200622 
316b1352070SAlan Wright 	rc = ndr_encode_decode_common(nds, ptype, &TYPEINFO(ndr_hdr), hdr);
317dc20a302Sas200622 
3188d7e4166Sjose borrego 	return (NDR_DRC_PTYPE_RPCHDR(rc));
319dc20a302Sas200622 }
320dc20a302Sas200622 
321*c5866007SKeyur Desai static int
322*c5866007SKeyur Desai ndr_decode_pac_hdr(ndr_stream_t *nds, ndr_pac_hdr_t *hdr)
323*c5866007SKeyur Desai {
324*c5866007SKeyur Desai 	int	rc;
325*c5866007SKeyur Desai 
326*c5866007SKeyur Desai 	if (nds->m_op != NDR_M_OP_UNMARSHALL)
327*c5866007SKeyur Desai 		return (NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH);
328*c5866007SKeyur Desai 
329*c5866007SKeyur Desai 	/*
330*c5866007SKeyur Desai 	 * All PDU headers are at least this big
331*c5866007SKeyur Desai 	 */
332*c5866007SKeyur Desai 	rc = NDS_GROW_PDU(nds, sizeof (ndr_pac_hdr_t), 0);
333*c5866007SKeyur Desai 	if (!rc)
334*c5866007SKeyur Desai 		return (NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT);
335*c5866007SKeyur Desai 
336*c5866007SKeyur Desai 	/*
337*c5866007SKeyur Desai 	 * Peek at the first eight bytes to figure out what we're doing.
338*c5866007SKeyur Desai 	 */
339*c5866007SKeyur Desai 	rc = NDS_GET_PDU(nds, 0, 8, (char *)hdr, 0, 0);
340*c5866007SKeyur Desai 	if (!rc)
341*c5866007SKeyur Desai 		return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED);
342*c5866007SKeyur Desai 
343*c5866007SKeyur Desai 	/* Must be set to 1 to indicate type serialization version 1. */
344*c5866007SKeyur Desai 	if (hdr->common_hdr.version != 1)
345*c5866007SKeyur Desai 		return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED);
346*c5866007SKeyur Desai 
347*c5866007SKeyur Desai 	/*
348*c5866007SKeyur Desai 	 * Set the byte swap flag if the PDU byte-order
349*c5866007SKeyur Desai 	 * is different from the local byte-order.
350*c5866007SKeyur Desai 	 */
351*c5866007SKeyur Desai 	nds->swap =
352*c5866007SKeyur Desai 	    (hdr->common_hdr.endianness != ndr_native_byte_order) ? 1 : 0;
353*c5866007SKeyur Desai 
354*c5866007SKeyur Desai 	rc = ndr_encode_decode_common(nds, NDR_PTYPE_PAC,
355*c5866007SKeyur Desai 	    &TYPEINFO(ndr_hdr), hdr);
356*c5866007SKeyur Desai 
357*c5866007SKeyur Desai 	return (NDR_DRC_PTYPE_RPCHDR(rc));
358*c5866007SKeyur Desai }
359*c5866007SKeyur Desai 
360dc20a302Sas200622 /*
3618d7e4166Sjose borrego  * Decode an RPC fragment header.  Use ndr_decode_pdu_hdr() to process
362dc20a302Sas200622  * the first fragment header then this function to process additional
363dc20a302Sas200622  * fragment headers.
364dc20a302Sas200622  */
365dc20a302Sas200622 void
3668d7e4166Sjose borrego ndr_decode_frag_hdr(ndr_stream_t *nds, ndr_common_header_t *hdr)
367dc20a302Sas200622 {
3682c1b14e5Sjose borrego 	ndr_common_header_t *tmp;
369dc20a302Sas200622 	uint8_t *pdu;
370dc20a302Sas200622 	int byte_order;
371dc20a302Sas200622 
3728d7e4166Sjose borrego 	pdu = (uint8_t *)nds->pdu_base_offset + nds->pdu_scan_offset;
3738d7e4166Sjose borrego 	bcopy(pdu, hdr, NDR_RSP_HDR_SIZE);
374dc20a302Sas200622 
375dc20a302Sas200622 	/*
376dc20a302Sas200622 	 * Swap non-byte fields if the PDU byte-order
377dc20a302Sas200622 	 * is different from the local byte-order.
378dc20a302Sas200622 	 */
3798d7e4166Sjose borrego 	byte_order = hdr->packed_drep.intg_char_rep & NDR_REPLAB_INTG_MASK;
380dc20a302Sas200622 
3818d7e4166Sjose borrego 	if (byte_order != ndr_native_byte_order) {
382dc20a302Sas200622 		/*LINTED E_BAD_PTR_CAST_ALIGN*/
3832c1b14e5Sjose borrego 		tmp = (ndr_common_header_t *)pdu;
384dc20a302Sas200622 
3858d7e4166Sjose borrego 		nds_bswap(&tmp->frag_length, &hdr->frag_length,
386dc20a302Sas200622 		    sizeof (WORD));
3878d7e4166Sjose borrego 		nds_bswap(&tmp->auth_length, &hdr->auth_length,
388dc20a302Sas200622 		    sizeof (WORD));
3898d7e4166Sjose borrego 		nds_bswap(&tmp->call_id, &hdr->call_id, sizeof (DWORD));
390dc20a302Sas200622 	}
391dc20a302Sas200622 }
392dc20a302Sas200622 
3939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
3949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Remove an RPC fragment header from the received data stream.
3959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
3969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * NDR stream on entry:
3979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
3989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *                |<--- frag --->|
3999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * +-----+--------+-----+--------+-----+---------+-----+
4009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * | hdr |  data  | hdr |  data  | hdr |  data   | ... |
4019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * +-----+--------+-----+--------+-----+---------+-----+
4029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *                 <----
4039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
4049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * NDR stream on return:
4059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
4069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * +-----+----------------+-----+---------+-----+
4079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * | hdr |       data     | hdr |  data   | ... |
4089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * +-----+----------------+-----+---------+-----+
4099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
4109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
4119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ndr_remove_frag_hdr(ndr_stream_t *nds)
4129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
4139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char	*hdr;
4149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char	*data;
4159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	nbytes;
4169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	hdr = (char *)nds->pdu_base_offset + nds->pdu_scan_offset;
4189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	data = hdr + NDR_RSP_HDR_SIZE;
4199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	nbytes = nds->pdu_size - nds->pdu_scan_offset - NDR_RSP_HDR_SIZE;
4209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bcopy(data, hdr, nbytes);
4229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	nds->pdu_size -= NDR_RSP_HDR_SIZE;
4239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
4249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4250658b32dSAlan Wright void
4260658b32dSAlan Wright ndr_show_hdr(ndr_common_header_t *hdr)
4270658b32dSAlan Wright {
4280658b32dSAlan Wright 	char	*fragtype;
4290658b32dSAlan Wright 
4300658b32dSAlan Wright 	if (hdr == NULL) {
4310658b32dSAlan Wright 		ndo_printf(NULL, NULL, "ndr hdr: <null>");
4320658b32dSAlan Wright 		return;
4330658b32dSAlan Wright 	}
4340658b32dSAlan Wright 
4350658b32dSAlan Wright 	if (NDR_IS_SINGLE_FRAG(hdr->pfc_flags))
4360658b32dSAlan Wright 		fragtype = "single";
4370658b32dSAlan Wright 	else if (NDR_IS_FIRST_FRAG(hdr->pfc_flags))
4380658b32dSAlan Wright 		fragtype = "first";
4390658b32dSAlan Wright 	else if (NDR_IS_LAST_FRAG(hdr->pfc_flags))
4400658b32dSAlan Wright 		fragtype = "last";
4410658b32dSAlan Wright 	else
4420658b32dSAlan Wright 		fragtype = "intermediate";
4430658b32dSAlan Wright 
4440658b32dSAlan Wright 	ndo_printf(NULL, NULL,
4450658b32dSAlan Wright 	    "ndr hdr: %d.%d ptype=%d, %s frag (flags=0x%08x) len=%d",
4460658b32dSAlan Wright 	    hdr->rpc_vers, hdr->rpc_vers_minor, hdr->ptype,
4470658b32dSAlan Wright 	    fragtype, hdr->pfc_flags, hdr->frag_length);
4480658b32dSAlan Wright }
4490658b32dSAlan Wright 
450dc20a302Sas200622 int
4518d7e4166Sjose borrego ndr_encode_pdu_hdr(ndr_xa_t *mxa)
452dc20a302Sas200622 {
4532c1b14e5Sjose borrego 	ndr_common_header_t	*hdr = &mxa->send_hdr.common_hdr;
4548d7e4166Sjose borrego 	ndr_stream_t		*nds = &mxa->send_nds;
455dc20a302Sas200622 	int			ptype;
456dc20a302Sas200622 	int			rc;
457dc20a302Sas200622 
4588d7e4166Sjose borrego 	if (nds->m_op != NDR_M_OP_MARSHALL)
459*c5866007SKeyur Desai 		return (NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH);
460dc20a302Sas200622 
461dc20a302Sas200622 	ptype = hdr->ptype;
4628d7e4166Sjose borrego 	if (ptype == NDR_PTYPE_REQUEST &&
4638d7e4166Sjose borrego 	    (hdr->pfc_flags & NDR_PFC_OBJECT_UUID) != 0) {
4648d7e4166Sjose borrego 		ptype = NDR_PTYPE_REQUEST_WITH;	/* fake for sizing */
465dc20a302Sas200622 	}
466dc20a302Sas200622 
467b1352070SAlan Wright 	rc = ndr_encode_decode_common(nds, ptype, &TYPEINFO(ndr_hdr), hdr);
468dc20a302Sas200622 
4698d7e4166Sjose borrego 	return (NDR_DRC_PTYPE_RPCHDR(rc));
470dc20a302Sas200622 }
471dc20a302Sas200622 
472dc20a302Sas200622 /*
473dc20a302Sas200622  * This is a hand-coded derivative of the automatically generated
474dc20a302Sas200622  * (un)marshalling routine for bind_ack headers. bind_ack headers
475dc20a302Sas200622  * have an interior conformant array, which is inconsistent with
476dc20a302Sas200622  * IDL/NDR rules.
477dc20a302Sas200622  */
478dc20a302Sas200622 extern struct ndr_typeinfo ndt__uchar;
479dc20a302Sas200622 extern struct ndr_typeinfo ndt__ushort;
480dc20a302Sas200622 extern struct ndr_typeinfo ndt__ulong;
481dc20a302Sas200622 
4828d7e4166Sjose borrego int ndr__ndr_bind_ack_hdr(ndr_ref_t *encl_ref);
4838d7e4166Sjose borrego ndr_typeinfo_t ndt__ndr_bind_ack_hdr = {
484dc20a302Sas200622     1,		/* NDR version */
485dc20a302Sas200622     3,		/* alignment */
486dc20a302Sas200622     NDR_F_STRUCT,	/* flags */
4878d7e4166Sjose borrego     ndr__ndr_bind_ack_hdr,	/* ndr_func */
488dc20a302Sas200622     68,		/* pdu_size_fixed_part */
489dc20a302Sas200622     0,		/* pdu_size_variable_part */
490dc20a302Sas200622     68,		/* c_size_fixed_part */
491dc20a302Sas200622     0,		/* c_size_variable_part */
492dc20a302Sas200622 };
493dc20a302Sas200622 
494dc20a302Sas200622 /*
495dc20a302Sas200622  * [_no_reorder]
496dc20a302Sas200622  */
497dc20a302Sas200622 int
4988d7e4166Sjose borrego ndr__ndr_bind_ack_hdr(ndr_ref_t *encl_ref)
499dc20a302Sas200622 {
5008d7e4166Sjose borrego 	ndr_stream_t		*nds = encl_ref->stream;
5012c1b14e5Sjose borrego 	struct ndr_bind_ack_hdr	*val = /*LINTED E_BAD_PTR_CAST_ALIGN*/
5022c1b14e5Sjose borrego 	    (struct ndr_bind_ack_hdr *)encl_ref->datum;
5038d7e4166Sjose borrego 	ndr_ref_t		myref;
504dc20a302Sas200622 	unsigned long		offset;
505dc20a302Sas200622 
506dc20a302Sas200622 	bzero(&myref, sizeof (myref));
507dc20a302Sas200622 	myref.enclosing = encl_ref;
508dc20a302Sas200622 	myref.stream = encl_ref->stream;
509dc20a302Sas200622 	myref.packed_alignment = 0;
510dc20a302Sas200622 
511dc20a302Sas200622 	/* do all members in order */
5122c1b14e5Sjose borrego 	NDR_MEMBER(_ndr_common_header, common_hdr, 0UL);
513dc20a302Sas200622 	NDR_MEMBER(_ushort, max_xmit_frag, 16UL);
514dc20a302Sas200622 	NDR_MEMBER(_ushort, max_recv_frag, 18UL);
515dc20a302Sas200622 	NDR_MEMBER(_ulong, assoc_group_id, 20UL);
516dc20a302Sas200622 
517dc20a302Sas200622 	/* port any is the conformant culprit */
518dc20a302Sas200622 	offset = 24UL;
519dc20a302Sas200622 
5208d7e4166Sjose borrego 	switch (nds->m_op) {
521dc20a302Sas200622 	case NDR_M_OP_MARSHALL:
522dc20a302Sas200622 		val->sec_addr.length =
523dc20a302Sas200622 		    strlen((char *)val->sec_addr.port_spec) + 1;
524dc20a302Sas200622 		break;
525dc20a302Sas200622 
526dc20a302Sas200622 	case NDR_M_OP_UNMARSHALL:
527dc20a302Sas200622 		break;
528dc20a302Sas200622 
529dc20a302Sas200622 	default:
530dc20a302Sas200622 		NDR_SET_ERROR(encl_ref, NDR_ERR_M_OP_INVALID);
531dc20a302Sas200622 		return (0);
532dc20a302Sas200622 	}
533dc20a302Sas200622 
534dc20a302Sas200622 	NDR_MEMBER(_ushort, sec_addr.length, offset);
535dc20a302Sas200622 	NDR_MEMBER_ARR_WITH_DIMENSION(_uchar, sec_addr.port_spec,
536dc20a302Sas200622 	    offset+2UL, val->sec_addr.length);
537dc20a302Sas200622 
538dc20a302Sas200622 	offset += 2;
539dc20a302Sas200622 	offset += val->sec_addr.length;
5408d7e4166Sjose borrego 	offset += NDR_ALIGN4(offset);
541dc20a302Sas200622 
5428d7e4166Sjose borrego 	NDR_MEMBER(_ndr_p_result_list, p_result_list, offset);
543dc20a302Sas200622 	return (1);
544dc20a302Sas200622 }
545dc20a302Sas200622 
5462c1b14e5Sjose borrego /*
5472c1b14e5Sjose borrego  * Assume a single presentation context element in the result list.
5482c1b14e5Sjose borrego  */
549dc20a302Sas200622 unsigned
5508d7e4166Sjose borrego ndr_bind_ack_hdr_size(ndr_xa_t *mxa)
551dc20a302Sas200622 {
5522c1b14e5Sjose borrego 	ndr_bind_ack_hdr_t *bahdr = &mxa->send_hdr.bind_ack_hdr;
553dc20a302Sas200622 	unsigned	offset;
554dc20a302Sas200622 	unsigned	length;
555dc20a302Sas200622 
556dc20a302Sas200622 	/* port any is the conformant culprit */
557dc20a302Sas200622 	offset = 24UL;
558dc20a302Sas200622 
559dc20a302Sas200622 	length = strlen((char *)bahdr->sec_addr.port_spec) + 1;
560dc20a302Sas200622 
561dc20a302Sas200622 	offset += 2;
562dc20a302Sas200622 	offset += length;
5638d7e4166Sjose borrego 	offset += NDR_ALIGN4(offset);
5648d7e4166Sjose borrego 	offset += sizeof (ndr_p_result_list_t);
5652c1b14e5Sjose borrego 	return (offset);
5662c1b14e5Sjose borrego }
5672c1b14e5Sjose borrego 
5682c1b14e5Sjose borrego /*
5692c1b14e5Sjose borrego  * This is a hand-coded derivative of the automatically generated
5702c1b14e5Sjose borrego  * (un)marshalling routine for alter_context_rsp headers.
5712c1b14e5Sjose borrego  * Alter context response headers have an interior conformant array,
5722c1b14e5Sjose borrego  * which is inconsistent with IDL/NDR rules.
5732c1b14e5Sjose borrego  */
5748d7e4166Sjose borrego int ndr__ndr_alter_context_rsp_hdr(ndr_ref_t *encl_ref);
5758d7e4166Sjose borrego ndr_typeinfo_t ndt__ndr_alter_context_rsp_hdr = {
5762c1b14e5Sjose borrego     1,			/* NDR version */
5772c1b14e5Sjose borrego     3,			/* alignment */
5782c1b14e5Sjose borrego     NDR_F_STRUCT,	/* flags */
5798d7e4166Sjose borrego     ndr__ndr_alter_context_rsp_hdr,	/* ndr_func */
5802c1b14e5Sjose borrego     56,			/* pdu_size_fixed_part */
5812c1b14e5Sjose borrego     0,			/* pdu_size_variable_part */
5822c1b14e5Sjose borrego     56,			/* c_size_fixed_part */
5832c1b14e5Sjose borrego     0,			/* c_size_variable_part */
5842c1b14e5Sjose borrego };
5852c1b14e5Sjose borrego 
5862c1b14e5Sjose borrego /*
5872c1b14e5Sjose borrego  * [_no_reorder]
5882c1b14e5Sjose borrego  */
5892c1b14e5Sjose borrego int
5908d7e4166Sjose borrego ndr__ndr_alter_context_rsp_hdr(ndr_ref_t *encl_ref)
5912c1b14e5Sjose borrego {
5928d7e4166Sjose borrego 	ndr_stream_t		*nds = encl_ref->stream;
5932c1b14e5Sjose borrego 	ndr_alter_context_rsp_hdr_t *val = /*LINTED E_BAD_PTR_CAST_ALIGN*/
5942c1b14e5Sjose borrego 	    (ndr_alter_context_rsp_hdr_t *)encl_ref->datum;
5958d7e4166Sjose borrego 	ndr_ref_t		myref;
5962c1b14e5Sjose borrego 	unsigned long		offset;
5972c1b14e5Sjose borrego 
5982c1b14e5Sjose borrego 	bzero(&myref, sizeof (myref));
5992c1b14e5Sjose borrego 	myref.enclosing = encl_ref;
6002c1b14e5Sjose borrego 	myref.stream = encl_ref->stream;
6012c1b14e5Sjose borrego 	myref.packed_alignment = 0;
6022c1b14e5Sjose borrego 
6032c1b14e5Sjose borrego 	/* do all members in order */
6042c1b14e5Sjose borrego 	NDR_MEMBER(_ndr_common_header, common_hdr, 0UL);
6052c1b14e5Sjose borrego 	NDR_MEMBER(_ushort, max_xmit_frag, 16UL);
6062c1b14e5Sjose borrego 	NDR_MEMBER(_ushort, max_recv_frag, 18UL);
6072c1b14e5Sjose borrego 	NDR_MEMBER(_ulong, assoc_group_id, 20UL);
6082c1b14e5Sjose borrego 
6092c1b14e5Sjose borrego 	offset = 24UL;	/* offset of sec_addr */
6102c1b14e5Sjose borrego 
6118d7e4166Sjose borrego 	switch (nds->m_op) {
6122c1b14e5Sjose borrego 	case NDR_M_OP_MARSHALL:
6132c1b14e5Sjose borrego 		val->sec_addr.length = 0;
6142c1b14e5Sjose borrego 		break;
6152c1b14e5Sjose borrego 
6162c1b14e5Sjose borrego 	case NDR_M_OP_UNMARSHALL:
6172c1b14e5Sjose borrego 		break;
6182c1b14e5Sjose borrego 
6192c1b14e5Sjose borrego 	default:
6202c1b14e5Sjose borrego 		NDR_SET_ERROR(encl_ref, NDR_ERR_M_OP_INVALID);
6212c1b14e5Sjose borrego 		return (0);
6222c1b14e5Sjose borrego 	}
6232c1b14e5Sjose borrego 
6242c1b14e5Sjose borrego 	NDR_MEMBER(_ushort, sec_addr.length, offset);
6252c1b14e5Sjose borrego 	NDR_MEMBER_ARR_WITH_DIMENSION(_uchar, sec_addr.port_spec,
6262c1b14e5Sjose borrego 	    offset+2UL, val->sec_addr.length);
6272c1b14e5Sjose borrego 
6282c1b14e5Sjose borrego 	offset += 2;	/* sizeof (sec_addr.length) */
6298d7e4166Sjose borrego 	offset += NDR_ALIGN4(offset);
6302c1b14e5Sjose borrego 
6318d7e4166Sjose borrego 	NDR_MEMBER(_ndr_p_result_list, p_result_list, offset);
6322c1b14e5Sjose borrego 	return (1);
6332c1b14e5Sjose borrego }
6342c1b14e5Sjose borrego 
6352c1b14e5Sjose borrego /*
6362c1b14e5Sjose borrego  * Assume a single presentation context element in the result list.
6372c1b14e5Sjose borrego  */
6382c1b14e5Sjose borrego unsigned
6398d7e4166Sjose borrego ndr_alter_context_rsp_hdr_size(void)
6402c1b14e5Sjose borrego {
6412c1b14e5Sjose borrego 	unsigned	offset;
6422c1b14e5Sjose borrego 
6432c1b14e5Sjose borrego 	offset = 24UL;	/* offset of sec_addr */
6442c1b14e5Sjose borrego 	offset += 2;	/* sizeof (sec_addr.length) */
6458d7e4166Sjose borrego 	offset += NDR_ALIGN4(offset);
6468d7e4166Sjose borrego 	offset += sizeof (ndr_p_result_list_t);
647dc20a302Sas200622 	return (offset);
648dc20a302Sas200622 }
649