nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* packet-pn-ptcp.c |
2 | * Routines for PN-PTCP (PROFINET Precision Time Clock Protocol) |
||
3 | * packet dissection. |
||
4 | * |
||
5 | * Wireshark - Network traffic analyzer |
||
6 | * By Gerald Combs <gerald@wireshark.org> |
||
7 | * Copyright 1998 Gerald Combs |
||
8 | * |
||
9 | * This program is free software; you can redistribute it and/or |
||
10 | * modify it under the terms of the GNU General Public License |
||
11 | * as published by the Free Software Foundation; either version 2 |
||
12 | * of the License, or (at your option) any later version. |
||
13 | * |
||
14 | * This program is distributed in the hope that it will be useful, |
||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
17 | * GNU General Public License for more details. |
||
18 | * |
||
19 | * You should have received a copy of the GNU General Public License |
||
20 | * along with this program; if not, write to the Free Software |
||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
||
22 | */ |
||
23 | |||
24 | #include "config.h" |
||
25 | |||
26 | #include <epan/packet.h> |
||
27 | #include <epan/oui.h> |
||
28 | #include <epan/dissectors/packet-dcerpc.h> |
||
29 | |||
30 | #include "packet-pn.h" |
||
31 | |||
32 | void proto_register_pn_ptcp(void); |
||
33 | void proto_reg_handoff_pn_ptcp(void); |
||
34 | |||
35 | static int proto_pn_ptcp = -1; |
||
36 | |||
37 | static int hf_pn_ptcp_header = -1; |
||
38 | static int hf_pn_ptcp_block = -1; |
||
39 | static int hf_pn_ptcp_block_tlvheader = -1; |
||
40 | |||
41 | static int hf_pn_ptcp_res1 = -1; |
||
42 | static int hf_pn_ptcp_res2 = -1; |
||
43 | static int hf_pn_ptcp_delay10ns = -1; |
||
44 | static int hf_pn_ptcp_seq_id = -1; |
||
45 | static int hf_pn_ptcp_delay1ns_byte = -1; |
||
46 | static int hf_pn_ptcp_delay1ns_fup = -1; |
||
47 | static int hf_pn_ptcp_delay1ns = -1; |
||
48 | |||
49 | static int hf_pn_ptcp_tl_length = -1; |
||
50 | static int hf_pn_ptcp_tl_type = -1; |
||
51 | |||
52 | static int hf_pn_ptcp_master_source_address = -1; |
||
53 | static int hf_pn_ptcp_subdomain_uuid = -1; |
||
54 | |||
55 | static int hf_pn_ptcp_port_mac_address = -1; |
||
56 | |||
57 | static int hf_pn_ptcp_t2portrxdelay = -1; |
||
58 | static int hf_pn_ptcp_t3porttxdelay = -1; |
||
59 | |||
60 | static int hf_pn_ptcp_t2timestamp = -1; |
||
61 | |||
62 | static int hf_pn_ptcp_epoch_number = -1; |
||
63 | static int hf_pn_ptcp_seconds = -1; |
||
64 | static int hf_pn_ptcp_nanoseconds = -1; |
||
65 | |||
66 | static int hf_pn_ptcp_flags = -1; |
||
67 | static int hf_pn_ptcp_currentutcoffset = -1; |
||
68 | |||
69 | static int hf_pn_ptcp_master_priority1 = -1; |
||
70 | static int hf_pn_ptcp_master_priority_level = -1; |
||
71 | static int hf_pn_ptcp_master_priority1_res = -1; |
||
72 | static int hf_pn_ptcp_master_priority1_act =-1; |
||
73 | |||
74 | static int hf_pn_ptcp_master_priority2 = -1; |
||
75 | static int hf_pn_ptcp_clock_class = -1; |
||
76 | static int hf_pn_ptcp_clock_accuracy = -1; |
||
77 | static int hf_pn_ptcp_clockvariance = -1; |
||
78 | |||
79 | static int hf_pn_ptcp_oui = -1; |
||
80 | static int hf_pn_ptcp_profinet_subtype = -1; |
||
81 | static int hf_pn_ptcp_irdata_uuid = -1; |
||
82 | |||
83 | static gint ett_pn_ptcp = -1; |
||
84 | static gint ett_pn_ptcp_header = -1; |
||
85 | static gint ett_pn_ptcp_block = -1; |
||
86 | static gint ett_pn_ptcp_block_header = -1; |
||
87 | |||
88 | #define OUI_PROFINET_MULTICAST 0x010ECF /* PROFIBUS Nutzerorganisation e.V. */ |
||
89 | |||
90 | |||
91 | #define PN_PTCP_BT_END 0x00 |
||
92 | #define PN_PTCP_BT_SUBDOMAIN 0x01 |
||
93 | #define PN_PTCP_BT_TIME 0x02 |
||
94 | #define PN_PTCP_BT_TIME_EXTENSION 0x03 |
||
95 | #define PN_PTCP_BT_MASTER 0x04 |
||
96 | #define PN_PTCP_BT_PORT_PARAMETER 0x05 |
||
97 | #define PN_PTCP_BT_DELAY_PARAMETER 0x06 |
||
98 | #define PN_PTCP_BT_PORT_TIME 0x07 |
||
99 | #define PN_PTCP_BT_OPTION 0x7F |
||
100 | #define PN_PTCP_BT_RTDATA 0x7F |
||
101 | |||
102 | |||
103 | static const value_string pn_ptcp_block_type[] = { |
||
104 | { PN_PTCP_BT_END, "End" }, |
||
105 | { PN_PTCP_BT_SUBDOMAIN, "Subdomain"}, |
||
106 | { PN_PTCP_BT_TIME, "Time"}, |
||
107 | { PN_PTCP_BT_TIME_EXTENSION, "TimeExtension"}, |
||
108 | { PN_PTCP_BT_MASTER, "Master"}, |
||
109 | { PN_PTCP_BT_PORT_PARAMETER, "PortParameter"}, |
||
110 | { PN_PTCP_BT_DELAY_PARAMETER, "DelayParameter"}, |
||
111 | { PN_PTCP_BT_PORT_TIME, "PortTime"}, |
||
112 | /*0x08 - 0x7E Reserved */ |
||
113 | { PN_PTCP_BT_OPTION, "Organizationally Specific"}, |
||
114 | { 0, NULL } |
||
115 | }; |
||
116 | |||
117 | static const value_string pn_ptcp_oui_vals[] = { |
||
118 | { OUI_PROFINET, "PROFINET" }, |
||
119 | { OUI_PROFINET_MULTICAST, "PROFINET" }, |
||
120 | { 0, NULL } |
||
121 | }; |
||
122 | |||
123 | static const value_string pn_ptcp_master_prio1_vals[] = { |
||
124 | { 0x00, "Sync slave" }, |
||
125 | { 0x01, "Primary master" }, |
||
126 | { 0x02, "Secondary master" }, |
||
127 | { 0x03, "Reserved" }, |
||
128 | { 0x04, "Reserved" }, |
||
129 | { 0x05, "Reserved" }, |
||
130 | { 0x06, "Reserved" }, |
||
131 | { 0x07, "Reserved" }, |
||
132 | { 0, NULL } |
||
133 | }; |
||
134 | |||
135 | static const value_string pn_ptcp_master_prio1_levels[] = { |
||
136 | { 0x00, "Level 0 (highest)" }, |
||
137 | { 0x01, "Level 1" }, |
||
138 | { 0x02, "Level 2" }, |
||
139 | { 0x03, "Level 3" }, |
||
140 | { 0x04, "Level 4" }, |
||
141 | { 0x05, "Level 5" }, |
||
142 | { 0x06, "Level 6" }, |
||
143 | { 0x07, "Level 7 (lowest)" }, |
||
144 | { 0, NULL } |
||
145 | }; |
||
146 | |||
147 | static const value_string pn_ptcp_master_prio1_vals_active[] = { |
||
148 | { 0x00, "inactive" }, |
||
149 | { 0x01, "active" }, |
||
150 | { 0, NULL } |
||
151 | }; |
||
152 | |||
153 | #if 0 |
||
154 | static const value_string pn_ptcp_master_prio1_short_vals[] = { |
||
155 | { 0x01, "Primary" }, |
||
156 | { 0x02, "Secondary" }, |
||
157 | { 0, NULL } |
||
158 | }; |
||
159 | #endif |
||
160 | |||
161 | static const value_string pn_ptcp_master_prio2_vals[] = { |
||
162 | { 0xFF, "Default" }, |
||
163 | { 0, NULL } |
||
164 | }; |
||
165 | |||
166 | static const value_string pn_ptcp_clock_class_vals[] = { |
||
167 | { 0xFF, "Slave-only clock" }, |
||
168 | { 0, NULL } |
||
169 | }; |
||
170 | |||
171 | static const value_string pn_ptcp_clock_accuracy_vals[] = { |
||
172 | { 0x20, "25ns" }, |
||
173 | { 0x21, "100ns (Default)" }, |
||
174 | { 0x22, "250ns" }, |
||
175 | { 0x23, "1us" }, |
||
176 | { 0x24, "2.5us" }, |
||
177 | { 0x25, "10us" }, |
||
178 | { 0x26, "25us" }, |
||
179 | { 0x27, "100us" }, |
||
180 | { 0x28, "250us" }, |
||
181 | { 0x29, "1ms" }, |
||
182 | { 0xFE, "Unknown" }, |
||
183 | { 0, NULL } |
||
184 | }; |
||
185 | |||
186 | static const value_string pn_ptcp_profinet_subtype_vals[] = { |
||
187 | { 0x01, "RTData" }, |
||
188 | { 0, NULL } |
||
189 | }; |
||
190 | |||
191 | |||
192 | |||
193 | |||
194 | static int |
||
195 | dissect_PNPTCP_TLVHeader(tvbuff_t *tvb, int offset, |
||
196 | packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 *type, guint16 *length) |
||
197 | { |
||
198 | guint16 tl_type; |
||
199 | guint16 tl_length; |
||
200 | |||
201 | |||
202 | /* Type */ |
||
203 | dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_ptcp_tl_type, &tl_type); |
||
204 | *type = tl_type >> 9; |
||
205 | |||
206 | /* Length */ |
||
207 | offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_ptcp_tl_length, &tl_length); |
||
208 | *length = tl_length & 0x1FF; |
||
209 | |||
210 | return offset; |
||
211 | } |
||
212 | |||
213 | |||
214 | static int |
||
215 | dissect_PNPTCP_Subdomain(tvbuff_t *tvb, int offset, |
||
216 | packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 u16FrameID) |
||
217 | { |
||
218 | guint8 mac[6]; |
||
219 | e_guid_t uuid; |
||
220 | |||
221 | |||
222 | /* MasterSourceAddress */ |
||
223 | offset = dissect_pn_mac(tvb, offset, pinfo, tree, hf_pn_ptcp_master_source_address, mac); |
||
224 | |||
225 | /* SubdomainUUID */ |
||
226 | offset = dissect_pn_uuid(tvb, offset, pinfo, tree, hf_pn_ptcp_subdomain_uuid, &uuid); |
||
227 | |||
228 | if ((u16FrameID == 0xff00) || (u16FrameID == 0xff01)) { |
||
229 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Master=%02x:%02x:%02x:%02x:%02x:%02x", |
||
230 | mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); |
||
231 | } |
||
232 | |||
233 | proto_item_append_text(item, ": MasterSource=%02x:%02x:%02x:%02x:%02x:%02x", |
||
234 | mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); |
||
235 | |||
236 | proto_item_append_text(item, ", Subdomain=%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", |
||
237 | uuid.data1, uuid.data2, uuid.data3, |
||
238 | uuid.data4[0], uuid.data4[1], |
||
239 | uuid.data4[2], uuid.data4[3], |
||
240 | uuid.data4[4], uuid.data4[5], |
||
241 | uuid.data4[6], uuid.data4[7]); |
||
242 | |||
243 | return offset; |
||
244 | } |
||
245 | |||
246 | |||
247 | static int |
||
248 | dissect_PNPTCP_Time(tvbuff_t *tvb, int offset, |
||
249 | packet_info *pinfo, proto_tree *tree, proto_item *item) |
||
250 | { |
||
251 | guint16 EpochNumber; |
||
252 | guint32 Seconds; |
||
253 | guint32 NanoSeconds; |
||
254 | |||
255 | |||
256 | /* EpochNumber */ |
||
257 | offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_ptcp_epoch_number, &EpochNumber); |
||
258 | |||
259 | /* Seconds */ |
||
260 | offset = dissect_pn_uint32(tvb, offset, pinfo, tree, hf_pn_ptcp_seconds, &Seconds); |
||
261 | |||
262 | /* NanoSeconds */ |
||
263 | offset = dissect_pn_uint32(tvb, offset, pinfo, tree, hf_pn_ptcp_nanoseconds, &NanoSeconds); |
||
264 | |||
265 | proto_item_append_text(item, ": Seconds=%u NanoSeconds=%u EpochNumber=%u", |
||
266 | Seconds, NanoSeconds, EpochNumber); |
||
267 | |||
268 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Time: %4us %09uns, Epoch: %u", |
||
269 | Seconds, NanoSeconds, EpochNumber); |
||
270 | |||
271 | return offset; |
||
272 | } |
||
273 | |||
274 | |||
275 | static int |
||
276 | dissect_PNPTCP_TimeExtension(tvbuff_t *tvb, int offset, |
||
277 | packet_info *pinfo, proto_tree *tree, proto_item *item) |
||
278 | { |
||
279 | guint16 Flags; |
||
280 | guint16 CurrentUTCOffset; |
||
281 | |||
282 | |||
283 | /* Flags */ |
||
284 | offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_ptcp_flags, &Flags); |
||
285 | |||
286 | /* CurrentUTCOffset */ |
||
287 | offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_ptcp_currentutcoffset, &CurrentUTCOffset); |
||
288 | |||
289 | /* Padding */ |
||
290 | offset = dissect_pn_align4(tvb, offset, pinfo, tree); |
||
291 | |||
292 | proto_item_append_text(item, ": Flags=0x%x, CurrentUTCOffset=%u", Flags, CurrentUTCOffset); |
||
293 | |||
294 | return offset; |
||
295 | } |
||
296 | |||
297 | |||
298 | static int |
||
299 | dissect_PNPTCP_Master(tvbuff_t *tvb, int offset, |
||
300 | packet_info *pinfo, proto_tree *tree, proto_item *item) |
||
301 | { |
||
302 | guint8 MasterPriority1; |
||
303 | guint8 MasterPriority2; |
||
304 | guint8 ClockClass; |
||
305 | guint8 ClockAccuracy; |
||
306 | gint16 ClockVariance; |
||
307 | |||
308 | |||
309 | /* MasterPriority1 is a bit field */ |
||
310 | /* Bit 0 - 2: PTCP_MasterPriority1.Priority */ |
||
311 | dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_master_priority1, &MasterPriority1); |
||
312 | /* Bit 3 - 5: PTCP_MasterPriority1.Level */ |
||
313 | dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_master_priority_level, &MasterPriority1); |
||
314 | /* Bit 6: PTCP_MasterPriority1.Reserved */ |
||
315 | dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_master_priority1_res, &MasterPriority1); |
||
316 | /* Bit 7: PTCP_MasterPriority1.Active */ |
||
317 | offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_master_priority1_act, &MasterPriority1); |
||
318 | |||
319 | /* MasterPriority2 */ |
||
320 | offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_master_priority2, &MasterPriority2); |
||
321 | |||
322 | /* ClockClass */ |
||
323 | offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_clock_class, &ClockClass); |
||
324 | |||
325 | /* ClockAccuracy */ |
||
326 | offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_clock_accuracy, &ClockAccuracy); |
||
327 | |||
328 | /* ClockVariance */ |
||
329 | offset = dissect_pn_int16(tvb, offset, pinfo, tree, hf_pn_ptcp_clockvariance, &ClockVariance); |
||
330 | |||
331 | /* Padding */ |
||
332 | offset = dissect_pn_align4(tvb, offset, pinfo, tree); |
||
333 | |||
334 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Prio1=\"%s\"", |
||
335 | val_to_str(MasterPriority1 & 0x7, pn_ptcp_master_prio1_vals, "(Reserved: 0x%x)")); |
||
336 | |||
337 | if ((MasterPriority1 & 0x80) == 0) { |
||
338 | proto_item_append_text(item, ": Prio1=\"%s\", Prio2=%s, Clock: Class=\"%s\", Accuracy=%s, Variance=%d", |
||
339 | val_to_str(MasterPriority1 & 0x7, pn_ptcp_master_prio1_vals, "(Reserved: 0x%x)"), |
||
340 | val_to_str(MasterPriority2, pn_ptcp_master_prio2_vals, "(Reserved: 0x%x)"), |
||
341 | val_to_str(ClockClass, pn_ptcp_clock_class_vals, "(Reserved: 0x%x)"), |
||
342 | val_to_str(ClockAccuracy, pn_ptcp_clock_accuracy_vals, "(Reserved: 0x%x)"), |
||
343 | ClockVariance); |
||
344 | } |
||
345 | else { |
||
346 | col_append_str(pinfo->cinfo, COL_INFO, " active"); |
||
347 | proto_item_append_text(item, ": Prio1=\"%s\" is active, Prio2=%s, Clock: Class=\"%s\", Accuracy=%s, Variance=%d", |
||
348 | val_to_str(MasterPriority1 & 0x7, pn_ptcp_master_prio1_vals, "(Reserved: 0x%x)"), |
||
349 | val_to_str(MasterPriority2, pn_ptcp_master_prio2_vals, "(Reserved: 0x%x)"), |
||
350 | val_to_str(ClockClass, pn_ptcp_clock_class_vals, "(Reserved: 0x%x)"), |
||
351 | val_to_str(ClockAccuracy, pn_ptcp_clock_accuracy_vals, "(Reserved: 0x%x)"), |
||
352 | ClockVariance); |
||
353 | } |
||
354 | |||
355 | |||
356 | return offset; |
||
357 | } |
||
358 | |||
359 | |||
360 | static int |
||
361 | dissect_PNPTCP_PortParameter(tvbuff_t *tvb, int offset, |
||
362 | packet_info *pinfo, proto_tree *tree, proto_item *item) |
||
363 | { |
||
364 | guint32 t2portrxdelay; |
||
365 | guint32 t3porttxdelay; |
||
366 | |||
367 | |||
368 | /* Padding */ |
||
369 | offset = dissect_pn_align4(tvb, offset, pinfo, tree); |
||
370 | |||
371 | /* T2PortRxDelay */ |
||
372 | offset = dissect_pn_uint32(tvb, offset, pinfo, tree, hf_pn_ptcp_t2portrxdelay, &t2portrxdelay); |
||
373 | |||
374 | /* T3PortTxDelay */ |
||
375 | offset = dissect_pn_uint32(tvb, offset, pinfo, tree, hf_pn_ptcp_t3porttxdelay, &t3porttxdelay); |
||
376 | |||
377 | proto_item_append_text(item, ": T2PortRxDelay=%uns, T3PortTxDelay=%uns", |
||
378 | t2portrxdelay, t3porttxdelay); |
||
379 | |||
380 | col_append_fstr(pinfo->cinfo, COL_INFO, ", T2Rx=%uns, T3Tx=%uns", |
||
381 | t2portrxdelay, t3porttxdelay); |
||
382 | |||
383 | return offset; |
||
384 | } |
||
385 | |||
386 | |||
387 | static int |
||
388 | dissect_PNPTCP_DelayParameter(tvbuff_t *tvb, int offset, |
||
389 | packet_info *pinfo, proto_tree *tree, proto_item *item) |
||
390 | { |
||
391 | guint8 mac[6]; |
||
392 | |||
393 | |||
394 | /* PortMACAddress */ |
||
395 | offset = dissect_pn_mac(tvb, offset, pinfo, tree, hf_pn_ptcp_port_mac_address, mac); |
||
396 | |||
397 | /* Padding */ |
||
398 | offset = dissect_pn_align4(tvb, offset, pinfo, tree); |
||
399 | |||
400 | |||
401 | proto_item_append_text(item, ": PortMAC=%02x:%02x:%02x:%02x:%02x:%02x", |
||
402 | mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); |
||
403 | |||
404 | col_append_fstr(pinfo->cinfo, COL_INFO, ", PortMAC=%02x:%02x:%02x:%02x:%02x:%02x", |
||
405 | mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); |
||
406 | |||
407 | return offset; |
||
408 | } |
||
409 | |||
410 | |||
411 | static int |
||
412 | dissect_PNPTCP_PortTime(tvbuff_t *tvb, int offset, |
||
413 | packet_info *pinfo, proto_tree *tree, proto_item *item) |
||
414 | { |
||
415 | guint32 t2timestamp; |
||
416 | |||
417 | |||
418 | /* Padding */ |
||
419 | offset = dissect_pn_align4(tvb, offset, pinfo, tree); |
||
420 | |||
421 | /* T2TimeStamp */ |
||
422 | offset = dissect_pn_uint32(tvb, offset, pinfo, tree, hf_pn_ptcp_t2timestamp, &t2timestamp); |
||
423 | |||
424 | proto_item_append_text(item, ": T2TimeStamp=%uns", t2timestamp); |
||
425 | |||
426 | col_append_fstr(pinfo->cinfo, COL_INFO, ", T2TS=%uns", t2timestamp); |
||
427 | |||
428 | return offset; |
||
429 | } |
||
430 | |||
431 | |||
432 | static int |
||
433 | dissect_PNPTCP_Option_PROFINET(tvbuff_t *tvb, int offset, |
||
434 | packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 length) |
||
435 | { |
||
436 | guint8 subType; |
||
437 | e_guid_t uuid; |
||
438 | |||
439 | /* OUI already dissected! */ |
||
440 | |||
441 | /* SubType */ |
||
442 | offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_ptcp_profinet_subtype, &subType); |
||
443 | length -= 1; |
||
444 | |||
445 | switch (subType) { |
||
446 | case 1: /* RTData */ |
||
447 | /* Padding */ |
||
448 | offset = dissect_pn_align4(tvb, offset, pinfo, tree); |
||
449 | |||
450 | /* IRDataUUID */ |
||
451 | offset = dissect_pn_uuid(tvb, offset, pinfo, tree, hf_pn_ptcp_irdata_uuid, &uuid); |
||
452 | proto_item_append_text(item, ": IRDataUUID=%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", |
||
453 | uuid.data1, uuid.data2, uuid.data3, |
||
454 | uuid.data4[0], uuid.data4[1], |
||
455 | uuid.data4[2], uuid.data4[3], |
||
456 | uuid.data4[4], uuid.data4[5], |
||
457 | uuid.data4[6], uuid.data4[7]); |
||
458 | |||
459 | break; |
||
460 | default: |
||
461 | offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, length); |
||
462 | break; |
||
463 | } |
||
464 | |||
465 | return offset; |
||
466 | } |
||
467 | |||
468 | |||
469 | static int |
||
470 | dissect_PNPTCP_Option(tvbuff_t *tvb, int offset, |
||
471 | packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 length) |
||
472 | { |
||
473 | guint32 oui; |
||
474 | |||
475 | |||
476 | /* verify remaining TLV length */ |
||
477 | if (length < 4) |
||
478 | { |
||
479 | /* too short */ |
||
480 | offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, length); |
||
481 | return (offset); |
||
482 | } |
||
483 | |||
484 | /* OUI (organizational unique id) */ |
||
485 | offset = dissect_pn_oid(tvb, offset, pinfo,tree, hf_pn_ptcp_oui, &oui); |
||
486 | length -= 3; |
||
487 | |||
488 | switch (oui) |
||
489 | { |
||
490 | case OUI_PROFINET: |
||
491 | case OUI_PROFINET_MULTICAST: |
||
492 | proto_item_append_text(item, ": PROFINET"); |
||
493 | offset = dissect_PNPTCP_Option_PROFINET(tvb, offset, pinfo, tree, item, length); |
||
494 | break; |
||
495 | default: |
||
496 | /* SubType */ |
||
497 | offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, length); |
||
498 | } |
||
499 | |||
500 | return (offset); |
||
501 | } |
||
502 | |||
503 | |||
504 | static int |
||
505 | dissect_PNPTCP_block(tvbuff_t *tvb, int offset, |
||
506 | packet_info *pinfo, proto_tree *tree, proto_item *item _U_, gboolean *end, guint16 u16FrameID) |
||
507 | { |
||
508 | guint16 type; |
||
509 | guint16 length; |
||
510 | |||
511 | proto_item *sub_item; |
||
512 | proto_tree *sub_tree; |
||
513 | proto_item *tlvheader_item; |
||
514 | proto_tree *tlvheader_tree; |
||
515 | guint32 u32SubStart; |
||
516 | |||
517 | |||
518 | *end = FALSE; |
||
519 | |||
520 | /* block subtree */ |
||
521 | sub_item = proto_tree_add_item(tree, hf_pn_ptcp_block, tvb, offset, 0, ENC_NA); |
||
522 | sub_tree = proto_item_add_subtree(sub_item, ett_pn_ptcp_block); |
||
523 | u32SubStart = offset; |
||
524 | |||
525 | /* tlvheader subtree */ |
||
526 | tlvheader_item = proto_tree_add_item(sub_tree, hf_pn_ptcp_block_tlvheader, tvb, offset, 2 /* len */, ENC_NA); |
||
527 | tlvheader_tree = proto_item_add_subtree(tlvheader_item, ett_pn_ptcp_block_header); |
||
528 | |||
529 | offset = dissect_PNPTCP_TLVHeader(tvb, offset, pinfo, tlvheader_tree, sub_item, &type, &length); |
||
530 | |||
531 | proto_item_set_text(sub_item, "%s", |
||
532 | val_to_str(type, pn_ptcp_block_type, "Unknown")); |
||
533 | |||
534 | proto_item_append_text(tlvheader_item, ": Type=%s (%x), Length=%u", |
||
535 | val_to_str(type, pn_ptcp_block_type, "Unknown"), type, length); |
||
536 | |||
537 | switch (type) { |
||
538 | case 0x00: /* End, no content */ |
||
539 | *end = TRUE; |
||
540 | break; |
||
541 | case 0x01: /* Subdomain */ |
||
542 | dissect_PNPTCP_Subdomain(tvb, offset, pinfo, sub_tree, sub_item, u16FrameID); |
||
543 | break; |
||
544 | case 0x02: /* Time */ |
||
545 | dissect_PNPTCP_Time(tvb, offset, pinfo, sub_tree, sub_item); |
||
546 | break; |
||
547 | case 0x03: /* TimeExtension */ |
||
548 | dissect_PNPTCP_TimeExtension(tvb, offset, pinfo, sub_tree, sub_item); |
||
549 | break; |
||
550 | case 0x04: /* Master */ |
||
551 | dissect_PNPTCP_Master(tvb, offset, pinfo, sub_tree, sub_item); |
||
552 | break; |
||
553 | case 0x05: /* PortParameter */ |
||
554 | dissect_PNPTCP_PortParameter(tvb, offset, pinfo, sub_tree, sub_item); |
||
555 | break; |
||
556 | case 0x06: /* DelayParameter */ |
||
557 | dissect_PNPTCP_DelayParameter(tvb, offset, pinfo, sub_tree, sub_item); |
||
558 | break; |
||
559 | case 0x07: /* PortTime */ |
||
560 | dissect_PNPTCP_PortTime(tvb, offset, pinfo, sub_tree, sub_item); |
||
561 | break; |
||
562 | case 0x7F: /* Organizational Specific */ |
||
563 | dissect_PNPTCP_Option(tvb, offset, pinfo, sub_tree, sub_item, length); |
||
564 | break; |
||
565 | default: |
||
566 | offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, length); |
||
567 | } |
||
568 | offset += length; |
||
569 | |||
570 | proto_item_set_len(sub_item, offset - u32SubStart); |
||
571 | |||
572 | return offset; |
||
573 | } |
||
574 | |||
575 | |||
576 | static int |
||
577 | dissect_PNPTCP_blocks(tvbuff_t *tvb, int offset, |
||
578 | packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 u16FrameID) |
||
579 | { |
||
580 | gboolean end = FALSE; |
||
581 | |||
582 | /* as long as we have some bytes, try a new block */ |
||
583 | while (!end) { |
||
584 | offset = dissect_PNPTCP_block(tvb, offset, pinfo, tree, item, &end, u16FrameID); |
||
585 | } |
||
586 | |||
587 | return offset; |
||
588 | } |
||
589 | |||
590 | |||
591 | static int |
||
592 | dissect_PNPTCP_FollowUpPDU(tvbuff_t *tvb, int offset, |
||
593 | packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 u16FrameID, |
||
594 | const char *name, const char *name_short) |
||
595 | { |
||
596 | proto_item *header_item; |
||
597 | proto_tree *header_tree; |
||
598 | guint16 seq_id; |
||
599 | gint32 delay1ns_fup; |
||
600 | |||
601 | |||
602 | /* dissect the header */ |
||
603 | header_item = proto_tree_add_item(tree, hf_pn_ptcp_header, tvb, offset, 20 /* len */, ENC_NA); |
||
604 | header_tree = proto_item_add_subtree(header_item, ett_pn_ptcp_header); |
||
605 | |||
606 | /* Padding 12 bytes */ |
||
607 | offset = dissect_pn_padding(tvb, offset, pinfo, header_tree, 12); |
||
608 | |||
609 | /* SequenceID */ |
||
610 | offset = dissect_pn_uint16(tvb, offset, pinfo, header_tree, hf_pn_ptcp_seq_id, &seq_id); |
||
611 | |||
612 | /* Padding */ |
||
613 | offset = dissect_pn_align4(tvb, offset, pinfo, header_tree); |
||
614 | |||
615 | /* Delay1ns_FUP */ |
||
616 | offset = dissect_pn_int32(tvb, offset, pinfo, header_tree, hf_pn_ptcp_delay1ns_fup, &delay1ns_fup); |
||
617 | |||
618 | col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq=%3u, Delay=%11dns", name, seq_id, delay1ns_fup); |
||
619 | proto_item_append_text(item, "%s: Sequence=%u, Delay=%dns", name_short, seq_id, delay1ns_fup); |
||
620 | proto_item_append_text(header_item, ": Sequence=%u, Delay=%dns", seq_id, delay1ns_fup); |
||
621 | |||
622 | |||
623 | /* dissect the TLV blocks */ |
||
624 | offset = dissect_PNPTCP_blocks(tvb, offset, pinfo, tree, item, u16FrameID); |
||
625 | |||
626 | return offset; |
||
627 | } |
||
628 | |||
629 | |||
630 | static int |
||
631 | dissect_PNPTCP_RTSyncPDU(tvbuff_t *tvb, int offset, |
||
632 | packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 u16FrameID, |
||
633 | const char *name, const char *name_short) |
||
634 | { |
||
635 | proto_item *header_item; |
||
636 | proto_tree *header_tree; |
||
637 | guint32 res_1; |
||
638 | guint32 res_2; |
||
639 | guint32 delay10ns; |
||
640 | guint16 seq_id; |
||
641 | guint8 delay1ns_8; |
||
642 | guint64 delay1ns_64; |
||
643 | guint32 delay1ns_32; |
||
644 | guint32 delayms; |
||
645 | |||
646 | |||
647 | header_item = proto_tree_add_item(tree, hf_pn_ptcp_header, tvb, offset, 20 /* len */, ENC_NA); |
||
648 | header_tree = proto_item_add_subtree(header_item, ett_pn_ptcp_header); |
||
649 | |||
650 | /* Reserved_1 */ |
||
651 | offset = dissect_pn_uint32(tvb, offset, pinfo, header_tree, hf_pn_ptcp_res1, &res_1); |
||
652 | |||
653 | /* Reserved_2 */ |
||
654 | offset = dissect_pn_uint32(tvb, offset, pinfo, header_tree, hf_pn_ptcp_res2, &res_2); |
||
655 | |||
656 | /* Delay10ns */ |
||
657 | offset = dissect_pn_uint32(tvb, offset, pinfo, header_tree, hf_pn_ptcp_delay10ns, &delay10ns); |
||
658 | |||
659 | /* SequenceID */ |
||
660 | offset = dissect_pn_uint16(tvb, offset, pinfo, header_tree, hf_pn_ptcp_seq_id, &seq_id); |
||
661 | |||
662 | /* Delay1ns */ |
||
663 | offset = dissect_pn_uint8(tvb, offset, pinfo, header_tree, hf_pn_ptcp_delay1ns_byte, &delay1ns_8); |
||
664 | |||
665 | /* Padding */ |
||
666 | offset = dissect_pn_align4(tvb, offset, pinfo, header_tree); |
||
667 | |||
668 | /* Delay1ns */ |
||
669 | offset = dissect_pn_uint32(tvb, offset, pinfo, header_tree, hf_pn_ptcp_delay1ns, &delay1ns_32); |
||
670 | |||
671 | /* Padding */ |
||
672 | offset = dissect_pn_align4(tvb, offset, pinfo, tree); |
||
673 | |||
674 | |||
675 | delay1ns_64 = ((guint64) delay10ns) * 10 + delay1ns_8 + delay1ns_32; |
||
676 | delayms = (guint32) (delay1ns_64 / (1000 * 1000)); |
||
677 | |||
678 | col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq=%3u, Delay=%11" G_GINT64_MODIFIER "uns", |
||
679 | name, seq_id, delay1ns_64); |
||
680 | proto_item_append_text(item, "%s: Sequence=%u, Delay=%" G_GINT64_MODIFIER "uns", |
||
681 | name_short, seq_id, delay1ns_64); |
||
682 | proto_item_append_text(header_item, ": Sequence=%u, Delay=%" G_GINT64_MODIFIER "uns", |
||
683 | seq_id, delay1ns_64); |
||
684 | |||
685 | if (delay1ns_64 != 0) |
||
686 | proto_item_append_text(header_item, " (%u.%03u,%03u,%03u sec)", |
||
687 | delayms / 1000, |
||
688 | delayms % 1000, |
||
689 | (delay10ns % (1000*100)) / 100, |
||
690 | delay10ns % 100 * 10 + delay1ns_8); |
||
691 | |||
692 | /* dissect the PDU */ |
||
693 | offset = dissect_PNPTCP_blocks(tvb, offset, pinfo, tree, item, u16FrameID); |
||
694 | |||
695 | return offset; |
||
696 | } |
||
697 | |||
698 | |||
699 | static int |
||
700 | dissect_PNPTCP_AnnouncePDU(tvbuff_t *tvb, int offset, |
||
701 | packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 u16FrameID, |
||
702 | const char *name, const char *name_short) |
||
703 | { |
||
704 | proto_item *header_item; |
||
705 | proto_tree *header_tree; |
||
706 | guint16 seq_id; |
||
707 | |||
708 | |||
709 | /* dissect the header */ |
||
710 | header_item = proto_tree_add_item(tree, hf_pn_ptcp_header, tvb, offset, 20 /* len */, ENC_NA); |
||
711 | header_tree = proto_item_add_subtree(header_item, ett_pn_ptcp_header); |
||
712 | |||
713 | /* Padding 12 bytes */ |
||
714 | offset = dissect_pn_padding(tvb, offset, pinfo, header_tree, 12); |
||
715 | |||
716 | /* SequenceID */ |
||
717 | offset = dissect_pn_uint16(tvb, offset, pinfo, header_tree, hf_pn_ptcp_seq_id, &seq_id); |
||
718 | |||
719 | /* Padding 6 bytes */ |
||
720 | offset = dissect_pn_padding(tvb, offset, pinfo, header_tree, 6); |
||
721 | |||
722 | col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq=%3u", name, seq_id); |
||
723 | proto_item_append_text(item, "%s: Sequence=%u", name_short, seq_id); |
||
724 | proto_item_append_text(header_item, ": Sequence=%u", seq_id); |
||
725 | |||
726 | |||
727 | /* dissect the PDU */ |
||
728 | offset = dissect_PNPTCP_blocks(tvb, offset, pinfo, tree, item, u16FrameID); |
||
729 | |||
730 | return offset; |
||
731 | } |
||
732 | |||
733 | |||
734 | static int |
||
735 | dissect_PNPTCP_DelayPDU(tvbuff_t *tvb, int offset, |
||
736 | packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 u16FrameID, |
||
737 | const char *name, const char *name_short) |
||
738 | { |
||
739 | proto_item *header_item; |
||
740 | proto_tree *header_tree; |
||
741 | guint16 seq_id; |
||
742 | guint32 delay1ns; |
||
743 | |||
744 | |||
745 | /* dissect the header */ |
||
746 | header_item = proto_tree_add_item(tree, hf_pn_ptcp_header, tvb, offset, 20 /* len */, ENC_NA); |
||
747 | header_tree = proto_item_add_subtree(header_item, ett_pn_ptcp_header); |
||
748 | |||
749 | /* Padding 12 bytes */ |
||
750 | offset = dissect_pn_padding(tvb, offset, pinfo, header_tree, 12); |
||
751 | |||
752 | /* SequenceID */ |
||
753 | offset = dissect_pn_uint16(tvb, offset, pinfo, header_tree, hf_pn_ptcp_seq_id, &seq_id); |
||
754 | |||
755 | /* Padding */ |
||
756 | offset = dissect_pn_align4(tvb, offset, pinfo, header_tree); |
||
757 | |||
758 | /* Delay1ns_FUP */ |
||
759 | offset = dissect_pn_uint32(tvb, offset, pinfo, header_tree, hf_pn_ptcp_delay1ns, &delay1ns); |
||
760 | |||
761 | col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq=%3u, Delay=%11uns", name, seq_id, delay1ns); |
||
762 | proto_item_append_text(item, "%s: Sequence=%u, Delay=%uns", name_short, seq_id, delay1ns); |
||
763 | proto_item_append_text(header_item, ": Sequence=%u, Delay=%uns", seq_id, delay1ns); |
||
764 | |||
765 | |||
766 | /* dissect the PDU */ |
||
767 | offset = dissect_PNPTCP_blocks(tvb, offset, pinfo, tree, item, u16FrameID); |
||
768 | |||
769 | return offset; |
||
770 | } |
||
771 | |||
772 | |||
773 | /* possibly dissect a PN-RT packet (frame ID must be in the appropriate range) */ |
||
774 | static gboolean |
||
775 | dissect_PNPTCP_Data_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
||
776 | { |
||
777 | /* the tvb will NOT contain the frame_id here, so get it from dissector data! */ |
||
778 | guint16 u16FrameID = GPOINTER_TO_UINT(data); |
||
779 | proto_item *item; |
||
780 | proto_tree *ptcp_tree; |
||
781 | int offset = 0; |
||
782 | guint32 u32SubStart; |
||
783 | |||
784 | |||
785 | /* frame id must be in valid range (acyclic Real-Time, PTCP) */ |
||
786 | /* 0x0000 - 0x007F: RTSyncPDU (with follow up) */ |
||
787 | /* 0x0080 - 0x00FF: RTSyncPDU (without follow up) */ |
||
788 | /* 0xFF00 - 0xFF1F: AnnouncePDU */ |
||
789 | /* 0xFF20 - 0xFF3F: FollowUpPDU */ |
||
790 | /* 0xFF40 - 0xFF5F: Delay...PDU */ |
||
791 | if ( ((u16FrameID >= 0x0100) && (u16FrameID < 0xFF00)) || (u16FrameID > 0xFF5F) ) { |
||
792 | /* we are not interested in this packet */ |
||
793 | return FALSE; |
||
794 | } |
||
795 | |||
796 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "PN-PTCP"); |
||
797 | col_clear(pinfo->cinfo, COL_INFO); |
||
798 | |||
799 | /* subtree for PTCP */ |
||
800 | item = proto_tree_add_protocol_format(tree, proto_pn_ptcp, tvb, 0, 0, "PROFINET PTCP, "); |
||
801 | ptcp_tree = proto_item_add_subtree(item, ett_pn_ptcp); |
||
802 | u32SubStart = offset; |
||
803 | |||
804 | switch (u16FrameID) { |
||
805 | /* range 1 (0x0000 - 0x007F) */ |
||
806 | /* 0x0000 - 0x001F reserved */ |
||
807 | case 0x0020: |
||
808 | offset = dissect_PNPTCP_RTSyncPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID, |
||
809 | "RTSync FU (Clock)", "RTSync FU (Clock)"); |
||
810 | break; |
||
811 | case 0x0021: |
||
812 | offset = dissect_PNPTCP_RTSyncPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID, |
||
813 | "RTSync FU (Time)", "RTSync FU (Time)"); |
||
814 | break; |
||
815 | /* 0x0022 - 0x007F reserved */ |
||
816 | |||
817 | /* range 2 (0x0080 - 0x00FF) */ |
||
818 | case 0x0080: |
||
819 | offset = dissect_PNPTCP_RTSyncPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID, |
||
820 | "RTSync (Clock)", "RTSync (Clock)"); |
||
821 | break; |
||
822 | case 0x0081: |
||
823 | offset = dissect_PNPTCP_RTSyncPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID, |
||
824 | "RTSync (Time)", "RTSync (Time)"); |
||
825 | break; |
||
826 | /* 0x0081 - 0x00FF reserved */ |
||
827 | |||
828 | /* range 7 (0xFF00 - 0xFF5F) */ |
||
829 | case 0xff00: |
||
830 | offset = dissect_PNPTCP_AnnouncePDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID, |
||
831 | "Announce (Clock)", "Announce (Clock)"); |
||
832 | break; |
||
833 | case 0xff01: |
||
834 | offset = dissect_PNPTCP_AnnouncePDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID, |
||
835 | "Announce (Time)", "Announce (Time)"); |
||
836 | break; |
||
837 | /* 0xFF02 - 0xFF1F reserved */ |
||
838 | case 0xff20: |
||
839 | offset = dissect_PNPTCP_FollowUpPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID, |
||
840 | "FollowUp (Clock)", "FollowUp (Clock)"); |
||
841 | break; |
||
842 | case 0xff21: |
||
843 | offset = dissect_PNPTCP_FollowUpPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID, |
||
844 | "FollowUp (Time)", "FollowUp (Time)"); |
||
845 | break; |
||
846 | /* 0xFF22 - 0xFF3F reserved */ |
||
847 | case 0xff40: |
||
848 | offset = dissect_PNPTCP_DelayPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID, |
||
849 | "DelayReq ", "DelayReq"); |
||
850 | break; |
||
851 | case 0xff41: |
||
852 | offset = dissect_PNPTCP_DelayPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID, |
||
853 | "DelayRes ", "DelayRes"); |
||
854 | break; |
||
855 | case 0xff42: |
||
856 | offset = dissect_PNPTCP_DelayPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID, |
||
857 | "DelayFuRes ", "DelayFuRes"); |
||
858 | break; |
||
859 | case 0xff43: |
||
860 | offset = dissect_PNPTCP_DelayPDU(tvb, offset, pinfo, ptcp_tree, item, u16FrameID, |
||
861 | "DelayRes ", "DelayRes"); |
||
862 | break; |
||
863 | /* 0xFF44 - 0xFF5F reserved */ |
||
864 | default: |
||
865 | offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, tvb_captured_length_remaining(tvb, offset)); |
||
866 | |||
867 | col_append_fstr(pinfo->cinfo, COL_INFO, "Reserved FrameID 0x%04x", u16FrameID); |
||
868 | |||
869 | proto_item_append_text(item, "Reserved FrameID 0x%04x", u16FrameID); |
||
870 | |||
871 | offset += tvb_captured_length_remaining(tvb, offset); |
||
872 | break; |
||
873 | } |
||
874 | |||
875 | proto_item_set_len(item, offset - u32SubStart); |
||
876 | |||
877 | return TRUE; |
||
878 | } |
||
879 | |||
880 | |||
881 | void |
||
882 | proto_register_pn_ptcp (void) |
||
883 | { |
||
884 | static hf_register_info hf[] = { |
||
885 | { &hf_pn_ptcp_header, |
||
886 | { "Header", "pn_ptcp.header", |
||
887 | FT_NONE, BASE_NONE, NULL, 0x0, |
||
888 | NULL, HFILL }}, |
||
889 | |||
890 | { &hf_pn_ptcp_block, |
||
891 | { "Block", "pn_ptcp.block", |
||
892 | FT_NONE, BASE_NONE, NULL, 0x0, |
||
893 | NULL, HFILL }}, |
||
894 | |||
895 | { &hf_pn_ptcp_block_tlvheader, |
||
896 | { "TLVHeader", "pn_ptcp.tlvheader", |
||
897 | FT_NONE, BASE_NONE, NULL, 0x0, |
||
898 | NULL, HFILL }}, |
||
899 | |||
900 | |||
901 | { &hf_pn_ptcp_res1, |
||
902 | { "Reserved 1", "pn_ptcp.res1", |
||
903 | FT_UINT32, BASE_DEC, NULL, 0x0, |
||
904 | NULL, HFILL }}, |
||
905 | |||
906 | { &hf_pn_ptcp_res2, |
||
907 | { "Reserved 2", "pn_ptcp.res2", |
||
908 | FT_UINT32, BASE_DEC, NULL, 0x0, |
||
909 | NULL, HFILL }}, |
||
910 | |||
911 | { &hf_pn_ptcp_delay10ns, |
||
912 | { "Delay10ns", "pn_ptcp.delay10ns", |
||
913 | FT_UINT32, BASE_DEC, NULL, 0x0, |
||
914 | NULL, HFILL }}, |
||
915 | |||
916 | { &hf_pn_ptcp_seq_id, |
||
917 | { "SequenceID", "pn_ptcp.sequence_id", |
||
918 | FT_UINT16, BASE_DEC, NULL, 0x0, |
||
919 | NULL, HFILL }}, |
||
920 | |||
921 | { &hf_pn_ptcp_delay1ns_byte, |
||
922 | { "Delay1ns_Byte", "pn_ptcp.delay1ns_byte", |
||
923 | FT_UINT8, BASE_DEC, NULL, 0x0, |
||
924 | NULL, HFILL }}, |
||
925 | |||
926 | { &hf_pn_ptcp_delay1ns, |
||
927 | { "Delay1ns", "pn_ptcp.delay1ns", |
||
928 | FT_UINT32, BASE_DEC, NULL, 0x0, |
||
929 | NULL, HFILL }}, |
||
930 | |||
931 | { &hf_pn_ptcp_delay1ns_fup, |
||
932 | { "Delay1ns_FUP", "pn_ptcp.delay1ns_fup", |
||
933 | FT_INT32, BASE_DEC, NULL, 0x0, |
||
934 | NULL, HFILL }}, |
||
935 | |||
936 | |||
937 | { &hf_pn_ptcp_tl_length, |
||
938 | { "TypeLength.Length", "pn_ptcp.tl_length", |
||
939 | FT_UINT16, BASE_DEC, 0x0, 0x1FF, |
||
940 | NULL, HFILL }}, |
||
941 | |||
942 | { &hf_pn_ptcp_tl_type, |
||
943 | { "TypeLength.Type", "pn_ptcp.tl_type", |
||
944 | FT_UINT16, BASE_DEC, 0x0, 0xFE00, |
||
945 | NULL, HFILL }}, |
||
946 | |||
947 | |||
948 | { &hf_pn_ptcp_master_source_address, |
||
949 | { "MasterSourceAddress", "pn_ptcp.master_source_address", |
||
950 | FT_ETHER, BASE_NONE, 0x0, 0x0, |
||
951 | NULL, HFILL }}, |
||
952 | |||
953 | { &hf_pn_ptcp_subdomain_uuid, |
||
954 | { "SubdomainUUID", "pn_ptcp.subdomain_uuid", |
||
955 | FT_GUID, BASE_NONE, 0x0, 0x0, |
||
956 | NULL, HFILL }}, |
||
957 | |||
958 | |||
959 | { &hf_pn_ptcp_port_mac_address, |
||
960 | { "PortMACAddress", "pn_ptcp.port_mac_address", |
||
961 | FT_ETHER, BASE_NONE, 0x0, 0x0, |
||
962 | NULL, HFILL }}, |
||
963 | |||
964 | |||
965 | { &hf_pn_ptcp_t2portrxdelay, |
||
966 | { "T2PortRxDelay (ns)", "pn_ptcp.t2portrxdelay", |
||
967 | FT_UINT32, BASE_DEC, 0x0, 0x0, |
||
968 | NULL, HFILL }}, |
||
969 | |||
970 | { &hf_pn_ptcp_t3porttxdelay, |
||
971 | { "T3PortTxDelay (ns)", "pn_ptcp.t3porttxdelay", |
||
972 | FT_UINT32, BASE_DEC, 0x0, 0x0, |
||
973 | NULL, HFILL }}, |
||
974 | |||
975 | { &hf_pn_ptcp_t2timestamp, |
||
976 | { "T2TimeStamp (ns)", "pn_ptcp.t2timestamp", |
||
977 | FT_UINT32, BASE_DEC, 0x0, 0x0, |
||
978 | NULL, HFILL }}, |
||
979 | |||
980 | |||
981 | { &hf_pn_ptcp_epoch_number, |
||
982 | { "EpochNumber", "pn_ptcp.epoch_number", |
||
983 | FT_UINT16, BASE_DEC, 0x0, 0x0, |
||
984 | NULL, HFILL }}, |
||
985 | |||
986 | { &hf_pn_ptcp_seconds, |
||
987 | { "Seconds", "pn_ptcp.seconds", |
||
988 | FT_UINT32, BASE_DEC, 0x0, 0x0, |
||
989 | NULL, HFILL }}, |
||
990 | |||
991 | { &hf_pn_ptcp_nanoseconds, |
||
992 | { "NanoSeconds", "pn_ptcp.nanoseconds", |
||
993 | FT_UINT32, BASE_DEC, 0x0, 0x0, |
||
994 | NULL, HFILL }}, |
||
995 | |||
996 | |||
997 | { &hf_pn_ptcp_flags, |
||
998 | { "Flags", "pn_ptcp.flags", |
||
999 | FT_UINT16, BASE_HEX, 0x0, 0x0, |
||
1000 | NULL, HFILL }}, |
||
1001 | |||
1002 | { &hf_pn_ptcp_currentutcoffset, |
||
1003 | { "CurrentUTCOffset", "pn_ptcp.currentutcoffset", |
||
1004 | FT_UINT16, BASE_DEC, 0x0, 0x0, |
||
1005 | NULL, HFILL }}, |
||
1006 | |||
1007 | |||
1008 | { &hf_pn_ptcp_master_priority1, |
||
1009 | { "MasterPriority1.Priority", "pn_ptcp.master_priority1_prio", |
||
1010 | FT_UINT8, BASE_HEX, VALS(pn_ptcp_master_prio1_vals), 0x07, |
||
1011 | NULL, HFILL }}, |
||
1012 | |||
1013 | { &hf_pn_ptcp_master_priority_level, |
||
1014 | { "MasterPriority1.Level", "pn_ptcp.master_priority1_level", |
||
1015 | FT_UINT8, BASE_HEX, VALS(pn_ptcp_master_prio1_levels), 0x38, |
||
1016 | NULL, HFILL }}, |
||
1017 | |||
1018 | { &hf_pn_ptcp_master_priority1_res, |
||
1019 | { "MasterPriority1.Reserved", "pn_ptcp.master_priority1_res", |
||
1020 | FT_UINT8, BASE_HEX, 0x0, 0x40, |
||
1021 | NULL, HFILL }}, |
||
1022 | |||
1023 | { &hf_pn_ptcp_master_priority1_act, |
||
1024 | { "MasterPriority1.Active", "pn_ptcp.master_priority1_act", |
||
1025 | FT_UINT8, BASE_HEX, VALS(pn_ptcp_master_prio1_vals_active), 0x80, |
||
1026 | NULL, HFILL }}, |
||
1027 | |||
1028 | { &hf_pn_ptcp_master_priority2, |
||
1029 | { "MasterPriority2", "pn_ptcp.master_priority2", |
||
1030 | FT_UINT8, BASE_DEC, VALS(pn_ptcp_master_prio2_vals), 0x0, |
||
1031 | NULL, HFILL }}, |
||
1032 | |||
1033 | { &hf_pn_ptcp_clock_class, |
||
1034 | { "ClockClass", "pn_ptcp.clock_class", |
||
1035 | FT_UINT8, BASE_DEC, VALS(pn_ptcp_clock_class_vals), 0x0, |
||
1036 | NULL, HFILL }}, |
||
1037 | |||
1038 | { &hf_pn_ptcp_clock_accuracy, |
||
1039 | { "ClockAccuracy", "pn_ptcp.clock_accuracy", |
||
1040 | FT_UINT8, BASE_DEC, VALS(pn_ptcp_clock_accuracy_vals), 0x0, |
||
1041 | NULL, HFILL }}, |
||
1042 | |||
1043 | { &hf_pn_ptcp_clockvariance, |
||
1044 | { "ClockVariance", "pn_ptcp.clockvariance", |
||
1045 | FT_INT16, BASE_DEC, 0x0, 0x0, |
||
1046 | NULL, HFILL }}, |
||
1047 | |||
1048 | |||
1049 | { &hf_pn_ptcp_oui, |
||
1050 | { "Organizationally Unique Identifier", "pn_ptcp.oui", |
||
1051 | FT_UINT24, BASE_HEX, VALS(pn_ptcp_oui_vals), 0x0, |
||
1052 | NULL, HFILL }}, |
||
1053 | |||
1054 | { &hf_pn_ptcp_profinet_subtype, |
||
1055 | { "Subtype", "pn_ptcp.subtype", |
||
1056 | FT_UINT8, BASE_HEX, VALS(pn_ptcp_profinet_subtype_vals), 0x0, |
||
1057 | "PROFINET Subtype", HFILL }}, |
||
1058 | |||
1059 | |||
1060 | { &hf_pn_ptcp_irdata_uuid, |
||
1061 | { "IRDataUUID", "pn_ptcp.irdata_uuid", |
||
1062 | FT_GUID, BASE_NONE, 0x0, 0x0, |
||
1063 | NULL, HFILL }}, |
||
1064 | |||
1065 | }; |
||
1066 | |||
1067 | static gint *ett[] = { |
||
1068 | &ett_pn_ptcp, |
||
1069 | &ett_pn_ptcp_header, |
||
1070 | &ett_pn_ptcp_block, |
||
1071 | &ett_pn_ptcp_block_header |
||
1072 | }; |
||
1073 | proto_pn_ptcp = proto_register_protocol ("PROFINET PTCP", "PN-PTCP", "pn_ptcp"); |
||
1074 | proto_register_field_array (proto_pn_ptcp, hf, array_length (hf)); |
||
1075 | proto_register_subtree_array (ett, array_length (ett)); |
||
1076 | } |
||
1077 | |||
1078 | void |
||
1079 | proto_reg_handoff_pn_ptcp (void) |
||
1080 | { |
||
1081 | /* register ourself as an heuristic pn-rt payload dissector */ |
||
1082 | heur_dissector_add("pn_rt", dissect_PNPTCP_Data_heur, "PROFINET PTCP IO", "pn_ptcp_pn_rt", proto_pn_ptcp, HEURISTIC_ENABLE); |
||
1083 | } |
||
1084 | |||
1085 | /* |
||
1086 | * Editor modelines - http://www.wireshark.org/tools/modelines.html |
||
1087 | * |
||
1088 | * Local variables: |
||
1089 | * c-basic-offset: 4 |
||
1090 | * tab-width: 8 |
||
1091 | * indent-tabs-mode: nil |
||
1092 | * End: |
||
1093 | * |
||
1094 | * vi: set shiftwidth=4 tabstop=8 expandtab: |
||
1095 | * :indentSize=4:tabSize=8:noTabs=true: |
||
1096 | */ |