/* packet-dcom-cba-acco.c * Routines for DCOM CBA * * Wireshark - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * SPDX-License-Identifier: GPL-2.0-or-later */ #include "config.h" #include #include #include #include #include #include #include #include #include "packet-dcom-cba-acco.h" #include void proto_register_dcom_cba_acco(void); void proto_reg_handoff_dcom_cba_acco(void); static int hf_cba_acco_opnum = -1; static int hf_cba_acco_ping_factor = -1; static int hf_cba_acco_count = -1; static int hf_cba_acco_item = -1; static int hf_cba_acco_data = -1; static int hf_cba_acco_qc = -1; static int hf_cba_acco_time_stamp = -1; static int hf_cba_acco_conn_qos_type = -1; static int hf_cba_acco_conn_qos_value = -1; static int hf_cba_acco_conn_state = -1; static int hf_cba_acco_conn_cons_id = -1; static int hf_cba_acco_conn_version = -1; static int hf_cba_acco_conn_prov_id = -1; static int hf_cba_acco_conn_provider = -1; static int hf_cba_acco_conn_consumer = -1; static int hf_cba_acco_conn_provider_item = -1; static int hf_cba_acco_conn_consumer_item = -1; static int hf_cba_acco_conn_substitute = -1; static int hf_cba_acco_conn_epsilon = -1; static int hf_cba_acco_conn_persist = -1; static int hf_cba_acco_cb_length = -1; static int hf_cba_acco_cb_conn_data = -1; static int hf_cba_acco_cb_version = -1; static int hf_cba_acco_cb_flags = -1; static int hf_cba_acco_cb_count = -1; static int hf_cba_acco_cb_item = -1; 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; static int hf_cba_acco_serversrt_prov_mac = -1; static int hf_cba_acco_serversrt_cons_mac = -1; static int hf_cba_acco_serversrt_cr_id = -1; static int hf_cba_acco_serversrt_cr_length = -1; static int hf_cba_acco_serversrt_cr_flags = -1; static int hf_cba_acco_serversrt_cr_flags_timestamped = -1; static int hf_cba_acco_serversrt_cr_flags_reconfigure = -1; static int hf_cba_acco_serversrt_record_length = -1; /* static int hf_cba_acco_serversrt_action = -1; */ static int hf_cba_acco_serversrt_last_connect = -1; static int hf_cba_getprovconnout = -1; static int hf_cba_type_desc_len = -1; static int hf_cba_connectincr = -1; static int hf_cba_connectoutcr = -1; static int hf_cba_connectin = -1; static int hf_cba_connectout = -1; static int hf_cba_getconnectionout = -1; static int hf_cba_readitemout = -1; static int hf_cba_writeitemin = -1; static int hf_cba_addconnectionin = -1; static int hf_cba_addconnectionout = -1; static int hf_cba_getidout = -1; static int hf_cba_getconsconnout = -1; static int hf_cba_diagconsconnout = -1; static int hf_cba_acco_conn_error_state = -1; static int hf_cba_acco_info_max = -1; static int hf_cba_acco_info_curr = -1; static int hf_cba_acco_cdb_cookie = -1; static int hf_cba_acco_rtauto = -1; static int hf_cba_acco_prov_crid = -1; static int hf_cba_acco_diag_req = -1; static int hf_cba_acco_diag_in_length = -1; static int hf_cba_acco_diag_out_length = -1; static int hf_cba_acco_diag_data = -1; static int hf_cba_acco_dcom_call = -1; static int hf_cba_acco_srt_call = -1; gint ett_cba_connectincr = -1; gint ett_cba_connectoutcr = -1; gint ett_cba_connectin = -1; gint ett_cba_connectout = -1; gint ett_cba_getprovconnout = -1; gint ett_cba_addconnectionin = -1; gint ett_cba_addconnectionout = -1; gint ett_cba_getidout = -1; 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 expert_field ei_cba_acco_pdev_find = EI_INIT; static expert_field ei_cba_acco_prov_crid = EI_INIT; static expert_field ei_cba_acco_conn_consumer = EI_INIT; static expert_field ei_cba_acco_ldev_unknown = EI_INIT; static expert_field ei_cba_acco_no_request_info = EI_INIT; static expert_field ei_cba_acco_ipid_unknown = EI_INIT; static expert_field ei_cba_acco_qc = EI_INIT; static expert_field ei_cba_acco_pdev_find_unknown_interface = EI_INIT; static expert_field ei_cba_acco_disconnect = EI_INIT; static expert_field ei_cba_acco_connect = EI_INIT; static int proto_ICBAAccoMgt = -1; static gint ett_ICBAAccoMgt = -1; static e_guid_t uuid_ICBAAccoMgt = { 0xcba00041, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } }; static guint16 ver_ICBAAccoMgt = 0; static int proto_ICBAAccoMgt2 = -1; static e_guid_t uuid_ICBAAccoMgt2 = { 0xcba00046, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } }; static guint16 ver_ICBAAccoMgt2 = 0; static int proto_ICBAAccoCallback = -1; static gint ett_ICBAAccoCallback = -1; static gint ett_ICBAAccoCallback_Buffer = -1; static gint ett_ICBAAccoCallback_Item = -1; static e_guid_t uuid_ICBAAccoCallback = { 0xcba00042, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } }; static guint16 ver_ICBAAccoCallback = 0; static int proto_ICBAAccoCallback2 = -1; static e_guid_t uuid_ICBAAccoCallback2 = { 0xcba00047, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } }; static guint16 ver_ICBAAccoCallback2 = 0; static int proto_ICBAAccoServer = -1; static gint ett_ICBAAccoServer = -1; static e_guid_t uuid_ICBAAccoServer = { 0xcba00043, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } }; static guint16 ver_ICBAAccoServer = 0; static int proto_ICBAAccoServer2 = -1; static e_guid_t uuid_ICBAAccoServer2 = { 0xcba00048, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } }; static guint16 ver_ICBAAccoServer2 = 0; static int proto_ICBAAccoServerSRT = -1; static gint ett_ICBAAccoServerSRT = -1; static e_guid_t uuid_ICBAAccoServerSRT = { 0xcba00045, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } }; static guint16 ver_ICBAAccoServerSRT = 0; static int proto_ICBAAccoSync = -1; static gint ett_ICBAAccoSync = -1; static e_guid_t uuid_ICBAAccoSync = { 0xcba00044, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } }; static guint16 ver_ICBAAccoSync = 0; static const value_string cba_acco_qc_vals[] = { { 0x1c, "BadOutOfService" }, { 0x44, "UncertainLastUsableValue" }, { 0x48, "UncertainSubstituteSet" }, { 0x50, "UncertainSensorNotAccurate" }, { 0x80, "GoodNonCascOk" }, { 0, NULL } }; static const value_string cba_qos_type_vals[] = { { 0x00, "Acyclic" }, { 0x01, "Acyclic seconds" }, /* obsolete */ { 0x02, "Acyclic status" }, { 0x03, "Acyclic HMI" }, { 0x20, "Constant" }, { 0x30, "Cyclic Real-Time" }, { 0, NULL } }; static const value_string cba_persist_vals[] = { { 0x00, "Volatile" }, { 0x01, "PendingPersistent" }, { 0x02, "Persistent" }, { 0, NULL } }; static const value_string cba_acco_conn_state_vals[] = { { 0x00, "Passive" }, { 0x01, "Active" }, { 0, NULL } }; #if 0 static const value_string cba_acco_serversrt_action_vals[] = { { 0x00, "Activate" }, { 0x01, "Deactivate" }, { 0x02, "Remove" }, { 0, NULL } }; #endif static const value_string cba_acco_serversrt_last_connect_vals[] = { { 0x00, "CR not complete" }, { 0x01, "CR complete" }, { 0, NULL } }; static const value_string cba_acco_diag_req_vals[] = { { 0x0000, "Function directory" }, { 0x1000, "DevCat statistic" }, { 0x2000, "Reset statistic" }, { 0x3000, "Consumer Comm. Events" }, { 0x4000, "Provider Comm. Events" }, { 0, NULL } }; static const true_false_string cba_acco_call_flags = { "Consumer calls Provider (TRUE)", "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; 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; /* as we are a plugin, we cannot get this from libwireshark! */ const true_false_string acco_flags_set_truth = { "Set", "Not set" }; static gboolean cba_filter_valid(packet_info *pinfo) { void* profinet_type = p_get_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0); return ((profinet_type != NULL) && (GPOINTER_TO_UINT(profinet_type) < 10)); } static gchar* cba_build_filter(packet_info *pinfo) { gboolean is_tcp = proto_is_frame_protocol(pinfo->layers, "tcp"); void* profinet_type = p_get_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0); if ((pinfo->net_src.type == AT_IPv4) && (pinfo->net_dst.type == AT_IPv4) && is_tcp) { /* IPv4 */ switch(GPOINTER_TO_UINT(profinet_type)) { case 1: return ws_strdup_printf("(ip.src eq %s and ip.dst eq %s and cba.acco.dcom == 1) || (ip.src eq %s and ip.dst eq %s and cba.acco.dcom == 0)", address_to_str(pinfo->pool, &pinfo->net_dst), address_to_str(pinfo->pool, &pinfo->net_src), address_to_str(pinfo->pool, &pinfo->net_src), address_to_str(pinfo->pool, &pinfo->net_dst)); case 2: return ws_strdup_printf("(ip.src eq %s and ip.dst eq %s and cba.acco.dcom == 1) || (ip.src eq %s and ip.dst eq %s and cba.acco.dcom == 0)", address_to_str(pinfo->pool, &pinfo->net_src), address_to_str(pinfo->pool, &pinfo->net_dst), address_to_str(pinfo->pool, &pinfo->net_dst), address_to_str(pinfo->pool, &pinfo->net_src)); case 3: return ws_strdup_printf("(ip.src eq %s and ip.dst eq %s and cba.acco.srt == 1) || (ip.src eq %s and ip.dst eq %s and cba.acco.srt == 0)", address_to_str(pinfo->pool, &pinfo->net_dst), address_to_str(pinfo->pool, &pinfo->net_src), address_to_str(pinfo->pool, &pinfo->net_src), address_to_str(pinfo->pool, &pinfo->net_dst)); case 4: return ws_strdup_printf("(ip.src eq %s and ip.dst eq %s and cba.acco.srt == 1) || (ip.src eq %s and ip.dst eq %s and cba.acco.srt == 0)", address_to_str(pinfo->pool, &pinfo->net_src), address_to_str(pinfo->pool, &pinfo->net_dst), address_to_str(pinfo->pool, &pinfo->net_dst), address_to_str(pinfo->pool, &pinfo->net_src)); default: return NULL; } } return NULL; } #if 0 static void cba_connection_dump(cba_connection_t *conn, const char *role) { if (conn->qostype != 0x30) { ws_debug_printf(" %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==0xffffffff ? "[pending]" : val_to_str(conn->connret, dcom_hresult_vals, "Unknown (0x%08x)"), conn->packet_first, conn->packet_last); } else { ws_debug_printf(" %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==0xffffffff ? "[pending]" : val_to_str(conn->connret, dcom_hresult_vals, "Unknown (0x%08x)"), conn->frame_offset); } } static 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; address addr; for(pdevs = cba_pdevs; pdevs != NULL; pdevs = g_list_next(pdevs)) { pdev = pdevs->data; set_address(&addr, AT_IPv4, 4, pdev->ip); ws_debug_printf("PDev #%5u: %s IFs:%u", pdev->first_packet, address_to_str(pinfo->pool, &addr), pdev->object ? g_list_length(pdev->object->interfaces) : 0); for(ldevs = pdev->ldevs; ldevs != NULL; ldevs = g_list_next(ldevs)) { ldev = ldevs->data; ws_debug_printf(" 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; ws_debug_printf(" 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==0xffffffff ? "[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; ws_debug_printf(" 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==0xffffffff ? "[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"); } } } } #endif cba_pdev_t * cba_pdev_find(packet_info *pinfo, const address *addr, e_guid_t *ipid) { cba_pdev_t *pdev; dcom_interface_t *interf; interf = dcom_interface_find(pinfo, addr, ipid); if (interf != NULL) { pdev = (cba_pdev_t *)interf->parent->private_data; if (pdev == NULL) { expert_add_info_format(pinfo, NULL, &ei_cba_acco_pdev_find, "pdev_find: no pdev for IP:%s IPID:%s", address_to_str(pinfo->pool, addr), guids_resolve_guid_to_str(ipid, pinfo->pool)); } } else { expert_add_info_format(pinfo, NULL, &ei_cba_acco_pdev_find_unknown_interface, "pdev_find: unknown interface of IP:%s IPID:%s", address_to_str(pinfo->pool, addr), guids_resolve_guid_to_str(ipid, pinfo->pool)); pdev = NULL; } return pdev; } cba_pdev_t * cba_pdev_add(packet_info *pinfo, const address *addr) { 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_pdev_t *)cba_iter->data; if (memcmp(pdev->ip, addr->data, 4) == 0) { return pdev; } } /* not found, create a new */ pdev = wmem_new(wmem_file_scope(), cba_pdev_t); memcpy( (void *) (pdev->ip), addr->data, 4); pdev->first_packet = pinfo->num; pdev->ldevs = NULL; pdev->object = NULL; cba_pdevs = g_list_append(cba_pdevs, pdev); return pdev; } void cba_pdev_link(packet_info *pinfo _U_, cba_pdev_t *pdev, dcom_interface_t *pdev_interf) { /* "crosslink" pdev interface and its 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 _U_, cba_ldev_t *ldev, dcom_interface_t *ldev_interf) { /* "crosslink" interface and its 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 _U_, cba_ldev_t *ldev, dcom_interface_t *acco_interf) { /* "crosslink" interface and its 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_ldev_t *)cba_iter->data; if (strcmp(ldev->name, name) == 0) { return ldev; } } /* not found, create a new */ ldev = wmem_new(wmem_file_scope(), cba_ldev_t); ldev->name = wmem_strdup(wmem_file_scope(), name); ldev->first_packet = pinfo->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 address *addr, e_guid_t *ipid) { dcom_interface_t *interf; cba_ldev_t *ldev; interf = dcom_interface_find(pinfo, addr, ipid); if (interf != NULL) { ldev = (cba_ldev_t *)interf->private_data; if (ldev == NULL) { ldev = (cba_ldev_t *)interf->parent->private_data; } if (ldev == NULL) { expert_add_info_format(pinfo, NULL, &ei_cba_acco_ldev_unknown, "Unknown LDev of %s", address_to_str(pinfo->pool, addr)); } } else { expert_add_info_format(pinfo, NULL, &ei_cba_acco_ipid_unknown, "Unknown IPID of %s", address_to_str(pinfo->pool, addr)); ldev = NULL; } return ldev; } static 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; address addr; 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; } set_address(&addr, AT_IPv4, 4, &ip); pdev = cba_pdev_add(pinfo, &addr); delim++; ldev = cba_ldev_add(pinfo, pdev, delim); g_free(ip_str); return ldev; } static gboolean cba_packet_in_range(packet_info *pinfo, guint packet_connect, guint packet_disconnect, guint packet_disconnectme) { if (packet_connect == 0) { expert_add_info_format(pinfo, NULL, &ei_cba_acco_connect, "cba_packet_in_range#%u: packet_connect not set?", pinfo->num); } if (packet_connect == 0 || pinfo->num < packet_connect) { return FALSE; } if (packet_disconnect != 0 && pinfo->num > packet_disconnect) { return FALSE; } if (packet_disconnectme != 0 && pinfo->num > packet_disconnectme) { return FALSE; } return TRUE; } static void cba_frame_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, cba_frame_t *frame) { if (tree) { proto_item *item; proto_item *sub_item; proto_tree *sub_tree; sub_tree = proto_tree_add_subtree_format(tree, tvb, 0, 0, ett_cba_frame_info, &sub_item, "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); 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); } } static 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_frame_t *)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 = wmem_new(wmem_file_scope(), cba_frame_t); frame->consparent = cons_ldev; frame->provparent = prov_ldev; frame->packet_connect = pinfo->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; } static void cba_frame_disconnect(packet_info *pinfo, cba_frame_t *frame) { if (frame->packet_disconnect == 0) { frame->packet_disconnect = pinfo->num; } if (frame->packet_disconnect != pinfo->num) { expert_add_info_format(pinfo, NULL, &ei_cba_acco_disconnect, "cba_frame_disconnect#%u: frame already disconnected in #%u", pinfo->num, frame->packet_disconnect); } } static 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 = (cba_frame_t *)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->num; } if (frame->packet_disconnectme != pinfo->num) { expert_add_info_format(pinfo, tree, &ei_cba_acco_disconnect, "cba_frame_disconnectme#%u: frame already disconnectme'd in #%u", pinfo->num, frame->packet_disconnectme); } } } } static 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 = (cba_pdev_t *)pdevs->data; /* find ldev */ for(ldevs = pdev->ldevs; ldevs != NULL; ldevs = g_list_next(ldevs)) { ldev = (cba_ldev_t *)ldevs->data; /* find frame */ for(frames = ldev->consframes; frames != NULL; frames = g_list_next(frames)) { frame = (cba_frame_t *)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; } static 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 = (cba_frame_t *)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(pinfo, NULL, &ei_cba_acco_prov_crid); return NULL; } static void cba_frame_incoming_data(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, cba_frame_t *frame) { if (frame->packet_first == 0) { frame->packet_first = pinfo->num; } if ( pinfo->num > frame->packet_last && cba_packet_in_range(pinfo, frame->packet_connect, frame->packet_disconnect, frame->packet_disconnectme)) { frame->packet_last = pinfo->num; } } static void cba_connection_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, cba_connection_t *conn) { if (tree) { proto_item *item; proto_item *sub_item; proto_tree *sub_tree; if (conn->qostype != 0x30) { sub_tree = proto_tree_add_subtree_format(tree, tvb, 0, 0, ett_cba_conn_info, &sub_item, "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_tree = proto_tree_add_subtree_format(tree, tvb, 0, 0, ett_cba_conn_info, &sub_item, "ProvItem:\"%s\" PID:0x%x CID:0x%x Len:%u", conn->provitem, conn->provid, conn->consid, conn->length); } 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); } } } static 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_connection_t *)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_connection_t *)cba_iter->data; if ( conn->consid == consid && cba_packet_in_range(pinfo, conn->packet_connect, conn->packet_disconnect, conn->packet_disconnectme)) { return conn; } } } conn = wmem_new(wmem_file_scope(), cba_connection_t); conn->consparentacco = cons_ldev; conn->provparentacco = prov_ldev; conn->parentframe = cons_frame; conn->packet_connect = pinfo->num; conn->packet_disconnect = 0; conn->packet_disconnectme = 0; conn->packet_first = 0; conn->packet_last = 0; conn->consid = consid; conn->provitem = wmem_strdup(wmem_file_scope(), 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; } static void cba_connection_disconnect(packet_info *pinfo, cba_connection_t *conn) { /* XXX - detect multiple disconnects? */ if (conn->packet_disconnect == 0) { conn->packet_disconnect = pinfo->num; } if (conn->packet_disconnect != pinfo->num) { expert_add_info_format(pinfo, NULL, &ei_cba_acco_disconnect, "connection_disconnect#%u: already disconnected", conn->packet_disconnect); } } static 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->consconns; conns != NULL; conns = g_list_next(conns)) { conn = (cba_connection_t *)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->num; } if (conn->packet_disconnectme != pinfo->num) { expert_add_info_format(pinfo, tree, &ei_cba_acco_disconnect, "connection_disconnectme#%u: already disconnectme'd", conn->packet_disconnectme); } } } } static cba_connection_t * cba_connection_find_by_provid(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, 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_connection_t *)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; } static void cba_connection_incoming_data(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, cba_connection_t *conn) { if (conn->packet_first == 0) { conn->packet_first = pinfo->num; } if ( pinfo->num > conn->packet_last && cba_packet_in_range(pinfo, conn->packet_connect, conn->packet_disconnect, conn->packet_disconnectme)) { conn->packet_last = pinfo->num; } } /* dissect a response containing an array of hresults (e.g: ICBAAccoMgt::RemoveConnections) */ static int dissect_HResultArray_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32HResult; guint32 u32Pointer; guint32 u32ArraySize = 0; guint32 u32Idx; guint32 u32Tmp; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer); if (u32Pointer) { offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32Idx = 1; u32Tmp = u32ArraySize; while (u32Tmp--) { offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult, u32Idx); u32Idx++; } } offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult); 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_ICBAAccoServer_SetActivation_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32HResult; guint32 u32Pointer; guint32 u32ArraySize = 0; guint32 u32Idx; guint32 u32Tmp; proto_item *item; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1)); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer); if (u32Pointer) { offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32Idx = 1; u32Tmp = u32ArraySize; while (u32Tmp--) { offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult, u32Idx); u32Idx++; } } offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult); 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_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32HResult; guint32 u32Pointer; guint32 u32ArraySize = 0; guint32 u32Idx; guint32 u32Tmp; proto_item *item; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3)); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer); if (u32Pointer) { offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32Idx = 1; u32Tmp = u32ArraySize; while (u32Tmp--) { offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult, u32Idx); u32Idx++; } } offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult); 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, dcerpc_info *di, guint8 *drep) { guint32 u32HResult; guint32 u32Pointer; guint32 u32ArraySize = 0; guint32 u32Idx; guint32 u32Tmp; proto_item *item; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3)); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer); if (u32Pointer) { offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32Idx = 1; u32Tmp = u32ArraySize; while (u32Tmp--) { offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult, u32Idx); u32Idx++; } } offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult); 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_ICBAAccoServer_Connect_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint16 u16QoSType; guint16 u16QoSValue; guint8 u8State; guint32 u32Count; guint32 u32ArraySize; guint32 u32VariableOffset; guint32 u32SubStart; guint32 u32Pointer; guint16 u16VarType; guint32 u32ConsID; gchar szItem[1000] = { 0 }; guint32 u32MaxItemLen = sizeof(szItem); gchar szCons[1000] = { 0 }; guint32 u32MaxConsLen = sizeof(szCons); guint32 u32Idx; proto_item *item; 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, di, drep); /* get corresponding provider ldev */ prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid); item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2)); offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_consumer, szCons, u32MaxConsLen); /* find the consumer ldev by its name */ cons_ldev = cba_acco_add(pinfo, szCons); offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_qos_type, &u16QoSType); offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_qos_value, &u16QoSValue); offset = dissect_dcom_BYTE(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_state, &u8State); offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, di, drep, 0, &cons_interf); if (cons_interf == NULL) { expert_add_info_format(pinfo, NULL, &ei_cba_acco_conn_consumer, "Server_Connect: consumer interface invalid"); } /* "crosslink" consumer interface and its 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, di, drep, hf_cba_acco_count, &u32Count); offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); /* link connections infos to the call */ if (prov_ldev != NULL && cons_ldev != NULL) { call = (server_connect_call_t *)wmem_alloc(wmem_file_scope(), sizeof(server_connect_call_t) + u32ArraySize * sizeof(cba_connection_t *)); call->conn_count = 0; call->frame = NULL; call->conns = (cba_connection_t **) (call+1); di->call_data->private_data = call; } else{ call = NULL; } u32VariableOffset = offset + u32ArraySize*16; /* array of CONNECTINs */ u32Idx = 1; while (u32ArraySize--) { proto_item *sub_item; proto_tree *sub_tree; sub_item = proto_tree_add_item(tree, hf_cba_connectin, tvb, offset, 0, ENC_NA); sub_tree = proto_item_add_subtree(sub_item, ett_cba_connectin); u32SubStart = offset; /* ProviderItem */ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_provider_item, szItem, u32MaxItemLen); } /* DataType */ offset = dissect_dcom_VARTYPE(tvb, offset, pinfo, sub_tree, di, drep, &u16VarType); /* Epsilon */ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_epsilon); } /* ConsumerID */ offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, 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) */ (guint16 *)wmem_memdup(wmem_file_scope(), &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, val_to_str(u16VarType, dcom_variant_type_vals, "Unknown (0x%04x)") ); proto_item_set_len(sub_item, offset - u32SubStart); u32Idx++; } col_append_fstr(pinfo->cinfo, COL_INFO, ": Consumer=\"%s\" Cnt=%u", szCons, u32Count); return u32VariableOffset; } static int dissect_ICBAAccoServer2_Connect2_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint16 u16QoSType; guint16 u16QoSValue; guint8 u8State; guint32 u32Count; guint32 u32ArraySize; guint32 u32VariableOffset; guint32 u32SubStart; guint32 u32Pointer; guint16 u16VarType; guint32 u32ConsID; gchar szItem[1000] = { 0 }; guint32 u32MaxItemLen = sizeof(szItem); gchar szCons[1000] = { 0 }; guint32 u32MaxConsLen = sizeof(szCons); guint32 u32Idx; guint16 u16TypeDescLen; guint32 u32ArraySize2; guint32 u32Idx2; guint16 u16VarType2 = -1; proto_item *item; dcom_interface_t *cons_interf; cba_ldev_t *prov_ldev; cba_ldev_t *cons_ldev; cba_connection_t *conn; guint16 typedesclen = 0; guint16 *typedesc = NULL; server_connect_call_t *call = NULL; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); /* get corresponding provider ldev */ prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid); item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2)); offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_consumer, szCons, u32MaxConsLen); /* find the consumer ldev by its name */ cons_ldev = cba_acco_add(pinfo, szCons); offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_qos_type, &u16QoSType); offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_qos_value, &u16QoSValue); offset = dissect_dcom_BYTE(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_state, &u8State); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer); if (u32Pointer) { offset = dissect_dcom_MInterfacePointer(tvb, offset, pinfo, tree, di, drep, 0, &cons_interf); if (cons_interf == NULL) { expert_add_info_format(pinfo, NULL, &ei_cba_acco_conn_consumer, "Server2_Connect2: consumer interface invalid"); } } else { /* GetConnectionData do it this way */ cons_interf = NULL; } /* "crosslink" consumer interface and its 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, di, drep, hf_cba_acco_count, &u32Count); offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); /* link connection infos to the call */ if (prov_ldev != NULL && cons_ldev != NULL) { call = (server_connect_call_t *)wmem_alloc(wmem_file_scope(), sizeof(server_connect_call_t) + u32ArraySize * sizeof(cba_connection_t *)); call->conn_count = 0; call->frame = NULL; call->conns = (cba_connection_t **) (call+1); di->call_data->private_data = call; } else{ call = NULL; } u32VariableOffset = offset + u32ArraySize*20; /* array of CONNECTINs */ u32Idx = 1; while (u32ArraySize--) { proto_item *sub_item; proto_tree *sub_tree; sub_item = proto_tree_add_item(tree, hf_cba_connectin, tvb, offset, 0, ENC_NA); sub_tree = proto_item_add_subtree(sub_item, ett_cba_connectin); u32SubStart = offset; /* ProviderItem */ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_provider_item, szItem, u32MaxItemLen); } /* TypeDescLen */ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_type_desc_len, &u16TypeDescLen); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); /* pTypeDesc */ if (u32Pointer) { u32VariableOffset = dissect_dcom_dcerpc_array_size(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, &u32ArraySize2); /* limit the allocation to a reasonable size */ if (u32ArraySize2 < 1000) { typedesc = (guint16 *)wmem_alloc0(wmem_file_scope(), 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, di, drep, &u16VarType); if (typedesc != NULL && u32Idx2 <= typedesclen) { typedesc[u32Idx2-1] = u16VarType; } /* remember first VarType only */ if (u32Idx2 == 1) { u16VarType2 = u16VarType; } u32Idx2++; } } /* Epsilon */ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_epsilon); } /* ConsumerID */ offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, 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, val_to_str(u16VarType2, dcom_variant_type_vals, "Unknown (0x%04x)") ); proto_item_set_len(sub_item, offset - u32SubStart); u32Idx++; } col_append_fstr(pinfo->cinfo, COL_INFO, ": Consumer=\"%s\" Cnt=%u", szCons, u32Count); return u32VariableOffset; } static int dissect_ICBAAccoServer_Connect_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint8 u8FirstConnect; guint32 u32Pointer; guint32 u32ArraySize = 0; guint32 u32HResult; guint32 u32Idx = 1; guint32 u32ProvID; guint32 u32SubStart; proto_item *item; cba_connection_t *conn; server_connect_call_t *call = (server_connect_call_t *)di->call_data->private_data; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); if (call == NULL) { expert_add_info(pinfo, NULL, &ei_cba_acco_no_request_info); } item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1)); offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_server_first_connect, &u8FirstConnect); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer); if (u32Pointer) { offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); /* array of CONNECTOUTs */ while(u32ArraySize--) { proto_item *sub_item; proto_tree *sub_tree; sub_item = proto_tree_add_item(tree, hf_cba_connectout, tvb, offset, 8, ENC_NA); sub_tree = proto_item_add_subtree(sub_item, ett_cba_connectout); u32SubStart = offset; offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_prov_id, &u32ProvID); offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, 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)") ); proto_item_set_len(sub_item, offset - u32SubStart); u32Idx++; } } offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, 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++; } col_append_fstr(pinfo->cinfo, COL_INFO, ": %s Cnt=%u -> %s", (u8FirstConnect) ? "First" : "NotFirst", u32Idx-1, val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return offset; } static int dissect_ICBAAccoServer_Disconnect_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Count; guint32 u32ArraySize; guint32 u32Idx; guint32 u32ProvID; proto_item *item; cba_ldev_t *prov_ldev; cba_connection_t *conn; server_connect_call_t *call; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2)); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid); /* link connection infos to the call */ if (prov_ldev != NULL) { call = (server_connect_call_t *)wmem_alloc(wmem_file_scope(), sizeof(server_connect_call_t) + u32ArraySize * sizeof(cba_connection_t *)); call->conn_count = 0; call->frame = NULL; call->conns = (cba_connection_t **) (call+1); di->call_data->private_data = call; } else{ call = NULL; } u32Idx = 1; while (u32ArraySize--) { offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, 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++; } /* update column info now */ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count); return offset; } static int dissect_ICBAAccoServer_Disconnect_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32HResult; guint32 u32Pointer; guint32 u32ArraySize = 0; guint32 u32Idx; guint32 u32Tmp; proto_item *item; cba_connection_t *conn; server_connect_call_t *call = (server_connect_call_t *)di->call_data->private_data; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); if (call == NULL) { expert_add_info(pinfo, NULL, &ei_cba_acco_no_request_info); } item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1)); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer); if (u32Pointer) { offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32Idx = 1; u32Tmp = u32ArraySize; while (u32Tmp--) { offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult, u32Idx); /* mark this connection as disconnected */ if (call && u32Idx <= call->conn_count) { conn = call->conns[u32Idx-1]; if (conn != NULL) { cba_connection_disconnect(pinfo, conn); } } u32Idx++; } } offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult); 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, dcerpc_info *di, guint8 *drep) { guint32 u32Count; guint32 u32ArraySize; guint32 u32Idx; guint32 u32ProvID; proto_item *item; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4)); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32Idx = 1; while (u32ArraySize--) { offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_prov_id, &u32ProvID, u32Idx); u32Idx++; } /* update column info now */ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count); return offset; } static int dissect_ICBAAccoServer_DisconnectMe_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { gchar szStr[1000]; guint32 u32MaxStr = sizeof(szStr); proto_item *item; cba_ldev_t *prov_ldev; cba_ldev_t *cons_ldev; server_disconnectme_call_t *call; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); /* get corresponding provider ldev */ prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid); item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2)); offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_consumer, szStr, u32MaxStr); /* find the consumer ldev by its name */ cons_ldev = cba_acco_add(pinfo, szStr); if (prov_ldev != NULL && cons_ldev != NULL) { call = wmem_new(wmem_file_scope(), server_disconnectme_call_t); call->cons = cons_ldev; call->prov = prov_ldev; di->call_data->private_data = call; } /* update column info now */ col_append_fstr(pinfo->cinfo, COL_INFO, " Consumer=\"%s\"", szStr); return offset; } static int dissect_ICBAAccoServer_DisconnectMe_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32HResult; proto_item *item; server_disconnectme_call_t *call; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1)); offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult); call = (server_disconnectme_call_t *)di->call_data->private_data; if (call) { cba_connection_disconnectme(tvb, pinfo, tree, call->cons, call->prov); } 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, dcerpc_info *di, guint8 *drep) { gchar szStr[1000]; guint32 u32MaxStr = sizeof(szStr); proto_item *item; cba_ldev_t *prov_ldev; cba_ldev_t *cons_ldev; server_disconnectme_call_t *call; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); /* get corresponding provider ldev */ prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid); item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4)); offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_consumer, szStr, u32MaxStr); /* find the consumer ldev by its name */ cons_ldev = cba_acco_add(pinfo, szStr); if (prov_ldev != NULL && cons_ldev != NULL) { call = wmem_new(wmem_file_scope(), server_disconnectme_call_t); call->cons = cons_ldev; call->prov = prov_ldev; di->call_data->private_data = call; } /* update column info now */ col_append_fstr(pinfo->cinfo, COL_INFO, " Consumer=\"%s\"", szStr); return offset; } static int dissect_ICBAAccoServerSRT_DisconnectMe_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32HResult; proto_item *item; server_disconnectme_call_t *call; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3)); offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult); call = (server_disconnectme_call_t *)di->call_data->private_data; if (call) { cba_frame_disconnectme(tvb, pinfo, tree, call->cons, call->prov); } col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return offset; } static int dissect_ICBAAccoServer_Ping_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32HResult; proto_item *item; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1)); offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult); col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return offset; } static int dissect_ICBAAccoServer_SetActivation_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint8 u8State; guint32 u32Count; guint32 u32ArraySize; guint32 u32Idx; guint32 u32ProvID; proto_item *item; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2)); offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_state, &u8State); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32Idx = 1; while (u32ArraySize--) { offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_prov_id, &u32ProvID, u32Idx); u32Idx++; } /* update column info now */ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count); return offset; } static int dissect_ICBAAccoServerSRT_SetActivation_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint8 u8State; guint32 u32Count; guint32 u32ArraySize; guint32 u32Idx; guint32 u32ProvID; proto_item *item; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4)); offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_state, &u8State); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32Idx = 1; while (u32ArraySize--) { offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_prov_id, &u32ProvID, u32Idx); u32Idx++; } /* update column info now */ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count); return offset; } static int dissect_ICBAAccoServer_Ping_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { gchar szStr[1000]; guint32 u32MaxStr = sizeof(szStr); proto_item *item; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2)); offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_consumer, szStr, u32MaxStr); /* update column info now */ col_append_fstr(pinfo->cinfo, COL_INFO, " Consumer=\"%s\"", szStr); return offset; } static int dissect_ICBAAccoServerSRT_ConnectCR_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { gchar szCons[1000] = { 0 }; guint32 u32MaxConsLen = sizeof(szCons); guint16 u16QoSType; guint16 u16QoSValue; guint8 u8ConsMac[6]; guint16 u16CRID = 0; guint16 u16CRLength = 0; guint32 u32Flags; guint32 u32Count; guint32 u32ArraySize; guint32 u32Idx; proto_item *item; proto_tree *flags_tree; guint32 u32SubStart; 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, di, drep); /* get corresponding provider ldev */ prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid); item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4)); /* szCons */ offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_consumer, szCons, u32MaxConsLen); /* find the consumer ldev by its name */ cons_ldev = cba_acco_add(pinfo, szCons); offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_qos_type, &u16QoSType); offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_qos_value, &u16QoSValue); offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, di, drep, 0, &cons_interf); if (cons_interf == NULL) { expert_add_info_format(pinfo, NULL, &ei_cba_acco_conn_consumer, "ServerSRT_ConnectCR: consumer interface invalid"); } /* "crosslink" consumer interface and its 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); proto_tree_add_ether(tree, hf_cba_acco_serversrt_cons_mac, tvb, offset, 6, u8ConsMac); offset += 6; /* add flags subtree */ offset = dissect_dcom_DWORD(tvb, offset, pinfo, NULL /*tree*/, di, drep, 0 /* hfindex */, &u32Flags); offset -= 4; item = proto_tree_add_uint_format_value(tree, hf_cba_acco_serversrt_cr_flags, tvb, offset, 4, u32Flags, "0x%02x (%s, %s)", u32Flags, (u32Flags & 0x2) ? "Reconfigure" : "not Reconfigure", (u32Flags & 0x1) ? "Timestamped" : "not Timestamped"); flags_tree = proto_item_add_subtree(item, ett_cba_acco_serversrt_cr_flags); proto_tree_add_boolean(flags_tree, hf_cba_acco_serversrt_cr_flags_reconfigure, tvb, offset, 4, u32Flags); proto_tree_add_boolean(flags_tree, hf_cba_acco_serversrt_cr_flags_timestamped, tvb, offset, 4, u32Flags); offset += 4; offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); /* link frame infos to the call */ if (prov_ldev != NULL && cons_ldev != NULL && u32ArraySize < 100) { call = (server_frame_call_t *)wmem_alloc(wmem_file_scope(), sizeof(server_frame_call_t) + u32ArraySize * sizeof(cba_frame_t *)); call->frame_count = 0; call->frames = (cba_frame_t **) (call+1); di->call_data->private_data = call; } else { call = NULL; } u32Idx = 1; while (u32ArraySize--) { proto_item *sub_item; proto_tree *sub_tree; /* array of CONNECTINCRs */ sub_item = proto_tree_add_item(tree, hf_cba_connectincr, tvb, offset, 0, ENC_NA); sub_tree = proto_item_add_subtree(sub_item, ett_cba_connectincr); u32SubStart = offset; offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_serversrt_cr_id, &u16CRID); offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, 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); proto_item_set_len(sub_item, offset - u32SubStart); u32Idx++; } /* update column info now */ col_append_fstr(pinfo->cinfo, COL_INFO, ": %sConsCRID=0x%x Len=%u QoS=%u", (u32Flags & 0x2) ? "Reco " : "", u16CRID, u16CRLength, u16QoSValue); return offset; } static int dissect_ICBAAccoServerSRT_ConnectCR_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint8 u8FirstConnect; guint8 u8ProvMac[6]; guint32 u32ProvCRID = 0; guint32 u32HResult; guint32 u32ArraySize; guint32 u32Idx = 1; guint32 u32Pointer; guint32 u32SubStart; proto_item *item; cba_frame_t *frame; server_frame_call_t *call = (server_frame_call_t *)di->call_data->private_data; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); if (call == NULL) { expert_add_info(pinfo, NULL, &ei_cba_acco_no_request_info); } item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3)); offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_server_first_connect, &u8FirstConnect); /* ProviderMAC (big-endian, 1byte-aligned) */ tvb_memcpy(tvb, u8ProvMac, offset, 6); proto_tree_add_ether(tree, hf_cba_acco_serversrt_prov_mac, tvb, offset, 6, u8ProvMac); offset += 6; offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer); if (u32Pointer) { offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); while (u32ArraySize--) { proto_item *sub_item; proto_tree *sub_tree; /* array of CONNECTOUTCRs */ sub_item = proto_tree_add_item(tree, hf_cba_connectoutcr, tvb, offset, 0, ENC_NA); sub_tree = proto_item_add_subtree(sub_item, ett_cba_connectoutcr); u32SubStart = offset; offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_prov_crid, &u32ProvCRID); offset = dissect_dcom_HRESULT(tvb, offset, pinfo, sub_tree, di, 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, val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); proto_item_set_len(sub_item, offset - u32SubStart); u32Idx++; } } offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, 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++; } col_append_fstr(pinfo->cinfo, COL_INFO, ": %s PCRID=0x%x -> %s", (u8FirstConnect) ? "FirstCR" : "NotFirstCR", u32ProvCRID, val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return offset; } static int dissect_ICBAAccoServerSRT_DisconnectCR_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Count; guint32 u32ArraySize; guint32 u32Idx; guint32 u32ProvCRID = 0; proto_item *item; cba_ldev_t *prov_ldev; cba_frame_t *frame; server_frame_call_t *call; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); /* get corresponding provider ldev */ prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid); item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4)); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); /* link frame infos to the call */ if (prov_ldev != NULL) { call = (server_frame_call_t *)wmem_alloc(wmem_file_scope(), sizeof(server_frame_call_t) + u32ArraySize * sizeof(cba_frame_t *)); call->frame_count = 0; call->frames = (cba_frame_t **) (call+1); di->call_data->private_data = call; } else{ call = NULL; } u32Idx = 1; while (u32ArraySize--) { offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, 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++; } /* update column info now */ col_append_fstr(pinfo->cinfo, COL_INFO, ": PCRID=0x%x", u32ProvCRID); return offset; } static int dissect_ICBAAccoServerSRT_DisconnectCR_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32HResult; guint32 u32Pointer; guint32 u32ArraySize = 0; guint32 u32Idx; guint32 u32Tmp; cba_frame_t *frame; proto_item *item; server_frame_call_t *call = (server_frame_call_t *)di->call_data->private_data; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3)); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer); if (u32Pointer) { offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32Idx = 1; u32Tmp = u32ArraySize; while (u32Tmp--) { offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult, u32Idx); /* put response data into the frame */ if (call && u32Idx <= call->frame_count) { frame = call->frames[u32Idx-1]; if (frame != NULL) { cba_frame_disconnect(pinfo, frame); } } u32Idx++; } } offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult); col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", 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, dcerpc_info *di, guint8 *drep) { guint32 u32ProvCRID; guint8 u8State; guint8 u8LastConnect; guint32 u32Count; guint32 u32ArraySize; guint32 u32VariableOffset; guint32 u32Idx; guint32 u32SubStart; guint32 u32Pointer; gchar szProvItem[1000] = { 0 }; guint32 u32MaxProvItemLen = sizeof(szProvItem); guint16 u16TypeDescLen; guint32 u32ArraySize2; guint32 u32Idx2; guint16 u16VarType2 = -1; guint16 u16VarType; guint32 u32ConsID; guint16 u16RecordLength; proto_item *item; cba_ldev_t *prov_ldev; cba_frame_t *frame = NULL; guint16 typedesclen = 0; guint16 *typedesc = NULL; cba_connection_t *conn; server_connect_call_t *call; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); /* get corresponding provider ldev */ prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid); item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4)); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, 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, di, drep, hf_cba_acco_conn_state, &u8State); offset = dissect_dcom_BYTE(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_serversrt_last_connect, &u8LastConnect); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); /* link connections infos to the call */ if (frame != NULL) { call = (server_connect_call_t *)wmem_alloc(wmem_file_scope(), sizeof(server_connect_call_t) + u32ArraySize * sizeof(cba_connection_t *)); call->conn_count = 0; call->frame = frame; call->conns = (cba_connection_t **) (call+1); di->call_data->private_data = call; } else{ call = NULL; } u32VariableOffset = offset + u32ArraySize*20; u32Idx = 1; while (u32ArraySize--) { proto_item *sub_item; proto_tree *sub_tree; /* array of CONNECTINs */ sub_item = proto_tree_add_item(tree, hf_cba_connectin, tvb, offset, 0, ENC_NA); sub_tree = proto_item_add_subtree(sub_item, ett_cba_connectin); u32SubStart = offset; /* ProviderItem */ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_provider_item, szProvItem, u32MaxProvItemLen); } /* TypeDescLen */ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_type_desc_len, &u16TypeDescLen); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); /* pTypeDesc */ if (u32Pointer) { u32VariableOffset = dissect_dcom_dcerpc_array_size(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, &u32ArraySize2); typedesc = (guint16 *)wmem_alloc0(wmem_file_scope(), 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, di, drep, &u16VarType); if (u32Idx2 <= typedesclen) { typedesc[u32Idx2-1] = u16VarType; } /* remember first VarType only */ if (u32Idx2 == 1) { u16VarType2 = u16VarType; } u32Idx2++; } } /* ConsumerID */ offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_cons_id, &u32ConsID); /* RecordLength */ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, 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, val_to_str(u16VarType2, dcom_variant_type_vals, "Unknown (0x%04x)") ); proto_item_set_len(sub_item, offset - u32SubStart); u32Idx++; } /* update column info now */ col_append_fstr(pinfo->cinfo, COL_INFO, ": %s Cnt=%u PCRID=0x%x", (u8LastConnect) ? "LastOfCR" : "", u32Idx-1, u32ProvCRID); return u32VariableOffset; } static int dissect_ICBAAccoServerSRT_Connect_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Pointer; guint32 u32ArraySize; guint32 u32Idx = 1; guint32 u32SubStart; guint32 u32ProvID; guint32 u32HResult; proto_item *item; server_connect_call_t *call = (server_connect_call_t *)di->call_data->private_data; cba_connection_t *conn; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); if (call == NULL) { expert_add_info(pinfo, NULL, &ei_cba_acco_no_request_info); } item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3)); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, 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, di, drep, &u32ArraySize); /* array of CONNECTOUTs */ while(u32ArraySize--) { proto_item *sub_item; proto_tree *sub_tree; sub_item = proto_tree_add_item(tree, hf_cba_connectout, tvb, offset, 8, ENC_NA); sub_tree = proto_item_add_subtree(sub_item, ett_cba_connectout); u32SubStart = offset; offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_prov_id, &u32ProvID); offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, 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)") ); proto_item_set_len(sub_item, offset - u32SubStart); u32Idx++; } } offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, 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++; } col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s", u32Idx-1, val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return offset; } static int dissect_Server_GetProvIDs_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Count; guint32 u32Pointer; guint32 u32ArraySize; guint32 u32Idx; guint32 u32ProvID; guint32 u32HResult; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); if (u32Count) { col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u ProvID=", u32Count); } else { col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count); } offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer); if (u32Pointer) { offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32Idx = 1; while (u32ArraySize--) { offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_prov_id, &u32ProvID, u32Idx); if (u32Idx == 1) { col_append_fstr(pinfo->cinfo, COL_INFO, "0x%x", u32ProvID); } else if (u32Idx < 10) { col_append_fstr(pinfo->cinfo, COL_INFO, ",0x%x", u32ProvID); } else if (u32Idx == 10) { col_append_str(pinfo->cinfo, COL_INFO, ",..."); } u32Idx++; } } offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult); col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return offset; } static int dissect_Server_GetProvConnections_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Count; guint32 u32ArraySize; guint32 u32Idx; guint32 u32ProvID; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32Idx = 1; while (u32ArraySize--) { offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_prov_id, &u32ProvID, u32Idx); u32Idx++; } /* update column info now */ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count); return offset; } static int dissect_Server_GetProvConnections_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Count; guint32 u32TmpCount; guint32 u32Pointer; guint32 u32VariableOffset; guint32 u32Idx; guint32 u32SubStart; gchar szCons[1000] = { 0 }; guint32 u32MaxConsLen = sizeof(szCons); gchar szProvItem[1000] = { 0 }; guint32 u32MaxProvItemLen = sizeof(szProvItem); guint32 u32ConsID; guint16 u16QoSType; guint16 u16QoSValue; guint8 u8State; guint32 u32HResult; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer); u32VariableOffset = offset; if (u32Pointer) { offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); u32VariableOffset = offset + u32Count*28; /* array fixed part (including pointers to variable part) */ u32TmpCount = u32Count; u32Idx = 1; while (u32TmpCount--) { proto_item *sub_item; proto_tree *sub_tree; sub_item = proto_tree_add_item(tree, hf_cba_getprovconnout, tvb, offset, 0, ENC_NA); sub_tree = proto_item_add_subtree(sub_item, ett_cba_getprovconnout); u32SubStart = offset; /* wszConsumer */ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_consumer, szCons, u32MaxConsLen); } /* wszProviderItem */ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_provider_item, szProvItem, u32MaxProvItemLen); } /* dwConsID */ offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_cons_id, &u32ConsID); /* Epsilon */ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_epsilon); } /* QoS Type */ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_qos_type, &u16QoSType); /* QoS Value */ offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_qos_value, &u16QoSValue); /* State */ offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_state, &u8State); /* PartialResult */ offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep, &u32HResult, u32Idx); proto_item_append_text(sub_item, "[%u]: %s", u32Idx, val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); proto_item_set_len(sub_item, offset - u32SubStart); u32Idx++; } } u32VariableOffset = dissect_dcom_HRESULT(tvb, u32VariableOffset, pinfo, tree, di, drep, &u32HResult); col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return u32VariableOffset; } #define CBA_MRSH_VERSION_DCOM 0x01 #define CBA_MRSH_VERSION_SRT_WITH_CONSID 0x10 #define CBA_MRSH_VERSION_SRT_WITHOUT_CONSID 0x11 static int dissect_CBA_Connection_Data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, cba_ldev_t *cons_ldev, cba_frame_t *frame) { guint8 u8Version; guint8 u8Flags; guint16 u16CountFix; guint16 u16Count; guint32 u32ItemIdx; guint32 u32HoleIdx; proto_item *conn_data_item = NULL; proto_tree *conn_data_tree = NULL; guint16 u16Len; guint32 u32ID; guint8 u8QC; guint16 u16DataLen; guint16 u16HdrLen; int offset = 0; int offset_hole; gboolean qc_reported = FALSE; int qc_good = 0; int qc_uncertain = 0; int qc_bad = 0; GList *conns; int item_offset; cba_connection_t *conn; /*** ALL data in this buffer is NOT aligned and always little endian ordered ***/ if (tree) { conn_data_item = proto_tree_add_item(tree, hf_cba_acco_cb_conn_data, tvb, offset, 0, ENC_NA); conn_data_tree = proto_item_add_subtree(conn_data_item, ett_ICBAAccoCallback_Buffer); } /* add buffer header */ u8Version = tvb_get_guint8 (tvb, offset); if (conn_data_tree) { proto_tree_add_item(conn_data_tree, hf_cba_acco_cb_version, tvb, offset, 1, ENC_LITTLE_ENDIAN); } offset += 1; u8Flags = tvb_get_guint8 (tvb, offset); if (conn_data_tree) { proto_tree_add_item(conn_data_tree, hf_cba_acco_cb_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN); } offset += 1; u16Count = tvb_get_letohs (tvb, offset); if (conn_data_tree) { proto_tree_add_item(conn_data_tree, hf_cba_acco_cb_count, tvb, offset, 2, ENC_LITTLE_ENDIAN); } 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) { proto_item *item; 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 col_append_fstr(pinfo->cinfo, COL_INFO, " Cnt=%u", u16Count); #endif /* is this an OnDataChanged buffer format (version), we know? */ if ((u8Version != CBA_MRSH_VERSION_DCOM) && (u8Version != CBA_MRSH_VERSION_SRT_WITH_CONSID) && (u8Version != CBA_MRSH_VERSION_SRT_WITHOUT_CONSID)) { return offset; } /* Timestamps are currently unused -> flags must be zero */ if (u8Flags != 0) { return offset; } u32ItemIdx = 1; u32HoleIdx = 1; while (u16Count--) { proto_item *sub_item; proto_tree *sub_tree; proto_item *item; /* find next record header */ u16Len = tvb_get_letohs (tvb, offset); /* trapped inside an empty hole? -> try to find next record header */ if (u16Len == 0 && (u8Version == CBA_MRSH_VERSION_SRT_WITH_CONSID || u8Version == CBA_MRSH_VERSION_SRT_WITHOUT_CONSID)) { u32HoleIdx++; offset_hole = offset; /* length smaller or larger than possible -> must be a hole */ while (u16Len == 0) { offset++; u16Len = tvb_get_letohs(tvb, offset); /* this is a bit tricky here! we know: */ /* u16Len must be greater than 3 (min. size of header itself) */ /* u16Len must be a lot smaller than 0x300 (max. size of frame) */ /* -> if we found a length larger than 0x300, */ /* this must be actually the high byte, so do one more step */ if (u16Len > 0x300) { u16Len = 0; } } proto_tree_add_none_format(conn_data_tree, hf_cba_acco_cb_item_hole, tvb, offset_hole, offset - offset_hole, "Hole(--): -------------, offset=%2u, length=%2u", offset_hole, offset - offset_hole); } /* add callback-item subtree */ sub_item = proto_tree_add_item(conn_data_tree, hf_cba_acco_cb_item, tvb, offset, 0, ENC_NA); 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, ENC_LITTLE_ENDIAN); } offset += 2; u16HdrLen = 2; if (u8Version == CBA_MRSH_VERSION_DCOM || u8Version == CBA_MRSH_VERSION_SRT_WITH_CONSID) { u32ID = tvb_get_letohl (tvb, offset); if (sub_tree) { proto_tree_add_item(sub_tree, hf_cba_acco_conn_cons_id, tvb, offset, 4, ENC_LITTLE_ENDIAN); } offset += 4; u16HdrLen += 4; } else { u32ID = 0; } u8QC = tvb_get_guint8 (tvb, offset); item = NULL; if (sub_tree) { item = proto_tree_add_item(sub_tree, hf_cba_acco_qc, tvb, offset, 1, ENC_LITTLE_ENDIAN); } offset += 1; u16HdrLen += 1; if ( u8QC != 0x80 && /* GoodNonCascOk */ u8QC != 0x1C && /* BadOutOfService (usually permanent, so don't report for every frame) */ qc_reported == 0) { expert_add_info_format(pinfo, item, &ei_cba_acco_qc, "%s QC: %s", u8Version == CBA_MRSH_VERSION_DCOM ? "DCOM" : "SRT", val_to_str(u8QC, cba_acco_qc_vals, "Unknown (0x%02x)")); qc_reported = 0; } switch(u8QC >> 6) { case(00): qc_bad++; break; case(01): qc_uncertain++; break; default: qc_good++; } /* user data length is item length without headers */ u16DataLen = u16Len - u16HdrLen; /* append text to subtree header */ if (u8Version == CBA_MRSH_VERSION_DCOM || u8Version == CBA_MRSH_VERSION_SRT_WITH_CONSID) { proto_item_append_text(sub_item, "[%2u]: ConsID=0x%08x, offset=%2u, length=%2u (user-length=%2u), QC=%s (0x%02x)", u32ItemIdx, u32ID, offset - u16HdrLen, u16Len, u16DataLen, val_to_str(u8QC, cba_acco_qc_vals, "Unknown (0x%02x)"), u8QC ); } else { proto_item_append_text(sub_item, "[%2u]: ConsID=-, offset=%2u, length=%2u (user-length=%2u), QC=%s (0x%02x)", u32ItemIdx, offset - u16HdrLen, u16Len, u16DataLen, val_to_str(u8QC, cba_acco_qc_vals, "Unknown (0x%02x)"), u8QC ); } proto_item_set_len(sub_item, u16Len); /* hexdump of user data */ proto_tree_add_item(sub_tree, hf_cba_acco_cb_item_data, tvb, offset, u16DataLen, ENC_NA); 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 = (cba_connection_t *)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 = (cba_connection_t *)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 (DCOM), Flags=0x%x, Count=%u", u8Version, u8Flags, u16CountFix); } else { proto_item_append_text(conn_data_item, ": Version=0x%x (SRT), Flags=0x%x, Count=%u, Items=%u, Holes=%u", u8Version, u8Flags, u16CountFix, u32ItemIdx-1, u32HoleIdx-1); } proto_item_set_len(conn_data_item, offset); col_append_fstr(pinfo->cinfo, COL_INFO, ", QC (G:%u,U:%u,B:%u)", qc_good, qc_uncertain, qc_bad); return offset; } static gboolean dissect_CBA_Connection_Data_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { guint8 u8Version; guint8 u8Flags; /* the tvb will NOT contain the frame_id here! */ guint16 u16FrameID = GPOINTER_TO_UINT(data); cba_frame_t *frame; /* frame id must be in valid range (cyclic Real-Time, class=1 or class=2) */ if (u16FrameID < 0x8000 || u16FrameID >= 0xfb00) { return FALSE; } u8Version = tvb_get_guint8 (tvb, 0); u8Flags = tvb_get_guint8 (tvb, 1); /* version and flags must be ok */ if (u8Version != 0x11 || u8Flags != 0x00) { return FALSE; } col_set_str(pinfo->cinfo, COL_PROTOCOL, "PN-CBA"); frame = cba_frame_find_by_cons(pinfo, (const guint8 *)pinfo->dl_dst.data, u16FrameID); dissect_CBA_Connection_Data(tvb, pinfo, tree, frame ? frame->consparent : NULL, frame); return TRUE; } static int dissect_ICBAAccoCallback_OnDataChanged_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Length; guint32 u32ArraySize; tvbuff_t *next_tvb; proto_item *item; cba_ldev_t *cons_ldev; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); /* get corresponding provider ldev */ cons_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid); item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1)); /* length */ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_cb_length, &u32Length); /* array size */ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); /*** the data below is NOT ndr encoded (especially NOT aligned)!!! ***/ /* dissect PROFINET component data (without header) */ next_tvb = tvb_new_subset_remaining(tvb, offset); offset += dissect_CBA_Connection_Data(next_tvb, pinfo, tree, cons_ldev, NULL /* frame */); return offset; } static int dissect_ICBAAccoCallback_OnDataChanged_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32HResult; proto_item *item; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2)); offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult); col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return offset; } static int dissect_ICBAAccoCallback_Gnip_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { proto_item *item; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3)); return offset; } static int dissect_ICBAAccoCallback_Gnip_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32HResult; proto_item *item; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4)); offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult); col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return offset; } static int dissect_ICBAAccoServer2_GetConnectionData_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { gchar szStr[1000]; guint32 u32MaxStr = sizeof(szStr); proto_item *item; cba_ldev_t *cons_ldev; cba_ldev_t **call; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2)); offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, 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 = (cba_ldev_t **)wmem_alloc(wmem_file_scope(), sizeof(cba_ldev_t *)); *call = cons_ldev; di->call_data->private_data = call; } /* update column info now */ 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, dcerpc_info *di, guint8 *drep) { guint32 u32Length; guint32 u32ArraySize; tvbuff_t *next_tvb; guint32 u32Pointer; guint32 u32HResult; proto_item *item; cba_ldev_t **call = (cba_ldev_t **)di->call_data->private_data; cba_ldev_t *cons_ldev = (call!=NULL) ? *call : NULL; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); if (cons_ldev == NULL) { expert_add_info(pinfo, NULL, &ei_cba_acco_no_request_info); } item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE); proto_item_set_generated(item); p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1)); /* length */ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_cb_length, &u32Length); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer); if (u32Pointer) { /* array size */ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); /*** the data below is NOT ndr encoded (especially NOT aligned)!!! ***/ /* dissect PROFINET component data (without header) */ next_tvb = tvb_new_subset_remaining(tvb, offset); offset += dissect_CBA_Connection_Data(next_tvb, pinfo, tree, (call != NULL) ? *call : NULL, NULL /* frame */); } offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult); /* update column info now */ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return offset; } static int dissect_ICBAAccoMgt_AddConnections_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { gchar szConsumer[1000] = { 0 }; guint32 u32MaxConsLen = sizeof(szConsumer); guint16 u16QoSType; guint16 u16QoSValue; guint8 u8State; guint32 u32Count; guint32 u32ArraySize; guint32 u32Pointer; guint16 u16Persistence; gchar szConsItem[1000] = { 0 }; guint32 u32MaxConsItemLen = sizeof(szConsItem); gchar szProvItem[1000] = { 0 }; guint32 u32MaxProvItemLen = sizeof(szProvItem); guint32 u32VariableOffset; guint32 u32SubStart; guint32 u32Idx; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_provider, szConsumer, u32MaxConsLen); offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_qos_type, &u16QoSType); offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_qos_value, &u16QoSValue); offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_state, &u8State); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32VariableOffset = offset + u32ArraySize * 20; u32Idx = 1; while (u32ArraySize--) { proto_item *sub_item; proto_tree *sub_tree; sub_item = proto_tree_add_item(tree, hf_cba_addconnectionin, tvb, offset, 0, ENC_NA); sub_tree = proto_item_add_subtree(sub_item, ett_cba_addconnectionin); u32SubStart = offset; offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_provider_item, szProvItem, u32MaxProvItemLen); } offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_consumer_item, szConsItem, u32MaxConsItemLen); } offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_persist, &u16Persistence); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_substitute); } offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_epsilon); } proto_item_append_text(sub_item, "[%u]: ConsItem=\"%s\" ProvItem=\"%s\" %s Pers=%u", u32Idx, szConsItem, szProvItem, val_to_str(u16Persistence, cba_persist_vals, "Unknown (0x%02x)"), u16Persistence); proto_item_set_len(sub_item, offset - u32SubStart); u32Idx++; } /* update column info now */ col_append_fstr(pinfo->cinfo, COL_INFO, ": Prov=\"%s\" State=%s Cnt=%u", szConsumer, val_to_str(u8State, cba_acco_conn_state_vals, "Unknown (0x%02x)"), u32Count); return u32VariableOffset; } static int dissect_ICBAAccoMgt_AddConnections_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Pointer; guint32 u32ArraySize = 0; guint32 u32ConsID; guint16 u16ConnVersion; guint32 u32HResult = 0; guint32 u32Count = 0; guint32 u32Idx; guint32 u32SubStart; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer); if (u32Pointer) { offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32Count = u32ArraySize; u32Idx = 1; while (u32ArraySize--) { proto_item *sub_item; proto_tree *sub_tree; sub_item = proto_tree_add_item(tree, hf_cba_addconnectionout, tvb, offset, 0, ENC_NA); sub_tree = proto_item_add_subtree(sub_item, ett_cba_addconnectionout); u32SubStart = offset; offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_cons_id, &u32ConsID); offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_version, &u16ConnVersion); offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep, &u32HResult, u32Idx); proto_item_append_text(sub_item, "[%u]: ConsID=0x%x Version=%u %s", u32Idx, u32ConsID, u16ConnVersion, val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); proto_item_set_len(sub_item, offset - u32SubStart); u32Idx++; } /* update column info now */ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count); } offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult); /* update column info now */ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return offset; } static int dissect_ICBAAccoMgt_RemoveConnections_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Count; guint32 u32ArraySize; guint32 u32Idx; guint32 u32ConsID; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32Idx = 1; while (u32ArraySize--) { offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_cons_id, &u32ConsID, u32Idx); u32Idx++; } /* update column info now */ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count); return offset; } static int dissect_ICBAAccoMgt_SetActivationState_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint8 u8State; guint32 u32Count; guint32 u32ArraySize; guint32 u32Idx; guint32 u32ConsID; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_state, &u8State); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32Idx = 1; while (u32ArraySize--) { offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_cons_id, &u32ConsID, u32Idx); u32Idx++; } /* update column info now */ col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count); return offset; } static int dissect_ICBAAccoMgt_GetInfo_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Max; guint32 u32CurCnt; guint32 u32HResult; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_info_max, &u32Max); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_info_curr, &u32CurCnt); offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult); col_append_fstr(pinfo->cinfo, COL_INFO, ": %u/%u -> %s", u32CurCnt, u32Max, val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return offset; } static int dissect_ICBAAccoMgt_GetIDs_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Count; guint32 u32Pointer; guint32 u32ArraySize; guint32 u32ConsID; guint8 u8State; guint16 u16Version; guint32 u32HResult; guint32 u32Idx; guint32 u32SubStart; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); if (u32Count) { col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u ConsID=", u32Count); } else { col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count); } offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer); if (u32Pointer) { offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32Idx = 1; while (u32ArraySize--) { proto_item *sub_item; proto_tree *sub_tree; sub_item = proto_tree_add_item(tree, hf_cba_getidout, tvb, offset, 0, ENC_NA); sub_tree = proto_item_add_subtree(sub_item, ett_cba_getidout); u32SubStart = offset; offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_cons_id, &u32ConsID); offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_state, &u8State); offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_version, &u16Version); offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep, &u32HResult, u32Idx); proto_item_append_text(sub_item, "[%u]: ConsID=0x%x State=%s Version=%u %s", u32Idx, u32ConsID, val_to_str(u8State, cba_acco_conn_state_vals, "Unknown (0x%02x)"), u16Version, val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); proto_item_set_len(sub_item, offset - u32SubStart); if (u32Idx == 1) { col_append_fstr(pinfo->cinfo, COL_INFO, "0x%x", u32ConsID); } else if (u32Idx < 10) { col_append_fstr(pinfo->cinfo, COL_INFO, ",0x%x", u32ConsID); } else if (u32Idx == 10) { col_append_str(pinfo->cinfo, COL_INFO, ",..."); } u32Idx++; } } offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult); col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return offset; } static int dissect_ICBAAccoMgt2_GetConsIDs_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Count; guint32 u32Pointer; guint32 u32ArraySize; guint32 u32Idx; guint32 u32ConsID; guint32 u32HResult; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); if (u32Count) { col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u ConsID=", u32Count); } else { col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count); } offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer); if (u32Pointer) { offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32Idx = 1; while (u32ArraySize--) { offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_cons_id, &u32ConsID, u32Idx); if (u32Idx == 1) { col_append_fstr(pinfo->cinfo, COL_INFO, "0x%x", u32ConsID); } else if (u32Idx < 10) { col_append_fstr(pinfo->cinfo, COL_INFO, ",0x%x", u32ConsID); } else if (u32Idx == 10) { col_append_str(pinfo->cinfo, COL_INFO, ",..."); } u32Idx++; } } offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult); col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return offset; } static int dissect_ICBAAccoMgt2_GetConsConnections_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Count; guint32 u32TmpCount; guint32 u32Pointer; guint32 u32HResult; guint16 u16QoSType; guint16 u16QoSValue; guint8 u8State; guint16 u16Persistence; guint32 u32SubStart; guint32 u32Idx; guint32 u32VariableOffset; gchar szProv[1000] = { 0 }; guint32 u32MaxProvLen = sizeof(szProv); gchar szProvItem[1000] = { 0 }; guint32 u32MaxProvItemLen = sizeof(szProvItem); gchar szConsItem[1000] = { 0 }; guint32 u32MaxConsItemLen = sizeof(szConsItem); offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer); u32VariableOffset = offset; if (u32Pointer) { offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); u32VariableOffset = offset + u32Count*32; /* array fixed part (including pointers to variable part) */ u32TmpCount = u32Count; u32Idx = 1; while (u32TmpCount--) { proto_item *sub_item; proto_tree *sub_tree; sub_item = proto_tree_add_item(tree, hf_cba_getconsconnout, tvb, offset, 0, ENC_NA); sub_tree = proto_item_add_subtree(sub_item, ett_cba_getconnectionout); u32SubStart = offset; offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_provider, szProv, u32MaxProvLen); } offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_provider_item, szProvItem, u32MaxProvItemLen); } offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_consumer_item, szConsItem, u32MaxConsItemLen); } offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_substitute); } offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_epsilon); } offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_qos_type, &u16QoSType); offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_qos_value, &u16QoSValue); offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_state, &u8State); offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_persist, &u16Persistence); offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep, &u32HResult, u32Idx); proto_item_append_text(sub_item, "[%u]: %s", u32Idx, val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); proto_item_set_len(sub_item, offset - u32SubStart); u32Idx++; } } u32VariableOffset = dissect_dcom_HRESULT(tvb, u32VariableOffset, pinfo, tree, di, drep, &u32HResult); col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return u32VariableOffset; } static int dissect_ICBAAccoMgt2_DiagConsConnections_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Count; guint32 u32TmpCount; guint32 u32Pointer; guint32 u32HResult; guint8 u8State; guint16 u16Persistence; guint16 u16ConnVersion; guint32 u32SubStart; guint32 u32Idx; guint32 u32VariableOffset; guint32 u32ConnErrorState; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer); u32VariableOffset = offset; if (u32Pointer) { offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); u32VariableOffset = offset + u32Count*16; /* array fixed part (including pointers to variable part) */ u32TmpCount = u32Count; u32Idx = 1; while (u32TmpCount--) { proto_item *sub_item; proto_tree *sub_tree; proto_item *state_item; sub_item = proto_tree_add_item(tree, hf_cba_diagconsconnout, tvb, offset, 0, ENC_NA); sub_tree = proto_item_add_subtree(sub_item, ett_cba_getconnectionout); u32SubStart = offset; offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_state, &u8State); offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_persist, &u16Persistence); offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_version, &u16ConnVersion); /* connection state */ #if 0 offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_error_state, &u32ConnErrorState); #endif offset = dissect_dcom_HRESULT_item(tvb, offset, pinfo, sub_tree, di, drep, &u32ConnErrorState, hf_cba_acco_conn_error_state, &state_item); proto_item_set_text(state_item, "ConnErrorState: %s (0x%x)", val_to_str(u32ConnErrorState, dcom_hresult_vals, "Unknown (0x%08x)"), u32ConnErrorState); offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep, &u32HResult, u32Idx); proto_item_append_text(sub_item, "[%u]: %s", u32Idx, val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); proto_item_set_len(sub_item, offset - u32SubStart); u32Idx++; } } u32VariableOffset = dissect_dcom_HRESULT(tvb, u32VariableOffset, pinfo, tree, di, drep, &u32HResult); col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return u32VariableOffset; } static int dissect_ICBAAccoMgt_GetConnections_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32ConsID; guint32 u32Count; guint32 u32ArraySize; guint32 u32Idx; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32Idx = 1; while (u32ArraySize--){ offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_cons_id, &u32ConsID, u32Idx); u32Idx++; } return offset; } static int dissect_ICBAAccoMgt_GetConnections_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Count; guint32 u32TmpCount; guint32 u32Pointer; guint32 u32HResult; guint16 u16QoSType; guint16 u16QoSValue; guint8 u8State; guint16 u16Persistence; guint16 u16ConnVersion; guint32 u32SubStart; guint32 u32Idx; guint32 u32VariableOffset; gchar szProv[1000] = { 0 }; guint32 u32MaxProvLen = sizeof(szProv); gchar szProvItem[1000] = { 0 }; guint32 u32MaxProvItemLen = sizeof(szProvItem); gchar szConsItem[1000] = { 0 }; guint32 u32MaxConsItemLen = sizeof(szConsItem); offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer); u32VariableOffset = offset; if (u32Pointer) { offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); u32VariableOffset = offset + u32Count*36; /* array fixed part (including pointers to variable part) */ u32TmpCount = u32Count; u32Idx = 1; while (u32TmpCount--) { proto_item *sub_item; proto_tree *sub_tree; sub_item = proto_tree_add_item(tree, hf_cba_getconnectionout, tvb, offset, 0, ENC_NA); sub_tree = proto_item_add_subtree(sub_item, ett_cba_getconnectionout); u32SubStart = offset; offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_provider, szProv, u32MaxProvLen); } offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_provider_item, szProvItem, u32MaxProvItemLen); } offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_consumer_item, szConsItem, u32MaxConsItemLen); } offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_substitute); } offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_epsilon); } offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_qos_type, &u16QoSType); offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_qos_value, &u16QoSValue); offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_state, &u8State); offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_persist, &u16Persistence); offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_conn_version, &u16ConnVersion); offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep, &u32HResult, u32Idx); proto_item_append_text(sub_item, "[%u]: %s", u32Idx, val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); proto_item_set_len(sub_item, offset - u32SubStart); u32Idx++; } } u32VariableOffset = dissect_dcom_HRESULT(tvb, u32VariableOffset, pinfo, tree, di, drep, &u32HResult); col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return u32VariableOffset; } static int dissect_ICBAAccoMgt_ReviseQoS_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint16 u16QoSType; guint16 u16QoSValue; gchar szStr[1000]; guint32 u32MaxStr = sizeof(szStr); offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_rtauto, szStr, u32MaxStr); offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_qos_type, &u16QoSType); offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_qos_value, &u16QoSValue); col_append_fstr(pinfo->cinfo, COL_INFO, ": RTAuto=\"%s\" QoSType=%s QoSValue=%u", szStr, val_to_str(u16QoSType, cba_qos_type_vals, "Unknown (0x%04x)"), u16QoSValue); return offset; } static int dissect_ICBAAccoMgt_ReviseQoS_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint16 u16QoSValue; guint32 u32HResult; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_conn_qos_value, &u16QoSValue); offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult); col_append_fstr(pinfo->cinfo, COL_INFO, ": %u -> %s", u16QoSValue, val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return offset; } static int dissect_ICBAAccoMgt_get_PingFactor_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint16 u16PF; guint32 u32HResult; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_ping_factor, &u16PF); offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult); col_append_fstr(pinfo->cinfo, COL_INFO, ": %u -> %s", u16PF, val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return offset; } static int dissect_ICBAAccoMgt_put_PingFactor_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint16 u16PF; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_ping_factor, &u16PF); col_append_fstr(pinfo->cinfo, COL_INFO, ": %u", u16PF); return offset; } static int dissect_ICBAAccoMgt_get_CDBCookie_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Cookie; guint32 u32HResult; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_cdb_cookie, &u32Cookie); offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, &u32HResult); col_append_fstr(pinfo->cinfo, COL_INFO, ": CDBCookie=0x%x -> %s", u32Cookie, val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return offset; } static int dissect_ICBAAccoMgt_GetDiagnosis_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Request; guint32 u32InLength; guint32 u32ArraySize; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_diag_req, &u32Request); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_diag_in_length, &u32InLength); offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); if (u32ArraySize != 0) { proto_tree_add_item(tree, hf_cba_acco_diag_data, tvb, offset, u32InLength, ENC_NA); } col_append_fstr(pinfo->cinfo, COL_INFO, ": %s: %u bytes", val_to_str(u32Request, cba_acco_diag_req_vals, "Unknown request (0x%08x)"), u32InLength); return offset; } static int dissect_ICBAAccoMgt_GetDiagnosis_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32OutLength; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_diag_out_length, &u32OutLength); if (u32OutLength != 0) { proto_tree_add_item(tree, hf_cba_acco_diag_data, tvb, offset, u32OutLength, ENC_NA); } col_append_fstr(pinfo->cinfo, COL_INFO, ": %u bytes", u32OutLength); return offset; } static int dissect_ICBAAccoSync_ReadItems_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Count; gchar szStr[1000]; guint32 u32MaxStr = sizeof(szStr); guint32 u32Pointer; guint32 u32ArraySize; guint32 u32VariableOffset; guint32 u32Idx; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32VariableOffset = offset + u32ArraySize*4; u32Idx = 1; while (u32ArraySize--) { offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_indexed_LPWSTR(tvb, u32VariableOffset, pinfo, tree, di, drep, hf_cba_acco_item, szStr, u32MaxStr, u32Idx); } u32Idx++; } col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count); return u32VariableOffset; } static int dissect_ICBAAccoSync_ReadItems_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Pointer; guint16 u16QC; guint32 u32ArraySize = 0; guint32 u32HResult; guint32 u32Idx; guint32 u32SubStart; guint32 u32VariableOffset; guint32 u32Tmp; offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer); u32VariableOffset = offset; if (u32Pointer) { offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32VariableOffset = offset + u32ArraySize * 20; u32Idx = 1; u32Tmp = u32ArraySize; while(u32Tmp--) { proto_item *sub_item; proto_tree *sub_tree; sub_item = proto_tree_add_item(tree, hf_cba_readitemout, tvb, offset, 0, ENC_NA); sub_tree = proto_item_add_subtree(sub_item, ett_cba_readitemout); u32SubStart = offset; offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_data); } offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_qc, &u16QC); offset = dissect_dcom_FILETIME(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_time_stamp, NULL); offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep, &u32HResult, u32Idx); proto_item_append_text(sub_item, "[%u]: QC=%s (0x%02x) %s", u32Idx, val_to_str(u16QC, cba_acco_qc_vals, "Unknown"), u16QC, val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); proto_item_set_len(sub_item, offset - u32SubStart); u32Idx++; } } u32VariableOffset = dissect_dcom_HRESULT(tvb, u32VariableOffset, pinfo, tree, di, drep, &u32HResult); col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s", u32ArraySize, val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return u32VariableOffset; } static int dissect_ICBAAccoSync_WriteItems_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Count; guint32 u32ArraySize; gchar szStr[1000]; guint32 u32MaxStr = sizeof(szStr); guint32 u32Pointer; guint32 u32VariableOffset; guint32 u32SubStart; guint32 u32Idx; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32VariableOffset = offset + u32ArraySize * 8; u32Idx = 1; while(u32ArraySize--) { proto_item *sub_item; proto_tree *sub_tree; sub_item = proto_tree_add_item(tree, hf_cba_writeitemin, tvb, offset, 0, ENC_NA); sub_tree = proto_item_add_subtree(sub_item, ett_cba_writeitemin); u32SubStart = offset; offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_item, szStr, u32MaxStr); } offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_data); } proto_item_append_text(sub_item, "[%u]: Item=\"%s\"", u32Idx, szStr); proto_item_set_len(sub_item, offset - u32SubStart); u32Idx++; } col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count); return u32VariableOffset; } static int dissect_ICBAAccoSync_WriteItemsQCD_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { guint32 u32Count; guint32 u32ArraySize; gchar szStr[1000]; guint32 u32MaxStr = sizeof(szStr); guint32 u32Pointer; guint32 u32VariableOffset; guint32 u32SubStart; guint32 u32Idx; guint16 u16QC; offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep, hf_cba_acco_count, &u32Count); offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep, &u32ArraySize); u32VariableOffset = offset + u32ArraySize * 20; u32Idx = 1; while(u32ArraySize--) { proto_item *sub_item; proto_tree *sub_tree; sub_item = proto_tree_add_item(tree, hf_cba_writeitemin, tvb, offset, 0, ENC_NA); sub_tree = proto_item_add_subtree(sub_item, ett_cba_writeitemin); u32SubStart = offset; offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_item, szStr, u32MaxStr); } offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_data); } offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_qc, &u16QC); offset = dissect_dcom_FILETIME(tvb, offset, pinfo, sub_tree, di, drep, hf_cba_acco_time_stamp, NULL); proto_item_append_text(sub_item, "[%u]: Item=\"%s\" QC=%s (0x%02x)", u32Idx, szStr, val_to_str(u16QC, cba_acco_qc_vals, "Unknown"), u16QC); proto_item_set_len(sub_item, offset - u32SubStart); u32Idx++; } col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count); return u32VariableOffset; } /* sub dissector table of ICBAAccoMgt / ICBAAccoMgt2 interface */ static dcerpc_sub_dissector ICBAAccoMgt_dissectors[] = { { 0, "QueryInterface", NULL, NULL }, { 1, "AddRef", NULL, NULL }, { 2, "Release", NULL, NULL }, { 3, "AddConnections", dissect_ICBAAccoMgt_AddConnections_rqst, dissect_ICBAAccoMgt_AddConnections_resp }, { 4, "RemoveConnections", dissect_ICBAAccoMgt_RemoveConnections_rqst, dissect_HResultArray_resp }, { 5, "ClearConnections", dissect_dcom_simple_rqst, dissect_dcom_simple_resp }, { 6, "SetActivationState", dissect_ICBAAccoMgt_SetActivationState_rqst, dissect_HResultArray_resp }, { 7, "GetInfo", dissect_dcom_simple_rqst, dissect_ICBAAccoMgt_GetInfo_resp }, { 8, "GetIDs", dissect_dcom_simple_rqst, dissect_ICBAAccoMgt_GetIDs_resp }, { 9, "GetConnections", dissect_ICBAAccoMgt_GetConnections_rqst, dissect_ICBAAccoMgt_GetConnections_resp }, {10, "ReviseQoS", dissect_ICBAAccoMgt_ReviseQoS_rqst, dissect_ICBAAccoMgt_ReviseQoS_resp }, {11, "get_PingFactor", dissect_dcom_simple_rqst, dissect_ICBAAccoMgt_get_PingFactor_resp }, {12, "put_PingFactor", dissect_ICBAAccoMgt_put_PingFactor_rqst, dissect_dcom_simple_resp }, {13, "get_CDBCookie", dissect_dcom_simple_rqst, dissect_ICBAAccoMgt_get_CDBCookie_resp }, /* stage 2 */ {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_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 }, }; /* sub dissector table of ICBAAccoCallback interface */ static dcerpc_sub_dissector ICBAAccoCallback_dissectors[] = { { 0, "QueryInterface", NULL, NULL }, { 1, "AddRef", NULL, NULL }, { 2, "Release", NULL, NULL }, { 3, "OnDataChanged", dissect_ICBAAccoCallback_OnDataChanged_rqst, dissect_ICBAAccoCallback_OnDataChanged_resp }, /* stage 2 */ { 4, "Gnip", dissect_ICBAAccoCallback_Gnip_rqst, dissect_ICBAAccoCallback_Gnip_resp }, { 0, NULL, NULL, NULL }, }; /* sub dissector table of ICBAAccoServer interface */ static dcerpc_sub_dissector ICBAAccoServer_dissectors[] = { { 0, "QueryInterface", NULL, NULL }, { 1, "AddRef", NULL, NULL }, { 2, "Release", NULL, NULL }, { 3, "Connect", dissect_ICBAAccoServer_Connect_rqst, dissect_ICBAAccoServer_Connect_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_ICBAAccoServer2_GetConnectionData_rqst, dissect_ICBAAccoServer2_GetConnectionData_resp }, { 0, NULL, NULL, NULL }, }; /* sub dissector table of ICBAAccoServerSRT interface (stage 2 only) */ static dcerpc_sub_dissector ICBAAccoServerSRT_dissectors[] = { { 0, "QueryInterface", NULL, NULL }, { 1, "AddRef", NULL, NULL }, { 2, "Release", NULL, NULL }, { 3, "ConnectCR", dissect_ICBAAccoServerSRT_ConnectCR_rqst, dissect_ICBAAccoServerSRT_ConnectCR_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_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 }, }; /* sub dissector table of ICBAAccoSync interface */ static dcerpc_sub_dissector ICBAAccoSync_dissectors[] = { { 0, "QueryInterface", NULL, NULL }, { 1, "AddRef", NULL, NULL }, { 2, "Release", NULL, NULL }, { 3, "ReadItems", dissect_ICBAAccoSync_ReadItems_rqst, dissect_ICBAAccoSync_ReadItems_resp }, { 4, "WriteItems", dissect_ICBAAccoSync_WriteItems_rqst, dissect_HResultArray_resp }, { 5, "WriteItemsQCD", dissect_ICBAAccoSync_WriteItemsQCD_rqst, dissect_HResultArray_resp }, { 0, NULL, NULL, NULL }, }; /* register protocol */ void proto_register_dcom_cba_acco (void) { static gint *ett3[3]; static gint *ett4[4]; static gint *ett5[5]; static hf_register_info hf_cba_acco_array[] = { { &hf_cba_acco_opnum, { "Operation", "cba.acco.opnum", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_ping_factor, { "PingFactor", "cba.acco.ping_factor", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_count, { "Count", "cba.acco.count", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_info_max, { "Max", "cba.acco.info_max", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_info_curr, { "Current", "cba.acco.info_curr", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_rtauto, { "RTAuto", "cba.acco.rtauto", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_item, { "Item", "cba.acco.item", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_data, { "Data", "cba.acco.data", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_qc, { "QualityCode", "cba.acco.qc", FT_UINT8, BASE_HEX, VALS(cba_acco_qc_vals), 0x0, NULL, HFILL } }, { &hf_cba_acco_time_stamp, { "TimeStamp", "cba.acco.time_stamp", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cba_readitemout, { "ReadItemOut", "cba.acco.readitemout", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_writeitemin, { "WriteItemIn", "cba.acco.writeitemin", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_cdb_cookie, { "CDBCookie", "cba.acco.cdb_cookie", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, /* dcom_hresult_vals from packet-dcom.h doesn't work here, as length is unknown! */ { &hf_cba_acco_conn_error_state, { "ConnErrorState", "cba.acco.conn_error_state", FT_UINT32, BASE_HEX, NULL /*VALS(dcom_hresult_vals)*/, 0x0, NULL, HFILL } }, { &hf_cba_acco_diag_req, { "Request", "cba.acco.diag_req", FT_UINT32, BASE_HEX, VALS(cba_acco_diag_req_vals), 0x0, NULL, HFILL } }, { &hf_cba_acco_diag_in_length, { "InLength", "cba.acco.diag_in_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_diag_out_length, { "OutLength", "cba.acco.diag_out_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_diag_data, { "Data", "cba.acco.diag_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_dcom_call, { "DcomRuntime", "cba.acco.dcom", FT_BOOLEAN, BASE_NONE, TFS(&cba_acco_call_flags), 0x0, "This is a DCOM runtime context", HFILL } }, { &hf_cba_acco_srt_call, { "SrtRuntime", "cba.acco.srt", FT_BOOLEAN, BASE_NONE, TFS(&cba_acco_call_flags), 0x0, "This is an SRT runtime context", HFILL } } }; static hf_register_info hf_cba_acco_server[] = { #if 0 { &hf_cba_acco_server_pICBAAccoCallback, { "pICBAAccoCallback", "cba.acco.server_pICBAAccoCallback", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, #endif { &hf_cba_acco_server_first_connect, { "FirstConnect", "cba.acco.server_first_connect", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_cba_getprovconnout, { "GETPROVCONNOUT", "cba.acco.getprovconnout", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_serversrt_prov_mac, { "ProviderMAC", "cba.acco.serversrt_prov_mac", FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_serversrt_cons_mac, { "ConsumerMAC", "cba.acco.serversrt_cons_mac", FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_serversrt_cr_id, { "ConsumerCRID", "cba.acco.serversrt_cr_id", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_serversrt_cr_length, { "CRLength", "cba.acco.serversrt_cr_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_serversrt_cr_flags, { "Flags", "cba.acco.serversrt_cr_flags", FT_UINT32, BASE_HEX, 0, 0x0, NULL, HFILL } }, { &hf_cba_acco_serversrt_cr_flags_timestamped, { "Timestamped", "cba.acco.serversrt_cr_flags_timestamped", FT_BOOLEAN, 32, TFS (&acco_flags_set_truth), 0x1, NULL, HFILL } }, { &hf_cba_acco_serversrt_cr_flags_reconfigure, { "Reconfigure", "cba.acco.serversrt_cr_flags_reconfigure", FT_BOOLEAN, 32, TFS (&acco_flags_set_truth), 0x2, NULL, HFILL } }, { &hf_cba_type_desc_len, { "TypeDescLen", "cba.acco.type_desc_len", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_serversrt_record_length, { "RecordLength", "cba.acco.serversrt_record_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, #if 0 { &hf_cba_acco_serversrt_action, { "Action", "cba.acco.serversrt_action", FT_UINT32, BASE_DEC, VALS(cba_acco_serversrt_action_vals), 0x0, NULL, HFILL } }, #endif { &hf_cba_acco_serversrt_last_connect, { "LastConnect", "cba.acco.serversrt_last_connect", FT_UINT8, BASE_DEC, VALS(cba_acco_serversrt_last_connect_vals), 0x0, NULL, HFILL } }, }; static hf_register_info hf_cba_connectcr_array[] = { { &hf_cba_acco_prov_crid, { "ProviderCRID", "cba.acco.prov_crid", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, }; static hf_register_info hf_cba_connect_array[] = { { &hf_cba_addconnectionin, { "ADDCONNECTIONIN", "cba.acco.addconnectionin", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_addconnectionout, { "ADDCONNECTIONOUT", "cba.acco.addconnectionout", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_getidout, { "GETIDOUT", "cba.acco.getidout", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_getconnectionout, { "GETCONNECTIONOUT", "cba.acco.getconnectionout", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_getconsconnout, { "GETCONSCONNOUT", "cba.acco.getconsconnout", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_diagconsconnout, { "DIAGCONSCONNOUT", "cba.acco.diagconsconnout", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_connectincr, { "CONNECTINCR", "cba.acco.connectincr", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_connectoutcr, { "CONNECTOUTCR", "cba.acco.connectoutcr", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_connectin, { "CONNECTIN", "cba.acco.connectin", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_connectout, { "CONNECTOUT", "cba.acco.connectout", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_conn_prov_id, { "ProviderID", "cba.acco.conn_prov_id", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_conn_cons_id, { "ConsumerID", "cba.acco.conn_cons_id", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_conn_version, { "ConnVersion", "cba.acco.conn_version", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_conn_consumer, { "Consumer", "cba.acco.conn_consumer", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_conn_qos_type, { "QoSType", "cba.acco.conn_qos_type", FT_UINT16, BASE_HEX, VALS(cba_qos_type_vals), 0x0, NULL, HFILL } }, { &hf_cba_acco_conn_qos_value, { "QoSValue", "cba.acco.conn_qos_value", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_conn_state, { "State", "cba.acco.conn_state", FT_UINT8, BASE_HEX, VALS(cba_acco_conn_state_vals), 0x0, NULL, HFILL } }, { &hf_cba_acco_conn_provider, { "Provider", "cba.acco.conn_provider", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_conn_provider_item, { "ProviderItem", "cba.acco.conn_provider_item", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_conn_consumer_item, { "ConsumerItem", "cba.acco.conn_consumer_item", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_conn_persist, { "Persistence", "cba.acco.conn_persist", FT_UINT16, BASE_HEX, VALS(cba_persist_vals), 0x0, NULL, HFILL } }, { &hf_cba_acco_conn_epsilon, { "Epsilon", "cba.acco.conn_epsilon", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_conn_substitute, { "Substitute", "cba.acco.conn_substitute", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, }; static hf_register_info hf_cba_acco_cb[] = { { &hf_cba_acco_cb_length, { "Length", "cba.acco.cb_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_cb_version, { "Version", "cba.acco.cb_version", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_cb_flags, { "Flags", "cba.acco.cb_flags", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_cb_count, { "Count", "cba.acco.cb_count", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_cb_conn_data, { "CBA Connection data", "cba.acco.cb_conn_data", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_cb_item, { "Item", "cba.acco.cb_item", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_cb_item_hole, { "Hole", "cba.acco.cb_item_hole", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_cb_item_length, { "Length", "cba.acco.cb_item_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_cba_acco_cb_item_data, { "Data(Hex)", "cba.acco.cb_item_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, 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 } }, }; static ei_register_info ei[] = { { &ei_cba_acco_pdev_find, { "cba.acco.pdev_find.fail", PI_UNDECODED, PI_NOTE, "pdev_find: no pdev for IP", EXPFILL }}, { &ei_cba_acco_pdev_find_unknown_interface, { "cba.acco.pdev_find.unknown_interface", PI_UNDECODED, PI_NOTE, "pdev_find: unknown interface", EXPFILL }}, { &ei_cba_acco_ldev_unknown, { "cba.acco.ldev.unknown", PI_UNDECODED, PI_NOTE, "Unknown LDev", EXPFILL }}, { &ei_cba_acco_ipid_unknown, { "cba.acco.ipid.unknown", PI_UNDECODED, PI_NOTE, "Unknown IPID", EXPFILL }}, { &ei_cba_acco_prov_crid, { "cba.acco.prov_crid.unknown", PI_UNDECODED, PI_NOTE, "Unknown provider frame ProvCRID", EXPFILL }}, { &ei_cba_acco_conn_consumer, { "cba.acco.conn_consumer.invalid", PI_UNDECODED, PI_NOTE, "Consumer interface invalid", EXPFILL }}, { &ei_cba_acco_no_request_info, { "cba.acco.no_request_info", PI_UNDECODED, PI_NOTE, "No request info, response data ignored", EXPFILL }}, { &ei_cba_acco_qc, { "cba.acco.qc.expert", PI_RESPONSE_CODE, PI_CHAT, "expert QC", EXPFILL }}, { &ei_cba_acco_disconnect, { "cba.acco.disconnect", PI_SEQUENCE, PI_NOTE, "Disconnection sequence issue", EXPFILL }}, { &ei_cba_acco_connect, { "cba.acco.connect_not_set", PI_SEQUENCE, PI_NOTE, "packet_connect not set", EXPFILL }}, }; expert_module_t* expert_cba_acco; ett5[0] = &ett_ICBAAccoMgt; ett5[1] = &ett_cba_addconnectionin; ett5[2] = &ett_cba_addconnectionout; ett5[3] = &ett_cba_getidout; ett5[4] = &ett_cba_getconnectionout; proto_ICBAAccoMgt = proto_register_protocol ("ICBAAccoMgt", "ICBAAccoMgt", "cba_acco_mgt"); proto_register_field_array(proto_ICBAAccoMgt, hf_cba_acco_array, array_length(hf_cba_acco_array)); proto_register_field_array(proto_ICBAAccoMgt, hf_cba_connect_array, array_length(hf_cba_connect_array)); proto_register_field_array(proto_ICBAAccoMgt, hf_cba_connectcr_array, array_length(hf_cba_connectcr_array)); proto_register_subtree_array (ett5, array_length (ett5)); /* XXX - just pick a protocol to register the expert info in */ /* XXX - also, just pick a protocol to use proto_data for */ expert_cba_acco = expert_register_protocol(proto_ICBAAccoMgt); expert_register_field_array(expert_cba_acco, ei, array_length(ei)); proto_ICBAAccoMgt2 = proto_register_protocol ("ICBAAccoMgt2", "ICBAAccoMgt2", "cba_acco_mgt2"); ett3[0] = &ett_ICBAAccoCallback; ett3[1] = &ett_ICBAAccoCallback_Item; ett3[2] = &ett_ICBAAccoCallback_Buffer; proto_ICBAAccoCallback = proto_register_protocol ("ICBAAccoCallback", "ICBAAccoCB", "cba_acco_cb"); proto_register_field_array(proto_ICBAAccoCallback, hf_cba_acco_cb, array_length(hf_cba_acco_cb)); proto_register_subtree_array (ett3, array_length (ett3)); proto_ICBAAccoCallback2 = proto_register_protocol ("ICBAAccoCallback2", "ICBAAccoCB2", "cba_acco_cb2"); ett4[0] = &ett_ICBAAccoServer; ett4[1] = &ett_cba_connectin; ett4[2] = &ett_cba_connectout; ett4[3] = &ett_cba_getprovconnout; proto_ICBAAccoServer = proto_register_protocol ("ICBAAccoServer", "ICBAAccoServ", "cba_acco_server"); proto_register_field_array(proto_ICBAAccoServer, hf_cba_acco_server, array_length(hf_cba_acco_server)); proto_register_subtree_array (ett4, array_length (ett4)); proto_ICBAAccoServer2 = proto_register_protocol ("ICBAAccoServer2", "ICBAAccoServ2", "cba_acco_server2"); ett4[0] = &ett_ICBAAccoServerSRT; ett4[1] = &ett_cba_acco_serversrt_cr_flags; ett4[2] = &ett_cba_connectincr; ett4[3] = &ett_cba_connectoutcr; proto_ICBAAccoServerSRT = proto_register_protocol ("ICBAAccoServerSRT", "ICBAAccoServSRT", "cba_acco_server_srt"); proto_register_subtree_array (ett4, array_length (ett4)); 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 (ett5, array_length (ett5)); register_conversation_filter("cba", "PN-CBA", cba_filter_valid, cba_build_filter); } /* handoff protocol */ void proto_reg_handoff_dcom_cba_acco (void) { /* Register the interfaces */ dcerpc_init_uuid(proto_ICBAAccoMgt, ett_ICBAAccoMgt, &uuid_ICBAAccoMgt, ver_ICBAAccoMgt, ICBAAccoMgt_dissectors, hf_cba_acco_opnum); dcerpc_init_uuid(proto_ICBAAccoMgt2, ett_ICBAAccoMgt, &uuid_ICBAAccoMgt2, ver_ICBAAccoMgt2, ICBAAccoMgt_dissectors, hf_cba_acco_opnum); dcerpc_init_uuid(proto_ICBAAccoCallback, ett_ICBAAccoCallback, &uuid_ICBAAccoCallback, ver_ICBAAccoCallback, ICBAAccoCallback_dissectors, hf_cba_acco_opnum); dcerpc_init_uuid(proto_ICBAAccoCallback2, ett_ICBAAccoCallback, &uuid_ICBAAccoCallback2, ver_ICBAAccoCallback2, ICBAAccoCallback_dissectors, hf_cba_acco_opnum); dcerpc_init_uuid(proto_ICBAAccoServer, ett_ICBAAccoServer, &uuid_ICBAAccoServer, ver_ICBAAccoServer, ICBAAccoServer_dissectors, hf_cba_acco_opnum); dcerpc_init_uuid(proto_ICBAAccoServer2, ett_ICBAAccoServer, &uuid_ICBAAccoServer2, ver_ICBAAccoServer2, ICBAAccoServer_dissectors, hf_cba_acco_opnum); dcerpc_init_uuid(proto_ICBAAccoServerSRT, ett_ICBAAccoServerSRT, &uuid_ICBAAccoServerSRT, ver_ICBAAccoServerSRT, ICBAAccoServerSRT_dissectors, hf_cba_acco_opnum); dcerpc_init_uuid(proto_ICBAAccoSync, ett_ICBAAccoSync, &uuid_ICBAAccoSync, ver_ICBAAccoSync, ICBAAccoSync_dissectors, hf_cba_acco_opnum); heur_dissector_add("pn_rt", dissect_CBA_Connection_Data_heur, "PROFINET CBA IO", "pn_cba_pn_rt", proto_ICBAAccoServer, HEURISTIC_ENABLE); } /* * Editor modelines - https://www.wireshark.org/tools/modelines.html * * Local variables: * c-basic-offset: 4 * tab-width: 8 * indent-tabs-mode: nil * End: * * vi: set shiftwidth=4 tabstop=8 expandtab: * :indentSize=4:tabSize=8:noTabs=true: */