2 * Routines for the disassembly of Extreme Networks specific
3 * protocols (EDP/ESRP/EAPS)
7 * Copyright 2005 Joerg Mayer (see AUTHORS file)
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 EAPS v2 is not supported (no spec)
32 Some stuff in the EDP Info field (no spec)
33 - Things seen in traces
34 Flags in the EDP Vlan field (value 0x01)
35 Meaning of special MAC adresses:
37 TLV type 0x0e (XOS only?) (EAPSv2?)
38 TLV type 0x15 (XOS only?)
39 EAPS type 0x10 (EAPSv2?)
44 EAPS v1 is specified in RFC3619
46 The following information is taken from the Extreme knowledge base
47 (login required). Search for ESRP.
48 Note: The information seems to be incorrect in at least one place
49 (position of edp.vlan.id).
51 ================================ snip ================================
57 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
58 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 0000
59 | SOURCE MAC ADDRESS |
60 +-------------------------------+-------------------------------+ 0004
61 | SOURCE MAC ADDRESS (CONT) | DEST MAC ADDRESS |
62 +-------------------------------+-------------------------------+ 0008
63 | DEST MAC ADDRESS (CONT) |
64 +-------------------------------+---------------+---------------+ 000C
65 | LENGTH | DSAP = AA | SSAP = AA |
66 +---------------+---------------+---------------+---------------+ 0010
67 | LLC TYPE = UI | UID = 00E02B |
68 +---------------+---------------+---------------+---------------+ 0014
69 | SNAP TYPE = 00BB | EDP VERSION | RESERVED |
70 +-------------------------------+---------------+---------------+ 0018
72 +-------------------------------+-------------------------------+ 001C
73 | SEQUENCE NUMBER | MACHINE ID |
74 +-------------------------------+-------------------------------+ 0020
75 | MACHINE ID (CONT.) |
76 +-------------------------------+---------------+---------------+ 0024
77 | MACHINE ID (CONT.) | MARKER=99(EDP)| TYPE=08 (ESRP)|
78 +-------------------------------+---------------+---------------+ 0028
79 | LENGTH = 001C |0=IP 1=IPX 2=L2| GROUP = 0 |
80 +-------------------------------+-------------------------------+ 002C
81 | PRIORITY | STATE: 0=?? 1=MSTR 2=SLAVE |
82 +-------------------------------+-------------------------------+ 0030
83 | NUMBER OF ACTIVE PORTS | VIRTUAL IP ADDRESS |
84 +-------------------------------+-------------------------------+ 0034
85 | VIRTUAL IP ADDRESS (CONT) | SYSTEM MAC ADDRESS |
86 +-------------------------------+-------------------------------+ 0038
87 | SYSTEM MAC ADDRESS (CONT.) |
88 +-------------------------------+-------------------------------+ 003C
89 | HELLO TIMER | RESERVED |
90 +-------------------------------+-------------------------------+ 0040
93 ******************************************************************************
96 EDP is a SNAP encapsulated frame. The top level looks like this:
97 The top level format is like this:
98 [ SNAP header ] [ EDP header] [ TLV 0 ] [ TLV 1 ] ... [ TLV N ]
106 8 octets: device id (currently 2 0 octets followed by system mac address)
108 TLV stands for Type, Length, Value.
109 Format of a TLV entry:
110 marker ( 1 octet): Hex 99
112 The following types are used:
113 Null (used as an end signal): 0
114 Display (Mib II display string): 1
115 Info (Basic system information): 2
118 Length: Length of subsequent data(2 octets)
119 Value: Length octets of data.
122 two octets: originating slot #
123 two octets: originating port #
124 two octets: Virtual Chassis Id (If originating port is connected to a virtual chassis).
126 four octets: software version
127 16 octets: Virtual Chassis Id connections
129 Format for Vlan info:
130 octet 0: Flags (bit 8 = 1 means this vlan has an IP interface)
131 octets 1,2,3: reserved.
132 octets 4,5: vlan Id (0 if untagged)
133 octets 6,7: reserved.
134 octets 8 - 11: Vlan IP address.
135 Rest of value: VLAN name.
137 Display string is merely length octets of the MIBII display string.
139 These are the structures you will see most often in EDP frames.
141 ================================ snap ================================
151 #include <epan/packet.h>
152 #include <epan/strutil.h>
153 #include <epan/in_cksum.h>
154 #include "packet-llc.h"
155 #include <epan/oui.h>
157 static int hf_llc_extreme_pid = -1;
159 static int proto_edp = -1;
161 static int hf_edp_version = -1;
162 static int hf_edp_reserved = -1;
163 static int hf_edp_length = -1;
164 static int hf_edp_checksum = -1;
165 static int hf_edp_checksum_good = -1;
166 static int hf_edp_checksum_bad = -1;
168 static int hf_edp_seqno = -1;
169 static int hf_edp_midtype = -1;
170 static int hf_edp_midmac = -1;
172 static int hf_edp_tlv_marker = -1;
173 static int hf_edp_tlv_type = -1;
174 static int hf_edp_tlv_length = -1;
176 static int hf_edp_display = -1;
177 static int hf_edp_display_string = -1;
179 static int hf_edp_info = -1;
180 static int hf_edp_info_slot = -1;
181 static int hf_edp_info_port = -1;
182 static int hf_edp_info_vchassid = -1;
183 static int hf_edp_info_reserved = -1;
184 static int hf_edp_info_version = -1;
185 static int hf_edp_info_version_major1 = -1;
186 static int hf_edp_info_version_major2 = -1;
187 static int hf_edp_info_version_sustaining = -1;
188 static int hf_edp_info_version_internal = -1;
189 static int hf_edp_info_vchassconn = -1;
191 static int hf_edp_vlan = -1;
192 static int hf_edp_vlan_flags = -1;
193 static int hf_edp_vlan_flags_ip = -1;
194 static int hf_edp_vlan_flags_reserved = -1;
195 static int hf_edp_vlan_flags_unknown = -1;
196 static int hf_edp_vlan_reserved1 = -1;
197 static int hf_edp_vlan_id = -1;
198 static int hf_edp_vlan_reserved2 = -1;
199 static int hf_edp_vlan_ip = -1;
200 static int hf_edp_vlan_name = -1;
202 static int hf_edp_esrp = -1;
203 static int hf_edp_esrp_proto = -1;
204 static int hf_edp_esrp_group = -1;
205 static int hf_edp_esrp_prio = -1;
206 static int hf_edp_esrp_state = -1;
207 static int hf_edp_esrp_ports = -1;
208 static int hf_edp_esrp_virtip = -1;
209 static int hf_edp_esrp_sysmac = -1;
210 static int hf_edp_esrp_hello = -1;
211 static int hf_edp_esrp_reserved = -1;
213 static int hf_edp_eaps = -1;
214 static int hf_edp_eaps_ver = -1;
215 static int hf_edp_eaps_type = -1;
216 static int hf_edp_eaps_ctrlvlanid = -1;
217 static int hf_edp_eaps_reserved0 = -1;
218 static int hf_edp_eaps_sysmac = -1;
219 static int hf_edp_eaps_hello = -1;
220 static int hf_edp_eaps_fail = -1;
221 static int hf_edp_eaps_state = -1;
222 static int hf_edp_eaps_reserved1 = -1;
223 static int hf_edp_eaps_helloseq = -1;
224 static int hf_edp_eaps_reserved2 = -1;
225 /* ELSM (Extreme Link Status Monitoring) */
226 static int hf_edp_elsm = -1;
227 static int hf_edp_elsm_unknown = -1;
228 /* ELRP (Extreme Loop Recognition Protocol)*/
229 static int hf_edp_elrp = -1;
230 static int hf_edp_elrp_unknown = -1;
231 /* Unknown element */
232 static int hf_edp_unknown = -1;
233 static int hf_edp_unknown_data = -1;
235 static int hf_edp_null = -1;
237 static gint ett_edp = -1;
238 static gint ett_edp_checksum = -1;
239 static gint ett_edp_tlv_header = -1;
240 static gint ett_edp_display = -1;
241 static gint ett_edp_info = -1;
242 static gint ett_edp_info_version = -1;
243 static gint ett_edp_vlan = -1;
244 static gint ett_edp_vlan_flags = -1;
245 static gint ett_edp_esrp = -1;
246 static gint ett_edp_eaps = -1;
247 static gint ett_edp_elrp = -1;
248 static gint ett_edp_elsm = -1;
249 static gint ett_edp_unknown = -1;
250 static gint ett_edp_null = -1;
252 #define PROTO_SHORT_NAME "EDP"
253 #define PROTO_LONG_NAME "Extreme Discovery Protocol"
255 static const value_string extreme_pid_vals[] = {
261 static const value_string esrp_proto_vals[] = {
269 static const value_string esrp_state_vals[] = {
288 static const value_string edp_type_vals[] = {
289 { EDP_TYPE_NULL, "Null"},
290 { EDP_TYPE_DISPLAY, "Display"},
291 { EDP_TYPE_INFO, "Info"},
292 { EDP_TYPE_VLAN, "VL"},
293 { EDP_TYPE_ESRP, "ESRP"},
294 { EDP_TYPE_ELRP, "ELRP"},
295 { EDP_TYPE_EAPS, "EAPS"},
296 { EDP_TYPE_ELSM, "ELSM"},
301 static const value_string edp_midtype_vals[] = {
307 static const value_string eaps_type_vals[] = {
309 { 6, "Ring up flush fdb" },
310 { 7, "Ring down flush fdb" },
316 static const value_string eaps_state_vals[] = {
322 { 5, "Pre Forwarding" },
328 dissect_tlv_header(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, int length _U_, proto_tree *tree)
330 proto_item *tlv_item;
331 proto_tree *tlv_tree;
336 tlv_marker = tvb_get_guint8(tvb, offset),
337 tlv_type = tvb_get_guint8(tvb, offset + 1);
338 tlv_length = tvb_get_ntohs(tvb, offset + 2);
340 tlv_item = proto_tree_add_text(tree, tvb, offset, 4,
341 "Marker 0x%02x, length %d, type %d = %s",
342 tlv_marker, tlv_length, tlv_type,
343 val_to_str(tlv_type, edp_type_vals, "Unknown (0x%02x)"));
345 tlv_tree = proto_item_add_subtree(tlv_item, ett_edp_tlv_header);
346 proto_tree_add_item(tlv_tree, hf_edp_tlv_marker, tvb, offset, 1,
350 proto_tree_add_uint(tlv_tree, hf_edp_tlv_type, tvb, offset, 1,
354 proto_tree_add_uint(tlv_tree, hf_edp_tlv_length, tvb, offset, 2,
360 dissect_display_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, int length, proto_tree *tree)
362 proto_item *display_item;
363 proto_tree *display_tree;
364 guint8 *display_name;
366 display_item = proto_tree_add_item(tree, hf_edp_display,
367 tvb, offset, length, FALSE);
369 display_tree = proto_item_add_subtree(display_item, ett_edp_display);
371 dissect_tlv_header(tvb, pinfo, offset, 4, display_tree);
375 display_name = tvb_get_ephemeral_string(tvb, offset, length);
376 proto_item_append_text(display_item, ": \"%s\"",
377 format_text(display_name, strlen(display_name)));
378 proto_tree_add_string(display_tree, hf_edp_display_string, tvb, offset, length,
383 dissect_null_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, int length _U_, proto_tree *tree)
385 proto_item *null_item;
386 proto_tree *null_tree;
388 null_item = proto_tree_add_protocol_format(tree, hf_edp_null,
389 tvb, offset, length, "Null");
391 null_tree = proto_item_add_subtree(null_item, ett_edp_null);
393 dissect_tlv_header(tvb, pinfo, offset, 4, null_tree);
398 dissect_info_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, int length, proto_tree *tree)
400 proto_item *ver_item;
401 proto_tree *ver_tree;
402 guint8 major1, major2, sustaining, internal;
404 proto_item *info_item;
405 proto_tree *info_tree;
407 /* The slot and port numbers printed on the chassis are 1
408 bigger than the transmitted values indicate */
409 slot = tvb_get_ntohs(tvb, offset + 0 + 4) + 1;
410 port = tvb_get_ntohs(tvb, offset + 2 + 4) + 1;
413 major1 = tvb_get_guint8(tvb, offset + 12 + 4);
414 major2 = tvb_get_guint8(tvb, offset + 13 + 4);
415 sustaining = tvb_get_guint8(tvb, offset + 14 + 4);
416 internal = tvb_get_guint8(tvb, offset + 15 + 4);
418 info_item = proto_tree_add_protocol_format(tree, hf_edp_info,
420 "Info: Slot/Port: %d/%d, Version: %d.%d.%d.%d",
421 slot, port, major1, major2, sustaining, internal);
423 info_tree = proto_item_add_subtree(info_item, ett_edp_info);
425 dissect_tlv_header(tvb, pinfo, offset, 4, info_tree);
428 proto_tree_add_uint(info_tree, hf_edp_info_slot, tvb, offset, 2,
432 proto_tree_add_uint(info_tree, hf_edp_info_port, tvb, offset, 2,
436 proto_tree_add_item(info_tree, hf_edp_info_vchassid, tvb, offset, 2,
440 proto_tree_add_item(info_tree, hf_edp_info_reserved, tvb, offset, 6,
444 /* Begin version subtree */
445 ver_item = proto_tree_add_text(info_tree, tvb, offset, 4,
446 "Version: %u.%u.%u Internal: %u", major1, major2,
447 sustaining, internal);
449 ver_tree = proto_item_add_subtree(ver_item, ett_edp_info_version);
451 proto_tree_add_item(ver_tree, hf_edp_info_version, tvb, offset, 4,
454 proto_tree_add_uint(ver_tree, hf_edp_info_version_major1, tvb, offset, 1,
458 proto_tree_add_uint(ver_tree, hf_edp_info_version_major2, tvb, offset, 1,
462 proto_tree_add_uint(ver_tree, hf_edp_info_version_sustaining, tvb, offset, 1,
466 proto_tree_add_uint(ver_tree, hf_edp_info_version_internal, tvb, offset, 1,
469 /* End of version subtree */
471 proto_tree_add_item(info_tree, hf_edp_info_vchassconn, tvb, offset, 16,
477 dissect_vlan_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, int length, proto_tree *tree)
479 proto_item *flags_item;
480 proto_tree *flags_tree;
481 proto_item *vlan_item;
482 proto_tree *vlan_tree;
483 proto_item *too_short_item;
487 vlan_item = proto_tree_add_item(tree, hf_edp_vlan, tvb,
488 offset, length, FALSE);
490 vlan_tree = proto_item_add_subtree(vlan_item, ett_edp_vlan);
492 dissect_tlv_header(tvb, pinfo, offset, 4, vlan_tree);
496 /* Begin flags subtree */
498 too_short_item = proto_tree_add_text(vlan_tree, tvb, 0, 0,
500 PROTO_ITEM_SET_GENERATED(too_short_item);
503 flags_item = proto_tree_add_item(vlan_tree, hf_edp_vlan_flags, tvb, offset, 1,
506 flags_tree = proto_item_add_subtree(flags_item, ett_edp_vlan_flags);
508 proto_tree_add_item(flags_tree, hf_edp_vlan_flags_ip, tvb, offset, 1,
510 proto_tree_add_item(flags_tree, hf_edp_vlan_flags_reserved, tvb, offset, 1,
512 proto_tree_add_item(flags_tree, hf_edp_vlan_flags_unknown, tvb, offset, 1,
516 /* End of flags subtree */
519 too_short_item = proto_tree_add_text(vlan_tree, tvb, 0, 0,
521 PROTO_ITEM_SET_GENERATED(too_short_item);
524 proto_tree_add_item(vlan_tree, hf_edp_vlan_reserved1, tvb, offset, 1,
530 too_short_item = proto_tree_add_text(vlan_tree, tvb, 0, 0,
532 PROTO_ITEM_SET_GENERATED(too_short_item);
535 vlan_id = tvb_get_ntohs(tvb, offset);
536 if (check_col(pinfo->cinfo, COL_INFO))
537 col_append_fstr(pinfo->cinfo, COL_INFO, "%d", vlan_id);
538 proto_item_append_text(vlan_item, ": ID %d", vlan_id);
539 proto_tree_add_uint(vlan_tree, hf_edp_vlan_id, tvb, offset, 2,
545 too_short_item = proto_tree_add_text(vlan_tree, tvb, 0, 0,
547 PROTO_ITEM_SET_GENERATED(too_short_item);
550 proto_tree_add_item(vlan_tree, hf_edp_vlan_reserved2, tvb, offset, 4,
556 too_short_item = proto_tree_add_text(vlan_tree, tvb, 0, 0,
558 PROTO_ITEM_SET_GENERATED(too_short_item);
561 proto_tree_add_item(vlan_tree, hf_edp_vlan_ip, tvb, offset, 4,
566 vlan_name = tvb_get_ephemeral_string(tvb, offset, length);
567 proto_item_append_text(vlan_item, ", Name \"%s\"",
568 format_text(vlan_name, strlen(vlan_name)));
569 proto_tree_add_string(vlan_tree, hf_edp_vlan_name, tvb, offset, length,
575 dissect_esrp_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, int length, proto_tree *tree)
577 proto_item *esrp_item;
578 proto_tree *esrp_tree;
581 group = tvb_get_guint8(tvb, offset + 1 + 4);
582 esrp_item = proto_tree_add_protocol_format(tree, hf_edp_esrp,
583 tvb, offset, length, "ESRP: Group %d", group);
585 esrp_tree = proto_item_add_subtree(esrp_item, ett_edp_esrp);
587 dissect_tlv_header(tvb, pinfo, offset, 4, esrp_tree);
590 proto_tree_add_item(esrp_tree, hf_edp_esrp_proto, tvb, offset, 1,
594 proto_tree_add_item(esrp_tree, hf_edp_esrp_group, tvb, offset, 1,
598 proto_tree_add_item(esrp_tree, hf_edp_esrp_prio, tvb, offset, 2,
602 proto_tree_add_item(esrp_tree, hf_edp_esrp_state, tvb, offset, 2,
606 proto_tree_add_item(esrp_tree, hf_edp_esrp_ports, tvb, offset, 2,
610 proto_tree_add_item(esrp_tree, hf_edp_esrp_virtip, tvb, offset, 4,
614 proto_tree_add_item(esrp_tree, hf_edp_esrp_sysmac, tvb, offset, 6,
618 proto_tree_add_item(esrp_tree, hf_edp_esrp_hello, tvb, offset, 2,
622 proto_tree_add_item(esrp_tree, hf_edp_esrp_reserved, tvb, offset, 2,
626 if (check_col(pinfo->cinfo, COL_PROTOCOL))
627 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ESRP");
631 dissect_eaps_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, int length _U_, proto_tree *tree)
633 proto_item *eaps_item;
634 proto_tree *eaps_tree;
637 ctrlvlanid = tvb_get_ntohs(tvb, offset + 2 + 4);
639 eaps_item = proto_tree_add_protocol_format(tree, hf_edp_eaps,
640 tvb, offset, length, "EAPS: Ctrlvlan %d", ctrlvlanid);
642 eaps_tree = proto_item_add_subtree(eaps_item, ett_edp_eaps);
644 dissect_tlv_header(tvb, pinfo, offset, 4, eaps_tree);
647 proto_tree_add_item(eaps_tree, hf_edp_eaps_ver, tvb, offset, 1,
651 proto_tree_add_item(eaps_tree, hf_edp_eaps_type, tvb, offset, 1,
655 proto_tree_add_item(eaps_tree, hf_edp_eaps_ctrlvlanid, tvb, offset, 2,
659 proto_tree_add_item(eaps_tree, hf_edp_eaps_reserved0, tvb, offset, 4,
663 proto_tree_add_item(eaps_tree, hf_edp_eaps_sysmac, tvb, offset, 6,
667 proto_tree_add_item(eaps_tree, hf_edp_eaps_hello, tvb, offset, 2,
671 proto_tree_add_item(eaps_tree, hf_edp_eaps_fail, tvb, offset, 2,
675 proto_tree_add_item(eaps_tree, hf_edp_eaps_state, tvb, offset, 1,
679 proto_tree_add_item(eaps_tree, hf_edp_eaps_reserved1, tvb, offset, 1,
683 proto_tree_add_item(eaps_tree, hf_edp_eaps_helloseq, tvb, offset, 2,
687 proto_tree_add_item(eaps_tree, hf_edp_eaps_reserved2, tvb, offset, 38,
691 if (check_col(pinfo->cinfo, COL_PROTOCOL))
692 col_set_str(pinfo->cinfo, COL_PROTOCOL, "EAPS");
696 dissect_elsm_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, int length, proto_tree *tree)
698 proto_item *elsm_item;
699 proto_tree *elsm_tree;
701 elsm_item = proto_tree_add_protocol_format(tree, hf_edp_elsm,
702 tvb, offset, length, "ELSM");
704 elsm_tree = proto_item_add_subtree(elsm_item, ett_edp_elsm);
706 dissect_tlv_header(tvb, pinfo, offset, 4, elsm_tree);
710 proto_tree_add_item(elsm_tree, hf_edp_elsm_unknown, tvb, offset, length,
716 dissect_elrp_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, int length, proto_tree *tree)
718 proto_item *elrp_item;
719 proto_tree *elrp_tree;
721 elrp_item = proto_tree_add_protocol_format(tree, hf_edp_elrp,
722 tvb, offset, length, "ELRP");
724 elrp_tree = proto_item_add_subtree(elrp_item, ett_edp_elrp);
726 dissect_tlv_header(tvb, pinfo, offset, 4, elrp_tree);
730 proto_tree_add_item(elrp_tree, hf_edp_elrp_unknown, tvb, offset, length,
735 dissect_unknown_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, int length, proto_tree *tree)
737 proto_item *unknown_item;
738 proto_tree *unknown_tree;
741 tlv_type = tvb_get_guint8(tvb, offset + 1);
743 unknown_item = proto_tree_add_protocol_format(tree, hf_edp_unknown,
744 tvb, offset, length, "Unknown element [0x%02x]", tlv_type);
746 unknown_tree = proto_item_add_subtree(unknown_item, ett_edp_unknown);
748 dissect_tlv_header(tvb, pinfo, offset, 4, unknown_tree);
752 proto_tree_add_item(unknown_tree, hf_edp_unknown_data, tvb, offset, length,
757 dissect_edp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
761 proto_tree *edp_tree = NULL;
762 proto_item *checksum_item;
763 proto_tree *checksum_tree;
765 guint16 packet_checksum, computed_checksum;
766 gboolean checksum_good, checksum_bad;
767 gboolean last = FALSE;
773 if (check_col(pinfo->cinfo, COL_PROTOCOL))
774 col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_SHORT_NAME);
775 if (check_col(pinfo->cinfo, COL_INFO))
776 col_set_str(pinfo->cinfo, COL_INFO, PROTO_SHORT_NAME ":");
779 ti = proto_tree_add_item(tree, proto_edp, tvb, offset, -1,
781 edp_tree = proto_item_add_subtree(ti, ett_edp);
783 proto_tree_add_item(edp_tree, hf_edp_version, tvb, offset, 1,
787 proto_tree_add_item(edp_tree, hf_edp_reserved, tvb, offset, 1,
791 data_length = tvb_get_ntohs(tvb, offset);
792 proto_tree_add_uint(edp_tree, hf_edp_length, tvb, offset, 2,
796 packet_checksum = tvb_get_ntohs(tvb, offset);
798 * If we have the entire ESP packet available, check the checksum.
800 if (tvb_bytes_exist(tvb, 0, data_length)) {
801 /* Checksum from version to null tlv */
802 cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, data_length);
803 cksum_vec[0].len = data_length;
804 computed_checksum = in_cksum(&cksum_vec[0], 1);
805 checksum_good = (computed_checksum == 0);
806 checksum_bad = !checksum_good;
808 checksum_item = proto_tree_add_uint_format(edp_tree,
809 hf_edp_checksum, tvb, offset, 2, packet_checksum,
810 "Checksum: 0x%04x [correct]",
813 checksum_item = proto_tree_add_uint_format(edp_tree,
814 hf_edp_checksum, tvb, offset, 2, packet_checksum,
815 "Checksum: 0x%04x [incorrect, should be 0x%04x]",
817 in_cksum_shouldbe(packet_checksum, computed_checksum));
820 checksum_good = checksum_bad = FALSE;
821 checksum_item = proto_tree_add_uint(edp_tree, hf_edp_checksum,
822 tvb, offset, 2, packet_checksum);
824 checksum_tree = proto_item_add_subtree(checksum_item, ett_edp_checksum);
825 checksum_item = proto_tree_add_boolean(checksum_tree, hf_edp_checksum_good,
826 tvb, offset, 2, checksum_good);
827 PROTO_ITEM_SET_GENERATED(checksum_item);
828 checksum_item = proto_tree_add_boolean(checksum_tree, hf_edp_checksum_bad,
829 tvb, offset, 2, checksum_bad);
830 PROTO_ITEM_SET_GENERATED(checksum_item);
833 proto_tree_add_item(edp_tree, hf_edp_seqno, tvb, offset, 2,
837 /* Machine ID is 8 bytes, if it starts with 0000, the remaining
839 proto_tree_add_item(edp_tree, hf_edp_midtype, tvb, offset, 2,
843 proto_tree_add_item(edp_tree, hf_edp_midmac, tvb, offset, 6,
847 /* Decode the individual TLVs */
848 while (offset < data_length && !last) {
849 if (data_length - offset < 4) {
850 tlvi = proto_tree_add_text(edp_tree, tvb, offset, 4,
851 "Too few bytes left for TLV: %u (< 4)",
852 data_length - offset);
856 tlv_type = tvb_get_guint8(tvb, offset + 1);
857 tlv_length = tvb_get_ntohs(tvb, offset + 2);
859 if ((tlv_length < 4) || (tlv_length > (data_length - offset))) {
860 tlvi = proto_tree_add_text(edp_tree, tvb, offset, 0,
861 "TLV with invalid length: %u", tlv_length);
865 if (check_col(pinfo->cinfo, COL_INFO))
866 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
867 val_to_str(tlv_type, edp_type_vals, "[0x%02x]"));
870 case EDP_TYPE_NULL: /* Last TLV */
871 dissect_null_tlv(tvb, pinfo, offset, tlv_length, edp_tree);
874 case EDP_TYPE_DISPLAY: /* MIB II display string */
875 dissect_display_tlv(tvb, pinfo, offset, tlv_length, edp_tree);
877 case EDP_TYPE_INFO: /* Basic system information */
878 dissect_info_tlv(tvb, pinfo, offset, tlv_length, edp_tree);
880 case EDP_TYPE_VLAN: /* VLAN info */
881 dissect_vlan_tlv(tvb, pinfo, offset, tlv_length, edp_tree);
883 case EDP_TYPE_ESRP: /* Extreme Standby Router Protocol */
884 dissect_esrp_tlv(tvb, pinfo, offset, tlv_length, edp_tree);
886 case EDP_TYPE_EAPS: /* Ethernet Automatic Protection Swtiching */
887 dissect_eaps_tlv(tvb, pinfo, offset, tlv_length, edp_tree);
889 case EDP_TYPE_ELSM: /* Extreme Link Status Monitoring */
890 dissect_elsm_tlv(tvb, pinfo, offset, tlv_length, edp_tree);
892 case EDP_TYPE_ELRP: /* Extreme Loop Recognition Protocol */
893 dissect_elrp_tlv(tvb, pinfo, offset, tlv_length, edp_tree);
896 dissect_unknown_tlv(tvb, pinfo, offset, tlv_length, edp_tree);
899 offset += tlv_length;
906 proto_register_edp(void)
908 static hf_register_info hf[] = {
912 { "Version", "edp.version", FT_UINT8, BASE_DEC, NULL,
916 { "Reserved", "edp.reserved", FT_UINT8, BASE_DEC, NULL,
920 { "Data length", "edp.length", FT_UINT16, BASE_DEC, NULL,
924 { "EDP checksum", "edp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
927 { &hf_edp_checksum_good,
928 { "Good", "edp.checksum_good", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
929 "True: checksum matches packet content; False: doesn't match content or not checked", HFILL }},
931 { &hf_edp_checksum_bad,
932 { "Bad ", "edp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
933 "True: checksum doesn't match packet content; False: matches content or not checked", HFILL }},
936 { "Sequence number", "edp.seqno", FT_UINT16, BASE_DEC, NULL,
940 { "Machine ID type", "edp.midtype", FT_UINT16, BASE_DEC, VALS(edp_midtype_vals),
944 { "Machine MAC", "edp.midmac", FT_ETHER, BASE_NONE, NULL,
948 { &hf_edp_tlv_marker,
949 { "TLV Marker", "edp.tlv.marker", FT_UINT8, BASE_HEX, NULL,
953 { "TLV type", "edp.tlv.type", FT_UINT8, BASE_DEC, VALS(edp_type_vals),
956 { &hf_edp_tlv_length,
957 { "TLV length", "edp.tlv.length", FT_UINT16, BASE_DEC, NULL,
960 /* Display element */
962 { "Display", "edp.display", FT_PROTOCOL, BASE_NONE, NULL,
963 0x0, "Display element", HFILL }},
965 { &hf_edp_display_string,
966 { "Name", "edp.display.string", FT_STRING, BASE_NONE, NULL,
967 0x0, "MIB II display string", HFILL }},
971 { "Info", "edp.info", FT_PROTOCOL, BASE_NONE, NULL,
972 0x0, "Info element", HFILL }},
975 { "Slot", "edp.info.slot", FT_UINT16, BASE_DEC, NULL,
976 0x0, "Originating slot #", HFILL }},
979 { "Port", "edp.info.port", FT_UINT16, BASE_DEC, NULL,
980 0x0, "Originating port #", HFILL }},
982 { &hf_edp_info_vchassid,
983 { "Virt chassis", "edp.info.vchassid", FT_UINT16, BASE_DEC, NULL,
984 0x0, "Virtual chassis ID", HFILL }},
986 { &hf_edp_info_reserved,
987 { "Reserved", "edp.info.reserved", FT_BYTES, BASE_NONE, NULL,
990 { &hf_edp_info_version,
991 { "Version", "edp.info.version", FT_UINT32, BASE_HEX, NULL,
992 0x0, "Software version", HFILL }},
994 { &hf_edp_info_version_major1,
995 { "Version (major1)", "edp.info.version.major1", FT_UINT8, BASE_DEC, NULL,
996 0x0, "Software version (major1)", HFILL }},
998 { &hf_edp_info_version_major2,
999 { "Version (major2)", "edp.info.version.major2", FT_UINT8, BASE_DEC, NULL,
1000 0x0, "Software version (major2)", HFILL }},
1002 { &hf_edp_info_version_sustaining,
1003 { "Version (sustaining)", "edp.info.version.sustaining", FT_UINT8, BASE_DEC, NULL,
1004 0x0, "Software version (sustaining)", HFILL }},
1006 { &hf_edp_info_version_internal,
1007 { "Version (internal)", "edp.info.version.internal", FT_UINT8, BASE_DEC, NULL,
1008 0x0, "Software version (internal)", HFILL }},
1010 { &hf_edp_info_vchassconn,
1011 { "Connections", "edp.info.vchassconn", FT_BYTES, BASE_NONE, NULL,
1012 0x0, "Virtual chassis connections", HFILL }},
1016 { "Vlan", "edp.vlan", FT_PROTOCOL, BASE_NONE, NULL,
1017 0x0, "Vlan element", HFILL }},
1019 { &hf_edp_vlan_flags,
1020 { "Flags", "edp.vlan.flags", FT_UINT8, BASE_HEX, NULL,
1023 { &hf_edp_vlan_flags_ip,
1024 { "Flags-IP", "edp.vlan.flags.ip", FT_BOOLEAN, 8, TFS(&flags_set_truth),
1025 0x80, "Vlan has IP address configured", HFILL }},
1027 { &hf_edp_vlan_flags_reserved,
1028 { "Flags-reserved", "edp.vlan.flags.reserved", FT_UINT8, BASE_HEX, NULL,
1031 { &hf_edp_vlan_flags_unknown,
1032 { "Flags-Unknown", "edp.vlan.flags.unknown", FT_BOOLEAN, 8, TFS(&flags_set_truth),
1035 { &hf_edp_vlan_reserved1,
1036 { "Reserved1", "edp.vlan.reserved1", FT_BYTES, BASE_NONE, NULL,
1040 { "Vlan ID", "edp.vlan.id", FT_UINT16, BASE_DEC, NULL,
1043 { &hf_edp_vlan_reserved2,
1044 { "Reserved2", "edp.vlan.reserved2", FT_BYTES, BASE_NONE, NULL,
1048 { "IP addr", "edp.vlan.ip", FT_IPv4, BASE_NONE, NULL,
1049 0x0, "VLAN IP address", HFILL }},
1051 { &hf_edp_vlan_name,
1052 { "Name", "edp.vlan.name", FT_STRING, BASE_NONE, NULL,
1053 0x0, "VLAN name", HFILL }},
1057 { "ESRP", "edp.esrp", FT_PROTOCOL, BASE_NONE, NULL,
1058 0x0, "Extreme Standby Router Protocol element", HFILL }},
1060 { &hf_edp_esrp_proto,
1061 { "Protocol", "edp.esrp.proto", FT_UINT8, BASE_DEC, VALS(esrp_proto_vals),
1064 { &hf_edp_esrp_group,
1065 { "Group", "edp.esrp.group", FT_UINT8, BASE_DEC, NULL,
1068 { &hf_edp_esrp_prio,
1069 { "Prio", "edp.esrp.prio", FT_UINT16, BASE_DEC, NULL,
1072 { &hf_edp_esrp_state,
1073 { "State", "edp.esrp.state", FT_UINT16, BASE_DEC, VALS(esrp_state_vals),
1076 { &hf_edp_esrp_ports,
1077 { "Ports", "edp.esrp.ports", FT_UINT16, BASE_DEC, NULL,
1078 0x0, "Number of active ports", HFILL }},
1080 { &hf_edp_esrp_virtip,
1081 { "VirtIP", "edp.esrp.virtip", FT_IPv4, BASE_NONE, NULL,
1082 0x0, "Virtual IP address", HFILL }},
1084 { &hf_edp_esrp_sysmac,
1085 { "Sys MAC", "edp.esrp.sysmac", FT_ETHER, BASE_NONE, NULL,
1086 0x0, "System MAC address", HFILL }},
1088 { &hf_edp_esrp_hello,
1089 { "Hello", "edp.esrp.hello", FT_UINT16, BASE_DEC, NULL,
1090 0x0, "Hello timer", HFILL }},
1092 { &hf_edp_esrp_reserved,
1093 { "Reserved", "edp.esrp.reserved", FT_BYTES, BASE_NONE, NULL,
1098 { "EAPS", "edp.eaps", FT_PROTOCOL, BASE_NONE, NULL,
1099 0x0, "Ethernet Automatic Protection Switching element", HFILL }},
1102 { "Version", "edp.eaps.ver", FT_UINT8, BASE_DEC, NULL,
1105 { &hf_edp_eaps_type,
1106 { "Type", "edp.eaps.type", FT_UINT8, BASE_DEC, VALS(eaps_type_vals),
1109 { &hf_edp_eaps_ctrlvlanid,
1110 { "Vlan ID", "edp.eaps.vlanid", FT_UINT16, BASE_DEC, NULL,
1111 0x0, "Control Vlan ID", HFILL }},
1113 { &hf_edp_eaps_reserved0,
1114 { "Reserved0", "edp.eaps.reserved0", FT_BYTES, BASE_NONE, NULL,
1117 { &hf_edp_eaps_sysmac,
1118 { "Sys MAC", "edp.eaps.sysmac", FT_ETHER, BASE_NONE, NULL,
1119 0x0, "System MAC address", HFILL }},
1121 { &hf_edp_eaps_hello,
1122 { "Hello", "edp.eaps.hello", FT_UINT16, BASE_DEC, NULL,
1123 0x0, "Hello timer", HFILL }},
1125 { &hf_edp_eaps_fail,
1126 { "Fail", "edp.eaps.fail", FT_UINT16, BASE_DEC, NULL,
1127 0x0, "Fail timer", HFILL }},
1129 { &hf_edp_eaps_state,
1130 { "State", "edp.eaps.state", FT_UINT8, BASE_DEC, VALS(eaps_state_vals),
1133 { &hf_edp_eaps_reserved1,
1134 { "Reserved1", "edp.eaps.reserved1", FT_BYTES, BASE_NONE, NULL,
1137 { &hf_edp_eaps_helloseq,
1138 { "Helloseq", "edp.eaps.helloseq", FT_UINT16, BASE_DEC, NULL,
1139 0x0, "Hello sequence", HFILL }},
1141 { &hf_edp_eaps_reserved2,
1142 { "Reserved2", "edp.eaps.reserved2", FT_BYTES, BASE_NONE, NULL,
1147 { "ELSM", "edp.elsm", FT_PROTOCOL, BASE_NONE, NULL,
1148 0x0, "Extreme Link Status Monitoring element", HFILL }},
1150 { &hf_edp_elsm_unknown,
1151 { "Unknown", "edp.elsm.unknown", FT_BYTES, BASE_NONE, NULL,
1156 { "ELRP", "edp.elrp", FT_PROTOCOL, BASE_NONE, NULL,
1157 0x0, "Extreme Loop Recognition Protocol element", HFILL }},
1159 { &hf_edp_elrp_unknown,
1160 { "Unknown", "edp.elrp.unknown", FT_BYTES, BASE_NONE, NULL,
1163 /* Unknown element */
1165 { "Unknown", "edp.unknown", FT_PROTOCOL, BASE_NONE, NULL,
1166 0x0, "Element unknown to Wireshark", HFILL }},
1168 { &hf_edp_unknown_data,
1169 { "Unknown", "edp.unknown.data", FT_BYTES, BASE_NONE, NULL,
1174 { "End", "edp.null", FT_PROTOCOL, BASE_NONE, NULL,
1175 0x0, "Last element", HFILL }},
1177 static gint *ett[] = {
1180 &ett_edp_tlv_header,
1181 &ett_edp_vlan_flags,
1184 &ett_edp_info_version,
1194 proto_edp = proto_register_protocol(PROTO_LONG_NAME,
1195 PROTO_SHORT_NAME, "edp");
1196 proto_register_field_array(proto_edp, hf, array_length(hf));
1197 proto_register_subtree_array(ett, array_length(ett));
1201 proto_reg_handoff_edp(void)
1203 dissector_handle_t edp_handle;
1205 edp_handle = create_dissector_handle(dissect_edp, proto_edp);
1206 dissector_add("llc.extreme_pid", 0x00bb, edp_handle);
1210 proto_register_extreme_oui(void)
1212 static hf_register_info hf = {
1213 &hf_llc_extreme_pid,
1214 { "PID", "llc.extreme_pid", FT_UINT16, BASE_HEX,
1215 VALS(extreme_pid_vals), 0x0, "", HFILL },
1218 llc_add_oui(OUI_EXTREME, "llc.extreme_pid", "Extreme OUI PID", &hf);