1 /* packet-ethercat-datagram.c
2 * Routines for ethercat packet disassembly
6 * Copyright (c) 2007 by Beckhoff Automation GmbH
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
41 #include <epan/packet.h>
42 #include <epan/addr_resolv.h>
43 #include <epan/strutil.h>
45 #include "packet-ethercat-datagram.h"
46 #include "packet-ecatmb.h"
48 static heur_dissector_list_t heur_subdissector_list;
49 static dissector_handle_t ecat_mailbox_handle;
51 /* Define the EtherCAT proto */
52 static int proto_ecat_datagram = -1;
54 /* Define the tree for EtherCAT */
55 static int ett_ecat = -1;
56 static int ett_ecat_header = -1;
57 static int ett_ecat_syncman = -1;
58 static int ett_ecat_syncflag = -1;
59 static int ett_ecat_fmmu = -1;
60 static int ett_ecat_fmmu_type = -1;
61 static int ett_ecat_fmmu_active = -1;
62 static int ett_ecat_dc = -1;
63 static int ett_ecat_length = -1;
64 static int ett_ecat_padding = -1;
65 static int ett_ecat_datagram_subtree = -1;
67 static int hf_ecat_sub;
68 static int hf_ecat_sub_data[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
69 static int hf_ecat_sub_cmd[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
70 static int hf_ecat_sub_idx[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
71 static int hf_ecat_sub_cnt[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
72 static int hf_ecat_sub_ado[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
73 static int hf_ecat_sub_adp[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
74 static int hf_ecat_sub_lad[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
76 static int hf_ecat_header = -1;
77 static int hf_ecat_data = -1;
78 static int hf_ecat_cnt = -1;
79 static int hf_ecat_cmd = -1;
80 static int hf_ecat_idx = -1;
81 static int hf_ecat_adp = -1;
82 static int hf_ecat_ado = -1;
83 static int hf_ecat_lad = -1;
84 static int hf_ecat_len = -1;
85 static int hf_ecat_int = -1;
86 static int hf_ecat_syncman = -1;
87 static int hf_ecat_syncman_start = -1;
88 static int hf_ecat_syncman_len = -1;
89 static int hf_ecat_syncman_flags = -1;
90 static int hf_ecat_syncman_flag0 = -1;
91 static int hf_ecat_syncman_flag1 = -1;
92 static int hf_ecat_syncman_flag2 = -1;
93 static int hf_ecat_syncman_flag4 = -1;
94 static int hf_ecat_syncman_flag5 = -1;
95 static int hf_ecat_syncman_flag8 = -1;
96 static int hf_ecat_syncman_flag9 = -1;
97 static int hf_ecat_syncman_flag10 = -1;
98 static int hf_ecat_syncman_flag11 = -1;
99 static int hf_ecat_syncman_flag12 = -1;
100 static int hf_ecat_syncman_flag13 = -1;
101 static int hf_ecat_syncman_flag16 = -1;
102 static int hf_ecat_fmmu = -1;
103 static int hf_ecat_fmmu_lstart = -1;
104 static int hf_ecat_fmmu_llen = -1;
105 static int hf_ecat_fmmu_lstartbit = -1;
106 static int hf_ecat_fmmu_lendbit = -1;
107 static int hf_ecat_fmmu_pstart = -1;
108 static int hf_ecat_fmmu_pstartbit = -1;
109 static int hf_ecat_fmmu_type = -1;
110 static int hf_ecat_fmmu_typeread = -1;
111 static int hf_ecat_fmmu_typewrite = -1;
112 static int hf_ecat_fmmu_active = -1;
113 static int hf_ecat_fmmu_active0 = -1;
115 static int hf_ecat_sub_dc_diff_da[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
116 static int hf_ecat_sub_dc_diff_bd[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
117 static int hf_ecat_sub_dc_diff_cb[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
118 static int hf_ecat_sub_dc_diff_cd[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
119 static int hf_ecat_sub_dc_diff_ba[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
120 static int hf_ecat_sub_dc_diff_ca[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
122 static int hf_ecat_dc_diff_da = -1;
123 static int hf_ecat_dc_diff_bd = -1;
124 static int hf_ecat_dc_diff_cb = -1;
125 static int hf_ecat_dc_diff_cd = -1;
126 static int hf_ecat_dc_diff_ba = -1;
127 static int hf_ecat_dc_diff_ca = -1;
129 static int hf_ecat_length_len = -1;
130 static int hf_ecat_length_r = -1;
131 static int hf_ecat_length_c = -1;
132 static int hf_ecat_length_m = -1;
134 static int hf_ecat_padding = -1;
136 static const value_string EcCmdShort[] =
157 static const value_string EcCmdLong[] =
159 { 0, "No operation" },
160 { 1, "Auto increment read" },
161 { 2, "Auto increment write" },
162 { 3, "Auto increment read write" },
163 { 4, "Configured address read" },
164 { 5, "Configured address write" },
165 { 6, "Configured address read write" },
166 { 7, "Broadcast read" },
167 { 8, "Broadcast write" },
168 { 9, "Broadcast read write" },
169 { 10, "Logical memory read" },
170 { 11, "Logical memory write" },
171 { 12, "Logical memory read write" },
172 { 13, "Auto increment read multiple write" },
173 { 14, "Configured read multiple write" },
178 static const value_string ecat_subframe_reserved_vals[] =
184 static const value_string ecat_subframe_circulating_vals[] =
186 { 0, "Frame is not circulating" },
187 { 1, "Frame has circulated once" },
191 static const value_string ecat_subframe_more_vals[] =
193 { 0, "Last EtherCAT datagram"},
194 { 1, "More EtherCAT datagrams will follow"},
198 static const true_false_string tfs_ecat_fmmu_typeread =
200 "Read in use", "Read ignore"
203 static const true_false_string tfs_ecat_fmmu_typewrite =
205 "Write in use", "Write ignore"
208 static const true_false_string tfs_ecat_fmmu_active =
210 "Enabled", "Disabled"
213 static const true_false_string tfs_ecat_syncman_flag0 =
215 "OPMODE xx", "OPMODE xx"
218 static const true_false_string tfs_ecat_syncman_flag1 =
220 "00: 3-Buf, 01: 3-Buf (Mon.), 10: 1-Buf", "00: 3-Buf, 01: 3-Buf (Mon.), 10: 1-Buf",
223 static const true_false_string tfs_ecat_syncman_flag2 =
228 static const true_false_string tfs_ecat_syncman_flag4 =
230 "IRQ ECAT enabled", "IRQ ECAT disabled"
233 static const true_false_string tfs_ecat_syncman_flag5 =
235 "IRQ PDI enabled", "IRQ PDI disabled"
238 static const true_false_string tfs_ecat_syncman_flag8 =
240 "IRQ Write 1", "IRQ Write 0"
243 static const true_false_string tfs_ecat_syncman_flag9 =
245 "IRQ Read 1", "IRQ Read 0"
248 static const true_false_string tfs_ecat_syncman_flag10 =
250 "Watchdog", "No Watchdog"
253 static const true_false_string tfs_ecat_syncman_flag11 =
255 "1-Buf written", "1-Buf read"
258 static const true_false_string tfs_ecat_syncman_flag12 =
260 "Buffer Status xx", "Buffer Status xx"
263 static const true_false_string tfs_ecat_syncman_flag13 =
265 "00: 1.Buf, 01: 2.Buf, 10: 3.Buf", "00: 1.Buf, 01: 2.Buf, 10: 3.Buf"
268 static const true_false_string tfs_ecat_syncman_flag16 =
270 "SyncMan enabled", "SyncMan disabled",
273 static const char* convertEcCmdToText(int cmd, const value_string ec_cmd[])
275 return val_to_str(cmd, ec_cmd, "<UNKNOWN: %d>");
278 #define ENDOF(p) ((p)+1) /* pointer to end of *p*/
283 EC_CMD_TYPE_APRD = 1,
284 EC_CMD_TYPE_APWR = 2,
285 EC_CMD_TYPE_APRW = 3,
286 EC_CMD_TYPE_FPRD = 4,
287 EC_CMD_TYPE_FPWR = 5,
288 EC_CMD_TYPE_FPRW = 6,
292 EC_CMD_TYPE_LRD = 10,
293 EC_CMD_TYPE_LWR = 11,
294 EC_CMD_TYPE_LRW = 12,
295 EC_CMD_TYPE_ARMW = 13,
296 EC_CMD_TYPE_FRMW = 14,
297 EC_CMD_TYPE_EXT = 255
300 static void init_EcParserHDR(EcParserHDR* pHdr, tvbuff_t *tvb, gint offset)
302 pHdr->cmd = tvb_get_guint8(tvb, offset++);
303 pHdr->idx = tvb_get_guint8(tvb, offset++);
304 pHdr->anAddrUnion.a.adp = tvb_get_letohs(tvb, offset); offset+=sizeof(guint16);
305 pHdr->anAddrUnion.a.ado = tvb_get_letohs(tvb, offset); offset+=sizeof(guint16);
306 pHdr->len = tvb_get_letohs(tvb, offset); offset+=sizeof(guint16);
307 pHdr->intr = tvb_get_letohs(tvb, offset);
310 static void init_dc_measure(guint32* pDC, tvbuff_t *tvb, gint offset)
313 for ( i=0; i<4; i++ )
315 pDC[i] = tvb_get_letohl(tvb, offset);
316 offset+=sizeof(guint32);
320 static guint16 get_wc(EcParserHDR* pHdr, tvbuff_t *tvb, gint offset)
322 return tvb_get_letohs(tvb, offset+EcParserHDR_Len+(pHdr->len&0x07ff));
325 static guint16 get_cmd_len(EcParserHDR* pHdr)
327 return (EcParserHDR_Len+(pHdr->len&0x07ff)+sizeof(guint16)); /*Header + data + wc*/
331 static void EcSummaryFormater(guint32 datalength, tvbuff_t *tvb, gint offset, char *szText, gint nMax)
338 EcParserHDR ecParser;
342 init_EcParserHDR(&ecFirst, tvb, offset);
344 while ( suboffset < datalength )
346 PEcParserHDR pEcParser;
349 init_EcParserHDR(&ecParser, tvb, offset+suboffset);
350 pEcParser = &ecParser;
353 pEcParser = &ecFirst;
357 nCmds[nSub] = pEcParser->cmd;
358 nLens[nSub] = pEcParser->len&0x07ff;
361 nLen += (pEcParser->len&0x07ff);
362 /* bit 14 -- roundtrip */
364 if ( (pEcParser->len&0x8000) == 0 )
367 suboffset+=get_cmd_len(pEcParser);
371 guint16 len = ecFirst.len&0x07ff;
372 guint16 cnt = get_wc(&ecFirst, tvb, offset);
373 g_snprintf ( szText, nMax, "'%s': Len: %d, Adp 0x%x, Ado 0x%x, Wc %d ",
374 convertEcCmdToText(ecFirst.cmd, EcCmdShort), len, ecFirst.anAddrUnion.a.adp, ecFirst.anAddrUnion.a.ado, cnt );
376 else if ( nSub == 2 )
378 g_snprintf ( szText, nMax, "%d Cmds, '%s': len %d, '%s': len %d ",
379 nSub, convertEcCmdToText(nCmds[0], EcCmdShort), nLens[0], convertEcCmdToText(nCmds[1], EcCmdShort), nLens[1]);
381 else if ( nSub == 3 )
383 g_snprintf ( szText, nMax, "%d Cmds, '%s': len %d, '%s': len %d, '%s': len %d",
384 nSub, convertEcCmdToText(nCmds[0], EcCmdShort), nLens[0], convertEcCmdToText(nCmds[1], EcCmdShort), nLens[1], convertEcCmdToText(nCmds[2], EcCmdShort), nLens[2]);
386 else if ( nSub == 4 )
388 g_snprintf ( szText, nMax, "%d Cmds, '%s': len %d, '%s': len %d, '%s': len %d, '%s': len %d",
389 nSub, convertEcCmdToText(nCmds[0], EcCmdShort), nLens[0], convertEcCmdToText(nCmds[1], EcCmdShort), nLens[1], convertEcCmdToText(nCmds[2], EcCmdShort), nLens[2], convertEcCmdToText(nCmds[3], EcCmdShort), nLens[3]);
392 g_snprintf ( szText, nMax, "%d Cmds, SumLen %d, '%s'... ",
393 nSub, nLen, convertEcCmdToText(ecFirst.cmd, EcCmdShort));
396 static void EcSubFormatter(tvbuff_t *tvb, gint offset, char *szText, gint nMax)
398 EcParserHDR ecParser;
401 init_EcParserHDR(&ecParser, tvb, offset);
402 len = ecParser.len&0x07ff;
403 cnt = get_wc(&ecParser, tvb, offset);
405 switch ( ecParser.cmd )
407 case EC_CMD_TYPE_NOP:
408 case EC_CMD_TYPE_APRD:
409 case EC_CMD_TYPE_APWR:
410 case EC_CMD_TYPE_APRW:
411 case EC_CMD_TYPE_FPRD:
412 case EC_CMD_TYPE_FPWR:
413 case EC_CMD_TYPE_FPRW:
414 case EC_CMD_TYPE_BRD:
415 case EC_CMD_TYPE_BWR:
416 case EC_CMD_TYPE_BRW:
417 case EC_CMD_TYPE_ARMW:
418 case EC_CMD_TYPE_FRMW:
419 g_snprintf ( szText, nMax, "EtherCAT datagram: Cmd: '%s' (%d), Len: %d, Adp 0x%x, Ado 0x%x, Cnt %d",
420 convertEcCmdToText(ecParser.cmd, EcCmdShort), ecParser.cmd, len, ecParser.anAddrUnion.a.adp, ecParser.anAddrUnion.a.ado, cnt);
422 case EC_CMD_TYPE_LRD:
423 case EC_CMD_TYPE_LWR:
424 case EC_CMD_TYPE_LRW:
425 g_snprintf ( szText, nMax, "EtherCAT datagram: Cmd: '%s' (%d), Len: %d, Addr 0x%x, Cnt %d",
426 convertEcCmdToText(ecParser.cmd, EcCmdShort), ecParser.cmd, len, ecParser.anAddrUnion.addr, cnt);
428 case EC_CMD_TYPE_EXT:
429 g_snprintf ( szText, nMax, "EtherCAT datagram: Cmd: 'EXT' (%d), Len: %d", ecParser.cmd, len);
432 g_snprintf ( szText, nMax, "EtherCAT datagram: Cmd: 'Unknown' (%d), Len: %d", ecParser.cmd, len);
436 /* Ethercat Datagram */
437 static void dissect_ecat_datagram(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
440 proto_item *ti, *aitem = NULL;
441 proto_tree *ecat_datagrams_tree = NULL;
444 int nMax = sizeof(szText)-1;
449 const guint datagram_length = tvb_length_remaining(tvb, offset);
450 guint datagram_padding_bytes = 0;
453 if (check_col(pinfo->cinfo, COL_PROTOCOL))
454 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ECAT");
456 if (check_col(pinfo->cinfo, COL_INFO))
457 col_clear(pinfo->cinfo, COL_INFO);
459 /* If the data portion of an EtherCAT datagram is less than 44 bytes, then
460 it must have been padded with an additional n number of bytes to reach a
461 total Ethernet frame length of 64 bytes (Ethernet header + Ethernet Data +
462 FCS). Hence at least 44 bytes data shall always be available in any
463 EtherCAT datagram. */
464 /* tvb_ensure_bytes_exist(tvb, offset, 44);
465 this is not correct, because the frame might have been captured before the
466 os added the padding bytes. E.g. in Windows the frames are captured on the
467 protocol layer. When another protocol driver sends a frame this frame does
468 not include the padding bytes.
471 /* Count the length of the individual EtherCAT datagrams (sub datagrams)
472 that are part of this EtherCAT frame. Stop counting when the current
473 sub datagram header tells that there are no more sub datagrams or when
474 there is no more data available in the PDU. */
477 init_EcParserHDR(&ecHdr, tvb, ecLength);
478 ecLength += get_cmd_len(&ecHdr);
479 } while ((ecLength < datagram_length) &&
480 (ecHdr.len & 0x8000));
482 /* Calculate the amount of padding data available in the PDU */
483 datagram_padding_bytes = datagram_length - ecLength;
485 EcSummaryFormater(ecLength, tvb, offset, szText, nMax);
486 if (check_col(pinfo->cinfo, COL_INFO))
487 col_append_str(pinfo->cinfo, COL_INFO, szText);
491 /* Create the EtherCAT datagram(s) subtree */
492 ti = proto_tree_add_item(tree, proto_ecat_datagram, tvb, 0, -1, TRUE);
493 ecat_datagrams_tree = proto_item_add_subtree(ti, ett_ecat);
495 proto_item_append_text(ti,": %s", szText);
498 /* Dissect all sub frames of this EtherCAT PDU */
501 proto_tree *ecat_datagram_tree = NULL, *ecat_header_tree = NULL, *ecat_fmmu_tree = NULL,
502 *ecat_fmmu_active_tree = NULL, *ecat_fmmu_type_tree = NULL, *ecat_syncman_tree = NULL,
503 *ecat_syncflag_tree = NULL, *ecat_dc_tree = NULL;
504 proto_item *hidden_item;
510 ETHERCAT_MBOX_HEADER mbox;
513 init_EcParserHDR(&ecHdr, tvb, suboffset);
515 subsize = get_cmd_len(&ecHdr);
516 len = ecHdr.len & 0x07ff;
518 if ( len >= sizeof(ETHERCAT_MBOX_HEADER_LEN) &&
519 (ecHdr.cmd==EC_CMD_TYPE_FPWR || ecHdr.cmd==EC_CMD_TYPE_FPRD || ecHdr.cmd==EC_CMD_TYPE_APWR || ecHdr.cmd==EC_CMD_TYPE_APRD) &&
520 ecHdr.anAddrUnion.a.ado>=0x1000
523 init_mbx_header(&mbox, tvb, suboffset+EcParserHDR_Len);
525 switch ( mbox.aControlUnion.v.Type )
527 case ETHERCAT_MBOX_TYPE_EOE:
528 case ETHERCAT_MBOX_TYPE_ADS:
529 case ETHERCAT_MBOX_TYPE_FOE:
530 case ETHERCAT_MBOX_TYPE_COE:
531 case ETHERCAT_MBOX_TYPE_SOE:
532 if ( /*pMBox->Length > 0 &&*/ mbox.Length <= 1500 /*&& pMBox->Length+sizeof(ETHERCAT_MBOX_HEADER_LEN) >= len*/ )
542 /* Create the sub tree for the current datagram */
543 EcSubFormatter(tvb, suboffset, szText, nMax);
544 aitem = proto_tree_add_text(ecat_datagrams_tree, tvb, suboffset, subsize, "%s", szText);
545 ecat_datagram_tree = proto_item_add_subtree(aitem, ett_ecat_datagram_subtree);
547 /* Create a subtree placeholder for the Header */
548 aitem = proto_tree_add_text(ecat_datagram_tree, tvb, offset, EcParserHDR_Len, "Header");
549 ecat_header_tree = proto_item_add_subtree(aitem, ett_ecat_header);
551 aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_cmd, tvb, suboffset, sizeof(ecHdr.cmd), TRUE);
553 aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_sub_cmd[subCount], tvb, suboffset, sizeof(ecHdr.cmd), TRUE);
554 PROTO_ITEM_SET_HIDDEN(aitem);
557 suboffset+= sizeof(ecHdr.cmd);
559 aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_idx, tvb, suboffset, sizeof(ecHdr.idx), TRUE);
561 aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_sub_idx[subCount], tvb, suboffset, sizeof(ecHdr.idx), TRUE);
562 PROTO_ITEM_SET_HIDDEN(aitem);
564 suboffset+= sizeof(ecHdr.idx);
571 aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_lad, tvb, suboffset, sizeof(ecHdr.anAddrUnion.a.adp)+sizeof(ecHdr.anAddrUnion.a.ado), TRUE);
573 aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_sub_lad[subCount], tvb, suboffset, sizeof(ecHdr.anAddrUnion.a.adp)+sizeof(ecHdr.anAddrUnion.a.ado), TRUE);
574 PROTO_ITEM_SET_HIDDEN(aitem);
577 suboffset += (sizeof(ecHdr.anAddrUnion.a.adp)+sizeof(ecHdr.anAddrUnion.a.ado));
580 aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_adp, tvb, suboffset, sizeof(ecHdr.anAddrUnion.a.adp), TRUE);
582 aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_sub_adp[subCount], tvb, suboffset, sizeof(ecHdr.anAddrUnion.a.adp), TRUE);
583 PROTO_ITEM_SET_HIDDEN(aitem);
586 suboffset+= sizeof(ecHdr.anAddrUnion.a.adp);
587 aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_ado, tvb, suboffset, sizeof(ecHdr.anAddrUnion.a.ado), TRUE);
589 aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_sub_ado[subCount], tvb, suboffset, sizeof(ecHdr.anAddrUnion.a.ado), TRUE);
590 PROTO_ITEM_SET_HIDDEN(aitem);
593 suboffset+= sizeof(ecHdr.anAddrUnion.a.ado);
597 proto_tree *length_sub_tree;
599 /* Add information about the length field (11 bit length, 3 bits
600 reserved, 1 bit circulating frame and 1 bit more in a sub tree */
601 aitem = proto_tree_add_text(ecat_header_tree, tvb, suboffset, sizeof(ecHdr.len),
602 "Length : %d (0x%x) - %s - %s",
603 len, len, ecHdr.len & 0x4000 ? "Roundtrip" : "No Roundtrip", ecHdr.len & 0x8000 ? "More Follows..." : "Last Sub Command");
604 length_sub_tree = proto_item_add_subtree(aitem, ett_ecat_length);
606 proto_tree_add_item(length_sub_tree, hf_ecat_length_len, tvb, suboffset, sizeof(ecHdr.len), TRUE);
607 proto_tree_add_item(length_sub_tree, hf_ecat_length_r, tvb, suboffset, sizeof(ecHdr.len), TRUE);
608 proto_tree_add_item(length_sub_tree, hf_ecat_length_c, tvb, suboffset, sizeof(ecHdr.len), TRUE);
609 proto_tree_add_item(length_sub_tree, hf_ecat_length_m, tvb, suboffset, sizeof(ecHdr.len), TRUE);
611 suboffset+= sizeof(ecHdr.len);
614 aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_int, tvb, suboffset, sizeof(ecHdr.intr), TRUE);
615 suboffset+= sizeof(ecHdr.intr);
619 suboffset+=EcParserHDR_Len;
622 if ( ecHdr.cmd>=1 && ecHdr.cmd<=9 && ecHdr.anAddrUnion.a.ado>=0x600 && ecHdr.anAddrUnion.a.ado<0x700 && (ecHdr.anAddrUnion.a.ado%16)==0 && (len%16)==0 )
626 /* Fieldbus Memory Management Units (FMMU) */
627 for ( b=0; b < MIN(16, len/16); b++ )
629 aitem = proto_tree_add_item(ecat_datagram_tree, hf_ecat_fmmu, tvb, suboffset, 16, TRUE);
630 proto_item_set_text(aitem, "Fieldbus Memory Management Units (FMMU)");
632 ecat_fmmu_tree = proto_item_add_subtree(aitem, ett_ecat_fmmu);
634 aitem = proto_tree_add_item(ecat_fmmu_tree, hf_ecat_fmmu_lstart, tvb, suboffset, 4, TRUE);
636 aitem = proto_tree_add_item(ecat_fmmu_tree, hf_ecat_fmmu_llen, tvb, suboffset, 2, TRUE);
638 aitem = proto_tree_add_item(ecat_fmmu_tree, hf_ecat_fmmu_lstartbit, tvb, suboffset, 1, TRUE);
640 aitem = proto_tree_add_item(ecat_fmmu_tree, hf_ecat_fmmu_lendbit, tvb, suboffset, 1, TRUE);
642 aitem = proto_tree_add_item(ecat_fmmu_tree, hf_ecat_fmmu_pstart, tvb, suboffset, 2, TRUE);
644 aitem = proto_tree_add_item(ecat_fmmu_tree, hf_ecat_fmmu_pstartbit, tvb, suboffset, 1, TRUE);
646 aitem = proto_tree_add_item(ecat_fmmu_tree, hf_ecat_fmmu_type, tvb, suboffset, 1, TRUE);
647 ecat_fmmu_type_tree = proto_item_add_subtree(aitem, ett_ecat_fmmu_type);
648 aitem = proto_tree_add_item(ecat_fmmu_type_tree, hf_ecat_fmmu_typeread, tvb, suboffset, 1, TRUE);
649 aitem = proto_tree_add_item(ecat_fmmu_type_tree, hf_ecat_fmmu_typewrite, tvb, suboffset, 1, TRUE);
652 aitem = proto_tree_add_item(ecat_fmmu_tree, hf_ecat_fmmu_active, tvb, suboffset, 1, TRUE);
653 ecat_fmmu_active_tree = proto_item_add_subtree(aitem, ett_ecat_fmmu_active);
654 aitem = proto_tree_add_item(ecat_fmmu_active_tree, hf_ecat_fmmu_active0, tvb, suboffset, 1, TRUE);
661 for (b = 0; b < MIN(32, len / 8); b++)
663 aitem = proto_tree_add_item(ecat_datagram_tree, hf_ecat_syncman, tvb, suboffset, 8, TRUE);
664 proto_item_set_text(aitem, "SyncManager");
665 ecat_syncman_tree = proto_item_add_subtree(aitem, ett_ecat_syncman);
667 aitem = proto_tree_add_item(ecat_syncman_tree, hf_ecat_syncman_start, tvb, suboffset, 2, TRUE);
669 aitem = proto_tree_add_item(ecat_syncman_tree, hf_ecat_syncman_len, tvb, suboffset, 2, TRUE);
672 aitem = proto_tree_add_item(ecat_syncman_tree, hf_ecat_syncman_flags, tvb, suboffset, 4, TRUE);
673 ecat_syncflag_tree = proto_item_add_subtree(aitem, ett_ecat_syncflag);
674 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag0, tvb, suboffset, 4, TRUE);
675 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag1, tvb, suboffset, 4, TRUE);
676 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag2, tvb, suboffset, 4, TRUE);
677 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag4, tvb, suboffset, 4, TRUE);
678 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag5, tvb, suboffset, 4, TRUE);
679 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag8, tvb, suboffset, 4, TRUE);
680 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag9, tvb, suboffset, 4, TRUE);
681 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag10, tvb, suboffset, 4, TRUE);
682 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag11, tvb, suboffset, 4, TRUE);
683 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag12, tvb, suboffset, 4, TRUE);
684 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag13, tvb, suboffset, 4, TRUE);
685 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag16, tvb, suboffset, 4, TRUE);
691 else if ( ecHdr.cmd>=1 && ecHdr.cmd<=9 && ecHdr.anAddrUnion.a.ado>=0x800 && ecHdr.anAddrUnion.a.ado<0x880 && (ecHdr.anAddrUnion.a.ado%8)==0 && (len%8)==0 )
696 for (b = 0; b < MIN(32, len / 8); b++)
698 aitem = proto_tree_add_item(ecat_datagram_tree, hf_ecat_syncman, tvb, suboffset, 8, TRUE);
699 proto_item_set_text(aitem, "SyncManager");
700 ecat_syncman_tree = proto_item_add_subtree(aitem, ett_ecat_syncman);
702 aitem = proto_tree_add_item(ecat_syncman_tree, hf_ecat_syncman_start, tvb, suboffset, 2, TRUE);
704 aitem = proto_tree_add_item(ecat_syncman_tree, hf_ecat_syncman_len, tvb, suboffset, 2, TRUE);
707 aitem = proto_tree_add_item(ecat_syncman_tree, hf_ecat_syncman_flags, tvb, suboffset, 4, TRUE);
708 ecat_syncflag_tree = proto_item_add_subtree(aitem, ett_ecat_syncflag);
709 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag0, tvb, suboffset, 4, TRUE);
710 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag1, tvb, suboffset, 4, TRUE);
711 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag2, tvb, suboffset, 4, TRUE);
712 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag4, tvb, suboffset, 4, TRUE);
713 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag5, tvb, suboffset, 4, TRUE);
714 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag8, tvb, suboffset, 4, TRUE);
715 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag9, tvb, suboffset, 4, TRUE);
716 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag10, tvb, suboffset, 4, TRUE);
717 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag11, tvb, suboffset, 4, TRUE);
718 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag12, tvb, suboffset, 4, TRUE);
719 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag13, tvb, suboffset, 4, TRUE);
720 aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag16, tvb, suboffset, 4, TRUE);
725 else if ( (ecHdr.cmd == 1 || ecHdr.cmd == 4) && ecHdr.anAddrUnion.a.ado == 0x900 && ecHdr.len >= 16 )
730 init_dc_measure(pDC, tvb, suboffset);
732 /* Allow sub dissectors to have a chance with this data */
733 if(!dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, ecat_datagram_tree))
735 /* No sub dissector did recognize this data, dissect it as data only */
736 aitem = proto_tree_add_item(ecat_datagram_tree, hf_ecat_data, tvb, suboffset, ecHdr.len & 0x07ff, TRUE);
737 ecat_dc_tree = proto_item_add_subtree(aitem, ett_ecat_dc);
741 /* A sub dissector handled the data, allow the rest of the
742 to add data to the correct place in the tree hierarchy. */
743 ecat_dc_tree = ecat_datagram_tree;
747 aitem = proto_tree_add_item(ecat_datagram_tree, hf_ecat_sub_data[subCount], tvb, offset + EcParserHDR_Len, ecHdr.len & 0x07ff, TRUE);
748 PROTO_ITEM_SET_HIDDEN(aitem);
753 proto_tree_add_uint(ecat_dc_tree, hf_ecat_dc_diff_da, tvb, suboffset, 4, pDC[3] - pDC[0]);
755 hidden_item = proto_tree_add_uint(ecat_dc_tree, hf_ecat_sub_dc_diff_da[subCount], tvb, suboffset, 4, pDC[3] - pDC[0]);
756 PROTO_ITEM_SET_HIDDEN(aitem);
761 proto_tree_add_uint(ecat_dc_tree, hf_ecat_dc_diff_bd, tvb, suboffset, 4, pDC[1] - pDC[3]);
763 hidden_item = proto_tree_add_uint(ecat_dc_tree, hf_ecat_sub_dc_diff_bd[subCount], tvb, suboffset, 4, pDC[1] - pDC[3]);
764 PROTO_ITEM_SET_HIDDEN(aitem);
767 else if ( pDC[2] != 0 )
769 proto_tree_add_uint(ecat_dc_tree, hf_ecat_dc_diff_cd, tvb, suboffset, 4, pDC[2] - pDC[3]);
771 hidden_item = proto_tree_add_uint(ecat_dc_tree, hf_ecat_sub_dc_diff_cd[subCount], tvb, suboffset, 4, pDC[2] - pDC[3]);
772 PROTO_ITEM_SET_HIDDEN(aitem);
778 proto_tree_add_uint(ecat_dc_tree, hf_ecat_dc_diff_ba, tvb, suboffset, 4, pDC[1] - pDC[0]);
780 hidden_item = proto_tree_add_uint(ecat_dc_tree, hf_ecat_sub_dc_diff_ba[subCount], tvb, suboffset, 4, pDC[1] - pDC[0]);
781 PROTO_ITEM_SET_HIDDEN(aitem);
785 proto_tree_add_uint(ecat_dc_tree, hf_ecat_dc_diff_cb, tvb, suboffset, 4, pDC[2] - pDC[1]);
787 hidden_item = proto_tree_add_uint(ecat_dc_tree, hf_ecat_sub_dc_diff_cb[subCount], tvb, suboffset, 4, pDC[2] - pDC[1]);
788 PROTO_ITEM_SET_HIDDEN(aitem);
792 else if ( pDC[2] != 0 )
794 proto_tree_add_uint(ecat_dc_tree, hf_ecat_dc_diff_ca, tvb, suboffset, 4, pDC[2] - pDC[0]);
796 hidden_item = proto_tree_add_uint(ecat_dc_tree, hf_ecat_sub_dc_diff_ca[subCount], tvb, suboffset, 4, pDC[2] - pDC[0]);
797 PROTO_ITEM_SET_HIDDEN(aitem);
804 const guint MBoxLength = mbox.Length + 6 /* MBOX header length */;
806 next_tvb = tvb_new_subset(tvb, suboffset, MBoxLength, MBoxLength);
807 call_dissector(ecat_mailbox_handle, next_tvb, pinfo, ecat_datagram_tree);
811 const guint startOfData = offset + EcParserHDR_Len + MBoxLength;
812 const guint dataLength = (ecHdr.len & 0x7ff) - MBoxLength;
813 if ( dataLength > 0 )
815 /* Allow sub dissectors to have a chance with this data */
816 if(!dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, ecat_datagram_tree))
818 /* No sub dissector did recognize this data, dissect it as data only */
819 aitem = proto_tree_add_item(ecat_datagram_tree, hf_ecat_data, tvb, startOfData, dataLength, TRUE);
823 aitem = proto_tree_add_item(ecat_datagram_tree, hf_ecat_sub_data[subCount], tvb, startOfData, dataLength, TRUE);
824 PROTO_ITEM_SET_HIDDEN(aitem);
833 /* Allow sub dissectors to have a chance with this data */
834 if(!dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, ecat_datagram_tree))
836 /* No sub dissector did recognize this data, dissect it as data only */
837 aitem = proto_tree_add_item(ecat_datagram_tree, hf_ecat_data, tvb, suboffset, ecHdr.len & 0x07ff, TRUE);
841 aitem = proto_tree_add_item(ecat_datagram_tree, hf_ecat_sub_data[subCount], tvb, offset + EcParserHDR_Len, ecHdr.len & 0x07ff, TRUE);
842 PROTO_ITEM_SET_HIDDEN(aitem);
849 aitem = proto_tree_add_item(ecat_datagram_tree, hf_ecat_cnt, tvb, offset + EcParserHDR_Len + len , 2, TRUE);
851 aitem = proto_tree_add_item(ecat_datagram_tree, hf_ecat_sub_cnt[subCount], tvb, offset + EcParserHDR_Len + len , 2, TRUE);
852 PROTO_ITEM_SET_HIDDEN(aitem);
858 } while((offset < datagram_length) &&
859 (ecHdr.len & 0x8000));
861 /* Add information that states which portion of the PDU that is pad bytes.
862 These are added just to get an Ethernet frame size of at least 64 bytes,
863 which is required by the protocol specification */
864 if(datagram_padding_bytes > 0)
866 proto_tree_add_item(tree, hf_ecat_padding, tvb, offset, tvb_length_remaining(tvb, offset), TRUE);
870 void proto_register_ecat(void)
872 static hf_register_info hf[] =
875 { "EtherCAT Frame", "ecat.sub", FT_BYTES, BASE_NONE, NULL, 0x0,
879 { "Header", "ecat.header",
880 FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }
882 { &hf_ecat_sub_data[0],
883 { "Data ", "ecat.sub1.data",
884 FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }
886 { &hf_ecat_sub_data[1],
887 { "Data ", "ecat.sub2.data",
888 FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }
890 { &hf_ecat_sub_data[2],
891 { "Data ", "ecat.sub3.data",
892 FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }
894 { &hf_ecat_sub_data[3],
895 { "Data ", "ecat.sub4.data",
896 FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }
898 { &hf_ecat_sub_data[4],
899 { "Data ", "ecat.sub5.data",
900 FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }
902 { &hf_ecat_sub_data[5],
903 { "Data ", "ecat.sub6.data",
904 FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }
906 { &hf_ecat_sub_data[6],
907 { "Data ", "ecat.sub7.data",
908 FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }
910 { &hf_ecat_sub_data[7],
911 { "Data ", "ecat.sub8.data",
912 FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }
914 { &hf_ecat_sub_data[8],
915 { "Data ", "ecat.sub9.data",
916 FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }
918 { &hf_ecat_sub_data[9],
919 { "Data ", "ecat.sub10.data",
920 FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }
923 { "Data ", "ecat.data",
924 FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }
927 { "Working Cnt", "ecat.cnt",
928 FT_UINT16, BASE_DEC, NULL, 0x0, "The working counter is increased once for each addressed device if at least one byte/bit of the data was successfully read and/or written by that device, it is increased once for every operation made by that device - read/write/read and write", HFILL }
930 { &hf_ecat_sub_cnt[0],
931 { "Working Cnt", "ecat.sub1.cnt",
932 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
934 { &hf_ecat_sub_cnt[1],
935 { "Working Cnt", "ecat.sub2.cnt",
936 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
938 { &hf_ecat_sub_cnt[2],
939 { "Working Cnt", "ecat.sub3.cnt",
940 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
942 { &hf_ecat_sub_cnt[3],
943 { "Working Cnt", "ecat.sub4.cnt",
944 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
946 { &hf_ecat_sub_cnt[4],
947 { "Working Cnt", "ecat.sub5.cnt",
948 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
950 { &hf_ecat_sub_cnt[5],
951 { "Working Cnt", "ecat.sub6.cnt",
952 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
954 { &hf_ecat_sub_cnt[6],
955 { "Working Cnt", "ecat.sub7.cnt",
956 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
958 { &hf_ecat_sub_cnt[7],
959 { "Working Cnt", "ecat.sub8.cnt",
960 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
962 { &hf_ecat_sub_cnt[8],
963 { "Working Cnt", "ecat.sub9.cnt",
964 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
966 { &hf_ecat_sub_cnt[9],
967 { "Working Cnt", "ecat.sub10.cnt",
968 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
971 { "Command ", "ecat.cmd",
972 FT_UINT8, BASE_HEX, VALS(EcCmdLong), 0x0, "", HFILL }
974 { &hf_ecat_sub_cmd[0],
975 { "Command ", "ecat.sub1.cmd",
976 FT_UINT8, BASE_HEX, VALS(EcCmdLong), 0x0, "", HFILL }
978 { &hf_ecat_sub_cmd[1],
979 { "Command ", "ecat.sub2.cmd",
980 FT_UINT8, BASE_HEX, VALS(EcCmdLong), 0x0, "", HFILL }
982 { &hf_ecat_sub_cmd[2],
983 { "Command ", "ecat.sub3.cmd",
984 FT_UINT8, BASE_HEX, VALS(EcCmdLong), 0x0, "", HFILL }
986 { &hf_ecat_sub_cmd[3],
987 { "Command ", "ecat.sub4.cmd",
988 FT_UINT8, BASE_HEX, VALS(EcCmdLong), 0x0, "", HFILL }
990 { &hf_ecat_sub_cmd[4],
991 { "Command ", "ecat.sub5.cmd",
992 FT_UINT8, BASE_HEX, VALS(EcCmdLong), 0x0, "", HFILL }
994 { &hf_ecat_sub_cmd[5],
995 { "Command ", "ecat.sub6.cmd",
996 FT_UINT8, BASE_HEX, VALS(EcCmdLong), 0x0, "", HFILL }
998 { &hf_ecat_sub_cmd[6],
999 { "Command ", "ecat.sub7.cmd",
1000 FT_UINT8, BASE_HEX, VALS(EcCmdLong), 0x0, "", HFILL }
1002 { &hf_ecat_sub_cmd[7],
1003 { "Command ", "ecat.sub8.cmd",
1004 FT_UINT8, BASE_HEX, VALS(EcCmdLong), 0x0, "", HFILL }
1006 { &hf_ecat_sub_cmd[8],
1007 { "Command ", "ecat.sub9.cmd",
1008 FT_UINT8, BASE_HEX, VALS(EcCmdLong), 0x0, "", HFILL }
1010 { &hf_ecat_sub_cmd[9],
1011 { "Command ", "ecat.sub10.cmd",
1012 FT_UINT8, BASE_HEX, VALS(EcCmdLong), 0x0, "", HFILL }
1015 { "Index ", "ecat.idx",
1016 FT_UINT8, BASE_HEX, NULL, 0x0,
1019 { &hf_ecat_sub_idx[0],
1020 { "Index ", "ecat.sub1.idx",
1021 FT_UINT8, BASE_HEX, NULL, 0x0,
1024 { &hf_ecat_sub_idx[1],
1025 { "Index ", "ecat.sub2.idx",
1026 FT_UINT8, BASE_HEX, NULL, 0x0,
1029 { &hf_ecat_sub_idx[2],
1030 { "Index ", "ecat.sub3.idx",
1031 FT_UINT8, BASE_HEX, NULL, 0x0,
1034 { &hf_ecat_sub_idx[3],
1035 { "Index ", "ecat.sub4.idx",
1036 FT_UINT8, BASE_HEX, NULL, 0x0,
1039 { &hf_ecat_sub_idx[4],
1040 { "Index ", "ecat.sub5.idx",
1041 FT_UINT8, BASE_HEX, NULL, 0x0,
1044 { &hf_ecat_sub_idx[5],
1045 { "Index ", "ecat.sub6.idx",
1046 FT_UINT8, BASE_HEX, NULL, 0x0,
1049 { &hf_ecat_sub_idx[6],
1050 { "Index ", "ecat.sub7.idx",
1051 FT_UINT8, BASE_HEX, NULL, 0x0,
1054 { &hf_ecat_sub_idx[7],
1055 { "Index ", "ecat.sub8.idx",
1056 FT_UINT8, BASE_HEX, NULL, 0x0,
1059 { &hf_ecat_sub_idx[8],
1060 { "Index ", "ecat.sub9.idx",
1061 FT_UINT8, BASE_HEX, NULL, 0x0,
1064 { &hf_ecat_sub_idx[9],
1065 { "Index ", "ecat.sub10.idx",
1066 FT_UINT8, BASE_HEX, NULL, 0x0,
1070 { "Slave Addr ", "ecat.adp",
1071 FT_UINT16, BASE_HEX, NULL, 0x0,
1074 { &hf_ecat_sub_adp[0],
1075 { "Slave Addr ", "ecat.sub1.adp",
1076 FT_UINT16, BASE_HEX, NULL, 0x0,
1079 { &hf_ecat_sub_adp[1],
1080 { "Slave Addr ", "ecat.sub2.adp",
1081 FT_UINT16, BASE_HEX, NULL, 0x0,
1084 { &hf_ecat_sub_adp[2],
1085 { "Slave Addr ", "ecat.sub3.adp",
1086 FT_UINT16, BASE_HEX, NULL, 0x0,
1089 { &hf_ecat_sub_adp[3],
1090 { "Slave Addr ", "ecat.sub4.adp",
1091 FT_UINT16, BASE_HEX, NULL, 0x0,
1094 { &hf_ecat_sub_adp[4],
1095 { "Slave Addr ", "ecat.sub5.adp",
1096 FT_UINT16, BASE_HEX, NULL, 0x0,
1099 { &hf_ecat_sub_adp[5],
1100 { "Slave Addr ", "ecat.sub6.adp",
1101 FT_UINT16, BASE_HEX, NULL, 0x0,
1104 { &hf_ecat_sub_adp[6],
1105 { "Slave Addr ", "ecat.sub7.adp",
1106 FT_UINT16, BASE_HEX, NULL, 0x0,
1109 { &hf_ecat_sub_adp[7],
1110 { "Slave Addr ", "ecat.sub8.adp",
1111 FT_UINT16, BASE_HEX, NULL, 0x0,
1114 { &hf_ecat_sub_adp[8],
1115 { "Slave Addr ", "ecat.sub9.adp",
1116 FT_UINT16, BASE_HEX, NULL, 0x0,
1119 { &hf_ecat_sub_adp[9],
1120 { "Slave Addr ", "ecat.sub10.adp",
1121 FT_UINT16, BASE_HEX, NULL, 0x0,
1125 { "Offset Addr", "ecat.ado",
1126 FT_UINT16, BASE_HEX, NULL, 0x0,
1129 { &hf_ecat_sub_ado[0],
1130 { "Offset Addr", "ecat.sub1.ado",
1131 FT_UINT16, BASE_HEX, NULL, 0x0,
1134 { &hf_ecat_sub_ado[1],
1135 { "Offset Addr", "ecat.sub2.ado",
1136 FT_UINT16, BASE_HEX, NULL, 0x0,
1139 { &hf_ecat_sub_ado[2],
1140 { "Offset Addr", "ecat.sub3.ado",
1141 FT_UINT16, BASE_HEX, NULL, 0x0,
1144 { &hf_ecat_sub_ado[3],
1145 { "Offset Addr", "ecat.sub4.ado",
1146 FT_UINT16, BASE_HEX, NULL, 0x0,
1149 { &hf_ecat_sub_ado[4],
1150 { "Offset Addr", "ecat.sub5.ado",
1151 FT_UINT16, BASE_HEX, NULL, 0x0,
1154 { &hf_ecat_sub_ado[5],
1155 { "Offset Addr", "ecat.sub6.ado",
1156 FT_UINT16, BASE_HEX, NULL, 0x0,
1159 { &hf_ecat_sub_ado[6],
1160 { "Offset Addr", "ecat.sub7.ado",
1161 FT_UINT16, BASE_HEX, NULL, 0x0,
1164 { &hf_ecat_sub_ado[7],
1165 { "Offset Addr", "ecat.sub8.ado",
1166 FT_UINT16, BASE_HEX, NULL, 0x0,
1169 { &hf_ecat_sub_ado[8],
1170 { "Offset Addr", "ecat.sub9.ado",
1171 FT_UINT16, BASE_HEX, NULL, 0x0,
1174 { &hf_ecat_sub_ado[9],
1175 { "Offset Addr", "ecat.sub10.ado",
1176 FT_UINT16, BASE_HEX, NULL, 0x0,
1180 { "Log Addr ", "ecat.lad",
1181 FT_UINT32, BASE_HEX, NULL, 0x0,
1184 { &hf_ecat_sub_lad[0],
1185 { "Log Addr ", "ecat.sub1.lad",
1186 FT_UINT32, BASE_HEX, NULL, 0x0,
1189 { &hf_ecat_sub_lad[1],
1190 { "Log Addr ", "ecat.sub2.lad",
1191 FT_UINT32, BASE_HEX, NULL, 0x0,
1194 { &hf_ecat_sub_lad[2],
1195 { "Log Addr ", "ecat.sub3.lad",
1196 FT_UINT32, BASE_HEX, NULL, 0x0,
1199 { &hf_ecat_sub_lad[3],
1200 { "Log Addr ", "ecat.sub4.lad",
1201 FT_UINT32, BASE_HEX, NULL, 0x0,
1204 { &hf_ecat_sub_lad[4],
1205 { "Log Addr ", "ecat.sub5.lad",
1206 FT_UINT32, BASE_HEX, NULL, 0x0,
1209 { &hf_ecat_sub_lad[5],
1210 { "Log Addr ", "ecat.sub6.lad",
1211 FT_UINT32, BASE_HEX, NULL, 0x0,
1214 { &hf_ecat_sub_lad[6],
1215 { "Log Addr ", "ecat.sub7.lad",
1216 FT_UINT32, BASE_HEX, NULL, 0x0,
1219 { &hf_ecat_sub_lad[7],
1220 { "Log Addr ", "ecat.sub8.lad",
1221 FT_UINT32, BASE_HEX, NULL, 0x0,
1224 { &hf_ecat_sub_lad[8],
1225 { "Log Addr ", "ecat.sub9.lad",
1226 FT_UINT32, BASE_HEX, NULL, 0x0,
1229 { &hf_ecat_sub_lad[9],
1230 { "Log Addr ", "ecat.sub10.lad",
1231 FT_UINT32, BASE_HEX, NULL, 0x0,
1235 { "Length ", "ecat.len",
1236 FT_UINT16, BASE_DEC, NULL, 0x0,
1240 { "Interrupt ", "ecat.int",
1241 FT_UINT16, BASE_HEX, NULL, 0x0,
1245 { "SyncManager", "ecat.syncman",
1246 FT_BYTES, BASE_NONE, NULL, 0x0,
1249 { &hf_ecat_syncman_start,
1250 { "Start Addr", "ecat.syncman.start",
1251 FT_UINT16, BASE_HEX, NULL, 0x0,
1254 { &hf_ecat_syncman_len,
1255 { "SM Length ", "ecat.syncman.len",
1256 FT_UINT16, BASE_HEX, NULL, 0x0,
1259 { &hf_ecat_syncman_flags,
1260 { "SM Flags ", "ecat.syncman.flags",
1261 FT_UINT32, BASE_HEX, NULL, 0x0,
1264 { &hf_ecat_syncman_flag0,
1265 { "SM Flag0", "ecat.syncman_flag0",
1266 FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag0), 0x00000001,
1269 { &hf_ecat_syncman_flag1,
1270 { "SM Flag1", "ecat.syncman_flag1",
1271 FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag1), 0x00000002,
1274 { &hf_ecat_syncman_flag2,
1275 { "SM Flag2", "ecat.syncman_flag2",
1276 FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag2), 0x00000004,
1279 { &hf_ecat_syncman_flag4,
1280 { "SM Flag4", "ecat.syncman_flag4",
1281 FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag4), 0x00000010,
1284 { &hf_ecat_syncman_flag5,
1285 { "SM Flag5", "ecat.syncman_flag5",
1286 FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag5), 0x00000020,
1289 { &hf_ecat_syncman_flag8,
1290 { "SM Flag8", "ecat.syncman_flag8",
1291 FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag8), 0x00000100,
1294 { &hf_ecat_syncman_flag9,
1295 { "SM Flag9", "ecat.syncman_flag9",
1296 FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag9), 0x00000200,
1299 { &hf_ecat_syncman_flag10,
1300 { "SM Flag10", "ecat.syncman_flag10",
1301 FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag10), 0x00000400,
1304 { &hf_ecat_syncman_flag11,
1305 { "SM Flag11", "ecat.syncman_flag11",
1306 FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag11), 0x00000800,
1309 { &hf_ecat_syncman_flag12,
1310 { "SM Flag12", "ecat.syncman_flag12",
1311 FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag12), 0x00001000,
1314 { &hf_ecat_syncman_flag13,
1315 { "SM Flag13", "ecat.syncman_flag13",
1316 FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag13), 0x00002000,
1319 { &hf_ecat_syncman_flag16,
1320 { "SM Flag16", "ecat.syncman_flag16",
1321 FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag16), 0x00010000,
1325 { "FMMU", "ecat.fmmu",
1326 FT_BYTES, BASE_NONE, NULL, 0x0,
1329 { &hf_ecat_fmmu_lstart,
1330 { "Log Start ", "ecat.fmmu.lstart",
1331 FT_UINT32, BASE_HEX, NULL, 0x0,
1334 { &hf_ecat_fmmu_llen,
1335 { "Log Length ", "ecat.fmmu.llen",
1336 FT_UINT16, BASE_HEX, NULL, 0x0,
1339 { &hf_ecat_fmmu_lstartbit,
1340 { "Log StartBit ", "ecat.fmmu.lstartbit",
1341 FT_UINT8, BASE_HEX, NULL, 0x0,
1344 { &hf_ecat_fmmu_lendbit,
1345 { "Log EndBit ", "ecat.fmmu.lendbit",
1346 FT_UINT8, BASE_HEX, NULL, 0x0,
1349 { &hf_ecat_fmmu_pstart,
1350 { "Phys Start ", "ecat.fmmu.pstart",
1351 FT_UINT8, BASE_HEX, NULL, 0x0,
1354 { &hf_ecat_fmmu_pstartbit,
1355 { "Phys StartBit", "ecat.fmmu.pstartbit",
1356 FT_UINT8, BASE_HEX, NULL, 0x0,
1359 { &hf_ecat_fmmu_type,
1360 { "FMMU Type ", "ecat.fmmu.type",
1361 FT_UINT8, BASE_HEX, NULL, 0x0,
1364 { &hf_ecat_fmmu_typeread,
1365 { "Type", "ecat.fmmu.typeread",
1366 FT_BOOLEAN, 8, TFS(&tfs_ecat_fmmu_typeread), 0x01,
1369 { &hf_ecat_fmmu_typewrite,
1370 { "Type", "ecat.fmmu.typewrite",
1371 FT_BOOLEAN, 8, TFS(&tfs_ecat_fmmu_typewrite), 0x02,
1374 { &hf_ecat_fmmu_active,
1375 { "FMMU Active ", "ecat.fmmu.active",
1376 FT_UINT8, BASE_HEX, NULL, 0x0,
1379 { &hf_ecat_fmmu_active0,
1380 { "Active", "ecat.fmmu.active0",
1381 FT_BOOLEAN, 8, TFS(&tfs_ecat_fmmu_active), 0x01,
1384 { &hf_ecat_dc_diff_da,
1385 { "DC D-A", "ecat.dc.dif.da",
1386 FT_UINT32, BASE_DEC, NULL, 0x0,
1389 { &hf_ecat_dc_diff_bd,
1390 { "DC B-D", "ecat.dc.dif.bd",
1391 FT_UINT32, BASE_DEC, NULL, 0x0,
1394 { &hf_ecat_dc_diff_cb,
1395 { "DC C-B", "ecat.dc.dif.cb",
1396 FT_UINT32, BASE_DEC, NULL, 0x0,
1399 { &hf_ecat_dc_diff_cd,
1400 { "DC C-D", "ecat.dc.dif.cd",
1401 FT_UINT32, BASE_DEC, NULL, 0x0,
1404 { &hf_ecat_dc_diff_ba,
1405 { "DC B-A", "ecat.dc.dif.ba",
1406 FT_UINT32, BASE_DEC, NULL, 0x0,
1409 { &hf_ecat_dc_diff_ca,
1410 { "DC C-A", "ecat.dc.dif.ca",
1411 FT_UINT32, BASE_DEC, NULL, 0x0,
1414 { &hf_ecat_sub_dc_diff_da[0],
1415 { "DC D-A", "ecat.sub1.dc.dif.da",
1416 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1418 { &hf_ecat_sub_dc_diff_da[1],
1419 { "DC D-A", "ecat.sub2.dc.dif.da",
1420 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1422 { &hf_ecat_sub_dc_diff_da[2],
1423 { "DC D-A", "ecat.sub3.dc.dif.da",
1424 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1426 { &hf_ecat_sub_dc_diff_da[3],
1427 { "DC D-A", "ecat.sub4.dc.dif.da",
1428 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1430 { &hf_ecat_sub_dc_diff_da[4],
1431 { "DC D-A", "ecat.sub5.dc.dif.da",
1432 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1434 { &hf_ecat_sub_dc_diff_da[5],
1435 { "DC D-A", "ecat.sub6.dc.dif.da",
1436 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1438 { &hf_ecat_sub_dc_diff_da[6],
1439 { "DC D-A", "ecat.sub7.dc.dif.da",
1440 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1442 { &hf_ecat_sub_dc_diff_da[7],
1443 { "DC D-A", "ecat.sub8.dc.dif.da",
1444 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1446 { &hf_ecat_sub_dc_diff_da[8],
1447 { "DC D-A", "ecat.sub9.dc.dif.da",
1448 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1450 { &hf_ecat_sub_dc_diff_da[9],
1451 { "DC D-A", "ecat.sub10.dc.dif.da",
1452 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1455 { &hf_ecat_sub_dc_diff_bd[0],
1456 { "DC B-C", "ecat.sub1.dc.dif.bd",
1457 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1459 { &hf_ecat_sub_dc_diff_bd[1],
1460 { "DC B-C", "ecat.sub2.dc.dif.bd",
1461 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1463 { &hf_ecat_sub_dc_diff_bd[2],
1464 { "DC B-C", "ecat.sub3.dc.dif.bd",
1465 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1467 { &hf_ecat_sub_dc_diff_bd[3],
1468 { "DC B-C", "ecat.sub4.dc.dif.bd",
1469 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1471 { &hf_ecat_sub_dc_diff_bd[4],
1472 { "DC B-C", "ecat.sub5.dc.dif.bd",
1473 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1475 { &hf_ecat_sub_dc_diff_bd[5],
1476 { "DC B-C", "ecat.sub6.dc.dif.bd",
1477 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1479 { &hf_ecat_sub_dc_diff_bd[6],
1480 { "DC B-C", "ecat.sub7.dc.dif.bd",
1481 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1483 { &hf_ecat_sub_dc_diff_bd[7],
1484 { "DC B-C", "ecat.sub8.dc.dif.bd",
1485 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1487 { &hf_ecat_sub_dc_diff_bd[8],
1488 { "DC B-C", "ecat.sub9.dc.dif.bd",
1489 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1491 { &hf_ecat_sub_dc_diff_bd[9],
1492 { "DC B-D", "ecat.sub10.dc.dif.bd",
1493 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1496 { &hf_ecat_sub_dc_diff_cb[0],
1497 { "DC C-B", "ecat.sub1.dc.dif.cb",
1498 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1500 { &hf_ecat_sub_dc_diff_cb[1],
1501 { "DC C-B", "ecat.sub2.dc.dif.cb",
1502 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1504 { &hf_ecat_sub_dc_diff_cb[2],
1505 { "DC C-B", "ecat.sub3.dc.dif.cb",
1506 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1508 { &hf_ecat_sub_dc_diff_cb[3],
1509 { "DC C-B", "ecat.sub4.dc.dif.cb",
1510 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1512 { &hf_ecat_sub_dc_diff_cb[4],
1513 { "DC C-B", "ecat.sub5.dc.dif.cb",
1514 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1516 { &hf_ecat_sub_dc_diff_cb[5],
1517 { "DC C-B", "ecat.sub6.dc.dif.cb",
1518 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1520 { &hf_ecat_sub_dc_diff_cb[6],
1521 { "DC C-B", "ecat.sub7.dc.dif.cb",
1522 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1524 { &hf_ecat_sub_dc_diff_cb[7],
1525 { "DC C-B", "ecat.sub8.dc.dif.cb",
1526 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1528 { &hf_ecat_sub_dc_diff_cb[8],
1529 { "DC C-B", "ecat.sub9.dc.dif.cb",
1530 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1532 { &hf_ecat_sub_dc_diff_cb[9],
1533 { "DC C-B", "ecat.sub10.dc.dif.cb",
1534 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1537 { &hf_ecat_sub_dc_diff_cd[0],
1538 { "DC C-D", "ecat.sub1.dc.dif.cd",
1539 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1541 { &hf_ecat_sub_dc_diff_cd[1],
1542 { "DC C-D", "ecat.sub2.dc.dif.cd",
1543 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1545 { &hf_ecat_sub_dc_diff_cd[2],
1546 { "DC C-D", "ecat.sub3.dc.dif.cd",
1547 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1549 { &hf_ecat_sub_dc_diff_cd[3],
1550 { "DC C-D", "ecat.sub4.dc.dif.cd",
1551 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1553 { &hf_ecat_sub_dc_diff_cd[4],
1554 { "DC C-D", "ecat.sub5.dc.dif.cd",
1555 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1557 { &hf_ecat_sub_dc_diff_cd[5],
1558 { "DC C-D", "ecat.sub6.dc.dif.cd",
1559 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1561 { &hf_ecat_sub_dc_diff_cd[6],
1562 { "DC C-D", "ecat.sub7.dc.dif.cd",
1563 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1565 { &hf_ecat_sub_dc_diff_cd[7],
1566 { "DC C-D", "ecat.sub8.dc.dif.cd",
1567 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1569 { &hf_ecat_sub_dc_diff_cd[8],
1570 { "DC C-D", "ecat.sub9.dc.dif.cd",
1571 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1573 { &hf_ecat_sub_dc_diff_cd[9],
1574 { "DC C-D", "ecat.sub10.dc.dif.cd",
1575 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1578 { &hf_ecat_sub_dc_diff_ba[0],
1579 { "DC B-A", "ecat.sub1.dc.dif.ba",
1580 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1582 { &hf_ecat_sub_dc_diff_ba[1],
1583 { "DC B-A", "ecat.sub2.dc.dif.ba",
1584 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1586 { &hf_ecat_sub_dc_diff_ba[2],
1587 { "DC B-A", "ecat.sub3.dc.dif.ba",
1588 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1590 { &hf_ecat_sub_dc_diff_ba[3],
1591 { "DC B-A", "ecat.sub4.dc.dif.ba",
1592 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1594 { &hf_ecat_sub_dc_diff_ba[4],
1595 { "DC B-A", "ecat.sub5.dc.dif.ba",
1596 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1598 { &hf_ecat_sub_dc_diff_ba[5],
1599 { "DC B-A", "ecat.sub6.dc.dif.ba",
1600 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1602 { &hf_ecat_sub_dc_diff_ba[6],
1603 { "DC B-A", "ecat.sub7.dc.dif.ba",
1604 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1606 { &hf_ecat_sub_dc_diff_ba[7],
1607 { "DC B-A", "ecat.sub8.dc.dif.ba",
1608 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1610 { &hf_ecat_sub_dc_diff_ba[8],
1611 { "DC B-A", "ecat.sub9.dc.dif.ba",
1612 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1614 { &hf_ecat_sub_dc_diff_ba[9],
1615 { "DC B-A", "ecat.sub10.dc.dif.ba",
1616 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1619 { &hf_ecat_sub_dc_diff_ca[0],
1620 { "DC C-A", "ecat.sub1.dc.dif.ca",
1621 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1623 { &hf_ecat_sub_dc_diff_ca[1],
1624 { "DC C-A", "ecat.sub2.dc.dif.ca",
1625 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1627 { &hf_ecat_sub_dc_diff_ca[2],
1628 { "DC C-A", "ecat.sub3.dc.dif.ca",
1629 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1631 { &hf_ecat_sub_dc_diff_ca[3],
1632 { "DC C-A", "ecat.sub4.dc.dif.ca",
1633 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1635 { &hf_ecat_sub_dc_diff_ca[4],
1636 { "DC C-A", "ecat.sub5.dc.dif.ca",
1637 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1639 { &hf_ecat_sub_dc_diff_ca[5],
1640 { "DC C-A", "ecat.sub6.dc.dif.ca",
1641 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1643 { &hf_ecat_sub_dc_diff_ca[6],
1644 { "DC C-A", "ecat.sub7.dc.dif.ca",
1645 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1647 { &hf_ecat_sub_dc_diff_ca[7],
1648 { "DC C-A", "ecat.sub8.dc.dif.ca",
1649 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1651 { &hf_ecat_sub_dc_diff_ca[8],
1652 { "DC C-A", "ecat.sub9.dc.dif.ca",
1653 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1655 { &hf_ecat_sub_dc_diff_ca[9],
1656 { "DC C-A", "ecat.sub10.dc.dif.ca",
1657 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
1659 { &hf_ecat_length_len,
1660 { "Length", "ecat.subframe.length",
1661 FT_UINT16, BASE_DEC, NULL, 0x07ff, "", HFILL}
1663 { &hf_ecat_length_r,
1664 { "Reserved", "ecat.subframe.reserved",
1665 FT_UINT16, BASE_DEC, VALS(&ecat_subframe_reserved_vals), 0x3800, "", HFILL}
1667 { &hf_ecat_length_c,
1668 { "Round trip", "ecat.subframe.circulating",
1669 FT_UINT16, BASE_DEC, VALS(&ecat_subframe_circulating_vals), 0x4000, "", HFILL}
1671 { &hf_ecat_length_m,
1672 { "Last indicator", "ecat.subframe.more",
1673 FT_UINT16, BASE_DEC, VALS(&ecat_subframe_more_vals), 0x8000, "", HFILL}
1676 { "Pad bytes", "ecat.subframe.pad_bytes",
1677 FT_BYTES, BASE_DEC, NULL, 0x0, "", HFILL}
1681 static gint *ett[] =
1688 &ett_ecat_fmmu_type,
1689 &ett_ecat_fmmu_active,
1693 &ett_ecat_datagram_subtree
1696 proto_ecat_datagram = proto_register_protocol("EtherCAT datagram(s)",
1698 proto_register_field_array(proto_ecat_datagram, hf, array_length(hf));
1699 proto_register_subtree_array(ett, array_length(ett));
1701 /* Sub dissector code */
1702 register_heur_dissector_list("ecat.data", &heur_subdissector_list);
1705 /* The registration hand-off routing */
1706 void proto_reg_handoff_ecat(void)
1708 dissector_handle_t ecat_handle;
1710 /* Register this dissector as a sub dissector to EtherCAT frame based on
1712 ecat_handle = create_dissector_handle(dissect_ecat_datagram, proto_ecat_datagram);
1713 dissector_add("ecatf.type", 1 /* EtherCAT type */, ecat_handle);
1715 ecat_mailbox_handle = find_dissector("ecat_mailbox");