wireshark/plugins/epan/profinet/packet-dcom-cba-acco.c

5159 lines
178 KiB
C

/* packet-dcom-cba-acco.c
* Routines for DCOM CBA
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "config.h"
#include <string.h>
#include <epan/packet.h>
#include <epan/expert.h>
#include <epan/addr_resolv.h>
#include <epan/conversation_filter.h>
#include <epan/proto_data.h>
#include <epan/dissectors/packet-dcerpc.h>
#include <epan/dissectors/packet-dcom.h>
#include "packet-dcom-cba-acco.h"
#include <epan/ws_printf.h>
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:
*/