6c49c03a011beb17c1c37b870e830e4840a31875
[metze/wireshark/wip.git] / plugins / profinet / packet-dcom-cba-acco.c
1 /* packet-dcom-cba-acco.c
2  * Routines for DCOM CBA
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22
23 #include "config.h"
24
25 #include <string.h>
26
27 #include <epan/packet.h>
28 #include <epan/expert.h>
29 #include <epan/addr_resolv.h>
30 #include <epan/dissector_filters.h>
31 #include <epan/proto_data.h>
32 #include <epan/dissectors/packet-dcerpc.h>
33 #include <epan/dissectors/packet-dcom.h>
34 #include "packet-dcom-cba-acco.h"
35
36 void proto_register_dcom_cba_acco(void);
37 void proto_reg_handoff_dcom_cba_acco(void);
38
39 static int hf_cba_acco_opnum = -1;
40
41 static int hf_cba_acco_ping_factor = -1;
42
43 static int hf_cba_acco_count = -1;
44
45 static int hf_cba_acco_item = -1;
46 static int hf_cba_acco_data = -1;
47 static int hf_cba_acco_qc = -1;
48 static int hf_cba_acco_time_stamp = -1;
49
50 static int hf_cba_acco_conn_qos_type = -1;
51 static int hf_cba_acco_conn_qos_value = -1;
52 static int hf_cba_acco_conn_state = -1;
53 static int hf_cba_acco_conn_cons_id = -1;
54 static int hf_cba_acco_conn_version = -1;
55 static int hf_cba_acco_conn_prov_id = -1;
56 static int hf_cba_acco_conn_provider = -1;
57 static int hf_cba_acco_conn_consumer = -1;
58 static int hf_cba_acco_conn_provider_item = -1;
59 static int hf_cba_acco_conn_consumer_item = -1;
60 static int hf_cba_acco_conn_substitute = -1;
61 static int hf_cba_acco_conn_epsilon = -1;
62 static int hf_cba_acco_conn_persist = -1;
63
64 static int hf_cba_acco_cb_length = -1;
65 static int hf_cba_acco_cb_conn_data = -1;
66 static int hf_cba_acco_cb_version = -1;
67 static int hf_cba_acco_cb_flags = -1;
68 static int hf_cba_acco_cb_count = -1;
69 static int hf_cba_acco_cb_item = -1;
70 static int hf_cba_acco_cb_item_hole = -1;
71 static int hf_cba_acco_cb_item_length = -1;
72 static int hf_cba_acco_cb_item_data = -1;
73
74 static int hf_cba_connect_in = -1;
75 static int hf_cba_disconnect_in = -1;
76 static int hf_cba_connectcr_in = -1;
77 static int hf_cba_disconnectcr_in = -1;
78 static int hf_cba_disconnectme_in = -1;
79 static int hf_cba_data_first_in = -1;
80 static int hf_cba_data_last_in = -1;
81
82 /* static int hf_cba_acco_server_pICBAAccoCallback = -1; */
83
84 static int hf_cba_acco_server_first_connect = -1;
85
86 static int hf_cba_acco_serversrt_prov_mac = -1;
87 static int hf_cba_acco_serversrt_cons_mac = -1;
88
89 static int hf_cba_acco_serversrt_cr_id = -1;
90 static int hf_cba_acco_serversrt_cr_length = -1;
91 static int hf_cba_acco_serversrt_cr_flags = -1;
92 static int hf_cba_acco_serversrt_cr_flags_timestamped = -1;
93 static int hf_cba_acco_serversrt_cr_flags_reconfigure = -1;
94 static int hf_cba_acco_serversrt_record_length = -1;
95 /* static int hf_cba_acco_serversrt_action = -1; */
96 static int hf_cba_acco_serversrt_last_connect = -1;
97
98 static int hf_cba_getprovconnout = -1;
99
100 static int hf_cba_type_desc_len = -1;
101
102 static int hf_cba_connectincr = -1;
103 static int hf_cba_connectoutcr = -1;
104 static int hf_cba_connectin = -1;
105 static int hf_cba_connectout = -1;
106 static int hf_cba_getconnectionout = -1;
107 static int hf_cba_readitemout = -1;
108 static int hf_cba_writeitemin = -1;
109 static int hf_cba_addconnectionin = -1;
110 static int hf_cba_addconnectionout = -1;
111 static int hf_cba_getidout = -1;
112
113 static int hf_cba_getconsconnout = -1;
114 static int hf_cba_diagconsconnout = -1;
115 static int hf_cba_acco_conn_error_state = -1;
116
117 static int hf_cba_acco_info_max = -1;
118 static int hf_cba_acco_info_curr = -1;
119
120 static int hf_cba_acco_cdb_cookie = -1;
121
122 static int hf_cba_acco_rtauto = -1;
123
124 static int hf_cba_acco_prov_crid = -1;
125
126 static int hf_cba_acco_diag_req = -1;
127 static int hf_cba_acco_diag_in_length = -1;
128 static int hf_cba_acco_diag_out_length = -1;
129 static int hf_cba_acco_diag_data = -1;
130 static int hf_cba_acco_dcom_call = -1;
131 static int hf_cba_acco_srt_call = -1;
132
133 gint ett_cba_connectincr = -1;
134 gint ett_cba_connectoutcr = -1;
135 gint ett_cba_connectin = -1;
136 gint ett_cba_connectout = -1;
137 gint ett_cba_getprovconnout = -1;
138 gint ett_cba_addconnectionin = -1;
139 gint ett_cba_addconnectionout = -1;
140 gint ett_cba_getidout = -1;
141 gint ett_cba_getconnectionout = -1;
142 gint ett_cba_readitemout = -1;
143 gint ett_cba_writeitemin = -1;
144 gint ett_cba_acco_serversrt_cr_flags = -1;
145 gint ett_cba_frame_info = -1;
146 gint ett_cba_conn_info = -1;
147
148 static expert_field ei_cba_acco_pdev_find = EI_INIT;
149 static expert_field ei_cba_acco_prov_crid = EI_INIT;
150 static expert_field ei_cba_acco_conn_consumer = EI_INIT;
151 static expert_field ei_cba_acco_ldev_unknown = EI_INIT;
152 static expert_field ei_cba_acco_no_request_info = EI_INIT;
153 static expert_field ei_cba_acco_ipid_unknown = EI_INIT;
154 static expert_field ei_cba_acco_qc = EI_INIT;
155 static expert_field ei_cba_acco_pdev_find_unknown_interface = EI_INIT;
156
157 static int proto_ICBAAccoMgt = -1;
158 static gint ett_ICBAAccoMgt = -1;
159 static e_guid_t uuid_ICBAAccoMgt = { 0xcba00041, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
160 static guint16  ver_ICBAAccoMgt = 0;
161
162 static int proto_ICBAAccoMgt2 = -1;
163 static e_guid_t uuid_ICBAAccoMgt2 = { 0xcba00046, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
164 static guint16  ver_ICBAAccoMgt2 = 0;
165
166 static int proto_ICBAAccoCallback = -1;
167 static gint ett_ICBAAccoCallback = -1;
168 static gint ett_ICBAAccoCallback_Buffer = -1;
169 static gint ett_ICBAAccoCallback_Item = -1;
170 static e_guid_t uuid_ICBAAccoCallback = { 0xcba00042, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
171 static guint16  ver_ICBAAccoCallback = 0;
172
173 static int proto_ICBAAccoCallback2 = -1;
174 static e_guid_t uuid_ICBAAccoCallback2 = { 0xcba00047, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
175 static guint16  ver_ICBAAccoCallback2 = 0;
176
177 static int proto_ICBAAccoServer = -1;
178 static gint ett_ICBAAccoServer = -1;
179 static e_guid_t uuid_ICBAAccoServer = { 0xcba00043, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
180 static guint16  ver_ICBAAccoServer = 0;
181
182 static int proto_ICBAAccoServer2 = -1;
183 static e_guid_t uuid_ICBAAccoServer2 = { 0xcba00048, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
184 static guint16  ver_ICBAAccoServer2 = 0;
185
186 static int      proto_ICBAAccoServerSRT = -1;
187 static gint     ett_ICBAAccoServerSRT   = -1;
188 static e_guid_t uuid_ICBAAccoServerSRT  = { 0xcba00045, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
189 static guint16  ver_ICBAAccoServerSRT   = 0;
190
191 static int      proto_ICBAAccoSync = -1;
192 static gint     ett_ICBAAccoSync   = -1;
193 static e_guid_t uuid_ICBAAccoSync  = { 0xcba00044, 0x6c97, 0x11d1, { 0x82, 0x71, 0x00, 0xa0, 0x24, 0x42, 0xdf, 0x7d } };
194 static guint16  ver_ICBAAccoSync   = 0;
195
196
197
198 static const value_string cba_acco_qc_vals[] = {
199     { 0x1c, "BadOutOfService" },
200     { 0x44, "UncertainLastUsableValue" },
201     { 0x48, "UncertainSubstituteSet" },
202     { 0x50, "UncertainSensorNotAccurate" },
203     { 0x80, "GoodNonCascOk" },
204     { 0, NULL }
205 };
206
207
208 static const value_string cba_qos_type_vals[] = {
209     { 0x00, "Acyclic" },
210     { 0x01, "Acyclic seconds" },        /* obsolete */
211     { 0x02, "Acyclic status" },
212     { 0x03, "Acyclic HMI" },
213     { 0x20, "Constant" },
214     { 0x30, "Cyclic Real-Time" },
215     { 0, NULL }
216 };
217
218
219 static const value_string cba_persist_vals[] = {
220     { 0x00, "Volatile" },
221     { 0x01, "PendingPersistent" },
222     { 0x02, "Persistent" },
223     { 0, NULL }
224 };
225
226
227 static const value_string cba_acco_conn_state_vals[] = {
228     { 0x00, "Passive" },
229     { 0x01, "Active" },
230     { 0, NULL }
231 };
232
233 #if 0
234 static const value_string cba_acco_serversrt_action_vals[] = {
235     { 0x00, "Activate" },
236     { 0x01, "Deactivate" },
237     { 0x02, "Remove" },
238     { 0, NULL }
239 };
240 #endif
241
242 static const value_string cba_acco_serversrt_last_connect_vals[] = {
243     { 0x00, "CR not complete" },
244     { 0x01, "CR complete" },
245     { 0, NULL }
246 };
247
248 static const value_string cba_acco_diag_req_vals[] = {
249     { 0x0000, "Function directory" },
250     { 0x1000, "DevCat statistic" },
251     { 0x2000, "Reset statistic" },
252     { 0x3000, "Consumer Comm. Events" },
253     { 0x4000, "Provider Comm. Events" },
254     { 0, NULL }
255 };
256
257 static const true_false_string cba_acco_call_flags = {
258     "Consumer calls Provider (TRUE)",
259     "Provider calls Consumer (FALSE)"
260 };
261
262 static const value_string cba_qos_type_short_vals[] = {
263     { 0x00, "DCOM" },
264     { 0x01, "DCOM(sec)" },      /* obsolete */
265     { 0x02, "Status" },
266     { 0x03, "HMI" },
267     { 0x20, "Const" },
268     { 0x30, "SRT" },
269     { 0, NULL }
270 };
271
272
273 typedef struct cba_frame_s {
274     cba_ldev_t   *consparent;
275     cba_ldev_t   *provparent;
276     GList        *conns;
277     guint         packet_connect;
278     guint         packet_disconnect;
279     guint         packet_disconnectme;
280     guint         packet_first;
281     guint         packet_last;
282
283     guint16       length;
284     const guint8  consmac[6];
285     guint16       conscrid;
286     guint32       provcrid;
287     guint32       conncrret;
288     guint16       qostype;
289     guint16       qosvalue;
290     guint16       offset;
291 } cba_frame_t;
292
293 typedef struct cba_connection_s {
294     cba_ldev_t   *consparentacco;
295     cba_ldev_t   *provparentacco;
296     cba_frame_t  *parentframe;
297     guint         packet_connect;
298     guint         packet_disconnect;
299     guint         packet_disconnectme;
300     guint         packet_first;
301     guint         packet_last;
302
303     guint16       length;
304     guint32       consid;
305     guint32       provid;
306     const gchar  *provitem;
307     guint32       connret;
308     guint16       typedesclen;
309     guint16      *typedesc;
310     guint16       qostype;
311     guint16       qosvalue;
312     guint16       frame_offset;
313 } cba_connection_t;
314
315
316 typedef struct server_frame_call_s {
317     guint         frame_count;
318     cba_frame_t **frames;
319 } server_frame_call_t;
320
321
322 typedef struct server_connect_call_s {
323     guint         conn_count;
324     cba_frame_t  *frame;
325     cba_connection_t **conns;
326 } server_connect_call_t;
327
328 typedef struct server_disconnectme_call_s {
329     cba_ldev_t   *cons;
330     cba_ldev_t   *prov;
331 } server_disconnectme_call_t;
332
333
334 GList *cba_pdevs;
335
336 /* as we are a plugin, we cannot get this from libwireshark! */
337 const true_false_string acco_flags_set_truth = { "Set", "Not set" };
338
339 static gboolean
340 cba_filter_valid(packet_info *pinfo)
341 {
342     void* profinet_type = p_get_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0);
343
344     return ((profinet_type != NULL) && (GPOINTER_TO_UINT(profinet_type) < 10));
345 }
346
347 static gchar*
348 cba_build_filter(packet_info *pinfo)
349 {
350     gboolean is_tcp = proto_is_frame_protocol(pinfo->layers, "tcp");
351     void* profinet_type = p_get_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0);
352
353     if ((pinfo->net_src.type == AT_IPv4) && (pinfo->net_dst.type == AT_IPv4) && is_tcp) {
354         /* IPv4 */
355         switch(GPOINTER_TO_UINT(profinet_type)) {
356         case 1:
357             return g_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)",
358                 address_to_str(pinfo->pool, &pinfo->net_dst),
359                 address_to_str(pinfo->pool, &pinfo->net_src),
360                 address_to_str(pinfo->pool, &pinfo->net_src),
361                 address_to_str(pinfo->pool, &pinfo->net_dst));
362         case 2:
363             return g_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)",
364                 address_to_str(pinfo->pool, &pinfo->net_src),
365                 address_to_str(pinfo->pool, &pinfo->net_dst),
366                 address_to_str(pinfo->pool, &pinfo->net_dst),
367                 address_to_str(pinfo->pool, &pinfo->net_src));
368         case 3:
369             return g_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)",
370                 address_to_str(pinfo->pool, &pinfo->net_dst),
371                 address_to_str(pinfo->pool, &pinfo->net_src),
372                 address_to_str(pinfo->pool, &pinfo->net_src),
373                 address_to_str(pinfo->pool, &pinfo->net_dst));
374         case 4:
375             return g_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)",
376                 address_to_str(pinfo->pool, &pinfo->net_src),
377                 address_to_str(pinfo->pool, &pinfo->net_dst),
378                 address_to_str(pinfo->pool, &pinfo->net_dst),
379                 address_to_str(pinfo->pool, &pinfo->net_src));
380         default:
381             return NULL;
382         }
383     }
384
385     return NULL;
386 }
387
388 #if 0
389 static void
390 cba_connection_dump(cba_connection_t *conn, const char *role)
391 {
392     if (conn->qostype != 0x30) {
393         g_warning("   %s#%5u: CID:0x%8x PID:0x%8x PItem:\"%s\" Type:%s QoS:%s/%u Ret:%s Data#%5u-#%5u",
394             role,
395             conn->packet_connect,
396             conn->consid, conn->provid, conn->provitem,
397             conn->typedesclen != 0 ? val_to_str(conn->typedesc[0], dcom_variant_type_vals, "Unknown (0x%08x)") : "-",
398             val_to_str(conn->qostype, cba_qos_type_short_vals, "0x%x"), conn->qosvalue,
399             conn->connret==0xffffffff ? "[pending]" : val_to_str(conn->connret, dcom_hresult_vals, "Unknown (0x%08x)"),
400             conn->packet_first, conn->packet_last);
401     } else {
402         g_warning("   %s#%5u: CID:0x%8x PID:0x%8x PItem:\"%s\" Type:%s QoS:%s/%u Ret:%s Off:%u",
403             role,
404             conn->packet_connect,
405             conn->consid, conn->provid, conn->provitem,
406             conn->typedesclen != 0 ? val_to_str(conn->typedesc[0], dcom_variant_type_vals, "Unknown (0x%08x)") : "-",
407             val_to_str(conn->qostype, cba_qos_type_short_vals, "0x%x"), conn->qosvalue,
408             conn->connret==0xffffffff ? "[pending]" : val_to_str(conn->connret, dcom_hresult_vals, "Unknown (0x%08x)"),
409             conn->frame_offset);
410     }
411 }
412
413
414 static void
415 cba_object_dump(void)
416 {
417     GList       *pdevs;
418     GList       *ldevs;
419     GList       *frames;
420     GList       *conns;
421     cba_pdev_t  *pdev;
422     cba_ldev_t  *ldev;
423     cba_frame_t *frame;
424     address     addr;
425
426
427     for(pdevs = cba_pdevs; pdevs != NULL; pdevs = g_list_next(pdevs)) {
428         pdev = pdevs->data;
429         set_address(&addr, AT_IPv4, 4, pdev->ip);
430         g_warning("PDev #%5u: %s IFs:%u", pdev->first_packet, address_to_str(wmem_packet_scope(), &addr),
431             pdev->object ? g_list_length(pdev->object->interfaces) : 0);
432
433         for(ldevs = pdev->ldevs; ldevs != NULL; ldevs = g_list_next(ldevs)) {
434             ldev = ldevs->data;
435             g_warning(" LDev#%5u: \"%s\" LDevIFs:%u AccoIFs:%u", ldev->first_packet, ldev->name,
436                 ldev->ldev_object ? g_list_length(ldev->ldev_object->interfaces) : 0,
437                 ldev->acco_object ? g_list_length(ldev->acco_object->interfaces) : 0);
438             for(frames = ldev->consframes; frames != NULL; frames = g_list_next(frames)) {
439                 frame = frames->data;
440                 g_warning("  ConsFrame#%5u: CCRID:0x%x PCRID:0x%x Len:%u Ret:%s Data#%5u-#%5u",
441                     frame->packet_connect, frame->conscrid, frame->provcrid, frame->length,
442                     frame->conncrret==0xffffffff ? "[pending]" : val_to_str(frame->conncrret, dcom_hresult_vals, "Unknown (0x%08x)"),
443                     frame->packet_first, frame->packet_last);
444                 for(conns = frame->conns; conns != NULL; conns = g_list_next(conns)) {
445                     cba_connection_dump(conns->data, "ConsConn");
446                 }
447             }
448             for(frames = ldev->provframes; frames != NULL; frames = g_list_next(frames)) {
449                 frame = frames->data;
450                 g_warning("  ProvFrame#%5u: CCRID:0x%x PCRID:0x%x Len:%u Ret:%s Data#%5u-#%5u",
451                     frame->packet_connect, frame->conscrid, frame->provcrid, frame->length,
452                     frame->conncrret==0xffffffff ? "[pending]" : val_to_str(frame->conncrret, dcom_hresult_vals, "Unknown (0x%08x)"),
453                     frame->packet_first, frame->packet_last);
454                 for(conns = frame->conns; conns != NULL; conns = g_list_next(conns)) {
455                     cba_connection_dump(conns->data, "ProvConn");
456                 }
457             }
458             for(conns = ldev->consconns; conns != NULL; conns = g_list_next(conns)) {
459                 cba_connection_dump(conns->data, "ConsConn");
460             }
461             for(conns = ldev->provconns; conns != NULL; conns = g_list_next(conns)) {
462                 cba_connection_dump(conns->data, "ProvConn");
463             }
464         }
465     }
466 }
467 #endif
468
469
470 cba_pdev_t *
471 cba_pdev_find(packet_info *pinfo, const address *addr, e_guid_t *ipid)
472 {
473     cba_pdev_t       *pdev;
474     dcom_interface_t *interf;
475
476
477     interf = dcom_interface_find(pinfo, addr, ipid);
478     if (interf != NULL) {
479         pdev = (cba_pdev_t *)interf->parent->private_data;
480         if (pdev == NULL) {
481             expert_add_info_format(pinfo, NULL, &ei_cba_acco_pdev_find, "pdev_find: no pdev for IP:%s IPID:%s",
482                 address_to_str(wmem_packet_scope(), addr), guids_resolve_guid_to_str(ipid));
483         }
484     } else {
485         expert_add_info_format(pinfo, NULL, &ei_cba_acco_pdev_find_unknown_interface, "pdev_find: unknown interface of IP:%s IPID:%s",
486             address_to_str(wmem_packet_scope(), addr), guids_resolve_guid_to_str(ipid));
487         pdev = NULL;
488     }
489
490     return pdev;
491 }
492
493
494 cba_pdev_t *
495 cba_pdev_add(packet_info *pinfo, const address *addr)
496 {
497     GList      *cba_iter;
498     cba_pdev_t *pdev;
499
500
501     /* find pdev */
502     for(cba_iter = cba_pdevs; cba_iter != NULL; cba_iter = g_list_next(cba_iter)) {
503         pdev = (cba_pdev_t *)cba_iter->data;
504         if (memcmp(pdev->ip, addr->data, 4) == 0) {
505             return pdev;
506         }
507     }
508
509     /* not found, create a new */
510     pdev = (cba_pdev_t *)wmem_alloc(wmem_file_scope(), sizeof(cba_pdev_t));
511     memcpy( (void *) (pdev->ip), addr->data, 4);
512     pdev->first_packet = pinfo->num;
513     pdev->ldevs        = NULL;
514     pdev->object       = NULL;
515     cba_pdevs = g_list_append(cba_pdevs, pdev);
516
517     return pdev;
518 }
519
520
521 void
522 cba_pdev_link(packet_info *pinfo _U_, cba_pdev_t *pdev, dcom_interface_t *pdev_interf)
523 {
524
525     /* "crosslink" pdev interface and its object */
526     pdev->object = pdev_interf->parent;
527     pdev_interf->private_data = pdev;
528     if (pdev_interf->parent) {
529         pdev_interf->parent->private_data = pdev;
530     }
531 }
532
533
534 void
535 cba_ldev_link(packet_info *pinfo _U_, cba_ldev_t *ldev, dcom_interface_t *ldev_interf)
536 {
537
538     /* "crosslink" interface and its object */
539     ldev->ldev_object = ldev_interf->parent;
540     ldev_interf->private_data = ldev;
541     if (ldev_interf->parent) {
542         ldev_interf->parent->private_data = ldev;
543     }
544 }
545
546
547 void
548 cba_ldev_link_acco(packet_info *pinfo _U_, cba_ldev_t *ldev, dcom_interface_t *acco_interf)
549 {
550
551     /* "crosslink" interface and its object */
552     ldev->acco_object = acco_interf->parent;
553     acco_interf->private_data = ldev;
554     if (acco_interf->parent) {
555         acco_interf->parent->private_data = ldev;
556     }
557 }
558
559
560 cba_ldev_t *
561 cba_ldev_add(packet_info *pinfo, cba_pdev_t *pdev, const char *name)
562 {
563     GList      *cba_iter;
564     cba_ldev_t *ldev;
565
566
567     /* find ldev */
568     for(cba_iter = pdev->ldevs; cba_iter != NULL; cba_iter = g_list_next(cba_iter)) {
569         ldev = (cba_ldev_t *)cba_iter->data;
570         if (strcmp(ldev->name, name) == 0) {
571             return ldev;
572         }
573     }
574
575     /* not found, create a new */
576     ldev = (cba_ldev_t *)wmem_alloc(wmem_file_scope(), sizeof(cba_ldev_t));
577     ldev->name         = wmem_strdup(wmem_file_scope(), name);
578     ldev->first_packet = pinfo->num;
579     ldev->ldev_object  = NULL;
580     ldev->acco_object  = NULL;
581     ldev->parent       = pdev;
582
583     ldev->provframes   = NULL;
584     ldev->consframes   = NULL;
585     ldev->provconns    = NULL;
586     ldev->consconns    = NULL;
587
588     pdev->ldevs = g_list_append(pdev->ldevs, ldev);
589
590     return ldev;
591 }
592
593
594 cba_ldev_t *
595 cba_ldev_find(packet_info *pinfo, const address *addr, e_guid_t *ipid) {
596     dcom_interface_t *interf;
597     cba_ldev_t       *ldev;
598
599
600     interf = dcom_interface_find(pinfo, addr, ipid);
601     if (interf != NULL) {
602         ldev = (cba_ldev_t *)interf->private_data;
603
604         if (ldev == NULL) {
605             ldev = (cba_ldev_t *)interf->parent->private_data;
606         }
607         if (ldev == NULL) {
608             expert_add_info_format(pinfo, NULL, &ei_cba_acco_ldev_unknown, "Unknown LDev of %s",
609                 address_to_str(wmem_packet_scope(), addr));
610         }
611     } else {
612         expert_add_info_format(pinfo, NULL, &ei_cba_acco_ipid_unknown, "Unknown IPID of %s",
613             address_to_str(wmem_packet_scope(), addr));
614         ldev = NULL;
615     }
616
617     return ldev;
618 }
619
620
621 static cba_ldev_t *
622 cba_acco_add(packet_info *pinfo, const char *acco)
623 {
624     char       *ip_str;
625     char       *delim;
626     guint32     ip;
627     cba_pdev_t *pdev;
628     cba_ldev_t *ldev;
629     address    addr;
630
631
632     ip_str = g_strdup(acco);
633     delim  = strchr(ip_str, '!');
634     if (delim ==  NULL) {
635         g_free(ip_str);
636         return NULL;
637     }
638     *delim = 0;
639
640     if (!get_host_ipaddr(ip_str, &ip)) {
641         g_free(ip_str);
642         return NULL;
643     }
644
645     set_address(&addr, AT_IPv4, 4, &ip);
646     pdev = cba_pdev_add(pinfo, &addr);
647     delim++;
648
649     ldev = cba_ldev_add(pinfo, pdev, delim);
650
651     g_free(ip_str);
652
653     return ldev;
654 }
655
656
657 static gboolean
658 cba_packet_in_range(packet_info *pinfo, guint packet_connect, guint packet_disconnect, guint packet_disconnectme)
659 {
660
661     if (packet_connect == 0) {
662         g_warning("cba_packet_in_range#%u: packet_connect not set?", pinfo->num);
663     }
664
665     if (packet_connect == 0 || pinfo->num < packet_connect) {
666         return FALSE;
667     }
668     if (packet_disconnect != 0 && pinfo->num > packet_disconnect) {
669         return FALSE;
670     }
671     if (packet_disconnectme != 0 && pinfo->num > packet_disconnectme) {
672         return FALSE;
673     }
674
675     return TRUE;
676 }
677
678
679 static void
680 cba_frame_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, cba_frame_t *frame)
681 {
682     if (tree) {
683         proto_item *item;
684         proto_item *sub_item;
685         proto_tree *sub_tree;
686
687         sub_tree = proto_tree_add_subtree_format(tree, tvb, 0, 0, ett_cba_frame_info, &sub_item,
688             "Cons:\"%s\" CCRID:0x%x Prov:\"%s\" PCRID:0x%x QoS:%s/%ums Len:%u",
689             frame->consparent ? frame->consparent->name : "", frame->conscrid,
690             frame->provparent ? frame->provparent->name : "", frame->provcrid,
691             val_to_str(frame->qostype, cba_qos_type_short_vals, "%u"),
692             frame->qosvalue, frame->length);
693         PROTO_ITEM_SET_GENERATED(sub_item);
694
695         item = proto_tree_add_uint(sub_tree, hf_cba_acco_conn_qos_type,       tvb, 0, 0, frame->qostype);
696         PROTO_ITEM_SET_GENERATED(item);
697         item = proto_tree_add_uint(sub_tree, hf_cba_acco_conn_qos_value,      tvb, 0, 0, frame->qosvalue);
698         PROTO_ITEM_SET_GENERATED(item);
699         item = proto_tree_add_uint(sub_tree, hf_cba_acco_serversrt_cr_id,     tvb, 0, 0, frame->conscrid);
700         PROTO_ITEM_SET_GENERATED(item);
701         item = proto_tree_add_uint(sub_tree, hf_cba_acco_prov_crid,           tvb, 0, 0, frame->provcrid);
702         PROTO_ITEM_SET_GENERATED(item);
703         item = proto_tree_add_uint(sub_tree, hf_cba_acco_serversrt_cr_length, tvb, 0, 0, frame->length);
704         PROTO_ITEM_SET_GENERATED(item);
705
706         if (frame->consparent != NULL) {
707             item = proto_tree_add_string(sub_tree, hf_cba_acco_conn_consumer, tvb, 0, 0, frame->consparent->name);
708             PROTO_ITEM_SET_GENERATED(item);
709         }
710         if (frame->provparent != NULL) {
711             item = proto_tree_add_string(sub_tree, hf_cba_acco_conn_provider, tvb, 0, 0, frame->provparent->name);
712             PROTO_ITEM_SET_GENERATED(item);
713         }
714
715         item = proto_tree_add_uint(sub_tree, hf_cba_connectcr_in,
716                     tvb, 0, 0, frame->packet_connect);
717         PROTO_ITEM_SET_GENERATED(item);
718         item = proto_tree_add_uint(sub_tree, hf_cba_data_first_in,
719                     tvb, 0, 0, frame->packet_first);
720         PROTO_ITEM_SET_GENERATED(item);
721         item = proto_tree_add_uint(sub_tree, hf_cba_data_last_in,
722                     tvb, 0, 0, frame->packet_last);
723         PROTO_ITEM_SET_GENERATED(item);
724         item = proto_tree_add_uint(sub_tree, hf_cba_disconnectcr_in,
725                     tvb, 0, 0, frame->packet_disconnect);
726         PROTO_ITEM_SET_GENERATED(item);
727         item = proto_tree_add_uint(sub_tree, hf_cba_disconnectme_in,
728                     tvb, 0, 0, frame->packet_disconnectme);
729         PROTO_ITEM_SET_GENERATED(item);
730     }
731 }
732
733
734 static cba_frame_t *
735 cba_frame_connect(packet_info *pinfo, cba_ldev_t *cons_ldev, cba_ldev_t *prov_ldev,
736               guint16 qostype, guint16 qosvalue, const guint8 *consmac, guint16 conscrid, guint16 length)
737 {
738     GList       *cba_iter;
739     cba_frame_t *frame;
740
741     /* find frame */
742     for(cba_iter = cons_ldev->consframes; cba_iter != NULL; cba_iter = g_list_next(cba_iter)) {
743         frame = (cba_frame_t *)cba_iter->data;
744         if ( frame->conscrid == conscrid &&
745             memcmp(frame->consmac, consmac, 6) == 0 &&
746             cba_packet_in_range(pinfo, frame->packet_connect, frame->packet_disconnect, frame->packet_disconnectme)) {
747             return frame;
748         }
749     }
750
751     frame = (cba_frame_t *)wmem_alloc(wmem_file_scope(), sizeof(cba_frame_t));
752
753     frame->consparent          = cons_ldev;
754     frame->provparent          = prov_ldev;
755
756     frame->packet_connect      = pinfo->num;
757     frame->packet_disconnect   = 0;
758     frame->packet_disconnectme = 0;
759     frame->packet_first        = 0;
760     frame->packet_last         = 0;
761
762     frame->length              = length;
763     memcpy( (guint8 *) (frame->consmac), consmac, sizeof(frame->consmac));
764     frame->conscrid            = conscrid;
765     frame->qostype             = qostype;
766     frame->qosvalue            = qosvalue;
767
768     frame->offset              = 4;
769     frame->conns               = NULL;
770
771     frame->provcrid            = 0;
772     frame->conncrret           = -1;
773
774     cons_ldev->consframes = g_list_append(cons_ldev->consframes, frame);
775     prov_ldev->provframes = g_list_append(prov_ldev->provframes, frame);
776
777     return frame;
778 }
779
780
781 static void
782 cba_frame_disconnect(packet_info *pinfo, cba_frame_t *frame)
783 {
784
785     if (frame->packet_disconnect == 0) {
786         frame->packet_disconnect = pinfo->num;
787     }
788
789     if (frame->packet_disconnect != pinfo->num) {
790         g_warning("cba_frame_disconnect#%u: frame already disconnected in #%u",
791             pinfo->num, frame->packet_disconnect);
792     }
793 }
794
795
796 static void
797 cba_frame_disconnectme(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, cba_ldev_t *cons_ldev, cba_ldev_t *prov_ldev)
798 {
799     GList       *frames;
800     cba_frame_t *frame;
801
802
803     for(frames = cons_ldev->consframes; frames != NULL; frames = g_list_next(frames)) {
804         frame = (cba_frame_t *)frames->data;
805
806         if ( frame->provparent == prov_ldev &&
807             cba_packet_in_range(pinfo, frame->packet_connect, frame->packet_disconnect, frame->packet_disconnectme)) {
808
809             cba_frame_info(tvb, pinfo, tree, frame);
810
811             if (frame->packet_disconnectme == 0) {
812                 frame->packet_disconnectme = pinfo->num;
813             }
814
815             if (frame->packet_disconnectme != pinfo->num) {
816                 g_warning("cba_frame_disconnectme#%u: frame already disconnectme'd in #%u",
817                     pinfo->num, frame->packet_disconnectme);
818             }
819         }
820     }
821 }
822
823
824 static cba_frame_t *
825 cba_frame_find_by_cons(packet_info *pinfo, const guint8 *consmac, guint16 conscrid)
826 {
827     GList       *pdevs;
828     GList       *ldevs;
829     GList       *frames;
830     cba_pdev_t  *pdev;
831     cba_ldev_t  *ldev;
832     cba_frame_t *frame;
833
834
835     /* find pdev */
836     for(pdevs = cba_pdevs; pdevs != NULL; pdevs = g_list_next(pdevs)) {
837         pdev = (cba_pdev_t *)pdevs->data;
838
839         /* find ldev */
840         for(ldevs = pdev->ldevs; ldevs != NULL; ldevs = g_list_next(ldevs)) {
841             ldev = (cba_ldev_t *)ldevs->data;
842
843             /* find frame */
844             for(frames = ldev->consframes; frames != NULL; frames = g_list_next(frames)) {
845                 frame = (cba_frame_t *)frames->data;
846
847                 if ( frame->conscrid == conscrid &&
848                     memcmp(frame->consmac, consmac, 6) == 0 &&
849                     cba_packet_in_range(pinfo, frame->packet_connect, frame->packet_disconnect, frame->packet_disconnectme)) {
850                     return frame;
851                 }
852             }
853         }
854     }
855
856     return NULL;
857 }
858
859
860 static cba_frame_t *
861 cba_frame_find_by_provcrid(packet_info *pinfo, cba_ldev_t *prov_ldev, guint32 provcrid)
862 {
863     GList       *frames;
864     cba_frame_t *frame;
865
866
867     if (prov_ldev == NULL) {
868         return NULL;
869     }
870
871     for(frames = prov_ldev->provframes; frames != NULL; frames = g_list_next(frames)) {
872         frame = (cba_frame_t *)frames->data;
873
874         if ( frame->provcrid == provcrid &&
875             cba_packet_in_range(pinfo, frame->packet_connect, frame->packet_disconnect, frame->packet_disconnectme)) {
876             return frame;
877         }
878     }
879
880     expert_add_info(pinfo, NULL, &ei_cba_acco_prov_crid);
881
882     return NULL;
883 }
884
885
886 static void
887 cba_frame_incoming_data(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, cba_frame_t *frame)
888 {
889     if (frame->packet_first == 0) {
890         frame->packet_first = pinfo->num;
891     }
892
893     if ( pinfo->num > frame->packet_last &&
894         cba_packet_in_range(pinfo, frame->packet_connect, frame->packet_disconnect, frame->packet_disconnectme)) {
895         frame->packet_last = pinfo->num;
896     }
897 }
898
899
900 static void
901 cba_connection_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, cba_connection_t *conn)
902 {
903     if (tree) {
904         proto_item *item;
905         proto_item *sub_item;
906         proto_tree *sub_tree;
907
908         if (conn->qostype != 0x30) {
909             sub_tree = proto_tree_add_subtree_format(tree, tvb, 0, 0, ett_cba_conn_info, &sub_item,
910                 "ProvItem:\"%s\" PID:0x%x CID:0x%x QoS:%s/%ums",
911                 conn->provitem, conn->provid, conn->consid,
912                 val_to_str(conn->qostype, cba_qos_type_short_vals, "%u"), conn->qosvalue);
913         } else {
914             sub_tree = proto_tree_add_subtree_format(tree, tvb, 0, 0, ett_cba_conn_info, &sub_item,
915                 "ProvItem:\"%s\" PID:0x%x CID:0x%x Len:%u",
916                 conn->provitem, conn->provid, conn->consid, conn->length);
917         }
918         PROTO_ITEM_SET_GENERATED(sub_item);
919
920         item = proto_tree_add_string(sub_tree, hf_cba_acco_conn_provider_item,    tvb, 0, 0 /* len */, conn->provitem);
921         PROTO_ITEM_SET_GENERATED(item);
922         item = proto_tree_add_uint(sub_tree, hf_cba_acco_conn_prov_id,            tvb, 0, 0 /* len */, conn->provid);
923         PROTO_ITEM_SET_GENERATED(item);
924         item = proto_tree_add_uint(sub_tree, hf_cba_acco_conn_cons_id,            tvb, 0, 0 /* len */, conn->consid);
925         PROTO_ITEM_SET_GENERATED(item);
926         item = proto_tree_add_uint(sub_tree, hf_cba_acco_serversrt_record_length, tvb, 0, 0 /* len */, conn->length);
927         PROTO_ITEM_SET_GENERATED(item);
928
929         if (conn->qostype != 0x30) {
930             item = proto_tree_add_uint(sub_tree, hf_cba_acco_conn_qos_type,
931                         tvb, 0, 0, conn->qostype);
932             PROTO_ITEM_SET_GENERATED(item);
933             item = proto_tree_add_uint(sub_tree, hf_cba_acco_conn_qos_value,
934                         tvb, 0, 0, conn->qosvalue);
935             PROTO_ITEM_SET_GENERATED(item);
936             item = proto_tree_add_uint(sub_tree, hf_cba_connect_in,
937                         tvb, 0, 0, conn->packet_connect);
938             PROTO_ITEM_SET_GENERATED(item);
939             item = proto_tree_add_uint(sub_tree, hf_cba_data_first_in,
940                         tvb, 0, 0, conn->packet_first);
941             PROTO_ITEM_SET_GENERATED(item);
942             item = proto_tree_add_uint(sub_tree, hf_cba_data_last_in,
943                         tvb, 0, 0, conn->packet_last);
944             PROTO_ITEM_SET_GENERATED(item);
945             item = proto_tree_add_uint(sub_tree, hf_cba_disconnect_in,
946                         tvb, 0, 0, conn->packet_disconnect);
947             PROTO_ITEM_SET_GENERATED(item);
948             item = proto_tree_add_uint(sub_tree, hf_cba_disconnectme_in,
949                         tvb, 0, 0, conn->packet_disconnectme);
950             PROTO_ITEM_SET_GENERATED(item);
951         }
952     }
953 }
954
955
956 static cba_connection_t *
957 cba_connection_connect(packet_info *pinfo, cba_ldev_t *cons_ldev, cba_ldev_t *prov_ldev, cba_frame_t *cons_frame,
958                    guint16 qostype, guint16 qosvalue, const char *provitem, guint32 consid, guint16 length,
959                    guint16 *typedesc, guint16 typedesclen)
960 {
961     GList *cba_iter;
962     cba_connection_t *conn;
963
964
965     /* find connection */
966     if (cons_frame != NULL) {
967         /* SRT: search in frame */
968         for(cba_iter = cons_frame->conns; cba_iter != NULL; cba_iter = g_list_next(cba_iter)) {
969             conn = (cba_connection_t *)cba_iter->data;
970             if (conn->consid == consid) {
971                 return conn;
972             }
973         }
974     } else {
975         /* DCOM: search in ldev */
976         for(cba_iter = cons_ldev->consconns; cba_iter != NULL; cba_iter = g_list_next(cba_iter)) {
977             conn = (cba_connection_t *)cba_iter->data;
978             if ( conn->consid == consid &&
979                 cba_packet_in_range(pinfo, conn->packet_connect, conn->packet_disconnect, conn->packet_disconnectme)) {
980                 return conn;
981             }
982         }
983     }
984
985     conn = (cba_connection_t *)wmem_alloc(wmem_file_scope(), sizeof(cba_connection_t));
986
987     conn->consparentacco      = cons_ldev;
988     conn->provparentacco      = prov_ldev;
989     conn->parentframe         = cons_frame;
990
991     conn->packet_connect      = pinfo->num;
992     conn->packet_disconnect   = 0;
993     conn->packet_disconnectme = 0;
994     conn->packet_first        = 0;
995     conn->packet_last         = 0;
996
997     conn->consid              = consid;
998     conn->provitem            = wmem_strdup(wmem_file_scope(), provitem);
999     conn->typedesclen         = typedesclen;
1000     conn->typedesc            = typedesc;
1001     conn->qostype             = qostype;
1002     conn->qosvalue            = qosvalue;
1003     conn->length              = length;
1004
1005     conn->provid              = 0;
1006     conn->connret             = -1;
1007
1008     if (cons_frame != NULL) {
1009         conn->frame_offset   = cons_frame->offset;
1010         conn->length         = length;
1011         cons_frame->offset  += length;
1012         cons_frame->conns    = g_list_append(cons_frame->conns, conn);
1013     } else {
1014         conn->frame_offset   = 0;
1015         cons_ldev->consconns = g_list_append(cons_ldev->consconns, conn);
1016         prov_ldev->provconns = g_list_append(prov_ldev->provconns, conn);
1017     }
1018
1019     return conn;
1020 }
1021
1022
1023 static void
1024 cba_connection_disconnect(packet_info *pinfo, cba_connection_t *conn)
1025 {
1026     /* XXX - detect multiple disconnects? */
1027     if (conn->packet_disconnect == 0) {
1028         conn->packet_disconnect = pinfo->num;
1029     }
1030
1031     if (conn->packet_disconnect != pinfo->num) {
1032         g_warning("connection_disconnect#%u: already disconnected",
1033                   conn->packet_disconnect);
1034     }
1035 }
1036
1037
1038 static void
1039 cba_connection_disconnectme(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, cba_ldev_t *cons_ldev, cba_ldev_t *prov_ldev)
1040 {
1041     GList *conns;
1042     cba_connection_t *conn;
1043
1044
1045     for(conns = cons_ldev->consconns; conns != NULL; conns = g_list_next(conns)) {
1046         conn = (cba_connection_t *)conns->data;
1047
1048         if ( conn->provparentacco == prov_ldev &&
1049             cba_packet_in_range(pinfo, conn->packet_connect, conn->packet_disconnect, conn->packet_disconnectme)) {
1050
1051             cba_connection_info(tvb, pinfo, tree, conn);
1052
1053             if (conn->packet_disconnectme == 0) {
1054                 conn->packet_disconnectme = pinfo->num;
1055             }
1056
1057             if (conn->packet_disconnectme != pinfo->num) {
1058                 g_warning("connection_disconnectme#%u: already disconnectme'd",
1059                           conn->packet_disconnectme);
1060             }
1061         }
1062     }
1063 }
1064
1065
1066 static cba_connection_t *
1067 cba_connection_find_by_provid(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, cba_ldev_t *prov_ldev, guint32 provid)
1068 {
1069     GList *cba_iter;
1070     cba_connection_t *conn;
1071
1072
1073     for(cba_iter = prov_ldev->provconns; cba_iter != NULL; cba_iter = g_list_next(cba_iter)) {
1074         conn = (cba_connection_t *)cba_iter->data;
1075         if ( conn->provid == provid &&
1076             cba_packet_in_range(pinfo, conn->packet_connect, conn->packet_disconnect, conn->packet_disconnectme)) {
1077             return conn;
1078         }
1079     }
1080     return NULL;
1081 }
1082
1083
1084 static void
1085 cba_connection_incoming_data(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, cba_connection_t *conn)
1086 {
1087     if (conn->packet_first == 0) {
1088         conn->packet_first = pinfo->num;
1089     }
1090
1091     if ( pinfo->num > conn->packet_last &&
1092         cba_packet_in_range(pinfo, conn->packet_connect, conn->packet_disconnect, conn->packet_disconnectme)) {
1093         conn->packet_last = pinfo->num;
1094     }
1095 }
1096
1097
1098 /* dissect a response containing an array of hresults (e.g: ICBAAccoMgt::RemoveConnections) */
1099 static int
1100 dissect_HResultArray_resp(tvbuff_t *tvb, int offset,
1101     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
1102 {
1103     guint32 u32HResult;
1104     guint32 u32Pointer;
1105     guint32 u32ArraySize = 0;
1106     guint32 u32Idx;
1107     guint32 u32Tmp;
1108
1109
1110     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
1111
1112     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
1113                             &u32Pointer);
1114
1115     if (u32Pointer) {
1116         offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
1117                             &u32ArraySize);
1118
1119         u32Idx = 1;
1120         u32Tmp = u32ArraySize;
1121         while (u32Tmp--) {
1122             offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, di, drep,
1123                             &u32HResult, u32Idx);
1124             u32Idx++;
1125         }
1126     }
1127
1128     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
1129                             &u32HResult);
1130
1131     col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s",
1132         u32ArraySize,
1133         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
1134
1135     return offset;
1136 }
1137
1138
1139 static int
1140 dissect_ICBAAccoServer_SetActivation_resp(tvbuff_t *tvb, int offset,
1141     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
1142 {
1143     guint32 u32HResult;
1144     guint32 u32Pointer;
1145     guint32 u32ArraySize = 0;
1146     guint32 u32Idx;
1147     guint32 u32Tmp;
1148     proto_item *item;
1149
1150
1151     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
1152
1153     item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
1154     PROTO_ITEM_SET_GENERATED(item);
1155     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1));
1156
1157     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
1158                         &u32Pointer);
1159
1160     if (u32Pointer) {
1161         offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
1162                             &u32ArraySize);
1163
1164         u32Idx = 1;
1165         u32Tmp = u32ArraySize;
1166         while (u32Tmp--) {
1167             offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, di, drep,
1168                                 &u32HResult, u32Idx);
1169             u32Idx++;
1170         }
1171     }
1172
1173     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
1174                         &u32HResult);
1175
1176     col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s",
1177         u32ArraySize,
1178         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
1179
1180     return offset;
1181 }
1182
1183
1184 static int
1185 dissect_ICBAAccoServerSRT_Disconnect_resp(tvbuff_t *tvb, int offset,
1186     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
1187 {
1188     guint32 u32HResult;
1189     guint32 u32Pointer;
1190     guint32 u32ArraySize = 0;
1191     guint32 u32Idx;
1192     guint32 u32Tmp;
1193     proto_item *item;
1194
1195
1196     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
1197
1198     item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE);
1199     PROTO_ITEM_SET_GENERATED(item);
1200     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3));
1201
1202     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
1203                         &u32Pointer);
1204
1205     if (u32Pointer) {
1206         offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
1207                             &u32ArraySize);
1208
1209         u32Idx = 1;
1210         u32Tmp = u32ArraySize;
1211         while (u32Tmp--) {
1212             offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, di, drep,
1213                                 &u32HResult, u32Idx);
1214             u32Idx++;
1215         }
1216     }
1217
1218     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
1219                         &u32HResult);
1220
1221     col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s",
1222         u32ArraySize,
1223         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
1224
1225     return offset;
1226 }
1227
1228
1229 static int
1230 dissect_ICBAAccoServerSRT_SetActivation_resp(tvbuff_t *tvb, int offset,
1231     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
1232 {
1233     guint32 u32HResult;
1234     guint32 u32Pointer;
1235     guint32 u32ArraySize = 0;
1236     guint32 u32Idx;
1237     guint32 u32Tmp;
1238     proto_item *item;
1239
1240
1241     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
1242
1243     item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE);
1244     PROTO_ITEM_SET_GENERATED(item);
1245     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3));
1246
1247     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
1248                         &u32Pointer);
1249
1250     if (u32Pointer) {
1251         offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
1252                             &u32ArraySize);
1253
1254         u32Idx = 1;
1255         u32Tmp = u32ArraySize;
1256         while (u32Tmp--) {
1257             offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, di, drep,
1258                                 &u32HResult, u32Idx);
1259             u32Idx++;
1260         }
1261     }
1262
1263     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
1264                         &u32HResult);
1265
1266     col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s",
1267         u32ArraySize,
1268         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
1269
1270     return offset;
1271 }
1272
1273
1274 static int
1275 dissect_ICBAAccoServer_Connect_rqst(tvbuff_t *tvb, int offset,
1276     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
1277 {
1278     guint16 u16QoSType;
1279     guint16 u16QoSValue;
1280     guint8  u8State;
1281     guint32 u32Count;
1282     guint32 u32ArraySize;
1283
1284     guint32 u32VariableOffset;
1285     guint32 u32SubStart;
1286     guint32 u32Pointer;
1287     guint16 u16VarType;
1288     guint32 u32ConsID;
1289     gchar   szItem[1000]  = { 0 };
1290     guint32 u32MaxItemLen = sizeof(szItem);
1291     gchar   szCons[1000]  = { 0 };
1292     guint32 u32MaxConsLen = sizeof(szCons);
1293     guint32 u32Idx;
1294
1295     proto_item       *item;
1296     dcom_interface_t *cons_interf;
1297     cba_ldev_t       *cons_ldev;
1298     cba_ldev_t       *prov_ldev;
1299     cba_connection_t *conn;
1300     server_connect_call_t *call;
1301
1302
1303     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
1304
1305     /* get corresponding provider ldev */
1306     prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid);
1307
1308     item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE);
1309     PROTO_ITEM_SET_GENERATED(item);
1310     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2));
1311
1312     offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep,
1313                        hf_cba_acco_conn_consumer, szCons, u32MaxConsLen);
1314
1315     /* find the consumer ldev by its name */
1316     cons_ldev = cba_acco_add(pinfo, szCons);
1317
1318     offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
1319                         hf_cba_acco_conn_qos_type, &u16QoSType);
1320     offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
1321                         hf_cba_acco_conn_qos_value, &u16QoSValue);
1322     offset = dissect_dcom_BYTE(tvb, offset, pinfo, tree, di, drep,
1323                         hf_cba_acco_conn_state, &u8State);
1324
1325     offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, di, drep, 0, &cons_interf);
1326     if (cons_interf == NULL) {
1327         expert_add_info_format(pinfo, NULL, &ei_cba_acco_conn_consumer,
1328             "Server_Connect: consumer interface invalid");
1329     }
1330
1331     /* "crosslink" consumer interface and its object */
1332     if (cons_interf != NULL && cons_ldev != NULL) {
1333         cba_ldev_link_acco(pinfo, cons_ldev, cons_interf);
1334     }
1335
1336     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
1337                         hf_cba_acco_count, &u32Count);
1338
1339     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
1340                         &u32ArraySize);
1341
1342     /* link connections infos to the call */
1343     if (prov_ldev != NULL && cons_ldev != NULL) {
1344         call = (server_connect_call_t *)wmem_alloc(wmem_file_scope(), sizeof(server_connect_call_t) + u32ArraySize * sizeof(cba_connection_t *));
1345         call->conn_count = 0;
1346         call->frame      = NULL;
1347         call->conns      = (cba_connection_t **) (call+1);
1348         di->call_data->private_data = call;
1349     } else{
1350         call = NULL;
1351     }
1352
1353     u32VariableOffset = offset + u32ArraySize*16;
1354
1355     /* array of CONNECTINs */
1356     u32Idx = 1;
1357     while (u32ArraySize--) {
1358         proto_item *sub_item;
1359         proto_tree *sub_tree;
1360
1361         sub_item    = proto_tree_add_item(tree, hf_cba_connectin, tvb, offset, 0, ENC_NA);
1362         sub_tree    = proto_item_add_subtree(sub_item, ett_cba_connectin);
1363         u32SubStart = offset;
1364
1365         /* ProviderItem */
1366         offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
1367                             &u32Pointer);
1368         if (u32Pointer) {
1369             u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
1370                             hf_cba_acco_conn_provider_item, szItem, u32MaxItemLen);
1371         }
1372
1373         /* DataType */
1374         offset = dissect_dcom_VARTYPE(tvb, offset, pinfo, sub_tree, di, drep,
1375                             &u16VarType);
1376
1377         /* Epsilon */
1378         offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
1379                             &u32Pointer);
1380         if (u32Pointer) {
1381             u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
1382                             hf_cba_acco_conn_epsilon);
1383         }
1384         /* ConsumerID */
1385         offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
1386                             hf_cba_acco_conn_cons_id, &u32ConsID);
1387
1388         /* add to object database */
1389         if (prov_ldev != NULL && cons_ldev != NULL) {
1390             conn = cba_connection_connect(pinfo, cons_ldev, prov_ldev, /*cons_frame*/ NULL,
1391                 u16QoSType, u16QoSValue, szItem, u32ConsID, 0,
1392                 /* XXX - VarType must be translated to new type description if it includes an array (0x2000) */
1393                 (guint16 *)wmem_memdup(wmem_file_scope(), &u16VarType, 2), 1);
1394
1395             cba_connection_info(tvb, pinfo, sub_tree, conn);
1396         } else {
1397             conn = NULL;
1398         }
1399
1400         /* add to current call */
1401         if (call != NULL) {
1402             call->conn_count++;
1403             call->conns[u32Idx-1] = conn;
1404         }
1405
1406         /* update subtree header */
1407         proto_item_append_text(sub_item, "[%u]: ConsID=0x%x, ProvItem=\"%s\", VarType=%s",
1408             u32Idx, u32ConsID, szItem,
1409             val_to_str(u16VarType, dcom_variant_type_vals, "Unknown (0x%04x)") );
1410         proto_item_set_len(sub_item, offset - u32SubStart);
1411
1412         u32Idx++;
1413     }
1414
1415     col_append_fstr(pinfo->cinfo, COL_INFO, ": Consumer=\"%s\" Cnt=%u", szCons, u32Count);
1416
1417     return u32VariableOffset;
1418 }
1419
1420 static int
1421 dissect_ICBAAccoServer2_Connect2_rqst(tvbuff_t *tvb, int offset,
1422     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
1423 {
1424     guint16 u16QoSType;
1425     guint16 u16QoSValue;
1426     guint8  u8State;
1427     guint32 u32Count;
1428     guint32 u32ArraySize;
1429
1430     guint32 u32VariableOffset;
1431     guint32 u32SubStart;
1432     guint32 u32Pointer;
1433     guint16 u16VarType;
1434     guint32 u32ConsID;
1435     gchar   szItem[1000]  = { 0 };
1436     guint32 u32MaxItemLen = sizeof(szItem);
1437     gchar   szCons[1000]  = { 0 };
1438     guint32 u32MaxConsLen = sizeof(szCons);
1439     guint32 u32Idx;
1440     guint16 u16TypeDescLen;
1441     guint32 u32ArraySize2;
1442     guint32 u32Idx2;
1443     guint16 u16VarType2   = -1;
1444
1445     proto_item       *item;
1446     dcom_interface_t *cons_interf;
1447     cba_ldev_t       *prov_ldev;
1448     cba_ldev_t       *cons_ldev;
1449     cba_connection_t *conn;
1450     guint16           typedesclen = 0;
1451     guint16          *typedesc    = NULL;
1452     server_connect_call_t *call   = NULL;
1453
1454
1455     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
1456
1457     /* get corresponding provider ldev */
1458     prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid);
1459
1460     item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE);
1461     PROTO_ITEM_SET_GENERATED(item);
1462     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2));
1463
1464     offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep,
1465                        hf_cba_acco_conn_consumer, szCons, u32MaxConsLen);
1466
1467     /* find the consumer ldev by its name */
1468     cons_ldev = cba_acco_add(pinfo, szCons);
1469
1470     offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
1471                         hf_cba_acco_conn_qos_type, &u16QoSType);
1472     offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
1473                         hf_cba_acco_conn_qos_value, &u16QoSValue);
1474     offset = dissect_dcom_BYTE(tvb, offset, pinfo, tree, di, drep,
1475                         hf_cba_acco_conn_state, &u8State);
1476
1477     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep, &u32Pointer);
1478
1479     if (u32Pointer) {
1480         offset = dissect_dcom_MInterfacePointer(tvb, offset, pinfo, tree, di, drep, 0, &cons_interf);
1481         if (cons_interf == NULL) {
1482             expert_add_info_format(pinfo, NULL, &ei_cba_acco_conn_consumer,
1483                 "Server2_Connect2: consumer interface invalid");
1484         }
1485     } else {
1486         /* GetConnectionData do it this way */
1487         cons_interf = NULL;
1488     }
1489
1490     /* "crosslink" consumer interface and its object */
1491     if (cons_interf != NULL && cons_ldev != NULL) {
1492         cba_ldev_link_acco(pinfo, cons_ldev, cons_interf);
1493     }
1494
1495     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
1496                         hf_cba_acco_count, &u32Count);
1497
1498     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
1499                         &u32ArraySize);
1500
1501     /* link connection infos to the call */
1502     if (prov_ldev != NULL && cons_ldev != NULL) {
1503         call = (server_connect_call_t *)wmem_alloc(wmem_file_scope(), sizeof(server_connect_call_t) + u32ArraySize * sizeof(cba_connection_t *));
1504         call->conn_count = 0;
1505         call->frame      = NULL;
1506         call->conns      = (cba_connection_t **) (call+1);
1507         di->call_data->private_data = call;
1508     } else{
1509         call = NULL;
1510     }
1511
1512     u32VariableOffset = offset + u32ArraySize*20;
1513
1514     /* array of CONNECTINs */
1515     u32Idx = 1;
1516     while (u32ArraySize--) {
1517         proto_item       *sub_item;
1518         proto_tree       *sub_tree;
1519
1520         sub_item = proto_tree_add_item(tree, hf_cba_connectin, tvb, offset, 0, ENC_NA);
1521         sub_tree = proto_item_add_subtree(sub_item, ett_cba_connectin);
1522         u32SubStart = offset;
1523
1524         /* ProviderItem */
1525         offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
1526                             &u32Pointer);
1527         if (u32Pointer) {
1528             u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
1529                             hf_cba_acco_conn_provider_item, szItem, u32MaxItemLen);
1530         }
1531
1532         /* TypeDescLen */
1533         offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
1534                             hf_cba_type_desc_len, &u16TypeDescLen);
1535
1536         offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
1537                             &u32Pointer);
1538         /* pTypeDesc */
1539         if (u32Pointer) {
1540             u32VariableOffset = dissect_dcom_dcerpc_array_size(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
1541                                 &u32ArraySize2);
1542
1543             /* limit the allocation to a reasonable size */
1544             if (u32ArraySize2 < 1000) {
1545                 typedesc = (guint16 *)wmem_alloc0(wmem_file_scope(), u32ArraySize2 * 2);
1546                 typedesclen = u32ArraySize2;
1547             } else {
1548                 typedesc = NULL;
1549                 typedesclen = 0;
1550             }
1551
1552             /* extended type description will build an array here */
1553             u32Idx2 = 1;
1554             while (u32ArraySize2--) {
1555                 /* ToBeDone: some of the type description values are counts */
1556                 u32VariableOffset = dissect_dcom_VARTYPE(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
1557                                 &u16VarType);
1558
1559                 if (typedesc != NULL && u32Idx2 <= typedesclen) {
1560                     typedesc[u32Idx2-1] = u16VarType;
1561                 }
1562
1563                 /* remember first VarType only */
1564                 if (u32Idx2 == 1) {
1565                     u16VarType2 = u16VarType;
1566                 }
1567                 u32Idx2++;
1568             }
1569         }
1570
1571         /* Epsilon */
1572         offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
1573                             &u32Pointer);
1574         if (u32Pointer) {
1575             u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
1576                             hf_cba_acco_conn_epsilon);
1577         }
1578         /* ConsumerID */
1579         offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
1580                             hf_cba_acco_conn_cons_id, &u32ConsID);
1581
1582         /* add to object database */
1583         if (prov_ldev != NULL && cons_ldev != NULL) {
1584             conn = cba_connection_connect(pinfo, cons_ldev, prov_ldev, /*cons_frame*/ NULL,
1585                 u16QoSType, u16QoSValue, szItem, u32ConsID, 0,
1586                 typedesc, typedesclen);
1587
1588             cba_connection_info(tvb, pinfo, sub_tree, conn);
1589         } else {
1590             conn = NULL;
1591         }
1592
1593         /* add to current call */
1594         if (call != NULL) {
1595             call->conn_count++;
1596             call->conns[u32Idx-1] = conn;
1597         }
1598
1599         /* update subtree header */
1600         proto_item_append_text(sub_item, "[%u]: ConsID=0x%x, ProvItem=\"%s\", TypeDesc=%s",
1601             u32Idx, u32ConsID, szItem,
1602             val_to_str(u16VarType2, dcom_variant_type_vals, "Unknown (0x%04x)") );
1603         proto_item_set_len(sub_item, offset - u32SubStart);
1604
1605         u32Idx++;
1606     }
1607
1608     col_append_fstr(pinfo->cinfo, COL_INFO, ": Consumer=\"%s\" Cnt=%u", szCons, u32Count);
1609
1610
1611     return u32VariableOffset;
1612 }
1613
1614
1615 static int
1616 dissect_ICBAAccoServer_Connect_resp(tvbuff_t *tvb, int offset,
1617     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
1618 {
1619     guint8  u8FirstConnect;
1620     guint32 u32Pointer;
1621     guint32 u32ArraySize = 0;
1622     guint32 u32HResult;
1623     guint32 u32Idx       = 1;
1624     guint32 u32ProvID;
1625     guint32 u32SubStart;
1626
1627     proto_item  *item;
1628     cba_connection_t *conn;
1629     server_connect_call_t *call = (server_connect_call_t *)di->call_data->private_data;
1630
1631
1632     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
1633
1634     if (call == NULL) {
1635         expert_add_info(pinfo, NULL, &ei_cba_acco_no_request_info);
1636     }
1637
1638     item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
1639     PROTO_ITEM_SET_GENERATED(item);
1640     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1));
1641
1642     offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, tree, di, drep,
1643                         hf_cba_acco_server_first_connect, &u8FirstConnect);
1644
1645     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
1646                         &u32Pointer);
1647
1648     if (u32Pointer) {
1649         offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
1650                             &u32ArraySize);
1651
1652         /* array of CONNECTOUTs */
1653         while(u32ArraySize--) {
1654             proto_item *sub_item;
1655             proto_tree *sub_tree;
1656
1657             sub_item = proto_tree_add_item(tree, hf_cba_connectout, tvb, offset, 8, ENC_NA);
1658             sub_tree = proto_item_add_subtree(sub_item, ett_cba_connectout);
1659             u32SubStart = offset;
1660
1661             offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
1662                                 hf_cba_acco_conn_prov_id, &u32ProvID);
1663
1664             offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
1665                                 &u32HResult, u32Idx);
1666
1667             /* put response data into the connection */
1668             if (call && u32Idx <= call->conn_count) {
1669                 conn = call->conns[u32Idx-1];
1670                 conn->provid  = u32ProvID;
1671                 conn->connret = u32HResult;
1672
1673                 cba_connection_info(tvb, pinfo, sub_tree, conn);
1674             }
1675
1676             proto_item_append_text(sub_item, "[%u]: ProvID=0x%x %s",
1677                 u32Idx, u32ProvID,
1678                 val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
1679             proto_item_set_len(sub_item, offset - u32SubStart);
1680
1681             u32Idx++;
1682         }
1683     }
1684
1685     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
1686                         &u32HResult);
1687
1688     /* this might be a global HRESULT */
1689     while(call && u32Idx <= call->conn_count) {
1690         conn = call->conns[u32Idx-1];
1691         conn->provid  = 0;
1692         conn->connret = u32HResult;
1693         u32Idx++;
1694     }
1695
1696     col_append_fstr(pinfo->cinfo, COL_INFO, ": %s Cnt=%u -> %s",
1697         (u8FirstConnect) ? "First" : "NotFirst",
1698         u32Idx-1,
1699         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
1700
1701     return offset;
1702 }
1703
1704
1705 static int
1706 dissect_ICBAAccoServer_Disconnect_rqst(tvbuff_t *tvb, int offset,
1707     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
1708 {
1709     guint32 u32Count;
1710     guint32 u32ArraySize;
1711     guint32 u32Idx;
1712     guint32 u32ProvID;
1713
1714     proto_item  *item;
1715     cba_ldev_t  *prov_ldev;
1716     cba_connection_t *conn;
1717     server_connect_call_t *call;
1718
1719
1720     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
1721
1722     item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE);
1723     PROTO_ITEM_SET_GENERATED(item);
1724     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2));
1725
1726     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
1727                         hf_cba_acco_count, &u32Count);
1728
1729     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
1730                         &u32ArraySize);
1731
1732     prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid);
1733
1734     /* link connection infos to the call */
1735     if (prov_ldev != NULL) {
1736         call = (server_connect_call_t *)wmem_alloc(wmem_file_scope(), sizeof(server_connect_call_t) + u32ArraySize * sizeof(cba_connection_t *));
1737         call->conn_count = 0;
1738         call->frame      = NULL;
1739         call->conns      = (cba_connection_t **) (call+1);
1740         di->call_data->private_data = call;
1741     } else{
1742         call = NULL;
1743     }
1744
1745     u32Idx = 1;
1746     while (u32ArraySize--) {
1747         offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep,
1748                         hf_cba_acco_conn_prov_id, &u32ProvID, u32Idx);
1749
1750         /* add to current call */
1751         if (call != NULL) {
1752             conn = cba_connection_find_by_provid(tvb, pinfo, tree, prov_ldev, u32ProvID);
1753             call->conn_count++;
1754             call->conns[u32Idx-1] = conn;
1755         }
1756
1757         u32Idx++;
1758     }
1759
1760     /* update column info now */
1761     col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
1762
1763
1764     return offset;
1765 }
1766
1767
1768 static int
1769 dissect_ICBAAccoServer_Disconnect_resp(tvbuff_t *tvb, int offset,
1770     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
1771 {
1772     guint32 u32HResult;
1773     guint32 u32Pointer;
1774     guint32 u32ArraySize = 0;
1775     guint32 u32Idx;
1776     guint32 u32Tmp;
1777
1778     proto_item  *item;
1779     cba_connection_t *conn;
1780     server_connect_call_t *call = (server_connect_call_t *)di->call_data->private_data;
1781
1782
1783     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
1784
1785     if (call == NULL) {
1786         expert_add_info(pinfo, NULL, &ei_cba_acco_no_request_info);
1787     }
1788
1789     item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
1790     PROTO_ITEM_SET_GENERATED(item);
1791     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1));
1792
1793     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
1794                         &u32Pointer);
1795
1796     if (u32Pointer) {
1797         offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
1798                             &u32ArraySize);
1799
1800         u32Idx = 1;
1801         u32Tmp = u32ArraySize;
1802         while (u32Tmp--) {
1803             offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, di, drep,
1804                                 &u32HResult, u32Idx);
1805
1806             /* mark this connection as disconnected */
1807             if (call && u32Idx <= call->conn_count) {
1808                 conn = call->conns[u32Idx-1];
1809                 if (conn != NULL) {
1810                     cba_connection_disconnect(pinfo, conn);
1811                 }
1812             }
1813
1814             u32Idx++;
1815         }
1816     }
1817
1818     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
1819                         &u32HResult);
1820
1821     col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s",
1822         u32ArraySize,
1823         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
1824
1825     return offset;
1826 }
1827
1828
1829 static int
1830 dissect_ICBAAccoServerSRT_Disconnect_rqst(tvbuff_t *tvb, int offset,
1831     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
1832 {
1833     guint32 u32Count;
1834     guint32 u32ArraySize;
1835     guint32 u32Idx;
1836     guint32 u32ProvID;
1837     proto_item *item;
1838
1839
1840     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
1841
1842     item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE);
1843     PROTO_ITEM_SET_GENERATED(item);
1844     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4));
1845
1846     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
1847                         hf_cba_acco_count, &u32Count);
1848
1849     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
1850                         &u32ArraySize);
1851
1852     u32Idx = 1;
1853     while (u32ArraySize--) {
1854         offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep,
1855                         hf_cba_acco_conn_prov_id, &u32ProvID, u32Idx);
1856         u32Idx++;
1857     }
1858
1859     /* update column info now */
1860     col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
1861
1862     return offset;
1863 }
1864
1865
1866 static int
1867 dissect_ICBAAccoServer_DisconnectMe_rqst(tvbuff_t *tvb, int offset,
1868     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
1869 {
1870     gchar        szStr[1000];
1871     guint32      u32MaxStr = sizeof(szStr);
1872     proto_item  *item;
1873     cba_ldev_t  *prov_ldev;
1874     cba_ldev_t  *cons_ldev;
1875     server_disconnectme_call_t *call;
1876
1877
1878     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
1879
1880     /* get corresponding provider ldev */
1881     prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid);
1882
1883     item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE);
1884     PROTO_ITEM_SET_GENERATED(item);
1885     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2));
1886
1887     offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep,
1888         hf_cba_acco_conn_consumer, szStr, u32MaxStr);
1889
1890     /* find the consumer ldev by its name */
1891     cons_ldev = cba_acco_add(pinfo, szStr);
1892
1893     if (prov_ldev != NULL && cons_ldev != NULL) {
1894         call = (server_disconnectme_call_t *)wmem_alloc(wmem_file_scope(), sizeof(server_disconnectme_call_t));
1895         call->cons = cons_ldev;
1896         call->prov = prov_ldev;
1897         di->call_data->private_data = call;
1898     }
1899
1900     /* update column info now */
1901     col_append_fstr(pinfo->cinfo, COL_INFO, " Consumer=\"%s\"", szStr);
1902
1903     return offset;
1904 }
1905
1906
1907 static int
1908 dissect_ICBAAccoServer_DisconnectMe_resp(tvbuff_t *tvb, int offset,
1909     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
1910 {
1911     guint32      u32HResult;
1912     proto_item  *item;
1913     server_disconnectme_call_t *call;
1914
1915
1916     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
1917
1918     item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
1919     PROTO_ITEM_SET_GENERATED(item);
1920     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1));
1921
1922     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
1923                     &u32HResult);
1924
1925     call = (server_disconnectme_call_t *)di->call_data->private_data;
1926     if (call) {
1927         cba_connection_disconnectme(tvb, pinfo, tree, call->cons, call->prov);
1928     }
1929
1930     col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
1931         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
1932
1933     return offset;
1934 }
1935
1936
1937 static int
1938 dissect_ICBAAccoServerSRT_DisconnectMe_rqst(tvbuff_t *tvb, int offset,
1939     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
1940 {
1941     gchar        szStr[1000];
1942     guint32      u32MaxStr = sizeof(szStr);
1943     proto_item  *item;
1944     cba_ldev_t  *prov_ldev;
1945     cba_ldev_t  *cons_ldev;
1946     server_disconnectme_call_t *call;
1947
1948
1949     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
1950
1951     /* get corresponding provider ldev */
1952     prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid);
1953
1954     item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE);
1955     PROTO_ITEM_SET_GENERATED(item);
1956     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4));
1957
1958     offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep,
1959         hf_cba_acco_conn_consumer, szStr, u32MaxStr);
1960
1961     /* find the consumer ldev by its name */
1962     cons_ldev = cba_acco_add(pinfo, szStr);
1963
1964     if (prov_ldev != NULL && cons_ldev != NULL) {
1965         call = (server_disconnectme_call_t *)wmem_alloc(wmem_file_scope(), sizeof(server_disconnectme_call_t));
1966         call->cons = cons_ldev;
1967         call->prov = prov_ldev;
1968         di->call_data->private_data = call;
1969     }
1970
1971     /* update column info now */
1972     col_append_fstr(pinfo->cinfo, COL_INFO, " Consumer=\"%s\"", szStr);
1973
1974     return offset;
1975 }
1976
1977
1978 static int
1979 dissect_ICBAAccoServerSRT_DisconnectMe_resp(tvbuff_t *tvb, int offset,
1980     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
1981 {
1982     guint32      u32HResult;
1983     proto_item  *item;
1984     server_disconnectme_call_t *call;
1985
1986
1987     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
1988
1989     item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE);
1990     PROTO_ITEM_SET_GENERATED(item);
1991     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3));
1992
1993     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
1994                     &u32HResult);
1995
1996     call = (server_disconnectme_call_t *)di->call_data->private_data;
1997     if (call) {
1998         cba_frame_disconnectme(tvb, pinfo, tree, call->cons, call->prov);
1999     }
2000
2001   col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
2002     val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
2003
2004     return offset;
2005 }
2006
2007
2008 static int
2009 dissect_ICBAAccoServer_Ping_resp(tvbuff_t *tvb, int offset,
2010     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2011 {
2012     guint32     u32HResult;
2013     proto_item *item;
2014
2015
2016     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
2017
2018     item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
2019     PROTO_ITEM_SET_GENERATED(item);
2020     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1));
2021
2022     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
2023                     &u32HResult);
2024
2025     col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
2026         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
2027
2028     return offset;
2029 }
2030
2031
2032 static int
2033 dissect_ICBAAccoServer_SetActivation_rqst(tvbuff_t *tvb, int offset,
2034     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2035 {
2036     guint8      u8State;
2037     guint32     u32Count;
2038     guint32     u32ArraySize;
2039     guint32     u32Idx;
2040     guint32     u32ProvID;
2041     proto_item *item;
2042
2043
2044     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
2045
2046     item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE);
2047     PROTO_ITEM_SET_GENERATED(item);
2048     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2));
2049
2050     offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, tree, di, drep,
2051                         hf_cba_acco_conn_state, &u8State);
2052
2053     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
2054                         hf_cba_acco_count, &u32Count);
2055
2056     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
2057                         &u32ArraySize);
2058
2059     u32Idx = 1;
2060     while (u32ArraySize--) {
2061         offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep,
2062                      hf_cba_acco_conn_prov_id, &u32ProvID, u32Idx);
2063         u32Idx++;
2064     }
2065
2066     /* update column info now */
2067
2068     col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
2069
2070     return offset;
2071 }
2072
2073
2074 static int
2075 dissect_ICBAAccoServerSRT_SetActivation_rqst(tvbuff_t *tvb, int offset,
2076     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2077 {
2078     guint8      u8State;
2079     guint32     u32Count;
2080     guint32     u32ArraySize;
2081     guint32     u32Idx;
2082     guint32     u32ProvID;
2083     proto_item *item;
2084
2085
2086     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
2087
2088     item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE);
2089     PROTO_ITEM_SET_GENERATED(item);
2090     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4));
2091
2092     offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, tree, di, drep,
2093                         hf_cba_acco_conn_state, &u8State);
2094
2095     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
2096                         hf_cba_acco_count, &u32Count);
2097
2098     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
2099                         &u32ArraySize);
2100
2101     u32Idx = 1;
2102     while (u32ArraySize--) {
2103         offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep,
2104                      hf_cba_acco_conn_prov_id, &u32ProvID, u32Idx);
2105         u32Idx++;
2106     }
2107
2108     /* update column info now */
2109     col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
2110
2111     return offset;
2112 }
2113
2114
2115 static int
2116 dissect_ICBAAccoServer_Ping_rqst(tvbuff_t *tvb, int offset,
2117     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2118 {
2119     gchar       szStr[1000];
2120     guint32     u32MaxStr = sizeof(szStr);
2121     proto_item *item;
2122
2123
2124     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
2125
2126     item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE);
2127     PROTO_ITEM_SET_GENERATED(item);
2128     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2));
2129
2130     offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep,
2131         hf_cba_acco_conn_consumer, szStr, u32MaxStr);
2132
2133     /* update column info now */
2134     col_append_fstr(pinfo->cinfo, COL_INFO, " Consumer=\"%s\"", szStr);
2135
2136     return offset;
2137 }
2138
2139
2140 static int
2141 dissect_ICBAAccoServerSRT_ConnectCR_rqst(tvbuff_t *tvb, int offset,
2142     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2143 {
2144     gchar   szCons[1000]            = { 0 };
2145     guint32           u32MaxConsLen = sizeof(szCons);
2146     guint16           u16QoSType;
2147     guint16           u16QoSValue;
2148     guint8            u8ConsMac[6];
2149     guint16           u16CRID       = 0;
2150     guint16           u16CRLength   = 0;
2151     guint32           u32Flags;
2152     guint32           u32Count;
2153     guint32           u32ArraySize;
2154     guint32           u32Idx;
2155     proto_item       *item;
2156     proto_tree       *flags_tree;
2157     guint32           u32SubStart;
2158     dcom_interface_t *cons_interf;
2159     cba_ldev_t       *prov_ldev;
2160     cba_ldev_t       *cons_ldev;
2161     cba_frame_t      *frame;
2162     server_frame_call_t *call;
2163
2164
2165     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
2166
2167     /* get corresponding provider ldev */
2168     prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid);
2169
2170     item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE);
2171     PROTO_ITEM_SET_GENERATED(item);
2172     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4));
2173
2174     /* szCons */
2175     offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep,
2176                        hf_cba_acco_conn_consumer, szCons, u32MaxConsLen);
2177
2178     /* find the consumer ldev by its name */
2179     cons_ldev = cba_acco_add(pinfo, szCons);
2180
2181     offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
2182                         hf_cba_acco_conn_qos_type, &u16QoSType);
2183     offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
2184                         hf_cba_acco_conn_qos_value, &u16QoSValue);
2185
2186     offset = dissect_dcom_PMInterfacePointer(tvb, offset, pinfo, tree, di, drep, 0, &cons_interf);
2187     if (cons_interf == NULL) {
2188         expert_add_info_format(pinfo, NULL, &ei_cba_acco_conn_consumer,
2189             "ServerSRT_ConnectCR: consumer interface invalid");
2190     }
2191
2192     /* "crosslink" consumer interface and its object */
2193     if (cons_interf != NULL && cons_ldev != NULL) {
2194         cba_ldev_link_acco(pinfo, cons_ldev, cons_interf);
2195     }
2196
2197     /* ConsumerMAC (big-endian, 1byte-aligned) */
2198     tvb_memcpy(tvb, u8ConsMac, offset, 6);
2199
2200     proto_tree_add_ether(tree, hf_cba_acco_serversrt_cons_mac, tvb,
2201         offset, 6, u8ConsMac);
2202     offset += 6;
2203
2204     /* add flags subtree */
2205     offset = dissect_dcom_DWORD(tvb, offset, pinfo, NULL /*tree*/, di, drep,
2206                         0 /* hfindex */, &u32Flags);
2207     offset -= 4;
2208     item = proto_tree_add_uint_format_value(tree, hf_cba_acco_serversrt_cr_flags,
2209         tvb, offset, 4, u32Flags,
2210         "0x%02x (%s, %s)", u32Flags,
2211         (u32Flags & 0x2) ? "Reconfigure" : "not Reconfigure",
2212         (u32Flags & 0x1) ? "Timestamped" : "not Timestamped");
2213     flags_tree = proto_item_add_subtree(item, ett_cba_acco_serversrt_cr_flags);
2214     proto_tree_add_boolean(flags_tree, hf_cba_acco_serversrt_cr_flags_reconfigure, tvb, offset, 4, u32Flags);
2215     proto_tree_add_boolean(flags_tree, hf_cba_acco_serversrt_cr_flags_timestamped, tvb, offset, 4, u32Flags);
2216     offset += 4;
2217
2218     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
2219                         hf_cba_acco_count, &u32Count);
2220
2221     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
2222                         &u32ArraySize);
2223
2224     /* link frame infos to the call */
2225     if (prov_ldev != NULL && cons_ldev != NULL && u32ArraySize < 100) {
2226         call = (server_frame_call_t *)wmem_alloc(wmem_file_scope(), sizeof(server_frame_call_t) + u32ArraySize * sizeof(cba_frame_t *));
2227         call->frame_count = 0;
2228         call->frames = (cba_frame_t **) (call+1);
2229         di->call_data->private_data = call;
2230     } else {
2231         call = NULL;
2232     }
2233
2234     u32Idx = 1;
2235     while (u32ArraySize--) {
2236         proto_item *sub_item;
2237         proto_tree *sub_tree;
2238
2239         /* array of CONNECTINCRs */
2240         sub_item = proto_tree_add_item(tree, hf_cba_connectincr, tvb, offset, 0, ENC_NA);
2241         sub_tree = proto_item_add_subtree(sub_item, ett_cba_connectincr);
2242         u32SubStart = offset;
2243
2244         offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
2245                             hf_cba_acco_serversrt_cr_id, &u16CRID);
2246
2247         offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
2248                             hf_cba_acco_serversrt_cr_length, &u16CRLength);
2249
2250         /* add to object database */
2251         if (prov_ldev != NULL && cons_ldev != NULL) {
2252             frame = cba_frame_connect(pinfo, cons_ldev, prov_ldev, u16QoSType, u16QoSValue, u8ConsMac, u16CRID, u16CRLength);
2253
2254             cba_frame_info(tvb, pinfo, sub_tree, frame);
2255         } else {
2256             frame = NULL;
2257         }
2258
2259         /* add to current call */
2260         if (call != NULL) {
2261             call->frame_count++;
2262             call->frames[u32Idx-1] = frame;
2263         }
2264
2265         /* update subtree header */
2266         proto_item_append_text(sub_item, "[%u]: CRID=0x%x, CRLength=%u",
2267             u32Idx, u16CRID, u16CRLength);
2268         proto_item_set_len(sub_item, offset - u32SubStart);
2269
2270         u32Idx++;
2271     }
2272
2273
2274     /* update column info now */
2275     col_append_fstr(pinfo->cinfo, COL_INFO, ": %sConsCRID=0x%x Len=%u QoS=%u",
2276            (u32Flags & 0x2) ? "Reco " : "", u16CRID, u16CRLength, u16QoSValue);
2277
2278     return offset;
2279 }
2280
2281
2282 static int
2283 dissect_ICBAAccoServerSRT_ConnectCR_resp(tvbuff_t *tvb, int offset,
2284     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2285 {
2286     guint8       u8FirstConnect;
2287     guint8       u8ProvMac[6];
2288     guint32      u32ProvCRID = 0;
2289     guint32      u32HResult;
2290     guint32      u32ArraySize;
2291     guint32      u32Idx      = 1;
2292     guint32      u32Pointer;
2293     guint32      u32SubStart;
2294     proto_item  *item;
2295     cba_frame_t *frame;
2296     server_frame_call_t *call = (server_frame_call_t *)di->call_data->private_data;
2297
2298
2299     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
2300
2301     if (call == NULL) {
2302         expert_add_info(pinfo, NULL, &ei_cba_acco_no_request_info);
2303     }
2304
2305     item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE);
2306     PROTO_ITEM_SET_GENERATED(item);
2307     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3));
2308
2309     offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, tree, di, drep,
2310                         hf_cba_acco_server_first_connect, &u8FirstConnect);
2311
2312     /* ProviderMAC (big-endian, 1byte-aligned) */
2313     tvb_memcpy(tvb, u8ProvMac, offset, 6);
2314
2315     proto_tree_add_ether(tree, hf_cba_acco_serversrt_prov_mac, tvb,
2316         offset, 6, u8ProvMac);
2317     offset += 6;
2318
2319
2320     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
2321                         &u32Pointer);
2322     if (u32Pointer) {
2323
2324         offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
2325                             &u32ArraySize);
2326
2327         while (u32ArraySize--) {
2328             proto_item *sub_item;
2329             proto_tree *sub_tree;
2330
2331             /* array of CONNECTOUTCRs */
2332             sub_item = proto_tree_add_item(tree, hf_cba_connectoutcr, tvb, offset, 0, ENC_NA);
2333             sub_tree = proto_item_add_subtree(sub_item, ett_cba_connectoutcr);
2334             u32SubStart = offset;
2335
2336             offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
2337                                         hf_cba_acco_prov_crid, &u32ProvCRID);
2338
2339             offset = dissect_dcom_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
2340                                           &u32HResult);
2341
2342             /* put response data into the frame */
2343             if (call && u32Idx <= call->frame_count) {
2344                 frame = call->frames[u32Idx-1];
2345                 frame->provcrid  = u32ProvCRID;
2346                 frame->conncrret = u32HResult;
2347
2348                 cba_frame_info(tvb, pinfo, sub_tree, frame);
2349             }
2350
2351             /* update subtree header */
2352             proto_item_append_text(sub_item, "[%u]: ProvCRID=0x%x, %s",
2353                                    u32Idx, u32ProvCRID,
2354                                    val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
2355             proto_item_set_len(sub_item, offset - u32SubStart);
2356
2357             u32Idx++;
2358         }
2359     }
2360
2361     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
2362                         &u32HResult);
2363
2364     /* this might be a global HRESULT */
2365     while(call && u32Idx <= call->frame_count) {
2366         frame = call->frames[u32Idx-1];
2367         frame->provcrid  = 0;
2368         frame->conncrret = u32HResult;
2369         u32Idx++;
2370     }
2371
2372     col_append_fstr(pinfo->cinfo, COL_INFO, ": %s PCRID=0x%x -> %s",
2373         (u8FirstConnect) ? "FirstCR" : "NotFirstCR",
2374         u32ProvCRID,
2375         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
2376
2377     return offset;
2378 }
2379
2380
2381 static int
2382 dissect_ICBAAccoServerSRT_DisconnectCR_rqst(tvbuff_t *tvb, int offset,
2383     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2384 {
2385     guint32      u32Count;
2386     guint32      u32ArraySize;
2387     guint32      u32Idx;
2388     guint32      u32ProvCRID = 0;
2389     proto_item  *item;
2390     cba_ldev_t  *prov_ldev;
2391     cba_frame_t *frame;
2392     server_frame_call_t *call;
2393
2394
2395     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
2396
2397     /* get corresponding provider ldev */
2398     prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid);
2399
2400     item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE);
2401     PROTO_ITEM_SET_GENERATED(item);
2402     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4));
2403
2404     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
2405                         hf_cba_acco_count, &u32Count);
2406
2407     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
2408                         &u32ArraySize);
2409
2410     /* link frame infos to the call */
2411     if (prov_ldev != NULL) {
2412         call = (server_frame_call_t *)wmem_alloc(wmem_file_scope(), sizeof(server_frame_call_t) + u32ArraySize * sizeof(cba_frame_t *));
2413         call->frame_count = 0;
2414         call->frames      = (cba_frame_t **) (call+1);
2415         di->call_data->private_data = call;
2416     } else{
2417         call = NULL;
2418     }
2419
2420     u32Idx = 1;
2421     while (u32ArraySize--) {
2422         offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep,
2423                         hf_cba_acco_prov_crid, &u32ProvCRID, u32Idx);
2424
2425         /* find frame and add it to current call */
2426         if (call != NULL) {
2427             frame = cba_frame_find_by_provcrid(pinfo, prov_ldev, u32ProvCRID);
2428             call->frame_count++;
2429             call->frames[u32Idx-1] = frame;
2430         }
2431
2432         u32Idx++;
2433     }
2434
2435     /* update column info now */
2436     col_append_fstr(pinfo->cinfo, COL_INFO, ": PCRID=0x%x",
2437            u32ProvCRID);
2438
2439     return offset;
2440 }
2441
2442
2443 static int
2444 dissect_ICBAAccoServerSRT_DisconnectCR_resp(tvbuff_t *tvb, int offset,
2445     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2446 {
2447     guint32      u32HResult;
2448     guint32      u32Pointer;
2449     guint32      u32ArraySize = 0;
2450     guint32      u32Idx;
2451     guint32      u32Tmp;
2452     cba_frame_t *frame;
2453     proto_item  *item;
2454     server_frame_call_t *call = (server_frame_call_t *)di->call_data->private_data;
2455
2456
2457     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
2458
2459     item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE);
2460     PROTO_ITEM_SET_GENERATED(item);
2461     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3));
2462
2463     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
2464                         &u32Pointer);
2465
2466     if (u32Pointer) {
2467         offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
2468                             &u32ArraySize);
2469
2470         u32Idx = 1;
2471         u32Tmp = u32ArraySize;
2472         while (u32Tmp--) {
2473             offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, tree, di, drep,
2474                                 &u32HResult, u32Idx);
2475             /* put response data into the frame */
2476             if (call && u32Idx <= call->frame_count) {
2477                 frame = call->frames[u32Idx-1];
2478                 if (frame != NULL) {
2479                     cba_frame_disconnect(pinfo, frame);
2480                 }
2481             }
2482
2483             u32Idx++;
2484         }
2485     }
2486
2487     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
2488                         &u32HResult);
2489
2490     col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
2491         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
2492
2493     return offset;
2494 }
2495
2496
2497 static int
2498 dissect_ICBAAccoServerSRT_Connect_rqst(tvbuff_t *tvb, int offset,
2499     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2500 {
2501     guint32 u32ProvCRID;
2502     guint8  u8State;
2503     guint8  u8LastConnect;
2504     guint32 u32Count;
2505     guint32 u32ArraySize;
2506     guint32 u32VariableOffset;
2507     guint32 u32Idx;
2508     guint32 u32SubStart;
2509     guint32 u32Pointer;
2510     gchar   szProvItem[1000]  = { 0 };
2511     guint32 u32MaxProvItemLen = sizeof(szProvItem);
2512     guint16 u16TypeDescLen;
2513     guint32 u32ArraySize2;
2514     guint32 u32Idx2;
2515     guint16 u16VarType2 = -1;
2516     guint16 u16VarType;
2517     guint32 u32ConsID;
2518     guint16 u16RecordLength;
2519
2520     proto_item  *item;
2521     cba_ldev_t  *prov_ldev;
2522     cba_frame_t *frame       = NULL;
2523     guint16      typedesclen = 0;
2524     guint16     *typedesc    = NULL;
2525
2526     cba_connection_t      *conn;
2527     server_connect_call_t *call;
2528
2529
2530     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
2531
2532     /* get corresponding provider ldev */
2533     prov_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid);
2534
2535     item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE);
2536     PROTO_ITEM_SET_GENERATED(item);
2537     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4));
2538
2539     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
2540                         hf_cba_acco_prov_crid, &u32ProvCRID);
2541
2542     frame = cba_frame_find_by_provcrid(pinfo, prov_ldev, u32ProvCRID);
2543
2544     if (frame != NULL) {
2545         cba_frame_info(tvb, pinfo, tree, frame);
2546     }
2547
2548     offset = dissect_dcom_BYTE(tvb, offset, pinfo, tree, di, drep,
2549                         hf_cba_acco_conn_state, &u8State);
2550
2551     offset = dissect_dcom_BYTE(tvb, offset, pinfo, tree, di, drep,
2552                         hf_cba_acco_serversrt_last_connect, &u8LastConnect);
2553
2554
2555     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
2556                         hf_cba_acco_count, &u32Count);
2557
2558     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
2559                         &u32ArraySize);
2560
2561     /* link connections infos to the call */
2562     if (frame != NULL) {
2563         call = (server_connect_call_t *)wmem_alloc(wmem_file_scope(), sizeof(server_connect_call_t) + u32ArraySize * sizeof(cba_connection_t *));
2564         call->conn_count = 0;
2565         call->frame = frame;
2566         call->conns = (cba_connection_t **) (call+1);
2567         di->call_data->private_data = call;
2568     } else{
2569         call = NULL;
2570     }
2571
2572     u32VariableOffset = offset + u32ArraySize*20;
2573
2574     u32Idx = 1;
2575     while (u32ArraySize--) {
2576         proto_item *sub_item;
2577         proto_tree *sub_tree;
2578
2579         /* array of CONNECTINs */
2580         sub_item = proto_tree_add_item(tree, hf_cba_connectin, tvb, offset, 0, ENC_NA);
2581         sub_tree = proto_item_add_subtree(sub_item, ett_cba_connectin);
2582         u32SubStart = offset;
2583
2584         /* ProviderItem */
2585         offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
2586                             &u32Pointer);
2587         if (u32Pointer) {
2588             u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
2589                             hf_cba_acco_conn_provider_item, szProvItem, u32MaxProvItemLen);
2590         }
2591
2592         /* TypeDescLen */
2593         offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
2594                             hf_cba_type_desc_len, &u16TypeDescLen);
2595
2596         offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
2597                             &u32Pointer);
2598         /* pTypeDesc */
2599         if (u32Pointer) {
2600             u32VariableOffset = dissect_dcom_dcerpc_array_size(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
2601                                 &u32ArraySize2);
2602
2603             typedesc = (guint16 *)wmem_alloc0(wmem_file_scope(), u32ArraySize2 * 2);
2604             typedesclen = u32ArraySize2;
2605
2606             /* extended type description will build an array here */
2607             u32Idx2 = 1;
2608             while (u32ArraySize2--) {
2609                 /* ToBeDone: some of the type description values are counts */
2610                 u32VariableOffset = dissect_dcom_VARTYPE(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
2611                                 &u16VarType);
2612
2613                 if (u32Idx2 <= typedesclen) {
2614                     typedesc[u32Idx2-1] = u16VarType;
2615                 }
2616
2617                 /* remember first VarType only */
2618                 if (u32Idx2 == 1) {
2619                     u16VarType2 = u16VarType;
2620                 }
2621                 u32Idx2++;
2622             }
2623         }
2624
2625         /* ConsumerID */
2626         offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
2627                             hf_cba_acco_conn_cons_id, &u32ConsID);
2628
2629         /* RecordLength */
2630         offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
2631                             hf_cba_acco_serversrt_record_length, &u16RecordLength);
2632
2633         /* add to object database */
2634         if (frame != NULL) {
2635             conn = cba_connection_connect(pinfo, frame->consparent, frame->provparent, frame,
2636                 frame->qostype, frame->qosvalue, szProvItem, u32ConsID, u16RecordLength,
2637                 typedesc, typedesclen);
2638
2639             cba_connection_info(tvb, pinfo, sub_tree, conn);
2640         } else {
2641             conn = NULL;
2642         }
2643
2644         /* add to current call */
2645         if (call != NULL) {
2646             call->conn_count++;
2647             call->conns[u32Idx-1] = conn;
2648         }
2649
2650         /* update subtree header */
2651         proto_item_append_text(sub_item, "[%u]: ConsID=0x%x, ProvItem=\"%s\", TypeDesc=%s",
2652             u32Idx, u32ConsID, szProvItem,
2653             val_to_str(u16VarType2, dcom_variant_type_vals, "Unknown (0x%04x)") );
2654         proto_item_set_len(sub_item, offset - u32SubStart);
2655
2656
2657         u32Idx++;
2658     }
2659
2660     /* update column info now */
2661     col_append_fstr(pinfo->cinfo, COL_INFO, ": %s Cnt=%u PCRID=0x%x",
2662         (u8LastConnect) ? "LastOfCR" : "",
2663         u32Idx-1,
2664         u32ProvCRID);
2665
2666     return u32VariableOffset;
2667 }
2668
2669
2670 static int
2671 dissect_ICBAAccoServerSRT_Connect_resp(tvbuff_t *tvb, int offset,
2672     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2673 {
2674     guint32 u32Pointer;
2675     guint32 u32ArraySize;
2676     guint32 u32Idx = 1;
2677     guint32 u32SubStart;
2678     guint32 u32ProvID;
2679     guint32 u32HResult;
2680
2681     proto_item  *item;
2682
2683     server_connect_call_t *call = (server_connect_call_t *)di->call_data->private_data;
2684     cba_connection_t      *conn;
2685
2686
2687     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
2688
2689     if (call == NULL) {
2690         expert_add_info(pinfo, NULL, &ei_cba_acco_no_request_info);
2691     }
2692
2693     item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE);
2694     PROTO_ITEM_SET_GENERATED(item);
2695     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3));
2696
2697     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
2698                         &u32Pointer);
2699
2700     if (call && call->frame != NULL) {
2701         cba_frame_info(tvb, pinfo, tree, call->frame);
2702     }
2703
2704     if (u32Pointer) {
2705         offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
2706                             &u32ArraySize);
2707
2708         /* array of CONNECTOUTs */
2709         while(u32ArraySize--) {
2710             proto_item *sub_item;
2711             proto_tree *sub_tree;
2712
2713             sub_item = proto_tree_add_item(tree, hf_cba_connectout, tvb, offset, 8, ENC_NA);
2714             sub_tree = proto_item_add_subtree(sub_item, ett_cba_connectout);
2715             u32SubStart = offset;
2716
2717             offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
2718                                 hf_cba_acco_conn_prov_id, &u32ProvID);
2719
2720             offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
2721                                 &u32HResult, u32Idx);
2722
2723             /* put response data into the frame */
2724             if (call && u32Idx <= call->conn_count) {
2725                 conn = call->conns[u32Idx-1];
2726                 conn->provid  = u32ProvID;
2727                 conn->connret = u32HResult;
2728
2729                 cba_connection_info(tvb, pinfo, sub_tree, conn);
2730             }
2731
2732             proto_item_append_text(sub_item, "[%u]: ProvID=0x%x %s",
2733                 u32Idx, u32ProvID,
2734                 val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
2735             proto_item_set_len(sub_item, offset - u32SubStart);
2736
2737             u32Idx++;
2738         }
2739     }
2740
2741     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
2742                         &u32HResult);
2743
2744     /* this might be a global HRESULT */
2745     while(call && u32Idx <= call->conn_count) {
2746         conn = call->conns[u32Idx-1];
2747         conn->provid  = 0;
2748         conn->connret = u32HResult;
2749         u32Idx++;
2750     }
2751
2752     col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s",
2753         u32Idx-1,
2754         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
2755
2756     return offset;
2757 }
2758
2759
2760 static int
2761 dissect_Server_GetProvIDs_resp(tvbuff_t *tvb, int offset,
2762     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2763 {
2764     guint32 u32Count;
2765     guint32 u32Pointer;
2766     guint32 u32ArraySize;
2767     guint32 u32Idx;
2768     guint32 u32ProvID;
2769     guint32 u32HResult;
2770
2771
2772     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
2773
2774     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
2775                         hf_cba_acco_count, &u32Count);
2776
2777     if (u32Count) {
2778         col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u ProvID=", u32Count);
2779     } else {
2780         col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
2781     }
2782
2783     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
2784                         &u32Pointer);
2785     if (u32Pointer) {
2786         offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
2787                             &u32ArraySize);
2788
2789         u32Idx = 1;
2790         while (u32ArraySize--) {
2791             offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo,
2792                      tree, di, drep,
2793                      hf_cba_acco_conn_prov_id, &u32ProvID, u32Idx);
2794
2795             if (u32Idx == 1) {
2796                 col_append_fstr(pinfo->cinfo, COL_INFO, "0x%x", u32ProvID);
2797             } else if (u32Idx < 10) {
2798                 col_append_fstr(pinfo->cinfo, COL_INFO, ",0x%x", u32ProvID);
2799             } else if (u32Idx == 10) {
2800                 col_append_str(pinfo->cinfo, COL_INFO, ",...");
2801             }
2802
2803             u32Idx++;
2804         }
2805     }
2806
2807     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
2808                         &u32HResult);
2809
2810     col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
2811         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
2812
2813     return offset;
2814 }
2815
2816
2817 static int
2818 dissect_Server_GetProvConnections_rqst(tvbuff_t *tvb, int offset,
2819     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2820 {
2821     guint32 u32Count;
2822     guint32 u32ArraySize;
2823     guint32 u32Idx;
2824     guint32 u32ProvID;
2825
2826
2827     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
2828
2829     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
2830                         hf_cba_acco_count, &u32Count);
2831
2832     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
2833                         &u32ArraySize);
2834
2835     u32Idx = 1;
2836     while (u32ArraySize--) {
2837         offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep,
2838                         hf_cba_acco_conn_prov_id, &u32ProvID, u32Idx);
2839         u32Idx++;
2840     }
2841
2842     /* update column info now */
2843     col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
2844
2845     return offset;
2846 }
2847
2848
2849 static int
2850 dissect_Server_GetProvConnections_resp(tvbuff_t *tvb, int offset,
2851     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
2852 {
2853     guint32 u32Count;
2854     guint32 u32TmpCount;
2855     guint32 u32Pointer;
2856     guint32 u32VariableOffset;
2857     guint32 u32Idx;
2858     guint32 u32SubStart;
2859     gchar   szCons[1000] = { 0 };
2860     guint32 u32MaxConsLen = sizeof(szCons);
2861     gchar   szProvItem[1000] = { 0 };
2862     guint32 u32MaxProvItemLen = sizeof(szProvItem);
2863     guint32 u32ConsID;
2864     guint16 u16QoSType;
2865     guint16 u16QoSValue;
2866     guint8  u8State;
2867     guint32 u32HResult;
2868
2869
2870     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
2871
2872     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
2873                         &u32Pointer);
2874
2875     u32VariableOffset = offset;
2876
2877     if (u32Pointer) {
2878         offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
2879                             hf_cba_acco_count, &u32Count);
2880
2881         u32VariableOffset = offset + u32Count*28;
2882
2883         /* array fixed part (including pointers to variable part) */
2884         u32TmpCount = u32Count;
2885         u32Idx = 1;
2886         while (u32TmpCount--) {
2887             proto_item *sub_item;
2888             proto_tree *sub_tree;
2889
2890             sub_item = proto_tree_add_item(tree, hf_cba_getprovconnout, tvb, offset, 0, ENC_NA);
2891             sub_tree = proto_item_add_subtree(sub_item, ett_cba_getprovconnout);
2892             u32SubStart = offset;
2893
2894             /* wszConsumer */
2895             offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
2896                                 &u32Pointer);
2897             if (u32Pointer) {
2898                 u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
2899                                hf_cba_acco_conn_consumer, szCons, u32MaxConsLen);
2900             }
2901             /* wszProviderItem */
2902             offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
2903                                 &u32Pointer);
2904             if (u32Pointer) {
2905                 u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
2906                                hf_cba_acco_conn_provider_item, szProvItem, u32MaxProvItemLen);
2907             }
2908             /* dwConsID */
2909             offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
2910                                 hf_cba_acco_conn_cons_id, &u32ConsID);
2911
2912             /* Epsilon */
2913             offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
2914                                 &u32Pointer);
2915             if (u32Pointer) {
2916                 u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
2917                                 hf_cba_acco_conn_epsilon);
2918             }
2919
2920             /* QoS Type */
2921             offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
2922                                 hf_cba_acco_conn_qos_type, &u16QoSType);
2923             /* QoS Value */
2924             offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
2925                                 hf_cba_acco_conn_qos_value, &u16QoSValue);
2926             /* State */
2927             offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, sub_tree, di, drep,
2928                                 hf_cba_acco_conn_state, &u8State);
2929             /* PartialResult */
2930             offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
2931                                 &u32HResult, u32Idx);
2932
2933             proto_item_append_text(sub_item, "[%u]: %s",
2934                 u32Idx,
2935                 val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
2936             proto_item_set_len(sub_item, offset - u32SubStart);
2937
2938             u32Idx++;
2939         }
2940     }
2941
2942     u32VariableOffset = dissect_dcom_HRESULT(tvb, u32VariableOffset, pinfo, tree, di, drep,
2943                         &u32HResult);
2944
2945     col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
2946         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
2947
2948     return u32VariableOffset;
2949 }
2950
2951
2952 #define CBA_MRSH_VERSION_DCOM                   0x01
2953 #define CBA_MRSH_VERSION_SRT_WITH_CONSID        0x10
2954 #define CBA_MRSH_VERSION_SRT_WITHOUT_CONSID     0x11
2955
2956
2957 static int
2958 dissect_CBA_Connection_Data(tvbuff_t *tvb,
2959     packet_info *pinfo, proto_tree *tree, cba_ldev_t *cons_ldev, cba_frame_t *frame)
2960 {
2961     guint8      u8Version;
2962     guint8      u8Flags;
2963     guint16     u16CountFix;
2964     guint16     u16Count;
2965     guint32     u32ItemIdx;
2966     guint32     u32HoleIdx;
2967     proto_item *conn_data_item = NULL;
2968     proto_tree *conn_data_tree = NULL;
2969     guint16     u16Len;
2970     guint32     u32ID;
2971     guint8      u8QC;
2972     guint16     u16DataLen;
2973     guint16     u16HdrLen;
2974     int         offset         = 0;
2975     int         offset_hole;
2976     gboolean    qc_reported    = FALSE;
2977     int         qc_good        = 0;
2978     int         qc_uncertain   = 0;
2979     int         qc_bad         = 0;
2980     GList      *conns;
2981     int         item_offset;
2982     cba_connection_t *conn;
2983
2984
2985     /*** ALL data in this buffer is NOT aligned and always little endian ordered ***/
2986
2987     if (tree) {
2988         conn_data_item = proto_tree_add_item(tree, hf_cba_acco_cb_conn_data, tvb, offset, 0, ENC_NA);
2989         conn_data_tree = proto_item_add_subtree(conn_data_item, ett_ICBAAccoCallback_Buffer);
2990     }
2991
2992     /* add buffer header */
2993     u8Version = tvb_get_guint8 (tvb, offset);
2994     if (conn_data_tree) {
2995         proto_tree_add_item(conn_data_tree, hf_cba_acco_cb_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2996     }
2997     offset += 1;
2998
2999     u8Flags = tvb_get_guint8 (tvb, offset);
3000     if (conn_data_tree) {
3001         proto_tree_add_item(conn_data_tree, hf_cba_acco_cb_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3002     }
3003     offset += 1;
3004
3005     u16Count = tvb_get_letohs (tvb, offset);
3006     if (conn_data_tree) {
3007         proto_tree_add_item(conn_data_tree, hf_cba_acco_cb_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3008     }
3009     offset += 2;
3010     u16CountFix = u16Count;
3011
3012     /* show meta information */
3013     if (frame) {
3014         cba_frame_info(tvb, pinfo, conn_data_tree, frame);
3015     } else {
3016         if (cons_ldev && cons_ldev->name) {
3017             proto_item *item;
3018             item = proto_tree_add_string(conn_data_tree, hf_cba_acco_conn_consumer, tvb, offset, 0, cons_ldev->name);
3019             PROTO_ITEM_SET_GENERATED(item);
3020         }
3021     }
3022
3023     /* update column info now */
3024 #if 0
3025     col_append_fstr(pinfo->cinfo, COL_INFO, " Cnt=%u", u16Count);
3026 #endif
3027
3028     /* is this an OnDataChanged buffer format (version), we know? */
3029     if ((u8Version != CBA_MRSH_VERSION_DCOM) &&
3030         (u8Version != CBA_MRSH_VERSION_SRT_WITH_CONSID) &&
3031         (u8Version != CBA_MRSH_VERSION_SRT_WITHOUT_CONSID))
3032     {
3033         return offset;
3034     }
3035
3036     /* Timestamps are currently unused -> flags must be zero */
3037     if (u8Flags != 0) {
3038         return offset;
3039     }
3040
3041     u32ItemIdx = 1;
3042     u32HoleIdx = 1;
3043     while (u16Count--) {
3044         proto_item *sub_item;
3045         proto_tree *sub_tree;
3046         proto_item *item;
3047
3048         /* find next record header */
3049         u16Len = tvb_get_letohs (tvb, offset);
3050
3051         /* trapped inside an empty hole? -> try to find next record header */
3052         if (u16Len == 0 &&
3053             (u8Version == CBA_MRSH_VERSION_SRT_WITH_CONSID ||
3054             u8Version == CBA_MRSH_VERSION_SRT_WITHOUT_CONSID))
3055         {
3056             u32HoleIdx++;
3057             offset_hole = offset;
3058             /* length smaller or larger than possible -> must be a hole */
3059             while (u16Len == 0) {
3060                 offset++;
3061                 u16Len = tvb_get_letohs(tvb, offset);
3062                 /* this is a bit tricky here! we know: */
3063                 /* u16Len must be greater than 3 (min. size of header itself) */
3064                 /* u16Len must be a lot smaller than 0x300 (max. size of frame) */
3065                 /* -> if we found a length larger than 0x300, */
3066                 /* this must be actually the high byte, so do one more step */
3067                 if (u16Len > 0x300) {
3068                     u16Len = 0;
3069                 }
3070             }
3071             proto_tree_add_none_format(conn_data_tree, hf_cba_acco_cb_item_hole, tvb,
3072                 offset_hole, offset - offset_hole,
3073                 "Hole(--): -------------, offset=%2u, length=%2u",
3074                 offset_hole, offset - offset_hole);
3075         }
3076
3077         /* add callback-item subtree */
3078         sub_item = proto_tree_add_item(conn_data_tree, hf_cba_acco_cb_item, tvb, offset, 0, ENC_NA);
3079         sub_tree = proto_item_add_subtree(sub_item, ett_ICBAAccoCallback_Item);
3080
3081         item_offset = offset;
3082
3083         /* add item header fields */
3084         if (sub_tree) {
3085             proto_tree_add_item(sub_tree, hf_cba_acco_cb_item_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3086         }
3087         offset    += 2;
3088         u16HdrLen  = 2;
3089
3090         if (u8Version == CBA_MRSH_VERSION_DCOM ||
3091             u8Version == CBA_MRSH_VERSION_SRT_WITH_CONSID)
3092         {
3093             u32ID = tvb_get_letohl (tvb, offset);
3094             if (sub_tree) {
3095                 proto_tree_add_item(sub_tree, hf_cba_acco_conn_cons_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3096             }
3097             offset    += 4;
3098             u16HdrLen += 4;
3099         } else {
3100             u32ID = 0;
3101         }
3102
3103         u8QC = tvb_get_guint8 (tvb, offset);
3104         item = NULL;
3105         if (sub_tree) {
3106             item = proto_tree_add_item(sub_tree, hf_cba_acco_qc, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3107         }
3108         offset    += 1;
3109         u16HdrLen += 1;
3110
3111         if ( u8QC != 0x80 && /* GoodNonCascOk */
3112             u8QC != 0x1C && /* BadOutOfService (usually permanent, so don't report for every frame) */
3113             qc_reported == 0) {
3114             expert_add_info_format(pinfo, item, &ei_cba_acco_qc, "%s QC: %s",
3115                 u8Version == CBA_MRSH_VERSION_DCOM ? "DCOM" : "SRT",
3116                 val_to_str(u8QC, cba_acco_qc_vals, "Unknown (0x%02x)"));
3117             qc_reported = 0;
3118         }
3119
3120         switch(u8QC >> 6) {
3121         case(00):
3122             qc_bad++;
3123             break;
3124         case(01):
3125             qc_uncertain++;
3126             break;
3127         default:
3128             qc_good++;
3129         }
3130
3131         /* user data length is item length without headers */
3132         u16DataLen = u16Len - u16HdrLen;
3133
3134         /* append text to subtree header */
3135         if (u8Version == CBA_MRSH_VERSION_DCOM ||
3136             u8Version == CBA_MRSH_VERSION_SRT_WITH_CONSID)
3137         {
3138             proto_item_append_text(sub_item,
3139                 "[%2u]: ConsID=0x%08x, offset=%2u, length=%2u (user-length=%2u), QC=%s (0x%02x)",
3140                 u32ItemIdx, u32ID, offset - u16HdrLen, u16Len, u16DataLen,
3141                 val_to_str(u8QC, cba_acco_qc_vals, "Unknown (0x%02x)"), u8QC );
3142         } else {
3143             proto_item_append_text(sub_item,
3144                 "[%2u]: ConsID=-, offset=%2u, length=%2u (user-length=%2u), QC=%s (0x%02x)",
3145                 u32ItemIdx, offset - u16HdrLen, u16Len, u16DataLen,
3146                 val_to_str(u8QC, cba_acco_qc_vals, "Unknown (0x%02x)"), u8QC );
3147         }
3148         proto_item_set_len(sub_item, u16Len);
3149
3150         /* hexdump of user data */
3151         proto_tree_add_item(sub_tree, hf_cba_acco_cb_item_data, tvb, offset, u16DataLen, ENC_NA);
3152         offset += u16DataLen;
3153
3154         if (frame != NULL ) {
3155             /* find offset in SRT */
3156             /* XXX - expensive! */
3157             cba_frame_incoming_data(tvb, pinfo, sub_tree, frame);
3158             for(conns = frame->conns; conns != NULL; conns = g_list_next(conns)) {
3159                 conn = (cba_connection_t *)conns->data;
3160                 if (conn->frame_offset == item_offset) {
3161                     cba_connection_info(tvb, pinfo, sub_tree, conn);
3162                     break;
3163                 }
3164             }
3165         } else {
3166             /* find consID in ldev */
3167             /* XXX - expensive! */
3168             if (cons_ldev != NULL) {
3169                 for(conns = cons_ldev->consconns; conns != NULL; conns = g_list_next(conns)) {
3170                     conn = (cba_connection_t *)conns->data;
3171                     if (conn->consid == u32ID) {
3172                         cba_connection_info(tvb, pinfo, sub_tree, conn);
3173                         cba_connection_incoming_data(tvb, pinfo, sub_tree, conn);
3174                         break;
3175                     }
3176                 }
3177             }
3178         }
3179
3180         u32ItemIdx++;
3181     }
3182
3183     if (u8Version == 1) {
3184         proto_item_append_text(conn_data_item,
3185             ": Version=0x%x (DCOM), Flags=0x%x, Count=%u",
3186             u8Version, u8Flags, u16CountFix);
3187     } else {
3188         proto_item_append_text(conn_data_item,
3189             ": Version=0x%x (SRT), Flags=0x%x, Count=%u, Items=%u, Holes=%u",
3190             u8Version, u8Flags, u16CountFix, u32ItemIdx-1, u32HoleIdx-1);
3191     }
3192     proto_item_set_len(conn_data_item, offset);
3193
3194     col_append_fstr(pinfo->cinfo, COL_INFO, ", QC (G:%u,U:%u,B:%u)",
3195         qc_good, qc_uncertain, qc_bad);
3196
3197     return offset;
3198 }
3199
3200
3201 static gboolean
3202 dissect_CBA_Connection_Data_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3203     void *data)
3204 {
3205     guint8       u8Version;
3206     guint8       u8Flags;
3207     /* the tvb will NOT contain the frame_id here! */
3208     guint16      u16FrameID = GPOINTER_TO_UINT(data);
3209     cba_frame_t *frame;
3210
3211     /* frame id must be in valid range (cyclic Real-Time, class=1 or class=2) */
3212     if (u16FrameID < 0x8000 || u16FrameID >= 0xfb00) {
3213         return FALSE;
3214     }
3215
3216     u8Version = tvb_get_guint8 (tvb, 0);
3217     u8Flags   = tvb_get_guint8 (tvb, 1);
3218
3219     /* version and flags must be ok */
3220     if (u8Version != 0x11 || u8Flags != 0x00) {
3221         return FALSE;
3222     }
3223
3224         col_set_str(pinfo->cinfo, COL_PROTOCOL, "PN-CBA");
3225
3226     frame = cba_frame_find_by_cons(pinfo, (const guint8 *)pinfo->dl_dst.data, u16FrameID);
3227
3228     dissect_CBA_Connection_Data(tvb, pinfo, tree, frame ? frame->consparent : NULL, frame);
3229
3230     return TRUE;
3231 }
3232
3233
3234 static int
3235 dissect_ICBAAccoCallback_OnDataChanged_rqst(tvbuff_t *tvb, int offset,
3236     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
3237 {
3238     guint32      u32Length;
3239     guint32      u32ArraySize;
3240     tvbuff_t    *next_tvb;
3241     proto_item  *item;
3242     cba_ldev_t  *cons_ldev;
3243
3244
3245     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
3246
3247     /* get corresponding provider ldev */
3248     cons_ldev = cba_ldev_find(pinfo, &pinfo->net_dst, &di->call_data->object_uuid);
3249
3250     item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
3251     PROTO_ITEM_SET_GENERATED(item);
3252     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1));
3253
3254     /* length */
3255     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
3256                         hf_cba_acco_cb_length, &u32Length);
3257
3258     /* array size */
3259     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
3260                         &u32ArraySize);
3261
3262     /*** the data below is NOT ndr encoded (especially NOT aligned)!!! ***/
3263     /* dissect PROFINET component data (without header) */
3264     next_tvb = tvb_new_subset_remaining(tvb, offset);
3265
3266     offset += dissect_CBA_Connection_Data(next_tvb, pinfo, tree, cons_ldev, NULL /* frame */);
3267
3268     return offset;
3269 }
3270
3271
3272 static int
3273 dissect_ICBAAccoCallback_OnDataChanged_resp(tvbuff_t *tvb, int offset,
3274     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
3275 {
3276     guint32     u32HResult;
3277     proto_item *item;
3278
3279
3280     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
3281
3282     item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE);
3283     PROTO_ITEM_SET_GENERATED(item);
3284     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2));
3285
3286     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
3287                     &u32HResult);
3288
3289     col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
3290         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
3291
3292     return offset;
3293 }
3294
3295
3296 static int
3297 dissect_ICBAAccoCallback_Gnip_rqst(tvbuff_t *tvb, int offset,
3298     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
3299 {
3300     proto_item *item;
3301
3302
3303     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
3304
3305     item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, FALSE);
3306     PROTO_ITEM_SET_GENERATED(item);
3307     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(3));
3308
3309     return offset;
3310 }
3311
3312
3313 static int
3314 dissect_ICBAAccoCallback_Gnip_resp(tvbuff_t *tvb, int offset,
3315     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
3316 {
3317     guint32     u32HResult;
3318     proto_item *item;
3319
3320
3321     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
3322
3323     item = proto_tree_add_boolean (tree, hf_cba_acco_srt_call, tvb, offset, 0, TRUE);
3324     PROTO_ITEM_SET_GENERATED(item);
3325     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(4));
3326
3327     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
3328                     &u32HResult);
3329
3330     col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
3331         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
3332
3333     return offset;
3334 }
3335
3336
3337 static int
3338 dissect_ICBAAccoServer2_GetConnectionData_rqst(tvbuff_t *tvb, int offset,
3339     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
3340 {
3341     gchar         szStr[1000];
3342     guint32       u32MaxStr = sizeof(szStr);
3343     proto_item   *item;
3344     cba_ldev_t   *cons_ldev;
3345     cba_ldev_t  **call;
3346
3347
3348     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
3349
3350     item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, TRUE);
3351     PROTO_ITEM_SET_GENERATED(item);
3352     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(2));
3353
3354     offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep,
3355         hf_cba_acco_conn_consumer, szStr, u32MaxStr);
3356
3357     cons_ldev = cba_acco_add(pinfo, szStr);
3358
3359     /* link ldev to the call */
3360     if (cons_ldev != NULL) {
3361         call = (cba_ldev_t **)wmem_alloc(wmem_file_scope(), sizeof(cba_ldev_t *));
3362         *call = cons_ldev;
3363         di->call_data->private_data = call;
3364     }
3365
3366     /* update column info now */
3367     col_append_fstr(pinfo->cinfo, COL_INFO, " Consumer=\"%s\"", szStr);
3368
3369     return offset;
3370 }
3371
3372
3373 static int
3374 dissect_ICBAAccoServer2_GetConnectionData_resp(tvbuff_t *tvb, int offset,
3375     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
3376 {
3377     guint32       u32Length;
3378     guint32       u32ArraySize;
3379     tvbuff_t     *next_tvb;
3380     guint32       u32Pointer;
3381     guint32       u32HResult;
3382     proto_item   *item;
3383     cba_ldev_t  **call      = (cba_ldev_t **)di->call_data->private_data;
3384     cba_ldev_t   *cons_ldev = (call!=NULL) ? *call : NULL;
3385
3386
3387     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
3388
3389     if (cons_ldev == NULL) {
3390         expert_add_info(pinfo, NULL, &ei_cba_acco_no_request_info);
3391     }
3392
3393     item = proto_tree_add_boolean (tree, hf_cba_acco_dcom_call, tvb, offset, 0, FALSE);
3394     PROTO_ITEM_SET_GENERATED(item);
3395     p_add_proto_data(pinfo->pool, pinfo, proto_ICBAAccoMgt, 0, GUINT_TO_POINTER(1));
3396
3397     /* length */
3398     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
3399                         hf_cba_acco_cb_length, &u32Length);
3400
3401     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
3402                         &u32Pointer);
3403     if (u32Pointer) {
3404         /* array size */
3405         offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
3406                             &u32ArraySize);
3407
3408         /*** the data below is NOT ndr encoded (especially NOT aligned)!!! ***/
3409         /* dissect PROFINET component data (without header) */
3410         next_tvb = tvb_new_subset_remaining(tvb, offset);
3411
3412         offset += dissect_CBA_Connection_Data(next_tvb, pinfo, tree, (call != NULL) ? *call : NULL, NULL /* frame */);
3413
3414     }
3415
3416     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
3417                         &u32HResult);
3418
3419     /* update column info now */
3420     col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
3421             val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
3422
3423     return offset;
3424 }
3425
3426
3427 static int
3428 dissect_ICBAAccoMgt_AddConnections_rqst(tvbuff_t *tvb, int offset,
3429     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
3430 {
3431     gchar   szConsumer[1000] = { 0 };
3432     guint32 u32MaxConsLen = sizeof(szConsumer);
3433     guint16 u16QoSType;
3434     guint16 u16QoSValue;
3435     guint8  u8State;
3436     guint32 u32Count;
3437     guint32 u32ArraySize;
3438     guint32 u32Pointer;
3439     guint16 u16Persistence;
3440     gchar   szConsItem[1000] = { 0 };
3441     guint32 u32MaxConsItemLen = sizeof(szConsItem);
3442     gchar   szProvItem[1000] = { 0 };
3443     guint32 u32MaxProvItemLen = sizeof(szProvItem);
3444     guint32 u32VariableOffset;
3445     guint32 u32SubStart;
3446     guint32 u32Idx;
3447
3448
3449     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
3450
3451     offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep,
3452                         hf_cba_acco_conn_provider, szConsumer, u32MaxConsLen);
3453     offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
3454                         hf_cba_acco_conn_qos_type, &u16QoSType);
3455     offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
3456                         hf_cba_acco_conn_qos_value, &u16QoSValue);
3457     offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, tree, di, drep,
3458                         hf_cba_acco_conn_state, &u8State);
3459
3460     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
3461                         hf_cba_acco_count, &u32Count);
3462
3463     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
3464                         &u32ArraySize);
3465
3466     u32VariableOffset = offset + u32ArraySize * 20;
3467
3468     u32Idx = 1;
3469     while (u32ArraySize--) {
3470         proto_item *sub_item;
3471         proto_tree *sub_tree;
3472
3473         sub_item = proto_tree_add_item(tree, hf_cba_addconnectionin, tvb, offset, 0, ENC_NA);
3474         sub_tree = proto_item_add_subtree(sub_item, ett_cba_addconnectionin);
3475         u32SubStart = offset;
3476
3477         offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
3478                             &u32Pointer);
3479         if (u32Pointer) {
3480             u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
3481                             hf_cba_acco_conn_provider_item, szProvItem, u32MaxProvItemLen);
3482         }
3483         offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
3484                             &u32Pointer);
3485         if (u32Pointer) {
3486             u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
3487                             hf_cba_acco_conn_consumer_item, szConsItem, u32MaxConsItemLen);
3488         }
3489         offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
3490                             hf_cba_acco_conn_persist, &u16Persistence);
3491
3492         offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
3493                             &u32Pointer);
3494         if (u32Pointer) {
3495             u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
3496                             hf_cba_acco_conn_substitute);
3497         }
3498         offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
3499                             &u32Pointer);
3500         if (u32Pointer) {
3501             u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
3502                             hf_cba_acco_conn_epsilon);
3503         }
3504         proto_item_append_text(sub_item, "[%u]: ConsItem=\"%s\" ProvItem=\"%s\" %s Pers=%u",
3505             u32Idx, szConsItem, szProvItem,
3506             val_to_str(u16Persistence, cba_persist_vals, "Unknown (0x%02x)"), u16Persistence);
3507         proto_item_set_len(sub_item, offset - u32SubStart);
3508
3509         u32Idx++;
3510     }
3511
3512     /* update column info now */
3513     col_append_fstr(pinfo->cinfo, COL_INFO, ": Prov=\"%s\" State=%s Cnt=%u",
3514             szConsumer,
3515             val_to_str(u8State, cba_acco_conn_state_vals, "Unknown (0x%02x)"),
3516             u32Count);
3517
3518     return u32VariableOffset;
3519 }
3520
3521
3522 static int
3523 dissect_ICBAAccoMgt_AddConnections_resp(tvbuff_t *tvb, int offset,
3524     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
3525 {
3526     guint32 u32Pointer;
3527     guint32 u32ArraySize = 0;
3528     guint32 u32ConsID;
3529     guint16 u16ConnVersion;
3530     guint32 u32HResult = 0;
3531     guint32 u32Count = 0;
3532     guint32 u32Idx;
3533     guint32 u32SubStart;
3534
3535
3536     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
3537
3538     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
3539                         &u32Pointer);
3540
3541     if (u32Pointer) {
3542         offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
3543                             &u32ArraySize);
3544
3545         u32Count = u32ArraySize;
3546         u32Idx = 1;
3547         while (u32ArraySize--) {
3548             proto_item *sub_item;
3549             proto_tree *sub_tree;
3550
3551             sub_item = proto_tree_add_item(tree, hf_cba_addconnectionout, tvb, offset, 0, ENC_NA);
3552             sub_tree = proto_item_add_subtree(sub_item, ett_cba_addconnectionout);
3553             u32SubStart = offset;
3554
3555             offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
3556                             hf_cba_acco_conn_cons_id, &u32ConsID);
3557
3558             offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
3559                                 hf_cba_acco_conn_version, &u16ConnVersion);
3560
3561             offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
3562                                 &u32HResult, u32Idx);
3563
3564             proto_item_append_text(sub_item, "[%u]: ConsID=0x%x Version=%u %s",
3565                 u32Idx, u32ConsID, u16ConnVersion,
3566                 val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
3567             proto_item_set_len(sub_item, offset - u32SubStart);
3568
3569             u32Idx++;
3570         }
3571
3572         /* update column info now */
3573         col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
3574     }
3575
3576     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
3577                         &u32HResult);
3578
3579     /* update column info now */
3580     col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
3581         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
3582
3583     return offset;
3584 }
3585
3586
3587 static int
3588 dissect_ICBAAccoMgt_RemoveConnections_rqst(tvbuff_t *tvb, int offset,
3589     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
3590 {
3591     guint32 u32Count;
3592     guint32 u32ArraySize;
3593     guint32 u32Idx;
3594     guint32 u32ConsID;
3595
3596
3597     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
3598
3599     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
3600                         hf_cba_acco_count, &u32Count);
3601
3602     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
3603                         &u32ArraySize);
3604
3605     u32Idx = 1;
3606     while (u32ArraySize--) {
3607         offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep,
3608                         hf_cba_acco_conn_cons_id, &u32ConsID, u32Idx);
3609         u32Idx++;
3610     }
3611
3612     /* update column info now */
3613     col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
3614
3615     return offset;
3616 }
3617
3618
3619 static int
3620 dissect_ICBAAccoMgt_SetActivationState_rqst(tvbuff_t *tvb, int offset,
3621     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
3622 {
3623     guint8  u8State;
3624     guint32 u32Count;
3625     guint32 u32ArraySize;
3626     guint32 u32Idx;
3627     guint32 u32ConsID;
3628
3629
3630     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
3631
3632     offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, tree, di, drep,
3633                         hf_cba_acco_conn_state, &u8State);
3634
3635     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
3636                         hf_cba_acco_count, &u32Count);
3637
3638     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
3639                         &u32ArraySize);
3640
3641     u32Idx = 1;
3642     while (u32ArraySize--) {
3643         offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep,
3644                         hf_cba_acco_conn_cons_id, &u32ConsID, u32Idx);
3645         u32Idx++;
3646     }
3647
3648     /* update column info now */
3649     col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
3650
3651     return offset;
3652 }
3653
3654
3655 static int
3656 dissect_ICBAAccoMgt_GetInfo_resp(tvbuff_t *tvb, int offset,
3657     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
3658 {
3659     guint32 u32Max;
3660     guint32 u32CurCnt;
3661     guint32 u32HResult;
3662
3663
3664     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
3665
3666     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
3667                         hf_cba_acco_info_max, &u32Max);
3668
3669     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
3670                         hf_cba_acco_info_curr, &u32CurCnt);
3671
3672     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
3673                         &u32HResult);
3674
3675     col_append_fstr(pinfo->cinfo, COL_INFO, ": %u/%u -> %s",
3676         u32CurCnt, u32Max,
3677         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
3678
3679     return offset;
3680 }
3681
3682
3683 static int
3684 dissect_ICBAAccoMgt_GetIDs_resp(tvbuff_t *tvb, int offset,
3685     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
3686 {
3687     guint32 u32Count;
3688     guint32 u32Pointer;
3689     guint32 u32ArraySize;
3690     guint32 u32ConsID;
3691     guint8  u8State;
3692     guint16 u16Version;
3693     guint32 u32HResult;
3694     guint32 u32Idx;
3695     guint32 u32SubStart;
3696
3697
3698     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
3699
3700     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
3701                         hf_cba_acco_count, &u32Count);
3702
3703     if (u32Count) {
3704         col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u ConsID=", u32Count);
3705     } else {
3706         col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
3707     }
3708
3709     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
3710                         &u32Pointer);
3711     if (u32Pointer) {
3712         offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
3713                             &u32ArraySize);
3714
3715         u32Idx = 1;
3716         while (u32ArraySize--) {
3717             proto_item *sub_item;
3718             proto_tree *sub_tree;
3719
3720             sub_item = proto_tree_add_item(tree, hf_cba_getidout, tvb, offset, 0, ENC_NA);
3721             sub_tree = proto_item_add_subtree(sub_item, ett_cba_getidout);
3722             u32SubStart = offset;
3723
3724             offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
3725                                 hf_cba_acco_conn_cons_id, &u32ConsID);
3726             offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, sub_tree, di, drep,
3727                                 hf_cba_acco_conn_state, &u8State);
3728             offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
3729                                 hf_cba_acco_conn_version, &u16Version);
3730             offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
3731                                 &u32HResult, u32Idx);
3732
3733             proto_item_append_text(sub_item, "[%u]: ConsID=0x%x State=%s Version=%u %s",
3734                 u32Idx, u32ConsID,
3735                 val_to_str(u8State, cba_acco_conn_state_vals, "Unknown (0x%02x)"),
3736                 u16Version,
3737                 val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
3738             proto_item_set_len(sub_item, offset - u32SubStart);
3739
3740             if (u32Idx == 1) {
3741                 col_append_fstr(pinfo->cinfo, COL_INFO, "0x%x", u32ConsID);
3742             } else if (u32Idx < 10) {
3743                 col_append_fstr(pinfo->cinfo, COL_INFO, ",0x%x", u32ConsID);
3744             } else if (u32Idx == 10) {
3745                 col_append_str(pinfo->cinfo, COL_INFO, ",...");
3746             }
3747
3748             u32Idx++;
3749         }
3750     }
3751
3752     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
3753                         &u32HResult);
3754
3755     col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
3756         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
3757
3758     return offset;
3759 }
3760
3761
3762 static int
3763 dissect_ICBAAccoMgt2_GetConsIDs_resp(tvbuff_t *tvb, int offset,
3764     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
3765 {
3766     guint32 u32Count;
3767     guint32 u32Pointer;
3768     guint32 u32ArraySize;
3769     guint32 u32Idx;
3770     guint32 u32ConsID;
3771     guint32 u32HResult;
3772
3773
3774     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
3775
3776     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
3777                         hf_cba_acco_count, &u32Count);
3778
3779     if (u32Count) {
3780         col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u ConsID=", u32Count);
3781     } else {
3782         col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
3783     }
3784
3785     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
3786                         &u32Pointer);
3787     if (u32Pointer) {
3788         offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
3789                             &u32ArraySize);
3790
3791         u32Idx = 1;
3792         while (u32ArraySize--) {
3793             offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo,
3794                      tree, di, drep,
3795                      hf_cba_acco_conn_cons_id, &u32ConsID, u32Idx);
3796
3797             if (u32Idx == 1) {
3798                 col_append_fstr(pinfo->cinfo, COL_INFO, "0x%x", u32ConsID);
3799             } else if (u32Idx < 10) {
3800                 col_append_fstr(pinfo->cinfo, COL_INFO, ",0x%x", u32ConsID);
3801             } else if (u32Idx == 10) {
3802                 col_append_str(pinfo->cinfo, COL_INFO, ",...");
3803             }
3804
3805             u32Idx++;
3806         }
3807     }
3808
3809     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
3810                         &u32HResult);
3811
3812     col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
3813         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
3814
3815     return offset;
3816 }
3817
3818
3819 static int
3820 dissect_ICBAAccoMgt2_GetConsConnections_resp(tvbuff_t *tvb, int offset,
3821     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
3822 {
3823     guint32 u32Count;
3824     guint32 u32TmpCount;
3825     guint32 u32Pointer;
3826     guint32 u32HResult;
3827
3828     guint16 u16QoSType;
3829     guint16 u16QoSValue;
3830     guint8  u8State;
3831     guint16 u16Persistence;
3832     guint32 u32SubStart;
3833     guint32 u32Idx;
3834     guint32 u32VariableOffset;
3835     gchar   szProv[1000] = { 0 };
3836     guint32 u32MaxProvLen = sizeof(szProv);
3837     gchar   szProvItem[1000] = { 0 };
3838     guint32 u32MaxProvItemLen = sizeof(szProvItem);
3839     gchar   szConsItem[1000] = { 0 };
3840     guint32 u32MaxConsItemLen = sizeof(szConsItem);
3841
3842
3843     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
3844
3845     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
3846                         &u32Pointer);
3847
3848     u32VariableOffset = offset;
3849
3850     if (u32Pointer) {
3851         offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
3852                             hf_cba_acco_count, &u32Count);
3853
3854         u32VariableOffset = offset + u32Count*32;
3855
3856         /* array fixed part (including pointers to variable part) */
3857         u32TmpCount = u32Count;
3858         u32Idx = 1;
3859         while (u32TmpCount--) {
3860             proto_item *sub_item;
3861             proto_tree *sub_tree;
3862
3863             sub_item    = proto_tree_add_item(tree, hf_cba_getconsconnout, tvb, offset, 0, ENC_NA);
3864             sub_tree    = proto_item_add_subtree(sub_item, ett_cba_getconnectionout);
3865             u32SubStart = offset;
3866
3867             offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
3868                                 &u32Pointer);
3869             if (u32Pointer) {
3870                 u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
3871                                hf_cba_acco_conn_provider, szProv, u32MaxProvLen);
3872             }
3873             offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
3874                                 &u32Pointer);
3875             if (u32Pointer) {
3876                 u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
3877                                hf_cba_acco_conn_provider_item, szProvItem, u32MaxProvItemLen);
3878             }
3879             offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
3880                                 &u32Pointer);
3881             if (u32Pointer) {
3882                 u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
3883                                 hf_cba_acco_conn_consumer_item, szConsItem, u32MaxConsItemLen);
3884             }
3885             offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
3886                                 &u32Pointer);
3887             if (u32Pointer) {
3888                 u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
3889                                 hf_cba_acco_conn_substitute);
3890             }
3891             offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
3892                                 &u32Pointer);
3893             if (u32Pointer) {
3894                 u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
3895                                 hf_cba_acco_conn_epsilon);
3896             }
3897
3898             offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
3899                                 hf_cba_acco_conn_qos_type, &u16QoSType);
3900             offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
3901                                 hf_cba_acco_conn_qos_value, &u16QoSValue);
3902             offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, sub_tree, di, drep,
3903                                 hf_cba_acco_conn_state, &u8State);
3904             offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
3905                                 hf_cba_acco_conn_persist, &u16Persistence);
3906             offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
3907                                 &u32HResult, u32Idx);
3908
3909             proto_item_append_text(sub_item, "[%u]: %s",
3910                 u32Idx,
3911                 val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
3912             proto_item_set_len(sub_item, offset - u32SubStart);
3913
3914             u32Idx++;
3915         }
3916     }
3917
3918     u32VariableOffset = dissect_dcom_HRESULT(tvb, u32VariableOffset, pinfo, tree, di, drep,
3919                         &u32HResult);
3920
3921     col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
3922         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
3923
3924     return u32VariableOffset;
3925 }
3926
3927
3928 static int
3929 dissect_ICBAAccoMgt2_DiagConsConnections_resp(tvbuff_t *tvb, int offset,
3930     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
3931 {
3932     guint32 u32Count;
3933     guint32 u32TmpCount;
3934     guint32 u32Pointer;
3935     guint32 u32HResult;
3936     guint8  u8State;
3937     guint16 u16Persistence;
3938     guint16 u16ConnVersion;
3939     guint32 u32SubStart;
3940     guint32 u32Idx;
3941     guint32 u32VariableOffset;
3942     guint32 u32ConnErrorState;
3943
3944
3945     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
3946
3947     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
3948                         &u32Pointer);
3949
3950     u32VariableOffset = offset;
3951
3952     if (u32Pointer) {
3953         offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
3954                             hf_cba_acco_count, &u32Count);
3955
3956         u32VariableOffset = offset + u32Count*16;
3957
3958         /* array fixed part (including pointers to variable part) */
3959         u32TmpCount = u32Count;
3960         u32Idx = 1;
3961         while (u32TmpCount--) {
3962             proto_item *sub_item;
3963             proto_tree *sub_tree;
3964             proto_item *state_item;
3965
3966             sub_item    = proto_tree_add_item(tree, hf_cba_diagconsconnout, tvb, offset, 0, ENC_NA);
3967             sub_tree    = proto_item_add_subtree(sub_item, ett_cba_getconnectionout);
3968             u32SubStart = offset;
3969
3970             offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, sub_tree, di, drep,
3971                                 hf_cba_acco_conn_state, &u8State);
3972             offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
3973                                 hf_cba_acco_conn_persist, &u16Persistence);
3974             offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
3975                                 hf_cba_acco_conn_version, &u16ConnVersion);
3976                         /* connection state */
3977 #if 0
3978             offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
3979                                 hf_cba_acco_conn_error_state, &u32ConnErrorState);
3980 #endif
3981             offset = dissect_dcom_HRESULT_item(tvb, offset, pinfo, sub_tree, di, drep,
3982                                  &u32ConnErrorState, hf_cba_acco_conn_error_state, &state_item);
3983             proto_item_set_text(state_item, "ConnErrorState: %s (0x%x)",
3984                                  val_to_str(u32ConnErrorState, dcom_hresult_vals, "Unknown (0x%08x)"),
3985                                  u32ConnErrorState);
3986
3987             offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
3988                                  &u32HResult, u32Idx);
3989
3990             proto_item_append_text(sub_item, "[%u]: %s",
3991               u32Idx,
3992               val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
3993             proto_item_set_len(sub_item, offset - u32SubStart);
3994
3995             u32Idx++;
3996         }
3997     }
3998
3999     u32VariableOffset = dissect_dcom_HRESULT(tvb, u32VariableOffset, pinfo, tree, di, drep,
4000                         &u32HResult);
4001
4002     col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
4003         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
4004
4005     return u32VariableOffset;
4006 }
4007
4008
4009 static int
4010 dissect_ICBAAccoMgt_GetConnections_rqst(tvbuff_t *tvb, int offset,
4011     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4012 {
4013     guint32 u32ConsID;
4014     guint32 u32Count;
4015     guint32 u32ArraySize;
4016     guint32 u32Idx;
4017
4018
4019     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
4020
4021     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
4022                         hf_cba_acco_count, &u32Count);
4023
4024     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
4025                         &u32ArraySize);
4026
4027     u32Idx = 1;
4028     while (u32ArraySize--){
4029         offset = dissect_dcom_indexed_DWORD(tvb, offset, pinfo, tree, di, drep,
4030                         hf_cba_acco_conn_cons_id, &u32ConsID, u32Idx);
4031         u32Idx++;
4032     }
4033
4034     return offset;
4035 }
4036
4037
4038 static int
4039 dissect_ICBAAccoMgt_GetConnections_resp(tvbuff_t *tvb, int offset,
4040     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4041 {
4042     guint32 u32Count;
4043     guint32 u32TmpCount;
4044     guint32 u32Pointer;
4045     guint32 u32HResult;
4046
4047     guint16 u16QoSType;
4048     guint16 u16QoSValue;
4049     guint8  u8State;
4050     guint16 u16Persistence;
4051     guint16 u16ConnVersion;
4052     guint32 u32SubStart;
4053     guint32 u32Idx;
4054     guint32 u32VariableOffset;
4055     gchar   szProv[1000] = { 0 };
4056     guint32 u32MaxProvLen = sizeof(szProv);
4057     gchar   szProvItem[1000] = { 0 };
4058     guint32 u32MaxProvItemLen = sizeof(szProvItem);
4059     gchar   szConsItem[1000] = { 0 };
4060     guint32 u32MaxConsItemLen = sizeof(szConsItem);
4061
4062
4063     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
4064
4065     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
4066                         &u32Pointer);
4067
4068     u32VariableOffset = offset;
4069
4070     if (u32Pointer) {
4071         offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
4072                             hf_cba_acco_count, &u32Count);
4073
4074         u32VariableOffset = offset + u32Count*36;
4075
4076         /* array fixed part (including pointers to variable part) */
4077         u32TmpCount = u32Count;
4078         u32Idx = 1;
4079         while (u32TmpCount--) {
4080             proto_item *sub_item;
4081             proto_tree *sub_tree;
4082
4083             sub_item = proto_tree_add_item(tree, hf_cba_getconnectionout, tvb, offset, 0, ENC_NA);
4084             sub_tree = proto_item_add_subtree(sub_item, ett_cba_getconnectionout);
4085             u32SubStart = offset;
4086
4087             offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
4088                                 &u32Pointer);
4089             if (u32Pointer) {
4090                 u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
4091                                hf_cba_acco_conn_provider, szProv, u32MaxProvLen);
4092             }
4093             offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
4094                                 &u32Pointer);
4095             if (u32Pointer) {
4096                 u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
4097                                hf_cba_acco_conn_provider_item, szProvItem, u32MaxProvItemLen);
4098             }
4099             offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
4100                                 &u32Pointer);
4101             if (u32Pointer) {
4102                 u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
4103                                 hf_cba_acco_conn_consumer_item, szConsItem, u32MaxConsItemLen);
4104             }
4105             offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
4106                                 &u32Pointer);
4107             if (u32Pointer) {
4108                 u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
4109                                 hf_cba_acco_conn_substitute);
4110             }
4111             offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
4112                                 &u32Pointer);
4113             if (u32Pointer) {
4114                 u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
4115                                 hf_cba_acco_conn_epsilon);
4116             }
4117
4118             offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
4119                                 hf_cba_acco_conn_qos_type, &u16QoSType);
4120             offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
4121                                 hf_cba_acco_conn_qos_value, &u16QoSValue);
4122             offset = dissect_dcom_BOOLEAN(tvb, offset, pinfo, sub_tree, di, drep,
4123                                 hf_cba_acco_conn_state, &u8State);
4124             offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
4125                                 hf_cba_acco_conn_persist, &u16Persistence);
4126             offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
4127                                 hf_cba_acco_conn_version, &u16ConnVersion);
4128             offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
4129                                 &u32HResult, u32Idx);
4130
4131             proto_item_append_text(sub_item, "[%u]: %s",
4132                 u32Idx,
4133                 val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
4134             proto_item_set_len(sub_item, offset - u32SubStart);
4135
4136             u32Idx++;
4137         }
4138     }
4139
4140     u32VariableOffset = dissect_dcom_HRESULT(tvb, u32VariableOffset, pinfo, tree, di, drep,
4141                         &u32HResult);
4142
4143     col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s",
4144         val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
4145
4146     return u32VariableOffset;
4147 }
4148
4149
4150 static int
4151 dissect_ICBAAccoMgt_ReviseQoS_rqst(tvbuff_t *tvb, int offset,
4152     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4153 {
4154     guint16 u16QoSType;
4155     guint16 u16QoSValue;
4156     gchar   szStr[1000];
4157     guint32 u32MaxStr = sizeof(szStr);
4158
4159
4160     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
4161
4162     offset = dissect_dcom_LPWSTR(tvb, offset, pinfo, tree, di, drep,
4163                         hf_cba_acco_rtauto, szStr, u32MaxStr);
4164
4165     offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
4166                         hf_cba_acco_conn_qos_type, &u16QoSType);
4167
4168     offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
4169                         hf_cba_acco_conn_qos_value, &u16QoSValue);
4170
4171     col_append_fstr(pinfo->cinfo, COL_INFO, ": RTAuto=\"%s\" QoSType=%s QoSValue=%u",
4172             szStr,
4173             val_to_str(u16QoSType, cba_qos_type_vals, "Unknown (0x%04x)"),
4174             u16QoSValue);
4175
4176     return offset;
4177 }
4178
4179
4180 static int
4181 dissect_ICBAAccoMgt_ReviseQoS_resp(tvbuff_t *tvb, int offset,
4182     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4183 {
4184     guint16 u16QoSValue;
4185     guint32 u32HResult;
4186
4187
4188     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
4189
4190     offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
4191                         hf_cba_acco_conn_qos_value, &u16QoSValue);
4192
4193     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
4194                         &u32HResult);
4195
4196     col_append_fstr(pinfo->cinfo, COL_INFO, ": %u -> %s",
4197       u16QoSValue,
4198       val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
4199
4200     return offset;
4201 }
4202
4203
4204 static int
4205 dissect_ICBAAccoMgt_get_PingFactor_resp(tvbuff_t *tvb, int offset,
4206     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4207 {
4208     guint16 u16PF;
4209     guint32 u32HResult;
4210
4211
4212     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
4213
4214     offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
4215                         hf_cba_acco_ping_factor, &u16PF);
4216
4217     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
4218                         &u32HResult);
4219
4220     col_append_fstr(pinfo->cinfo, COL_INFO, ": %u -> %s",
4221       u16PF,
4222       val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
4223
4224     return offset;
4225 }
4226
4227
4228 static int
4229 dissect_ICBAAccoMgt_put_PingFactor_rqst(tvbuff_t *tvb, int offset,
4230     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4231 {
4232     guint16 u16PF;
4233
4234
4235     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
4236
4237     offset = dissect_dcom_WORD(tvb, offset, pinfo, tree, di, drep,
4238                         hf_cba_acco_ping_factor, &u16PF);
4239
4240     col_append_fstr(pinfo->cinfo, COL_INFO, ": %u", u16PF);
4241
4242     return offset;
4243 }
4244
4245
4246
4247 static int
4248 dissect_ICBAAccoMgt_get_CDBCookie_resp(tvbuff_t *tvb, int offset,
4249     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4250 {
4251     guint32 u32Cookie;
4252     guint32 u32HResult;
4253
4254
4255     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
4256
4257     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
4258                         hf_cba_acco_cdb_cookie, &u32Cookie);
4259
4260     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
4261                         &u32HResult);
4262
4263     col_append_fstr(pinfo->cinfo, COL_INFO, ": CDBCookie=0x%x -> %s",
4264             u32Cookie,
4265             val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
4266
4267     return offset;
4268 }
4269
4270
4271 static int
4272 dissect_ICBAAccoMgt_GetDiagnosis_rqst(tvbuff_t *tvb, int offset,
4273     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4274 {
4275     guint32 u32Request;
4276     guint32 u32InLength;
4277     guint32 u32ArraySize;
4278
4279
4280     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
4281
4282     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
4283                         hf_cba_acco_diag_req, &u32Request);
4284
4285     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
4286                         hf_cba_acco_diag_in_length, &u32InLength);
4287
4288     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
4289                         &u32ArraySize);
4290
4291     if (u32ArraySize != 0) {
4292         proto_tree_add_item(tree, hf_cba_acco_diag_data, tvb, offset, u32InLength, ENC_NA);
4293     }
4294
4295     col_append_fstr(pinfo->cinfo, COL_INFO, ": %s: %u bytes",
4296             val_to_str(u32Request, cba_acco_diag_req_vals, "Unknown request (0x%08x)"),
4297             u32InLength);
4298
4299     return offset;
4300 }
4301
4302
4303 static int
4304 dissect_ICBAAccoMgt_GetDiagnosis_resp(tvbuff_t *tvb, int offset,
4305     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4306 {
4307     guint32 u32OutLength;
4308
4309
4310     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
4311
4312     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
4313                         hf_cba_acco_diag_out_length, &u32OutLength);
4314
4315     if (u32OutLength != 0) {
4316         proto_tree_add_item(tree, hf_cba_acco_diag_data, tvb, offset, u32OutLength, ENC_NA);
4317     }
4318
4319     col_append_fstr(pinfo->cinfo, COL_INFO, ": %u bytes",
4320             u32OutLength);
4321
4322     return offset;
4323 }
4324
4325
4326 static int
4327 dissect_ICBAAccoSync_ReadItems_rqst(tvbuff_t *tvb, int offset,
4328     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4329 {
4330     guint32 u32Count;
4331     gchar   szStr[1000];
4332     guint32 u32MaxStr = sizeof(szStr);
4333     guint32 u32Pointer;
4334     guint32 u32ArraySize;
4335     guint32 u32VariableOffset;
4336     guint32 u32Idx;
4337
4338
4339     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
4340
4341     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
4342                         hf_cba_acco_count, &u32Count);
4343
4344     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
4345                         &u32ArraySize);
4346
4347     u32VariableOffset = offset + u32ArraySize*4;
4348
4349     u32Idx = 1;
4350     while (u32ArraySize--) {
4351         offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
4352                             &u32Pointer);
4353         if (u32Pointer) {
4354             u32VariableOffset = dissect_dcom_indexed_LPWSTR(tvb, u32VariableOffset, pinfo, tree, di, drep,
4355                             hf_cba_acco_item, szStr, u32MaxStr, u32Idx);
4356         }
4357
4358         u32Idx++;
4359     }
4360
4361     col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
4362
4363     return u32VariableOffset;
4364 }
4365
4366
4367
4368
4369 static int
4370 dissect_ICBAAccoSync_ReadItems_resp(tvbuff_t *tvb, int offset,
4371     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4372 {
4373     guint32 u32Pointer;
4374     guint16 u16QC;
4375     guint32 u32ArraySize = 0;
4376     guint32 u32HResult;
4377     guint32 u32Idx;
4378     guint32 u32SubStart;
4379     guint32 u32VariableOffset;
4380     guint32 u32Tmp;
4381
4382
4383     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
4384
4385     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, di, drep,
4386                         &u32Pointer);
4387     u32VariableOffset = offset;
4388
4389     if (u32Pointer) {
4390         offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
4391                             &u32ArraySize);
4392
4393         u32VariableOffset = offset + u32ArraySize * 20;
4394         u32Idx = 1;
4395         u32Tmp = u32ArraySize;
4396         while(u32Tmp--) {
4397             proto_item *sub_item;
4398             proto_tree *sub_tree;
4399
4400             sub_item = proto_tree_add_item(tree, hf_cba_readitemout, tvb, offset, 0, ENC_NA);
4401             sub_tree = proto_item_add_subtree(sub_item, ett_cba_readitemout);
4402             u32SubStart = offset;
4403
4404             offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
4405                                 &u32Pointer);
4406             if (u32Pointer) {
4407                 u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep, hf_cba_acco_data);
4408             }
4409
4410             offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
4411                                 hf_cba_acco_qc, &u16QC);
4412             offset = dissect_dcom_FILETIME(tvb, offset, pinfo, sub_tree, di, drep,
4413                                 hf_cba_acco_time_stamp, NULL);
4414
4415             offset = dissect_dcom_indexed_HRESULT(tvb, offset, pinfo, sub_tree, di, drep,
4416                                 &u32HResult, u32Idx);
4417
4418             proto_item_append_text(sub_item, "[%u]: QC=%s (0x%02x) %s",
4419                 u32Idx,
4420                 val_to_str(u16QC, cba_acco_qc_vals, "Unknown"),
4421                 u16QC,
4422                 val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
4423             proto_item_set_len(sub_item, offset - u32SubStart);
4424
4425             u32Idx++;
4426         }
4427     }
4428
4429     u32VariableOffset = dissect_dcom_HRESULT(tvb, u32VariableOffset, pinfo, tree, di, drep,
4430                        &u32HResult);
4431
4432     col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u -> %s",
4433       u32ArraySize,
4434       val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") );
4435
4436     return u32VariableOffset;
4437 }
4438
4439
4440 static int
4441 dissect_ICBAAccoSync_WriteItems_rqst(tvbuff_t *tvb, int offset,
4442     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4443 {
4444     guint32 u32Count;
4445     guint32 u32ArraySize;
4446     gchar   szStr[1000];
4447     guint32 u32MaxStr = sizeof(szStr);
4448     guint32 u32Pointer;
4449     guint32 u32VariableOffset;
4450     guint32 u32SubStart;
4451     guint32 u32Idx;
4452
4453
4454     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
4455
4456     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
4457                         hf_cba_acco_count, &u32Count);
4458
4459     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
4460                         &u32ArraySize);
4461
4462     u32VariableOffset = offset + u32ArraySize * 8;
4463     u32Idx = 1;
4464     while(u32ArraySize--) {
4465         proto_item *sub_item;
4466         proto_tree *sub_tree;
4467
4468         sub_item = proto_tree_add_item(tree, hf_cba_writeitemin, tvb, offset, 0, ENC_NA);
4469         sub_tree = proto_item_add_subtree(sub_item, ett_cba_writeitemin);
4470         u32SubStart = offset;
4471
4472         offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
4473                             &u32Pointer);
4474         if (u32Pointer) {
4475             u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
4476                             hf_cba_acco_item, szStr, u32MaxStr);
4477         }
4478         offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
4479                             &u32Pointer);
4480         if (u32Pointer) {
4481             u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
4482                             hf_cba_acco_data);
4483         }
4484
4485         proto_item_append_text(sub_item, "[%u]: Item=\"%s\"", u32Idx, szStr);
4486         proto_item_set_len(sub_item, offset - u32SubStart);
4487
4488         u32Idx++;
4489     }
4490
4491     col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
4492
4493     return u32VariableOffset;
4494 }
4495
4496
4497
4498 static int
4499 dissect_ICBAAccoSync_WriteItemsQCD_rqst(tvbuff_t *tvb, int offset,
4500     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
4501 {
4502     guint32 u32Count;
4503     guint32 u32ArraySize;
4504     gchar   szStr[1000];
4505     guint32 u32MaxStr = sizeof(szStr);
4506     guint32 u32Pointer;
4507     guint32 u32VariableOffset;
4508     guint32 u32SubStart;
4509     guint32 u32Idx;
4510     guint16 u16QC;
4511
4512     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
4513
4514     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
4515                         hf_cba_acco_count, &u32Count);
4516
4517     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, di, drep,
4518                         &u32ArraySize);
4519
4520     u32VariableOffset = offset + u32ArraySize * 20;
4521     u32Idx = 1;
4522     while(u32ArraySize--) {
4523         proto_item *sub_item;
4524         proto_tree *sub_tree;
4525
4526         sub_item = proto_tree_add_item(tree, hf_cba_writeitemin, tvb, offset, 0, ENC_NA);
4527         sub_tree = proto_item_add_subtree(sub_item, ett_cba_writeitemin);
4528         u32SubStart = offset;
4529
4530         offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
4531                             &u32Pointer);
4532         if (u32Pointer) {
4533         u32VariableOffset = dissect_dcom_LPWSTR(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
4534                             hf_cba_acco_item, szStr, u32MaxStr);
4535         }
4536
4537         offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
4538                             &u32Pointer);
4539         if (u32Pointer) {
4540         u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, sub_tree, di, drep,
4541                             hf_cba_acco_data);
4542         }
4543
4544         offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
4545                             hf_cba_acco_qc, &u16QC);
4546
4547         offset = dissect_dcom_FILETIME(tvb, offset, pinfo, sub_tree, di, drep,
4548                             hf_cba_acco_time_stamp, NULL);
4549
4550         proto_item_append_text(sub_item, "[%u]: Item=\"%s\" QC=%s (0x%02x)",
4551             u32Idx, szStr,
4552             val_to_str(u16QC, cba_acco_qc_vals, "Unknown"), u16QC);
4553
4554         proto_item_set_len(sub_item, offset - u32SubStart);
4555         u32Idx++;
4556     }
4557
4558     col_append_fstr(pinfo->cinfo, COL_INFO, ": Cnt=%u", u32Count);
4559
4560     return u32VariableOffset;
4561 }
4562
4563
4564 /* sub dissector table of ICBAAccoMgt / ICBAAccoMgt2 interface */
4565 static dcerpc_sub_dissector ICBAAccoMgt_dissectors[] = {
4566     { 0, "QueryInterface",      NULL, NULL },
4567     { 1, "AddRef",              NULL, NULL },
4568     { 2, "Release",             NULL, NULL },
4569
4570     { 3, "AddConnections",      dissect_ICBAAccoMgt_AddConnections_rqst, dissect_ICBAAccoMgt_AddConnections_resp },
4571     { 4, "RemoveConnections",   dissect_ICBAAccoMgt_RemoveConnections_rqst, dissect_HResultArray_resp },
4572     { 5, "ClearConnections",    dissect_dcom_simple_rqst, dissect_dcom_simple_resp },
4573     { 6, "SetActivationState",  dissect_ICBAAccoMgt_SetActivationState_rqst, dissect_HResultArray_resp },
4574     { 7, "GetInfo",             dissect_dcom_simple_rqst, dissect_ICBAAccoMgt_GetInfo_resp },
4575     { 8, "GetIDs",              dissect_dcom_simple_rqst, dissect_ICBAAccoMgt_GetIDs_resp },
4576     { 9, "GetConnections",      dissect_ICBAAccoMgt_GetConnections_rqst, dissect_ICBAAccoMgt_GetConnections_resp },
4577     {10, "ReviseQoS",           dissect_ICBAAccoMgt_ReviseQoS_rqst, dissect_ICBAAccoMgt_ReviseQoS_resp },
4578     {11, "get_PingFactor",      dissect_dcom_simple_rqst, dissect_ICBAAccoMgt_get_PingFactor_resp },
4579     {12, "put_PingFactor",      dissect_ICBAAccoMgt_put_PingFactor_rqst, dissect_dcom_simple_resp },
4580     {13, "get_CDBCookie",       dissect_dcom_simple_rqst, dissect_ICBAAccoMgt_get_CDBCookie_resp },
4581     /* stage 2 */
4582     {14, "GetConsIDs",          dissect_dcom_simple_rqst, dissect_ICBAAccoMgt2_GetConsIDs_resp },
4583     {15, "GetConsConnections",  dissect_ICBAAccoMgt_GetConnections_rqst, dissect_ICBAAccoMgt2_GetConsConnections_resp },
4584     {16, "DiagConsConnections", dissect_ICBAAccoMgt_GetConnections_rqst, dissect_ICBAAccoMgt2_DiagConsConnections_resp },
4585     {17, "GetProvIDs",          dissect_dcom_simple_rqst, dissect_Server_GetProvIDs_resp },
4586     {18, "GetProvConnections",  dissect_Server_GetProvConnections_rqst, dissect_Server_GetProvConnections_resp },
4587     {19, "GetDiagnosis",        dissect_ICBAAccoMgt_GetDiagnosis_rqst, dissect_ICBAAccoMgt_GetDiagnosis_resp },
4588     { 0, NULL, NULL, NULL },
4589 };
4590
4591
4592 /* sub dissector table of ICBAAccoCallback interface */
4593 static dcerpc_sub_dissector ICBAAccoCallback_dissectors[] = {
4594     { 0, "QueryInterface", NULL, NULL },
4595     { 1, "AddRef",         NULL, NULL },
4596     { 2, "Release",        NULL, NULL },
4597
4598     { 3, "OnDataChanged",  dissect_ICBAAccoCallback_OnDataChanged_rqst, dissect_ICBAAccoCallback_OnDataChanged_resp },
4599     /* stage 2 */
4600     { 4, "Gnip",           dissect_ICBAAccoCallback_Gnip_rqst, dissect_ICBAAccoCallback_Gnip_resp },
4601     { 0, NULL, NULL, NULL },
4602 };
4603
4604
4605 /* sub dissector table of ICBAAccoServer interface */
4606 static dcerpc_sub_dissector ICBAAccoServer_dissectors[] = {
4607     { 0, "QueryInterface",    NULL, NULL },
4608     { 1, "AddRef",            NULL, NULL },
4609     { 2, "Release",           NULL, NULL },
4610
4611     { 3, "Connect",           dissect_ICBAAccoServer_Connect_rqst, dissect_ICBAAccoServer_Connect_resp },
4612     { 4, "Disconnect",        dissect_ICBAAccoServer_Disconnect_rqst, dissect_ICBAAccoServer_Disconnect_resp },
4613     { 5, "DisconnectMe",      dissect_ICBAAccoServer_DisconnectMe_rqst, dissect_ICBAAccoServer_DisconnectMe_resp },
4614     { 6, "SetActivation",     dissect_ICBAAccoServer_SetActivation_rqst, dissect_ICBAAccoServer_SetActivation_resp },
4615     { 7, "Ping",              dissect_ICBAAccoServer_Ping_rqst, dissect_ICBAAccoServer_Ping_resp },
4616     /* stage 2 */
4617     { 8, "Connect2",          dissect_ICBAAccoServer2_Connect2_rqst, dissect_ICBAAccoServer_Connect_resp },
4618     { 9, "GetConnectionData", dissect_ICBAAccoServer2_GetConnectionData_rqst, dissect_ICBAAccoServer2_GetConnectionData_resp },
4619     { 0, NULL, NULL, NULL },
4620 };
4621
4622
4623 /* sub dissector table of ICBAAccoServerSRT interface (stage 2 only) */
4624 static dcerpc_sub_dissector ICBAAccoServerSRT_dissectors[] = {
4625     { 0, "QueryInterface", NULL, NULL },
4626     { 1, "AddRef",         NULL, NULL },
4627     { 2, "Release",        NULL, NULL },
4628
4629     { 3, "ConnectCR",      dissect_ICBAAccoServerSRT_ConnectCR_rqst, dissect_ICBAAccoServerSRT_ConnectCR_resp },
4630     { 4, "DisconnectCR",   dissect_ICBAAccoServerSRT_DisconnectCR_rqst, dissect_ICBAAccoServerSRT_DisconnectCR_resp },
4631     { 5, "Connect",        dissect_ICBAAccoServerSRT_Connect_rqst, dissect_ICBAAccoServerSRT_Connect_resp },
4632     { 6, "Disconnect",     dissect_ICBAAccoServerSRT_Disconnect_rqst, dissect_ICBAAccoServerSRT_Disconnect_resp },
4633     { 7, "DisconnectMe",   dissect_ICBAAccoServerSRT_DisconnectMe_rqst, dissect_ICBAAccoServerSRT_DisconnectMe_resp },
4634     { 8, "SetActivation",  dissect_ICBAAccoServerSRT_SetActivation_rqst, dissect_ICBAAccoServerSRT_SetActivation_resp },
4635     { 0, NULL, NULL, NULL },
4636 };
4637
4638
4639 /* sub dissector table of ICBAAccoSync interface */
4640 static dcerpc_sub_dissector ICBAAccoSync_dissectors[] = {
4641     { 0, "QueryInterface", NULL, NULL },
4642     { 1, "AddRef",         NULL, NULL },
4643     { 2, "Release",        NULL, NULL },
4644
4645     { 3, "ReadItems",      dissect_ICBAAccoSync_ReadItems_rqst, dissect_ICBAAccoSync_ReadItems_resp },
4646     { 4, "WriteItems",     dissect_ICBAAccoSync_WriteItems_rqst, dissect_HResultArray_resp },
4647     { 5, "WriteItemsQCD",  dissect_ICBAAccoSync_WriteItemsQCD_rqst, dissect_HResultArray_resp },
4648     { 0, NULL, NULL, NULL },
4649 };
4650
4651
4652 /* register protocol */
4653 void
4654 proto_register_dcom_cba_acco (void)
4655 {
4656     static gint *ett3[3];
4657     static gint *ett4[4];
4658     static gint *ett5[5];
4659
4660
4661     static hf_register_info hf_cba_acco_array[] = {
4662         { &hf_cba_acco_opnum,
4663           { "Operation", "cba.acco.opnum",
4664             FT_UINT16, BASE_DEC, NULL, 0x0,
4665             NULL, HFILL }
4666         },
4667         { &hf_cba_acco_ping_factor,
4668           { "PingFactor", "cba.acco.ping_factor",
4669             FT_UINT16, BASE_DEC, NULL, 0x0,
4670             NULL, HFILL }
4671         },
4672         { &hf_cba_acco_count,
4673           { "Count", "cba.acco.count",
4674             FT_UINT32, BASE_DEC, NULL, 0x0,
4675             NULL, HFILL }
4676         },
4677         { &hf_cba_acco_info_max,
4678           { "Max", "cba.acco.info_max",
4679             FT_UINT32, BASE_DEC, NULL, 0x0,
4680             NULL, HFILL }
4681         },
4682         { &hf_cba_acco_info_curr,
4683           { "Current", "cba.acco.info_curr",
4684             FT_UINT32, BASE_DEC, NULL, 0x0,
4685             NULL, HFILL }
4686         },
4687         { &hf_cba_acco_rtauto,
4688           { "RTAuto", "cba.acco.rtauto",
4689             FT_STRING, BASE_NONE, NULL, 0x0,
4690             NULL, HFILL }
4691         },
4692         { &hf_cba_acco_item,
4693           { "Item", "cba.acco.item",
4694             FT_STRING, BASE_NONE, NULL, 0x0,
4695             NULL, HFILL }
4696         },
4697         { &hf_cba_acco_data,
4698           { "Data", "cba.acco.data",
4699             FT_NONE, BASE_NONE, NULL, 0x0,
4700             NULL, HFILL }
4701         },
4702         { &hf_cba_acco_qc,
4703           { "QualityCode", "cba.acco.qc",
4704             FT_UINT8, BASE_HEX, VALS(cba_acco_qc_vals), 0x0,
4705             NULL, HFILL }
4706         },
4707         { &hf_cba_acco_time_stamp,
4708           { "TimeStamp", "cba.acco.time_stamp",
4709             FT_UINT64, BASE_DEC, NULL, 0x0,
4710             NULL, HFILL }
4711         },
4712         { &hf_cba_readitemout,
4713           { "ReadItemOut", "cba.acco.readitemout",
4714             FT_NONE, BASE_NONE, NULL, 0x0,
4715             NULL, HFILL }
4716         },
4717         { &hf_cba_writeitemin,
4718           { "WriteItemIn", "cba.acco.writeitemin",
4719             FT_NONE, BASE_NONE, NULL, 0x0,
4720             NULL, HFILL }
4721         },
4722         { &hf_cba_acco_cdb_cookie,
4723           { "CDBCookie", "cba.acco.cdb_cookie",
4724             FT_UINT32, BASE_HEX, NULL, 0x0,
4725             NULL, HFILL }
4726         },
4727                 /* dcom_hresult_vals from packet-dcom.h doesn't work here, as length is unknown! */
4728         { &hf_cba_acco_conn_error_state,
4729           { "ConnErrorState", "cba.acco.conn_error_state",
4730             FT_UINT32, BASE_HEX, NULL /*VALS(dcom_hresult_vals)*/, 0x0,
4731             NULL, HFILL }
4732         },
4733         { &hf_cba_acco_diag_req,
4734           { "Request", "cba.acco.diag_req",
4735             FT_UINT32, BASE_HEX, VALS(cba_acco_diag_req_vals), 0x0,
4736             NULL, HFILL }
4737         },
4738         { &hf_cba_acco_diag_in_length,
4739           { "InLength", "cba.acco.diag_in_length",
4740             FT_UINT32, BASE_DEC, NULL, 0x0,
4741             NULL, HFILL }
4742         },
4743         { &hf_cba_acco_diag_out_length,
4744           { "OutLength", "cba.acco.diag_out_length",
4745             FT_UINT32, BASE_DEC, NULL, 0x0,
4746             NULL, HFILL }
4747         },
4748         { &hf_cba_acco_diag_data,
4749           { "Data", "cba.acco.diag_data",
4750             FT_BYTES, BASE_NONE, NULL, 0x0,
4751             NULL, HFILL }
4752         },
4753         { &hf_cba_acco_dcom_call,
4754           { "DcomRuntime", "cba.acco.dcom",
4755             FT_BOOLEAN, BASE_NONE, TFS(&cba_acco_call_flags), 0x0,
4756             "This is a DCOM runtime context", HFILL }
4757         },
4758         { &hf_cba_acco_srt_call,
4759           { "SrtRuntime", "cba.acco.srt",
4760             FT_BOOLEAN, BASE_NONE, TFS(&cba_acco_call_flags), 0x0,
4761             "This is an SRT runtime context", HFILL }
4762         }
4763
4764     };
4765
4766     static hf_register_info hf_cba_acco_server[] = {
4767 #if 0
4768         { &hf_cba_acco_server_pICBAAccoCallback,
4769           { "pICBAAccoCallback", "cba.acco.server_pICBAAccoCallback",
4770             FT_BYTES, BASE_NONE, NULL, 0x0,
4771             NULL, HFILL }
4772         },
4773 #endif
4774         { &hf_cba_acco_server_first_connect,
4775           { "FirstConnect", "cba.acco.server_first_connect",
4776             FT_UINT8, BASE_HEX, NULL, 0x0,
4777             NULL, HFILL }
4778         },
4779         { &hf_cba_getprovconnout,
4780           { "GETPROVCONNOUT", "cba.acco.getprovconnout",
4781             FT_NONE, BASE_NONE, NULL, 0x0,
4782             NULL, HFILL }
4783         },
4784         { &hf_cba_acco_serversrt_prov_mac,
4785           { "ProviderMAC", "cba.acco.serversrt_prov_mac",
4786             FT_ETHER, BASE_NONE, NULL, 0x0,
4787             NULL, HFILL }
4788         },
4789         { &hf_cba_acco_serversrt_cons_mac,
4790           { "ConsumerMAC", "cba.acco.serversrt_cons_mac",
4791             FT_ETHER, BASE_NONE, NULL, 0x0,
4792             NULL, HFILL }
4793         },
4794         { &hf_cba_acco_serversrt_cr_id,
4795           { "ConsumerCRID", "cba.acco.serversrt_cr_id",
4796             FT_UINT16, BASE_HEX, NULL, 0x0,
4797             NULL, HFILL }
4798         },
4799         { &hf_cba_acco_serversrt_cr_length,
4800           { "CRLength", "cba.acco.serversrt_cr_length",
4801             FT_UINT16, BASE_DEC, NULL, 0x0,
4802             NULL, HFILL }
4803         },
4804         { &hf_cba_acco_serversrt_cr_flags,
4805           { "Flags", "cba.acco.serversrt_cr_flags",
4806             FT_UINT32, BASE_HEX, 0, 0x0,
4807             NULL, HFILL }
4808         },
4809         { &hf_cba_acco_serversrt_cr_flags_timestamped,
4810           { "Timestamped", "cba.acco.serversrt_cr_flags_timestamped",
4811             FT_BOOLEAN, 32, TFS (&acco_flags_set_truth), 0x1,
4812             NULL, HFILL }
4813         },
4814         { &hf_cba_acco_serversrt_cr_flags_reconfigure,
4815           { "Reconfigure", "cba.acco.serversrt_cr_flags_reconfigure",
4816             FT_BOOLEAN, 32, TFS (&acco_flags_set_truth), 0x2,
4817             NULL, HFILL }
4818         },
4819         { &hf_cba_type_desc_len,
4820           { "TypeDescLen", "cba.acco.type_desc_len",
4821             FT_UINT16, BASE_DEC, NULL, 0x0,
4822             NULL, HFILL }
4823         },
4824         { &hf_cba_acco_serversrt_record_length,
4825           { "RecordLength", "cba.acco.serversrt_record_length",
4826             FT_UINT16, BASE_DEC, NULL, 0x0,
4827             NULL, HFILL }
4828         },
4829 #if 0
4830         { &hf_cba_acco_serversrt_action,
4831           { "Action", "cba.acco.serversrt_action",
4832             FT_UINT32, BASE_DEC, VALS(cba_acco_serversrt_action_vals), 0x0,
4833             NULL, HFILL }
4834         },
4835 #endif
4836         { &hf_cba_acco_serversrt_last_connect,
4837           { "LastConnect", "cba.acco.serversrt_last_connect",
4838             FT_UINT8, BASE_DEC, VALS(cba_acco_serversrt_last_connect_vals), 0x0,
4839             NULL, HFILL }
4840         },
4841     };
4842
4843     static hf_register_info hf_cba_connectcr_array[] = {
4844         { &hf_cba_acco_prov_crid,
4845           { "ProviderCRID", "cba.acco.prov_crid",
4846             FT_UINT32, BASE_HEX, NULL, 0x0,
4847             NULL, HFILL }
4848         },
4849     };
4850
4851     static hf_register_info hf_cba_connect_array[] = {
4852         { &hf_cba_addconnectionin,
4853           { "ADDCONNECTIONIN", "cba.acco.addconnectionin",
4854             FT_NONE, BASE_NONE, NULL, 0x0,
4855             NULL, HFILL }
4856         },
4857         { &hf_cba_addconnectionout,
4858           { "ADDCONNECTIONOUT", "cba.acco.addconnectionout",
4859             FT_NONE, BASE_NONE, NULL, 0x0,
4860             NULL, HFILL }
4861         },
4862         { &hf_cba_getidout,
4863           { "GETIDOUT", "cba.acco.getidout",
4864             FT_NONE, BASE_NONE, NULL, 0x0,
4865             NULL, HFILL }
4866         },
4867         { &hf_cba_getconnectionout,
4868           { "GETCONNECTIONOUT", "cba.acco.getconnectionout",
4869             FT_NONE, BASE_NONE, NULL, 0x0,
4870             NULL, HFILL }
4871         },
4872         { &hf_cba_getconsconnout,
4873           { "GETCONSCONNOUT", "cba.acco.getconsconnout",
4874             FT_NONE, BASE_NONE, NULL, 0x0,
4875             NULL, HFILL }
4876         },
4877         { &hf_cba_diagconsconnout,
4878           { "DIAGCONSCONNOUT", "cba.acco.diagconsconnout",
4879             FT_NONE, BASE_NONE, NULL, 0x0,
4880             NULL, HFILL }
4881         },
4882         { &hf_cba_connectincr,
4883           { "CONNECTINCR", "cba.acco.connectincr",
4884             FT_NONE, BASE_NONE, NULL, 0x0,
4885             NULL, HFILL }
4886         },
4887         { &hf_cba_connectoutcr,
4888           { "CONNECTOUTCR", "cba.acco.connectoutcr",
4889             FT_NONE, BASE_NONE, NULL, 0x0,
4890             NULL, HFILL }
4891         },
4892         { &hf_cba_connectin,
4893           { "CONNECTIN", "cba.acco.connectin",
4894             FT_NONE, BASE_NONE, NULL, 0x0,
4895             NULL, HFILL }
4896         },
4897         { &hf_cba_connectout,
4898           { "CONNECTOUT", "cba.acco.connectout",
4899             FT_NONE, BASE_NONE, NULL, 0x0,
4900             NULL, HFILL }
4901         },
4902         { &hf_cba_acco_conn_prov_id,
4903           { "ProviderID", "cba.acco.conn_prov_id",
4904             FT_UINT32, BASE_HEX, NULL, 0x0,
4905             NULL, HFILL }
4906         },
4907         { &hf_cba_acco_conn_cons_id,
4908           { "ConsumerID", "cba.acco.conn_cons_id",
4909             FT_UINT32, BASE_HEX, NULL, 0x0,
4910             NULL, HFILL }
4911         },
4912         { &hf_cba_acco_conn_version,
4913           { "ConnVersion", "cba.acco.conn_version",
4914             FT_UINT16, BASE_HEX, NULL, 0x0,
4915             NULL, HFILL }
4916         },
4917         { &hf_cba_acco_conn_consumer,
4918           { "Consumer", "cba.acco.conn_consumer",
4919             FT_STRING, BASE_NONE, NULL, 0x0,
4920             NULL, HFILL }
4921         },
4922         { &hf_cba_acco_conn_qos_type,
4923           { "QoSType", "cba.acco.conn_qos_type",
4924             FT_UINT16, BASE_HEX, VALS(cba_qos_type_vals), 0x0,
4925             NULL, HFILL }
4926         },
4927         { &hf_cba_acco_conn_qos_value,
4928           { "QoSValue", "cba.acco.conn_qos_value",
4929             FT_UINT16, BASE_DEC, NULL, 0x0,
4930             NULL, HFILL }
4931         },
4932         { &hf_cba_acco_conn_state,
4933           { "State", "cba.acco.conn_state",
4934             FT_UINT8, BASE_HEX, VALS(cba_acco_conn_state_vals), 0x0,
4935             NULL, HFILL }
4936         },
4937         { &hf_cba_acco_conn_provider,
4938           { "Provider", "cba.acco.conn_provider",
4939             FT_STRING, BASE_NONE, NULL, 0x0,
4940             NULL, HFILL }
4941         },
4942         { &hf_cba_acco_conn_provider_item,
4943           { "ProviderItem", "cba.acco.conn_provider_item",
4944             FT_STRING, BASE_NONE, NULL, 0x0,
4945             NULL, HFILL }
4946         },
4947         { &hf_cba_acco_conn_consumer_item,
4948           { "ConsumerItem", "cba.acco.conn_consumer_item",
4949             FT_STRING, BASE_NONE, NULL, 0x0,
4950             NULL, HFILL }
4951         },
4952         { &hf_cba_acco_conn_persist,
4953           { "Persistence", "cba.acco.conn_persist",
4954             FT_UINT16, BASE_HEX, VALS(cba_persist_vals), 0x0,
4955             NULL, HFILL }
4956         },
4957         { &hf_cba_acco_conn_epsilon,
4958           { "Epsilon", "cba.acco.conn_epsilon",
4959             FT_NONE, BASE_NONE, NULL, 0x0,
4960             NULL, HFILL }
4961         },
4962         { &hf_cba_acco_conn_substitute,
4963           { "Substitute", "cba.acco.conn_substitute",
4964             FT_NONE, BASE_NONE, NULL, 0x0,
4965             NULL, HFILL }
4966         },
4967     };
4968
4969     static hf_register_info hf_cba_acco_cb[] = {
4970         { &hf_cba_acco_cb_length,
4971           { "Length", "cba.acco.cb_length",
4972             FT_UINT32, BASE_DEC, NULL, 0x0,
4973             NULL, HFILL }
4974         },
4975         { &hf_cba_acco_cb_version,
4976           { "Version", "cba.acco.cb_version",
4977             FT_UINT8, BASE_HEX, NULL, 0x0,
4978             NULL, HFILL }
4979         },
4980         { &hf_cba_acco_cb_flags,
4981           { "Flags", "cba.acco.cb_flags",
4982             FT_UINT8, BASE_HEX, NULL, 0x0,
4983             NULL, HFILL }
4984         },
4985         { &hf_cba_acco_cb_count,
4986           { "Count", "cba.acco.cb_count",
4987             FT_UINT16, BASE_DEC, NULL, 0x0,
4988             NULL, HFILL }
4989         },
4990         { &hf_cba_acco_cb_conn_data,
4991           { "CBA Connection data", "cba.acco.cb_conn_data",
4992             FT_NONE, BASE_NONE, NULL, 0x0,
4993             NULL, HFILL }
4994         },
4995         { &hf_cba_acco_cb_item,
4996           { "Item", "cba.acco.cb_item",
4997             FT_NONE, BASE_NONE, NULL, 0x0,
4998             NULL, HFILL }
4999         },
5000         { &hf_cba_acco_cb_item_hole,
5001           { "Hole", "cba.acco.cb_item_hole",
5002             FT_NONE, BASE_NONE, NULL, 0x0,
5003             NULL, HFILL }
5004         },
5005         { &hf_cba_acco_cb_item_length,
5006           { "Length", "cba.acco.cb_item_length",
5007             FT_UINT16, BASE_DEC, NULL, 0x0,
5008             NULL, HFILL }
5009         },
5010         { &hf_cba_acco_cb_item_data,
5011           { "Data(Hex)", "cba.acco.cb_item_data",
5012             FT_BYTES, BASE_NONE, NULL, 0x0,
5013             NULL, HFILL }
5014         },
5015         { &hf_cba_connect_in,
5016           { "Connect in frame", "cba.connect_in",
5017             FT_FRAMENUM, BASE_NONE, NULL, 0,
5018             "This connection Connect was in the packet with this number", HFILL }
5019         },
5020         { &hf_cba_disconnect_in,
5021           { "Disconnect in frame", "cba.disconnect_in",
5022             FT_FRAMENUM, BASE_NONE, NULL, 0,
5023             "This connection Disconnect was in the packet with this number", HFILL }
5024         },
5025         { &hf_cba_connectcr_in,
5026           { "ConnectCR in frame", "cba.connect_in",
5027             FT_FRAMENUM, BASE_NONE, NULL, 0,
5028             "This frame ConnectCR was in the packet with this number", HFILL }
5029         },
5030         { &hf_cba_disconnectcr_in,
5031           { "DisconnectCR in frame", "cba.disconnect_in",
5032             FT_FRAMENUM, BASE_NONE, NULL, 0,
5033             "This frame DisconnectCR was in the packet with this number", HFILL }
5034         },
5035         { &hf_cba_disconnectme_in,
5036           { "DisconnectMe in frame", "cba.disconnectme_in",
5037             FT_FRAMENUM, BASE_NONE, NULL, 0,
5038             "This connection/frame DisconnectMe was in the packet with this number", HFILL }
5039         },
5040         { &hf_cba_data_first_in,
5041           { "First data in frame", "cba.data_first_in",
5042             FT_FRAMENUM, BASE_NONE, NULL, 0,
5043             "The first data of this connection/frame in the packet with this number", HFILL }
5044         },
5045         { &hf_cba_data_last_in,
5046           { "Last data in frame", "cba.data_last_in",
5047             FT_FRAMENUM, BASE_NONE, NULL, 0,
5048             "The last data of this connection/frame in the packet with this number", HFILL }
5049         },
5050     };
5051
5052     static ei_register_info ei[] = {
5053         { &ei_cba_acco_pdev_find, { "cba.acco.pdev_find.fail", PI_UNDECODED, PI_NOTE, "pdev_find: no pdev for IP", EXPFILL }},
5054         { &ei_cba_acco_pdev_find_unknown_interface, { "cba.acco.pdev_find.unknown_interface", PI_UNDECODED, PI_NOTE, "pdev_find: unknown interface", EXPFILL }},
5055         { &ei_cba_acco_ldev_unknown, { "cba.acco.ldev.unknown", PI_UNDECODED, PI_NOTE, "Unknown LDev", EXPFILL }},
5056         { &ei_cba_acco_ipid_unknown, { "cba.acco.ipid.unknown", PI_UNDECODED, PI_NOTE, "Unknown IPID", EXPFILL }},
5057         { &ei_cba_acco_prov_crid, { "cba.acco.prov_crid.unknown", PI_UNDECODED, PI_NOTE, "Unknown provider frame ProvCRID", EXPFILL }},
5058         { &ei_cba_acco_conn_consumer, { "cba.acco.conn_consumer.invalid", PI_UNDECODED, PI_NOTE, "Consumer interface invalid", EXPFILL }},
5059         { &ei_cba_acco_no_request_info, { "cba.acco.no_request_info", PI_UNDECODED, PI_NOTE, "No request info, response data ignored", EXPFILL }},
5060         { &ei_cba_acco_qc, { "cba.acco.qc.expert", PI_RESPONSE_CODE, PI_CHAT, "expert QC", EXPFILL }},
5061     };
5062
5063     expert_module_t* expert_cba_acco;
5064
5065     ett5[0] = &ett_ICBAAccoMgt;
5066     ett5[1] = &ett_cba_addconnectionin;
5067     ett5[2] = &ett_cba_addconnectionout;
5068     ett5[3] = &ett_cba_getidout;
5069     ett5[4] = &ett_cba_getconnectionout;
5070     proto_ICBAAccoMgt = proto_register_protocol ("ICBAAccoMgt", "ICBAAccoMgt", "cba_acco_mgt");
5071     proto_register_field_array(proto_ICBAAccoMgt, hf_cba_acco_array, array_length(hf_cba_acco_array));
5072     proto_register_field_array(proto_ICBAAccoMgt, hf_cba_connect_array, array_length(hf_cba_connect_array));
5073     proto_register_field_array(proto_ICBAAccoMgt, hf_cba_connectcr_array, array_length(hf_cba_connectcr_array));
5074     proto_register_subtree_array (ett5, array_length (ett5));
5075
5076     /* XXX - just pick a protocol to register the expert info in */
5077     /* XXX - also, just pick a protocol to use proto_data for */
5078     expert_cba_acco = expert_register_protocol(proto_ICBAAccoMgt);
5079     expert_register_field_array(expert_cba_acco, ei, array_length(ei));
5080
5081     proto_ICBAAccoMgt2 = proto_register_protocol ("ICBAAccoMgt2", "ICBAAccoMgt2", "cba_acco_mgt2");
5082
5083     ett3[0] = &ett_ICBAAccoCallback;
5084     ett3[1] = &ett_ICBAAccoCallback_Item;
5085     ett3[2] = &ett_ICBAAccoCallback_Buffer;
5086     proto_ICBAAccoCallback = proto_register_protocol ("ICBAAccoCallback", "ICBAAccoCB", "cba_acco_cb");
5087     proto_register_field_array(proto_ICBAAccoCallback, hf_cba_acco_cb, array_length(hf_cba_acco_cb));
5088     proto_register_subtree_array (ett3, array_length (ett3));
5089
5090     proto_ICBAAccoCallback2 = proto_register_protocol ("ICBAAccoCallback2", "ICBAAccoCB2", "cba_acco_cb2");
5091
5092     ett4[0] = &ett_ICBAAccoServer;
5093     ett4[1] = &ett_cba_connectin;
5094     ett4[2] = &ett_cba_connectout;
5095     ett4[3] = &ett_cba_getprovconnout;
5096     proto_ICBAAccoServer = proto_register_protocol ("ICBAAccoServer", "ICBAAccoServ", "cba_acco_server");
5097     proto_register_field_array(proto_ICBAAccoServer, hf_cba_acco_server, array_length(hf_cba_acco_server));
5098     proto_register_subtree_array (ett4, array_length (ett4));
5099
5100     proto_ICBAAccoServer2 = proto_register_protocol ("ICBAAccoServer2", "ICBAAccoServ2", "cba_acco_server2");
5101
5102     ett4[0] = &ett_ICBAAccoServerSRT;
5103     ett4[1] = &ett_cba_acco_serversrt_cr_flags;
5104     ett4[2] = &ett_cba_connectincr;
5105     ett4[3] = &ett_cba_connectoutcr;
5106     proto_ICBAAccoServerSRT = proto_register_protocol ("ICBAAccoServerSRT", "ICBAAccoServSRT", "cba_acco_server_srt");
5107     proto_register_subtree_array (ett4, array_length (ett4));
5108
5109     ett5[0] = &ett_ICBAAccoSync;
5110     ett5[1] = &ett_cba_readitemout;
5111     ett5[2] = &ett_cba_writeitemin;
5112     ett5[3] = &ett_cba_frame_info;
5113     ett5[4] = &ett_cba_conn_info;
5114     proto_ICBAAccoSync = proto_register_protocol ("ICBAAccoSync", "ICBAAccoSync", "cba_acco_sync");
5115     proto_register_subtree_array (ett5, array_length (ett5));
5116
5117     register_conversation_filter("cba", "PN-CBA", cba_filter_valid, cba_build_filter);
5118 }
5119
5120
5121 /* handoff protocol */
5122 void
5123 proto_reg_handoff_dcom_cba_acco (void)
5124 {
5125     /* Register the interfaces */
5126     dcerpc_init_uuid(proto_ICBAAccoMgt, ett_ICBAAccoMgt,
5127         &uuid_ICBAAccoMgt, ver_ICBAAccoMgt, ICBAAccoMgt_dissectors, hf_cba_acco_opnum);
5128
5129     dcerpc_init_uuid(proto_ICBAAccoMgt2, ett_ICBAAccoMgt,
5130         &uuid_ICBAAccoMgt2, ver_ICBAAccoMgt2, ICBAAccoMgt_dissectors, hf_cba_acco_opnum);
5131
5132     dcerpc_init_uuid(proto_ICBAAccoCallback, ett_ICBAAccoCallback,
5133         &uuid_ICBAAccoCallback, ver_ICBAAccoCallback, ICBAAccoCallback_dissectors, hf_cba_acco_opnum);
5134
5135     dcerpc_init_uuid(proto_ICBAAccoCallback2, ett_ICBAAccoCallback,
5136         &uuid_ICBAAccoCallback2, ver_ICBAAccoCallback2, ICBAAccoCallback_dissectors, hf_cba_acco_opnum);
5137
5138     dcerpc_init_uuid(proto_ICBAAccoServer, ett_ICBAAccoServer,
5139         &uuid_ICBAAccoServer, ver_ICBAAccoServer, ICBAAccoServer_dissectors, hf_cba_acco_opnum);
5140
5141     dcerpc_init_uuid(proto_ICBAAccoServer2, ett_ICBAAccoServer,
5142         &uuid_ICBAAccoServer2, ver_ICBAAccoServer2, ICBAAccoServer_dissectors, hf_cba_acco_opnum);
5143
5144     dcerpc_init_uuid(proto_ICBAAccoServerSRT, ett_ICBAAccoServerSRT,
5145         &uuid_ICBAAccoServerSRT, ver_ICBAAccoServerSRT, ICBAAccoServerSRT_dissectors, hf_cba_acco_opnum);
5146
5147     dcerpc_init_uuid(proto_ICBAAccoSync, ett_ICBAAccoSync,
5148         &uuid_ICBAAccoSync, ver_ICBAAccoSync, ICBAAccoSync_dissectors, hf_cba_acco_opnum);
5149
5150
5151     heur_dissector_add("pn_rt", dissect_CBA_Connection_Data_heur, "PROFINET CBA IO", "pn_cba_pn_rt", proto_ICBAAccoServer, HEURISTIC_ENABLE);
5152 }
5153
5154 /*
5155  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
5156  *
5157  * Local variables:
5158  * c-basic-offset: 4
5159  * tab-width: 8
5160  * indent-tabs-mode: nil
5161  * End:
5162  *
5163  * vi: set shiftwidth=4 tabstop=8 expandtab:
5164  * :indentSize=4:tabSize=8:noTabs=true:
5165  */