diff --git a/plugins/opcua/opcua.c b/plugins/opcua/opcua.c index 3200204087..0b1a89f421 100644 --- a/plugins/opcua/opcua.c +++ b/plugins/opcua/opcua.c @@ -167,32 +167,32 @@ static void dissect_opcua_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree col_set_str(pinfo->cinfo, COL_PROTOCOL, "OpcUa"); /* parse message type */ - if (tvb->real_data[0] == 'H' && tvb->real_data[1] == 'E' && tvb->real_data[2] == 'L') + if (tvb_memeql(tvb, 0, "HEL", 3)) { msgtype = MSG_HELLO; pfctParse = parseHello; } - else if (tvb->real_data[0] == 'A' && tvb->real_data[1] == 'C' && tvb->real_data[2] == 'K') + else if (tvb_memeql(tvb, 0, "ACK", 3)) { msgtype = MSG_ACKNOWLEDGE; pfctParse = parseAcknowledge; } - else if (tvb->real_data[0] == 'E' && tvb->real_data[1] == 'R' && tvb->real_data[2] == 'R') + else if (tvb_memeql(tvb, 0, "ERR", 3)) { msgtype = MSG_ERROR; pfctParse = parseError; } - else if (tvb->real_data[0] == 'M' && tvb->real_data[1] == 'S' && tvb->real_data[2] == 'G') + else if (tvb_memeql(tvb, 0, "MSG", 3)) { msgtype = MSG_MESSAGE; pfctParse = parseMessage; } - else if (tvb->real_data[0] == 'O' && tvb->real_data[1] == 'P' && tvb->real_data[2] == 'N') + else if (tvb_memeql(tvb, 0, "OPN", 3)) { msgtype = MSG_OPENSECURECHANNEL; pfctParse = parseOpenSecureChannel; } - else if (tvb->real_data[0] == 'C' && tvb->real_data[1] == 'L' && tvb->real_data[2] == 'O') + else if (tvb_memeql(tvb, 0, "CLO", 3)) { msgtype = MSG_CLOSESECURECHANNEL; pfctParse = parseCloseSecureChannel; diff --git a/plugins/opcua/opcua_simpletypes.c b/plugins/opcua/opcua_simpletypes.c index 777a842e8c..45a7a10640 100644 --- a/plugins/opcua/opcua_simpletypes.c +++ b/plugins/opcua/opcua_simpletypes.c @@ -34,9 +34,6 @@ #include #include -/* string buffer */ -#define MAX_BUFFER 256 - #define DIAGNOSTICINFO_ENCODINGMASK_SYMBOLICID_FLAG 0x01 #define DIAGNOSTICINFO_ENCODINGMASK_NAMESPACE_FLAG 0x02 #define DIAGNOSTICINFO_ENCODINGMASK_LOCALIZEDTEXT_FLAG 0x04 @@ -56,6 +53,9 @@ #define EXTOBJ_ENCODINGMASK_BINBODY_FLAG 0x01 #define EXTOBJ_ENCODINGMASK_XMLBODY_FLAG 0x02 +/* Chosen arbitrarily */ +#define MAX_ARRAY_LEN 10000 + static int hf_opcua_diag_mask_symbolicflag = -1; static int hf_opcua_diag_mask_namespaceflag = -1; static int hf_opcua_diag_mask_localizedtextflag = -1; @@ -338,35 +338,28 @@ void parseInt64(proto_tree *tree, tvbuff_t *tvb, gint *pOffset, int hfIndex) void parseString(proto_tree *tree, tvbuff_t *tvb, gint *pOffset, int hfIndex) { - char *szValue = ep_alloc(MAX_BUFFER); + char *szValue; gint iOffset = *pOffset; gint32 iLen = tvb_get_letohl(tvb, *pOffset); iOffset+=4; - if (szValue) + if (iLen == -1) { - if (iLen == -1) - { - g_snprintf(szValue, MAX_BUFFER, "[OpcUa Null String]"); - } - else if (iLen >= 0) - { - int iStrLen = iLen; - if (iStrLen > (MAX_BUFFER-1)) iStrLen = MAX_BUFFER - 1; - /* copy non null terminated string of length iStrlen */ - strncpy(szValue, (char*)&tvb->real_data[iOffset], iStrLen); - /* set null terminator */ - szValue[iStrLen] = 0; - iOffset += iLen; /* eat the whole string */ - } - else - { - g_snprintf(szValue, MAX_BUFFER, "[Invalid String] Ups, something is wrong with this message."); - } - - proto_tree_add_string(tree, hfIndex, tvb, *pOffset, (iOffset - *pOffset), szValue); - *pOffset = iOffset; + proto_tree_add_string(tree, hfIndex, tvb, *pOffset, (iOffset - *pOffset), + "[OpcUa Null String]"); } + else if (iLen >= 0) + { + iOffset += iLen; /* eat the whole string */ + proto_tree_add_item(tree, hfIndex, tvb, *pOffset, (iOffset - *pOffset), TRUE); + } + else + { + szValue = ep_strdup_printf("[Invalid String] Invalid length: %d", iLen); + proto_tree_add_string(tree, hfIndex, tvb, *pOffset, (iOffset - *pOffset), szValue); + } + + *pOffset = iOffset; } void parseStatusCode(proto_tree *tree, tvbuff_t *tvb, gint *pOffset, int hfIndex) @@ -644,9 +637,17 @@ void parseVariant(proto_tree *tree, tvbuff_t *tvb, gint *pOffset, char *szFieldN proto_tree *subtree = proto_item_add_subtree(ti, ett_opcua_array); int i; - for (i=0; i MAX_ARRAY_LEN) + { + PROTO_ITEM_SET_GENERATED(proto_tree_add_text(tree, tvb, *pOffset, 4, "Array length %d too large to process", iLen)); + return; + } + + *pOffset += 4; for (i=0; i MAX_ARRAY_LEN) + { + PROTO_ITEM_SET_GENERATED(proto_tree_add_text(tree, tvb, *pOffset, 4, "Array length %d too large to process", iLen)); + return; + } + + *pOffset += 4; for (i=0; i MAX_ARRAY_LEN) + { + PROTO_ITEM_SET_GENERATED(proto_tree_add_text(tree, tvb, *pOffset, 4, "Array length %d too large to process", iLen)); + return; + } + + *pOffset += 4; for (i=0; i 255) length = 255; - /* copy non null terminated string data */ - strncpy(szValue, value, length); - /* set null terminator */ - szValue[length] = 0; - - proto_tree_add_string(tree, hfindex, tvb, start, length, szValue); - } -} - /* Transport Layer: message parsers */ void parseHello(proto_tree *tree, tvbuff_t *tvb, gint *pOffset) { - addString(tree, hf_opcua_transport_type, tvb, *pOffset, 3, tvb->real_data); *pOffset+=3; - addString(tree, hf_opcua_transport_chunk, tvb, *pOffset, 1, &tvb->real_data[*pOffset]); *pOffset+=1; + proto_tree_add_item(tree, hf_opcua_transport_type, tvb, *pOffset, 3, TRUE); *pOffset+=3; + proto_tree_add_item(tree, hf_opcua_transport_chunk, tvb, *pOffset, 1, TRUE); *pOffset+=1; proto_tree_add_item(tree, hf_opcua_transport_size, tvb, *pOffset, 4, TRUE); *pOffset+=4; proto_tree_add_item(tree, hf_opcua_transport_ver, tvb, *pOffset, 4, TRUE); *pOffset+=4; proto_tree_add_item(tree, hf_opcua_transport_rbs, tvb, *pOffset, 4, TRUE); *pOffset+=4; @@ -166,8 +142,8 @@ void parseHello(proto_tree *tree, tvbuff_t *tvb, gint *pOffset) void parseAcknowledge(proto_tree *tree, tvbuff_t *tvb, gint *pOffset) { - addString(tree, hf_opcua_transport_type, tvb, *pOffset, 3, tvb->real_data); *pOffset+=3; - addString(tree, hf_opcua_transport_chunk, tvb, *pOffset, 1, &tvb->real_data[*pOffset]); *pOffset+=1; + proto_tree_add_item(tree, hf_opcua_transport_type, tvb, *pOffset, 3, TRUE); *pOffset+=3; + proto_tree_add_item(tree, hf_opcua_transport_chunk, tvb, *pOffset, 1, TRUE); *pOffset+=1; proto_tree_add_item(tree, hf_opcua_transport_size, tvb, *pOffset, 4, TRUE); *pOffset+=4; proto_tree_add_item(tree, hf_opcua_transport_ver, tvb, *pOffset, 4, TRUE); *pOffset+=4; proto_tree_add_item(tree, hf_opcua_transport_rbs, tvb, *pOffset, 4, TRUE); *pOffset+=4; @@ -178,8 +154,8 @@ void parseAcknowledge(proto_tree *tree, tvbuff_t *tvb, gint *pOffset) void parseError(proto_tree *tree, tvbuff_t *tvb, gint *pOffset) { - addString(tree, hf_opcua_transport_type, tvb, *pOffset, 3, tvb->real_data); *pOffset+=3; - addString(tree, hf_opcua_transport_chunk, tvb, *pOffset, 1, &tvb->real_data[*pOffset]); *pOffset+=1; + proto_tree_add_item(tree, hf_opcua_transport_type, tvb, *pOffset, 3, TRUE); *pOffset+=3; + proto_tree_add_item(tree, hf_opcua_transport_chunk, tvb, *pOffset, 1, TRUE); *pOffset+=1; proto_tree_add_item(tree, hf_opcua_transport_size, tvb, *pOffset, 4, TRUE); *pOffset+=4; proto_tree_add_item(tree, hf_opcua_transport_error, tvb, *pOffset, 4, TRUE); *pOffset+=4; parseString(tree, tvb, pOffset, hf_opcua_transport_reason); @@ -192,8 +168,8 @@ void parseMessage(proto_tree *tree, tvbuff_t *tvb, gint *pOffset) proto_tree *nodeid_tree; int ServiceId = 0; - addString(tree, hf_opcua_transport_type, tvb, *pOffset, 3, tvb->real_data); *pOffset+=3; - addString(tree, hf_opcua_transport_chunk, tvb, *pOffset, 1, &tvb->real_data[*pOffset]); *pOffset+=1; + proto_tree_add_item(tree, hf_opcua_transport_type, tvb, *pOffset, 3, TRUE); *pOffset+=3; + proto_tree_add_item(tree, hf_opcua_transport_chunk, tvb, *pOffset, 1, TRUE); *pOffset+=1; proto_tree_add_item(tree, hf_opcua_transport_size, tvb, *pOffset, 4, TRUE); *pOffset+=4; proto_tree_add_item(tree, hf_opcua_transport_scid, tvb, *pOffset, 4, TRUE); *pOffset+=4; @@ -223,8 +199,8 @@ void parseOpenSecureChannel(proto_tree *tree, tvbuff_t *tvb, gint *pOffset) proto_tree *nodeid_tree; int ServiceId = 0; - addString(tree, hf_opcua_transport_type, tvb, *pOffset, 3, tvb->real_data); *pOffset+=3; - addString(tree, hf_opcua_transport_chunk, tvb, *pOffset, 1, &tvb->real_data[*pOffset]); *pOffset+=1; + proto_tree_add_item(tree, hf_opcua_transport_type, tvb, *pOffset, 3, TRUE); *pOffset+=3; + proto_tree_add_item(tree, hf_opcua_transport_chunk, tvb, *pOffset, 1, TRUE); *pOffset+=1; proto_tree_add_item(tree, hf_opcua_transport_size, tvb, *pOffset, 4, TRUE); *pOffset+=4; proto_tree_add_item(tree, hf_opcua_transport_scid, tvb, *pOffset, 4, TRUE); *pOffset+=4; parseString(tree, tvb, pOffset, hf_opcua_transport_spu); @@ -247,8 +223,8 @@ void parseOpenSecureChannel(proto_tree *tree, tvbuff_t *tvb, gint *pOffset) void parseCloseSecureChannel(proto_tree *tree, tvbuff_t *tvb, gint *pOffset) { - addString(tree, hf_opcua_transport_type, tvb, *pOffset, 3, tvb->real_data); *pOffset+=3; - addString(tree, hf_opcua_transport_chunk, tvb, *pOffset, 1, &tvb->real_data[*pOffset]); *pOffset+=1; + proto_tree_add_item(tree, hf_opcua_transport_type, tvb, *pOffset, 3, TRUE); *pOffset+=3; + proto_tree_add_item(tree, hf_opcua_transport_chunk, tvb, *pOffset, 1, TRUE); *pOffset+=1; proto_tree_add_item(tree, hf_opcua_transport_size, tvb, *pOffset, 4, TRUE); *pOffset+=4; proto_tree_add_item(tree, hf_opcua_transport_scid, tvb, *pOffset, 4, TRUE); *pOffset+=4; }