diff options
author | Ashlee Young <ashlee@onosfw.com> | 2015-09-09 22:21:41 -0700 |
---|---|---|
committer | Ashlee Young <ashlee@onosfw.com> | 2015-09-09 22:21:41 -0700 |
commit | 8879b125d26e8db1a5633de5a9c692eb2d1c4f83 (patch) | |
tree | c7259d85a991b83dfa85ab2e339360669fc1f58e /framework/src/suricata/src/app-layer-dcerpc-udp.c | |
parent | 13d05bc8458758ee39cb829098241e89616717ee (diff) |
suricata checkin based on commit id a4bce14770beee46a537eda3c3f6e8e8565d5d0a
Change-Id: I9a214fa0ee95e58fc640e50bd604dac7f42db48f
Diffstat (limited to 'framework/src/suricata/src/app-layer-dcerpc-udp.c')
-rw-r--r-- | framework/src/suricata/src/app-layer-dcerpc-udp.c | 1115 |
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 |