2 * Routines for DNP dissection
3 * Copyright 2003, 2006, 2007, 2013 Graham Bloice <graham.bloice<at>trihedral.com>
5 * DNP3.0 Application Layer Object dissection added by Chris Bontje (cbontje<at>gmail.com)
6 * Device attribute and Secure Authentication object dissection added by Chris Bontje
7 * Copyright 2005, 2013, 2023
9 * Major updates: tcp and application layer defragmentation, more object dissections by Graham Bloice
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * SPDX-License-Identifier: GPL-2.0-or-later
22 #include <epan/packet.h>
23 #include <epan/prefs.h>
24 #include <epan/reassemble.h>
25 #include "packet-tcp.h"
26 #include "packet-udp.h"
27 #include <epan/expert.h>
28 #include <epan/to_str.h>
29 #include <epan/crc16-tvb.h>
31 #include <epan/unit_strings.h>
32 #include <wsutil/crc16.h>
33 #include <wsutil/str_util.h>
34 #include <wsutil/utf8_entities.h>
35 #include <epan/conversation.h>
36 #include <epan/proto_data.h>
38 #include <epan/conversation_table.h>
39 #include "packet-tls.h"
46 * although note that you have to join the DNP organization to get to
47 * see the protocol specs online - otherwise, you have to buy a
50 * ...Application Layer Notes...
52 * Application Layer Decoding based on information available in
53 * DNP3 Basic 4 Documentation Set, specifically the document:
54 * "DNP V3.00 Application Layer" v0.03 P009-0PD.APP & Technical Bulletins
56 * ---------------------------------------------------------------------------
58 * Several command codes were missing, causing the dissector to abort decoding
59 * on valid packets. Those commands have been added.
61 * The semantics of Variation 0 have been cleaned up. Variation 0 is the
62 * "Default Variation". It is used only in Master -> Slave read commands
63 * to request the data in whatever variation the Slave is configured to use by
64 * default. Decoder strings have been added to the Binary Output and
65 * Analog Output objects (10 and 40) so that group read commands will
68 * Roy M. Silvernail <roy@rant-central.com> 01/05/2009
72 /***************************************************************************/
73 /* DNP 3.0 Constants */
74 /***************************************************************************/
75 #define DNP_HDR_LEN 10
76 #define TCP_PORT_DNP 20000
77 #define UDP_PORT_DNP 20000
78 #define TCP_PORT_DNP_TLS 19999
80 /***************************************************************************/
81 /* Datalink and Transport Layer Bit-Masks */
82 /***************************************************************************/
83 #define DNP3_CTL_DIR 0x80
84 #define DNP3_CTL_PRM 0x40
85 #define DNP3_CTL_FCB 0x20
86 #define DNP3_CTL_FCV 0x10
87 #define DNP3_CTL_RES 0x20
88 #define DNP3_CTL_DFC 0x10
89 #define DNP3_CTL_FUNC 0x0f
91 #define DNP3_TR_FIR 0x40
92 #define DNP3_TR_FIN 0x80
93 #define DNP3_TR_SEQ 0x3f
95 #define AL_MAX_CHUNK_SIZE 16
97 /***************************************************************************/
98 /* Data Link Function codes */
99 /***************************************************************************/
100 /* Primary to Secondary */
101 #define DL_FUNC_RESET_LINK 0x00
102 #define DL_FUNC_RESET_PROC 0x01
103 #define DL_FUNC_TEST_LINK 0x02
104 #define DL_FUNC_USER_DATA 0x03
105 #define DL_FUNC_UNC_DATA 0x04
106 #define DL_FUNC_LINK_STAT 0x09
108 /* Secondary to Primary */
109 #define DL_FUNC_ACK 0x00
110 #define DL_FUNC_NACK 0x01
111 #define DL_FUNC_STAT_LINK 0x0B
112 #define DL_FUNC_NO_FUNC 0x0E
113 #define DL_FUNC_NOT_IMPL 0x0F
115 /***************************************************************************/
116 /* Application Layer Bit-Masks */
117 /***************************************************************************/
118 #define DNP3_AL_UNS 0x10
119 #define DNP3_AL_CON 0x20
120 #define DNP3_AL_FIN 0x40
121 #define DNP3_AL_FIR 0x80
122 #define DNP3_AL_SEQ 0x0f
123 #define DNP3_AL_FUNC 0xff
125 /***************************************************************************/
126 /* Application Layer Function codes */
127 /***************************************************************************/
128 #define AL_FUNC_CONFIRM 0x00 /* 00 - Confirm */
129 #define AL_FUNC_READ 0x01 /* 01 - Read */
130 #define AL_FUNC_WRITE 0x02 /* 02 - Write */
131 #define AL_FUNC_SELECT 0x03 /* 03 - Select */
132 #define AL_FUNC_OPERATE 0x04 /* 04 - Operate */
133 #define AL_FUNC_DIROP 0x05 /* 05 - Direct Operate */
134 #define AL_FUNC_DIROPNACK 0x06 /* 06 - Direct Operate No ACK */
135 #define AL_FUNC_FRZ 0x07 /* 07 - Immediate Freeze */
136 #define AL_FUNC_FRZNACK 0x08 /* 08 - Immediate Freeze No ACK */
137 #define AL_FUNC_FRZCLR 0x09 /* 09 - Freeze and Clear */
138 #define AL_FUNC_FRZCLRNACK 0x0A /* 10 - Freeze and Clear No ACK */
139 #define AL_FUNC_FRZT 0x0B /* 11 - Freeze With Time */
140 #define AL_FUNC_FRZTNACK 0x0C /* 12 - Freeze With Time No ACK */
141 #define AL_FUNC_COLDRST 0x0D /* 13 - Cold Restart */
142 #define AL_FUNC_WARMRST 0x0E /* 14 - Warm Restart */
143 #define AL_FUNC_INITDATA 0x0F /* 15 - Initialize Data */
144 #define AL_FUNC_INITAPP 0x10 /* 16 - Initialize Application */
145 #define AL_FUNC_STARTAPP 0x11 /* 17 - Start Application */
146 #define AL_FUNC_STOPAPP 0x12 /* 18 - Stop Application */
147 #define AL_FUNC_SAVECFG 0x13 /* 19 - Save Configuration */
148 #define AL_FUNC_ENSPMSG 0x14 /* 20 - Enable Spontaneous Msg */
149 #define AL_FUNC_DISSPMSG 0x15 /* 21 - Disable Spontaneous Msg */
150 #define AL_FUNC_ASSIGNCL 0x16 /* 22 - Assign Classes */
151 #define AL_FUNC_DELAYMST 0x17 /* 23 - Delay Measurement */
152 #define AL_FUNC_RECCT 0x18 /* 24 - Record Current Time */
153 #define AL_FUNC_OPENFILE 0x19 /* 25 - Open File */
154 #define AL_FUNC_CLOSEFILE 0x1A /* 26 - Close File */
155 #define AL_FUNC_DELETEFILE 0x1B /* 27 - Delete File */
156 #define AL_FUNC_GETFILEINF 0x1C /* 28 - Get File Info */
157 #define AL_FUNC_AUTHFILE 0x1D /* 29 - Authenticate File */
158 #define AL_FUNC_ABORTFILE 0x1E /* 30 - Abort File */
159 #define AL_FUNC_ACTCNF 0x1F /* 31 - Activate Config */
160 #define AL_FUNC_AUTHREQ 0x20 /* 32 - Authentication Request */
161 #define AL_FUNC_AUTHERR 0x21 /* 33 - Authentication Error */
162 #define AL_FUNC_RESPON 0x81 /* 129 - Response */
163 #define AL_FUNC_UNSOLI 0x82 /* 130 - Unsolicited Response */
164 #define AL_FUNC_AUTHRESP 0x83 /* 131 - Authentication Response */
166 /***************************************************************************/
167 /* Application Layer Internal Indication (IIN) bits */
168 /* 2 Bytes, message formatting: [First Octet] | [Second Octet] */
169 /***************************************************************************/
171 #define AL_IIN_BMSG 0x0100 /* Bit 0 - Broadcast message rx'd */
172 #define AL_IIN_CLS1D 0x0200 /* Bit 1 - Class 1 Data Available */
173 #define AL_IIN_CLS2D 0x0400 /* Bit 2 - Class 2 Data Available */
174 #define AL_IIN_CLS3D 0x0800 /* Bit 3 - Class 3 Data Available */
175 #define AL_IIN_TSR 0x1000 /* Bit 4 - Time Sync Req'd from Master */
176 #define AL_IIN_DOL 0x2000 /* Bit 5 - Outputs in Local Mode */
177 #define AL_IIN_DT 0x4000 /* Bit 6 - Device Trouble */
178 #define AL_IIN_RST 0x8000 /* Bit 7 - Device Restart */
181 #define AL_IIN_FCNI 0x0001 /* Bit 0 - Function code not implemented */
182 #define AL_IIN_OBJU 0x0002 /* Bit 1 - Requested Objects Unknown */
183 #define AL_IIN_PIOOR 0x0004 /* Bit 2 - Parameters Invalid or Out of Range */
184 #define AL_IIN_EBO 0x0008 /* Bit 3 - Event Buffer Overflow */
185 #define AL_IIN_OAE 0x0010 /* Bit 4 - Operation Already Executing */
186 #define AL_IIN_CC 0x0020 /* Bit 5 - Device Configuration Corrupt */
187 /* 0x0040 Bit 6 - Reserved */
188 /* 0x0080 Bit 7 - Reserved */
190 /***************************************************************************/
191 /* Application Layer Data Object Qualifier */
192 /***************************************************************************/
194 #define AL_OBJQ_PREFIX 0x70 /* x111xxxx Masks Prefix from Qualifier */
195 #define AL_OBJQ_RANGE 0x0F /* xxxx1111 Masks Range from Qualifier */
197 /* Index Size (3-bits x111xxxx) */
198 /* When Qualifier Code != 11 */
199 #define AL_OBJQL_PREFIX_NI 0x00 /* Objects are Packed with no index */
200 #define AL_OBJQL_PREFIX_1O 0x01 /* Objects are prefixed w/ 1-octet index */
201 #define AL_OBJQL_PREFIX_2O 0x02 /* Objects are prefixed w/ 2-octet index */
202 #define AL_OBJQL_PREFIX_4O 0x03 /* Objects are prefixed w/ 4-octet index */
203 #define AL_OBJQL_PREFIX_1OS 0x04 /* Objects are prefixed w/ 1-octet object size */
204 #define AL_OBJQL_PREFIX_2OS 0x05 /* Objects are prefixed w/ 2-octet object size */
205 #define AL_OBJQL_PREFIX_4OS 0x06 /* Objects are prefixed w/ 4-octet object size */
207 /* When Qualifier Code == 11 */
208 #define AL_OBJQL_IDX11_1OIS 0x01 /* 1 octet identifier size */
209 #define AL_OBJQL_IDX11_2OIS 0x02 /* 2 octet identifier size */
210 #define AL_OBJQL_IDX11_4OIS 0x03 /* 4 octet identifier size */
212 /* Qualifier Code (4-bits) */
213 /* 4-bits ( xxxx1111 ) */
214 #define AL_OBJQL_RANGE_SSI8 0x00 /* 00 8-bit Start and Stop Indices in Range Field */
215 #define AL_OBJQL_RANGE_SSI16 0x01 /* 01 16-bit Start and Stop Indices in Range Field */
216 #define AL_OBJQL_RANGE_SSI32 0x02 /* 02 32-bit Start and Stop Indices in Range Field */
217 #define AL_OBJQL_RANGE_AA8 0x03 /* 03 8-bit Absolute Address in Range Field */
218 #define AL_OBJQL_RANGE_AA16 0x04 /* 04 16-bit Absolute Address in Range Field */
219 #define AL_OBJQL_RANGE_AA32 0x05 /* 05 32-bit Absolute Address in Range Field */
220 #define AL_OBJQL_RANGE_R0 0x06 /* 06 Length of Range field is 0 (no range field) */
221 #define AL_OBJQL_RANGE_SF8 0x07 /* 07 8-bit Single Field Quantity */
222 #define AL_OBJQL_RANGE_SF16 0x08 /* 08 16-bit Single Field Quantity */
223 #define AL_OBJQL_RANGE_SF32 0x09 /* 09 32-bit Single Field Quantity */
224 /* 0x0A 10 Reserved */
225 #define AL_OBJQL_RANGE_FF 0x0B /* 11 Free-format Qualifier, range field has 1 octet count of objects */
226 /* 0x0C 12 Reserved */
227 /* 0x0D 13 Reserved */
228 /* 0x0E 14 Reserved */
229 /* 0x0F 15 Reserved */
231 /***************************************************************************/
232 /* Application Layer Data Object Definitions */
233 /***************************************************************************/
235 /* Masks for Object group and variation */
236 #define AL_OBJ_GRP_MASK 0xFF00
237 #define AL_OBJ_VAR_MASK 0x00FF
239 /* Accessors for group and mask */
240 #define AL_OBJ_GROUP(GV) (((GV) & AL_OBJ_GRP_MASK) >> 8)
241 #define AL_OBJ_VARIATION(GV) ((GV) & AL_OBJ_VAR_MASK)
243 /* Data Type values */
244 #define AL_DATA_TYPE_NONE 0x0
245 #define AL_DATA_TYPE_VSTR 0x1
246 #define AL_DATA_TYPE_UINT 0x2
247 #define AL_DATA_TYPE_INT 0x3
248 #define AL_DATA_TYPE_FLT 0x4
249 #define AL_DATA_TYPE_OSTR 0x5
250 #define AL_DATA_TYPE_BSTR 0x6
251 #define AL_DATA_TYPE_TIME 0x7
252 #define AL_DATA_TYPE_UNCD 0x8
253 #define AL_DATA_TYPE_U8BS8LIST 0xFE
254 #define AL_DATA_TYPE_U8BS8EXLIST 0xFF
256 /* Device Attributes */
257 #define AL_OBJ_DA_GRP 0x0000 /* 00 00 Device Attributes Group and null variation */
258 #define AL_OBJ_DA_CFG_ID 0x00C4 /* 00 196 Device Attributes - Configuration ID */
259 #define AL_OBJ_DA_CFG_VER 0x00C5 /* 00 197 Device Attributes - Configuration version */
260 #define AL_OBJ_DA_CFG_BLD_DATE 0x00C6 /* 00 198 Device Attributes - Configuration build date */
261 #define AL_OBJ_DA_CFG_CHG_DATE 0x00C7 /* 00 199 Device Attributes - Configuration last change date */
262 #define AL_OBJ_DA_CFG_SIG 0x00C8 /* 00 200 Device Attributes - Configuration signature */
263 #define AL_OBJ_DA_CFG_SIG_ALG 0x00C9 /* 00 201 Device Attributes - Configuration signature algorithm */
264 #define AL_OBJ_DA_MRID 0x00CA /* 00 202 Device Attributes - Master Resource ID (mRID) */
265 #define AL_OBJ_DA_ALT 0x00CB /* 00 203 Device Attributes - Device altitude */
266 #define AL_OBJ_DA_LONG 0x00CC /* 00 204 Device Attributes - Device longitude */
267 #define AL_OBJ_DA_LAT 0x00CD /* 00 205 Device Attributes - Device latitude */
268 #define AL_OBJ_DA_SEC_OP 0x00CE /* 00 206 Device Attributes - User-assigned secondary operator name */
269 #define AL_OBJ_DA_PRM_OP 0x00CF /* 00 207 Device Attributes - User-assigned primary operator name */
270 #define AL_OBJ_DA_SYS_NAME 0x00D0 /* 00 208 Device Attributes - User-assigned system name */
271 #define AL_OBJ_DA_SEC_VER 0x00D1 /* 00 209 Device Attributes - Secure authentication version */
272 #define AL_OBJ_DA_SEC_STAT 0x00D2 /* 00 210 Device Attributes - Number of security statistics per association */
273 #define AL_OBJ_DA_USR_ATTR 0x00D3 /* 00 211 Device Attributes - Identifier of support for user-specific attributes */
274 #define AL_OBJ_DA_MSTR_DSP 0x00D4 /* 00 212 Device Attributes - Number of master-defined data set prototypes */
275 #define AL_OBJ_DA_OS_DSP 0x00D5 /* 00 213 Device Attributes - Number of outstation-defined data set prototypes */
276 #define AL_OBJ_DA_MSTR_DS 0x00D6 /* 00 214 Device Attributes - Number of master-defined data sets */
277 #define AL_OBJ_DA_OS_DS 0x00D7 /* 00 215 Device Attributes - Number of outstation-defined data sets */
278 #define AL_OBJ_DA_BO_REQ 0x00D8 /* 00 216 Device Attributes - Max number of binary outputs per request */
279 #define AL_OBJ_DA_LOC_TA 0x00D9 /* 00 217 Device Attributes - Local timing accuracy */
280 #define AL_OBJ_DA_DUR_TA 0x00DA /* 00 218 Device Attributes - Duration of timing accuracy */
281 #define AL_OBJ_DA_AO_EVT 0x00DB /* 00 219 Device Attributes - Support for analog output events */
282 #define AL_OBJ_DA_MAX_AO 0x00DC /* 00 220 Device Attributes - Max analog output index */
283 #define AL_OBJ_DA_NUM_AO 0x00DD /* 00 221 Device Attributes - Number of analog outputs */
284 #define AL_OBJ_DA_BO_EVT 0x00DE /* 00 222 Device Attributes - Support for binary output events */
285 #define AL_OBJ_DA_MAX_BO 0x00DF /* 00 223 Device Attributes - Max binary output index */
286 #define AL_OBJ_DA_NUM_BO 0x00E0 /* 00 224 Device Attributes - Number of binary outputs */
287 #define AL_OBJ_DA_FCTR_EVT 0x00E1 /* 00 225 Device Attributes - Support for frozen counter events */
288 #define AL_OBJ_DA_FCTR 0x00E2 /* 00 226 Device Attributes - Support for frozen counters */
289 #define AL_OBJ_DA_CTR_EVT 0x00E3 /* 00 227 Device Attributes - Support for counter events */
290 #define AL_OBJ_DA_MAX_CTR 0x00E4 /* 00 228 Device Attributes - Max counter index */
291 #define AL_OBJ_DA_NUM_CTR 0x00E5 /* 00 229 Device Attributes - Number of counter points */
292 #define AL_OBJ_DA_AIF 0x00E6 /* 00 230 Device Attributes - Support for frozen analog inputs */
293 #define AL_OBJ_DA_AI_EVT 0x00E7 /* 00 231 Device Attributes - Support for analog input events */
294 #define AL_OBJ_DA_MAX_AI 0x00E8 /* 00 232 Device Attributes - Maximum analog input index */
295 #define AL_OBJ_DA_NUM_AI 0x00E9 /* 00 233 Device Attributes - Number of analog input points */
296 #define AL_OBJ_DA_2BI_EVT 0x00EA /* 00 234 Device Attributes - Support for Double-Bit BI Events */
297 #define AL_OBJ_DA_MAX_2BI 0x00EB /* 00 235 Device Attributes - Max Double-bit BI Point Index */
298 #define AL_OBJ_DA_NUM_2BI 0x00EC /* 00 236 Device Attributes - Number of Double-bit BI Points */
299 #define AL_OBJ_DA_BI_EVT 0x00ED /* 00 237 Device Attributes - Support for Binary Input Events */
300 #define AL_OBJ_DA_MAX_BI 0x00EE /* 00 238 Device Attributes - Max Binary Input Point Index */
301 #define AL_OBJ_DA_NUM_BI 0x00EF /* 00 239 Device Attributes - Number of Binary Input Points */
302 #define AL_OBJ_DA_MXTX_FR 0x00F0 /* 00 240 Device Attributes - Maximum Transmit Fragment Size */
303 #define AL_OBJ_DA_MXRX_FR 0x00F1 /* 00 241 Device Attributes - Maximum Receive Fragment Size */
304 #define AL_OBJ_DA_SWVER 0x00F2 /* 00 242 Device Attributes - Device Manufacturers SW Version */
305 #define AL_OBJ_DA_HWVER 0x00F3 /* 00 243 Device Attributes - Device Manufacturers HW Version */
306 #define AL_OBJ_DA_OWNER 0x00F4 /* 00 244 Device Attributes - User-assigned owner name */
307 #define AL_OBJ_DA_LOC 0x00F5 /* 00 245 Device Attributes - User-Assigned Location */
308 #define AL_OBJ_DA_ID 0x00F6 /* 00 246 Device Attributes - User-Assigned ID code/number */
309 #define AL_OBJ_DA_DEVNAME 0x00F7 /* 00 247 Device Attributes - User-Assigned Device Name */
310 #define AL_OBJ_DA_SERNUM 0x00F8 /* 00 248 Device Attributes - Device Serial Number */
311 #define AL_OBJ_DA_CONF 0x00F9 /* 00 249 Device Attributes - DNP Subset and Conformance */
312 #define AL_OBJ_DA_PROD 0x00FA /* 00 250 Device Attributes - Device Product Name and Model */
313 /* 00 251 Future Assignment */
314 #define AL_OBJ_DA_MFG 0x00FC /* 00 252 Device Attributes - Device Manufacturers Name */
315 /* 00 253 Future Assignment */
316 #define AL_OBJ_DA_ALL 0x00FE /* 00 254 Device Attributes - Non-specific All-attributes Req */
317 #define AL_OBJ_DA_LVAR 0x00FF /* 00 255 Device Attributes - List of Attribute Variations */
319 /* Binary Input Objects */
320 #define AL_OBJ_BI_ALL 0x0100 /* 01 00 Binary Input Default Variation */
321 #define AL_OBJ_BI_1BIT 0x0101 /* 01 01 Single-bit Binary Input */
322 #define AL_OBJ_BI_STAT 0x0102 /* 01 02 Binary Input With Status */
323 #define AL_OBJ_BIC_ALL 0x0200 /* 02 00 Binary Input Change Default Variation */
324 #define AL_OBJ_BIC_NOTIME 0x0201 /* 02 01 Binary Input Change Without Time */
325 #define AL_OBJ_BIC_TIME 0x0202 /* 02 02 Binary Input Change With Time */
326 #define AL_OBJ_BIC_RTIME 0x0203 /* 02 03 Binary Input Change With Relative Time */
328 /* Double-bit Input Objects */
329 #define AL_OBJ_2BI_ALL 0x0300 /* 03 00 Double-bit Input Default Variation */
330 #define AL_OBJ_2BI_NF 0x0301 /* 03 01 Double-bit Input No Flags */
331 #define AL_OBJ_2BI_STAT 0x0302 /* 03 02 Double-bit Input With Status */
332 #define AL_OBJ_2BIC_ALL 0x0400 /* 04 00 Double-bit Input Change Default Variation */
333 #define AL_OBJ_2BIC_NOTIME 0x0401 /* 04 01 Double-bit Input Change Without Time */
334 #define AL_OBJ_2BIC_TIME 0x0402 /* 04 02 Double-bit Input Change With Time */
335 #define AL_OBJ_2BIC_RTIME 0x0403 /* 04 03 Double-bit Input Change With Relative Time */
337 /* Binary Input Quality Flags */
338 #define AL_OBJ_BI_FLAG0 0x01 /* Point Online (0=Offline; 1=Online) */
339 #define AL_OBJ_BI_FLAG1 0x02 /* Restart (0=Normal; 1=Restart) */
340 #define AL_OBJ_BI_FLAG2 0x04 /* Comms Lost (0=Normal; 1=Lost) */
341 #define AL_OBJ_BI_FLAG3 0x08 /* Remote Force (0=Normal; 1=Forced) */
342 #define AL_OBJ_BI_FLAG4 0x10 /* Local Force (0=Normal; 1=Forced) */
343 #define AL_OBJ_BI_FLAG5 0x20 /* Chatter Filter (0=Normal; 1=Filter On) */
344 #define AL_OBJ_BI_FLAG6 0x40 /* Double-bit LSB (0=Off; 1=On) */
345 #define AL_OBJ_BI_FLAG7 0x80 /* Point State (0=Off; 1=On) or Double-bit MSB */
347 #define AL_OBJ_2BI_STATE_INTERMEDIATE 0x00
348 #define AL_OBJ_2BI_STATE_OFF 0x01
349 #define AL_OBJ_2BI_STATE_ON 0x02
350 #define AL_OBJ_2BI_STATE_INDETERM 0x03
352 #define AL_OBJ_DBI_MASK 0xC0 /* Double bit point state mask
353 (0 = Intermediate, 1 = Determined off, 2 = Determined on, 3 = Indeterminate */
355 /***************************************************************************/
356 /* Binary Output Objects */
357 #define AL_OBJ_BO_ALL 0x0A00 /* 10 00 Binary Output Default Variation */
358 #define AL_OBJ_BO 0x0A01 /* 10 01 Binary Output */
359 #define AL_OBJ_BO_STAT 0x0A02 /* 10 02 Binary Output Status */
360 #define AL_OBJ_BOC_ALL 0x0B00 /* 11 00 Binary Output Change Default Variation */
361 #define AL_OBJ_BOC_NOTIME 0x0B01 /* 11 01 Binary Output Change Without Time */
362 #define AL_OBJ_BOC_TIME 0x0B02 /* 11 02 Binary Output Change With Time */
363 #define AL_OBJ_CTLOP_BLK 0x0C01 /* 12 01 Control Relay Output Block */
364 #define AL_OBJ_CTL_PCB 0x0C02 /* 12 02 Pattern Control Block */
365 #define AL_OBJ_CTL_PMASK 0x0C03 /* 12 03 Pattern Mask */
366 #define AL_OBJ_BOE_NOTIME 0x0D01 /* 13 01 Binary Output Command Event Without Time */
367 #define AL_OBJ_BOE_TIME 0x0D02 /* 13 02 Binary Output Command Event With Time */
369 #define AL_OBJCTLC_CODE 0x0F /* Bit-Mask xxxx1111 for Control Code 'Code' */
370 #define AL_OBJCTLC_MISC 0x30 /* Bit-Mask xx11xxxx for Control Code Queue (obsolete) and Clear Fields */
371 #define AL_OBJCTLC_TC 0xC0 /* Bit-Mask 11xxxxxx for Control Code 'Trip/Close' */
373 #define AL_OBJCTLC_CODE0 0x00 /* xxxx0000 NUL Operation; only process R attribute */
374 #define AL_OBJCTLC_CODE1 0x01 /* xxxx0001 Pulse On ^On-Time -> vOff-Time, remain off */
375 #define AL_OBJCTLC_CODE2 0x02 /* xxxx0010 Pulse Off vOff-Time -> ^On-Time, remain on */
376 #define AL_OBJCTLC_CODE3 0x03 /* xxxx0011 Latch On */
377 #define AL_OBJCTLC_CODE4 0x04 /* xxxx0100 Latch Off */
378 /* 0x05-0x15 Reserved */
380 #define AL_OBJCTLC_NOTSET 0x00 /* xx00xxxx for Control Code, Clear and Queue not set */
381 #define AL_OBJCTLC_QUEUE 0x01 /* xxx1xxxx for Control Code, Clear Field 'Queue' */
382 #define AL_OBJCTLC_CLEAR 0x02 /* xx1xxxxx for Control Code, Clear Field 'Clear' */
383 #define AL_OBJCTLC_BOTHSET 0x03 /* xx11xxxx for Control Code, Clear and Queue both set */
385 #define AL_OBJCTLC_TC0 0x00 /* 00xxxxxx NUL */
386 #define AL_OBJCTLC_TC1 0x01 /* 01xxxxxx Close */
387 #define AL_OBJCTLC_TC2 0x02 /* 10xxxxxx Trip */
388 #define AL_OBJCTLC_TC3 0x03 /* 11xxxxxx Reserved */
390 #define AL_OBJCTL_STAT0 0x00 /* Request Accepted, Initiated or Queued */
391 #define AL_OBJCTL_STAT1 0x01 /* Request Not Accepted; Arm-timer expired */
392 #define AL_OBJCTL_STAT2 0x02 /* Request Not Accepted; No 'SELECT' rx'd */
393 #define AL_OBJCTL_STAT3 0x03 /* Request Not Accepted; Format errors in ctrl request */
394 #define AL_OBJCTL_STAT4 0x04 /* Control Operation Not Supported for this point */
395 #define AL_OBJCTL_STAT5 0x05 /* Request Not Accepted; Ctrl Queue full or pt. active */
396 #define AL_OBJCTL_STAT6 0x06 /* Request Not Accepted; Ctrl HW Problems */
397 #define AL_OBJCTL_STAT7 0x07 /* Request Not Accepted; Local/Remote switch in Local*/
398 #define AL_OBJCTL_STAT8 0x08 /* Request Not Accepted; Too many operations requested */
399 #define AL_OBJCTL_STAT9 0x09 /* Request Not Accepted; Insufficient authorization */
400 #define AL_OBJCTL_STAT10 0x0A /* Request Not Accepted; Local automation proc active */
401 #define AL_OBJCTL_STAT11 0x0B /* Request Not Accepted; Processing limited */
402 #define AL_OBJCTL_STAT12 0x0C /* Request Not Accepted; Out of range value */
403 #define AL_OBJCTL_STAT126 0x7E /* Non Participating (NOP request) */
404 #define AL_OBJCTL_STAT127 0x7F /* Request Not Accepted; Undefined error */
406 #define AL_OBJCTL_STATUS_MASK 0x7F
408 /* Binary Output Quality Flags */
409 #define AL_OBJ_BO_FLAG0 0x01 /* Point Online (0=Offline; 1=Online) */
410 #define AL_OBJ_BO_FLAG1 0x02 /* Restart (0=Normal; 1=Restart) */
411 #define AL_OBJ_BO_FLAG2 0x04 /* Comms Lost (0=Normal; 1=Lost) */
412 #define AL_OBJ_BO_FLAG3 0x08 /* Remote Force (0=Normal; 1=Forced) */
413 #define AL_OBJ_BO_FLAG4 0x10 /* Local Force (0=Normal; 1=Forced) */
414 #define AL_OBJ_BO_FLAG5 0x20 /* Reserved */
415 #define AL_OBJ_BO_FLAG6 0x40 /* Reserved */
416 #define AL_OBJ_BO_FLAG7 0x80 /* Point State (0=Off; 1=On) */
418 /***************************************************************************/
419 /* Counter Objects */
420 #define AL_OBJ_CTR_ALL 0x1400 /* 20 00 Binary Counter Default Variation */
421 #define AL_OBJ_CTR_32 0x1401 /* 20 01 32-Bit Binary Counter */
422 #define AL_OBJ_CTR_16 0x1402 /* 20 02 16-Bit Binary Counter */
423 #define AL_OBJ_DCTR_32 0x1403 /* 20 03 32-Bit Delta Counter */
424 #define AL_OBJ_DCTR_16 0x1404 /* 20 04 16-Bit Delta Counter */
425 #define AL_OBJ_CTR_32NF 0x1405 /* 20 05 32-Bit Binary Counter Without Flag */
426 #define AL_OBJ_CTR_16NF 0x1406 /* 20 06 16-Bit Binary Counter Without Flag */
427 #define AL_OBJ_DCTR_32NF 0x1407 /* 20 07 32-Bit Delta Counter Without Flag */
428 #define AL_OBJ_DCTR_16NF 0x1408 /* 20 08 16-Bit Delta Counter Without Flag */
429 #define AL_OBJ_FCTR_ALL 0x1500 /* 21 00 Frozen Binary Counter Default Variation */
430 #define AL_OBJ_FCTR_32 0x1501 /* 21 01 32-Bit Frozen Counter */
431 #define AL_OBJ_FCTR_16 0x1502 /* 21 02 16-Bit Frozen Counter */
432 #define AL_OBJ_FDCTR_32 0x1503 /* 21 03 32-Bit Frozen Delta Counter */
433 #define AL_OBJ_FDCTR_16 0x1504 /* 21 04 16-Bit Frozen Delta Counter */
434 #define AL_OBJ_FCTR_32T 0x1505 /* 21 05 32-Bit Frozen Counter w/ Time of Freeze */
435 #define AL_OBJ_FCTR_16T 0x1506 /* 21 06 16-Bit Frozen Counter w/ Time of Freeze */
436 #define AL_OBJ_FDCTR_32T 0x1507 /* 21 07 32-Bit Frozen Delta Counter w/ Time of Freeze */
437 #define AL_OBJ_FDCTR_16T 0x1508 /* 21 08 16-Bit Frozen Delta Counter w/ Time of Freeze */
438 #define AL_OBJ_FCTR_32NF 0x1509 /* 21 09 32-Bit Frozen Counter Without Flag */
439 #define AL_OBJ_FCTR_16NF 0x150A /* 21 10 16-Bit Frozen Counter Without Flag */
440 #define AL_OBJ_FDCTR_32NF 0x150B /* 21 11 32-Bit Frozen Delta Counter Without Flag */
441 #define AL_OBJ_FDCTR_16NF 0x150C /* 21 12 16-Bit Frozen Delta Counter Without Flag */
442 #define AL_OBJ_CTRC_ALL 0x1600 /* 22 00 Counter Change Event Default Variation */
443 #define AL_OBJ_CTRC_32 0x1601 /* 22 01 32-Bit Counter Change Event w/o Time */
444 #define AL_OBJ_CTRC_16 0x1602 /* 22 02 16-Bit Counter Change Event w/o Time */
445 #define AL_OBJ_DCTRC_32 0x1603 /* 22 03 32-Bit Delta Counter Change Event w/o Time */
446 #define AL_OBJ_DCTRC_16 0x1604 /* 22 04 16-Bit Delta Counter Change Event w/o Time */
447 #define AL_OBJ_CTRC_32T 0x1605 /* 22 05 32-Bit Counter Change Event with Time */
448 #define AL_OBJ_CTRC_16T 0x1606 /* 22 06 16-Bit Counter Change Event with Time */
449 #define AL_OBJ_DCTRC_32T 0x1607 /* 22 07 32-Bit Delta Counter Change Event with Time */
450 #define AL_OBJ_DCTRC_16T 0x1608 /* 22 08 16-Bit Delta Counter Change Event with Time */
451 #define AL_OBJ_FCTRC_ALL 0x1700 /* 23 00 Frozen Binary Counter Change Event Default Variation */
452 #define AL_OBJ_FCTRC_32 0x1701 /* 23 01 32-Bit Frozen Counter Change Event */
453 #define AL_OBJ_FCTRC_16 0x1702 /* 23 02 16-Bit Frozen Counter Change Event */
454 #define AL_OBJ_FDCTRC_32 0x1703 /* 23 03 32-Bit Frozen Delta Counter Change Event */
455 #define AL_OBJ_FDCTRC_16 0x1704 /* 23 04 16-Bit Frozen Delta Counter Change Event */
456 #define AL_OBJ_FCTRC_32T 0x1705 /* 23 05 32-Bit Frozen Counter Change Event w/ Time of Freeze */
457 #define AL_OBJ_FCTRC_16T 0x1706 /* 23 06 16-Bit Frozen Counter Change Event w/ Time of Freeze */
458 #define AL_OBJ_FDCTRC_32T 0x1707 /* 23 07 32-Bit Frozen Delta Counter Change Event w/ Time of Freeze */
459 #define AL_OBJ_FDCTRC_16T 0x1708 /* 23 08 16-Bit Frozen Delta Counter Change Event w/ Time of Freeze */
461 /* Counter Quality Flags */
462 #define AL_OBJ_CTR_FLAG0 0x01 /* Point Online (0=Offline; 1=Online) */
463 #define AL_OBJ_CTR_FLAG1 0x02 /* Restart (0=Normal; 1=Restart) */
464 #define AL_OBJ_CTR_FLAG2 0x04 /* Comms Lost (0=Normal; 1=Lost) */
465 #define AL_OBJ_CTR_FLAG3 0x08 /* Remote Force (0=Normal; 1=Forced) */
466 #define AL_OBJ_CTR_FLAG4 0x10 /* Local Force (0=Normal; 1=Forced) */
467 #define AL_OBJ_CTR_FLAG5 0x20 /* Roll-over (0=Normal; 1=Roll-Over) */
468 #define AL_OBJ_CTR_FLAG6 0x40 /* Discontinuity (0=Normal; 1=Discontinuity) */
469 #define AL_OBJ_CTR_FLAG7 0x80 /* Reserved */
471 /***************************************************************************/
472 /* Analog Input Objects */
473 #define AL_OBJ_AI_ALL 0x1E00 /* 30 00 Analog Input Default Variation */
474 #define AL_OBJ_AI_32 0x1E01 /* 30 01 32-Bit Analog Input */
475 #define AL_OBJ_AI_16 0x1E02 /* 30 02 16-Bit Analog Input */
476 #define AL_OBJ_AI_32NF 0x1E03 /* 30 03 32-Bit Analog Input Without Flag */
477 #define AL_OBJ_AI_16NF 0x1E04 /* 30 04 16-Bit Analog Input Without Flag */
478 #define AL_OBJ_AI_FLT 0x1E05 /* 30 05 32-Bit Floating Point Input */
479 #define AL_OBJ_AI_DBL 0x1E06 /* 30 06 64-Bit Floating Point Input */
480 #define AL_OBJ_AIFC_32 0x1F01 /* 31 01 32-Bit Frozen Analog Input */
481 #define AL_OBJ_AIFC_16 0x1F02 /* 31 02 16-Bit Frozen Analog Input */
482 #define AL_OBJ_AIFC_32TOF 0x1F03 /* 31 03 32-Bit Frozen Analog Input w/ Time of Freeze */
483 #define AL_OBJ_AIFC_16TOF 0x1F04 /* 31 04 16-Bit Frozen Analog Input w/ Time of Freeze */
484 #define AL_OBJ_AIFC_32NF 0x1F05 /* 31 05 32-Bit Frozen Analog Input Without Flag */
485 #define AL_OBJ_AIFC_16NF 0x1F06 /* 31 06 16-Bit Frozen Analog Input Without Flag */
486 #define AL_OBJ_AIF_FLT 0x1F07 /* 31 07 32-Bit Frozen Floating Point Input */
487 #define AL_OBJ_AIF_DBL 0x1F08 /* 31 08 64-Bit Frozen Floating Point Input */
488 #define AL_OBJ_AIC_ALL 0x2000 /* 32 00 Analog Input Change Default Variation */
489 #define AL_OBJ_AIC_32NT 0x2001 /* 32 01 32-Bit Analog Change Event w/o Time */
490 #define AL_OBJ_AIC_16NT 0x2002 /* 32 02 16-Bit Analog Change Event w/o Time */
491 #define AL_OBJ_AIC_32T 0x2003 /* 32 03 32-Bit Analog Change Event w/ Time */
492 #define AL_OBJ_AIC_16T 0x2004 /* 32 04 16-Bit Analog Change Event w/ Time */
493 #define AL_OBJ_AIC_FLTNT 0x2005 /* 32 05 32-Bit Floating Point Change Event w/o Time*/
494 #define AL_OBJ_AIC_DBLNT 0x2006 /* 32 06 64-Bit Floating Point Change Event w/o Time*/
495 #define AL_OBJ_AIC_FLTT 0x2007 /* 32 07 32-Bit Floating Point Change Event w/ Time*/
496 #define AL_OBJ_AIC_DBLT 0x2008 /* 32 08 64-Bit Floating Point Change Event w/ Time*/
497 #define AL_OBJ_AIFC_32NT 0x2101 /* 33 01 32-Bit Frozen Analog Event w/o Time */
498 #define AL_OBJ_AIFC_16NT 0x2102 /* 33 02 16-Bit Frozen Analog Event w/o Time */
499 #define AL_OBJ_AIFC_32T 0x2103 /* 33 03 32-Bit Frozen Analog Event w/ Time */
500 #define AL_OBJ_AIFC_16T 0x2104 /* 33 04 16-Bit Frozen Analog Event w/ Time */
501 #define AL_OBJ_AIFC_FLTNT 0x2105 /* 33 05 32-Bit Floating Point Frozen Change Event w/o Time*/
502 #define AL_OBJ_AIFC_DBLNT 0x2106 /* 33 06 64-Bit Floating Point Frozen Change Event w/o Time*/
503 #define AL_OBJ_AIFC_FLTT 0x2107 /* 33 07 32-Bit Floating Point Frozen Change Event w/ Time*/
504 #define AL_OBJ_AIFC_DBLT 0x2108 /* 33 08 64-Bit Floating Point Frozen Change Event w/ Time*/
506 /* Analog Input Quality Flags */
507 #define AL_OBJ_AI_FLAG0 0x01 /* Point Online (0=Offline; 1=Online) */
508 #define AL_OBJ_AI_FLAG1 0x02 /* Restart (0=Normal; 1=Restart) */
509 #define AL_OBJ_AI_FLAG2 0x04 /* Comms Lost (0=Normal; 1=Lost) */
510 #define AL_OBJ_AI_FLAG3 0x08 /* Remote Force (0=Normal; 1=Forced) */
511 #define AL_OBJ_AI_FLAG4 0x10 /* Local Force (0=Normal; 1=Forced) */
512 #define AL_OBJ_AI_FLAG5 0x20 /* Over-Range (0=Normal; 1=Over-Range) */
513 #define AL_OBJ_AI_FLAG6 0x40 /* Reference Check (0=Normal; 1=Error) */
514 #define AL_OBJ_AI_FLAG7 0x80 /* Reserved */
516 #define AL_OBJ_AIDB_ALL 0x2200 /* 34 00 Analog Input Deadband Default Variation */
517 #define AL_OBJ_AIDB_16 0x2201 /* 34 01 16-Bit Analog Input Deadband */
518 #define AL_OBJ_AIDB_32 0x2202 /* 34 02 32-Bit Analog Input Deadband */
519 #define AL_OBJ_AIDB_FLT 0x2203 /* 34 03 Floating Point Analog Input Deadband */
521 /***************************************************************************/
522 /* Analog Output Objects */
523 #define AL_OBJ_AO_ALL 0x2800 /* 40 00 Analog Output Default Variation */
524 #define AL_OBJ_AO_32 0x2801 /* 40 01 32-Bit Analog Output Status */
525 #define AL_OBJ_AO_16 0x2802 /* 40 02 16-Bit Analog Output Status */
526 #define AL_OBJ_AO_FLT 0x2803 /* 40 03 32-Bit Floating Point Output Status */
527 #define AL_OBJ_AO_DBL 0x2804 /* 40 04 64-Bit Floating Point Output Status */
528 #define AL_OBJ_AO_32OPB 0x2901 /* 41 01 32-Bit Analog Output Block */
529 #define AL_OBJ_AO_16OPB 0x2902 /* 41 02 16-Bit Analog Output Block */
530 #define AL_OBJ_AO_FLTOPB 0x2903 /* 41 03 32-Bit Floating Point Output Block */
531 #define AL_OBJ_AO_DBLOPB 0x2904 /* 41 04 64-Bit Floating Point Output Block */
532 #define AL_OBJ_AOC_ALL 0x2A00 /* 42 00 Analog Output Event Default Variation */
533 #define AL_OBJ_AOC_32NT 0x2A01 /* 42 01 32-Bit Analog Output Event w/o Time */
534 #define AL_OBJ_AOC_16NT 0x2A02 /* 42 02 16-Bit Analog Output Event w/o Time */
535 #define AL_OBJ_AOC_32T 0x2A03 /* 42 03 32-Bit Analog Output Event w/ Time */
536 #define AL_OBJ_AOC_16T 0x2A04 /* 42 04 16-Bit Analog Output Event w/ Time */
537 #define AL_OBJ_AOC_FLTNT 0x2A05 /* 42 05 32-Bit Floating Point Output Event w/o Time */
538 #define AL_OBJ_AOC_DBLNT 0x2A06 /* 42 06 64-Bit Floating Point Output Event w/o Time */
539 #define AL_OBJ_AOC_FLTT 0x2A07 /* 42 07 32-Bit Floating Point Output Event w/ Time */
540 #define AL_OBJ_AOC_DBLT 0x2A08 /* 42 08 64-Bit Floating Point Output Event w/ Time */
541 #define AL_OBJ_AOC_32EVNT 0x2B01 /* 43 01 32-Bit Analog Output Command Event w/o Time */
542 #define AL_OBJ_AOC_16EVNT 0x2B02 /* 43 02 16-Bit Analog Output Command Event w/o Time */
543 #define AL_OBJ_AOC_32EVTT 0x2B03 /* 43 03 32-Bit Analog Output Command Event w/ Time */
544 #define AL_OBJ_AOC_16EVTT 0x2B04 /* 43 04 16-Bit Analog Output Command Event w/ Time */
545 #define AL_OBJ_AOC_FLTEVNT 0x2B05 /* 43 05 32-Bit Floating Point Analog Output Command Event w/o Time */
546 #define AL_OBJ_AOC_DBLEVNT 0x2B06 /* 43 06 64-Bit Floating PointAnalog Output Command Event w/o Time */
547 #define AL_OBJ_AOC_FLTEVTT 0x2B07 /* 43 07 32-Bit Floating Point Analog Output Command Event w/ Time */
548 #define AL_OBJ_AOC_DBLEVTT 0x2B08 /* 43 08 64-Bit Floating PointAnalog Output Command Event w/ Time */
550 /* Analog Output Quality Flags */
551 #define AL_OBJ_AO_FLAG0 0x01 /* Point Online (0=Offline; 1=Online) */
552 #define AL_OBJ_AO_FLAG1 0x02 /* Restart (0=Normal; 1=Restart) */
553 #define AL_OBJ_AO_FLAG2 0x04 /* Comms Lost (0=Normal; 1=Lost) */
554 #define AL_OBJ_AO_FLAG3 0x08 /* Remote Force (0=Normal; 1=Forced) */
555 #define AL_OBJ_AO_FLAG4 0x10 /* Local Force (0=Normal; 1=Forced) */
556 #define AL_OBJ_AO_FLAG5 0x20 /* Reserved */
557 #define AL_OBJ_AO_FLAG6 0x40 /* Reserved */
558 #define AL_OBJ_AO_FLAG7 0x80 /* Reserved */
560 /***************************************************************************/
562 #define AL_OBJ_TD_ALL 0x3200 /* 50 00 Time and Date Default Variation */
563 #define AL_OBJ_TD 0x3201 /* 50 01 Time and Date */
564 #define AL_OBJ_TDI 0x3202 /* 50 02 Time and Date w/ Interval */
565 #define AL_OBJ_TDR 0x3203 /* 50 03 Last Recorded Time and Date */
566 #define AL_OBJ_TDCTO 0x3301 /* 51 01 Time and Date CTO */
567 #define AL_OBJ_UTDCTO 0x3302 /* 51 02 Unsynchronized Time and Date CTO */
568 #define AL_OBJ_TDELAYC 0x3401 /* 52 01 Time Delay Coarse */
569 #define AL_OBJ_TDELAYF 0x3402 /* 52 02 Time Delay Fine */
571 /***************************************************************************/
572 /* Class Data Objects */
573 #define AL_OBJ_CLASS0 0x3C01 /* 60 01 Class 0 Data */
574 #define AL_OBJ_CLASS1 0x3C02 /* 60 02 Class 1 Data */
575 #define AL_OBJ_CLASS2 0x3C03 /* 60 03 Class 2 Data */
576 #define AL_OBJ_CLASS3 0x3C04 /* 60 04 Class 3 Data */
578 /***************************************************************************/
580 #define AL_OBJ_FILE_CMD 0x4603 /* 70 03 File Control - Command */
581 #define AL_OBJ_FILE_STAT 0x4604 /* 70 04 File Control - Status */
582 #define AL_OBJ_FILE_TRANS 0x4605 /* 70 05 File Control - Transport */
583 #define AL_OBJ_FILE_TRAN_ST 0x4606 /* 70 05 File Control - Transport Status */
585 /* File Control Mode flags */
586 #define AL_OBJ_FILE_MODE_NULL 0x00 /* NULL */
587 #define AL_OBJ_FILE_MODE_READ 0x01 /* READ */
588 #define AL_OBJ_FILE_MODE_WRITE 0x02 /* WRITE */
589 #define AL_OBJ_FILE_MODE_APPEND 0x03 /* APPEND */
591 /***************************************************************************/
593 #define AL_OBJ_IIN 0x5001 /* 80 01 Internal Indications */
595 /***************************************************************************/
597 #define AL_OBJ_DS_PROTO 0x5501 /* 85 01 Data-Set Prototype, with UUID */
598 #define AL_OBJ_DSD_CONT 0x5601 /* 86 01 Data-Set Descriptor, Data-Set Contents */
599 #define AL_OBJ_DSD_CHAR 0x5602 /* 86 02 Data-Set Descriptor, Characteristics */
600 #define AL_OBJ_DSD_PIDX 0x5603 /* 86 03 Data-Set Descriptor, Point Index Attributes */
601 #define AL_OBJ_DS_PV 0x5701 /* 87 01 Data-Set, Present Value */
602 #define AL_OBJ_DS_SS 0x5801 /* 88 01 Data-Set, Snapshot */
604 /***************************************************************************/
605 /* Octet String Objects */
606 #define AL_OBJ_OCT 0x6E00 /* 110 xx Octet string */
607 #define AL_OBJ_OCT_EVT 0x6F00 /* 111 xx Octet string event */
609 /***************************************************************************/
610 /* Virtual Terminal Objects */
611 #define AL_OBJ_VT_OBLK 0x7000 /* 112 xx Virtual Terminal Output Block */
612 #define AL_OBJ_VT_EVTD 0x7100 /* 113 xx Virtual Terminal Event Data */
614 /***************************************************************************/
615 /* Secure Authentication ('SA') Objects */
616 #define AL_OBJ_SA_AUTH_CH 0x7801 /* 120 01 Authentication Challenge */
617 #define AL_OBJ_SA_AUTH_RP 0x7802 /* 120 02 Authentication Reply */
618 #define AL_OBJ_SA_AUTH_AGMRQ 0x7803 /* 120 03 Authentication Aggressive Mode Request */
619 #define AL_OBJ_SA_AUTH_SKSR 0x7804 /* 120 04 Authentication Session Key Status Request */
620 #define AL_OBJ_SA_AUTH_SKS 0x7805 /* 120 05 Authentication Session Key Status */
621 #define AL_OBJ_SA_AUTH_SKC 0x7806 /* 120 06 Authentication Session Key Change */
622 #define AL_OBJ_SA_AUTH_ERR 0x7807 /* 120 07 Authentication Error */
623 #define AL_OBJ_SA_AUTH_MAC 0x7809 /* 120 09 Authentication Message Authentication Code */
624 #define AL_OBJ_SA_AUTH_USC 0x780A /* 120 10 Authentication User Status Change - Not supported */
625 #define AL_OBJ_SA_AUTH_UKCR 0x780B /* 120 11 Authentication Update Key Change Request */
626 #define AL_OBJ_SA_AUTH_UKCRP 0x780C /* 120 12 Authentication Update Key Change Reply */
627 #define AL_OBJ_SA_AUTH_UKC 0x780D /* 120 13 Authentication Update Key Change */
628 #define AL_OBJ_SA_AUTH_UKCC 0x780F /* 120 15 Authentication Update Key Change Confirmation */
629 #define AL_OBJ_SA_SECSTAT 0x7901 /* 121 01 Security Statistics */
630 #define AL_OBJ_SA_SECSTATEVT 0x7A01 /* 122 01 Security Statistic Event */
631 #define AL_OBJ_SA_SECSTATEVTT 0x7A02 /* 122 02 Security Statistic Event w/ Time */
634 /***************************************************************************/
635 /* End of Application Layer Data Object Definitions */
636 /***************************************************************************/
638 void proto_register_dnp3(void);
639 void proto_reg_handoff_dnp3(void);
641 /* Initialize the protocol and registered fields */
642 static int proto_dnp3
;
643 static int hf_dnp3_start
;
644 static int hf_dnp3_len
;
645 static int hf_dnp3_ctl
;
646 static int hf_dnp3_ctl_prifunc
;
647 static int hf_dnp3_ctl_secfunc
;
648 static int hf_dnp3_ctl_dir
;
649 static int hf_dnp3_ctl_prm
;
650 static int hf_dnp3_ctl_fcb
;
651 static int hf_dnp3_ctl_fcv
;
652 static int hf_dnp3_ctl_dfc
;
653 static int hf_dnp3_dst
;
654 static int hf_dnp3_src
;
655 static int hf_dnp3_addr
;
656 static int hf_dnp3_data_hdr_crc
;
657 static int hf_dnp3_data_hdr_crc_status
;
658 static int hf_dnp3_tr_ctl
;
659 static int hf_dnp3_tr_fin
;
660 static int hf_dnp3_tr_fir
;
661 static int hf_dnp3_tr_seq
;
662 static int hf_dnp3_data_chunk
;
663 static int hf_dnp3_data_chunk_len
;
664 static int hf_dnp3_data_chunk_crc
;
665 static int hf_dnp3_data_chunk_crc_status
;
667 /* Added for Application Layer Decoding */
668 static int hf_dnp3_al_ctl
;
669 static int hf_dnp3_al_fir
;
670 static int hf_dnp3_al_fin
;
671 static int hf_dnp3_al_con
;
672 static int hf_dnp3_al_uns
;
673 static int hf_dnp3_al_seq
;
674 static int hf_dnp3_al_func
;
675 static int hf_dnp3_al_iin
;
676 static int hf_dnp3_al_iin_bmsg
;
677 static int hf_dnp3_al_iin_cls1d
;
678 static int hf_dnp3_al_iin_cls2d
;
679 static int hf_dnp3_al_iin_cls3d
;
680 static int hf_dnp3_al_iin_tsr
;
681 static int hf_dnp3_al_iin_dol
;
682 static int hf_dnp3_al_iin_dt
;
683 static int hf_dnp3_al_iin_rst
;
684 static int hf_dnp3_al_iin_fcni
;
685 static int hf_dnp3_al_iin_obju
;
686 static int hf_dnp3_al_iin_pioor
;
687 static int hf_dnp3_al_iin_ebo
;
688 static int hf_dnp3_al_iin_oae
;
689 static int hf_dnp3_al_iin_cc
;
690 static int hf_dnp3_al_obj
;
691 static int hf_dnp3_al_objq_prefix
;
692 static int hf_dnp3_al_objq_range
;
693 static int hf_dnp3_al_range_start8
;
694 static int hf_dnp3_al_range_stop8
;
695 static int hf_dnp3_al_range_start16
;
696 static int hf_dnp3_al_range_stop16
;
697 static int hf_dnp3_al_range_start32
;
698 static int hf_dnp3_al_range_stop32
;
699 static int hf_dnp3_al_range_abs8
;
700 static int hf_dnp3_al_range_abs16
;
701 static int hf_dnp3_al_range_abs32
;
702 static int hf_dnp3_al_range_quant8
;
703 static int hf_dnp3_al_range_quant16
;
704 static int hf_dnp3_al_range_quant32
;
705 static int hf_dnp3_al_index8
;
706 static int hf_dnp3_al_index16
;
707 static int hf_dnp3_al_index32
;
708 static int hf_dnp3_al_size8
;
709 static int hf_dnp3_al_size16
;
710 static int hf_dnp3_al_size32
;
711 static int hf_dnp3_bocs_bit
;
713 /* static int hf_dnp3_al_objq;*/
714 /* static int hf_dnp3_al_nobj; */
716 static int hf_dnp3_al_ptnum; */
717 static int hf_dnp3_al_biq_b0
;
718 static int hf_dnp3_al_biq_b1
;
719 static int hf_dnp3_al_biq_b2
;
720 static int hf_dnp3_al_biq_b3
;
721 static int hf_dnp3_al_biq_b4
;
722 static int hf_dnp3_al_biq_b5
;
723 static int hf_dnp3_al_biq_b6
;
724 static int hf_dnp3_al_biq_b7
;
725 static int hf_dnp3_al_boq_b0
;
726 static int hf_dnp3_al_boq_b1
;
727 static int hf_dnp3_al_boq_b2
;
728 static int hf_dnp3_al_boq_b3
;
729 static int hf_dnp3_al_boq_b4
;
730 static int hf_dnp3_al_boq_b5
;
731 static int hf_dnp3_al_boq_b6
;
732 static int hf_dnp3_al_boq_b7
;
733 static int hf_dnp3_al_ctrq_b0
;
734 static int hf_dnp3_al_ctrq_b1
;
735 static int hf_dnp3_al_ctrq_b2
;
736 static int hf_dnp3_al_ctrq_b3
;
737 static int hf_dnp3_al_ctrq_b4
;
738 static int hf_dnp3_al_ctrq_b5
;
739 static int hf_dnp3_al_ctrq_b6
;
740 static int hf_dnp3_al_ctrq_b7
;
741 static int hf_dnp3_al_aiq_b0
;
742 static int hf_dnp3_al_aiq_b1
;
743 static int hf_dnp3_al_aiq_b2
;
744 static int hf_dnp3_al_aiq_b3
;
745 static int hf_dnp3_al_aiq_b4
;
746 static int hf_dnp3_al_aiq_b5
;
747 static int hf_dnp3_al_aiq_b6
;
748 static int hf_dnp3_al_aiq_b7
;
749 static int hf_dnp3_al_aoq_b0
;
750 static int hf_dnp3_al_aoq_b1
;
751 static int hf_dnp3_al_aoq_b2
;
752 static int hf_dnp3_al_aoq_b3
;
753 static int hf_dnp3_al_aoq_b4
;
754 static int hf_dnp3_al_aoq_b5
;
755 static int hf_dnp3_al_aoq_b6
;
756 static int hf_dnp3_al_aoq_b7
;
757 static int hf_dnp3_al_timestamp
;
758 static int hf_dnp3_al_file_perms
;
759 static int hf_dnp3_al_file_perms_read_owner
;
760 static int hf_dnp3_al_file_perms_write_owner
;
761 static int hf_dnp3_al_file_perms_exec_owner
;
762 static int hf_dnp3_al_file_perms_read_group
;
763 static int hf_dnp3_al_file_perms_write_group
;
764 static int hf_dnp3_al_file_perms_exec_group
;
765 static int hf_dnp3_al_file_perms_read_world
;
766 static int hf_dnp3_al_file_perms_write_world
;
767 static int hf_dnp3_al_file_perms_exec_world
;
768 static int hf_dnp3_al_rel_timestamp
;
769 static int hf_dnp3_al_ana16
;
770 static int hf_dnp3_al_ana32
;
771 static int hf_dnp3_al_anaflt
;
772 static int hf_dnp3_al_anadbl
;
773 static int hf_dnp3_al_bit
;
774 static int hf_dnp3_al_bit0
;
775 static int hf_dnp3_al_bit1
;
776 static int hf_dnp3_al_bit2
;
777 static int hf_dnp3_al_bit3
;
778 static int hf_dnp3_al_bit4
;
779 static int hf_dnp3_al_bit5
;
780 static int hf_dnp3_al_bit6
;
781 static int hf_dnp3_al_bit7
;
782 static int hf_dnp3_al_2bit
;
783 static int hf_dnp3_al_2bit0
;
784 static int hf_dnp3_al_2bit1
;
785 static int hf_dnp3_al_2bit2
;
786 static int hf_dnp3_al_2bit3
;
787 static int hf_dnp3_al_cnt16
;
788 static int hf_dnp3_al_cnt32
;
789 static int hf_dnp3_al_ctrlstatus
;
790 static int hf_dnp3_al_anaout16
;
791 static int hf_dnp3_al_anaout32
;
792 static int hf_dnp3_al_anaoutflt
;
793 static int hf_dnp3_al_anaoutdbl
;
794 static int hf_dnp3_al_file_mode
;
795 static int hf_dnp3_al_file_auth
;
796 static int hf_dnp3_al_file_size
;
797 static int hf_dnp3_al_file_maxblk
;
798 static int hf_dnp3_al_file_reqID
;
799 static int hf_dnp3_al_file_handle
;
800 static int hf_dnp3_al_file_status
;
801 static int hf_dnp3_al_file_blocknum
;
802 static int hf_dnp3_al_file_lastblock
;
803 static int hf_dnp3_al_file_data
;
804 static int hf_dnp3_ctlobj_code_c
;
805 static int hf_dnp3_ctlobj_code_m
;
806 static int hf_dnp3_ctlobj_code_tc
;
807 static int hf_dnp3_al_datatype
;
808 static int hf_dnp3_al_da_length
;
809 static int hf_dnp3_al_da_uint8
;
810 static int hf_dnp3_al_da_uint16
;
811 static int hf_dnp3_al_da_uint32
;
812 static int hf_dnp3_al_da_int8
;
813 static int hf_dnp3_al_da_int16
;
814 static int hf_dnp3_al_da_int32
;
815 static int hf_dnp3_al_da_flt
;
816 static int hf_dnp3_al_da_dbl
;
817 static int hf_dnp3_al_sa_cd
;
818 static int hf_dnp3_al_sa_cdl
;
819 static int hf_dnp3_al_sa_csq
;
820 static int hf_dnp3_al_sa_err
;
821 static int hf_dnp3_al_sa_key
;
822 static int hf_dnp3_al_sa_kcm
;
823 static int hf_dnp3_al_sa_ks
;
824 static int hf_dnp3_al_sa_ksq
;
825 static int hf_dnp3_al_sa_kwa
;
826 static int hf_dnp3_al_sa_mac
;
827 static int hf_dnp3_al_sa_mal
;
828 static int hf_dnp3_al_sa_rfc
;
829 static int hf_dnp3_al_sa_seq
;
830 static int hf_dnp3_al_sa_uk
;
831 static int hf_dnp3_al_sa_ukl
;
832 static int hf_dnp3_al_sa_usr
;
833 static int hf_dnp3_al_sa_usrn
;
834 static int hf_dnp3_al_sa_usrnl
;
835 static int hf_dnp3_al_sa_assoc_id
;
837 /* Generated from convert_proto_tree_add_text.pl */
838 static int hf_dnp3_al_point_index
;
839 static int hf_dnp3_al_da_value
;
840 static int hf_dnp3_al_count
;
841 static int hf_dnp3_al_on_time
;
842 static int hf_dnp3_al_off_time
;
843 static int hf_dnp3_al_time_delay
;
844 static int hf_dnp3_al_file_string_offset
;
845 static int hf_dnp3_al_file_string_length
;
846 static int hf_dnp3_al_file_name
;
847 static int hf_dnp3_al_octet_string
;
848 static int hf_dnp3_unknown_data_chunk
;
850 /***************************************************************************/
851 /* Value String Look-Ups */
852 /***************************************************************************/
853 static const value_string dnp3_ctl_func_pri_vals
[] = {
854 { DL_FUNC_RESET_LINK
, "Reset of Remote Link" },
855 { DL_FUNC_RESET_PROC
, "Reset of User Process" },
856 { DL_FUNC_TEST_LINK
, "Test Function For Link" },
857 { DL_FUNC_USER_DATA
, "User Data" },
858 { DL_FUNC_UNC_DATA
, "Unconfirmed User Data" },
859 { DL_FUNC_LINK_STAT
, "Request Link Status" },
863 static const value_string dnp3_ctl_func_sec_vals
[] = {
864 { DL_FUNC_ACK
, "ACK" },
865 { DL_FUNC_NACK
, "NACK" },
866 { DL_FUNC_STAT_LINK
, "Status of Link" },
867 { DL_FUNC_NO_FUNC
, "Link Service Not Functioning" },
868 { DL_FUNC_NOT_IMPL
, "Link Service Not Used or Implemented" },
873 static const value_string dnp3_ctl_flags_pri_vals
[] = {
874 { DNP3_CTL_DIR
, "DIR" },
875 { DNP3_CTL_PRM
, "PRM" },
876 { DNP3_CTL_FCB
, "FCB" },
877 { DNP3_CTL_FCV
, "FCV" },
883 static const value_string dnp3_ctl_flags_sec_vals
[]= {
884 { DNP3_CTL_DIR
, "DIR" },
885 { DNP3_CTL_PRM
, "PRM" },
886 { DNP3_CTL_RES
, "RES" },
887 { DNP3_CTL_DFC
, "DFC" },
893 static const value_string dnp3_tr_flags_vals
[] = {
894 { DNP3_TR_FIN
, "FIN" },
895 { DNP3_TR_FIR
, "FIR" },
901 static const value_string dnp3_al_flags_vals
[] = {
902 { DNP3_AL_FIR
, "FIR" },
903 { DNP3_AL_FIN
, "FIN" },
904 { DNP3_AL_CON
, "CON" },
905 { DNP3_AL_UNS
, "UNS" },
910 /* Application Layer Function Code Values */
911 static const value_string dnp3_al_func_vals
[] = {
912 { AL_FUNC_CONFIRM
, "Confirm" },
913 { AL_FUNC_READ
, "Read" },
914 { AL_FUNC_WRITE
, "Write" },
915 { AL_FUNC_SELECT
, "Select" },
916 { AL_FUNC_OPERATE
, "Operate" },
917 { AL_FUNC_DIROP
, "Direct Operate" },
918 { AL_FUNC_DIROPNACK
, "Direct Operate No Ack" },
919 { AL_FUNC_FRZ
, "Immediate Freeze" },
920 { AL_FUNC_FRZNACK
, "Immediate Freeze No Ack" },
921 { AL_FUNC_FRZCLR
, "Freeze and Clear" },
922 { AL_FUNC_FRZCLRNACK
, "Freeze and Clear No ACK" },
923 { AL_FUNC_FRZT
, "Freeze With Time" },
924 { AL_FUNC_FRZTNACK
, "Freeze With Time No ACK" },
925 { AL_FUNC_COLDRST
, "Cold Restart" },
926 { AL_FUNC_WARMRST
, "Warm Restart" },
927 { AL_FUNC_INITDATA
, "Initialize Data" },
928 { AL_FUNC_INITAPP
, "Initialize Application" },
929 { AL_FUNC_STARTAPP
, "Start Application" },
930 { AL_FUNC_STOPAPP
, "Stop Application" },
931 { AL_FUNC_SAVECFG
, "Save Configuration" },
932 { AL_FUNC_ENSPMSG
, "Enable Spontaneous Messages" },
933 { AL_FUNC_DISSPMSG
, "Disable Spontaneous Messages" },
934 { AL_FUNC_ASSIGNCL
, "Assign Classes" },
935 { AL_FUNC_DELAYMST
, "Delay Measurement" },
936 { AL_FUNC_RECCT
, "Record Current Time" },
937 { AL_FUNC_OPENFILE
, "Open File" },
938 { AL_FUNC_CLOSEFILE
, "Close File" },
939 { AL_FUNC_DELETEFILE
, "Delete File" },
940 { AL_FUNC_GETFILEINF
, "Get File Info" },
941 { AL_FUNC_AUTHFILE
, "Authenticate File" },
942 { AL_FUNC_ABORTFILE
, "Abort File" },
943 { AL_FUNC_ACTCNF
, "Activate Config" },
944 { AL_FUNC_AUTHREQ
, "Authentication Request" },
945 { AL_FUNC_AUTHERR
, "Authentication Error" },
946 { AL_FUNC_RESPON
, "Response" },
947 { AL_FUNC_UNSOLI
, "Unsolicited Response" },
948 { AL_FUNC_AUTHRESP
, "Authentication Response" },
951 static value_string_ext dnp3_al_func_vals_ext
= VALUE_STRING_EXT_INIT(dnp3_al_func_vals
);
953 /* Application Layer Internal Indication (IIN) bit Values */
954 static const value_string dnp3_al_iin_vals
[] = {
955 { AL_IIN_BMSG
, "Broadcast message Rx'd" },
956 { AL_IIN_CLS1D
, "Class 1 Data Available" },
957 { AL_IIN_CLS2D
, "Class 2 Data Available" },
958 { AL_IIN_CLS3D
, "Class 3 Data Available" },
959 { AL_IIN_TSR
, "Time Sync Required from Master" },
960 { AL_IIN_DOL
, "Outputs in Local Mode" },
961 { AL_IIN_DT
, "Device Trouble" },
962 { AL_IIN_RST
, "Device Restart" },
963 { AL_IIN_FCNI
, "Function Code not implemented" },
964 { AL_IIN_OBJU
, "Requested Objects Unknown" },
965 { AL_IIN_PIOOR
, "Parameters Invalid or Out of Range" },
966 { AL_IIN_EBO
, "Event Buffer Overflow" },
967 { AL_IIN_OAE
, "Operation Already Executing" },
968 { AL_IIN_CC
, "Device Configuration Corrupt" },
972 /* Application Layer Object Qualifier Prefix Values When Qualifier Code != 11 */
973 static const value_string dnp3_al_objq_prefix_vals
[] = {
974 { AL_OBJQL_PREFIX_NI
, "None" },
975 { AL_OBJQL_PREFIX_1O
, "1-Octet Index Prefix" },
976 { AL_OBJQL_PREFIX_2O
, "2-Octet Index Prefix" },
977 { AL_OBJQL_PREFIX_4O
, "4-Octet Index Prefix" },
978 { AL_OBJQL_PREFIX_1OS
, "1-Octet Object Size Prefix" },
979 { AL_OBJQL_PREFIX_2OS
, "2-Octet Object Size Prefix" },
980 { AL_OBJQL_PREFIX_4OS
, "4-Octet Object Size Prefix" },
983 static value_string_ext dnp3_al_objq_prefix_vals_ext
= VALUE_STRING_EXT_INIT(dnp3_al_objq_prefix_vals
);
985 /* Application Layer Object Qualifier Range Values */
986 static const value_string dnp3_al_objq_range_vals
[] = {
987 { AL_OBJQL_RANGE_SSI8
, "8-bit Start and Stop Indices" },
988 { AL_OBJQL_RANGE_SSI16
, "16-bit Start and Stop Indices" },
989 { AL_OBJQL_RANGE_SSI32
, "32-bit Start and Stop Indices" },
990 { AL_OBJQL_RANGE_AA8
, "8-bit Absolute Address in Range Field" },
991 { AL_OBJQL_RANGE_AA16
, "16-bit Absolute Address in Range Field" },
992 { AL_OBJQL_RANGE_AA32
, "32-bit Absolute Address in Range Field" },
993 { AL_OBJQL_RANGE_R0
, "No Range Field" },
994 { AL_OBJQL_RANGE_SF8
, "8-bit Single Field Quantity" },
995 { AL_OBJQL_RANGE_SF16
, "16-bit Single Field Quantity" },
996 { AL_OBJQL_RANGE_SF32
, "32-bit Single Field Quantity" },
998 { AL_OBJQL_RANGE_FF
, "Free-format Qualifier" },
1001 static value_string_ext dnp3_al_objq_range_vals_ext
= VALUE_STRING_EXT_INIT(dnp3_al_objq_range_vals
);
1003 /* Application Layer Data Object Values */
1004 static const value_string dnp3_al_obj_vals
[] = {
1005 { AL_OBJ_DA_CFG_ID
, "Device Attributes - Configuration ID (Obj:00, Var:196)" },
1006 { AL_OBJ_DA_CFG_VER
, "Device Attributes - Configuration version (Obj:00, Var:197)" },
1007 { AL_OBJ_DA_CFG_BLD_DATE
,"Device Attributes - Configuration build date (Obj:00, Var:198)" },
1008 { AL_OBJ_DA_CFG_CHG_DATE
,"Device Attributes - Configuration last change date (Obj:00, Var:199)" },
1009 { AL_OBJ_DA_CFG_SIG
, "Device Attributes - Configuration signature (Obj:00, Var:200)" },
1010 { AL_OBJ_DA_CFG_SIG_ALG
, "Device Attributes - Configuration signature algorithm (Obj:00, Var:201)" },
1011 { AL_OBJ_DA_MRID
, "Device Attributes - Master Resource ID (mRID) (Obj:00, Var:202)" },
1012 { AL_OBJ_DA_ALT
, "Device Attributes - Device altitude (Obj:00, Var:203)" },
1013 { AL_OBJ_DA_LONG
, "Device Attributes - Device longitude (Obj:00, Var:204)" },
1014 { AL_OBJ_DA_LAT
, "Device Attributes - Device latitude (Obj:00, Var:205)" },
1015 { AL_OBJ_DA_SEC_OP
, "Device Attributes - User-assigned secondary operator name (Obj:00, Var:206)" },
1016 { AL_OBJ_DA_PRM_OP
, "Device Attributes - User-assigned primary operator name (Obj:00, Var:207)" },
1017 { AL_OBJ_DA_SYS_NAME
, "Device Attributes - User-assigned system name (Obj:00, Var:208)" },
1018 { AL_OBJ_DA_SEC_VER
, "Device Attributes - Secure authentication version (Obj:00, Var:209)" },
1019 { AL_OBJ_DA_SEC_STAT
, "Device Attributes - Number of security statistics per association (Obj:00, Var:210)" },
1020 { AL_OBJ_DA_USR_ATTR
, "Device Attributes - Identifier of support for user-specific attributes (Obj:00, Var:211)" },
1021 { AL_OBJ_DA_MSTR_DSP
, "Device Attributes - Number of master-defined data set prototypes (Obj:00, Var:212)" },
1022 { AL_OBJ_DA_OS_DSP
, "Device Attributes - Number of outstation-defined data set prototypes (Obj:00, Var:213)" },
1023 { AL_OBJ_DA_MSTR_DS
, "Device Attributes - Number of master-defined data sets (Obj:00, Var:214)" },
1024 { AL_OBJ_DA_OS_DS
, "Device Attributes - Number of outstation-defined data sets (Obj:00, Var:215)" },
1025 { AL_OBJ_DA_BO_REQ
, "Device Attributes - Max number of binary outputs per request (Obj:00, Var:216)" },
1026 { AL_OBJ_DA_LOC_TA
, "Device Attributes - Local timing accuracy (Obj:00, Var:217)" },
1027 { AL_OBJ_DA_DUR_TA
, "Device Attributes - Duration of timing accuracy (Obj:00, Var:218)" },
1028 { AL_OBJ_DA_AO_EVT
, "Device Attributes - Support for analog output events (Obj:00, Var:219)" },
1029 { AL_OBJ_DA_MAX_AO
, "Device Attributes - Max analog output index (Obj:00, Var:220)" },
1030 { AL_OBJ_DA_NUM_AO
, "Device Attributes - Number of analog outputs (Obj:00, Var:221)" },
1031 { AL_OBJ_DA_BO_EVT
, "Device Attributes - Support for binary output events (Obj:00, Var:222)" },
1032 { AL_OBJ_DA_MAX_BO
, "Device Attributes - Max binary output index (Obj:00, Var:223)" },
1033 { AL_OBJ_DA_NUM_BO
, "Device Attributes - Number of binary outputs (Obj:00, Var:224)" },
1034 { AL_OBJ_DA_FCTR_EVT
, "Device Attributes - Support for frozen counter events (Obj:00, Var:225)" },
1035 { AL_OBJ_DA_FCTR
, "Device Attributes - Support for frozen counters (Obj:00, Var:226)" },
1036 { AL_OBJ_DA_CTR_EVT
, "Device Attributes - Support for counter events (Obj:00, Var:227)" },
1037 { AL_OBJ_DA_MAX_CTR
, "Device Attributes - Max counter index (Obj:00, Var:228)" },
1038 { AL_OBJ_DA_NUM_CTR
, "Device Attributes - Number of counter points (Obj:00, Var:229)" },
1039 { AL_OBJ_DA_AIF
, "Device Attributes - Support for frozen analog inputs (Obj:00, Var:230)" },
1040 { AL_OBJ_DA_AI_EVT
, "Device Attributes - Support for analog input events (Obj:00, Var:231)" },
1041 { AL_OBJ_DA_MAX_AI
, "Device Attributes - Maximum analog input index (Obj:00, Var:232)" },
1042 { AL_OBJ_DA_NUM_AI
, "Device Attributes - Number of analog input points (Obj:00, Var:233)" },
1043 { AL_OBJ_DA_2BI_EVT
, "Device Attributes - Support for Double-Bit BI Events (Obj:00, Var:234)" },
1044 { AL_OBJ_DA_MAX_2BI
, "Device Attributes - Max Double-bit BI Point Index (Obj:00, Var:235)" },
1045 { AL_OBJ_DA_NUM_2BI
, "Device Attributes - Number of Double-bit BI Points (Obj:00, Var:236)" },
1046 { AL_OBJ_DA_BI_EVT
, "Device Attributes - Support for Binary Input Events (Obj:00, Var:237)" },
1047 { AL_OBJ_DA_MAX_BI
, "Device Attributes - Max Binary Input Point Index (Obj:00, Var:238)" },
1048 { AL_OBJ_DA_NUM_BI
, "Device Attributes - Number of Binary Input Points (Obj:00, Var:239)" },
1049 { AL_OBJ_DA_MXTX_FR
, "Device Attributes - Maximum Transmit Fragment Size (Obj:00, Var:240)" },
1050 { AL_OBJ_DA_MXRX_FR
, "Device Attributes - Maximum Receive Fragment Size (Obj:00, Var:241)" },
1051 { AL_OBJ_DA_SWVER
, "Device Attributes - Device Manufacturers SW Version (Obj:00, Var:242)" },
1052 { AL_OBJ_DA_HWVER
, "Device Attributes - Device Manufacturers HW Version (Obj:00, Var:243)" },
1053 { AL_OBJ_DA_LOC
, "Device Attributes - User-Assigned Location (Obj:00, Var:245)" },
1054 { AL_OBJ_DA_ID
, "Device Attributes - User-Assigned ID code/number (Obj:00, Var:246)" },
1055 { AL_OBJ_DA_DEVNAME
, "Device Attributes - User-Assigned Device Name (Obj:00, Var:247)" },
1056 { AL_OBJ_DA_SERNUM
, "Device Attributes - Device Serial Number (Obj:00, Var:248)" },
1057 { AL_OBJ_DA_CONF
, "Device Attributes - DNP Subset and Conformance (Obj:00, Var:249)" },
1058 { AL_OBJ_DA_PROD
, "Device Attributes - Device Product Name and Model (Obj:00, Var:250)" },
1059 { AL_OBJ_DA_MFG
, "Device Attributes - Device Manufacturers Name (Obj:00, Var:252)" },
1060 { AL_OBJ_DA_ALL
, "Device Attributes - Non-specific All-attributes Request (Obj:00, Var:254)" },
1061 { AL_OBJ_DA_LVAR
, "Device Attributes - List of Attribute Variations (Obj:00, Var:255)" },
1062 { AL_OBJ_BI_ALL
, "Binary Input Default Variation (Obj:01, Var:Default)" },
1063 { AL_OBJ_BI_1BIT
, "Single-Bit Binary Input (Obj:01, Var:01)" },
1064 { AL_OBJ_BI_STAT
, "Binary Input With Status (Obj:01, Var:02)" },
1065 { AL_OBJ_BIC_ALL
, "Binary Input Change Default Variation (Obj:02, Var:Default)" },
1066 { AL_OBJ_BIC_NOTIME
, "Binary Input Change Without Time (Obj:02, Var:01)" },
1067 { AL_OBJ_BIC_TIME
, "Binary Input Change With Time (Obj:02, Var:02)" },
1068 { AL_OBJ_BIC_RTIME
, "Binary Input Change With Relative Time (Obj:02, Var:03)" },
1069 { AL_OBJ_2BI_ALL
, "Double-bit Input Default Variation (Obj:03, Var:Default)" },
1070 { AL_OBJ_2BI_NF
, "Double-bit Input No Flags (Obj:03, Var:01)" },
1071 { AL_OBJ_2BI_STAT
, "Double-bit Input With Status (Obj:03, Var:02)" },
1072 { AL_OBJ_2BIC_ALL
, "Double-bit Input Change Default Variation (Obj:04, Var:Default)" },
1073 { AL_OBJ_2BIC_NOTIME
, "Double-bit Input Change Without Time (Obj:04, Var:01)" },
1074 { AL_OBJ_2BIC_TIME
, "Double-bit Input Change With Time (Obj:04, Var:02)" },
1075 { AL_OBJ_2BIC_RTIME
, "Double-bit Input Change With Relative Time (Obj:04, Var:03)" },
1076 { AL_OBJ_BO_ALL
, "Binary Output Default Variation (Obj:10, Var:Default)" },
1077 { AL_OBJ_BO
, "Binary Output (Obj:10, Var:01)" },
1078 { AL_OBJ_BO_STAT
, "Binary Output Status (Obj:10, Var:02)" },
1079 { AL_OBJ_BOC_ALL
, "Binary Output Change Default Variation (Obj:11, Var:Default)" },
1080 { AL_OBJ_BOC_NOTIME
, "Binary Output Change Without Time (Obj:11, Var:01)" },
1081 { AL_OBJ_BOC_TIME
, "Binary Output Change With Time (Obj:11, Var:02)" },
1082 { AL_OBJ_CTLOP_BLK
, "Control Relay Output Block (Obj:12, Var:01)" },
1083 { AL_OBJ_CTL_PCB
, "Pattern Control Block (Obj:12, Var:02)" },
1084 { AL_OBJ_CTL_PMASK
, "Pattern Mask (Obj:12, Var:03)" },
1085 { AL_OBJ_BOE_NOTIME
, "Binary Command Event Without Time (Obj 13, Var:01)" },
1086 { AL_OBJ_BOE_TIME
, "Binary Command Event With Time (Obj 13, Var:02)" },
1087 { AL_OBJ_CTR_ALL
, "Binary Counter Default Variation (Obj:20, Var:Default)" },
1088 { AL_OBJ_CTR_32
, "32-Bit Binary Counter (Obj:20, Var:01)" },
1089 { AL_OBJ_CTR_16
, "16-Bit Binary Counter (Obj:20, Var:02)" },
1090 { AL_OBJ_DCTR_32
, "32-Bit Binary Delta Counter (Obj:20, Var:03)" },
1091 { AL_OBJ_DCTR_16
, "16-Bit Binary Delta Counter (Obj:20, Var:04)" },
1092 { AL_OBJ_CTR_32NF
, "32-Bit Binary Counter Without Flag (Obj:20, Var:05)" },
1093 { AL_OBJ_CTR_16NF
, "16-Bit Binary Counter Without Flag (Obj:20, Var:06)" },
1094 { AL_OBJ_DCTR_32NF
, "32-Bit Binary Delta Counter Without Flag (Obj:20, Var:07)" },
1095 { AL_OBJ_DCTR_16NF
, "16-Bit Binary Delta Counter Without Flag (Obj:20, Var:08)" },
1096 { AL_OBJ_FCTR_ALL
, "Frozen Binary Counter Default Variation (Obj:21, Var:Default)" },
1097 { AL_OBJ_FCTR_32
, "32-Bit Frozen Binary Counter (Obj:21, Var:01)" },
1098 { AL_OBJ_FCTR_16
, "16-Bit Frozen Binary Counter (Obj:21, Var:02)" },
1099 { AL_OBJ_FDCTR_32
, "32-Bit Frozen Binary Delta Counter (Obj:21, Var:03)" },
1100 { AL_OBJ_FDCTR_16
, "16-Bit Frozen Binary Delta Counter (Obj:21, Var:04)" },
1101 { AL_OBJ_FCTR_32T
, "32-Bit Frozen Binary Counter With Flag and Time (Obj:21, Var:05)" },
1102 { AL_OBJ_FCTR_16T
, "16-Bit Frozen Binary Counter With Flag and Time (Obj:21, Var:06)" },
1103 { AL_OBJ_FDCTR_32T
, "32-Bit Frozen Binary Delta Counter With Flag and Time (Obj:21, Var:07)" },
1104 { AL_OBJ_FDCTR_16T
, "16-Bit Frozen Binary Delta Counter With Flag and Time (Obj:21, Var:08)" },
1105 { AL_OBJ_FCTR_32NF
, "32-Bit Frozen Binary Counter Without Flag (Obj:21, Var:09)" },
1106 { AL_OBJ_FCTR_16NF
, "16-Bit Frozen Binary Counter Without Flag (Obj:21, Var:10)" },
1107 { AL_OBJ_FDCTR_32NF
, "32-Bit Frozen Binary Delta Counter Without Flag (Obj:21, Var:11)" },
1108 { AL_OBJ_FDCTR_16NF
, "16-Bit Frozen Binary Delta Counter Without Flag (Obj:21, Var:12)" },
1109 { AL_OBJ_CTRC_ALL
, "Binary Counter Change Default Variation (Obj:22, Var:Default)" },
1110 { AL_OBJ_CTRC_32
, "32-Bit Counter Change Event w/o Time (Obj:22, Var:01)" },
1111 { AL_OBJ_CTRC_16
, "16-Bit Counter Change Event w/o Time (Obj:22, Var:02)" },
1112 { AL_OBJ_DCTRC_32
, "32-Bit Delta Counter Change Event w/o Time (Obj:22, Var:03)" },
1113 { AL_OBJ_DCTRC_16
, "16-Bit Delta Counter Change Event w/o Time (Obj:22, Var:04)" },
1114 { AL_OBJ_CTRC_32T
, "32-Bit Counter Change Event with Time (Obj:22, Var:05)" },
1115 { AL_OBJ_CTRC_16T
, "16-Bit Counter Change Event with Time (Obj:22, Var:06)" },
1116 { AL_OBJ_DCTRC_32T
, "32-Bit Delta Counter Change Event with Time (Obj:22, Var:07)" },
1117 { AL_OBJ_DCTRC_16T
, "16-Bit Delta Counter Change Event with Time (Obj:22, Var:08)" },
1118 { AL_OBJ_FCTRC_ALL
, "Frozen Binary Counter Change Default Variation (Obj:23, Var:Default)" },
1119 { AL_OBJ_FCTRC_32
, "32-Bit Frozen Counter Change Event w/o Time (Obj:23, Var:01)" },
1120 { AL_OBJ_FCTRC_16
, "16-Bit Frozen Counter Change Event w/o Time (Obj:23, Var:02)" },
1121 { AL_OBJ_FDCTRC_32
, "32-Bit Frozen Delta Counter Change Event w/o Time (Obj:23, Var:03)" },
1122 { AL_OBJ_FDCTRC_16
, "16-Bit Frozen Delta Counter Change Event w/o Time (Obj:23, Var:04)" },
1123 { AL_OBJ_FCTRC_32T
, "32-Bit Frozen Counter Change Event with Time (Obj:23, Var:05)" },
1124 { AL_OBJ_FCTRC_16T
, "16-Bit Frozen Counter Change Event with Time (Obj:23, Var:06)" },
1125 { AL_OBJ_FDCTRC_32T
, "32-Bit Frozen Delta Counter Change Event with Time (Obj:23, Var:07)" },
1126 { AL_OBJ_FDCTRC_16T
, "16-Bit Frozen Delta Counter Change Event with Time (Obj:23, Var:08)" },
1127 { AL_OBJ_AI_ALL
, "Analog Input Default Variation (Obj:30, Var:Default)" },
1128 { AL_OBJ_AI_32
, "32-Bit Analog Input (Obj:30, Var:01)" },
1129 { AL_OBJ_AI_16
, "16-Bit Analog Input (Obj:30, Var:02)" },
1130 { AL_OBJ_AI_32NF
, "32-Bit Analog Input Without Flag (Obj:30, Var:03)" },
1131 { AL_OBJ_AI_16NF
, "16-Bit Analog Input Without Flag (Obj:30, Var:04)" },
1132 { AL_OBJ_AI_FLT
, "32-Bit Floating Point Input (Obj:30, Var:05)" },
1133 { AL_OBJ_AI_DBL
, "64-Bit Floating Point Input (Obj:30, Var:06)" },
1134 { AL_OBJ_AIFC_32
, "32-Bit Frozen Analog Input (Obj:31, Var:01)" },
1135 { AL_OBJ_AIFC_16
, "16-Bit Frozen Analog Input (Obj:31, Var:02)" },
1136 { AL_OBJ_AIFC_32TOF
, "32-Bit Frozen Analog Input w/ Time of Freeze (Obj:31, Var:03)" },
1137 { AL_OBJ_AIFC_16TOF
, "16-Bit Frozen Analog Input w/ Time of Freeze (Obj:31, Var:04)" },
1138 { AL_OBJ_AIFC_32NF
, "32-Bit Frozen Analog Input Without Flag (Obj:31, Var:05)" },
1139 { AL_OBJ_AIFC_16NF
, "16-Bit Frozen Analog Input Without Flag (Obj:31, Var:06)" },
1140 { AL_OBJ_AIF_FLT
, "32-Bit Frozen Floating Point Input (Obj:31, Var:07)" },
1141 { AL_OBJ_AIF_DBL
, "64-Bit Frozen Floating Point Input (Obj:31, Var:08)" },
1142 { AL_OBJ_AIC_ALL
, "Analog Input Change Default Variation (Obj:32, Var:Default)" },
1143 { AL_OBJ_AIC_32NT
, "32-Bit Analog Change Event w/o Time (Obj:32, Var:01)" },
1144 { AL_OBJ_AIC_16NT
, "16-Bit Analog Change Event w/o Time (Obj:32, Var:02)" },
1145 { AL_OBJ_AIC_32T
, "32-Bit Analog Change Event with Time (Obj:32, Var:03)" },
1146 { AL_OBJ_AIC_16T
, "16-Bit Analog Change Event with Time (Obj:32, Var:04)" },
1147 { AL_OBJ_AIC_FLTNT
, "32-Bit Floating Point Change Event w/o Time (Obj:32, Var:05)" },
1148 { AL_OBJ_AIC_DBLNT
, "64-Bit Floating Point Change Event w/o Time (Obj:32, Var:06)" },
1149 { AL_OBJ_AIC_FLTT
, "32-Bit Floating Point Change Event w/ Time (Obj:32, Var:07)" },
1150 { AL_OBJ_AIC_DBLT
, "64-Bit Floating Point Change Event w/ Time (Obj:32, Var:08)" },
1151 { AL_OBJ_AIFC_32NT
, "32-Bit Frozen Analog Event w/o Time (Obj:33, Var:01)" },
1152 { AL_OBJ_AIFC_16NT
, "16-Bit Frozen Analog Event w/o Time (Obj:33, Var:02)" },
1153 { AL_OBJ_AIFC_32T
, "32-Bit Frozen Analog Event w/ Time (Obj:33, Var:03)" },
1154 { AL_OBJ_AIFC_16T
, "16-Bit Frozen Analog Event w/ Time (Obj:33, Var:04)" },
1155 { AL_OBJ_AIFC_FLTNT
, "32-Bit Floating Point Frozen Change Event w/o Time (Obj:33, Var:05)" },
1156 { AL_OBJ_AIFC_DBLNT
, "64-Bit Floating Point Frozen Change Event w/o Time (Obj:33, Var:06)" },
1157 { AL_OBJ_AIFC_FLTT
, "32-Bit Floating Point Frozen Change Event w/ Time (Obj:33, Var:07)" },
1158 { AL_OBJ_AIFC_DBLT
, "64-Bit Floating Point Frozen Change Event w/ Time (Obj:33, Var:08)" },
1159 { AL_OBJ_AIDB_ALL
, "Analog Input Deadband Default Variation (Obj:34, Var:Default)" },
1160 { AL_OBJ_AIDB_16
, "16-Bit Analog Input Deadband (Obj:34, Var:01)" },
1161 { AL_OBJ_AIDB_32
, "32-Bit Analog Input Deadband (Obj:34, Var:02)" },
1162 { AL_OBJ_AIDB_FLT
, "32-Bit Floating Point Analog Input Deadband (Obj:34, Var:03)" },
1163 { AL_OBJ_AO_ALL
, "Analog Output Default Variation (Obj:40, Var:Default)" },
1164 { AL_OBJ_AO_32
, "32-Bit Analog Output Status (Obj:40, Var:01)" },
1165 { AL_OBJ_AO_16
, "16-Bit Analog Output Status (Obj:40, Var:02)" },
1166 { AL_OBJ_AO_FLT
, "32-Bit Floating Point Output Status (Obj:40, Var:03)" },
1167 { AL_OBJ_AO_DBL
, "64-Bit Floating Point Output Status (Obj:40, Var:04)" },
1168 { AL_OBJ_AO_32OPB
, "32-Bit Analog Output Block (Obj:41, Var:01)" },
1169 { AL_OBJ_AO_16OPB
, "16-Bit Analog Output Block (Obj:41, Var:02)" },
1170 { AL_OBJ_AO_FLTOPB
, "32-Bit Floating Point Output Block (Obj:41, Var:03)" },
1171 { AL_OBJ_AO_DBLOPB
, "64-Bit Floating Point Output Block (Obj:41, Var:04)" },
1172 { AL_OBJ_AOC_ALL
, "Analog Output Event Default Variation (Obj:42, Var:Default)" },
1173 { AL_OBJ_AOC_32NT
, "32-Bit Analog Output Event w/o Time (Obj:42, Var:01)" },
1174 { AL_OBJ_AOC_16NT
, "16-Bit Analog Output Event w/o Time (Obj:42, Var:02)" },
1175 { AL_OBJ_AOC_32T
, "32-Bit Analog Output Event with Time (Obj:42, Var:03)" },
1176 { AL_OBJ_AOC_16T
, "16-Bit Analog Output Event with Time (Obj:42, Var:04)" },
1177 { AL_OBJ_AOC_FLTNT
, "32-Bit Floating Point Output Event w/o Time (Obj:42, Var:05)" },
1178 { AL_OBJ_AOC_DBLNT
, "64-Bit Floating Point Output Event w/o Time (Obj:42, Var:06)" },
1179 { AL_OBJ_AOC_FLTT
, "32-Bit Floating Point Output Event w/ Time (Obj:42, Var:07)" },
1180 { AL_OBJ_AOC_DBLT
, "64-Bit Floating Point Output Event w/ Time (Obj:42, Var:08)" },
1181 { AL_OBJ_AOC_32EVNT
, "32-Bit Analog Output Event w/o Time (Obj:43, Var:01)" },
1182 { AL_OBJ_AOC_16EVNT
, "16-Bit Analog Output Event w/o Time (Obj:43, Var:02)" },
1183 { AL_OBJ_AOC_32EVTT
, "32-Bit Analog Output Event with Time (Obj:43, Var:03)" },
1184 { AL_OBJ_AOC_16EVTT
, "16-Bit Analog Output Event with Time (Obj:43, Var:04)" },
1185 { AL_OBJ_AOC_FLTEVNT
, "32-Bit Floating Point Output Event w/o Time (Obj:43, Var:05)" },
1186 { AL_OBJ_AOC_DBLEVNT
, "64-Bit Floating Point Output Event w/o Time (Obj:43, Var:06)" },
1187 { AL_OBJ_AOC_FLTEVTT
, "32-Bit Floating Point Output Event w/ Time (Obj:43, Var:07)" },
1188 { AL_OBJ_AOC_DBLEVTT
, "64-Bit Floating Point Output Event w/ Time (Obj:43, Var:08)" },
1189 { AL_OBJ_TD_ALL
, "Time and Date Default Variations (Obj:50, Var:Default)" },
1190 { AL_OBJ_TD
, "Time and Date (Obj:50, Var:01)" },
1191 { AL_OBJ_TDI
, "Time and Date w/Interval (Obj:50, Var:02)" },
1192 { AL_OBJ_TDR
, "Last Recorded Time and Date (Obj:50, Var:03)" },
1193 { AL_OBJ_TDCTO
, "Time and Date CTO (Obj:51, Var:01)" },
1194 { AL_OBJ_UTDCTO
, "Unsynchronized Time and Date CTO (Obj:51, Var:02)"},
1195 { AL_OBJ_TDELAYF
, "Time Delay - Fine (Obj:52, Var:02)" },
1196 { AL_OBJ_CLASS0
, "Class 0 Data (Obj:60, Var:01)" },
1197 { AL_OBJ_CLASS1
, "Class 1 Data (Obj:60, Var:02)" },
1198 { AL_OBJ_CLASS2
, "Class 2 Data (Obj:60, Var:03)" },
1199 { AL_OBJ_CLASS3
, "Class 3 Data (Obj:60, Var:04)" },
1200 { AL_OBJ_FILE_CMD
, "File Control - File Command (Obj:70, Var:03)" },
1201 { AL_OBJ_FILE_STAT
, "File Control - File Status (Obj:70, Var:04)" },
1202 { AL_OBJ_FILE_TRANS
, "File Control - File Transport (Obj:70, Var:05)" },
1203 { AL_OBJ_FILE_TRAN_ST
, "File Control - File Transport Status (Obj:70, Var:06)" },
1204 { AL_OBJ_IIN
, "Internal Indications (Obj:80, Var:01)" },
1205 { AL_OBJ_DS_PROTO
, "Data-Set Prototype, with UUID (Obj:85, Var:01)" },
1206 { AL_OBJ_DSD_CONT
, "Data-Set Descriptor, Data-Set Contents (Obj:86, Var:01)" },
1207 { AL_OBJ_DSD_CHAR
, "Data-Set Descriptor, Characteristics (Obj:86, Var:02)" },
1208 { AL_OBJ_DSD_PIDX
, "Data-Set Descriptor, Point Index Attributes (Obj:86, Var:03)" },
1209 { AL_OBJ_DS_PV
, "Data-Set, Present Value (Obj:87, Var:01)" },
1210 { AL_OBJ_DS_SS
, "Data-Set, Snapshot (Obj:88, Var:01)" },
1211 { AL_OBJ_OCT
, "Octet String (Obj:110)" },
1212 { AL_OBJ_OCT_EVT
, "Octet String Event (Obj:111)" },
1213 { AL_OBJ_VT_OBLK
, "Virtual Terminal Output Block (Obj:112)" },
1214 { AL_OBJ_VT_EVTD
, "Virtual Terminal Event Data (Obj:113)" },
1215 { AL_OBJ_SA_AUTH_CH
, "Authentication Challenge (Obj:120, Var:01)" },
1216 { AL_OBJ_SA_AUTH_RP
, "Authentication Reply (Obj:120, Var:02)" },
1217 { AL_OBJ_SA_AUTH_AGMRQ
, "Authentication Aggressive Mode Request (Obj:120, Var:03)" },
1218 { AL_OBJ_SA_AUTH_SKSR
, "Authentication Session Key Status Request (Obj:120, Var:04)" },
1219 { AL_OBJ_SA_AUTH_SKS
, "Authentication Session Key Status (Obj:120, Var:05)" },
1220 { AL_OBJ_SA_AUTH_SKC
, "Authentication Session Key Change (Obj:120, Var:06)" },
1221 { AL_OBJ_SA_AUTH_ERR
, "Authentication Error (Obj:120, Var:07)" },
1222 { AL_OBJ_SA_AUTH_MAC
, "Authentication Message Authentication Code (Obj:120, Var:09)" },
1223 { AL_OBJ_SA_AUTH_UKCR
, "Authentication Update Key Change Request (Obj:120, Var:11)" },
1224 { AL_OBJ_SA_AUTH_UKCRP
, "Authentication Update Key Change Reply (Obj:120, Var:12)"},
1225 { AL_OBJ_SA_AUTH_UKC
, "Authentication Update Key Change (Obj:120, Var:13)"},
1226 { AL_OBJ_SA_AUTH_UKCC
, "Authentication Update Key Change Confirmation (Obj:120, Var:15)"},
1227 { AL_OBJ_SA_SECSTAT
, "Security Statistics (Obj:121, Var:01)" },
1228 { AL_OBJ_SA_SECSTATEVT
, "Security Statistic Event (Obj:122, Var:01)" },
1229 { AL_OBJ_SA_SECSTATEVTT
, "Security Statistic Event w/ Time (Obj:122, Var:02)" },
1232 static value_string_ext dnp3_al_obj_vals_ext
= VALUE_STRING_EXT_INIT(dnp3_al_obj_vals
);
1234 /* Application Layer Control Code 'Operation Type' Values */
1235 static const value_string dnp3_al_ctlc_code_vals
[] = {
1236 { AL_OBJCTLC_CODE0
, "NUL Operation" },
1237 { AL_OBJCTLC_CODE1
, "Pulse On" },
1238 { AL_OBJCTLC_CODE2
, "Pulse Off" },
1239 { AL_OBJCTLC_CODE3
, "Latch On" },
1240 { AL_OBJCTLC_CODE4
, "Latch Off" },
1244 /* Application Layer Control Code 'Clear Field' Values */
1245 static const value_string dnp3_al_ctlc_misc_vals
[] = {
1246 { AL_OBJCTLC_QUEUE
, "Queue" },
1247 { AL_OBJCTLC_CLEAR
, "Clear" },
1248 { AL_OBJCTLC_NOTSET
, "Not Set" },
1249 { AL_OBJCTLC_BOTHSET
, "Queue and Clear" },
1253 /* Application Layer Control Code 'Trip Close Code' Values */
1254 static const value_string dnp3_al_ctlc_tc_vals
[] = {
1255 { AL_OBJCTLC_TC0
, "NUL" },
1256 { AL_OBJCTLC_TC1
, "Close" },
1257 { AL_OBJCTLC_TC2
, "Trip" },
1258 { AL_OBJCTLC_TC3
, "Reserved" },
1262 /* Application Layer Control Status Values */
1263 static const value_string dnp3_al_ctl_status_vals
[] = {
1264 { AL_OBJCTL_STAT0
, "Req. Accepted/Init/Queued" },
1265 { AL_OBJCTL_STAT1
, "Req. Not Accepted; Arm-Timer Expired" },
1266 { AL_OBJCTL_STAT2
, "Req. Not Accepted; No 'SELECT' Received" },
1267 { AL_OBJCTL_STAT3
, "Req. Not Accepted; Format Err. in Ctl Req." },
1268 { AL_OBJCTL_STAT4
, "Ctl Oper. Not Supported For This Point" },
1269 { AL_OBJCTL_STAT5
, "Req. Not Accepted; Ctrl Queue Full/Point Active" },
1270 { AL_OBJCTL_STAT6
, "Req. Not Accepted; Ctrl Hardware Problems" },
1271 { AL_OBJCTL_STAT7
, "Req. Not Accepted; Local/Remote switch in Local" },
1272 { AL_OBJCTL_STAT8
, "Req. Not Accepted; Too many operations" },
1273 { AL_OBJCTL_STAT9
, "Req. Not Accepted; Insufficient authorization" },
1274 { AL_OBJCTL_STAT10
, "Req. Not Accepted; Local automation proc active" },
1275 { AL_OBJCTL_STAT11
, "Req. Not Accepted; Processing limited" },
1276 { AL_OBJCTL_STAT12
, "Req. Not Accepted; Out of range value" },
1277 { AL_OBJCTL_STAT126
, "Req. Not Accepted; Non-participating (NOP request)" },
1278 { AL_OBJCTL_STAT127
, "Req. Not Accepted; Undefined error" },
1281 static value_string_ext dnp3_al_ctl_status_vals_ext
= VALUE_STRING_EXT_INIT(dnp3_al_ctl_status_vals
);
1284 /* Application Layer Binary Input Quality Flag Values */
1285 static const value_string dnp3_al_biflag_vals
[] = {
1286 { AL_OBJ_BI_FLAG0
, "Online" },
1287 { AL_OBJ_BI_FLAG1
, "Restart" },
1288 { AL_OBJ_BI_FLAG2
, "Comm Fail" },
1289 { AL_OBJ_BI_FLAG3
, "Remote Forced" },
1290 { AL_OBJ_BI_FLAG4
, "Locally Forced" },
1291 { AL_OBJ_BI_FLAG5
, "Chatter Filter" },
1297 /* Application Layer Counter Quality Flag Values */
1298 static const value_string dnp3_al_ctrflag_vals
[] = {
1299 { AL_OBJ_CTR_FLAG0
, "Online" },
1300 { AL_OBJ_CTR_FLAG1
, "Restart" },
1301 { AL_OBJ_CTR_FLAG2
, "Comm Fail" },
1302 { AL_OBJ_CTR_FLAG3
, "Remote Forced" },
1303 { AL_OBJ_CTR_FLAG4
, "Locally Forced" },
1304 { AL_OBJ_CTR_FLAG5
, "Roll-Over" },
1305 { AL_OBJ_CTR_FLAG6
, "Discontinuity" },
1311 /* Application Layer Analog Input Quality Flag Values */
1312 static const value_string dnp3_al_aiflag_vals
[] = {
1313 { AL_OBJ_AI_FLAG0
, "Online" },
1314 { AL_OBJ_AI_FLAG1
, "Restart" },
1315 { AL_OBJ_AI_FLAG2
, "Comm Fail" },
1316 { AL_OBJ_AI_FLAG3
, "Remote Forced" },
1317 { AL_OBJ_AI_FLAG4
, "Locally Forced" },
1318 { AL_OBJ_AI_FLAG5
, "Over-Range" },
1319 { AL_OBJ_AI_FLAG6
, "Ref. Error" },
1324 /* Application Layer Double-bit status values */
1325 static const value_string dnp3_al_2bit_vals
[] = {
1326 { AL_OBJ_2BI_STATE_INTERMEDIATE
, "Intermediate" },
1327 { AL_OBJ_2BI_STATE_OFF
, "Determined Off" },
1328 { AL_OBJ_2BI_STATE_ON
, "Determined On" },
1329 { AL_OBJ_2BI_STATE_INDETERM
, "Indeterminate" },
1332 static value_string_ext dnp3_al_dbi_vals_ext
= VALUE_STRING_EXT_INIT(dnp3_al_2bit_vals
);
1334 /* Application Layer File Control Mode values */
1335 static const value_string dnp3_al_file_mode_vals
[] = {
1336 { AL_OBJ_FILE_MODE_NULL
, "NULL" },
1337 { AL_OBJ_FILE_MODE_READ
, "READ" },
1338 { AL_OBJ_FILE_MODE_WRITE
, "WRITE" },
1339 { AL_OBJ_FILE_MODE_APPEND
, "APPEND" },
1343 /* Application Layer File Control Status values */
1344 static const value_string dnp3_al_file_status_vals
[] = {
1346 { 1, "PERMISSION DENIED" },
1347 { 2, "INVALID MODE" },
1348 { 3, "FILE NOT FOUND" },
1349 { 4, "FILE LOCKED" },
1350 { 5, "TOO MANY OPEN" },
1351 { 6, "INVALID HANDLE" },
1352 { 7, "WRITE BLOCK SIZE" },
1354 { 9, "CANNOT ABORT" },
1355 { 16, "NOT OPENED" },
1356 { 17, "HANDLE EXPIRED" },
1357 { 18, "BUFFER OVERRUN" },
1359 { 20, "BLOCK SEQUENCE" },
1360 { 255, "UNDEFINED" },
1363 static value_string_ext dnp3_al_file_status_vals_ext
= VALUE_STRING_EXT_INIT(dnp3_al_file_status_vals
);
1365 /* Application Layer Data Type values */
1366 static const value_string dnp3_al_data_type_vals
[] = {
1367 { AL_DATA_TYPE_NONE
, "NONE (Placeholder)" },
1368 { AL_DATA_TYPE_VSTR
, "VSTR (Visible ASCII String)" },
1369 { AL_DATA_TYPE_UINT
, "UINT (Unsigned Integer)" },
1370 { AL_DATA_TYPE_INT
, "INT (Signed Integer)" },
1371 { AL_DATA_TYPE_FLT
, "FLT (Floating Point)" },
1372 { AL_DATA_TYPE_OSTR
, "OSTR (Octet String)" },
1373 { AL_DATA_TYPE_BSTR
, "BSTR (Bit String)" },
1374 { AL_DATA_TYPE_TIME
, "TIME (DNP3 Time UINT48)" },
1375 { AL_DATA_TYPE_UNCD
, "UNCD (Unicode String)" },
1376 { AL_DATA_TYPE_U8BS8LIST
, "U8BS8LIST (List of UINT8 - BSTR8 pairs)" },
1377 { AL_DATA_TYPE_U8BS8EXLIST
, "U8BS8EXLIST (Extended List of UINT8 - BSTR8 pairs)" },
1381 /* Application Layer Read Object Type values */
1382 static const value_string dnp3_al_read_obj_vals
[] = {
1383 { (AL_OBJ_DA_GRP
& 0xFF00), "Device Attribute" },
1384 { (AL_OBJ_BI_ALL
& 0xFF00), "Binary Input" },
1385 { (AL_OBJ_BIC_ALL
& 0xFF00), "Binary Input Change" },
1386 { (AL_OBJ_2BI_ALL
& 0xFF00), "Double-bit Input" },
1387 { (AL_OBJ_2BIC_ALL
& 0xFF00), "Double-bit Input Change" },
1388 { (AL_OBJ_BO_ALL
& 0xFF00), "Binary Output" },
1389 { (AL_OBJ_BOC_ALL
& 0xFF00), "Binary Output Change" },
1390 { (AL_OBJ_CTR_ALL
& 0xFF00), "Counter" },
1391 { (AL_OBJ_FCTR_ALL
& 0xFF00), "Frozen Counter" },
1392 { (AL_OBJ_CTRC_ALL
& 0xFF00), "Counter Change" },
1393 { (AL_OBJ_FCTRC_ALL
& 0xFF00), "Frozen Counter Change" },
1394 { (AL_OBJ_AI_ALL
& 0xFF00), "Analog Input" },
1395 { (AL_OBJ_AIC_ALL
& 0xFF00), "Analog Input Change" },
1396 { (AL_OBJ_AO_ALL
& 0xFF00), "Analog Output" },
1397 { (AL_OBJ_AOC_ALL
& 0xFF00), "Analog Output Change" },
1398 { (AL_OBJ_TD_ALL
& 0xFF00), "Time and Date" },
1399 { (AL_OBJ_FILE_CMD
& 0xFF00), "File Control" },
1400 { (AL_OBJ_IIN
& 0xFF00), "Internal Indications" },
1401 { (AL_OBJ_OCT
& 0xFF00), "Octet String" },
1402 { (AL_OBJ_OCT_EVT
& 0xFF00), "Octet String Event" },
1403 { (AL_OBJ_VT_EVTD
& 0xFF00), "Virtual Terminal Event Data" },
1404 { (AL_OBJ_SA_AUTH_CH
& 0xFF00), "Secure Authentication" },
1408 static value_string_ext dnp3_al_read_obj_vals_ext
= VALUE_STRING_EXT_INIT(dnp3_al_read_obj_vals
);
1410 /* Application Layer Write Object Type values */
1411 static const value_string dnp3_al_write_obj_vals
[] = {
1412 { (AL_OBJ_TD_ALL
& 0xFF00), "Time and Date" },
1413 { (AL_OBJ_FILE_CMD
& 0xFF00), "File Control" },
1414 { (AL_OBJ_IIN
& 0xFF00), "Internal Indications" },
1415 { (AL_OBJ_OCT
& 0xFF00), "Octet String" },
1416 { (AL_OBJ_OCT_EVT
& 0xFF00), "Octet String Event" },
1417 { (AL_OBJ_VT_OBLK
& 0xFF00), "Virtual Terminal Output Block" },
1418 { (AL_OBJ_SA_AUTH_CH
& 0xFF00), "Secure Authentication" },
1422 static value_string_ext dnp3_al_write_obj_vals_ext
= VALUE_STRING_EXT_INIT(dnp3_al_write_obj_vals
);
1424 /* DNP SA Key Wrap Algorithm Values */
1425 static const value_string dnp3_al_sa_kwa_vals
[] = {
1432 /* DNP SA Key Status Values */
1433 static const value_string dnp3_al_sa_ks_vals
[] = {
1442 /* DNP SA MAC Algorithm Values */
1443 static const value_string dnp3_al_sa_mal_vals
[] = {
1444 { 0, "No MAC value in this message" },
1445 { 1, "HMAC SHA-1 truncated to 4 octets (serial)" },
1446 { 2, "HMAC SHA-1 truncated to 10 octets (networked)" },
1447 { 3, "HMAC SHA-256 truncated to 8 octets (serial)" },
1448 { 4, "HMAC SHA-256 truncated to 16 octets (networked)" },
1449 { 5, "HMAC SHA-1 truncated to 8 octets (serial)" },
1450 { 6, "AES-GMAC (output is 12 octets)" },
1454 /* DNP SA Error Values */
1455 static const value_string dnp3_al_sa_err_vals
[] = {
1457 { 1, "Authentication failed" },
1458 { 2, "Unexpected Response" },
1459 { 3, "No response" },
1460 { 4, "Aggressive Mode not supported" },
1461 { 5, "MAC Algorithm not supported" },
1462 { 6, "Key Wrap Algorithm not supported" },
1463 { 7, "Authorization failed" },
1464 { 8, "Update Key Change Method not permitted" },
1465 { 9, "Invalid Signature" },
1466 { 10, "Invalid Certification Data" },
1467 { 11, "Unknown User" },
1468 { 12, "Max Session Key Status Requests Exceeded" },
1472 /* DNP SA Key Change Method Values */
1473 static const value_string dnp3_al_sa_kcm_vals
[] = {
1475 { 1, "Obsolete. Do Not Use" },
1476 { 2, "Obsolete. Do Not Use" },
1477 { 3, "Symmetric AES-128 / SHA-1-HMAC" },
1478 { 4, "Symmetric AES-256 / SHA-256-HMAC" },
1479 { 5, "Symmetric AES-256 / AES-GMAC" },
1480 { 64, "Obsolete. Do Not Use" },
1481 { 65, "Obsolete. Do Not Use" },
1482 { 66, "Obsolete. Do Not Use" },
1483 { 67, "Asymmetric RSA-1024 / DSA SHA-1 / SHA-1-HMAC" },
1484 { 68, "Asymmetric RSA-2048 / DSA SHA-256 / SHA-256-HMAC" },
1485 { 69, "Asymmetric RSA-3072 / DSA SHA-256 / SHA-256-HMAC" },
1486 { 70, "Asymmetric RSA-2048 / DSA SHA-256 / AES-GMAC" },
1487 { 71, "Asymmetric RSA-3072 / DSA SHA-256 / AES-GMAC" },
1491 /* DNP SA Reason for Challenge Values */
1492 static const value_string dnp3_al_sa_rfc_vals
[] = {
1498 /* DNP SA Security Statistic Values */
1499 static const value_string dnp3_al_sa_secstat_vals
[] = {
1500 { 0, "(Unexpected Messages)" },
1501 { 1, "(Authorization Failures)" },
1502 { 2, "(Authentication Failures)" },
1503 { 3, "(Reply Timeouts)" },
1504 { 4, "(Rekeys Due to Authentication Failure)" },
1505 { 5, "(Total Messages Sent)" },
1506 { 6, "(Total Messages Received)" },
1507 { 7, "(Critical Messages Sent)" },
1508 { 8, "(Critical Messages Received)" },
1509 { 9, "(Discarded Messages)" },
1510 { 10, "(Error Messages Sent)" },
1511 { 11, "(Error Messages Rxed)" },
1512 { 12, "(Successful Authentications)" },
1513 { 13, "(Session Key Changes)" },
1514 { 14, "(Failed Session Key Changes)" },
1515 { 15, "(Update Key Changes)" },
1516 { 16, "(Failed Update Key Changes)" },
1517 { 17, "(Rekeys Due to Restarts)" },
1521 static value_string_ext dnp3_al_sa_secstat_vals_ext
= VALUE_STRING_EXT_INIT(dnp3_al_sa_secstat_vals
);
1523 /* Initialize the subtree pointers */
1524 static int ett_dnp3
;
1525 static int ett_dnp3_dl
;
1526 static int ett_dnp3_dl_ctl
;
1527 static int ett_dnp3_tr_ctl
;
1528 static int ett_dnp3_dl_data
;
1529 static int ett_dnp3_dl_chunk
;
1530 static int ett_dnp3_al
;
1531 static int ett_dnp3_al_ctl
;
1532 static int ett_dnp3_al_obj_point_tcc
;
1534 /* Added for Application Layer Decoding */
1535 static int ett_dnp3_al_iin
;
1536 static int ett_dnp3_al_obj
;
1537 static int ett_dnp3_al_obj_qualifier
;
1538 static int ett_dnp3_al_obj_range
;
1539 static int ett_dnp3_al_objdet
;
1540 static int ett_dnp3_al_obj_quality
;
1541 static int ett_dnp3_al_obj_point
;
1542 static int ett_dnp3_al_obj_point_perms
;
1544 static expert_field ei_dnp_num_items_neg
;
1545 static expert_field ei_dnp_invalid_length
;
1546 static expert_field ei_dnp_iin_abnormal
;
1547 static expert_field ei_dnp3_data_hdr_crc_incorrect
;
1548 static expert_field ei_dnp3_data_chunk_crc_incorrect
;
1549 static expert_field ei_dnp3_unknown_object
;
1550 static expert_field ei_dnp3_unknown_group0_variation
;
1551 static expert_field ei_dnp3_num_items_invalid
;
1552 /* Generated from convert_proto_tree_add_text.pl */
1554 static expert_field ei_dnp3_buffering_user_data_until_final_frame_is_received
;
1557 /* Tables for reassembly of fragments. */
1558 static reassembly_table al_reassembly_table
;
1560 /* ************************************************************************* */
1561 /* Header values for reassembly */
1562 /* ************************************************************************* */
1563 static int hf_al_frag_data
;
1564 static int hf_dnp3_fragment
;
1565 static int hf_dnp3_fragments
;
1566 static int hf_dnp3_fragment_overlap
;
1567 static int hf_dnp3_fragment_overlap_conflict
;
1568 static int hf_dnp3_fragment_multiple_tails
;
1569 static int hf_dnp3_fragment_too_long_fragment
;
1570 static int hf_dnp3_fragment_error
;
1571 static int hf_dnp3_fragment_count
;
1572 static int hf_dnp3_fragment_reassembled_in
;
1573 static int hf_dnp3_fragment_reassembled_length
;
1574 static int ett_dnp3_fragment
;
1575 static int ett_dnp3_fragments
;
1577 static dissector_handle_t dnp3_tcp_handle
;
1578 static dissector_handle_t dnp3_udp_handle
;
1580 static const fragment_items dnp3_frag_items
= {
1582 &ett_dnp3_fragments
,
1585 &hf_dnp3_fragment_overlap
,
1586 &hf_dnp3_fragment_overlap_conflict
,
1587 &hf_dnp3_fragment_multiple_tails
,
1588 &hf_dnp3_fragment_too_long_fragment
,
1589 &hf_dnp3_fragment_error
,
1590 &hf_dnp3_fragment_count
,
1591 &hf_dnp3_fragment_reassembled_in
,
1592 &hf_dnp3_fragment_reassembled_length
,
1593 /* Reassembled data field */
1598 /* desegmentation of DNP3 over TCP */
1599 static bool dnp3_desegment
= true;
1601 /* Enum for different quality type fields */
1611 /* calculates crc given a buffer of characters and a length of buffer */
1613 calculateCRC(const void *buf
, unsigned len
) {
1614 uint16_t crc
= crc16_0x3D65_seed((const uint8_t *)buf
, len
, 0);
1618 /* calculates crc given a tvbuff, offset, and length */
1620 calculateCRCtvb(tvbuff_t
*tvb
, unsigned offset
, unsigned len
) {
1621 uint16_t crc
= crc16_0x3D65_tvb_offset_seed(tvb
, offset
, len
, 0);
1625 /* calculate the extended sequence number - top 16 bits of the previous sequence number,
1626 * plus our own; then correct for wrapping */
1628 calculate_extended_seqno(uint32_t previous_seqno
, uint8_t raw_seqno
)
1630 uint32_t seqno
= (previous_seqno
& 0xffffffc0) | raw_seqno
;
1631 if (seqno
+ 0x20 < previous_seqno
) {
1633 } else if (previous_seqno
+ 0x20 < seqno
) {
1634 /* we got an out-of-order packet which happened to go backwards over the
1641 static int dnp3_tap
;
1643 typedef struct _dnp3_packet_info
1649 } dnp3_packet_info_t
;
1651 static const char* dnp3_conv_get_filter_type(conv_item_t
* conv
, conv_filter_type_e filter
)
1653 if (filter
== CONV_FT_SRC_ADDRESS
) {
1654 if (conv
->src_address
.type
== AT_NUMERIC
)
1658 if (filter
== CONV_FT_DST_ADDRESS
) {
1659 if (conv
->dst_address
.type
== AT_NUMERIC
)
1663 if (filter
== CONV_FT_ANY_ADDRESS
) {
1664 if (conv
->src_address
.type
== AT_NUMERIC
&& conv
->dst_address
.type
== AT_NUMERIC
)
1668 return CONV_FILTER_INVALID
;
1671 static ct_dissector_info_t dnp3_ct_dissector_info
= { &dnp3_conv_get_filter_type
};
1673 static const char* dnp3_get_filter_type(endpoint_item_t
* endpoint
, conv_filter_type_e filter
)
1675 if (endpoint
->myaddress
.type
== AT_NUMERIC
) {
1676 if (filter
== CONV_FT_ANY_ADDRESS
)
1678 else if (filter
== CONV_FT_SRC_ADDRESS
)
1680 else if (filter
== CONV_FT_DST_ADDRESS
)
1684 return CONV_FILTER_INVALID
;
1687 static et_dissector_info_t dnp3_dissector_info
= { &dnp3_get_filter_type
};
1689 static tap_packet_status
1690 dnp3_conversation_packet(void* pct
, packet_info
* pinfo
,
1691 epan_dissect_t
* edt _U_
, const void* vip
, tap_flags_t flags
)
1694 address
* src
= wmem_new0(pinfo
->pool
, address
);
1695 address
* dst
= wmem_new0(pinfo
->pool
, address
);
1696 conv_hash_t
* hash
= (conv_hash_t
*)pct
;
1697 const dnp3_packet_info_t
* dnp3_info
= (const dnp3_packet_info_t
*)vip
;
1699 hash
->flags
= flags
;
1701 alloc_address_wmem(pinfo
->pool
, src
, AT_NUMERIC
, (int)sizeof(uint16_t), &dnp3_info
->dl_src
);
1702 alloc_address_wmem(pinfo
->pool
, dst
, AT_NUMERIC
, (int)sizeof(uint16_t), &dnp3_info
->dl_dst
);
1704 add_conversation_table_data(hash
, src
, dst
, 0, 0, 1, dnp3_info
->msg_len
, &pinfo
->rel_ts
, &pinfo
->abs_ts
,
1705 &dnp3_ct_dissector_info
, CONVERSATION_DNP3
);
1707 return TAP_PACKET_REDRAW
;
1710 static tap_packet_status
1711 dnp3_endpoint_packet(void* pit
, packet_info
* pinfo
,
1712 epan_dissect_t
* edt _U_
, const void* vip
, tap_flags_t flags
)
1714 address
* src
= wmem_new0(pinfo
->pool
, address
);
1715 address
* dst
= wmem_new0(pinfo
->pool
, address
);
1716 conv_hash_t
* hash
= (conv_hash_t
*)pit
;
1717 const dnp3_packet_info_t
* dnp3_info
= (const dnp3_packet_info_t
*)vip
;
1719 hash
->flags
= flags
;
1721 alloc_address_wmem(pinfo
->pool
, src
, AT_NUMERIC
, (int)sizeof(uint16_t), &dnp3_info
->dl_src
);
1722 alloc_address_wmem(pinfo
->pool
, dst
, AT_NUMERIC
, (int)sizeof(uint16_t), &dnp3_info
->dl_src
);
1724 add_endpoint_table_data(hash
, src
, 0, true, 1, dnp3_info
->msg_len
, &dnp3_dissector_info
, ENDPOINT_NONE
);
1725 add_endpoint_table_data(hash
, dst
, 0, false, 1, dnp3_info
->msg_len
, &dnp3_dissector_info
, ENDPOINT_NONE
);
1727 return TAP_PACKET_REDRAW
;
1730 /*****************************************************************/
1731 /* Application Layer Process Internal Indications (IIN) */
1732 /*****************************************************************/
1734 dnp3_al_process_iin(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*al_tree
)
1738 static int* const indications
[] = {
1739 &hf_dnp3_al_iin_rst
,
1741 &hf_dnp3_al_iin_dol
,
1742 &hf_dnp3_al_iin_tsr
,
1743 &hf_dnp3_al_iin_cls3d
,
1744 &hf_dnp3_al_iin_cls2d
,
1745 &hf_dnp3_al_iin_cls1d
,
1746 &hf_dnp3_al_iin_bmsg
,
1748 &hf_dnp3_al_iin_oae
,
1749 &hf_dnp3_al_iin_ebo
,
1750 &hf_dnp3_al_iin_pioor
,
1751 &hf_dnp3_al_iin_obju
,
1752 &hf_dnp3_al_iin_fcni
,
1756 tiin
= proto_tree_add_bitmask(al_tree
, tvb
, offset
, hf_dnp3_al_iin
, ett_dnp3_al_iin
, indications
, ENC_BIG_ENDIAN
);
1757 al_iin
= tvb_get_ntohs(tvb
, offset
);
1759 /* If IIN indicates an abnormal condition, add expert info */
1760 if ((al_iin
& AL_IIN_DT
) || (al_iin
& AL_IIN_CC
) || (al_iin
& AL_IIN_OAE
) || (al_iin
& AL_IIN_EBO
) ||
1761 (al_iin
& AL_IIN_PIOOR
) || (al_iin
& AL_IIN_OBJU
) || (al_iin
& AL_IIN_FCNI
)) {
1762 expert_add_info(pinfo
, tiin
, &ei_dnp_iin_abnormal
);
1766 /**************************************************************/
1767 /* Function to determine Application Layer Object Prefix size */
1768 /* and Point address. */
1769 /**************************************************************/
1771 dnp3_al_obj_procprefix(tvbuff_t
*tvb
, int offset
, uint8_t al_objq_prefix
, uint32_t *al_ptaddr
, proto_tree
*item_tree
)
1773 int prefixbytes
= 0;
1774 proto_item
*prefix_item
;
1776 switch (al_objq_prefix
)
1778 case AL_OBJQL_PREFIX_NI
: /* No Prefix */
1780 prefix_item
= proto_tree_add_uint(item_tree
, hf_dnp3_al_point_index
, tvb
, offset
, 0, *al_ptaddr
);
1781 proto_item_set_generated(prefix_item
);
1783 case AL_OBJQL_PREFIX_1O
:
1784 *al_ptaddr
= tvb_get_uint8(tvb
, offset
);
1785 proto_tree_add_item(item_tree
, hf_dnp3_al_index8
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1788 case AL_OBJQL_PREFIX_2O
:
1789 *al_ptaddr
= tvb_get_letohs(tvb
, offset
);
1790 proto_tree_add_item(item_tree
, hf_dnp3_al_index16
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1793 case AL_OBJQL_PREFIX_4O
:
1794 *al_ptaddr
= tvb_get_letohl(tvb
, offset
);
1795 proto_tree_add_item(item_tree
, hf_dnp3_al_index32
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1798 case AL_OBJQL_PREFIX_1OS
:
1799 *al_ptaddr
= tvb_get_uint8(tvb
, offset
);
1800 proto_tree_add_item(item_tree
, hf_dnp3_al_size8
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1803 case AL_OBJQL_PREFIX_2OS
:
1804 *al_ptaddr
= tvb_get_letohs(tvb
, offset
);
1805 proto_tree_add_item(item_tree
, hf_dnp3_al_size16
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1808 case AL_OBJQL_PREFIX_4OS
:
1809 *al_ptaddr
= tvb_get_letohl(tvb
, offset
);
1810 proto_tree_add_item(item_tree
, hf_dnp3_al_size32
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1817 /*****************************************************************/
1818 /* Function to add the same string to two separate tree items */
1819 /*****************************************************************/
1821 dnp3_append_2item_text(proto_item
*item1
, proto_item
*item2
, const char *text
)
1823 proto_item_append_text(item1
, "%s", text
);
1824 proto_item_append_text(item2
, "%s", text
);
1827 /*****************************************************************/
1828 /* Function to Determine Application Layer Point Quality Flags & */
1829 /* add Point Quality Flag Sub-Tree */
1830 /*****************************************************************/
1832 dnp3_al_obj_quality(tvbuff_t
*tvb
, int offset
, uint8_t al_ptflags
, proto_tree
*point_tree
, proto_item
*point_item
, enum QUALITY_TYPE type
)
1835 proto_tree
*quality_tree
;
1836 proto_item
*quality_item
;
1837 int hf0
= 0, hf1
= 0, hf2
= 0, hf3
= 0, hf4
= 0, hf5
= 0, hf6
= 0, hf7
= 0;
1840 proto_item_append_text(point_item
, " (Quality: ");
1841 quality_tree
= proto_tree_add_subtree(point_tree
, tvb
, offset
, 1, ett_dnp3_al_obj_quality
, &quality_item
, "Quality: ");
1843 if (al_ptflags
& AL_OBJ_BI_FLAG0
) {
1844 dnp3_append_2item_text(point_item
, quality_item
, "Online");
1847 dnp3_append_2item_text(point_item
, quality_item
, "Offline");
1849 if (al_ptflags
& AL_OBJ_BI_FLAG1
) dnp3_append_2item_text(point_item
, quality_item
, ", Restart");
1850 if (al_ptflags
& AL_OBJ_BI_FLAG2
) dnp3_append_2item_text(point_item
, quality_item
, ", Comm Fail");
1851 if (al_ptflags
& AL_OBJ_BI_FLAG3
) dnp3_append_2item_text(point_item
, quality_item
, ", Remote Force");
1852 if (al_ptflags
& AL_OBJ_BI_FLAG4
) dnp3_append_2item_text(point_item
, quality_item
, ", Local Force");
1855 case BIN_IN
: /* Binary Input Quality flags */
1856 case DBIN_IN
: /* 2 bit Binary Input Quality flags */
1857 if (al_ptflags
& AL_OBJ_BI_FLAG5
) dnp3_append_2item_text(point_item
, quality_item
, ", Chatter Filter");
1859 hf0
= hf_dnp3_al_biq_b0
;
1860 hf1
= hf_dnp3_al_biq_b1
;
1861 hf2
= hf_dnp3_al_biq_b2
;
1862 hf3
= hf_dnp3_al_biq_b3
;
1863 hf4
= hf_dnp3_al_biq_b4
;
1864 hf5
= hf_dnp3_al_biq_b5
;
1865 if (type
== BIN_IN
) {
1866 hf6
= hf_dnp3_al_biq_b6
;
1867 hf7
= hf_dnp3_al_biq_b7
;
1869 else /* MUST be DBIN_IN */ {
1870 hf6
= hf_dnp3_al_2bit
;
1874 case BIN_OUT
: /* Binary Output Quality flags */
1875 hf0
= hf_dnp3_al_boq_b0
;
1876 hf1
= hf_dnp3_al_boq_b1
;
1877 hf2
= hf_dnp3_al_boq_b2
;
1878 hf3
= hf_dnp3_al_boq_b3
;
1879 hf4
= hf_dnp3_al_boq_b4
;
1880 hf5
= hf_dnp3_al_boq_b5
;
1881 hf6
= hf_dnp3_al_boq_b6
;
1882 hf7
= hf_dnp3_al_boq_b7
;
1885 case ANA_IN
: /* Analog Input Quality flags */
1886 if (al_ptflags
& AL_OBJ_AI_FLAG5
) dnp3_append_2item_text(point_item
, quality_item
, ", Over-Range");
1887 if (al_ptflags
& AL_OBJ_AI_FLAG6
) dnp3_append_2item_text(point_item
, quality_item
, ", Reference Check");
1889 hf0
= hf_dnp3_al_aiq_b0
;
1890 hf1
= hf_dnp3_al_aiq_b1
;
1891 hf2
= hf_dnp3_al_aiq_b2
;
1892 hf3
= hf_dnp3_al_aiq_b3
;
1893 hf4
= hf_dnp3_al_aiq_b4
;
1894 hf5
= hf_dnp3_al_aiq_b5
;
1895 hf6
= hf_dnp3_al_aiq_b6
;
1896 hf7
= hf_dnp3_al_aiq_b7
;
1899 case ANA_OUT
: /* Analog Output Quality flags */
1900 hf0
= hf_dnp3_al_aoq_b0
;
1901 hf1
= hf_dnp3_al_aoq_b1
;
1902 hf2
= hf_dnp3_al_aoq_b2
;
1903 hf3
= hf_dnp3_al_aoq_b3
;
1904 hf4
= hf_dnp3_al_aoq_b4
;
1905 hf5
= hf_dnp3_al_aoq_b5
;
1906 hf6
= hf_dnp3_al_aoq_b6
;
1907 hf7
= hf_dnp3_al_aoq_b7
;
1910 case COUNTER
: /* Counter Quality flags */
1911 if (al_ptflags
& AL_OBJ_CTR_FLAG5
) dnp3_append_2item_text(point_item
, quality_item
, ", Roll-over");
1912 if (al_ptflags
& AL_OBJ_CTR_FLAG6
) dnp3_append_2item_text(point_item
, quality_item
, ", Discontinuity");
1914 hf0
= hf_dnp3_al_ctrq_b0
;
1915 hf1
= hf_dnp3_al_ctrq_b1
;
1916 hf2
= hf_dnp3_al_ctrq_b2
;
1917 hf3
= hf_dnp3_al_ctrq_b3
;
1918 hf4
= hf_dnp3_al_ctrq_b4
;
1919 hf5
= hf_dnp3_al_ctrq_b5
;
1920 hf6
= hf_dnp3_al_ctrq_b6
;
1921 hf7
= hf_dnp3_al_ctrq_b7
;
1925 if (quality_tree
!= NULL
) {
1927 proto_tree_add_item(quality_tree
, hf7
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1929 proto_tree_add_item(quality_tree
, hf6
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1930 proto_tree_add_item(quality_tree
, hf5
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1931 proto_tree_add_item(quality_tree
, hf4
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1932 proto_tree_add_item(quality_tree
, hf3
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1933 proto_tree_add_item(quality_tree
, hf2
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1934 proto_tree_add_item(quality_tree
, hf1
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1935 proto_tree_add_item(quality_tree
, hf0
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1937 proto_item_append_text(point_item
, ")");
1940 /**********************************************************************/
1941 /* Function to convert DNP3 timestamp to nstime_t value */
1942 /**********************************************************************/
1943 /* 48-bit Time Format */
1944 /* MSB FF EE DD CC BB AA LSB */
1945 /* ffffffff eeeeeeee dddddddd cccccccc bbbbbbbb aaaaaaaa */
1946 /* 47 40 39 32 31 24 23 16 15 8 7 0 */
1948 /* Value is ms since 00:00 on 1/1/1970 */
1949 /**********************************************************************/
1951 dnp3_al_get_timestamp(nstime_t
*timestamp
, tvbuff_t
*tvb
, int data_pos
)
1957 lo
= tvb_get_letohs(tvb
, data_pos
);
1958 hi
= tvb_get_letohl(tvb
, data_pos
+ 2);
1960 time_ms
= (uint64_t)hi
* 0x10000 + lo
;
1962 timestamp
->secs
= (long)(time_ms
/ 1000);
1963 timestamp
->nsecs
= (int)(time_ms
% 1000) * 1000000;
1967 dnp3_al_empty_obj(uint16_t al_obj
)
1970 /* return a true if we expect an empty object (default var, class object, etc) */
1973 case AL_OBJ_BI_ALL
: /* Binary Input Default Variation (Obj:01, Var:Default) */
1974 case AL_OBJ_BIC_ALL
: /* Binary Input Change Default Variation (Obj:02, Var:Default) */
1975 case AL_OBJ_BOC_ALL
: /* Binary Output Event Default Variation (Obj:11, Var:Default) */
1976 case AL_OBJ_2BI_ALL
: /* Double-bit Input Default Variation (Obj:03, Var:Default) */
1977 case AL_OBJ_2BIC_ALL
: /* Double-bit Input Change Default Variation (Obj:04, Var:Default) */
1978 case AL_OBJ_CTR_ALL
: /* Binary Counter Default Variation (Obj:20, Var:Default) */
1979 case AL_OBJ_CTRC_ALL
: /* Binary Counter Change Default Variation (Obj:22 Var:Default) */
1980 case AL_OBJ_AI_ALL
: /* Analog Input Default Variation (Obj:30, Var:Default) */
1981 case AL_OBJ_AIC_ALL
: /* Analog Input Change Default Variation (Obj:32 Var:Default) */
1982 case AL_OBJ_AIDB_ALL
: /* Analog Input Deadband Default Variation (Obj:34, Var:Default) */
1983 case AL_OBJ_AOC_ALL
: /* Analog Output Event Default Variation (Obj:42 Var:Default) */
1984 case AL_OBJ_CLASS0
: /* Class Data Objects */
1994 /*****************************************************************/
1995 /* Desc: Application Layer Process Object Details */
1996 /* Returns: New offset pointer into tvb */
1997 /*****************************************************************/
1999 dnp3_al_process_object(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
,
2000 proto_tree
*robj_tree
, bool header_only
,
2001 uint16_t *al_objtype
, nstime_t
*al_cto
)
2004 uint8_t al_objq
, al_objq_prefix
, al_objq_range
, al_oct_len
= 0, bitindex
;
2005 uint16_t al_obj
, temp
;
2006 uint32_t al_ptaddr
= 0;
2008 int orig_offset
, rangebytes
= 0;
2009 proto_item
*object_item
, *range_item
;
2010 proto_tree
*object_tree
, *qualifier_tree
, *range_tree
;
2011 const char *sec_stat_str
;
2012 orig_offset
= offset
;
2014 /* Application Layer Objects in this Message */
2016 al_obj
= tvb_get_ntohs(tvb
, offset
);
2018 /* Special handling for Octet string objects as the variation is the length of the string */
2019 temp
= al_obj
& 0xFF00;
2020 if ((temp
== AL_OBJ_OCT
) || (temp
== AL_OBJ_OCT_EVT
)) {
2021 al_oct_len
= al_obj
& 0xFF;
2025 /* Special handling for Aggressive Mode Requests (Obj:120, Var3) and Message Authentication Codes (Obj:120, Var:9)
2026 objects that occur in read messages and require full dissection */
2027 if ((al_obj
== AL_OBJ_SA_AUTH_AGMRQ
) || (al_obj
== AL_OBJ_SA_AUTH_MAC
)) {
2028 header_only
= false;
2031 /* Create Data Objects Detail Tree */
2032 if (AL_OBJ_GROUP(al_obj
) == 0x0) {
2033 object_item
= proto_tree_add_uint_format(robj_tree
, hf_dnp3_al_obj
, tvb
, offset
, 2, al_obj
,
2034 "Object(s): %s (0x%04x)",
2035 val_to_str_ext_const(al_obj
, &dnp3_al_obj_vals_ext
, "Unknown group 0 Variation"),
2037 if (try_val_to_str_ext(al_obj
, &dnp3_al_obj_vals_ext
) == NULL
) {
2038 expert_add_info(pinfo
, object_item
, &ei_dnp3_unknown_group0_variation
);
2041 else if ((AL_OBJ_GROUP(al_obj
) == AL_OBJ_GROUP(AL_OBJ_OCT
)) || (AL_OBJ_GROUP(al_obj
) == AL_OBJ_GROUP(AL_OBJ_OCT_EVT
))) {
2042 /* For octet strings the variation is the length */
2043 object_item
= proto_tree_add_uint_format(robj_tree
, hf_dnp3_al_obj
, tvb
, offset
, 2, al_obj
,
2044 "Object(s): %s (0x%04x), Length: %d",
2045 val_to_str_ext_const(al_obj
, &dnp3_al_obj_vals_ext
, "Unknown Object\\Variation"),
2046 al_obj
, al_oct_len
);
2049 object_item
= proto_tree_add_uint_format(robj_tree
, hf_dnp3_al_obj
, tvb
, offset
, 2, al_obj
,
2050 "Object(s): %s (0x%04x)",
2051 val_to_str_ext_const(al_obj
, &dnp3_al_obj_vals_ext
, "Unknown Object\\Variation"),
2053 if (try_val_to_str_ext(al_obj
, &dnp3_al_obj_vals_ext
) == NULL
) {
2054 expert_add_info(pinfo
, object_item
, &ei_dnp3_unknown_object
);
2057 object_tree
= proto_item_add_subtree(object_item
, ett_dnp3_al_obj
);
2061 /* Object Qualifier */
2062 al_objq
= tvb_get_uint8(tvb
, offset
);
2063 al_objq_prefix
= al_objq
& AL_OBJQ_PREFIX
;
2064 al_objq_prefix
= al_objq_prefix
>> 4;
2065 al_objq_range
= al_objq
& AL_OBJQ_RANGE
;
2067 qualifier_tree
= proto_tree_add_subtree_format(object_tree
, tvb
, offset
, 1, ett_dnp3_al_obj_qualifier
, NULL
,
2068 "Qualifier Field, Prefix: %s, Range: %s",
2069 val_to_str_ext_const(al_objq_prefix
, &dnp3_al_objq_prefix_vals_ext
, "Unknown Prefix Type"),
2070 val_to_str_ext_const(al_objq_range
, &dnp3_al_objq_range_vals_ext
, "Unknown Range Type"));
2071 proto_tree_add_item(qualifier_tree
, hf_dnp3_al_objq_prefix
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2072 proto_tree_add_item(qualifier_tree
, hf_dnp3_al_objq_range
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2076 /* Create (possibly synthesized) number of items and range field tree */
2077 range_tree
= proto_tree_add_subtree(object_tree
, tvb
, offset
, 0, ett_dnp3_al_obj_range
, &range_item
, "Number of Items: ");
2079 switch (al_objq_range
)
2081 case AL_OBJQL_RANGE_SSI8
: /* 8-bit Start and Stop Indices in Range Field */
2082 num_items
= ( tvb_get_uint8(tvb
, offset
+1) - tvb_get_uint8(tvb
, offset
) + 1);
2083 proto_item_set_generated(range_item
);
2084 al_ptaddr
= tvb_get_uint8(tvb
, offset
);
2085 proto_tree_add_item(range_tree
, hf_dnp3_al_range_start8
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2086 proto_tree_add_item(range_tree
, hf_dnp3_al_range_stop8
, tvb
, offset
+ 1, 1, ENC_LITTLE_ENDIAN
);
2089 case AL_OBJQL_RANGE_SSI16
: /* 16-bit Start and Stop Indices in Range Field */
2090 num_items
= ( tvb_get_letohs(tvb
, offset
+2) - tvb_get_letohs(tvb
, (offset
)) + 1);
2091 proto_item_set_generated(range_item
);
2092 al_ptaddr
= tvb_get_letohs(tvb
, offset
);
2093 proto_tree_add_item(range_tree
, hf_dnp3_al_range_start16
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2094 proto_tree_add_item(range_tree
, hf_dnp3_al_range_stop16
, tvb
, offset
+ 2, 2, ENC_LITTLE_ENDIAN
);
2097 case AL_OBJQL_RANGE_SSI32
: /* 32-bit Start and Stop Indices in Range Field */
2098 num_items
= ( tvb_get_letohl(tvb
, offset
+4) - tvb_get_letohl(tvb
, offset
) + 1);
2099 proto_item_set_generated(range_item
);
2100 al_ptaddr
= tvb_get_letohl(tvb
, offset
);
2101 proto_tree_add_item(range_tree
, hf_dnp3_al_range_start32
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2102 proto_tree_add_item(range_tree
, hf_dnp3_al_range_stop32
, tvb
, offset
+ 4, 4, ENC_LITTLE_ENDIAN
);
2105 case AL_OBJQL_RANGE_AA8
: /* 8-bit Absolute Address in Range Field */
2107 proto_item_set_generated(range_item
);
2108 al_ptaddr
= tvb_get_uint8(tvb
, offset
);
2109 proto_tree_add_item(range_tree
, hf_dnp3_al_range_abs8
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2112 case AL_OBJQL_RANGE_AA16
: /* 16-bit Absolute Address in Range Field */
2114 proto_item_set_generated(range_item
);
2115 al_ptaddr
= tvb_get_letohs(tvb
, offset
);
2116 proto_tree_add_item(range_tree
, hf_dnp3_al_range_abs16
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2119 case AL_OBJQL_RANGE_AA32
: /* 32-bit Absolute Address in Range Field */
2121 proto_item_set_generated(range_item
);
2122 al_ptaddr
= tvb_get_letohl(tvb
, offset
);
2123 proto_tree_add_item(range_tree
, hf_dnp3_al_range_abs32
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2126 case AL_OBJQL_RANGE_SF8
: /* 8-bit Single Field Quantity in Range Field */
2127 num_items
= tvb_get_uint8(tvb
, offset
);
2128 proto_tree_add_item(range_tree
, hf_dnp3_al_range_quant8
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2130 proto_item_set_len(range_item
, rangebytes
);
2132 case AL_OBJQL_RANGE_SF16
: /* 16-bit Single Field Quantity in Range Field */
2133 num_items
= tvb_get_letohs(tvb
, offset
);
2134 proto_tree_add_item(range_tree
, hf_dnp3_al_range_quant16
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2136 proto_item_set_len(range_item
, rangebytes
);
2138 case AL_OBJQL_RANGE_SF32
: /* 32-bit Single Field Quantity in Range Field */
2139 num_items
= tvb_get_letohl(tvb
, offset
);
2140 proto_tree_add_item(range_tree
, hf_dnp3_al_range_quant32
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2142 proto_item_set_len(range_item
, rangebytes
);
2144 case AL_OBJQL_RANGE_FF
: /* 8 bit object count in Range Field */
2145 num_items
= tvb_get_uint8(tvb
, offset
);
2146 proto_tree_add_item(range_tree
, hf_dnp3_al_range_quant8
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2148 proto_item_set_len(range_item
, rangebytes
);
2150 if (num_items
> 0) {
2151 proto_item_append_text(object_item
, ", %d point%s", num_items
, plurality(num_items
, "", "s"));
2153 proto_item_append_text(range_item
, "%d", num_items
);
2155 /* A negative number of items is an error */
2156 if (num_items
< 0) {
2157 proto_item_append_text(range_item
, " (bogus)");
2158 expert_add_info(pinfo
, range_item
, &ei_dnp_num_items_neg
);
2159 return tvb_captured_length(tvb
);
2162 /* Move offset past any range field */
2163 offset
+= rangebytes
;
2165 bitindex
= 0; /* Temp variable for cycling through points when object values are encoded into
2166 bits; primarily objects 0x0101, 0x0301 & 0x1001 */
2168 /* Only process the point information for replies or items with point index lists */
2169 if (!header_only
|| al_objq_prefix
> 0) {
2173 start_offset
= offset
;
2174 for (item_num
= 0; item_num
< num_items
; item_num
++)
2176 proto_item
*point_item
;
2177 proto_tree
*point_tree
;
2181 /* Create Point item and process prefix */
2182 if (al_objq_prefix
<= AL_OBJQL_PREFIX_4O
) {
2183 point_tree
= proto_tree_add_subtree(object_tree
, tvb
, offset
, -1, ett_dnp3_al_obj_point
, &point_item
, "Point Number");
2186 point_tree
= proto_tree_add_subtree(object_tree
, tvb
, offset
, -1, ett_dnp3_al_obj_point
, &point_item
, "Object: Size");
2190 prefixbytes
= dnp3_al_obj_procprefix(tvb
, offset
, al_objq_prefix
, &al_ptaddr
, point_tree
);
2192 /* If this is an 'empty' object type as the num_items field is not equal to zero,
2193 then the packet is potentially malicious */
2194 if (dnp3_al_empty_obj(al_obj
)) {
2195 proto_item_append_text(range_item
, " (bogus)");
2196 expert_add_info(pinfo
, range_item
, &ei_dnp3_num_items_invalid
);
2200 proto_item_append_text(point_item
, " %u", al_ptaddr
);
2201 proto_item_set_len(point_item
, prefixbytes
);
2202 data_pos
+= prefixbytes
;
2204 if (!header_only
|| (AL_OBJQL_PREFIX_1OS
<= al_objq_prefix
&& al_objq_prefix
<= AL_OBJQL_PREFIX_4OS
)) {
2205 /* Process the object values */
2206 uint8_t al_2bit
, al_ptflags
, al_bi_val
, al_tcc_code
, al_sa_mac_len
;
2207 int16_t al_val_int16
;
2208 uint16_t al_val_uint16
, al_ctlobj_stat
;
2209 uint16_t al_relms
, al_filename_len
, al_file_ctrl_mode
;
2210 uint16_t sa_username_len
, sa_challengedata_len
, sa_updatekey_len
;
2211 int32_t al_val_int32
;
2212 uint32_t al_val_uint32
, file_data_size
;
2213 nstime_t al_reltime
, al_abstime
;
2217 const char *ctl_status_str
;
2219 /* Device Attributes (g0) all have a type code, use that rather than the individual variation */
2220 if (AL_OBJ_GROUP(al_obj
) == 0x0) {
2224 /* Add and retrieve the data type */
2225 proto_tree_add_item_ret_uint(point_tree
, hf_dnp3_al_datatype
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
, &data_type
);
2228 /* If a valid data type process it */
2229 if (try_val_to_str(data_type
, dnp3_al_data_type_vals
) != NULL
) {
2231 case AL_DATA_TYPE_NONE
:
2233 case AL_DATA_TYPE_VSTR
:
2234 da_len
= tvb_get_uint8(tvb
, data_pos
);
2235 proto_tree_add_item(point_tree
, hf_dnp3_al_da_length
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
2237 const uint8_t* da_value
;
2238 proto_tree_add_item_ret_string(point_tree
, hf_dnp3_al_da_value
, tvb
, data_pos
, da_len
, ENC_ASCII
|ENC_NA
, pinfo
->pool
, &da_value
);
2239 proto_item_append_text(object_item
, ", Value: %s", da_value
);
2242 case AL_DATA_TYPE_UINT
:
2243 da_len
= tvb_get_uint8(tvb
, data_pos
);
2244 proto_tree_add_item(point_tree
, hf_dnp3_al_da_length
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
2247 proto_tree_add_item(point_tree
, hf_dnp3_al_da_uint8
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
2248 proto_item_append_text(object_item
, ", Value: %u", tvb_get_uint8(tvb
, data_pos
));
2251 else if (da_len
== 2) {
2252 proto_tree_add_item(point_tree
, hf_dnp3_al_da_uint16
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
2253 proto_item_append_text(object_item
, ", Value: %u", tvb_get_letohs(tvb
, data_pos
));
2256 else if (da_len
== 4) {
2257 proto_tree_add_item(point_tree
, hf_dnp3_al_da_uint32
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
2258 proto_item_append_text(object_item
, ", Value: %u", tvb_get_letohl(tvb
, data_pos
));
2262 case AL_DATA_TYPE_INT
:
2263 da_len
= tvb_get_uint8(tvb
, data_pos
);
2264 proto_tree_add_item(point_tree
, hf_dnp3_al_da_length
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
2267 proto_tree_add_item(point_tree
, hf_dnp3_al_da_int8
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
2268 proto_item_append_text(object_item
, ", Value: %d", tvb_get_uint8(tvb
, data_pos
));
2271 else if (da_len
== 2) {
2272 proto_tree_add_item(point_tree
, hf_dnp3_al_da_int16
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
2273 proto_item_append_text(object_item
, ", Value: %d", tvb_get_letohs(tvb
, data_pos
));
2276 else if (da_len
== 4) {
2277 proto_tree_add_item(point_tree
, hf_dnp3_al_da_int32
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
2278 proto_item_append_text(object_item
, ", Value: %d", tvb_get_letohl(tvb
, data_pos
));
2282 case AL_DATA_TYPE_FLT
:
2283 da_len
= tvb_get_uint8(tvb
, data_pos
);
2284 proto_tree_add_item(point_tree
, hf_dnp3_al_da_length
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
2287 proto_tree_add_item(point_tree
, hf_dnp3_al_da_flt
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
2288 proto_item_append_text(object_item
, ", Value: %g", tvb_get_letohieee_float(tvb
, data_pos
));
2291 else if (da_len
== 8) {
2292 proto_tree_add_item(point_tree
, hf_dnp3_al_da_dbl
, tvb
, data_pos
, 8, ENC_LITTLE_ENDIAN
);
2293 proto_item_append_text(object_item
, ", Value: %g", tvb_get_letohieee_double(tvb
, data_pos
));
2297 case AL_DATA_TYPE_OSTR
:
2299 case AL_DATA_TYPE_BSTR
:
2301 case AL_DATA_TYPE_TIME
:
2303 case AL_DATA_TYPE_UNCD
:
2305 case AL_DATA_TYPE_U8BS8LIST
:
2307 case AL_DATA_TYPE_U8BS8EXLIST
:
2315 /* All other objects are handled here, by their variations */
2319 /* There is nothing to handle for the default variations */
2320 case AL_OBJ_BI_ALL
: /* Binary Input Default Variation (Obj:01, Var:Default) */
2321 case AL_OBJ_BIC_ALL
: /* Binary Input Change Default Variation (Obj:02, Var:Default) */
2322 case AL_OBJ_BOC_ALL
: /* Binary Output Event Default Variation (Obj:11, Var:Default) */
2323 case AL_OBJ_2BI_ALL
: /* Double-bit Input Default Variation (Obj:03, Var:Default) */
2324 case AL_OBJ_2BIC_ALL
: /* Double-bit Input Change Default Variation (Obj:04, Var:Default) */
2325 case AL_OBJ_CTR_ALL
: /* Binary Counter Default Variation (Obj:20, Var:Default) */
2326 case AL_OBJ_CTRC_ALL
: /* Binary Counter Change Default Variation (Obj:22 Var:Default) */
2327 case AL_OBJ_AI_ALL
: /* Analog Input Default Variation (Obj:30, Var:Default) */
2328 case AL_OBJ_AIC_ALL
: /* Analog Input Change Default Variation (Obj:32 Var:Default) */
2329 case AL_OBJ_AIDB_ALL
: /* Analog Input Deadband Default Variation (Obj:34, Var:Default) */
2330 case AL_OBJ_AOC_ALL
: /* Analog Output Event Default Variation (Obj:42 Var:Default) */
2331 case AL_OBJ_CLASS0
: /* Class Data Objects */
2339 /* Bit-based Data objects here */
2340 case AL_OBJ_BI_1BIT
: /* Single-Bit Binary Input (Obj:01, Var:01) */
2341 case AL_OBJ_BO
: /* Binary Output (Obj:10, Var:01) */
2342 case AL_OBJ_CTL_PMASK
: /* Pattern Mask (Obj:12, Var:03) */
2343 case AL_OBJ_IIN
: /* Internal Indications - IIN (Obj: 80, Var:01) */
2345 /* Extract the bit from the packed byte */
2346 al_bi_val
= tvb_get_uint8(tvb
, data_pos
);
2347 al_bit
= (al_bi_val
& 1) > 0;
2348 if (al_obj
== AL_OBJ_IIN
) {
2349 /* For an IIN bit, work out the IIN constant value for the bit position to get the name of the bit */
2350 uint16_t iin_bit
= 0;
2351 if (al_ptaddr
< 8) {
2352 iin_bit
= 0x100 << al_ptaddr
;
2355 iin_bit
= 1 << (al_ptaddr
- 8);
2357 proto_item_append_text(point_item
, " (%s), Value: %u",
2358 val_to_str_const(iin_bit
, dnp3_al_iin_vals
, "Invalid IIN bit"), al_bit
);
2362 if (al_objq_prefix
!= AL_OBJQL_PREFIX_NI
) {
2363 /* Each item has an index prefix, in this case bump
2364 the bitindex to force the correct offset adjustment */
2368 /* Regular packed bits, get the value at the appropriate bit index */
2369 al_bit
= (al_bi_val
& (1 << bitindex
)) > 0;
2371 proto_item_append_text(point_item
, ", Value: %u", al_bit
);
2375 proto_tree_add_boolean(point_tree
, hf_dnp3_al_bit0
, tvb
, data_pos
, 1, al_bi_val
);
2378 proto_tree_add_boolean(point_tree
, hf_dnp3_al_bit1
, tvb
, data_pos
, 1, al_bi_val
);
2381 proto_tree_add_boolean(point_tree
, hf_dnp3_al_bit2
, tvb
, data_pos
, 1, al_bi_val
);
2384 proto_tree_add_boolean(point_tree
, hf_dnp3_al_bit3
, tvb
, data_pos
, 1, al_bi_val
);
2387 proto_tree_add_boolean(point_tree
, hf_dnp3_al_bit4
, tvb
, data_pos
, 1, al_bi_val
);
2390 proto_tree_add_boolean(point_tree
, hf_dnp3_al_bit5
, tvb
, data_pos
, 1, al_bi_val
);
2393 proto_tree_add_boolean(point_tree
, hf_dnp3_al_bit6
, tvb
, data_pos
, 1, al_bi_val
);
2396 proto_tree_add_boolean(point_tree
, hf_dnp3_al_bit7
, tvb
, data_pos
, 1, al_bi_val
);
2402 proto_item_set_len(point_item
, prefixbytes
+ 1);
2404 /* Increment the bit index for next cycle */
2407 /* If we have counted 8 bits or read the last item,
2408 reset bit index and move onto the next byte */
2409 if ((bitindex
> 7) || (item_num
== (num_items
-1)))
2412 offset
+= (prefixbytes
+ 1);
2416 case AL_OBJ_2BI_NF
: /* Double-bit Input No Flags (Obj:03, Var:01) */
2418 /* Extract the Double-bit from the packed byte */
2419 al_bi_val
= tvb_get_uint8(tvb
, offset
);
2420 al_2bit
= ((al_bi_val
>> (bitindex
<< 1)) & 3);
2422 proto_item_append_text(point_item
, ", State: %s", val_to_str_ext(al_2bit
, &dnp3_al_dbi_vals_ext
, "Unknown double bit state (0x%02x)"));
2426 proto_tree_add_uint(point_tree
, hf_dnp3_al_2bit0
, tvb
, offset
, 1, al_bi_val
);
2429 proto_tree_add_uint(point_tree
, hf_dnp3_al_2bit1
, tvb
, offset
, 1, al_bi_val
);
2432 proto_tree_add_uint(point_tree
, hf_dnp3_al_2bit2
, tvb
, offset
, 1, al_bi_val
);
2435 proto_tree_add_uint(point_tree
, hf_dnp3_al_2bit3
, tvb
, offset
, 1, al_bi_val
);
2441 proto_item_set_len(point_item
, prefixbytes
+ 1);
2443 /* Increment the bit index for next cycle */
2446 /* If we have counted 4 double bits or read the last item,
2447 reset bit index and move onto the next byte */
2448 if ((bitindex
> 3) || (item_num
== (num_items
-1)))
2451 offset
+= (prefixbytes
+ 1);
2455 case AL_OBJ_BI_STAT
: /* Binary Input With Status (Obj:01, Var:02) */
2456 case AL_OBJ_BIC_NOTIME
: /* Binary Input Change Without Time (Obj:02, Var:01) */
2457 case AL_OBJ_BO_STAT
: /* Binary Output Status (Obj:10, Var:02) */
2458 case AL_OBJ_BOC_NOTIME
: /* Binary Output Change Without Time (Obj:11, Var:01) */
2460 /* Get Point Flags */
2461 al_ptflags
= tvb_get_uint8(tvb
, data_pos
);
2464 case AL_OBJ_BI_STAT
:
2465 case AL_OBJ_BIC_NOTIME
:
2466 dnp3_al_obj_quality(tvb
, data_pos
, al_ptflags
, point_tree
, point_item
, BIN_IN
);
2468 case AL_OBJ_BO_STAT
:
2469 case AL_OBJ_BOC_NOTIME
:
2470 dnp3_al_obj_quality(tvb
, data_pos
, al_ptflags
, point_tree
, point_item
, BIN_OUT
);
2475 al_bit
= (al_ptflags
& AL_OBJ_BI_FLAG7
) > 0;
2476 proto_item_append_text(point_item
, ", Value: %u", al_bit
);
2478 proto_item_set_len(point_item
, data_pos
- offset
);
2483 case AL_OBJ_2BI_STAT
: /* Double-bit Input With Status (Obj:03, Var:02) */
2484 case AL_OBJ_2BIC_NOTIME
: /* Double-bit Input Change Without Time (Obj:04, Var:01) */
2486 /* Get Point Flags */
2487 al_ptflags
= tvb_get_uint8(tvb
, data_pos
);
2488 dnp3_al_obj_quality(tvb
, data_pos
, al_ptflags
, point_tree
, point_item
, DBIN_IN
);
2491 al_2bit
= (al_ptflags
>> 6) & 3;
2492 proto_item_append_text(point_item
, ", State: %s", val_to_str_ext(al_2bit
, &dnp3_al_dbi_vals_ext
, "Unknown double bit state (0x%02x)"));
2493 proto_item_set_len(point_item
, data_pos
- offset
);
2498 case AL_OBJ_BIC_TIME
: /* Binary Input Change w/ Time (Obj:02, Var:02) */
2499 case AL_OBJ_BOC_TIME
: /* Binary Output Change w/ Time (Obj:11, Var:02) */
2501 /* Get Point Flags */
2502 al_ptflags
= tvb_get_uint8(tvb
, data_pos
);
2504 case AL_OBJ_BIC_TIME
:
2505 dnp3_al_obj_quality(tvb
, data_pos
, al_ptflags
, point_tree
, point_item
, BIN_IN
);
2507 case AL_OBJ_BOC_TIME
:
2508 dnp3_al_obj_quality(tvb
, data_pos
, al_ptflags
, point_tree
, point_item
, BIN_OUT
);
2514 dnp3_al_get_timestamp(&al_abstime
, tvb
, data_pos
);
2515 proto_tree_add_time(point_tree
, hf_dnp3_al_timestamp
, tvb
, data_pos
, 6, &al_abstime
);
2518 al_bit
= (al_ptflags
& AL_OBJ_BI_FLAG7
) >> 7; /* bit shift 1xxxxxxx -> xxxxxxx1 */
2519 proto_item_append_text(point_item
, ", Value: %u, Timestamp: %s",
2520 al_bit
, abs_time_to_str(pinfo
->pool
, &al_abstime
, ABSOLUTE_TIME_UTC
, false));
2521 proto_item_set_len(point_item
, data_pos
- offset
);
2526 case AL_OBJ_2BIC_TIME
: /* Double-bit Input Change w/ Time (Obj:04, Var:02) */
2528 /* Get Point Flags */
2529 al_ptflags
= tvb_get_uint8(tvb
, data_pos
);
2530 dnp3_al_obj_quality(tvb
, (offset
+prefixbytes
), al_ptflags
, point_tree
, point_item
, DBIN_IN
);
2534 dnp3_al_get_timestamp(&al_abstime
, tvb
, data_pos
);
2535 proto_tree_add_time(point_tree
, hf_dnp3_al_timestamp
, tvb
, data_pos
, 6, &al_abstime
);
2538 al_2bit
= (al_ptflags
>> 6) & 3; /* bit shift 11xxxxxx -> 00000011 */
2539 proto_item_append_text(point_item
, ", State: %s, Timestamp: %s",
2540 val_to_str_ext(al_2bit
, &dnp3_al_dbi_vals_ext
, "Unknown double bit state (0x%02x)"),
2541 abs_time_to_str(pinfo
->pool
, &al_abstime
, ABSOLUTE_TIME_UTC
, FALSE
));
2542 proto_item_set_len(point_item
, data_pos
- offset
);
2547 case AL_OBJ_BIC_RTIME
: /* Binary Input Change w/ Relative Time (Obj:02, Var:03) */
2548 case AL_OBJ_2BIC_RTIME
: /* Double-bit Input Change w/ Relative Time (Obj:04, Var:03) */
2550 /* Get Point Flags */
2551 al_ptflags
= tvb_get_uint8(tvb
, data_pos
);
2552 if (al_obj
== AL_OBJ_BIC_RTIME
) {
2553 dnp3_al_obj_quality(tvb
, data_pos
, al_ptflags
, point_tree
, point_item
, BIN_IN
);
2555 else /* MUST be AL_OBJ_2BIC_RTIME */ {
2556 dnp3_al_obj_quality(tvb
, data_pos
, al_ptflags
, point_tree
, point_item
, DBIN_IN
);
2560 /* Get relative time in ms, and convert to ns_time */
2561 al_relms
= tvb_get_letohs(tvb
, data_pos
);
2562 al_reltime
.secs
= al_relms
/ 1000;
2563 al_reltime
.nsecs
= (al_relms
% 1000) * 1000000;
2564 /* Now add to CTO time */
2565 nstime_sum(&al_abstime
, al_cto
, &al_reltime
);
2566 proto_tree_add_time(point_tree
, hf_dnp3_al_rel_timestamp
, tvb
, data_pos
, 2, &al_reltime
);
2570 case AL_OBJ_BIC_RTIME
:
2571 al_bit
= (al_ptflags
& AL_OBJ_BI_FLAG7
) >> 7; /* bit shift 1xxxxxxx -> xxxxxxx1 */
2572 proto_item_append_text(point_item
, ", Value: %u, Timestamp: %s",
2573 al_bit
, abs_time_to_str(pinfo
->pool
, &al_abstime
, ABSOLUTE_TIME_UTC
, false));
2575 case AL_OBJ_2BIC_RTIME
:
2576 al_2bit
= (al_ptflags
>> 6) & 3; /* bit shift 11xxxxxx -> 00000011 */
2577 proto_item_append_text(point_item
, ", State: %s, Timestamp: %s",
2578 val_to_str_ext(al_2bit
, &dnp3_al_dbi_vals_ext
, "Unknown double bit state (0x%02x)"),
2579 abs_time_to_str(pinfo
->pool
, &al_abstime
, ABSOLUTE_TIME_UTC
, FALSE
));
2582 proto_item_set_len(point_item
, data_pos
- offset
);
2587 case AL_OBJ_CTLOP_BLK
: /* Control Relay Output Block (Obj:12, Var:01) */
2588 case AL_OBJ_CTL_PCB
: /* Pattern Control Block (Obj:12, Var:02) */
2590 proto_tree
*tcc_tree
;
2592 /* Add a expand/collapse for TCC */
2593 al_tcc_code
= tvb_get_uint8(tvb
, data_pos
);
2594 tcc_tree
= proto_tree_add_subtree_format(point_tree
, tvb
, data_pos
, 1,
2595 ett_dnp3_al_obj_point_tcc
, NULL
, "Control Code [0x%02x]",al_tcc_code
);
2597 /* Add the Control Code to the Point number list for quick visual reference as to the operation */
2598 proto_item_append_text(point_item
, " [%s]", val_to_str_const((al_tcc_code
& AL_OBJCTLC_CODE
),
2599 dnp3_al_ctlc_code_vals
,
2600 "Invalid Operation"));
2602 /* Add Trip/Close qualifier (if applicable) to previously appended quick visual reference */
2603 proto_item_append_text(point_item
, " [%s]", val_to_str_const((al_tcc_code
& AL_OBJCTLC_TC
) >> 6,
2604 dnp3_al_ctlc_tc_vals
,
2605 "Invalid Qualifier"));
2609 /* Control Code 'Operation Type' */
2610 proto_tree_add_item(tcc_tree
, hf_dnp3_ctlobj_code_c
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
2612 /* Control Code Misc Values */
2613 proto_tree_add_item(tcc_tree
, hf_dnp3_ctlobj_code_m
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
2615 /* Control Code 'Trip Close Code' */
2616 proto_tree_add_item(tcc_tree
, hf_dnp3_ctlobj_code_tc
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
2619 /* Get "Count" Field */
2620 proto_tree_add_item(point_tree
, hf_dnp3_al_count
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
2623 /* Get "On Time" Field */
2624 proto_tree_add_item(point_tree
, hf_dnp3_al_on_time
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
2627 /* Get "Off Time" Field */
2628 proto_tree_add_item(point_tree
, hf_dnp3_al_off_time
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
2631 /* Get "Control Status" Field */
2632 proto_tree_add_item(point_tree
, hf_dnp3_al_ctrlstatus
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
2635 proto_item_set_len(point_item
, data_pos
- offset
);
2641 case AL_OBJ_BOE_NOTIME
: /* Binary Command Event (Obj:13, Var:01) */
2642 case AL_OBJ_BOE_TIME
: /* Binary Command Event with time (Obj:13, Var:02) */
2643 case AL_OBJ_AOC_32EVNT
: /* 32-bit Analog Command Event (Obj:43, Var:01) */
2644 case AL_OBJ_AOC_16EVNT
: /* 16-bit Analog Command Event (Obj:43, Var:02) */
2645 case AL_OBJ_AOC_32EVTT
: /* 32-bit Analog Command Event with time (Obj:43, Var:03) */
2646 case AL_OBJ_AOC_16EVTT
: /* 16-bit Analog Command Event with time (Obj:43, Var:04) */
2647 case AL_OBJ_AOC_FLTEVNT
: /* 32-bit Floating Point Analog Command Event (Obj:43, Var:05) */
2648 case AL_OBJ_AOC_DBLEVNT
: /* 64-bit Floating Point Analog Command Event (Obj:43, Var:06) */
2649 case AL_OBJ_AOC_FLTEVTT
: /* 32-bit Floating Point Analog Command Event with time (Obj:43, Var:07) */
2650 case AL_OBJ_AOC_DBLEVTT
: /* 64-bit Floating Point Analog Command Event with time (Obj:43, Var:08) */
2652 /* Get the status code */
2653 al_ctlobj_stat
= tvb_get_uint8(tvb
, data_pos
) & AL_OBJCTL_STATUS_MASK
;
2654 ctl_status_str
= val_to_str_ext(al_ctlobj_stat
, &dnp3_al_ctl_status_vals_ext
, "Invalid Status (0x%02x)");
2655 proto_item_append_text(point_item
, " [Status: %s (0x%02x)]", ctl_status_str
, al_ctlobj_stat
);
2656 proto_tree_add_item(point_tree
, hf_dnp3_al_ctrlstatus
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
2658 /* Get the command value */
2661 case AL_OBJ_BOE_NOTIME
:
2662 case AL_OBJ_BOE_TIME
:
2663 proto_tree_add_item(point_tree
, hf_dnp3_bocs_bit
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
2666 case AL_OBJ_AOC_32EVNT
:
2667 case AL_OBJ_AOC_32EVTT
:
2668 data_pos
+= 1; /* Step past status */
2669 al_val_int32
= tvb_get_letohl(tvb
, data_pos
);
2670 proto_item_append_text(point_item
, ", Value: %d", al_val_int32
);
2671 proto_tree_add_item(point_tree
, hf_dnp3_al_anaout32
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
2673 case AL_OBJ_AOC_16EVNT
:
2674 case AL_OBJ_AOC_16EVTT
:
2675 data_pos
+= 1; /* Step past status */
2676 al_val_int16
= tvb_get_letohs(tvb
, data_pos
);
2677 proto_item_append_text(point_item
, ", Value: %d", al_val_int16
);
2678 proto_tree_add_item(point_tree
, hf_dnp3_al_anaout16
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
2681 case AL_OBJ_AOC_FLTEVNT
:
2682 case AL_OBJ_AOC_FLTEVTT
:
2683 data_pos
+= 1; /* Step past status */
2684 al_valflt
= tvb_get_letohieee_float(tvb
, data_pos
);
2685 proto_item_append_text(point_item
, ", Value: %g", al_valflt
);
2686 proto_tree_add_item(point_tree
, hf_dnp3_al_anaoutflt
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
2689 case AL_OBJ_AOC_DBLEVNT
:
2690 case AL_OBJ_AOC_DBLEVTT
:
2691 data_pos
+= 1; /* Step past status */
2692 al_valdbl
= tvb_get_letohieee_double(tvb
, data_pos
);
2693 proto_item_append_text(point_item
, ", Value: %g", al_valdbl
);
2694 proto_tree_add_item(point_tree
, hf_dnp3_al_anaoutdbl
, tvb
, data_pos
, 8, ENC_LITTLE_ENDIAN
);
2699 /* Get the timestamp */
2702 case AL_OBJ_BOE_TIME
: /* Binary Command Event with time (Obj:13, Var:02) */
2703 case AL_OBJ_AOC_32EVTT
: /* 32-bit Analog Command Event with time (Obj:43, Var:03) */
2704 case AL_OBJ_AOC_16EVTT
: /* 16-bit Analog Command Event with time (Obj:43, Var:04) */
2705 case AL_OBJ_AOC_FLTEVTT
: /* 32-bit Floating Point Analog Command Event with time (Obj:43, Var:07) */
2706 case AL_OBJ_AOC_DBLEVTT
: /* 64-bit Floating Point Analog Command Event with time (Obj:43, Var:08) */
2707 dnp3_al_get_timestamp(&al_abstime
, tvb
, data_pos
);
2708 proto_item_append_text(point_item
, ", Timestamp: %s", abs_time_to_str(pinfo
->pool
, &al_abstime
, ABSOLUTE_TIME_UTC
, false));
2709 proto_tree_add_time(point_tree
, hf_dnp3_al_timestamp
, tvb
, data_pos
, 6, &al_abstime
);
2714 proto_item_set_len(point_item
, data_pos
- offset
);
2719 case AL_OBJ_AO_32OPB
: /* 32-Bit Analog Output Block (Obj:41, Var:01) */
2720 case AL_OBJ_AO_16OPB
: /* 16-Bit Analog Output Block (Obj:41, Var:02) */
2721 case AL_OBJ_AO_FLTOPB
: /* 32-Bit Floating Point Output Block (Obj:41, Var:03) */
2722 case AL_OBJ_AO_DBLOPB
: /* 64-Bit Floating Point Output Block (Obj:41, Var:04) */
2726 case AL_OBJ_AO_32OPB
:
2727 al_val_int32
= tvb_get_letohl(tvb
, data_pos
);
2728 proto_item_append_text(point_item
, ", Value: %d", al_val_int32
);
2729 proto_tree_add_item(point_tree
, hf_dnp3_al_anaout32
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
2732 case AL_OBJ_AO_16OPB
:
2733 al_val_int16
= tvb_get_letohs(tvb
, data_pos
);
2734 proto_item_append_text(point_item
, ", Value: %d", al_val_int16
);
2735 proto_tree_add_item(point_tree
, hf_dnp3_al_anaout16
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
2738 case AL_OBJ_AO_FLTOPB
:
2739 al_valflt
= tvb_get_letohieee_float(tvb
, data_pos
);
2740 proto_item_append_text(point_item
, ", Value: %g", al_valflt
);
2741 proto_tree_add_item(point_tree
, hf_dnp3_al_anaoutflt
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
2744 case AL_OBJ_AO_DBLOPB
:
2745 al_valdbl
= tvb_get_letohieee_double(tvb
, data_pos
);
2746 proto_item_append_text(point_item
, ", Value: %g", al_valdbl
);
2747 proto_tree_add_item(point_tree
, hf_dnp3_al_anaoutdbl
, tvb
, data_pos
, 8, ENC_LITTLE_ENDIAN
);
2752 /* Get control status */
2753 al_ctlobj_stat
= tvb_get_uint8(tvb
, data_pos
) & AL_OBJCTL_STATUS_MASK
;
2754 ctl_status_str
= val_to_str_ext(al_ctlobj_stat
, &dnp3_al_ctl_status_vals_ext
, "Invalid Status (0x%02x)");
2755 proto_item_append_text(point_item
, " [Status: %s (0x%02x)]", ctl_status_str
, al_ctlobj_stat
);
2756 proto_tree_add_item(point_tree
, hf_dnp3_al_ctrlstatus
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
2759 proto_item_set_len(point_item
, data_pos
- offset
);
2764 case AL_OBJ_CTR_32
: /* 32-Bit Binary Counter (Obj:20, Var:01) */
2765 case AL_OBJ_CTR_16
: /* 16-Bit Binary Counter (Obj:20, Var:02) */
2766 case AL_OBJ_DCTR_32
: /* 32-Bit Binary Delta Counter (Obj:20, Var:03) */
2767 case AL_OBJ_DCTR_16
: /* 16-Bit Binary Delta Counter (Obj:20, Var:04) */
2768 case AL_OBJ_CTR_32NF
: /* 32-Bit Binary Counter Without Flag (Obj:20, Var:05) */
2769 case AL_OBJ_CTR_16NF
: /* 16-Bit Binary Counter Without Flag (Obj:20, Var:06) */
2770 case AL_OBJ_DCTR_32NF
: /* 32-Bit Binary Delta Counter Without Flag (Obj:20, Var:07) */
2771 case AL_OBJ_DCTR_16NF
: /* 16-Bit Binary Delta Counter Without Flag (Obj:20, Var:08) */
2772 case AL_OBJ_FCTR_32
: /* 32-Bit Frozen Counter (Obj:21, Var:01) */
2773 case AL_OBJ_FCTR_16
: /* 16-Bit Frozen Counter (Obj:21, Var:02) */
2774 case AL_OBJ_FDCTR_32
: /* 21 03 32-Bit Frozen Delta Counter */
2775 case AL_OBJ_FDCTR_16
: /* 21 04 16-Bit Frozen Delta Counter */
2776 case AL_OBJ_FCTR_32T
: /* 32-Bit Frozen Counter w/ Time of Freeze (Obj:21 Var:05 ) */
2777 case AL_OBJ_FCTR_16T
: /* 16-Bit Frozen Counter w/ Time of Freeze (Obj:21 Var:06) */
2778 case AL_OBJ_FDCTR_32T
: /* 32-Bit Frozen Delta Counter w/ Time of Freeze (Obj:21 Var:07) */
2779 case AL_OBJ_FDCTR_16T
: /* 16-Bit Frozen Delta Counter w/ Time of Freeze (Obj:21 Var:08) */
2780 case AL_OBJ_FCTR_32NF
: /* 32-Bit Frozen Counter Without Flag (Obj:21 Var:09) */
2781 case AL_OBJ_FCTR_16NF
: /* 16-Bit Frozen Counter Without Flag (Obj:21 Var:10) */
2782 case AL_OBJ_FDCTR_32NF
: /* 32-Bit Frozen Delta Counter Without Flag (Obj:21 Var:11) */
2783 case AL_OBJ_FDCTR_16NF
: /* 16-Bit Frozen Delta Counter Without Flag (Obj:21 Var:12) */
2784 case AL_OBJ_CTRC_32
: /* 32-Bit Counter Change Event w/o Time (Obj:22, Var:01) */
2785 case AL_OBJ_CTRC_16
: /* 16-Bit Counter Change Event w/o Time (Obj:22, Var:02) */
2786 case AL_OBJ_DCTRC_32
: /* 32-Bit Delta Counter Change Event w/o Time (Obj:22, Var:03) */
2787 case AL_OBJ_DCTRC_16
: /* 16-Bit Delta Counter Change Event w/o Time (Obj:22, Var:04) */
2788 case AL_OBJ_CTRC_32T
: /* 32-Bit Counter Change Event with Time (Obj:22, Var:05) */
2789 case AL_OBJ_CTRC_16T
: /* 16-Bit Counter Change Event with Time (Obj:22, Var:06) */
2790 case AL_OBJ_DCTRC_32T
: /* 32-Bit Delta Counter Change Event with Time (Obj:22, Var:07) */
2791 case AL_OBJ_DCTRC_16T
: /* 16-Bit Delta Counter Change Event with Time (Obj:22, Var:08) */
2792 case AL_OBJ_FCTRC_32
: /* 32-Bit Frozen Counter Change Event (Obj:23 Var:01) */
2793 case AL_OBJ_FCTRC_16
: /* 16-Bit Frozen Counter Change Event (Obj:23 Var:02) */
2794 case AL_OBJ_FDCTRC_32
: /* 32-Bit Frozen Delta Counter Change Event (Obj:23 Var:03) */
2795 case AL_OBJ_FDCTRC_16
: /* 16-Bit Frozen Delta Counter Change Event (Obj:23 Var:04) */
2796 case AL_OBJ_FCTRC_32T
: /* 32-Bit Frozen Counter Change Event w/ Time of Freeze (Obj:23 Var:05) */
2797 case AL_OBJ_FCTRC_16T
: /* 16-Bit Frozen Counter Change Event w/ Time of Freeze (Obj:23 Var:06) */
2798 case AL_OBJ_FDCTRC_32T
: /* 32-Bit Frozen Delta Counter Change Event w/ Time of Freeze (Obj:23 Var:07) */
2799 case AL_OBJ_FDCTRC_16T
: /* 16-Bit Frozen Delta Counter Change Event w/ Time of Freeze (Obj:23 Var:08) */
2801 /* Get Point Flags for those types that have them, it's easier to block out those that don't have flags */
2804 case AL_OBJ_CTR_32NF
:
2805 case AL_OBJ_CTR_16NF
:
2806 case AL_OBJ_DCTR_32NF
:
2807 case AL_OBJ_DCTR_16NF
:
2808 case AL_OBJ_FCTR_32NF
:
2809 case AL_OBJ_FCTR_16NF
:
2810 case AL_OBJ_FDCTR_32NF
:
2811 case AL_OBJ_FDCTR_16NF
:
2815 al_ptflags
= tvb_get_uint8(tvb
, data_pos
);
2816 dnp3_al_obj_quality(tvb
, data_pos
, al_ptflags
, point_tree
, point_item
, COUNTER
);
2821 /* Get Counter values */
2825 case AL_OBJ_DCTR_32
:
2826 case AL_OBJ_CTR_32NF
:
2827 case AL_OBJ_DCTR_32NF
:
2828 case AL_OBJ_FCTR_32
:
2829 case AL_OBJ_FDCTR_32
:
2830 case AL_OBJ_FCTR_32T
:
2831 case AL_OBJ_FDCTR_32T
:
2832 case AL_OBJ_FCTR_32NF
:
2833 case AL_OBJ_FDCTR_32NF
:
2834 case AL_OBJ_CTRC_32
:
2835 case AL_OBJ_DCTRC_32
:
2836 case AL_OBJ_CTRC_32T
:
2837 case AL_OBJ_DCTRC_32T
:
2838 case AL_OBJ_FCTRC_32
:
2839 case AL_OBJ_FDCTRC_32
:
2840 case AL_OBJ_FCTRC_32T
:
2841 case AL_OBJ_FDCTRC_32T
:
2843 al_val_uint32
= tvb_get_letohl(tvb
, data_pos
);
2844 proto_item_append_text(point_item
, ", Count: %u", al_val_uint32
);
2845 proto_tree_add_item(point_tree
, hf_dnp3_al_cnt32
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
2850 case AL_OBJ_DCTR_16
:
2851 case AL_OBJ_CTR_16NF
:
2852 case AL_OBJ_DCTR_16NF
:
2853 case AL_OBJ_FCTR_16
:
2854 case AL_OBJ_FDCTR_16
:
2855 case AL_OBJ_FCTR_16T
:
2856 case AL_OBJ_FDCTR_16T
:
2857 case AL_OBJ_FCTR_16NF
:
2858 case AL_OBJ_FDCTR_16NF
:
2859 case AL_OBJ_CTRC_16
:
2860 case AL_OBJ_DCTRC_16
:
2861 case AL_OBJ_CTRC_16T
:
2862 case AL_OBJ_DCTRC_16T
:
2863 case AL_OBJ_FCTRC_16
:
2864 case AL_OBJ_FDCTRC_16
:
2865 case AL_OBJ_FCTRC_16T
:
2866 case AL_OBJ_FDCTRC_16T
:
2868 al_val_uint16
= tvb_get_letohs(tvb
, data_pos
);
2869 proto_item_append_text(point_item
, ", Count: %u", al_val_uint16
);
2870 proto_tree_add_item(point_tree
, hf_dnp3_al_cnt16
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
2875 /* Get the time for those points that have it */
2878 case AL_OBJ_FCTR_32T
:
2879 case AL_OBJ_FCTR_16T
:
2880 case AL_OBJ_FDCTR_32T
:
2881 case AL_OBJ_FDCTR_16T
:
2882 case AL_OBJ_CTRC_32T
:
2883 case AL_OBJ_CTRC_16T
:
2884 case AL_OBJ_DCTRC_32T
:
2885 case AL_OBJ_DCTRC_16T
:
2886 case AL_OBJ_FCTRC_32T
:
2887 case AL_OBJ_FCTRC_16T
:
2888 case AL_OBJ_FDCTRC_32T
:
2889 case AL_OBJ_FDCTRC_16T
:
2890 dnp3_al_get_timestamp(&al_abstime
, tvb
, data_pos
);
2891 proto_item_append_text(point_item
, ", Timestamp: %s", abs_time_to_str(pinfo
->pool
, &al_abstime
, ABSOLUTE_TIME_UTC
, false));
2892 proto_tree_add_time(point_tree
, hf_dnp3_al_timestamp
, tvb
, data_pos
, 6, &al_abstime
);
2897 proto_item_set_len(point_item
, data_pos
- offset
);
2901 case AL_OBJ_AI_32
: /* 32-Bit Analog Input (Obj:30, Var:01) */
2902 case AL_OBJ_AI_16
: /* 16-Bit Analog Input (Obj:30, Var:02) */
2903 case AL_OBJ_AI_32NF
: /* 32-Bit Analog Input Without Flag (Obj:30, Var:03) */
2904 case AL_OBJ_AI_16NF
: /* 16-Bit Analog Input Without Flag (Obj:30, Var:04) */
2905 case AL_OBJ_AI_FLT
: /* 32-Bit Floating Point Input (Obj:30, Var:05) */
2906 case AL_OBJ_AI_DBL
: /* 64-Bit Floating Point Input (Obj:30, Var:06) */
2907 case AL_OBJ_AIFC_32
: /* 32-Bit Frozen Analog Input (Obj:31, Var:01) */
2908 case AL_OBJ_AIFC_16
: /* 16-Bit Frozen Analog Input (Obj:31, Var:02) */
2909 case AL_OBJ_AIFC_32TOF
: /* 32-Bit Frozen Analog Input w/ Time of Freeze (Obj:31, Var:03) */
2910 case AL_OBJ_AIFC_16TOF
: /* 16-Bit Frozen Analog Input w/ Time of Freeze (Obj:31, Var:04) */
2911 case AL_OBJ_AIFC_32NF
: /* 32-Bit Frozen Analog Input Without Flag (Obj:31, Var:05) */
2912 case AL_OBJ_AIFC_16NF
: /* 16-Bit Frozen Analog Input Without Flag (Obj:31, Var:06) */
2913 case AL_OBJ_AIF_FLT
: /* 32-Bit Frozen Floating Point Input (Obj:31, Var:07) */
2914 case AL_OBJ_AIF_DBL
: /* 64-Bit Frozen Floating Point Input (Obj:31, Var:08) */
2915 case AL_OBJ_AIC_32NT
: /* 32-Bit Analog Change Event w/o Time (Obj:32, Var:01) */
2916 case AL_OBJ_AIC_16NT
: /* 16-Bit Analog Change Event w/o Time (Obj:32, Var:02) */
2917 case AL_OBJ_AIC_32T
: /* 32-Bit Analog Change Event with Time (Obj:32, Var:03) */
2918 case AL_OBJ_AIC_16T
: /* 16-Bit Analog Change Event with Time (Obj:32, Var:04) */
2919 case AL_OBJ_AIC_FLTNT
: /* 32-Bit Floating Point Change Event w/o Time (Obj:32, Var:05) */
2920 case AL_OBJ_AIC_DBLNT
: /* 64-Bit Floating Point Change Event w/o Time (Obj:32, Var:06) */
2921 case AL_OBJ_AIC_FLTT
: /* 32-Bit Floating Point Change Event w/ Time (Obj:32, Var:07) */
2922 case AL_OBJ_AIC_DBLT
: /* 64-Bit Floating Point Change Event w/ Time (Obj:32, Var:08) */
2923 case AL_OBJ_AIFC_32NT
: /* 32-Bit Frozen Analog Event w/o Time (Obj:33, Var:01) */
2924 case AL_OBJ_AIFC_16NT
: /* 16-Bit Frozen Analog Event w/o Time (Obj:33, Var:02) */
2925 case AL_OBJ_AIFC_32T
: /* 32-Bit Frozen Analog Event w/ Time (Obj:33, Var:03) */
2926 case AL_OBJ_AIFC_16T
: /* 16-Bit Frozen Analog Event w/ Time (Obj:33, Var:04) */
2927 case AL_OBJ_AIFC_FLTNT
: /* 32-Bit Floating Point Frozen Change Event w/o Time (Obj:33, Var:05) */
2928 case AL_OBJ_AIFC_DBLNT
: /* 64-Bit Floating Point Frozen Change Event w/o Time (Obj:33, Var:06) */
2929 case AL_OBJ_AIFC_FLTT
: /* 32-Bit Floating Point Frozen Change Event w/ Time (Obj:33, Var:07) */
2930 case AL_OBJ_AIFC_DBLT
: /* 64-Bit Floating Point Frozen Change Event w/ Time (Obj:33, Var:08) */
2931 case AL_OBJ_AIDB_16
: /* 16-Bit Analog Input Deadband (Obj:34, Var:01) */
2932 case AL_OBJ_AIDB_32
: /* 32-Bit Analog Input Deadband (Obj:34, Var:02) */
2933 case AL_OBJ_AIDB_FLT
: /* 32-Bit Floating Point Analog Input Deadband (Obj:34, Var:03) */
2935 /* Get Point Flags for those types that have them */
2938 case AL_OBJ_AI_32NF
:
2939 case AL_OBJ_AI_16NF
:
2940 case AL_OBJ_AIFC_32NF
:
2941 case AL_OBJ_AIFC_16NF
:
2942 case AL_OBJ_AIDB_16
:
2943 case AL_OBJ_AIDB_32
:
2944 case AL_OBJ_AIDB_FLT
:
2948 al_ptflags
= tvb_get_uint8(tvb
, data_pos
);
2949 dnp3_al_obj_quality(tvb
, data_pos
, al_ptflags
, point_tree
, point_item
, ANA_IN
);
2957 case AL_OBJ_AI_32NF
:
2958 case AL_OBJ_AIFC_32
:
2959 case AL_OBJ_AIFC_32TOF
:
2960 case AL_OBJ_AIFC_32NF
:
2961 case AL_OBJ_AIC_32NT
:
2962 case AL_OBJ_AIC_32T
:
2963 case AL_OBJ_AIFC_32NT
:
2964 case AL_OBJ_AIFC_32T
:
2965 case AL_OBJ_AIDB_32
:
2967 al_val_int32
= tvb_get_letohl(tvb
, data_pos
);
2968 proto_item_append_text(point_item
, ", Value: %d", al_val_int32
);
2969 proto_tree_add_item(point_tree
, hf_dnp3_al_ana32
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
2974 case AL_OBJ_AI_16NF
:
2975 case AL_OBJ_AIFC_16
:
2976 case AL_OBJ_AIFC_16TOF
:
2977 case AL_OBJ_AIFC_16NF
:
2978 case AL_OBJ_AIC_16NT
:
2979 case AL_OBJ_AIC_16T
:
2980 case AL_OBJ_AIFC_16NT
:
2981 case AL_OBJ_AIFC_16T
:
2982 case AL_OBJ_AIDB_16
:
2984 al_val_int16
= tvb_get_letohs(tvb
, data_pos
);
2985 proto_item_append_text(point_item
, ", Value: %d", al_val_int16
);
2986 proto_tree_add_item(point_tree
, hf_dnp3_al_ana16
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
2991 case AL_OBJ_AIF_FLT
:
2992 case AL_OBJ_AIC_FLTNT
:
2993 case AL_OBJ_AIC_FLTT
:
2994 case AL_OBJ_AIFC_FLTNT
:
2995 case AL_OBJ_AIFC_FLTT
:
2996 case AL_OBJ_AIDB_FLT
:
2998 al_valflt
= tvb_get_letohieee_float(tvb
, data_pos
);
2999 proto_item_append_text(point_item
, ", Value: %g", al_valflt
);
3000 proto_tree_add_item(point_tree
, hf_dnp3_al_anaflt
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3005 case AL_OBJ_AIF_DBL
:
3006 case AL_OBJ_AIC_DBLNT
:
3007 case AL_OBJ_AIC_DBLT
:
3008 case AL_OBJ_AIFC_DBLNT
:
3009 case AL_OBJ_AIFC_DBLT
:
3011 al_valdbl
= tvb_get_letohieee_double(tvb
, data_pos
);
3012 proto_item_append_text(point_item
, ", Value: %g", al_valdbl
);
3013 proto_tree_add_item(point_tree
, hf_dnp3_al_anadbl
, tvb
, data_pos
, 8, ENC_LITTLE_ENDIAN
);
3021 case AL_OBJ_AIC_32T
:
3022 case AL_OBJ_AIC_16T
:
3023 case AL_OBJ_AIC_FLTT
:
3024 case AL_OBJ_AIC_DBLT
:
3025 case AL_OBJ_AIFC_32T
:
3026 case AL_OBJ_AIFC_16T
:
3027 case AL_OBJ_AIFC_FLTT
:
3028 case AL_OBJ_AIFC_DBLT
:
3030 dnp3_al_get_timestamp(&al_abstime
, tvb
, data_pos
);
3031 proto_item_append_text(point_item
, ", Timestamp: %s", abs_time_to_str(pinfo
->pool
, &al_abstime
, ABSOLUTE_TIME_UTC
, false));
3032 proto_tree_add_time(point_tree
, hf_dnp3_al_timestamp
, tvb
, data_pos
, 6, &al_abstime
);
3036 case AL_OBJ_AIFC_32TOF
:
3037 case AL_OBJ_AIFC_16TOF
:
3039 dnp3_al_get_timestamp(&al_abstime
, tvb
, data_pos
);
3040 proto_item_append_text(point_item
, ", Time of Freeze: %s", abs_time_to_str(pinfo
->pool
, &al_abstime
, ABSOLUTE_TIME_UTC
, false));
3041 proto_tree_add_time(point_tree
, hf_dnp3_al_timestamp
, tvb
, data_pos
, 6, &al_abstime
);
3046 proto_item_set_len(point_item
, data_pos
- offset
);
3051 case AL_OBJ_AO_32
: /* 32-Bit Analog Output Status (Obj:40, Var:01) */
3052 case AL_OBJ_AO_16
: /* 16-Bit Analog Output Status (Obj:40, Var:02) */
3053 case AL_OBJ_AO_FLT
: /* 32-Bit Floating Point Output Status (Obj:40, Var:03) */
3054 case AL_OBJ_AO_DBL
: /* 64-Bit Floating Point Output Status (Obj:40, Var:04) */
3055 case AL_OBJ_AOC_32NT
: /* 32-Bit Analog Output Event w/o Time (Obj:42, Var:01) */
3056 case AL_OBJ_AOC_16NT
: /* 16-Bit Analog Output Event w/o Time (Obj:42, Var:02) */
3057 case AL_OBJ_AOC_32T
: /* 32-Bit Analog Output Event with Time (Obj:42, Var:03) */
3058 case AL_OBJ_AOC_16T
: /* 16-Bit Analog Output Event with Time (Obj:42, Var:04) */
3059 case AL_OBJ_AOC_FLTNT
: /* 32-Bit Floating Point Output Event w/o Time (Obj:42, Var:05) */
3060 case AL_OBJ_AOC_DBLNT
: /* 64-Bit Floating Point Output Event w/o Time (Obj:42, Var:06) */
3061 case AL_OBJ_AOC_FLTT
: /* 32-Bit Floating Point Output Event w/ Time (Obj:42, Var:07) */
3062 case AL_OBJ_AOC_DBLT
: /* 64-Bit Floating Point Output Event w/ Time (Obj:42, Var:08) */
3064 /* Get Point Flags */
3065 al_ptflags
= tvb_get_uint8(tvb
, data_pos
);
3066 dnp3_al_obj_quality(tvb
, data_pos
, al_ptflags
, point_tree
, point_item
, ANA_OUT
);
3071 case AL_OBJ_AO_32
: /* 32-Bit Analog Output Status (Obj:40, Var:01) */
3072 case AL_OBJ_AOC_32NT
: /* 32-Bit Analog Output Event w/o Time (Obj:42, Var:01) */
3073 case AL_OBJ_AOC_32T
: /* 32-Bit Analog Output Event with Time (Obj:42, Var:03) */
3075 al_val_int32
= tvb_get_letohl(tvb
, data_pos
);
3076 proto_item_append_text(point_item
, ", Value: %d", al_val_int32
);
3077 proto_tree_add_item(point_tree
, hf_dnp3_al_anaout32
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3081 case AL_OBJ_AO_16
: /* 16-Bit Analog Output Status (Obj:40, Var:02) */
3082 case AL_OBJ_AOC_16NT
: /* 16-Bit Analog Output Event w/o Time (Obj:42, Var:02) */
3083 case AL_OBJ_AOC_16T
: /* 16-Bit Analog Output Event with Time (Obj:42, Var:04) */
3085 al_val_int16
= tvb_get_letohs(tvb
, data_pos
);
3086 proto_item_append_text(point_item
, ", Value: %d", al_val_int16
);
3087 proto_tree_add_item(point_tree
, hf_dnp3_al_anaout16
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3091 case AL_OBJ_AO_FLT
: /* 32-Bit Floating Point Output Status (Obj:40, Var:03) */
3092 case AL_OBJ_AOC_FLTNT
: /* 32-Bit Floating Point Output Event w/o Time (Obj:42, Var:05) */
3093 case AL_OBJ_AOC_FLTT
: /* 32-Bit Floating Point Output Event w/ Time (Obj:42, Var:07) */
3095 al_valflt
= tvb_get_letohieee_float(tvb
, data_pos
);
3096 proto_item_append_text(point_item
, ", Value: %g", al_valflt
);
3097 proto_tree_add_item(point_tree
, hf_dnp3_al_anaoutflt
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3101 case AL_OBJ_AO_DBL
: /* 64-Bit Floating Point Output Status (Obj:40, Var:04) */
3102 case AL_OBJ_AOC_DBLNT
: /* 64-Bit Floating Point Output Event w/o Time (Obj:42, Var:06) */
3103 case AL_OBJ_AOC_DBLT
: /* 64-Bit Floating Point Output Event w/ Time (Obj:42, Var:08) */
3105 al_valdbl
= tvb_get_letohieee_double(tvb
, data_pos
);
3106 proto_item_append_text(point_item
, ", Value: %g", al_valdbl
);
3107 proto_tree_add_item(point_tree
, hf_dnp3_al_anaoutdbl
, tvb
, data_pos
, 8, ENC_LITTLE_ENDIAN
);
3115 case AL_OBJ_AOC_32T
:
3116 case AL_OBJ_AOC_16T
:
3117 case AL_OBJ_AOC_FLTT
:
3118 case AL_OBJ_AOC_DBLT
:
3119 dnp3_al_get_timestamp(&al_abstime
, tvb
, data_pos
);
3120 proto_item_append_text(point_item
, ", Timestamp: %s", abs_time_to_str(pinfo
->pool
, &al_abstime
, ABSOLUTE_TIME_UTC
, false));
3121 proto_tree_add_time(point_tree
, hf_dnp3_al_timestamp
, tvb
, data_pos
, 6, &al_abstime
);
3126 proto_item_set_len(point_item
, data_pos
- offset
);
3130 case AL_OBJ_TD
: /* Time and Date (Obj:50, Var:01) */
3131 case AL_OBJ_TDR
: /* Time and Date at Last Recorded Time (Obj:50, Var:03) */
3132 case AL_OBJ_TDCTO
: /* Time and Date CTO (Obj:51, Var:01) */
3133 case AL_OBJ_UTDCTO
: /* Unsynchronized Time and Date CTO (Obj:51, Var:02) */
3135 dnp3_al_get_timestamp(&al_abstime
, tvb
, data_pos
);
3136 proto_tree_add_time(object_tree
, hf_dnp3_al_timestamp
, tvb
, data_pos
, 6, &al_abstime
);
3138 proto_item_set_len(point_item
, data_pos
- offset
);
3140 if (al_obj
== AL_OBJ_TDCTO
) {
3141 /* Copy the time object to the CTO for any other relative time objects in this response */
3142 nstime_copy(al_cto
, &al_abstime
);
3148 case AL_OBJ_TDELAYF
: /* Time Delay - Fine (Obj:52, Var:02) */
3150 proto_tree_add_item(object_tree
, hf_dnp3_al_time_delay
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3152 proto_item_set_len(point_item
, data_pos
- offset
);
3157 case AL_OBJ_FILE_CMD
: /* File Control - File Command (Obj:70, Var:03) */
3158 /* File name offset and length */
3159 proto_tree_add_item(point_tree
, hf_dnp3_al_file_string_offset
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3161 al_filename_len
= tvb_get_letohs(tvb
, data_pos
);
3162 proto_tree_add_item(point_tree
, hf_dnp3_al_file_string_length
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3165 /* Grab the mode as it determines if some of the following fields are relevant */
3166 al_file_ctrl_mode
= tvb_get_letohs(tvb
, data_pos
+ 16);
3169 if (al_file_ctrl_mode
== AL_OBJ_FILE_MODE_WRITE
) {
3170 dnp3_al_get_timestamp(&al_abstime
, tvb
, data_pos
);
3171 proto_tree_add_time(point_tree
, hf_dnp3_al_timestamp
, tvb
, data_pos
, 6, &al_abstime
);
3176 if (al_file_ctrl_mode
== AL_OBJ_FILE_MODE_WRITE
) {
3177 proto_item
*perms_item
;
3178 proto_tree
*perms_tree
;
3180 perms_item
= proto_tree_add_item(point_tree
, hf_dnp3_al_file_perms
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3182 perms_tree
= proto_item_add_subtree(perms_item
, ett_dnp3_al_obj_point_perms
);
3183 proto_tree_add_item(perms_tree
, hf_dnp3_al_file_perms_read_owner
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3184 proto_tree_add_item(perms_tree
, hf_dnp3_al_file_perms_write_owner
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3185 proto_tree_add_item(perms_tree
, hf_dnp3_al_file_perms_exec_owner
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3186 proto_tree_add_item(perms_tree
, hf_dnp3_al_file_perms_read_group
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3187 proto_tree_add_item(perms_tree
, hf_dnp3_al_file_perms_write_group
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3188 proto_tree_add_item(perms_tree
, hf_dnp3_al_file_perms_exec_group
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3189 proto_tree_add_item(perms_tree
, hf_dnp3_al_file_perms_read_world
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3190 proto_tree_add_item(perms_tree
, hf_dnp3_al_file_perms_write_world
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3191 proto_tree_add_item(perms_tree
, hf_dnp3_al_file_perms_exec_world
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3196 proto_tree_add_item(point_tree
, hf_dnp3_al_file_auth
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3200 if (al_file_ctrl_mode
== AL_OBJ_FILE_MODE_WRITE
|| al_file_ctrl_mode
== AL_OBJ_FILE_MODE_APPEND
) {
3201 proto_tree_add_item(point_tree
, hf_dnp3_al_file_size
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3203 data_pos
+= 4; //-V525
3206 proto_tree_add_item(point_tree
, hf_dnp3_al_file_mode
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3209 /* Max Block Size */
3210 proto_tree_add_item(point_tree
, hf_dnp3_al_file_maxblk
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3214 proto_tree_add_item(point_tree
, hf_dnp3_al_file_reqID
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3218 if (al_filename_len
> 0) {
3219 proto_tree_add_item(point_tree
, hf_dnp3_al_file_name
, tvb
, data_pos
, al_filename_len
, ENC_ASCII
);
3221 data_pos
+= al_filename_len
;
3222 proto_item_set_len(point_item
, data_pos
- offset
);
3227 case AL_OBJ_FILE_STAT
: /* File Control - File Status (Obj:70, Var:04) */
3230 proto_tree_add_item(point_tree
, hf_dnp3_al_file_handle
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3234 proto_tree_add_item(point_tree
, hf_dnp3_al_file_size
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3237 /* Max Block Size */
3238 proto_tree_add_item(point_tree
, hf_dnp3_al_file_maxblk
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3242 proto_tree_add_item(point_tree
, hf_dnp3_al_file_reqID
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3246 proto_tree_add_item(point_tree
, hf_dnp3_al_file_status
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
3250 file_data_size
= al_ptaddr
- (data_pos
- offset
- prefixbytes
);
3251 if ((file_data_size
) > 0) {
3252 proto_tree_add_item(point_tree
, hf_dnp3_al_file_data
, tvb
, data_pos
, file_data_size
, ENC_NA
);
3253 data_pos
+= file_data_size
;
3256 proto_item_set_len(point_item
, data_pos
- offset
);
3261 case AL_OBJ_FILE_TRANS
: /* File Control - File Transport (Obj:70, Var:05) */
3264 proto_tree_add_item(point_tree
, hf_dnp3_al_file_handle
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3267 /* File block (bits 0 - 30) and last block flag (bit 31) */
3268 proto_tree_add_item(point_tree
, hf_dnp3_al_file_blocknum
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3269 proto_tree_add_item(point_tree
, hf_dnp3_al_file_lastblock
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3273 file_data_size
= al_ptaddr
- (data_pos
- offset
- prefixbytes
);
3274 if ((file_data_size
) > 0) {
3275 proto_tree_add_item(point_tree
, hf_dnp3_al_file_data
, tvb
, data_pos
, file_data_size
, ENC_NA
);
3276 data_pos
+= file_data_size
;
3279 proto_item_set_len(point_item
, data_pos
- offset
);
3284 case AL_OBJ_FILE_TRAN_ST
: /* File Control Tansport Status (Obj:70, Var:06) */
3287 proto_tree_add_item(point_tree
, hf_dnp3_al_file_handle
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3290 /* File block (bits 0 - 30) and last block flag (bit 31) */
3291 proto_tree_add_item(point_tree
, hf_dnp3_al_file_blocknum
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3292 proto_tree_add_item(point_tree
, hf_dnp3_al_file_lastblock
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3296 proto_tree_add_item(point_tree
, hf_dnp3_al_file_status
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
3300 file_data_size
= al_ptaddr
- (data_pos
- offset
- prefixbytes
);
3301 if ((file_data_size
) > 0) {
3302 proto_tree_add_item(point_tree
, hf_dnp3_al_file_data
, tvb
, data_pos
, file_data_size
, ENC_NA
);
3303 data_pos
+= file_data_size
;
3306 proto_item_set_len(point_item
, data_pos
- offset
);
3311 case AL_OBJ_OCT
: /* Octet string */
3312 case AL_OBJ_OCT_EVT
: /* Octet string event */
3314 /* read the number of bytes defined by the variation */
3315 if (al_oct_len
> 0) {
3316 proto_tree_add_item(object_tree
, hf_dnp3_al_octet_string
, tvb
, data_pos
, al_oct_len
, ENC_NA
);
3317 data_pos
+= al_oct_len
;
3318 proto_item_set_len(point_item
, data_pos
- offset
);
3324 case AL_OBJ_SA_AUTH_CH
: /* Authentication Challenge (Obj:120, Var:01) */
3326 /* Challenge Sequence Number */
3327 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_csq
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3331 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_usr
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3335 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_mal
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
3338 /* Reason for Challenge */
3339 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_rfc
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
3342 /* Challenge Data */
3343 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_cd
, tvb
, data_pos
, (al_ptaddr
-8), ENC_NA
);
3344 data_pos
+= (al_ptaddr
-8);
3349 case AL_OBJ_SA_AUTH_RP
: /* Authentication Reply (Obj:120, Var:02) */
3351 /* Challenge Sequence Number */
3352 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_csq
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3356 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_usr
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3360 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_mac
, tvb
, data_pos
, (al_ptaddr
-6), ENC_NA
);
3361 data_pos
+= (al_ptaddr
-6);
3366 case AL_OBJ_SA_AUTH_AGMRQ
: /* Authentication Aggressive Mode Request (Obj:120, Var:03) */
3368 /* Challenge Sequence Number */
3369 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_csq
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3373 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_usr
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3379 case AL_OBJ_SA_AUTH_SKSR
: /* Authentication Session Key Status Request (Obj:120, Var:04) */
3382 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_usr
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3388 case AL_OBJ_SA_AUTH_SKS
: /* Authentication Session Key Status (Obj:120, Var:05) */
3390 /* Key Change Sequence Number */
3391 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_ksq
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3395 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_usr
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3398 /* Key Wrap Algorithm */
3399 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_kwa
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
3403 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_ks
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
3407 /* Use the MAC Algorithm to determine the length of the MAC Value */
3408 temp
= tvb_get_uint8(tvb
, data_pos
);
3430 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_mal
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
3433 /* Challenge Data Length */
3434 al_val_uint16
= tvb_get_letohs(tvb
, data_pos
);
3435 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_cdl
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3438 /* Challenge Data */
3439 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_cd
, tvb
, data_pos
, al_val_uint16
, ENC_NA
);
3440 data_pos
+= al_val_uint16
;
3443 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_mac
, tvb
, data_pos
, al_sa_mac_len
, ENC_NA
);
3444 data_pos
+= al_sa_mac_len
;
3449 case AL_OBJ_SA_AUTH_SKC
: /* Authentication Session Key Change (Obj:120, Var:06) */
3451 /* Key Change Sequence Number */
3452 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_ksq
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3456 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_usr
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3460 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_key
, tvb
, data_pos
, (al_ptaddr
-6), ENC_NA
);
3461 data_pos
+= (al_ptaddr
-6);
3466 case AL_OBJ_SA_AUTH_ERR
: /* Authentication Error (Obj:120, Var:07) */
3468 /* Sequence Number - Can be Challenge or Key Change */
3469 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_seq
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3473 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_usr
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3476 /* Association ID */
3477 proto_tree_add_item(point_tree
, hf_dnp3_al_sa_assoc_id
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3481 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_err
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
3484 /* Error Timestamp */
3485 dnp3_al_get_timestamp(&al_abstime
, tvb
, data_pos
);
3486 proto_tree_add_time(object_tree
, hf_dnp3_al_timestamp
, tvb
, data_pos
, 6, &al_abstime
);
3490 /* Optional footer for any remaining data */
3496 case AL_OBJ_SA_AUTH_MAC
: /* Authentication Message Authentication Code (Obj:120, Var:09) */
3497 case AL_OBJ_SA_AUTH_UKCC
: /* Authentication Update Key Change Confirmation (Obj:120, Var:15) */
3500 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_mac
, tvb
, data_pos
, al_ptaddr
, ENC_NA
);
3501 data_pos
+= al_ptaddr
;
3506 case AL_OBJ_SA_AUTH_UKCR
: /* Authentication Update Key Change Request (Obj:120, Var:11) */
3508 /* Key Change Method */
3509 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_kcm
, tvb
, data_pos
, 1, ENC_LITTLE_ENDIAN
);
3512 /* User Name Length */
3513 sa_username_len
= tvb_get_letohs(tvb
, data_pos
);
3514 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_usrnl
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3517 /* Challenge Data Length */
3518 sa_challengedata_len
= tvb_get_letohs(tvb
, data_pos
);
3519 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_cdl
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3523 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_usrn
, tvb
, data_pos
, sa_username_len
, ENC_ASCII
);
3524 data_pos
+= sa_username_len
;
3526 /* Challenge Data */
3527 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_cd
, tvb
, data_pos
, sa_challengedata_len
, ENC_NA
);
3528 data_pos
+= sa_challengedata_len
;
3533 case AL_OBJ_SA_AUTH_UKCRP
: /* Authentication Update Key Change Reply (Obj:120, Var:12) */
3535 /* Sequence Number - Can be Challenge or Key Change */
3536 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_seq
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3540 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_usr
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3543 /* Challenge Data Length */
3544 sa_challengedata_len
= tvb_get_letohs(tvb
, data_pos
);
3545 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_cdl
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3548 /* Challenge Data */
3549 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_cd
, tvb
, data_pos
, sa_challengedata_len
, ENC_NA
);
3550 data_pos
+= sa_challengedata_len
;
3555 case AL_OBJ_SA_AUTH_UKC
: /* Authentication Update Key Change (Obj:120, Var:13) */
3557 /* Sequence Number - Can be Challenge or Key Change */
3558 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_seq
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3562 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_usr
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3565 /* Encrypted Update Key Length */
3566 sa_updatekey_len
= tvb_get_letohs(tvb
, data_pos
);
3567 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_ukl
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3570 /* Encrypted Update Key Data */
3571 proto_tree_add_item(object_tree
, hf_dnp3_al_sa_uk
, tvb
, data_pos
, sa_updatekey_len
, ENC_NA
);
3572 data_pos
+= sa_updatekey_len
;
3577 case AL_OBJ_SA_SECSTAT
: /* Security Statistics (Obj:121, Var:01) */
3578 case AL_OBJ_SA_SECSTATEVT
: /* Security Statistic Event (Obj:122, Var:01) */
3579 case AL_OBJ_SA_SECSTATEVTT
: /* Security Statistic Event w/ Time (Obj:122, Var:02) */
3581 /* Security Statistic Description */
3582 sec_stat_str
= val_to_str_ext(al_ptaddr
, &dnp3_al_sa_secstat_vals_ext
, "Unknown statistic (%u)");
3583 proto_item_append_text(point_item
, " %s", sec_stat_str
);
3586 al_ptflags
= tvb_get_uint8(tvb
, data_pos
);
3587 dnp3_al_obj_quality(tvb
, data_pos
, al_ptflags
, point_tree
, point_item
, COUNTER
);
3590 /* Association ID */
3591 al_val_uint16
= tvb_get_letohs(tvb
, data_pos
);
3592 proto_item_append_text(point_item
, ", Association ID: %u", al_val_uint16
);
3593 proto_tree_add_item(point_tree
, hf_dnp3_al_sa_assoc_id
, tvb
, data_pos
, 2, ENC_LITTLE_ENDIAN
);
3596 /* 32-bit Count Value */
3597 al_val_uint32
= tvb_get_letohl(tvb
, data_pos
);
3598 proto_item_append_text(point_item
, ", Count: %u", al_val_uint32
);
3599 proto_tree_add_item(point_tree
, hf_dnp3_al_cnt32
, tvb
, data_pos
, 4, ENC_LITTLE_ENDIAN
);
3602 if (al_obj
== AL_OBJ_SA_SECSTATEVTT
) {
3603 dnp3_al_get_timestamp(&al_abstime
, tvb
, data_pos
);
3604 proto_item_append_text(point_item
, ", Timestamp: %s", abs_time_to_str(pinfo
->pool
, &al_abstime
, ABSOLUTE_TIME_UTC
, false));
3605 proto_tree_add_time(point_tree
, hf_dnp3_al_timestamp
, tvb
, data_pos
, 6, &al_abstime
);
3612 default: /* In case of unknown object */
3614 proto_tree_add_item(object_tree
, hf_dnp3_unknown_data_chunk
, tvb
, offset
, -1, ENC_NA
);
3615 offset
= tvb_captured_length(tvb
); /* Finish decoding if unknown object is encountered... */
3620 /* And increment the point address, may be overwritten by an index value */
3624 /* No objects, just prefixes, move past prefix values */
3627 if (start_offset
> offset
) {
3628 expert_add_info(pinfo
, point_item
, &ei_dnp_invalid_length
);
3629 offset
= tvb_captured_length(tvb
); /* Finish decoding if unknown object is encountered... */
3633 proto_item_set_len(object_item
, offset
- orig_offset
);
3638 /*****************************************************************/
3639 /* Application Layer Dissector */
3640 /*****************************************************************/
3642 dissect_dnp3_al(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
3644 uint8_t al_ctl
, al_seq
, al_func
, al_class
= 0, i
;
3645 uint16_t bytes
, obj_type
= 0;
3646 unsigned data_len
= 0, offset
= 0;
3647 proto_item
*ti
, *tc
;
3648 proto_tree
*al_tree
, *robj_tree
;
3649 const char *func_code_str
, *obj_type_str
;
3651 static int * const control_flags
[] = {
3660 nstime_set_zero (&al_cto
);
3662 data_len
= tvb_captured_length(tvb
);
3664 /* Handle the control byte and function code */
3665 al_ctl
= tvb_get_uint8(tvb
, offset
);
3666 al_seq
= al_ctl
& DNP3_AL_SEQ
;
3667 al_func
= tvb_get_uint8(tvb
, (offset
+1));
3668 func_code_str
= val_to_str_ext(al_func
, &dnp3_al_func_vals_ext
, "Unknown function (0x%02x)");
3670 /* Clear out lower layer info */
3671 col_clear(pinfo
->cinfo
, COL_INFO
);
3672 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
, func_code_str
);
3673 col_set_fence(pinfo
->cinfo
, COL_INFO
);
3675 /* format up the text representation */
3676 al_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, data_len
, ett_dnp3_al
, &ti
, "Application Layer: (");
3677 if (al_ctl
& DNP3_AL_FIR
) proto_item_append_text(ti
, "FIR, ");
3678 if (al_ctl
& DNP3_AL_FIN
) proto_item_append_text(ti
, "FIN, ");
3679 if (al_ctl
& DNP3_AL_CON
) proto_item_append_text(ti
, "CON, ");
3680 if (al_ctl
& DNP3_AL_UNS
) proto_item_append_text(ti
, "UNS, ");
3681 proto_item_append_text(ti
, "Sequence %u, %s)", al_seq
, func_code_str
);
3683 /* Application Layer control byte subtree */
3684 tc
= proto_tree_add_bitmask(al_tree
, tvb
, offset
, hf_dnp3_al_ctl
, ett_dnp3_al_ctl
, control_flags
, ENC_BIG_ENDIAN
);
3685 proto_item_append_text(tc
, "(");
3686 if (al_ctl
& DNP3_AL_FIR
) proto_item_append_text(tc
, "FIR, ");
3687 if (al_ctl
& DNP3_AL_FIN
) proto_item_append_text(tc
, "FIN, ");
3688 if (al_ctl
& DNP3_AL_CON
) proto_item_append_text(tc
, "CON, ");
3689 if (al_ctl
& DNP3_AL_UNS
) proto_item_append_text(tc
, "UNS, ");
3690 proto_item_append_text(tc
, "Sequence %u)", al_seq
);
3694 /* If this packet is NOT the final Application Layer Message, exit and continue
3695 processing the remaining data in the fragment. */
3696 if (!(al_ctl
& DNP3_AL_FIN
)) {
3697 t_robj
= proto_tree_add_expert(al_tree
, pinfo
, &ei_dnp3_buffering_user_data_until_final_frame_is_received
, tvb
, offset
, -1);
3702 /* Application Layer Function Code Byte */
3703 proto_tree_add_uint_format(al_tree
, hf_dnp3_al_func
, tvb
, offset
, 1, al_func
,
3704 "Function Code: %s (0x%02x)", func_code_str
, al_func
);
3709 case AL_FUNC_CONFIRM
: /* Confirm Function Code 0x00 */
3711 /* If the application layer data is longer than two bytes in length it may have SA objects appended to it */
3714 /* Create Confirm Data Objects Tree */
3715 robj_tree
= proto_tree_add_subtree(al_tree
, tvb
, offset
, -1, ett_dnp3_al_objdet
, NULL
, "CONFIRM Data Objects");
3717 /* Process Data Object Details */
3718 while (offset
<= (data_len
-2)) { /* 2 octet object code + CRC32 */
3719 offset
= dnp3_al_process_object(tvb
, pinfo
, offset
, robj_tree
, true, &obj_type
, &al_cto
);
3724 case AL_FUNC_READ
: /* Read Function Code 0x01 */
3726 /* Create Read Request Data Objects Tree */
3727 robj_tree
= proto_tree_add_subtree(al_tree
, tvb
, offset
, -1, ett_dnp3_al_objdet
, NULL
, "READ Request Data Objects");
3729 /* Process Data Object Details */
3730 while (offset
<= (data_len
-2)) { /* 2 octet object code + CRC32 */
3731 offset
= dnp3_al_process_object(tvb
, pinfo
, offset
, robj_tree
, true, &obj_type
, &al_cto
);
3733 /* Update class type for each object that was a class read */
3739 al_class
|= (1 << ((obj_type
& 0x0f) - 1));
3742 /* For reads for specific object types, bit-mask out the first byte and add the generic obj description to the column info */
3743 obj_type_str
= val_to_str_ext_const((obj_type
& 0xFF00), &dnp3_al_read_obj_vals_ext
, "Unknown Object Type");
3744 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
, obj_type_str
);
3750 /* Update the col info if there were class reads */
3751 if (al_class
!= 0) {
3752 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
, "Class ");
3753 for (i
= 0; i
< 4; i
++) {
3754 if (al_class
& (1 << i
)) {
3755 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%u", i
);
3762 case AL_FUNC_WRITE
: /* Write Function Code 0x02 */
3764 /* Create Write Request Data Objects Tree */
3765 robj_tree
= proto_tree_add_subtree(al_tree
, tvb
, offset
, -1, ett_dnp3_al_objdet
, NULL
, "WRITE Request Data Objects");
3767 /* Process Data Object Details */
3768 while (offset
<= (data_len
-2)) { /* 2 octet object code + CRC32 */
3769 offset
= dnp3_al_process_object(tvb
, pinfo
, offset
, robj_tree
, false, &obj_type
, &al_cto
);
3771 /* For writes for specific object types, bit-mask out the first byte and add the generic obj description to the column info */
3772 obj_type_str
= val_to_str_ext_const((obj_type
& 0xFF00), &dnp3_al_write_obj_vals_ext
, "Unknown Object Type");
3773 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
, obj_type_str
);
3779 case AL_FUNC_SELECT
: /* Select Function Code 0x03 */
3781 /* Create Select Request Data Objects Tree */
3782 robj_tree
= proto_tree_add_subtree(al_tree
, tvb
, offset
, -1, ett_dnp3_al_objdet
, NULL
, "SELECT Request Data Objects");
3784 /* Process Data Object Details */
3785 while (offset
<= (data_len
-2)) { /* 2 octet object code + CRC32 */
3786 offset
= dnp3_al_process_object(tvb
, pinfo
, offset
, robj_tree
, false, &obj_type
, &al_cto
);
3791 case AL_FUNC_OPERATE
: /* Operate Function Code 0x04 */
3792 /* Functionally identical to 'SELECT' Function Code */
3794 /* Create Operate Request Data Objects Tree */
3795 robj_tree
= proto_tree_add_subtree(al_tree
, tvb
, offset
, -1, ett_dnp3_al_objdet
, NULL
, "OPERATE Request Data Objects");
3797 /* Process Data Object Details */
3798 while (offset
<= (data_len
-2)) { /* 2 octet object code + CRC32 */
3799 offset
= dnp3_al_process_object(tvb
, pinfo
, offset
, robj_tree
, false, &obj_type
, &al_cto
);
3804 case AL_FUNC_DIROP
: /* Direct Operate Function Code 0x05 */
3805 case AL_FUNC_DIROPNACK
: /* Direct Operate No ACK Function Code 0x06 */
3806 /* Functionally identical to 'SELECT' Function Code */
3808 /* Create Direct Operate Request Data Objects Tree */
3809 robj_tree
= proto_tree_add_subtree(al_tree
, tvb
, offset
, -1, ett_dnp3_al_objdet
, NULL
, "DIRECT OPERATE Request Data Objects");
3811 /* Process Data Object Details */
3812 while (offset
<= (data_len
-2)) { /* 2 octet object code + CRC32 */
3813 offset
= dnp3_al_process_object(tvb
, pinfo
, offset
, robj_tree
, false, &obj_type
, &al_cto
);
3818 case AL_FUNC_FRZ
: /* Immediate Freeze Function Code 0x07 */
3819 case AL_FUNC_FRZNACK
: /* Immediate Freeze No ACK Function Code 0x08 */
3820 case AL_FUNC_FRZCLR
: /* Freeze and Clear Function Code 0x09 */
3821 case AL_FUNC_FRZCLRNACK
: /* Freeze and Clear No ACK Function Code 0x0A */
3823 /* Create Freeze Request Data Objects Tree */
3824 robj_tree
= proto_tree_add_subtree(al_tree
, tvb
, offset
, -1, ett_dnp3_al_objdet
, NULL
, "Freeze Request Data Objects");
3826 /* Process Data Object Details */
3827 while (offset
<= (data_len
-2)) { /* 2 octet object code + CRC32 */
3828 offset
= dnp3_al_process_object(tvb
, pinfo
, offset
, robj_tree
, true, &obj_type
, &al_cto
);
3833 case AL_FUNC_ENSPMSG
: /* Enable Spontaneous Messages Function Code 0x14 */
3835 /* Create Enable Spontaneous Messages Data Objects Tree */
3836 robj_tree
= proto_tree_add_subtree(al_tree
, tvb
, offset
, -1, ett_dnp3_al_objdet
, NULL
, "Enable Spontaneous Msg's Data Objects");
3838 /* Process Data Object Details */
3839 while (offset
<= (data_len
-2)) { /* 2 octet object code + CRC32 */
3840 offset
= dnp3_al_process_object(tvb
, pinfo
, offset
, robj_tree
, false, &obj_type
, &al_cto
);
3845 case AL_FUNC_DISSPMSG
: /* Disable Spontaneous Messages Function Code 0x15 */
3847 /* Create Disable Spontaneous Messages Data Objects Tree */
3848 robj_tree
= proto_tree_add_subtree(al_tree
, tvb
, offset
, -1, ett_dnp3_al_objdet
, NULL
, "Disable Spontaneous Msg's Data Objects");
3850 /* Process Data Object Details */
3851 while (offset
<= (data_len
-2)) { /* 2 octet object code + CRC32 */
3852 offset
= dnp3_al_process_object(tvb
, pinfo
, offset
, robj_tree
, false, &obj_type
, &al_cto
);
3857 case AL_FUNC_DELAYMST
: /* Delay Measurement Function Code 0x17 */
3861 case AL_FUNC_OPENFILE
: /* Open File Function Code 0x19 */
3862 case AL_FUNC_CLOSEFILE
: /* Close File Function Code 0x1A */
3863 case AL_FUNC_DELETEFILE
: /* Delete File Function Code 0x1B */
3865 /* Create File Data Objects Tree */
3866 robj_tree
= proto_tree_add_subtree(al_tree
, tvb
, offset
, -1, ett_dnp3_al_objdet
, NULL
, "File Data Objects");
3868 /* Process Data Object Details */
3869 while (offset
<= (data_len
-2)) { /* 2 octet object code + CRC32 */
3870 offset
= dnp3_al_process_object(tvb
, pinfo
, offset
, robj_tree
, false, &obj_type
, &al_cto
);
3875 case AL_FUNC_AUTHREQ
: /* Authentication Request Function Code 0x20 */
3876 case AL_FUNC_AUTHERR
: /* Authentication Error Function Code 0x21 */
3879 /* Create Authentication Request Data Objects Tree */
3880 robj_tree
= proto_tree_add_subtree(al_tree
, tvb
, offset
, -1, ett_dnp3_al_objdet
, NULL
, "Authentication Request Data Objects");
3882 /* Process Data Object Details */
3883 while (offset
<= (data_len
-2)) { /* 2 octet object code + CRC32 */
3884 offset
= dnp3_al_process_object(tvb
, pinfo
, offset
, robj_tree
, false, &obj_type
, &al_cto
);
3889 case AL_FUNC_RESPON
: /* Response Function Code 0x81 */
3890 case AL_FUNC_UNSOLI
: /* Unsolicited Response Function Code 0x82 */
3891 case AL_FUNC_AUTHRESP
: /* Authentication Response Function Code 0x83 */
3893 /* Application Layer IIN bits req'd if message is a response */
3894 dnp3_al_process_iin(tvb
, pinfo
, offset
, al_tree
);
3897 /* Ensure there is actual data remaining in the message.
3898 A response will not contain data following the IIN bits,
3899 if there is none available */
3900 bytes
= tvb_reported_length_remaining(tvb
, offset
);
3903 /* Create Response Data Objects Tree */
3904 robj_tree
= proto_tree_add_subtree(al_tree
, tvb
, offset
, -1, ett_dnp3_al_objdet
, NULL
, "RESPONSE Data Objects");
3906 /* Process Data Object Details */
3907 while (offset
<= (data_len
-2)) { /* 2 octet object code + CRC32 */
3908 offset
= dnp3_al_process_object(tvb
, pinfo
, offset
, robj_tree
, false, &obj_type
, &al_cto
);
3914 default: /* Unknown Function */
3922 /*****************************************************************/
3923 /* Data Link and Transport layer dissector */
3924 /*****************************************************************/
3926 dissect_dnp3_message(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
3928 proto_item
*ti
, *tdl
, *tc
, *hidden_item
;
3929 proto_tree
*dnp3_tree
, *dl_tree
, *field_tree
;
3930 int offset
= 0, temp_offset
= 0;
3932 uint8_t dl_len
, dl_ctl
, dl_func
;
3933 const char *func_code_str
;
3934 uint16_t dl_dst
, dl_src
, calc_dl_crc
;
3936 /* Make entries in Protocol column and Info column on summary display */
3937 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "DNP 3.0");
3938 col_clear(pinfo
->cinfo
, COL_INFO
);
3940 /* Skip "0x0564" header bytes */
3943 dl_len
= tvb_get_uint8(tvb
, temp_offset
);
3946 dl_ctl
= tvb_get_uint8(tvb
, temp_offset
);
3949 dl_dst
= tvb_get_letohs(tvb
, temp_offset
);
3952 dl_src
= tvb_get_letohs(tvb
, temp_offset
);
3954 dl_func
= dl_ctl
& DNP3_CTL_FUNC
;
3955 dl_prm
= dl_ctl
& DNP3_CTL_PRM
;
3956 func_code_str
= val_to_str(dl_func
, dl_prm
? dnp3_ctl_func_pri_vals
: dnp3_ctl_func_sec_vals
,
3957 "Unknown function (0x%02x)");
3959 /* Make sure source and dest are always in the info column. This might not
3960 * be the first DL segment (PDU) in the frame so add a separator. */
3961 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, "; ", "%u " UTF8_RIGHTWARDS_ARROW
" %u", dl_src
, dl_dst
);
3962 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
, "len=%u, %s", dl_len
, func_code_str
);
3964 /* create display subtree for the protocol */
3965 ti
= proto_tree_add_item(tree
, proto_dnp3
, tvb
, offset
, -1, ENC_NA
);
3966 dnp3_tree
= proto_item_add_subtree(ti
, ett_dnp3
);
3968 /* Create Subtree for Data Link Layer */
3969 dl_tree
= proto_tree_add_subtree_format(dnp3_tree
, tvb
, offset
, DNP_HDR_LEN
, ett_dnp3_dl
, &tdl
,
3970 "Data Link Layer, Len: %u, From: %u, To: %u, ", dl_len
, dl_src
, dl_dst
);
3972 if (dl_ctl
& DNP3_CTL_DIR
) proto_item_append_text(tdl
, "DIR, ");
3973 if (dl_ctl
& DNP3_CTL_PRM
) proto_item_append_text(tdl
, "PRM, ");
3974 if (dl_ctl
& DNP3_CTL_FCB
) proto_item_append_text(tdl
, "FCB, ");
3975 if (dl_ctl
& DNP3_CTL_FCV
) proto_item_append_text(tdl
, "FCV, ");
3978 if (dl_ctl
& DNP3_CTL_DIR
) proto_item_append_text(tdl
, "DIR, ");
3979 if (dl_ctl
& DNP3_CTL_PRM
) proto_item_append_text(tdl
, "PRM, ");
3980 if (dl_ctl
& DNP3_CTL_RES
) proto_item_append_text(tdl
, "RES, ");
3981 if (dl_ctl
& DNP3_CTL_DFC
) proto_item_append_text(tdl
, "DFC, ");
3983 proto_item_append_text(tdl
, "%s", func_code_str
);
3986 proto_tree_add_item(dl_tree
, hf_dnp3_start
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3989 /* add length field */
3990 proto_tree_add_item(dl_tree
, hf_dnp3_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3993 /* Add Control Byte Subtree */
3994 tc
= proto_tree_add_uint_format_value(dl_tree
, hf_dnp3_ctl
, tvb
, offset
, 1, dl_ctl
,
3995 "0x%02x (", dl_ctl
);
3996 /* Add Text to Control Byte Subtree Header */
3998 if (dl_ctl
& DNP3_CTL_DIR
) proto_item_append_text(tc
, "DIR, ");
3999 if (dl_ctl
& DNP3_CTL_PRM
) proto_item_append_text(tc
, "PRM, ");
4000 if (dl_ctl
& DNP3_CTL_FCB
) proto_item_append_text(tc
, "FCB, ");
4001 if (dl_ctl
& DNP3_CTL_FCV
) proto_item_append_text(tc
, "FCV, ");
4004 if (dl_ctl
& DNP3_CTL_DIR
) proto_item_append_text(tc
, "DIR, ");
4005 if (dl_ctl
& DNP3_CTL_PRM
) proto_item_append_text(tc
, "PRM, ");
4006 if (dl_ctl
& DNP3_CTL_RES
) proto_item_append_text(tc
, "RES, ");
4007 if (dl_ctl
& DNP3_CTL_DFC
) proto_item_append_text(tc
, "DFC, ");
4009 proto_item_append_text(tc
, "%s)", func_code_str
);
4010 field_tree
= proto_item_add_subtree(tc
, ett_dnp3_dl_ctl
);
4012 /* Add Control Byte Subtree Items */
4014 proto_tree_add_item(field_tree
, hf_dnp3_ctl_dir
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4015 proto_tree_add_item(field_tree
, hf_dnp3_ctl_prm
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4016 proto_tree_add_item(field_tree
, hf_dnp3_ctl_fcb
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4017 proto_tree_add_item(field_tree
, hf_dnp3_ctl_fcv
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4018 proto_tree_add_item(field_tree
, hf_dnp3_ctl_prifunc
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4021 proto_tree_add_item(field_tree
, hf_dnp3_ctl_dir
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4022 proto_tree_add_item(field_tree
, hf_dnp3_ctl_prm
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4023 proto_tree_add_item(field_tree
, hf_dnp3_ctl_dfc
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4024 proto_tree_add_item(field_tree
, hf_dnp3_ctl_secfunc
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4028 /* add destination and source addresses */
4029 /* XXX - We could create AT_NUMERIC (or a newly registered address type)
4030 * addressses from these, either just for a conversation table or even
4031 * to set pinfo->src / dst. */
4032 proto_tree_add_item(dl_tree
, hf_dnp3_dst
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4033 hidden_item
= proto_tree_add_item(dl_tree
, hf_dnp3_addr
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4034 proto_item_set_hidden(hidden_item
);
4036 proto_tree_add_item(dl_tree
, hf_dnp3_src
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4037 hidden_item
= proto_tree_add_item(dl_tree
, hf_dnp3_addr
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4038 proto_item_set_hidden(hidden_item
);
4041 dnp3_packet_info_t
* dnp3_info
= wmem_new0(pinfo
->pool
, dnp3_packet_info_t
);
4042 dnp3_info
->dl_src
= dl_src
;
4043 dnp3_info
->dl_dst
= dl_dst
;
4044 dnp3_info
->msg_len
= dl_len
;
4046 tap_queue_packet(dnp3_tap
, pinfo
, dnp3_info
);
4048 /* and header CRC */
4049 calc_dl_crc
= calculateCRCtvb(tvb
, 0, DNP_HDR_LEN
- 2);
4050 proto_tree_add_checksum(dl_tree
, tvb
, offset
, hf_dnp3_data_hdr_crc
,
4051 hf_dnp3_data_hdr_crc_status
, &ei_dnp3_data_hdr_crc_incorrect
,
4052 pinfo
, calc_dl_crc
, ENC_LITTLE_ENDIAN
, PROTO_CHECKSUM_VERIFY
);
4055 /* If the DataLink function is 'Request Link Status' or 'Status of Link',
4056 or 'Reset Link' we don't expect any Transport or Application Layer Data
4057 NOTE: This code should probably check what DOES have TR or AL data */
4058 if ((dl_func
!= DL_FUNC_LINK_STAT
) && (dl_func
!= DL_FUNC_STAT_LINK
) &&
4059 (dl_func
!= DL_FUNC_RESET_LINK
) && (dl_func
!= DL_FUNC_ACK
)) //-V560 (both codes are the same value but semantically different)
4061 proto_tree
*data_tree
;
4062 proto_item
*data_ti
;
4063 uint8_t tr_ctl
, tr_seq
;
4064 bool tr_fir
, tr_fin
;
4065 uint8_t *al_buffer
, *al_buffer_ptr
;
4067 int data_start
= offset
;
4069 bool crc_OK
= false;
4072 static int * const transport_flags
[] = {
4079 /* get the transport layer byte */
4080 tr_ctl
= tvb_get_uint8(tvb
, offset
);
4081 tr_seq
= tr_ctl
& DNP3_TR_SEQ
;
4082 tr_fir
= tr_ctl
& DNP3_TR_FIR
;
4083 tr_fin
= tr_ctl
& DNP3_TR_FIN
;
4085 uint32_t ext_seq
= tr_seq
;
4087 if (!PINFO_FD_VISITED(pinfo
)) {
4088 /* create a unidirectional conversation. Use the addresses (IP currently)
4089 * as the reassembly functions use that anyway, and the DNP3.0 DL
4090 * addresses but intentionally NOT the TCP or UDP ports. */
4091 conversation_element_t
* conv_key
= wmem_alloc_array(pinfo
->pool
, conversation_element_t
, 5);
4092 conv_key
[0].type
= CE_ADDRESS
;
4093 copy_address_shallow(&(conv_key
[0].addr_val
), &pinfo
->src
);
4094 conv_key
[1].type
= CE_ADDRESS
;
4095 copy_address_shallow(&(conv_key
[1].addr_val
), &pinfo
->dst
);
4096 conv_key
[2].type
= CE_UINT
;
4097 conv_key
[2].port_val
= dl_src
;
4098 conv_key
[3].type
= CE_UINT
;
4099 conv_key
[3].uint_val
= dl_dst
;
4100 conv_key
[4].type
= CE_CONVERSATION_TYPE
;
4101 conv_key
[4].conversation_type_val
= CONVERSATION_DNP3
;
4102 conversation_t
* conv
= find_conversation_full(pinfo
->num
, conv_key
);
4105 prev
= GPOINTER_TO_UINT(conversation_get_proto_data(conv
, proto_dnp3
));
4108 conv
= conversation_new_full(pinfo
->num
, conv_key
);
4110 ext_seq
= calculate_extended_seqno(prev
, tr_seq
);
4111 /* The only thing we store right now is the 32 bit extended sequence
4112 * number, so we don't need a conversation_data type. */
4113 conversation_add_proto_data(conv
, proto_dnp3
, GUINT_TO_POINTER(ext_seq
));
4114 p_add_proto_data(wmem_file_scope(), pinfo
, proto_dnp3
, tr_seq
, GUINT_TO_POINTER(ext_seq
));
4116 ext_seq
= GPOINTER_TO_UINT(p_get_proto_data(wmem_file_scope(), pinfo
, proto_dnp3
, tr_seq
));
4119 /* Add Transport Layer Tree */
4120 tc
= proto_tree_add_bitmask(dnp3_tree
, tvb
, offset
, hf_dnp3_tr_ctl
, ett_dnp3_tr_ctl
, transport_flags
, ENC_BIG_ENDIAN
);
4121 proto_item_append_text(tc
, "(");
4122 if (tr_fir
) proto_item_append_text(tc
, "FIR, ");
4123 if (tr_fin
) proto_item_append_text(tc
, "FIN, ");
4124 proto_item_append_text(tc
, "Sequence %u)", tr_seq
);
4126 /* Add data chunk tree */
4127 data_tree
= proto_tree_add_subtree(dnp3_tree
, tvb
, offset
, -1, ett_dnp3_dl_data
, &data_ti
, "Data Chunks");
4129 /* extract the application layer data, validating the CRCs */
4131 /* XXX - check for dl_len <= 5 */
4132 data_len
= dl_len
- 5;
4133 al_buffer
= (uint8_t *)wmem_alloc(pinfo
->pool
, data_len
);
4134 al_buffer_ptr
= al_buffer
;
4136 tl_offset
= 1; /* skip the initial transport layer byte when assembling chunks for the application layer tvb */
4137 while (data_len
> 0)
4140 const uint8_t *chk_ptr
;
4141 proto_tree
*chk_tree
;
4142 proto_item
*chk_len_ti
;
4143 uint16_t calc_crc
, act_crc
;
4145 chk_size
= MIN(data_len
, AL_MAX_CHUNK_SIZE
);
4146 chk_ptr
= tvb_get_ptr(tvb
, offset
, chk_size
);
4147 memcpy(al_buffer_ptr
, chk_ptr
+ tl_offset
, chk_size
- tl_offset
);
4148 al_buffer_ptr
+= chk_size
- tl_offset
;
4150 chk_tree
= proto_tree_add_subtree_format(data_tree
, tvb
, offset
, chk_size
+ 2, ett_dnp3_dl_chunk
, NULL
, "Data Chunk: %u", i
);
4151 proto_tree_add_item(chk_tree
, hf_dnp3_data_chunk
, tvb
, offset
, chk_size
, ENC_NA
);
4152 chk_len_ti
= proto_tree_add_uint(chk_tree
, hf_dnp3_data_chunk_len
, tvb
, offset
, 0, chk_size
);
4153 proto_item_set_generated(chk_len_ti
);
4157 calc_crc
= calculateCRC(chk_ptr
, chk_size
);
4158 proto_tree_add_checksum(chk_tree
, tvb
, offset
, hf_dnp3_data_chunk_crc
,
4159 hf_dnp3_data_chunk_crc_status
, &ei_dnp3_data_chunk_crc_incorrect
,
4160 pinfo
, calc_crc
, ENC_LITTLE_ENDIAN
, PROTO_CHECKSUM_VERIFY
);
4161 act_crc
= tvb_get_letohs(tvb
, offset
);
4163 crc_OK
= calc_crc
== act_crc
;
4166 /* Don't trust the rest of the data, get out of here */
4169 data_len
-= chk_size
;
4171 tl_offset
= 0; /* copy all the data in the rest of the chunks */
4173 proto_item_set_len(data_ti
, offset
- data_start
);
4175 /* if crc OK, set up new tvb */
4179 bool save_fragmented
;
4181 al_tvb
= tvb_new_child_real_data(tvb
, al_buffer
, (unsigned) (al_buffer_ptr
-al_buffer
), (int) (al_buffer_ptr
-al_buffer
));
4183 /* Check for fragmented packet */
4184 save_fragmented
= pinfo
->fragmented
;
4186 /* Reassemble AL fragments */
4187 static unsigned al_max_fragments
= 60; /* In practice 9 - 2048 (AL) / 249 (AL Fragment) */
4188 fragment_head
*frag_al
= NULL
;
4189 pinfo
->fragmented
= true;
4190 if (!pinfo
->fd
->visited
)
4192 frag_al
= fragment_add_seq_single(&al_reassembly_table
,
4193 al_tvb
, 0, pinfo
, ext_seq
, NULL
,
4194 tvb_reported_length(al_tvb
), /* As this is a constructed tvb, all of it is ok */
4200 frag_al
= fragment_get_reassembled_id(&al_reassembly_table
, pinfo
, ext_seq
);
4205 /* This is the fragment in which reassembly occurred iff FIN is set. */
4208 next_tvb
= process_reassembled_data(al_tvb
, 0, pinfo
,
4209 "Reassembled DNP 3.0 Application Layer message", frag_al
, &dnp3_frag_items
,
4211 /* As a complete AL message will have cleared the info column,
4212 make sure source and dest are always in the info column */
4213 //col_append_fstr(pinfo->cinfo, COL_INFO, "from %u to %u", dl_src, dl_dst);
4214 //col_set_fence(pinfo->cinfo, COL_INFO);
4215 dissect_dnp3_al(next_tvb
, pinfo
, dnp3_tree
);
4219 proto_tree_add_uint(dnp3_tree
, hf_dnp3_fragment_reassembled_in
, tvb
, 0, 0,
4220 frag_al
->reassembled_in
);
4221 /* Lock any column info set by the DL and TL */
4222 col_set_fence(pinfo
->cinfo
, COL_INFO
);
4223 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
4224 " (Application Layer fragment %u, reassembled in packet %u)",
4225 tr_seq
, frag_al
->reassembled_in
);
4226 proto_tree_add_item(dnp3_tree
, hf_al_frag_data
, al_tvb
, 0, -1, ENC_NA
);
4231 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
4232 " (Application Layer Unreassembled fragment %u)",
4234 proto_tree_add_item(dnp3_tree
, hf_al_frag_data
, al_tvb
, 0, -1, ENC_NA
);
4237 pinfo
->fragmented
= save_fragmented
;
4241 /* CRC error - throw away the data. */
4242 wmem_free(pinfo
->pool
, al_buffer
);
4247 /* Set the length of the message */
4248 proto_item_set_len(ti
, offset
);
4253 check_dnp3_header(tvbuff_t
*tvb
, bool dnp3_heuristics
)
4255 /* Assume the CRC will be bad */
4256 bool goodCRC
= false;
4258 /* How big is the actual buffer */
4259 int length
= tvb_captured_length(tvb
);
4261 /* Calculate the header CRC if the bytes are available */
4262 if (length
>= DNP_HDR_LEN
) {
4263 uint16_t calc_crc
= calculateCRCtvb(tvb
, 0, DNP_HDR_LEN
- 2);
4264 goodCRC
= (calc_crc
== tvb_get_letohs(tvb
, 8));
4267 /* For a heuristic match we must have at least a header, beginning with 0x0564
4268 and a valid header CRC */
4269 if (dnp3_heuristics
) {
4270 if ( !goodCRC
|| (tvb_get_ntohs(tvb
, 0) != 0x0564)) {
4275 /* For a non-heuristic match, at least the first byte is 0x05 and if available
4276 the second byte is 64 and if available the CRC is valid */
4277 if (tvb_get_uint8(tvb
, 0) != 0x05) {
4280 if ((length
> 1) && (tvb_get_uint8(tvb
, 1) != 0x64)) {
4283 if ((length
>= DNP_HDR_LEN
) && !goodCRC
) {
4291 get_dnp3_message_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
,
4292 int offset
, void *data _U_
)
4294 uint16_t message_len
; /* need 16 bits as total can exceed 255 */
4295 uint16_t data_crc
; /* No. of user data CRC bytes */
4297 message_len
= tvb_get_uint8(tvb
, offset
+ 2);
4299 /* Add in 2 bytes for header start octets,
4300 1 byte for len itself,
4301 2 bytes for header CRC
4302 data CRC bytes (2 bytes per 16 bytes of data
4305 data_crc
= (uint16_t)(ceil((message_len
- 5) / 16.0)) * 2;
4306 message_len
+= 2 + 1 + 2 + data_crc
;
4311 dissect_dnp3_tcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
4313 if (!check_dnp3_header(tvb
, false)) {
4317 tcp_dissect_pdus(tvb
, pinfo
, tree
, true, DNP_HDR_LEN
,
4318 get_dnp3_message_len
, dissect_dnp3_message
, data
);
4320 return tvb_captured_length(tvb
);
4324 dissect_dnp3_tcp_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
4326 if (!check_dnp3_header(tvb
, true)) {
4330 tcp_dissect_pdus(tvb
, pinfo
, tree
, true, DNP_HDR_LEN
,
4331 get_dnp3_message_len
, dissect_dnp3_message
, data
);
4337 dnp3_udp_check_header(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset _U_
, void *data _U_
)
4339 return check_dnp3_header(tvb
, false);
4343 dnp3_udp_check_header_heur(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset _U_
, void *data _U_
)
4345 return check_dnp3_header(tvb
, true);
4349 dissect_dnp3_udp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
4351 return udp_dissect_pdus(tvb
, pinfo
, tree
, DNP_HDR_LEN
, dnp3_udp_check_header
,
4352 get_dnp3_message_len
, dissect_dnp3_message
, data
);
4356 dissect_dnp3_udp_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
4358 return (udp_dissect_pdus(tvb
, pinfo
, tree
, DNP_HDR_LEN
, dnp3_udp_check_header_heur
,
4359 get_dnp3_message_len
, dissect_dnp3_message
, data
) != 0);
4363 /* Register the protocol with Wireshark */
4366 proto_register_dnp3(void)
4369 /* Setup list of header fields */
4370 static hf_register_info hf
[] = {
4372 { "Start Bytes", "dnp3.start",
4373 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
4378 { "Length", "dnp3.len",
4379 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
4380 "Frame Data Length", HFILL
}
4384 { "Control", "dnp3.ctl",
4385 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
4386 "Frame Control Byte", HFILL
}
4389 { &hf_dnp3_ctl_prifunc
,
4390 { "Control Function Code", "dnp3.ctl.prifunc",
4391 FT_UINT8
, BASE_DEC
, VALS(dnp3_ctl_func_pri_vals
), DNP3_CTL_FUNC
,
4392 "Frame Control Function Code", HFILL
}
4395 { &hf_dnp3_ctl_secfunc
,
4396 { "Control Function Code", "dnp3.ctl.secfunc",
4397 FT_UINT8
, BASE_DEC
, VALS(dnp3_ctl_func_sec_vals
), DNP3_CTL_FUNC
,
4398 "Frame Control Function Code", HFILL
}
4401 { &hf_dnp3_ctlobj_code_c
,
4402 { "Operation Type", "dnp3.ctl.op",
4403 FT_UINT8
, BASE_DEC
, VALS(dnp3_al_ctlc_code_vals
), AL_OBJCTLC_CODE
,
4404 "Control Code, Operation Type", HFILL
}
4407 { &hf_dnp3_ctlobj_code_m
,
4408 { "Queue / Clear Field", "dnp3.ctl.clr",
4409 FT_UINT8
, BASE_DEC
, VALS(dnp3_al_ctlc_misc_vals
), AL_OBJCTLC_MISC
,
4410 "Control Code, Clear Field", HFILL
}
4413 { &hf_dnp3_ctlobj_code_tc
,
4414 { "Trip Control Code", "dnp3.ctl.trip",
4415 FT_UINT8
, BASE_DEC
, VALS(dnp3_al_ctlc_tc_vals
), AL_OBJCTLC_TC
,
4416 "Control Code, Trip Close Control", HFILL
}
4420 { "Direction", "dnp3.ctl.dir",
4421 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), DNP3_CTL_DIR
,
4426 { "Primary", "dnp3.ctl.prm",
4427 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), DNP3_CTL_PRM
,
4432 { "Frame Count Bit", "dnp3.ctl.fcb",
4433 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), DNP3_CTL_FCB
,
4438 { "Frame Count Valid", "dnp3.ctl.fcv",
4439 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), DNP3_CTL_FCV
,
4444 { "Data Flow Control", "dnp3.ctl.dfc",
4445 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), DNP3_CTL_DFC
,
4450 { "Destination", "dnp3.dst",
4451 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4452 "Destination Address", HFILL
}
4456 { "Source", "dnp3.src",
4457 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4458 "Source Address", HFILL
}
4462 { "Address", "dnp3.addr",
4463 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4464 "Source or Destination Address", HFILL
}
4467 { &hf_dnp3_data_hdr_crc
,
4468 { "Data Link Header checksum", "dnp3.hdr.CRC",
4469 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
4473 { &hf_dnp3_data_hdr_crc_status
,
4474 { "Data Link Header Checksum Status", "dnp.hdr.CRC.status",
4475 FT_UINT8
, BASE_NONE
, VALS(proto_checksum_vals
), 0x0,
4480 { "Transport Control", "dnp3.tr.ctl",
4481 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
4482 "Transport Layer Control Byte", HFILL
}
4486 { "Final", "dnp3.tr.fin",
4487 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), DNP3_TR_FIN
,
4492 { "First", "dnp3.tr.fir",
4493 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), DNP3_TR_FIR
,
4498 { "Sequence", "dnp3.tr.seq",
4499 FT_UINT8
, BASE_DEC
, NULL
, DNP3_TR_SEQ
,
4500 "Frame Sequence Number", HFILL
}
4503 { &hf_dnp3_data_chunk
,
4504 { "Data Chunk", "dnp.data_chunk",
4505 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
4509 { &hf_dnp3_data_chunk_len
,
4510 { "Data Chunk length", "dnp.data_chunk_len",
4511 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4515 { &hf_dnp3_data_chunk_crc
,
4516 { "Data Chunk checksum", "dnp.data_chunk.CRC",
4517 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
4521 { &hf_dnp3_data_chunk_crc_status
,
4522 { "Data Chunk Checksum Status", "dnp.data_chunk.CRC.status",
4523 FT_UINT8
, BASE_NONE
, VALS(proto_checksum_vals
), 0x0,
4528 { "Application Control", "dnp3.al.ctl",
4529 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
4530 "Application Layer Control Byte", HFILL
}
4534 { "First", "dnp3.al.fir",
4535 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), DNP3_AL_FIR
,
4540 { "Final", "dnp3.al.fin",
4541 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), DNP3_AL_FIN
,
4546 { "Confirm", "dnp3.al.con",
4547 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), DNP3_AL_CON
,
4552 { "Unsolicited", "dnp3.al.uns",
4553 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), DNP3_AL_UNS
,
4558 { "Sequence", "dnp3.al.seq",
4559 FT_UINT8
, BASE_DEC
, NULL
, DNP3_AL_SEQ
,
4560 "Frame Sequence Number", HFILL
}
4564 { "Application Layer Function Code", "dnp3.al.func",
4565 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &dnp3_al_func_vals_ext
, DNP3_AL_FUNC
,
4570 { "Internal Indications", "dnp3.al.iin",
4571 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
4572 "Application Layer IIN", HFILL
}
4575 { &hf_dnp3_al_iin_bmsg
,
4576 { "Broadcast Msg Rx", "dnp3.al.iin.bmsg",
4577 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), AL_IIN_BMSG
,
4581 { &hf_dnp3_al_iin_cls1d
,
4582 { "Class 1 Data Available", "dnp3.al.iin.cls1d",
4583 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), AL_IIN_CLS1D
,
4587 { &hf_dnp3_al_iin_cls2d
,
4588 { "Class 2 Data Available", "dnp3.al.iin.cls2d",
4589 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), AL_IIN_CLS2D
,
4593 { &hf_dnp3_al_iin_cls3d
,
4594 { "Class 3 Data Available", "dnp3.al.iin.cls3d",
4595 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), AL_IIN_CLS3D
,
4599 { &hf_dnp3_al_iin_tsr
,
4600 { "Time Sync Required", "dnp3.al.iin.tsr",
4601 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), AL_IIN_TSR
,
4605 { &hf_dnp3_al_iin_dol
,
4606 { "Digital Outputs in Local", "dnp3.al.iin.dol",
4607 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), AL_IIN_DOL
,
4611 { &hf_dnp3_al_iin_dt
,
4612 { "Device Trouble", "dnp3.al.iin.dt",
4613 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), AL_IIN_DT
,
4617 { &hf_dnp3_al_iin_rst
,
4618 { "Device Restart", "dnp3.al.iin.rst",
4619 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), AL_IIN_RST
,
4623 { &hf_dnp3_al_iin_fcni
,
4624 { "Function Code not implemented", "dnp3.al.iin.fcni",
4625 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), AL_IIN_FCNI
,
4629 { &hf_dnp3_al_iin_obju
,
4630 { "Requested Objects Unknown", "dnp3.al.iin.obju",
4631 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), AL_IIN_OBJU
,
4635 { &hf_dnp3_al_iin_pioor
,
4636 { "Parameters Invalid or Out of Range", "dnp3.al.iin.pioor",
4637 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), AL_IIN_PIOOR
,
4641 { &hf_dnp3_al_iin_ebo
,
4642 { "Event Buffer Overflow", "dnp3.al.iin.ebo",
4643 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), AL_IIN_EBO
,
4647 { &hf_dnp3_al_iin_oae
,
4648 { "Operation Already Executing", "dnp3.al.iin.oae",
4649 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), AL_IIN_OAE
,
4653 { &hf_dnp3_al_iin_cc
,
4654 { "Configuration Corrupt", "dnp3.al.iin.cc",
4655 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), AL_IIN_CC
,
4660 { "Object", "dnp3.al.obj",
4661 FT_UINT16
, BASE_HEX
|BASE_EXT_STRING
, &dnp3_al_obj_vals_ext
, 0x0,
4662 "Application Layer Object", HFILL
}
4665 { &hf_dnp3_al_objq_prefix
,
4666 { "Prefix Code", "dnp3.al.objq.prefix",
4667 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &dnp3_al_objq_prefix_vals_ext
, AL_OBJQ_PREFIX
,
4668 "Object Prefix Code", HFILL
}
4671 { &hf_dnp3_al_objq_range
,
4672 { "Range Code", "dnp3.al.objq.range",
4673 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &dnp3_al_objq_range_vals_ext
, AL_OBJQ_RANGE
,
4674 "Object Range Specifier Code", HFILL
}
4677 { &hf_dnp3_al_range_start8
,
4678 { "Start (8 bit)", "dnp3.al.range.start",
4679 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
4680 "Object Start Index", HFILL
}
4683 { &hf_dnp3_al_range_stop8
,
4684 { "Stop (8 bit)", "dnp3.al.range.stop",
4685 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
4686 "Object Stop Index", HFILL
}
4689 { &hf_dnp3_al_range_start16
,
4690 { "Start (16 bit)", "dnp3.al.range.start",
4691 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4692 "Object Start Index", HFILL
}
4695 { &hf_dnp3_al_range_stop16
,
4696 { "Stop (16 bit)", "dnp3.al.range.stop",
4697 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4698 "Object Stop Index", HFILL
}
4701 { &hf_dnp3_al_range_start32
,
4702 { "Start (32 bit)", "dnp3.al.range.start",
4703 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
4704 "Object Start Index", HFILL
}
4707 { &hf_dnp3_al_range_stop32
,
4708 { "Stop (32 bit)", "dnp3.al.range.stop",
4709 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
4710 "Object Stop Index", HFILL
}
4713 { &hf_dnp3_al_range_abs8
,
4714 { "Address (8 bit)", "dnp3.al.range.abs",
4715 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
4716 "Object Absolute Address", HFILL
}
4719 { &hf_dnp3_al_range_abs16
,
4720 { "Address (16 bit)", "dnp3.al.range.abs",
4721 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4722 "Object Absolute Address", HFILL
}
4725 { &hf_dnp3_al_range_abs32
,
4726 { "Address (32 bit)", "dnp3.al.range.abs",
4727 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
4728 "Object Absolute Address", HFILL
}
4731 { &hf_dnp3_al_range_quant8
,
4732 { "Quantity (8 bit)", "dnp3.al.range.quantity",
4733 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
4734 "Object Quantity", HFILL
}
4737 { &hf_dnp3_al_range_quant16
,
4738 { "Quantity (16 bit)", "dnp3.al.range.quantity",
4739 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4740 "Object Quantity", HFILL
}
4743 { &hf_dnp3_al_range_quant32
,
4744 { "Quantity (32 bit)", "dnp3.al.range.quantity",
4745 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
4746 "Object Quantity", HFILL
}
4749 { &hf_dnp3_al_index8
,
4750 { "Index (8 bit)", "dnp3.al.index",
4751 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
4752 "Object Index", HFILL
}
4755 { &hf_dnp3_al_index16
,
4756 { "Index (16 bit)", "dnp3.al.index",
4757 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4758 "Object Index", HFILL
}
4761 { &hf_dnp3_al_index32
,
4762 { "Index (32 bit)", "dnp3.al.index",
4763 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
4764 "Object Index", HFILL
}
4768 { &hf_dnp3_al_ptnum
,
4769 { "Object Point Number", "dnp3.al.ptnum",
4770 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4775 { &hf_dnp3_al_size8
,
4776 { "Size (8 bit)", "dnp3.al.size",
4777 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
4778 "Object Size", HFILL
}
4781 { &hf_dnp3_al_size16
,
4782 { "Size (16 bit)", "dnp3.al.size",
4783 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4784 "Object Size", HFILL
}
4787 { &hf_dnp3_al_size32
,
4788 { "Size (32 bit)", "dnp3.al.size",
4789 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
4790 "Object Size", HFILL
}
4793 { &hf_dnp3_bocs_bit
,
4794 { "Commanded State", "dnp3.al.bocs",
4795 FT_BOOLEAN
, 8, TFS(&tfs_on_off
), 0x80,
4796 "Binary Output Commanded state", HFILL
}
4800 { "Value (bit)", "dnp3.al.bit",
4801 FT_BOOLEAN
, 8, TFS(&tfs_on_off
), 0x1,
4802 "Digital Value (1 bit)", HFILL
}
4806 { "Value (bit)", "dnp3.al.bit",
4807 FT_BOOLEAN
, 8, TFS(&tfs_on_off
), 0x01,
4808 "Digital Value (1 bit)", HFILL
}
4811 { "Value (bit)", "dnp3.al.bit",
4812 FT_BOOLEAN
, 8, TFS(&tfs_on_off
), 0x02,
4813 "Digital Value (1 bit)", HFILL
}
4816 { "Value (bit)", "dnp3.al.bit",
4817 FT_BOOLEAN
, 8, TFS(&tfs_on_off
), 0x04,
4818 "Digital Value (1 bit)", HFILL
}
4821 { "Value (bit)", "dnp3.al.bit",
4822 FT_BOOLEAN
, 8, TFS(&tfs_on_off
), 0x08,
4823 "Digital Value (1 bit)", HFILL
}
4826 { "Value (bit)", "dnp3.al.bit",
4827 FT_BOOLEAN
, 8, TFS(&tfs_on_off
), 0x10,
4828 "Digital Value (1 bit)", HFILL
}
4831 { "Value (bit)", "dnp3.al.bit",
4832 FT_BOOLEAN
, 8, TFS(&tfs_on_off
), 0x20,
4833 "Digital Value (1 bit)", HFILL
}
4836 { "Value (bit)", "dnp3.al.bit",
4837 FT_BOOLEAN
, 8, TFS(&tfs_on_off
), 0x40,
4838 "Digital Value (1 bit)", HFILL
}
4841 { "Value (bit)", "dnp3.al.bit",
4842 FT_BOOLEAN
, 8, TFS(&tfs_on_off
), 0x80,
4843 "Digital Value (1 bit)", HFILL
}
4847 { "Value (Double-bit)", "dnp3.al.2bit",
4848 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &dnp3_al_dbi_vals_ext
, AL_OBJ_DBI_MASK
,
4849 "Digital Value (Double-bit)", HFILL
}
4852 { &hf_dnp3_al_2bit0
,
4853 { "Value (Double-bit)", "dnp3.al.2bit",
4854 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &dnp3_al_dbi_vals_ext
, 0x03,
4855 "Digital Value (Double-bit)", HFILL
}
4858 { &hf_dnp3_al_2bit1
,
4859 { "Value (Double-bit)", "dnp3.al.2bit",
4860 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &dnp3_al_dbi_vals_ext
, 0x0c,
4861 "Digital Value (Double-bit)", HFILL
}
4864 { &hf_dnp3_al_2bit2
,
4865 { "Value (Double-bit)", "dnp3.al.2bit",
4866 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &dnp3_al_dbi_vals_ext
, 0x30,
4867 "Digital Value (Double-bit)", HFILL
}
4869 { &hf_dnp3_al_2bit3
,
4870 { "Value (Double-bit)", "dnp3.al.2bit",
4871 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &dnp3_al_dbi_vals_ext
, 0xc0,
4872 "Digital Value (Double-bit)", HFILL
}
4875 { &hf_dnp3_al_ana16
,
4876 { "Value (16 bit)", "dnp3.al.ana.int",
4877 FT_INT16
, BASE_DEC
, NULL
, 0x0,
4878 "Analog Value (16 bit)", HFILL
}
4881 { &hf_dnp3_al_ana32
,
4882 { "Value (32 bit)", "dnp3.al.ana.int",
4883 FT_INT32
, BASE_DEC
, NULL
, 0x0,
4884 "Analog Value (32 bit)", HFILL
}
4887 { &hf_dnp3_al_anaflt
,
4888 { "Value (float)", "dnp3.al.ana.float",
4889 FT_FLOAT
, BASE_NONE
, NULL
, 0x0,
4890 "Analog Value (float)", HFILL
}
4893 { &hf_dnp3_al_anadbl
,
4894 { "Value (double)", "dnp3.al.ana.double",
4895 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
4896 "Analog Value (double)", HFILL
}
4899 { &hf_dnp3_al_anaout16
,
4900 { "Output Value (16 bit)", "dnp3.al.anaout.int",
4901 FT_INT16
, BASE_DEC
, NULL
, 0x0,
4905 { &hf_dnp3_al_anaout32
,
4906 { "Output Value (32 bit)", "dnp3.al.anaout.int",
4907 FT_INT32
, BASE_DEC
, NULL
, 0x0,
4911 { &hf_dnp3_al_anaoutflt
,
4912 { "Output Value (float)", "dnp3.al.anaout.float",
4913 FT_FLOAT
, BASE_NONE
, NULL
, 0x0,
4917 { &hf_dnp3_al_anaoutdbl
,
4918 { "Output (double)", "dnp3.al.anaout.double",
4919 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
4920 "Output Value (double)", HFILL
}
4923 { &hf_dnp3_al_cnt16
,
4924 { "Counter (16 bit)", "dnp3.al.cnt",
4925 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4926 "Counter Value (16 bit)", HFILL
}
4929 { &hf_dnp3_al_cnt32
,
4930 { "Counter (32 bit)", "dnp3.al.cnt",
4931 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
4932 "Counter Value (32 bit)", HFILL
}
4935 { &hf_dnp3_al_ctrlstatus
,
4936 { "Control Status", "dnp3.al.ctrlstatus",
4937 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &dnp3_al_ctl_status_vals_ext
, AL_OBJCTL_STATUS_MASK
,
4941 { &hf_dnp3_al_file_mode
,
4942 { "File Control Mode", "dnp3.al.file.mode",
4943 FT_UINT16
, BASE_DEC
, VALS(dnp3_al_file_mode_vals
), 0x0,
4947 { &hf_dnp3_al_file_auth
,
4948 { "File Authentication Key", "dnp3.al.file.auth",
4949 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
4953 { &hf_dnp3_al_file_size
,
4954 { "File Size", "dnp3.al.file.size",
4955 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
4959 { &hf_dnp3_al_file_maxblk
,
4960 { "File Max Block Size", "dnp3.al.file.maxblock",
4961 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4965 { &hf_dnp3_al_file_reqID
,
4966 { "File Request Identifier", "dnp3.al.file.reqID",
4967 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4971 { &hf_dnp3_al_file_status
,
4972 { "File Control Status", "dnp3.al.file.status",
4973 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &dnp3_al_file_status_vals_ext
, 0x0,
4977 { &hf_dnp3_al_file_handle
,
4978 { "File Handle", "dnp3.al.file.handle",
4979 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
4983 { &hf_dnp3_al_file_blocknum
,
4984 { "File Block Number", "dnp3.al.file.blocknum",
4985 FT_UINT32
, BASE_HEX
, NULL
, 0x7fffffff,
4989 { &hf_dnp3_al_file_lastblock
,
4990 { "File Last Block", "dnp3.al.file.lastblock",
4991 FT_BOOLEAN
, 32, TFS(&tfs_set_notset
), 0x80000000,
4995 { &hf_dnp3_al_file_data
,
4996 { "File Data", "dnp3.al.file.data",
4997 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5001 { &hf_dnp3_al_biq_b0
,
5002 { "Online", "dnp3.al.biq.b0",
5003 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_BI_FLAG0
,
5007 { &hf_dnp3_al_biq_b1
,
5008 { "Restart", "dnp3.al.biq.b1",
5009 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_BI_FLAG1
,
5013 { &hf_dnp3_al_biq_b2
,
5014 { "Comm Fail", "dnp3.al.biq.b2",
5015 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_BI_FLAG2
,
5019 { &hf_dnp3_al_biq_b3
,
5020 { "Remote Force", "dnp3.al.biq.b3",
5021 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_BI_FLAG3
,
5025 { &hf_dnp3_al_biq_b4
,
5026 { "Local Force", "dnp3.al.biq.b4",
5027 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_BI_FLAG4
,
5031 { &hf_dnp3_al_biq_b5
,
5032 { "Chatter Filter", "dnp3.al.biq.b5",
5033 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_BI_FLAG5
,
5037 { &hf_dnp3_al_biq_b6
,
5038 { "Reserved", "dnp3.al.biq.b6",
5039 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_BI_FLAG6
,
5043 { &hf_dnp3_al_biq_b7
,
5044 { "Point Value", "dnp3.al.biq.b7",
5045 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_BI_FLAG7
,
5049 { &hf_dnp3_al_boq_b0
,
5050 { "Online", "dnp3.al.boq.b0",
5051 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_BO_FLAG0
,
5055 { &hf_dnp3_al_boq_b1
,
5056 { "Restart", "dnp3.al.boq.b1",
5057 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_BO_FLAG1
,
5061 { &hf_dnp3_al_boq_b2
,
5062 { "Comm Fail", "dnp3.al.boq.b2",
5063 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_BO_FLAG2
,
5067 { &hf_dnp3_al_boq_b3
,
5068 { "Remote Force", "dnp3.al.boq.b3",
5069 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_BO_FLAG3
,
5073 { &hf_dnp3_al_boq_b4
,
5074 { "Local Force", "dnp3.al.boq.b4",
5075 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_BO_FLAG4
,
5079 { &hf_dnp3_al_boq_b5
,
5080 { "Reserved", "dnp3.al.boq.b5",
5081 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_BO_FLAG5
,
5085 { &hf_dnp3_al_boq_b6
,
5086 { "Reserved", "dnp3.al.boq.b6",
5087 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_BO_FLAG6
,
5091 { &hf_dnp3_al_boq_b7
,
5092 { "Point Value", "dnp3.al.boq.b7",
5093 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_BO_FLAG7
,
5097 { &hf_dnp3_al_ctrq_b0
,
5098 { "Online", "dnp3.al.ctrq.b0",
5099 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_CTR_FLAG0
,
5103 { &hf_dnp3_al_ctrq_b1
,
5104 { "Restart", "dnp3.al.ctrq.b1",
5105 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_CTR_FLAG1
,
5109 { &hf_dnp3_al_ctrq_b2
,
5110 { "Comm Fail", "dnp3.al.ctrq.b2",
5111 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_CTR_FLAG2
,
5115 { &hf_dnp3_al_ctrq_b3
,
5116 { "Remote Force", "dnp3.al.ctrq.b3",
5117 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_CTR_FLAG3
,
5121 { &hf_dnp3_al_ctrq_b4
,
5122 { "Local Force", "dnp3.al.ctrq.b4",
5123 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_CTR_FLAG4
,
5127 { &hf_dnp3_al_ctrq_b5
,
5128 { "Roll-Over", "dnp3.al.ctrq.b5",
5129 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_CTR_FLAG5
,
5133 { &hf_dnp3_al_ctrq_b6
,
5134 { "Discontinuity", "dnp3.al.ctrq.b6",
5135 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_CTR_FLAG6
,
5139 { &hf_dnp3_al_ctrq_b7
,
5140 { "Reserved", "dnp3.al.ctrq.b7",
5141 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_CTR_FLAG7
,
5145 { &hf_dnp3_al_aiq_b0
,
5146 { "Online", "dnp3.al.aiq.b0",
5147 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_AI_FLAG0
,
5151 { &hf_dnp3_al_aiq_b1
,
5152 { "Restart", "dnp3.al.aiq.b1",
5153 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_AI_FLAG1
,
5157 { &hf_dnp3_al_aiq_b2
,
5158 { "Comm Fail", "dnp3.al.aiq.b2",
5159 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_AI_FLAG2
,
5163 { &hf_dnp3_al_aiq_b3
,
5164 { "Remote Force", "dnp3.al.aiq.b3",
5165 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_AI_FLAG3
,
5169 { &hf_dnp3_al_aiq_b4
,
5170 { "Local Force", "dnp3.al.aiq.b4",
5171 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_AI_FLAG4
,
5175 { &hf_dnp3_al_aiq_b5
,
5176 { "Over-Range", "dnp3.al.aiq.b5",
5177 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_AI_FLAG5
,
5181 { &hf_dnp3_al_aiq_b6
,
5182 { "Reference Check", "dnp3.al.aiq.b6",
5183 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_AI_FLAG6
,
5187 { &hf_dnp3_al_aiq_b7
,
5188 { "Reserved", "dnp3.al.aiq.b7",
5189 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_AI_FLAG7
,
5193 { &hf_dnp3_al_aoq_b0
,
5194 { "Online", "dnp3.al.aoq.b0",
5195 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_AO_FLAG0
,
5199 { &hf_dnp3_al_aoq_b1
,
5200 { "Restart", "dnp3.al.aoq.b1",
5201 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_AO_FLAG1
,
5205 { &hf_dnp3_al_aoq_b2
,
5206 { "Comm Fail", "dnp3.al.aoq.b2",
5207 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_AO_FLAG2
,
5211 { &hf_dnp3_al_aoq_b3
,
5212 { "Remote Force", "dnp3.al.aoq.b3",
5213 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_AO_FLAG3
,
5217 { &hf_dnp3_al_aoq_b4
,
5218 { "Local Force", "dnp3.al.aoq.b4",
5219 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_AO_FLAG4
,
5223 { &hf_dnp3_al_aoq_b5
,
5224 { "Reserved", "dnp3.al.aoq.b5",
5225 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_AO_FLAG5
,
5229 { &hf_dnp3_al_aoq_b6
,
5230 { "Reserved", "dnp3.al.aoq.b6",
5231 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_AO_FLAG6
,
5235 { &hf_dnp3_al_aoq_b7
,
5236 { "Reserved", "dnp3.al.aoq.b7",
5237 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), AL_OBJ_AO_FLAG7
,
5241 { &hf_dnp3_al_timestamp
,
5242 { "Timestamp", "dnp3.al.timestamp",
5243 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0,
5244 "Object Timestamp", HFILL
}
5247 { &hf_dnp3_al_file_perms
,
5248 { "Permissions", "dnp3.al.file.perms",
5249 FT_UINT16
, BASE_OCT
, NULL
, 0x0,
5253 { &hf_dnp3_al_file_perms_read_owner
,
5254 { "Read permission for owner", "dnp3.al.file.perms.read_owner",
5255 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0400,
5259 { &hf_dnp3_al_file_perms_write_owner
,
5260 { "Write permission for owner", "dnp3.al.file.perms.write_owner",
5261 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0200,
5265 { &hf_dnp3_al_file_perms_exec_owner
,
5266 { "Execute permission for owner", "dnp3.al.file.perms.exec_owner",
5267 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 0100,
5271 { &hf_dnp3_al_file_perms_read_group
,
5272 { "Read permission for group", "dnp3.al.file.perms.read_group",
5273 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 040,
5277 { &hf_dnp3_al_file_perms_write_group
,
5278 { "Write permission for group", "dnp3.al.file.perms.write_group",
5279 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 020,
5283 { &hf_dnp3_al_file_perms_exec_group
,
5284 { "Execute permission for group", "dnp3.al.file.perms.exec_group",
5285 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 010,
5289 { &hf_dnp3_al_file_perms_read_world
,
5290 { "Read permission for world", "dnp3.al.file.perms.read_world",
5291 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 04,
5295 { &hf_dnp3_al_file_perms_write_world
,
5296 { "Write permission for world", "dnp3.al.file.perms.write_world",
5297 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 02,
5301 { &hf_dnp3_al_file_perms_exec_world
,
5302 { "Execute permission for world", "dnp3.al.file.perms.exec_world",
5303 FT_BOOLEAN
, 16, TFS(&tfs_yes_no
), 01,
5307 { &hf_dnp3_al_rel_timestamp
,
5308 { "Relative Timestamp", "dnp3.al.reltimestamp",
5309 FT_RELATIVE_TIME
, BASE_NONE
, NULL
, 0,
5310 "Object Relative Timestamp", HFILL
}
5313 { &hf_dnp3_al_datatype
,
5314 { "Data Type", "dnp3.al.datatype",
5315 FT_UINT8
, BASE_HEX
, VALS(dnp3_al_data_type_vals
), 0,
5319 { &hf_dnp3_al_da_length
,
5320 { "Device Attribute Length", "dnp3.al.da.length",
5321 FT_UINT8
, BASE_DEC
, NULL
, 0,
5325 { &hf_dnp3_al_da_uint8
,
5326 { "Device Attribute 8-Bit Unsigned Integer Value", "dnp3.al.da.uint8",
5327 FT_UINT8
, BASE_DEC
, NULL
, 0,
5331 { &hf_dnp3_al_da_uint16
,
5332 { "Device Attribute 16-Bit Unsigned Integer Value", "dnp3.al.da.uint16",
5333 FT_UINT16
, BASE_DEC
, NULL
, 0,
5337 { &hf_dnp3_al_da_uint32
,
5338 { "Device Attribute 32-Bit Unsigned Integer Value", "dnp3.al.da.uint32",
5339 FT_UINT32
, BASE_DEC
, NULL
, 0,
5343 { &hf_dnp3_al_da_int8
,
5344 { "Device Attribute 8-Bit Integer Value", "dnp3.al.da.int8",
5345 FT_INT8
, BASE_DEC
, NULL
, 0,
5349 { &hf_dnp3_al_da_int16
,
5350 { "Device Attribute 16-Bit Integer Value", "dnp3.al.da.int16",
5351 FT_INT16
, BASE_DEC
, NULL
, 0,
5355 { &hf_dnp3_al_da_int32
,
5356 { "Device Attribute 32-Bit Integer Value", "dnp3.al.da.int32",
5357 FT_INT32
, BASE_DEC
, NULL
, 0,
5361 { &hf_dnp3_al_da_flt
,
5362 { "Device Attribute Float Value", "dnp3.al.da.float",
5363 FT_FLOAT
, BASE_NONE
, NULL
, 0,
5367 { &hf_dnp3_al_da_dbl
,
5368 { "Device Attribute Double Value", "dnp3.al.da.double",
5369 FT_DOUBLE
, BASE_NONE
, NULL
, 0,
5373 { &hf_dnp3_al_sa_assoc_id
,
5374 { "Association ID" , "dnp3.al.sa.assoc_id",
5375 FT_UINT16
, BASE_DEC
, NULL
, 0,
5379 { &hf_dnp3_al_sa_cd
,
5380 {"Challenge Data", "dnp3.al.sa.cd",
5381 FT_BYTES
, BASE_NONE
, NULL
, 0x00,
5384 { &hf_dnp3_al_sa_cdl
,
5385 { "Challenge Data Length", "dnp3.al.sa.cdl",
5386 FT_UINT16
, BASE_HEX
, NULL
, 0,
5390 { &hf_dnp3_al_sa_csq
,
5391 { "Challenge Sequence Number" , "dnp3.al.sa.csq",
5392 FT_UINT32
, BASE_DEC
, NULL
, 0,
5396 { &hf_dnp3_al_sa_err
,
5397 { "Error Code", "dnp3.al.sa.err",
5398 FT_UINT8
, BASE_HEX
, VALS(dnp3_al_sa_err_vals
), 0,
5402 { &hf_dnp3_al_sa_kcm
,
5403 { "Key Change Method", "dnp3.al.sa.kcm",
5404 FT_UINT8
, BASE_HEX
, VALS(dnp3_al_sa_kcm_vals
), 0,
5408 { &hf_dnp3_al_sa_key
,
5409 {"Key Data", "dnp3.al.sa.key",
5410 FT_BYTES
, BASE_NONE
, NULL
, 0x00,
5413 { &hf_dnp3_al_sa_ks
,
5414 { "Key Status", "dnp3.al.sa.kw",
5415 FT_UINT8
, BASE_HEX
, VALS(dnp3_al_sa_ks_vals
), 0,
5419 { &hf_dnp3_al_sa_ksq
,
5420 { "Key Change Sequence Number" , "dnp3.al.sa.ksq",
5421 FT_UINT32
, BASE_DEC
, NULL
, 0,
5425 { &hf_dnp3_al_sa_kwa
,
5426 { "Key Wrap Algorithm", "dnp3.al.sa.kwa",
5427 FT_UINT8
, BASE_HEX
, VALS(dnp3_al_sa_kwa_vals
), 0,
5431 { &hf_dnp3_al_sa_mac
,
5432 {"MAC Value", "dnp3.al.sa.mac",
5433 FT_BYTES
, BASE_NONE
, NULL
, 0x00,
5436 { &hf_dnp3_al_sa_mal
,
5437 { "MAC Algorithm", "dnp3.al.sa.mal",
5438 FT_UINT8
, BASE_HEX
, VALS(dnp3_al_sa_mal_vals
), 0,
5442 { &hf_dnp3_al_sa_rfc
,
5443 { "Reason for Challenge", "dnp3.al.sa.rfc",
5444 FT_UINT8
, BASE_HEX
, VALS(dnp3_al_sa_rfc_vals
), 0,
5448 { &hf_dnp3_al_sa_seq
,
5449 { "Sequence Number" , "dnp3.al.sa.seq",
5450 FT_UINT32
, BASE_DEC
, NULL
, 0,
5454 { &hf_dnp3_al_sa_uk
,
5455 {"Encrypted Update Key Data", "dnp3.al.sa.uk",
5456 FT_BYTES
, BASE_NONE
, NULL
, 0x00,
5459 { &hf_dnp3_al_sa_ukl
,
5460 { "Encrypted Update Key Length", "dnp3.al.sa.ukl",
5461 FT_UINT16
, BASE_DEC
, NULL
, 0,
5465 { &hf_dnp3_al_sa_usr
,
5466 { "User Number" , "dnp3.al.sa.usr",
5467 FT_UINT16
, BASE_DEC
, NULL
, 0,
5471 { &hf_dnp3_al_sa_usrn
,
5472 { "User Name", "dnp3.al.sa.usrn",
5473 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5476 { &hf_dnp3_al_sa_usrnl
,
5477 { "User name Length", "dnp3.al.sa.usrnl",
5478 FT_UINT16
, BASE_DEC
, NULL
, 0,
5483 {"DNP3.0 AL Fragment Data", "dnp3.al.frag_data",
5484 FT_BYTES
, BASE_NONE
, NULL
, 0x00,
5485 "DNP 3.0 Application Layer Fragment Data", HFILL
}},
5487 { &hf_dnp3_fragment
,
5488 { "DNP 3.0 AL Fragment", "dnp3.al.fragment",
5489 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
5490 "DNP 3.0 Application Layer Fragment", HFILL
}
5493 { &hf_dnp3_fragments
,
5494 { "DNP 3.0 AL Fragments", "dnp3.al.fragments",
5495 FT_NONE
, BASE_NONE
, NULL
, 0x0,
5496 "DNP 3.0 Application Layer Fragments", HFILL
}
5499 { &hf_dnp3_fragment_overlap
,
5500 { "Fragment overlap", "dnp3.al.fragment.overlap",
5501 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
5502 "Fragment overlaps with other fragments", HFILL
}
5505 { &hf_dnp3_fragment_overlap_conflict
,
5506 { "Conflicting data in fragment overlap", "dnp3.al.fragment.overlap.conflict",
5507 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
5508 "Overlapping fragments contained conflicting data", HFILL
}
5511 { &hf_dnp3_fragment_multiple_tails
,
5512 { "Multiple tail fragments found", "dnp3.al.fragment.multipletails",
5513 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
5514 "Several tails were found when defragmenting the packet", HFILL
}
5517 { &hf_dnp3_fragment_too_long_fragment
,
5518 { "Fragment too long", "dnp3.al.fragment.toolongfragment",
5519 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
5520 "Fragment contained data past end of packet", HFILL
}
5523 { &hf_dnp3_fragment_error
,
5524 { "Defragmentation error", "dnp3.al.fragment.error",
5525 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
5526 "Defragmentation error due to illegal fragments", HFILL
}
5529 { &hf_dnp3_fragment_count
,
5530 { "Fragment count", "dnp3.al.fragment.count",
5531 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5535 { &hf_dnp3_fragment_reassembled_in
,
5536 { "Reassembled PDU In Frame", "dnp3.al.fragment.reassembled_in",
5537 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
5538 "This PDU is reassembled in this frame", HFILL
}
5541 { &hf_dnp3_fragment_reassembled_length
,
5542 { "Reassembled DNP length", "dnp3.al.fragment.reassembled.length",
5543 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5544 "The total length of the reassembled payload", HFILL
}
5546 /* Generated from convert_proto_tree_add_text.pl */
5547 { &hf_dnp3_al_point_index
, { "Point Index", "dnp3.al.point_index", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
5548 { &hf_dnp3_al_da_value
, { "Value", "dnp3.al.da.value", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
5549 { &hf_dnp3_al_count
, { "Count", "dnp3.al.count", FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
5550 { &hf_dnp3_al_on_time
, { "On Time", "dnp3.al.on_time", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
5551 { &hf_dnp3_al_off_time
, { "Off Time", "dnp3.al.off_time", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
5552 { &hf_dnp3_al_time_delay
, { "Time Delay", "dnp3.al.time_delay", FT_UINT16
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_milliseconds
), 0x0, NULL
, HFILL
}},
5553 { &hf_dnp3_al_file_string_offset
, { "File String Offset", "dnp3.al.file_string_offset", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
5554 { &hf_dnp3_al_file_string_length
, { "File String Length", "dnp3.al.file_string_length", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
5555 { &hf_dnp3_al_file_name
, { "File Name", "dnp3.al.file_name", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
5556 { &hf_dnp3_al_octet_string
, { "Octet String", "dnp3.al.octet_string", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
5557 { &hf_dnp3_unknown_data_chunk
, { "Unknown Data Chunk", "dnp3.al.unknown_data_chunk", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
5561 /* Setup protocol subtree array */
5562 static int *ett
[] = {
5571 &ett_dnp3_al_obj_point_tcc
,
5574 &ett_dnp3_al_obj_qualifier
,
5575 &ett_dnp3_al_obj_range
,
5576 &ett_dnp3_al_objdet
,
5577 &ett_dnp3_al_obj_quality
,
5578 &ett_dnp3_al_obj_point
,
5579 &ett_dnp3_al_obj_point_perms
,
5583 static ei_register_info ei
[] = {
5584 { &ei_dnp_num_items_neg
, { "dnp3.num_items_neg", PI_MALFORMED
, PI_ERROR
, "Negative number of items", EXPFILL
}},
5585 { &ei_dnp_invalid_length
, { "dnp3.invalid_length", PI_MALFORMED
, PI_ERROR
, "Invalid length", EXPFILL
}},
5586 { &ei_dnp_iin_abnormal
, { "dnp3.iin_abnormal", PI_PROTOCOL
, PI_WARN
, "IIN Abnormality", EXPFILL
}},
5587 { &ei_dnp3_data_hdr_crc_incorrect
, { "dnp3.hdr.CRC.incorrect", PI_CHECKSUM
, PI_WARN
, "Data Link Header Checksum incorrect", EXPFILL
}},
5588 { &ei_dnp3_data_chunk_crc_incorrect
, { "dnp3.data_chunk.CRC.incorrect", PI_CHECKSUM
, PI_WARN
, "Data Chunk Checksum incorrect", EXPFILL
}},
5589 { &ei_dnp3_unknown_object
, { "dnp3.unknown_object", PI_PROTOCOL
, PI_WARN
, "Unknown Object\\Variation", EXPFILL
}},
5590 { &ei_dnp3_unknown_group0_variation
, { "dnp3.unknown_group0_variation", PI_PROTOCOL
, PI_WARN
, "Unknown Group 0 Variation", EXPFILL
}},
5591 { &ei_dnp3_num_items_invalid
, { "dnp3.num_items_invalid", PI_MALFORMED
, PI_ERROR
, "Number of items is invalid for normally empty object. Potentially malicious packet", EXPFILL
}},
5592 /* Generated from convert_proto_tree_add_text.pl */
5594 { &ei_dnp3_buffering_user_data_until_final_frame_is_received
, { "dnp3.buffering_user_data_until_final_frame_is_received", PI_PROTOCOL
, PI_WARN
, "Buffering User Data Until Final Frame is Received..", EXPFILL
}},
5598 module_t
*dnp3_module
;
5599 expert_module_t
* expert_dnp3
;
5601 reassembly_table_register(&al_reassembly_table
,
5602 &addresses_reassembly_table_functions
);
5604 /* Register the protocol name and description */
5605 proto_dnp3
= proto_register_protocol("Distributed Network Protocol 3.0", "DNP 3.0", "dnp3");
5607 /* Register the dissector so it may be used as a User DLT payload protocol */
5608 dnp3_tcp_handle
= register_dissector("dnp3.tcp", dissect_dnp3_tcp
, proto_dnp3
);
5609 dnp3_udp_handle
= register_dissector("dnp3.udp", dissect_dnp3_udp
, proto_dnp3
);
5611 /* Required function calls to register the header fields and subtrees used */
5612 proto_register_field_array(proto_dnp3
, hf
, array_length(hf
));
5613 proto_register_subtree_array(ett
, array_length(ett
));
5614 expert_dnp3
= expert_register_protocol(proto_dnp3
);
5615 expert_register_field_array(expert_dnp3
, ei
, array_length(ei
));
5617 dnp3_module
= prefs_register_protocol(proto_dnp3
, NULL
);
5618 prefs_register_obsolete_preference(dnp3_module
, "heuristics");
5619 prefs_register_bool_preference(dnp3_module
, "desegment",
5620 "Reassemble DNP3 messages spanning multiple TCP segments",
5621 "Whether the DNP3 dissector should reassemble messages spanning multiple TCP segments."
5622 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
5626 dnp3_tap
= register_tap("dnp3");
5628 register_conversation_table(proto_dnp3
, true, dnp3_conversation_packet
, dnp3_endpoint_packet
);
5632 proto_reg_handoff_dnp3(void)
5634 /* register as heuristic dissector for both TCP and UDP */
5635 heur_dissector_add("tcp", dissect_dnp3_tcp_heur
, "DNP 3.0 over TCP", "dnp3_tcp", proto_dnp3
, HEURISTIC_DISABLE
);
5636 heur_dissector_add("udp", dissect_dnp3_udp_heur
, "DNP 3.0 over UDP", "dnp3_udp", proto_dnp3
, HEURISTIC_DISABLE
);
5638 dissector_add_uint_with_preference("tcp.port", TCP_PORT_DNP
, dnp3_tcp_handle
);
5639 dissector_add_uint_with_preference("udp.port", UDP_PORT_DNP
, dnp3_udp_handle
);
5640 dissector_add_for_decode_as("rtacser.data", dnp3_udp_handle
);
5642 ssl_dissector_add(TCP_PORT_DNP_TLS
, dnp3_tcp_handle
);
5651 * indent-tabs-mode: nil
5654 * ex: set shiftwidth=2 tabstop=8 expandtab:
5655 * :indentSize=2:tabSize=8:noTabs=true: