2007-05-15 09:05:53 +00:00
/******************************************************************************
* * Copyright ( C ) 2006 - 2007 ascolab GmbH . All Rights Reserved .
* * Web : http : //www.ascolab.com
2009-10-20 14:03:00 +00:00
* *
2018-02-09 08:52:20 +00:00
* * SPDX - License - Identifier : GPL - 2.0 - or - later
2009-10-20 14:03:00 +00:00
* *
2007-05-15 09:05:53 +00:00
* * This file is provided AS IS with NO WARRANTY OF ANY KIND , INCLUDING THE
* * WARRANTY OF DESIGN , MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .
2009-10-20 14:03:00 +00:00
* *
2007-05-15 09:05:53 +00:00
* * Project : OpcUa Wireshark Plugin
* *
* * Description : Implementation of OpcUa built - in type parsers .
* * This contains all the simple types and some complex types .
* *
* * Author : Gerhard Gappmeier < gerhard . gappmeier @ ascolab . com >
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-09-20 01:29:52 +00:00
# include "config.h"
2007-05-15 09:05:53 +00:00
# include <epan/packet.h>
2014-10-16 17:25:08 +00:00
# include <epan/expert.h>
2007-05-15 09:05:53 +00:00
# include <epan/dissectors/packet-windows-common.h>
2018-07-12 16:35:08 +00:00
# include <epan/proto_data.h>
2007-05-15 09:05:53 +00:00
# include "opcua_simpletypes.h"
# include "opcua_hfindeces.h"
2014-06-10 11:36:06 +00:00
# include "opcua_statuscode.h"
2007-05-15 09:05:53 +00:00
# define DIAGNOSTICINFO_ENCODINGMASK_SYMBOLICID_FLAG 0x01
# define DIAGNOSTICINFO_ENCODINGMASK_NAMESPACE_FLAG 0x02
# define DIAGNOSTICINFO_ENCODINGMASK_LOCALIZEDTEXT_FLAG 0x04
2014-07-30 10:34:58 +00:00
# define DIAGNOSTICINFO_ENCODINGMASK_LOCALE_FLAG 0x08
# define DIAGNOSTICINFO_ENCODINGMASK_ADDITIONALINFO_FLAG 0x10
# define DIAGNOSTICINFO_ENCODINGMASK_INNERSTATUSCODE_FLAG 0x20
# define DIAGNOSTICINFO_ENCODINGMASK_INNERDIAGNOSTICINFO_FLAG 0x40
2007-05-15 09:05:53 +00:00
# define LOCALIZEDTEXT_ENCODINGBYTE_LOCALE 0x01
# define LOCALIZEDTEXT_ENCODINGBYTE_TEXT 0x02
2014-06-10 09:25:30 +00:00
# define NODEID_NAMESPACEURIFLAG 0x80
2009-04-06 18:30:04 +00:00
# define NODEID_SERVERINDEXFLAG 0x40
2007-05-15 09:05:53 +00:00
# define DATAVALUE_ENCODINGBYTE_VALUE 0x01
# define DATAVALUE_ENCODINGBYTE_STATUSCODE 0x02
# define DATAVALUE_ENCODINGBYTE_SOURCETIMESTAMP 0x04
# define DATAVALUE_ENCODINGBYTE_SERVERTIMESTAMP 0x08
2009-04-06 18:30:04 +00:00
# define DATAVALUE_ENCODINGBYTE_SOURCEPICOSECONDS 0x10
# define DATAVALUE_ENCODINGBYTE_SERVERPICOSECONDS 0x20
2007-05-15 09:05:53 +00:00
# define EXTOBJ_ENCODINGMASK_BINBODY_FLAG 0x01
# define EXTOBJ_ENCODINGMASK_XMLBODY_FLAG 0x02
2014-06-12 08:11:06 +00:00
# define STATUSCODE_STRUCTURECHANGED 0x8000
# define STATUSCODE_SEMANTICSCHANGED 0x4000
# define STATUSCODE_INFOTYPE_DATAVALUE 0x00000400
# define STATUSCODE_INFOBIT_OVERFLOW 0x0080
# define STATUSCODE_INFOBIT_HISTORIAN_PARTIAL 0x0004
# define STATUSCODE_INFOBIT_HISTORIAN_EXTRADATA 0x0008
# define STATUSCODE_INFOBIT_HISTORIAN_MULTIVALUE 0x0010
2015-12-07 16:59:35 +00:00
# define RETURNDIAGNOSTICS_SERVICELEVEL_SYMBOLICID 0x0001
# define RETURNDIAGNOSTICS_SERVICELEVEL_LOCALIZEDTEXT 0x0002
# define RETURNDIAGNOSTICS_SERVICELEVEL_ADDITIONALINFO 0x0004
# define RETURNDIAGNOSTICS_SERVICELEVEL_INNERSTATUSCODE 0x0008
# define RETURNDIAGNOSTICS_SERVICELEVEL_INNERDIAGNOSTICS 0x0010
# define RETURNDIAGNOSTICS_OPERATIONLEVEL_SYMBOLICID 0x0020
# define RETURNDIAGNOSTICS_OPERATIONLEVEL_LOCALIZEDTEXT 0x0040
# define RETURNDIAGNOSTICS_OPERATIONLEVEL_ADDITIONALINFO 0x0080
# define RETURNDIAGNOSTICS_OPERATIONLEVEL_INNERSTATUSCODE 0x0100
# define RETURNDIAGNOSTICS_OPERATIONLEVEL_INNERDIAGNOSTICS 0x0200
2017-05-01 21:36:21 +00:00
# define NODECLASSMASK_ALL 0x0000
# define NODECLASSMASK_OBJECT 0x0001
# define NODECLASSMASK_VARIABLE 0x0002
# define NODECLASSMASK_METHOD 0x0004
# define NODECLASSMASK_OBJECTTYPE 0x0008
# define NODECLASSMASK_VARIABLETYPE 0x0010
# define NODECLASSMASK_REFERENCETYPE 0x0020
# define NODECLASSMASK_DATATYPE 0x0040
# define NODECLASSMASK_VIEW 0x0080
# define RESULTMASK_REFERENCETYPE 0x0001
# define RESULTMASK_ISFORWARD 0x0002
# define RESULTMASK_NODECLASS 0x0004
# define RESULTMASK_BROWSENAME 0x0008
# define RESULTMASK_DISPLAYNAME 0x0010
# define RESULTMASK_TYPEDEFINITION 0x0020
# define RESULTMASK_ALL 0x003F
2007-05-15 09:05:53 +00:00
2009-09-09 00:18:15 +00:00
/* Chosen arbitrarily */
# define MAX_ARRAY_LEN 10000
2018-07-12 16:35:08 +00:00
# define MAX_NESTING_DEPTH 100
2009-09-09 00:18:15 +00:00
2014-10-16 12:59:53 +00:00
static int hf_opcua_diag_mask = - 1 ;
2007-05-15 09:05:53 +00:00
static int hf_opcua_diag_mask_symbolicflag = - 1 ;
static int hf_opcua_diag_mask_namespaceflag = - 1 ;
static int hf_opcua_diag_mask_localizedtextflag = - 1 ;
2014-07-30 10:34:58 +00:00
static int hf_opcua_diag_mask_localeflag = - 1 ;
2007-05-15 09:05:53 +00:00
static int hf_opcua_diag_mask_additionalinfoflag = - 1 ;
static int hf_opcua_diag_mask_innerstatuscodeflag = - 1 ;
static int hf_opcua_diag_mask_innerdiaginfoflag = - 1 ;
2014-10-16 12:59:53 +00:00
static int hf_opcua_loctext_mask = - 1 ;
2007-05-15 09:05:53 +00:00
static int hf_opcua_loctext_mask_localeflag = - 1 ;
static int hf_opcua_loctext_mask_textflag = - 1 ;
2014-10-16 12:59:53 +00:00
static int hf_opcua_datavalue_mask = - 1 ;
2007-05-15 09:05:53 +00:00
static int hf_opcua_datavalue_mask_valueflag = - 1 ;
static int hf_opcua_datavalue_mask_statuscodeflag = - 1 ;
static int hf_opcua_datavalue_mask_sourcetimestampflag = - 1 ;
static int hf_opcua_datavalue_mask_servertimestampflag = - 1 ;
2009-04-06 18:30:04 +00:00
static int hf_opcua_datavalue_mask_sourcepicoseconds = - 1 ;
static int hf_opcua_datavalue_mask_serverpicoseconds = - 1 ;
2007-05-15 09:05:53 +00:00
static int hf_opcua_nodeid_encodingmask = - 1 ;
2014-10-16 18:02:51 +00:00
static int hf_opcua_expandednodeid_mask = - 1 ;
2014-06-10 09:46:05 +00:00
static int hf_opcua_expandednodeid_mask_namespaceuri = - 1 ;
static int hf_opcua_expandednodeid_mask_serverindex = - 1 ;
2007-05-15 09:05:53 +00:00
static int hf_opcua_variant_encodingmask = - 1 ;
2014-06-10 09:25:30 +00:00
static int hf_opcua_nodeid_nsindex = - 1 ;
2007-05-15 09:05:53 +00:00
static int hf_opcua_nodeid_numeric = - 1 ;
2014-06-10 09:47:07 +00:00
static int hf_opcua_nodeid_string = - 1 ;
static int hf_opcua_nodeid_guid = - 1 ;
static int hf_opcua_nodeid_bytestring = - 1 ;
2009-04-06 18:30:04 +00:00
static int hf_opcua_localizedtext_locale = - 1 ;
static int hf_opcua_localizedtext_text = - 1 ;
static int hf_opcua_qualifiedname_id = - 1 ;
static int hf_opcua_qualifiedname_name = - 1 ;
2007-05-15 09:05:53 +00:00
static int hf_opcua_SourceTimestamp = - 1 ;
2009-04-06 18:30:04 +00:00
static int hf_opcua_SourcePicoseconds = - 1 ;
2007-05-15 09:05:53 +00:00
static int hf_opcua_ServerTimestamp = - 1 ;
2009-04-06 18:30:04 +00:00
static int hf_opcua_ServerPicoseconds = - 1 ;
2007-05-15 09:05:53 +00:00
static int hf_opcua_diag_symbolicid = - 1 ;
static int hf_opcua_diag_namespace = - 1 ;
static int hf_opcua_diag_localizedtext = - 1 ;
2014-07-30 10:34:58 +00:00
static int hf_opcua_diag_locale = - 1 ;
2007-05-15 09:05:53 +00:00
static int hf_opcua_diag_additionalinfo = - 1 ;
static int hf_opcua_diag_innerstatuscode = - 1 ;
2014-10-16 12:59:53 +00:00
static int hf_opcua_extobj_mask = - 1 ;
2007-05-15 09:05:53 +00:00
static int hf_opcua_extobj_mask_binbodyflag = - 1 ;
static int hf_opcua_extobj_mask_xmlbodyflag = - 1 ;
2009-04-06 18:30:04 +00:00
static int hf_opcua_ArraySize = - 1 ;
static int hf_opcua_ServerIndex = - 1 ;
2014-06-12 08:11:06 +00:00
static int hf_opcua_status_StructureChanged = - 1 ;
static int hf_opcua_status_SemanticsChanged = - 1 ;
static int hf_opcua_status_InfoBit_Limit_Overflow = - 1 ;
static int hf_opcua_status_InfoBit_Historian_Partial = - 1 ;
static int hf_opcua_status_InfoBit_Historian_ExtraData = - 1 ;
static int hf_opcua_status_InfoBit_Historian_MultiValue = - 1 ;
static int hf_opcua_status_InfoType = - 1 ;
static int hf_opcua_status_Limit = - 1 ;
static int hf_opcua_status_Historian = - 1 ;
2015-12-07 16:59:35 +00:00
int hf_opcua_returnDiag = - 1 ;
int hf_opcua_returnDiag_mask_sl_symbolicId = - 1 ;
int hf_opcua_returnDiag_mask_sl_localizedText = - 1 ;
int hf_opcua_returnDiag_mask_sl_additionalinfo = - 1 ;
int hf_opcua_returnDiag_mask_sl_innerstatuscode = - 1 ;
int hf_opcua_returnDiag_mask_sl_innerdiagnostics = - 1 ;
int hf_opcua_returnDiag_mask_ol_symbolicId = - 1 ;
int hf_opcua_returnDiag_mask_ol_localizedText = - 1 ;
int hf_opcua_returnDiag_mask_ol_additionalinfo = - 1 ;
int hf_opcua_returnDiag_mask_ol_innerstatuscode = - 1 ;
int hf_opcua_returnDiag_mask_ol_innerdiagnostics = - 1 ;
2017-05-01 21:36:21 +00:00
int hf_opcua_nodeClassMask = - 1 ;
int hf_opcua_nodeClassMask_all = - 1 ;
int hf_opcua_nodeClassMask_object = - 1 ;
int hf_opcua_nodeClassMask_variable = - 1 ;
int hf_opcua_nodeClassMask_method = - 1 ;
int hf_opcua_nodeClassMask_objecttype = - 1 ;
int hf_opcua_nodeClassMask_variabletype = - 1 ;
int hf_opcua_nodeClassMask_referencetype = - 1 ;
int hf_opcua_nodeClassMask_datatype = - 1 ;
int hf_opcua_nodeClassMask_view = - 1 ;
int hf_opcua_resultMask = - 1 ;
int hf_opcua_resultMask_all = - 1 ;
int hf_opcua_resultMask_referencetype = - 1 ;
int hf_opcua_resultMask_isforward = - 1 ;
int hf_opcua_resultMask_nodeclass = - 1 ;
int hf_opcua_resultMask_browsename = - 1 ;
int hf_opcua_resultMask_displayname = - 1 ;
int hf_opcua_resultMask_typedefinition = - 1 ;
2007-05-15 09:05:53 +00:00
2014-10-16 17:25:08 +00:00
static expert_field ei_array_length = EI_INIT ;
2018-07-12 16:35:08 +00:00
static expert_field ei_nesting_depth = EI_INIT ;
extern int proto_opcua ;
2014-10-16 17:25:08 +00:00
2007-05-15 09:05:53 +00:00
/** NodeId encoding mask table */
static const value_string g_nodeidmasks [ ] = {
2014-06-10 09:46:05 +00:00
{ 0x00 , " Two byte encoded Numeric " } ,
{ 0x01 , " Four byte encoded Numeric " } ,
{ 0x02 , " Numeric of arbitrary length " } ,
{ 0x03 , " String " } ,
{ 0x04 , " GUID " } ,
{ 0x05 , " Opaque " } ,
2007-05-15 09:05:53 +00:00
{ 0 , NULL }
} ;
2014-06-12 08:11:06 +00:00
/** StatusCode info types */
static const value_string g_infotype [ ] = {
{ 0x00 , " Not used " } ,
{ 0x01 , " DataValue " } ,
{ 0x02 , " Reserved " } ,
{ 0x03 , " Reserved " } ,
{ 0 , NULL }
} ;
/** StatusCode Limit types */
static const value_string g_limit [ ] = {
{ 0x00 , " None " } ,
{ 0x01 , " Low " } ,
{ 0x02 , " High " } ,
{ 0x03 , " Constant " } ,
{ 0 , NULL }
} ;
/** StatusCode Historian types */
static const value_string g_historian [ ] = {
{ 0x00 , " Raw " } ,
{ 0x01 , " Calculated " } ,
{ 0x02 , " Interpolated " } ,
{ 0x03 , " Reserved " } ,
{ 0 , NULL }
} ;
2007-05-15 09:05:53 +00:00
/** UA Variant Type enum */
typedef enum _OpcUa_BuiltInType
{
OpcUaType_Null = 0 ,
OpcUaType_Boolean = 1 ,
OpcUaType_SByte = 2 ,
OpcUaType_Byte = 3 ,
OpcUaType_Int16 = 4 ,
OpcUaType_UInt16 = 5 ,
OpcUaType_Int32 = 6 ,
OpcUaType_UInt32 = 7 ,
OpcUaType_Int64 = 8 ,
OpcUaType_UInt64 = 9 ,
OpcUaType_Float = 10 ,
OpcUaType_Double = 11 ,
OpcUaType_String = 12 ,
OpcUaType_DateTime = 13 ,
OpcUaType_Guid = 14 ,
OpcUaType_ByteString = 15 ,
OpcUaType_XmlElement = 16 ,
OpcUaType_NodeId = 17 ,
OpcUaType_ExpandedNodeId = 18 ,
OpcUaType_StatusCode = 19 ,
2009-04-06 18:30:04 +00:00
OpcUaType_QualifiedName = 20 ,
OpcUaType_LocalizedText = 21 ,
OpcUaType_ExtensionObject = 22 ,
OpcUaType_DataValue = 23 ,
OpcUaType_Variant = 24 ,
OpcUaType_DiagnosticInfo = 25
2007-05-15 09:05:53 +00:00
}
OpcUa_BuiltInType ;
/** Variant encoding mask table */
static const value_string g_VariantTypes [ ] = {
2014-10-06 01:34:19 +00:00
{ 0 , " Null " } ,
{ 1 , " Boolean " } ,
{ 2 , " SByte " } ,
{ 3 , " Byte " } ,
{ 4 , " Int16 " } ,
{ 5 , " UInt16 " } ,
{ 6 , " Int32 " } ,
{ 7 , " UInt32 " } ,
{ 8 , " Int64 " } ,
{ 9 , " UInt64 " } ,
2007-05-15 09:05:53 +00:00
{ 10 , " Float " } ,
{ 11 , " Double " } ,
{ 12 , " String " } ,
{ 13 , " DateTime " } ,
{ 14 , " Guid " } ,
{ 15 , " ByteString " } ,
{ 16 , " XmlElement " } ,
{ 17 , " NodeId " } ,
{ 18 , " ExpandedNodeId " } ,
{ 19 , " StatusCode " } ,
2010-12-02 20:44:18 +00:00
{ 20 , " QualifiedName " } ,
{ 21 , " LocalizedText " } ,
{ 22 , " ExtensionObject " } ,
{ 23 , " DataValue " } ,
{ 24 , " Variant " } ,
{ 25 , " DiagnosticInfo " } ,
2007-05-15 09:05:53 +00:00
{ 0x80 , " Array of Null " } ,
{ 0x80 + 1 , " Array of Boolean " } ,
{ 0x80 + 2 , " Array of SByte " } ,
{ 0x80 + 3 , " Array of Byte " } ,
{ 0x80 + 4 , " Array of Int16 " } ,
{ 0x80 + 5 , " Array of UInt16 " } ,
{ 0x80 + 6 , " Array of Int32 " } ,
{ 0x80 + 7 , " Array of UInt32 " } ,
{ 0x80 + 8 , " Array of Int64 " } ,
{ 0x80 + 9 , " Array of UInt64 " } ,
{ 0x80 + 10 , " Array of Float " } ,
{ 0x80 + 11 , " Array of Double " } ,
{ 0x80 + 12 , " Array of String " } ,
{ 0x80 + 13 , " Array of DateTime " } ,
{ 0x80 + 14 , " Array of Guid " } ,
{ 0x80 + 15 , " Array of ByteString " } ,
{ 0x80 + 16 , " Array of XmlElement " } ,
{ 0x80 + 17 , " Array of NodeId " } ,
{ 0x80 + 18 , " Array of ExpandedNodeId " } ,
{ 0x80 + 19 , " Array of StatusCode " } ,
2010-12-02 20:44:18 +00:00
{ 0x80 + 20 , " Array of QualifiedName " } ,
{ 0x80 + 21 , " Array of LocalizedText " } ,
{ 0x80 + 22 , " Array of ExtensionObject " } ,
{ 0x80 + 23 , " Array of DataValue " } ,
{ 0x80 + 24 , " Array of Variant " } ,
{ 0x80 + 25 , " Array of DiagnosticInfo " } ,
2013-02-15 15:24:39 +00:00
{ 0xC0 , " Matrix of Null " } ,
{ 0xC0 + 1 , " Matrix of Boolean " } ,
{ 0xC0 + 2 , " Matrix of SByte " } ,
{ 0xC0 + 3 , " Matrix of Byte " } ,
{ 0xC0 + 4 , " Matrix of Int16 " } ,
{ 0xC0 + 5 , " Matrix of UInt16 " } ,
{ 0xC0 + 6 , " Matrix of Int32 " } ,
{ 0xC0 + 7 , " Matrix of UInt32 " } ,
{ 0xC0 + 8 , " Matrix of Int64 " } ,
{ 0xC0 + 9 , " Matrix of UInt64 " } ,
{ 0xC0 + 10 , " Matrix of Float " } ,
{ 0xC0 + 11 , " Matrix of Double " } ,
{ 0xC0 + 12 , " Matrix of String " } ,
{ 0xC0 + 13 , " Matrix of DateTime " } ,
{ 0xC0 + 14 , " Matrix of Guid " } ,
{ 0xC0 + 15 , " Matrix of ByteString " } ,
{ 0xC0 + 16 , " Matrix of XmlElement " } ,
{ 0xC0 + 17 , " Matrix of NodeId " } ,
{ 0xC0 + 18 , " Matrix of ExpandedNodeId " } ,
{ 0xC0 + 19 , " Matrix of StatusCode " } ,
{ 0xC0 + 20 , " Matrix of QualifiedName " } ,
{ 0xC0 + 21 , " Matrix of LocalizedText " } ,
{ 0xC0 + 22 , " Matrix of ExtensionObject " } ,
{ 0xC0 + 23 , " Matrix of DataValue " } ,
{ 0xC0 + 24 , " Matrix of Variant " } ,
{ 0xC0 + 25 , " Matrix of DiagnosticInfo " } ,
2007-05-15 09:05:53 +00:00
{ 0 , NULL }
} ;
2009-04-06 18:30:04 +00:00
# define VARIANT_ARRAYDIMENSIONS 0x40
2007-05-15 09:05:53 +00:00
# define VARIANT_ARRAYMASK 0x80
2017-05-01 21:36:21 +00:00
/** BrowseRequest's BrowseDescription's NodeClassMaskTable enum table */
static const value_string g_NodeClassMask [ ] = {
{ NODECLASSMASK_ALL , " All " } ,
{ 0 , NULL }
} ;
/* BrowseRequest's BrowseDescription's ResultMaskTable enum table */
static const value_string g_ResultMask [ ] = {
{ RESULTMASK_ALL , " All " } ,
{ 0 , NULL }
} ;
2007-05-15 09:05:53 +00:00
/* trees */
static gint ett_opcua_diagnosticinfo = - 1 ;
2014-06-12 10:22:35 +00:00
static gint ett_opcua_diagnosticinfo_encodingmask = - 1 ;
2007-05-15 09:05:53 +00:00
static gint ett_opcua_nodeid = - 1 ;
2014-06-12 10:22:35 +00:00
static gint ett_opcua_expandednodeid = - 1 ;
2014-10-16 18:02:51 +00:00
static gint ett_opcua_expandednodeid_encodingmask = - 1 ;
2007-05-15 09:05:53 +00:00
static gint ett_opcua_localizedtext = - 1 ;
2014-06-12 10:22:35 +00:00
static gint ett_opcua_localizedtext_encodingmask = - 1 ;
2007-05-15 09:05:53 +00:00
static gint ett_opcua_qualifiedname = - 1 ;
static gint ett_opcua_datavalue = - 1 ;
2014-06-12 10:22:35 +00:00
static gint ett_opcua_datavalue_encodingmask = - 1 ;
2007-05-15 09:05:53 +00:00
static gint ett_opcua_variant = - 1 ;
2014-06-12 10:22:35 +00:00
static gint ett_opcua_variant_arraydims = - 1 ;
2007-05-15 09:05:53 +00:00
static gint ett_opcua_extensionobject = - 1 ;
2014-06-12 10:22:35 +00:00
static gint ett_opcua_extensionobject_encodingmask = - 1 ;
2014-06-12 08:11:06 +00:00
static gint ett_opcua_statuscode = - 1 ;
static gint ett_opcua_statuscode_info = - 1 ;
2014-06-12 15:36:32 +00:00
gint ett_opcua_array_Boolean = - 1 ;
gint ett_opcua_array_SByte = - 1 ;
gint ett_opcua_array_Byte = - 1 ;
gint ett_opcua_array_Int16 = - 1 ;
gint ett_opcua_array_UInt16 = - 1 ;
gint ett_opcua_array_Int32 = - 1 ;
gint ett_opcua_array_UInt32 = - 1 ;
gint ett_opcua_array_Int64 = - 1 ;
gint ett_opcua_array_UInt64 = - 1 ;
gint ett_opcua_array_Float = - 1 ;
gint ett_opcua_array_Double = - 1 ;
gint ett_opcua_array_String = - 1 ;
gint ett_opcua_array_DateTime = - 1 ;
gint ett_opcua_array_Guid = - 1 ;
gint ett_opcua_array_ByteString = - 1 ;
gint ett_opcua_array_XmlElement = - 1 ;
gint ett_opcua_array_NodeId = - 1 ;
gint ett_opcua_array_ExpandedNodeId = - 1 ;
gint ett_opcua_array_StatusCode = - 1 ;
gint ett_opcua_array_DiagnosticInfo = - 1 ;
gint ett_opcua_array_QualifiedName = - 1 ;
gint ett_opcua_array_LocalizedText = - 1 ;
gint ett_opcua_array_ExtensionObject = - 1 ;
gint ett_opcua_array_DataValue = - 1 ;
gint ett_opcua_array_Variant = - 1 ;
2015-12-07 16:59:35 +00:00
gint ett_opcua_returnDiagnostics = - 1 ;
2017-05-01 21:36:21 +00:00
gint ett_opcua_nodeClassMask = - 1 ;
gint ett_opcua_resultMask = - 1 ;
2007-05-15 09:05:53 +00:00
static gint * ett [ ] =
{
2014-10-06 01:34:19 +00:00
& ett_opcua_diagnosticinfo ,
& ett_opcua_diagnosticinfo_encodingmask ,
& ett_opcua_nodeid ,
& ett_opcua_expandednodeid ,
2014-10-16 18:02:51 +00:00
& ett_opcua_expandednodeid_encodingmask ,
2014-10-06 01:34:19 +00:00
& ett_opcua_localizedtext ,
& ett_opcua_localizedtext_encodingmask ,
& ett_opcua_qualifiedname ,
& ett_opcua_datavalue ,
& ett_opcua_datavalue_encodingmask ,
& ett_opcua_variant ,
& ett_opcua_variant_arraydims ,
& ett_opcua_extensionobject ,
& ett_opcua_extensionobject_encodingmask ,
& ett_opcua_statuscode ,
& ett_opcua_statuscode_info ,
& ett_opcua_array_Boolean ,
& ett_opcua_array_SByte ,
& ett_opcua_array_Byte ,
& ett_opcua_array_Int16 ,
& ett_opcua_array_UInt16 ,
& ett_opcua_array_Int32 ,
& ett_opcua_array_UInt32 ,
& ett_opcua_array_Int64 ,
& ett_opcua_array_UInt64 ,
& ett_opcua_array_Float ,
& ett_opcua_array_Double ,
& ett_opcua_array_String ,
& ett_opcua_array_DateTime ,
& ett_opcua_array_Guid ,
& ett_opcua_array_ByteString ,
& ett_opcua_array_XmlElement ,
& ett_opcua_array_NodeId ,
& ett_opcua_array_ExpandedNodeId ,
& ett_opcua_array_StatusCode ,
& ett_opcua_array_DiagnosticInfo ,
& ett_opcua_array_QualifiedName ,
& ett_opcua_array_LocalizedText ,
& ett_opcua_array_ExtensionObject ,
& ett_opcua_array_DataValue ,
2015-12-07 16:59:35 +00:00
& ett_opcua_array_Variant ,
2017-05-01 21:36:21 +00:00
& ett_opcua_returnDiagnostics ,
& ett_opcua_nodeClassMask ,
& ett_opcua_resultMask
2007-05-15 09:05:53 +00:00
} ;
void registerSimpleTypes ( int proto )
{
2014-10-16 17:25:08 +00:00
expert_module_t * expert_proto ;
2009-06-22 04:58:08 +00:00
static hf_register_info hf [ ] =
{
2015-12-07 16:59:35 +00:00
/* id full name abbreviation type display strings bitmask blurb HFILL */
{ & hf_opcua_diag_mask , { " EncodingMask " , " opcua.diag.mask " , FT_UINT8 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_diag_mask_symbolicflag , { " has symbolic id " , " opcua.diag.has_symbolic_id " , FT_BOOLEAN , 8 , NULL , DIAGNOSTICINFO_ENCODINGMASK_SYMBOLICID_FLAG , NULL , HFILL } } ,
{ & hf_opcua_diag_mask_namespaceflag , { " has namespace " , " opcua.diag.has_namespace " , FT_BOOLEAN , 8 , NULL , DIAGNOSTICINFO_ENCODINGMASK_NAMESPACE_FLAG , NULL , HFILL } } ,
{ & hf_opcua_diag_mask_localizedtextflag , { " has localizedtext " , " opcua.diag.has_localizedtext " , FT_BOOLEAN , 8 , NULL , DIAGNOSTICINFO_ENCODINGMASK_LOCALIZEDTEXT_FLAG , NULL , HFILL } } ,
{ & hf_opcua_diag_mask_localeflag , { " has locale " , " opcua.diag.has_locale " , FT_BOOLEAN , 8 , NULL , DIAGNOSTICINFO_ENCODINGMASK_LOCALE_FLAG , NULL , HFILL } } ,
{ & hf_opcua_diag_mask_additionalinfoflag , { " has additional info " , " opcua.diag.has_additional_info " , FT_BOOLEAN , 8 , NULL , DIAGNOSTICINFO_ENCODINGMASK_ADDITIONALINFO_FLAG , NULL , HFILL } } ,
{ & hf_opcua_diag_mask_innerstatuscodeflag , { " has inner statuscode " , " opcua.diag.has_inner_statuscode " , FT_BOOLEAN , 8 , NULL , DIAGNOSTICINFO_ENCODINGMASK_INNERSTATUSCODE_FLAG , NULL , HFILL } } ,
{ & hf_opcua_diag_mask_innerdiaginfoflag , { " has inner diagnostic info " , " opcua.diag.has_inner_diagnostic_code " , FT_BOOLEAN , 8 , NULL , DIAGNOSTICINFO_ENCODINGMASK_INNERDIAGNOSTICINFO_FLAG , NULL , HFILL } } ,
{ & hf_opcua_loctext_mask , { " EncodingMask " , " opcua.loctext.mask " , FT_UINT8 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_loctext_mask_localeflag , { " has locale information " , " opcua.loctext.has_locale_information " , FT_BOOLEAN , 8 , NULL , LOCALIZEDTEXT_ENCODINGBYTE_LOCALE , NULL , HFILL } } ,
{ & hf_opcua_loctext_mask_textflag , { " has text " , " opcua.loctext.has_text " , FT_BOOLEAN , 8 , NULL , LOCALIZEDTEXT_ENCODINGBYTE_TEXT , NULL , HFILL } } ,
{ & hf_opcua_nodeid_encodingmask , { " EncodingMask " , " opcua.nodeid.encodingmask " , FT_UINT8 , BASE_HEX , VALS ( g_nodeidmasks ) , 0x0F , NULL , HFILL } } ,
{ & hf_opcua_nodeid_nsindex , { " Namespace Index " , " opcua.nodeid.nsindex " , FT_UINT16 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_nodeid_numeric , { " Identifier Numeric " , " opcua.nodeid.numeric " , FT_UINT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_nodeid_string , { " Identifier String " , " opcua.nodeid.string " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_nodeid_guid , { " Identifier Guid " , " opcua.nodeid.guid " , FT_GUID , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_nodeid_bytestring , { " Identifier ByteString " , " opcua.nodeid.bytestring " , FT_BYTES , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_expandednodeid_mask , { " EncodingMask " , " opcua.expandednodeid.mask " , FT_UINT8 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_expandednodeid_mask_namespaceuri , { " has namespace uri " , " opcua.expandednodeid.has_namespace_uri " , FT_BOOLEAN , 8 , NULL , NODEID_NAMESPACEURIFLAG , NULL , HFILL } } ,
{ & hf_opcua_expandednodeid_mask_serverindex , { " has server index " , " opcua.expandednodeid.has_server_index " , FT_BOOLEAN , 8 , NULL , NODEID_SERVERINDEXFLAG , NULL , HFILL } } ,
{ & hf_opcua_localizedtext_locale , { " Locale " , " opcua.loctext.Locale " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_localizedtext_text , { " Text " , " opcua.loctext.Text " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_qualifiedname_id , { " Id " , " opcua.qualname.Id " , FT_UINT16 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_qualifiedname_name , { " Name " , " opcua.qualname.Name " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_datavalue_mask , { " EncodingMask " , " opcua.datavalue.mask " , FT_UINT8 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_datavalue_mask_valueflag , { " has value " , " opcua.datavalue.has_value " , FT_BOOLEAN , 8 , NULL , DATAVALUE_ENCODINGBYTE_VALUE , NULL , HFILL } } ,
{ & hf_opcua_datavalue_mask_statuscodeflag , { " has statuscode " , " opcua.datavalue.has_statuscode " , FT_BOOLEAN , 8 , NULL , DATAVALUE_ENCODINGBYTE_STATUSCODE , NULL , HFILL } } ,
{ & hf_opcua_datavalue_mask_sourcetimestampflag , { " has source timestamp " , " opcua.datavalue.has_source_timestamp " , FT_BOOLEAN , 8 , NULL , DATAVALUE_ENCODINGBYTE_SOURCETIMESTAMP , NULL , HFILL } } ,
{ & hf_opcua_datavalue_mask_servertimestampflag , { " has server timestamp " , " opcua.datavalue.has_server_timestamp " , FT_BOOLEAN , 8 , NULL , DATAVALUE_ENCODINGBYTE_SERVERTIMESTAMP , NULL , HFILL } } ,
{ & hf_opcua_datavalue_mask_sourcepicoseconds , { " has source picoseconds " , " opcua.datavalue.has_source_picoseconds " , FT_BOOLEAN , 8 , NULL , DATAVALUE_ENCODINGBYTE_SOURCEPICOSECONDS , NULL , HFILL } } ,
{ & hf_opcua_datavalue_mask_serverpicoseconds , { " has server picoseconds " , " opcua.datavalue.has_server_picoseconds " , FT_BOOLEAN , 8 , NULL , DATAVALUE_ENCODINGBYTE_SERVERPICOSECONDS , NULL , HFILL } } ,
{ & hf_opcua_variant_encodingmask , { " Variant Type " , " opcua.variant.has_value " , FT_UINT8 , BASE_HEX , VALS ( g_VariantTypes ) , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_SourceTimestamp , { " SourceTimestamp " , " opcua.datavalue.SourceTimestamp " , FT_ABSOLUTE_TIME , ABSOLUTE_TIME_LOCAL , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_SourcePicoseconds , { " SourcePicoseconds " , " opcua.datavalue.SourcePicoseconds " , FT_UINT16 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_ServerTimestamp , { " ServerTimestamp " , " opcua.datavalue.ServerTimestamp " , FT_ABSOLUTE_TIME , ABSOLUTE_TIME_LOCAL , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_ServerPicoseconds , { " ServerPicoseconds " , " opcua.datavalue.ServerPicoseconds " , FT_UINT16 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_diag_symbolicid , { " SymbolicId " , " opcua.diag.SymbolicId " , FT_INT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_diag_namespace , { " Namespace " , " opcua.diag.Namespace " , FT_INT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_diag_localizedtext , { " LocalizedText " , " opcua.diag.LocalizedText " , FT_INT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_diag_locale , { " Locale " , " opcua.diag.Locale " , FT_INT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_diag_additionalinfo , { " AdditionalInfo " , " opcua.diag.AdditionalInfo " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_diag_innerstatuscode , { " InnerStatusCode " , " opcua.diag.InnerStatusCode " , FT_UINT32 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_extobj_mask , { " EncodingMask " , " opcua.extobj.mask " , FT_UINT8 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_extobj_mask_binbodyflag , { " has binary body " , " opcua.extobj.has_binary_body " , FT_BOOLEAN , 8 , NULL , EXTOBJ_ENCODINGMASK_BINBODY_FLAG , NULL , HFILL } } ,
{ & hf_opcua_extobj_mask_xmlbodyflag , { " has xml body " , " opcua.extobj.has_xml_body " , FT_BOOLEAN , 8 , NULL , EXTOBJ_ENCODINGMASK_XMLBODY_FLAG , NULL , HFILL } } ,
{ & hf_opcua_ArraySize , { " ArraySize " , " opcua.variant.ArraySize " , FT_INT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_ServerIndex , { " ServerIndex " , " opcua.expandednodeid.ServerIndex " , FT_UINT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_status_StructureChanged , { " StructureChanged " , " opcua.statuscode.structureChanged " , FT_BOOLEAN , 16 , NULL , STATUSCODE_STRUCTURECHANGED , NULL , HFILL } } ,
{ & hf_opcua_status_SemanticsChanged , { " SemanticsChanged " , " opcua.statuscode.semanticsChanged " , FT_BOOLEAN , 16 , NULL , STATUSCODE_SEMANTICSCHANGED , NULL , HFILL } } ,
{ & hf_opcua_status_InfoBit_Limit_Overflow , { " Overflow " , " opcua.statuscode.overflow " , FT_BOOLEAN , 16 , NULL , STATUSCODE_INFOBIT_OVERFLOW , NULL , HFILL } } ,
{ & hf_opcua_status_InfoBit_Historian_Partial , { " HistorianBit: Partial " , " opcua.statuscode.historian.partial " , FT_BOOLEAN , 16 , NULL , STATUSCODE_INFOBIT_HISTORIAN_PARTIAL , NULL , HFILL } } ,
{ & hf_opcua_status_InfoBit_Historian_ExtraData , { " HistorianBit: ExtraData " , " opcua.statuscode.historian.extraData " , FT_BOOLEAN , 16 , NULL , STATUSCODE_INFOBIT_HISTORIAN_EXTRADATA , NULL , HFILL } } ,
{ & hf_opcua_status_InfoBit_Historian_MultiValue , { " HistorianBit: MultiValue " , " opcua.statuscode.historian.multiValue " , FT_BOOLEAN , 16 , NULL , STATUSCODE_INFOBIT_HISTORIAN_MULTIVALUE , NULL , HFILL } } ,
{ & hf_opcua_status_InfoType , { " InfoType " , " opcua.statuscode.infoType " , FT_UINT16 , BASE_HEX , VALS ( g_infotype ) , 0x0C00 , NULL , HFILL } } ,
{ & hf_opcua_status_Limit , { " Limit " , " opcua.statuscode.limit " , FT_UINT16 , BASE_HEX , VALS ( g_limit ) , 0x0300 , NULL , HFILL } } ,
{ & hf_opcua_status_Historian , { " Historian " , " opcua.statuscode.historian " , FT_UINT16 , BASE_HEX , VALS ( g_historian ) , 0x0003 , NULL , HFILL } } ,
{ & hf_opcua_returnDiag , { " Return Diagnostics " , " opcua.returndiag " , FT_UINT32 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_returnDiag_mask_sl_symbolicId , { " ServiceLevel / SymbolicId " , " opcua.returndiag.servicelevel.symbolicid " , FT_BOOLEAN , 16 , NULL , RETURNDIAGNOSTICS_SERVICELEVEL_SYMBOLICID , NULL , HFILL } } ,
{ & hf_opcua_returnDiag_mask_sl_localizedText , { " ServiceLevel / LocalizedText " , " opcua.returndiag.servicelevel.localizedtext " , FT_BOOLEAN , 16 , NULL , RETURNDIAGNOSTICS_SERVICELEVEL_LOCALIZEDTEXT , NULL , HFILL } } ,
{ & hf_opcua_returnDiag_mask_sl_additionalinfo , { " ServiceLevel / AdditionalInfo " , " opcua.returndiag.servicelevel.additionalinfo " , FT_BOOLEAN , 16 , NULL , RETURNDIAGNOSTICS_SERVICELEVEL_ADDITIONALINFO , NULL , HFILL } } ,
{ & hf_opcua_returnDiag_mask_sl_innerstatuscode , { " ServiceLevel / Inner StatusCode " , " opcua.returndiag.servicelevel.innerstatuscode " , FT_BOOLEAN , 16 , NULL , RETURNDIAGNOSTICS_SERVICELEVEL_INNERSTATUSCODE , NULL , HFILL } } ,
{ & hf_opcua_returnDiag_mask_sl_innerdiagnostics , { " ServiceLevel / Inner Diagnostics " , " opcua.returndiag.servicelevel.innerdiagnostics " , FT_BOOLEAN , 16 , NULL , RETURNDIAGNOSTICS_SERVICELEVEL_INNERDIAGNOSTICS , NULL , HFILL } } ,
{ & hf_opcua_returnDiag_mask_ol_symbolicId , { " OperationLevel / SymbolicId " , " opcua.returndiag.operationlevel.symbolicid " , FT_BOOLEAN , 16 , NULL , RETURNDIAGNOSTICS_OPERATIONLEVEL_SYMBOLICID , NULL , HFILL } } ,
{ & hf_opcua_returnDiag_mask_ol_localizedText , { " OperationLevel / LocalizedText " , " opcua.returndiag.operationlevel.localizedtext " , FT_BOOLEAN , 16 , NULL , RETURNDIAGNOSTICS_OPERATIONLEVEL_LOCALIZEDTEXT , NULL , HFILL } } ,
{ & hf_opcua_returnDiag_mask_ol_additionalinfo , { " OperationLevel / AdditionalInfo " , " opcua.returndiag.operationlevel.additionalinfo " , FT_BOOLEAN , 16 , NULL , RETURNDIAGNOSTICS_OPERATIONLEVEL_ADDITIONALINFO , NULL , HFILL } } ,
{ & hf_opcua_returnDiag_mask_ol_innerstatuscode , { " OperationLevel / Inner StatusCode " , " opcua.returndiag.operationlevel.innerstatuscode " , FT_BOOLEAN , 16 , NULL , RETURNDIAGNOSTICS_OPERATIONLEVEL_INNERSTATUSCODE , NULL , HFILL } } ,
{ & hf_opcua_returnDiag_mask_ol_innerdiagnostics , { " OperationLevel / Inner Diagnostics " , " opcua.returndiag.operationlevel.innerdiagnostics " , FT_BOOLEAN , 16 , NULL , RETURNDIAGNOSTICS_OPERATIONLEVEL_INNERDIAGNOSTICS , NULL , HFILL } } ,
2017-05-01 21:36:21 +00:00
{ & hf_opcua_nodeClassMask , { " Node Class Mask " , " opcua.nodeclassmask " , FT_UINT32 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_nodeClassMask_all , { " Node Class Mask " , " opcua.nodeclassmask.all " , FT_UINT32 , BASE_HEX , VALS ( g_NodeClassMask ) , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_nodeClassMask_object , { " Object " , " opcua.nodeclassmask.object " , FT_BOOLEAN , 16 , NULL , NODECLASSMASK_OBJECT , NULL , HFILL } } ,
{ & hf_opcua_nodeClassMask_variable , { " Variable " , " opcua.nodeclassmask.variable " , FT_BOOLEAN , 16 , NULL , NODECLASSMASK_VARIABLE , NULL , HFILL } } ,
{ & hf_opcua_nodeClassMask_method , { " Method " , " opcua.nodeclassmask.method " , FT_BOOLEAN , 16 , NULL , NODECLASSMASK_METHOD , NULL , HFILL } } ,
{ & hf_opcua_nodeClassMask_objecttype , { " ObjectType " , " opcua.nodeclassmask.objecttype " , FT_BOOLEAN , 16 , NULL , NODECLASSMASK_OBJECTTYPE , NULL , HFILL } } ,
{ & hf_opcua_nodeClassMask_variabletype , { " VariableType " , " opcua.nodeclassmask.variabletype " , FT_BOOLEAN , 16 , NULL , NODECLASSMASK_VARIABLETYPE , NULL , HFILL } } ,
{ & hf_opcua_nodeClassMask_referencetype , { " ReferenceType " , " opcua.nodeclassmask.referencetype " , FT_BOOLEAN , 16 , NULL , NODECLASSMASK_REFERENCETYPE , NULL , HFILL } } ,
{ & hf_opcua_nodeClassMask_datatype , { " DataType " , " opcua.nodeclassmask.datatype " , FT_BOOLEAN , 16 , NULL , NODECLASSMASK_DATATYPE , NULL , HFILL } } ,
{ & hf_opcua_nodeClassMask_view , { " View " , " opcua.nodeclassmask.view " , FT_BOOLEAN , 16 , NULL , NODECLASSMASK_VIEW , NULL , HFILL } } ,
{ & hf_opcua_resultMask , { " Result Mask " , " opcua.resultmask " , FT_UINT32 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_opcua_resultMask_referencetype , { " Reference Type " , " opcua.resultmask.referencetype " , FT_BOOLEAN , 16 , NULL , RESULTMASK_REFERENCETYPE , NULL , HFILL } } ,
{ & hf_opcua_resultMask_isforward , { " Is Forward " , " opcua.resultmask.isforward " , FT_BOOLEAN , 16 , NULL , RESULTMASK_ISFORWARD , NULL , HFILL } } ,
{ & hf_opcua_resultMask_nodeclass , { " Node Class " , " opcua.resultmask.nodeclass " , FT_BOOLEAN , 16 , NULL , RESULTMASK_NODECLASS , NULL , HFILL } } ,
{ & hf_opcua_resultMask_browsename , { " Browse Name " , " opcua.resultmask.browsename " , FT_BOOLEAN , 16 , NULL , RESULTMASK_BROWSENAME , NULL , HFILL } } ,
{ & hf_opcua_resultMask_displayname , { " Display Name " , " opcua.resultmask.displayname " , FT_BOOLEAN , 16 , NULL , RESULTMASK_DISPLAYNAME , NULL , HFILL } } ,
2020-09-02 08:59:15 +00:00
{ & hf_opcua_resultMask_typedefinition , { " Type Definition " , " opcua.resultmask.typedefinition " , FT_BOOLEAN , 16 , NULL , RESULTMASK_TYPEDEFINITION , NULL , HFILL } } ,
2017-05-01 21:36:21 +00:00
{ & hf_opcua_resultMask_all , { " Result Mask " , " opcua.resultmask.all " , FT_UINT32 , BASE_HEX , VALS ( g_ResultMask ) , 0x0 , NULL , HFILL } } ,
} ;
2009-06-22 04:58:08 +00:00
2014-10-16 17:25:08 +00:00
static ei_register_info ei [ ] = {
{ & ei_array_length , { " opcua.array.length " , PI_UNDECODED , PI_ERROR , " Max array length exceeded " , EXPFILL } } ,
2018-07-12 16:35:08 +00:00
{ & ei_nesting_depth , { " opcua.nestingdepth " , PI_UNDECODED , PI_ERROR , " Max nesting depth exceeded " , EXPFILL } } ,
2014-10-16 17:25:08 +00:00
} ;
2007-05-15 09:05:53 +00:00
proto_register_field_array ( proto , hf , array_length ( hf ) ) ;
proto_register_subtree_array ( ett , array_length ( ett ) ) ;
2014-10-16 17:25:08 +00:00
expert_proto = expert_register_protocol ( proto ) ;
expert_register_field_array ( expert_proto , ei , array_length ( ei ) ) ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
proto_item * parseBoolean ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo _U_ , gint * pOffset , int hfIndex )
2007-05-15 09:05:53 +00:00
{
2014-06-12 14:54:25 +00:00
proto_item * item = proto_tree_add_item ( tree , hfIndex , tvb , * pOffset , 1 , ENC_LITTLE_ENDIAN ) ;
* pOffset + = 1 ;
return item ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
proto_item * parseByte ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo _U_ , gint * pOffset , int hfIndex )
2007-05-15 09:05:53 +00:00
{
2014-06-12 14:54:25 +00:00
proto_item * item = proto_tree_add_item ( tree , hfIndex , tvb , * pOffset , 1 , ENC_LITTLE_ENDIAN ) ;
* pOffset + = 1 ;
return item ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
proto_item * parseSByte ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo _U_ , gint * pOffset , int hfIndex )
2007-05-15 09:05:53 +00:00
{
2014-06-12 14:54:25 +00:00
proto_item * item = proto_tree_add_item ( tree , hfIndex , tvb , * pOffset , 1 , ENC_LITTLE_ENDIAN ) ;
* pOffset + = 1 ;
return item ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
proto_item * parseUInt16 ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo _U_ , gint * pOffset , int hfIndex )
2007-05-15 09:05:53 +00:00
{
2014-06-12 14:54:25 +00:00
proto_item * item = proto_tree_add_item ( tree , hfIndex , tvb , * pOffset , 2 , ENC_LITTLE_ENDIAN ) ;
* pOffset + = 2 ;
return item ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
proto_item * parseInt16 ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo _U_ , gint * pOffset , int hfIndex )
2007-05-15 09:05:53 +00:00
{
2014-06-12 14:54:25 +00:00
proto_item * item = proto_tree_add_item ( tree , hfIndex , tvb , * pOffset , 2 , ENC_LITTLE_ENDIAN ) ;
* pOffset + = 2 ;
return item ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
proto_item * parseUInt32 ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo _U_ , gint * pOffset , int hfIndex )
2007-05-15 09:05:53 +00:00
{
2014-06-12 14:54:25 +00:00
proto_item * item = proto_tree_add_item ( tree , hfIndex , tvb , * pOffset , 4 , ENC_LITTLE_ENDIAN ) ;
* pOffset + = 4 ;
return item ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
proto_item * parseInt32 ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo _U_ , gint * pOffset , int hfIndex )
2007-05-15 09:05:53 +00:00
{
2014-06-12 14:54:25 +00:00
proto_item * item = proto_tree_add_item ( tree , hfIndex , tvb , * pOffset , 4 , ENC_LITTLE_ENDIAN ) ;
* pOffset + = 4 ;
return item ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
proto_item * parseUInt64 ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo _U_ , gint * pOffset , int hfIndex )
2007-05-15 09:05:53 +00:00
{
2014-06-12 14:54:25 +00:00
proto_item * item = proto_tree_add_item ( tree , hfIndex , tvb , * pOffset , 8 , ENC_LITTLE_ENDIAN ) ;
* pOffset + = 8 ;
return item ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
proto_item * parseInt64 ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo _U_ , gint * pOffset , int hfIndex )
2007-05-15 09:05:53 +00:00
{
2014-06-12 14:54:25 +00:00
proto_item * item = proto_tree_add_item ( tree , hfIndex , tvb , * pOffset , 8 , ENC_LITTLE_ENDIAN ) ;
* pOffset + = 8 ;
return item ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
proto_item * parseString ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo _U_ , gint * pOffset , int hfIndex )
2007-05-15 09:05:53 +00:00
{
2014-06-12 14:54:25 +00:00
proto_item * item = NULL ;
2009-09-09 00:18:15 +00:00
char * szValue ;
2007-05-15 09:05:53 +00:00
gint iOffset = * pOffset ;
gint32 iLen = tvb_get_letohl ( tvb , * pOffset ) ;
iOffset + = 4 ;
2009-09-09 00:18:15 +00:00
if ( iLen = = - 1 )
2007-05-15 09:05:53 +00:00
{
2014-06-12 14:54:25 +00:00
item = proto_tree_add_item ( tree , hfIndex , tvb , * pOffset , 0 , ENC_NA ) ;
2010-11-16 16:45:22 +00:00
proto_item_append_text ( item , " [OpcUa Null String] " ) ;
2013-02-15 15:24:39 +00:00
proto_item_set_end ( item , tvb , * pOffset + 4 ) ;
2009-09-09 00:18:15 +00:00
}
2010-11-16 16:45:22 +00:00
else if ( iLen = = 0 )
2009-09-09 00:18:15 +00:00
{
2014-06-12 14:54:25 +00:00
item = proto_tree_add_item ( tree , hfIndex , tvb , * pOffset , 0 , ENC_NA ) ;
2010-11-16 16:45:22 +00:00
proto_item_append_text ( item , " [OpcUa Empty String] " ) ;
2013-02-15 15:24:39 +00:00
proto_item_set_end ( item , tvb , * pOffset + 4 ) ;
2010-11-16 16:45:22 +00:00
}
else if ( iLen > 0 )
{
2014-06-12 14:54:25 +00:00
item = proto_tree_add_item ( tree , hfIndex , tvb , iOffset , iLen , ENC_UTF_8 | ENC_NA ) ;
2009-09-09 00:18:15 +00:00
iOffset + = iLen ; /* eat the whole string */
}
else
{
2014-06-12 14:54:25 +00:00
item = proto_tree_add_item ( tree , hfIndex , tvb , * pOffset , 0 , ENC_NA ) ;
2013-09-17 21:34:05 +00:00
szValue = wmem_strdup_printf ( wmem_packet_scope ( ) , " [Invalid String] Invalid length: %d " , iLen ) ;
2010-11-16 16:45:22 +00:00
proto_item_append_text ( item , " %s " , szValue ) ;
2013-02-15 15:24:39 +00:00
proto_item_set_end ( item , tvb , * pOffset + 4 ) ;
2007-05-15 09:05:53 +00:00
}
2009-09-09 00:18:15 +00:00
* pOffset = iOffset ;
2014-06-12 14:54:25 +00:00
return item ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
proto_item * parseStatusCode ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo _U_ , gint * pOffset , int hfIndex )
2007-05-15 09:05:53 +00:00
{
2014-06-10 11:36:06 +00:00
proto_item * item = NULL ;
guint32 uStatusCode = 0 ;
const gchar * szStatusCode = NULL ;
item = proto_tree_add_item ( tree , hfIndex , tvb , * pOffset , 4 , ENC_LITTLE_ENDIAN ) ;
uStatusCode = tvb_get_letohl ( tvb , * pOffset ) ;
szStatusCode = val_to_str_const ( uStatusCode & 0xFFFF0000 , g_statusCodes , " Unknown Status Code " ) ;
proto_item_append_text ( item , " [%s] " , szStatusCode ) ;
2014-06-12 08:11:06 +00:00
/* check for status code info flags */
if ( uStatusCode & 0x0000FFFF )
{
gint iOffset = * pOffset ;
proto_tree * flags_tree ;
proto_item * ti_inner ;
flags_tree = proto_item_add_subtree ( item , ett_opcua_statuscode ) ;
proto_tree_add_item ( flags_tree , hf_opcua_status_StructureChanged , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flags_tree , hf_opcua_status_SemanticsChanged , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
ti_inner = proto_tree_add_item ( flags_tree , hf_opcua_status_InfoType , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
switch ( uStatusCode & 0x00000C00 )
{
case STATUSCODE_INFOTYPE_DATAVALUE :
{
/* InfoType == DataValue */
proto_tree * tree_inner ;
tree_inner = proto_item_add_subtree ( ti_inner , ett_opcua_statuscode_info ) ;
proto_tree_add_item ( tree_inner , hf_opcua_status_Limit , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree_inner , hf_opcua_status_InfoBit_Limit_Overflow , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree_inner , hf_opcua_status_InfoBit_Historian_MultiValue , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree_inner , hf_opcua_status_InfoBit_Historian_ExtraData , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree_inner , hf_opcua_status_InfoBit_Historian_Partial , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree_inner , hf_opcua_status_Historian , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
}
default :
break ;
}
}
2007-05-15 09:05:53 +00:00
* pOffset + = 4 ;
2014-06-12 14:54:25 +00:00
return item ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
void parseLocalizedText ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo , gint * pOffset , const char * szFieldName )
2007-05-15 09:05:53 +00:00
{
2020-06-19 01:14:46 +00:00
static int * const loctext_mask [ ] = { & hf_opcua_loctext_mask_localeflag ,
2014-10-16 12:59:53 +00:00
& hf_opcua_loctext_mask_textflag ,
NULL } ;
2007-05-15 09:05:53 +00:00
gint iOffset = * pOffset ;
guint8 EncodingMask ;
proto_tree * subtree ;
proto_item * ti ;
2014-07-10 01:21:32 +00:00
subtree = proto_tree_add_subtree_format ( tree , tvb , * pOffset , - 1 , ett_opcua_localizedtext , & ti , " %s: LocalizedText " , szFieldName ) ;
2007-05-15 09:05:53 +00:00
/* parse encoding mask */
EncodingMask = tvb_get_guint8 ( tvb , iOffset ) ;
2014-10-16 12:59:53 +00:00
proto_tree_add_bitmask ( subtree , tvb , iOffset , hf_opcua_loctext_mask , ett_opcua_localizedtext_encodingmask , loctext_mask , ENC_LITTLE_ENDIAN ) ;
2007-05-15 09:05:53 +00:00
iOffset + + ;
if ( EncodingMask & LOCALIZEDTEXT_ENCODINGBYTE_LOCALE )
{
2014-10-16 17:06:31 +00:00
parseString ( subtree , tvb , pinfo , & iOffset , hf_opcua_localizedtext_locale ) ;
2007-05-15 09:05:53 +00:00
}
if ( EncodingMask & LOCALIZEDTEXT_ENCODINGBYTE_TEXT )
{
2014-10-16 17:06:31 +00:00
parseString ( subtree , tvb , pinfo , & iOffset , hf_opcua_localizedtext_text ) ;
2007-05-15 09:05:53 +00:00
}
2013-02-15 15:24:39 +00:00
proto_item_set_end ( ti , tvb , iOffset ) ;
2007-05-15 09:05:53 +00:00
* pOffset = iOffset ;
}
2014-10-16 17:06:31 +00:00
proto_item * parseGuid ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo _U_ , gint * pOffset , int hfIndex )
2007-05-15 09:05:53 +00:00
{
2019-10-16 12:42:02 +00:00
proto_item * item = proto_tree_add_item ( tree , hfIndex , tvb , * pOffset , GUID_LEN , ENC_LITTLE_ENDIAN ) ;
2014-06-12 14:54:25 +00:00
* pOffset + = GUID_LEN ;
return item ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
proto_item * parseByteString ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo _U_ , gint * pOffset , int hfIndex )
2007-05-15 09:05:53 +00:00
{
2014-06-12 14:54:25 +00:00
proto_item * item = NULL ;
2010-11-16 16:45:22 +00:00
char * szValue ;
2007-05-15 09:05:53 +00:00
int iOffset = * pOffset ;
gint32 iLen = tvb_get_letohl ( tvb , iOffset ) ;
iOffset + = 4 ;
if ( iLen = = - 1 )
{
2014-06-12 14:54:25 +00:00
item = proto_tree_add_item ( tree , hfIndex , tvb , * pOffset , 0 , ENC_NA ) ;
2010-11-16 16:45:22 +00:00
proto_item_append_text ( item , " [OpcUa Null ByteString] " ) ;
2013-02-15 15:24:39 +00:00
proto_item_set_end ( item , tvb , * pOffset + 4 ) ;
2010-11-16 16:45:22 +00:00
}
else if ( iLen = = 0 )
{
2014-06-12 14:54:25 +00:00
item = proto_tree_add_item ( tree , hfIndex , tvb , * pOffset , 0 , ENC_NA ) ;
2010-11-16 16:45:22 +00:00
proto_item_append_text ( item , " [OpcUa Empty ByteString] " ) ;
2013-02-15 15:24:39 +00:00
proto_item_set_end ( item , tvb , * pOffset + 4 ) ;
2007-05-15 09:05:53 +00:00
}
2010-11-16 16:45:22 +00:00
else if ( iLen > 0 )
2007-05-15 09:05:53 +00:00
{
2014-06-12 14:54:25 +00:00
item = proto_tree_add_item ( tree , hfIndex , tvb , iOffset , iLen , ENC_NA ) ;
2010-11-16 16:45:22 +00:00
iOffset + = iLen ; /* eat the whole bytestring */
2007-05-15 09:05:53 +00:00
}
2010-11-16 16:45:22 +00:00
else
{
2014-06-12 14:54:25 +00:00
item = proto_tree_add_item ( tree , hfIndex , tvb , * pOffset , 0 , ENC_NA ) ;
2013-09-17 21:34:05 +00:00
szValue = wmem_strdup_printf ( wmem_packet_scope ( ) , " [Invalid ByteString] Invalid length: %d " , iLen ) ;
2010-11-16 16:45:22 +00:00
proto_item_append_text ( item , " %s " , szValue ) ;
2013-02-15 15:24:39 +00:00
proto_item_set_end ( item , tvb , * pOffset + 4 ) ;
2010-11-16 16:45:22 +00:00
}
2007-05-15 09:05:53 +00:00
* pOffset = iOffset ;
2014-06-12 14:54:25 +00:00
return item ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
proto_item * parseXmlElement ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo , gint * pOffset , int hfIndex )
2007-05-15 09:05:53 +00:00
{
2014-10-16 17:06:31 +00:00
return parseByteString ( tree , tvb , pinfo , pOffset , hfIndex ) ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
proto_item * parseFloat ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo _U_ , gint * pOffset , int hfIndex )
2007-05-15 09:05:53 +00:00
{
2014-06-12 14:54:25 +00:00
proto_item * item = proto_tree_add_item ( tree , hfIndex , tvb , * pOffset , ( int ) sizeof ( gfloat ) , ENC_LITTLE_ENDIAN ) ;
* pOffset + = ( int ) sizeof ( gfloat ) ;
return item ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
proto_item * parseDouble ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo _U_ , gint * pOffset , int hfIndex )
2007-05-15 09:05:53 +00:00
{
2014-06-12 14:54:25 +00:00
proto_item * item = proto_tree_add_item ( tree , hfIndex , tvb , * pOffset , ( int ) sizeof ( gdouble ) , ENC_LITTLE_ENDIAN ) ;
* pOffset + = ( int ) sizeof ( gdouble ) ;
return item ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
proto_item * parseDateTime ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo _U_ , gint * pOffset , int hfIndex )
2007-05-15 09:05:53 +00:00
{
2014-06-12 14:54:25 +00:00
proto_item * item = NULL ;
2014-10-11 00:30:59 +00:00
* pOffset = dissect_nt_64bit_time_ex ( tvb , tree , * pOffset , hfIndex , & item , FALSE ) ;
2014-06-12 14:54:25 +00:00
return item ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
void parseDiagnosticInfo ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo , gint * pOffset , const char * szFieldName )
2007-05-15 09:05:53 +00:00
{
2020-06-19 01:14:46 +00:00
static int * const diag_mask [ ] = { & hf_opcua_diag_mask_symbolicflag ,
2014-10-16 12:59:53 +00:00
& hf_opcua_diag_mask_namespaceflag ,
& hf_opcua_diag_mask_localizedtextflag ,
& hf_opcua_diag_mask_localeflag ,
& hf_opcua_diag_mask_additionalinfoflag ,
& hf_opcua_diag_mask_innerstatuscodeflag ,
& hf_opcua_diag_mask_innerdiaginfoflag ,
NULL } ;
2007-05-15 09:05:53 +00:00
gint iOffset = * pOffset ;
guint8 EncodingMask ;
proto_tree * subtree ;
proto_item * ti ;
2018-07-12 16:35:08 +00:00
guint opcua_nested_count ;
2007-05-15 09:05:53 +00:00
2014-07-10 01:21:32 +00:00
subtree = proto_tree_add_subtree_format ( tree , tvb , * pOffset , - 1 , ett_opcua_diagnosticinfo , & ti , " %s: DiagnosticInfo " , szFieldName ) ;
2007-05-15 09:05:53 +00:00
2018-07-12 16:35:08 +00:00
/* prevent a too high nesting depth */
opcua_nested_count = GPOINTER_TO_UINT ( p_get_proto_data ( pinfo - > pool , pinfo , proto_opcua , 0 ) ) ;
2018-10-20 18:30:27 +00:00
if ( opcua_nested_count > = MAX_NESTING_DEPTH )
2018-07-12 16:35:08 +00:00
{
expert_add_info ( pinfo , ti , & ei_nesting_depth ) ;
return ;
}
2018-10-20 18:30:27 +00:00
opcua_nested_count + + ;
2018-07-12 16:35:08 +00:00
p_add_proto_data ( pinfo - > pool , pinfo , proto_opcua , 0 , GUINT_TO_POINTER ( opcua_nested_count ) ) ;
2007-05-15 09:05:53 +00:00
/* parse encoding mask */
EncodingMask = tvb_get_guint8 ( tvb , iOffset ) ;
2014-10-16 12:59:53 +00:00
proto_tree_add_bitmask ( subtree , tvb , iOffset , hf_opcua_diag_mask , ett_opcua_diagnosticinfo_encodingmask , diag_mask , ENC_LITTLE_ENDIAN ) ;
2007-05-15 09:05:53 +00:00
iOffset + + ;
if ( EncodingMask & DIAGNOSTICINFO_ENCODINGMASK_SYMBOLICID_FLAG )
{
2014-10-16 17:06:31 +00:00
parseInt32 ( subtree , tvb , pinfo , & iOffset , hf_opcua_diag_symbolicid ) ;
2007-05-15 09:05:53 +00:00
}
if ( EncodingMask & DIAGNOSTICINFO_ENCODINGMASK_NAMESPACE_FLAG )
{
2014-10-16 17:06:31 +00:00
parseInt32 ( subtree , tvb , pinfo , & iOffset , hf_opcua_diag_namespace ) ;
2007-05-15 09:05:53 +00:00
}
if ( EncodingMask & DIAGNOSTICINFO_ENCODINGMASK_LOCALIZEDTEXT_FLAG )
{
2014-10-16 17:06:31 +00:00
parseInt32 ( subtree , tvb , pinfo , & iOffset , hf_opcua_diag_localizedtext ) ;
2007-05-15 09:05:53 +00:00
}
2014-07-30 10:34:58 +00:00
if ( EncodingMask & DIAGNOSTICINFO_ENCODINGMASK_LOCALE_FLAG )
{
2014-10-16 17:06:31 +00:00
parseInt32 ( subtree , tvb , pinfo , & iOffset , hf_opcua_diag_locale ) ;
2014-07-30 10:34:58 +00:00
}
2007-05-15 09:05:53 +00:00
if ( EncodingMask & DIAGNOSTICINFO_ENCODINGMASK_ADDITIONALINFO_FLAG )
{
2014-10-16 17:06:31 +00:00
parseString ( subtree , tvb , pinfo , & iOffset , hf_opcua_diag_additionalinfo ) ;
2007-05-15 09:05:53 +00:00
}
if ( EncodingMask & DIAGNOSTICINFO_ENCODINGMASK_INNERSTATUSCODE_FLAG )
{
2014-10-16 17:06:31 +00:00
parseStatusCode ( subtree , tvb , pinfo , & iOffset , hf_opcua_diag_innerstatuscode ) ;
2007-05-15 09:05:53 +00:00
}
if ( EncodingMask & DIAGNOSTICINFO_ENCODINGMASK_INNERDIAGNOSTICINFO_FLAG )
{
2014-10-16 17:06:31 +00:00
parseDiagnosticInfo ( subtree , tvb , pinfo , & iOffset , " Inner DiagnosticInfo " ) ;
2007-05-15 09:05:53 +00:00
}
2013-02-15 15:24:39 +00:00
proto_item_set_end ( ti , tvb , iOffset ) ;
2007-05-15 09:05:53 +00:00
* pOffset = iOffset ;
2018-10-20 18:30:27 +00:00
opcua_nested_count - - ;
p_add_proto_data ( pinfo - > pool , pinfo , proto_opcua , 0 , GUINT_TO_POINTER ( opcua_nested_count ) ) ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
void parseQualifiedName ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo , gint * pOffset , const char * szFieldName )
2007-05-15 09:05:53 +00:00
{
2014-07-10 01:21:32 +00:00
proto_item * ti ;
proto_tree * subtree = proto_tree_add_subtree_format ( tree , tvb , * pOffset , - 1 ,
ett_opcua_qualifiedname , & ti , " %s: QualifiedName " , szFieldName ) ;
2007-05-15 09:05:53 +00:00
2014-10-16 17:06:31 +00:00
parseUInt16 ( subtree , tvb , pinfo , pOffset , hf_opcua_qualifiedname_id ) ;
parseString ( subtree , tvb , pinfo , pOffset , hf_opcua_qualifiedname_name ) ;
2013-02-15 15:24:39 +00:00
proto_item_set_end ( ti , tvb , * pOffset ) ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
void parseDataValue ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo , gint * pOffset , const char * szFieldName )
2007-05-15 09:05:53 +00:00
{
2020-06-19 01:14:46 +00:00
static int * const datavalue_mask [ ] = { & hf_opcua_datavalue_mask_valueflag ,
2014-10-16 12:59:53 +00:00
& hf_opcua_datavalue_mask_statuscodeflag ,
& hf_opcua_datavalue_mask_sourcetimestampflag ,
& hf_opcua_datavalue_mask_servertimestampflag ,
& hf_opcua_datavalue_mask_sourcepicoseconds ,
& hf_opcua_datavalue_mask_serverpicoseconds ,
NULL } ;
2014-07-10 01:21:32 +00:00
proto_item * ti ;
proto_tree * subtree = proto_tree_add_subtree_format ( tree , tvb , * pOffset , - 1 ,
ett_opcua_datavalue , & ti , " %s: DataValue " , szFieldName ) ;
2007-05-15 09:05:53 +00:00
gint iOffset = * pOffset ;
guint8 EncodingMask ;
EncodingMask = tvb_get_guint8 ( tvb , iOffset ) ;
2014-10-16 12:59:53 +00:00
proto_tree_add_bitmask ( subtree , tvb , iOffset , hf_opcua_datavalue_mask , ett_opcua_datavalue_encodingmask , datavalue_mask , ENC_LITTLE_ENDIAN ) ;
2007-05-15 09:05:53 +00:00
iOffset + + ;
if ( EncodingMask & DATAVALUE_ENCODINGBYTE_VALUE )
{
2014-10-16 17:06:31 +00:00
parseVariant ( subtree , tvb , pinfo , & iOffset , " Value " ) ;
2007-05-15 09:05:53 +00:00
}
if ( EncodingMask & DATAVALUE_ENCODINGBYTE_STATUSCODE )
{
2014-10-16 17:06:31 +00:00
parseStatusCode ( subtree , tvb , pinfo , & iOffset , hf_opcua_StatusCode ) ;
2007-05-15 09:05:53 +00:00
}
if ( EncodingMask & DATAVALUE_ENCODINGBYTE_SOURCETIMESTAMP )
{
2014-10-16 17:06:31 +00:00
parseDateTime ( subtree , tvb , pinfo , & iOffset , hf_opcua_SourceTimestamp ) ;
2007-05-15 09:05:53 +00:00
}
2009-04-06 18:30:04 +00:00
if ( EncodingMask & DATAVALUE_ENCODINGBYTE_SOURCEPICOSECONDS )
{
2014-10-16 17:06:31 +00:00
parseUInt16 ( subtree , tvb , pinfo , & iOffset , hf_opcua_SourcePicoseconds ) ;
2009-04-06 18:30:04 +00:00
}
2007-05-15 09:05:53 +00:00
if ( EncodingMask & DATAVALUE_ENCODINGBYTE_SERVERTIMESTAMP )
{
2014-10-16 17:06:31 +00:00
parseDateTime ( subtree , tvb , pinfo , & iOffset , hf_opcua_ServerTimestamp ) ;
2007-05-15 09:05:53 +00:00
}
2009-04-06 18:30:04 +00:00
if ( EncodingMask & DATAVALUE_ENCODINGBYTE_SERVERPICOSECONDS )
{
2014-10-16 17:06:31 +00:00
parseUInt16 ( subtree , tvb , pinfo , & iOffset , hf_opcua_ServerPicoseconds ) ;
2009-04-06 18:30:04 +00:00
}
2007-05-15 09:05:53 +00:00
2013-02-15 15:24:39 +00:00
proto_item_set_end ( ti , tvb , iOffset ) ;
2007-05-15 09:05:53 +00:00
* pOffset = iOffset ;
}
2014-10-16 17:06:31 +00:00
void parseVariant ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo , gint * pOffset , const char * szFieldName )
2007-05-15 09:05:53 +00:00
{
2014-07-10 01:21:32 +00:00
proto_item * ti ;
proto_tree * subtree = proto_tree_add_subtree_format ( tree , tvb , * pOffset , - 1 ,
ett_opcua_variant , & ti , " %s: Variant " , szFieldName ) ;
2007-05-15 09:05:53 +00:00
gint iOffset = * pOffset ;
guint8 EncodingMask ;
2013-02-15 15:24:39 +00:00
gint32 ArrayDimensions = 0 ;
2018-07-12 16:35:08 +00:00
guint opcua_nested_count ;
/* prevent a too high nesting depth */
opcua_nested_count = GPOINTER_TO_UINT ( p_get_proto_data ( pinfo - > pool , pinfo , proto_opcua , 0 ) ) ;
2018-10-20 18:30:27 +00:00
if ( opcua_nested_count > = MAX_NESTING_DEPTH )
2018-07-12 16:35:08 +00:00
{
expert_add_info ( pinfo , ti , & ei_nesting_depth ) ;
return ;
}
2018-10-20 18:30:27 +00:00
opcua_nested_count + + ;
2018-07-12 16:35:08 +00:00
p_add_proto_data ( pinfo - > pool , pinfo , proto_opcua , 0 , GUINT_TO_POINTER ( opcua_nested_count ) ) ;
2007-05-15 09:05:53 +00:00
EncodingMask = tvb_get_guint8 ( tvb , iOffset ) ;
2011-10-06 14:46:34 +00:00
proto_tree_add_item ( subtree , hf_opcua_variant_encodingmask , tvb , iOffset , 1 , ENC_LITTLE_ENDIAN ) ;
2007-05-15 09:05:53 +00:00
iOffset + + ;
if ( EncodingMask & VARIANT_ARRAYMASK )
{
2009-04-06 18:30:04 +00:00
/* type is encoded in bits 0-5 */
switch ( EncodingMask & 0x3f )
2007-05-15 09:05:53 +00:00
{
case OpcUaType_Null : break ;
2014-10-16 17:06:31 +00:00
case OpcUaType_Boolean : parseArraySimple ( subtree , tvb , pinfo , & iOffset , " Boolean " , " Boolean " , hf_opcua_Boolean , parseBoolean , ett_opcua_array_Boolean ) ; break ;
case OpcUaType_SByte : parseArraySimple ( subtree , tvb , pinfo , & iOffset , " SByte " , " SByte " , hf_opcua_SByte , parseSByte , ett_opcua_array_SByte ) ; break ;
case OpcUaType_Byte : parseArraySimple ( subtree , tvb , pinfo , & iOffset , " Byte " , " Byte " , hf_opcua_Byte , parseByte , ett_opcua_array_Byte ) ; break ;
case OpcUaType_Int16 : parseArraySimple ( subtree , tvb , pinfo , & iOffset , " Int16 " , " Int16 " , hf_opcua_Int16 , parseInt16 , ett_opcua_array_Int16 ) ; break ;
case OpcUaType_UInt16 : parseArraySimple ( subtree , tvb , pinfo , & iOffset , " UInt16 " , " UInt16 " , hf_opcua_UInt16 , parseUInt16 , ett_opcua_array_UInt16 ) ; break ;
case OpcUaType_Int32 : parseArraySimple ( subtree , tvb , pinfo , & iOffset , " Int32 " , " Int32 " , hf_opcua_Int32 , parseInt32 , ett_opcua_array_Int32 ) ; break ;
case OpcUaType_UInt32 : parseArraySimple ( subtree , tvb , pinfo , & iOffset , " UInt32 " , " UInt32 " , hf_opcua_UInt32 , parseUInt32 , ett_opcua_array_UInt32 ) ; break ;
case OpcUaType_Int64 : parseArraySimple ( subtree , tvb , pinfo , & iOffset , " Int64 " , " Int64 " , hf_opcua_Int64 , parseInt64 , ett_opcua_array_Int64 ) ; break ;
case OpcUaType_UInt64 : parseArraySimple ( subtree , tvb , pinfo , & iOffset , " UInt64 " , " UInt64 " , hf_opcua_UInt64 , parseUInt64 , ett_opcua_array_UInt64 ) ; break ;
case OpcUaType_Float : parseArraySimple ( subtree , tvb , pinfo , & iOffset , " Float " , " Float " , hf_opcua_Float , parseFloat , ett_opcua_array_Float ) ; break ;
case OpcUaType_Double : parseArraySimple ( subtree , tvb , pinfo , & iOffset , " Double " , " Double " , hf_opcua_Double , parseDouble , ett_opcua_array_Double ) ; break ;
case OpcUaType_String : parseArraySimple ( subtree , tvb , pinfo , & iOffset , " String " , " String " , hf_opcua_String , parseString , ett_opcua_array_String ) ; break ;
case OpcUaType_DateTime : parseArraySimple ( subtree , tvb , pinfo , & iOffset , " DateTime " , " DateTime " , hf_opcua_DateTime , parseDateTime , ett_opcua_array_DateTime ) ; break ;
case OpcUaType_Guid : parseArraySimple ( subtree , tvb , pinfo , & iOffset , " Guid " , " Guid " , hf_opcua_Guid , parseGuid , ett_opcua_array_Guid ) ; break ;
case OpcUaType_ByteString : parseArraySimple ( subtree , tvb , pinfo , & iOffset , " ByteString " , " ByteString " , hf_opcua_ByteString , parseByteString , ett_opcua_array_ByteString ) ; break ;
case OpcUaType_XmlElement : parseArraySimple ( subtree , tvb , pinfo , & iOffset , " XmlElement " , " XmlElement " , hf_opcua_XmlElement , parseXmlElement , ett_opcua_array_XmlElement ) ; break ;
case OpcUaType_NodeId : parseArrayComplex ( subtree , tvb , pinfo , & iOffset , " NodeId " , " NodeId " , parseNodeId , ett_opcua_array_NodeId ) ; break ;
case OpcUaType_ExpandedNodeId : parseArrayComplex ( subtree , tvb , pinfo , & iOffset , " ExpandedNodeId " , " ExpandedNodeId " , parseExpandedNodeId , ett_opcua_array_ExpandedNodeId ) ; break ;
case OpcUaType_StatusCode : parseArraySimple ( subtree , tvb , pinfo , & iOffset , " StatusCode " , " StatusCode " , hf_opcua_StatusCode , parseStatusCode , ett_opcua_array_StatusCode ) ; break ;
case OpcUaType_DiagnosticInfo : parseArrayComplex ( subtree , tvb , pinfo , & iOffset , " DiagnosticInfo " , " DiagnosticInfo " , parseDiagnosticInfo , ett_opcua_array_DiagnosticInfo ) ; break ;
case OpcUaType_QualifiedName : parseArrayComplex ( subtree , tvb , pinfo , & iOffset , " QualifiedName " , " QualifiedName " , parseQualifiedName , ett_opcua_array_QualifiedName ) ; break ;
case OpcUaType_LocalizedText : parseArrayComplex ( subtree , tvb , pinfo , & iOffset , " LocalizedText " , " LocalizedText " , parseLocalizedText , ett_opcua_array_LocalizedText ) ; break ;
case OpcUaType_ExtensionObject : parseArrayComplex ( subtree , tvb , pinfo , & iOffset , " ExtensionObject " , " ExtensionObject " , parseExtensionObject , ett_opcua_array_ExtensionObject ) ; break ;
case OpcUaType_DataValue : parseArrayComplex ( subtree , tvb , pinfo , & iOffset , " DataValue " , " DataValue " , parseDataValue , ett_opcua_array_DataValue ) ; break ;
case OpcUaType_Variant : parseArrayComplex ( subtree , tvb , pinfo , & iOffset , " Variant " , " Variant " , parseVariant , ett_opcua_array_Variant ) ; break ;
2007-05-15 09:05:53 +00:00
}
2010-11-15 18:52:41 +00:00
if ( EncodingMask & VARIANT_ARRAYDIMENSIONS )
{
2014-07-10 01:21:32 +00:00
proto_item * ti_2 ;
proto_tree * subtree_2 = proto_tree_add_subtree ( subtree , tvb , iOffset , - 1 ,
ett_opcua_variant_arraydims , & ti_2 , " ArrayDimensions " ) ;
2010-11-15 18:52:41 +00:00
int i ;
2013-02-15 15:24:39 +00:00
/* read array length */
ArrayDimensions = tvb_get_letohl ( tvb , iOffset ) ;
proto_tree_add_item ( subtree_2 , hf_opcua_ArraySize , tvb , iOffset , 4 , ENC_LITTLE_ENDIAN ) ;
if ( ArrayDimensions > MAX_ARRAY_LEN )
2010-11-15 18:52:41 +00:00
{
2014-10-16 17:25:08 +00:00
proto_tree_add_expert_format ( subtree_2 , pinfo , & ei_array_length , tvb , iOffset , 4 , " ArrayDimensions length %d too large to process " , ArrayDimensions ) ;
2013-02-15 15:24:39 +00:00
return ;
}
iOffset + = 4 ;
for ( i = 0 ; i < ArrayDimensions ; i + + )
{
2014-10-16 17:06:31 +00:00
parseInt32 ( subtree_2 , tvb , pinfo , & iOffset , hf_opcua_Int32 ) ;
2010-11-15 18:52:41 +00:00
}
2013-02-15 15:24:39 +00:00
proto_item_set_end ( ti_2 , tvb , iOffset ) ;
2010-11-15 18:52:41 +00:00
}
2007-05-15 09:05:53 +00:00
}
else
{
2009-04-06 18:30:04 +00:00
/* type is encoded in bits 0-5 */
switch ( EncodingMask & 0x3f )
2007-05-15 09:05:53 +00:00
{
case OpcUaType_Null : break ;
2014-10-16 17:06:31 +00:00
case OpcUaType_Boolean : parseBoolean ( subtree , tvb , pinfo , & iOffset , hf_opcua_Boolean ) ; break ;
case OpcUaType_SByte : parseSByte ( subtree , tvb , pinfo , & iOffset , hf_opcua_SByte ) ; break ;
case OpcUaType_Byte : parseByte ( subtree , tvb , pinfo , & iOffset , hf_opcua_Byte ) ; break ;
case OpcUaType_Int16 : parseInt16 ( subtree , tvb , pinfo , & iOffset , hf_opcua_Int16 ) ; break ;
case OpcUaType_UInt16 : parseUInt16 ( subtree , tvb , pinfo , & iOffset , hf_opcua_UInt16 ) ; break ;
case OpcUaType_Int32 : parseInt32 ( subtree , tvb , pinfo , & iOffset , hf_opcua_Int32 ) ; break ;
case OpcUaType_UInt32 : parseUInt32 ( subtree , tvb , pinfo , & iOffset , hf_opcua_UInt32 ) ; break ;
case OpcUaType_Int64 : parseInt64 ( subtree , tvb , pinfo , & iOffset , hf_opcua_Int64 ) ; break ;
case OpcUaType_UInt64 : parseUInt64 ( subtree , tvb , pinfo , & iOffset , hf_opcua_UInt64 ) ; break ;
case OpcUaType_Float : parseFloat ( subtree , tvb , pinfo , & iOffset , hf_opcua_Float ) ; break ;
case OpcUaType_Double : parseDouble ( subtree , tvb , pinfo , & iOffset , hf_opcua_Double ) ; break ;
case OpcUaType_String : parseString ( subtree , tvb , pinfo , & iOffset , hf_opcua_String ) ; break ;
case OpcUaType_DateTime : parseDateTime ( subtree , tvb , pinfo , & iOffset , hf_opcua_DateTime ) ; break ;
case OpcUaType_Guid : parseGuid ( subtree , tvb , pinfo , & iOffset , hf_opcua_Guid ) ; break ;
case OpcUaType_ByteString : parseByteString ( subtree , tvb , pinfo , & iOffset , hf_opcua_ByteString ) ; break ;
case OpcUaType_XmlElement : parseXmlElement ( subtree , tvb , pinfo , & iOffset , hf_opcua_XmlElement ) ; break ;
case OpcUaType_NodeId : parseNodeId ( subtree , tvb , pinfo , & iOffset , " Value " ) ; break ;
case OpcUaType_ExpandedNodeId : parseExpandedNodeId ( subtree , tvb , pinfo , & iOffset , " Value " ) ; break ;
case OpcUaType_StatusCode : parseStatusCode ( subtree , tvb , pinfo , & iOffset , hf_opcua_StatusCode ) ; break ;
case OpcUaType_DiagnosticInfo : parseDiagnosticInfo ( subtree , tvb , pinfo , & iOffset , " Value " ) ; break ;
case OpcUaType_QualifiedName : parseQualifiedName ( subtree , tvb , pinfo , & iOffset , " Value " ) ; break ;
case OpcUaType_LocalizedText : parseLocalizedText ( subtree , tvb , pinfo , & iOffset , " Value " ) ; break ;
case OpcUaType_ExtensionObject : parseExtensionObject ( subtree , tvb , pinfo , & iOffset , " Value " ) ; break ;
case OpcUaType_DataValue : parseDataValue ( subtree , tvb , pinfo , & iOffset , " Value " ) ; break ;
case OpcUaType_Variant : parseVariant ( subtree , tvb , pinfo , & iOffset , " Value " ) ; break ;
2007-05-15 09:05:53 +00:00
}
}
2009-10-20 14:03:00 +00:00
2013-02-15 15:24:39 +00:00
proto_item_set_end ( ti , tvb , iOffset ) ;
2007-05-15 09:05:53 +00:00
* pOffset = iOffset ;
2018-10-20 18:30:27 +00:00
opcua_nested_count - - ;
p_add_proto_data ( pinfo - > pool , pinfo , proto_opcua , 0 , GUINT_TO_POINTER ( opcua_nested_count ) ) ;
2007-05-15 09:05:53 +00:00
}
/** General parsing function for arrays of simple types.
* All arrays have one 4 byte signed integer length information ,
* followed by n data elements .
*/
2014-10-16 17:06:31 +00:00
void parseArraySimple ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo , gint * pOffset , const char * szFieldName , const char * szTypeName , int hfIndex , fctSimpleTypeParser pParserFunction , const gint idx )
2007-05-15 09:05:53 +00:00
{
2014-07-10 01:21:32 +00:00
proto_item * ti ;
proto_tree * subtree = proto_tree_add_subtree_format ( tree , tvb , * pOffset , - 1 , idx , & ti , " %s: Array of %s " , szFieldName , szTypeName ) ;
2007-05-15 09:05:53 +00:00
int i ;
gint32 iLen ;
/* read array length */
iLen = tvb_get_letohl ( tvb , * pOffset ) ;
2011-10-06 14:46:34 +00:00
proto_tree_add_item ( subtree , hf_opcua_ArraySize , tvb , * pOffset , 4 , ENC_LITTLE_ENDIAN ) ;
2007-05-15 09:05:53 +00:00
2009-09-09 00:18:15 +00:00
if ( iLen > MAX_ARRAY_LEN )
{
2014-10-16 17:25:08 +00:00
proto_tree_add_expert_format ( subtree , pinfo , & ei_array_length , tvb , * pOffset , 4 , " Array length %d too large to process " , iLen ) ;
2009-09-09 00:18:15 +00:00
return ;
}
* pOffset + = 4 ;
2007-05-15 09:05:53 +00:00
for ( i = 0 ; i < iLen ; i + + )
{
2014-10-16 17:06:31 +00:00
proto_item * arrayItem = ( * pParserFunction ) ( subtree , tvb , pinfo , pOffset , hfIndex ) ;
2014-06-12 14:54:25 +00:00
if ( arrayItem ! = NULL )
{
proto_item_prepend_text ( arrayItem , " [%i]: " , i ) ;
}
2007-05-15 09:05:53 +00:00
}
2013-02-15 15:24:39 +00:00
proto_item_set_end ( ti , tvb , * pOffset ) ;
2007-05-15 09:05:53 +00:00
}
/** General parsing function for arrays of enums.
* All arrays have one 4 byte signed integer length information ,
* followed by n data elements .
*/
2014-10-16 17:06:31 +00:00
void parseArrayEnum ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo , gint * pOffset , const char * szFieldName , const char * szTypeName , fctEnumParser pParserFunction , const gint idx )
2007-05-15 09:05:53 +00:00
{
2014-07-10 01:21:32 +00:00
proto_item * ti ;
proto_tree * subtree = proto_tree_add_subtree_format ( tree , tvb , * pOffset , - 1 , idx , & ti , " %s: Array of %s " , szFieldName , szTypeName ) ;
2007-05-15 09:05:53 +00:00
int i ;
gint32 iLen ;
/* read array length */
iLen = tvb_get_letohl ( tvb , * pOffset ) ;
2011-10-06 14:46:34 +00:00
proto_tree_add_item ( subtree , hf_opcua_ArraySize , tvb , * pOffset , 4 , ENC_LITTLE_ENDIAN ) ;
2007-05-15 09:05:53 +00:00
2009-09-09 00:18:15 +00:00
if ( iLen > MAX_ARRAY_LEN )
{
2014-10-16 17:25:08 +00:00
proto_tree_add_expert_format ( subtree , pinfo , & ei_array_length , tvb , * pOffset , 4 , " Array length %d too large to process " , iLen ) ;
2009-09-09 00:18:15 +00:00
return ;
}
* pOffset + = 4 ;
2007-05-15 09:05:53 +00:00
for ( i = 0 ; i < iLen ; i + + )
{
2014-10-16 17:06:31 +00:00
( * pParserFunction ) ( subtree , tvb , pinfo , pOffset ) ;
2007-05-15 09:05:53 +00:00
}
2013-02-15 15:24:39 +00:00
proto_item_set_end ( ti , tvb , * pOffset ) ;
2007-05-15 09:05:53 +00:00
}
/** General parsing function for arrays of complex types.
* All arrays have one 4 byte signed integer length information ,
* followed by n data elements .
*/
2014-10-16 17:06:31 +00:00
void parseArrayComplex ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo , gint * pOffset , const char * szFieldName , const char * szTypeName , fctComplexTypeParser pParserFunction , const gint idx )
2007-05-15 09:05:53 +00:00
{
2014-07-10 01:21:32 +00:00
proto_item * ti ;
proto_tree * subtree = proto_tree_add_subtree_format ( tree , tvb , * pOffset , - 1 , idx , & ti , " %s: Array of %s " , szFieldName , szTypeName ) ;
2007-05-15 09:05:53 +00:00
int i ;
gint32 iLen ;
/* read array length */
iLen = tvb_get_letohl ( tvb , * pOffset ) ;
2011-10-06 14:46:34 +00:00
proto_tree_add_item ( subtree , hf_opcua_ArraySize , tvb , * pOffset , 4 , ENC_LITTLE_ENDIAN ) ;
2007-05-15 09:05:53 +00:00
2009-09-09 00:18:15 +00:00
if ( iLen > MAX_ARRAY_LEN )
{
2014-10-16 17:25:08 +00:00
proto_tree_add_expert_format ( subtree , pinfo , & ei_array_length , tvb , * pOffset , 4 , " Array length %d too large to process " , iLen ) ;
2009-09-09 00:18:15 +00:00
return ;
}
* pOffset + = 4 ;
2007-05-15 09:05:53 +00:00
for ( i = 0 ; i < iLen ; i + + )
{
char szNum [ 20 ] ;
g_snprintf ( szNum , 20 , " [%i] " , i ) ;
2014-10-16 17:06:31 +00:00
( * pParserFunction ) ( subtree , tvb , pinfo , pOffset , szNum ) ;
2007-05-15 09:05:53 +00:00
}
2013-02-15 15:24:39 +00:00
proto_item_set_end ( ti , tvb , * pOffset ) ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
void parseNodeId ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo , gint * pOffset , const char * szFieldName )
2007-05-15 09:05:53 +00:00
{
2014-07-10 01:21:32 +00:00
proto_item * ti ;
proto_tree * subtree = proto_tree_add_subtree_format ( tree , tvb , * pOffset , - 1 , ett_opcua_nodeid , & ti , " %s: NodeId " , szFieldName ) ;
2007-05-15 09:05:53 +00:00
gint iOffset = * pOffset ;
guint8 EncodingMask ;
EncodingMask = tvb_get_guint8 ( tvb , iOffset ) ;
2011-10-06 14:46:34 +00:00
proto_tree_add_item ( subtree , hf_opcua_nodeid_encodingmask , tvb , iOffset , 1 , ENC_LITTLE_ENDIAN ) ;
2007-05-15 09:05:53 +00:00
iOffset + + ;
switch ( EncodingMask )
{
case 0x00 : /* two byte node id */
2011-10-06 14:46:34 +00:00
proto_tree_add_item ( subtree , hf_opcua_nodeid_numeric , tvb , iOffset , 1 , ENC_LITTLE_ENDIAN ) ;
2007-05-15 09:05:53 +00:00
iOffset + = 1 ;
break ;
case 0x01 : /* four byte node id */
2014-06-10 09:25:30 +00:00
proto_tree_add_item ( subtree , hf_opcua_nodeid_nsindex , tvb , iOffset , 1 , ENC_LITTLE_ENDIAN ) ;
2007-05-15 09:05:53 +00:00
iOffset + = 1 ;
2011-10-06 14:46:34 +00:00
proto_tree_add_item ( subtree , hf_opcua_nodeid_numeric , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
2007-05-15 09:05:53 +00:00
iOffset + = 2 ;
break ;
case 0x02 : /* numeric, that does not fit into four bytes */
2014-06-10 09:25:30 +00:00
proto_tree_add_item ( subtree , hf_opcua_nodeid_nsindex , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
2009-04-06 18:30:04 +00:00
iOffset + = 2 ;
2011-10-06 14:46:34 +00:00
proto_tree_add_item ( subtree , hf_opcua_nodeid_numeric , tvb , iOffset , 4 , ENC_LITTLE_ENDIAN ) ;
2007-05-15 09:05:53 +00:00
iOffset + = 4 ;
break ;
case 0x03 : /* string */
2014-06-10 09:25:30 +00:00
proto_tree_add_item ( subtree , hf_opcua_nodeid_nsindex , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
2009-04-06 18:30:04 +00:00
iOffset + = 2 ;
2014-10-16 17:06:31 +00:00
parseString ( subtree , tvb , pinfo , & iOffset , hf_opcua_nodeid_string ) ;
2007-05-15 09:05:53 +00:00
break ;
2009-04-06 18:30:04 +00:00
case 0x04 : /* guid */
2014-06-10 09:25:30 +00:00
proto_tree_add_item ( subtree , hf_opcua_nodeid_nsindex , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
2009-04-06 18:30:04 +00:00
iOffset + = 2 ;
2014-10-16 17:06:31 +00:00
parseGuid ( subtree , tvb , pinfo , & iOffset , hf_opcua_nodeid_guid ) ;
2007-05-15 09:05:53 +00:00
break ;
2009-04-06 18:30:04 +00:00
case 0x05 : /* byte string */
2014-06-10 09:25:30 +00:00
proto_tree_add_item ( subtree , hf_opcua_nodeid_nsindex , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
2012-05-05 04:57:40 +00:00
iOffset + = 2 ;
2014-10-16 17:06:31 +00:00
parseByteString ( subtree , tvb , pinfo , & iOffset , hf_opcua_nodeid_bytestring ) ;
2007-05-15 09:05:53 +00:00
break ;
} ;
2013-02-15 15:24:39 +00:00
proto_item_set_end ( ti , tvb , iOffset ) ;
2007-05-15 09:05:53 +00:00
* pOffset = iOffset ;
}
2014-10-16 17:06:31 +00:00
void parseExtensionObject ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo , gint * pOffset , const char * szFieldName )
2007-05-15 09:05:53 +00:00
{
2020-06-19 01:14:46 +00:00
static int * const extobj_mask [ ] = { & hf_opcua_extobj_mask_binbodyflag ,
2014-10-16 12:59:53 +00:00
& hf_opcua_extobj_mask_xmlbodyflag ,
NULL } ;
2007-05-15 09:05:53 +00:00
gint iOffset = * pOffset ;
guint8 EncodingMask ;
2010-11-16 17:00:50 +00:00
guint32 TypeId ;
2007-05-15 09:05:53 +00:00
proto_tree * extobj_tree ;
proto_item * ti ;
2018-07-12 16:35:08 +00:00
guint opcua_nested_count ;
2007-05-15 09:05:53 +00:00
/* add extension object subtree */
2014-07-10 01:21:32 +00:00
extobj_tree = proto_tree_add_subtree_format ( tree , tvb , * pOffset , - 1 , ett_opcua_extensionobject , & ti , " %s: ExtensionObject " , szFieldName ) ;
2007-05-15 09:05:53 +00:00
2018-07-12 16:35:08 +00:00
/* prevent a too high nesting depth */
opcua_nested_count = GPOINTER_TO_UINT ( p_get_proto_data ( pinfo - > pool , pinfo , proto_opcua , 0 ) ) ;
2018-10-20 18:30:27 +00:00
if ( opcua_nested_count > = MAX_NESTING_DEPTH )
2018-07-12 16:35:08 +00:00
{
expert_add_info ( pinfo , ti , & ei_nesting_depth ) ;
return ;
}
2018-10-20 18:30:27 +00:00
opcua_nested_count + + ;
2018-07-12 16:35:08 +00:00
p_add_proto_data ( pinfo - > pool , pinfo , proto_opcua , 0 , GUINT_TO_POINTER ( opcua_nested_count ) ) ;
2007-05-15 09:05:53 +00:00
/* add nodeid subtree */
2010-11-16 17:00:50 +00:00
TypeId = getExtensionObjectType ( tvb , & iOffset ) ;
2014-10-16 17:06:31 +00:00
parseExpandedNodeId ( extobj_tree , tvb , pinfo , & iOffset , " TypeId " ) ;
2007-05-15 09:05:53 +00:00
/* parse encoding mask */
EncodingMask = tvb_get_guint8 ( tvb , iOffset ) ;
2014-10-16 12:59:53 +00:00
proto_tree_add_bitmask ( extobj_tree , tvb , iOffset , hf_opcua_extobj_mask , ett_opcua_extensionobject_encodingmask , extobj_mask , ENC_LITTLE_ENDIAN ) ;
2007-05-15 09:05:53 +00:00
iOffset + + ;
if ( EncodingMask & EXTOBJ_ENCODINGMASK_BINBODY_FLAG ) /* has binary body ? */
{
2014-10-16 17:06:31 +00:00
dispatchExtensionObjectType ( extobj_tree , tvb , pinfo , & iOffset , TypeId ) ;
2007-05-15 09:05:53 +00:00
}
2013-02-15 15:24:39 +00:00
proto_item_set_end ( ti , tvb , iOffset ) ;
2007-05-15 09:05:53 +00:00
* pOffset = iOffset ;
2018-10-20 18:30:27 +00:00
opcua_nested_count - - ;
p_add_proto_data ( pinfo - > pool , pinfo , proto_opcua , 0 , GUINT_TO_POINTER ( opcua_nested_count ) ) ;
2007-05-15 09:05:53 +00:00
}
2014-10-16 17:06:31 +00:00
void parseExpandedNodeId ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo , gint * pOffset , const char * szFieldName )
2007-05-15 09:05:53 +00:00
{
2020-06-19 01:14:46 +00:00
static int * const expandednodeid_mask [ ] = { & hf_opcua_nodeid_encodingmask ,
2014-10-16 18:02:51 +00:00
& hf_opcua_expandednodeid_mask_serverindex ,
2015-12-07 16:56:22 +00:00
& hf_opcua_expandednodeid_mask_namespaceuri ,
2014-10-16 18:02:51 +00:00
NULL } ;
2014-07-10 01:21:32 +00:00
proto_item * ti ;
proto_tree * subtree = proto_tree_add_subtree_format ( tree , tvb , * pOffset , - 1 ,
ett_opcua_expandednodeid , & ti , " %s: ExpandedNodeId " , szFieldName ) ;
2007-05-15 09:05:53 +00:00
gint iOffset = * pOffset ;
2007-05-15 09:53:26 +00:00
guint8 EncodingMask ;
2007-05-15 09:05:53 +00:00
EncodingMask = tvb_get_guint8 ( tvb , iOffset ) ;
2014-10-16 18:02:51 +00:00
proto_tree_add_bitmask ( subtree , tvb , iOffset , hf_opcua_expandednodeid_mask , ett_opcua_expandednodeid_encodingmask , expandednodeid_mask , ENC_LITTLE_ENDIAN ) ;
2007-05-15 09:05:53 +00:00
iOffset + + ;
2014-06-10 08:51:52 +00:00
switch ( EncodingMask & 0x0F )
2007-05-15 09:05:53 +00:00
{
case 0x00 : /* two byte node id */
2011-10-06 14:46:34 +00:00
proto_tree_add_item ( subtree , hf_opcua_nodeid_numeric , tvb , iOffset , 1 , ENC_LITTLE_ENDIAN ) ;
2007-05-15 09:05:53 +00:00
iOffset + = 1 ;
break ;
case 0x01 : /* four byte node id */
2014-06-10 09:25:30 +00:00
proto_tree_add_item ( subtree , hf_opcua_nodeid_nsindex , tvb , iOffset , 1 , ENC_LITTLE_ENDIAN ) ;
2007-05-15 09:05:53 +00:00
iOffset + = 1 ;
2011-10-06 14:46:34 +00:00
proto_tree_add_item ( subtree , hf_opcua_nodeid_numeric , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
2007-05-15 09:05:53 +00:00
iOffset + = 2 ;
break ;
case 0x02 : /* numeric, that does not fit into four bytes */
2014-06-10 09:25:30 +00:00
proto_tree_add_item ( subtree , hf_opcua_nodeid_nsindex , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
2009-04-06 18:30:04 +00:00
iOffset + = 2 ;
2011-10-06 14:46:34 +00:00
proto_tree_add_item ( subtree , hf_opcua_nodeid_numeric , tvb , iOffset , 4 , ENC_LITTLE_ENDIAN ) ;
2007-05-15 09:05:53 +00:00
iOffset + = 4 ;
break ;
case 0x03 : /* string */
2014-06-10 09:25:30 +00:00
proto_tree_add_item ( subtree , hf_opcua_nodeid_nsindex , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
2009-04-06 18:30:04 +00:00
iOffset + = 2 ;
2014-10-16 17:06:31 +00:00
parseString ( subtree , tvb , pinfo , & iOffset , hf_opcua_nodeid_string ) ;
2007-05-15 09:05:53 +00:00
break ;
2009-04-06 18:30:04 +00:00
case 0x04 : /* guid */
2014-06-10 09:25:30 +00:00
proto_tree_add_item ( subtree , hf_opcua_nodeid_nsindex , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
2009-04-06 18:30:04 +00:00
iOffset + = 2 ;
2014-10-16 17:06:31 +00:00
parseGuid ( subtree , tvb , pinfo , & iOffset , hf_opcua_nodeid_guid ) ;
2007-05-15 09:05:53 +00:00
break ;
2009-04-06 18:30:04 +00:00
case 0x05 : /* byte string */
2014-06-10 09:25:30 +00:00
proto_tree_add_item ( subtree , hf_opcua_nodeid_nsindex , tvb , iOffset , 2 , ENC_LITTLE_ENDIAN ) ;
2009-04-06 18:30:04 +00:00
iOffset + = 2 ;
2014-10-16 17:06:31 +00:00
parseByteString ( subtree , tvb , pinfo , & iOffset , hf_opcua_nodeid_bytestring ) ;
2007-05-15 09:05:53 +00:00
break ;
} ;
2014-06-10 09:25:30 +00:00
if ( EncodingMask & NODEID_NAMESPACEURIFLAG )
2007-05-15 09:05:53 +00:00
{
2014-10-16 17:06:31 +00:00
parseString ( subtree , tvb , pinfo , & iOffset , hf_opcua_NamespaceUri ) ;
2007-05-15 09:05:53 +00:00
}
2009-04-06 18:30:04 +00:00
if ( EncodingMask & NODEID_SERVERINDEXFLAG )
{
2014-10-16 17:06:31 +00:00
parseUInt32 ( subtree , tvb , pinfo , & iOffset , hf_opcua_ServerIndex ) ;
2009-04-06 18:30:04 +00:00
}
2007-05-15 09:05:53 +00:00
2013-02-15 15:24:39 +00:00
proto_item_set_end ( ti , tvb , iOffset ) ;
2007-05-15 09:05:53 +00:00
* pOffset = iOffset ;
}
2010-11-16 17:00:50 +00:00
guint32 getExtensionObjectType ( tvbuff_t * tvb , gint * pOffset )
{
gint iOffset = * pOffset ;
guint8 EncodingMask ;
guint32 Numeric = 0 ;
EncodingMask = tvb_get_guint8 ( tvb , iOffset ) ;
iOffset + + ;
switch ( EncodingMask )
{
case 0x00 : /* two byte node id */
Numeric = tvb_get_guint8 ( tvb , iOffset ) ;
2013-09-02 23:15:17 +00:00
/*iOffset+=1;*/
2010-11-16 17:00:50 +00:00
break ;
case 0x01 : /* four byte node id */
iOffset + = 1 ;
Numeric = tvb_get_letohs ( tvb , iOffset ) ;
break ;
case 0x02 : /* numeric, that does not fit into four bytes */
2018-06-18 17:47:17 +00:00
iOffset + = 2 ;
2010-11-16 17:00:50 +00:00
Numeric = tvb_get_letohl ( tvb , iOffset ) ;
break ;
case 0x03 : /* string */
case 0x04 : /* uri */
case 0x05 : /* guid */
case 0x06 : /* byte string */
/* NOT USED */
break ;
} ;
return Numeric ;
}
2014-10-06 01:34:19 +00:00
2017-05-01 21:36:21 +00:00
void parseNodeClassMask ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo _U_ , gint * pOffset )
{
2020-06-19 01:14:46 +00:00
static int * const nodeclass_mask [ ] = {
2017-05-01 21:36:21 +00:00
& hf_opcua_nodeClassMask_object ,
& hf_opcua_nodeClassMask_variable ,
& hf_opcua_nodeClassMask_method ,
& hf_opcua_nodeClassMask_objecttype ,
& hf_opcua_nodeClassMask_variabletype ,
& hf_opcua_nodeClassMask_referencetype ,
& hf_opcua_nodeClassMask_datatype ,
& hf_opcua_nodeClassMask_view ,
NULL } ;
guint8 NodeClassMask = tvb_get_guint8 ( tvb , * pOffset ) ;
if ( NodeClassMask = = NODECLASSMASK_ALL )
{
proto_tree_add_item ( tree , hf_opcua_nodeClassMask_all , tvb , * pOffset , 4 , ENC_LITTLE_ENDIAN ) ;
}
else
{
proto_tree_add_bitmask ( tree , tvb , * pOffset , hf_opcua_nodeClassMask , ett_opcua_nodeClassMask , nodeclass_mask , ENC_LITTLE_ENDIAN ) ;
}
* pOffset + = 4 ;
}
void parseResultMask ( proto_tree * tree , tvbuff_t * tvb , packet_info * pinfo _U_ , gint * pOffset )
{
2020-06-19 01:14:46 +00:00
static int * const browseresult_mask [ ] = {
2017-05-01 21:36:21 +00:00
& hf_opcua_resultMask_referencetype ,
& hf_opcua_resultMask_isforward ,
& hf_opcua_resultMask_nodeclass ,
& hf_opcua_resultMask_browsename ,
& hf_opcua_resultMask_displayname ,
& hf_opcua_resultMask_typedefinition ,
NULL } ;
guint8 ResultMask = tvb_get_guint8 ( tvb , * pOffset ) ;
if ( ResultMask = = RESULTMASK_ALL )
{
proto_tree_add_item ( tree , hf_opcua_resultMask_all , tvb , * pOffset , 4 , ENC_LITTLE_ENDIAN ) ;
}
else
{
proto_tree_add_bitmask ( tree , tvb , * pOffset , hf_opcua_resultMask , ett_opcua_resultMask , browseresult_mask , ENC_LITTLE_ENDIAN ) ;
}
* pOffset + = 4 ;
}
2014-10-06 01:34:19 +00:00
/*
2019-07-26 18:43:17 +00:00
* Editor modelines - https : //www.wireshark.org/tools/modelines.html
2014-10-06 01:34:19 +00:00
*
* Local variables :
* c - basic - offset : 4
* tab - width : 8
* indent - tabs - mode : nil
* End :
*
* vi : set shiftwidth = 4 tabstop = 8 expandtab :
* : indentSize = 4 : tabSize = 8 : noTabs = true :
*/