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