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
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 */
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 */
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
65 #define BOOLSTR(val) ((val) ? "True" : "False")
66 #define REQRSP(val) ((val & BCP_PROT_FLG_REQ) ? "Request " : "Response ")
69 void proto_reg_handoff_bluecom(void);
70 void proto_register_bluecom(void);
73 static dissector_handle_t bcp_handle
;
74 static dissector_table_t bcp_subdissector_table
;
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" },
156 * dissector function of connect data (request and response)
158 * input: tree, buffer (block data), flags (req or rsp)
162 dissect_bcp_connect_data(packet_info
*pinfo
, proto_tree
*bcp_tree
, tvbuff_t
*tvb
, int flags
)
164 proto_tree
*bcp_subtree
= NULL
;
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
);
178 proto_tree_add_item(bcp_subtree
, hf_bcp_connectreq_lenout
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
180 proto_tree_add_item(bcp_subtree
, hf_bcp_connectreq_cycletime
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
182 proto_tree_add_item(bcp_subtree
, hf_bcp_connectreq_offlinefactor
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
184 proto_tree_add_item(bcp_subtree
, hf_bcp_connectreq_ipaddr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
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
);
205 proto_tree_add_item(bcp_subtree
, hf_bcp_connectrsp_lenin
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
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)
218 dissect_bcp_search_data(packet_info
*pinfo
, proto_tree
*bcp_tree
, tvbuff_t
*tvb
, int flags
)
220 proto_tree
*bcp_subtree
= NULL
;
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
);
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)
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
)
247 bcp_subtree
= proto_tree_add_subtree_format(bcp_tree
, tvb
, offset
, len
, ett_bcp_data
, NULL
,
248 "BCP Search Request: Unknown AddrType");
252 proto_tree_add_item(bcp_subtree
, hf_bcp_searchreq_addrtype
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
254 proto_tree_add_item(bcp_subtree
, hf_bcp_searchreq_reserved
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
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
);
264 case BCP_SEARCH_NAME
:
265 proto_tree_add_item(bcp_subtree
, hf_bcp_searchreq_name
, tvb
, offset
, BCP_NAME_LEN
, ENC_ASCII
);
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
);
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
);
287 proto_tree_add_item(bcp_subtree
, hf_bcp_searchrsp_starttime
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
289 proto_tree_add_item(bcp_subtree
, hf_bcp_searchrsp_lenin
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
291 proto_tree_add_item(bcp_subtree
, hf_bcp_searchrsp_lenout
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
293 proto_tree_add_item(bcp_subtree
, hf_bcp_searchrsp_ipaddr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
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)
313 dissect_bcp_identify_data(packet_info
*pinfo
, proto_tree
*bcp_tree
, tvbuff_t
*tvb
)
315 proto_tree
*bcp_subtree
= NULL
;
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
);
328 proto_tree_add_item(bcp_subtree
, hf_bcp_identify_starttime
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
330 proto_tree_add_item(bcp_subtree
, hf_bcp_identify_ipaddr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
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)
349 dissect_bcp_sync_data(proto_tree
*bcp_tree
, tvbuff_t
*tvb
)
351 proto_tree
*bcp_subtree
= NULL
;
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
);
361 proto_tree_add_item(bcp_subtree
, hf_bcp_sync_cycletime
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
363 proto_tree_add_item(bcp_subtree
, hf_bcp_sync_dataratio
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
365 proto_tree_add_item(bcp_subtree
, hf_bcp_sync_identify
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
367 proto_tree_add_item(bcp_subtree
, hf_bcp_sync_vlantag
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
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)
386 dissect_bcp_data(proto_tree
*bcp_tree
, packet_info
*pinfo
, tvbuff_t
*tvb
,
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
);
396 /* Call the sub-dissector. */
397 call_dissector(handle
, tvb
, pinfo
, bcp_tree
);
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
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",
425 val_to_str_const(*cmd
, bcp_cmds
, "UNKNOWN"), *cmd
,
429 proto_tree_add_item(bcp_subtree
, hf_bcp_hdr_sourceid
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
431 proto_tree_add_item(bcp_subtree
, hf_bcp_hdr_destid
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
433 proto_tree_add_item(bcp_subtree
, hf_bcp_hdr_transid
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
435 proto_tree_add_item(bcp_subtree
, hf_bcp_hdr_cmd
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
437 proto_tree_add_item(bcp_subtree
, hf_bcp_hdr_slavestate
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
439 proto_tree_add_item(bcp_subtree
, hf_bcp_hdr_blockflags
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
441 proto_tree_add_item(bcp_subtree
, hf_bcp_hdr_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
443 proto_tree_add_item(bcp_subtree
, hf_bcp_hdr_fragoffset
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
445 proto_tree_add_item(bcp_subtree
, hf_bcp_hdr_timestamp
, tvb
, offset
, 8, ENC_BIG_ENDIAN
);
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
458 dissect_bcp_protocol_header(proto_tree
*bcp_tree
, tvbuff_t
*tvb
,
459 unsigned offset
, int *flags
, unsigned *blocknb
,
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",
473 proto_tree_add_item(bcp_subtree
, hf_bcp_hdr_version
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
475 proto_tree_add_item(bcp_subtree
, hf_bcp_hdr_format
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
477 proto_tree_add_item(bcp_subtree
, hf_bcp_hdr_protflags
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
479 proto_tree_add_item(bcp_subtree
, hf_bcp_hdr_blocknb
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
481 proto_tree_add_item(bcp_subtree
, hf_bcp_hdr_segcode
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
483 proto_tree_add_item(bcp_subtree
, hf_bcp_hdr_auth
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
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
;
497 volatile unsigned offset
= 0;
498 proto_tree
*bcp_tree
= NULL
;
499 proto_item
*bcp_item_base
= NULL
;
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: ");
509 bcp_item_base
= proto_tree_add_item(tree
, proto_bcp
, tvb
, 0, -1, ENC_NA
);
511 bcp_tree
= proto_item_add_subtree(bcp_item_base
, ett_bcp
);
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",
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
);
534 case BCP_BLK_CMD_SYNC
:
535 dissect_bcp_sync_data(bcp_tree
, block_tvb
);
538 case BCP_BLK_CMD_IDENTIFY
:
539 dissect_bcp_identify_data(pinfo
, bcp_tree
, block_tvb
);
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
);
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
);
552 case BCP_BLK_CMD_DATA
:
554 dissect_bcp_data(bcp_tree
, pinfo
, block_tvb
, segcode
);
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
);
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
}},
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
}},
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
}},
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
}},
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
}},
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
}},
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
}},
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
[] = {
763 &ett_bcp_blockheader
,
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
,
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
799 * indent-tabs-mode: nil
802 * vi: set shiftwidth=4 tabstop=8 expandtab:
803 * :indentSize=4:tabSize=8:noTabs=true: