diff options
author | Jaap Keuter <jaap.keuter@xs4all.nl> | 2009-11-12 22:35:27 +0000 |
---|---|---|
committer | Jaap Keuter <jaap.keuter@xs4all.nl> | 2009-11-12 22:35:27 +0000 |
commit | aca15d236e3861c93bc5c776b2ae1a93acd9516b (patch) | |
tree | 62ac6b9c35578691b66971cce6cc933b8c04588f /epan/dissectors/packet-netperfmeter.c | |
parent | bd92a72428e0cb49d05301f53135f28c2ae7bc9c (diff) |
From Thomas Dreibholz:
NetPerfMeter is an Open Source TCP/UDP/SCTP/DCCP network performance metering
application for Linux, FreeBSD and MacOS X. It can be downloaded here:
http://www.exp-math.uni-essen.de/~dreibh/netperfmeter/ . The protocol used by
this application for the transport of control and data is called NetPerfMeter
protocol. The attached patch is a dissector to decode its packets.
svn path=/trunk/; revision=30943
Diffstat (limited to 'epan/dissectors/packet-netperfmeter.c')
-rw-r--r-- | epan/dissectors/packet-netperfmeter.c | 443 |
1 files changed, 443 insertions, 0 deletions
diff --git a/epan/dissectors/packet-netperfmeter.c b/epan/dissectors/packet-netperfmeter.c new file mode 100644 index 0000000000..1ee0962566 --- /dev/null +++ b/epan/dissectors/packet-netperfmeter.c @@ -0,0 +1,443 @@ +/* packet-netperfmeter.c + * Routines for the NetPerfMeter Protocol used by the Open Source + * network performance meter application NetPerfMeter: + * http://www.exp-math.uni-essen.de/~dreibh/netperfmeter/ + * + * Copyright 2009 by Thomas Dreibholz <dreibh [AT] iem.uni-due.de> + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * Copied from README.developer + * + * 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <epan/packet.h> +#include <stdio.h> + + +static int proto_npmp = -1; +static gint ett_npmp = -1; +static gint ett_onoffarray = -1; + + +#define PPID_NETPERFMETER_CONTROL 0x29097605 +#define PPID_NETPERFMETER_DATA 0x29097606 + + +/* Initialize the protocol and registered fields */ +#define INIT_FIELD(variable, offset, length) \ + static int hf_##variable = -1; \ + static const int offset_##variable = offset; \ + static const int length_##variable = length; + +#define NETPERFMETER_ACKNOWLEDGE 0x01 +#define NETPERFMETER_ADD_FLOW 0x02 +#define NETPERFMETER_REMOVE_FLOW 0x03 +#define NETPERFMETER_IDENTIFY_FLOW 0x04 +#define NETPERFMETER_DATA 0x05 +#define NETPERFMETER_START 0x06 +#define NETPERFMETER_STOP 0x07 +#define NETPERFMETER_RESULTS 0x08 + +static const value_string message_type_values[] = { + { NETPERFMETER_ACKNOWLEDGE, "NetPerfMeter Acknowledge" }, + { NETPERFMETER_ADD_FLOW, "NetPerfMeter Add Flow" }, + { NETPERFMETER_REMOVE_FLOW, "NetPerfMeter Remove Flow" }, + { NETPERFMETER_IDENTIFY_FLOW, "NetPerfMeter Identify Flow" }, + { NETPERFMETER_DATA, "NetPerfMeter Data" }, + { NETPERFMETER_START, "NetPerfMeter Start Measurement" }, + { NETPERFMETER_STOP, "NetPerfMeter Stop Measurement" }, + { NETPERFMETER_RESULTS, "NetPerfMeter Results" }, + { 0, NULL } +}; + +INIT_FIELD(message_type, 0, 1) +INIT_FIELD(message_flags, 1, 1) +INIT_FIELD(message_length, 2, 2) + +INIT_FIELD(acknowledge_flowid, 4, 4) +INIT_FIELD(acknowledge_measurementid, 8, 8) +INIT_FIELD(acknowledge_streamid, 16, 2) +INIT_FIELD(acknowledge_padding, 18, 2) +INIT_FIELD(acknowledge_status, 20, 4) + +INIT_FIELD(addflow_flowid, 4, 4) +INIT_FIELD(addflow_measurementid, 8, 8) +INIT_FIELD(addflow_streamid, 16, 2) +INIT_FIELD(addflow_protocol, 18, 1) +INIT_FIELD(addflow_flags, 19, 1) +INIT_FIELD(addflow_description, 20, 32) +INIT_FIELD(addflow_ordered, 52, 4) +INIT_FIELD(addflow_reliable, 56, 4) +INIT_FIELD(addflow_retranstrials, 60, 4) +INIT_FIELD(addflow_framerate1, 64, 8) +INIT_FIELD(addflow_framerate2, 72, 8) +INIT_FIELD(addflow_framerate3, 80, 8) +INIT_FIELD(addflow_framerate4, 88, 8) +INIT_FIELD(addflow_framesize1, 96, 8) +INIT_FIELD(addflow_framesize2, 104, 8) +INIT_FIELD(addflow_framesize3, 112, 8) +INIT_FIELD(addflow_framesize4, 120, 8) +INIT_FIELD(addflow_frameraterng, 128, 1) +INIT_FIELD(addflow_framesizerng, 129, 1) +INIT_FIELD(addflow_rcvbuffersize, 130, 4) +INIT_FIELD(addflow_sndbuffersize, 134, 4) +INIT_FIELD(addflow_maxmsgsize, 138, 2) +INIT_FIELD(addflow_padding, 140, 2) +INIT_FIELD(addflow_onoffevents, 142, 2) +INIT_FIELD(addflow_onoffeventarray, 144, 4) + +INIT_FIELD(removeflow_flowid, 4, 4) +INIT_FIELD(removeflow_measurementid, 8, 8) +INIT_FIELD(removeflow_streamid, 16, 2) + +INIT_FIELD(identifyflow_flowid, 4, 4) +INIT_FIELD(identifyflow_magicnumber, 8, 8) +INIT_FIELD(identifyflow_measurementid, 16, 8) +INIT_FIELD(identifyflow_streamid, 24, 2) + +INIT_FIELD(data_flowid, 4, 4) +INIT_FIELD(data_measurementid, 8, 8) +INIT_FIELD(data_streamid, 16, 2) +INIT_FIELD(data_padding, 18, 2) +INIT_FIELD(data_frameid, 20, 4) +INIT_FIELD(data_packetseqnumber, 24, 8) +INIT_FIELD(data_byteseqnumber, 32, 8) +INIT_FIELD(data_timestamp, 40, 8) +INIT_FIELD(data_payload, 48, 0) + +INIT_FIELD(start_padding, 4, 4) +INIT_FIELD(start_measurementid, 8, 8) + +INIT_FIELD(stop_padding, 4, 4) +INIT_FIELD(stop_measurementid, 8, 8) + +INIT_FIELD(results_data, 4, 0) + + +/* Setup list of random number generator types */ +static const value_string rng_type_values[] = { + { 0, "Constant" }, + { 1, "Uniform" }, + { 2, "Neg. Exponential" }, + { 0, NULL } +}; + +/* Setup list of header fields */ +static hf_register_info hf[] = { + { &hf_message_type, { "Type", "npmp.message_type", FT_UINT8, BASE_DEC, VALS(message_type_values), 0x0, NULL, HFILL } }, + { &hf_message_flags, { "Flags", "npmp.message_flags", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_message_length, { "Length", "npmp.message_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + + { &hf_acknowledge_flowid, { "Flow ID", "npmp.acknowledge_flowid", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + { &hf_acknowledge_measurementid, { "Measurement ID", "npmp.acknowledge_measurementid", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + { &hf_acknowledge_streamid, { "Stream ID", "npmp.acknowledge_streamid", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_acknowledge_padding, { "Padding", "npmp.acknowledge_padding", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + { &hf_acknowledge_status, { "Status", "npmp.acknowledge_status", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + + { &hf_addflow_flowid, { "Flow ID", "npmp.addflow_flowid", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_measurementid, { "Measurement ID", "npmp.addflow_measurementid", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_streamid, { "Stream ID", "npmp.addflow_streamid", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_protocol, { "Protocol", "npmp.addflow_protocol", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_flags, { "Flags", "npmp.addflow_flags", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_description, { "Description", "npmp.addflow_description", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_ordered, { "Ordered", "npmp.addflow_ordered", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_reliable, { "Reliable", "npmp.addflow_reliable", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_retranstrials, { "Retransmission Trials", "npmp.addflow_retranstrials", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_frameraterng, { "Frame Rate RNG", "npmp.addflow_frameraterng", FT_UINT8, BASE_DEC, VALS(rng_type_values), 0x0, NULL, HFILL } }, + { &hf_addflow_framerate1, { "Frame Rate 1", "npmp.addflow_framerate1", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_framerate2, { "Frame Rate 2", "npmp.addflow_framerate2", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_framerate3, { "Frame Rate 3", "npmp.addflow_framerate3", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_framerate4, { "Frame Rate 4", "npmp.addflow_framerate4", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_framesizerng, { "Frame Size RNG", "npmp.addflow_framesizerng", FT_UINT8, BASE_DEC, VALS(rng_type_values), 0x0, NULL, HFILL } }, + { &hf_addflow_framesize1, { "Frame Size 1", "npmp.addflow_framesize1", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_framesize2, { "Frame Size 2", "npmp.addflow_framesize2", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_framesize3, { "Frame Size 3", "npmp.addflow_framesize3", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_framesize4, { "Frame Size 4", "npmp.addflow_framesize4", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_rcvbuffersize, { "Receive Buffer Size", "npmp.addflow_rcvbuffersize", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_sndbuffersize, { "Send Buffer Size", "npmp.addflow_sndbuffersize", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_maxmsgsize, { "Max. Message Size", "npmp.addflow_maxmsgsize", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_padding, { "Padding", "npmp.addflow_padding", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_onoffevents, { "On/Off Events", "npmp.addflow_onoffevents", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_addflow_onoffeventarray, { "On/Off Event", "npmp.addflow_onoffeventarray", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + + { &hf_removeflow_flowid, { "Flow ID", "npmp.removeflow_flowid", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + { &hf_removeflow_measurementid, { "Measurement ID", "npmp.removeflow_measurementid", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + { &hf_removeflow_streamid, { "Stream ID", "npmp.removeflow_streamid", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + + { &hf_identifyflow_flowid, { "Flow ID", "npmp.identifyflow_flowid", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + { &hf_identifyflow_magicnumber, { "Magic Number", "npmp.identifyflow_magicnumber", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + { &hf_identifyflow_measurementid, { "Measurement ID", "npmp.identifyflow_measurementid", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + { &hf_identifyflow_streamid, { "Stream ID", "npmp.identifyflow_streamid", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + + { &hf_data_flowid, { "Flow ID", "npmp.data_flowid", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + { &hf_data_measurementid, { "Measurement ID", "npmp.data_measurementid", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + { &hf_data_streamid, { "Stream ID", "npmp.data_streamid", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_data_padding, { "Padding", "npmp.data_padding", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + { &hf_data_frameid, { "Frame ID", "npmp.data_frameid", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_data_packetseqnumber, { "Packet Seq Number", "npmp.data_packetseqnumber", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_data_byteseqnumber, { "Byte Seq Number", "npmp.data_byteseqnumber", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_data_timestamp, { "Time Stamp", "npmp.data_timestamp", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_data_payload, { "Payload", "npmp.data_payload", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, + + { &hf_start_padding, { "Padding", "npmp.start_padding", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + { &hf_start_measurementid, { "Measurement ID", "npmp.start_measurementid", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + + { &hf_stop_padding, { "Padding", "npmp.stop_padding", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + { &hf_stop_measurementid, { "Measurement ID", "npmp.stop_measurementid", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL } }, + + { &hf_results_data, { "Data", "npmp.results_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +}; + + +#define ADD_FIELD(tree, field) proto_tree_add_item(tree, hf_##field, message_tvb, offset_##field, length_##field, FALSE) + + +static void +dissect_npmp_acknowledge_message(tvbuff_t *message_tvb, proto_tree *message_tree) +{ + ADD_FIELD(message_tree, acknowledge_flowid); + ADD_FIELD(message_tree, acknowledge_measurementid); + ADD_FIELD(message_tree, acknowledge_streamid); + ADD_FIELD(message_tree, acknowledge_status); +} + + +static void +dissect_npmp_add_flow_message(tvbuff_t *message_tvb, proto_tree *message_tree) +{ + guint32 retranstrials; + proto_item* onoffitem; + proto_tree* onofftree; + guint16 onoffevents; + guint32 onoffvalue; + unsigned int i; + + ADD_FIELD(message_tree, addflow_flowid); + ADD_FIELD(message_tree, addflow_measurementid); + ADD_FIELD(message_tree, addflow_streamid); + ADD_FIELD(message_tree, addflow_protocol); + ADD_FIELD(message_tree, addflow_flags); + ADD_FIELD(message_tree, addflow_description); + + proto_tree_add_double_format_value(message_tree, hf_addflow_ordered, message_tvb, offset_addflow_ordered, length_addflow_ordered, + 100.0 * tvb_get_ntohl(message_tvb, offset_addflow_ordered) / (double)0xffffffff, "%1.3f%%", + 100.0 * tvb_get_ntohl(message_tvb, offset_addflow_ordered) / (double)0xffffffff); + proto_tree_add_double_format_value(message_tree, hf_addflow_reliable, message_tvb, offset_addflow_reliable, length_addflow_reliable, + 100.0 * tvb_get_ntohl(message_tvb, offset_addflow_reliable) / (double)0xffffffff, "%1.3f%%", + 100.0 * tvb_get_ntohl(message_tvb, offset_addflow_reliable) / (double)0xffffffff); + + retranstrials = tvb_get_ntohl(message_tvb, offset_addflow_retranstrials); + proto_tree_add_uint_format_value(message_tree, hf_addflow_retranstrials, message_tvb, offset_addflow_retranstrials, length_addflow_retranstrials, + retranstrials, (retranstrials & (1 << 31)) ? "%u ms" : "%u trials", + retranstrials &~ (1 << 31)); + + ADD_FIELD(message_tree, addflow_frameraterng); + ADD_FIELD(message_tree, addflow_framerate1); + ADD_FIELD(message_tree, addflow_framerate2); + ADD_FIELD(message_tree, addflow_framerate3); + ADD_FIELD(message_tree, addflow_framerate4); + ADD_FIELD(message_tree, addflow_framesizerng); + ADD_FIELD(message_tree, addflow_framesize1); + ADD_FIELD(message_tree, addflow_framesize2); + ADD_FIELD(message_tree, addflow_framesize3); + ADD_FIELD(message_tree, addflow_framesize4); + ADD_FIELD(message_tree, addflow_maxmsgsize); + ADD_FIELD(message_tree, addflow_rcvbuffersize); + ADD_FIELD(message_tree, addflow_sndbuffersize); + ADD_FIELD(message_tree, addflow_padding); + + onoffitem = ADD_FIELD(message_tree, addflow_onoffevents); + + onoffevents = tvb_get_ntohs(message_tvb, offset_addflow_onoffevents); + if (onoffevents > 0) { + onofftree = proto_item_add_subtree(onoffitem, ett_onoffarray); + for(i = 0;i < onoffevents;i++) { + onoffvalue = tvb_get_ntohl(message_tvb, offset_addflow_onoffeventarray + (sizeof(guint32) * i)); + proto_tree_add_uint_format(onofftree, hf_addflow_onoffeventarray, message_tvb, + offset_addflow_onoffeventarray + (sizeof(guint32) * i), sizeof(guint32), + onoffvalue, "%1.3f s: set to %s", onoffvalue / 1000.0, (i & 1) ? "OFF" : "ON"); + } + } +} + + +static void +dissect_npmp_remove_flow_message(tvbuff_t *message_tvb, proto_tree *message_tree) +{ + ADD_FIELD(message_tree, removeflow_flowid); + ADD_FIELD(message_tree, removeflow_measurementid); + ADD_FIELD(message_tree, removeflow_streamid); +} + + +static void +dissect_npmp_identify_flow_message(tvbuff_t *message_tvb, proto_tree *message_tree) +{ + ADD_FIELD(message_tree, identifyflow_magicnumber); + ADD_FIELD(message_tree, identifyflow_flowid); + ADD_FIELD(message_tree, identifyflow_measurementid); + ADD_FIELD(message_tree, identifyflow_streamid); +} + + +static void +dissect_npmp_data_message(tvbuff_t *message_tvb, proto_tree *message_tree) +{ + const guint16 message_length = tvb_get_ntohs(message_tvb, offset_message_length); + + ADD_FIELD(message_tree, data_flowid); + ADD_FIELD(message_tree, data_measurementid); + ADD_FIELD(message_tree, data_streamid); + ADD_FIELD(message_tree, data_padding); + ADD_FIELD(message_tree, data_frameid); + ADD_FIELD(message_tree, data_packetseqnumber); + ADD_FIELD(message_tree, data_byteseqnumber); + ADD_FIELD(message_tree, data_timestamp); + if (message_length > offset_data_payload) { + proto_tree_add_item(message_tree, hf_data_payload, message_tvb, offset_data_payload, message_length - offset_data_payload, FALSE); + } +} + + +static void +dissect_npmp_start_message(tvbuff_t *message_tvb, proto_tree *message_tree) +{ + ADD_FIELD(message_tree, start_measurementid); +} + + +static void +dissect_npmp_stop_message(tvbuff_t *message_tvb, proto_tree *message_tree) +{ + ADD_FIELD(message_tree, stop_measurementid); +} + + +static void +dissect_npmp_results_message(tvbuff_t *message_tvb, proto_tree *message_tree) +{ + const guint16 message_length = tvb_get_guint8(message_tvb, offset_message_length); + if (message_length > offset_results_data) { + proto_tree_add_item(message_tree, hf_results_data, message_tvb, offset_results_data, message_length - offset_results_data, FALSE); + } +} + + +static void +dissect_npmp_message(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *npmp_tree) +{ + guint8 type; + + type = tvb_get_guint8(message_tvb, offset_message_type); + if (pinfo && (check_col(pinfo->cinfo, COL_INFO))) { + col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(type, message_type_values, "Unknown NetPerfMeterProtocol type")); + } + + ADD_FIELD(npmp_tree, message_type); + ADD_FIELD(npmp_tree, message_flags); + ADD_FIELD(npmp_tree, message_length); + + switch (type) { + case NETPERFMETER_ACKNOWLEDGE: + dissect_npmp_acknowledge_message(message_tvb, npmp_tree); + break; + case NETPERFMETER_ADD_FLOW: + dissect_npmp_add_flow_message(message_tvb, npmp_tree); + break; + case NETPERFMETER_REMOVE_FLOW: + dissect_npmp_remove_flow_message(message_tvb, npmp_tree); + break; + case NETPERFMETER_IDENTIFY_FLOW: + dissect_npmp_identify_flow_message(message_tvb, npmp_tree); + break; + case NETPERFMETER_DATA: + dissect_npmp_data_message(message_tvb, npmp_tree); + break; + case NETPERFMETER_START: + dissect_npmp_start_message(message_tvb, npmp_tree); + break; + case NETPERFMETER_STOP: + dissect_npmp_stop_message(message_tvb, npmp_tree); + break; + case NETPERFMETER_RESULTS: + dissect_npmp_results_message(message_tvb, npmp_tree); + break; + } +} + + +static int +dissect_npmp(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_item *npmp_item; + proto_tree *npmp_tree; + + /* pinfo is NULL only if dissect_npmp_message is called from dissect_error cause */ + if (pinfo && (check_col(pinfo->cinfo, COL_PROTOCOL))) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "NetPerfMeterProtocol"); + + /* In the interest of speed, if "tree" is NULL, don't do any work not + necessary to generate protocol tree items. */ + if (tree) { + /* create the npmp protocol tree */ + npmp_item = proto_tree_add_item(tree, proto_npmp, message_tvb, 0, -1, FALSE); + npmp_tree = proto_item_add_subtree(npmp_item, ett_npmp); + } else { + npmp_tree = NULL; + }; + /* dissect the message */ + dissect_npmp_message(message_tvb, pinfo, npmp_tree); + return(TRUE); +} + + +/* Register the protocol with Wireshark */ +void +proto_register_npmp(void) +{ + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_npmp, + &ett_onoffarray + }; + + /* Register the protocol name and description */ + proto_npmp = proto_register_protocol("NetPerfMeter Protocol", "NetPerfMeterProtocol", "npmp"); + + /* Required function calls to register the header fields and subtrees used */ + proto_register_field_array(proto_npmp, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + + +void +proto_reg_handoff_npmp(void) +{ + dissector_handle_t npmp_handle; + + npmp_handle = new_create_dissector_handle(dissect_npmp, proto_npmp); + dissector_add("sctp.ppi", PPID_NETPERFMETER_CONTROL, npmp_handle); + dissector_add("sctp.ppi", PPID_NETPERFMETER_DATA, npmp_handle); +} |