2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. 2N/A * An MSRPC compatible implementation of OSF DCE RPC. DCE RPC is derived 2N/A * from the Apollo Network Computing Architecture (NCA) RPC implementation. 2N/A * CAE Specification (1997) 2N/A * DCE 1.1: Remote Procedure Call 2N/A * Document Number: C706 2N/A * ogspecs@opengroup.org 2N/A * This implementation is based on the DCE Remote Procedure Call spec with 2N/A * enhancements to support Unicode strings. The diagram below shows the 2N/A * DCE RPC layers compared against ONC SUN RPC. 2N/A * NDR RPC Layers Sun RPC Layers Remark 2N/A * +---------------+ +---------------+ +---------------+ 2N/A * +---------------+ +---------------+ 2N/A * | Application | | Application | The application 2N/A * +---------------+ +---------------+ 2N/A * | Hand coded | | RPCGEN gen'd | Where the real 2N/A * +---------------+ +---------------+ 2N/A * +---------------+ +---------------+ 2N/A * | RPC Protocol | | RPC Protocol | Headers, Auth, 2N/A * | rpcpdu.ndl | | | 2N/A * +---------------+ +---------------+ 2N/A * | IDL gen'd | | RPCGEN gen'd | Aggregate 2N/A * | NDR stubs | | XDR stubs | Composition 2N/A * +---------------+ +---------------+ 2N/A * | NDR Represen | | XDR Represen | Byte order, padding 2N/A * +---------------+ +---------------+ 2N/A * | Packet Heaps | | Network Conn | DCERPC does not talk 2N/A * | ndo_*.c | | clnt_{tcp,udp}| directly to network. 2N/A * +---------------+ +---------------+ 2N/A * There are two major differences between the DCE RPC and ONC RPC: 2N/A * 1. NDR RPC only generates or processes packets from buffers. Other 2N/A * layers must take care of packet transmission and reception. 2N/A * The packet heaps are managed through a simple interface provided 2N/A * by the Network Data Representation (NDR) module called ndr_stream_t. 2N/A * ndo_*.c modules implement the different flavors (operations) of 2N/A * ONC RPC communicates directly with the network. You have to do 2N/A * something special for the RPC packet to be placed in a buffer 2N/A * rather than sent to the wire. 2N/A * 2. NDR RPC uses application provided heaps to support operations. 2N/A * A heap is a single, monolithic chunk of memory that NDR RPC manages 2N/A * as it allocates. When the operation and its result are done, the 2N/A * heap is disposed of as a single item. The transaction, which 2N/A * is the anchor of most operations, contains the necessary book- 2N/A * keeping for the heap. 2N/A * ONC RPC uses malloc() liberally throughout its run-time system. 2N/A * To free results, ONC RPC supports an XDR_FREE operation that 2N/A * traverses data structures freeing memory as it goes, whether 2N/A * it was malloc'd or not. 2N/A * Dispatch Return Code (DRC) 2N/A * 0x8000 15:01 Set to indicate a fault, clear indicates status 2N/A * 0x00FF 00:08 PTYPE_... of PDU, 0xFF for header 2N/A/* Fake PTYPE DRC discriminators */ 2N/A/* DRC Recognizers */ 2N/A * (Un)Marshalling category specifiers 2N/A * Resource category specifier 2N/A * Parameters. Usually #define'd with useful alias 2N/A * The list of bindings is anchored at a connection. Nothing in the 2N/A * RPC mechanism allocates them. Binding elements which have service==0 2N/A * indicate free elements. When a connection is instantiated, at least 2N/A * one free binding entry should also be established. Something like 2N/A * this should suffice for most (all) situations: 2N/A * struct connection { 2N/A * ndr_binding_t *binding_list_head; 2N/A * ndr_binding_t binding_pool[N_BINDING_POOL]; 2N/A * init_connection(struct connection *conn) { 2N/A * ndr_svc_binding_pool_init(&conn->binding_list_head, 2N/A * conn->binding_pool, N_BINDING_POOL); 2N/A * The binding list space must be provided by the application library 2N/A * for use by the underlying RPC library. We need at least two binding 2N/A * slots per connection. 2N/A * Number of bytes required to align SIZE on the next dword/4-byte 2N/A * DCE RPC strings (CAE section 14.3.4) are represented as varying or varying 2N/A * and conformant one-dimensional arrays. Characters can be single-byte 2N/A * or multi-byte as long as all characters conform to a fixed element size, 2N/A * i.e. UCS-2 is okay but UTF-8 is not a valid DCE RPC string format. The 2N/A * string is terminated by a null character of the appropriate element size. 2N/A * This format uses the size_is, first_is and length_is attributes (CAE 2N/A * typedef struct string { 2N/A * wchar_t string[ANY_SIZE_ARRAY]; 2N/A * The size_is attribute is used to specify the number of data elements in 2N/A * each dimension of an array. 2N/A * The first_is attribute is used to define the lower bound for significant 2N/A * elements in each dimension of an array. For strings this is always 0. 2N/A * The length_is attribute is used to define the number of significant 2N/A * elements in each dimension of an array. For strings this is typically 2N/A * the same as size_is. Although it might be (size_is - 1) if the string 2N/A * is null terminated. 2N/A * 4 bytes 4 bytes 4 bytes 2bytes 2bytes 2bytes 2bytes 2N/A * +---------+---------+---------+------+------+------+------+ 2N/A * |size_is |first_is |length_is| char | char | char | char | 2N/A * +---------+---------+---------+------+------+------+------+ 2N/A * Unfortunately, not all MSRPC Unicode strings are null terminated, which 2N/A * means that the recipient has to manually null-terminate the string after 2N/A * it has been unmarshalled. There may be a wide-char pad following a 2N/A * string, and it may sometimes contains zero, but it's not guaranteed. 2N/A * To deal with this, MSRPC sometimes uses an additional wrapper with two 2N/A * more fields, as shown below. 2N/A * length: the array length in bytes excluding terminating null bytes 2N/A * maxlen: the array length in bytes including null terminator bytes 2N/A * LPTSTR: converted to a string_t by NDR 2N/A * typedef struct ms_string { 2N/A * A number of heap areas are used during marshalling and unmarshalling. 2N/A * Under some circumstances these areas can be discarded by the library 2N/A * code, i.e. on the server side before returning to the client and on 2N/A * completion of a client side bind. In the case of a client side RPC 2N/A * call, these areas must be preserved after an RPC returns to give the 2N/A * caller time to take a copy of the data. In this case the client must 2N/A * call ndr_clnt_free_heap to free the memory. 2N/A * The heap management data definition looks a bit like this: 2N/A * heap -> +---------------+ +------------+ 2N/A * | iovec[0].base | --> | data block | 2N/A * | iovec[0].len | +------------+ 2N/A * iov -> +---------------+ +------------+ 2N/A * | iovec[n].base | --> | data block | 2N/A * | iovec[n].len | +------------+ 2N/A * +---------------+ ^ ^ 2N/A * next ----------------------+ | 2N/A * top -----------------------------------+ 2N/A * Setting MAXIOV to 384 will use ((8 * 384) + 16) = 3088 bytes 2N/A * of the first heap block. 2N/A * - for non-null-terminated strings. 2N/A * size_is (actually a copy of length_is) will 2N/A * be inserted here by the marshalling library. 2N/A * size_is (actually a copy of length_is) will 2N/A * be inserted here by the marshalling library. 2N/A unsigned short ptype;
/* high bits special */ 2N/A * 20-byte opaque id used by various RPC services. 2N/A#
endif /* _LIBNDR_H */