From Stefan Metzmacher:
[obnox/wireshark/wip.git] / epan / dissectors / packet-dcerpc.c
index 8c32bfbf51de1f0fc74f8dcb4400e6f814bc3d98..14b852147d7a38b381917bd458e96d449f84cb17 100644 (file)
@@ -5,8 +5,8 @@
  *
  * $Id$
  *
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
  * This program is free software; you can redistribute it and/or
 #include <epan/dissectors/packet-frame.h>
 #include <epan/dissectors/packet-dcerpc-nt.h>
 #include <epan/expert.h>
-
-#ifdef _WIN32
-#include <tchar.h>
-#endif
-
-#ifndef MIN
-#define MIN(x,y) ((x)<(y))?(x):(y)
-#endif
+#include <epan/strutil.h>
 
 static int dcerpc_tap = -1;
 
@@ -307,11 +300,14 @@ static const value_string reject_status_vals[] = {
        { 0x80004001, "E_NOTIMPL" },
        { 0x80004003, "E_POINTER" },
        { 0x80004004, "E_ABORT" },
+       { 0x8000FFFF, "E_UNEXPECTED" },
        { 0x80010105, "RPC_E_SERVERFAULT" },
        { 0x80010108, "RPC_E_DISCONNECTED" },
        { 0x80010113, "RPC_E_INVALID_IPID" },
        { 0x8001011F, "RPC_E_TIMEOUT" },
+       { 0x80020003, "DISP_E_MEMBERNOTFOUND" },
        { 0x80020006, "DISP_E_UNKNOWNNAME" },
+       { 0x8002000E, "DISP_E_BADPARAMCOUNT" },
        { 0x8004CB00, "CBA_E_MALFORMED" },
        { 0x8004CB01, "CBA_E_UNKNOWNOBJECT" },
        { 0x8004CB09, "CBA_E_INVALIDCOOKIE" },
@@ -319,9 +315,15 @@ static const value_string reject_status_vals[] = {
        { 0x8004CB0C, "CBA_E_QOSVALUEUNSUPPORTED" },
        { 0x8004CB0F, "CBA_E_NOTAPPLICABLE" },
        { 0x8004CB12, "CBA_E_LIMITVIOLATION" },
+       { 0x8004CB13, "CBA_E_QOSTYPENOTAPPLICABLE" },
+       { 0x8004CB18, "CBA_E_OUTOFPARTNERACCOS" },
+       { 0x8004CB1C, "CBA_E_FLAGUNSUPPORTED" },
+       { 0x8004CB23, "CBA_E_FRAMECOUNTUNSUPPORTED" },
+       { 0x8004CB25, "CBA_E_MODECHANGE" },
        { 0x8007000E, "E_OUTOFMEMORY" },
        { 0x80070057, "E_INVALIDARG" },
        { 0x800706d1, "RPC_S_PROCNUM_OUT_OF_RANGE" },
+       { 0x80070776, "OR_INVALID_OXID" },
        { 0,          NULL }
 };
 
@@ -363,11 +365,14 @@ static int hf_dcerpc_cn_max_xmit = -1;
 static int hf_dcerpc_cn_max_recv = -1;
 static int hf_dcerpc_cn_assoc_group = -1;
 static int hf_dcerpc_cn_num_ctx_items = -1;
+static int hf_dcerpc_cn_ctx_item = -1;
 static int hf_dcerpc_cn_ctx_id = -1;
 static int hf_dcerpc_cn_num_trans_items = -1;
+static int hf_dcerpc_cn_bind_abstract_syntax = -1;
 static int hf_dcerpc_cn_bind_if_id = -1;
 static int hf_dcerpc_cn_bind_if_ver = -1;
 static int hf_dcerpc_cn_bind_if_ver_minor = -1;
+static int hf_dcerpc_cn_bind_trans_syntax = -1;
 static int hf_dcerpc_cn_bind_trans_id = -1;
 static int hf_dcerpc_cn_bind_trans_ver = -1;
 static int hf_dcerpc_cn_alloc_hint = -1;
@@ -456,6 +461,7 @@ static gint ett_dcerpc = -1;
 static gint ett_dcerpc_cn_flags = -1;
 static gint ett_dcerpc_cn_ctx = -1;
 static gint ett_dcerpc_cn_iface = -1;
+static gint ett_dcerpc_cn_trans_syntax = -1;
 static gint ett_dcerpc_drep = -1;
 static gint ett_dcerpc_dg_flags1 = -1;
 static gint ett_dcerpc_dg_flags2 = -1;
@@ -484,38 +490,6 @@ static const fragment_items dcerpc_frag_items = {
 /* list of hooks to be called when init_protocols is done */
 GHookList dcerpc_hooks_init_protos;
 
-#ifdef _WIN32
-int ResolveWin32UUID(e_uuid_t if_id, char *UUID_NAME, int UUID_NAME_MAX_LEN)
-{
-       char REG_UUID_NAME[MAX_PATH];
-       HKEY hKey = NULL;
-       DWORD UUID_MAX_SIZE = MAX_PATH;
-       TCHAR REG_UUID_STR[MAX_PATH];
-
-       if(UUID_NAME_MAX_LEN < 2)
-               return 0;
-       REG_UUID_NAME[0] = '\0';
-       _snwprintf(REG_UUID_STR, MAX_PATH, _T("SOFTWARE\\Classes\\Interface\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"),
-                       if_id.Data1, if_id.Data2, if_id.Data3,
-                       if_id.Data4[0], if_id.Data4[1],
-                       if_id.Data4[2], if_id.Data4[3],
-                       if_id.Data4[4], if_id.Data4[5],
-                       if_id.Data4[6], if_id.Data4[7]);
-       if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_UUID_STR, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
-       {
-               if (RegQueryValueEx(hKey, NULL, NULL, NULL, (LPBYTE)REG_UUID_NAME, &UUID_MAX_SIZE) == ERROR_SUCCESS && UUID_MAX_SIZE <= MAX_PATH)
-                       {
-                       g_snprintf(UUID_NAME, UUID_NAME_MAX_LEN, "%s", REG_UUID_NAME);
-                       RegCloseKey(hKey);
-                       return strlen(REG_UUID_NAME);
-               }
-               RegCloseKey(hKey);
-       }
-       return 0; /* we didn't find anything anyhow. Please don't use the string! */
-
-}
-#endif
-
 static dcerpc_info *
 get_next_di(void)
 {
@@ -720,32 +694,13 @@ dcerpc_init_uuid (int proto, int ett, e_uuid_t *uuid, guint16 ver,
 
     hf_info = proto_registrar_get_nth(opnum_hf);
     hf_info->strings = value_string_from_subdissectors(procs);
-}
-
-
-/* try to get registered name for this uuid */
-const gchar *dcerpc_get_uuid_name(e_uuid_t *uuid, guint16 ver)
-{
-    dcerpc_uuid_key key;
-    dcerpc_uuid_value *sub_proto;
-
 
-       /* try to get registered uuid "name" of if_id */
-       key.uuid = *uuid;
-       key.ver = ver;
-
-       if ((sub_proto = g_hash_table_lookup (dcerpc_uuids, &key)) != NULL
-                && proto_is_protocol_enabled(sub_proto->proto)) {
-
-               return sub_proto->name;
-       }
-
-       return NULL;
+    /* add this GUID to the global name resolving */
+    guids_add_uuid(uuid, proto_get_protocol_short_name (value->proto));
 }
 
-
 /* Function to find the name of a registered protocol
- * or NULL if the protocol/version is not known to ethereal.
+ * or NULL if the protocol/version is not known to wireshark.
  */
 const char *
 dcerpc_get_proto_name(e_uuid_t *uuid, guint16 ver)
@@ -762,7 +717,7 @@ dcerpc_get_proto_name(e_uuid_t *uuid, guint16 ver)
 }
 
 /* Function to find the opnum hf-field of a registered protocol
- * or -1 if the protocol/version is not known to ethereal.
+ * or -1 if the protocol/version is not known to wireshark.
  */
 int
 dcerpc_get_proto_hf_opnum(e_uuid_t *uuid, guint16 ver)
@@ -807,7 +762,7 @@ value_string *value_string_from_subdissectors(dcerpc_sub_dissector *sd)
 }
 
 /* Function to find the subdissector table of a registered protocol
- * or NULL if the protocol/version is not known to ethereal.
+ * or NULL if the protocol/version is not known to wireshark.
  */
 dcerpc_sub_dissector *
 dcerpc_get_proto_sub_dissector(e_uuid_t *uuid, guint16 ver)
@@ -1133,57 +1088,19 @@ dissect_dcerpc_double(tvbuff_t *tvb, gint offset, packet_info *pinfo _U_,
 
 int
 dissect_dcerpc_uuid_t (tvbuff_t *tvb, gint offset, packet_info *pinfo _U_,
-                    proto_tree *tree, char *drep,
+                    proto_tree *tree, guint8 *drep,
                     int hfindex, e_uuid_t *pdata)
 {
     e_uuid_t uuid;
-       header_field_info* hfi;
-#if 0
-       gchar *uuid_name;
-#endif
 
 
-    dcerpc_tvb_get_uuid (tvb, offset, drep, &uuid);
+    if (drep[0] & 0x10) {
+        tvb_get_letohguid (tvb, offset, (e_guid_t *) &uuid);
+    } else {
+        tvb_get_ntohguid (tvb, offset, (e_guid_t *) &uuid);
+    }
     if (tree) {
-               /* get name of protocol field to prepend it later */
-               hfi = proto_registrar_get_nth(hfindex);
-
-#if 0
-        /* XXX - get the name won't work correct, as we don't know the version of this uuid (if it has one) */
-               /* look for a registered uuid name */
-               uuid_name = dcerpc_get_uuid_name(&uuid, 0);
-
-               if (uuid_name) {
-                       /* we know the name of this uuid */
-                       proto_tree_add_string_format (tree, hfindex, tvb, offset, 16, "",
-                                      "%s: %s (%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
-                                                                         hfi->name, uuid_name,
-                                      uuid.Data1, uuid.Data2, uuid.Data3,
-                                      uuid.Data4[0], uuid.Data4[1],
-                                      uuid.Data4[2], uuid.Data4[3],
-                                      uuid.Data4[4], uuid.Data4[5],
-                                      uuid.Data4[6], uuid.Data4[7]);
-               } else {
-#endif
-                       /* GUID have changed from FT_STRING to FT_GUID
-                          but we havent changed all dissectors yet.
-                        */
-                       if(hfi->type==FT_GUID){
-                               proto_tree_add_item(tree, hfindex, tvb, offset, 16, (drep[0] & 0x10));
-                       } else {
-                               /* we don't know the name of this uuid */
-                               proto_tree_add_string_format (tree, hfindex, tvb, offset, 16, "",
-                                     "%s: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-                                     hfi->name,
-                                      uuid.Data1, uuid.Data2, uuid.Data3,
-                                      uuid.Data4[0], uuid.Data4[1],
-                                      uuid.Data4[2], uuid.Data4[3],
-                                      uuid.Data4[4], uuid.Data4[5],
-                                      uuid.Data4[6], uuid.Data4[7]);
-                       }
-#if 0
-               }
-#endif
+               proto_tree_add_guid(tree, hfindex, tvb, offset, 16, (e_guid_t *) &uuid);
     }
     if (pdata) {
         *pdata = uuid;
@@ -1218,18 +1135,14 @@ dcerpc_tvb_get_ntohl (tvbuff_t *tvb, gint offset, guint8 *drep)
 void
 dcerpc_tvb_get_uuid (tvbuff_t *tvb, gint offset, guint8 *drep, e_uuid_t *uuid)
 {
-    unsigned int i;
-    uuid->Data1 = dcerpc_tvb_get_ntohl (tvb, offset, drep);
-    uuid->Data2 = dcerpc_tvb_get_ntohs (tvb, offset+4, drep);
-    uuid->Data3 = dcerpc_tvb_get_ntohs (tvb, offset+6, drep);
-
-    for (i=0; i<sizeof (uuid->Data4); i++) {
-        uuid->Data4[i] = tvb_get_guint8 (tvb, offset+8+i);
+    if (drep[0] & 0x10) {
+        tvb_get_letohguid (tvb, offset, (e_guid_t *) uuid);
+    } else {
+        tvb_get_ntohguid (tvb, offset, (e_guid_t *) uuid);
     }
 }
 
 
-
 /* NDR arrays */
 /* function to dissect a unidimensional conformant array */
 int
@@ -1297,7 +1210,10 @@ dissect_ndr_ucvarray(tvbuff_t *tvb, gint offset, packet_info *pinfo,
 
                /* real run, dissect the elements */
                for(i=0;i<di->array_actual_count;i++){
+                       old_offset = offset;
                        offset = (*fnct)(tvb, offset, pinfo, tree, drep);
+                        if (offset <= old_offset)
+                                THROW(ReportedBoundsError);
                }
        }
 
@@ -2211,14 +2127,12 @@ dcerpc_try_handoff (packet_info *pinfo, proto_tree *tree,
     dcerpc_dissect_fnct_t *volatile sub_dissect;
     const char *volatile saved_proto;
     void *volatile saved_private_data;
-    guint length, reported_length;
+    guint length = 0, reported_length = 0;
     tvbuff_t *volatile stub_tvb;
     volatile guint auth_pad_len;
     volatile int auth_pad_offset;
-#ifdef _WIN32
-    char UUID_NAME[MAX_PATH];
-#endif
     proto_item *sub_item=NULL;
+    proto_item *pi;
 
     key.uuid = info->call_data->uuid;
     key.ver = info->call_data->ver;
@@ -2234,20 +2148,8 @@ dcerpc_try_handoff (packet_info *pinfo, proto_tree *tree,
        proto_tree_add_boolean_hidden(dcerpc_tree, hf_dcerpc_unknown_if_id,
                                          tvb, offset, 0, TRUE);
        if (check_col (pinfo->cinfo, COL_INFO)) {
-#ifdef _WIN32
-               if(ResolveWin32UUID(info->call_data->uuid, UUID_NAME, MAX_PATH))
-                       col_append_fstr (pinfo->cinfo, COL_INFO, " [%s] UUID: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x rpcver: %u",
-                               UUID_NAME, info->call_data->uuid.Data1, info->call_data->uuid.Data2, info->call_data->uuid.Data3, info->call_data->uuid.Data4[0],
-                               info->call_data->uuid.Data4[1], info->call_data->uuid.Data4[2], info->call_data->uuid.Data4[3],
-                               info->call_data->uuid.Data4[4], info->call_data->uuid.Data4[5], info->call_data->uuid.Data4[6],
-                               info->call_data->uuid.Data4[7], info->call_data->ver);
-else
-#endif
-               col_append_fstr (pinfo->cinfo, COL_INFO, " UNKUUID: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x rpcver: %u",
-                       info->call_data->uuid.Data1, info->call_data->uuid.Data2, info->call_data->uuid.Data3, info->call_data->uuid.Data4[0],
-                       info->call_data->uuid.Data4[1], info->call_data->uuid.Data4[2], info->call_data->uuid.Data4[3],
-                       info->call_data->uuid.Data4[4], info->call_data->uuid.Data4[5], info->call_data->uuid.Data4[6],
-                       info->call_data->uuid.Data4[7], info->call_data->ver);
+               col_append_fstr (pinfo->cinfo, COL_INFO, " %s V%u",
+                       guids_resolve_uuid_to_str(&info->call_data->uuid), info->call_data->ver);
        }
 
         if (decrypted_tvb != NULL) {
@@ -2277,9 +2179,13 @@ else
                       name, (info->ptype == PDU_REQ) ? "request" : "response");
     }
 
+    sub_dissect = (info->ptype == PDU_REQ) ?
+           proc->dissect_rqst : proc->dissect_resp;
+
     if (tree) {
-        sub_item = proto_tree_add_item (tree, sub_proto->proto_id, tvb, 0,
-                                        -1, FALSE);
+        sub_item = proto_tree_add_item (tree, sub_proto->proto_id,
+                                       (decrypted_tvb != NULL)?decrypted_tvb:tvb,
+                                       0, -1, FALSE);
 
         if (sub_item) {
             sub_tree = proto_item_add_subtree (sub_item, sub_proto->ett);
@@ -2290,25 +2196,32 @@ else
          * Put the operation number into the tree along with
          * the operation's name.
          */
-
        if (sub_proto->opnum_hf != -1)
-            proto_tree_add_uint_format(sub_tree, sub_proto->opnum_hf,
-                                       tvb, 0, 0, info->call_data->opnum,
-                                       "Operation: %s (%u)",
-                                       name, info->call_data->opnum);
+                proto_tree_add_uint_format(sub_tree, sub_proto->opnum_hf,
+                                           tvb, 0, 0, info->call_data->opnum,
+                                           "Operation: %s (%u)",
+                                           name, info->call_data->opnum);
        else
-            proto_tree_add_uint_format(sub_tree, hf_dcerpc_op, tvb,
-                                       0, 0, info->call_data->opnum,
-                                       "Operation: %s (%u)",
-                                       name, info->call_data->opnum);
-    }
-
-    sub_dissect = (info->ptype == PDU_REQ) ?
-           proc->dissect_rqst : proc->dissect_resp;
+                proto_tree_add_uint_format(sub_tree, hf_dcerpc_op, tvb,
+                                           0, 0, info->call_data->opnum,
+                                           "Operation: %s (%u)",
+                                           name, info->call_data->opnum);
+
+        if(info->ptype == PDU_REQ && info->call_data->rep_frame!=0) {
+            pi = proto_tree_add_uint(sub_tree, hf_dcerpc_response_in,
+                                     tvb, 0, 0, info->call_data->rep_frame);
+            PROTO_ITEM_SET_GENERATED(pi);
+       }
+        if(info->ptype == PDU_RESP && info->call_data->req_frame!=0) {
+            pi = proto_tree_add_uint(sub_tree, hf_dcerpc_request_in,
+                                     tvb, 0, 0, info->call_data->req_frame);
+            PROTO_ITEM_SET_GENERATED(pi);
+       }
+    } /* tree */
 
     if (decrypted_tvb != NULL) {
         /* Either there was no encryption or we successfully decrypted
-           the entrypted payload. */
+           the encrypted payload. */
         if (sub_dissect) {
             /* We have a subdissector - call it. */
             saved_proto = pinfo->current_proto;
@@ -2318,12 +2231,13 @@ else
 
             init_ndr_pointer_list(pinfo);
 
+            length = tvb_length(decrypted_tvb);
+            reported_length = tvb_reported_length(decrypted_tvb);
+
             /*
              * Remove the authentication padding from the stub data.
              */
             if (auth_info != NULL && auth_info->auth_pad_len != 0) {
-                length = tvb_length(decrypted_tvb);
-                reported_length = tvb_reported_length(decrypted_tvb);
                 if (reported_length >= auth_info->auth_pad_len) {
                     /*
                      * OK, the padding length isn't so big that it
@@ -2341,7 +2255,7 @@ else
                     if (length > reported_length)
                         length = reported_length;
 
-                    stub_tvb = tvb_new_subset(tvb, 0, length, reported_length);
+                    stub_tvb = tvb_new_subset(decrypted_tvb, 0, length, reported_length);
                     auth_pad_len = auth_info->auth_pad_len;
                     auth_pad_offset = reported_length;
                 } else {
@@ -2354,6 +2268,8 @@ else
                     stub_tvb = NULL;
                     auth_pad_len = reported_length;
                     auth_pad_offset = 0;
+                    length = 0;
+                    reported_length = 0;
                 }
             } else {
                 /*
@@ -2364,6 +2280,10 @@ else
                 auth_pad_offset = 0;
             }
 
+            if (sub_item) {
+               proto_item_set_len(sub_item, length);
+            }
+
             if (stub_tvb != NULL) {
                 /*
                  * Catch all exceptions other than BoundsError, so that even
@@ -2375,25 +2295,31 @@ else
                  * dissect; just re-throw that exception.
                  */
                 TRY {
-                    offset = sub_dissect (decrypted_tvb, 0, pinfo, sub_tree,
+                    int remaining;
+
+                    offset = sub_dissect (stub_tvb, 0, pinfo, sub_tree,
                                           drep);
-                    if(tree) {
-                        proto_item_set_len(sub_item, offset);
-                    }
 
                     /* If we have a subdissector and it didn't dissect all
                        data in the tvb, make a note of it. */
-                    /* XXX - don't do this, as this could be just another RPC Req./Resp. in this PDU */
-                    /*if (tvb_reported_length_remaining(stub_tvb, offset) > 0) {
+                    remaining = tvb_reported_length_remaining(stub_tvb, offset);
+                    if (remaining > 0) {
+                        proto_tree_add_text(sub_tree, stub_tvb, offset,
+                                            remaining,
+                                            "[Long frame (%d byte%s)]",
+                                            remaining,
+                                            plurality(remaining, "", "s"));
                         if (check_col(pinfo->cinfo, COL_INFO))
                             col_append_fstr(pinfo->cinfo, COL_INFO,
-                                            "[Long frame (%d bytes)]",
-                                            tvb_reported_length_remaining(stub_tvb, offset));
-                    }*/
+                                            "[Long frame (%d byte%s)]",
+                                            remaining,
+                                            plurality(remaining, "", "s"));
+
+                    }
                 } CATCH(BoundsError) {
                     RETHROW;
                 } CATCH_ALL {
-                    show_exception(decrypted_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
+                    show_exception(stub_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
                 } ENDTRY;
             }
 
@@ -2604,12 +2530,10 @@ dissect_dcerpc_cn_bind (tvbuff_t *tvb, gint offset, packet_info *pinfo,
     e_uuid_t trans_id;
     guint32 trans_ver;
     guint16 if_ver, if_ver_minor;
-    char uuid_str[DCERPC_UUID_STR_LEN];
-    int uuid_str_len;
     dcerpc_auth_info auth_info;
-#ifdef _WIN32
-    char UUID_NAME[MAX_PATH];
-#endif
+    char *uuid_str;
+    const char *uuid_name = NULL;
+       proto_item *iface_item;
 
     offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
                                     hf_dcerpc_cn_max_xmit, NULL);
@@ -2627,56 +2551,64 @@ dissect_dcerpc_cn_bind (tvbuff_t *tvb, gint offset, packet_info *pinfo,
     offset += 3;
 
     for (i = 0; i < num_ctx_items; i++) {
+           proto_item *ctx_item;
            proto_tree *ctx_tree = NULL, *iface_tree = NULL;
+        gint ctx_offset = offset;
 
-      offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, NULL, hdr->drep,
+      dissect_dcerpc_uint16 (tvb, offset, pinfo, NULL, hdr->drep,
                                       hf_dcerpc_cn_ctx_id, &ctx_id);
 
+      if (check_col (pinfo->cinfo, COL_DCE_CTX)) {
+               if(pinfo->dcectxid == 0) {
+                       col_append_fstr (pinfo->cinfo, COL_DCE_CTX, "%u", ctx_id);
+               } else {
+                       /* this is not the first DCE-RPC request/response in this (TCP?-)PDU,
+                        * prepend a delimiter */
+                       col_append_fstr (pinfo->cinfo, COL_DCE_CTX, "#%u", ctx_id);
+               }
+      }
+
       /* save context ID for use with dcerpc_add_conv_to_bind_table() */
       /* (if we have multiple contexts, this might cause "decode as"
        *  to behave unpredictably) */
       pinfo->dcectxid = ctx_id;
 
       if (dcerpc_tree) {
-             proto_item *ctx_item;
-
-             ctx_item = proto_tree_add_item(dcerpc_tree, hf_dcerpc_cn_ctx_id,
-                                            tvb, offset - 2, 2,
+             ctx_item = proto_tree_add_item(dcerpc_tree, hf_dcerpc_cn_ctx_item,
+                                            tvb, offset, 0,
                                             hdr->drep[0] & 0x10);
-
              ctx_tree = proto_item_add_subtree(ctx_item, ett_dcerpc_cn_ctx);
       }
 
+      offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, ctx_tree, hdr->drep,
+                                      hf_dcerpc_cn_ctx_id, &ctx_id);
       offset = dissect_dcerpc_uint8 (tvb, offset, pinfo, ctx_tree, hdr->drep,
                                       hf_dcerpc_cn_num_trans_items, &num_trans_items);
 
+      if(dcerpc_tree) {
+        proto_item_append_text(ctx_item, "[%u]: ID:%u", i+1, ctx_id);
+      }
+
       /* padding */
       offset += 1;
 
-      /* XXX - use "dissect_ndr_uuid_t()"? */
       dcerpc_tvb_get_uuid (tvb, offset, hdr->drep, &if_id);
       if (ctx_tree) {
-         proto_item *iface_item;
-
-         uuid_str_len = g_snprintf(uuid_str, DCERPC_UUID_STR_LEN,
-                                 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-                                  if_id.Data1, if_id.Data2, if_id.Data3,
-                                  if_id.Data4[0], if_id.Data4[1],
-                                  if_id.Data4[2], if_id.Data4[3],
-                                  if_id.Data4[4], if_id.Data4[5],
-                                  if_id.Data4[6], if_id.Data4[7]);
-
-         if (uuid_str_len == -1 || uuid_str_len >= DCERPC_UUID_STR_LEN)
-                 memset(uuid_str, 0, DCERPC_UUID_STR_LEN);
-#ifdef _WIN32
-         if(ResolveWin32UUID(if_id, UUID_NAME, MAX_PATH))
-                 iface_item = proto_tree_add_string_format (ctx_tree, hf_dcerpc_cn_bind_if_id, tvb,
-                                        offset, 16, uuid_str, "Interface: %s\tUUID: %s", UUID_NAME, uuid_str);
-         else
-#endif
-          iface_item = proto_tree_add_string_format (ctx_tree, hf_dcerpc_cn_bind_if_id, tvb,
-                                        offset, 16, uuid_str, "Interface UUID: %s", uuid_str);
+
+      iface_item = proto_tree_add_item(ctx_tree, hf_dcerpc_cn_bind_abstract_syntax, tvb, offset, 0, FALSE);
          iface_tree = proto_item_add_subtree(iface_item, ett_dcerpc_cn_iface);
+
+      uuid_str = guid_to_str((e_guid_t*)&if_id);
+      uuid_name = guids_get_uuid_name(&if_id);
+      if(uuid_name) {
+                 proto_tree_add_guid_format (iface_tree, hf_dcerpc_cn_bind_if_id, tvb,
+                                        offset, 16, (e_guid_t *) &if_id, "Interface: %s UUID: %s", uuid_name, uuid_str);
+          proto_item_append_text(iface_item, ": %s", uuid_name);
+      } else {
+          proto_tree_add_guid_format (iface_tree, hf_dcerpc_cn_bind_if_id, tvb,
+                                        offset, 16, (e_guid_t *) &if_id, "Interface UUID: %s", uuid_str);
+          proto_item_append_text(iface_item, ": %s", uuid_str);
+      }
       }
       offset += 16;
 
@@ -2692,6 +2624,11 @@ dissect_dcerpc_cn_bind (tvbuff_t *tvb, gint offset, packet_info *pinfo,
                                           hf_dcerpc_cn_bind_if_ver, &if_ver);
       }
 
+      if (ctx_tree) {
+          proto_item_append_text(iface_item, " V%u.%u", if_ver, if_ver_minor);
+          proto_item_set_len(iface_item, 20);
+      }
+
       if (!saw_ctx_item) {
         conv = find_conversation (pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
                                   pinfo->srcport, pinfo->destport, 0);
@@ -2729,60 +2666,42 @@ dissect_dcerpc_cn_bind (tvbuff_t *tvb, gint offset, packet_info *pinfo,
        }
 
         if (check_col (pinfo->cinfo, COL_INFO)) {
-         dcerpc_uuid_key key;
-         dcerpc_uuid_value *value;
-
-         key.uuid = if_id;
-         key.ver = if_ver;
-
          if (num_ctx_items > 1)
                  col_append_fstr(pinfo->cinfo, COL_INFO, ", %u context items, 1st", num_ctx_items);
 
-         if ((value = g_hash_table_lookup(dcerpc_uuids, &key)))
-                 col_append_fstr(pinfo->cinfo, COL_INFO, " UUID: %s", value->name);
-         else
-#ifdef _WIN32
-               if(ResolveWin32UUID(if_id, UUID_NAME, MAX_PATH))
-                       col_append_fstr(pinfo->cinfo, COL_INFO, " [%s] UUID: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x ver %u.%u",
-                           UUID_NAME, if_id.Data1, if_id.Data2, if_id.Data3,
-                           if_id.Data4[0], if_id.Data4[1],
-                           if_id.Data4[2], if_id.Data4[3],
-                           if_id.Data4[4], if_id.Data4[5],
-                           if_id.Data4[6], if_id.Data4[7],
-                           if_ver, if_ver_minor);
-         else
-#endif
-                       col_append_fstr(pinfo->cinfo, COL_INFO, " UUID: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x ver %u.%u",
-                           if_id.Data1, if_id.Data2, if_id.Data3,
-                           if_id.Data4[0], if_id.Data4[1],
-                           if_id.Data4[2], if_id.Data4[3],
-                           if_id.Data4[4], if_id.Data4[5],
-                           if_id.Data4[6], if_id.Data4[7],
-                           if_ver, if_ver_minor);
+               col_append_fstr(pinfo->cinfo, COL_INFO, " %s V%u.%u",
+                       guids_resolve_uuid_to_str(&if_id), if_ver, if_ver_minor);
         }
         saw_ctx_item = TRUE;
       }
 
       for (j = 0; j < num_trans_items; j++) {
-        /* XXX - use "dissect_ndr_uuid_t()"? */
+           proto_tree *trans_tree = NULL;
+           proto_item *trans_item = NULL;
+
         dcerpc_tvb_get_uuid (tvb, offset, hdr->drep, &trans_id);
-        if (iface_tree) {
-           uuid_str_len = g_snprintf(uuid_str, DCERPC_UUID_STR_LEN,
-                                  "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-                                  trans_id.Data1, trans_id.Data2, trans_id.Data3,
-                                  trans_id.Data4[0], trans_id.Data4[1],
-                                  trans_id.Data4[2], trans_id.Data4[3],
-                                  trans_id.Data4[4], trans_id.Data4[5],
-                                  trans_id.Data4[6], trans_id.Data4[7]);
-            if (uuid_str_len == -1 || uuid_str_len >= DCERPC_UUID_STR_LEN)
-                memset(uuid_str, 0, DCERPC_UUID_STR_LEN);
-            proto_tree_add_string_format (iface_tree, hf_dcerpc_cn_bind_trans_id, tvb,
-                                          offset, 16, uuid_str, "Transfer Syntax: %s", uuid_str);
+        if (ctx_tree) {
+
+        trans_item = proto_tree_add_item(ctx_tree, hf_dcerpc_cn_bind_trans_syntax, tvb, offset, 0, FALSE);
+        trans_tree = proto_item_add_subtree(trans_item, ett_dcerpc_cn_trans_syntax);
+
+        uuid_str = guid_to_str((e_guid_t *) &trans_id);
+            proto_tree_add_guid_format (trans_tree, hf_dcerpc_cn_bind_trans_id, tvb,
+                                          offset, 16, (e_guid_t *) &trans_id, "Transfer Syntax: %s", uuid_str);
+            proto_item_append_text(trans_item, "[%u]: %s", j+1, uuid_str);
         }
         offset += 16;
 
-        offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, iface_tree, hdr->drep,
+        offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, trans_tree, hdr->drep,
                                         hf_dcerpc_cn_bind_trans_ver, &trans_ver);
+        if (ctx_tree) {
+          proto_item_set_len(trans_item, 20);
+          proto_item_append_text(trans_item, " V%u", trans_ver);
+        }
+      }
+
+      if(ctx_tree) {
+        proto_item_set_len(ctx_item, offset - ctx_offset);
       }
     }
 
@@ -2806,8 +2725,6 @@ dissect_dcerpc_cn_bind_ack (tvbuff_t *tvb, gint offset, packet_info *pinfo,
     guint16 reason;
     e_uuid_t trans_id;
     guint32 trans_ver;
-    char uuid_str[DCERPC_UUID_STR_LEN];
-    int uuid_str_len;
     dcerpc_auth_info auth_info;
 
     offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
@@ -2843,7 +2760,7 @@ dissect_dcerpc_cn_bind_ack (tvbuff_t *tvb, gint offset, packet_info *pinfo,
 
        if(dcerpc_tree){
                proto_item *ctx_item;
-               ctx_item = proto_tree_add_text(dcerpc_tree, tvb, offset, 24, "Context ID: %d", i);
+               ctx_item = proto_tree_add_text(dcerpc_tree, tvb, offset, 24, "Context ID[%u]", i+1);
                ctx_tree = proto_item_add_subtree(ctx_item, ett_dcerpc_cn_ctx);
        }
 
@@ -2862,20 +2779,11 @@ dissect_dcerpc_cn_bind_ack (tvbuff_t *tvb, gint offset, packet_info *pinfo,
             offset += 2;
         }
 
-        /* XXX - use "dissect_ndr_uuid_t()"? */
         dcerpc_tvb_get_uuid (tvb, offset, hdr->drep, &trans_id);
         if (ctx_tree) {
-           uuid_str_len = g_snprintf(uuid_str, DCERPC_UUID_STR_LEN,
-                                  "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-                                  trans_id.Data1, trans_id.Data2, trans_id.Data3,
-                                  trans_id.Data4[0], trans_id.Data4[1],
-                                  trans_id.Data4[2], trans_id.Data4[3],
-                                  trans_id.Data4[4], trans_id.Data4[5],
-                                  trans_id.Data4[6], trans_id.Data4[7]);
-           if (uuid_str_len == -1 || uuid_str_len >= DCERPC_UUID_STR_LEN)
-                 memset(uuid_str, 0, DCERPC_UUID_STR_LEN);
-            proto_tree_add_string_format (ctx_tree, hf_dcerpc_cn_ack_trans_id, tvb,
-                                          offset, 16, uuid_str, "Transfer Syntax: %s", uuid_str);
+            proto_tree_add_guid_format (ctx_tree, hf_dcerpc_cn_ack_trans_id, tvb,
+                                          offset, 16, (e_guid_t *) &trans_id, "Transfer Syntax: %s",
+                                          guid_to_str((e_guid_t *) &trans_id));
         }
         offset += 16;
 
@@ -3103,7 +3011,7 @@ dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
        nor the first fragment then there is nothing more we can do
        so we just have to exit
     */
-    if( !dcerpc_reassemble )
+    if( !dcerpc_reassemble || (tvb_length(tvb)!=tvb_reported_length(tvb)) )
         goto end_cn_stub;
 
     /* if we didnt get 'frame' we dont know where the PDU started and thus
@@ -3129,9 +3037,9 @@ dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
     /* defragmentation is a bit tricky, as there's no offset of the fragment
      * in the protocol data.
      *
-        * just use fragment_add_seq_next() and hope that TCP/SMB segments coming
-        * in with the correct sequence.
-    */
+     * just use fragment_add_seq_next() and hope that TCP/SMB segments coming
+     * in with the correct sequence.
+     */
     fd_head = fragment_add_seq_next(decrypted_tvb, 0, pinfo, frame,
                dcerpc_co_fragment_table, dcerpc_co_reassemble_table,
                tvb_length(decrypted_tvb),
@@ -3149,8 +3057,12 @@ end_cn_stub:
            tvbuff_t *next_tvb;
         proto_item *frag_tree_item;
 
-               next_tvb = tvb_new_real_data(fd_head->data, fd_head->len, fd_head->len);
-           tvb_set_child_real_data_tvbuff(decrypted_tvb, next_tvb);
+           next_tvb = tvb_new_real_data(fd_head->data, fd_head->len, fd_head->len);
+           if(decrypted_tvb){
+               tvb_set_child_real_data_tvbuff(decrypted_tvb, next_tvb);
+           } else {
+               tvb_set_child_real_data_tvbuff(payload_tvb, next_tvb);
+           }
            add_new_data_source(pinfo, next_tvb, "Reassembled DCE/RPC");
            show_fragment_tree(fd_head, &dcerpc_frag_items,
                        tree, pinfo, next_tvb, &frag_tree_item);
@@ -3164,15 +3076,20 @@ end_cn_stub:
            pinfo->fragmented = FALSE;
 
                expert_add_info_format(pinfo, frag_tree_item, PI_REASSEMBLE, PI_CHAT,
-                       "%s fragment, %u bytes reassembled here in #%u",
-                       fragment_type(hdr->flags), fd_head->len, fd_head->reassembled_in);
+                       "%s fragment, reassembled",
+                       fragment_type(hdr->flags));
 
            dcerpc_try_handoff (pinfo, tree, dcerpc_tree, next_tvb,
                next_tvb, hdr->drep, di, auth_info);
 
        } else {
-           pi = proto_tree_add_uint(dcerpc_tree, hf_dcerpc_reassembled_in,
+           if(decrypted_tvb){
+               pi = proto_tree_add_uint(dcerpc_tree, hf_dcerpc_reassembled_in,
                                decrypted_tvb, 0, 0, fd_head->reassembled_in);
+           } else {
+               pi = proto_tree_add_uint(dcerpc_tree, hf_dcerpc_reassembled_in,
+                               payload_tvb, 0, 0, fd_head->reassembled_in);
+           }
         PROTO_ITEM_SET_GENERATED(pi);
         parent_pi = proto_tree_get_parent(dcerpc_tree);
         if(parent_pi != NULL) {
@@ -3270,11 +3187,9 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, gint offset, packet_info *pinfo,
     conversation_t *conv;
     guint16 ctx_id;
     guint16 opnum;
-    e_uuid_t obj_id;
+    e_uuid_t obj_id = DCERPC_UUID_NULL;
     dcerpc_auth_info auth_info;
     guint32 alloc_hint;
-    char uuid_str[DCERPC_UUID_STR_LEN];
-    int uuid_str_len;
     proto_item *pi;
     proto_item *parent_pi;
 
@@ -3288,6 +3203,16 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, gint offset, packet_info *pinfo,
         proto_item_append_text(parent_pi, " Ctx: %u", ctx_id);
     }
 
+    if (check_col (pinfo->cinfo, COL_DCE_CTX)) {
+               if(pinfo->dcectxid == 0) {
+                       col_append_fstr (pinfo->cinfo, COL_DCE_CTX, "%u", ctx_id);
+               } else {
+                       /* this is not the first DCE-RPC request/response in this (TCP?-)PDU,
+                        * prepend a delimiter */
+                       col_append_fstr (pinfo->cinfo, COL_DCE_CTX, "#%u", ctx_id);
+               }
+    }
+
     offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
                                     hf_dcerpc_opnum, &opnum);
 
@@ -3300,24 +3225,11 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, gint offset, packet_info *pinfo,
     }
 
     if (hdr->flags & PFC_OBJECT_UUID) {
-        /* XXX - use "dissect_ndr_uuid_t()"? */
         dcerpc_tvb_get_uuid (tvb, offset, hdr->drep, &obj_id);
         if (dcerpc_tree) {
-           uuid_str_len = g_snprintf(uuid_str, DCERPC_UUID_STR_LEN,
-                                    "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-                                    obj_id.Data1, obj_id.Data2, obj_id.Data3,
-                                    obj_id.Data4[0],
-                                    obj_id.Data4[1],
-                                    obj_id.Data4[2],
-                                    obj_id.Data4[3],
-                                    obj_id.Data4[4],
-                                    obj_id.Data4[5],
-                                    obj_id.Data4[6],
-                                    obj_id.Data4[7]);
-           if (uuid_str_len == -1 || uuid_str_len >= DCERPC_UUID_STR_LEN)
-                 memset(uuid_str, 0, DCERPC_UUID_STR_LEN);
-            proto_tree_add_string_format (dcerpc_tree, hf_dcerpc_obj_id, tvb,
-                                          offset, 16, uuid_str, "Object UUID: %s", uuid_str);
+            proto_tree_add_guid_format (dcerpc_tree, hf_dcerpc_obj_id, tvb,
+                                          offset, 16, (e_guid_t *) &obj_id, "Object UUID: %s",
+                                          guid_to_str((e_guid_t *) &obj_id));
         }
         offset += 16;
     }
@@ -3389,11 +3301,13 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, gint offset, packet_info *pinfo,
                                call_value=se_alloc (sizeof (dcerpc_call_value));
                                call_value->uuid = bind_value->uuid;
                                call_value->ver = bind_value->ver;
+                call_value->object_uuid = obj_id;
                                call_value->opnum = opnum;
                                call_value->req_frame=pinfo->fd->num;
                                call_value->req_time=pinfo->fd->abs_ts;
                                call_value->rep_frame=0;
                                call_value->max_ptr=0;
+                               call_value->se_data = NULL;
                                call_value->private_data = NULL;
                                g_hash_table_insert (dcerpc_cn_calls, call_key, call_value);
 
@@ -3429,8 +3343,14 @@ dissect_dcerpc_cn_rqst (tvbuff_t *tvb, gint offset, packet_info *pinfo,
            dissect_dcerpc_cn_stub (tvb, offset, pinfo, dcerpc_tree, tree,
                                    hdr, di, &auth_info, alloc_hint,
                                    value->req_frame);
-       } else
+        } else {
+        /* no bind information, simply show stub data */
+        pi = proto_tree_add_text(dcerpc_tree, tvb, offset, 0, "No bind info for this interface Context ID - capture start too late?");
+        PROTO_ITEM_SET_GENERATED(pi);
+           expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_NOTE, "No bind info for interface Context ID:%u",
+            ctx_id);
            show_stub_data (tvb, offset, dcerpc_tree, &auth_info, TRUE);
+        }
     }
 
     /* Dissect the verifier */
@@ -3450,6 +3370,7 @@ dissect_dcerpc_cn_resp (tvbuff_t *tvb, gint offset, packet_info *pinfo,
     guint32 alloc_hint;
     proto_item *pi;
     proto_item *parent_pi;
+    e_uuid_t obj_id_null = DCERPC_UUID_NULL;
 
     offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
                                     hf_dcerpc_cn_alloc_hint, &alloc_hint);
@@ -3461,6 +3382,17 @@ dissect_dcerpc_cn_resp (tvbuff_t *tvb, gint offset, packet_info *pinfo,
         proto_item_append_text(parent_pi, " Ctx: %u", ctx_id);
     }
 
+    if (check_col (pinfo->cinfo, COL_DCE_CTX)) {
+               if(pinfo->dcectxid == 0) {
+                       col_append_fstr (pinfo->cinfo, COL_DCE_CTX, "%u", ctx_id);
+               } else {
+                       /* this is not the first DCE-RPC request/response in this (TCP?-)PDU,
+                        * prepend a delimiter */
+                       col_append_fstr (pinfo->cinfo, COL_DCE_CTX, "#%u", ctx_id);
+               }
+    }
+
+
     /* save context ID for use with dcerpc_add_conv_to_bind_table() */
     pinfo->dcectxid = ctx_id;
 
@@ -3531,6 +3463,16 @@ dissect_dcerpc_cn_resp (tvbuff_t *tvb, gint offset, packet_info *pinfo,
            di->call_data = value;
 
            proto_tree_add_uint (dcerpc_tree, hf_dcerpc_opnum, tvb, 0, 0, value->opnum);
+
+        /* (optional) "Object UUID" from request */
+        if (value && dcerpc_tree && memcmp(&value->object_uuid, &obj_id_null, sizeof(obj_id_null)) != 0) {
+                pi = proto_tree_add_guid_format (dcerpc_tree, hf_dcerpc_obj_id, tvb,
+                                              offset, 0, (e_guid_t *) &value->object_uuid, "Object UUID: %s",
+                                              guid_to_str((e_guid_t *) &value->object_uuid));
+                PROTO_ITEM_SET_GENERATED(pi);
+        }
+
+        /* request in */
            if(value->req_frame!=0){
                nstime_t delta_ts;
                pi = proto_tree_add_uint(dcerpc_tree, hf_dcerpc_request_in,
@@ -3542,13 +3484,24 @@ dissect_dcerpc_cn_resp (tvbuff_t *tvb, gint offset, packet_info *pinfo,
                nstime_delta(&delta_ts, &pinfo->fd->abs_ts, &value->req_time);
                pi = proto_tree_add_time(dcerpc_tree, hf_dcerpc_time, tvb, offset, 0, &delta_ts);
         PROTO_ITEM_SET_GENERATED(pi);
+        } else {
+                   pi = proto_tree_add_text(dcerpc_tree,
+                                       tvb, 0, 0, "No request to this DCE/RPC call found");
+                   expert_add_info_format(pinfo, pi, PI_SEQUENCE, PI_NOTE,
+                           "No request to this DCE/RPC call found");
            }
 
            dissect_dcerpc_cn_stub (tvb, offset, pinfo, dcerpc_tree, tree,
                                    hdr, di, &auth_info, alloc_hint,
                                    value->rep_frame);
-        } else
+        } else {
+            /* no bind information, simply show stub data */
+            pi = proto_tree_add_text(dcerpc_tree, tvb, offset, 0, "No bind info for this interface Context ID - capture start too late?");
+            PROTO_ITEM_SET_GENERATED(pi);
+               expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_NOTE, "No bind info for interface Context ID:%u",
+                ctx_id);
             show_stub_data (tvb, offset, dcerpc_tree, &auth_info, TRUE);
+        }
     }
 
     /* Dissect the verifier */
@@ -3573,6 +3526,16 @@ dissect_dcerpc_cn_fault (tvbuff_t *tvb, gint offset, packet_info *pinfo,
     offset = dissect_dcerpc_uint16 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
                                     hf_dcerpc_cn_ctx_id, &ctx_id);
 
+    if (check_col (pinfo->cinfo, COL_DCE_CTX)) {
+               if(pinfo->dcectxid == 0) {
+                       col_append_fstr (pinfo->cinfo, COL_DCE_CTX, "%u", ctx_id);
+               } else {
+                       /* this is not the first DCE-RPC request/response in this (TCP?-)PDU,
+                        * prepend a delimiter */
+                       col_append_fstr (pinfo->cinfo, COL_DCE_CTX, "#%u", ctx_id);
+               }
+    }
+
     offset = dissect_dcerpc_uint8 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
                                    hf_dcerpc_cn_cancel_count, NULL);
     /* padding */
@@ -3672,6 +3635,11 @@ dissect_dcerpc_cn_fault (tvbuff_t *tvb, gint offset, packet_info *pinfo,
                nstime_delta(&delta_ts, &pinfo->fd->abs_ts, &value->req_time);
                pi = proto_tree_add_time(dcerpc_tree, hf_dcerpc_time, tvb, offset, 0, &delta_ts);
         PROTO_ITEM_SET_GENERATED(pi);
+        } else {
+                   pi = proto_tree_add_text(dcerpc_tree,
+                                       tvb, 0, 0, "No request to this DCE/RPC call found");
+                   expert_add_info_format(pinfo, pi, PI_SEQUENCE, PI_NOTE,
+                           "No request to this DCE/RPC call found");
            }
 
            length = tvb_length_remaining(tvb, offset);
@@ -3922,7 +3890,7 @@ dissect_dcerpc_cn (tvbuff_t *tvb, int offset, packet_info *pinfo,
 
     if(pinfo->dcectxid != 0) {
         /* this is not the first DCE-RPC request/response in this (TCP?-)PDU */
-               expert_add_info_format(pinfo, NULL, PI_SEQUENCE, PI_NOTE, "Multiple DCE/RPC fragments/PDU's in one packet");
+               expert_add_info_format(pinfo, NULL, PI_SEQUENCE, PI_CHAT, "Multiple DCE/RPC fragments/PDU's in one packet");
        }
 
     offset = start_offset;
@@ -4539,11 +4507,13 @@ dissect_dcerpc_dg_rqst (tvbuff_t *tvb, int offset, packet_info *pinfo,
        call_value=se_alloc (sizeof (dcerpc_call_value));
        call_value->uuid = hdr->if_id;
        call_value->ver = hdr->if_ver;
+       call_value->object_uuid = hdr->obj_id;
        call_value->opnum = hdr->opnum;
        call_value->req_frame=pinfo->fd->num;
        call_value->req_time=pinfo->fd->abs_ts;
        call_value->rep_frame=0;
        call_value->max_ptr=0;
+       call_value->se_data = NULL;
        call_value->private_data = NULL;
        g_hash_table_insert (dcerpc_dg_calls, call_key, call_value);
 
@@ -4559,10 +4529,12 @@ dissect_dcerpc_dg_rqst (tvbuff_t *tvb, int offset, packet_info *pinfo,
     if (!value) {
         v.uuid = hdr->if_id;
         v.ver = hdr->if_ver;
+        v.object_uuid = hdr->obj_id;
         v.opnum = hdr->opnum;
         v.req_frame = pinfo->fd->num;
         v.rep_frame = 0;
         v.max_ptr = 0;
+        v.se_data=NULL;
         v.private_data=NULL;
         value = &v;
     }
@@ -4622,9 +4594,11 @@ dissect_dcerpc_dg_resp (tvbuff_t *tvb, int offset, packet_info *pinfo,
     if (!value) {
         v.uuid = hdr->if_id;
         v.ver = hdr->if_ver;
+        v.object_uuid = hdr->obj_id;
         v.opnum = hdr->opnum;
         v.req_frame=0;
         v.rep_frame=pinfo->fd->num;
+        v.se_data=NULL;
         v.private_data=NULL;
         value = &v;
     }
@@ -4647,6 +4621,11 @@ dissect_dcerpc_dg_resp (tvbuff_t *tvb, int offset, packet_info *pinfo,
        nstime_delta(&delta_ts, &pinfo->fd->abs_ts, &value->req_time);
        pi = proto_tree_add_time(dcerpc_tree, hf_dcerpc_time, tvb, offset, 0, &delta_ts);
     PROTO_ITEM_SET_GENERATED(pi);
+    } else {
+               pi = proto_tree_add_text(dcerpc_tree,
+                                   tvb, 0, 0, "No request to this DCE/RPC call found");
+               expert_add_info_format(pinfo, pi, PI_SEQUENCE, PI_NOTE,
+                       "No request to this DCE/RPC call found");
     }
     dissect_dcerpc_dg_stub (tvb, offset, pinfo, dcerpc_tree, tree, hdr, di);
 }
@@ -4703,8 +4682,8 @@ dissect_dcerpc_dg (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     int offset = 0;
     conversation_t *conv;
     int auth_level;
-    char uuid_str[DCERPC_UUID_STR_LEN];
-    int uuid_str_len;
+    char *uuid_str;
+    const char *uuid_name = NULL;
 
     /*
      * Check if this looks like a CL DCERPC call.  All dg packets
@@ -4858,62 +4837,29 @@ dissect_dcerpc_dg (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     offset++;
 
     if (tree) {
-        /* XXX - use "dissect_ndr_uuid_t()"? */
-       uuid_str_len = g_snprintf(uuid_str, DCERPC_UUID_STR_LEN,
-                                "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-                                hdr.obj_id.Data1, hdr.obj_id.Data2, hdr.obj_id.Data3,
-                                hdr.obj_id.Data4[0],
-                                hdr.obj_id.Data4[1],
-                                hdr.obj_id.Data4[2],
-                                hdr.obj_id.Data4[3],
-                                hdr.obj_id.Data4[4],
-                                hdr.obj_id.Data4[5],
-                                hdr.obj_id.Data4[6],
-                                hdr.obj_id.Data4[7]);
-        if (uuid_str_len == -1 || uuid_str_len >= DCERPC_UUID_STR_LEN)
-               memset(uuid_str, 0, DCERPC_UUID_STR_LEN);
-        proto_tree_add_string_format (dcerpc_tree, hf_dcerpc_obj_id, tvb,
-                                      offset, 16, uuid_str, "Object UUID: %s", uuid_str);
+        proto_tree_add_guid_format (dcerpc_tree, hf_dcerpc_obj_id, tvb,
+            offset, 16, (e_guid_t *) &hdr.obj_id, "Object UUID: %s",
+            guid_to_str((e_guid_t *) &hdr.obj_id));
     }
     offset += 16;
 
     if (tree) {
-        /* XXX - use "dissect_ndr_uuid_t()"? */
-       uuid_str_len = g_snprintf(uuid_str, DCERPC_UUID_STR_LEN,
-                                "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-                                hdr.if_id.Data1, hdr.if_id.Data2, hdr.if_id.Data3,
-                                hdr.if_id.Data4[0],
-                                hdr.if_id.Data4[1],
-                                hdr.if_id.Data4[2],
-                                hdr.if_id.Data4[3],
-                                hdr.if_id.Data4[4],
-                                hdr.if_id.Data4[5],
-                                hdr.if_id.Data4[6],
-                                hdr.if_id.Data4[7]);
-        if (uuid_str_len == -1 || uuid_str_len >= DCERPC_UUID_STR_LEN)
-               memset(uuid_str, 0, DCERPC_UUID_STR_LEN);
-        proto_tree_add_string_format (dcerpc_tree, hf_dcerpc_dg_if_id, tvb,
-                                      offset, 16, uuid_str, "Interface: %s", uuid_str);
+        uuid_str = guid_to_str((e_guid_t*)&hdr.if_id);
+        uuid_name = guids_get_uuid_name(&hdr.if_id);
+        if(uuid_name) {
+                 proto_tree_add_guid_format (dcerpc_tree, hf_dcerpc_dg_if_id, tvb,
+                                        offset, 16, (e_guid_t *) &hdr.if_id, "Interface: %s UUID: %s", uuid_name, uuid_str);
+        } else {
+          proto_tree_add_guid_format (dcerpc_tree, hf_dcerpc_dg_if_id, tvb,
+                                        offset, 16, (e_guid_t *) &hdr.if_id, "Interface UUID: %s", uuid_str);
+        }
     }
     offset += 16;
 
     if (tree) {
-        /* XXX - use "dissect_ndr_uuid_t()"? */
-       uuid_str_len = g_snprintf(uuid_str, DCERPC_UUID_STR_LEN,
-                                "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-                                hdr.act_id.Data1, hdr.act_id.Data2, hdr.act_id.Data3,
-                                hdr.act_id.Data4[0],
-                                hdr.act_id.Data4[1],
-                                hdr.act_id.Data4[2],
-                                hdr.act_id.Data4[3],
-                                hdr.act_id.Data4[4],
-                                hdr.act_id.Data4[5],
-                                hdr.act_id.Data4[6],
-                                hdr.act_id.Data4[7]);
-        if (uuid_str_len == -1 || uuid_str_len >= DCERPC_UUID_STR_LEN)
-               memset(uuid_str, 0, DCERPC_UUID_STR_LEN);
-        proto_tree_add_string_format (dcerpc_tree, hf_dcerpc_dg_act_id, tvb,
-                                      offset, 16, uuid_str, "Activity: %s", uuid_str);
+        proto_tree_add_guid_format (dcerpc_tree, hf_dcerpc_dg_act_id, tvb,
+                                      offset, 16, (e_guid_t *) &hdr.act_id, "Activity: %s",
+                                      guid_to_str((e_guid_t *) &hdr.act_id));
     }
     offset += 16;
 
@@ -5049,7 +4995,10 @@ dissect_dcerpc_dg (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         break;
 
     case PDU_FACK:
-        dissect_dcerpc_dg_fack (tvb, offset, pinfo, dcerpc_tree, &hdr);
+        /* Body is optional */
+        /* XXX - we assume "frag_len" is the length of the body */
+        if (hdr.frag_len != 0)
+            dissect_dcerpc_dg_fack (tvb, offset, pinfo, dcerpc_tree, &hdr);
         break;
 
     case PDU_REJECT:
@@ -5169,20 +5118,26 @@ proto_register_dcerpc (void)
           { "Assoc Group", "dcerpc.cn_assoc_group", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
         { &hf_dcerpc_cn_num_ctx_items,
           { "Num Ctx Items", "dcerpc.cn_num_ctx_items", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
+        { &hf_dcerpc_cn_ctx_item,
+          { "Ctx Item", "dcerpc.cn_ctx_item", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
         { &hf_dcerpc_cn_ctx_id,
           { "Context ID", "dcerpc.cn_ctx_id", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
         { &hf_dcerpc_cn_num_trans_items,
           { "Num Trans Items", "dcerpc.cn_num_trans_items", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
+        { &hf_dcerpc_cn_bind_abstract_syntax,
+          { "Abstract Syntax", "dcerpc.cn_bind_abstract_syntax", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
         { &hf_dcerpc_cn_bind_if_id,
-          { "Interface UUID", "dcerpc.cn_bind_to_uuid", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
+          { "Interface UUID", "dcerpc.cn_bind_to_uuid", FT_GUID, BASE_NONE, NULL, 0x0, "", HFILL }},
         { &hf_dcerpc_cn_bind_if_ver,
           { "Interface Ver", "dcerpc.cn_bind_if_ver", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
         { &hf_dcerpc_cn_bind_if_ver_minor,
           { "Interface Ver Minor", "dcerpc.cn_bind_if_ver_minor", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
+        { &hf_dcerpc_cn_bind_trans_syntax,
+          { "Transfer Syntax", "dcerpc.cn_bind_trans", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
         { &hf_dcerpc_cn_bind_trans_id,
-          { "Transfer Syntax", "dcerpc.cn_bind_trans_id", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
+          { "ID", "dcerpc.cn_bind_trans_id", FT_GUID, BASE_NONE, NULL, 0x0, "", HFILL }},
         { &hf_dcerpc_cn_bind_trans_ver,
-          { "Syntax ver", "dcerpc.cn_bind_trans_ver", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
+          { "ver", "dcerpc.cn_bind_trans_ver", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
         { &hf_dcerpc_cn_alloc_hint,
           { "Alloc hint", "dcerpc.cn_alloc_hint", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
         { &hf_dcerpc_cn_sec_addr_len,
@@ -5196,7 +5151,7 @@ proto_register_dcerpc (void)
         { &hf_dcerpc_cn_ack_reason,
           { "Ack reason", "dcerpc.cn_ack_reason", FT_UINT16, BASE_DEC, VALS(p_provider_reason_vals), 0x0, "", HFILL }},
         { &hf_dcerpc_cn_ack_trans_id,
-          { "Transfer Syntax", "dcerpc.cn_ack_trans_id", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
+          { "Transfer Syntax", "dcerpc.cn_ack_trans_id", FT_GUID, BASE_NONE, NULL, 0x0, "", HFILL }},
         { &hf_dcerpc_cn_ack_trans_ver,
           { "Syntax ver", "dcerpc.cn_ack_trans_ver", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
         { &hf_dcerpc_cn_reject_reason,
@@ -5286,11 +5241,11 @@ proto_register_dcerpc (void)
         { &hf_dcerpc_krb5_av_key_auth_verifier,
           { "Authentication Verifier", "dcerpc.krb5_av.auth_verifier", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
         { &hf_dcerpc_obj_id,
-          { "Object", "dcerpc.obj_id", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
+          { "Object", "dcerpc.obj_id", FT_GUID, BASE_NONE, NULL, 0x0, "", HFILL }},
         { &hf_dcerpc_dg_if_id,
-          { "Interface", "dcerpc.dg_if_id", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
+          { "Interface", "dcerpc.dg_if_id", FT_GUID, BASE_NONE, NULL, 0x0, "", HFILL }},
         { &hf_dcerpc_dg_act_id,
-          { "Activity", "dcerpc.dg_act_id", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
+          { "Activity", "dcerpc.dg_act_id", FT_GUID, BASE_NONE, NULL, 0x0, "", HFILL }},
         { &hf_dcerpc_opnum,
           { "Opnum", "dcerpc.opnum", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
 
@@ -5386,6 +5341,7 @@ proto_register_dcerpc (void)
         &ett_dcerpc_cn_flags,
         &ett_dcerpc_cn_ctx,
         &ett_dcerpc_cn_iface,
+        &ett_dcerpc_cn_trans_syntax,
         &ett_dcerpc_drep,
         &ett_dcerpc_dg_flags1,
         &ett_dcerpc_dg_flags2,