aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/suricata/src/app-layer-dcerpc-common.h
blob: cdda563009d1abdf81a79fc69993a76f9661f78b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
/* Copyright (C) 2007-2010 Open Information Security Foundation
 *
 * You can copy, redistribute or modify this Program under the terms of
 * the GNU General Public License version 2 as published by the Free
 * Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * version 2 along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

/**
 * \file
 *
 * \author Kirby Kuehl <kkuehl@gmail.com>
 */

#ifndef __APP_LAYER_DCERPC_COMMON_H__
#define __APP_LAYER_DCERPC_COMMON_H__

#include "app-layer-protos.h"
#include "app-layer-parser.h"
#include "flow.h"
#include "queue.h"
#include "util-byte.h"

void RegisterDCERPCParsers(void);
void DCERPCParserTests(void);
void DCERPCParserRegisterTests(void);

// http://www.opengroup.org/onlinepubs/9629399/chap12.htm#tagcjh_17_06
#define REQUEST             0
#define PING                1
#define RESPONSE            2
#define FAULT               3
#define WORKING             4
#define NOCALL              5
#define REJECT              6
#define ACK                 7
#define CL_CANCEL           8
#define FACK                9
#define CANCEL_ACK          10
#define BIND                11
#define BIND_ACK            12
#define BIND_NAK            13
#define ALTER_CONTEXT       14
#define ALTER_CONTEXT_RESP  15
#define SHUTDOWN            17
#define CO_CANCEL           18
#define ORPHANED            19
#if 0
typedef struct {
    uint8_t rpc_vers; /* 4 RPC protocol major version (4 LSB only)*/
    uint8_t ptype;      /* Packet type (5 LSB only) */
    uint8_t flags1;     /* Packet flags */
    uint8_t flags2;     /* Packet flags */
    uint8_t drep[3];    /* Data representation format label */
    uint8_t serial_hi;  /* High byte of serial number */
    uuid_t         object;     /* Object identifier */
    uuid_t         if_id;      /* Interface identifier */
    uuid_t         act_id;     /* Activity identifier */
    unsigned long  server_boot;/* Server boot time */
    unsigned long  if_vers;    /* Interface version */
    unsigned long  seqnum;     /* Sequence number */
    unsigned short opnum;      /* Operation number */
    unsigned short ihint;      /* Interface hint */
    unsigned short ahint;      /* Activity hint */
    unsigned short len;        /* Length of packet body */
    unsigned short fragnum;    /* Fragment number */
    unsigned small auth_proto; /* Authentication protocol identifier*/
    unsigned small serial_lo;  /* Low byte of serial number */
} dc_rpc_cl_pkt_hdr_t;
#endif

#define RESERVED_01     0x01
#define LASTFRAG        0x02
#define FRAG            0x04
#define NOFACK          0x08
#define MAYBE           0x10
#define IDEMPOTENT      0x20
#define BROADCAST       0x40
#define RESERVED_80     0x80

#define CANCEL_PENDING  0x02
#define RESERVED_04     0x04
#define RESERVED_10     0x10
#define RESERVED_20     0x20
#define RESERVED_40     0x40
#define RESERVED_80     0x80

typedef struct DCERPCHdr_ {
    uint8_t rpc_vers;       /**< 00:01 RPC version should be 5 */
    uint8_t rpc_vers_minor; /**< 01:01 minor version */
    uint8_t type;           /**< 02:01 packet type */
    uint8_t pfc_flags;      /**< 03:01 flags (see PFC_... ) */
    uint8_t packed_drep[4]; /**< 04:04 NDR data representation format label */
    uint16_t frag_length;   /**< 08:02 total length of fragment */
    uint16_t auth_length;   /**< 10:02 length of auth_value */
    uint32_t call_id;       /**< 12:04 call identifier */
} DCERPCHdr;

#define DCERPC_HDR_LEN 16

typedef struct DCERPCHdrUdp_ {
    uint8_t rpc_vers;   /**< 4 RPC protocol major version (4 LSB only)*/
    uint8_t type;       /**< Packet type (5 LSB only) */
    uint8_t flags1;     /**< Packet flags */
    uint8_t flags2;     /**< Packet flags */
    uint8_t drep[3];    /**< Data representation format label */
    uint8_t serial_hi;  /**< High byte of serial number */
    uint8_t objectuuid[16];
    uint8_t interfaceuuid[16];
    uint8_t activityuuid[16];
    uint32_t server_boot;   /**< Server boot time */
    uint32_t if_vers;   /**< Interface version */
    uint32_t seqnum;    /**< Sequence number */
    uint16_t opnum;     /**< Operation number */
    uint16_t ihint;     /**< Interface hint */
    uint16_t ahint;     /**< Activity hint */
    uint16_t fraglen;   /**< Length of packet body */
    uint16_t fragnum;   /**< Fragment number */
    uint8_t auth_proto; /**< Authentication protocol identifier*/
    uint8_t serial_lo;  /**< Low byte of serial number */
} DCERPCHdrUdp;

