1 /****************************************************************************
2  * Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3  * Copyright (C) 2008-2013 Sourcefire, Inc.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License Version 2 as
7  * published by the Free Software Foundation.  You may not use, modify or
8  * distribute this program under any other version of the GNU General
9  * Public License.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  *
20  ****************************************************************************
21  *
22  ****************************************************************************/
23 
24 #ifndef DCERPC_H
25 #define DCERPC_H
26 
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"  /* For WORDS_BIGENDIAN */
29 #endif
30 
31 /********************************************************************
32  * Enumerations
33  ********************************************************************/
34 /* DCE/RPC byte order flag */
35 typedef enum _DceRpcBoFlag
36 {
37     DCERPC_BO_FLAG__NONE,
38     DCERPC_BO_FLAG__BIG_ENDIAN,
39     DCERPC_BO_FLAG__LITTLE_ENDIAN
40 
41 } DceRpcBoFlag;
42 
43 /*
44  * Common to Connectionless and Connection Oriented
45  */
46 typedef enum _DceRpcPduType
47 {
48     DCERPC_PDU_TYPE__REQUEST = 0,
49     DCERPC_PDU_TYPE__PING,
50     DCERPC_PDU_TYPE__RESPONSE,
51     DCERPC_PDU_TYPE__FAULT,
52     DCERPC_PDU_TYPE__WORKING,
53     DCERPC_PDU_TYPE__NOCALL,
54     DCERPC_PDU_TYPE__REJECT,
55     DCERPC_PDU_TYPE__ACK,
56     DCERPC_PDU_TYPE__CL_CANCEL,
57     DCERPC_PDU_TYPE__FACK,
58     DCERPC_PDU_TYPE__CANCEL_ACK,
59     DCERPC_PDU_TYPE__BIND,
60     DCERPC_PDU_TYPE__BIND_ACK,
61     DCERPC_PDU_TYPE__BIND_NACK,
62     DCERPC_PDU_TYPE__ALTER_CONTEXT,
63     DCERPC_PDU_TYPE__ALTER_CONTEXT_RESP,
64     DCERPC_PDU_TYPE__AUTH3,
65     DCERPC_PDU_TYPE__SHUTDOWN,
66     DCERPC_PDU_TYPE__CO_CANCEL,
67     DCERPC_PDU_TYPE__ORPHANED,
68     DCERPC_PDU_TYPE__MICROSOFT_PROPRIETARY_OUTLOOK2003_RPC_OVER_HTTP,
69     DCERPC_PDU_TYPE__MAX
70 
71 } DceRpcPduType;
72 
73 /* Version 4 is for Connectionless
74  * Version 5 is for Connection oriented */
75 typedef enum _DceRpcProtoMajorVers
76 {
77     DCERPC_PROTO_MAJOR_VERS__4 = 4,
78     DCERPC_PROTO_MAJOR_VERS__5 = 5
79 
80 } DceRpcProtoMajorVers;
81 
82 typedef enum _DceRpcProtoMinorVers
83 {
84     DCERPC_PROTO_MINOR_VERS__0 = 0,
85     DCERPC_PROTO_MINOR_VERS__1 = 1
86 
87 } DceRpcProtoMinorVers;
88 
89 /*
90  * Connectionless
91  */
92 typedef enum _DceRpcClFlags1
93 {
94     DCERPC_CL_FLAGS1__RESERVED_01 = 0x01,
95     DCERPC_CL_FLAGS1__LASTFRAG = 0x02,
96     DCERPC_CL_FLAGS1__FRAG = 0x04,
97     DCERPC_CL_FLAGS1__NOFACK = 0x08,
98     DCERPC_CL_FLAGS1__MAYBE = 0x10,
99     DCERPC_CL_FLAGS1__IDEMPOTENT = 0x20,
100     DCERPC_CL_FLAGS1__BROADCAST = 0x40,
101     DCERPC_CL_FLAGS1__RESERVED_80 = 0x80
102 
103 } DceRpcClFlags1;
104 
105 typedef enum _DceRpcClFlags2
106 {
107     DCERPC_CL_FLAGS2__RESERVED_01 = 0x01,
108     DCERPC_CL_FLAGS2__CANCEL_PENDING = 0x02,
109     DCERPC_CL_FLAGS2__RESERVED_04 = 0x04,
110     DCERPC_CL_FLAGS2__RESERVED_08 = 0x08,
111     DCERPC_CL_FLAGS2__RESERVED_10 = 0x10,
112     DCERPC_CL_FLAGS2__RESERVED_20 = 0x20,
113     DCERPC_CL_FLAGS2__RESERVED_40 = 0x40,
114     DCERPC_CL_FLAGS2__RESERVED_80 = 0x80
115 
116 } DceRpcClFlags2;
117 
118 typedef enum _DCERPC_AuthProto
119 {
120     DCERPC_AUTH_PROTO__NONE = 0,
121     DCERPC_AUTH_PROTO__OSF_DCERPC_PK_AUTH = 1
122 
123 } DCERPC_AuthProto;
124 
125 /*
126  * Connection oriented
127  */
128 typedef enum _DceRpcCoPfcFlags
129 {
130     DCERPC_CO_PFC_FLAGS__FIRST_FRAG = 0x01,
131     DCERPC_CO_PFC_FLAGS__LAST_FRAG = 0x02,
132     DCERPC_CO_PFC_FLAGS__PENDING_CANCEL = 0x04,
133     DCERPC_CO_PFC_FLAGS__RESERVED_1 = 0x08,
134     DCERPC_CO_PFC_FLAGS__CONC_MPX = 0x10,
135     DCERPC_CO_PFC_FLAGS__DID_NOT_EXECUTE = 0x20,
136     DCERPC_CO_PFC_FLAGS__MAYBE = 0x40,
137     DCERPC_CO_PFC_FLAGS__OBJECT_UUID = 0x80
138 
139 } DceRpcCoPfcFlags;
140 
141 /* Presentation context definition result */
142 typedef enum _DceRpcCoContDefResult
143 {
144     DCERPC_CO_CONT_DEF_RESULT__ACCEPTANCE = 0,
145     DCERPC_CO_CONT_DEF_RESULT__USER_REJECTION,
146     DCERPC_CO_CONT_DEF_RESULT__PROVIDER_REJECTION
147 
148 } DceRpcCoContDefResult;
149 
150 /* Presentation provider rejection reason */
151 typedef enum _DceRpcCoProvRejReason
152 {
153     DCERPC_CO_PROV_REJ_REASON__REASON_NOT_SPECIFIED = 0,
154     DCERPC_CO_PROV_REJ_REASON__ABSTRACT_SYNTAX_NOT_SUPPORTED,
155     DCERPC_CO_PROV_REJ_REASON__PROPOSED_TRANSFER_SYNTAXES_NOT_SUPPORTED,
156     DCERPC_CO_PROV_REJ_REASON__LOCAL_LIMIT_EXCEEDED
157 
158 } DceRpcCoProvRejReason;
159 
160 typedef enum _DceRpcCoBindNakReason
161 {
162     DCERPC_CO_BIND_NAK_REASON__REASON_NOT_SPECIFIED = 0,
163     DCERPC_CO_BIND_NAK_REASON__TEMPORARY_CONGESTION,
164     DCERPC_CO_BIND_NAK_REASON__LOCAL_LIMIT_EXECEEDED,
165     DCERPC_CO_BIND_NAK_REASON__CALLED_PADDR_UNKNOWN,
166     DCERPC_CO_BIND_NAK_REASON__PROTOCOL_VERSION_NOT_SUPPORTED,
167     DCERPC_CO_BIND_NAK_REASON__DEFAULT_CONTEXT_NOT_SUPPORTED,
168     DCERPC_CO_BIND_NAK_REASON__USER_DATA_NOT_READABLE,
169     DCERPC_CO_BIND_NAK_REASON__NO_PSAP_AVAILABLE
170 
171 } DceRpcCoBindNakReason;
172 
173 typedef enum _DceRpcCoAuthLevelType
174 {
175     DCERPC_CO_AUTH_LEVEL__NONE = 1,
176     DCERPC_CO_AUTH_LEVEL__CONNECT,
177     DCERPC_CO_AUTH_LEVEL__CALL,
178     DCERPC_CO_AUTH_LEVEL__PKT,
179     DCERPC_CO_AUTH_LEVEL__PKT_INTEGRITY,
180     DCERPC_CO_AUTH_LEVEL__PKT_PRIVACY
181 
182 } DceRpcCoAuthLevelType;
183 
184 /********************************************************************
185  * Structures
186  ********************************************************************/
187 #ifdef WIN32
188 #pragma pack(push, dcerpc_hdrs, 1)
189 #else
190 #pragma pack(1)
191 #endif
192 
193 typedef struct _Uuid
194 {
195     uint32_t time_low;
196     uint16_t time_mid;
197     uint16_t time_high_and_version;
198     uint8_t clock_seq_and_reserved;
199     uint8_t clock_seq_low;
200     uint8_t node[6];
201 
202 } Uuid;
203 
204 /*
205  * Connectionless
206  */
207 typedef struct _DceRpcClHdr   /* Connectionless header */
208 {
209     uint8_t rpc_vers;
210     uint8_t ptype;
211     uint8_t flags1;
212     uint8_t flags2;
213     uint8_t drep[3];
214     uint8_t serial_hi;
215     Uuid object;
216     Uuid if_id;
217     Uuid act_id;
218     uint32_t server_boot;
219     uint32_t if_vers;
220     uint32_t seqnum;
221     uint16_t opnum;
222     uint16_t ihint;
223     uint16_t ahint;
224     uint16_t len;
225     uint16_t fragnum;
226     uint8_t auth_proto;
227     uint8_t serial_lo;
228 
229 } DceRpcClHdr;
230 
231 /* ack PDU contains no body */
232 
233 /* cancel PDU */
234 typedef struct _DceRpcClCancel
235 {
236     uint32_t vers;
237     uint32_t cancel_id;
238 
239 } DceRpcClCancel;
240 
241 /* cancel_ack PDU */
242 typedef struct _DceRpcClCancelAck
243 {
244     uint32_t vers;
245     uint32_t cancel_id;
246     int server_is_accepting;
247 
248 } DceRpcClCancelAck;
249 
250 /* fack PDU */
251 typedef struct _DceRpcClFack
252 {
253     uint8_t vers;
254     uint8_t pad1;
255     uint16_t window_size;
256     uint32_t max_tpdu;
257     uint32_t max_frag_size;
258     uint16_t serial_num;
259     uint16_t selack_len;
260     uint32_t selack[1];  /* variable length */
261 
262 } DceRpcClFack;
263 
264 /* fault PDU */
265 typedef struct _DceRpcClFault
266 {
267     uint32_t status;  /* status code */
268 
269 } DceRpcClFault;
270 
271 /* nocall PDU (negative reply to ping) contains no body */
272 /* ping PDU contains no body */
273 
274 /* reject PDU is the same as fack */
275 typedef DceRpcClFault DceRpcClReject;
276 
277 /* request PDU contains stub data as body */
278 /* response PDU contains stub data as body */
279 
280 /* working PDU (positive reply to ping) contains no body */
281 
282 /*
283  * Connection oriented
284  */
285 typedef struct _DceRpcCoVersion
286 {
287     uint8_t major;
288     uint8_t minor;
289 
290 } DceRpcCoVersion;
291 
292 /* Connection oriented common header */
293 typedef struct _DceRpcCoHdr
294 {
295     DceRpcCoVersion pversion;
296     uint8_t ptype;
297     uint8_t pfc_flags;
298     uint8_t packed_drep[4];
299     uint16_t frag_length;
300     uint16_t auth_length;
301     uint32_t call_id;
302 
303 } DceRpcCoHdr;
304 
305 /* Presentation syntax id */
306 typedef struct _DceRpcCoSynId
307 {
308     Uuid if_uuid;
309     uint32_t if_version;
310 
311 } DceRpcCoSynId;
312 
313 /* Presentation context element */
314 typedef struct _DceRpcCoContElem
315 {
316     uint16_t p_cont_id;
317     uint8_t n_transfer_syn;  /* number of transfer syntaxes */
318     uint8_t reserved;
319     DceRpcCoSynId abstract_syntax;
320 #if 0
321     DceRpcCoSynId transfer_syntaxes[]; /* variable length */
322 #endif
323 } DceRpcCoContElem;
324 
325 #if 0   /* Put this in the Bind header */
326 /* Presentation context list */
327 typedef struct _DceRpcCoContList
328 {
329     uint8_t n_context_elem;   /* number of context elements */
330     uint8_t reserved;
331     uint16_t reserved2;
332 #if 0
333     DceRpcCoContElem p_cont_elem[];  /* variable length */
334 #endif
335 } DceRpcCoContList;
336 #endif
337 
338 /* Presentation result */
339 typedef struct _DceRpcCoContResult
340 {
341     uint16_t result;
342     uint16_t reason;
343     DceRpcCoSynId transfer_syntax;
344 
345 } DceRpcCoContResult;
346 
347 typedef struct _DceRpcCoContResultList
348 {
349     uint8_t n_results;
350     uint8_t reserved;
351     uint16_t reserved2;
352 #if 0
353     DceRpcCoContResult p_results[];  /* variable length */
354 #endif
355 } DceRpcCoContResultList;
356 
357 /* DCE version supported */
358 typedef struct _DceRpcCoVerSup
359 {
360     uint8_t n_protocols;  /* number of protocols */
361 #if 0
362     DceRpcCoVersion protocols[];  /* variable length */
363 #endif
364 } DceRpcCoVerSup;
365 
366 /* Bind */
367 typedef struct _DceRpcCoBind
368 {
369     uint16_t max_xmit_frag;
370     uint16_t max_recv_frag;
371     uint32_t assoc_group_id;
372     uint8_t n_context_elem;   /* number of context elements */
373     uint8_t reserved;
374     uint16_t reserved2;
375 #if 0
376     uint16_t p_cont_id;
377     uint8_t n_tranfer_syn;  /* number of transfer syntaxes */
378     uint8_t reserved;
379     DceRpcCoSynId abstract_syntax;
380 #endif
381 #if 0
382     DceRpcCoContList p_context_elem_list;  /* variable length */
383     auth_verifier_co_t auth_verifier;
384 #endif
385 } DceRpcCoBind;
386 
387 /* Bind response */
388 typedef struct _DceRpcCoBindAck
389 {
390     uint16_t max_xmit_frag;
391     uint16_t max_recv_frag;
392     uint32_t assoc_group_id;
393     uint16_t sec_addr_len;
394 #if 0
395     char sec_addr[];  /* variable length */
396     uint8_t pad2[align(4)];     /* this is really to align the above field
397                                    whose last member is a variable len str.
398                                    It will be 0-3 bytes long. */
399     DceRpcCoContResultList p_context_elem;
400     aut_verifier_co_t auth_verifier;
401 #endif
402 } DceRpcCoBindAck;
403 
404 typedef DceRpcCoBind DceRpcCoAltCtx;
405 typedef DceRpcCoBindAck DceRpcCoAltCtxResp;
406 
407 typedef struct _DceRpcCoBindNak
408 {
409     DceRpcCoBindNakReason provider_reject_reason;
410 #if 0
411     DceRpcCoVerSup versions;  /* variable length */
412 #endif
413 } DceRpcCoBindNak;
414 
415 #if 0
416 typedef struct _DceRpcCoCancel
417 {
418     auth_verifier_co_t auth_verifier;
419 } DceRpcCoCancel;
420 #endif
421 
422 typedef struct _DceRpcCoFault
423 {
424     uint32_t alloc_hint;
425     uint16_t context_id;
426     uint8_t cancel_count;
427     uint8_t reserved;
428     uint32_t status;
429     uint8_t reserved2[4];
430 #if 0
431     uint8_t stub data[]   /* 8 octet aligned if auth_verifier, which will
432                              take care of the pad. */
433     auth_verifier_co_t auth_verifier;
434 #endif
435 } DceRpcCoFault;
436 
437 #if 0
438 typedef struct _DceRpcCoOrphaned
439 {
440     auth_verifier_co_t auth_verifier;
441 } DceRpcCoOrphaned;
442 #endif
443 
444 typedef struct _DceRpcCoRequest
445 {
446     uint32_t alloc_hint;
447     uint16_t context_id;
448     uint16_t opnum;
449 #if 0
450     Uuid object;           /* only if object flag is set */
451     uint8_t stub data[];   /* 8 octet aligned if auth_verifier, which will
452                               take care of the pad. */
453     auth_verifier_co_t auth_verifier;
454 #endif
455 } DceRpcCoRequest;
456 
457 typedef struct _DceRpcCoResponse
458 {
459     uint32_t alloc_hint;
460     uint16_t context_id;
461     uint8_t cancel_count;
462     uint8_t reserved;
463 #if 0
464     uint8_t stub data[]   /* 8 octet aligned if auth_verifier, which will
465                              take care of the pad. */
466     auth_verifier_co_t auth_verifier;
467 #endif
468 } DceRpcCoResponse;
469 
470 #if 0
471 typedef struct _DceRpcCoShutdown
472 {
473     // nothing
474 
475 } DceRpcCoShutdown;
476 #endif
477 
478 typedef struct _DceRpcCoAuthVerifier
479 {
480 #if 0
481     uint8_t auth_pad[];  /* variable length to restore 4 byte alignment */
482 #endif
483     uint8_t auth_type;
484     uint8_t auth_level;
485     uint8_t auth_pad_length;
486     uint8_t auth_reserved;
487     uint32_t auth_context_id;
488 #if 0
489     uint8_t auth_value[];  /* variable auth_length */
490 #endif
491 
492 } DceRpcCoAuthVerifier;
493 
494 /* Optional Data used with Reject/Disconnect header
495  * These do not share the common header, but are special
496  * cases (pretty much the same as the common header) */
497 typedef uint16_t DceRpcReasonCode;
498 
499 typedef struct _DceRpcCoOptData
500 {
501     DceRpcCoVersion pversion;
502     uint8_t reserved[2];
503     uint8_t packed_drep[4];
504     uint32_t reject_status;
505     uint8_t reserved2[4];
506 
507 } DceRpcCoOptData;
508 
509 typedef struct _DceRpcCoRejHdr
510 {
511     DceRpcReasonCode reason_code;
512     DceRpcCoOptData rpc_info;
513 
514 } DceRpcCoRejHdr;
515 
516 /* Disconnect header same as Reject header */
517 typedef DceRpcCoRejHdr DceRpcCoDiscHdr;
518 
519 #ifdef WIN32
520 #pragma pack(pop, dcerpc_hdrs)
521 #else
522 #pragma pack()
523 #endif
524 
525 /********************************************************************
526  * Inline functions prototypes
527  ********************************************************************/
528 static inline DceRpcBoFlag DceRpcByteOrder(const uint8_t);
529 static inline uint16_t DceRpcNtohs(const uint16_t *, const DceRpcBoFlag);
530 static inline uint16_t DceRpcHtons(const uint16_t *, const DceRpcBoFlag);
531 static inline uint32_t DceRpcNtohl(const uint32_t *, const DceRpcBoFlag);
532 static inline uint32_t DceRpcHtonl(const uint32_t *, const DceRpcBoFlag);
533 
534 /* Connectionless */
535 static inline uint8_t DceRpcClRpcVers(const DceRpcClHdr *);
536 static inline DceRpcBoFlag DceRpcClByteOrder(const DceRpcClHdr *);
537 static inline uint32_t DceRpcClIfaceVers(const DceRpcClHdr *);
538 static inline uint16_t DceRpcClOpnum(const DceRpcClHdr *);
539 static inline uint32_t DceRpcClSeqNum(const DceRpcClHdr *);
540 static inline uint16_t DceRpcClFragNum(const DceRpcClHdr *);
541 static inline int DceRpcClFragFlag(const DceRpcClHdr *);
542 static inline int DceRpcClLastFrag(const DceRpcClHdr *);
543 static inline int DceRpcClFirstFrag(const DceRpcClHdr *);
544 static inline uint16_t DceRpcClLen(const DceRpcClHdr *);
545 static inline int DceRpcClFrag(const DceRpcClHdr *);
546 
547 /* Connection oriented */
548 static inline uint8_t DceRpcCoVersMaj(const DceRpcCoHdr *);
549 static inline uint8_t DceRpcCoVersMin(const DceRpcCoHdr *);
550 static inline DceRpcPduType DceRpcCoPduType(const DceRpcCoHdr *);
551 static inline int DceRpcCoFirstFrag(const DceRpcCoHdr *);
552 static inline int DceRpcCoLastFrag(const DceRpcCoHdr *);
553 static inline int DceRpcCoObjectFlag(const DceRpcCoHdr *);
554 static inline DceRpcBoFlag DceRpcCoByteOrder(const DceRpcCoHdr *);
555 static inline uint16_t DceRpcCoFragLen(const DceRpcCoHdr *);
556 static inline uint16_t DceRpcCoAuthLen(const DceRpcCoHdr *);
557 static inline uint32_t DceRpcCoCallId(const DceRpcCoHdr *);
558 static inline uint16_t DceRpcCoCtxId(const DceRpcCoHdr *, const DceRpcCoRequest *);
559 static inline uint16_t DceRpcCoCtxIdResp(const DceRpcCoHdr *, const DceRpcCoResponse *);
560 static inline uint16_t DceRpcCoOpnum(const DceRpcCoHdr *, const DceRpcCoRequest *);
561 static inline uint16_t DceRpcCoBindMaxXmitFrag(const DceRpcCoHdr *, const DceRpcCoBind *);
562 static inline uint16_t DceRpcCoBindAckMaxRecvFrag(const DceRpcCoHdr *, const DceRpcCoBindAck *);
563 static inline uint8_t DceRpcCoNumCtxItems(const DceRpcCoBind *);
564 static inline uint16_t DceRpcCoContElemCtxId(const DceRpcCoHdr *, const DceRpcCoContElem *);
565 static inline uint8_t DceRpcCoContElemNumTransSyntaxes(const DceRpcCoContElem *);
566 static inline const Uuid * DceRpcCoContElemIface(const DceRpcCoContElem *);
567 static inline uint16_t DceRpcCoContElemIfaceVersMaj(const DceRpcCoHdr *, const DceRpcCoContElem *);
568 static inline uint16_t DceRpcCoContElemIfaceVersMin(const DceRpcCoHdr *, const DceRpcCoContElem *);
569 static inline uint16_t DceRpcCoSecAddrLen(const DceRpcCoHdr *, const DceRpcCoBindAck *);
570 static inline uint8_t DceRpcCoContNumResults(const DceRpcCoContResultList *);
571 static inline uint16_t DceRpcCoContRes(const DceRpcCoHdr *, const DceRpcCoContResult *);
572 static inline uint16_t DceRpcCoAuthPad(const DceRpcCoAuthVerifier *);
573 static inline uint8_t DceRpcCoAuthLevel(const DceRpcCoAuthVerifier *);
574 
575 /********************************************************************
576  * Function:
577  *
578  * Purpose:
579  *
580  * Arguments:
581  *
582  * Returns:
583  *
584  ********************************************************************/
DceRpcByteOrder(const uint8_t value)585 static inline DceRpcBoFlag DceRpcByteOrder(const uint8_t value)
586 {
587     if ((value & 0x10) >> 4)
588         return DCERPC_BO_FLAG__LITTLE_ENDIAN;
589 
590     return DCERPC_BO_FLAG__BIG_ENDIAN;
591 }
592 
593 /********************************************************************
594  * Function:
595  *
596  * Purpose:
597  *
598  * Arguments:
599  *
600  * Returns:
601  *
602  ********************************************************************/
DceRpcNtohs(const uint16_t * ptr,const DceRpcBoFlag bo_flag)603 static inline uint16_t DceRpcNtohs(const uint16_t *ptr, const DceRpcBoFlag bo_flag)
604 {
605     uint16_t value;
606 
607     if (ptr == NULL)
608         return 0;
609 
610 #ifdef WORDS_MUSTALIGN
611     value = *((uint8_t *)ptr) << 8 | *((uint8_t *)ptr + 1);
612 #else
613     value = *ptr;
614 #endif  /* WORDS_MUSTALIGN */
615 
616     if (bo_flag == DCERPC_BO_FLAG__NONE)
617         return value;
618 
619 #ifdef WORDS_BIGENDIAN
620     if (bo_flag == DCERPC_BO_FLAG__BIG_ENDIAN)
621 #else
622     if (bo_flag == DCERPC_BO_FLAG__LITTLE_ENDIAN)
623 #endif  /* WORDS_BIGENDIAN */
624         return value;
625 
626     return ((value & 0xff00) >> 8) | ((value & 0x00ff) << 8);
627 }
628 
629 /********************************************************************
630  * Function:
631  *
632  * Purpose:
633  *
634  * Arguments:
635  *
636  * Returns:
637  *
638  ********************************************************************/
DceRpcHtons(const uint16_t * ptr,const DceRpcBoFlag bo_flag)639 static inline uint16_t DceRpcHtons(const uint16_t *ptr, const DceRpcBoFlag bo_flag)
640 {
641     return DceRpcNtohs(ptr, bo_flag);
642 }
643 
644 /********************************************************************
645  * Function:
646  *
647  * Purpose:
648  *
649  * Arguments:
650  *
651  * Returns:
652  *
653  ********************************************************************/
DceRpcNtohl(const uint32_t * ptr,const DceRpcBoFlag bo_flag)654 static inline uint32_t DceRpcNtohl(const uint32_t *ptr, const DceRpcBoFlag bo_flag)
655 {
656     uint32_t value;
657 
658     if (ptr == NULL)
659         return 0;
660 
661 #ifdef WORDS_MUSTALIGN
662     value = *((uint8_t *)ptr)     << 24 | *((uint8_t *)ptr + 1) << 16 |
663             *((uint8_t *)ptr + 2) << 8  | *((uint8_t *)ptr + 3);
664 #else
665     value = *ptr;
666 #endif  /* WORDS_MUSTALIGN */
667 
668     if (bo_flag == DCERPC_BO_FLAG__NONE)
669         return value;
670 
671 #ifdef WORDS_BIGENDIAN
672     if (bo_flag == DCERPC_BO_FLAG__BIG_ENDIAN)
673 #else
674     if (bo_flag == DCERPC_BO_FLAG__LITTLE_ENDIAN)
675 #endif  /* WORDS_BIGENDIAN */
676         return value;
677 
678     return ((value & 0xff000000) >> 24) | ((value & 0x00ff0000) >> 8) |
679            ((value & 0x0000ff00) << 8)  | ((value & 0x000000ff) << 24);
680 }
681 
682 /********************************************************************
683  * Function:
684  *
685  * Purpose:
686  *
687  * Arguments:
688  *
689  * Returns:
690  *
691  ********************************************************************/
DceRpcHtonl(const uint32_t * ptr,const DceRpcBoFlag bo_flag)692 static inline uint32_t DceRpcHtonl(const uint32_t *ptr, const DceRpcBoFlag bo_flag)
693 {
694     return DceRpcNtohl(ptr, bo_flag);
695 }
696 
697 /********************************************************************
698  * Function:
699  *
700  * Purpose:
701  *
702  * Arguments:
703  *
704  * Returns:
705  *
706  ********************************************************************/
DceRpcClRpcVers(const DceRpcClHdr * cl)707 static inline uint8_t DceRpcClRpcVers(const DceRpcClHdr *cl)
708 {
709     return cl->rpc_vers;
710 }
711 
712 /********************************************************************
713  * Function:
714  *
715  * Purpose:
716  *
717  * Arguments:
718  *
719  * Returns:
720  *
721  ********************************************************************/
DceRpcClPduType(const DceRpcClHdr * cl)722 static inline uint8_t DceRpcClPduType(const DceRpcClHdr *cl)
723 {
724     return cl->ptype;
725 }
726 
727 /********************************************************************
728  * Function:
729  *
730  * Purpose:
731  *
732  * Arguments:
733  *
734  * Returns:
735  *
736  ********************************************************************/
DceRpcClByteOrder(const DceRpcClHdr * cl)737 static inline DceRpcBoFlag DceRpcClByteOrder(const DceRpcClHdr *cl)
738 {
739     return DceRpcByteOrder(cl->drep[0]);
740 }
741 
742 /********************************************************************
743  * Function:
744  *
745  * Purpose:
746  *
747  * Arguments:
748  *
749  * Returns:
750  *
751  ********************************************************************/
DceRpcClIface(const DceRpcClHdr * cl)752 static inline const Uuid * DceRpcClIface(const DceRpcClHdr *cl)
753 {
754     return &cl->if_id;
755 }
756 
757 /********************************************************************
758  * Function:
759  *
760  * Purpose:
761  *
762  * Arguments:
763  *
764  * Returns:
765  *
766  ********************************************************************/
DceRpcClIfaceVers(const DceRpcClHdr * cl)767 static inline uint32_t DceRpcClIfaceVers(const DceRpcClHdr *cl)
768 {
769     return DceRpcNtohl(&cl->if_vers, DceRpcClByteOrder(cl));
770 }
771 
772 /********************************************************************
773  * Function:
774  *
775  * Purpose:
776  *
777  * Arguments:
778  *
779  * Returns:
780  *
781  ********************************************************************/
DceRpcClOpnum(const DceRpcClHdr * cl)782 static inline uint16_t DceRpcClOpnum(const DceRpcClHdr *cl)
783 {
784     return DceRpcNtohs(&cl->opnum, DceRpcClByteOrder(cl));
785 }
786 
787 /********************************************************************
788  * Function:
789  *
790  * Purpose:
791  *
792  * Arguments:
793  *
794  * Returns:
795  *
796  ********************************************************************/
DceRpcClSeqNum(const DceRpcClHdr * cl)797 static inline uint32_t DceRpcClSeqNum(const DceRpcClHdr *cl)
798 {
799     return DceRpcNtohl(&cl->seqnum, DceRpcClByteOrder(cl));
800 }
801 
802 /********************************************************************
803  * Function:
804  *
805  * Purpose:
806  *
807  * Arguments:
808  *
809  * Returns:
810  *
811  ********************************************************************/
DceRpcClFragNum(const DceRpcClHdr * cl)812 static inline uint16_t DceRpcClFragNum(const DceRpcClHdr *cl)
813 {
814     return DceRpcNtohs(&cl->fragnum, DceRpcClByteOrder(cl));
815 }
816 
817 /********************************************************************
818  * Function:
819  *
820  * Purpose:
821  *
822  * Arguments:
823  *
824  * Returns:
825  *
826  ********************************************************************/
DceRpcClFragFlag(const DceRpcClHdr * cl)827 static inline int DceRpcClFragFlag(const DceRpcClHdr *cl)
828 {
829     return cl->flags1 & DCERPC_CL_FLAGS1__FRAG;
830 }
831 
832 /********************************************************************
833  * Function:
834  *
835  * Purpose:
836  *
837  * Arguments:
838  *
839  * Returns:
840  *
841  ********************************************************************/
DceRpcClLastFrag(const DceRpcClHdr * cl)842 static inline int DceRpcClLastFrag(const DceRpcClHdr *cl)
843 {
844     return cl->flags1 & DCERPC_CL_FLAGS1__LASTFRAG;
845 }
846 
847 /********************************************************************
848  * Function:
849  *
850  * Purpose:
851  *
852  * Arguments:
853  *
854  * Returns:
855  *
856  ********************************************************************/
DceRpcClFirstFrag(const DceRpcClHdr * cl)857 static inline int DceRpcClFirstFrag(const DceRpcClHdr *cl)
858 {
859     return (DceRpcClFragFlag(cl) && (DceRpcClFragNum(cl) == 0));
860 }
861 
862 /********************************************************************
863  * Function:
864  *
865  * Purpose:
866  *
867  * Arguments:
868  *
869  * Returns:
870  *
871  ********************************************************************/
DceRpcClLen(const DceRpcClHdr * cl)872 static inline uint16_t DceRpcClLen(const DceRpcClHdr *cl)
873 {
874     return DceRpcNtohs(&cl->len, DceRpcClByteOrder(cl));
875 }
876 
877 /********************************************************************
878  * Function:
879  *
880  * Purpose:
881  *
882  * Arguments:
883  *
884  * Returns:
885  *
886  ********************************************************************/
DceRpcClFrag(const DceRpcClHdr * cl)887 static inline int DceRpcClFrag(const DceRpcClHdr *cl)
888 {
889     if (DceRpcClFragFlag(cl))
890     {
891         if (DceRpcClLastFrag(cl) && (DceRpcClFragNum(cl) == 0))
892             return 0;
893 
894         return 1;
895     }
896 
897     return 0;
898 }
899 
900 /********************************************************************
901  * Function:
902  *
903  * Purpose:
904  *
905  * Arguments:
906  *
907  * Returns:
908  *
909  ********************************************************************/
DceRpcCoVersMaj(const DceRpcCoHdr * co)910 static inline uint8_t DceRpcCoVersMaj(const DceRpcCoHdr *co)
911 {
912     return co->pversion.major;
913 }
914 
915 /********************************************************************
916  * Function:
917  *
918  * Purpose:
919  *
920  * Arguments:
921  *
922  * Returns:
923  *
924  ********************************************************************/
DceRpcCoVersMin(const DceRpcCoHdr * co)925 static inline uint8_t DceRpcCoVersMin(const DceRpcCoHdr *co)
926 {
927     return co->pversion.minor;
928 }
929 
930 /********************************************************************
931  * Function:
932  *
933  * Purpose:
934  *
935  * Arguments:
936  *
937  * Returns:
938  *
939  ********************************************************************/
DceRpcCoPduType(const DceRpcCoHdr * co)940 static inline DceRpcPduType DceRpcCoPduType(const DceRpcCoHdr *co)
941 {
942     return (DceRpcPduType)co->ptype;
943 }
944 
945 /********************************************************************
946  * Function:
947  *
948  * Purpose:
949  *
950  * Arguments:
951  *
952  * Returns:
953  *
954  ********************************************************************/
DceRpcCoFirstFrag(const DceRpcCoHdr * co)955 static inline int DceRpcCoFirstFrag(const DceRpcCoHdr *co)
956 {
957     return co->pfc_flags & DCERPC_CO_PFC_FLAGS__FIRST_FRAG;
958 }
959 
960 /********************************************************************
961  * Function:
962  *
963  * Purpose:
964  *
965  * Arguments:
966  *
967  * Returns:
968  *
969  ********************************************************************/
DceRpcCoLastFrag(const DceRpcCoHdr * co)970 static inline int DceRpcCoLastFrag(const DceRpcCoHdr *co)
971 {
972     return co->pfc_flags & DCERPC_CO_PFC_FLAGS__LAST_FRAG;
973 }
974 
975 /********************************************************************
976  * Function:
977  *
978  * Purpose:
979  *
980  * Arguments:
981  *
982  * Returns:
983  *
984  ********************************************************************/
DceRpcCoObjectFlag(const DceRpcCoHdr * co)985 static inline int DceRpcCoObjectFlag(const DceRpcCoHdr *co)
986 {
987     return co->pfc_flags & DCERPC_CO_PFC_FLAGS__OBJECT_UUID;
988 }
989 
990 /********************************************************************
991  * Function:
992  *
993  * Purpose:
994  *
995  * Arguments:
996  *
997  * Returns:
998  *
999  ********************************************************************/
DceRpcCoByteOrder(const DceRpcCoHdr * co)1000 static inline DceRpcBoFlag DceRpcCoByteOrder(const DceRpcCoHdr *co)
1001 {
1002     return DceRpcByteOrder(co->packed_drep[0]);
1003 }
1004 
1005 /********************************************************************
1006  * Function:
1007  *
1008  * Purpose:
1009  *
1010  * Arguments:
1011  *
1012  * Returns:
1013  *
1014  ********************************************************************/
DceRpcCoFragLen(const DceRpcCoHdr * co)1015 static inline uint16_t DceRpcCoFragLen(const DceRpcCoHdr *co)
1016 {
1017     return DceRpcNtohs(&co->frag_length, DceRpcCoByteOrder(co));
1018 }
1019 
1020 /********************************************************************
1021  * Function:
1022  *
1023  * Purpose:
1024  *
1025  * Arguments:
1026  *
1027  * Returns:
1028  *
1029  ********************************************************************/
DceRpcCoAuthLen(const DceRpcCoHdr * co)1030 static inline uint16_t DceRpcCoAuthLen(const DceRpcCoHdr *co)
1031 {
1032     return DceRpcNtohs(&co->auth_length, DceRpcCoByteOrder(co));
1033 }
1034 
1035 /********************************************************************
1036  * Function:
1037  *
1038  * Purpose:
1039  *
1040  * Arguments:
1041  *
1042  * Returns:
1043  *
1044  ********************************************************************/
DceRpcCoCallId(const DceRpcCoHdr * co)1045 static inline uint32_t DceRpcCoCallId(const DceRpcCoHdr *co)
1046 {
1047     return DceRpcNtohl(&co->call_id, DceRpcCoByteOrder(co));
1048 }
1049 
1050 /********************************************************************
1051  * Function:
1052  *
1053  * Purpose:
1054  *
1055  * Arguments:
1056  *
1057  * Returns:
1058  *
1059  ********************************************************************/
DceRpcCoOpnum(const DceRpcCoHdr * co,const DceRpcCoRequest * cor)1060 static inline uint16_t DceRpcCoOpnum(const DceRpcCoHdr *co, const DceRpcCoRequest *cor)
1061 {
1062     return DceRpcNtohs(&cor->opnum, DceRpcCoByteOrder(co));
1063 }
1064 
1065 /********************************************************************
1066  * Function:
1067  *
1068  * Purpose:
1069  *
1070  * Arguments:
1071  *
1072  * Returns:
1073  *
1074  ********************************************************************/
DceRpcCoCtxId(const DceRpcCoHdr * co,const DceRpcCoRequest * cor)1075 static inline uint16_t DceRpcCoCtxId(const DceRpcCoHdr *co, const DceRpcCoRequest *cor)
1076 {
1077     return DceRpcNtohs(&cor->context_id, DceRpcCoByteOrder(co));
1078 }
1079 
1080 /********************************************************************
1081  * Function:
1082  *
1083  * Purpose:
1084  *
1085  * Arguments:
1086  *
1087  * Returns:
1088  *
1089  ********************************************************************/
DceRpcCoCtxIdResp(const DceRpcCoHdr * co,const DceRpcCoResponse * cor)1090 static inline uint16_t DceRpcCoCtxIdResp(const DceRpcCoHdr *co, const DceRpcCoResponse *cor)
1091 {
1092     return DceRpcNtohs(&cor->context_id, DceRpcCoByteOrder(co));
1093 }
1094 
1095 /********************************************************************
1096  * Function:
1097  *
1098  * Purpose:
1099  *
1100  * Arguments:
1101  *
1102  * Returns:
1103  *
1104  ********************************************************************/
DceRpcCoBindMaxXmitFrag(const DceRpcCoHdr * co,const DceRpcCoBind * cob)1105 static inline uint16_t DceRpcCoBindMaxXmitFrag(const DceRpcCoHdr *co, const DceRpcCoBind *cob)
1106 {
1107     return DceRpcNtohs(&cob->max_xmit_frag, DceRpcCoByteOrder(co));
1108 }
1109 
1110 /********************************************************************
1111  * Function:
1112  *
1113  * Purpose:
1114  *
1115  * Arguments:
1116  *
1117  * Returns:
1118  *
1119  ********************************************************************/
DceRpcCoBindAckMaxRecvFrag(const DceRpcCoHdr * co,const DceRpcCoBindAck * coba)1120 static inline uint16_t DceRpcCoBindAckMaxRecvFrag(const DceRpcCoHdr *co, const DceRpcCoBindAck *coba)
1121 {
1122     return DceRpcNtohs(&coba->max_recv_frag, DceRpcCoByteOrder(co));
1123 }
1124 
1125 /********************************************************************
1126  * Function:
1127  *
1128  * Purpose:
1129  *
1130  * Arguments:
1131  *
1132  * Returns:
1133  *
1134  ********************************************************************/
DceRpcCoNumCtxItems(const DceRpcCoBind * cob)1135 static inline uint8_t DceRpcCoNumCtxItems(const DceRpcCoBind *cob)
1136 {
1137     return cob->n_context_elem;
1138 }
1139 
1140 /********************************************************************
1141  * Function:
1142  *
1143  * Purpose:
1144  *
1145  * Arguments:
1146  *
1147  * Returns:
1148  *
1149  ********************************************************************/
DceRpcCoContElemCtxId(const DceRpcCoHdr * co,const DceRpcCoContElem * coce)1150 static inline uint16_t DceRpcCoContElemCtxId(const DceRpcCoHdr *co, const DceRpcCoContElem *coce)
1151 {
1152     return DceRpcNtohs(&coce->p_cont_id, DceRpcCoByteOrder(co));
1153 }
1154 
1155 /********************************************************************
1156  * Function:
1157  *
1158  * Purpose:
1159  *
1160  * Arguments:
1161  *
1162  * Returns:
1163  *
1164  ********************************************************************/
DceRpcCoContElemNumTransSyntaxes(const DceRpcCoContElem * coce)1165 static inline uint8_t DceRpcCoContElemNumTransSyntaxes(const DceRpcCoContElem *coce)
1166 {
1167     return coce->n_transfer_syn;
1168 }
1169 
1170 /********************************************************************
1171  * Function:
1172  *
1173  * Purpose:
1174  *
1175  * Arguments:
1176  *
1177  * Returns:
1178  *
1179  ********************************************************************/
DceRpcCoContElemIface(const DceRpcCoContElem * coce)1180 static inline const Uuid * DceRpcCoContElemIface(const DceRpcCoContElem *coce)
1181 {
1182     return &coce->abstract_syntax.if_uuid;
1183 }
1184 
1185 /********************************************************************
1186  * Function:
1187  *
1188  * Purpose:
1189  *
1190  * Arguments:
1191  *
1192  * Returns:
1193  *
1194  ********************************************************************/
DceRpcCoContElemIfaceVersMaj(const DceRpcCoHdr * co,const DceRpcCoContElem * coce)1195 static inline uint16_t DceRpcCoContElemIfaceVersMaj(const DceRpcCoHdr *co, const DceRpcCoContElem *coce)
1196 {
1197     return (uint16_t)(DceRpcNtohl(&coce->abstract_syntax.if_version, DceRpcCoByteOrder(co)) & 0x0000ffff);
1198 }
1199 
1200 /********************************************************************
1201  * Function:
1202  *
1203  * Purpose:
1204  *
1205  * Arguments:
1206  *
1207  * Returns:
1208  *
1209  ********************************************************************/
DceRpcCoContElemIfaceVersMin(const DceRpcCoHdr * co,const DceRpcCoContElem * coce)1210 static inline uint16_t DceRpcCoContElemIfaceVersMin(const DceRpcCoHdr *co, const DceRpcCoContElem *coce)
1211 {
1212     return (uint16_t)(DceRpcNtohl(&coce->abstract_syntax.if_version, DceRpcCoByteOrder(co)) >> 16);
1213 }
1214 
1215 /********************************************************************
1216  * Function:
1217  *
1218  * Purpose:
1219  *
1220  * Arguments:
1221  *
1222  * Returns:
1223  *
1224  ********************************************************************/
DceRpcCoSecAddrLen(const DceRpcCoHdr * co,const DceRpcCoBindAck * coba)1225 static inline uint16_t DceRpcCoSecAddrLen(const DceRpcCoHdr *co, const DceRpcCoBindAck *coba)
1226 {
1227     return DceRpcNtohs(&coba->sec_addr_len, DceRpcCoByteOrder(co));
1228 }
1229 
1230 /********************************************************************
1231  * Function:
1232  *
1233  * Purpose:
1234  *
1235  * Arguments:
1236  *
1237  * Returns:
1238  *
1239  ********************************************************************/
DceRpcCoContNumResults(const DceRpcCoContResultList * cocrl)1240 static inline uint8_t DceRpcCoContNumResults(const DceRpcCoContResultList *cocrl)
1241 {
1242     return cocrl->n_results;
1243 }
1244 
1245 /********************************************************************
1246  * Function:
1247  *
1248  * Purpose:
1249  *
1250  * Arguments:
1251  *
1252  * Returns:
1253  *
1254  ********************************************************************/
DceRpcCoContRes(const DceRpcCoHdr * co,const DceRpcCoContResult * cocr)1255 static inline uint16_t DceRpcCoContRes(const DceRpcCoHdr *co, const DceRpcCoContResult *cocr)
1256 {
1257     return DceRpcNtohs(&cocr->result, DceRpcCoByteOrder(co));
1258 }
1259 
1260 /********************************************************************
1261  * Function:
1262  *
1263  * Purpose:
1264  *
1265  * Arguments:
1266  *
1267  * Returns:
1268  *
1269  ********************************************************************/
DceRpcCoAuthPad(const DceRpcCoAuthVerifier * coav)1270 static inline uint16_t DceRpcCoAuthPad(const DceRpcCoAuthVerifier *coav)
1271 {
1272     return coav->auth_pad_length;
1273 }
1274 
1275 /********************************************************************
1276  * Function:
1277  *
1278  * Purpose:
1279  *
1280  * Arguments:
1281  *
1282  * Returns:
1283  *
1284  ********************************************************************/
DceRpcCoAuthLevel(const DceRpcCoAuthVerifier * coav)1285 static inline uint8_t DceRpcCoAuthLevel(const DceRpcCoAuthVerifier *coav)
1286 {
1287     return coav->auth_level;
1288 }
1289 
1290 #endif  /* DCERPC_H */
1291 
1292