1 /* packet-slowprotocols.c
2 * Routines for EtherType (0x8809) Slow Protocols disassembly.
4 * $Id: packet-slowprotocols.c,v 1.4 2002/08/28 21:00:31 jmayer Exp $
6 * Copyright 2002 Steve Housley <steve_housley@3com.com>
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@ethereal.com>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 /* *** WARNING!! *** Only a dissector for LACPDU (Link Aggregation Control
28 * Protocol Data Unit) disassembly has currently been implemented.
38 #include <epan/packet.h>
42 #include <epan/resolv.h>
44 /* Offsets of fields within a LACPDU */
46 #define LACPDU_SUBTYPE 0
47 #define LACPDU_VERSION_NUMBER 1
49 #define LACPDU_ACTOR_TYPE 2
50 #define LACPDU_ACTOR_INFO_LEN 3
51 #define LACPDU_ACTOR_SYS_PRIORITY 4
52 #define LACPDU_ACTOR_SYSTEM 6
53 #define LACPDU_ACTOR_KEY 12
54 #define LACPDU_ACTOR_PORT_PRIORITY 14
55 #define LACPDU_ACTOR_PORT 16
56 #define LACPDU_ACTOR_STATE 18
57 #define LACPDU_ACTOR_RESERVED 19
59 #define LACPDU_PARTNER_TYPE 22
60 #define LACPDU_PARTNER_INFO_LEN 23
61 #define LACPDU_PARTNER_SYS_PRIORITY 24
62 #define LACPDU_PARTNER_SYSTEM 26
63 #define LACPDU_PARTNER_KEY 32
64 #define LACPDU_PARTNER_PORT_PRIORITY 34
65 #define LACPDU_PARTNER_PORT 36
66 #define LACPDU_PARTNER_STATE 38
67 #define LACPDU_PARTNER_RESERVED 39
69 #define LACPDU_COLL_TYPE 42
70 #define LACPDU_COLL_INFO_LEN 43
71 #define LACPDU_COLL_MAX_DELAY 44
72 #define LACPDU_COLL_RESERVED 46
74 #define LACPDU_TERM_TYPE 58
75 #define LACPDU_TERM_LEN 59
76 #define LACPDU_TERM_RESERVED 60
78 /* Actor and Partner Flag bits */
80 #define LACPDU_FLAGS_ACTIVITY 0x01
81 #define LACPDU_FLAGS_TIMEOUT 0x02
82 #define LACPDU_FLAGS_AGGREGATION 0x04
83 #define LACPDU_FLAGS_SYNC 0x08
84 #define LACPDU_FLAGS_COLLECTING 0x10
85 #define LACPDU_FLAGS_DISTRIB 0x20
86 #define LACPDU_FLAGS_DEFAULTED 0x40
87 #define LACPDU_FLAGS_EXPIRED 0x80
89 /* Initialise the protocol and registered fields */
91 static int proto_lacpdu = -1;
93 static int hf_lacpdu_subtype = -1;
94 static int hf_lacpdu_version_number = -1;
96 static int hf_lacpdu_actor_type = -1;
97 static int hf_lacpdu_actor_info_len = -1;
98 static int hf_lacpdu_actor_sys_priority = -1;
99 static int hf_lacpdu_actor_sys = -1;
100 static int hf_lacpdu_actor_key = -1;
101 static int hf_lacpdu_actor_port_priority = -1;
102 static int hf_lacpdu_actor_port = -1;
103 static int hf_lacpdu_actor_state = -1;
104 static int hf_lacpdu_flags_a_activity = -1;
105 static int hf_lacpdu_flags_a_timeout = -1;
106 static int hf_lacpdu_flags_a_aggregation = -1;
107 static int hf_lacpdu_flags_a_sync = -1;
108 static int hf_lacpdu_flags_a_collecting = -1;
109 static int hf_lacpdu_flags_a_distrib = -1;
110 static int hf_lacpdu_flags_a_defaulted = -1;
111 static int hf_lacpdu_flags_a_expired = -1;
112 static int hf_lacpdu_actor_reserved = -1;
114 static int hf_lacpdu_partner_type = -1;
115 static int hf_lacpdu_partner_info_len = -1;
116 static int hf_lacpdu_partner_sys_priority = -1;
117 static int hf_lacpdu_partner_sys = -1;
118 static int hf_lacpdu_partner_key = -1;
119 static int hf_lacpdu_partner_port_priority = -1;
120 static int hf_lacpdu_partner_port = -1;
121 static int hf_lacpdu_partner_state = -1;
122 static int hf_lacpdu_flags_p_activity = -1;
123 static int hf_lacpdu_flags_p_timeout = -1;
124 static int hf_lacpdu_flags_p_aggregation = -1;
125 static int hf_lacpdu_flags_p_sync = -1;
126 static int hf_lacpdu_flags_p_collecting = -1;
127 static int hf_lacpdu_flags_p_distrib = -1;
128 static int hf_lacpdu_flags_p_defaulted = -1;
129 static int hf_lacpdu_flags_p_expired = -1;
130 static int hf_lacpdu_partner_reserved = -1;
132 static int hf_lacpdu_coll_type = -1;
133 static int hf_lacpdu_coll_info_len = -1;
134 static int hf_lacpdu_coll_max_delay = -1;
135 static int hf_lacpdu_coll_reserved = -1;
137 static int hf_lacpdu_term_type = -1;
138 static int hf_lacpdu_term_len = -1;
139 static int hf_lacpdu_term_reserved = -1;
141 /* Initialise the subtree pointers */
143 static gint ett_lacpdu = -1;
144 static gint ett_lacpdu_a_flags = -1;
145 static gint ett_lacpdu_p_flags = -1;
147 /* General declarations and macros */
149 #define LACP_SUBTYPE 0x1
151 static const char initial_sep[] = " (";
152 static const char cont_sep[] = ", ";
154 #define APPEND_BOOLEAN_FLAG(flag, item, string) \
157 proto_item_append_text(item, string, sep); \
161 /* Code to actually dissect the LACPDU packets */
163 dissect_lacpdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
172 const guint8 *resv_bytes;
174 proto_tree *lacpdu_tree;
175 proto_item *lacpdu_item;
176 proto_tree *actor_flags_tree;
177 proto_item *actor_flags_item;
178 proto_tree *partner_flags_tree;
179 proto_item *partner_flags_item;
185 if (check_col(pinfo->cinfo, COL_PROTOCOL))
187 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LACP"); /* LACP Protocol */
190 if (check_col(pinfo->cinfo, COL_INFO))
192 col_clear(pinfo->cinfo, COL_INFO);
197 /* Add LACP Heading */
198 lacpdu_item = proto_tree_add_protocol_format(tree, proto_lacpdu, tvb,
199 0, -1, "Link Aggregation Control Protocol");
200 lacpdu_tree = proto_item_add_subtree(lacpdu_item, ett_lacpdu);
203 raw_octet = tvb_get_guint8(tvb, LACPDU_VERSION_NUMBER);
204 proto_tree_add_uint(lacpdu_tree, hf_lacpdu_version_number, tvb,
205 LACPDU_VERSION_NUMBER, 1, raw_octet);
207 if (check_col(pinfo->cinfo, COL_INFO))
209 col_append_fstr(pinfo->cinfo, COL_INFO, "Version %d. ", raw_octet);
213 raw_octet = tvb_get_guint8(tvb, LACPDU_ACTOR_TYPE);
214 proto_tree_add_uint(lacpdu_tree, hf_lacpdu_actor_type, tvb,
215 LACPDU_ACTOR_TYPE, 1, raw_octet);
217 /* Actor Info Length */
218 raw_octet = tvb_get_guint8(tvb, LACPDU_ACTOR_INFO_LEN);
219 proto_tree_add_uint(lacpdu_tree, hf_lacpdu_actor_info_len, tvb,
220 LACPDU_ACTOR_INFO_LEN, 1, raw_octet);
222 /* Actor System Priority */
224 raw_word = tvb_get_ntohs(tvb, LACPDU_ACTOR_SYS_PRIORITY);
225 proto_tree_add_uint(lacpdu_tree, hf_lacpdu_actor_sys_priority, tvb,
226 LACPDU_ACTOR_SYS_PRIORITY, 2, raw_word);
229 a_sys = tvb_get_ptr(tvb, LACPDU_ACTOR_SYSTEM , 6);
230 proto_tree_add_ether(lacpdu_tree, hf_lacpdu_actor_sys, tvb,
231 LACPDU_ACTOR_SYSTEM, 6, a_sys);
235 raw_word = tvb_get_ntohs(tvb, LACPDU_ACTOR_KEY);
236 proto_tree_add_uint(lacpdu_tree, hf_lacpdu_actor_key, tvb,
237 LACPDU_ACTOR_KEY, 2, raw_word);
239 /* Actor Port Priority */
241 raw_word = tvb_get_ntohs(tvb, LACPDU_ACTOR_PORT_PRIORITY);
242 proto_tree_add_uint(lacpdu_tree, hf_lacpdu_actor_port_priority, tvb,
243 LACPDU_ACTOR_PORT_PRIORITY, 2, raw_word);
247 raw_word = tvb_get_ntohs(tvb, LACPDU_ACTOR_PORT);
248 proto_tree_add_uint(lacpdu_tree, hf_lacpdu_actor_port, tvb,
249 LACPDU_ACTOR_PORT, 2, raw_word);
251 if (check_col(pinfo->cinfo, COL_INFO))
253 col_append_fstr(pinfo->cinfo, COL_INFO, "Actor Port = %d ", raw_word);
258 flags = tvb_get_guint8(tvb, LACPDU_ACTOR_STATE);
259 actor_flags_item = proto_tree_add_uint(lacpdu_tree, hf_lacpdu_actor_state, tvb,
260 LACPDU_ACTOR_STATE, 1, flags);
261 actor_flags_tree = proto_item_add_subtree(actor_flags_item, ett_lacpdu_a_flags);
267 APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_ACTIVITY, actor_flags_item,
269 proto_tree_add_boolean(actor_flags_tree, hf_lacpdu_flags_a_activity, tvb,
270 LACPDU_ACTOR_STATE, 1, flags);
274 APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_TIMEOUT, actor_flags_item,
276 proto_tree_add_boolean(actor_flags_tree, hf_lacpdu_flags_a_timeout, tvb,
277 LACPDU_ACTOR_STATE, 1, flags);
279 /* Aggregation Flag */
281 APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_AGGREGATION, actor_flags_item,
283 proto_tree_add_boolean(actor_flags_tree, hf_lacpdu_flags_a_aggregation, tvb,
284 LACPDU_ACTOR_STATE, 1, flags);
286 /* Synchronization Flag */
288 APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_SYNC, actor_flags_item,
289 "%sSynchronization");
290 proto_tree_add_boolean(actor_flags_tree, hf_lacpdu_flags_a_sync, tvb,
291 LACPDU_ACTOR_STATE, 1, flags);
293 /* Collecting Flag */
295 APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_COLLECTING, actor_flags_item,
297 proto_tree_add_boolean(actor_flags_tree, hf_lacpdu_flags_a_collecting, tvb,
298 LACPDU_ACTOR_STATE, 1, flags);
301 /* Distributing Flag */
303 APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_DISTRIB, actor_flags_item,
305 proto_tree_add_boolean(actor_flags_tree, hf_lacpdu_flags_a_distrib, tvb,
306 LACPDU_ACTOR_STATE, 1, flags);
310 APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_DEFAULTED, actor_flags_item,
312 proto_tree_add_boolean(actor_flags_tree, hf_lacpdu_flags_a_defaulted, tvb,
313 LACPDU_ACTOR_STATE, 1, flags);
317 APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_EXPIRED, actor_flags_item,
319 proto_tree_add_boolean(actor_flags_tree, hf_lacpdu_flags_a_expired, tvb,
320 LACPDU_ACTOR_STATE, 1, flags);
323 if (sep != initial_sep)
325 /* We put something in; put in the terminating ")" */
326 proto_item_append_text(actor_flags_item, ")");
331 resv_bytes = tvb_get_ptr(tvb, LACPDU_ACTOR_RESERVED, 3);
332 proto_tree_add_bytes(lacpdu_tree, hf_lacpdu_actor_reserved, tvb,
333 LACPDU_ACTOR_RESERVED, 3, resv_bytes);
337 raw_octet = tvb_get_guint8(tvb, LACPDU_PARTNER_TYPE);
338 proto_tree_add_uint(lacpdu_tree, hf_lacpdu_partner_type, tvb,
339 LACPDU_PARTNER_TYPE, 1, raw_octet);
341 /* Partner Info Length */
342 raw_octet = tvb_get_guint8(tvb, LACPDU_PARTNER_INFO_LEN);
343 proto_tree_add_uint(lacpdu_tree, hf_lacpdu_partner_info_len, tvb,
344 LACPDU_PARTNER_INFO_LEN, 1, raw_octet);
346 /* Partner System Priority */
348 raw_word = tvb_get_ntohs(tvb, LACPDU_PARTNER_SYS_PRIORITY);
349 proto_tree_add_uint(lacpdu_tree, hf_lacpdu_partner_sys_priority, tvb,
350 LACPDU_PARTNER_SYS_PRIORITY, 2, raw_word);
354 p_sys = tvb_get_ptr(tvb, LACPDU_PARTNER_SYSTEM, 6);
355 proto_tree_add_ether(lacpdu_tree, hf_lacpdu_partner_sys, tvb,
356 LACPDU_PARTNER_SYSTEM, 6, p_sys);
360 raw_word = tvb_get_ntohs(tvb, LACPDU_PARTNER_KEY);
361 proto_tree_add_uint(lacpdu_tree, hf_lacpdu_partner_key, tvb,
362 LACPDU_PARTNER_KEY, 2, raw_word);
364 /* Partner Port Priority */
366 raw_word = tvb_get_ntohs(tvb, LACPDU_PARTNER_PORT_PRIORITY);
367 proto_tree_add_uint(lacpdu_tree, hf_lacpdu_partner_port_priority, tvb,
368 LACPDU_PARTNER_PORT_PRIORITY, 2, raw_word);
372 raw_word = tvb_get_ntohs(tvb, LACPDU_PARTNER_PORT);
373 proto_tree_add_uint(lacpdu_tree, hf_lacpdu_partner_port, tvb,
374 LACPDU_PARTNER_PORT, 2, raw_word);
376 if (check_col(pinfo->cinfo, COL_INFO))
378 col_append_fstr(pinfo->cinfo, COL_INFO, "Partner Port = %d ", raw_word);
383 flags = tvb_get_guint8(tvb, LACPDU_PARTNER_STATE);
384 partner_flags_item = proto_tree_add_uint(lacpdu_tree, hf_lacpdu_partner_state, tvb,
385 LACPDU_PARTNER_STATE, 1, flags);
386 partner_flags_tree = proto_item_add_subtree(partner_flags_item, ett_lacpdu_p_flags);
392 APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_ACTIVITY, partner_flags_item,
394 proto_tree_add_boolean(partner_flags_tree, hf_lacpdu_flags_p_activity, tvb,
395 LACPDU_PARTNER_STATE, 1, flags);
399 APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_TIMEOUT, partner_flags_item,
401 proto_tree_add_boolean(partner_flags_tree, hf_lacpdu_flags_p_timeout, tvb,
402 LACPDU_PARTNER_STATE, 1, flags);
404 /* Aggregation Flag */
406 APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_AGGREGATION, partner_flags_item,
408 proto_tree_add_boolean(partner_flags_tree, hf_lacpdu_flags_p_aggregation, tvb,
409 LACPDU_PARTNER_STATE, 1, flags);
411 /* Synchronization Flag */
413 APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_SYNC, partner_flags_item,
414 "%sSynchronization");
415 proto_tree_add_boolean(partner_flags_tree, hf_lacpdu_flags_p_sync, tvb,
416 LACPDU_PARTNER_STATE, 1, flags);
418 /* Collecting Flag */
420 APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_COLLECTING, partner_flags_item,
422 proto_tree_add_boolean(partner_flags_tree, hf_lacpdu_flags_p_collecting, tvb,
423 LACPDU_PARTNER_STATE, 1, flags);
426 /* Distributing Flag */
428 APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_DISTRIB, partner_flags_item,
430 proto_tree_add_boolean(partner_flags_tree, hf_lacpdu_flags_p_distrib, tvb,
431 LACPDU_PARTNER_STATE, 1, flags);
435 APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_DEFAULTED, partner_flags_item,
437 proto_tree_add_boolean(partner_flags_tree, hf_lacpdu_flags_p_defaulted, tvb,
438 LACPDU_PARTNER_STATE, 1, flags);
442 APPEND_BOOLEAN_FLAG(flags & LACPDU_FLAGS_EXPIRED, partner_flags_item,
444 proto_tree_add_boolean(partner_flags_tree, hf_lacpdu_flags_p_expired, tvb,
445 LACPDU_PARTNER_STATE, 1, flags);
448 if (sep != initial_sep)
450 /* We put something in; put in the terminating ")" */
451 proto_item_append_text(partner_flags_item, ")");
454 /* Partner Reserved */
456 resv_bytes = tvb_get_ptr(tvb, LACPDU_PARTNER_RESERVED, 3);
457 proto_tree_add_bytes(lacpdu_tree, hf_lacpdu_partner_reserved, tvb,
458 LACPDU_PARTNER_RESERVED, 3, resv_bytes);
462 raw_octet = tvb_get_guint8(tvb, LACPDU_COLL_TYPE);
463 proto_tree_add_uint(lacpdu_tree, hf_lacpdu_coll_type, tvb,
464 LACPDU_COLL_TYPE, 1, raw_octet);
466 /* Collector Info Length */
467 raw_octet = tvb_get_guint8(tvb, LACPDU_COLL_INFO_LEN);
468 proto_tree_add_uint(lacpdu_tree, hf_lacpdu_coll_info_len, tvb,
469 LACPDU_COLL_INFO_LEN, 1, raw_octet);
471 /* Collector Max Delay */
473 raw_word = tvb_get_ntohs(tvb, LACPDU_COLL_MAX_DELAY);
474 proto_tree_add_uint(lacpdu_tree, hf_lacpdu_coll_max_delay, tvb,
475 LACPDU_COLL_MAX_DELAY, 2, raw_word);
477 /* Collector Reserved */
479 resv_bytes = tvb_get_ptr(tvb, LACPDU_COLL_RESERVED, 12);
480 proto_tree_add_bytes(lacpdu_tree, hf_lacpdu_coll_reserved, tvb,
481 LACPDU_COLL_RESERVED, 12, resv_bytes);
483 /* Terminator Type */
484 raw_octet = tvb_get_guint8(tvb, LACPDU_TERM_TYPE);
485 proto_tree_add_uint(lacpdu_tree, hf_lacpdu_term_type, tvb,
486 LACPDU_TERM_TYPE, 1, raw_octet);
488 /* Terminator Info Length */
489 raw_octet = tvb_get_guint8(tvb, LACPDU_TERM_LEN);
490 proto_tree_add_uint(lacpdu_tree, hf_lacpdu_term_len, tvb,
491 LACPDU_TERM_LEN, 1, raw_octet);
493 /* Terminator Reserved */
495 resv_bytes = tvb_get_ptr(tvb, LACPDU_TERM_RESERVED, 50);
496 proto_tree_add_bytes(lacpdu_tree, hf_lacpdu_term_reserved, tvb,
497 LACPDU_TERM_RESERVED, 50, resv_bytes);
502 /* Code to dissect the Slow Protocol packets */
504 dissect_slow_protocols(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
511 /* Get the Slow Protocol Subtype value */
512 raw_octet = tvb_get_guint8(tvb, LACPDU_SUBTYPE);
514 if (raw_octet != LACP_SUBTYPE)
516 /* This is not a LACPDU. Do not disassemble. */
517 /* Requires implementation at a later date. */
518 if (check_col(pinfo->cinfo, COL_PROTOCOL))
520 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Slow Protocols"); /* Slow Protocols */
523 /* Display the subtype value to aid the user. */
524 if (check_col(pinfo->cinfo, COL_INFO))
526 col_add_fstr(pinfo->cinfo, COL_INFO, "Subtype = %u.", raw_octet);
532 /* This is a LACPDU so decode it! */
533 dissect_lacpdu(tvb, pinfo, tree);
538 /* Register the protocol with Ethereal */
540 static const value_string subtype_vals[] = {
542 { 2, "Marker Protocol" },
546 static const true_false_string yesno = {
552 proto_register_lacpdu(void)
554 /* Setup list of header fields */
556 static hf_register_info hf[] = {
558 { &hf_lacpdu_subtype,
559 { "Subtype", "lacp.subtype",
560 FT_UINT8, BASE_HEX, VALS(subtype_vals), 0x0,
561 "The specific Slow Protocol being used", HFILL }},
563 { &hf_lacpdu_version_number,
564 { "LACP Version Number", "lacp.version",
565 FT_UINT8, BASE_HEX, NULL, 0x0,
566 "Identifies the LACP version", HFILL }},
568 { &hf_lacpdu_actor_type,
569 { "Actor Information", "lacp.actorInfo",
570 FT_UINT8, BASE_HEX, NULL, 0x0,
571 "TLV type = Actor", HFILL }},
573 { &hf_lacpdu_actor_info_len,
574 { "Actor Information Length", "lacp.actorInfoLen",
575 FT_UINT8, BASE_HEX, NULL, 0x0,
576 "The length of the Actor TLV", HFILL }},
578 { &hf_lacpdu_actor_sys_priority,
579 { "Actor System Priority", "lacp.actorSysPriority",
580 FT_UINT16, BASE_DEC, NULL, 0x0,
581 "The priority assigned to this System by management or admin", HFILL }},
583 { &hf_lacpdu_actor_sys,
584 { "Actor System", "lacp.actorSystem",
585 FT_ETHER, BASE_NONE, NULL, 0x0,
586 "The Actor's System ID encoded as a MAC address", HFILL }},
588 { &hf_lacpdu_actor_key,
589 { "Actor Key", "lacp.actorKey",
590 FT_UINT16, BASE_DEC, NULL, 0x0,
591 "The operational Key value assigned to the port by the Actor", HFILL }},
593 { &hf_lacpdu_actor_port_priority,
594 { "Actor Port Priority", "lacp.actorPortPriority",
595 FT_UINT16, BASE_DEC, NULL, 0x0,
596 "The priority assigned to the port by the Actor (via Management or Admin)", HFILL }},
598 { &hf_lacpdu_actor_port,
599 { "Actor Port", "lacp.actorPort",
600 FT_UINT16, BASE_DEC, NULL, 0x0,
601 "The port number assigned to the port by the Actor (via Management or Admin)", HFILL }},
603 { &hf_lacpdu_actor_state,
604 { "Actor State", "lacp.actorState",
605 FT_UINT8, BASE_HEX, NULL, 0x0,
606 "The Actor's state variables for the port, encoded as bits within a single octet", HFILL }},
608 { &hf_lacpdu_flags_a_activity,
609 { "LACP Activity", "lacp.actorState.activity",
610 FT_BOOLEAN, 8, TFS(&yesno), LACPDU_FLAGS_ACTIVITY,
611 "Activity control value for this link. Active = 1, Passive = 0", HFILL }},
613 { &hf_lacpdu_flags_a_timeout,
614 { "LACP Timeout", "lacp.actorState.timeout",
615 FT_BOOLEAN, 8, TFS(&yesno), LACPDU_FLAGS_TIMEOUT,
616 "Timeout control value for this link. Short Timeout = 1, Long Timeout = 0", HFILL }},
619 { &hf_lacpdu_flags_a_aggregation,
620 { "Aggregation", "lacp.actorState.aggregation",
621 FT_BOOLEAN, 8, TFS(&yesno), LACPDU_FLAGS_AGGREGATION,
622 "Aggregatable = 1, Individual = 0", HFILL }},
625 { &hf_lacpdu_flags_a_sync,
626 { "Synchronization", "lacp.actorState.synchronization",
627 FT_BOOLEAN, 8, TFS(&yesno), LACPDU_FLAGS_SYNC,
628 "In Sync = 1, Out of Sync = 0", HFILL }},
631 { &hf_lacpdu_flags_a_collecting,
632 { "Collecting", "lacp.actorState.collecting",
633 FT_BOOLEAN, 8, TFS(&yesno), LACPDU_FLAGS_COLLECTING,
634 "Collection of incoming frames is: Enabled = 1, Disabled = 0", HFILL }},
637 { &hf_lacpdu_flags_a_distrib,
638 { "Distributing", "lacp.actorState.distributing",
639 FT_BOOLEAN, 8, TFS(&yesno), LACPDU_FLAGS_DISTRIB,
640 "Distribution of outgoing frames is: Enabled = 1, Disabled = 0", HFILL }},
644 { &hf_lacpdu_flags_a_defaulted,
645 { "Defaulted", "lacp.actorState.defaulted",
646 FT_BOOLEAN, 8, TFS(&yesno), LACPDU_FLAGS_DEFAULTED,
647 "1 = Actor Rx machine is using DEFAULT Partner info, 0 = using info in Rx'd LACPDU", HFILL }},
650 { &hf_lacpdu_flags_a_expired,
651 { "Expired", "lacp.actorState.expired",
652 FT_BOOLEAN, 8, TFS(&yesno), LACPDU_FLAGS_EXPIRED,
653 "1 = Actor Rx machine is EXPIRED, 0 = is NOT EXPIRED", HFILL }},
656 { &hf_lacpdu_actor_reserved,
657 { "Reserved", "lacp.reserved",
658 FT_BYTES, BASE_NONE, NULL, 0x0,
661 { &hf_lacpdu_partner_type,
662 { "Partner Information", "lacp.partnerInfo",
663 FT_UINT8, BASE_HEX, NULL, 0x0,
664 "TLV type = Partner", HFILL }},
666 { &hf_lacpdu_partner_info_len,
667 { "Partner Information Length", "lacp.partnerInfoLen",
668 FT_UINT8, BASE_HEX, NULL, 0x0,
669 "The length of the Partner TLV", HFILL }},
671 { &hf_lacpdu_partner_sys_priority,
672 { "Partner System Priority", "lacp.partnerSysPriority",
673 FT_UINT16, BASE_DEC, NULL, 0x0,
674 "The priority assigned to the Partner System by management or admin", HFILL }},
676 { &hf_lacpdu_partner_sys,
677 { "Partner System", "lacp.partnerSystem",
678 FT_ETHER, BASE_NONE, NULL, 0x0,
679 "The Partner's System ID encoded as a MAC address", HFILL }},
681 { &hf_lacpdu_partner_key,
682 { "Partner Key", "lacp.partnerKey",
683 FT_UINT16, BASE_DEC, NULL, 0x0,
684 "The operational Key value assigned to the port associated with this link by the Partner", HFILL }},
686 { &hf_lacpdu_partner_port_priority,
687 { "Partner Port Priority", "lacp.partnerPortPriority",
688 FT_UINT16, BASE_DEC, NULL, 0x0,
689 "The priority assigned to the port by the Partner (via Management or Admin)", HFILL }},
691 { &hf_lacpdu_partner_port,
692 { "Partner Port", "lacp.partnerPort",
693 FT_UINT16, BASE_DEC, NULL, 0x0,
694 "The port number associated with this link assigned to the port by the Partner (via Management or Admin)", HFILL }},
696 { &hf_lacpdu_partner_state,
697 { "Partner State", "lacp.partnerState",
698 FT_UINT8, BASE_HEX, NULL, 0x0,
699 "The Partner's state variables for the port, encoded as bits within a single octet", HFILL }},
701 { &hf_lacpdu_flags_p_activity,
702 { "LACP Activity", "lacp.partnerState.activity",
703 FT_BOOLEAN, 8, TFS(&yesno), LACPDU_FLAGS_ACTIVITY,
704 "Activity control value for this link. Active = 1, Passive = 0", HFILL }},
706 { &hf_lacpdu_flags_p_timeout,
707 { "LACP Timeout", "lacp.partnerState.timeout",
708 FT_BOOLEAN, 8, TFS(&yesno), LACPDU_FLAGS_TIMEOUT,
709 "Timeout control value for this link. Short Timeout = 1, Long Timeout = 0", HFILL }},
712 { &hf_lacpdu_flags_p_aggregation,
713 { "Aggregation", "lacp.partnerState.aggregation",
714 FT_BOOLEAN, 8, TFS(&yesno), LACPDU_FLAGS_AGGREGATION,
715 "Aggregatable = 1, Individual = 0", HFILL }},
718 { &hf_lacpdu_flags_p_sync,
719 { "Synchronization", "lacp.partnerState.synchronization",
720 FT_BOOLEAN, 8, TFS(&yesno), LACPDU_FLAGS_SYNC,
721 "In Sync = 1, Out of Sync = 0", HFILL }},
724 { &hf_lacpdu_flags_p_collecting,
725 { "Collecting", "lacp.partnerState.collecting",
726 FT_BOOLEAN, 8, TFS(&yesno), LACPDU_FLAGS_COLLECTING,
727 "Collection of incoming frames is: Enabled = 1, Disabled = 0", HFILL }},
730 { &hf_lacpdu_flags_p_distrib,
731 { "Distributing", "lacp.partnerState.distributing",
732 FT_BOOLEAN, 8, TFS(&yesno), LACPDU_FLAGS_DISTRIB,
733 "Distribution of outgoing frames is: Enabled = 1, Disabled = 0", HFILL }},
737 { &hf_lacpdu_flags_p_defaulted,
738 { "Defaulted", "lacp.partnerState.defaulted",
739 FT_BOOLEAN, 8, TFS(&yesno), LACPDU_FLAGS_DEFAULTED,
740 "1 = Actor Rx machine is using DEFAULT Partner info, 0 = using info in Rx'd LACPDU", HFILL }},
743 { &hf_lacpdu_flags_p_expired,
744 { "Expired", "lacp.partnerState.expired",
745 FT_BOOLEAN, 8, TFS(&yesno), LACPDU_FLAGS_EXPIRED,
746 "1 = Actor Rx machine is EXPIRED, 0 = is NOT EXPIRED", HFILL }},
749 { &hf_lacpdu_partner_reserved,
750 { "Reserved", "lacp.reserved",
751 FT_BYTES, BASE_NONE, NULL, 0x0,
754 { &hf_lacpdu_coll_type,
755 { "Collector Information", "lacp.collectorInfo",
756 FT_UINT8, BASE_HEX, NULL, 0x0,
757 "TLV type = Collector", HFILL }},
759 { &hf_lacpdu_coll_info_len,
760 { "Collector Information Length", "lacp.collectorInfoLen",
761 FT_UINT8, BASE_HEX, NULL, 0x0,
762 "The length of the Collector TLV", HFILL }},
764 { &hf_lacpdu_coll_max_delay,
765 { "Collector Max Delay", "lacp.collectorMaxDelay",
766 FT_UINT16, BASE_DEC, NULL, 0x0,
767 "The max delay of the station tx'ing the LACPDU (in tens of usecs)", HFILL }},
769 { &hf_lacpdu_coll_reserved,
770 { "Reserved", "lacp.reserved",
771 FT_BYTES, BASE_NONE, NULL, 0x0,
775 { &hf_lacpdu_term_type,
776 { "Terminator Information", "lacp.termInfo",
777 FT_UINT8, BASE_HEX, NULL, 0x0,
778 "TLV type = Terminator", HFILL }},
780 { &hf_lacpdu_term_len,
781 { "Terminator Length", "lacp.termLen",
782 FT_UINT8, BASE_HEX, NULL, 0x0,
783 "The length of the Terminator TLV", HFILL }},
785 { &hf_lacpdu_term_reserved,
786 { "Reserved", "lacp.reserved",
787 FT_BYTES, BASE_NONE, NULL, 0x0,
792 /* Setup protocol subtree array */
794 static gint *ett[] = {
800 /* Register the protocol name and description */
802 proto_lacpdu = proto_register_protocol("Link Aggregation Control Protocol", "LACP", "lacp");
804 /* Required function calls to register the header fields and subtrees used */
806 proto_register_field_array(proto_lacpdu, hf, array_length(hf));
807 proto_register_subtree_array(ett, array_length(ett));
813 proto_reg_handoff_lacpdu(void)
815 dissector_handle_t slow_protocols_handle;
817 slow_protocols_handle = create_dissector_handle(dissect_slow_protocols, proto_lacpdu);
818 dissector_add("ethertype", ETHERTYPE_SLOW_PROTOCOLS, slow_protocols_handle);