#define DCERPC_UDP_HDR_LEN 80

#define DCERPC_UUID_ENTRY_FLAG_FF       0x0001  /**< FIRST flag set on the packet
                                                  that contained this uuid entry */

typedef struct DCERPCUuidEntry_ {
    uint16_t ctxid;
    uint16_t internal_id;
    uint16_t result;
    uint8_t uuid[16];
    uint16_t version;
    uint16_t versionminor;
    uint16_t flags;                             /**< DCERPC_UUID_ENTRY_FLAG_* flags */
    TAILQ_ENTRY(DCERPCUuidEntry_) next;
} DCERPCUuidEntry;

typedef struct DCERPCBindBindAck_ {
    uint8_t numctxitems;
    uint8_t numctxitemsleft;
    uint8_t ctxbytesprocessed;
    uint16_t ctxid;
    uint8_t uuid[16];
    uint16_t version;
    uint16_t versionminor;
    DCERPCUuidEntry *uuid_entry;
    TAILQ_HEAD(, DCERPCUuidEntry_) uuid_list;
    /* the interface uuids that the server has accepted */
    TAILQ_HEAD(, DCERPCUuidEntry_) accepted_uuid_list;
    uint16_t uuid_internal_id;
    uint16_t secondaryaddrlen;
    uint16_t secondaryaddrlenleft;
    uint16_t result;
} DCERPCBindBindAck;

typedef struct DCERPCRequest_ {
    uint16_t ctxid;
    uint16_t opnum;
    /* holds the stub data for the request */
    uint8_t *stub_data_buffer;
    /* length of the above buffer */
    uint32_t stub_data_buffer_len;
    /* used by the dce preproc to indicate fresh entry in the stub data buffer */
    uint8_t stub_data_fresh;
    uint8_t first_request_seen;
} DCERPCRequest;

typedef struct DCERPCResponse_ {
    /* holds the stub data for the response */
    uint8_t *stub_data_buffer;
    /* length of the above buffer */
    uint32_t stub_data_buffer_len;
    /* used by the dce preproc to indicate fresh entry in the stub data buffer */
    uint8_t stub_data_fresh;
} DCERPCResponse;

typedef struct DCERPC_ {
    DCERPCHdr dcerpchdr;
    DCERPCBindBindAck dcerpcbindbindack;
    DCERPCRequest dcerpcrequest;
    DCERPCResponse dcerpcresponse;
    uint16_t bytesprocessed;
    uint8_t pad;
    uint16_t padleft;
    uint16_t transaction_id;
    /* indicates if the dcerpc pdu state is in the middle of processing
     * a fragmented pdu */
    uint8_t pdu_fragged;
} DCERPC;

typedef struct DCERPCUDP_ {
    DCERPCHdrUdp dcerpchdrudp;
    DCERPCBindBindAck dcerpcbindbindack;
    DCERPCRequest dcerpcrequest;
    DCERPCResponse dcerpcresponse;
    uint16_t bytesprocessed;
    uint16_t fraglenleft;
    uint8_t *frag_data;
    DCERPCUuidEntry *uuid_entry;
    TAILQ_HEAD(, uuid_entry) uuid_list;
} DCERPCUDP;

/** First fragment */
#define PFC_FIRST_FRAG           0x01
/** Last fragment */
#define PFC_LAST_FRAG            0x02
/** Cancel was pending at sender */
#define PFC_PENDING_CANCEL       0x04
#define PFC_RESERVED_1           0x08
/** supports concurrent multiplexing of a single connection. */
#define PFC_CONC_MPX             0x10
/** only meaningful on `fault' packet; if true, guaranteed
 *  call did not execute. */
#define PFC_DID_NOT_EXECUTE      0x20
/** `maybe' call semantics requested */
#define PFC_MAYBE                0x40
/** if true, a non-nil object UUID was specified in the handle, and
 *  is present in the optional object field. If false, the object field
 * is omitted. */
#define PFC_OBJECT_UUID          0x80

#define REASON_NOT_SPECIFIED            0
#define TEMPORARY_CONGESTION            1
#define LOCAL_LIMIT_EXCEEDED            2
#define CALLED_PADDR_UNKNOWN            3 /* not used */
#define PROTOCOL_VERSION_NOT_SUPPORTED  4
#define DEFAULT_CONTEXT_NOT_SUPPORTED   5 /* not used */
#define USER_DATA_NOT_READABLE          6 /* not used */
#define NO_PSAP_AVAILABLE               7 /* not used */

int32_t DCERPCParser(DCERPC *, uint8_t *, uint32_t);
void hexdump(const void *buf, size_t len);
void printUUID(char *type, DCERPCUuidEntry *uuid);

#endif /* __APP_LAYER_DCERPC_COMMON_H__ */