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 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  *
  25  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  26  */
  27 
  28 #ifndef _SMBSRV_NDR_H
  29 #define _SMBSRV_NDR_H
  30 
  31 /*
  32  * Network Data Representation (NDR) is a compatible subset of DCE RPC
  33  * and MSRPC NDR.  NDR is used to move parameters consisting of
  34  * complicated trees of data constructs between an RPC client and server.
  35  *
  36  * CAE Specification (1997)
  37  * DCE 1.1: Remote Procedure Call
  38  * Document Number: C706
  39  * The Open Group
  40  * ogspecs@opengroup.org
  41  */
  42 
  43 #include <sys/types.h>
  44 #include <sys/uio.h>
  45 #include <stdlib.h>
  46 #include <string.h>
  47 
  48 #include <smb/wintypes.h>
  49 #include <libmlrpc/ndrtypes.ndl>
  50 #include <libmlrpc/rpcpdu.ndl>
  51 
  52 #ifdef __cplusplus
  53 extern "C" {
  54 #endif
  55 
  56 /*
  57  * Normal sequence:
  58  *      - Application calls client-side stub w/ TOP-MOST arg structure
  59  *      - client stub performs NDR_M_OP_MARSHALL+NDR_DIR_IN
  60  *      - PDU conveyed (request, aka call, aka query)
  61  *      - server stub performs NDR_M_OP_UNMARSHALL+NDR_DIR_IN
  62  *      - server function called w/ TOP-MOST arg structure
  63  *      - server function returns w/ TOP-MOST arg structure modified
  64  *      - server stub performs NDR_M_OP_MARSHALL+NDR_DIR_OUT
  65  *      - PDU conveyed (reply, aka result, aka response)
  66  *      - client stub performs NDR_M_OP_UNMARSHALL+NDR_DIR_OUT
  67  *      - return to Application w/ TOP-MOST arg structure modified
  68  *
  69  * An interface is a sequence of top-most constructs.  Each top-most
  70  * construct corresponds to one parameter, either argument or return
  71  * value.
  72  *
  73  * A top-most construct is a sequence of outer constructs.  The first
  74  * outer construct is the referent of the argument, and the subsequent
  75  * outer constructs are descendents referenced by pointers from prior
  76  * constructs.
  77  *
  78  * An outer construct is a sequence of variable-sized info, fixed-sized
  79  * data, and variable-sized data.
  80  */
  81 
  82 /*
  83  * Terminology
  84  *
  85  * The ALL UPPER CASE terms recur in the DCE/RPC documentation.
  86  * The mixed-case names have been introduced as a reading aid.
  87  *
  88  * Size         The size of an array in elements. Think of this
  89  *              as the amount to malloc().
  90  *
  91  * Length       The number of elements of an array which are significant
  92  *              Think of this as the amount to bcopy().
  93  *
  94  * Known        Size/length is known at build time.
  95  *
  96  * Determined   Size/length is determined at run time.
  97  *
  98  * FIXED        The Size and Length are Known.
  99  *              Think of this as a string constant or a DOS 8.3 file name.
 100  *              char array[] = "A Constant Size/Length";
 101  *
 102  * CONFORMANT   The Size is Determined. Length is the same as Size.
 103  *              Think of this as strdup().
 104  *              char *array = strdup("Something");
 105  *
 106  * VARYING      The Size is Known. The Length is determined.
 107  *              Think of this as a strcpy() of a variable length string
 108  *              into a fixed length buffer:
 109  *              char array[100];
 110  *              strcpy(array, "very short string");
 111  *
 112  * VARYING/CONFORMANT
 113  *              The Size is Determined. The Length is separately Determined.
 114  *              Think of this like:
 115  *              char *array = malloc(size);
 116  *              strcpy(array, "short string");
 117  *
 118  * STRING       Strings can be CONFORMANT, VARYING, or CONFORMANT/VARYING.
 119  *              A string is fundamentally an array with the last
 120  *              significant element some sort of NULL.
 121  */
 122 
 123 #define NDR_F_NONE              0x0000  /* no flags */
 124 #define NDR_F_PARAMS_MASK       0x00FF
 125 #define NDR_F_SIZE_IS           0x0001  /* [size_is(X)] required/given */
 126 #define NDR_F_LENGTH_IS         0x0002  /* not implemented */
 127 #define NDR_F_SWITCH_IS         0x0004  /* [switch_is(X)] req./given */
 128 #define NDR_F_IS_STRING         0x0008  /* [string] req./given */
 129 #define NDR_F_IS_POINTER        0x0010  /* TYPE * ... req./given */
 130 #define NDR_F_IS_REFERENCE      0x0020  /* TYPE & ... req./given */
 131 #define NDR_F_DIMENSION_IS      0x0040  /* TYPE [N] req./given */
 132 
 133 #define NDR_F_WHENCE_MASK       0x00F0
 134 #define NDR_F_BACKPTR           0x0010  /* ref cause by pointer */
 135 #define NDR_F_OUTER             0x0020  /* ref caused by outer */
 136 #define NDR_F_TOPMOST           0x0040  /* ref caused by topmost */
 137 
 138 #define NDR_F_TYPEOP_MASK       0x0F00
 139 #define NDR_F_ARRAY             0x0100  /* type is array of somethings */
 140 #define NDR_F_POINTER           0x0200  /* type is pointer to something(s) */
 141 #define NDR_F_STRING            0x0300  /* type is string of somethings */
 142 #define NDR_F_UNION             0x0400  /* type is a union */
 143 #define NDR_F_STRUCT            0x0500  /* type is a structure */
 144 #define NDR_F_OPERATION         0x0600  /* type is a structure, special */
 145 #define NDR_F_INTERFACE         0x0700  /* type is a union, special */
 146 #define NDR_F_CONFORMANT        0x1000  /* struct conforming (var-size tail) */
 147 #define NDR_F_VARYING           0x2000  /* not implemented */
 148 
 149 struct ndr_heap;
 150 struct ndr_stream;
 151 struct ndr_reference;
 152 
 153 typedef uint16_t ndr_wchar_t;
 154 
 155 typedef struct ndr_typeinfo {
 156         unsigned char           version;        /* sanity check */
 157         unsigned char           alignment;      /* mask */
 158         unsigned short          type_flags;     /* NDR_F_... */
 159         int                     (*ndr_func)(struct ndr_reference *);
 160         unsigned short          pdu_size_fixed_part;
 161         unsigned short          pdu_size_variable_part;
 162         unsigned short          c_size_fixed_part;
 163         unsigned short          c_size_variable_part;
 164 } ndr_typeinfo_t;
 165 
 166 typedef struct ndr_reference {
 167         struct ndr_reference    *next;          /* queue list (outer only) */
 168         struct ndr_reference    *enclosing;     /* e.g. struct for this memb */
 169         struct ndr_stream       *stream;        /* root of NDR */
 170         ndr_typeinfo_t          *ti;            /* type of data referenced */
 171         char                    *name;          /* name of this member */
 172         unsigned long           pdu_offset;     /* referent in stub data */
 173         char                    *datum;         /* referent in local memory */
 174         char                    **backptr;      /* referer to set */
 175         unsigned short          outer_flags;    /* XXX_is() from top level */
 176         unsigned short          inner_flags;    /* XXX_is() in encapsulated */
 177         unsigned short          type_flags;     /* "requires" */
 178         unsigned short          packed_alignment;
 179         unsigned long           size_is;        /* conforming constructs */
 180         unsigned long           strlen_is;      /* strings */
 181         unsigned long           switch_is;      /* union arg selector */
 182         unsigned long           dimension_is;   /* fixed-len array size */
 183         unsigned long           pdu_end_offset; /* offset for limit of PDU */
 184 } ndr_ref_t;
 185 
 186 /*
 187  * For all operations, the ndr_stream, which is the root of NDR processing,
 188  * is the primary object.  When available, the appropriate ndr_ref_t
 189  * is passed, NULL otherwise.  Functions that return 'int' should return
 190  * TRUE (!0) or FALSE (0).  When functions return FALSE, including
 191  * ndo_malloc() returning NULL, they should set the stream->error to an
 192  * appropriate indicator of what went wrong.
 193  *
 194  * Functions ndo_get_pdu(), ndo_put_pdu(), and ndo_pad_pdu() must
 195  * never grow the PDU data.  A request for out-of-bounds data is an error.
 196  * The swap_bytes flag is 1 if NDR knows that the byte-order in the PDU
 197  * is different from the local system.  ndo_pad_pdu() advised that the
 198  * affected bytes should be zero filled.
 199  */
 200 typedef struct ndr_stream_ops {
 201         char *(*ndo_malloc)(struct ndr_stream *, unsigned, ndr_ref_t *);
 202         int (*ndo_free)(struct ndr_stream *, char *, ndr_ref_t *);
 203         int (*ndo_grow_pdu)(struct ndr_stream *, unsigned long, ndr_ref_t *);
 204         int (*ndo_pad_pdu)(struct ndr_stream *, unsigned long,
 205             unsigned long, ndr_ref_t *);
 206         int (*ndo_get_pdu)(struct ndr_stream *, unsigned long,
 207             unsigned long, char *, int, ndr_ref_t *);
 208         int (*ndo_put_pdu)(struct ndr_stream *, unsigned long,
 209             unsigned long, char *, int, ndr_ref_t *);
 210         void (*ndo_tattle)(struct ndr_stream *, char *, ndr_ref_t *);
 211         void (*ndo_tattle_error)(struct ndr_stream *, ndr_ref_t *);
 212         int (*ndo_reset)(struct ndr_stream *);
 213         void (*ndo_destruct)(struct ndr_stream *);
 214 } ndr_stream_ops_t;
 215 
 216 #define NDS_MALLOC(NDS, LEN, REF) \
 217         (*(NDS)->ndo->ndo_malloc)(NDS, LEN, REF)
 218 #define NDS_GROW_PDU(NDS, WANT_END_OFF, REF) \
 219         (*(NDS)->ndo->ndo_grow_pdu)(NDS, WANT_END_OFF, REF)
 220 #define NDS_PAD_PDU(NDS, PDU_OFFSET, N_BYTES, REF) \
 221         (*(NDS)->ndo->ndo_pad_pdu)(NDS, PDU_OFFSET, N_BYTES, REF)
 222 #define NDS_GET_PDU(NDS, PDU_OFFSET, N_BYTES, BUF, SWAP, REF) \
 223         (*(NDS)->ndo->ndo_get_pdu)(NDS, PDU_OFFSET, N_BYTES, BUF, SWAP, REF)
 224 #define NDS_PUT_PDU(NDS, PDU_OFFSET, N_BYTES, BUF, SWAP, REF) \
 225         (*(NDS)->ndo->ndo_put_pdu)(NDS, PDU_OFFSET, N_BYTES, BUF, SWAP, REF)
 226 #define NDS_TATTLE(NDS, WHAT, REF) \
 227         (*(NDS)->ndo->ndo_tattle)(NDS, WHAT, REF)
 228 #define NDS_TATTLE_ERROR(NDS, WHAT, REF) \
 229         (*(NDS)->ndo->ndo_tattle_error)(NDS, REF)
 230 #define NDS_RESET(NDS)          (*(NDS)->ndo->ndo_reset)(NDS)
 231 #define NDS_DESTRUCT(NDS)       (*(NDS)->ndo->ndo_destruct)(NDS)
 232 
 233 typedef struct ndr_stream {
 234         unsigned long           pdu_size;
 235         unsigned long           pdu_max_size;
 236         unsigned long           pdu_base_offset;
 237         unsigned long           pdu_scan_offset;
 238         unsigned char           *pdu_base_addr;
 239 
 240         ndr_stream_ops_t        *ndo;
 241 
 242         unsigned char           m_op;
 243         unsigned char           dir;
 244         unsigned char           swap;           /* native/net endian swap */
 245         unsigned char           flags;
 246         short                   error;
 247         short                   error_ref;
 248 
 249         ndr_ref_t *outer_queue_head;
 250         ndr_ref_t **outer_queue_tailp;
 251         ndr_ref_t *outer_current;
 252         struct ndr_heap *heap;
 253 } ndr_stream_t;
 254 
 255 #define NDR_M_OP_NONE           0x00
 256 #define NDR_M_OP_MARSHALL       0x01    /* data moving from datum to PDU */
 257 #define NDR_M_OP_UNMARSHALL     0x02    /* data moving from PDU to datum */
 258 
 259 #define NDR_DIR_NONE            0x00
 260 #define NDR_DIR_IN              0x10    /* data moving from caller to callee */
 261 #define NDR_DIR_OUT             0x20    /* data moving from callee to caller */
 262 
 263 #define NDR_MODE_CALL_SEND      (NDR_M_OP_MARSHALL + NDR_DIR_IN)
 264 #define NDR_MODE_CALL_RECV      (NDR_M_OP_UNMARSHALL + NDR_DIR_IN)
 265 #define NDR_MODE_RETURN_SEND    (NDR_M_OP_MARSHALL + NDR_DIR_OUT)
 266 #define NDR_MODE_RETURN_RECV    (NDR_M_OP_UNMARSHALL + NDR_DIR_OUT)
 267 #define NDR_MODE_BUF_ENCODE     NDR_MODE_CALL_SEND
 268 #define NDR_MODE_BUF_DECODE     NDR_MODE_RETURN_RECV
 269 
 270 #define NDR_MODE_TO_M_OP(MODE)  ((MODE) & 0x0F)
 271 #define NDR_MODE_TO_DIR(MODE)   ((MODE) & 0xF0)
 272 #define NDR_M_OP_AND_DIR_TO_MODE(M_OP, DIR)     ((M_OP)|(DIR))
 273 
 274 #define NDR_MODE_MATCH(NDS, MODE) \
 275         (NDR_M_OP_AND_DIR_TO_MODE((NDS)->m_op, (NDS)->dir) == (MODE))
 276 
 277 #define NDR_IS_FIRST_FRAG(F)    ((F) & NDR_PFC_FIRST_FRAG)
 278 #define NDR_IS_LAST_FRAG(F)     ((F) & NDR_PFC_LAST_FRAG)
 279 #define NDR_IS_SINGLE_FRAG(F)   \
 280         (NDR_IS_FIRST_FRAG((F)) && NDR_IS_LAST_FRAG((F)))
 281 
 282 #define NDS_F_NONE              0x00
 283 #define NDS_F_NOTERM            0x01    /* strings are not null terminated */
 284 #define NDS_F_NONULL            0x02    /* strings: no null on size_is */
 285 #define NDS_SETF(S, F)          ((S)->flags |= (F))
 286 #define NDS_CLEARF(S, F)        ((S)->flags &= ~(F))
 287 
 288 #define NDR_ERR_MALLOC_FAILED           -1
 289 #define NDR_ERR_M_OP_INVALID            -2
 290 #define NDR_ERR_UNDERFLOW               -3
 291 #define NDR_ERR_GROW_FAILED             -4      /* overflow */
 292 #define NDR_ERR_PAD_FAILED              -5      /* couldn't possibly happen */
 293 #define NDR_ERR_OUTER_HEADER_BAD        -6
 294 #define NDR_ERR_SWITCH_VALUE_ILLEGAL    -7
 295 #define NDR_ERR_SWITCH_VALUE_INVALID    -8
 296 #define NDR_ERR_SWITCH_VALUE_MISSING    -9
 297 #define NDR_ERR_SIZE_IS_MISMATCH_PDU    -10
 298 #define NDR_ERR_SIZE_IS_MISMATCH_AFTER  -11
 299 #define NDR_ERR_SIZE_IS_UNEXPECTED      -12
 300 #define NDR_ERR_SIZE_IS_DUPLICATED      -13
 301 #define NDR_ERR_OUTER_PARAMS_MISMATCH   -14
 302 #define NDR_ERR_ARRAY_VARLEN_ILLEGAL    -15
 303 #define NDR_ERR_ARRAY_UNION_ILLEGAL     -16
 304 #define NDR_ERR_OUTER_PARAMS_BAD        -17
 305 #define NDR_ERR_OUTER_UNION_ILLEGAL     -18
 306 #define NDR_ERR_TOPMOST_UNION_ILLEGAL   -19
 307 #define NDR_ERR_TOPMOST_VARLEN_ILLEGAL  -20
 308 #define NDR_ERR_INNER_PARAMS_BAD        -21
 309 #define NDR_ERR_UNIMPLEMENTED           -22
 310 #define NDR_ERR_NOT_AN_INTERFACE        -23
 311 #define NDR_ERR_STRLEN                  -24
 312 #define NDR_ERR_STRING_SIZING           -25
 313 #define NDR_ERR_BOUNDS_CHECK            -26
 314 
 315 #define NDR_SET_ERROR(REF, ERROR)                       \
 316         ((REF)->stream->error = (ERROR),          \
 317         (REF)->stream->error_ref = __LINE__,              \
 318         NDS_TATTLE_ERROR((REF)->stream, 0, REF))
 319 
 320 #define NDR_TATTLE(REF, WHAT) \
 321         (*(REF)->stream->ndo->ndo_tattle)((REF)->stream, WHAT, REF)
 322 
 323 #define MEMBER_STR(MEMBER) #MEMBER
 324 
 325 #define NDR_DIR_IS_IN  (encl_ref->stream->dir == NDR_DIR_IN)
 326 #define NDR_DIR_IS_OUT (encl_ref->stream->dir == NDR_DIR_OUT)
 327 
 328 #define NDR_MEMBER_WITH_ARG(TYPE, MEMBER, OFFSET, \
 329                 ARGFLAGS, ARGMEM, ARGVAL) { \
 330                 myref.pdu_offset = encl_ref->pdu_offset + (OFFSET);  \
 331                 myref.name = MEMBER_STR(MEMBER);                        \
 332                 myref.datum = (char *)&val->MEMBER;                      \
 333                 myref.inner_flags = ARGFLAGS;                           \
 334                 myref.ti = &ndt_##TYPE;                                     \
 335                 myref.ARGMEM = ARGVAL;                                  \
 336                 if (!ndr_inner(&myref))                                     \
 337                         return (0);                                     \
 338         }
 339 
 340 #define NDR_MEMBER(TYPE, MEMBER, OFFSET) \
 341         NDR_MEMBER_WITH_ARG(TYPE, MEMBER, OFFSET, \
 342                 NDR_F_NONE, size_is, 0)
 343 
 344 #define NDR_MEMBER_ARR_WITH_SIZE_IS(TYPE, MEMBER, OFFSET, SIZE_IS) \
 345         NDR_MEMBER_WITH_ARG(TYPE, MEMBER, OFFSET, \
 346                 NDR_F_SIZE_IS, size_is, SIZE_IS)
 347 
 348 #define NDR_MEMBER_ARR_WITH_DIMENSION(TYPE, MEMBER, OFFSET, SIZE_IS) \
 349         NDR_MEMBER_WITH_ARG(TYPE, MEMBER, OFFSET, \
 350                 NDR_F_DIMENSION_IS, dimension_is, SIZE_IS)
 351 
 352 #define NDR_MEMBER_PTR_WITH_SIZE_IS(TYPE, MEMBER, OFFSET, SIZE_IS) \
 353         NDR_MEMBER_WITH_ARG(TYPE, MEMBER, OFFSET, \
 354                 NDR_F_SIZE_IS+NDR_F_IS_POINTER, size_is, SIZE_IS)
 355 
 356 #define NDR_MEMBER_PTR(TYPE, MEMBER, OFFSET)            \
 357         NDR_MEMBER_WITH_ARG(TYPE, MEMBER, OFFSET,       \
 358                 NDR_F_IS_POINTER, size_is, 0)
 359 
 360 #define NDR_MEMBER_WITH_SWITCH_IS(TYPE, MEMBER, OFFSET, SWITCH_IS)      \
 361         NDR_MEMBER_WITH_ARG(TYPE, MEMBER, OFFSET,                       \
 362                 NDR_F_SWITCH_IS, switch_is, SWITCH_IS)
 363 
 364 
 365 #define NDR_TOPMOST_MEMBER_WITH_ARG(TYPE, MEMBER, \
 366                 ARGFLAGS, ARGMEM, ARGVAL) { \
 367                 myref.pdu_offset = -1;                                  \
 368                 myref.name = MEMBER_STR(MEMBER);                        \
 369                 myref.datum = (char *)&val->MEMBER;                      \
 370                 myref.inner_flags = ARGFLAGS;                           \
 371                 myref.ti = &ndt_##TYPE;                                     \
 372                 myref.ARGMEM = ARGVAL;                                  \
 373                 if (!ndr_topmost(&myref))                           \
 374                         return (0);                                     \
 375         }
 376 
 377 #define NDR_TOPMOST_MEMBER(TYPE, MEMBER)                                \
 378         NDR_TOPMOST_MEMBER_WITH_ARG(TYPE, MEMBER,                       \
 379                 NDR_F_NONE, size_is, 0)
 380 
 381 #define NDR_TOPMOST_MEMBER_ARR_WITH_SIZE_IS(TYPE, MEMBER, SIZE_IS)      \
 382         NDR_TOPMOST_MEMBER_WITH_ARG(TYPE, MEMBER,                       \
 383                 NDR_F_SIZE_IS, size_is, SIZE_IS)
 384 
 385 #define NDR_TOPMOST_MEMBER_ARR_WITH_DIMENSION(TYPE, MEMBER, SIZE_IS)    \
 386         NDR_TOPMOST_MEMBER_WITH_ARG(TYPE, MEMBER,                       \
 387                 NDR_F_DIMENSION_IS, dimension_is, SIZE_IS)
 388 
 389 #define NDR_TOPMOST_MEMBER_PTR_WITH_SIZE_IS(TYPE, MEMBER, SIZE_IS)      \
 390         NDR_TOPMOST_MEMBER_WITH_ARG(TYPE, MEMBER,                       \
 391                 NDR_F_SIZE_IS+NDR_F_IS_POINTER, size_is, SIZE_IS)
 392 
 393 #define NDR_TOPMOST_MEMBER_PTR(TYPE, MEMBER)            \
 394         NDR_TOPMOST_MEMBER_WITH_ARG(TYPE, MEMBER,       \
 395                 NDR_F_IS_POINTER, size_is, 0)
 396 
 397 #define NDR_TOPMOST_MEMBER_REF(TYPE, MEMBER)            \
 398         NDR_TOPMOST_MEMBER_WITH_ARG(TYPE, MEMBER,       \
 399                 NDR_F_IS_REFERENCE, size_is, 0)
 400 
 401 #define NDR_TOPMOST_MEMBER_REF_WITH_SIZE_IS(TYPE, MEMBER, SIZE_IS)      \
 402         NDR_TOPMOST_MEMBER_WITH_ARG(TYPE, MEMBER,                       \
 403                 NDR_F_SIZE_IS+NDR_F_IS_REFERENCE, size_is, SIZE_IS)
 404 
 405 #define NDR_TOPMOST_MEMBER_WITH_SWITCH_IS(TYPE, MEMBER, SWITCH_IS)      \
 406         NDR_TOPMOST_MEMBER_WITH_ARG(TYPE, MEMBER,                       \
 407                 NDR_F_SWITCH_IS, switch_is, SWITCH_IS)
 408 
 409 /* this is assuming offset+0 */
 410 #define NDR_PARAMS_MEMBER_WITH_ARG(TYPE, MEMBER, ARGFLAGS, \
 411         ARGMEM, ARGVAL) { \
 412                 myref.pdu_offset = encl_ref->pdu_offset;             \
 413                 myref.name = MEMBER_STR(MEMBER);                        \
 414                 myref.datum = (char *)&val->MEMBER;                      \
 415                 myref.inner_flags = ARGFLAGS;                           \
 416                 myref.ti = &ndt_##TYPE;                                     \
 417                 myref.ARGMEM = ARGVAL;                                  \
 418                 if (!ndr_params(&myref))                            \
 419                         return (0);                                     \
 420         }
 421 
 422 #define NDR_PARAMS_MEMBER(TYPE, MEMBER)                 \
 423         NDR_PARAMS_MEMBER_WITH_ARG(TYPE, MEMBER,        \
 424         NDR_F_NONE, size_is, 0)
 425 
 426 #define NDR_STRING_DIM          1
 427 #define NDR_ANYSIZE_DIM         1
 428 
 429 int ndo_process(struct ndr_stream *, ndr_typeinfo_t *, char *);
 430 int ndo_operation(struct ndr_stream *, ndr_typeinfo_t *, int opnum, char *);
 431 void ndo_printf(struct ndr_stream *, ndr_ref_t *, const char *, ...);
 432 void ndo_trace(const char *);
 433 void ndo_fmt(struct ndr_stream *, ndr_ref_t *, char *);
 434 
 435 int ndr_params(ndr_ref_t *);
 436 int ndr_topmost(ndr_ref_t *);
 437 int ndr_run_outer_queue(struct ndr_stream *);
 438 int ndr_outer(ndr_ref_t *);
 439 int ndr_outer_fixed(ndr_ref_t *);
 440 int ndr_outer_fixed_array(ndr_ref_t *);
 441 int ndr_outer_conformant_array(ndr_ref_t *);
 442 int ndr_outer_conformant_construct(ndr_ref_t *);
 443 int ndr_size_is(ndr_ref_t *);
 444 int ndr_outer_string(ndr_ref_t *);
 445 int ndr_outer_peek_sizing(ndr_ref_t *, unsigned, unsigned long *);
 446 int ndr_outer_poke_sizing(ndr_ref_t *, unsigned, unsigned long *);
 447 int ndr_outer_align(ndr_ref_t *);
 448 int ndr_outer_grow(ndr_ref_t *, unsigned);
 449 int ndr_inner(ndr_ref_t *);
 450 int ndr_inner_pointer(ndr_ref_t *);
 451 int ndr_inner_reference(ndr_ref_t *);
 452 int ndr_inner_array(ndr_ref_t *);
 453 
 454 size_t ndr_mbstowcs(struct ndr_stream *, ndr_wchar_t *, const char *, size_t);
 455 
 456 void nds_bswap(void *src, void *dst, size_t len);
 457 
 458 #ifdef __cplusplus
 459 }
 460 #endif
 461 
 462 #endif /* _SMBSRV_NDR_H */