summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-dcom-cba-acco.c1598
-rw-r--r--epan/dissectors/packet-dcom-cba-acco.h50
-rw-r--r--epan/dissectors/packet-dcom-cba.c100
-rw-r--r--epan/dissectors/packet-dcom-dispatch.c2
-rw-r--r--epan/dissectors/packet-dcom-oxid.c4
-rw-r--r--epan/dissectors/packet-dcom-remact.c28
-rw-r--r--epan/dissectors/packet-dcom-remunkn.c64
-rw-r--r--epan/dissectors/packet-dcom-sysact.c4
-rw-r--r--epan/dissectors/packet-dcom.c313
-rw-r--r--epan/dissectors/packet-dcom.h52
10 files changed, 2076 insertions, 139 deletions
diff --git a/epan/dissectors/packet-dcom-cba-acco.c b/epan/dissectors/packet-dcom-cba-acco.c
index c2d7b351bb..10468460bb 100644
--- a/epan/dissectors/packet-dcom-cba-acco.c
+++ b/epan/dissectors/packet-dcom-cba-acco.c
@@ -34,6 +34,8 @@
#include <glib.h>
#include <epan/packet.h>
#include <epan/expert.h>
+#include <epan/emem.h>
+#include <epan/addr_resolv.h>
#include "packet-dcerpc.h"
#include "packet-dcom.h"
#include "packet-dcom-cba-acco.h"
@@ -73,6 +75,14 @@ static int hf_cba_acco_cb_item_hole = -1;
static int hf_cba_acco_cb_item_length = -1;
static int hf_cba_acco_cb_item_data = -1;
+static int hf_cba_connect_in = -1;
+static int hf_cba_disconnect_in = -1;
+static int hf_cba_connectcr_in = -1;
+static int hf_cba_disconnectcr_in = -1;
+static int hf_cba_disconnectme_in = -1;
+static int hf_cba_data_first_in = -1;
+static int hf_cba_data_last_in = -1;
+
static int hf_cba_acco_server_pICBAAccoCallback = -1;
static int hf_cba_acco_server_first_connect = -1;
@@ -136,6 +146,8 @@ gint ett_cba_getconnectionout = -1;
gint ett_cba_readitemout = -1;
gint ett_cba_writeitemin = -1;
gint ett_cba_acco_serversrt_cr_flags = -1;
+gint ett_cba_frame_info = -1;
+gint ett_cba_conn_info = -1;
static int proto_ICBAAccoMgt = -1;
static gint ett_ICBAAccoMgt = -1;
@@ -240,6 +252,788 @@ static const true_false_string cba_acco_call_flags = {
"Provider calls Consumer (FALSE)"
};
+static const value_string cba_qos_type_short_vals[] = {
+ { 0x00, "DCOM" },
+ { 0x01, "DCOM(sec)" }, /* obsolete */
+ { 0x02, "Status" },
+ { 0x03, "HMI" },
+ { 0x20, "Const" },
+ { 0x30, "SRT" },
+ { 0, NULL }
+};
+
+
+typedef struct cba_frame_s {
+ cba_ldev_t *consparent;
+ cba_ldev_t *provparent;
+ GList *conns;
+ guint packet_connect;
+ guint packet_disconnect;
+ guint packet_disconnectme;
+ guint packet_first;
+ guint packet_last;
+
+ guint16 length;
+ const guint8 consmac[6];
+ guint16 conscrid;
+ guint32 provcrid;
+ guint32 conncrret;
+ guint16 qostype;
+ guint16 qosvalue;
+ guint16 offset;
+} cba_frame_t;
+
+typedef struct cba_connection_s {
+ cba_ldev_t *consparentacco;
+ cba_ldev_t *provparentacco;
+ cba_frame_t *parentframe;
+ guint packet_connect;
+ guint packet_disconnect;
+ guint packet_disconnectme;
+ guint packet_first;
+ guint packet_last;
+
+ guint16 length;
+ guint32 consid;
+ guint32 provid;
+ const gchar *provitem;
+ guint32 connret;
+ guint16 typedesclen;
+ guint16 *typedesc;
+ guint16 qostype;
+ guint16 qosvalue;
+ guint16 frame_offset;
+} cba_connection_t;
+
+
+typedef struct server_frame_call_s {
+ guint frame_count;
+ cba_frame_t **frames;
+} server_frame_call_t;
+
+
+typedef struct server_connect_call_s {
+ guint conn_count;
+ cba_frame_t *frame;
+ cba_connection_t **conns;
+} server_connect_call_t;
+
+typedef struct server_disconnectme_call_s {
+ cba_ldev_t *cons;
+ cba_ldev_t *prov;
+} server_disconnectme_call_t;
+
+
+GList *cba_pdevs;
+
+
+void
+cba_connection_dump(cba_connection_t *conn, char *role)
+{
+ if(conn->qostype != 0x30) {
+ g_warning(" %s#%5u: CID:0x%8x PID:0x%8x PItem:\"%s\" Type:%s QoS:%s/%u Ret:%s Data#%5u-#%5u",
+ role,
+ conn->packet_connect,
+ conn->consid, conn->provid, conn->provitem,
+ conn->typedesclen != 0 ? val_to_str(conn->typedesc[0], dcom_variant_type_vals, "Unknown (0x%08x)") : "-",
+ val_to_str(conn->qostype, cba_qos_type_short_vals, "0x%x"), conn->qosvalue,
+ conn->connret==-1 ? "[pending]" : val_to_str(conn->connret, dcom_hresult_vals, "Unknown (0x%08x)"),
+ conn->packet_first, conn->packet_last);
+ } else {
+ g_warning(" %s#%5u: CID:0x%8x PID:0x%8x PItem:\"%s\" Type:%s QoS:%s/%u Ret:%s Off:%u",
+ role,
+ conn->packet_connect,
+ conn->consid, conn->provid, conn->provitem,
+ conn->typedesclen != 0 ? val_to_str(conn->typedesc[0], dcom_variant_type_vals, "Unknown (0x%08x)") : "-",
+ val_to_str(conn->qostype, cba_qos_type_short_vals, "0x%x"), conn->qosvalue,
+ conn->connret==-1 ? "[pending]" : val_to_str(conn->connret, dcom_hresult_vals, "Unknown (0x%08x)"),
+ conn->frame_offset);
+ }
+}
+
+
+void
+cba_object_dump(void)
+{
+ GList *pdevs;
+ GList *ldevs;
+ GList *frames;
+ GList *conns;
+ cba_pdev_t *pdev;
+ cba_ldev_t *ldev;
+ cba_frame_t *frame;
+
+
+
+
+ for(pdevs = cba_pdevs; pdevs != NULL; pdevs = g_list_next(pdevs)) {
+ pdev = pdevs->data;
+ g_warning("PDev #%5u: %s IFs:%u", pdev->first_packet, ip_to_str(pdev->ip),
+ pdev->object ? g_list_length(pdev->object->interfaces) : 0);
+
+ for(ldevs = pdev->ldevs; ldevs != NULL; ldevs = g_list_next(ldevs)) {
+ ldev = ldevs->data;
+ g_warning(" LDev#%5u: \"%s\" LDevIFs:%u AccoIFs:%u", ldev->first_packet, ldev->name,
+ ldev->ldev_object ? g_list_length(ldev->ldev_object->interfaces) : 0,
+ ldev->acco_object ? g_list_length(ldev->acco_object->interfaces) : 0);
+ for(frames = ldev->consframes; frames != NULL; frames = g_list_next(frames)) {
+ frame = frames->data;
+ g_warning(" ConsFrame#%5u: CCRID:0x%x PCRID:0x%x Len:%u Ret:%s Data#%5u-#%5u",
+ frame->packet_connect, frame->conscrid, frame->provcrid, frame->length,
+ frame->conncrret==-1 ? "[pending]" : val_to_str(frame->conncrret, dcom_hresult_vals, "Unknown (0x%08x)"),
+ frame->packet_first, frame->packet_last);
+ for(conns = frame->conns; conns != NULL; conns = g_list_next(conns)) {
+ cba_connection_dump(conns->data, "ConsConn");
+ }
+ }
+ for(frames = ldev->provframes; frames != NULL; frames = g_list_next(frames)) {
+ frame = frames->data;
+ g_warning(" ProvFrame#%5u: CCRID:0x%x PCRID:0x%x Len:%u Ret:%s Data#%5u-#%5u",
+ frame->packet_connect, frame->conscrid, frame->provcrid, frame->length,
+ frame->conncrret==-1 ? "[pending]" : val_to_str(frame->conncrret, dcom_hresult_vals, "Unknown (0x%08x)"),
+ frame->packet_first, frame->packet_last);
+ for(conns = frame->conns; conns != NULL; conns = g_list_next(conns)) {
+ cba_connection_dump(conns->data, "ProvConn");
+ }
+ }
+ for(conns = ldev->consconns; conns != NULL; conns = g_list_next(conns)) {
+ cba_connection_dump(conns->data, "ConsConn");
+ }
+ for(conns = ldev->provconns; conns != NULL; conns = g_list_next(conns)) {
+ cba_connection_dump(conns->data, "ProvConn");
+ }
+ }
+ }
+}
+
+
+cba_pdev_t *
+cba_pdev_find(packet_info *pinfo, const char *ip, e_uuid_t *ipid)
+{
+ cba_pdev_t *pdev;
+ dcom_interface_t *interf;
+
+
+ interf = dcom_interface_find(pinfo, ip, ipid);
+ if(interf != NULL) {
+ pdev = interf->parent->private_data;
+ if(pdev == NULL) {
+ expert_add_info_format(pinfo, NULL, PI_UNDECODED, PI_WARN, "pdev_find: no pdev for IP:%s IPID:%s",
+ ip_to_str(ip), dcom_uuid_to_str(ipid));
+ }
+ } else {
+ expert_add_info_format(pinfo, NULL, PI_UNDECODED, PI_WARN, "pdev_find: unknown interface of IP:%s IPID:%s",
+ ip_to_str(ip), dcom_uuid_to_str(ipid));
+ pdev = NULL;
+ }
+
+ return pdev;
+}
+
+
+cba_pdev_t *
+cba_pdev_add(packet_info *pinfo, const char *ip)
+{
+ GList *cba_iter;
+ cba_pdev_t *pdev;
+
+
+ /* find pdev */
+ for(cba_iter = cba_pdevs; cba_iter != NULL; cba_iter = g_list_next(cba_iter)) {
+ pdev = cba_iter->data;
+ if(memcmp(pdev->ip, ip, 4) == 0) {
+ return pdev;
+ }
+ }
+
+ /* not found, create a new */
+ pdev = se_alloc(sizeof(cba_pdev_t));
+ memcpy( (void *) (pdev->ip), ip, 4);
+ pdev->first_packet = pinfo->fd->num;
+ pdev->ldevs = NULL;
+ pdev->object = NULL;
+ cba_pdevs = g_list_append(cba_pdevs, pdev);
+
+ return pdev;
+}
+
+
+void
+cba_pdev_link(packet_info *pinfo, cba_pdev_t *pdev, dcom_interface_t *pdev_interf)
+{
+
+ /* "crosslink" pdev interface and it's object */
+ pdev->object = pdev_interf->parent;
+ pdev_interf->private_data = pdev;
+ if(pdev_interf->parent) {
+ pdev_interf->parent->private_data = pdev;
+ }
+}
+
+
+void
+cba_ldev_link(packet_info *pinfo, cba_ldev_t *ldev, dcom_interface_t *ldev_interf)
+{
+
+ /* "crosslink" interface and it's object */
+ ldev->ldev_object = ldev_interf->parent;
+ ldev_interf->private_data = ldev;
+ if(ldev_interf->parent) {
+ ldev_interf->parent->private_data = ldev;
+ }
+}
+
+
+void
+cba_ldev_link_acco(packet_info *pinfo, cba_ldev_t *ldev, dcom_interface_t *acco_interf)
+{
+
+ /* "crosslink" interface and it's object */
+ ldev->acco_object = acco_interf->parent;
+ acco_interf->private_data = ldev;
+ if(acco_interf->parent) {
+ acco_interf->parent->private_data = ldev;
+ }
+}
+
+
+cba_ldev_t *
+cba_ldev_add(packet_info *pinfo, cba_pdev_t *pdev, const char *name)
+{
+ GList *cba_iter;
+ cba_ldev_t *ldev;
+
+
+ /* find ldev */
+ for(cba_iter = pdev->ldevs; cba_iter != NULL; cba_iter = g_list_next(cba_iter)) {
+ ldev = cba_iter->data;
+ if(strcmp(ldev->name, name) == 0) {
+ return ldev;
+ }
+ }
+
+ /* not found, create a new */
+ ldev = se_alloc(sizeof(cba_ldev_t));
+ ldev->name = se_strdup(name);
+ ldev->first_packet = pinfo->fd->num;
+ ldev->ldev_object = NULL;
+ ldev->acco_object = NULL;
+ ldev->parent = pdev;
+
+ ldev->provframes = NULL;
+ ldev->consframes = NULL;
+ ldev->provconns = NULL;
+ ldev->consconns = NULL;
+
+ pdev->ldevs = g_list_append(pdev->ldevs, ldev);
+
+ return ldev;
+}
+
+
+cba_ldev_t *
+cba_ldev_find(packet_info *pinfo, const gchar *ip, e_uuid_t *ipid) {
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ dcom_interface_t *interf;
+ cba_ldev_t *ldev;
+
+
+ interf = dcom_interface_find(pinfo, ip, ipid);
+ if(interf != NULL) {
+ ldev = interf->private_data;
+
+ if(ldev == NULL) {
+ ldev = interf->parent->private_data;
+ }
+ if(ldev == NULL) {
+ expert_add_info_format(pinfo, NULL, PI_UNDECODED, PI_WARN, "ldev_find: no ldev for IP:%s IPID:%s",
+ ip_to_str(ip), dcom_uuid_to_str(&info->call_data->object_uuid));
+ }
+ } else {
+ expert_add_info_format(pinfo, NULL, PI_UNDECODED, PI_WARN, "ldev_find: unknown interface of IP:%s IPID:%s",
+ ip_to_str(ip), dcom_uuid_to_str(&info->call_data->object_uuid));
+ ldev = NULL;
+ }
+
+ /*g_warning("cba_ldev_find#%u: private:0x%x parent:0x%x",
+ pinfo->fd->num, interf->private_data, interf->parent ? interf->parent->private_data: NULL);*/
+
+ return ldev;
+}
+
+
+cba_ldev_t *
+cba_acco_add(packet_info *pinfo, const char *acco)
+{
+ char *ip_str;
+ char *delim;
+ guint32 ip;
+ cba_pdev_t *pdev;
+ cba_ldev_t *ldev;
+
+
+ ip_str = g_strdup(acco);
+ delim = strchr(ip_str, '!');
+ if(delim == NULL) {
+ g_free(ip_str);
+ return NULL;
+ }
+ *delim = 0;
+
+ if(!get_host_ipaddr(ip_str, &ip)) {
+ g_free(ip_str);
+ return NULL;
+ }
+ ip = ntohl(ip);
+
+ pdev = cba_pdev_add(pinfo, (char *) &ip);
+ delim++;
+
+ ldev = cba_ldev_add(pinfo, pdev, delim);
+
+ g_free(ip_str);
+
+ return ldev;
+}
+
+
+gboolean
+cba_packet_in_range(packet_info *pinfo, guint packet_connect, guint packet_disconnect, guint packet_disconnectme)
+{
+
+ if(packet_connect == 0) {
+ g_warning("cba_packet_in_range#%u: packet_connect not set?", pinfo->fd->num);
+ }
+
+ if(packet_connect == 0 || pinfo->fd->num < packet_connect) {
+ return FALSE;
+ }
+ if(packet_disconnect != 0 && pinfo->fd->num > packet_disconnect) {
+ return FALSE;
+ }
+ if(packet_disconnectme != 0 && pinfo->fd->num > packet_disconnectme) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+void
+cba_frame_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, cba_frame_t *frame)
+{
+ proto_item *item;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ if (tree) {
+ sub_item = proto_tree_add_text(tree, tvb, 0, 0, "Cons:\"%s\" CCRID:0x%x Prov:\"%s\" PCRID:0x%x QoS:%s/%ums Len:%u",
+ frame->consparent ? frame->consparent->name : "", frame->conscrid,
+ frame->provparent ? frame->provparent->name : "", frame->provcrid,
+ val_to_str(frame->qostype, cba_qos_type_short_vals, "%u"), frame->qosvalue, frame->length);
+ sub_tree = proto_item_add_subtree(sub_item, ett_cba_frame_info);
+ PROTO_ITEM_SET_GENERATED(sub_item);
+
+ item = proto_tree_add_uint(sub_tree, hf_cba_acco_conn_qos_type, tvb, 0, 0, frame->qostype);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_acco_conn_qos_value, tvb, 0, 0, frame->qosvalue);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_acco_serversrt_cr_id, tvb, 0, 0, frame->conscrid);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_acco_prov_crid, tvb, 0, 0, frame->provcrid);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_acco_serversrt_cr_length, tvb, 0, 0, frame->length);
+ PROTO_ITEM_SET_GENERATED(item);
+
+ if(frame->consparent != NULL) {
+ item = proto_tree_add_string(sub_tree, hf_cba_acco_conn_consumer, tvb, 0, 0, frame->consparent->name);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
+ if(frame->provparent != NULL) {
+ item = proto_tree_add_string(sub_tree, hf_cba_acco_conn_provider, tvb, 0, 0, frame->provparent->name);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
+
+ item = proto_tree_add_uint(sub_tree, hf_cba_connectcr_in,
+ tvb, 0, 0, frame->packet_connect);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_data_first_in,
+ tvb, 0, 0, frame->packet_first);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_data_last_in,
+ tvb, 0, 0, frame->packet_last);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_disconnectcr_in,
+ tvb, 0, 0, frame->packet_disconnect);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_disconnectme_in,
+ tvb, 0, 0, frame->packet_disconnectme);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
+}
+
+
+cba_frame_t *
+cba_frame_connect(packet_info *pinfo, cba_ldev_t *cons_ldev, cba_ldev_t *prov_ldev,
+ guint16 qostype, guint16 qosvalue, const guint8 *consmac, guint16 conscrid, guint16 length)
+{
+ GList *cba_iter;
+ cba_frame_t *frame;
+
+ /* find frame */
+ for(cba_iter = cons_ldev->consframes; cba_iter != NULL; cba_iter = g_list_next(cba_iter)) {
+ frame = cba_iter->data;
+ if( frame->conscrid == conscrid &&
+ memcmp(frame->consmac, consmac, 6) == 0 &&
+ cba_packet_in_range(pinfo, frame->packet_connect, frame->packet_disconnect, frame->packet_disconnectme)) {
+ return frame;
+ }
+ }
+
+ frame = se_alloc(sizeof(cba_frame_t));
+
+ frame->consparent = cons_ldev;
+ frame->provparent = prov_ldev;
+
+ frame->packet_connect = pinfo->fd->num;
+ frame->packet_disconnect = 0;
+ frame->packet_disconnectme = 0;
+ frame->packet_first = 0;
+ frame->packet_last = 0;
+
+ frame->length = length;
+ memcpy( (guint8 *) (frame->consmac), consmac, sizeof(frame->consmac));
+ frame->conscrid = conscrid;
+ frame->qostype = qostype;
+ frame->qosvalue = qosvalue;
+
+ frame->offset = 4;
+ frame->conns = NULL;
+
+ frame->provcrid = 0;
+ frame->conncrret = -1;
+
+ cons_ldev->consframes = g_list_append(cons_ldev->consframes, frame);
+ prov_ldev->provframes = g_list_append(prov_ldev->provframes, frame);
+
+ return frame;
+}
+
+
+void
+cba_frame_disconnect(packet_info *pinfo, cba_frame_t *frame)
+{
+
+ if(frame->packet_disconnect == 0) {
+ frame->packet_disconnect = pinfo->fd->num;
+ }
+
+ if(frame->packet_disconnect != pinfo->fd->num) {
+ g_warning("cba_frame_disconnect#%u: frame already disconnected in #%u",
+ pinfo->fd->num, frame->packet_disconnect);
+ }
+}
+
+
+void
+cba_frame_disconnectme(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, cba_ldev_t *cons_ldev, cba_ldev_t *prov_ldev)
+{
+ GList *frames;
+ cba_frame_t *frame;
+
+
+ for(frames = cons_ldev->consframes; frames != NULL; frames = g_list_next(frames)) {
+ frame = frames->data;
+
+ if( frame->provparent == prov_ldev &&
+ cba_packet_in_range(pinfo, frame->packet_connect, frame->packet_disconnect, frame->packet_disconnectme)) {
+
+ cba_frame_info(tvb, pinfo, tree, frame);
+
+ if(frame->packet_disconnectme == 0) {
+ frame->packet_disconnectme = pinfo->fd->num;
+ }
+
+ if(frame->packet_disconnectme != pinfo->fd->num) {
+ g_warning("cba_frame_disconnectme#%u: frame already disconnectme'd in #%u",
+ pinfo->fd->num, frame->packet_disconnectme);
+ }
+ }
+ }
+}
+
+
+cba_frame_t *
+cba_frame_find_by_cons(packet_info *pinfo, const guint8 *consmac, guint16 conscrid)
+{
+ GList *pdevs;
+ GList *ldevs;
+ GList *frames;
+ cba_pdev_t *pdev;
+ cba_ldev_t *ldev;
+ cba_frame_t *frame;
+
+
+ /* find pdev */
+ for(pdevs = cba_pdevs; pdevs != NULL; pdevs = g_list_next(pdevs)) {
+ pdev = pdevs->data;
+
+ /* find ldev */
+ for(ldevs = pdev->ldevs; ldevs != NULL; ldevs = g_list_next(ldevs)) {
+ ldev = ldevs->data;
+
+ /* find frame */
+ for(frames = ldev->consframes; frames != NULL; frames = g_list_next(frames)) {
+ frame = frames->data;
+
+ if( frame->conscrid == conscrid &&
+ memcmp(frame->consmac, consmac, 6) == 0 &&
+ cba_packet_in_range(pinfo, frame->packet_connect, frame->packet_disconnect, frame->packet_disconnectme)) {
+ return frame;
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+cba_frame_t *
+cba_frame_find_by_provcrid(packet_info *pinfo, cba_ldev_t *prov_ldev, guint32 provcrid)
+{
+ GList *frames;
+ cba_frame_t *frame;
+
+
+ if(prov_ldev == NULL) {
+ return NULL;
+ }
+
+ for(frames = prov_ldev->provframes; frames != NULL; frames = g_list_next(frames)) {
+ frame = frames->data;
+
+ if( frame->provcrid == provcrid &&
+ cba_packet_in_range(pinfo, frame->packet_connect, frame->packet_disconnect, frame->packet_disconnectme)) {
+ return frame;
+ }
+ }
+
+ expert_add_info_format(pinfo, NULL, PI_UNDECODED, PI_WARN,
+ "find_by_provcrid: couldn't find provider frame for ProvCRID:0x%x", provcrid);
+
+ return NULL;
+}
+
+
+void
+cba_frame_incoming_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, cba_frame_t *frame)
+{
+ if(frame->packet_first == 0) {
+ frame->packet_first = pinfo->fd->num;
+ }
+
+ if( pinfo->fd->num > frame->packet_last &&
+ cba_packet_in_range(pinfo, frame->packet_connect, frame->packet_disconnect, frame->packet_disconnectme)) {
+ frame->packet_last = pinfo->fd->num;
+ }
+}
+
+
+void
+cba_connection_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, cba_connection_t *conn)
+{
+ proto_item *item;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ if (tree) {
+ if(conn->qostype != 0x30) {
+ sub_item = proto_tree_add_text(tree, tvb, 0, 0, "ProvItem:\"%s\" PID:0x%x CID:0x%x QoS:%s/%ums",
+ conn->provitem, conn->provid, conn->consid,
+ val_to_str(conn->qostype, cba_qos_type_short_vals, "%u"), conn->qosvalue);
+ } else {
+ sub_item = proto_tree_add_text(tree, tvb, 0, 0, "ProvItem:\"%s\" PID:0x%x CID:0x%x Len:%u",
+ conn->provitem, conn->provid, conn->consid, conn->length);
+ }
+ sub_tree = proto_item_add_subtree(sub_item, ett_cba_conn_info);
+ PROTO_ITEM_SET_GENERATED(sub_item);
+
+ item = proto_tree_add_string(sub_tree, hf_cba_acco_conn_provider_item, tvb, 0, 0 /* len */, conn->provitem);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_acco_conn_prov_id, tvb, 0, 0 /* len */, conn->provid);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_acco_conn_cons_id, tvb, 0, 0 /* len */, conn->consid);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_acco_serversrt_record_length, tvb, 0, 0 /* len */, conn->length);
+ PROTO_ITEM_SET_GENERATED(item);
+
+ if(conn->qostype != 0x30) {
+ item = proto_tree_add_uint(sub_tree, hf_cba_acco_conn_qos_type,
+ tvb, 0, 0, conn->qostype);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_acco_conn_qos_value,
+ tvb, 0, 0, conn->qosvalue);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_connect_in,
+ tvb, 0, 0, conn->packet_connect);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_data_first_in,
+ tvb, 0, 0, conn->packet_first);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_data_last_in,
+ tvb, 0, 0, conn->packet_last);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_disconnect_in,
+ tvb, 0, 0, conn->packet_disconnect);
+ PROTO_ITEM_SET_GENERATED(item);
+ item = proto_tree_add_uint(sub_tree, hf_cba_disconnectme_in,
+ tvb, 0, 0, conn->packet_disconnectme);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
+ }
+}
+
+
+cba_connection_t *
+cba_connection_connect(packet_info *pinfo, cba_ldev_t *cons_ldev, cba_ldev_t *prov_ldev, cba_frame_t *cons_frame,
+ guint16 qostype, guint16 qosvalue, const char *provitem, guint32 consid, guint16 length,
+ guint16 *typedesc, guint16 typedesclen)
+{
+ GList *cba_iter;
+ cba_connection_t *conn;
+
+
+ /* find connection */
+ if(cons_frame != NULL) {
+ /* SRT: search in frame */
+ for(cba_iter = cons_frame->conns; cba_iter != NULL; cba_iter = g_list_next(cba_iter)) {
+ conn = cba_iter->data;
+ if(conn->consid == consid) {
+ return conn;
+ }
+ }
+ } else {
+ /* DCOM: search in ldev */
+ for(cba_iter = cons_ldev->consconns; cba_iter != NULL; cba_iter = g_list_next(cba_iter)) {
+ conn = cba_iter->data;
+ if( conn->consid == consid &&
+ cba_packet_in_range(pinfo, conn->packet_connect, conn->packet_disconnect, conn->packet_disconnectme)) {
+ return conn;
+ }
+ }
+ }
+
+ conn = se_alloc(sizeof(cba_connection_t));
+
+ conn->consparentacco = cons_ldev;
+ conn->provparentacco = prov_ldev;
+ conn->parentframe = cons_frame;
+
+ conn->packet_connect = pinfo->fd->num;
+ conn->packet_disconnect = 0;
+ conn->packet_disconnectme = 0;
+ conn->packet_first = 0;
+ conn->packet_last = 0;
+
+ conn->consid = consid;
+ conn->provitem = se_strdup(provitem);
+ conn->typedesclen = typedesclen;
+ conn->typedesc = typedesc;
+ conn->qostype = qostype;
+ conn->qosvalue = qosvalue;
+ conn->length = length;
+
+ conn->provid = 0;
+ conn->connret = -1;
+
+ if(cons_frame != NULL) {
+ conn->frame_offset = cons_frame->offset;
+ conn->length = length;
+ cons_frame->offset += length;
+ cons_frame->conns = g_list_append(cons_frame->conns, conn);
+ } else {
+ conn->frame_offset = 0;
+ cons_ldev->consconns = g_list_append(cons_ldev->consconns, conn);
+ prov_ldev->provconns = g_list_append(prov_ldev->provconns, conn);
+ }
+
+ return conn;
+}
+
+
+void
+cba_connection_disconnect(packet_info *pinfo, cba_connection_t *conn)
+{
+ /* XXX - detect multiple disconnects? */
+ if(conn->packet_disconnect == 0) {
+ conn->packet_disconnect = pinfo->fd->num;
+ }
+
+ if(conn->packet_disconnect != pinfo->fd->num) {
+ g_warning("connection_disconnect#%u: already disconnected");
+ }
+}
+
+
+void
+cba_connection_disconnectme(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, cba_ldev_t *cons_ldev, cba_ldev_t *prov_ldev)
+{
+ GList *conns;
+ cba_connection_t *conn;
+
+
+ for(conns = cons_ldev->consframes; conns != NULL; conns = g_list_next(conns)) {
+ conn = conns->data;
+
+ if( conn->provparentacco == prov_ldev &&
+ cba_packet_in_range(pinfo, conn->packet_connect, conn->packet_disconnect, conn->packet_disconnectme)) {
+
+ cba_connection_info(tvb, pinfo, tree, conn);
+
+ if(conn->packet_disconnectme == 0) {
+ conn->packet_disconnectme = pinfo->fd->num;
+ }
+
+ if(conn->packet_disconnectme != pinfo->fd->num) {
+ g_warning("connection_disconnectme#%u: already disconnectme'd");
+ }
+ }
+ }
+}
+
+
+cba_connection_t *
+cba_connection_find_by_provid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, cba_ldev_t *prov_ldev, guint32 provid)
+{
+ GList *cba_iter;
+ cba_connection_t *conn;
+
+
+ for(cba_iter = prov_ldev->provconns; cba_iter != NULL; cba_iter = g_list_next(cba_iter)) {
+ conn = cba_iter->data;
+ if( conn->provid == provid &&
+ cba_packet_in_range(pinfo, conn->packet_connect, conn->packet_disconnect, conn->packet_disconnectme)) {
+ return conn;
+ }
+ }
+ return NULL;
+}
+
+
+void
+cba_connection_incoming_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, cba_connection_t *conn)
+{
+ if(conn->packet_first == 0) {
+ conn->packet_first = pinfo->fd->num;
+ }
+
+ if( pinfo->fd->num > conn->packet_last &&
+ cba_packet_in_range(pinfo, conn->packet_connect, conn->packet_disconnect, conn->packet_disconnectme)) {
+ conn->packet_last = pinfo->fd->num;
+ }
+}
+
/* dissect a response containing an array of hresults (e.g: ICBAAccoMgt::RemoveConnections) */
static int
@@ -285,7 +1079,7 @@ dissect_HResultArray_resp(tvbuff_t *tvb, int offset,
static int
-dissect_ICBAAccoServer_HResultArray_resp(tvbuff_t *tvb, int offset,
+dissect_ICBAAccoServer_SetActivation_resp(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
guint32 u32HResult;
@@ -332,7 +1126,54 @@ dissect_ICBAAccoServer_HResultArray_resp(tvbuff_t *tvb, int offset,
static int
-dissect_ICBAAccoServerSRT_HResultArray_resp(tvbuff_t *tvb, int offset,
+dissect_ICBAAccoServerSRT_Disconnect_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint32 u32HResult;
+ guint32 u32Pointer;
+ guint32 u32ArraySize = 0;
+ guint32 u32Idx;
+ guint32 u32Tmp;
+ proto_item *item;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, drep);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE);
+ PROTO_ITEM_SET_GENERATED(item);
+ pinfo->profinet_type = 3;
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, drep,
+ &u32Pointer);
+
+ if (u32Pointer) {
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, drep,
+ &u32ArraySize);
+
+ u32Idx = 1;
+ u32Tmp = u32ArraySize;
+ while (u32Tmp--) {
+ offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, drep,
+ &u32HResult, u32Idx);
+ u32Idx++;
+ }
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep,
+ &u32HResult);
+
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s",
+ u32ArraySize,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+ }
+
+ return offset;
+}
+
+
+static int
+dissect_ICBAAccoServerSRT_SetActivation_resp(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
guint32 u32HResult;
@@ -401,10 +1242,19 @@ dissect_ICBAAccoServer_Connect_rqst(tvbuff_t *tvb, int offset,
guint32 u32MaxConsLen = sizeof(szCons);
guint32 u32Idx;
proto_item *item;
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ dcom_interface_t *cons_interf;
+ cba_ldev_t *cons_ldev;
+ cba_ldev_t *prov_ldev;
+ cba_connection_t *conn;
+ server_connect_call_t *call;
offset = dissect_dcom_this(tvb, offset, pinfo, tree, drep);
+ /* get corresponding provider ldev */
+ prov_ldev = cba_ldev_find(pinfo, pinfo->net_dst.data, &info->call_data->object_uuid);
+
item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE);
PROTO_ITEM_SET_GENERATED(item);
pinfo->profinet_type = 2;
@@ -412,6 +1262,9 @@ dissect_ICBAAccoServer_Connect_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, drep,
hf_cba_acco_conn_consumer, szCons, u32MaxConsLen);
+ /* find the consumer ldev by it's name */
+ cons_ldev = cba_acco_add(pinfo, szCons);
+
offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, drep,
hf_cba_acco_conn_qos_type, &u16QoSType);
offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, drep,
@@ -419,7 +1272,16 @@ dissect_ICBAAccoServer_Connect_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_BYTE(tvb, offset, pinfo, tree, drep,
hf_cba_acco_conn_state, &u8State);
- offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, drep, 0);
+ offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, drep, 0, &cons_interf);
+ if(cons_interf == NULL) {
+ expert_add_info_format(pinfo, NULL, PI_UNDECODED, PI_WARN,
+ "Server_Connect: consumer interface invalid");
+ }
+
+ /* "crosslink" consumer interface and it's object */
+ if(cons_interf != NULL && cons_ldev != NULL) {
+ cba_ldev_link_acco(pinfo, cons_ldev, cons_interf);
+ }
offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, drep,
hf_cba_acco_count, &u32Count);
@@ -427,6 +1289,17 @@ dissect_ICBAAccoServer_Connect_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, drep,
&u32ArraySize);
+ /* link connections infos to the call */
+ if(prov_ldev != NULL && cons_ldev != NULL) {
+ call = se_alloc(sizeof(server_connect_call_t) + u32ArraySize * sizeof(cba_connection_t *));
+ call->conn_count = 0;
+ call->frame = NULL;
+ call->conns = (cba_connection_t **) (call+1);
+ info->call_data->private_data = call;
+ } else{
+ call = NULL;
+ }
+
u32VariableOffset = offset + u32ArraySize*16;
/* array of CONNECTINs */
@@ -459,6 +1332,24 @@ dissect_ICBAAccoServer_Connect_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
hf_cba_acco_conn_cons_id, &u32ConsID);
+ /* add to object database */
+ if(prov_ldev != NULL && cons_ldev != NULL) {
+ conn = cba_connection_connect(pinfo, cons_ldev, prov_ldev, /*cons_frame*/ NULL,
+ u16QoSType, u16QoSValue, szItem, u32ConsID, 0,
+ /* XXX - VarType must be translated to new type description if it includes an array (0x2000) */
+ se_memdup(&u16VarType, 2), 1);
+
+ cba_connection_info(tvb, pinfo, sub_tree, conn);
+ } else {
+ conn = NULL;
+ }
+
+ /* add to current call */
+ if(call != NULL) {
+ call->conn_count++;
+ call->conns[u32Idx-1] = conn;
+ }
+
/* update subtree header */
proto_item_append_text(sub_item, "[%u]: ConsID=0x%x, ProvItem=\"%s\", VarType=%s",
u32Idx, u32ConsID, szItem,
@@ -502,10 +1393,20 @@ dissect_ICBAAccoServer2_Connect2_rqst(tvbuff_t *tvb, int offset,
guint32 u32Idx2;
guint16 u16VarType2 = -1;
proto_item *item;
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ dcom_interface_t *cons_interf;
+ cba_ldev_t *prov_ldev;
+ cba_ldev_t *cons_ldev;
+ cba_connection_t *conn;
+ server_connect_call_t *call = NULL;
+ guint16 typedesclen = 0;
+ guint16 *typedesc = NULL;
offset = dissect_dcom_this(tvb, offset, pinfo, tree, drep);
+ /* get corresponding provider ldev */
+ prov_ldev = cba_ldev_find(pinfo, pinfo->net_dst.data, &info->call_data->object_uuid);
item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE);
PROTO_ITEM_SET_GENERATED(item);
@@ -514,6 +1415,9 @@ dissect_ICBAAccoServer2_Connect2_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, drep,
hf_cba_acco_conn_consumer, szCons, u32MaxConsLen);
+ /* find the consumer ldev by it's name */
+ cons_ldev = cba_acco_add(pinfo, szCons);
+
offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, drep,
hf_cba_acco_conn_qos_type, &u16QoSType);
offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, drep,
@@ -521,7 +1425,23 @@ dissect_ICBAAccoServer2_Connect2_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_BYTE(tvb, offset, pinfo, tree, drep,
hf_cba_acco_conn_state, &u8State);
- offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, drep, 0);
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, drep, &u32Pointer);
+
+ if (u32Pointer) {
+ offset = dissect_dcom_MInterfacePointer(tvb, offset, pinfo, tree, drep, 0, &cons_interf);
+ if(cons_interf == NULL) {
+ expert_add_info_format(pinfo, NULL, PI_UNDECODED, PI_WARN,
+ "Server2_Connect2: consumer interface invalid");
+ }
+ } else {
+ /* GetConnectionData do it this way */
+ cons_interf = NULL;
+ }
+
+ /* "crosslink" consumer interface and it's object */
+ if(cons_interf != NULL && cons_ldev != NULL) {
+ cba_ldev_link_acco(pinfo, cons_ldev, cons_interf);
+ }
offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, drep,
hf_cba_acco_count, &u32Count);
@@ -529,6 +1449,17 @@ dissect_ICBAAccoServer2_Connect2_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, drep,
&u32ArraySize);
+ /* link connection infos to the call */
+ if(prov_ldev != NULL && cons_ldev != NULL) {
+ call = se_alloc(sizeof(server_connect_call_t) + u32ArraySize * sizeof(cba_connection_t *));
+ call->conn_count = 0;
+ call->frame = NULL;
+ call->conns = (cba_connection_t **) (call+1);
+ info->call_data->private_data = call;
+ } else{
+ call = NULL;
+ }
+
u32VariableOffset = offset + u32ArraySize*20;
/* array of CONNECTINs */
@@ -557,12 +1488,26 @@ dissect_ICBAAccoServer2_Connect2_rqst(tvbuff_t *tvb, int offset,
u32VariableOffset = dissect_dcom_dcerpc_array_size(tvb, u32VariableOffset, pinfo, sub_tree, drep,
&u32ArraySize2);
+ /* limit the allocation to a reasonable size */
+ if(u32ArraySize2 < 1000) {
+ typedesc = se_alloc0(u32ArraySize2 * 2);
+ typedesclen = u32ArraySize2;
+ } else {
+ typedesc = NULL;
+ typedesclen = 0;
+ }
+
/* extended type description will build an array here */
u32Idx2 = 1;
while (u32ArraySize2--) {
/* ToBeDone: some of the type description values are counts */
u32VariableOffset = dissect_dcom_VARTYPE(tvb, u32VariableOffset, pinfo, sub_tree, drep,
&u16VarType);
+
+ if(typedesc != NULL && u32Idx2 <= typedesclen) {
+ typedesc[u32Idx2-1] = u16VarType;
+ }
+
/* remember first VarType only */
if (u32Idx2 == 1) {
u16VarType2 = u16VarType;
@@ -582,6 +1527,23 @@ dissect_ICBAAccoServer2_Connect2_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
hf_cba_acco_conn_cons_id, &u32ConsID);
+ /* add to object database */
+ if(prov_ldev != NULL && cons_ldev != NULL) {
+ conn = cba_connection_connect(pinfo, cons_ldev, prov_ldev, /*cons_frame*/ NULL,
+ u16QoSType, u16QoSValue, szItem, u32ConsID, 0,
+ typedesc, typedesclen);
+
+ cba_connection_info(tvb, pinfo, sub_tree, conn);
+ } else {
+ conn = NULL;
+ }
+
+ /* add to current call */
+ if(call != NULL) {
+ call->conn_count++;
+ call->conns[u32Idx-1] = conn;
+ }
+
/* update subtree header */
proto_item_append_text(sub_item, "[%u]: ConsID=0x%x, ProvItem=\"%s\", TypeDesc=%s",
u32Idx, u32ConsID, szItem,
@@ -605,7 +1567,7 @@ dissect_ICBAAccoServer_Connect_resp(tvbuff_t *tvb, int offset,
{
guint8 u8FirstConnect;
guint32 u32Pointer;
- guint32 u32ArraySize;
+ guint32 u32ArraySize = 0;
guint32 u32HResult;
guint32 u32Idx = 1;
guint32 u32ProvID;
@@ -613,10 +1575,19 @@ dissect_ICBAAccoServer_Connect_resp(tvbuff_t *tvb, int offset,
proto_tree *sub_tree;
guint32 u32SubStart;
proto_item *item;
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ server_connect_call_t *call = info->call_data->private_data;
+ cba_connection_t *conn;
offset = dissect_dcom_that(tvb, offset, pinfo, tree, drep);
+ if(call == NULL) {
+ expert_add_info_format(pinfo, NULL, PI_UNDECODED, PI_WARN,
+ "Server_Connect: return values ignored from #%u",
+ info->call_data->req_frame);
+ }
+
item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
PROTO_ITEM_SET_GENERATED(item);
pinfo->profinet_type = 1;
@@ -643,6 +1614,15 @@ dissect_ICBAAccoServer_Connect_resp(tvbuff_t *tvb, int offset,
offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, drep,
&u32HResult, u32Idx);
+ /* put response data into the connection */
+ if(call && u32Idx <= call->conn_count) {
+ conn = call->conns[u32Idx-1];
+ conn->provid = u32ProvID;
+ conn->connret = u32HResult;
+
+ cba_connection_info(tvb, pinfo, sub_tree, conn);
+ }
+
proto_item_append_text(sub_item, "[%u]: ProvID=0x%x %s",
u32Idx, u32ProvID,
val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
@@ -655,6 +1635,14 @@ dissect_ICBAAccoServer_Connect_resp(tvbuff_t *tvb, int offset,
offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep,
&u32HResult);
+ /* this might be a global HRESULT */
+ while(call && u32Idx <= call->conn_count) {
+ conn = call->conns[u32Idx-1];
+ conn->provid = 0;
+ conn->connret = u32HResult;
+ u32Idx++;
+ }
+
if (check_col(pinfo->cinfo, COL_INFO)) {
col_append_fstr(pinfo->cinfo, COL_INFO, ": %s Cnt=%u -> %s",
(u8FirstConnect) ? "First" : "NotFirst",
@@ -675,6 +1663,10 @@ dissect_ICBAAccoServer_Disconnect_rqst(tvbuff_t *tvb, int offset,
guint32 u32Idx;
guint32 u32ProvID;
proto_item *item;
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ cba_ldev_t *prov_ldev;
+ cba_connection_t *conn;
+ server_connect_call_t *call;
offset = dissect_dcom_this(tvb, offset, pinfo, tree, drep);
@@ -689,10 +1681,31 @@ dissect_ICBAAccoServer_Disconnect_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, drep,
&u32ArraySize);
+ prov_ldev = cba_ldev_find(pinfo, pinfo->net_dst.data, &info->call_data->object_uuid);
+
+ /* link connection infos to the call */
+ if(prov_ldev != NULL) {
+ call = se_alloc(sizeof(server_connect_call_t) + u32ArraySize * sizeof(cba_connection_t *));
+ call->conn_count = 0;
+ call->frame = NULL;
+ call->conns = (cba_connection_t **) (call+1);
+ info->call_data->private_data = call;
+ } else{
+ call = NULL;
+ }
+
u32Idx = 1;
while (u32ArraySize--) {
offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, drep,
hf_cba_acco_conn_prov_id, &u32ProvID, u32Idx);
+
+ /* add to current call */
+ if(call != NULL) {
+ conn = cba_connection_find_by_provid(tvb, pinfo, tree, prov_ldev, u32ProvID);
+ call->conn_count++;
+ call->conns[u32Idx-1] = conn;
+ }
+
u32Idx++;
}
@@ -706,6 +1719,69 @@ dissect_ICBAAccoServer_Disconnect_rqst(tvbuff_t *tvb, int offset,
static int
+dissect_ICBAAccoServer_Disconnect_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint32 u32HResult;
+ guint32 u32Pointer;
+ guint32 u32ArraySize = 0;
+ guint32 u32Idx;
+ guint32 u32Tmp;
+ proto_item *item;
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ server_connect_call_t *call = info->call_data->private_data;
+ cba_connection_t *conn;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, drep);
+
+ if(call == NULL) {
+ expert_add_info_format(pinfo, NULL, PI_UNDECODED, PI_WARN,
+ "Server_Disconnect: return values ignored from #%u",
+ info->call_data->req_frame);
+ }
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
+ PROTO_ITEM_SET_GENERATED(item);
+ pinfo->profinet_type = 1;
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, drep,
+ &u32Pointer);
+
+ if (u32Pointer) {
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, drep,
+ &u32ArraySize);
+
+ u32Idx = 1;
+ u32Tmp = u32ArraySize;
+ while (u32Tmp--) {
+ offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, drep,
+ &u32HResult, u32Idx);
+
+ /* mark this connection as disconnected */
+ if(call && u32Idx <= call->conn_count) {
+ conn = call->conns[u32Idx-1];
+ cba_connection_disconnect(pinfo, conn);
+ }
+
+ u32Idx++;
+ }
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep,
+ &u32HResult);
+
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s",
+ u32ArraySize,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+ }
+
+ return offset;
+}
+
+
+static int
dissect_ICBAAccoServerSRT_Disconnect_rqst(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
@@ -745,16 +1821,23 @@ dissect_ICBAAccoServerSRT_Disconnect_rqst(tvbuff_t *tvb, int offset,
static int
-dissect_ICBAAccoServer_Consumer_rqst(tvbuff_t *tvb, int offset,
+dissect_ICBAAccoServer_DisconnectMe_rqst(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
gchar szStr[1000];
guint32 u32MaxStr = sizeof(szStr);
proto_item *item;
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ cba_ldev_t *prov_ldev;
+ cba_ldev_t *cons_ldev;
+ server_disconnectme_call_t *call;
offset = dissect_dcom_this(tvb, offset, pinfo, tree, drep);
+ /* get corresponding provider ldev */
+ prov_ldev = cba_ldev_find(pinfo, pinfo->net_dst.data, &info->call_data->object_uuid);
+
item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE);
PROTO_ITEM_SET_GENERATED(item);
pinfo->profinet_type = 2;
@@ -762,6 +1845,16 @@ dissect_ICBAAccoServer_Consumer_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, drep,
hf_cba_acco_conn_consumer, szStr, u32MaxStr);
+ /* find the consumer ldev by it's name */
+ cons_ldev = cba_acco_add(pinfo, szStr);
+
+ if(prov_ldev != NULL && cons_ldev != NULL) {
+ call = se_alloc(sizeof(server_disconnectme_call_t));
+ call->cons = cons_ldev;
+ call->prov = prov_ldev;
+ info->call_data->private_data = call;
+ }
+
/* update column info now */
if (check_col(pinfo->cinfo, COL_INFO)) {
col_append_fstr(pinfo->cinfo, COL_INFO, " Consumer=\"%s\"", szStr);
@@ -771,6 +1864,39 @@ dissect_ICBAAccoServer_Consumer_rqst(tvbuff_t *tvb, int offset,
}
+static int
+dissect_ICBAAccoServer_DisconnectMe_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint32 u32HResult;
+ proto_item *item;
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ server_disconnectme_call_t *call;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, drep);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
+ PROTO_ITEM_SET_GENERATED(item);
+ pinfo->profinet_type = 1;
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep,
+ &u32HResult);
+
+ call = info->call_data->private_data;
+ if(call) {
+ cba_connection_disconnectme(tvb, pinfo, tree, call->cons, call->prov);
+ }
+
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+ }
+
+ return offset;
+}
+
+
static int
dissect_ICBAAccoServerSRT_DisconnectMe_rqst(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
@@ -778,10 +1904,17 @@ dissect_ICBAAccoServerSRT_DisconnectMe_rqst(tvbuff_t *tvb, int offset,
gchar szStr[1000];
guint32 u32MaxStr = sizeof(szStr);
proto_item *item;
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ cba_ldev_t *prov_ldev;
+ cba_ldev_t *cons_ldev;
+ server_disconnectme_call_t *call;
offset = dissect_dcom_this(tvb, offset, pinfo, tree, drep);
+ /* get corresponding provider ldev */
+ prov_ldev = cba_ldev_find(pinfo, pinfo->net_dst.data, &info->call_data->object_uuid);
+
item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE);
PROTO_ITEM_SET_GENERATED(item);
pinfo->profinet_type = 4;
@@ -789,6 +1922,16 @@ dissect_ICBAAccoServerSRT_DisconnectMe_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, drep,
hf_cba_acco_conn_consumer, szStr, u32MaxStr);
+ /* find the consumer ldev by it's name */
+ cons_ldev = cba_acco_add(pinfo, szStr);
+
+ if(prov_ldev != NULL && cons_ldev != NULL) {
+ call = se_alloc(sizeof(server_disconnectme_call_t));
+ call->cons = cons_ldev;
+ call->prov = prov_ldev;
+ info->call_data->private_data = call;
+ }
+
/* update column info now */
if (check_col(pinfo->cinfo, COL_INFO)) {
col_append_fstr(pinfo->cinfo, COL_INFO, " Consumer=\"%s\"", szStr);
@@ -799,22 +1942,29 @@ dissect_ICBAAccoServerSRT_DisconnectMe_rqst(tvbuff_t *tvb, int offset,
static int
-dissect_ICBAAccoServer_simple_resp(tvbuff_t *tvb, int offset,
+dissect_ICBAAccoServerSRT_DisconnectMe_resp(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
guint32 u32HResult;
proto_item *item;
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ server_disconnectme_call_t *call;
offset = dissect_dcom_that(tvb, offset, pinfo, tree, drep);
- item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
+ item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE);
PROTO_ITEM_SET_GENERATED(item);
- pinfo->profinet_type = 1;
+ pinfo->profinet_type = 3;
offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep,
&u32HResult);
+ call = info->call_data->private_data;
+ if(call) {
+ cba_frame_disconnectme(tvb, pinfo, tree, call->cons, call->prov);
+ }
+
if (check_col(pinfo->cinfo, COL_INFO)) {
col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
@@ -825,7 +1975,7 @@ dissect_ICBAAccoServer_simple_resp(tvbuff_t *tvb, int offset,
static int
-dissect_ICBAAccoServerSRT_simple_resp(tvbuff_t *tvb, int offset,
+dissect_ICBAAccoServer_Ping_resp(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
guint32 u32HResult;
@@ -834,9 +1984,9 @@ dissect_ICBAAccoServerSRT_simple_resp(tvbuff_t *tvb, int offset,
offset = dissect_dcom_that(tvb, offset, pinfo, tree, drep);
- item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE);
+ item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
PROTO_ITEM_SET_GENERATED(item);
- pinfo->profinet_type = 3;
+ pinfo->profinet_type = 1;
offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep,
&u32HResult);
@@ -983,10 +2133,19 @@ dissect_ICBAAccoServerSRT_ConnectCR_rqst(tvbuff_t *tvb, int offset,
proto_item *sub_item;
proto_tree *sub_tree;
guint32 u32SubStart;
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ dcom_interface_t *cons_interf;
+ cba_ldev_t *prov_ldev;
+ cba_ldev_t *cons_ldev;
+ cba_frame_t *frame;
+ server_frame_call_t *call;
offset = dissect_dcom_this(tvb, offset, pinfo, tree, drep);
+ /* get corresponding provider ldev */
+ prov_ldev = cba_ldev_find(pinfo, pinfo->net_dst.data, &info->call_data->object_uuid);
+
item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE);
PROTO_ITEM_SET_GENERATED(item);
pinfo->profinet_type = 4;
@@ -995,12 +2154,24 @@ dissect_ICBAAccoServerSRT_ConnectCR_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, drep,
hf_cba_acco_conn_consumer, szCons, u32MaxConsLen);
+ /* find the consumer ldev by it's name */
+ cons_ldev = cba_acco_add(pinfo, szCons);
+
offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, drep,
hf_cba_acco_conn_qos_type, &u16QoSType);
offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, drep,
hf_cba_acco_conn_qos_value, &u16QoSValue);
- offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, drep, 0);
+ offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, drep, 0, &cons_interf);
+ if(cons_interf == NULL) {
+ expert_add_info_format(pinfo, NULL, PI_UNDECODED, PI_WARN,
+ "ServerSRT_ConnectCR: consumer interface invalid");
+ }
+
+ /* "crosslink" consumer interface and it's object */
+ if(cons_interf != NULL && cons_ldev != NULL) {
+ cba_ldev_link_acco(pinfo, cons_ldev, cons_interf);
+ }
/* ConsumerMAC (big-endian, 1byte-aligned) */
tvb_memcpy(tvb, u8ConsMac, offset, 6);
@@ -1029,6 +2200,16 @@ dissect_ICBAAccoServerSRT_ConnectCR_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, drep,
&u32ArraySize);
+ /* link frame infos to the call */
+ if(prov_ldev != NULL && cons_ldev != NULL) {
+ call = se_alloc(sizeof(server_frame_call_t) + u32ArraySize * sizeof(cba_frame_t *));
+ call->frame_count = 0;
+ call->frames = (cba_frame_t **) (call+1);
+ info->call_data->private_data = call;
+ } else{
+ call = NULL;
+ }
+
u32Idx = 1;
while (u32ArraySize--) {
/* array of CONNECTINCRs */
@@ -1042,6 +2223,21 @@ dissect_ICBAAccoServerSRT_ConnectCR_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, drep,
hf_cba_acco_serversrt_cr_length, &u16CRLength);
+ /* add to object database */
+ if(prov_ldev != NULL && cons_ldev != NULL) {
+ frame = cba_frame_connect(pinfo, cons_ldev, prov_ldev, u16QoSType, u16QoSValue, u8ConsMac, u16CRID, u16CRLength);
+
+ cba_frame_info(tvb, pinfo, sub_tree, frame);
+ } else {
+ frame = NULL;
+ }
+
+ /* add to current call */
+ if(call != NULL) {
+ call->frame_count++;
+ call->frames[u32Idx-1] = frame;
+ }
+
/* update subtree header */
proto_item_append_text(sub_item, "[%u]: CRID=0x%x, CRLength=%u",
u32Idx, u16CRID, u16CRLength);
@@ -1076,10 +2272,19 @@ dissect_ICBAAccoServerSRT_ConnectCR_resp(tvbuff_t *tvb, int offset,
proto_tree *sub_tree;
guint32 u32SubStart;
proto_item *item;
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ server_frame_call_t *call = info->call_data->private_data;
+ cba_frame_t *frame;
offset = dissect_dcom_that(tvb, offset, pinfo, tree, drep);
+ if(call == NULL) {
+ expert_add_info_format(pinfo, NULL, PI_UNDECODED, PI_WARN,
+ "ServerSRT_ConnectCR: return values ignored from #%u",
+ info->call_data->req_frame);
+ }
+
item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE);
PROTO_ITEM_SET_GENERATED(item);
pinfo->profinet_type = 3;
@@ -1115,6 +2320,15 @@ dissect_ICBAAccoServerSRT_ConnectCR_resp(tvbuff_t *tvb, int offset,
offset = dissect_dcom_HRESULT(tvb, offset, pinfo, sub_tree, drep,
&u32HResult);
+ /* put response data into the frame */
+ if(call && u32Idx <= call->frame_count) {
+ frame = call->frames[u32Idx-1];
+ frame->provcrid = u32ProvCRID;
+ frame->conncrret = u32HResult;
+
+ cba_frame_info(tvb, pinfo, sub_tree, frame);
+ }
+
/* update subtree header */
proto_item_append_text(sub_item, "[%u]: ProvCRID=0x%x, %s",
u32Idx, u32ProvCRID,
@@ -1128,6 +2342,14 @@ dissect_ICBAAccoServerSRT_ConnectCR_resp(tvbuff_t *tvb, int offset,
offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep,
&u32HResult);
+ /* this might be a global HRESULT */
+ while(call && u32Idx <= call->frame_count) {
+ frame = call->frames[u32Idx-1];
+ frame->provcrid = 0;
+ frame->conncrret = u32HResult;
+ u32Idx++;
+ }
+
if (check_col(pinfo->cinfo, COL_INFO)) {
col_append_fstr(pinfo->cinfo, COL_INFO, ": %s PCRID=0x%x -> %s",
(u8FirstConnect) ? "FirstCR" : "NotFirstCR",
@@ -1148,9 +2370,16 @@ dissect_ICBAAccoServerSRT_DisconnectCR_rqst(tvbuff_t *tvb, int offset,
guint32 u32Idx;
guint32 u32ProvCRID;
proto_item *item;
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ cba_ldev_t *prov_ldev;
+ cba_frame_t *frame;
+ server_frame_call_t *call;
+
offset = dissect_dcom_this(tvb, offset, pinfo, tree, drep);
+ /* get corresponding provider ldev */
+ prov_ldev = cba_ldev_find(pinfo, pinfo->net_dst.data, &info->call_data->object_uuid);
item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE);
PROTO_ITEM_SET_GENERATED(item);
@@ -1162,10 +2391,28 @@ dissect_ICBAAccoServerSRT_DisconnectCR_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, drep,
&u32ArraySize);
+ /* link frame infos to the call */
+ if(prov_ldev != NULL) {
+ call = se_alloc(sizeof(server_frame_call_t) + u32ArraySize * sizeof(cba_frame_t *));
+ call->frame_count = 0;
+ call->frames = (cba_frame_t **) (call+1);
+ info->call_data->private_data = call;
+ } else{
+ call = NULL;
+ }
+
u32Idx = 1;
while (u32ArraySize--) {
offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, drep,
hf_cba_acco_prov_crid, &u32ProvCRID, u32Idx);
+
+ /* find frame and add it to current call */
+ if(call != NULL) {
+ frame = cba_frame_find_by_provcrid(pinfo, prov_ldev, u32ProvCRID);
+ call->frame_count++;
+ call->frames[u32Idx-1] = frame;
+ }
+
u32Idx++;
}
@@ -1179,6 +2426,62 @@ dissect_ICBAAccoServerSRT_DisconnectCR_rqst(tvbuff_t *tvb, int offset,
static int
+dissect_ICBAAccoServerSRT_DisconnectCR_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint32 u32HResult;
+ guint32 u32Pointer;
+ guint32 u32ArraySize = 0;
+ guint32 u32Idx;
+ guint32 u32Tmp;
+ proto_item *item;
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ server_frame_call_t *call = info->call_data->private_data;
+ cba_frame_t *frame;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, drep);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE);
+ PROTO_ITEM_SET_GENERATED(item);
+ pinfo->profinet_type = 3;
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, drep,
+ &u32Pointer);
+
+ if (u32Pointer) {
+ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, drep,
+ &u32ArraySize);
+
+ u32Idx = 1;
+ u32Tmp = u32ArraySize;
+ while (u32Tmp--) {
+ offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, drep,
+ &u32HResult, u32Idx);
+ /* put response data into the frame */
+ if(call && u32Idx <= call->frame_count) {
+ frame = call->frames[u32Idx-1];
+ cba_frame_disconnect(pinfo, frame);
+ }
+
+ u32Idx++;
+ }
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep,
+ &u32HResult);
+
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s",
+ u32ArraySize,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+ }
+
+ return offset;
+}
+
+
+static int
dissect_ICBAAccoServerSRT_Connect_rqst(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
@@ -1203,10 +2506,20 @@ dissect_ICBAAccoServerSRT_Connect_rqst(tvbuff_t *tvb, int offset,
guint32 u32ConsID;
guint16 u16RecordLength;
proto_item *item;
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ cba_ldev_t *prov_ldev;
+ cba_frame_t *frame = NULL;
+ cba_connection_t *conn;
+ guint16 typedesclen = 0;
+ guint16 *typedesc = NULL;
+ server_connect_call_t *call;
offset = dissect_dcom_this(tvb, offset, pinfo, tree, drep);
+ /* get corresponding provider ldev */
+ prov_ldev = cba_ldev_find(pinfo, pinfo->net_dst.data, &info->call_data->object_uuid);
+
item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE);
PROTO_ITEM_SET_GENERATED(item);
pinfo->profinet_type = 4;
@@ -1214,6 +2527,12 @@ dissect_ICBAAccoServerSRT_Connect_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, drep,
hf_cba_acco_prov_crid, &u32ProvCRID);
+ frame = cba_frame_find_by_provcrid(pinfo, prov_ldev, u32ProvCRID);
+
+ if(frame != NULL) {
+ cba_frame_info(tvb, pinfo, tree, frame);
+ }
+
offset = dissect_dcom_BYTE(tvb, offset, pinfo, tree, drep,
hf_cba_acco_conn_state, &u8State);
@@ -1227,6 +2546,17 @@ dissect_ICBAAccoServerSRT_Connect_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, drep,
&u32ArraySize);
+ /* link connections infos to the call */
+ if(frame != NULL) {
+ call = se_alloc(sizeof(server_connect_call_t) + u32ArraySize * sizeof(cba_connection_t *));
+ call->conn_count = 0;
+ call->frame = frame;
+ call->conns = (cba_connection_t **) (call+1);
+ info->call_data->private_data = call;
+ } else{
+ call = NULL;
+ }
+
u32VariableOffset = offset + u32ArraySize*20;
u32Idx = 1;
@@ -1255,13 +2585,21 @@ dissect_ICBAAccoServerSRT_Connect_rqst(tvbuff_t *tvb, int offset,
u32VariableOffset = dissect_dcom_dcerpc_array_size(tvb, u32VariableOffset, pinfo, sub_tree, drep,
&u32ArraySize2);
+ typedesc = se_alloc0(u32ArraySize2 * 2);
+ typedesclen = u32ArraySize2;
+
/* extended type description will build an array here */
u32Idx2 = 1;
while (u32ArraySize2--) {
/* ToBeDone: some of the type description values are counts */
u32VariableOffset = dissect_dcom_VARTYPE(tvb, u32VariableOffset, pinfo, sub_tree, drep,
&u16VarType);
- /* remember first VarType only */
+
+ if(u32Idx2 <= typedesclen) {
+ typedesc[u32Idx2-1] = u16VarType;
+ }
+
+ /* remember first VarType only */
if (u32Idx2 == 1) {
u16VarType2 = u16VarType;
}
@@ -1277,6 +2615,23 @@ dissect_ICBAAccoServerSRT_Connect_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, drep,
hf_cba_acco_serversrt_record_length, &u16RecordLength);
+ /* add to object database */
+ if(frame != NULL) {
+ conn = cba_connection_connect(pinfo, frame->consparent, frame->provparent, frame,
+ frame->qostype, frame->qosvalue, szProvItem, u32ConsID, u16RecordLength,
+ typedesc, typedesclen);
+
+ cba_connection_info(tvb, pinfo, sub_tree, conn);
+ } else {
+ conn = NULL;
+ }
+
+ /* add to current call */
+ if(call != NULL) {
+ call->conn_count++;
+ call->conns[u32Idx-1] = conn;
+ }
+
/* update subtree header */
proto_item_append_text(sub_item, "[%u]: ConsID=0x%x, ProvItem=\"%s\", TypeDesc=%s",
u32Idx, u32ConsID, szProvItem,
@@ -1312,10 +2667,18 @@ dissect_ICBAAccoServerSRT_Connect_resp(tvbuff_t *tvb, int offset,
guint32 u32ProvID;
guint32 u32HResult;
proto_item *item;
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ server_connect_call_t *call = info->call_data->private_data;
+ cba_connection_t *conn;
offset = dissect_dcom_that(tvb, offset, pinfo, tree, drep);
+ if(call == NULL) {
+ expert_add_info_format(pinfo, NULL, PI_UNDECODED, PI_WARN,
+ "ServerSRT_ConnectCR: return values ignored from #%u", info->call_data->req_frame);
+ }
+
item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE);
PROTO_ITEM_SET_GENERATED(item);
pinfo->profinet_type = 3;
@@ -1323,6 +2686,10 @@ dissect_ICBAAccoServerSRT_Connect_resp(tvbuff_t *tvb, int offset,
offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, drep,
&u32Pointer);
+ if(call && call->frame != NULL) {
+ cba_frame_info(tvb, pinfo, tree, call->frame);
+ }
+
if (u32Pointer) {
offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, drep,
&u32ArraySize);
@@ -1339,6 +2706,15 @@ dissect_ICBAAccoServerSRT_Connect_resp(tvbuff_t *tvb, int offset,
offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, drep,
&u32HResult, u32Idx);
+ /* put response data into the frame */
+ if(call && u32Idx <= call->conn_count) {
+ conn = call->conns[u32Idx-1];
+ conn->provid = u32ProvID;
+ conn->connret = u32HResult;
+
+ cba_connection_info(tvb, pinfo, sub_tree, conn);
+ }
+
proto_item_append_text(sub_item, "[%u]: ProvID=0x%x %s",
u32Idx, u32ProvID,
val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
@@ -1351,6 +2727,14 @@ dissect_ICBAAccoServerSRT_Connect_resp(tvbuff_t *tvb, int offset,
offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep,
&u32HResult);
+ /* this might be a global HRESULT */
+ while(call && u32Idx <= call->conn_count) {
+ conn = call->conns[u32Idx-1];
+ conn->provid = 0;
+ conn->connret = u32HResult;
+ u32Idx++;
+ }
+
if (check_col(pinfo->cinfo, COL_INFO)) {
col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s",
u32Idx-1,
@@ -1362,7 +2746,7 @@ dissect_ICBAAccoServerSRT_Connect_resp(tvbuff_t *tvb, int offset,
static int
-dissect_ICBAAccoMgt2_GetProvIDs_resp(tvbuff_t *tvb, int offset,
+dissect_Server_GetProvIDs_resp(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
guint32 u32Count;
@@ -1425,7 +2809,7 @@ dissect_ICBAAccoMgt2_GetProvIDs_resp(tvbuff_t *tvb, int offset,
static int
-dissect_ICBAAccoMgt2_GetProvConnections_rqst(tvbuff_t *tvb, int offset,
+dissect_Server_GetProvConnections_rqst(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
guint32 u32Count;
@@ -1459,7 +2843,7 @@ dissect_ICBAAccoMgt2_GetProvConnections_rqst(tvbuff_t *tvb, int offset,
static int
-dissect_ICBAAccoMgt2_GetProvConnections_resp(tvbuff_t *tvb, int offset,
+dissect_Server_GetProvConnections_resp(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
guint32 u32Count;
@@ -1569,7 +2953,7 @@ dissect_ICBAAccoMgt2_GetProvConnections_resp(tvbuff_t *tvb, int offset,
int
dissect_CBA_Connection_Data(tvbuff_t *tvb,
- packet_info *pinfo, proto_tree *tree)
+ packet_info *pinfo, proto_tree *tree, cba_ldev_t *cons_ldev, cba_frame_t *frame)
{
guint8 u8Version;
guint8 u8Flags;
@@ -1593,7 +2977,10 @@ dissect_CBA_Connection_Data(tvbuff_t *tvb,
int qc_good = 0;
int qc_uncertain = 0;
int qc_bad = 0;
-/* guint32 bTimeStamped = 0;*/
+ GList *conns;
+ cba_connection_t *conn;
+ int item_offset;
+
/*** ALL data in this buffer is NOT aligned and always little endian ordered ***/
@@ -1622,6 +3009,16 @@ dissect_CBA_Connection_Data(tvbuff_t *tvb,
offset += 2;
u16CountFix = u16Count;
+ /* show meta information */
+ if(frame) {
+ cba_frame_info(tvb, pinfo, conn_data_tree, frame);
+ } else {
+ if(cons_ldev && cons_ldev->name) {
+ item = proto_tree_add_string(conn_data_tree, hf_cba_acco_conn_consumer, tvb, offset, 0, cons_ldev->name);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
+ }
+
/* update column info now */
#if 0
if (check_col(pinfo->cinfo, COL_INFO))
@@ -1677,6 +3074,8 @@ dissect_CBA_Connection_Data(tvbuff_t *tvb,
sub_item = proto_tree_add_item(conn_data_tree, hf_cba_acco_cb_item, tvb, offset, 0, FALSE);
sub_tree = proto_item_add_subtree(sub_item, ett_ICBAAccoCallback_Item);
+ item_offset = offset;
+
/* add item header fields */
if (sub_tree) {
proto_tree_add_item(sub_tree, hf_cba_acco_cb_item_length, tvb, offset, 2, TRUE);
@@ -1748,12 +3147,38 @@ dissect_CBA_Connection_Data(tvbuff_t *tvb,
tvb_get_ptr(tvb, offset, u16DataLen));
offset += u16DataLen;
+ if(frame != NULL ) {
+ /* find offset in SRT */
+ /* XXX - expensive! */
+ cba_frame_incoming_data(tvb, pinfo, sub_tree, frame);
+ for(conns = frame->conns; conns != NULL; conns = g_list_next(conns)) {
+ conn = conns->data;
+ if(conn->frame_offset == item_offset) {
+ cba_connection_info(tvb, pinfo, sub_tree, conn);
+ break;
+ }
+ }
+ } else {
+ /* find consID in ldev */
+ /* XXX - expensive! */
+ if(cons_ldev != NULL) {
+ for(conns = cons_ldev->consconns; conns != NULL; conns = g_list_next(conns)) {
+ conn = conns->data;
+ if(conn->consid == u32ID) {
+ cba_connection_info(tvb, pinfo, sub_tree, conn);
+ cba_connection_incoming_data(tvb, pinfo, sub_tree, conn);
+ break;
+ }
+ }
+ }
+ }
+
u32ItemIdx++;
}
if (u8Version == 1) {
proto_item_append_text(conn_data_item,
- ": Version=0x%x (OnDataChanged), Flags=0x%x, Count=%u",
+ ": Version=0x%x (DCOM), Flags=0x%x, Count=%u",
u8Version, u8Flags, u16CountFix);
} else {
proto_item_append_text(conn_data_item,
@@ -1777,6 +3202,7 @@ dissect_CBA_Connection_Data_heur(tvbuff_t *tvb,
guint8 u8Version;
guint8 u8Flags;
guint16 u16FrameID;
+ cba_frame_t *frame;
/* the tvb will NOT contain the frame_id here! */
u16FrameID = GPOINTER_TO_UINT(pinfo->private_data);
@@ -1797,7 +3223,9 @@ dissect_CBA_Connection_Data_heur(tvbuff_t *tvb,
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_add_str(pinfo->cinfo, COL_PROTOCOL, "PN-CBA");
- dissect_CBA_Connection_Data(tvb, pinfo, tree);
+ frame = cba_frame_find_by_cons(pinfo, pinfo->dl_dst.data, u16FrameID);
+
+ dissect_CBA_Connection_Data(tvb, pinfo, tree, frame ? frame->consparent : NULL, frame);
return TRUE;
}
@@ -1811,10 +3239,15 @@ dissect_ICBAAccoCallback_OnDataChanged_rqst(tvbuff_t *tvb, int offset,
guint32 u32ArraySize;
tvbuff_t *next_tvb;
proto_item *item;
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ cba_ldev_t *cons_ldev;
offset = dissect_dcom_this(tvb, offset, pinfo, tree, drep);
+ /* get corresponding provider ldev */
+ cons_ldev = cba_ldev_find(pinfo, pinfo->net_dst.data, &info->call_data->object_uuid);
+
item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
PROTO_ITEM_SET_GENERATED(item);
pinfo->profinet_type = 1;
@@ -1831,7 +3264,7 @@ dissect_ICBAAccoCallback_OnDataChanged_rqst(tvbuff_t *tvb, int offset,
/* dissect PROFINET component data (without header) */
next_tvb = tvb_new_subset(tvb, offset, -1, -1);
- offset += dissect_CBA_Connection_Data(next_tvb, pinfo, tree);
+ offset += dissect_CBA_Connection_Data(next_tvb, pinfo, tree, cons_ldev, NULL /* frame */);
/* XXX */
/* tvb_free(next_tvb);*/
@@ -1840,7 +3273,7 @@ dissect_ICBAAccoCallback_OnDataChanged_rqst(tvbuff_t *tvb, int offset,
}
-static int
+static int
dissect_ICBAAccoCallback_OnDataChanged_resp(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
@@ -1910,6 +3343,45 @@ dissect_ICBAAccoCallback_Gnip_resp(tvbuff_t *tvb, int offset,
static int
+dissect_ICBAAccoServer2_GetConnectionData_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ gchar szStr[1000];
+ guint32 u32MaxStr = sizeof(szStr);
+ proto_item *item;
+ cba_ldev_t *cons_ldev;
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ cba_ldev_t **call;
+
+
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, drep);
+
+ item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE);
+ PROTO_ITEM_SET_GENERATED(item);
+ pinfo->profinet_type = 2;
+
+ offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, drep,
+ hf_cba_acco_conn_consumer, szStr, u32MaxStr);
+
+ cons_ldev = cba_acco_add(pinfo, szStr);
+
+ /* link ldev to the call */
+ if(cons_ldev != NULL) {
+ call = se_alloc(sizeof(cba_ldev_t *));
+ *call = cons_ldev;
+ info->call_data->private_data = call;
+ }
+
+ /* update column info now */
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Consumer=\"%s\"", szStr);
+ }
+
+ return offset;
+}
+
+
+static int
dissect_ICBAAccoServer2_GetConnectionData_resp(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
@@ -1919,10 +3391,18 @@ dissect_ICBAAccoServer2_GetConnectionData_resp(tvbuff_t *tvb, int offset,
guint32 u32Pointer;
guint32 u32HResult;
proto_item *item;
-
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ cba_ldev_t **call = info->call_data->private_data;
+ cba_ldev_t *cons_ldev = (call!=NULL) ? *call : NULL;
+
offset = dissect_dcom_that(tvb, offset, pinfo, tree, drep);
+ if(cons_ldev == NULL) {
+ expert_add_info_format(pinfo, NULL, PI_UNDECODED, PI_WARN,
+ "Server2_GCD: return values ignored from #%u", info->call_data->req_frame);
+ }
+
item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
PROTO_ITEM_SET_GENERATED(item);
pinfo->profinet_type = 1;
@@ -1942,7 +3422,7 @@ dissect_ICBAAccoServer2_GetConnectionData_resp(tvbuff_t *tvb, int offset,
/* dissect PROFINET component data (without header) */
next_tvb = tvb_new_subset(tvb, offset, -1, -1);
- offset += dissect_CBA_Connection_Data(next_tvb, pinfo, tree);
+ offset += dissect_CBA_Connection_Data(next_tvb, pinfo, tree, (call != NULL) ? *call : NULL, NULL /* frame */);
/* XXX */
/* tvb_free(next_tvb);*/
@@ -2106,14 +3586,18 @@ dissect_ICBAAccoMgt_AddConnections_resp(tvbuff_t *tvb, int offset,
u32Idx++;
}
- offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep,
- &u32HResult);
- }
+ /* update column info now */
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
+ }
+ }
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep,
+ &u32HResult);
+
/* update column info now */
if (check_col(pinfo->cinfo, COL_INFO)) {
- col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s",
- u32Count,
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
}
@@ -3148,8 +4632,8 @@ static dcerpc_sub_dissector ICBAAccoMgt_dissectors[] = {
{14, "GetConsIDs", dissect_dcom_simple_rqst, dissect_ICBAAccoMgt2_GetConsIDs_resp },
{15, "GetConsConnections", dissect_ICBAAccoMgt_GetConnections_rqst, dissect_ICBAAccoMgt2_GetConsConnections_resp },
{16, "DiagConsConnections", dissect_ICBAAccoMgt_GetConnections_rqst, dissect_ICBAAccoMgt2_DiagConsConnections_resp },
- {17, "GetProvIDs", dissect_dcom_simple_rqst, dissect_ICBAAccoMgt2_GetProvIDs_resp },
- {18, "GetProvConnections", dissect_ICBAAccoMgt2_GetProvConnections_rqst, dissect_ICBAAccoMgt2_GetProvConnections_resp },
+ {17, "GetProvIDs", dissect_dcom_simple_rqst, dissect_Server_GetProvIDs_resp },
+ {18, "GetProvConnections", dissect_Server_GetProvConnections_rqst, dissect_Server_GetProvConnections_resp },
{19, "GetDiagnosis", dissect_ICBAAccoMgt_GetDiagnosis_rqst, dissect_ICBAAccoMgt_GetDiagnosis_resp },
{ 0, NULL, NULL, NULL },
};
@@ -3175,13 +4659,13 @@ static dcerpc_sub_dissector ICBAAccoServer_dissectors[] = {
{ 2, "Release", NULL, NULL },
{ 3, "Connect", dissect_ICBAAccoServer_Connect_rqst, dissect_ICBAAccoServer_Connect_resp },
- { 4, "Disconnect", dissect_ICBAAccoServer_Disconnect_rqst, dissect_ICBAAccoServer_HResultArray_resp },
- { 5, "DisconnectMe", dissect_ICBAAccoServer_Consumer_rqst, dissect_ICBAAccoServer_simple_resp },
- { 6, "SetActivation", dissect_ICBAAccoServer_SetActivation_rqst, dissect_ICBAAccoServer_HResultArray_resp },
- { 7, "Ping", dissect_ICBAAccoServer_Ping_rqst, dissect_ICBAAccoServer_simple_resp },
+ { 4, "Disconnect", dissect_ICBAAccoServer_Disconnect_rqst, dissect_ICBAAccoServer_Disconnect_resp },
+ { 5, "DisconnectMe", dissect_ICBAAccoServer_DisconnectMe_rqst, dissect_ICBAAccoServer_DisconnectMe_resp },
+ { 6, "SetActivation", dissect_ICBAAccoServer_SetActivation_rqst, dissect_ICBAAccoServer_SetActivation_resp },
+ { 7, "Ping", dissect_ICBAAccoServer_Ping_rqst, dissect_ICBAAccoServer_Ping_resp },
/* stage 2 */
{ 8, "Connect2", dissect_ICBAAccoServer2_Connect2_rqst, dissect_ICBAAccoServer_Connect_resp },
- { 9, "GetConnectionData", dissect_ICBAAccoServer_Consumer_rqst, dissect_ICBAAccoServer2_GetConnectionData_resp },
+ { 9, "GetConnectionData", dissect_ICBAAccoServer2_GetConnectionData_rqst, dissect_ICBAAccoServer2_GetConnectionData_resp },
{ 0, NULL, NULL, NULL },
};
@@ -3193,12 +4677,11 @@ static dcerpc_sub_dissector ICBAAccoServerSRT_dissectors[] = {
{ 2, "Release", NULL, NULL },
{ 3, "ConnectCR", dissect_ICBAAccoServerSRT_ConnectCR_rqst, dissect_ICBAAccoServerSRT_ConnectCR_resp },
- { 4, "DisconnectCR", dissect_ICBAAccoServerSRT_DisconnectCR_rqst, dissect_ICBAAccoServerSRT_HResultArray_resp },
+ { 4, "DisconnectCR", dissect_ICBAAccoServerSRT_DisconnectCR_rqst, dissect_ICBAAccoServerSRT_DisconnectCR_resp },
{ 5, "Connect", dissect_ICBAAccoServerSRT_Connect_rqst, dissect_ICBAAccoServerSRT_Connect_resp },
- { 6, "Disconnect", dissect_ICBAAccoServerSRT_Disconnect_rqst, dissect_ICBAAccoServerSRT_HResultArray_resp },
- { 7, "DisconnectMe", dissect_ICBAAccoServerSRT_DisconnectMe_rqst, dissect_ICBAAccoServerSRT_simple_resp },
- { 8, "SetActivation", dissect_ICBAAccoServerSRT_SetActivation_rqst, dissect_ICBAAccoServerSRT_HResultArray_resp },
-
+ { 6, "Disconnect", dissect_ICBAAccoServerSRT_Disconnect_rqst, dissect_ICBAAccoServerSRT_Disconnect_resp },
+ { 7, "DisconnectMe", dissect_ICBAAccoServerSRT_DisconnectMe_rqst, dissect_ICBAAccoServerSRT_DisconnectMe_resp },
+ { 8, "SetActivation", dissect_ICBAAccoServerSRT_SetActivation_rqst, dissect_ICBAAccoServerSRT_SetActivation_resp },
{ 0, NULL, NULL, NULL },
};
@@ -3373,6 +4856,27 @@ proto_register_dcom_cba_acco (void)
{ "Length", "cba.acco.cb_item_length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
{ &hf_cba_acco_cb_item_data,
{ "Data(Hex)", "cba.acco.cb_item_data", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
+ { &hf_cba_connect_in,
+ { "Connect in frame", "cba.connect_in", FT_FRAMENUM, BASE_NONE,
+ NULL, 0, "This connection Connect was in the packet with this number", HFILL }},
+ { &hf_cba_disconnect_in,
+ { "Disconnect in frame", "cba.disconnect_in", FT_FRAMENUM, BASE_NONE,
+ NULL, 0, "This connection Disconnect was in the packet with this number", HFILL }},
+ { &hf_cba_connectcr_in,
+ { "ConnectCR in frame", "cba.connect_in", FT_FRAMENUM, BASE_NONE,
+ NULL, 0, "This frame ConnectCR was in the packet with this number", HFILL }},
+ { &hf_cba_disconnectcr_in,
+ { "DisconnectCR in frame", "cba.disconnect_in", FT_FRAMENUM, BASE_NONE,
+ NULL, 0, "This frame DisconnectCR was in the packet with this number", HFILL }},
+ { &hf_cba_disconnectme_in,
+ { "DisconnectMe in frame", "cba.disconnectme_in", FT_FRAMENUM, BASE_NONE,
+ NULL, 0, "This connection/frame DisconnectMe was in the packet with this number", HFILL }},
+ { &hf_cba_data_first_in,
+ { "First data in frame", "cba.data_first_in", FT_FRAMENUM, BASE_NONE,
+ NULL, 0, "The first data of this connection/frame in the packet with this number", HFILL }},
+ { &hf_cba_data_last_in,
+ { "Last data in frame", "cba.data_last_in", FT_FRAMENUM, BASE_NONE,
+ NULL, 0, "The last data of this connection/frame in the packet with this number", HFILL }},
};
ett5[0] = &ett_ICBAAccoMgt;
@@ -3414,11 +4918,13 @@ proto_register_dcom_cba_acco (void)
proto_ICBAAccoServerSRT = proto_register_protocol ("ICBAAccoServerSRT", "ICBAAccoServSRT", "cba_acco_server_srt");
proto_register_subtree_array (ett4, array_length (ett4));
- ett3[0] = &ett_ICBAAccoSync;
- ett3[1] = &ett_cba_readitemout;
- ett3[2] = &ett_cba_writeitemin;
+ ett5[0] = &ett_ICBAAccoSync;
+ ett5[1] = &ett_cba_readitemout;
+ ett5[2] = &ett_cba_writeitemin;
+ ett5[3] = &ett_cba_frame_info;
+ ett5[4] = &ett_cba_conn_info;
proto_ICBAAccoSync = proto_register_protocol ("ICBAAccoSync", "ICBAAccoSync", "cba_acco_sync");
- proto_register_subtree_array (ett3, array_length (ett3));
+ proto_register_subtree_array (ett5, array_length (ett5));
}
diff --git a/epan/dissectors/packet-dcom-cba-acco.h b/epan/dissectors/packet-dcom-cba-acco.h
index 73ca6441ee..d7d2438a0a 100644
--- a/epan/dissectors/packet-dcom-cba-acco.h
+++ b/epan/dissectors/packet-dcom-cba-acco.h
@@ -25,8 +25,54 @@
#ifndef __PACKET_DCERPC_DCOM_CBA_ACCO_H
#define __PACKET_DCERPC_DCOM_CBA_ACCO_H
-int
+typedef struct cba_pdev_s {
+ GList *ldevs;
+ dcom_object_t *object;
+ gint first_packet;
+
+ const guint8 ip[4];
+} cba_pdev_t;
+
+typedef struct cba_ldev_s {
+ GList *provframes;
+ GList *consframes;
+ GList *provconns;
+ GList *consconns;
+ dcom_object_t *ldev_object;
+ dcom_object_t *acco_object;
+ cba_pdev_t *parent;
+ gint first_packet;
+
+ const char *name;
+} cba_ldev_t;
+
+
+extern GList *cba_pdevs;
+
+extern cba_pdev_t *
+cba_pdev_find(packet_info *pinfo, const char *ip, e_uuid_t *ipid);
+
+extern void
+cba_pdev_link(packet_info *pinfo, cba_pdev_t *pdev, dcom_interface_t *pdev_interf);
+
+extern cba_pdev_t *
+cba_pdev_add(packet_info *pinfo, const char *ip);
+
+extern void
+cba_ldev_link(packet_info *pinfo, cba_ldev_t *ldev, dcom_interface_t *ldev_interf);
+
+extern void
+cba_ldev_link_acco(packet_info *pinfo, cba_ldev_t *ldev, dcom_interface_t *acco_interf);
+
+extern cba_ldev_t *
+cba_ldev_find(packet_info *pinfo, const gchar *ip, e_uuid_t *ipid);
+
+extern cba_ldev_t *
+cba_ldev_add(packet_info *pinfo, cba_pdev_t *pdev, const char *name);
+
+
+/*int
dissect_CBA_Connection_Data(tvbuff_t *tvb, packet_info *pinfo,
- proto_tree *tree);
+ proto_tree *tree, cba_ldev_t *ldev, cba_frame_t *frame);*/
#endif /* packet-dcerpc-dcom-cba-acco.h */
diff --git a/epan/dissectors/packet-dcom-cba.c b/epan/dissectors/packet-dcom-cba.c
index a0164f4d2e..d273d29d6e 100644
--- a/epan/dissectors/packet-dcom-cba.c
+++ b/epan/dissectors/packet-dcom-cba.c
@@ -33,9 +33,12 @@
#include <glib.h>
#include <epan/packet.h>
+#include <epan/emem.h>
+#include <epan/expert.h>
#include "packet-dcerpc.h"
#include "packet-dcom.h"
#include "packet-dcom-dispatch.h"
+#include "packet-dcom-cba-acco.h"
static int hf_cba_opnum = -1;
@@ -569,6 +572,8 @@ dissect_ICBAPhysicalDevice_get_LogicalDevice_rqst(tvbuff_t *tvb, int offset,
guint32 u32Pointer;
gchar szStr[1000];
guint32 u32MaxStr = sizeof(szStr);
+ dcerpc_info *info = (dcerpc_info *) pinfo->private_data;
+ gchar *call;
offset = dissect_dcom_this(tvb, offset, pinfo, tree, drep);
@@ -579,7 +584,12 @@ dissect_ICBAPhysicalDevice_get_LogicalDevice_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_BSTR(tvb, offset, pinfo, tree, drep,
hf_cba_name, szStr, u32MaxStr);
}
-
+
+ if(szStr != NULL) {
+ call = se_strdup(szStr);
+ info->call_data->private_data = call;
+ }
+
if (check_col(pinfo->cinfo, COL_INFO)) {
col_append_fstr(pinfo->cinfo, COL_INFO, ": \"%s\"", szStr);
}
@@ -593,11 +603,31 @@ dissect_ICBAPhysicalDevice_get_LogicalDevice_resp(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
guint32 u32HResult;
+ dcerpc_info *info = (dcerpc_info *) pinfo->private_data;
+ gchar *ldev_name = info->call_data->private_data;
+ dcom_interface_t *pdev_interf;
+ dcom_interface_t *ldev_interf;
+ cba_pdev_t *pdev;
+ cba_ldev_t *ldev;
offset = dissect_dcom_that(tvb, offset, pinfo, tree, drep);
- offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, drep, 0);
+ offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, drep, 0, &ldev_interf);
+
+ /* try to read the ldev name from the request */
+ if(ldev_name != NULL && ldev_interf != NULL) {
+ /* XXX - this is a hack to create a pdev interface */
+ /* as I currently don't understand the objref process for a root interface! */
+ pdev_interf = dcom_interface_new(pinfo, pinfo->net_dst.data, &uuid_ICBAPhysicalDevice, 0, 0, &info->call_data->object_uuid);
+ if(pdev_interf != NULL) {
+ pdev = cba_pdev_add(pinfo, pinfo->net_dst.data);
+ cba_pdev_link(pinfo, pdev, pdev_interf);
+
+ ldev = cba_ldev_add(pinfo, pdev, ldev_name);
+ cba_ldev_link(pinfo, ldev, ldev_interf);
+ }
+ }
offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep,
&u32HResult);
@@ -730,7 +760,38 @@ dissect_Revision_resp(tvbuff_t *tvb, int offset,
static int
-dissect_get_Name_resp(tvbuff_t *tvb, int offset,
+dissect_ICBALogicalDevice_get_Name_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ gchar szStr[1000];
+ guint32 u32MaxStr = sizeof(szStr);
+ guint32 u32Pointer;
+ guint32 u32HResult;
+
+
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, drep,
+ &u32Pointer);
+ if (u32Pointer) {
+ offset = dissect_dcom_BSTR(tvb, offset, pinfo, tree, drep,
+ hf_cba_name, szStr, u32MaxStr);
+ }
+
+ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep,
+ &u32HResult);
+
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ": \"%s\" -> %s", szStr,
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
+ }
+
+ return offset;
+}
+
+
+static int
+dissect_RTAuto_get_Name_resp(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
@@ -743,11 +804,25 @@ dissect_ICBALogicalDevice_get_ACCO_resp(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
guint32 u32HResult;
+ dcom_interface_t *acco_interf;
+ dcerpc_info *info = (dcerpc_info *) pinfo->private_data;
+ cba_ldev_t *ldev;
offset = dissect_dcom_that(tvb, offset, pinfo, tree, drep);
- offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, drep, 0);
+ offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, drep, 0, &acco_interf);
+ if(acco_interf == NULL) {
+ expert_add_info_format(pinfo, NULL, PI_UNDECODED, PI_WARN,
+ "LDev_get_ACCO: can't resolve ACCO interface pointer");
+ }
+
+ ldev = cba_ldev_find(pinfo, pinfo->net_src.data, &info->call_data->object_uuid);
+
+ /* "crosslink" interface and it's object */
+ if(ldev != NULL && acco_interf != NULL) {
+ cba_ldev_link_acco(pinfo, ldev, acco_interf);
+ }
offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep, &u32HResult);
@@ -769,7 +844,7 @@ dissect_ICBALogicalDevice_get_RTAuto_resp(tvbuff_t *tvb, int offset,
offset = dissect_dcom_that(tvb, offset, pinfo, tree, drep);
- offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, drep, 0);
+ offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, drep, 0, NULL);
offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep, &u32HResult);
@@ -857,7 +932,7 @@ dissect_Advise_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_this(tvb, offset, pinfo, tree, drep);
- offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, drep, 0);
+ offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, drep, 0, NULL);
return offset;
}
@@ -1001,7 +1076,7 @@ dissect_ICBAPhysicalDevicePCEvent_OnLogicalDeviceAdded_rqst(tvbuff_t *tvb, int o
offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, drep,
hf_cba_cookie, &u32Cookie);
- offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, drep, 0);
+ offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, drep, 0, NULL);
offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep,
&u32HResult);
@@ -1158,7 +1233,7 @@ static dcerpc_sub_dissector ICBALogicalDevice_dissectors[] = {
{ 5, "GetIDsOfNames", dissect_IDispatch_GetIDsOfNames_rqst, dissect_IDispatch_GetIDsOfNames_resp },
{ 6, "Invoke", dissect_IDispatch_Invoke_rqst, dissect_IDispatch_Invoke_resp },
- { 7, "get_Name", dissect_dcom_simple_rqst, dissect_get_Name_resp },
+ { 7, "get_Name", dissect_dcom_simple_rqst, dissect_ICBALogicalDevice_get_Name_resp },
{ 8, "get_Producer", dissect_dcom_simple_rqst, dissect_get_Producer_resp },
{ 9, "get_Product", dissect_dcom_simple_rqst, dissect_get_Product_resp },
{10, "get_SerialNo", dissect_dcom_simple_rqst, dissect_get_SerialNo_resp },
@@ -1262,7 +1337,7 @@ static dcerpc_sub_dissector ICBARTAuto_dissectors[] = {
{ 5, "GetIDsOfNames", dissect_IDispatch_GetIDsOfNames_rqst, dissect_IDispatch_GetIDsOfNames_resp },
{ 6, "Invoke", dissect_IDispatch_Invoke_rqst, dissect_IDispatch_Invoke_resp },
- { 7, "get_Name", dissect_dcom_simple_rqst, dissect_get_Name_resp },
+ { 7, "get_Name", dissect_dcom_simple_rqst, dissect_RTAuto_get_Name_resp },
{ 8, "Revision", dissect_dcom_simple_rqst, dissect_Revision_resp },
/* stage 2 */
@@ -1290,6 +1365,11 @@ static dcerpc_sub_dissector ICBASystemProperties_dissectors[] = {
};
+static void cba_reinit( void) {
+ cba_pdevs = NULL;
+}
+
+
/* register protocol */
void
proto_register_dcom_cba (void)
@@ -1451,6 +1531,8 @@ proto_register_dcom_cba (void)
ett[0] = &ett_ICBASystemProperties;
proto_ICBASystemProperties = proto_register_protocol ("ICBASystemProperties", "ICBASysProp", "cba_sysprop");
proto_register_subtree_array (ett, array_length (ett));
+
+ register_init_routine(cba_reinit);
}
diff --git a/epan/dissectors/packet-dcom-dispatch.c b/epan/dissectors/packet-dcom-dispatch.c
index bca151fe9d..3e489c7dc0 100644
--- a/epan/dissectors/packet-dcom-dispatch.c
+++ b/epan/dissectors/packet-dcom-dispatch.c
@@ -147,7 +147,7 @@ dissect_IDispatch_GetTypeInfo_resp(tvbuff_t *tvb, int offset,
offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, drep,
&u32Pointer);
if (u32Pointer) {
- offset = dissect_dcom_MInterfacePointer(tvb, offset, pinfo, tree, drep, hf_dispatch_itinfo);
+ offset = dissect_dcom_MInterfacePointer(tvb, offset, pinfo, tree, drep, hf_dispatch_itinfo, NULL /* XXX */);
}
/* HRESULT of call */
diff --git a/epan/dissectors/packet-dcom-oxid.c b/epan/dissectors/packet-dcom-oxid.c
index 95fadcb31f..d4580673ce 100644
--- a/epan/dissectors/packet-dcom-oxid.c
+++ b/epan/dissectors/packet-dcom-oxid.c
@@ -239,7 +239,7 @@ dissect_oxid_resolve_oxid2_resp(tvbuff_t *tvb, int offset,
&u32ArraySize);
offset = dissect_dcom_DUALSTRINGARRAY(tvb, offset, pinfo, tree, drep,
- hf_oxid_bindings);
+ hf_oxid_bindings, NULL);
offset = dissect_dcom_UUID(tvb, offset, pinfo, tree, drep,
hf_oxid_ipid, &ipid);
@@ -275,7 +275,7 @@ dissect_oxid_server_alive2_resp(tvbuff_t *tvb, int offset, packet_info *pinfo,
dissect_dcerpc_uint64(tvb , offset, pinfo, tree, drep, hf_oxid_Unknown1, NULL);
offset += 8;
- offset = dissect_dcom_DUALSTRINGARRAY(tvb, offset, pinfo, tree, drep, hf_oxid_ds_array);
+ offset = dissect_dcom_DUALSTRINGARRAY(tvb, offset, pinfo, tree, drep, hf_oxid_ds_array, NULL);
/* unknown field 2 */
dissect_dcerpc_uint64(tvb, offset, pinfo, tree, drep, hf_oxid_Unknown2, NULL);
diff --git a/epan/dissectors/packet-dcom-remact.c b/epan/dissectors/packet-dcom-remact.c
index a90268e2e7..93e5671f21 100644
--- a/epan/dissectors/packet-dcom-remact.c
+++ b/epan/dissectors/packet-dcom-remact.c
@@ -39,8 +39,6 @@
static int hf_remact_opnum = -1;
-static int hf_remact_clsid = -1;
-static int hf_remact_iid = -1;
static int hf_remact_requested_protseqs = -1;
static int hf_remact_protseqs = -1;
static int hf_remact_interfaces = -1;
@@ -50,9 +48,7 @@ static int hf_remact_object_name = -1;
static int hf_remact_object_storage = -1;
static int hf_remact_interface_data = -1;
-static int hf_remact_oxid = -1;
static int hf_remact_oxid_bindings = -1;
-static int hf_remact_ipid = -1;
static int hf_remact_authn_hint = -1;
static const value_string dcom_protseq_vals[] = {
@@ -86,6 +82,8 @@ dissect_remact_remote_activation_rqst(tvbuff_t *tvb, int offset,
guint32 u32ArraySize;
guint32 u32ItemIdx;
guint16 u16ProtSeqs;
+ e_uuid_t clsid;
+ e_uuid_t iid;
gchar szObjName[1000] = { 0 };
guint32 u32ObjNameLen = sizeof(szObjName);
@@ -93,7 +91,7 @@ dissect_remact_remote_activation_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_this(tvb, offset, pinfo, tree, drep);
offset = dissect_dcom_append_UUID(tvb, offset, pinfo, tree, drep,
- hf_remact_clsid, "CLSID", -1);
+ hf_dcom_clsid, "CLSID", -1, &clsid);
offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, drep,
&u32Pointer);
@@ -103,7 +101,7 @@ dissect_remact_remote_activation_rqst(tvbuff_t *tvb, int offset,
}
offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, drep,
- hf_remact_object_storage);
+ hf_remact_object_storage, NULL /* XXX */);
offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, drep,
hf_remact_client_impl_level, &u32ClientImpLevel);
@@ -121,7 +119,7 @@ dissect_remact_remote_activation_rqst(tvbuff_t *tvb, int offset,
u32ItemIdx = 1;
while (u32Interfaces--) {
offset = dissect_dcom_append_UUID(tvb, offset, pinfo, tree, drep,
- hf_remact_iid, "IID", u32ArraySize);
+ hf_dcom_iid, "IID", u32ArraySize, &iid);
u32ItemIdx++;
}
@@ -161,18 +159,18 @@ dissect_remact_remote_activation_resp(tvbuff_t *tvb, int offset,
offset = dissect_dcom_that(tvb, offset, pinfo, tree, drep);
offset = dissect_dcom_ID(tvb, offset, pinfo, tree, drep,
- hf_remact_oxid, NULL);
+ hf_dcom_oxid, NULL);
offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, drep,
&u32Pointer);
if (u32Pointer) {
offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, drep,
&u32ArraySize);
offset = dissect_dcom_DUALSTRINGARRAY(tvb, offset, pinfo, tree, drep,
- hf_remact_oxid_bindings);
+ hf_remact_oxid_bindings, NULL);
}
offset = dissect_dcom_UUID(tvb, offset, pinfo, tree, drep,
- hf_remact_ipid, &ipid);
+ hf_dcom_ipid, &ipid);
offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, drep,
hf_remact_authn_hint, &u32AuthnHint);
offset = dissect_dcom_COMVERSION(tvb, offset, pinfo, tree, drep,
@@ -189,7 +187,7 @@ dissect_remact_remote_activation_resp(tvbuff_t *tvb, int offset,
&u32Pointer);
if (u32Pointer) {
u32VariableOffset = dissect_dcom_MInterfacePointer(tvb, u32VariableOffset, pinfo, tree, drep,
- hf_remact_interface_data);
+ hf_remact_interface_data, NULL /* XXX */);
}
}
offset = u32VariableOffset;
@@ -235,10 +233,6 @@ proto_register_remact (void)
{ &hf_remact_opnum,
{ "Operation", "remact_opnum", FT_UINT16, BASE_DEC, NULL, 0x0, "Operation", HFILL }},
- { &hf_remact_clsid,
- { "CLSID", "remact_clsid", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
- { &hf_remact_iid,
- { "IID", "remact_iid", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
{ &hf_remact_requested_protseqs,
{ "RequestedProtSeqs", "remact_req_prot_seqs", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
{ &hf_remact_protseqs,
@@ -256,12 +250,8 @@ proto_register_remact (void)
{ &hf_remact_interface_data,
{ "InterfaceData", "remact_interface_data", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
- { &hf_remact_oxid,
- { "OXID", "remact_oxid", FT_UINT64, BASE_HEX, NULL, 0x0, "", HFILL }},
{ &hf_remact_oxid_bindings,
{ "OxidBindings", "hf_remact_oxid_bindings", FT_NONE, BASE_DEC, NULL, 0x0, "", HFILL }},
- { &hf_remact_ipid,
- { "IPID", "remact_ipid", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
{ &hf_remact_authn_hint,
{ "AuthnHint", "remact_authn_hint", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
};
diff --git a/epan/dissectors/packet-dcom-remunkn.c b/epan/dissectors/packet-dcom-remunkn.c
index 4f608681d8..d7f29aaf08 100644
--- a/epan/dissectors/packet-dcom-remunkn.c
+++ b/epan/dissectors/packet-dcom-remunkn.c
@@ -33,6 +33,7 @@
#include <glib.h>
#include <epan/packet.h>
+#include <epan/emem.h>
#include "packet-dcerpc.h"
#include "packet-dcom.h"
@@ -76,6 +77,11 @@ static guint16 ver_remunk2 = 0;
static int proto_remunk2 = -1;
+typedef struct remunk_remqueryinterface_call_s {
+ guint iid_count;
+ e_uuid_t *iids;
+} remunk_remqueryinterface_call_t;
+
static int
dissect_remunk_remqueryinterface_rqst(tvbuff_t *tvb, int offset,
@@ -86,9 +92,12 @@ dissect_remunk_remqueryinterface_rqst(tvbuff_t *tvb, int offset,
guint16 u16IIDs;
guint32 u32ArraySize;
guint32 u32ItemIdx;
+ e_uuid_t iid;
+ dcerpc_info *info = (dcerpc_info *) pinfo->private_data;
+ remunk_remqueryinterface_call_t *call;
- offset = dissect_dcom_this(tvb, offset, pinfo, tree, drep);
+ offset = dissect_dcom_this(tvb, offset, pinfo, tree, drep);
offset = dissect_dcom_UUID(tvb, offset, pinfo, tree, drep,
hf_remunk_ipid, &ipid);
@@ -102,10 +111,22 @@ dissect_remunk_remqueryinterface_rqst(tvbuff_t *tvb, int offset,
offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, drep,
&u32ArraySize);
- u32ItemIdx = 1;
- while (u32ArraySize--) {
+ /* limit the allocation to a reasonable size */
+ if(u32ArraySize < 100) {
+ call = se_alloc(sizeof(remunk_remqueryinterface_call_t) + u32ArraySize * sizeof(e_uuid_t));
+ call->iid_count = u32ArraySize;
+ call->iids = (e_uuid_t *) (call+1);
+ info->call_data->private_data = call;
+ } else {
+ call = NULL;
+ }
+
+ for (u32ItemIdx = 0; u32ArraySize--; u32ItemIdx++) {
offset = dissect_dcom_append_UUID(tvb, offset, pinfo, tree, drep,
- hf_remunk_iid, "IID", u32ItemIdx++);
+ hf_remunk_iid, "IID", u32ItemIdx+1, &iid);
+ if(call != NULL) {
+ call->iids[u32ItemIdx] = iid;
+ }
}
return offset;
@@ -123,9 +144,17 @@ dissect_remunk_remqueryinterface_resp(tvbuff_t *tvb, int offset,
proto_tree *sub_tree;
guint32 u32HResult;
guint32 u32SubStart;
+ e_uuid_t iid;
+ e_uuid_t iid_null = DCERPC_UUID_NULL;
+ dcerpc_info *info = (dcerpc_info *) pinfo->private_data;
+ remunk_remqueryinterface_call_t *call = info->call_data->private_data;
+ guint64 oxid;
+ guint64 oid;
+ e_uuid_t ipid;
+ dcom_interface_t *dcom_if;
- offset = dissect_dcom_that(tvb, offset, pinfo, tree, drep);
+ offset = dissect_dcom_that(tvb, offset, pinfo, tree, drep);
offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, drep,
&u32Pointer);
@@ -134,7 +163,7 @@ dissect_remunk_remqueryinterface_resp(tvbuff_t *tvb, int offset,
u32ItemIdx = 1;
while (u32ArraySize--) {
- /* add subtree */
+ /* add subtree */
sub_item = proto_tree_add_item(tree, hf_remunk_qiresult, tvb, offset, 0, FALSE);
sub_tree = proto_item_add_subtree(sub_item, ett_remunk_rqi_result);
@@ -144,10 +173,27 @@ dissect_remunk_remqueryinterface_resp(tvbuff_t *tvb, int offset,
u32SubStart = offset - 4;
offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, drep,
&u32Pointer);
- if (u32Pointer) {
- offset = dissect_dcom_STDOBJREF(tvb, offset, pinfo, sub_tree, drep, 0 /* hfindex */);
+
+ /* try to read the iid from the request */
+ if(call != NULL && u32ItemIdx <= call->iid_count) {
+ iid = call->iids[u32ItemIdx-1];
+ } else {
+ iid = iid_null;
}
+ /* XXX - this doesn't seem to be dependent on the pointer above?!? */
+ /*if (u32Pointer) {*/
+ offset = dissect_dcom_STDOBJREF(tvb, offset, pinfo, sub_tree, drep, 0 /* hfindex */,
+ &oxid, &oid, &ipid);
+ /*}*/
+
+ /* add interface instance to database (we currently only handle IPv4) */
+ if(pinfo->net_src.type == AT_IPv4) {
+ dcom_if = dcom_interface_new(pinfo,
+ pinfo->net_src.data,
+ &iid, oxid, oid, &ipid);
+ }
+
/* update subtree */
proto_item_append_text(sub_item, "[%u]: %s",
u32ItemIdx,
@@ -163,7 +209,7 @@ dissect_remunk_remqueryinterface_resp(tvbuff_t *tvb, int offset,
u32ItemIdx++;
}
-
+
/* HRESULT of call */
offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep,
&u32HResult);
diff --git a/epan/dissectors/packet-dcom-sysact.c b/epan/dissectors/packet-dcom-sysact.c
index 6b278d06ea..43c0f119eb 100644
--- a/epan/dissectors/packet-dcom-sysact.c
+++ b/epan/dissectors/packet-dcom-sysact.c
@@ -58,7 +58,7 @@ dissect_remsysact_remotecreateinstance_rqst(tvbuff_t *tvb, int offset,
4);
offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, drep,
- hf_sysact_unknown);
+ hf_sysact_unknown, NULL /* XXX */);
return offset;
}
@@ -72,7 +72,7 @@ dissect_remsysact_remotecreateinstance_resp(tvbuff_t *tvb, int offset,
offset = dissect_dcom_that(tvb, offset, pinfo, tree, drep);
offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, drep,
- hf_sysact_unknown);
+ hf_sysact_unknown, NULL /* XXX */);
offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep,
NULL /* pu32HResult */);
diff --git a/epan/dissectors/packet-dcom.c b/epan/dissectors/packet-dcom.c
index 8cabf32b95..116f147514 100644
--- a/epan/dissectors/packet-dcom.c
+++ b/epan/dissectors/packet-dcom.c
@@ -85,6 +85,8 @@
#include <glib.h>
#include <epan/packet.h>
#include <epan/emem.h>
+#include <epan/addr_resolv.h>
+#include <epan/inet_aton.h>
#include "packet-dcerpc.h"
#include "packet-dcom.h"
#include "prefs.h"
@@ -134,8 +136,8 @@ gint ett_dcom_objref = -1;
static int hf_dcom_objref = -1;
static int hf_dcom_objref_signature = -1;
static int hf_dcom_objref_flags = -1;
-static int hf_dcom_objref_iid = -1;
-static int hf_dcom_objref_clsid = -1;
+int hf_dcom_iid = -1;
+int hf_dcom_clsid = -1;
static int hf_dcom_objref_resolver_address = -1;
static int hf_dcom_objref_cbextension = -1;
static int hf_dcom_objref_size = -1;
@@ -144,9 +146,9 @@ gint ett_dcom_stdobjref = -1;
static int hf_dcom_stdobjref = -1;
static int hf_dcom_stdobjref_flags = -1;
static int hf_dcom_stdobjref_public_refs = -1;
-static int hf_dcom_stdobjref_oxid = -1;
-static int hf_dcom_stdobjref_oid = -1;
-static int hf_dcom_stdobjref_ipid = -1;
+int hf_dcom_oxid = -1;
+int hf_dcom_oid = -1;
+int hf_dcom_ipid = -1;
gint ett_dcom_dualstringarray = -1;
gint ett_dcom_dualstringarray_binding = -1;
@@ -214,6 +216,160 @@ static int hf_dcom_vt_byref = -1;
static int hf_dcom_vt_dispatch = -1;
+GList *dcom_machines;
+GList *dcom_interfaces;
+
+void dcom_interface_dump(void) {
+ dcom_machine_t *machine;
+ dcom_object_t *object;
+ dcom_interface_t *interf;
+ GList *machines;
+ GList *objects;
+ GList *interfaces;
+
+
+ for(machines = dcom_machines; machines != NULL; machines = g_list_next(machines)) {
+ machine = machines->data;
+ g_warning("Machine(#%4u): IP:%s", machine->first_packet, ip_to_str(machine->ip));
+
+ for(objects = machine->objects; objects != NULL; objects = g_list_next(objects)) {
+ object = objects->data;
+ g_warning(" Object(#%4u): OID:0x%x%x private:0x%x", object->first_packet, object->oid, object->private_data);
+
+ for(interfaces = object->interfaces; interfaces != NULL; interfaces = g_list_next(interfaces)) {
+ interf = interfaces->data;
+ g_warning(" Interface(#%4u): iid:%s",
+ interf->first_packet, dcom_uuid_to_str(&interf->iid));
+ g_warning(" ipid:%s", dcom_uuid_to_str(&interf->ipid));
+ }
+ }
+ }
+}
+
+
+dcom_interface_t *dcom_interface_find(packet_info *pinfo, const guint8 *ip, e_uuid_t *ipid)
+{
+ dcom_interface_t *interf;
+ GList *interfaces;
+ static const e_uuid_t uuid_null = DCERPC_UUID_NULL;
+
+
+ if(memcmp(ipid, &uuid_null, sizeof(uuid_null)) == 0)
+ {
+ return NULL;
+ }
+
+ for(interfaces = dcom_interfaces; interfaces != NULL; interfaces = g_list_next(interfaces)) {
+ interf = interfaces->data;
+
+ if(memcmp(&interf->ipid, ipid, sizeof(e_uuid_t)) == 0) {
+ return interf;
+ }
+ }
+
+ return NULL;
+}
+
+
+dcom_interface_t *dcom_interface_new(packet_info *pinfo, const guint8 *ip, e_uuid_t *iid, guint64 oxid, guint64 oid, e_uuid_t *ipid)
+{
+ static const e_uuid_t uuid_null = DCERPC_UUID_NULL;
+ GList *dcom_iter;
+ dcom_machine_t *machine;
+ dcom_object_t *object;
+ dcom_interface_t *interf;
+
+
+ if( memcmp(iid, &uuid_null, sizeof(uuid_null)) == 0 ||
+ memcmp(ipid, &uuid_null, sizeof(uuid_null)) == 0)
+ {
+ return NULL;
+ }
+
+ if(oxid == 0 || oid == 0) {
+ /*g_warning("interface_new#%u", pinfo->fd->num);*/
+
+ interf = se_alloc(sizeof(dcom_interface_t));
+ interf->parent = NULL; //object;
+ interf->private_data = NULL;
+ interf->first_packet = pinfo->fd->num;
+ interf->iid = *iid;
+ interf->ipid = *ipid;
+
+ dcom_interfaces = g_list_append(dcom_interfaces, interf);
+ //object->interfaces = g_list_append(object->interfaces, interf);
+ return interf;
+ }
+
+ /* find machine */
+ dcom_iter = dcom_machines;
+ while(dcom_iter != NULL) {
+ machine = dcom_iter->data;
+ if(memcmp(machine->ip, ip, 4) == 0) {
+ break;
+ }
+ dcom_iter = g_list_next(dcom_iter);
+ }
+
+ /* create new machine if not found */
+ if(dcom_iter == NULL) {
+ machine = se_alloc(sizeof(dcom_machine_t));
+ memcpy( (void *) (machine->ip), ip, 4);
+ machine->objects = NULL;
+ machine->first_packet = pinfo->fd->num;
+ dcom_machines = g_list_append(dcom_machines, machine);
+ }
+
+ /* find object */
+ dcom_iter = machine->objects;
+ while(dcom_iter != NULL) {
+ object = dcom_iter->data;
+ if(object->oid == oid) {
+ break;
+ }
+ dcom_iter = g_list_next(dcom_iter);
+ }
+
+ /* create new object if not found */
+ if(dcom_iter == NULL) {
+ object = se_alloc(sizeof(dcom_object_t));
+ object->parent = machine;
+ object->interfaces = NULL;
+ object->private_data = NULL;
+ object->first_packet = pinfo->fd->num;
+ object->oid = oid;
+ object->oxid = oxid;
+
+ machine->objects = g_list_append(machine->objects, object);
+ }
+
+ /* find interface */
+ dcom_iter = object->interfaces;
+ while(dcom_iter != NULL) {
+ interf = dcom_iter->data;
+ if(memcmp(&interf->ipid, ipid, sizeof(e_uuid_t)) == 0) {
+ break;
+ }
+ dcom_iter = g_list_next(dcom_iter);
+ }
+
+ /* create new interface if not found */
+ if(dcom_iter == NULL) {
+ interf = se_alloc(sizeof(dcom_interface_t));
+ interf->parent = object;
+ interf->private_data = NULL;
+ interf->first_packet = pinfo->fd->num;
+ interf->iid = *iid;
+ interf->ipid = *ipid;
+
+ object->interfaces = g_list_append(object->interfaces, interf);
+ dcom_interfaces = g_list_append(dcom_interfaces, interf);
+ }
+
+ return interf;
+}
+
+
/*
* Flag bits in connection-oriented PDU header.
*/
@@ -586,6 +742,9 @@ dissect_dcom_this(tvbuff_t *tvb, int offset,
proto_item *sub_item;
proto_tree *sub_tree;
guint32 u32SubStart;
+ proto_item *pi;
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ e_uuid_t uuid_null = DCERPC_UUID_NULL;
sub_item = proto_tree_add_protocol_format(tree, proto_dcom, tvb, offset, 0,
@@ -611,6 +770,11 @@ dissect_dcom_this(tvbuff_t *tvb, int offset,
u16VersionMajor, u16VersionMinor, dcom_uuid_to_str(&uuidCausality));
proto_item_set_len(sub_item, offset - u32SubStart);
+ if(memcmp(&info->call_data->object_uuid, &uuid_null, sizeof(uuid_null)) != 0) {
+ pi = proto_tree_add_guid(tree, hf_dcom_ipid, tvb, offset, GUID_LEN, (e_guid_t *) &info->call_data->object_uuid);
+ PROTO_ITEM_SET_GENERATED(pi);
+ }
+
return offset;
}
@@ -623,6 +787,9 @@ dissect_dcom_that(tvbuff_t *tvb, int offset,
proto_item *sub_item;
proto_tree *sub_tree;
guint32 u32SubStart;
+ proto_item *pi;
+ dcerpc_info *info = (dcerpc_info *)pinfo->private_data;
+ e_uuid_t uuid_null = DCERPC_UUID_NULL;
sub_item = proto_tree_add_protocol_format(tree, proto_dcom, tvb, offset, 0,
@@ -638,6 +805,11 @@ dissect_dcom_that(tvbuff_t *tvb, int offset,
/* update subtree header */
proto_item_set_len(sub_item, offset - u32SubStart);
+ if(memcmp(&info->call_data->object_uuid, &uuid_null, sizeof(uuid_null)) != 0) {
+ pi = proto_tree_add_guid(tree, hf_dcom_ipid, tvb, offset, GUID_LEN, (e_guid_t *) &info->call_data->object_uuid);
+ PROTO_ITEM_SET_GENERATED(pi);
+ }
+
return offset;
}
@@ -1177,7 +1349,7 @@ dissect_dcom_VARIANT(tvbuff_t *tvb, int offset, packet_info *pinfo,
offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, drep, &u32Pointer);
if (u32Pointer) {
offset = dissect_dcom_MInterfacePointer(tvb, offset, pinfo, sub_tree, drep,
- hf_dcom_vt_dispatch);
+ hf_dcom_vt_dispatch, NULL); /* XXX - how to handle this? */
}
break;
case(WIRESHARK_VT_ARRAY):
@@ -1217,21 +1389,20 @@ dissect_dcom_VARIANT(tvbuff_t *tvb, int offset, packet_info *pinfo,
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)
+ int hfindex, const gchar *field_name, int field_index, e_uuid_t *uuid)
{
- e_uuid_t uuid;
const gchar *uuid_name;
offset = dissect_dcom_UUID(tvb, offset, pinfo, tree, drep,
- hfindex, &uuid);
+ 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);
+ uuid_name = dcerpc_get_uuid_name(uuid, 0);
if (field_index != -1) {
col_append_fstr(pinfo->cinfo, COL_INFO, " %s[%u]=%s",
@@ -1437,7 +1608,7 @@ dissect_dcom_BSTR(tvbuff_t *tvb, gint offset, packet_info *pinfo,
/* dissect an DUALSTRINGARRAY */
int
dissect_dcom_DUALSTRINGARRAY(tvbuff_t *tvb, gint offset, packet_info *pinfo,
- proto_tree *tree, guint8 *drep, int hfindex)
+ proto_tree *tree, guint8 *drep, int hfindex, gchar *ip)
{
guint16 u16NumEntries;
guint16 u16SecurityOffset;
@@ -1456,6 +1627,9 @@ dissect_dcom_DUALSTRINGARRAY(tvbuff_t *tvb, gint offset, packet_info *pinfo,
proto_tree *subsub_tree;
guint32 u32SubSubStart;
gboolean isPrintable;
+ guint32 first_ip = 0;
+ guint32 curr_ip = 0;
+ struct in_addr ipaddr;
/* add subtree header */
@@ -1485,6 +1659,30 @@ dissect_dcom_DUALSTRINGARRAY(tvbuff_t *tvb, gint offset, packet_info *pinfo,
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) */
+ /* XXX - this conversion is ugly */
+ if (inet_aton(szStr, &ipaddr)) {
+ if(get_host_ipaddr(szStr, &curr_ip)) {
+ curr_ip = ntohl(curr_ip);
+
+ /*expert_add_info_format(pinfo, NULL, PI_UNDECODED, PI_WARN, "DUALSTRINGARRAY: IP:%s",
+ ip_to_str( (gchar *) &curr_ip));*/
+
+ if(first_ip == 0) {
+ if(ip != NULL) {
+ memcpy(ip, &curr_ip, sizeof(curr_ip));
+ }
+ first_ip = curr_ip;
+ } else {
+ if(first_ip != curr_ip) {
+ expert_add_info_format(pinfo, NULL, PI_UNDECODED, PI_NOTE,
+ "DUALSTRINGARRAY: multiple IP's %s %s",
+ ip_to_str( (char *) &first_ip), ip_to_str( (char *) &curr_ip));
+ }
+ }
+ }
+ }
+
proto_item_append_text(subsub_item, "[%u]: TowerId=%s, NetworkAddr=\"%s\"",
u32StringBindings,
val_to_str(u16TowerId, dcom_dualstringarray_tower_id_vals, "Unknown (0x%04x"),
@@ -1532,11 +1730,11 @@ dissect_dcom_DUALSTRINGARRAY(tvbuff_t *tvb, gint offset, packet_info *pinfo,
/* dissect an STDOBJREF */
int
dissect_dcom_STDOBJREF(tvbuff_t *tvb, gint offset, packet_info *pinfo,
- proto_tree *tree, guint8 *drep, int hfindex _U_)
+ proto_tree *tree, guint8 *drep, int hfindex _U_,
+ guint64 *oxid, guint64 *oid, e_uuid_t *ipid)
{
guint32 u32Flags;
guint32 u32PublicRefs;
- e_uuid_t ipid;
proto_item *sub_item;
proto_tree *sub_tree;
guint32 u32SubStart;
@@ -1553,15 +1751,15 @@ dissect_dcom_STDOBJREF(tvbuff_t *tvb, gint offset, packet_info *pinfo,
offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
hf_dcom_stdobjref_public_refs, &u32PublicRefs);
offset = dissect_dcom_ID(tvb, offset, pinfo, sub_tree, drep,
- hf_dcom_stdobjref_oxid, NULL);
+ hf_dcom_oxid, oxid);
offset = dissect_dcom_ID(tvb, offset, pinfo, sub_tree, drep,
- hf_dcom_stdobjref_oid, NULL);
+ hf_dcom_oid, oid);
offset = dissect_dcom_UUID(tvb, offset, pinfo, sub_tree, drep,
- hf_dcom_stdobjref_ipid, &ipid);
+ hf_dcom_ipid, ipid);
/* append info to subtree header */
proto_item_append_text(sub_item, ": PublicRefs=%u IPID=%s",
- u32PublicRefs, dcom_uuid_to_str(&ipid));
+ u32PublicRefs, dcom_uuid_to_str(ipid));
proto_item_set_len(sub_item, offset - u32SubStart);
return offset;
@@ -1571,7 +1769,7 @@ dissect_dcom_STDOBJREF(tvbuff_t *tvb, gint offset, packet_info *pinfo,
/* dissect an OBJREF */
int
dissect_dcom_OBJREF(tvbuff_t *tvb, gint offset, packet_info *pinfo,
- proto_tree *tree, guint8 *drep, int hfindex)
+ proto_tree *tree, guint8 *drep, int hfindex, dcom_interface_t **interf)
{
guint32 u32Signature;
guint32 u32Flags;
@@ -1582,6 +1780,11 @@ dissect_dcom_OBJREF(tvbuff_t *tvb, gint offset, packet_info *pinfo,
guint32 u32SubStart;
guint32 u32CBExtension;
guint32 u32Size;
+ guint64 oxid;
+ guint64 oid;
+ e_uuid_t ipid;
+ dcom_interface_t *dcom_if = NULL;
+ gchar ip[4];
/* add subtree header */
@@ -1595,25 +1798,26 @@ dissect_dcom_OBJREF(tvbuff_t *tvb, gint offset, packet_info *pinfo,
offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
hf_dcom_objref_flags, &u32Flags);
offset = dissect_dcom_UUID(tvb, offset, pinfo, sub_tree, drep,
- hf_dcom_objref_iid, &iid);
-
+ hf_dcom_iid, &iid);
switch(u32Flags) {
case(0x1): /* standard */
- offset = dissect_dcom_STDOBJREF(tvb, offset, pinfo, sub_tree, drep, hfindex);
+ offset = dissect_dcom_STDOBJREF(tvb, offset, pinfo, sub_tree, drep, hfindex,
+ &oxid, &oid, &ipid);
offset = dissect_dcom_DUALSTRINGARRAY(tvb, offset, pinfo, sub_tree, drep,
- hf_dcom_objref_resolver_address);
+ hf_dcom_objref_resolver_address, ip);
break;
case(0x2): /* handler (untested) */
- offset = dissect_dcom_STDOBJREF(tvb, offset, pinfo, sub_tree, drep, hfindex);
+ offset = dissect_dcom_STDOBJREF(tvb, offset, pinfo, sub_tree, drep, hfindex,
+ &oxid, &oid, &iid);
offset = dissect_dcom_UUID(tvb, offset, pinfo, sub_tree, drep,
- hf_dcom_objref_clsid, &clsid);
+ hf_dcom_clsid, &clsid);
offset = dissect_dcom_DUALSTRINGARRAY(tvb, offset, pinfo, sub_tree, drep,
- hf_dcom_objref_resolver_address);
+ hf_dcom_objref_resolver_address, ip);
break;
case(0x4): /* custom */
offset = dissect_dcom_UUID(tvb, offset, pinfo, sub_tree, drep,
- hf_dcom_objref_clsid, &clsid);
+ hf_dcom_clsid, &clsid);
offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
hf_dcom_objref_cbextension, &u32CBExtension);
offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, drep,
@@ -1623,6 +1827,19 @@ dissect_dcom_OBJREF(tvbuff_t *tvb, gint offset, packet_info *pinfo,
break;
}
+ if(u32Flags == 0x1 || u32Flags == 0x2) {
+ /* add interface instance to database (we currently only handle IPv4) */
+ if(pinfo->net_src.type == AT_IPv4) {
+ dcom_if = dcom_interface_new(pinfo,
+ ip,
+ &iid, oxid, oid, &ipid);
+ }
+ }
+
+ if(interf != NULL) {
+ *interf = dcom_if;
+ }
+
/* append info to subtree header */
proto_item_set_len(sub_item, offset - u32SubStart);
@@ -1634,7 +1851,7 @@ dissect_dcom_OBJREF(tvbuff_t *tvb, gint offset, packet_info *pinfo,
/* dissect an MInterfacePointer */
int
dissect_dcom_MInterfacePointer(tvbuff_t *tvb, gint offset, packet_info *pinfo,
- proto_tree *tree, guint8 *drep, int hfindex)
+ proto_tree *tree, guint8 *drep, int hfindex, dcom_interface_t **interf)
{
guint32 u32CntData;
guint32 u32ArraySize;
@@ -1657,7 +1874,7 @@ dissect_dcom_MInterfacePointer(tvbuff_t *tvb, gint offset, packet_info *pinfo,
offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, sub_tree, drep, &u32ArraySize);
- offset = dissect_dcom_OBJREF(tvb, offset, pinfo, sub_tree, drep, hfindex);
+ offset = dissect_dcom_OBJREF(tvb, offset, pinfo, sub_tree, drep, hfindex, interf);
/* append info to subtree header */
proto_item_set_len(sub_item, offset - u32SubStart);
@@ -1669,7 +1886,7 @@ dissect_dcom_MInterfacePointer(tvbuff_t *tvb, gint offset, packet_info *pinfo,
/* dissect a pointer to a MInterfacePointer */
int
dissect_dcom_PMInterfacePointer(tvbuff_t *tvb, gint offset, packet_info *pinfo,
- proto_tree *tree, guint8 *drep, int hfindex)
+ proto_tree *tree, guint8 *drep, int hfindex, dcom_interface_t **interf)
{
guint32 u32Pointer;
@@ -1677,8 +1894,12 @@ dissect_dcom_PMInterfacePointer(tvbuff_t *tvb, gint offset, packet_info *pinfo,
offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, drep, &u32Pointer);
if (u32Pointer) {
- offset = dissect_dcom_MInterfacePointer(tvb, offset, pinfo, tree, drep, hfindex);
- }
+ offset = dissect_dcom_MInterfacePointer(tvb, offset, pinfo, tree, drep, hfindex, interf);
+ } else {
+ if(interf != NULL) {
+ *interf = NULL;
+ }
+ }
return offset;
}
@@ -1695,6 +1916,12 @@ void dcom_register_server_coclass(int proto _U_, int ett _U_, e_uuid_t *uuid _U_
}
+static void dcom_reinit( void) {
+ dcom_machines = NULL;
+ dcom_interfaces = NULL;
+}
+
+
void
proto_register_dcom (void)
{
@@ -1709,7 +1936,7 @@ proto_register_dcom (void)
{ &hf_dcom_this_res,
{ "Reserved", "dcom.this.res", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
{ &hf_dcom_this_cid,
- { "Causality ID", "dcom.this.uuid", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}
+ { "Causality ID", "dcom.this.uuid", FT_GUID, BASE_NONE, NULL, 0x0, "", HFILL }}
};
static hf_register_info hf_dcom_that_array[] = {
@@ -1781,10 +2008,10 @@ proto_register_dcom (void)
{ "Signature", "dcom.objref.signature", FT_UINT32, BASE_HEX, VALS(dcom_objref_signature_vals), 0x0, "", HFILL }},
{ &hf_dcom_objref_flags,
{ "Flags", "dcom.objref.flags", FT_UINT32, BASE_HEX, VALS(dcom_objref_flag_vals), 0x0, "", HFILL }},
- { &hf_dcom_objref_iid,
- { "IID", "dcom.objref.iid", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
- { &hf_dcom_objref_clsid,
- { "CLSID", "dcom.objref.clsid", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf_dcom_iid,
+ { "IID", "dcom.iid", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf_dcom_clsid,
+ { "CLSID", "dcom.clsid", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
{ &hf_dcom_objref_resolver_address,
{ "ResolverAddress", "dcom.objref.resolver_address", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
{ &hf_dcom_objref_cbextension,
@@ -1800,12 +2027,12 @@ proto_register_dcom (void)
{ "Flags", "dcom.stdobjref.flags", FT_UINT32, BASE_HEX, VALS(dcom_stdobjref_flag_vals), 0x0, "", HFILL }},
{ &hf_dcom_stdobjref_public_refs,
{ "PublicRefs", "dcom.stdobjref.public_refs", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
- { &hf_dcom_stdobjref_oxid,
- { "OXID", "dcom.stdobjref.oxid", FT_UINT64, BASE_HEX, NULL, 0x0, "", HFILL }},
- { &hf_dcom_stdobjref_oid,
- { "OID", "dcom.stdobjref.oid", FT_UINT64, BASE_HEX, NULL, 0x0, "", HFILL }},
- { &hf_dcom_stdobjref_ipid,
- { "IPID", "dcom.stdobjref.ipid", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}
+ { &hf_dcom_oxid,
+ { "OXID", "dcom.oxid", FT_UINT64, BASE_HEX, NULL, 0x0, "", HFILL }},
+ { &hf_dcom_oid,
+ { "OID", "dcom.oid", FT_UINT64, BASE_HEX, NULL, 0x0, "", HFILL }},
+ { &hf_dcom_ipid,
+ { "IPID", "dcom.ipid", FT_GUID, BASE_NONE, NULL, 0x0, "", HFILL }}
};
static hf_register_info hf_dcom_dualstringarray_array[] = {
@@ -1950,6 +2177,8 @@ proto_register_dcom (void)
"Display some DCOM unmarshalled fields "
"usually hidden",
&dcom_prefs_display_unmarshalling_details);
+
+ register_init_routine(dcom_reinit);
}
diff --git a/epan/dissectors/packet-dcom.h b/epan/dissectors/packet-dcom.h
index c95d0228c2..4d9cabcf89 100644
--- a/epan/dissectors/packet-dcom.h
+++ b/epan/dissectors/packet-dcom.h
@@ -29,10 +29,48 @@
extern const value_string dcom_hresult_vals[];
extern const value_string dcom_variant_type_vals[];
+extern int hf_dcom_iid;
+extern int hf_dcom_clsid;
+extern int hf_dcom_oxid;
+extern int hf_dcom_oid;
+extern int hf_dcom_ipid;
+
/* preferences */
extern int dcom_prefs_display_unmarshalling_details;
+typedef struct dcom_machine_s {
+ GList *objects;
+ gint first_packet;
+
+ const guint8 ip[4];
+} dcom_machine_t;
+
+typedef struct dcom_object_s {
+ dcom_machine_t *parent;
+ GList *interfaces;
+ void *private_data;
+ gint first_packet;
+
+ guint64 oid;
+ guint64 oxid;
+} dcom_object_t;
+
+typedef struct dcom_interface_s {
+ dcom_object_t *parent;
+ void *private_data;
+ gint first_packet;
+
+ e_uuid_t iid;
+ e_uuid_t ipid; /* the DCE/RPC Object UUID */
+} dcom_interface_t;
+
+
+extern dcom_interface_t *dcom_interface_new(packet_info *pinfo, const guint8 *ip, e_uuid_t *iid, guint64 oxid, guint64 oid, e_uuid_t *ipid);
+extern dcom_interface_t *dcom_interface_find(packet_info *pinfo, const guint8 *ip, e_uuid_t *ipid);
+extern void dcom_interface_dump(void);
+
+
/* the essential DCOM this and that, starting every call */
extern int
dissect_dcom_this(tvbuff_t *tvb, int offset,
@@ -59,7 +97,7 @@ dissect_dcom_that(tvbuff_t *tvb, int offset,
extern 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);
+ int hfindex, const gchar *field_name, int field_index, e_uuid_t *uuid);
extern const gchar* dcom_uuid_to_str(e_uuid_t *uuid);
extern int
@@ -103,22 +141,22 @@ dissect_dcom_BSTR(tvbuff_t *tvb, gint offset, packet_info *pinfo,
extern int
dissect_dcom_DUALSTRINGARRAY(tvbuff_t *tvb, gint offset, packet_info *pinfo,
- proto_tree *tree, guint8 *drep, int hfindex);
+ proto_tree *tree, guint8 *drep, int hfindex, gchar *ip);
extern int
dissect_dcom_STDOBJREF(tvbuff_t *tvb, gint offset, packet_info *pinfo,
- proto_tree *tree, guint8 *drep, int hfindex);
-
+ proto_tree *tree, guint8 *drep, int hfindex,
+ guint64 *oxid, guint64 *oid, e_uuid_t *ipid);
extern int
dissect_dcom_OBJREF(tvbuff_t *tvb, gint offset, packet_info *pinfo,
- proto_tree *tree, guint8 *drep, int hfindex);
+ proto_tree *tree, guint8 *drep, int hfindex, dcom_interface_t **interf);
extern int
dissect_dcom_MInterfacePointer(tvbuff_t *tvb, gint offset, packet_info *pinfo,
- proto_tree *tree, guint8 *drep, int hfindex);
+ proto_tree *tree, guint8 *drep, int hfindex, dcom_interface_t **interf);
extern int
dissect_dcom_PMInterfacePointer(tvbuff_t *tvb, gint offset, packet_info *pinfo,
- proto_tree *tree, guint8 *drep, int hfindex);
+ proto_tree *tree, guint8 *drep, int hfindex, dcom_interface_t **interf);
extern int
dissect_dcom_VARTYPE(tvbuff_t *tvb, int offset,