diff options
Diffstat (limited to 'plugins/epan/opcua/opcua_simpletypes.c')
-rw-r--r-- | plugins/epan/opcua/opcua_simpletypes.c | 360 |
1 files changed, 221 insertions, 139 deletions
diff --git a/plugins/epan/opcua/opcua_simpletypes.c b/plugins/epan/opcua/opcua_simpletypes.c index 945b528794..da98a823f5 100644 --- a/plugins/epan/opcua/opcua_simpletypes.c +++ b/plugins/epan/opcua/opcua_simpletypes.c @@ -19,8 +19,11 @@ #include <epan/packet.h> #include <epan/expert.h> -#include <epan/dissectors/packet-windows-common.h> +#include <epan/proto.h> #include <epan/proto_data.h> +#include <epan/asn1.h> +#include <epan/dissectors/packet-windows-common.h> +#include <epan/dissectors/packet-x509af.h> #include "opcua_simpletypes.h" #include "opcua_hfindeces.h" #include "opcua_statuscode.h" @@ -83,94 +86,94 @@ #define MAX_ARRAY_LEN 10000 #define MAX_NESTING_DEPTH 100 -static int hf_opcua_diag_mask = -1; -static int hf_opcua_diag_mask_symbolicflag = -1; -static int hf_opcua_diag_mask_namespaceflag = -1; -static int hf_opcua_diag_mask_localizedtextflag = -1; -static int hf_opcua_diag_mask_localeflag = -1; -static int hf_opcua_diag_mask_additionalinfoflag = -1; -static int hf_opcua_diag_mask_innerstatuscodeflag = -1; -static int hf_opcua_diag_mask_innerdiaginfoflag = -1; -static int hf_opcua_loctext_mask = -1; -static int hf_opcua_loctext_mask_localeflag = -1; -static int hf_opcua_loctext_mask_textflag = -1; -static int hf_opcua_datavalue_mask = -1; -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; -static int hf_opcua_datavalue_mask_sourcepicoseconds = -1; -static int hf_opcua_datavalue_mask_serverpicoseconds = -1; -static int hf_opcua_nodeid_encodingmask = -1; -static int hf_opcua_expandednodeid_mask = -1; -static int hf_opcua_expandednodeid_mask_namespaceuri = -1; -static int hf_opcua_expandednodeid_mask_serverindex = -1; -static int hf_opcua_variant_encodingmask = -1; -static int hf_opcua_nodeid_nsindex = -1; -static int hf_opcua_nodeid_numeric = -1; -static int hf_opcua_nodeid_string = -1; -static int hf_opcua_nodeid_guid = -1; -static int hf_opcua_nodeid_bytestring = -1; -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; -static int hf_opcua_SourceTimestamp = -1; -static int hf_opcua_SourcePicoseconds = -1; -static int hf_opcua_ServerTimestamp = -1; -static int hf_opcua_ServerPicoseconds = -1; -static int hf_opcua_diag_symbolicid = -1; -static int hf_opcua_diag_namespace = -1; -static int hf_opcua_diag_localizedtext = -1; -static int hf_opcua_diag_locale = -1; -static int hf_opcua_diag_additionalinfo = -1; -static int hf_opcua_diag_innerstatuscode = -1; -static int hf_opcua_extobj_mask = -1; -static int hf_opcua_extobj_mask_binbodyflag = -1; -static int hf_opcua_extobj_mask_xmlbodyflag = -1; -static int hf_opcua_ArraySize = -1; -static int hf_opcua_ServerIndex = -1; -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; -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; -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; - -static expert_field ei_array_length = EI_INIT; -static expert_field ei_nesting_depth = EI_INIT; +static int hf_opcua_diag_mask; +static int hf_opcua_diag_mask_symbolicflag; +static int hf_opcua_diag_mask_namespaceflag; +static int hf_opcua_diag_mask_localizedtextflag; +static int hf_opcua_diag_mask_localeflag; +static int hf_opcua_diag_mask_additionalinfoflag; +static int hf_opcua_diag_mask_innerstatuscodeflag; +static int hf_opcua_diag_mask_innerdiaginfoflag; +static int hf_opcua_loctext_mask; +static int hf_opcua_loctext_mask_localeflag; +static int hf_opcua_loctext_mask_textflag; +static int hf_opcua_datavalue_mask; +static int hf_opcua_datavalue_mask_valueflag; +static int hf_opcua_datavalue_mask_statuscodeflag; +static int hf_opcua_datavalue_mask_sourcetimestampflag; +static int hf_opcua_datavalue_mask_servertimestampflag; +static int hf_opcua_datavalue_mask_sourcepicoseconds; +static int hf_opcua_datavalue_mask_serverpicoseconds; +static int hf_opcua_nodeid_encodingmask; +static int hf_opcua_expandednodeid_mask; +static int hf_opcua_expandednodeid_mask_namespaceuri; +static int hf_opcua_expandednodeid_mask_serverindex; +static int hf_opcua_variant_encodingmask; +static int hf_opcua_nodeid_nsindex; +static int hf_opcua_nodeid_numeric; +static int hf_opcua_nodeid_string; +static int hf_opcua_nodeid_guid; +static int hf_opcua_nodeid_bytestring; +static int hf_opcua_localizedtext_locale; +static int hf_opcua_localizedtext_text; +static int hf_opcua_qualifiedname_id; +static int hf_opcua_qualifiedname_name; +static int hf_opcua_SourceTimestamp; +static int hf_opcua_SourcePicoseconds; +static int hf_opcua_ServerTimestamp; +static int hf_opcua_ServerPicoseconds; +static int hf_opcua_diag_symbolicid; +static int hf_opcua_diag_namespace; +static int hf_opcua_diag_localizedtext; +static int hf_opcua_diag_locale; +static int hf_opcua_diag_additionalinfo; +static int hf_opcua_diag_innerstatuscode; +static int hf_opcua_extobj_mask; +static int hf_opcua_extobj_mask_binbodyflag; +static int hf_opcua_extobj_mask_xmlbodyflag; +static int hf_opcua_ArraySize; +static int hf_opcua_ServerIndex; +static int hf_opcua_status_StructureChanged; +static int hf_opcua_status_SemanticsChanged; +static int hf_opcua_status_InfoBit_Limit_Overflow; +static int hf_opcua_status_InfoBit_Historian_Partial; +static int hf_opcua_status_InfoBit_Historian_ExtraData; +static int hf_opcua_status_InfoBit_Historian_MultiValue; +static int hf_opcua_status_InfoType; +static int hf_opcua_status_Limit; +static int hf_opcua_status_Historian; +int hf_opcua_returnDiag; +int hf_opcua_returnDiag_mask_sl_symbolicId; +int hf_opcua_returnDiag_mask_sl_localizedText; +int hf_opcua_returnDiag_mask_sl_additionalinfo; +int hf_opcua_returnDiag_mask_sl_innerstatuscode; +int hf_opcua_returnDiag_mask_sl_innerdiagnostics; +int hf_opcua_returnDiag_mask_ol_symbolicId; +int hf_opcua_returnDiag_mask_ol_localizedText; +int hf_opcua_returnDiag_mask_ol_additionalinfo; +int hf_opcua_returnDiag_mask_ol_innerstatuscode; +int hf_opcua_returnDiag_mask_ol_innerdiagnostics; +int hf_opcua_nodeClassMask; +int hf_opcua_nodeClassMask_all; +int hf_opcua_nodeClassMask_object; +int hf_opcua_nodeClassMask_variable; +int hf_opcua_nodeClassMask_method; +int hf_opcua_nodeClassMask_objecttype; +int hf_opcua_nodeClassMask_variabletype; +int hf_opcua_nodeClassMask_referencetype; +int hf_opcua_nodeClassMask_datatype; +int hf_opcua_nodeClassMask_view; +int hf_opcua_resultMask; +int hf_opcua_resultMask_all; +int hf_opcua_resultMask_referencetype; +int hf_opcua_resultMask_isforward; +int hf_opcua_resultMask_nodeclass; +int hf_opcua_resultMask_browsename; +int hf_opcua_resultMask_displayname; +int hf_opcua_resultMask_typedefinition; + +static expert_field ei_array_length; +static expert_field ei_nesting_depth; extern int proto_opcua; @@ -342,50 +345,50 @@ static const value_string g_ResultMask[] = { }; /* trees */ -static gint ett_opcua_diagnosticinfo = -1; -static gint ett_opcua_diagnosticinfo_encodingmask = -1; -static gint ett_opcua_nodeid = -1; -static gint ett_opcua_expandednodeid = -1; -static gint ett_opcua_expandednodeid_encodingmask = -1; -static gint ett_opcua_localizedtext = -1; -static gint ett_opcua_localizedtext_encodingmask = -1; -static gint ett_opcua_qualifiedname = -1; -static gint ett_opcua_datavalue = -1; -static gint ett_opcua_datavalue_encodingmask = -1; -static gint ett_opcua_variant = -1; -static gint ett_opcua_variant_arraydims = -1; -static gint ett_opcua_extensionobject = -1; -static gint ett_opcua_extensionobject_encodingmask = -1; -static gint ett_opcua_statuscode = -1; -static gint ett_opcua_statuscode_info = -1; -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; -gint ett_opcua_returnDiagnostics = -1; -gint ett_opcua_nodeClassMask = -1; -gint ett_opcua_resultMask = -1; +static gint ett_opcua_diagnosticinfo; +static gint ett_opcua_diagnosticinfo_encodingmask; +static gint ett_opcua_nodeid; +static gint ett_opcua_expandednodeid; +static gint ett_opcua_expandednodeid_encodingmask; +static gint ett_opcua_localizedtext; +static gint ett_opcua_localizedtext_encodingmask; +static gint ett_opcua_qualifiedname; +static gint ett_opcua_datavalue; +static gint ett_opcua_datavalue_encodingmask; +static gint ett_opcua_variant; +static gint ett_opcua_variant_arraydims; +static gint ett_opcua_extensionobject; +static gint ett_opcua_extensionobject_encodingmask; +static gint ett_opcua_statuscode; +static gint ett_opcua_statuscode_info; +gint ett_opcua_array_Boolean; +gint ett_opcua_array_SByte; +gint ett_opcua_array_Byte; +gint ett_opcua_array_Int16; +gint ett_opcua_array_UInt16; +gint ett_opcua_array_Int32; +gint ett_opcua_array_UInt32; +gint ett_opcua_array_Int64; +gint ett_opcua_array_UInt64; +gint ett_opcua_array_Float; +gint ett_opcua_array_Double; +gint ett_opcua_array_String; +gint ett_opcua_array_DateTime; +gint ett_opcua_array_Guid; +gint ett_opcua_array_ByteString; +gint ett_opcua_array_XmlElement; +gint ett_opcua_array_NodeId; +gint ett_opcua_array_ExpandedNodeId; +gint ett_opcua_array_StatusCode; +gint ett_opcua_array_DiagnosticInfo; +gint ett_opcua_array_QualifiedName; +gint ett_opcua_array_LocalizedText; +gint ett_opcua_array_ExtensionObject; +gint ett_opcua_array_DataValue; +gint ett_opcua_array_Variant; +gint ett_opcua_returnDiagnostics; +gint ett_opcua_nodeClassMask; +gint ett_opcua_resultMask; static gint *ett[] = { @@ -641,6 +644,50 @@ proto_item* parseString(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, return item; } +proto_item* parseString_ret_string_and_length(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, gint *pOffset, int hfIndex, const guint8 **retval, gint *lenretval) +{ + proto_item *item = NULL; + char *szValue; + gint iOffset = *pOffset; + gint32 iLen = tvb_get_letohl(tvb, *pOffset); + iOffset+=4; + + if (retval) { + *retval = ""; + } + if (lenretval) { + *lenretval = iLen; + } + + if (iLen == -1) + { + item = proto_tree_add_item(tree, hfIndex, tvb, *pOffset, 0, ENC_NA); + proto_item_append_text(item, "[OpcUa Null String]"); + proto_item_set_end(item, tvb, *pOffset + 4); + } + else if (iLen == 0) + { + item = proto_tree_add_item(tree, hfIndex, tvb, *pOffset, 0, ENC_NA); + proto_item_append_text(item, "[OpcUa Empty String]"); + proto_item_set_end(item, tvb, *pOffset + 4); + } + else if (iLen > 0) + { + item = proto_tree_add_item_ret_string_and_length(tree, hfIndex, tvb, iOffset, iLen, ENC_UTF_8|ENC_NA, NULL, retval, lenretval); + iOffset += iLen; /* eat the whole string */ + } + else + { + item = proto_tree_add_item(tree, hfIndex, tvb, *pOffset, 0, ENC_NA); + szValue = wmem_strdup_printf(pinfo->pool, "[Invalid String] Invalid length: %d", iLen); + proto_item_append_text(item, "%s", szValue); + proto_item_set_end(item, tvb, *pOffset + 4); + } + + *pOffset = iOffset; + return item; +} + proto_item* parseStatusCode(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, gint *pOffset, int hfIndex) { proto_item *item = NULL; @@ -835,14 +882,14 @@ void parseDiagnosticInfo(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gi { parseInt32(subtree, tvb, pinfo, &iOffset, hf_opcua_diag_namespace); } - if (EncodingMask & DIAGNOSTICINFO_ENCODINGMASK_LOCALIZEDTEXT_FLAG) - { - parseInt32(subtree, tvb, pinfo, &iOffset, hf_opcua_diag_localizedtext); - } if (EncodingMask & DIAGNOSTICINFO_ENCODINGMASK_LOCALE_FLAG) { parseInt32(subtree, tvb, pinfo, &iOffset, hf_opcua_diag_locale); } + if (EncodingMask & DIAGNOSTICINFO_ENCODINGMASK_LOCALIZEDTEXT_FLAG) + { + parseInt32(subtree, tvb, pinfo, &iOffset, hf_opcua_diag_localizedtext); + } if (EncodingMask & DIAGNOSTICINFO_ENCODINGMASK_ADDITIONALINFO_FLAG) { parseString(subtree, tvb, pinfo, &iOffset, hf_opcua_diag_additionalinfo); @@ -875,6 +922,41 @@ void parseQualifiedName(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gin proto_item_set_end(ti, tvb, *pOffset); } +void parseCertificate(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gint *pOffset, int hfIndex) +{ + proto_item *item = NULL; + char *szValue; + int iOffset = *pOffset; + gint32 iLen = tvb_get_letohl(tvb, iOffset); + iOffset += 4; + + if (iLen == -1) + { + item = proto_tree_add_bytes_with_length(tree, hfIndex, tvb, *pOffset, 4, NULL, 0); + proto_item_append_text(item, "[OpcUa Null ByteString]"); + } + else if (iLen == 0) + { + item = proto_tree_add_bytes_with_length(tree, hfIndex, tvb, *pOffset, 4, NULL, 0); + proto_item_append_text(item, "[OpcUa Empty ByteString]"); + } + else if (iLen > 0) + { + asn1_ctx_t asn1_ctx; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + dissect_x509af_Certificate(FALSE, tvb, iOffset, &asn1_ctx, tree, hfIndex); + iOffset += iLen; /* eat the whole bytestring */ + } + else + { + item = proto_tree_add_bytes_with_length(tree, hfIndex, tvb, *pOffset, 4, NULL, 0); + szValue = wmem_strdup_printf(pinfo->pool, "[Invalid ByteString] Invalid length: %d", iLen); + proto_item_append_text(item, "%s", szValue); + } + + *pOffset = iOffset; +} + void parseDataValue(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gint *pOffset, const char *szFieldName) { static int * const datavalue_mask[] = {&hf_opcua_datavalue_mask_valueflag, @@ -1134,7 +1216,7 @@ void parseArrayComplex(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gint for (i=0; i<iLen; i++) { char szNum[20]; - g_snprintf(szNum, 20, "[%i]", i); + snprintf(szNum, 20, "[%i]", i); (*pParserFunction)(subtree, tvb, pinfo, pOffset, szNum); } proto_item_set_end(ti, tvb, *pOffset); @@ -1218,7 +1300,7 @@ void parseExtensionObject(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, g /* add nodeid subtree */ TypeId = getExtensionObjectType(tvb, &iOffset); - parseExpandedNodeId(extobj_tree, tvb, pinfo, &iOffset, "TypeId"); + parseNodeId(extobj_tree, tvb, pinfo, &iOffset, "TypeId"); /* parse encoding mask */ EncodingMask = tvb_get_guint8(tvb, iOffset); |