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