aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/suricata/src/app-layer-dcerpc-udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/suricata/src/app-layer-dcerpc-udp.c')
-rw-r--r--framework/src/suricata/src/app-layer-dcerpc-udp.c1115
1 files changed, 1115 insertions, 0 deletions
diff --git a/framework/src/suricata/src/app-layer-dcerpc-udp.c b/framework/src/suricata/src/app-layer-dcerpc-udp.c
new file mode 100644
index 00000000..58d714d0
--- /dev/null
+++ b/framework/src/suricata/src/app-layer-dcerpc-udp.c
@@ -0,0 +1,1115 @@
+/*
+ * Copyright (c) 2009, 2010 Open Information Security Foundation
+ *
+ * \author Kirby Kuehl <kkuehl@gmail.com>
+ *
+ * \todo Updated by AS: Inspect the possibilities of sending junk start at the
+ * start of udp session to avoid alproto detection.
+ */
+
+#include "suricata-common.h"
+#include "suricata.h"
+
+#include "debug.h"
+#include "decode.h"
+
+#include "flow-util.h"
+
+#include "threads.h"
+
+#include "util-print.h"
+#include "util-pool.h"
+#include "util-debug.h"
+
+#include "stream-tcp-private.h"
+#include "stream-tcp-reassemble.h"
+#include "stream-tcp.h"
+#include "stream.h"
+
+#include "app-layer-protos.h"
+#include "app-layer-parser.h"
+#include "app-layer.h"
+
+#include "util-spm.h"
+#include "util-unittest.h"
+
+#include "app-layer-dcerpc-udp.h"
+
+enum {
+ DCERPC_FIELD_NONE = 0,
+ DCERPC_PARSE_DCERPC_HEADER,
+ DCERPC_PARSE_DCERPC_BIND,
+ DCERPC_PARSE_DCERPC_BIND_ACK,
+ DCERPC_PARSE_DCERPC_REQUEST,
+ /* must be last */
+ DCERPC_FIELD_MAX,
+};
+
+/** \internal
+ * \retval stub_len or 0 in case of error */
+static uint32_t FragmentDataParser(Flow *f, void *dcerpcudp_state,
+ AppLayerParserState *pstate,
+ uint8_t *input, uint32_t input_len)
+{
+ SCEnter();
+ DCERPCUDPState *sstate = (DCERPCUDPState *) dcerpcudp_state;
+ uint8_t **stub_data_buffer = NULL;
+ uint32_t *stub_data_buffer_len = NULL;
+ uint8_t *stub_data_fresh = NULL;
+ uint16_t stub_len = 0;
+ void *ptmp;
+
+ /* request PDU. Retrieve the request stub buffer */
+ if (sstate->dcerpc.dcerpchdrudp.type == REQUEST) {
+ stub_data_buffer = &sstate->dcerpc.dcerpcrequest.stub_data_buffer;
+ stub_data_buffer_len = &sstate->dcerpc.dcerpcrequest.stub_data_buffer_len;
+ stub_data_fresh = &sstate->dcerpc.dcerpcrequest.stub_data_fresh;
+
+ /* response PDU. Retrieve the response stub buffer */
+ } else {
+ stub_data_buffer = &sstate->dcerpc.dcerpcresponse.stub_data_buffer;
+ stub_data_buffer_len = &sstate->dcerpc.dcerpcresponse.stub_data_buffer_len;
+ stub_data_fresh = &sstate->dcerpc.dcerpcresponse.stub_data_fresh;
+ }
+
+ stub_len = (sstate->dcerpc.fraglenleft < input_len) ? sstate->dcerpc.fraglenleft : input_len;
+
+ if (stub_len == 0) {
+ SCReturnUInt(0);
+ }
+ /* if the frag is the the first frag irrespective of it being a part of
+ * a multi frag PDU or not, it indicates the previous PDU's stub would
+ * have been buffered and processed and we can use the buffer to hold
+ * frags from a fresh request/response */
+ if (sstate->dcerpc.dcerpchdrudp.flags1 & PFC_FIRST_FRAG) {
+ *stub_data_buffer_len = 0;
+ }
+
+ ptmp = SCRealloc(*stub_data_buffer, *stub_data_buffer_len + stub_len);
+ if (ptmp == NULL) {
+ SCFree(*stub_data_buffer);
+ *stub_data_buffer = NULL;
+ SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
+ SCReturnUInt(0);
+ }
+
+ *stub_data_buffer = ptmp;
+ memcpy(*stub_data_buffer + *stub_data_buffer_len, input, stub_len);
+
+ *stub_data_fresh = 1;
+ /* length of the buffered stub */
+ *stub_data_buffer_len += stub_len;
+
+ sstate->dcerpc.fraglenleft -= stub_len;
+ sstate->dcerpc.bytesprocessed += stub_len;
+
+#ifdef DEBUG
+ if (SCLogDebugEnabled()) {
+ int i = 0;
+ for (i = 0; i < stub_len; i++) {
+ SCLogDebug("0x%02x ", input[i]);
+ }
+ }
+#endif
+
+ SCReturnUInt((uint32_t)stub_len);
+}
+
+/**
+ * \brief DCERPCParseHeader parses the 16 byte DCERPC header
+ * A fast path for normal decoding is used when there is enough bytes
+ * present to parse the entire header. A slow path is used to parse
+ * fragmented packets.
+ */
+static int DCERPCUDPParseHeader(Flow *f, void *dcerpcudp_state,
+ AppLayerParserState *pstate,
+ uint8_t *input, uint32_t input_len)
+{
+ SCEnter();
+ uint8_t *p = input;
+ DCERPCUDPState *sstate = (DCERPCUDPState *) dcerpcudp_state;
+ if (input_len) {
+ switch (sstate->bytesprocessed) {
+ case 0:
+ // fallthrough
+ /* above statement to prevent coverity FPs from the switch
+ * fall through */
+ if (input_len >= DCERPC_UDP_HDR_LEN) {
+ sstate->dcerpc.dcerpchdrudp.rpc_vers = *p;
+ if (sstate->dcerpc.dcerpchdrudp.rpc_vers != 4) {
+ SCLogDebug("DCERPC UDP Header did not validate");
+ SCReturnInt(-1);
+ }
+ sstate->dcerpc.dcerpchdrudp.type = *(p + 1);
+ sstate->dcerpc.dcerpchdrudp.flags1 = *(p + 2);
+ sstate->dcerpc.dcerpchdrudp.flags2 = *(p + 3);
+ sstate->dcerpc.dcerpchdrudp.drep[0] = *(p + 4);
+ sstate->dcerpc.dcerpchdrudp.drep[1] = *(p + 5);
+ sstate->dcerpc.dcerpchdrudp.drep[2] = *(p + 6);
+ sstate->dcerpc.dcerpchdrudp.serial_hi = *(p + 7);
+ sstate->dcerpc.dcerpchdrudp.objectuuid[3] = *(p + 8);
+ sstate->dcerpc.dcerpchdrudp.objectuuid[2] = *(p + 9);
+ sstate->dcerpc.dcerpchdrudp.objectuuid[1] = *(p + 10);
+ sstate->dcerpc.dcerpchdrudp.objectuuid[0] = *(p + 11);
+ sstate->dcerpc.dcerpchdrudp.objectuuid[5] = *(p + 12);
+ sstate->dcerpc.dcerpchdrudp.objectuuid[4] = *(p + 13);
+ sstate->dcerpc.dcerpchdrudp.objectuuid[7] = *(p + 14);
+ sstate->dcerpc.dcerpchdrudp.objectuuid[6] = *(p + 15);
+ sstate->dcerpc.dcerpchdrudp.objectuuid[8] = *(p + 16);
+ sstate->dcerpc.dcerpchdrudp.objectuuid[9] = *(p + 17);
+ sstate->dcerpc.dcerpchdrudp.objectuuid[10] = *(p + 18);
+ sstate->dcerpc.dcerpchdrudp.objectuuid[11] = *(p + 19);
+ sstate->dcerpc.dcerpchdrudp.objectuuid[12] = *(p + 20);
+ sstate->dcerpc.dcerpchdrudp.objectuuid[13] = *(p + 21);
+ sstate->dcerpc.dcerpchdrudp.objectuuid[14] = *(p + 22);
+ sstate->dcerpc.dcerpchdrudp.objectuuid[15] = *(p + 23);
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[3] = *(p + 24);
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[2] = *(p + 25);
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[1] = *(p + 26);
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[0] = *(p + 27);
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[5] = *(p + 28);
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[4] = *(p + 29);
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[7] = *(p + 30);
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[6] = *(p + 31);
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[8] = *(p + 32);
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[9] = *(p + 33);
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[10] = *(p + 34);
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[11] = *(p + 35);
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[12] = *(p + 36);
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[13] = *(p + 37);
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[14] = *(p + 38);
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[15] = *(p + 39);
+ sstate->dcerpc.dcerpchdrudp.activityuuid[3] = *(p + 40);
+ sstate->dcerpc.dcerpchdrudp.activityuuid[2] = *(p + 41);
+ sstate->dcerpc.dcerpchdrudp.activityuuid[1] = *(p + 42);
+ sstate->dcerpc.dcerpchdrudp.activityuuid[0] = *(p + 43);
+ sstate->dcerpc.dcerpchdrudp.activityuuid[5] = *(p + 44);
+ sstate->dcerpc.dcerpchdrudp.activityuuid[4] = *(p + 45);
+ sstate->dcerpc.dcerpchdrudp.activityuuid[7] = *(p + 46);
+ sstate->dcerpc.dcerpchdrudp.activityuuid[6] = *(p + 47);
+ sstate->dcerpc.dcerpchdrudp.activityuuid[8] = *(p + 48);
+ sstate->dcerpc.dcerpchdrudp.activityuuid[9] = *(p + 49);
+ sstate->dcerpc.dcerpchdrudp.activityuuid[10] = *(p + 50);
+ sstate->dcerpc.dcerpchdrudp.activityuuid[11] = *(p + 51);
+ sstate->dcerpc.dcerpchdrudp.activityuuid[12] = *(p + 52);
+ sstate->dcerpc.dcerpchdrudp.activityuuid[13] = *(p + 53);
+ sstate->dcerpc.dcerpchdrudp.activityuuid[14] = *(p + 54);
+ sstate->dcerpc.dcerpchdrudp.activityuuid[15] = *(p + 55);
+ if (sstate->dcerpc.dcerpchdrudp.drep[0] == 0x10) {
+ sstate->dcerpc.dcerpchdrudp.server_boot = *(p + 56);
+ sstate->dcerpc.dcerpchdrudp.server_boot |= *(p + 57) << 8;
+ sstate->dcerpc.dcerpchdrudp.server_boot |= *(p + 58) << 16;
+ sstate->dcerpc.dcerpchdrudp.server_boot |= *(p + 59) << 24;
+ sstate->dcerpc.dcerpchdrudp.if_vers = *(p + 60);
+ sstate->dcerpc.dcerpchdrudp.if_vers |= *(p + 61) << 8;
+ sstate->dcerpc.dcerpchdrudp.if_vers |= *(p + 62) << 16;
+ sstate->dcerpc.dcerpchdrudp.if_vers |= *(p + 63) << 24;
+ sstate->dcerpc.dcerpchdrudp.seqnum = *(p + 64);
+ sstate->dcerpc.dcerpchdrudp.seqnum |= *(p + 65) << 8;
+ sstate->dcerpc.dcerpchdrudp.seqnum |= *(p + 66) << 16;
+ sstate->dcerpc.dcerpchdrudp.seqnum |= *(p + 67) << 24;
+ sstate->dcerpc.dcerpchdrudp.opnum = *(p + 68);
+ sstate->dcerpc.dcerpchdrudp.opnum |= *(p + 69) << 8;
+ sstate->dcerpc.dcerpchdrudp.ihint = *(p + 70);
+ sstate->dcerpc.dcerpchdrudp.ihint |= *(p + 71) << 8;
+ sstate->dcerpc.dcerpchdrudp.ahint = *(p + 72);
+ sstate->dcerpc.dcerpchdrudp.ahint |= *(p + 73) << 8;
+ sstate->dcerpc.dcerpchdrudp.fraglen = *(p + 74);
+ sstate->dcerpc.dcerpchdrudp.fraglen |= *(p + 75) << 8;
+ sstate->dcerpc.dcerpchdrudp.fragnum = *(p + 76);
+ sstate->dcerpc.dcerpchdrudp.fragnum |= *(p + 77) << 8;
+ } else {
+ sstate->dcerpc.dcerpchdrudp.server_boot = *(p + 56) << 24;
+ sstate->dcerpc.dcerpchdrudp.server_boot |= *(p + 57) << 16;
+ sstate->dcerpc.dcerpchdrudp.server_boot |= *(p + 58) << 8;
+ sstate->dcerpc.dcerpchdrudp.server_boot |= *(p + 59);
+ sstate->dcerpc.dcerpchdrudp.if_vers = *(p + 60) << 24;
+ sstate->dcerpc.dcerpchdrudp.if_vers |= *(p + 61) << 16;
+ sstate->dcerpc.dcerpchdrudp.if_vers |= *(p + 62) << 8;
+ sstate->dcerpc.dcerpchdrudp.if_vers |= *(p + 63);
+ sstate->dcerpc.dcerpchdrudp.seqnum = *(p + 64) << 24;
+ sstate->dcerpc.dcerpchdrudp.seqnum |= *(p + 65) << 16;
+ sstate->dcerpc.dcerpchdrudp.seqnum |= *(p + 66) << 8;
+ sstate->dcerpc.dcerpchdrudp.seqnum |= *(p + 67);
+ sstate->dcerpc.dcerpchdrudp.opnum = *(p + 68) << 24;
+ sstate->dcerpc.dcerpchdrudp.opnum |= *(p + 69) << 16;
+ sstate->dcerpc.dcerpchdrudp.ihint = *(p + 70) << 8;
+ sstate->dcerpc.dcerpchdrudp.ihint |= *(p + 71);
+ sstate->dcerpc.dcerpchdrudp.ahint = *(p + 72) << 8;
+ sstate->dcerpc.dcerpchdrudp.ahint |= *(p + 73);
+ sstate->dcerpc.dcerpchdrudp.fraglen = *(p + 74) << 8;
+ sstate->dcerpc.dcerpchdrudp.fraglen |= *(p + 75);
+ sstate->dcerpc.dcerpchdrudp.fragnum = *(p + 76) << 8;
+ sstate->dcerpc.dcerpchdrudp.fragnum |= *(p + 77);
+ }
+ sstate->fraglenleft = sstate->dcerpc.dcerpchdrudp.fraglen;
+ sstate->dcerpc.dcerpchdrudp.auth_proto = *(p + 78);
+ sstate->dcerpc.dcerpchdrudp.serial_lo = *(p + 79);
+ sstate->bytesprocessed = DCERPC_UDP_HDR_LEN;
+ sstate->uuid_entry = (DCERPCUuidEntry *) SCCalloc(1,
+ sizeof(DCERPCUuidEntry));
+ if (sstate->uuid_entry == NULL) {
+ SCReturnUInt(-1);
+ } else {
+ memcpy(sstate->uuid_entry->uuid,
+ sstate->dcerpc.dcerpchdrudp.activityuuid,
+ sizeof(sstate->dcerpc.dcerpchdrudp.activityuuid));
+ TAILQ_INSERT_HEAD(&sstate->uuid_list, sstate->uuid_entry,
+ next);
+#ifdef UNITTESTS
+ if (RunmodeIsUnittests()) {
+ printUUID("DCERPC UDP", sstate->uuid_entry);
+
+ }
+#endif
+ }
+ SCReturnUInt(80);
+ break;
+ } else {
+ sstate->dcerpc.dcerpchdrudp.rpc_vers = *(p++);
+ if (sstate->dcerpc.dcerpchdrudp.rpc_vers != 4) {
+ SCLogDebug("DCERPC UDP Header did not validate");
+ SCReturnInt(-1);
+ }
+ if (!(--input_len))
+ break;
+ /* We fall through to the next case if we still have input.
+ * Same applies for other cases as well */
+ }
+ /* fall through */
+ case 1:
+ sstate->dcerpc.dcerpchdrudp.type = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 2:
+ sstate->dcerpc.dcerpchdrudp.flags1 = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 3:
+ sstate->dcerpc.dcerpchdrudp.flags2 = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 4:
+ sstate->dcerpc.dcerpchdrudp.drep[0] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 5:
+ sstate->dcerpc.dcerpchdrudp.drep[1] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 6:
+ sstate->dcerpc.dcerpchdrudp.drep[2] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 7:
+ sstate->dcerpc.dcerpchdrudp.serial_hi = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 8:
+ sstate->dcerpc.dcerpchdrudp.objectuuid[3] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 9:
+ sstate->dcerpc.dcerpchdrudp.objectuuid[2] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 10:
+ sstate->dcerpc.dcerpchdrudp.objectuuid[1] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 11:
+ sstate->dcerpc.dcerpchdrudp.objectuuid[0] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 12:
+ sstate->dcerpc.dcerpchdrudp.objectuuid[5] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 13:
+ sstate->dcerpc.dcerpchdrudp.objectuuid[4] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 14:
+ sstate->dcerpc.dcerpchdrudp.objectuuid[7] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 15:
+ sstate->dcerpc.dcerpchdrudp.objectuuid[6] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 16:
+ sstate->dcerpc.dcerpchdrudp.objectuuid[8] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 17:
+ sstate->dcerpc.dcerpchdrudp.objectuuid[9] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 18:
+ sstate->dcerpc.dcerpchdrudp.objectuuid[10] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 19:
+ sstate->dcerpc.dcerpchdrudp.objectuuid[11] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 20:
+ sstate->dcerpc.dcerpchdrudp.objectuuid[12] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 21:
+ sstate->dcerpc.dcerpchdrudp.objectuuid[13] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 22:
+ sstate->dcerpc.dcerpchdrudp.objectuuid[14] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 23:
+ sstate->dcerpc.dcerpchdrudp.objectuuid[15] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 24:
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[3] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 25:
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[2] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 26:
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[1] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 27:
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[0] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 28:
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[5] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 29:
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[4] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 30:
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[7] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 31:
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[6] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 32:
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[8] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 33:
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[9] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 34:
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[10] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 35:
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[11] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 36:
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[12] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 37:
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[13] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 38:
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[14] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 39:
+ sstate->dcerpc.dcerpchdrudp.interfaceuuid[15] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 40:
+ sstate->dcerpc.dcerpchdrudp.activityuuid[3] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 41:
+ sstate->dcerpc.dcerpchdrudp.activityuuid[2] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 42:
+ sstate->dcerpc.dcerpchdrudp.activityuuid[1] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 43:
+ sstate->dcerpc.dcerpchdrudp.activityuuid[0] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 44:
+ sstate->dcerpc.dcerpchdrudp.activityuuid[5] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 45:
+ sstate->dcerpc.dcerpchdrudp.activityuuid[4] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 46:
+ sstate->dcerpc.dcerpchdrudp.activityuuid[7] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 47:
+ sstate->dcerpc.dcerpchdrudp.activityuuid[6] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 48:
+ sstate->dcerpc.dcerpchdrudp.activityuuid[8] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 49:
+ sstate->dcerpc.dcerpchdrudp.activityuuid[9] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 50:
+ sstate->dcerpc.dcerpchdrudp.activityuuid[10] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 51:
+ sstate->dcerpc.dcerpchdrudp.activityuuid[11] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 52:
+ sstate->dcerpc.dcerpchdrudp.activityuuid[12] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 53:
+ sstate->dcerpc.dcerpchdrudp.activityuuid[13] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 54:
+ sstate->dcerpc.dcerpchdrudp.activityuuid[14] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 55:
+ sstate->dcerpc.dcerpchdrudp.activityuuid[15] = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 56:
+ sstate->dcerpc.dcerpchdrudp.server_boot = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 57:
+ sstate->dcerpc.dcerpchdrudp.server_boot |= *(p++) << 8;
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 58:
+ sstate->dcerpc.dcerpchdrudp.server_boot |= *(p++) << 16;
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 59:
+ sstate->dcerpc.dcerpchdrudp.server_boot |= *(p++) << 24;
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 60:
+ sstate->dcerpc.dcerpchdrudp.if_vers = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 61:
+ sstate->dcerpc.dcerpchdrudp.if_vers |= *(p++) << 8;
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 62:
+ sstate->dcerpc.dcerpchdrudp.if_vers |= *(p++) << 16;
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 63:
+ sstate->dcerpc.dcerpchdrudp.if_vers |= *(p++) << 24;
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 64:
+ sstate->dcerpc.dcerpchdrudp.seqnum = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 65:
+ sstate->dcerpc.dcerpchdrudp.seqnum |= *(p++) << 8;
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 66:
+ sstate->dcerpc.dcerpchdrudp.seqnum |= *(p++) << 16;
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 67:
+ sstate->dcerpc.dcerpchdrudp.seqnum |= *(p++) << 24;
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 68:
+ sstate->dcerpc.dcerpchdrudp.opnum = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 69:
+ sstate->dcerpc.dcerpchdrudp.opnum |= *(p++) << 8;
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 70:
+ sstate->dcerpc.dcerpchdrudp.ihint = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 71:
+ sstate->dcerpc.dcerpchdrudp.ihint |= *(p++) << 8;
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 72:
+ sstate->dcerpc.dcerpchdrudp.ahint = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 73:
+ sstate->dcerpc.dcerpchdrudp.ahint |= *(p++) << 8;
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 74:
+ sstate->dcerpc.dcerpchdrudp.fraglen = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 75:
+ sstate->dcerpc.dcerpchdrudp.fraglen |= *(p++) << 8;
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 76:
+ sstate->dcerpc.dcerpchdrudp.fragnum = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 77:
+ sstate->dcerpc.dcerpchdrudp.fragnum |= *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 78:
+ sstate->dcerpc.dcerpchdrudp.auth_proto = *(p++);
+ if (!(--input_len))
+ break;
+ /* fall through */
+ case 79:
+ sstate->dcerpc.dcerpchdrudp.serial_lo = *(p++);
+ if (sstate->dcerpc.dcerpchdrudp.drep[0] != 0x10) {
+ sstate->dcerpc.dcerpchdrudp.server_boot = SCByteSwap32(sstate->dcerpc.dcerpchdrudp.server_boot);
+ sstate->dcerpc.dcerpchdrudp.if_vers= SCByteSwap32(sstate->dcerpc.dcerpchdrudp.if_vers);
+ sstate->dcerpc.dcerpchdrudp.seqnum= SCByteSwap32(sstate->dcerpc.dcerpchdrudp.seqnum);
+ sstate->dcerpc.dcerpchdrudp.opnum = SCByteSwap16(sstate->dcerpc.dcerpchdrudp.opnum);
+ sstate->dcerpc.dcerpchdrudp.ihint= SCByteSwap16(sstate->dcerpc.dcerpchdrudp.ihint);
+ sstate->dcerpc.dcerpchdrudp.ahint = SCByteSwap16(sstate->dcerpc.dcerpchdrudp.ahint);
+ sstate->dcerpc.dcerpchdrudp.fraglen = SCByteSwap16(sstate->dcerpc.dcerpchdrudp.fraglen);
+ sstate->dcerpc.dcerpchdrudp.fragnum = SCByteSwap16(sstate->dcerpc.dcerpchdrudp.fragnum);
+ }
+ sstate->fraglenleft = sstate->dcerpc.dcerpchdrudp.fraglen;
+ sstate->uuid_entry = (DCERPCUuidEntry *) SCCalloc(1,
+ sizeof(DCERPCUuidEntry));
+ if (sstate->uuid_entry == NULL) {
+ SCReturnUInt(-1);
+ } else {
+ memcpy(sstate->uuid_entry->uuid,
+ sstate->dcerpc.dcerpchdrudp.activityuuid,
+ sizeof(sstate->dcerpc.dcerpchdrudp.activityuuid));
+ TAILQ_INSERT_HEAD(&sstate->uuid_list, sstate->uuid_entry,
+ next);
+#ifdef UNITTESTS
+ if (RunmodeIsUnittests()) {
+ printUUID("DCERPC UDP", sstate->uuid_entry);
+ }
+#endif
+ }
+ --input_len;
+ break;
+ }
+ }
+ sstate->bytesprocessed += (p - input);
+ SCReturnInt((p - input));
+}
+
+static int DCERPCUDPParse(Flow *f, void *dcerpc_state,
+ AppLayerParserState *pstate,
+ uint8_t *input, uint32_t input_len,
+ void *local_data)
+{
+ uint32_t retval = 0;
+ uint32_t parsed = 0;
+ int hdrretval = 0;
+ SCEnter();
+
+ if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+ SCReturnInt(1);
+ } else if (input == NULL || input_len == 0) {
+ SCReturnInt(-1);
+ }
+
+ DCERPCUDPState *sstate = (DCERPCUDPState *) dcerpc_state;
+ while (sstate->bytesprocessed < DCERPC_UDP_HDR_LEN && input_len) {
+ hdrretval = DCERPCUDPParseHeader(f, dcerpc_state, pstate, input,
+ input_len);
+ if (hdrretval == -1 || hdrretval > (int32_t)input_len) {
+ sstate->bytesprocessed = 0;
+ SCReturnInt(hdrretval);
+ } else {
+ parsed += hdrretval;
+ input_len -= hdrretval;
+ }
+ }
+
+#if 0
+ printf("Done with DCERPCUDPParseHeader bytesprocessed %u/%u left %u\n",
+ sstate->bytesprocessed, sstate->dcerpc.dcerpchdrudp.fraglen, input_len);
+ printf("\nDCERPC Version:\t%u\n", sstate->dcerpc.dcerpchdrudp.rpc_vers);
+ printf("DCERPC Type:\t%u\n", sstate->dcerpc.dcerpchdrudp.ptype);
+ printf("DCERPC Flags1:\t0x%02x\n", sstate->dcerpc.dcerpchdrudp.flags1);
+ printf("DCERPC Flags2:\t0x%02x\n", sstate->dcerpc.dcerpchdrudp.flags2);
+ printf("DCERPC Packed Drep:\t%02x %02x %02x\n",
+ sstate->dcerpc.dcerpchdrudp.drep[0], sstate->dcerpc.dcerpchdrudp.drep[1],
+ sstate->dcerpc.dcerpchdrudp.drep[2]);
+ printf("DCERPC Frag Length:\t0x%04x %u\n", sstate->dcerpc.dcerpchdrudp.fraglen,
+ sstate->dcerpc.dcerpchdrudp.fraglen);
+ printf("DCERPC Frag Number:\t0x%04x\n", sstate->dcerpc.dcerpchdrudp.fragnum);
+ printf("DCERPC OpNum:\t0x%04x\n", sstate->dcerpc.dcerpchdrudp.opnum);
+#endif
+
+ while (sstate->bytesprocessed >= DCERPC_UDP_HDR_LEN
+ && sstate->bytesprocessed < sstate->dcerpc.dcerpchdrudp.fraglen
+ && input_len) {
+ retval = FragmentDataParser(f, dcerpc_state, pstate, input + parsed,
+ input_len);
+ if (retval || retval > input_len) {
+ parsed += retval;
+ input_len -= retval;
+ } else if (input_len) {
+ SCLogDebug("Error parsing DCERPC UDP Fragment Data");
+ parsed -= input_len;
+ input_len = 0;
+ sstate->bytesprocessed = 0;
+ }
+ }
+
+ if (sstate->bytesprocessed == sstate->dcerpc.dcerpchdrudp.fraglen) {
+ sstate->bytesprocessed = 0;
+ }
+ if (pstate == NULL)
+ SCReturnInt(-1);
+
+ SCReturnInt(1);
+}
+
+static void *DCERPCUDPStateAlloc(void)
+{
+ void *s = SCMalloc(sizeof(DCERPCUDPState));
+ if (unlikely(s == NULL))
+ return NULL;
+
+ memset(s, 0, sizeof(DCERPCUDPState));
+ return s;
+}
+
+static void DCERPCUDPStateFree(void *s)
+{
+ DCERPCUDPState *sstate = (DCERPCUDPState *) s;
+
+ DCERPCUuidEntry *item;
+
+ while ((item = TAILQ_FIRST(&sstate->uuid_list))) {
+ //printUUID("Free", item);
+ TAILQ_REMOVE(&sstate->uuid_list, item, next);
+ SCFree(item);
+ }
+ if (sstate->dcerpc.dcerpcrequest.stub_data_buffer != NULL) {
+ SCFree(sstate->dcerpc.dcerpcrequest.stub_data_buffer);
+ sstate->dcerpc.dcerpcrequest.stub_data_buffer = NULL;
+ sstate->dcerpc.dcerpcrequest.stub_data_buffer_len = 0;
+ }
+ if (sstate->dcerpc.dcerpcresponse.stub_data_buffer != NULL) {
+ SCFree(sstate->dcerpc.dcerpcresponse.stub_data_buffer);
+ sstate->dcerpc.dcerpcresponse.stub_data_buffer = NULL;
+ sstate->dcerpc.dcerpcresponse.stub_data_buffer_len = 0;
+ }
+ SCFree(s);
+}
+
+static int DCERPCUDPRegisterPatternsForProtocolDetection(void)
+{
+ if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_DCERPC,
+ "|04 00|", 2, 0, STREAM_TOSERVER) < 0)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+void RegisterDCERPCUDPParsers(void)
+{
+ char *proto_name = "dcerpc";
+
+ if (AppLayerProtoDetectConfProtoDetectionEnabled("udp", proto_name)) {
+ AppLayerProtoDetectRegisterProtocol(ALPROTO_DCERPC, proto_name);
+ if (DCERPCUDPRegisterPatternsForProtocolDetection() < 0)
+ return;
+ } else {
+ SCLogInfo("Protocol detection and parser disabled for %s protocol.",
+ "dcerpc");
+ return;
+ }
+
+ if (AppLayerParserConfParserEnabled("udp", "dcerpc")) {
+ AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_DCERPC, STREAM_TOSERVER,
+ DCERPCUDPParse);
+ AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_DCERPC, STREAM_TOCLIENT,
+ DCERPCUDPParse);
+ AppLayerParserRegisterStateFuncs(IPPROTO_UDP, ALPROTO_DCERPC, DCERPCUDPStateAlloc,
+ DCERPCUDPStateFree);
+ AppLayerParserRegisterParserAcceptableDataDirection(IPPROTO_UDP, ALPROTO_DCERPC, STREAM_TOSERVER);
+ } else {
+ SCLogInfo("Parsed disabled for %s protocol. Protocol detection"
+ "still on.", "dcerpc");
+ }
+#ifdef UNITTESTS
+ AppLayerParserRegisterProtocolUnittests(IPPROTO_UDP, ALPROTO_DCERPC, DCERPCUDPParserRegisterTests);
+#endif
+
+ return;
+}
+
+/* UNITTESTS */
+#ifdef UNITTESTS
+/** \test DCERPC UDP Header Parsing and UUID handling
+ */
+
+int DCERPCUDPParserTest01(void)
+{
+ int result = 1;
+ Flow f;
+ uint8_t dcerpcrequest[] = {
+ 0x04, 0x00, 0x2c, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x3f, 0x98, 0xf0, 0x5c, 0xd9, 0x63, 0xcc, 0x46,
+ 0xc2, 0x74, 0x51, 0x6c, 0x8a, 0x53, 0x7d, 0x6f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0x70, 0x05, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x32, 0x24, 0x58, 0xfd,
+ 0xcc, 0x45, 0x64, 0x49, 0xb0, 0x70, 0xdd, 0xae,
+ 0x74, 0x2c, 0x96, 0xd2, 0x60, 0x5e, 0x0d, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x70, 0x5e, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x7c, 0x5e, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x80, 0x96, 0xf1, 0xf1,
+ 0x2a, 0x4d, 0xce, 0x11, 0xa6, 0x6a, 0x00, 0x20,
+ 0xaf, 0x6e, 0x72, 0xf4, 0x0c, 0x00, 0x00, 0x00,
+ 0x4d, 0x41, 0x52, 0x42, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0d, 0xf0, 0xad, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0xa8, 0xf4, 0x0b, 0x00,
+ 0x10, 0x09, 0x00, 0x00, 0x10, 0x09, 0x00, 0x00,
+ 0x4d, 0x45, 0x4f, 0x57, 0x04, 0x00, 0x00, 0x00,
+ 0xa2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x38, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x00, 0x00, 0x00, 0x00, 0xe0, 0x08, 0x00, 0x00,
+ 0xd8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
+ 0xc8, 0x00, 0x00, 0x00, 0x4d, 0x45, 0x4f, 0x57,
+ 0xd8, 0x08, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc4, 0x28, 0xcd, 0x00,
+ 0x64, 0x29, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x07, 0x00, 0x00, 0x00, 0xb9, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0xab, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0xa5, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0xa6, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0xa4, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0xad, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0xaa, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x07, 0x00, 0x00, 0x00,
+ 0x60, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
+ 0x90, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x28, 0x06, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
+ 0x50, 0x00, 0x00, 0x00, 0x4f, 0xb6, 0x88, 0x20,
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
+ 0x48, 0x00, 0x00, 0x00, 0x07, 0x00, 0x66, 0x00,
+ 0x06, 0x09, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x78, 0x19, 0x0c, 0x00,
+ 0x58, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x98, 0x93,
+ 0x98, 0x4f, 0xd2, 0x11, 0xa9, 0x3d, 0xbe, 0x57,
+ 0xb2, 0x00, 0x00, 0x00, 0x32, 0x00, 0x31, 0x00,
+ 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
+ 0x80, 0x00, 0x00, 0x00, 0x0d, 0xf0, 0xad, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x43, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
+ 0x4d, 0x45, 0x4f, 0x57, 0x04, 0x00, 0x00, 0x00,
+ 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x3b, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x01, 0x00, 0x81, 0xc5, 0x17, 0x03,
+ 0x80, 0x0e, 0xe9, 0x4a, 0x99, 0x99, 0xf1, 0x8a,
+ 0x50, 0x6f, 0x7a, 0x85, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
+ 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x6e, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xd8, 0xda, 0x0d, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x2f, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x46, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
+ 0x10, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2e, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
+ 0x68, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xff, 0xff,
+ 0x68, 0x8b, 0x0b, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xfe, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xfe, 0x02, 0x00, 0x00, 0x5c, 0x00, 0x5c, 0x00,
+ 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00,
+ 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00,
+ 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00,
+ 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00,
+ 0x31, 0x00, 0x31, 0x00, 0x9d, 0x13, 0x00, 0x01,
+ 0xcc, 0xe0, 0xfd, 0x7f, 0xcc, 0xe0, 0xfd, 0x7f,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
+ uint32_t requestlen = sizeof(dcerpcrequest);
+
+ TcpSession ssn;
+ DCERPCUuidEntry *uuid_entry;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&f, 0, sizeof(f));
+ memset(&ssn, 0, sizeof(ssn));
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_UDP;
+ f.protomap = FlowGetProtoMapping(f.proto);
+
+ StreamTcpInitConfig(TRUE);
+
+ SCMutexLock(&f.m);
+ int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER|STREAM_START, dcerpcrequest, requestlen);
+ if (r != 0) {
+ printf("dcerpc header check returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ DCERPCUDPState *dcerpc_state = f.alstate;
+ if (dcerpc_state == NULL) {
+ printf("no dcerpc state: ");
+ result = 0;
+ goto end;
+ }
+
+ if (dcerpc_state->dcerpc.dcerpchdrudp.rpc_vers != 4) {
+ printf("expected dcerpc version 0x04, got 0x%02x : ",
+ dcerpc_state->dcerpc.dcerpchdrudp.rpc_vers);
+ result = 0;
+ goto end;
+ }
+
+ if (dcerpc_state->dcerpc.dcerpchdrudp.fraglen != 1392) {
+ printf("expected dcerpc fraglen 0x%02x , got 0x%02x : ", 1392, dcerpc_state->dcerpc.dcerpchdrudp.fraglen);
+ result = 0;
+ goto end;
+ }
+
+ if (dcerpc_state->dcerpc.dcerpchdrudp.opnum != 4) {
+ printf("expected dcerpc opnum 0x%02x , got 0x%02x : ", 4, dcerpc_state->dcerpc.dcerpchdrudp.opnum);
+ result = 0;
+ goto end;
+ }
+
+ TAILQ_FOREACH(uuid_entry, &dcerpc_state->uuid_list, next) {
+ printUUID("REQUEST", uuid_entry);
+ }
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ StreamTcpFreeConfig(TRUE);
+ return result;
+}
+
+void DCERPCUDPParserRegisterTests(void)
+{
+ UtRegisterTest("DCERPCUDPParserTest01", DCERPCUDPParserTest01, 1);
+}
+#endif