2 * Routines for ethercat packet disassembly
4 * Copyright (c) 2007 by Beckhoff Automation GmbH
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
17 #include <epan/packet.h>
19 #include "packet-nv.h"
21 void proto_register_nv(void);
22 void proto_reg_handoff_nv(void);
24 /* Define the nv proto */
27 static dissector_handle_t nv_handle
;
30 static int ett_nv_header
;
31 static int ett_nv_var
;
32 static int ett_nv_varheader
;
34 /* static int hf_nv_summary; */
35 static int hf_nv_header
;
36 static int hf_nv_publisher
;
37 static int hf_nv_count
;
38 static int hf_nv_cycleindex
;
39 static int hf_nv_variable
;
40 static int hf_nv_varheader
;
42 static int hf_nv_hash
;
43 static int hf_nv_length
;
44 static int hf_nv_quality
;
45 static int hf_nv_data
;
48 static void NvSummaryFormater(tvbuff_t
*tvb
, int offset
, char *szText
, int nMax
)
50 uint32_t nvOffset
= offset
;
52 snprintf ( szText
, nMax
, "Network Vars from %d.%d.%d.%d.%d.%d - %d Var(s)",
53 tvb_get_uint8(tvb
, nvOffset
),
54 tvb_get_uint8(tvb
, nvOffset
+1),
55 tvb_get_uint8(tvb
, nvOffset
+2),
56 tvb_get_uint8(tvb
, nvOffset
+3),
57 tvb_get_uint8(tvb
, nvOffset
+4),
58 tvb_get_uint8(tvb
, nvOffset
+5),
59 tvb_get_letohs(tvb
, nvOffset
+6));
62 static void NvPublisherFormater(tvbuff_t
*tvb
, int offset
, char *szText
, int nMax
)
64 uint32_t nvOffset
= offset
;
66 snprintf ( szText
, nMax
, "Publisher %d.%d.%d.%d.%d.%d",
67 tvb_get_uint8(tvb
, nvOffset
),
68 tvb_get_uint8(tvb
, nvOffset
+1),
69 tvb_get_uint8(tvb
, nvOffset
+2),
70 tvb_get_uint8(tvb
, nvOffset
+3),
71 tvb_get_uint8(tvb
, nvOffset
+4),
72 tvb_get_uint8(tvb
, nvOffset
+5));
75 static void NvVarHeaderFormater(tvbuff_t
*tvb
, int offset
, char *szText
, int nMax
)
77 snprintf ( szText
, nMax
, "Variable - Id = %d, Length = %d",
78 tvb_get_letohs(tvb
, offset
),
79 tvb_get_letohs(tvb
, offset
+4));
82 static int dissect_nv(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
85 proto_tree
*nv_tree
, *nv_header_tree
, *nv_var_tree
,*nv_varheader_tree
;
88 int nMax
= (int)sizeof(szText
)-1;
92 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "TC-NV");
94 col_clear(pinfo
->cinfo
, COL_INFO
);
96 NvSummaryFormater(tvb
, offset
, szText
, nMax
);
97 col_append_str(pinfo
->cinfo
, COL_INFO
, szText
);
103 ti
= proto_tree_add_item(tree
, proto_nv
, tvb
, 0, -1, ENC_NA
);
104 nv_tree
= proto_item_add_subtree(ti
, ett_nv
);
105 proto_item_append_text(ti
,": %s",szText
);
107 ti
= proto_tree_add_item(nv_tree
, hf_nv_header
, tvb
, offset
, NvParserHDR_Len
, ENC_NA
);
109 nv_header_tree
= proto_item_add_subtree(ti
, ett_nv_header
);
111 ti
= proto_tree_add_item(nv_header_tree
, hf_nv_publisher
, tvb
, offset
, (int)sizeof(uint8_t)*6, ENC_NA
);
112 NvPublisherFormater(tvb
, offset
, szText
, nMax
);
113 proto_item_set_text(ti
, "%s", szText
);
114 offset
+=((int)sizeof(uint8_t)*6);
116 proto_tree_add_item(nv_header_tree
, hf_nv_count
, tvb
, offset
, (int)sizeof(uint16_t), ENC_LITTLE_ENDIAN
);
117 nv_count
= tvb_get_letohs(tvb
, offset
);
118 offset
+=(int)sizeof(uint16_t);
120 proto_tree_add_item(nv_header_tree
, hf_nv_cycleindex
, tvb
, offset
, (int)sizeof(uint16_t), ENC_LITTLE_ENDIAN
);
121 offset
= NvParserHDR_Len
;
123 for ( i
=0; i
< nv_count
; i
++ )
125 uint16_t var_length
= tvb_get_letohs(tvb
, offset
+4);
127 ti
= proto_tree_add_item(nv_tree
, hf_nv_variable
, tvb
, offset
, ETYPE_88A4_NV_DATA_HEADER_Len
+var_length
, ENC_NA
);
128 NvVarHeaderFormater(tvb
, offset
, szText
, nMax
);
129 proto_item_set_text(ti
, "%s", szText
);
131 nv_var_tree
= proto_item_add_subtree(ti
, ett_nv_var
);
132 ti
= proto_tree_add_item(nv_var_tree
, hf_nv_varheader
, tvb
, offset
, ETYPE_88A4_NV_DATA_HEADER_Len
, ENC_NA
);
134 nv_varheader_tree
= proto_item_add_subtree(ti
, ett_nv_varheader
);
135 proto_tree_add_item(nv_varheader_tree
, hf_nv_id
, tvb
, offset
, (int)sizeof(uint16_t), ENC_LITTLE_ENDIAN
);
136 offset
+=(int)sizeof(uint16_t);
138 proto_tree_add_item(nv_varheader_tree
, hf_nv_hash
, tvb
, offset
, (int)sizeof(uint16_t), ENC_LITTLE_ENDIAN
);
139 offset
+=(int)sizeof(uint16_t);
141 proto_tree_add_item(nv_varheader_tree
, hf_nv_length
, tvb
, offset
, (int)sizeof(uint16_t), ENC_LITTLE_ENDIAN
);
142 offset
+=(int)sizeof(uint16_t);
144 proto_tree_add_item(nv_varheader_tree
, hf_nv_quality
, tvb
, offset
, (int)sizeof(uint16_t), ENC_LITTLE_ENDIAN
);
145 offset
+=(int)sizeof(uint16_t);
147 proto_tree_add_item(nv_var_tree
, hf_nv_data
, tvb
, offset
, var_length
, ENC_NA
);
151 return tvb_captured_length(tvb
);
154 void proto_register_nv(void)
156 static hf_register_info hf
[] =
159 { &hf_nv_summary
, { "Summary of the Nv Packet", "tc_nv.summary",
160 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
164 { &hf_nv_header
, { "Header", "tc_nv.header",
165 FT_NONE
, BASE_NONE
, NULL
, 0x0,
168 { &hf_nv_publisher
, { "Publisher", "tc_nv.publisher",
169 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
172 { &hf_nv_count
, { "Count", "tc_nv.count",
173 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
176 { &hf_nv_cycleindex
, { "CycleIndex", "tc_nv.cycleindex",
177 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
180 { &hf_nv_variable
, { "Variable", "tc_nv.variable",
181 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
184 { &hf_nv_varheader
, { "VarHeader", "tc_nv.varheader",
185 FT_NONE
, BASE_NONE
, NULL
, 0x0,
188 { &hf_nv_id
, { "Id", "tc_nv.id",
189 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
192 { &hf_nv_hash
, { "Hash", "tc_nv.hash",
193 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
196 { &hf_nv_length
, { "Length", "tc_nv.length",
197 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
200 { &hf_nv_quality
, { "Quality", "tc_nv.quality",
201 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
204 { &hf_nv_data
, { "Data", "tc_nv.data",
205 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
218 proto_nv
= proto_register_protocol("TwinCAT NV", "TC-NV","tc_nv");
219 proto_register_field_array(proto_nv
,hf
,array_length(hf
));
220 proto_register_subtree_array(ett
,array_length(ett
));
221 nv_handle
= register_dissector("tc_nv", dissect_nv
, proto_nv
);
224 void proto_reg_handoff_nv(void)
226 dissector_add_uint("ecatf.type", 4, nv_handle
);
230 * Editor modelines - https://www.wireshark.org/tools/modelines.html
235 * indent-tabs-mode: nil
238 * ex: set shiftwidth=3 tabstop=8 expandtab:
239 * :indentSize=3:tabSize=8:noTabs=true: