summaryrefslogtreecommitdiff
path: root/epan/dissectors/packet-dcom.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-dcom.c')
-rw-r--r--epan/dissectors/packet-dcom.c224
1 files changed, 146 insertions, 78 deletions
diff --git a/epan/dissectors/packet-dcom.c b/epan/dissectors/packet-dcom.c
index e38728f339..f399057ae1 100644
--- a/epan/dissectors/packet-dcom.c
+++ b/epan/dissectors/packet-dcom.c
@@ -215,8 +215,13 @@ static int hf_dcom_vt_bstr = -1;
static int hf_dcom_vt_byref = -1;
static int hf_dcom_vt_dispatch = -1;
-static e_uuid_t uuid_debug_ext = { 0xf1f19680, 0x4d2a, 0x11ce, { 0xa6, 0x6a, 0x00, 0x20, 0xaf, 0x6e, 0x72, 0xf4} };
-static e_uuid_t uuid_ext_error_ext = { 0xf1f19681, 0x4d2a, 0x11ce, { 0xa6, 0x6a, 0x00, 0x20, 0xaf, 0x6e, 0x72, 0xf4} };
+static e_uuid_t uuid_debug_ext = { 0xf1f19680, 0x4d2a, 0x11ce, { 0xa6, 0x6a, 0x00, 0x20, 0xaf, 0x6e, 0x72, 0xf4} };
+static e_uuid_t uuid_ext_error_ext ={ 0xf1f19681, 0x4d2a, 0x11ce, { 0xa6, 0x6a, 0x00, 0x20, 0xaf, 0x6e, 0x72, 0xf4} };
+
+static e_uuid_t ipid_rem_unknown = { 0x00000131, 0x1234, 0x5678, { 0xCA, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} };
+static e_uuid_t iid_unknown = { 0x00000000, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} };
+static e_uuid_t uuid_null = { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} };
+static e_uuid_t iid_class_factory = { 0x00000001, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} };
GList *dcom_machines;
GList *dcom_interfaces;
@@ -227,66 +232,7 @@ static const value_string dcom_thisthat_flag_vals[] = {
};
-typedef struct _guid_key {
- e_guid_t guid;
-} guid_key;
-
-typedef struct _guid_value {
- const gchar *name;
- void *private_data;
-} guid_value;
-
-
-GHashTable *guids=NULL;
-
-static gint
-guid_equal (gconstpointer k1, gconstpointer k2)
-{
- const guid_key *key1 = (const guid_key *)k1;
- const guid_key *key2 = (const guid_key *)k2;
- return ((memcmp (&key1->guid, &key2->guid, sizeof (e_guid_t)) == 0));
-}
-
-static guint
-guid_hash (gconstpointer k)
-{
- const guid_key *key = (const guid_key *)k;
- /* This isn't perfect, but the Data1 part of these is almost always
- unique. */
- return key->guid.data1;
-}
-
-
-void guid_add_name(e_guid_t *guid, gchar *name, void *private_data)
-{
- guid_key *key = g_malloc (sizeof (*key));
- guid_value *value = g_malloc (sizeof (*value));
-
- key->guid = *guid;
-
- value->name = name;
- value->private_data = private_data;
-
- g_hash_table_insert (guids, key, value);
-}
-
-
-/* try to get registered name for this guid */
-const gchar *guid_get_name(e_guid_t *guid)
-{
- guid_key key;
- guid_value *value;
-
-
- /* try to get registered guid "name" of if_id */
- key.guid = *guid;
-
- if ((value = g_hash_table_lookup (guids, &key)) != NULL) {
- return value->name;
- }
-
- return NULL;
-}
+GHashTable *dcom_uuids=NULL;
void dcom_interface_dump(void) {
@@ -781,7 +727,7 @@ dissect_dcom_extent(tvbuff_t *tvb, int offset,
hf_dcom_extent_id, &uuidExtend);
/* look for a registered uuid name */
- if((uuid_name = guid_get_name( (e_guid_t *) &uuidExtend)) != NULL) {
+ if((uuid_name = guids_get_guid_name(dcom_uuids, (e_guid_t *) &uuidExtend)) != NULL) {
proto_tree_add_guid_format_value(sub_tree, hf_dcom_extent_id, tvb,
offset, sizeof(e_uuid_t), (e_guid_t *) &uuidExtend, "%s (%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
uuid_name,
@@ -1481,29 +1427,145 @@ dissect_dcom_VARIANT(tvbuff_t *tvb, int offset, packet_info *pinfo,
int
+dissect_dcom_UUID(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep,
+ int hfindex, e_uuid_t *pdata)
+{
+ const gchar *uuid_name;
+ proto_item *pi;
+ header_field_info *hfi;
+ e_uuid_t uuid;
+#ifdef _WIN32
+ char uuid_name2[MAX_PATH];
+#endif
+
+ /* XXX - this is far from being performance optimized! */
+
+ /* get the UUID, but don't put it into the tree */
+ offset = dissect_ndr_uuid_t(tvb, offset, pinfo, NULL, drep,
+ hfindex, &uuid);
+
+ /* look for a registered uuid name */
+ uuid_name = dcerpc_get_uuid_name(&uuid, 0);
+ if(uuid_name == NULL) {
+ uuid_name = guids_get_guid_name(dcom_uuids, (e_guid_t *) &uuid);
+ }
+
+#ifdef _WIN32
+ if(uuid_name == NULL && ResolveWin32UUID(uuid, uuid_name2, MAX_PATH)) {
+ uuid_name = uuid_name2;
+ }
+#endif
+
+ /* add to the tree */
+ hfi = proto_registrar_get_nth(hfindex);
+ pi = proto_tree_add_guid_format(tree, hfindex, tvb, offset-16, 16, (e_guid_t *) &uuid, "%s: ", hfi->name);
+
+ /* give an expert info, if UUID is not known and not of a "temporary" kind */
+ if( uuid_name == NULL &&
+ strcmp(hfi->name, "Causality ID") != 0 &&
+ strcmp(hfi->name, "IPID") != 0)
+ {
+ expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_NOTE, "unknown %s: %s",
+ hfi->name, guid_to_str( (e_guid_t *) &uuid));
+ }
+
+ if(uuid_name) {
+ proto_item_append_text(pi, "%s (", uuid_name);
+ }
+
+ proto_item_append_text(pi, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ 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(uuid_name) {
+ proto_item_append_text(pi, ")", uuid_name);
+ }
+
+ if(pdata != NULL) {
+ *pdata = uuid;
+ }
+
+ return offset;
+}
+
+
+int
dissect_dcom_append_UUID(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep,
- int hfindex, const gchar *field_name, int field_index, e_uuid_t *uuid)
+ int hfindex, int field_index, e_uuid_t *uuid)
{
const gchar *uuid_name;
+ proto_item *pi;
+ header_field_info *hfi;
+#ifdef _WIN32
+ char uuid_name2[MAX_PATH];
+#endif
+
+ /* XXX - this is far from being performance optimized! */
- offset = dissect_dcom_UUID(tvb, offset, pinfo, tree, drep,
+ /* get the UUID, but don't put it into the tree */
+ offset = dissect_ndr_uuid_t(tvb, offset, pinfo, NULL, drep,
hfindex, uuid);
- /* update column info now */
- if (check_col(pinfo->cinfo, COL_INFO)) {
- /* XXX: improve it: getting the hash value is done the second time here */
+ /* look for a registered uuid name */
+ uuid_name = dcerpc_get_uuid_name(uuid, 0);
+ if(uuid_name == NULL) {
+ uuid_name = guids_get_guid_name(dcom_uuids, (e_guid_t *) uuid);
+ }
+
+#ifdef _WIN32
+ if(uuid_name == NULL && ResolveWin32UUID(uuid, uuid_name2, MAX_PATH)) {
+ uuid_name = uuid_name2;
+ }
+#endif
+
+ /* add to the tree */
+ hfi = proto_registrar_get_nth(hfindex);
+ pi = proto_tree_add_guid_format(tree, hfindex, tvb, offset-16, 16, (e_guid_t *) uuid, "%s", hfi->name);
- /* look for a registered uuid name */
- uuid_name = dcerpc_get_uuid_name(uuid, 0);
+ /* give an expert info, if UUID is not known and not of a "temporary" kind */
+ if( uuid_name == NULL &&
+ strcmp(hfi->name, "Causality ID") != 0 &&
+ strcmp(hfi->name, "IPID") != 0)
+ {
+ expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_NOTE, "unknown %s: %s",
+ hfi->name, guid_to_str( (e_guid_t *) uuid));
+ }
+
+ if (field_index != -1) {
+ proto_item_append_text(pi, "[%u]: ", field_index);
+ } else {
+ proto_item_append_text(pi, ": ", field_index);
+ }
+ if(uuid_name) {
+ proto_item_append_text(pi, "%s (", uuid_name);
+ }
+
+ proto_item_append_text(pi, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ 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(uuid_name) {
+ proto_item_append_text(pi, ")", uuid_name);
+ }
+
+ /* update column info now */
+ if (check_col(pinfo->cinfo, COL_INFO)) {
if (field_index != -1) {
col_append_fstr(pinfo->cinfo, COL_INFO, " %s[%u]=%s",
- field_name, field_index, (uuid_name) ? uuid_name : "???");
+ hfi->name, field_index, (uuid_name) ? uuid_name : "???");
} else {
col_append_fstr(pinfo->cinfo, COL_INFO, " %s=%s",
- field_name, (uuid_name) ? uuid_name : "???");
+ hfi->name, (uuid_name) ? uuid_name : "???");
}
}
@@ -1724,6 +1786,7 @@ dissect_dcom_DUALSTRINGARRAY(tvbuff_t *tvb, gint offset, packet_info *pinfo,
guint32 first_ip = 0;
guint32 curr_ip = 0;
struct in_addr ipaddr;
+ proto_item *pi;
/* add subtree header */
@@ -1750,7 +1813,7 @@ dissect_dcom_DUALSTRINGARRAY(tvbuff_t *tvb, gint offset, packet_info *pinfo,
u32Start = offset;
/* we don't know the (zero terminated) input length, use the buffer length instead */
offset = dcom_tvb_get_nwstringz0(tvb, offset, u32MaxStr, szStr, u32MaxStr, &isPrintable);
- proto_tree_add_string(subsub_tree, hf_dcom_dualstringarray_string_network_addr,
+ pi = proto_tree_add_string(subsub_tree, hf_dcom_dualstringarray_string_network_addr,
tvb, u32Start, offset - u32Start, szStr);
/* convert ip address (if it is dotted decimal) */
@@ -1769,7 +1832,7 @@ dissect_dcom_DUALSTRINGARRAY(tvbuff_t *tvb, gint offset, packet_info *pinfo,
first_ip = curr_ip;
} else {
if(first_ip != curr_ip) {
- expert_add_info_format(pinfo, NULL, PI_UNDECODED, PI_NOTE,
+ expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_NOTE,
"DUALSTRINGARRAY: multiple IP's %s %s",
ip_to_str( (char *) &first_ip), ip_to_str( (char *) &curr_ip));
}
@@ -2262,10 +2325,15 @@ proto_register_dcom (void)
proto_register_field_array(proto_dcom, hf_dcom_sa_array, array_length(hf_dcom_sa_array));
proto_register_subtree_array (ett_dcom, array_length (ett_dcom));
- guids = g_hash_table_new (guid_hash, guid_equal);
- guid_add_name( (e_guid_t *) &uuid_debug_ext, "Debug Information Body Extension", NULL);
- guid_add_name( (e_guid_t *) &uuid_ext_error_ext, "Extended Error Info Body Extension", NULL);
-
+ /* register some "well known" UUID's */
+ dcom_uuids = guids_new();
+ guids_add_guid(dcom_uuids, (e_guid_t *) &uuid_debug_ext, "Debug Information Body Extension", NULL);
+ guids_add_guid(dcom_uuids, (e_guid_t *) &uuid_ext_error_ext, "Extended Error Info Body Extension", NULL);
+ guids_add_guid(dcom_uuids, (e_guid_t *) &ipid_rem_unknown, "IRemUnknown", NULL);
+ guids_add_guid(dcom_uuids, (e_guid_t *) &iid_unknown, "IUnknown", NULL);
+ guids_add_guid(dcom_uuids, (e_guid_t *) &uuid_null, "NULL", NULL);
+ guids_add_guid(dcom_uuids, (e_guid_t *) &iid_class_factory, "IClassFactory", NULL);
+
/* preferences */
dcom_module = prefs_register_protocol(proto_dcom, proto_reg_handoff_dcom);