Bug Summary

File:builds/wireshark/wireshark/epan/dissectors/packet-dnp.c
Warning:line 4085, column 14
Value stored to 'ext_seq' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name packet-dnp.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-18/lib/clang/18 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /usr/include/mit-krb5 -isystem /usr/include/libxml2 -isystem /builds/wireshark/wireshark/build/epan/dissectors -isystem /builds/wireshark/wireshark/epan/dissectors -isystem /builds/wireshark/wireshark/epan -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-truncation -Wno-format-nonliteral -Wno-pointer-sign -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -dwarf-debug-flags /usr/lib/llvm-18/bin/clang -### --analyze -x c -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /usr/include/mit-krb5 -isystem /usr/include/libxml2 -isystem /builds/wireshark/wireshark/build/epan/dissectors -isystem /builds/wireshark/wireshark/epan/dissectors -isystem /builds/wireshark/wireshark/epan -fvisibility=hidden -fexcess-precision=fast -fstrict-flex-arrays=3 -fstack-clash-protection -fcf-protection=full -D _GLIBCXX_ASSERTIONS -fstack-protector-strong -fno-delete-null-pointer-checks -fno-strict-overflow -fno-strict-aliasing -fexceptions -Wno-format-truncation -Wno-format-nonliteral -fdiagnostics-color=always -Wno-pointer-sign -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -std=gnu11 -fPIC /builds/wireshark/wireshark/epan/dissectors/packet-dnp.c -o /builds/wireshark/wireshark/sbout/2024-11-18-100252-3912-1 -Xclang -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2024-11-18-100252-3912-1 -x c /builds/wireshark/wireshark/epan/dissectors/packet-dnp.c
1/* packet-dnp.c
2 * Routines for DNP dissection
3 * Copyright 2003, 2006, 2007, 2013 Graham Bloice <graham.bloice<at>trihedral.com>
4 *
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
8 *
9 * Major updates: tcp and application layer defragmentation, more object dissections by Graham Bloice
10 *
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <[email protected]>
13 * Copyright 1998 Gerald Combs
14 *
15 * SPDX-License-Identifier: GPL-2.0-or-later
16 */
17
18#include "config.h"
19
20#include <math.h>
21
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>
30#include <epan/tfs.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>
37#include <epan/tap.h>
38#include <epan/conversation_table.h>
39#include "packet-tls.h"
40
41/*
42 * See
43 *
44 * http://www.dnp.org/
45 *
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
48 * dead-tree version.
49 *
50 * ...Application Layer Notes...
51 *
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
55 *
56 * ---------------------------------------------------------------------------
57 *
58 * Several command codes were missing, causing the dissector to abort decoding
59 * on valid packets. Those commands have been added.
60 *
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
66 * decode properly.
67 *
68 * Roy M. Silvernail <[email protected]> 01/05/2009
69 *
70 */
71
72/***************************************************************************/
73/* DNP 3.0 Constants */
74/***************************************************************************/
75#define DNP_HDR_LEN10 10
76#define TCP_PORT_DNP20000 20000
77#define UDP_PORT_DNP20000 20000
78#define TCP_PORT_DNP_TLS19999 19999
79
80/***************************************************************************/
81/* Datalink and Transport Layer Bit-Masks */
82/***************************************************************************/
83#define DNP3_CTL_DIR0x80 0x80
84#define DNP3_CTL_PRM0x40 0x40
85#define DNP3_CTL_FCB0x20 0x20
86#define DNP3_CTL_FCV0x10 0x10
87#define DNP3_CTL_RES0x20 0x20
88#define DNP3_CTL_DFC0x10 0x10
89#define DNP3_CTL_FUNC0x0f 0x0f
90
91#define DNP3_TR_FIR0x40 0x40
92#define DNP3_TR_FIN0x80 0x80
93#define DNP3_TR_SEQ0x3f 0x3f
94
95#define AL_MAX_CHUNK_SIZE16 16
96
97/***************************************************************************/
98/* Data Link Function codes */
99/***************************************************************************/
100/* Primary to Secondary */
101#define DL_FUNC_RESET_LINK0x00 0x00
102#define DL_FUNC_RESET_PROC0x01 0x01
103#define DL_FUNC_TEST_LINK0x02 0x02
104#define DL_FUNC_USER_DATA0x03 0x03
105#define DL_FUNC_UNC_DATA0x04 0x04
106#define DL_FUNC_LINK_STAT0x09 0x09
107
108/* Secondary to Primary */
109#define DL_FUNC_ACK0x00 0x00
110#define DL_FUNC_NACK0x01 0x01
111#define DL_FUNC_STAT_LINK0x0B 0x0B
112#define DL_FUNC_NO_FUNC0x0E 0x0E
113#define DL_FUNC_NOT_IMPL0x0F 0x0F
114
115/***************************************************************************/
116/* Application Layer Bit-Masks */
117/***************************************************************************/
118#define DNP3_AL_UNS0x10 0x10
119#define DNP3_AL_CON0x20 0x20
120#define DNP3_AL_FIN0x40 0x40
121#define DNP3_AL_FIR0x80 0x80
122#define DNP3_AL_SEQ0x0f 0x0f
123#define DNP3_AL_FUNC0xff 0xff
124
125/***************************************************************************/
126/* Application Layer Function codes */
127/***************************************************************************/
128#define AL_FUNC_CONFIRM0x00 0x00 /* 00 - Confirm */
129#define AL_FUNC_READ0x01 0x01 /* 01 - Read */
130#define AL_FUNC_WRITE0x02 0x02 /* 02 - Write */
131#define AL_FUNC_SELECT0x03 0x03 /* 03 - Select */
132#define AL_FUNC_OPERATE0x04 0x04 /* 04 - Operate */
133#define AL_FUNC_DIROP0x05 0x05 /* 05 - Direct Operate */
134#define AL_FUNC_DIROPNACK0x06 0x06 /* 06 - Direct Operate No ACK */
135#define AL_FUNC_FRZ0x07 0x07 /* 07 - Immediate Freeze */
136#define AL_FUNC_FRZNACK0x08 0x08 /* 08 - Immediate Freeze No ACK */
137#define AL_FUNC_FRZCLR0x09 0x09 /* 09 - Freeze and Clear */
138#define AL_FUNC_FRZCLRNACK0x0A 0x0A /* 10 - Freeze and Clear No ACK */
139#define AL_FUNC_FRZT0x0B 0x0B /* 11 - Freeze With Time */
140#define AL_FUNC_FRZTNACK0x0C 0x0C /* 12 - Freeze With Time No ACK */
141#define AL_FUNC_COLDRST0x0D 0x0D /* 13 - Cold Restart */
142#define AL_FUNC_WARMRST0x0E 0x0E /* 14 - Warm Restart */
143#define AL_FUNC_INITDATA0x0F 0x0F /* 15 - Initialize Data */
144#define AL_FUNC_INITAPP0x10 0x10 /* 16 - Initialize Application */
145#define AL_FUNC_STARTAPP0x11 0x11 /* 17 - Start Application */
146#define AL_FUNC_STOPAPP0x12 0x12 /* 18 - Stop Application */
147#define AL_FUNC_SAVECFG0x13 0x13 /* 19 - Save Configuration */
148#define AL_FUNC_ENSPMSG0x14 0x14 /* 20 - Enable Spontaneous Msg */
149#define AL_FUNC_DISSPMSG0x15 0x15 /* 21 - Disable Spontaneous Msg */
150#define AL_FUNC_ASSIGNCL0x16 0x16 /* 22 - Assign Classes */
151#define AL_FUNC_DELAYMST0x17 0x17 /* 23 - Delay Measurement */
152#define AL_FUNC_RECCT0x18 0x18 /* 24 - Record Current Time */
153#define AL_FUNC_OPENFILE0x19 0x19 /* 25 - Open File */
154#define AL_FUNC_CLOSEFILE0x1A 0x1A /* 26 - Close File */
155#define AL_FUNC_DELETEFILE0x1B 0x1B /* 27 - Delete File */
156#define AL_FUNC_GETFILEINF0x1C 0x1C /* 28 - Get File Info */
157#define AL_FUNC_AUTHFILE0x1D 0x1D /* 29 - Authenticate File */
158#define AL_FUNC_ABORTFILE0x1E 0x1E /* 30 - Abort File */
159#define AL_FUNC_ACTCNF0x1F 0x1F /* 31 - Activate Config */
160#define AL_FUNC_AUTHREQ0x20 0x20 /* 32 - Authentication Request */
161#define AL_FUNC_AUTHERR0x21 0x21 /* 33 - Authentication Error */
162#define AL_FUNC_RESPON0x81 0x81 /* 129 - Response */
163#define AL_FUNC_UNSOLI0x82 0x82 /* 130 - Unsolicited Response */
164#define AL_FUNC_AUTHRESP0x83 0x83 /* 131 - Authentication Response */
165
166/***************************************************************************/
167/* Application Layer Internal Indication (IIN) bits */
168/* 2 Bytes, message formatting: [First Octet] | [Second Octet] */
169/***************************************************************************/
170/* Octet 1 */
171#define AL_IIN_BMSG0x0100 0x0100 /* Bit 0 - Broadcast message rx'd */
172#define AL_IIN_CLS1D0x0200 0x0200 /* Bit 1 - Class 1 Data Available */
173#define AL_IIN_CLS2D0x0400 0x0400 /* Bit 2 - Class 2 Data Available */
174#define AL_IIN_CLS3D0x0800 0x0800 /* Bit 3 - Class 3 Data Available */
175#define AL_IIN_TSR0x1000 0x1000 /* Bit 4 - Time Sync Req'd from Master */
176#define AL_IIN_DOL0x2000 0x2000 /* Bit 5 - Outputs in Local Mode */
177#define AL_IIN_DT0x4000 0x4000 /* Bit 6 - Device Trouble */
178#define AL_IIN_RST0x8000 0x8000 /* Bit 7 - Device Restart */
179
180/* Octet 2 */
181#define AL_IIN_FCNI0x0001 0x0001 /* Bit 0 - Function code not implemented */
182#define AL_IIN_OBJU0x0002 0x0002 /* Bit 1 - Requested Objects Unknown */
183#define AL_IIN_PIOOR0x0004 0x0004 /* Bit 2 - Parameters Invalid or Out of Range */
184#define AL_IIN_EBO0x0008 0x0008 /* Bit 3 - Event Buffer Overflow */
185#define AL_IIN_OAE0x0010 0x0010 /* Bit 4 - Operation Already Executing */
186#define AL_IIN_CC0x0020 0x0020 /* Bit 5 - Device Configuration Corrupt */
187 /* 0x0040 Bit 6 - Reserved */
188 /* 0x0080 Bit 7 - Reserved */
189
190/***************************************************************************/
191/* Application Layer Data Object Qualifier */
192/***************************************************************************/
193/* Bit-Masks */
194#define AL_OBJQ_PREFIX0x70 0x70 /* x111xxxx Masks Prefix from Qualifier */
195#define AL_OBJQ_RANGE0x0F 0x0F /* xxxx1111 Masks Range from Qualifier */
196
197/* Index Size (3-bits x111xxxx) */
198/* When Qualifier Code != 11 */
199#define AL_OBJQL_PREFIX_NI0x00 0x00 /* Objects are Packed with no index */
200#define AL_OBJQL_PREFIX_1O0x01 0x01 /* Objects are prefixed w/ 1-octet index */
201#define AL_OBJQL_PREFIX_2O0x02 0x02 /* Objects are prefixed w/ 2-octet index */
202#define AL_OBJQL_PREFIX_4O0x03 0x03 /* Objects are prefixed w/ 4-octet index */
203#define AL_OBJQL_PREFIX_1OS0x04 0x04 /* Objects are prefixed w/ 1-octet object size */
204#define AL_OBJQL_PREFIX_2OS0x05 0x05 /* Objects are prefixed w/ 2-octet object size */
205#define AL_OBJQL_PREFIX_4OS0x06 0x06 /* Objects are prefixed w/ 4-octet object size */
206
207/* When Qualifier Code == 11 */
208#define AL_OBJQL_IDX11_1OIS0x01 0x01 /* 1 octet identifier size */
209#define AL_OBJQL_IDX11_2OIS0x02 0x02 /* 2 octet identifier size */
210#define AL_OBJQL_IDX11_4OIS0x03 0x03 /* 4 octet identifier size */
211
212/* Qualifier Code (4-bits) */
213/* 4-bits ( xxxx1111 ) */
214#define AL_OBJQL_RANGE_SSI80x00 0x00 /* 00 8-bit Start and Stop Indices in Range Field */
215#define AL_OBJQL_RANGE_SSI160x01 0x01 /* 01 16-bit Start and Stop Indices in Range Field */
216#define AL_OBJQL_RANGE_SSI320x02 0x02 /* 02 32-bit Start and Stop Indices in Range Field */
217#define AL_OBJQL_RANGE_AA80x03 0x03 /* 03 8-bit Absolute Address in Range Field */
218#define AL_OBJQL_RANGE_AA160x04 0x04 /* 04 16-bit Absolute Address in Range Field */
219#define AL_OBJQL_RANGE_AA320x05 0x05 /* 05 32-bit Absolute Address in Range Field */
220#define AL_OBJQL_RANGE_R00x06 0x06 /* 06 Length of Range field is 0 (no range field) */
221#define AL_OBJQL_RANGE_SF80x07 0x07 /* 07 8-bit Single Field Quantity */
222#define AL_OBJQL_RANGE_SF160x08 0x08 /* 08 16-bit Single Field Quantity */
223#define AL_OBJQL_RANGE_SF320x09 0x09 /* 09 32-bit Single Field Quantity */
224 /* 0x0A 10 Reserved */
225#define AL_OBJQL_RANGE_FF0x0B 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 */
230
231/***************************************************************************/
232/* Application Layer Data Object Definitions */
233/***************************************************************************/
234
235/* Masks for Object group and variation */
236#define AL_OBJ_GRP_MASK0xFF00 0xFF00
237#define AL_OBJ_VAR_MASK0x00FF 0x00FF
238
239/* Accessors for group and mask */
240#define AL_OBJ_GROUP(GV)(((GV) & 0xFF00) >> 8) (((GV) & AL_OBJ_GRP_MASK0xFF00) >> 8)
241#define AL_OBJ_VARIATION(GV)((GV) & 0x00FF) ((GV) & AL_OBJ_VAR_MASK0x00FF)
242
243/* Data Type values */
244#define AL_DATA_TYPE_NONE0x0 0x0
245#define AL_DATA_TYPE_VSTR0x1 0x1
246#define AL_DATA_TYPE_UINT0x2 0x2
247#define AL_DATA_TYPE_INT0x3 0x3
248#define AL_DATA_TYPE_FLT0x4 0x4
249#define AL_DATA_TYPE_OSTR0x5 0x5
250#define AL_DATA_TYPE_BSTR0x6 0x6
251#define AL_DATA_TYPE_TIME0x7 0x7
252#define AL_DATA_TYPE_UNCD0x8 0x8
253#define AL_DATA_TYPE_U8BS8LIST0xFE 0xFE
254#define AL_DATA_TYPE_U8BS8EXLIST0xFF 0xFF
255
256/* Device Attributes */
257#define AL_OBJ_DA_GRP0x0000 0x0000 /* 00 00 Device Attributes Group and null variation */
258#define AL_OBJ_DA_CFG_ID0x00C4 0x00C4 /* 00 196 Device Attributes - Configuration ID */
259#define AL_OBJ_DA_CFG_VER0x00C5 0x00C5 /* 00 197 Device Attributes - Configuration version */
260#define AL_OBJ_DA_CFG_BLD_DATE0x00C6 0x00C6 /* 00 198 Device Attributes - Configuration build date */
261#define AL_OBJ_DA_CFG_CHG_DATE0x00C7 0x00C7 /* 00 199 Device Attributes - Configuration last change date */
262#define AL_OBJ_DA_CFG_SIG0x00C8 0x00C8 /* 00 200 Device Attributes - Configuration signature */
263#define AL_OBJ_DA_CFG_SIG_ALG0x00C9 0x00C9 /* 00 201 Device Attributes - Configuration signature algorithm */
264#define AL_OBJ_DA_MRID0x00CA 0x00CA /* 00 202 Device Attributes - Master Resource ID (mRID) */
265#define AL_OBJ_DA_ALT0x00CB 0x00CB /* 00 203 Device Attributes - Device altitude */
266#define AL_OBJ_DA_LONG0x00CC 0x00CC /* 00 204 Device Attributes - Device longitude */
267#define AL_OBJ_DA_LAT0x00CD 0x00CD /* 00 205 Device Attributes - Device latitude */
268#define AL_OBJ_DA_SEC_OP0x00CE 0x00CE /* 00 206 Device Attributes - User-assigned secondary operator name */
269#define AL_OBJ_DA_PRM_OP0x00CF 0x00CF /* 00 207 Device Attributes - User-assigned primary operator name */
270#define AL_OBJ_DA_SYS_NAME0x00D0 0x00D0 /* 00 208 Device Attributes - User-assigned system name */
271#define AL_OBJ_DA_SEC_VER0x00D1 0x00D1 /* 00 209 Device Attributes - Secure authentication version */
272#define AL_OBJ_DA_SEC_STAT0x00D2 0x00D2 /* 00 210 Device Attributes - Number of security statistics per association */
273#define AL_OBJ_DA_USR_ATTR0x00D3 0x00D3 /* 00 211 Device Attributes - Identifier of support for user-specific attributes */
274#define AL_OBJ_DA_MSTR_DSP0x00D4 0x00D4 /* 00 212 Device Attributes - Number of master-defined data set prototypes */
275#define AL_OBJ_DA_OS_DSP0x00D5 0x00D5 /* 00 213 Device Attributes - Number of outstation-defined data set prototypes */
276#define AL_OBJ_DA_MSTR_DS0x00D6 0x00D6 /* 00 214 Device Attributes - Number of master-defined data sets */
277#define AL_OBJ_DA_OS_DS0x00D7 0x00D7 /* 00 215 Device Attributes - Number of outstation-defined data sets */
278#define AL_OBJ_DA_BO_REQ0x00D8 0x00D8 /* 00 216 Device Attributes - Max number of binary outputs per request */
279#define AL_OBJ_DA_LOC_TA0x00D9 0x00D9 /* 00 217 Device Attributes - Local timing accuracy */
280#define AL_OBJ_DA_DUR_TA0x00DA 0x00DA /* 00 218 Device Attributes - Duration of timing accuracy */
281#define AL_OBJ_DA_AO_EVT0x00DB 0x00DB /* 00 219 Device Attributes - Support for analog output events */
282#define AL_OBJ_DA_MAX_AO0x00DC 0x00DC /* 00 220 Device Attributes - Max analog output index */
283#define AL_OBJ_DA_NUM_AO0x00DD 0x00DD /* 00 221 Device Attributes - Number of analog outputs */
284#define AL_OBJ_DA_BO_EVT0x00DE 0x00DE /* 00 222 Device Attributes - Support for binary output events */
285#define AL_OBJ_DA_MAX_BO0x00DF 0x00DF /* 00 223 Device Attributes - Max binary output index */
286#define AL_OBJ_DA_NUM_BO0x00E0 0x00E0 /* 00 224 Device Attributes - Number of binary outputs */
287#define AL_OBJ_DA_FCTR_EVT0x00E1 0x00E1 /* 00 225 Device Attributes - Support for frozen counter events */
288#define AL_OBJ_DA_FCTR0x00E2 0x00E2 /* 00 226 Device Attributes - Support for frozen counters */
289#define AL_OBJ_DA_CTR_EVT0x00E3 0x00E3 /* 00 227 Device Attributes - Support for counter events */
290#define AL_OBJ_DA_MAX_CTR0x00E4 0x00E4 /* 00 228 Device Attributes - Max counter index */
291#define AL_OBJ_DA_NUM_CTR0x00E5 0x00E5 /* 00 229 Device Attributes - Number of counter points */
292#define AL_OBJ_DA_AIF0x00E6 0x00E6 /* 00 230 Device Attributes - Support for frozen analog inputs */
293#define AL_OBJ_DA_AI_EVT0x00E7 0x00E7 /* 00 231 Device Attributes - Support for analog input events */
294#define AL_OBJ_DA_MAX_AI0x00E8 0x00E8 /* 00 232 Device Attributes - Maximum analog input index */
295#define AL_OBJ_DA_NUM_AI0x00E9 0x00E9 /* 00 233 Device Attributes - Number of analog input points */
296#define AL_OBJ_DA_2BI_EVT0x00EA 0x00EA /* 00 234 Device Attributes - Support for Double-Bit BI Events */
297#define AL_OBJ_DA_MAX_2BI0x00EB 0x00EB /* 00 235 Device Attributes - Max Double-bit BI Point Index */
298#define AL_OBJ_DA_NUM_2BI0x00EC 0x00EC /* 00 236 Device Attributes - Number of Double-bit BI Points */
299#define AL_OBJ_DA_BI_EVT0x00ED 0x00ED /* 00 237 Device Attributes - Support for Binary Input Events */
300#define AL_OBJ_DA_MAX_BI0x00EE 0x00EE /* 00 238 Device Attributes - Max Binary Input Point Index */
301#define AL_OBJ_DA_NUM_BI0x00EF 0x00EF /* 00 239 Device Attributes - Number of Binary Input Points */
302#define AL_OBJ_DA_MXTX_FR0x00F0 0x00F0 /* 00 240 Device Attributes - Maximum Transmit Fragment Size */
303#define AL_OBJ_DA_MXRX_FR0x00F1 0x00F1 /* 00 241 Device Attributes - Maximum Receive Fragment Size */
304#define AL_OBJ_DA_SWVER0x00F2 0x00F2 /* 00 242 Device Attributes - Device Manufacturers SW Version */
305#define AL_OBJ_DA_HWVER0x00F3 0x00F3 /* 00 243 Device Attributes - Device Manufacturers HW Version */
306#define AL_OBJ_DA_OWNER0x00F4 0x00F4 /* 00 244 Device Attributes - User-assigned owner name */
307#define AL_OBJ_DA_LOC0x00F5 0x00F5 /* 00 245 Device Attributes - User-Assigned Location */
308#define AL_OBJ_DA_ID0x00F6 0x00F6 /* 00 246 Device Attributes - User-Assigned ID code/number */
309#define AL_OBJ_DA_DEVNAME0x00F7 0x00F7 /* 00 247 Device Attributes - User-Assigned Device Name */
310#define AL_OBJ_DA_SERNUM0x00F8 0x00F8 /* 00 248 Device Attributes - Device Serial Number */
311#define AL_OBJ_DA_CONF0x00F9 0x00F9 /* 00 249 Device Attributes - DNP Subset and Conformance */
312#define AL_OBJ_DA_PROD0x00FA 0x00FA /* 00 250 Device Attributes - Device Product Name and Model */
313 /* 00 251 Future Assignment */
314#define AL_OBJ_DA_MFG0x00FC 0x00FC /* 00 252 Device Attributes - Device Manufacturers Name */
315 /* 00 253 Future Assignment */
316#define AL_OBJ_DA_ALL0x00FE 0x00FE /* 00 254 Device Attributes - Non-specific All-attributes Req */
317#define AL_OBJ_DA_LVAR0x00FF 0x00FF /* 00 255 Device Attributes - List of Attribute Variations */
318
319/* Binary Input Objects */
320#define AL_OBJ_BI_ALL0x0100 0x0100 /* 01 00 Binary Input Default Variation */
321#define AL_OBJ_BI_1BIT0x0101 0x0101 /* 01 01 Single-bit Binary Input */
322#define AL_OBJ_BI_STAT0x0102 0x0102 /* 01 02 Binary Input With Status */
323#define AL_OBJ_BIC_ALL0x0200 0x0200 /* 02 00 Binary Input Change Default Variation */
324#define AL_OBJ_BIC_NOTIME0x0201 0x0201 /* 02 01 Binary Input Change Without Time */
325#define AL_OBJ_BIC_TIME0x0202 0x0202 /* 02 02 Binary Input Change With Time */
326#define AL_OBJ_BIC_RTIME0x0203 0x0203 /* 02 03 Binary Input Change With Relative Time */
327
328/* Double-bit Input Objects */
329#define AL_OBJ_2BI_ALL0x0300 0x0300 /* 03 00 Double-bit Input Default Variation */
330#define AL_OBJ_2BI_NF0x0301 0x0301 /* 03 01 Double-bit Input No Flags */
331#define AL_OBJ_2BI_STAT0x0302 0x0302 /* 03 02 Double-bit Input With Status */
332#define AL_OBJ_2BIC_ALL0x0400 0x0400 /* 04 00 Double-bit Input Change Default Variation */
333#define AL_OBJ_2BIC_NOTIME0x0401 0x0401 /* 04 01 Double-bit Input Change Without Time */
334#define AL_OBJ_2BIC_TIME0x0402 0x0402 /* 04 02 Double-bit Input Change With Time */
335#define AL_OBJ_2BIC_RTIME0x0403 0x0403 /* 04 03 Double-bit Input Change With Relative Time */
336
337/* Binary Input Quality Flags */
338#define AL_OBJ_BI_FLAG00x01 0x01 /* Point Online (0=Offline; 1=Online) */
339#define AL_OBJ_BI_FLAG10x02 0x02 /* Restart (0=Normal; 1=Restart) */
340#define AL_OBJ_BI_FLAG20x04 0x04 /* Comms Lost (0=Normal; 1=Lost) */
341#define AL_OBJ_BI_FLAG30x08 0x08 /* Remote Force (0=Normal; 1=Forced) */
342#define AL_OBJ_BI_FLAG40x10 0x10 /* Local Force (0=Normal; 1=Forced) */
343#define AL_OBJ_BI_FLAG50x20 0x20 /* Chatter Filter (0=Normal; 1=Filter On) */
344#define AL_OBJ_BI_FLAG60x40 0x40 /* Double-bit LSB (0=Off; 1=On) */
345#define AL_OBJ_BI_FLAG70x80 0x80 /* Point State (0=Off; 1=On) or Double-bit MSB */
346
347#define AL_OBJ_2BI_STATE_INTERMEDIATE0x00 0x00
348#define AL_OBJ_2BI_STATE_OFF0x01 0x01
349#define AL_OBJ_2BI_STATE_ON0x02 0x02
350#define AL_OBJ_2BI_STATE_INDETERM0x03 0x03
351
352#define AL_OBJ_DBI_MASK0xC0 0xC0 /* Double bit point state mask
353(0 = Intermediate, 1 = Determined off, 2 = Determined on, 3 = Indeterminate */
354
355/***************************************************************************/
356/* Binary Output Objects */
357#define AL_OBJ_BO_ALL0x0A00 0x0A00 /* 10 00 Binary Output Default Variation */
358#define AL_OBJ_BO0x0A01 0x0A01 /* 10 01 Binary Output */
359#define AL_OBJ_BO_STAT0x0A02 0x0A02 /* 10 02 Binary Output Status */
360#define AL_OBJ_BOC_ALL0x0B00 0x0B00 /* 11 00 Binary Output Change Default Variation */
361#define AL_OBJ_BOC_NOTIME0x0B01 0x0B01 /* 11 01 Binary Output Change Without Time */
362#define AL_OBJ_BOC_TIME0x0B02 0x0B02 /* 11 02 Binary Output Change With Time */
363#define AL_OBJ_CTLOP_BLK0x0C01 0x0C01 /* 12 01 Control Relay Output Block */
364#define AL_OBJ_CTL_PCB0x0C02 0x0C02 /* 12 02 Pattern Control Block */
365#define AL_OBJ_CTL_PMASK0x0C03 0x0C03 /* 12 03 Pattern Mask */
366#define AL_OBJ_BOE_NOTIME0x0D01 0x0D01 /* 13 01 Binary Output Command Event Without Time */
367#define AL_OBJ_BOE_TIME0x0D02 0x0D02 /* 13 02 Binary Output Command Event With Time */
368
369#define AL_OBJCTLC_CODE0x0F 0x0F /* Bit-Mask xxxx1111 for Control Code 'Code' */
370#define AL_OBJCTLC_MISC0x30 0x30 /* Bit-Mask xx11xxxx for Control Code Queue (obsolete) and Clear Fields */
371#define AL_OBJCTLC_TC0xC0 0xC0 /* Bit-Mask 11xxxxxx for Control Code 'Trip/Close' */
372
373#define AL_OBJCTLC_CODE00x00 0x00 /* xxxx0000 NUL Operation; only process R attribute */
374#define AL_OBJCTLC_CODE10x01 0x01 /* xxxx0001 Pulse On ^On-Time -> vOff-Time, remain off */
375#define AL_OBJCTLC_CODE20x02 0x02 /* xxxx0010 Pulse Off vOff-Time -> ^On-Time, remain on */
376#define AL_OBJCTLC_CODE30x03 0x03 /* xxxx0011 Latch On */
377#define AL_OBJCTLC_CODE40x04 0x04 /* xxxx0100 Latch Off */
378 /* 0x05-0x15 Reserved */
379
380#define AL_OBJCTLC_NOTSET0x00 0x00 /* xx00xxxx for Control Code, Clear and Queue not set */
381#define AL_OBJCTLC_QUEUE0x01 0x01 /* xxx1xxxx for Control Code, Clear Field 'Queue' */
382#define AL_OBJCTLC_CLEAR0x02 0x02 /* xx1xxxxx for Control Code, Clear Field 'Clear' */
383#define AL_OBJCTLC_BOTHSET0x03 0x03 /* xx11xxxx for Control Code, Clear and Queue both set */
384
385#define AL_OBJCTLC_TC00x00 0x00 /* 00xxxxxx NUL */
386#define AL_OBJCTLC_TC10x01 0x01 /* 01xxxxxx Close */
387#define AL_OBJCTLC_TC20x02 0x02 /* 10xxxxxx Trip */
388#define AL_OBJCTLC_TC30x03 0x03 /* 11xxxxxx Reserved */
389
390#define AL_OBJCTL_STAT00x00 0x00 /* Request Accepted, Initiated or Queued */
391#define AL_OBJCTL_STAT10x01 0x01 /* Request Not Accepted; Arm-timer expired */
392#define AL_OBJCTL_STAT20x02 0x02 /* Request Not Accepted; No 'SELECT' rx'd */
393#define AL_OBJCTL_STAT30x03 0x03 /* Request Not Accepted; Format errors in ctrl request */
394#define AL_OBJCTL_STAT40x04 0x04 /* Control Operation Not Supported for this point */
395#define AL_OBJCTL_STAT50x05 0x05 /* Request Not Accepted; Ctrl Queue full or pt. active */
396#define AL_OBJCTL_STAT60x06 0x06 /* Request Not Accepted; Ctrl HW Problems */
397#define AL_OBJCTL_STAT70x07 0x07 /* Request Not Accepted; Local/Remote switch in Local*/
398#define AL_OBJCTL_STAT80x08 0x08 /* Request Not Accepted; Too many operations requested */
399#define AL_OBJCTL_STAT90x09 0x09 /* Request Not Accepted; Insufficient authorization */
400#define AL_OBJCTL_STAT100x0A 0x0A /* Request Not Accepted; Local automation proc active */
401#define AL_OBJCTL_STAT110x0B 0x0B /* Request Not Accepted; Processing limited */
402#define AL_OBJCTL_STAT120x0C 0x0C /* Request Not Accepted; Out of range value */
403#define AL_OBJCTL_STAT1260x7E 0x7E /* Non Participating (NOP request) */
404#define AL_OBJCTL_STAT1270x7F 0x7F /* Request Not Accepted; Undefined error */
405
406#define AL_OBJCTL_STATUS_MASK0x7F 0x7F
407
408/* Binary Output Quality Flags */
409#define AL_OBJ_BO_FLAG00x01 0x01 /* Point Online (0=Offline; 1=Online) */
410#define AL_OBJ_BO_FLAG10x02 0x02 /* Restart (0=Normal; 1=Restart) */
411#define AL_OBJ_BO_FLAG20x04 0x04 /* Comms Lost (0=Normal; 1=Lost) */
412#define AL_OBJ_BO_FLAG30x08 0x08 /* Remote Force (0=Normal; 1=Forced) */
413#define AL_OBJ_BO_FLAG40x10 0x10 /* Local Force (0=Normal; 1=Forced) */
414#define AL_OBJ_BO_FLAG50x20 0x20 /* Reserved */
415#define AL_OBJ_BO_FLAG60x40 0x40 /* Reserved */
416#define AL_OBJ_BO_FLAG70x80 0x80 /* Point State (0=Off; 1=On) */
417
418/***************************************************************************/
419/* Counter Objects */
420#define AL_OBJ_CTR_ALL0x1400 0x1400 /* 20 00 Binary Counter Default Variation */
421#define AL_OBJ_CTR_320x1401 0x1401 /* 20 01 32-Bit Binary Counter */
422#define AL_OBJ_CTR_160x1402 0x1402 /* 20 02 16-Bit Binary Counter */
423#define AL_OBJ_DCTR_320x1403 0x1403 /* 20 03 32-Bit Delta Counter */
424#define AL_OBJ_DCTR_160x1404 0x1404 /* 20 04 16-Bit Delta Counter */
425#define AL_OBJ_CTR_32NF0x1405 0x1405 /* 20 05 32-Bit Binary Counter Without Flag */
426#define AL_OBJ_CTR_16NF0x1406 0x1406 /* 20 06 16-Bit Binary Counter Without Flag */
427#define AL_OBJ_DCTR_32NF0x1407 0x1407 /* 20 07 32-Bit Delta Counter Without Flag */
428#define AL_OBJ_DCTR_16NF0x1408 0x1408 /* 20 08 16-Bit Delta Counter Without Flag */
429#define AL_OBJ_FCTR_ALL0x1500 0x1500 /* 21 00 Frozen Binary Counter Default Variation */
430#define AL_OBJ_FCTR_320x1501 0x1501 /* 21 01 32-Bit Frozen Counter */
431#define AL_OBJ_FCTR_160x1502 0x1502 /* 21 02 16-Bit Frozen Counter */
432#define AL_OBJ_FDCTR_320x1503 0x1503 /* 21 03 32-Bit Frozen Delta Counter */
433#define AL_OBJ_FDCTR_160x1504 0x1504 /* 21 04 16-Bit Frozen Delta Counter */
434#define AL_OBJ_FCTR_32T0x1505 0x1505 /* 21 05 32-Bit Frozen Counter w/ Time of Freeze */
435#define AL_OBJ_FCTR_16T0x1506 0x1506 /* 21 06 16-Bit Frozen Counter w/ Time of Freeze */
436#define AL_OBJ_FDCTR_32T0x1507 0x1507 /* 21 07 32-Bit Frozen Delta Counter w/ Time of Freeze */
437#define AL_OBJ_FDCTR_16T0x1508 0x1508 /* 21 08 16-Bit Frozen Delta Counter w/ Time of Freeze */
438#define AL_OBJ_FCTR_32NF0x1509 0x1509 /* 21 09 32-Bit Frozen Counter Without Flag */
439#define AL_OBJ_FCTR_16NF0x150A 0x150A /* 21 10 16-Bit Frozen Counter Without Flag */
440#define AL_OBJ_FDCTR_32NF0x150B 0x150B /* 21 11 32-Bit Frozen Delta Counter Without Flag */
441#define AL_OBJ_FDCTR_16NF0x150C 0x150C /* 21 12 16-Bit Frozen Delta Counter Without Flag */
442#define AL_OBJ_CTRC_ALL0x1600 0x1600 /* 22 00 Counter Change Event Default Variation */
443#define AL_OBJ_CTRC_320x1601 0x1601 /* 22 01 32-Bit Counter Change Event w/o Time */
444#define AL_OBJ_CTRC_160x1602 0x1602 /* 22 02 16-Bit Counter Change Event w/o Time */
445#define AL_OBJ_DCTRC_320x1603 0x1603 /* 22 03 32-Bit Delta Counter Change Event w/o Time */
446#define AL_OBJ_DCTRC_160x1604 0x1604 /* 22 04 16-Bit Delta Counter Change Event w/o Time */
447#define AL_OBJ_CTRC_32T0x1605 0x1605 /* 22 05 32-Bit Counter Change Event with Time */
448#define AL_OBJ_CTRC_16T0x1606 0x1606 /* 22 06 16-Bit Counter Change Event with Time */
449#define AL_OBJ_DCTRC_32T0x1607 0x1607 /* 22 07 32-Bit Delta Counter Change Event with Time */
450#define AL_OBJ_DCTRC_16T0x1608 0x1608 /* 22 08 16-Bit Delta Counter Change Event with Time */
451#define AL_OBJ_FCTRC_ALL0x1700 0x1700 /* 23 00 Frozen Binary Counter Change Event Default Variation */
452#define AL_OBJ_FCTRC_320x1701 0x1701 /* 23 01 32-Bit Frozen Counter Change Event */
453#define AL_OBJ_FCTRC_160x1702 0x1702 /* 23 02 16-Bit Frozen Counter Change Event */
454#define AL_OBJ_FDCTRC_320x1703 0x1703 /* 23 03 32-Bit Frozen Delta Counter Change Event */
455#define AL_OBJ_FDCTRC_160x1704 0x1704 /* 23 04 16-Bit Frozen Delta Counter Change Event */
456#define AL_OBJ_FCTRC_32T0x1705 0x1705 /* 23 05 32-Bit Frozen Counter Change Event w/ Time of Freeze */
457#define AL_OBJ_FCTRC_16T0x1706 0x1706 /* 23 06 16-Bit Frozen Counter Change Event w/ Time of Freeze */
458#define AL_OBJ_FDCTRC_32T0x1707 0x1707 /* 23 07 32-Bit Frozen Delta Counter Change Event w/ Time of Freeze */
459#define AL_OBJ_FDCTRC_16T0x1708 0x1708 /* 23 08 16-Bit Frozen Delta Counter Change Event w/ Time of Freeze */
460
461/* Counter Quality Flags */
462#define AL_OBJ_CTR_FLAG00x01 0x01 /* Point Online (0=Offline; 1=Online) */
463#define AL_OBJ_CTR_FLAG10x02 0x02 /* Restart (0=Normal; 1=Restart) */
464#define AL_OBJ_CTR_FLAG20x04 0x04 /* Comms Lost (0=Normal; 1=Lost) */
465#define AL_OBJ_CTR_FLAG30x08 0x08 /* Remote Force (0=Normal; 1=Forced) */
466#define AL_OBJ_CTR_FLAG40x10 0x10 /* Local Force (0=Normal; 1=Forced) */
467#define AL_OBJ_CTR_FLAG50x20 0x20 /* Roll-over (0=Normal; 1=Roll-Over) */
468#define AL_OBJ_CTR_FLAG60x40 0x40 /* Discontinuity (0=Normal; 1=Discontinuity) */
469#define AL_OBJ_CTR_FLAG70x80 0x80 /* Reserved */
470
471/***************************************************************************/
472/* Analog Input Objects */
473#define AL_OBJ_AI_ALL0x1E00 0x1E00 /* 30 00 Analog Input Default Variation */
474#define AL_OBJ_AI_320x1E01 0x1E01 /* 30 01 32-Bit Analog Input */
475#define AL_OBJ_AI_160x1E02 0x1E02 /* 30 02 16-Bit Analog Input */
476#define AL_OBJ_AI_32NF0x1E03 0x1E03 /* 30 03 32-Bit Analog Input Without Flag */
477#define AL_OBJ_AI_16NF0x1E04 0x1E04 /* 30 04 16-Bit Analog Input Without Flag */
478#define AL_OBJ_AI_FLT0x1E05 0x1E05 /* 30 05 32-Bit Floating Point Input */
479#define AL_OBJ_AI_DBL0x1E06 0x1E06 /* 30 06 64-Bit Floating Point Input */
480#define AL_OBJ_AIFC_320x1F01 0x1F01 /* 31 01 32-Bit Frozen Analog Input */
481#define AL_OBJ_AIFC_160x1F02 0x1F02 /* 31 02 16-Bit Frozen Analog Input */
482#define AL_OBJ_AIFC_32TOF0x1F03 0x1F03 /* 31 03 32-Bit Frozen Analog Input w/ Time of Freeze */
483#define AL_OBJ_AIFC_16TOF0x1F04 0x1F04 /* 31 04 16-Bit Frozen Analog Input w/ Time of Freeze */
484#define AL_OBJ_AIFC_32NF0x1F05 0x1F05 /* 31 05 32-Bit Frozen Analog Input Without Flag */
485#define AL_OBJ_AIFC_16NF0x1F06 0x1F06 /* 31 06 16-Bit Frozen Analog Input Without Flag */
486#define AL_OBJ_AIF_FLT0x1F07 0x1F07 /* 31 07 32-Bit Frozen Floating Point Input */
487#define AL_OBJ_AIF_DBL0x1F08 0x1F08 /* 31 08 64-Bit Frozen Floating Point Input */
488#define AL_OBJ_AIC_ALL0x2000 0x2000 /* 32 00 Analog Input Change Default Variation */
489#define AL_OBJ_AIC_32NT0x2001 0x2001 /* 32 01 32-Bit Analog Change Event w/o Time */
490#define AL_OBJ_AIC_16NT0x2002 0x2002 /* 32 02 16-Bit Analog Change Event w/o Time */
491#define AL_OBJ_AIC_32T0x2003 0x2003 /* 32 03 32-Bit Analog Change Event w/ Time */
492#define AL_OBJ_AIC_16T0x2004 0x2004 /* 32 04 16-Bit Analog Change Event w/ Time */
493#define AL_OBJ_AIC_FLTNT0x2005 0x2005 /* 32 05 32-Bit Floating Point Change Event w/o Time*/
494#define AL_OBJ_AIC_DBLNT0x2006 0x2006 /* 32 06 64-Bit Floating Point Change Event w/o Time*/
495#define AL_OBJ_AIC_FLTT0x2007 0x2007 /* 32 07 32-Bit Floating Point Change Event w/ Time*/
496#define AL_OBJ_AIC_DBLT0x2008 0x2008 /* 32 08 64-Bit Floating Point Change Event w/ Time*/
497#define AL_OBJ_AIFC_32NT0x2101 0x2101 /* 33 01 32-Bit Frozen Analog Event w/o Time */
498#define AL_OBJ_AIFC_16NT0x2102 0x2102 /* 33 02 16-Bit Frozen Analog Event w/o Time */
499#define AL_OBJ_AIFC_32T0x2103 0x2103 /* 33 03 32-Bit Frozen Analog Event w/ Time */
500#define AL_OBJ_AIFC_16T0x2104 0x2104 /* 33 04 16-Bit Frozen Analog Event w/ Time */
501#define AL_OBJ_AIFC_FLTNT0x2105 0x2105 /* 33 05 32-Bit Floating Point Frozen Change Event w/o Time*/
502#define AL_OBJ_AIFC_DBLNT0x2106 0x2106 /* 33 06 64-Bit Floating Point Frozen Change Event w/o Time*/
503#define AL_OBJ_AIFC_FLTT0x2107 0x2107 /* 33 07 32-Bit Floating Point Frozen Change Event w/ Time*/
504#define AL_OBJ_AIFC_DBLT0x2108 0x2108 /* 33 08 64-Bit Floating Point Frozen Change Event w/ Time*/
505
506/* Analog Input Quality Flags */
507#define AL_OBJ_AI_FLAG00x01 0x01 /* Point Online (0=Offline; 1=Online) */
508#define AL_OBJ_AI_FLAG10x02 0x02 /* Restart (0=Normal; 1=Restart) */
509#define AL_OBJ_AI_FLAG20x04 0x04 /* Comms Lost (0=Normal; 1=Lost) */
510#define AL_OBJ_AI_FLAG30x08 0x08 /* Remote Force (0=Normal; 1=Forced) */
511#define AL_OBJ_AI_FLAG40x10 0x10 /* Local Force (0=Normal; 1=Forced) */
512#define AL_OBJ_AI_FLAG50x20 0x20 /* Over-Range (0=Normal; 1=Over-Range) */
513#define AL_OBJ_AI_FLAG60x40 0x40 /* Reference Check (0=Normal; 1=Error) */
514#define AL_OBJ_AI_FLAG70x80 0x80 /* Reserved */
515
516#define AL_OBJ_AIDB_ALL0x2200 0x2200 /* 34 00 Analog Input Deadband Default Variation */
517#define AL_OBJ_AIDB_160x2201 0x2201 /* 34 01 16-Bit Analog Input Deadband */
518#define AL_OBJ_AIDB_320x2202 0x2202 /* 34 02 32-Bit Analog Input Deadband */
519#define AL_OBJ_AIDB_FLT0x2203 0x2203 /* 34 03 Floating Point Analog Input Deadband */
520
521/***************************************************************************/
522/* Analog Output Objects */
523#define AL_OBJ_AO_ALL0x2800 0x2800 /* 40 00 Analog Output Default Variation */
524#define AL_OBJ_AO_320x2801 0x2801 /* 40 01 32-Bit Analog Output Status */
525#define AL_OBJ_AO_160x2802 0x2802 /* 40 02 16-Bit Analog Output Status */
526#define AL_OBJ_AO_FLT0x2803 0x2803 /* 40 03 32-Bit Floating Point Output Status */
527#define AL_OBJ_AO_DBL0x2804 0x2804 /* 40 04 64-Bit Floating Point Output Status */
528#define AL_OBJ_AO_32OPB0x2901 0x2901 /* 41 01 32-Bit Analog Output Block */
529#define AL_OBJ_AO_16OPB0x2902 0x2902 /* 41 02 16-Bit Analog Output Block */
530#define AL_OBJ_AO_FLTOPB0x2903 0x2903 /* 41 03 32-Bit Floating Point Output Block */
531#define AL_OBJ_AO_DBLOPB0x2904 0x2904 /* 41 04 64-Bit Floating Point Output Block */
532#define AL_OBJ_AOC_ALL0x2A00 0x2A00 /* 42 00 Analog Output Event Default Variation */
533#define AL_OBJ_AOC_32NT0x2A01 0x2A01 /* 42 01 32-Bit Analog Output Event w/o Time */
534#define AL_OBJ_AOC_16NT0x2A02 0x2A02 /* 42 02 16-Bit Analog Output Event w/o Time */
535#define AL_OBJ_AOC_32T0x2A03 0x2A03 /* 42 03 32-Bit Analog Output Event w/ Time */
536#define AL_OBJ_AOC_16T0x2A04 0x2A04 /* 42 04 16-Bit Analog Output Event w/ Time */
537#define AL_OBJ_AOC_FLTNT0x2A05 0x2A05 /* 42 05 32-Bit Floating Point Output Event w/o Time */
538#define AL_OBJ_AOC_DBLNT0x2A06 0x2A06 /* 42 06 64-Bit Floating Point Output Event w/o Time */
539#define AL_OBJ_AOC_FLTT0x2A07 0x2A07 /* 42 07 32-Bit Floating Point Output Event w/ Time */
540#define AL_OBJ_AOC_DBLT0x2A08 0x2A08 /* 42 08 64-Bit Floating Point Output Event w/ Time */
541#define AL_OBJ_AOC_32EVNT0x2B01 0x2B01 /* 43 01 32-Bit Analog Output Command Event w/o Time */
542#define AL_OBJ_AOC_16EVNT0x2B02 0x2B02 /* 43 02 16-Bit Analog Output Command Event w/o Time */
543#define AL_OBJ_AOC_32EVTT0x2B03 0x2B03 /* 43 03 32-Bit Analog Output Command Event w/ Time */
544#define AL_OBJ_AOC_16EVTT0x2B04 0x2B04 /* 43 04 16-Bit Analog Output Command Event w/ Time */
545#define AL_OBJ_AOC_FLTEVNT0x2B05 0x2B05 /* 43 05 32-Bit Floating Point Analog Output Command Event w/o Time */
546#define AL_OBJ_AOC_DBLEVNT0x2B06 0x2B06 /* 43 06 64-Bit Floating PointAnalog Output Command Event w/o Time */
547#define AL_OBJ_AOC_FLTEVTT0x2B07 0x2B07 /* 43 07 32-Bit Floating Point Analog Output Command Event w/ Time */
548#define AL_OBJ_AOC_DBLEVTT0x2B08 0x2B08 /* 43 08 64-Bit Floating PointAnalog Output Command Event w/ Time */
549
550/* Analog Output Quality Flags */
551#define AL_OBJ_AO_FLAG00x01 0x01 /* Point Online (0=Offline; 1=Online) */
552#define AL_OBJ_AO_FLAG10x02 0x02 /* Restart (0=Normal; 1=Restart) */
553#define AL_OBJ_AO_FLAG20x04 0x04 /* Comms Lost (0=Normal; 1=Lost) */
554#define AL_OBJ_AO_FLAG30x08 0x08 /* Remote Force (0=Normal; 1=Forced) */
555#define AL_OBJ_AO_FLAG40x10 0x10 /* Local Force (0=Normal; 1=Forced) */
556#define AL_OBJ_AO_FLAG50x20 0x20 /* Reserved */
557#define AL_OBJ_AO_FLAG60x40 0x40 /* Reserved */
558#define AL_OBJ_AO_FLAG70x80 0x80 /* Reserved */
559
560/***************************************************************************/
561/* Time Objects */
562#define AL_OBJ_TD_ALL0x3200 0x3200 /* 50 00 Time and Date Default Variation */
563#define AL_OBJ_TD0x3201 0x3201 /* 50 01 Time and Date */
564#define AL_OBJ_TDI0x3202 0x3202 /* 50 02 Time and Date w/ Interval */
565#define AL_OBJ_TDR0x3203 0x3203 /* 50 03 Last Recorded Time and Date */
566#define AL_OBJ_TDCTO0x3301 0x3301 /* 51 01 Time and Date CTO */
567#define AL_OBJ_UTDCTO0x3302 0x3302 /* 51 02 Unsynchronized Time and Date CTO */
568#define AL_OBJ_TDELAYC0x3401 0x3401 /* 52 01 Time Delay Coarse */
569#define AL_OBJ_TDELAYF0x3402 0x3402 /* 52 02 Time Delay Fine */
570
571/***************************************************************************/
572/* Class Data Objects */
573#define AL_OBJ_CLASS00x3C01 0x3C01 /* 60 01 Class 0 Data */
574#define AL_OBJ_CLASS10x3C02 0x3C02 /* 60 02 Class 1 Data */
575#define AL_OBJ_CLASS20x3C03 0x3C03 /* 60 03 Class 2 Data */
576#define AL_OBJ_CLASS30x3C04 0x3C04 /* 60 04 Class 3 Data */
577
578/***************************************************************************/
579/* File Objects */
580#define AL_OBJ_FILE_CMD0x4603 0x4603 /* 70 03 File Control - Command */
581#define AL_OBJ_FILE_STAT0x4604 0x4604 /* 70 04 File Control - Status */
582#define AL_OBJ_FILE_TRANS0x4605 0x4605 /* 70 05 File Control - Transport */
583#define AL_OBJ_FILE_TRAN_ST0x4606 0x4606 /* 70 05 File Control - Transport Status */
584
585/* File Control Mode flags */
586#define AL_OBJ_FILE_MODE_NULL0x00 0x00 /* NULL */
587#define AL_OBJ_FILE_MODE_READ0x01 0x01 /* READ */
588#define AL_OBJ_FILE_MODE_WRITE0x02 0x02 /* WRITE */
589#define AL_OBJ_FILE_MODE_APPEND0x03 0x03 /* APPEND */
590
591/***************************************************************************/
592/* Device Objects */
593#define AL_OBJ_IIN0x5001 0x5001 /* 80 01 Internal Indications */
594
595/***************************************************************************/
596/* Data Sets */
597#define AL_OBJ_DS_PROTO0x5501 0x5501 /* 85 01 Data-Set Prototype, with UUID */
598#define AL_OBJ_DSD_CONT0x5601 0x5601 /* 86 01 Data-Set Descriptor, Data-Set Contents */
599#define AL_OBJ_DSD_CHAR0x5602 0x5602 /* 86 02 Data-Set Descriptor, Characteristics */
600#define AL_OBJ_DSD_PIDX0x5603 0x5603 /* 86 03 Data-Set Descriptor, Point Index Attributes */
601#define AL_OBJ_DS_PV0x5701 0x5701 /* 87 01 Data-Set, Present Value */
602#define AL_OBJ_DS_SS0x5801 0x5801 /* 88 01 Data-Set, Snapshot */
603
604/***************************************************************************/
605/* Octet String Objects */
606#define AL_OBJ_OCT0x6E00 0x6E00 /* 110 xx Octet string */
607#define AL_OBJ_OCT_EVT0x6F00 0x6F00 /* 111 xx Octet string event */
608
609/***************************************************************************/
610/* Virtual Terminal Objects */
611#define AL_OBJ_VT_OBLK0x7000 0x7000 /* 112 xx Virtual Terminal Output Block */
612#define AL_OBJ_VT_EVTD0x7100 0x7100 /* 113 xx Virtual Terminal Event Data */
613
614/***************************************************************************/
615/* Secure Authentication ('SA') Objects */
616#define AL_OBJ_SA_AUTH_CH0x7801 0x7801 /* 120 01 Authentication Challenge */
617#define AL_OBJ_SA_AUTH_RP0x7802 0x7802 /* 120 02 Authentication Reply */
618#define AL_OBJ_SA_AUTH_AGMRQ0x7803 0x7803 /* 120 03 Authentication Aggressive Mode Request */
619#define AL_OBJ_SA_AUTH_SKSR0x7804 0x7804 /* 120 04 Authentication Session Key Status Request */
620#define AL_OBJ_SA_AUTH_SKS0x7805 0x7805 /* 120 05 Authentication Session Key Status */
621#define AL_OBJ_SA_AUTH_SKC0x7806 0x7806 /* 120 06 Authentication Session Key Change */
622#define AL_OBJ_SA_AUTH_ERR0x7807 0x7807 /* 120 07 Authentication Error */
623#define AL_OBJ_SA_AUTH_MAC0x7809 0x7809 /* 120 09 Authentication Message Authentication Code */
624#define AL_OBJ_SA_AUTH_USC0x780A 0x780A /* 120 10 Authentication User Status Change - Not supported */
625#define AL_OBJ_SA_AUTH_UKCR0x780B 0x780B /* 120 11 Authentication Update Key Change Request */
626#define AL_OBJ_SA_AUTH_UKCRP0x780C 0x780C /* 120 12 Authentication Update Key Change Reply */
627#define AL_OBJ_SA_AUTH_UKC0x780D 0x780D /* 120 13 Authentication Update Key Change */
628#define AL_OBJ_SA_AUTH_UKCC0x780F 0x780F /* 120 15 Authentication Update Key Change Confirmation */
629#define AL_OBJ_SA_SECSTAT0x7901 0x7901 /* 121 01 Security Statistics */
630#define AL_OBJ_SA_SECSTATEVT0x7A01 0x7A01 /* 122 01 Security Statistic Event */
631#define AL_OBJ_SA_SECSTATEVTT0x7A02 0x7A02 /* 122 02 Security Statistic Event w/ Time */
632
633
634/***************************************************************************/
635/* End of Application Layer Data Object Definitions */
636/***************************************************************************/
637
638void proto_register_dnp3(void);
639void proto_reg_handoff_dnp3(void);
640
641/* Initialize the protocol and registered fields */
642static int proto_dnp3;
643static int hf_dnp3_start;
644static int hf_dnp3_len;
645static int hf_dnp3_ctl;
646static int hf_dnp3_ctl_prifunc;
647static int hf_dnp3_ctl_secfunc;
648static int hf_dnp3_ctl_dir;
649static int hf_dnp3_ctl_prm;
650static int hf_dnp3_ctl_fcb;
651static int hf_dnp3_ctl_fcv;
652static int hf_dnp3_ctl_dfc;
653static int hf_dnp3_dst;
654static int hf_dnp3_src;
655static int hf_dnp3_addr;
656static int hf_dnp3_data_hdr_crc;
657static int hf_dnp3_data_hdr_crc_status;
658static int hf_dnp3_tr_ctl;
659static int hf_dnp3_tr_fin;
660static int hf_dnp3_tr_fir;
661static int hf_dnp3_tr_seq;
662static int hf_dnp3_data_chunk;
663static int hf_dnp3_data_chunk_len;
664static int hf_dnp3_data_chunk_crc;
665static int hf_dnp3_data_chunk_crc_status;
666
667/* Added for Application Layer Decoding */
668static int hf_dnp3_al_ctl;
669static int hf_dnp3_al_fir;
670static int hf_dnp3_al_fin;
671static int hf_dnp3_al_con;
672static int hf_dnp3_al_uns;
673static int hf_dnp3_al_seq;
674static int hf_dnp3_al_func;
675static int hf_dnp3_al_iin;
676static int hf_dnp3_al_iin_bmsg;
677static int hf_dnp3_al_iin_cls1d;
678static int hf_dnp3_al_iin_cls2d;
679static int hf_dnp3_al_iin_cls3d;
680static int hf_dnp3_al_iin_tsr;
681static int hf_dnp3_al_iin_dol;
682static int hf_dnp3_al_iin_dt;
683static int hf_dnp3_al_iin_rst;
684static int hf_dnp3_al_iin_fcni;
685static int hf_dnp3_al_iin_obju;
686static int hf_dnp3_al_iin_pioor;
687static int hf_dnp3_al_iin_ebo;
688static int hf_dnp3_al_iin_oae;
689static int hf_dnp3_al_iin_cc;
690static int hf_dnp3_al_obj;
691static int hf_dnp3_al_objq_prefix;
692static int hf_dnp3_al_objq_range;
693static int hf_dnp3_al_range_start8;
694static int hf_dnp3_al_range_stop8;
695static int hf_dnp3_al_range_start16;
696static int hf_dnp3_al_range_stop16;
697static int hf_dnp3_al_range_start32;
698static int hf_dnp3_al_range_stop32;
699static int hf_dnp3_al_range_abs8;
700static int hf_dnp3_al_range_abs16;
701static int hf_dnp3_al_range_abs32;
702static int hf_dnp3_al_range_quant8;
703static int hf_dnp3_al_range_quant16;
704static int hf_dnp3_al_range_quant32;
705static int hf_dnp3_al_index8;
706static int hf_dnp3_al_index16;
707static int hf_dnp3_al_index32;
708static int hf_dnp3_al_size8;
709static int hf_dnp3_al_size16;
710static int hf_dnp3_al_size32;
711static int hf_dnp3_bocs_bit;
712
713/* static int hf_dnp3_al_objq;*/
714/* static int hf_dnp3_al_nobj; */
715/* XXX - unused
716static int hf_dnp3_al_ptnum; */
717static int hf_dnp3_al_biq_b0;
718static int hf_dnp3_al_biq_b1;
719static int hf_dnp3_al_biq_b2;
720static int hf_dnp3_al_biq_b3;
721static int hf_dnp3_al_biq_b4;
722static int hf_dnp3_al_biq_b5;
723static int hf_dnp3_al_biq_b6;
724static int hf_dnp3_al_biq_b7;
725static int hf_dnp3_al_boq_b0;
726static int hf_dnp3_al_boq_b1;
727static int hf_dnp3_al_boq_b2;
728static int hf_dnp3_al_boq_b3;
729static int hf_dnp3_al_boq_b4;
730static int hf_dnp3_al_boq_b5;
731static int hf_dnp3_al_boq_b6;
732static int hf_dnp3_al_boq_b7;
733static int hf_dnp3_al_ctrq_b0;
734static int hf_dnp3_al_ctrq_b1;
735static int hf_dnp3_al_ctrq_b2;
736static int hf_dnp3_al_ctrq_b3;
737static int hf_dnp3_al_ctrq_b4;
738static int hf_dnp3_al_ctrq_b5;
739static int hf_dnp3_al_ctrq_b6;
740static int hf_dnp3_al_ctrq_b7;
741static int hf_dnp3_al_aiq_b0;
742static int hf_dnp3_al_aiq_b1;
743static int hf_dnp3_al_aiq_b2;
744static int hf_dnp3_al_aiq_b3;
745static int hf_dnp3_al_aiq_b4;
746static int hf_dnp3_al_aiq_b5;
747static int hf_dnp3_al_aiq_b6;
748static int hf_dnp3_al_aiq_b7;
749static int hf_dnp3_al_aoq_b0;
750static int hf_dnp3_al_aoq_b1;
751static int hf_dnp3_al_aoq_b2;
752static int hf_dnp3_al_aoq_b3;
753static int hf_dnp3_al_aoq_b4;
754static int hf_dnp3_al_aoq_b5;
755static int hf_dnp3_al_aoq_b6;
756static int hf_dnp3_al_aoq_b7;
757static int hf_dnp3_al_timestamp;
758static int hf_dnp3_al_file_perms;
759static int hf_dnp3_al_file_perms_read_owner;
760static int hf_dnp3_al_file_perms_write_owner;
761static int hf_dnp3_al_file_perms_exec_owner;
762static int hf_dnp3_al_file_perms_read_group;
763static int hf_dnp3_al_file_perms_write_group;
764static int hf_dnp3_al_file_perms_exec_group;
765static int hf_dnp3_al_file_perms_read_world;
766static int hf_dnp3_al_file_perms_write_world;
767static int hf_dnp3_al_file_perms_exec_world;
768static int hf_dnp3_al_rel_timestamp;
769static int hf_dnp3_al_ana16;
770static int hf_dnp3_al_ana32;
771static int hf_dnp3_al_anaflt;
772static int hf_dnp3_al_anadbl;
773static int hf_dnp3_al_bit;
774static int hf_dnp3_al_bit0;
775static int hf_dnp3_al_bit1;
776static int hf_dnp3_al_bit2;
777static int hf_dnp3_al_bit3;
778static int hf_dnp3_al_bit4;
779static int hf_dnp3_al_bit5;
780static int hf_dnp3_al_bit6;
781static int hf_dnp3_al_bit7;
782static int hf_dnp3_al_2bit;
783static int hf_dnp3_al_2bit0;
784static int hf_dnp3_al_2bit1;
785static int hf_dnp3_al_2bit2;
786static int hf_dnp3_al_2bit3;
787static int hf_dnp3_al_cnt16;
788static int hf_dnp3_al_cnt32;
789static int hf_dnp3_al_ctrlstatus;
790static int hf_dnp3_al_anaout16;
791static int hf_dnp3_al_anaout32;
792static int hf_dnp3_al_anaoutflt;
793static int hf_dnp3_al_anaoutdbl;
794static int hf_dnp3_al_file_mode;
795static int hf_dnp3_al_file_auth;
796static int hf_dnp3_al_file_size;
797static int hf_dnp3_al_file_maxblk;
798static int hf_dnp3_al_file_reqID;
799static int hf_dnp3_al_file_handle;
800static int hf_dnp3_al_file_status;
801static int hf_dnp3_al_file_blocknum;
802static int hf_dnp3_al_file_lastblock;
803static int hf_dnp3_al_file_data;
804static int hf_dnp3_ctlobj_code_c;
805static int hf_dnp3_ctlobj_code_m;
806static int hf_dnp3_ctlobj_code_tc;
807static int hf_dnp3_al_datatype;
808static int hf_dnp3_al_da_length;
809static int hf_dnp3_al_da_uint8;
810static int hf_dnp3_al_da_uint16;
811static int hf_dnp3_al_da_uint32;
812static int hf_dnp3_al_da_int8;
813static int hf_dnp3_al_da_int16;
814static int hf_dnp3_al_da_int32;
815static int hf_dnp3_al_da_flt;
816static int hf_dnp3_al_da_dbl;
817static int hf_dnp3_al_sa_cd;
818static int hf_dnp3_al_sa_cdl;
819static int hf_dnp3_al_sa_csq;
820static int hf_dnp3_al_sa_err;
821static int hf_dnp3_al_sa_key;
822static int hf_dnp3_al_sa_kcm;
823static int hf_dnp3_al_sa_ks;
824static int hf_dnp3_al_sa_ksq;
825static int hf_dnp3_al_sa_kwa;
826static int hf_dnp3_al_sa_mac;
827static int hf_dnp3_al_sa_mal;
828static int hf_dnp3_al_sa_rfc;
829static int hf_dnp3_al_sa_seq;
830static int hf_dnp3_al_sa_uk;
831static int hf_dnp3_al_sa_ukl;
832static int hf_dnp3_al_sa_usr;
833static int hf_dnp3_al_sa_usrn;
834static int hf_dnp3_al_sa_usrnl;
835static int hf_dnp3_al_sa_assoc_id;
836
837/* Generated from convert_proto_tree_add_text.pl */
838static int hf_dnp3_al_point_index;
839static int hf_dnp3_al_da_value;
840static int hf_dnp3_al_count;
841static int hf_dnp3_al_on_time;
842static int hf_dnp3_al_off_time;
843static int hf_dnp3_al_time_delay;
844static int hf_dnp3_al_file_string_offset;
845static int hf_dnp3_al_file_string_length;
846static int hf_dnp3_al_file_name;
847static int hf_dnp3_al_octet_string;
848static int hf_dnp3_unknown_data_chunk;
849
850/***************************************************************************/
851/* Value String Look-Ups */
852/***************************************************************************/
853static const value_string dnp3_ctl_func_pri_vals[] = {
854 { DL_FUNC_RESET_LINK0x00, "Reset of Remote Link" },
855 { DL_FUNC_RESET_PROC0x01, "Reset of User Process" },
856 { DL_FUNC_TEST_LINK0x02, "Test Function For Link" },
857 { DL_FUNC_USER_DATA0x03, "User Data" },
858 { DL_FUNC_UNC_DATA0x04, "Unconfirmed User Data" },
859 { DL_FUNC_LINK_STAT0x09, "Request Link Status" },
860 { 0, NULL((void*)0) }
861};
862
863static const value_string dnp3_ctl_func_sec_vals[] = {
864 { DL_FUNC_ACK0x00, "ACK" },
865 { DL_FUNC_NACK0x01, "NACK" },
866 { DL_FUNC_STAT_LINK0x0B, "Status of Link" },
867 { DL_FUNC_NO_FUNC0x0E, "Link Service Not Functioning" },
868 { DL_FUNC_NOT_IMPL0x0F, "Link Service Not Used or Implemented" },
869 { 0, NULL((void*)0) }
870};
871
872#if 0
873static const value_string dnp3_ctl_flags_pri_vals[] = {
874 { DNP3_CTL_DIR0x80, "DIR" },
875 { DNP3_CTL_PRM0x40, "PRM" },
876 { DNP3_CTL_FCB0x20, "FCB" },
877 { DNP3_CTL_FCV0x10, "FCV" },
878 { 0, NULL((void*)0) }
879};
880#endif
881
882#if 0
883static const value_string dnp3_ctl_flags_sec_vals[]= {
884 { DNP3_CTL_DIR0x80, "DIR" },
885 { DNP3_CTL_PRM0x40, "PRM" },
886 { DNP3_CTL_RES0x20, "RES" },
887 { DNP3_CTL_DFC0x10, "DFC" },
888 { 0, NULL((void*)0) }
889};
890#endif
891
892#if 0
893static const value_string dnp3_tr_flags_vals[] = {
894 { DNP3_TR_FIN0x80, "FIN" },
895 { DNP3_TR_FIR0x40, "FIR" },
896 { 0, NULL((void*)0) }
897};
898#endif
899
900#if 0
901static const value_string dnp3_al_flags_vals[] = {
902 { DNP3_AL_FIR0x80, "FIR" },
903 { DNP3_AL_FIN0x40, "FIN" },
904 { DNP3_AL_CON0x20, "CON" },
905 { DNP3_AL_UNS0x10, "UNS" },
906 { 0, NULL((void*)0) }
907};
908#endif
909
910/* Application Layer Function Code Values */
911static const value_string dnp3_al_func_vals[] = {
912 { AL_FUNC_CONFIRM0x00, "Confirm" },
913 { AL_FUNC_READ0x01, "Read" },
914 { AL_FUNC_WRITE0x02, "Write" },
915 { AL_FUNC_SELECT0x03, "Select" },
916 { AL_FUNC_OPERATE0x04, "Operate" },
917 { AL_FUNC_DIROP0x05, "Direct Operate" },
918 { AL_FUNC_DIROPNACK0x06, "Direct Operate No Ack" },
919 { AL_FUNC_FRZ0x07, "Immediate Freeze" },
920 { AL_FUNC_FRZNACK0x08, "Immediate Freeze No Ack" },
921 { AL_FUNC_FRZCLR0x09, "Freeze and Clear" },
922 { AL_FUNC_FRZCLRNACK0x0A, "Freeze and Clear No ACK" },
923 { AL_FUNC_FRZT0x0B, "Freeze With Time" },
924 { AL_FUNC_FRZTNACK0x0C, "Freeze With Time No ACK" },
925 { AL_FUNC_COLDRST0x0D, "Cold Restart" },
926 { AL_FUNC_WARMRST0x0E, "Warm Restart" },
927 { AL_FUNC_INITDATA0x0F, "Initialize Data" },
928 { AL_FUNC_INITAPP0x10, "Initialize Application" },
929 { AL_FUNC_STARTAPP0x11, "Start Application" },
930 { AL_FUNC_STOPAPP0x12, "Stop Application" },
931 { AL_FUNC_SAVECFG0x13, "Save Configuration" },
932 { AL_FUNC_ENSPMSG0x14, "Enable Spontaneous Messages" },
933 { AL_FUNC_DISSPMSG0x15, "Disable Spontaneous Messages" },
934 { AL_FUNC_ASSIGNCL0x16, "Assign Classes" },
935 { AL_FUNC_DELAYMST0x17, "Delay Measurement" },
936 { AL_FUNC_RECCT0x18, "Record Current Time" },
937 { AL_FUNC_OPENFILE0x19, "Open File" },
938 { AL_FUNC_CLOSEFILE0x1A, "Close File" },
939 { AL_FUNC_DELETEFILE0x1B, "Delete File" },
940 { AL_FUNC_GETFILEINF0x1C, "Get File Info" },
941 { AL_FUNC_AUTHFILE0x1D, "Authenticate File" },
942 { AL_FUNC_ABORTFILE0x1E, "Abort File" },
943 { AL_FUNC_ACTCNF0x1F, "Activate Config" },
944 { AL_FUNC_AUTHREQ0x20, "Authentication Request" },
945 { AL_FUNC_AUTHERR0x21, "Authentication Error" },
946 { AL_FUNC_RESPON0x81, "Response" },
947 { AL_FUNC_UNSOLI0x82, "Unsolicited Response" },
948 { AL_FUNC_AUTHRESP0x83, "Authentication Response" },
949 { 0, NULL((void*)0) }
950};
951static value_string_ext dnp3_al_func_vals_ext = VALUE_STRING_EXT_INIT(dnp3_al_func_vals){ _try_val_to_str_ext_init, 0, (sizeof (dnp3_al_func_vals) / sizeof
((dnp3_al_func_vals)[0]))-1, dnp3_al_func_vals, "dnp3_al_func_vals"
}
;
952
953/* Application Layer Internal Indication (IIN) bit Values */
954static const value_string dnp3_al_iin_vals[] = {
955 { AL_IIN_BMSG0x0100, "Broadcast message Rx'd" },
956 { AL_IIN_CLS1D0x0200, "Class 1 Data Available" },
957 { AL_IIN_CLS2D0x0400, "Class 2 Data Available" },
958 { AL_IIN_CLS3D0x0800, "Class 3 Data Available" },
959 { AL_IIN_TSR0x1000, "Time Sync Required from Master" },
960 { AL_IIN_DOL0x2000, "Outputs in Local Mode" },
961 { AL_IIN_DT0x4000, "Device Trouble" },
962 { AL_IIN_RST0x8000, "Device Restart" },
963 { AL_IIN_FCNI0x0001, "Function Code not implemented" },
964 { AL_IIN_OBJU0x0002, "Requested Objects Unknown" },
965 { AL_IIN_PIOOR0x0004, "Parameters Invalid or Out of Range" },
966 { AL_IIN_EBO0x0008, "Event Buffer Overflow" },
967 { AL_IIN_OAE0x0010, "Operation Already Executing" },
968 { AL_IIN_CC0x0020, "Device Configuration Corrupt" },
969 { 0, NULL((void*)0) }
970};
971
972/* Application Layer Object Qualifier Prefix Values When Qualifier Code != 11 */
973static const value_string dnp3_al_objq_prefix_vals[] = {
974 { AL_OBJQL_PREFIX_NI0x00, "None" },
975 { AL_OBJQL_PREFIX_1O0x01, "1-Octet Index Prefix" },
976 { AL_OBJQL_PREFIX_2O0x02, "2-Octet Index Prefix" },
977 { AL_OBJQL_PREFIX_4O0x03, "4-Octet Index Prefix" },
978 { AL_OBJQL_PREFIX_1OS0x04, "1-Octet Object Size Prefix" },
979 { AL_OBJQL_PREFIX_2OS0x05, "2-Octet Object Size Prefix" },
980 { AL_OBJQL_PREFIX_4OS0x06, "4-Octet Object Size Prefix" },
981 { 0, NULL((void*)0) }
982};
983static value_string_ext dnp3_al_objq_prefix_vals_ext = VALUE_STRING_EXT_INIT(dnp3_al_objq_prefix_vals){ _try_val_to_str_ext_init, 0, (sizeof (dnp3_al_objq_prefix_vals
) / sizeof ((dnp3_al_objq_prefix_vals)[0]))-1, dnp3_al_objq_prefix_vals
, "dnp3_al_objq_prefix_vals" }
;
984
985/* Application Layer Object Qualifier Range Values */
986static const value_string dnp3_al_objq_range_vals[] = {
987 { AL_OBJQL_RANGE_SSI80x00, "8-bit Start and Stop Indices" },
988 { AL_OBJQL_RANGE_SSI160x01, "16-bit Start and Stop Indices" },
989 { AL_OBJQL_RANGE_SSI320x02, "32-bit Start and Stop Indices" },
990 { AL_OBJQL_RANGE_AA80x03, "8-bit Absolute Address in Range Field" },
991 { AL_OBJQL_RANGE_AA160x04, "16-bit Absolute Address in Range Field" },
992 { AL_OBJQL_RANGE_AA320x05, "32-bit Absolute Address in Range Field" },
993 { AL_OBJQL_RANGE_R00x06, "No Range Field" },
994 { AL_OBJQL_RANGE_SF80x07, "8-bit Single Field Quantity" },
995 { AL_OBJQL_RANGE_SF160x08, "16-bit Single Field Quantity" },
996 { AL_OBJQL_RANGE_SF320x09, "32-bit Single Field Quantity" },
997 { 10, "Reserved" },
998 { AL_OBJQL_RANGE_FF0x0B, "Free-format Qualifier" },
999 { 0, NULL((void*)0) }
1000};
1001static value_string_ext dnp3_al_objq_range_vals_ext = VALUE_STRING_EXT_INIT(dnp3_al_objq_range_vals){ _try_val_to_str_ext_init, 0, (sizeof (dnp3_al_objq_range_vals
) / sizeof ((dnp3_al_objq_range_vals)[0]))-1, dnp3_al_objq_range_vals
, "dnp3_al_objq_range_vals" }
;
1002
1003/* Application Layer Data Object Values */
1004static const value_string dnp3_al_obj_vals[] = {
1005 { AL_OBJ_DA_CFG_ID0x00C4, "Device Attributes - Configuration ID (Obj:00, Var:196)" },
1006 { AL_OBJ_DA_CFG_VER0x00C5, "Device Attributes - Configuration version (Obj:00, Var:197)" },
1007 { AL_OBJ_DA_CFG_BLD_DATE0x00C6,"Device Attributes - Configuration build date (Obj:00, Var:198)" },
1008 { AL_OBJ_DA_CFG_CHG_DATE0x00C7,"Device Attributes - Configuration last change date (Obj:00, Var:199)" },
1009 { AL_OBJ_DA_CFG_SIG0x00C8, "Device Attributes - Configuration signature (Obj:00, Var:200)" },
1010 { AL_OBJ_DA_CFG_SIG_ALG0x00C9, "Device Attributes - Configuration signature algorithm (Obj:00, Var:201)" },
1011 { AL_OBJ_DA_MRID0x00CA, "Device Attributes - Master Resource ID (mRID) (Obj:00, Var:202)" },
1012 { AL_OBJ_DA_ALT0x00CB, "Device Attributes - Device altitude (Obj:00, Var:203)" },
1013 { AL_OBJ_DA_LONG0x00CC, "Device Attributes - Device longitude (Obj:00, Var:204)" },
1014 { AL_OBJ_DA_LAT0x00CD, "Device Attributes - Device latitude (Obj:00, Var:205)" },
1015 { AL_OBJ_DA_SEC_OP0x00CE, "Device Attributes - User-assigned secondary operator name (Obj:00, Var:206)" },
1016 { AL_OBJ_DA_PRM_OP0x00CF, "Device Attributes - User-assigned primary operator name (Obj:00, Var:207)" },
1017 { AL_OBJ_DA_SYS_NAME0x00D0, "Device Attributes - User-assigned system name (Obj:00, Var:208)" },
1018 { AL_OBJ_DA_SEC_VER0x00D1, "Device Attributes - Secure authentication version (Obj:00, Var:209)" },
1019 { AL_OBJ_DA_SEC_STAT0x00D2, "Device Attributes - Number of security statistics per association (Obj:00, Var:210)" },
1020 { AL_OBJ_DA_USR_ATTR0x00D3, "Device Attributes - Identifier of support for user-specific attributes (Obj:00, Var:211)" },
1021 { AL_OBJ_DA_MSTR_DSP0x00D4, "Device Attributes - Number of master-defined data set prototypes (Obj:00, Var:212)" },
1022 { AL_OBJ_DA_OS_DSP0x00D5, "Device Attributes - Number of outstation-defined data set prototypes (Obj:00, Var:213)" },
1023 { AL_OBJ_DA_MSTR_DS0x00D6, "Device Attributes - Number of master-defined data sets (Obj:00, Var:214)" },
1024 { AL_OBJ_DA_OS_DS0x00D7, "Device Attributes - Number of outstation-defined data sets (Obj:00, Var:215)" },
1025 { AL_OBJ_DA_BO_REQ0x00D8, "Device Attributes - Max number of binary outputs per request (Obj:00, Var:216)" },
1026 { AL_OBJ_DA_LOC_TA0x00D9, "Device Attributes - Local timing accuracy (Obj:00, Var:217)" },
1027 { AL_OBJ_DA_DUR_TA0x00DA, "Device Attributes - Duration of timing accuracy (Obj:00, Var:218)" },
1028 { AL_OBJ_DA_AO_EVT0x00DB, "Device Attributes - Support for analog output events (Obj:00, Var:219)" },
1029 { AL_OBJ_DA_MAX_AO0x00DC, "Device Attributes - Max analog output index (Obj:00, Var:220)" },
1030 { AL_OBJ_DA_NUM_AO0x00DD, "Device Attributes - Number of analog outputs (Obj:00, Var:221)" },
1031 { AL_OBJ_DA_BO_EVT0x00DE, "Device Attributes - Support for binary output events (Obj:00, Var:222)" },
1032 { AL_OBJ_DA_MAX_BO0x00DF, "Device Attributes - Max binary output index (Obj:00, Var:223)" },
1033 { AL_OBJ_DA_NUM_BO0x00E0, "Device Attributes - Number of binary outputs (Obj:00, Var:224)" },
1034 { AL_OBJ_DA_FCTR_EVT0x00E1, "Device Attributes - Support for frozen counter events (Obj:00, Var:225)" },
1035 { AL_OBJ_DA_FCTR0x00E2, "Device Attributes - Support for frozen counters (Obj:00, Var:226)" },
1036 { AL_OBJ_DA_CTR_EVT0x00E3, "Device Attributes - Support for counter events (Obj:00, Var:227)" },
1037 { AL_OBJ_DA_MAX_CTR0x00E4, "Device Attributes - Max counter index (Obj:00, Var:228)" },
1038 { AL_OBJ_DA_NUM_CTR0x00E5, "Device Attributes - Number of counter points (Obj:00, Var:229)" },
1039 { AL_OBJ_DA_AIF0x00E6, "Device Attributes - Support for frozen analog inputs (Obj:00, Var:230)" },
1040 { AL_OBJ_DA_AI_EVT0x00E7, "Device Attributes - Support for analog input events (Obj:00, Var:231)" },
1041 { AL_OBJ_DA_MAX_AI0x00E8, "Device Attributes - Maximum analog input index (Obj:00, Var:232)" },
1042 { AL_OBJ_DA_NUM_AI0x00E9, "Device Attributes - Number of analog input points (Obj:00, Var:233)" },
1043 { AL_OBJ_DA_2BI_EVT0x00EA, "Device Attributes - Support for Double-Bit BI Events (Obj:00, Var:234)" },
1044 { AL_OBJ_DA_MAX_2BI0x00EB, "Device Attributes - Max Double-bit BI Point Index (Obj:00, Var:235)" },
1045 { AL_OBJ_DA_NUM_2BI0x00EC, "Device Attributes - Number of Double-bit BI Points (Obj:00, Var:236)" },
1046 { AL_OBJ_DA_BI_EVT0x00ED, "Device Attributes - Support for Binary Input Events (Obj:00, Var:237)" },
1047 { AL_OBJ_DA_MAX_BI0x00EE, "Device Attributes - Max Binary Input Point Index (Obj:00, Var:238)" },
1048 { AL_OBJ_DA_NUM_BI0x00EF, "Device Attributes - Number of Binary Input Points (Obj:00, Var:239)" },
1049 { AL_OBJ_DA_MXTX_FR0x00F0, "Device Attributes - Maximum Transmit Fragment Size (Obj:00, Var:240)" },
1050 { AL_OBJ_DA_MXRX_FR0x00F1, "Device Attributes - Maximum Receive Fragment Size (Obj:00, Var:241)" },
1051 { AL_OBJ_DA_SWVER0x00F2, "Device Attributes - Device Manufacturers SW Version (Obj:00, Var:242)" },
1052 { AL_OBJ_DA_HWVER0x00F3, "Device Attributes - Device Manufacturers HW Version (Obj:00, Var:243)" },
1053 { AL_OBJ_DA_LOC0x00F5, "Device Attributes - User-Assigned Location (Obj:00, Var:245)" },
1054 { AL_OBJ_DA_ID0x00F6, "Device Attributes - User-Assigned ID code/number (Obj:00, Var:246)" },
1055 { AL_OBJ_DA_DEVNAME0x00F7, "Device Attributes - User-Assigned Device Name (Obj:00, Var:247)" },
1056 { AL_OBJ_DA_SERNUM0x00F8, "Device Attributes - Device Serial Number (Obj:00, Var:248)" },
1057 { AL_OBJ_DA_CONF0x00F9, "Device Attributes - DNP Subset and Conformance (Obj:00, Var:249)" },
1058 { AL_OBJ_DA_PROD0x00FA, "Device Attributes - Device Product Name and Model (Obj:00, Var:250)" },
1059 { AL_OBJ_DA_MFG0x00FC, "Device Attributes - Device Manufacturers Name (Obj:00, Var:252)" },
1060 { AL_OBJ_DA_ALL0x00FE, "Device Attributes - Non-specific All-attributes Request (Obj:00, Var:254)" },
1061 { AL_OBJ_DA_LVAR0x00FF, "Device Attributes - List of Attribute Variations (Obj:00, Var:255)" },
1062 { AL_OBJ_BI_ALL0x0100, "Binary Input Default Variation (Obj:01, Var:Default)" },
1063 { AL_OBJ_BI_1BIT0x0101, "Single-Bit Binary Input (Obj:01, Var:01)" },
1064 { AL_OBJ_BI_STAT0x0102, "Binary Input With Status (Obj:01, Var:02)" },
1065 { AL_OBJ_BIC_ALL0x0200, "Binary Input Change Default Variation (Obj:02, Var:Default)" },
1066 { AL_OBJ_BIC_NOTIME0x0201, "Binary Input Change Without Time (Obj:02, Var:01)" },
1067 { AL_OBJ_BIC_TIME0x0202, "Binary Input Change With Time (Obj:02, Var:02)" },
1068 { AL_OBJ_BIC_RTIME0x0203, "Binary Input Change With Relative Time (Obj:02, Var:03)" },
1069 { AL_OBJ_2BI_ALL0x0300, "Double-bit Input Default Variation (Obj:03, Var:Default)" },
1070 { AL_OBJ_2BI_NF0x0301, "Double-bit Input No Flags (Obj:03, Var:01)" },
1071 { AL_OBJ_2BI_STAT0x0302, "Double-bit Input With Status (Obj:03, Var:02)" },
1072 { AL_OBJ_2BIC_ALL0x0400, "Double-bit Input Change Default Variation (Obj:04, Var:Default)" },
1073 { AL_OBJ_2BIC_NOTIME0x0401, "Double-bit Input Change Without Time (Obj:04, Var:01)" },
1074 { AL_OBJ_2BIC_TIME0x0402, "Double-bit Input Change With Time (Obj:04, Var:02)" },
1075 { AL_OBJ_2BIC_RTIME0x0403, "Double-bit Input Change With Relative Time (Obj:04, Var:03)" },
1076 { AL_OBJ_BO_ALL0x0A00, "Binary Output Default Variation (Obj:10, Var:Default)" },
1077 { AL_OBJ_BO0x0A01, "Binary Output (Obj:10, Var:01)" },
1078 { AL_OBJ_BO_STAT0x0A02, "Binary Output Status (Obj:10, Var:02)" },
1079 { AL_OBJ_BOC_ALL0x0B00, "Binary Output Change Default Variation (Obj:11, Var:Default)" },
1080 { AL_OBJ_BOC_NOTIME0x0B01, "Binary Output Change Without Time (Obj:11, Var:01)" },
1081 { AL_OBJ_BOC_TIME0x0B02, "Binary Output Change With Time (Obj:11, Var:02)" },
1082 { AL_OBJ_CTLOP_BLK0x0C01, "Control Relay Output Block (Obj:12, Var:01)" },
1083 { AL_OBJ_CTL_PCB0x0C02, "Pattern Control Block (Obj:12, Var:02)" },
1084 { AL_OBJ_CTL_PMASK0x0C03, "Pattern Mask (Obj:12, Var:03)" },
1085 { AL_OBJ_BOE_NOTIME0x0D01, "Binary Command Event Without Time (Obj 13, Var:01)" },
1086 { AL_OBJ_BOE_TIME0x0D02, "Binary Command Event With Time (Obj 13, Var:02)" },
1087 { AL_OBJ_CTR_ALL0x1400, "Binary Counter Default Variation (Obj:20, Var:Default)" },
1088 { AL_OBJ_CTR_320x1401, "32-Bit Binary Counter (Obj:20, Var:01)" },
1089 { AL_OBJ_CTR_160x1402, "16-Bit Binary Counter (Obj:20, Var:02)" },
1090 { AL_OBJ_DCTR_320x1403, "32-Bit Binary Delta Counter (Obj:20, Var:03)" },
1091 { AL_OBJ_DCTR_160x1404, "16-Bit Binary Delta Counter (Obj:20, Var:04)" },
1092 { AL_OBJ_CTR_32NF0x1405, "32-Bit Binary Counter Without Flag (Obj:20, Var:05)" },
1093 { AL_OBJ_CTR_16NF0x1406, "16-Bit Binary Counter Without Flag (Obj:20, Var:06)" },
1094 { AL_OBJ_DCTR_32NF0x1407, "32-Bit Binary Delta Counter Without Flag (Obj:20, Var:07)" },
1095 { AL_OBJ_DCTR_16NF0x1408, "16-Bit Binary Delta Counter Without Flag (Obj:20, Var:08)" },
1096 { AL_OBJ_FCTR_ALL0x1500, "Frozen Binary Counter Default Variation (Obj:21, Var:Default)" },
1097 { AL_OBJ_FCTR_320x1501, "32-Bit Frozen Binary Counter (Obj:21, Var:01)" },
1098 { AL_OBJ_FCTR_160x1502, "16-Bit Frozen Binary Counter (Obj:21, Var:02)" },
1099 { AL_OBJ_FDCTR_320x1503, "32-Bit Frozen Binary Delta Counter (Obj:21, Var:03)" },
1100 { AL_OBJ_FDCTR_160x1504, "16-Bit Frozen Binary Delta Counter (Obj:21, Var:04)" },
1101 { AL_OBJ_FCTR_32T0x1505, "32-Bit Frozen Binary Counter With Flag and Time (Obj:21, Var:05)" },
1102 { AL_OBJ_FCTR_16T0x1506, "16-Bit Frozen Binary Counter With Flag and Time (Obj:21, Var:06)" },
1103 { AL_OBJ_FDCTR_32T0x1507, "32-Bit Frozen Binary Delta Counter With Flag and Time (Obj:21, Var:07)" },
1104 { AL_OBJ_FDCTR_16T0x1508, "16-Bit Frozen Binary Delta Counter With Flag and Time (Obj:21, Var:08)" },
1105 { AL_OBJ_FCTR_32NF0x1509, "32-Bit Frozen Binary Counter Without Flag (Obj:21, Var:09)" },
1106 { AL_OBJ_FCTR_16NF0x150A, "16-Bit Frozen Binary Counter Without Flag (Obj:21, Var:10)" },
1107 { AL_OBJ_FDCTR_32NF0x150B, "32-Bit Frozen Binary Delta Counter Without Flag (Obj:21, Var:11)" },
1108 { AL_OBJ_FDCTR_16NF0x150C, "16-Bit Frozen Binary Delta Counter Without Flag (Obj:21, Var:12)" },
1109 { AL_OBJ_CTRC_ALL0x1600, "Binary Counter Change Default Variation (Obj:22, Var:Default)" },
1110 { AL_OBJ_CTRC_320x1601, "32-Bit Counter Change Event w/o Time (Obj:22, Var:01)" },
1111 { AL_OBJ_CTRC_160x1602, "16-Bit Counter Change Event w/o Time (Obj:22, Var:02)" },
1112 { AL_OBJ_DCTRC_320x1603, "32-Bit Delta Counter Change Event w/o Time (Obj:22, Var:03)" },
1113 { AL_OBJ_DCTRC_160x1604, "16-Bit Delta Counter Change Event w/o Time (Obj:22, Var:04)" },
1114 { AL_OBJ_CTRC_32T0x1605, "32-Bit Counter Change Event with Time (Obj:22, Var:05)" },
1115 { AL_OBJ_CTRC_16T0x1606, "16-Bit Counter Change Event with Time (Obj:22, Var:06)" },
1116 { AL_OBJ_DCTRC_32T0x1607, "32-Bit Delta Counter Change Event with Time (Obj:22, Var:07)" },
1117 { AL_OBJ_DCTRC_16T0x1608, "16-Bit Delta Counter Change Event with Time (Obj:22, Var:08)" },
1118 { AL_OBJ_FCTRC_ALL0x1700, "Frozen Binary Counter Change Default Variation (Obj:23, Var:Default)" },
1119 { AL_OBJ_FCTRC_320x1701, "32-Bit Frozen Counter Change Event w/o Time (Obj:23, Var:01)" },
1120 { AL_OBJ_FCTRC_160x1702, "16-Bit Frozen Counter Change Event w/o Time (Obj:23, Var:02)" },
1121 { AL_OBJ_FDCTRC_320x1703, "32-Bit Frozen Delta Counter Change Event w/o Time (Obj:23, Var:03)" },
1122 { AL_OBJ_FDCTRC_160x1704, "16-Bit Frozen Delta Counter Change Event w/o Time (Obj:23, Var:04)" },
1123 { AL_OBJ_FCTRC_32T0x1705, "32-Bit Frozen Counter Change Event with Time (Obj:23, Var:05)" },
1124 { AL_OBJ_FCTRC_16T0x1706, "16-Bit Frozen Counter Change Event with Time (Obj:23, Var:06)" },
1125 { AL_OBJ_FDCTRC_32T0x1707, "32-Bit Frozen Delta Counter Change Event with Time (Obj:23, Var:07)" },
1126 { AL_OBJ_FDCTRC_16T0x1708, "16-Bit Frozen Delta Counter Change Event with Time (Obj:23, Var:08)" },
1127 { AL_OBJ_AI_ALL0x1E00, "Analog Input Default Variation (Obj:30, Var:Default)" },
1128 { AL_OBJ_AI_320x1E01, "32-Bit Analog Input (Obj:30, Var:01)" },
1129 { AL_OBJ_AI_160x1E02, "16-Bit Analog Input (Obj:30, Var:02)" },
1130 { AL_OBJ_AI_32NF0x1E03, "32-Bit Analog Input Without Flag (Obj:30, Var:03)" },
1131 { AL_OBJ_AI_16NF0x1E04, "16-Bit Analog Input Without Flag (Obj:30, Var:04)" },
1132 { AL_OBJ_AI_FLT0x1E05, "32-Bit Floating Point Input (Obj:30, Var:05)" },
1133 { AL_OBJ_AI_DBL0x1E06, "64-Bit Floating Point Input (Obj:30, Var:06)" },
1134 { AL_OBJ_AIFC_320x1F01, "32-Bit Frozen Analog Input (Obj:31, Var:01)" },
1135 { AL_OBJ_AIFC_160x1F02, "16-Bit Frozen Analog Input (Obj:31, Var:02)" },
1136 { AL_OBJ_AIFC_32TOF0x1F03, "32-Bit Frozen Analog Input w/ Time of Freeze (Obj:31, Var:03)" },
1137 { AL_OBJ_AIFC_16TOF0x1F04, "16-Bit Frozen Analog Input w/ Time of Freeze (Obj:31, Var:04)" },
1138 { AL_OBJ_AIFC_32NF0x1F05, "32-Bit Frozen Analog Input Without Flag (Obj:31, Var:05)" },
1139 { AL_OBJ_AIFC_16NF0x1F06, "16-Bit Frozen Analog Input Without Flag (Obj:31, Var:06)" },
1140 { AL_OBJ_AIF_FLT0x1F07, "32-Bit Frozen Floating Point Input (Obj:31, Var:07)" },
1141 { AL_OBJ_AIF_DBL0x1F08, "64-Bit Frozen Floating Point Input (Obj:31, Var:08)" },
1142 { AL_OBJ_AIC_ALL0x2000, "Analog Input Change Default Variation (Obj:32, Var:Default)" },
1143 { AL_OBJ_AIC_32NT0x2001, "32-Bit Analog Change Event w/o Time (Obj:32, Var:01)" },
1144 { AL_OBJ_AIC_16NT0x2002, "16-Bit Analog Change Event w/o Time (Obj:32, Var:02)" },
1145 { AL_OBJ_AIC_32T0x2003, "32-Bit Analog Change Event with Time (Obj:32, Var:03)" },
1146 { AL_OBJ_AIC_16T0x2004, "16-Bit Analog Change Event with Time (Obj:32, Var:04)" },
1147 { AL_OBJ_AIC_FLTNT0x2005, "32-Bit Floating Point Change Event w/o Time (Obj:32, Var:05)" },
1148 { AL_OBJ_AIC_DBLNT0x2006, "64-Bit Floating Point Change Event w/o Time (Obj:32, Var:06)" },
1149 { AL_OBJ_AIC_FLTT0x2007, "32-Bit Floating Point Change Event w/ Time (Obj:32, Var:07)" },
1150 { AL_OBJ_AIC_DBLT0x2008, "64-Bit Floating Point Change Event w/ Time (Obj:32, Var:08)" },
1151 { AL_OBJ_AIFC_32NT0x2101, "32-Bit Frozen Analog Event w/o Time (Obj:33, Var:01)" },
1152 { AL_OBJ_AIFC_16NT0x2102, "16-Bit Frozen Analog Event w/o Time (Obj:33, Var:02)" },
1153 { AL_OBJ_AIFC_32T0x2103, "32-Bit Frozen Analog Event w/ Time (Obj:33, Var:03)" },
1154 { AL_OBJ_AIFC_16T0x2104, "16-Bit Frozen Analog Event w/ Time (Obj:33, Var:04)" },
1155 { AL_OBJ_AIFC_FLTNT0x2105, "32-Bit Floating Point Frozen Change Event w/o Time (Obj:33, Var:05)" },
1156 { AL_OBJ_AIFC_DBLNT0x2106, "64-Bit Floating Point Frozen Change Event w/o Time (Obj:33, Var:06)" },
1157 { AL_OBJ_AIFC_FLTT0x2107, "32-Bit Floating Point Frozen Change Event w/ Time (Obj:33, Var:07)" },
1158 { AL_OBJ_AIFC_DBLT0x2108, "64-Bit Floating Point Frozen Change Event w/ Time (Obj:33, Var:08)" },
1159 { AL_OBJ_AIDB_ALL0x2200, "Analog Input Deadband Default Variation (Obj:34, Var:Default)" },
1160 { AL_OBJ_AIDB_160x2201, "16-Bit Analog Input Deadband (Obj:34, Var:01)" },
1161 { AL_OBJ_AIDB_320x2202, "32-Bit Analog Input Deadband (Obj:34, Var:02)" },
1162 { AL_OBJ_AIDB_FLT0x2203, "32-Bit Floating Point Analog Input Deadband (Obj:34, Var:03)" },
1163 { AL_OBJ_AO_ALL0x2800, "Analog Output Default Variation (Obj:40, Var:Default)" },
1164 { AL_OBJ_AO_320x2801, "32-Bit Analog Output Status (Obj:40, Var:01)" },
1165 { AL_OBJ_AO_160x2802, "16-Bit Analog Output Status (Obj:40, Var:02)" },
1166 { AL_OBJ_AO_FLT0x2803, "32-Bit Floating Point Output Status (Obj:40, Var:03)" },
1167 { AL_OBJ_AO_DBL0x2804, "64-Bit Floating Point Output Status (Obj:40, Var:04)" },
1168 { AL_OBJ_AO_32OPB0x2901, "32-Bit Analog Output Block (Obj:41, Var:01)" },
1169 { AL_OBJ_AO_16OPB0x2902, "16-Bit Analog Output Block (Obj:41, Var:02)" },
1170 { AL_OBJ_AO_FLTOPB0x2903, "32-Bit Floating Point Output Block (Obj:41, Var:03)" },
1171 { AL_OBJ_AO_DBLOPB0x2904, "64-Bit Floating Point Output Block (Obj:41, Var:04)" },
1172 { AL_OBJ_AOC_ALL0x2A00, "Analog Output Event Default Variation (Obj:42, Var:Default)" },
1173 { AL_OBJ_AOC_32NT0x2A01, "32-Bit Analog Output Event w/o Time (Obj:42, Var:01)" },
1174 { AL_OBJ_AOC_16NT0x2A02, "16-Bit Analog Output Event w/o Time (Obj:42, Var:02)" },
1175 { AL_OBJ_AOC_32T0x2A03, "32-Bit Analog Output Event with Time (Obj:42, Var:03)" },
1176 { AL_OBJ_AOC_16T0x2A04, "16-Bit Analog Output Event with Time (Obj:42, Var:04)" },
1177 { AL_OBJ_AOC_FLTNT0x2A05, "32-Bit Floating Point Output Event w/o Time (Obj:42, Var:05)" },
1178 { AL_OBJ_AOC_DBLNT0x2A06, "64-Bit Floating Point Output Event w/o Time (Obj:42, Var:06)" },
1179 { AL_OBJ_AOC_FLTT0x2A07, "32-Bit Floating Point Output Event w/ Time (Obj:42, Var:07)" },
1180 { AL_OBJ_AOC_DBLT0x2A08, "64-Bit Floating Point Output Event w/ Time (Obj:42, Var:08)" },
1181 { AL_OBJ_AOC_32EVNT0x2B01, "32-Bit Analog Output Event w/o Time (Obj:43, Var:01)" },
1182 { AL_OBJ_AOC_16EVNT0x2B02, "16-Bit Analog Output Event w/o Time (Obj:43, Var:02)" },
1183 { AL_OBJ_AOC_32EVTT0x2B03, "32-Bit Analog Output Event with Time (Obj:43, Var:03)" },
1184 { AL_OBJ_AOC_16EVTT0x2B04, "16-Bit Analog Output Event with Time (Obj:43, Var:04)" },
1185 { AL_OBJ_AOC_FLTEVNT0x2B05, "32-Bit Floating Point Output Event w/o Time (Obj:43, Var:05)" },
1186 { AL_OBJ_AOC_DBLEVNT0x2B06, "64-Bit Floating Point Output Event w/o Time (Obj:43, Var:06)" },
1187 { AL_OBJ_AOC_FLTEVTT0x2B07, "32-Bit Floating Point Output Event w/ Time (Obj:43, Var:07)" },
1188 { AL_OBJ_AOC_DBLEVTT0x2B08, "64-Bit Floating Point Output Event w/ Time (Obj:43, Var:08)" },
1189 { AL_OBJ_TD_ALL0x3200, "Time and Date Default Variations (Obj:50, Var:Default)" },
1190 { AL_OBJ_TD0x3201, "Time and Date (Obj:50, Var:01)" },
1191 { AL_OBJ_TDI0x3202, "Time and Date w/Interval (Obj:50, Var:02)" },
1192 { AL_OBJ_TDR0x3203, "Last Recorded Time and Date (Obj:50, Var:03)" },
1193 { AL_OBJ_TDCTO0x3301, "Time and Date CTO (Obj:51, Var:01)" },
1194 { AL_OBJ_UTDCTO0x3302, "Unsynchronized Time and Date CTO (Obj:51, Var:02)"},
1195 { AL_OBJ_TDELAYF0x3402, "Time Delay - Fine (Obj:52, Var:02)" },
1196 { AL_OBJ_CLASS00x3C01, "Class 0 Data (Obj:60, Var:01)" },
1197 { AL_OBJ_CLASS10x3C02, "Class 1 Data (Obj:60, Var:02)" },
1198 { AL_OBJ_CLASS20x3C03, "Class 2 Data (Obj:60, Var:03)" },
1199 { AL_OBJ_CLASS30x3C04, "Class 3 Data (Obj:60, Var:04)" },
1200 { AL_OBJ_FILE_CMD0x4603, "File Control - File Command (Obj:70, Var:03)" },
1201 { AL_OBJ_FILE_STAT0x4604, "File Control - File Status (Obj:70, Var:04)" },
1202 { AL_OBJ_FILE_TRANS0x4605, "File Control - File Transport (Obj:70, Var:05)" },
1203 { AL_OBJ_FILE_TRAN_ST0x4606, "File Control - File Transport Status (Obj:70, Var:06)" },
1204 { AL_OBJ_IIN0x5001, "Internal Indications (Obj:80, Var:01)" },
1205 { AL_OBJ_DS_PROTO0x5501, "Data-Set Prototype, with UUID (Obj:85, Var:01)" },
1206 { AL_OBJ_DSD_CONT0x5601, "Data-Set Descriptor, Data-Set Contents (Obj:86, Var:01)" },
1207 { AL_OBJ_DSD_CHAR0x5602, "Data-Set Descriptor, Characteristics (Obj:86, Var:02)" },
1208 { AL_OBJ_DSD_PIDX0x5603, "Data-Set Descriptor, Point Index Attributes (Obj:86, Var:03)" },
1209 { AL_OBJ_DS_PV0x5701, "Data-Set, Present Value (Obj:87, Var:01)" },
1210 { AL_OBJ_DS_SS0x5801, "Data-Set, Snapshot (Obj:88, Var:01)" },
1211 { AL_OBJ_OCT0x6E00, "Octet String (Obj:110)" },
1212 { AL_OBJ_OCT_EVT0x6F00, "Octet String Event (Obj:111)" },
1213 { AL_OBJ_VT_OBLK0x7000, "Virtual Terminal Output Block (Obj:112)" },
1214 { AL_OBJ_VT_EVTD0x7100, "Virtual Terminal Event Data (Obj:113)" },
1215 { AL_OBJ_SA_AUTH_CH0x7801, "Authentication Challenge (Obj:120, Var:01)" },
1216 { AL_OBJ_SA_AUTH_RP0x7802, "Authentication Reply (Obj:120, Var:02)" },
1217 { AL_OBJ_SA_AUTH_AGMRQ0x7803, "Authentication Aggressive Mode Request (Obj:120, Var:03)" },
1218 { AL_OBJ_SA_AUTH_SKSR0x7804, "Authentication Session Key Status Request (Obj:120, Var:04)" },
1219 { AL_OBJ_SA_AUTH_SKS0x7805, "Authentication Session Key Status (Obj:120, Var:05)" },
1220 { AL_OBJ_SA_AUTH_SKC0x7806, "Authentication Session Key Change (Obj:120, Var:06)" },
1221 { AL_OBJ_SA_AUTH_ERR0x7807, "Authentication Error (Obj:120, Var:07)" },
1222 { AL_OBJ_SA_AUTH_MAC0x7809, "Authentication Message Authentication Code (Obj:120, Var:09)" },
1223 { AL_OBJ_SA_AUTH_UKCR0x780B, "Authentication Update Key Change Request (Obj:120, Var:11)" },
1224 { AL_OBJ_SA_AUTH_UKCRP0x780C, "Authentication Update Key Change Reply (Obj:120, Var:12)"},
1225 { AL_OBJ_SA_AUTH_UKC0x780D, "Authentication Update Key Change (Obj:120, Var:13)"},
1226 { AL_OBJ_SA_AUTH_UKCC0x780F, "Authentication Update Key Change Confirmation (Obj:120, Var:15)"},
1227 { AL_OBJ_SA_SECSTAT0x7901, "Security Statistics (Obj:121, Var:01)" },
1228 { AL_OBJ_SA_SECSTATEVT0x7A01, "Security Statistic Event (Obj:122, Var:01)" },
1229 { AL_OBJ_SA_SECSTATEVTT0x7A02, "Security Statistic Event w/ Time (Obj:122, Var:02)" },
1230 { 0, NULL((void*)0) }
1231};
1232static value_string_ext dnp3_al_obj_vals_ext = VALUE_STRING_EXT_INIT(dnp3_al_obj_vals){ _try_val_to_str_ext_init, 0, (sizeof (dnp3_al_obj_vals) / sizeof
((dnp3_al_obj_vals)[0]))-1, dnp3_al_obj_vals, "dnp3_al_obj_vals"
}
;
1233
1234/* Application Layer Control Code 'Operation Type' Values */
1235static const value_string dnp3_al_ctlc_code_vals[] = {
1236 { AL_OBJCTLC_CODE00x00, "NUL Operation" },
1237 { AL_OBJCTLC_CODE10x01, "Pulse On" },
1238 { AL_OBJCTLC_CODE20x02, "Pulse Off" },
1239 { AL_OBJCTLC_CODE30x03, "Latch On" },
1240 { AL_OBJCTLC_CODE40x04, "Latch Off" },
1241 { 0, NULL((void*)0) }
1242};
1243
1244/* Application Layer Control Code 'Clear Field' Values */
1245static const value_string dnp3_al_ctlc_misc_vals[] = {
1246 { AL_OBJCTLC_QUEUE0x01, "Queue" },
1247 { AL_OBJCTLC_CLEAR0x02, "Clear" },
1248 { AL_OBJCTLC_NOTSET0x00, "Not Set" },
1249 { AL_OBJCTLC_BOTHSET0x03, "Queue and Clear" },
1250 { 0, NULL((void*)0) }
1251};
1252
1253/* Application Layer Control Code 'Trip Close Code' Values */
1254static const value_string dnp3_al_ctlc_tc_vals[] = {
1255 { AL_OBJCTLC_TC00x00, "NUL" },
1256 { AL_OBJCTLC_TC10x01, "Close" },
1257 { AL_OBJCTLC_TC20x02, "Trip" },
1258 { AL_OBJCTLC_TC30x03, "Reserved" },
1259 { 0, NULL((void*)0) }
1260};
1261
1262/* Application Layer Control Status Values */
1263static const value_string dnp3_al_ctl_status_vals[] = {
1264 { AL_OBJCTL_STAT00x00, "Req. Accepted/Init/Queued" },
1265 { AL_OBJCTL_STAT10x01, "Req. Not Accepted; Arm-Timer Expired" },
1266 { AL_OBJCTL_STAT20x02, "Req. Not Accepted; No 'SELECT' Received" },
1267 { AL_OBJCTL_STAT30x03, "Req. Not Accepted; Format Err. in Ctl Req." },
1268 { AL_OBJCTL_STAT40x04, "Ctl Oper. Not Supported For This Point" },
1269 { AL_OBJCTL_STAT50x05, "Req. Not Accepted; Ctrl Queue Full/Point Active" },
1270 { AL_OBJCTL_STAT60x06, "Req. Not Accepted; Ctrl Hardware Problems" },
1271 { AL_OBJCTL_STAT70x07, "Req. Not Accepted; Local/Remote switch in Local" },
1272 { AL_OBJCTL_STAT80x08, "Req. Not Accepted; Too many operations" },
1273 { AL_OBJCTL_STAT90x09, "Req. Not Accepted; Insufficient authorization" },
1274 { AL_OBJCTL_STAT100x0A, "Req. Not Accepted; Local automation proc active" },
1275 { AL_OBJCTL_STAT110x0B, "Req. Not Accepted; Processing limited" },
1276 { AL_OBJCTL_STAT120x0C, "Req. Not Accepted; Out of range value" },
1277 { AL_OBJCTL_STAT1260x7E, "Req. Not Accepted; Non-participating (NOP request)" },
1278 { AL_OBJCTL_STAT1270x7F, "Req. Not Accepted; Undefined error" },
1279 { 0, NULL((void*)0) }
1280};
1281static value_string_ext dnp3_al_ctl_status_vals_ext = VALUE_STRING_EXT_INIT(dnp3_al_ctl_status_vals){ _try_val_to_str_ext_init, 0, (sizeof (dnp3_al_ctl_status_vals
) / sizeof ((dnp3_al_ctl_status_vals)[0]))-1, dnp3_al_ctl_status_vals
, "dnp3_al_ctl_status_vals" }
;
1282
1283#if 0
1284/* Application Layer Binary Input Quality Flag Values */
1285static const value_string dnp3_al_biflag_vals[] = {
1286 { AL_OBJ_BI_FLAG00x01, "Online" },
1287 { AL_OBJ_BI_FLAG10x02, "Restart" },
1288 { AL_OBJ_BI_FLAG20x04, "Comm Fail" },
1289 { AL_OBJ_BI_FLAG30x08, "Remote Forced" },
1290 { AL_OBJ_BI_FLAG40x10, "Locally Forced" },
1291 { AL_OBJ_BI_FLAG50x20, "Chatter Filter" },
1292 { 0, NULL((void*)0) }
1293};
1294#endif
1295
1296#if 0
1297/* Application Layer Counter Quality Flag Values */
1298static const value_string dnp3_al_ctrflag_vals[] = {
1299 { AL_OBJ_CTR_FLAG00x01, "Online" },
1300 { AL_OBJ_CTR_FLAG10x02, "Restart" },
1301 { AL_OBJ_CTR_FLAG20x04, "Comm Fail" },
1302 { AL_OBJ_CTR_FLAG30x08, "Remote Forced" },
1303 { AL_OBJ_CTR_FLAG40x10, "Locally Forced" },
1304 { AL_OBJ_CTR_FLAG50x20, "Roll-Over" },
1305 { AL_OBJ_CTR_FLAG60x40, "Discontinuity" },
1306 { 0, NULL((void*)0) }
1307};
1308#endif
1309
1310#if 0
1311/* Application Layer Analog Input Quality Flag Values */
1312static const value_string dnp3_al_aiflag_vals[] = {
1313 { AL_OBJ_AI_FLAG00x01, "Online" },
1314 { AL_OBJ_AI_FLAG10x02, "Restart" },
1315 { AL_OBJ_AI_FLAG20x04, "Comm Fail" },
1316 { AL_OBJ_AI_FLAG30x08, "Remote Forced" },
1317 { AL_OBJ_AI_FLAG40x10, "Locally Forced" },
1318 { AL_OBJ_AI_FLAG50x20, "Over-Range" },
1319 { AL_OBJ_AI_FLAG60x40, "Ref. Error" },
1320 { 0, NULL((void*)0) }
1321};
1322#endif
1323
1324/* Application Layer Double-bit status values */
1325static const value_string dnp3_al_2bit_vals[] = {
1326 { AL_OBJ_2BI_STATE_INTERMEDIATE0x00, "Intermediate" },
1327 { AL_OBJ_2BI_STATE_OFF0x01, "Determined Off" },
1328 { AL_OBJ_2BI_STATE_ON0x02, "Determined On" },
1329 { AL_OBJ_2BI_STATE_INDETERM0x03, "Indeterminate" },
1330 { 0, NULL((void*)0) }
1331};
1332static value_string_ext dnp3_al_dbi_vals_ext = VALUE_STRING_EXT_INIT(dnp3_al_2bit_vals){ _try_val_to_str_ext_init, 0, (sizeof (dnp3_al_2bit_vals) / sizeof
((dnp3_al_2bit_vals)[0]))-1, dnp3_al_2bit_vals, "dnp3_al_2bit_vals"
}
;
1333
1334/* Application Layer File Control Mode values */
1335static const value_string dnp3_al_file_mode_vals[] = {
1336 { AL_OBJ_FILE_MODE_NULL0x00, "NULL" },
1337 { AL_OBJ_FILE_MODE_READ0x01, "READ" },
1338 { AL_OBJ_FILE_MODE_WRITE0x02, "WRITE" },
1339 { AL_OBJ_FILE_MODE_APPEND0x03, "APPEND" },
1340 { 0, NULL((void*)0) }
1341};
1342
1343/* Application Layer File Control Status values */
1344static const value_string dnp3_al_file_status_vals[] = {
1345 { 0, "SUCCESS" },
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" },
1353 { 8, "COMM LOST" },
1354 { 9, "CANNOT ABORT" },
1355 { 16, "NOT OPENED" },
1356 { 17, "HANDLE EXPIRED" },
1357 { 18, "BUFFER OVERRUN" },
1358 { 19, "FATAL" },
1359 { 20, "BLOCK SEQUENCE" },
1360 { 255, "UNDEFINED" },
1361 { 0, NULL((void*)0) }
1362};
1363static value_string_ext dnp3_al_file_status_vals_ext = VALUE_STRING_EXT_INIT(dnp3_al_file_status_vals){ _try_val_to_str_ext_init, 0, (sizeof (dnp3_al_file_status_vals
) / sizeof ((dnp3_al_file_status_vals)[0]))-1, dnp3_al_file_status_vals
, "dnp3_al_file_status_vals" }
;
1364
1365/* Application Layer Data Type values */
1366static const value_string dnp3_al_data_type_vals[] = {
1367 { AL_DATA_TYPE_NONE0x0, "NONE (Placeholder)" },
1368 { AL_DATA_TYPE_VSTR0x1, "VSTR (Visible ASCII String)" },
1369 { AL_DATA_TYPE_UINT0x2, "UINT (Unsigned Integer)" },
1370 { AL_DATA_TYPE_INT0x3, "INT (Signed Integer)" },
1371 { AL_DATA_TYPE_FLT0x4, "FLT (Floating Point)" },
1372 { AL_DATA_TYPE_OSTR0x5, "OSTR (Octet String)" },
1373 { AL_DATA_TYPE_BSTR0x6, "BSTR (Bit String)" },
1374 { AL_DATA_TYPE_TIME0x7, "TIME (DNP3 Time UINT48)" },
1375 { AL_DATA_TYPE_UNCD0x8, "UNCD (Unicode String)" },
1376 { AL_DATA_TYPE_U8BS8LIST0xFE, "U8BS8LIST (List of UINT8 - BSTR8 pairs)" },
1377 { AL_DATA_TYPE_U8BS8EXLIST0xFF, "U8BS8EXLIST (Extended List of UINT8 - BSTR8 pairs)" },
1378 { 0, NULL((void*)0) }
1379};
1380
1381/* Application Layer Read Object Type values */
1382static const value_string dnp3_al_read_obj_vals[] = {
1383 { (AL_OBJ_DA_GRP0x0000 & 0xFF00), "Device Attribute" },
1384 { (AL_OBJ_BI_ALL0x0100 & 0xFF00), "Binary Input" },
1385 { (AL_OBJ_BIC_ALL0x0200 & 0xFF00), "Binary Input Change" },
1386 { (AL_OBJ_2BI_ALL0x0300 & 0xFF00), "Double-bit Input" },
1387 { (AL_OBJ_2BIC_ALL0x0400 & 0xFF00), "Double-bit Input Change" },
1388 { (AL_OBJ_BO_ALL0x0A00 & 0xFF00), "Binary Output" },
1389 { (AL_OBJ_BOC_ALL0x0B00 & 0xFF00), "Binary Output Change" },
1390 { (AL_OBJ_CTR_ALL0x1400 & 0xFF00), "Counter" },
1391 { (AL_OBJ_FCTR_ALL0x1500 & 0xFF00), "Frozen Counter" },
1392 { (AL_OBJ_CTRC_ALL0x1600 & 0xFF00), "Counter Change" },
1393 { (AL_OBJ_FCTRC_ALL0x1700 & 0xFF00), "Frozen Counter Change" },
1394 { (AL_OBJ_AI_ALL0x1E00 & 0xFF00), "Analog Input" },
1395 { (AL_OBJ_AIC_ALL0x2000 & 0xFF00), "Analog Input Change" },
1396 { (AL_OBJ_AO_ALL0x2800 & 0xFF00), "Analog Output" },
1397 { (AL_OBJ_AOC_ALL0x2A00 & 0xFF00), "Analog Output Change" },
1398 { (AL_OBJ_TD_ALL0x3200 & 0xFF00), "Time and Date" },
1399 { (AL_OBJ_FILE_CMD0x4603 & 0xFF00), "File Control" },
1400 { (AL_OBJ_IIN0x5001 & 0xFF00), "Internal Indications" },
1401 { (AL_OBJ_OCT0x6E00 & 0xFF00), "Octet String" },
1402 { (AL_OBJ_OCT_EVT0x6F00 & 0xFF00), "Octet String Event" },
1403 { (AL_OBJ_VT_EVTD0x7100 & 0xFF00), "Virtual Terminal Event Data" },
1404 { (AL_OBJ_SA_AUTH_CH0x7801 & 0xFF00), "Secure Authentication" },
1405 { 0, NULL((void*)0) }
1406};
1407
1408static value_string_ext dnp3_al_read_obj_vals_ext = VALUE_STRING_EXT_INIT(dnp3_al_read_obj_vals){ _try_val_to_str_ext_init, 0, (sizeof (dnp3_al_read_obj_vals
) / sizeof ((dnp3_al_read_obj_vals)[0]))-1, dnp3_al_read_obj_vals
, "dnp3_al_read_obj_vals" }
;
1409
1410/* Application Layer Write Object Type values */
1411static const value_string dnp3_al_write_obj_vals[] = {
1412 { (AL_OBJ_TD_ALL0x3200 & 0xFF00), "Time and Date" },
1413 { (AL_OBJ_FILE_CMD0x4603 & 0xFF00), "File Control" },
1414 { (AL_OBJ_IIN0x5001 & 0xFF00), "Internal Indications" },
1415 { (AL_OBJ_OCT0x6E00 & 0xFF00), "Octet String" },
1416 { (AL_OBJ_OCT_EVT0x6F00 & 0xFF00), "Octet String Event" },
1417 { (AL_OBJ_VT_OBLK0x7000 & 0xFF00), "Virtual Terminal Output Block" },
1418 { (AL_OBJ_SA_AUTH_CH0x7801 & 0xFF00), "Secure Authentication" },
1419 { 0, NULL((void*)0) }
1420};
1421
1422static value_string_ext dnp3_al_write_obj_vals_ext = VALUE_STRING_EXT_INIT(dnp3_al_write_obj_vals){ _try_val_to_str_ext_init, 0, (sizeof (dnp3_al_write_obj_vals
) / sizeof ((dnp3_al_write_obj_vals)[0]))-1, dnp3_al_write_obj_vals
, "dnp3_al_write_obj_vals" }
;
1423
1424/* DNP SA Key Wrap Algorithm Values */
1425static const value_string dnp3_al_sa_kwa_vals[] = {
1426 { 0, "Unused" },
1427 { 1, "AES-128" },
1428 { 2, "AES-256" },
1429 { 0, NULL((void*)0) }
1430};
1431
1432/* DNP SA Key Status Values */
1433static const value_string dnp3_al_sa_ks_vals[] = {
1434 { 0, "Not Used" },
1435 { 1, "OK" },
1436 { 2, "NOT_INIT" },
1437 { 3, "COMM_FAIL" },
1438 { 4, "AUTH_FAIL" },
1439 { 0, NULL((void*)0) }
1440};
1441
1442/* DNP SA MAC Algorithm Values */
1443static 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)" },
1451 { 0, NULL((void*)0) }
1452};
1453
1454/* DNP SA Error Values */
1455static const value_string dnp3_al_sa_err_vals[] = {
1456 { 0, "Not used" },
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" },
1469 { 0, NULL((void*)0) }
1470};
1471
1472/* DNP SA Key Change Method Values */
1473static const value_string dnp3_al_sa_kcm_vals[] = {
1474 { 0, "Not used" },
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" },
1488 { 0, NULL((void*)0) }
1489};
1490
1491/* DNP SA Reason for Challenge Values */
1492static const value_string dnp3_al_sa_rfc_vals[] = {
1493 { 0, "Not Used" },
1494 { 1, "CRITICAL" },
1495 { 0, NULL((void*)0) }
1496};
1497
1498/* DNP SA Security Statistic Values */
1499static 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)" },
1518 { 0, NULL((void*)0) }
1519};
1520
1521static value_string_ext dnp3_al_sa_secstat_vals_ext = VALUE_STRING_EXT_INIT(dnp3_al_sa_secstat_vals){ _try_val_to_str_ext_init, 0, (sizeof (dnp3_al_sa_secstat_vals
) / sizeof ((dnp3_al_sa_secstat_vals)[0]))-1, dnp3_al_sa_secstat_vals
, "dnp3_al_sa_secstat_vals" }
;
1522
1523/* Initialize the subtree pointers */
1524static int ett_dnp3;
1525static int ett_dnp3_dl;
1526static int ett_dnp3_dl_ctl;
1527static int ett_dnp3_tr_ctl;
1528static int ett_dnp3_dl_data;
1529static int ett_dnp3_dl_chunk;
1530static int ett_dnp3_al;
1531static int ett_dnp3_al_ctl;
1532static int ett_dnp3_al_obj_point_tcc;
1533
1534/* Added for Application Layer Decoding */
1535static int ett_dnp3_al_iin;
1536static int ett_dnp3_al_obj;
1537static int ett_dnp3_al_obj_qualifier;
1538static int ett_dnp3_al_obj_range;
1539static int ett_dnp3_al_objdet;
1540static int ett_dnp3_al_obj_quality;
1541static int ett_dnp3_al_obj_point;
1542static int ett_dnp3_al_obj_point_perms;
1543
1544static expert_field ei_dnp_num_items_neg;
1545static expert_field ei_dnp_invalid_length;
1546static expert_field ei_dnp_iin_abnormal;
1547static expert_field ei_dnp3_data_hdr_crc_incorrect;
1548static expert_field ei_dnp3_data_chunk_crc_incorrect;
1549static expert_field ei_dnp3_unknown_object;
1550static expert_field ei_dnp3_unknown_group0_variation;
1551static expert_field ei_dnp3_num_items_invalid;
1552/* Generated from convert_proto_tree_add_text.pl */
1553#if 0
1554static expert_field ei_dnp3_buffering_user_data_until_final_frame_is_received;
1555#endif
1556
1557/* Tables for reassembly of fragments. */
1558static reassembly_table al_reassembly_table;
1559
1560/* ************************************************************************* */
1561/* Header values for reassembly */
1562/* ************************************************************************* */
1563static int hf_al_frag_data;
1564static int hf_dnp3_fragment;
1565static int hf_dnp3_fragments;
1566static int hf_dnp3_fragment_overlap;
1567static int hf_dnp3_fragment_overlap_conflict;
1568static int hf_dnp3_fragment_multiple_tails;
1569static int hf_dnp3_fragment_too_long_fragment;
1570static int hf_dnp3_fragment_error;
1571static int hf_dnp3_fragment_count;
1572static int hf_dnp3_fragment_reassembled_in;
1573static int hf_dnp3_fragment_reassembled_length;
1574static int ett_dnp3_fragment;
1575static int ett_dnp3_fragments;
1576
1577static dissector_handle_t dnp3_tcp_handle;
1578static dissector_handle_t dnp3_udp_handle;
1579
1580static const fragment_items dnp3_frag_items = {
1581 &ett_dnp3_fragment,
1582 &ett_dnp3_fragments,
1583 &hf_dnp3_fragments,
1584 &hf_dnp3_fragment,
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 */
1594 NULL((void*)0),
1595 "DNP 3.0 fragments"
1596};
1597
1598/* desegmentation of DNP3 over TCP */
1599static bool_Bool dnp3_desegment = true1;
1600
1601/* Enum for different quality type fields */
1602enum QUALITY_TYPE {
1603 BIN_IN,
1604 DBIN_IN,
1605 BIN_OUT,
1606 ANA_IN,
1607 ANA_OUT,
1608 COUNTER
1609};
1610
1611/* calculates crc given a buffer of characters and a length of buffer */
1612static uint16_t
1613calculateCRC(const void *buf, unsigned len) {
1614 uint16_t crc = crc16_0x3D65_seed((const uint8_t *)buf, len, 0);
1615 return ~crc;
1616}
1617
1618/* calculates crc given a tvbuff, offset, and length */
1619static uint16_t
1620calculateCRCtvb(tvbuff_t *tvb, unsigned offset, unsigned len) {
1621 uint16_t crc = crc16_0x3D65_tvb_offset_seed(tvb, offset, len, 0);
1622 return ~crc;
1623}
1624
1625/* calculate the extended sequence number - top 16 bits of the previous sequence number,
1626 * plus our own; then correct for wrapping */
1627static uint32_t
1628calculate_extended_seqno(uint32_t previous_seqno, uint8_t raw_seqno)
1629{
1630 uint32_t seqno = (previous_seqno & 0xffffffc0) | raw_seqno;
1631 if (seqno + 0x20 < previous_seqno) {
1632 seqno += 0x40;
1633 } else if (previous_seqno + 0x20 < seqno) {
1634 /* we got an out-of-order packet which happened to go backwards over the
1635 * wrap boundary */
1636 seqno -= 0x40;
1637 }
1638 return seqno;
1639}
1640
1641static int dnp3_tap;
1642
1643typedef struct _dnp3_packet_info
1644{
1645 uint16_t dl_src;
1646 uint16_t dl_dst;
1647 uint16_t msg_len;
1648
1649} dnp3_packet_info_t;
1650
1651static const char* dnp3_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter)
1652{
1653 if (filter == CONV_FT_SRC_ADDRESS) {
1654 if (conv->src_address.type == AT_NUMERIC)
1655 return "dnp3.src";
1656 }
1657
1658 if (filter == CONV_FT_DST_ADDRESS) {
1659 if (conv->dst_address.type == AT_NUMERIC)
1660 return "dnp3.dst";
1661 }
1662
1663 if (filter == CONV_FT_ANY_ADDRESS) {
1664 if (conv->src_address.type == AT_NUMERIC && conv->dst_address.type == AT_NUMERIC)
1665 return "dnp3.addr";
1666 }
1667
1668 return CONV_FILTER_INVALID"INVALID";
1669}
1670
1671static ct_dissector_info_t dnp3_ct_dissector_info = { &dnp3_conv_get_filter_type };
1672
1673static const char* dnp3_get_filter_type(endpoint_item_t* endpoint, conv_filter_type_e filter)
1674{
1675 if (endpoint->myaddress.type == AT_NUMERIC) {
1676 if (filter == CONV_FT_ANY_ADDRESS)
1677 return "dnp3.addr";
1678 else if (filter == CONV_FT_SRC_ADDRESS)
1679 return "dnp3.src";
1680 else if (filter == CONV_FT_DST_ADDRESS)
1681 return "dnp3.dst";
1682 }
1683
1684 return CONV_FILTER_INVALID"INVALID";
1685}
1686
1687static et_dissector_info_t dnp3_dissector_info = { &dnp3_get_filter_type };
1688
1689static tap_packet_status
1690dnp3_conversation_packet(void* pct, packet_info* pinfo,
1691 epan_dissect_t* edt _U___attribute__((unused)), const void* vip, tap_flags_t flags)
1692{
1693
1694 address* src = wmem_new0(pinfo->pool, address)((address*)wmem_alloc0((pinfo->pool), sizeof(address)));
1695 address* dst = wmem_new0(pinfo->pool, address)((address*)wmem_alloc0((pinfo->pool), sizeof(address)));
1696 conv_hash_t* hash = (conv_hash_t*)pct;
1697 const dnp3_packet_info_t* dnp3_info = (const dnp3_packet_info_t*)vip;
1698
1699 hash->flags = flags;
1700
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);
1703
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);
1706
1707 return TAP_PACKET_REDRAW;
1708}
1709
1710static tap_packet_status
1711dnp3_endpoint_packet(void* pit, packet_info* pinfo,
1712 epan_dissect_t* edt _U___attribute__((unused)), const void* vip, tap_flags_t flags)
1713{
1714 address* src = wmem_new0(pinfo->pool, address)((address*)wmem_alloc0((pinfo->pool), sizeof(address)));
1715 address* dst = wmem_new0(pinfo->pool, address)((address*)wmem_alloc0((pinfo->pool), sizeof(address)));
1716 conv_hash_t* hash = (conv_hash_t*)pit;
1717 const dnp3_packet_info_t* dnp3_info = (const dnp3_packet_info_t*)vip;
1718
1719 hash->flags = flags;
1720
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);
1723
1724 add_endpoint_table_data(hash, src, 0, true1, 1, dnp3_info->msg_len, &dnp3_dissector_info, ENDPOINT_NONECONVERSATION_NONE);
1725 add_endpoint_table_data(hash, dst, 0, false0, 1, dnp3_info->msg_len, &dnp3_dissector_info, ENDPOINT_NONECONVERSATION_NONE);
1726
1727 return TAP_PACKET_REDRAW;
1728}
1729
1730/*****************************************************************/
1731/* Application Layer Process Internal Indications (IIN) */
1732/*****************************************************************/
1733static void
1734dnp3_al_process_iin(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *al_tree)
1735{
1736 uint16_t al_iin;
1737 proto_item *tiin;
1738 static int* const indications[] = {
1739 &hf_dnp3_al_iin_rst,
1740 &hf_dnp3_al_iin_dt,
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,
1747 &hf_dnp3_al_iin_cc,
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,
1753 NULL((void*)0)
1754 };
1755
1756 tiin = proto_tree_add_bitmask(al_tree, tvb, offset, hf_dnp3_al_iin, ett_dnp3_al_iin, indications, ENC_BIG_ENDIAN0x00000000);
1757 al_iin = tvb_get_ntohs(tvb, offset);
1758
1759 /* If IIN indicates an abnormal condition, add expert info */
1760 if ((al_iin & AL_IIN_DT0x4000) || (al_iin & AL_IIN_CC0x0020) || (al_iin & AL_IIN_OAE0x0010) || (al_iin & AL_IIN_EBO0x0008) ||
1761 (al_iin & AL_IIN_PIOOR0x0004) || (al_iin & AL_IIN_OBJU0x0002) || (al_iin & AL_IIN_FCNI0x0001)) {
1762 expert_add_info(pinfo, tiin, &ei_dnp_iin_abnormal);
1763 }
1764}
1765
1766/**************************************************************/
1767/* Function to determine Application Layer Object Prefix size */
1768/* and Point address. */
1769/**************************************************************/
1770static int
1771dnp3_al_obj_procprefix(tvbuff_t *tvb, int offset, uint8_t al_objq_prefix, uint32_t *al_ptaddr, proto_tree *item_tree)
1772{
1773 int prefixbytes = 0;
1774 proto_item *prefix_item;
1775
1776 switch (al_objq_prefix)
1777 {
1778 case AL_OBJQL_PREFIX_NI0x00: /* No Prefix */
1779 prefixbytes = 0;
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);
1782 break;
1783 case AL_OBJQL_PREFIX_1O0x01:
1784 *al_ptaddr = tvb_get_uint8(tvb, offset);
1785 proto_tree_add_item(item_tree, hf_dnp3_al_index8, tvb, offset, 1, ENC_LITTLE_ENDIAN0x80000000);
1786 prefixbytes = 1;
1787 break;
1788 case AL_OBJQL_PREFIX_2O0x02:
1789 *al_ptaddr = tvb_get_letohs(tvb, offset);
1790 proto_tree_add_item(item_tree, hf_dnp3_al_index16, tvb, offset, 2, ENC_LITTLE_ENDIAN0x80000000);
1791 prefixbytes = 2;
1792 break;
1793 case AL_OBJQL_PREFIX_4O0x03:
1794 *al_ptaddr = tvb_get_letohl(tvb, offset);
1795 proto_tree_add_item(item_tree, hf_dnp3_al_index32, tvb, offset, 4, ENC_LITTLE_ENDIAN0x80000000);
1796 prefixbytes = 4;
1797 break;
1798 case AL_OBJQL_PREFIX_1OS0x04:
1799 *al_ptaddr = tvb_get_uint8(tvb, offset);
1800 proto_tree_add_item(item_tree, hf_dnp3_al_size8, tvb, offset, 1, ENC_LITTLE_ENDIAN0x80000000);
1801 prefixbytes = 1;
1802 break;
1803 case AL_OBJQL_PREFIX_2OS0x05:
1804 *al_ptaddr = tvb_get_letohs(tvb, offset);
1805 proto_tree_add_item(item_tree, hf_dnp3_al_size16, tvb, offset, 2, ENC_LITTLE_ENDIAN0x80000000);
1806 prefixbytes = 2;
1807 break;
1808 case AL_OBJQL_PREFIX_4OS0x06:
1809 *al_ptaddr = tvb_get_letohl(tvb, offset);
1810 proto_tree_add_item(item_tree, hf_dnp3_al_size32, tvb, offset, 4, ENC_LITTLE_ENDIAN0x80000000);
1811 prefixbytes = 4;
1812 break;
1813 }
1814 return prefixbytes;
1815}
1816
1817/*****************************************************************/
1818/* Function to add the same string to two separate tree items */
1819/*****************************************************************/
1820static void
1821dnp3_append_2item_text(proto_item *item1, proto_item *item2, const char *text)
1822{
1823 proto_item_append_text(item1, "%s", text);
1824 proto_item_append_text(item2, "%s", text);
1825}
1826
1827/*****************************************************************/
1828/* Function to Determine Application Layer Point Quality Flags & */
1829/* add Point Quality Flag Sub-Tree */
1830/*****************************************************************/
1831static void
1832dnp3_al_obj_quality(tvbuff_t *tvb, int offset, uint8_t al_ptflags, proto_tree *point_tree, proto_item *point_item, enum QUALITY_TYPE type)
1833{
1834
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;
1838
1839 /* Common code */
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: ");
1842
1843 if (al_ptflags & AL_OBJ_BI_FLAG00x01) {
1844 dnp3_append_2item_text(point_item, quality_item, "Online");
1845 }
1846 else {
1847 dnp3_append_2item_text(point_item, quality_item, "Offline");
1848 }
1849 if (al_ptflags & AL_OBJ_BI_FLAG10x02) dnp3_append_2item_text(point_item, quality_item, ", Restart");
1850 if (al_ptflags & AL_OBJ_BI_FLAG20x04) dnp3_append_2item_text(point_item, quality_item, ", Comm Fail");
1851 if (al_ptflags & AL_OBJ_BI_FLAG30x08) dnp3_append_2item_text(point_item, quality_item, ", Remote Force");
1852 if (al_ptflags & AL_OBJ_BI_FLAG40x10) dnp3_append_2item_text(point_item, quality_item, ", Local Force");
1853
1854 switch (type) {
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_FLAG50x20) dnp3_append_2item_text(point_item, quality_item, ", Chatter Filter");
1858
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;
1868 }
1869 else /* MUST be DBIN_IN */ {
1870 hf6 = hf_dnp3_al_2bit;
1871 }
1872 break;
1873
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;
1883 break;
1884
1885 case ANA_IN: /* Analog Input Quality flags */
1886 if (al_ptflags & AL_OBJ_AI_FLAG50x20) dnp3_append_2item_text(point_item, quality_item, ", Over-Range");
1887 if (al_ptflags & AL_OBJ_AI_FLAG60x40) dnp3_append_2item_text(point_item, quality_item, ", Reference Check");
1888
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;
1897 break;
1898
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;
1908 break;
1909
1910 case COUNTER: /* Counter Quality flags */
1911 if (al_ptflags & AL_OBJ_CTR_FLAG50x20) dnp3_append_2item_text(point_item, quality_item, ", Roll-over");
1912 if (al_ptflags & AL_OBJ_CTR_FLAG60x40) dnp3_append_2item_text(point_item, quality_item, ", Discontinuity");
1913
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;
1922 break;
1923 }
1924
1925 if (quality_tree != NULL((void*)0)) {
1926 if (hf7) {
1927 proto_tree_add_item(quality_tree, hf7, tvb, offset, 1, ENC_LITTLE_ENDIAN0x80000000);
1928 }
1929 proto_tree_add_item(quality_tree, hf6, tvb, offset, 1, ENC_LITTLE_ENDIAN0x80000000);
1930 proto_tree_add_item(quality_tree, hf5, tvb, offset, 1, ENC_LITTLE_ENDIAN0x80000000);
1931 proto_tree_add_item(quality_tree, hf4, tvb, offset, 1, ENC_LITTLE_ENDIAN0x80000000);
1932 proto_tree_add_item(quality_tree, hf3, tvb, offset, 1, ENC_LITTLE_ENDIAN0x80000000);
1933 proto_tree_add_item(quality_tree, hf2, tvb, offset, 1, ENC_LITTLE_ENDIAN0x80000000);
1934 proto_tree_add_item(quality_tree, hf1, tvb, offset, 1, ENC_LITTLE_ENDIAN0x80000000);
1935 proto_tree_add_item(quality_tree, hf0, tvb, offset, 1, ENC_LITTLE_ENDIAN0x80000000);
1936 }
1937 proto_item_append_text(point_item, ")");
1938}
1939
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 */
1947/* */
1948/* Value is ms since 00:00 on 1/1/1970 */
1949/**********************************************************************/
1950static void
1951dnp3_al_get_timestamp(nstime_t *timestamp, tvbuff_t *tvb, int data_pos)
1952{
1953
1954 uint32_t hi, lo;
1955 uint64_t time_ms;
1956
1957 lo = tvb_get_letohs(tvb, data_pos);
1958 hi = tvb_get_letohl(tvb, data_pos + 2);
1959
1960 time_ms = (uint64_t)hi * 0x10000 + lo;
1961
1962 timestamp->secs = (long)(time_ms / 1000);
1963 timestamp->nsecs = (int)(time_ms % 1000) * 1000000;
1964}
1965
1966static bool_Bool
1967dnp3_al_empty_obj(uint16_t al_obj)
1968{
1969
1970 /* return a true if we expect an empty object (default var, class object, etc) */
1971 switch (al_obj)
1972 {
1973 case AL_OBJ_BI_ALL0x0100: /* Binary Input Default Variation (Obj:01, Var:Default) */
1974 case AL_OBJ_BIC_ALL0x0200: /* Binary Input Change Default Variation (Obj:02, Var:Default) */
1975 case AL_OBJ_BOC_ALL0x0B00: /* Binary Output Event Default Variation (Obj:11, Var:Default) */
1976 case AL_OBJ_2BI_ALL0x0300: /* Double-bit Input Default Variation (Obj:03, Var:Default) */
1977 case AL_OBJ_2BIC_ALL0x0400: /* Double-bit Input Change Default Variation (Obj:04, Var:Default) */
1978 case AL_OBJ_CTR_ALL0x1400: /* Binary Counter Default Variation (Obj:20, Var:Default) */
1979 case AL_OBJ_CTRC_ALL0x1600: /* Binary Counter Change Default Variation (Obj:22 Var:Default) */
1980 case AL_OBJ_AI_ALL0x1E00: /* Analog Input Default Variation (Obj:30, Var:Default) */
1981 case AL_OBJ_AIC_ALL0x2000: /* Analog Input Change Default Variation (Obj:32 Var:Default) */
1982 case AL_OBJ_AIDB_ALL0x2200: /* Analog Input Deadband Default Variation (Obj:34, Var:Default) */
1983 case AL_OBJ_AOC_ALL0x2A00: /* Analog Output Event Default Variation (Obj:42 Var:Default) */
1984 case AL_OBJ_CLASS00x3C01: /* Class Data Objects */
1985 case AL_OBJ_CLASS10x3C02:
1986 case AL_OBJ_CLASS20x3C03:
1987 case AL_OBJ_CLASS30x3C04:
1988 return true1;
1989 default:
1990 return false0;
1991 }
1992}
1993
1994/*****************************************************************/
1995/* Desc: Application Layer Process Object Details */
1996/* Returns: New offset pointer into tvb */
1997/*****************************************************************/
1998static int
1999dnp3_al_process_object(tvbuff_t *tvb, packet_info *pinfo, int offset,
2000 proto_tree *robj_tree, bool_Bool header_only,
2001 uint16_t *al_objtype, nstime_t *al_cto)
2002{
2003
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;
2007 int num_items = 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;
2013
2014 /* Application Layer Objects in this Message */
2015 *al_objtype =
2016 al_obj = tvb_get_ntohs(tvb, offset);
2017
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_OCT0x6E00) || (temp == AL_OBJ_OCT_EVT0x6F00 )) {
2021 al_oct_len = al_obj & 0xFF;
2022 al_obj = temp;
2023 }
2024
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_AGMRQ0x7803) || (al_obj == AL_OBJ_SA_AUTH_MAC0x7809)) {
2028 header_only = false0;
2029 }
2030
2031 /* Create Data Objects Detail Tree */
2032 if (AL_OBJ_GROUP(al_obj)(((al_obj) & 0xFF00) >> 8) == 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"),
2036 al_obj);
2037 if (try_val_to_str_ext(al_obj, &dnp3_al_obj_vals_ext) == NULL((void*)0)) {
2038 expert_add_info(pinfo, object_item, &ei_dnp3_unknown_group0_variation);
2039 }
2040 }
2041 else if ((AL_OBJ_GROUP(al_obj)(((al_obj) & 0xFF00) >> 8) == AL_OBJ_GROUP(AL_OBJ_OCT)(((0x6E00) & 0xFF00) >> 8)) || (AL_OBJ_GROUP(al_obj)(((al_obj) & 0xFF00) >> 8) == AL_OBJ_GROUP(AL_OBJ_OCT_EVT)(((0x6F00) & 0xFF00) >> 8))) {
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);
2047 }
2048 else {
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"),
2052 al_obj);
2053 if (try_val_to_str_ext(al_obj, &dnp3_al_obj_vals_ext) == NULL((void*)0)) {
2054 expert_add_info(pinfo, object_item, &ei_dnp3_unknown_object);
2055 }
2056 }
2057 object_tree = proto_item_add_subtree(object_item, ett_dnp3_al_obj);
2058
2059 offset += 2;
2060
2061 /* Object Qualifier */
2062 al_objq = tvb_get_uint8(tvb, offset);
2063 al_objq_prefix = al_objq & AL_OBJQ_PREFIX0x70;
2064 al_objq_prefix = al_objq_prefix >> 4;
2065 al_objq_range = al_objq & AL_OBJQ_RANGE0x0F;
2066
2067 qualifier_tree = proto_tree_add_subtree_format(object_tree, tvb, offset, 1, ett_dnp3_al_obj_qualifier, NULL((void*)0),
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_ENDIAN0x00000000);
2072 proto_tree_add_item(qualifier_tree, hf_dnp3_al_objq_range, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2073
2074 offset += 1;
2075
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: ");
2078
2079 switch (al_objq_range)
2080 {
2081 case AL_OBJQL_RANGE_SSI80x00: /* 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_ENDIAN0x80000000);
2086 proto_tree_add_item(range_tree, hf_dnp3_al_range_stop8, tvb, offset + 1, 1, ENC_LITTLE_ENDIAN0x80000000);
2087 rangebytes = 2;
2088 break;
2089 case AL_OBJQL_RANGE_SSI160x01: /* 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_ENDIAN0x80000000);
2094 proto_tree_add_item(range_tree, hf_dnp3_al_range_stop16, tvb, offset + 2, 2, ENC_LITTLE_ENDIAN0x80000000);
2095 rangebytes = 4;
2096 break;
2097 case AL_OBJQL_RANGE_SSI320x02: /* 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_ENDIAN0x80000000);
2102 proto_tree_add_item(range_tree, hf_dnp3_al_range_stop32, tvb, offset + 4, 4, ENC_LITTLE_ENDIAN0x80000000);
2103 rangebytes = 8;
2104 break;
2105 case AL_OBJQL_RANGE_AA80x03: /* 8-bit Absolute Address in Range Field */
2106 num_items = 1;
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_ENDIAN0x80000000);
2110 rangebytes = 1;
2111 break;
2112 case AL_OBJQL_RANGE_AA160x04: /* 16-bit Absolute Address in Range Field */
2113 num_items = 1;
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_ENDIAN0x80000000);
2117 rangebytes = 2;
2118 break;
2119 case AL_OBJQL_RANGE_AA320x05: /* 32-bit Absolute Address in Range Field */
2120 num_items = 1;
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_ENDIAN0x80000000);
2124 rangebytes = 4;
2125 break;
2126 case AL_OBJQL_RANGE_SF80x07: /* 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_ENDIAN0x80000000);
2129 rangebytes = 1;
2130 proto_item_set_len(range_item, rangebytes);
2131 break;
2132 case AL_OBJQL_RANGE_SF160x08: /* 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_ENDIAN0x80000000);
2135 rangebytes = 2;
2136 proto_item_set_len(range_item, rangebytes);
2137 break;
2138 case AL_OBJQL_RANGE_SF320x09: /* 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_ENDIAN0x80000000);
2141 rangebytes = 4;
2142 proto_item_set_len(range_item, rangebytes);
2143 break;
2144 case AL_OBJQL_RANGE_FF0x0B: /* 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_ENDIAN0x80000000);
2147 rangebytes = 1;
2148 proto_item_set_len(range_item, rangebytes);
2149 }
2150 if (num_items > 0) {
2151 proto_item_append_text(object_item, ", %d point%s", num_items, plurality(num_items, "", "s")((num_items) == 1 ? ("") : ("s")));
2152 }
2153 proto_item_append_text(range_item, "%d", num_items);
2154
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);
2160 }
2161
2162 /* Move offset past any range field */
2163 offset += rangebytes;
2164
2165 bitindex = 0; /* Temp variable for cycling through points when object values are encoded into
2166 bits; primarily objects 0x0101, 0x0301 & 0x1001 */
2167
2168 /* Only process the point information for replies or items with point index lists */
2169 if (!header_only || al_objq_prefix > 0) {
2170 int item_num;
2171 int start_offset;
2172
2173 start_offset = offset;
2174 for (item_num = 0; item_num < num_items; item_num++)
2175 {
2176 proto_item *point_item;
2177 proto_tree *point_tree;
2178 unsigned data_pos;
2179 int prefixbytes;
2180
2181 /* Create Point item and process prefix */
2182 if (al_objq_prefix <= AL_OBJQL_PREFIX_4O0x03) {
2183 point_tree = proto_tree_add_subtree(object_tree, tvb, offset, -1, ett_dnp3_al_obj_point, &point_item, "Point Number");
2184 }
2185 else {
2186 point_tree = proto_tree_add_subtree(object_tree, tvb, offset, -1, ett_dnp3_al_obj_point, &point_item, "Object: Size");
2187 }
2188
2189 data_pos = offset;
2190 prefixbytes = dnp3_al_obj_procprefix(tvb, offset, al_objq_prefix, &al_ptaddr, point_tree);
2191
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);
2197 num_items = 0;
2198 }
2199
2200 proto_item_append_text(point_item, " %u", al_ptaddr);
2201 proto_item_set_len(point_item, prefixbytes);
2202 data_pos += prefixbytes;
2203
2204 if (!header_only || (AL_OBJQL_PREFIX_1OS0x04 <= al_objq_prefix && al_objq_prefix <= AL_OBJQL_PREFIX_4OS0x06)) {
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;
2214 bool_Bool al_bit;
2215 float al_valflt;
2216 double al_valdbl;
2217 const char *ctl_status_str;
2218
2219 /* Device Attributes (g0) all have a type code, use that rather than the individual variation */
2220 if (AL_OBJ_GROUP(al_obj)(((al_obj) & 0xFF00) >> 8) == 0x0) {
2221 uint32_t data_type;
2222 uint8_t da_len;
2223
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_ENDIAN0x80000000, &data_type);
2226 data_pos++;
2227
2228 /* If a valid data type process it */
2229 if (try_val_to_str(data_type, dnp3_al_data_type_vals) != NULL((void*)0)) {
2230 switch(data_type) {
2231 case AL_DATA_TYPE_NONE0x0:
2232 break;
2233 case AL_DATA_TYPE_VSTR0x1:
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_ENDIAN0x80000000);
2236 data_pos++;
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_ASCII0x00000000|ENC_NA0x00000000, pinfo->pool, &da_value);
2239 proto_item_append_text(object_item, ", Value: %s", da_value);
2240 data_pos += da_len;
2241 break;
2242 case AL_DATA_TYPE_UINT0x2:
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_ENDIAN0x80000000);
2245 data_pos++;
2246 if (da_len == 1) {
2247 proto_tree_add_item(point_tree, hf_dnp3_al_da_uint8, tvb, data_pos, 1, ENC_LITTLE_ENDIAN0x80000000);
2248 proto_item_append_text(object_item, ", Value: %u", tvb_get_uint8(tvb, data_pos));
2249 data_pos++;
2250 }
2251 else if (da_len == 2) {
2252 proto_tree_add_item(point_tree, hf_dnp3_al_da_uint16, tvb, data_pos, 2, ENC_LITTLE_ENDIAN0x80000000);
2253 proto_item_append_text(object_item, ", Value: %u", tvb_get_letohs(tvb, data_pos));
2254 data_pos += 2;
2255 }
2256 else if (da_len == 4) {
2257 proto_tree_add_item(point_tree, hf_dnp3_al_da_uint32, tvb, data_pos, 4, ENC_LITTLE_ENDIAN0x80000000);
2258 proto_item_append_text(object_item, ", Value: %u", tvb_get_letohl(tvb, data_pos));
2259 data_pos += 4;
2260 }
2261 break;
2262 case AL_DATA_TYPE_INT0x3:
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_ENDIAN0x80000000);
2265 data_pos++;
2266 if (da_len == 1) {
2267 proto_tree_add_item(point_tree, hf_dnp3_al_da_int8, tvb, data_pos, 1, ENC_LITTLE_ENDIAN0x80000000);
2268 proto_item_append_text(object_item, ", Value: %d", tvb_get_uint8(tvb, data_pos));
2269 data_pos++;
2270 }
2271 else if (da_len == 2) {
2272 proto_tree_add_item(point_tree, hf_dnp3_al_da_int16, tvb, data_pos, 2, ENC_LITTLE_ENDIAN0x80000000);
2273 proto_item_append_text(object_item, ", Value: %d", tvb_get_letohs(tvb, data_pos));
2274 data_pos += 2;
2275 }
2276 else if (da_len == 4) {
2277 proto_tree_add_item(point_tree, hf_dnp3_al_da_int32, tvb, data_pos, 4, ENC_LITTLE_ENDIAN0x80000000);
2278 proto_item_append_text(object_item, ", Value: %d", tvb_get_letohl(tvb, data_pos));
2279 data_pos += 4;
2280 }
2281 break;
2282 case AL_DATA_TYPE_FLT0x4:
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_ENDIAN0x80000000);
2285 data_pos++;
2286 if (da_len == 4) {
2287 proto_tree_add_item(point_tree, hf_dnp3_al_da_flt, tvb, data_pos, 4, ENC_LITTLE_ENDIAN0x80000000);
2288 proto_item_append_text(object_item, ", Value: %g", tvb_get_letohieee_float(tvb, data_pos));
2289 data_pos += 4;
2290 }
2291 else if (da_len == 8) {
2292 proto_tree_add_item(point_tree, hf_dnp3_al_da_dbl, tvb, data_pos, 8, ENC_LITTLE_ENDIAN0x80000000);
2293 proto_item_append_text(object_item, ", Value: %g", tvb_get_letohieee_double(tvb, data_pos));
2294 data_pos += 8;
2295 }
2296 break;
2297 case AL_DATA_TYPE_OSTR0x5:
2298 break;
2299 case AL_DATA_TYPE_BSTR0x6:
2300 break;
2301 case AL_DATA_TYPE_TIME0x7:
2302 break;
2303 case AL_DATA_TYPE_UNCD0x8:
2304 break;
2305 case AL_DATA_TYPE_U8BS8LIST0xFE:
2306 break;
2307 case AL_DATA_TYPE_U8BS8EXLIST0xFF:
2308 break;
2309 }
2310 }
2311 offset = data_pos;
2312 }
2313 else {
2314
2315 /* All other objects are handled here, by their variations */
2316 switch (al_obj)
2317 {
2318
2319 /* There is nothing to handle for the default variations */
2320 case AL_OBJ_BI_ALL0x0100: /* Binary Input Default Variation (Obj:01, Var:Default) */
2321 case AL_OBJ_BIC_ALL0x0200: /* Binary Input Change Default Variation (Obj:02, Var:Default) */
2322 case AL_OBJ_BOC_ALL0x0B00: /* Binary Output Event Default Variation (Obj:11, Var:Default) */
2323 case AL_OBJ_2BI_ALL0x0300: /* Double-bit Input Default Variation (Obj:03, Var:Default) */
2324 case AL_OBJ_2BIC_ALL0x0400: /* Double-bit Input Change Default Variation (Obj:04, Var:Default) */
2325 case AL_OBJ_CTR_ALL0x1400: /* Binary Counter Default Variation (Obj:20, Var:Default) */
2326 case AL_OBJ_CTRC_ALL0x1600: /* Binary Counter Change Default Variation (Obj:22 Var:Default) */
2327 case AL_OBJ_AI_ALL0x1E00: /* Analog Input Default Variation (Obj:30, Var:Default) */
2328 case AL_OBJ_AIC_ALL0x2000: /* Analog Input Change Default Variation (Obj:32 Var:Default) */
2329 case AL_OBJ_AIDB_ALL0x2200: /* Analog Input Deadband Default Variation (Obj:34, Var:Default) */
2330 case AL_OBJ_AOC_ALL0x2A00: /* Analog Output Event Default Variation (Obj:42 Var:Default) */
2331 case AL_OBJ_CLASS00x3C01: /* Class Data Objects */
2332 case AL_OBJ_CLASS10x3C02:
2333 case AL_OBJ_CLASS20x3C03:
2334 case AL_OBJ_CLASS30x3C04:
2335
2336 offset = data_pos;
2337 break;
2338
2339 /* Bit-based Data objects here */
2340 case AL_OBJ_BI_1BIT0x0101: /* Single-Bit Binary Input (Obj:01, Var:01) */
2341 case AL_OBJ_BO0x0A01: /* Binary Output (Obj:10, Var:01) */
2342 case AL_OBJ_CTL_PMASK0x0C03: /* Pattern Mask (Obj:12, Var:03) */
2343 case AL_OBJ_IIN0x5001: /* Internal Indications - IIN (Obj: 80, Var:01) */
2344
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_IIN0x5001) {
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;
2353 }
2354 else {
2355 iin_bit = 1 << (al_ptaddr - 8);
2356 }
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);
2359 }
2360 else
2361 {
2362 if (al_objq_prefix != AL_OBJQL_PREFIX_NI0x00) {
2363 /* Each item has an index prefix, in this case bump
2364 the bitindex to force the correct offset adjustment */
2365 bitindex = 7;
2366 }
2367 else {
2368 /* Regular packed bits, get the value at the appropriate bit index */
2369 al_bit = (al_bi_val & (1 << bitindex)) > 0;
2370 }
2371 proto_item_append_text(point_item, ", Value: %u", al_bit);
2372 }
2373 switch(bitindex) {
2374 case 0:
2375 proto_tree_add_boolean(point_tree, hf_dnp3_al_bit0, tvb, data_pos, 1, al_bi_val);
2376 break;
2377 case 1:
2378 proto_tree_add_boolean(point_tree, hf_dnp3_al_bit1, tvb, data_pos, 1, al_bi_val);
2379 break;
2380 case 2:
2381 proto_tree_add_boolean(point_tree, hf_dnp3_al_bit2, tvb, data_pos, 1, al_bi_val);
2382 break;
2383 case 3:
2384 proto_tree_add_boolean(point_tree, hf_dnp3_al_bit3, tvb, data_pos, 1, al_bi_val);
2385 break;
2386 case 4:
2387 proto_tree_add_boolean(point_tree, hf_dnp3_al_bit4, tvb, data_pos, 1, al_bi_val);
2388 break;
2389 case 5:
2390 proto_tree_add_boolean(point_tree, hf_dnp3_al_bit5, tvb, data_pos, 1, al_bi_val);
2391 break;
2392 case 6:
2393 proto_tree_add_boolean(point_tree, hf_dnp3_al_bit6, tvb, data_pos, 1, al_bi_val);
2394 break;
2395 case 7:
2396 proto_tree_add_boolean(point_tree, hf_dnp3_al_bit7, tvb, data_pos, 1, al_bi_val);
2397 break;
2398
2399 default:
2400 break;
2401 }
2402 proto_item_set_len(point_item, prefixbytes + 1);
2403
2404 /* Increment the bit index for next cycle */
2405 bitindex++;
2406
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)))
2410 {
2411 bitindex = 0;
2412 offset += (prefixbytes + 1);
2413 }
2414 break;
2415
2416 case AL_OBJ_2BI_NF0x0301: /* Double-bit Input No Flags (Obj:03, Var:01) */
2417
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);
2421
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)"));
2423 switch (bitindex)
2424 {
2425 case 0:
2426 proto_tree_add_uint(point_tree, hf_dnp3_al_2bit0, tvb, offset, 1, al_bi_val);
2427 break;
2428 case 1:
2429 proto_tree_add_uint(point_tree, hf_dnp3_al_2bit1, tvb, offset, 1, al_bi_val);
2430 break;
2431 case 2:
2432 proto_tree_add_uint(point_tree, hf_dnp3_al_2bit2, tvb, offset, 1, al_bi_val);
2433 break;
2434 case 3:
2435 proto_tree_add_uint(point_tree, hf_dnp3_al_2bit3, tvb, offset, 1, al_bi_val);
2436 break;
2437
2438 default:
2439 break;
2440 }
2441 proto_item_set_len(point_item, prefixbytes + 1);
2442
2443 /* Increment the bit index for next cycle */
2444 bitindex++;
2445
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)))
2449 {
2450 bitindex = 0;
2451 offset += (prefixbytes + 1);
2452 }
2453 break;
2454
2455 case AL_OBJ_BI_STAT0x0102: /* Binary Input With Status (Obj:01, Var:02) */
2456 case AL_OBJ_BIC_NOTIME0x0201: /* Binary Input Change Without Time (Obj:02, Var:01) */
2457 case AL_OBJ_BO_STAT0x0A02: /* Binary Output Status (Obj:10, Var:02) */
2458 case AL_OBJ_BOC_NOTIME0x0B01: /* Binary Output Change Without Time (Obj:11, Var:01) */
2459
2460 /* Get Point Flags */
2461 al_ptflags = tvb_get_uint8(tvb, data_pos);
2462
2463 switch (al_obj) {
2464 case AL_OBJ_BI_STAT0x0102:
2465 case AL_OBJ_BIC_NOTIME0x0201:
2466 dnp3_al_obj_quality(tvb, data_pos, al_ptflags, point_tree, point_item, BIN_IN);
2467 break;
2468 case AL_OBJ_BO_STAT0x0A02:
2469 case AL_OBJ_BOC_NOTIME0x0B01:
2470 dnp3_al_obj_quality(tvb, data_pos, al_ptflags, point_tree, point_item, BIN_OUT);
2471 break;
2472 }
2473 data_pos += 1;
2474
2475 al_bit = (al_ptflags & AL_OBJ_BI_FLAG70x80) > 0;
2476 proto_item_append_text(point_item, ", Value: %u", al_bit);
2477
2478 proto_item_set_len(point_item, data_pos - offset);
2479
2480 offset = data_pos;
2481 break;
2482
2483 case AL_OBJ_2BI_STAT0x0302: /* Double-bit Input With Status (Obj:03, Var:02) */
2484 case AL_OBJ_2BIC_NOTIME0x0401: /* Double-bit Input Change Without Time (Obj:04, Var:01) */
2485
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);
2489 data_pos += 1;
2490
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);
2494
2495 offset = data_pos;
2496 break;
2497
2498 case AL_OBJ_BIC_TIME0x0202: /* Binary Input Change w/ Time (Obj:02, Var:02) */
2499 case AL_OBJ_BOC_TIME0x0B02: /* Binary Output Change w/ Time (Obj:11, Var:02) */
2500
2501 /* Get Point Flags */
2502 al_ptflags = tvb_get_uint8(tvb, data_pos);
2503 switch (al_obj) {
2504 case AL_OBJ_BIC_TIME0x0202:
2505 dnp3_al_obj_quality(tvb, data_pos, al_ptflags, point_tree, point_item, BIN_IN);
2506 break;
2507 case AL_OBJ_BOC_TIME0x0B02:
2508 dnp3_al_obj_quality(tvb, data_pos, al_ptflags, point_tree, point_item, BIN_OUT);
2509 break;
2510 }
2511 data_pos += 1;
2512
2513 /* Get timestamp */
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);
2516 data_pos += 6;
2517
2518 al_bit = (al_ptflags & AL_OBJ_BI_FLAG70x80) >> 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)abs_time_to_str_ex(pinfo->pool, &al_abstime, ABSOLUTE_TIME_UTC
, (0) ? (1U << 0) : 0)
);
2521 proto_item_set_len(point_item, data_pos - offset);
2522
2523 offset = data_pos;
2524 break;
2525
2526 case AL_OBJ_2BIC_TIME0x0402: /* Double-bit Input Change w/ Time (Obj:04, Var:02) */
2527
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);
2531 data_pos += 1;
2532
2533 /* Get timestamp */
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);
2536 data_pos += 6;
2537
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)abs_time_to_str_ex(pinfo->pool, &al_abstime, ABSOLUTE_TIME_UTC
, ((0)) ? (1U << 0) : 0)
);
2542 proto_item_set_len(point_item, data_pos - offset);
2543
2544 offset = data_pos;
2545 break;
2546
2547 case AL_OBJ_BIC_RTIME0x0203: /* Binary Input Change w/ Relative Time (Obj:02, Var:03) */
2548 case AL_OBJ_2BIC_RTIME0x0403: /* Double-bit Input Change w/ Relative Time (Obj:04, Var:03) */
2549
2550 /* Get Point Flags */
2551 al_ptflags = tvb_get_uint8(tvb, data_pos);
2552 if (al_obj == AL_OBJ_BIC_RTIME0x0203) {
2553 dnp3_al_obj_quality(tvb, data_pos, al_ptflags, point_tree, point_item, BIN_IN);
2554 }
2555 else /* MUST be AL_OBJ_2BIC_RTIME */ {
2556 dnp3_al_obj_quality(tvb, data_pos, al_ptflags, point_tree, point_item, DBIN_IN);
2557 }
2558 data_pos += 1;
2559
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);
2567 data_pos += 2;
2568
2569 switch (al_obj) {
2570 case AL_OBJ_BIC_RTIME0x0203:
2571 al_bit = (al_ptflags & AL_OBJ_BI_FLAG70x80) >> 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)abs_time_to_str_ex(pinfo->pool, &al_abstime, ABSOLUTE_TIME_UTC
, (0) ? (1U << 0) : 0)
);
2574 break;
2575 case AL_OBJ_2BIC_RTIME0x0403:
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)abs_time_to_str_ex(pinfo->pool, &al_abstime, ABSOLUTE_TIME_UTC
, ((0)) ? (1U << 0) : 0)
);
2580 break;
2581 }
2582 proto_item_set_len(point_item, data_pos - offset);
2583
2584 offset = data_pos;
2585 break;
2586
2587 case AL_OBJ_CTLOP_BLK0x0C01: /* Control Relay Output Block (Obj:12, Var:01) */
2588 case AL_OBJ_CTL_PCB0x0C02: /* Pattern Control Block (Obj:12, Var:02) */
2589 {
2590 proto_tree *tcc_tree;
2591
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((void*)0), "Control Code [0x%02x]",al_tcc_code);
2596
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_CODE0x0F),
2599 dnp3_al_ctlc_code_vals,
2600 "Invalid Operation"));
2601
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_TC0xC0) >> 6,
2604 dnp3_al_ctlc_tc_vals,
2605 "Invalid Qualifier"));
2606
2607
2608
2609 /* Control Code 'Operation Type' */
2610 proto_tree_add_item(tcc_tree, hf_dnp3_ctlobj_code_c, tvb, data_pos, 1, ENC_LITTLE_ENDIAN0x80000000);
2611
2612 /* Control Code Misc Values */
2613 proto_tree_add_item(tcc_tree, hf_dnp3_ctlobj_code_m, tvb, data_pos, 1, ENC_LITTLE_ENDIAN0x80000000);
2614
2615 /* Control Code 'Trip Close Code' */
2616 proto_tree_add_item(tcc_tree, hf_dnp3_ctlobj_code_tc, tvb, data_pos, 1, ENC_LITTLE_ENDIAN0x80000000);
2617 data_pos += 1;
2618
2619 /* Get "Count" Field */
2620 proto_tree_add_item(point_tree, hf_dnp3_al_count, tvb, data_pos, 1, ENC_LITTLE_ENDIAN0x80000000);
2621 data_pos += 1;
2622
2623 /* Get "On Time" Field */
2624 proto_tree_add_item(point_tree, hf_dnp3_al_on_time, tvb, data_pos, 4, ENC_LITTLE_ENDIAN0x80000000);
2625 data_pos += 4;
2626
2627 /* Get "Off Time" Field */
2628 proto_tree_add_item(point_tree, hf_dnp3_al_off_time, tvb, data_pos, 4, ENC_LITTLE_ENDIAN0x80000000);
2629 data_pos += 4;
2630
2631 /* Get "Control Status" Field */
2632 proto_tree_add_item(point_tree, hf_dnp3_al_ctrlstatus, tvb, data_pos, 1, ENC_LITTLE_ENDIAN0x80000000);
2633 data_pos += 1;
2634
2635 proto_item_set_len(point_item, data_pos - offset);
2636
2637 offset = data_pos;
2638 break;
2639 }
2640
2641 case AL_OBJ_BOE_NOTIME0x0D01: /* Binary Command Event (Obj:13, Var:01) */
2642 case AL_OBJ_BOE_TIME0x0D02: /* Binary Command Event with time (Obj:13, Var:02) */
2643 case AL_OBJ_AOC_32EVNT0x2B01: /* 32-bit Analog Command Event (Obj:43, Var:01) */
2644 case AL_OBJ_AOC_16EVNT0x2B02: /* 16-bit Analog Command Event (Obj:43, Var:02) */
2645 case AL_OBJ_AOC_32EVTT0x2B03: /* 32-bit Analog Command Event with time (Obj:43, Var:03) */
2646 case AL_OBJ_AOC_16EVTT0x2B04: /* 16-bit Analog Command Event with time (Obj:43, Var:04) */
2647 case AL_OBJ_AOC_FLTEVNT0x2B05: /* 32-bit Floating Point Analog Command Event (Obj:43, Var:05) */
2648 case AL_OBJ_AOC_DBLEVNT0x2B06: /* 64-bit Floating Point Analog Command Event (Obj:43, Var:06) */
2649 case AL_OBJ_AOC_FLTEVTT0x2B07: /* 32-bit Floating Point Analog Command Event with time (Obj:43, Var:07) */
2650 case AL_OBJ_AOC_DBLEVTT0x2B08: /* 64-bit Floating Point Analog Command Event with time (Obj:43, Var:08) */
2651 {
2652 /* Get the status code */
2653 al_ctlobj_stat = tvb_get_uint8(tvb, data_pos) & AL_OBJCTL_STATUS_MASK0x7F;
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_ENDIAN0x80000000);
2657
2658 /* Get the command value */
2659 switch(al_obj)
2660 {
2661 case AL_OBJ_BOE_NOTIME0x0D01:
2662 case AL_OBJ_BOE_TIME0x0D02:
2663 proto_tree_add_item(point_tree, hf_dnp3_bocs_bit, tvb, data_pos, 1, ENC_LITTLE_ENDIAN0x80000000);
2664 data_pos += 1;
2665 break;
2666 case AL_OBJ_AOC_32EVNT0x2B01:
2667 case AL_OBJ_AOC_32EVTT0x2B03:
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_ENDIAN0x80000000);
2672 break;
2673 case AL_OBJ_AOC_16EVNT0x2B02:
2674 case AL_OBJ_AOC_16EVTT0x2B04:
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_ENDIAN0x80000000);
2679 data_pos += 2;
2680 break;
2681 case AL_OBJ_AOC_FLTEVNT0x2B05:
2682 case AL_OBJ_AOC_FLTEVTT0x2B07:
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_ENDIAN0x80000000);
2687 data_pos += 4;
2688 break;
2689 case AL_OBJ_AOC_DBLEVNT0x2B06:
2690 case AL_OBJ_AOC_DBLEVTT0x2B08:
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_ENDIAN0x80000000);
2695 data_pos += 8;
2696 break;
2697 }
2698
2699 /* Get the timestamp */
2700 switch(al_obj)
2701 {
2702 case AL_OBJ_BOE_TIME0x0D02: /* Binary Command Event with time (Obj:13, Var:02) */
2703 case AL_OBJ_AOC_32EVTT0x2B03: /* 32-bit Analog Command Event with time (Obj:43, Var:03) */
2704 case AL_OBJ_AOC_16EVTT0x2B04: /* 16-bit Analog Command Event with time (Obj:43, Var:04) */
2705 case AL_OBJ_AOC_FLTEVTT0x2B07: /* 32-bit Floating Point Analog Command Event with time (Obj:43, Var:07) */
2706 case AL_OBJ_AOC_DBLEVTT0x2B08: /* 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)abs_time_to_str_ex(pinfo->pool, &al_abstime, ABSOLUTE_TIME_UTC
, (0) ? (1U << 0) : 0)
);
2709 proto_tree_add_time(point_tree, hf_dnp3_al_timestamp, tvb, data_pos, 6, &al_abstime);
2710 data_pos += 6;
2711 break;
2712 }
2713
2714 proto_item_set_len(point_item, data_pos - offset);
2715 offset = data_pos;
2716 break;
2717 }
2718
2719 case AL_OBJ_AO_32OPB0x2901: /* 32-Bit Analog Output Block (Obj:41, Var:01) */
2720 case AL_OBJ_AO_16OPB0x2902: /* 16-Bit Analog Output Block (Obj:41, Var:02) */
2721 case AL_OBJ_AO_FLTOPB0x2903: /* 32-Bit Floating Point Output Block (Obj:41, Var:03) */
2722 case AL_OBJ_AO_DBLOPB0x2904: /* 64-Bit Floating Point Output Block (Obj:41, Var:04) */
2723
2724 switch (al_obj)
2725 {
2726 case AL_OBJ_AO_32OPB0x2901:
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_ENDIAN0x80000000);
2730 data_pos += 4;
2731 break;
2732 case AL_OBJ_AO_16OPB0x2902:
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_ENDIAN0x80000000);
2736 data_pos += 2;
2737 break;
2738 case AL_OBJ_AO_FLTOPB0x2903:
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_ENDIAN0x80000000);
2742 data_pos += 4;
2743 break;
2744 case AL_OBJ_AO_DBLOPB0x2904:
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_ENDIAN0x80000000);
2748 data_pos += 8;
2749 break;
2750 }
2751
2752 /* Get control status */
2753 al_ctlobj_stat = tvb_get_uint8(tvb, data_pos) & AL_OBJCTL_STATUS_MASK0x7F;
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_ENDIAN0x80000000);
2757 data_pos += 1;
2758
2759 proto_item_set_len(point_item, data_pos - offset);
2760
2761 offset = data_pos;
2762 break;
2763
2764 case AL_OBJ_CTR_320x1401: /* 32-Bit Binary Counter (Obj:20, Var:01) */
2765 case AL_OBJ_CTR_160x1402: /* 16-Bit Binary Counter (Obj:20, Var:02) */
2766 case AL_OBJ_DCTR_320x1403: /* 32-Bit Binary Delta Counter (Obj:20, Var:03) */
2767 case AL_OBJ_DCTR_160x1404: /* 16-Bit Binary Delta Counter (Obj:20, Var:04) */
2768 case AL_OBJ_CTR_32NF0x1405: /* 32-Bit Binary Counter Without Flag (Obj:20, Var:05) */
2769 case AL_OBJ_CTR_16NF0x1406: /* 16-Bit Binary Counter Without Flag (Obj:20, Var:06) */
2770 case AL_OBJ_DCTR_32NF0x1407: /* 32-Bit Binary Delta Counter Without Flag (Obj:20, Var:07) */
2771 case AL_OBJ_DCTR_16NF0x1408: /* 16-Bit Binary Delta Counter Without Flag (Obj:20, Var:08) */
2772 case AL_OBJ_FCTR_320x1501: /* 32-Bit Frozen Counter (Obj:21, Var:01) */
2773 case AL_OBJ_FCTR_160x1502: /* 16-Bit Frozen Counter (Obj:21, Var:02) */
2774 case AL_OBJ_FDCTR_320x1503: /* 21 03 32-Bit Frozen Delta Counter */
2775 case AL_OBJ_FDCTR_160x1504: /* 21 04 16-Bit Frozen Delta Counter */
2776 case AL_OBJ_FCTR_32T0x1505: /* 32-Bit Frozen Counter w/ Time of Freeze (Obj:21 Var:05 ) */
2777 case AL_OBJ_FCTR_16T0x1506: /* 16-Bit Frozen Counter w/ Time of Freeze (Obj:21 Var:06) */
2778 case AL_OBJ_FDCTR_32T0x1507: /* 32-Bit Frozen Delta Counter w/ Time of Freeze (Obj:21 Var:07) */
2779 case AL_OBJ_FDCTR_16T0x1508: /* 16-Bit Frozen Delta Counter w/ Time of Freeze (Obj:21 Var:08) */
2780 case AL_OBJ_FCTR_32NF0x1509: /* 32-Bit Frozen Counter Without Flag (Obj:21 Var:09) */
2781 case AL_OBJ_FCTR_16NF0x150A: /* 16-Bit Frozen Counter Without Flag (Obj:21 Var:10) */
2782 case AL_OBJ_FDCTR_32NF0x150B: /* 32-Bit Frozen Delta Counter Without Flag (Obj:21 Var:11) */
2783 case AL_OBJ_FDCTR_16NF0x150C: /* 16-Bit Frozen Delta Counter Without Flag (Obj:21 Var:12) */
2784 case AL_OBJ_CTRC_320x1601: /* 32-Bit Counter Change Event w/o Time (Obj:22, Var:01) */
2785 case AL_OBJ_CTRC_160x1602: /* 16-Bit Counter Change Event w/o Time (Obj:22, Var:02) */
2786 case AL_OBJ_DCTRC_320x1603: /* 32-Bit Delta Counter Change Event w/o Time (Obj:22, Var:03) */
2787 case AL_OBJ_DCTRC_160x1604: /* 16-Bit Delta Counter Change Event w/o Time (Obj:22, Var:04) */
2788 case AL_OBJ_CTRC_32T0x1605: /* 32-Bit Counter Change Event with Time (Obj:22, Var:05) */
2789 case AL_OBJ_CTRC_16T0x1606: /* 16-Bit Counter Change Event with Time (Obj:22, Var:06) */
2790 case AL_OBJ_DCTRC_32T0x1607: /* 32-Bit Delta Counter Change Event with Time (Obj:22, Var:07) */
2791 case AL_OBJ_DCTRC_16T0x1608: /* 16-Bit Delta Counter Change Event with Time (Obj:22, Var:08) */
2792 case AL_OBJ_FCTRC_320x1701: /* 32-Bit Frozen Counter Change Event (Obj:23 Var:01) */
2793 case AL_OBJ_FCTRC_160x1702: /* 16-Bit Frozen Counter Change Event (Obj:23 Var:02) */
2794 case AL_OBJ_FDCTRC_320x1703: /* 32-Bit Frozen Delta Counter Change Event (Obj:23 Var:03) */
2795 case AL_OBJ_FDCTRC_160x1704: /* 16-Bit Frozen Delta Counter Change Event (Obj:23 Var:04) */
2796 case AL_OBJ_FCTRC_32T0x1705: /* 32-Bit Frozen Counter Change Event w/ Time of Freeze (Obj:23 Var:05) */
2797 case AL_OBJ_FCTRC_16T0x1706: /* 16-Bit Frozen Counter Change Event w/ Time of Freeze (Obj:23 Var:06) */
2798 case AL_OBJ_FDCTRC_32T0x1707: /* 32-Bit Frozen Delta Counter Change Event w/ Time of Freeze (Obj:23 Var:07) */
2799 case AL_OBJ_FDCTRC_16T0x1708: /* 16-Bit Frozen Delta Counter Change Event w/ Time of Freeze (Obj:23 Var:08) */
2800
2801 /* Get Point Flags for those types that have them, it's easier to block out those that don't have flags */
2802 switch (al_obj)
2803 {
2804 case AL_OBJ_CTR_32NF0x1405:
2805 case AL_OBJ_CTR_16NF0x1406:
2806 case AL_OBJ_DCTR_32NF0x1407:
2807 case AL_OBJ_DCTR_16NF0x1408:
2808 case AL_OBJ_FCTR_32NF0x1509:
2809 case AL_OBJ_FCTR_16NF0x150A:
2810 case AL_OBJ_FDCTR_32NF0x150B:
2811 case AL_OBJ_FDCTR_16NF0x150C:
2812 break;
2813
2814 default:
2815 al_ptflags = tvb_get_uint8(tvb, data_pos);
2816 dnp3_al_obj_quality(tvb, data_pos, al_ptflags, point_tree, point_item, COUNTER);
2817 data_pos += 1;
2818 break;
2819 }
2820
2821 /* Get Counter values */
2822 switch (al_obj)
2823 {
2824 case AL_OBJ_CTR_320x1401:
2825 case AL_OBJ_DCTR_320x1403:
2826 case AL_OBJ_CTR_32NF0x1405:
2827 case AL_OBJ_DCTR_32NF0x1407:
2828 case AL_OBJ_FCTR_320x1501:
2829 case AL_OBJ_FDCTR_320x1503:
2830 case AL_OBJ_FCTR_32T0x1505:
2831 case AL_OBJ_FDCTR_32T0x1507:
2832 case AL_OBJ_FCTR_32NF0x1509:
2833 case AL_OBJ_FDCTR_32NF0x150B:
2834 case AL_OBJ_CTRC_320x1601:
2835 case AL_OBJ_DCTRC_320x1603:
2836 case AL_OBJ_CTRC_32T0x1605:
2837 case AL_OBJ_DCTRC_32T0x1607:
2838 case AL_OBJ_FCTRC_320x1701:
2839 case AL_OBJ_FDCTRC_320x1703:
2840 case AL_OBJ_FCTRC_32T0x1705:
2841 case AL_OBJ_FDCTRC_32T0x1707:
2842
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_ENDIAN0x80000000);
2846 data_pos += 4;
2847 break;
2848
2849 case AL_OBJ_CTR_160x1402:
2850 case AL_OBJ_DCTR_160x1404:
2851 case AL_OBJ_CTR_16NF0x1406:
2852 case AL_OBJ_DCTR_16NF0x1408:
2853 case AL_OBJ_FCTR_160x1502:
2854 case AL_OBJ_FDCTR_160x1504:
2855 case AL_OBJ_FCTR_16T0x1506:
2856 case AL_OBJ_FDCTR_16T0x1508:
2857 case AL_OBJ_FCTR_16NF0x150A:
2858 case AL_OBJ_FDCTR_16NF0x150C:
2859 case AL_OBJ_CTRC_160x1602:
2860 case AL_OBJ_DCTRC_160x1604:
2861 case AL_OBJ_CTRC_16T0x1606:
2862 case AL_OBJ_DCTRC_16T0x1608:
2863 case AL_OBJ_FCTRC_160x1702:
2864 case AL_OBJ_FDCTRC_160x1704:
2865 case AL_OBJ_FCTRC_16T0x1706:
2866 case AL_OBJ_FDCTRC_16T0x1708:
2867
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_ENDIAN0x80000000);
2871 data_pos += 2;
2872 break;
2873 }
2874
2875 /* Get the time for those points that have it */
2876 switch (al_obj)
2877 {
2878 case AL_OBJ_FCTR_32T0x1505:
2879 case AL_OBJ_FCTR_16T0x1506:
2880 case AL_OBJ_FDCTR_32T0x1507:
2881 case AL_OBJ_FDCTR_16T0x1508:
2882 case AL_OBJ_CTRC_32T0x1605:
2883 case AL_OBJ_CTRC_16T0x1606:
2884 case AL_OBJ_DCTRC_32T0x1607:
2885 case AL_OBJ_DCTRC_16T0x1608:
2886 case AL_OBJ_FCTRC_32T0x1705:
2887 case AL_OBJ_FCTRC_16T0x1706:
2888 case AL_OBJ_FDCTRC_32T0x1707:
2889 case AL_OBJ_FDCTRC_16T0x1708:
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)abs_time_to_str_ex(pinfo->pool, &al_abstime, ABSOLUTE_TIME_UTC
, (0) ? (1U << 0) : 0)
);
2892 proto_tree_add_time(point_tree, hf_dnp3_al_timestamp, tvb, data_pos, 6, &al_abstime);
2893 data_pos += 6;
2894 break;
2895 }
2896
2897 proto_item_set_len(point_item, data_pos - offset);
2898 offset = data_pos;
2899 break;
2900
2901 case AL_OBJ_AI_320x1E01: /* 32-Bit Analog Input (Obj:30, Var:01) */
2902 case AL_OBJ_AI_160x1E02: /* 16-Bit Analog Input (Obj:30, Var:02) */
2903 case AL_OBJ_AI_32NF0x1E03: /* 32-Bit Analog Input Without Flag (Obj:30, Var:03) */
2904 case AL_OBJ_AI_16NF0x1E04: /* 16-Bit Analog Input Without Flag (Obj:30, Var:04) */
2905 case AL_OBJ_AI_FLT0x1E05: /* 32-Bit Floating Point Input (Obj:30, Var:05) */
2906 case AL_OBJ_AI_DBL0x1E06: /* 64-Bit Floating Point Input (Obj:30, Var:06) */
2907 case AL_OBJ_AIFC_320x1F01: /* 32-Bit Frozen Analog Input (Obj:31, Var:01) */
2908 case AL_OBJ_AIFC_160x1F02: /* 16-Bit Frozen Analog Input (Obj:31, Var:02) */
2909 case AL_OBJ_AIFC_32TOF0x1F03: /* 32-Bit Frozen Analog Input w/ Time of Freeze (Obj:31, Var:03) */
2910 case AL_OBJ_AIFC_16TOF0x1F04: /* 16-Bit Frozen Analog Input w/ Time of Freeze (Obj:31, Var:04) */
2911 case AL_OBJ_AIFC_32NF0x1F05: /* 32-Bit Frozen Analog Input Without Flag (Obj:31, Var:05) */
2912 case AL_OBJ_AIFC_16NF0x1F06: /* 16-Bit Frozen Analog Input Without Flag (Obj:31, Var:06) */
2913 case AL_OBJ_AIF_FLT0x1F07: /* 32-Bit Frozen Floating Point Input (Obj:31, Var:07) */
2914 case AL_OBJ_AIF_DBL0x1F08: /* 64-Bit Frozen Floating Point Input (Obj:31, Var:08) */
2915 case AL_OBJ_AIC_32NT0x2001: /* 32-Bit Analog Change Event w/o Time (Obj:32, Var:01) */
2916 case AL_OBJ_AIC_16NT0x2002: /* 16-Bit Analog Change Event w/o Time (Obj:32, Var:02) */
2917 case AL_OBJ_AIC_32T0x2003: /* 32-Bit Analog Change Event with Time (Obj:32, Var:03) */
2918 case AL_OBJ_AIC_16T0x2004: /* 16-Bit Analog Change Event with Time (Obj:32, Var:04) */
2919 case AL_OBJ_AIC_FLTNT0x2005: /* 32-Bit Floating Point Change Event w/o Time (Obj:32, Var:05) */
2920 case AL_OBJ_AIC_DBLNT0x2006: /* 64-Bit Floating Point Change Event w/o Time (Obj:32, Var:06) */
2921 case AL_OBJ_AIC_FLTT0x2007: /* 32-Bit Floating Point Change Event w/ Time (Obj:32, Var:07) */
2922 case AL_OBJ_AIC_DBLT0x2008: /* 64-Bit Floating Point Change Event w/ Time (Obj:32, Var:08) */
2923 case AL_OBJ_AIFC_32NT0x2101: /* 32-Bit Frozen Analog Event w/o Time (Obj:33, Var:01) */
2924 case AL_OBJ_AIFC_16NT0x2102: /* 16-Bit Frozen Analog Event w/o Time (Obj:33, Var:02) */
2925 case AL_OBJ_AIFC_32T0x2103: /* 32-Bit Frozen Analog Event w/ Time (Obj:33, Var:03) */
2926 case AL_OBJ_AIFC_16T0x2104: /* 16-Bit Frozen Analog Event w/ Time (Obj:33, Var:04) */
2927 case AL_OBJ_AIFC_FLTNT0x2105: /* 32-Bit Floating Point Frozen Change Event w/o Time (Obj:33, Var:05) */
2928 case AL_OBJ_AIFC_DBLNT0x2106: /* 64-Bit Floating Point Frozen Change Event w/o Time (Obj:33, Var:06) */
2929 case AL_OBJ_AIFC_FLTT0x2107: /* 32-Bit Floating Point Frozen Change Event w/ Time (Obj:33, Var:07) */
2930 case AL_OBJ_AIFC_DBLT0x2108: /* 64-Bit Floating Point Frozen Change Event w/ Time (Obj:33, Var:08) */
2931 case AL_OBJ_AIDB_160x2201: /* 16-Bit Analog Input Deadband (Obj:34, Var:01) */
2932 case AL_OBJ_AIDB_320x2202: /* 32-Bit Analog Input Deadband (Obj:34, Var:02) */
2933 case AL_OBJ_AIDB_FLT0x2203: /* 32-Bit Floating Point Analog Input Deadband (Obj:34, Var:03) */
2934
2935 /* Get Point Flags for those types that have them */
2936 switch (al_obj)
2937 {
2938 case AL_OBJ_AI_32NF0x1E03:
2939 case AL_OBJ_AI_16NF0x1E04:
2940 case AL_OBJ_AIFC_32NF0x1F05:
2941 case AL_OBJ_AIFC_16NF0x1F06:
2942 case AL_OBJ_AIDB_160x2201:
2943 case AL_OBJ_AIDB_320x2202:
2944 case AL_OBJ_AIDB_FLT0x2203:
2945 break;
2946
2947 default:
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);
2950 data_pos += 1;
2951 break;
2952 }
2953
2954 switch (al_obj)
2955 {
2956 case AL_OBJ_AI_320x1E01:
2957 case AL_OBJ_AI_32NF0x1E03:
2958 case AL_OBJ_AIFC_320x1F01:
2959 case AL_OBJ_AIFC_32TOF0x1F03:
2960 case AL_OBJ_AIFC_32NF0x1F05:
2961 case AL_OBJ_AIC_32NT0x2001:
2962 case AL_OBJ_AIC_32T0x2003:
2963 case AL_OBJ_AIFC_32NT0x2101:
2964 case AL_OBJ_AIFC_32T0x2103:
2965 case AL_OBJ_AIDB_320x2202:
2966
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_ENDIAN0x80000000);
2970 data_pos += 4;
2971 break;
2972
2973 case AL_OBJ_AI_160x1E02:
2974 case AL_OBJ_AI_16NF0x1E04:
2975 case AL_OBJ_AIFC_160x1F02:
2976 case AL_OBJ_AIFC_16TOF0x1F04:
2977 case AL_OBJ_AIFC_16NF0x1F06:
2978 case AL_OBJ_AIC_16NT0x2002:
2979 case AL_OBJ_AIC_16T0x2004:
2980 case AL_OBJ_AIFC_16NT0x2102:
2981 case AL_OBJ_AIFC_16T0x2104:
2982 case AL_OBJ_AIDB_160x2201:
2983
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_ENDIAN0x80000000);
2987 data_pos += 2;
2988 break;
2989
2990 case AL_OBJ_AI_FLT0x1E05:
2991 case AL_OBJ_AIF_FLT0x1F07:
2992 case AL_OBJ_AIC_FLTNT0x2005:
2993 case AL_OBJ_AIC_FLTT0x2007:
2994 case AL_OBJ_AIFC_FLTNT0x2105:
2995 case AL_OBJ_AIFC_FLTT0x2107:
2996 case AL_OBJ_AIDB_FLT0x2203:
2997
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_ENDIAN0x80000000);
3001 data_pos += 4;
3002 break;
3003
3004 case AL_OBJ_AI_DBL0x1E06:
3005 case AL_OBJ_AIF_DBL0x1F08:
3006 case AL_OBJ_AIC_DBLNT0x2006:
3007 case AL_OBJ_AIC_DBLT0x2008:
3008 case AL_OBJ_AIFC_DBLNT0x2106:
3009 case AL_OBJ_AIFC_DBLT0x2108:
3010
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_ENDIAN0x80000000);
3014 data_pos += 8;
3015 break;
3016 }
3017
3018 /* Get timestamp */
3019 switch (al_obj)
3020 {
3021 case AL_OBJ_AIC_32T0x2003:
3022 case AL_OBJ_AIC_16T0x2004:
3023 case AL_OBJ_AIC_FLTT0x2007:
3024 case AL_OBJ_AIC_DBLT0x2008:
3025 case AL_OBJ_AIFC_32T0x2103:
3026 case AL_OBJ_AIFC_16T0x2104:
3027 case AL_OBJ_AIFC_FLTT0x2107:
3028 case AL_OBJ_AIFC_DBLT0x2108:
3029
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)abs_time_to_str_ex(pinfo->pool, &al_abstime, ABSOLUTE_TIME_UTC
, (0) ? (1U << 0) : 0)
);
3032 proto_tree_add_time(point_tree, hf_dnp3_al_timestamp, tvb, data_pos, 6, &al_abstime);
3033 data_pos += 6;
3034 break;
3035
3036 case AL_OBJ_AIFC_32TOF0x1F03:
3037 case AL_OBJ_AIFC_16TOF0x1F04:
3038
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)abs_time_to_str_ex(pinfo->pool, &al_abstime, ABSOLUTE_TIME_UTC
, (0) ? (1U << 0) : 0)
);
3041 proto_tree_add_time(point_tree, hf_dnp3_al_timestamp, tvb, data_pos, 6, &al_abstime);
3042 data_pos += 6;
3043 break;
3044 }
3045
3046 proto_item_set_len(point_item, data_pos - offset);
3047
3048 offset = data_pos;
3049 break;
3050
3051 case AL_OBJ_AO_320x2801: /* 32-Bit Analog Output Status (Obj:40, Var:01) */
3052 case AL_OBJ_AO_160x2802: /* 16-Bit Analog Output Status (Obj:40, Var:02) */
3053 case AL_OBJ_AO_FLT0x2803: /* 32-Bit Floating Point Output Status (Obj:40, Var:03) */
3054 case AL_OBJ_AO_DBL0x2804: /* 64-Bit Floating Point Output Status (Obj:40, Var:04) */
3055 case AL_OBJ_AOC_32NT0x2A01: /* 32-Bit Analog Output Event w/o Time (Obj:42, Var:01) */
3056 case AL_OBJ_AOC_16NT0x2A02: /* 16-Bit Analog Output Event w/o Time (Obj:42, Var:02) */
3057 case AL_OBJ_AOC_32T0x2A03: /* 32-Bit Analog Output Event with Time (Obj:42, Var:03) */
3058 case AL_OBJ_AOC_16T0x2A04: /* 16-Bit Analog Output Event with Time (Obj:42, Var:04) */
3059 case AL_OBJ_AOC_FLTNT0x2A05: /* 32-Bit Floating Point Output Event w/o Time (Obj:42, Var:05) */
3060 case AL_OBJ_AOC_DBLNT0x2A06: /* 64-Bit Floating Point Output Event w/o Time (Obj:42, Var:06) */
3061 case AL_OBJ_AOC_FLTT0x2A07: /* 32-Bit Floating Point Output Event w/ Time (Obj:42, Var:07) */
3062 case AL_OBJ_AOC_DBLT0x2A08: /* 64-Bit Floating Point Output Event w/ Time (Obj:42, Var:08) */
3063
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);
3067 data_pos += 1;
3068
3069 switch (al_obj)
3070 {
3071 case AL_OBJ_AO_320x2801: /* 32-Bit Analog Output Status (Obj:40, Var:01) */
3072 case AL_OBJ_AOC_32NT0x2A01: /* 32-Bit Analog Output Event w/o Time (Obj:42, Var:01) */
3073 case AL_OBJ_AOC_32T0x2A03: /* 32-Bit Analog Output Event with Time (Obj:42, Var:03) */
3074
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_ENDIAN0x80000000);
3078 data_pos += 4;
3079 break;
3080
3081 case AL_OBJ_AO_160x2802: /* 16-Bit Analog Output Status (Obj:40, Var:02) */
3082 case AL_OBJ_AOC_16NT0x2A02: /* 16-Bit Analog Output Event w/o Time (Obj:42, Var:02) */
3083 case AL_OBJ_AOC_16T0x2A04: /* 16-Bit Analog Output Event with Time (Obj:42, Var:04) */
3084
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_ENDIAN0x80000000);
3088 data_pos += 2;
3089 break;
3090
3091 case AL_OBJ_AO_FLT0x2803: /* 32-Bit Floating Point Output Status (Obj:40, Var:03) */
3092 case AL_OBJ_AOC_FLTNT0x2A05: /* 32-Bit Floating Point Output Event w/o Time (Obj:42, Var:05) */
3093 case AL_OBJ_AOC_FLTT0x2A07: /* 32-Bit Floating Point Output Event w/ Time (Obj:42, Var:07) */
3094
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_ENDIAN0x80000000);
3098 data_pos += 4;
3099 break;
3100
3101 case AL_OBJ_AO_DBL0x2804: /* 64-Bit Floating Point Output Status (Obj:40, Var:04) */
3102 case AL_OBJ_AOC_DBLNT0x2A06: /* 64-Bit Floating Point Output Event w/o Time (Obj:42, Var:06) */
3103 case AL_OBJ_AOC_DBLT0x2A08: /* 64-Bit Floating Point Output Event w/ Time (Obj:42, Var:08) */
3104
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_ENDIAN0x80000000);
3108 data_pos += 8;
3109 break;
3110 }
3111
3112 /* Get timestamp */
3113 switch (al_obj)
3114 {
3115 case AL_OBJ_AOC_32T0x2A03:
3116 case AL_OBJ_AOC_16T0x2A04:
3117 case AL_OBJ_AOC_FLTT0x2A07:
3118 case AL_OBJ_AOC_DBLT0x2A08:
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)abs_time_to_str_ex(pinfo->pool, &al_abstime, ABSOLUTE_TIME_UTC
, (0) ? (1U << 0) : 0)
);
3121 proto_tree_add_time(point_tree, hf_dnp3_al_timestamp, tvb, data_pos, 6, &al_abstime);
3122 data_pos += 6;
3123 break;
3124 }
3125
3126 proto_item_set_len(point_item, data_pos - offset);
3127 offset = data_pos;
3128 break;
3129
3130 case AL_OBJ_TD0x3201: /* Time and Date (Obj:50, Var:01) */
3131 case AL_OBJ_TDR0x3203: /* Time and Date at Last Recorded Time (Obj:50, Var:03) */
3132 case AL_OBJ_TDCTO0x3301: /* Time and Date CTO (Obj:51, Var:01) */
3133 case AL_OBJ_UTDCTO0x3302: /* Unsynchronized Time and Date CTO (Obj:51, Var:02) */
3134
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);
3137 data_pos += 6;
3138 proto_item_set_len(point_item, data_pos - offset);
3139
3140 if (al_obj == AL_OBJ_TDCTO0x3301) {
3141 /* Copy the time object to the CTO for any other relative time objects in this response */
3142 nstime_copy(al_cto, &al_abstime);
3143 }
3144
3145 offset = data_pos;
3146 break;
3147
3148 case AL_OBJ_TDELAYF0x3402: /* Time Delay - Fine (Obj:52, Var:02) */
3149
3150 proto_tree_add_item(object_tree, hf_dnp3_al_time_delay, tvb, data_pos, 2, ENC_LITTLE_ENDIAN0x80000000);
3151 data_pos += 2;
3152 proto_item_set_len(point_item, data_pos - offset);
3153
3154 offset = data_pos;
3155 break;
3156
3157 case AL_OBJ_FILE_CMD0x4603: /* 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_ENDIAN0x80000000);
3160 data_pos += 2;
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_ENDIAN0x80000000);
3163 data_pos += 2;
3164
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);
3167
3168 /* Creation Time */
3169 if (al_file_ctrl_mode == AL_OBJ_FILE_MODE_WRITE0x02) {
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);
3172 }
3173 data_pos += 6;
3174
3175 /* Perms */
3176 if (al_file_ctrl_mode == AL_OBJ_FILE_MODE_WRITE0x02) {
3177 proto_item *perms_item;
3178 proto_tree *perms_tree;
3179
3180 perms_item = proto_tree_add_item(point_tree, hf_dnp3_al_file_perms, tvb, offset, 2, ENC_LITTLE_ENDIAN0x80000000);
3181
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_ENDIAN0x80000000);
3184 proto_tree_add_item(perms_tree, hf_dnp3_al_file_perms_write_owner, tvb, offset, 2, ENC_LITTLE_ENDIAN0x80000000);
3185 proto_tree_add_item(perms_tree, hf_dnp3_al_file_perms_exec_owner, tvb, offset, 2, ENC_LITTLE_ENDIAN0x80000000);
3186 proto_tree_add_item(perms_tree, hf_dnp3_al_file_perms_read_group, tvb, offset, 2, ENC_LITTLE_ENDIAN0x80000000);
3187 proto_tree_add_item(perms_tree, hf_dnp3_al_file_perms_write_group, tvb, offset, 2, ENC_LITTLE_ENDIAN0x80000000);
3188 proto_tree_add_item(perms_tree, hf_dnp3_al_file_perms_exec_group, tvb, offset, 2, ENC_LITTLE_ENDIAN0x80000000);
3189 proto_tree_add_item(perms_tree, hf_dnp3_al_file_perms_read_world, tvb, offset, 2, ENC_LITTLE_ENDIAN0x80000000);
3190 proto_tree_add_item(perms_tree, hf_dnp3_al_file_perms_write_world, tvb, offset, 2, ENC_LITTLE_ENDIAN0x80000000);
3191 proto_tree_add_item(perms_tree, hf_dnp3_al_file_perms_exec_world, tvb, offset, 2, ENC_LITTLE_ENDIAN0x80000000);
3192 }
3193 data_pos += 2;
3194
3195 /* Auth Key */
3196 proto_tree_add_item(point_tree, hf_dnp3_al_file_auth, tvb, data_pos, 4, ENC_LITTLE_ENDIAN0x80000000);
3197 data_pos += 4;
3198
3199 /* File Size */
3200 if (al_file_ctrl_mode == AL_OBJ_FILE_MODE_WRITE0x02 || al_file_ctrl_mode == AL_OBJ_FILE_MODE_APPEND0x03) {
3201 proto_tree_add_item(point_tree, hf_dnp3_al_file_size, tvb, data_pos, 4, ENC_LITTLE_ENDIAN0x80000000);
3202 }
3203 data_pos += 4; //-V525
3204
3205 /* Mode */
3206 proto_tree_add_item(point_tree, hf_dnp3_al_file_mode, tvb, data_pos, 2, ENC_LITTLE_ENDIAN0x80000000);
3207 data_pos += 2;
3208
3209 /* Max Block Size */
3210 proto_tree_add_item(point_tree, hf_dnp3_al_file_maxblk, tvb, data_pos, 2, ENC_LITTLE_ENDIAN0x80000000);
3211 data_pos += 2;
3212
3213 /* Request ID */
3214 proto_tree_add_item(point_tree, hf_dnp3_al_file_reqID, tvb, data_pos, 2, ENC_LITTLE_ENDIAN0x80000000);
3215 data_pos += 2;
3216
3217 /* Filename */
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_ASCII0x00000000);
3220 }
3221 data_pos += al_filename_len;
3222 proto_item_set_len(point_item, data_pos - offset);
3223
3224 offset = data_pos;
3225 break;
3226
3227 case AL_OBJ_FILE_STAT0x4604: /* File Control - File Status (Obj:70, Var:04) */
3228
3229 /* File Handle */
3230 proto_tree_add_item(point_tree, hf_dnp3_al_file_handle, tvb, data_pos, 4, ENC_LITTLE_ENDIAN0x80000000);
3231 data_pos += 4;
3232
3233 /* File Size */
3234 proto_tree_add_item(point_tree, hf_dnp3_al_file_size, tvb, data_pos, 4, ENC_LITTLE_ENDIAN0x80000000);
3235 data_pos += 4;
3236
3237 /* Max Block Size */
3238 proto_tree_add_item(point_tree, hf_dnp3_al_file_maxblk, tvb, data_pos, 2, ENC_LITTLE_ENDIAN0x80000000);
3239 data_pos += 2;
3240
3241 /* Request ID */
3242 proto_tree_add_item(point_tree, hf_dnp3_al_file_reqID, tvb, data_pos, 2, ENC_LITTLE_ENDIAN0x80000000);
3243 data_pos += 2;
3244
3245 /* Status code */
3246 proto_tree_add_item(point_tree, hf_dnp3_al_file_status, tvb, data_pos, 1, ENC_LITTLE_ENDIAN0x80000000);
3247 data_pos += 1;
3248
3249 /* Optional text */
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_NA0x00000000);
3253 data_pos += file_data_size;
3254 }
3255
3256 proto_item_set_len(point_item, data_pos - offset);
3257
3258 offset = data_pos;
3259 break;
3260
3261 case AL_OBJ_FILE_TRANS0x4605: /* File Control - File Transport (Obj:70, Var:05) */
3262
3263 /* File Handle */
3264 proto_tree_add_item(point_tree, hf_dnp3_al_file_handle, tvb, data_pos, 4, ENC_LITTLE_ENDIAN0x80000000);
3265 data_pos += 4;
3266
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_ENDIAN0x80000000);
3269 proto_tree_add_item(point_tree, hf_dnp3_al_file_lastblock, tvb, data_pos, 4, ENC_LITTLE_ENDIAN0x80000000);
3270 data_pos += 4;
3271
3272 /* File data */
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_NA0x00000000);
3276 data_pos += file_data_size;
3277 }
3278
3279 proto_item_set_len(point_item, data_pos - offset);
3280
3281 offset = data_pos;
3282 break;
3283
3284 case AL_OBJ_FILE_TRAN_ST0x4606: /* File Control Tansport Status (Obj:70, Var:06) */
3285
3286 /* File Handle */
3287 proto_tree_add_item(point_tree, hf_dnp3_al_file_handle, tvb, data_pos, 4, ENC_LITTLE_ENDIAN0x80000000);
3288 data_pos += 4;
3289
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_ENDIAN0x80000000);
3292 proto_tree_add_item(point_tree, hf_dnp3_al_file_lastblock, tvb, data_pos, 4, ENC_LITTLE_ENDIAN0x80000000);
3293 data_pos += 4;
3294
3295 /* Status code */
3296 proto_tree_add_item(point_tree, hf_dnp3_al_file_status, tvb, data_pos, 1, ENC_LITTLE_ENDIAN0x80000000);
3297 data_pos += 1;
3298
3299 /* Optional text */
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_NA0x00000000);
3303 data_pos += file_data_size;
3304 }
3305
3306 proto_item_set_len(point_item, data_pos - offset);
3307
3308 offset = data_pos;
3309 break;
3310
3311 case AL_OBJ_OCT0x6E00: /* Octet string */
3312 case AL_OBJ_OCT_EVT0x6F00: /* Octet string event */
3313
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_NA0x00000000);
3317 data_pos += al_oct_len;
3318 proto_item_set_len(point_item, data_pos - offset);
3319 }
3320
3321 offset = data_pos;
3322 break;
3323
3324 case AL_OBJ_SA_AUTH_CH0x7801: /* Authentication Challenge (Obj:120, Var:01) */
3325
3326 /* Challenge Sequence Number */
3327 proto_tree_add_item(object_tree, hf_dnp3_al_sa_csq, tvb, data_pos, 4, ENC_LITTLE_ENDIAN0x80000000);
3328 data_pos += 4;
3329
3330 /* User Number */
3331 proto_tree_add_item(object_tree, hf_dnp3_al_sa_usr, tvb, data_pos, 2, ENC_LITTLE_ENDIAN0x80000000);
3332 data_pos += 2;
3333
3334 /* MAC Algorithm */
3335 proto_tree_add_item(object_tree, hf_dnp3_al_sa_mal, tvb, data_pos, 1, ENC_LITTLE_ENDIAN0x80000000);
3336 data_pos += 1;
3337
3338 /* Reason for Challenge */
3339 proto_tree_add_item(object_tree, hf_dnp3_al_sa_rfc, tvb, data_pos, 1, ENC_LITTLE_ENDIAN0x80000000);
3340 data_pos += 1;
3341
3342 /* Challenge Data */
3343 proto_tree_add_item(object_tree, hf_dnp3_al_sa_cd, tvb, data_pos, (al_ptaddr-8), ENC_NA0x00000000);
3344 data_pos += (al_ptaddr-8);
3345
3346 offset = data_pos;
3347 break;
3348
3349 case AL_OBJ_SA_AUTH_RP0x7802: /* Authentication Reply (Obj:120, Var:02) */
3350
3351 /* Challenge Sequence Number */
3352 proto_tree_add_item(object_tree, hf_dnp3_al_sa_csq, tvb, data_pos, 4, ENC_LITTLE_ENDIAN0x80000000);
3353 data_pos += 4;
3354
3355 /* User Number */
3356 proto_tree_add_item(object_tree, hf_dnp3_al_sa_usr, tvb, data_pos, 2, ENC_LITTLE_ENDIAN0x80000000);
3357 data_pos += 2;
3358
3359 /* MAC Value */
3360 proto_tree_add_item(object_tree, hf_dnp3_al_sa_mac, tvb, data_pos, (al_ptaddr-6), ENC_NA0x00000000);
3361 data_pos += (al_ptaddr-6);
3362
3363 offset = data_pos;
3364 break;
3365
3366 case AL_OBJ_SA_AUTH_AGMRQ0x7803: /* Authentication Aggressive Mode Request (Obj:120, Var:03) */
3367
3368 /* Challenge Sequence Number */
3369 proto_tree_add_item(object_tree, hf_dnp3_al_sa_csq, tvb, data_pos, 4, ENC_LITTLE_ENDIAN0x80000000);
3370 data_pos += 4;
3371
3372 /* User Number */
3373 proto_tree_add_item(object_tree, hf_dnp3_al_sa_usr, tvb, data_pos, 2, ENC_LITTLE_ENDIAN0x80000000);
3374 data_pos += 2;
3375
3376 offset = data_pos;
3377 break;
3378
3379 case AL_OBJ_SA_AUTH_SKSR0x7804: /* Authentication Session Key Status Request (Obj:120, Var:04) */
3380
3381 /* User Number */
3382 proto_tree_add_item(object_tree, hf_dnp3_al_sa_usr, tvb, data_pos, 2, ENC_LITTLE_ENDIAN0x80000000);
3383 data_pos += 2;
3384
3385 offset = data_pos;
3386 break;
3387
3388 case AL_OBJ_SA_AUTH_SKS0x7805: /* Authentication Session Key Status (Obj:120, Var:05) */
3389
3390 /* Key Change Sequence Number */
3391 proto_tree_add_item(object_tree, hf_dnp3_al_sa_ksq, tvb, data_pos, 4, ENC_LITTLE_ENDIAN0x80000000);
3392 data_pos += 4;
3393
3394 /* User Number */
3395 proto_tree_add_item(object_tree, hf_dnp3_al_sa_usr, tvb, data_pos, 2, ENC_LITTLE_ENDIAN0x80000000);
3396 data_pos += 2;
3397
3398 /* Key Wrap Algorithm */
3399 proto_tree_add_item(object_tree, hf_dnp3_al_sa_kwa, tvb, data_pos, 1, ENC_LITTLE_ENDIAN0x80000000);
3400 data_pos += 1;
3401
3402 /* Key Status */
3403 proto_tree_add_item(object_tree, hf_dnp3_al_sa_ks, tvb, data_pos, 1, ENC_LITTLE_ENDIAN0x80000000);
3404 data_pos += 1;
3405
3406 /* MAC Algorithm */
3407 /* Use the MAC Algorithm to determine the length of the MAC Value */
3408 temp = tvb_get_uint8(tvb, data_pos);
3409 switch (temp) {
3410 case 1:
3411 al_sa_mac_len = 4;
3412 break;
3413 case 2:
3414 al_sa_mac_len = 10;
3415 break;
3416 case 3:
3417 case 5:
3418 al_sa_mac_len = 8;
3419 break;
3420 case 4:
3421 al_sa_mac_len = 16;
3422 break;
3423 case 6:
3424 al_sa_mac_len = 12;
3425 break;
3426 default:
3427 al_sa_mac_len = 0;
3428 break;
3429 }
3430 proto_tree_add_item(object_tree, hf_dnp3_al_sa_mal, tvb, data_pos, 1, ENC_LITTLE_ENDIAN0x80000000);
3431 data_pos += 1;
3432
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_ENDIAN0x80000000);
3436 data_pos += 2;
3437
3438 /* Challenge Data */
3439 proto_tree_add_item(object_tree, hf_dnp3_al_sa_cd, tvb, data_pos, al_val_uint16, ENC_NA0x00000000);
3440 data_pos += al_val_uint16;
3441
3442 /* MAC Value */
3443 proto_tree_add_item(object_tree, hf_dnp3_al_sa_mac, tvb, data_pos, al_sa_mac_len, ENC_NA0x00000000);
3444 data_pos += al_sa_mac_len;
3445
3446 offset = data_pos;
3447 break;
3448
3449 case AL_OBJ_SA_AUTH_SKC0x7806: /* Authentication Session Key Change (Obj:120, Var:06) */
3450
3451 /* Key Change Sequence Number */
3452 proto_tree_add_item(object_tree, hf_dnp3_al_sa_ksq, tvb, data_pos, 4, ENC_LITTLE_ENDIAN0x80000000);
3453 data_pos += 4;
3454
3455 /* User Number */
3456 proto_tree_add_item(object_tree, hf_dnp3_al_sa_usr, tvb, data_pos, 2, ENC_LITTLE_ENDIAN0x80000000);
3457 data_pos += 2;
3458
3459 /* Key Data */
3460 proto_tree_add_item(object_tree, hf_dnp3_al_sa_key, tvb, data_pos, (al_ptaddr-6), ENC_NA0x00000000);
3461 data_pos += (al_ptaddr-6);
3462
3463 offset = data_pos;
3464 break;
3465
3466 case AL_OBJ_SA_AUTH_ERR0x7807: /* Authentication Error (Obj:120, Var:07) */
3467
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_ENDIAN0x80000000);
3470 data_pos += 4;
3471
3472 /* User Number */
3473 proto_tree_add_item(object_tree, hf_dnp3_al_sa_usr, tvb, data_pos, 2, ENC_LITTLE_ENDIAN0x80000000);
3474 data_pos += 2;
3475
3476 /* Association ID */
3477 proto_tree_add_item(point_tree, hf_dnp3_al_sa_assoc_id, tvb, data_pos, 2, ENC_LITTLE_ENDIAN0x80000000);
3478 data_pos += 2;
3479
3480 /* Error Code */
3481 proto_tree_add_item(object_tree, hf_dnp3_al_sa_err, tvb, data_pos, 1, ENC_LITTLE_ENDIAN0x80000000);
3482 data_pos += 1;
3483
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);
3487 data_pos += 6;
3488
3489 /* Error Text */
3490 /* Optional footer for any remaining data */
3491
3492 offset = data_pos;
3493 break;
3494
3495
3496 case AL_OBJ_SA_AUTH_MAC0x7809: /* Authentication Message Authentication Code (Obj:120, Var:09) */
3497 case AL_OBJ_SA_AUTH_UKCC0x780F: /* Authentication Update Key Change Confirmation (Obj:120, Var:15) */
3498
3499 /* MAC Value */
3500 proto_tree_add_item(object_tree, hf_dnp3_al_sa_mac, tvb, data_pos, al_ptaddr, ENC_NA0x00000000);
3501 data_pos += al_ptaddr;
3502
3503 offset = data_pos;
3504 break;
3505
3506 case AL_OBJ_SA_AUTH_UKCR0x780B: /* Authentication Update Key Change Request (Obj:120, Var:11) */
3507
3508 /* Key Change Method */
3509 proto_tree_add_item(object_tree, hf_dnp3_al_sa_kcm, tvb, data_pos, 1, ENC_LITTLE_ENDIAN0x80000000);
3510 data_pos += 1;
3511
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_ENDIAN0x80000000);
3515 data_pos += 2;
3516
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_ENDIAN0x80000000);
3520 data_pos += 2;
3521
3522 /* User Name */
3523 proto_tree_add_item(object_tree, hf_dnp3_al_sa_usrn, tvb, data_pos, sa_username_len, ENC_ASCII0x00000000);
3524 data_pos += sa_username_len;
3525
3526 /* Challenge Data */
3527 proto_tree_add_item(object_tree, hf_dnp3_al_sa_cd, tvb, data_pos, sa_challengedata_len, ENC_NA0x00000000);
3528 data_pos += sa_challengedata_len;
3529
3530 offset = data_pos;
3531 break;
3532
3533 case AL_OBJ_SA_AUTH_UKCRP0x780C: /* Authentication Update Key Change Reply (Obj:120, Var:12) */
3534
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_ENDIAN0x80000000);
3537 data_pos += 4;
3538
3539 /* User Number */
3540 proto_tree_add_item(object_tree, hf_dnp3_al_sa_usr, tvb, data_pos, 2, ENC_LITTLE_ENDIAN0x80000000);
3541 data_pos += 2;
3542
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_ENDIAN0x80000000);
3546 data_pos += 2;
3547
3548 /* Challenge Data */
3549 proto_tree_add_item(object_tree, hf_dnp3_al_sa_cd, tvb, data_pos, sa_challengedata_len, ENC_NA0x00000000);
3550 data_pos += sa_challengedata_len;
3551
3552 offset = data_pos;
3553 break;
3554
3555 case AL_OBJ_SA_AUTH_UKC0x780D: /* Authentication Update Key Change (Obj:120, Var:13) */
3556
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_ENDIAN0x80000000);
3559 data_pos += 4;
3560
3561 /* User Number */
3562 proto_tree_add_item(object_tree, hf_dnp3_al_sa_usr, tvb, data_pos, 2, ENC_LITTLE_ENDIAN0x80000000);
3563 data_pos += 2;
3564
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_ENDIAN0x80000000);
3568 data_pos += 2;
3569
3570 /* Encrypted Update Key Data */
3571 proto_tree_add_item(object_tree, hf_dnp3_al_sa_uk, tvb, data_pos, sa_updatekey_len, ENC_NA0x00000000);
3572 data_pos += sa_updatekey_len;
3573
3574 offset = data_pos;
3575 break;
3576
3577 case AL_OBJ_SA_SECSTAT0x7901: /* Security Statistics (Obj:121, Var:01) */
3578 case AL_OBJ_SA_SECSTATEVT0x7A01: /* Security Statistic Event (Obj:122, Var:01) */
3579 case AL_OBJ_SA_SECSTATEVTT0x7A02: /* Security Statistic Event w/ Time (Obj:122, Var:02) */
3580
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);
3584
3585 /* Quality Flags */
3586 al_ptflags = tvb_get_uint8(tvb, data_pos);
3587 dnp3_al_obj_quality(tvb, data_pos, al_ptflags, point_tree, point_item, COUNTER);
3588 data_pos += 1;
3589
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_ENDIAN0x80000000);
3594 data_pos += 2;
3595
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_ENDIAN0x80000000);
3600 data_pos += 4;
3601
3602 if (al_obj == AL_OBJ_SA_SECSTATEVTT0x7A02) {
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)abs_time_to_str_ex(pinfo->pool, &al_abstime, ABSOLUTE_TIME_UTC
, (0) ? (1U << 0) : 0)
);
3605 proto_tree_add_time(point_tree, hf_dnp3_al_timestamp, tvb, data_pos, 6, &al_abstime);
3606 data_pos += 6;
3607 }
3608
3609 offset = data_pos;
3610 break;
3611
3612 default: /* In case of unknown object */
3613
3614 proto_tree_add_item(object_tree, hf_dnp3_unknown_data_chunk, tvb, offset, -1, ENC_NA0x00000000);
3615 offset = tvb_captured_length(tvb); /* Finish decoding if unknown object is encountered... */
3616 break;
3617 }
3618 }
3619
3620 /* And increment the point address, may be overwritten by an index value */
3621 al_ptaddr++;
3622 }
3623 else {
3624 /* No objects, just prefixes, move past prefix values */
3625 offset = data_pos;
3626 }
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... */
3630 }
3631 }
3632 }
3633 proto_item_set_len(object_item, offset - orig_offset);
3634
3635 return offset;
3636}
3637
3638/*****************************************************************/
3639/* Application Layer Dissector */
3640/*****************************************************************/
3641static int
3642dissect_dnp3_al(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3643{
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;
3650 nstime_t al_cto;
3651 static int * const control_flags[] = {
3652 &hf_dnp3_al_fir,
3653 &hf_dnp3_al_fin,
3654 &hf_dnp3_al_con,
3655 &hf_dnp3_al_uns,
3656 &hf_dnp3_al_seq,
3657 NULL((void*)0)
3658 };
3659
3660 nstime_set_zero (&al_cto);
3661
3662 data_len = tvb_captured_length(tvb);
3663
3664 /* Handle the control byte and function code */
3665 al_ctl = tvb_get_uint8(tvb, offset);
3666 al_seq = al_ctl & DNP3_AL_SEQ0x0f;
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)");
3669
3670 /* Clear out lower layer info */
3671 col_clear(pinfo->cinfo, COL_INFO);
3672 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL((void*)0), func_code_str);
3673 col_set_fence(pinfo->cinfo, COL_INFO);
3674
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_FIR0x80) proto_item_append_text(ti, "FIR, ");
3678 if (al_ctl & DNP3_AL_FIN0x40) proto_item_append_text(ti, "FIN, ");
3679 if (al_ctl & DNP3_AL_CON0x20) proto_item_append_text(ti, "CON, ");
3680 if (al_ctl & DNP3_AL_UNS0x10) proto_item_append_text(ti, "UNS, ");
3681 proto_item_append_text(ti, "Sequence %u, %s)", al_seq, func_code_str);
3682
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_ENDIAN0x00000000);
3685 proto_item_append_text(tc, "(");
3686 if (al_ctl & DNP3_AL_FIR0x80) proto_item_append_text(tc, "FIR, ");
3687 if (al_ctl & DNP3_AL_FIN0x40) proto_item_append_text(tc, "FIN, ");
3688 if (al_ctl & DNP3_AL_CON0x20) proto_item_append_text(tc, "CON, ");
3689 if (al_ctl & DNP3_AL_UNS0x10) proto_item_append_text(tc, "UNS, ");
3690 proto_item_append_text(tc, "Sequence %u)", al_seq);
3691 offset += 1;
3692
3693#if 0
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_FIN0x40)) {
3697 t_robj = proto_tree_add_expert(al_tree, pinfo, &ei_dnp3_buffering_user_data_until_final_frame_is_received, tvb, offset, -1);
3698 return 1;
3699 }
3700#endif
3701
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);
3705 offset += 1;
3706
3707 switch (al_func)
3708 {
3709 case AL_FUNC_CONFIRM0x00: /* Confirm Function Code 0x00 */
3710
3711 /* If the application layer data is longer than two bytes in length it may have SA objects appended to it */
3712 if (data_len > 2) {
3713
3714 /* Create Confirm Data Objects Tree */
3715 robj_tree = proto_tree_add_subtree(al_tree, tvb, offset, -1, ett_dnp3_al_objdet, NULL((void*)0), "CONFIRM Data Objects");
3716
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, true1, &obj_type, &al_cto);
3720 }
3721 }
3722 break;
3723
3724 case AL_FUNC_READ0x01: /* Read Function Code 0x01 */
3725
3726 /* Create Read Request Data Objects Tree */
3727 robj_tree = proto_tree_add_subtree(al_tree, tvb, offset, -1, ett_dnp3_al_objdet, NULL((void*)0), "READ Request Data Objects");
3728
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, true1, &obj_type, &al_cto);
3732
3733 /* Update class type for each object that was a class read */
3734 switch(obj_type) {
3735 case AL_OBJ_CLASS00x3C01:
3736 case AL_OBJ_CLASS10x3C02:
3737 case AL_OBJ_CLASS20x3C03:
3738 case AL_OBJ_CLASS30x3C04:
3739 al_class |= (1 << ((obj_type & 0x0f) - 1));
3740 break;
3741 default:
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((void*)0), obj_type_str);
3745 break;
3746 }
3747
3748 }
3749
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((void*)0), "Class ");
3753 for (i = 0; i < 4; i++) {
3754 if (al_class & (1 << i)) {
3755 col_append_fstr(pinfo->cinfo, COL_INFO, "%u", i);
3756 }
3757 }
3758 }
3759
3760 break;
3761
3762 case AL_FUNC_WRITE0x02: /* Write Function Code 0x02 */
3763
3764 /* Create Write Request Data Objects Tree */
3765 robj_tree = proto_tree_add_subtree(al_tree, tvb, offset, -1, ett_dnp3_al_objdet, NULL((void*)0), "WRITE Request Data Objects");
3766
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, false0, &obj_type, &al_cto);
3770
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((void*)0), obj_type_str);
3774
3775 }
3776
3777 break;
3778
3779 case AL_FUNC_SELECT0x03: /* Select Function Code 0x03 */
3780
3781 /* Create Select Request Data Objects Tree */
3782 robj_tree = proto_tree_add_subtree(al_tree, tvb, offset, -1, ett_dnp3_al_objdet, NULL((void*)0), "SELECT Request Data Objects");
3783
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, false0, &obj_type, &al_cto);
3787 }
3788
3789 break;
3790
3791 case AL_FUNC_OPERATE0x04: /* Operate Function Code 0x04 */
3792 /* Functionally identical to 'SELECT' Function Code */
3793
3794 /* Create Operate Request Data Objects Tree */
3795 robj_tree = proto_tree_add_subtree(al_tree, tvb, offset, -1, ett_dnp3_al_objdet, NULL((void*)0), "OPERATE Request Data Objects");
3796
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, false0, &obj_type, &al_cto);
3800 }
3801
3802 break;
3803
3804 case AL_FUNC_DIROP0x05: /* Direct Operate Function Code 0x05 */
3805 case AL_FUNC_DIROPNACK0x06: /* Direct Operate No ACK Function Code 0x06 */
3806 /* Functionally identical to 'SELECT' Function Code */
3807
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((void*)0), "DIRECT OPERATE Request Data Objects");
3810
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, false0, &obj_type, &al_cto);
3814 }
3815
3816 break;
3817
3818 case AL_FUNC_FRZ0x07: /* Immediate Freeze Function Code 0x07 */
3819 case AL_FUNC_FRZNACK0x08: /* Immediate Freeze No ACK Function Code 0x08 */
3820 case AL_FUNC_FRZCLR0x09: /* Freeze and Clear Function Code 0x09 */
3821 case AL_FUNC_FRZCLRNACK0x0A: /* Freeze and Clear No ACK Function Code 0x0A */
3822
3823 /* Create Freeze Request Data Objects Tree */
3824 robj_tree = proto_tree_add_subtree(al_tree, tvb, offset, -1, ett_dnp3_al_objdet, NULL((void*)0), "Freeze Request Data Objects");
3825
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, true1, &obj_type, &al_cto);
3829 }
3830
3831 break;
3832
3833 case AL_FUNC_ENSPMSG0x14: /* Enable Spontaneous Messages Function Code 0x14 */
3834
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((void*)0), "Enable Spontaneous Msg's Data Objects");
3837
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, false0, &obj_type, &al_cto);
3841 }
3842
3843 break;
3844
3845 case AL_FUNC_DISSPMSG0x15: /* Disable Spontaneous Messages Function Code 0x15 */
3846
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((void*)0), "Disable Spontaneous Msg's Data Objects");
3849
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, false0, &obj_type, &al_cto);
3853 }
3854
3855 break;
3856
3857 case AL_FUNC_DELAYMST0x17: /* Delay Measurement Function Code 0x17 */
3858
3859 break;
3860
3861 case AL_FUNC_OPENFILE0x19: /* Open File Function Code 0x19 */
3862 case AL_FUNC_CLOSEFILE0x1A: /* Close File Function Code 0x1A */
3863 case AL_FUNC_DELETEFILE0x1B: /* Delete File Function Code 0x1B */
3864
3865 /* Create File Data Objects Tree */
3866 robj_tree = proto_tree_add_subtree(al_tree, tvb, offset, -1, ett_dnp3_al_objdet, NULL((void*)0), "File Data Objects");
3867
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, false0, &obj_type, &al_cto);
3871 }
3872
3873 break;
3874
3875 case AL_FUNC_AUTHREQ0x20: /* Authentication Request Function Code 0x20 */
3876 case AL_FUNC_AUTHERR0x21: /* Authentication Error Function Code 0x21 */
3877
3878
3879 /* Create Authentication Request Data Objects Tree */
3880 robj_tree = proto_tree_add_subtree(al_tree, tvb, offset, -1, ett_dnp3_al_objdet, NULL((void*)0), "Authentication Request Data Objects");
3881
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, false0, &obj_type, &al_cto);
3885 }
3886
3887 break;
3888
3889 case AL_FUNC_RESPON0x81: /* Response Function Code 0x81 */
3890 case AL_FUNC_UNSOLI0x82: /* Unsolicited Response Function Code 0x82 */
3891 case AL_FUNC_AUTHRESP0x83: /* Authentication Response Function Code 0x83 */
3892
3893 /* Application Layer IIN bits req'd if message is a response */
3894 dnp3_al_process_iin(tvb, pinfo, offset, al_tree);
3895 offset += 2;
3896
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);
3901 if (bytes > 0)
3902 {
3903 /* Create Response Data Objects Tree */
3904 robj_tree = proto_tree_add_subtree(al_tree, tvb, offset, -1, ett_dnp3_al_objdet, NULL((void*)0), "RESPONSE Data Objects");
3905
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, false0, &obj_type, &al_cto);
3909 }
3910
3911 break;
3912 }
3913
3914 default: /* Unknown Function */
3915
3916 break;
3917 }
3918
3919 return 0;
3920}
3921
3922/*****************************************************************/
3923/* Data Link and Transport layer dissector */
3924/*****************************************************************/
3925static int
3926dissect_dnp3_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U___attribute__((unused)))
3927{
3928 proto_item *ti, *tdl, *tc, *hidden_item;
3929 proto_tree *dnp3_tree, *dl_tree, *field_tree;
3930 int offset = 0, temp_offset = 0;
3931 bool_Bool dl_prm;
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;
3935
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);
3939
3940 /* Skip "0x0564" header bytes */
3941 temp_offset += 2;
3942
3943 dl_len = tvb_get_uint8(tvb, temp_offset);
3944 temp_offset += 1;
3945
3946 dl_ctl = tvb_get_uint8(tvb, temp_offset);
3947 temp_offset += 1;
3948
3949 dl_dst = tvb_get_letohs(tvb, temp_offset);
3950 temp_offset += 2;
3951
3952 dl_src = tvb_get_letohs(tvb, temp_offset);
3953
3954 dl_func = dl_ctl & DNP3_CTL_FUNC0x0f;
3955 dl_prm = dl_ctl & DNP3_CTL_PRM0x40;
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)");
3958
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"\u2192" " %u", dl_src, dl_dst);
3962 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL((void*)0), "len=%u, %s", dl_len, func_code_str);
3963
3964 /* create display subtree for the protocol */
3965 ti = proto_tree_add_item(tree, proto_dnp3, tvb, offset, -1, ENC_NA0x00000000);
3966 dnp3_tree = proto_item_add_subtree(ti, ett_dnp3);
3967
3968 /* Create Subtree for Data Link Layer */
3969 dl_tree = proto_tree_add_subtree_format(dnp3_tree, tvb, offset, DNP_HDR_LEN10, ett_dnp3_dl, &tdl,
3970 "Data Link Layer, Len: %u, From: %u, To: %u, ", dl_len, dl_src, dl_dst);
3971 if (dl_prm) {
3972 if (dl_ctl & DNP3_CTL_DIR0x80) proto_item_append_text(tdl, "DIR, ");
3973 if (dl_ctl & DNP3_CTL_PRM0x40) proto_item_append_text(tdl, "PRM, ");
3974 if (dl_ctl & DNP3_CTL_FCB0x20) proto_item_append_text(tdl, "FCB, ");
3975 if (dl_ctl & DNP3_CTL_FCV0x10) proto_item_append_text(tdl, "FCV, ");
3976 }
3977 else {
3978 if (dl_ctl & DNP3_CTL_DIR0x80) proto_item_append_text(tdl, "DIR, ");
3979 if (dl_ctl & DNP3_CTL_PRM0x40) proto_item_append_text(tdl, "PRM, ");
3980 if (dl_ctl & DNP3_CTL_RES0x20) proto_item_append_text(tdl, "RES, ");
3981 if (dl_ctl & DNP3_CTL_DFC0x10) proto_item_append_text(tdl, "DFC, ");
3982 }
3983 proto_item_append_text(tdl, "%s", func_code_str);
3984
3985 /* start bytes */
3986 proto_tree_add_item(dl_tree, hf_dnp3_start, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
3987 offset += 2;
3988
3989 /* add length field */
3990 proto_tree_add_item(dl_tree, hf_dnp3_len, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3991 offset += 1;
3992
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 */
3997 if (dl_prm) {
3998 if (dl_ctl & DNP3_CTL_DIR0x80) proto_item_append_text(tc, "DIR, ");
3999 if (dl_ctl & DNP3_CTL_PRM0x40) proto_item_append_text(tc, "PRM, ");
4000 if (dl_ctl & DNP3_CTL_FCB0x20) proto_item_append_text(tc, "FCB, ");
4001 if (dl_ctl & DNP3_CTL_FCV0x10) proto_item_append_text(tc, "FCV, ");
4002 }
4003 else {
4004 if (dl_ctl & DNP3_CTL_DIR0x80) proto_item_append_text(tc, "DIR, ");
4005 if (dl_ctl & DNP3_CTL_PRM0x40) proto_item_append_text(tc, "PRM, ");
4006 if (dl_ctl & DNP3_CTL_RES0x20) proto_item_append_text(tc, "RES, ");
4007 if (dl_ctl & DNP3_CTL_DFC0x10) proto_item_append_text(tc, "DFC, ");
4008 }
4009 proto_item_append_text(tc, "%s)", func_code_str );
4010 field_tree = proto_item_add_subtree(tc, ett_dnp3_dl_ctl);
4011
4012 /* Add Control Byte Subtree Items */
4013 if (dl_prm) {
4014 proto_tree_add_item(field_tree, hf_dnp3_ctl_dir, tvb, offset, 1, ENC_LITTLE_ENDIAN0x80000000);
4015 proto_tree_add_item(field_tree, hf_dnp3_ctl_prm, tvb, offset, 1, ENC_LITTLE_ENDIAN0x80000000);
4016 proto_tree_add_item(field_tree, hf_dnp3_ctl_fcb, tvb, offset, 1, ENC_LITTLE_ENDIAN0x80000000);
4017 proto_tree_add_item(field_tree, hf_dnp3_ctl_fcv, tvb, offset, 1, ENC_LITTLE_ENDIAN0x80000000);
4018 proto_tree_add_item(field_tree, hf_dnp3_ctl_prifunc, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4019 }
4020 else {
4021 proto_tree_add_item(field_tree, hf_dnp3_ctl_dir, tvb, offset, 1, ENC_LITTLE_ENDIAN0x80000000);
4022 proto_tree_add_item(field_tree, hf_dnp3_ctl_prm, tvb, offset, 1, ENC_LITTLE_ENDIAN0x80000000);
4023 proto_tree_add_item(field_tree, hf_dnp3_ctl_dfc, tvb, offset, 1, ENC_LITTLE_ENDIAN0x80000000);
4024 proto_tree_add_item(field_tree, hf_dnp3_ctl_secfunc, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4025 }
4026 offset += 1;
4027
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_ENDIAN0x80000000);
4033 hidden_item = proto_tree_add_item(dl_tree, hf_dnp3_addr, tvb, offset, 2, ENC_LITTLE_ENDIAN0x80000000);
4034 proto_item_set_hidden(hidden_item);
4035 offset += 2;
4036 proto_tree_add_item(dl_tree, hf_dnp3_src, tvb, offset, 2, ENC_LITTLE_ENDIAN0x80000000);
4037 hidden_item = proto_tree_add_item(dl_tree, hf_dnp3_addr, tvb, offset, 2, ENC_LITTLE_ENDIAN0x80000000);
4038 proto_item_set_hidden(hidden_item);
4039 offset += 2;
4040
4041 dnp3_packet_info_t* dnp3_info = wmem_new0(pinfo->pool, dnp3_packet_info_t)((dnp3_packet_info_t*)wmem_alloc0((pinfo->pool), sizeof(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;
4045
4046 tap_queue_packet(dnp3_tap, pinfo, dnp3_info);
4047
4048 /* and header CRC */
4049 calc_dl_crc = calculateCRCtvb(tvb, 0, DNP_HDR_LEN10 - 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_ENDIAN0x80000000, PROTO_CHECKSUM_VERIFY0x01);
4053 offset += 2;
4054
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_STAT0x09) && (dl_func != DL_FUNC_STAT_LINK0x0B) &&
4059 (dl_func != DL_FUNC_RESET_LINK0x00) && (dl_func != DL_FUNC_ACK0x00)) //-V560 (both codes are the same value but semantically different)
4060 {
4061 proto_tree *data_tree;
4062 proto_item *data_ti;
4063 uint8_t tr_ctl, tr_seq;
4064 bool_Bool tr_fir, tr_fin;
4065 uint8_t *al_buffer, *al_buffer_ptr;
4066 uint8_t data_len;
4067 int data_start = offset;
4068 int tl_offset;
4069 bool_Bool crc_OK = false0;
4070 tvbuff_t *next_tvb;
4071 unsigned i;
4072 static int * const transport_flags[] = {
4073 &hf_dnp3_tr_fin,
4074 &hf_dnp3_tr_fir,
4075 &hf_dnp3_tr_seq,
4076 NULL((void*)0)
4077 };
4078
4079 /* get the transport layer byte */
4080 tr_ctl = tvb_get_uint8(tvb, offset);
4081 tr_seq = tr_ctl & DNP3_TR_SEQ0x3f;
4082 tr_fir = tr_ctl & DNP3_TR_FIR0x40;
4083 tr_fin = tr_ctl & DNP3_TR_FIN0x80;
4084
4085 uint32_t ext_seq = tr_seq;
Value stored to 'ext_seq' during its initialization is never read
4086
4087 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
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)((conversation_element_t*)wmem_alloc((pinfo->pool), (((((5
)) <= 0) || ((size_t)sizeof(conversation_element_t) > (
9223372036854775807L / (size_t)((5))))) ? 0 : (sizeof(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);
4103 uint32_t prev;
4104 if (conv) {
4105 prev = GPOINTER_TO_UINT(conversation_get_proto_data(conv, proto_dnp3))((guint) (gulong) (conversation_get_proto_data(conv, proto_dnp3
)))
;
4106 } else {
4107 prev = tr_seq;
4108 conv = conversation_new_full(pinfo->num, conv_key);
4109 }
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)((gpointer) (gulong) (ext_seq)));
4114 p_add_proto_data(wmem_file_scope(), pinfo, proto_dnp3, tr_seq, GUINT_TO_POINTER(ext_seq)((gpointer) (gulong) (ext_seq)));
4115 } else {
4116 ext_seq = GPOINTER_TO_UINT(p_get_proto_data(wmem_file_scope(), pinfo, proto_dnp3, tr_seq))((guint) (gulong) (p_get_proto_data(wmem_file_scope(), pinfo,
proto_dnp3, tr_seq)))
;
4117 }
4118
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_ENDIAN0x00000000);
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);
4125
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");
4128
4129 /* extract the application layer data, validating the CRCs */
4130
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;
4135 i = 0;
4136 tl_offset = 1; /* skip the initial transport layer byte when assembling chunks for the application layer tvb */
4137 while (data_len > 0)
4138 {
4139 uint8_t chk_size;
4140 const uint8_t *chk_ptr;
4141 proto_tree *chk_tree;
4142 proto_item *chk_len_ti;
4143 uint16_t calc_crc, act_crc;
4144
4145 chk_size = MIN(data_len, AL_MAX_CHUNK_SIZE)(((data_len) < (16)) ? (data_len) : (16));
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;
4149
4150 chk_tree = proto_tree_add_subtree_format(data_tree, tvb, offset, chk_size + 2, ett_dnp3_dl_chunk, NULL((void*)0), "Data Chunk: %u", i);
4151 proto_tree_add_item(chk_tree, hf_dnp3_data_chunk, tvb, offset, chk_size, ENC_NA0x00000000);
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);
4154
4155 offset += chk_size;
4156
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_ENDIAN0x80000000, PROTO_CHECKSUM_VERIFY0x01);
4161 act_crc = tvb_get_letohs(tvb, offset);
4162 offset += 2;
4163 crc_OK = calc_crc == act_crc;
4164 if (!crc_OK)
4165 {
4166 /* Don't trust the rest of the data, get out of here */
4167 break;
4168 }
4169 data_len -= chk_size;
4170 i++;
4171 tl_offset = 0; /* copy all the data in the rest of the chunks */
4172 }
4173 proto_item_set_len(data_ti, offset - data_start);
4174
4175 /* if crc OK, set up new tvb */
4176 if (crc_OK)
4177 {
4178 tvbuff_t *al_tvb;
4179 bool_Bool save_fragmented;
4180
4181 al_tvb = tvb_new_child_real_data(tvb, al_buffer, (unsigned) (al_buffer_ptr-al_buffer), (int) (al_buffer_ptr-al_buffer));
4182
4183 /* Check for fragmented packet */
4184 save_fragmented = pinfo->fragmented;
4185
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((void*)0);
4189 pinfo->fragmented = true1;
4190 if (!pinfo->fd->visited)
4191 {
4192 frag_al = fragment_add_seq_single(&al_reassembly_table,
4193 al_tvb, 0, pinfo, ext_seq, NULL((void*)0),
4194 tvb_reported_length(al_tvb), /* As this is a constructed tvb, all of it is ok */
4195 tr_fir, tr_fin,
4196 al_max_fragments);
4197 }
4198 else
4199 {
4200 frag_al = fragment_get_reassembled_id(&al_reassembly_table, pinfo, ext_seq);
4201 }
4202
4203 if (frag_al)
4204 {
4205 /* This is the fragment in which reassembly occurred iff FIN is set. */
4206 if (tr_fin)
4207 {
4208 next_tvb = process_reassembled_data(al_tvb, 0, pinfo,
4209 "Reassembled DNP 3.0 Application Layer message", frag_al, &dnp3_frag_items,
4210 NULL((void*)0), dnp3_tree);
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);
4216 }
4217 else
4218 {
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_NA0x00000000);
4227 }
4228 }
4229 else
4230 {
4231 col_append_fstr(pinfo->cinfo, COL_INFO,
4232 " (Application Layer Unreassembled fragment %u)",
4233 tr_seq);
4234 proto_tree_add_item(dnp3_tree, hf_al_frag_data, al_tvb, 0, -1, ENC_NA0x00000000);
4235 }
4236
4237 pinfo->fragmented = save_fragmented;
4238 }
4239 else
4240 {
4241 /* CRC error - throw away the data. */
4242 wmem_free(pinfo->pool, al_buffer);
4243 next_tvb = NULL((void*)0);
4244 }
4245 }
4246
4247 /* Set the length of the message */
4248 proto_item_set_len(ti, offset);
4249 return offset;
4250}
4251
4252static bool_Bool
4253check_dnp3_header(tvbuff_t *tvb, bool_Bool dnp3_heuristics)
4254{
4255 /* Assume the CRC will be bad */
4256 bool_Bool goodCRC = false0;
4257
4258 /* How big is the actual buffer */
4259 int length = tvb_captured_length(tvb);
4260
4261 /* Calculate the header CRC if the bytes are available */
4262 if (length >= DNP_HDR_LEN10) {
4263 uint16_t calc_crc = calculateCRCtvb(tvb, 0, DNP_HDR_LEN10 - 2);
4264 goodCRC = (calc_crc == tvb_get_letohs(tvb, 8));
4265 }
4266
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)) {
4271 return false0;
4272 }
4273 }
4274 else {
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) {
4278 return false0;
4279 }
4280 if ((length > 1) && (tvb_get_uint8(tvb, 1) != 0x64)) {
4281 return false0;
4282 }
4283 if ((length >= DNP_HDR_LEN10) && !goodCRC) {
4284 return false0;
4285 }
4286 }
4287 return true1;
4288}
4289
4290static unsigned
4291get_dnp3_message_len(packet_info *pinfo _U___attribute__((unused)), tvbuff_t *tvb,
4292 int offset, void *data _U___attribute__((unused)))
4293{
4294 uint16_t message_len; /* need 16 bits as total can exceed 255 */
4295 uint16_t data_crc; /* No. of user data CRC bytes */
4296
4297 message_len = tvb_get_uint8(tvb, offset + 2);
4298
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
4303 */
4304
4305 data_crc = (uint16_t)(ceil((message_len - 5) / 16.0)) * 2;
4306 message_len += 2 + 1 + 2 + data_crc;
4307 return message_len;
4308}
4309
4310static int
4311dissect_dnp3_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
4312{
4313 if (!check_dnp3_header(tvb, false0)) {
4314 return 0;
4315 }
4316
4317 tcp_dissect_pdus(tvb, pinfo, tree, true1, DNP_HDR_LEN10,
4318 get_dnp3_message_len, dissect_dnp3_message, data);
4319
4320 return tvb_captured_length(tvb);
4321}
4322
4323static bool_Bool
4324dissect_dnp3_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
4325{
4326 if (!check_dnp3_header(tvb, true1)) {
4327 return false0;
4328 }
4329
4330 tcp_dissect_pdus(tvb, pinfo, tree, true1, DNP_HDR_LEN10,
4331 get_dnp3_message_len, dissect_dnp3_message, data);
4332
4333 return true1;
4334}
4335
4336static bool_Bool
4337dnp3_udp_check_header(packet_info *pinfo _U___attribute__((unused)), tvbuff_t *tvb, int offset _U___attribute__((unused)), void *data _U___attribute__((unused)))
4338{
4339 return check_dnp3_header(tvb, false0);
4340}
4341
4342static bool_Bool
4343dnp3_udp_check_header_heur(packet_info *pinfo _U___attribute__((unused)), tvbuff_t *tvb, int offset _U___attribute__((unused)), void *data _U___attribute__((unused)))
4344{
4345 return check_dnp3_header(tvb, true1);
4346}
4347
4348static int
4349dissect_dnp3_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
4350{
4351 return udp_dissect_pdus(tvb, pinfo, tree, DNP_HDR_LEN10, dnp3_udp_check_header,
4352 get_dnp3_message_len, dissect_dnp3_message, data);
4353}
4354
4355static bool_Bool
4356dissect_dnp3_udp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
4357{
4358 return (udp_dissect_pdus(tvb, pinfo, tree, DNP_HDR_LEN10, dnp3_udp_check_header_heur,
4359 get_dnp3_message_len, dissect_dnp3_message, data) != 0);
4360
4361}
4362
4363/* Register the protocol with Wireshark */
4364
4365void
4366proto_register_dnp3(void)
4367{
4368
4369/* Setup list of header fields */
4370 static hf_register_info hf[] = {
4371 { &hf_dnp3_start,
4372 { "Start Bytes", "dnp3.start",
4373 FT_UINT16, BASE_HEX, NULL((void*)0), 0x0,
4374 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4375 },
4376
4377 { &hf_dnp3_len,
4378 { "Length", "dnp3.len",
4379 FT_UINT8, BASE_DEC, NULL((void*)0), 0x0,
4380 "Frame Data Length", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4381 },
4382
4383 { &hf_dnp3_ctl,
4384 { "Control", "dnp3.ctl",
4385 FT_UINT8, BASE_HEX, NULL((void*)0), 0x0,
4386 "Frame Control Byte", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4387 },
4388
4389 { &hf_dnp3_ctl_prifunc,
4390 { "Control Function Code", "dnp3.ctl.prifunc",
4391 FT_UINT8, BASE_DEC, VALS(dnp3_ctl_func_pri_vals)((0 ? (const struct _value_string*)0 : ((dnp3_ctl_func_pri_vals
))))
, DNP3_CTL_FUNC0x0f,
4392 "Frame Control Function Code", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4393 },
4394
4395 { &hf_dnp3_ctl_secfunc,
4396 { "Control Function Code", "dnp3.ctl.secfunc",
4397 FT_UINT8, BASE_DEC, VALS(dnp3_ctl_func_sec_vals)((0 ? (const struct _value_string*)0 : ((dnp3_ctl_func_sec_vals
))))
, DNP3_CTL_FUNC0x0f,
4398 "Frame Control Function Code", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4399 },
4400
4401 { &hf_dnp3_ctlobj_code_c,
4402 { "Operation Type", "dnp3.ctl.op",
4403 FT_UINT8, BASE_DEC, VALS(dnp3_al_ctlc_code_vals)((0 ? (const struct _value_string*)0 : ((dnp3_al_ctlc_code_vals
))))
, AL_OBJCTLC_CODE0x0F,
4404 "Control Code, Operation Type", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4405 },
4406
4407 { &hf_dnp3_ctlobj_code_m,
4408 { "Queue / Clear Field", "dnp3.ctl.clr",
4409 FT_UINT8, BASE_DEC, VALS(dnp3_al_ctlc_misc_vals)((0 ? (const struct _value_string*)0 : ((dnp3_al_ctlc_misc_vals
))))
, AL_OBJCTLC_MISC0x30,
4410 "Control Code, Clear Field", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4411 },
4412
4413 { &hf_dnp3_ctlobj_code_tc,
4414 { "Trip Control Code", "dnp3.ctl.trip",
4415 FT_UINT8, BASE_DEC, VALS(dnp3_al_ctlc_tc_vals)((0 ? (const struct _value_string*)0 : ((dnp3_al_ctlc_tc_vals
))))
, AL_OBJCTLC_TC0xC0,
4416 "Control Code, Trip Close Control", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4417 },
4418
4419 { &hf_dnp3_ctl_dir,
4420 { "Direction", "dnp3.ctl.dir",
4421 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, DNP3_CTL_DIR0x80,
4422 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4423 },
4424
4425 { &hf_dnp3_ctl_prm,
4426 { "Primary", "dnp3.ctl.prm",
4427 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, DNP3_CTL_PRM0x40,
4428 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4429 },
4430
4431 { &hf_dnp3_ctl_fcb,
4432 { "Frame Count Bit", "dnp3.ctl.fcb",
4433 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, DNP3_CTL_FCB0x20,
4434 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4435 },
4436
4437 { &hf_dnp3_ctl_fcv,
4438 { "Frame Count Valid", "dnp3.ctl.fcv",
4439 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, DNP3_CTL_FCV0x10,
4440 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4441 },
4442
4443 { &hf_dnp3_ctl_dfc,
4444 { "Data Flow Control", "dnp3.ctl.dfc",
4445 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, DNP3_CTL_DFC0x10,
4446 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4447 },
4448
4449 { &hf_dnp3_dst,
4450 { "Destination", "dnp3.dst",
4451 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
4452 "Destination Address", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4453 },
4454
4455 { &hf_dnp3_src,
4456 { "Source", "dnp3.src",
4457 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
4458 "Source Address", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4459 },
4460
4461 { &hf_dnp3_addr,
4462 { "Address", "dnp3.addr",
4463 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
4464 "Source or Destination Address", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4465 },
4466
4467 { &hf_dnp3_data_hdr_crc,
4468 { "Data Link Header checksum", "dnp3.hdr.CRC",
4469 FT_UINT16, BASE_HEX, NULL((void*)0), 0x0,
4470 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4471 },
4472
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)((0 ? (const struct _value_string*)0 : ((proto_checksum_vals)
)))
, 0x0,
4476 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4477 },
4478
4479 { &hf_dnp3_tr_ctl,
4480 { "Transport Control", "dnp3.tr.ctl",
4481 FT_UINT8, BASE_HEX, NULL((void*)0), 0x0,
4482 "Transport Layer Control Byte", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4483 },
4484
4485 { &hf_dnp3_tr_fin,
4486 { "Final", "dnp3.tr.fin",
4487 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, DNP3_TR_FIN0x80,
4488 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4489 },
4490
4491 { &hf_dnp3_tr_fir,
4492 { "First", "dnp3.tr.fir",
4493 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, DNP3_TR_FIR0x40,
4494 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4495 },
4496
4497 { &hf_dnp3_tr_seq,
4498 { "Sequence", "dnp3.tr.seq",
4499 FT_UINT8, BASE_DEC, NULL((void*)0), DNP3_TR_SEQ0x3f,
4500 "Frame Sequence Number", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4501 },
4502
4503 { &hf_dnp3_data_chunk,
4504 { "Data Chunk", "dnp.data_chunk",
4505 FT_BYTES, BASE_NONE, NULL((void*)0), 0x0,
4506 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4507 },
4508
4509 { &hf_dnp3_data_chunk_len,
4510 { "Data Chunk length", "dnp.data_chunk_len",
4511 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
4512 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4513 },
4514
4515 { &hf_dnp3_data_chunk_crc,
4516 { "Data Chunk checksum", "dnp.data_chunk.CRC",
4517 FT_UINT16, BASE_HEX, NULL((void*)0), 0x0,
4518 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4519 },
4520
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)((0 ? (const struct _value_string*)0 : ((proto_checksum_vals)
)))
, 0x0,
4524 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4525 },
4526
4527 { &hf_dnp3_al_ctl,
4528 { "Application Control", "dnp3.al.ctl",
4529 FT_UINT8, BASE_HEX, NULL((void*)0), 0x0,
4530 "Application Layer Control Byte", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4531 },
4532
4533 { &hf_dnp3_al_fir,
4534 { "First", "dnp3.al.fir",
4535 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, DNP3_AL_FIR0x80,
4536 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4537 },
4538
4539 { &hf_dnp3_al_fin,
4540 { "Final", "dnp3.al.fin",
4541 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, DNP3_AL_FIN0x40,
4542 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4543 },
4544
4545 { &hf_dnp3_al_con,
4546 { "Confirm", "dnp3.al.con",
4547 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, DNP3_AL_CON0x20,
4548 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4549 },
4550
4551 { &hf_dnp3_al_uns,
4552 { "Unsolicited", "dnp3.al.uns",
4553 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, DNP3_AL_UNS0x10,
4554 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4555 },
4556
4557 { &hf_dnp3_al_seq,
4558 { "Sequence", "dnp3.al.seq",
4559 FT_UINT8, BASE_DEC, NULL((void*)0), DNP3_AL_SEQ0x0f,
4560 "Frame Sequence Number", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4561 },
4562
4563 { &hf_dnp3_al_func,
4564 { "Application Layer Function Code", "dnp3.al.func",
4565 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200, &dnp3_al_func_vals_ext, DNP3_AL_FUNC0xff,
4566 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4567 },
4568
4569 { &hf_dnp3_al_iin,
4570 { "Internal Indications", "dnp3.al.iin",
4571 FT_UINT16, BASE_HEX, NULL((void*)0), 0x0,
4572 "Application Layer IIN", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4573 },
4574
4575 { &hf_dnp3_al_iin_bmsg,
4576 { "Broadcast Msg Rx", "dnp3.al.iin.bmsg",
4577 FT_BOOLEAN, 16, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_IIN_BMSG0x0100,
4578 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4579 },
4580
4581 { &hf_dnp3_al_iin_cls1d,
4582 { "Class 1 Data Available", "dnp3.al.iin.cls1d",
4583 FT_BOOLEAN, 16, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_IIN_CLS1D0x0200,
4584 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4585 },
4586
4587 { &hf_dnp3_al_iin_cls2d,
4588 { "Class 2 Data Available", "dnp3.al.iin.cls2d",
4589 FT_BOOLEAN, 16, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_IIN_CLS2D0x0400,
4590 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4591 },
4592
4593 { &hf_dnp3_al_iin_cls3d,
4594 { "Class 3 Data Available", "dnp3.al.iin.cls3d",
4595 FT_BOOLEAN, 16, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_IIN_CLS3D0x0800,
4596 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4597 },
4598
4599 { &hf_dnp3_al_iin_tsr,
4600 { "Time Sync Required", "dnp3.al.iin.tsr",
4601 FT_BOOLEAN, 16, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_IIN_TSR0x1000,
4602 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4603 },
4604
4605 { &hf_dnp3_al_iin_dol,
4606 { "Digital Outputs in Local", "dnp3.al.iin.dol",
4607 FT_BOOLEAN, 16, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_IIN_DOL0x2000,
4608 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4609 },
4610
4611 { &hf_dnp3_al_iin_dt,
4612 { "Device Trouble", "dnp3.al.iin.dt",
4613 FT_BOOLEAN, 16, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_IIN_DT0x4000,
4614 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4615 },
4616
4617 { &hf_dnp3_al_iin_rst,
4618 { "Device Restart", "dnp3.al.iin.rst",
4619 FT_BOOLEAN, 16, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_IIN_RST0x8000,
4620 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4621 },
4622
4623 { &hf_dnp3_al_iin_fcni,
4624 { "Function Code not implemented", "dnp3.al.iin.fcni",
4625 FT_BOOLEAN, 16, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_IIN_FCNI0x0001,
4626 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4627 },
4628
4629 { &hf_dnp3_al_iin_obju,
4630 { "Requested Objects Unknown", "dnp3.al.iin.obju",
4631 FT_BOOLEAN, 16, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_IIN_OBJU0x0002,
4632 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4633 },
4634
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)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_IIN_PIOOR0x0004,
4638 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4639 },
4640
4641 { &hf_dnp3_al_iin_ebo,
4642 { "Event Buffer Overflow", "dnp3.al.iin.ebo",
4643 FT_BOOLEAN, 16, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_IIN_EBO0x0008,
4644 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4645 },
4646
4647 { &hf_dnp3_al_iin_oae,
4648 { "Operation Already Executing", "dnp3.al.iin.oae",
4649 FT_BOOLEAN, 16, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_IIN_OAE0x0010,
4650 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4651 },
4652
4653 { &hf_dnp3_al_iin_cc,
4654 { "Configuration Corrupt", "dnp3.al.iin.cc",
4655 FT_BOOLEAN, 16, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_IIN_CC0x0020,
4656 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4657 },
4658
4659 { &hf_dnp3_al_obj,
4660 { "Object", "dnp3.al.obj",
4661 FT_UINT16, BASE_HEX|BASE_EXT_STRING0x00000200, &dnp3_al_obj_vals_ext, 0x0,
4662 "Application Layer Object", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4663 },
4664
4665 { &hf_dnp3_al_objq_prefix,
4666 { "Prefix Code", "dnp3.al.objq.prefix",
4667 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200, &dnp3_al_objq_prefix_vals_ext, AL_OBJQ_PREFIX0x70,
4668 "Object Prefix Code", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4669 },
4670
4671 { &hf_dnp3_al_objq_range,
4672 { "Range Code", "dnp3.al.objq.range",
4673 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200, &dnp3_al_objq_range_vals_ext, AL_OBJQ_RANGE0x0F,
4674 "Object Range Specifier Code", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4675 },
4676
4677 { &hf_dnp3_al_range_start8,
4678 { "Start (8 bit)", "dnp3.al.range.start",
4679 FT_UINT8, BASE_DEC, NULL((void*)0), 0x0,
4680 "Object Start Index", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4681 },
4682
4683 { &hf_dnp3_al_range_stop8,
4684 { "Stop (8 bit)", "dnp3.al.range.stop",
4685 FT_UINT8, BASE_DEC, NULL((void*)0), 0x0,
4686 "Object Stop Index", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4687 },
4688
4689 { &hf_dnp3_al_range_start16,
4690 { "Start (16 bit)", "dnp3.al.range.start",
4691 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
4692 "Object Start Index", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4693 },
4694
4695 { &hf_dnp3_al_range_stop16,
4696 { "Stop (16 bit)", "dnp3.al.range.stop",
4697 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
4698 "Object Stop Index", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4699 },
4700
4701 { &hf_dnp3_al_range_start32,
4702 { "Start (32 bit)", "dnp3.al.range.start",
4703 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
4704 "Object Start Index", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4705 },
4706
4707 { &hf_dnp3_al_range_stop32,
4708 { "Stop (32 bit)", "dnp3.al.range.stop",
4709 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
4710 "Object Stop Index", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4711 },
4712
4713 { &hf_dnp3_al_range_abs8,
4714 { "Address (8 bit)", "dnp3.al.range.abs",
4715 FT_UINT8, BASE_DEC, NULL((void*)0), 0x0,
4716 "Object Absolute Address", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4717 },
4718
4719 { &hf_dnp3_al_range_abs16,
4720 { "Address (16 bit)", "dnp3.al.range.abs",
4721 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
4722 "Object Absolute Address", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4723 },
4724
4725 { &hf_dnp3_al_range_abs32,
4726 { "Address (32 bit)", "dnp3.al.range.abs",
4727 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
4728 "Object Absolute Address", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4729 },
4730
4731 { &hf_dnp3_al_range_quant8,
4732 { "Quantity (8 bit)", "dnp3.al.range.quantity",
4733 FT_UINT8, BASE_DEC, NULL((void*)0), 0x0,
4734 "Object Quantity", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4735 },
4736
4737 { &hf_dnp3_al_range_quant16,
4738 { "Quantity (16 bit)", "dnp3.al.range.quantity",
4739 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
4740 "Object Quantity", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4741 },
4742
4743 { &hf_dnp3_al_range_quant32,
4744 { "Quantity (32 bit)", "dnp3.al.range.quantity",
4745 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
4746 "Object Quantity", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4747 },
4748
4749 { &hf_dnp3_al_index8,
4750 { "Index (8 bit)", "dnp3.al.index",
4751 FT_UINT8, BASE_DEC, NULL((void*)0), 0x0,
4752 "Object Index", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4753 },
4754
4755 { &hf_dnp3_al_index16,
4756 { "Index (16 bit)", "dnp3.al.index",
4757 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
4758 "Object Index", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4759 },
4760
4761 { &hf_dnp3_al_index32,
4762 { "Index (32 bit)", "dnp3.al.index",
4763 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
4764 "Object Index", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4765 },
4766
4767#if 0
4768 { &hf_dnp3_al_ptnum,
4769 { "Object Point Number", "dnp3.al.ptnum",
4770 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
4771 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4772 },
4773#endif
4774
4775 { &hf_dnp3_al_size8,
4776 { "Size (8 bit)", "dnp3.al.size",
4777 FT_UINT8, BASE_DEC, NULL((void*)0), 0x0,
4778 "Object Size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4779 },
4780
4781 { &hf_dnp3_al_size16,
4782 { "Size (16 bit)", "dnp3.al.size",
4783 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
4784 "Object Size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4785 },
4786
4787 { &hf_dnp3_al_size32,
4788 { "Size (32 bit)", "dnp3.al.size",
4789 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
4790 "Object Size", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4791 },
4792
4793 { &hf_dnp3_bocs_bit,
4794 { "Commanded State", "dnp3.al.bocs",
4795 FT_BOOLEAN, 8, TFS(&tfs_on_off)((0 ? (const struct true_false_string*)0 : ((&tfs_on_off)
)))
, 0x80,
4796 "Binary Output Commanded state", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4797 },
4798
4799 { &hf_dnp3_al_bit,
4800 { "Value (bit)", "dnp3.al.bit",
4801 FT_BOOLEAN, 8, TFS(&tfs_on_off)((0 ? (const struct true_false_string*)0 : ((&tfs_on_off)
)))
, 0x1,
4802 "Digital Value (1 bit)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4803 },
4804
4805 { &hf_dnp3_al_bit0,
4806 { "Value (bit)", "dnp3.al.bit",
4807 FT_BOOLEAN, 8, TFS(&tfs_on_off)((0 ? (const struct true_false_string*)0 : ((&tfs_on_off)
)))
, 0x01,
4808 "Digital Value (1 bit)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4809 },
4810 { &hf_dnp3_al_bit1,
4811 { "Value (bit)", "dnp3.al.bit",
4812 FT_BOOLEAN, 8, TFS(&tfs_on_off)((0 ? (const struct true_false_string*)0 : ((&tfs_on_off)
)))
, 0x02,
4813 "Digital Value (1 bit)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4814 },
4815 { &hf_dnp3_al_bit2,
4816 { "Value (bit)", "dnp3.al.bit",
4817 FT_BOOLEAN, 8, TFS(&tfs_on_off)((0 ? (const struct true_false_string*)0 : ((&tfs_on_off)
)))
, 0x04,
4818 "Digital Value (1 bit)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4819 },
4820 { &hf_dnp3_al_bit3,
4821 { "Value (bit)", "dnp3.al.bit",
4822 FT_BOOLEAN, 8, TFS(&tfs_on_off)((0 ? (const struct true_false_string*)0 : ((&tfs_on_off)
)))
, 0x08,
4823 "Digital Value (1 bit)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4824 },
4825 { &hf_dnp3_al_bit4,
4826 { "Value (bit)", "dnp3.al.bit",
4827 FT_BOOLEAN, 8, TFS(&tfs_on_off)((0 ? (const struct true_false_string*)0 : ((&tfs_on_off)
)))
, 0x10,
4828 "Digital Value (1 bit)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4829 },
4830 { &hf_dnp3_al_bit5,
4831 { "Value (bit)", "dnp3.al.bit",
4832 FT_BOOLEAN, 8, TFS(&tfs_on_off)((0 ? (const struct true_false_string*)0 : ((&tfs_on_off)
)))
, 0x20,
4833 "Digital Value (1 bit)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4834 },
4835 { &hf_dnp3_al_bit6,
4836 { "Value (bit)", "dnp3.al.bit",
4837 FT_BOOLEAN, 8, TFS(&tfs_on_off)((0 ? (const struct true_false_string*)0 : ((&tfs_on_off)
)))
, 0x40,
4838 "Digital Value (1 bit)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4839 },
4840 { &hf_dnp3_al_bit7,
4841 { "Value (bit)", "dnp3.al.bit",
4842 FT_BOOLEAN, 8, TFS(&tfs_on_off)((0 ? (const struct true_false_string*)0 : ((&tfs_on_off)
)))
, 0x80,
4843 "Digital Value (1 bit)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4844 },
4845
4846 { &hf_dnp3_al_2bit,
4847 { "Value (Double-bit)", "dnp3.al.2bit",
4848 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200, &dnp3_al_dbi_vals_ext, AL_OBJ_DBI_MASK0xC0,
4849 "Digital Value (Double-bit)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4850 },
4851
4852 { &hf_dnp3_al_2bit0,
4853 { "Value (Double-bit)", "dnp3.al.2bit",
4854 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200, &dnp3_al_dbi_vals_ext, 0x03,
4855 "Digital Value (Double-bit)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4856 },
4857
4858 { &hf_dnp3_al_2bit1,
4859 { "Value (Double-bit)", "dnp3.al.2bit",
4860 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200, &dnp3_al_dbi_vals_ext, 0x0c,
4861 "Digital Value (Double-bit)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4862 },
4863
4864 { &hf_dnp3_al_2bit2,
4865 { "Value (Double-bit)", "dnp3.al.2bit",
4866 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200, &dnp3_al_dbi_vals_ext, 0x30,
4867 "Digital Value (Double-bit)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4868 },
4869 { &hf_dnp3_al_2bit3,
4870 { "Value (Double-bit)", "dnp3.al.2bit",
4871 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200, &dnp3_al_dbi_vals_ext, 0xc0,
4872 "Digital Value (Double-bit)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4873 },
4874
4875 { &hf_dnp3_al_ana16,
4876 { "Value (16 bit)", "dnp3.al.ana.int",
4877 FT_INT16, BASE_DEC, NULL((void*)0), 0x0,
4878 "Analog Value (16 bit)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4879 },
4880
4881 { &hf_dnp3_al_ana32,
4882 { "Value (32 bit)", "dnp3.al.ana.int",
4883 FT_INT32, BASE_DEC, NULL((void*)0), 0x0,
4884 "Analog Value (32 bit)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4885 },
4886
4887 { &hf_dnp3_al_anaflt,
4888 { "Value (float)", "dnp3.al.ana.float",
4889 FT_FLOAT, BASE_NONE, NULL((void*)0), 0x0,
4890 "Analog Value (float)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4891 },
4892
4893 { &hf_dnp3_al_anadbl,
4894 { "Value (double)", "dnp3.al.ana.double",
4895 FT_DOUBLE, BASE_NONE, NULL((void*)0), 0x0,
4896 "Analog Value (double)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4897 },
4898
4899 { &hf_dnp3_al_anaout16,
4900 { "Output Value (16 bit)", "dnp3.al.anaout.int",
4901 FT_INT16, BASE_DEC, NULL((void*)0), 0x0,
4902 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4903 },
4904
4905 { &hf_dnp3_al_anaout32,
4906 { "Output Value (32 bit)", "dnp3.al.anaout.int",
4907 FT_INT32, BASE_DEC, NULL((void*)0), 0x0,
4908 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4909 },
4910
4911 { &hf_dnp3_al_anaoutflt,
4912 { "Output Value (float)", "dnp3.al.anaout.float",
4913 FT_FLOAT, BASE_NONE, NULL((void*)0), 0x0,
4914 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4915 },
4916
4917 { &hf_dnp3_al_anaoutdbl,
4918 { "Output (double)", "dnp3.al.anaout.double",
4919 FT_DOUBLE, BASE_NONE, NULL((void*)0), 0x0,
4920 "Output Value (double)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4921 },
4922
4923 { &hf_dnp3_al_cnt16,
4924 { "Counter (16 bit)", "dnp3.al.cnt",
4925 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
4926 "Counter Value (16 bit)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4927 },
4928
4929 { &hf_dnp3_al_cnt32,
4930 { "Counter (32 bit)", "dnp3.al.cnt",
4931 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
4932 "Counter Value (32 bit)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4933 },
4934
4935 { &hf_dnp3_al_ctrlstatus,
4936 { "Control Status", "dnp3.al.ctrlstatus",
4937 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200, &dnp3_al_ctl_status_vals_ext, AL_OBJCTL_STATUS_MASK0x7F,
4938 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4939 },
4940
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)((0 ? (const struct _value_string*)0 : ((dnp3_al_file_mode_vals
))))
, 0x0,
4944 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4945 },
4946
4947 { &hf_dnp3_al_file_auth,
4948 { "File Authentication Key", "dnp3.al.file.auth",
4949 FT_UINT32, BASE_HEX, NULL((void*)0), 0x0,
4950 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4951 },
4952
4953 { &hf_dnp3_al_file_size,
4954 { "File Size", "dnp3.al.file.size",
4955 FT_UINT32, BASE_HEX, NULL((void*)0), 0x0,
4956 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4957 },
4958
4959 { &hf_dnp3_al_file_maxblk,
4960 { "File Max Block Size", "dnp3.al.file.maxblock",
4961 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
4962 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4963 },
4964
4965 { &hf_dnp3_al_file_reqID,
4966 { "File Request Identifier", "dnp3.al.file.reqID",
4967 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
4968 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4969 },
4970
4971 { &hf_dnp3_al_file_status,
4972 { "File Control Status", "dnp3.al.file.status",
4973 FT_UINT8, BASE_DEC|BASE_EXT_STRING0x00000200, &dnp3_al_file_status_vals_ext, 0x0,
4974 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4975 },
4976
4977 { &hf_dnp3_al_file_handle,
4978 { "File Handle", "dnp3.al.file.handle",
4979 FT_UINT32, BASE_HEX, NULL((void*)0), 0x0,
4980 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4981 },
4982
4983 { &hf_dnp3_al_file_blocknum,
4984 { "File Block Number", "dnp3.al.file.blocknum",
4985 FT_UINT32, BASE_HEX, NULL((void*)0), 0x7fffffff,
4986 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4987 },
4988
4989 { &hf_dnp3_al_file_lastblock,
4990 { "File Last Block", "dnp3.al.file.lastblock",
4991 FT_BOOLEAN, 32, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0x80000000,
4992 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4993 },
4994
4995 { &hf_dnp3_al_file_data,
4996 { "File Data", "dnp3.al.file.data",
4997 FT_BYTES, BASE_NONE, NULL((void*)0), 0x0,
4998 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
4999 },
5000
5001 { &hf_dnp3_al_biq_b0,
5002 { "Online", "dnp3.al.biq.b0",
5003 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_BI_FLAG00x01,
5004 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5005 },
5006
5007 { &hf_dnp3_al_biq_b1,
5008 { "Restart", "dnp3.al.biq.b1",
5009 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_BI_FLAG10x02,
5010 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5011 },
5012
5013 { &hf_dnp3_al_biq_b2,
5014 { "Comm Fail", "dnp3.al.biq.b2",
5015 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_BI_FLAG20x04,
5016 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5017 },
5018
5019 { &hf_dnp3_al_biq_b3,
5020 { "Remote Force", "dnp3.al.biq.b3",
5021 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_BI_FLAG30x08,
5022 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5023 },
5024
5025 { &hf_dnp3_al_biq_b4,
5026 { "Local Force", "dnp3.al.biq.b4",
5027 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_BI_FLAG40x10,
5028 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5029 },
5030
5031 { &hf_dnp3_al_biq_b5,
5032 { "Chatter Filter", "dnp3.al.biq.b5",
5033 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_BI_FLAG50x20,
5034 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5035 },
5036
5037 { &hf_dnp3_al_biq_b6,
5038 { "Reserved", "dnp3.al.biq.b6",
5039 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_BI_FLAG60x40,
5040 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5041 },
5042
5043 { &hf_dnp3_al_biq_b7,
5044 { "Point Value", "dnp3.al.biq.b7",
5045 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_BI_FLAG70x80,
5046 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5047 },
5048
5049 { &hf_dnp3_al_boq_b0,
5050 { "Online", "dnp3.al.boq.b0",
5051 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_BO_FLAG00x01,
5052 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5053 },
5054
5055 { &hf_dnp3_al_boq_b1,
5056 { "Restart", "dnp3.al.boq.b1",
5057 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_BO_FLAG10x02,
5058 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5059 },
5060
5061 { &hf_dnp3_al_boq_b2,
5062 { "Comm Fail", "dnp3.al.boq.b2",
5063 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_BO_FLAG20x04,
5064 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5065 },
5066
5067 { &hf_dnp3_al_boq_b3,
5068 { "Remote Force", "dnp3.al.boq.b3",
5069 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_BO_FLAG30x08,
5070 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5071 },
5072
5073 { &hf_dnp3_al_boq_b4,
5074 { "Local Force", "dnp3.al.boq.b4",
5075 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_BO_FLAG40x10,
5076 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5077 },
5078
5079 { &hf_dnp3_al_boq_b5,
5080 { "Reserved", "dnp3.al.boq.b5",
5081 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_BO_FLAG50x20,
5082 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5083 },
5084
5085 { &hf_dnp3_al_boq_b6,
5086 { "Reserved", "dnp3.al.boq.b6",
5087 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_BO_FLAG60x40,
5088 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5089 },
5090
5091 { &hf_dnp3_al_boq_b7,
5092 { "Point Value", "dnp3.al.boq.b7",
5093 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_BO_FLAG70x80,
5094 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5095 },
5096
5097 { &hf_dnp3_al_ctrq_b0,
5098 { "Online", "dnp3.al.ctrq.b0",
5099 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_CTR_FLAG00x01,
5100 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5101 },
5102
5103 { &hf_dnp3_al_ctrq_b1,
5104 { "Restart", "dnp3.al.ctrq.b1",
5105 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_CTR_FLAG10x02,
5106 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5107 },
5108
5109 { &hf_dnp3_al_ctrq_b2,
5110 { "Comm Fail", "dnp3.al.ctrq.b2",
5111 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_CTR_FLAG20x04,
5112 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5113 },
5114
5115 { &hf_dnp3_al_ctrq_b3,
5116 { "Remote Force", "dnp3.al.ctrq.b3",
5117 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_CTR_FLAG30x08,
5118 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5119 },
5120
5121 { &hf_dnp3_al_ctrq_b4,
5122 { "Local Force", "dnp3.al.ctrq.b4",
5123 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_CTR_FLAG40x10,
5124 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5125 },
5126
5127 { &hf_dnp3_al_ctrq_b5,
5128 { "Roll-Over", "dnp3.al.ctrq.b5",
5129 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_CTR_FLAG50x20,
5130 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5131 },
5132
5133 { &hf_dnp3_al_ctrq_b6,
5134 { "Discontinuity", "dnp3.al.ctrq.b6",
5135 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_CTR_FLAG60x40,
5136 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5137 },
5138
5139 { &hf_dnp3_al_ctrq_b7,
5140 { "Reserved", "dnp3.al.ctrq.b7",
5141 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_CTR_FLAG70x80,
5142 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5143 },
5144
5145 { &hf_dnp3_al_aiq_b0,
5146 { "Online", "dnp3.al.aiq.b0",
5147 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_AI_FLAG00x01,
5148 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5149 },
5150
5151 { &hf_dnp3_al_aiq_b1,
5152 { "Restart", "dnp3.al.aiq.b1",
5153 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_AI_FLAG10x02,
5154 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5155 },
5156
5157 { &hf_dnp3_al_aiq_b2,
5158 { "Comm Fail", "dnp3.al.aiq.b2",
5159 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_AI_FLAG20x04,
5160 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5161 },
5162
5163 { &hf_dnp3_al_aiq_b3,
5164 { "Remote Force", "dnp3.al.aiq.b3",
5165 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_AI_FLAG30x08,
5166 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5167 },
5168
5169 { &hf_dnp3_al_aiq_b4,
5170 { "Local Force", "dnp3.al.aiq.b4",
5171 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_AI_FLAG40x10,
5172 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5173 },
5174
5175 { &hf_dnp3_al_aiq_b5,
5176 { "Over-Range", "dnp3.al.aiq.b5",
5177 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_AI_FLAG50x20,
5178 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5179 },
5180
5181 { &hf_dnp3_al_aiq_b6,
5182 { "Reference Check", "dnp3.al.aiq.b6",
5183 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_AI_FLAG60x40,
5184 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5185 },
5186
5187 { &hf_dnp3_al_aiq_b7,
5188 { "Reserved", "dnp3.al.aiq.b7",
5189 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_AI_FLAG70x80,
5190 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5191 },
5192
5193 { &hf_dnp3_al_aoq_b0,
5194 { "Online", "dnp3.al.aoq.b0",
5195 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_AO_FLAG00x01,
5196 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5197 },
5198
5199 { &hf_dnp3_al_aoq_b1,
5200 { "Restart", "dnp3.al.aoq.b1",
5201 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_AO_FLAG10x02,
5202 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5203 },
5204
5205 { &hf_dnp3_al_aoq_b2,
5206 { "Comm Fail", "dnp3.al.aoq.b2",
5207 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_AO_FLAG20x04,
5208 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5209 },
5210
5211 { &hf_dnp3_al_aoq_b3,
5212 { "Remote Force", "dnp3.al.aoq.b3",
5213 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_AO_FLAG30x08,
5214 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5215 },
5216
5217 { &hf_dnp3_al_aoq_b4,
5218 { "Local Force", "dnp3.al.aoq.b4",
5219 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_AO_FLAG40x10,
5220 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5221 },
5222
5223 { &hf_dnp3_al_aoq_b5,
5224 { "Reserved", "dnp3.al.aoq.b5",
5225 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_AO_FLAG50x20,
5226 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5227 },
5228
5229 { &hf_dnp3_al_aoq_b6,
5230 { "Reserved", "dnp3.al.aoq.b6",
5231 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_AO_FLAG60x40,
5232 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5233 },
5234
5235 { &hf_dnp3_al_aoq_b7,
5236 { "Reserved", "dnp3.al.aoq.b7",
5237 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, AL_OBJ_AO_FLAG70x80,
5238 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5239 },
5240
5241 { &hf_dnp3_al_timestamp,
5242 { "Timestamp", "dnp3.al.timestamp",
5243 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL((void*)0), 0,
5244 "Object Timestamp", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5245 },
5246
5247 { &hf_dnp3_al_file_perms,
5248 { "Permissions", "dnp3.al.file.perms",
5249 FT_UINT16, BASE_OCT, NULL((void*)0), 0x0,
5250 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5251 },
5252
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)((0 ? (const struct true_false_string*)0 : ((&tfs_yes_no)
)))
, 0400,
5256 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5257 },
5258
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)((0 ? (const struct true_false_string*)0 : ((&tfs_yes_no)
)))
, 0200,
5262 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5263 },
5264
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)((0 ? (const struct true_false_string*)0 : ((&tfs_yes_no)
)))
, 0100,
5268 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5269 },
5270
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)((0 ? (const struct true_false_string*)0 : ((&tfs_yes_no)
)))
, 040,
5274 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5275 },
5276
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)((0 ? (const struct true_false_string*)0 : ((&tfs_yes_no)
)))
, 020,
5280 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5281 },
5282
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)((0 ? (const struct true_false_string*)0 : ((&tfs_yes_no)
)))
, 010,
5286 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5287 },
5288
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)((0 ? (const struct true_false_string*)0 : ((&tfs_yes_no)
)))
, 04,
5292 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5293 },
5294
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)((0 ? (const struct true_false_string*)0 : ((&tfs_yes_no)
)))
, 02,
5298 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5299 },
5300
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)((0 ? (const struct true_false_string*)0 : ((&tfs_yes_no)
)))
, 01,
5304 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5305 },
5306
5307 { &hf_dnp3_al_rel_timestamp,
5308 { "Relative Timestamp", "dnp3.al.reltimestamp",
5309 FT_RELATIVE_TIME, BASE_NONE, NULL((void*)0), 0,
5310 "Object Relative Timestamp", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5311 },
5312
5313 { &hf_dnp3_al_datatype,
5314 { "Data Type", "dnp3.al.datatype",
5315 FT_UINT8, BASE_HEX, VALS(dnp3_al_data_type_vals)((0 ? (const struct _value_string*)0 : ((dnp3_al_data_type_vals
))))
, 0,
5316 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5317 },
5318
5319 { &hf_dnp3_al_da_length,
5320 { "Device Attribute Length", "dnp3.al.da.length",
5321 FT_UINT8, BASE_DEC, NULL((void*)0), 0,
5322 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5323 },
5324
5325 { &hf_dnp3_al_da_uint8,
5326 { "Device Attribute 8-Bit Unsigned Integer Value", "dnp3.al.da.uint8",
5327 FT_UINT8, BASE_DEC, NULL((void*)0), 0,
5328 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5329 },
5330
5331 { &hf_dnp3_al_da_uint16,
5332 { "Device Attribute 16-Bit Unsigned Integer Value", "dnp3.al.da.uint16",
5333 FT_UINT16, BASE_DEC, NULL((void*)0), 0,
5334 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5335 },
5336
5337 { &hf_dnp3_al_da_uint32,
5338 { "Device Attribute 32-Bit Unsigned Integer Value", "dnp3.al.da.uint32",
5339 FT_UINT32, BASE_DEC, NULL((void*)0), 0,
5340 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5341 },
5342
5343 { &hf_dnp3_al_da_int8,
5344 { "Device Attribute 8-Bit Integer Value", "dnp3.al.da.int8",
5345 FT_INT8, BASE_DEC, NULL((void*)0), 0,
5346 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5347 },
5348
5349 { &hf_dnp3_al_da_int16,
5350 { "Device Attribute 16-Bit Integer Value", "dnp3.al.da.int16",
5351 FT_INT16, BASE_DEC, NULL((void*)0), 0,
5352 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5353 },
5354
5355 { &hf_dnp3_al_da_int32,
5356 { "Device Attribute 32-Bit Integer Value", "dnp3.al.da.int32",
5357 FT_INT32, BASE_DEC, NULL((void*)0), 0,
5358 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5359 },
5360
5361 { &hf_dnp3_al_da_flt,
5362 { "Device Attribute Float Value", "dnp3.al.da.float",
5363 FT_FLOAT, BASE_NONE, NULL((void*)0), 0,
5364 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5365 },
5366
5367 { &hf_dnp3_al_da_dbl,
5368 { "Device Attribute Double Value", "dnp3.al.da.double",
5369 FT_DOUBLE, BASE_NONE, NULL((void*)0), 0,
5370 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5371 },
5372
5373 { &hf_dnp3_al_sa_assoc_id,
5374 { "Association ID" , "dnp3.al.sa.assoc_id",
5375 FT_UINT16, BASE_DEC, NULL((void*)0), 0,
5376 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5377 },
5378
5379 { &hf_dnp3_al_sa_cd,
5380 {"Challenge Data", "dnp3.al.sa.cd",
5381 FT_BYTES, BASE_NONE, NULL((void*)0), 0x00,
5382 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5383
5384 { &hf_dnp3_al_sa_cdl,
5385 { "Challenge Data Length", "dnp3.al.sa.cdl",
5386 FT_UINT16, BASE_HEX, NULL((void*)0), 0,
5387 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5388 },
5389
5390 { &hf_dnp3_al_sa_csq,
5391 { "Challenge Sequence Number" , "dnp3.al.sa.csq",
5392 FT_UINT32, BASE_DEC, NULL((void*)0), 0,
5393 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5394 },
5395
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 ? (const struct _value_string*)0 : ((dnp3_al_sa_err_vals)
)))
, 0,
5399 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5400 },
5401
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 ? (const struct _value_string*)0 : ((dnp3_al_sa_kcm_vals)
)))
, 0,
5405 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5406 },
5407
5408 { &hf_dnp3_al_sa_key,
5409 {"Key Data", "dnp3.al.sa.key",
5410 FT_BYTES, BASE_NONE, NULL((void*)0), 0x00,
5411 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5412
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 ? (const struct _value_string*)0 : ((dnp3_al_sa_ks_vals))
))
, 0,
5416 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5417 },
5418
5419 { &hf_dnp3_al_sa_ksq,
5420 { "Key Change Sequence Number" , "dnp3.al.sa.ksq",
5421 FT_UINT32, BASE_DEC, NULL((void*)0), 0,
5422 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5423 },
5424
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 ? (const struct _value_string*)0 : ((dnp3_al_sa_kwa_vals)
)))
, 0,
5428 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5429 },
5430
5431 { &hf_dnp3_al_sa_mac,
5432 {"MAC Value", "dnp3.al.sa.mac",
5433 FT_BYTES, BASE_NONE, NULL((void*)0), 0x00,
5434 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5435
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 ? (const struct _value_string*)0 : ((dnp3_al_sa_mal_vals)
)))
, 0,
5439 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5440 },
5441
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 ? (const struct _value_string*)0 : ((dnp3_al_sa_rfc_vals)
)))
, 0,
5445 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5446 },
5447
5448 { &hf_dnp3_al_sa_seq,
5449 { "Sequence Number" , "dnp3.al.sa.seq",
5450 FT_UINT32, BASE_DEC, NULL((void*)0), 0,
5451 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5452 },
5453
5454 { &hf_dnp3_al_sa_uk,
5455 {"Encrypted Update Key Data", "dnp3.al.sa.uk",
5456 FT_BYTES, BASE_NONE, NULL((void*)0), 0x00,
5457 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5458
5459 { &hf_dnp3_al_sa_ukl,
5460 { "Encrypted Update Key Length", "dnp3.al.sa.ukl",
5461 FT_UINT16, BASE_DEC, NULL((void*)0), 0,
5462 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5463 },
5464
5465 { &hf_dnp3_al_sa_usr,
5466 { "User Number" , "dnp3.al.sa.usr",
5467 FT_UINT16, BASE_DEC, NULL((void*)0), 0,
5468 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5469 },
5470
5471 { &hf_dnp3_al_sa_usrn,
5472 { "User Name", "dnp3.al.sa.usrn",
5473 FT_STRING, BASE_NONE, NULL((void*)0), 0x0,
5474 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5475
5476 { &hf_dnp3_al_sa_usrnl,
5477 { "User name Length", "dnp3.al.sa.usrnl",
5478 FT_UINT16, BASE_DEC, NULL((void*)0), 0,
5479 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5480 },
5481
5482 { &hf_al_frag_data,
5483 {"DNP3.0 AL Fragment Data", "dnp3.al.frag_data",
5484 FT_BYTES, BASE_NONE, NULL((void*)0), 0x00,
5485 "DNP 3.0 Application Layer Fragment Data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5486
5487 { &hf_dnp3_fragment,
5488 { "DNP 3.0 AL Fragment", "dnp3.al.fragment",
5489 FT_FRAMENUM, BASE_NONE, NULL((void*)0), 0x0,
5490 "DNP 3.0 Application Layer Fragment", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5491 },
5492
5493 { &hf_dnp3_fragments,
5494 { "DNP 3.0 AL Fragments", "dnp3.al.fragments",
5495 FT_NONE, BASE_NONE, NULL((void*)0), 0x0,
5496 "DNP 3.0 Application Layer Fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5497 },
5498
5499 { &hf_dnp3_fragment_overlap,
5500 { "Fragment overlap", "dnp3.al.fragment.overlap",
5501 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
5502 "Fragment overlaps with other fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5503 },
5504
5505 { &hf_dnp3_fragment_overlap_conflict,
5506 { "Conflicting data in fragment overlap", "dnp3.al.fragment.overlap.conflict",
5507 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
5508 "Overlapping fragments contained conflicting data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5509 },
5510
5511 { &hf_dnp3_fragment_multiple_tails,
5512 { "Multiple tail fragments found", "dnp3.al.fragment.multipletails",
5513 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
5514 "Several tails were found when defragmenting the packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5515 },
5516
5517 { &hf_dnp3_fragment_too_long_fragment,
5518 { "Fragment too long", "dnp3.al.fragment.toolongfragment",
5519 FT_BOOLEAN, BASE_NONE, NULL((void*)0), 0x0,
5520 "Fragment contained data past end of packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5521 },
5522
5523 { &hf_dnp3_fragment_error,
5524 { "Defragmentation error", "dnp3.al.fragment.error",
5525 FT_FRAMENUM, BASE_NONE, NULL((void*)0), 0x0,
5526 "Defragmentation error due to illegal fragments", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5527 },
5528
5529 { &hf_dnp3_fragment_count,
5530 { "Fragment count", "dnp3.al.fragment.count",
5531 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
5532 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5533 },
5534
5535 { &hf_dnp3_fragment_reassembled_in,
5536 { "Reassembled PDU In Frame", "dnp3.al.fragment.reassembled_in",
5537 FT_FRAMENUM, BASE_NONE, NULL((void*)0), 0x0,
5538 "This PDU is reassembled in this frame", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5539 },
5540
5541 { &hf_dnp3_fragment_reassembled_length,
5542 { "Reassembled DNP length", "dnp3.al.fragment.reassembled.length",
5543 FT_UINT32, BASE_DEC, NULL((void*)0), 0x0,
5544 "The total length of the reassembled payload", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }
5545 },
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((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5548 { &hf_dnp3_al_da_value, { "Value", "dnp3.al.da.value", FT_STRING, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5549 { &hf_dnp3_al_count, { "Count", "dnp3.al.count", FT_UINT8, BASE_DEC, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5550 { &hf_dnp3_al_on_time, { "On Time", "dnp3.al.on_time", FT_UINT32, BASE_DEC, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5551 { &hf_dnp3_al_off_time, { "Off Time", "dnp3.al.off_time", FT_UINT32, BASE_DEC, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5552 { &hf_dnp3_al_time_delay, { "Time Delay", "dnp3.al.time_delay", FT_UINT16, BASE_DEC|BASE_UNIT_STRING0x00001000, UNS(&units_milliseconds)((0 ? (const struct unit_name_string*)0 : ((&units_milliseconds
))))
, 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5553 { &hf_dnp3_al_file_string_offset, { "File String Offset", "dnp3.al.file_string_offset", FT_UINT16, BASE_DEC, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5554 { &hf_dnp3_al_file_string_length, { "File String Length", "dnp3.al.file_string_length", FT_UINT16, BASE_DEC, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5555 { &hf_dnp3_al_file_name, { "File Name", "dnp3.al.file_name", FT_STRING, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5556 { &hf_dnp3_al_octet_string, { "Octet String", "dnp3.al.octet_string", FT_BYTES, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5557 { &hf_dnp3_unknown_data_chunk, { "Unknown Data Chunk", "dnp3.al.unknown_data_chunk", FT_BYTES, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5558
5559 };
5560
5561/* Setup protocol subtree array */
5562 static int *ett[] = {
5563 &ett_dnp3,
5564 &ett_dnp3_dl,
5565 &ett_dnp3_dl_ctl,
5566 &ett_dnp3_tr_ctl,
5567 &ett_dnp3_dl_data,
5568 &ett_dnp3_dl_chunk,
5569 &ett_dnp3_al,
5570 &ett_dnp3_al_ctl,
5571 &ett_dnp3_al_obj_point_tcc,
5572 &ett_dnp3_al_iin,
5573 &ett_dnp3_al_obj,
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,
5580 &ett_dnp3_fragment,
5581 &ett_dnp3_fragments
5582 };
5583 static ei_register_info ei[] = {
5584 { &ei_dnp_num_items_neg, { "dnp3.num_items_neg", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Negative number of items", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
5585 { &ei_dnp_invalid_length, { "dnp3.invalid_length", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Invalid length", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
5586 { &ei_dnp_iin_abnormal, { "dnp3.iin_abnormal", PI_PROTOCOL0x09000000, PI_WARN0x00600000, "IIN Abnormality", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
5587 { &ei_dnp3_data_hdr_crc_incorrect, { "dnp3.hdr.CRC.incorrect", PI_CHECKSUM0x01000000, PI_WARN0x00600000, "Data Link Header Checksum incorrect", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
5588 { &ei_dnp3_data_chunk_crc_incorrect, { "dnp3.data_chunk.CRC.incorrect", PI_CHECKSUM0x01000000, PI_WARN0x00600000, "Data Chunk Checksum incorrect", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
5589 { &ei_dnp3_unknown_object, { "dnp3.unknown_object", PI_PROTOCOL0x09000000, PI_WARN0x00600000, "Unknown Object\\Variation", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
5590 { &ei_dnp3_unknown_group0_variation, { "dnp3.unknown_group0_variation", PI_PROTOCOL0x09000000, PI_WARN0x00600000, "Unknown Group 0 Variation", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
5591 { &ei_dnp3_num_items_invalid, { "dnp3.num_items_invalid", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Number of items is invalid for normally empty object. Potentially malicious packet", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
5592 /* Generated from convert_proto_tree_add_text.pl */
5593#if 0
5594 { &ei_dnp3_buffering_user_data_until_final_frame_is_received, { "dnp3.buffering_user_data_until_final_frame_is_received", PI_PROTOCOL0x09000000, PI_WARN0x00600000, "Buffering User Data Until Final Frame is Received..", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
5595#endif
5596 };
5597
5598 module_t *dnp3_module;
5599 expert_module_t* expert_dnp3;
5600
5601 reassembly_table_register(&al_reassembly_table,
5602 &addresses_reassembly_table_functions);
5603
5604/* Register the protocol name and description */
5605 proto_dnp3 = proto_register_protocol("Distributed Network Protocol 3.0", "DNP 3.0", "dnp3");
5606
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);
5610
5611/* Required function calls to register the header fields and subtrees used */
5612 proto_register_field_array(proto_dnp3, hf, array_length(hf)(sizeof (hf) / sizeof (hf)[0]));
5613 proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0]));
5614 expert_dnp3 = expert_register_protocol(proto_dnp3);
5615 expert_register_field_array(expert_dnp3, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
5616
5617 dnp3_module = prefs_register_protocol(proto_dnp3, NULL((void*)0));
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.",
5623 &dnp3_desegment);
5624
5625 /* Register tap */
5626 dnp3_tap = register_tap("dnp3");
5627
5628 register_conversation_table(proto_dnp3, true1, dnp3_conversation_packet, dnp3_endpoint_packet);
5629}
5630
5631void
5632proto_reg_handoff_dnp3(void)
5633{
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);
5637
5638 dissector_add_uint_with_preference("tcp.port", TCP_PORT_DNP20000, dnp3_tcp_handle);
5639 dissector_add_uint_with_preference("udp.port", UDP_PORT_DNP20000, dnp3_udp_handle);
5640 dissector_add_for_decode_as("rtacser.data", dnp3_udp_handle);
5641
5642 ssl_dissector_add(TCP_PORT_DNP_TLS19999, dnp3_tcp_handle);
5643}
5644
5645/*
5646 * Editor modelines
5647 *
5648 * Local Variables:
5649 * c-basic-offset: 2
5650 * tab-width: 8
5651 * indent-tabs-mode: nil
5652 * End:
5653 *
5654 * ex: set shiftwidth=2 tabstop=8 expandtab:
5655 * :indentSize=2:tabSize=8:noTabs=true:
5656 */
5657