diff options
author | Ulf Lamping <ulf.lamping@web.de> | 2007-05-15 09:53:26 +0000 |
---|---|---|
committer | Ulf Lamping <ulf.lamping@web.de> | 2007-05-15 09:53:26 +0000 |
commit | bfa57bdb6d0af3657b05b243295cc1b676a2cd3d (patch) | |
tree | e0081ae675ccde46c153ae73ee0b6adf1e834e2b /plugins/opcua/opcua_transport_layer.c | |
parent | a944d1a3e89561e6223913fc61d881081bfb23f7 (diff) |
from Gerhard Gappmeier:
renamed prefix ua_ -> opcua_
remove unused code
svn path=/trunk/; revision=21784
Diffstat (limited to 'plugins/opcua/opcua_transport_layer.c')
-rw-r--r-- | plugins/opcua/opcua_transport_layer.c | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/plugins/opcua/opcua_transport_layer.c b/plugins/opcua/opcua_transport_layer.c new file mode 100644 index 0000000000..b96e92adff --- /dev/null +++ b/plugins/opcua/opcua_transport_layer.c @@ -0,0 +1,211 @@ +/****************************************************************************** +** $Id$ +** +** Copyright (C) 2006-2007 ascolab GmbH. All Rights Reserved. +** Web: http://www.ascolab.com +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License +** as published by the Free Software Foundation; either version 2 +** of the License, or (at your option) any later version. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** Project: OpcUa Wireshark Plugin +** +** Description: OpcUa Transport Layer Decoder. +** +** Author: Gerhard Gappmeier <gerhard.gappmeier@ascolab.com> +** Last change by: $Author: gergap $ +** +******************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <gmodule.h> +#include <epan/packet.h> +#include "opcua_security_layer.h" +#include "opcua_application_layer.h" +#include "opcua_simpletypes.h" +#include <string.h> +#include <epan/emem.h> + +void dispatchService(proto_tree *tree, tvbuff_t *tvb, gint *pOffset, int ServiceId); + +static int hf_opcua_transport_sig = -1; +static int hf_opcua_transport_len = -1; +static int hf_opcua_transport_ver = -1; +static int hf_opcua_transport_cid = -1; +static int hf_opcua_transport_lifetime = -1; +static int hf_opcua_transport_sbl = -1; +static int hf_opcua_transport_rbl = -1; +static int hf_opcua_transport_endpoint = -1; +static int hf_opcua_transport_rlifetime = -1; +static int hf_opcua_transport_rsbl = -1; +static int hf_opcua_transport_rrbl = -1; +static int hf_opcua_transport_altendpoint = -1; +static int hf_opcua_transport_rqid = -1; +static int hf_opcua_transport_status = -1; +extern gint ett_opcua_nodeid; + +static hf_register_info hf[] = +{ + { &hf_opcua_transport_sig, + /* full name , abbreviation , type , display , strings, bitmask, blurb, id, parent, ref_count, bitshift */ + { "Signature", "transport.sig", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_opcua_transport_len, + { "Message Length", "transport.len", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_opcua_transport_ver, + { "Version", "transport.ver", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_opcua_transport_cid, + { "ConnectionId", "transport.cid", FT_GUID, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_opcua_transport_lifetime, + { "Lifetime", "transport.lifetime", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_opcua_transport_sbl, + { "SendBufferLength", "transport.sbl", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_opcua_transport_rbl, + { "ReceiveBufferLength", "transport.rbl", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_opcua_transport_endpoint, + { "EndPoint", "transport.endpoint", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_opcua_transport_rlifetime, + { "Revised Lifetime", "transport.rlifetime", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_opcua_transport_rsbl, + { "Revised SendBufferLength", "transport.rsbl", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_opcua_transport_rrbl, + { "Revised ReceiveBufferLength", "transport.rrbl", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_opcua_transport_altendpoint, + { "Alternate EndPoint", "transport.altendpoint", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_opcua_transport_rqid, + { "RequestId", "transport.rqid", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_opcua_transport_status, + { "StatusCode", "transport.status", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + } +}; + +/** subtree types */ +extern gint ett_opcua_extensionobject; + +/** Register transport layer types. */ +void registerTransportLayerTypes(int proto) +{ + proto_register_field_array(proto, hf, array_length(hf)); +} + +/** helper functions for adding strings, + * that are not zero terminated. + */ +void addString(proto_tree *tree, + int hfindex, + tvbuff_t *tvb, + gint start, + gint length, + const char *value) +{ + char *szValue = ep_alloc(256); + + if (szValue) + { + if (length > 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_sig, tvb, *pOffset, 4, tvb->real_data); *pOffset+=4; + proto_tree_add_item(tree, hf_opcua_transport_len, 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_cid, tvb, *pOffset, 16, TRUE); *pOffset+=16; + proto_tree_add_item(tree, hf_opcua_transport_lifetime, tvb, *pOffset, 4, TRUE); *pOffset+=4; + proto_tree_add_item(tree, hf_opcua_transport_sbl, tvb, *pOffset, 4, TRUE); *pOffset+=4; + proto_tree_add_item(tree, hf_opcua_transport_rbl, tvb, *pOffset, 4, TRUE); *pOffset+=4; + parseString(tree, tvb, pOffset, hf_opcua_transport_endpoint); +} + +void parseAcknowledge(proto_tree *tree, tvbuff_t *tvb, gint *pOffset) +{ + addString(tree, hf_opcua_transport_sig, tvb, *pOffset, 4, tvb->real_data); *pOffset+=4; + proto_tree_add_item(tree, hf_opcua_transport_len, tvb, *pOffset, 4, TRUE); *pOffset+=4; + proto_tree_add_item(tree, hf_opcua_transport_cid, tvb, *pOffset, 16, TRUE); *pOffset+=16; + proto_tree_add_item(tree, hf_opcua_transport_rlifetime, tvb, *pOffset, 4, TRUE); *pOffset+=4; + proto_tree_add_item(tree, hf_opcua_transport_rsbl, tvb, *pOffset, 4, TRUE); *pOffset+=4; + proto_tree_add_item(tree, hf_opcua_transport_rrbl, tvb, *pOffset, 4, TRUE); *pOffset+=4; + parseString(tree, tvb, pOffset, hf_opcua_transport_altendpoint); +} + +void parseDisconnect(proto_tree *tree, tvbuff_t *tvb, gint *pOffset) +{ + addString(tree, hf_opcua_transport_sig, tvb, *pOffset, 4, tvb->real_data); *pOffset+=4; + proto_tree_add_item(tree, hf_opcua_transport_len, tvb, *pOffset, 4, TRUE); *pOffset+=4; + proto_tree_add_item(tree, hf_opcua_transport_cid, tvb, *pOffset, 16, TRUE); *pOffset+=16; +} + +void parseData(proto_tree *tree, tvbuff_t *tvb, gint *pOffset) +{ + proto_item *ti; + proto_tree *encobj_tree; + proto_tree *nodeid_tree; + int ServiceId = 0; + + addString(tree, hf_opcua_transport_sig, tvb, *pOffset, 4, tvb->real_data); *pOffset+=4; + proto_tree_add_item(tree, hf_opcua_transport_len, tvb, *pOffset, 4, TRUE); *pOffset+=4; + proto_tree_add_item(tree, hf_opcua_transport_cid, tvb, *pOffset, 16, TRUE); *pOffset+=16; + proto_tree_add_item(tree, hf_opcua_transport_rqid, tvb, *pOffset, 4, TRUE); *pOffset+=4; + + /* message data contains the security layer */ + parseSecurityLayer(tree, tvb, pOffset); + + /* AT THE MOMENT NO SECURITY IS IMPLEMENTED IN UA. + * WE CAN JUST JUMP INTO THE APPLICATION LAYER DATA. + * THIS WILL CHAHNGE IN THE FUTURE. */ + + /* add encodeable object subtree */ + ti = proto_tree_add_text(tree, tvb, 0, -1, "Message : Encodeable Object"); + encobj_tree = proto_item_add_subtree(ti, ett_opcua_extensionobject); + + /* add nodeid subtree */ + ti = proto_tree_add_text(encobj_tree, tvb, 0, -1, "TypeId : ExpandedNodeId"); + nodeid_tree = proto_item_add_subtree(ti, ett_opcua_nodeid); + ServiceId = parseServiceNodeId(nodeid_tree, tvb, pOffset, "NodeId") - 1; + + dispatchService(encobj_tree, tvb, pOffset, ServiceId); +} + +void parseAbort(proto_tree *tree, tvbuff_t *tvb, gint *pOffset) +{ + addString(tree, hf_opcua_transport_sig, tvb, *pOffset, 4, tvb->real_data); *pOffset+=4; + proto_tree_add_item(tree, hf_opcua_transport_len, tvb, *pOffset, 4, TRUE); *pOffset+=4; + proto_tree_add_item(tree, hf_opcua_transport_cid, tvb, *pOffset, 16, TRUE); *pOffset+=16; + proto_tree_add_item(tree, hf_opcua_transport_rqid, tvb, *pOffset, 4, TRUE); *pOffset+=4; +} + +void parseError(proto_tree *tree, tvbuff_t *tvb, gint *pOffset) +{ + addString(tree, hf_opcua_transport_sig, tvb, *pOffset, 4, tvb->real_data); *pOffset+=4; + proto_tree_add_item(tree, hf_opcua_transport_len, tvb, *pOffset, 4, TRUE); *pOffset+=4; + proto_tree_add_item(tree, hf_opcua_transport_cid, tvb, *pOffset, 16, TRUE); *pOffset+=16; + proto_tree_add_item(tree, hf_opcua_transport_rqid, tvb, *pOffset, 4, TRUE); *pOffset+=4; + proto_tree_add_item(tree, hf_opcua_transport_status, tvb, *pOffset, 4, TRUE); *pOffset+=4; +} |