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