Get rid of get_ber_last_reated_item() and fix dissection of wIN-TriggerList.
[obnox/wireshark/wip.git] / epan / dissectors / packet-extreme.c
1 /* packet-extreme.c
2  * Routines for the disassembly of Extreme Networks specific
3  * protocols (EDP/ESRP/EAPS)
4  *
5  * $Id$
6  *
7  * Copyright 2005 Joerg Mayer (see AUTHORS file)
8  *
9  * Wireshark - Network traffic analyzer
10  * By Gerald Combs <gerald@wireshark.org>
11  * Copyright 1998 Gerald Combs
12  *
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.
17  *
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.
22  *
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.
26  */
27
28 /*
29   TODO:
30   - General
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:
36         ExtremeN:00:00:06
37    TLV type 0x0e (XOS only?) (EAPSv2?)
38    TLV type 0x15 (XOS only?)
39    EAPS type 0x10 (EAPSv2?)
40    ESRP state 0x03
41
42 Specs:
43
44 EAPS v1 is specified in RFC3619
45
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).
50
51 ================================ snip ================================
52
53 ESRP Packet Format:
54 -------------------
55
56  0                               1
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
71 |            LENGTH             |           CHECKSUM            |
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
91
92
93 ******************************************************************************
94
95
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 ]
99
100 Header format:
101 1 octet: EDP version
102 1 octet: reserved
103 2 octets: length
104 2 octets: checksum
105 2 octets: sequence #
106 8 octets: device id (currently 2 0 octets followed by system mac address)
107
108 TLV stands for Type, Length, Value.
109 Format of a TLV entry:
110 marker ( 1 octet): Hex 99
111 type ( 1 octet):
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
116               Vlan Info                      : 5
117               ESRP                           : 8
118 Length: Length of subsequent data(2 octets)
119 Value: Length octets of data.
120
121 Format for Info TLV:
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).
125 six octets: reserved
126 four octets: software version
127 16 octets: Virtual Chassis Id connections
128
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.
136
137 Display string is merely length octets of the MIBII display string.
138
139 These are the structures you will see most often in EDP frames.
140
141 ================================ snap ================================
142
143  */
144
145 #ifdef HAVE_CONFIG_H
146 #  include "config.h"
147 #endif
148
149 #include <string.h>
150 #include <glib.h>
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>
156
157 static int hf_llc_extreme_pid = -1;
158
159 static int proto_edp = -1;
160 /* EDP header */
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;
167
168 static int hf_edp_seqno = -1;
169 static int hf_edp_midtype = -1;
170 static int hf_edp_midmac = -1;
171 /* TLV header */
172 static int hf_edp_tlv_marker = -1;
173 static int hf_edp_tlv_type = -1;
174 static int hf_edp_tlv_length = -1;
175 /* Display string */
176 static int hf_edp_display = -1;
177 static int hf_edp_display_string = -1;
178 /* Info element */
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;
190 /* Vlan element */
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;
201 /* ESRP element */
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;
212 /* EAPS element */
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;
234 /* Null element */
235 static int hf_edp_null = -1;
236
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;
251
252 #define PROTO_SHORT_NAME "EDP"
253 #define PROTO_LONG_NAME "Extreme Discovery Protocol"
254
255 static const value_string extreme_pid_vals[] = {
256         { 0x00bb,       "EDP" },
257
258         { 0,            NULL }
259 };
260
261 static const value_string esrp_proto_vals[] = {
262         { 0,    "IP" },
263         { 1,    "IPX" },
264         { 2,    "L2" },
265
266         { 0, NULL }
267 };
268
269 static const value_string esrp_state_vals[] = {
270         { 0,    "??" },
271         { 1,    "Master" },
272         { 2,    "Slave" },
273
274         { 0, NULL }
275 };
276
277 typedef enum {
278         EDP_TYPE_NULL = 0,
279         EDP_TYPE_DISPLAY,
280         EDP_TYPE_INFO,
281         EDP_TYPE_VLAN = 5,
282         EDP_TYPE_ESRP = 8,
283         EDP_TYPE_EAPS = 0xb,
284         EDP_TYPE_ELRP = 0xd,
285         EDP_TYPE_ELSM = 0xf
286 } edp_type_t;
287
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"},
297
298         { 0,    NULL }
299 };
300
301 static const value_string edp_midtype_vals[] = {
302         { 0,    "MAC" },
303
304         { 0,    NULL }
305 };
306
307 static const value_string eaps_type_vals[] = {
308         { 5,    "Health" },
309         { 6,    "Ring up flush fdb" },
310         { 7,    "Ring down flush fdb" },
311         { 8,    "Link down" },
312
313         { 0,    NULL }
314 };
315
316 static const value_string eaps_state_vals[] = {
317         { 0,    "Idle" },
318         { 1,    "Complete" },
319         { 2,    "Failed" },
320         { 3,    "Links up" },
321         { 4,    "Links down" },
322         { 5,    "Pre Forwarding" },
323
324         { 0,    NULL }
325 };
326
327 static void
328 dissect_tlv_header(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, int length _U_, proto_tree *tree)
329 {
330         proto_item      *tlv_item;
331         proto_tree      *tlv_tree;
332         guint8          tlv_marker;
333         guint8          tlv_type;
334         guint16         tlv_length;
335
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);
339
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)"));
344
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,
347                 FALSE);
348         offset += 1;
349
350         proto_tree_add_uint(tlv_tree, hf_edp_tlv_type, tvb, offset, 1,
351                 tlv_type);
352         offset += 1;
353
354         proto_tree_add_uint(tlv_tree, hf_edp_tlv_length, tvb, offset, 2,
355                 tlv_length);
356         offset += 2;
357 }
358
359 static void
360 dissect_display_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, int length, proto_tree *tree)
361 {
362         proto_item      *display_item;
363         proto_tree      *display_tree;
364         guint8          *display_name;
365
366         display_item = proto_tree_add_item(tree, hf_edp_display,
367                 tvb, offset, length, FALSE);
368
369         display_tree = proto_item_add_subtree(display_item, ett_edp_display);
370
371         dissect_tlv_header(tvb, pinfo, offset, 4, display_tree);
372         offset += 4;
373         length -= 4;
374
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,
379                 display_name);
380 }
381
382 static void
383 dissect_null_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, int length _U_, proto_tree *tree)
384 {
385         proto_item      *null_item;
386         proto_tree      *null_tree;
387
388         null_item = proto_tree_add_protocol_format(tree, hf_edp_null,
389                 tvb, offset, length, "Null");
390
391         null_tree = proto_item_add_subtree(null_item, ett_edp_null);
392
393         dissect_tlv_header(tvb, pinfo, offset, 4, null_tree);
394         offset += 4;
395 }
396
397 static void
398 dissect_info_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, int length, proto_tree *tree)
399 {
400         proto_item *ver_item;
401         proto_tree *ver_tree;
402         guint8 major1, major2, sustaining, internal;
403         guint16 port, slot;
404         proto_item      *info_item;
405         proto_tree      *info_tree;
406
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;
411
412         /* version */
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);
417
418         info_item = proto_tree_add_protocol_format(tree, hf_edp_info,
419                 tvb, offset, length,
420                 "Info: Slot/Port: %d/%d, Version: %d.%d.%d.%d",
421                 slot, port, major1, major2, sustaining, internal);
422
423         info_tree = proto_item_add_subtree(info_item, ett_edp_info);
424
425         dissect_tlv_header(tvb, pinfo, offset, 4, info_tree);
426         offset += 4;
427
428         proto_tree_add_uint(info_tree, hf_edp_info_slot, tvb, offset, 2,
429                 slot);
430         offset += 2;
431
432         proto_tree_add_uint(info_tree, hf_edp_info_port, tvb, offset, 2,
433                 port);
434         offset += 2;
435
436         proto_tree_add_item(info_tree, hf_edp_info_vchassid, tvb, offset, 2,
437                 FALSE);
438         offset += 2;
439
440         proto_tree_add_item(info_tree, hf_edp_info_reserved, tvb, offset, 6,
441                 FALSE);
442         offset += 6;
443
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);
448
449         ver_tree = proto_item_add_subtree(ver_item, ett_edp_info_version);
450
451         proto_tree_add_item(ver_tree, hf_edp_info_version, tvb, offset, 4,
452                 FALSE);
453
454         proto_tree_add_uint(ver_tree, hf_edp_info_version_major1, tvb, offset, 1,
455                 major1);
456         offset += 1;
457
458         proto_tree_add_uint(ver_tree, hf_edp_info_version_major2, tvb, offset, 1,
459                 major2);
460         offset += 1;
461
462         proto_tree_add_uint(ver_tree, hf_edp_info_version_sustaining, tvb, offset, 1,
463                 sustaining);
464         offset += 1;
465
466         proto_tree_add_uint(ver_tree, hf_edp_info_version_internal, tvb, offset, 1,
467                 internal);
468         offset += 1;
469         /* End of version subtree */
470
471         proto_tree_add_item(info_tree, hf_edp_info_vchassconn, tvb, offset, 16,
472                 FALSE);
473         offset += 16;
474 }
475
476 static void
477 dissect_vlan_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, int length, proto_tree *tree)
478 {
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;
484         guint16         vlan_id;
485         guint8          *vlan_name;
486
487         vlan_item = proto_tree_add_item(tree, hf_edp_vlan, tvb,
488                 offset, length, FALSE);
489
490         vlan_tree = proto_item_add_subtree(vlan_item, ett_edp_vlan);
491
492         dissect_tlv_header(tvb, pinfo, offset, 4, vlan_tree);
493         offset += 4;
494         length -= 4;
495
496         /* Begin flags subtree */
497         if (length < 1) {
498                 too_short_item = proto_tree_add_text(vlan_tree, tvb, 0, 0,
499                     "TLV is too short");
500                 PROTO_ITEM_SET_GENERATED(too_short_item);
501                 return;
502         }
503         flags_item = proto_tree_add_item(vlan_tree, hf_edp_vlan_flags, tvb, offset, 1,
504                 FALSE);
505
506         flags_tree = proto_item_add_subtree(flags_item, ett_edp_vlan_flags);
507
508         proto_tree_add_item(flags_tree, hf_edp_vlan_flags_ip, tvb, offset, 1,
509                 FALSE);
510         proto_tree_add_item(flags_tree, hf_edp_vlan_flags_reserved, tvb, offset, 1,
511                 FALSE);
512         proto_tree_add_item(flags_tree, hf_edp_vlan_flags_unknown, tvb, offset, 1,
513                 FALSE);
514         offset += 1;
515         length -= 1;
516         /* End of flags subtree */
517
518         if (length < 1) {
519                 too_short_item = proto_tree_add_text(vlan_tree, tvb, 0, 0,
520                     "TLV is too short");
521                 PROTO_ITEM_SET_GENERATED(too_short_item);
522                 return;
523         }
524         proto_tree_add_item(vlan_tree, hf_edp_vlan_reserved1, tvb, offset, 1,
525                 FALSE);
526         offset += 1;
527         length -= 1;
528
529         if (length < 2) {
530                 too_short_item = proto_tree_add_text(vlan_tree, tvb, 0, 0,
531                     "TLV is too short");
532                 PROTO_ITEM_SET_GENERATED(too_short_item);
533                 return;
534         }
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,
540                 vlan_id);
541         offset += 2;
542         length -= 2;
543
544         if (length < 4) {
545                 too_short_item = proto_tree_add_text(vlan_tree, tvb, 0, 0,
546                     "TLV is too short");
547                 PROTO_ITEM_SET_GENERATED(too_short_item);
548                 return;
549         }
550         proto_tree_add_item(vlan_tree, hf_edp_vlan_reserved2, tvb, offset, 4,
551                 FALSE);
552         offset += 4;
553         length -= 4;
554
555         if (length < 4) {
556                 too_short_item = proto_tree_add_text(vlan_tree, tvb, 0, 0,
557                     "TLV is too short");
558                 PROTO_ITEM_SET_GENERATED(too_short_item);
559                 return;
560         }
561         proto_tree_add_item(vlan_tree, hf_edp_vlan_ip, tvb, offset, 4,
562                 FALSE);
563         offset += 4;
564         length -= 4;
565
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,
570                 vlan_name);
571         offset += length;
572 }
573
574 static void
575 dissect_esrp_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, int length, proto_tree *tree)
576 {
577         proto_item      *esrp_item;
578         proto_tree      *esrp_tree;
579         guint16         group;
580
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);
584
585         esrp_tree = proto_item_add_subtree(esrp_item, ett_edp_esrp);
586
587         dissect_tlv_header(tvb, pinfo, offset, 4, esrp_tree);
588         offset += 4;
589
590         proto_tree_add_item(esrp_tree, hf_edp_esrp_proto, tvb, offset, 1,
591                 FALSE);
592         offset += 1;
593
594         proto_tree_add_item(esrp_tree, hf_edp_esrp_group, tvb, offset, 1,
595                 FALSE);
596         offset += 1;
597
598         proto_tree_add_item(esrp_tree, hf_edp_esrp_prio, tvb, offset, 2,
599                 FALSE);
600         offset += 2;
601
602         proto_tree_add_item(esrp_tree, hf_edp_esrp_state, tvb, offset, 2,
603                 FALSE);
604         offset += 2;
605
606         proto_tree_add_item(esrp_tree, hf_edp_esrp_ports, tvb, offset, 2,
607                 FALSE);
608         offset += 2;
609
610         proto_tree_add_item(esrp_tree, hf_edp_esrp_virtip, tvb, offset, 4,
611                 FALSE);
612         offset += 4;
613
614         proto_tree_add_item(esrp_tree, hf_edp_esrp_sysmac, tvb, offset, 6,
615                 FALSE);
616         offset += 6;
617
618         proto_tree_add_item(esrp_tree, hf_edp_esrp_hello, tvb, offset, 2,
619                 FALSE);
620         offset += 2;
621
622         proto_tree_add_item(esrp_tree, hf_edp_esrp_reserved, tvb, offset, 2,
623                 FALSE);
624         offset += 2;
625
626         if (check_col(pinfo->cinfo, COL_PROTOCOL))
627                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ESRP");
628 }
629
630 static void
631 dissect_eaps_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, int length _U_, proto_tree *tree)
632 {
633         proto_item      *eaps_item;
634         proto_tree      *eaps_tree;
635         guint16         ctrlvlanid;
636
637         ctrlvlanid = tvb_get_ntohs(tvb, offset + 2 + 4);
638
639         eaps_item = proto_tree_add_protocol_format(tree, hf_edp_eaps,
640                 tvb, offset, length, "EAPS: Ctrlvlan %d", ctrlvlanid);
641
642         eaps_tree = proto_item_add_subtree(eaps_item, ett_edp_eaps);
643
644         dissect_tlv_header(tvb, pinfo, offset, 4, eaps_tree);
645         offset += 4;
646
647         proto_tree_add_item(eaps_tree, hf_edp_eaps_ver, tvb, offset, 1,
648                 FALSE);
649         offset += 1;
650
651         proto_tree_add_item(eaps_tree, hf_edp_eaps_type, tvb, offset, 1,
652                 FALSE);
653         offset += 1;
654
655         proto_tree_add_item(eaps_tree, hf_edp_eaps_ctrlvlanid, tvb, offset, 2,
656                 FALSE);
657         offset += 2;
658
659         proto_tree_add_item(eaps_tree, hf_edp_eaps_reserved0, tvb, offset, 4,
660                 FALSE);
661         offset += 4;
662
663         proto_tree_add_item(eaps_tree, hf_edp_eaps_sysmac, tvb, offset, 6,
664                 FALSE);
665         offset += 6;
666
667         proto_tree_add_item(eaps_tree, hf_edp_eaps_hello, tvb, offset, 2,
668                 FALSE);
669         offset += 2;
670
671         proto_tree_add_item(eaps_tree, hf_edp_eaps_fail, tvb, offset, 2,
672                 FALSE);
673         offset += 2;
674
675         proto_tree_add_item(eaps_tree, hf_edp_eaps_state, tvb, offset, 1,
676                 FALSE);
677         offset += 1;
678
679         proto_tree_add_item(eaps_tree, hf_edp_eaps_reserved1, tvb, offset, 1,
680                 FALSE);
681         offset += 1;
682
683         proto_tree_add_item(eaps_tree, hf_edp_eaps_helloseq, tvb, offset, 2,
684                 FALSE);
685         offset += 2;
686
687         proto_tree_add_item(eaps_tree, hf_edp_eaps_reserved2, tvb, offset, 38,
688                 FALSE);
689         offset += 38;
690
691         if (check_col(pinfo->cinfo, COL_PROTOCOL))
692                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "EAPS");
693 }
694
695 static void
696 dissect_elsm_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, int length, proto_tree *tree)
697 {
698         proto_item      *elsm_item;
699         proto_tree      *elsm_tree;
700
701         elsm_item = proto_tree_add_protocol_format(tree, hf_edp_elsm,
702                 tvb, offset, length, "ELSM");
703
704         elsm_tree = proto_item_add_subtree(elsm_item, ett_edp_elsm);
705
706         dissect_tlv_header(tvb, pinfo, offset, 4, elsm_tree);
707         offset += 4;
708         length -= 4;
709
710         proto_tree_add_item(elsm_tree, hf_edp_elsm_unknown, tvb, offset, length,
711                 FALSE);
712         offset += 4;
713 }
714
715 static void
716 dissect_elrp_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, int length, proto_tree *tree)
717 {
718         proto_item      *elrp_item;
719         proto_tree      *elrp_tree;
720
721         elrp_item = proto_tree_add_protocol_format(tree, hf_edp_elrp,
722                 tvb, offset, length, "ELRP");
723
724         elrp_tree = proto_item_add_subtree(elrp_item, ett_edp_elrp);
725
726         dissect_tlv_header(tvb, pinfo, offset, 4, elrp_tree);
727         offset += 4;
728         length -= 4;
729
730         proto_tree_add_item(elrp_tree, hf_edp_elrp_unknown, tvb, offset, length,
731                 FALSE);
732 }
733
734 static void
735 dissect_unknown_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, int length, proto_tree *tree)
736 {
737         proto_item      *unknown_item;
738         proto_tree      *unknown_tree;
739         guint8          tlv_type;
740
741         tlv_type = tvb_get_guint8(tvb, offset + 1);
742
743         unknown_item = proto_tree_add_protocol_format(tree, hf_edp_unknown,
744                 tvb, offset, length, "Unknown element [0x%02x]", tlv_type);
745
746         unknown_tree = proto_item_add_subtree(unknown_item, ett_edp_unknown);
747
748         dissect_tlv_header(tvb, pinfo, offset, 4, unknown_tree);
749         offset += 4;
750         length -= 4;
751
752         proto_tree_add_item(unknown_tree, hf_edp_unknown_data, tvb, offset, length,
753                 FALSE);
754 }
755
756 static void
757 dissect_edp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
758 {
759         proto_item *ti;
760         proto_item *tlvi;
761         proto_tree *edp_tree = NULL;
762         proto_item *checksum_item;
763         proto_tree *checksum_tree;
764         guint32 offset = 0;
765         guint16 packet_checksum, computed_checksum;
766         gboolean checksum_good, checksum_bad;
767         gboolean last = FALSE;
768         guint8 tlv_type;
769         guint16 tlv_length;
770         guint16 data_length;
771         vec_t cksum_vec[1];
772
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 ":");
777
778         if (tree) {
779                 ti = proto_tree_add_item(tree, proto_edp, tvb, offset, -1,
780                     FALSE);
781                 edp_tree = proto_item_add_subtree(ti, ett_edp);
782
783                 proto_tree_add_item(edp_tree, hf_edp_version, tvb, offset, 1,
784                         FALSE);
785                 offset += 1;
786
787                 proto_tree_add_item(edp_tree, hf_edp_reserved, tvb, offset, 1,
788                         FALSE);
789                 offset += 1;
790
791                 data_length = tvb_get_ntohs(tvb, offset);
792                 proto_tree_add_uint(edp_tree, hf_edp_length, tvb, offset, 2,
793                         data_length);
794                 offset += 2;
795
796                 packet_checksum = tvb_get_ntohs(tvb, offset);
797                 /*
798                  * If we have the entire ESP packet available, check the checksum.
799                  */
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;
807                         if (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]",
811                                         packet_checksum);
812                         } else {
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]",
816                                         packet_checksum,
817                                         in_cksum_shouldbe(packet_checksum, computed_checksum));
818                         }
819                 } else {
820                         checksum_good = checksum_bad = FALSE;
821                         checksum_item = proto_tree_add_uint(edp_tree, hf_edp_checksum,
822                                 tvb, offset, 2, packet_checksum);
823                 }
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);
831                 offset += 2;
832
833                 proto_tree_add_item(edp_tree, hf_edp_seqno, tvb, offset, 2,
834                         FALSE);
835                 offset += 2;
836
837                 /* Machine ID is 8 bytes, if it starts with 0000, the remaining
838                    6 bytes are a MAC */
839                 proto_tree_add_item(edp_tree, hf_edp_midtype, tvb, offset, 2,
840                         FALSE);
841                 offset += 2;
842
843                 proto_tree_add_item(edp_tree, hf_edp_midmac, tvb, offset, 6,
844                         FALSE);
845                 offset += 6;
846
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);
853                                 offset += 4;
854                                 break;
855                         }
856                         tlv_type = tvb_get_guint8(tvb, offset + 1);
857                         tlv_length = tvb_get_ntohs(tvb, offset + 2);
858
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);
862                                 last = TRUE;
863                                 break;
864                         }
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]"));
868
869                         switch (tlv_type) {
870                         case EDP_TYPE_NULL: /* Last TLV */
871                                 dissect_null_tlv(tvb, pinfo, offset, tlv_length, edp_tree);
872                                 last = 1;
873                                 break;
874                         case EDP_TYPE_DISPLAY: /* MIB II display string */
875                                 dissect_display_tlv(tvb, pinfo, offset, tlv_length, edp_tree);
876                                 break;
877                         case EDP_TYPE_INFO: /* Basic system information */
878                                 dissect_info_tlv(tvb, pinfo, offset, tlv_length, edp_tree);
879                                 break;
880                         case EDP_TYPE_VLAN: /* VLAN info */
881                                 dissect_vlan_tlv(tvb, pinfo, offset, tlv_length, edp_tree);
882                                 break;
883                         case EDP_TYPE_ESRP: /* Extreme Standby Router Protocol */
884                                 dissect_esrp_tlv(tvb, pinfo, offset, tlv_length, edp_tree);
885                                 break;
886                         case EDP_TYPE_EAPS: /* Ethernet Automatic Protection Swtiching */
887                                 dissect_eaps_tlv(tvb, pinfo, offset, tlv_length, edp_tree);
888                                 break;
889                         case EDP_TYPE_ELSM: /* Extreme Link Status Monitoring */
890                                 dissect_elsm_tlv(tvb, pinfo, offset, tlv_length, edp_tree);
891                                 break;
892                         case EDP_TYPE_ELRP: /* Extreme Loop Recognition Protocol */
893                                 dissect_elrp_tlv(tvb, pinfo, offset, tlv_length, edp_tree);
894                                 break;
895                         default:
896                                 dissect_unknown_tlv(tvb, pinfo, offset, tlv_length, edp_tree);
897                                 break;
898                         }
899                         offset += tlv_length;
900                 }
901
902         }
903 }
904
905 void
906 proto_register_edp(void)
907 {
908         static hf_register_info hf[] = {
909
910         /* EDP header */
911                 { &hf_edp_version,
912                 { "Version",    "edp.version", FT_UINT8, BASE_DEC, NULL,
913                         0x0, "", HFILL }},
914
915                 { &hf_edp_reserved,
916                 { "Reserved",   "edp.reserved", FT_UINT8, BASE_DEC, NULL,
917                         0x0, "", HFILL }},
918
919                 { &hf_edp_length,
920                 { "Data length",        "edp.length", FT_UINT16, BASE_DEC, NULL,
921                         0x0, "", HFILL }},
922
923                 { &hf_edp_checksum,
924                 { "EDP checksum",       "edp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
925                         "", HFILL }},
926
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 }},
930
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 }},
934
935                 { &hf_edp_seqno,
936                 { "Sequence number",    "edp.seqno", FT_UINT16, BASE_DEC, NULL,
937                         0x0, "", HFILL }},
938
939                 { &hf_edp_midtype,
940                 { "Machine ID type",    "edp.midtype", FT_UINT16, BASE_DEC, VALS(edp_midtype_vals),
941                         0x0, "", HFILL }},
942
943                 { &hf_edp_midmac,
944                 { "Machine MAC",        "edp.midmac", FT_ETHER, BASE_NONE, NULL,
945                         0x0, "", HFILL }},
946
947         /* TLV header */
948                 { &hf_edp_tlv_marker,
949                 { "TLV Marker", "edp.tlv.marker", FT_UINT8, BASE_HEX, NULL,
950                         0x0, "", HFILL }},
951
952                 { &hf_edp_tlv_type,
953                 { "TLV type",   "edp.tlv.type", FT_UINT8, BASE_DEC, VALS(edp_type_vals),
954                         0x0, "", HFILL }},
955
956                 { &hf_edp_tlv_length,
957                 { "TLV length", "edp.tlv.length", FT_UINT16, BASE_DEC, NULL,
958                         0x0, "", HFILL }},
959
960         /* Display element */
961                 { &hf_edp_display,
962                 { "Display",    "edp.display", FT_PROTOCOL, BASE_NONE, NULL,
963                         0x0, "Display element", HFILL }},
964
965                 { &hf_edp_display_string,
966                 { "Name",       "edp.display.string", FT_STRING, BASE_NONE, NULL,
967                         0x0, "MIB II display string", HFILL }},
968
969         /* Info element */
970                 { &hf_edp_info,
971                 { "Info",       "edp.info", FT_PROTOCOL, BASE_NONE, NULL,
972                         0x0, "Info element", HFILL }},
973
974                 { &hf_edp_info_slot,
975                 { "Slot",       "edp.info.slot", FT_UINT16, BASE_DEC, NULL,
976                         0x0, "Originating slot #", HFILL }},
977
978                 { &hf_edp_info_port,
979                 { "Port",       "edp.info.port", FT_UINT16, BASE_DEC, NULL,
980                         0x0, "Originating port #", HFILL }},
981
982                 { &hf_edp_info_vchassid,
983                 { "Virt chassis",       "edp.info.vchassid", FT_UINT16, BASE_DEC, NULL,
984                         0x0, "Virtual chassis ID", HFILL }},
985
986                 { &hf_edp_info_reserved,
987                 { "Reserved",   "edp.info.reserved", FT_BYTES, BASE_NONE, NULL,
988                         0x0, "", HFILL }},
989
990                 { &hf_edp_info_version,
991                 { "Version",    "edp.info.version", FT_UINT32, BASE_HEX, NULL,
992                         0x0, "Software version", HFILL }},
993
994                 { &hf_edp_info_version_major1,
995                 { "Version (major1)",   "edp.info.version.major1", FT_UINT8, BASE_DEC, NULL,
996                         0x0, "Software version (major1)", HFILL }},
997
998                 { &hf_edp_info_version_major2,
999                 { "Version (major2)",   "edp.info.version.major2", FT_UINT8, BASE_DEC, NULL,
1000                         0x0, "Software version (major2)", HFILL }},
1001
1002                 { &hf_edp_info_version_sustaining,
1003                 { "Version (sustaining)",       "edp.info.version.sustaining", FT_UINT8, BASE_DEC, NULL,
1004                         0x0, "Software version (sustaining)", HFILL }},
1005
1006                 { &hf_edp_info_version_internal,
1007                 { "Version (internal)", "edp.info.version.internal", FT_UINT8, BASE_DEC, NULL,
1008                         0x0, "Software version (internal)", HFILL }},
1009
1010                 { &hf_edp_info_vchassconn,
1011                 { "Connections",        "edp.info.vchassconn", FT_BYTES, BASE_NONE, NULL,
1012                         0x0, "Virtual chassis connections", HFILL }},
1013
1014         /* VLAN element */
1015                 { &hf_edp_vlan,
1016                 { "Vlan",       "edp.vlan", FT_PROTOCOL, BASE_NONE, NULL,
1017                         0x0, "Vlan element", HFILL }},
1018
1019                 { &hf_edp_vlan_flags,
1020                 { "Flags",      "edp.vlan.flags", FT_UINT8, BASE_HEX, NULL,
1021                         0x0, "", HFILL }},
1022
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 }},
1026
1027                 { &hf_edp_vlan_flags_reserved,
1028                 { "Flags-reserved",     "edp.vlan.flags.reserved", FT_UINT8, BASE_HEX, NULL,
1029                         0x7e, "", HFILL }},
1030
1031                 { &hf_edp_vlan_flags_unknown,
1032                 { "Flags-Unknown",      "edp.vlan.flags.unknown", FT_BOOLEAN, 8, TFS(&flags_set_truth),
1033                         0x01, "", HFILL }},
1034
1035                 { &hf_edp_vlan_reserved1,
1036                 { "Reserved1",  "edp.vlan.reserved1", FT_BYTES, BASE_NONE, NULL,
1037                         0x0, "", HFILL }},
1038
1039                 { &hf_edp_vlan_id,
1040                 { "Vlan ID",    "edp.vlan.id", FT_UINT16, BASE_DEC, NULL,
1041                         0x0, "", HFILL }},
1042
1043                 { &hf_edp_vlan_reserved2,
1044                 { "Reserved2",  "edp.vlan.reserved2", FT_BYTES, BASE_NONE, NULL,
1045                         0x0, "", HFILL }},
1046
1047                 { &hf_edp_vlan_ip,
1048                 { "IP addr",    "edp.vlan.ip", FT_IPv4, BASE_NONE, NULL,
1049                         0x0, "VLAN IP address", HFILL }},
1050
1051                 { &hf_edp_vlan_name,
1052                 { "Name",       "edp.vlan.name", FT_STRING, BASE_NONE, NULL,
1053                         0x0, "VLAN name", HFILL }},
1054
1055         /* ESRP element */
1056                 { &hf_edp_esrp,
1057                 { "ESRP",       "edp.esrp", FT_PROTOCOL, BASE_NONE, NULL,
1058                         0x0, "Extreme Standby Router Protocol element", HFILL }},
1059
1060                 { &hf_edp_esrp_proto,
1061                 { "Protocol",   "edp.esrp.proto", FT_UINT8, BASE_DEC, VALS(esrp_proto_vals),
1062                         0x0, "", HFILL }},
1063
1064                 { &hf_edp_esrp_group,
1065                 { "Group",      "edp.esrp.group", FT_UINT8, BASE_DEC, NULL,
1066                         0x0, "", HFILL }},
1067
1068                 { &hf_edp_esrp_prio,
1069                 { "Prio",       "edp.esrp.prio", FT_UINT16, BASE_DEC, NULL,
1070                         0x0, "", HFILL }},
1071
1072                 { &hf_edp_esrp_state,
1073                 { "State",      "edp.esrp.state", FT_UINT16, BASE_DEC, VALS(esrp_state_vals),
1074                         0x0, "", HFILL }},
1075
1076                 { &hf_edp_esrp_ports,
1077                 { "Ports",      "edp.esrp.ports", FT_UINT16, BASE_DEC, NULL,
1078                         0x0, "Number of active ports", HFILL }},
1079
1080                 { &hf_edp_esrp_virtip,
1081                 { "VirtIP",     "edp.esrp.virtip", FT_IPv4, BASE_NONE, NULL,
1082                         0x0, "Virtual IP address", HFILL }},
1083
1084                 { &hf_edp_esrp_sysmac,
1085                 { "Sys MAC",    "edp.esrp.sysmac", FT_ETHER, BASE_NONE, NULL,
1086                         0x0, "System MAC address", HFILL }},
1087
1088                 { &hf_edp_esrp_hello,
1089                 { "Hello",      "edp.esrp.hello", FT_UINT16, BASE_DEC, NULL,
1090                         0x0, "Hello timer", HFILL }},
1091
1092                 { &hf_edp_esrp_reserved,
1093                 { "Reserved",   "edp.esrp.reserved", FT_BYTES, BASE_NONE, NULL,
1094                         0x0, "", HFILL }},
1095
1096         /* EAPS element */
1097                 { &hf_edp_eaps,
1098                 { "EAPS",       "edp.eaps", FT_PROTOCOL, BASE_NONE, NULL,
1099                         0x0, "Ethernet Automatic Protection Switching element", HFILL }},
1100
1101                 { &hf_edp_eaps_ver,
1102                 { "Version",    "edp.eaps.ver", FT_UINT8, BASE_DEC, NULL,
1103                         0x0, "", HFILL }},
1104
1105                 { &hf_edp_eaps_type,
1106                 { "Type",       "edp.eaps.type", FT_UINT8, BASE_DEC, VALS(eaps_type_vals),
1107                         0x0, "", HFILL }},
1108
1109                 { &hf_edp_eaps_ctrlvlanid,
1110                 { "Vlan ID",    "edp.eaps.vlanid", FT_UINT16, BASE_DEC, NULL,
1111                         0x0, "Control Vlan ID", HFILL }},
1112
1113                 { &hf_edp_eaps_reserved0,
1114                 { "Reserved0",  "edp.eaps.reserved0", FT_BYTES, BASE_NONE, NULL,
1115                         0x0, "", HFILL }},
1116
1117                 { &hf_edp_eaps_sysmac,
1118                 { "Sys MAC",    "edp.eaps.sysmac", FT_ETHER, BASE_NONE, NULL,
1119                         0x0, "System MAC address", HFILL }},
1120
1121                 { &hf_edp_eaps_hello,
1122                 { "Hello",      "edp.eaps.hello", FT_UINT16, BASE_DEC, NULL,
1123                         0x0, "Hello timer", HFILL }},
1124
1125                 { &hf_edp_eaps_fail,
1126                 { "Fail",       "edp.eaps.fail", FT_UINT16, BASE_DEC, NULL,
1127                         0x0, "Fail timer", HFILL }},
1128
1129                 { &hf_edp_eaps_state,
1130                 { "State",      "edp.eaps.state", FT_UINT8, BASE_DEC, VALS(eaps_state_vals),
1131                         0x0, "", HFILL }},
1132
1133                 { &hf_edp_eaps_reserved1,
1134                 { "Reserved1",  "edp.eaps.reserved1", FT_BYTES, BASE_NONE, NULL,
1135                         0x0, "", HFILL }},
1136
1137                 { &hf_edp_eaps_helloseq,
1138                 { "Helloseq",   "edp.eaps.helloseq", FT_UINT16, BASE_DEC, NULL,
1139                         0x0, "Hello sequence", HFILL }},
1140
1141                 { &hf_edp_eaps_reserved2,
1142                 { "Reserved2",  "edp.eaps.reserved2", FT_BYTES, BASE_NONE, NULL,
1143                         0x0, "", HFILL }},
1144
1145         /* ELSM element */
1146                 { &hf_edp_elsm,
1147                 { "ELSM",       "edp.elsm", FT_PROTOCOL, BASE_NONE, NULL,
1148                         0x0, "Extreme Link Status Monitoring element", HFILL }},
1149
1150                 { &hf_edp_elsm_unknown,
1151                 { "Unknown",    "edp.elsm.unknown", FT_BYTES, BASE_NONE, NULL,
1152                         0x0, "", HFILL }},
1153
1154         /* ELRP element */
1155                 { &hf_edp_elrp,
1156                 { "ELRP",       "edp.elrp", FT_PROTOCOL, BASE_NONE, NULL,
1157                         0x0, "Extreme Loop Recognition Protocol element", HFILL }},
1158
1159                 { &hf_edp_elrp_unknown,
1160                 { "Unknown",    "edp.elrp.unknown", FT_BYTES, BASE_NONE, NULL,
1161                         0x0, "", HFILL }},
1162
1163         /* Unknown element */
1164                 { &hf_edp_unknown,
1165                 { "Unknown",    "edp.unknown", FT_PROTOCOL, BASE_NONE, NULL,
1166                         0x0, "Element unknown to Wireshark", HFILL }},
1167
1168                 { &hf_edp_unknown_data,
1169                 { "Unknown",    "edp.unknown.data", FT_BYTES, BASE_NONE, NULL,
1170                         0x0, "", HFILL }},
1171
1172         /* Null element */
1173                 { &hf_edp_null,
1174                 { "End",        "edp.null", FT_PROTOCOL, BASE_NONE, NULL,
1175                         0x0, "Last element", HFILL }},
1176         };
1177         static gint *ett[] = {
1178                 &ett_edp,
1179                 &ett_edp_checksum,
1180                 &ett_edp_tlv_header,
1181                 &ett_edp_vlan_flags,
1182                 &ett_edp_display,
1183                 &ett_edp_info,
1184                 &ett_edp_info_version,
1185                 &ett_edp_vlan,
1186                 &ett_edp_esrp,
1187                 &ett_edp_eaps,
1188                 &ett_edp_elrp,
1189                 &ett_edp_elsm,
1190                 &ett_edp_unknown,
1191                 &ett_edp_null,
1192         };
1193
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));
1198 }
1199
1200 void
1201 proto_reg_handoff_edp(void)
1202 {
1203         dissector_handle_t edp_handle;
1204
1205         edp_handle = create_dissector_handle(dissect_edp, proto_edp);
1206         dissector_add("llc.extreme_pid", 0x00bb, edp_handle);
1207 }
1208
1209 void
1210 proto_register_extreme_oui(void)
1211 {
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 },
1216         };
1217
1218         llc_add_oui(OUI_EXTREME, "llc.extreme_pid", "Extreme OUI PID", &hf);
1219 }