Split off the dissectors for 802.3 "slow protocols".

Add a dissector table for the 802.3 "slow protocols" subtype, split the
dissectors for those protocols into separate files, and have them
register in that dissector table.

Remove some unnecessary #includes while we're at it.

Change-Id: Ic36c9c255efdd348055fa4f21fd6cc094f74e378
Reviewed-on: https://code.wireshark.org/review/1891
Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
Guy Harris 2014-05-30 21:48:41 -07:00
parent 60daebaf16
commit c91dd11ccb
9 changed files with 4412 additions and 4205 deletions

View File

@ -863,6 +863,7 @@ set(DISSECTOR_SRC
dissectors/packet-kt.c
dissectors/packet-l1-events.c
dissectors/packet-l2tp.c
dissectors/packet-lacp.c
dissectors/packet-lanforge.c
dissectors/packet-lapb.c
dissectors/packet-lapbether.c
@ -912,6 +913,7 @@ set(DISSECTOR_SRC
dissectors/packet-macsec.c
dissectors/packet-mactelnet.c
dissectors/packet-manolito.c
dissectors/packet-marker.c
dissectors/packet-mausb.c
dissectors/packet-mbim.c
dissectors/packet-mbtcp.c
@ -1024,6 +1026,7 @@ set(DISSECTOR_SRC
dissectors/packet-ntp.c
dissectors/packet-null.c
dissectors/packet-nwmtp.c
dissectors/packet-oampdu.c
dissectors/packet-oicq.c
dissectors/packet-oipf.c
dissectors/packet-olsr.c
@ -1042,6 +1045,7 @@ set(DISSECTOR_SRC
dissectors/packet-osi.c
dissectors/packet-ositp.c
dissectors/packet-ospf.c
dissectors/packet-ossp.c
dissectors/packet-ouch.c
dissectors/packet-p_mul.c
dissectors/packet-pathport.c

View File

@ -233,6 +233,7 @@ LIBWIRESHARK_INCLUDES = \
show_exception.h \
sigcomp_state_hdlr.h \
sigcomp-udvm.h \
slow_protocol_subtypes.h \
sminmpec.h \
sna-utils.h \
stat_cmd_args.h \

View File

@ -783,6 +783,7 @@ DISSECTOR_SRC = \
packet-kt.c \
packet-l1-events.c \
packet-l2tp.c \
packet-lacp.c \
packet-lanforge.c \
packet-lapb.c \
packet-lapbether.c \
@ -832,6 +833,7 @@ DISSECTOR_SRC = \
packet-macsec.c \
packet-mactelnet.c \
packet-manolito.c \
packet-marker.c \
packet-mausb.c \
packet-mbim.c \
packet-mbtcp.c \
@ -944,6 +946,7 @@ DISSECTOR_SRC = \
packet-ntp.c \
packet-null.c \
packet-nwmtp.c \
packet-oampdu.c \
packet-oicq.c \
packet-oipf.c \
packet-olsr.c \
@ -961,6 +964,7 @@ DISSECTOR_SRC = \
packet-osi.c \
packet-ositp.c \
packet-ospf.c \
packet-ossp.c \
packet-ouch.c \
packet-p_mul.c \
packet-pathport.c \

View File

@ -0,0 +1,693 @@
/* packet-lacp.c
* Routines for Link Aggregation Control Protocol dissection.
* IEEE Std 802.1AX
*
* Copyright 2002 Steve Housley <steve_housley@3com.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* 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/slow_protocol_subtypes.h>
/* General declarations */
void proto_register_lacp(void);
void proto_reg_handoff_lacp(void);
/* Actor and Partner Flag bits */
#define LACPDU_FLAGS_ACTIVITY 0x01
#define LACPDU_FLAGS_TIMEOUT 0x02
#define LACPDU_FLAGS_AGGREGATION 0x04
#define LACPDU_FLAGS_SYNC 0x08
#define LACPDU_FLAGS_COLLECTING 0x10
#define LACPDU_FLAGS_DISTRIB 0x20
#define LACPDU_FLAGS_DEFAULTED 0x40
#define LACPDU_FLAGS_EXPIRED 0x80
/* Initialise the protocol and registered fields */
static int proto_lacp = -1;
static int hf_lacp_version_number = -1;
static int hf_lacp_actor_type = -1;
static int hf_lacp_actor_info_len = -1;
static int hf_lacp_actor_sys_priority = -1;
static int hf_lacp_actor_sys = -1;
static int hf_lacp_actor_key = -1;
static int hf_lacp_actor_port_priority = -1;
static int hf_lacp_actor_port = -1;
static int hf_lacp_actor_state = -1;
static int hf_lacp_flags_a_activity = -1;
static int hf_lacp_flags_a_timeout = -1;
static int hf_lacp_flags_a_aggregation = -1;
static int hf_lacp_flags_a_sync = -1;
static int hf_lacp_flags_a_collecting = -1;
static int hf_lacp_flags_a_distrib = -1;
static int hf_lacp_flags_a_defaulted = -1;
static int hf_lacp_flags_a_expired = -1;
static int hf_lacp_actor_reserved = -1;
static int hf_lacp_partner_type = -1;
static int hf_lacp_partner_info_len = -1;
static int hf_lacp_partner_sys_priority = -1;
static int hf_lacp_partner_sys = -1;
static int hf_lacp_partner_key = -1;
static int hf_lacp_partner_port_priority = -1;
static int hf_lacp_partner_port = -1;
static int hf_lacp_partner_state = -1;
static int hf_lacp_flags_p_activity = -1;
static int hf_lacp_flags_p_timeout = -1;
static int hf_lacp_flags_p_aggregation = -1;
static int hf_lacp_flags_p_sync = -1;
static int hf_lacp_flags_p_collecting = -1;
static int hf_lacp_flags_p_distrib = -1;
static int hf_lacp_flags_p_defaulted = -1;
static int hf_lacp_flags_p_expired = -1;
static int hf_lacp_partner_reserved = -1;
static int hf_lacp_coll_type = -1;
static int hf_lacp_coll_info_len = -1;
static int hf_lacp_coll_max_delay = -1;
static int hf_lacp_coll_reserved = -1;
static int hf_lacp_term_type = -1;
static int hf_lacp_term_len = -1;
static int hf_lacp_term_reserved = -1;
/* Initialise the subtree pointers */
static gint ett_lacp = -1;
static gint ett_lacp_a_flags = -1;
static gint ett_lacp_p_flags = -1;
static const char initial_sep[] = " (";
static const char cont_sep[] = ", ";
#define APPEND_BOOLEAN_FLAG(flag, item, string) \
if(flag){ \
if(item) \
proto_item_append_text(item, string, sep); \
sep = cont_sep; \
}
/*
* Name: dissect_lacp
*
* Description:
* This function is used to dissect the Link Aggregation Control Protocol
* defined in IEEE 802.1AX
*
* Input Arguments:
* tvb: buffer associated with the rcv packet (see tvbuff.h).
* pinfo: structure associated with the rcv packet (see packet_info.h).
* tree: the protocol tree associated with the rcv packet (see proto.h).
*
* Return Values: None
*
* Notes:
*/
static void
dissect_lacp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
int offset = 0;
guint16 raw_word;
guint8 raw_octet;
guint8 flags;
proto_tree *lacpdu_tree;
proto_item *lacpdu_item;
proto_tree *actor_flags_tree;
proto_item *actor_flags_item;
proto_tree *partner_flags_tree;
proto_item *partner_flags_item;
const char *sep;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "LACP");
col_set_str(pinfo->cinfo, COL_INFO, "Link Aggregation Control Protocol");
if (tree)
{
/* Add LACP Heading */
lacpdu_item = proto_tree_add_protocol_format(tree, proto_lacp, tvb,
0, -1, "Link Aggregation Control Protocol");
lacpdu_tree = proto_item_add_subtree(lacpdu_item, ett_lacp);
/* Version Number */
raw_octet = tvb_get_guint8(tvb, offset);
col_append_fstr(pinfo->cinfo, COL_INFO, "Version %d. ", raw_octet);
proto_tree_add_uint(lacpdu_tree, hf_lacp_version_number, tvb,
offset, 1, raw_octet);
offset += 1;
/* Actor Type */
proto_tree_add_item(lacpdu_tree, hf_lacp_actor_type, tvb,
offset, 1, ENC_NA);
offset += 1;
/* Actor Info Length */
proto_tree_add_item(lacpdu_tree, hf_lacp_actor_info_len, tvb,
offset, 1, ENC_NA);
offset += 1;
/* Actor System Priority */
proto_tree_add_item(lacpdu_tree, hf_lacp_actor_sys_priority, tvb,
offset, 2, ENC_BIG_ENDIAN);
offset += 2;
/* Actor System */
proto_tree_add_item(lacpdu_tree, hf_lacp_actor_sys, tvb,
offset, 6, ENC_NA);
offset += 6;
/* Actor Key */
proto_tree_add_item(lacpdu_tree, hf_lacp_actor_key, tvb,
offset, 2, ENC_BIG_ENDIAN);
offset += 2;
/* Actor Port Priority */
proto_tree_add_item(lacpdu_tree, hf_lacp_actor_port_priority, tvb,
offset, 2, ENC_BIG_ENDIAN);
offset += 2;
/* Actor Port */
raw_word = tvb_get_ntohs(tvb, offset);
col_append_fstr(pinfo->cinfo, COL_INFO, "Actor Port = %d ", raw_word);
proto_tree_add_uint(lacpdu_tree, hf_lacp_actor_port, tvb,
offset, 2, raw_word);
offset += 2;
/* Actor State */
flags = tvb_get_guint8(tvb, offset);
actor_flags_item = proto_tree_add_uint(lacpdu_tree, hf_lacp_actor_state, tvb,
offset, 1, flags);
actor_flags_tree = proto_item_add_subtree(actor_flags_item, ett_lacp_a_flags);
sep = initial_sep;
/* Activity Flag */
APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_ACTIVITY, actor_flags_item,
"%sActivity");
proto_tree_add_boolean(actor_flags_tree, hf_lacp_flags_a_activity, tvb,
offset, 1, flags);
/* Timeout Flag */
APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_TIMEOUT, actor_flags_item,
"%sTimeout");
proto_tree_add_boolean(actor_flags_tree, hf_lacp_flags_a_timeout, tvb,
offset, 1, flags);
/* Aggregation Flag */
APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_AGGREGATION, actor_flags_item,
"%sAggregation");
proto_tree_add_boolean(actor_flags_tree, hf_lacp_flags_a_aggregation, tvb,
offset, 1, flags);
/* Synchronization Flag */
APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_SYNC, actor_flags_item,
"%sSynchronization");
proto_tree_add_boolean(actor_flags_tree, hf_lacp_flags_a_sync, tvb,
offset, 1, flags);
/* Collecting Flag */
APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_COLLECTING, actor_flags_item,
"%sCollecting");
proto_tree_add_boolean(actor_flags_tree, hf_lacp_flags_a_collecting, tvb,
offset, 1, flags);
/* Distributing Flag */
APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_DISTRIB, actor_flags_item,
"%sDistributing");
proto_tree_add_boolean(actor_flags_tree, hf_lacp_flags_a_distrib, tvb,
offset, 1, flags);
/* Defaulted Flag */
APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_DEFAULTED, actor_flags_item,
"%sDefaulted");
proto_tree_add_boolean(actor_flags_tree, hf_lacp_flags_a_defaulted, tvb,
offset, 1, flags);
/* Expired Flag */
APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_EXPIRED, actor_flags_item,
"%sExpired");
proto_tree_add_boolean(actor_flags_tree, hf_lacp_flags_a_expired, tvb,
offset, 1, flags);
if (sep != initial_sep)
{
/* We put something in; put in the terminating ")" */
proto_item_append_text(actor_flags_item, ")");
}
offset += 1;
/* Actor Reserved */
proto_tree_add_item(lacpdu_tree, hf_lacp_actor_reserved, tvb,
offset, 3, ENC_NA);
offset += 3;
/* Partner Type */
proto_tree_add_item(lacpdu_tree, hf_lacp_partner_type, tvb,
offset, 1, ENC_NA);
offset += 1;
/* Partner Info Length */
proto_tree_add_item(lacpdu_tree, hf_lacp_partner_info_len, tvb,
offset, 1, ENC_NA);
offset += 1;
/* Partner System Priority */
proto_tree_add_item(lacpdu_tree, hf_lacp_partner_sys_priority, tvb,
offset, 2, ENC_BIG_ENDIAN);
offset += 2;
/* Partner System */
proto_tree_add_item(lacpdu_tree, hf_lacp_partner_sys, tvb,
offset, 6, ENC_NA);
offset += 6;
/* Partner Key */
proto_tree_add_item(lacpdu_tree, hf_lacp_partner_key, tvb,
offset, 2, ENC_BIG_ENDIAN);
offset += 2;
/* Partner Port Priority */
proto_tree_add_item(lacpdu_tree, hf_lacp_partner_port_priority, tvb,
offset, 2, ENC_BIG_ENDIAN);
offset += 2;
/* Partner Port */
raw_word = tvb_get_ntohs(tvb, offset);
col_append_fstr(pinfo->cinfo, COL_INFO, "Partner Port = %d ", raw_word);
proto_tree_add_uint(lacpdu_tree, hf_lacp_partner_port, tvb,
offset, 2, raw_word);
offset += 2;
/* Partner State */
flags = tvb_get_guint8(tvb, offset);
partner_flags_item = proto_tree_add_uint(lacpdu_tree, hf_lacp_partner_state, tvb,
offset, 1, flags);
partner_flags_tree = proto_item_add_subtree(partner_flags_item, ett_lacp_p_flags);
sep = initial_sep;
/* Activity Flag */
APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_ACTIVITY, partner_flags_item,
"%sActivity");
proto_tree_add_boolean(partner_flags_tree, hf_lacp_flags_p_activity, tvb,
offset, 1, flags);
/* Timeout Flag */
APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_TIMEOUT, partner_flags_item,
"%sTimeout");
proto_tree_add_boolean(partner_flags_tree, hf_lacp_flags_p_timeout, tvb,
offset, 1, flags);
/* Aggregation Flag */
APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_AGGREGATION, partner_flags_item,
"%sAggregation");
proto_tree_add_boolean(partner_flags_tree, hf_lacp_flags_p_aggregation, tvb,
offset, 1, flags);
/* Synchronization Flag */
APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_SYNC, partner_flags_item,
"%sSynchronization");
proto_tree_add_boolean(partner_flags_tree, hf_lacp_flags_p_sync, tvb,
offset, 1, flags);
/* Collecting Flag */
APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_COLLECTING, partner_flags_item,
"%sCollecting");
proto_tree_add_boolean(partner_flags_tree, hf_lacp_flags_p_collecting, tvb,
offset, 1, flags);
/* Distributing Flag */
APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_DISTRIB, partner_flags_item,
"%sDistributing");
proto_tree_add_boolean(partner_flags_tree, hf_lacp_flags_p_distrib, tvb,
offset, 1, flags);
/* Defaulted Flag */
APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_DEFAULTED, partner_flags_item,
"%sDefaulted");
proto_tree_add_boolean(partner_flags_tree, hf_lacp_flags_p_defaulted, tvb,
offset, 1, flags);
/* Expired Flag */
APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_EXPIRED, partner_flags_item,
"%sExpired");
proto_tree_add_boolean(partner_flags_tree, hf_lacp_flags_p_expired, tvb,
offset, 1, flags);
if (sep != initial_sep)
{
/* We put something in; put in the terminating ")" */
proto_item_append_text(partner_flags_item, ")");
}
offset += 1;
/* Partner Reserved */
proto_tree_add_item(lacpdu_tree, hf_lacp_partner_reserved, tvb,
offset, 3, ENC_NA);
offset += 3;
/* Collector Type */
proto_tree_add_item(lacpdu_tree, hf_lacp_coll_type, tvb,
offset, 1, ENC_NA);
offset += 1;
/* Collector Info Length */
proto_tree_add_item(lacpdu_tree, hf_lacp_coll_info_len, tvb,
offset, 1, ENC_NA);
offset += 1;
/* Collector Max Delay */
proto_tree_add_item(lacpdu_tree, hf_lacp_coll_max_delay, tvb,
offset, 2, ENC_BIG_ENDIAN);
offset += 2;
/* Collector Reserved */
proto_tree_add_item(lacpdu_tree, hf_lacp_coll_reserved, tvb,
offset, 12, ENC_NA);
offset += 12;
/* Terminator Type */
proto_tree_add_item(lacpdu_tree, hf_lacp_term_type, tvb,
offset, 1, ENC_NA);
offset += 1;
/* Terminator Info Length */
proto_tree_add_item(lacpdu_tree, hf_lacp_term_len, tvb,
offset, 1, ENC_NA);
offset += 1;
/* Terminator Reserved */
proto_tree_add_item(lacpdu_tree, hf_lacp_term_reserved, tvb,
offset, 50, ENC_NA);
}
}
/* Register the protocol with Wireshark */
void
proto_register_lacp(void)
{
/* Setup list of header fields */
static hf_register_info hf[] = {
{ &hf_lacp_version_number,
{ "LACP Version Number", "lacp.version",
FT_UINT8, BASE_HEX, NULL, 0x0,
"Identifies the LACP version", HFILL }},
{ &hf_lacp_actor_type,
{ "Actor Information", "lacp.actorInfo",
FT_UINT8, BASE_HEX, NULL, 0x0,
"TLV type = Actor", HFILL }},
{ &hf_lacp_actor_info_len,
{ "Actor Information Length", "lacp.actorInfoLen",
FT_UINT8, BASE_HEX, NULL, 0x0,
"The length of the Actor TLV", HFILL }},
{ &hf_lacp_actor_sys_priority,
{ "Actor System Priority", "lacp.actorSysPriority",
FT_UINT16, BASE_DEC, NULL, 0x0,
"The priority assigned to this System by management or admin", HFILL }},
{ &hf_lacp_actor_sys,
{ "Actor System", "lacp.actorSystem",
FT_ETHER, BASE_NONE, NULL, 0x0,
"The Actor's System ID encoded as a MAC address", HFILL }},
{ &hf_lacp_actor_key,
{ "Actor Key", "lacp.actorKey",
FT_UINT16, BASE_DEC, NULL, 0x0,
"The operational Key value assigned to the port by the Actor", HFILL }},
{ &hf_lacp_actor_port_priority,
{ "Actor Port Priority", "lacp.actorPortPriority",
FT_UINT16, BASE_DEC, NULL, 0x0,
"The priority assigned to the port by the Actor (via Management or Admin)", HFILL }},
{ &hf_lacp_actor_port,
{ "Actor Port", "lacp.actorPort",
FT_UINT16, BASE_DEC, NULL, 0x0,
"The port number assigned to the port by the Actor (via Management or Admin)", HFILL }},
{ &hf_lacp_actor_state,
{ "Actor State", "lacp.actorState",
FT_UINT8, BASE_HEX, NULL, 0x0,
"The Actor's state variables for the port, encoded as bits within a single octet", HFILL }},
{ &hf_lacp_flags_a_activity,
{ "LACP Activity", "lacp.actorState.activity",
FT_BOOLEAN, 8, TFS(&tfs_yes_no), LACPDU_FLAGS_ACTIVITY,
"Activity control value for this link. Active = 1, Passive = 0", HFILL }},
{ &hf_lacp_flags_a_timeout,
{ "LACP Timeout", "lacp.actorState.timeout",
FT_BOOLEAN, 8, TFS(&tfs_yes_no), LACPDU_FLAGS_TIMEOUT,
"Timeout control value for this link. Short Timeout = 1, Long Timeout = 0", HFILL }},
{ &hf_lacp_flags_a_aggregation,
{ "Aggregation", "lacp.actorState.aggregation",
FT_BOOLEAN, 8, TFS(&tfs_yes_no), LACPDU_FLAGS_AGGREGATION,
"Aggregatable = 1, Individual = 0", HFILL }},
{ &hf_lacp_flags_a_sync,
{ "Synchronization", "lacp.actorState.synchronization",
FT_BOOLEAN, 8, TFS(&tfs_yes_no), LACPDU_FLAGS_SYNC,
"In Sync = 1, Out of Sync = 0", HFILL }},
{ &hf_lacp_flags_a_collecting,
{ "Collecting", "lacp.actorState.collecting",
FT_BOOLEAN, 8, TFS(&tfs_yes_no), LACPDU_FLAGS_COLLECTING,
"Collection of incoming frames is: Enabled = 1, Disabled = 0", HFILL }},
{ &hf_lacp_flags_a_distrib,
{ "Distributing", "lacp.actorState.distributing",
FT_BOOLEAN, 8, TFS(&tfs_yes_no), LACPDU_FLAGS_DISTRIB,
"Distribution of outgoing frames is: Enabled = 1, Disabled = 0", HFILL }},
{ &hf_lacp_flags_a_defaulted,
{ "Defaulted", "lacp.actorState.defaulted",
FT_BOOLEAN, 8, TFS(&tfs_yes_no), LACPDU_FLAGS_DEFAULTED,
"1 = Actor Rx machine is using DEFAULT Partner info, 0 = using info in Rx'd LACPDU", HFILL }},
{ &hf_lacp_flags_a_expired,
{ "Expired", "lacp.actorState.expired",
FT_BOOLEAN, 8, TFS(&tfs_yes_no), LACPDU_FLAGS_EXPIRED,
"1 = Actor Rx machine is EXPIRED, 0 = is NOT EXPIRED", HFILL }},
{ &hf_lacp_actor_reserved,
{ "Reserved", "lacp.reserved",
FT_BYTES, BASE_NONE, NULL, 0x0,
NULL, HFILL }},
{ &hf_lacp_partner_type,
{ "Partner Information", "lacp.partnerInfo",
FT_UINT8, BASE_HEX, NULL, 0x0,
"TLV type = Partner", HFILL }},
{ &hf_lacp_partner_info_len,
{ "Partner Information Length", "lacp.partnerInfoLen",
FT_UINT8, BASE_HEX, NULL, 0x0,
"The length of the Partner TLV", HFILL }},
{ &hf_lacp_partner_sys_priority,
{ "Partner System Priority", "lacp.partnerSysPriority",
FT_UINT16, BASE_DEC, NULL, 0x0,
"The priority assigned to the Partner System by management or admin", HFILL }},
{ &hf_lacp_partner_sys,
{ "Partner System", "lacp.partnerSystem",
FT_ETHER, BASE_NONE, NULL, 0x0,
"The Partner's System ID encoded as a MAC address", HFILL }},
{ &hf_lacp_partner_key,
{ "Partner Key", "lacp.partnerKey",
FT_UINT16, BASE_DEC, NULL, 0x0,
"The operational Key value assigned to the port associated with this link by the Partner", HFILL }},
{ &hf_lacp_partner_port_priority,
{ "Partner Port Priority", "lacp.partnerPortPriority",
FT_UINT16, BASE_DEC, NULL, 0x0,
"The priority assigned to the port by the Partner (via Management or Admin)", HFILL }},
{ &hf_lacp_partner_port,
{ "Partner Port", "lacp.partnerPort",
FT_UINT16, BASE_DEC, NULL, 0x0,
"The port number associated with this link assigned to the port by the Partner (via Management or Admin)", HFILL }},
{ &hf_lacp_partner_state,
{ "Partner State", "lacp.partnerState",
FT_UINT8, BASE_HEX, NULL, 0x0,
"The Partner's state variables for the port, encoded as bits within a single octet", HFILL }},
{ &hf_lacp_flags_p_activity,
{ "LACP Activity", "lacp.partnerState.activity",
FT_BOOLEAN, 8, TFS(&tfs_yes_no), LACPDU_FLAGS_ACTIVITY,
"Activity control value for this link. Active = 1, Passive = 0", HFILL }},
{ &hf_lacp_flags_p_timeout,
{ "LACP Timeout", "lacp.partnerState.timeout",
FT_BOOLEAN, 8, TFS(&tfs_yes_no), LACPDU_FLAGS_TIMEOUT,
"Timeout control value for this link. Short Timeout = 1, Long Timeout = 0", HFILL }},
{ &hf_lacp_flags_p_aggregation,
{ "Aggregation", "lacp.partnerState.aggregation",
FT_BOOLEAN, 8, TFS(&tfs_yes_no), LACPDU_FLAGS_AGGREGATION,
"Aggregatable = 1, Individual = 0", HFILL }},
{ &hf_lacp_flags_p_sync,
{ "Synchronization", "lacp.partnerState.synchronization",
FT_BOOLEAN, 8, TFS(&tfs_yes_no), LACPDU_FLAGS_SYNC,
"In Sync = 1, Out of Sync = 0", HFILL }},
{ &hf_lacp_flags_p_collecting,
{ "Collecting", "lacp.partnerState.collecting",
FT_BOOLEAN, 8, TFS(&tfs_yes_no), LACPDU_FLAGS_COLLECTING,
"Collection of incoming frames is: Enabled = 1, Disabled = 0", HFILL }},
{ &hf_lacp_flags_p_distrib,
{ "Distributing", "lacp.partnerState.distributing",
FT_BOOLEAN, 8, TFS(&tfs_yes_no), LACPDU_FLAGS_DISTRIB,
"Distribution of outgoing frames is: Enabled = 1, Disabled = 0", HFILL }},
{ &hf_lacp_flags_p_defaulted,
{ "Defaulted", "lacp.partnerState.defaulted",
FT_BOOLEAN, 8, TFS(&tfs_yes_no), LACPDU_FLAGS_DEFAULTED,
"1 = Actor Rx machine is using DEFAULT Partner info, 0 = using info in Rx'd LACPDU", HFILL }},
{ &hf_lacp_flags_p_expired,
{ "Expired", "lacp.partnerState.expired",
FT_BOOLEAN, 8, TFS(&tfs_yes_no), LACPDU_FLAGS_EXPIRED,
"1 = Actor Rx machine is EXPIRED, 0 = is NOT EXPIRED", HFILL }},
{ &hf_lacp_partner_reserved,
{ "Reserved", "lacp.reserved",
FT_BYTES, BASE_NONE, NULL, 0x0,
NULL, HFILL }},
{ &hf_lacp_coll_type,
{ "Collector Information", "lacp.collectorInfo",
FT_UINT8, BASE_HEX, NULL, 0x0,
"TLV type = Collector", HFILL }},
{ &hf_lacp_coll_info_len,
{ "Collector Information Length", "lacp.collectorInfoLen",
FT_UINT8, BASE_HEX, NULL, 0x0,
"The length of the Collector TLV", HFILL }},
{ &hf_lacp_coll_max_delay,
{ "Collector Max Delay", "lacp.collectorMaxDelay",
FT_UINT16, BASE_DEC, NULL, 0x0,
"The max delay of the station tx'ing the LACPDU (in tens of usecs)", HFILL }},
{ &hf_lacp_coll_reserved,
{ "Reserved", "lacp.coll_reserved",
FT_BYTES, BASE_NONE, NULL, 0x0,
NULL, HFILL }},
{ &hf_lacp_term_type,
{ "Terminator Information", "lacp.termInfo",
FT_UINT8, BASE_HEX, NULL, 0x0,
"TLV type = Terminator", HFILL }},
{ &hf_lacp_term_len,
{ "Terminator Length", "lacp.termLen",
FT_UINT8, BASE_HEX, NULL, 0x0,
"The length of the Terminator TLV", HFILL }},
{ &hf_lacp_term_reserved,
{ "Reserved", "lacp.term_reserved",
FT_BYTES, BASE_NONE, NULL, 0x0,
NULL, HFILL }},
};
/* Setup protocol subtree array */
static gint *ett[] = {
&ett_lacp,
&ett_lacp_a_flags,
&ett_lacp_p_flags,
};
/* Register the protocol name and description */
proto_lacp = proto_register_protocol("LACP", "Link Aggregation Control Protocol", "lacp");
/* Required function calls to register the header fields and subtrees used */
proto_register_field_array(proto_lacp, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
}
void
proto_reg_handoff_lacp(void)
{
dissector_handle_t lacp_handle;
lacp_handle = create_dissector_handle(dissect_lacp, proto_lacp);
dissector_add_uint("slow.subtype", LACP_SUBTYPE, lacp_handle);
}

View File

@ -0,0 +1,204 @@
/* packet-marker.c
* Routines for Link Aggregation Marker protocol dissection.
* IEEE Std 802.1AX
*
* Copyright 2002 Steve Housley <steve_housley@3com.com>
* Copyright 2005 Dominique Bastien <dbastien@accedian.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* 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/slow_protocol_subtypes.h>
/* General declarations */
void proto_register_marker(void);
void proto_reg_handoff_marker(void);
/* MARKER TLVs subtype */
#define MARKERPDU_END_MARKER 0x0
#define MARKERPDU_MARKER_INFO 0x1
#define MARKERPDU_MARKER_RESPONSE 0x2
static const value_string marker_vals[] = {
{ MARKERPDU_MARKER_INFO, "Marker Information" },
{ MARKERPDU_MARKER_RESPONSE, "Marker Response Information" },
{ 0, NULL }
};
/* Initialise the protocol and registered fields */
static int proto_marker = -1;
static int hf_marker_version_number = -1;
static int hf_marker_tlv_type = -1;
static int hf_marker_tlv_length = -1;
static int hf_marker_req_port = -1;
static int hf_marker_req_system = -1;
static int hf_marker_req_trans_id = -1;
/* Initialise the subtree pointers */
static gint ett_marker = -1;
/*
* Name: dissect_marker
*
* Description:
* This function is used to dissect the Link Aggregation Marker Protocol
* slow protocols defined in IEEE802.3 clause 43.5 (The PDUs are defined
* in section 43.5.3.2). The TLV types are 0x01 for a marker TLV and 0x02
* for a marker response. A value of 0x00 indicates an end of message.
*
* Input Arguments:
* tvb: buffer associated with the rcv packet (see tvbuff.h).
* pinfo: structure associated with the rcv packet (see packet_info.h).
* tree: the protocol tree associated with the rcv packet (see proto.h).
*
* Return Values: None
*
* Notes:
* Dominique Bastien (dbastien@accedian.com)
* + add support for MARKER and MARKER Response PDUs.
*/
static void
dissect_marker(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
int offset = 0;
guint8 raw_octet;
proto_tree *marker_tree;
proto_item *marker_item;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "Marker");
col_set_str(pinfo->cinfo, COL_INFO, "Marker Protocol");
if (tree)
{
marker_item = proto_tree_add_protocol_format(tree, proto_marker, tvb,
0, -1, "Marker Protocol");
marker_tree = proto_item_add_subtree(marker_item, ett_marker);
/* Version Number */
proto_tree_add_item(marker_tree, hf_marker_version_number, tvb,
offset, 1, ENC_NA);
offset += 1;
while (1)
{
/* TLV Type */
raw_octet = tvb_get_guint8(tvb, offset);
if (raw_octet == MARKERPDU_END_MARKER)
break;
proto_tree_add_uint(marker_tree, hf_marker_tlv_type, tvb,
offset, 1, raw_octet);
offset += 1;
/* TLV Length */
proto_tree_add_item(marker_tree, hf_marker_tlv_length, tvb,
offset, 1, ENC_NA);
offset += 1;
/* Requester Port */
proto_tree_add_item(marker_tree, hf_marker_req_port, tvb,
offset, 2, ENC_BIG_ENDIAN);
offset += 2;
/* Requester System */
proto_tree_add_item(marker_tree, hf_marker_req_system, tvb,
offset, 6, ENC_NA);
offset += 6;
/* Requester Transaction ID */
proto_tree_add_item(marker_tree, hf_marker_req_trans_id, tvb,
offset, 4, ENC_BIG_ENDIAN);
offset += 4;
/* Pad to align */
offset += 2;
}
}
}
/* Register the protocol with Wireshark */
void
proto_register_marker(void)
{
/* Setup list of header fields */
static hf_register_info hf[] = {
{ &hf_marker_version_number,
{ "Version Number", "marker.version",
FT_UINT8, BASE_HEX, NULL, 0x0,
"Marker protocol version", HFILL }},
{ &hf_marker_tlv_type,
{ "TLV Type", "marker.tlvType",
FT_UINT8, BASE_HEX, VALS(marker_vals), 0x0,
NULL, HFILL }},
{ &hf_marker_tlv_length,
{ "TLV Length", "marker.tlvLen",
FT_UINT8, BASE_HEX, NULL, 0x0,
"Length of the Actor TLV", HFILL }},
{ &hf_marker_req_port,
{ "Requester Port", "marker.requesterPort",
FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL }},
{ &hf_marker_req_system,
{ "Requester System", "marker.requesterSystem",
FT_ETHER, BASE_NONE, NULL, 0x0,
"Requester System ID encoded as a MAC address", HFILL }},
{ &hf_marker_req_trans_id,
{ "Requester Transaction ID", "marker.requesterTransId",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }},
};
/* Setup protocol subtree array */
static gint *ett[] = {
&ett_marker,
};
/* Register the protocol name and description */
proto_marker = proto_register_protocol("Marker", "Link Aggregation Marker Protocol", "marker");
/* Required function calls to register the header fields and subtrees used */
proto_register_field_array(proto_marker, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
}
void
proto_reg_handoff_marker(void)
{
dissector_handle_t marker_handle;
marker_handle = create_dissector_handle(dissect_marker, proto_marker);
dissector_add_uint("slow.subtype", MARKER_SUBTYPE, marker_handle);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,696 @@
/* packet-ossp.c
* Routines for Organization Specific Slow Protocol dissection
* IEEE Std 802.3, Annex 57B
*
* Copyright 2002 Steve Housley <steve_housley@3com.com>
* Copyright 2009 Artem Tamazov <artem.tamazov@telllabs.com>
* Copyright 2010 Roberto Morro <roberto.morro[AT]tilab.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* 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/slow_protocol_subtypes.h>
#include <epan/addr_resolv.h>
#include <epan/expert.h>
/* General declarations */
void proto_register_ossp(void);
void proto_reg_handoff_ossp(void);
/*
* ESMC
*/
#define ITU_OUI_0 0x00
#define ITU_OUI_1 0x19
#define ITU_OUI_2 0xa7
#define OUI_SIZE 3
#define ESMC_ITU_SUBTYPE 0x0001
#define ESMC_VERSION_1 0x01
#define ESMC_QL_TLV_TYPE 0x01
#define ESMC_QL_TLV_LENGTH 0x04
#define ESMC_TIMESTAMP_TLV_TYPE 0x02
#define ESMC_TIMESTAMP_TLV_LENGTH 0x08
static const value_string esmc_event_flag_vals[] = {
{ 0, "Information ESMC PDU" },
{ 1, "Time-critical Event ESMC PDU" },
{ 0, NULL }
};
static const value_string esmc_tlv_type_vals[] = {
{ 1, "Quality Level" },
{ 2, "Timestamp" },
{ 0, NULL }
};
static const value_string esmc_timestamp_valid_flag_vals[] = {
{ 0, "Not set. Do not use Timestamp value even if Timestamp TLV present" },
{ 1, "Set. Timestamp TLV Present" },
{ 0, NULL }
};
/* G.781 5.5.1.1 Option I SDH (same in G.707) */
static const value_string esmc_quality_level_opt_1_vals[] = {
{ 2, "QL-PRC, Primary reference clock (G.811)" },
{ 4, "QL-SSU-A, Type I or V SSU clock (G.812), 'transit node clock'" },
{ 8, "QL-SSU-B, Type VI SSU clock (G.812), 'local node clock'" },
{ 11, "QL-SEC, SEC clock (G.813, Option I) or QL-EEC1 (G.8262)" },
{ 15, "QL-DNU, 'Do Not Use'" },
{ 0, NULL }
};
static const value_string esmc_quality_level_opt_1_vals_short[] = {
{ 2, "QL-PRC" },
{ 4, "QL-SSU-A" },
{ 8, "QL-SSU-B" },
{ 11, "QL-SEC" },
{ 15, "QL-DNU" },
{ 0, NULL }
};
#if 0 /*not used yet*/
/* G.781 5.5.1.2 Option II SDH synchronization networking */
static const value_string esmc_quality_level_opt_2_vals[] = {
{ 0, "QL-STU, unknown - signal does not carry the QL message of the source" },
{ 1, "QL-PRS, PRS clock (G.811) / ST1, Stratum 1 Traceable" },
{ 4, "QL-TNC, Transit Node Clock (G.812, Type V)" },
{ 7, "QL-ST2, Stratum 2 clock (G.812, Type II)" },
{ 10, "QL-ST3, Stratum 3 clock (G.812, Type IV) or QL-EEC2 (G.8262)" },
{ 12, "QL-SMC, SONET self timed clock (G.813, Option II) / SMC 20 ppm Clock Traceable" },
{ 13, "QL-ST3E, Stratum 3E clock (G.812, Type III)" },
{ 14, "QL-PROV, provisionable by the network operator / Reserved for Network Synchronization" },
{ 15, "QL-DUS, shall not be used for synchronization" },
{ 0, NULL }
};
static const value_string esmc_quality_level_opt_2_short[] = {
{ 0, "QL-STU" },
{ 1, "QL-PRS" },
{ 4, "QL-TNC" },
{ 7, "QL-ST2" },
{ 10, "QL-ST3" },
{ 12, "QL-SMC" },
{ 13, "QL-ST3E" },
{ 14, "QL-PROV" },
{ 15, "QL-DUS" },
{ 0, NULL }
};
#endif
static const value_string esmc_quality_level_invalid_vals[] = {
{ 0, "QL-INV0" },
{ 1, "QL-INV1" },
{ 2, "QL-INV2" },
{ 3, "QL-INV3" },
{ 4, "QL-INV4" },
{ 5, "QL-INV5" },
{ 6, "QL-INV6" },
{ 7, "QL-INV7" },
{ 8, "QL-INV8" },
{ 9, "QL-INV9" },
{ 10, "QL-INV10" },
{ 11, "QL-INV11" },
{ 12, "QL-INV12" },
{ 13, "QL-INV13" },
{ 14, "QL-INV14" },
{ 15, "QL-INV15" },
{ 0, NULL }
};
/* Initialise the protocol and registered fields */
static int proto_ossp = -1;
static int hf_ossp_oui = -1;
static int hf_itu_subtype = -1;
static int hf_esmc_version = -1;
static int hf_esmc_event_flag = -1;
static int hf_esmc_timestamp_valid_flag = -1;
static int hf_esmc_reserved_32 = -1;
static int hf_esmc_tlv = -1;
static int hf_esmc_tlv_type = -1;
static int hf_esmc_tlv_length = -1;
static int hf_esmc_tlv_ql_unused = -1;
static int hf_esmc_tlv_ts_reserved = -1;
static int hf_esmc_quality_level_opt_1 = -1;
#if 0 /*not used yet*/
static int hf_esmc_quality_level_opt_2 = -1;
#endif
static int hf_esmc_quality_level_invalid = -1;
static int hf_esmc_timestamp = -1;
static int hf_esmc_padding = -1;
/*
* The Timestamp TLV and Timestamp Valid Flag fields
* are proposed in WD56 document for G.8264.
* WD56 is not accepted at this moment (June 2009).
*
* The following variable controls dissection of Timestamp fields.
* Implementation is not fully complete yet -- in this version
* Timestamp dissection is always enabled.
*
* I expect that when WD56 proposal for G.8264 will be accepted,
* ESMC Version would be used to control Timestamp dissection.
* In this case this variable will be eliminated (replaced).
*
* Until that, a preference which controls Timestamp
* dissection may be added, if such need arise.
* At the moment this is not practical as nobody needs this.
*/
static gboolean pref_decode_esmc_timestamp = TRUE;
/* Initialise the subtree pointers */
static gint ett_ossppdu = -1;
static gint ett_itu_ossp = -1;
static gint ett_esmc = -1;
static expert_field ei_esmc_tlv_type_ql_type_not_first = EI_INIT;
static expert_field ei_esmc_tlv_type_not_timestamp = EI_INIT;
static expert_field ei_esmc_quality_level_invalid = EI_INIT;
static expert_field ei_esmc_tlv_ql_unused_not_zero = EI_INIT;
static expert_field ei_esmc_tlv_type_decoded_as_timestamp = EI_INIT;
static expert_field ei_esmc_tlv_type_decoded_as_ql_type = EI_INIT;
static expert_field ei_esmc_version_compliance = EI_INIT;
static expert_field ei_esmc_tlv_length_bad = EI_INIT;
static expert_field ei_esmc_reserved_not_zero = EI_INIT;
static dissector_handle_t dh_data;
static void
dissect_esmc_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *treex);
static void
dissect_itu_ossp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
/*
* Name: dissect_ossp_pdu
*
* Description:
* This function is used to dissect the Organization Specific Slow
* Protocol defined in IEEE 802.3 Annex 57B. Currently only the ESMC
* slow protocol as defined in ITU-T G.8264 is implemented
*
* Input Arguments:
* tvb: buffer associated with the rcv packet (see tvbuff.h).
* pinfo: structure associated with the rcv packet (see packet_info.h).
* tree: the protocol tree associated with the rcv packet (see proto.h).
*
* Return Values: None
*
* Notes:
* Roberto Morro (roberto.morro[AT]tilab.com)
*/
static void
dissect_ossp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
gint offset = 0;
const gchar *str;
proto_item *oui_item, *ossp_item;
proto_tree *ossp_tree;
tvbuff_t *ossp_tvb;
const guint8 itu_oui[] = {ITU_OUI_0, ITU_OUI_1, ITU_OUI_2};
/* OUI of the organization defining the protocol */
str = tvb_get_manuf_name(tvb, offset+1);
col_set_str(pinfo->cinfo, COL_PROTOCOL, "OSSP");
col_add_fstr(pinfo->cinfo, COL_INFO, "OUI: %s", str);
ossp_item = proto_tree_add_protocol_format(tree, proto_ossp, tvb, 0, -1,
"Organization Specific Slow Protocol");
ossp_tree = proto_item_add_subtree(ossp_item, ett_ossppdu);
oui_item = proto_tree_add_item(ossp_tree, hf_ossp_oui,
tvb, offset, OUI_SIZE, ENC_NA);
proto_item_append_text(oui_item, " (%s)", str);
offset += 3;
/*
* XXX - should have a dissector table here, but we don't yet
* support OUIs as keys in dissector tables.
*/
ossp_tvb = tvb_new_subset_remaining(tvb, offset);
if (tvb_memeql(tvb, 1, itu_oui, OUI_SIZE) == 0)
{
dissect_itu_ossp(ossp_tvb, pinfo, ossp_tree);
}
/* new Organization Specific Slow Protocols go hereafter */
#if 0
else if (tvb_memeql(tvb, 1, xxx_oui, OUI_SIZE) == 0)
{
dissect_xxx_ossp(ossp_tvb, pinfo, ossp_tree);
}
else if (tvb_memeql(tvb, 1, yyy_oui, OUI_SIZE) == 0)
{
dissect_yyy_ossp(ossp_tvb, pinfo, ossp_tree);
}
#endif
else
{
proto_item_append_text(oui_item, " (Unknown OSSP organization)");
}
}
/*
* Name: dissect_itu_ossp
*
* Description:
* This function is used to dissect the ITU-T OSSP (Organization Specific
* Slow Protocol). Currently only the Ethernet Synchronization
* Messaging Channel (ESMC) slow protocol as defined in ITU-T G.8264
* is implemented
*
* Input Arguments:
* tvb: buffer associated with the rcv packet (see tvbuff.h).
* pinfo: structure associated with the rcv packet (see packet_info.h).
* tree: the protocol tree associated with the rcv packet (see proto.h).
* subtype: the protocol subtype (according to IEEE802.3 annex 57B)
*
* Return Values: None
*
* Notes:
* Roberto Morro (roberto.morro[AT]tilab.com)
*/
static void
dissect_itu_ossp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
guint16 subtype;
proto_tree *itu_ossp_tree, *ti;
/* ITU-T OSSP Subtype */
subtype = tvb_get_ntohs(tvb, 0);
ti = proto_tree_add_item(tree, hf_itu_subtype, tvb, 0, 2, ENC_BIG_ENDIAN);
itu_ossp_tree = proto_item_add_subtree(ti, ett_itu_ossp);
switch (subtype)
{
case ESMC_ITU_SUBTYPE:
dissect_esmc_pdu(tvb, pinfo, itu_ossp_tree);
break;
/* Other ITU-T defined slow protocols go hereafter */
#if 0
case XXXX_ITU_SUBTYPE:
dissect_xxxx_pdu(tvb, pinfo, itu_ossp_tree);
break;
#endif
default:
proto_item_append_text(itu_ossp_tree, " (Unknown)");
}
}
/*
* Description:
* This function is used to dissect ESMC PDU defined G.8264/Y.1364
* clause 11.3.1.1.
*
* Added: TimeStamp TLV as per WD56 proposal for G.8264,
* "TLVs for ESMC and Querying Capability".
*/
static void
dissect_esmc_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *treex)
{
gint offset = 2; /*starting from ESMC Version */
gboolean event_flag;
gboolean malformed = FALSE;
gint ql = -1; /*negative means unknown:*/
gboolean timestamp_valid_flag = FALSE; /*set if timestamp valid*/
gint32 timestamp = -1; /*nanoseconds*/
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ESMC");
proto_item_append_text(treex, ": ESMC");
{
proto_tree *tree_a;
tree_a = proto_item_add_subtree(treex, ett_esmc);
{ /* version */
proto_item *item_b;
item_b = proto_tree_add_item(tree_a, hf_esmc_version, tvb, offset, 1, ENC_BIG_ENDIAN);
if ((tvb_get_guint8(tvb, offset) >> 4) != ESMC_VERSION_1)
{
malformed = TRUE;
expert_add_info_format(pinfo, item_b, &ei_esmc_version_compliance, "Version must be 0x%.1x claim compliance with Version 1 of this protocol", ESMC_VERSION_1);
}
/*stay at the same octet in tvb*/
}
{ /* event flag */
event_flag = ((tvb_get_guint8(tvb, offset) & 0x08) != 0);
proto_tree_add_item(tree_a, hf_esmc_event_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
/*stay at the same octet in tvb*/
}
if (pref_decode_esmc_timestamp)
{ /* timestamp valid flag */
timestamp_valid_flag = ((tvb_get_guint8(tvb, offset) & 0x04) != 0);
proto_tree_add_item(tree_a, hf_esmc_timestamp_valid_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
/*stay at the same octet in tvb*/
}
{ /* reserved bits */
proto_item *item_b;
guint32 reserved;
reserved = tvb_get_ntohl(tvb, offset)
& (pref_decode_esmc_timestamp ? 0x3ffffff : 0x7ffffff);
item_b = proto_tree_add_uint_format_value(tree_a, hf_esmc_reserved_32, tvb, offset, 4
, reserved, "0x%.7x", reserved);
if (reserved != 0x0)
{
malformed = TRUE;
expert_add_info_format(pinfo, item_b, &ei_esmc_reserved_not_zero, "Reserved bits must be set to all zero on transmitter");
}
offset += 4;
}
proto_item_append_text(treex, ", Event:%s", event_flag ?
"Time-critical" : "Information");
/*
* Quality Level TLV is mandatory at fixed location.
*/
{
proto_item *item_b;
guint8 type;
item_b = proto_tree_add_item(tree_a, hf_esmc_tlv, tvb, offset, 4, ENC_NA);
{
proto_tree *tree_b;
tree_b = proto_item_add_subtree(item_b, ett_esmc);
{
proto_item *item_c;
guint16 length;
guint8 unused;
/* type */
type = tvb_get_guint8(tvb, offset);
item_c = proto_tree_add_item(tree_b, hf_esmc_tlv_type, tvb, offset, 1, ENC_BIG_ENDIAN);
if (type != ESMC_QL_TLV_TYPE)
{
malformed = TRUE;
expert_add_info_format(pinfo, item_c, &ei_esmc_tlv_type_ql_type_not_first, "TLV Type must be == 0x%.2x (QL) because QL TLV must be first in the ESMC PDU", ESMC_QL_TLV_TYPE);
expert_add_info(pinfo, item_c, &ei_esmc_tlv_type_decoded_as_ql_type);
}
offset += 1;
/* length */
length = tvb_get_ntohs(tvb, offset);
item_c = proto_tree_add_item(tree_b, hf_esmc_tlv_length, tvb, offset, 2, ENC_BIG_ENDIAN);
if (length != ESMC_QL_TLV_LENGTH)
{
malformed = TRUE;
expert_add_info_format(pinfo, item_c, &ei_esmc_tlv_length_bad, "QL TLV Length must be == 0x%.4x", ESMC_QL_TLV_LENGTH);
expert_add_info_format(pinfo, item_c, &ei_esmc_tlv_type_decoded_as_ql_type, "Let's decode this TLV as if Length has valid value");
}
offset += 2;
/* value */
unused = tvb_get_guint8(tvb, offset); /*as temp var*/
ql = unused & 0x0f;
unused &= 0xf0;
item_c = proto_tree_add_item(tree_b, hf_esmc_tlv_ql_unused, tvb, offset, 1, ENC_BIG_ENDIAN);
if (unused != 0x00)
{
malformed = TRUE;
expert_add_info(pinfo, item_c, &ei_esmc_tlv_ql_unused_not_zero);
}
if (NULL != try_val_to_str(ql, esmc_quality_level_opt_1_vals))
{
proto_tree_add_item(tree_b, hf_esmc_quality_level_opt_1, tvb, offset, 1, ENC_BIG_ENDIAN);
}
else
{
item_c = proto_tree_add_item(tree_b, hf_esmc_quality_level_invalid, tvb, offset, 1, ENC_BIG_ENDIAN);
expert_add_info(pinfo, item_c, &ei_esmc_quality_level_invalid);
}
offset += 1;
}
}
proto_item_append_text(item_b, ", %s"
, val_to_str(ql, esmc_quality_level_opt_1_vals_short, "QL-INV%d"));
}
proto_item_append_text(treex, ", %s"
, val_to_str(ql, esmc_quality_level_opt_1_vals_short, "QL-INV%d"));
if (pref_decode_esmc_timestamp)
{
/*
* Timestamp TLV is optional at fixed location.
* Decode it if Timestamp Valid flag is set,
* or if type of next TLV is 0x02.
*/
guint8 type;
type = tvb_get_guint8(tvb, offset);
if (timestamp_valid_flag || type == ESMC_TIMESTAMP_TLV_TYPE)
{
proto_item *item_b;
item_b = proto_tree_add_item(tree_a, hf_esmc_tlv, tvb, offset, 8, ENC_NA);
{
proto_tree *tree_b;
tree_b = proto_item_add_subtree(item_b, ett_esmc);
{
proto_item *item_c;
guint16 length;
guint8 reserved;
/* type */
item_c = proto_tree_add_item(tree_b, hf_esmc_tlv_type, tvb, offset, 1, ENC_BIG_ENDIAN);
if (type != ESMC_TIMESTAMP_TLV_TYPE)
{
malformed = TRUE;
expert_add_info_format(pinfo, item_c, &ei_esmc_tlv_type_not_timestamp, "TLV Type must be == 0x%.2x (Timestamp) because Timestamp Valid Flag is set", ESMC_TIMESTAMP_TLV_TYPE);
expert_add_info(pinfo, item_c, &ei_esmc_tlv_type_decoded_as_timestamp);
}
offset += 1;
/* length */
length = tvb_get_ntohs(tvb, offset);
item_c = proto_tree_add_item(tree_b, hf_esmc_tlv_length, tvb, offset, 2, ENC_BIG_ENDIAN);
if (length != ESMC_TIMESTAMP_TLV_LENGTH)
{
malformed = TRUE;
expert_add_info_format(pinfo, item_c, &ei_esmc_tlv_length_bad, "Timestamp TLV Length must be == 0x%.4x", ESMC_TIMESTAMP_TLV_LENGTH);
expert_add_info_format(pinfo, item_c, &ei_esmc_tlv_type_decoded_as_timestamp, "Let's decode this TLV as if Length has valid value");
}
offset += 2;
/* value */
timestamp = (gint32)tvb_get_ntohl(tvb, offset);
item_c = proto_tree_add_item(tree_b, hf_esmc_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
if (!timestamp_valid_flag) proto_item_append_text(item_c, " [invalid]");
offset += 4;
/* reserved */
reserved = tvb_get_guint8(tvb, offset);
item_c = proto_tree_add_item(tree_b, hf_esmc_tlv_ts_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
if (reserved != 0x0)
{
expert_add_info(pinfo, item_c, &ei_esmc_reserved_not_zero);
}
offset += 1;
}
}
proto_item_append_text(item_b, ", Timestamp: %d ns", timestamp);
if (!timestamp_valid_flag) proto_item_append_text(item_b, " [invalid]");
}
}
if (timestamp_valid_flag)
{
proto_item_append_text(treex, ", Timestamp:%d", timestamp);
}
}
{ /* padding */
gint padding_size;
padding_size = tvb_captured_length_remaining(tvb, offset);
if (0 != padding_size)
{
proto_tree* tree_a;
tree_a = proto_item_add_subtree(treex, ett_esmc);
{
proto_item* item_b;
tvbuff_t* tvb_next;
tvb_next = tvb_new_subset(tvb, offset, padding_size, -1);
item_b = proto_tree_add_item(tree_a, hf_esmc_padding, tvb_next, 0, -1, ENC_NA);
proto_item_append_text(item_b, ", %d %s%s", padding_size
, "octet", plurality(padding_size,"","s"));
{
proto_tree* tree_b;
tree_b = proto_item_add_subtree(item_b, ett_esmc);
call_dissector(dh_data, tvb_next, pinfo, tree_b);
}
}
}
}
/* append summary info */
col_add_fstr(pinfo->cinfo, COL_INFO, "Event:%s", event_flag ?
"Time-critical" : "Information");
if (ql >= 0)
{
col_append_fstr(pinfo->cinfo, COL_INFO, ", %s"
, val_to_str(ql, esmc_quality_level_opt_1_vals_short, "QL-INVALID-%d"));
}
if (timestamp_valid_flag)
{
col_append_fstr(pinfo->cinfo, COL_INFO, ", TS:%d", timestamp);
}
if (malformed)
{
col_append_str(pinfo->cinfo, COL_INFO, ", Malformed PDU");
}
}
/* Register the protocol with Wireshark */
void
proto_register_ossp(void)
{
/* Setup list of header fields */
static hf_register_info hf[] = {
{ &hf_ossp_oui,
{ "OUI", "ossp.oui",
FT_BYTES, BASE_NONE, NULL, 0,
"IEEE assigned Organizationally Unique Identifier", HFILL }},
{ &hf_itu_subtype,
{ "ITU-T OSSP Subtype", "ossp.itu.subtype",
FT_UINT16, BASE_HEX, NULL, 0,
"Subtype assigned by the ITU-T", HFILL }},
{ &hf_esmc_version,
{ "Version", "ossp.esmc.version",
FT_UINT8, BASE_HEX, NULL, 0xf0,
"This field indicates the version of ITU-T SG15 Q13 OSSP frame format", HFILL }},
{ &hf_esmc_event_flag,
{ "Event Flag", "ossp.esmc.event_flag",
FT_UINT8, BASE_HEX, VALS(esmc_event_flag_vals), 0x08,
"This bit distinguishes the critical, time sensitive behaviour of the"
" ESMC Event PDU from the ESMC Information PDU", HFILL }},
{ &hf_esmc_timestamp_valid_flag,
{ "Timestamp Valid Flag", "ossp.esmc.timestamp_valid_flag",
FT_UINT8, BASE_HEX, VALS(esmc_timestamp_valid_flag_vals), 0x04,
"Indicates validity (i.e. presence) of the Timestamp TLV", HFILL }},
{ &hf_esmc_reserved_32,
{ "Reserved", "ossp.esmc.reserved",
FT_UINT32, BASE_HEX, NULL, 0,
"Reserved. Set to all zero at the transmitter and ignored by the receiver", HFILL }},
{ &hf_esmc_tlv,
{ "ESMC TLV", "ossp.esmc.tlv",
FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }},
{ &hf_esmc_tlv_type,
{ "TLV Type", "ossp.esmc.tlv_type",
FT_UINT8, BASE_HEX, VALS(esmc_tlv_type_vals), 0,
NULL, HFILL }},
{ &hf_esmc_tlv_length,
{ "TLV Length", "ossp.esmc.tlv_length",
FT_UINT16, BASE_HEX, NULL, 0,
NULL, HFILL }},
{ &hf_esmc_tlv_ql_unused,
{ "Unused", "ossp.esmc.tlv_ql_unused",
FT_UINT8, BASE_HEX, NULL, 0xf0,
"This field is not used in QL TLV", HFILL }},
{ &hf_esmc_quality_level_opt_1,
{ "SSM Code", "ossp.esmc.ql",
FT_UINT8, BASE_HEX, VALS(esmc_quality_level_opt_1_vals), 0x0f,
"Quality Level information", HFILL }},
#if 0 /*not used yet*/
{ &hf_esmc_quality_level_opt_2,
{ "SSM Code", "ossp.esmc.ql",
FT_UINT8, BASE_HEX, VALS(esmc_quality_level_opt_2_vals), 0x0f,
"Quality Level information", HFILL }},
#endif
{ &hf_esmc_quality_level_invalid,
{ "SSM Code", "ossp.esmc.ql",
FT_UINT8, BASE_HEX, VALS(esmc_quality_level_invalid_vals), 0x0f,
"Quality Level information", HFILL }},
{ &hf_esmc_timestamp,
{ "Timestamp (ns)", "ossp.esmc.timestamp",
FT_INT32, BASE_DEC, NULL, 0,
"Timestamp according to the \"whole nanoseconds\" part of the IEEE 1588 originTimestamp", HFILL }},
{ &hf_esmc_tlv_ts_reserved,
{ "Reserved", "ossp.esmc.tlv_ts_reserved",
FT_UINT8, BASE_HEX, NULL, 0,
"Reserved. Set to all zero at the transmitter and ignored by the receiver", HFILL }},
{ &hf_esmc_padding,
{ "Padding", "ossp.esmc.padding",
FT_BYTES, BASE_NONE, NULL, 0x0,
"This field contains necessary padding to achieve the minimum frame size of 64 bytes at least", HFILL }},
};
/* Setup protocol subtree array */
static gint *ett[] = {
&ett_esmc,
&ett_ossppdu,
&ett_itu_ossp
};
static ei_register_info ei[] = {
{ &ei_esmc_version_compliance, { "ossp.esmc.version.compliance", PI_MALFORMED, PI_ERROR, "Version must claim compliance with Version 1 of this protocol", EXPFILL }},
{ &ei_esmc_tlv_type_ql_type_not_first, { "ossp.esmc.tlv_type.ql_type_not_first", PI_MALFORMED, PI_ERROR, "TLV Type must be QL because QL TLV must be first in the ESMC PDU", EXPFILL }},
{ &ei_esmc_tlv_type_decoded_as_ql_type, { "ossp.esmc.tlv_type.decoded_as_ql_type", PI_UNDECODED, PI_NOTE, "Let's decode as if this is QL TLV", EXPFILL }},
{ &ei_esmc_tlv_length_bad, { "ossp.esmc.tlv_length.bad", PI_MALFORMED, PI_ERROR, "QL TLV Length must be X", EXPFILL }},
{ &ei_esmc_tlv_ql_unused_not_zero, { "ossp.esmc.tlv_ql_unused.not_zero", PI_MALFORMED, PI_WARN, "Unused bits of TLV must be all zeroes", EXPFILL }},
{ &ei_esmc_quality_level_invalid, { "ossp.esmc.ql.invalid", PI_UNDECODED, PI_WARN, "Invalid SSM message, unknown QL code", EXPFILL }},
{ &ei_esmc_tlv_type_not_timestamp, { "ossp.esmc.tlv_type.not_timestamp", PI_MALFORMED, PI_ERROR, "TLV Type must be == Timestamp because Timestamp Valid Flag is set", EXPFILL }},
{ &ei_esmc_tlv_type_decoded_as_timestamp, { "ossp.esmc.tlv_type.decoded_as_timestamp", PI_UNDECODED, PI_NOTE, "Let's decode as if this is Timestamp TLV", EXPFILL }},
{ &ei_esmc_reserved_not_zero, { "ossp.esmc.reserved_bits_must_be_set_to_all_zero", PI_PROTOCOL, PI_WARN, "Reserved bits must be set to all zero", EXPFILL }},
};
expert_module_t* expert_ossp;
/* Register the protocol name and description */
proto_ossp = proto_register_protocol("OSSP", "Organization Specific Slow Protocol", "ossp");
/* Required function calls to register the header fields and subtrees used */
proto_register_field_array(proto_ossp, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
expert_ossp = expert_register_protocol(proto_ossp);
expert_register_field_array(expert_ossp, ei, array_length(ei));
}
void
proto_reg_handoff_ossp(void)
{
dissector_handle_t ossp_handle;
ossp_handle = create_dissector_handle(dissect_ossp_pdu, proto_ossp);
dissector_add_uint("slow.subtype", OSSP_SUBTYPE, ossp_handle);
dh_data = find_dissector("data");
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,6 @@
#define LACP_SUBTYPE 0x1
#define MARKER_SUBTYPE 0x2
#define OAM_SUBTYPE 0x3
#define OSSP_SUBTYPE 0xa /* IEEE 802.3 Annex 57A*/