aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/epan/opcua/opcua_simpletypes.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/epan/opcua/opcua_simpletypes.c')
-rw-r--r--plugins/epan/opcua/opcua_simpletypes.c360
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);