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