2 * Routines for Ether-S-I/O dissection (from Saia Burgess Controls AG )
3 * Copyright 2010, Christian Durrer <christian.durrer@sensemail.ch>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include <epan/packet.h>
30 #include <epan/expert.h>
33 #define ESIO_TRANSFER 0x01
34 #define ESIO_STATUS 0x02
36 void proto_register_esio(void);
37 void proto_reg_handoff_esio(void);
39 /* Initialize the protocol and registered fields */
40 static int proto_esio
= -1;
41 static int hf_esio_type
= -1;
42 static int hf_esio_version
= -1;
43 static int hf_esio_length
= -1;
44 static int hf_esio_transaction_id
= -1;
45 static int hf_esio_tlg_id
= -1;
46 static int hf_esio_src_stn_id
= -1;
47 static int hf_esio_data_nbr
= -1;
48 static int hf_esio_data_flags
= -1;
49 static int hf_esio_data_transfer_id
= -1;
50 static int hf_esio_data_dest_id
= -1;
51 static int hf_esio_data_length
= -1;
52 static int hf_esio_data
= -1;
53 static int hf_esio_sts_type
= -1;
54 static int hf_esio_sts_size
= -1;
55 static int hf_esio_rio_sts
= -1;
56 static int hf_esio_rio_tlgs_lost
= -1;
57 static int hf_esio_rio_diag
= -1;
58 static int hf_esio_rio_flags
= -1;
60 /* Initialize the subtree pointers */
61 static gint ett_esio
= -1;
62 static gint ett_esio_header
= -1;
63 static gint ett_esio_transfer_header
= -1;
64 static gint ett_esio_transfer_data
= -1;
65 static gint ett_esio_data
= -1;
67 static expert_field ei_esio_telegram_lost
= EI_INIT
;
69 /* value to string definitions*/
70 /* Ether-S-I/O telegram types*/
71 static const value_string esio_tlg_types
[] = {
73 {1, "Data transfer telegram"},
74 {2, "Status/Diag telegram"},
78 /* Status telegram types*/
79 static const value_string esio_sts_types
[] = {
85 /* check whether the packet looks like SBUS or not */
87 is_esio_pdu(tvbuff_t
*tvb
)
89 /* we need at least 8 bytes to determine whether this is
91 /* minimal length is 20 bytes*/
92 if (tvb_length(tvb
) < 20) {
95 /* First four bytes must be "ESIO"*/
96 if (tvb_strneql(tvb
, 0, "ESIO", 4) != 0) {
99 /* fifth byte must be 0*/
100 if (tvb_get_guint8(tvb
, 4) > 0x00) {
103 /* sixth byte indicates telegram type and must be 0, 1 or 2*/
104 if (tvb_get_guint8(tvb
, 5) > 0x02) {
107 /* seventh byte must be 0*/
108 if (tvb_get_guint8(tvb
, 6) > 0x00) {
111 /* eight byte indicates telegram version and must be 0 (up to now)*/
112 if (tvb_get_guint8(tvb
, 7) > 0x00) {
115 /*header seems to be Ether-S-I/O*/
119 /*Dissect the telegram*/
121 dissect_esio(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
124 /* Set up structures needed to add the protocol subtree and manage it */
126 proto_tree
*esio_tree
, *esio_header_tree
, *esio_transfer_header_tree
,
127 *esio_data_tansfer_tree
, *esio_data_tree
;
131 guint8 esio_nbr_data_transfers
;
132 guint16 esio_telegram_type
;
133 guint16 esio_tlg_type
;
134 guint16 esio_transfer_length
;
135 guint32 esio_transfer_dest_id
;
139 /* does this look like an sbus pdu? */
140 if (!is_esio_pdu(tvb
)) {
144 /* Make entries in Protocol column and Info column on summary display */
145 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ESIO");
146 col_clear(pinfo
->cinfo
, COL_INFO
);
147 esio_telegram_type
= tvb_get_guint8(tvb
,5);
149 switch (esio_telegram_type
) {
151 esio_src_id
= tvb_get_ntohl(tvb
,16);
152 esio_nbr_data_transfers
= tvb_get_guint8(tvb
, 20);
153 esio_dst_id
= tvb_get_ntohl(tvb
,26);
154 col_add_fstr( pinfo
->cinfo
, COL_INFO
,
155 "Data transfer: Src ID: %d, Dst ID(s): %d",
156 esio_src_id
, esio_dst_id
);
157 if (esio_nbr_data_transfers
> 1) {
158 col_append_str( pinfo
->cinfo
, COL_INFO
,
163 esio_src_id
= tvb_get_ntohl(tvb
,16);
164 col_add_fstr( pinfo
->cinfo
, COL_INFO
,
165 "Status/diag telegram: Src ID: %d",
169 /* All other telegrams */
170 col_set_str( pinfo
->cinfo
, COL_INFO
,
175 /* create display subtree for the protocol */
177 ti
= proto_tree_add_item(tree
, proto_esio
, tvb
, offset
, -1, ENC_NA
);
178 esio_tree
= proto_item_add_subtree(ti
, ett_esio
);
179 /*Add subtree for Ether-S-I/O header*/
180 et
= proto_tree_add_text(esio_tree
, tvb
, offset
, 12, "Ether-S-I/O header");
181 esio_header_tree
= proto_item_add_subtree(et
, ett_esio_header
);
182 offset
+= 4; /*first four bytes are "ESIO"*/
183 /* add items to the Ether-S-I/O header subtree*/
184 esio_tlg_type
= tvb_get_ntohs(tvb
,offset
);
185 proto_tree_add_item(esio_header_tree
,
186 hf_esio_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
188 proto_tree_add_item(esio_header_tree
,
189 hf_esio_version
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
191 proto_tree_add_item(esio_header_tree
,
192 hf_esio_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
194 proto_tree_add_item(esio_header_tree
,
195 hf_esio_transaction_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
197 switch (esio_tlg_type
) {
200 /*Add subtree for Ether-S-I/O header*/
201 et
= proto_tree_add_text(esio_tree
, tvb
, offset
, 12, "Transfer header");
202 esio_transfer_header_tree
= proto_item_add_subtree(et
, ett_esio_transfer_header
);
203 proto_tree_add_item(esio_transfer_header_tree
,
204 hf_esio_tlg_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
206 proto_tree_add_item(esio_transfer_header_tree
,
207 hf_esio_src_stn_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
209 esio_nbr_data_transfers
= tvb_get_guint8(tvb
,offset
);
210 proto_tree_add_item(esio_transfer_header_tree
,
211 hf_esio_data_nbr
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
213 proto_tree_add_item(esio_transfer_header_tree
,
214 hf_esio_data_flags
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
216 for (i
=((esio_nbr_data_transfers
)); i
>0; i
--) {
217 /*Add subtree(s) for Ether-S-I/O data transfers*/
218 esio_transfer_dest_id
= tvb_get_ntohl(tvb
,(offset
+4));
219 esio_transfer_length
= tvb_get_ntohs(tvb
,(offset
+8));
220 et
= proto_tree_add_text(esio_tree
, tvb
, offset
,
221 (esio_transfer_length
+ 10), "Data transfer to ID: %d ",
222 esio_transfer_dest_id
);
223 esio_data_tansfer_tree
= proto_item_add_subtree(et
, ett_esio_transfer_data
);
224 proto_tree_add_item(esio_data_tansfer_tree
,
225 hf_esio_data_transfer_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
227 proto_tree_add_item(esio_data_tansfer_tree
,
228 hf_esio_data_dest_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
230 proto_tree_add_item(esio_data_tansfer_tree
,
231 hf_esio_data_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
233 /*here comes the data*/
234 et
= proto_tree_add_text(esio_data_tansfer_tree
, tvb
, offset
,
235 esio_transfer_length
, "Data bytes ");
236 esio_data_tree
= proto_item_add_subtree(et
, ett_esio_data
);
237 for (i
=((esio_transfer_length
)); i
>0; i
--) {
238 proto_tree_add_item(esio_data_tree
,
239 hf_esio_data
, tvb
, offset
,
247 proto_item
*hi
= NULL
;
249 proto_tree_add_item(esio_tree
,
250 hf_esio_sts_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
251 proto_tree_add_item(esio_tree
,
252 hf_esio_sts_size
, tvb
, offset
+2, 2, ENC_BIG_ENDIAN
);
253 proto_tree_add_item(esio_tree
,
254 hf_esio_src_stn_id
, tvb
, offset
+4, 4, ENC_BIG_ENDIAN
);
255 proto_tree_add_item(esio_tree
,
256 hf_esio_rio_sts
, tvb
, offset
+8,
258 hi
= proto_tree_add_item(esio_tree
,
259 hf_esio_rio_tlgs_lost
, tvb
, offset
+9,
261 proto_tree_add_item(esio_tree
,
262 hf_esio_rio_diag
, tvb
, offset
+10,
264 proto_tree_add_item(esio_tree
,
265 hf_esio_rio_flags
, tvb
, offset
+11, 1, ENC_BIG_ENDIAN
);
267 if (tvb_get_guint8(tvb
, offset
+ 9) > 0) {
268 expert_add_info(pinfo
, hi
, &ei_esio_telegram_lost
);
276 return tvb_length(tvb
);
277 /*End of dissect_sbus*/
280 /* Register the protocol with Wireshark */
282 proto_register_esio(void)
284 /* Setup list of header fields See Section 1.6.1 for details*/
285 static hf_register_info hf
[] = {
287 { "Telegram type", "esio.type",
288 FT_UINT16
, BASE_HEX
, VALS(esio_tlg_types
), 0,
293 { "Version", "esio.vers",
294 FT_UINT16
, BASE_DEC
, NULL
, 0,
299 { "Length (bytes)", "esio.len",
300 FT_UINT16
, BASE_DEC
, NULL
, 0,
304 { &hf_esio_transaction_id
,
305 { "Transaction ID", "esio.transaction_id",
306 FT_UINT16
, BASE_DEC
, NULL
, 0,
310 { &hf_esio_src_stn_id
,
311 { "Source station ID", "esio.src_stn_id",
312 FT_UINT32
, BASE_DEC
, NULL
, 0,
317 { "Telegram ID", "esio.transfer.tlg_id",
318 FT_UINT32
, BASE_DEC
, NULL
, 0,
323 { "Nbr. of data transfers", "esio.data.nbr",
324 FT_UINT8
, BASE_DEC
, NULL
, 0,
328 { &hf_esio_data_flags
,
329 { "Transfer header flags", "esio.data.flags",
330 FT_UINT8
, BASE_HEX
, NULL
, 0,
334 { &hf_esio_data_transfer_id
,
335 { "Data transfer ID", "esio.data.transfer_id",
336 FT_UINT32
, BASE_DEC
, NULL
, 0,
340 { &hf_esio_data_dest_id
,
341 { "Data destination ID", "esio.data.destination_id",
342 FT_UINT32
, BASE_DEC
, NULL
, 0,
346 { &hf_esio_data_length
,
347 { "Data transfer length", "esio.data.length",
348 FT_UINT16
, BASE_DEC
, NULL
, 0,
353 { "Data", "esio.data",
354 FT_UINT8
, BASE_DEC
, NULL
, 0,
359 { "Status type", "esio.sts.type",
360 FT_UINT16
, BASE_HEX
, VALS(esio_sts_types
), 0,
365 { "Status length (bytes)", "esio.sts.length",
366 FT_UINT16
, BASE_DEC
, NULL
, 0,
371 { "RIO status", "esio.sts.rio_sts",
372 FT_UINT8
, BASE_DEC
, NULL
, 0,
376 { &hf_esio_rio_tlgs_lost
,
377 { "Lost telegrams to RIO", "esio.sts.rio_lost_tlg",
378 FT_UINT8
, BASE_DEC
, NULL
, 0,
383 { "RIO diagnostics", "esio.sts.rio_diag",
384 FT_UINT8
, BASE_DEC
, NULL
, 0,
388 { &hf_esio_rio_flags
,
389 { "RIO flags", "esio.sts.rio_flags",
390 FT_UINT8
, BASE_HEX
, NULL
, 0,
396 /* Setup protocol subtree array */
397 static gint
*ett
[] = {
400 &ett_esio_transfer_header
,
401 &ett_esio_transfer_data
,
405 static ei_register_info ei
[] = {
406 { &ei_esio_telegram_lost
, { "esio.telegram_lost", PI_SEQUENCE
, PI_NOTE
, "Telegram(s) lost", EXPFILL
}},
409 expert_module_t
* expert_esio
;
411 /* Register the protocol name and description */
412 proto_esio
= proto_register_protocol("SAIA Ether-S-I/O protocol", "ESIO", "esio");
414 /* Required function calls to register the header fields and subtrees used */
415 proto_register_field_array(proto_esio
, hf
, array_length(hf
));
416 proto_register_subtree_array(ett
, array_length(ett
));
417 expert_esio
= expert_register_protocol(proto_esio
);
418 expert_register_field_array(expert_esio
, ei
, array_length(ei
));
422 proto_reg_handoff_esio(void)
424 dissector_handle_t esio_handle
;
426 esio_handle
= new_create_dissector_handle(dissect_esio
, proto_esio
);
427 dissector_add_uint("udp.port", 6060, esio_handle
);
436 * indent-tabs-mode: nil
439 * ex: set shiftwidth=7 tabstop=8 expandtab:
440 * :indentSize=7:tabSize=8:noTabs=true: