/src/wireshark/epan/dissectors/packet-epl_v1.c
Line | Count | Source |
1 | | /* packet-epl_v1.c |
2 | | * Routines for "ETHERNET Powerlink 1.0" dissection |
3 | | * (ETHERNET Powerlink Powerlink WhitePaper V0006-B) |
4 | | * |
5 | | * Copyright (c) 2006: Zurich University of Applied Sciences Winterthur (ZHW) |
6 | | * Institute of Embedded Systems (InES) |
7 | | * http://ines.zhwin.ch |
8 | | * |
9 | | * - Dominic Bechaz <bdo@zhwin.ch> |
10 | | * - David Buechi <bhd@zhwin.ch> |
11 | | * |
12 | | * |
13 | | * A dissector for: |
14 | | * Wireshark - Network traffic analyzer |
15 | | * By Gerald Combs <gerald@wireshark.org> |
16 | | * Copyright 1999 Gerald Combs |
17 | | * |
18 | | * SPDX-License-Identifier: GPL-2.0-or-later |
19 | | */ |
20 | | |
21 | | #include "config.h" |
22 | | |
23 | | #include <epan/packet.h> |
24 | | #include <epan/etypes.h> |
25 | | void proto_register_epl_v1(void); |
26 | | void proto_reg_handoff_epl_v1(void); |
27 | | |
28 | | static dissector_handle_t epl_v1_handle; |
29 | | |
30 | | /* Offsets of fields within an EPL_V1 packet. */ |
31 | 1 | #define EPL_V1_SERVICE_OFFSET 0 /* same offset for all message types*/ |
32 | 1 | #define EPL_V1_DEST_OFFSET 1 /* same offset for all message types*/ |
33 | 1 | #define EPL_V1_SRC_OFFSET 2 /* same offset for all message types*/ |
34 | | |
35 | | #define EPL_V1_SOC_C2_OFFSET 3 |
36 | | #define EPL_V1_SOC_PF_OFFSET 3 |
37 | | #define EPL_V1_SOC_NET_COMMAND_OFFSET 4 |
38 | | #define EPL_V1_SOC_NET_TIME_OFFSET 6 |
39 | | #define EPL_V1_SOC_POWERLINK_CYCLE_TIME_OFFSET 10 |
40 | | #define EPL_V1_SOC_NET_COMMAND_PARAMETER_OFFSET 14 |
41 | | |
42 | | #define EPL_V1_PREQ_C2_OFFSET 3 |
43 | | /* "Powerlink Multimanager Konzept V1.1" protocol extension*/ |
44 | | #define PMM_KONZEPT_V1_1_PREQ_YA 3 |
45 | | #define PMM_KONZEPT_V1_1_PREQ_SC 3 |
46 | | /* end "Powerlink Multimanager Konzept V1.1" protocol extension*/ |
47 | | #define EPL_V1_PREQ_RD_OFFSET 3 |
48 | | #define EPL_V1_PREQ_RD_OFFSET 3 |
49 | | #define EPL_V1_PREQ_POLL_SIZE_OUT_OFFSET 4 |
50 | | #define EPL_V1_PREQ_OUT_DATA_OFFSET 10 |
51 | | |
52 | | #define EPL_V1_PRES_C2_OFFSET 3 |
53 | | #define EPL_V1_PRES_EX_OFFSET 3 |
54 | | #define EPL_V1_PRES_RS_OFFSET 3 |
55 | | #define EPL_V1_PRES_WA_OFFSET 3 |
56 | | #define EPL_V1_PRES_ER_OFFSET 3 |
57 | | #define EPL_V1_PRES_RD_OFFSET 3 |
58 | | #define EPL_V1_PRES_POLL_SIZE_IN_OFFSET 4 |
59 | | #define EPL_V1_PRES_IN_DATA_OFFSET 10 |
60 | | |
61 | | #define EPL_V1_EOC_NET_COMMAND_OFFSET 4 |
62 | | #define EPL_V1_EOC_NET_COMMAND_PARAMETER_OFFSET 14 |
63 | | |
64 | 0 | #define EPL_V1_AINV_CHANNEL_OFFSET 3 |
65 | | |
66 | 0 | #define EPL_V1_ASND_CHANNEL_OFFSET 3 |
67 | | #define EPL_V1_ASND_SIZE_OFFSET 4 |
68 | | #define EPL_V1_ASND_DATA_OFFSET 6 |
69 | | #define EPL_V1_ASND_NODE_ID_OFFSET 6 |
70 | | #define EPL_V1_ASND_HARDWARE_REVISION_OFFSET 10 |
71 | | #define EPL_V1_ASND_FIRMWARE_VERSION_OFFSET 14 |
72 | | #define EPL_V1_ASND_DEVICE_VARIANT_OFFSET 18 |
73 | | #define EPL_V1_ASND_POLL_IN_SIZE_OFFSET 22 |
74 | | #define EPL_V1_ASND_POLL_OUT_SIZE_OFFSET 26 |
75 | | |
76 | | /* EPL_V1 message types */ |
77 | 0 | #define EPL_V1_SOC 0x01 |
78 | 0 | #define EPL_V1_EOC 0x02 |
79 | 0 | #define EPL_V1_PREQ 0x03 |
80 | 0 | #define EPL_V1_PRES 0x04 |
81 | 0 | #define EPL_V1_AINV 0x05 |
82 | 0 | #define EPL_V1_ASND 0x06 |
83 | | |
84 | | static const value_string service_vals[] = { |
85 | | {EPL_V1_SOC, "Start of Cyclic (SoC)" }, |
86 | | {EPL_V1_EOC, "End of Cyclic (EoC)" }, |
87 | | {EPL_V1_PREQ, "Poll Request (PReq)" }, |
88 | | {EPL_V1_PRES, "Poll Response (PRes)" }, |
89 | | {EPL_V1_AINV, "Acyclic Invite (AInv)" }, |
90 | | {EPL_V1_ASND, "Acyclic Send (ASnd)" }, |
91 | | {0,NULL} |
92 | | }; |
93 | | |
94 | | /* Channel values for EPL_V1 message type "AInv" */ |
95 | 0 | #define EPL_V1_AINV_IDENT 1 |
96 | | #define EPL_V1_AINV_GENERIC 255 |
97 | | |
98 | | static const value_string ainv_channel_number_vals[] = { |
99 | | {EPL_V1_AINV_IDENT, "Ident" }, |
100 | | {EPL_V1_AINV_GENERIC, "Generic Channel" }, |
101 | | {0,NULL} |
102 | | }; |
103 | | |
104 | | /* Channel values for EPL_V1 message type "ASnd" */ |
105 | | #define EPL_V1_ASND_IDENT 1 |
106 | | #define EPL_V1_ASND_GENERIC 255 |
107 | | |
108 | | static const value_string asnd_channel_number_vals[] = { |
109 | | {EPL_V1_ASND_IDENT, "Ident" }, |
110 | | {EPL_V1_ASND_GENERIC, "Generic Channel" }, |
111 | | {0,NULL} |
112 | | }; |
113 | | |
114 | | /* Net Command values for EPL_V1 message type "SoC" */ |
115 | | #define EPL_V1_SOC_NET_COMMAND_IDLE 0 |
116 | | #define EPL_V1_SOC_NET_COMMAND_ACTIVE 1 |
117 | | |
118 | | static const value_string soc_net_command_vals[] = { |
119 | | {EPL_V1_SOC_NET_COMMAND_IDLE, "Net Command Idle" }, |
120 | | {EPL_V1_SOC_NET_COMMAND_ACTIVE, "Net Command Active"}, |
121 | | {0,NULL} |
122 | | }; |
123 | | |
124 | | /* Net Command values for EPL_V1 message type "EoC" */ |
125 | | #define EPL_V1_EOC_NET_COMMAND_IDLE 0 |
126 | | #define EPL_V1_EOC_NET_COMMAND_ACTIVE 1 |
127 | | |
128 | | static const value_string eoc_net_command_vals[] = { |
129 | | {EPL_V1_EOC_NET_COMMAND_IDLE, "Net Command Idle" }, |
130 | | {EPL_V1_EOC_NET_COMMAND_ACTIVE, "Net Command Active"}, |
131 | | {0,NULL} |
132 | | }; |
133 | | |
134 | | |
135 | | /* Initialize the protocol and registered fields */ |
136 | | static int proto_epl_v1; |
137 | | static int hf_epl_v1_service; |
138 | | static int hf_epl_v1_dest; |
139 | | static int hf_epl_v1_src; |
140 | | |
141 | | static int hf_epl_v1_soc_ms; |
142 | | static int hf_epl_v1_soc_ps; |
143 | | static int hf_epl_v1_soc_net_command; |
144 | | static int hf_epl_v1_soc_net_time; |
145 | | static int hf_epl_v1_soc_powerlink_cycle_time; |
146 | | static int hf_epl_v1_soc_net_command_parameter; |
147 | | |
148 | | static int hf_epl_v1_preq_ms; |
149 | | static int hf_epl_v1_preq_rd; |
150 | | static int hf_epl_v1_preq_poll_size_out; |
151 | | static int hf_epl_v1_preq_out_data; |
152 | | |
153 | | static int hf_epl_v1_pres_ms; |
154 | | static int hf_epl_v1_pres_ex; |
155 | | static int hf_epl_v1_pres_rs; |
156 | | static int hf_epl_v1_pres_wa; |
157 | | static int hf_epl_v1_pres_er; |
158 | | static int hf_epl_v1_pres_rd; |
159 | | static int hf_epl_v1_pres_poll_size_in; |
160 | | static int hf_epl_v1_pres_in_data; |
161 | | |
162 | | static int hf_epl_v1_eoc_net_command; |
163 | | static int hf_epl_v1_eoc_net_command_parameter; |
164 | | |
165 | | static int hf_epl_v1_ainv_channel; |
166 | | |
167 | | static int hf_epl_v1_asnd_channel; |
168 | | static int hf_epl_v1_asnd_size; |
169 | | static int hf_epl_v1_asnd_data; |
170 | | static int hf_epl_v1_asnd_node_id; |
171 | | static int hf_epl_v1_asnd_hardware_revision; |
172 | | static int hf_epl_v1_asnd_firmware_version; |
173 | | static int hf_epl_v1_asnd_device_variant; |
174 | | static int hf_epl_v1_asnd_poll_in_size; |
175 | | static int hf_epl_v1_asnd_poll_out_size; |
176 | | |
177 | | static int ett_epl_v1; |
178 | | |
179 | | |
180 | | static int |
181 | | dissect_epl_v1_soc(proto_tree *epl_v1_tree, tvbuff_t *tvb, int offset) |
182 | 0 | { |
183 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_soc_ms, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
184 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_soc_ps, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
185 | 0 | offset += 1; |
186 | |
|
187 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_soc_net_command, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
188 | 0 | offset += 2; |
189 | |
|
190 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_soc_net_time, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
191 | 0 | offset += 4; |
192 | |
|
193 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_soc_powerlink_cycle_time, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
194 | 0 | offset += 4; |
195 | |
|
196 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_soc_net_command_parameter, tvb, offset, 32, ENC_NA); |
197 | 0 | offset += 32; |
198 | |
|
199 | 0 | return offset; |
200 | 0 | } |
201 | | |
202 | | |
203 | | static int |
204 | | dissect_epl_v1_eoc(proto_tree *epl_v1_tree, tvbuff_t *tvb, int offset) |
205 | 0 | { |
206 | 0 | offset += 1; |
207 | |
|
208 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_eoc_net_command, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
209 | 0 | offset += 8; |
210 | |
|
211 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_eoc_net_command_parameter, tvb, offset, 32, ENC_NA); |
212 | 0 | offset += 32; |
213 | |
|
214 | 0 | return offset; |
215 | 0 | } |
216 | | |
217 | | |
218 | | static int |
219 | | dissect_epl_v1_preq(proto_tree *epl_v1_tree, tvbuff_t *tvb, int offset) |
220 | 0 | { |
221 | 0 | uint16_t len; |
222 | |
|
223 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_preq_ms, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
224 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_preq_rd, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
225 | 0 | offset += 1; |
226 | | |
227 | | /* get length of data */ |
228 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_preq_poll_size_out, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
229 | 0 | len = tvb_get_letohs(tvb, offset); |
230 | 0 | offset += 6; |
231 | |
|
232 | 0 | if(len>0){ |
233 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_preq_out_data, tvb, offset, len, ENC_NA); |
234 | 0 | offset += len; |
235 | 0 | } |
236 | |
|
237 | 0 | return offset; |
238 | 0 | } |
239 | | |
240 | | |
241 | | |
242 | | static int |
243 | | dissect_epl_v1_pres(proto_tree *epl_v1_tree, tvbuff_t *tvb, int offset) |
244 | 0 | { |
245 | 0 | uint16_t len; |
246 | |
|
247 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_pres_ms, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
248 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_pres_ex, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
249 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_pres_rs, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
250 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_pres_wa, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
251 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_pres_er, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
252 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_pres_rd, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
253 | 0 | offset += 1; |
254 | | |
255 | | /* get length of data */ |
256 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_pres_poll_size_in, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
257 | 0 | len = tvb_get_letohs(tvb, offset); |
258 | 0 | offset += 6; |
259 | |
|
260 | 0 | if(len>0){ |
261 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_pres_in_data, tvb, offset, len, ENC_NA); |
262 | 0 | offset += len; |
263 | 0 | } |
264 | |
|
265 | 0 | return offset; |
266 | 0 | } |
267 | | |
268 | | |
269 | | |
270 | | static int |
271 | | dissect_epl_v1_ainv(proto_tree *epl_v1_tree, tvbuff_t *tvb, int offset) |
272 | 0 | { |
273 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_ainv_channel, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
274 | 0 | offset += 1; |
275 | |
|
276 | 0 | return offset; |
277 | 0 | } |
278 | | |
279 | | |
280 | | |
281 | | static int |
282 | | dissect_epl_v1_asnd(proto_tree *epl_v1_tree, tvbuff_t *tvb, int offset) |
283 | 0 | { |
284 | 0 | uint8_t epl_v1_asnd_channel; |
285 | 0 | uint16_t len; |
286 | | |
287 | | /* get ASnd channel */ |
288 | 0 | proto_tree_add_item_ret_uint8(epl_v1_tree, hf_epl_v1_asnd_channel, tvb, offset, 1, ENC_LITTLE_ENDIAN, &epl_v1_asnd_channel); |
289 | 0 | offset += 1; |
290 | | |
291 | | /* get length of data */ |
292 | 0 | proto_tree_add_item_ret_uint16(epl_v1_tree, hf_epl_v1_asnd_size, tvb, offset, 2, ENC_LITTLE_ENDIAN, &len); |
293 | 0 | offset += 2; |
294 | | |
295 | | /* "Ident" or "Generic" channel? */ |
296 | 0 | if(epl_v1_asnd_channel == EPL_V1_AINV_IDENT){ /* Ident channel*/ |
297 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_asnd_node_id, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
298 | 0 | offset += 4; |
299 | |
|
300 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_asnd_hardware_revision, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
301 | 0 | offset += 4; |
302 | |
|
303 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_asnd_firmware_version, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
304 | 0 | offset += 4; |
305 | |
|
306 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_asnd_device_variant, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
307 | 0 | offset += 4; |
308 | |
|
309 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_asnd_poll_in_size, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
310 | 0 | offset += 4; |
311 | |
|
312 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_asnd_poll_out_size, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
313 | 0 | offset += 4; |
314 | 0 | } else { /* "Generic" and all other channels */ |
315 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_asnd_data, tvb, offset, len, ENC_NA); |
316 | 0 | offset += len; |
317 | 0 | } |
318 | |
|
319 | 0 | return offset; |
320 | 0 | } |
321 | | |
322 | | |
323 | | |
324 | | /* Code to actually dissect the packets */ |
325 | | static int |
326 | | dissect_epl_v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
327 | 1 | { |
328 | 1 | uint8_t epl_v1_service, epl_v1_dest, epl_v1_src, epl_v1_ainv_ch, epl_v1_asnd_ch; |
329 | 1 | int offset; |
330 | 1 | proto_item *ti=NULL; |
331 | 1 | proto_tree *epl_v1_tree=NULL; |
332 | | |
333 | | |
334 | 1 | if(tvb_captured_length(tvb) < 3){ |
335 | | /* Not enough data for an EPL_V1 header; don't try to interpret it */ |
336 | 0 | return false; |
337 | 0 | } |
338 | | |
339 | 1 | offset = 0; |
340 | | |
341 | | /* make entries in Protocol column and Info column on summary display */ |
342 | 1 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "EPL_V1"); |
343 | 1 | col_clear(pinfo->cinfo, COL_INFO); |
344 | | |
345 | | /* get service type */ |
346 | 1 | epl_v1_service = tvb_get_uint8(tvb, EPL_V1_SERVICE_OFFSET) & 0x7F; |
347 | | |
348 | | /* get destination */ |
349 | 1 | epl_v1_dest = tvb_get_uint8(tvb, EPL_V1_DEST_OFFSET); |
350 | | |
351 | | /* get source */ |
352 | 1 | epl_v1_src = tvb_get_uint8(tvb, EPL_V1_SRC_OFFSET); |
353 | | |
354 | | /* choose the right string for "Info" column */ |
355 | 1 | switch(epl_v1_service){ |
356 | 0 | case EPL_V1_SOC: |
357 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "SoC dest = %3d src = %3d ", epl_v1_dest, epl_v1_src); |
358 | 0 | break; |
359 | | |
360 | 0 | case EPL_V1_EOC: |
361 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "EoC dest = %3d src = %3d ", epl_v1_dest, epl_v1_src); |
362 | 0 | break; |
363 | | |
364 | 0 | case EPL_V1_PREQ: |
365 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "PReq dest = %3d src = %3d ", epl_v1_dest, epl_v1_src); |
366 | 0 | break; |
367 | | |
368 | 0 | case EPL_V1_PRES: |
369 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "PRes dest = %3d src = %3d ", epl_v1_dest, epl_v1_src); |
370 | 0 | break; |
371 | | |
372 | 0 | case EPL_V1_AINV: |
373 | | /* get AInv channel */ |
374 | 0 | epl_v1_ainv_ch = tvb_get_uint8(tvb, EPL_V1_AINV_CHANNEL_OFFSET); |
375 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "AInv dest = %3d src = %3d channel = %s ", |
376 | 0 | epl_v1_dest, epl_v1_src, val_to_str(pinfo->pool, epl_v1_ainv_ch, ainv_channel_number_vals, "unknown Channel (%d)")); |
377 | 0 | break; |
378 | | |
379 | 0 | case EPL_V1_ASND: |
380 | | /* get ASnd channel */ |
381 | 0 | epl_v1_asnd_ch = tvb_get_uint8(tvb, EPL_V1_ASND_CHANNEL_OFFSET); |
382 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "ASnd dest = %3d src = %3d channel = %s ", |
383 | 0 | epl_v1_dest, epl_v1_src, val_to_str(pinfo->pool, epl_v1_asnd_ch, asnd_channel_number_vals, "unknown Channel (%d)")); |
384 | 0 | break; |
385 | | |
386 | 1 | default: /* no valid EPL packet */ |
387 | 1 | return false; |
388 | 1 | } |
389 | | |
390 | 0 | if(tree){ |
391 | | /* create display subtree for the protocol */ |
392 | 0 | ti = proto_tree_add_item(tree, proto_epl_v1, tvb, 0, -1, ENC_NA); |
393 | |
|
394 | 0 | epl_v1_tree = proto_item_add_subtree(ti, ett_epl_v1); |
395 | 0 | } |
396 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_service, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
397 | 0 | offset += 1; |
398 | |
|
399 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_dest, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
400 | 0 | offset += 1; |
401 | |
|
402 | 0 | proto_tree_add_item(epl_v1_tree, hf_epl_v1_src, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
403 | 0 | offset += 1; |
404 | | |
405 | | /* The rest of the epl_v1 dissector depends on the message type */ |
406 | 0 | switch(epl_v1_service){ |
407 | 0 | case EPL_V1_SOC: |
408 | 0 | offset = dissect_epl_v1_soc(epl_v1_tree, tvb, offset); |
409 | 0 | break; |
410 | | |
411 | 0 | case EPL_V1_EOC: |
412 | 0 | offset = dissect_epl_v1_eoc(epl_v1_tree, tvb, offset); |
413 | 0 | break; |
414 | | |
415 | 0 | case EPL_V1_PREQ: |
416 | 0 | offset = dissect_epl_v1_preq(epl_v1_tree, tvb, offset); |
417 | 0 | break; |
418 | | |
419 | 0 | case EPL_V1_PRES: |
420 | 0 | offset = dissect_epl_v1_pres(epl_v1_tree, tvb, offset); |
421 | 0 | break; |
422 | | |
423 | 0 | case EPL_V1_AINV: |
424 | 0 | offset = dissect_epl_v1_ainv(epl_v1_tree, tvb, offset); |
425 | 0 | break; |
426 | | |
427 | 0 | case EPL_V1_ASND: |
428 | 0 | offset = dissect_epl_v1_asnd(epl_v1_tree, tvb, offset); |
429 | 0 | break; |
430 | | |
431 | 0 | default: /* not a valid MessageType - can't dissect any further. */ |
432 | 0 | return false; |
433 | 0 | } |
434 | 0 | return offset; |
435 | 0 | } |
436 | | |
437 | | |
438 | | |
439 | | void |
440 | | proto_register_epl_v1(void) |
441 | 15 | { |
442 | 15 | static hf_register_info hf[] = { |
443 | | /* Common data fields (same for all message types) */ |
444 | 15 | { &hf_epl_v1_service, |
445 | 15 | { "Service", "epl_v1.service", |
446 | 15 | FT_UINT8, BASE_DEC, VALS(service_vals), 0x7F, |
447 | 15 | NULL, HFILL } |
448 | 15 | }, |
449 | 15 | { &hf_epl_v1_dest, |
450 | 15 | { "Destination", "epl_v1.dest", |
451 | 15 | FT_UINT8, BASE_DEC, NULL, 0x00, |
452 | 15 | NULL, HFILL } |
453 | 15 | }, |
454 | 15 | { &hf_epl_v1_src, |
455 | 15 | { "Source", "epl_v1.src", |
456 | 15 | FT_UINT8, BASE_DEC, NULL, 0x00, |
457 | 15 | NULL, HFILL } |
458 | 15 | }, |
459 | | /* SoC data fields*/ |
460 | 15 | { &hf_epl_v1_soc_ms, |
461 | 15 | { "MS (Multiplexed Slot)", "epl_v1.soc.ms", |
462 | 15 | FT_UINT8, BASE_DEC, NULL, 0x80, |
463 | 15 | NULL, HFILL } |
464 | 15 | }, |
465 | 15 | { &hf_epl_v1_soc_ps, |
466 | 15 | { "PS (Prescaled Slot)", "epl_v1.soc.ps", |
467 | 15 | FT_UINT8, BASE_DEC, NULL, 0x40, |
468 | 15 | NULL, HFILL } |
469 | 15 | }, |
470 | 15 | { &hf_epl_v1_soc_net_command, |
471 | 15 | { "Net Command", "epl_v1.soc.netcommand", |
472 | 15 | FT_UINT16, BASE_DEC, VALS(soc_net_command_vals), 0x0, |
473 | 15 | NULL, HFILL } |
474 | 15 | }, |
475 | 15 | { &hf_epl_v1_soc_net_time, |
476 | 15 | { "Net Time", "epl_v1.soc.nettime", |
477 | 15 | FT_UINT32, BASE_DEC, NULL, 0x0, |
478 | 15 | NULL, HFILL } |
479 | 15 | }, |
480 | 15 | { &hf_epl_v1_soc_powerlink_cycle_time, |
481 | 15 | { "Cycle Time", "epl_v1.soc.cycletime", |
482 | 15 | FT_UINT32, BASE_DEC, NULL, 0x0, |
483 | 15 | NULL, HFILL } |
484 | 15 | }, |
485 | 15 | { &hf_epl_v1_soc_net_command_parameter, |
486 | 15 | { "Net Command Parameter", "epl_v1.soc.netcommand.parameter", |
487 | 15 | FT_BYTES, BASE_NONE, NULL, 0x0, |
488 | 15 | NULL, HFILL } |
489 | 15 | }, |
490 | | /* PReq data fields*/ |
491 | 15 | { &hf_epl_v1_preq_ms, |
492 | 15 | { "MS (Multiplexed Slot)", "epl_v1.preq.ms", |
493 | 15 | FT_UINT8, BASE_DEC, NULL, 0x20, |
494 | 15 | NULL, HFILL } |
495 | 15 | }, |
496 | 15 | { &hf_epl_v1_preq_rd, |
497 | 15 | { "RD (Ready)", "epl_v1.preq.rd", |
498 | 15 | FT_UINT8, BASE_DEC, NULL, 0x01, |
499 | 15 | NULL, HFILL } |
500 | 15 | }, |
501 | 15 | { &hf_epl_v1_preq_poll_size_out, |
502 | 15 | { "Poll Size OUT", "epl_v1.preq.pollsize", |
503 | 15 | FT_UINT16, BASE_DEC, NULL, 0x00, |
504 | 15 | NULL, HFILL } |
505 | 15 | }, |
506 | 15 | { &hf_epl_v1_preq_out_data, |
507 | 15 | { "OUT Data", "epl_v1.preq.data", |
508 | 15 | FT_BYTES, BASE_NONE, NULL, 0x00, |
509 | 15 | NULL, HFILL } |
510 | 15 | }, |
511 | | /* PRes data fields*/ |
512 | 15 | { &hf_epl_v1_pres_ms, |
513 | 15 | { "MS (Multiplexed)", "epl_v1.pres.ms", |
514 | 15 | FT_UINT8, BASE_DEC, NULL, 0x20, |
515 | 15 | NULL, HFILL } |
516 | 15 | }, |
517 | 15 | { &hf_epl_v1_pres_ex, |
518 | 15 | { "EX (Exception)", "epl_v1.pres.ex", |
519 | 15 | FT_UINT8, BASE_DEC, NULL, 0x10, |
520 | 15 | NULL, HFILL } |
521 | 15 | }, |
522 | 15 | { &hf_epl_v1_pres_rs, |
523 | 15 | { "RS (Request to Send)", "epl_v1.pres.rs", |
524 | 15 | FT_UINT8, BASE_DEC, NULL, 0x08, |
525 | 15 | NULL, HFILL } |
526 | 15 | }, |
527 | 15 | { &hf_epl_v1_pres_wa, |
528 | 15 | { "WA (Warning)", "epl_v1.pres.wa", |
529 | 15 | FT_UINT8, BASE_DEC, NULL, 0x04, |
530 | 15 | NULL, HFILL } |
531 | 15 | }, |
532 | 15 | { &hf_epl_v1_pres_er, |
533 | 15 | { "ER (Error)", "epl_v1.pres.er", |
534 | 15 | FT_UINT8, BASE_DEC, NULL, 0x02, |
535 | 15 | NULL, HFILL } |
536 | 15 | }, |
537 | 15 | { &hf_epl_v1_pres_rd, |
538 | 15 | { "RD (Ready)", "epl_v1.pres.rd", |
539 | 15 | FT_UINT8, BASE_DEC, NULL, 0x01, |
540 | 15 | NULL, HFILL } |
541 | 15 | }, |
542 | 15 | { &hf_epl_v1_pres_poll_size_in, |
543 | 15 | { "Poll Size IN", "epl_v1.pres.pollsize", |
544 | 15 | FT_UINT16, BASE_DEC, NULL, 0x00, |
545 | 15 | NULL, HFILL } |
546 | 15 | }, |
547 | 15 | { &hf_epl_v1_pres_in_data, |
548 | 15 | { "IN Data", "epl_v1.pres.data", |
549 | 15 | FT_BYTES, BASE_NONE, NULL, 0x00, |
550 | 15 | NULL, HFILL } |
551 | 15 | }, |
552 | | /* EoC data fields*/ |
553 | 15 | { &hf_epl_v1_eoc_net_command, |
554 | 15 | { "Net Command", "epl_v1.eoc.netcommand", |
555 | 15 | FT_UINT16, BASE_DEC, VALS(eoc_net_command_vals), 0x00, |
556 | 15 | NULL, HFILL } |
557 | 15 | }, |
558 | 15 | { &hf_epl_v1_eoc_net_command_parameter, |
559 | 15 | { "Net Command Parameter", "epl_v1.soa.netcommand.parameter", |
560 | 15 | FT_BYTES, BASE_NONE, NULL, 0x00, |
561 | 15 | NULL, HFILL } |
562 | 15 | }, |
563 | | /* AInv data fields*/ |
564 | 15 | { &hf_epl_v1_ainv_channel, |
565 | 15 | { "Channel", "epl_v1.ainv.channel", |
566 | 15 | FT_UINT8, BASE_DEC, VALS(ainv_channel_number_vals), 0x00, |
567 | 15 | NULL, HFILL } |
568 | 15 | }, |
569 | | /* ASnd data fields*/ |
570 | 15 | { &hf_epl_v1_asnd_channel, |
571 | 15 | { "Channel", "epl_v1.asnd.channel", |
572 | 15 | FT_UINT8, BASE_DEC, VALS(asnd_channel_number_vals), 0x00, |
573 | 15 | NULL, HFILL } |
574 | 15 | }, |
575 | 15 | { &hf_epl_v1_asnd_size, |
576 | 15 | { "Size", "epl_v1.asnd.size", |
577 | 15 | FT_UINT16, BASE_DEC, NULL, 0x00, |
578 | 15 | NULL, HFILL } |
579 | 15 | }, |
580 | 15 | { &hf_epl_v1_asnd_data, |
581 | 15 | { "Data", "epl_v1.asnd.data", |
582 | 15 | FT_BYTES, BASE_NONE, NULL, 0x00, |
583 | 15 | NULL, HFILL } |
584 | 15 | }, |
585 | | |
586 | 15 | { &hf_epl_v1_asnd_node_id, |
587 | 15 | { "NodeID", "epl_v1.asnd.node_id", |
588 | 15 | FT_UINT32, BASE_DEC, NULL, 0x00, |
589 | 15 | NULL, HFILL } |
590 | 15 | }, |
591 | 15 | { &hf_epl_v1_asnd_hardware_revision, |
592 | 15 | { "Hardware Revision", "epl_v1.asnd.hardware.revision", |
593 | 15 | FT_UINT32, BASE_DEC, NULL, 0x00, |
594 | 15 | NULL, HFILL } |
595 | 15 | }, |
596 | 15 | { &hf_epl_v1_asnd_firmware_version, |
597 | 15 | { "Firmware Version", "epl_v1.asnd.firmware.version", |
598 | 15 | FT_UINT32, BASE_DEC, NULL, 0x00, |
599 | 15 | NULL, HFILL } |
600 | 15 | }, |
601 | 15 | { &hf_epl_v1_asnd_device_variant, |
602 | 15 | { "Device Variant", "epl_v1.asnd.device.variant", |
603 | 15 | FT_UINT32, BASE_DEC, NULL, 0x00, |
604 | 15 | NULL, HFILL } |
605 | 15 | }, |
606 | 15 | { &hf_epl_v1_asnd_poll_in_size, |
607 | 15 | { "Poll IN Size", "epl_v1.asnd.poll.in.size", |
608 | 15 | FT_UINT32, BASE_DEC, NULL, 0x00, |
609 | 15 | NULL, HFILL } |
610 | 15 | }, |
611 | 15 | { &hf_epl_v1_asnd_poll_out_size, |
612 | 15 | { "Poll OUT Size", "epl_v1.asnd.poll.out.size", |
613 | 15 | FT_UINT32, BASE_DEC, NULL, 0x00, |
614 | 15 | NULL, HFILL } |
615 | 15 | }, |
616 | 15 | }; |
617 | | |
618 | | /* Setup protocol subtree array */ |
619 | 15 | static int *ett[] = { |
620 | 15 | &ett_epl_v1, |
621 | 15 | }; |
622 | | |
623 | | /* Register the protocol name and description */ |
624 | 15 | proto_epl_v1 = proto_register_protocol("ETHERNET Powerlink V1.0", "EPL_V1", "epl_v1"); |
625 | | |
626 | | /* Required function calls to register the header fields and subtrees used */ |
627 | 15 | proto_register_field_array(proto_epl_v1, hf, array_length(hf)); |
628 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
629 | | |
630 | 15 | epl_v1_handle = register_dissector("epl_v1", dissect_epl_v1, proto_epl_v1); |
631 | 15 | } |
632 | | |
633 | | |
634 | | |
635 | | void |
636 | | proto_reg_handoff_epl_v1(void) |
637 | 15 | { |
638 | 15 | dissector_add_uint("ethertype", ETHERTYPE_EPL_V1, epl_v1_handle); |
639 | 15 | } |
640 | | |
641 | | /* |
642 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
643 | | * |
644 | | * Local variables: |
645 | | * c-basic-offset: 8 |
646 | | * tab-width: 8 |
647 | | * indent-tabs-mode: t |
648 | | * End: |
649 | | * |
650 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
651 | | * :indentSize=8:tabSize=8:noTabs=false: |
652 | | */ |