Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-bluecom.c
blobc29e64182e1243e26ab840f4c06d76df07e57cb4
1 /* packet-bluecom.c
3 * Routines and register functions of bluecom dissector
5 * Bachmann bluecom Protocol
6 * Packet dissector based on Ethernet
8 * COPYRIGHT BY BACHMANN ELECTRONIC GmbH 2016
9 * Contact: Gerhard Khueny <g.khueny@bachmann.info>
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * SPDX-License-Identifier: GPL-2.0-or-later
18 #include "config.h"
20 #include <epan/packet.h>
21 #include <epan/etypes.h>
22 #include <epan/to_str.h>
23 #include <epan/exceptions.h>
24 #include <epan/show_exception.h>
26 /* bluecom protocol defines */
28 /* BCP_ETH_VLAN_HDR */
29 #define BCP_VLAN_TYPE 0x8100 /* ethernet vlan type */
30 #define BCP_ETH_TYPE 0x892D /* ethernet type */
32 #define BCP_PROT_FLG_REQ 0x01 /* request */
33 #define BCP_PROT_FLG_RSP 0x02 /* response */
34 #define BCP_PROT_FLG_PRIM 0x80 /* primary */
36 /* BCP_BLOCK_HDR */
37 #define BCP_SLAVEID_ANY 0x0000 /* zero reserved */
38 #define BCP_SLAVEID_MASK 0x01FF /* open range for 512 nodes */
39 /* see 'BCP_MAX_NODE_NB' */
40 #define BCP_SLAVEID_MST 0x1000 /* master bit */
41 #define BCP_SLAVEID_SLV 0x2000 /* slave bit */
43 #define BCP_BLK_CMD_SYNC 0 /* master -> slave */
44 #define BCP_BLK_CMD_DATA 1 /* master/slave -> slave/master */
45 #define BCP_BLK_CMD_IDENTIFY 2 /* slave -> master */
46 #define BCP_BLK_CMD_SEARCH 3 /* master/slave -> slave */
47 #define BCP_BLK_CMD_CONNECT 4 /* master -> slave */
49 #define BCP_BLK_FLG_VALID 0x01 /* data written by APP -> valid */
50 #define BCP_BLK_FLG_PTP 0x02 /* PTP timestamp */
52 /* BCP_SEARCH_XXX */
53 #define BCP_NAME_LEN 32 /* slave name length */
55 #define BCP_SEARCH_NAME 1 /* search options */
56 #define BCP_SEARCH_IPADDR 2
57 #define BCP_SEARCH_DEFAULT BCP_SEARCH_NAME
59 #define BCP_ETHADDR_LEN 6 /* ethernet address length */
61 #define BCP_PROTOCOL_HDR_LEN 10 /* FIXME: use sizeof with packed from header */
62 #define BCP_BLOCK_HDR_LEN 24
64 /* helper defines */
65 #define BOOLSTR(val) ((val) ? "True" : "False")
66 #define REQRSP(val) ((val & BCP_PROT_FLG_REQ) ? "Request " : "Response ")
68 /* prototypes */
69 void proto_reg_handoff_bluecom(void);
70 void proto_register_bluecom(void);
72 /* static handles */
73 static dissector_handle_t bcp_handle;
74 static dissector_table_t bcp_subdissector_table;
76 static int proto_bcp;
77 static int ett_bcp;
78 static int ett_bcp_header;
79 static int ett_bcp_blockheader;
80 static int ett_bcp_data;
82 /* protocol data id */
83 static int hf_bcp_hdr_version;
84 static int hf_bcp_hdr_format;
85 static int hf_bcp_hdr_protflags;
86 static int hf_bcp_hdr_blocknb;
87 static int hf_bcp_hdr_segcode;
88 static int hf_bcp_hdr_auth;
89 static int hf_bcp_hdr_sourceid;
90 static int hf_bcp_hdr_destid;
91 static int hf_bcp_hdr_transid;
92 static int hf_bcp_hdr_cmd;
93 static int hf_bcp_hdr_slavestate;
94 static int hf_bcp_hdr_blockflags;
95 static int hf_bcp_hdr_len;
96 static int hf_bcp_hdr_timestamp;
97 static int hf_bcp_hdr_fragoffset;
99 static int hf_bcp_sync_starttime;
100 static int hf_bcp_sync_cycletime;
101 static int hf_bcp_sync_dataratio;
102 static int hf_bcp_sync_identify;
103 static int hf_bcp_sync_vlantag;
104 static int hf_bcp_sync_ethaddr;
105 static int hf_bcp_sync_ethaddr2;
107 static int hf_bcp_identify_error;
108 static int hf_bcp_identify_starttime;
109 static int hf_bcp_identify_ipaddr;
110 static int hf_bcp_identify_name;
111 static int hf_bcp_identify_ethaddr;
112 static int hf_bcp_identify_ethaddr2;
114 static int hf_bcp_searchreq_addrtype;
115 static int hf_bcp_searchreq_reserved;
116 static int hf_bcp_searchreq_name;
117 static int hf_bcp_searchreq_ipaddrfirst;
118 static int hf_bcp_searchreq_ipaddrlast;
119 static int hf_bcp_searchreq_addrdata;
121 static int hf_bcp_searchrsp_error;
122 static int hf_bcp_searchrsp_starttime;
123 static int hf_bcp_searchrsp_lenin;
124 static int hf_bcp_searchrsp_lenout;
125 static int hf_bcp_searchrsp_ipaddr;
126 static int hf_bcp_searchrsp_name;
127 static int hf_bcp_searchrsp_ethaddr;
128 static int hf_bcp_searchrsp_ethaddr2;
130 static int hf_bcp_connectreq_lenin;
131 static int hf_bcp_connectreq_lenout;
132 static int hf_bcp_connectreq_cycletime;
133 static int hf_bcp_connectreq_offlinefactor;
134 static int hf_bcp_connectreq_ipaddr;
135 static int hf_bcp_connectreq_name;
136 static int hf_bcp_connectreq_ethaddr;
137 static int hf_bcp_connectreq_ethaddr2;
139 static int hf_bcp_connectrsp_error;
140 static int hf_bcp_connectrsp_lenin;
141 static int hf_bcp_connectrsp_lenout;
143 static int hf_bcp_userdata;
145 /* command defines */
146 static const value_string bcp_cmds[] = {
147 { BCP_BLK_CMD_SYNC, "SYNC" },
148 { BCP_BLK_CMD_DATA, "DATA" },
149 { BCP_BLK_CMD_IDENTIFY, "IDENTIFY" },
150 { BCP_BLK_CMD_SEARCH, "SEARCH" },
151 { BCP_BLK_CMD_CONNECT, "CONNECT" },
152 { 0, NULL }
156 * dissector function of connect data (request and response)
158 * input: tree, buffer (block data), flags (req or rsp)
159 * return: nothing
161 static void
162 dissect_bcp_connect_data(packet_info *pinfo, proto_tree *bcp_tree, tvbuff_t *tvb, int flags)
164 proto_tree *bcp_subtree = NULL;
165 unsigned offset = 0;
166 unsigned offset_base = offset;
167 unsigned len = tvb_reported_length(tvb);
169 if (flags & BCP_PROT_FLG_REQ)
171 bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, offset, len, ett_bcp_data, NULL,
172 "BCP Connect Request: Name=%s IpAddr=%s",
173 tvb_get_string_enc(pinfo->pool, tvb, offset + 16, BCP_NAME_LEN, ENC_ASCII),
174 tvb_ip_to_str(pinfo->pool, tvb, offset + 12));
176 proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_lenin, tvb, offset, 2, ENC_BIG_ENDIAN);
177 offset += 2;
178 proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_lenout, tvb, offset, 2, ENC_BIG_ENDIAN);
179 offset += 2;
180 proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_cycletime, tvb, offset, 4, ENC_BIG_ENDIAN);
181 offset += 4;
182 proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_offlinefactor, tvb, offset, 2, ENC_BIG_ENDIAN);
183 offset += 4;
184 proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_ipaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
185 offset += 4;
186 proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_name, tvb, offset, BCP_NAME_LEN, ENC_ASCII);
187 offset += BCP_NAME_LEN;
188 proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_ethaddr, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
189 offset += BCP_ETHADDR_LEN;
190 if((len-(offset-offset_base)))
192 proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_ethaddr2, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
193 offset += BCP_ETHADDR_LEN;
197 if (flags & BCP_PROT_FLG_RSP)
199 bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, offset, len, ett_bcp_data, NULL,
200 "BCP Connect Response: Error=%d",
201 tvb_get_ntohl(tvb, offset));
203 proto_tree_add_item(bcp_subtree, hf_bcp_connectrsp_error, tvb, offset, 4, ENC_BIG_ENDIAN);
204 offset += 4;
205 proto_tree_add_item(bcp_subtree, hf_bcp_connectrsp_lenin, tvb, offset, 2, ENC_BIG_ENDIAN);
206 offset += 2;
207 proto_tree_add_item(bcp_subtree, hf_bcp_connectrsp_lenout, tvb, offset, 2, ENC_BIG_ENDIAN);
212 * dissector function of search data (request and response)
214 * input: tree, buffer (block data) flags (req or rsp)
215 * return: nothing
217 static void
218 dissect_bcp_search_data(packet_info *pinfo, proto_tree *bcp_tree, tvbuff_t *tvb, int flags)
220 proto_tree *bcp_subtree = NULL;
221 unsigned type = 0;
222 unsigned offset = 0;
223 unsigned offset_base = offset;
224 unsigned len = tvb_reported_length(tvb);
226 if (flags & BCP_PROT_FLG_REQ)
228 type = tvb_get_ntohl(tvb, offset);
229 switch (type)
231 case BCP_SEARCH_IPADDR:
232 bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, offset, len, ett_bcp_data, NULL,
233 "BCP Search Request: IpAddrFirst=%s, IpAddrLast=%s",
234 tvb_ip_to_str(pinfo->pool, tvb, offset + 8),
235 tvb_ip_to_str(pinfo->pool, tvb, offset + 12)
237 break;
239 case BCP_SEARCH_NAME:
240 bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, offset, len, ett_bcp_data, NULL,
241 "BCP Search Request: Name=%s",
242 tvb_get_string_enc(pinfo->pool, tvb, offset + 8, BCP_NAME_LEN, ENC_ASCII)
244 break;
246 default:
247 bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, offset, len, ett_bcp_data, NULL,
248 "BCP Search Request: Unknown AddrType");
249 break;
252 proto_tree_add_item(bcp_subtree, hf_bcp_searchreq_addrtype, tvb, offset, 4, ENC_BIG_ENDIAN);
253 offset += 4;
254 proto_tree_add_item(bcp_subtree, hf_bcp_searchreq_reserved, tvb, offset, 4, ENC_BIG_ENDIAN);
255 offset += 4;
257 switch (type)
259 case BCP_SEARCH_IPADDR:
260 proto_tree_add_item(bcp_subtree, hf_bcp_searchreq_ipaddrfirst, tvb, offset, 4, ENC_BIG_ENDIAN);
261 proto_tree_add_item(bcp_subtree, hf_bcp_searchreq_ipaddrlast, tvb, offset + 4, 4, ENC_BIG_ENDIAN);
262 break;
264 case BCP_SEARCH_NAME:
265 proto_tree_add_item(bcp_subtree, hf_bcp_searchreq_name, tvb, offset, BCP_NAME_LEN, ENC_ASCII);
266 break;
268 default:
269 proto_tree_add_bytes_format(bcp_subtree, hf_bcp_searchreq_addrdata, tvb, offset, BCP_NAME_LEN,
270 NULL, "Unknown Address Data (%u bytes)", BCP_NAME_LEN);
271 break;
273 offset += BCP_NAME_LEN;
276 if (flags & BCP_PROT_FLG_RSP)
278 bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, offset, len, ett_bcp_data, NULL,
279 "BCP Search Response: Name=%s, IpAddr=%s Error=%d",
280 tvb_get_string_enc(pinfo->pool, tvb, offset + 16, BCP_NAME_LEN, ENC_ASCII),
281 tvb_ip_to_str(pinfo->pool, tvb, offset + 12),
282 tvb_get_letohl(tvb, offset)
285 proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_error, tvb, offset, 4, ENC_NA);
286 offset += 4;
287 proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_starttime, tvb, offset, 4, ENC_BIG_ENDIAN);
288 offset += 4;
289 proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_lenin, tvb, offset, 2, ENC_BIG_ENDIAN);
290 offset += 2;
291 proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_lenout, tvb, offset, 2, ENC_BIG_ENDIAN);
292 offset += 2;
293 proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_ipaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
294 offset += 4;
295 proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_name, tvb, offset, BCP_NAME_LEN, ENC_ASCII);
296 offset += BCP_NAME_LEN;
297 proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_ethaddr, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
298 offset += BCP_ETHADDR_LEN;
299 if((len-(offset-offset_base)))
301 proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_ethaddr2, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
307 * dissector function of identify data (request)
309 * input: tree, buffer (block data), flags (req or rsp)
310 * return: nothing
312 static void
313 dissect_bcp_identify_data(packet_info *pinfo, proto_tree *bcp_tree, tvbuff_t *tvb)
315 proto_tree *bcp_subtree = NULL;
316 unsigned offset = 0;
317 unsigned offset_base = offset;
318 unsigned len = tvb_reported_length(tvb);
320 bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, offset, len, ett_bcp_data, NULL,
321 "BCP Identify Request: Name=%s, IpAddr=%s",
322 tvb_get_string_enc(pinfo->pool, tvb, offset + 12, BCP_NAME_LEN, ENC_ASCII),
323 tvb_ip_to_str(pinfo->pool, tvb, offset + 8)
326 proto_tree_add_item(bcp_subtree, hf_bcp_identify_error, tvb, offset, 4, ENC_BIG_ENDIAN);
327 offset += 4;
328 proto_tree_add_item(bcp_subtree, hf_bcp_identify_starttime, tvb, offset, 4, ENC_BIG_ENDIAN);
329 offset += 4;
330 proto_tree_add_item(bcp_subtree, hf_bcp_identify_ipaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
331 offset += 4;
332 proto_tree_add_item(bcp_subtree, hf_bcp_identify_name, tvb, offset, BCP_NAME_LEN, ENC_ASCII);
333 offset += BCP_NAME_LEN;
334 proto_tree_add_item(bcp_subtree, hf_bcp_identify_ethaddr, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
335 offset += BCP_ETHADDR_LEN;
336 if((len-(offset-offset_base)))
338 proto_tree_add_item(bcp_subtree, hf_bcp_identify_ethaddr2, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
343 * dissector function of sync data
345 * input: tree, buffer (block data)
346 * return: nothing
348 static void
349 dissect_bcp_sync_data(proto_tree *bcp_tree, tvbuff_t *tvb)
351 proto_tree *bcp_subtree = NULL;
352 unsigned offset = 0;
353 unsigned offset_base = offset;
354 unsigned len = tvb_reported_length(tvb);
356 bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, offset, len, ett_bcp_data, NULL,
357 "BCP Sync Data: Identify=%s",
358 BOOLSTR(tvb_get_uint8(tvb, offset + 9)));
359 proto_tree_add_item(bcp_subtree, hf_bcp_sync_starttime, tvb, offset, 4, ENC_BIG_ENDIAN);
360 offset += 4;
361 proto_tree_add_item(bcp_subtree, hf_bcp_sync_cycletime, tvb, offset, 4, ENC_BIG_ENDIAN);
362 offset += 4;
363 proto_tree_add_item(bcp_subtree, hf_bcp_sync_dataratio, tvb, offset, 1, ENC_BIG_ENDIAN);
364 offset += 1;
365 proto_tree_add_item(bcp_subtree, hf_bcp_sync_identify, tvb, offset, 1, ENC_BIG_ENDIAN);
366 offset += 1;
367 proto_tree_add_item(bcp_subtree, hf_bcp_sync_vlantag, tvb, offset, 2, ENC_BIG_ENDIAN);
368 offset += 2;
370 /* protocol expansion*/
371 if((len-(offset-offset_base)))
373 proto_tree_add_item(bcp_subtree, hf_bcp_sync_ethaddr, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
374 offset += BCP_ETHADDR_LEN;
375 proto_tree_add_item(bcp_subtree, hf_bcp_sync_ethaddr2, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
380 * dissector function of data command
382 * input: tree, buffer (block data)
383 * return: nothing
385 static void
386 dissect_bcp_data(proto_tree *bcp_tree, packet_info *pinfo, tvbuff_t *tvb,
387 unsigned segcode)
389 dissector_handle_t handle;
391 /* Probably a sub-dissector exists for this type/version combination. */
392 handle = dissector_get_uint_handle(bcp_subdissector_table, segcode);
394 if (handle)
396 /* Call the sub-dissector. */
397 call_dissector(handle, tvb, pinfo, bcp_tree);
399 else
401 proto_tree_add_item(bcp_tree, hf_bcp_userdata, tvb, 0, -1, ENC_NA);
407 * dissector function of block header
409 * input: tree, buffer (data), offset (data pointer), number of header block
410 * output: command from header, length of following data
411 * return: updated offset
413 static unsigned
414 dissect_bcp_block_header(proto_tree *bcp_tree, tvbuff_t *tvb, unsigned offset,
415 unsigned blocknb, unsigned *cmd, unsigned *len)
417 proto_tree *bcp_subtree = NULL;
419 *cmd = tvb_get_uint8(tvb, offset + 6);
420 *len = tvb_get_ntohs(tvb, offset + 12);
422 bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, offset, BCP_BLOCK_HDR_LEN, ett_bcp_blockheader, NULL,
423 "BCP Block Header (%u): Cmd=%s (%u), Len=%u",
424 blocknb,
425 val_to_str_const(*cmd, bcp_cmds, "UNKNOWN"), *cmd,
426 *len
429 proto_tree_add_item(bcp_subtree, hf_bcp_hdr_sourceid, tvb, offset, 2, ENC_BIG_ENDIAN);
430 offset += 2;
431 proto_tree_add_item(bcp_subtree, hf_bcp_hdr_destid, tvb, offset, 2, ENC_BIG_ENDIAN);
432 offset += 2;
433 proto_tree_add_item(bcp_subtree, hf_bcp_hdr_transid, tvb, offset, 2, ENC_BIG_ENDIAN);
434 offset += 2;
435 proto_tree_add_item(bcp_subtree, hf_bcp_hdr_cmd, tvb, offset, 1, ENC_BIG_ENDIAN);
436 offset += 1;
437 proto_tree_add_item(bcp_subtree, hf_bcp_hdr_slavestate, tvb, offset, 1, ENC_BIG_ENDIAN);
438 offset += 1;
439 proto_tree_add_item(bcp_subtree, hf_bcp_hdr_blockflags, tvb, offset, 1, ENC_BIG_ENDIAN);
440 offset += 4;
441 proto_tree_add_item(bcp_subtree, hf_bcp_hdr_len, tvb, offset, 2, ENC_BIG_ENDIAN);
442 offset += 2;
443 proto_tree_add_item(bcp_subtree, hf_bcp_hdr_fragoffset, tvb, offset, 2, ENC_BIG_ENDIAN);
444 offset += 2;
445 proto_tree_add_item(bcp_subtree, hf_bcp_hdr_timestamp, tvb, offset, 8, ENC_BIG_ENDIAN);
446 offset += 8;
447 return offset;
451 * dissector function of protocol header
453 * input: tree, buffer (data), offset (data pointer)
454 * output: flags, block count, segcode from header
455 * return: updated offset
457 static unsigned
458 dissect_bcp_protocol_header(proto_tree *bcp_tree, tvbuff_t *tvb,
459 unsigned offset, int *flags, unsigned *blocknb,
460 unsigned *segcode)
462 proto_tree *bcp_subtree = NULL;
464 *flags = tvb_get_uint8(tvb, offset + 2);
465 *blocknb = tvb_get_uint8(tvb, offset + 3);
466 *segcode = tvb_get_ntohs(tvb, offset + 4);
468 bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, 0, BCP_PROTOCOL_HDR_LEN, ett_bcp_header, NULL,
469 "BCP Protocol Header: BlockNb=%d, SegCode=%d",
470 *blocknb,
471 *segcode);
473 proto_tree_add_item(bcp_subtree, hf_bcp_hdr_version, tvb, offset, 1, ENC_BIG_ENDIAN);
474 offset += 1;
475 proto_tree_add_item(bcp_subtree, hf_bcp_hdr_format, tvb, offset, 1, ENC_BIG_ENDIAN);
476 offset += 1;
477 proto_tree_add_item(bcp_subtree, hf_bcp_hdr_protflags, tvb, offset, 1, ENC_BIG_ENDIAN);
478 offset += 1;
479 proto_tree_add_item(bcp_subtree, hf_bcp_hdr_blocknb, tvb, offset, 1, ENC_BIG_ENDIAN);
480 offset += 1;
481 proto_tree_add_item(bcp_subtree, hf_bcp_hdr_segcode, tvb, offset, 2, ENC_BIG_ENDIAN);
482 offset += 2;
483 proto_tree_add_item(bcp_subtree, hf_bcp_hdr_auth, tvb, offset, 4, ENC_BIG_ENDIAN);
484 offset += 4;
485 return offset;
490 * dissect_bcp - the bcp dissector function
492 static int dissect_bluecom(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
494 unsigned cmd, flags, blocknb;
495 volatile unsigned block;
496 unsigned len;
497 volatile unsigned offset = 0;
498 proto_tree *bcp_tree = NULL;
499 proto_item *bcp_item_base = NULL;
500 tvbuff_t *block_tvb;
501 unsigned segcode = 0;
503 /* set protocol name column */
504 col_set_str(pinfo->cinfo, COL_PROTOCOL, "bluecom");
505 /* clear out stuff in the info column */
506 col_set_str(pinfo->cinfo, COL_INFO, "CMD: ");
508 /* add base item */
509 bcp_item_base = proto_tree_add_item(tree, proto_bcp, tvb, 0, -1, ENC_NA);
510 /* add base tree */
511 bcp_tree = proto_item_add_subtree(bcp_item_base, ett_bcp);
513 /* BCP header */
514 offset = dissect_bcp_protocol_header(bcp_tree, tvb, offset, &flags, &blocknb, &segcode);
516 /* set info column */
517 col_append_fstr(pinfo->cinfo, COL_INFO, "segcode=%u blocks=%u",
518 segcode, blocknb);
520 /* Iterate over blocks */
521 for (block = 0; block < blocknb; block++)
523 /* BCP block header*/
524 offset = dissect_bcp_block_header(bcp_tree, tvb, offset, block, &cmd, &len);
526 /* append text to BCP base */
527 proto_item_append_text(bcp_item_base, ", %s (%u) len=%u",
528 val_to_str_const(cmd, bcp_cmds, "UNKNOWN"), cmd, len);
530 block_tvb = tvb_new_subset_length(tvb, offset, len);
531 TRY {
532 switch (cmd)
534 case BCP_BLK_CMD_SYNC:
535 dissect_bcp_sync_data(bcp_tree, block_tvb);
536 break;
538 case BCP_BLK_CMD_IDENTIFY:
539 dissect_bcp_identify_data(pinfo, bcp_tree, block_tvb);
540 break;
542 case BCP_BLK_CMD_SEARCH:
543 col_append_str(pinfo->cinfo, COL_INFO, REQRSP(flags));
544 dissect_bcp_search_data(pinfo, bcp_tree, block_tvb, flags);
545 break;
547 case BCP_BLK_CMD_CONNECT:
548 col_append_str(pinfo->cinfo, COL_INFO, REQRSP(flags));
549 dissect_bcp_connect_data(pinfo, bcp_tree, block_tvb, flags);
550 break;
552 case BCP_BLK_CMD_DATA:
553 default:
554 dissect_bcp_data(bcp_tree, pinfo, block_tvb, segcode);
555 break;
557 } CATCH_NONFATAL_ERRORS {
559 * Somebody threw an exception that means that there was
560 * a problem dissecting the block. Just show the exception
561 * and then continue to dissect blocks.
563 show_exception(block_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
564 } ENDTRY;
565 offset += len;
568 return offset;
572 * register dissector
574 void
575 proto_register_bluecom(void)
577 static hf_register_info hf_bcp[] = {
578 /* BCP_PROTOCOL_HDR */
579 { &hf_bcp_hdr_version, {
580 "Version", "bluecom.hdr.version", FT_UINT8,
581 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
582 { &hf_bcp_hdr_format, {
583 "Format", "bluecom.hdr.format", FT_UINT8,
584 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
585 { &hf_bcp_hdr_protflags, {
586 "Flags", "bluecom.hdr.protflags", FT_UINT8,
587 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
588 { &hf_bcp_hdr_blocknb, {
589 "BlockNb", "bluecom.hdr.blocknb", FT_UINT8,
590 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
591 { &hf_bcp_hdr_segcode, {
592 "SegCode", "bluecom.hdr.segcode", FT_UINT16,
593 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
594 { &hf_bcp_hdr_auth, {
595 "Auth", "bluecom.hdr.auth", FT_UINT32,
596 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
598 /* BCP_BLOCK_HDR */
599 { &hf_bcp_hdr_sourceid, {
600 "SourceId", "bluecom.hdr.sourceid", FT_UINT16,
601 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
602 { &hf_bcp_hdr_destid, {
603 "DestId", "bluecom.hdr.destid", FT_UINT16,
604 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
605 { &hf_bcp_hdr_transid, {
606 "TransId", "bluecom.hdr.transid", FT_UINT16,
607 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
608 { &hf_bcp_hdr_cmd, {
609 "Cmd", "bluecom.hdr.cmd", FT_UINT8,
610 BASE_HEX, VALS(bcp_cmds), 0, NULL, HFILL }},
611 { &hf_bcp_hdr_slavestate, {
612 "SlaveState", "bluecom.hdr.slavestate", FT_UINT8,
613 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
614 { &hf_bcp_hdr_blockflags, {
615 "Flags", "bluecom.hdr.blockflags", FT_UINT8,
616 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
617 { &hf_bcp_hdr_len, {
618 "Len", "bluecom.hdr.len", FT_UINT16,
619 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
620 { &hf_bcp_hdr_fragoffset, {
621 "FragOffset", "bluecom.hdr.fragoffset", FT_UINT16,
622 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
623 { &hf_bcp_hdr_timestamp, {
624 "Timestamp", "bluecom.hdr.timestamp", FT_ABSOLUTE_TIME,
625 ABSOLUTE_TIME_LOCAL, NULL, 0, NULL, HFILL }},
627 /* BCP_SYNC_DATA */
628 { &hf_bcp_sync_starttime, {
629 "StartTime", "bluecom.sync.blockflags", FT_UINT32,
630 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
631 { &hf_bcp_sync_cycletime, {
632 "CycleTime", "bluecom.sync.cycletime", FT_UINT32,
633 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
634 { &hf_bcp_sync_dataratio, {
635 "DataRatio", "bluecom.sync.dataratio", FT_UINT8,
636 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
637 { &hf_bcp_sync_identify, {
638 "Identify", "bluecom.sync.identify", FT_BOOLEAN,
639 BASE_NONE, NULL, 0, NULL, HFILL }},
640 { &hf_bcp_sync_vlantag, {
641 "VlanTag", "bluecom.sync.vlantag", FT_UINT16,
642 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
643 { &hf_bcp_sync_ethaddr, {
644 "EthAddr", "bluecom.sync.ethaddr", FT_ETHER,
645 BASE_NONE, NULL, 0, NULL, HFILL }},
646 { &hf_bcp_sync_ethaddr2, {
647 "EthAddr2", "bluecom.sync.ethaddr2", FT_ETHER,
648 BASE_NONE, NULL, 0, NULL, HFILL }},
650 /* BCP_IDENTIFY_REQ */
651 { &hf_bcp_identify_error, {
652 "Error", "bluecom.identify.error", FT_UINT32,
653 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
654 { &hf_bcp_identify_starttime, {
655 "StartTime", "bluecom.identify.starttime", FT_UINT32,
656 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
657 { &hf_bcp_identify_ipaddr, {
658 "IpAddr", "bluecom.identify.ipaddr", FT_IPv4,
659 BASE_NONE, NULL, 0, NULL, HFILL }},
660 { &hf_bcp_identify_name, {
661 "Name", "bluecom.identify.name", FT_STRING,
662 BASE_NONE, NULL, 0, NULL, HFILL }},
663 { &hf_bcp_identify_ethaddr, {
664 "EthAddr", "bluecom.identify.ethaddr", FT_ETHER,
665 BASE_NONE, NULL, 0, NULL, HFILL }},
666 { &hf_bcp_identify_ethaddr2, {
667 "EthAddr2", "bluecom.identify.ethaddr2", FT_ETHER,
668 BASE_NONE, NULL, 0, NULL, HFILL }},
670 /* BCP_SEARCH_REQ */
671 { &hf_bcp_searchreq_addrtype, {
672 "AddrType", "bluecom.searchreq.addrtype", FT_UINT32,
673 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
674 { &hf_bcp_searchreq_reserved, {
675 "Reserved", "bluecom.searchreq.reserved", FT_UINT32,
676 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
677 { &hf_bcp_searchreq_name, {
678 "Name", "bluecom.searchreq.name", FT_STRING,
679 BASE_NONE, NULL, 0, NULL, HFILL }},
680 { &hf_bcp_searchreq_ipaddrfirst, {
681 "IpAddrFirst", "bluecom.searchreq.ipaddrfirst", FT_IPv4,
682 BASE_NONE, NULL, 0, NULL, HFILL }},
683 { &hf_bcp_searchreq_ipaddrlast, {
684 "IpAddrLast", "bluecom.searchreq.ipaddrlast", FT_IPv4,
685 BASE_NONE, NULL, 0, NULL, HFILL }},
686 { &hf_bcp_searchreq_addrdata, {
687 "Data", "bluecom.searchreq.addrdata", FT_BYTES,
688 BASE_NONE, NULL, 0, NULL, HFILL }},
690 /* BCP_SEARCH_RSP */
691 { &hf_bcp_searchrsp_error, {
692 "Error", "bluecom.searchrsp.error", FT_UINT32,
693 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
694 { &hf_bcp_searchrsp_starttime, {
695 "StartTime", "bluecom.searchrsp.starttime", FT_UINT32,
696 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
697 { &hf_bcp_searchrsp_lenin, {
698 "LenIn", "bluecom.searchrsp.lenin", FT_UINT16,
699 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
700 { &hf_bcp_searchrsp_lenout, {
701 "LenOut", "bluecom.searchrsp.lenout", FT_UINT16,
702 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
703 { &hf_bcp_searchrsp_ipaddr, {
704 "IpAddr", "bluecom.searchrsp.ipaddr", FT_IPv4,
705 BASE_NONE, NULL, 0, NULL, HFILL }},
706 { &hf_bcp_searchrsp_name, {
707 "Name", "bluecom.searchrsp.name", FT_STRING,
708 BASE_NONE, NULL, 0, NULL, HFILL }},
709 { &hf_bcp_searchrsp_ethaddr, {
710 "EthAddr", "bluecom.searchrsp.ethaddr", FT_ETHER,
711 BASE_NONE, NULL, 0, NULL, HFILL }},
712 { &hf_bcp_searchrsp_ethaddr2, {
713 "EthAddr2", "bluecom.searchrsp.ethaddr2", FT_ETHER,
714 BASE_NONE, NULL, 0, NULL, HFILL }},
716 /* BCP_CONNECT_REQ */
717 { &hf_bcp_connectreq_lenin, {
718 "LenIn", "bluecom.connectreq.lenin", FT_UINT16,
719 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
720 { &hf_bcp_connectreq_lenout, {
721 "LenOut", "bluecom.connectreq.lenout", FT_UINT16,
722 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
723 { &hf_bcp_connectreq_cycletime, {
724 "CycleTime", "bluecom.connectreq.cycletime", FT_UINT32,
725 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
726 { &hf_bcp_connectreq_offlinefactor, {
727 "OfflineFactor", "bluecom.connectreq.offlinefactor", FT_UINT16,
728 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
729 { &hf_bcp_connectreq_ipaddr, {
730 "IpAddr", "bluecom.connectreq.ipaddr", FT_IPv4,
731 BASE_NONE, NULL, 0, NULL, HFILL }},
732 { &hf_bcp_connectreq_name, {
733 "Name", "bluecom.connectreq.name", FT_STRING,
734 BASE_NONE, NULL, 0, NULL, HFILL }},
735 { &hf_bcp_connectreq_ethaddr, {
736 "EthAddr", "bluecom.connectreq.ethaddr", FT_ETHER,
737 BASE_NONE, NULL, 0, NULL, HFILL }},
738 { &hf_bcp_connectreq_ethaddr2, {
739 "EthAddr2", "bluecom.connectreq.ethaddr2", FT_ETHER,
740 BASE_NONE, NULL, 0, NULL, HFILL }},
742 /* BCP_CONNECT_RSP */
743 { &hf_bcp_connectrsp_error, {
744 "Error", "bluecom.connectrsp.error", FT_UINT32,
745 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
746 { &hf_bcp_connectrsp_lenin, {
747 "LenIn", "bluecom.connectrsp.lenin", FT_UINT16,
748 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
749 { &hf_bcp_connectrsp_lenout, {
750 "LenOut", "bluecom.connectrsp.lenout", FT_UINT16,
751 BASE_DEC_HEX, NULL, 0, NULL, HFILL }},
753 /* USERDATA */
754 { &hf_bcp_userdata, {
755 "BCP Userdata", "bluecom.userdata", FT_BYTES,
756 BASE_NONE, NULL, 0, NULL, HFILL }}
759 /* define subtree elements - this is used for behavior of tree display */
760 static int *ett[] = {
761 &ett_bcp,
762 &ett_bcp_header,
763 &ett_bcp_blockheader,
764 &ett_bcp_data,
767 /* register protocol */
768 proto_bcp = proto_register_protocol("bluecom Protocol", "bluecom", "bluecom");
770 /* register elements */
771 proto_register_field_array(proto_bcp, hf_bcp, array_length(hf_bcp));
772 /* register subtree elements */
773 proto_register_subtree_array(ett, array_length(ett));
775 /* register dissector */
776 bcp_handle = register_dissector("bluecom", dissect_bluecom, proto_bcp);
778 /* add dissector table */
779 bcp_subdissector_table = register_dissector_table("bluecomseg", "bluecom SegCode", proto_bcp,
780 FT_UINT8, BASE_DEC);
784 * hand off dissector
786 void
787 proto_reg_handoff_bluecom(void)
789 /* Add dissector handle */
790 dissector_add_uint("ethertype", ETHERTYPE_BLUECOM, bcp_handle);
794 * Editor modelines - https://www.wireshark.org/tools/modelines.html
796 * Local variables:
797 * c-basic-offset: 4
798 * tab-width: 8
799 * indent-tabs-mode: nil
800 * End:
802 * vi: set shiftwidth=4 tabstop=8 expandtab:
803 * :indentSize=4:tabSize=8:noTabs=true: