wireshark/epan/dissectors/packet-netperfmeter.c
Guy Harris 8ed7a73e22 Fix a bunch of warnings.
Cast away some implicit 64-bit-to-32-bit conversion errors due to use of
sizeof.

Cast away some implicit 64-bit-to-32-bit conversion errors due to use of
strtol() and strtoul().

Change some data types to avoid those implicit conversion warnings.

When assigning a constant to a float, make sure the constant isn't a
double, by appending "f" to the constant.

Constify a bunch of variables, parameters, and return values to
eliminate warnings due to strings being given const qualifiers.  Cast
away those warnings in some cases where an API we don't control forces
us to do so.

Enable a bunch of additional warnings by default.  Note why at least
some of the other warnings aren't enabled.

randpkt.c and text2pcap.c are used to build programs, so they don't need
to be in EXTRA_DIST.

If the user specifies --enable-warnings-as-errors, add -Werror *even if
the user specified --enable-extra-gcc-flags; assume they know what
they're doing and are willing to have the compile fail due to the extra
GCC warnings being treated as errors.

svn path=/trunk/; revision=46748
2012-12-26 05:57:06 +00:00

466 lines
24 KiB
C

/* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <epan/packet.h>
#include <epan/sctpppids.h>
static int proto_npmp = -1;
static gint ett_npmp = -1;
static gint ett_onoffarray = -1;
#define PPID_NETPERFMETER_CONTROL_LEGACY 0x29097605
#define PPID_NETPERFMETER_DATA_LEGACY 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_cmt, 140, 1)
INIT_FIELD(addflow_ccid, 141, 1)
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 Transport Layer protocol types */
static const value_string proto_type_values[] = {
{ 6, "TCP" },
{ 8, "MPTCP" },
{ 17, "UDP" },
{ 33, "DCCP" },
{ 132, "SCTP" },
{ 0, NULL }
};
/* Setup list of CMT values */
static const value_string cmt_values[] = {
{ 0, "Off" },
{ 1, "CMT" },
{ 2, "CMT/RPv1" },
{ 3, "CMT/RPv2" },
{ 4, "MPTCP-Like" },
{ 0, NULL }
};
/* 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, VALS(proto_type_values), 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_cmt, { "CMT", "npmp.addflow_cmt", FT_UINT8, BASE_HEX, VALS(cmt_values), 0x0, NULL, HFILL } },
{ &hf_addflow_ccid, { "CCID", "npmp.addflow_ccid", FT_UINT8, 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_UINT(tree, field) proto_tree_add_item(tree, hf_##field, message_tvb, offset_##field, length_##field, ENC_BIG_ENDIAN)
#define ADD_FIELD_STRING(tree, field) proto_tree_add_item(tree, hf_##field, message_tvb, offset_##field, length_##field, ENC_ASCII|ENC_NA)
static void
dissect_npmp_acknowledge_message(tvbuff_t *message_tvb, proto_tree *message_tree)
{
ADD_FIELD_UINT(message_tree, acknowledge_flowid);
ADD_FIELD_UINT(message_tree, acknowledge_measurementid);
ADD_FIELD_UINT(message_tree, acknowledge_streamid);
ADD_FIELD_UINT(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_UINT(message_tree, addflow_flowid);
ADD_FIELD_UINT(message_tree, addflow_measurementid);
ADD_FIELD_UINT(message_tree, addflow_streamid);
ADD_FIELD_UINT(message_tree, addflow_protocol);
ADD_FIELD_UINT(message_tree, addflow_flags);
ADD_FIELD_STRING(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_UINT(message_tree, addflow_frameraterng);
ADD_FIELD_UINT(message_tree, addflow_framerate1);
ADD_FIELD_UINT(message_tree, addflow_framerate2);
ADD_FIELD_UINT(message_tree, addflow_framerate3);
ADD_FIELD_UINT(message_tree, addflow_framerate4);
ADD_FIELD_UINT(message_tree, addflow_framesizerng);
ADD_FIELD_UINT(message_tree, addflow_framesize1);
ADD_FIELD_UINT(message_tree, addflow_framesize2);
ADD_FIELD_UINT(message_tree, addflow_framesize3);
ADD_FIELD_UINT(message_tree, addflow_framesize4);
ADD_FIELD_UINT(message_tree, addflow_rcvbuffersize);
ADD_FIELD_UINT(message_tree, addflow_sndbuffersize);
ADD_FIELD_UINT(message_tree, addflow_maxmsgsize);
ADD_FIELD_UINT(message_tree, addflow_cmt);
ADD_FIELD_UINT(message_tree, addflow_ccid);
onoffitem = ADD_FIELD_UINT(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 + (int)(sizeof(guint32) * i));
proto_tree_add_uint_format(onofftree, hf_addflow_onoffeventarray, message_tvb,
offset_addflow_onoffeventarray + (int)(sizeof(guint32) * i), (int)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_UINT(message_tree, removeflow_flowid);
ADD_FIELD_UINT(message_tree, removeflow_measurementid);
ADD_FIELD_UINT(message_tree, removeflow_streamid);
}
static void
dissect_npmp_identify_flow_message(tvbuff_t *message_tvb, proto_tree *message_tree)
{
ADD_FIELD_UINT(message_tree, identifyflow_magicnumber);
ADD_FIELD_UINT(message_tree, identifyflow_flowid);
ADD_FIELD_UINT(message_tree, identifyflow_measurementid);
ADD_FIELD_UINT(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_UINT(message_tree, data_flowid);
ADD_FIELD_UINT(message_tree, data_measurementid);
ADD_FIELD_UINT(message_tree, data_streamid);
ADD_FIELD_UINT(message_tree, data_padding);
ADD_FIELD_UINT(message_tree, data_frameid);
ADD_FIELD_UINT(message_tree, data_packetseqnumber);
ADD_FIELD_UINT(message_tree, data_byteseqnumber);
ADD_FIELD_UINT(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, ENC_NA);
}
}
static void
dissect_npmp_start_message(tvbuff_t *message_tvb, proto_tree *message_tree)
{
ADD_FIELD_UINT(message_tree, start_measurementid);
}
static void
dissect_npmp_stop_message(tvbuff_t *message_tvb, proto_tree *message_tree)
{
ADD_FIELD_UINT(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, ENC_NA);
}
}
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 (check_col(pinfo->cinfo, COL_INFO)) {
col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str_const(type, message_type_values, "Unknown NetPerfMeterProtocol type"));
}
ADD_FIELD_UINT(npmp_tree, message_type);
ADD_FIELD_UINT(npmp_tree, message_flags);
ADD_FIELD_UINT(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, void *data _U_)
{
proto_item *npmp_item;
proto_tree *npmp_tree;
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, ENC_NA);
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_uint("sctp.ppi", PPID_NETPERFMETER_CONTROL_LEGACY, npmp_handle);
dissector_add_uint("sctp.ppi", PPID_NETPERFMETER_DATA_LEGACY, npmp_handle);
dissector_add_uint("sctp.ppi", NPMP_CTRL_PAYLOAD_PROTOCOL_ID, npmp_handle);
dissector_add_uint("sctp.ppi", NPMP_DATA_PAYLOAD_PROTOCOL_ID, npmp_handle);
}