Ethereal-dev: [Ethereal-dev] GVRP dissector for Ethereal
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: techishi@xxxxxxxxxxxxxx
Date: Thu, 30 Nov 100 09:44:16 +0800 (CST)
Dear Sirs,
Here is my codes for GVRP dissector. Since I did not have CVS nor Cygwin
installed on my computer, I could only submit the whole modified file and
the files I created in this email. Following are the codes.
Kevin Shi
=================================================================================
[Beginning of the modified version of "packet-bpdu.c"]
-------------------------------------------------
/* packet-bpdu.c
* Routines for BPDU (Spanning Tree Protocol) disassembly
*
* $Id: packet-bpdu.c,v 1.15 2000/11/19 08:53:55 guy Exp $
*
* Copyright 1999 Christophe Tronche <ch.tronche@xxxxxxxxxxxx>
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@xxxxxxxx>
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#include <stdio.h>
#include <string.h>
#include <glib.h>
#include "packet.h"
#include "llcsaps.h"
#include "resolv.h"
/* Include this for GVRP dissector */
#include "packet-gvrp.h"
/* Offsets of fields within a BPDU */
#define BPDU_IDENTIFIER 0
#define BPDU_VERSION_IDENTIFIER 2
#define BPDU_TYPE 3
#define BPDU_FLAGS 4
#define BPDU_ROOT_IDENTIFIER 5
#define BPDU_ROOT_PATH_COST 13
#define BPDU_BRIDGE_IDENTIFIER 17
#define BPDU_PORT_IDENTIFIER 25
#define BPDU_MESSAGE_AGE 27
#define BPDU_MAX_AGE 29
#define BPDU_HELLO_TIME 31
#define BPDU_FORWARD_DELAY 33
static int proto_bpdu = -1;
static int hf_bpdu_proto_id = -1;
static int hf_bpdu_version_id = -1;
static int hf_bpdu_type = -1;
static int hf_bpdu_flags = -1;
static int hf_bpdu_root_mac = -1;
static int hf_bpdu_root_cost = -1;
static int hf_bpdu_bridge_mac = -1;
static int hf_bpdu_port_id = -1;
static int hf_bpdu_msg_age = -1;
static int hf_bpdu_max_age = -1;
static int hf_bpdu_hello_time = -1;
static int hf_bpdu_forward_delay = -1;
static gint ett_bpdu = -1;
static void
dissect_bpdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
guint16 protocol_identifier;
guint8 protocol_version_identifier;
guint8 bpdu_type;
guint8 flags;
guint16 root_identifier_bridge_priority;
guint8 *root_identifier_mac;
gchar *root_identifier_mac_str;
guint32 root_path_cost;
guint16 bridge_identifier_bridge_priority;
guint8 *bridge_identifier_mac;
gchar *bridge_identifier_mac_str;
guint16 port_identifier;
double message_age;
double max_age;
double hello_time;
double forward_delay;
proto_tree *bpdu_tree;
proto_item *ti;
CHECK_DISPLAY_AS_DATA(proto_bpdu, tvb, pinfo, tree);
/* GARP application frames require special interpretation of the
destination
address field; otherwise, they will be mistaken as BPDU frames.
Fortunately, they can be recognized by checking the first 6 octets
of the
destination address, which are in the range from 01-80-C2-00-00-20
to
01-80-C2-00-00-2F. */
if ( pinfo->dl_dst.data[0] == 0x01 &&
pinfo->dl_dst.data[1] == 0x80 &&
pinfo->dl_dst.data[2] == 0xC2 &&
pinfo->dl_dst.data[3] == 0x00 &&
pinfo->dl_dst.data[4] == 0x00 &&
((pinfo->dl_dst.data[5] & 0x20) == 0x20)) {
protocol_identifier = tvb_get_ntohs(tvb, BPDU_IDENTIFIER);
/* Future expansion for GMRP */
if (pinfo->dl_dst.data[5] == 0x20) {
}
/* for GVRP */
if (pinfo->dl_dst.data[5] == 0x21) {
dissect_gvrp(tvb, pinfo, tree);
return;
}
pinfo->current_proto = "GARP";
if (check_col(pinfo->fd, COL_PROTOCOL)) {
col_set_str(pinfo->fd, COL_PROTOCOL, "GARP"); /* Generic
Attribute Registration Protocol */
}
if (check_col(pinfo->fd, COL_INFO)) {
col_set_str(pinfo->fd, COL_PROTOCOL, "Unknown GARP
application");
}
return;
}
pinfo->current_proto = "STP";
bpdu_type = tvb_get_guint8(tvb, BPDU_TYPE);
flags = tvb_get_guint8(tvb, BPDU_FLAGS);
root_identifier_bridge_priority = tvb_get_ntohs(tvb,
BPDU_ROOT_IDENTIFIER);
root_identifier_mac = tvb_get_ptr(tvb, BPDU_ROOT_IDENTIFIER + 2, 6);
root_identifier_mac_str = ether_to_str(root_identifier_mac);
root_path_cost = tvb_get_ntohl(tvb, BPDU_ROOT_PATH_COST);
port_identifier = tvb_get_ntohs(tvb, BPDU_PORT_IDENTIFIER);
if (check_col(pinfo->fd, COL_PROTOCOL)) {
col_set_str(pinfo->fd, COL_PROTOCOL, "STP"); /* Spanning Tree
Protocol */
}
if (check_col(pinfo->fd, COL_INFO)) {
if (bpdu_type == 0)
col_add_fstr(pinfo->fd, COL_INFO, "Conf. %sRoot = %d/%s
Cost = %d Port = 0x%04x",
flags & 0x1 ? "TC + " : "",
root_identifier_bridge_priority,
root_identifier_mac_str, root_path_cost,
port_identifier);
else if (bpdu_type == 0x80)
col_add_fstr(pinfo->fd, COL_INFO, "Topology Change
Notification");
}
if (tree) {
protocol_identifier = tvb_get_ntohs(tvb, BPDU_IDENTIFIER);
protocol_version_identifier = tvb_get_guint8(tvb,
BPDU_VERSION_IDENTIFIER);
ti = proto_tree_add_protocol_format(tree, proto_bpdu, tvb, 0,
35,
"Spanning Tree Protocol");
bpdu_tree = proto_item_add_subtree(ti, ett_bpdu);
proto_tree_add_uint_format(bpdu_tree, hf_bpdu_proto_id, tvb,
BPDU_IDENTIFIER, 2,
protocol_identifier,
"Protocol Identifier: 0x%04x (%s)",
protocol_identifier,
protocol_identifier == 0 ?
"Spanning Tree" : "Unknown
Protocol");
proto_tree_add_uint(bpdu_tree, hf_bpdu_version_id, tvb,
BPDU_VERSION_IDENTIFIER, 1,
protocol_version_identifier);
if (protocol_version_identifier != 0)
proto_tree_add_text(bpdu_tree, tvb,
BPDU_VERSION_IDENTIFIER, 1, " (Warning: this version of packet-bpdu only
knows about version = 0)");
proto_tree_add_uint_format(bpdu_tree, hf_bpdu_type, tvb,
BPDU_TYPE, 1,
bpdu_type,
"BPDU Type: 0x%02x (%s)",
bpdu_type,
bpdu_type == 0 ? "Configuration" :
bpdu_type == 0x80 ? "Topology Change
Notification" : "Unknown");
if (bpdu_type != 0) {
dissect_data(tvb, BPDU_TYPE + 1, pinfo, tree);
return;
}
bridge_identifier_bridge_priority = tvb_get_ntohs(tvb,
BPDU_BRIDGE_IDENTIFIER);
bridge_identifier_mac = tvb_get_ptr(tvb, BPDU_BRIDGE_IDENTIFIER
+ 2, 6);
bridge_identifier_mac_str = ether_to_str(bridge_identifier_mac);
message_age = tvb_get_ntohs(tvb, BPDU_MESSAGE_AGE) / 256.0;
max_age = tvb_get_ntohs(tvb, BPDU_MAX_AGE) / 256.0;
hello_time = tvb_get_ntohs(tvb, BPDU_HELLO_TIME) / 256.0;
forward_delay = tvb_get_ntohs(tvb, BPDU_FORWARD_DELAY) / 256.0;
proto_tree_add_uint(bpdu_tree, hf_bpdu_flags, tvb,
BPDU_FLAGS, 1, flags);
if (flags & 0x80)
proto_tree_add_text(bpdu_tree, tvb, BPDU_FLAGS, 1, "
1... .... Topology Change Acknowledgment");
if (flags & 0x01)
proto_tree_add_text(bpdu_tree, tvb, BPDU_FLAGS, 1, "
.... ...1 Topology Change");
proto_tree_add_ether_hidden(bpdu_tree, hf_bpdu_root_mac, tvb,
BPDU_ROOT_IDENTIFIER + 2, 6,
root_identifier_mac);
proto_tree_add_text(bpdu_tree, tvb,
BPDU_ROOT_IDENTIFIER, 8,
"Root Identifier: %d / %s",
root_identifier_bridge_priority,
root_identifier_mac_str);
proto_tree_add_uint(bpdu_tree, hf_bpdu_root_cost, tvb,
BPDU_ROOT_PATH_COST, 4,
root_path_cost);
proto_tree_add_text(bpdu_tree, tvb,
BPDU_BRIDGE_IDENTIFIER, 8,
"Bridge Identifier: %d / %s",
bridge_identifier_bridge_priority,
bridge_identifier_mac_str);
proto_tree_add_ether_hidden(bpdu_tree, hf_bpdu_bridge_mac, tvb,
BPDU_BRIDGE_IDENTIFIER + 2, 6,
bridge_identifier_mac);
proto_tree_add_uint(bpdu_tree, hf_bpdu_port_id, tvb,
BPDU_PORT_IDENTIFIER, 2,
port_identifier);
proto_tree_add_double(bpdu_tree, hf_bpdu_msg_age, tvb,
BPDU_MESSAGE_AGE, 2,
message_age);
proto_tree_add_double(bpdu_tree, hf_bpdu_max_age, tvb,
BPDU_MAX_AGE, 2,
max_age);
proto_tree_add_double(bpdu_tree, hf_bpdu_hello_time, tvb,
BPDU_HELLO_TIME, 2,
hello_time);
proto_tree_add_double(bpdu_tree, hf_bpdu_forward_delay, tvb,
BPDU_FORWARD_DELAY, 2,
forward_delay);
}
}
void
proto_register_bpdu(void)
{
static hf_register_info hf[] = {
{ &hf_bpdu_proto_id,
{ "Protocol Identifier", "stp.protocol",
FT_UINT16, BASE_HEX, NULL, 0x0,
"" }},
{ &hf_bpdu_version_id,
{ "Protocol Version Identifier", "stp.version",
FT_UINT8, BASE_DEC, NULL, 0x0,
"" }},
{ &hf_bpdu_type,
{ "BPDU type", "stp.type",
FT_UINT8, BASE_HEX, NULL, 0x0,
"" }},
{ &hf_bpdu_flags,
{ "BPDU flags", "stp.flags",
FT_UINT8, BASE_HEX, NULL, 0x0,
"" }},
{ &hf_bpdu_root_mac,
{ "Root Identifier", "stp.root.hw",
FT_ETHER, BASE_NONE, NULL, 0x0,
"" }},
{ &hf_bpdu_root_cost,
{ "Root Path Cost", "stp.root.cost",
FT_UINT32, BASE_DEC, NULL, 0x0,
"" }},
{ &hf_bpdu_bridge_mac,
{ "Bridge Identifier", "stp.bridge.hw",
FT_ETHER, BASE_NONE, NULL, 0x0,
""}},
{ &hf_bpdu_port_id,
{ "Port identifier", "stp.port",
FT_UINT16, BASE_HEX, NULL, 0x0,
""}},
{ &hf_bpdu_msg_age,
{ "Message Age", "stp.msg_age",
FT_DOUBLE, BASE_NONE, NULL, 0x0,
"" }},
{ &hf_bpdu_max_age,
{ "Max Age", "stp.max_age",
FT_DOUBLE, BASE_NONE, NULL, 0x0,
"" }},
{ &hf_bpdu_hello_time,
{ "Hello Time", "stp.hello",
FT_DOUBLE, BASE_NONE, NULL, 0x0,
"" }},
{ &hf_bpdu_forward_delay,
{ "Forward Delay", "stp.forward",
FT_DOUBLE, BASE_NONE, NULL, 0x0,
"" }},
};
static gint *ett[] = {
&ett_bpdu,
};
proto_bpdu = proto_register_protocol("Spanning Tree Protocol", "stp");
proto_register_field_array(proto_bpdu, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
register_dissector("bpdu", dissect_bpdu);
}
void
proto_reg_handoff_bpdu(void)
{
dissector_add("llc.dsap", SAP_BPDU, dissect_bpdu);
}
-------------------------------------------------
[End of the modified version of "packet-bpdu.c"]
=================================================================================
[Beginning of "packet-gvrp.h"]
-------------------------------------------------
/* packet-gvrp.c
* Routines for GVRP (GARP VLAN Registration Protocol) dissection
* Copyright 2000, Kevin Shi <techishi@xxxxxxxxxxxxxx>
*
* $Id: README.developer,v 1.21 2000/11/06 09:56:10 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@xxxxxxxxxx>
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA.
*/
#ifndef __PACKET_GVRP_H__
#define __PACKET_GVRP_H__
void dissect_gvrp(tvbuff_t *, packet_info *, proto_tree *);
#endif /* packet-atm.h */
-------------------------------------------------
[End of "packet-gvrp.h"]
=================================================================================
[Beginning of "packet-gvrp.c"]
-------------------------------------------------
/* packet-gvrp.c
* Routines for GVRP (GARP VLAN Registration Protocol) dissection
* Copyright 2000, Kevin Shi <techishi@xxxxxxxxxxxxxx>
*
* $Id: README.developer,v 1.21 2000/11/06 09:56:10 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@xxxxxxxxxx>
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#include <glib.h>
#ifdef NEED_SNPRINTF_H
# include "snprintf.h"
#endif
#include "packet.h"
#include "llcsaps.h"
/* Initialize the protocol and registered fields */
static int proto_gvrp = -1;
static int hf_gvrp_proto_id = -1;
static int hf_gvrp_attribute_type = -1;
static int hf_gvrp_attribute_length = -1;
static int hf_gvrp_attribute_event = -1;
static int hf_gvrp_attribute_value = -1;
static int hf_gvrp_end_of_mark = -1;
/* Initialize the subtree pointers */
static gint ett_gvrp = -1;
static gint ett_gvrp_message = -1;
static gint ett_gvrp_attribute_list = -1;
static gint ett_gvrp_attribute = -1;
/* Constant definitions */
#define GARP_DEFAULT_PROTOCOL_ID 0x0001
#define GARP_END_OF_MARK 0x00
#define GVRP_ATTRIBUTE_TYPE 0x01
/* The length of GVRP LeaveAll attribute should be 2 octets (one for length
and the other for event) */
#define GVRP_LENGTH_LEAVEALL (sizeof(guint8)+sizeof(guint8))
/* The length of GVRP attribute other than LeaveAll should be 4 octets (one
for length, one for event,
* and the last two for VID value).
*/
#define GVRP_LENGTH_NON_LEAVEALL
(sizeof(guint8)+sizeof(guint8)+sizeof(guint16))
/* Packet offset definitions */
#define GARP_PROTOCOL_ID 0
/* Event definitions */
#define GVRP_EVENT_LEAVEALL 0
#define GVRP_EVENT_JOINEMPTY 1
#define GVRP_EVENT_JOININ 2
#define GVRP_EVENT_LEAVEEMPTY 3
#define GVRP_EVENT_LEAVEIN 4
#define GVRP_EVENT_EMPTY 5
static char gvrp_event_LeaveAll[] = "Leave All";
static char gvrp_event_JoinIn[] = "Join In";
static char gvrp_event_JoinEmpty[] = "Join Empty";
static char gvrp_event_LeaveIn[] = "Leave In";
static char gvrp_event_LeaveEmpty[] = "Leave Empty";
static char gvrp_event_Empty[] = "Empty";
static char gvrp_event_unknown[] = "Unknown Event";
/* Code to actually dissect the packets */
void
dissect_gvrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_item *ti;
proto_tree *gvrp_tree;
guint16 protocol_id;
guint8 octet;
int msg_index, attr_index, offset = 0, length =
tvb_reported_length(tvb);
CHECK_DISPLAY_AS_DATA(proto_gvrp, tvb, pinfo, tree);
pinfo->current_proto = "GVRP";
if (check_col(pinfo->fd, COL_PROTOCOL))
col_add_str(pinfo->fd, COL_PROTOCOL, "GVRP");
if (check_col(pinfo->fd, COL_INFO))
col_add_str(pinfo->fd, COL_INFO, "GVRP");
if (tree)
{
ti = proto_tree_add_item(tree, proto_gvrp, tvb, 0, length, FALSE);
gvrp_tree = proto_item_add_subtree(ti, ett_gvrp);
/* Read in GARP protocol ID */
protocol_id = tvb_get_ntohs(tvb, GARP_PROTOCOL_ID);
proto_tree_add_uint_format(gvrp_tree, hf_gvrp_proto_id, tvb,
GARP_PROTOCOL_ID, sizeof(guint16),
protocol_id,
"Protocol Identifier: 0x%04x (%s)",
protocol_id,
protocol_id == GARP_DEFAULT_PROTOCOL_ID ?
"GARP VLAN Registration Protocol" :
"Unknown Protocol");
/* Currently only one protocol ID is supported */
if (protocol_id != GARP_DEFAULT_PROTOCOL_ID)
{
proto_tree_add_text(gvrp_tree, tvb, GARP_PROTOCOL_ID,
sizeof(guint16),
" (Warning: this version of packet-gvrp
only knows about protocol id = 1)");
dissect_data(tvb, GARP_PROTOCOL_ID + sizeof(guint16), pinfo,
tree);
return;
}
offset += sizeof(guint16);
length -= sizeof(guint16);
msg_index = 0;
/* Begin to parse GARP messages */
while (length)
{
proto_item *msg_item;
int msg_start = offset;
/* Read in attribute type. */
octet = tvb_get_guint8(tvb, offset);
/* Check for end of mark */
if (octet == GARP_END_OF_MARK)
{
/* End of GARP PDU */
if (msg_index)
{
proto_tree_add_text(gvrp_tree, tvb, offset,
sizeof(guint8), "End of mark");
break;
}
else
{
dissect_data(tvb, offset, pinfo, tree);
return;
}
}
offset += sizeof(guint8);
length -= sizeof(guint8);
/* GVRP only support one attribute type. */
if (octet != GVRP_ATTRIBUTE_TYPE)
{
dissect_data(tvb, offset, pinfo, tree);
return;
}
msg_item = proto_tree_add_text(gvrp_tree, tvb, msg_start, 0,
"Message %d", msg_index + 1);
proto_tree_add_text(gvrp_tree, tvb, msg_start, sizeof(guint8),
" Attribute Type: %d (%s)", octet,
(octet == GVRP_ATTRIBUTE_TYPE) ? "VID
Attribute Type" : "Unknown Attribute Type");
attr_index = 0;
while (length)
{
int attr_start = offset;
proto_item *attr_item;
/* Read in attribute length. */
octet = tvb_get_guint8(tvb, offset);
/* Check for end of mark */
if (octet == GARP_END_OF_MARK)
{
/* If at least one message has been already read,
* check for another end of mark.
*/
if (attr_index)
{
proto_tree_add_text(gvrp_tree, tvb, offset,
sizeof(guint8), " End of mark");
offset += sizeof(guint8);
length -= sizeof(guint8);
proto_item_set_len(msg_item, offset - msg_start);
break;
}
else
{
dissect_data(tvb, offset, pinfo, tree);
return;
}
}
else
{
guint8 event;
guint16 value;
char *string;
offset += sizeof(guint8);
length -= sizeof(guint8);
attr_item = proto_tree_add_text(gvrp_tree, tvb,
attr_start, 0, " Attribute %d", attr_index + 1);
proto_tree_add_text(gvrp_tree, tvb, attr_start,
sizeof(guint8), " Length: %d", octet);
/* Read in attribute event */
event = tvb_get_guint8(tvb, offset);
if (((event == GVRP_EVENT_LEAVEALL) && (octet !=
GVRP_LENGTH_LEAVEALL)) ||
((event != GVRP_EVENT_LEAVEALL) && (octet !=
GVRP_LENGTH_NON_LEAVEALL)))
{
dissect_data(tvb, offset, pinfo, tree);
return;
}
switch (event)
{
case GVRP_EVENT_LEAVEALL:
string = gvrp_event_LeaveAll;
break;
case GVRP_EVENT_JOINEMPTY:
string = gvrp_event_JoinEmpty;
break;
case GVRP_EVENT_JOININ:
string = gvrp_event_JoinIn;
break;
case GVRP_EVENT_LEAVEEMPTY:
string = gvrp_event_LeaveEmpty;
break;
case GVRP_EVENT_LEAVEIN:
string = gvrp_event_LeaveIn;
break;
case GVRP_EVENT_EMPTY:
string = gvrp_event_Empty;
break;
default: /* Unknown attribute event */
string = gvrp_event_unknown;
break;
}
proto_tree_add_text(gvrp_tree, tvb, offset,
sizeof(guint8), " Event: %d (%s)", event, string);
offset += sizeof(guint8);
length -= sizeof(guint8);
if (string == gvrp_event_unknown)
{
dissect_data(tvb, offset, pinfo, tree);
return;
}
if (string != gvrp_event_LeaveAll)
{
/* Read in attribute value */
value = tvb_get_ntohs(tvb, offset);
proto_tree_add_text(gvrp_tree, tvb, offset,
sizeof(guint16), " Value: %d", value);
offset += sizeof(guint16);
length -= sizeof(guint16);
}
}
proto_item_set_len(attr_item, offset - attr_start);
attr_index++;
}
msg_index++;
}
}
}
/* Register the protocol with Ethereal */
void
proto_register_gvrp(void)
{
static hf_register_info hf[] = {
{ &hf_gvrp_proto_id,
{ "GARP Protocol ID", "garp.protocol_id",
FT_UINT16, BASE_HEX, NULL, 0x0,
"" }
}
};
static gint *ett[] = {
&ett_gvrp
};
/* Register the protocol name and description for GVRP */
proto_gvrp = proto_register_protocol("GARP VLAN Registration Protocol",
"GVRP");
/* Required function calls to register the header fields and subtrees
used by GVRP */
proto_register_field_array(proto_gvrp, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
}
-------------------------------------------------
[End of "packet-gvrp.c"]
- Follow-Ups:
- Re: [Ethereal-dev] GVRP dissector for Ethereal
- From: Guy Harris
- Re: [Ethereal-dev] GVRP dissector for Ethereal
- Prev by Date: Re: [Ethereal-dev] It would appear that guint16's in LDP are little endian?
- Next by Date: [Ethereal-dev] anon CVS lock problems
- Previous by thread: Re: [Ethereal-dev] It would appear that guint16's in LDP are little endian?
- Next by thread: Re: [Ethereal-dev] GVRP dissector for Ethereal
- Index(es):





