suricata
app-layer-dcerpc-udp.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009, 2010 Open Information Security Foundation
3  *
4  * You can copy, redistribute or modify this Program under the terms of
5  * the GNU General Public License version 2 as published by the Free
6  * Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * version 2 along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16  * 02110-1301, USA.
17  */
18 
19 /* \file
20  *
21  * \author Kirby Kuehl <kkuehl@gmail.com>
22  *
23  * \todo Updated by AS: Inspect the possibilities of sending junk start at the
24  * start of udp session to avoid alproto detection.
25  */
26 
27 #include "suricata-common.h"
28 #include "suricata.h"
29 
30 #include "debug.h"
31 #include "decode.h"
32 
33 #include "flow-util.h"
34 
35 #include "threads.h"
36 
37 #include "util-print.h"
38 #include "util-pool.h"
39 #include "util-debug.h"
40 
41 #include "stream-tcp-private.h"
42 #include "stream-tcp-reassemble.h"
43 #include "stream-tcp.h"
44 #include "stream.h"
45 
46 #include "app-layer-protos.h"
47 #include "app-layer-parser.h"
48 #include "app-layer.h"
49 
50 #include "util-spm.h"
51 #include "util-unittest.h"
52 
53 #include "app-layer-dcerpc-udp.h"
54 
55 enum {
61  /* must be last */
63 };
64 
65 /** \internal
66  * \retval stub_len or 0 in case of error */
67 static uint32_t FragmentDataParser(Flow *f, void *dcerpcudp_state,
68  AppLayerParserState *pstate, const uint8_t *input, uint32_t input_len)
69 {
70  SCEnter();
71  DCERPCUDPState *sstate = (DCERPCUDPState *) dcerpcudp_state;
72  uint8_t **stub_data_buffer = NULL;
73  uint32_t *stub_data_buffer_len = NULL;
74  uint16_t stub_len = 0;
75  void *ptmp;
76 
77  /* request PDU. Retrieve the request stub buffer */
78  if (sstate->dcerpc.dcerpchdrudp.type == REQUEST) {
79  stub_data_buffer = &sstate->dcerpc.dcerpcrequest.stub_data_buffer;
80  stub_data_buffer_len = &sstate->dcerpc.dcerpcrequest.stub_data_buffer_len;
81 
82  /* response PDU. Retrieve the response stub buffer */
83  } else {
84  stub_data_buffer = &sstate->dcerpc.dcerpcresponse.stub_data_buffer;
85  stub_data_buffer_len = &sstate->dcerpc.dcerpcresponse.stub_data_buffer_len;
86  }
87 
88  stub_len = (sstate->dcerpc.fraglenleft < input_len) ? sstate->dcerpc.fraglenleft : input_len;
89 
90  if (stub_len == 0) {
91  SCReturnUInt(0);
92  }
93  /* if the frag is the the first frag irrespective of it being a part of
94  * a multi frag PDU or not, it indicates the previous PDU's stub would
95  * have been buffered and processed and we can use the buffer to hold
96  * frags from a fresh request/response */
97  if (sstate->dcerpc.dcerpchdrudp.flags1 & PFC_FIRST_FRAG) {
98  *stub_data_buffer_len = 0;
99  }
100 
101  ptmp = SCRealloc(*stub_data_buffer, *stub_data_buffer_len + stub_len);
102  if (ptmp == NULL) {
103  SCFree(*stub_data_buffer);
104  *stub_data_buffer = NULL;
105  SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
106  SCReturnUInt(0);
107  }
108 
109  *stub_data_buffer = ptmp;
110  memcpy(*stub_data_buffer + *stub_data_buffer_len, input, stub_len);
111 
112  /* length of the buffered stub */
113  *stub_data_buffer_len += stub_len;
114 
115  sstate->dcerpc.fraglenleft -= stub_len;
116  sstate->dcerpc.bytesprocessed += stub_len;
117 
118 #ifdef DEBUG
119  if (SCLogDebugEnabled()) {
120  int i = 0;
121  for (i = 0; i < stub_len; i++) {
122  SCLogDebug("0x%02x ", input[i]);
123  }
124  }
125 #endif
126 
127  SCReturnUInt((uint32_t)stub_len);
128 }
129 
130 /**
131  * \brief DCERPCParseHeader parses the 16 byte DCERPC header
132  * A fast path for normal decoding is used when there is enough bytes
133  * present to parse the entire header. A slow path is used to parse
134  * fragmented packets.
135  */
136 static int DCERPCUDPParseHeader(Flow *f, void *dcerpcudp_state,
137  AppLayerParserState *pstate, const uint8_t *input, uint32_t input_len)
138 {
139  SCEnter();
140  const uint8_t *p = input;
141  DCERPCUDPState *sstate = (DCERPCUDPState *) dcerpcudp_state;
142  if (input_len) {
143  switch (sstate->bytesprocessed) {
144  case 0:
145  // fallthrough
146  /* above statement to prevent coverity FPs from the switch
147  * fall through */
148  if (input_len >= DCERPC_UDP_HDR_LEN) {
149  sstate->dcerpc.dcerpchdrudp.rpc_vers = *p;
150  if (sstate->dcerpc.dcerpchdrudp.rpc_vers != 4) {
151  SCLogDebug("DCERPC UDP Header did not validate");
152  SCReturnInt(-1);
153  }
154  sstate->dcerpc.dcerpchdrudp.type = *(p + 1);
155  sstate->dcerpc.dcerpchdrudp.flags1 = *(p + 2);
156  sstate->dcerpc.dcerpchdrudp.flags2 = *(p + 3);
157  sstate->dcerpc.dcerpchdrudp.drep[0] = *(p + 4);
158  sstate->dcerpc.dcerpchdrudp.drep[1] = *(p + 5);
159  sstate->dcerpc.dcerpchdrudp.drep[2] = *(p + 6);
160  sstate->dcerpc.dcerpchdrudp.serial_hi = *(p + 7);
161  sstate->dcerpc.dcerpchdrudp.objectuuid[3] = *(p + 8);
162  sstate->dcerpc.dcerpchdrudp.objectuuid[2] = *(p + 9);
163  sstate->dcerpc.dcerpchdrudp.objectuuid[1] = *(p + 10);
164  sstate->dcerpc.dcerpchdrudp.objectuuid[0] = *(p + 11);
165  sstate->dcerpc.dcerpchdrudp.objectuuid[5] = *(p + 12);
166  sstate->dcerpc.dcerpchdrudp.objectuuid[4] = *(p + 13);
167  sstate->dcerpc.dcerpchdrudp.objectuuid[7] = *(p + 14);
168  sstate->dcerpc.dcerpchdrudp.objectuuid[6] = *(p + 15);
169  sstate->dcerpc.dcerpchdrudp.objectuuid[8] = *(p + 16);
170  sstate->dcerpc.dcerpchdrudp.objectuuid[9] = *(p + 17);
171  sstate->dcerpc.dcerpchdrudp.objectuuid[10] = *(p + 18);
172  sstate->dcerpc.dcerpchdrudp.objectuuid[11] = *(p + 19);
173  sstate->dcerpc.dcerpchdrudp.objectuuid[12] = *(p + 20);
174  sstate->dcerpc.dcerpchdrudp.objectuuid[13] = *(p + 21);
175  sstate->dcerpc.dcerpchdrudp.objectuuid[14] = *(p + 22);
176  sstate->dcerpc.dcerpchdrudp.objectuuid[15] = *(p + 23);
177  sstate->dcerpc.dcerpchdrudp.interfaceuuid[3] = *(p + 24);
178  sstate->dcerpc.dcerpchdrudp.interfaceuuid[2] = *(p + 25);
179  sstate->dcerpc.dcerpchdrudp.interfaceuuid[1] = *(p + 26);
180  sstate->dcerpc.dcerpchdrudp.interfaceuuid[0] = *(p + 27);
181  sstate->dcerpc.dcerpchdrudp.interfaceuuid[5] = *(p + 28);
182  sstate->dcerpc.dcerpchdrudp.interfaceuuid[4] = *(p + 29);
183  sstate->dcerpc.dcerpchdrudp.interfaceuuid[7] = *(p + 30);
184  sstate->dcerpc.dcerpchdrudp.interfaceuuid[6] = *(p + 31);
185  sstate->dcerpc.dcerpchdrudp.interfaceuuid[8] = *(p + 32);
186  sstate->dcerpc.dcerpchdrudp.interfaceuuid[9] = *(p + 33);
187  sstate->dcerpc.dcerpchdrudp.interfaceuuid[10] = *(p + 34);
188  sstate->dcerpc.dcerpchdrudp.interfaceuuid[11] = *(p + 35);
189  sstate->dcerpc.dcerpchdrudp.interfaceuuid[12] = *(p + 36);
190  sstate->dcerpc.dcerpchdrudp.interfaceuuid[13] = *(p + 37);
191  sstate->dcerpc.dcerpchdrudp.interfaceuuid[14] = *(p + 38);
192  sstate->dcerpc.dcerpchdrudp.interfaceuuid[15] = *(p + 39);
193  sstate->dcerpc.dcerpchdrudp.activityuuid[3] = *(p + 40);
194  sstate->dcerpc.dcerpchdrudp.activityuuid[2] = *(p + 41);
195  sstate->dcerpc.dcerpchdrudp.activityuuid[1] = *(p + 42);
196  sstate->dcerpc.dcerpchdrudp.activityuuid[0] = *(p + 43);
197  sstate->dcerpc.dcerpchdrudp.activityuuid[5] = *(p + 44);
198  sstate->dcerpc.dcerpchdrudp.activityuuid[4] = *(p + 45);
199  sstate->dcerpc.dcerpchdrudp.activityuuid[7] = *(p + 46);
200  sstate->dcerpc.dcerpchdrudp.activityuuid[6] = *(p + 47);
201  sstate->dcerpc.dcerpchdrudp.activityuuid[8] = *(p + 48);
202  sstate->dcerpc.dcerpchdrudp.activityuuid[9] = *(p + 49);
203  sstate->dcerpc.dcerpchdrudp.activityuuid[10] = *(p + 50);
204  sstate->dcerpc.dcerpchdrudp.activityuuid[11] = *(p + 51);
205  sstate->dcerpc.dcerpchdrudp.activityuuid[12] = *(p + 52);
206  sstate->dcerpc.dcerpchdrudp.activityuuid[13] = *(p + 53);
207  sstate->dcerpc.dcerpchdrudp.activityuuid[14] = *(p + 54);
208  sstate->dcerpc.dcerpchdrudp.activityuuid[15] = *(p + 55);
209  if (sstate->dcerpc.dcerpchdrudp.drep[0] == 0x10) {
210  sstate->dcerpc.dcerpchdrudp.server_boot = (uint32_t) *(p + 56);
211  sstate->dcerpc.dcerpchdrudp.server_boot |= (uint32_t) *(p + 57) << 8;
212  sstate->dcerpc.dcerpchdrudp.server_boot |= (uint32_t) *(p + 58) << 16;
213  sstate->dcerpc.dcerpchdrudp.server_boot |= (uint32_t) *(p + 59) << 24;
214  sstate->dcerpc.dcerpchdrudp.if_vers = (uint32_t) *(p + 60);
215  sstate->dcerpc.dcerpchdrudp.if_vers |= (uint32_t) *(p + 61) << 8;
216  sstate->dcerpc.dcerpchdrudp.if_vers |= (uint32_t) *(p + 62) << 16;
217  sstate->dcerpc.dcerpchdrudp.if_vers |= (uint32_t) *(p + 63) << 24;
218  sstate->dcerpc.dcerpchdrudp.seqnum = (uint32_t) *(p + 64);
219  sstate->dcerpc.dcerpchdrudp.seqnum |= (uint32_t) *(p + 65) << 8;
220  sstate->dcerpc.dcerpchdrudp.seqnum |= (uint32_t) *(p + 66) << 16;
221  sstate->dcerpc.dcerpchdrudp.seqnum |= (uint32_t) *(p + 67) << 24;
222  sstate->dcerpc.dcerpchdrudp.opnum = *(p + 68);
223  sstate->dcerpc.dcerpchdrudp.opnum |= *(p + 69) << 8;
224  sstate->dcerpc.dcerpchdrudp.ihint = *(p + 70);
225  sstate->dcerpc.dcerpchdrudp.ihint |= *(p + 71) << 8;
226  sstate->dcerpc.dcerpchdrudp.ahint = *(p + 72);
227  sstate->dcerpc.dcerpchdrudp.ahint |= *(p + 73) << 8;
228  sstate->dcerpc.dcerpchdrudp.fraglen = *(p + 74);
229  sstate->dcerpc.dcerpchdrudp.fraglen |= *(p + 75) << 8;
230  sstate->dcerpc.dcerpchdrudp.fragnum = *(p + 76);
231  sstate->dcerpc.dcerpchdrudp.fragnum |= *(p + 77) << 8;
232  } else {
233  sstate->dcerpc.dcerpchdrudp.server_boot = (uint32_t) *(p + 56) << 24;
234  sstate->dcerpc.dcerpchdrudp.server_boot |= (uint32_t) *(p + 57) << 16;
235  sstate->dcerpc.dcerpchdrudp.server_boot |= (uint32_t) *(p + 58) << 8;
236  sstate->dcerpc.dcerpchdrudp.server_boot |= (uint32_t) *(p + 59);
237  sstate->dcerpc.dcerpchdrudp.if_vers = (uint32_t) *(p + 60) << 24;
238  sstate->dcerpc.dcerpchdrudp.if_vers |= (uint32_t) *(p + 61) << 16;
239  sstate->dcerpc.dcerpchdrudp.if_vers |= (uint32_t) *(p + 62) << 8;
240  sstate->dcerpc.dcerpchdrudp.if_vers |= (uint32_t) *(p + 63);
241  sstate->dcerpc.dcerpchdrudp.seqnum = (uint32_t) *(p + 64) << 24;
242  sstate->dcerpc.dcerpchdrudp.seqnum |= (uint32_t) *(p + 65) << 16;
243  sstate->dcerpc.dcerpchdrudp.seqnum |= (uint32_t) *(p + 66) << 8;
244  sstate->dcerpc.dcerpchdrudp.seqnum |= (uint32_t) *(p + 67);
245  sstate->dcerpc.dcerpchdrudp.opnum = *(p + 68) << 8;
246  sstate->dcerpc.dcerpchdrudp.opnum |= *(p + 69);
247  sstate->dcerpc.dcerpchdrudp.ihint = *(p + 70) << 8;
248  sstate->dcerpc.dcerpchdrudp.ihint |= *(p + 71);
249  sstate->dcerpc.dcerpchdrudp.ahint = *(p + 72) << 8;
250  sstate->dcerpc.dcerpchdrudp.ahint |= *(p + 73);
251  sstate->dcerpc.dcerpchdrudp.fraglen = *(p + 74) << 8;
252  sstate->dcerpc.dcerpchdrudp.fraglen |= *(p + 75);
253  sstate->dcerpc.dcerpchdrudp.fragnum = *(p + 76) << 8;
254  sstate->dcerpc.dcerpchdrudp.fragnum |= *(p + 77);
255  }
256  sstate->fraglenleft = sstate->dcerpc.dcerpchdrudp.fraglen;
257  sstate->dcerpc.dcerpchdrudp.auth_proto = *(p + 78);
258  sstate->dcerpc.dcerpchdrudp.serial_lo = *(p + 79);
260  sstate->uuid_entry = (DCERPCUuidEntry *) SCCalloc(1,
261  sizeof(DCERPCUuidEntry));
262  if (sstate->uuid_entry == NULL) {
263  SCReturnUInt(-1);
264  } else {
265  memcpy(sstate->uuid_entry->uuid,
267  sizeof(sstate->dcerpc.dcerpchdrudp.activityuuid));
268  TAILQ_INSERT_HEAD(&sstate->uuid_list, sstate->uuid_entry,
269  next);
270 #ifdef UNITTESTS
271  if (RunmodeIsUnittests()) {
272  printUUID("DCERPC UDP", sstate->uuid_entry);
273 
274  }
275 #endif
276  }
277  SCReturnUInt(80);
278  break;
279  } else {
280  sstate->dcerpc.dcerpchdrudp.rpc_vers = *(p++);
281  if (sstate->dcerpc.dcerpchdrudp.rpc_vers != 4) {
282  SCLogDebug("DCERPC UDP Header did not validate");
283  SCReturnInt(-1);
284  }
285  if (!(--input_len))
286  break;
287  /* We fall through to the next case if we still have input.
288  * Same applies for other cases as well */
289  }
290  /* fall through */
291  case 1:
292  sstate->dcerpc.dcerpchdrudp.type = *(p++);
293  if (!(--input_len))
294  break;
295  /* fall through */
296  case 2:
297  sstate->dcerpc.dcerpchdrudp.flags1 = *(p++);
298  if (!(--input_len))
299  break;
300  /* fall through */
301  case 3:
302  sstate->dcerpc.dcerpchdrudp.flags2 = *(p++);
303  if (!(--input_len))
304  break;
305  /* fall through */
306  case 4:
307  sstate->dcerpc.dcerpchdrudp.drep[0] = *(p++);
308  if (!(--input_len))
309  break;
310  /* fall through */
311  case 5:
312  sstate->dcerpc.dcerpchdrudp.drep[1] = *(p++);
313  if (!(--input_len))
314  break;
315  /* fall through */
316  case 6:
317  sstate->dcerpc.dcerpchdrudp.drep[2] = *(p++);
318  if (!(--input_len))
319  break;
320  /* fall through */
321  case 7:
322  sstate->dcerpc.dcerpchdrudp.serial_hi = *(p++);
323  if (!(--input_len))
324  break;
325  /* fall through */
326  case 8:
327  sstate->dcerpc.dcerpchdrudp.objectuuid[3] = *(p++);
328  if (!(--input_len))
329  break;
330  /* fall through */
331  case 9:
332  sstate->dcerpc.dcerpchdrudp.objectuuid[2] = *(p++);
333  if (!(--input_len))
334  break;
335  /* fall through */
336  case 10:
337  sstate->dcerpc.dcerpchdrudp.objectuuid[1] = *(p++);
338  if (!(--input_len))
339  break;
340  /* fall through */
341  case 11:
342  sstate->dcerpc.dcerpchdrudp.objectuuid[0] = *(p++);
343  if (!(--input_len))
344  break;
345  /* fall through */
346  case 12:
347  sstate->dcerpc.dcerpchdrudp.objectuuid[5] = *(p++);
348  if (!(--input_len))
349  break;
350  /* fall through */
351  case 13:
352  sstate->dcerpc.dcerpchdrudp.objectuuid[4] = *(p++);
353  if (!(--input_len))
354  break;
355  /* fall through */
356  case 14:
357  sstate->dcerpc.dcerpchdrudp.objectuuid[7] = *(p++);
358  if (!(--input_len))
359  break;
360  /* fall through */
361  case 15:
362  sstate->dcerpc.dcerpchdrudp.objectuuid[6] = *(p++);
363  if (!(--input_len))
364  break;
365  /* fall through */
366  case 16:
367  sstate->dcerpc.dcerpchdrudp.objectuuid[8] = *(p++);
368  if (!(--input_len))
369  break;
370  /* fall through */
371  case 17:
372  sstate->dcerpc.dcerpchdrudp.objectuuid[9] = *(p++);
373  if (!(--input_len))
374  break;
375  /* fall through */
376  case 18:
377  sstate->dcerpc.dcerpchdrudp.objectuuid[10] = *(p++);
378  if (!(--input_len))
379  break;
380  /* fall through */
381  case 19:
382  sstate->dcerpc.dcerpchdrudp.objectuuid[11] = *(p++);
383  if (!(--input_len))
384  break;
385  /* fall through */
386  case 20:
387  sstate->dcerpc.dcerpchdrudp.objectuuid[12] = *(p++);
388  if (!(--input_len))
389  break;
390  /* fall through */
391  case 21:
392  sstate->dcerpc.dcerpchdrudp.objectuuid[13] = *(p++);
393  if (!(--input_len))
394  break;
395  /* fall through */
396  case 22:
397  sstate->dcerpc.dcerpchdrudp.objectuuid[14] = *(p++);
398  if (!(--input_len))
399  break;
400  /* fall through */
401  case 23:
402  sstate->dcerpc.dcerpchdrudp.objectuuid[15] = *(p++);
403  if (!(--input_len))
404  break;
405  /* fall through */
406  case 24:
407  sstate->dcerpc.dcerpchdrudp.interfaceuuid[3] = *(p++);
408  if (!(--input_len))
409  break;
410  /* fall through */
411  case 25:
412  sstate->dcerpc.dcerpchdrudp.interfaceuuid[2] = *(p++);
413  if (!(--input_len))
414  break;
415  /* fall through */
416  case 26:
417  sstate->dcerpc.dcerpchdrudp.interfaceuuid[1] = *(p++);
418  if (!(--input_len))
419  break;
420  /* fall through */
421  case 27:
422  sstate->dcerpc.dcerpchdrudp.interfaceuuid[0] = *(p++);
423  if (!(--input_len))
424  break;
425  /* fall through */
426  case 28:
427  sstate->dcerpc.dcerpchdrudp.interfaceuuid[5] = *(p++);
428  if (!(--input_len))
429  break;
430  /* fall through */
431  case 29:
432  sstate->dcerpc.dcerpchdrudp.interfaceuuid[4] = *(p++);
433  if (!(--input_len))
434  break;
435  /* fall through */
436  case 30:
437  sstate->dcerpc.dcerpchdrudp.interfaceuuid[7] = *(p++);
438  if (!(--input_len))
439  break;
440  /* fall through */
441  case 31:
442  sstate->dcerpc.dcerpchdrudp.interfaceuuid[6] = *(p++);
443  if (!(--input_len))
444  break;
445  /* fall through */
446  case 32:
447  sstate->dcerpc.dcerpchdrudp.interfaceuuid[8] = *(p++);
448  if (!(--input_len))
449  break;
450  /* fall through */
451  case 33:
452  sstate->dcerpc.dcerpchdrudp.interfaceuuid[9] = *(p++);
453  if (!(--input_len))
454  break;
455  /* fall through */
456  case 34:
457  sstate->dcerpc.dcerpchdrudp.interfaceuuid[10] = *(p++);
458  if (!(--input_len))
459  break;
460  /* fall through */
461  case 35:
462  sstate->dcerpc.dcerpchdrudp.interfaceuuid[11] = *(p++);
463  if (!(--input_len))
464  break;
465  /* fall through */
466  case 36:
467  sstate->dcerpc.dcerpchdrudp.interfaceuuid[12] = *(p++);
468  if (!(--input_len))
469  break;
470  /* fall through */
471  case 37:
472  sstate->dcerpc.dcerpchdrudp.interfaceuuid[13] = *(p++);
473  if (!(--input_len))
474  break;
475  /* fall through */
476  case 38:
477  sstate->dcerpc.dcerpchdrudp.interfaceuuid[14] = *(p++);
478  if (!(--input_len))
479  break;
480  /* fall through */
481  case 39:
482  sstate->dcerpc.dcerpchdrudp.interfaceuuid[15] = *(p++);
483  if (!(--input_len))
484  break;
485  /* fall through */
486  case 40:
487  sstate->dcerpc.dcerpchdrudp.activityuuid[3] = *(p++);
488  if (!(--input_len))
489  break;
490  /* fall through */
491  case 41:
492  sstate->dcerpc.dcerpchdrudp.activityuuid[2] = *(p++);
493  if (!(--input_len))
494  break;
495  /* fall through */
496  case 42:
497  sstate->dcerpc.dcerpchdrudp.activityuuid[1] = *(p++);
498  if (!(--input_len))
499  break;
500  /* fall through */
501  case 43:
502  sstate->dcerpc.dcerpchdrudp.activityuuid[0] = *(p++);
503  if (!(--input_len))
504  break;
505  /* fall through */
506  case 44:
507  sstate->dcerpc.dcerpchdrudp.activityuuid[5] = *(p++);
508  if (!(--input_len))
509  break;
510  /* fall through */
511  case 45:
512  sstate->dcerpc.dcerpchdrudp.activityuuid[4] = *(p++);
513  if (!(--input_len))
514  break;
515  /* fall through */
516  case 46:
517  sstate->dcerpc.dcerpchdrudp.activityuuid[7] = *(p++);
518  if (!(--input_len))
519  break;
520  /* fall through */
521  case 47:
522  sstate->dcerpc.dcerpchdrudp.activityuuid[6] = *(p++);
523  if (!(--input_len))
524  break;
525  /* fall through */
526  case 48:
527  sstate->dcerpc.dcerpchdrudp.activityuuid[8] = *(p++);
528  if (!(--input_len))
529  break;
530  /* fall through */
531  case 49:
532  sstate->dcerpc.dcerpchdrudp.activityuuid[9] = *(p++);
533  if (!(--input_len))
534  break;
535  /* fall through */
536  case 50:
537  sstate->dcerpc.dcerpchdrudp.activityuuid[10] = *(p++);
538  if (!(--input_len))
539  break;
540  /* fall through */
541  case 51:
542  sstate->dcerpc.dcerpchdrudp.activityuuid[11] = *(p++);
543  if (!(--input_len))
544  break;
545  /* fall through */
546  case 52:
547  sstate->dcerpc.dcerpchdrudp.activityuuid[12] = *(p++);
548  if (!(--input_len))
549  break;
550  /* fall through */
551  case 53:
552  sstate->dcerpc.dcerpchdrudp.activityuuid[13] = *(p++);
553  if (!(--input_len))
554  break;
555  /* fall through */
556  case 54:
557  sstate->dcerpc.dcerpchdrudp.activityuuid[14] = *(p++);
558  if (!(--input_len))
559  break;
560  /* fall through */
561  case 55:
562  sstate->dcerpc.dcerpchdrudp.activityuuid[15] = *(p++);
563  if (!(--input_len))
564  break;
565  /* fall through */
566  case 56:
567  sstate->dcerpc.dcerpchdrudp.server_boot = (uint32_t) *(p++);
568  if (!(--input_len))
569  break;
570  /* fall through */
571  case 57:
572  sstate->dcerpc.dcerpchdrudp.server_boot |= (uint32_t) *(p++) << 8;
573  if (!(--input_len))
574  break;
575  /* fall through */
576  case 58:
577  sstate->dcerpc.dcerpchdrudp.server_boot |= (uint32_t) *(p++) << 16;
578  if (!(--input_len))
579  break;
580  /* fall through */
581  case 59:
582  sstate->dcerpc.dcerpchdrudp.server_boot |= (uint32_t) *(p++) << 24;
583  if (!(--input_len))
584  break;
585  /* fall through */
586  case 60:
587  sstate->dcerpc.dcerpchdrudp.if_vers = (uint32_t) *(p++);
588  if (!(--input_len))
589  break;
590  /* fall through */
591  case 61:
592  sstate->dcerpc.dcerpchdrudp.if_vers |= (uint32_t) *(p++) << 8;
593  if (!(--input_len))
594  break;
595  /* fall through */
596  case 62:
597  sstate->dcerpc.dcerpchdrudp.if_vers |= (uint32_t) *(p++) << 16;
598  if (!(--input_len))
599  break;
600  /* fall through */
601  case 63:
602  sstate->dcerpc.dcerpchdrudp.if_vers |= (uint32_t) *(p++) << 24;
603  if (!(--input_len))
604  break;
605  /* fall through */
606  case 64:
607  sstate->dcerpc.dcerpchdrudp.seqnum = (uint32_t) *(p++);
608  if (!(--input_len))
609  break;
610  /* fall through */
611  case 65:
612  sstate->dcerpc.dcerpchdrudp.seqnum |= (uint32_t) *(p++) << 8;
613  if (!(--input_len))
614  break;
615  /* fall through */
616  case 66:
617  sstate->dcerpc.dcerpchdrudp.seqnum |= (uint32_t) *(p++) << 16;
618  if (!(--input_len))
619  break;
620  /* fall through */
621  case 67:
622  sstate->dcerpc.dcerpchdrudp.seqnum |= (uint32_t) *(p++) << 24;
623  if (!(--input_len))
624  break;
625  /* fall through */
626  case 68:
627  sstate->dcerpc.dcerpchdrudp.opnum = *(p++);
628  if (!(--input_len))
629  break;
630  /* fall through */
631  case 69:
632  sstate->dcerpc.dcerpchdrudp.opnum |= *(p++) << 8;
633  if (!(--input_len))
634  break;
635  /* fall through */
636  case 70:
637  sstate->dcerpc.dcerpchdrudp.ihint = *(p++);
638  if (!(--input_len))
639  break;
640  /* fall through */
641  case 71:
642  sstate->dcerpc.dcerpchdrudp.ihint |= *(p++) << 8;
643  if (!(--input_len))
644  break;
645  /* fall through */
646  case 72:
647  sstate->dcerpc.dcerpchdrudp.ahint = *(p++);
648  if (!(--input_len))
649  break;
650  /* fall through */
651  case 73:
652  sstate->dcerpc.dcerpchdrudp.ahint |= *(p++) << 8;
653  if (!(--input_len))
654  break;
655  /* fall through */
656  case 74:
657  sstate->dcerpc.dcerpchdrudp.fraglen = *(p++);
658  if (!(--input_len))
659  break;
660  /* fall through */
661  case 75:
662  sstate->dcerpc.dcerpchdrudp.fraglen |= *(p++) << 8;
663  if (!(--input_len))
664  break;
665  /* fall through */
666  case 76:
667  sstate->dcerpc.dcerpchdrudp.fragnum = *(p++);
668  if (!(--input_len))
669  break;
670  /* fall through */
671  case 77:
672  sstate->dcerpc.dcerpchdrudp.fragnum |= *(p++);
673  if (!(--input_len))
674  break;
675  /* fall through */
676  case 78:
677  sstate->dcerpc.dcerpchdrudp.auth_proto = *(p++);
678  if (!(--input_len))
679  break;
680  /* fall through */
681  case 79:
682  sstate->dcerpc.dcerpchdrudp.serial_lo = *(p++);
683  if (sstate->dcerpc.dcerpchdrudp.drep[0] != 0x10) {
692  }
693  sstate->fraglenleft = sstate->dcerpc.dcerpchdrudp.fraglen;
694  sstate->uuid_entry = (DCERPCUuidEntry *) SCCalloc(1,
695  sizeof(DCERPCUuidEntry));
696  if (sstate->uuid_entry == NULL) {
697  SCReturnUInt(-1);
698  } else {
699  memcpy(sstate->uuid_entry->uuid,
701  sizeof(sstate->dcerpc.dcerpchdrudp.activityuuid));
702  TAILQ_INSERT_HEAD(&sstate->uuid_list, sstate->uuid_entry,
703  next);
704 #ifdef UNITTESTS
705  if (RunmodeIsUnittests()) {
706  printUUID("DCERPC UDP", sstate->uuid_entry);
707  }
708 #endif
709  }
710  --input_len;
711  break;
712  }
713  }
714  sstate->bytesprocessed += (p - input);
715  SCReturnInt((p - input));
716 }
717 
718 static int DCERPCUDPParse(Flow *f, void *dcerpc_state,
719  AppLayerParserState *pstate, const uint8_t *input, uint32_t input_len,
720  void *local_data, const uint8_t flags)
721 {
722  uint32_t retval = 0;
723  uint32_t parsed = 0;
724  int hdrretval = 0;
725  SCEnter();
726 
727  if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
728  SCReturnInt(1);
729  } else if (input == NULL || input_len == 0) {
730  SCReturnInt(-1);
731  }
732 
733  DCERPCUDPState *sstate = (DCERPCUDPState *) dcerpc_state;
734  while (sstate->bytesprocessed < DCERPC_UDP_HDR_LEN && input_len) {
735  hdrretval = DCERPCUDPParseHeader(f, dcerpc_state, pstate, input,
736  input_len);
737  if (hdrretval == -1 || hdrretval > (int32_t)input_len) {
738  sstate->bytesprocessed = 0;
739  SCReturnInt(hdrretval);
740  } else {
741  parsed += hdrretval;
742  input_len -= hdrretval;
743  }
744  }
745 
746 #if 0
747  printf("Done with DCERPCUDPParseHeader bytesprocessed %u/%u left %u\n",
748  sstate->bytesprocessed, sstate->dcerpc.dcerpchdrudp.fraglen, input_len);
749  printf("\nDCERPC Version:\t%u\n", sstate->dcerpc.dcerpchdrudp.rpc_vers);
750  printf("DCERPC Type:\t%u\n", sstate->dcerpc.dcerpchdrudp.ptype);
751  printf("DCERPC Flags1:\t0x%02x\n", sstate->dcerpc.dcerpchdrudp.flags1);
752  printf("DCERPC Flags2:\t0x%02x\n", sstate->dcerpc.dcerpchdrudp.flags2);
753  printf("DCERPC Packed Drep:\t%02x %02x %02x\n",
754  sstate->dcerpc.dcerpchdrudp.drep[0], sstate->dcerpc.dcerpchdrudp.drep[1],
755  sstate->dcerpc.dcerpchdrudp.drep[2]);
756  printf("DCERPC Frag Length:\t0x%04x %u\n", sstate->dcerpc.dcerpchdrudp.fraglen,
757  sstate->dcerpc.dcerpchdrudp.fraglen);
758  printf("DCERPC Frag Number:\t0x%04x\n", sstate->dcerpc.dcerpchdrudp.fragnum);
759  printf("DCERPC OpNum:\t0x%04x\n", sstate->dcerpc.dcerpchdrudp.opnum);
760 #endif
761 
762  while (sstate->bytesprocessed >= DCERPC_UDP_HDR_LEN
763  && sstate->bytesprocessed < sstate->dcerpc.dcerpchdrudp.fraglen
764  && input_len) {
765  retval = FragmentDataParser(f, dcerpc_state, pstate, input + parsed,
766  input_len);
767  if (retval || retval > input_len) {
768  parsed += retval;
769  input_len -= retval;
770  } else if (input_len) {
771  SCLogDebug("Error parsing DCERPC UDP Fragment Data");
772  parsed -= input_len;
773  input_len = 0;
774  sstate->bytesprocessed = 0;
775  }
776  }
777 
778  if (sstate->bytesprocessed == sstate->dcerpc.dcerpchdrudp.fraglen) {
779  sstate->bytesprocessed = 0;
780  }
781  if (pstate == NULL)
782  SCReturnInt(-1);
783 
784  SCReturnInt(1);
785 }
786 
787 static void *DCERPCUDPStateAlloc(void)
788 {
789  void *s = SCMalloc(sizeof(DCERPCUDPState));
790  if (unlikely(s == NULL))
791  return NULL;
792 
793  memset(s, 0, sizeof(DCERPCUDPState));
794  return s;
795 }
796 
797 static void DCERPCUDPStateFree(void *s)
798 {
799  DCERPCUDPState *sstate = (DCERPCUDPState *) s;
800 
801  DCERPCUuidEntry *item;
802 
803  while ((item = TAILQ_FIRST(&sstate->uuid_list))) {
804  //printUUID("Free", item);
805  TAILQ_REMOVE(&sstate->uuid_list, item, next);
806  SCFree(item);
807  }
808  if (sstate->dcerpc.dcerpcrequest.stub_data_buffer != NULL) {
810  sstate->dcerpc.dcerpcrequest.stub_data_buffer = NULL;
812  }
813  if (sstate->dcerpc.dcerpcresponse.stub_data_buffer != NULL) {
815  sstate->dcerpc.dcerpcresponse.stub_data_buffer = NULL;
817  }
818 
819  if (sstate->de_state != NULL) {
821  }
822 
823  SCFree(s);
824 }
825 
826 static int DCERPCUDPSetTxDetectState(void *vtx, DetectEngineState *de_state)
827 {
828  DCERPCUDPState *dce_state = (DCERPCUDPState *)vtx;
829  dce_state->de_state = de_state;
830  return 0;
831 }
832 
833 static DetectEngineState *DCERPCUDPGetTxDetectState(void *vtx)
834 {
835  DCERPCUDPState *dce_state = (DCERPCUDPState *)vtx;
836  return dce_state->de_state;
837 }
838 
839 static void DCERPCUDPStateTransactionFree(void *state, uint64_t tx_id)
840 {
841  /* do nothing */
842 }
843 
844 static void *DCERPCUDPGetTx(void *state, uint64_t tx_id)
845 {
846  DCERPCUDPState *dce_state = (DCERPCUDPState *)state;
847  return dce_state;
848 }
849 
850 static uint64_t DCERPCUDPGetTxCnt(void *state)
851 {
852  /* single tx */
853  return 1;
854 }
855 
856 static int DCERPCUDPGetAlstateProgressCompletionStatus(uint8_t direction)
857 {
858  return 1;
859 }
860 
861 static int DCERPCUDPGetAlstateProgress(void *tx, uint8_t direction)
862 {
863  return 0;
864 }
865 
866 static int DCERPCUDPRegisterPatternsForProtocolDetection(void)
867 {
869  "|04 00|", 2, 0, STREAM_TOSERVER) < 0)
870  {
871  return -1;
872  }
873 
874  return 0;
875 }
876 
878 {
879  const char *proto_name = "dcerpc";
880 
881  if (AppLayerProtoDetectConfProtoDetectionEnabled("udp", proto_name)) {
883  if (DCERPCUDPRegisterPatternsForProtocolDetection() < 0)
884  return;
885  } else {
886  SCLogInfo("Protocol detection and parser disabled for %s protocol.",
887  "dcerpc");
888  return;
889  }
890 
891  if (AppLayerParserConfParserEnabled("udp", "dcerpc")) {
893  DCERPCUDPParse);
895  DCERPCUDPParse);
896  AppLayerParserRegisterStateFuncs(IPPROTO_UDP, ALPROTO_DCERPC, DCERPCUDPStateAlloc,
897  DCERPCUDPStateFree);
899 
900  AppLayerParserRegisterTxFreeFunc(IPPROTO_UDP, ALPROTO_DCERPC, DCERPCUDPStateTransactionFree);
901 
903  DCERPCUDPGetTxDetectState, DCERPCUDPSetTxDetectState);
904 
905  AppLayerParserRegisterGetTx(IPPROTO_UDP, ALPROTO_DCERPC, DCERPCUDPGetTx);
906 
907  AppLayerParserRegisterGetTxCnt(IPPROTO_UDP, ALPROTO_DCERPC, DCERPCUDPGetTxCnt);
908 
909  AppLayerParserRegisterGetStateProgressFunc(IPPROTO_UDP, ALPROTO_DCERPC, DCERPCUDPGetAlstateProgress);
910 
912  DCERPCUDPGetAlstateProgressCompletionStatus);
913  } else {
914  SCLogInfo("Parsed disabled for %s protocol. Protocol detection"
915  "still on.", "dcerpc");
916  }
917 #ifdef UNITTESTS
919 #endif
920 
921  return;
922 }
923 
924 /* UNITTESTS */
925 #ifdef UNITTESTS
926 /** \test DCERPC UDP Header Parsing and UUID handling
927  */
928 
929 static int DCERPCUDPParserTest01(void)
930 {
931  int result = 1;
932  Flow f;
933  uint8_t dcerpcrequest[] = {
934  0x04, 0x00, 0x2c, 0x00, 0x10, 0x00, 0x00, 0x00,
935  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
936  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
937  0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
938  0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
939  0x3f, 0x98, 0xf0, 0x5c, 0xd9, 0x63, 0xcc, 0x46,
940  0xc2, 0x74, 0x51, 0x6c, 0x8a, 0x53, 0x7d, 0x6f,
941  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
942  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xff, 0xff,
943  0xff, 0xff, 0x70, 0x05, 0x00, 0x00, 0x00, 0x00,
944  0x05, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
945  0x00, 0x00, 0x00, 0x00, 0x32, 0x24, 0x58, 0xfd,
946  0xcc, 0x45, 0x64, 0x49, 0xb0, 0x70, 0xdd, 0xae,
947  0x74, 0x2c, 0x96, 0xd2, 0x60, 0x5e, 0x0d, 0x00,
948  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
949  0x70, 0x5e, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x00,
950  0x7c, 0x5e, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
951  0x10, 0x00, 0x00, 0x00, 0x80, 0x96, 0xf1, 0xf1,
952  0x2a, 0x4d, 0xce, 0x11, 0xa6, 0x6a, 0x00, 0x20,
953  0xaf, 0x6e, 0x72, 0xf4, 0x0c, 0x00, 0x00, 0x00,
954  0x4d, 0x41, 0x52, 0x42, 0x01, 0x00, 0x00, 0x00,
955  0x00, 0x00, 0x00, 0x00, 0x0d, 0xf0, 0xad, 0xba,
956  0x00, 0x00, 0x00, 0x00, 0xa8, 0xf4, 0x0b, 0x00,
957  0x10, 0x09, 0x00, 0x00, 0x10, 0x09, 0x00, 0x00,
958  0x4d, 0x45, 0x4f, 0x57, 0x04, 0x00, 0x00, 0x00,
959  0xa2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
960  0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
961  0x38, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
962  0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
963  0x00, 0x00, 0x00, 0x00, 0xe0, 0x08, 0x00, 0x00,
964  0xd8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
965  0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
966  0xc8, 0x00, 0x00, 0x00, 0x4d, 0x45, 0x4f, 0x57,
967  0xd8, 0x08, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00,
968  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
969  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
970  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
971  0x00, 0x00, 0x00, 0x00, 0xc4, 0x28, 0xcd, 0x00,
972  0x64, 0x29, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00,
973  0x07, 0x00, 0x00, 0x00, 0xb9, 0x01, 0x00, 0x00,
974  0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
975  0x00, 0x00, 0x00, 0x46, 0xab, 0x01, 0x00, 0x00,
976  0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
977  0x00, 0x00, 0x00, 0x46, 0xa5, 0x01, 0x00, 0x00,
978  0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
979  0x00, 0x00, 0x00, 0x46, 0xa6, 0x01, 0x00, 0x00,
980  0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
981  0x00, 0x00, 0x00, 0x46, 0xa4, 0x01, 0x00, 0x00,
982  0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
983  0x00, 0x00, 0x00, 0x46, 0xad, 0x01, 0x00, 0x00,
984  0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
985  0x00, 0x00, 0x00, 0x46, 0xaa, 0x01, 0x00, 0x00,
986  0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
987  0x00, 0x00, 0x00, 0x46, 0x07, 0x00, 0x00, 0x00,
988  0x60, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
989  0x90, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
990  0x20, 0x00, 0x00, 0x00, 0x28, 0x06, 0x00, 0x00,
991  0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
992  0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
993  0x50, 0x00, 0x00, 0x00, 0x4f, 0xb6, 0x88, 0x20,
994  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
995  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
996  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
997  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
998  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
999  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1000  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1001  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1002  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1003  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1004  0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
1005  0x48, 0x00, 0x00, 0x00, 0x07, 0x00, 0x66, 0x00,
1006  0x06, 0x09, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
1007  0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
1008  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1009  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1010  0x00, 0x00, 0x00, 0x00, 0x78, 0x19, 0x0c, 0x00,
1011  0x58, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00,
1012  0x01, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x98, 0x93,
1013  0x98, 0x4f, 0xd2, 0x11, 0xa9, 0x3d, 0xbe, 0x57,
1014  0xb2, 0x00, 0x00, 0x00, 0x32, 0x00, 0x31, 0x00,
1015  0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
1016  0x80, 0x00, 0x00, 0x00, 0x0d, 0xf0, 0xad, 0xba,
1017  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1018  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1019  0x18, 0x43, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
1020  0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
1021  0x4d, 0x45, 0x4f, 0x57, 0x04, 0x00, 0x00, 0x00,
1022  0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1023  0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
1024  0x3b, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1025  0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
1026  0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
1027  0x01, 0x00, 0x01, 0x00, 0x81, 0xc5, 0x17, 0x03,
1028  0x80, 0x0e, 0xe9, 0x4a, 0x99, 0x99, 0xf1, 0x8a,
1029  0x50, 0x6f, 0x7a, 0x85, 0x02, 0x00, 0x00, 0x00,
1030  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1031  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1032  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1033  0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
1034  0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x6e, 0x00,
1035  0x00, 0x00, 0x00, 0x00, 0xd8, 0xda, 0x0d, 0x00,
1036  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1037  0x20, 0x2f, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
1038  0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1039  0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1040  0x46, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00,
1041  0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
1042  0x10, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2e, 0x00,
1043  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1044  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1045  0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
1046  0x68, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xff, 0xff,
1047  0x68, 0x8b, 0x0b, 0x00, 0x02, 0x00, 0x00, 0x00,
1048  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1049  0xfe, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1050  0xfe, 0x02, 0x00, 0x00, 0x5c, 0x00, 0x5c, 0x00,
1051  0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00,
1052  0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00,
1053  0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00,
1054  0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00,
1055  0x31, 0x00, 0x31, 0x00, 0x9d, 0x13, 0x00, 0x01,
1056  0xcc, 0xe0, 0xfd, 0x7f, 0xcc, 0xe0, 0xfd, 0x7f,
1057  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1058  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1059  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1060  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1061  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1062  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1063  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1064  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1065  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1066  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1067  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1068  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1069  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1070  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1071  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1072  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1073  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1074  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1075  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1076  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1077  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1078  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1079  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1080  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1081  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1082  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1083  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1084  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1085  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1086  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1087  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1088  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1089  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1090  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1091  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1092  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1093  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1094  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1095  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1096  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1097  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1098  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1099  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1100  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1101  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1102  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1103  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1104  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1105  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1106  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1107  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1108  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1109  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1110  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1111  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1112  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1113  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1114  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1115  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1116  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
1117  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
1118  uint32_t requestlen = sizeof(dcerpcrequest);
1119 
1120  TcpSession ssn;
1121  DCERPCUuidEntry *uuid_entry;
1123 
1124  memset(&f, 0, sizeof(f));
1125  memset(&ssn, 0, sizeof(ssn));
1126  FLOW_INITIALIZE(&f);
1127  f.protoctx = (void *)&ssn;
1128  f.proto = IPPROTO_UDP;
1130  f.alproto = ALPROTO_DCERPC;
1131 
1133 
1134  FLOWLOCK_WRLOCK(&f);
1135  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_DCERPC,
1137  dcerpcrequest,
1138  requestlen);
1139  if (r != 0) {
1140  printf("dcerpc header check returned %" PRId32 ", expected 0: ", r);
1141  result = 0;
1142  FLOWLOCK_UNLOCK(&f);
1143  goto end;
1144  }
1145  FLOWLOCK_UNLOCK(&f);
1146 
1147  DCERPCUDPState *dcerpc_state = f.alstate;
1148  if (dcerpc_state == NULL) {
1149  printf("no dcerpc state: ");
1150  result = 0;
1151  goto end;
1152  }
1153 
1154  if (dcerpc_state->dcerpc.dcerpchdrudp.rpc_vers != 4) {
1155  printf("expected dcerpc version 0x04, got 0x%02x : ",
1156  dcerpc_state->dcerpc.dcerpchdrudp.rpc_vers);
1157  result = 0;
1158  goto end;
1159  }
1160 
1161  if (dcerpc_state->dcerpc.dcerpchdrudp.fraglen != 1392) {
1162  printf("expected dcerpc fraglen 0x%02x , got 0x%02x : ", 1392, dcerpc_state->dcerpc.dcerpchdrudp.fraglen);
1163  result = 0;
1164  goto end;
1165  }
1166 
1167  if (dcerpc_state->dcerpc.dcerpchdrudp.opnum != 4) {
1168  printf("expected dcerpc opnum 0x%02x , got 0x%02x : ", 4, dcerpc_state->dcerpc.dcerpchdrudp.opnum);
1169  result = 0;
1170  goto end;
1171  }
1172 
1173  TAILQ_FOREACH(uuid_entry, &dcerpc_state->uuid_list, next) {
1174  printUUID("REQUEST", uuid_entry);
1175  }
1176 
1177 end:
1178  if (alp_tctx != NULL) {
1179  AppLayerParserThreadCtxFree(alp_tctx);
1180  }
1182  return result;
1183 }
1184 
1186 {
1187  UtRegisterTest("DCERPCUDPParserTest01", DCERPCUDPParserTest01);
1188 }
1189 #endif
uint16_t flags
#define SCLogDebug(...)
Definition: util-debug.h:335
DCERPCRequest dcerpcrequest
#define TAILQ_FIRST(head)
Definition: queue.h:339
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:350
struct HtpBodyChunk_ * next
DCERPCResponse dcerpcresponse
void AppLayerParserRegisterGetStateProgressFunc(uint8_t ipproto, AppProto alproto, int(*StateGetProgress)(void *alstate, uint8_t direction))
uint8_t proto
Definition: flow.h:344
#define FLOWLOCK_UNLOCK(fb)
Definition: flow.h:243
#define unlikely(expr)
Definition: util-optimize.h:35
int AppLayerProtoDetectConfProtoDetectionEnabled(const char *ipproto, const char *alproto)
Given a protocol name, checks if proto detection is enabled in the conf file.
int AppLayerParserStateIssetFlag(AppLayerParserState *pstate, uint8_t flag)
void AppLayerParserRegisterParserAcceptableDataDirection(uint8_t ipproto, AppProto alproto, uint8_t direction)
void AppLayerParserRegisterDetectStateFuncs(uint8_t ipproto, AppProto alproto, DetectEngineState *(*GetTxDetectState)(void *tx), int(*SetTxDetectState)(void *tx, DetectEngineState *))
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
uint8_t FlowGetProtoMapping(uint8_t proto)
Function to map the protocol to the defined FLOW_PROTO_* enumeration.
Definition: flow-util.c:95
#define SCReturnUInt(x)
Definition: util-debug.h:343
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:669
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:240
#define TRUE
void * protoctx
Definition: flow.h:400
int SCLogDebugEnabled(void)
Returns whether debug messages are enabled to be logged or not.
Definition: util-debug.c:624
void RegisterDCERPCUDPParsers(void)
void * alstate
Definition: flow.h:438
int AppLayerParserConfParserEnabled(const char *ipproto, const char *alproto_name)
check if a parser is enabled in the config Returns enabled always if: were running unittests and when...
#define SCCalloc(nm, a)
Definition: util-mem.h:253
int AppLayerParserRegisterParser(uint8_t ipproto, AppProto alproto, uint8_t direction, AppLayerParserFPtr Parser)
Register app layer parser for the protocol.
void AppLayerParserRegisterGetTx(uint8_t ipproto, AppProto alproto, void *(StateGetTx)(void *alstate, uint64_t tx_id))
void DCERPCUDPParserRegisterTests(void)
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:412
#define SCEnter(...)
Definition: util-debug.h:337
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
#define REQUEST
#define PFC_FIRST_FRAG
#define STREAM_TOCLIENT
Definition: stream.h:32
#define SCByteSwap32(x)
Definition: util-byte.h:70
void AppLayerParserRegisterGetStateProgressCompletionStatus(AppProto alproto, int(*StateGetProgressCompletionStatus)(uint8_t direction))
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol&#39;s parser thread context.
DCERPCUuidEntry * uuid_entry
void DetectEngineStateFree(DetectEngineState *state)
Frees a DetectEngineState object.
int RunmodeIsUnittests(void)
Definition: suricata.c:267
#define SCReturnInt(x)
Definition: util-debug.h:341
#define SCRealloc(x, a)
Definition: util-mem.h:238
DCERPCHdrUdp dcerpchdrudp
void printUUID(const char *type, DCERPCUuidEntry *uuid)
printUUID function used to print UUID, Major and Minor Version Number and if it was Accepted or Rejec...
#define SCMalloc(a)
Definition: util-mem.h:222
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:254
void AppLayerProtoDetectRegisterProtocol(AppProto alproto, const char *alproto_name)
Registers a protocol for protocol detection phase.
#define SCFree(a)
Definition: util-mem.h:322
DetectEngineState * de_state
#define TAILQ_INSERT_HEAD(head, elm, field)
Definition: queue.h:375
int AppLayerProtoDetectPMRegisterPatternCS(uint8_t ipproto, AppProto alproto, const char *pattern, uint16_t depth, uint16_t offset, uint8_t direction)
Registers a case-sensitive pattern for protocol detection.
uint16_t tx_id
void AppLayerParserRegisterProtocolUnittests(uint8_t ipproto, AppProto alproto, void(*RegisterUnittests)(void))
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
#define STREAM_START
Definition: stream.h:29
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
#define STREAM_TOSERVER
Definition: stream.h:31
#define DCERPC_UDP_HDR_LEN
#define APP_LAYER_PARSER_EOF
void AppLayerParserRegisterGetTxCnt(uint8_t ipproto, AppProto alproto, uint64_t(*StateGetTxCnt)(void *alstate))
void AppLayerParserRegisterStateFuncs(uint8_t ipproto, AppProto alproto, void *(*StateAlloc)(void), void(*StateFree)(void *))
AppProto alproto
application level protocol
Definition: flow.h:409
uint8_t protomap
Definition: flow.h:404
Flow data structure.
Definition: flow.h:325
#define SCByteSwap16(x)
Definition: util-byte.h:69
void AppLayerParserRegisterTxFreeFunc(uint8_t ipproto, AppProto alproto, void(*StateTransactionFree)(void *, uint64_t))