3 * Author: Thomas Wiens, 2014 (th.wiens@gmx.de)
4 * Description: Wireshark dissector for S7-Communication
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
15 #include <epan/packet.h>
16 #include <epan/reassemble.h>
19 #include <wsutil/array.h>
20 #include <wsutil/strtoi.h>
21 #include <epan/expert.h>
23 #include "packet-s7comm.h"
24 #include "packet-s7comm_szl_ids.h"
26 #define PROTO_TAG_S7COMM "S7COMM"
28 /* Min. telegram length for heuristic check */
29 #define S7COMM_MIN_TELEGRAM_LENGTH 10
31 /* Protocol identifier */
32 #define S7COMM_PROT_ID 0x32
34 /* Wireshark ID of the S7COMM protocol */
35 static int proto_s7comm
;
37 /* Forward declarations */
38 void proto_reg_handoff_s7comm(void);
39 void proto_register_s7comm (void);
40 static uint32_t s7comm_decode_ud_tis_data(tvbuff_t
*tvb
, proto_tree
*tree
, uint8_t type
, uint8_t subfunc
, uint16_t td_size
, uint32_t offset
);
42 /**************************************************************************
45 #define S7COMM_ROSCTR_JOB 0x01
46 #define S7COMM_ROSCTR_ACK 0x02
47 #define S7COMM_ROSCTR_ACK_DATA 0x03
48 #define S7COMM_ROSCTR_USERDATA 0x07
50 static const value_string rosctr_names
[] = {
51 { S7COMM_ROSCTR_JOB
, "Job" }, /* Request: job with acknowledgement */
52 { S7COMM_ROSCTR_ACK
, "Ack" }, /* acknowledgement without additional field */
53 { S7COMM_ROSCTR_ACK_DATA
, "Ack_Data" }, /* Response: acknowledgement with additional field */
54 { S7COMM_ROSCTR_USERDATA
, "Userdata" },
57 /**************************************************************************
58 * Error classes in header
60 #define S7COMM_ERRCLS_NONE 0x00
61 #define S7COMM_ERRCLS_APPREL 0x81
62 #define S7COMM_ERRCLS_OBJDEF 0x82
63 #define S7COMM_ERRCLS_RESOURCE 0x83
64 #define S7COMM_ERRCLS_SERVICE 0x84
65 #define S7COMM_ERRCLS_SUPPLIES 0x85
66 #define S7COMM_ERRCLS_ACCESS 0x87
68 static const value_string errcls_names
[] = {
69 { S7COMM_ERRCLS_NONE
, "No error" },
70 { S7COMM_ERRCLS_APPREL
, "Application relationship" },
71 { S7COMM_ERRCLS_OBJDEF
, "Object definition" },
72 { S7COMM_ERRCLS_RESOURCE
, "No resources available" },
73 { S7COMM_ERRCLS_SERVICE
, "Error on service processing" },
74 { S7COMM_ERRCLS_SUPPLIES
, "Error on supplies" },
75 { S7COMM_ERRCLS_ACCESS
, "Access error" },
79 /**************************************************************************
80 * Error code in parameter part
83 static const value_string param_errcode_names
[] = {
84 { 0x0000, "No error" },
85 { 0x0110, "Invalid block number" },
86 { 0x0111, "Invalid request length" },
87 { 0x0112, "Invalid parameter" },
88 { 0x0113, "Invalid block type" },
89 { 0x0114, "Block not found" },
90 { 0x0115, "Block already exists" },
91 { 0x0116, "Block is write-protected" },
92 { 0x0117, "The block/operating system update is too large" },
93 { 0x0118, "Invalid block number" },
94 { 0x0119, "Incorrect password entered" },
95 { 0x011A, "PG resource error" },
96 { 0x011B, "PLC resource error" },
97 { 0x011C, "Protocol error" },
98 { 0x011D, "Too many blocks (module-related restriction)" },
99 { 0x011E, "There is no longer a connection to the database, or S7DOS handle is invalid" },
100 { 0x011F, "Result buffer too small" },
101 { 0x0120, "End of block list" },
102 { 0x0140, "Insufficient memory available" },
103 { 0x0141, "Job cannot be processed because of a lack of resources" },
104 { 0x8001, "The requested service cannot be performed while the block is in the current status" },
105 { 0x8003, "S7 protocol error: Error occurred while transferring the block" },
106 { 0x8100, "Application, general error: Service unknown to remote module" },
107 { 0x8104, "This service is not implemented on the module or a frame error was reported" },
108 { 0x8204, "The type specification for the object is inconsistent" },
109 { 0x8205, "A copied block already exists and is not linked" },
110 { 0x8301, "Insufficient memory space or work memory on the module, or specified storage medium not accessible" },
111 { 0x8302, "Too few resources available or the processor resources are not available" },
112 { 0x8304, "No further parallel upload possible. There is a resource bottleneck" },
113 { 0x8305, "Function not available" },
114 { 0x8306, "Insufficient work memory (for copying, linking, loading AWP)" },
115 { 0x8307, "Not enough retentive work memory (for copying, linking, loading AWP)" },
116 { 0x8401, "S7 protocol error: Invalid service sequence (for example, loading or uploading a block)" },
117 { 0x8402, "Service cannot execute owing to status of the addressed object" },
118 { 0x8404, "S7 protocol: The function cannot be performed" },
119 { 0x8405, "Remote block is in DISABLE state (CFB). The function cannot be performed" },
120 { 0x8500, "S7 protocol error: Wrong frames" },
121 { 0x8503, "Alarm from the module: Service canceled prematurely" },
122 { 0x8701, "Error addressing the object on the communications partner (for example, area length error)" },
123 { 0x8702, "The requested service is not supported by the module" },
124 { 0x8703, "Access to object refused" },
125 { 0x8704, "Access error: Object damaged" },
126 { 0xD001, "Protocol error: Illegal job number" },
127 { 0xD002, "Parameter error: Illegal job variant" },
128 { 0xD003, "Parameter error: Debugging function not supported by module" },
129 { 0xD004, "Parameter error: Illegal job status" },
130 { 0xD005, "Parameter error: Illegal job termination" },
131 { 0xD006, "Parameter error: Illegal link disconnection ID" },
132 { 0xD007, "Parameter error: Illegal number of buffer elements" },
133 { 0xD008, "Parameter error: Illegal scan rate" },
134 { 0xD009, "Parameter error: Illegal number of executions" },
135 { 0xD00A, "Parameter error: Illegal trigger event" },
136 { 0xD00B, "Parameter error: Illegal trigger condition" },
137 { 0xD011, "Parameter error in path of the call environment: Block does not exist" },
138 { 0xD012, "Parameter error: Wrong address in block" },
139 { 0xD014, "Parameter error: Block being deleted/overwritten" },
140 { 0xD015, "Parameter error: Illegal tag address" },
141 { 0xD016, "Parameter error: Test jobs not possible, because of errors in user program" },
142 { 0xD017, "Parameter error: Illegal trigger number" },
143 { 0xD025, "Parameter error: Invalid path" },
144 { 0xD026, "Parameter error: Illegal access type" },
145 { 0xD027, "Parameter error: This number of data blocks is not permitted" },
146 { 0xD031, "Internal protocol error" },
147 { 0xD032, "Parameter error: Wrong result buffer length" },
148 { 0xD033, "Protocol error: Wrong job length" },
149 { 0xD03F, "Coding error: Error in parameter section (for example, reserve bytes not equal to 0)" },
150 { 0xD041, "Data error: Illegal status list ID" },
151 { 0xD042, "Data error: Illegal tag address" },
152 { 0xD043, "Data error: Referenced job not found, check job data" },
153 { 0xD044, "Data error: Illegal tag value, check job data" },
154 { 0xD045, "Data error: Exiting the ODIS control is not allowed in HOLD" },
155 { 0xD046, "Data error: Illegal measuring stage during run-time measurement" },
156 { 0xD047, "Data error: Illegal hierarchy in 'Read job list'" },
157 { 0xD048, "Data error: Illegal deletion ID in 'Delete job'" },
158 { 0xD049, "Invalid substitute ID in 'Replace job'" },
159 { 0xD04A, "Error executing 'program status'" },
160 { 0xD05F, "Coding error: Error in data section (for example, reserve bytes not equal to 0, ...)" },
161 { 0xD061, "Resource error: No memory space for job" },
162 { 0xD062, "Resource error: Job list full" },
163 { 0xD063, "Resource error: Trigger event occupied" },
164 { 0xD064, "Resource error: Not enough memory space for one result buffer element" },
165 { 0xD065, "Resource error: Not enough memory space for several result buffer elements" },
166 { 0xD066, "Resource error: The timer available for run-time measurement is occupied by another job" },
167 { 0xD067, "Resource error: Too many 'modify tag' jobs active (in particular multi-processor operation)" },
168 { 0xD081, "Function not permitted in current mode" },
169 { 0xD082, "Mode error: Cannot exit HOLD mode" },
170 { 0xD0A1, "Function not permitted in current protection level" },
171 { 0xD0A2, "Function not possible at present, because a function is running that modifies memory" },
172 { 0xD0A3, "Too many 'modify tag' jobs active on the I/O (in particular multi-processor operation)" },
173 { 0xD0A4, "'Forcing' has already been established" },
174 { 0xD0A5, "Referenced job not found" },
175 { 0xD0A6, "Job cannot be disabled/enabled" },
176 { 0xD0A7, "Job cannot be deleted, for example because it is currently being read" },
177 { 0xD0A8, "Job cannot be replaced, for example because it is currently being read or deleted" },
178 { 0xD0A9, "Job cannot be read, for example because it is currently being deleted" },
179 { 0xD0AA, "Time limit exceeded in processing operation" },
180 { 0xD0AB, "Invalid job parameters in process operation" },
181 { 0xD0AC, "Invalid job data in process operation" },
182 { 0xD0AD, "Operating mode already set" },
183 { 0xD0AE, "The job was set up over a different connection and can only be handled over this connection" },
184 { 0xD0C1, "At least one error has been detected while accessing the tag(s)" },
185 { 0xD0C2, "Change to STOP/HOLD mode" },
186 { 0xD0C3, "At least one error was detected while accessing the tag(s). Mode change to STOP/HOLD" },
187 { 0xD0C4, "Timeout during run-time measurement" },
188 { 0xD0C5, "Display of block stack inconsistent, because blocks were deleted/reloaded" },
189 { 0xD0C6, "Job was automatically deleted as the jobs it referenced have been deleted" },
190 { 0xD0C7, "The job was automatically deleted because STOP mode was exited" },
191 { 0xD0C8, "'Block status' aborted because of inconsistencies between test job and running program" },
192 { 0xD0C9, "Exit the status area by resetting OB90" },
193 { 0xD0CA, "Exiting the status range by resetting OB90 and access error reading tags before exiting" },
194 { 0xD0CB, "The output disable for the peripheral outputs has been activated again" },
195 { 0xD0CC, "The amount of data for the debugging functions is restricted by the time limit" },
196 { 0xD201, "Syntax error in block name" },
197 { 0xD202, "Syntax error in function parameters" },
198 { 0xD205, "Linked block already exists in RAM: Conditional copying is not possible" },
199 { 0xD206, "Linked block already exists in EPROM: Conditional copying is not possible" },
200 { 0xD208, "Maximum number of copied (not linked) blocks on module exceeded" },
201 { 0xD209, "(At least) one of the given blocks not found on the module" },
202 { 0xD20A, "The maximum number of blocks that can be linked with one job was exceeded" },
203 { 0xD20B, "The maximum number of blocks that can be deleted with one job was exceeded" },
204 { 0xD20C, "OB cannot be copied because the associated priority class does not exist" },
205 { 0xD20D, "SDB cannot be interpreted (for example, unknown number)" },
206 { 0xD20E, "No (further) block available" },
207 { 0xD20F, "Module-specific maximum block size exceeded" },
208 { 0xD210, "Invalid block number" },
209 { 0xD212, "Incorrect header attribute (run-time relevant)" },
210 { 0xD213, "Too many SDBs. Note the restrictions on the module being used" },
211 { 0xD216, "Invalid user program - reset module" },
212 { 0xD217, "Protection level specified in module properties not permitted" },
213 { 0xD218, "Incorrect attribute (active/passive)" },
214 { 0xD219, "Incorrect block lengths (for example, incorrect length of first section or of the whole block)" },
215 { 0xD21A, "Incorrect local data length or write-protection code faulty" },
216 { 0xD21B, "Module cannot compress or compression was interrupted early" },
217 { 0xD21D, "The volume of dynamic project data transferred is illegal" },
218 { 0xD21E, "Unable to assign parameters to a module (such as FM, CP). The system data could not be linked" },
219 { 0xD220, "Invalid programming language. Note the restrictions on the module being used" },
220 { 0xD221, "The system data for connections or routing are not valid" },
221 { 0xD222, "The system data of the global data definition contain invalid parameters" },
222 { 0xD223, "Error in instance data block for communication function block or maximum number of instance DBs exceeded" },
223 { 0xD224, "The SCAN system data block contains invalid parameters" },
224 { 0xD225, "The DP system data block contains invalid parameters" },
225 { 0xD226, "A structural error occurred in a block" },
226 { 0xD230, "A structural error occurred in a block" },
227 { 0xD231, "At least one loaded OB cannot be copied because the associated priority class does not exist" },
228 { 0xD232, "At least one block number of a loaded block is illegal" },
229 { 0xD234, "Block exists twice in the specified memory medium or in the job" },
230 { 0xD235, "The block contains an incorrect checksum" },
231 { 0xD236, "The block does not contain a checksum" },
232 { 0xD237, "You are about to load the block twice, i.e. a block with the same time stamp already exists on the CPU" },
233 { 0xD238, "At least one of the blocks specified is not a DB" },
234 { 0xD239, "At least one of the DBs specified is not available as a linked variant in the load memory" },
235 { 0xD23A, "At least one of the specified DBs is considerably different from the copied and linked variant" },
236 { 0xD240, "Coordination rules violated" },
237 { 0xD241, "The function is not permitted in the current protection level" },
238 { 0xD242, "Protection violation while processing F blocks" },
239 { 0xD250, "Update and module ID or version do not match" },
240 { 0xD251, "Incorrect sequence of operating system components" },
241 { 0xD252, "Checksum error" },
242 { 0xD253, "No executable loader available; update only possible using a memory card" },
243 { 0xD254, "Storage error in operating system" },
244 { 0xD280, "Error compiling block in S7-300 CPU" },
245 { 0xD2A1, "Another block function or a trigger on a block is active" },
246 { 0xD2A2, "A trigger is active on a block. Complete the debugging function first" },
247 { 0xD2A3, "The block is not active (linked), the block is occupied or the block is currently marked for deletion" },
248 { 0xD2A4, "The block is already being processed by another block function" },
249 { 0xD2A6, "It is not possible to save and change the user program simultaneously" },
250 { 0xD2A7, "The block has the attribute 'unlinked' or is not processed" },
251 { 0xD2A8, "An active debugging function is preventing parameters from being assigned to the CPU" },
252 { 0xD2A9, "New parameters are being assigned to the CPU" },
253 { 0xD2AA, "New parameters are currently being assigned to the modules" },
254 { 0xD2AB, "The dynamic configuration limits are currently being changed" },
255 { 0xD2AC, "A running active or deactivate assignment (SFC 12) is temporarily preventing R-KiR process" },
256 { 0xD2B0, "An error occurred while configuring in RUN (CiR)" },
257 { 0xD2C0, "The maximum number of technological objects has been exceeded" },
258 { 0xD2C1, "The same technology data block already exists on the module" },
259 { 0xD2C2, "Downloading the user program or downloading the hardware configuration is not possible" },
260 { 0xD401, "Information function unavailable" },
261 { 0xD402, "Information function unavailable" },
262 { 0xD403, "Service has already been logged on/off (Diagnostics/PMC)" },
263 { 0xD404, "Maximum number of nodes reached. No more logons possible for diagnostics/PMC" },
264 { 0xD405, "Service not supported or syntax error in function parameters" },
265 { 0xD406, "Required information currently unavailable" },
266 { 0xD407, "Diagnostics error occurred" },
267 { 0xD408, "Update aborted" },
268 { 0xD409, "Error on DP bus" },
269 { 0xD601, "Syntax error in function parameter" },
270 { 0xD602, "Incorrect password entered" },
271 { 0xD603, "The connection has already been legitimized" },
272 { 0xD604, "The connection has already been enabled" },
273 { 0xD605, "Legitimization not possible because password does not exist" },
274 { 0xD801, "At least one tag address is invalid" },
275 { 0xD802, "Specified job does not exist" },
276 { 0xD803, "Illegal job status" },
277 { 0xD804, "Illegal cycle time (illegal time base or multiple)" },
278 { 0xD805, "No more cyclic read jobs can be set up" },
279 { 0xD806, "The referenced job is in a state in which the requested function cannot be performed" },
280 { 0xD807, "Function aborted due to overload, meaning executing the read cycle takes longer than the set scan cycle time" },
281 { 0xDC01, "Date and/or time invalid" },
282 { 0xE201, "CPU is already the master" },
283 { 0xE202, "Connect and update not possible due to different user program in flash module" },
284 { 0xE203, "Connect and update not possible due to different firmware" },
285 { 0xE204, "Connect and update not possible due to different memory configuration" },
286 { 0xE205, "Connect/update aborted due to synchronization error" },
287 { 0xE206, "Connect/update denied due to coordination violation" },
288 { 0xEF01, "S7 protocol error: Error at ID2; only 00H permitted in job" },
289 { 0xEF02, "S7 protocol error: Error at ID2; set of resources does not exist" },
292 static value_string_ext param_errcode_names_ext
= VALUE_STRING_EXT_INIT(param_errcode_names
);
294 /**************************************************************************
295 * Function codes in parameter part
297 #define S7COMM_SERV_CPU 0x00
298 #define S7COMM_SERV_MODETRANS 0x01
299 #define S7COMM_SERV_SETUPCOMM 0xF0
300 #define S7COMM_SERV_READVAR 0x04
301 #define S7COMM_SERV_WRITEVAR 0x05
303 #define S7COMM_FUNCREQUESTDOWNLOAD 0x1A
304 #define S7COMM_FUNCDOWNLOADBLOCK 0x1B
305 #define S7COMM_FUNCDOWNLOADENDED 0x1C
306 #define S7COMM_FUNCSTARTUPLOAD 0x1D
307 #define S7COMM_FUNCUPLOAD 0x1E
308 #define S7COMM_FUNCENDUPLOAD 0x1F
309 #define S7COMM_FUNCPISERVICE 0x28
310 #define S7COMM_FUNC_PLC_STOP 0x29
312 static const value_string param_functionnames
[] = {
313 { S7COMM_SERV_CPU
, "CPU services" },
314 { S7COMM_SERV_MODETRANS
, "Mode transition" },
315 { S7COMM_SERV_SETUPCOMM
, "Setup communication" },
316 { S7COMM_SERV_READVAR
, "Read Var" },
317 { S7COMM_SERV_WRITEVAR
, "Write Var" },
318 /* Block management services */
319 { S7COMM_FUNCREQUESTDOWNLOAD
, "Request download" },
320 { S7COMM_FUNCDOWNLOADBLOCK
, "Download block" },
321 { S7COMM_FUNCDOWNLOADENDED
, "Download ended" },
322 { S7COMM_FUNCSTARTUPLOAD
, "Start upload" },
323 { S7COMM_FUNCUPLOAD
, "Upload" },
324 { S7COMM_FUNCENDUPLOAD
, "End upload" },
325 { S7COMM_FUNCPISERVICE
, "PI-Service" },
326 { S7COMM_FUNC_PLC_STOP
, "PLC Stop" },
329 /**************************************************************************
332 #define S7COMM_AREA_DATARECORD 0x01 /* Data record, used with RDREC or firmware updates on CP */
333 #define S7COMM_AREA_SYSINFO 0x03 /* System info of 200 family */
334 #define S7COMM_AREA_SYSFLAGS 0x05 /* System flags of 200 family */
335 #define S7COMM_AREA_ANAIN 0x06 /* analog inputs of 200 family */
336 #define S7COMM_AREA_ANAOUT 0x07 /* analog outputs of 200 family */
337 #define S7COMM_AREA_P 0x80 /* direct peripheral access */
338 #define S7COMM_AREA_INPUTS 0x81
339 #define S7COMM_AREA_OUTPUTS 0x82
340 #define S7COMM_AREA_FLAGS 0x83
341 #define S7COMM_AREA_DB 0x84 /* data blocks */
342 #define S7COMM_AREA_DI 0x85 /* instance data blocks */
343 #define S7COMM_AREA_LOCAL 0x86 /* local data (should not be accessible over network) */
344 #define S7COMM_AREA_V 0x87 /* previous (Vorgaenger) local data (should not be accessible over network) */
345 #define S7COMM_AREA_COUNTER 28 /* S7 counters */
346 #define S7COMM_AREA_TIMER 29 /* S7 timers */
347 #define S7COMM_AREA_COUNTER200 30 /* IEC counters (200 family) */
348 #define S7COMM_AREA_TIMER200 31 /* IEC timers (200 family) */
350 static const value_string item_areanames
[] = {
351 { S7COMM_AREA_DATARECORD
, "Data record" },
352 { S7COMM_AREA_SYSINFO
, "System info of 200 family" },
353 { S7COMM_AREA_SYSFLAGS
, "System flags of 200 family" },
354 { S7COMM_AREA_ANAIN
, "Analog inputs of 200 family" },
355 { S7COMM_AREA_ANAOUT
, "Analog outputs of 200 family" },
356 { S7COMM_AREA_P
, "Direct peripheral access (P)" },
357 { S7COMM_AREA_INPUTS
, "Inputs (I)" },
358 { S7COMM_AREA_OUTPUTS
, "Outputs (Q)" },
359 { S7COMM_AREA_FLAGS
, "Flags (M)" },
360 { S7COMM_AREA_DB
, "Data blocks (DB)" },
361 { S7COMM_AREA_DI
, "Instance data blocks (DI)" },
362 { S7COMM_AREA_LOCAL
, "Local data (L)" },
363 { S7COMM_AREA_V
, "Unknown yet (V)" },
364 { S7COMM_AREA_COUNTER
, "S7 counters (C)" },
365 { S7COMM_AREA_TIMER
, "S7 timers (T)" },
366 { S7COMM_AREA_COUNTER200
, "IEC counters (200 family)" },
367 { S7COMM_AREA_TIMER200
, "IEC timers (200 family)" },
371 static const value_string item_areanames_short
[] = {
372 { S7COMM_AREA_DATARECORD
, "RECORD" },
373 { S7COMM_AREA_SYSINFO
, "SI200" },
374 { S7COMM_AREA_SYSFLAGS
, "SF200" },
375 { S7COMM_AREA_ANAIN
, "AI200" },
376 { S7COMM_AREA_ANAOUT
, "AO" },
377 { S7COMM_AREA_P
, "P" },
378 { S7COMM_AREA_INPUTS
, "I" },
379 { S7COMM_AREA_OUTPUTS
, "Q" },
380 { S7COMM_AREA_FLAGS
, "M" },
381 { S7COMM_AREA_DB
, "DB" },
382 { S7COMM_AREA_DI
, "DI" },
383 { S7COMM_AREA_LOCAL
, "L" },
384 { S7COMM_AREA_V
, "V" },
385 { S7COMM_AREA_COUNTER
, "C" },
386 { S7COMM_AREA_TIMER
, "T" },
387 { S7COMM_AREA_COUNTER200
, "C200" },
388 { S7COMM_AREA_TIMER200
, "T200" },
391 /**************************************************************************
392 * Transport sizes in item data
394 /* types of 1 byte length */
395 #define S7COMM_TRANSPORT_SIZE_BIT 1
396 #define S7COMM_TRANSPORT_SIZE_BYTE 2
397 #define S7COMM_TRANSPORT_SIZE_CHAR 3
398 /* types of 2 bytes length */
399 #define S7COMM_TRANSPORT_SIZE_WORD 4
400 #define S7COMM_TRANSPORT_SIZE_INT 5
401 /* types of 4 bytes length */
402 #define S7COMM_TRANSPORT_SIZE_DWORD 6
403 #define S7COMM_TRANSPORT_SIZE_DINT 7
404 #define S7COMM_TRANSPORT_SIZE_REAL 8
406 #define S7COMM_TRANSPORT_SIZE_DATE 9
407 #define S7COMM_TRANSPORT_SIZE_TOD 10
408 #define S7COMM_TRANSPORT_SIZE_TIME 11
409 #define S7COMM_TRANSPORT_SIZE_S5TIME 12
410 #define S7COMM_TRANSPORT_SIZE_DT 15
411 /* Timer or counter */
412 #define S7COMM_TRANSPORT_SIZE_COUNTER 28
413 #define S7COMM_TRANSPORT_SIZE_TIMER 29
414 #define S7COMM_TRANSPORT_SIZE_IEC_COUNTER 30
415 #define S7COMM_TRANSPORT_SIZE_IEC_TIMER 31
416 #define S7COMM_TRANSPORT_SIZE_HS_COUNTER 32
417 static const value_string item_transportsizenames
[] = {
418 { S7COMM_TRANSPORT_SIZE_BIT
, "BIT" },
419 { S7COMM_TRANSPORT_SIZE_BYTE
, "BYTE" },
420 { S7COMM_TRANSPORT_SIZE_CHAR
, "CHAR" },
421 { S7COMM_TRANSPORT_SIZE_WORD
, "WORD" },
422 { S7COMM_TRANSPORT_SIZE_INT
, "INT" },
423 { S7COMM_TRANSPORT_SIZE_DWORD
, "DWORD" },
424 { S7COMM_TRANSPORT_SIZE_DINT
, "DINT" },
425 { S7COMM_TRANSPORT_SIZE_REAL
, "REAL" },
426 { S7COMM_TRANSPORT_SIZE_TOD
, "TOD" },
427 { S7COMM_TRANSPORT_SIZE_TIME
, "TIME" },
428 { S7COMM_TRANSPORT_SIZE_S5TIME
, "S5TIME" },
429 { S7COMM_TRANSPORT_SIZE_DT
, "DATE_AND_TIME" },
430 { S7COMM_TRANSPORT_SIZE_COUNTER
, "COUNTER" },
431 { S7COMM_TRANSPORT_SIZE_TIMER
, "TIMER" },
432 { S7COMM_TRANSPORT_SIZE_IEC_COUNTER
, "IEC TIMER" },
433 { S7COMM_TRANSPORT_SIZE_IEC_TIMER
, "IEC COUNTER" },
434 { S7COMM_TRANSPORT_SIZE_HS_COUNTER
, "HS COUNTER" },
438 /**************************************************************************
439 * Syntax Ids of variable specification
441 #define S7COMM_SYNTAXID_S7ANY 0x10 /* Address data S7-Any pointer-like DB1.DBX10.2 */
442 #define S7COMM_SYNTAXID_SHORT 0x11
443 #define S7COMM_SYNTAXID_EXT 0x12
444 #define S7COMM_SYNTAXID_PBC_ID 0x13 /* R_ID for PBC */
445 #define S7COMM_SYNTAXID_ALARM_LOCKFREESET 0x15 /* Alarm lock/free dataset */
446 #define S7COMM_SYNTAXID_ALARM_INDSET 0x16 /* Alarm indication dataset */
447 #define S7COMM_SYNTAXID_ALARM_ACKSET 0x19 /* Alarm acknowledge message dataset */
448 #define S7COMM_SYNTAXID_ALARM_QUERYREQSET 0x1a /* Alarm query request dataset */
449 #define S7COMM_SYNTAXID_NOTIFY_INDSET 0x1c /* Notify indication dataset */
450 #define S7COMM_SYNTAXID_NCK 0x82 /* Sinumerik NCK HMI access (current units) */
451 #define S7COMM_SYNTAXID_NCK_METRIC 0x83 /* Sinumerik NCK HMI access metric units */
452 #define S7COMM_SYNTAXID_NCK_INCH 0x84 /* Sinumerik NCK HMI access inch */
453 #define S7COMM_SYNTAXID_DRIVEESANY 0xa2 /* seen on Drive ES Starter with routing over S7 */
454 #define S7COMM_SYNTAXID_1200SYM 0xb2 /* Symbolic address mode of S7-1200 */
455 #define S7COMM_SYNTAXID_DBREAD 0xb0 /* Kind of DB block read, seen only at an S7-400 */
457 static const value_string item_syntaxid_names
[] = {
458 { S7COMM_SYNTAXID_S7ANY
, "S7ANY" },
459 { S7COMM_SYNTAXID_SHORT
, "ParameterShort" },
460 { S7COMM_SYNTAXID_EXT
, "ParameterExtended" },
461 { S7COMM_SYNTAXID_PBC_ID
, "PBC-R_ID" },
462 { S7COMM_SYNTAXID_ALARM_LOCKFREESET
, "ALARM_LOCKFREE" },
463 { S7COMM_SYNTAXID_ALARM_INDSET
, "ALARM_IND" },
464 { S7COMM_SYNTAXID_ALARM_ACKSET
, "ALARM_ACK" },
465 { S7COMM_SYNTAXID_ALARM_QUERYREQSET
, "ALARM_QUERYREQ" },
466 { S7COMM_SYNTAXID_NOTIFY_INDSET
, "NOTIFY_IND" },
467 { S7COMM_SYNTAXID_NCK
, "NCK" },
468 { S7COMM_SYNTAXID_NCK_METRIC
, "NCK_M" },
469 { S7COMM_SYNTAXID_NCK_INCH
, "NCK_I" },
470 { S7COMM_SYNTAXID_DRIVEESANY
, "DRIVEESANY" },
471 { S7COMM_SYNTAXID_1200SYM
, "1200SYM" },
472 { S7COMM_SYNTAXID_DBREAD
, "DBREAD" },
476 /**************************************************************************
477 * Transport sizes in data
479 #define S7COMM_DATA_TRANSPORT_SIZE_NULL 0
480 #define S7COMM_DATA_TRANSPORT_SIZE_BBIT 3 /* bit access, len is in bits */
481 #define S7COMM_DATA_TRANSPORT_SIZE_BBYTE 4 /* byte/word/dword access, len is in bits */
482 #define S7COMM_DATA_TRANSPORT_SIZE_BINT 5 /* integer access, len is in bits */
483 #define S7COMM_DATA_TRANSPORT_SIZE_BDINT 6 /* integer access, len is in bytes */
484 #define S7COMM_DATA_TRANSPORT_SIZE_BREAL 7 /* real access, len is in bytes */
485 #define S7COMM_DATA_TRANSPORT_SIZE_BSTR 9 /* octet string, len is in bytes */
486 #define S7COMM_DATA_TRANSPORT_SIZE_NCKADDR1 17 /* NCK address description, fixed length */
487 #define S7COMM_DATA_TRANSPORT_SIZE_NCKADDR2 18 /* NCK address description, fixed length */
489 static const value_string data_transportsizenames
[] = {
490 { S7COMM_DATA_TRANSPORT_SIZE_NULL
, "NULL" },
491 { S7COMM_DATA_TRANSPORT_SIZE_BBIT
, "BIT" },
492 { S7COMM_DATA_TRANSPORT_SIZE_BBYTE
, "BYTE/WORD/DWORD" },
493 { S7COMM_DATA_TRANSPORT_SIZE_BINT
, "INTEGER" },
494 { S7COMM_DATA_TRANSPORT_SIZE_BDINT
, "DINTEGER" },
495 { S7COMM_DATA_TRANSPORT_SIZE_BREAL
, "REAL" },
496 { S7COMM_DATA_TRANSPORT_SIZE_BSTR
, "OCTET STRING" },
497 { S7COMM_DATA_TRANSPORT_SIZE_NCKADDR1
, "NCK ADDRESS1" },
498 { S7COMM_DATA_TRANSPORT_SIZE_NCKADDR2
, "NCK ADDRESS2" },
501 /**************************************************************************
502 * Returnvalues of an item response
505 const value_string s7comm_item_return_valuenames
[] = {
506 { S7COMM_ITEM_RETVAL_RESERVED
, "Reserved" },
507 { S7COMM_ITEM_RETVAL_DATA_HW_FAULT
, "Hardware error" },
508 { S7COMM_ITEM_RETVAL_DATA_ACCESS_FAULT
, "Accessing the object not allowed" },
509 { S7COMM_ITEM_RETVAL_DATA_OUTOFRANGE
, "Invalid address" },
510 { S7COMM_ITEM_RETVAL_DATA_NOT_SUP
, "Data type not supported" },
511 { S7COMM_ITEM_RETVAL_DATA_SIZEMISMATCH
, "Data type inconsistent" },
512 { S7COMM_ITEM_RETVAL_DATA_ERR
, "Object does not exist" },
513 { S7COMM_ITEM_RETVAL_DATA_OK
, "Success" },
516 /**************************************************************************
517 * Block Types, used when blocktype is transferred as string
519 #define S7COMM_BLOCKTYPE_OB 0x3038 /* '08' */
520 #define S7COMM_BLOCKTYPE_CMOD 0x3039 /* '09' */
521 #define S7COMM_BLOCKTYPE_DB 0x3041 /* '0A' */
522 #define S7COMM_BLOCKTYPE_SDB 0x3042 /* '0B' */
523 #define S7COMM_BLOCKTYPE_FC 0x3043 /* '0C' */
524 #define S7COMM_BLOCKTYPE_SFC 0x3044 /* '0D' */
525 #define S7COMM_BLOCKTYPE_FB 0x3045 /* '0E' */
526 #define S7COMM_BLOCKTYPE_SFB 0x3046 /* '0F' */
528 static const value_string blocktype_names
[] = {
529 { S7COMM_BLOCKTYPE_OB
, "OB" },
530 { S7COMM_BLOCKTYPE_CMOD
, "CMod" },
531 { S7COMM_BLOCKTYPE_DB
, "DB" },
532 { S7COMM_BLOCKTYPE_SDB
, "SDB" },
533 { S7COMM_BLOCKTYPE_FC
, "FC" },
534 { S7COMM_BLOCKTYPE_SFC
, "SFC" },
535 { S7COMM_BLOCKTYPE_FB
, "FB" },
536 { S7COMM_BLOCKTYPE_SFB
, "SFB" },
541 static const value_string blocktype_attribute1_names
[] = {
542 { '_', "Complete Module" },
543 { '$', "Module header for up-loading" },
547 static const value_string blocktype_attribute2_names
[] = {
548 { 'P', "Passive (copied, but not chained) module" },
549 { 'A', "Active embedded module" },
550 { 'B', "Active as well as passive module" },
554 /**************************************************************************
557 #define S7COMM_SUBBLKTYPE_NONE 0x00
558 #define S7COMM_SUBBLKTYPE_OB 0x08
559 #define S7COMM_SUBBLKTYPE_DB 0x0a
560 #define S7COMM_SUBBLKTYPE_SDB 0x0b
561 #define S7COMM_SUBBLKTYPE_FC 0x0c
562 #define S7COMM_SUBBLKTYPE_SFC 0x0d
563 #define S7COMM_SUBBLKTYPE_FB 0x0e
564 #define S7COMM_SUBBLKTYPE_SFB 0x0f
566 static const value_string subblktype_names
[] = {
567 { S7COMM_SUBBLKTYPE_NONE
, "Not set" },
568 { S7COMM_SUBBLKTYPE_OB
, "OB" },
569 { S7COMM_SUBBLKTYPE_DB
, "DB" },
570 { S7COMM_SUBBLKTYPE_SDB
, "SDB" },
571 { S7COMM_SUBBLKTYPE_FC
, "FC" },
572 { S7COMM_SUBBLKTYPE_SFC
, "SFC" },
573 { S7COMM_SUBBLKTYPE_FB
, "FB" },
574 { S7COMM_SUBBLKTYPE_SFB
, "SFB" },
578 /**************************************************************************
581 #define S7COMM_BLOCKSECURITY_OFF 0
582 #define S7COMM_BLOCKSECURITY_KNOWHOWPROTECT 3
584 static const value_string blocksecurity_names
[] = {
585 { S7COMM_BLOCKSECURITY_OFF
, "None" },
586 { S7COMM_BLOCKSECURITY_KNOWHOWPROTECT
, "Know How Protect" },
589 /**************************************************************************
592 static const value_string blocklanguage_names
[] = {
593 { 0x00, "Not defined" },
601 { 0x08, "CPU-DB" }, /* DB was created from Plc programm (CREAT_DB) */
602 { 0x11, "SDB (after overall reset)" }, /* another SDB, don't know what it means, in SDB 1 and SDB 2, uncertain*/
603 { 0x12, "SDB (Routing)" }, /* another SDB, in SDB 999 and SDB 1000 (routing information), uncertain */
604 { 0x29, "ENCRYPT" }, /* block is encrypted with S7-Block-Privacy */
608 /**************************************************************************
609 * Names of types in userdata parameter part
612 static const value_string userdata_type_names
[] = {
613 { S7COMM_UD_TYPE_IND
, "Indication" },
614 { S7COMM_UD_TYPE_REQ
, "Request" },
615 { S7COMM_UD_TYPE_RES
, "Response" },
619 /**************************************************************************
620 * Subfunctions only used in Sinumerik NC file download
622 #define S7COMM_NCPRG_FUNCREQUESTDOWNLOAD 1
623 #define S7COMM_NCPRG_FUNCDOWNLOADBLOCK 2
624 #define S7COMM_NCPRG_FUNCCONTDOWNLOAD 3
625 #define S7COMM_NCPRG_FUNCDOWNLOADENDED 4
626 #define S7COMM_NCPRG_FUNCSTARTUPLOAD 6
627 #define S7COMM_NCPRG_FUNCUPLOAD 7
628 #define S7COMM_NCPRG_FUNCCONTUPLOAD 8
630 static const value_string userdata_ncprg_subfunc_names
[] = {
631 { S7COMM_NCPRG_FUNCREQUESTDOWNLOAD
, "Request download" },
632 { S7COMM_NCPRG_FUNCDOWNLOADBLOCK
, "Download block" },
633 { S7COMM_NCPRG_FUNCCONTDOWNLOAD
, "Continue download" },
634 { S7COMM_NCPRG_FUNCDOWNLOADENDED
, "Download ended" },
635 { S7COMM_NCPRG_FUNCSTARTUPLOAD
, "Start upload" },
636 { S7COMM_NCPRG_FUNCUPLOAD
, "Upload" },
637 { S7COMM_NCPRG_FUNCCONTUPLOAD
, "Continue upload" },
641 /**************************************************************************
642 * Subfunctions for Data Record Routing to Profibus
644 #define S7COMM_DRR_FUNCINIT 1
645 #define S7COMM_DRR_FUNCFINISH 2
646 #define S7COMM_DRR_FUNCDATA 3
648 static const value_string userdata_drr_subfunc_names
[] = {
649 { S7COMM_DRR_FUNCINIT
, "DRR Init" },
650 { S7COMM_DRR_FUNCFINISH
, "DRR Finish" },
651 { S7COMM_DRR_FUNCDATA
, "DRR Data" },
655 /**************************************************************************
656 * Userdata Parameter, last data unit
658 #define S7COMM_UD_LASTDATAUNIT_YES 0x00
659 #define S7COMM_UD_LASTDATAUNIT_NO 0x01
661 static const value_string userdata_lastdataunit_names
[] = {
662 { S7COMM_UD_LASTDATAUNIT_YES
, "Yes" },
663 { S7COMM_UD_LASTDATAUNIT_NO
, "No" },
667 /**************************************************************************
668 * Names of Function groups in userdata parameter part
670 #define S7COMM_UD_FUNCGROUP_TIS 0x01
671 #define S7COMM_UD_FUNCGROUP_CYCLIC 0x02
672 #define S7COMM_UD_FUNCGROUP_BLOCK 0x03
673 #define S7COMM_UD_FUNCGROUP_CPU 0x04
674 #define S7COMM_UD_FUNCGROUP_SEC 0x05 /* Security functions e.g. plc password */
675 #define S7COMM_UD_FUNCGROUP_PBC_BSEND 0x06 /* PBC = Programmable Block Communication (PBK in german) */
676 #define S7COMM_UD_FUNCGROUP_TIME 0x07
677 #define S7COMM_UD_FUNCGROUP_NCPRG 0x3f
678 #define S7COMM_UD_FUNCGROUP_DRR 0x20
680 static const value_string userdata_functiongroup_names
[] = {
681 { S7COMM_UD_FUNCGROUP_TIS
, "Programmer commands" },
682 { S7COMM_UD_FUNCGROUP_CYCLIC
, "Cyclic services" }, /* to read data from plc without a request */
683 { S7COMM_UD_FUNCGROUP_BLOCK
, "Block functions" },
684 { S7COMM_UD_FUNCGROUP_CPU
, "CPU functions" },
685 { S7COMM_UD_FUNCGROUP_SEC
, "Security" },
686 { S7COMM_UD_FUNCGROUP_PBC_BSEND
, "PBC BSEND" },
687 { S7COMM_UD_FUNCGROUP_TIME
, "Time functions" },
688 { S7COMM_UD_FUNCGROUP_NCPRG
, "NC programming" },
689 { S7COMM_UD_FUNCGROUP_DRR
, "DR Routing" },
693 /**************************************************************************
694 * Variable status: Area of data request
705 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_MX 0x00
706 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_MB 0x01
707 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_MW 0x02
708 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_MD 0x03
709 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_EX 0x10
710 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_EB 0x11
711 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_EW 0x12
712 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_ED 0x13
713 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_AX 0x20
714 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_AB 0x21
715 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_AW 0x22
716 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_AD 0x23
717 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_PEB 0x31
718 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_PEW 0x32
719 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_PED 0x33
720 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_DBX 0x70
721 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_DBB 0x71
722 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_DBW 0x72
723 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_DBD 0x73
724 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_T 0x54
725 #define S7COMM_UD_SUBF_TIS_VARSTAT_AREA_C 0x64
727 static const value_string userdata_tis_varstat_area_names
[] = {
728 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_MX
, "MX" },
729 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_MB
, "MB" },
730 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_MW
, "MW" },
731 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_MD
, "MD" },
732 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_EB
, "IB" },
733 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_EX
, "IX" },
734 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_EW
, "IW" },
735 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_ED
, "ID" },
736 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_AX
, "QX" },
737 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_AB
, "QB" },
738 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_AW
, "QW" },
739 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_AD
, "QD" },
740 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_PEB
, "PIB" },
741 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_PEW
, "PIW" },
742 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_PED
, "PID" },
743 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_DBX
, "DBX" },
744 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_DBB
, "DBB" },
745 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_DBW
, "DBW" },
746 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_DBD
, "DBD" },
747 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_T
, "TIMER" },
748 { S7COMM_UD_SUBF_TIS_VARSTAT_AREA_C
, "COUNTER" },
752 /**************************************************************************
753 * Names of userdata subfunctions in group 1 (Programmer commands)
754 * In szl dataset 0x0132/2 these are defined as "Test and installation functions TIS".
755 * The methods supported by the CPU are listed in the funkt_n bits.
757 #define S7COMM_UD_SUBF_TIS_BLOCKSTAT 0x01
758 #define S7COMM_UD_SUBF_TIS_VARSTAT 0x02
759 #define S7COMM_UD_SUBF_TIS_OUTISTACK 0x03
760 #define S7COMM_UD_SUBF_TIS_OUTBSTACK 0x04
761 #define S7COMM_UD_SUBF_TIS_OUTLSTACK 0x05
762 #define S7COMM_UD_SUBF_TIS_TIMEMEAS 0x06
763 #define S7COMM_UD_SUBF_TIS_FORCESEL 0x07
764 #define S7COMM_UD_SUBF_TIS_MODVAR 0x08
765 #define S7COMM_UD_SUBF_TIS_FORCE 0x09
766 #define S7COMM_UD_SUBF_TIS_BREAKPOINT 0x0a
767 #define S7COMM_UD_SUBF_TIS_EXITHOLD 0x0b
768 #define S7COMM_UD_SUBF_TIS_MEMORYRES 0x0c
769 #define S7COMM_UD_SUBF_TIS_DISABLEJOB 0x0d
770 #define S7COMM_UD_SUBF_TIS_ENABLEJOB 0x0e
771 #define S7COMM_UD_SUBF_TIS_DELETEJOB 0x0f
772 #define S7COMM_UD_SUBF_TIS_READJOBLIST 0x10
773 #define S7COMM_UD_SUBF_TIS_READJOB 0x11
774 #define S7COMM_UD_SUBF_TIS_REPLACEJOB 0x12
775 #define S7COMM_UD_SUBF_TIS_BLOCKSTAT2 0x13
776 #define S7COMM_UD_SUBF_TIS_FLASHLED 0x16
778 static const value_string userdata_tis_subfunc_names
[] = {
779 { S7COMM_UD_SUBF_TIS_BLOCKSTAT
, "Block status" },
780 { S7COMM_UD_SUBF_TIS_VARSTAT
, "Variable status" },
781 { S7COMM_UD_SUBF_TIS_OUTISTACK
, "Output ISTACK" },
782 { S7COMM_UD_SUBF_TIS_OUTBSTACK
, "Output BSTACK" },
783 { S7COMM_UD_SUBF_TIS_OUTLSTACK
, "Output LSTACK" },
784 { S7COMM_UD_SUBF_TIS_TIMEMEAS
, "Time measurement from to" }, /* never seen yet */
785 { S7COMM_UD_SUBF_TIS_FORCESEL
, "Force selection" },
786 { S7COMM_UD_SUBF_TIS_MODVAR
, "Modify variable" },
787 { S7COMM_UD_SUBF_TIS_FORCE
, "Force" },
788 { S7COMM_UD_SUBF_TIS_BREAKPOINT
, "Breakpoint" },
789 { S7COMM_UD_SUBF_TIS_EXITHOLD
, "Exit HOLD" },
790 { S7COMM_UD_SUBF_TIS_MEMORYRES
, "Memory reset" },
791 { S7COMM_UD_SUBF_TIS_DISABLEJOB
, "Disable job" },
792 { S7COMM_UD_SUBF_TIS_ENABLEJOB
, "Enable job" },
793 { S7COMM_UD_SUBF_TIS_DELETEJOB
, "Delete job" },
794 { S7COMM_UD_SUBF_TIS_READJOBLIST
, "Read job list" },
795 { S7COMM_UD_SUBF_TIS_READJOB
, "Read job" },
796 { S7COMM_UD_SUBF_TIS_REPLACEJOB
, "Replace job" },
797 { S7COMM_UD_SUBF_TIS_BLOCKSTAT2
, "Block status v2" },
798 { S7COMM_UD_SUBF_TIS_FLASHLED
, "Flash LED" },
802 /**************************************************************************
803 * Variable status: Trigger point
805 static const value_string userdata_varstat_trgevent_names
[] = {
806 { 0x0000, "Immediately" },
807 { 0x0100, "System Trigger" },
808 { 0x0200, "System checkpoint main cycle start" },
809 { 0x0300, "System checkpoint main cycle end" },
810 { 0x0400, "Mode transition RUN-STOP" },
811 { 0x0500, "After code address" },
812 { 0x0600, "Code address area" },
813 { 0x0601, "Code address area with call environment" }, /* Call conditions like opened DB/DI or called block */
814 { 0x0700, "Data address" },
815 { 0x0800, "Data address area" },
816 { 0x0900, "Local data address" },
817 { 0x0a00, "Local data address area" },
818 { 0x0b00, "Range trigger" },
819 { 0x0c00, "Before code address" },
823 /**************************************************************************
824 * Names of userdata subfunctions in group 2 (cyclic data)
826 #define S7COMM_UD_SUBF_CYCLIC_TRANSF 0x01
827 #define S7COMM_UD_SUBF_CYCLIC_UNSUBSCRIBE 0x04
828 #define S7COMM_UD_SUBF_CYCLIC_CHANGE 0x05
829 #define S7COMM_UD_SUBF_CYCLIC_CHANGE_MOD 0x07
830 #define S7COMM_UD_SUBF_CYCLIC_RDREC 0x08
832 static const value_string userdata_cyclic_subfunc_names
[] = {
833 { S7COMM_UD_SUBF_CYCLIC_TRANSF
, "Cyclic transfer" },
834 { S7COMM_UD_SUBF_CYCLIC_UNSUBSCRIBE
, "Unsubscribe" },
835 { S7COMM_UD_SUBF_CYCLIC_CHANGE
, "Change driven transfer" },
836 { S7COMM_UD_SUBF_CYCLIC_CHANGE_MOD
, "Change driven transfer modify" },
837 { S7COMM_UD_SUBF_CYCLIC_RDREC
, "RDREC" },
841 /**************************************************************************
842 * Timebase for cyclic services
844 static const value_string cycl_interval_timebase_names
[] = {
845 { 0, "100 milliseconds" },
851 /**************************************************************************
852 * Names of userdata subfunctions in group 3 (Block functions)
854 #define S7COMM_UD_SUBF_BLOCK_LIST 0x01
855 #define S7COMM_UD_SUBF_BLOCK_LISTTYPE 0x02
856 #define S7COMM_UD_SUBF_BLOCK_BLOCKINFO 0x03
858 static const value_string userdata_block_subfunc_names
[] = {
859 { S7COMM_UD_SUBF_BLOCK_LIST
, "List blocks" },
860 { S7COMM_UD_SUBF_BLOCK_LISTTYPE
, "List blocks of type" },
861 { S7COMM_UD_SUBF_BLOCK_BLOCKINFO
, "Get block info" },
865 /**************************************************************************
866 * Names of userdata subfunctions in group 4 (CPU functions)
868 #define S7COMM_UD_SUBF_CPU_SCAN_IND 0x09
869 #define S7COMM_UD_SUBF_CPU_AR_SEND_IND 0x10
871 static const value_string userdata_cpu_subfunc_names
[] = {
872 { S7COMM_UD_SUBF_CPU_READSZL
, "Read SZL" },
873 { S7COMM_UD_SUBF_CPU_MSGS
, "Message service" }, /* Header constant is also different here */
874 { S7COMM_UD_SUBF_CPU_DIAGMSG
, "Diagnostic message" }, /* Diagnostic message from PLC */
875 { S7COMM_UD_SUBF_CPU_ALARM8_IND
, "ALARM_8 indication" }, /* PLC is indicating an ALARM message, using ALARM_8 SFBs */
876 { S7COMM_UD_SUBF_CPU_NOTIFY_IND
, "NOTIFY indication" }, /* PLC is indicating a NOTIFY message, using NOTIFY SFBs */
877 { S7COMM_UD_SUBF_CPU_ALARM8LOCK
, "ALARM_8 lock" }, /* Lock an ALARM message from HMI/SCADA */
878 { S7COMM_UD_SUBF_CPU_ALARM8UNLOCK
, "ALARM_8 unlock" }, /* Unlock an ALARM message from HMI/SCADA */
879 { S7COMM_UD_SUBF_CPU_SCAN_IND
, "SCAN indication" }, /* PLC is indicating a SCAN message */
880 { S7COMM_UD_SUBF_CPU_AR_SEND_IND
, "AR_SEND indication" }, /* PLC is indicating a AR_SEND message */
881 { S7COMM_UD_SUBF_CPU_ALARMS_IND
, "ALARM_S indication" }, /* PLC is indicating an ALARM message, using ALARM_S/ALARM_D SFCs */
882 { S7COMM_UD_SUBF_CPU_ALARMSQ_IND
, "ALARM_SQ indication" }, /* PLC is indicating an ALARM message, using ALARM_SQ/ALARM_DQ SFCs */
883 { S7COMM_UD_SUBF_CPU_ALARMQUERY
, "ALARM query" }, /* HMI/SCADA query of ALARMs */
884 { S7COMM_UD_SUBF_CPU_ALARMACK
, "ALARM ack" }, /* Alarm was acknowledged in HMI/SCADA */
885 { S7COMM_UD_SUBF_CPU_ALARMACK_IND
, "ALARM ack indication" }, /* Alarm acknowledge indication from CPU to HMI */
886 { S7COMM_UD_SUBF_CPU_ALARM8LOCK_IND
, "ALARM lock indication" }, /* Alarm lock indication from CPU to HMI */
887 { S7COMM_UD_SUBF_CPU_ALARM8UNLOCK_IND
, "ALARM unlock indication" }, /* Alarm unlock indication from CPU to HMI */
888 { S7COMM_UD_SUBF_CPU_NOTIFY8_IND
, "NOTIFY_8 indication" },
892 /**************************************************************************
893 * Names of userdata subfunctions in group 5 (Security?)
895 #define S7COMM_UD_SUBF_SEC_PASSWD 0x01
897 static const value_string userdata_sec_subfunc_names
[] = {
898 { S7COMM_UD_SUBF_SEC_PASSWD
, "PLC password" },
902 /**************************************************************************
903 * Names of userdata subfunctions in group 7 (Time functions)
905 #define S7COMM_UD_SUBF_TIME_READ 0x01
906 #define S7COMM_UD_SUBF_TIME_SET 0x02
907 #define S7COMM_UD_SUBF_TIME_READF 0x03
908 #define S7COMM_UD_SUBF_TIME_SET2 0x04
910 static const value_string userdata_time_subfunc_names
[] = {
911 { S7COMM_UD_SUBF_TIME_READ
, "Read clock" },
912 { S7COMM_UD_SUBF_TIME_SET
, "Set clock" },
913 { S7COMM_UD_SUBF_TIME_READF
, "Read clock (following)" },
914 { S7COMM_UD_SUBF_TIME_SET2
, "Set clock" },
918 /*******************************************************************************************************
919 * Weekday names in DATE_AND_TIME
921 static const value_string weekdaynames
[] = {
933 /**************************************************************************
934 **************************************************************************/
936 /**************************************************************************
937 * Flags for LID access
939 #define S7COMM_TIA1200_VAR_ENCAPS_LID 0x2
940 #define S7COMM_TIA1200_VAR_ENCAPS_IDX 0x3
941 #define S7COMM_TIA1200_VAR_OBTAIN_LID 0x4
942 #define S7COMM_TIA1200_VAR_OBTAIN_IDX 0x5
943 #define S7COMM_TIA1200_VAR_PART_START 0x6
944 #define S7COMM_TIA1200_VAR_PART_LEN 0x7
946 static const value_string tia1200_var_lid_flag_names
[] = {
947 { S7COMM_TIA1200_VAR_ENCAPS_LID
, "Encapsulated LID" },
948 { S7COMM_TIA1200_VAR_ENCAPS_IDX
, "Encapsulated Index" },
949 { S7COMM_TIA1200_VAR_OBTAIN_LID
, "Obtain by LID" },
950 { S7COMM_TIA1200_VAR_OBTAIN_IDX
, "Obtain by Index" },
951 { S7COMM_TIA1200_VAR_PART_START
, "Part Start Address" },
952 { S7COMM_TIA1200_VAR_PART_LEN
, "Part Length" },
956 /**************************************************************************
957 * TIA 1200 Area Names for variable access
959 #define S7COMM_TIA1200_VAR_ITEM_AREA1_DB 0x8a0e /* Reading DB, 2 byte DB-Number following */
960 #define S7COMM_TIA1200_VAR_ITEM_AREA1_IQMCT 0x0000 /* Reading I/Q/M/C/T, 2 Byte detail area following */
962 static const value_string tia1200_var_item_area1_names
[] = {
963 { S7COMM_TIA1200_VAR_ITEM_AREA1_DB
, "DB" },
964 { S7COMM_TIA1200_VAR_ITEM_AREA1_IQMCT
, "IQMCT" },
968 #define S7COMM_TIA1200_VAR_ITEM_AREA2_I 0x50
969 #define S7COMM_TIA1200_VAR_ITEM_AREA2_Q 0x51
970 #define S7COMM_TIA1200_VAR_ITEM_AREA2_M 0x52
971 #define S7COMM_TIA1200_VAR_ITEM_AREA2_C 0x53
972 #define S7COMM_TIA1200_VAR_ITEM_AREA2_T 0x54
974 static const value_string tia1200_var_item_area2_names
[] = {
975 { S7COMM_TIA1200_VAR_ITEM_AREA2_I
, "Inputs (I)" },
976 { S7COMM_TIA1200_VAR_ITEM_AREA2_Q
, "Outputs (Q)" },
977 { S7COMM_TIA1200_VAR_ITEM_AREA2_M
, "Flags (M)" },
978 { S7COMM_TIA1200_VAR_ITEM_AREA2_C
, "Counter (C)" },
979 { S7COMM_TIA1200_VAR_ITEM_AREA2_T
, "Timer (T)" },
983 /**************************************************************************
986 #define S7COMM_NCK_AREA_N_NCK 0
987 #define S7COMM_NCK_AREA_B_MODEGROUP 1
988 #define S7COMM_NCK_AREA_C_CHANNEL 2
989 #define S7COMM_NCK_AREA_A_AXIS 3
990 #define S7COMM_NCK_AREA_T_TOOL 4
991 #define S7COMM_NCK_AREA_V_FEEDDRIVE 5
992 #define S7COMM_NCK_AREA_H_MAINDRIVE 6
993 #define S7COMM_NCK_AREA_M_MMC 7
995 static const value_string nck_area_names
[] = {
996 { S7COMM_NCK_AREA_N_NCK
, "N - NCK" },
997 { S7COMM_NCK_AREA_B_MODEGROUP
, "B - Mode group" },
998 { S7COMM_NCK_AREA_C_CHANNEL
, "C - Channel" },
999 { S7COMM_NCK_AREA_A_AXIS
, "A - Axis" },
1000 { S7COMM_NCK_AREA_T_TOOL
, "T - Tool" },
1001 { S7COMM_NCK_AREA_V_FEEDDRIVE
, "V - Feed drive" },
1002 { S7COMM_NCK_AREA_H_MAINDRIVE
, "M - Main drive" },
1003 { S7COMM_NCK_AREA_M_MMC
, "M - MMC" },
1007 static const value_string nck_module_names
[] = {
1008 { 0x10, "Y - Global system data" },
1009 { 0x11, "YNCFL - NCK instruction groups" },
1010 { 0x12, "FU - NCU global settable frames" },
1011 { 0x13, "FA - Active NCU global frames" },
1012 { 0x14, "TO - Tool data" },
1013 { 0x15, "RP - Arithmetic parameters" },
1014 { 0x16, "SE - Setting data" },
1015 { 0x17, "SGUD - SGUD-Block" },
1016 { 0x18, "LUD - Local userdata" },
1017 { 0x19, "TC - Toolholder parameters" },
1018 { 0x1a, "M - Machine data" },
1019 { 0x1c, "WAL - Working area limitation" },
1020 { 0x1e, "DIAG - Internal diagnostic data" },
1021 { 0x1f, "CC - Unknown" },
1022 { 0x20, "FE - Channel-specific external frame" },
1023 { 0x21, "TD - Tool data: General data" },
1024 { 0x22, "TS - Tool edge data: Monitoring data" },
1025 { 0x23, "TG - Tool data: Grinding-specific data" },
1026 { 0x24, "TU - Tool data" },
1027 { 0x25, "TUE - Tool edge data, userdefined data" },
1028 { 0x26, "TV - Tool data, directory" },
1029 { 0x27, "TM - Magazine data: General data" },
1030 { 0x28, "TP - Magazine data: Location data" },
1031 { 0x29, "TPM - Magazine data: Multiple assignment of location data" },
1032 { 0x2a, "TT - Magazine data: Location typ" },
1033 { 0x2b, "TMV - Magazine data: Directory" },
1034 { 0x2c, "TMC - Magazine data: Configuration data" },
1035 { 0x2d, "MGUD - MGUD-Block" },
1036 { 0x2e, "UGUD - UGUD-Block" },
1037 { 0x2f, "GUD4 - GUD4-Block" },
1038 { 0x30, "GUD5 - GUD5-Block" },
1039 { 0x31, "GUD6 - GUD6-Block" },
1040 { 0x32, "GUD7 - GUD7-Block" },
1041 { 0x33, "GUD8 - GUD8-Block" },
1042 { 0x34, "GUD9 - GUD9-Block" },
1043 { 0x35, "PA - Channel-specific protection zones" },
1044 { 0x36, "GD1 - SGUD-Block GD1" },
1045 { 0x37, "NIB - State data: Nibbling" },
1046 { 0x38, "ETP - Types of events" },
1047 { 0x39, "ETPD - Data lists for protocolling" },
1048 { 0x3a, "SYNACT - Channel-specific synchronous actions" },
1049 { 0x3b, "DIAGN - Diagnostic data" },
1050 { 0x3c, "VSYN - Channel-specific user variables for synchronous actions" },
1051 { 0x3d, "TUS - Tool data: user monitoring data" },
1052 { 0x3e, "TUM - Tool data: user magazine data" },
1053 { 0x3f, "TUP - Tool data: user magazine place data" },
1054 { 0x40, "TF - Parameterizing, return parameters of _N_TMGETT, _N_TSEARC" },
1055 { 0x41, "FB - Channel-specific base frames" },
1056 { 0x42, "SSP2 - State data: Spindle" },
1057 { 0x43, "PUD - programmglobale Benutzerdaten" },
1058 { 0x44, "TOS - Edge-related location-dependent fine total offsets" },
1059 { 0x45, "TOST - Edge-related location-dependent fine total offsets, transformed" },
1060 { 0x46, "TOE - Edge-related coarse total offsets, setup offsets" },
1061 { 0x47, "TOET - Edge-related coarse total offsets, transformed setup offsets" },
1062 { 0x48, "AD - Adapter data" },
1063 { 0x49, "TOT - Edge data: Transformed offset data" },
1064 { 0x4a, "AEV - Working offsets: Directory" },
1065 { 0x4b, "YFAFL - NCK instruction groups (Fanuc)" },
1066 { 0x4c, "FS - System-Frame" },
1067 { 0x4d, "SD - Servo data" },
1068 { 0x4e, "TAD - Application-specific data" },
1069 { 0x4f, "TAO - Application-specific cutting edge data" },
1070 { 0x50, "TAS - Application-specific monitoring data" },
1071 { 0x51, "TAM - Application-specific magazine data" },
1072 { 0x52, "TAP - Application-specific magazine location data" },
1073 { 0x53, "MEM - Unknown" },
1074 { 0x54, "SALUC - Alarm actions: List in reverse chronological order" },
1075 { 0x55, "AUXFU - Auxiliary functions" },
1076 { 0x56, "TDC - Tool/Tools" },
1077 { 0x57, "CP - Generic coupling" },
1078 { 0x6e, "SDME - Unknown" },
1079 { 0x6f, "SPARPI - Program pointer on interruption" },
1080 { 0x70, "SEGA - State data: Geometry axes in tool offset memory (extended)" },
1081 { 0x71, "SEMA - State data: Machine axes (extended)" },
1082 { 0x72, "SSP - State data: Spindle" },
1083 { 0x73, "SGA - State data: Geometry axes in tool offset memory" },
1084 { 0x74, "SMA - State data: Machine axes" },
1085 { 0x75, "SALAL - Alarms: List organized according to time" },
1086 { 0x76, "SALAP - Alarms: List organized according to priority" },
1087 { 0x77, "SALA - Alarms: List organized according to time" },
1088 { 0x78, "SSYNAC - Synchronous actions" },
1089 { 0x79, "SPARPF - Program pointers for block search and stop run" },
1090 { 0x7a, "SPARPP - Program pointer in automatic operation" },
1091 { 0x7b, "SNCF - Active G functions" },
1092 { 0x7d, "SPARP - Part program information" },
1093 { 0x7e, "SINF - Part-program-specific status data" },
1094 { 0x7f, "S - State data" },
1095 { 0x80, "0x80 - Unknown" },
1096 { 0x81, "0x81 - Unknown" },
1097 { 0x82, "0x82 - Unknown" },
1098 { 0x83, "0x83 - Unknown" },
1099 { 0x84, "0x84 - Unknown" },
1100 { 0x85, "0x85 - Unknown" },
1101 { 0xfd, "0 - Internal" },
1104 static value_string_ext nck_module_names_ext
= VALUE_STRING_EXT_INIT(nck_module_names
);
1106 static int hf_s7comm_tia1200_item_reserved1
; /* 1 Byte Reserved (always 0xff?) */
1107 static int hf_s7comm_tia1200_item_area1
; /* 2 Byte2 Root area (DB or IQMCT) */
1108 static int hf_s7comm_tia1200_item_area2
; /* 2 Bytes detail area (I/Q/M/C/T) */
1109 static int hf_s7comm_tia1200_item_area2unknown
; /* 2 Bytes detail area for possible unknown or not seen areas */
1110 static int hf_s7comm_tia1200_item_dbnumber
; /* 2 Bytes DB number */
1111 static int hf_s7comm_tia1200_item_crc
; /* 4 Bytes CRC */
1113 static int hf_s7comm_tia1200_substructure_item
; /* Substructure */
1114 static int hf_s7comm_tia1200_var_lid_flags
; /* LID Flags */
1115 static int hf_s7comm_tia1200_item_value
;
1117 /**************************************************************************
1118 **************************************************************************/
1121 static int hf_s7comm_header
;
1122 static int hf_s7comm_header_protid
; /* Header Byte 0 */
1123 static int hf_s7comm_header_rosctr
; /* Header Bytes 1 */
1124 static int hf_s7comm_header_redid
; /* Header Bytes 2, 3 */
1125 static int hf_s7comm_header_pduref
; /* Header Bytes 4, 5 */
1126 static int hf_s7comm_header_parlg
; /* Header Bytes 6, 7 */
1127 static int hf_s7comm_header_datlg
; /* Header Bytes 8, 9 */
1128 static int hf_s7comm_header_errcls
; /* Header Byte 10, only available at type 2 or 3 */
1129 static int hf_s7comm_header_errcod
; /* Header Byte 11, only available at type 2 or 3 */
1130 /* Parameter Block */
1131 static int hf_s7comm_param
;
1132 static int hf_s7comm_param_errcod
; /* Parameter part: Error code */
1133 static int hf_s7comm_param_service
; /* Parameter part: service */
1134 static int hf_s7comm_param_itemcount
; /* Parameter part: item count */
1135 static int hf_s7comm_param_data
; /* Parameter part: data */
1136 static int hf_s7comm_param_neg_pdu_length
; /* Parameter part: Negotiate PDU length */
1137 static int hf_s7comm_param_setup_reserved1
; /* Parameter part: Reserved byte in communication setup pdu*/
1139 static int hf_s7comm_param_maxamq_calling
; /* Parameter part: Max AmQ calling */
1140 static int hf_s7comm_param_maxamq_called
; /* Parameter part: Max AmQ called */
1143 static int hf_s7comm_param_item
;
1144 static int hf_s7comm_param_subitem
; /* Substructure */
1145 static int hf_s7comm_item_varspec
; /* Variable specification */
1146 static int hf_s7comm_item_varspec_length
; /* Length of following address specification */
1147 static int hf_s7comm_item_syntax_id
; /* Syntax Id */
1148 static int hf_s7comm_item_transport_size
; /* Transport size, 1 Byte*/
1149 static int hf_s7comm_item_length
; /* length, 2 Bytes*/
1150 static int hf_s7comm_item_db
; /* DB/M/E/A, 2 Bytes */
1151 static int hf_s7comm_item_area
; /* Area code, 1 byte */
1152 static int hf_s7comm_item_address
; /* Bit address, 3 Bytes */
1153 static int hf_s7comm_item_address_byte
; /* address: Byte address */
1154 static int hf_s7comm_item_address_bit
; /* address: Bit address */
1155 static int hf_s7comm_item_address_nr
; /* address: Timer/Counter/block number */
1156 /* Special variable read with Syntax-Id 0xb0 (DBREAD) */
1157 static int hf_s7comm_item_dbread_numareas
; /* Number of areas following, 1 Byte*/
1158 static int hf_s7comm_item_dbread_length
; /* length, 1 Byte*/
1159 static int hf_s7comm_item_dbread_db
; /* DB number, 2 Bytes*/
1160 static int hf_s7comm_item_dbread_startadr
; /* Start address, 2 Bytes*/
1161 /* Reading frequency inverter parameters via routing */
1162 static int hf_s7comm_item_driveesany_unknown1
; /* Unknown value 1, 1 Byte */
1163 static int hf_s7comm_item_driveesany_unknown2
; /* Unknown value 2, 2 Bytes */
1164 static int hf_s7comm_item_driveesany_unknown3
; /* Unknown value 3, 2 Bytes */
1165 static int hf_s7comm_item_driveesany_parameter_nr
; /* Parameter number, 2 Bytes */
1166 static int hf_s7comm_item_driveesany_parameter_idx
; /* Parameter index, 2 Bytes */
1167 /* NCK access with Syntax-Id 0x82 */
1168 static int hf_s7comm_item_nck_areaunit
; /* Bitmask: aaauuuuu: a=area, u=unit */
1169 static int hf_s7comm_item_nck_area
;
1170 static int hf_s7comm_item_nck_unit
;
1171 static int hf_s7comm_item_nck_column
;
1172 static int hf_s7comm_item_nck_line
;
1173 static int hf_s7comm_item_nck_module
;
1174 static int hf_s7comm_item_nck_linecount
;
1176 static int hf_s7comm_data
;
1177 static int hf_s7comm_data_returncode
; /* return code, 1 byte */
1178 static int hf_s7comm_data_transport_size
; /* transport size 1 byte */
1179 static int hf_s7comm_data_length
; /* Length of data, 2 Bytes */
1181 static int hf_s7comm_data_item
;
1183 static int hf_s7comm_readresponse_data
;
1184 static int hf_s7comm_data_fillbyte
;
1186 /* timefunction: s7 timestamp */
1187 static int hf_s7comm_data_ts
;
1188 static int hf_s7comm_data_ts_reserved
;
1189 static int hf_s7comm_data_ts_year1
; /* first byte of BCD coded year, should be ignored */
1190 static int hf_s7comm_data_ts_year2
; /* second byte of BCD coded year, if 00...89 then it's 2000...2089, else 1990...1999*/
1191 static int hf_s7comm_data_ts_month
;
1192 static int hf_s7comm_data_ts_day
;
1193 static int hf_s7comm_data_ts_hour
;
1194 static int hf_s7comm_data_ts_minute
;
1195 static int hf_s7comm_data_ts_second
;
1196 static int hf_s7comm_data_ts_millisecond
;
1197 static int hf_s7comm_data_ts_weekday
;
1199 /* userdata, block services */
1200 static int hf_s7comm_userdata_data
;
1202 static int hf_s7comm_userdata_param_type
;
1203 static int hf_s7comm_userdata_param_funcgroup
;
1204 static int hf_s7comm_userdata_param_subfunc_prog
;
1205 static int hf_s7comm_userdata_param_subfunc_cyclic
;
1206 static int hf_s7comm_userdata_param_subfunc_block
;
1207 static int hf_s7comm_userdata_param_subfunc_cpu
;
1208 static int hf_s7comm_userdata_param_subfunc_sec
;
1209 static int hf_s7comm_userdata_param_subfunc_time
;
1210 static int hf_s7comm_userdata_param_subfunc_ncprg
;
1211 static int hf_s7comm_userdata_param_subfunc_drr
;
1212 static int hf_s7comm_userdata_param_subfunc
; /* for all other subfunctions */
1213 static int hf_s7comm_userdata_param_seq_num
;
1214 static int hf_s7comm_userdata_param_dataunitref
;
1215 static int hf_s7comm_userdata_param_dataunit
;
1217 /* block functions, list blocks of type */
1218 static int hf_s7comm_ud_blockinfo_block_type
; /* Block type, 2 bytes */
1219 static int hf_s7comm_ud_blockinfo_block_num
; /* Block number, 2 bytes as int */
1220 static int hf_s7comm_ud_blockinfo_block_cnt
; /* Count, 2 bytes as int */
1221 static int hf_s7comm_ud_blockinfo_block_flags
; /* Block flags (unknown), 1 byte */
1222 static int hf_s7comm_ud_blockinfo_block_lang
; /* Block language, 1 byte, stringlist blocklanguage_names */
1223 /* block functions, get block infos */
1224 static int hf_s7comm_ud_blockinfo_block_num_ascii
; /* Block number, 5 bytes, ASCII*/
1225 static int hf_s7comm_ud_blockinfo_filesys
; /* Filesystem, 1 byte, ASCII*/
1226 static int hf_s7comm_ud_blockinfo_res_infolength
; /* Length of Info, 2 bytes as int */
1227 static int hf_s7comm_ud_blockinfo_res_unknown2
; /* Unknown blockinfo 2, 2 bytes, HEX*/
1228 static int hf_s7comm_ud_blockinfo_res_const3
; /* Constant 3, 2 bytes, ASCII */
1229 static int hf_s7comm_ud_blockinfo_res_unknown
; /* Unknown byte(s) */
1230 static int hf_s7comm_ud_blockinfo_subblk_type
; /* Subblk type, 1 byte, stringlist subblktype_names */
1231 static int hf_s7comm_ud_blockinfo_load_mem_len
; /* Length load memory, 4 bytes, int */
1232 static int hf_s7comm_ud_blockinfo_blocksecurity
; /* Block Security, 4 bytes, stringlist blocksecurity_names*/
1233 static int hf_s7comm_ud_blockinfo_interface_timestamp
;/* Interface Timestamp, string */
1234 static int hf_s7comm_ud_blockinfo_code_timestamp
; /* Code Timestamp, string */
1235 static int hf_s7comm_ud_blockinfo_ssb_len
; /* SSB length, 2 bytes, int */
1236 static int hf_s7comm_ud_blockinfo_add_len
; /* ADD length, 2 bytes, int */
1237 static int hf_s7comm_ud_blockinfo_localdata_len
; /* Length localdata, 2 bytes, int */
1238 static int hf_s7comm_ud_blockinfo_mc7_len
; /* Length MC7 code, 2 bytes, int */
1239 static int hf_s7comm_ud_blockinfo_author
; /* Author, 8 bytes, ASCII */
1240 static int hf_s7comm_ud_blockinfo_family
; /* Family, 8 bytes, ASCII */
1241 static int hf_s7comm_ud_blockinfo_headername
; /* Name (Header), 8 bytes, ASCII */
1242 static int hf_s7comm_ud_blockinfo_headerversion
; /* Version (Header), 8 bytes, ASCII */
1243 static int hf_s7comm_ud_blockinfo_checksum
; /* Block checksum, 2 bytes, HEX */
1244 static int hf_s7comm_ud_blockinfo_reserved1
; /* Reserved 1, 4 bytes, HEX */
1245 static int hf_s7comm_ud_blockinfo_reserved2
; /* Reserved 2, 4 bytes, HEX */
1247 static int hf_s7comm_userdata_blockinfo_flags
; /* Some flags in Block info response */
1248 static int hf_s7comm_userdata_blockinfo_linked
; /* Some flags in Block info response */
1249 static int hf_s7comm_userdata_blockinfo_standard_block
;
1250 static int hf_s7comm_userdata_blockinfo_nonretain
; /* Some flags in Block info response */
1251 static int ett_s7comm_userdata_blockinfo_flags
;
1252 static int * const s7comm_userdata_blockinfo_flags_fields
[] = {
1253 &hf_s7comm_userdata_blockinfo_linked
,
1254 &hf_s7comm_userdata_blockinfo_standard_block
,
1255 &hf_s7comm_userdata_blockinfo_nonretain
,
1259 /* Programmer commands / Test and installation (TIS) functions */
1260 static int hf_s7comm_tis_parameter
;
1261 static int hf_s7comm_tis_data
;
1262 static int hf_s7comm_tis_parametersize
;
1263 static int hf_s7comm_tis_datasize
;
1264 static int hf_s7comm_tis_param1
;
1265 static int hf_s7comm_tis_param2
;
1266 static const value_string tis_param2_names
[] = { /* Values and their meaning are not always clearly defined in every function */
1267 { 0, "Update Monitor Variables / Activate Modify Values"},
1268 { 1, "Monitor Variable / Modify Variable" },
1269 { 2, "Modify Variable permanent" },
1270 { 256, "Force immediately" },
1273 static int hf_s7comm_tis_param3
;
1274 static const value_string tis_param3_names
[] = {
1275 { 0, "Every cycle (permanent)" },
1277 { 2, "Always (force)" },
1280 static int hf_s7comm_tis_answersize
;
1281 static int hf_s7comm_tis_param5
;
1282 static int hf_s7comm_tis_param6
;
1283 static int hf_s7comm_tis_param7
;
1284 static int hf_s7comm_tis_param8
;
1285 static int hf_s7comm_tis_param9
;
1286 static int hf_s7comm_tis_trgevent
;
1287 static int hf_s7comm_tis_res_param1
;
1288 static int hf_s7comm_tis_res_param2
;
1289 static int hf_s7comm_tis_job_function
;
1290 static int hf_s7comm_tis_job_seqnr
;
1291 static int hf_s7comm_tis_job_reserved
;
1296 static int hf_s7comm_tis_interrupted_blocktype
;
1297 static int hf_s7comm_tis_interrupted_blocknr
;
1298 static int hf_s7comm_tis_interrupted_address
;
1299 static int hf_s7comm_tis_interrupted_prioclass
;
1300 static int hf_s7comm_tis_continued_blocktype
;
1301 static int hf_s7comm_tis_continued_blocknr
;
1302 static int hf_s7comm_tis_continued_address
;
1303 static int hf_s7comm_tis_breakpoint_blocktype
;
1304 static int hf_s7comm_tis_breakpoint_blocknr
;
1305 static int hf_s7comm_tis_breakpoint_address
;
1306 static int hf_s7comm_tis_breakpoint_reserved
;
1308 static int hf_s7comm_tis_p_callenv
;
1309 static const value_string tis_p_callenv_names
[] = {
1310 { 0, "Specified call environment"},
1311 { 2, "Specified global and/or instance data block"},
1314 static int hf_s7comm_tis_p_callcond
;
1315 static const value_string tis_p_callcond_names
[] = {
1316 { 0x0000, "Not set" },
1317 { 0x0001, "On block number" },
1318 { 0x0101, "On block number with code address" },
1319 { 0x0a00, "On DB1 (DB) content" },
1320 { 0x000a, "On DB2 (DI) content" },
1321 { 0x0a0a, "On DB1 (DB) and DB2 (DI) content" },
1324 static int hf_s7comm_tis_p_callcond_blocktype
;
1325 static int hf_s7comm_tis_p_callcond_blocknr
;
1326 static int hf_s7comm_tis_p_callcond_address
;
1329 static int hf_s7comm_tis_register_db1_type
;
1330 static int hf_s7comm_tis_register_db2_type
;
1331 static int hf_s7comm_tis_register_db1_nr
;
1332 static int hf_s7comm_tis_register_db2_nr
;
1333 static int hf_s7comm_tis_register_accu1
;
1334 static int hf_s7comm_tis_register_accu2
;
1335 static int hf_s7comm_tis_register_accu3
;
1336 static int hf_s7comm_tis_register_accu4
;
1337 static int hf_s7comm_tis_register_ar1
;
1338 static int hf_s7comm_tis_register_ar2
;
1339 static int hf_s7comm_tis_register_stw
;
1340 static int hf_s7comm_tis_exithold_until
;
1341 static const value_string tis_exithold_until_names
[] = {
1342 { 0, "Next breakpoint" },
1343 { 1, "Next statement" },
1346 static int hf_s7comm_tis_exithold_res1
;
1347 static int hf_s7comm_tis_bstack_nest_depth
;
1348 static int hf_s7comm_tis_bstack_reserved
;
1349 static int hf_s7comm_tis_istack_reserved
;
1350 static int hf_s7comm_tis_lstack_reserved
;
1351 static int hf_s7comm_tis_lstack_size
;
1352 static int hf_s7comm_tis_lstack_data
;
1353 static int hf_s7comm_tis_blockstat_flagsunknown
;
1354 static int hf_s7comm_tis_blockstat_number_of_lines
;
1355 static int hf_s7comm_tis_blockstat_line_address
;
1356 static int hf_s7comm_tis_blockstat_data
;
1357 static int hf_s7comm_tis_blockstat_reserved
;
1359 /* Organization block local data */
1360 static int hf_s7comm_ob_ev_class
;
1361 static int hf_s7comm_ob_scan_1
;
1362 static int hf_s7comm_ob_strt_inf
;
1363 static int hf_s7comm_ob_flt_id
;
1364 static int hf_s7comm_ob_priority
;
1365 static int hf_s7comm_ob_number
;
1366 static int hf_s7comm_ob_reserved_1
;
1367 static int hf_s7comm_ob_reserved_2
;
1368 static int hf_s7comm_ob_reserved_3
;
1369 static int hf_s7comm_ob_reserved_4
;
1370 static int hf_s7comm_ob_reserved_4_dw
;
1371 static int hf_s7comm_ob_prev_cycle
;
1372 static int hf_s7comm_ob_min_cycle
;
1373 static int hf_s7comm_ob_max_cycle
;
1374 static int hf_s7comm_ob_period_exe
;
1375 static int hf_s7comm_ob_sign
;
1376 static int hf_s7comm_ob_dtime
;
1377 static int hf_s7comm_ob_phase_offset
;
1378 static int hf_s7comm_ob_exec_freq
;
1379 static int hf_s7comm_ob_io_flag
;
1380 static int hf_s7comm_ob_mdl_addr
;
1381 static int hf_s7comm_ob_point_addr
;
1382 static int hf_s7comm_ob_inf_len
;
1383 static int hf_s7comm_ob_alarm_type
;
1384 static int hf_s7comm_ob_alarm_slot
;
1385 static int hf_s7comm_ob_alarm_spec
;
1386 static int hf_s7comm_ob_error_info
;
1387 static int hf_s7comm_ob_err_ev_class
;
1388 static int hf_s7comm_ob_err_ev_num
;
1389 static int hf_s7comm_ob_err_ob_priority
;
1390 static int hf_s7comm_ob_err_ob_num
;
1391 static int hf_s7comm_ob_rack_cpu
;
1392 static int hf_s7comm_ob_8x_fault_flags
;
1393 static int hf_s7comm_ob_mdl_type_b
;
1394 static int hf_s7comm_ob_mdl_type_w
;
1395 static int hf_s7comm_ob_rack_num
;
1396 static int hf_s7comm_ob_racks_flt
;
1397 static int hf_s7comm_ob_strtup
;
1398 static int hf_s7comm_ob_stop
;
1399 static int hf_s7comm_ob_strt_info
;
1400 static int hf_s7comm_ob_sw_flt
;
1401 static int hf_s7comm_ob_blk_type
;
1402 static int hf_s7comm_ob_flt_reg
;
1403 static int hf_s7comm_ob_flt_blk_num
;
1404 static int hf_s7comm_ob_prg_addr
;
1405 static int hf_s7comm_ob_mem_area
;
1406 static int hf_s7comm_ob_mem_addr
;
1408 static int hf_s7comm_diagdata_req_block_type
;
1409 static int hf_s7comm_diagdata_req_block_num
;
1410 static int hf_s7comm_diagdata_req_startaddr_awl
;
1411 static int hf_s7comm_diagdata_req_saz
;
1413 /* Flags for requested registers in diagnostic data telegrams */
1414 static int hf_s7comm_diagdata_registerflag
; /* Registerflags */
1415 static int hf_s7comm_diagdata_registerflag_stw
; /* STW = Status word */
1416 static int hf_s7comm_diagdata_registerflag_accu1
; /* Accumulator 1 */
1417 static int hf_s7comm_diagdata_registerflag_accu2
; /* Accumulator 2 */
1418 static int hf_s7comm_diagdata_registerflag_ar1
; /* Addressregister 1 */
1419 static int hf_s7comm_diagdata_registerflag_ar2
; /* Addressregister 2 */
1420 static int hf_s7comm_diagdata_registerflag_db1
; /* Datablock register 1 */
1421 static int hf_s7comm_diagdata_registerflag_db2
; /* Datablock register 2 */
1422 static int ett_s7comm_diagdata_registerflag
;
1423 static int * const s7comm_diagdata_registerflag_fields
[] = {
1424 &hf_s7comm_diagdata_registerflag_stw
,
1425 &hf_s7comm_diagdata_registerflag_accu1
,
1426 &hf_s7comm_diagdata_registerflag_accu2
,
1427 &hf_s7comm_diagdata_registerflag_ar1
,
1428 &hf_s7comm_diagdata_registerflag_ar2
,
1429 &hf_s7comm_diagdata_registerflag_db1
,
1430 &hf_s7comm_diagdata_registerflag_db2
,
1434 static heur_dissector_list_t s7comm_heur_subdissector_list
;
1436 static expert_field ei_s7comm_data_blockcontrol_block_num_invalid
;
1437 static expert_field ei_s7comm_ud_blockinfo_block_num_ascii_invalid
;
1439 /* PI service name IDs. Index represents the index in pi_service_names */
1442 S7COMM_PI_UNKNOWN
= 0,
1512 /* Description for PI service names */
1513 static const string_string pi_service_names
[] = {
1514 { "UNKNOWN", "PI-Service is currently unknown" },
1515 { "_INSE", "PI-Service _INSE (Activates a PLC module)" },
1516 { "_INS2", "PI-Service _INS2 (Activates a PLC module)" },
1517 { "_DELE", "PI-Service _DELE (Removes module from the PLC's passive file system)" },
1518 { "P_PROGRAM", "PI-Service P_PROGRAM (PLC Start / Stop)" },
1519 { "_MODU", "PI-Service _MODU (PLC Copy Ram to Rom)" },
1520 { "_GARB", "PI-Service _GARB (Compress PLC memory)" },
1521 { "_N_LOGIN_", "PI-Service _N_LOGIN_ (Login)" },
1522 { "_N_LOGOUT", "PI-Service _N_LOGOUT (Logout)" },
1523 { "_N_CANCEL", "PI-Service _N_CANCEL (Cancels NC alarm)" },
1524 { "_N_DASAVE", "PI-Service _N_DASAVE (PI-Service for copying data from SRAM to FLASH)" },
1525 { "_N_DIGIOF", "PI-Service _N_DIGIOF (Turns off digitizing)" },
1526 { "_N_DIGION", "PI-Service _N_DIGION (Turns on digitizing)" },
1527 { "_N_DZERO_", "PI-Service _N_DZERO_ (Set all D nos. invalid for function \"unique D no.\")" },
1528 { "_N_ENDEXT", "PI-Service _N_ENDEXT ()" },
1529 { "_N_F_OPER", "PI-Service _N_F_OPER (Opens a file read-only)" },
1530 { "_N_OST_OF", "PI-Service _N_OST_OF (Overstore OFF)" },
1531 { "_N_OST_ON", "PI-Service _N_OST_ON (Overstore ON)" },
1532 { "_N_SCALE_", "PI-Service _N_SCALE_ (Unit of measurement setting (metric<->INCH))" },
1533 { "_N_SETUFR", "PI-Service _N_SETUFR (Activates user frame)" },
1534 { "_N_STRTLK", "PI-Service _N_STRTLK (The global start disable is set)" },
1535 { "_N_STRTUL", "PI-Service _N_STRTUL (The global start disable is reset)" },
1536 { "_N_TMRASS", "PI-Service _N_TMRASS (Resets the Active status)" },
1537 { "_N_F_DELE", "PI-Service _N_F_DELE (Deletes file)" },
1538 { "_N_EXTERN", "PI-Service _N_EXTERN (Selects external program for execution)" },
1539 { "_N_EXTMOD", "PI-Service _N_EXTMOD (Selects external program for execution)" },
1540 { "_N_F_DELR", "PI-Service _N_F_DELR (Delete file even without access rights)" },
1541 { "_N_F_XFER", "PI-Service _N_F_XFER (Selects file for uploading)" },
1542 { "_N_LOCKE_", "PI-Service _N_LOCKE_ (Locks the active file for editing)" },
1543 { "_N_SELECT", "PI-Service _N_SELECT (Selects program for execution)" },
1544 { "_N_SRTEXT", "PI-Service _N_SRTEXT (A file is being marked in /_N_EXT_DIR)" },
1545 { "_N_F_CLOS", "PI-Service _N_F_CLOS (Closes file)" },
1546 { "_N_F_OPEN", "PI-Service _N_F_OPEN (Opens file)" },
1547 { "_N_F_SEEK", "PI-Service _N_F_SEEK (Position the file search pointer)" },
1548 { "_N_ASUP__", "PI-Service _N_ASUP__ (Assigns interrupt)" },
1549 { "_N_CHEKDM", "PI-Service _N_CHEKDM (Start uniqueness check on D numbers)" },
1550 { "_N_CHKDNO", "PI-Service _N_CHKDNO (Check whether the tools have unique D numbers)" },
1551 { "_N_CONFIG", "PI-Service _N_CONFIG (Reconfigures machine data)" },
1552 { "_N_CRCEDN", "PI-Service _N_CRCEDN (Creates a cutting edge by specifying an edge no.)" },
1553 { "_N_DELECE", "PI-Service _N_DELECE (Deletes a cutting edge)" },
1554 { "_N_CREACE", "PI-Service _N_CREACE (Creates a cutting edge)" },
1555 { "_N_CREATO", "PI-Service _N_CREATO (Creates a tool)" },
1556 { "_N_DELETO", "PI-Service _N_DELETO (Deletes tool)" },
1557 { "_N_CRTOCE", "PI-Service _N_CRTOCE (Generate tool with specified edge number)" },
1558 { "_N_DELVAR", "PI-Service _N_DELVAR (Delete data block)" },
1559 { "_N_F_COPY", "PI-Service _N_F_COPY (Copies file within the NCK)" },
1560 { "_N_F_DMDA", "PI-Service _N_F_DMDA (Deletes MDA memory)" },
1561 { "_N_F_PROR", "PI-Service _N_F_PROR" },
1562 { "_N_F_PROT", "PI-Service _N_F_PROT (Assigns a protection level to a file)" },
1563 { "_N_F_RENA", "PI-Service _N_F_RENA (Renames file)" },
1564 { "_N_FINDBL", "PI-Service _N_FINDBL (Activates search)" },
1565 { "_N_IBN_SS", "PI-Service _N_IBN_SS (Sets the set-up switch)" },
1566 { "_N_MMCSEM", "PI-Service _N_MMCSEM (MMC-Semaphore)" },
1567 { "_N_NCKMOD", "PI-Service _N_NCKMOD (The mode in which the NCK will work is being set)" },
1568 { "_N_NEWPWD", "PI-Service _N_NEWPWD (New password)" },
1569 { "_N_SEL_BL", "PI-Service _N_SEL_BL (Selects a new block)" },
1570 { "_N_SETTST", "PI-Service _N_SETTST (Activate tools for replacement tool group)" },
1571 { "_N_TMAWCO", "PI-Service _N_TMAWCO (Set the active wear group in one magazine)" },
1572 { "_N_TMCRTC", "PI-Service _N_TMCRTC (Create tool with specified edge number)" },
1573 { "_N_TMCRTO", "PI-Service _N_TMCRTO (Creates tool in the tool management)" },
1574 { "_N_TMFDPL", "PI-Service _N_TMFDPL (Searches an empty place for loading)" },
1575 { "_N_TMFPBP", "PI-Service _N_TMFPBP (Searches for empty location)" },
1576 { "_N_TMGETT", "PI-Service _N_TMGETT (Determines T-number for specific toolID with Duplono)" },
1577 { "_N_TMMVTL", "PI-Service _N_TMMVTL (Loads or unloads a tool)" },
1578 { "_N_TMPCIT", "PI-Service _N_TMPCIT (Sets increment value of the piece counter)" },
1579 { "_N_TMPOSM", "PI-Service _N_TMPOSM (Positions a magazine or tool)" },
1580 { "_N_TRESMO", "PI-Service _N_TRESMO (Reset monitoring values)" },
1581 { "_N_TSEARC", "PI-Service _N_TSEARC (Complex search via search screenforms)" },
1585 /* Function 0x28 (PI Start) */
1586 static int hf_s7comm_piservice_unknown1
; /* Unknown bytes */
1587 static int hf_s7comm_piservice_parameterblock
;
1588 static int hf_s7comm_piservice_parameterblock_len
;
1589 static int hf_s7comm_piservice_servicename
;
1591 static int ett_s7comm_piservice_parameterblock
;
1593 static int hf_s7comm_piservice_string_len
;
1594 static int hf_s7comm_pi_n_x_addressident
;
1595 static int hf_s7comm_pi_n_x_password
;
1596 static int hf_s7comm_pi_n_x_filename
;
1597 static int hf_s7comm_pi_n_x_editwindowname
;
1598 static int hf_s7comm_pi_n_x_seekpointer
;
1599 static int hf_s7comm_pi_n_x_windowsize
;
1600 static int hf_s7comm_pi_n_x_comparestring
;
1601 static int hf_s7comm_pi_n_x_skipcount
;
1602 static int hf_s7comm_pi_n_x_interruptnr
;
1603 static int hf_s7comm_pi_n_x_priority
;
1604 static int hf_s7comm_pi_n_x_liftfast
;
1605 static int hf_s7comm_pi_n_x_blsync
;
1606 static int hf_s7comm_pi_n_x_magnr
;
1607 static int hf_s7comm_pi_n_x_dnr
;
1608 static int hf_s7comm_pi_n_x_spindlenumber
;
1609 static int hf_s7comm_pi_n_x_wznr
;
1610 static int hf_s7comm_pi_n_x_class
;
1611 static int hf_s7comm_pi_n_x_tnr
;
1612 static int hf_s7comm_pi_n_x_toolnumber
;
1613 static int hf_s7comm_pi_n_x_cenumber
;
1614 static int hf_s7comm_pi_n_x_datablocknumber
;
1615 static int hf_s7comm_pi_n_x_firstcolumnnumber
;
1616 static int hf_s7comm_pi_n_x_lastcolumnnumber
;
1617 static int hf_s7comm_pi_n_x_firstrownumber
;
1618 static int hf_s7comm_pi_n_x_lastrownumber
;
1619 static int hf_s7comm_pi_n_x_direction
;
1620 static int hf_s7comm_pi_n_x_sourcefilename
;
1621 static int hf_s7comm_pi_n_x_destinationfilename
;
1622 static int hf_s7comm_pi_n_x_channelnumber
;
1623 static int hf_s7comm_pi_n_x_protection
;
1624 static int hf_s7comm_pi_n_x_oldfilename
;
1625 static int hf_s7comm_pi_n_x_newfilename
;
1626 static int hf_s7comm_pi_n_x_findmode
;
1627 static int hf_s7comm_pi_n_x_switch
;
1628 static int hf_s7comm_pi_n_x_functionnumber
;
1629 static int hf_s7comm_pi_n_x_semaphorevalue
;
1630 static int hf_s7comm_pi_n_x_onoff
;
1631 static int hf_s7comm_pi_n_x_mode
;
1632 static int hf_s7comm_pi_n_x_factor
;
1633 static int hf_s7comm_pi_n_x_passwordlevel
;
1634 static int hf_s7comm_pi_n_x_linenumber
;
1635 static int hf_s7comm_pi_n_x_weargroup
;
1636 static int hf_s7comm_pi_n_x_toolstatus
;
1637 static int hf_s7comm_pi_n_x_wearsearchstrat
;
1638 static int hf_s7comm_pi_n_x_toolid
;
1639 static int hf_s7comm_pi_n_x_duplonumber
;
1640 static int hf_s7comm_pi_n_x_edgenumber
;
1641 static int hf_s7comm_pi_n_x_placenr
;
1642 static int hf_s7comm_pi_n_x_placerefnr
;
1643 static int hf_s7comm_pi_n_x_magrefnr
;
1644 static int hf_s7comm_pi_n_x_magnrfrom
;
1645 static int hf_s7comm_pi_n_x_placenrfrom
;
1646 static int hf_s7comm_pi_n_x_magnrto
;
1647 static int hf_s7comm_pi_n_x_placenrto
;
1648 static int hf_s7comm_pi_n_x_halfplacesleft
;
1649 static int hf_s7comm_pi_n_x_halfplacesright
;
1650 static int hf_s7comm_pi_n_x_halfplacesup
;
1651 static int hf_s7comm_pi_n_x_halfplacesdown
;
1652 static int hf_s7comm_pi_n_x_placetype
;
1653 static int hf_s7comm_pi_n_x_searchdirection
;
1654 static int hf_s7comm_pi_n_x_toolname
;
1655 static int hf_s7comm_pi_n_x_placenrsource
;
1656 static int hf_s7comm_pi_n_x_magnrsource
;
1657 static int hf_s7comm_pi_n_x_placenrdestination
;
1658 static int hf_s7comm_pi_n_x_magnrdestination
;
1659 static int hf_s7comm_pi_n_x_incrementnumber
;
1660 static int hf_s7comm_pi_n_x_monitoringmode
;
1661 static int hf_s7comm_pi_n_x_kindofsearch
;
1663 static int hf_s7comm_data_plccontrol_argument
; /* Argument, 2 Bytes as char */
1664 static int hf_s7comm_data_plccontrol_block_cnt
; /* Number of blocks, 1 Byte as int */
1665 static int hf_s7comm_data_pi_inse_unknown
;
1666 static int hf_s7comm_data_plccontrol_part2_len
; /* Length part 2 in bytes, 1 Byte as Int */
1668 /* block control functions */
1669 static int hf_s7comm_data_blockcontrol_unknown1
; /* for all unknown bytes in blockcontrol */
1670 static int hf_s7comm_data_blockcontrol_errorcode
; /* Error code 2 bytes as int, 0 is no error */
1671 static int hf_s7comm_data_blockcontrol_uploadid
;
1672 static int hf_s7comm_data_blockcontrol_file_ident
; /* File identifier, as ASCII */
1673 static int hf_s7comm_data_blockcontrol_block_type
; /* Block type, 2 Byte */
1674 static int hf_s7comm_data_blockcontrol_block_num
; /* Block number, 5 Bytes, ASCII */
1675 static int hf_s7comm_data_blockcontrol_dest_filesys
; /* Destination filesystem, 1 Byte, ASCII */
1676 static int hf_s7comm_data_blockcontrol_part2_len
; /* Length part 2 in bytes, 1 Byte Int */
1677 static int hf_s7comm_data_blockcontrol_part2_unknown
; /* Unknown char, ASCII */
1678 static int hf_s7comm_data_blockcontrol_loadmem_len
; /* Length load memory in bytes, ASCII */
1679 static int hf_s7comm_data_blockcontrol_mc7code_len
; /* Length of MC7 code in bytes, ASCII */
1680 static int hf_s7comm_data_blockcontrol_filename_len
;
1681 static int hf_s7comm_data_blockcontrol_filename
;
1682 static int hf_s7comm_data_blockcontrol_upl_lenstring_len
;
1683 static int hf_s7comm_data_blockcontrol_upl_lenstring
;
1685 static int hf_s7comm_data_blockcontrol_functionstatus
;
1686 static int hf_s7comm_data_blockcontrol_functionstatus_more
;
1687 static int hf_s7comm_data_blockcontrol_functionstatus_error
;
1688 static int ett_s7comm_data_blockcontrol_status
;
1689 static int * const s7comm_data_blockcontrol_status_fields
[] = {
1690 &hf_s7comm_data_blockcontrol_functionstatus_more
,
1691 &hf_s7comm_data_blockcontrol_functionstatus_error
,
1695 static int ett_s7comm_plcfilename
;
1696 static int hf_s7comm_data_ncprg_unackcount
;
1697 static int hf_s7comm_data_ncprg_filelength
;
1698 static int hf_s7comm_data_ncprg_filetime
;
1699 static int hf_s7comm_data_ncprg_filepath
;
1700 static int hf_s7comm_data_ncprg_filedata
;
1702 /* Data record routing to Profibus */
1703 static int hf_s7comm_data_drr_data
;
1705 /* Variable status */
1706 static int hf_s7comm_varstat_unknown
; /* Unknown byte(s), hex */
1707 static int hf_s7comm_varstat_item_count
; /* Item count, 2 bytes, int */
1708 static int hf_s7comm_varstat_req_memory_area
; /* Memory area, 1 byte, stringlist userdata_tis_varstat_area_names */
1709 static int hf_s7comm_varstat_req_repetition_factor
; /* Repetition factor, 1 byte as int */
1710 static int hf_s7comm_varstat_req_db_number
; /* DB number, 2 bytes as int */
1711 static int hf_s7comm_varstat_req_startaddress
; /* Startaddress, 2 bytes as int */
1712 static int hf_s7comm_varstat_req_bitpos
;
1714 /* cyclic services */
1715 static int hf_s7comm_cycl_interval_timebase
; /* Interval timebase, 1 byte, int */
1716 static int hf_s7comm_cycl_interval_time
; /* Interval time, 1 byte, int */
1717 static int hf_s7comm_cycl_function
;
1718 static int hf_s7comm_cycl_jobid
;
1721 static int hf_s7comm_rdrec_mlen
; /* Max. length in bytes of the data record data to be read */
1722 static int hf_s7comm_rdrec_index
; /* Data record number */
1723 static int hf_s7comm_rdrec_id
; /* Diagnostic address */
1724 static int hf_s7comm_rdrec_statuslen
; /* Length of optional status data */
1725 static int hf_s7comm_rdrec_statusdata
; /* Optional status data */
1726 static int hf_s7comm_rdrec_recordlen
; /* Length of data record data read */
1727 static int hf_s7comm_rdrec_data
; /* The read data record */
1728 static int hf_s7comm_rdrec_reserved1
;
1730 /* PBC, Programmable Block Functions */
1731 static int hf_s7comm_pbc_unknown
; /* unknown, 1 byte */
1732 static int hf_s7comm_pbc_bsend_r_id
; /* Request ID R_ID, 4 bytes as hex */
1733 static int hf_s7comm_pbc_bsend_len
;
1734 static int hf_s7comm_pbc_usend_unknown1
;
1735 static int hf_s7comm_pbc_usend_r_id
;
1736 static int hf_s7comm_pbc_usend_unknown2
;
1737 static int hf_s7comm_pbc_arsend_ar_id
;
1738 static int hf_s7comm_pbc_arsend_ret
;
1739 static int hf_s7comm_pbc_arsend_unknown
;
1740 static int hf_s7comm_pbc_arsend_len
;
1742 /* Alarm messages */
1743 static int hf_s7comm_cpu_alarm_message_item
;
1744 static int hf_s7comm_cpu_alarm_message_obj_item
;
1745 static int hf_s7comm_cpu_alarm_message_function
;
1746 static int hf_s7comm_cpu_alarm_message_nr_objects
;
1747 static int hf_s7comm_cpu_alarm_message_nr_add_values
;
1748 static int hf_s7comm_cpu_alarm_message_eventid
;
1749 static int hf_s7comm_cpu_alarm_message_timestamp_coming
;
1750 static int hf_s7comm_cpu_alarm_message_timestamp_going
;
1751 static int hf_s7comm_cpu_alarm_message_associated_value
;
1752 static int hf_s7comm_cpu_alarm_message_eventstate
;
1753 static int hf_s7comm_cpu_alarm_message_state
;
1754 static int hf_s7comm_cpu_alarm_message_ackstate_coming
;
1755 static int hf_s7comm_cpu_alarm_message_ackstate_going
;
1756 static int hf_s7comm_cpu_alarm_message_event_coming
;
1757 static int hf_s7comm_cpu_alarm_message_event_going
;
1758 static int hf_s7comm_cpu_alarm_message_event_lastchanged
;
1759 static int hf_s7comm_cpu_alarm_message_event_reserved
;
1760 static int hf_s7comm_cpu_alarm_message_scan_unknown1
;
1761 static int hf_s7comm_cpu_alarm_message_scan_unknown2
;
1763 static int hf_s7comm_cpu_alarm_message_signal_sig1
;
1764 static int hf_s7comm_cpu_alarm_message_signal_sig2
;
1765 static int hf_s7comm_cpu_alarm_message_signal_sig3
;
1766 static int hf_s7comm_cpu_alarm_message_signal_sig4
;
1767 static int hf_s7comm_cpu_alarm_message_signal_sig5
;
1768 static int hf_s7comm_cpu_alarm_message_signal_sig6
;
1769 static int hf_s7comm_cpu_alarm_message_signal_sig7
;
1770 static int hf_s7comm_cpu_alarm_message_signal_sig8
;
1771 static int ett_s7comm_cpu_alarm_message_signal
;
1772 static int * const s7comm_cpu_alarm_message_signal_fields
[] = {
1773 &hf_s7comm_cpu_alarm_message_signal_sig1
,
1774 &hf_s7comm_cpu_alarm_message_signal_sig2
,
1775 &hf_s7comm_cpu_alarm_message_signal_sig3
,
1776 &hf_s7comm_cpu_alarm_message_signal_sig4
,
1777 &hf_s7comm_cpu_alarm_message_signal_sig5
,
1778 &hf_s7comm_cpu_alarm_message_signal_sig6
,
1779 &hf_s7comm_cpu_alarm_message_signal_sig7
,
1780 &hf_s7comm_cpu_alarm_message_signal_sig8
,
1784 static int hf_s7comm_cpu_alarm_query_unknown1
;
1785 static int hf_s7comm_cpu_alarm_query_querytype
;
1786 static int hf_s7comm_cpu_alarm_query_unknown2
;
1787 static int hf_s7comm_cpu_alarm_query_alarmtype
;
1788 static int hf_s7comm_cpu_alarm_query_completelen
;
1789 static int hf_s7comm_cpu_alarm_query_datasetlen
;
1790 static int hf_s7comm_cpu_alarm_query_resunknown1
;
1792 /* CPU diagnostic messages */
1793 static int hf_s7comm_cpu_diag_msg_item
;
1794 static int hf_s7comm_cpu_diag_msg_eventid
;
1795 static int hf_s7comm_cpu_diag_msg_eventid_class
;
1796 static int hf_s7comm_cpu_diag_msg_eventid_ident_entleave
;
1797 static int hf_s7comm_cpu_diag_msg_eventid_ident_diagbuf
;
1798 static int hf_s7comm_cpu_diag_msg_eventid_ident_interr
;
1799 static int hf_s7comm_cpu_diag_msg_eventid_ident_exterr
;
1800 static int hf_s7comm_cpu_diag_msg_eventid_nr
;
1801 static int hf_s7comm_cpu_diag_msg_prioclass
;
1802 static int hf_s7comm_cpu_diag_msg_obnumber
;
1803 static int hf_s7comm_cpu_diag_msg_datid
;
1804 static int hf_s7comm_cpu_diag_msg_info1
;
1805 static int hf_s7comm_cpu_diag_msg_info2
;
1807 static int ett_s7comm_cpu_diag_msg_eventid
;
1808 static int * const s7comm_cpu_diag_msg_eventid_fields
[] = {
1809 &hf_s7comm_cpu_diag_msg_eventid_class
,
1810 &hf_s7comm_cpu_diag_msg_eventid_ident_entleave
,
1811 &hf_s7comm_cpu_diag_msg_eventid_ident_diagbuf
,
1812 &hf_s7comm_cpu_diag_msg_eventid_ident_interr
,
1813 &hf_s7comm_cpu_diag_msg_eventid_ident_exterr
,
1814 &hf_s7comm_cpu_diag_msg_eventid_nr
,
1818 static const true_false_string tfs_s7comm_cpu_diag_msg_eventid_ident_entleave
= {
1823 static const value_string cpu_diag_msg_eventid_class_names
[] = {
1824 { 0x01, "Standard OB events" },
1825 { 0x02, "Synchronous errors" },
1826 { 0x03, "Asynchronous errors" },
1827 { 0x04, "Mode transitions" },
1828 { 0x05, "Run-time events" },
1829 { 0x06, "Communication events" },
1830 { 0x07, "Events for fail-safe and fault-tolerant systems" },
1831 { 0x08, "Standardized diagnostic data on modules" },
1832 { 0x09, "Predefined user events" },
1833 { 0x0a, "Freely definable events" },
1834 { 0x0b, "Freely definable events" },
1835 { 0x0c, "Reserved" },
1836 { 0x0d, "Reserved" },
1837 { 0x0e, "Reserved" },
1838 { 0x0f, "Events for modules other than CPUs" },
1842 static const value_string cpu_diag_eventid_fix_names
[] = {
1843 { 0x113A, "Start request for cyclic interrupt OB with special handling (S7-300 only)" },
1844 { 0x1155, "Status alarm for PROFIBUS DP" },
1845 { 0x1156, "Update interrupt for PROFIBUS DP" },
1846 { 0x1157, "Manufacturer interrupt for PROFIBUS DP" },
1847 { 0x1158, "Status interrupt for PROFINET IO" },
1848 { 0x1159, "Update interrupt for PROFINET IO" },
1849 { 0x115A, "Manufacturer interrupt for PROFINET IO" },
1850 { 0x115B, "IO: Profile-specific interrupt" },
1851 { 0x116A, "Technology synchronization interrupt" },
1852 { 0x1381, "Request for manual warm restart" },
1853 { 0x1382, "Request for automatic warm restart" },
1854 { 0x1383, "Request for manual hot restart" },
1855 { 0x1384, "Request for automatic hot restart" },
1856 { 0x1385, "Request for manual cold restart" },
1857 { 0x1386, "Request for automatic cold restart" },
1858 { 0x1387, "Master CPU: request for manual cold restart" },
1859 { 0x1388, "Master CPU: request for automatic cold restart" },
1860 { 0x138A, "Master CPU: request for manual warm restart" },
1861 { 0x138B, "Master CPU: request for automatic warm restart" },
1862 { 0x138C, "Standby CPU: request for manual hot restart" },
1863 { 0x138D, "Standby CPU: request for automatic hot restart" },
1864 { 0x2521, "BCD conversion error" },
1865 { 0x2522, "Area length error when reading" },
1866 { 0x2523, "Area length error when writing" },
1867 { 0x2524, "Area error when reading" },
1868 { 0x2525, "Area error when writing" },
1869 { 0x2526, "Timer number error" },
1870 { 0x2527, "Counter number error" },
1871 { 0x2528, "Alignment error when reading" },
1872 { 0x2529, "Alignment error when writing" },
1873 { 0x2530, "Write error when accessing the DB" },
1874 { 0x2531, "Write error when accessing the DI" },
1875 { 0x2532, "Block number error when opening a DB" },
1876 { 0x2533, "Block number error when opening a DI" },
1877 { 0x2534, "Block number error when calling an FC" },
1878 { 0x2535, "Block number error when calling an FB" },
1879 { 0x253A, "DB not loaded" },
1880 { 0x253C, "FC not loaded" },
1881 { 0x253D, "SFC not loaded" },
1882 { 0x253E, "FB not loaded" },
1883 { 0x253F, "SFB not loaded" },
1884 { 0x2942, "I/O access error, reading" },
1885 { 0x2943, "I/O access error, writing" },
1886 { 0x3267, "End of module reconfiguration" },
1887 { 0x3367, "Start of module reconfiguration" },
1888 { 0x34A4, "PROFInet Interface DB can be addressed again" },
1889 { 0x3501, "Cycle time exceeded" },
1890 { 0x3502, "User interface (OB or FRB) request error" },
1891 { 0x3503, "Delay too long processing a priority class" },
1892 { 0x3505, "Time-of-day interrupt(s) skipped due to new clock setting" },
1893 { 0x3506, "Time-of-day interrupt(s) skipped when changing to RUN after HOLD" },
1894 { 0x3507, "Multiple OB request errors caused internal buffer overflow" },
1895 { 0x3508, "Synchronous cycle interrupt-timing error" },
1896 { 0x3509, "Interrupt loss due to excess interrupt load" },
1897 { 0x350A, "Resume RUN mode after CiR" },
1898 { 0x350B, "Technology synchronization interrupt - timing error" },
1899 { 0x3571, "Nesting depth too high in nesting levels" },
1900 { 0x3572, "Nesting depth for Master Control Relays too high" },
1901 { 0x3573, "Nesting depth too high after synchronous errors" },
1902 { 0x3574, "Nesting depth for block calls (U stack) too high" },
1903 { 0x3575, "Nesting depth for block calls (B stack) too high" },
1904 { 0x3576, "Local data allocation error" },
1905 { 0x3578, "Unknown instruction" },
1906 { 0x357A, "Jump instruction to target outside of the block" },
1907 { 0x3582, "Memory error detected and corrected by operating system" },
1908 { 0x3583, "Accumulation of detected and corrected memo errors" },
1909 { 0x3585, "Error in the PC operating system (only for LC RTX)" },
1910 { 0x3587, "Multi-bit memory error detected and corrected" },
1911 { 0x35A1, "User interface (OB or FRB) not found" },
1912 { 0x35A2, "OB not loaded (started by SFC or operating system due to configuration)" },
1913 { 0x35A3, "Error when operating system accesses a block" },
1914 { 0x35A4, "PROFInet Interface DB cannot be addressed" },
1915 { 0x35D2, "Diagnostic entries cannot be sent at present" },
1916 { 0x35D3, "Synchronization frames cannot be sent" },
1917 { 0x35D4, "Illegal time jump resulting from synchronization" },
1918 { 0x35D5, "Error adopting the synchronization time" },
1919 { 0x35E1, "Incorrect frame ID in GD" },
1920 { 0x35E2, "GD packet status cannot be entered in DB" },
1921 { 0x35E3, "Frame length error in GD" },
1922 { 0x35E4, "Illegal GD packet number received" },
1923 { 0x35E5, "Error accessing DB in communication SFBs for configured S7 connections" },
1924 { 0x35E6, "GD total status cannot be entered in DB" },
1925 { 0x3821, "BATTF: failure on at least one backup battery of the central rack, problem eliminated" },
1926 { 0x3822, "BAF: failure of backup voltage on central rack, problem eliminated" },
1927 { 0x3823, "24 volt supply failure on central rack, problem eliminated" },
1928 { 0x3825, "BATTF: failure on at least one backup battery of the redundant central rack, problem eliminated" },
1929 { 0x3826, "BAF: failure of backup voltage on redundant central rack, problem eliminated" },
1930 { 0x3827, "24 volt supply failure on redundant central rack, problem eliminated" },
1931 { 0x3831, "BATTF: failure of at least one backup battery of the expansion rack, problem eliminated" },
1932 { 0x3832, "BAF: failure of backup voltage on expansion rack, problem eliminated" },
1933 { 0x3833, "24 volt supply failure on at least one expansion rack, problem eliminated" },
1934 { 0x3842, "Module OK" },
1935 { 0x3854, "PROFINET IO interface submodule/submodule and matches the configured interface submodule/submodule" },
1936 { 0x3855, "PROFINET IO interface submodule/submodule inserted, but does not match the configured interface submodule/submodule" },
1937 { 0x3856, "PROFINET IO interface submodule/submodule inserted, but error in module parameter assignment" },
1938 { 0x3858, "PROFINET IO interface submodule access error corrected" },
1939 { 0x3861, "Module/interface module inserted, module type OK" },
1940 { 0x3863, "Module/interface module plugged in, but wrong module type" },
1941 { 0x3864, "Module/interface module plugged in, but causing problem (type ID unreadable)" },
1942 { 0x3865, "Module plugged in, but error in module parameter assignment" },
1943 { 0x3866, "Module can be addressed again, load voltage error removed" },
1944 { 0x3881, "Interface error leaving state" },
1945 { 0x3884, "Interface module plugged in" },
1946 { 0x38B3, "I/O access error when updating the process image input table" },
1947 { 0x38B4, "I/O access error when transferring the process image to the output modules" },
1948 { 0x38C1, "Expansion rack operational again (1 to 21), leaving state" },
1949 { 0x38C2, "Expansion rack operational again but mismatch between setpoint and actual configuration" },
1950 { 0x38C4, "Distributed I/Os: station failure, leaving state" },
1951 { 0x38C5, "Distributed I/Os: station fault, leaving state" },
1952 { 0x38C6, "Expansion rack operational again, but error(s) in module parameter assignment" },
1953 { 0x38C7, "DP: station operational again, but error(s) in module parameter assignment" },
1954 { 0x38C8, "DP: station operational again, but mismatch between setpoint and actual configuration" },
1955 { 0x38CB, "PROFINET IO station operational again" },
1956 { 0x38CC, "PROFINET IO station error corrected" },
1957 { 0x3921, "BATTF: failure on at least one backup battery of the central rack" },
1958 { 0x3922, "BAF: failure of backup voltage on central rack" },
1959 { 0x3923, "24 volt supply failure on central rack" },
1960 { 0x3925, "BATTF: failure on at least one backup battery of the redundant central rack" },
1961 { 0x3926, "BAF: failure of backup voltage on redundant central rack" },
1962 { 0x3927, "24 volt supply failure on redundant central rack" },
1963 { 0x3931, "BATTF: failure of at least one backup battery of the expansion rack" },
1964 { 0x3932, "BAF: failure of backup voltage on expansion rack" },
1965 { 0x3933, "24 volt supply failure on at least one expansion rack" },
1966 { 0x3942, "Module error" },
1967 { 0x3951, "PROFINET IO submodule removed" },
1968 { 0x3954, "PROFINET IO interface submodule/submodule removed" },
1969 { 0x3961, "Module/interface module removed, cannot be addressed" },
1970 { 0x3966, "Module cannot be addressed, load voltage error" },
1971 { 0x3968, "Module reconfiguration has ended with error" },
1972 { 0x3981, "Interface error entering state" },
1973 { 0x3984, "Interface module removed" },
1974 { 0x3986, "Performance of an H-Sync link negatively affected" },
1975 { 0x39B1, "I/O access error when updating the process image input table" },
1976 { 0x39B2, "I/O access error when transferring the process image to the output modules" },
1977 { 0x39B3, "I/O access error when updating the process image input table" },
1978 { 0x39B4, "I/O access error when transferring the process image to the output modules" },
1979 { 0x39C1, "Expansion rack failure (1 to 21), entering state" },
1980 { 0x39C3, "Distributed I/Os: master system failure entering state" },
1981 { 0x39C4, "Distributed I/Os: station failure, entering state" },
1982 { 0x39C5, "Distributed I/Os: station fault, entering state" },
1983 { 0x39CA, "PROFINET IO system failure" },
1984 { 0x39CB, "PROFINET IO station failure" },
1985 { 0x39CC, "PROFINET IO station error" },
1986 { 0x39CD, "PROFINET IO station operational again, but expected configuration does not match actual configuration" },
1987 { 0x39CE, "PROFINET IO station operational again, but error(s) in module parameter assignment" },
1988 { 0x42F3, "Checksum error detected and corrected by the operating system" },
1989 { 0x42F4, "Standby CPU: connection/update via SFC90 is locked in the master CPU" },
1990 { 0x4300, "Backed-up power on" },
1991 { 0x4301, "Mode transition from STOP to STARTUP" },
1992 { 0x4302, "Mode transition from STARTUP to RUN" },
1993 { 0x4303, "STOP caused by stop switch being activated" },
1994 { 0x4304, "STOP caused by PG STOP operation or by SFB 20 STOP" },
1995 { 0x4305, "HOLD: breakpoint reached" },
1996 { 0x4306, "HOLD: breakpoint exited" },
1997 { 0x4307, "Memory reset started by PG operation" },
1998 { 0x4308, "Memory reset started by switch setting" },
1999 { 0x4309, "Memory reset started automatically (power on not backed up)" },
2000 { 0x430A, "HOLD exited, transition to STOP" },
2001 { 0x430D, "STOP caused by other CPU in multicomputing" },
2002 { 0x430E, "Memory reset executed" },
2003 { 0x430F, "STOP on the module due to STOP on a CPU" },
2004 { 0x4318, "Start of CiR" },
2005 { 0x4319, "CiR completed" },
2006 { 0x4357, "Module watchdog started" },
2007 { 0x4358, "All modules are ready for operation" },
2008 { 0x43B0, "Firmware update was successful" },
2009 { 0x43B4, "Error in firmware fuse" },
2010 { 0x43B6, "Firmware updates canceled by redundant modules" },
2011 { 0x43D3, "STOP on standby CPU" },
2012 { 0x43DC, "Abort during link-up with switchover" },
2013 { 0x43DE, "Updating aborted due to monitoring time being exceeded during the n-th attempt, new update attempt initiated" },
2014 { 0x43DF, "Updating aborted for final time due to monitoring time being exceeded after completing the maximum amount of attempts. User intervention required" },
2015 { 0x43E0, "Change from solo mode after link-up" },
2016 { 0x43E1, "Change from link-up after updating" },
2017 { 0x43E2, "Change from updating to redundant mode" },
2018 { 0x43E3, "Master CPU: change from redundant mode to solo mode" },
2019 { 0x43E4, "Standby CPU: change from redundant mode after error-search mode" },
2020 { 0x43E5, "Standby CPU: change from error-search mode after link-up or STOP" },
2021 { 0x43E6, "Link-up aborted on the standby CPU" },
2022 { 0x43E7, "Updating aborted on the standby CPU" },
2023 { 0x43E8, "Standby CPU: change from link-up after startup" },
2024 { 0x43E9, "Standby CPU: change from startup after updating" },
2025 { 0x43F1, "Reserve-master switchover" },
2026 { 0x43F2, "Coupling of incompatible H-CPUs blocked by system program" },
2027 { 0x4510, "STOP violation of the CPU's data range" },
2028 { 0x4520, "DEFECTIVE: STOP not possible" },
2029 { 0x4521, "DEFECTIVE: failure of instruction processing processor" },
2030 { 0x4522, "DEFECTIVE: failure of clock chip" },
2031 { 0x4523, "DEFECTIVE: failure of clock pulse generator" },
2032 { 0x4524, "DEFECTIVE: failure of timer update function" },
2033 { 0x4525, "DEFECTIVE: failure of multicomputing synchronization" },
2034 { 0x4527, "DEFECTIVE: failure of I/O access monitoring" },
2035 { 0x4528, "DEFECTIVE: failure of scan time monitoring" },
2036 { 0x4530, "DEFECTIVE: memory test error in internal memory" },
2037 { 0x4532, "DEFECTIVE: failure of core resources" },
2038 { 0x4536, "DEFECTIVE: switch defective" },
2039 { 0x4540, "STOP: Memory expansion of the internal work memory has gaps. First memory expansion too small or missing" },
2040 { 0x4541, "STOP caused by priority class system" },
2041 { 0x4542, "STOP caused by object management system" },
2042 { 0x4543, "STOP caused by test functions" },
2043 { 0x4544, "STOP caused by diagnostic system" },
2044 { 0x4545, "STOP caused by communication system" },
2045 { 0x4546, "STOP caused by CPU memory management" },
2046 { 0x4547, "STOP caused by process image management" },
2047 { 0x4548, "STOP caused by I/O management" },
2048 { 0x454A, "STOP caused by configuration: an OB deselected with STEP 7 was being loaded into the CPU during STARTUP" },
2049 { 0x4550, "DEFECTIVE: internal system error" },
2050 { 0x4555, "No restart possible, monitoring time elapsed" },
2051 { 0x4556, "STOP: memory reset request from communication system / due to data inconsistency" },
2052 { 0x4562, "STOP caused by programming error (OB not loaded or not possible)" },
2053 { 0x4563, "STOP caused by I/O access error (OB not loaded or not possible)" },
2054 { 0x4567, "STOP caused by H event" },
2055 { 0x4568, "STOP caused by time error (OB not loaded or not possible)" },
2056 { 0x456A, "STOP caused by diagnostic interrupt (OB not loaded or not possible)" },
2057 { 0x456B, "STOP caused by removing/inserting module (OB not loaded or not possible)" },
2058 { 0x456C, "STOP caused by CPU hardware error (OB not loaded or not possible, or no FRB)" },
2059 { 0x456D, "STOP caused by program sequence error (OB not loaded or not possible)" },
2060 { 0x456E, "STOP caused by communication error (OB not loaded or not possible)" },
2061 { 0x456F, "STOP caused by rack failure OB (OB not loaded or not possible)" },
2062 { 0x4570, "STOP caused by process interrupt (OB not loaded or not possible)" },
2063 { 0x4571, "STOP caused by nesting stack error" },
2064 { 0x4572, "STOP caused by master control relay stack error" },
2065 { 0x4573, "STOP caused by exceeding the nesting depth for synchronous errors" },
2066 { 0x4574, "STOP caused by exceeding interrupt stack nesting depth in the priority class stack" },
2067 { 0x4575, "STOP caused by exceeding block stack nesting depth in the priority class stack" },
2068 { 0x4576, "STOP caused by error when allocating the local data" },
2069 { 0x4578, "STOP caused by unknown opcode" },
2070 { 0x457A, "STOP caused by code length error" },
2071 { 0x457B, "STOP caused by DB not being loaded on on-board I/Os" },
2072 { 0x457D, "Reset/clear request because the version of the internal interface to the integrated technology was changed" },
2073 { 0x457F, "STOP caused by STOP command" },
2074 { 0x4580, "STOP: back-up buffer contents inconsistent (no transition to RUN)" },
2075 { 0x4590, "STOP caused by overloading the internal functions" },
2076 { 0x45D5, "LINK-UP rejected due to mismatched CPU memory configuration of the sub-PLC" },
2077 { 0x45D6, "LINK-UP rejected due to mismatched system program of the sub-PLC" },
2078 { 0x45D8, "DEFECTIVE: hardware fault detected due to other error" },
2079 { 0x45D9, "STOP due to SYNC module error" },
2080 { 0x45DA, "STOP due to synchronization error between H CPUs" },
2081 { 0x45DD, "LINK-UP rejected due to running test or other online functions" },
2082 { 0x4926, "DEFECTIVE: failure of the watchdog for I/O access" },
2083 { 0x4931, "STOP or DEFECTIVE: memory test error in memory submodule" },
2084 { 0x4933, "Checksum error" },
2085 { 0x4934, "DEFECTIVE: memory not available" },
2086 { 0x4935, "DEFECTIVE: cancelled by watchdog/processor exceptions" },
2087 { 0x4949, "STOP caused by continuous hardware interrupt" },
2088 { 0x494D, "STOP caused by I/O error" },
2089 { 0x494E, "STOP caused by power failure" },
2090 { 0x494F, "STOP caused by configuration error" },
2091 { 0x4959, "One or more modules not ready for operation" },
2092 { 0x497C, "STOP caused by integrated technology" },
2093 { 0x49A0, "STOP caused by parameter assignment error or non-permissible variation of setpoint and actual extension: Start-up blocked" },
2094 { 0x49A1, "STOP caused by parameter assignment error: memory reset request" },
2095 { 0x49A2, "STOP caused by error in parameter modification: startup disabled" },
2096 { 0x49A3, "STOP caused by error in parameter modification: memory reset request" },
2097 { 0x49A4, "STOP: inconsistency in configuration data" },
2098 { 0x49A5, "STOP: distributed I/Os: inconsistency in the loaded configuration information" },
2099 { 0x49A6, "STOP: distributed I/Os: invalid configuration information" },
2100 { 0x49A7, "STOP: distributed I/Os: no configuration information" },
2101 { 0x49A8, "STOP: error indicated by the interface module for the distributed I/Os" },
2102 { 0x49B1, "Firmware update data incorrect" },
2103 { 0x49B2, "Firmware update: hardware version does not match firmware" },
2104 { 0x49B3, "Firmware update: module type does not match firmware" },
2105 { 0x49D0, "LINK-UP aborted due to violation of coordination rules" },
2106 { 0x49D1, "LINK-UP/UPDATE sequence aborted" },
2107 { 0x49D2, "Standby CPU changed to STOP due to STOP on the master CPU during link-up" },
2108 { 0x49D4, "STOP on a master, since partner CPU is also a master (link-up error)" },
2109 { 0x49D7, "LINK-UP rejected due to change in user program or in configuration" },
2110 { 0x510F, "A problem as occurred with WinLC. This problem has caused the CPU to go into STOP mode or has caused a fault in the CPU" },
2111 { 0x530D, "New startup information in the STOP mode" },
2112 { 0x5311, "Startup despite Not Ready message from module(s)" },
2113 { 0x5371, "Distributed I/Os: end of the synchronization with a DP master" },
2114 { 0x5380, "Diagnostic buffer entries of interrupt and asynchronous errors disabled" },
2115 { 0x5395, "Distributed I/Os: reset of a DP master" },
2116 { 0x53A2, "Download of technology firmware successful" },
2117 { 0x53A4, "Download of technology DB not successful" },
2118 { 0x53FF, "Reset to factory setting" },
2119 { 0x5445, "Start of System reconfiguration in RUN mode" },
2120 { 0x5481, "All licenses for runtime software are complete again" },
2121 { 0x5498, "No more inconsistency with DP master systems due to CiR" },
2122 { 0x5545, "Start of System reconfiguration in RUN mode" },
2123 { 0x5581, "One or several licenses for runtime software are missing" },
2124 { 0x558A, "Difference between the MLFB of the configured and inserted CPU" },
2125 { 0x558B, "Difference in the firmware version of the configured and inserted CPU" },
2126 { 0x5598, "Start of possible inconsistency with DP master systems due to CiR" },
2127 { 0x55A5, "Version conflict: internal interface with integrated technology" },
2128 { 0x55A6, "The maximum number of technology objects has been exceeded" },
2129 { 0x55A7, "A technology DB of this type is already present" },
2130 { 0x5879, "Diagnostic message from DP interface: EXTF LED off" },
2131 { 0x5960, "Parameter assignment error when switching" },
2132 { 0x5961, "Parameter assignment error" },
2133 { 0x5962, "Parameter assignment error preventing startup" },
2134 { 0x5963, "Parameter assignment error with memory reset request" },
2135 { 0x5966, "Parameter assignment error when switching" },
2136 { 0x5969, "Parameter assignment error with startup blocked" },
2137 { 0x596A, "PROFINET IO: IP address of an IO device already present" },
2138 { 0x596B, "IP address of an Ethernet interface already exists" },
2139 { 0x596C, "Name of an Ethernet interface already exists" },
2140 { 0x596D, "The existing network configuration does not mach the system requirements or configuration" },
2141 { 0x5979, "Diagnostic message from DP interface: EXTF LED on" },
2142 { 0x597C, "DP Global Control command failed or moved" },
2143 { 0x59A0, "The interrupt can not be associated in the CPU" },
2144 { 0x59A1, "Configuration error in the integrated technology" },
2145 { 0x59A3, "Error when downloading the integrated technology" },
2146 { 0x6253, "Firmware update: End of firmware download over the network" },
2147 { 0x6316, "Interface error when starting programmable controller" },
2148 { 0x6353, "Firmware update: Start of firmware download over the network" },
2149 { 0x6390, "Formatting of Micro Memory Card complete" },
2150 { 0x6500, "Connection ID exists twice on module" },
2151 { 0x6501, "Connection resources inadequate" },
2152 { 0x6502, "Error in the connection description" },
2153 { 0x6510, "CFB structure error detected in instance DB when evaluating EPROM" },
2154 { 0x6514, "GD packet number exists twice on the module" },
2155 { 0x6515, "Inconsistent length specifications in GD configuration information" },
2156 { 0x6521, "No memory submodule and no internal memory available" },
2157 { 0x6522, "Illegal memory submodule: replace submodule and reset memory" },
2158 { 0x6523, "Memory reset request due to error accessing submodule" },
2159 { 0x6524, "Memory reset request due to error in block header" },
2160 { 0x6526, "Memory reset request due to memory replacement" },
2161 { 0x6527, "Memory replaced, therefore restart not possible" },
2162 { 0x6528, "Object handling function in the STOP/HOLD mode, no restart possible" },
2163 { 0x6529, "No startup possible during the \"load user program\" function" },
2164 { 0x652A, "No startup because block exists twice in user memory" },
2165 { 0x652B, "No startup because block is too long for submodule - replace submodule" },
2166 { 0x652C, "No startup due to illegal OB on submodule" },
2167 { 0x6532, "No startup because illegal configuration information on submodule" },
2168 { 0x6533, "Memory reset request because of invalid submodule content" },
2169 { 0x6534, "No startup: block exists more than once on submodule" },
2170 { 0x6535, "No startup: not enough memory to transfer block from submodule" },
2171 { 0x6536, "No startup: submodule contains an illegal block number" },
2172 { 0x6537, "No startup: submodule contains a block with an illegal length" },
2173 { 0x6538, "Local data or write-protection ID (for DB) of a block illegal for CPU" },
2174 { 0x6539, "Illegal command in block (detected by compiler)" },
2175 { 0x653A, "Memory reset request because local OB data on submodule too short" },
2176 { 0x6543, "No startup: illegal block type" },
2177 { 0x6544, "No startup: attribute \"relevant for processing\" illegal" },
2178 { 0x6545, "Source language illegal" },
2179 { 0x6546, "Maximum amount of configuration information reached" },
2180 { 0x6547, "Parameter assignment error assigning parameters to modules (not on P bus, cancel download)" },
2181 { 0x6548, "Plausibility error during block check" },
2182 { 0x6549, "Structure error in block" },
2183 { 0x6550, "A block has an error in the CRC" },
2184 { 0x6551, "A block has no CRC" },
2185 { 0x6560, "SCAN overflow" },
2186 { 0x6805, "Resource problem on configured connections, eliminated" },
2187 { 0x6881, "Interface error leaving state" },
2188 { 0x6905, "Resource problem on configured connections" },
2189 { 0x6981, "Interface error entering state" },
2190 { 0x72A2, "Failure of a DP master or a DP master system" },
2191 { 0x72A3, "Redundancy restored on the DP slave" },
2192 { 0x72DB, "Safety program: safety mode disabled" },
2193 { 0x72E0, "Loss of redundancy in communication, problem eliminated" },
2194 { 0x7301, "Loss of redundancy (1 of 2) due to failure of a CPU" },
2195 { 0x7302, "Loss of redundancy (1 of 2) due to STOP on the standby triggered by user" },
2196 { 0x7303, "H system (1 of 2) changed to redundant mode" },
2197 { 0x7323, "Discrepancy found in operating system data" },
2198 { 0x7331, "Standby-master switchover due to master failure" },
2199 { 0x7333, "Standby-master switchover due to system modification during runtime" },
2200 { 0x7334, "Standby-master switchover due to communication error at the synchronization module" },
2201 { 0x7340, "Synchronization error in user program due to elapsed wait time" },
2202 { 0x7341, "Synchronization error in user program due to waiting at different synchronization points" },
2203 { 0x7342, "Synchronization error in operating system due to waiting at different synchronization points" },
2204 { 0x7343, "Synchronization error in operating system due to elapsed wait time" },
2205 { 0x7344, "Synchronization error in operating system due to incorrect data" },
2206 { 0x734A, "The \"Re-enable\" job triggered by SFC 90 \"H_CTRL\" was executed" },
2207 { 0x73A3, "Loss of redundancy on the DP slave" },
2208 { 0x73C1, "Update process canceled" },
2209 { 0x73C2, "Updating aborted due to monitoring time being exceeded during the n-th attempt (1 = n = max. possible number of update attempts after abort due to excessive monitoring time)" },
2210 { 0x73D8, "Safety mode disabled" },
2211 { 0x73DB, "Safety program: safety mode enabled" },
2212 { 0x73E0, "Loss of redundancy in communication" },
2213 { 0x74DD, "Safety program: Shutdown of a fail-save runtime group disabled" },
2214 { 0x74DE, "Safety program: Shutdown of the F program disabled" },
2215 { 0x74DF, "Start of F program initialization" },
2216 { 0x7520, "Error in RAM comparison" },
2217 { 0x7521, "Error in comparison of process image output value" },
2218 { 0x7522, "Error in comparison of memory bits, timers, or counters" },
2219 { 0x75D1, "Safety program: Internal CPU error" },
2220 { 0x75D2, "Safety program error: Cycle time time-out" },
2221 { 0x75D6, "Data corrupted in safety program prior to the output to F I/O" },
2222 { 0x75D7, "Data corrupted in safety program prior to the output to partner F-CPU" },
2223 { 0x75D9, "Invalid REAL number in a DB" },
2224 { 0x75DA, "Safety program: Error in safety data format" },
2225 { 0x75DC, "Runtime group, internal protocol error" },
2226 { 0x75DD, "Safety program: Shutdown of a fail-save runtime group enabled" },
2227 { 0x75DE, "Safety program: Shutdown of the F program enabled" },
2228 { 0x75DF, "End of F program initialization" },
2229 { 0x75E1, "Safety program: Error in FB \"F_PLK\" or \"F_PLK_O\" or \"F_CYC_CO\" or \"F_TEST\" or \"F_TESTC\"" },
2230 { 0x75E2, "Safety program: Area length error" },
2231 { 0x7852, "SYNC module inserted" },
2232 { 0x7855, "SYNC module eliminated" },
2233 { 0x78D3, "Communication error between PROFIsafe and F I/O" },
2234 { 0x78D4, "Error in safety relevant communication between F CPUs" },
2235 { 0x78D5, "Error in safety relevant communication between F CPUs" },
2236 { 0x78E3, "F-I/O device input channel depassivated" },
2237 { 0x78E4, "F-I/O device output channel depassivated" },
2238 { 0x78E5, "F-I/O device depassivated" },
2239 { 0x7934, "Standby-master switchover due to connection problem at the SYNC module" },
2240 { 0x7950, "Synchronization module missing" },
2241 { 0x7951, "Change at the SYNC module without Power On" },
2242 { 0x7952, "SYNC module removed" },
2243 { 0x7953, "Change at the SYNC-module without reset" },
2244 { 0x7954, "SYNC module: rack number assigned twice" },
2245 { 0x7955, "SYNC module error" },
2246 { 0x7956, "Illegal rack number set on SYNC module" },
2247 { 0x7960, "Redundant I/O: Time-out of discrepancy time at digital input, error is not yet localized" },
2248 { 0x7961, "Redundant I/O, digital input error: Signal change after expiration of the discrepancy time" },
2249 { 0x7962, "Redundant I/O: Digital input error" },
2250 { 0x796F, "Redundant I/O: The I/O was globally disabled" },
2251 { 0x7970, "Redundant I/O: Digital output error" },
2252 { 0x7980, "Redundant I/O: Time-out of discrepancy time at analog input" },
2253 { 0x7981, "Redundant I/O: Analog input error" },
2254 { 0x7990, "Redundant I/O: Analog output error" },
2255 { 0x79D3, "Communication error between PROFIsafe and F I/O" },
2256 { 0x79D4, "Error in safety relevant communication between F CPUs" },
2257 { 0x79D5, "Error in safety relevant communication between F CPUs" },
2258 { 0x79E3, "F-I/O device input channel passivated" },
2259 { 0x79E4, "F-I/O device output channel passivated" },
2260 { 0x79E5, "F-I/O device passivated" },
2261 { 0x79E6, "Inconsistent safety program" },
2262 { 0x79E7, "Simulation block (F system block) loaded" },
2265 static value_string_ext cpu_diag_eventid_fix_names_ext
= VALUE_STRING_EXT_INIT(cpu_diag_eventid_fix_names
);
2267 static const value_string cpu_diag_eventid_0x8_0x9_names
[] = {
2268 { 0x8000, "Module fault/OK" },
2269 { 0x8001, "Internal error" },
2270 { 0x8002, "External error" },
2271 { 0x8003, "Channel error" },
2272 { 0x8004, "No external auxiliary voltage" },
2273 { 0x8005, "No front connector" },
2274 { 0x8006, "No parameter assignment" },
2275 { 0x8007, "Incorrect parameters in module" },
2276 { 0x8030, "User submodule incorrect/not found" },
2277 { 0x8031, "Communication problem" },
2278 { 0x8032, "Operating mode: RUN/STOP (STOP: entering state, RUN: leaving state)" },
2279 { 0x8033, "Time monitoring responded (watchdog)" },
2280 { 0x8034, "Internal module power failure" },
2281 { 0x8035, "BATTF: battery exhausted" },
2282 { 0x8036, "Total backup failed" },
2283 { 0x8040, "Expansion rack failed" },
2284 { 0x8041, "Processor failure" },
2285 { 0x8042, "EPROM error" },
2286 { 0x8043, "RAM error" },
2287 { 0x8044, "ADC/DAC error" },
2288 { 0x8045, "Fuse blown" },
2289 { 0x8046, "Hardware interrupt lost Any" },
2290 { 0x8050, "Configuration/parameter assignment error" },
2291 { 0x8051, "Common mode error" },
2292 { 0x8052, "Short circuit to phase" },
2293 { 0x8053, "Short circuit to ground" },
2294 { 0x8054, "Wire break" },
2295 { 0x8055, "Reference channel error" },
2296 { 0x8056, "Below measuring range" },
2297 { 0x8057, "Above measuring range Analog input" },
2298 { 0x8060, "Configuration/parameter assignment error" },
2299 { 0x8061, "Common mode error" },
2300 { 0x8062, "Short circuit to phase" },
2301 { 0x8063, "Short circuit to ground" },
2302 { 0x8064, "Wire break" },
2303 { 0x8066, "No load voltage" },
2304 { 0x8070, "Configuration/parameter assignment error" },
2305 { 0x8071, "Chassis ground fault" },
2306 { 0x8072, "Short circuit to phase (sensor)" },
2307 { 0x8073, "Short circuit to ground (sensor)" },
2308 { 0x8074, "Wire break" },
2309 { 0x8075, "No sensor power supply Digital input" },
2310 { 0x8080, "Configuration/parameter assignment error" },
2311 { 0x8081, "Chassis ground fault" },
2312 { 0x8082, "Short circuit to phase" },
2313 { 0x8083, "Short circuit to ground" },
2314 { 0x8084, "Wire break" },
2315 { 0x8085, "Fuse tripped" },
2316 { 0x8086, "No load voltage" },
2317 { 0x8087, "Excess temperature Digital output" },
2318 { 0x80B0, "Counter module, signal A faulty" },
2319 { 0x80B1, "Counter module, signal B faulty" },
2320 { 0x80B2, "Counter module, signal N faulty" },
2321 { 0x80B3, "Counter module, incorrect value passed between the channels" },
2322 { 0x80B4, "Counter module, 5.2 V sensor supply faulty" },
2323 { 0x80B5, "Counter module, 24 V sensor supply faulty" },
2324 { 0x9001, "Automatic/Manual mode (coming=man,going=auto)" },
2325 { 0x9002, "OPEN/CLOSED, ON/OFF" },
2326 { 0x9003, "Manual command enable" },
2327 { 0x9004, "Unit protective command (OPEN/CLOSED)" },
2328 { 0x9005, "Process enable" },
2329 { 0x9006, "System protection command" },
2330 { 0x9007, "Process value monitoring responded" },
2331 { 0x9008, "Manipulated variable monitoring responded" },
2332 { 0x9009, "System deviation greater than permitted" },
2333 { 0x900A, "Limit position error" },
2334 { 0x900B, "Runtime error" },
2335 { 0x900C, "Command execution error (sequencer)" },
2336 { 0x900D, "Operating status running > OPEN" },
2337 { 0x900E, "Operating status running > CLOSED" },
2338 { 0x900F, "Command blocking" },
2339 { 0x9011, "Process status OPEN/ON" },
2340 { 0x9012, "Process status CLOSED/OFF" },
2341 { 0x9013, "Process status intermediate position" },
2342 { 0x9014, "Process status ON via AUTO" },
2343 { 0x9015, "Process status ON via manual" },
2344 { 0x9016, "Process status ON via protective command" },
2345 { 0x9017, "Process status OFF via AUTO" },
2346 { 0x9018, "Process status OFF via manual" },
2347 { 0x9019, "Process status OFF via protective command" },
2348 { 0x9021, "Function error on approach" },
2349 { 0x9022, "Function error on leaving" },
2350 { 0x9031, "Actuator (DE/WE) limit position OPEN" },
2351 { 0x9032, "Actuator (DE/WE) limit position not OPEN" },
2352 { 0x9033, "Actuator (DE/WE) limit position CLOSED" },
2353 { 0x9034, "Actuator (DE/WE) limit position not CLOSED" },
2354 { 0x9041, "Illegal status, tolerance time elapsed" },
2355 { 0x9042, "Illegal status, tolerance time not elapsed" },
2356 { 0x9043, "Interlock error, tolerance time = 0" },
2357 { 0x9044, "Interlock error, tolerance time > 0" },
2358 { 0x9045, "No reaction" },
2359 { 0x9046, "Final status exited illegally, tolerance time = 0" },
2360 { 0x9047, "Final status exited illegally, tolerance time > 0" },
2361 { 0x9050, "Upper limit of signal range USR" },
2362 { 0x9051, "Upper limit of measuring range UMR" },
2363 { 0x9052, "Lower limit of signal range LSR" },
2364 { 0x9053, "Lower limit of measuring range LMR" },
2365 { 0x9054, "Upper alarm limit UAL" },
2366 { 0x9055, "Upper warning limit UWL" },
2367 { 0x9056, "Upper tolerance limit UTL" },
2368 { 0x9057, "Lower tolerance limit LTL" },
2369 { 0x9058, "Lower warning limit LWL" },
2370 { 0x9059, "Lower alarm limit LAL" },
2371 { 0x9060, "GRAPH7 step entering/leaving" },
2372 { 0x9061, "GRAPH7 interlock error" },
2373 { 0x9062, "GRAPH7 execution error" },
2374 { 0x9063, "GRAPH7 error noted" },
2375 { 0x9064, "GRAPH7 error acknowledged" },
2376 { 0x9070, "Trend exceeded in positive direction" },
2377 { 0x9071, "Trend exceeded in negative direction" },
2378 { 0x9072, "No reaction" },
2379 { 0x9073, "Final state exited illegally" },
2380 { 0x9080, "Limit value exceeded, tolerance time = 0" },
2381 { 0x9081, "Limit value exceeded, tolerance time > 0" },
2382 { 0x9082, "Below limit value, tolerance time = 0" },
2383 { 0x9083, "Below limit value, tolerance time > 0" },
2384 { 0x9084, "Gradient exceeded, tolerance time = 0" },
2385 { 0x9085, "Gradient exceeded, tolerance time > 0" },
2386 { 0x9086, "Below gradient, tolerance time = 0" },
2387 { 0x9087, "Below gradient, tolerance time > 0" },
2388 { 0x9090, "User parameter assignment error entering/leaving" },
2389 { 0x90F0, "Overflow" },
2390 { 0x90F1, "Underflow" },
2391 { 0x90F2, "Division by 0" },
2392 { 0x90F3, "Illegal calculation operation" },
2395 static value_string_ext cpu_diag_eventid_0x8_0x9_names_ext
= VALUE_STRING_EXT_INIT(cpu_diag_eventid_0x8_0x9_names
);
2397 /**************************************************************************
2398 * Type of alarmquery in alarm query request
2400 #define S7COMM_ALARM_MESSAGE_QUERYTYPE_BYALARMTYPE 1
2401 #define S7COMM_ALARM_MESSAGE_QUERYTYPE_BYEVENTID 3
2403 static const value_string alarm_message_querytype_names
[] = {
2404 { S7COMM_ALARM_MESSAGE_QUERYTYPE_BYALARMTYPE
, "ByAlarmtype" },
2405 { S7COMM_ALARM_MESSAGE_QUERYTYPE_BYEVENTID
, "ByEventID" },
2409 /**************************************************************************
2410 * Alarmtype in alarm query
2412 #define S7COMM_ALARM_MESSAGE_QUERY_ALARMTYPE_SCAN 1
2413 #define S7COMM_ALARM_MESSAGE_QUERY_ALARMTYPE_ALARM_8 2
2414 #define S7COMM_ALARM_MESSAGE_QUERY_ALARMTYPE_ALARM_S 4
2416 static const value_string alarm_message_query_alarmtype_names
[] = {
2417 { S7COMM_ALARM_MESSAGE_QUERY_ALARMTYPE_SCAN
, "SCAN" },
2418 { S7COMM_ALARM_MESSAGE_QUERY_ALARMTYPE_ALARM_8
, "ALARM_8" },
2419 { S7COMM_ALARM_MESSAGE_QUERY_ALARMTYPE_ALARM_S
, "ALARM_S" },
2423 /* CPU message service */
2424 static int hf_s7comm_cpu_msgservice_subscribe_events
;
2425 static int hf_s7comm_cpu_msgservice_subscribe_events_modetrans
;
2426 static int hf_s7comm_cpu_msgservice_subscribe_events_system
;
2427 static int hf_s7comm_cpu_msgservice_subscribe_events_userdefined
;
2428 static int hf_s7comm_cpu_msgservice_subscribe_events_alarms
;
2429 static int ett_s7comm_cpu_msgservice_subscribe_events
;
2430 static int * const s7comm_cpu_msgservice_subscribe_events_fields
[] = {
2431 &hf_s7comm_cpu_msgservice_subscribe_events_modetrans
,
2432 &hf_s7comm_cpu_msgservice_subscribe_events_system
,
2433 &hf_s7comm_cpu_msgservice_subscribe_events_userdefined
,
2434 &hf_s7comm_cpu_msgservice_subscribe_events_alarms
,
2437 static int hf_s7comm_cpu_msgservice_req_reserved1
;
2438 static int hf_s7comm_cpu_msgservice_username
;
2439 static int hf_s7comm_cpu_msgservice_almtype
;
2440 static int hf_s7comm_cpu_msgservice_req_reserved2
;
2441 static int hf_s7comm_cpu_msgservice_res_result
;
2442 static int hf_s7comm_cpu_msgservice_res_reserved1
;
2443 static int hf_s7comm_cpu_msgservice_res_reserved2
;
2444 static int hf_s7comm_cpu_msgservice_res_reserved3
;
2446 #define S7COMM_CPU_MSG_ALMTYPE_SCAN_ABORT 0
2447 #define S7COMM_CPU_MSG_ALMTYPE_SCAN_INITIATE 1
2448 #define S7COMM_CPU_MSG_ALMTYPE_ALARM_ABORT 4
2449 #define S7COMM_CPU_MSG_ALMTYPE_ALARM_INITIATE 5
2450 #define S7COMM_CPU_MSG_ALMTYPE_AR_SEND_ABORT 6
2451 #define S7COMM_CPU_MSG_ALMTYPE_AR_SEND_INITIATE 7
2452 #define S7COMM_CPU_MSG_ALMTYPE_ALARM_S_ABORT 8
2453 #define S7COMM_CPU_MSG_ALMTYPE_ALARM_S_INITIATE 9
2455 static const value_string cpu_msgservice_almtype_names
[] = {
2456 { S7COMM_CPU_MSG_ALMTYPE_SCAN_ABORT
, "SCAN_ABORT" },
2457 { S7COMM_CPU_MSG_ALMTYPE_SCAN_INITIATE
, "SCAN_INITIATE" },
2458 { S7COMM_CPU_MSG_ALMTYPE_ALARM_ABORT
, "ALARM_ABORT" },
2459 { S7COMM_CPU_MSG_ALMTYPE_ALARM_INITIATE
, "ALARM_INITIATE" },
2460 { S7COMM_CPU_MSG_ALMTYPE_AR_SEND_ABORT
, "AR_SEND_ABORT" },
2461 { S7COMM_CPU_MSG_ALMTYPE_AR_SEND_INITIATE
, "AR_SEND_INITIATE" },
2462 { S7COMM_CPU_MSG_ALMTYPE_ALARM_S_ABORT
, "ALARM_S_ABORT" },
2463 { S7COMM_CPU_MSG_ALMTYPE_ALARM_S_INITIATE
, "ALARM_S_INITIATE" },
2467 static int hf_s7comm_modetrans_param_unknown1
;
2468 static int hf_s7comm_modetrans_param_mode
;
2469 static const value_string modetrans_param_mode_names
[] = {
2471 { 1, "Warm Restart" },
2473 { 3, "Hot Restart" },
2475 { 6, "Cold Restart" },
2476 { 9, "RUN_R (H-System redundant)" },
2481 static int hf_s7comm_modetrans_param_unknown2
;
2483 /* These fields used when reassembling S7COMM fragments */
2484 static int hf_s7comm_fragments
;
2485 static int hf_s7comm_fragment
;
2486 static int hf_s7comm_fragment_overlap
;
2487 static int hf_s7comm_fragment_overlap_conflict
;
2488 static int hf_s7comm_fragment_multiple_tails
;
2489 static int hf_s7comm_fragment_too_long_fragment
;
2490 static int hf_s7comm_fragment_error
;
2491 static int hf_s7comm_fragment_count
;
2492 static int hf_s7comm_reassembled_in
;
2493 static int hf_s7comm_reassembled_length
;
2494 static int ett_s7comm_fragment
;
2495 static int ett_s7comm_fragments
;
2497 static const fragment_items s7comm_frag_items
= {
2498 /* Fragment subtrees */
2499 &ett_s7comm_fragment
,
2500 &ett_s7comm_fragments
,
2501 /* Fragment fields */
2502 &hf_s7comm_fragments
,
2503 &hf_s7comm_fragment
,
2504 &hf_s7comm_fragment_overlap
,
2505 &hf_s7comm_fragment_overlap_conflict
,
2506 &hf_s7comm_fragment_multiple_tails
,
2507 &hf_s7comm_fragment_too_long_fragment
,
2508 &hf_s7comm_fragment_error
,
2509 &hf_s7comm_fragment_count
,
2510 /* Reassembled in field */
2511 &hf_s7comm_reassembled_in
,
2512 /* Reassembled length field */
2513 &hf_s7comm_reassembled_length
,
2514 /* Reassembled data field */
2520 static reassembly_table s7comm_reassembly_table
;
2522 /* These are the ids of the subtrees that we are creating */
2523 static int ett_s7comm
; /* S7 communication tree, parent of all other subtree */
2524 static int ett_s7comm_header
; /* Subtree for header block */
2525 static int ett_s7comm_param
; /* Subtree for parameter block */
2526 static int ett_s7comm_param_item
; /* Subtree for items in parameter block */
2527 static int ett_s7comm_param_subitem
; /* Subtree for subitems under items in parameter block */
2528 static int ett_s7comm_data
; /* Subtree for data block */
2529 static int ett_s7comm_data_item
; /* Subtree for an item in data block */
2530 static int ett_s7comm_item_address
; /* Subtree for an address (byte/bit) */
2531 static int ett_s7comm_cpu_alarm_message
; /* Subtree for an alarm message */
2532 static int ett_s7comm_cpu_alarm_message_object
; /* Subtree for an alarm message block*/
2533 static int ett_s7comm_cpu_alarm_message_timestamp
; /* Subtree for an alarm message timestamp */
2534 static int ett_s7comm_cpu_alarm_message_associated_value
; /* Subtree for an alarm message associated value */
2535 static int ett_s7comm_cpu_diag_msg
; /* Subtree for a CPU diagnostic message */
2536 static int ett_s7comm_prog_parameter
;
2537 static int ett_s7comm_prog_data
;
2539 static const char mon_names
[][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
2541 /*******************************************************************************************************
2543 * Converts a siemens special timestamp to a string of 25+1 bytes length (e.g. "Apr 15, 2009 12:49:30.520").
2544 * The timestamp is 6 bytes long, one word is the number of days since 1.1.1984, and 4 bytes milliseconds of the day
2546 *******************************************************************************************************/
2548 s7comm_get_timestring_from_s7time(tvbuff_t
*tvb
, unsigned offset
, char *str
, int max
)
2555 day_msec
= tvb_get_ntohl(tvb
, offset
);
2556 days
= tvb_get_ntohs(tvb
, offset
+ 4);
2558 t
= 441763200L; /* 1.1.1984 00:00:00 */
2559 t
+= (uint32_t)days
* (24*60*60);
2560 t
+= day_msec
/ 1000;
2564 snprintf(str
, max
, "%s %2d, %d %02d:%02d:%02d.%03d", mon_names
[mt
->tm_mon
], mt
->tm_mday
,
2565 mt
->tm_year
+ 1900, mt
->tm_hour
, mt
->tm_min
, mt
->tm_sec
, day_msec
% 1000);
2569 /*******************************************************************************************************
2571 * Helper for time functions
2574 *******************************************************************************************************/
2576 s7comm_uint8_from_bcd(uint8_t i
)
2578 return 10 * (i
/16) + (i
% 16);
2581 /*******************************************************************************************************
2583 * Helper for time functions
2584 * Add a BCD coded timestamp (10/8 Bytes length) to tree
2586 *******************************************************************************************************/
2588 s7comm_add_timestamp_to_tree(tvbuff_t
*tvb
,
2592 bool has_ten_bytes
) /* if this is false the [0] reserved and [1] year bytes are missing */
2594 uint8_t timestamp
[10];
2600 proto_item
*item
= NULL
;
2601 proto_item
*time_tree
= NULL
;
2603 int timestamp_size
= 10;
2605 if (has_ten_bytes
) {
2606 /* The low nibble of byte 10 is weekday, the high nibble the LSD of msec */
2607 for (i
= 0; i
< 9; i
++) {
2608 timestamp
[i
] = s7comm_uint8_from_bcd(tvb_get_uint8(tvb
, offset
+ i
));
2610 tmp
= tvb_get_uint8(tvb
, offset
+ 9) >> 4;
2612 /* this is a 8 byte timestamp, where the reserved and the year byte is missing */
2615 timestamp
[1] = 19; /* start with 19.., will be corrected later */
2616 for (i
= 0; i
< 7; i
++) {
2617 timestamp
[i
+ 2] = s7comm_uint8_from_bcd(tvb_get_uint8(tvb
, offset
+ i
));
2619 tmp
= tvb_get_uint8(tvb
, offset
+ 7) >> 4;
2621 timestamp
[9] = s7comm_uint8_from_bcd(tmp
);
2623 msec
= (uint16_t)timestamp
[8] * 10 + (uint16_t)timestamp
[9];
2624 year_org
= timestamp
[1];
2625 /* year special: ignore the first byte, since some cpus give 1914 for 2014
2626 * if second byte is below 89, it's 2000..2089, if over 90 it's 1990..1999
2628 if (timestamp
[2] < 89) {
2631 /* convert time to nstime_t */
2632 mt
.tm_year
= (timestamp
[1] * 100 + timestamp
[2]) - 1900;
2633 mt
.tm_mon
= timestamp
[3] - 1;
2634 mt
.tm_mday
= timestamp
[4];
2635 mt
.tm_hour
= timestamp
[5];
2636 mt
.tm_min
= timestamp
[6];
2637 mt
.tm_sec
= timestamp
[7];
2639 tv
.secs
= mktime(&mt
);
2640 tv
.nsecs
= msec
* 1000000;
2641 if (mt
.tm_mon
>= 0 && mt
.tm_mon
<= 11) {
2642 item
= proto_tree_add_time_format(tree
, hf_s7comm_data_ts
, tvb
, offset
, timestamp_size
, &tv
,
2643 "S7 Timestamp: %s %2d, %d %02d:%02d:%02d.%03d", mon_names
[mt
.tm_mon
], mt
.tm_mday
,
2644 mt
.tm_year
+ 1900, mt
.tm_hour
, mt
.tm_min
, mt
.tm_sec
,
2646 time_tree
= proto_item_add_subtree(item
, ett_s7comm_data_item
);
2648 /* timefunction: s7 timestamp */
2649 if (has_ten_bytes
) {
2650 proto_tree_add_uint(time_tree
, hf_s7comm_data_ts_reserved
, tvb
, offset
, 1, timestamp
[0]);
2652 proto_tree_add_uint(time_tree
, hf_s7comm_data_ts_year1
, tvb
, offset
, 1, year_org
);
2655 proto_tree_add_uint(time_tree
, hf_s7comm_data_ts_year2
, tvb
, offset
, 1, timestamp
[2]);
2657 proto_tree_add_uint(time_tree
, hf_s7comm_data_ts_month
, tvb
, offset
, 1, timestamp
[3]);
2659 proto_tree_add_uint(time_tree
, hf_s7comm_data_ts_day
, tvb
, offset
, 1, timestamp
[4]);
2661 proto_tree_add_uint(time_tree
, hf_s7comm_data_ts_hour
, tvb
, offset
, 1, timestamp
[5]);
2663 proto_tree_add_uint(time_tree
, hf_s7comm_data_ts_minute
, tvb
, offset
, 1, timestamp
[6]);
2665 proto_tree_add_uint(time_tree
, hf_s7comm_data_ts_second
, tvb
, offset
, 1, timestamp
[7]);
2667 proto_tree_add_uint(time_tree
, hf_s7comm_data_ts_millisecond
, tvb
, offset
, 2, msec
);
2668 proto_tree_add_item(time_tree
, hf_s7comm_data_ts_weekday
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2671 if (append_text
== true) {
2672 proto_item_append_text(tree
, "(Timestamp: %s %2d, %d %02d:%02d:%02d.%03d)", mon_names
[mt
.tm_mon
], mt
.tm_mday
,
2673 mt
.tm_year
+ 1900, mt
.tm_hour
, mt
.tm_min
, mt
.tm_sec
,
2677 /* If the timestamp is invalid, continue as best as we can */
2678 if (has_ten_bytes
) {
2688 /*******************************************************************************************************
2690 * Generate a comma separated string for registerflags
2692 *******************************************************************************************************/
2694 make_registerflag_string(char *str
, uint8_t flags
, int max
)
2696 (void) g_strlcpy(str
, "", max
);
2697 if (flags
& 0x01) (void) g_strlcat(str
, "STW, ", max
);
2698 if (flags
& 0x02) (void) g_strlcat(str
, "ACCU1, ", max
);
2699 if (flags
& 0x04) (void) g_strlcat(str
, "ACCU2, ", max
);
2700 if (flags
& 0x08) (void) g_strlcat(str
, "AR1, ", max
);
2701 if (flags
& 0x10) (void) g_strlcat(str
, "AR2, ", max
);
2702 if (flags
& 0x20) (void) g_strlcat(str
, "DB1, ", max
);
2703 if (flags
& 0x40) (void) g_strlcat(str
, "DB2, ", max
);
2704 if (strlen(str
) > 2)
2705 str
[strlen(str
) - 2 ] = '\0';
2708 /*******************************************************************************************************
2710 * Addressdefinition for Syntax ID S7-ANY (Step 7 Classic 300/400 or 1200/1500 not optimized)
2711 * type == 0x12, length == 10, syntax-ID == 0x10
2713 *******************************************************************************************************/
2715 s7comm_syntaxid_s7any(tvbuff_t
*tvb
,
2719 uint32_t t_size
= 0;
2723 uint32_t a_address
= 0;
2724 uint32_t bytepos
= 0;
2725 uint32_t bitpos
= 0;
2726 proto_item
*address_item
= NULL
;
2727 proto_tree
*address_item_tree
= NULL
;
2729 /* Transport size, 1 byte */
2730 proto_tree_add_item_ret_uint(tree
, hf_s7comm_item_transport_size
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &t_size
);
2732 /* Special handling of data record */
2733 area
= tvb_get_uint8(tvb
, offset
+ 4); /* peek area first */
2734 if (area
== S7COMM_AREA_DATARECORD
) {
2736 proto_tree_add_item_ret_uint(tree
, hf_s7comm_rdrec_mlen
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &len
);
2738 /* INDEX, 2 bytes */
2739 proto_tree_add_item_ret_uint(tree
, hf_s7comm_rdrec_index
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &db
);
2742 proto_tree_add_uint(tree
, hf_s7comm_item_area
, tvb
, offset
, 1, area
);
2745 proto_tree_add_item_ret_uint(tree
, hf_s7comm_rdrec_id
, tvb
, offset
, 3, ENC_BIG_ENDIAN
, &a_address
);
2747 proto_item_append_text(tree
, " (RECORD MLEN=%d INDEX=0x%04x ID=%d)", len
, db
, a_address
);
2749 /* Length, 2 bytes */
2750 proto_tree_add_item_ret_uint(tree
, hf_s7comm_item_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &len
);
2752 /* DB number, 2 bytes */
2753 proto_tree_add_item_ret_uint(tree
, hf_s7comm_item_db
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &db
);
2756 proto_tree_add_uint(tree
, hf_s7comm_item_area
, tvb
, offset
, 1, area
);
2758 /* Address, 3 bytes */
2759 address_item
= proto_tree_add_item_ret_uint(tree
, hf_s7comm_item_address
, tvb
, offset
, 3, ENC_BIG_ENDIAN
, &a_address
);
2760 address_item_tree
= proto_item_add_subtree(address_item
, ett_s7comm_item_address
);
2761 bytepos
= a_address
/ 8;
2762 bitpos
= a_address
% 8;
2763 /* build a full address to show item data directly beside the item */
2764 proto_item_append_text(tree
, " (%s", val_to_str(area
, item_areanames_short
, "unknown area 0x%02x"));
2765 if (area
== S7COMM_AREA_TIMER
|| area
== S7COMM_AREA_COUNTER
) {
2766 proto_item_append_text(tree
, " %d)", a_address
);
2767 proto_tree_add_uint(address_item_tree
, hf_s7comm_item_address_nr
, tvb
, offset
, 3, a_address
);
2769 proto_tree_add_uint(address_item_tree
, hf_s7comm_item_address_byte
, tvb
, offset
, 3, a_address
);
2770 proto_tree_add_uint(address_item_tree
, hf_s7comm_item_address_bit
, tvb
, offset
, 3, a_address
);
2771 if (area
== S7COMM_AREA_DB
) {
2772 proto_item_append_text(tree
, " %d.DBX", db
);
2773 } else if (area
== S7COMM_AREA_DI
) {
2774 proto_item_append_text(tree
, " %d.DIX", db
);
2776 proto_item_append_text(tree
, " %d.%d %s %d)",
2777 bytepos
, bitpos
, val_to_str(t_size
, item_transportsizenames
, "Unknown transport size: 0x%02x"), len
);
2783 /*******************************************************************************************************
2785 * Addressdefinition to read a DB area (S7-400 special)
2786 * type == 0x12, length >= 7, syntax-ID == 0xb0
2788 *******************************************************************************************************/
2790 s7comm_syntaxid_dbread(tvbuff_t
*tvb
,
2794 uint32_t number_of_areas
= 0;
2797 uint32_t bytepos
= 0;
2799 proto_item
*sub_item
= NULL
;
2800 proto_tree
*sub_item_tree
= NULL
;
2802 proto_tree_add_item_ret_uint(tree
, hf_s7comm_item_dbread_numareas
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &number_of_areas
);
2803 proto_item_append_text(tree
, " (%d Data-Areas of Syntax-Id DBREAD)", number_of_areas
);
2805 for (i
= 0; i
< number_of_areas
; i
++) {
2806 sub_item
= proto_tree_add_item(tree
, hf_s7comm_param_subitem
, tvb
, offset
, 5, ENC_NA
);
2807 sub_item_tree
= proto_item_add_subtree(sub_item
, ett_s7comm_param_subitem
);
2808 proto_tree_add_item_ret_uint(sub_item_tree
, hf_s7comm_item_dbread_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &len
);
2810 proto_tree_add_item_ret_uint(sub_item_tree
, hf_s7comm_item_dbread_db
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &db
);
2812 proto_tree_add_item_ret_uint(sub_item_tree
, hf_s7comm_item_dbread_startadr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &bytepos
);
2814 /* Display in pseudo S7-Any Format */
2815 proto_item_append_text(sub_item
, " [%d]: (DB%d.DBB %d BYTE %d)", i
+1, db
, bytepos
, len
);
2820 /*******************************************************************************************************
2822 * Addressdefinition for TIA S7 1200 symbolic address mode
2823 * type == 0x12, length >= 14, syntax-ID == 0xb2
2825 *******************************************************************************************************/
2827 s7comm_syntaxid_1200sym(tvbuff_t
*tvb
,
2830 uint8_t varspec_length
)
2832 uint32_t tia_var_area1
= 0;
2833 uint32_t tia_var_area2
= 0;
2834 uint8_t tia_lid_flags
= 0;
2835 uint32_t tia_value
= 0;
2837 proto_item
*sub_item
= NULL
;
2838 proto_tree
*sub_item_tree
= NULL
;
2840 proto_item_append_text(tree
, " 1200 symbolic address");
2841 /* first byte in address seems always to be 0xff */
2842 proto_tree_add_item(tree
, hf_s7comm_tia1200_item_reserved1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2844 /* When Bytes 2/3 == 0, then Bytes 4/5 defines the area as known from classic 300/400 address mode.
2845 * When Bytes 2/3 == 0x8a0e then Bytes 4/5 are containing the DB number.
2847 proto_tree_add_item_ret_uint(tree
, hf_s7comm_tia1200_item_area1
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &tia_var_area1
);
2849 tia_var_area2
= tvb_get_ntohs(tvb
, offset
);
2850 if (tia_var_area1
== S7COMM_TIA1200_VAR_ITEM_AREA1_IQMCT
) {
2851 proto_tree_add_uint(tree
, hf_s7comm_tia1200_item_area2
, tvb
, offset
, 2, tia_var_area2
);
2852 proto_item_append_text(tree
, " - Accessing %s", val_to_str(tia_var_area2
, tia1200_var_item_area2_names
, "Unknown IQMCT Area: 0x%04x"));
2854 } else if (tia_var_area1
== S7COMM_TIA1200_VAR_ITEM_AREA1_DB
) {
2855 proto_tree_add_uint(tree
, hf_s7comm_tia1200_item_dbnumber
, tvb
, offset
, 2, tia_var_area2
);
2856 proto_item_append_text(tree
, " - Accessing DB%d", tia_var_area2
);
2859 /* for current unknown areas */
2860 proto_tree_add_uint(tree
, hf_s7comm_tia1200_item_area2unknown
, tvb
, offset
, 2, tia_var_area2
);
2861 proto_item_append_text(tree
, " - Unknown area specification");
2864 proto_tree_add_item(tree
, hf_s7comm_tia1200_item_crc
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2867 for (i
= 0; i
< (varspec_length
- 10) / 4; i
++) {
2868 sub_item
= proto_tree_add_item(tree
, hf_s7comm_tia1200_substructure_item
, tvb
, offset
, 4, ENC_NA
);
2869 sub_item_tree
= proto_item_add_subtree(sub_item
, ett_s7comm_param_subitem
);
2870 tia_lid_flags
= tvb_get_uint8(tvb
, offset
) >> 4;
2871 proto_tree_add_item(sub_item_tree
, hf_s7comm_tia1200_var_lid_flags
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2872 tia_value
= tvb_get_ntohl(tvb
, offset
) & 0x0fffffff;
2873 proto_item_append_text(sub_item
, " [%d]: %s, Value: %u", i
+ 1,
2874 val_to_str(tia_lid_flags
, tia1200_var_lid_flag_names
, "Unknown flags: 0x%02x"),
2877 proto_tree_add_item(sub_item_tree
, hf_s7comm_tia1200_item_value
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2883 /*******************************************************************************************************
2885 * Addressdefinition for Sinumeric NCK access
2886 * type == 0x12, length == 8, syntax-ID == 0x82 or == 0x83 or == 0x84
2888 *******************************************************************************************************/
2890 s7comm_syntaxid_nck(tvbuff_t
*tvb
,
2895 uint32_t nck_area
= 0;
2896 uint32_t nck_unit
= 0;
2897 uint32_t nck_column
= 0;
2898 uint32_t nck_line
= 0;
2899 uint32_t nck_module
= 0;
2901 proto_tree_add_item_ret_uint(tree
, hf_s7comm_item_nck_areaunit
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &area
);
2902 nck_area
= area
>> 5;
2903 nck_unit
= area
& 0x1f;
2904 proto_tree_add_item(tree
, hf_s7comm_item_nck_area
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2905 proto_tree_add_item(tree
, hf_s7comm_item_nck_unit
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2907 proto_tree_add_item_ret_uint(tree
, hf_s7comm_item_nck_column
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &nck_column
);
2909 proto_tree_add_item_ret_uint(tree
, hf_s7comm_item_nck_line
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &nck_line
);
2911 proto_tree_add_item_ret_uint(tree
, hf_s7comm_item_nck_module
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &nck_module
);
2913 proto_tree_add_item(tree
, hf_s7comm_item_nck_linecount
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2915 proto_item_append_text(tree
, " (NCK Area:%d Unit:%d Column:%d Line:%d Module:0x%02x)",
2916 nck_area
, nck_unit
, nck_column
, nck_line
, nck_module
);
2920 /*******************************************************************************************************
2922 * Addressdefinition for accessing Multimaster / Sinamics frequency convertes via routing from DriveES.
2923 * type == 0x12, length == 10, syntax-ID == 0x82
2925 *******************************************************************************************************/
2927 s7comm_syntaxid_driveesany(tvbuff_t
*tvb
,
2934 proto_tree_add_item(tree
, hf_s7comm_item_driveesany_unknown1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2936 proto_tree_add_item(tree
, hf_s7comm_item_driveesany_unknown2
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2938 proto_tree_add_item(tree
, hf_s7comm_item_driveesany_unknown3
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2940 proto_tree_add_item_ret_uint(tree
, hf_s7comm_item_driveesany_parameter_nr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &nr
);
2942 proto_tree_add_item_ret_uint(tree
, hf_s7comm_item_driveesany_parameter_idx
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &idx
);
2944 proto_item_append_text(tree
, " (DriveES Parameter: %d[%d])", nr
, idx
);
2948 /*******************************************************************************************************
2950 * Dissect the parameter details of a read/write request (Items)
2952 *******************************************************************************************************/
2954 s7comm_decode_param_item(tvbuff_t
*tvb
,
2956 proto_tree
*sub_tree
,
2959 proto_item
*item
= NULL
;
2960 proto_tree
*item_tree
= NULL
;
2961 uint8_t var_spec_type
= 0;
2962 uint8_t var_spec_length
= 0;
2963 uint8_t var_spec_syntax_id
= 0;
2965 var_spec_type
= tvb_get_uint8(tvb
, offset
);
2966 var_spec_length
= tvb_get_uint8(tvb
, offset
+ 1);
2967 var_spec_syntax_id
= tvb_get_uint8(tvb
, offset
+ 2);
2969 /* Insert a new tree for every item */
2970 item
= proto_tree_add_item(sub_tree
, hf_s7comm_param_item
, tvb
, offset
, var_spec_length
+ 2, ENC_NA
);
2971 item_tree
= proto_item_add_subtree(item
, ett_s7comm_param_item
);
2972 proto_item_append_text(item
, " [%d]:", item_no
+ 1);
2974 /* Item head, constant 3 bytes */
2975 proto_tree_add_item(item_tree
, hf_s7comm_item_varspec
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2977 proto_tree_add_item(item_tree
, hf_s7comm_item_varspec_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2979 proto_tree_add_item(item_tree
, hf_s7comm_item_syntax_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2982 if (var_spec_type
== 0x12 && var_spec_length
== 10 && var_spec_syntax_id
== S7COMM_SYNTAXID_S7ANY
) {
2983 /* Step 7 Classic 300 400 */
2984 offset
= s7comm_syntaxid_s7any(tvb
, offset
, item_tree
);
2985 } else if (var_spec_type
== 0x12 && var_spec_length
>= 7 && var_spec_syntax_id
== S7COMM_SYNTAXID_DBREAD
) {
2986 /* S7-400 special address mode (kind of cyclic read) */
2987 offset
= s7comm_syntaxid_dbread(tvb
, offset
, item_tree
);
2988 } else if (var_spec_type
== 0x12 && var_spec_length
>= 14 && var_spec_syntax_id
== S7COMM_SYNTAXID_1200SYM
) {
2989 /* TIA S7 1200 symbolic address mode */
2990 offset
= s7comm_syntaxid_1200sym(tvb
, offset
, item_tree
, var_spec_length
);
2991 } else if (var_spec_type
== 0x12 && var_spec_length
== 8
2992 && ((var_spec_syntax_id
== S7COMM_SYNTAXID_NCK
)
2993 || (var_spec_syntax_id
== S7COMM_SYNTAXID_NCK_METRIC
)
2994 || (var_spec_syntax_id
== S7COMM_SYNTAXID_NCK_INCH
))) {
2995 /* Sinumerik NCK access */
2996 offset
= s7comm_syntaxid_nck(tvb
, offset
, item_tree
);
2997 } else if (var_spec_type
== 0x12 && var_spec_length
== 10 && var_spec_syntax_id
== S7COMM_SYNTAXID_DRIVEESANY
) {
2998 /* Accessing frequency inverter parameters (via routing) */
2999 offset
= s7comm_syntaxid_driveesany(tvb
, offset
, item_tree
);
3002 /* var spec, length and syntax id are still added to tree here */
3003 offset
+= var_spec_length
- 1;
3004 proto_item_append_text(item_tree
, " Unknown variable specification");
3009 /*******************************************************************************************************
3011 * Decode parameter part of a PDU for setup communication
3013 *******************************************************************************************************/
3015 s7comm_decode_pdu_setup_communication(tvbuff_t
*tvb
,
3019 proto_tree_add_item(tree
, hf_s7comm_param_setup_reserved1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3021 proto_tree_add_item(tree
, hf_s7comm_param_maxamq_calling
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3023 proto_tree_add_item(tree
, hf_s7comm_param_maxamq_called
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3025 proto_tree_add_item(tree
, hf_s7comm_param_neg_pdu_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3030 /*******************************************************************************************************
3032 * PDU Type: Response -> Function Write -> Data part
3034 *******************************************************************************************************/
3036 s7comm_decode_response_write_data(tvbuff_t
*tvb
,
3041 uint8_t ret_val
= 0;
3043 proto_item
*item
= NULL
;
3044 proto_tree
*item_tree
= NULL
;
3046 for (i
= 0; i
< item_count
; i
++) {
3047 ret_val
= tvb_get_uint8(tvb
, offset
);
3048 /* Insert a new tree for every item */
3049 item
= proto_tree_add_item(tree
, hf_s7comm_data_item
, tvb
, offset
, 1, ENC_NA
);
3050 item_tree
= proto_item_add_subtree(item
, ett_s7comm_data_item
);
3051 proto_item_append_text(item
, " [%d]: (%s)", i
+1, val_to_str(ret_val
, s7comm_item_return_valuenames
, "Unknown code: 0x%02x"));
3052 proto_tree_add_uint(item_tree
, hf_s7comm_data_returncode
, tvb
, offset
, 1, ret_val
);
3058 /*******************************************************************************************************
3060 * PDU Type: Response -> Function Read -> Data part
3061 * Request -> Function Write -> Data part
3063 *******************************************************************************************************/
3065 s7comm_decode_response_read_data(tvbuff_t
*tvb
,
3070 uint8_t ret_val
= 0;
3072 uint16_t len
= 0, len2
= 0;
3073 uint16_t head_len
= 4; /* 1 byte res-code, 1 byte transp-size, 2 bytes len */
3075 proto_item
*item
= NULL
;
3076 proto_tree
*item_tree
= NULL
;
3078 /* Maybe this is only valid for Sinumerik NCK: Pre-check transport-size
3079 * If transport size is 0x11 or 0x12, then an array with requested NCK areas will follow.
3081 tsize
= tvb_get_uint8(tvb
, offset
+ 1);
3082 if (tsize
== S7COMM_DATA_TRANSPORT_SIZE_NCKADDR1
|| tsize
== S7COMM_DATA_TRANSPORT_SIZE_NCKADDR2
) {
3083 proto_tree_add_item(tree
, hf_s7comm_data_returncode
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3084 proto_tree_add_uint(tree
, hf_s7comm_data_transport_size
, tvb
, offset
+ 1, 1, tsize
);
3086 for (i
= 0; i
< item_count
; i
++) {
3087 offset
= s7comm_decode_param_item(tvb
, offset
, tree
, i
);
3091 for (i
= 0; i
< item_count
; i
++) {
3092 ret_val
= tvb_get_uint8(tvb
, offset
);
3093 if (ret_val
== S7COMM_ITEM_RETVAL_RESERVED
||
3094 ret_val
== S7COMM_ITEM_RETVAL_DATA_OK
||
3095 ret_val
== S7COMM_ITEM_RETVAL_DATA_ERR
3097 tsize
= tvb_get_uint8(tvb
, offset
+ 1);
3098 len
= tvb_get_ntohs(tvb
, offset
+ 2);
3099 /* calculate length in bytes */
3100 if (tsize
== S7COMM_DATA_TRANSPORT_SIZE_BBIT
||
3101 tsize
== S7COMM_DATA_TRANSPORT_SIZE_BBYTE
||
3102 tsize
== S7COMM_DATA_TRANSPORT_SIZE_BINT
3103 ) { /* given length is in number of bits */
3104 if (len
% 8) { /* len is not a multiple of 8, then round up to next number */
3112 /* the PLC places extra bytes at the end of all but last result, if length is not a multiple of 2 */
3113 if ((len
% 2) && (i
< (item_count
-1))) {
3119 /* Insert a new tree for every item */
3120 item
= proto_tree_add_item(tree
, hf_s7comm_data_item
, tvb
, offset
, len
+ head_len
, ENC_NA
);
3121 item_tree
= proto_item_add_subtree(item
, ett_s7comm_data_item
);
3122 proto_item_append_text(item
, " [%d]: (%s)", i
+1, val_to_str(ret_val
, s7comm_item_return_valuenames
, "Unknown code: 0x%02x"));
3124 proto_tree_add_uint(item_tree
, hf_s7comm_data_returncode
, tvb
, offset
, 1, ret_val
);
3125 proto_tree_add_uint(item_tree
, hf_s7comm_data_transport_size
, tvb
, offset
+ 1, 1, tsize
);
3126 proto_tree_add_uint(item_tree
, hf_s7comm_data_length
, tvb
, offset
+ 2, 2, len
);
3129 if (ret_val
== S7COMM_ITEM_RETVAL_DATA_OK
|| ret_val
== S7COMM_ITEM_RETVAL_RESERVED
) {
3130 proto_tree_add_item(item_tree
, hf_s7comm_readresponse_data
, tvb
, offset
, len
, ENC_NA
);
3133 proto_tree_add_item(item_tree
, hf_s7comm_data_fillbyte
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3142 /*******************************************************************************************************
3144 * PDU Type: Request or Response -> Function 0x29 (PLC control functions -> STOP)
3146 *******************************************************************************************************/
3148 s7comm_decode_plc_controls_param_hex29(tvbuff_t
*tvb
,
3154 /* The first byte 0x29 is checked and inserted to tree outside, so skip it here */
3156 /* Meaning of first 5 bytes (Part 1) is unknown */
3157 proto_tree_add_item(tree
, hf_s7comm_piservice_unknown1
, tvb
, offset
, 5, ENC_NA
);
3160 len
= tvb_get_uint8(tvb
, offset
);
3161 proto_tree_add_uint(tree
, hf_s7comm_data_plccontrol_part2_len
, tvb
, offset
, 1, len
);
3163 /* Function as string */
3164 proto_tree_add_item(tree
, hf_s7comm_piservice_servicename
, tvb
, offset
, len
, ENC_ASCII
);
3170 /*******************************************************************************************************
3171 * PI_START Parameters: Decodes a parameter array with string values.
3172 *******************************************************************************************************/
3174 s7comm_decode_pistart_parameters(tvbuff_t
*tvb
,
3177 proto_tree
*param_tree
,
3178 const uint8_t *servicename
,
3179 uint8_t nfields
, /* number of fields used */
3180 unsigned hf
[], /* array with header fields */
3185 wmem_strbuf_t
*args_buf
;
3186 args_buf
= wmem_strbuf_create(pinfo
->pool
);
3188 for (i
= 0; i
< nfields
; i
++) {
3189 len
= tvb_get_uint8(tvb
, offset
);
3190 proto_tree_add_uint(param_tree
, hf_s7comm_piservice_string_len
, tvb
, offset
, 1, len
);
3192 proto_tree_add_item(param_tree
, hf
[i
], tvb
, offset
, len
, ENC_ASCII
|ENC_NA
);
3193 wmem_strbuf_append(args_buf
, "\"");
3194 wmem_strbuf_append(args_buf
, tvb_format_text(pinfo
->pool
, tvb
, offset
, len
));
3195 if (i
< nfields
-1) {
3196 wmem_strbuf_append(args_buf
, "\", ");
3198 wmem_strbuf_append(args_buf
, "\"");
3200 offset
+= len
+ (len
% 2 == 0);
3202 proto_item_append_text(param_tree
, ": (%s)", wmem_strbuf_get_str(args_buf
));
3203 proto_item_append_text(tree
, " -> %s(%s)", servicename
, wmem_strbuf_get_str(args_buf
));
3204 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> %s(%s)", servicename
, wmem_strbuf_get_str(args_buf
));
3209 /*******************************************************************************************************
3211 *******************************************************************************************************/
3213 s7comm_decode_pi_service(tvbuff_t
*tvb
,
3219 uint16_t len
, paramlen
;
3220 uint32_t startoffset
;
3221 uint32_t paramoffset
;
3224 const uint8_t *servicename
;
3226 const uint8_t *str1
;
3229 int pi_servicename_idx
;
3230 const char *pi_servicename_descr
;
3232 proto_item
*item
= NULL
;
3233 proto_item
*itemadd
= NULL
;
3234 proto_tree
*param_tree
= NULL
;
3235 proto_tree
*file_tree
= NULL
;
3240 startoffset
= offset
;
3242 /* The first byte is checked and inserted to tree outside, so skip it here */
3245 /* First part is unknown, 7 bytes */
3246 proto_tree_add_item(tree
, hf_s7comm_piservice_unknown1
, tvb
, offset
, 7, ENC_NA
);
3249 if (offset
- startoffset
>= plength
) {
3252 /* Parameter block */
3253 paramlen
= tvb_get_ntohs(tvb
, offset
);
3254 proto_tree_add_uint(tree
, hf_s7comm_piservice_parameterblock_len
, tvb
, offset
, 2, paramlen
);
3257 paramoffset
= offset
;
3258 item
= proto_tree_add_item(tree
, hf_s7comm_piservice_parameterblock
, tvb
, offset
, paramlen
, ENC_NA
);
3259 param_tree
= proto_item_add_subtree(item
, ett_s7comm_piservice_parameterblock
);
3262 /* PI servicename */
3263 len
= tvb_get_uint8(tvb
, offset
);
3264 proto_tree_add_uint(tree
, hf_s7comm_piservice_string_len
, tvb
, offset
, 1, len
);
3266 item
= proto_tree_add_item_ret_string(tree
, hf_s7comm_piservice_servicename
, tvb
, offset
, len
, ENC_ASCII
|ENC_NA
, pinfo
->pool
, &servicename
);
3269 /* get the index position in pi_service_names, and add infotext with description to the item */
3270 pi_servicename_descr
= try_str_to_str_idx((const char*)servicename
, pi_service_names
, &pi_servicename_idx
);
3271 if (pi_servicename_idx
< 0) {
3272 pi_servicename_idx
= S7COMM_PI_UNKNOWN
;
3273 pi_servicename_descr
= "Unknown PI Service";
3275 proto_item_append_text(item
, " [%s]", pi_servicename_descr
);
3277 /* Work parameter data, depending on servicename */
3278 switch (pi_servicename_idx
) {
3279 case S7COMM_PI_INSE
:
3280 case S7COMM_PI_INS2
:
3281 case S7COMM_PI_DELE
:
3282 count
= tvb_get_uint8(tvb
, paramoffset
); /* number of blocks following */
3283 proto_tree_add_uint(param_tree
, hf_s7comm_data_plccontrol_block_cnt
, tvb
, paramoffset
, 1, count
);
3285 /* Unknown, is always 0x00 */
3286 proto_tree_add_item(param_tree
, hf_s7comm_data_pi_inse_unknown
, tvb
, paramoffset
, 1, ENC_BIG_ENDIAN
);
3288 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> %s(", servicename
);
3289 for (i
= 0; i
< count
; i
++) {
3290 item
= proto_tree_add_item(param_tree
, hf_s7comm_data_blockcontrol_filename
, tvb
, paramoffset
, 8, ENC_ASCII
);
3291 file_tree
= proto_item_add_subtree(item
, ett_s7comm_plcfilename
);
3292 blocktype
= tvb_get_ntohs(tvb
, paramoffset
);
3293 itemadd
= proto_tree_add_item(file_tree
, hf_s7comm_data_blockcontrol_block_type
, tvb
, paramoffset
, 2, ENC_ASCII
);
3294 proto_item_append_text(itemadd
, " (%s)", val_to_str(blocktype
, blocktype_names
, "Unknown Block type: 0x%04x"));
3296 proto_tree_add_item_ret_string(file_tree
, hf_s7comm_data_blockcontrol_block_num
, tvb
, paramoffset
, 5, ENC_ASCII
|ENC_NA
, pinfo
->pool
, &str
);
3298 num_valid
= ws_strtoi32((const char*)str
, NULL
, &num
);
3299 proto_item_append_text(file_tree
, " [%s ",
3300 val_to_str(blocktype
, blocktype_names
, "Unknown Block type: 0x%04x"));
3301 col_append_str(pinfo
->cinfo
, COL_INFO
,
3302 val_to_str(blocktype
, blocktype_names
, "Unknown Block type: 0x%04x"));
3304 proto_item_append_text(file_tree
, "%d]", num
);
3305 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%d", num
);
3307 expert_add_info(pinfo
, file_tree
, &ei_s7comm_data_blockcontrol_block_num_invalid
);
3308 proto_item_append_text(file_tree
, "NaN]");
3309 col_append_str(pinfo
->cinfo
, COL_INFO
, "NaN");
3312 col_append_str(pinfo
->cinfo
, COL_INFO
, ", ");
3314 itemadd
= proto_tree_add_item(file_tree
, hf_s7comm_data_blockcontrol_dest_filesys
, tvb
, paramoffset
, 1, ENC_ASCII
);
3315 proto_item_append_text(itemadd
, " (%s)", char_val_to_str(tvb_get_uint8(tvb
, paramoffset
), blocktype_attribute2_names
, "Unknown filesys"));
3318 col_append_str(pinfo
->cinfo
, COL_INFO
, ")");
3320 case S7COMM_PIP_PROGRAM
:
3321 case S7COMM_PI_MODU
:
3322 case S7COMM_PI_GARB
:
3323 if (paramlen
== 0) {
3324 proto_item_append_text(param_tree
, ": ()");
3325 proto_item_append_text(tree
, " -> %s()", servicename
);
3326 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> %s()", servicename
);
3328 proto_tree_add_item_ret_string(param_tree
, hf_s7comm_data_plccontrol_argument
, tvb
, paramoffset
, paramlen
, ENC_ASCII
|ENC_NA
, pinfo
->pool
, &str1
);
3329 proto_item_append_text(param_tree
, ": (\"%s\")", str1
);
3330 proto_item_append_text(tree
, " -> %s(\"%s\")", servicename
, str1
);
3331 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> %s(\"%s\")", servicename
, str1
);
3334 case S7COMM_PI_N_LOGIN_
:
3335 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3336 hf
[1] = hf_s7comm_pi_n_x_password
;
3337 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 2, hf
, paramoffset
);
3339 case S7COMM_PI_N_LOGOUT
:
3340 case S7COMM_PI_N_CANCEL
:
3341 case S7COMM_PI_N_DASAVE
:
3342 case S7COMM_PI_N_DIGIOF
:
3343 case S7COMM_PI_N_DIGION
:
3344 case S7COMM_PI_N_DZERO_
:
3345 case S7COMM_PI_N_ENDEXT
:
3346 case S7COMM_PI_N_OST_OF
:
3347 case S7COMM_PI_N_OST_ON
:
3348 case S7COMM_PI_N_SCALE_
:
3349 case S7COMM_PI_N_SETUFR
:
3350 case S7COMM_PI_N_STRTLK
:
3351 case S7COMM_PI_N_STRTUL
:
3352 case S7COMM_PI_N_TMRASS
:
3353 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3354 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 1, hf
, paramoffset
);
3356 case S7COMM_PI_N_F_DELE
:
3357 case S7COMM_PI_N_EXTERN
:
3358 case S7COMM_PI_N_EXTMOD
:
3359 case S7COMM_PI_N_F_DELR
:
3360 case S7COMM_PI_N_F_XFER
:
3361 case S7COMM_PI_N_LOCKE_
:
3362 case S7COMM_PI_N_SELECT
:
3363 case S7COMM_PI_N_SRTEXT
:
3364 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3365 hf
[1] = hf_s7comm_pi_n_x_filename
;
3366 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 2, hf
, paramoffset
);
3368 case S7COMM_PI_N_F_CLOS
:
3369 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3370 hf
[1] = hf_s7comm_pi_n_x_editwindowname
;
3371 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 2, hf
, paramoffset
);
3373 case S7COMM_PI_N_F_OPEN
:
3374 case S7COMM_PI_N_F_OPER
:
3375 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3376 hf
[1] = hf_s7comm_pi_n_x_filename
;
3377 hf
[2] = hf_s7comm_pi_n_x_editwindowname
;
3378 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 3, hf
, paramoffset
);
3380 case S7COMM_PI_N_F_SEEK
:
3381 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3382 hf
[1] = hf_s7comm_pi_n_x_editwindowname
;
3383 hf
[2] = hf_s7comm_pi_n_x_seekpointer
;
3384 hf
[3] = hf_s7comm_pi_n_x_windowsize
;
3385 hf
[4] = hf_s7comm_pi_n_x_comparestring
;
3386 hf
[5] = hf_s7comm_pi_n_x_skipcount
;
3387 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 6, hf
, paramoffset
);
3389 case S7COMM_PI_N_ASUP__
:
3390 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3391 hf
[1] = hf_s7comm_pi_n_x_interruptnr
;
3392 hf
[2] = hf_s7comm_pi_n_x_priority
;
3393 hf
[3] = hf_s7comm_pi_n_x_liftfast
;
3394 hf
[4] = hf_s7comm_pi_n_x_blsync
;
3395 hf
[5] = hf_s7comm_pi_n_x_filename
;
3396 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 6, hf
, paramoffset
);
3398 case S7COMM_PI_N_CHEKDM
:
3399 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3400 hf
[1] = hf_s7comm_pi_n_x_magnr
;
3401 hf
[2] = hf_s7comm_pi_n_x_dnr
;
3402 hf
[3] = hf_s7comm_pi_n_x_spindlenumber
;
3403 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 4, hf
, paramoffset
);
3405 case S7COMM_PI_N_CHKDNO
:
3406 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3407 hf
[1] = hf_s7comm_pi_n_x_wznr
;
3408 hf
[2] = hf_s7comm_pi_n_x_wznr
;
3409 hf
[3] = hf_s7comm_pi_n_x_dnr
;
3410 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 4, hf
, paramoffset
);
3412 case S7COMM_PI_N_CONFIG
:
3413 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3414 hf
[1] = hf_s7comm_pi_n_x_class
;
3415 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 2, hf
, paramoffset
);
3417 case S7COMM_PI_N_CRCEDN
:
3418 case S7COMM_PI_N_DELECE
:
3419 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3420 hf
[1] = hf_s7comm_pi_n_x_tnr
;
3421 hf
[2] = hf_s7comm_pi_n_x_dnr
;
3422 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 3, hf
, paramoffset
);
3424 case S7COMM_PI_N_CREACE
:
3425 case S7COMM_PI_N_CREATO
:
3426 case S7COMM_PI_N_DELETO
:
3427 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3428 hf
[1] = hf_s7comm_pi_n_x_toolnumber
;
3429 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 2, hf
, paramoffset
);
3431 case S7COMM_PI_N_CRTOCE
:
3432 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3433 hf
[1] = hf_s7comm_pi_n_x_toolnumber
;
3434 hf
[2] = hf_s7comm_pi_n_x_cenumber
;
3435 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 3, hf
, paramoffset
);
3437 case S7COMM_PI_N_DELVAR
:
3438 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3439 hf
[1] = hf_s7comm_pi_n_x_datablocknumber
;
3440 hf
[2] = hf_s7comm_pi_n_x_firstcolumnnumber
;
3441 hf
[3] = hf_s7comm_pi_n_x_lastcolumnnumber
;
3442 hf
[4] = hf_s7comm_pi_n_x_firstrownumber
;
3443 hf
[5] = hf_s7comm_pi_n_x_lastrownumber
;
3444 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 6, hf
, paramoffset
);
3446 case S7COMM_PI_N_F_COPY
:
3447 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3448 hf
[1] = hf_s7comm_pi_n_x_direction
;
3449 hf
[2] = hf_s7comm_pi_n_x_sourcefilename
;
3450 hf
[3] = hf_s7comm_pi_n_x_destinationfilename
;
3451 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 4, hf
, paramoffset
);
3453 case S7COMM_PI_N_F_DMDA
:
3454 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3455 hf
[1] = hf_s7comm_pi_n_x_channelnumber
;
3456 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 2, hf
, paramoffset
);
3458 case S7COMM_PI_N_F_PROR
:
3459 case S7COMM_PI_N_F_PROT
:
3460 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3461 hf
[1] = hf_s7comm_pi_n_x_filename
;
3462 hf
[2] = hf_s7comm_pi_n_x_protection
;
3463 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 3, hf
, paramoffset
);
3465 case S7COMM_PI_N_F_RENA
:
3466 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3467 hf
[1] = hf_s7comm_pi_n_x_oldfilename
;
3468 hf
[2] = hf_s7comm_pi_n_x_newfilename
;
3469 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 3, hf
, paramoffset
);
3471 case S7COMM_PI_N_FINDBL
:
3472 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3473 hf
[1] = hf_s7comm_pi_n_x_findmode
;
3474 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 2, hf
, paramoffset
);
3476 case S7COMM_PI_N_IBN_SS
:
3477 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3478 hf
[1] = hf_s7comm_pi_n_x_switch
;
3479 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 2, hf
, paramoffset
);
3481 case S7COMM_PI_N_MMCSEM
:
3482 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3483 hf
[1] = hf_s7comm_pi_n_x_functionnumber
;
3484 hf
[2] = hf_s7comm_pi_n_x_semaphorevalue
;
3485 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 3, hf
, paramoffset
);
3487 case S7COMM_PI_N_NCKMOD
:
3488 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3489 hf
[1] = hf_s7comm_pi_n_x_onoff
;
3490 hf
[2] = hf_s7comm_pi_n_x_mode
;
3491 hf
[3] = hf_s7comm_pi_n_x_factor
;
3492 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 4, hf
, paramoffset
);
3494 case S7COMM_PI_N_NEWPWD
:
3495 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3496 hf
[1] = hf_s7comm_pi_n_x_password
;
3497 hf
[2] = hf_s7comm_pi_n_x_passwordlevel
;
3498 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 3, hf
, paramoffset
);
3500 case S7COMM_PI_N_SEL_BL
:
3501 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3502 hf
[1] = hf_s7comm_pi_n_x_linenumber
;
3503 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 2, hf
, paramoffset
);
3505 case S7COMM_PI_N_SETTST
:
3506 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3507 hf
[1] = hf_s7comm_pi_n_x_magnr
;
3508 hf
[2] = hf_s7comm_pi_n_x_weargroup
;
3509 hf
[3] = hf_s7comm_pi_n_x_toolstatus
;
3510 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 4, hf
, paramoffset
);
3512 case S7COMM_PI_N_TMAWCO
:
3513 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3514 hf
[1] = hf_s7comm_pi_n_x_magnr
;
3515 hf
[2] = hf_s7comm_pi_n_x_weargroup
;
3516 hf
[3] = hf_s7comm_pi_n_x_wearsearchstrat
;
3517 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 4, hf
, paramoffset
);
3519 case S7COMM_PI_N_TMCRTC
:
3520 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3521 hf
[1] = hf_s7comm_pi_n_x_toolid
;
3522 hf
[2] = hf_s7comm_pi_n_x_toolnumber
;
3523 hf
[3] = hf_s7comm_pi_n_x_duplonumber
;
3524 hf
[4] = hf_s7comm_pi_n_x_edgenumber
;
3525 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 5, hf
, paramoffset
);
3527 case S7COMM_PI_N_TMCRTO
:
3528 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3529 hf
[1] = hf_s7comm_pi_n_x_toolid
;
3530 hf
[2] = hf_s7comm_pi_n_x_toolnumber
;
3531 hf
[3] = hf_s7comm_pi_n_x_duplonumber
;
3532 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 4, hf
, paramoffset
);
3534 case S7COMM_PI_N_TMFDPL
:
3535 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3536 hf
[1] = hf_s7comm_pi_n_x_toolnumber
;
3537 hf
[2] = hf_s7comm_pi_n_x_placenr
;
3538 hf
[3] = hf_s7comm_pi_n_x_magnr
;
3539 hf
[4] = hf_s7comm_pi_n_x_placerefnr
;
3540 hf
[5] = hf_s7comm_pi_n_x_magrefnr
;
3541 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 6, hf
, paramoffset
);
3543 case S7COMM_PI_N_TMFPBP
:
3544 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3545 hf
[1] = hf_s7comm_pi_n_x_magnrfrom
;
3546 hf
[2] = hf_s7comm_pi_n_x_placenrfrom
;
3547 hf
[3] = hf_s7comm_pi_n_x_magnrto
;
3548 hf
[4] = hf_s7comm_pi_n_x_placenrto
;
3549 hf
[5] = hf_s7comm_pi_n_x_magrefnr
;
3550 hf
[6] = hf_s7comm_pi_n_x_placerefnr
;
3551 hf
[7] = hf_s7comm_pi_n_x_halfplacesleft
;
3552 hf
[8] = hf_s7comm_pi_n_x_halfplacesright
;
3553 hf
[9] = hf_s7comm_pi_n_x_halfplacesup
;
3554 hf
[10] = hf_s7comm_pi_n_x_halfplacesdown
;
3555 hf
[11] = hf_s7comm_pi_n_x_placetype
;
3556 hf
[12] = hf_s7comm_pi_n_x_searchdirection
;
3557 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 13, hf
, paramoffset
);
3559 case S7COMM_PI_N_TMGETT
:
3560 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3561 hf
[1] = hf_s7comm_pi_n_x_toolname
;
3562 hf
[2] = hf_s7comm_pi_n_x_duplonumber
;
3563 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 3, hf
, paramoffset
);
3565 case S7COMM_PI_N_TMMVTL
:
3566 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3567 hf
[1] = hf_s7comm_pi_n_x_toolnumber
;
3568 hf
[2] = hf_s7comm_pi_n_x_placenrsource
;
3569 hf
[3] = hf_s7comm_pi_n_x_magnrsource
;
3570 hf
[4] = hf_s7comm_pi_n_x_placenrdestination
;
3571 hf
[5] = hf_s7comm_pi_n_x_magnrdestination
;
3572 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 6, hf
, paramoffset
);
3574 case S7COMM_PI_N_TMPCIT
:
3575 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3576 hf
[1] = hf_s7comm_pi_n_x_spindlenumber
;
3577 hf
[2] = hf_s7comm_pi_n_x_incrementnumber
;
3578 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 3, hf
, paramoffset
);
3580 case S7COMM_PI_N_TMPOSM
:
3581 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3582 hf
[1] = hf_s7comm_pi_n_x_toolnumber
;
3583 hf
[2] = hf_s7comm_pi_n_x_toolid
;
3584 hf
[3] = hf_s7comm_pi_n_x_duplonumber
;
3585 hf
[4] = hf_s7comm_pi_n_x_placenrsource
;
3586 hf
[5] = hf_s7comm_pi_n_x_magnrsource
;
3587 hf
[6] = hf_s7comm_pi_n_x_placenrdestination
;
3588 hf
[7] = hf_s7comm_pi_n_x_magnrdestination
;
3589 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 8, hf
, paramoffset
);
3591 case S7COMM_PI_N_TRESMO
:
3592 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3593 hf
[1] = hf_s7comm_pi_n_x_toolnumber
;
3594 hf
[2] = hf_s7comm_pi_n_x_dnr
;
3595 hf
[3] = hf_s7comm_pi_n_x_monitoringmode
;
3596 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 4, hf
, paramoffset
);
3598 case S7COMM_PI_N_TSEARC
:
3599 hf
[0] = hf_s7comm_pi_n_x_addressident
;
3600 hf
[1] = hf_s7comm_pi_n_x_magnrfrom
;
3601 hf
[2] = hf_s7comm_pi_n_x_placenrfrom
;
3602 hf
[3] = hf_s7comm_pi_n_x_magnrto
;
3603 hf
[4] = hf_s7comm_pi_n_x_placenrto
;
3604 hf
[5] = hf_s7comm_pi_n_x_magrefnr
;
3605 hf
[6] = hf_s7comm_pi_n_x_placerefnr
;
3606 hf
[7] = hf_s7comm_pi_n_x_searchdirection
;
3607 hf
[8] = hf_s7comm_pi_n_x_kindofsearch
;
3608 s7comm_decode_pistart_parameters(tvb
, pinfo
, tree
, param_tree
, servicename
, 9, hf
, paramoffset
);
3611 /* Don't know how to interpret the parameters, show only the PI servicename */
3612 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> [%s]", servicename
);
3617 /*******************************************************************************************************
3619 * Decode a blockname/filename used in block/file upload/download
3621 *******************************************************************************************************/
3623 s7comm_decode_plc_controls_filename(tvbuff_t
*tvb
,
3625 proto_tree
*param_tree
,
3631 bool is_plcfilename
;
3632 proto_item
*item
= NULL
;
3633 proto_item
*itemadd
= NULL
;
3634 proto_tree
*file_tree
= NULL
;
3636 len
= tvb_get_uint8(tvb
, offset
);
3637 proto_tree_add_uint(param_tree
, hf_s7comm_data_blockcontrol_filename_len
, tvb
, offset
, 1, len
);
3639 item
= proto_tree_add_item(param_tree
, hf_s7comm_data_blockcontrol_filename
, tvb
, offset
, len
, ENC_ASCII
);
3640 /* The filename when uploading from PLC has a well known structure, which can be further dissected.
3641 * An upload from a NC is a simple filename string with no deeper structure.
3642 * Check for PLC filename, by checking some fixed fields.
3644 is_plcfilename
= false;
3646 blocktype
= tvb_get_ntohs(tvb
, offset
+ 1);
3647 if ((tvb_get_uint8(tvb
, offset
) == '_') && (blocktype
>= S7COMM_BLOCKTYPE_OB
) && (blocktype
<= S7COMM_BLOCKTYPE_SFB
)) {
3650 is_plcfilename
= true;
3651 file_tree
= proto_item_add_subtree(item
, ett_s7comm_plcfilename
);
3652 itemadd
= proto_tree_add_item(file_tree
, hf_s7comm_data_blockcontrol_file_ident
, tvb
, offset
, 1, ENC_ASCII
);
3653 proto_item_append_text(itemadd
, " (%s)", val_to_str(tvb_get_uint8(tvb
, offset
), blocktype_attribute1_names
, "Unknown identifier: %c"));
3655 itemadd
= proto_tree_add_item(file_tree
, hf_s7comm_data_blockcontrol_block_type
, tvb
, offset
, 2, ENC_ASCII
);
3656 proto_item_append_text(itemadd
, " (%s)", val_to_str(blocktype
, blocktype_names
, "Unknown Block type: 0x%04x"));
3658 proto_tree_add_item_ret_string(file_tree
, hf_s7comm_data_blockcontrol_block_num
, tvb
, offset
, 5, ENC_ASCII
|ENC_NA
, pinfo
->pool
, &str
);
3660 num_valid
= ws_strtoi32((const char*)str
, NULL
, &num
);
3661 proto_item_append_text(file_tree
, " [%s",
3662 val_to_str(blocktype
, blocktype_names
, "Unknown Block type: 0x%04x"));
3663 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> Block:[%s",
3664 val_to_str(blocktype
, blocktype_names
, "Unknown Block type: 0x%04x"));
3666 proto_item_append_text(file_tree
, "%d]", num
);
3667 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%d]", num
);
3669 expert_add_info(pinfo
, file_tree
, &ei_s7comm_data_blockcontrol_block_num_invalid
);
3670 proto_item_append_text(file_tree
, "NaN]");
3671 col_append_str(pinfo
->cinfo
, COL_INFO
, "NaN]");
3673 itemadd
= proto_tree_add_item(file_tree
, hf_s7comm_data_blockcontrol_dest_filesys
, tvb
, offset
, 1, ENC_ASCII
);
3674 proto_item_append_text(itemadd
, " (%s)", char_val_to_str(tvb_get_uint8(tvb
, offset
), blocktype_attribute2_names
, "Unknown filesys"));
3678 if (is_plcfilename
== false) {
3679 str
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, len
, ENC_ASCII
);
3680 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " File:[%s]", str
);
3686 /*******************************************************************************************************
3688 * PDU Type: Request or Response -> Function 0x1d, 0x1e, 0x1f (block control functions) for upload
3690 *******************************************************************************************************/
3692 s7comm_decode_plc_controls_updownload(tvbuff_t
*tvb
,
3695 proto_tree
*param_tree
,
3704 const char *errorcode_text
;
3705 proto_item
*item
= NULL
;
3706 proto_tree
*data_tree
= NULL
;
3708 function
= tvb_get_uint8(tvb
, offset
);
3713 /*---------------------------------------------------------------------*/
3714 case S7COMM_FUNCREQUESTDOWNLOAD
:
3715 if (rosctr
== S7COMM_ROSCTR_JOB
) {
3716 proto_tree_add_bitmask(param_tree
, tvb
, offset
, hf_s7comm_data_blockcontrol_functionstatus
,
3717 ett_s7comm_data_blockcontrol_status
, s7comm_data_blockcontrol_status_fields
, ENC_BIG_ENDIAN
);
3719 proto_tree_add_item(param_tree
, hf_s7comm_data_blockcontrol_unknown1
, tvb
, offset
, 2, ENC_NA
);
3721 /* on upload this is the upload-id, here it is anything else (or not used ) */
3722 proto_tree_add_item(param_tree
, hf_s7comm_data_blockcontrol_unknown1
, tvb
, offset
, 4, ENC_NA
);
3724 offset
= s7comm_decode_plc_controls_filename(tvb
, pinfo
, param_tree
, offset
);
3726 len
= tvb_get_uint8(tvb
, offset
);
3727 proto_tree_add_uint(param_tree
, hf_s7comm_data_blockcontrol_part2_len
, tvb
, offset
, 1, len
);
3729 /* first byte unknown '1' */
3730 proto_tree_add_item(param_tree
, hf_s7comm_data_blockcontrol_part2_unknown
, tvb
, offset
, 1, ENC_ASCII
);
3732 proto_tree_add_item(param_tree
, hf_s7comm_data_blockcontrol_loadmem_len
, tvb
, offset
, 6, ENC_ASCII
);
3734 proto_tree_add_item(param_tree
, hf_s7comm_data_blockcontrol_mc7code_len
, tvb
, offset
, 6, ENC_ASCII
);
3737 } else if (rosctr
== S7COMM_ROSCTR_ACK_DATA
) {
3739 proto_tree_add_bitmask(param_tree
, tvb
, offset
, hf_s7comm_data_blockcontrol_functionstatus
,
3740 ett_s7comm_data_blockcontrol_status
, s7comm_data_blockcontrol_status_fields
, ENC_BIG_ENDIAN
);
3745 /*---------------------------------------------------------------------*/
3746 case S7COMM_FUNCSTARTUPLOAD
:
3747 proto_tree_add_bitmask(param_tree
, tvb
, offset
, hf_s7comm_data_blockcontrol_functionstatus
,
3748 ett_s7comm_data_blockcontrol_status
, s7comm_data_blockcontrol_status_fields
, ENC_BIG_ENDIAN
);
3750 proto_tree_add_item(param_tree
, hf_s7comm_data_blockcontrol_unknown1
, tvb
, offset
, 2, ENC_NA
);
3752 proto_tree_add_item(param_tree
, hf_s7comm_data_blockcontrol_uploadid
, tvb
, offset
, 4, ENC_NA
);
3754 if (rosctr
== S7COMM_ROSCTR_JOB
) {
3755 offset
= s7comm_decode_plc_controls_filename(tvb
, pinfo
, param_tree
, offset
);
3756 } else if (rosctr
== S7COMM_ROSCTR_ACK_DATA
) {
3758 /* If uploading from a PLC, the response has a string with the length
3759 * of the complete module in bytes, which maybe transferred/split into many PDUs.
3760 * On a NC file upload, there are no such fields.
3762 len
= tvb_get_uint8(tvb
, offset
);
3763 proto_tree_add_uint(param_tree
, hf_s7comm_data_blockcontrol_upl_lenstring_len
, tvb
, offset
, 1, len
);
3765 proto_tree_add_item(param_tree
, hf_s7comm_data_blockcontrol_upl_lenstring
, tvb
, offset
, len
, ENC_ASCII
);
3770 /*---------------------------------------------------------------------*/
3771 case S7COMM_FUNCUPLOAD
:
3772 case S7COMM_FUNCDOWNLOADBLOCK
:
3773 if (rosctr
== S7COMM_ROSCTR_JOB
) {
3774 proto_tree_add_bitmask(param_tree
, tvb
, offset
, hf_s7comm_data_blockcontrol_functionstatus
,
3775 ett_s7comm_data_blockcontrol_status
, s7comm_data_blockcontrol_status_fields
, ENC_BIG_ENDIAN
);
3777 proto_tree_add_item(param_tree
, hf_s7comm_data_blockcontrol_unknown1
, tvb
, offset
, 2, ENC_NA
);
3779 if (function
== S7COMM_FUNCUPLOAD
) {
3780 proto_tree_add_item(param_tree
, hf_s7comm_data_blockcontrol_uploadid
, tvb
, offset
, 4, ENC_NA
);
3783 proto_tree_add_item(param_tree
, hf_s7comm_data_blockcontrol_unknown1
, tvb
, offset
, 4, ENC_NA
);
3785 offset
= s7comm_decode_plc_controls_filename(tvb
, pinfo
, param_tree
, offset
);
3787 } else if (rosctr
== S7COMM_ROSCTR_ACK_DATA
) {
3789 proto_tree_add_bitmask(param_tree
, tvb
, offset
, hf_s7comm_data_blockcontrol_functionstatus
,
3790 ett_s7comm_data_blockcontrol_status
, s7comm_data_blockcontrol_status_fields
, ENC_BIG_ENDIAN
);
3794 item
= proto_tree_add_item(tree
, hf_s7comm_data
, tvb
, offset
, dlength
, ENC_NA
);
3795 data_tree
= proto_item_add_subtree(item
, ett_s7comm_data
);
3796 proto_tree_add_item(data_tree
, hf_s7comm_data_length
, tvb
, offset
, 2, ENC_NA
);
3798 proto_tree_add_item(data_tree
, hf_s7comm_data_blockcontrol_unknown1
, tvb
, offset
, 2, ENC_NA
);
3800 proto_tree_add_item(data_tree
, hf_s7comm_readresponse_data
, tvb
, offset
, dlength
- 4, ENC_NA
);
3801 offset
+= dlength
- 4;
3805 /*---------------------------------------------------------------------*/
3806 case S7COMM_FUNCENDUPLOAD
:
3807 case S7COMM_FUNCDOWNLOADENDED
:
3808 if (rosctr
== S7COMM_ROSCTR_JOB
) {
3809 proto_tree_add_bitmask(param_tree
, tvb
, offset
, hf_s7comm_data_blockcontrol_functionstatus
,
3810 ett_s7comm_data_blockcontrol_status
, s7comm_data_blockcontrol_status_fields
, ENC_BIG_ENDIAN
);
3812 item
= proto_tree_add_item_ret_uint(param_tree
, hf_s7comm_data_blockcontrol_errorcode
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &errorcode
);
3813 /* here it uses the same errorcode from parameter part */
3814 if ((errorcode_text
= try_val_to_str_ext(errorcode
, ¶m_errcode_names_ext
))) {
3815 proto_item_append_text(item
, " (%s)", errorcode_text
);
3818 if (function
== S7COMM_FUNCENDUPLOAD
) {
3819 proto_tree_add_item(param_tree
, hf_s7comm_data_blockcontrol_uploadid
, tvb
, offset
, 4, ENC_NA
);
3822 proto_tree_add_item(param_tree
, hf_s7comm_data_blockcontrol_unknown1
, tvb
, offset
, 4, ENC_NA
);
3824 offset
= s7comm_decode_plc_controls_filename(tvb
, pinfo
, param_tree
, offset
);
3826 } else if (rosctr
== S7COMM_ROSCTR_ACK_DATA
) {
3828 proto_tree_add_bitmask(param_tree
, tvb
, offset
, hf_s7comm_data_blockcontrol_functionstatus
,
3829 ett_s7comm_data_blockcontrol_status
, s7comm_data_blockcontrol_status_fields
, ENC_BIG_ENDIAN
);
3835 /* if an error occurred show in info column */
3836 if (errorcode
> 0) {
3837 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> Errorcode:[0x%04x]", errorcode
);
3842 /*******************************************************************************************************
3844 * PDU Type: User Data -> Function group 1 -> Programmer commands -> Block status (0x13 or 0x01)
3846 *******************************************************************************************************/
3848 s7comm_decode_ud_tis_blockstat(tvbuff_t
*tvb
,
3849 proto_tree
*td_tree
,
3855 proto_item
*item
= NULL
;
3856 proto_tree
*item_tree
= NULL
;
3859 uint16_t item_size
= 4;
3860 uint8_t registerflags
;
3863 if (type
== S7COMM_UD_TYPE_REQ
) {
3864 if (subfunc
== S7COMM_UD_SUBF_TIS_BLOCKSTAT2
) {
3865 proto_tree_add_item(td_tree
, hf_s7comm_tis_blockstat_flagsunknown
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3867 line_cnt
= tvb_get_uint8(tvb
, offset
);
3868 proto_tree_add_uint(td_tree
, hf_s7comm_tis_blockstat_number_of_lines
, tvb
, offset
, 1, line_cnt
);
3870 proto_tree_add_item(td_tree
, hf_s7comm_tis_blockstat_reserved
, tvb
, offset
, 1, ENC_NA
);
3873 proto_tree_add_item(td_tree
, hf_s7comm_tis_blockstat_reserved
, tvb
, offset
, 1, ENC_NA
);
3875 line_cnt
= (td_size
- 2) / 2;
3877 proto_tree_add_bitmask(td_tree
, tvb
, offset
, hf_s7comm_diagdata_registerflag
,
3878 ett_s7comm_diagdata_registerflag
, s7comm_diagdata_registerflag_fields
, ENC_BIG_ENDIAN
);
3881 if (subfunc
== S7COMM_UD_SUBF_TIS_BLOCKSTAT2
) {
3886 for (line_nr
= 0; line_nr
< line_cnt
; line_nr
++) {
3887 item
= proto_tree_add_item(td_tree
, hf_s7comm_data_item
, tvb
, offset
, item_size
, ENC_NA
);
3888 item_tree
= proto_item_add_subtree(item
, ett_s7comm_data_item
);
3889 if (subfunc
== S7COMM_UD_SUBF_TIS_BLOCKSTAT2
) {
3890 proto_tree_add_item(item_tree
, hf_s7comm_tis_blockstat_line_address
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3893 proto_tree_add_item(item_tree
, hf_s7comm_tis_blockstat_reserved
, tvb
, offset
, 1, ENC_NA
);
3895 registerflags
= tvb_get_uint8(tvb
, offset
);
3896 make_registerflag_string(str_flags
, registerflags
, sizeof(str_flags
));
3897 proto_item_append_text(item
, " [%d]: (%s)", line_nr
+1, str_flags
);
3898 proto_tree_add_bitmask(item_tree
, tvb
, offset
, hf_s7comm_diagdata_registerflag
,
3899 ett_s7comm_diagdata_registerflag
, s7comm_diagdata_registerflag_fields
, ENC_BIG_ENDIAN
);
3902 } else if (type
== S7COMM_UD_TYPE_IND
) {
3903 /* The response data can only be dissected when the requested registers for each line
3904 * from the job setup is known. As the STW is only 16 Bits and all other registers 32 Bits,
3905 * this has no fixed structure.
3906 * The only thing that can be shown is the start address. Next the requested registers,
3907 * the start address of next line with the requested registers and so on.
3909 proto_tree_add_item(td_tree
, hf_s7comm_diagdata_req_startaddr_awl
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3911 proto_tree_add_item(td_tree
, hf_s7comm_tis_blockstat_data
, tvb
, offset
, td_size
- 2, ENC_NA
);
3912 offset
+= (td_size
- 2);
3914 /* TODO: Show unknown data as raw bytes */
3915 proto_tree_add_item(td_tree
, hf_s7comm_tis_blockstat_reserved
, tvb
, offset
, td_size
, ENC_NA
);
3921 /*******************************************************************************************************
3923 * PDU Type: User Data -> Function group 1 -> Programmer commands -> Item address
3925 *******************************************************************************************************/
3927 s7comm_decode_ud_tis_item_address(tvbuff_t
*tvb
,
3929 proto_tree
*sub_tree
,
3933 uint32_t bytepos
= 0;
3935 uint16_t bitpos
= 0;
3938 proto_item
*item
= NULL
;
3940 /* Insert a new tree with 6 bytes for every item */
3941 item
= proto_tree_add_item(sub_tree
, hf_s7comm_param_item
, tvb
, offset
, 6, ENC_NA
);
3943 sub_tree
= proto_item_add_subtree(item
, ett_s7comm_param_item
);
3945 proto_item_append_text(item
, " [%d]%s:", item_no
+ 1, add_text
);
3948 area
= tvb_get_uint8(tvb
, offset
);
3949 proto_tree_add_item(sub_tree
, hf_s7comm_varstat_req_memory_area
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3952 /* Length (repetition factor), 1 byte. If area is a bit address, then this is the bit number.
3953 * The area is a bit address when the low nibble is zero.
3956 len
= tvb_get_uint8(tvb
, offset
);
3957 proto_tree_add_uint(sub_tree
, hf_s7comm_varstat_req_repetition_factor
, tvb
, offset
, 1, len
);
3960 bitpos
= tvb_get_uint8(tvb
, offset
);
3961 proto_tree_add_uint(sub_tree
, hf_s7comm_varstat_req_bitpos
, tvb
, offset
, 1, bitpos
);
3965 /* DB number, 2 bytes */
3966 db
= tvb_get_ntohs(tvb
, offset
);
3967 proto_tree_add_uint(sub_tree
, hf_s7comm_varstat_req_db_number
, tvb
, offset
, 2, db
);
3970 /* byte offset, 2 bytes */
3971 bytepos
= tvb_get_ntohs(tvb
, offset
);
3972 proto_tree_add_uint(sub_tree
, hf_s7comm_varstat_req_startaddress
, tvb
, offset
, 2, bytepos
);
3975 /* build a full address to show item data directly beside the item */
3977 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_MX
:
3978 proto_item_append_text(sub_tree
, " (M%d.%d)", bytepos
, bitpos
);
3980 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_MB
:
3981 proto_item_append_text(sub_tree
, " (M%d.0 BYTE %d)", bytepos
, len
);
3983 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_MW
:
3984 proto_item_append_text(sub_tree
, " (M%d.0 WORD %d)", bytepos
, len
);
3986 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_MD
:
3987 proto_item_append_text(sub_tree
, " (M%d.0 DWORD %d)", bytepos
, len
);
3989 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_EX
:
3990 proto_item_append_text(sub_tree
, " (I%d.%d)", bytepos
, bitpos
);
3992 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_EB
:
3993 proto_item_append_text(sub_tree
, " (I%d.0 BYTE %d)", bytepos
, len
);
3995 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_EW
:
3996 proto_item_append_text(sub_tree
, " (I%d.0 WORD %d)", bytepos
, len
);
3998 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_ED
:
3999 proto_item_append_text(sub_tree
, " (I%d.0 DWORD %d)", bytepos
, len
);
4001 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_AX
:
4002 proto_item_append_text(sub_tree
, " (Q%d.%d)", bytepos
, bitpos
);
4004 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_AB
:
4005 proto_item_append_text(sub_tree
, " (Q%d.0 BYTE %d)", bytepos
, len
);
4007 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_AW
:
4008 proto_item_append_text(sub_tree
, " (Q%d.0 WORD %d)", bytepos
, len
);
4010 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_AD
:
4011 proto_item_append_text(sub_tree
, " (Q%d.0 DWORD %d)", bytepos
, len
);
4013 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_PEB
:
4014 proto_item_append_text(sub_tree
, " (PI%d.0 BYTE %d)", bytepos
, len
);
4016 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_PEW
:
4017 proto_item_append_text(sub_tree
, " (PI%d.0 WORD %d)", bytepos
, len
);
4019 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_PED
:
4020 proto_item_append_text(sub_tree
, " (PI%d.0 DWORD %d)", bytepos
, len
);
4022 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_DBX
:
4023 proto_item_append_text(sub_tree
, " (DB%d.DBX%d.%d)", db
, bytepos
, bitpos
);
4025 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_DBB
:
4026 proto_item_append_text(sub_tree
, " (DB%d.DBX%d.0 BYTE %d)", db
, bytepos
, len
);
4028 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_DBW
:
4029 proto_item_append_text(sub_tree
, " (DB%d.DBX%d.0 WORD %d)", db
, bytepos
, len
);
4031 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_DBD
:
4032 proto_item_append_text(sub_tree
, " (DB%d.DBX%d.0 DWORD %d)", db
, bytepos
, len
);
4034 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_T
:
4035 /* it's possible to read multiple timers */
4037 proto_item_append_text(sub_tree
, " (T %d..%d)", bytepos
, bytepos
+ len
- 1);
4039 proto_item_append_text(sub_tree
, " (T %d)", bytepos
);
4041 case S7COMM_UD_SUBF_TIS_VARSTAT_AREA_C
:
4042 /* it's possible to read multiple counters */
4044 proto_item_append_text(sub_tree
, " (C %d..%d)", bytepos
, bytepos
+ len
- 1);
4046 proto_item_append_text(sub_tree
, " (C %d)", bytepos
);
4052 /*******************************************************************************************************
4054 * PDU Type: User Data -> Function group 1 -> Programmer commands -> Item value
4056 *******************************************************************************************************/
4058 s7comm_decode_ud_tis_item_value(tvbuff_t
*tvb
,
4060 proto_tree
*sub_tree
,
4064 uint16_t len
= 0, len2
= 0;
4065 uint8_t ret_val
= 0;
4067 uint8_t head_len
= 4;
4069 proto_item
*item
= NULL
;
4071 ret_val
= tvb_get_uint8(tvb
, offset
);
4072 if (ret_val
== S7COMM_ITEM_RETVAL_RESERVED
||
4073 ret_val
== S7COMM_ITEM_RETVAL_DATA_OK
||
4074 ret_val
== S7COMM_ITEM_RETVAL_DATA_ERR
4076 tsize
= tvb_get_uint8(tvb
, offset
+ 1);
4077 len
= tvb_get_ntohs(tvb
, offset
+ 2);
4079 if (tsize
== S7COMM_DATA_TRANSPORT_SIZE_BBYTE
|| tsize
== S7COMM_DATA_TRANSPORT_SIZE_BINT
) {
4082 /* the PLC places extra bytes at the end if length is not a multiple of 2 */
4089 /* Insert a new tree for every item */
4090 item
= proto_tree_add_item(sub_tree
, hf_s7comm_data_item
, tvb
, offset
, len
+ head_len
, ENC_NA
);
4091 sub_tree
= proto_item_add_subtree(item
, ett_s7comm_data_item
);
4093 proto_item_append_text(item
, " [%d]%s: (%s)", item_no
+ 1, add_text
, val_to_str(ret_val
, s7comm_item_return_valuenames
, "Unknown code: 0x%02x"));
4095 proto_tree_add_uint(sub_tree
, hf_s7comm_data_returncode
, tvb
, offset
, 1, ret_val
);
4096 proto_tree_add_uint(sub_tree
, hf_s7comm_data_transport_size
, tvb
, offset
+ 1, 1, tsize
);
4097 proto_tree_add_uint(sub_tree
, hf_s7comm_data_length
, tvb
, offset
+ 2, 2, len
);
4100 if (ret_val
== S7COMM_ITEM_RETVAL_DATA_OK
|| ret_val
== S7COMM_ITEM_RETVAL_RESERVED
) {
4101 proto_tree_add_item(sub_tree
, hf_s7comm_readresponse_data
, tvb
, offset
, len
, ENC_NA
);
4104 proto_tree_add_item(sub_tree
, hf_s7comm_data_fillbyte
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4111 /*******************************************************************************************************
4113 * PDU Type: User Data -> Function group 1 -> Programmer commands -> Force (0x09)
4115 *******************************************************************************************************/
4117 s7comm_decode_ud_tis_force(tvbuff_t
*tvb
,
4118 proto_tree
*td_tree
,
4122 uint16_t item_count
;
4124 uint8_t ret_val
= 0;
4125 proto_item
*item
= NULL
;
4126 proto_tree
*item_tree
= NULL
;
4129 case S7COMM_UD_TYPE_REQ
:
4130 item_count
= tvb_get_ntohs(tvb
, offset
);
4131 proto_tree_add_uint(td_tree
, hf_s7comm_varstat_item_count
, tvb
, offset
, 2, item_count
);
4133 for (i
= 0; i
< item_count
; i
++) {
4134 offset
= s7comm_decode_ud_tis_item_address(tvb
, offset
, td_tree
, i
, " Address to force");
4136 for (i
= 0; i
< item_count
; i
++) {
4137 offset
= s7comm_decode_ud_tis_item_value(tvb
, offset
, td_tree
, i
, " Value to force");
4140 case S7COMM_UD_TYPE_IND
:
4141 item_count
= tvb_get_ntohs(tvb
, offset
);
4142 proto_tree_add_uint(td_tree
, hf_s7comm_varstat_item_count
, tvb
, offset
, 2, item_count
);
4144 for (i
= 0; i
< item_count
; i
++) {
4145 item
= proto_tree_add_item(td_tree
, hf_s7comm_data_item
, tvb
, offset
, 1, ENC_NA
);
4146 item_tree
= proto_item_add_subtree(item
, ett_s7comm_data_item
);
4147 ret_val
= tvb_get_uint8(tvb
, offset
);
4148 proto_tree_add_uint(item_tree
, hf_s7comm_data_returncode
, tvb
, offset
, 1, ret_val
);
4149 proto_item_append_text(item
, " [%d]: (%s)", i
+ 1, val_to_str(ret_val
, s7comm_item_return_valuenames
, "Unknown code: 0x%02x"));
4152 if (item_count
% 2) {
4153 proto_tree_add_item(item_tree
, hf_s7comm_data_fillbyte
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4161 /*******************************************************************************************************
4163 * PDU Type: User Data -> Function group 1 -> Programmer commands / Test and installation functions
4164 * Dissects the parameter part
4166 *******************************************************************************************************/
4168 s7comm_decode_ud_tis_param(tvbuff_t
*tvb
,
4174 uint32_t start_offset
;
4175 uint32_t callenv_setup
= 0;
4176 proto_item
*item
= NULL
;
4177 proto_tree
*tp_tree
= NULL
;
4179 start_offset
= offset
;
4181 item
= proto_tree_add_item(tree
, hf_s7comm_tis_parameter
, tvb
, offset
, tp_size
, ENC_NA
);
4182 tp_tree
= proto_item_add_subtree(item
, ett_s7comm_prog_parameter
);
4183 if (type
== S7COMM_UD_TYPE_REQ
) {
4185 proto_tree_add_item(tp_tree
, hf_s7comm_tis_param1
, tvb
, offset
, 2, ENC_NA
);
4187 proto_tree_add_item(tp_tree
, hf_s7comm_tis_param2
, tvb
, offset
, 2, ENC_NA
);
4190 if (tp_size
>= 20) {
4191 proto_tree_add_item(tp_tree
, hf_s7comm_tis_param3
, tvb
, offset
, 2, ENC_NA
);
4193 proto_tree_add_item(tp_tree
, hf_s7comm_tis_answersize
, tvb
, offset
, 2, ENC_NA
);
4195 proto_tree_add_item(tp_tree
, hf_s7comm_tis_param5
, tvb
, offset
, 2, ENC_NA
);
4197 proto_tree_add_item(tp_tree
, hf_s7comm_tis_param6
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4199 proto_tree_add_item(tp_tree
, hf_s7comm_tis_param7
, tvb
, offset
, 2, ENC_NA
);
4201 proto_tree_add_item(tp_tree
, hf_s7comm_tis_param8
, tvb
, offset
, 2, ENC_NA
);
4203 proto_tree_add_item(tp_tree
, hf_s7comm_tis_param9
, tvb
, offset
, 2, ENC_NA
);
4205 proto_tree_add_item(tp_tree
, hf_s7comm_tis_trgevent
, tvb
, offset
, 2, ENC_NA
);
4208 if (tp_size
>= 26) {
4209 proto_tree_add_item(tp_tree
, hf_s7comm_diagdata_req_block_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4211 proto_tree_add_item(tp_tree
, hf_s7comm_diagdata_req_block_num
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4213 proto_tree_add_item(tp_tree
, hf_s7comm_diagdata_req_startaddr_awl
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4216 if (tp_size
>= 28) {
4217 proto_tree_add_item(tp_tree
, hf_s7comm_diagdata_req_saz
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4220 if (tp_size
>= 36) {
4221 proto_tree_add_item_ret_uint(tp_tree
, hf_s7comm_tis_p_callenv
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &callenv_setup
);
4223 proto_tree_add_item(tp_tree
, hf_s7comm_tis_p_callcond
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4225 if (callenv_setup
== 2) {
4226 proto_tree_add_item(tp_tree
, hf_s7comm_tis_register_db1_nr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4228 proto_tree_add_item(tp_tree
, hf_s7comm_tis_register_db2_nr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4230 proto_tree_add_item(tp_tree
, hf_s7comm_tis_p_callcond_blocktype
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4232 proto_tree_add_item(tp_tree
, hf_s7comm_tis_p_callcond_blocknr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4234 if (tp_size
>= 38) {
4235 proto_tree_add_item(tp_tree
, hf_s7comm_tis_p_callcond_address
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4240 proto_tree_add_item(tp_tree
, hf_s7comm_tis_res_param1
, tvb
, offset
, 2, ENC_NA
);
4242 proto_tree_add_item(tp_tree
, hf_s7comm_tis_res_param2
, tvb
, offset
, 2, ENC_NA
);
4245 /* May be we don't know all values when here, so set offset to the given length */
4246 return start_offset
+ tp_size
;
4249 /*******************************************************************************************************
4251 * PDU Type: User Data -> Function group 1 -> Programmer commands -> Disable job (0x0d), Enable job (0x0e),
4252 * Delete job (0x0f), Read job list (0x10),
4255 *******************************************************************************************************/
4257 // NOLINTNEXTLINE(misc-no-recursion)
4258 s7comm_decode_ud_tis_jobs(tvbuff_t
*tvb
,
4259 proto_tree
*td_tree
,
4266 proto_item
*item
= NULL
;
4267 proto_tree
*item_tree
= NULL
;
4268 uint16_t job_tp_size
;
4269 uint16_t job_td_size
;
4270 proto_tree
*job_td_tree
= NULL
;
4271 uint8_t job_subfunc
;
4273 if (type
== S7COMM_UD_TYPE_REQ
) {
4275 case S7COMM_UD_SUBF_TIS_DELETEJOB
:
4276 proto_tree_add_item(td_tree
, hf_s7comm_tis_job_reserved
, tvb
, offset
, 2, ENC_NA
);
4279 case S7COMM_UD_SUBF_TIS_ENABLEJOB
:
4280 case S7COMM_UD_SUBF_TIS_DISABLEJOB
:
4281 case S7COMM_UD_SUBF_TIS_READJOB
:
4282 proto_tree_add_item(td_tree
, hf_s7comm_tis_job_function
, tvb
, offset
, 1, ENC_NA
);
4284 proto_tree_add_item(td_tree
, hf_s7comm_tis_job_seqnr
, tvb
, offset
, 1, ENC_NA
);
4287 case S7COMM_UD_SUBF_TIS_READJOBLIST
:
4288 /* 4 bytes, possible as filter? */
4289 proto_tree_add_item(td_tree
, hf_s7comm_tis_job_reserved
, tvb
, offset
, 2, ENC_NA
);
4291 proto_tree_add_item(td_tree
, hf_s7comm_tis_job_reserved
, tvb
, offset
, 2, ENC_NA
);
4294 case S7COMM_UD_SUBF_TIS_REPLACEJOB
:
4295 proto_tree_add_item(td_tree
, hf_s7comm_tis_job_reserved
, tvb
, offset
, 2, ENC_NA
);
4297 /* The job which has to be replaced */
4298 job_subfunc
= tvb_get_uint8(tvb
, offset
);
4299 proto_tree_add_item(td_tree
, hf_s7comm_tis_job_function
, tvb
, offset
, 1, ENC_NA
);
4301 proto_tree_add_item(td_tree
, hf_s7comm_tis_job_seqnr
, tvb
, offset
, 1, ENC_NA
);
4303 job_tp_size
= tvb_get_ntohs(tvb
, offset
);
4304 proto_tree_add_item(td_tree
, hf_s7comm_tis_parametersize
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4306 job_td_size
= tvb_get_ntohs(tvb
, offset
);
4307 proto_tree_add_item(td_tree
, hf_s7comm_tis_datasize
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4309 /* New job parameter tree */
4310 if (job_tp_size
> 0) {
4311 offset
= s7comm_decode_ud_tis_param(tvb
, td_tree
, S7COMM_UD_TYPE_REQ
, job_tp_size
, offset
);
4313 /* New job data tree */
4314 if (job_td_size
> 0) {
4315 // We recurse here, but we'll run out of packet before we run out of stack.
4316 offset
= s7comm_decode_ud_tis_data(tvb
, td_tree
, S7COMM_UD_TYPE_REQ
, job_subfunc
, job_td_size
, offset
);
4322 case S7COMM_UD_SUBF_TIS_READJOBLIST
:
4323 /* 4 bytes each job:
4325 * - 2 bytes status: 1=active, 0=idle/pending?
4327 for (i
= 0; i
< td_size
/ 4; i
++) {
4328 item
= proto_tree_add_item(td_tree
, hf_s7comm_data_item
, tvb
, offset
, 4, ENC_NA
);
4329 item_tree
= proto_item_add_subtree(item
, ett_s7comm_data_item
);
4330 proto_item_append_text(item
, " [%d] Job", i
+ 1);
4332 proto_tree_add_item(item_tree
, hf_s7comm_tis_job_function
, tvb
, offset
, 1, ENC_NA
);
4334 proto_tree_add_item(item_tree
, hf_s7comm_tis_job_seqnr
, tvb
, offset
, 1, ENC_NA
);
4336 proto_tree_add_item(item_tree
, hf_s7comm_tis_job_reserved
, tvb
, offset
, 2, ENC_NA
);
4340 case S7COMM_UD_SUBF_TIS_READJOB
:
4341 /* This includes the same data as in the job request. With the disadvantage that is does
4342 * not contain information of the function, so the data can't be further dissected.
4343 * We need to know the function from the request.
4345 job_tp_size
= tvb_get_ntohs(tvb
, offset
);
4346 proto_tree_add_item(td_tree
, hf_s7comm_tis_parametersize
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4348 job_td_size
= tvb_get_ntohs(tvb
, offset
);
4349 proto_tree_add_item(td_tree
, hf_s7comm_tis_datasize
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4351 /* Job parameter tree */
4352 if (job_tp_size
> 0) {
4353 offset
= s7comm_decode_ud_tis_param(tvb
, td_tree
, S7COMM_UD_TYPE_REQ
, job_tp_size
, offset
);
4356 if (job_td_size
> 0) {
4357 item
= proto_tree_add_item(td_tree
, hf_s7comm_tis_data
, tvb
, offset
, job_td_size
, ENC_NA
);
4358 job_td_tree
= proto_item_add_subtree(item
, ett_s7comm_prog_data
);
4359 proto_tree_add_item(job_td_tree
, hf_s7comm_tis_job_reserved
, tvb
, offset
, job_td_size
, ENC_NA
);
4360 offset
+= job_td_size
;
4368 /*******************************************************************************************************
4370 * PDU Type: User Data -> Function group 1 -> Programmer commands -> Variable status (0x03)
4372 *******************************************************************************************************/
4374 s7comm_decode_ud_tis_varstat(tvbuff_t
*tvb
,
4375 proto_tree
*td_tree
,
4379 uint16_t item_count
;
4383 case S7COMM_UD_TYPE_REQ
:
4384 item_count
= tvb_get_ntohs(tvb
, offset
);
4385 proto_tree_add_uint(td_tree
, hf_s7comm_varstat_item_count
, tvb
, offset
, 2, item_count
);
4387 for (i
= 0; i
< item_count
; i
++) {
4388 offset
= s7comm_decode_ud_tis_item_address(tvb
, offset
, td_tree
, i
, " Address to read");
4391 case S7COMM_UD_TYPE_IND
:
4392 item_count
= tvb_get_ntohs(tvb
, offset
);
4393 proto_tree_add_uint(td_tree
, hf_s7comm_varstat_item_count
, tvb
, offset
, 2, item_count
);
4395 for (i
= 0; i
< item_count
; i
++) {
4396 offset
= s7comm_decode_ud_tis_item_value(tvb
, offset
, td_tree
, i
, " Read data");
4403 /*******************************************************************************************************
4405 * PDU Type: User Data -> Function group 1 -> Programmer commands -> Modify variable (0x08)
4407 *******************************************************************************************************/
4409 s7comm_decode_ud_tis_modvar(tvbuff_t
*tvb
,
4410 proto_tree
*td_tree
,
4414 uint16_t item_count
;
4416 uint8_t ret_val
= 0;
4417 proto_item
*item
= NULL
;
4418 proto_tree
*item_tree
= NULL
;
4421 case S7COMM_UD_TYPE_REQ
:
4422 item_count
= tvb_get_ntohs(tvb
, offset
);
4423 proto_tree_add_uint(td_tree
, hf_s7comm_varstat_item_count
, tvb
, offset
, 2, item_count
);
4425 for (i
= 0; i
< item_count
; i
++) {
4426 offset
= s7comm_decode_ud_tis_item_address(tvb
, offset
, td_tree
, i
, " Address to write");
4428 for (i
= 0; i
< item_count
; i
++) {
4429 offset
= s7comm_decode_ud_tis_item_value(tvb
, offset
, td_tree
, i
, " Data to write");
4432 case S7COMM_UD_TYPE_IND
:
4433 item_count
= tvb_get_ntohs(tvb
, offset
);
4434 proto_tree_add_uint(td_tree
, hf_s7comm_varstat_item_count
, tvb
, offset
, 2, item_count
);
4436 for (i
= 0; i
< item_count
; i
++) {
4437 item
= proto_tree_add_item(td_tree
, hf_s7comm_data_item
, tvb
, offset
, 1, ENC_NA
);
4438 item_tree
= proto_item_add_subtree(item
, ett_s7comm_data_item
);
4439 ret_val
= tvb_get_uint8(tvb
, offset
);
4440 proto_tree_add_uint(item_tree
, hf_s7comm_data_returncode
, tvb
, offset
, 1, ret_val
);
4441 proto_item_append_text(item
, " [%d]: (%s)", i
+ 1, val_to_str(ret_val
, s7comm_item_return_valuenames
, "Unknown code: 0x%02x"));
4444 if (item_count
% 2) {
4445 proto_tree_add_item(item_tree
, hf_s7comm_data_fillbyte
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4453 /*******************************************************************************************************
4455 * PDU Type: User Data -> Function group 1 -> Programmer commands -> Output ISTACK (0x03)
4457 *******************************************************************************************************/
4459 s7comm_decode_ud_tis_istack(tvbuff_t
*tvb
,
4460 proto_tree
*td_tree
,
4464 uint8_t ob_number
= 0;
4466 case S7COMM_UD_TYPE_REQ
:
4467 proto_tree_add_item(td_tree
, hf_s7comm_tis_istack_reserved
, tvb
, offset
, 2, ENC_NA
);
4470 case S7COMM_UD_TYPE_RES
:
4471 case S7COMM_UD_TYPE_IND
:
4472 proto_tree_add_item(td_tree
, hf_s7comm_tis_continued_blocktype
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4474 proto_tree_add_item(td_tree
, hf_s7comm_tis_continued_blocknr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4476 proto_tree_add_item(td_tree
, hf_s7comm_tis_continued_address
, tvb
, offset
, 2, ENC_NA
);
4478 proto_tree_add_item(td_tree
, hf_s7comm_tis_register_db1_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4480 proto_tree_add_item(td_tree
, hf_s7comm_tis_register_db2_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4482 proto_tree_add_item(td_tree
, hf_s7comm_tis_register_db1_nr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4484 proto_tree_add_item(td_tree
, hf_s7comm_tis_register_db2_nr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4486 proto_tree_add_item(td_tree
, hf_s7comm_tis_istack_reserved
, tvb
, offset
, 4, ENC_NA
);
4488 proto_tree_add_item(td_tree
, hf_s7comm_tis_register_accu1
, tvb
, offset
, 4, ENC_NA
);
4490 proto_tree_add_item(td_tree
, hf_s7comm_tis_register_accu2
, tvb
, offset
, 4, ENC_NA
);
4492 proto_tree_add_item(td_tree
, hf_s7comm_tis_register_accu3
, tvb
, offset
, 4, ENC_NA
);
4494 proto_tree_add_item(td_tree
, hf_s7comm_tis_register_accu4
, tvb
, offset
, 4, ENC_NA
);
4496 proto_tree_add_item(td_tree
, hf_s7comm_tis_register_ar1
, tvb
, offset
, 4, ENC_NA
);
4498 proto_tree_add_item(td_tree
, hf_s7comm_tis_register_ar2
, tvb
, offset
, 4, ENC_NA
);
4500 proto_tree_add_item(td_tree
, hf_s7comm_tis_istack_reserved
, tvb
, offset
, 2, ENC_NA
);
4502 proto_tree_add_item(td_tree
, hf_s7comm_tis_register_stw
, tvb
, offset
, 2, ENC_NA
);
4504 proto_tree_add_item(td_tree
, hf_s7comm_tis_interrupted_blocktype
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4506 proto_tree_add_item(td_tree
, hf_s7comm_tis_interrupted_blocknr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4508 proto_tree_add_item(td_tree
, hf_s7comm_tis_interrupted_address
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4510 proto_tree_add_item(td_tree
, hf_s7comm_tis_istack_reserved
, tvb
, offset
, 2, ENC_NA
);
4512 proto_tree_add_item(td_tree
, hf_s7comm_tis_istack_reserved
, tvb
, offset
, 4, ENC_NA
);
4514 /* read the OB number first */
4515 ob_number
= tvb_get_uint8(tvb
, offset
+ 3);
4516 switch (ob_number
) {
4517 case 1: /* Cyclic execution */
4518 proto_tree_add_item(td_tree
, hf_s7comm_ob_ev_class
, tvb
, offset
, 1, ENC_NA
);
4520 proto_tree_add_item(td_tree
, hf_s7comm_ob_scan_1
, tvb
, offset
, 1, ENC_NA
);
4522 proto_tree_add_item(td_tree
, hf_s7comm_ob_priority
, tvb
, offset
, 1, ENC_NA
);
4524 proto_tree_add_item(td_tree
, hf_s7comm_ob_number
, tvb
, offset
, 1, ENC_NA
);
4526 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_1
, tvb
, offset
, 1, ENC_NA
);
4528 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_2
, tvb
, offset
, 1, ENC_NA
);
4530 proto_tree_add_item(td_tree
, hf_s7comm_ob_prev_cycle
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4532 proto_tree_add_item(td_tree
, hf_s7comm_ob_min_cycle
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4534 proto_tree_add_item(td_tree
, hf_s7comm_ob_max_cycle
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4537 case 10: /* Time of day interrupt 0..7 */
4545 proto_tree_add_item(td_tree
, hf_s7comm_ob_ev_class
, tvb
, offset
, 1, ENC_NA
);
4547 proto_tree_add_item(td_tree
, hf_s7comm_ob_strt_inf
, tvb
, offset
, 1, ENC_NA
);
4549 proto_tree_add_item(td_tree
, hf_s7comm_ob_priority
, tvb
, offset
, 1, ENC_NA
);
4551 proto_tree_add_item(td_tree
, hf_s7comm_ob_number
, tvb
, offset
, 1, ENC_NA
);
4553 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_1
, tvb
, offset
, 1, ENC_NA
);
4555 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_2
, tvb
, offset
, 1, ENC_NA
);
4557 proto_tree_add_item(td_tree
, hf_s7comm_ob_period_exe
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4559 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_3
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4561 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_4
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4564 case 20: /* Time delay interrupt 0..3 */
4568 proto_tree_add_item(td_tree
, hf_s7comm_ob_ev_class
, tvb
, offset
, 1, ENC_NA
);
4570 proto_tree_add_item(td_tree
, hf_s7comm_ob_strt_inf
, tvb
, offset
, 1, ENC_NA
);
4572 proto_tree_add_item(td_tree
, hf_s7comm_ob_priority
, tvb
, offset
, 1, ENC_NA
);
4574 proto_tree_add_item(td_tree
, hf_s7comm_ob_scan_1
, tvb
, offset
, 1, ENC_NA
);
4576 proto_tree_add_item(td_tree
, hf_s7comm_ob_number
, tvb
, offset
, 1, ENC_NA
);
4578 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_1
, tvb
, offset
, 1, ENC_NA
);
4580 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_2
, tvb
, offset
, 1, ENC_NA
);
4582 proto_tree_add_item(td_tree
, hf_s7comm_ob_sign
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4584 proto_tree_add_item(td_tree
, hf_s7comm_ob_dtime
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4587 case 30: /* Cyclic interrupt 0..8 */
4596 proto_tree_add_item(td_tree
, hf_s7comm_ob_ev_class
, tvb
, offset
, 1, ENC_NA
);
4598 proto_tree_add_item(td_tree
, hf_s7comm_ob_strt_inf
, tvb
, offset
, 1, ENC_NA
);
4600 proto_tree_add_item(td_tree
, hf_s7comm_ob_priority
, tvb
, offset
, 1, ENC_NA
);
4602 proto_tree_add_item(td_tree
, hf_s7comm_ob_number
, tvb
, offset
, 1, ENC_NA
);
4604 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_1
, tvb
, offset
, 1, ENC_NA
);
4606 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_2
, tvb
, offset
, 1, ENC_NA
);
4608 proto_tree_add_item(td_tree
, hf_s7comm_ob_phase_offset
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4610 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_3
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4612 proto_tree_add_item(td_tree
, hf_s7comm_ob_exec_freq
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4615 case 40: /* Hardware interrupt 0..8 */
4624 proto_tree_add_item(td_tree
, hf_s7comm_ob_ev_class
, tvb
, offset
, 1, ENC_NA
);
4626 proto_tree_add_item(td_tree
, hf_s7comm_ob_strt_inf
, tvb
, offset
, 1, ENC_NA
);
4628 proto_tree_add_item(td_tree
, hf_s7comm_ob_priority
, tvb
, offset
, 1, ENC_NA
);
4630 proto_tree_add_item(td_tree
, hf_s7comm_ob_number
, tvb
, offset
, 1, ENC_NA
);
4632 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_1
, tvb
, offset
, 1, ENC_NA
);
4634 proto_tree_add_item(td_tree
, hf_s7comm_ob_io_flag
, tvb
, offset
, 1, ENC_NA
);
4636 proto_tree_add_item(td_tree
, hf_s7comm_ob_mdl_addr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4638 proto_tree_add_item(td_tree
, hf_s7comm_ob_point_addr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4641 case 55: /* DP Statusalarm */
4642 case 56: /* DP Updatealarm */
4643 case 57: /* DP Specific alarm */
4644 proto_tree_add_item(td_tree
, hf_s7comm_ob_ev_class
, tvb
, offset
, 1, ENC_NA
);
4646 proto_tree_add_item(td_tree
, hf_s7comm_ob_strt_inf
, tvb
, offset
, 1, ENC_NA
);
4648 proto_tree_add_item(td_tree
, hf_s7comm_ob_priority
, tvb
, offset
, 1, ENC_NA
);
4650 proto_tree_add_item(td_tree
, hf_s7comm_ob_number
, tvb
, offset
, 1, ENC_NA
);
4652 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_1
, tvb
, offset
, 1, ENC_NA
);
4654 proto_tree_add_item(td_tree
, hf_s7comm_ob_io_flag
, tvb
, offset
, 1, ENC_NA
);
4656 proto_tree_add_item(td_tree
, hf_s7comm_ob_mdl_addr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4658 proto_tree_add_item(td_tree
, hf_s7comm_ob_inf_len
, tvb
, offset
, 1, ENC_NA
);
4660 proto_tree_add_item(td_tree
, hf_s7comm_ob_alarm_type
, tvb
, offset
, 1, ENC_NA
);
4662 proto_tree_add_item(td_tree
, hf_s7comm_ob_alarm_slot
, tvb
, offset
, 1, ENC_NA
);
4664 proto_tree_add_item(td_tree
, hf_s7comm_ob_alarm_spec
, tvb
, offset
, 1, ENC_NA
);
4667 case 80: /* Cycle time fault */
4668 proto_tree_add_item(td_tree
, hf_s7comm_ob_ev_class
, tvb
, offset
, 1, ENC_NA
);
4670 proto_tree_add_item(td_tree
, hf_s7comm_ob_flt_id
, tvb
, offset
, 1, ENC_NA
);
4672 proto_tree_add_item(td_tree
, hf_s7comm_ob_priority
, tvb
, offset
, 1, ENC_NA
);
4674 proto_tree_add_item(td_tree
, hf_s7comm_ob_number
, tvb
, offset
, 1, ENC_NA
);
4676 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_1
, tvb
, offset
, 1, ENC_NA
);
4678 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_2
, tvb
, offset
, 1, ENC_NA
);
4680 proto_tree_add_item(td_tree
, hf_s7comm_ob_error_info
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4682 proto_tree_add_item(td_tree
, hf_s7comm_ob_err_ev_class
, tvb
, offset
, 1, ENC_NA
);
4684 proto_tree_add_item(td_tree
, hf_s7comm_ob_err_ev_num
, tvb
, offset
, 1, ENC_NA
);
4686 proto_tree_add_item(td_tree
, hf_s7comm_ob_err_ob_priority
, tvb
, offset
, 1, ENC_NA
);
4688 proto_tree_add_item(td_tree
, hf_s7comm_ob_err_ob_num
, tvb
, offset
, 1, ENC_NA
);
4691 case 81: /* Power supply fault */
4692 proto_tree_add_item(td_tree
, hf_s7comm_ob_ev_class
, tvb
, offset
, 1, ENC_NA
);
4694 proto_tree_add_item(td_tree
, hf_s7comm_ob_flt_id
, tvb
, offset
, 1, ENC_NA
);
4696 proto_tree_add_item(td_tree
, hf_s7comm_ob_priority
, tvb
, offset
, 1, ENC_NA
);
4698 proto_tree_add_item(td_tree
, hf_s7comm_ob_number
, tvb
, offset
, 1, ENC_NA
);
4700 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_1
, tvb
, offset
, 1, ENC_NA
);
4702 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_2
, tvb
, offset
, 1, ENC_NA
);
4704 proto_tree_add_item(td_tree
, hf_s7comm_ob_rack_cpu
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4706 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_3
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4708 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_4
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4711 case 82: /* I/O Point fault 1 */
4712 proto_tree_add_item(td_tree
, hf_s7comm_ob_ev_class
, tvb
, offset
, 1, ENC_NA
);
4714 proto_tree_add_item(td_tree
, hf_s7comm_ob_flt_id
, tvb
, offset
, 1, ENC_NA
);
4716 proto_tree_add_item(td_tree
, hf_s7comm_ob_priority
, tvb
, offset
, 1, ENC_NA
);
4718 proto_tree_add_item(td_tree
, hf_s7comm_ob_number
, tvb
, offset
, 1, ENC_NA
);
4720 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_1
, tvb
, offset
, 1, ENC_NA
);
4722 proto_tree_add_item(td_tree
, hf_s7comm_ob_io_flag
, tvb
, offset
, 1, ENC_NA
);
4724 proto_tree_add_item(td_tree
, hf_s7comm_ob_mdl_addr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4726 proto_tree_add_item(td_tree
, hf_s7comm_ob_8x_fault_flags
, tvb
, offset
, 1, ENC_NA
);
4728 proto_tree_add_item(td_tree
, hf_s7comm_ob_mdl_type_b
, tvb
, offset
, 1, ENC_NA
);
4730 proto_tree_add_item(td_tree
, hf_s7comm_ob_8x_fault_flags
, tvb
, offset
, 1, ENC_NA
);
4732 proto_tree_add_item(td_tree
, hf_s7comm_ob_8x_fault_flags
, tvb
, offset
, 1, ENC_NA
);
4735 case 83: /* I/O Point fault 2 */
4736 proto_tree_add_item(td_tree
, hf_s7comm_ob_ev_class
, tvb
, offset
, 1, ENC_NA
);
4738 proto_tree_add_item(td_tree
, hf_s7comm_ob_flt_id
, tvb
, offset
, 1, ENC_NA
);
4740 proto_tree_add_item(td_tree
, hf_s7comm_ob_priority
, tvb
, offset
, 1, ENC_NA
);
4742 proto_tree_add_item(td_tree
, hf_s7comm_ob_number
, tvb
, offset
, 1, ENC_NA
);
4744 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_1
, tvb
, offset
, 1, ENC_NA
);
4746 proto_tree_add_item(td_tree
, hf_s7comm_ob_io_flag
, tvb
, offset
, 1, ENC_NA
);
4748 proto_tree_add_item(td_tree
, hf_s7comm_ob_mdl_addr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4750 proto_tree_add_item(td_tree
, hf_s7comm_ob_rack_num
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4752 proto_tree_add_item(td_tree
, hf_s7comm_ob_mdl_type_w
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4755 case 84: /* CPU fault */
4756 proto_tree_add_item(td_tree
, hf_s7comm_ob_ev_class
, tvb
, offset
, 1, ENC_NA
);
4758 proto_tree_add_item(td_tree
, hf_s7comm_ob_flt_id
, tvb
, offset
, 1, ENC_NA
);
4760 proto_tree_add_item(td_tree
, hf_s7comm_ob_priority
, tvb
, offset
, 1, ENC_NA
);
4762 proto_tree_add_item(td_tree
, hf_s7comm_ob_number
, tvb
, offset
, 1, ENC_NA
);
4764 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_1
, tvb
, offset
, 1, ENC_NA
);
4766 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_2
, tvb
, offset
, 1, ENC_NA
);
4768 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_3
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4770 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_4_dw
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4773 case 85: /* OB not loaded fault */
4774 case 87: /* Communication Fault */
4775 proto_tree_add_item(td_tree
, hf_s7comm_ob_ev_class
, tvb
, offset
, 1, ENC_NA
);
4777 proto_tree_add_item(td_tree
, hf_s7comm_ob_flt_id
, tvb
, offset
, 1, ENC_NA
);
4779 proto_tree_add_item(td_tree
, hf_s7comm_ob_priority
, tvb
, offset
, 1, ENC_NA
);
4781 proto_tree_add_item(td_tree
, hf_s7comm_ob_number
, tvb
, offset
, 1, ENC_NA
);
4783 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_1
, tvb
, offset
, 1, ENC_NA
);
4785 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_2
, tvb
, offset
, 1, ENC_NA
);
4787 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_3
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4789 proto_tree_add_item(td_tree
, hf_s7comm_ob_err_ev_class
, tvb
, offset
, 1, ENC_NA
);
4791 proto_tree_add_item(td_tree
, hf_s7comm_ob_err_ev_num
, tvb
, offset
, 1, ENC_NA
);
4793 proto_tree_add_item(td_tree
, hf_s7comm_ob_err_ob_priority
, tvb
, offset
, 1, ENC_NA
);
4795 proto_tree_add_item(td_tree
, hf_s7comm_ob_err_ob_num
, tvb
, offset
, 1, ENC_NA
);
4798 case 86: /* Loss of rack fault */
4799 proto_tree_add_item(td_tree
, hf_s7comm_ob_ev_class
, tvb
, offset
, 1, ENC_NA
);
4801 proto_tree_add_item(td_tree
, hf_s7comm_ob_flt_id
, tvb
, offset
, 1, ENC_NA
);
4803 proto_tree_add_item(td_tree
, hf_s7comm_ob_priority
, tvb
, offset
, 1, ENC_NA
);
4805 proto_tree_add_item(td_tree
, hf_s7comm_ob_number
, tvb
, offset
, 1, ENC_NA
);
4807 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_1
, tvb
, offset
, 1, ENC_NA
);
4809 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_2
, tvb
, offset
, 1, ENC_NA
);
4811 proto_tree_add_item(td_tree
, hf_s7comm_ob_mdl_addr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4813 proto_tree_add_item(td_tree
, hf_s7comm_ob_racks_flt
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4816 case 90: /* Background cycle */
4817 proto_tree_add_item(td_tree
, hf_s7comm_ob_ev_class
, tvb
, offset
, 1, ENC_NA
);
4819 proto_tree_add_item(td_tree
, hf_s7comm_ob_strt_inf
, tvb
, offset
, 1, ENC_NA
);
4821 proto_tree_add_item(td_tree
, hf_s7comm_ob_priority
, tvb
, offset
, 1, ENC_NA
);
4823 proto_tree_add_item(td_tree
, hf_s7comm_ob_number
, tvb
, offset
, 1, ENC_NA
);
4825 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_1
, tvb
, offset
, 1, ENC_NA
);
4827 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_2
, tvb
, offset
, 1, ENC_NA
);
4829 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_3
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4831 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_4_dw
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4834 case 100: /* Complete restart */
4835 case 101: /* Restart */
4836 case 102: /* Cold restart */
4837 proto_tree_add_item(td_tree
, hf_s7comm_ob_ev_class
, tvb
, offset
, 1, ENC_NA
);
4839 proto_tree_add_item(td_tree
, hf_s7comm_ob_strtup
, tvb
, offset
, 1, ENC_NA
);
4841 proto_tree_add_item(td_tree
, hf_s7comm_ob_priority
, tvb
, offset
, 1, ENC_NA
);
4843 proto_tree_add_item(td_tree
, hf_s7comm_ob_number
, tvb
, offset
, 1, ENC_NA
);
4845 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_1
, tvb
, offset
, 1, ENC_NA
);
4847 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_2
, tvb
, offset
, 1, ENC_NA
);
4849 proto_tree_add_item(td_tree
, hf_s7comm_ob_stop
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4851 proto_tree_add_item(td_tree
, hf_s7comm_ob_strt_info
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4854 case 121: /* Programming Error */
4855 proto_tree_add_item(td_tree
, hf_s7comm_ob_ev_class
, tvb
, offset
, 1, ENC_NA
);
4857 proto_tree_add_item(td_tree
, hf_s7comm_ob_sw_flt
, tvb
, offset
, 1, ENC_NA
);
4859 proto_tree_add_item(td_tree
, hf_s7comm_ob_priority
, tvb
, offset
, 1, ENC_NA
);
4861 proto_tree_add_item(td_tree
, hf_s7comm_ob_number
, tvb
, offset
, 1, ENC_NA
);
4863 proto_tree_add_item(td_tree
, hf_s7comm_ob_blk_type
, tvb
, offset
, 1, ENC_NA
);
4865 proto_tree_add_item(td_tree
, hf_s7comm_ob_reserved_1
, tvb
, offset
, 1, ENC_NA
);
4867 proto_tree_add_item(td_tree
, hf_s7comm_ob_flt_reg
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4869 proto_tree_add_item(td_tree
, hf_s7comm_ob_flt_blk_num
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4871 proto_tree_add_item(td_tree
, hf_s7comm_ob_prg_addr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4874 case 122: /* Module Access Error */
4875 proto_tree_add_item(td_tree
, hf_s7comm_ob_ev_class
, tvb
, offset
, 1, ENC_NA
);
4877 proto_tree_add_item(td_tree
, hf_s7comm_ob_sw_flt
, tvb
, offset
, 1, ENC_NA
);
4879 proto_tree_add_item(td_tree
, hf_s7comm_ob_priority
, tvb
, offset
, 1, ENC_NA
);
4881 proto_tree_add_item(td_tree
, hf_s7comm_ob_number
, tvb
, offset
, 1, ENC_NA
);
4883 proto_tree_add_item(td_tree
, hf_s7comm_ob_blk_type
, tvb
, offset
, 1, ENC_NA
);
4885 proto_tree_add_item(td_tree
, hf_s7comm_ob_mem_area
, tvb
, offset
, 1, ENC_NA
);
4887 proto_tree_add_item(td_tree
, hf_s7comm_ob_mem_addr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4889 proto_tree_add_item(td_tree
, hf_s7comm_ob_flt_blk_num
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4891 proto_tree_add_item(td_tree
, hf_s7comm_ob_prg_addr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4895 proto_tree_add_item(td_tree
, hf_s7comm_ob_ev_class
, tvb
, offset
, 1, ENC_NA
);
4897 proto_tree_add_item(td_tree
, hf_s7comm_tis_istack_reserved
, tvb
, offset
, 1, ENC_NA
);
4899 proto_tree_add_item(td_tree
, hf_s7comm_ob_priority
, tvb
, offset
, 1, ENC_NA
);
4901 proto_tree_add_item(td_tree
, hf_s7comm_ob_number
, tvb
, offset
, 1, ENC_NA
);
4903 proto_tree_add_item(td_tree
, hf_s7comm_tis_istack_reserved
, tvb
, offset
, 2, ENC_NA
);
4905 proto_tree_add_item(td_tree
, hf_s7comm_tis_istack_reserved
, tvb
, offset
, 2, ENC_NA
);
4907 proto_tree_add_item(td_tree
, hf_s7comm_tis_istack_reserved
, tvb
, offset
, 2, ENC_NA
);
4909 proto_tree_add_item(td_tree
, hf_s7comm_tis_istack_reserved
, tvb
, offset
, 2, ENC_NA
);
4913 offset
= s7comm_add_timestamp_to_tree(tvb
, td_tree
, offset
, false, false);
4918 /*******************************************************************************************************
4920 * PDU Type: User Data -> Function group 1 -> Programmer commands -> Output BSTACK (0x04)
4922 *******************************************************************************************************/
4924 s7comm_decode_ud_tis_bstack(tvbuff_t
*tvb
,
4925 proto_tree
*td_tree
,
4932 uint16_t blocknumber
;
4933 proto_item
*item
= NULL
;
4934 proto_tree
*item_tree
= NULL
;
4938 /* Possible firmware bug in IM151-8 CPU, where also the date size information
4939 * in the header is 4 bytes too short.
4941 replen
= tvb_reported_length_remaining(tvb
, offset
);
4942 if (replen
< td_size
) {
4943 /* TODO: Show this mismatch? We fix the length here. */
4947 case S7COMM_UD_TYPE_REQ
:
4948 proto_tree_add_item(td_tree
, hf_s7comm_tis_bstack_reserved
, tvb
, offset
, 2, ENC_NA
);
4951 case S7COMM_UD_TYPE_RES
:
4952 case S7COMM_UD_TYPE_IND
:
4956 item
= proto_tree_add_item(td_tree
, hf_s7comm_data_item
, tvb
, offset
, 16, ENC_NA
);
4957 item_tree
= proto_item_add_subtree(item
, ett_s7comm_data_item
);
4958 blocktype
= tvb_get_ntohs(tvb
, offset
);
4959 proto_tree_add_item(item_tree
, hf_s7comm_tis_interrupted_blocktype
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4961 blocknumber
= tvb_get_ntohs(tvb
, offset
);
4962 proto_tree_add_item(item_tree
, hf_s7comm_tis_interrupted_blocknr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4964 proto_tree_add_item(item_tree
, hf_s7comm_tis_interrupted_address
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4966 proto_tree_add_item(item_tree
, hf_s7comm_tis_register_db1_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4968 proto_tree_add_item(item_tree
, hf_s7comm_tis_register_db2_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4970 proto_tree_add_item(item_tree
, hf_s7comm_tis_register_db1_nr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4972 proto_tree_add_item(item_tree
, hf_s7comm_tis_register_db2_nr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4974 proto_tree_add_item(item_tree
, hf_s7comm_tis_bstack_reserved
, tvb
, offset
, 4, ENC_NA
);
4976 proto_item_append_text(item
, " [%d] BSTACK entry for: %s %d", i
++,
4977 val_to_str(blocktype
, subblktype_names
, "Unknown Subblk type: 0x%02x"), blocknumber
);
4979 if (blocktype
== S7COMM_SUBBLKTYPE_OB
) {
4980 proto_tree_add_item(item_tree
, hf_s7comm_tis_interrupted_prioclass
, tvb
, offset
, 1, ENC_NA
);
4982 proto_tree_add_item(item_tree
, hf_s7comm_tis_bstack_reserved
, tvb
, offset
, 1, ENC_NA
);
4984 proto_tree_add_item(item_tree
, hf_s7comm_tis_bstack_reserved
, tvb
, offset
, 2, ENC_NA
);
4988 offset
= s7comm_add_timestamp_to_tree(tvb
, item_tree
, offset
, false, false);
4991 proto_tree_add_item(item_tree
, hf_s7comm_tis_bstack_reserved
, tvb
, offset
, rem
, ENC_NA
);
5001 /*******************************************************************************************************
5003 * PDU Type: User Data -> Function group 1 -> Programmer commands -> Output LSTACK (0x05)
5005 *******************************************************************************************************/
5007 s7comm_decode_ud_tis_lstack(tvbuff_t
*tvb
,
5008 proto_tree
*td_tree
,
5014 if (type
== S7COMM_UD_TYPE_REQ
) {
5015 proto_tree_add_item(td_tree
, hf_s7comm_tis_interrupted_prioclass
, tvb
, offset
, 1, ENC_NA
);
5017 proto_tree_add_item(td_tree
, hf_s7comm_tis_bstack_nest_depth
, tvb
, offset
, 1, ENC_NA
);
5020 proto_tree_add_item(td_tree
, hf_s7comm_tis_interrupted_blocktype
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5022 proto_tree_add_item(td_tree
, hf_s7comm_tis_interrupted_blocknr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5024 proto_tree_add_item(td_tree
, hf_s7comm_tis_interrupted_address
, tvb
, offset
, 2, ENC_NA
);
5026 len
= tvb_get_ntohs(tvb
, offset
);
5027 proto_tree_add_item(td_tree
, hf_s7comm_tis_lstack_size
, tvb
, offset
, 2, ENC_NA
);
5029 proto_tree_add_item(td_tree
, hf_s7comm_tis_lstack_data
, tvb
, offset
, len
, ENC_NA
);
5031 proto_tree_add_item(td_tree
, hf_s7comm_tis_interrupted_prioclass
, tvb
, offset
, 1, ENC_NA
);
5033 proto_tree_add_item(td_tree
, hf_s7comm_tis_lstack_reserved
, tvb
, offset
, 1, ENC_NA
);
5035 proto_tree_add_item(td_tree
, hf_s7comm_tis_lstack_reserved
, tvb
, offset
, 2, ENC_NA
);
5037 offset
= s7comm_add_timestamp_to_tree(tvb
, td_tree
, offset
, false, false);
5041 /*******************************************************************************************************
5043 * PDU Type: User Data -> Function group 1 -> Programmer commands -> Exit Hold (0x0b)
5045 *******************************************************************************************************/
5047 s7comm_decode_ud_tis_exithold(tvbuff_t
*tvb
,
5048 proto_tree
*td_tree
,
5052 /* Only request with data payload was seen */
5054 case S7COMM_UD_TYPE_REQ
:
5055 proto_tree_add_item(td_tree
, hf_s7comm_tis_exithold_until
, tvb
, offset
, 1, ENC_NA
);
5057 proto_tree_add_item(td_tree
, hf_s7comm_tis_exithold_res1
, tvb
, offset
, 1, ENC_NA
);
5064 /*******************************************************************************************************
5066 * PDU Type: User Data -> Function group 1 -> Programmer commands -> Breakpoint (0x0a)
5068 *******************************************************************************************************/
5070 s7comm_decode_ud_tis_breakpoint(tvbuff_t
*tvb
,
5071 proto_tree
*td_tree
,
5076 case S7COMM_UD_TYPE_REQ
:
5077 proto_tree_add_item(td_tree
, hf_s7comm_tis_breakpoint_reserved
, tvb
, offset
, 2, ENC_NA
);
5080 case S7COMM_UD_TYPE_RES
:
5081 case S7COMM_UD_TYPE_IND
:
5082 /* Info: Both blocknumbers and addresses are the same on online-blockview inside a block.
5083 * On return out of a block, the first address contains the current breakpoint, the second
5084 * address the address from where it was returned (previous block).
5086 proto_tree_add_item(td_tree
, hf_s7comm_tis_interrupted_blocktype
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5088 proto_tree_add_item(td_tree
, hf_s7comm_tis_interrupted_blocknr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5090 proto_tree_add_item(td_tree
, hf_s7comm_tis_interrupted_address
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5092 proto_tree_add_item(td_tree
, hf_s7comm_tis_breakpoint_blocktype
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5094 proto_tree_add_item(td_tree
, hf_s7comm_tis_breakpoint_blocknr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5096 proto_tree_add_item(td_tree
, hf_s7comm_tis_breakpoint_address
, tvb
, offset
, 2, ENC_NA
);
5098 proto_tree_add_item(td_tree
, hf_s7comm_tis_breakpoint_reserved
, tvb
, offset
, 2, ENC_NA
);
5100 proto_tree_add_item(td_tree
, hf_s7comm_tis_register_stw
, tvb
, offset
, 2, ENC_NA
);
5102 proto_tree_add_item(td_tree
, hf_s7comm_tis_register_accu1
, tvb
, offset
, 4, ENC_NA
);
5104 proto_tree_add_item(td_tree
, hf_s7comm_tis_register_accu2
, tvb
, offset
, 4, ENC_NA
);
5106 proto_tree_add_item(td_tree
, hf_s7comm_tis_register_ar1
, tvb
, offset
, 4, ENC_NA
);
5108 proto_tree_add_item(td_tree
, hf_s7comm_tis_register_ar2
, tvb
, offset
, 4, ENC_NA
);
5110 proto_tree_add_item(td_tree
, hf_s7comm_tis_register_db1_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5112 proto_tree_add_item(td_tree
, hf_s7comm_tis_register_db2_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5114 proto_tree_add_item(td_tree
, hf_s7comm_tis_register_db1_nr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5116 proto_tree_add_item(td_tree
, hf_s7comm_tis_register_db2_nr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5122 /*******************************************************************************************************
5124 * PDU Type: User Data -> Function group 1 -> Programmer commands / Test and installation functions
5125 * Dissects the data part
5127 *******************************************************************************************************/
5129 // NOLINTNEXTLINE(misc-no-recursion)
5130 s7comm_decode_ud_tis_data(tvbuff_t
*tvb
,
5137 proto_item
*item
= NULL
;
5138 proto_tree
*td_tree
= NULL
;
5141 item
= proto_tree_add_item(tree
, hf_s7comm_tis_data
, tvb
, offset
, td_size
, ENC_NA
);
5142 td_tree
= proto_item_add_subtree(item
, ett_s7comm_prog_data
);
5144 case S7COMM_UD_SUBF_TIS_OUTISTACK
:
5145 offset
= s7comm_decode_ud_tis_istack(tvb
, td_tree
, type
, offset
);
5147 case S7COMM_UD_SUBF_TIS_OUTBSTACK
:
5148 offset
= s7comm_decode_ud_tis_bstack(tvb
, td_tree
, td_size
, type
, offset
);
5150 case S7COMM_UD_SUBF_TIS_OUTLSTACK
:
5151 offset
= s7comm_decode_ud_tis_lstack(tvb
, td_tree
, type
, offset
);
5153 case S7COMM_UD_SUBF_TIS_BREAKPOINT
:
5154 offset
= s7comm_decode_ud_tis_breakpoint(tvb
, td_tree
, type
, offset
);
5156 case S7COMM_UD_SUBF_TIS_EXITHOLD
:
5157 offset
= s7comm_decode_ud_tis_exithold(tvb
, td_tree
, type
, offset
);
5159 case S7COMM_UD_SUBF_TIS_BLOCKSTAT
:
5160 case S7COMM_UD_SUBF_TIS_BLOCKSTAT2
:
5161 offset
= s7comm_decode_ud_tis_blockstat(tvb
, td_tree
, td_size
, type
, subfunc
, offset
);
5163 case S7COMM_UD_SUBF_TIS_VARSTAT
:
5164 offset
= s7comm_decode_ud_tis_varstat(tvb
, td_tree
, type
, offset
);
5166 case S7COMM_UD_SUBF_TIS_DISABLEJOB
:
5167 case S7COMM_UD_SUBF_TIS_ENABLEJOB
:
5168 case S7COMM_UD_SUBF_TIS_DELETEJOB
:
5169 case S7COMM_UD_SUBF_TIS_READJOBLIST
:
5170 case S7COMM_UD_SUBF_TIS_READJOB
:
5171 case S7COMM_UD_SUBF_TIS_REPLACEJOB
:
5172 // We recurse here, but we'll run out of packet before we run out of stack.
5173 offset
= s7comm_decode_ud_tis_jobs(tvb
, td_tree
, td_size
, type
, subfunc
, offset
);
5175 case S7COMM_UD_SUBF_TIS_MODVAR
:
5176 offset
= s7comm_decode_ud_tis_modvar(tvb
, td_tree
, type
, offset
);
5178 case S7COMM_UD_SUBF_TIS_FORCE
:
5179 offset
= s7comm_decode_ud_tis_force(tvb
, td_tree
, type
, offset
);
5182 proto_tree_add_item(td_tree
, hf_s7comm_varstat_unknown
, tvb
, offset
, td_size
, ENC_NA
);
5190 /*******************************************************************************************************
5192 * PDU Type: User Data -> Function group 1 -> Programmer commands / Test and installation functions
5194 *******************************************************************************************************/
5196 s7comm_decode_ud_tis_subfunc(tvbuff_t
*tvb
,
5197 proto_tree
*data_tree
,
5202 uint16_t tp_size
= 0;
5203 uint16_t td_size
= 0;
5205 tp_size
= tvb_get_ntohs(tvb
, offset
);
5206 proto_tree_add_item(data_tree
, hf_s7comm_tis_parametersize
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5208 td_size
= tvb_get_ntohs(tvb
, offset
);
5209 proto_tree_add_item(data_tree
, hf_s7comm_tis_datasize
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5211 /* Parameter tree */
5212 offset
= s7comm_decode_ud_tis_param(tvb
, data_tree
, type
, tp_size
, offset
);
5214 offset
= s7comm_decode_ud_tis_data(tvb
, data_tree
, type
, subfunc
, td_size
, offset
);
5218 /*******************************************************************************************************
5220 * PDU Type: User Data -> Function group 5 -> Security functions?
5222 *******************************************************************************************************/
5224 s7comm_decode_ud_security_subfunc(tvbuff_t
*tvb
,
5225 proto_tree
*data_tree
,
5229 /* Display dataset as raw bytes. Maybe this part can be extended with further knowledge. */
5230 proto_tree_add_item(data_tree
, hf_s7comm_userdata_data
, tvb
, offset
, dlength
, ENC_NA
);
5236 /*******************************************************************************************************
5238 * PDU Type: User Data -> Function group 6 -> PBC, Programmable Block Functions (e.g. BSEND/BRECV), before reassembly
5240 *******************************************************************************************************/
5242 s7comm_decode_ud_pbc_bsend_pre_reass(tvbuff_t
*tvb
,
5244 proto_tree
*data_tree
,
5247 uint32_t *r_id
, /* R_ID of the PBC communication */
5250 if ((type
== S7COMM_UD_TYPE_REQ
|| type
== S7COMM_UD_TYPE_RES
) && (*dlength
>= 8)) {
5251 proto_tree_add_item(data_tree
, hf_s7comm_item_varspec
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5253 proto_tree_add_item(data_tree
, hf_s7comm_item_varspec_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5255 proto_tree_add_item(data_tree
, hf_s7comm_item_syntax_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5257 /* 0x00 when passive partners is sending, 0xcc when active partner is sending? */
5258 proto_tree_add_item(data_tree
, hf_s7comm_pbc_unknown
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5260 proto_tree_add_item(data_tree
, hf_s7comm_pbc_bsend_r_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
5261 *r_id
= tvb_get_ntohl(tvb
, offset
);
5262 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " R_ID=0x%X", *r_id
);
5269 /*******************************************************************************************************
5271 * PDU Type: User Data -> Function group 6 -> PBC, Programmable Block Functions (e.g. BSEND/BRECV)
5273 *******************************************************************************************************/
5275 s7comm_decode_ud_pbc_bsend_subfunc(tvbuff_t
*tvb
,
5276 proto_tree
*data_tree
,
5282 proto_tree_add_item(data_tree
, hf_s7comm_pbc_bsend_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5284 proto_tree_add_item(data_tree
, hf_s7comm_userdata_data
, tvb
, offset
, dlength
- 2, ENC_NA
);
5287 if (tvb_reported_length_remaining(tvb
, offset
) > 0) {
5288 struct tvbuff
*next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
5289 heur_dtbl_entry_t
*hdtbl_entry
;
5290 if (!dissector_try_heuristic(s7comm_heur_subdissector_list
, next_tvb
, pinfo
, tree
, &hdtbl_entry
, NULL
)) {
5291 call_data_dissector(next_tvb
, pinfo
, data_tree
);
5295 offset
+= (dlength
- 2);
5300 /*******************************************************************************************************
5302 * PDU Type: User Data -> PBC, Programmable Block Function USEND
5304 *******************************************************************************************************/
5306 s7comm_decode_ud_usend(tvbuff_t
*tvb
,
5311 proto_item
*item
= NULL
;
5312 proto_tree
*data_tree
= NULL
;
5313 proto_tree
*item_tree
= NULL
;
5321 item
= proto_tree_add_item(tree
, hf_s7comm_data
, tvb
, offset
, dlength
, ENC_NA
);
5322 data_tree
= proto_item_add_subtree(item
, ett_s7comm_data
);
5324 ret_val
= tvb_get_uint8(tvb
, offset
);
5325 proto_tree_add_uint(data_tree
, hf_s7comm_data_returncode
, tvb
, offset
, 1, ret_val
);
5328 proto_tree_add_item(data_tree
, hf_s7comm_pbc_usend_unknown1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5331 item_count
= tvb_get_uint8(tvb
, offset
+ 1); /* max. 4 possible */
5332 proto_tree_add_uint(data_tree
, hf_s7comm_param_itemcount
, tvb
, offset
, 2, item_count
);
5335 for (i
= 0; i
< item_count
; i
++) {
5336 tsize
= tvb_get_uint8(tvb
, offset
+ 1);
5337 len
= tvb_get_ntohs(tvb
, offset
+ 2);
5338 /* calculate length in bytes */
5339 if (tsize
== S7COMM_DATA_TRANSPORT_SIZE_BBIT
||
5340 tsize
== S7COMM_DATA_TRANSPORT_SIZE_BBYTE
||
5341 tsize
== S7COMM_DATA_TRANSPORT_SIZE_BINT
5351 if ((len
% 2) && (i
< (item_count
-1))) {
5357 item
= proto_tree_add_item(data_tree
, hf_s7comm_data_item
, tvb
, offset
, len
+ 4, ENC_NA
);
5358 item_tree
= proto_item_add_subtree(item
, ett_s7comm_data_item
);
5359 proto_item_append_text(item
, " [%d]", i
+1);
5360 proto_tree_add_item(item_tree
, hf_s7comm_pbc_usend_unknown2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5361 proto_tree_add_uint(item_tree
, hf_s7comm_data_transport_size
, tvb
, offset
+ 1, 1, tsize
);
5362 proto_tree_add_uint(item_tree
, hf_s7comm_data_length
, tvb
, offset
+ 2, 2, len
);
5365 proto_tree_add_item(item_tree
, hf_s7comm_readresponse_data
, tvb
, offset
, len
, ENC_NA
);
5368 proto_tree_add_item(item_tree
, hf_s7comm_data_fillbyte
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5376 /*******************************************************************************************************
5378 * PDU Type: User Data -> NC programming functions (file download/upload), before reassembly
5380 *******************************************************************************************************/
5382 s7comm_decode_ud_ncprg_pre_reass(tvbuff_t
*tvb
,
5383 proto_tree
*data_tree
,
5389 if ((type
== S7COMM_UD_TYPE_RES
|| type
== S7COMM_UD_TYPE_IND
) &&
5390 (subfunc
== S7COMM_NCPRG_FUNCDOWNLOADBLOCK
||
5391 subfunc
== S7COMM_NCPRG_FUNCUPLOAD
||
5392 subfunc
== S7COMM_NCPRG_FUNCSTARTUPLOAD
)) {
5393 proto_tree_add_item(data_tree
, hf_s7comm_data_blockcontrol_unknown1
, tvb
, offset
, 2, ENC_NA
);
5400 /*******************************************************************************************************
5402 * PDU Type: User Data -> NC programming functions (file download/upload)
5404 *******************************************************************************************************/
5406 s7comm_decode_ud_ncprg_subfunc(tvbuff_t
*tvb
,
5408 proto_tree
*data_tree
,
5414 const uint8_t *str_filename
;
5415 uint32_t string_end_offset
;
5416 uint32_t string_len
;
5417 uint32_t filelength
;
5418 uint32_t start_offset
;
5421 if (type
== S7COMM_UD_TYPE_REQ
&& subfunc
== S7COMM_NCPRG_FUNCREQUESTDOWNLOAD
) {
5422 proto_tree_add_item_ret_string(data_tree
, hf_s7comm_data_blockcontrol_filename
, tvb
, offset
, dlength
,
5423 ENC_ASCII
|ENC_NA
, pinfo
->pool
, &str_filename
);
5424 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " File:[%s]", str_filename
);
5426 } else if (type
== S7COMM_UD_TYPE_REQ
&& subfunc
== S7COMM_NCPRG_FUNCSTARTUPLOAD
) {
5427 proto_tree_add_item(data_tree
, hf_s7comm_data_ncprg_unackcount
, tvb
, offset
, 1, ENC_NA
);
5430 proto_tree_add_item(data_tree
, hf_s7comm_data_blockcontrol_unknown1
, tvb
, offset
, 1, ENC_NA
);
5433 proto_tree_add_item_ret_string(data_tree
, hf_s7comm_data_blockcontrol_filename
, tvb
, offset
, dlength
,
5434 ENC_ASCII
|ENC_NA
, pinfo
->pool
, &str_filename
);
5435 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " File:[%s]", str_filename
);
5437 } else if (type
== S7COMM_UD_TYPE_RES
&& subfunc
== S7COMM_NCPRG_FUNCREQUESTDOWNLOAD
) {
5438 proto_tree_add_item(data_tree
, hf_s7comm_data_ncprg_unackcount
, tvb
, offset
, 1, ENC_NA
);
5440 proto_tree_add_item(data_tree
, hf_s7comm_data_blockcontrol_unknown1
, tvb
, offset
, 1, ENC_NA
);
5442 } else if (type
== S7COMM_UD_TYPE_IND
&& (subfunc
== S7COMM_NCPRG_FUNCCONTUPLOAD
|| subfunc
== S7COMM_NCPRG_FUNCCONTDOWNLOAD
)) {
5443 proto_tree_add_item(data_tree
, hf_s7comm_data_ncprg_unackcount
, tvb
, offset
, 1, ENC_NA
);
5445 proto_tree_add_item(data_tree
, hf_s7comm_data_blockcontrol_unknown1
, tvb
, offset
, 1, ENC_NA
);
5447 } else if ((type
== S7COMM_UD_TYPE_RES
|| type
== S7COMM_UD_TYPE_IND
) &&
5448 (subfunc
== S7COMM_NCPRG_FUNCDOWNLOADBLOCK
||
5449 subfunc
== S7COMM_NCPRG_FUNCUPLOAD
||
5450 subfunc
== S7COMM_NCPRG_FUNCSTARTUPLOAD
)) {
5451 start_offset
= offset
;
5452 /* file length may be contain only spaces when downloading a directory */
5453 proto_tree_add_item(data_tree
, hf_s7comm_data_ncprg_filelength
, tvb
, offset
, 8, ENC_ASCII
);
5455 proto_tree_add_item(data_tree
, hf_s7comm_data_ncprg_filetime
, tvb
, offset
, 16, ENC_ASCII
);
5457 /* File path and file data aren't always there */
5459 if (subfunc
== S7COMM_NCPRG_FUNCDOWNLOADBLOCK
|| subfunc
== S7COMM_NCPRG_FUNCSTARTUPLOAD
|| subfunc
== S7COMM_NCPRG_FUNCUPLOAD
) {
5460 string_end_offset
= tvb_find_uint8(tvb
, offset
, dlength
-8-16, 0x0a);
5461 if (string_end_offset
> 0) {
5462 string_len
= string_end_offset
- offset
+ 1; /* include 0x0a */
5463 proto_tree_add_item(data_tree
, hf_s7comm_data_ncprg_filepath
, tvb
, offset
, string_len
, ENC_ASCII
);
5464 offset
+= string_len
;
5465 filelength
= dlength
- (offset
- start_offset
);
5466 proto_tree_add_item(data_tree
, hf_s7comm_data_ncprg_filedata
, tvb
, offset
, filelength
, ENC_NA
);
5467 offset
+= filelength
;
5472 proto_tree_add_item(data_tree
, hf_s7comm_data_blockcontrol_unknown1
, tvb
, offset
, 2, ENC_NA
);
5476 proto_tree_add_item(data_tree
, hf_s7comm_userdata_data
, tvb
, offset
, dlength
, ENC_NA
);
5484 /*******************************************************************************************************
5486 * PDU Type: User Data -> Data record routing to Profibus
5488 *******************************************************************************************************/
5490 s7comm_decode_ud_drr_subfunc(tvbuff_t
*tvb
,
5495 /* As a start add only a data block. At least there are min. 6 bytes of a header.
5496 * At some point of the data, parts of the Profinet dissector may be reusable,
5497 * as there's an overlap between the Profibus and Profinet Specification.
5500 proto_tree_add_item(tree
, hf_s7comm_data_drr_data
, tvb
, offset
, dlength
, ENC_NA
);
5507 /*******************************************************************************************************
5509 * PDU Type: User Data -> Message services -> AR_SEND parameters on initiate/abort
5511 *******************************************************************************************************/
5513 s7comm_decode_message_service_ar_send_args(tvbuff_t
*tvb
,
5522 proto_item
*item
= NULL
;
5523 proto_tree
*item_tree
= NULL
;
5525 item_count
= tvb_get_uint8(tvb
, offset
);
5526 proto_tree_add_uint(tree
, hf_s7comm_param_itemcount
, tvb
, offset
, 1, item_count
);
5529 for (i
= 0; i
< item_count
; i
++) {
5530 if (type
== S7COMM_UD_TYPE_REQ
) {
5531 item
= proto_tree_add_item(tree
, hf_s7comm_data_item
, tvb
, offset
, 8, ENC_NA
);
5532 item_tree
= proto_item_add_subtree(item
, ett_s7comm_data_item
);
5533 proto_tree_add_item(item_tree
, hf_s7comm_item_varspec
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5535 proto_tree_add_item(item_tree
, hf_s7comm_item_varspec_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5537 proto_tree_add_item(item_tree
, hf_s7comm_item_syntax_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5539 proto_tree_add_item(item_tree
, hf_s7comm_pbc_arsend_unknown
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5541 proto_tree_add_item_ret_uint(item_tree
, hf_s7comm_pbc_arsend_ar_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &ar_id
);
5542 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s0x%X", (i
== 0) ? " AR_ID=" : ",", ar_id
);
5543 proto_item_append_text(item
, " [%d]: AR_ID=0x%X", i
+1, ar_id
);
5545 } else if (type
== S7COMM_UD_TYPE_RES
) {
5546 item
= proto_tree_add_item(tree
, hf_s7comm_data_item
, tvb
, offset
, 1, ENC_NA
);
5547 item_tree
= proto_item_add_subtree(item
, ett_s7comm_data_item
);
5548 proto_item_append_text(item
, " [%d]", i
+1);
5549 /* Kind of return code. But from what was captured, it doesn't matter if the AR_ID of the request is not available */
5550 proto_tree_add_item(item_tree
, hf_s7comm_pbc_arsend_ret
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5554 /* Fill byte on response if number of items is uneven */
5555 if (type
== S7COMM_UD_TYPE_RES
&& (item_count
% 2)) {
5556 proto_tree_add_item(tree
, hf_s7comm_data_fillbyte
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5562 /*******************************************************************************************************
5564 * PDU Type: User Data -> Message services
5566 *******************************************************************************************************/
5568 s7comm_decode_message_service(tvbuff_t
*tvb
,
5570 proto_tree
*data_tree
,
5577 char events_string
[42];
5580 case S7COMM_UD_TYPE_REQ
:
5581 events
= tvb_get_uint8(tvb
, offset
);
5582 proto_tree_add_bitmask(data_tree
, tvb
, offset
, hf_s7comm_cpu_msgservice_subscribe_events
,
5583 ett_s7comm_cpu_msgservice_subscribe_events
, s7comm_cpu_msgservice_subscribe_events_fields
, ENC_BIG_ENDIAN
);
5585 proto_tree_add_item(data_tree
, hf_s7comm_cpu_msgservice_req_reserved1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5588 (void) g_strlcpy(events_string
, "", sizeof(events_string
));
5589 if (events
& 0x01) (void) g_strlcat(events_string
, "MODE,", sizeof(events_string
)); /* Change in mode-transition: Stop, Run, by Push and Function-group=0, Subfunction: 0=Stop, 1=Warm Restart, 2=RUN */
5590 if (events
& 0x02) (void) g_strlcat(events_string
, "SYS,", sizeof(events_string
)); /* System diagnostics */
5591 if (events
& 0x04) (void) g_strlcat(events_string
, "USR,", sizeof(events_string
)); /* User-defined diagnostic messages */
5592 if (events
& 0x08) (void) g_strlcat(events_string
, "-4-,", sizeof(events_string
)); /* currently unknown flag */
5593 if (events
& 0x10) (void) g_strlcat(events_string
, "-5-,", sizeof(events_string
)); /* currently unknown flag */
5594 if (events
& 0x20) (void) g_strlcat(events_string
, "-6-,", sizeof(events_string
)); /* currently unknown flag */
5595 if (events
& 0x40) (void) g_strlcat(events_string
, "-7-,", sizeof(events_string
)); /* currently unknown flag */
5596 if (events
& 0x80) (void) g_strlcat(events_string
, "ALM,", sizeof(events_string
)); /* Program block message, type of message in additional field */
5597 if (strlen(events_string
) > 2)
5598 events_string
[strlen(events_string
) - 1 ] = '\0';
5599 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " SubscribedEvents=(%s)", events_string
);
5601 proto_tree_add_item(data_tree
, hf_s7comm_cpu_msgservice_username
, tvb
, offset
, 8, ENC_ASCII
);
5603 if ((events
& 0x80) && (dlength
> 10)) {
5604 almtype
= tvb_get_uint8(tvb
, offset
);
5605 proto_tree_add_item(data_tree
, hf_s7comm_cpu_msgservice_almtype
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5606 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " AlmType=%s", val_to_str(almtype
, cpu_msgservice_almtype_names
, "Unknown type: 0x%02x"));
5608 if (almtype
== S7COMM_CPU_MSG_ALMTYPE_AR_SEND_INITIATE
|| almtype
== S7COMM_CPU_MSG_ALMTYPE_AR_SEND_ABORT
) {
5609 offset
= s7comm_decode_message_service_ar_send_args(tvb
, pinfo
, data_tree
, type
, offset
);
5611 proto_tree_add_item(data_tree
, hf_s7comm_cpu_msgservice_req_reserved2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5616 case S7COMM_UD_TYPE_RES
:
5617 proto_tree_add_item(data_tree
, hf_s7comm_cpu_msgservice_res_result
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5619 proto_tree_add_item(data_tree
, hf_s7comm_cpu_msgservice_res_reserved1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5622 almtype
= tvb_get_uint8(tvb
, offset
);
5623 proto_tree_add_item(data_tree
, hf_s7comm_cpu_msgservice_almtype
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5624 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " AlmType=%s", val_to_str(almtype
, cpu_msgservice_almtype_names
, "Unknown type: 0x%02x"));
5626 if (almtype
== S7COMM_CPU_MSG_ALMTYPE_AR_SEND_INITIATE
|| almtype
== S7COMM_CPU_MSG_ALMTYPE_AR_SEND_ABORT
) {
5627 offset
= s7comm_decode_message_service_ar_send_args(tvb
, pinfo
, data_tree
, type
, offset
);
5629 proto_tree_add_item(data_tree
, hf_s7comm_cpu_msgservice_res_reserved2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5631 proto_tree_add_item(data_tree
, hf_s7comm_cpu_msgservice_res_reserved3
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5641 /*******************************************************************************************************
5643 * PDU Type: User Data -> AR_SEND, before reassembly
5645 *******************************************************************************************************/
5647 s7comm_decode_ud_cpu_ar_send_pre_reass(tvbuff_t
*tvb
,
5649 proto_tree
*data_tree
,
5655 if (*dlength
>= 8) {
5656 proto_tree_add_item(data_tree
, hf_s7comm_item_varspec
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5658 proto_tree_add_item(data_tree
, hf_s7comm_item_varspec_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5660 proto_tree_add_item(data_tree
, hf_s7comm_item_syntax_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5662 proto_tree_add_item(data_tree
, hf_s7comm_pbc_arsend_unknown
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5664 proto_tree_add_item_ret_uint(data_tree
, hf_s7comm_pbc_arsend_ar_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &ar_id
);
5665 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " AR_ID=0x%X", ar_id
);
5673 /*******************************************************************************************************
5675 * PDU Type: User Data -> AR_SEND
5677 *******************************************************************************************************/
5679 s7comm_decode_ud_cpu_ar_send(tvbuff_t
*tvb
,
5680 proto_tree
*data_tree
,
5685 /* Only the first fragment contains the length. As we get the length after reassembly, it's ok. */
5686 proto_tree_add_item_ret_uint(data_tree
, hf_s7comm_pbc_arsend_len
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &len
);
5689 proto_tree_add_item(data_tree
, hf_s7comm_userdata_data
, tvb
, offset
, len
, ENC_NA
);
5694 /*******************************************************************************************************
5696 * PDU Type: User Data -> Function group 4 -> alarm, main tree for all except query response
5698 *******************************************************************************************************/
5700 s7comm_decode_ud_cpu_alarm_main(tvbuff_t
*tvb
,
5702 proto_tree
*data_tree
,
5707 uint32_t start_offset
;
5708 uint32_t asc_start_offset
;
5709 uint32_t msg_obj_start_offset
;
5711 proto_item
*msg_item
= NULL
;
5712 proto_tree
*msg_item_tree
= NULL
;
5713 proto_item
*msg_obj_item
= NULL
;
5714 proto_tree
*msg_obj_item_tree
= NULL
;
5715 proto_item
*msg_work_item
= NULL
;
5716 proto_tree
*msg_work_item_tree
= NULL
;
5720 uint8_t nr_of_additional_values
;
5721 uint8_t signalstate
;
5725 uint8_t varspec_length
;
5727 start_offset
= offset
;
5729 msg_item
= proto_tree_add_item(data_tree
, hf_s7comm_cpu_alarm_message_item
, tvb
, offset
, 0, ENC_NA
);
5730 msg_item_tree
= proto_item_add_subtree(msg_item
, ett_s7comm_cpu_alarm_message
);
5733 case S7COMM_UD_SUBF_CPU_SCAN_IND
:
5734 proto_tree_add_item(msg_item_tree
, hf_s7comm_cpu_alarm_message_scan_unknown1
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5736 msg_work_item
= proto_tree_add_item(msg_item_tree
, hf_s7comm_cpu_alarm_message_timestamp_coming
, tvb
, offset
, 8, ENC_NA
);
5737 msg_work_item_tree
= proto_item_add_subtree(msg_work_item
, ett_s7comm_cpu_alarm_message_timestamp
);
5738 offset
= s7comm_add_timestamp_to_tree(tvb
, msg_work_item_tree
, offset
, true, false);
5739 proto_tree_add_item(msg_item_tree
, hf_s7comm_cpu_alarm_message_scan_unknown2
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5742 case S7COMM_UD_SUBF_CPU_ALARM8_IND
:
5743 case S7COMM_UD_SUBF_CPU_ALARMACK_IND
:
5744 case S7COMM_UD_SUBF_CPU_ALARMSQ_IND
:
5745 case S7COMM_UD_SUBF_CPU_ALARMS_IND
:
5746 case S7COMM_UD_SUBF_CPU_NOTIFY_IND
:
5747 case S7COMM_UD_SUBF_CPU_NOTIFY8_IND
:
5748 msg_work_item
= proto_tree_add_item(msg_item_tree
, hf_s7comm_cpu_alarm_message_timestamp_coming
, tvb
, offset
, 8, ENC_NA
);
5749 msg_work_item_tree
= proto_item_add_subtree(msg_work_item
, ett_s7comm_cpu_alarm_message_timestamp
);
5750 offset
= s7comm_add_timestamp_to_tree(tvb
, msg_work_item_tree
, offset
, true, false);
5753 proto_tree_add_item(msg_item_tree
, hf_s7comm_cpu_alarm_message_function
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5755 nr_objects
= tvb_get_uint8(tvb
, offset
);
5756 proto_tree_add_uint(msg_item_tree
, hf_s7comm_cpu_alarm_message_nr_objects
, tvb
, offset
, 1, nr_objects
);
5758 for (i
= 0; i
< nr_objects
; i
++) {
5759 msg_obj_start_offset
= offset
;
5760 msg_obj_item
= proto_tree_add_item(msg_item_tree
, hf_s7comm_cpu_alarm_message_obj_item
, tvb
, offset
, 0, ENC_NA
);
5761 msg_obj_item_tree
= proto_item_add_subtree(msg_obj_item
, ett_s7comm_cpu_alarm_message_object
);
5762 proto_item_append_text(msg_obj_item_tree
, " [%d]", i
+1);
5763 if (type
== S7COMM_UD_TYPE_REQ
|| type
== S7COMM_UD_TYPE_IND
) {
5764 proto_tree_add_item(msg_obj_item_tree
, hf_s7comm_item_varspec
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5766 varspec_length
= tvb_get_uint8(tvb
, offset
);
5767 proto_tree_add_uint(msg_obj_item_tree
, hf_s7comm_item_varspec_length
, tvb
, offset
, 1, varspec_length
);
5769 syntax_id
= tvb_get_uint8(tvb
, offset
);
5770 proto_tree_add_uint(msg_obj_item_tree
, hf_s7comm_item_syntax_id
, tvb
, offset
, 1, syntax_id
);
5772 switch (syntax_id
) {
5773 case S7COMM_SYNTAXID_ALARM_LOCKFREESET
:
5774 case S7COMM_SYNTAXID_ALARM_INDSET
:
5775 case S7COMM_SYNTAXID_NOTIFY_INDSET
:
5776 case S7COMM_SYNTAXID_ALARM_ACKSET
:
5777 nr_of_additional_values
= tvb_get_uint8(tvb
, offset
);
5778 proto_tree_add_uint(msg_obj_item_tree
, hf_s7comm_cpu_alarm_message_nr_add_values
, tvb
, offset
, 1, nr_of_additional_values
);
5780 ev_id
= tvb_get_ntohl(tvb
, offset
);
5781 proto_tree_add_uint(msg_obj_item_tree
, hf_s7comm_cpu_alarm_message_eventid
, tvb
, offset
, 4, ev_id
);
5783 proto_item_append_text(msg_obj_item_tree
, ": EventID=0x%08x", ev_id
);
5784 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " EventID=0x%08x", ev_id
);
5785 if (syntax_id
== S7COMM_SYNTAXID_ALARM_INDSET
|| syntax_id
== S7COMM_SYNTAXID_NOTIFY_INDSET
) {
5786 signalstate
= tvb_get_uint8(tvb
, offset
);
5787 proto_tree_add_bitmask(msg_obj_item_tree
, tvb
, offset
, hf_s7comm_cpu_alarm_message_eventstate
,
5788 ett_s7comm_cpu_alarm_message_signal
, s7comm_cpu_alarm_message_signal_fields
, ENC_BIG_ENDIAN
);
5790 /* show SIG with True values for a quick overview in info-column */
5791 if (signalstate
> 0) {
5792 col_append_str(pinfo
->cinfo
, COL_INFO
, " On=[");
5793 for (sig_nr
= 0; sig_nr
< 8; sig_nr
++) {
5794 if (signalstate
& 0x01) {
5796 if (signalstate
== 0) {
5797 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "SIG_%d", sig_nr
+ 1);
5799 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "SIG_%d,", sig_nr
+ 1);
5805 col_append_str(pinfo
->cinfo
, COL_INFO
, "]");
5807 proto_tree_add_bitmask(msg_obj_item_tree
, tvb
, offset
, hf_s7comm_cpu_alarm_message_state
,
5808 ett_s7comm_cpu_alarm_message_signal
, s7comm_cpu_alarm_message_signal_fields
, ENC_BIG_ENDIAN
);
5811 if (syntax_id
== S7COMM_SYNTAXID_ALARM_INDSET
|| syntax_id
== S7COMM_SYNTAXID_ALARM_ACKSET
|| syntax_id
== S7COMM_SYNTAXID_NOTIFY_INDSET
) {
5812 proto_tree_add_bitmask(msg_obj_item_tree
, tvb
, offset
, hf_s7comm_cpu_alarm_message_ackstate_going
,
5813 ett_s7comm_cpu_alarm_message_signal
, s7comm_cpu_alarm_message_signal_fields
, ENC_BIG_ENDIAN
);
5815 proto_tree_add_bitmask(msg_obj_item_tree
, tvb
, offset
, hf_s7comm_cpu_alarm_message_ackstate_coming
,
5816 ett_s7comm_cpu_alarm_message_signal
, s7comm_cpu_alarm_message_signal_fields
, ENC_BIG_ENDIAN
);
5819 if (syntax_id
== S7COMM_SYNTAXID_NOTIFY_INDSET
) {
5820 proto_tree_add_bitmask(msg_obj_item_tree
, tvb
, offset
, hf_s7comm_cpu_alarm_message_event_going
,
5821 ett_s7comm_cpu_alarm_message_signal
, s7comm_cpu_alarm_message_signal_fields
, ENC_BIG_ENDIAN
);
5823 proto_tree_add_bitmask(msg_obj_item_tree
, tvb
, offset
, hf_s7comm_cpu_alarm_message_event_coming
,
5824 ett_s7comm_cpu_alarm_message_signal
, s7comm_cpu_alarm_message_signal_fields
, ENC_BIG_ENDIAN
);
5826 proto_tree_add_bitmask(msg_obj_item_tree
, tvb
, offset
, hf_s7comm_cpu_alarm_message_event_lastchanged
,
5827 ett_s7comm_cpu_alarm_message_signal
, s7comm_cpu_alarm_message_signal_fields
, ENC_BIG_ENDIAN
);
5829 proto_tree_add_item(msg_obj_item_tree
, hf_s7comm_cpu_alarm_message_event_reserved
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5832 if (syntax_id
== S7COMM_SYNTAXID_ALARM_INDSET
|| syntax_id
== S7COMM_SYNTAXID_NOTIFY_INDSET
) {
5833 if (nr_of_additional_values
> 0) {
5834 asc_start_offset
= offset
;
5835 msg_work_item
= proto_tree_add_item(msg_obj_item_tree
, hf_s7comm_cpu_alarm_message_associated_value
, tvb
, offset
, 0, ENC_NA
);
5836 msg_work_item_tree
= proto_item_add_subtree(msg_work_item
, ett_s7comm_cpu_alarm_message_associated_value
);
5837 offset
= s7comm_decode_response_read_data(tvb
, msg_work_item_tree
, nr_of_additional_values
, offset
);
5838 proto_item_set_len(msg_work_item_tree
, offset
- asc_start_offset
);
5842 case S7COMM_SYNTAXID_ALARM_QUERYREQSET
:
5843 proto_tree_add_item(msg_obj_item_tree
, hf_s7comm_cpu_alarm_query_unknown1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5845 querytype
= tvb_get_uint8(tvb
, offset
);
5846 proto_tree_add_uint(msg_obj_item_tree
, hf_s7comm_cpu_alarm_query_querytype
, tvb
, offset
, 1, querytype
);
5848 proto_tree_add_item(msg_obj_item_tree
, hf_s7comm_cpu_alarm_query_unknown2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5850 ev_id
= tvb_get_ntohl(tvb
, offset
);
5851 /* there is a querytype=8, which only occurs when a previous SZL request 0x131 index 0x10 has a missing flag in funk_1 */
5852 switch (querytype
) {
5853 case S7COMM_ALARM_MESSAGE_QUERYTYPE_BYALARMTYPE
:
5854 proto_tree_add_item(msg_obj_item_tree
, hf_s7comm_cpu_alarm_query_alarmtype
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
5855 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " ByAlarmtype=%s",
5856 val_to_str(ev_id
, alarm_message_query_alarmtype_names
, "Unknown Alarmtype: %u"));
5858 case S7COMM_ALARM_MESSAGE_QUERYTYPE_BYEVENTID
:
5859 proto_tree_add_item(msg_obj_item_tree
, hf_s7comm_cpu_alarm_message_eventid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
5860 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " ByEventID=0x%08x", ev_id
);
5868 /* for current unknown syntax id, set offset to end of dataset. The varspec_length includes
5869 * the byte for the syntax_id, so minus one.
5871 offset
+= (varspec_length
- 1);
5874 } else if (type
== S7COMM_UD_TYPE_RES
) {
5875 ret_val
= tvb_get_uint8(tvb
, offset
);
5876 proto_item_append_text(msg_obj_item_tree
, ": (%s)", val_to_str(ret_val
, s7comm_item_return_valuenames
, "Unknown code: 0x%02x"));
5877 proto_tree_add_uint(msg_obj_item_tree
, hf_s7comm_data_returncode
, tvb
, offset
, 1, ret_val
);
5880 proto_item_set_len(msg_obj_item_tree
, offset
- msg_obj_start_offset
);
5882 proto_item_set_len(msg_item_tree
, offset
- start_offset
);
5886 /*******************************************************************************************************
5888 * PDU Type: User Data -> Function group 4 -> alarm query response
5890 *******************************************************************************************************/
5892 s7comm_decode_ud_cpu_alarm_query_response(tvbuff_t
*tvb
,
5893 proto_tree
*data_tree
,
5896 proto_item
*msg_item
= NULL
;
5897 proto_tree
*msg_item_tree
= NULL
;
5898 proto_item
*msg_obj_item
= NULL
;
5899 proto_tree
*msg_obj_item_tree
= NULL
;
5900 proto_item
*msg_work_item
= NULL
;
5901 proto_tree
*msg_work_item_tree
= NULL
;
5902 uint32_t start_offset
;
5903 uint32_t msg_obj_start_offset
;
5904 uint32_t asc_start_offset
;
5908 uint16_t complete_length
;
5909 int32_t remaining_length
;
5912 start_offset
= offset
;
5913 msg_item
= proto_tree_add_item(data_tree
, hf_s7comm_cpu_alarm_message_item
, tvb
, offset
, 0, ENC_NA
);
5914 msg_item_tree
= proto_item_add_subtree(msg_item
, ett_s7comm_cpu_alarm_message
);
5916 /* Maybe this value here is something different, always 0x00 or 0x01 */
5917 proto_tree_add_item(msg_item_tree
, hf_s7comm_cpu_alarm_message_function
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5919 proto_tree_add_item(msg_item_tree
, hf_s7comm_cpu_alarm_message_nr_objects
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5921 returncode
= tvb_get_uint8(tvb
, offset
);
5922 proto_tree_add_uint(msg_item_tree
, hf_s7comm_data_returncode
, tvb
, offset
, 1, returncode
);
5924 proto_tree_add_item(msg_item_tree
, hf_s7comm_data_transport_size
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5926 complete_length
= tvb_get_ntohs(tvb
, offset
);
5927 proto_tree_add_uint(msg_item_tree
, hf_s7comm_cpu_alarm_query_completelen
, tvb
, offset
, 2, complete_length
);
5928 remaining_length
= (int32_t)complete_length
;
5931 if (returncode
== S7COMM_ITEM_RETVAL_DATA_OK
) {
5933 msg_obj_start_offset
= offset
;
5934 msg_obj_item
= proto_tree_add_item(msg_item_tree
, hf_s7comm_cpu_alarm_message_obj_item
, tvb
, offset
, 0, ENC_NA
);
5935 msg_obj_item_tree
= proto_item_add_subtree(msg_obj_item
, ett_s7comm_cpu_alarm_message_object
);
5937 proto_tree_add_item(msg_obj_item_tree
, hf_s7comm_cpu_alarm_query_datasetlen
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5939 proto_tree_add_item(msg_obj_item_tree
, hf_s7comm_cpu_alarm_query_resunknown1
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
5941 /* begin of count dataset length */
5942 alarmtype
= tvb_get_uint8(tvb
, offset
);
5943 proto_tree_add_uint(msg_obj_item_tree
, hf_s7comm_cpu_alarm_query_alarmtype
, tvb
, offset
, 1, alarmtype
);
5944 proto_item_append_text(msg_obj_item_tree
, " (Alarmtype=%s)", val_to_str(alarmtype
, alarm_message_query_alarmtype_names
, "Unknown Alarmtype: %u"));
5946 ev_id
= tvb_get_ntohl(tvb
, offset
);
5947 proto_tree_add_uint(msg_obj_item_tree
, hf_s7comm_cpu_alarm_message_eventid
, tvb
, offset
, 4, ev_id
);
5948 proto_item_append_text(msg_obj_item_tree
, ": EventID=0x%08x", ev_id
);
5950 proto_tree_add_item(msg_obj_item_tree
, hf_s7comm_cpu_alarm_query_resunknown1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
5952 proto_tree_add_bitmask(msg_obj_item_tree
, tvb
, offset
, hf_s7comm_cpu_alarm_message_eventstate
,
5953 ett_s7comm_cpu_alarm_message_signal
, s7comm_cpu_alarm_message_signal_fields
, ENC_BIG_ENDIAN
);
5955 proto_tree_add_bitmask(msg_obj_item_tree
, tvb
, offset
, hf_s7comm_cpu_alarm_message_ackstate_going
,
5956 ett_s7comm_cpu_alarm_message_signal
, s7comm_cpu_alarm_message_signal_fields
, ENC_BIG_ENDIAN
);
5958 proto_tree_add_bitmask(msg_obj_item_tree
, tvb
, offset
, hf_s7comm_cpu_alarm_message_ackstate_coming
,
5959 ett_s7comm_cpu_alarm_message_signal
, s7comm_cpu_alarm_message_signal_fields
, ENC_BIG_ENDIAN
);
5961 if (alarmtype
== S7COMM_ALARM_MESSAGE_QUERY_ALARMTYPE_ALARM_S
) {
5962 /* 8 bytes timestamp (coming)*/
5963 msg_work_item
= proto_tree_add_item(msg_obj_item_tree
, hf_s7comm_cpu_alarm_message_timestamp_coming
, tvb
, offset
, 8, ENC_NA
);
5964 msg_work_item_tree
= proto_item_add_subtree(msg_work_item
, ett_s7comm_cpu_alarm_message_timestamp
);
5965 offset
= s7comm_add_timestamp_to_tree(tvb
, msg_work_item_tree
, offset
, true, false);
5966 /* Associated value of coming alarm */
5967 asc_start_offset
= offset
;
5968 msg_work_item
= proto_tree_add_item(msg_obj_item_tree
, hf_s7comm_cpu_alarm_message_associated_value
, tvb
, offset
, 0, ENC_NA
);
5969 msg_work_item_tree
= proto_item_add_subtree(msg_work_item
, ett_s7comm_cpu_alarm_message_associated_value
);
5970 offset
= s7comm_decode_response_read_data(tvb
, msg_work_item_tree
, 1, offset
);
5971 proto_item_set_len(msg_work_item_tree
, offset
- asc_start_offset
);
5972 /* 8 bytes timestamp (going)
5973 * If all bytes in timestamp are zero, then the message is still active. */
5974 msg_work_item
= proto_tree_add_item(msg_obj_item_tree
, hf_s7comm_cpu_alarm_message_timestamp_going
, tvb
, offset
, 8, ENC_NA
);
5975 msg_work_item_tree
= proto_item_add_subtree(msg_work_item
, ett_s7comm_cpu_alarm_message_timestamp
);
5976 offset
= s7comm_add_timestamp_to_tree(tvb
, msg_work_item_tree
, offset
, true, false);
5977 /* Associated value of going alarm */
5978 asc_start_offset
= offset
;
5979 msg_work_item
= proto_tree_add_item(msg_obj_item_tree
, hf_s7comm_cpu_alarm_message_associated_value
, tvb
, offset
, 0, ENC_NA
);
5980 msg_work_item_tree
= proto_item_add_subtree(msg_work_item
, ett_s7comm_cpu_alarm_message_associated_value
);
5981 offset
= s7comm_decode_response_read_data(tvb
, msg_work_item_tree
, 1, offset
);
5982 proto_item_set_len(msg_work_item_tree
, offset
- asc_start_offset
);
5984 remaining_length
= remaining_length
- (offset
- msg_obj_start_offset
);
5985 proto_item_set_len(msg_obj_item_tree
, offset
- msg_obj_start_offset
);
5986 /* when complete_length is 0xffff, then loop until terminating null */
5987 if (complete_length
== 0xffff) {
5988 cont
= (tvb_get_uint8(tvb
, offset
) > 0);
5990 cont
= (remaining_length
> 0);
5994 proto_item_set_len(msg_item_tree
, offset
- start_offset
);
5999 /*******************************************************************************************************
6001 * PDU Type: User Data -> Function group 4 -> diagnostic message
6002 * Also used as a dataset in the diagnostic buffer, read with SZL-ID 0x00a0 index 0.
6004 *******************************************************************************************************/
6006 s7comm_decode_ud_cpu_diagnostic_message(tvbuff_t
*tvb
,
6008 bool add_info_to_col
,
6009 proto_tree
*data_tree
,
6012 proto_item
*msg_item
= NULL
;
6013 proto_tree
*msg_item_tree
= NULL
;
6015 uint16_t eventid_masked
;
6016 const char *event_text
;
6017 bool has_text
= false;
6019 msg_item
= proto_tree_add_item(data_tree
, hf_s7comm_cpu_diag_msg_item
, tvb
, offset
, 20, ENC_NA
);
6020 msg_item_tree
= proto_item_add_subtree(msg_item
, ett_s7comm_cpu_diag_msg
);
6022 eventid
= tvb_get_ntohs(tvb
, offset
);
6023 if ((eventid
>= 0x8000) && (eventid
<= 0x9fff)) {
6024 eventid_masked
= eventid
& 0xf0ff;
6025 if ((event_text
= try_val_to_str_ext(eventid_masked
, &cpu_diag_eventid_0x8_0x9_names_ext
))) {
6026 if (add_info_to_col
) {
6027 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " Event='%s'", event_text
);
6031 if (add_info_to_col
) {
6032 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " EventID=0x%04x", eventid
);
6035 } else if ((eventid
>= 0x1000) && (eventid
< 0x8000)) {
6036 if ((event_text
= try_val_to_str_ext(eventid
, &cpu_diag_eventid_fix_names_ext
))) {
6037 if (add_info_to_col
) {
6038 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " Event='%s'", event_text
);
6042 if (add_info_to_col
) {
6043 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " EventID=0x%04x", eventid
);
6047 if (add_info_to_col
) {
6048 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " EventID=0x%04x", eventid
);
6051 proto_tree_add_bitmask(msg_item_tree
, tvb
, offset
, hf_s7comm_cpu_diag_msg_eventid
,
6052 ett_s7comm_cpu_diag_msg_eventid
, s7comm_cpu_diag_msg_eventid_fields
, ENC_BIG_ENDIAN
);
6054 proto_item_append_text(msg_item_tree
, ": Event='%s'", event_text
);
6056 proto_item_append_text(msg_item_tree
, ": EventID=0x%04x", eventid
);
6059 proto_tree_add_item(msg_item_tree
, hf_s7comm_cpu_diag_msg_prioclass
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
6061 proto_tree_add_item(msg_item_tree
, hf_s7comm_cpu_diag_msg_obnumber
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
6063 proto_tree_add_item(msg_item_tree
, hf_s7comm_cpu_diag_msg_datid
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
6065 proto_tree_add_item(msg_item_tree
, hf_s7comm_cpu_diag_msg_info1
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
6067 proto_tree_add_item(msg_item_tree
, hf_s7comm_cpu_diag_msg_info2
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
6069 offset
= s7comm_add_timestamp_to_tree(tvb
, msg_item_tree
, offset
, false, false);
6074 /*******************************************************************************************************
6076 * PDU Type: User Data -> Function group 7 -> time functions
6078 *******************************************************************************************************/
6080 s7comm_decode_ud_time_subfunc(tvbuff_t
*tvb
,
6081 proto_tree
*data_tree
,
6084 uint8_t ret_val
, /* Return value in data part */
6088 bool know_data
= false;
6091 case S7COMM_UD_SUBF_TIME_READ
:
6092 case S7COMM_UD_SUBF_TIME_READF
:
6093 if (type
== S7COMM_UD_TYPE_RES
) {
6094 if (ret_val
== S7COMM_ITEM_RETVAL_DATA_OK
) {
6095 proto_item_append_text(data_tree
, ": ");
6096 offset
= s7comm_add_timestamp_to_tree(tvb
, data_tree
, offset
, true, true);
6101 case S7COMM_UD_SUBF_TIME_SET
:
6102 case S7COMM_UD_SUBF_TIME_SET2
:
6103 if (type
== S7COMM_UD_TYPE_REQ
) {
6104 if (ret_val
== S7COMM_ITEM_RETVAL_DATA_OK
) {
6105 proto_item_append_text(data_tree
, ": ");
6106 offset
= s7comm_add_timestamp_to_tree(tvb
, data_tree
, offset
, true, true);
6115 if (know_data
== false && dlength
> 0) {
6116 proto_tree_add_item(data_tree
, hf_s7comm_userdata_data
, tvb
, offset
, dlength
, ENC_NA
);
6122 /*******************************************************************************************************
6124 * PDU Type: User Data -> Function group 3 -> block functions
6126 *******************************************************************************************************/
6128 s7comm_decode_ud_block_subfunc(tvbuff_t
*tvb
,
6130 proto_tree
*data_tree
,
6133 uint8_t ret_val
, /* Return value in data part */
6134 uint8_t tsize
, /* transport size in data part */
6140 const uint8_t *pBlocknumber
;
6141 uint16_t blocknumber
;
6143 uint16_t blocktype16
;
6144 bool know_data
= false;
6145 proto_item
*item
= NULL
;
6146 proto_tree
*item_tree
= NULL
;
6147 proto_item
*itemadd
= NULL
;
6148 char str_timestamp
[30];
6149 char str_version
[10];
6152 /*************************************************
6155 case S7COMM_UD_SUBF_BLOCK_LIST
:
6156 if (type
== S7COMM_UD_TYPE_REQ
) {
6157 /* Is this a possible combination? Never seen it... */
6159 } else if (type
== S7COMM_UD_TYPE_RES
) {
6160 count
= dlength
/ 4;
6161 for (i
= 0; i
< count
; i
++) {
6162 /* Insert a new tree of 4 byte length for every item */
6163 item
= proto_tree_add_item(data_tree
, hf_s7comm_data_item
, tvb
, offset
, 4, ENC_NA
);
6164 item_tree
= proto_item_add_subtree(item
, ett_s7comm_data_item
);
6165 blocktype16
= tvb_get_ntohs(tvb
, offset
);
6166 proto_item_append_text(item
, " [%d]: (Block type %s)", i
+1, val_to_str(blocktype16
, blocktype_names
, "Unknown Block type: 0x%04x"));
6167 itemadd
= proto_tree_add_item(item_tree
, hf_s7comm_ud_blockinfo_block_type
, tvb
, offset
, 2, ENC_ASCII
);
6168 proto_item_append_text(itemadd
, " (%s)", val_to_str(blocktype16
, blocktype_names
, "Unknown Block type: 0x%04x"));
6170 proto_tree_add_item(item_tree
, hf_s7comm_ud_blockinfo_block_cnt
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
6176 /*************************************************
6177 * List blocks of type
6179 case S7COMM_UD_SUBF_BLOCK_LISTTYPE
:
6180 if (type
== S7COMM_UD_TYPE_REQ
) {
6181 if (tsize
!= S7COMM_DATA_TRANSPORT_SIZE_NULL
) {
6182 blocktype16
= tvb_get_ntohs(tvb
, offset
);
6183 itemadd
= proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_block_type
, tvb
, offset
, 2, ENC_ASCII
);
6184 proto_item_append_text(itemadd
, " (%s)", val_to_str(blocktype16
, blocktype_names
, "Unknown Block type: 0x%04x"));
6185 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " Type:[%s]",
6186 val_to_str(blocktype16
, blocktype_names
, "Unknown Block type: 0x%04x"));
6187 proto_item_append_text(data_tree
, ": (%s)",
6188 val_to_str(blocktype16
, blocktype_names
, "Unknown Block type: 0x%04x"));
6193 } else if (type
== S7COMM_UD_TYPE_RES
) {
6194 if (tsize
!= S7COMM_DATA_TRANSPORT_SIZE_NULL
) {
6195 count
= dlength
/ 4;
6197 for (i
= 0; i
< count
; i
++) {
6198 /* Insert a new tree of 4 byte length for every item */
6199 item
= proto_tree_add_item(data_tree
, hf_s7comm_data_item
, tvb
, offset
, 4, ENC_NA
);
6200 item_tree
= proto_item_add_subtree(item
, ett_s7comm_data_item
);
6202 proto_item_append_text(item
, " [%d]: (Block number %d)", i
+1, tvb_get_ntohs(tvb
, offset
));
6203 proto_tree_add_item(item_tree
, hf_s7comm_ud_blockinfo_block_num
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
6205 /* The first Byte is unknown, kind of flags? */
6206 proto_tree_add_item(item_tree
, hf_s7comm_ud_blockinfo_block_flags
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
6208 proto_tree_add_item(item_tree
, hf_s7comm_ud_blockinfo_block_lang
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
6215 /*************************************************
6218 case S7COMM_UD_SUBF_BLOCK_BLOCKINFO
:
6219 if (type
== S7COMM_UD_TYPE_REQ
) {
6220 if (tsize
!= S7COMM_DATA_TRANSPORT_SIZE_NULL
) {
6223 /* 8 Bytes of Data follow, 1./ 2. type, 3-7 blocknumber as ascii number */
6224 blocktype16
= tvb_get_ntohs(tvb
, offset
);
6225 itemadd
= proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_block_type
, tvb
, offset
, 2, ENC_ASCII
);
6226 proto_item_append_text(itemadd
, " (%s)", val_to_str(blocktype16
, blocktype_names
, "Unknown Block type: 0x%04x"));
6228 proto_tree_add_item_ret_string(data_tree
, hf_s7comm_ud_blockinfo_block_num_ascii
, tvb
, offset
, 5, ENC_ASCII
|ENC_NA
, pinfo
->pool
, &pBlocknumber
);
6229 num_valid
= ws_strtoi32((const char*)pBlocknumber
, NULL
, &num
);
6230 proto_item_append_text(data_tree
, " [%s ",
6231 val_to_str(blocktype16
, blocktype_names
, "Unknown Block type: 0x%04x"));
6232 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> Block:[%s ",
6233 val_to_str(blocktype16
, blocktype_names
, "Unknown Block type: 0x%04x"));
6235 proto_item_append_text(data_tree
, "%d]", num
);
6236 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%d]", num
);
6238 expert_add_info(pinfo
, data_tree
, &ei_s7comm_ud_blockinfo_block_num_ascii_invalid
);
6239 proto_item_append_text(data_tree
, "NaN]");
6240 col_append_str(pinfo
->cinfo
, COL_INFO
, "NaN]");
6243 itemadd
= proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_filesys
, tvb
, offset
, 1, ENC_ASCII
);
6244 proto_item_append_text(itemadd
, " (%s)", char_val_to_str(tvb_get_uint8(tvb
, offset
), blocktype_attribute2_names
, "Unknown filesys"));
6249 } else if (type
== S7COMM_UD_TYPE_RES
) {
6251 if (ret_val
== S7COMM_ITEM_RETVAL_DATA_OK
) {
6252 itemadd
= proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_block_type
, tvb
, offset
, 2, ENC_ASCII
);
6253 proto_item_append_text(itemadd
, " (%s)", val_to_str(tvb_get_ntohs(tvb
, offset
), blocktype_names
, "Unknown Block type: 0x%04x"));
6255 proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_res_infolength
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
6257 proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_res_unknown2
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
6259 proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_res_const3
, tvb
, offset
, 2, ENC_ASCII
);
6261 proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_res_unknown
, tvb
, offset
, 1, ENC_NA
);
6263 proto_tree_add_bitmask(data_tree
, tvb
, offset
, hf_s7comm_userdata_blockinfo_flags
,
6264 ett_s7comm_userdata_blockinfo_flags
, s7comm_userdata_blockinfo_flags_fields
, ENC_BIG_ENDIAN
);
6266 proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_block_lang
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
6268 blocktype
= tvb_get_uint8(tvb
, offset
);
6269 proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_subblk_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
6271 blocknumber
= tvb_get_ntohs(tvb
, offset
);
6272 proto_tree_add_uint(data_tree
, hf_s7comm_ud_blockinfo_block_num
, tvb
, offset
, 2, blocknumber
);
6273 /* Add block type and number to info column */
6274 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> Block:[%s %d]",
6275 val_to_str(blocktype
, subblktype_names
, "Unknown Subblk type: 0x%02x"),
6277 proto_item_append_text(data_tree
, ": (Block:[%s %d])",
6278 val_to_str(blocktype
, subblktype_names
, "Unknown Subblk type: 0x%02x"),
6281 /* "Length Load mem" -> the length in Step7 Manager seems to be this length +6 bytes */
6282 proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_load_mem_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
6284 proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_blocksecurity
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
6286 s7comm_get_timestring_from_s7time(tvb
, offset
, str_timestamp
, sizeof(str_timestamp
));
6287 proto_tree_add_string(data_tree
, hf_s7comm_ud_blockinfo_code_timestamp
, tvb
, offset
, 6, str_timestamp
);
6289 s7comm_get_timestring_from_s7time(tvb
, offset
, str_timestamp
, sizeof(str_timestamp
));
6290 proto_tree_add_string(data_tree
, hf_s7comm_ud_blockinfo_interface_timestamp
, tvb
, offset
, 6, str_timestamp
);
6292 proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_ssb_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
6294 proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_add_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
6296 proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_localdata_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
6298 proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_mc7_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
6300 proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_author
, tvb
, offset
, 8, ENC_ASCII
);
6302 proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_family
, tvb
, offset
, 8, ENC_ASCII
);
6304 proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_headername
, tvb
, offset
, 8, ENC_ASCII
);
6306 snprintf(str_version
, sizeof(str_version
), "%d.%d", ((tvb_get_uint8(tvb
, offset
) & 0xf0) >> 4), tvb_get_uint8(tvb
, offset
) & 0x0f);
6307 proto_tree_add_string(data_tree
, hf_s7comm_ud_blockinfo_headerversion
, tvb
, offset
, 1, str_version
);
6309 proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_res_unknown
, tvb
, offset
, 1, ENC_NA
);
6311 proto_tree_add_checksum(data_tree
, tvb
, offset
, hf_s7comm_ud_blockinfo_checksum
, -1, NULL
, pinfo
, 0, ENC_BIG_ENDIAN
, PROTO_CHECKSUM_NO_FLAGS
);
6313 proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_reserved1
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
6315 proto_tree_add_item(data_tree
, hf_s7comm_ud_blockinfo_reserved2
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
6324 if (know_data
== false && dlength
> 0) {
6325 proto_tree_add_item(data_tree
, hf_s7comm_userdata_data
, tvb
, offset
, dlength
, ENC_NA
);
6331 /*******************************************************************************************************
6333 * PDU Type: User Data -> Function group 2 -> Read record
6335 *******************************************************************************************************/
6337 s7comm_decode_ud_readrec(tvbuff_t
*tvb
,
6347 if (type
== S7COMM_UD_TYPE_REQ
) {
6348 proto_tree_add_item(tree
, hf_s7comm_rdrec_reserved1
, tvb
, offset
, 1, ENC_NA
);
6350 /* Although here is an item_count field, values above 1 aren't allowed or at least never seen */
6351 item_count
= tvb_get_uint8(tvb
, offset
);
6352 proto_tree_add_uint(tree
, hf_s7comm_param_itemcount
, tvb
, offset
, 1, item_count
);
6354 if (item_count
> 0) {
6355 offset
= s7comm_decode_param_item(tvb
, offset
, tree
, 0);
6357 } else if (type
== S7COMM_UD_TYPE_RES
) {
6358 /* The item with data is used for optional status code similar to the
6359 * STATUS output of SFB52 RDREC used in Plc code.
6361 proto_tree_add_item(tree
, hf_s7comm_rdrec_reserved1
, tvb
, offset
, 1, ENC_NA
);
6363 item_count
= tvb_get_uint8(tvb
, offset
);
6364 proto_tree_add_uint(tree
, hf_s7comm_param_itemcount
, tvb
, offset
, 1, item_count
);
6366 /* As all testsubjects have shown that no more than one item is allowed,
6367 * we decode only the first item here.
6369 if (item_count
> 0) {
6370 proto_tree_add_item_ret_uint(tree
, hf_s7comm_data_returncode
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &ret_val
);
6372 if (ret_val
== S7COMM_ITEM_RETVAL_DATA_OK
) {
6373 proto_tree_add_item(tree
, hf_s7comm_data_transport_size
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
6376 proto_tree_add_item_ret_uint(tree
, hf_s7comm_rdrec_statuslen
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &statuslen
);
6378 if (statuslen
> 0) {
6379 proto_tree_add_item(tree
, hf_s7comm_rdrec_statusdata
, tvb
, offset
, statuslen
, ENC_NA
);
6380 offset
+= statuslen
;
6382 offset
+= 1; /* Fillbyte */
6384 if (ret_val
== S7COMM_ITEM_RETVAL_DATA_OK
) {
6385 proto_tree_add_item_ret_uint(tree
, hf_s7comm_rdrec_recordlen
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &reclen
);
6388 proto_tree_add_item(tree
, hf_s7comm_rdrec_data
, tvb
, offset
, reclen
, ENC_NA
);
6397 /*******************************************************************************************************
6399 * PDU Type: User Data -> Function group 2 -> cyclic services
6401 *******************************************************************************************************/
6403 s7comm_decode_ud_cyclic_subfunc(tvbuff_t
*tvb
,
6406 proto_tree
*data_tree
,
6412 bool know_data
= false;
6413 uint32_t offset_old
;
6421 case S7COMM_UD_SUBF_CYCLIC_CHANGE_MOD
:
6422 if (type
== S7COMM_UD_TYPE_REQ
) {
6423 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " JobID=%d", seq_num
);
6426 case S7COMM_UD_SUBF_CYCLIC_TRANSF
:
6427 case S7COMM_UD_SUBF_CYCLIC_CHANGE
:
6428 item_count
= tvb_get_uint8(tvb
, offset
+ 1); /* first byte reserved??? */
6429 proto_tree_add_uint(data_tree
, hf_s7comm_param_itemcount
, tvb
, offset
, 2, item_count
);
6431 if (type
== S7COMM_UD_TYPE_REQ
) {
6432 proto_tree_add_item(data_tree
, hf_s7comm_cycl_interval_timebase
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
6434 proto_tree_add_item(data_tree
, hf_s7comm_cycl_interval_time
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
6436 for (i
= 0; i
< item_count
; i
++) {
6437 offset_old
= offset
;
6438 offset
= s7comm_decode_param_item(tvb
, offset
, data_tree
, i
);
6439 /* if length is not a multiple of 2 and this is not the last item, then add a fill-byte */
6440 len_item
= offset
- offset_old
;
6441 if ((len_item
% 2) && (i
< (item_count
-1))) {
6445 } else if (type
== S7COMM_UD_TYPE_RES
|| type
== S7COMM_UD_TYPE_IND
) {
6446 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " JobID=%d", seq_num
);
6447 offset
= s7comm_decode_response_read_data(tvb
, data_tree
, item_count
, offset
);
6451 case S7COMM_UD_SUBF_CYCLIC_UNSUBSCRIBE
:
6452 if (type
== S7COMM_UD_TYPE_REQ
) {
6453 proto_tree_add_item(data_tree
, hf_s7comm_cycl_function
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
6455 proto_tree_add_item(data_tree
, hf_s7comm_cycl_jobid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
6456 job_id
= tvb_get_uint8(tvb
, offset
);
6457 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " JobID=%d", job_id
);
6460 } else if (type
== S7COMM_UD_TYPE_RES
) {
6461 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " JobID=%d", seq_num
);
6464 case S7COMM_UD_SUBF_CYCLIC_RDREC
:
6465 offset
= s7comm_decode_ud_readrec(tvb
, data_tree
, type
, offset
);
6470 if (know_data
== false && dlength
> 0) {
6471 proto_tree_add_item(data_tree
, hf_s7comm_userdata_data
, tvb
, offset
, dlength
, ENC_NA
);
6477 /*******************************************************************************************************
6479 * PDU Type: User Data: Data part and reassembly
6481 *******************************************************************************************************/
6483 s7comm_decode_ud_data(tvbuff_t
*tvb
,
6491 uint8_t data_unit_ref
,
6492 uint8_t last_data_unit
,
6494 proto_tree
*root_tree
)
6496 proto_item
*item
= NULL
;
6497 proto_tree
*data_tree
= NULL
;
6501 uint32_t length_rem
= 0;
6502 bool save_fragmented
;
6503 uint32_t frag_id
= 0;
6504 bool more_frags
= false;
6505 bool is_fragmented
= false;
6506 tvbuff_t
* new_tvb
= NULL
;
6507 tvbuff_t
* next_tvb
= NULL
;
6508 fragment_head
*fd_head
;
6509 char str_fragadd
[32];
6511 /* The first 4 bytes of the data part of a userdata telegram are the same for all types.
6512 * This is also the minimum length of the data part.
6515 item
= proto_tree_add_item(tree
, hf_s7comm_data
, tvb
, offset
, dlength
, ENC_NA
);
6516 data_tree
= proto_item_add_subtree(item
, ett_s7comm_data
);
6518 ret_val
= tvb_get_uint8(tvb
, offset
);
6519 proto_tree_add_uint(data_tree
, hf_s7comm_data_returncode
, tvb
, offset
, 1, ret_val
);
6521 /* Not definitely known part, kind of "transport size"? constant 0x09, 1 byte
6522 * The position is the same as in a data response/write telegram,
6524 tsize
= tvb_get_uint8(tvb
, offset
);
6525 proto_tree_add_uint(data_tree
, hf_s7comm_data_transport_size
, tvb
, offset
, 1, tsize
);
6527 len
= tvb_get_ntohs(tvb
, offset
);
6528 proto_tree_add_uint(data_tree
, hf_s7comm_data_length
, tvb
, offset
, 2, len
);
6532 more_frags
= (last_data_unit
== S7COMM_UD_LASTDATAUNIT_NO
);
6533 /* Some packets have an additional header before the payload, which must be
6534 * extracted from the data before reassembly.
6536 switch (funcgroup
) {
6537 case S7COMM_UD_FUNCGROUP_NCPRG
:
6538 offset
= s7comm_decode_ud_ncprg_pre_reass(tvb
, data_tree
, type
, subfunc
, &len
, offset
);
6539 /* Unfortunately on NC programming the first PDU is always shown as reassembled also when not fragmented,
6540 * because data_unit_ref may overflow and start again at 0 on big file transfers.
6542 is_fragmented
= true;
6545 case S7COMM_UD_FUNCGROUP_PBC_BSEND
:
6546 /* The R_ID is used for fragment identification */
6547 offset
= s7comm_decode_ud_pbc_bsend_pre_reass(tvb
, pinfo
, data_tree
, type
, &len
, &frag_id
, offset
);
6548 is_fragmented
= data_unit_ref
> 0 || seq_num
> 0;
6550 case S7COMM_UD_FUNCGROUP_CPU
:
6551 if (subfunc
== S7COMM_UD_SUBF_CPU_AR_SEND_IND
) {
6552 offset
= s7comm_decode_ud_cpu_ar_send_pre_reass(tvb
, pinfo
, data_tree
, &len
, offset
);
6554 /* fragment identification is always the same here */
6555 is_fragmented
= (data_unit_ref
> 0);
6556 frag_id
= data_unit_ref
;
6559 is_fragmented
= (data_unit_ref
> 0);
6560 frag_id
= data_unit_ref
;
6563 /* Reassembly of fragmented data part */
6564 save_fragmented
= pinfo
->fragmented
;
6565 if (is_fragmented
) { /* fragmented */
6566 pinfo
->fragmented
= true;
6567 /* NC programming uses a different method of fragment indication. The sequence number is used as reference-id,
6568 * the data unit reference number is increased with every packet, as the sender does not need to wait for
6569 * the acknowledge of the packet. Also different in NC programming is, that also when a packet is not
6570 * fragmented, data_unit_ref is > 0 and "reassembled" would be displayed even when not fragmented (count number of fragments?)
6571 * Using fragment number does not work here, as it's only one byte. And if there are more than 255 fragments this would fail.
6573 fd_head
= fragment_add_seq_next(&s7comm_reassembly_table
,
6575 frag_id
, /* ID for fragments belonging together */
6576 NULL
, /* void *data */
6577 len
, /* fragment length - to the end */
6578 more_frags
); /* More fragments? */
6579 snprintf(str_fragadd
, sizeof(str_fragadd
), " id=%d", frag_id
);
6580 new_tvb
= process_reassembled_data(tvb
, offset
, pinfo
,
6581 "Reassembled S7COMM", fd_head
, &s7comm_frag_items
,
6583 if (new_tvb
) { /* take it all */
6584 /* add reassembly info only when there's more than one fragment */
6585 if (fd_head
&& fd_head
->next
) {
6586 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " (S7COMM reassembled%s)", str_fragadd
);
6587 proto_item_append_text(data_tree
, " (S7COMM reassembled%s)", str_fragadd
);
6591 } else { /* make a new subset */
6592 next_tvb
= tvb_new_subset_length(tvb
, offset
, -1);
6593 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " (S7COMM fragment%s)", str_fragadd
);
6594 proto_item_append_text(data_tree
, " (S7COMM fragment%s)", str_fragadd
);
6597 } else { /* Not fragmented */
6600 pinfo
->fragmented
= save_fragmented
;
6601 length_rem
= tvb_reported_length_remaining(next_tvb
, offset
);
6603 if (last_data_unit
== S7COMM_UD_LASTDATAUNIT_YES
&& length_rem
> 0) {
6604 switch (funcgroup
) {
6605 case S7COMM_UD_FUNCGROUP_TIS
:
6606 offset
= s7comm_decode_ud_tis_subfunc(next_tvb
, data_tree
, type
, subfunc
, offset
);
6608 case S7COMM_UD_FUNCGROUP_CYCLIC
:
6609 offset
= s7comm_decode_ud_cyclic_subfunc(next_tvb
, pinfo
, seq_num
, data_tree
, type
, subfunc
, length_rem
, offset
);
6611 case S7COMM_UD_FUNCGROUP_BLOCK
:
6612 offset
= s7comm_decode_ud_block_subfunc(next_tvb
, pinfo
, data_tree
, type
, subfunc
, ret_val
, tsize
, length_rem
, offset
);
6614 case S7COMM_UD_FUNCGROUP_CPU
:
6616 case S7COMM_UD_SUBF_CPU_READSZL
:
6617 offset
= s7comm_decode_ud_cpu_szl_subfunc(next_tvb
, pinfo
, data_tree
, type
, ret_val
, length_rem
, offset
);
6619 case S7COMM_UD_SUBF_CPU_NOTIFY_IND
:
6620 case S7COMM_UD_SUBF_CPU_NOTIFY8_IND
:
6621 case S7COMM_UD_SUBF_CPU_ALARMSQ_IND
:
6622 case S7COMM_UD_SUBF_CPU_ALARMS_IND
:
6623 case S7COMM_UD_SUBF_CPU_SCAN_IND
:
6624 case S7COMM_UD_SUBF_CPU_ALARMACK
:
6625 case S7COMM_UD_SUBF_CPU_ALARMACK_IND
:
6626 case S7COMM_UD_SUBF_CPU_ALARM8_IND
:
6627 case S7COMM_UD_SUBF_CPU_ALARM8LOCK
:
6628 case S7COMM_UD_SUBF_CPU_ALARM8LOCK_IND
:
6629 case S7COMM_UD_SUBF_CPU_ALARM8UNLOCK
:
6630 case S7COMM_UD_SUBF_CPU_ALARM8UNLOCK_IND
:
6631 offset
= s7comm_decode_ud_cpu_alarm_main(next_tvb
, pinfo
, data_tree
, type
, subfunc
, offset
);
6633 case S7COMM_UD_SUBF_CPU_ALARMQUERY
:
6634 if (type
== S7COMM_UD_TYPE_RES
) {
6635 offset
= s7comm_decode_ud_cpu_alarm_query_response(next_tvb
, data_tree
, offset
);
6637 offset
= s7comm_decode_ud_cpu_alarm_main(next_tvb
, pinfo
, data_tree
, type
, subfunc
, offset
);
6640 case S7COMM_UD_SUBF_CPU_DIAGMSG
:
6641 offset
= s7comm_decode_ud_cpu_diagnostic_message(next_tvb
, pinfo
, true, data_tree
, offset
);
6643 case S7COMM_UD_SUBF_CPU_MSGS
:
6644 offset
= s7comm_decode_message_service(next_tvb
, pinfo
, data_tree
, type
, length_rem
, offset
);
6646 case S7COMM_UD_SUBF_CPU_AR_SEND_IND
:
6647 offset
= s7comm_decode_ud_cpu_ar_send(next_tvb
, data_tree
, offset
);
6650 /* print other currently unknown data as raw bytes */
6651 proto_tree_add_item(data_tree
, hf_s7comm_userdata_data
, next_tvb
, offset
, length_rem
, ENC_NA
);
6655 case S7COMM_UD_FUNCGROUP_SEC
:
6656 offset
= s7comm_decode_ud_security_subfunc(next_tvb
, data_tree
, length_rem
, offset
);
6658 case S7COMM_UD_FUNCGROUP_PBC_BSEND
:
6659 offset
= s7comm_decode_ud_pbc_bsend_subfunc(next_tvb
, data_tree
, length_rem
, offset
, pinfo
, root_tree
);
6661 case S7COMM_UD_FUNCGROUP_TIME
:
6662 offset
= s7comm_decode_ud_time_subfunc(next_tvb
, data_tree
, type
, subfunc
, ret_val
, length_rem
, offset
);
6664 case S7COMM_UD_FUNCGROUP_NCPRG
:
6665 offset
= s7comm_decode_ud_ncprg_subfunc(next_tvb
, pinfo
, data_tree
, type
, subfunc
, length_rem
, offset
);
6667 case S7COMM_UD_FUNCGROUP_DRR
:
6668 offset
= s7comm_decode_ud_drr_subfunc(next_tvb
, data_tree
, length_rem
, offset
);
6679 /*******************************************************************************************************
6680 *******************************************************************************************************
6682 * PDU Type: User Data
6684 *******************************************************************************************************
6685 *******************************************************************************************************/
6687 s7comm_decode_ud(tvbuff_t
*tvb
,
6693 proto_tree
*root_tree
)
6695 proto_item
*item
= NULL
;
6696 proto_tree
*param_tree
= NULL
;
6699 uint32_t offset_temp
;
6705 uint8_t data_unit_ref
= 0;
6706 uint8_t last_data_unit
= 0;
6709 uint8_t varspec_syntax_id
= 0;
6711 /* Add parameter tree */
6712 item
= proto_tree_add_item(tree
, hf_s7comm_param
, tvb
, offset
, plength
, ENC_NA
);
6713 param_tree
= proto_item_add_subtree(item
, ett_s7comm_param
);
6715 offset_temp
= offset
;
6717 function
= tvb_get_uint8(tvb
, offset_temp
);
6718 proto_tree_add_uint(param_tree
, hf_s7comm_param_service
, tvb
, offset_temp
, 1, function
);
6721 /* It's like an itemcounter, but only the value of 1 is allowed. */
6722 proto_tree_add_item(param_tree
, hf_s7comm_param_itemcount
, tvb
, offset_temp
, 1, ENC_BIG_ENDIAN
);
6725 if (function
== S7COMM_SERV_MODETRANS
) {
6726 /* Mode transition indication needs a separate handling */
6727 proto_item_append_text(param_tree
, ": ->(Mode transition indication)");
6728 col_append_str(pinfo
->cinfo
, COL_INFO
, " Function:[Mode transition indication]");
6729 proto_tree_add_item(param_tree
, hf_s7comm_modetrans_param_unknown1
, tvb
, offset_temp
, 4, ENC_BIG_ENDIAN
);
6731 mode
= tvb_get_uint8(tvb
, offset_temp
);
6732 proto_tree_add_uint(param_tree
, hf_s7comm_modetrans_param_mode
, tvb
, offset_temp
, 1, mode
);
6734 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> [%s]",
6735 val_to_str(mode
, modetrans_param_mode_names
, "Unknown mode: 0x%02x"));
6736 proto_item_append_text(param_tree
, " ->(%s)", val_to_str(mode
, modetrans_param_mode_names
, "Unknown mode: 0x%02x"));
6737 proto_tree_add_item(param_tree
, hf_s7comm_modetrans_param_unknown2
, tvb
, offset_temp
, 1, ENC_BIG_ENDIAN
);
6739 /* No data part here */
6743 proto_tree_add_item(param_tree
, hf_s7comm_item_varspec
, tvb
, offset_temp
, 1, ENC_BIG_ENDIAN
);
6745 proto_tree_add_item(param_tree
, hf_s7comm_item_varspec_length
, tvb
, offset_temp
, 1, ENC_BIG_ENDIAN
);
6747 varspec_syntax_id
= tvb_get_uint8(tvb
, offset_temp
);
6748 proto_tree_add_item(param_tree
, hf_s7comm_item_syntax_id
, tvb
, offset_temp
, 1, ENC_BIG_ENDIAN
);
6751 if (varspec_syntax_id
== S7COMM_SYNTAXID_PBC_ID
) {
6752 /* When the R_ID occurs here, it's USEND and needs a separate handling */
6753 proto_item_append_text(param_tree
, ": (Indication) ->(USEND)");
6754 col_append_str(pinfo
->cinfo
, COL_INFO
, " Function:[Indication] -> [USEND]");
6755 proto_tree_add_item(param_tree
, hf_s7comm_pbc_unknown
, tvb
, offset_temp
, 1, ENC_BIG_ENDIAN
);
6757 proto_tree_add_item_ret_uint(param_tree
, hf_s7comm_pbc_usend_r_id
, tvb
, offset_temp
, 4, ENC_BIG_ENDIAN
, &r_id
);
6758 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " R_ID=0x%X", r_id
);
6759 /* USEND data must fit in a single PDU. Fragmentation is not possible and we can dissect the data part here. */
6760 offset
+= plength
; /* To start of data part */
6761 offset
= s7comm_decode_ud_usend(tvb
, tree
, dlength
, offset
);
6762 /* Return here as all data is decoded */
6766 /* Left 2 bits for indication/request/response
6767 * Right 6 bits for the function group
6769 type
= (tvb_get_uint8(tvb
, offset_temp
) & 0xc0) >> 6;
6770 funcgroup
= (tvb_get_uint8(tvb
, offset_temp
) & 0x3f);
6771 proto_tree_add_item(param_tree
, hf_s7comm_userdata_param_type
, tvb
, offset_temp
, 1, ENC_BIG_ENDIAN
);
6772 proto_tree_add_item(param_tree
, hf_s7comm_userdata_param_funcgroup
, tvb
, offset_temp
, 1, ENC_BIG_ENDIAN
);
6775 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " Function:[%s] -> [%s]",
6776 val_to_str(type
, userdata_type_names
, "Unknown type: 0x%02x"),
6777 val_to_str(funcgroup
, userdata_functiongroup_names
, "Unknown function group: 0x%02x")
6779 proto_item_append_text(param_tree
, ": (%s)", val_to_str(type
, userdata_type_names
, "Unknown type: 0x%02x"));
6780 proto_item_append_text(param_tree
, " ->(%s)", val_to_str(funcgroup
, userdata_functiongroup_names
, "Unknown function group: 0x%02x"));
6782 /* 1 Byte subfunction */
6783 subfunc
= tvb_get_uint8(tvb
, offset_temp
);
6784 switch (funcgroup
) {
6785 case S7COMM_UD_FUNCGROUP_TIS
:
6786 proto_tree_add_uint(param_tree
, hf_s7comm_userdata_param_subfunc_prog
, tvb
, offset_temp
, 1, subfunc
);
6787 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> [%s]",
6788 val_to_str(subfunc
, userdata_tis_subfunc_names
, "Unknown subfunc: 0x%02x"));
6789 proto_item_append_text(param_tree
, " ->(%s)", val_to_str(subfunc
, userdata_tis_subfunc_names
, "Unknown subfunc: 0x%02x"));
6791 case S7COMM_UD_FUNCGROUP_CYCLIC
:
6792 proto_tree_add_uint(param_tree
, hf_s7comm_userdata_param_subfunc_cyclic
, tvb
, offset_temp
, 1, subfunc
);
6793 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> [%s]",
6794 val_to_str(subfunc
, userdata_cyclic_subfunc_names
, "Unknown subfunc: 0x%02x"));
6795 proto_item_append_text(param_tree
, " ->(%s)", val_to_str(subfunc
, userdata_cyclic_subfunc_names
, "Unknown subfunc: 0x%02x"));
6797 case S7COMM_UD_FUNCGROUP_BLOCK
:
6798 proto_tree_add_uint(param_tree
, hf_s7comm_userdata_param_subfunc_block
, tvb
, offset_temp
, 1, subfunc
);
6799 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> [%s]",
6800 val_to_str(subfunc
, userdata_block_subfunc_names
, "Unknown subfunc: 0x%02x"));
6801 proto_item_append_text(param_tree
, " ->(%s)", val_to_str(subfunc
, userdata_block_subfunc_names
, "Unknown subfunc: 0x%02x"));
6803 case S7COMM_UD_FUNCGROUP_CPU
:
6804 proto_tree_add_uint(param_tree
, hf_s7comm_userdata_param_subfunc_cpu
, tvb
, offset_temp
, 1, subfunc
);
6805 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> [%s]",
6806 val_to_str(subfunc
, userdata_cpu_subfunc_names
, "Unknown subfunc: 0x%02x"));
6807 proto_item_append_text(param_tree
, " ->(%s)", val_to_str(subfunc
, userdata_cpu_subfunc_names
, "Unknown subfunc: 0x%02x"));
6809 case S7COMM_UD_FUNCGROUP_SEC
:
6810 proto_tree_add_uint(param_tree
, hf_s7comm_userdata_param_subfunc_sec
, tvb
, offset_temp
, 1, subfunc
);
6811 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> [%s]",
6812 val_to_str(subfunc
, userdata_sec_subfunc_names
, "Unknown subfunc: 0x%02x"));
6813 proto_item_append_text(param_tree
, " ->(%s)", val_to_str(subfunc
, userdata_sec_subfunc_names
, "Unknown subfunc: 0x%02x"));
6815 case S7COMM_UD_FUNCGROUP_TIME
:
6816 proto_tree_add_uint(param_tree
, hf_s7comm_userdata_param_subfunc_time
, tvb
, offset_temp
, 1, subfunc
);
6817 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> [%s]",
6818 val_to_str(subfunc
, userdata_time_subfunc_names
, "Unknown subfunc: 0x%02x"));
6819 proto_item_append_text(param_tree
, " ->(%s)", val_to_str(subfunc
, userdata_time_subfunc_names
, "Unknown subfunc: 0x%02x"));
6821 case S7COMM_UD_FUNCGROUP_DRR
:
6822 proto_tree_add_uint(param_tree
, hf_s7comm_userdata_param_subfunc_drr
, tvb
, offset_temp
, 1, subfunc
);
6823 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> [%s]",
6824 val_to_str(subfunc
, userdata_drr_subfunc_names
, "Unknown subfunc: 0x%02x"));
6825 proto_item_append_text(param_tree
, " ->(%s)", val_to_str(subfunc
, userdata_drr_subfunc_names
, "Unknown subfunc: 0x%02x"));
6827 case S7COMM_UD_FUNCGROUP_NCPRG
:
6828 proto_tree_add_uint(param_tree
, hf_s7comm_userdata_param_subfunc_ncprg
, tvb
, offset_temp
, 1, subfunc
);
6829 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> [%s]",
6830 val_to_str(subfunc
, userdata_ncprg_subfunc_names
, "Unknown subfunc: 0x%02x"));
6831 proto_item_append_text(param_tree
, " ->(%s)", val_to_str(subfunc
, userdata_ncprg_subfunc_names
, "Unknown subfunc: 0x%02x"));
6834 proto_tree_add_uint(param_tree
, hf_s7comm_userdata_param_subfunc
, tvb
, offset_temp
, 1, subfunc
);
6838 /* 1 Byte sequence number */
6839 seq_num
= tvb_get_uint8(tvb
, offset_temp
);
6840 proto_tree_add_item(param_tree
, hf_s7comm_userdata_param_seq_num
, tvb
, offset_temp
, 1, ENC_BIG_ENDIAN
);
6842 if (varspec_syntax_id
== S7COMM_SYNTAXID_EXT
) {
6843 /* 1 Byte data unit reference. If packet is fragmented, all packets with this number belong together.
6844 * But there are function which use a different fragment identification methon.
6846 data_unit_ref
= tvb_get_uint8(tvb
, offset_temp
);
6847 proto_tree_add_item(param_tree
, hf_s7comm_userdata_param_dataunitref
, tvb
, offset_temp
, 1, ENC_BIG_ENDIAN
);
6849 /* 1 Byte fragmented flag, if this is not the last data unit (telegram is fragmented) this is != 0 */
6850 last_data_unit
= tvb_get_uint8(tvb
, offset_temp
);
6851 proto_tree_add_item(param_tree
, hf_s7comm_userdata_param_dataunit
, tvb
, offset_temp
, 1, ENC_BIG_ENDIAN
);
6853 proto_tree_add_item_ret_uint(param_tree
, hf_s7comm_param_errcod
, tvb
, offset_temp
, 2, ENC_BIG_ENDIAN
, &errorcode
);
6854 if (errorcode
> 0) {
6855 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> Errorcode:[0x%04x]", errorcode
);
6860 offset
= s7comm_decode_ud_data(tvb
, pinfo
, tree
, dlength
, type
, funcgroup
, subfunc
, seq_num
, data_unit_ref
, last_data_unit
, offset
, root_tree
);
6865 /*******************************************************************************************************
6867 * PDU Type: Request or Response
6869 *******************************************************************************************************/
6871 s7comm_decode_req_resp(tvbuff_t
*tvb
,
6879 proto_item
*item
= NULL
;
6880 proto_tree
*param_tree
= NULL
;
6881 proto_tree
*data_tree
= NULL
;
6882 uint8_t function
= 0;
6883 uint8_t item_count
= 0;
6885 uint32_t offset_old
;
6889 /* Add parameter tree */
6890 item
= proto_tree_add_item(tree
, hf_s7comm_param
, tvb
, offset
, plength
, ENC_NA
);
6891 param_tree
= proto_item_add_subtree(item
, ett_s7comm_param
);
6892 /* Analyze function */
6893 function
= tvb_get_uint8(tvb
, offset
);
6894 /* add param.function to info column */
6895 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " Function:[%s]", val_to_str(function
, param_functionnames
, "Unknown function: 0x%02x"));
6896 proto_tree_add_uint(param_tree
, hf_s7comm_param_service
, tvb
, offset
, 1, function
);
6897 /* show param.function code at the tree */
6898 proto_item_append_text(param_tree
, ": (%s)", val_to_str(function
, param_functionnames
, "Unknown function: 0x%02x"));
6901 if (rosctr
== S7COMM_ROSCTR_JOB
) {
6903 case S7COMM_SERV_READVAR
:
6904 case S7COMM_SERV_WRITEVAR
:
6905 item_count
= tvb_get_uint8(tvb
, offset
);
6906 proto_tree_add_uint(param_tree
, hf_s7comm_param_itemcount
, tvb
, offset
, 1, item_count
);
6908 /* parse item data */
6909 for (i
= 0; i
< item_count
; i
++) {
6910 offset_old
= offset
;
6911 offset
= s7comm_decode_param_item(tvb
, offset
, param_tree
, i
);
6912 /* if length is not a multiple of 2 and this is not the last item, then add a fill-byte */
6913 len
= offset
- offset_old
;
6914 if ((len
% 2) && (i
< (item_count
-1))) {
6918 /* in write-function there is a data part */
6919 if ((function
== S7COMM_SERV_WRITEVAR
) && (dlength
> 0)) {
6920 item
= proto_tree_add_item(tree
, hf_s7comm_data
, tvb
, offset
, dlength
, ENC_NA
);
6921 data_tree
= proto_item_add_subtree(item
, ett_s7comm_data
);
6922 /* Add returned data to data-tree */
6923 offset
= s7comm_decode_response_read_data(tvb
, data_tree
, item_count
, offset
);
6926 case S7COMM_SERV_SETUPCOMM
:
6927 offset
= s7comm_decode_pdu_setup_communication(tvb
, param_tree
, offset
);
6929 /* Special functions */
6930 case S7COMM_FUNCREQUESTDOWNLOAD
:
6931 case S7COMM_FUNCDOWNLOADBLOCK
:
6932 case S7COMM_FUNCDOWNLOADENDED
:
6933 case S7COMM_FUNCSTARTUPLOAD
:
6934 case S7COMM_FUNCUPLOAD
:
6935 case S7COMM_FUNCENDUPLOAD
:
6936 offset
= s7comm_decode_plc_controls_updownload(tvb
, pinfo
, tree
, param_tree
, plength
, dlength
, offset
-1, rosctr
);
6938 case S7COMM_FUNCPISERVICE
:
6939 offset
= s7comm_decode_pi_service(tvb
, pinfo
, param_tree
, plength
, offset
-1);
6941 case S7COMM_FUNC_PLC_STOP
:
6942 offset
= s7comm_decode_plc_controls_param_hex29(tvb
, param_tree
, offset
-1);
6946 /* Print unknown part as raw bytes */
6948 proto_tree_add_item(param_tree
, hf_s7comm_param_data
, tvb
, offset
, plength
- 1, ENC_NA
);
6950 offset
+= plength
- 1; /* 1 byte function code */
6953 * First 2 bytes in data seem to be a length indicator of (dlength -4 ), so next 2 bytes
6954 * seem to indicate something else. But I'm not sure, so leave it as it is.....
6956 item
= proto_tree_add_item(tree
, hf_s7comm_data
, tvb
, offset
, dlength
, ENC_NA
);
6957 data_tree
= proto_item_add_subtree(item
, ett_s7comm_data
);
6958 proto_tree_add_item(data_tree
, hf_s7comm_readresponse_data
, tvb
, offset
, dlength
, ENC_NA
);
6963 } else if (rosctr
== S7COMM_ROSCTR_ACK_DATA
) {
6965 case S7COMM_SERV_READVAR
:
6966 case S7COMM_SERV_WRITEVAR
:
6967 /* This is a read-response, so the requested data may follow when address in request was ok */
6968 item_count
= tvb_get_uint8(tvb
, offset
);
6969 proto_tree_add_uint(param_tree
, hf_s7comm_param_itemcount
, tvb
, offset
, 1, item_count
);
6972 item
= proto_tree_add_item(tree
, hf_s7comm_data
, tvb
, offset
, dlength
, ENC_NA
);
6973 data_tree
= proto_item_add_subtree(item
, ett_s7comm_data
);
6974 /* Add returned data to data-tree */
6975 if ((function
== S7COMM_SERV_READVAR
) && (dlength
> 0)) {
6976 offset
= s7comm_decode_response_read_data(tvb
, data_tree
, item_count
, offset
);
6977 } else if ((function
== S7COMM_SERV_WRITEVAR
) && (dlength
> 0)) {
6978 offset
= s7comm_decode_response_write_data(tvb
, data_tree
, item_count
, offset
);
6981 case S7COMM_SERV_SETUPCOMM
:
6982 offset
= s7comm_decode_pdu_setup_communication(tvb
, param_tree
, offset
);
6984 case S7COMM_FUNCREQUESTDOWNLOAD
:
6985 case S7COMM_FUNCDOWNLOADBLOCK
:
6986 case S7COMM_FUNCDOWNLOADENDED
:
6987 case S7COMM_FUNCSTARTUPLOAD
:
6988 case S7COMM_FUNCUPLOAD
:
6989 case S7COMM_FUNCENDUPLOAD
:
6990 offset
= s7comm_decode_plc_controls_updownload(tvb
, pinfo
, tree
, param_tree
, plength
, dlength
, offset
-1, rosctr
);
6992 case S7COMM_FUNCPISERVICE
:
6994 proto_tree_add_bitmask(param_tree
, tvb
, offset
, hf_s7comm_data_blockcontrol_functionstatus
,
6995 ett_s7comm_data_blockcontrol_status
, s7comm_data_blockcontrol_status_fields
, ENC_BIG_ENDIAN
);
7000 /* Print unknown part as raw bytes */
7002 proto_tree_add_item(param_tree
, hf_s7comm_param_data
, tvb
, offset
, plength
- 1, ENC_NA
);
7004 offset
+= plength
- 1; /* 1 byte function code */
7007 * First 2 bytes in data seem to be a length indicator of (dlength -4 ), so next 2 bytes
7008 * seem to indicate something else. But I'm not sure, so leave it as it is.....
7010 item
= proto_tree_add_item(tree
, hf_s7comm_data
, tvb
, offset
, dlength
, ENC_NA
);
7011 data_tree
= proto_item_add_subtree(item
, ett_s7comm_data
);
7012 proto_tree_add_item(data_tree
, hf_s7comm_readresponse_data
, tvb
, offset
, dlength
, ENC_NA
);
7022 /*******************************************************************************************************
7023 *******************************************************************************************************
7025 * S7-Protocol (main tree)
7027 *******************************************************************************************************
7028 *******************************************************************************************************/
7030 dissect_s7comm(tvbuff_t
*tvb
,
7035 proto_item
*s7comm_item
= NULL
;
7036 proto_item
*s7comm_sub_item
= NULL
;
7037 proto_tree
*s7comm_tree
= NULL
;
7038 proto_tree
*s7comm_header_tree
= NULL
;
7040 uint32_t offset
= 0;
7043 uint8_t hlength
= 10; /* Header 10 Bytes, when type 2 or 3 (Response) -> 12 Bytes */
7044 uint16_t plength
= 0;
7045 uint16_t dlength
= 0;
7046 uint16_t errorcode
= 0;
7048 /*----------------- Heuristic Checks - Begin */
7049 /* 1) check for minimum length */
7050 if(tvb_captured_length(tvb
) < S7COMM_MIN_TELEGRAM_LENGTH
)
7052 /* 2) first byte must be 0x32 */
7053 if (tvb_get_uint8(tvb
, 0) != S7COMM_PROT_ID
)
7055 /* 3) second byte is a type field and only can contain values between 0x01-0x07 (1/2/3/7) */
7056 if (tvb_get_uint8(tvb
, 1) < 0x01 || tvb_get_uint8(tvb
, 1) > 0x07)
7058 /*----------------- Heuristic Checks - End */
7060 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, PROTO_TAG_S7COMM
);
7061 col_clear(pinfo
->cinfo
, COL_INFO
);
7062 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, " | ", "");
7064 rosctr
= tvb_get_uint8(tvb
, 1); /* Get the type byte */
7065 if (rosctr
== 2 || rosctr
== 3) hlength
= 12; /* Header 10 Bytes, when type 2 or 3 (response) -> 12 Bytes */
7067 /* display some infos in info-column of wireshark */
7068 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "ROSCTR:[%-8s]", val_to_str(rosctr
, rosctr_names
, "Unknown: 0x%02x"));
7070 s7comm_item
= proto_tree_add_item(tree
, proto_s7comm
, tvb
, 0, -1, ENC_NA
);
7071 s7comm_tree
= proto_item_add_subtree(s7comm_item
, ett_s7comm
);
7073 /* insert header tree */
7074 s7comm_sub_item
= proto_tree_add_item(s7comm_tree
, hf_s7comm_header
,
7075 tvb
, offset
, hlength
, ENC_NA
);
7077 /* insert sub-items in header tree */
7078 s7comm_header_tree
= proto_item_add_subtree(s7comm_sub_item
, ett_s7comm_header
);
7080 /* Protocol Identifier, constant 0x32 */
7081 proto_tree_add_item(s7comm_header_tree
, hf_s7comm_header_protid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
7084 /* ROSCTR (Remote Operating Service Control) - PDU Type */
7085 proto_tree_add_uint(s7comm_header_tree
, hf_s7comm_header_rosctr
, tvb
, offset
, 1, rosctr
);
7086 /* Show pdu type beside the header tree */
7087 proto_item_append_text(s7comm_header_tree
, ": (%s)", val_to_str(rosctr
, rosctr_names
, "Unknown ROSCTR: 0x%02x"));
7089 /* Redundancy ID, reserved */
7090 proto_tree_add_item(s7comm_header_tree
, hf_s7comm_header_redid
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
7092 /* Protocol Data Unit Reference */
7093 proto_tree_add_item(s7comm_header_tree
, hf_s7comm_header_pduref
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
7095 /* Parameter length */
7096 plength
= tvb_get_ntohs(tvb
, offset
);
7097 proto_tree_add_uint(s7comm_header_tree
, hf_s7comm_header_parlg
, tvb
, offset
, 2, plength
);
7100 dlength
= tvb_get_ntohs(tvb
, offset
);
7101 proto_tree_add_uint(s7comm_header_tree
, hf_s7comm_header_datlg
, tvb
, offset
, 2, dlength
);
7103 /* when type is 2 or 3 there are 2 bytes with errorclass and errorcode */
7104 if (hlength
== 12) {
7105 errorcode
= tvb_get_ntohs(tvb
, offset
); /* this uses the same errorcodes (combined) from parameter part */
7106 proto_tree_add_item(s7comm_header_tree
, hf_s7comm_header_errcls
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
7108 proto_tree_add_item(s7comm_header_tree
, hf_s7comm_header_errcod
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
7110 /* when there is an error, use the errorcode from parameterpart*/
7111 if (errorcode
> 0) {
7112 s7comm_item
= proto_tree_add_item(s7comm_header_tree
, hf_s7comm_param_errcod
, tvb
, offset
-2, 2, ENC_BIG_ENDIAN
);
7113 proto_item_set_generated (s7comm_item
);
7118 case S7COMM_ROSCTR_JOB
:
7119 case S7COMM_ROSCTR_ACK_DATA
:
7120 s7comm_decode_req_resp(tvb
, pinfo
, s7comm_tree
, plength
, dlength
, offset
, rosctr
);
7122 case S7COMM_ROSCTR_USERDATA
:
7123 s7comm_decode_ud(tvb
, pinfo
, s7comm_tree
, plength
, dlength
, offset
, tree
);
7126 /* Add the errorcode from header as last entry in info column */
7127 if (errorcode
> 0) {
7128 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> Errorcode:[0x%04x]", errorcode
);
7130 /* set fence as there may be more than one S7comm PDU in one frame */
7131 col_set_fence(pinfo
->cinfo
, COL_INFO
);
7135 /*******************************************************************************************************
7136 * Reassembly of S7COMM
7137 *******************************************************************************************************/
7139 s7comm_defragment_init(void)
7141 reassembly_table_init(&s7comm_reassembly_table
,
7142 &addresses_ports_reassembly_table_functions
);
7145 /*******************************************************************************************************
7146 *******************************************************************************************************/
7148 proto_register_s7comm (void)
7150 expert_module_t
* expert_s7comm
;
7153 * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
7155 static hf_register_info hf
[] = {
7156 { &hf_s7comm_header
,
7157 { "Header", "s7comm.header", FT_NONE
, BASE_NONE
, NULL
, 0x0,
7158 "This is the header of S7 communication", HFILL
}},
7159 { &hf_s7comm_header_protid
,
7160 { "Protocol Id", "s7comm.header.protid", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7161 "Protocol Identification, 0x32 for S7", HFILL
}},
7162 { &hf_s7comm_header_rosctr
,
7163 { "ROSCTR", "s7comm.header.rosctr", FT_UINT8
, BASE_DEC
, VALS(rosctr_names
), 0x0,
7164 "Remote Operating Service Control", HFILL
}},
7165 { &hf_s7comm_header_redid
,
7166 { "Redundancy Identification (Reserved)", "s7comm.header.redid", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
7167 "Redundancy Identification (Reserved), should be always 0x0000", HFILL
}},
7168 { &hf_s7comm_header_pduref
,
7169 { "Protocol Data Unit Reference", "s7comm.header.pduref", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7171 { &hf_s7comm_header_parlg
,
7172 { "Parameter length", "s7comm.header.parlg", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7173 "Specifies the entire length of the parameter block in bytes", HFILL
}},
7174 { &hf_s7comm_header_datlg
,
7175 { "Data length", "s7comm.header.datlg", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7176 "Specifies the entire length of the data block in bytes", HFILL
}},
7177 { &hf_s7comm_header_errcls
,
7178 { "Error class", "s7comm.header.errcls", FT_UINT8
, BASE_HEX
, VALS(errcls_names
), 0x0,
7180 { &hf_s7comm_header_errcod
,
7181 { "Error code", "s7comm.header.errcod", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7185 { "Parameter", "s7comm.param", FT_NONE
, BASE_NONE
, NULL
, 0x0,
7186 "This is the parameter part of S7 communication", HFILL
}},
7187 { &hf_s7comm_param_errcod
,
7188 { "Error code", "s7comm.param.errcod", FT_UINT16
, BASE_HEX
| BASE_EXT_STRING
, ¶m_errcode_names_ext
, 0x0,
7190 { &hf_s7comm_param_service
,
7191 { "Function", "s7comm.param.func", FT_UINT8
, BASE_HEX
, VALS(param_functionnames
), 0x0,
7192 "Indicates the function of parameter/data", HFILL
}},
7193 { &hf_s7comm_param_maxamq_calling
,
7194 { "Max AmQ (parallel jobs with ack) calling", "s7comm.param.maxamq_calling", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7196 { &hf_s7comm_param_maxamq_called
,
7197 { "Max AmQ (parallel jobs with ack) called", "s7comm.param.maxamq_called", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7199 { &hf_s7comm_param_setup_reserved1
,
7200 { "Reserved", "s7comm.param.setup_reserved1", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7202 { &hf_s7comm_param_neg_pdu_length
,
7203 { "PDU length", "s7comm.param.pdu_length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7204 "Negotiated PDU length", HFILL
}},
7205 { &hf_s7comm_param_itemcount
,
7206 { "Item count", "s7comm.param.itemcount", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7207 "Number of Items in parameter/data part", HFILL
}},
7208 { &hf_s7comm_param_data
,
7209 { "Parameter data", "s7comm.param.data", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
7211 { &hf_s7comm_param_item
,
7212 { "Item", "s7comm.param.item", FT_NONE
, BASE_NONE
, NULL
, 0x0,
7214 { &hf_s7comm_param_subitem
,
7215 { "Subitem", "s7comm.param.subitem", FT_NONE
, BASE_NONE
, NULL
, 0x0,
7217 { &hf_s7comm_item_varspec
,
7218 { "Variable specification", "s7comm.param.item.varspec", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7220 { &hf_s7comm_item_varspec_length
,
7221 { "Length of following address specification", "s7comm.param.item.varspec_length", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7223 { &hf_s7comm_item_syntax_id
,
7224 { "Syntax Id", "s7comm.param.item.syntaxid", FT_UINT8
, BASE_HEX
, VALS(item_syntaxid_names
), 0x0,
7225 "Syntax Id, format type of following address specification", HFILL
}},
7226 { &hf_s7comm_item_transport_size
,
7227 { "Transport size", "s7comm.param.item.transp_size", FT_UINT8
, BASE_DEC
, VALS(item_transportsizenames
), 0x0,
7229 { &hf_s7comm_item_length
,
7230 { "Length", "s7comm.param.item.length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7232 { &hf_s7comm_item_db
,
7233 { "DB number", "s7comm.param.item.db", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7235 { &hf_s7comm_item_area
,
7236 { "Area", "s7comm.param.item.area", FT_UINT8
, BASE_HEX
, VALS(item_areanames
), 0x0,
7238 { &hf_s7comm_item_address
,
7239 { "Address", "s7comm.param.item.address", FT_UINT24
, BASE_HEX
, NULL
, 0x0,
7241 { &hf_s7comm_item_address_byte
,
7242 { "Byte Address", "s7comm.param.item.address.byte", FT_UINT24
, BASE_DEC
, NULL
, 0x07fff8,
7244 { &hf_s7comm_item_address_bit
,
7245 { "Bit Address", "s7comm.param.item.address.bit", FT_UINT24
, BASE_DEC
, NULL
, 0x000007,
7247 { &hf_s7comm_item_address_nr
,
7248 { "Number (T/C/BLOCK)", "s7comm.param.item.address.number", FT_UINT24
, BASE_DEC
, NULL
, 0x00ffff,
7250 /* Special variable read with Syntax-Id 0xb0 (DBREAD) */
7251 { &hf_s7comm_item_dbread_numareas
,
7252 { "Number of areas", "s7comm.param.item.dbread.numareas", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7253 "Number of area specifications following", HFILL
}},
7254 { &hf_s7comm_item_dbread_length
,
7255 { "Bytes to read", "s7comm.param.item.dbread.length", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7256 "Number of bytes to read", HFILL
}},
7257 { &hf_s7comm_item_dbread_db
,
7258 { "DB number", "s7comm.param.item.dbread.db", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7260 { &hf_s7comm_item_dbread_startadr
,
7261 { "Start address", "s7comm.param.item.dbread.startaddress", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7263 /* Reading frequency inverter parameters via routing */
7264 { &hf_s7comm_item_driveesany_unknown1
,
7265 { "DriveES Unknown 1", "s7comm.param.item.driveesany.unknown1", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7267 { &hf_s7comm_item_driveesany_unknown2
,
7268 { "DriveES Unknown 2", "s7comm.param.item.driveesany.unknown2", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7270 { &hf_s7comm_item_driveesany_unknown3
,
7271 { "DriveES Unknown 3", "s7comm.param.item.driveesany.unknown3", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
7273 { &hf_s7comm_item_driveesany_parameter_nr
,
7274 { "DriveES Parameter number", "s7comm.param.item.driveesany.parameternr", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7276 { &hf_s7comm_item_driveesany_parameter_idx
,
7277 { "DriveES Parameter index", "s7comm.param.item.driveesany.parameteridx", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7279 /* NCK access with Syntax-Id 0x82 */
7280 { &hf_s7comm_item_nck_areaunit
,
7281 { "NCK Area/Unit", "s7comm.param.item.nck.area_unit", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7282 "NCK Area/Unit: Bitmask aaauuuuu: a=area, u=unit", HFILL
}},
7283 { &hf_s7comm_item_nck_area
,
7284 { "NCK Area", "s7comm.param.item.nck.area", FT_UINT8
, BASE_DEC
, VALS(nck_area_names
), 0xe0,
7286 { &hf_s7comm_item_nck_unit
,
7287 { "NCK Unit", "s7comm.param.item.nck.unit", FT_UINT8
, BASE_DEC
, NULL
, 0x1f,
7289 { &hf_s7comm_item_nck_column
,
7290 { "NCK Column number", "s7comm.param.item.nck.column", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7292 { &hf_s7comm_item_nck_line
,
7293 { "NCK Line number", "s7comm.param.item.nck.line", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7295 { &hf_s7comm_item_nck_module
,
7296 { "NCK Module", "s7comm.param.item.nck.module", FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
, &nck_module_names_ext
, 0x0,
7298 { &hf_s7comm_item_nck_linecount
,
7299 { "NCK Linecount", "s7comm.param.item.nck.linecount", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7303 { "Data", "s7comm.data", FT_NONE
, BASE_NONE
, NULL
, 0x0,
7304 "This is the data part of S7 communication", HFILL
}},
7305 { &hf_s7comm_data_returncode
,
7306 { "Return code", "s7comm.data.returncode", FT_UINT8
, BASE_HEX
, VALS(s7comm_item_return_valuenames
), 0x0,
7308 { &hf_s7comm_data_transport_size
,
7309 { "Transport size", "s7comm.data.transportsize", FT_UINT8
, BASE_HEX
, VALS(data_transportsizenames
), 0x0,
7310 "Data type / Transport size. If 3, 4 or 5 the following length gives the number of bits, otherwise the number of bytes.", HFILL
}},
7311 { &hf_s7comm_data_length
,
7312 { "Length", "s7comm.data.length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7313 "Length of data", HFILL
}},
7315 { &hf_s7comm_data_item
,
7316 { "Item", "s7comm.data.item", FT_NONE
, BASE_NONE
, NULL
, 0x0,
7319 { &hf_s7comm_readresponse_data
,
7320 { "Data", "s7comm.resp.data", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
7322 { &hf_s7comm_data_fillbyte
,
7323 { "Fill byte", "s7comm.data.fillbyte", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7326 { &hf_s7comm_userdata_data
,
7327 { "Data", "s7comm.data.userdata", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
7328 "Userdata data", HFILL
}},
7330 /* Userdata parameter 8/12 Bytes len*/
7331 { &hf_s7comm_userdata_param_type
,
7332 { "Type", "s7comm.param.userdata.type", FT_UINT8
, BASE_DEC
, VALS(userdata_type_names
), 0xc0,
7333 "Type of parameter", HFILL
}},
7334 { &hf_s7comm_userdata_param_funcgroup
,
7335 { "Function group", "s7comm.param.userdata.funcgroup", FT_UINT8
, BASE_DEC
, VALS(userdata_functiongroup_names
), 0x3f,
7338 { &hf_s7comm_userdata_param_subfunc_prog
,
7339 { "Subfunction", "s7comm.param.userdata.subfunc", FT_UINT8
, BASE_DEC
, VALS(userdata_tis_subfunc_names
), 0x0,
7341 { &hf_s7comm_userdata_param_subfunc_cyclic
,
7342 { "Subfunction", "s7comm.param.userdata.subfunc", FT_UINT8
, BASE_DEC
, VALS(userdata_cyclic_subfunc_names
), 0x0,
7344 { &hf_s7comm_userdata_param_subfunc_block
,
7345 { "Subfunction", "s7comm.param.userdata.subfunc", FT_UINT8
, BASE_DEC
, VALS(userdata_block_subfunc_names
), 0x0,
7347 { &hf_s7comm_userdata_param_subfunc_cpu
,
7348 { "Subfunction", "s7comm.param.userdata.subfunc", FT_UINT8
, BASE_DEC
, VALS(userdata_cpu_subfunc_names
), 0x0,
7350 { &hf_s7comm_userdata_param_subfunc_sec
,
7351 { "Subfunction", "s7comm.param.userdata.subfunc", FT_UINT8
, BASE_DEC
, VALS(userdata_sec_subfunc_names
), 0x0,
7353 { &hf_s7comm_userdata_param_subfunc_time
,
7354 { "Subfunction", "s7comm.param.userdata.subfunc", FT_UINT8
, BASE_DEC
, VALS(userdata_time_subfunc_names
), 0x0,
7356 { &hf_s7comm_userdata_param_subfunc
,
7357 { "Subfunction", "s7comm.param.userdata.subfunc", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7359 { &hf_s7comm_userdata_param_subfunc_ncprg
,
7360 { "Subfunction", "s7comm.param.userdata.subfunc", FT_UINT8
, BASE_DEC
, VALS(userdata_ncprg_subfunc_names
), 0x0,
7362 { &hf_s7comm_userdata_param_subfunc_drr
,
7363 { "Subfunction", "s7comm.param.userdata.subfunc", FT_UINT8
, BASE_DEC
, VALS(userdata_drr_subfunc_names
), 0x0,
7366 { &hf_s7comm_userdata_param_seq_num
,
7367 { "Sequence number", "s7comm.param.userdata.seq_num", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7370 { &hf_s7comm_userdata_param_dataunitref
,
7371 { "Data unit reference number", "s7comm.param.userdata.dataunitref", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7372 "Data unit reference number if PDU is fragmented", HFILL
}},
7374 { &hf_s7comm_userdata_param_dataunit
,
7375 { "Last data unit", "s7comm.param.userdata.lastdataunit", FT_UINT8
, BASE_HEX
, VALS(userdata_lastdataunit_names
), 0x0,
7378 /* block functions / info */
7379 { &hf_s7comm_ud_blockinfo_block_type
,
7380 { "Block type", "s7comm.blockinfo.blocktype", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7382 { &hf_s7comm_ud_blockinfo_block_cnt
,
7383 { "Block count", "s7comm.blockinfo.block_count", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7385 { &hf_s7comm_ud_blockinfo_block_num
,
7386 { "Block number", "s7comm.blockinfo.block_num", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7388 { &hf_s7comm_ud_blockinfo_block_flags
,
7389 { "Block flags (unknown)", "s7comm.blockinfo.flags", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7391 { &hf_s7comm_ud_blockinfo_block_lang
,
7392 { "Block language", "s7comm.blockinfo.block_lang", FT_UINT8
, BASE_DEC
, VALS(blocklanguage_names
), 0x0,
7394 { &hf_s7comm_ud_blockinfo_block_num_ascii
,
7395 { "Block number", "s7comm.data.blockinfo.block_number", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7397 { &hf_s7comm_ud_blockinfo_filesys
,
7398 { "Filesystem", "s7comm.data.blockinfo.filesys", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7400 { &hf_s7comm_ud_blockinfo_res_infolength
,
7401 { "Length of Info", "s7comm.blockinfo.res_infolength", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7402 "Length of Info in bytes", HFILL
}},
7403 { &hf_s7comm_ud_blockinfo_res_unknown2
,
7404 { "Unknown blockinfo 2", "s7comm.blockinfo.res_unknown2", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
7406 { &hf_s7comm_ud_blockinfo_res_const3
,
7407 { "Constant 3", "s7comm.blockinfo.res_const3", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7408 "Possible constant 3, seems to be always 'pp'", HFILL
}},
7409 { &hf_s7comm_ud_blockinfo_res_unknown
,
7410 { "Unknown byte(s) blockinfo", "s7comm.blockinfo.res_unknown", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
7412 { &hf_s7comm_ud_blockinfo_subblk_type
,
7413 { "Subblk type", "s7comm.blockinfo.subblk_type", FT_UINT8
, BASE_DEC
, VALS(subblktype_names
), 0x0,
7415 { &hf_s7comm_ud_blockinfo_load_mem_len
,
7416 { "Length load memory", "s7comm.blockinfo.load_mem_len", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
7417 "Length of load memory in bytes", HFILL
}},
7418 { &hf_s7comm_ud_blockinfo_blocksecurity
,
7419 { "Block Security", "s7comm.blockinfo.blocksecurity", FT_UINT32
, BASE_DEC
, VALS(blocksecurity_names
), 0x0,
7421 { &hf_s7comm_ud_blockinfo_interface_timestamp
,
7422 { "Interface timestamp", "s7comm.blockinfo.interface_timestamp", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7424 { &hf_s7comm_ud_blockinfo_code_timestamp
,
7425 { "Code timestamp", "s7comm.blockinfo.code_timestamp", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7427 { &hf_s7comm_ud_blockinfo_ssb_len
,
7428 { "SSB length", "s7comm.blockinfo.ssb_len", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7430 { &hf_s7comm_ud_blockinfo_add_len
,
7431 { "ADD length", "s7comm.blockinfo.add_len", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7433 { &hf_s7comm_ud_blockinfo_localdata_len
,
7434 { "Localdata length", "s7comm.blockinfo.localdata_len", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7435 "Length of localdata in bytes", HFILL
}},
7436 { &hf_s7comm_ud_blockinfo_mc7_len
,
7437 { "MC7 code length", "s7comm.blockinfo.mc7_len", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7438 "Length of MC7 code in bytes", HFILL
}},
7439 { &hf_s7comm_ud_blockinfo_author
,
7440 { "Author", "s7comm.blockinfo.author", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7442 { &hf_s7comm_ud_blockinfo_family
,
7443 { "Family", "s7comm.blockinfo.family", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7445 { &hf_s7comm_ud_blockinfo_headername
,
7446 { "Name (Header)", "s7comm.blockinfo.headername", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7448 { &hf_s7comm_ud_blockinfo_headerversion
,
7449 { "Version (Header)", "s7comm.blockinfo.headerversion", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7451 { &hf_s7comm_ud_blockinfo_checksum
,
7452 { "Block checksum", "s7comm.blockinfo.checksum", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
7454 { &hf_s7comm_ud_blockinfo_reserved1
,
7455 { "Reserved 1", "s7comm.blockinfo.reserved1", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
7457 { &hf_s7comm_ud_blockinfo_reserved2
,
7458 { "Reserved 2", "s7comm.blockinfo.reserved2", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
7461 /* Flags in blockinfo response */
7462 { &hf_s7comm_userdata_blockinfo_flags
,
7463 { "Block flags", "s7comm.param.userdata.blockinfo.flags", FT_UINT8
, BASE_HEX
, NULL
, 0xff,
7464 "Some block configuration flags", HFILL
}},
7465 /* Bit : 0 -> DB Linked = true */
7466 { &hf_s7comm_userdata_blockinfo_linked
,
7467 { "Linked", "s7comm.param.userdata.blockinfo.linked", FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x01,
7469 /* Bit : 1 -> Standard block = true */
7470 { &hf_s7comm_userdata_blockinfo_standard_block
,
7471 { "Standard block", "s7comm.param.userdata.blockinfo.standard_block", FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x02,
7473 /* Bit : 5 -> DB Non Retain = true */
7474 { &hf_s7comm_userdata_blockinfo_nonretain
,
7475 { "Non Retain", "s7comm.param.userdata.blockinfo.nonretain", FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x08,
7478 /* Programmer commands / Test and installation (TIS) functions */
7479 { &hf_s7comm_tis_parameter
,
7480 { "TIS Parameter", "s7comm.tis.parameter", FT_NONE
, BASE_NONE
, NULL
, 0x0,
7481 "TIS Test and Installation: Parameter", HFILL
}},
7482 { &hf_s7comm_tis_data
,
7483 { "TIS Data", "s7comm.cpu.tis.data", FT_NONE
, BASE_NONE
, NULL
, 0x0,
7484 "TIS Test and Installation: Data", HFILL
}},
7485 { &hf_s7comm_tis_parametersize
,
7486 { "TIS Parameter size", "s7comm.tis.parametersize", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7488 { &hf_s7comm_tis_datasize
,
7489 { "TIS Data size", "s7comm.tis.datasize", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7491 { &hf_s7comm_tis_param1
,
7492 { "TIS Parameter 1", "s7comm.tis.param1", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7494 { &hf_s7comm_tis_param2
,
7495 { "TIS Parameter 2 - Trigger type", "s7comm.tis.param2", FT_UINT16
, BASE_DEC
, VALS(tis_param2_names
), 0x0,
7497 { &hf_s7comm_tis_param3
,
7498 { "TIS Parameter 3 - Trigger frequency", "s7comm.tis.param3", FT_UINT16
, BASE_DEC
, VALS(tis_param3_names
), 0x0,
7500 { &hf_s7comm_tis_answersize
,
7501 { "TIS Parameter 4 - Answer size", "s7comm.tis.answersize", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7502 "TIS Answer size: Expected data size of PLC answer to this job", HFILL
}},
7503 { &hf_s7comm_tis_param5
,
7504 { "TIS Parameter 5", "s7comm.tis.param5", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7506 { &hf_s7comm_tis_param6
,
7507 { "TIS Parameter 6", "s7comm.tis.param6", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7509 { &hf_s7comm_tis_param7
,
7510 { "TIS Parameter 7", "s7comm.tis.param7", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7512 { &hf_s7comm_tis_param8
,
7513 { "TIS Parameter 8", "s7comm.tis.param8", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7515 { &hf_s7comm_tis_param9
,
7516 { "TIS Parameter 9", "s7comm.tis.param9", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7518 { &hf_s7comm_tis_trgevent
,
7519 { "TIS Parameter 10 - Trigger event", "s7comm.varstat.trgevent", FT_UINT16
, BASE_HEX
, VALS(userdata_varstat_trgevent_names
), 0x0,
7521 { &hf_s7comm_tis_res_param1
,
7522 { "TIS Response Parameter 1", "s7comm.tis.res.param1", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
7524 { &hf_s7comm_tis_res_param2
,
7525 { "TIS Response Parameter 2", "s7comm.tis.res.param2", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
7527 { &hf_s7comm_tis_job_function
,
7528 { "Job function", "s7comm.tis.job.function", FT_UINT8
, BASE_DEC
, VALS(userdata_tis_subfunc_names
), 0x0,
7530 { &hf_s7comm_tis_job_seqnr
,
7531 { "Job reference sequence number", "s7comm.tis.job.response_seq_num", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7532 "Job reference sequence number (find function setup with s7comm.param.userdata.seq_num)", HFILL
}},
7533 { &hf_s7comm_tis_job_reserved
,
7534 { "Job Reserved / Unknown", "s7comm.tis.job.reserved", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
7536 { &hf_s7comm_tis_interrupted_blocktype
,
7537 { "Interrupted block type", "s7comm.tis.interrupted.blocktype", FT_UINT16
, BASE_DEC
, VALS(subblktype_names
), 0x0,
7539 { &hf_s7comm_tis_interrupted_blocknr
,
7540 { "Interrupted block number", "s7comm.tis.interrupted.blocknumber", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7542 { &hf_s7comm_tis_interrupted_address
,
7543 { "Interrupted code address", "s7comm.tis.interrupted.address", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7545 { &hf_s7comm_tis_interrupted_prioclass
,
7546 { "Interrupted priority class", "s7comm.tis.interrupted.priorityclass", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7548 { &hf_s7comm_tis_continued_blocktype
,
7549 { "Continued block type", "s7comm.tis.continued.blocktype", FT_UINT16
, BASE_DEC
, VALS(subblktype_names
), 0x0,
7551 { &hf_s7comm_tis_continued_blocknr
,
7552 { "Continued block number", "s7comm.tis.continued.blocknumber", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7554 { &hf_s7comm_tis_continued_address
,
7555 { "Continued code address", "s7comm.tis.continued.address", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7557 { &hf_s7comm_tis_breakpoint_blocktype
,
7558 { "Breakpoint block type", "s7comm.tis.breakpoint.blocktype", FT_UINT16
, BASE_DEC
, VALS(subblktype_names
), 0x0,
7560 { &hf_s7comm_tis_breakpoint_blocknr
,
7561 { "Breakpoint block number", "s7comm.tis.breakpoint.blocknumber", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7563 { &hf_s7comm_tis_breakpoint_address
,
7564 { "Breakpoint code address", "s7comm.tis.breakpoint.address", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7566 { &hf_s7comm_tis_breakpoint_reserved
,
7567 { "Breakpoint Reserved / Unknown", "s7comm.tis.breakpoint.reserved", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
7570 { &hf_s7comm_tis_p_callenv
,
7571 { "Call environment setup", "s7comm.tis.callenv_setup", FT_UINT16
, BASE_DEC
, VALS(tis_p_callenv_names
), 0x0,
7573 { &hf_s7comm_tis_p_callcond
,
7574 { "Call condition", "s7comm.tis.callenv_cond", FT_UINT16
, BASE_DEC
, VALS(tis_p_callcond_names
), 0x0,
7576 { &hf_s7comm_tis_p_callcond_blocktype
,
7577 { "Call condition block type", "s7comm.tis.callenv_cond_blocktype", FT_UINT16
, BASE_DEC
, VALS(subblktype_names
), 0x0,
7579 { &hf_s7comm_tis_p_callcond_blocknr
,
7580 { "Call condition block number", "s7comm.tis.callenv_cond_blocknumber", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7582 { &hf_s7comm_tis_p_callcond_address
,
7583 { "Call condition code address", "s7comm.tis.callenv_cond_blockaddress", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7586 { &hf_s7comm_tis_register_db1_type
,
7587 { "Register DB1 content type", "s7comm.tis.db1.type", FT_UINT8
, BASE_DEC
, VALS(subblktype_names
), 0x0,
7589 { &hf_s7comm_tis_register_db2_type
,
7590 { "Register DB2 content type", "s7comm.tis.db2.type", FT_UINT8
, BASE_DEC
, VALS(subblktype_names
), 0x0,
7592 { &hf_s7comm_tis_register_db1_nr
,
7593 { "Register DB1 block number", "s7comm.tis.db1.number", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7595 { &hf_s7comm_tis_register_db2_nr
,
7596 { "Register DB2 block number", "s7comm.tis.db2.number", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7598 { &hf_s7comm_tis_register_accu1
,
7599 { "Register ACCU1", "s7comm.tis.accu1", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
7601 { &hf_s7comm_tis_register_accu2
,
7602 { "Register ACCU2", "s7comm.tis.accu2", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
7604 { &hf_s7comm_tis_register_accu3
,
7605 { "Register ACCU3", "s7comm.tis.accu3", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
7607 { &hf_s7comm_tis_register_accu4
,
7608 { "Register ACCU4", "s7comm.tis.accu4", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
7610 { &hf_s7comm_tis_register_ar1
,
7611 { "Register AR1", "s7comm.tis.ar1", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
7613 { &hf_s7comm_tis_register_ar2
,
7614 { "Register AR2", "s7comm.tis.ar2", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
7616 { &hf_s7comm_tis_register_stw
,
7617 { "Register STW", "s7comm.tis.stw", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
7619 { &hf_s7comm_tis_exithold_until
,
7620 { "Exit HOLD state until", "s7comm.tis.exithold_until", FT_UINT8
, BASE_DEC
, VALS(tis_exithold_until_names
), 0x0,
7622 { &hf_s7comm_tis_exithold_res1
,
7623 { "Exit HOLD Reserved / Unknown", "s7comm.tis.exithold_res1", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7625 { &hf_s7comm_tis_bstack_nest_depth
,
7626 { "BSTACK nesting depth", "s7comm.tis.bstack.neting_depth", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7628 { &hf_s7comm_tis_bstack_reserved
,
7629 { "BSTACK Reserved / Unknown", "s7comm.tis.bstack.reserved", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
7631 { &hf_s7comm_tis_istack_reserved
,
7632 { "ISTACK Reserved / Unknown", "s7comm.tis.istack.reserved", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
7634 { &hf_s7comm_tis_lstack_reserved
,
7635 { "LSTACK Reserved / Unknown", "s7comm.tis.lstack.reserved", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
7637 { &hf_s7comm_tis_lstack_size
,
7638 { "Localdata stack size", "s7comm.tis.lstack.size", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7640 { &hf_s7comm_tis_lstack_data
,
7641 { "Localdata stack data", "s7comm.tis.lstack.data", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
7643 { &hf_s7comm_tis_blockstat_flagsunknown
,
7644 { "Blockstat flags", "s7comm.tis.blockstat.flagsunknown", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7646 { &hf_s7comm_tis_blockstat_number_of_lines
,
7647 { "Number of lines", "s7comm.tis.blockstat.number_of_lines", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7649 { &hf_s7comm_tis_blockstat_line_address
,
7650 { "Address", "s7comm.tis.blockstat.line_address", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7652 { &hf_s7comm_tis_blockstat_data
,
7653 { "Blockstatus data", "s7comm.tis.blockstat.data", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
7655 { &hf_s7comm_tis_blockstat_reserved
,
7656 { "Blockstatus Reserved / Unknown", "s7comm.tis.blockstat.reserved", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
7658 /* Organization block local data */
7659 { &hf_s7comm_ob_ev_class
,
7660 { "OB Event class", "s7comm.ob.ev_class", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7661 "OB Event class (Bits 0-3 = 1 (Coming event), Bits 4-7 = 1 (Event class 1))", HFILL
}},
7662 { &hf_s7comm_ob_scan_1
,
7663 { "OB Scan 1", "s7comm.ob.scan_1", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7664 "OB Scan 1 (1=Cold restart scan 1 of OB 1), (3=Scan 2-n of OB 1)", HFILL
}},
7665 { &hf_s7comm_ob_strt_inf
,
7666 { "OB Start info", "s7comm.ob.strt_info", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7667 "OB Start info (OB n has started)", HFILL
}},
7668 { &hf_s7comm_ob_flt_id
,
7669 { "OB Fault identification code", "s7comm.ob.flt_id", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7671 { &hf_s7comm_ob_priority
,
7672 { "OB Priority", "s7comm.ob.priority", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7673 "OB Priority (1 is lowest)", HFILL
}},
7674 { &hf_s7comm_ob_number
,
7675 { "OB Number", "s7comm.ob.number", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7677 { &hf_s7comm_ob_reserved_1
,
7678 { "OB Reserved 1", "s7comm.ob.reserved_1", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7679 "OB Reserved 1 (Reserved for System)", HFILL
}},
7680 { &hf_s7comm_ob_reserved_2
,
7681 { "OB Reserved 2", "s7comm.ob.reserved_2", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7682 "OB Reserved 2 (Reserved for System)", HFILL
}},
7683 { &hf_s7comm_ob_reserved_3
,
7684 { "OB Reserved 3", "s7comm.ob.reserved_3", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
7685 "OB Reserved 3 (Reserved for System)", HFILL
}},
7686 { &hf_s7comm_ob_reserved_4
,
7687 { "OB Reserved 4", "s7comm.ob.reserved_4", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
7688 "OB Reserved 4 (Reserved for System)", HFILL
}},
7689 { &hf_s7comm_ob_reserved_4_dw
,
7690 { "OB Reserved 4", "s7comm.ob.reserved_4_dw", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
7691 "OB Reserved 4 (Reserved for System)", HFILL
}},
7692 { &hf_s7comm_ob_prev_cycle
,
7693 { "OB Cycle time of previous OB scan (ms)", "s7comm.ob.prev_cycle", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7695 { &hf_s7comm_ob_min_cycle
,
7696 { "OB Minimum cycle time of OB (ms)", "s7comm.ob.min_cycle", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7698 { &hf_s7comm_ob_max_cycle
,
7699 { "OB Maximum cycle time of OB (ms)", "s7comm.ob.max_cycle", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7701 { &hf_s7comm_ob_period_exe
,
7702 { "OB Period of execution", "s7comm.ob.period_exe", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
7703 "OB Period of execution (once, per minute/hour/day/week/month/year)", HFILL
}},
7704 { &hf_s7comm_ob_sign
,
7705 { "OB Identifier input (SIGN) attached to SRT_DINT", "s7comm.ob.sign", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
7707 { &hf_s7comm_ob_dtime
,
7708 { "OB Delay time (DTIME) input to SRT_DINT instruction", "s7comm.ob.dtime", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
7710 { &hf_s7comm_ob_phase_offset
,
7711 { "OB Phase offset (ms)", "s7comm.ob.phase_offset", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7713 { &hf_s7comm_ob_exec_freq
,
7714 { "OB Frequency of execution (ms)", "s7comm.ob.exec_freq", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7716 { &hf_s7comm_ob_io_flag
,
7717 { "OB IO flags", "s7comm.ob.io_flag", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7718 "OB IO flags (0x54=input module, 0x55=output module)", HFILL
}},
7719 { &hf_s7comm_ob_mdl_addr
,
7720 { "OB Base address of module initiating interrupt", "s7comm.ob.mdl_addr", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
7722 { &hf_s7comm_ob_point_addr
,
7723 { "OB Address of interrupt point on module", "s7comm.ob.point_addr", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
7725 { &hf_s7comm_ob_inf_len
,
7726 { "OB Length of information", "s7comm.ob.inf_len", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7728 { &hf_s7comm_ob_alarm_type
,
7729 { "OB Type of alarm", "s7comm.ob.alarm_type", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7731 { &hf_s7comm_ob_alarm_slot
,
7732 { "OB Slot", "s7comm.ob.alarm_slot", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7734 { &hf_s7comm_ob_alarm_spec
,
7735 { "OB Specifier", "s7comm.ob.alarm_spec", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7737 { &hf_s7comm_ob_error_info
,
7738 { "OB Error information on event", "s7comm.ob.error_info", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
7740 { &hf_s7comm_ob_err_ev_class
,
7741 { "OB Class of event causing error", "s7comm.ob.err_ev_class", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7743 { &hf_s7comm_ob_err_ev_num
,
7744 { "OB Number of event causing error", "s7comm.ob.err_ev_num", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7746 { &hf_s7comm_ob_err_ob_priority
,
7747 { "OB Priority of OB causing error", "s7comm.ob.err_ob_priority", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7749 { &hf_s7comm_ob_err_ob_num
,
7750 { "OB Number of OB causing error", "s7comm.ob.err_ob_num", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7752 { &hf_s7comm_ob_rack_cpu
,
7753 { "OB Rack / CPU number", "s7comm.ob.rack_cpu", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
7755 { &hf_s7comm_ob_8x_fault_flags
,
7756 { "OB 8x Fault flags", "s7comm.ob.8x_fault_flags", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7758 { &hf_s7comm_ob_mdl_type_b
,
7759 { "OB Type of module", "s7comm.ob.mdl_type_b", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7761 { &hf_s7comm_ob_mdl_type_w
,
7762 { "OB Module type with point fault", "s7comm.ob.mdl_type_w", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
7764 { &hf_s7comm_ob_rack_num
,
7765 { "OB Number of rack that has module with point fault", "s7comm.ob.rack_num", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7767 { &hf_s7comm_ob_racks_flt
,
7768 { "OB Racks in fault", "s7comm.ob.racks_flt", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
7770 { &hf_s7comm_ob_strtup
,
7771 { "OB Method of startup", "s7comm.ob.strtup", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7773 { &hf_s7comm_ob_stop
,
7774 { "OB Event that caused CPU to stop", "s7comm.ob.stop", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
7776 { &hf_s7comm_ob_strt_info
,
7777 { "OB Information on how system started", "s7comm.ob.strt_info", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
7779 { &hf_s7comm_ob_sw_flt
,
7780 { "OB Software programming fault", "s7comm.ob.sw_flt", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7782 { &hf_s7comm_ob_blk_type
,
7783 { "OB Type of block fault occurred in", "s7comm.ob.blk_type", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7785 { &hf_s7comm_ob_flt_reg
,
7786 { "OB Specific register that caused fault", "s7comm.ob.flt_reg", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
7788 { &hf_s7comm_ob_flt_blk_num
,
7789 { "OB Number of block that programming fault occurred in", "s7comm.ob.flt_blk_num", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7791 { &hf_s7comm_ob_prg_addr
,
7792 { "OB Address in block where programming fault occurred", "s7comm.ob.prg_addr", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7794 { &hf_s7comm_ob_mem_area
,
7795 { "OB Memory area where access error occurred", "s7comm.ob.mem_area", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
7797 { &hf_s7comm_ob_mem_addr
,
7798 { "OB Memory address where access error occurred", "s7comm.ob.mem_addr", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
7800 { &hf_s7comm_diagdata_req_block_type
,
7801 { "Block type", "s7comm.diagdata.req.blocktype", FT_UINT16
, BASE_DEC
, VALS(subblktype_names
), 0x0,
7803 { &hf_s7comm_diagdata_req_block_num
,
7804 { "Block number", "s7comm.diagdata.req.blocknumber", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7806 { &hf_s7comm_diagdata_req_startaddr_awl
,
7807 { "Start address AWL", "s7comm.diagdata.req.startaddr_awl", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7809 { &hf_s7comm_diagdata_req_saz
,
7810 { "Step address counter (SAZ)", "s7comm.diagdata.req.saz", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7813 /* Flags for requested registers in diagnostic data telegrams */
7814 { &hf_s7comm_diagdata_registerflag
,
7815 { "Registers", "s7comm.diagdata.register", FT_UINT8
, BASE_HEX
, NULL
, 0x00,
7816 "Requested registers", HFILL
}},
7817 { &hf_s7comm_diagdata_registerflag_stw
,
7818 { "STW", "s7comm.diagdata.register.stw", FT_BOOLEAN
, 8, NULL
, 0x01,
7819 "STW / Status word", HFILL
}},
7820 { &hf_s7comm_diagdata_registerflag_accu1
,
7821 { "ACCU1", "s7comm.diagdata.register.accu1", FT_BOOLEAN
, 8, NULL
, 0x02,
7822 "ACCU1 / Accumulator 1", HFILL
}},
7823 { &hf_s7comm_diagdata_registerflag_accu2
,
7824 { "ACCU2", "s7comm.diagdata.register.accu2", FT_BOOLEAN
, 8, NULL
, 0x04,
7825 "ACCU2 / Accumulator 2", HFILL
}},
7826 { &hf_s7comm_diagdata_registerflag_ar1
,
7827 { "AR1", "s7comm.diagdata.register.ar1", FT_BOOLEAN
, 8, NULL
, 0x08,
7828 "AR1 / Addressregister 1", HFILL
}},
7829 { &hf_s7comm_diagdata_registerflag_ar2
,
7830 { "AR2", "s7comm.diagdata.register.ar2", FT_BOOLEAN
, 8, NULL
, 0x10,
7831 "AR2 / Addressregister 2", HFILL
}},
7832 { &hf_s7comm_diagdata_registerflag_db1
,
7833 { "DB1", "s7comm.diagdata.register.db1", FT_BOOLEAN
, 8, NULL
, 0x20,
7834 "DB1 (global)/ Datablock register 1", HFILL
}},
7835 { &hf_s7comm_diagdata_registerflag_db2
,
7836 { "DB2", "s7comm.diagdata.register.db2", FT_BOOLEAN
, 8, NULL
, 0x40,
7837 "DB2 (instance) / Datablock register 2", HFILL
}},
7839 /* timefunction: s7 timestamp */
7840 { &hf_s7comm_data_ts
,
7841 { "S7 Timestamp", "s7comm.data.ts", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x00,
7842 "S7 Timestamp, BCD coded", HFILL
}},
7843 { &hf_s7comm_data_ts_reserved
,
7844 { "S7 Timestamp - Reserved", "s7comm.data.ts_reserved", FT_UINT8
, BASE_HEX
, NULL
, 0x00,
7845 "S7 Timestamp: Reserved byte", HFILL
}},
7846 { &hf_s7comm_data_ts_year1
,
7847 { "S7 Timestamp - Year 1", "s7comm.data.ts_year1", FT_UINT8
, BASE_DEC
, NULL
, 0x00,
7848 "S7 Timestamp: BCD coded year thousands/hundreds, should be ignored (19 or 20)", HFILL
}},
7849 { &hf_s7comm_data_ts_year2
,
7850 { "S7 Timestamp - Year 2", "s7comm.data.ts_year2", FT_UINT8
, BASE_DEC
, NULL
, 0x00,
7851 "S7 Timestamp: BCD coded year, if 00...89 then it's 2000...2089, else 1990...1999", HFILL
}},
7852 { &hf_s7comm_data_ts_month
,
7853 { "S7 Timestamp - Month", "s7comm.data.ts_month", FT_UINT8
, BASE_DEC
, NULL
, 0x00,
7854 "S7 Timestamp: BCD coded month", HFILL
}},
7855 { &hf_s7comm_data_ts_day
,
7856 { "S7 Timestamp - Day", "s7comm.data.ts_day", FT_UINT8
, BASE_DEC
, NULL
, 0x00,
7857 "S7 Timestamp: BCD coded day", HFILL
}},
7858 { &hf_s7comm_data_ts_hour
,
7859 { "S7 Timestamp - Hour", "s7comm.data.ts_hour", FT_UINT8
, BASE_DEC
, NULL
, 0x00,
7860 "S7 Timestamp: BCD coded hour", HFILL
}},
7861 { &hf_s7comm_data_ts_minute
,
7862 { "S7 Timestamp - Minute", "s7comm.data.ts_minute", FT_UINT8
, BASE_DEC
, NULL
, 0x00,
7863 "S7 Timestamp: BCD coded minute", HFILL
}},
7864 { &hf_s7comm_data_ts_second
,
7865 { "S7 Timestamp - Second", "s7comm.data.ts_second", FT_UINT8
, BASE_DEC
, NULL
, 0x00,
7866 "S7 Timestamp: BCD coded second", HFILL
}},
7867 { &hf_s7comm_data_ts_millisecond
,
7868 { "S7 Timestamp - Milliseconds", "s7comm.data.ts_millisecond", FT_UINT16
, BASE_DEC
, NULL
, 0x00,
7869 "S7 Timestamp: BCD coded milliseconds (left 3 nibbles)", HFILL
}},
7870 { &hf_s7comm_data_ts_weekday
,
7871 { "S7 Timestamp - Weekday", "s7comm.data.ts_weekday", FT_UINT16
, BASE_DEC
, VALS(weekdaynames
), 0x000f,
7872 "S7 Timestamp: Weekday number (right nibble, 1=Su,2=Mo,..)", HFILL
}},
7874 /* Function 0x28 (PI service) and 0x29 */
7875 { &hf_s7comm_piservice_unknown1
,
7876 { "Unknown bytes", "s7comm.param.pistart.unknown1", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
7878 { &hf_s7comm_piservice_parameterblock_len
,
7879 { "Parameter block length", "s7comm.param.pistart.parameterblock_len", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
7880 "Length of Parameter block in bytes", HFILL
}},
7881 { &hf_s7comm_piservice_parameterblock
,
7882 { "Parameter block", "s7comm.param.pistart.parameterblock", FT_NONE
, BASE_NONE
, NULL
, 0x0,
7884 { &hf_s7comm_piservice_servicename
,
7885 { "PI (program invocation) Service", "s7comm.param.pistart.servicename", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7888 /* PI Service parameters for NC services */
7889 { &hf_s7comm_piservice_string_len
,
7890 { "String length", "s7comm.param.pi.n_x.string_len", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
7891 "Length of the following string. If LengthByte + Stringlen is uneven, a fillbyte is added", HFILL
}},
7892 { &hf_s7comm_pi_n_x_addressident
,
7893 { "Addressidentification", "s7comm.param.pi.n_x.addressident", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7894 "Addressidentification (RangeID / Index)", HFILL
}},
7895 { &hf_s7comm_pi_n_x_filename
,
7896 { "Filename", "s7comm.param.pi.n_x.filename", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7897 "Name of the file or directory", HFILL
}},
7898 { &hf_s7comm_pi_n_x_editwindowname
,
7899 { "Editor Window Name", "s7comm.param.pi.n_x.editwindowname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7901 { &hf_s7comm_pi_n_x_password
,
7902 { "Password", "s7comm.param.pi.n_x.password", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7904 { &hf_s7comm_pi_n_x_seekpointer
,
7905 { "Seek pointer", "s7comm.param.pi.n_x.seekpointer", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7906 "SeekPointer string with exact 9 digit/character(s)", HFILL
}},
7907 { &hf_s7comm_pi_n_x_windowsize
,
7908 { "Window size", "s7comm.param.pi.n_x.windowsize", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7910 { &hf_s7comm_pi_n_x_comparestring
,
7911 { "Compare String", "s7comm.param.pi.n_x.comparestring", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7913 { &hf_s7comm_pi_n_x_skipcount
,
7914 { "Skip Count", "s7comm.param.pi.n_x.skipcount", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7916 { &hf_s7comm_pi_n_x_interruptnr
,
7917 { "Interrupt Number", "s7comm.param.pi.n_x.interruptnr", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7918 "Interrupt Number: Interrupt number corresponds to the input number which caused the interrupt" , HFILL
}},
7919 { &hf_s7comm_pi_n_x_priority
,
7920 { "Priority", "s7comm.param.pi.n_x.priority", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7922 { &hf_s7comm_pi_n_x_liftfast
,
7923 { "Liftfast", "s7comm.param.pi.n_x.liftfast", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7924 "Liftfast: Indicates whether an interrupt routine should simultaneously cause a fast lift-off motion" , HFILL
}},
7925 { &hf_s7comm_pi_n_x_blsync
,
7926 { "Blsync", "s7comm.param.pi.n_x.blsync", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7927 "Blsync: Indicates whether the interrupt has to be synchronized to the next block end" , HFILL
}},
7928 { &hf_s7comm_pi_n_x_magnr
,
7929 { "Magnr", "s7comm.param.pi.n_x.magnr", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7930 "Magnr: Magazine number" , HFILL
}},
7931 { &hf_s7comm_pi_n_x_dnr
,
7932 { "DNr", "s7comm.param.pi.n_x.dnr", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7933 "DNr: D number" , HFILL
}},
7934 { &hf_s7comm_pi_n_x_spindlenumber
,
7935 { "Spindle Number", "s7comm.param.pi.n_x.spindlenumber", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7937 { &hf_s7comm_pi_n_x_wznr
,
7938 { "WZ-Nr", "s7comm.param.pi.n_x.wznr", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7939 "WZ-Nr: Tool number" , HFILL
}},
7940 { &hf_s7comm_pi_n_x_class
,
7941 { "Class", "s7comm.param.pi.n_x.class", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7942 "Class: Classify machine data" , HFILL
}},
7943 { &hf_s7comm_pi_n_x_tnr
,
7944 { "TNr", "s7comm.param.pi.n_x.tnr", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7946 { &hf_s7comm_pi_n_x_toolnumber
,
7947 { "Tool Number", "s7comm.param.pi.n_x.toolnumber", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7949 { &hf_s7comm_pi_n_x_cenumber
,
7950 { "CE-Number", "s7comm.param.pi.n_x.cenumber", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7952 { &hf_s7comm_pi_n_x_datablocknumber
,
7953 { "Datablock Number", "s7comm.param.pi.n_x.datablocknumber", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7955 { &hf_s7comm_pi_n_x_firstcolumnnumber
,
7956 { "First Column Number", "s7comm.param.pi.n_x.firstcolumnnumber", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7958 { &hf_s7comm_pi_n_x_lastcolumnnumber
,
7959 { "Last Column Number", "s7comm.param.pi.n_x.lastcolumnnumber", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7961 { &hf_s7comm_pi_n_x_firstrownumber
,
7962 { "First Row Number", "s7comm.param.pi.n_x.firstrownnumber", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7964 { &hf_s7comm_pi_n_x_lastrownumber
,
7965 { "Last Row Number", "s7comm.param.pi.n_x.lastrownnumber", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7967 { &hf_s7comm_pi_n_x_direction
,
7968 { "Direction", "s7comm.param.pi.n_x.direction", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7970 { &hf_s7comm_pi_n_x_sourcefilename
,
7971 { "Source-Filename", "s7comm.param.pi.n_x.sourcefilename", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7973 { &hf_s7comm_pi_n_x_destinationfilename
,
7974 { "Destination-Filename", "s7comm.param.pi.n_x.destinationfilename", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7976 { &hf_s7comm_pi_n_x_channelnumber
,
7977 { "Channel Number", "s7comm.param.pi.n_x.channelnumber", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7979 { &hf_s7comm_pi_n_x_protection
,
7980 { "Protection", "s7comm.param.pi.n_x.protection", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7982 { &hf_s7comm_pi_n_x_oldfilename
,
7983 { "Old Filename", "s7comm.param.pi.n_x.oldfilename", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7985 { &hf_s7comm_pi_n_x_newfilename
,
7986 { "New Filename", "s7comm.param.pi.n_x.newfilename", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7988 { &hf_s7comm_pi_n_x_findmode
,
7989 { "Findmode", "s7comm.param.pi.n_x.findmode", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7991 { &hf_s7comm_pi_n_x_switch
,
7992 { "Switch", "s7comm.param.pi.n_x.switch", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7994 { &hf_s7comm_pi_n_x_functionnumber
,
7995 { "Function Number", "s7comm.param.pi.n_x.functionnumber", FT_STRING
, BASE_NONE
, NULL
, 0x0,
7997 { &hf_s7comm_pi_n_x_semaphorevalue
,
7998 { "Semaphore Value", "s7comm.param.pi.n_x.semaphorevalue", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8000 { &hf_s7comm_pi_n_x_onoff
,
8001 { "OnOff", "s7comm.param.pi.n_x.onoff", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8003 { &hf_s7comm_pi_n_x_mode
,
8004 { "Mode", "s7comm.param.pi.n_x.mode", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8006 { &hf_s7comm_pi_n_x_factor
,
8007 { "Factor", "s7comm.param.pi.n_x.factor", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8009 { &hf_s7comm_pi_n_x_passwordlevel
,
8010 { "Password Level", "s7comm.param.pi.n_x.passwordlevel", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8012 { &hf_s7comm_pi_n_x_linenumber
,
8013 { "Line Number", "s7comm.param.pi.n_x.linenumber", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8015 { &hf_s7comm_pi_n_x_weargroup
,
8016 { "Wear Group", "s7comm.param.pi.n_x.weargroup", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8018 { &hf_s7comm_pi_n_x_toolstatus
,
8019 { "Tool Status", "s7comm.param.pi.n_x.toolstatus", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8021 { &hf_s7comm_pi_n_x_wearsearchstrat
,
8022 { "Search Strategy", "s7comm.param.pi.n_x.wearsearchstrat", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8024 { &hf_s7comm_pi_n_x_toolid
,
8025 { "Tool ID", "s7comm.param.pi.n_x.toolid", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8027 { &hf_s7comm_pi_n_x_duplonumber
,
8028 { "Duplo Number", "s7comm.param.pi.n_x.duplonumber", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8030 { &hf_s7comm_pi_n_x_edgenumber
,
8031 { "Edge Number", "s7comm.param.pi.n_x.edgenumber", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8033 { &hf_s7comm_pi_n_x_placenr
,
8034 { "Place Number", "s7comm.param.pi.n_x.placenr", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8036 { &hf_s7comm_pi_n_x_placerefnr
,
8037 { "Place Reference Number", "s7comm.param.pi.n_x.placerefnr", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8039 { &hf_s7comm_pi_n_x_magrefnr
,
8040 { "Magazine Reference Number", "s7comm.param.pi.n_x.magrefnr", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8042 { &hf_s7comm_pi_n_x_placenrfrom
,
8043 { "Place Number from", "s7comm.param.pi.n_x.placenrfrom", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8045 { &hf_s7comm_pi_n_x_magnrfrom
,
8046 { "Magazine Number from", "s7comm.param.pi.n_x.magnrfrom", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8048 { &hf_s7comm_pi_n_x_placenrto
,
8049 { "Place Number to", "s7comm.param.pi.n_x.placenrto", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8051 { &hf_s7comm_pi_n_x_magnrto
,
8052 { "Magazine Number to", "s7comm.param.pi.n_x.magnrto", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8054 { &hf_s7comm_pi_n_x_halfplacesleft
,
8055 { "Half places left", "s7comm.param.pi.n_x.halfplacesleft", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8057 { &hf_s7comm_pi_n_x_halfplacesright
,
8058 { "Half places right", "s7comm.param.pi.n_x.halfplacesright", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8060 { &hf_s7comm_pi_n_x_halfplacesup
,
8061 { "Half places up", "s7comm.param.pi.n_x.halfplacesup", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8063 { &hf_s7comm_pi_n_x_halfplacesdown
,
8064 { "Half places down", "s7comm.param.pi.n_x.halfplacesdown", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8066 { &hf_s7comm_pi_n_x_placetype
,
8067 { "Place type index", "s7comm.param.pi.n_x.placetype", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8069 { &hf_s7comm_pi_n_x_searchdirection
,
8070 { "Search direction", "s7comm.param.pi.n_x.searchdirection", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8072 { &hf_s7comm_pi_n_x_toolname
,
8073 { "Tool Name", "s7comm.param.pi.n_x.toolname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8075 { &hf_s7comm_pi_n_x_placenrsource
,
8076 { "Place Number Source", "s7comm.param.pi.n_x.placenrsource", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8078 { &hf_s7comm_pi_n_x_magnrsource
,
8079 { "Magazine Number Source", "s7comm.param.pi.n_x.magnrsource", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8081 { &hf_s7comm_pi_n_x_placenrdestination
,
8082 { "Place Number Destination", "s7comm.param.pi.n_x.placenrdestination", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8084 { &hf_s7comm_pi_n_x_magnrdestination
,
8085 { "Magazine Number Destination", "s7comm.param.pi.n_x.magnrdestination", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8087 { &hf_s7comm_pi_n_x_incrementnumber
,
8088 { "Increment Number", "s7comm.param.pi.n_x.incrementnumber", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8090 { &hf_s7comm_pi_n_x_monitoringmode
,
8091 { "Monitoring mode", "s7comm.param.pi.n_x.monitoringmode", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8093 { &hf_s7comm_pi_n_x_kindofsearch
,
8094 { "Kind of search", "s7comm.param.pi.n_x.kindofsearch", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8097 { &hf_s7comm_data_pi_inse_unknown
,
8098 { "Unknown byte", "s7comm.param.pi.inse.unknown", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8101 { &hf_s7comm_data_plccontrol_argument
,
8102 { "Argument", "s7comm.param.pistart.argument", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8104 { &hf_s7comm_data_plccontrol_block_cnt
,
8105 { "Number of blocks", "s7comm.data.plccontrol.block_cnt", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8107 { &hf_s7comm_data_plccontrol_part2_len
,
8108 { "Length part 2", "s7comm.data.plccontrol.part2_len", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8109 "Length of part 2 in bytes", HFILL
}},
8111 /* block control functions */
8112 { &hf_s7comm_data_blockcontrol_unknown1
,
8113 { "Unknown byte(s) in blockcontrol", "s7comm.data.blockcontrol.unknown1", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
8115 { &hf_s7comm_data_blockcontrol_errorcode
,
8116 { "Errorcode", "s7comm.data.blockcontrol.errorcode", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
8117 "Errorcode, 0 on success", HFILL
}},
8118 { &hf_s7comm_data_blockcontrol_uploadid
,
8119 { "UploadID", "s7comm.data.blockcontrol.uploadid", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
8121 { &hf_s7comm_data_blockcontrol_file_ident
,
8122 { "File identifier", "s7comm.data.blockcontrol.file_identifier", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8123 "File identifier: '_'=complete module; '$'=Module header for up-loading", HFILL
}},
8124 { &hf_s7comm_data_blockcontrol_block_type
,
8125 { "Block type", "s7comm.data.blockcontrol.block_type", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8127 { &hf_s7comm_data_blockcontrol_block_num
,
8128 { "Block number", "s7comm.data.blockcontrol.block_number", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8130 { &hf_s7comm_data_blockcontrol_dest_filesys
,
8131 { "Destination filesystem", "s7comm.data.blockcontrol.dest_filesys", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8133 { &hf_s7comm_data_blockcontrol_part2_len
,
8134 { "Length part 2", "s7comm.data.blockcontrol.part2_len", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8135 "Length of part 2 in bytes", HFILL
}},
8136 { &hf_s7comm_data_blockcontrol_part2_unknown
,
8137 { "Unknown char before load mem", "s7comm.data.blockcontrol.part2_unknown", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8139 { &hf_s7comm_data_blockcontrol_loadmem_len
,
8140 { "Length of load memory", "s7comm.data.blockcontrol.loadmem_len", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8141 "Length of load memory in bytes", HFILL
}},
8142 { &hf_s7comm_data_blockcontrol_mc7code_len
,
8143 { "Length of MC7 code", "s7comm.data.blockcontrol.mc7code_len", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8144 "Length of MC7 code in bytes", HFILL
}},
8146 { &hf_s7comm_data_blockcontrol_filename_len
,
8147 { "Filename Length", "s7comm.param.blockcontrol.filename_len", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8148 "Length following filename in bytes", HFILL
}},
8149 { &hf_s7comm_data_blockcontrol_filename
,
8150 { "Filename", "s7comm.param.blockcontrol.filename", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8152 { &hf_s7comm_data_blockcontrol_upl_lenstring_len
,
8153 { "Blocklengthstring Length", "s7comm.param.blockcontrol.upl_lenstring_len", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8154 "Length following blocklength string in bytes", HFILL
}},
8155 { &hf_s7comm_data_blockcontrol_upl_lenstring
,
8156 { "Blocklength", "s7comm.param.blockcontrol.upl_lenstring", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8157 "Length of the complete uploadblock in bytes, may be split into many PDUs", HFILL
}},
8158 { &hf_s7comm_data_blockcontrol_functionstatus
,
8159 { "Function Status", "s7comm.param.blockcontrol.functionstatus", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8160 "0=no error, 1=more data, 2=error", HFILL
}},
8161 { &hf_s7comm_data_blockcontrol_functionstatus_more
,
8162 { "More data following", "s7comm.param.blockcontrol.functionstatus.more", FT_BOOLEAN
, 8, NULL
, 0x01,
8163 "More data of the block/file can be retrieved with another request", HFILL
}},
8164 { &hf_s7comm_data_blockcontrol_functionstatus_error
,
8165 { "Error", "s7comm.param.blockcontrol.functionstatus.error", FT_BOOLEAN
, 8, NULL
, 0x02,
8166 "An error occurred", HFILL
}},
8168 /* NC programming functions */
8169 { &hf_s7comm_data_ncprg_unackcount
,
8170 { "Number of telegrams sent without acknowledge", "s7comm.data.ncprg.unackcount", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8172 { &hf_s7comm_data_ncprg_filelength
,
8173 { "NC file length", "s7comm.data.ncprg.filelength", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8174 "NC file length: length of file date + file path", HFILL
}},
8175 { &hf_s7comm_data_ncprg_filetime
,
8176 { "NC file timestamp", "s7comm.data.ncprg.filetime", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8178 { &hf_s7comm_data_ncprg_filepath
,
8179 { "NC file path", "s7comm.data.ncprg.filepath", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8181 { &hf_s7comm_data_ncprg_filedata
,
8182 { "NC file data", "s7comm.data.ncprg.filedata", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
8185 /* Data record routing to Profibus */
8186 { &hf_s7comm_data_drr_data
,
8187 { "DRR Data", "s7comm.data.drr.data", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
8190 /* Variable status */
8191 { &hf_s7comm_varstat_unknown
,
8192 { "Unknown byte(s) varstat", "s7comm.varstat.unknown", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
8194 { &hf_s7comm_varstat_item_count
,
8195 { "Item count", "s7comm.varstat.item_count", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8197 { &hf_s7comm_varstat_req_memory_area
,
8198 { "Memory area", "s7comm.varstat.req.memory_area", FT_UINT8
, BASE_DEC
, VALS(userdata_tis_varstat_area_names
), 0x0,
8200 { &hf_s7comm_varstat_req_repetition_factor
,
8201 { "Repetition factor", "s7comm.varstat.req.repetition_factor", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8203 { &hf_s7comm_varstat_req_db_number
,
8204 { "DB number", "s7comm.varstat.req.db_number", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8205 "DB number, when area is DB", HFILL
}},
8206 { &hf_s7comm_varstat_req_startaddress
,
8207 { "Startaddress", "s7comm.varstat.req.startaddress", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8208 "Startaddress / byteoffset", HFILL
}},
8209 { &hf_s7comm_varstat_req_bitpos
,
8210 { "Bitposition", "s7comm.varstat.req.bitpos", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8213 /* cyclic services */
8214 { &hf_s7comm_cycl_interval_timebase
,
8215 { "Interval timebase", "s7comm.cyclic.interval_timebase", FT_UINT8
, BASE_DEC
, VALS(cycl_interval_timebase_names
), 0x0,
8217 { &hf_s7comm_cycl_interval_time
,
8218 { "Interval time factor", "s7comm.cyclic.interval_time", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8220 { &hf_s7comm_cycl_function
,
8221 { "Function", "s7comm.cyclic.function", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8223 { &hf_s7comm_cycl_jobid
,
8224 { "Job-ID", "s7comm.cyclic.job_id", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8228 { &hf_s7comm_rdrec_mlen
,
8229 { "Rdrec Mlen", "s7comm.readrec.mlen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8230 "MLEN, Max. length in bytes of the data record data to be read", HFILL
}},
8231 { &hf_s7comm_rdrec_index
,
8232 { "Rdrec Index", "s7comm.readrec.index", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
8233 "INDEX, Data record number", HFILL
}},
8234 { &hf_s7comm_rdrec_id
,
8235 { "Rdrec ID", "s7comm.readrec.id", FT_UINT24
, BASE_DEC
, NULL
, 0x0,
8236 "ID, Diagnostic address", HFILL
}},
8237 { &hf_s7comm_rdrec_statuslen
,
8238 { "Rdrec Status Len", "s7comm.readrec.statuslen", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8239 "STATUS LEN, Length of status data", HFILL
}},
8240 { &hf_s7comm_rdrec_statusdata
,
8241 { "Rdrec Status", "s7comm.readrec.status", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
8242 "STATUS, Status data", HFILL
}},
8243 { &hf_s7comm_rdrec_recordlen
,
8244 { "Rdrec Len", "s7comm.readrec.len", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8245 "LEN, Length of data record data read", HFILL
}},
8246 { &hf_s7comm_rdrec_data
,
8247 { "Rdrec Data", "s7comm.readrec.data", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
8248 "DATA, The read data record", HFILL
}},
8249 { &hf_s7comm_rdrec_reserved1
,
8250 { "Rdrec reserved", "s7comm.readrec.reserved1", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
8253 /* PBC, Programmable Block Functions */
8254 { &hf_s7comm_pbc_unknown
,
8255 { "PBC unknown", "s7comm.pbc.unknown", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8257 { &hf_s7comm_pbc_bsend_r_id
,
8258 { "PBC BSEND R_ID", "s7comm.pbc.req.bsend.r_id", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
8260 { &hf_s7comm_pbc_bsend_len
,
8261 { "PBC BSEND LEN", "s7comm.pbc.req.bsend.len", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
8263 { &hf_s7comm_pbc_usend_unknown1
,
8264 { "PBC USEND unknown 1", "s7comm.pbc.usend.unknown1", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8266 { &hf_s7comm_pbc_usend_r_id
,
8267 { "PBC USEND R_ID", "s7comm.pbc.usend.r_id", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
8269 { &hf_s7comm_pbc_usend_unknown2
,
8270 { "PBC USEND unknown 2", "s7comm.pbc.usend.unknown2", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8272 { &hf_s7comm_pbc_arsend_ret
,
8273 { "PBC AR_SEND Returncode", "s7comm.pbc.arsend.ret", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8275 { &hf_s7comm_pbc_arsend_unknown
,
8276 { "PBC AR_SEND unknown", "s7comm.pbc.arsend.unknown", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8278 { &hf_s7comm_pbc_arsend_ar_id
,
8279 { "PBC AR_SEND AR_ID", "s7comm.pbc.arsend.ar_id", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
8281 { &hf_s7comm_pbc_arsend_len
,
8282 { "PBC AR_SEND LEN", "s7comm.pbc.arsend.len", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
8286 { &hf_s7comm_cpu_alarm_message_item
,
8287 { "Alarm message", "s7comm.alarm.message", FT_NONE
, BASE_NONE
, NULL
, 0x0,
8289 { &hf_s7comm_cpu_alarm_message_obj_item
,
8290 { "Message object", "s7comm.alarm.message_object", FT_NONE
, BASE_NONE
, NULL
, 0x0,
8292 { &hf_s7comm_cpu_alarm_message_function
,
8293 { "Function identifier", "s7comm.alarm.function", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8295 { &hf_s7comm_cpu_alarm_message_nr_objects
,
8296 { "Number of message objects", "s7comm.alarm.nr_objects", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8298 { &hf_s7comm_cpu_alarm_message_nr_add_values
,
8299 { "Number of associated values", "s7comm.alarm.nr_add_values", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8301 { &hf_s7comm_cpu_alarm_message_eventid
,
8302 { "EventID", "s7comm.alarm.event_id", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
8304 { &hf_s7comm_cpu_alarm_message_timestamp_coming
,
8305 { "Timestamp message coming", "s7comm.alarm.timestamp_coming", FT_NONE
, BASE_NONE
, NULL
, 0x0,
8307 { &hf_s7comm_cpu_alarm_message_timestamp_going
,
8308 { "Timestamp message going", "s7comm.alarm.timestamp_going", FT_NONE
, BASE_NONE
, NULL
, 0x0,
8310 { &hf_s7comm_cpu_alarm_message_associated_value
,
8311 { "Associated value(s)", "s7comm.alarm.associated_value", FT_NONE
, BASE_NONE
, NULL
, 0x0,
8313 { &hf_s7comm_cpu_alarm_message_eventstate
,
8314 { "EventState", "s7comm.alarm.eventstate", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8316 { &hf_s7comm_cpu_alarm_message_signal_sig1
,
8317 { "SIG_1", "s7comm.alarm.signal.sig1", FT_BOOLEAN
, 8, NULL
, 0x01,
8318 "Current state of Signal SIG_1", HFILL
}},
8319 { &hf_s7comm_cpu_alarm_message_signal_sig2
,
8320 { "SIG_2", "s7comm.alarm.signal.sig2", FT_BOOLEAN
, 8, NULL
, 0x02,
8321 "Current state of Signal SIG_2", HFILL
}},
8322 { &hf_s7comm_cpu_alarm_message_signal_sig3
,
8323 { "SIG_3", "s7comm.alarm.signal.sig3", FT_BOOLEAN
, 8, NULL
, 0x04,
8324 "Current state of Signal SIG_3", HFILL
}},
8325 { &hf_s7comm_cpu_alarm_message_signal_sig4
,
8326 { "SIG_4", "s7comm.alarm.signal.sig4", FT_BOOLEAN
, 8, NULL
, 0x08,
8327 "Current state of Signal SIG_4", HFILL
}},
8328 { &hf_s7comm_cpu_alarm_message_signal_sig5
,
8329 { "SIG_5", "s7comm.alarm.signal.sig5", FT_BOOLEAN
, 8, NULL
, 0x10,
8330 "Current state of Signal SIG_5", HFILL
}},
8331 { &hf_s7comm_cpu_alarm_message_signal_sig6
,
8332 { "SIG_6", "s7comm.alarm.signal.sig6", FT_BOOLEAN
, 8, NULL
, 0x20,
8333 "Current state of Signal SIG_6", HFILL
}},
8334 { &hf_s7comm_cpu_alarm_message_signal_sig7
,
8335 { "SIG_7", "s7comm.alarm.signal.sig7", FT_BOOLEAN
, 8, NULL
, 0x40,
8336 "Current state of Signal SIG_7", HFILL
}},
8337 { &hf_s7comm_cpu_alarm_message_signal_sig8
,
8338 { "SIG_8", "s7comm.alarm.signal.sig8", FT_BOOLEAN
, 8, NULL
, 0x80,
8339 "Current state of Signal SIG_8", HFILL
}},
8340 { &hf_s7comm_cpu_alarm_message_state
,
8341 { "State", "s7comm.alarm.state", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8343 { &hf_s7comm_cpu_alarm_message_ackstate_coming
,
8344 { "AckState coming", "s7comm.alarm.ack_state.coming", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8345 "Acknowledge state coming (1=Event acknowledged, 0=Event not acknowledged)", HFILL
}},
8346 { &hf_s7comm_cpu_alarm_message_ackstate_going
,
8347 { "AckState going", "s7comm.alarm.ack_state.going", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8348 "Acknowledge state going (1=Event acknowledged, 0=Event not acknowledged)", HFILL
}},
8349 { &hf_s7comm_cpu_alarm_message_event_coming
,
8350 { "Event coming", "s7comm.alarm.event.coming", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8352 { &hf_s7comm_cpu_alarm_message_event_going
,
8353 { "Event going", "s7comm.alarm.event.going", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8355 { &hf_s7comm_cpu_alarm_message_event_lastchanged
,
8356 { "Event last changed", "s7comm.alarm.event.lastchanged", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8358 { &hf_s7comm_cpu_alarm_message_event_reserved
,
8359 { "Reserved", "s7comm.alarm.event.reserved", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8361 { &hf_s7comm_cpu_alarm_message_scan_unknown1
,
8362 { "SCAN unknown 1", "s7comm.alarm.scan.unknown1", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
8364 { &hf_s7comm_cpu_alarm_message_scan_unknown2
,
8365 { "SCAN unknown 2", "s7comm.alarm.scan.unknown2", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
8367 /* Alarm message query */
8368 { &hf_s7comm_cpu_alarm_query_unknown1
,
8369 { "Unknown/Reserved (1)", "s7comm.alarm.query.unknown1", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8371 { &hf_s7comm_cpu_alarm_query_querytype
,
8372 { "Querytype", "s7comm.alarm.query.querytype", FT_UINT8
, BASE_DEC
, VALS(alarm_message_querytype_names
), 0x0,
8374 { &hf_s7comm_cpu_alarm_query_unknown2
,
8375 { "Unknown/Reserved (2)", "s7comm.alarm.query.unknown2", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8377 { &hf_s7comm_cpu_alarm_query_alarmtype
,
8378 { "Alarmtype", "s7comm.alarm.query.alarmtype", FT_UINT32
, BASE_DEC
, VALS(alarm_message_query_alarmtype_names
), 0x0,
8380 { &hf_s7comm_cpu_alarm_query_completelen
,
8381 { "Complete data length", "s7comm.alarm.query.complete_length", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
8382 "Complete data length (with ALARM_S this is 0xffff, as they might be split into many telegrams)", HFILL
}},
8383 { &hf_s7comm_cpu_alarm_query_datasetlen
,
8384 { "Length of dataset", "s7comm.alarm.query.dataset_length", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8386 { &hf_s7comm_cpu_alarm_query_resunknown1
,
8387 { "Unknown", "s7comm.alarm.query.resunknown1", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
8389 /* CPU diagnostic messages */
8390 { &hf_s7comm_cpu_diag_msg_item
,
8391 { "CPU diagnostic message", "s7comm.cpu.diag_msg", FT_NONE
, BASE_NONE
, NULL
, 0x0,
8393 { &hf_s7comm_cpu_diag_msg_eventid
,
8394 { "Event ID", "s7comm.cpu.diag_msg.eventid", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
8396 { &hf_s7comm_cpu_diag_msg_eventid_class
,
8397 { "Event class", "s7comm.cpu.diag_msg.eventid.class", FT_UINT16
, BASE_HEX
, VALS(cpu_diag_msg_eventid_class_names
), 0xf000,
8399 { &hf_s7comm_cpu_diag_msg_eventid_ident_entleave
,
8400 { "Event entering state", "s7comm.cpu.diag_msg.eventid.ident.entleave", FT_BOOLEAN
, 16, TFS(&tfs_s7comm_cpu_diag_msg_eventid_ident_entleave
), 0x0100,
8401 "Event identifier: 0=Event leaving state,1=Event entering state", HFILL
}},
8402 { &hf_s7comm_cpu_diag_msg_eventid_ident_diagbuf
,
8403 { "Entry in diagnostic buffer", "s7comm.cpu.diag_msg.eventid.ident.diagbuf", FT_BOOLEAN
, 16, NULL
, 0x0200,
8404 "Event identifier: Entry in diagnostic buffer", HFILL
}},
8405 { &hf_s7comm_cpu_diag_msg_eventid_ident_interr
,
8406 { "Internal error", "s7comm.cpu.diag_msg.eventid.ident.interr", FT_BOOLEAN
, 16, NULL
, 0x0400,
8407 "Event identifier: Internal error", HFILL
}},
8408 { &hf_s7comm_cpu_diag_msg_eventid_ident_exterr
,
8409 { "External error", "s7comm.cpu.diag_msg.eventid.ident.exterr", FT_BOOLEAN
, 16, NULL
, 0x0800,
8410 "Event identifier: External error", HFILL
}},
8411 { &hf_s7comm_cpu_diag_msg_eventid_nr
,
8412 { "Event number", "s7comm.cpu.diag_msg.eventid.nr", FT_UINT16
, BASE_HEX
, NULL
, 0x00ff,
8414 { &hf_s7comm_cpu_diag_msg_prioclass
,
8415 { "Priority class", "s7comm.cpu.diag_msg.prioclass", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8417 { &hf_s7comm_cpu_diag_msg_obnumber
,
8418 { "OB number", "s7comm.cpu.diag_msg.obnumber", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
8420 { &hf_s7comm_cpu_diag_msg_datid
,
8421 { "DatID", "s7comm.cpu.diag_msg.datid", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
8423 { &hf_s7comm_cpu_diag_msg_info1
,
8424 { "INFO1 Additional information 1", "s7comm.cpu.diag_msg.info1", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
8426 { &hf_s7comm_cpu_diag_msg_info2
,
8427 { "INFO2 Additional information 2", "s7comm.cpu.diag_msg.info2", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
8429 /* CPU message service */
8430 { &hf_s7comm_cpu_msgservice_subscribe_events
,
8431 { "Subscribed events", "s7comm.cpu.msg.events", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8433 { &hf_s7comm_cpu_msgservice_subscribe_events_modetrans
,
8434 { "Mode-transition", "s7comm.cpu.msg.events.modetrans", FT_BOOLEAN
, 8, NULL
, 0x01,
8435 "MODE: Register for mode-transition events via func-group=0 and subfunction=state", HFILL
}},
8436 { &hf_s7comm_cpu_msgservice_subscribe_events_system
,
8437 { "System-diagnostics", "s7comm.cpu.msg.events.system", FT_BOOLEAN
, 8, NULL
, 0x02,
8438 "SYS: Register for system diagnostic events", HFILL
}},
8439 { &hf_s7comm_cpu_msgservice_subscribe_events_userdefined
,
8440 { "Userdefined", "s7comm.cpu.msg.events.userdefined", FT_BOOLEAN
, 8, NULL
, 0x04,
8441 "USR: Register system user-defined diagnostic messages", HFILL
}},
8442 { &hf_s7comm_cpu_msgservice_subscribe_events_alarms
,
8443 { "Alarms", "s7comm.cpu.msg.events.alarms", FT_BOOLEAN
, 8, NULL
, 0x80,
8444 "ALM: Register alarm events (ALARM, SCAN, ALARM_S) type of event defined in additional field", HFILL
}},
8445 { &hf_s7comm_cpu_msgservice_req_reserved1
,
8446 { "Reserved/Unknown", "s7comm.cpu.msg.req_reserved1", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8448 { &hf_s7comm_cpu_msgservice_username
,
8449 { "Username", "s7comm.cpu.msg.username", FT_STRING
, BASE_NONE
, NULL
, 0x0,
8451 { &hf_s7comm_cpu_msgservice_almtype
,
8452 { "Alarm type", "s7comm.cpu.msg.almtype", FT_UINT8
, BASE_DEC
, VALS(cpu_msgservice_almtype_names
), 0x0,
8454 { &hf_s7comm_cpu_msgservice_req_reserved2
,
8455 { "Reserved/Unknown", "s7comm.cpu.msg.req_reserved2", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8457 { &hf_s7comm_cpu_msgservice_res_result
,
8458 { "Result", "s7comm.cpu.msg.res_result", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8460 { &hf_s7comm_cpu_msgservice_res_reserved1
,
8461 { "Reserved/Unknown", "s7comm.cpu.msg.res_reserved1", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8463 { &hf_s7comm_cpu_msgservice_res_reserved2
,
8464 { "Reserved/Unknown", "s7comm.cpu.msg.res_reserved2", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8466 { &hf_s7comm_cpu_msgservice_res_reserved3
,
8467 { "Reserved/Unknown", "s7comm.cpu.msg.res_reserved3", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8469 { &hf_s7comm_modetrans_param_unknown1
,
8470 { "Reserved/Unknown", "s7comm.param.modetrans.unknown1", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
8472 { &hf_s7comm_modetrans_param_mode
,
8473 { "Current mode", "s7comm.param.modetrans.mode", FT_UINT8
, BASE_DEC
, VALS(modetrans_param_mode_names
), 0x0,
8475 { &hf_s7comm_modetrans_param_unknown2
,
8476 { "Reserved/Unknown", "s7comm.param.modetrans.unknown2", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8479 /* TIA Portal stuff */
8480 { &hf_s7comm_tia1200_item_reserved1
,
8481 { "1200 sym Reserved", "s7comm.tiap.item.reserved1", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
8483 { &hf_s7comm_tia1200_item_area1
,
8484 { "1200 sym root area 1", "s7comm.tiap.item.area1", FT_UINT16
, BASE_HEX
, VALS(tia1200_var_item_area1_names
), 0x0,
8485 "Area from where to read: DB or Inputs, Outputs, etc.", HFILL
}},
8486 { &hf_s7comm_tia1200_item_area2
,
8487 { "1200 sym root area 2", "s7comm.tiap.item.area2", FT_UINT16
, BASE_HEX
, VALS(tia1200_var_item_area2_names
), 0x0,
8488 "Specifies the area from where to read", HFILL
}},
8489 { &hf_s7comm_tia1200_item_area2unknown
,
8490 { "1200 sym root area 2 unknown", "s7comm.tiap.item.area2unknown", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
8491 "For current unknown areas", HFILL
}},
8492 { &hf_s7comm_tia1200_item_dbnumber
,
8493 { "1200 sym root DB number", "s7comm.tiap.item.dbnumber", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
8495 { &hf_s7comm_tia1200_item_crc
,
8496 { "1200 sym CRC", "s7comm.tiap.item.crc", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
8497 "CRC generated out of symbolic name with (x^32+x^31+x^30+x^29+x^28+x^26+x^23+x^21+x^19+x^18+x^15+x^14+x^13+x^12+x^9+x^8+x^4+x+1)", HFILL
}},
8498 { &hf_s7comm_tia1200_var_lid_flags
,
8499 { "LID flags", "s7comm.tiap.item.lid_flags", FT_UINT8
, BASE_DEC
, VALS(tia1200_var_lid_flag_names
), 0xf0,
8501 { &hf_s7comm_tia1200_substructure_item
,
8502 { "Substructure", "s7comm.tiap.item.substructure", FT_NONE
, BASE_NONE
, NULL
, 0x0,
8504 { &hf_s7comm_tia1200_item_value
,
8505 { "Value", "s7comm.tiap.item.value", FT_UINT32
, BASE_DEC
, NULL
, 0x0fffffff,
8508 /* Fragment fields */
8509 { &hf_s7comm_fragment_overlap
,
8510 { "Fragment overlap", "s7comm.fragment.overlap", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
8511 "Fragment overlaps with other fragments", HFILL
}},
8512 { &hf_s7comm_fragment_overlap_conflict
,
8513 { "Conflicting data in fragment overlap", "s7comm.fragment.overlap.conflict", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
8514 "Overlapping fragments contained conflicting data", HFILL
}},
8515 { &hf_s7comm_fragment_multiple_tails
,
8516 { "Multiple tail fragments found", "s7comm.fragment.multipletails", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
8517 "Several tails were found when defragmenting the packet", HFILL
}},
8518 { &hf_s7comm_fragment_too_long_fragment
,
8519 { "Fragment too long", "s7comm.fragment.toolongfragment", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
8520 "Fragment contained data past end of packet", HFILL
}},
8521 { &hf_s7comm_fragment_error
,
8522 { "Defragmentation error", "s7comm.fragment.error", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
8523 "Defragmentation error due to illegal fragments", HFILL
}},
8524 { &hf_s7comm_fragment_count
,
8525 { "Fragment count", "s7comm.fragment.count", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
8527 { &hf_s7comm_reassembled_in
,
8528 { "Reassembled in", "s7comm.reassembled.in", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
8529 "S7COMM fragments are reassembled in the given packet", HFILL
}},
8530 { &hf_s7comm_reassembled_length
,
8531 { "Reassembled S7COMM length", "s7comm.reassembled.length", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
8532 "The total length of the reassembled payload", HFILL
}},
8533 { &hf_s7comm_fragment
,
8534 { "S7COMM Fragment", "s7comm.fragment", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
8536 { &hf_s7comm_fragments
,
8537 { "S7COMM Fragments", "s7comm.fragments", FT_NONE
, BASE_NONE
, NULL
, 0x0,
8541 static ei_register_info ei
[] = {
8542 { &ei_s7comm_data_blockcontrol_block_num_invalid
, { "s7comm.data.blockcontrol.block_number.invalid", PI_MALFORMED
, PI_ERROR
,
8543 "Block number must be a string containing an integer", EXPFILL
}},
8544 { &ei_s7comm_ud_blockinfo_block_num_ascii_invalid
, { "s7comm.data.blockinfo.block_number.invalid", PI_MALFORMED
, PI_ERROR
,
8545 "Block info must be a string containing an integer", EXPFILL
}}
8548 static int *ett
[] = {
8552 &ett_s7comm_param_item
,
8553 &ett_s7comm_param_subitem
,
8555 &ett_s7comm_data_item
,
8556 &ett_s7comm_item_address
,
8557 &ett_s7comm_diagdata_registerflag
,
8558 &ett_s7comm_userdata_blockinfo_flags
,
8559 &ett_s7comm_cpu_alarm_message
,
8560 &ett_s7comm_cpu_alarm_message_object
,
8561 &ett_s7comm_cpu_alarm_message_signal
,
8562 &ett_s7comm_cpu_alarm_message_timestamp
,
8563 &ett_s7comm_cpu_alarm_message_associated_value
,
8564 &ett_s7comm_cpu_diag_msg
,
8565 &ett_s7comm_cpu_diag_msg_eventid
,
8566 &ett_s7comm_cpu_msgservice_subscribe_events
,
8567 &ett_s7comm_piservice_parameterblock
,
8568 &ett_s7comm_data_blockcontrol_status
,
8569 &ett_s7comm_plcfilename
,
8570 &ett_s7comm_prog_parameter
,
8571 &ett_s7comm_prog_data
,
8572 &ett_s7comm_fragments
,
8573 &ett_s7comm_fragment
,
8576 proto_s7comm
= proto_register_protocol ("S7 Communication", "S7COMM", "s7comm");
8578 proto_register_field_array(proto_s7comm
, hf
, array_length (hf
));
8580 s7comm_register_szl_types(proto_s7comm
);
8582 proto_register_subtree_array(ett
, array_length (ett
));
8584 expert_s7comm
= expert_register_protocol(proto_s7comm
);
8585 expert_register_field_array(expert_s7comm
, ei
, array_length(ei
));
8587 register_init_routine(s7comm_defragment_init
);
8588 s7comm_heur_subdissector_list
= register_heur_dissector_list_with_description("s7comm-bsend", "S7COMM BSEND/BRECV", proto_s7comm
);
8591 /* Register this protocol */
8593 proto_reg_handoff_s7comm(void)
8595 /* register ourself as an heuristic cotp (ISO 8073) payload dissector */
8596 heur_dissector_add("cotp", dissect_s7comm
, "S7 Communication over COTP", "s7comm_cotp", proto_s7comm
, HEURISTIC_ENABLE
);
8597 heur_dissector_add("cotp_is", dissect_s7comm
, "S7 Communication over COTP (inactive subset)", "s7comm_cotp_is", proto_s7comm
, HEURISTIC_ENABLE
);
8601 * Editor modelines - https://www.wireshark.org/tools/modelines.html
8606 * indent-tabs-mode: nil
8609 * vi: set shiftwidth=4 tabstop=8 expandtab:
8610 * :indentSize=4:tabSize=8:noTabs=true: